]> granicus.if.org Git - clang/commitdiff
Make sure Sema creates a field for 'this' captures. (Doug, please double-check that...
authorEli Friedman <eli.friedman@gmail.com>
Sat, 11 Feb 2012 02:51:16 +0000 (02:51 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Sat, 11 Feb 2012 02:51:16 +0000 (02:51 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150292 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/ScopeInfo.h
lib/Sema/SemaExprCXX.cpp
test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp

index 91f468b3e537d954b510489f254185a15fc031a2..ea77ff49cb5980fb172ad38575d61131222f3f9b 100644 (file)
@@ -156,8 +156,8 @@ public:
         CopyExprAndNested(Cpy, isNested) {}
 
     enum IsThisCapture { ThisCapture };
-    Capture(IsThisCapture, bool isNested, SourceLocation Loc)
-      : VarAndKind(0, Cap_This), CopyExprAndNested(0, isNested), Loc(Loc) {
+    Capture(IsThisCapture, bool isNested, SourceLocation Loc, Expr *Cpy)
+      : VarAndKind(0, Cap_This), CopyExprAndNested(Cpy, isNested), Loc(Loc) {
     }
 
     bool isThisCapture() const { return VarAndKind.getInt() == Cap_This; }
@@ -208,8 +208,8 @@ public:
     CaptureMap[Var] = Captures.size();
   }
 
-  void AddThisCapture(bool isNested, SourceLocation Loc) {
-    Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc));
+  void AddThisCapture(bool isNested, SourceLocation Loc, Expr *Cpy) {
+    Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, Cpy));
     CXXThisCaptureIndex = Captures.size();
   }
 
index 5a2a827230852df0d46a9856ca4f5d72144600b6..c16d7e2282ed0951f3bc20cdeab2642d78fa92d1 100644 (file)
@@ -707,8 +707,22 @@ void Sema::CheckCXXThisCapture(SourceLocation Loc, bool Explicit) {
   for (unsigned idx = FunctionScopes.size() - 1;
        NumClosures; --idx, --NumClosures) {
     CapturingScopeInfo *CSI = cast<CapturingScopeInfo>(FunctionScopes[idx]);
+    Expr *ThisExpr = 0;
+    if (LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(CSI)) {
+      // For lambda expressions, build a field and an initializing expression.
+      QualType ThisTy = getCurrentThisType();
+      CXXRecordDecl *Lambda = LSI->Lambda;
+      FieldDecl *Field
+        = FieldDecl::Create(Context, Lambda, Loc, Loc, 0, ThisTy,
+                            Context.getTrivialTypeSourceInfo(ThisTy, Loc),
+                            0, false, false);
+      Field->setImplicit(true);
+      Field->setAccess(AS_private);
+      Lambda->addDecl(Field);
+      ThisExpr = new (Context) CXXThisExpr(Loc, ThisTy, /*isImplicit=*/true);
+    }
     bool isNested = NumClosures > 1;
-    CSI->AddThisCapture(isNested, Loc);
+    CSI->AddThisCapture(isNested, Loc, ThisExpr);
   }
 }
 
index ad603e17193dc9097b2c6c7aa03a81921b9d295b..1f7580eedc1c6700f46c7586e8938b0d9cff0693 100644 (file)
@@ -55,3 +55,11 @@ void test_layout(char a, short b) {
   };
   static_assert(sizeof(x) == sizeof(ExpectedLayout), "Layout mismatch!");
 }
+
+struct ExpectedThisLayout {
+  ExpectedThisLayout* a;
+  void f() {
+    auto x = [this]() -> void {};
+    static_assert(sizeof(x) == sizeof(ExpectedThisLayout), "Layout mismatch!");
+  }
+};