[PATCH] D33393: [PATCH] Libcxxabi Demangler PR32890

2017-05-22 Thread Marcel Boehme via Phabricator via cfe-commits
marcel added a comment.

In https://reviews.llvm.org/D33393#761679, @erik.pilkington wrote:

> Do you agree that this is the right approach here?


Sure. As long as it fixes PR32890.
You could append my test case as a quick-check.

So, I'll go ahead and abandon this revision?


https://reviews.llvm.org/D33393



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33393: [PATCH] Libcxxabi Demangler PR32890

2017-05-22 Thread Erik Pilkington via Phabricator via cfe-commits
erik.pilkington added a comment.

Could you please add more context lines in any future patches? Makes it easier 
to review!

I think we fixed the same problem at the same time, I have 
https://reviews.llvm.org/D33368 that also fixes this! The reason that inserting 
into db.names.back() sometimes results in a insertion out of bounds is that 
parse_type() can sometimes append multiple names into `db.names` (ie for a 
reference to a pack expansion). This results in db.names.back() no longer being 
the text `'lambda`, which makes inserting at +7 dangerous. I think we should 
handle this case by appending them one by one into the lambda's parameters, 
which is what my patch does. Do you agree that this is the right approach here?




Comment at: src/cxa_demangle.cpp:3080
+  
db.names.back().first.insert(db.names.back().first.begin()+7, t0, t1);
 t0 = t1;
 }

We shouldn't make progress here if something invalid happened, if the 
names.back().size() is less than 7 then we should just bail out and return 
first.


https://reviews.llvm.org/D33393



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33393: [PATCH] Libcxxabi Demangler PR32890

2017-05-22 Thread Marcel Boehme via Phabricator via cfe-commits
marcel updated this revision to Diff 99850.
marcel added a comment.

Fixing off-by-one. Passes `make check-cxxabi` for LLVM in trunk on my machine 
(x86-64, Ubuntu 16.04).


https://reviews.llvm.org/D33393

Files:
  CREDITS.TXT
  src/cxa_demangle.cpp
  test/test_demangle.pass.cpp


Index: test/test_demangle.pass.cpp
===
--- test/test_demangle.pass.cpp
+++ test/test_demangle.pass.cpp
@@ -29665,6 +29665,7 @@
 
"\x44\x74\x70\x74\x71\x75\x32\x43\x41\x38\x65\x6E\x9B\x72\x4D\xC1\x43\x41\x72\x4D\x6E\x77\x38\x9A\x8E\x44\x6F\x64\x6C\x53\xF9\x5F\x70\x74\x70\x69\x45\x38\xD3\x73\x9E\x2A\x37",
 
"\x46\x44\x74\x70\x74\x71\x75\x32\x43\x41\x72\x4D\x6E\x65\x34\x9F\xC1\x43\x41\x72\x4D\x6E\x77\x38\x9A\x8E\x44\x6F\x64\x6C\x53\xF9\x5F\x70\x74\x70\x69\x45\x34\xD3\x73\x9E\x2A\x37\x72\x33\x8E\x3A\x29\x8E\x44\x35",
"_ZcvCiIJEEDvT__T_vT_v",
+"Z1JIJ1_T_EE3o00EUlT_E0",
 };
 
 const unsigned NI = sizeof(invalid_cases) / sizeof(invalid_cases[0]);
Index: src/cxa_demangle.cpp
===
--- src/cxa_demangle.cpp
+++ src/cxa_demangle.cpp
@@ -3075,7 +3075,8 @@
 const char* t1 = t0 + 1;
 while (t1 != last && std::isdigit(*t1))
 ++t1;
-db.names.back().first.insert(db.names.back().first.begin()+7, 
t0, t1);
+if (db.names.back().first.length() >= 7)
+  
db.names.back().first.insert(db.names.back().first.begin()+7, t0, t1);
 t0 = t1;
 }
 if (t0 == last || *t0 != '_')
Index: CREDITS.TXT
===
--- CREDITS.TXT
+++ CREDITS.TXT
@@ -12,6 +12,10 @@
 E: aa...@aaronballman.com
 D: Minor patches
 
+N: Marcel Boehme
+E: marcel.boe...@acm.org
+D: Minor patches
+
 N: Logan Chien
 E: logan.ch...@mediatek.com
 D: ARM EHABI Unwind & Exception Handling


Index: test/test_demangle.pass.cpp
===
--- test/test_demangle.pass.cpp
+++ test/test_demangle.pass.cpp
@@ -29665,6 +29665,7 @@
 "\x44\x74\x70\x74\x71\x75\x32\x43\x41\x38\x65\x6E\x9B\x72\x4D\xC1\x43\x41\x72\x4D\x6E\x77\x38\x9A\x8E\x44\x6F\x64\x6C\x53\xF9\x5F\x70\x74\x70\x69\x45\x38\xD3\x73\x9E\x2A\x37",
 "\x46\x44\x74\x70\x74\x71\x75\x32\x43\x41\x72\x4D\x6E\x65\x34\x9F\xC1\x43\x41\x72\x4D\x6E\x77\x38\x9A\x8E\x44\x6F\x64\x6C\x53\xF9\x5F\x70\x74\x70\x69\x45\x34\xD3\x73\x9E\x2A\x37\x72\x33\x8E\x3A\x29\x8E\x44\x35",
"_ZcvCiIJEEDvT__T_vT_v",
+"Z1JIJ1_T_EE3o00EUlT_E0",
 };
 
 const unsigned NI = sizeof(invalid_cases) / sizeof(invalid_cases[0]);
Index: src/cxa_demangle.cpp
===
--- src/cxa_demangle.cpp
+++ src/cxa_demangle.cpp
@@ -3075,7 +3075,8 @@
 const char* t1 = t0 + 1;
 while (t1 != last && std::isdigit(*t1))
 ++t1;
-db.names.back().first.insert(db.names.back().first.begin()+7, t0, t1);
+if (db.names.back().first.length() >= 7)
+  db.names.back().first.insert(db.names.back().first.begin()+7, t0, t1);
 t0 = t1;
 }
 if (t0 == last || *t0 != '_')
Index: CREDITS.TXT
===
--- CREDITS.TXT
+++ CREDITS.TXT
@@ -12,6 +12,10 @@
 E: aa...@aaronballman.com
 D: Minor patches
 
+N: Marcel Boehme
+E: marcel.boe...@acm.org
+D: Minor patches
+
 N: Logan Chien
 E: logan.ch...@mediatek.com
 D: ARM EHABI Unwind & Exception Handling
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33393: [PATCH] Libcxxabi Demangler PR32890

2017-05-22 Thread Marcel Boehme via Phabricator via cfe-commits
marcel added inline comments.



Comment at: src/cxa_demangle.cpp:3078-3079
 ++t1;
-db.names.back().first.insert(db.names.back().first.begin()+7, 
t0, t1);
+if (db.names.back().first.length() > 7)
+  db.names.back().first.insert(db.names.back().first.begin() + 
7, t0, t1);
 t0 = t1;

dexonsmith wrote:
> Should this be `>= 7`?
You are right. Thanks for spotting this. Updating the patch.


https://reviews.llvm.org/D33393



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33393: [PATCH] Libcxxabi Demangler PR32890

2017-05-22 Thread Duncan P. N. Exon Smith via Phabricator via cfe-commits
dexonsmith added a reviewer: erik.pilkington.
dexonsmith added inline comments.



Comment at: src/cxa_demangle.cpp:3078-3079
 ++t1;
-db.names.back().first.insert(db.names.back().first.begin()+7, 
t0, t1);
+if (db.names.back().first.length() > 7)
+  db.names.back().first.insert(db.names.back().first.begin() + 
7, t0, t1);
 t0 = t1;

Should this be `>= 7`?


https://reviews.llvm.org/D33393



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31627: [coroutines] Skip over passthrough operator co_await

2017-05-22 Thread Gor Nishanov via Phabricator via cfe-commits
GorNishanov closed this revision.
GorNishanov added a comment.

r303605 = b026b234d55d6b9fab849389b2085204f530af5d


https://reviews.llvm.org/D31627



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r303605 - [coroutines] Skip over passthrough operator co_await

2017-05-22 Thread Gor Nishanov via cfe-commits
Author: gornishanov
Date: Tue May 23 00:25:31 2017
New Revision: 303605

URL: http://llvm.org/viewvc/llvm-project?rev=303605&view=rev
Log:
[coroutines] Skip over passthrough operator co_await

https://reviews.llvm.org/D31627

Modified:
cfe/trunk/lib/CodeGen/CGCoroutine.cpp
cfe/trunk/test/CodeGenCoroutines/coro-await.cpp

