Skip to content

Commit 34096e4

Browse files
authored
Merge pull request #6320 from Michael137/bugfix/lldb-imported-namespaces-to-20221013
2 parents e849d3c + de77ee5 commit 34096e4

15 files changed

+247
-1
lines changed

lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3266,6 +3266,11 @@ DWARFASTParserClang::GetClangDeclContextForDIE(const DWARFDIE &die) {
32663266
try_parsing_type = false;
32673267
break;
32683268

3269+
case DW_TAG_imported_declaration:
3270+
decl_ctx = ResolveImportedDeclarationDIE(die);
3271+
try_parsing_type = false;
3272+
break;
3273+
32693274
case DW_TAG_lexical_block:
32703275
decl_ctx = GetDeclContextForBlock(die);
32713276
try_parsing_type = false;
@@ -3428,6 +3433,42 @@ DWARFASTParserClang::ResolveNamespaceDIE(const DWARFDIE &die) {
34283433
return nullptr;
34293434
}
34303435

3436+
clang::NamespaceDecl *
3437+
DWARFASTParserClang::ResolveImportedDeclarationDIE(const DWARFDIE &die) {
3438+
assert(die && die.Tag() == DW_TAG_imported_declaration);
3439+
3440+
// See if we cached a NamespaceDecl for this imported declaration
3441+
// already
3442+
auto it = m_die_to_decl_ctx.find(die.GetDIE());
3443+
if (it != m_die_to_decl_ctx.end())
3444+
return static_cast<clang::NamespaceDecl *>(it->getSecond());
3445+
3446+
clang::NamespaceDecl *namespace_decl = nullptr;
3447+
3448+
const DWARFDIE imported_uid =
3449+
die.GetAttributeValueAsReferenceDIE(DW_AT_import);
3450+
if (!imported_uid)
3451+
return nullptr;
3452+
3453+
switch (imported_uid.Tag()) {
3454+
case DW_TAG_imported_declaration:
3455+
namespace_decl = ResolveImportedDeclarationDIE(imported_uid);
3456+
break;
3457+
case DW_TAG_namespace:
3458+
namespace_decl = ResolveNamespaceDIE(imported_uid);
3459+
break;
3460+
default:
3461+
return nullptr;
3462+
}
3463+
3464+
if (!namespace_decl)
3465+
return nullptr;
3466+
3467+
LinkDeclContextToDIE(namespace_decl, die);
3468+
3469+
return namespace_decl;
3470+
}
3471+
34313472
clang::DeclContext *DWARFASTParserClang::GetClangDeclContextContainingDIE(
34323473
const DWARFDIE &die, DWARFDIE *decl_ctx_die_copy) {
34333474
SymbolFileDWARF *dwarf = die.GetDWARF();

lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,17 @@ class DWARFASTParserClang : public DWARFASTParser {
118118

119119
clang::NamespaceDecl *ResolveNamespaceDIE(const DWARFDIE &die);
120120

121+
/// Returns the namespace decl that a DW_TAG_imported_declaration imports.
122+
///
123+
/// \param[in] die The import declaration to resolve. If the DIE is not a
124+
/// DW_TAG_imported_declaration the behaviour is undefined.
125+
///
126+
/// \returns The decl corresponding to the namespace that the specified
127+
/// 'die' imports. If the imported entity is not a namespace
128+
/// or another import declaration, returns nullptr. If an error
129+
/// occurs, returns nullptr.
130+
clang::NamespaceDecl *ResolveImportedDeclarationDIE(const DWARFDIE &die);
131+
121132
bool ParseTemplateDIE(const DWARFDIE &die,
122133
lldb_private::TypeSystemClang::TemplateParameterInfos
123134
&template_param_infos);

lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit,
207207
case DW_TAG_enumeration_type:
208208
case DW_TAG_inlined_subroutine:
209209
case DW_TAG_namespace:
210+
case DW_TAG_imported_declaration:
210211
case DW_TAG_string_type:
211212
case DW_TAG_structure_type:
212213
case DW_TAG_subprogram:
@@ -353,6 +354,7 @@ void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit,
353354
break;
354355

355356
case DW_TAG_namespace:
357+
case DW_TAG_imported_declaration:
356358
if (name)
357359
set.namespaces.Insert(ConstString(name), ref);
358360
break;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
CXX_SOURCES := main.cpp
2+
3+
include Makefile.rules
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
"""
2+
Test that we correctly handle namespace
3+
expression evaluation through namespace
4+
aliases.
5+
"""
6+
7+
import lldb
8+
9+
from lldbsuite.test.decorators import *
10+
from lldbsuite.test.lldbtest import *
11+
from lldbsuite.test import lldbutil
12+
13+
class TestInlineNamespace(TestBase):
14+
def do_test(self, params):
15+
self.build()
16+
17+
lldbutil.run_to_source_breakpoint(self,
18+
"return A::B::C::a", lldb.SBFileSpec("main.cpp"))
19+
20+
self.expect_expr("A::C::a", result_type="int", result_value="-1")
21+
self.expect_expr("A::D::a", result_type="int", result_value="-1")
22+
23+
self.expect_expr("A::C::func()", result_type="int", result_value="0")
24+
self.expect_expr("A::D::func()", result_type="int", result_value="0")
25+
26+
self.expect_expr("E::C::a", result_type="int", result_value="-1")
27+
self.expect_expr("E::D::a", result_type="int", result_value="-1")
28+
self.expect_expr("F::a", result_type="int", result_value="-1")
29+
self.expect_expr("G::a", result_type="int", result_value="-1")
30+
31+
@skipIf(debug_info=no_match(["dsym"]))
32+
def test_dsym(self):
33+
self.do_test({})
34+
35+
@skipIf(debug_info="dsym")
36+
def test_dwarf(self):
37+
self.do_test(dict(CFLAGS_EXTRAS="-gdwarf-5 -gpubnames"))
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
namespace A {
2+
inline namespace _A {
3+
namespace B {
4+
namespace C {
5+
int a = -1;
6+
7+
int func() { return 0; }
8+
} // namespace C
9+
} // namespace B
10+
11+
namespace C = B::C;
12+
namespace D = B::C;
13+
14+
} // namespace _A
15+
} // namespace A
16+
17+
namespace E = A;
18+
namespace F = E::C;
19+
namespace G = F;
20+
21+
int main(int argc, char **argv) { return A::B::C::a; }

llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1289,9 +1289,17 @@ DIE *DwarfCompileUnit::constructImportedEntityDIE(
12891289
addSourceLine(*IMDie, Module->getLine(), Module->getFile());
12901290
addDIEEntry(*IMDie, dwarf::DW_AT_import, *EntityDie);
12911291
StringRef Name = Module->getName();
1292-
if (!Name.empty())
1292+
if (!Name.empty()) {
12931293
addString(*IMDie, dwarf::DW_AT_name, Name);
12941294

1295+
// FIXME: if consumers ever start caring about handling
1296+
// unnamed import declarations such as `using ::nullptr_t`
1297+
// or `using namespace std::ranges`, we could add the
1298+
// import declaration into the accelerator table with the
1299+
// name being the one of the entity being imported.
1300+
DD->addAccelNamespace(*CUNode, Name, *IMDie);
1301+
}
1302+
12951303
// This is for imported module with renamed entities (such as variables and
12961304
// subprograms).
12971305
DINodeArray Elements = Module->getElements();

llvm/lib/DWARFLinker/DWARFLinker.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1568,6 +1568,8 @@ DIE *DWARFLinker::DIECloner::cloneDIE(const DWARFDie &InputDIE,
15681568
if (!AttrInfo.Name)
15691569
AttrInfo.Name = StringPool.getEntry("(anonymous namespace)");
15701570
Unit.addNamespaceAccelerator(Die, AttrInfo.Name);
1571+
} else if (Tag == dwarf::DW_TAG_imported_declaration && AttrInfo.Name) {
1572+
Unit.addNamespaceAccelerator(Die, AttrInfo.Name);
15711573
} else if (isTypeTag(Tag) && !AttrInfo.IsDeclaration &&
15721574
getDIENames(InputDIE, AttrInfo, StringPool) && AttrInfo.Name &&
15731575
AttrInfo.Name.getString()[0]) {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Compiled on MacOS using:
2+
// clang++ -c -std=c++2a -gdwarf-4 -O0 -o accel-imported-declaration.macho-arm64.o
3+
4+
namespace A {
5+
namespace B {
6+
namespace C {
7+
int a = -1;
8+
} // namespace C
9+
} // namespace B
10+
11+
namespace C = B::C;
12+
13+
using namespace B::C;
14+
using B::C::a;
15+
} // namespace A
Binary file not shown.

0 commit comments

Comments
 (0)