Author: echristo
Date: Thu Mar  1 15:36:52 2012
New Revision: 151838

URL: http://llvm.org/viewvc/llvm-project?rev=151838&view=rev
Log:
Reapply r151702 with a small fix for a failure to cut and paste
correctly.

Still rdar://10900684

Added:
    cfe/trunk/test/CodeGenCXX/debug-lambda-expressions.cpp
Modified:
    cfe/trunk/lib/CodeGen/CGDebugInfo.cpp

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=151838&r1=151837&r2=151838&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Thu Mar  1 15:36:52 2012
@@ -749,44 +749,75 @@
                     SmallVectorImpl<llvm::Value *> &elements,
                     llvm::DIType RecordTy) {
   unsigned fieldNo = 0;
-  const FieldDecl *LastFD = 0;
-  bool IsMsStruct = record->hasAttr<MsStructAttr>();
-  
   const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
-  for (RecordDecl::field_iterator I = record->field_begin(),
-                                  E = record->field_end();
-       I != E; ++I, ++fieldNo) {
-    FieldDecl *field = *I;
-    if (IsMsStruct) {
-      // Zero-length bitfields following non-bitfield members are ignored
-      if (CGM.getContext().ZeroBitfieldFollowsNonBitfield((field), LastFD)) {
-        --fieldNo;
-        continue;
+  const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(record);
+
+  // For C++11 Lambdas a Fields will be the same as a Capture, but the Capture
+  // has the name and the location of the variable so we should iterate over
+  // both concurrently.
+  if (CXXDecl && CXXDecl->isLambda()) {
+    RecordDecl::field_iterator Field = CXXDecl->field_begin();
+    unsigned fieldno = 0;
+    for (CXXRecordDecl::capture_const_iterator I = CXXDecl->captures_begin(),
+           E = CXXDecl->captures_end(); I != E; ++I, ++Field, ++fieldno) {
+      const LambdaExpr::Capture C = *I;
+      // TODO: Need to handle 'this' in some way by probably renaming the
+      // this of the lambda class and having a field member of 'this'.
+      if (C.capturesVariable()) {
+        VarDecl *V = C.getCapturedVar();
+        llvm::DIFile VUnit = getOrCreateFile(C.getLocation());
+        StringRef VName = V->getName();
+        uint64_t SizeInBitsOverride = 0;
+        if (Field->isBitField()) {
+          SizeInBitsOverride = Field->getBitWidthValue(CGM.getContext());
+          assert(SizeInBitsOverride && "found named 0-width bitfield");
+        }
+        llvm::DIType fieldType
+          = createFieldType(VName, Field->getType(), SizeInBitsOverride, 
C.getLocation(),
+                            Field->getAccess(), layout.getFieldOffset(fieldno),
+                            VUnit, RecordTy);
+        elements.push_back(fieldType);
       }
-      LastFD = field;
     }
+  } else {
+    bool IsMsStruct = record->hasAttr<MsStructAttr>();
+    const FieldDecl *LastFD = 0;
+    for (RecordDecl::field_iterator I = record->field_begin(),
+           E = record->field_end();
+         I != E; ++I, ++fieldNo) {
+      FieldDecl *field = *I;
+
+      if (IsMsStruct) {
+        // Zero-length bitfields following non-bitfield members are ignored
+        if (CGM.getContext().ZeroBitfieldFollowsNonBitfield((field), LastFD)) {
+          --fieldNo;
+          continue;
+        }
+        LastFD = field;
+      }
 
-    StringRef name = field->getName();
-    QualType type = field->getType();
+      StringRef name = field->getName();
+      QualType type = field->getType();
 
-    // Ignore unnamed fields unless they're anonymous structs/unions.
-    if (name.empty() && !type->isRecordType()) {
-      LastFD = field;
-      continue;
-    }
+      // Ignore unnamed fields unless they're anonymous structs/unions.
+      if (name.empty() && !type->isRecordType()) {
+        LastFD = field;
+        continue;
+      }
 
-    uint64_t SizeInBitsOverride = 0;
-    if (field->isBitField()) {
-      SizeInBitsOverride = field->getBitWidthValue(CGM.getContext());
-      assert(SizeInBitsOverride && "found named 0-width bitfield");
-    }
+      uint64_t SizeInBitsOverride = 0;
+      if (field->isBitField()) {
+        SizeInBitsOverride = field->getBitWidthValue(CGM.getContext());
+        assert(SizeInBitsOverride && "found named 0-width bitfield");
+      }
 
-    llvm::DIType fieldType
-      = createFieldType(name, type, SizeInBitsOverride,
-                        field->getLocation(), field->getAccess(),
-                        layout.getFieldOffset(fieldNo), tunit, RecordTy);
+      llvm::DIType fieldType
+        = createFieldType(name, type, SizeInBitsOverride,
+                          field->getLocation(), field->getAccess(),
+                          layout.getFieldOffset(fieldNo), tunit, RecordTy);
 
-    elements.push_back(fieldType);
+      elements.push_back(fieldType);
+    }
   }
 }
 

Added: cfe/trunk/test/CodeGenCXX/debug-lambda-expressions.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/debug-lambda-expressions.cpp?rev=151838&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/debug-lambda-expressions.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/debug-lambda-expressions.cpp Thu Mar  1 15:36:52 
2012
@@ -0,0 +1,71 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s 
-fexceptions -std=c++11 -g | FileCheck %s
+
+auto var = [](int i) { return i+1; };
+
+extern "C" auto cvar = []{};
+
+int a() { return []{ return 1; }(); }
+
+int b(int x) { return [x]{return x;}(); }
+
+int c(int x) { return [&x]{return x;}(); }
+
+struct D { D(); D(const D&); int x; };
+int d(int x) { D y[10]; [x,y] { return y[x].x; }(); }
+
+
+// A: 5
+// CHECK: [[A_FUNC:.*]] = metadata !{i32 {{.*}}, i32 0, metadata [[FILE:.*]], 
metadata !"a", metadata !"a", metadata !"_Z1av", metadata {{.*}}, i32 
[[A_LINE:.*]], metadata {{.*}}, i1 false, i1 true, i32 0, i32 0, null, i32 256, 
i1 false, i32 ()* @_Z1av, null, null, {{.*}} [ DW_TAG_subprogram ]
+
+// Randomness for file. -- 6
+// CHECK: [[FILE]] = metadata !{i32 {{.*}}, metadata 
!{{.*}}debug-lambda-expressions.cpp{{.*}}; [ DW_TAG_file_type ]
+
+// B: 12
+// CHECK: [[B_FUNC:.*]] = metadata !{i32 786478, i32 0, metadata [[FILE]], 
metadata !"b", metadata !"b", metadata !"_Z1bi", metadata [[FILE]], i32 
[[B_LINE:.*]], metadata {{.*}}, i1 false, i1 true, i32 0, i32 0, null, i32 256, 
i1 false, i32 (i32)* @_Z1bi, null, null, {{.*}} ; [ DW_TAG_subprogram ]
+
+// C: 17
+// CHECK: [[C_FUNC:.*]] = metadata !{i32 {{.*}}, i32 0, metadata [[FILE]], 
metadata !"c", metadata !"c", metadata !"_Z1ci", metadata [[FILE]], i32 
[[C_LINE:.*]], metadata {{.*}}, i1 false, i1 true, i32 0, i32 0, null, i32 256, 
i1 false, i32 (i32)* @_Z1ci, null, null, metadata {{.*}} ; [ DW_TAG_subprogram ]
+
+// D: 20
+// CHECK: [[D_FUNC:.*]] = metadata !{i32 {{.*}}, i32 0, metadata [[FILE]], 
metadata !"d", metadata !"d", metadata !"_Z1di", metadata [[FILE]], i32 
[[D_LINE:.*]], metadata {{.*}}, i1 false, i1 true, i32 0, i32 0, null, i32 256, 
i1 false, i32 (i32)* @_Z1di, null, null, metadata {{.*}} ; [ DW_TAG_subprogram ]
+
+// Back to D. -- 120
+// CHECK: [[LAM_D:.*]] = metadata !{i32 {{.*}}, metadata [[D_FUNC]], metadata 
!"", metadata [[FILE]], i32 [[D_LINE]], i64 352, i64 32, i32 0, i32 0, null, 
metadata [[LAM_D_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ]
+// CHECK: [[LAM_D_ARGS]] = metadata !{metadata [[CAP_D_X:.*]], metadata 
[[CAP_D_Y:.*]], metadata [[CON_LAM_D:.*]], metadata [[DES_LAM_D:.*]]}
+// CHECK: [[CAP_D_X]] = metadata !{i32 {{.*}}, metadata [[LAM_D]], metadata 
!"x", metadata [[FILE]], i32 14, i64 32, i64 32, i64 0, i32 1, metadata {{.*}} 
; [ DW_TAG_member ]
+// CHECK: [[CAP_D_Y]] = metadata !{i32 {{.*}}, metadata [[LAM_D]], metadata 
!"y", metadata [[FILE]], i32 14, i64 320, i64 32, i64 32, i32 1, metadata 
{{.*}} ; [ DW_TAG_member ]
+// CHECK: [[CON_LAM_D]] = metadata {{.*}}[[LAM_D]], metadata !"operator()", 
metadata !"operator()"{{.*}}[ DW_TAG_subprogram ]
+// CHECK: [[DES_LAM_D]] = metadata {{.*}}[[LAM_D]], metadata !"~", metadata 
!"~"{{.*}}[ DW_TAG_subprogram ]
+
+
+// Back to C. -- 159
+// CHECK: [[LAM_C:.*]] = metadata !{i32 {{.*}}, metadata [[C_FUNC]], metadata 
!"", metadata [[FILE]], i32 [[C_LINE]], i64 64, i64 64, i32 0, i32 0, null, 
metadata [[LAM_C_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ]
+// CHECK: [[LAM_C_ARGS]] = metadata !{metadata [[CAP_C:.*]], metadata 
[[CON_LAM_C:.*]], metadata [[DES_LAM_C:.*]]}
+// Ignoring the member type for now.
+// CHECK: [[CAP_C]] = metadata !{i32 {{.*}}, metadata [[LAM_C]], metadata 
!"x", metadata [[FILE]], i32 [[C_LINE]], i64 64, i64 64, i64 0, i32 1, metadata 
{{.*}}} ; [ DW_TAG_member ]
+// CHECK: [[CON_LAM_C]] = metadata {{.*}}[[LAM_C]], metadata !"operator()", 
metadata !"operator()"{{.*}}[ DW_TAG_subprogram ]
+// CHECK: [[DES_LAM_C]] = metadata {{.*}}[[LAM_C]], metadata !"~", metadata 
!"~"{{.*}}[ DW_TAG_subprogram ]
+
+
+// Back to B. -- 179
+// CHECK: [[LAM_B:.*]] = metadata !{i32 {{.*}}, metadata [[B_FUNC]], metadata 
!"", metadata [[FILE]], i32 [[B_LINE]], i64 32, i64 32, i32 0, i32 0, null, 
metadata [[LAM_B_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ]
+// CHECK: [[LAM_B_ARGS]] = metadata !{metadata [[CAP_B:.*]], metadata 
[[CON_LAM_B:.*]], metadata [[DES_LAM_B:.*]]}
+// CHECK: [[CAP_B]] = metadata !{i32 {{.*}}, metadata [[LAM_B]], metadata 
!"x", metadata [[FILE]], i32 [[B_LINE]], i64 32, i64 32, i64 0, i32 1, metadata 
{{.*}}} ; [ DW_TAG_member ]
+// CHECK: [[CON_LAM_B]] = metadata {{.*}}[[LAM_B]], metadata !"operator()", 
metadata !"operator()"{{.*}}[ DW_TAG_subprogram ]
+// CHECK: [[DES_LAM_B]] = metadata {{.*}}[[LAM_B]], metadata !"~", metadata 
!"~"{{.*}}[ DW_TAG_subprogram ]
+
+// Back to A. -- 204
+// CHECK: [[LAM_A:.*]] = metadata !{i32 {{.*}}, metadata [[A_FUNC]], metadata 
!"", metadata [[FILE]], i32 [[A_LINE]], i64 8, i64 8, i32 0, i32 0, null, 
metadata [[LAM_A_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ]
+// CHECK: [[LAM_A_ARGS]] = metadata !{metadata [[CON_LAM_A:.*]], metadata 
[[DES_LAM_A:.*]]}
+// CHECK: [[CON_LAM_A]] = metadata {{.*}}[[LAM_A]], metadata !"operator()", 
metadata !"operator()"{{.*}}[ DW_TAG_subprogram ]
+// CHECK: [[DES_LAM_A]] = metadata {{.*}}[[LAM_A]], metadata !"~", metadata 
!"~"{{.*}}[ DW_TAG_subprogram ]
+
+// VAR:
+// CHECK: metadata !{i32 {{.*}}, i32 0, null, metadata !"var", metadata 
!"var", metadata !"", metadata [[FILE]], i32 [[VAR_LINE:.*]], metadata 
![[VAR_T:.*]], i32 1, i32 1, %class.anon* @var} ; [ DW_TAG_variable ]
+// CHECK: [[VAR_T]] = metadata !{i32 {{.*}}, null, metadata !"", metadata 
[[FILE]], i32 [[VAR_LINE]], i64 8, i64 8, i32 0, i32 0, null, metadata 
![[VAR_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ]
+// CHECK: [[VAR_ARGS]] = metadata !{metadata !{{.*}}, metadata !{{.*}}, 
metadata !{{.*}}}
+
+// CVAR:
+// CHECK: metadata !{i32 {{.*}}, i32 0, null, metadata !"cvar", metadata 
!"cvar", metadata !"", metadata [[FILE]], i32 [[CVAR_LINE:.*]], metadata 
![[CVAR_T:.*]], i32 0, i32 1, %class.anon.0* @cvar} ; [ DW_TAG_variable ]
+// CHECK: [[CVAR_T]] = metadata !{i32 {{.*}}, null, metadata !"", metadata 
[[FILE]], i32 [[CVAR_LINE]], i64 8, i64 8, i32 0, i32 0, null, metadata 
![[CVAR_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ]
+// CHECK: [[CVAR_ARGS]] = metadata !{metadata !{{.*}}, metadata !{{.*}}, 
metadata !{{.*}}}


_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to