Modified: cfe/trunk/lib/CodeGen/CGCoroutine.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCoroutine.cpp?rev=303605&r1=303604&r2=303605&view=diff
==
--- cfe/trunk/lib/CodeGen/CGCoroutine.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCoroutine.cpp Tue May 23 00:25:31 2017
@@ -151,6 +151,20 @@ static RValue emitSuspendExpression(Code
 AwaitKind Kind, AggValueSlot aggSlot,
 bool ignoreResult) {
   auto *E = S.getCommonExpr();
+
+  // FIXME: rsmith 5/22/2017. Does it still make sense for us to have a 
+  // UO_Coawait at all? As I recall, the only purpose it ever had was to
+  // represent a dependent co_await expression that couldn't yet be resolved to
+  // a CoawaitExpr. But now we have (and need!) a separate DependentCoawaitExpr
+  // node to store unqualified lookup results, it seems that the UnaryOperator
+  // portion of the representation serves no purpose (and as seen in this 
patch,
+  // it's getting in the way). Can we remove it?
+
+  // Skip passthrough operator co_await (present when awaiting on an LValue).
+  if (auto *UO = dyn_cast(E))
+if (UO->getOpcode() == UO_Coawait)
+  E = UO->getSubExpr();
+
   auto Binder =
   CodeGenFunction::OpaqueValueMappingData::bind(CGF, S.getOpaqueValue(), 
E);
   auto UnbindOnExit = llvm::make_scope_exit([&] { Binder.unbind(CGF); });

Modified: cfe/trunk/test/CodeGenCoroutines/coro-await.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCoroutines/coro-await.cpp?rev=303605&r1=303604&r2=303605&view=diff
==
--- cfe/trunk/test/CodeGenCoroutines/coro-await.cpp (original)
+++ cfe/trunk/test/CodeGenCoroutines/coro-await.cpp Tue May 23 00:25:31 2017
@@ -271,3 +271,10 @@ extern "C" void EndlessLoop() {
   // CHECK-NOT: call void 
@_ZNSt12experimental16coroutine_traitsIJvEE12promise_type13final_suspendEv(
   // CHECK-NOT: call zeroext i1 
@_ZN10final_susp11await_readyEv(%struct.final_susp*
 }
+
+// Verifies that we don't crash when awaiting on an lvalue.
+// CHECK-LABEL: @_Z11AwaitLValuev(
+void AwaitLValue() {
+  suspend_always lval;
+  co_await lval;
+}


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r303604 - Added LLVM_FALLTHROUGH to address gcc warning: this statement may fall through.

2017-05-22 Thread Galina Kistanova via cfe-commits
Author: gkistanova
Date: Tue May 23 00:17:49 2017
New Revision: 303604

URL: http://llvm.org/viewvc/llvm-project?rev=303604&view=rev
Log:
Added LLVM_FALLTHROUGH to address gcc warning: this statement may fall through.

Modified:
cfe/trunk/lib/Driver/ToolChains/Myriad.cpp

Modified: cfe/trunk/lib/Driver/ToolChains/Myriad.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Myriad.cpp?rev=303604&r1=303603&r2=303604&view=diff
==
--- cfe/trunk/lib/Driver/ToolChains/Myriad.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChains/Myriad.cpp Tue May 23 00:17:49 2017
@@ -217,6 +217,7 @@ MyriadToolChain::MyriadToolChain(const D
   default:
 D.Diag(clang::diag::err_target_unsupported_arch)
 << Triple.getArchName() << "myriad";
+LLVM_FALLTHROUGH;
   case llvm::Triple::sparc:
   case llvm::Triple::sparcel:
   case llvm::Triple::shave:


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31608: [coroutines] Add emission of initial and final suspends

2017-05-22 Thread Gor Nishanov via Phabricator via cfe-commits
GorNishanov closed this revision.
GorNishanov added a comment.

r303603 = 12cdab350043e7ff931af5f13d3e3afe85b76628


https://reviews.llvm.org/D31608



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r303603 - [coroutines] Add emission of initial and final suspends

2017-05-22 Thread Gor Nishanov via cfe-commits
Author: gornishanov
Date: Tue May 23 00:04:01 2017
New Revision: 303603

URL: http://llvm.org/viewvc/llvm-project?rev=303603&view=rev
Log:
[coroutines] Add emission of initial and final suspends

https://reviews.llvm.org/D31608

Modified:
cfe/trunk/lib/CodeGen/CGCoroutine.cpp
cfe/trunk/test/CodeGenCoroutines/coro-await.cpp
cfe/trunk/test/CodeGenCoroutines/coro-cleanup.cpp

Modified: cfe/trunk/lib/CodeGen/CGCoroutine.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCoroutine.cpp?rev=303603&r1=303602&r2=303603&view=diff
==
--- cfe/trunk/lib/CodeGen/CGCoroutine.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCoroutine.cpp Tue May 23 00:04:01 2017
@@ -388,7 +388,10 @@ void CodeGenFunction::EmitCoroutineBody(
 
 CurCoro.Data->FinalJD = getJumpDestInCurrentScope(FinalBB);
 
-// FIXME: Emit initial suspend and more before the body.
+// FIXME: Emit param moves.
+
+CurCoro.Data->CurrentAwaitKind = AwaitKind::Init;
+EmitStmt(S.getInitSuspendStmt());
 
 CurCoro.Data->CurrentAwaitKind = AwaitKind::Normal;
 
@@ -410,7 +413,8 @@ void CodeGenFunction::EmitCoroutineBody(
 const bool HasCoreturns = CurCoro.Data->CoreturnCount > 0;
 if (CanFallthrough || HasCoreturns) {
   EmitBlock(FinalBB);
-  // FIXME: Emit final suspend.
+  CurCoro.Data->CurrentAwaitKind = AwaitKind::Final;
+  EmitStmt(S.getFinalSuspendStmt());
 }
   }
 

Modified: cfe/trunk/test/CodeGenCoroutines/coro-await.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCoroutines/coro-await.cpp?rev=303603&r1=303602&r2=303603&view=diff
==
--- cfe/trunk/test/CodeGenCoroutines/coro-await.cpp (original)
+++ cfe/trunk/test/CodeGenCoroutines/coro-await.cpp Tue May 23 00:04:01 2017
@@ -21,6 +21,17 @@ struct coroutine_handle : coroutine_hand
 }
 }
 
+struct init_susp {
+  bool await_ready();
+  void await_suspend(std::experimental::coroutine_handle<>);
+  void await_resume();
+};
+struct final_susp {
+  bool await_ready();
+  void await_suspend(std::experimental::coroutine_handle<>);
+  void await_resume();
+};
+
 struct suspend_always {
   int stuff;
   bool await_ready();
@@ -32,8 +43,8 @@ template<>
 struct std::experimental::coroutine_traits {
   struct promise_type {
 void get_return_object();
-suspend_always initial_suspend();
-suspend_always final_suspend();
+init_susp initial_suspend();
+final_susp final_suspend();
 void return_void();
   };
 };
@@ -42,6 +53,13 @@ struct std::experimental::coroutine_trai
 extern "C" void f0() {
   // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.begin(
 
+  // See if initial_suspend was issued:
+  // --
+  // CHECK: call void 
@_ZNSt12experimental16coroutine_traitsIJvEE12promise_type15initial_suspendEv(
+  // CHECK-NEXT: call zeroext i1 
@_ZN9init_susp11await_readyEv(%struct.init_susp*
+  // CHECK: %[[INITSP_ID:.+]] = call token @llvm.coro.save(
+  // CHECK: call i8 @llvm.coro.suspend(token %[[INITSP_ID]], i1 false)
+
   co_await suspend_always{};
   // See if we need to suspend:
   // --
@@ -76,6 +94,13 @@ extern "C" void f0() {
   // --
   // CHECK: [[READY_BB]]:
   // CHECK:  call void 
@_ZN14suspend_always12await_resumeEv(%struct.suspend_always* %[[AWAITABLE]])
+
+  // See if final_suspend was issued:
+  // --
+  // CHECK: call void 
@_ZNSt12experimental16coroutine_traitsIJvEE12promise_type13final_suspendEv(
+  // CHECK-NEXT: call zeroext i1 
@_ZN10final_susp11await_readyEv(%struct.final_susp*
+  // CHECK: %[[FINALSP_ID:.+]] = call token @llvm.coro.save(
+  // CHECK: call i8 @llvm.coro.suspend(token %[[FINALSP_ID]], i1 true)
 }
 
 struct suspend_maybe {
@@ -91,8 +116,8 @@ template<>
 struct std::experimental::coroutine_traits {
   struct promise_type {
 void get_return_object();
-suspend_always initial_suspend();
-suspend_always final_suspend();
+init_susp initial_suspend();
+final_susp final_suspend();
 void return_void();
 suspend_maybe yield_value(int);
   };
@@ -228,3 +253,21 @@ extern "C" void TestOpAwait() {
   // CHECK: call void @_ZN5MyAggawEv(%struct.MyAgg* %
   // CHECK: call void @_ZN11AggrAwaiter12await_resumeEv(%struct.Aggr* sret %
 }
+
+// CHECK-LABEL: EndlessLoop(
+extern "C" void EndlessLoop() {
+  // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.begin(
+
+  // See if initial_suspend was issued:
+  // --
+  // CHECK: call void 
@_ZNSt12experimental16coroutine_traitsIJvEE12promise_type15initial_suspendEv(
+  // CHECK-NEXT: call zeroext i1 
@_ZN9init_susp11await_readyEv(%struct.init_susp*
+
+  for (;;)
+co_await suspend_always{};
+
+  // Verify that final_suspend was NOT issued:
+  // --
+  // CHECK-NOT: call void 
@_ZNSt12experimental16coroutine_

[PATCH] D31590: [coroutines] Add support for deallocation elision

2017-05-22 Thread Gor Nishanov via Phabricator via cfe-commits
GorNishanov added a comment.

Commited: r303599 = abbd4f85db96b0ed1478e2ee52e9f1eec7404131


https://reviews.llvm.org/D31590



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r303599 - [coroutines] Add support for deallocation elision

2017-05-22 Thread Gor Nishanov via cfe-commits
Author: gornishanov
Date: Mon May 22 23:21:27 2017
New Revision: 303599

URL: http://llvm.org/viewvc/llvm-project?rev=303599&view=rev
Log:
[coroutines] Add support for deallocation elision

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.

Modified:
cfe/trunk/lib/CodeGen/CGCoroutine.cpp
cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp

Modified: cfe/trunk/lib/CodeGen/CGCoroutine.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCoroutine.cpp?rev=303599&r1=303598&r2=303599&view=diff
==
--- cfe/trunk/lib/CodeGen/CGCoroutine.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCoroutine.cpp Mon May 22 23:21:27 2017
@@ -62,6 +62,10 @@ struct clang::CodeGen::CGCoroData {
   // 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.
@@ -262,14 +266,47 @@ namespace {
 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) {}
 };
@@ -431,7 +468,7 @@ RValue CodeGenFunction::EmitCoroutineInt
   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.
@@ -442,5 +479,10 @@ RValue CodeGenFunction::EmitCoroutineInt
 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);
 }

Modified: cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp?rev=303599&r1=303598&r2=303599&view=diff
==
--- cfe/trunk/test/CodeGenCo

[PATCH] D31590: [coroutines] Add support for deallocation elision

2017-05-22 Thread Gor Nishanov via Phabricator via cfe-commits
GorNishanov accepted this revision.
GorNishanov added a comment.

LGTM


https://reviews.llvm.org/D31590



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33368: [libcxxabi][demangler] Fix a crash in the demangler

2017-05-22 Thread Saleem Abdulrasool via Phabricator via cfe-commits
compnerd added inline comments.



Comment at: src/cxa_demangle.cpp:3036
 break;
-if (db.names.size() < 2)
+if (k1 <= k0)
 return first;

erik.pilkington wrote:
> compnerd wrote:
> > I'm not sure how `k1` can be `<` than `k0`.  Isn't this effectively always 
> > going down the `==` path?  If I'm just mistaken, then I think that this 
> > needs a comment.
> I agree that it should be impossible, but the previous version handled this 
> case with the `if (db.names.size() < 2)` check, when really `db.names.size()` 
> can only be 1 or greater. I think it makes more sense to be paranoid here, I 
> trust this file about as far as I can throw it (And I can't throw it very 
> far, its not a tangible object).
Hmm, how about being paranoid, and converting that to an assertion and then 
doing the `==` check?  This code is already incredibly complicated, so adding 
additional things like this only makes it harder to understand whats going on.



Comment at: src/cxa_demangle.cpp:3042-3051
+for (size_t k = k0; k < k1; ++k) {
+auto tmp = db.names[k].move_full();
+if (!tmp.empty())
+{
+if (!is_first_it)
+db.names[lambda_pos].first.append(", ");
+is_first_it = false;

dexonsmith wrote:
> compnerd wrote:
> > I think that using a bit of algorithm here might be nice.
> > 
> > std::ostringstream oss(db.names[lambda_pos]);
> > std::copy_if(db.names[k0], db.names[k1], 
> > std::ostream_iterator(oss, ",  "),
> >  [](const std::string &s) -> bool { return !s.empty(); });
> Introducing a dependency on `std::ostream` would be awkward.  libc++abi.dylib 
> cannot link against libc++.dylib, and it would bloat libc++abi.dylib to use 
> custom traits to pull in a full copy.
Ugh, thats a good point.  Very well.  However, there doesnt seem to be any 
iterator invalidation here, so we can still just iterate over a slice here, 
which would be nicer.


https://reviews.llvm.org/D33368



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33259: Don't defer to the GCC driver for linking arm-baremetal

2017-05-22 Thread Saleem Abdulrasool via Phabricator via cfe-commits
compnerd added inline comments.



Comment at: lib/Driver/ToolChains/BareMetal.cpp:68
+  SmallString<128> Dir(getDriver().ResourceDir);
+  llvm::sys::path::append(Dir, "lib", "baremetal");
+  return Dir.str();

jroelofs wrote:
> compnerd wrote:
> > jroelofs wrote:
> > > compnerd wrote:
> > > > Why not just the standard `arm` directory?
> > > There are a few differences between the stuff in the existing ones, and 
> > > what is needed on baremetal. For example __enable_execute_stack, emutls, 
> > > as well as anything else that assumes existence of pthreads support 
> > > shouldn't be there.
> > Well, I think that "baremetal" here is a bad idea.  How about using the 
> > android approach?  Use `clang_rt.builtins-arm-baremetal.a` ?
> Why? Given the way the cmake goop works in lib/runtimes + compiler-rt, the 
> folder name there has to be the same as the CMAKE_SYSTEM_NAME. The 
> alternative, I guess, is to call it 'generic', but I'm not convinced that's 
> better than 'baremetal'.
Because I can have a baremetal environment that uses a different architecture.  
How do you differentiate between the MIPS and ARM bare metal runtimes?  The way 
that the compiler actually looks up the builtins is that it uses 
`clang_rt.[component]-[arch][-variant]`



Comment at: lib/Driver/ToolChains/BareMetal.h:42
+
+  const char *getDefaultLinker() const override { return "ld.lld"; }
+

ruiu wrote:
> jroelofs wrote:
> > compnerd wrote:
> > > jroelofs wrote:
> > > > compnerd wrote:
> > > > > I think that this really should be `ld` still, as that is the 
> > > > > canonical name for the linker.
> > > > You mean `lld`?
> > > > 
> > > > ```
> > > > $ lld
> > > > lld is a generic driver.
> > > > Invoke ld.lld (Unix), ld (macOS) or lld-link (Windows) instead.
> > > > ```
> > > > 
> > > > Or are you saying: "make binutils ld the default, not llvm's lld"?
> > > Im saying use the name "ld".  ld is a symlink on most linux distributions 
> > > these days.  ld -> ld.gold, ld.bfd, ld.lld
> > I don't think this makes sense. I don't care about "most linux 
> > distributions", but rather about putting together an LLVM baremetal 
> > distribution based as much as possible on LLVM components. If someone wants 
> > a different linker, they can use `-fuse-ld=` and/or `-B`.
> > 
> > Also, doesn't using a symlink named `ld` cause `lld` to behave like a 
> > mach-o linker? We really want the elf one here.
> If you invoke lld as ld, it behaves as a Mach-O linker on macOS. On other 
> OSes, it behaves as an ELF linker.
`ld` really is just the unix name for the linker.  I think that at some point 
we are going to have to consider cross-linking with lld.  Adding a `-flavor 
` with `-fuse-ld=lld` makes sense I think.


https://reviews.llvm.org/D33259



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31586: [coroutines] Replace all coro.frame builtins with an SSA value of coro.begin

2017-05-22 Thread Gor Nishanov via Phabricator via cfe-commits
GorNishanov accepted this revision.
GorNishanov added a comment.
This revision is now accepted and ready to land.

Committed: r303598 = cd8cc3ea48a887f846b3cbfc6dcb546a7b4de3af


https://reviews.llvm.org/D31586



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r303598 - [coroutines] Replace all coro.frame builtins with an SSA value of coro.begin

2017-05-22 Thread Gor Nishanov via cfe-commits
Author: gornishanov
Date: Mon May 22 22:46:59 2017
New Revision: 303598

URL: http://llvm.org/viewvc/llvm-project?rev=303598&view=rev
Log:
[coroutines] Replace all coro.frame builtins with an SSA value of coro.begin

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.

Modified:
cfe/trunk/lib/CodeGen/CGCoroutine.cpp
cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp
cfe/trunk/test/CodeGenCoroutines/coro-await.cpp
cfe/trunk/test/CodeGenCoroutines/coro-builtins.c

Modified: cfe/trunk/lib/CodeGen/CGCoroutine.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCoroutine.cpp?rev=303598&r1=303597&r2=303598&view=diff
==
--- cfe/trunk/lib/CodeGen/CGCoroutine.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCoroutine.cpp Mon May 22 22:46:59 2017
@@ -57,6 +57,11 @@ struct clang::CodeGen::CGCoroData {
   // builtin.
   llvm::CallInst *CoroId = nullptr;
 
+  // Stores the llvm.coro.begin emitted in the function so that we can replace
+  // all coro.frame intrinsics with direct SSA value of coro.begin that returns
+  // the address of the coroutine frame of the current coroutine.
+  llvm::CallInst *CoroBegin = 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.
@@ -330,8 +335,9 @@ void CodeGenFunction::EmitCoroutineBody(
   auto *Phi = Builder.CreatePHI(VoidPtrTy, 2);
   Phi->addIncoming(NullPtr, EntryBB);
   Phi->addIncoming(AllocateCall, AllocOrInvokeContBB);
-  Builder.CreateCall(
+  auto *CoroBegin = Builder.CreateCall(
   CGM.getIntrinsic(llvm::Intrinsic::coro_begin), {CoroId, Phi});
+  CurCoro.Data->CoroBegin = CoroBegin;
 
   CurCoro.Data->CleanupJD = getJumpDestInCurrentScope(RetBB);
   {
@@ -388,6 +394,17 @@ RValue CodeGenFunction::EmitCoroutineInt
   switch (IID) {
   default:
 break;
+  // The coro.frame builtin is replaced with an SSA value of the coro.begin
+  // intrinsic.
+  case llvm::Intrinsic::coro_frame: {
+if (CurCoro.Data && CurCoro.Data->CoroBegin) {
+  return RValue::get(CurCoro.Data->CoroBegin);
+}
+CGM.Error(E->getLocStart(), "this builtin expect that __builtin_coro_begin 
"
+  "has been used earlier in this function");
+auto NullPtr = llvm::ConstantPointerNull::get(Builder.getInt8PtrTy());
+return RValue::get(NullPtr);
+  }
   // The following three intrinsics take a token parameter referring to a token
   // returned by earlier call to @llvm.coro.id. Since we cannot represent it in
   // builtins, we patch it up here.
@@ -414,10 +431,16 @@ RValue CodeGenFunction::EmitCoroutineInt
   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
+  // 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.
   if (IID == llvm::Intrinsic::coro_id) {
 createCoroData(*this, CurCoro, Call, E);
   }
+  else if (IID == llvm::Intrinsic::coro_begin) {
+if (CurCoro.Data)
+  CurCoro.Data->CoroBegin = Call;
+  }
   return RValue::get(Call);
 }

Modified: cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp?rev=303598&r1=303597&r2=303598&view=diff
==
--- cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp (original)
+++ cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp Mon May 22 22:46:59 2017
@@ -66,9 +66,8 @@ extern "C" void f0(global_new_delete_tag
 
   // 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.begin(token %[[ID]], i8* 
%[[PHI]])
 
-  // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.frame()
   // CHECK: %[[MEM:.+]] = call i8* @llvm.coro.free(token %[[ID]], i8* 
%[[FRAME]])
   // CHECK: call void @_ZdlPv(i8* %[[MEM]])
   co_return;
@@ -93,7 +92,7 @@ extern "C" void f1(promise_new_tag ) {
   // CHECK: %[[SIZE:.+]] = call i64 @llvm.coro.size.i64()
   // CHECK: call i8* 
@_ZNSt12experimental16coroutine_traitsIJv15promise_new_tagEE12promise_typenwEm(i64
 %[[SIZE]])
 
-  // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.frame()
+  // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.begin(
   // CHECK: %[[MEM:.+]] = call i8* @llvm.coro.free(token %[[ID]], i8* 
%[[FRAME]])
   // CHECK: call void @_ZdlPv(i8* %[[MEM]])
   co_return;
@@ -118,7 +117,7 @@ ext

[PATCH] D31586: [coroutines] Replace all coro.frame builtins with an SSA value of coro.begin

2017-05-22 Thread Gor Nishanov via Phabricator via cfe-commits
GorNishanov updated this revision to Diff 99843.
GorNishanov added a comment.

merged with top of the trunk. preparing to land


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
@@ -66,9 +66,8 @@
 
   // 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.begin(token %[[ID]], i8* %[[PHI]])
 
-  // CHEC

[PATCH] D33430: [clang-tidy] Do not dereference a null BaseType

2017-05-22 Thread Chih-Hung Hsieh via Phabricator via cfe-commits
chh created this revision.
Herald added a subscriber: xazax.hun.

Check BaseType before dereference.
Simplified test case is derived from Android Open Source code.


https://reviews.llvm.org/D33430

Files:
  clang-tidy/misc/ForwardingReferenceOverloadCheck.cpp
  test/clang-tidy/misc-forwarding-reference-overload.cpp


Index: test/clang-tidy/misc-forwarding-reference-overload.cpp
===
--- test/clang-tidy/misc-forwarding-reference-overload.cpp
+++ test/clang-tidy/misc-forwarding-reference-overload.cpp
@@ -121,3 +121,25 @@
 private:
   Test6(const Test6 &rhs);
 };
+
+// Do not dereference a null BaseType.
+template  class result_of;
+template  class result_of<_Fp(_Args...)> { };
+template  using result_of_t = typename result_of<_Tp>::type;
+
+template  struct __overload;
+template 
+struct __overload<_Tp, _Types...> : __overload<_Types...> {
+  using __overload<_Types...>::operator();
+};
+
+template 
+using __best_match_t = typename 
result_of_t<__overload<_Types...>(_Tp&&)>::type;
+
+template 
+class variant {
+public:
+  template  >
+  constexpr variant(_Arg&& __arg) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: constructor accepting a 
forwarding reference can hide the copy and move constructors
+};
Index: clang-tidy/misc/ForwardingReferenceOverloadCheck.cpp
===
--- clang-tidy/misc/ForwardingReferenceOverloadCheck.cpp
+++ clang-tidy/misc/ForwardingReferenceOverloadCheck.cpp
@@ -40,6 +40,8 @@
   if (const auto *Dependent = BaseType->getAs()) {
 BaseType = Dependent->getQualifier()->getAsType();
   }
+  if (!BaseType)
+return false;
   if (CheckTemplate(BaseType->getAs())) {
 return true; // Case: enable_if_t< >.
   } else if (const auto *Elaborated = BaseType->getAs()) {


Index: test/clang-tidy/misc-forwarding-reference-overload.cpp
===
--- test/clang-tidy/misc-forwarding-reference-overload.cpp
+++ test/clang-tidy/misc-forwarding-reference-overload.cpp
@@ -121,3 +121,25 @@
 private:
   Test6(const Test6 &rhs);
 };
+
+// Do not dereference a null BaseType.
+template  class result_of;
+template  class result_of<_Fp(_Args...)> { };
+template  using result_of_t = typename result_of<_Tp>::type;
+
+template  struct __overload;
+template 
+struct __overload<_Tp, _Types...> : __overload<_Types...> {
+  using __overload<_Types...>::operator();
+};
+
+template 
+using __best_match_t = typename result_of_t<__overload<_Types...>(_Tp&&)>::type;
+
+template 
+class variant {
+public:
+  template  >
+  constexpr variant(_Arg&& __arg) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: constructor accepting a forwarding reference can hide the copy and move constructors
+};
Index: clang-tidy/misc/ForwardingReferenceOverloadCheck.cpp
===
--- clang-tidy/misc/ForwardingReferenceOverloadCheck.cpp
+++ clang-tidy/misc/ForwardingReferenceOverloadCheck.cpp
@@ -40,6 +40,8 @@
   if (const auto *Dependent = BaseType->getAs()) {
 BaseType = Dependent->getQualifier()->getAsType();
   }
+  if (!BaseType)
+return false;
   if (CheckTemplate(BaseType->getAs())) {
 return true; // Case: enable_if_t< >.
   } else if (const auto *Elaborated = BaseType->getAs()) {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31584: [coroutines] Add support for allocation elision

2017-05-22 Thread Gor Nishanov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL303596: [coroutines] Add support for allocation elision 
(authored by GorNishanov).

Changed prior to commit:
  https://reviews.llvm.org/D31584?vs=93805&id=99838#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D31584

Files:
  cfe/trunk/lib/CodeGen/CGCoroutine.cpp
  cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp


Index: cfe/trunk/lib/CodeGen/CGCoroutine.cpp
===
--- cfe/trunk/lib/CodeGen/CGCoroutine.cpp
+++ cfe/trunk/lib/CodeGen/CGCoroutine.cpp
@@ -284,6 +284,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");
 
@@ -293,12 +296,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);
@@ -308,9 +319,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: cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp
===
--- cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp
+++ cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp
@@ -56,8 +56,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: cfe/trunk/lib/CodeGen/CGCoroutine.cpp
===
--- cfe/trunk/lib/CodeGen/CGCoroutine.cpp
+++ cfe/trunk/lib/CodeGen/CGCoroutine.cpp
@@ -284,6 +284,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");
 
@@ -293,12 +296,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 = llv

r303596 - [coroutines] Add support for allocation elision

2017-05-22 Thread Gor Nishanov via cfe-commits
Author: gornishanov
Date: Mon May 22 20:13:17 2017
New Revision: 303596

URL: http://llvm.org/viewvc/llvm-project?rev=303596&view=rev
Log:
[coroutines] Add support for allocation elision

Summary:
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)
```

Reviewers: majnemer, EricWF

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D31584

Modified:
cfe/trunk/lib/CodeGen/CGCoroutine.cpp
cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp

Modified: cfe/trunk/lib/CodeGen/CGCoroutine.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCoroutine.cpp?rev=303596&r1=303595&r2=303596&view=diff
==
--- cfe/trunk/lib/CodeGen/CGCoroutine.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCoroutine.cpp Mon May 22 20:13:17 2017
@@ -284,6 +284,9 @@ void CodeGenFunction::EmitCoroutineBody(
   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");
 
@@ -293,12 +296,20 @@ void CodeGenFunction::EmitCoroutineBody(
   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);
@@ -308,9 +319,19 @@ void CodeGenFunction::EmitCoroutineBody(
 // 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);
   {

Modified: cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp?rev=303596&r1=303595&r2=303596&view=diff
==
--- cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp (original)
+++ cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp Mon May 22 20:13:17 2017
@@ -56,8 +56,17 @@ struct std::experimental::coroutine_trai
 // 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]])


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31414: [NFC, Refactor] Modernize TemplateIdAnnotation using TrailingObjects

2017-05-22 Thread Faisal Vali via Phabricator via cfe-commits
faisalv closed this revision.
faisalv added a comment.

Committed as https://reviews.llvm.org/rL303594


https://reviews.llvm.org/D31414



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r303594 - [NFC, Refactor] Modernize TemplateIdAnnotation using TrailingObjects

2017-05-22 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Mon May 22 20:07:12 2017
New Revision: 303594

URL: http://llvm.org/viewvc/llvm-project?rev=303594&view=rev
Log:
[NFC, Refactor] Modernize TemplateIdAnnotation using TrailingObjects

A refactoring of TemplateIdAnnotation that uses TrailingObjects to create a 
variably-sized object on the heap.

https://reviews.llvm.org/D31414

Thanks to Aaron B for the review!


Modified:
cfe/trunk/include/clang/Basic/TemplateKinds.h
cfe/trunk/include/clang/Sema/ParsedTemplate.h
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/lib/Parse/ParseTemplate.cpp

Modified: cfe/trunk/include/clang/Basic/TemplateKinds.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TemplateKinds.h?rev=303594&r1=303593&r2=303594&view=diff
==
--- cfe/trunk/include/clang/Basic/TemplateKinds.h (original)
+++ cfe/trunk/include/clang/Basic/TemplateKinds.h Mon May 22 20:07:12 2017
@@ -26,13 +26,21 @@ enum TemplateNameKind {
   TNK_Function_template,
   /// The name refers to a template whose specialization produces a
   /// type. The template itself could be a class template, template
-  /// template parameter, or C++0x template alias.
+  /// template parameter, or template alias.
   TNK_Type_template,
   /// The name refers to a variable template whose specialization produces a
   /// variable.
   TNK_Var_template,
-  /// The name refers to a dependent template name. Whether the
-  /// template name is assumed to refer to a type template or a
+  /// The name refers to a dependent template name: 
+  /// \code
+  /// template struct apply2 {
+  ///   typedef typename MetaFun::template apply::type type;
+  /// };
+  /// \endcode
+  ///
+  /// Here, "apply" is a dependent template name within the typename
+  /// specifier in the typedef. "apply" is a nested template, and 
+  /// whether the template name is assumed to refer to a type template or a
   /// function template depends on the context in which the template
   /// name occurs.
   TNK_Dependent_template_name

Modified: cfe/trunk/include/clang/Sema/ParsedTemplate.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ParsedTemplate.h?rev=303594&r1=303593&r2=303594&view=diff
==
--- cfe/trunk/include/clang/Sema/ParsedTemplate.h (original)
+++ cfe/trunk/include/clang/Sema/ParsedTemplate.h Mon May 22 20:07:12 2017
@@ -145,12 +145,15 @@ namespace clang {
   /// expressions, or template names, and the source locations for important 
   /// tokens. All of the information about template arguments is allocated 
   /// directly after this structure.
-  struct TemplateIdAnnotation {
+  struct TemplateIdAnnotation final
+  : private llvm::TrailingObjects {
+friend TrailingObjects;
 /// \brief The nested-name-specifier that precedes the template name.
 CXXScopeSpec SS;
 
-/// TemplateKWLoc - The location of the template keyword within the
-/// source.
+/// TemplateKWLoc - The location of the template keyword.
+/// For e.g. typename T::template Y
 SourceLocation TemplateKWLoc;
 
 /// TemplateNameLoc - The location of the template name within the
@@ -183,34 +186,56 @@ namespace clang {
 
 /// \brief Retrieves a pointer to the template arguments
 ParsedTemplateArgument *getTemplateArgs() { 
-  return reinterpret_cast(this + 1); 
+  return getTrailingObjects(); 
 }
 
 /// \brief Creates a new TemplateIdAnnotation with NumArgs arguments and
 /// appends it to List.
 static TemplateIdAnnotation *
-Allocate(unsigned NumArgs, SmallVectorImpl &List) {
-  TemplateIdAnnotation *TemplateId
-= (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) +
-  sizeof(ParsedTemplateArgument) * 
NumArgs);
-  TemplateId->NumArgs = NumArgs;
-  
-  // Default-construct nested-name-specifier.
-  new (&TemplateId->SS) CXXScopeSpec();
-  
-  // Default-construct parsed template arguments.
-  ParsedTemplateArgument *TemplateArgs = TemplateId->getTemplateArgs();
-  for (unsigned I = 0; I != NumArgs; ++I)
-new (TemplateArgs + I) ParsedTemplateArgument();
-  
-  List.push_back(TemplateId);
+Create(CXXScopeSpec SS, SourceLocation TemplateKWLoc,
+   SourceLocation TemplateNameLoc, IdentifierInfo *Name,
+   OverloadedOperatorKind OperatorKind,
+   ParsedTemplateTy OpaqueTemplateName, TemplateNameKind TemplateKind,
+   SourceLocation LAngleLoc, SourceLocation RAngleLoc,
+   ArrayRef TemplateArgs,
+   SmallVectorImpl &CleanupList) {
+
+  TemplateIdAnnotation *TemplateId = new (std::malloc(
+  totalSizeToAlloc(TemplateArgs.size(
+  TemplateIdAnnotation(SS, TemplateKWLoc, TemplateNameLoc, Name,
+   OperatorKind, OpaqueTemplateName, TemplateKi

[PATCH] D31670: [coroutines] Implement correct GRO lifetime

2017-05-22 Thread Gor Nishanov via Phabricator via cfe-commits
GorNishanov marked an inline comment as done.
GorNishanov added a comment.

@rsmith, better now? :)


https://reviews.llvm.org/D31670



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31670: [coroutines] Implement correct GRO lifetime

2017-05-22 Thread Gor Nishanov via Phabricator via cfe-commits
GorNishanov updated this revision to Diff 99837.
GorNishanov added a comment.

Remember old_top before emitting the cleanup and walk set Active on all emitted 
cleanups.
I tried to add Active flag to Emission, but it ended up being very hairy, so I 
went with the first option suggested.


https://reviews.llvm.org/D31670

Files:
  lib/CodeGen/CGCoroutine.cpp
  test/CodeGenCoroutines/coro-gro.cpp

Index: test/CodeGenCoroutines/coro-gro.cpp
===
--- /dev/null
+++ test/CodeGenCoroutines/coro-gro.cpp
@@ -0,0 +1,86 @@
+// Verifies lifetime of __gro local variable
+// Verify that coroutine promise and allocated memory are freed up on exception.
+// RUN: %clang_cc1 -std=c++1z -fcoroutines-ts -triple=x86_64-unknown-linux-gnu -emit-llvm -o - %s -disable-llvm-passes | FileCheck %s
+
+namespace std::experimental {
+template  struct coroutine_traits;
+
+template  struct coroutine_handle {
+  coroutine_handle() = default;
+  static coroutine_handle from_address(void *) noexcept;
+};
+template <> struct coroutine_handle {
+  static coroutine_handle from_address(void *) noexcept;
+  coroutine_handle() = default;
+  template 
+  coroutine_handle(coroutine_handle) noexcept;
+};
+}
+
+struct suspend_always {
+  bool await_ready() noexcept;
+  void await_suspend(std::experimental::coroutine_handle<>) noexcept;
+  void await_resume() noexcept;
+};
+
+struct GroType {
+  ~GroType();
+  operator int() noexcept;
+};
+
+template <> struct std::experimental::coroutine_traits {
+  struct promise_type {
+GroType get_return_object() noexcept;
+suspend_always initial_suspend() noexcept;
+suspend_always final_suspend() noexcept;
+void return_void() noexcept;
+promise_type();
+~promise_type();
+void unhandled_exception() noexcept;
+  };
+};
+
+struct Cleanup { ~Cleanup(); };
+void doSomething() noexcept;
+
+// CHECK: define i32 @_Z1fv(
+int f() {
+  // CHECK: %[[RetVal:.+]] = alloca i32
+  // CHECK: %[[GroActive:.+]] = alloca i1
+
+  // CHECK: %[[Size:.+]] = call i64 @llvm.coro.size.i64()
+  // CHECK: call i8* @_Znwm(i64 %[[Size]])
+  // CHECK: store i1 false, i1* %[[GroActive]]
+  // CHECK: call void @_ZNSt12experimental16coroutine_traitsIJiEE12promise_typeC1Ev(
+  // CHECK: call void @_ZNSt12experimental16coroutine_traitsIJiEE12promise_type17get_return_objectEv(
+  // CHECK: store i1 true, i1* %[[GroActive]]
+
+  Cleanup cleanup;
+  doSomething();
+  co_return;
+
+  // CHECK: call void @_Z11doSomethingv(
+  // CHECK: call void @_ZNSt12experimental16coroutine_traitsIJiEE12promise_type11return_voidEv(
+  // CHECK: call void @_ZN7CleanupD1Ev(
+
+  // Destroy promise and free the memory.
+
+  // CHECK: call void @_ZNSt12experimental16coroutine_traitsIJiEE12promise_typeD1Ev(
+  // CHECK: %[[Mem:.+]] = call i8* @llvm.coro.free(
+  // CHECK: call void @_ZdlPv(i8* %[[Mem]])
+
+  // Initialize retval from Gro and destroy Gro
+
+  // CHECK: %[[Conv:.+]] = call i32 @_ZN7GroTypecviEv(
+  // CHECK: store i32 %[[Conv]], i32* %[[RetVal]]
+  // CHECK: %[[IsActive:.+]] = load i1, i1* %[[GroActive]]
+  // CHECK: br i1 %[[IsActive]], label %[[CleanupGro:.+]], label %[[Done:.+]]
+
+  // CHECK: [[CleanupGro]]:
+  // CHECK:   call void @_ZN7GroTypeD1Ev(
+  // CHECK:   br label %[[Done]]
+
+  // CHECK: [[Done]]:
+  // CHECK:   %[[LoadRet:.+]] = load i32, i32* %[[RetVal]]
+  // CHECK:   ret i32 %[[LoadRet]]
+}
Index: lib/CodeGen/CGCoroutine.cpp
===
--- lib/CodeGen/CGCoroutine.cpp
+++ lib/CodeGen/CGCoroutine.cpp
@@ -11,6 +11,7 @@
 //
 //===--===//
 
+#include "CGCleanup.h"
 #include "CodeGenFunction.h"
 #include "llvm/ADT/ScopeExit.h"
 #include "clang/AST/StmtCXX.h"
@@ -270,6 +271,72 @@
 };
 }
 
+namespace {
+struct GetReturnObjectManager {
+  CodeGenFunction &CGF;
+  CGBuilderTy &Builder;
+  const CoroutineBodyStmt &S;
+
+  Address GroActiveFlag;
+  CodeGenFunction::AutoVarEmission GroEmission;
+
+  GetReturnObjectManager(CodeGenFunction &CGF, const CoroutineBodyStmt &S)
+  : CGF(CGF), Builder(CGF.Builder), S(S), GroActiveFlag(Address::invalid()),
+GroEmission(CodeGenFunction::AutoVarEmission::invalid()) {}
+
+  // The gro variable has to outlive coroutine frame and coroutine promise, but,
+  // it can only be initialized after coroutine promise was created, thus, we
+  // split its emission in two parts. EmitGroAlloca emits an alloca and sets up
+  // cleanups. Later when coroutine promise is available we initialize the gro
+  // and sets the flag that the cleanup is now active.
+
+  void EmitGroAlloca() {
+auto *GroDeclStmt = dyn_cast(S.getResultDecl());
+if (!GroDeclStmt) {
+  // If get_return_object returns void, no need to do an alloca.
+  return;
+}
+
+auto *GroVarDecl = cast(GroDeclStmt->getSingleDecl());
+
+// Set GRO flag that it is not initialized yet
+GroActiveFlag =
+  CGF.CreateTe

r303593 - Adjust clang test for r303590

2017-05-22 Thread Teresa Johnson via cfe-commits
Author: tejohnson
Date: Mon May 22 19:35:09 2017
New Revision: 303593

URL: http://llvm.org/viewvc/llvm-project?rev=303593&view=rev
Log:
Adjust clang test for r303590

Forgot to commit this separately from the llvm change to use a new
module flag type for pic and pie levels. Should fix the bot errors

Modified:
cfe/trunk/test/CodeGen/piclevels.c

Modified: cfe/trunk/test/CodeGen/piclevels.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/piclevels.c?rev=303593&r1=303592&r2=303593&view=diff
==
--- cfe/trunk/test/CodeGen/piclevels.c (original)
+++ cfe/trunk/test/CodeGen/piclevels.c Mon May 22 19:35:09 2017
@@ -1,7 +1,12 @@
-// RUN: %clang_cc1 -emit-llvm -pic-level 2 %s -o - | FileCheck %s 
-check-prefix=CHECK-BIGPIC
-// RUN: %clang_cc1 -emit-llvm -pic-level 1 %s -o - | FileCheck %s 
-check-prefix=CHECK-SMALLPIC
+// RUN: %clang_cc1 -emit-llvm -pic-level 2 %s -o - | FileCheck %s 
-check-prefix=CHECK-BIGPIC -check-prefix=CHECK-NOPIE
+// RUN: %clang_cc1 -emit-llvm -pic-level 1 %s -o - | FileCheck %s 
-check-prefix=CHECK-SMALLPIC -check-prefix=CHECK-NOPIE
+// RUN: %clang_cc1 -emit-llvm -pic-level 2 -pic-is-pie %s -o - | FileCheck %s 
-check-prefix=CHECK-BIGPIC -check-prefix=CHECK-BIGPIE
+// RUN: %clang_cc1 -emit-llvm -pic-level 1 -pic-is-pie %s -o - | FileCheck %s 
-check-prefix=CHECK-SMALLPIC -check-prefix=CHECK-SMALLPIE
 
 // CHECK-BIGPIC: !llvm.module.flags = !{{{.*}}}
-// CHECK-BIGPIC: !{{[0-9]+}} = !{i32 1, !"PIC Level", i32 2}
+// CHECK-BIGPIC: !{{[0-9]+}} = !{i32 7, !"PIC Level", i32 2}
 // CHECK-SMALLPIC: !llvm.module.flags = !{{{.*}}}
-// CHECK-SMALLPIC: !{{[0-9]+}} = !{i32 1, !"PIC Level", i32 1}
+// CHECK-SMALLPIC: !{{[0-9]+}} = !{i32 7, !"PIC Level", i32 1}
+// CHECK-NOPIE-NOT: PIE Level
+// CHECK-BIGPIE: !{{[0-9]+}} = !{i32 7, !"PIE Level", i32 2}
+// CHECK-SMALLPIE: !{{[0-9]+}} = !{i32 7, !"PIE Level", i32 1}


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33424: Lexer: allow imaginary constants in GNU mode (only).

2017-05-22 Thread Richard Smith via Phabricator via cfe-commits
rsmith added a comment.

Counterproposal: in `-std=*++14` onwards, treat this construct as a 
user-defined literal, but fall back on the built-in interpretation if name 
lookup doesn't find an `operator""i` function. (The two interpretations only 
conflict if the source code explicitly does something like `using namespace 
std::complex_literals;`, which seems like a pretty big clue that the user 
expected `1.0i`to be `std::complex` rather than `_Complex double`.)

If we find that's not enough for GCC compatibility in practice (perhaps in old 
code using `using namespace std;`), we can consider whether we want to make 
`-std=gnu++*` cause the built-in interpretation of the `i*` suffixes to be 
preferred over the overloaded interpretations.




Comment at: clang/lib/Lex/LiteralSupport.cpp:656
   // "i", "if", and "il" are user-defined suffixes in C++1y.
-  if (*s == 'i' && PP.getLangOpts().CPlusPlus14)
+  if (*s == 'i' && !PP.getLangOpts().GNUMode)
 break;

I'm unconvinced this is sufficient justification to remove this 
previously-supported extension from `-std=c*` and `-std=c++98` modes.


https://reviews.llvm.org/D33424



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r303589 - Add option to include multiple lines in snippets.

2017-05-22 Thread Richard Smith via cfe-commits
Author: rsmith
Date: Mon May 22 18:51:40 2017
New Revision: 303589

URL: http://llvm.org/viewvc/llvm-project?rev=303589&view=rev
Log:
Add option to include multiple lines in snippets.

When a diagnostic includes a highlighted range spanning multiple lines, clang
now supports printing out multiple lines of context if necessary to show the
highlighted ranges. This is not yet exposed in the driver, but can be enabled
by "-Xclang -fcaret-diagnostics-max-lines -Xclang N".

This is experimental until we can find out whether it works well in practice,
and if so, what a good default for the maximum number of lines is.

Added:
cfe/trunk/test/Misc/caret-diags-multiline.cpp
Modified:
cfe/trunk/include/clang/Basic/DiagnosticOptions.def
cfe/trunk/include/clang/Basic/DiagnosticOptions.h
cfe/trunk/include/clang/Driver/CC1Options.td
cfe/trunk/lib/Frontend/CompilerInvocation.cpp
cfe/trunk/lib/Frontend/TextDiagnostic.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticOptions.def
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticOptions.def?rev=303589&r1=303588&r2=303589&view=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticOptions.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticOptions.def Mon May 22 18:51:40 2017
@@ -87,6 +87,8 @@ VALUE_DIAGOPT(TemplateBacktraceLimit, 32
 VALUE_DIAGOPT(ConstexprBacktraceLimit, 32, DefaultConstexprBacktraceLimit)
 /// Limit number of times to perform spell checking.
 VALUE_DIAGOPT(SpellCheckingLimit, 32, DefaultSpellCheckingLimit)
+/// Limit number of lines shown in a snippet.
+VALUE_DIAGOPT(SnippetLineLimit, 32, DefaultSnippetLineLimit)
 
 VALUE_DIAGOPT(TabStop, 32, DefaultTabStop) /// The distance between tab stops.
 /// Column limit for formatting message diagnostics, or 0 if unused.

Modified: cfe/trunk/include/clang/Basic/DiagnosticOptions.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticOptions.h?rev=303589&r1=303588&r2=303589&view=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticOptions.h (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticOptions.h Mon May 22 18:51:40 2017
@@ -63,11 +63,15 @@ public:
   enum TextDiagnosticFormat { Clang, MSVC, Vi };
 
   // Default values.
-  enum { DefaultTabStop = 8, MaxTabStop = 100,
+  enum {
+DefaultTabStop = 8,
+MaxTabStop = 100,
 DefaultMacroBacktraceLimit = 6,
 DefaultTemplateBacktraceLimit = 10,
 DefaultConstexprBacktraceLimit = 10,
-DefaultSpellCheckingLimit = 50 };
+DefaultSpellCheckingLimit = 50,
+DefaultSnippetLineLimit = 1,
+  };
 
   // Define simple diagnostic options (with no accessors).
 #define DIAGOPT(Name, Bits, Default) unsigned Name : Bits;

Modified: cfe/trunk/include/clang/Driver/CC1Options.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=303589&r1=303588&r2=303589&view=diff
==
--- cfe/trunk/include/clang/Driver/CC1Options.td (original)
+++ cfe/trunk/include/clang/Driver/CC1Options.td Mon May 22 18:51:40 2017
@@ -359,6 +359,9 @@ def fconstexpr_backtrace_limit : Separat
   HelpText<"Set the maximum number of entries to print in a constexpr 
evaluation backtrace (0 = no limit).">;
 def fspell_checking_limit : Separate<["-"], "fspell-checking-limit">, 
MetaVarName<"">,
   HelpText<"Set the maximum number of times to perform spell checking on 
unrecognized identifiers (0 = no limit).">;
+def fcaret_diagnostics_max_lines :
+  Separate<["-"], "fcaret-diagnostics-max-lines">, MetaVarName<"">,
+  HelpText<"Set the maximum number of source lines to show in a caret 
diagnostic">;
 def fmessage_length : Separate<["-"], "fmessage-length">, MetaVarName<"">,
   HelpText<"Format message diagnostics so that they fit within N columns or 
fewer, when possible.">;
 def verify : Flag<["-"], "verify">,

Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=303589&r1=303588&r2=303589&view=diff
==
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Mon May 22 18:51:40 2017
@@ -1087,6 +1087,9 @@ bool clang::ParseDiagnosticArgs(Diagnost
   Opts.SpellCheckingLimit = getLastArgIntValue(
   Args, OPT_fspell_checking_limit,
   DiagnosticOptions::DefaultSpellCheckingLimit, Diags);
+  Opts.SnippetLineLimit = getLastArgIntValue(
+  Args, OPT_fcaret_diagnostics_max_lines,
+  DiagnosticOptions::DefaultSnippetLineLimit, Diags);
   Opts.TabStop = getLastArgIntValue(Args, OPT_ftabstop,
 DiagnosticOptions::DefaultTabStop, Diags);
   if (Opts.TabStop == 0 || Opts.TabStop > Di

Re: r303582 - Give files from #line the characteristics of the current file

2017-05-22 Thread Richard Smith via cfe-commits
On 22 May 2017 at 15:22, Reid Kleckner via cfe-commits <
cfe-commits@lists.llvm.org> wrote:

> On Mon, May 22, 2017 at 3:17 PM, Richard Smith 
> wrote:
>
>>// If the StrTok is "eod", then it wasn't present.  Otherwise, it must
>>> be a
>>>// string followed by eod.
>>> -  if (StrTok.is(tok::eod))
>>> -; // ok
>>> -  else if (StrTok.isNot(tok::string_literal)) {
>>> +  if (StrTok.is(tok::eod)) {
>>> +// Treat this like "#line NN", which doesn't change file
>>> characteristics.
>>> +FileKind = SourceMgr.getFileCharacteristic(DigitTok.getLocation());
>>>
>>
>> This change for "# " handling makes sense (and I've checked and
>> it matches GCC), but it looks like we don't have test coverage for either
>> the old or new behavior. Can I interest you in adding some? :)
>>
>
> We do have coverage for it, see test/Preprocessor/line-directive.c:
> """
> # 192 "glomp.h" 3 // System header.
> typedef int y;  // ok
> typedef int y;  // ok
>
> typedef int q;  // q is in system header.
>
> #line 42 "blonk.h"  // doesn't change system headerness.
>
> typedef int z;  // ok
> typedef int z;  // ok
>
> # 97 // doesn't change system headerness.
>
> typedef int z1;  // ok
> typedef int z1;  // ok
> """
>
> We were just getting similar behavior because of the code I removed that
> sends us to the #line directive handling when the filename isn't present.
>

Ah, I see. It looks like, prior to your change, we got self-inconsistent
results. "# " worked properly when compiling (and we do have
coverage for that, per the above test), but not when preprocessing (for
which we don't have test coverage). So for instance, this input:

# 1 "foo" 3
# 2
x

preprocesses as

# 1 "foo" 3
# 2 "foo"
x

before your change and as

# 1 "foo" 3
# 2 "foo" 3
x

after your change.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D30837: [libcxx] Support for shared_ptr

2017-05-22 Thread Erik Pilkington via Phabricator via cfe-commits
erik.pilkington added a comment.

Ping!


https://reviews.llvm.org/D30837



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r303584 - [coroutines] Fix coro-eh-cleanup.cpp test

2017-05-22 Thread Gor Nishanov via cfe-commits
Author: gornishanov
Date: Mon May 22 17:41:28 2017
New Revision: 303584

URL: http://llvm.org/viewvc/llvm-project?rev=303584&view=rev
Log:
[coroutines] Fix coro-eh-cleanup.cpp test

Modified:
cfe/trunk/test/CodeGenCoroutines/coro-eh-cleanup.cpp

Modified: cfe/trunk/test/CodeGenCoroutines/coro-eh-cleanup.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCoroutines/coro-eh-cleanup.cpp?rev=303584&r1=303583&r2=303584&view=diff
==
--- cfe/trunk/test/CodeGenCoroutines/coro-eh-cleanup.cpp (original)
+++ cfe/trunk/test/CodeGenCoroutines/coro-eh-cleanup.cpp Mon May 22 17:41:28 
2017
@@ -51,7 +51,7 @@ coro_t f() {
 // CHECK: [[EHCLEANUP]]:
 // CHECK:   %[[INNERPAD:.+]] = cleanuppad within none []
 // CHECK:   call void @"\01??_DCleanup@@QEAAXXZ"(
-// CHECK:   cleanupret from %4 unwind label %[[CATCHDISPATCH:.+]]
+// CHECK:   cleanupret from %{{.+}} unwind label %[[CATCHDISPATCH:.+]]
 
 // CHECK: [[CATCHDISPATCH]]:
 // CHECK:   catchswitch within none [label %[[CATCHPAD:.+]]] unwind label 
%[[COROENDBB:.+]]


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31692: [coroutines] Wrap the body of the coroutine in try-catch

2017-05-22 Thread Gor Nishanov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL303583: [coroutines] Wrap the body of the coroutine in 
try-catch (authored by GorNishanov).

Changed prior to commit:
  https://reviews.llvm.org/D31692?vs=99815&id=99827#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D31692

Files:
  cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
  cfe/trunk/lib/CodeGen/CGCoroutine.cpp
  cfe/trunk/lib/Sema/SemaCoroutine.cpp
  cfe/trunk/test/CodeGenCoroutines/coro-cleanup.cpp
  cfe/trunk/test/CodeGenCoroutines/coro-eh-cleanup.cpp
  cfe/trunk/test/SemaCXX/coroutine-seh.cpp

Index: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
===
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8960,6 +8960,8 @@
   InGroup;
 def err_coroutine_promise_get_return_object_on_allocation_failure : Error<
   "%0: 'get_return_object_on_allocation_failure()' must be a static member function">;
+def err_seh_in_a_coroutine_with_cxx_exceptions : Error<
+  "cannot use SEH '__try' in a coroutine when C++ exceptions are enabled">;
 def err_coroutine_promise_new_requires_nothrow : Error<
   "%0 is required to have a non-throwing noexcept specification when the promise "
"type declares 'get_return_object_on_allocation_failure()'">;
Index: cfe/trunk/test/SemaCXX/coroutine-seh.cpp
===
--- cfe/trunk/test/SemaCXX/coroutine-seh.cpp
+++ cfe/trunk/test/SemaCXX/coroutine-seh.cpp
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -std=c++1z -fcoroutines-ts -verify %s -fcxx-exceptions -fexceptions -triple x86_64-windows-msvc -fms-extensions
+namespace std::experimental {
+template  struct coroutine_traits;
+
+template  struct coroutine_handle {
+  coroutine_handle() = default;
+  static coroutine_handle from_address(void *) noexcept;
+};
+template <> struct coroutine_handle {
+  static coroutine_handle from_address(void *) noexcept;
+  coroutine_handle() = default;
+  template 
+  coroutine_handle(coroutine_handle) noexcept;
+};
+}
+
+struct suspend_always {
+  bool await_ready() noexcept;
+  void await_suspend(std::experimental::coroutine_handle<>) noexcept;
+  void await_resume() noexcept;
+};
+
+template <> struct std::experimental::coroutine_traits {
+  struct promise_type {
+void get_return_object() noexcept;
+suspend_always initial_suspend() noexcept;
+suspend_always final_suspend() noexcept;
+void return_void() noexcept;
+void unhandled_exception() noexcept;
+  };
+};
+
+void SEH_used() {
+  __try { // expected-error {{cannot use SEH '__try' in a coroutine when C++ exceptions are enabled}}
+co_return; // expected-note {{function is a coroutine due to use of 'co_return' here}}
+  } __except(0) {}
+}
Index: cfe/trunk/test/CodeGenCoroutines/coro-cleanup.cpp
===
--- cfe/trunk/test/CodeGenCoroutines/coro-cleanup.cpp
+++ cfe/trunk/test/CodeGenCoroutines/coro-cleanup.cpp
@@ -6,38 +6,38 @@
 
 template  struct coroutine_handle {
   coroutine_handle() = default;
-  static coroutine_handle from_address(void *) { return {}; }
+  static coroutine_handle from_address(void *) noexcept;
 };
 template <> struct coroutine_handle {
-  static coroutine_handle from_address(void *) { return {}; }
+  static coroutine_handle from_address(void *) noexcept;
   coroutine_handle() = default;
   template 
-  coroutine_handle(coroutine_handle) {}
+  coroutine_handle(coroutine_handle) noexcept;
 };
 }
 
 struct suspend_always {
-  bool await_ready();
-  void await_suspend(std::experimental::coroutine_handle<>);
-  void await_resume();
+  bool await_ready() noexcept;
+  void await_suspend(std::experimental::coroutine_handle<>) noexcept;
+  void await_resume() noexcept;
 };
 
 template <> struct std::experimental::coroutine_traits {
   struct promise_type {
-void get_return_object();
-suspend_always initial_suspend();
-suspend_always final_suspend();
-void return_void();
+void get_return_object() noexcept;
+suspend_always initial_suspend() noexcept;
+suspend_always final_suspend() noexcept;
+void return_void() noexcept;
 promise_type();
 ~promise_type();
-void unhandled_exception();
+void unhandled_exception() noexcept;
   };
 };
 
 struct Cleanup { ~Cleanup(); };
 void may_throw();
 
-// CHECK: define void @_Z1fv(
+// CHECK-LABEL: define void @_Z1fv(
 void f() {
   // CHECK: call i8* @_Znwm(i64
 
@@ -52,23 +52,46 @@
   // if may_throw throws, check that we destroy the promise and free the memory.
 
   // CHECK: invoke void @_Z9may_throwv(
-  // CHECK-NEXT: to label %{{.+}} unwind label %[[PromDtorPad:.+]]
+  // CHECK-NEXT: to label %{{.+}} unwind label %[[CatchPad:.+]]
 
   // CHECK: [[DeallocPad]]:
   // CHECK-NEXT: landingpad
   // CHECK-NEXT:   cleanup
   // CHECK: br label %[[Dealloc:.+]]
 
-  // CHECK: [[PromD

r303583 - [coroutines] Wrap the body of the coroutine in try-catch

2017-05-22 Thread Gor Nishanov via cfe-commits
Author: gornishanov
Date: Mon May 22 17:33:17 2017
New Revision: 303583

URL: http://llvm.org/viewvc/llvm-project?rev=303583&view=rev
Log:
[coroutines] Wrap the body of the coroutine in try-catch

Summary:
If unhandled_exception member function is present in the coroutine promise,
wrap the body of the coroutine in:

```
try {
  body
} catch(...) { promise.unhandled_exception(); }
```

Reviewers: EricWF, rnk, rsmith

Reviewed By: rsmith

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D31692

Added:
cfe/trunk/test/SemaCXX/coroutine-seh.cpp
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/CodeGen/CGCoroutine.cpp
cfe/trunk/lib/Sema/SemaCoroutine.cpp
cfe/trunk/test/CodeGenCoroutines/coro-cleanup.cpp
cfe/trunk/test/CodeGenCoroutines/coro-eh-cleanup.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=303583&r1=303582&r2=303583&view=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon May 22 17:33:17 
2017
@@ -8960,6 +8960,8 @@ def warn_coroutine_promise_unhandled_exc
   InGroup;
 def err_coroutine_promise_get_return_object_on_allocation_failure : Error<
   "%0: 'get_return_object_on_allocation_failure()' must be a static member 
function">;
+def err_seh_in_a_coroutine_with_cxx_exceptions : Error<
+  "cannot use SEH '__try' in a coroutine when C++ exceptions are enabled">;
 def err_coroutine_promise_new_requires_nothrow : Error<
   "%0 is required to have a non-throwing noexcept specification when the 
promise "
"type declares 'get_return_object_on_allocation_failure()'">;

Modified: cfe/trunk/lib/CodeGen/CGCoroutine.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCoroutine.cpp?rev=303583&r1=303582&r2=303583&view=diff
==
--- cfe/trunk/lib/CodeGen/CGCoroutine.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCoroutine.cpp Mon May 22 17:33:17 2017
@@ -270,6 +270,15 @@ struct CallCoroDelete final : public EHS
 };
 }
 
+static void emitBodyAndFallthrough(CodeGenFunction &CGF,
+   const CoroutineBodyStmt &S, Stmt *Body) {
+  CGF.EmitStmt(Body);
+  const bool CanFallthrough = CGF.Builder.GetInsertBlock();
+  if (CanFallthrough)
+if (Stmt *OnFallthrough = S.getFallthroughHandler())
+  CGF.EmitStmt(OnFallthrough);
+}
+
 void CodeGenFunction::EmitCoroutineBody(const CoroutineBodyStmt &S) {
   auto *NullPtr = llvm::ConstantPointerNull::get(Builder.getInt8PtrTy());
   auto &TI = CGM.getContext().getTargetInfo();
@@ -318,7 +327,19 @@ void CodeGenFunction::EmitCoroutineBody(
 // FIXME: Emit initial suspend and more before the body.
 
 CurCoro.Data->CurrentAwaitKind = AwaitKind::Normal;
-EmitStmt(S.getBody());
+
+if (auto *OnException = S.getExceptionHandler()) {
+  auto Loc = S.getLocStart();
+  CXXCatchStmt Catch(Loc, /*exDecl=*/nullptr, OnException);
+  auto *TryStmt = CXXTryStmt::Create(getContext(), Loc, S.getBody(), 
&Catch);
+
+  EnterCXXTryStmt(*TryStmt);
+  emitBodyAndFallthrough(*this, S, TryStmt->getTryBlock());
+  ExitCXXTryStmt(*TryStmt);
+}
+else {
+  emitBodyAndFallthrough(*this, S, S.getBody());
+}
 
 // See if we need to generate final suspend.
 const bool CanFallthrough = Builder.GetInsertBlock();

Modified: cfe/trunk/lib/Sema/SemaCoroutine.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCoroutine.cpp?rev=303583&r1=303582&r2=303583&view=diff
==
--- cfe/trunk/lib/Sema/SemaCoroutine.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCoroutine.cpp Mon May 22 17:33:17 2017
@@ -1043,6 +1043,15 @@ bool CoroutineStmtBuilder::makeOnExcepti
   if (UnhandledException.isInvalid())
 return false;
 
+  // Since the body of the coroutine will be wrapped in try-catch, it will
+  // be incompatible with SEH __try if present in a function.
+  if (!S.getLangOpts().Borland && Fn.FirstSEHTryLoc.isValid()) {
+S.Diag(Fn.FirstSEHTryLoc, 
diag::err_seh_in_a_coroutine_with_cxx_exceptions);
+S.Diag(Fn.FirstCoroutineStmtLoc, diag::note_declared_coroutine_here)
+<< Fn.getFirstCoroutineStmtKeyword();
+return false;
+  }
+
   this->OnException = UnhandledException.get();
   return true;
 }

Modified: cfe/trunk/test/CodeGenCoroutines/coro-cleanup.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCoroutines/coro-cleanup.cpp?rev=303583&r1=303582&r2=303583&view=diff
==
--- cfe/trunk/test/CodeGenCoroutines/coro-cleanup.cpp (original)
+++ cfe/trunk/test/CodeGenCoroutines/coro-cleanup.cpp Mon May 22 17

[PATCH] D33424: Lexer: allow imaginary constants in GNU mode (only).

2017-05-22 Thread Tim Northover via Phabricator via cfe-commits
t.p.northover created this revision.
Herald added a subscriber: mcrosier.

While looking into the regression tests' compatibility with C++14, many of the 
failures were because that specification defined UDLs for imaginary constants, 
specifically ones ending in 'i' and 'il'. This conflicted with the previous GNU 
extension that allowed them purely as a builtin literal syntax so they'd been 
disabled in C++14 mode.

GCC's behaviour is to use the builtin constants in all "-std=gnu++N" modes but 
disable them for "-std=c++11" and "-std=c++14" (they are still permitted in 
"-std=c++98"). This seemed inconsistent (and likely an implementation detail 
rather than intended behaviour) so my patch makes the decision purely on 
whether we're in GNU mode.

Does it look reasonable?

Tim.


https://reviews.llvm.org/D33424

Files:
  clang/lib/Lex/LiteralSupport.cpp
  clang/test/SemaCXX/constexpr-printing.cpp
  clang/unittests/AST/DeclTest.cpp


Index: clang/unittests/AST/DeclTest.cpp
===
--- clang/unittests/AST/DeclTest.cpp
+++ clang/unittests/AST/DeclTest.cpp
@@ -26,7 +26,7 @@
   // This is a regression test for a memory leak in APValues for structs that
   // allocate memory. This test only fails if run under valgrind with full leak
   // checking enabled.
-  std::vector Args(1, "-std=c++11");
+  std::vector Args(1, "-std=gnu++11");
   Args.push_back("-fno-ms-extensions");
   ASSERT_TRUE(runToolOnCodeWithArgs(
   Factory->create(),
Index: clang/test/SemaCXX/constexpr-printing.cpp
===
--- clang/test/SemaCXX/constexpr-printing.cpp
+++ clang/test/SemaCXX/constexpr-printing.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -std=c++11 -fsyntax-only -verify -triple x86_64-linux-gnu
+// RUN: %clang_cc1 %s -std=gnu++11 -fsyntax-only -verify -triple 
x86_64-linux-gnu
 
 struct S;
 constexpr int extract(const S &s);
Index: clang/lib/Lex/LiteralSupport.cpp
===
--- clang/lib/Lex/LiteralSupport.cpp
+++ clang/lib/Lex/LiteralSupport.cpp
@@ -653,7 +653,7 @@
 }
   }
   // "i", "if", and "il" are user-defined suffixes in C++1y.
-  if (*s == 'i' && PP.getLangOpts().CPlusPlus14)
+  if (*s == 'i' && !PP.getLangOpts().GNUMode)
 break;
   // fall through.
 case 'j':


Index: clang/unittests/AST/DeclTest.cpp
===
--- clang/unittests/AST/DeclTest.cpp
+++ clang/unittests/AST/DeclTest.cpp
@@ -26,7 +26,7 @@
   // This is a regression test for a memory leak in APValues for structs that
   // allocate memory. This test only fails if run under valgrind with full leak
   // checking enabled.
-  std::vector Args(1, "-std=c++11");
+  std::vector Args(1, "-std=gnu++11");
   Args.push_back("-fno-ms-extensions");
   ASSERT_TRUE(runToolOnCodeWithArgs(
   Factory->create(),
Index: clang/test/SemaCXX/constexpr-printing.cpp
===
--- clang/test/SemaCXX/constexpr-printing.cpp
+++ clang/test/SemaCXX/constexpr-printing.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -std=c++11 -fsyntax-only -verify -triple x86_64-linux-gnu
+// RUN: %clang_cc1 %s -std=gnu++11 -fsyntax-only -verify -triple x86_64-linux-gnu
 
 struct S;
 constexpr int extract(const S &s);
Index: clang/lib/Lex/LiteralSupport.cpp
===
--- clang/lib/Lex/LiteralSupport.cpp
+++ clang/lib/Lex/LiteralSupport.cpp
@@ -653,7 +653,7 @@
 }
   }
   // "i", "if", and "il" are user-defined suffixes in C++1y.
-  if (*s == 'i' && PP.getLangOpts().CPlusPlus14)
+  if (*s == 'i' && !PP.getLangOpts().GNUMode)
 break;
   // fall through.
 case 'j':
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: r303582 - Give files from #line the characteristics of the current file

2017-05-22 Thread Reid Kleckner via cfe-commits
On Mon, May 22, 2017 at 3:17 PM, Richard Smith 
wrote:

>// If the StrTok is "eod", then it wasn't present.  Otherwise, it must
>> be a
>>// string followed by eod.
>> -  if (StrTok.is(tok::eod))
>> -; // ok
>> -  else if (StrTok.isNot(tok::string_literal)) {
>> +  if (StrTok.is(tok::eod)) {
>> +// Treat this like "#line NN", which doesn't change file
>> characteristics.
>> +FileKind = SourceMgr.getFileCharacteristic(DigitTok.getLocation());
>>
>
> This change for "# " handling makes sense (and I've checked and it
> matches GCC), but it looks like we don't have test coverage for either the
> old or new behavior. Can I interest you in adding some? :)
>

We do have coverage for it, see test/Preprocessor/line-directive.c:
"""
# 192 "glomp.h" 3 // System header.
typedef int y;  // ok
typedef int y;  // ok

typedef int q;  // q is in system header.

#line 42 "blonk.h"  // doesn't change system headerness.

typedef int z;  // ok
typedef int z;  // ok

# 97 // doesn't change system headerness.

typedef int z1;  // ok
typedef int z1;  // ok
"""

We were just getting similar behavior because of the code I removed that
sends us to the #line directive handling when the filename isn't present.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: r303582 - Give files from #line the characteristics of the current file

2017-05-22 Thread Richard Smith via cfe-commits
On 22 May 2017 at 14:42, Reid Kleckner via cfe-commits <
cfe-commits@lists.llvm.org> wrote:

> Author: rnk
> Date: Mon May 22 16:42:58 2017
> New Revision: 303582
>
> URL: http://llvm.org/viewvc/llvm-project?rev=303582&view=rev
> Log:
> Give files from #line the characteristics of the current file
>
> This allows #line directives to appear in system headers that have code
> that clang would normally warn on. This is compatible with GCC, which is
> easy to test by running `gcc -E`.
>
> Fixes PR30752
>
> Added:
> cfe/trunk/test/Frontend/Inputs/SystemHeaderPrefix/line.h
> cfe/trunk/test/Frontend/Inputs/SystemHeaderPrefix/noline.h
> cfe/trunk/test/Frontend/system-header-line-directive.c
> Modified:
> cfe/trunk/include/clang/Basic/SourceManager.h
> cfe/trunk/include/clang/Basic/SourceManagerInternals.h
> cfe/trunk/lib/Basic/SourceManager.cpp
> cfe/trunk/lib/Frontend/FrontendAction.cpp
> cfe/trunk/lib/Lex/PPDirectives.cpp
> cfe/trunk/lib/Lex/Pragma.cpp
>
> Modified: cfe/trunk/include/clang/Basic/SourceManager.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
> clang/Basic/SourceManager.h?rev=303582&r1=303581&r2=303582&view=diff
> 
> ==
> --- cfe/trunk/include/clang/Basic/SourceManager.h (original)
> +++ cfe/trunk/include/clang/Basic/SourceManager.h Mon May 22 16:42:58 2017
> @@ -1399,10 +1399,9 @@ public:
>/// specified by Loc.
>///
>/// If FilenameID is -1, it is considered to be unspecified.
> -  void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID);
>void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID,
> bool IsFileEntry, bool IsFileExit,
> -   bool IsSystemHeader, bool IsExternCHeader);
> +   SrcMgr::CharacteristicKind FileKind);
>
>/// \brief Determine if the source manager has a line table.
>bool hasLineTable() const { return LineTable != nullptr; }
>
> Modified: cfe/trunk/include/clang/Basic/SourceManagerInternals.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/
> SourceManagerInternals.h?rev=303582&r1=303581&r2=303582&view=diff
> 
> ==
> --- cfe/trunk/include/clang/Basic/SourceManagerInternals.h (original)
> +++ cfe/trunk/include/clang/Basic/SourceManagerInternals.h Mon May 22
> 16:42:58 2017
> @@ -102,8 +102,6 @@ public:
>unsigned getNumFilenames() const { return FilenamesByID.size(); }
>
>void AddLineNote(FileID FID, unsigned Offset,
> -   unsigned LineNo, int FilenameID);
> -  void AddLineNote(FileID FID, unsigned Offset,
> unsigned LineNo, int FilenameID,
> unsigned EntryExit, SrcMgr::CharacteristicKind
> FileKind);
>
>
> Modified: cfe/trunk/lib/Basic/SourceManager.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/
> SourceManager.cpp?rev=303582&r1=303581&r2=303582&view=diff
> 
> ==
> --- cfe/trunk/lib/Basic/SourceManager.cpp (original)
> +++ cfe/trunk/lib/Basic/SourceManager.cpp Mon May 22 16:42:58 2017
> @@ -183,48 +183,22 @@ unsigned LineTableInfo::getLineTableFile
>return IterBool.first->second;
>  }
>
> -/// AddLineNote - Add a line note to the line table that indicates that
> there
> -/// is a \#line at the specified FID/Offset location which changes the
> presumed
> -/// location to LineNo/FilenameID.
> -void LineTableInfo::AddLineNote(FileID FID, unsigned Offset,
> -unsigned LineNo, int FilenameID) {
> -  std::vector &Entries = LineEntries[FID];
> -
> -  assert((Entries.empty() || Entries.back().FileOffset < Offset) &&
> - "Adding line entries out of order!");
> -
> -  SrcMgr::CharacteristicKind Kind = SrcMgr::C_User;
> -  unsigned IncludeOffset = 0;
> -
> -  if (!Entries.empty()) {
> -// If this is a '#line 4' after '#line 42 "foo.h"', make sure to
> remember
> -// that we are still in "foo.h".
> -if (FilenameID == -1)
> -  FilenameID = Entries.back().FilenameID;
> -
> -// If we are after a line marker that switched us to system header
> mode, or
> -// that set #include information, preserve it.
> -Kind = Entries.back().FileKind;
> -IncludeOffset = Entries.back().IncludeOffset;
> -  }
> -
> -  Entries.push_back(LineEntry::get(Offset, LineNo, FilenameID, Kind,
> -   IncludeOffset));
> -}
> -
> -/// AddLineNote This is the same as the previous version of AddLineNote,
> but is
> -/// used for GNU line markers.  If EntryExit is 0, then this doesn't
> change the
> -/// presumed \#include stack.  If it is 1, this is a file entry, if it is
> 2 then
> -/// this is a file exit.  FileKind specifies whether this is a system
> header or
> -/// extern C system header.
> -void LineTableInfo::AddLineNote(FileID FID

[PATCH] D31692: [coroutines] Wrap the body of the coroutine in try-catch

2017-05-22 Thread Richard Smith via Phabricator via cfe-commits
rsmith accepted this revision.
rsmith added a comment.
This revision is now accepted and ready to land.

LGTM


https://reviews.llvm.org/D31692



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33398: Remove __unaligned preventively when mangling types in Itanium ABI

2017-05-22 Thread Richard Smith via Phabricator via cfe-commits
rsmith added inline comments.



Comment at: lib/AST/ItaniumMangle.cpp:2329-2333
+  // __unaligned is not currently mangled in any way. This implies that it is
+  // not a relevant qualifier for substitutions (while CVR and maybe others
+  // are). This triggers an assertion when this is the only qualifier and the
+  // unqualified type is a class. So let's remove it preventively here.
+  quals.removeUnaligned();

I don't think this is the right place/way to handle this: given

```
void f(struct X __unaligned *p, struct X *q) {}
```

it looks like we'll mangle as `_Z1fP1XP1X` with this patch, which seems wrong: 
this should presumably instead be `_Z1fP1XS0_`.

But regardless, I think the right thing to do is to invent a mangling for 
`__unaligned`, since we support overloading on it; the most appropriate 
mangling would be `U11__unaligned`, per 
http://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling-type. (You'll need 
to extend `mangleQualifiers` to emit this and 
`hasMangledSubstitutionQualifiers` to ignore it.)


https://reviews.llvm.org/D33398



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r303582 - Give files from #line the characteristics of the current file

2017-05-22 Thread Reid Kleckner via cfe-commits
Author: rnk
Date: Mon May 22 16:42:58 2017
New Revision: 303582

URL: http://llvm.org/viewvc/llvm-project?rev=303582&view=rev
Log:
Give files from #line the characteristics of the current file

This allows #line directives to appear in system headers that have code
that clang would normally warn on. This is compatible with GCC, which is
easy to test by running `gcc -E`.

Fixes PR30752

Added:
cfe/trunk/test/Frontend/Inputs/SystemHeaderPrefix/line.h
cfe/trunk/test/Frontend/Inputs/SystemHeaderPrefix/noline.h
cfe/trunk/test/Frontend/system-header-line-directive.c
Modified:
cfe/trunk/include/clang/Basic/SourceManager.h
cfe/trunk/include/clang/Basic/SourceManagerInternals.h
cfe/trunk/lib/Basic/SourceManager.cpp
cfe/trunk/lib/Frontend/FrontendAction.cpp
cfe/trunk/lib/Lex/PPDirectives.cpp
cfe/trunk/lib/Lex/Pragma.cpp

Modified: cfe/trunk/include/clang/Basic/SourceManager.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/SourceManager.h?rev=303582&r1=303581&r2=303582&view=diff
==
--- cfe/trunk/include/clang/Basic/SourceManager.h (original)
+++ cfe/trunk/include/clang/Basic/SourceManager.h Mon May 22 16:42:58 2017
@@ -1399,10 +1399,9 @@ public:
   /// specified by Loc.
   ///
   /// If FilenameID is -1, it is considered to be unspecified.
-  void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID);
   void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID,
bool IsFileEntry, bool IsFileExit,
-   bool IsSystemHeader, bool IsExternCHeader);
+   SrcMgr::CharacteristicKind FileKind);
 
   /// \brief Determine if the source manager has a line table.
   bool hasLineTable() const { return LineTable != nullptr; }

Modified: cfe/trunk/include/clang/Basic/SourceManagerInternals.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/SourceManagerInternals.h?rev=303582&r1=303581&r2=303582&view=diff
==
--- cfe/trunk/include/clang/Basic/SourceManagerInternals.h (original)
+++ cfe/trunk/include/clang/Basic/SourceManagerInternals.h Mon May 22 16:42:58 
2017
@@ -102,8 +102,6 @@ public:
   unsigned getNumFilenames() const { return FilenamesByID.size(); }
 
   void AddLineNote(FileID FID, unsigned Offset,
-   unsigned LineNo, int FilenameID);
-  void AddLineNote(FileID FID, unsigned Offset,
unsigned LineNo, int FilenameID,
unsigned EntryExit, SrcMgr::CharacteristicKind FileKind);
 

Modified: cfe/trunk/lib/Basic/SourceManager.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/SourceManager.cpp?rev=303582&r1=303581&r2=303582&view=diff
==
--- cfe/trunk/lib/Basic/SourceManager.cpp (original)
+++ cfe/trunk/lib/Basic/SourceManager.cpp Mon May 22 16:42:58 2017
@@ -183,48 +183,22 @@ unsigned LineTableInfo::getLineTableFile
   return IterBool.first->second;
 }
 
-/// AddLineNote - Add a line note to the line table that indicates that there
-/// is a \#line at the specified FID/Offset location which changes the presumed
-/// location to LineNo/FilenameID.
-void LineTableInfo::AddLineNote(FileID FID, unsigned Offset,
-unsigned LineNo, int FilenameID) {
-  std::vector &Entries = LineEntries[FID];
-
-  assert((Entries.empty() || Entries.back().FileOffset < Offset) &&
- "Adding line entries out of order!");
-
-  SrcMgr::CharacteristicKind Kind = SrcMgr::C_User;
-  unsigned IncludeOffset = 0;
-
-  if (!Entries.empty()) {
-// If this is a '#line 4' after '#line 42 "foo.h"', make sure to remember
-// that we are still in "foo.h".
-if (FilenameID == -1)
-  FilenameID = Entries.back().FilenameID;
-
-// If we are after a line marker that switched us to system header mode, or
-// that set #include information, preserve it.
-Kind = Entries.back().FileKind;
-IncludeOffset = Entries.back().IncludeOffset;
-  }
-
-  Entries.push_back(LineEntry::get(Offset, LineNo, FilenameID, Kind,
-   IncludeOffset));
-}
-
-/// AddLineNote This is the same as the previous version of AddLineNote, but is
-/// used for GNU line markers.  If EntryExit is 0, then this doesn't change the
-/// presumed \#include stack.  If it is 1, this is a file entry, if it is 2 
then
-/// this is a file exit.  FileKind specifies whether this is a system header or
-/// extern C system header.
-void LineTableInfo::AddLineNote(FileID FID, unsigned Offset,
-unsigned LineNo, int FilenameID,
-unsigned EntryExit,
+/// Add a line note to the line table that indicates that there is a \#line or
+/// GNU line marker at the specified FID/Offset location which changes the
+/// presumed location 

[PATCH] D31692: [coroutines] Wrap the body of the coroutine in try-catch

2017-05-22 Thread Gor Nishanov via Phabricator via cfe-commits
GorNishanov updated this revision to Diff 99815.
GorNishanov added a comment.

Fix misspelling in a comment.
@rsmith, Looks good now?


https://reviews.llvm.org/D31692

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/CodeGen/CGCoroutine.cpp
  lib/Sema/SemaCoroutine.cpp
  test/CodeGenCoroutines/coro-cleanup.cpp
  test/CodeGenCoroutines/coro-eh-cleanup.cpp
  test/SemaCXX/coroutine-seh.cpp

Index: test/SemaCXX/coroutine-seh.cpp
===
--- /dev/null
+++ test/SemaCXX/coroutine-seh.cpp
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -std=c++1z -fcoroutines-ts -verify %s -fcxx-exceptions -fexceptions -triple x86_64-windows-msvc -fms-extensions
+namespace std::experimental {
+template  struct coroutine_traits;
+
+template  struct coroutine_handle {
+  coroutine_handle() = default;
+  static coroutine_handle from_address(void *) noexcept;
+};
+template <> struct coroutine_handle {
+  static coroutine_handle from_address(void *) noexcept;
+  coroutine_handle() = default;
+  template 
+  coroutine_handle(coroutine_handle) noexcept;
+};
+}
+
+struct suspend_always {
+  bool await_ready() noexcept;
+  void await_suspend(std::experimental::coroutine_handle<>) noexcept;
+  void await_resume() noexcept;
+};
+
+template <> struct std::experimental::coroutine_traits {
+  struct promise_type {
+void get_return_object() noexcept;
+suspend_always initial_suspend() noexcept;
+suspend_always final_suspend() noexcept;
+void return_void() noexcept;
+void unhandled_exception() noexcept;
+  };
+};
+
+void SEH_used() {
+  __try { // expected-error {{cannot use SEH '__try' in a coroutine when C++ exceptions are enabled}}
+co_return; // expected-note {{function is a coroutine due to use of 'co_return' here}}
+  } __except(0) {}
+}
Index: test/CodeGenCoroutines/coro-eh-cleanup.cpp
===
--- test/CodeGenCoroutines/coro-eh-cleanup.cpp
+++ test/CodeGenCoroutines/coro-eh-cleanup.cpp
@@ -51,7 +51,13 @@
 // CHECK: [[EHCLEANUP]]:
 // CHECK:   %[[INNERPAD:.+]] = cleanuppad within none []
 // CHECK:   call void @"\01??_DCleanup@@QEAAXXZ"(
-// CHECK:   cleanupret from %[[INNERPAD]] unwind label %[[COROENDBB:.+]]
+// CHECK:   cleanupret from %4 unwind label %[[CATCHDISPATCH:.+]]
+
+// CHECK: [[CATCHDISPATCH]]:
+// CHECK:   catchswitch within none [label %[[CATCHPAD:.+]]] unwind label %[[COROENDBB:.+]]
+// CHECK: [[CATCHPAD]]:
+// CHECK:   call void @"\01?unhandled_exception@promise_type@coro_t@@QEAAXXZ"
+
 // CHECK: [[COROENDBB]]:
 // CHECK-NEXT: %[[CLPAD:.+]] = cleanuppad within none
 // CHECK-NEXT: call i1 @llvm.coro.end(i8* null, i1 true) [ "funclet"(token %[[CLPAD]]) ]
@@ -62,8 +68,14 @@
 // CHECK-LPAD:   to label %[[CONT:.+]] unwind label %[[EHCLEANUP:.+]]
 // CHECK-LPAD: [[EHCLEANUP]]:
 // CHECK-LPAD:landingpad { i8*, i32 }
-// CHECK-LPAD:  cleanup
+// CHECK-LPAD:  catch
 // CHECK-LPAD:   call void @_ZN7CleanupD1Ev(
+// CHECK-LPAD:   call i8* @__cxa_begin_catch
+// CHECK-LPAD:   call void @_ZN6coro_t12promise_type19unhandled_exceptionEv
+// CHECK-LPAD:   invoke void @__cxa_end_catch()
+// CHECK-LPAD: to label %{{.+}} unwind label %[[UNWINDBB:.+]]
+
+// CHECK-LPAD: [[UNWINDBB]]:
 // CHECK-LPAD:   %[[I1RESUME:.+]] = call i1 @llvm.coro.end(i8* null, i1 true)
 // CHECK-LPAD:   br i1  %[[I1RESUME]], label %[[EHRESUME:.+]], label
 // CHECK-LPAD: [[EHRESUME]]:
Index: test/CodeGenCoroutines/coro-cleanup.cpp
===
--- test/CodeGenCoroutines/coro-cleanup.cpp
+++ test/CodeGenCoroutines/coro-cleanup.cpp
@@ -6,38 +6,38 @@
 
 template  struct coroutine_handle {
   coroutine_handle() = default;
-  static coroutine_handle from_address(void *) { return {}; }
+  static coroutine_handle from_address(void *) noexcept;
 };
 template <> struct coroutine_handle {
-  static coroutine_handle from_address(void *) { return {}; }
+  static coroutine_handle from_address(void *) noexcept;
   coroutine_handle() = default;
   template 
-  coroutine_handle(coroutine_handle) {}
+  coroutine_handle(coroutine_handle) noexcept;
 };
 }
 
 struct suspend_always {
-  bool await_ready();
-  void await_suspend(std::experimental::coroutine_handle<>);
-  void await_resume();
+  bool await_ready() noexcept;
+  void await_suspend(std::experimental::coroutine_handle<>) noexcept;
+  void await_resume() noexcept;
 };
 
 template <> struct std::experimental::coroutine_traits {
   struct promise_type {
-void get_return_object();
-suspend_always initial_suspend();
-suspend_always final_suspend();
-void return_void();
+void get_return_object() noexcept;
+suspend_always initial_suspend() noexcept;
+suspend_always final_suspend() noexcept;
+void return_void() noexcept;
 promise_type();
 ~promise_type();
-void unhandled_exception();
+void unhandled_exception() noexcept;
   };
 };
 
 struct Cleanup { ~Cleanup()

[PATCH] D31692: [coroutines] Wrap the body of the coroutine in try-catch

2017-05-22 Thread Gor Nishanov via Phabricator via cfe-commits
GorNishanov updated this revision to Diff 99814.
GorNishanov added a comment.

1. Heap allocate CxxTryStmt in CGCoroutine.
2. Merge with trunk


https://reviews.llvm.org/D31692

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/CodeGen/CGCoroutine.cpp
  lib/Sema/SemaCoroutine.cpp
  test/CodeGenCoroutines/coro-cleanup.cpp
  test/CodeGenCoroutines/coro-eh-cleanup.cpp
  test/SemaCXX/coroutine-seh.cpp

Index: test/SemaCXX/coroutine-seh.cpp
===
--- /dev/null
+++ test/SemaCXX/coroutine-seh.cpp
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -std=c++1z -fcoroutines-ts -verify %s -fcxx-exceptions -fexceptions -triple x86_64-windows-msvc -fms-extensions
+namespace std::experimental {
+template  struct coroutine_traits;
+
+template  struct coroutine_handle {
+  coroutine_handle() = default;
+  static coroutine_handle from_address(void *) noexcept;
+};
+template <> struct coroutine_handle {
+  static coroutine_handle from_address(void *) noexcept;
+  coroutine_handle() = default;
+  template 
+  coroutine_handle(coroutine_handle) noexcept;
+};
+}
+
+struct suspend_always {
+  bool await_ready() noexcept;
+  void await_suspend(std::experimental::coroutine_handle<>) noexcept;
+  void await_resume() noexcept;
+};
+
+template <> struct std::experimental::coroutine_traits {
+  struct promise_type {
+void get_return_object() noexcept;
+suspend_always initial_suspend() noexcept;
+suspend_always final_suspend() noexcept;
+void return_void() noexcept;
+void unhandled_exception() noexcept;
+  };
+};
+
+void SEH_used() {
+  __try { // expected-error {{cannot use SEH '__try' in a coroutine when C++ exceptions are enabled}}
+co_return; // expected-note {{function is a coroutine due to use of 'co_return' here}}
+  } __except(0) {}
+}
Index: test/CodeGenCoroutines/coro-eh-cleanup.cpp
===
--- test/CodeGenCoroutines/coro-eh-cleanup.cpp
+++ test/CodeGenCoroutines/coro-eh-cleanup.cpp
@@ -51,7 +51,13 @@
 // CHECK: [[EHCLEANUP]]:
 // CHECK:   %[[INNERPAD:.+]] = cleanuppad within none []
 // CHECK:   call void @"\01??_DCleanup@@QEAAXXZ"(
-// CHECK:   cleanupret from %[[INNERPAD]] unwind label %[[COROENDBB:.+]]
+// CHECK:   cleanupret from %4 unwind label %[[CATCHDISPATCH:.+]]
+
+// CHECK: [[CATCHDISPATCH]]:
+// CHECK:   catchswitch within none [label %[[CATCHPAD:.+]]] unwind label %[[COROENDBB:.+]]
+// CHECK: [[CATCHPAD]]:
+// CHECK:   call void @"\01?unhandled_exception@promise_type@coro_t@@QEAAXXZ"
+
 // CHECK: [[COROENDBB]]:
 // CHECK-NEXT: %[[CLPAD:.+]] = cleanuppad within none
 // CHECK-NEXT: call i1 @llvm.coro.end(i8* null, i1 true) [ "funclet"(token %[[CLPAD]]) ]
@@ -62,8 +68,14 @@
 // CHECK-LPAD:   to label %[[CONT:.+]] unwind label %[[EHCLEANUP:.+]]
 // CHECK-LPAD: [[EHCLEANUP]]:
 // CHECK-LPAD:landingpad { i8*, i32 }
-// CHECK-LPAD:  cleanup
+// CHECK-LPAD:  catch
 // CHECK-LPAD:   call void @_ZN7CleanupD1Ev(
+// CHECK-LPAD:   call i8* @__cxa_begin_catch
+// CHECK-LPAD:   call void @_ZN6coro_t12promise_type19unhandled_exceptionEv
+// CHECK-LPAD:   invoke void @__cxa_end_catch()
+// CHECK-LPAD: to label %{{.+}} unwind label %[[UNWINDBB:.+]]
+
+// CHECK-LPAD: [[UNWINDBB]]:
 // CHECK-LPAD:   %[[I1RESUME:.+]] = call i1 @llvm.coro.end(i8* null, i1 true)
 // CHECK-LPAD:   br i1  %[[I1RESUME]], label %[[EHRESUME:.+]], label
 // CHECK-LPAD: [[EHRESUME]]:
Index: test/CodeGenCoroutines/coro-cleanup.cpp
===
--- test/CodeGenCoroutines/coro-cleanup.cpp
+++ test/CodeGenCoroutines/coro-cleanup.cpp
@@ -6,38 +6,38 @@
 
 template  struct coroutine_handle {
   coroutine_handle() = default;
-  static coroutine_handle from_address(void *) { return {}; }
+  static coroutine_handle from_address(void *) noexcept;
 };
 template <> struct coroutine_handle {
-  static coroutine_handle from_address(void *) { return {}; }
+  static coroutine_handle from_address(void *) noexcept;
   coroutine_handle() = default;
   template 
-  coroutine_handle(coroutine_handle) {}
+  coroutine_handle(coroutine_handle) noexcept;
 };
 }
 
 struct suspend_always {
-  bool await_ready();
-  void await_suspend(std::experimental::coroutine_handle<>);
-  void await_resume();
+  bool await_ready() noexcept;
+  void await_suspend(std::experimental::coroutine_handle<>) noexcept;
+  void await_resume() noexcept;
 };
 
 template <> struct std::experimental::coroutine_traits {
   struct promise_type {
-void get_return_object();
-suspend_always initial_suspend();
-suspend_always final_suspend();
-void return_void();
+void get_return_object() noexcept;
+suspend_always initial_suspend() noexcept;
+suspend_always final_suspend() noexcept;
+void return_void() noexcept;
 promise_type();
 ~promise_type();
-void unhandled_exception();
+void unhandled_exception() noexcept;
   };
 };
 
 struct Cleanup { ~

[PATCH] D33357: Avoid calling report_fatal_error in the destructor of raw_fd_ostream when saving a module timestamp file

2017-05-22 Thread Bruno Cardoso Lopes via Phabricator via cfe-commits
bruno added a comment.

Any idea why we're hitting this issue in the first place? The error that gets 
cleaned up is reported at some point before? Seems to me that we're going to 
fail to update the timestamp but continue as nothing happened, I wonder how 
many other issues this might trigger...

> I couldn't think of a way to test this, do you think it's possible to have a 
> test for this?

If you can come up with a testcase it would be awesome, but for this to trigger 
you'd have to reproduce the concurrent scenario in the testcase, which I don't 
see how.


Repository:
  rL LLVM

https://reviews.llvm.org/D33357



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33259: Don't defer to the GCC driver for linking arm-baremetal

2017-05-22 Thread Rui Ueyama via Phabricator via cfe-commits
ruiu added inline comments.



Comment at: lib/Driver/ToolChains/BareMetal.h:42
+
+  const char *getDefaultLinker() const override { return "ld.lld"; }
+

jroelofs wrote:
> compnerd wrote:
> > jroelofs wrote:
> > > compnerd wrote:
> > > > I think that this really should be `ld` still, as that is the canonical 
> > > > name for the linker.
> > > You mean `lld`?
> > > 
> > > ```
> > > $ lld
> > > lld is a generic driver.
> > > Invoke ld.lld (Unix), ld (macOS) or lld-link (Windows) instead.
> > > ```
> > > 
> > > Or are you saying: "make binutils ld the default, not llvm's lld"?
> > Im saying use the name "ld".  ld is a symlink on most linux distributions 
> > these days.  ld -> ld.gold, ld.bfd, ld.lld
> I don't think this makes sense. I don't care about "most linux 
> distributions", but rather about putting together an LLVM baremetal 
> distribution based as much as possible on LLVM components. If someone wants a 
> different linker, they can use `-fuse-ld=` and/or `-B`.
> 
> Also, doesn't using a symlink named `ld` cause `lld` to behave like a mach-o 
> linker? We really want the elf one here.
If you invoke lld as ld, it behaves as a Mach-O linker on macOS. On other OSes, 
it behaves as an ELF linker.


https://reviews.llvm.org/D33259



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33333: Emit warning when throw exception in destruct or dealloc functions which has a (possible implicit) noexcept specifier

2017-05-22 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 99802.
jyu2 added a comment.

This is new version should address all @Aaron's commands, but CFG part.

I would not think we should go that far in the compiler for this.

Thanks.


https://reviews.llvm.org/D3

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Sema/SemaExprCXX.cpp
  lib/Sema/TreeTransform.h
  test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p1.cpp
  test/CXX/except/except.spec/p11.cpp
  test/SemaCXX/warn-throw-out_noexcept_func.cpp

Index: lib/Sema/SemaExprCXX.cpp
===
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -687,6 +687,47 @@
   return BuildCXXThrow(OpLoc, Ex, IsThrownVarInScope);
 }
 
+static bool isNoexcept(const FunctionDecl * FD)
+{
+  if (const FunctionProtoType *FPT = FD->getType()->castAs()) 
+if (FPT->getExceptionSpecType() != EST_None &&
+FPT->getNoexceptSpec(FD->getASTContext()) ==
+   FunctionProtoType::NR_Nothrow) 
+  return true;
+  return false;
+}
+
+static bool isNoexceptTrue(const FunctionDecl * FD) {
+  // Avoid emitting error twice.
+  if (const auto * TempFD = FD->getTemplateInstantiationPattern())
+if (isNoexcept(TempFD)) 
+  return false;
+  return isNoexcept(FD);
+}
+
+
+void Sema::CheckCXXThrowInNonThrowingFunc(SourceLocation OpLoc) {
+  bool isInCXXTryBlock = false;
+  for (Scope *S = getCurScope(); S; S = S->getParent())
+if (S->isTryScope()) {
+  isInCXXTryBlock = true;
+  break;
+} else if (S->isFunctionScope()) 
+  break;
+  if (const FunctionDecl *FD = getCurFunctionDecl())
+if (!isInCXXTryBlock && !getSourceManager().isInSystemHeader(OpLoc))
+  if (isNoexceptTrue(FD)) {
+Diag(OpLoc, diag::warn_throw_in_noexcept_func) << FD;
+if (getLangOpts().CPlusPlus11 &&
+(isa(FD) ||
+ FD->getDeclName().getCXXOverloadedOperator() == OO_Delete ||
+ FD->getDeclName().getCXXOverloadedOperator() == OO_Array_Delete))
+  Diag(FD->getLocation(), diag::note_throw_in_dtor);
+else
+  Diag(FD->getLocation(), diag::note_throw_in_function);
+  }
+}
+
 ExprResult Sema::BuildCXXThrow(SourceLocation OpLoc, Expr *Ex,
bool IsThrownVarInScope) {
   // Don't report an error if 'throw' is used in system headers.
@@ -702,6 +743,8 @@
   if (getCurScope() && getCurScope()->isOpenMPSimdDirectiveScope())
 Diag(OpLoc, diag::err_omp_simd_region_cannot_use_stmt) << "throw";
 
+  CheckCXXThrowInNonThrowingFunc(OpLoc);
+
   if (Ex && !Ex->isTypeDependent()) {
 QualType ExceptionObjectTy = Context.getExceptionObjectType(Ex->getType());
 if (CheckCXXThrowOperand(OpLoc, ExceptionObjectTy, Ex))
Index: lib/Sema/TreeTransform.h
===
--- lib/Sema/TreeTransform.h
+++ lib/Sema/TreeTransform.h
@@ -9873,9 +9873,10 @@
   if (SubExpr.isInvalid())
 return ExprError();
 
-  if (!getDerived().AlwaysRebuild() &&
-  SubExpr.get() == E->getSubExpr())
+  if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr()) {
+getSema().CheckCXXThrowInNonThrowingFunc(E->getThrowLoc());
 return E;
+  }
 
   return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),
   E->isThrownVariableInScope());
Index: include/clang/Sema/Sema.h
===
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -4967,6 +4967,9 @@
   ExprResult BuildCXXThrow(SourceLocation OpLoc, Expr *Ex,
bool IsThrownVarInScope);
   bool CheckCXXThrowOperand(SourceLocation ThrowLoc, QualType ThrowTy, Expr *E);
+  /// Check if throw is used in function with a non-throwing noexcept 
+  /// specifier.
+  void CheckCXXThrowInNonThrowingFunc(SourceLocation OpLoc);
 
   /// ActOnCXXTypeConstructExpr - Parse construction of a specified type.
   /// Can be interpreted either as function-style casting ("int(x)")
Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -6331,6 +6331,15 @@
   "cannot use '%0' with exceptions disabled">;
 def err_objc_exceptions_disabled : Error<
   "cannot use '%0' with Objective-C exceptions disabled">;
+def warn_throw_in_noexcept_func 
+: Warning<"%0 has a non-throwing exception specification but can still "
+  "throw, may result in unexpected program termination.">, 
+  InGroup;
+def note_throw_in_dtor 
+: Note<"destructor or deallocator has a (possible implicit) non-throwing "
+  "excepton specification">;
+def note_throw_in_function 
+: Note<"nonthrowing function declare here">;
 def err_seh_try_outside_functions : Error<
   "cannot use SEH '__try' in blocks, capt

[PATCH] D33259: Don't defer to the GCC driver for linking arm-baremetal

2017-05-22 Thread Jonathan Roelofs via Phabricator via cfe-commits
jroelofs added inline comments.



Comment at: cmake/caches/BaremetalARM.cmake:1
+set(LLVM_TARGETS_TO_BUILD ARM CACHE STRING "")
+

compnerd wrote:
> jroelofs wrote:
> > compnerd wrote:
> > > Please rename this file to `BareMetalARMv6.cmake`.  (I'm interested in 
> > > the suffix primarily).
> > My plan is to eventually add multilibs to this configuration, so while that 
> > makes sense short term, I don't think it makes sense long term.
> > 
> > With that in mind, do you still want me to rename it?
> I think it makes sense longer term still.  ARMv6 vs ARMv7.  Even if you do 
> multilib, that wouldnt take care of that right?
It's not limited to just ARMv6m multilibs... imagine it had:


```
set(LLVM_BUILTIN_TARGETS "armv6m-none-eabi;armv7m-none-eabi" CACHE STRING 
"Builtin Targets")
```

Then naming the file `BaremetalARMv6m.cmake` will be inappropriately specific.


Granted, the way clangrt is built/used now isn't very conducive to multilibs 
that differ by more than just the arch, since the name currently has to be of 
the form: `libclang_rt-builtins-${triple's subarch}.a`, which for example 
doesn't allow for differentiating between:
```
v7m;@mthumb@march=armv7-m
v7m-PIC;@mthumb@march=armv7-m@fPIC
```

or

```
v7a-neon;@march=armv7-a@mfloat-abi=softfp@mfpu=neon
v7a-vfpv3-d16;@march=armv7-a@mfloat-abi=softfp@mfpu=vfpv3-d16
```



Comment at: lib/Driver/ToolChains/BareMetal.cpp:68
+  SmallString<128> Dir(getDriver().ResourceDir);
+  llvm::sys::path::append(Dir, "lib", "baremetal");
+  return Dir.str();

compnerd wrote:
> jroelofs wrote:
> > compnerd wrote:
> > > Why not just the standard `arm` directory?
> > There are a few differences between the stuff in the existing ones, and 
> > what is needed on baremetal. For example __enable_execute_stack, emutls, as 
> > well as anything else that assumes existence of pthreads support shouldn't 
> > be there.
> Well, I think that "baremetal" here is a bad idea.  How about using the 
> android approach?  Use `clang_rt.builtins-arm-baremetal.a` ?
Why? Given the way the cmake goop works in lib/runtimes + compiler-rt, the 
folder name there has to be the same as the CMAKE_SYSTEM_NAME. The alternative, 
I guess, is to call it 'generic', but I'm not convinced that's better than 
'baremetal'.



Comment at: lib/Driver/ToolChains/BareMetal.h:42
+
+  const char *getDefaultLinker() const override { return "ld.lld"; }
+

compnerd wrote:
> jroelofs wrote:
> > compnerd wrote:
> > > I think that this really should be `ld` still, as that is the canonical 
> > > name for the linker.
> > You mean `lld`?
> > 
> > ```
> > $ lld
> > lld is a generic driver.
> > Invoke ld.lld (Unix), ld (macOS) or lld-link (Windows) instead.
> > ```
> > 
> > Or are you saying: "make binutils ld the default, not llvm's lld"?
> Im saying use the name "ld".  ld is a symlink on most linux distributions 
> these days.  ld -> ld.gold, ld.bfd, ld.lld
I don't think this makes sense. I don't care about "most linux distributions", 
but rather about putting together an LLVM baremetal distribution based as much 
as possible on LLVM components. If someone wants a different linker, they can 
use `-fuse-ld=` and/or `-B`.

Also, doesn't using a symlink named `ld` cause `lld` to behave like a mach-o 
linker? We really want the elf one here.


https://reviews.llvm.org/D33259



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D30170: Function definition may have uninstantiated body

2017-05-22 Thread Richard Smith via Phabricator via cfe-commits
rsmith added a comment.

Do we really need two different notions of "definition" and "odr definition" 
here? What goes wrong if we always treat the "instantiation of a friend 
function definition" case as being a definition?




Comment at: include/clang/AST/Decl.h:1789
+  // function is not used yet, but the declaration is considered a
+  // definition, it does not allow other definition of this function.
+  //   - it does not have a user specified body, but it does not allow

it -> and



Comment at: include/clang/AST/Decl.h:1829-1830
 
+  /// Returns true if the function is defined and other definitions are not
+  /// allowed in the redeclaration chain.
+  ///

This will not be true in the presence of modules: we will ensure that at most 
one declaration has a body, but multiple declarations can be instantiated from 
a defined member function of a class template, for instance. So I think the 
constraint is that you're not allowed to add *more* such definitions.



Comment at: include/clang/AST/Decl.h:1842
+
+  /// Returns true if this declaration is a definition is the sense of ODR
+  /// checks.

is the sense -> in the sense



Comment at: include/clang/AST/Decl.h:1848
+  return true;
+if (FunctionDecl *Original = getInstantiatedFromMemberFunction())
+  return Original->isOdrDefined();

I think this will do the wrong thing for an explicit specialization of a member 
of a class template:

```
template struct A { void f() {}; };
template<> void A::f();
```

Here, `A::f()` is "instantiated from a member function" but it's not a 
definition, not even in the ODR sense. I think it would suffice to also check 
whether `Original` is a friend declaration here.



Comment at: lib/AST/Decl.cpp:2538
+if (I->isThisDeclarationADefinition()) {
+  Definition = I->IsDeleted ? I->getCanonicalDecl() : I;
+  return true;

It seems incorrect to me for `isThisDeclarationADefinition()` to return `true` 
on a redeclaration of a deleted function: only the first declaration should be 
considered to be a definition in that case. (This special case should be in 
`isThisDeclarationADefinition()`, not in `isDefined()`.)



Comment at: lib/Sema/SemaDecl.cpp:11882
+
+  if (FD == Definition)
+return;

This looks wrong to me: `CheckForFunctionRedefinition` is intended to be called 
*before* marking the function in question as a definition. If you call it 
afterwards, then the `isOdrDefined` call won't work properly because it will 
always check to see whether `FD` is a definition before checking any other 
declaration. So any case that reaches here with `FD` being a definition seems 
like a bug. I expect we're only getting here in that case due to the missing 
check for friend in `isThisDeclarationAnOdrDefinition`.


https://reviews.llvm.org/D30170



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31646: [coroutines] Build GRO declaration and return GRO statement

2017-05-22 Thread Gor Nishanov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
GorNishanov marked an inline comment as done.
Closed by commit rL303573: [coroutines] Build GRO declaration and return GRO 
statement (authored by GorNishanov).

Changed prior to commit:
  https://reviews.llvm.org/D31646?vs=99796&id=99798#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D31646

Files:
  cfe/trunk/include/clang/AST/StmtCXX.h
  cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
  cfe/trunk/lib/AST/StmtCXX.cpp
  cfe/trunk/lib/CodeGen/CGCoroutine.cpp
  cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp
  cfe/trunk/lib/Sema/CoroutineStmtBuilder.h
  cfe/trunk/lib/Sema/SemaCoroutine.cpp
  cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp
  cfe/trunk/test/SemaCXX/coroutines.cpp

Index: cfe/trunk/include/clang/AST/StmtCXX.h
===
--- cfe/trunk/include/clang/AST/StmtCXX.h
+++ cfe/trunk/include/clang/AST/StmtCXX.h
@@ -308,7 +308,9 @@
 OnFallthrough, ///< Handler for control flow falling off the body.
 Allocate,  ///< Coroutine frame memory allocation.
 Deallocate,///< Coroutine frame memory deallocation.
-ReturnValue,   ///< Return value for thunk function.
+ReturnValue,   ///< Return value for thunk function: p.get_return_object().
+ResultDecl,///< Declaration holding the result of get_return_object.
+ReturnStmt,///< Return statement for the thunk function.
 ReturnStmtOnAllocFailure, ///< Return statement if allocation failed.
 FirstParamMove ///< First offset for move construction of parameter copies.
   };
@@ -332,7 +334,9 @@
 Stmt *OnFallthrough = nullptr;
 Expr *Allocate = nullptr;
 Expr *Deallocate = nullptr;
-Stmt *ReturnValue = nullptr;
+Expr *ReturnValue = nullptr;
+Stmt *ResultDecl = nullptr;
+Stmt *ReturnStmt = nullptr;
 Stmt *ReturnStmtOnAllocFailure = nullptr;
 ArrayRef ParamMoves;
   };
@@ -381,10 +385,11 @@
   Expr *getDeallocate() const {
 return cast_or_null(getStoredStmts()[SubStmt::Deallocate]);
   }
-
   Expr *getReturnValueInit() const {
-return cast_or_null(getStoredStmts()[SubStmt::ReturnValue]);
+return cast(getStoredStmts()[SubStmt::ReturnValue]);
   }
+  Stmt *getResultDecl() const { return getStoredStmts()[SubStmt::ResultDecl]; }
+  Stmt *getReturnStmt() const { return getStoredStmts()[SubStmt::ReturnStmt]; }
   Stmt *getReturnStmtOnAllocFailure() const {
 return getStoredStmts()[SubStmt::ReturnStmtOnAllocFailure];
   }
Index: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
===
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8910,6 +8910,8 @@
   "return statement not allowed in coroutine; did you mean 'co_return'?">;
 def note_declared_coroutine_here : Note<
   "function is a coroutine due to use of '%0' here">;
+def note_promise_member_declared_here : Note<
+  "'%0' is declared here">;
 def err_coroutine_objc_method : Error<
   "Objective-C methods as coroutines are not yet supported">;
 def err_coroutine_unevaluated_context : Error<
Index: cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp
===
--- cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp
+++ cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp
@@ -156,14 +156,24 @@
 
 // CHECK-LABEL: f4(
 extern "C" int f4(promise_on_alloc_failure_tag) {
+  // CHECK: %[[RetVal:.+]] = alloca i32
   // CHECK: %[[ID:.+]] = call token @llvm.coro.id(i32 16
   // CHECK: %[[SIZE:.+]] = call i64 @llvm.coro.size.i64()
   // CHECK: %[[MEM:.+]] = call i8* @_ZnwmRKSt9nothrow_t(i64 %[[SIZE]], %"struct.std::nothrow_t"* dereferenceable(1) @_ZStL7nothrow)
   // CHECK: %[[OK:.+]] = icmp ne i8* %[[MEM]], null
   // CHECK: br i1 %[[OK]], label %[[OKBB:.+]], label %[[ERRBB:.+]]
 
   // CHECK: [[ERRBB]]:
-  // CHECK: %[[RETVAL:.+]] = call i32 @_ZNSt12experimental16coroutine_traitsIJi28promise_on_alloc_failure_tagEE12promise_type39get_return_object_on_allocation_failureEv(
-  // CHECK: ret i32 %[[RETVAL]]
+  // CHECK:   %[[FailRet:.+]] = call i32 @_ZNSt12experimental16coroutine_traitsIJi28promise_on_alloc_failure_tagEE12promise_type39get_return_object_on_allocation_failureEv(
+  // CHECK:   store i32 %[[FailRet]], i32* %[[RetVal]]
+  // CHECK:   br label %[[RetBB:.+]]
+
+  // CHECK: [[OKBB]]:
+  // CHECK:   %[[OkRet:.+]] = call i32 @_ZNSt12experimental16coroutine_traitsIJi28promise_on_alloc_failure_tagEE12promise_type17get_return_objectEv(
+  // CHECK:   store i32 %[[OkRet]], i32* %[[RetVal]]
+
+  // CHECK: [[RetBB]]:
+  // CHECK:   %[[LoadRet:.+]] = load i32, i32* %[[RetVal]], align 4
+  // CHECK:   ret i32 %[[LoadRet]]
   co_return;
 }
Index: cfe/trunk/test/SemaCXX/coroutines.cpp
===
--- cfe/trunk/test/SemaCXX/coroutines.cpp
+++ cfe/trunk/test/SemaCXX/coroutines.c

r303573 - [coroutines] Build GRO declaration and return GRO statement

2017-05-22 Thread Gor Nishanov via cfe-commits
Author: gornishanov
Date: Mon May 22 15:22:23 2017
New Revision: 303573

URL: http://llvm.org/viewvc/llvm-project?rev=303573&view=rev
Log:
[coroutines] Build GRO declaration and return GRO statement

Summary:
1. build declaration of the gro local variable that keeps the result of 
get_return_object.
2. build return statement returning the gro variable
3. emit them during CodeGen
4. sema and CodeGen tests updated

Reviewers: EricWF, rsmith

Reviewed By: rsmith

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D31646

Modified:
cfe/trunk/include/clang/AST/StmtCXX.h
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/AST/StmtCXX.cpp
cfe/trunk/lib/CodeGen/CGCoroutine.cpp
cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp
cfe/trunk/lib/Sema/CoroutineStmtBuilder.h
cfe/trunk/lib/Sema/SemaCoroutine.cpp
cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp
cfe/trunk/test/SemaCXX/coroutines.cpp

Modified: cfe/trunk/include/clang/AST/StmtCXX.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtCXX.h?rev=303573&r1=303572&r2=303573&view=diff
==
--- cfe/trunk/include/clang/AST/StmtCXX.h (original)
+++ cfe/trunk/include/clang/AST/StmtCXX.h Mon May 22 15:22:23 2017
@@ -308,7 +308,9 @@ class CoroutineBodyStmt final
 OnFallthrough, ///< Handler for control flow falling off the body.
 Allocate,  ///< Coroutine frame memory allocation.
 Deallocate,///< Coroutine frame memory deallocation.
-ReturnValue,   ///< Return value for thunk function.
+ReturnValue,   ///< Return value for thunk function: p.get_return_object().
+ResultDecl,///< Declaration holding the result of get_return_object.
+ReturnStmt,///< Return statement for the thunk function.
 ReturnStmtOnAllocFailure, ///< Return statement if allocation failed.
 FirstParamMove ///< First offset for move construction of parameter copies.
   };
@@ -332,7 +334,9 @@ public:
 Stmt *OnFallthrough = nullptr;
 Expr *Allocate = nullptr;
 Expr *Deallocate = nullptr;
-Stmt *ReturnValue = nullptr;
+Expr *ReturnValue = nullptr;
+Stmt *ResultDecl = nullptr;
+Stmt *ReturnStmt = nullptr;
 Stmt *ReturnStmtOnAllocFailure = nullptr;
 ArrayRef ParamMoves;
   };
@@ -381,10 +385,11 @@ public:
   Expr *getDeallocate() const {
 return cast_or_null(getStoredStmts()[SubStmt::Deallocate]);
   }
-
   Expr *getReturnValueInit() const {
-return cast_or_null(getStoredStmts()[SubStmt::ReturnValue]);
+return cast(getStoredStmts()[SubStmt::ReturnValue]);
   }
+  Stmt *getResultDecl() const { return getStoredStmts()[SubStmt::ResultDecl]; }
+  Stmt *getReturnStmt() const { return getStoredStmts()[SubStmt::ReturnStmt]; }
   Stmt *getReturnStmtOnAllocFailure() const {
 return getStoredStmts()[SubStmt::ReturnStmtOnAllocFailure];
   }

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=303573&r1=303572&r2=303573&view=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon May 22 15:22:23 
2017
@@ -8910,6 +8910,8 @@ def err_return_in_coroutine : Error<
   "return statement not allowed in coroutine; did you mean 'co_return'?">;
 def note_declared_coroutine_here : Note<
   "function is a coroutine due to use of '%0' here">;
+def note_promise_member_declared_here : Note<
+  "'%0' is declared here">;
 def err_coroutine_objc_method : Error<
   "Objective-C methods as coroutines are not yet supported">;
 def err_coroutine_unevaluated_context : Error<

Modified: cfe/trunk/lib/AST/StmtCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtCXX.cpp?rev=303573&r1=303572&r2=303573&view=diff
==
--- cfe/trunk/lib/AST/StmtCXX.cpp (original)
+++ cfe/trunk/lib/AST/StmtCXX.cpp Mon May 22 15:22:23 2017
@@ -88,7 +88,7 @@ const VarDecl *CXXForRangeStmt::getLoopV
 }
 
 CoroutineBodyStmt *CoroutineBodyStmt::Create(
-const ASTContext &C, CoroutineBodyStmt::CtorArgs const& Args) {
+const ASTContext &C, CoroutineBodyStmt::CtorArgs const &Args) {
   std::size_t Size = totalSizeToAlloc(
   CoroutineBodyStmt::FirstParamMove + Args.ParamMoves.size());
 
@@ -108,6 +108,8 @@ CoroutineBodyStmt::CoroutineBodyStmt(Cor
   SubStmts[CoroutineBodyStmt::Allocate] = Args.Allocate;
   SubStmts[CoroutineBodyStmt::Deallocate] = Args.Deallocate;
   SubStmts[CoroutineBodyStmt::ReturnValue] = Args.ReturnValue;
+  SubStmts[CoroutineBodyStmt::ResultDecl] = Args.ResultDecl;
+  SubStmts[CoroutineBodyStmt::ReturnStmt] = Args.ReturnStmt;
   SubStmts[CoroutineBodyStmt::ReturnStmtOnAllocFailure] =
   Args.ReturnStmtOnAllocFailure;
   std

[PATCH] D31627: [coroutines] Skip over passthrough operator co_await

2017-05-22 Thread Gor Nishanov via Phabricator via cfe-commits
GorNishanov added a comment.

In https://reviews.llvm.org/D31627#761320, @rsmith wrote:

> Does it still make sense for us to have a `UO_Coawait` at all? As I recall, 
> the only purpose it ever had was to represent a dependent `co_await` 
> expression that couldn't yet be resolved to a `CoawaitExpr`. But now we have 
> (and need!) a separate `DependentCoawaitExpr` node to store unqualified 
> lookup results, it seems that the `UnaryOperator` portion of the 
> representation serves no purpose (and as seen in this patch, it's getting in 
> the way). Can we remove it?
>
> Anyway, this change LGTM for now.


Thank you for the review! 
I'll see if I can remove UO_Coawait in a separate patch


https://reviews.llvm.org/D31627



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31646: [coroutines] Build GRO declaration and return GRO statement

2017-05-22 Thread Gor Nishanov via Phabricator via cfe-commits
GorNishanov updated this revision to Diff 99796.
GorNishanov added a comment.

Thank you very much for the review!

Merged with top of the trunk, implemented suggested changes, preparing to land


https://reviews.llvm.org/D31646

Files:
  include/clang/AST/StmtCXX.h
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/AST/StmtCXX.cpp
  lib/CodeGen/CGCoroutine.cpp
  lib/Sema/AnalysisBasedWarnings.cpp
  lib/Sema/CoroutineStmtBuilder.h
  lib/Sema/SemaCoroutine.cpp
  test/CodeGenCoroutines/coro-alloc.cpp
  test/SemaCXX/coroutines.cpp

Index: test/SemaCXX/coroutines.cpp
===
--- test/SemaCXX/coroutines.cpp
+++ test/SemaCXX/coroutines.cpp
@@ -746,3 +746,75 @@
co_return;
 }
 template coro dependent_uses_nothrow_new(good_promise_13);
+
+struct mismatch_gro_type_tag1 {};
+template<>
+struct std::experimental::coroutine_traits {
+  struct promise_type {
+void get_return_object() {} //expected-note {{'get_return_object' is declared here}}
+suspend_always initial_suspend() { return {}; }
+suspend_always final_suspend() { return {}; }
+void return_void() {}
+void unhandled_exception();
+  };
+};
+
+extern "C" int f(mismatch_gro_type_tag1) { 
+  // expected-error@-1 {{cannot initialize return object of type 'int' with an rvalue of type 'void'}}
+  co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
+}
+
+struct mismatch_gro_type_tag2 {};
+template<>
+struct std::experimental::coroutine_traits {
+  struct promise_type {
+void* get_return_object() {} //expected-note {{'get_return_object' is declared here}}
+suspend_always initial_suspend() { return {}; }
+suspend_always final_suspend() { return {}; }
+void return_void() {}
+void unhandled_exception();
+  };
+};
+
+extern "C" int f(mismatch_gro_type_tag2) { 
+  // expected-error@-1 {{cannot initialize return object of type 'int' with an lvalue of type 'void *'}}
+  co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
+}
+
+struct mismatch_gro_type_tag3 {};
+template<>
+struct std::experimental::coroutine_traits {
+  struct promise_type {
+int get_return_object() {}
+static void get_return_object_on_allocation_failure() {} //expected-note {{'get_return_object_on_allocation_failure' is declared here}}
+suspend_always initial_suspend() { return {}; }
+suspend_always final_suspend() { return {}; }
+void return_void() {}
+void unhandled_exception();
+  };
+};
+
+extern "C" int f(mismatch_gro_type_tag3) { 
+  // expected-error@-1 {{cannot initialize return object of type 'int' with an rvalue of type 'void'}}
+  co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
+}
+
+
+struct mismatch_gro_type_tag4 {};
+template<>
+struct std::experimental::coroutine_traits {
+  struct promise_type {
+int get_return_object() {}
+static char* get_return_object_on_allocation_failure() {} //expected-note {{'get_return_object_on_allocation_failure' is declared here}}
+suspend_always initial_suspend() { return {}; }
+suspend_always final_suspend() { return {}; }
+void return_void() {}
+void unhandled_exception();
+  };
+};
+
+extern "C" int f(mismatch_gro_type_tag4) { 
+  // expected-error@-1 {{cannot initialize return object of type 'int' with an rvalue of type 'char *'}}
+  co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
+}
+
Index: test/CodeGenCoroutines/coro-alloc.cpp
===
--- test/CodeGenCoroutines/coro-alloc.cpp
+++ test/CodeGenCoroutines/coro-alloc.cpp
@@ -156,14 +156,24 @@
 
 // CHECK-LABEL: f4(
 extern "C" int f4(promise_on_alloc_failure_tag) {
+  // CHECK: %[[RetVal:.+]] = alloca i32
   // CHECK: %[[ID:.+]] = call token @llvm.coro.id(i32 16
   // CHECK: %[[SIZE:.+]] = call i64 @llvm.coro.size.i64()
   // CHECK: %[[MEM:.+]] = call i8* @_ZnwmRKSt9nothrow_t(i64 %[[SIZE]], %"struct.std::nothrow_t"* dereferenceable(1) @_ZStL7nothrow)
   // CHECK: %[[OK:.+]] = icmp ne i8* %[[MEM]], null
   // CHECK: br i1 %[[OK]], label %[[OKBB:.+]], label %[[ERRBB:.+]]
 
   // CHECK: [[ERRBB]]:
-  // CHECK: %[[RETVAL:.+]] = call i32 @_ZNSt12experimental16coroutine_traitsIJi28promise_on_alloc_failure_tagEE12promise_type39get_return_object_on_allocation_failureEv(
-  // CHECK: ret i32 %[[RETVAL]]
+  // CHECK:   %[[FailRet:.+]] = call i32 @_ZNSt12experimental16coroutine_traitsIJi28promise_on_alloc_failure_tagEE12promise_type39get_return_object_on_allocation_failureEv(
+  // CHECK:   store i32 %[[FailRet]], i32* %[[RetVal]]
+  // CHECK:   br label %[[RetBB:.+]]
+
+  // CHECK: [[OKBB]]:
+  // CHECK:   %[[OkRet:.+]] = call i32 @_ZNSt12experimental16coroutine_traitsIJi28promise_on_alloc_failure_tagEE12promise_type17get_return_objectEv(
+  // CHECK:   store i32 %[[OkRet]], i32* %[[RetVal]]
+
+  // CHECK: [[RetBB]]:
+  // CHECK:   %[[LoadRet:.+]] = load i32, i32* %[[RetVa

[PATCH] D31627: [coroutines] Skip over passthrough operator co_await

2017-05-22 Thread Richard Smith via Phabricator via cfe-commits
rsmith accepted this revision.
rsmith added a comment.
This revision is now accepted and ready to land.

Does it still make sense for us to have a `UO_Coawait` at all? As I recall, the 
only purpose it ever had was to represent a dependent `co_await` expression 
that couldn't yet be resolved to a `CoawaitExpr`. But now we have (and need!) a 
separate `DependentCoawaitExpr` node to store unqualified lookup results, it 
seems that the `UnaryOperator` portion of the representation serves no purpose 
(and as seen in this patch, it's getting in the way). Can we remove it?

Anyway, this change LGTM for now.




Comment at: lib/CodeGen/CGCoroutine.cpp:146
+
+  // Skip paththrough operator co_await (present when awaiting on an LValue).
+  if (auto *UO = dyn_cast(E))

paththrough -> passthrough



Comment at: lib/CodeGen/CGCoroutine.cpp:148-149
+  if (auto *UO = dyn_cast(E))
+  if (UO->getOpcode() == UO_Coawait)
+E = UO->getSubExpr();
+

Indent.


https://reviews.llvm.org/D31627



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32449: Modifying PthreadLockChecker.cpp to reduce false positives.

2017-05-22 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ added a comment.

Thanks, this is great! Two more things:

- You have touched other code, unrelated to your patch, with clang-format; 
we're usually trying to avoid that, because it creates merge conflicts out of 
nowhere, and because some of that code actually seems formatted by hand 
intentionally. It's better to revert these changes; you can use the `git 
clang-format` thing to format only actual changes.

- Updating .gitignore sounds like the right thing to do (llvm's .gitignore 
already has this), but i guess we'd better make a separate commit for that.




Comment at: lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp:143-146
+if(lstate->isSchrodingerUntouched())
+  state = state->remove(lockR);
+else if(lstate->isSchrodingerUnlocked())
+  state = state->set(lockR, LockState::getUnlocked());

malhar1995 wrote:
> NoQ wrote:
> > I think we can be certain that the lock is in one of these states, and 
> > assert that.
> We can be certain that the lock state will be either of the two only if I add 
> the following statement before returning from this function.
> ```
> state = state->remove(lockR);
> ```
> If I don't add the above statement, a return value symbol for the region 
> specified by lockR will still be in DestroyRetVal and it may have an actual 
> lock state (locked, unlocked or destroyed).
Yep, that's a great thing to do. I didn't notice this.

Generally, it's great to keep the program state free from stuff that would no 
longer be necessary.


Repository:
  rL LLVM

https://reviews.llvm.org/D32449



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31608: [coroutines] Add emission of initial and final suspends

2017-05-22 Thread Richard Smith via Phabricator via cfe-commits
rsmith accepted this revision.
rsmith added a comment.
This revision is now accepted and ready to land.

LGTM


https://reviews.llvm.org/D31608



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31692: [coroutines] Wrap the body of the coroutine in try-catch

2017-05-22 Thread Richard Smith via Phabricator via cfe-commits
rsmith added inline comments.



Comment at: include/clang/AST/StmtCXX.h:128
+struct CXXTryStmt::OnStack : CXXTryStmt {
+  alignas(CXXTryStmt) Stmt *Stmts[2];
+  OnStack(SourceLocation tryLoc, Stmt *tryBlock, Stmt *handler)

This makes more assumptions about record layout and the ability to reach 
derived-class members through pointer arithmetic than I'd prefer. We're only 
going to have at most one of these per coroutine for which we emit an IR 
definition, so it seems fine for CodeGen to just go ahead and allocate one in 
the normal way.

Alternatively, it looks like it'd be straightforward to refactor `CodeGen`'s 
`EnterCXXTryStmt` / `ExitCXXTryStmt` to take an `ArrayRef` instead 
of a `CXXTryStmt`, which would let you avoid this machinery entirely.


https://reviews.llvm.org/D31692



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31670: [coroutines] Implement correct GRO lifetime

2017-05-22 Thread Richard Smith via Phabricator via cfe-commits
rsmith added inline comments.



Comment at: lib/CodeGen/CGCoroutine.cpp:273
+
+// FIXME: There must be a cleaner way to do this!
+if (auto *Cleanup = 
dyn_cast_or_null(&*CGF.EHStack.begin())) {

It doesn't seem safe to assume that a prior `EHCleanupScope` would be for the 
GRO variable, nor that it can only have one such cleanup. How about this: grab 
a stable EHStack iterator before you emit cleanups, grab another afterwards, 
and iterate over the cleanups in that range modifying them as appropriate.

Even that seems a bit fragile, though. Would it be feasible to thread the 
'active' flag through `EmitAutoVarCleanups` (perhaps add it to 
`AutoVarEmission`)?


https://reviews.llvm.org/D31670



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D21508: Make friend function template definition available if class is instantiated.

2017-05-22 Thread Serge Pavlov via Phabricator via cfe-commits
sepavloff updated this revision to Diff 99789.
sepavloff edited the summary of this revision.
sepavloff added a comment.

Updated patch


https://reviews.llvm.org/D21508

Files:
  include/clang/AST/DeclTemplate.h
  lib/AST/Decl.cpp
  lib/AST/DeclTemplate.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  test/SemaCXX/friend2.cpp

Index: test/SemaCXX/friend2.cpp
===
--- test/SemaCXX/friend2.cpp
+++ test/SemaCXX/friend2.cpp
@@ -129,6 +129,83 @@
 void func_22() {} // expected-error{{redefinition of 'func_22'}}
 
 
+// Case of template friend functions.
+
+template void func_31(T *x);
+template
+struct C31a {
+  template friend void func_31(T *x) {}
+};
+template
+struct C31b {
+  template friend void func_31(T *x) {}
+};
+
+
+template inline void func_32(T *x) {}
+template
+struct C32a {
+  template friend void func_32(T *x) {}
+};
+template
+struct C32b {
+  template friend void func_32(T *x) {}
+};
+
+
+template
+struct C33a {
+  template friend void func_33(T *x) {}
+};
+template
+struct C33b {
+  template friend void func_33(T *x) {}
+};
+
+
+template inline void func_34(T *x) {}  // expected-note{{previous definition is here}}
+template
+struct C34 {
+  template friend void func_34(T *x) {} // expected-error{{redefinition of 'func_34'}}
+};
+
+C34 v34;  // expected-note{{in instantiation of template class 'C34' requested here}}
+
+
+template inline void func_35(T *x);
+template
+struct C35a {
+  template friend void func_35(T *x) {} // expected-note{{previous definition is here}}
+};
+template
+struct C35b {
+  template friend void func_35(T *x) {} // expected-error{{redefinition of 'func_35'}}
+};
+
+C35a v35a;
+C35b v35b;  // expected-note{{in instantiation of template class 'C35b' requested here}}
+
+
+template void func_36(T *x);
+template
+struct C36 {
+  template friend void func_36(T *x) {}  // expected-error{{redefinition of 'func_36'}}
+ // expected-note@-1{{previous definition is here}}
+};
+
+C36 v36a;
+C36 v36b;  //expected-note{{in instantiation of template class 'C36' requested here}}
+
+
+template void func_37(T *x);
+template
+struct C37 {
+  template friend void func_37(T *x) {} // expected-note{{previous definition is here}}
+};
+
+C37 v37;
+template void func_37(T *x) {} // expected-error{{redefinition of 'func_37'}}
+
 
 namespace pr22307 {
 
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1792,7 +1792,9 @@
   // If the original function was part of a friend declaration,
   // inherit its namespace state and add it to the owner.
   if (isFriend) {
-PrincipalDecl->setObjectOfFriendDecl();
+Function->setObjectOfFriendDecl();
+if (FunctionTemplate)
+  FunctionTemplate->setObjectOfFriendDecl();
 DC->makeDeclVisibleInContext(PrincipalDecl);
 
 bool QueuedInstantiation = false;
Index: lib/Sema/SemaDecl.cpp
===
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -11874,9 +11874,35 @@
const FunctionDecl *EffectiveDefinition,
SkipBodyInfo *SkipBody) {
   const FunctionDecl *Definition = EffectiveDefinition;
-  if (!Definition)
-if (!FD->isOdrDefined(Definition))
+  if (!Definition) {
+if (FunctionTemplateDecl *FTD = FD->getDescribedFunctionTemplate()) {
+  FunctionTemplateDecl *DefTD = nullptr;
+  if (!FTD->isDefined(DefTD))
+return;
+  const FunctionDecl *Def = DefTD->getTemplatedDecl();
+
+  // If the found definition is a template with uninstantiated body, it
+  // can be replaced in specialization:
+  //
+  //template struct X {
+  //  template void f(T, U) { }
+  //};
+  //template<> template void X::f(int x, U y) {
+  //  x = y;
+  //}
+  //
+  // In this example the specialization 'X' contains declaration of
+  // 'f', which is considered a definition by 'isDefined' because it is
+  // obtained by instantiation of 'X::f', which has a body.
+  //
+  if (isa(Def->getLexicalDeclContext()) &&
+  !Def->isThisDeclarationADefinition() &&
+  Def->getFriendObjectKind() == Decl::FOK_None)
+return;
+  Definition = Def;
+} else if (!FD->isOdrDefined(Definition))
   return;
+  }
   assert(Definition);
 
   if (FD == Definition)
Index: lib/AST/DeclTemplate.cpp
===
--- lib/AST/DeclTemplate.cpp
+++ lib/AST/DeclTemplate.cpp
@@ -231,6 +231,30 @@
   return CommonPtr;
 }
 
+bool FunctionTemplateDecl::isDefined(FunctionTemplateDecl *&Def) const {
+  FunctionTemplateDecl *UninstantiatedDef = nullptr;
+  for (auto I : redecls()) {
+auto FTD = 

[PATCH] D21508: Make friend function template definition available if class is instantiated.

2017-05-22 Thread Serge Pavlov via Phabricator via cfe-commits
sepavloff marked an inline comment as done.
sepavloff added inline comments.



Comment at: lib/AST/DeclTemplate.cpp:292-311
+FunctionTemplateDecl *FunctionTemplateDecl::getDefinition() const {
+  for (auto *R : redecls()) {
+FunctionTemplateDecl *F = cast(R);
+if (F->isThisDeclarationADefinition())
+  return F;
+
+// If template does not have a body, probably it is instantiated from

rsmith wrote:
> It seems to me that we're getting something fundamentally wrong in the way we 
> model friend function definitions where we've instantiated the declaration 
> but not the definition. Here's a case we get wrong on the 
> non-function-template side:
> 
>   template struct X { friend void f() {} };
>   X xi;
>   void f() {}
> 
> Line 3 should be ill-formed here due to redefinition, but we don't detect 
> that because we don't believe that the declaration we instantiated on line 2 
> is a definition. That seems to be the heart of the problem.
> 
> Instead of adding this function, can you try changing 
> `FunctionDecl::isThisDeclarationADefinition` to contain the above logic (that 
> is: if this function is a friend that was instantiated from a definition, 
> then it's a definition even if we don't have a body yet)?
The code snippet miscompiles due to another problem, it is related to friend 
functions, not function templates, and is addressed by D30170.

> Instead of adding this function, can you try changing 
> FunctionDecl::isThisDeclarationADefinition to contain the above logic

`FunctionDecl::isThisDeclarationADefinition` is used in many places, in some it 
should not consider uninstantiated bodies. Making special function for such 
checks makes the fix more compact and reduces the risk to break existing code. 
For function declarations it is `isThisDeclarationAnOdrDefinition` introduced 
in D30170, for function templates `isDefined` is created in the updated version 
of this patch.



Comment at: lib/Sema/SemaDecl.cpp:8856
+  (NewTemplateDecl->getFriendObjectKind() != Decl::FOK_None ||
+   OldTemplateDecl->getFriendObjectKind() != Decl::FOK_None))
+if (FunctionTemplateDecl *NewDef = NewTemplateDecl->getDefinition())

rsmith wrote:
> This doesn't look right; the `OldTemplateDecl` might be `FOK_None` but could 
> still have a definition as a `friend`.
> 
> I'm not convinced this is the right place for this check. There are two 
> different cases here:
> 
> 1) The redefinition error is introduced by parsing a definition in the source 
> code. That should already be handled by `ActOnStartOfFunctionDef`.
> 2) The redefinition error is introduced by instantiating a friend function 
> template declaration (that has a definition).
> 
> I think check (2) belongs in the template instantiation code rather than 
> here.  In fact, at the end of `TemplateDeclInstantiator::VisitFunctionDecl`, 
> there is an attempt to enforce the relevant rule; it just doesn't get all the 
> cases right.
Indeed, marking both `FunctionTemplateDecl` and corresponding `FunctionDecl` as 
friends was enough to make `TemplateDeclInstantiator::VisitFunctionDecl` work 
properly.

As for the case (1), the check was moved to `CheckForFunctionRedefinition`, 
which is eventually called from `ActOnStartOfFunctionDef`.


https://reviews.llvm.org/D21508



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31646: [coroutines] Build GRO declaration and return GRO statement

2017-05-22 Thread Richard Smith via Phabricator via cfe-commits
rsmith accepted this revision.
rsmith added a comment.
This revision is now accepted and ready to land.

LGTM




Comment at: lib/Sema/AnalysisBasedWarnings.cpp:338
+  // In a coroutine, only co_return statements count as normal returns. 
Remember
+  // if we are processing the coroutine or not.
+  const bool IsCoroutine = isa(AC.getBody());

the -> a



Comment at: lib/Sema/SemaCoroutine.cpp:1079-1083
+  // FIXME: ActOnReturnStmt expects a scope that is inside of the function, due
+  //   to CheckJumpOutOfSEHFinally(*this, ReturnLoc, *CurScope->getFnParent());
+  //   S.getCurScope()->getFnParent() == nullptr at ActOnFinishFunctionBody 
when
+  //   CoroutineBodyStmt is built. Figure it out and fix it.
+  //   Use BuildReturnStmt here to unbreak sanitized tests. (Gor:3/27/2017)

I'm not sure you need this FIXME; using `BuildReturnStmt` here instead of 
`ActOnReturnStmt` to skip the checks that we apply to parsed return statements 
but not instantiated return statements seems appropriate to me, so there's 
probably nothing to fix.


https://reviews.llvm.org/D31646



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31414: [NFC, Refactor] Modernize TemplateIdAnnotation using TrailingObjects

2017-05-22 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman accepted this revision.
aaron.ballman added a comment.
This revision is now accepted and ready to land.

LGTM!


https://reviews.llvm.org/D31414



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33333: Emit warning when throw exception in destruct or dealloc functions which has a (possible implicit) noexcept specifier

2017-05-22 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added a comment.

In https://reviews.llvm.org/D3#761233, @aaron.ballman wrote:

> In https://reviews.llvm.org/D3#761224, @rnk wrote:
>
> > Re: clang-tidy, I would rather implement this as a traditional compiler 
> > warning.
> >
> > In https://reviews.llvm.org/D3#761208, @aaron.ballman wrote:
> >
> > > In https://reviews.llvm.org/D3#761126, @jyu2 wrote:
> > >
> > > > As I said, I don't think checking throw type matching catch handler 
> > > > type is compiler's job.  I'd like either silence all warning for that.  
> > > > What do you think?
> > >
> > >
> > > Consider the following cases:
> > >  ...
> > >  I think the expected behavior in these cases is reasonable (and can be 
> > > done with a CFG) rather than manually looking at the scope stack like 
> > > you're doing.
> >
> >
> > I agree with @jyu2, we should do something simple. I think it would be 
> > simple to handle all cases except for `h`, which requires semantic analysis 
> > to figure out if the thrown object would be caught by the catch parameter. 
> > Implementing that is more likely to introduce bugs in the compiler than it 
> > is to find bugs in user code.
>
>
> I'm not certain I agree with the assertion it's more likely to introduce bugs 
> in the compiler than find bugs in user code. Machine-generated code runs into 
> silly things like this, and it's nice to warn the user about it. However, it 
> may be reasonable to do that in a follow-up patch -- but that patch is likely 
> to have a lot of churn since it's not really plausible to implement with the 
> way @jyu2 has structured this patch. By making this an analysis-based warning 
> instead, that would alleviate my concerns (but would likely require 
> implementing the CFG approach anyway).
>
> > I doubt we need the CFG for any of this. The later examples are all 
> > throwing exceptions from catch blocks, which is the same as not having an 
> > open try scope.
>
> Sure, if you cut out the cases that require a CFG, you don't need a CFG for 
> it. :-P Use of a CFG would eliminate obvious false-positives such as `h()`.
>
> Also, there should be some tests with function-try-blocks.


Sure, I will add that.


https://reviews.llvm.org/D3



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33333: Emit warning when throw exception in destruct or dealloc functions which has a (possible implicit) noexcept specifier

2017-05-22 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

In https://reviews.llvm.org/D3#761224, @rnk wrote:

> Re: clang-tidy, I would rather implement this as a traditional compiler 
> warning.
>
> In https://reviews.llvm.org/D3#761208, @aaron.ballman wrote:
>
> > In https://reviews.llvm.org/D3#761126, @jyu2 wrote:
> >
> > > As I said, I don't think checking throw type matching catch handler type 
> > > is compiler's job.  I'd like either silence all warning for that.  What 
> > > do you think?
> >
> >
> > Consider the following cases:
> >  ...
> >  I think the expected behavior in these cases is reasonable (and can be 
> > done with a CFG) rather than manually looking at the scope stack like 
> > you're doing.
>
>
> I agree with @jyu2, we should do something simple. I think it would be simple 
> to handle all cases except for `h`, which requires semantic analysis to 
> figure out if the thrown object would be caught by the catch parameter. 
> Implementing that is more likely to introduce bugs in the compiler than it is 
> to find bugs in user code.


I'm not certain I agree with the assertion it's more likely to introduce bugs 
in the compiler than find bugs in user code. Machine-generated code runs into 
silly things like this, and it's nice to warn the user about it. However, it 
may be reasonable to do that in a follow-up patch -- but that patch is likely 
to have a lot of churn since it's not really plausible to implement with the 
way @jyu2 has structured this patch. By making this an analysis-based warning 
instead, that would alleviate my concerns (but would likely require 
implementing the CFG approach anyway).

> I doubt we need the CFG for any of this. The later examples are all throwing 
> exceptions from catch blocks, which is the same as not having an open try 
> scope.

Sure, if you cut out the cases that require a CFG, you don't need a CFG for it. 
:-P Use of a CFG would eliminate obvious false-positives such as `h()`.

Also, there should be some tests with function-try-blocks.


https://reviews.llvm.org/D3



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31414: [NFC, Refactor] Modernize TemplateIdAnnotation using TrailingObjects

2017-05-22 Thread Faisal Vali via Phabricator via cfe-commits
faisalv marked 2 inline comments as done.
faisalv added a comment.

mark aaron's feedback as done.


https://reviews.llvm.org/D31414



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31414: [NFC, Refactor] Modernize TemplateIdAnnotation using TrailingObjects

2017-05-22 Thread Faisal Vali via Phabricator via cfe-commits
faisalv updated this revision to Diff 99787.
faisalv added a comment.

Incorporated Aaron's feedback - thanks Aaron!


https://reviews.llvm.org/D31414

Files:
  include/clang/Basic/TemplateKinds.h
  include/clang/Sema/ParsedTemplate.h
  lib/Parse/ParseExprCXX.cpp
  lib/Parse/ParseTemplate.cpp

Index: lib/Parse/ParseTemplate.cpp
===
--- lib/Parse/ParseTemplate.cpp
+++ lib/Parse/ParseTemplate.cpp
@@ -1011,25 +1011,21 @@
 // Build a template-id annotation token that can be processed
 // later.
 Tok.setKind(tok::annot_template_id);
-TemplateIdAnnotation *TemplateId
-  = TemplateIdAnnotation::Allocate(TemplateArgs.size(), TemplateIds);
-TemplateId->TemplateNameLoc = TemplateNameLoc;
-if (TemplateName.getKind() == UnqualifiedId::IK_Identifier) {
-  TemplateId->Name = TemplateName.Identifier;
-  TemplateId->Operator = OO_None;
-} else {
-  TemplateId->Name = nullptr;
-  TemplateId->Operator = TemplateName.OperatorFunctionId.Operator;
-}
-TemplateId->SS = SS;
-TemplateId->TemplateKWLoc = TemplateKWLoc;
-TemplateId->Template = Template;
-TemplateId->Kind = TNK;
-TemplateId->LAngleLoc = LAngleLoc;
-TemplateId->RAngleLoc = RAngleLoc;
-ParsedTemplateArgument *Args = TemplateId->getTemplateArgs();
-for (unsigned Arg = 0, ArgEnd = TemplateArgs.size(); Arg != ArgEnd; ++Arg)
-  Args[Arg] = ParsedTemplateArgument(TemplateArgs[Arg]);
+
+IdentifierInfo *TemplateII =
+TemplateName.getKind() == UnqualifiedId::IK_Identifier
+? TemplateName.Identifier
+: nullptr;
+
+OverloadedOperatorKind OpKind =
+TemplateName.getKind() == UnqualifiedId::IK_Identifier
+? OO_None
+: TemplateName.OperatorFunctionId.Operator;
+
+TemplateIdAnnotation *TemplateId = TemplateIdAnnotation::Create(
+  SS, TemplateKWLoc, TemplateNameLoc, TemplateII, OpKind, Template, TNK,
+  LAngleLoc, RAngleLoc, TemplateArgs, TemplateIds);
+
 Tok.setAnnotationValue(TemplateId);
 if (TemplateKWLoc.isValid())
   Tok.setLocation(TemplateKWLoc);
Index: lib/Parse/ParseExprCXX.cpp
===
--- lib/Parse/ParseExprCXX.cpp
+++ lib/Parse/ParseExprCXX.cpp
@@ -2120,31 +2120,18 @@
   Id.getKind() == UnqualifiedId::IK_LiteralOperatorId) {
 // Form a parsed representation of the template-id to be stored in the
 // UnqualifiedId.
-TemplateIdAnnotation *TemplateId
-  = TemplateIdAnnotation::Allocate(TemplateArgs.size(), TemplateIds);
 
 // FIXME: Store name for literal operator too.
-if (Id.getKind() == UnqualifiedId::IK_Identifier) {
-  TemplateId->Name = Id.Identifier;
-  TemplateId->Operator = OO_None;
-  TemplateId->TemplateNameLoc = Id.StartLocation;
-} else {
-  TemplateId->Name = nullptr;
-  TemplateId->Operator = Id.OperatorFunctionId.Operator;
-  TemplateId->TemplateNameLoc = Id.StartLocation;
-}
+IdentifierInfo *TemplateII =
+Id.getKind() == UnqualifiedId::IK_Identifier ? Id.Identifier : nullptr;
+OverloadedOperatorKind OpKind = Id.getKind() == UnqualifiedId::IK_Identifier
+? OO_None
+: Id.OperatorFunctionId.Operator;
 
-TemplateId->SS = SS;
-TemplateId->TemplateKWLoc = TemplateKWLoc;
-TemplateId->Template = Template;
-TemplateId->Kind = TNK;
-TemplateId->LAngleLoc = LAngleLoc;
-TemplateId->RAngleLoc = RAngleLoc;
-ParsedTemplateArgument *Args = TemplateId->getTemplateArgs();
-for (unsigned Arg = 0, ArgEnd = TemplateArgs.size(); 
- Arg != ArgEnd; ++Arg)
-  Args[Arg] = TemplateArgs[Arg];
-
+TemplateIdAnnotation *TemplateId = TemplateIdAnnotation::Create(
+SS, TemplateKWLoc, Id.StartLocation, TemplateII, OpKind, Template, TNK,
+LAngleLoc, RAngleLoc, TemplateArgs, TemplateIds);
+
 Id.setTemplateId(TemplateId);
 return false;
   }
Index: include/clang/Sema/ParsedTemplate.h
===
--- include/clang/Sema/ParsedTemplate.h
+++ include/clang/Sema/ParsedTemplate.h
@@ -145,12 +145,15 @@
   /// expressions, or template names, and the source locations for important 
   /// tokens. All of the information about template arguments is allocated 
   /// directly after this structure.
-  struct TemplateIdAnnotation {
+  struct TemplateIdAnnotation final
+  : private llvm::TrailingObjects {
+friend TrailingObjects;
 /// \brief The nested-name-specifier that precedes the template name.
 CXXScopeSpec SS;
 
-/// TemplateKWLoc - The location of the template keyword within the
-/// source.
+/// TemplateKWLoc - The location of the template keyword.
+/// For e.g. typename T::template Y
 SourceLocation TemplateKWLoc;
 
 /// TemplateNameLoc - The location of the template

[PATCH] D33333: Emit warning when throw exception in destruct or dealloc functions which has a (possible implicit) noexcept specifier

2017-05-22 Thread Reid Kleckner via Phabricator via cfe-commits
rnk added a comment.

Re: clang-tidy, I would rather implement this as a traditional compiler warning.

In https://reviews.llvm.org/D3#761208, @aaron.ballman wrote:

> In https://reviews.llvm.org/D3#761126, @jyu2 wrote:
>
> > As I said, I don't think checking throw type matching catch handler type is 
> > compiler's job.  I'd like either silence all warning for that.  What do you 
> > think?
>
>
> Consider the following cases:
>  ...
>  I think the expected behavior in these cases is reasonable (and can be done 
> with a CFG) rather than manually looking at the scope stack like you're doing.


I agree with @jyu2, we should do something simple. I think it would be simple 
to handle all cases except for `h`, which requires semantic analysis to figure 
out if the thrown object would be caught by the catch parameter. Implementing 
that is more likely to introduce bugs in the compiler than it is to find bugs 
in user code. I doubt we need the CFG for any of this. The later examples are 
all throwing exceptions from catch blocks, which is the same as not having an 
open try scope.


https://reviews.llvm.org/D3



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33333: Emit warning when throw exception in destruct or dealloc functions which has a (possible implicit) noexcept specifier

2017-05-22 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

In https://reviews.llvm.org/D3#761126, @jyu2 wrote:

> In https://reviews.llvm.org/D3#760431, @aaron.ballman wrote:
>
> > In https://reviews.llvm.org/D3#760419, @jyu2 wrote:
> >
> > > In https://reviews.llvm.org/D3#760149, @aaron.ballman wrote:
> > >
> > > > As an FYI, there is a related check currently under development in 
> > > > clang-tidy; we probably should not duplicate this functionality in both 
> > > > places. See https://reviews.llvm.org/D19201 for the other review.
> > >
> > >
> > > To my understanding, clang-tidy is kind of source check tool.  It does 
> > > more intensive checking than compiler.  
> > >  My purpose here is to emit minimum warning form compiler, in case, 
> > > clang-tidy is not used.
> >
> >
> > Sort of correct. clang-tidy doesn't necessarily do more intensive checking 
> > than the compiler. It's more an AST matching source checking tool for 
> > checks that are either expensive or have a higher false-positive rate than 
> > we'd want to see in the frontend.
> >
> > I think that this particular check should probably be in the frontend, like 
> > you're doing. My biggest concern is that we do not duplicate functionality 
> > between the two tools. https://reviews.llvm.org/D19201 has has a 
> > considerable amount of review, so you should look at the test cases there 
> > and ensure you are handling them (including the fixits). Hopefully your 
> > patch ends up covering all of the functionality in the clang-tidy patch.
> >
> > > In https://reviews.llvm.org/D3#760353, @Prazek wrote:
> > > 
> > >> Could you add similar tests as the ones that Stanislaw provied in his 
> > >> patch?
> > >>  Like the one with checking if throw is catched, or the conditional 
> > >> noexcept (by a macro, etc)
> > > 
> > > 
> > > Good idea!  Could add “marco” test for this.  But I am not sure compiler 
> > > want to add check for throw caught by different catch handler.  Because 
> > > at compile time, compiler can not statically determine which catch 
> > > handler will be used to caught the exception on all time.   I would think 
> > > that is pragma's responsibility.
> > > 
> > > For example:
> > > 
> > >   If (a) throw A else throw B;  
> > >
> > >
> > > 
> > > My main concern there is implicit noexcept gets set by compiler, which 
> > > cause runtime to termination.
>
>
> As I said, I don't think checking throw type matching catch handler type is 
> compiler's job.  I'd like either silence all warning for that.  What do you 
> think?


Consider the following cases:

  void f() noexcept { // Should not diagnose
try {
  throw 12;
} catch (int) {
}
  }
  
  void g() noexcept { // Should not diagnose
try {
  throw 12;
} catch (...) {
}
  }
  
  void h() noexcept { // Should diagnose
try {
  throw 12;
} catch (const char *) {
}
  }
  
  void i() noexcept { // Should diagnose
try {
  throw 12;
} catch (int) {
  throw;
}
  }
  
  void j() noexcept { // Should diagnose
try {
  throw 12;
} catch (int) {
  throw "haha";
}
  }
  
  void k() noexcept { // Should diagnose
try {
  throw 12;
} catch (...) {
  throw;
}
  }

I think the expected behavior in these cases is reasonable (and can be done 
with a CFG) rather than manually looking at the scope stack like you're doing.




Comment at: include/clang/Basic/DiagnosticGroups.td:140
 def Exceptions : DiagGroup<"exceptions">;
+def ThrowInNoexceptFunc : DiagGroup<"throw-in-noexcept-function">;
 

No need to add a group for this; you can define one inline with the warning, 
but perhaps the exceptions group already covers it.



Comment at: include/clang/Basic/DiagnosticSemaKinds.td:6335
+def warn_throw_in_noexcept_func 
+: Warning<"'%0' function assumed not to throw an exception but does. "
+  "Throwing exception may cause termination.">, 

Do not quote %0. Also, remove the full-stop and capitalized "Throwing". 
Diagnostics are not complete sentences. I think it should probably read `"%0 
has a non-throwing exception specification but can still throw, resulting in 
unexpected program termination"` (or something along those lines).



Comment at: include/clang/Basic/DiagnosticSemaKinds.td:6342
+def note_throw_in_function 
+: Note<"__declspec(nothrow), throw(), noexcept(true), or noexcept was "
+  "specified on the function">;

Rather than make the note spell out all the various ways a function can be 
nothrow, we should either say "nonthrowing function declare here" or specify 
which reason the function is not throwing using %select.



Comment at: include/clang/Sema/Sema.h:4970
   bool CheckCXXThrowOperand(SourceLocation ThrowLoc, QualType ThrowTy, Expr 
*E);
+  /// Check if throw is used in function with non-throwing noexcept 
+  /// specifier.

with non

Re: r303546 - [mips] Support `micromips` attribute

2017-05-22 Thread Aaron Ballman via cfe-commits
On Mon, May 22, 2017 at 12:00 PM, Simon Atanasyan  wrote:
> On Mon, May 22, 2017 at 3:57 PM, Aaron Ballman  wrote:
>> On Mon, May 22, 2017 at 8:47 AM, Simon Atanasyan via cfe-commits
>>  wrote:
>>> Author: atanasyan
>>> Date: Mon May 22 07:47:43 2017
>>> New Revision: 303546
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=303546&view=rev
>>> Log:
>>> [mips] Support `micromips` attribute
>>>
>>> This patch adds support for the `micromips` and `nomicromips` attributes
>>> for MIPS targets.
>>>
>>> Differential revision: https://reviews.llvm.org/D33363
>
> [...]
>
>>> Modified: cfe/trunk/include/clang/Basic/Attr.td
>>> URL: 
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=303546&r1=303545&r2=303546&view=diff
>>> ==
>>> --- cfe/trunk/include/clang/Basic/Attr.td (original)
>>> +++ cfe/trunk/include/clang/Basic/Attr.td Mon May 22 07:47:43 2017
>>> @@ -1179,6 +1179,12 @@ def MipsInterrupt : InheritableAttr, Tar
>>>let Documentation = [MipsInterruptDocs];
>>>  }
>>>
>>> +def MicroMips : InheritableAttr, TargetSpecificAttr {
>>> +  let Spellings = [GCC<"micromips">];
>>> +  let Subjects = SubjectList<[Function], ErrorDiag>;
>>
>> Why is this an error rather than a warning? Same question below.
>
> Because GCC shows the error in this case. And I cannot imagine any
> reason why micromips attribute added to non-function declaration.

Misapplication of attributes generally means the attribute is ignored;
assuming the program can continue to execute reasonably with the
attribute ignored, we usually don't diagnose as an error. I can't
think of a reason why ignoring this attribute would require us to fail
to translate the program. (This is why the default behavior of the
SubjectList is to warn rather than err, btw.)

Thank you for the other fixes!

~Aaron

>
> % mips-mti-linux-gnu-gcc --version
> mips-mti-linux-gnu-gcc (Codescape GNU Tools 2016.05-01 for MIPS MTI Linux) 
> 4.9.2
>
> % mips-mti-linux-gnu-gcc -c attr-micromips.c
> tools/clang/test/Sema/attr-micromips.c:6:1: error: ‘nomicromips’
> attribute only applies to functions
>  __attribute((nomicromips)) int a; // expected-error {{attribute only
> applies to functions}}
>  ^
> tools/clang/test/Sema/attr-micromips.c:7:1: error: ‘micromips’
> attribute only applies to functions
>  __attribute((micromips)) int b;   // expected-error {{attribute only
> applies to functions}}
>
>>> Modified: cfe/trunk/include/clang/Basic/AttrDocs.td
>>> URL: 
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrDocs.td?rev=303546&r1=303545&r2=303546&view=diff
>>> ==
>>> --- cfe/trunk/include/clang/Basic/AttrDocs.td (original)
>>> +++ cfe/trunk/include/clang/Basic/AttrDocs.td Mon May 22 07:47:43 2017
>>> @@ -1269,6 +1269,19 @@ The semantics are as follows:
>>>}];
>>>  }
>>>
>>> +def MicroMipsDocs : Documentation {
>>> +  let Category = DocCatFunction;
>>> +  let Content = [{
>>> +Clang supports the GNU style ``__attribute__((micromips))`` and
>>> +``__attribute__((nomicromips))`` attributes on MIPS targets. These 
>>> attributes
>>> +may be attached to a function definition and instructs the backend to 
>>> generate
>>> +or not to generate microMIPS code for that function.
>>> +
>>> +These attributes override the -mmicromips and -mno-micromips options
>>
>> Please quote the command line options with ``.
>
> Fixed at r303564.
>
>>> Added: cfe/trunk/test/Sema/attr-micromips.c
>>> URL: 
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-micromips.c?rev=303546&view=auto
>>> ==
>>> --- cfe/trunk/test/Sema/attr-micromips.c (added)
>>> +++ cfe/trunk/test/Sema/attr-micromips.c Mon May 22 07:47:43 2017
>>> @@ -0,0 +1,15 @@
>>> +// RUN: %clang_cc1 -triple mips-linux-gnu -fsyntax-only -verify %s
>>> +
>>> +__attribute__((nomicromips(0))) void foo1();  // expected-error 
>>> {{'nomicromips' attribute takes no arguments}}
>>> +__attribute__((micromips(1))) void foo2();// expected-error 
>>> {{'micromips' attribute takes no arguments}}
>>> +
>>> +__attribute((nomicromips)) int a; // expected-error {{attribute only 
>>> applies to functions}}
>>> +__attribute((micromips)) int b;   // expected-error {{attribute only 
>>> applies to functions}}
>>> +
>>> +__attribute__((micromips,mips16)) void foo5();  // expected-error 
>>> {{'micromips' and 'mips16' attributes are not compatible}} \
>>> +// expected-note 
>>> {{conflicting attribute is here}}
>>> +__attribute__((mips16,micromips)) void foo6();  // expected-error 
>>> {{'mips16' and 'micromips' attributes are not compatible}} \
>>> +// expected-note 
>>> {{conflicting attribute is here}}
>>
>> Can you also add a test like:
>>
>> __attribute__((mips16)) 

[PATCH] D33272: Method loadFromCommandLine should be able to report errors

2017-05-22 Thread Serge Pavlov via Phabricator via cfe-commits
sepavloff added a comment.

Thank you!

I put updated fix here. If it is OK, I'll commit it tomorrow.




Comment at: lib/Tooling/CompilationDatabase.cpp:292
+  if (Argc == 0) {
+ErrorMsg = "error: no arguments specified\n";
+return nullptr;

alexfh wrote:
> The lack of the arguments (or the `--` below) shouldn't be treated as an 
> error (at least an error that is worth showing to the user). The caller will 
> just move on to trying the next kind of a compilation database. The only 
> actual errors we can get here may be coming from `stripPositionalArgs`.
> 
> The caller should be modified accordingly (i.e. not output anything when both 
> the return value is `nullptr` and `ErrorMsg` is empty).
What if error message contains a prefix that indicates if this is error or 
warning? Errors could be printed and warnings ignored in 
`CommonOptionsParser.cpp:122`. Such solution would allow clients to investigate 
failures in more details.



https://reviews.llvm.org/D33272



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33272: Method loadFromCommandLine should be able to report errors

2017-05-22 Thread Serge Pavlov via Phabricator via cfe-commits
sepavloff updated this revision to Diff 99786.
sepavloff marked an inline comment as done.
sepavloff added a comment.

Addressed reviewer's notes.


https://reviews.llvm.org/D33272

Files:
  include/clang/Tooling/CompilationDatabase.h
  lib/Frontend/CreateInvocationFromCommandLine.cpp
  lib/Tooling/CommonOptionsParser.cpp
  lib/Tooling/CompilationDatabase.cpp
  lib/Tooling/Tooling.cpp
  unittests/Tooling/CompilationDatabaseTest.cpp

Index: unittests/Tooling/CompilationDatabaseTest.cpp
===
--- unittests/Tooling/CompilationDatabaseTest.cpp
+++ unittests/Tooling/CompilationDatabaseTest.cpp
@@ -504,29 +504,35 @@
 
 TEST(ParseFixedCompilationDatabase, ReturnsNullOnEmptyArgumentList) {
   int Argc = 0;
-  std::unique_ptr Database(
-  FixedCompilationDatabase::loadFromCommandLine(Argc, nullptr));
+  std::string ErrorMsg;
+  std::unique_ptr Database =
+  FixedCompilationDatabase::loadFromCommandLine(Argc, nullptr, ErrorMsg);
   EXPECT_FALSE(Database);
+  EXPECT_EQ(ErrorMsg, "warning: no arguments specified\n");
   EXPECT_EQ(0, Argc);
 }
 
 TEST(ParseFixedCompilationDatabase, ReturnsNullWithoutDoubleDash) {
   int Argc = 2;
   const char *Argv[] = { "1", "2" };
+  std::string ErrorMsg;
   std::unique_ptr Database(
-  FixedCompilationDatabase::loadFromCommandLine(Argc, Argv));
+  FixedCompilationDatabase::loadFromCommandLine(Argc, Argv, ErrorMsg));
   EXPECT_FALSE(Database);
+  EXPECT_EQ(ErrorMsg, "warning: double dash not found\n");
   EXPECT_EQ(2, Argc);
 }
 
 TEST(ParseFixedCompilationDatabase, ReturnsArgumentsAfterDoubleDash) {
   int Argc = 5;
   const char *Argv[] = {
 "1", "2", "--\0no-constant-folding", "-DDEF3", "-DDEF4"
   };
+  std::string ErrorMsg;
   std::unique_ptr Database(
-  FixedCompilationDatabase::loadFromCommandLine(Argc, Argv));
+  FixedCompilationDatabase::loadFromCommandLine(Argc, Argv, ErrorMsg));
   ASSERT_TRUE((bool)Database);
+  ASSERT_TRUE(ErrorMsg.empty());
   std::vector Result =
 Database->getCompileCommands("source");
   ASSERT_EQ(1ul, Result.size());
@@ -543,9 +549,11 @@
 TEST(ParseFixedCompilationDatabase, ReturnsEmptyCommandLine) {
   int Argc = 3;
   const char *Argv[] = { "1", "2", "--\0no-constant-folding" };
-  std::unique_ptr Database(
-  FixedCompilationDatabase::loadFromCommandLine(Argc, Argv));
+  std::string ErrorMsg;
+  std::unique_ptr Database =
+  FixedCompilationDatabase::loadFromCommandLine(Argc, Argv, ErrorMsg);
   ASSERT_TRUE((bool)Database);
+  ASSERT_TRUE(ErrorMsg.empty());
   std::vector Result =
 Database->getCompileCommands("source");
   ASSERT_EQ(1ul, Result.size());
@@ -560,9 +568,11 @@
 TEST(ParseFixedCompilationDatabase, HandlesPositionalArgs) {
   const char *Argv[] = {"1", "2", "--", "-c", "somefile.cpp", "-DDEF3"};
   int Argc = sizeof(Argv) / sizeof(char*);
-  std::unique_ptr Database(
-  FixedCompilationDatabase::loadFromCommandLine(Argc, Argv));
+  std::string ErrorMsg;
+  std::unique_ptr Database =
+  FixedCompilationDatabase::loadFromCommandLine(Argc, Argv, ErrorMsg);
   ASSERT_TRUE((bool)Database);
+  ASSERT_TRUE(ErrorMsg.empty());
   std::vector Result =
 Database->getCompileCommands("source");
   ASSERT_EQ(1ul, Result.size());
@@ -579,9 +589,11 @@
 TEST(ParseFixedCompilationDatabase, HandlesArgv0) {
   const char *Argv[] = {"1", "2", "--", "mytool", "somefile.cpp"};
   int Argc = sizeof(Argv) / sizeof(char*);
-  std::unique_ptr Database(
-  FixedCompilationDatabase::loadFromCommandLine(Argc, Argv));
+  std::string ErrorMsg;
+  std::unique_ptr Database =
+  FixedCompilationDatabase::loadFromCommandLine(Argc, Argv, ErrorMsg);
   ASSERT_TRUE((bool)Database);
+  ASSERT_TRUE(ErrorMsg.empty());
   std::vector Result =
 Database->getCompileCommands("source");
   ASSERT_EQ(1ul, Result.size());
Index: lib/Tooling/Tooling.cpp
===
--- lib/Tooling/Tooling.cpp
+++ lib/Tooling/Tooling.cpp
@@ -260,6 +260,8 @@
   Driver->setCheckInputsExist(false);
   const std::unique_ptr Compilation(
   Driver->BuildCompilation(llvm::makeArrayRef(Argv)));
+  if (!Compilation)
+return false;
   const llvm::opt::ArgStringList *const CC1Args = getCC1Arguments(
   &Diagnostics, Compilation.get());
   if (!CC1Args) {
Index: lib/Tooling/CompilationDatabase.cpp
===
--- lib/Tooling/CompilationDatabase.cpp
+++ lib/Tooling/CompilationDatabase.cpp
@@ -27,6 +27,7 @@
 #include "llvm/Option/Arg.h"
 #include "llvm/Support/Host.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
 #include 
 #include 
 using namespace clang;
@@ -150,23 +151,21 @@
 // options.
 class UnusedInputDiagConsumer : public DiagnosticConsumer {
 public:
-  UnusedInputDiagConsumer() : Other(nullptr) {}
-
-  // Useful for debugging, chain diagnostics to another consumer after
-  // recording for our own purposes.
-  UnusedInputDiag

[PATCH] D33170: [X86] Adding avx512_vpopcntdq feature set and its intrinsics

2017-05-22 Thread Craig Topper via Phabricator via cfe-commits
craig.topper accepted this revision.
craig.topper added a comment.
This revision is now accepted and ready to land.

LGTM




Comment at: lib/CodeGen/CGBuiltin.cpp:7526
+llvm::Type *ResultType = ConvertType(E->getType());
+llvm::Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ResultType);
+return Builder.CreateCall(F, Ops);

oren_ben_simhon wrote:
> oren_ben_simhon wrote:
> > craig.topper wrote:
> > > Why did the call to ConvertType come back? This code can just be
> > > 
> > > 
> > > ```
> > > llvm::Function *F = CGM.getIntrinsic(Intrinsic::ctpop, Ops[0]->getType());
> > > return Builder.CreateCall(F, Ops);
> > > ```
> > After checking it again, I reverted that change because AFAIK Ops[0] is the 
> > first argument and not the return type of the statement.
> After checking it again, I reverted that change because AFAIK Ops[0] is the 
> first argument and not the return type of the statement.  
That's true, but for this intrinsic they are required to be the same type. But 
its not a big deal.


Repository:
  rL LLVM

https://reviews.llvm.org/D33170



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33277: [Clang][x86][Inline Asm] - Enum support for MS syntax

2017-05-22 Thread Reid Kleckner via Phabricator via cfe-commits
rnk added inline comments.



Comment at: lib/Sema/SemaStmtAsm.cpp:674
+  Expr::EvalResult EvlResult;
+  // Try to evaluate the identifier as enum constant
+  if (isa(Res->getType()) && Res->EvaluateAsRValue(EvlResult, 

Please add a comment explaining that non-enum integer constants should not be 
folded. I expected that MSVC would fold constexpr integers here, but it does 
not, so that's worth noting.



Comment at: test/CodeGen/x86-ms-inline-asm-enum_feature.cpp:12
+  const int a = 0;
+  // CHECK-NOT: mov eax, [$$0]
+  __asm mov eax, [a]

mharoush wrote:
> rnk wrote:
> > Use CHECK-LABEL, CHECK, and CHECK-SAME the way that the existing 
> > ms-inline-asm.c tests do so that this test is easier to debug when it fails.
> This test case was just meant verify that other Integer constants are not 
> folded since we get a different behavior for statements such as mov eax, [a]. 
> #---
> In this example X86AsmParser regards the address of the variable 'a' and not 
> its value i.e. we end up with the value of 'a' in eax (loaded from the stack) 
> and not with the value pointed by the const int value of 'a' as its address.
> ---#
> 
> I can clarify the intention in a comment or completely remove the test case 
> since this isn't really required here.
The test case is fine and the intention is clear, I am just suggesting that you 
use more FileCheck features (CHECK-LABEL and CHECK-SAME) to make the test 
easier to debug when it fails in the future.


Repository:
  rL LLVM

https://reviews.llvm.org/D33277



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33278: [LLVM][x86][Inline Asm] - Enum support for MS syntax

2017-05-22 Thread Reid Kleckner via Phabricator via cfe-commits
rnk added inline comments.



Comment at: include/llvm/MC/MCParser/MCAsmParser.h:64
 unsigned &Offset) = 0;
+  virtual bool EvaluateLookupAsEnum(void *LookupResult,int64_t &Result) = 0;
 };

mharoush wrote:
> rnk wrote:
> > It would be cleaner if InlineAsmIdentifierInfo simply contained an APInt 
> > indicating that the identifier in question was an enum, or other integral 
> > constant expression. Less callbacks to implement.
> Done
Thanks! This is better.



Comment at: include/llvm/MC/MCParser/MCAsmParser.h:40
   void *OpDecl;
   bool IsVarDecl;
   unsigned Length, Size, Type;

Please group the booleans to reduce padding. Ideally, make this an enum 
something like:
```
enum IdKind : uint8_t {
  Variable,
  Function,
  ConstInt,
};
IdKind Kind;
```
This is smaller and prevents nonsense states.



Comment at: lib/Target/X86/AsmParser/X86AsmParser.cpp:1382
+if (const MCConstantExpr *CE = 
+dyn_cast_or_null(Val)) {
+  StringRef ErrMsg;

Please use clang-format here and elsewhere



Comment at: lib/Target/X86/AsmParser/X86AsmParser.cpp:722
+  bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End, 
+bool &ReplaceEnumIdentifier);
   std::unique_ptr

mharoush wrote:
> rnk wrote:
> > Please try to eliminate the need for this extra boolean out parameter.
> This flag is used in case we try to compile something like mov edx, A+6 ( 
> when A is defined as ConstantEnum ) the original condition (Line:1905) will 
> skip the rewrite since we have an identifier as the first Token, however if 
> we try to compile 6+A it will be rewritten as expected.
> 
> I tried to solve this in different ways, I got either the exact opposite (A+6 
> was replaced and 6+A wasn't) or a collision of rewrites when trying to 
> preform other forms of replacements and leaving this section intact. 
> 
> I can perhaps change the way we handle general expressions to the same way we 
> handle them under parseIntelBracExpression, meaning use the first iteration 
> of X86AsmParser to reformat the string (write imm prefixes and replace 
> identifiers when needed) then refactor the string to its canonical form on 
> the second pass. 
> 
> In short this was the simplest solution that worked without regression, maybe 
> you have a better idea?
> 
> If the issue is the method signature pollution I can move this flag into the 
> SM class as a member to indicate a rewrite is needed, however since this flag 
> and method are limited to this context alone, I am not sure if the overhead 
> is wanted in such case . 
I suspect there is a way to simplify the code so that this corner case no 
longer exists. I don't really have time to dig through the test cases to come 
up with it, but please make an effort.


Repository:
  rL LLVM

https://reviews.llvm.org/D33278



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r303568 - [index] Index the default template parameter values

2017-05-22 Thread Alex Lorenz via cfe-commits
Author: arphaman
Date: Mon May 22 11:50:54 2017
New Revision: 303568

URL: http://llvm.org/viewvc/llvm-project?rev=303568&view=rev
Log:
[index] Index the default template parameter values

rdar://32323724

Modified:
cfe/trunk/lib/Index/IndexDecl.cpp
cfe/trunk/test/Index/Core/index-source.cpp

Modified: cfe/trunk/lib/Index/IndexDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/IndexDecl.cpp?rev=303568&r1=303567&r2=303568&view=diff
==
--- cfe/trunk/lib/Index/IndexDecl.cpp (original)
+++ cfe/trunk/lib/Index/IndexDecl.cpp Mon May 22 11:50:54 2017
@@ -63,6 +63,17 @@ public:
 case TemplateArgument::Type:
   IndexCtx.indexTypeSourceInfo(LocInfo.getAsTypeSourceInfo(), Parent, DC);
   break;
+case TemplateArgument::Template:
+case TemplateArgument::TemplateExpansion:
+  IndexCtx.indexNestedNameSpecifierLoc(TALoc.getTemplateQualifierLoc(),
+   Parent, DC);
+  if (const TemplateDecl *TD = TALoc.getArgument()
+   .getAsTemplateOrTemplatePattern()
+   .getAsTemplateDecl()) {
+if (const NamedDecl *TTD = TD->getTemplatedDecl())
+  IndexCtx.handleReference(TTD, TALoc.getTemplateNameLoc(), Parent, 
DC);
+  }
+  break;
 default:
   break;
 }
@@ -610,8 +621,43 @@ public:
 return true;
   }
 
+  static bool shouldIndexTemplateParameterDefaultValue(const NamedDecl *D) {
+if (!D)
+  return false;
+// We want to index the template parameters only once when indexing the
+// canonical declaration.
+if (const auto *FD = dyn_cast(D))
+  return FD->getCanonicalDecl() == FD;
+else if (const auto *TD = dyn_cast(D))
+  return TD->getCanonicalDecl() == TD;
+else if (const auto *VD = dyn_cast(D))
+  return VD->getCanonicalDecl() == VD;
+return true;
+  }
+
   bool VisitTemplateDecl(const TemplateDecl *D) {
 // FIXME: Template parameters.
+
+// Index the default values for the template parameters.
+const NamedDecl *Parent = D->getTemplatedDecl();
+if (D->getTemplateParameters() &&
+shouldIndexTemplateParameterDefaultValue(Parent)) {
+  const TemplateParameterList *Params = D->getTemplateParameters();
+  for (const NamedDecl *TP : *Params) {
+if (const auto *TTP = dyn_cast(TP)) {
+  if (TTP->hasDefaultArgument())
+IndexCtx.indexTypeSourceInfo(TTP->getDefaultArgumentInfo(), 
Parent);
+} else if (const auto *NTTP = dyn_cast(TP)) {
+  if (NTTP->hasDefaultArgument())
+IndexCtx.indexBody(NTTP->getDefaultArgument(), Parent);
+} else if (const auto *TTPD = dyn_cast(TP)) {
+  if (TTPD->hasDefaultArgument())
+handleTemplateArgumentLoc(TTPD->getDefaultArgument(), Parent,
+  /*DC=*/nullptr);
+}
+  }
+}
+
 return Visit(D->getTemplatedDecl());
   }
 

Modified: cfe/trunk/test/Index/Core/index-source.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/Core/index-source.cpp?rev=303568&r1=303567&r2=303568&view=diff
==
--- cfe/trunk/test/Index/Core/index-source.cpp (original)
+++ cfe/trunk/test/Index/Core/index-source.cpp Mon May 22 11:50:54 2017
@@ -374,3 +374,62 @@ struct DeletedMethods {
 // CHECK: [[@LINE-3]]:24 | struct/C++ | DeletedMethods | c:@S@DeletedMethods | 
 | Ref,RelCont | rel: 1
 // CHECK: [[@LINE-4]]:3 | struct/C++ | DeletedMethods | c:@S@DeletedMethods | 
 | Ref,RelCont | rel: 1
 };
+
+namespace ns2 {
+template struct ACollectionDecl { };
+}
+
+template | 
Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | TemplateDefaultValues | 
c:@ST>3#T#NI#t>1#T@TemplateDefaultValues
+ int x = Record::C,
+// CHECK: [[@LINE-1]]:26 | static-property/C++ | C | c:@S@Record@C | 
__ZN6Record1CE | Ref,Read,RelCont | rel: 1
+// CHECK-NEXT: RelCont | TemplateDefaultValues | 
c:@ST>3#T#NI#t>1#T@TemplateDefaultValues
+// CHECK: [[@LINE-3]]:18 | struct/C++ | Record | c:@S@Record |  | 
Ref,RelCont | rel: 1
+ template  class Collection = ns2::ACollectionDecl>
+// CHECK: [[@LINE-1]]:49 | namespace/C++ | ns2 | c:@N@ns2 |  | 
Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | TemplateDefaultValues | 
c:@ST>3#T#NI#t>1#T@TemplateDefaultValues
+// CHECK: [[@LINE-3]]:54 | struct(Gen)/C++ | ACollectionDecl | 
c:@N@ns2@ST>1#T@ACollectionDecl |  | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | TemplateDefaultValues | 
c:@ST>3#T#NI#t>1#T@TemplateDefaultValues
+struct TemplateDefaultValues { };
+
+template | 
Ref,RelCont | rel: 1
+ int x = sizeof(Cls)>
+// CHECK: [[@LINE-1]]:25 | class/C++ | Cls | c:@S@Cls |  | 
Ref,RelCont | rel: 1
+void functionTemplateDefaultValues() { }
+
+namespace ensureDefaultTemplateParamsAreRecordedOnce {
+
+template
+// CHECK: [[@LINE-1]]:23 | class/C++ | 

[PATCH] D33368: [libcxxabi][demangler] Fix a crash in the demangler

2017-05-22 Thread Erik Pilkington via Phabricator via cfe-commits
erik.pilkington added inline comments.



Comment at: src/cxa_demangle.cpp:3036
 break;
-if (db.names.size() < 2)
+if (k1 <= k0)
 return first;

compnerd wrote:
> I'm not sure how `k1` can be `<` than `k0`.  Isn't this effectively always 
> going down the `==` path?  If I'm just mistaken, then I think that this needs 
> a comment.
I agree that it should be impossible, but the previous version handled this 
case with the `if (db.names.size() < 2)` check, when really `db.names.size()` 
can only be 1 or greater. I think it makes more sense to be paranoid here, I 
trust this file about as far as I can throw it (And I can't throw it very far, 
its not a tangible object).


https://reviews.llvm.org/D33368



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33277: [Clang][x86][Inline Asm] - Enum support for MS syntax

2017-05-22 Thread Matan via Phabricator via cfe-commits
mharoush marked an inline comment as done.
mharoush added inline comments.



Comment at: lib/Parse/ParseStmtAsm.cpp:100
+  // result of a call to LookupInlineAsmIdentifier.
+  bool EvaluateLookupAsEnum(void *LookupResult, int64_t &Result) {
+if (!LookupResult) return false;

rnk wrote:
> Please format this, clang-format will do the job
Revised



Comment at: test/CodeGen/x86-ms-inline-asm-enum_feature.cpp:12
+  const int a = 0;
+  // CHECK-NOT: mov eax, [$$0]
+  __asm mov eax, [a]

rnk wrote:
> Use CHECK-LABEL, CHECK, and CHECK-SAME the way that the existing 
> ms-inline-asm.c tests do so that this test is easier to debug when it fails.
This test case was just meant verify that other Integer constants are not 
folded since we get a different behavior for statements such as mov eax, [a]. 
#---
In this example X86AsmParser regards the address of the variable 'a' and not 
its value i.e. we end up with the value of 'a' in eax (loaded from the stack) 
and not with the value pointed by the const int value of 'a' as its address.
---#

I can clarify the intention in a comment or completely remove the test case 
since this isn't really required here.


Repository:
  rL LLVM

https://reviews.llvm.org/D33277



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33395: [clangd] Split clangd into library+executable (mainly for unit tests).

2017-05-22 Thread Benjamin Kramer via Phabricator via cfe-commits
bkramer accepted this revision.
bkramer added a comment.
This revision is now accepted and ready to land.

looks good to me


https://reviews.llvm.org/D33395



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33277: [Clang][x86][Inline Asm] - Enum support for MS syntax

2017-05-22 Thread Matan via Phabricator via cfe-commits
mharoush updated this revision to Diff 99780.
mharoush added a comment.

removed functions and dropped an irrelevant test case.


Repository:
  rL LLVM

https://reviews.llvm.org/D33277

Files:
  lib/Sema/SemaStmtAsm.cpp
  test/CodeGen/x86-ms-inline-asm-enum_feature.cpp


Index: lib/Sema/SemaStmtAsm.cpp
===
--- lib/Sema/SemaStmtAsm.cpp
+++ lib/Sema/SemaStmtAsm.cpp
@@ -662,11 +662,21 @@
   }
 
   fillInlineAsmTypeInfo(Context, T, Info);
-
+  
+  Expr *Res = Result.get();
   // We can work with the expression as long as it's not an r-value.
-  if (!Result.get()->isRValue())
+  if (!Res->isRValue()) {
 Info.IsVarDecl = true;
+return Result;
+  }
 
+  Expr::EvalResult EvlResult;
+  // Try to evaluate the identifier as enum constant
+  if (isa(Res->getType()) && Res->EvaluateAsRValue(EvlResult, 
+   getASTContext())) {
+Info.ConstIntValue = EvlResult.Val.getInt();
+Info.IsConstEnum = true;
+  }
   return Result;
 }
 
Index: test/CodeGen/x86-ms-inline-asm-enum_feature.cpp
===
--- test/CodeGen/x86-ms-inline-asm-enum_feature.cpp
+++ test/CodeGen/x86-ms-inline-asm-enum_feature.cpp
@@ -0,0 +1,44 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 %s -fasm-blocks -emit-llvm -o - | FileCheck %s
+namespace x {
+enum { A = 12 };
+namespace y {
+enum { A = 17 };
+}
+}
+
+void x86_enum_namespaces() {
+  enum { A = 1 };
+  // CHECK: mov eax, $$12
+  __asm mov eax, x::A
+  // CHECK: mov eax, $$17
+  __asm mov eax, x::y::A
+  // CHECK: mov eax, $$1
+  __asm mov eax, A
+}
+
+void x86_enum_arithmethic() {
+  enum { A = 1, B };
+  // CHECK: mov eax, $$21
+  __asm mov eax, (A + 9) * 2 + A
+  // CHECK: mov eax, $$4
+  __asm mov eax, A << 2
+  // CHECK: mov eax, $$2
+  __asm mov eax, B & 3
+  // CHECK: mov eax, $$5
+  __asm mov eax, 3 + (B & 3)
+  // CHECK: mov eax, $$8
+  __asm mov eax, 2 << A * B
+}
+
+void x86_enum_mem() {
+  int arr[4];
+  enum { A = 4, B };
+  
+  // CHECK: mov eax, [($$12 + $$9) + $$4 * $$5 + $$3 + $$3 + eax]
+  __asm { mov eax, [(x::A + 9) + A * B + 3 + 3 + eax] }
+  // CHECK: mov eax, dword ptr $$4$0
+  __asm { mov eax, dword ptr [arr + A] }
+  // CHECK: mov eax, dword ptr $$8$0
+  __asm { mov eax, dword ptr A[arr + A] }
+}
\ No newline at end of file


Index: lib/Sema/SemaStmtAsm.cpp
===
--- lib/Sema/SemaStmtAsm.cpp
+++ lib/Sema/SemaStmtAsm.cpp
@@ -662,11 +662,21 @@
   }
 
   fillInlineAsmTypeInfo(Context, T, Info);
-
+  
+  Expr *Res = Result.get();
   // We can work with the expression as long as it's not an r-value.
-  if (!Result.get()->isRValue())
+  if (!Res->isRValue()) {
 Info.IsVarDecl = true;
+return Result;
+  }
 
+  Expr::EvalResult EvlResult;
+  // Try to evaluate the identifier as enum constant
+  if (isa(Res->getType()) && Res->EvaluateAsRValue(EvlResult, 
+   getASTContext())) {
+Info.ConstIntValue = EvlResult.Val.getInt();
+Info.IsConstEnum = true;
+  }
   return Result;
 }
 
Index: test/CodeGen/x86-ms-inline-asm-enum_feature.cpp
===
--- test/CodeGen/x86-ms-inline-asm-enum_feature.cpp
+++ test/CodeGen/x86-ms-inline-asm-enum_feature.cpp
@@ -0,0 +1,44 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 %s -fasm-blocks -emit-llvm -o - | FileCheck %s
+namespace x {
+enum { A = 12 };
+namespace y {
+enum { A = 17 };
+}
+}
+
+void x86_enum_namespaces() {
+  enum { A = 1 };
+  // CHECK: mov eax, $$12
+  __asm mov eax, x::A
+  // CHECK: mov eax, $$17
+  __asm mov eax, x::y::A
+  // CHECK: mov eax, $$1
+  __asm mov eax, A
+}
+
+void x86_enum_arithmethic() {
+  enum { A = 1, B };
+  // CHECK: mov eax, $$21
+  __asm mov eax, (A + 9) * 2 + A
+  // CHECK: mov eax, $$4
+  __asm mov eax, A << 2
+  // CHECK: mov eax, $$2
+  __asm mov eax, B & 3
+  // CHECK: mov eax, $$5
+  __asm mov eax, 3 + (B & 3)
+  // CHECK: mov eax, $$8
+  __asm mov eax, 2 << A * B
+}
+
+void x86_enum_mem() {
+  int arr[4];
+  enum { A = 4, B };
+  
+  // CHECK: mov eax, [($$12 + $$9) + $$4 * $$5 + $$3 + $$3 + eax]
+  __asm { mov eax, [(x::A + 9) + A * B + 3 + 3 + eax] }
+  // CHECK: mov eax, dword ptr $$4$0
+  __asm { mov eax, dword ptr [arr + A] }
+  // CHECK: mov eax, dword ptr $$8$0
+  __asm { mov eax, dword ptr A[arr + A] }
+}
\ No newline at end of file
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32896: [OpenCL] Make CLK_NULL_RESERVE_ID invalid reserve id.

2017-05-22 Thread Yaxun Liu via Phabricator via cfe-commits
yaxunl added inline comments.



Comment at: lib/Headers/opencl-c.h:16020
+// The macro CLK_NULL_RESERVE_ID refers to an invalid reservation ID.
+#define CLK_NULL_RESERVE_ID (__builtin_astype((void *)0, reserve_id_t))
 bool __ovld is_valid_reserve_id(reserve_id_t reserve_id);

bader wrote:
> yaxunl wrote:
> > bader wrote:
> > > yaxunl wrote:
> > > > yaxunl wrote:
> > > > > bader wrote:
> > > > > > yaxunl wrote:
> > > > > > > Anastasia wrote:
> > > > > > > > echuraev wrote:
> > > > > > > > > yaxunl wrote:
> > > > > > > > > > Anastasia wrote:
> > > > > > > > > > > yaxunl wrote:
> > > > > > > > > > > > Anastasia wrote:
> > > > > > > > > > > > > Looks good from my side.
> > > > > > > > > > > > > 
> > > > > > > > > > > > > @yaxunl , since you originally committed this. Could 
> > > > > > > > > > > > > you please verify that changing from `SIZE_MAX` to 
> > > > > > > > > > > > > `0` would be fine.
> > > > > > > > > > > > > 
> > > > > > > > > > > > > Btw, we have a similar definition for 
> > > > > > > > > > > > > `CLK_NULL_EVENT`.
> > > > > > > > > > > > `__PIPE_RESERVE_ID_VALID_BIT` is implementation detail 
> > > > > > > > > > > > and not part of the spec. I would suggest to remove it 
> > > > > > > > > > > > from this header file.
> > > > > > > > > > > > 
> > > > > > > > > > > > The spec only requires CLK_NULL_RESERVE_ID to be 
> > > > > > > > > > > > defined but does not define its value. Naturally a 
> > > > > > > > > > > > valid id starts from 0 and increases. I don't see 
> > > > > > > > > > > > significant advantage to change CLK_NULL_RESERVE_ID 
> > > > > > > > > > > > from __SIZE_MAX to 0.
> > > > > > > > > > > > 
> > > > > > > > > > > > Is there any reason that this change is needed?
> > > > > > > > > > > I don't see issues to commit things outside of spec as 
> > > > > > > > > > > soon as they prefixed properly with "__".  But I agree it 
> > > > > > > > > > > would be nice to see if it's any useful and what the 
> > > > > > > > > > > motivation is for having different implementation.
> > > > > > > > > > For `__PIPE_RESERVE_ID_VALID_BIT`, it assumes that the 
> > > > > > > > > > implementation uses one specific bit of a reserve id to 
> > > > > > > > > > indicate that the reserve id is valid. Not all 
> > > > > > > > > > implementations assume that. Actually I am curious why that 
> > > > > > > > > > is needed too.
> > > > > > > > > About `CLK_NULL_RESERVE_ID`: we check that reserve id is 
> > > > > > > > > valid if significant bit equal to one. `CLK_NULL_RESERVE_ID 
> > > > > > > > > refers to an invalid reservation, so if `CLK_NULL_RESERVE_ID 
> > > > > > > > > equal to 0, we can be sure that significant bit doesn't equal 
> > > > > > > > > to 1 and it is invalid reserve id. Also it is more obviously 
> > > > > > > > > if CLK_**NULL**_RESERVE_ID is equal to 0.
> > > > > > > > > 
> > > > > > > > > What about `__PIPE_RESERVE_ID_VALID_BIT`: As I understand 
> > > > > > > > > previous implementation also assumes that one specific bit 
> > > > > > > > > was of a reverse id was used to indicate that the reserve id 
> > > > > > > > > is valid. So, we just increased reserve id size by one bit on 
> > > > > > > > > 32-bit platforms and by 33 bits on 64-bit platforms. 
> > > > > > > > It is more logical to me that `CLK_NULL_RESERVE_ID` is 0, but 
> > > > > > > > spec doesn't define it of course.
> > > > > > > In our implementation, valid reserve id starts at 0 and 
> > > > > > > increasing linearly until `__SIZE_MAX-1`. This change will break 
> > > > > > > our implementation.
> > > > > > > 
> > > > > > > However, we can modify our implementation to adopt this change 
> > > > > > > since it brings about benefits overall.
> > > > > > Ideally it would be great to have unified implementation, but we 
> > > > > > can define device specific value for CLK_NULL_RESERVE_ID by using 
> > > > > > ifdef directive.
> > > > > How about
> > > > > 
> > > > > ```
> > > > > __attribute__((const)) size_t __clk_null_reserve_id();
> > > > > #define CLK_NULL_RESERVE_ID __clk_null_reserve_id()
> > > > > 
> > > > > ```
> > > > > I think the spec does not require it to be compile time constant. 
> > > > > Then each library can implement its own __clk_null_reserve_id() 
> > > > > whereas the IR is target independent.
> > > > Or we only do this for SPIR and define it as target specific value for 
> > > > other targets.
> > > Defining CLK_NULL_RESERVE_ID as a function call should also work, but 
> > > IMHO compile time constant is preferable option.
> > > I don't think making it compile time constant for SPIR only makes sense 
> > > to me - in this case we can use constant for all targets.
> > > 
> > > How about following approach: use 0 by default and allow other targets 
> > > re-define CLK_NULL_RESERVE_ID value.
> > > 
> > > ```
> > > #ifndef CLK_NULL_RESERVE_ID
> > >   #define CLK_NULL_RESERVE_ID 0
> > > #endif // CLK_NULL_RESERVE_ID 
> > > ```
> > > 
> > > If CLK_NULL_RESERVE_ID defined via -D comm

[PATCH] D33278: [LLVM][x86][Inline Asm] - Enum support for MS syntax

2017-05-22 Thread Matan via Phabricator via cfe-commits
mharoush updated this revision to Diff 99778.
mharoush added a comment.

Using identifier info to pass enum information.


Repository:
  rL LLVM

https://reviews.llvm.org/D33278

Files:
  include/llvm/MC/MCParser/MCAsmParser.h
  lib/Target/X86/AsmParser/X86AsmParser.cpp

Index: lib/Target/X86/AsmParser/X86AsmParser.cpp
===
--- lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -718,7 +718,8 @@
   ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start, unsigned Size);
   std::unique_ptr ParseRoundingModeOp(SMLoc Start, SMLoc End);
   bool ParseIntelNamedOperator(StringRef Name, IntelExprStateMachine &SM);
-  bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);
+  bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End, 
+bool &ReplaceEnumIdentifier);
   std::unique_ptr
   ParseIntelBracExpression(unsigned SegReg, SMLoc Start, int64_t ImmDisp,
bool isSymbol, unsigned Size);
@@ -1306,8 +1307,9 @@
 return false;
   return true;
 }
-
-bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
+bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End, 
+bool &ReplaceEnumIdentifier) {
+  ReplaceEnumIdentifier = false;
   MCAsmParser &Parser = getParser();
   const AsmToken &Tok = Parser.getTok();
 
@@ -1368,11 +1370,40 @@
 PrevTK == AsmToken::RBrac) {
   return false;
   } else {
-InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
+InlineAsmIdentifierInfo Info;
+Info.clear();
 if (ParseIntelIdentifier(Val, Identifier, Info,
  /*Unevaluated=*/false, End))
   return true;
-SM.onIdentifierExpr(Val, Identifier);
+// Check if the parsed identifier was a constant Integer. Here we 
+// assume Val is of type MCConstantExpr only when it is safe to replace
+// the identifier with its constant value.
+if (const MCConstantExpr *CE = 
+dyn_cast_or_null(Val)) {
+  StringRef ErrMsg;
+  // SM should treat the value as it would an explicit integer in the 
+  // expression.
+  if(SM.onInteger(CE->getValue(), ErrMsg)) 
+return Error(IdentLoc, ErrMsg);
+  // In case we are called on a bracketed expression,
+  if (isParsingInlineAsm() && SM.getAddImmPrefix()) {
+// A single rewrite of the integer value is preformed for each enum
+// identifier. This is only done when we are inside a bracketed 
+// expression in order to match the behavior for the equivalent 
+// integer tokens.
+size_t Len = End.getPointer() - IdentLoc.getPointer();
+InstInfo->AsmRewrites->emplace_back(AOK_Imm, IdentLoc,Len, 
+CE->getValue());
+break;
+  }
+  // Set force rewrite flag only when not bracketed expression.
+  ReplaceEnumIdentifier = true;
+} else {
+  // Notify the SM a variable identifier was found.
+  InlineAsmIdentifierInfo &SMInfo = SM.getIdentifierInfo();
+  	  SMInfo = Info;
+  SM.onIdentifierExpr(Val, Identifier);
+}
   }
   break;
 }
@@ -1452,7 +1483,8 @@
   // may have already parsed an immediate displacement before the bracketed
   // expression.
   IntelExprStateMachine SM(ImmDisp, /*StopOnLBrac=*/false, /*AddImmPrefix=*/true);
-  if (ParseIntelExpression(SM, End))
+  bool ReplaceEnumIdentifier;
+  if (ParseIntelExpression(SM, End, ReplaceEnumIdentifier))
 return nullptr;
 
   const MCExpr *Disp = nullptr;
@@ -1559,7 +1591,15 @@
   // failed parsing.
   assert((End.getPointer() == EndPtr || !Result) &&
  "frontend claimed part of a token?");
-
+  
+  // Check if the search yielded a constant integer (enum identifier).
+  if (Result && Info.IsConstEnum) {
+// By creating MCConstantExpr we let the user of Val know it is safe
+// to use as an explicit constant with value = ConstVal.
+Val = MCConstantExpr::create(Info.ConstIntValue.getSExtValue(), 
+ getParser().getContext());
+return false;
+  }
   // If the identifier lookup was unsuccessful, assume that we are dealing with
   // a label.
   if (!Result) {
@@ -1852,18 +1892,21 @@
   AsmToken StartTok = Tok;
   IntelExprStateMachine SM(/*Imm=*/0, /*StopOnLBrac=*/true,
/*AddImmPrefix=*/false);
-  if (ParseIntelExpression(SM, End))
+  // The parsed expression may contain enum identifier tokens which we must 
+  // replace, ReplaceEnumIdentifier flag lets us know when to force rewrite.
+  bool ReplaceEnumIdentifier;
+  if (ParseIntelExpression(SM, End, ReplaceEnumIdentifier))
 return nullptr;
-
   bool isSymbol = SM.getSym() && 

[PATCH] D33278: [LLVM][x86][Inline Asm] - Enum support for MS syntax

2017-05-22 Thread Matan via Phabricator via cfe-commits
mharoush marked an inline comment as done.
mharoush added inline comments.



Comment at: include/llvm/MC/MCParser/MCAsmParser.h:64
 unsigned &Offset) = 0;
+  virtual bool EvaluateLookupAsEnum(void *LookupResult,int64_t &Result) = 0;
 };

rnk wrote:
> It would be cleaner if InlineAsmIdentifierInfo simply contained an APInt 
> indicating that the identifier in question was an enum, or other integral 
> constant expression. Less callbacks to implement.
Done



Comment at: lib/Target/X86/AsmParser/X86AsmParser.cpp:722
+  bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End, 
+bool &ReplaceEnumIdentifier);
   std::unique_ptr

