r186210 - Compute 'this' correctly for block in lambda.

Eli Friedman eli.friedman at gmail.com
Fri Jul 12 15:05:26 PDT 2013


Author: efriedma
Date: Fri Jul 12 17:05:26 2013
New Revision: 186210

URL: http://llvm.org/viewvc/llvm-project?rev=186210&view=rev
Log:
Compute 'this' correctly for block in lambda.

Using CurFuncDecl is both correct and simple compared to crawling
the DeclContexts of the block.

Fixes <rdar://problem/14415072>.

Modified:
    cfe/trunk/lib/CodeGen/CGBlocks.cpp
    cfe/trunk/test/CodeGenObjCXX/lambda-expressions.mm

Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=186210&r1=186209&r2=186210&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Fri Jul 12 17:05:26 2013
@@ -355,14 +355,9 @@ static void computeBlockInfo(CodeGenModu
 
   // First, 'this'.
   if (block->capturesCXXThis()) {
-    const DeclContext *DC = block->getDeclContext();
-    for (; isa<BlockDecl>(DC); DC = cast<BlockDecl>(DC)->getDeclContext())
-      ;
-    QualType thisType;
-    if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC))
-      thisType = C.getPointerType(C.getRecordType(RD));
-    else
-      thisType = cast<CXXMethodDecl>(DC)->getThisType(C);
+    assert(CGF && CGF->CurFuncDecl && isa<CXXMethodDecl>(CGF->CurFuncDecl) &&
+           "Can't capture 'this' outside a method");
+    QualType thisType = cast<CXXMethodDecl>(CGF->CurFuncDecl)->getThisType(C);
 
     llvm::Type *llvmType = CGM.getTypes().ConvertType(thisType);
     std::pair<CharUnits,CharUnits> tinfo

Modified: cfe/trunk/test/CodeGenObjCXX/lambda-expressions.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/lambda-expressions.mm?rev=186210&r1=186209&r2=186210&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjCXX/lambda-expressions.mm (original)
+++ cfe/trunk/test/CodeGenObjCXX/lambda-expressions.mm Fri Jul 12 17:05:26 2013
@@ -60,6 +60,12 @@ void take_block(void (^block)()) { block
 }
 @end
 
+// Check lines for BlockInLambda test below
+// ARC: define internal i32 @___ZZN13BlockInLambda1X1fEvENKUlvE_clEv_block_invoke
+// ARC: [[Y:%.*]] = getelementptr inbounds %"struct.BlockInLambda::X"* {{.*}}, i32 0, i32 1
+// ARC-NEXT: [[YVAL:%.*]] = load i32* [[Y]], align 4
+// ARC-NEXT: ret i32 [[YVAL]]
+
 typedef int (^fptr)();
 template<typename T> struct StaticMembers {
   static fptr f;
@@ -69,6 +75,18 @@ fptr StaticMembers<T>::f = [] { auto f =
 template fptr StaticMembers<float>::f;
 // ARC: define linkonce_odr i32 ()* @_ZZNK13StaticMembersIfE1fMUlvE_clEvENKUlvE_cvU13block_pointerFivEEv
 
+namespace BlockInLambda {
+  struct X {
+    int x,y;
+    void f() {
+      [this]{return ^{return y;}();}();
+    };
+  };
+  void g(X& x) {
+    x.f();
+  };
+}
+
 
 // ARC: attributes [[NUW]] = { nounwind{{.*}} }
 // MRC: attributes [[NUW]] = { nounwind{{.*}} }





More information about the cfe-commits mailing list