From 7ff0c5d30d365ba5d4f08e1d2fcea0370b21699b Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Sat, 18 Feb 2012 00:50:17 +0000 Subject: [PATCH] Add in a caching mechanism so that forward declarations are replaced 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 | 40 ++++++++++++++++----- lib/CodeGen/CGDebugInfo.h | 7 +++- test/CodeGenCXX/debug-info-dup-fwd-decl.cpp | 10 +++--- 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index aa7f150fcf..75e99ac5f2 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -553,9 +553,7 @@ llvm::DIType CGDebugInfo::CreatePointeeType(QualType PointeeTy, RecordDecl *RD = RTy->getDecl(); llvm::DIDescriptor FDContext = getContextDescriptor(cast(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 >::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(VI->second)); + + llvm::DenseMap::iterator it = + TypeCache.find(VI->first); + if (it != TypeCache.end()) { + // Verify that the debug info still exists. + if (&*it->second) + RepTy = llvm::DIType(cast(it->second)); + } + + if (Ty.Verify() && RepTy.Verify()) + Ty.replaceAllUsesWith(RepTy); + } + DBuilder.finalize(); +} diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h index 1116336ca7..a071b06c26 100644 --- a/lib/CodeGen/CGDebugInfo.h +++ b/lib/CodeGen/CGDebugInfo.h @@ -56,6 +56,10 @@ class CGDebugInfo { /// CompleteTypeCache - Cache of previously constructed complete RecordTypes. llvm::DenseMap CompletedTypeCache; + /// ReplaceMap - Cache of forward declared types to RAUW at the end of + /// compilation. + std::vector >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. diff --git a/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp b/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp index 1f50256dff..e67987b5a3 100644 --- a/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp +++ b/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp @@ -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,