rnk wrote:
> Please try to eliminate the need for this extra boolean out parameter.
This flag is used in case we try to compile something like mov edx, A+6 ( when 
A is defined as ConstantEnum ) the original condition (Line:1905) will skip the 
rewrite since we have an identifier as the first Token, however if we try to 
compile 6+A it will be rewritten as expected.

I tried to solve this in different ways, I got either the exact opposite (A+6 
was replaced and 6+A wasn't) or a collision of rewrites when trying to preform 
other forms of replacements and leaving this section intact. 

I can perhaps change the way we handle general expressions to the same way we 
handle them under parseIntelBracExpression, meaning use the first iteration of 
X86AsmParser to reformat the string (write imm prefixes and replace identifiers 
when needed) then refactor the string to its canonical form on the second pass. 

In short this was the simplest solution that worked without regression, maybe 
you have a better idea?

If the issue is the method signature pollution I can move this flag into the SM 
class as a member to indicate a rewrite is needed, however since this flag and 
method are limited to this context alone, I am not sure if the overhead is 
wanted in such case . 


Repository:
  rL LLVM

https://reviews.llvm.org/D33278



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33333: Emit warning when throw exception in destruct or dealloc functions which has a (possible implicit) noexcept specifier

2017-05-22 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added a comment.

In https://reviews.llvm.org/D3#760431, @aaron.ballman wrote:

> In https://reviews.llvm.org/D3#760419, @jyu2 wrote:
>
> > In https://reviews.llvm.org/D3#760149, @aaron.ballman wrote:
> >
> > > As an FYI, there is a related check currently under development in 
> > > clang-tidy; we probably should not duplicate this functionality in both 
> > > places. See https://reviews.llvm.org/D19201 for the other review.
> >
> >
> > To my understanding, clang-tidy is kind of source check tool.  It does more 
> > intensive checking than compiler.  
> >  My purpose here is to emit minimum warning form compiler, in case, 
> > clang-tidy is not used.
>
>
> Sort of correct. clang-tidy doesn't necessarily do more intensive checking 
> than the compiler. It's more an AST matching source checking tool for checks 
> that are either expensive or have a higher false-positive rate than we'd want 
> to see in the frontend.
>
> I think that this particular check should probably be in the frontend, like 
> you're doing. My biggest concern is that we do not duplicate functionality 
> between the two tools. https://reviews.llvm.org/D19201 has has a considerable 
> amount of review, so you should look at the test cases there and ensure you 
> are handling them (including the fixits). Hopefully your patch ends up 
> covering all of the functionality in the clang-tidy patch.
>
> > In https://reviews.llvm.org/D3#760353, @Prazek wrote:
> > 
> >> Could you add similar tests as the ones that Stanislaw provied in his 
> >> patch?
> >>  Like the one with checking if throw is catched, or the conditional 
> >> noexcept (by a macro, etc)
> > 
> > 
> > Good idea!  Could add “marco” test for this.  But I am not sure compiler 
> > want to add check for throw caught by different catch handler.  Because at 
> > compile time, compiler can not statically determine which catch handler 
> > will be used to caught the exception on all time.   I would think that is 
> > pragma's responsibility.
> > 
> > For example:
> > 
> >   If (a) throw A else throw B;  
> >
> >
> > 
> > My main concern there is implicit noexcept gets set by compiler, which 
> > cause runtime to termination.


As I said, I don't think checking throw type matching catch handler type is 
compiler's job.  I'd like either silence all warning for that.  What do you 
think?


https://reviews.llvm.org/D3



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33395: [clangd] Split clangd into library+executable (mainly for unit tests).

2017-05-22 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov marked an inline comment as done.
ilya-biryukov added inline comments.



Comment at: clangd/tool/ClangdMain.cpp:11
+#include "../ClangdLSPServer.h"
+#include "../JSONRPCDispatcher.h"
 #include "llvm/Support/CommandLine.h"

krasimir wrote:
> I'd suggest to not have parent directory includes, but add them to the cmake 
> file as in other extra tools, like in:
> https://github.com/llvm-mirror/clang-tools-extra/blob/master/clang-query/tool/CMakeLists.txt
Done. I've actually followed a pattern of CMakeLists.txt from tool-extra, 
albeit a different one :-)
https://github.com/llvm-mirror/clang-tools-extra/blob/master/clang-tidy/tool/ClangTidyMain.cpp


