Michael137 created this revision. Michael137 added reviewers: aprantl, labath. Herald added a reviewer: shafik. Herald added a project: All. Michael137 requested review of this revision. Herald added a project: LLDB. Herald added a subscriber: lldb-commits.
**Summary** This patch makes the expression evaluator understand namespace aliases. This will become important once `std::ranges` become more widespread since `std::views` is defined as: namespace std { namespace ranges::views {} namespace views = ranges::views; } **Testing** - Added API test Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D143398 Files: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h lldb/test/API/commands/expression/namespace-alias/Makefile lldb/test/API/commands/expression/namespace-alias/TestInlineNamespaceAlias.py lldb/test/API/commands/expression/namespace-alias/main.cpp
Index: lldb/test/API/commands/expression/namespace-alias/main.cpp =================================================================== --- /dev/null +++ lldb/test/API/commands/expression/namespace-alias/main.cpp @@ -0,0 +1,21 @@ +namespace A { +inline namespace _A { +namespace B { +namespace C { +int a = -1; + +int func() { return 0; } +} // namespace C +} // namespace B + +namespace C = B::C; +namespace D = B::C; + +} // namespace _A +} // namespace A + +namespace E = A; +namespace F = E::C; +namespace G = F; + +int main(int argc, char **argv) { return A::B::C::a; } Index: lldb/test/API/commands/expression/namespace-alias/TestInlineNamespaceAlias.py =================================================================== --- /dev/null +++ lldb/test/API/commands/expression/namespace-alias/TestInlineNamespaceAlias.py @@ -0,0 +1,29 @@ +""" +Test that we correctly handle namespace +expression evaluation through namespace +aliases. +""" + +import lldb + +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +class TestInlineNamespace(TestBase): + def test(self): + self.build() + + lldbutil.run_to_source_breakpoint(self, + "return A::B::C::a", lldb.SBFileSpec("main.cpp")) + + self.expect_expr("A::C::a", result_type="int", result_value="-1") + self.expect_expr("A::D::a", result_type="int", result_value="-1") + + self.expect_expr("A::C::func()", result_type="int", result_value="0") + self.expect_expr("A::D::func()", result_type="int", result_value="0") + + self.expect_expr("E::C::a", result_type="int", result_value="-1") + self.expect_expr("E::D::a", result_type="int", result_value="-1") + self.expect_expr("F::a", result_type="int", result_value="-1") + self.expect_expr("G::a", result_type="int", result_value="-1") Index: lldb/test/API/commands/expression/namespace-alias/Makefile =================================================================== --- /dev/null +++ lldb/test/API/commands/expression/namespace-alias/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h @@ -132,6 +132,17 @@ clang::NamespaceDecl *ResolveNamespaceDIE(const DWARFDIE &die); + /// Returns the namespace decl that a DW_TAG_imported_declaration imports. + /// + /// \param[in] die The import declaration to resolve. If the DIE is not a + /// DW_TAG_imported_declaration the behaviour is undefined. + /// + /// \returns The decl corresponding to the namespace that the specified + /// 'die' imports. If the imported entity is not a namespace + /// or another import declaration, returns nullptr. If an error + /// occurs, returns nullptr. + clang::NamespaceDecl *ResolveImportedDeclarationDIE(const DWARFDIE &die); + bool ParseTemplateDIE(const DWARFDIE &die, lldb_private::TypeSystemClang::TemplateParameterInfos &template_param_infos); Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -3304,6 +3304,11 @@ try_parsing_type = false; break; + case DW_TAG_imported_declaration: + decl_ctx = ResolveImportedDeclarationDIE(die); + try_parsing_type = false; + break; + case DW_TAG_lexical_block: decl_ctx = GetDeclContextForBlock(die); try_parsing_type = false; @@ -3465,6 +3470,41 @@ return nullptr; } +clang::NamespaceDecl * +DWARFASTParserClang::ResolveImportedDeclarationDIE(const DWARFDIE &die) { + assert(die && die.Tag() == DW_TAG_imported_declaration); + + // See if we cached a NamespaceDecl for this imported declaration + // already + clang::NamespaceDecl *namespace_decl = + static_cast<clang::NamespaceDecl *>(m_die_to_decl_ctx[die.GetDIE()]); + if (namespace_decl) + return namespace_decl; + + const DWARFDIE imported_uid = + die.GetAttributeValueAsReferenceDIE(DW_AT_import); + if (!imported_uid) + return nullptr; + + switch (imported_uid.Tag()) { + case DW_TAG_imported_declaration: + namespace_decl = ResolveImportedDeclarationDIE(imported_uid); + break; + case DW_TAG_namespace: + namespace_decl = ResolveNamespaceDIE(imported_uid); + break; + default: + return nullptr; + } + + if (!namespace_decl) + return nullptr; + + LinkDeclContextToDIE(namespace_decl, die); + + return namespace_decl; +} + clang::DeclContext *DWARFASTParserClang::GetClangDeclContextContainingDIE( const DWARFDIE &die, DWARFDIE *decl_ctx_die_copy) { SymbolFileDWARF *dwarf = die.GetDWARF();
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits