From fc46ebc2b1345723a894ae352cfb206c1d930295 Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Mon, 20 May 2013 22:50:41 +0000 Subject: [PATCH] PR14606: Debug Info for namespace aliases/DW_TAG_imported_module This resolves the last of the PR14606 failures in the GDB 7.5 test suite. (but there are still unresolved issues in the imported_decl case - we need to implement optional/lazy decls for functions & variables like we already do for types) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@182329 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGDebugInfo.cpp | 24 ++++++++++++++++++++ lib/CodeGen/CGDebugInfo.h | 4 ++++ lib/CodeGen/CGDecl.cpp | 5 ++++- lib/CodeGen/CodeGenModule.cpp | 5 ++++- test/CodeGenCXX/debug-info-namespace.cpp | 28 ++++++++++++++---------- 5 files changed, 53 insertions(+), 13 deletions(-) diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index a8ab1c1c6b..eff9d2284f 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -3084,6 +3084,30 @@ void CGDebugInfo::EmitUsingDecl(const UsingDecl &UD) { getLineNumber(USD.getLocation())); } +llvm::DIImportedEntity +CGDebugInfo::EmitNamespaceAlias(const NamespaceAliasDecl &NA) { + if (CGM.getCodeGenOpts().getDebugInfo() < CodeGenOptions::LimitedDebugInfo) + return llvm::DIImportedEntity(0); + llvm::WeakVH &VH = NamespaceAliasCache[&NA]; + if (VH) + return llvm::DIImportedEntity(cast(VH)); + llvm::DIImportedEntity R(0); + if (const NamespaceAliasDecl *Underlying = + dyn_cast(NA.getAliasedNamespace())) + // This could cache & dedup here rather than relying on metadata deduping. + R = DBuilder.createImportedModule( + getCurrentContextDescriptor(cast(NA.getDeclContext())), + EmitNamespaceAlias(*Underlying), getLineNumber(NA.getLocation()), + NA.getName()); + else + R = DBuilder.createImportedModule( + getCurrentContextDescriptor(cast(NA.getDeclContext())), + getOrCreateNameSpace(cast(NA.getAliasedNamespace())), + getLineNumber(NA.getLocation()), NA.getName()); + VH = R; + return R; +} + /// getOrCreateNamesSpace - Return namespace descriptor for the given /// namespace decl. llvm::DINameSpace diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h index f19f750e60..cca6e1ba31 100644 --- a/lib/CodeGen/CGDebugInfo.h +++ b/lib/CodeGen/CGDebugInfo.h @@ -101,6 +101,7 @@ class CGDebugInfo { /// using declarations) that aren't covered by other more specific caches. llvm::DenseMap DeclCache; llvm::DenseMap NameSpaceCache; + llvm::DenseMap NamespaceAliasCache; llvm::DenseMap StaticDataMemberCache; /// Helper functions for getOrCreateType. @@ -277,6 +278,9 @@ public: /// \brief - Emit C++ using declaration. void EmitUsingDecl(const UsingDecl &UD); + /// \brief - Emit C++ namespace alias. + llvm::DIImportedEntity EmitNamespaceAlias(const NamespaceAliasDecl &NA); + /// getOrCreateRecordType - Emit record type's standalone debug info. llvm::DIType getOrCreateRecordType(QualType Ty, SourceLocation L); diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index ce7a13d456..9741f5878e 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -79,7 +79,6 @@ void CodeGenFunction::EmitDecl(const Decl &D) { case Decl::Enum: // enum X; case Decl::EnumConstant: // enum ? { X = ? } case Decl::CXXRecord: // struct/union/class X; [C++] - case Decl::NamespaceAlias: case Decl::StaticAssert: // static_assert(X, ""); [C++0x] case Decl::Label: // __label__ x; case Decl::Import: @@ -88,6 +87,10 @@ void CodeGenFunction::EmitDecl(const Decl &D) { // None of these decls require codegen support. return; + case Decl::NamespaceAlias: + if (CGDebugInfo *DI = getDebugInfo()) + DI->EmitNamespaceAlias(cast(D)); + return; case Decl::Using: // using X; [C++] if (CGDebugInfo *DI = getDebugInfo()) DI->EmitUsingDecl(cast(D)); diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 3a967c6fdc..e65128813e 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -2879,10 +2879,13 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { case Decl::ClassTemplate: case Decl::FunctionTemplate: case Decl::TypeAliasTemplate: - case Decl::NamespaceAlias: case Decl::Block: case Decl::Empty: break; + case Decl::NamespaceAlias: + if (CGDebugInfo *DI = getModuleDebugInfo()) + DI->EmitNamespaceAlias(cast(*D)); + return; case Decl::UsingDirective: // using namespace X; [C++] if (CGDebugInfo *DI = getModuleDebugInfo()) DI->EmitUsingDirective(cast(*D)); diff --git a/test/CodeGenCXX/debug-info-namespace.cpp b/test/CodeGenCXX/debug-info-namespace.cpp index 0f4e73cbe3..aa739ab933 100644 --- a/test/CodeGenCXX/debug-info-namespace.cpp +++ b/test/CodeGenCXX/debug-info-namespace.cpp @@ -16,6 +16,7 @@ using namespace B; } using namespace A; +namespace E = A; int func(bool b) { if (b) { @@ -28,7 +29,9 @@ int func(bool b) { using B::f1; using B::i; using B::baz; - return i; + namespace X = A; + namespace Y = X; + return i + X::B::i + Y::B::i; } // This should work even if 'i' and 'func' were declarations & not definitions, @@ -40,23 +43,26 @@ int func(bool b) { // CHECK: [[NS:![0-9]*]] = {{.*}}, metadata [[FILE2:![0-9]*]], metadata [[CTXT:![0-9]*]], {{.*}} ; [ DW_TAG_namespace ] [B] [line 1] // CHECK: [[CTXT]] = {{.*}}, metadata [[FILE]], null, {{.*}} ; [ DW_TAG_namespace ] [A] [line 5] // CHECK: [[F1:![0-9]*]] {{.*}} ; [ DW_TAG_subprogram ] [line 4] [def] [f1] -// CHECK: [[FUNC:![0-9]*]] {{.*}} ; [ DW_TAG_subprogram ] [line 14] [def] [func] +// CHECK: [[FUNC:![0-9]*]] {{.*}} ; [ DW_TAG_subprogram ] [line 15] [def] [func] // CHECK: [[FILE2]]} ; [ DW_TAG_file_type ] [{{.*}}foo.cpp] // CHECK: [[I:![0-9]*]] = {{.*}}, metadata [[NS]], metadata !"i", {{.*}} ; [ DW_TAG_variable ] [i] -// CHECK: [[MODULES]] = metadata !{metadata [[M1:![0-9]*]], metadata [[M2:![0-9]*]], metadata [[M3:![0-9]*]], metadata [[M4:![0-9]*]], metadata [[M5:![0-9]*]], metadata [[M6:![0-9]*]], metadata [[M7:![0-9]*]], metadata [[M8:![0-9]*]], metadata [[M9:![0-9]*]]} +// CHECK: [[MODULES]] = metadata !{metadata [[M1:![0-9]*]], metadata [[M2:![0-9]*]], metadata [[M3:![0-9]*]], metadata [[M4:![0-9]*]], metadata [[M5:![0-9]*]], metadata [[M6:![0-9]*]], metadata [[M7:![0-9]*]], metadata [[M8:![0-9]*]], metadata [[M9:![0-9]*]], metadata [[M10:![0-9]*]], metadata [[M11:![0-9]*]], metadata [[M12:![0-9]*]]} // CHECK: [[M1]] = metadata !{i32 {{[0-9]*}}, metadata [[CTXT]], metadata [[NS]], i32 9} ; [ DW_TAG_imported_module ] // CHECK: [[M2]] = metadata !{i32 {{[0-9]*}}, metadata [[CU]], metadata [[CTXT]], i32 12} ; [ DW_TAG_imported_module ] -// CHECK: [[M3]] = metadata !{i32 {{[0-9]*}}, metadata [[LEX:![0-9]*]], metadata [[NS]], i32 16} ; [ DW_TAG_imported_module ] -// CHECK: [[LEX]] = metadata !{i32 {{[0-9]*}}, metadata [[FILE2]], metadata [[FUNC]], i32 15, i32 0, i32 0} ; [ DW_TAG_lexical_block ] -// CHECK: [[M4]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata [[CTXT]], i32 19} ; [ DW_TAG_imported_module ] -// CHECK: [[M5]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata [[FOO:![0-9]*]], i32 20} ; [ DW_TAG_imported_declaration ] +// CHECK: [[M3]] = metadata !{i32 {{[0-9]*}}, metadata [[CU]], metadata [[CTXT]], i32 13, metadata !"E"} ; [ DW_TAG_imported_module ] +// CHECK: [[M4]] = metadata !{i32 {{[0-9]*}}, metadata [[LEX:![0-9]*]], metadata [[NS]], i32 17} ; [ DW_TAG_imported_module ] +// CHECK: [[LEX]] = metadata !{i32 {{[0-9]*}}, metadata [[FILE2]], metadata [[FUNC]], i32 16, i32 0, i32 0} ; [ DW_TAG_lexical_block ] +// CHECK: [[M5]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata [[CTXT]], i32 20} ; [ DW_TAG_imported_module ] +// CHECK: [[M6]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata [[FOO:![0-9]*]], i32 21} ; [ DW_TAG_imported_declaration ] // CHECK: [[FOO]] {{.*}} ; [ DW_TAG_structure_type ] [foo] [line 5, size 0, align 0, offset 0] [fwd] [from ] -// CHECK: [[M6]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata [[BAR:![0-9]*]], i32 21} ; [ DW_TAG_imported_declaration ] +// CHECK: [[M7]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata [[BAR:![0-9]*]], i32 22} ; [ DW_TAG_imported_declaration ] // CHECK: [[BAR]] {{.*}} ; [ DW_TAG_structure_type ] [bar] [line 6, {{.*}}] [fwd] [from ] -// CHECK: [[M7]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata [[F1]], i32 22} ; [ DW_TAG_imported_declaration ] -// CHECK: [[M8]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata [[I]], i32 23} ; [ DW_TAG_imported_declaration ] -// CHECK: [[M9]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata [[BAZ:![0-9]*]], i32 24} ; [ DW_TAG_imported_declaration ] +// CHECK: [[M8]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata [[F1]], i32 23} ; [ DW_TAG_imported_declaration ] +// CHECK: [[M9]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata [[I]], i32 24} ; [ DW_TAG_imported_declaration ] +// CHECK: [[M10]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata [[BAZ:![0-9]*]], i32 25} ; [ DW_TAG_imported_declaration ] // CHECK: [[BAZ]] = metadata !{i32 {{[0-9]*}}, metadata [[FOOCPP]], metadata [[NS]], {{.*}} ; [ DW_TAG_typedef ] [baz] {{.*}} [from bar] +// CHECK: [[M11]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata [[CTXT]], i32 26, metadata !"X"} ; [ DW_TAG_imported_module ] +// CHECK: [[M12]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata [[M11]], i32 27, metadata !"Y"} ; [ DW_TAG_imported_module ] // CHECK-GMLT: [[CU:![0-9]*]] = {{.*}}[[MODULES:![0-9]*]], metadata !""} ; [ DW_TAG_compile_unit ] // CHECK-GMLT: [[MODULES]] = metadata !{i32 0} -- 2.40.0