https://reviews.llvm.org/D33395



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31646: [coroutines] Build GRO declaration and return GRO statement

2017-05-22 Thread Gor Nishanov via Phabricator via cfe-commits
GorNishanov added a comment.

@rsmith  barely audible ping


https://reviews.llvm.org/D31646



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33416: [clangd] Allow to use vfs::FileSystem for file accesses.

2017-05-22 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov created this revision.
Herald added a subscriber: mgorny.

Custom vfs::FileSystem is currently used for unit tests.
This revision depends on https://reviews.llvm.org/D33397.


https://reviews.llvm.org/D33416

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/ClangdUnitStore.h
  unittests/CMakeLists.txt
  unittests/clangd/CMakeLists.txt
  unittests/clangd/ClangdTests.cpp

Index: unittests/clangd/ClangdTests.cpp
===
--- /dev/null
+++ unittests/clangd/ClangdTests.cpp
@@ -0,0 +1,361 @@
+//===-- ClangdTes.cpp - Change namespace unit tests ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "ClangdServer.h"
+#include "clang/Basic/VirtualFileSystem.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Regex.h"
+#include "gtest/gtest.h"
+#include 
+#include 
+#include 
+#include 
+
+namespace clang {
+namespace vfs {
+
+/// An implementation of vfs::FileSystem that only allows access to
+/// files and folders inside a set of whitelisted directories.
+///
+/// FIXME(ibiryukov): should it also emulate access to parents of whitelisted
+/// directories with only whitelisted contents?
+class FilteredFileSystem : public vfs::FileSystem {
+public:
+  /// The paths inside \p WhitelistedDirs should be absolute
+  FilteredFileSystem(std::vector WhitelistedDirs,
+ IntrusiveRefCntPtr InnerFS)
+  : WhitelistedDirs(std::move(WhitelistedDirs)), InnerFS(InnerFS) {
+assert(std::all_of(WhitelistedDirs.begin(), WhitelistedDirs.end(),
+   [](const std::string &Path) -> bool {
+ return llvm::sys::path::is_absolute(Path);
+   }) &&
+   "Not all WhitelistedDirs are absolute");
+  }
+
+  virtual llvm::ErrorOr status(const Twine &Path) {
+if (!isInsideWhitelistedDir(Path))
+  return llvm::errc::no_such_file_or_directory;
+return InnerFS->status(Path);
+  }
+
+  virtual llvm::ErrorOr>
+  openFileForRead(const Twine &Path) {
+if (!isInsideWhitelistedDir(Path))
+  return llvm::errc::no_such_file_or_directory;
+return InnerFS->openFileForRead(Path);
+  }
+
+  llvm::ErrorOr>
+  getBufferForFile(const Twine &Name, int64_t FileSize = -1,
+   bool RequiresNullTerminator = true,
+   bool IsVolatile = false) {
+if (!isInsideWhitelistedDir(Name))
+  return llvm::errc::no_such_file_or_directory;
+return InnerFS->getBufferForFile(Name, FileSize, RequiresNullTerminator,
+ IsVolatile);
+  }
+
+  virtual directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) {
+if (!isInsideWhitelistedDir(Dir)) {
+  EC = llvm::errc::no_such_file_or_directory;
+  return directory_iterator();
+}
+return InnerFS->dir_begin(Dir, EC);
+  }
+
+  virtual std::error_code setCurrentWorkingDirectory(const Twine &Path) {
+return InnerFS->setCurrentWorkingDirectory(Path);
+  }
+
+  virtual llvm::ErrorOr getCurrentWorkingDirectory() const {
+return InnerFS->getCurrentWorkingDirectory();
+  }
+
+  bool exists(const Twine &Path) {
+if (!isInsideWhitelistedDir(Path))
+  return false;
+return InnerFS->exists(Path);
+  }
+
+  std::error_code makeAbsolute(SmallVectorImpl &Path) const {
+return InnerFS->makeAbsolute(Path);
+  }
+
+private:
+  bool isInsideWhitelistedDir(const Twine &InputPath) const {
+SmallString<128> Path;
+InputPath.toVector(Path);
+
+if (makeAbsolute(Path))
+  return false;
+
+for (const auto &Dir : WhitelistedDirs) {
+  if (Path.startswith(Dir))
+return true;
+}
+return false;
+  }
+
+  std::vector WhitelistedDirs;
+  IntrusiveRefCntPtr InnerFS;
+};
+
+/// Create a vfs::FileSystem that has access only to temporary directories
+/// (obtained by calling system_temp_directory).
+IntrusiveRefCntPtr getTempOnlyFS() {
+  llvm::SmallString<128> TmpDir1;
+  llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false, TmpDir1);
+  llvm::SmallString<128> TmpDir2;
+  llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/true, TmpDir2);
+
+  std::vector TmpDirs;
+  TmpDirs.push_back(TmpDir1.str());
+  if (TmpDir2 != TmpDir2)
+TmpDirs.push_back(TmpDir2.str());
+  return new vfs::FilteredFileSystem(std::move(TmpDirs),
+ vfs::getRealFileSystem());
+}
+} // namespace vfs
+
+namespace clangd {
+namespace {
+
+class ErrorCheckingDiagConsumer : public DiagnosticsConsumer {
+public:
+  void onDiagnosticsReady(PathRef File,
+

Re: r303546 - [mips] Support `micromips` attribute

2017-05-22 Thread Simon Atanasyan via cfe-commits
On Mon, May 22, 2017 at 3:57 PM, Aaron Ballman  wrote:
> On Mon, May 22, 2017 at 8:47 AM, Simon Atanasyan via cfe-commits
>  wrote:
>> Author: atanasyan
>> Date: Mon May 22 07:47:43 2017
>> New Revision: 303546
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=303546&view=rev
>> Log:
>> [mips] Support `micromips` attribute
>>
>> This patch adds support for the `micromips` and `nomicromips` attributes
>> for MIPS targets.
>>
>> Differential revision: https://reviews.llvm.org/D33363

[...]

>> Modified: cfe/trunk/include/clang/Basic/Attr.td
>> URL: 
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=303546&r1=303545&r2=303546&view=diff
>> ==
>> --- cfe/trunk/include/clang/Basic/Attr.td (original)
>> +++ cfe/trunk/include/clang/Basic/Attr.td Mon May 22 07:47:43 2017
>> @@ -1179,6 +1179,12 @@ def MipsInterrupt : InheritableAttr, Tar
>>let Documentation = [MipsInterruptDocs];
>>  }
>>
>> +def MicroMips : InheritableAttr, TargetSpecificAttr {
>> +  let Spellings = [GCC<"micromips">];
>> +  let Subjects = SubjectList<[Function], ErrorDiag>;
>
> Why is this an error rather than a warning? Same question below.

Because GCC shows the error in this case. And I cannot imagine any
reason why micromips attribute added to non-function declaration.

% mips-mti-linux-gnu-gcc --version
mips-mti-linux-gnu-gcc (Codescape GNU Tools 2016.05-01 for MIPS MTI Linux) 4.9.2

% mips-mti-linux-gnu-gcc -c attr-micromips.c
tools/clang/test/Sema/attr-micromips.c:6:1: error: ‘nomicromips’
attribute only applies to functions
 __attribute((nomicromips)) int a; // expected-error {{attribute only
applies to functions}}
 ^
tools/clang/test/Sema/attr-micromips.c:7:1: error: ‘micromips’
attribute only applies to functions
 __attribute((micromips)) int b;   // expected-error {{attribute only
applies to functions}}

