[PATCH] D31328: [clangd] Add code completion support
stanionascu added inline comments. Comment at: clangd/Protocol.cpp:613 + if (CI.kind != CompletionItemKind::Missing) +Os << R"("kind":)" << static_cast(CI.kind) << R"(",)"; + if (!CI.detail.empty()) if kind is actually provided there will be a trailing quote, as in ("kind": 4"). https://reviews.llvm.org/D31328 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30547: [clang-tidy] Forwarding reference overload in constructors
leanil updated this revision to Diff 93774. leanil added a comment. Simplify checking the presence of copy and move ctors. Repository: rL LLVM https://reviews.llvm.org/D30547 Files: clang-tidy/misc/CMakeLists.txt clang-tidy/misc/ForwardingReferenceOverloadCheck.cpp clang-tidy/misc/ForwardingReferenceOverloadCheck.h clang-tidy/misc/MiscTidyModule.cpp docs/ReleaseNotes.rst docs/clang-tidy/checks/list.rst docs/clang-tidy/checks/misc-forwarding-reference-overload.rst test/clang-tidy/misc-forwarding-reference-overload.cpp Index: test/clang-tidy/misc-forwarding-reference-overload.cpp === --- /dev/null +++ test/clang-tidy/misc-forwarding-reference-overload.cpp @@ -0,0 +1,139 @@ +// RUN: %check_clang_tidy %s misc-forwarding-reference-overload %t + +namespace std { +template +struct enable_if {}; + +template +struct enable_if { typedef T type; }; + +template +using enable_if_t = typename enable_if::type; + +template +struct enable_if_nice { typedef T type; }; +} + +namespace foo { +template +struct enable_if { typedef T type; }; +} + +template +constexpr bool just_true = true; + +class Test1 { +public: + template + Test1(T &&n); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor accepting a forwarding reference can hide the copy and move constructors [misc-forwarding-reference-overload] + + template + Test1(T &&n, int i = 5, ...); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor accepting a forwarding reference can hide the copy and move constructors [misc-forwarding-reference-overload] + + template ::type> + Test1(T &&n); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor accepting a forwarding reference can hide the copy and move constructors [misc-forwarding-reference-overload] + + template + Test1(T &&n, typename foo::enable_if::type i = 5, ...); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor accepting a forwarding reference can hide the copy and move constructors [misc-forwarding-reference-overload] + + Test1(const Test1 &other) {} + // CHECK-MESSAGES: :[[@LINE-1]]:3: note: copy constructor declared here + + Test1(Test1 &other) {} + // CHECK-MESSAGES: :[[@LINE-1]]:3: note: copy constructor declared here + + Test1(Test1 &&other) {} + // CHECK-MESSAGES: :[[@LINE-1]]:3: note: move constructor declared here +}; + +template +class Test2 { +public: + // Two parameters without default value, can't act as copy / move constructor. + template + Test2(T &&n, V &&m, int i = 5, ...); + + // Guarded with enable_if. + template + Test2(T &&n, int i = 5, std::enable_if_t a = 5, ...); + + // Guarded with enable_if. + template ::type &> + Test2(T &&n); + + // Guarded with enable_if. + template + Test2(T &&n, typename std::enable_if>::type **a = nullptr); + + // Guarded with enable_if. + template > *&&> + Test2(T &&n, double d = 0.0); + + // Not a forwarding reference parameter. + template + Test2(const T &&n); + + // Not a forwarding reference parameter. + Test2(int &&x); + + // Two parameters without default value, can't act as copy / move constructor. + template + Test2(T &&n, int x); + + // Not a forwarding reference parameter. + template + Test2(U &&n); +}; + +// The copy and move constructors are both disabled. +class Test3 { +public: + template + Test3(T &&n); + + template + Test3(T &&n, int I = 5, ...); + + Test3(const Test3 &rhs) = delete; + +private: + Test3(Test3 &&rhs); +}; + +// Both the copy and the (compiler generated) move constructors can be hidden. +class Test4 { +public: + template + Test4(T &&n); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor accepting a forwarding reference can hide the copy and move constructors [misc-forwarding-reference-overload] + + Test4(const Test4 &rhs); + // CHECK-MESSAGES: :[[@LINE-1]]:3: note: copy constructor declared here +}; + +// Only the (compiler generated) copy constructor can be hidden. +class Test5 { +public: + template + Test5(T &&n); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor accepting a forwarding reference can hide the copy constructor [misc-forwarding-reference-overload] + + Test5(Test5 &&rhs) = delete; +}; + +// Only the move constructor can be hidden. +class Test6 { +public: + template + Test6(T &&n); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor accepting a forwarding reference can hide the move constructor [misc-forwarding-reference-overload] + + Test6(Test6 &&rhs); + // CHECK-MESSAGES: :[[@LINE-1]]:3: note: move constructor declared here +private: + Test6(const Test6 &rhs); +}; \ No newline at end of file Index: docs/clang-tidy/checks/misc-forwarding-reference-overload.rst === --- /dev/null +++ docs/clang-tidy/checks/misc-forwarding-reference-overload.rst @@ -0,0 +1,52 @@ +.. title:: clang-tidy - misc-forwarding-reference-overload + +misc-forwarding-reference-
[PATCH] D29262: Fixes to modernize-use-using
krystyna updated this revision to Diff 93797. krystyna marked 2 inline comments as done. https://reviews.llvm.org/D29262 Files: clang-tidy/modernize/UseUsingCheck.cpp clang-tidy/modernize/UseUsingCheck.h test/clang-tidy/modernize-use-using-macros.cpp test/clang-tidy/modernize-use-using.cpp Index: test/clang-tidy/modernize-use-using.cpp === --- test/clang-tidy/modernize-use-using.cpp +++ test/clang-tidy/modernize-use-using.cpp @@ -89,7 +89,6 @@ #define CODE typedef int INT CODE; -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' // CHECK-FIXES: #define CODE typedef int INT // CHECK-FIXES: CODE; @@ -102,7 +101,6 @@ #define TYPEDEF typedef TYPEDEF Foo Bak; -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' // CHECK-FIXES: #define TYPEDEF typedef // CHECK-FIXES: TYPEDEF Foo Bak; @@ -148,3 +146,18 @@ struct { int d; } typedef S4; // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' // CHECK-FIXES: struct { int d; } typedef S4; + +namespace my_space { + class my_cclass {}; + typedef my_cclass FuncType; +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'using' instead of 'typedef' +// CHECK-FIXES: using FuncType = my_cclass; +} + +#define lol 4 +typedef unsigned Map[lol]; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' + +typedef void (*fun_type)(); +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' +// CHECK-FIXES: using fun_type = void (*)(); Index: test/clang-tidy/modernize-use-using-macros.cpp === --- /dev/null +++ test/clang-tidy/modernize-use-using-macros.cpp @@ -0,0 +1,23 @@ +// RUN: %check_clang_tidy %s modernize-use-using %t -- \ +// RUN: -config="{CheckOptions: [{key: modernize-use-using.IgnoreMacros, value: 0}]}" \ +// RUN: -- -std=c++11 -I %S/Inputs/modernize-use-using + +#define CODE typedef int INT + +CODE; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' +// CHECK-FIXES: #define CODE typedef int INT +// CHECK-FIXES: CODE; + +struct Foo; +#define Bar Baz +typedef Foo Bar; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' +// CHECK-FIXES: #define Bar Baz +// CHECK-FIXES: using Baz = Foo; + +#define TYPEDEF typedef +TYPEDEF Foo Bak; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' +// CHECK-FIXES: #define TYPEDEF typedef +// CHECK-FIXES: TYPEDEF Foo Bak; Index: clang-tidy/modernize/UseUsingCheck.h === --- clang-tidy/modernize/UseUsingCheck.h +++ clang-tidy/modernize/UseUsingCheck.h @@ -21,9 +21,14 @@ /// For the user-facing documentation see: /// http://clang.llvm.org/extra/clang-tidy/checks/modernize-use-using.html class UseUsingCheck : public ClangTidyCheck { + + const bool IgnoreMacros; + public: - UseUsingCheck(StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context) {} + UseUsingCheck(StringRef Name, ClangTidyContext *Context); + void storeOptions(ClangTidyOptions::OptionMap &Opts) override { +Options.store(Opts, "IgnoreMacros", IgnoreMacros); + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; }; Index: clang-tidy/modernize/UseUsingCheck.cpp === --- clang-tidy/modernize/UseUsingCheck.cpp +++ clang-tidy/modernize/UseUsingCheck.cpp @@ -17,6 +17,10 @@ namespace tidy { namespace modernize { +UseUsingCheck::UseUsingCheck(StringRef Name, ClangTidyContext *Context) +: ClangTidyCheck(Name, Context), + IgnoreMacros(Options.get("IgnoreMacros", true)) {} + void UseUsingCheck::registerMatchers(MatchFinder *Finder) { if (!getLangOpts().CPlusPlus11) return; @@ -79,18 +83,28 @@ auto &Context = *Result.Context; auto &SM = *Result.SourceManager; + SourceLocation StartLoc = MatchedDecl->getLocStart(); + + if (StartLoc.isMacroID() && IgnoreMacros) +return; + auto Diag = - diag(MatchedDecl->getLocStart(), "use 'using' instead of 'typedef'"); + diag(StartLoc, "use 'using' instead of 'typedef'"); - SourceLocation StartLoc = MatchedDecl->getLocStart(); - if (StartLoc.isMacroID()) + // do not fix if there is macro or array + if (MatchedDecl->getUnderlyingType()->isArrayType() || StartLoc.isMacroID()) return; if (CheckRemoval(SM, StartLoc, Context)) { +auto printPolicy = PrintingPolicy(getLangOpts()); +printPolicy.SuppressScope = true; +printPolicy.ConstantArraySizeAsWritten = true; +printPolicy.UseVoidForZeroParams = false; + Diag << FixItHint::CreateReplacement( MatchedDecl->getSourceRange(), "using " + MatchedDecl->getNameAsString() + " = " + -MatchedDecl->getUnde
[PATCH] D29262: Fixes to modernize-use-using
This revision was automatically updated to reflect the committed changes. Closed by commit rL299340: Fixes for modernize-use-using check: (authored by krystynka). Changed prior to commit: https://reviews.llvm.org/D29262?vs=93797&id=93804#toc Repository: rL LLVM https://reviews.llvm.org/D29262 Files: clang-tools-extra/trunk/clang-tidy/modernize/UseUsingCheck.cpp clang-tools-extra/trunk/clang-tidy/modernize/UseUsingCheck.h clang-tools-extra/trunk/test/clang-tidy/modernize-use-using-macros.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-use-using.cpp Index: clang-tools-extra/trunk/test/clang-tidy/modernize-use-using-macros.cpp === --- clang-tools-extra/trunk/test/clang-tidy/modernize-use-using-macros.cpp +++ clang-tools-extra/trunk/test/clang-tidy/modernize-use-using-macros.cpp @@ -0,0 +1,23 @@ +// RUN: %check_clang_tidy %s modernize-use-using %t -- \ +// RUN: -config="{CheckOptions: [{key: modernize-use-using.IgnoreMacros, value: 0}]}" \ +// RUN: -- -std=c++11 -I %S/Inputs/modernize-use-using + +#define CODE typedef int INT + +CODE; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' +// CHECK-FIXES: #define CODE typedef int INT +// CHECK-FIXES: CODE; + +struct Foo; +#define Bar Baz +typedef Foo Bar; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' +// CHECK-FIXES: #define Bar Baz +// CHECK-FIXES: using Baz = Foo; + +#define TYPEDEF typedef +TYPEDEF Foo Bak; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' +// CHECK-FIXES: #define TYPEDEF typedef +// CHECK-FIXES: TYPEDEF Foo Bak; Index: clang-tools-extra/trunk/test/clang-tidy/modernize-use-using.cpp === --- clang-tools-extra/trunk/test/clang-tidy/modernize-use-using.cpp +++ clang-tools-extra/trunk/test/clang-tidy/modernize-use-using.cpp @@ -89,7 +89,6 @@ #define CODE typedef int INT CODE; -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' // CHECK-FIXES: #define CODE typedef int INT // CHECK-FIXES: CODE; @@ -102,7 +101,6 @@ #define TYPEDEF typedef TYPEDEF Foo Bak; -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' // CHECK-FIXES: #define TYPEDEF typedef // CHECK-FIXES: TYPEDEF Foo Bak; @@ -148,3 +146,18 @@ struct { int d; } typedef S4; // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' // CHECK-FIXES: struct { int d; } typedef S4; + +namespace my_space { + class my_cclass {}; + typedef my_cclass FuncType; +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'using' instead of 'typedef' +// CHECK-FIXES: using FuncType = my_cclass; +} + +#define lol 4 +typedef unsigned Map[lol]; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' + +typedef void (*fun_type)(); +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' +// CHECK-FIXES: using fun_type = void (*)(); Index: clang-tools-extra/trunk/clang-tidy/modernize/UseUsingCheck.cpp === --- clang-tools-extra/trunk/clang-tidy/modernize/UseUsingCheck.cpp +++ clang-tools-extra/trunk/clang-tidy/modernize/UseUsingCheck.cpp @@ -17,6 +17,10 @@ namespace tidy { namespace modernize { +UseUsingCheck::UseUsingCheck(StringRef Name, ClangTidyContext *Context) +: ClangTidyCheck(Name, Context), + IgnoreMacros(Options.get("IgnoreMacros", true)) {} + void UseUsingCheck::registerMatchers(MatchFinder *Finder) { if (!getLangOpts().CPlusPlus11) return; @@ -79,18 +83,28 @@ auto &Context = *Result.Context; auto &SM = *Result.SourceManager; + SourceLocation StartLoc = MatchedDecl->getLocStart(); + + if (StartLoc.isMacroID() && IgnoreMacros) +return; + auto Diag = - diag(MatchedDecl->getLocStart(), "use 'using' instead of 'typedef'"); + diag(StartLoc, "use 'using' instead of 'typedef'"); - SourceLocation StartLoc = MatchedDecl->getLocStart(); - if (StartLoc.isMacroID()) + // do not fix if there is macro or array + if (MatchedDecl->getUnderlyingType()->isArrayType() || StartLoc.isMacroID()) return; if (CheckRemoval(SM, StartLoc, Context)) { +auto printPolicy = PrintingPolicy(getLangOpts()); +printPolicy.SuppressScope = true; +printPolicy.ConstantArraySizeAsWritten = true; +printPolicy.UseVoidForZeroParams = false; + Diag << FixItHint::CreateReplacement( MatchedDecl->getSourceRange(), "using " + MatchedDecl->getNameAsString() + " = " + -MatchedDecl->getUnderlyingType().getAsString(getLangOpts())); +MatchedDecl->getUnderlyingType().getAsString(printPolicy)); } } Index: clang-tools-extra/trunk/clang-tidy/modernize/UseUsingCheck.h === --- clang-tools-extra/trunk/clang-tidy/modernize/UseUsingCheck.h +++ clang
[PATCH] D31584: [coroutines] Add support for allocation elision
GorNishanov created this revision. We wrap allocation code so that backend can elide it if necessary. llvm.coro.alloc intrinsic returns true, when allocation is needed and false otherwise. %NeedAlloc = call i1 @llvm.coro.alloc(token %2) br i1 %NeedAlloc, label %AllocBB, label %InitBB AllocBB: %5 = call i64 @llvm.coro.size.i64() %call = call i8* @_Znwm(i64 %5) ; operator new br label %InitBB InitBB: %Phi = phi i8* [ null, %0 ], [ %call, %4 ] call i8* @llvm.coro.begin(token %2, i8* %Phi) https://reviews.llvm.org/D31584 Files: lib/CodeGen/CGCoroutine.cpp test/CodeGenCoroutines/coro-alloc.cpp Index: test/CodeGenCoroutines/coro-alloc.cpp === --- test/CodeGenCoroutines/coro-alloc.cpp +++ test/CodeGenCoroutines/coro-alloc.cpp @@ -43,8 +43,17 @@ // CHECK-LABEL: f0( extern "C" void f0(global_new_delete_tag) { // CHECK: %[[ID:.+]] = call token @llvm.coro.id(i32 16 + // CHECK: %[[NeedAlloc:.+]] = call i1 @llvm.coro.alloc(token %[[ID]]) + // CHECK: br i1 %[[NeedAlloc]], label %[[AllocBB:.+]], label %[[InitBB:.+]] + + // CHECK: [[AllocBB]]: // CHECK: %[[SIZE:.+]] = call i64 @llvm.coro.size.i64() - // CHECK: call i8* @_Znwm(i64 %[[SIZE]]) + // CHECK: %[[MEM:.+]] = call i8* @_Znwm(i64 %[[SIZE]]) + // CHECK: br label %[[InitBB]] + + // CHECK: [[InitBB]]: + // CHECK: %[[PHI:.+]] = phi i8* [ null, %{{.+}} ], [ %call, %[[AllocBB]] ] + // CHECK: call i8* @llvm.coro.begin(token %[[ID]], i8* %[[PHI]]) // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.frame() // CHECK: %[[MEM:.+]] = call i8* @llvm.coro.free(token %[[ID]], i8* %[[FRAME]]) Index: lib/CodeGen/CGCoroutine.cpp === --- lib/CodeGen/CGCoroutine.cpp +++ lib/CodeGen/CGCoroutine.cpp @@ -238,6 +238,9 @@ auto &TI = CGM.getContext().getTargetInfo(); unsigned NewAlign = TI.getNewAlign() / TI.getCharWidth(); + auto *EntryBB = Builder.GetInsertBlock(); + auto *AllocBB = createBasicBlock("coro.alloc"); + auto *InitBB = createBasicBlock("coro.init"); auto *FinalBB = createBasicBlock("coro.final"); auto *RetBB = createBasicBlock("coro.ret"); @@ -247,12 +250,20 @@ createCoroData(*this, CurCoro, CoroId); CurCoro.Data->SuspendBB = RetBB; + // Backend is allowed to elide memory allocations, to help it, emit + // auto mem = coro.alloc() ? 0 : ... allocation code ...; + auto *CoroAlloc = Builder.CreateCall( + CGM.getIntrinsic(llvm::Intrinsic::coro_alloc), {CoroId}); + + Builder.CreateCondBr(CoroAlloc, AllocBB, InitBB); + + EmitBlock(AllocBB); auto *AllocateCall = EmitScalarExpr(S.getAllocate()); + auto *AllocOrInvokeContBB = Builder.GetInsertBlock(); // Handle allocation failure if 'ReturnStmtOnAllocFailure' was provided. if (auto *RetOnAllocFailure = S.getReturnStmtOnAllocFailure()) { auto *RetOnFailureBB = createBasicBlock("coro.ret.on.failure"); -auto *InitBB = createBasicBlock("coro.init"); // See if allocation was successful. auto *NullPtr = llvm::ConstantPointerNull::get(Int8PtrTy); @@ -262,9 +273,19 @@ // If not, return OnAllocFailure object. EmitBlock(RetOnFailureBB); EmitStmt(RetOnAllocFailure); - -EmitBlock(InitBB); } + else { +Builder.CreateBr(InitBB); + } + + EmitBlock(InitBB); + + // Pass the result of the allocation to coro.begin. + auto *Phi = Builder.CreatePHI(VoidPtrTy, 2); + Phi->addIncoming(NullPtr, EntryBB); + Phi->addIncoming(AllocateCall, AllocOrInvokeContBB); + Builder.CreateCall( + CGM.getIntrinsic(llvm::Intrinsic::coro_begin), {CoroId, Phi}); CurCoro.Data->CleanupJD = getJumpDestInCurrentScope(RetBB); { Index: test/CodeGenCoroutines/coro-alloc.cpp === --- test/CodeGenCoroutines/coro-alloc.cpp +++ test/CodeGenCoroutines/coro-alloc.cpp @@ -43,8 +43,17 @@ // CHECK-LABEL: f0( extern "C" void f0(global_new_delete_tag) { // CHECK: %[[ID:.+]] = call token @llvm.coro.id(i32 16 + // CHECK: %[[NeedAlloc:.+]] = call i1 @llvm.coro.alloc(token %[[ID]]) + // CHECK: br i1 %[[NeedAlloc]], label %[[AllocBB:.+]], label %[[InitBB:.+]] + + // CHECK: [[AllocBB]]: // CHECK: %[[SIZE:.+]] = call i64 @llvm.coro.size.i64() - // CHECK: call i8* @_Znwm(i64 %[[SIZE]]) + // CHECK: %[[MEM:.+]] = call i8* @_Znwm(i64 %[[SIZE]]) + // CHECK: br label %[[InitBB]] + + // CHECK: [[InitBB]]: + // CHECK: %[[PHI:.+]] = phi i8* [ null, %{{.+}} ], [ %call, %[[AllocBB]] ] + // CHECK: call i8* @llvm.coro.begin(token %[[ID]], i8* %[[PHI]]) // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.frame() // CHECK: %[[MEM:.+]] = call i8* @llvm.coro.free(token %[[ID]], i8* %[[FRAME]]) Index: lib/CodeGen/CGCoroutine.cpp === --- lib/CodeGen/CGCoroutine.cpp +++ lib/CodeGen/CGCoroutine.cpp @@ -238,6 +238,9 @@ auto &TI = CGM.getContext().getTargetInfo(); uns
[PATCH] D31586: [coroutines] Replace all coro.frame builtins with an SSA value of coro.begin
GorNishanov created this revision. SemaCoroutine forms expressions referring to the coroutine frame of the enclosing coroutine using coro.frame builtin. During codegen, we emit llvm.coro.begin intrinsic that returns the address of the coroutine frame. When coro.frame is emitted, we replace it with SSA value of coro.begin. https://reviews.llvm.org/D31586 Files: lib/CodeGen/CGCoroutine.cpp test/CodeGenCoroutines/coro-alloc.cpp test/CodeGenCoroutines/coro-await.cpp test/CodeGenCoroutines/coro-builtins.c Index: test/CodeGenCoroutines/coro-builtins.c === --- test/CodeGenCoroutines/coro-builtins.c +++ test/CodeGenCoroutines/coro-builtins.c @@ -2,7 +2,7 @@ void *myAlloc(long long); -// CHECK-LABEL: f( +// CHECK-LABEL: f( void f(int n) { // CHECK: %n.addr = alloca i32 // CHECK: %n_copy = alloca i32 @@ -19,31 +19,25 @@ // CHECK-NEXT: %[[SIZE:.+]] = call i64 @llvm.coro.size.i64() // CHECK-NEXT: %[[MEM:.+]] = call i8* @myAlloc(i64 %[[SIZE]]) - // CHECK-NEXT: %[[BEG:.+]] = call i8* @llvm.coro.begin(token %[[COROID]], i8* %[[MEM]]) + // CHECK-NEXT: %[[FRAME:.+]] = call i8* @llvm.coro.begin(token %[[COROID]], i8* %[[MEM]]) __builtin_coro_begin(myAlloc(__builtin_coro_size())); - // CHECK-NEXT: %[[FRAME1:.+]] = call i8* @llvm.coro.frame() - // CHECK-NEXT: call void @llvm.coro.resume(i8* %[[FRAME1]]) + // CHECK-NEXT: call void @llvm.coro.resume(i8* %[[FRAME]]) __builtin_coro_resume(__builtin_coro_frame()); - // CHECK-NEXT: %[[FRAME2:.+]] = call i8* @llvm.coro.frame() - // CHECK-NEXT: call void @llvm.coro.destroy(i8* %[[FRAME2]]) + // CHECK-NEXT: call void @llvm.coro.destroy(i8* %[[FRAME]]) __builtin_coro_destroy(__builtin_coro_frame()); - // CHECK-NEXT: %[[FRAME3:.+]] = call i8* @llvm.coro.frame() - // CHECK-NEXT: call i1 @llvm.coro.done(i8* %[[FRAME3]]) + // CHECK-NEXT: call i1 @llvm.coro.done(i8* %[[FRAME]]) __builtin_coro_done(__builtin_coro_frame()); - // CHECK-NEXT: %[[FRAME4:.+]] = call i8* @llvm.coro.frame() - // CHECK-NEXT: call i8* @llvm.coro.promise(i8* %[[FRAME4]], i32 48, i1 false) + // CHECK-NEXT: call i8* @llvm.coro.promise(i8* %[[FRAME]], i32 48, i1 false) __builtin_coro_promise(__builtin_coro_frame(), 48, 0); - // CHECK-NEXT: %[[FRAME5:.+]] = call i8* @llvm.coro.frame() - // CHECK-NEXT: call i8* @llvm.coro.free(token %[[COROID]], i8* %[[FRAME5]]) + // CHECK-NEXT: call i8* @llvm.coro.free(token %[[COROID]], i8* %[[FRAME]]) __builtin_coro_free(__builtin_coro_frame()); - // CHECK-NEXT: %[[FRAME6:.+]] = call i8* @llvm.coro.frame() - // CHECK-NEXT: call i1 @llvm.coro.end(i8* %[[FRAME6]], i1 false) + // CHECK-NEXT: call i1 @llvm.coro.end(i8* %[[FRAME]], i1 false) __builtin_coro_end(__builtin_coro_frame(), 0); // CHECK-NEXT: call i8 @llvm.coro.suspend(token none, i1 true) Index: test/CodeGenCoroutines/coro-await.cpp === --- test/CodeGenCoroutines/coro-await.cpp +++ test/CodeGenCoroutines/coro-await.cpp @@ -40,6 +40,7 @@ // CHECK-LABEL: f0( extern "C" void f0() { + // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.begin( co_await suspend_always{}; // See if we need to suspend: @@ -54,7 +55,6 @@ // --- // Build the coroutine handle and pass it to await_suspend // --- - // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.frame() // CHECK: call i8* @_ZNSt12experimental16coroutine_handleINS_16coroutine_traitsIJvEE12promise_typeEE12from_addressEPv(i8* %[[FRAME]]) // ... many lines of code to coerce coroutine_handle into an i8* scalar // CHECK: %[[CH:.+]] = load i8*, i8** %{{.+}} @@ -100,8 +100,9 @@ // CHECK-LABEL: f1( extern "C" void f1(int) { - co_yield 42; // CHECK: %[[PROMISE:.+]] = alloca %"struct.std::experimental::coroutine_traits::promise_type" + // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.begin( + co_yield 42; // CHECK: call void @_ZNSt12experimental16coroutine_traitsIJviEE12promise_type11yield_valueEi(%struct.suspend_maybe* sret %[[AWAITER:.+]], %"struct.std::experimental::coroutine_traits::promise_type"* %[[PROMISE]], i32 42) // See if we need to suspend: @@ -116,7 +117,6 @@ // --- // Build the coroutine handle and pass it to await_suspend // --- - // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.frame() // CHECK: call i8* @_ZNSt12experimental16coroutine_handleINS_16coroutine_traitsIJviEE12promise_typeEE12from_addressEPv(i8* %[[FRAME]]) // ... many lines of code to coerce coroutine_handle into an i8* scalar // CHECK: %[[CH:.+]] = load i8*, i8** %{{.+}} Index: test/CodeGenCoroutines/coro-alloc.cpp === --- test/CodeGenCoroutines/coro-alloc.cpp +++ test/CodeGenCoroutines/coro-alloc.cpp @@ -53,9 +53,8 @@ // CHECK: [[InitBB]]: // CHECK: %[[PHI:.+]] = phi i8* [ null,
[PATCH] D31588: Fix PR25627: Certain constant local variables must be usable as template arguments (without being odr-used)
faisalv created this revision. This patch ensures that clang processes the expression-nodes that are generated when disambiguating between types and expressions within template arguments, as if they were truly constant-expressions. Currently, trunk correctly disambiguates, and identifies the expression as an expression - and while it annotates the token with the expression - it fails to complete the odr-use processing (specifically, failing to trigger Sema::UpdateMarkingForLValueToRValue as is done so for all Constant Expressions, which removes it from being considered odr-used). For e.g: template struct X { }; void f() { const int N = 10; X x; // should be OK. [] { return X{}; }; // also OK - no capture. } See a related bug: https://bugs.llvm.org//show_bug.cgi?id=25627 The fix is as follows: - Remove the EnteredConstantEvaluatedContext action from ParseTemplateArgumentList (relying that ParseTemplateArgument will get it right) - Add the EnteredConstantEvaluatedContext action just prior to undergoing the disambiguating parse, and if the parse succeeds for an expression, make sure it doesn't linger within MaybeODRUsedExprs by clearing it (while asserting that it only contains the offending expression) I need to add some tests... and fix one regression. Does the approach look sound? Thanks! Repository: rL LLVM https://reviews.llvm.org/D31588 Files: lib/Parse/ParseTemplate.cpp Index: lib/Parse/ParseTemplate.cpp === --- lib/Parse/ParseTemplate.cpp +++ lib/Parse/ParseTemplate.cpp @@ -1198,42 +1198,73 @@ // expression is resolved to a type-id, regardless of the form of // the corresponding template-parameter. // - // Therefore, we initially try to parse a type-id. - if (isCXXTypeId(TypeIdAsTemplateArgument)) { -SourceLocation Loc = Tok.getLocation(); -TypeResult TypeArg = ParseTypeName(/*Range=*/nullptr, - Declarator::TemplateTypeArgContext); -if (TypeArg.isInvalid()) - return ParsedTemplateArgument(); - -return ParsedTemplateArgument(ParsedTemplateArgument::Type, - TypeArg.get().getAsOpaquePtr(), - Loc); - } - + // Therefore, we initially try to parse a type-id. + { +EnterExpressionEvaluationContext EnterConstantEvaluated( +Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated); +if (isCXXTypeId(TypeIdAsTemplateArgument)) { + SourceLocation Loc = Tok.getLocation(); + TypeResult TypeArg = + ParseTypeName(/*Range=*/nullptr, Declarator::TemplateTypeArgContext); + if (TypeArg.isInvalid()) +return ParsedTemplateArgument(); + + return ParsedTemplateArgument(ParsedTemplateArgument::Type, +TypeArg.get().getAsOpaquePtr(), Loc); +} else { + // If we disambiguated as an expression that we identified as potentially + // not being odr-used (consistent with a template argument context), and + // annotated our token as that expression, then remove it from the + // MaybeODRUsedExprs so that it doesn't trigger a false error, since it + // would otherwise have been removed when completing processing of a + // constant expression. + if (Actions.MaybeODRUseExprs.size()) { +assert(Actions.MaybeODRUseExprs.size() == 1 && + "we should only need to parse one expression to determine an " + "error or typeid"); +assert(Tok.getKind() == tok::annot_primary_expr && + getExprAnnotation(Tok).get() == + *Actions.MaybeODRUseExprs.begin() && + "The expression (DeclRefExpr or MemExpr) stored within " + "MaybeODRUseExprs for later checking whether we perform an " + "lvalue-to-rvalue conversion before determining odr-use must be " + "the same as the annotated token during ambiguity resolution"); +// We clear this state, since this lingering partially processed +// expression should not trigger an error now and we don't need to save +// it for later since we can be certain that this expression would +// eventually have been removed during ActOnConstantExpression called +// from ParseConstantExpression when parsing the non-type template +// argument below. Eitherway, the appropriate checking for an +// appropriate constant-expression that matches the +// non-type-template-parameter occurs later in CheckTemplateArgument. +Actions.MaybeODRUseExprs.clear(); + } +} + } // End ExpressionEvaluationContext + // Try to parse a template template argument. { TentativeParsingAction TPA(*this); -ParsedTemplateArgument TemplateTemplateArgument - = ParseTemplateTemplateArgument(); +ParsedTemplateArgument TemplateTemplateArgument = +ParseTem
[PATCH] D31404: [OpenCL] Allow alloca return non-zero private pointer
yaxunl updated this revision to Diff 93820. yaxunl marked an inline comment as done. yaxunl added a comment. Update for the llvm IRBuilder API change for alloca. Removed data layout argument. Moved a lit test to SemaOpenCL. https://reviews.llvm.org/D31404 Files: include/clang/AST/ASTContext.h include/clang/AST/Type.h include/clang/Basic/AddressSpaces.h include/clang/Basic/DiagnosticSemaKinds.td lib/AST/ASTContext.cpp lib/AST/ExprClassification.cpp lib/AST/TypePrinter.cpp lib/Basic/Targets.cpp lib/CodeGen/CGCall.cpp lib/CodeGen/CGExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaOverload.cpp lib/Sema/SemaType.cpp test/CodeGenOpenCL/address-space-constant-initializers.cl test/CodeGenOpenCL/address-spaces.cl test/CodeGenOpenCL/amdgpu-env-amdgiz.cl test/CodeGenOpenCL/vla.cl test/Sema/address_spaces.c test/Sema/invalid-assignment-constant-address-space.c test/SemaOpenCL/invalid-assignment-constant-address-space.cl Index: test/SemaOpenCL/invalid-assignment-constant-address-space.cl === --- /dev/null +++ test/SemaOpenCL/invalid-assignment-constant-address-space.cl @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only + +int constant c[3] = {0}; + +void foo() { + c[0] = 1; //expected-error{{read-only variable is not assignable}} +} Index: test/Sema/invalid-assignment-constant-address-space.c === --- test/Sema/invalid-assignment-constant-address-space.c +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only - -#define OPENCL_CONSTANT 8388354 -int __attribute__((address_space(OPENCL_CONSTANT))) c[3] = {0}; - -void foo() { - c[0] = 1; //expected-error{{read-only variable is not assignable}} -} Index: test/Sema/address_spaces.c === --- test/Sema/address_spaces.c +++ test/Sema/address_spaces.c @@ -19,8 +19,8 @@ _AS1 int array[5]; // expected-error {{automatic variable qualified with an address space}} _AS1 int arrarr[5][5]; // expected-error {{automatic variable qualified with an address space}} - __attribute__((address_space(-1))) int *_boundsA; // expected-error {{address space is negative}} - __attribute__((address_space(0x7F))) int *_boundsB; + __attribute__((address_space(-1))) int *_boundsA; // expected-warning {{address space is negative}} + __attribute__((address_space(0x7F))) int *_boundsB; // expected-error {{address space is larger than the maximum supported}} __attribute__((address_space(0x100))) int *_boundsC; // expected-error {{address space is larger than the maximum supported}} // chosen specifically to overflow 32 bits and come out reasonable __attribute__((address_space(4294967500))) int *_boundsD; // expected-error {{address space is larger than the maximum supported}} Index: test/CodeGenOpenCL/vla.cl === --- test/CodeGenOpenCL/vla.cl +++ test/CodeGenOpenCL/vla.cl @@ -1,18 +1,26 @@ -// RUN: %clang_cc1 -emit-llvm -triple "spir-unknown-unknown" -O0 -cl-std=CL2.0 -o - %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -triple "spir-unknown-unknown" -O0 -cl-std=CL2.0 -o - %s | FileCheck -check-prefixes=CHECK,SPIR %s +// RUN: %clang_cc1 -emit-llvm -triple amdgcn-amd-amdhsa-opencl -O0 -cl-std=CL2.0 -o - %s | FileCheck -check-prefixes=CHECK,SPIR %s +// RUN: %clang_cc1 -emit-llvm -triple amdgcn-amd-amdhsa-amdgizcl -O0 -cl-std=CL2.0 -o - %s | FileCheck -check-prefixes=CHECK,GIZ %s constant int sz0 = 5; -// CHECK: @sz0 = addrspace(2) constant i32 5 +// SPIR: @sz0 = addrspace(2) constant i32 5 +// GIZ: @sz0 = addrspace(4) constant i32 5 const global int sz1 = 16; // CHECK: @sz1 = addrspace(1) constant i32 16 const constant int sz2 = 8; -// CHECK: @sz2 = addrspace(2) constant i32 8 +// SPIR: @sz2 = addrspace(2) constant i32 8 +// GIZ: @sz2 = addrspace(4) constant i32 8 // CHECK: @testvla.vla2 = internal addrspace(3) global [8 x i16] undef kernel void testvla() { int vla0[sz0]; -// CHECK: %vla0 = alloca [5 x i32] +// SPIR: %vla0 = alloca [5 x i32] +// SPIR-NOT: %vla0 = alloca [5 x i32]{{.*}}addrspace +// GIZ: %vla0 = alloca [5 x i32]{{.*}}addrspace(5) char vla1[sz1]; -// CHECK: %vla1 = alloca [16 x i8] +// SPIR: %vla1 = alloca [16 x i8] +// SPIR-NOT: %vla1 = alloca [16 x i8]{{.*}}addrspace +// GIZ: %vla1 = alloca [16 x i8]{{.*}}addrspace(5) local short vla2[sz2]; } Index: test/CodeGenOpenCL/amdgpu-env-amdgiz.cl === --- test/CodeGenOpenCL/amdgpu-env-amdgiz.cl +++ test/CodeGenOpenCL/amdgpu-env-amdgiz.cl @@ -4,6 +4,6 @@ // RUN: %clang_cc1 %s -O0 -triple amdgcn---amdgizcl -emit-llvm -o - | FileCheck -check-prefix=GIZ %s // CHECK: target datalayout = "e-p:32:32-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-
[PATCH] D31590: [coroutines] Add support for deallocation elision
GorNishanov created this revision. Wrap deallocation code with: if (auto *mem = coro.free()) Deallocate When backend decides to elide allocations it will replace coro.free with nullptr to suppress deallocation code. https://reviews.llvm.org/D31590 Files: lib/CodeGen/CGCoroutine.cpp test/CodeGenCoroutines/coro-alloc.cpp Index: test/CodeGenCoroutines/coro-alloc.cpp === --- test/CodeGenCoroutines/coro-alloc.cpp +++ test/CodeGenCoroutines/coro-alloc.cpp @@ -56,7 +56,15 @@ // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.begin(token %[[ID]], i8* %[[PHI]]) // CHECK: %[[MEM:.+]] = call i8* @llvm.coro.free(token %[[ID]], i8* %[[FRAME]]) + // CHECK: %[[NeedDealloc:.+]] = icmp ne i8* %[[MEM]], null + // CHECK: br i1 %[[NeedDealloc]], label %[[FreeBB:.+]], label %[[Afterwards:.+]] + + // CHECK: [[FreeBB]]: // CHECK: call void @_ZdlPv(i8* %[[MEM]]) + // CHECK: br label %[[Afterwards]] + + // CHECK: [[Afterwards]]: + // CHECK: ret void co_return; } Index: lib/CodeGen/CGCoroutine.cpp === --- lib/CodeGen/CGCoroutine.cpp +++ lib/CodeGen/CGCoroutine.cpp @@ -62,6 +62,10 @@ // the address of the coroutine frame of the current coroutine. llvm::CallInst *CoroBegin = nullptr; + // Stores the last emitted coro.free for the deallocate expressions, we use it + // to wrap dealloc code with if(auto mem = coro.free) dealloc(mem). + llvm::CallInst *LastCoroFree = nullptr; + // If coro.id came from the builtin, remember the expression to give better // diagnostic. If CoroIdExpr is nullptr, the coro.id was created by // EmitCoroutineBody. @@ -225,14 +229,47 @@ struct CallCoroDelete final : public EHScopeStack::Cleanup { Stmt *Deallocate; - // TODO: Wrap deallocate in if(coro.free(...)) Deallocate. + // Emit "if (coro.free(CoroId, CoroBegin)) Deallocate;" + + // Note: That deallocation will be emitted twice: once for a normal exit and + // once for exceptional exit. This usage is safe because Deallocate does not + // contain any declarations. The SubStmtBuilder::makeNewAndDeleteExpr() + // builds a single call to a deallocation function which is safe to emit + // multiple times. void Emit(CodeGenFunction &CGF, Flags) override { -// Note: That deallocation will be emitted twice: once for a normal exit and -// once for exceptional exit. This usage is safe because Deallocate does not -// contain any declarations. The SubStmtBuilder::makeNewAndDeleteExpr() -// builds a single call to a deallocation function which is safe to emit -// multiple times. +// Remember the current point, as we are going to emit deallocation code +// first to get to coro.free instruction that is an argument to a delete +// call. +BasicBlock *SaveInsertBlock = CGF.Builder.GetInsertBlock(); + +auto *FreeBB = CGF.createBasicBlock("coro.free"); +CGF.EmitBlock(FreeBB); CGF.EmitStmt(Deallocate); + +auto *AfterFreeBB = CGF.createBasicBlock("after.coro.free"); +CGF.EmitBlock(AfterFreeBB); + +// We should have captured coro.free from the emission of deallocate. +auto *CoroFree = CGF.CurCoro.Data->LastCoroFree; +if (!CoroFree) { + CGF.CGM.Error(Deallocate->getLocStart(), +"Deallocation expressoin does not refer to coro.free"); + return; +} + +// Get back to the block we were originally and move coro.free there. +auto *InsertPt = SaveInsertBlock->getTerminator(); +CoroFree->moveBefore(InsertPt); +CGF.Builder.SetInsertPoint(InsertPt); + +// Add if (auto *mem = coro.free) Deallocate; +auto *NullPtr = llvm::ConstantPointerNull::get(CGF.Int8PtrTy); +auto *Cond = CGF.Builder.CreateICmpNE(CoroFree, NullPtr); +CGF.Builder.CreateCondBr(Cond, FreeBB, AfterFreeBB); + +// No longer need old terminator. +InsertPt->eraseFromParent(); +CGF.Builder.SetInsertPoint(AfterFreeBB); } explicit CallCoroDelete(Stmt *DeallocStmt) : Deallocate(DeallocStmt) {} }; @@ -365,7 +402,7 @@ llvm::Value *F = CGM.getIntrinsic(IID); llvm::CallInst *Call = Builder.CreateCall(F, Args); - // Note: The following code is to enable to emit coroutine intrinsics by + // Note: The following code is to enable to emit coro.id and coro.begin by // hand to experiment with coroutines in C. // If we see @llvm.coro.id remember it in the CoroData. We will update // coro.alloc, coro.begin and coro.free intrinsics to refer to it. @@ -376,5 +413,10 @@ if (CurCoro.Data) CurCoro.Data->CoroBegin = Call; } - return RValue::get(Call); + else if (IID == llvm::Intrinsic::coro_free) { +// Remember the last coro_free as we need it to build the conditional +// deletion of the coroutine frame. +if (CurCoro.Data) + CurCoro.Data->LastCoroFree = Call; + } return RValue::get(Call); } ___ cfe-commits maili
r299346 - [AVX-512] Fix some intrinsic macros that use the wrong macro parameter names and don't have parentheses around them.
Author: ctopper Date: Sun Apr 2 22:41:29 2017 New Revision: 299346 URL: http://llvm.org/viewvc/llvm-project?rev=299346&view=rev Log: [AVX-512] Fix some intrinsic macros that use the wrong macro parameter names and don't have parentheses around them. Thanks to Matthew Barr for reporting this issue. Modified: cfe/trunk/lib/Headers/avx512fintrin.h Modified: cfe/trunk/lib/Headers/avx512fintrin.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/avx512fintrin.h?rev=299346&r1=299345&r2=299346&view=diff == --- cfe/trunk/lib/Headers/avx512fintrin.h (original) +++ cfe/trunk/lib/Headers/avx512fintrin.h Sun Apr 2 22:41:29 2017 @@ -7862,12 +7862,12 @@ _mm512_mask_cvtepi64_storeu_epi16 (void 3 + ((imm) & 0x3) * 4); }) #define _mm512_mask_extracti32x4_epi32(W, U, A, imm) __extension__ ({ \ - (__m128i)__builtin_ia32_selectd_128((__mmask8)__U, \ + (__m128i)__builtin_ia32_selectd_128((__mmask8)(U), \ (__v4si)_mm512_extracti32x4_epi32((A), (imm)), \ (__v4si)__W); }) #define _mm512_maskz_extracti32x4_epi32(U, A, imm) __extension__ ({ \ - (__m128i)__builtin_ia32_selectd_128((__mmask8)__U, \ + (__m128i)__builtin_ia32_selectd_128((__mmask8)(U), \ (__v4si)_mm512_extracti32x4_epi32((A), (imm)), \ (__v4si)_mm_setzero_si128()); }) @@ -7880,12 +7880,12 @@ _mm512_mask_cvtepi64_storeu_epi16 (void ((imm) & 1) ? 7 : 3); }) #define _mm512_mask_extracti64x4_epi64(W, U, A, imm) __extension__ ({ \ - (__m256i)__builtin_ia32_selectq_256((__mmask8)__U, \ + (__m256i)__builtin_ia32_selectq_256((__mmask8)(U), \ (__v4di)_mm512_extracti64x4_epi64((A), (imm)), \ (__v4di)__W); }) #define _mm512_maskz_extracti64x4_epi64(U, A, imm) __extension__ ({ \ - (__m256i)__builtin_ia32_selectq_256((__mmask8)__U, \ + (__m256i)__builtin_ia32_selectq_256((__mmask8)(U), \ (__v4di)_mm512_extracti64x4_epi64((A), (imm)), \ (__v4di)_mm256_setzero_si256()); }) ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r299347 - [AVX-512] Fix a couple more intrinsic macros I missed in r299346.
Author: ctopper Date: Sun Apr 2 22:51:57 2017 New Revision: 299347 URL: http://llvm.org/viewvc/llvm-project?rev=299347&view=rev Log: [AVX-512] Fix a couple more intrinsic macros I missed in r299346. Modified: cfe/trunk/lib/Headers/avx512fintrin.h Modified: cfe/trunk/lib/Headers/avx512fintrin.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/avx512fintrin.h?rev=299347&r1=299346&r2=299347&view=diff == --- cfe/trunk/lib/Headers/avx512fintrin.h (original) +++ cfe/trunk/lib/Headers/avx512fintrin.h Sun Apr 2 22:51:57 2017 @@ -7864,7 +7864,7 @@ _mm512_mask_cvtepi64_storeu_epi16 (void #define _mm512_mask_extracti32x4_epi32(W, U, A, imm) __extension__ ({ \ (__m128i)__builtin_ia32_selectd_128((__mmask8)(U), \ (__v4si)_mm512_extracti32x4_epi32((A), (imm)), \ -(__v4si)__W); }) +(__v4si)(W)); }) #define _mm512_maskz_extracti32x4_epi32(U, A, imm) __extension__ ({ \ (__m128i)__builtin_ia32_selectd_128((__mmask8)(U), \ @@ -7882,7 +7882,7 @@ _mm512_mask_cvtepi64_storeu_epi16 (void #define _mm512_mask_extracti64x4_epi64(W, U, A, imm) __extension__ ({ \ (__m256i)__builtin_ia32_selectq_256((__mmask8)(U), \ (__v4di)_mm512_extracti64x4_epi64((A), (imm)), \ -(__v4di)__W); }) +(__v4di)(W)); }) #define _mm512_maskz_extracti64x4_epi64(U, A, imm) __extension__ ({ \ (__m256i)__builtin_ia32_selectq_256((__mmask8)(U), \ ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libcxx] r299348 - [libc++] Explicitly mark specializations as dllexport
Author: smeenai Date: Sun Apr 2 23:04:24 2017 New Revision: 299348 URL: http://llvm.org/viewvc/llvm-project?rev=299348&view=rev Log: [libc++] Explicitly mark specializations as dllexport Method specializations don't get exported even if there's an exported extern template instantiation on Windows. Explicitly mark the methods for export. They're already exported on Linux and Darwin, so there's no ABI change on those platforms. Modified: libcxx/trunk/include/locale Modified: libcxx/trunk/include/locale URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/locale?rev=299348&r1=299347&r2=299348&view=diff == --- libcxx/trunk/include/locale (original) +++ libcxx/trunk/include/locale Sun Apr 2 23:04:24 2017 @@ -2631,10 +2631,10 @@ private: void init(const char*); }; -template<> void moneypunct_byname::init(const char*); -template<> void moneypunct_byname::init(const char*); -template<> void moneypunct_byname::init(const char*); -template<> void moneypunct_byname::init(const char*); +template<> _LIBCPP_FUNC_VIS void moneypunct_byname::init(const char*); +template<> _LIBCPP_FUNC_VIS void moneypunct_byname::init(const char*); +template<> _LIBCPP_FUNC_VIS void moneypunct_byname::init(const char*); +template<> _LIBCPP_FUNC_VIS void moneypunct_byname::init(const char*); _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname) _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname) ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31404: [OpenCL] Allow alloca return non-zero private pointer
t-tye added inline comments. Comment at: include/clang/AST/Type.h:339-340 +auto Addr = getAddressSpace(); +if (Addr == 0) + return 0; +return Addr - LangAS::target_first; Since you mention this is only used for `__attribute__((address_space(n)))`, why is this check for 0 needed? If it is needed then to match other places should it simply be: ``` if (Addr) return Addr - LangAS::target_first; return 0; ``` Comment at: include/clang/Basic/DiagnosticSemaKinds.td:2451-2453 +def warn_attribute_address_space_negative : Warning< + "address space is negative">, + InGroup>; Now the one questionable test has been fixed, should the handling of address_space attribute go back to it being an error if n is negative? That seems more logical. Comment at: lib/AST/ASTContext.cpp:9555 + // alloca. + if (AS == LangAS::Default && LangOpts.OpenCL) +return getTargetInfo().getDataLayout().getAllocaAddrSpace(); To be consistent with other places should this simply be: ``` if (!AS && LangOpts.OpenCL) ``` Comment at: lib/AST/ASTContext.cpp:9556 + if (AS == LangAS::Default && LangOpts.OpenCL) +return getTargetInfo().getDataLayout().getAllocaAddrSpace(); + if (AS >= LangAS::target_first) An alternative to doing this would be to add an opencl_private to LangAS and have each target map it accordingly. Then this could be: ``` // If a target specific address space was specified, simply return it. if (AS >= LangAS::target_first) return AS - LangAS::target_first; // For OpenCL, only function local variables are not explicitly marked with // an address space in the AST, so treat them as the OpenCL private address space. if (!AS && LangOpts.OpenCL) AS = LangAS::opencl_private; return (*AddrSpaceMap)[AS]; ``` This seems to better express what is happening here. If no address space was specified, and the language is OpenCL, then treat it as OpenCL private and map it according to the target mapping. If wanted to eliminate the LangAS::Default named constant then that would be possible as it is no longer being used by name. However, would need to ensure that the first named enumerators starts at 1 so that 0 is left as the "no value explicitly specified" value that each target must map to the target specific generic address space. Comment at: lib/Sema/SemaExprCXX.cpp:2052 + else if (AllocType.getQualifiers().getAddressSpace() && + AllocType.getQualifiers().getAddressSpace() != LangAS::target_first) return Diag(Loc, diag::err_address_space_qualified_new) Should this be `>= LangAS::target_first` ? Seems it is wanting to check if an `__attribute__((address_space(n)))` was specified. Comment at: lib/Sema/SemaExprCXX.cpp:3123 +if (Pointee.getQualifiers().getAddressSpace() && + Pointee.getQualifiers().getAddressSpace() != LangAS::target_first) return Diag(Ex.get()->getLocStart(), Ditto. https://reviews.llvm.org/D31404 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits