]> granicus.if.org Git - clang/commitdiff
DebugInfo: Don't emit vbase 'containing types' for context chain limited types
authorDavid Blaikie <dblaikie@gmail.com>
Sun, 18 Aug 2013 16:55:33 +0000 (16:55 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Sun, 18 Aug 2013 16:55:33 +0000 (16:55 +0000)
Possible minor reduction in debug info & avoid some cases where creating
a context chain could lead to the type the context chain is being
created for, being created. (this is still possible with template
parameters - tests/fixes/improvements to follow)

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@188639 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGDebugInfo.cpp
lib/CodeGen/CGDebugInfo.h
test/CodeGenCXX/debug-info-class.cpp

index 71253caabbd9a1c6a5c393afe04a9488b9a30695..31422830f19f34c2079f629d03d60c3f7ed35508 100644 (file)
@@ -1453,6 +1453,9 @@ llvm::DIType CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) {
   if (FwdDecl.isForwardDecl())
     return FwdDecl;
 
+  if (const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
+    CollectContainingType(CXXDecl, FwdDecl);
+
   // Push the struct on region stack.
   LexicalBlockStack.push_back(&*FwdDecl);
   RegionMap[Ty->getDecl()] = llvm::WeakVH(FwdDecl);
@@ -2207,34 +2210,37 @@ llvm::DIType CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
   RegionMap[Ty->getDecl()] = llvm::WeakVH(RealDecl);
   TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = RealDecl;
 
-  if (const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
-    // A class's primary base or the class itself contains the vtable.
-    llvm::DICompositeType ContainingType;
-    const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
-    if (const CXXRecordDecl *PBase = RL.getPrimaryBase()) {
-      // Seek non virtual primary base root.
-      while (1) {
-        const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
-        const CXXRecordDecl *PBT = BRL.getPrimaryBase();
-        if (PBT && !BRL.isPrimaryBaseVirtual())
-          PBase = PBT;
-        else
-          break;
-      }
-      ContainingType = llvm::DICompositeType(
-          getOrCreateType(QualType(PBase->getTypeForDecl(), 0), DefUnit));
-    } else if (CXXDecl->isDynamicClass())
-      ContainingType = RealDecl;
-
-    RealDecl.setContainingType(ContainingType);
-    if (const ClassTemplateSpecializationDecl *TSpecial =
-            dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
-      RealDecl.setTypeArray(llvm::DIArray(),
-                            CollectCXXTemplateParams(TSpecial, DefUnit));
-  }
+  if (const ClassTemplateSpecializationDecl *TSpecial =
+          dyn_cast<ClassTemplateSpecializationDecl>(RD))
+    RealDecl.setTypeArray(llvm::DIArray(),
+                          CollectCXXTemplateParams(TSpecial, DefUnit));
   return RealDecl;
 }
 
+void CGDebugInfo::CollectContainingType(const CXXRecordDecl *RD,
+                                        llvm::DICompositeType RealDecl) {
+  // A class's primary base or the class itself contains the vtable.
+  llvm::DICompositeType ContainingType;
+  const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
+  if (const CXXRecordDecl *PBase = RL.getPrimaryBase()) {
+    // Seek non virtual primary base root.
+    while (1) {
+      const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
+      const CXXRecordDecl *PBT = BRL.getPrimaryBase();
+      if (PBT && !BRL.isPrimaryBaseVirtual())
+        PBase = PBT;
+      else
+        break;
+    }
+    ContainingType = llvm::DICompositeType(
+        getOrCreateType(QualType(PBase->getTypeForDecl(), 0),
+                        getOrCreateFile(RD->getLocation())));
+  } else if (RD->isDynamicClass())
+    ContainingType = RealDecl;
+
+  RealDecl.setContainingType(ContainingType);
+}
+
 /// CreateMemberType - Create new member and increase Offset by FType's size.
 llvm::DIType CGDebugInfo::CreateMemberType(llvm::DIFile Unit, QualType FType,
                                            StringRef Name,
index 39436e18a72d6781271bc1a9646a9a6d880f0fa3..54b9267f8e4e8c190b1287da670c588f8ff4dd31 100644 (file)
@@ -117,6 +117,7 @@ class CGDebugInfo {
   llvm::DIType CreateType(const RecordType *Ty, bool Declaration);
   llvm::DIType CreateTypeDefinition(const RecordType *Ty);
   llvm::DIType CreateLimitedType(const RecordType *Ty);
+  void CollectContainingType(const CXXRecordDecl *RD, llvm::DICompositeType CT);
   llvm::DIType CreateType(const ObjCInterfaceType *Ty, llvm::DIFile F);
   llvm::DIType CreateType(const ObjCObjectType *Ty, llvm::DIFile F);
   llvm::DIType CreateType(const VectorType *Ty, llvm::DIFile F);
index df2492603e360bc182a54ce00a0ed0a7fe263d7e..0a337dc05d8c8d2c9bcf79252f0d715db0cd68fb 100644 (file)
@@ -12,6 +12,14 @@ class B {
 public:
   virtual ~B();
 };
+
+struct C {
+  virtual void func();
+  struct inner {
+    int j;
+  };
+};
+
 struct A {
   int one;
   static const int HdrSize = 52;
@@ -24,6 +32,7 @@ struct A {
 
 int main(int argc, char **argv) {
   B b;
+  C::inner c_i;
   if (argc) {
     A a;
   }
@@ -44,5 +53,11 @@ int main(int argc, char **argv) {
 // CHECK: HdrSize
 // CHECK: DW_TAG_class_type ] [B]
 // CHECK: metadata !"_vptr$B", {{.*}}, i32 64, metadata !{{.*}}} ; [ DW_TAG_member ]
-// CHECK: ![[EXCEPTLOC]] = metadata !{i32 31,
-// CHECK: ![[RETLOC]] = metadata !{i32 30,
+// CHECK: metadata [[C_INNER_MEM:![0-9]*]], i32 0, null, null} ; [ DW_TAG_structure_type ] [inner] {{.*}} [def]
+// Context chains (in Clang -flimit-debug-info and in GCC generally) contain
+// definitions without members (& without a vbase 'containing type'):
+// CHECK: null, i32 0, null, null} ; [ DW_TAG_structure_type ] [C] {{.*}} [def]
+// CHECK: [[C_INNER_MEM]] = metadata !{metadata [[C_INNER_I:![0-9]*]]}
+// CHECK: [[C_INNER_I]] = {{.*}} ; [ DW_TAG_member ] [j] {{.*}} [from int]
+// CHECK: ![[EXCEPTLOC]] = metadata !{i32 40,
+// CHECK: ![[RETLOC]] = metadata !{i32 39,