>> Modified: cfe/trunk/include/clang/Basic/AttrDocs.td
>> URL: 
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrDocs.td?rev=303546&r1=303545&r2=303546&view=diff
>> ==
>> --- cfe/trunk/include/clang/Basic/AttrDocs.td (original)
>> +++ cfe/trunk/include/clang/Basic/AttrDocs.td Mon May 22 07:47:43 2017
>> @@ -1269,6 +1269,19 @@ The semantics are as follows:
>>}];
>>  }
>>
>> +def MicroMipsDocs : Documentation {
>> +  let Category = DocCatFunction;
>> +  let Content = [{
>> +Clang supports the GNU style ``__attribute__((micromips))`` and
>> +``__attribute__((nomicromips))`` attributes on MIPS targets. These 
>> attributes
>> +may be attached to a function definition and instructs the backend to 
>> generate
>> +or not to generate microMIPS code for that function.
>> +
>> +These attributes override the -mmicromips and -mno-micromips options
>
> Please quote the command line options with ``.

Fixed at r303564.

>> Added: cfe/trunk/test/Sema/attr-micromips.c
>> URL: 
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-micromips.c?rev=303546&view=auto
>> ==
>> --- cfe/trunk/test/Sema/attr-micromips.c (added)
>> +++ cfe/trunk/test/Sema/attr-micromips.c Mon May 22 07:47:43 2017
>> @@ -0,0 +1,15 @@
>> +// RUN: %clang_cc1 -triple mips-linux-gnu -fsyntax-only -verify %s
>> +
>> +__attribute__((nomicromips(0))) void foo1();  // expected-error 
>> {{'nomicromips' attribute takes no arguments}}
>> +__attribute__((micromips(1))) void foo2();// expected-error 
>> {{'micromips' attribute takes no arguments}}
>> +
>> +__attribute((nomicromips)) int a; // expected-error {{attribute only 
>> applies to functions}}
>> +__attribute((micromips)) int b;   // expected-error {{attribute only 
>> applies to functions}}
>> +
>> +__attribute__((micromips,mips16)) void foo5();  // expected-error 
>> {{'micromips' and 'mips16' attributes are not compatible}} \
>> +// expected-note 
>> {{conflicting attribute is here}}
>> +__attribute__((mips16,micromips)) void foo6();  // expected-error 
>> {{'mips16' and 'micromips' attributes are not compatible}} \
>> +// expected-note 
>> {{conflicting attribute is here}}
>
> Can you also add a test like:
>
> __attribute__((mips16)) void foo9(void) __attribute__((micromips));

