summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.cpp33
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.h12
-rw-r--r--clang/test/Modules/DebugInfoNamespace.cpp19
-rw-r--r--clang/test/Modules/Inputs/DebugInfoNamespace/A.h3
-rw-r--r--clang/test/Modules/Inputs/DebugInfoNamespace/B.h3
-rw-r--r--clang/test/Modules/Inputs/DebugInfoNamespace/module.modulemap8
6 files changed, 65 insertions, 13 deletions
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 3e543466056..d15ae06b455 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/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;
}
diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h
index 5050ca0ad3f..beafd25f9b1 100644
--- a/clang/lib/CodeGen/CGDebugInfo.h
+++ b/clang/lib/CodeGen/CGDebugInfo.h
@@ -125,7 +125,8 @@ class CGDebugInfo {
/// Cache declarations relevant to DW_TAG_imported_declarations (C++
/// using declarations) that aren't covered by other more specific caches.
llvm::DenseMap<const Decl *, llvm::TrackingMDRef> DeclCache;
- llvm::DenseMap<const NamespaceDecl *, llvm::TrackingMDRef> NameSpaceCache;
+ typedef std::pair<const NamespaceDecl *, const llvm::DIModule *> NamespaceKey;
+ llvm::DenseMap<NamespaceKey, llvm::TrackingMDRef> NamespaceCache;
llvm::DenseMap<const NamespaceAliasDecl *, llvm::TrackingMDRef>
NamespaceAliasCache;
llvm::DenseMap<const Decl *, llvm::TypedTrackingMDRef<llvm::DIDerivedType>>
@@ -194,8 +195,15 @@ class CGDebugInfo {
getOrCreateFunctionType(const Decl *D, QualType FnType, llvm::DIFile *F);
/// \return debug info descriptor for vtable.
llvm::DIType *getOrCreateVTablePtrType(llvm::DIFile *F);
+
+ /// \return namespace descriptor for the given namespace decl.
+ ///
/// \return namespace descriptor for the given namespace decl.
- llvm::DINamespace *getOrCreateNameSpace(const NamespaceDecl *N);
+ /// \param ParentModule The parent module (or nullptr) of this particular
+ /// namespace decl. This needs to be passed in because
+ /// the AST merges namespace decls.
+ llvm::DINamespace *getOrCreateNamespace(const NamespaceDecl *N,
+ llvm::DIModule *ParentModule);
llvm::DIType *CreatePointerLikeType(llvm::dwarf::Tag Tag, const Type *Ty,
QualType PointeeTy, llvm::DIFile *F);
llvm::DIType *getOrCreateStructPtrType(StringRef Name, llvm::DIType *&Cache);
diff --git a/clang/test/Modules/DebugInfoNamespace.cpp b/clang/test/Modules/DebugInfoNamespace.cpp
new file mode 100644
index 00000000000..33add085d8a
--- /dev/null
+++ b/clang/test/Modules/DebugInfoNamespace.cpp
@@ -0,0 +1,19 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -x objective-c++ -std=c++11 -debug-info-kind=standalone \
+// RUN: -dwarf-ext-refs -fmodules \
+// RUN: -fmodule-format=obj -fimplicit-module-maps \
+// RUN: -triple %itanium_abi_triple -fmodules-cache-path=%t \
+// RUN: %s -I %S/Inputs/DebugInfoNamespace -I %t -emit-llvm -o - \
+// RUN: | FileCheck %s
+
+#include "A.h"
+#include "B.h"
+using namespace N;
+B b;
+
+// Verify that the forward decl of B is in module B.
+//
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "B",
+// CHECK-SAME: scope: ![[N:[0-9]+]]
+// CHECK: ![[N]] = !DINamespace(name: "N", scope: ![[B:[0-9]+]])
+// CHECK: ![[B]] = !DIModule(scope: null, name: "B",
diff --git a/clang/test/Modules/Inputs/DebugInfoNamespace/A.h b/clang/test/Modules/Inputs/DebugInfoNamespace/A.h
new file mode 100644
index 00000000000..dc5a1cd26ab
--- /dev/null
+++ b/clang/test/Modules/Inputs/DebugInfoNamespace/A.h
@@ -0,0 +1,3 @@
+namespace N {
+ struct A {};
+}
diff --git a/clang/test/Modules/Inputs/DebugInfoNamespace/B.h b/clang/test/Modules/Inputs/DebugInfoNamespace/B.h
new file mode 100644
index 00000000000..c9033a54d4e
--- /dev/null
+++ b/clang/test/Modules/Inputs/DebugInfoNamespace/B.h
@@ -0,0 +1,3 @@
+namespace N {
+ struct B {};
+}
diff --git a/clang/test/Modules/Inputs/DebugInfoNamespace/module.modulemap b/clang/test/Modules/Inputs/DebugInfoNamespace/module.modulemap
new file mode 100644
index 00000000000..9300fcf98c6
--- /dev/null
+++ b/clang/test/Modules/Inputs/DebugInfoNamespace/module.modulemap
@@ -0,0 +1,8 @@
+module A {
+ header "A.h"
+ export *
+}
+module B {
+ header "B.h"
+ export *
+}
OpenPOWER on IntegriCloud