r191606 - Switch from putting init capture VarDecls in the surrounding DeclContext to

Richard Smith richard-llvm at metafoo.co.uk
Fri Sep 27 21:31:26 PDT 2013


Author: rsmith
Date: Fri Sep 27 23:31:26 2013
New Revision: 191606

URL: http://llvm.org/viewvc/llvm-project?rev=191606&view=rev
Log:
Switch from putting init capture VarDecls in the surrounding DeclContext to
putting them in the call operator's DeclContext. This better matches the
language wording and avoids some cases where code gets confused by them for
namespace-scope lambdas and the like.

Modified:
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaLambda.cpp
    cfe/trunk/test/CodeGenCXX/cxx1y-init-captures.cpp

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=191606&r1=191605&r2=191606&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Sep 27 23:31:26 2013
@@ -1577,7 +1577,9 @@ Sema::BuildDeclRefExpr(ValueDecl *D, Qua
 
   bool refersToEnclosingScope =
     (CurContext != D->getDeclContext() &&
-     D->getDeclContext()->isFunctionOrMethod());
+     D->getDeclContext()->isFunctionOrMethod()) ||
+    (isa<VarDecl>(D) &&
+     cast<VarDecl>(D)->isInitCapture());
 
   DeclRefExpr *E;
   if (isa<VarTemplateSpecializationDecl>(D)) {
@@ -8116,9 +8118,14 @@ static NonConstCaptureKind isReferenceTo
   assert(var->hasLocalStorage() && "capture added 'const' to non-local?");
 
   // Decide whether the first capture was for a block or a lambda.
-  DeclContext *DC = S.CurContext;
-  while (DC->getParent() != var->getDeclContext())
+  DeclContext *DC = S.CurContext, *Prev = 0;
+  while (DC != var->getDeclContext()) {
+    Prev = DC;
     DC = DC->getParent();
+  }
+  // Unless we have an init-capture, we've gone one step too far.
+  if (!var->isInitCapture())
+    DC = Prev;
   return (isa<BlockDecl>(DC) ? NCCK_Block : NCCK_Lambda);
 }
 
@@ -11353,7 +11360,7 @@ bool Sema::tryCaptureVariable(VarDecl *V
   bool Nested = false;
   
   DeclContext *DC = CurContext;
-  if (Var->getDeclContext() == DC) return true;
+  if (!Var->isInitCapture() && Var->getDeclContext() == DC) return true;
   if (!Var->hasLocalStorage()) return true;
 
   bool HasBlocksAttr = Var->hasAttr<BlocksAttr>();

Modified: cfe/trunk/lib/Sema/SemaLambda.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=191606&r1=191605&r2=191606&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLambda.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLambda.cpp Fri Sep 27 23:31:26 2013
@@ -514,7 +514,7 @@ VarDecl *Sema::checkInitCapture(SourceLo
   // used as a variable, and only exists as a way to name and refer to the
   // init-capture.
   // FIXME: Pass in separate source locations for '&' and identifier.
-  VarDecl *NewVD = VarDecl::Create(Context, CurContext->getLexicalParent(), Loc,
+  VarDecl *NewVD = VarDecl::Create(Context, CurContext, Loc,
                                    Loc, Id, TSI->getType(), TSI, SC_Auto);
   NewVD->setInitCapture(true);
   NewVD->setReferenced(true);

Modified: cfe/trunk/test/CodeGenCXX/cxx1y-init-captures.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx1y-init-captures.cpp?rev=191606&r1=191605&r2=191606&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/cxx1y-init-captures.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/cxx1y-init-captures.cpp Fri Sep 27 23:31:26 2013
@@ -94,5 +94,9 @@ int h(int a) {
   } ();
 }
 
+// Ensure we can emit code for init-captures in global lambdas too.
+auto global_lambda = [a = 0] () mutable { return ++a; };
+int get_incremented() { return global_lambda(); }
+
 // CHECK-LABEL: define internal void @"_ZZ1fvEN3$_0D2Ev"(
 // CHECK: call void @_ZN1SD1Ev(





More information about the cfe-commits mailing list