Fixed at r303565.

-- 
Simon Atanasyan
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33395: [clangd] Split clangd into library+executable (mainly for unit tests).

2017-05-22 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov updated this revision to Diff 99774.
ilya-biryukov added a comment.

Got rid of relative includes from parent dir in ClangdMain.cpp. (Addressed 
krasimir's comments)


https://reviews.llvm.org/D33395

Files:
  clangd/CMakeLists.txt
  clangd/ClangdMain.cpp
  clangd/tool/CMakeLists.txt
  clangd/tool/ClangdMain.cpp

Index: clangd/ClangdMain.cpp
===
--- /dev/null
+++ clangd/ClangdMain.cpp
@@ -1,40 +0,0 @@
-//===--- ClangdMain.cpp - clangd server loop --===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===--===//
-
-#include "ClangdLSPServer.h"
-#include "JSONRPCDispatcher.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Program.h"
-
-#include 
-#include 
-#include 
-
-using namespace clang;
-using namespace clang::clangd;
-
-static llvm::cl::opt
-RunSynchronously("run-synchronously",
- llvm::cl::desc("parse on main thread"),
- llvm::cl::init(false), llvm::cl::Hidden);
-
-int main(int argc, char *argv[]) {
-  llvm::cl::ParseCommandLineOptions(argc, argv, "clangd");
-
-  llvm::raw_ostream &Outs = llvm::outs();
-  llvm::raw_ostream &Logs = llvm::errs();
-  JSONOutput Out(Outs, Logs);
-
-  // Change stdin to binary to not lose \r\n on windows.
-  llvm::sys::ChangeStdinToBinary();
-
-  ClangdLSPServer LSPServer(Out, RunSynchronously);
-  LSPServer.run(std::cin);
-}
Index: clangd/tool/CMakeLists.txt
===
--- clangd/tool/CMakeLists.txt
+++ clangd/tool/CMakeLists.txt
@@ -1,20 +1,14 @@
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
+
 add_clang_executable(clangd
-  ClangdLSPServer.cpp
   ClangdMain.cpp
-  ClangdServer.cpp
-  ClangdUnit.cpp
-  ClangdUnitStore.cpp
-  DraftStore.cpp
-  GlobalCompilationDatabase.cpp
-  JSONRPCDispatcher.cpp
-  Protocol.cpp
-  ProtocolHandlers.cpp
   )
 
 install(TARGETS clangd RUNTIME DESTINATION bin)
 
 target_link_libraries(clangd
   clangBasic
+  clangDaemon
   clangFormat
   clangFrontend
   clangSema
Index: clangd/CMakeLists.txt
===
--- clangd/CMakeLists.txt
+++ clangd/CMakeLists.txt
@@ -1,6 +1,5 @@
-add_clang_executable(clangd
+add_clang_library(clangDaemon
   ClangdLSPServer.cpp
-  ClangdMain.cpp
   ClangdServer.cpp
   ClangdUnit.cpp
   ClangdUnitStore.cpp
@@ -11,14 +10,14 @@
   ProtocolHandlers.cpp
   )
 
-install(TARGETS clangd RUNTIME DESTINATION bin)
-
-target_link_libraries(clangd
+target_link_libraries(clangDaemon
   clangBasic
   clangFormat
   clangFrontend
   clangSema
   clangTooling
   clangToolingCore
   LLVMSupport
   )
+
+add_subdirectory(tool)
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r303565 - [mips] Add one more check to the micromips attribute test case. NFC

2017-05-22 Thread Simon Atanasyan via cfe-commits
Author: atanasyan
Date: Mon May 22 10:53:34 2017
New Revision: 303565

URL: http://llvm.org/viewvc/llvm-project?rev=303565&view=rev
Log:
[mips] Add one more check to the micromips attribute test case. NFC

Modified:
cfe/trunk/test/Sema/attr-micromips.c

Modified: cfe/trunk/test/Sema/attr-micromips.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-micromips.c?rev=303565&r1=303564&r2=303565&view=diff
==
--- cfe/trunk/test/Sema/attr-micromips.c (original)
+++ cfe/trunk/test/Sema/attr-micromips.c Mon May 22 10:53:34 2017
@@ -13,3 +13,5 @@ __attribute__((mips16,micromips)) void f
 
 __attribute((micromips)) void foo7();
 __attribute((nomicromips)) void foo8();
+__attribute__((mips16)) void foo9(void) __attribute__((micromips)); // 
expected-error {{'micromips' and 'mips16' attributes are not compatible}} \
+// 
expected-note {{conflicting attribute is here}}


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r303564 - [mips] Quote command line options with `` in the micromips attribute description. NFC

2017-05-22 Thread Simon Atanasyan via cfe-commits
Author: atanasyan
Date: Mon May 22 10:53:31 2017
New Revision: 303564

URL: http://llvm.org/viewvc/llvm-project?rev=303564&view=rev
Log:
[mips] Quote command line options with `` in the micromips attribute 
description. NFC

Modified:
cfe/trunk/include/clang/Basic/AttrDocs.td

Modified: cfe/trunk/include/clang/Basic/AttrDocs.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrDocs.td?rev=303564&r1=303563&r2=303564&view=diff
==
--- cfe/trunk/include/clang/Basic/AttrDocs.td (original)
+++ cfe/trunk/include/clang/Basic/AttrDocs.td Mon May 22 10:53:31 2017
@@ -1277,7 +1277,7 @@ Clang supports the GNU style ``__attribu
 may be attached to a function definition and instructs the backend to generate
 or not to generate microMIPS code for that function.
 
-These attributes override the -mmicromips and -mno-micromips options
+These attributes override the `-mmicromips` and `-mno-micromips` options
 on the command line.
   }];
 }


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33415: Replaced WorkerRequest with std::function...

2017-05-22 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov created this revision.

And implemented a helper function to dump an AST of a file for
testing/debugging purposes.


https://reviews.llvm.org/D33415

Files:
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/ClangdUnitStore.h

Index: clangd/ClangdUnitStore.h
===
--- clangd/ClangdUnitStore.h
+++ clangd/ClangdUnitStore.h
@@ -50,6 +50,18 @@
   std::forward(Action));
   }
 
