]> granicus.if.org Git - clang/commitdiff
Add in a caching mechanism so that forward declarations are replaced
authorEric Christopher <echristo@apple.com>
Sat, 18 Feb 2012 00:50:17 +0000 (00:50 +0000)
committerEric Christopher <echristo@apple.com>
Sat, 18 Feb 2012 00:50:17 +0000 (00:50 +0000)
with full types if they exist.

rdar://10809898 and rdar://10209967 and rdar://10400981

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

lib/CodeGen/CGDebugInfo.cpp
lib/CodeGen/CGDebugInfo.h
test/CodeGenCXX/debug-info-dup-fwd-decl.cpp

index aa7f150fcf7ba21928175f0135f5b85b7431d562..75e99ac5f2596de1453fa8d302a099d9d7a9f6e1 100644 (file)
@@ -553,9 +553,7 @@ llvm::DIType CGDebugInfo::CreatePointeeType(QualType PointeeTy,
     RecordDecl *RD = RTy->getDecl();
     llvm::DIDescriptor FDContext =
       getContextDescriptor(cast<Decl>(RD->getDeclContext()));
-    llvm::DIType RetTy = createRecordFwdDecl(RD, FDContext);
-    TypeCache[PointeeTy.getAsOpaquePtr()] = RetTy;
-    return RetTy;
+    return createRecordFwdDecl(RD, FDContext);
   }
   return getOrCreateType(PointeeTy, Unit);
 
@@ -1616,6 +1614,10 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit) {
 
   // Otherwise create the type.
   llvm::DIType Res = CreateTypeNode(Ty, Unit);
+
+  llvm::DIType TC = getTypeOrNull(Ty);
+  if (TC.Verify() && TC.isForwardDecl())
+    ReplaceMap.push_back(std::make_pair(Ty.getAsOpaquePtr(), TC));
   
   // And update the type cache.
   TypeCache[Ty.getAsOpaquePtr()] = Res;
@@ -1725,6 +1727,9 @@ llvm::DIType CGDebugInfo::getOrCreateLimitedType(QualType Ty,
   // Otherwise create the type.
   llvm::DIType Res = CreateLimitedTypeNode(Ty, Unit);
 
+  if (T.Verify() && T.isForwardDecl())
+    ReplaceMap.push_back(std::make_pair(Ty.getAsOpaquePtr(), T));
+
   // And update the type cache.
   TypeCache[Ty.getAsOpaquePtr()] = Res;
   return Res;
@@ -1747,11 +1752,8 @@ llvm::DIType CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
 
   // If this is just a forward declaration, construct an appropriately
   // marked node and just return it.
-  if (!RD->getDefinition()) {
-    llvm::DIType RTy = createRecordFwdDecl(RD, RDContext);
-    TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = RTy;
-    return RTy;
-  }
+  if (!RD->getDefinition())
+    return createRecordFwdDecl(RD, RDContext);
 
   uint64_t Size = CGM.getContext().getTypeSize(Ty);
   uint64_t Align = CGM.getContext().getTypeAlign(Ty);
@@ -2561,3 +2563,25 @@ CGDebugInfo::getOrCreateNameSpace(const NamespaceDecl *NSDecl) {
   NameSpaceCache[NSDecl] = llvm::WeakVH(NS);
   return NS;
 }
+
+void CGDebugInfo::finalize(void) {
+  for (std::vector<std::pair<void *, llvm::WeakVH> >::const_iterator VI
+         = ReplaceMap.begin(), VE = ReplaceMap.end(); VI != VE; ++VI) {
+    llvm::DIType Ty, RepTy;
+    // Verify that the debug info still exists.
+    if (&*VI->second)
+      Ty = llvm::DIType(cast<llvm::MDNode>(VI->second));
+    
+    llvm::DenseMap<void *, llvm::WeakVH>::iterator it =
+      TypeCache.find(VI->first);
+    if (it != TypeCache.end()) {
+      // Verify that the debug info still exists.
+      if (&*it->second)
+        RepTy = llvm::DIType(cast<llvm::MDNode>(it->second));
+    }
+    
+    if (Ty.Verify() && RepTy.Verify())
+      Ty.replaceAllUsesWith(RepTy);
+  }
+  DBuilder.finalize();
+}
index 1116336ca76bb239063b934adb75ca90992532ba..a071b06c26d388983820eb1fbe433c8bdfd097f6 100644 (file)
@@ -56,6 +56,10 @@ class CGDebugInfo {
   /// CompleteTypeCache - Cache of previously constructed complete RecordTypes.
   llvm::DenseMap<void *, llvm::WeakVH> CompletedTypeCache;
 
+  /// ReplaceMap - Cache of forward declared types to RAUW at the end of
+  /// compilation.
+  std::vector<std::pair<void *, llvm::WeakVH> >ReplaceMap;
+
   bool BlockLiteralGenericSet;
   llvm::DIType BlockLiteralGeneric;
 
@@ -160,7 +164,8 @@ class CGDebugInfo {
 public:
   CGDebugInfo(CodeGenModule &CGM);
   ~CGDebugInfo();
-  void finalize() { DBuilder.finalize(); }
+
+  void finalize(void);
 
   /// setLocation - Update the current source location. If \arg loc is
   /// invalid it is ignored.
index 1f50256dff7eefe713171fc4db7f4bb6f5555d1b..e67987b5a3536953a6e15c996113c80a87c82dd4 100644 (file)
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin %s -o - | FileCheck %s
-// XFAIL: *
+// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin -fno-limit-debug-info %s -o - | FileCheck %s
+
 class Test
 {
 public:
@@ -19,6 +19,6 @@ protected:
 
 Test t;
 
-// CHECK: metadata !"data", metadata !7, i32 14, i64 32, i64 32, i32 0, i32 0
-// CHECK: metadata !"", null, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !5} ; [ DW_TAG_pointer_type ]
-// CHECK-NOT: metadata !"data", metadata !7, i32 13, i64 0, i64 0, i32 0, i32 4,
+// CHECK: metadata !"", null, i32 0, i64 64, i64 64, i64 0, i32 0, metadata {{.*}} [ DW_TAG_pointer_type ]
+// CHECK: metadata !"data", metadata !6, i32 14, i64 32, i64 32, i32 0, i32 0
+// CHECK-NOT: metadata !"data", metadata {{.*}}, i32 14, i64 0, i64 0, i32 0, i32 4,