diff options
author | Eric Christopher <echristo@apple.com> | 2012-01-20 22:10:15 +0000 |
---|---|---|
committer | Eric Christopher <echristo@apple.com> | 2012-01-20 22:10:15 +0000 |
commit | 4ddca8ab795be2bb239a80b48a57d09f54dc07ba (patch) | |
tree | 6ef54ab705ad02ff6043bf726f085dc90a31fcfe /lib/CodeGen/CGDebugInfo.cpp | |
parent | 3575c456e969d71623fe83e19ea499285cdb3567 (diff) |
When adding types to the context chain for record types, just emit
a forward declaration unless we already have a type. We can fill it in
later if it's actually used.
Fixes PR11345
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148584 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGDebugInfo.cpp')
-rw-r--r-- | lib/CodeGen/CGDebugInfo.cpp | 57 |
1 files changed, 54 insertions, 3 deletions
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 3d0e8cc29b..332fa8e1b8 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -479,6 +479,53 @@ llvm::DIType CGDebugInfo::CreateType(const PointerType *Ty, Ty->getPointeeType(), Unit); } +// Walk up the context chain and create forward decls for record decls, +// and normal descriptors for namespaces. +llvm::DIDescriptor CGDebugInfo::createContextChain(const Decl *Context) { + if (!Context) + return TheCU; + + // See if we already have the parent. + llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator + I = RegionMap.find(Context); + if (I != RegionMap.end()) + return llvm::DIDescriptor(dyn_cast_or_null<llvm::MDNode>(&*I->second)); + + // Check namespace. + if (const NamespaceDecl *NSDecl = dyn_cast<NamespaceDecl>(Context)) + return llvm::DIDescriptor(getOrCreateNameSpace(NSDecl)); + + if (const RecordDecl *RD = dyn_cast<RecordDecl>(Context)) { + if (!RD->isDependentType()) { + llvm::DIFile DefUnit = getOrCreateFile(RD->getLocation()); + unsigned Line = getLineNumber(RD->getLocation()); + llvm::DIDescriptor FDContext = + createContextChain(cast<Decl>(RD->getDeclContext())); + + const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD); + llvm::DIType Ty = llvm::DIType(); + + if (CXXDecl) + Ty = DBuilder.createClassType(FDContext, RD->getName(), DefUnit, + Line, 0, 0, 0, + llvm::DIType::FlagFwdDecl, + llvm::DIType(), llvm::DIArray()); + else if (RD->isStruct()) + Ty = DBuilder.createStructType(FDContext, RD->getName(), DefUnit, + Line, 0, 0, llvm::DIType::FlagFwdDecl, + llvm::DIArray()); + else if (RD->isUnion()) + Ty = DBuilder.createUnionType(FDContext, RD->getName(), DefUnit, + Line, 0, 0, llvm::DIType::FlagFwdDecl, + llvm::DIArray()); + + RegionMap[Context] = llvm::WeakVH(Ty); + return llvm::DIDescriptor(Ty); + } + } + return TheCU; +} + /// CreatePointeeType - Create Pointee type. If Pointee is a record /// then emit record's fwd if debug info size reduction is enabled. llvm::DIType CGDebugInfo::CreatePointeeType(QualType PointeeTy, @@ -1073,8 +1120,12 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty) { // its members. Finally, we create a descriptor for the complete type (which // may refer to the forward decl if the struct is recursive) and replace all // uses of the forward declaration with the final definition. - llvm::DIDescriptor FDContext = - getContextDescriptor(cast<Decl>(RD->getDeclContext())); + + llvm::DIDescriptor FDContext; + if (CGM.getCodeGenOpts().LimitDebugInfo) + FDContext = createContextChain(cast<Decl>(RD->getDeclContext())); + else + FDContext = getContextDescriptor(cast<Decl>(RD->getDeclContext())); // If this is just a forward declaration, construct an appropriately // marked node and just return it. @@ -1193,7 +1244,7 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty) { // Now that we have a real decl for the struct, replace anything using the // old decl with the new one. This will recursively update the debug info. llvm::DIType(FwdDeclNode).replaceAllUsesWith(RealDecl); - RegionMap[RD] = llvm::WeakVH(RealDecl); + RegionMap[Ty->getDecl()] = llvm::WeakVH(RealDecl); return llvm::DIType(RealDecl); } |