+  /// Run the specified \p Action on the ClangdUnit for \p File.
+  /// Unit for \p File should exist in the store.
+  template 
+  void runOnExistingUnit(PathRef File, Func Action) {
+std::lock_guard Lock(Mutex);
+
+auto It = OpenedFiles.find(File);
+assert(It != OpenedFiles.end() && "File is not in OpenedFiles");
+
+Action(It->second);
+  }
+
   /// Remove ClangdUnit for \p File, if any
   void removeUnitIfPresent(PathRef File);
 
Index: clangd/ClangdUnit.h
===
--- clangd/ClangdUnit.h
+++ clangd/ClangdUnit.h
@@ -16,6 +16,10 @@
 #include "clang/Tooling/Core/Replacement.h"
 #include 
 
+namespace llvm {
+class raw_ostream;
+}
+
 namespace clang {
 class ASTUnit;
 class PCHContainerOperations;
@@ -52,6 +56,10 @@
   /// located in the current file.
   std::vector getLocalDiagnostics() const;
 
+  /// For testing/debugging purposes. Note that this method deserializes all
+  /// unserialized Decls, so use with care.
+  void dumpAST(llvm::raw_ostream &OS) const;
+
 private:
   Path FileName;
   std::unique_ptr Unit;
Index: clangd/ClangdUnit.cpp
===
--- clangd/ClangdUnit.cpp
+++ clangd/ClangdUnit.cpp
@@ -222,3 +222,7 @@
   }
   return Result;
 }
+
+void ClangdUnit::dumpAST(llvm::raw_ostream &OS) const {
+  Unit->getASTContext().getTranslationUnitDecl()->dump(OS, true);
+}
Index: clangd/ClangdServer.h
===
--- clangd/ClangdServer.h
+++ clangd/ClangdServer.h
@@ -24,6 +24,7 @@
 #include "Protocol.h"
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -49,30 +50,21 @@
   std::vector Diagnostics) = 0;
 };
 
-enum class WorkerRequestKind { ParseAndPublishDiagnostics, RemoveDocData };
-
-/// A request to the worker thread
-class WorkerRequest {
-public:
-  WorkerRequest() = default;
-  WorkerRequest(WorkerRequestKind Kind, Path File, DocVersion Version);
-
-  WorkerRequestKind Kind;
-  Path File;
-  DocVersion Version;
-};
-
 class ClangdServer;
 
 /// Handles running WorkerRequests of ClangdServer on a separate threads.
 /// Currently runs only one worker thread.
 class ClangdScheduler {
 public:
-  ClangdScheduler(ClangdServer &Server, bool RunSynchronously);
+  ClangdScheduler(bool RunSynchronously);
   ~ClangdScheduler();
 
-  /// Enqueue WorkerRequest to be run on a worker thread
-  void enqueue(ClangdServer &Server, WorkerRequest Request);
+  /// Add \p Request to the start of the queue. \p Request will be run on a
+  /// separate worker thread.
+  void addToFront(std::function Request);
+  /// Add \p Request to the end of the queue. \p Request will be run on a
+  /// separate worker thread.
+  void addToEnd(std::function Request);
 
 private:
   bool RunSynchronously;
@@ -83,11 +75,10 @@
   std::thread Worker;
   /// Setting Done to true will make the worker thread terminate.
   bool Done = false;
-  /// A LIFO queue of requests. Note that requests are discarded if the
-  /// `version` field is not equal to the one stored inside DraftStore.
+  /// A queue of requests.
   /// FIXME(krasimir): code completion should always have priority over parsing
   /// for diagnostics.
-  std::deque RequestQueue;
+  std::deque> RequestQueue;
   /// Condition variable to wake up the worker thread.
   std::condition_variable RequestCV;
 };
@@ -126,12 +117,12 @@
   /// conversions in outside code, maybe there's a way to get rid of it.
   std::string getDocument(PathRef File);
 
-private:
-  friend class ClangdScheduler;
-
-  /// This function is called on a worker thread.
-  void handleRequest(WorkerRequest Request);
+  /// Only for testing purposes.
+  /// Waits until all requests to worker thread are finished and dumps AST for
+  /// \p File. \p File must be in the list of added documents.
+  std::string dumpAST(PathRef File);
 
+private:
   std::unique_ptr CDB;
   std::unique_ptr DiagConsumer;
   DraftStore DraftMgr;
Index: clangd/ClangdServer.cpp
===
--- clangd/ClangdServer.cpp
+++ clangd/ClangdServer.cpp
@@ -15,6 +15,8 @@
 #include "clang/Tooling/CompilationDatabase.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/raw_ostream.h"
+#include 
 
 using namespace clang;
 using namespace clang::clangd;
@@ -56,22 +58,18 @@
   return {Lines, Cols};
 }
 
-WorkerRequest:

r303563 - [index] Index the deleted functions

2017-05-22 Thread Alex Lorenz via cfe-commits
Author: arphaman
Date: Mon May 22 10:42:45 2017
New Revision: 303563

URL: http://llvm.org/viewvc/llvm-project?rev=303563&view=rev
Log:
[index] Index the deleted functions

rdar://32323386

Modified:
cfe/trunk/lib/Index/IndexDecl.cpp
cfe/trunk/test/Index/Core/index-source.cpp

Modified: cfe/trunk/lib/Index/IndexDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/IndexDecl.cpp?rev=303563&r1=303562&r2=303563&view=diff
==
--- cfe/trunk/lib/Index/IndexDecl.cpp (original)
+++ cfe/trunk/lib/Index/IndexDecl.cpp Mon May 22 10:42:45 2017
@@ -217,9 +217,6 @@ public:
   }
 
   bool VisitFunctionDecl(const FunctionDecl *D) {
-if (D->isDeleted())
-  return true;
-
 SymbolRoleSet Roles{};
 SmallVector Relations;
 if (auto *CXXMD = dyn_cast(D)) {

Modified: cfe/trunk/test/Index/Core/index-source.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/Core/index-source.cpp?rev=303563&r1=303562&r2=303563&view=diff
==
--- cfe/trunk/test/Index/Core/index-source.cpp (original)
+++ cfe/trunk/test/Index/Core/index-source.cpp Mon May 22 10:42:45 2017
@@ -366,3 +366,11 @@ struct IndexDefaultValue {
 // CHECK: [[@LINE-2]]:30 | struct/C++ | Record | c:@S@Record |  | 
Ref,RelCont | rel: 1
}
 };
+
+struct DeletedMethods {
+  DeletedMethods(const DeletedMethods &) = delete;
+// CHECK: [[@LINE-1]]:3 | constructor/cxx-copy-ctor/C++ | DeletedMethods | 
c:@S@DeletedMethods@F@DeletedMethods#&1$@S@DeletedMethods# | 
__ZN14DeletedMethodsC1ERKS_ | Def,RelChild | rel: 1
+// CHECK: RelChild | DeletedMethods | c:@S@DeletedMethods
+// CHECK: [[@LINE-3]]:24 | struct/C++ | DeletedMethods | c:@S@DeletedMethods | 
 | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-4]]:3 | struct/C++ | DeletedMethods | c:@S@DeletedMethods | 
 | Ref,RelCont | rel: 1
+};


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33250: [Sema][ObjC] Fix a bug where -Wunguarded-availability was emitted at the wrong location

2017-05-22 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL303562: [Sema][ObjC] Fix a bug where 
-Wunguarded-availability was emitted at the wrong… (authored by epilk).

Changed prior to commit:
  https://reviews.llvm.org/D33250?vs=99605&id=99772#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D33250

Files:
  cfe/trunk/lib/Sema/SemaDeclAttr.cpp
  cfe/trunk/test/SemaObjC/unguarded-availability.m


Index: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
===
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp
@@ -7258,6 +7258,12 @@
 
   bool TraverseLambdaExpr(LambdaExpr *E) { return true; }
 
+  bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *PRE) {
+if (PRE->isClassReceiver())
+  DiagnoseDeclAvailability(PRE->getClassReceiver(), 
PRE->getReceiverLocation());
+return true;
+  }
+
   bool VisitObjCMessageExpr(ObjCMessageExpr *Msg) {
 if (ObjCMethodDecl *D = Msg->getMethodDecl())
   DiagnoseDeclAvailability(
@@ -7387,6 +7393,9 @@
   const Type *TyPtr = Ty.getTypePtr();
   SourceRange Range{Ty.getBeginLoc(), Ty.getEndLoc()};
 
+  if (Range.isInvalid())
+return true;
+
   if (const TagType *TT = dyn_cast(TyPtr)) {
 TagDecl *TD = TT->getDecl();
 DiagnoseDeclAvailability(TD, Range);
Index: cfe/trunk/test/SemaObjC/unguarded-availability.m
===
--- cfe/trunk/test/SemaObjC/unguarded-availability.m
+++ cfe/trunk/test/SemaObjC/unguarded-availability.m
@@ -135,6 +135,26 @@
 func_10_12();
 };
 
+AVAILABLE_10_12
+__attribute__((objc_root_class))
+@interface InterWithProp // expected-note 2 {{marked partial here}}
+@property(class) int x;
++ (void) setX: (int)newX AVAILABLE_10_12; // expected-note{{marked partial 
here}}
+@end
+void test_property(void) {
+  int y = InterWithProp.x; // expected-warning{{'InterWithProp' is only 
available on macOS 10.12 or newer}} expected-note{{@available}}
+  InterWithProp.x = y; // expected-warning{{'InterWithProp' is only available 
on macOS 10.12 or newer}} expected-note{{@available}} expected-warning{{'setX:' 
is only available on macOS 10.12 or newer}} expected-note{{@available}}
+}
+
+__attribute__((objc_root_class))
+@interface Subscriptable
+- (id)objectAtIndexedSubscript:(int)sub AVAILABLE_10_12; // 
expected-note{{marked partial here}}
+@end
+
+void test_at(Subscriptable *x) {
+  id y = x[42]; // expected-warning{{'objectAtIndexedSubscript:' is only 
available on macOS 10.12 or newer}} expected-note{{@available}}
+}
+
 #ifdef OBJCPP
 
 int f(char) AVAILABLE_10_12;


Index: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
===
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp
@@ -7258,6 +7258,12 @@
 
   bool TraverseLambdaExpr(LambdaExpr *E) { return true; }
 
+  bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *PRE) {
+if (PRE->isClassReceiver())
+  DiagnoseDeclAvailability(PRE->getClassReceiver(), PRE->getReceiverLocation());
+return true;
+  }
+
   bool VisitObjCMessageExpr(ObjCMessageExpr *Msg) {
 if (ObjCMethodDecl *D = Msg->getMethodDecl())
   DiagnoseDeclAvailability(
@@ -7387,6 +7393,9 @@
   const Type *TyPtr = Ty.getTypePtr();
   SourceRange Range{Ty.getBeginLoc(), Ty.getEndLoc()};
 
+  if (Range.isInvalid())
+return true;
+
   if (const TagType *TT = dyn_cast(TyPtr)) {
 TagDecl *TD = TT->getDecl();
 DiagnoseDeclAvailability(TD, Range);
Index: cfe/trunk/test/SemaObjC/unguarded-availability.m
===
--- cfe/trunk/test/SemaObjC/unguarded-availability.m
+++ cfe/trunk/test/SemaObjC/unguarded-availability.m
@@ -135,6 +135,26 @@
 func_10_12();
 };
 
+AVAILABLE_10_12
+__attribute__((objc_root_class))
+@interface InterWithProp // expected-note 2 {{marked partial here}}
+@property(class) int x;
++ (void) setX: (int)newX AVAILABLE_10_12; // expected-note{{marked partial here}}
+@end
+void test_property(void) {
+  int y = InterWithProp.x; // expected-warning{{'InterWithProp' is only available on macOS 10.12 or newer}} expected-note{{@available}}
+  InterWithProp.x = y; // expected-warning{{'InterWithProp' is only available on macOS 10.12 or newer}} expected-note{{@available}} expected-warning{{'setX:' is only available on macOS 10.12 or newer}} expected-note{{@available}}
+}
+
+__attribute__((objc_root_class))
+@interface Subscriptable
+- (id)objectAtIndexedSubscript:(int)sub AVAILABLE_10_12; // expected-note{{marked partial here}}
+@end
+
+void test_at(Subscriptable *x) {
+  id y = x[42]; // expected-warning{{'objectAtIndexedSubscript:' is only available on macOS 10.12 or newer}} expected-note{{@available}}
+}
+
 #ifdef OBJCPP
 
 int f(char) AVAILABLE_10_12;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mail

r303562 - [Sema][ObjC] Fix a bug where -Wunguarded-availability was emitted at the wrong location

2017-05-22 Thread Erik Pilkington via cfe-commits
Author: epilk
Date: Mon May 22 10:41:12 2017
New Revision: 303562

URL: http://llvm.org/viewvc/llvm-project?rev=303562&view=rev
Log:
[Sema][ObjC] Fix a bug where -Wunguarded-availability was emitted at the wrong 
location

Differential revision: https://reviews.llvm.org/D33250

Modified:
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
cfe/trunk/test/SemaObjC/unguarded-availability.m

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=303562&r1=303561&r2=303562&view=diff
==
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Mon May 22 10:41:12 2017
@@ -7258,6 +7258,12 @@ public:
 
   bool TraverseLambdaExpr(LambdaExpr *E) { return true; }
 
+  bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *PRE) {
+if (PRE->isClassReceiver())
+  DiagnoseDeclAvailability(PRE->getClassReceiver(), 
PRE->getReceiverLocation());
+return true;
+  }
+
   bool VisitObjCMessageExpr(ObjCMessageExpr *Msg) {
 if (ObjCMethodDecl *D = Msg->getMethodDecl())
   DiagnoseDeclAvailability(
@@ -7387,6 +7393,9 @@ bool DiagnoseUnguardedAvailability::Visi
   const Type *TyPtr = Ty.getTypePtr();
   SourceRange Range{Ty.getBeginLoc(), Ty.getEndLoc()};
 
+  if (Range.isInvalid())
+return true;
+
   if (const TagType *TT = dyn_cast(TyPtr)) {
 TagDecl *TD = TT->getDecl();
 DiagnoseDeclAvailability(TD, Range);

Modified: cfe/trunk/test/SemaObjC/unguarded-availability.m
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/unguarded-availability.m?rev=303562&r1=303561&r2=303562&view=diff
==
--- cfe/trunk/test/SemaObjC/unguarded-availability.m (original)
+++ cfe/trunk/test/SemaObjC/unguarded-availability.m Mon May 22 10:41:12 2017
@@ -135,6 +135,26 @@ void (^topLevelBlockDecl)() = ^ {
 func_10_12();
 };
 
+AVAILABLE_10_12
+__attribute__((objc_root_class))
+@interface InterWithProp // expected-note 2 {{marked partial here}}
+@property(class) int x;
++ (void) setX: (int)newX AVAILABLE_10_12; // expected-note{{marked partial 
here}}
+@end
+void test_property(void) {
+  int y = InterWithProp.x; // expected-warning{{'InterWithProp' is only 
available on macOS 10.12 or newer}} expected-note{{@available}}
+  InterWithProp.x = y; // expected-warning{{'InterWithProp' is only available 
on macOS 10.12 or newer}} expected-note{{@available}} expected-warning{{'setX:' 
is only available on macOS 10.12 or newer}} expected-note{{@available}}
+}
+
+__attribute__((objc_root_class))
+@interface Subscriptable
+- (id)objectAtIndexedSubscript:(int)sub AVAILABLE_10_12; // 
expected-note{{marked partial here}}
+@end
+
+void test_at(Subscriptable *x) {
+  id y = x[42]; // expected-warning{{'objectAtIndexedSubscript:' is only 
available on macOS 10.12 or newer}} expected-note{{@available}}
+}
+
 #ifdef OBJCPP
 
 int f(char) AVAILABLE_10_12;


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33304: [WIP][clang-tidy] Add a new module Android and a new check for file descriptors.

2017-05-22 Thread Yan Wang via Phabricator via cfe-commits
yawanng added a comment.

I will make some major changes to this CL based on the current suggestions from 
reviewers and update it for further review later. Thank you for the valuable 
advice.


Repository:
  rL LLVM

https://reviews.llvm.org/D33304



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33412: Add support for #pragma clang section

2017-05-22 Thread Javed Absar via Phabricator via cfe-commits
javed.absar created this revision.
Herald added a subscriber: aemerson.

This patch adds support for a '#pragma clang section' directive in clang.
 An RFC was sent out earlier by my colleague  James Molloy:
 http://lists.llvm.org/pipermail/cfe-dev/2017-March/053100.html

  

Purpose:

  The purpose of this is to provide to developers a means to specify 
section-names
  for global variables, functions and static variables, using #pragma 
directives.
  This will provide a migration path towards clang for developers in the 
embedded
  and automotive domain. For example, AUTOSAR, an automotive standard, mandates
  the use of a #pragma in header files to determine in which sections 
initialized
  and uninitialized data get put into.
  This feature is implemented in our legacy ARM Compiler 5 toolchain and GCC 
forks
  used across the automotive space that have this feature implemented compatible
  with the ARM Compiler 5 implementation. The documentation is here:
  
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0472m/chr1359124985290.html


User-Visible Behavior:

  The developer can specify section names as:
#pragma clang section bss="myBSS" data="myData" rodata="myRodata" 
text="myText"
  
  The developer can "unspecify" a section name with empty string e.g.
#pragma clang section bss="" data="" text="" rodata=""
  
  1. The pragma applies to all global variable, statics and function 
declarations
  from the pragma to the end of the translation unit.
  2. The pragma clang section is enabled automatically, without need of any 
flags.
  3. This feature is only defined to work sensibly for ELF targets.
  4. If section name is specified through _attribute_((section("myname"))), then
  the attribute name gains precedence over any applicable section name via 
pragma directives.
  5. Global variables, including - basic types, arrays, struct - that are 
initialized to zero
   e.g. int x = 0; will be placed in the named bss section, if one is present.  
  
  6. The section type using '#pragma clang section' approach does not does NOT
  try to infer section-kind from the name.
  For example, assigning a section ".bss.mysec" does NOT mean it will be placed 
