[PATCH] D31328: [clangd] Add code completion support

2017-04-02 Thread Stanislav Ionascu via Phabricator via cfe-commits
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

2017-04-02 Thread AndrĂ¡s Leitereg via Phabricator via cfe-commits
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

2017-04-02 Thread Krystyna via Phabricator via cfe-commits
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

2017-04-02 Thread Phabricator via Phabricator via cfe-commits
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

2017-04-02 Thread Gor Nishanov via Phabricator via cfe-commits
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

2017-04-02 Thread Gor Nishanov via Phabricator via cfe-commits
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)

2017-04-02 Thread Faisal Vali via Phabricator via cfe-commits
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

2017-04-02 Thread Yaxun Liu via Phabricator via cfe-commits
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

2017-04-02 Thread Gor Nishanov via Phabricator via cfe-commits
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.

2017-04-02 Thread Craig Topper via cfe-commits
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.

2017-04-02 Thread Craig Topper via cfe-commits
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

2017-04-02 Thread Shoaib Meenai via cfe-commits
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

2017-04-02 Thread Tony Tye via Phabricator via cfe-commits
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