diff options
author | Adrian Prantl <aprantl@apple.com> | 2017-05-11 22:59:19 +0000 |
---|---|---|
committer | Adrian Prantl <aprantl@apple.com> | 2017-05-11 22:59:19 +0000 |
commit | 7c80de2a7fd93882e335d7c0fa4165d3b5e2923a (patch) | |
tree | 4eef57a5c4ece19e2838780f6b774955841bf010 /lib/CodeGen/CGDebugInfo.cpp | |
parent | 8d78bb136ceafc05a24290e440440628fda8f468 (diff) |
Module Debug Info: Emit namespaced C++ forward decls in the correct module.
The AST merges NamespaceDecls, but for module debug info it is
important to put a namespace decl (or rather its children) into the
correct (sub-)module, so we need to use the parent module of the decl
that triggered this namespace to be serialized as a second key when
looking up DINamespace nodes.
rdar://problem/29339538
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@302840 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGDebugInfo.cpp')
-rw-r--r-- | lib/CodeGen/CGDebugInfo.cpp | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 3e54346605..d15ae06b45 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -208,8 +208,10 @@ llvm::DIScope *CGDebugInfo::getContextDescriptor(const Decl *Context, } // Check namespace. - if (const auto *NSDecl = dyn_cast<NamespaceDecl>(Context)) - return getOrCreateNameSpace(NSDecl); + if (const auto *NSDecl = dyn_cast<NamespaceDecl>(Context)) { + auto *ParentModule = dyn_cast<llvm::DIModule>(Default); + return getOrCreateNamespace(NSDecl, ParentModule); + } if (const auto *RDecl = dyn_cast<RecordDecl>(Context)) if (!RDecl->isDependentType()) @@ -2861,7 +2863,7 @@ void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit, if (DebugKind >= codegenoptions::LimitedDebugInfo) { if (const NamespaceDecl *NSDecl = dyn_cast_or_null<NamespaceDecl>(FD->getDeclContext())) - FDContext = getOrCreateNameSpace(NSDecl); + FDContext = getOrCreateNamespace(NSDecl, getParentModuleOrNull(FD)); else if (const RecordDecl *RDecl = dyn_cast_or_null<RecordDecl>(FD->getDeclContext())) { llvm::DIScope *Mod = getParentModuleOrNull(RDecl); @@ -3961,7 +3963,7 @@ void CGDebugInfo::EmitUsingDirective(const UsingDirectiveDecl &UD) { CGM.getCodeGenOpts().DebugExplicitImport) { DBuilder.createImportedModule( getCurrentContextDescriptor(cast<Decl>(UD.getDeclContext())), - getOrCreateNameSpace(NSDecl), + getOrCreateNamespace(NSDecl, getParentModuleOrNull(&UD)), getLineNumber(UD.getLocation())); } } @@ -4021,23 +4023,32 @@ CGDebugInfo::EmitNamespaceAlias(const NamespaceAliasDecl &NA) { else R = DBuilder.createImportedDeclaration( getCurrentContextDescriptor(cast<Decl>(NA.getDeclContext())), - getOrCreateNameSpace(cast<NamespaceDecl>(NA.getAliasedNamespace())), + getOrCreateNamespace(cast<NamespaceDecl>(NA.getAliasedNamespace()), + getParentModuleOrNull(&NA)), getLineNumber(NA.getLocation()), NA.getName()); VH.reset(R); return R; } llvm::DINamespace * -CGDebugInfo::getOrCreateNameSpace(const NamespaceDecl *NSDecl) { +CGDebugInfo::getOrCreateNamespace(const NamespaceDecl *NSDecl, + llvm::DIModule *ParentModule) { NSDecl = NSDecl->getCanonicalDecl(); - auto I = NameSpaceCache.find(NSDecl); - if (I != NameSpaceCache.end()) + // The AST merges NamespaceDecls, but for module debug info it is important to + // put a namespace decl (or rather its children) into the correct + // (sub-)module, so use the parent module of the decl that triggered this + // namespace to be serialized as a second key. + NamespaceKey Key = {NSDecl, ParentModule}; + auto I = NamespaceCache.find(Key); + if (I != NamespaceCache.end()) return cast<llvm::DINamespace>(I->second); llvm::DIScope *Context = getDeclContextDescriptor(NSDecl); - llvm::DINamespace *NS = - DBuilder.createNameSpace(Context, NSDecl->getName(), NSDecl->isInline()); - NameSpaceCache[NSDecl].reset(NS); + // Don't trust the context if it is a DIModule (see comment above). + llvm::DINamespace *NS = DBuilder.createNameSpace( + isa<llvm::DIModule>(Context) ? ParentModule : Context, NSDecl->getName(), + NSDecl->isInline()); + NamespaceCache[Key].reset(NS); return NS; } |