in BSS.


Design:

  The decision about which section-kind applies to each global is not taken by 
this
  implementation but is purely inquired from the default back-end 
implementation in LLVM.
  Once the section-kind is known, appropriate section name as specified by the 
user
  using pragma directive, is applied to that global.
  Note that this is more effective approach than choosing the section name in 
the front-end
  when optimisation passes have not been run and the final proper section is 
not known.

There is a llvm corresponding patch with this patch.


https://reviews.llvm.org/D33412

Files:
  include/clang/Basic/Attr.td
  include/clang/Basic/DiagnosticParseKinds.td
  include/clang/Parse/Parser.h
  include/clang/Sema/Sema.h
  lib/CodeGen/CGDecl.cpp
  lib/CodeGen/CodeGenModule.cpp
  lib/Parse/ParsePragma.cpp
  lib/Sema/SemaAttr.cpp
  lib/Sema/SemaDecl.cpp
  test/CodeGenCXX/clang-sections-tentative.c
  test/CodeGenCXX/clang-sections.cpp
  test/Sema/pragma-clang-section.c

Index: test/Sema/pragma-clang-section.c
===
--- /dev/null
+++ test/Sema/pragma-clang-section.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple arm-none-eabi
+#pragma clang section bss="mybss.1" data="mydata.1" rodata="myrodata.1" text="mytext.1"
+#pragma clang section bss="" data="" rodata="" text=""
+#pragma clang section
+
+#pragma clang section dss="mybss.2" // expected-error {{expected one of [bss|data|rodata|text] section kind in '#pragma clang section'}}
+#pragma clang section deta="mydata.2" // expected-error {{expected one of [bss|data|rodata|text] section kind in '#pragma clang section'}}
+#pragma clang section rodeta="rodata.2" // expected-error {{expected one of [bss|data|rodata|text] section kind in '#pragma clang section'}}
+#pragma clang section taxt="text.2" // expected-error {{expected one of [bss|data|rodata|text] section kind in '#pragma clang section'}}
+
+#pragma clang section section bss="mybss.2"  // expected-error {{expected one of [bss|data|rodata|text] section kind in '#pragma clang section'}}
+
+#pragma clang section bss "mybss.2"   // expected-error {{expected '=' following '#pragma clang section bss'}}
+#pragma clang section data "mydata.2"   // expected-error {{expected '=' following '#pragma clang section data'}}
+#pragma clang section rodata "myrodata.2"   // expected-error {{expected '=' following '#pragma clang section rodata'}}
+#pragma clang section bss="" data="" rodata="" text="" more //expected-error {{expected one of [bss|data|rodata|text] section kind in '#pragma clang section'}}
+int a;
Index: test/CodeGenCXX/clang-sections.cpp
===
--- /dev/null
+++ test/C

r303559 - [index] Visit the default argument values in function definitions

2017-05-22 Thread Alex Lorenz via cfe-commits
Author: arphaman
Date: Mon May 22 10:17:44 2017
New Revision: 303559

URL: http://llvm.org/viewvc/llvm-project?rev=303559&view=rev
Log:
[index] Visit the default argument values in function definitions

rdar://32323315

Modified:
cfe/trunk/lib/Index/IndexDecl.cpp
cfe/trunk/test/Index/Core/index-source.cpp

Modified: cfe/trunk/lib/Index/IndexDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/IndexDecl.cpp?rev=303559&r1=303558&r2=303559&view=diff
==
--- cfe/trunk/lib/Index/IndexDecl.cpp (original)
+++ cfe/trunk/lib/Index/IndexDecl.cpp Mon May 22 10:17:44 2017
@@ -98,6 +98,17 @@ public:
   }
 }
   }
+} else {
+  // Index the default parameter value for function definitions.
+  if (const auto *FD = dyn_cast(D)) {
+if (FD->isThisDeclarationADefinition()) {
+  for (const auto *PV : FD->parameters()) {
+if (PV->hasDefaultArg() && !PV->hasUninstantiatedDefaultArg() &&
+!PV->hasUnparsedDefaultArg())
+  IndexCtx.indexBody(PV->getDefaultArg(), D);
+  }
+}
+  }
 }
   }
 

Modified: cfe/trunk/test/Index/Core/index-source.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/Core/index-source.cpp?rev=303559&r1=303558&r2=303559&view=diff
==
--- cfe/trunk/test/Index/Core/index-source.cpp (original)
+++ cfe/trunk/test/Index/Core/index-source.cpp Mon May 22 10:17:44 2017
@@ -1,7 +1,7 @@
 // RUN: c-index-test core -print-source-symbols -- %s -std=c++14 -target 
x86_64-apple-macosx10.7 | FileCheck %s
 
 // CHECK: [[@LINE+1]]:7 | class/C++ | Cls | [[Cls_USR:.*]] |  | Def 
| rel: 0
-class Cls {
+class Cls { public:
   // CHECK: [[@LINE+3]]:3 | constructor/C++ | Cls | c:@S@Cls@F@Cls#I# | 
__ZN3ClsC1Ei | Decl,RelChild | rel: 1
   // CHECK-NEXT: RelChild | Cls | c:@S@Cls
   // CHECK: [[@LINE+1]]:3 | class/C++ | Cls | c:@S@Cls |  | 
Ref,RelCont | rel: 1
@@ -350,3 +350,19 @@ void innerUsingNamespace() {
 // CHECK-NOT: [[@LINE-3]]:21
   }
 }
+
+void indexDefaultValueInDefn(Cls cls = Cls(gvi), Record param = Record()) {
+// CHECK: [[@LINE-1]]:40 | class/C++ | Cls | c:@S@Cls |  | 
Ref,RelCont | rel: 1
+// CHECK: [[@LINE-2]]:44 | variable/C | gvi | c:@gvi | _gvi | Ref,Read,RelCont 
| rel: 1
+// CHECK-NOT: [[@LINE-3]]:44
+// CHECK: [[@LINE-4]]:65 | struct/C++ | Record | c:@S@Record |  | 
Ref,RelCont | rel: 1
+// CHECK-NOT: [[@LINE-5]]:65
+}
+
+template class T>
+struct IndexDefaultValue {
+   IndexDefaultValue(int k = Record::C) {
+// CHECK: [[@LINE-1]]:38 | static-property/C++ | C | c:@S@Record@C | 
__ZN6Record1CE | Ref,Read,RelCont | rel: 1
+// CHECK: [[@LINE-2]]:30 | struct/C++ | Record | c:@S@Record |  | 
Ref,RelCont | rel: 1
+   }
+};


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32896: [OpenCL] Make CLK_NULL_RESERVE_ID invalid reserve id.

2017-05-22 Thread Alexey Bader via Phabricator via cfe-commits
bader added inline comments.



Comment at: lib/Headers/opencl-c.h:16020
+// The macro CLK_NULL_RESERVE_ID refers to an invalid reservation ID.
+#define CLK_NULL_RESERVE_ID (__builtin_astype((void *)0, reserve_id_t))
 bool __ovld is_valid_reserve_id(reserve_id_t reserve_id);

yaxunl wrote:
> bader wrote:
> > yaxunl wrote:
> > > yaxunl wrote:
> > > > bader wrote:
> > > > > yaxunl wrote:
> > > > > > Anastasia wrote:
> > > > > > > echuraev wrote:
> > > > > > > > yaxunl wrote:
> > > > > > > > > Anastasia wrote:
> > > > > > > > > > yaxunl wrote:
> > > > > > > > > > > Anastasia wrote:
> > > > > > > > > > > > Looks good from my side.
> > > > > > > > > > > > 
> > > > > > > > > > > > @yaxunl , since you originally committed this. Could 
> > > > > > > > > > > > you please verify that changing from `SIZE_MAX` to `0` 
> > > > > > > > > > > > would be fine.
> > > > > > > > > > > > 
> > > > > > > > > > > > Btw, we have a similar definition for `CLK_NULL_EVENT`.
> > > > > > > > > > > `__PIPE_RESERVE_ID_VALID_BIT` is implementation detail 
> > > > > > > > > > > and not part of the spec. I would suggest to remove it 
> > > > > > > > > > > from this header file.
> > > > > > > > > > > 
> > > > > > > > > > > The spec only requires CLK_NULL_RESERVE_ID to be defined 
> > > > > > > > > > > but does not define its value. Naturally a valid id 
> > > > > > > > > > > starts from 0 and increases. I don't see significant 
> > > > > > > > > > > advantage to change CLK_NULL_RESERVE_ID from __SIZE_MAX 
> > > > > > > > > > > to 0.
> > > > > > > > > > > 
> > > > > > > > > > > Is there any reason that this change is needed?
> > > > > > > > > > I don't see issues to commit things outside of spec as soon 
> > > > > > > > > > as they prefixed properly with "__".  But I agree it would 
> > > > > > > > > > be nice to see if it's any useful and what the motivation 
> > > > > > > > > > is for having different implementation.
> > > > > > > > > For `__PIPE_RESERVE_ID_VALID_BIT`, it assumes that the 
> > > > > > > > > implementation uses one specific bit of a reserve id to 
> > > > > > > > > indicate that the reserve id is valid. Not all 
> > > > > > > > > implementations assume that. Actually I am curious why that 
> > > > > > > > > is needed too.
> > > > > > > > About `CLK_NULL_RESERVE_ID`: we check that reserve id is valid 
> > > > > > > > if significant bit equal to one. `CLK_NULL_RESERVE_ID refers to 
> > > > > > > > an invalid reservation, so if `CLK_NULL_RESERVE_ID equal to 0, 
> > > > > > > > we can be sure that significant bit doesn't equal to 1 and it 
> > > > > > > > is invalid reserve id. Also it is more obviously if 
> > > > > > > > CLK_**NULL**_RESERVE_ID is equal to 0.
> > > > > > > > 
> > > > > > > > What about `__PIPE_RESERVE_ID_VALID_BIT`: As I understand 
> > > > > > > > previous implementation also assumes that one specific bit was 
> > > > > > > > of a reverse id was used to indicate that the reserve id is 
> > > > > > > > valid. So, we just increased reserve id size by one bit on 
> > > > > > > > 32-bit platforms and by 33 bits on 64-bit platforms. 
> > > > > > > It is more logical to me that `CLK_NULL_RESERVE_ID` is 0, but 
> > > > > > > spec doesn't define it of course.
> > > > > > In our implementation, valid reserve id starts at 0 and increasing 
> > > > > > linearly until `__SIZE_MAX-1`. This change will break our 
> > > > > > implementation.
> > > > > > 
> > > > > > However, we can modify our implementation to adopt this change 
> > > > > > since it brings about benefits overall.
> > > > > Ideally it would be great to have unified implementation, but we can 
> > > > > define device specific value for CLK_NULL_RESERVE_ID by using ifdef 
> > > > > directive.
> > > > How about
> > > > 
> > > > ```
> > > > __attribute__((const)) size_t __clk_null_reserve_id();
> > > > #define CLK_NULL_RESERVE_ID __clk_null_reserve_id()
> > > > 
> > > > ```
> > > > I think the spec does not require it to be compile time constant. Then 
> > > > each library can implement its own __clk_null_reserve_id() whereas the 
> > > > IR is target independent.
> > > Or we only do this for SPIR and define it as target specific value for 
> > > other targets.
> > Defining CLK_NULL_RESERVE_ID as a function call should also work, but IMHO 
> > compile time constant is preferable option.
> > I don't think making it compile time constant for SPIR only makes sense to 
> > me - in this case we can use constant for all targets.
> > 
> > How about following approach: use 0 by default and allow other targets 
> > re-define CLK_NULL_RESERVE_ID value.
> > 
> > ```
> > #ifndef CLK_NULL_RESERVE_ID
> >   #define CLK_NULL_RESERVE_ID 0
> > #endif // CLK_NULL_RESERVE_ID 
> > ```
> > 
> > If CLK_NULL_RESERVE_ID defined via -D command line option or included 
> > before OpenCL C header file (via -include option), the defined value will 
> > be used, otherwise 0.
> > 
> > Will it work for you?
> No. That makes us unable to consume SPIR since CLK_N

r303557 - clang-format: [JS] avoid line breaks before unindented r_parens.

2017-05-22 Thread Martin Probst via cfe-commits
Author: mprobst
Date: Mon May 22 09:58:26 2017
New Revision: 303557

URL: http://llvm.org/viewvc/llvm-project?rev=303557&view=rev
Log:
clang-format: [JS] avoid line breaks before unindented r_parens.

The change that enabled wrapping at the previous scope's indentation had
unintended side-effects in that clang-format would prefer to wrap
closing parentheses to the next line if it avoided a wrap on the next
line (assuming very narrow lines):

fooObject
.someCall(barbazbam)
.then(bam);

Would get formatted as:

fooObject.someCall(barbazbam
).then(bam);

Because the ')' is now indented at the parent level (fooObject).

Normally formatting a builder pattern style call sequence like that is
outlawed in clang-format anyway. However for JavaScript this is special
cased to support trailing .bind calls.

This change disallows this special case when following a closing ')' to
avoid the problem.

Included are some random comment fixes.

Reviewers: djasper

Subscribers: klimek, cfe-commits

Differential Revision: https://reviews.llvm.org/D33399

Modified:
cfe/trunk/lib/Format/ContinuationIndenter.cpp
cfe/trunk/lib/Format/TokenAnnotator.cpp
cfe/trunk/unittests/Format/FormatTestJS.cpp

Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.cpp?rev=303557&r1=303556&r2=303557&view=diff
==
--- cfe/trunk/lib/Format/ContinuationIndenter.cpp (original)
+++ cfe/trunk/lib/Format/ContinuationIndenter.cpp Mon May 22 09:58:26 2017
@@ -207,7 +207,7 @@ bool ContinuationIndenter::mustBreak(con
   // ...
   //   }.bind(...));
   // FIXME: We should find a more generic solution to this problem.
-  !(State.Column <= NewLineColumn &&
+  !(State.Column <= NewLineColumn && Previous.isNot(tok::r_paren) &&
 Style.Language == FormatStyle::LK_JavaScript))
 return true;
 

Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=303557&r1=303556&r2=303557&view=diff
==
--- cfe/trunk/lib/Format/TokenAnnotator.cpp (original)
+++ cfe/trunk/lib/Format/TokenAnnotator.cpp Mon May 22 09:58:26 2017
@@ -2570,7 +2570,7 @@ bool TokenAnnotator::canBreakBefore(cons
 Keywords.kw_interface, Keywords.kw_type, tok::kw_static,
 tok::kw_public, tok::kw_private, tok::kw_protected,
 Keywords.kw_abstract, Keywords.kw_get, Keywords.kw_set))
-  return false; // Otherwise a semicolon is inserted.
+  return false; // Otherwise automatic semicolon insertion would trigger.
 if (Left.is(TT_JsFatArrow) && Right.is(tok::l_brace))
   return false;
 if (Left.is(TT_JsTypeColon))

Modified: cfe/trunk/unittests/Format/FormatTestJS.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestJS.cpp?rev=303557&r1=303556&r2=303557&view=diff
==
--- cfe/trunk/unittests/Format/FormatTestJS.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTestJS.cpp Mon May 22 09:58:26 2017
@@ -1823,6 +1823,11 @@ TEST_F(FormatTestJS, NonNullAssertionOpe
   verifyFormat("let x = !foo;\n");
   verifyFormat("let x = foo[0]!;\n");
   verifyFormat("let x = (foo)!;\n");
+  verifyFormat("let x = x(foo!);\n");
+  verifyFormat(
+  "a.aa(a.a!).then(\n"
+  "x => x(x));\n",
+  getGoogleJSStyleWithColumns(20));
   verifyFormat("let x = foo! - 1;\n");
   verifyFormat("let x = {foo: 1}!;\n");
   verifyFormat(


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33285: clang-format: do not reflow bullet lists

2017-05-22 Thread Francois Ferrand via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL303556: clang-format: do not reflow bullet lists (authored 
by Typz).

Changed prior to commit:
  https://reviews.llvm.org/D33285?vs=99436&id=99764#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D33285

Files:
  cfe/trunk/lib/Format/BreakableToken.cpp
  cfe/trunk/unittests/Format/FormatTestComments.cpp

Index: cfe/trunk/unittests/Format/FormatTestComments.cpp
===
--- cfe/trunk/unittests/Format/FormatTestComments.cpp
+++ cfe/trunk/unittests/Format/FormatTestComments.cpp
@@ -1577,7 +1577,7 @@
" *\n"
" * long */",
getLLVMStyleWithColumns(20)));
-  
+
   // Don't reflow lines having content that is a single character.
   EXPECT_EQ("// long long long\n"
 "// long\n"
@@ -1602,7 +1602,7 @@
 format("// long long long long\n"
"// @param arg",
getLLVMStyleWithColumns(20)));
-  
+
   // Don't reflow lines starting with 'TODO'.
   EXPECT_EQ("// long long long\n"
 "// long\n"
@@ -1671,6 +1671,69 @@
"//  long",
getLLVMStyleWithColumns(20)));
 
+  // Don't reflow separate bullets in list
+  EXPECT_EQ("// - long long long\n"
+"// long\n"
+"// - long",
+format("// - long long long long\n"
+   "// - long",
+   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("// * long long long\n"
+"// long\n"
+"// * long",
+format("// * long long long long\n"
+   "// * long",
+   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("// + long long long\n"
+"// long\n"
+"// + long",
+format("// + long long long long\n"
+   "// + long",
+   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("// 1. long long long\n"
+"// long\n"
+"// 2. long",
+format("// 1. long long long long\n"
+   "// 2. long",
+   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("// -# long long long\n"
+"// long\n"
+"// -# long",
+format("// -# long long long long\n"
+   "// -# long",
+   getLLVMStyleWithColumns(20)));
+
+  EXPECT_EQ("// - long long long\n"
+"// long long long\n"
+"// - long",
+format("// - long long long long\n"
+   "// long long\n"
+   "// - long",
+   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("// - long long long\n"
+"// long long long\n"
+"// long\n"
+"// - long",
+format("// - long long long long\n"
+   "// long long long\n"
+   "// - long",
+   getLLVMStyleWithColumns(20)));
+
+  // Large number (>2 digits) are not list items
+  EXPECT_EQ("// long long long\n"
+"// long 1024. long.",
+format("// long long long long\n"
+   "// 1024. long.",
+   getLLVMStyleWithColumns(20)));
+
+  // Do not break before number, to avoid introducing a non-reflowable doxygen
+  // list item.
+  EXPECT_EQ("// long long\n"
+"// long 10. long.",
+format("// long long long 10.\n"
+   "// long.",
+   getLLVMStyleWithColumns(20)));
+
   // Don't break or reflow after implicit string literals.
   verifyFormat("#include  // l l l\n"
" // l",
Index: cfe/trunk/lib/Format/BreakableToken.cpp
===
--- cfe/trunk/lib/Format/BreakableToken.cpp
+++ cfe/trunk/lib/Format/BreakableToken.cpp
@@ -78,6 +78,14 @@
   }
 
   StringRef::size_type SpaceOffset = Text.find_last_of(Blanks, MaxSplitBytes);
+
+  // Do not split before a number followed by a dot: this would be interpreted
+  // as a numbered list, which would prevent re-flowing in subsequent passes.
+  static llvm::Regex kNumberedListRegexp = llvm::Regex("^[1-9][0-9]?\\.");
+  if (SpaceOffset != StringRef::npos &&
+  kNumberedListRegexp.match(Text.substr(SpaceOffset).ltrim(Blanks)))
+SpaceOffset = Text.find_last_of(Blanks, SpaceOffset);
+
   if (SpaceOffset == StringRef::npos ||
   // Don't break at leading whitespace.
   Text.find_last_not_of(Blanks, SpaceOffset) == StringRef::npos) {
@@ -299,15 +307,24 @@
 static bool mayReflowContent(StringRef Content) {
   Content = Content.trim(Blanks);
   // Lines starting with '@' commonly have special meaning.
-  static const SmallVector kSpecialMeaningPrefixes = {
-  "@", "TODO", "FIXME", "XXX"};
+  // Lines starting with '-', '-#', '+' or '*' are bulleted/numbered lists.
+  static const SmallVector kSpecialMeaningPrefixes = {
+  "@", "TODO", "FIXME"

r303556 - clang-format: do not reflow bullet lists

2017-05-22 Thread Francois Ferrand via cfe-commits
Author: typz
Date: Mon May 22 09:47:17 2017
New Revision: 303556

URL: http://llvm.org/viewvc/llvm-project?rev=303556&view=rev
Log:
clang-format: do not reflow bullet lists

Summary:
This patch prevents reflowing bullet lists in block comments.

It handles all lists supported by doxygen and markdown, e.g. bullet
lists starting with '-', '*', '+', as well as numbered lists starting
with -# or a number followed by a dot.

Reviewers: krasimir

Reviewed By: krasimir

Subscribers: djasper, klimek, cfe-commits

Differential Revision: https://reviews.llvm.org/D33285

Modified:
cfe/trunk/lib/Format/BreakableToken.cpp
cfe/trunk/unittests/Format/FormatTestComments.cpp

Modified: cfe/trunk/lib/Format/BreakableToken.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/BreakableToken.cpp?rev=303556&r1=303555&r2=303556&view=diff
==
--- cfe/trunk/lib/Format/BreakableToken.cpp (original)
+++ cfe/trunk/lib/Format/BreakableToken.cpp Mon May 22 09:47:17 2017
@@ -78,6 +78,14 @@ static BreakableToken::Split getCommentS
   }
 
   StringRef::size_type SpaceOffset = Text.find_last_of(Blanks, MaxSplitBytes);
+
+  // Do not split before a number followed by a dot: this would be interpreted
+  // as a numbered list, which would prevent re-flowing in subsequent passes.
+  static llvm::Regex kNumberedListRegexp = llvm::Regex("^[1-9][0-9]?\\.");
+  if (SpaceOffset != StringRef::npos &&
+  kNumberedListRegexp.match(Text.substr(SpaceOffset).ltrim(Blanks)))
+SpaceOffset = Text.find_last_of(Blanks, SpaceOffset);
+
   if (SpaceOffset == StringRef::npos ||
   // Don't break at leading whitespace.
   Text.find_last_not_of(Blanks, SpaceOffset) == StringRef::npos) {
@@ -299,8 +307,9 @@ const FormatToken &BreakableComment::tok
 static bool mayReflowContent(StringRef Content) {
   Content = Content.trim(Blanks);
   // Lines starting with '@' commonly have special meaning.
-  static const SmallVector kSpecialMeaningPrefixes = {
-  "@", "TODO", "FIXME", "XXX"};
+  // Lines starting with '-', '-#', '+' or '*' are bulleted/numbered lists.
+  static const SmallVector kSpecialMeaningPrefixes = {
+  "@", "TODO", "FIXME", "XXX", "-# ", "- ", "+ ", "* " };
   bool hasSpecialMeaningPrefix = false;
   for (StringRef Prefix : kSpecialMeaningPrefixes) {
 if (Content.startswith(Prefix)) {
@@ -308,6 +317,14 @@ static bool mayReflowContent(StringRef C
   break;
 }
   }
+
+  // Numbered lists may also start with a number followed by '.'
+  // To avoid issues if a line starts with a number which is actually the end
+  // of a previous line, we only consider numbers with up to 2 digits.
+  static llvm::Regex kNumberedListRegexp = llvm::Regex("^[1-9][0-9]?\\. ");
+  hasSpecialMeaningPrefix = hasSpecialMeaningPrefix ||
+kNumberedListRegexp.match(Content);
+
   // Simple heuristic for what to reflow: content should contain at least two
   // characters and either the first or second character must be
   // non-punctuation.

Modified: cfe/trunk/unittests/Format/FormatTestComments.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestComments.cpp?rev=303556&r1=303555&r2=303556&view=diff
==
--- cfe/trunk/unittests/Format/FormatTestComments.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTestComments.cpp Mon May 22 09:47:17 2017
@@ -1577,7 +1577,7 @@ TEST_F(FormatTestComments, ReflowsCommen
" *\n"
" * long */",
getLLVMStyleWithColumns(20)));
-  
+
   // Don't reflow lines having content that is a single character.
   EXPECT_EQ("// long long long\n"
 "// long\n"
@@ -1602,7 +1602,7 @@ TEST_F(FormatTestComments, ReflowsCommen
 format("// long long long long\n"
"// @param arg",
getLLVMStyleWithColumns(20)));
-  
+
   // Don't reflow lines starting with 'TODO'.
   EXPECT_EQ("// long long long\n"
 "// long\n"
@@ -1671,6 +1671,69 @@ TEST_F(FormatTestComments, ReflowsCommen
"//  long",
getLLVMStyleWithColumns(20)));
 
+  // Don't reflow separate bullets in list
+  EXPECT_EQ("// - long long long\n"
+"// long\n"
+"// - long",
+format("// - long long long long\n"
+   "// - long",
+   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("// * long long long\n"
+"// long\n"
+"// * long",
+format("// * long long long long\n"
+   "// * long",
+   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("// + long long long\n"
+"// long\n"
+"// + long",
+format("// + long long long long\n"
+   "// + long",
+   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("// 1. long long 

[PATCH] D32896: [OpenCL] Make CLK_NULL_RESERVE_ID invalid reserve id.

2017-05-22 Thread Yaxun Liu via Phabricator via cfe-commits
yaxunl added inline comments.



Comment at: lib/Headers/opencl-c.h:16020
+// The macro CLK_NULL_RESERVE_ID refers to an invalid reservation ID.
+#define CLK_NULL_RESERVE_ID (__builtin_astype((void *)0, reserve_id_t))
 bool __ovld is_valid_reserve_id(reserve_id_t reserve_id);

bader wrote:
> yaxunl wrote:
> > yaxunl wrote:
> > > bader wrote:
> > > > yaxunl wrote:
> > > > > Anastasia wrote:
> > > > > > echuraev wrote:
> > > > > > > yaxunl wrote:
> > > > > > > > Anastasia wrote:
> > > > > > > > > yaxunl wrote:
> > > > > > > > > > Anastasia wrote:
> > > > > > > > > > > Looks good from my side.
> > > > > > > > > > > 
> > > > > > > > > > > @yaxunl , since you originally committed this. Could you 
> > > > > > > > > > > please verify that changing from `SIZE_MAX` to `0` would 
> > > > > > > > > > > be fine.
> > > > > > > > > > > 
> > > > > > > > > > > Btw, we have a similar definition for `CLK_NULL_EVENT`.
> > > > > > > > > > `__PIPE_RESERVE_ID_VALID_BIT` is implementation detail and 
> > > > > > > > > > not part of the spec. I would suggest to remove it from 
> > > > > > > > > > this header file.
> > > > > > > > > > 
> > > > > > > > > > The spec only requires CLK_NULL_RESERVE_ID to be defined 
> > > > > > > > > > but does not define its value. Naturally a valid id starts 
> > > > > > > > > > from 0 and increases. I don't see significant advantage to 
> > > > > > > > > > change CLK_NULL_RESERVE_ID from __SIZE_MAX to 0.
> > > > > > > > > > 
> > > > > > > > > > Is there any reason that this change is needed?
> > > > > > > > > I don't see issues to commit things outside of spec as soon 
> > > > > > > > > as they prefixed properly with "__".  But I agree it would be 
> > > > > > > > > nice to see if it's any useful and what the motivation is for 
> > > > > > > > > having different implementation.
> > > > > > > > For `__PIPE_RESERVE_ID_VALID_BIT`, it assumes that the 
> > > > > > > > implementation uses one specific bit of a reserve id to 
> > > > > > > > indicate that the reserve id is valid. Not all implementations 
> > > > > > > > assume that. Actually I am curious why that is needed too.
> > > > > > > About `CLK_NULL_RESERVE_ID`: we check that reserve id is valid if 
> > > > > > > significant bit equal to one. `CLK_NULL_RESERVE_ID refers to an 
> > > > > > > invalid reservation, so if `CLK_NULL_RESERVE_ID equal to 0, we 
> > > > > > > can be sure that significant bit doesn't equal to 1 and it is 
> > > > > > > invalid reserve id. Also it is more obviously if 
> > > > > > > CLK_**NULL**_RESERVE_ID is equal to 0.
> > > > > > > 
> > > > > > > What about `__PIPE_RESERVE_ID_VALID_BIT`: As I understand 
> > > > > > > previous implementation also assumes that one specific bit was of 
> > > > > > > a reverse id was used to indicate that the reserve id is valid. 
> > > > > > > So, we just increased reserve id size by one bit on 32-bit 
> > > > > > > platforms and by 33 bits on 64-bit platforms. 
> > > > > > It is more logical to me that `CLK_NULL_RESERVE_ID` is 0, but spec 
> > > > > > doesn't define it of course.
> > > > > In our implementation, valid reserve id starts at 0 and increasing 
> > > > > linearly until `__SIZE_MAX-1`. This change will break our 
> > > > > implementation.
> > > > > 
> > > > > However, we can modify our implementation to adopt this change since 
> > > > > it brings about benefits overall.
> > > > Ideally it would be great to have unified implementation, but we can 
> > > > define device specific value for CLK_NULL_RESERVE_ID by using ifdef 
> > > > directive.
> > > How about
> > > 
> > > ```
> > > __attribute__((const)) size_t __clk_null_reserve_id();
> > > #define CLK_NULL_RESERVE_ID __clk_null_reserve_id()
> > > 
> > > ```
> > > I think the spec does not require it to be compile time constant. Then 
> > > each library can implement its own __clk_null_reserve_id() whereas the IR 
> > > is target independent.
> > Or we only do this for SPIR and define it as target specific value for 
> > other targets.
> Defining CLK_NULL_RESERVE_ID as a function call should also work, but IMHO 
> compile time constant is preferable option.
> I don't think making it compile time constant for SPIR only makes sense to me 
> - in this case we can use constant for all targets.
> 
> How about following approach: use 0 by default and allow other targets 
> re-define CLK_NULL_RESERVE_ID value.
> 
> ```
> #ifndef CLK_NULL_RESERVE_ID
>   #define CLK_NULL_RESERVE_ID 0
> #endif // CLK_NULL_RESERVE_ID 
> ```
> 
> If CLK_NULL_RESERVE_ID defined via -D command line option or included before 
> OpenCL C header file (via -include option), the defined value will be used, 
> otherwise 0.
> 
> Will it work for you?
No. That makes us unable to consume SPIR since CLK_NULL_RESERVE_ID is hardcoded 
as 0 when the source code is translated to SPIR whereas our target expects ~0U.

To get a portable IR we need to represent CLK_NULL_RESERVE_ID as a function 
which can be lowered to a constant by a specific t

[PATCH] D32480: clang-format: Add CompactNamespaces option

2017-05-22 Thread Francois Ferrand via Phabricator via cfe-commits
Typz updated this revision to Diff 99763.
Typz added a comment.

Remove dependency on https://reviews.llvm.org/D33314


https://reviews.llvm.org/D32480

Files:
  include/clang/Format/Format.h
  lib/Format/Format.cpp
  lib/Format/NamespaceEndCommentsFixer.cpp
  lib/Format/UnwrappedLineFormatter.cpp
  unittests/Format/FormatTest.cpp

Index: unittests/Format/FormatTest.cpp
===
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -1309,6 +1309,140 @@
Style));
 }
 
+TEST_F(FormatTest, FormatsCompactNamespaces) {
+  FormatStyle Style = getLLVMStyle();
+  Style.CompactNamespaces = true;
+
+  verifyFormat("namespace A { namespace B {\n"
+			   "}} // namespace A::B",
+			   Style);
+
+  EXPECT_EQ("namespace out { namespace in {\n"
+"}} // namespace out::in",
+format("namespace out {\n"
+   "namespace in {\n"
+   "} // namespace in\n"
+   "} // namespace out",
+   Style));
+
+  EXPECT_EQ("namespace out { namespace in1 {\n"
+"} // namespace in1\n"
+"namespace in2 {\n"
+"}} // namespace out::in2",
+format("namespace out {\n"
+   "namespace in1 {\n"
+   "} // namespace in1\n"
+   "namespace in2 {\n"
+   "} // namespace in2\n"
+   "} // namespace out",
+   Style));
+
+  EXPECT_EQ("namespace out {\n"
+"int i;\n"
+"namespace in {\n"
+"int j;\n"
+"} // namespace in\n"
+"int k;\n"
+"} // namespace out",
+format("namespace out { int i;\n"
+   "namespace in { int j; } // namespace in\n"
+   "int k; } // namespace out",
+   Style));
+
+  EXPECT_EQ("namespace A { namespace B { namespace C {\n"
+"}}} // namespace A::B::C\n",
+format("namespace A { namespace B {\n"
+   "namespace C {\n"
+   "}} // namespace B::C\n"
+   "} // namespace A\n",
+   Style));
+
+  EXPECT_EQ("namespace  {\n"
+			"namespace  {\n"
+"}} // namespace ::",
+format("namespace  {\n"
+   "namespace  {\n"
+   "} // namespace \n"
+   "} // namespace ",
+   Style));
+
+  EXPECT_EQ("namespace a { namespace b {\n"
+			"namespace c {\n"
+"}}} // namespace a::b::c",
+format("namespace a {\n"
+   "namespace b {\n"
+   "namespace c {\n"
+   "} // namespace c\n"
+   "} // namespace b\n"
+   "} // namespace a",
+   Style));
+
+  // Missing comments are added
+  EXPECT_EQ("namespace out { namespace in {\n"
+			"int i;\n"
+			"int j;\n"
+"}} // namespace out::in",
+format("namespace out {\n"
+   "namespace in {\n"
+   "int i;\n"
+   "int j;\n"
+   "}\n"
+   "}",
+   Style));
+
+  // Incorrect comments are fixed
+  EXPECT_EQ("namespace out { namespace in {\n"
+"}} // namespace out::in",
+format("namespace out { namespace in {\n"
+   "}} // namespace out",
+   Style));
+  EXPECT_EQ("namespace out { namespace in {\n"
+"}} // namespace out::in",
+format("namespace out { namespace in {\n"
+   "}} // namespace in",
+   Style));
+
+  // Extra semicolon after 'inner' closing brace prevents merging
+  EXPECT_EQ("namespace out { namespace in {\n"
+"}; } // namespace out::in",
+format("namespace out {\n"
+   "namespace in {\n"
+   "}; // namespace in\n"
+   "} // namespace out",
+   Style));
+
+  // Extra semicolon after 'outer' closing brace is conserved
+  EXPECT_EQ("namespace out { namespace in {\n"
+"}}; // namespace out::in",
+format("namespace out {\n"
+   "namespace in {\n"
+   "} // namespace in\n"
+   "}; // namespace out",
+   Style));
+
+  Style.NamespaceIndentation = FormatStyle::NI_All;
+  EXPECT_EQ("namespace out { namespace in {\n"
+"int i;\n"
+"}} // namespace out::in",
+format("na

  1   2   >