This revision was automatically updated to reflect the committed changes. Closed by commit rG6cdfa2957437: [lldb][ClangExpression] Filter out non-root namespaces in FindNamespace (authored by Michael137).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D147436/new/ https://reviews.llvm.org/D147436 Files: lldb/include/lldb/Symbol/SymbolFile.h lldb/include/lldb/Symbol/SymbolFileOnDemand.h lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h lldb/source/Symbol/SymbolFileOnDemand.cpp lldb/test/API/lang/cpp/namespace/TestNamespace.py lldb/test/API/lang/cpp/namespace/main.cpp
Index: lldb/test/API/lang/cpp/namespace/main.cpp =================================================================== --- lldb/test/API/lang/cpp/namespace/main.cpp +++ lldb/test/API/lang/cpp/namespace/main.cpp @@ -102,6 +102,31 @@ return myfunc2(3) + j + i + a + 2 + anon_uint + a_uint + b_uint + y_uint; // Set break point at this line. } +namespace B { +struct Bar { + int x() { return 42; } +}; +Bar bar; +} // namespace B + +namespace A::B { +struct Bar { + int y() { return 137; } +}; +} // namespace A::B + +namespace NS1::NS2 { +struct Foo { + int bar() { return -2; } +}; +} // namespace NS1::NS2 + +namespace NS2 { +struct Foo { + int bar() { return -3; } +}; +} // namespace NS2 + int main (int argc, char const *argv[]) { @@ -112,5 +137,8 @@ A::B::test_lookup_at_nested_ns_scope_after_using(); test_lookup_before_using_directive(); test_lookup_after_using_directive(); - return Foo::myfunc(12); + ::B::Bar bb; + A::B::Bar ab; + return Foo::myfunc(12) + bb.x() + ab.y() + NS1::NS2::Foo{}.bar() + + NS2::Foo{}.bar(); } Index: lldb/test/API/lang/cpp/namespace/TestNamespace.py =================================================================== --- lldb/test/API/lang/cpp/namespace/TestNamespace.py +++ lldb/test/API/lang/cpp/namespace/TestNamespace.py @@ -225,3 +225,11 @@ self.expect("expression variadic_sum", patterns=[ '\(anonymous namespace\)::variadic_sum\(int, ...\)']) + + self.expect_expr("::B::Bar b; b.x()", result_type="int", result_value="42") + self.expect_expr("A::B::Bar b; b.y()", result_type="int", result_value="137") + self.expect_expr("::NS1::NS2::Foo{}.bar() == -2 && ::NS2::Foo{}.bar() == -3", + result_type="bool", result_value="true") + # FIXME: C++ unqualified namespace lookups currently not supported when instantiating types. + self.expect_expr("NS2::Foo{}.bar() == -3", result_type="bool", result_value="false") + self.expect_expr("((::B::Bar*)&::B::bar)->x()", result_type="int", result_value="42") Index: lldb/source/Symbol/SymbolFileOnDemand.cpp =================================================================== --- lldb/source/Symbol/SymbolFileOnDemand.cpp +++ lldb/source/Symbol/SymbolFileOnDemand.cpp @@ -483,13 +483,16 @@ CompilerDeclContext SymbolFileOnDemand::FindNamespace(ConstString name, - const CompilerDeclContext &parent_decl_ctx) { + const CompilerDeclContext &parent_decl_ctx, + bool only_root_namespaces) { if (!m_debug_info_enabled) { LLDB_LOG(GetLog(), "[{0}] {1}({2}) is skipped", GetSymbolFileName(), __FUNCTION__, name); - return SymbolFile::FindNamespace(name, parent_decl_ctx); + return SymbolFile::FindNamespace(name, parent_decl_ctx, + only_root_namespaces); } - return m_sym_file_impl->FindNamespace(name, parent_decl_ctx); + return m_sym_file_impl->FindNamespace(name, parent_decl_ctx, + only_root_namespaces); } std::vector<std::unique_ptr<lldb_private::CallEdge>> Index: lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h =================================================================== --- lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -157,9 +157,10 @@ llvm::Expected<lldb::TypeSystemSP> GetTypeSystemForLanguage(lldb::LanguageType language) override; - lldb_private::CompilerDeclContext FindNamespace( - lldb_private::ConstString name, - const lldb_private::CompilerDeclContext &parent_decl_ctx) override; + lldb_private::CompilerDeclContext + FindNamespace(lldb_private::ConstString name, + const lldb_private::CompilerDeclContext &parent_decl_ctx, + bool only_root_namespaces) override; llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } Index: lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -1697,7 +1697,7 @@ lldb_private::CompilerDeclContext SymbolFilePDB::FindNamespace(lldb_private::ConstString name, - const CompilerDeclContext &parent_decl_ctx) { + const CompilerDeclContext &parent_decl_ctx, bool) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); auto type_system_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); Index: lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h =================================================================== --- lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h +++ lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h @@ -152,9 +152,9 @@ llvm::Expected<lldb::TypeSystemSP> GetTypeSystemForLanguage(lldb::LanguageType language) override; - CompilerDeclContext - FindNamespace(ConstString name, - const CompilerDeclContext &parent_decl_ctx) override; + CompilerDeclContext FindNamespace(ConstString name, + const CompilerDeclContext &parent_decl_ctx, + bool only_root_namespaces) override; llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } Index: lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -2133,9 +2133,8 @@ TypeClass type_mask, lldb_private::TypeList &type_list) {} -CompilerDeclContext -SymbolFileNativePDB::FindNamespace(ConstString name, - const CompilerDeclContext &parent_decl_ctx) { +CompilerDeclContext SymbolFileNativePDB::FindNamespace( + ConstString name, const CompilerDeclContext &parent_decl_ctx, bool) { return {}; } Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -136,9 +136,10 @@ lldb_private::LanguageSet languages, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, lldb_private::TypeMap &types) override; - lldb_private::CompilerDeclContext FindNamespace( - lldb_private::ConstString name, - const lldb_private::CompilerDeclContext &parent_decl_ctx) override; + lldb_private::CompilerDeclContext + FindNamespace(lldb_private::ConstString name, + const lldb_private::CompilerDeclContext &parent_decl_ctx, + bool only_root_namespaces) override; void GetTypes(lldb_private::SymbolContextScope *sc_scope, lldb::TypeClass type_mask, lldb_private::TypeList &type_list) override; Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -1256,13 +1256,14 @@ } CompilerDeclContext SymbolFileDWARFDebugMap::FindNamespace( - lldb_private::ConstString name, - const CompilerDeclContext &parent_decl_ctx) { + lldb_private::ConstString name, const CompilerDeclContext &parent_decl_ctx, + bool only_root_namespaces) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); CompilerDeclContext matching_namespace; ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { - matching_namespace = oso_dwarf->FindNamespace(name, parent_decl_ctx); + matching_namespace = + oso_dwarf->FindNamespace(name, parent_decl_ctx, only_root_namespaces); return (bool)matching_namespace; }); Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -214,9 +214,10 @@ llvm::Expected<lldb::TypeSystemSP> GetTypeSystemForLanguage(lldb::LanguageType language) override; - lldb_private::CompilerDeclContext FindNamespace( - lldb_private::ConstString name, - const lldb_private::CompilerDeclContext &parent_decl_ctx) override; + lldb_private::CompilerDeclContext + FindNamespace(lldb_private::ConstString name, + const lldb_private::CompilerDeclContext &parent_decl_ctx, + bool only_root_namespaces) override; void PreloadSymbols() override; @@ -274,7 +275,7 @@ static bool DIEInDeclContext(const lldb_private::CompilerDeclContext &parent_decl_ctx, - const DWARFDIE &die); + const DWARFDIE &die, bool only_root_namespaces = false); std::vector<std::unique_ptr<lldb_private::CallEdge>> ParseCallEdgesInFunction(lldb_private::UserID func_id) override; Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -2324,12 +2324,19 @@ } bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext &decl_ctx, - const DWARFDIE &die) { + const DWARFDIE &die, + bool only_root_namespaces) { // If we have no parent decl context to match this DIE matches, and if the // parent decl context isn't valid, we aren't trying to look for any // particular decl context so any die matches. - if (!decl_ctx.IsValid()) + if (!decl_ctx.IsValid()) { + // ...But if we are only checking root decl contexts, confirm that the + // 'die' is a top-level context. + if (only_root_namespaces) + return die.GetParent().Tag() == dwarf::DW_TAG_compile_unit; + return true; + } if (die) { if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU())) { @@ -2632,7 +2639,8 @@ CompilerDeclContext SymbolFileDWARF::FindNamespace(ConstString name, - const CompilerDeclContext &parent_decl_ctx) { + const CompilerDeclContext &parent_decl_ctx, + bool only_root_namespaces) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); Log *log = GetLog(DWARFLog::Lookups); @@ -2648,7 +2656,7 @@ return namespace_decl_ctx; m_index->GetNamespaces(name, [&](DWARFDIE die) { - if (!DIEInDeclContext(parent_decl_ctx, die)) + if (!DIEInDeclContext(parent_decl_ctx, die, only_root_namespaces)) return true; // The containing decl contexts don't match DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU()); Index: lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h =================================================================== --- lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h +++ lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h @@ -134,9 +134,9 @@ llvm::inconvertibleErrorCode()); } - CompilerDeclContext - FindNamespace(ConstString name, - const CompilerDeclContext &parent_decl_ctx) override { + CompilerDeclContext FindNamespace(ConstString name, + const CompilerDeclContext &parent_decl_ctx, + bool only_root_namespaces) override { return CompilerDeclContext(); } Index: lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp =================================================================== --- lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp +++ lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp @@ -700,7 +700,18 @@ if (!symbol_file) continue; - found_namespace_decl = symbol_file->FindNamespace(name, namespace_decl); + // If namespace_decl is not valid, 'FindNamespace' would look for + // any namespace called 'name' (ignoring parent contexts) and return + // the first one it finds. Thus if we're doing a qualified lookup only + // consider root namespaces. E.g., in an expression ::A::B::Foo, the + // lookup of ::A will result in a qualified lookup. Note, namespace + // disambiguation for function calls are handled separately in + // SearchFunctionsInSymbolContexts. + const bool find_root_namespaces = + context.m_decl_context && + context.m_decl_context->shouldUseQualifiedLookup(); + found_namespace_decl = symbol_file->FindNamespace( + name, namespace_decl, /* only root namespaces */ find_root_namespaces); if (found_namespace_decl) { context.m_namespace_map->push_back( Index: lldb/include/lldb/Symbol/SymbolFileOnDemand.h =================================================================== --- lldb/include/lldb/Symbol/SymbolFileOnDemand.h +++ lldb/include/lldb/Symbol/SymbolFileOnDemand.h @@ -171,9 +171,10 @@ llvm::Expected<lldb::TypeSystemSP> GetTypeSystemForLanguage(lldb::LanguageType language) override; - lldb_private::CompilerDeclContext FindNamespace( - lldb_private::ConstString name, - const lldb_private::CompilerDeclContext &parent_decl_ctx) override; + lldb_private::CompilerDeclContext + FindNamespace(lldb_private::ConstString name, + const lldb_private::CompilerDeclContext &parent_decl_ctx, + bool only_root_namespaces) override; std::vector<std::unique_ptr<lldb_private::CallEdge>> ParseCallEdgesInFunction(UserID func_id) override; Index: lldb/include/lldb/Symbol/SymbolFile.h =================================================================== --- lldb/include/lldb/Symbol/SymbolFile.h +++ lldb/include/lldb/Symbol/SymbolFile.h @@ -327,8 +327,17 @@ virtual llvm::Expected<lldb::TypeSystemSP> GetTypeSystemForLanguage(lldb::LanguageType language) = 0; + /// Finds a namespace of name \ref name and whose parent + /// context is \ref parent_decl_ctx. + /// + /// If \code{.cpp} !parent_decl_ctx.IsValid() \endcode + /// then this function will consider all namespaces that + /// match the name. If \ref only_root_namespaces is + /// true, only consider in the search those DIEs that + /// represent top-level namespaces. virtual CompilerDeclContext - FindNamespace(ConstString name, const CompilerDeclContext &parent_decl_ctx) { + FindNamespace(ConstString name, const CompilerDeclContext &parent_decl_ctx, + bool only_root_namespaces = false) { return CompilerDeclContext(); }
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits