llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lldb Author: Adrian Prantl (adrian-prantl) <details> <summary>Changes</summary> I need this API in the Swift plugin, but it seems generally useful enough to expose it in the main branch. --- Full diff: https://github.com/llvm/llvm-project/pull/69981.diff 15 Files Affected: - (modified) lldb/include/lldb/Symbol/Function.h (+6) - (modified) lldb/include/lldb/Symbol/SymbolFile.h (+7-5) - (modified) lldb/include/lldb/Symbol/Type.h (+1-1) - (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp (+4-5) - (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp (+17-15) - (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h (+1-1) - (modified) lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (+12-2) - (modified) lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (+3) - (modified) lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp (+11-2) - (modified) lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h (+2) - (modified) lldb/source/Symbol/Function.cpp (+22-1) - (modified) lldb/source/Symbol/Type.cpp (+17-15) - (modified) lldb/test/Shell/SymbolFile/DWARF/x86/find-basic-function.cpp (+1-1) - (modified) lldb/test/Shell/SymbolFile/DWARF/x86/module-ownership.mm (+1-1) - (modified) lldb/tools/lldb-test/lldb-test.cpp (+8-4) ``````````diff diff --git a/lldb/include/lldb/Symbol/Function.h b/lldb/include/lldb/Symbol/Function.h index 28afdbff1eb233e..de69fd949d24748 100644 --- a/lldb/include/lldb/Symbol/Function.h +++ b/lldb/include/lldb/Symbol/Function.h @@ -533,6 +533,12 @@ class Function : public UserID, public SymbolContextScope { /// The DeclContext, or NULL if none exists. CompilerDeclContext GetDeclContext(); + /// Get the CompilerContext for this function, if available. + /// + /// \return + /// The CompilerContext, or NULL if none exists. + std::vector<CompilerContext> GetCompilerContext(); + /// Get accessor for the type that describes the function return value type, /// and parameter types. /// diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h index 512dd9acb86db61..b40d0f03b6e0130 100644 --- a/lldb/include/lldb/Symbol/SymbolFile.h +++ b/lldb/include/lldb/Symbol/SymbolFile.h @@ -225,14 +225,16 @@ class SymbolFile : public PluginInterface { virtual bool CompleteType(CompilerType &compiler_type) = 0; virtual void ParseDeclsForContext(CompilerDeclContext decl_ctx) {} - virtual CompilerDecl GetDeclForUID(lldb::user_id_t uid) { - return CompilerDecl(); - } + virtual CompilerDecl GetDeclForUID(lldb::user_id_t uid) { return {}; } virtual CompilerDeclContext GetDeclContextForUID(lldb::user_id_t uid) { - return CompilerDeclContext(); + return {}; } virtual CompilerDeclContext GetDeclContextContainingUID(lldb::user_id_t uid) { - return CompilerDeclContext(); + return {}; + } + virtual std::vector<CompilerContext> + GetCompilerContextForUID(lldb::user_id_t uid) { + return {}; } virtual uint32_t ResolveSymbolContext(const Address &so_addr, lldb::SymbolContextItem resolve_scope, diff --git a/lldb/include/lldb/Symbol/Type.h b/lldb/include/lldb/Symbol/Type.h index c505262cd9eaecf..3d9ed2183d81ecd 100644 --- a/lldb/include/lldb/Symbol/Type.h +++ b/lldb/include/lldb/Symbol/Type.h @@ -34,7 +34,7 @@ struct CompilerContext { } bool operator!=(const CompilerContext &rhs) const { return !(*this == rhs); } - void Dump() const; + void Dump(Stream *s) const; CompilerContextKind kind; ConstString name; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 545a5dcc7d0fd09..43d61a9f66c0ba2 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -142,8 +142,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc, // If this type comes from a Clang module, recursively look in the // DWARF section of the .pcm file in the module cache. Clang // generates DWO skeleton units as breadcrumbs to find them. - llvm::SmallVector<CompilerContext, 4> decl_context; - die.GetDeclContext(decl_context); + std::vector<CompilerContext> decl_context = die.GetDeclContext(); TypeMap pcm_types; // The type in the Clang module must have the same language as the current CU. @@ -2286,7 +2285,7 @@ CompilerDecl DWARFASTParserClang::GetDeclForUIDFromDWARF(const DWARFDIE &die) { clang::Decl *clang_decl = GetClangDeclForDIE(die); if (clang_decl != nullptr) return m_ast.GetCompilerDecl(clang_decl); - return CompilerDecl(); + return {}; } CompilerDeclContext @@ -2294,7 +2293,7 @@ DWARFASTParserClang::GetDeclContextForUIDFromDWARF(const DWARFDIE &die) { clang::DeclContext *clang_decl_ctx = GetClangDeclContextForDIE(die); if (clang_decl_ctx) return m_ast.CreateDeclContext(clang_decl_ctx); - return CompilerDeclContext(); + return {}; } CompilerDeclContext @@ -2303,7 +2302,7 @@ DWARFASTParserClang::GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) { GetClangDeclContextContainingDIE(die, nullptr); if (clang_decl_ctx) return m_ast.CreateDeclContext(clang_decl_ctx); - return CompilerDeclContext(); + return {}; } size_t DWARFASTParserClang::ParseChildEnumerators( diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp index d43c2ac276fb819..b5bfa31a40a8ff2 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp @@ -373,47 +373,49 @@ std::vector<DWARFDIE> DWARFDIE::GetDeclContextDIEs() const { return result; } -void DWARFDIE::GetDeclContext( - llvm::SmallVectorImpl<lldb_private::CompilerContext> &context) const { +std::vector<lldb_private::CompilerContext> DWARFDIE::GetDeclContext() const { + std::vector<lldb_private::CompilerContext> context; const dw_tag_t tag = Tag(); if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit) - return; + return context; DWARFDIE parent = GetParent(); if (parent) - parent.GetDeclContext(context); + context = parent.GetDeclContext(); + auto push_ctx = [&](CompilerContextKind kind, llvm::StringRef name) { + context.push_back({kind, ConstString(name)}); + }; switch (tag) { case DW_TAG_module: - context.push_back({CompilerContextKind::Module, ConstString(GetName())}); + push_ctx(CompilerContextKind::Module, GetName()); break; case DW_TAG_namespace: - context.push_back({CompilerContextKind::Namespace, ConstString(GetName())}); + push_ctx(CompilerContextKind::Namespace, GetName()); break; case DW_TAG_structure_type: - context.push_back({CompilerContextKind::Struct, ConstString(GetName())}); + push_ctx(CompilerContextKind::Struct, GetName()); break; case DW_TAG_union_type: - context.push_back({CompilerContextKind::Union, ConstString(GetName())}); + push_ctx(CompilerContextKind::Union, GetName()); break; case DW_TAG_class_type: - context.push_back({CompilerContextKind::Class, ConstString(GetName())}); + push_ctx(CompilerContextKind::Class, GetName()); break; case DW_TAG_enumeration_type: - context.push_back({CompilerContextKind::Enum, ConstString(GetName())}); + push_ctx(CompilerContextKind::Enum, GetName()); break; case DW_TAG_subprogram: - context.push_back( - {CompilerContextKind::Function, ConstString(GetPubname())}); + push_ctx(CompilerContextKind::Function, GetPubname()); break; case DW_TAG_variable: - context.push_back( - {CompilerContextKind::Variable, ConstString(GetPubname())}); +push_ctx(CompilerContextKind::Variable, GetPubname()); break; case DW_TAG_typedef: - context.push_back({CompilerContextKind::Typedef, ConstString(GetName())}); + push_ctx(CompilerContextKind::Typedef, GetName()); break; default: break; } + return context; } DWARFDIE diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h index 25b313bf0995742..a68af62c8b3e20c 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h @@ -74,7 +74,7 @@ class DWARFDIE : public DWARFBaseDIE { /// Return this DIE's decl context as it is needed to look up types /// in Clang's -gmodules debug info format. - void GetDeclContext(llvm::SmallVectorImpl<CompilerContext> &context) const; + std::vector<CompilerContext> GetDeclContext() const; // Getting attribute values from the DIE. // diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 737c65d0712e0db..f306093819d41d1 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -1454,6 +1454,17 @@ SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) { return CompilerDeclContext(); } +std::vector<CompilerContext> +SymbolFileDWARF::GetCompilerContextForUID(lldb::user_id_t type_uid) { + std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); + // Anytime we have a lldb::user_id_t, we must get the DIE by calling + // SymbolFileDWARF::GetDIE(). See comments inside the + // SymbolFileDWARF::GetDIE() for details. + if (DWARFDIE die = GetDIE(type_uid)) + return die.GetDeclContext(); + return {}; +} + Type *SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); // Anytime we have a lldb::user_id_t, we must get the DIE by calling @@ -2709,8 +2720,7 @@ void SymbolFileDWARF::FindTypes( if (!languages[GetLanguageFamily(*die.GetCU())]) return true; - llvm::SmallVector<CompilerContext, 4> die_context; - die.GetDeclContext(die_context); + std::vector<CompilerContext> die_context = die.GetDeclContext(); if (!contextMatches(die_context, pattern)) return true; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index 646d5d9a471c41c..0689ffe0d65dcf6 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -153,6 +153,9 @@ class SymbolFileDWARF : public SymbolFileCommon { CompilerDeclContext GetDeclContextContainingUID(lldb::user_id_t uid) override; + std::vector<CompilerContext> + GetCompilerContextForUID(lldb::user_id_t uid) override; + void ParseDeclsForContext(CompilerDeclContext decl_ctx) override; uint32_t ResolveSymbolContext(const Address &so_addr, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp index f789cbac9a717f1..567c06b4a475d25 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -1382,7 +1382,7 @@ SymbolFileDWARFDebugMap::GetDeclContextForUID(lldb::user_id_t type_uid) { SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx); if (oso_dwarf) return oso_dwarf->GetDeclContextForUID(type_uid); - return CompilerDeclContext(); + return {}; } CompilerDeclContext @@ -1391,7 +1391,16 @@ SymbolFileDWARFDebugMap::GetDeclContextContainingUID(lldb::user_id_t type_uid) { SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx); if (oso_dwarf) return oso_dwarf->GetDeclContextContainingUID(type_uid); - return CompilerDeclContext(); + return {}; +} + +std::vector<CompilerContext> +SymbolFileDWARFDebugMap::GetCompilerContextForUID(lldb::user_id_t type_uid) { + const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid); + SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx); + if (oso_dwarf) + return oso_dwarf->GetCompilerContextForUID(type_uid); + return {}; } void SymbolFileDWARFDebugMap::ParseDeclsForContext( diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h index 52fa1dca3da5f23..a337a76b7a69a66 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -93,6 +93,8 @@ class SymbolFileDWARFDebugMap : public SymbolFileCommon { CompilerDeclContext GetDeclContextForUID(lldb::user_id_t uid) override; CompilerDeclContext GetDeclContextContainingUID(lldb::user_id_t uid) override; + std::vector<CompilerContext> + GetCompilerContextForUID(lldb::user_id_t uid) override; void ParseDeclsForContext(CompilerDeclContext decl_ctx) override; bool CompleteType(CompilerType &compiler_type) override; diff --git a/lldb/source/Symbol/Function.cpp b/lldb/source/Symbol/Function.cpp index c651e4573854108..b89d36eaa7fd110 100644 --- a/lldb/source/Symbol/Function.cpp +++ b/lldb/source/Symbol/Function.cpp @@ -396,6 +396,17 @@ void Function::GetDescription(Stream *s, lldb::DescriptionLevel level, s->AsRawOstream() << ", name = \"" << name << '"'; if (mangled) s->AsRawOstream() << ", mangled = \"" << mangled << '"'; + if (level == eDescriptionLevelVerbose) { + *s << ", decl_context = {"; + auto decl_context = GetCompilerContext(); + // Drop the function itself from the context chain. + if (decl_context.size()) + decl_context.pop_back(); + llvm::interleave( + decl_context.begin(), decl_context.end(), + [&](CompilerContext &ctx) { ctx.Dump(s); }, [&]() { *s << ", "; }); + *s << "}"; + } *s << ", range = "; Address::DumpStyle fallback_style; if (level == eDescriptionLevelVerbose) @@ -519,7 +530,17 @@ CompilerDeclContext Function::GetDeclContext() { if (SymbolFile *sym_file = module_sp->GetSymbolFile()) return sym_file->GetDeclContextForUID(GetID()); } - return CompilerDeclContext(); + return {}; +} + +std::vector<CompilerContext> Function::GetCompilerContext() { + ModuleSP module_sp = CalculateSymbolContextModule(); + + if (module_sp) { + if (SymbolFile *sym_file = module_sp->GetSymbolFile()) + return sym_file->GetCompilerContextForUID(GetID()); + } + return {}; } Type *Function::GetType() { diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp index 548300d5709533c..66b2369c504a15a 100644 --- a/lldb/source/Symbol/Type.cpp +++ b/lldb/source/Symbol/Type.cpp @@ -64,49 +64,51 @@ bool lldb_private::contextMatches(llvm::ArrayRef<CompilerContext> context_chain, return true; } -void CompilerContext::Dump() const { +void CompilerContext::Dump(Stream *s) const { + if (!s) + return; switch (kind) { default: - printf("Invalid"); + *s << "Invalid"; break; case CompilerContextKind::TranslationUnit: - printf("TranslationUnit"); + *s << "TranslationUnit"; break; case CompilerContextKind::Module: - printf("Module"); + *s << "Module"; break; case CompilerContextKind::Namespace: - printf("Namespace"); + *s << "Namespace"; break; case CompilerContextKind::Class: - printf("Class"); + *s << "Class"; break; case CompilerContextKind::Struct: - printf("Structure"); + *s << "Structure"; break; case CompilerContextKind::Union: - printf("Union"); + *s << "Union"; break; case CompilerContextKind::Function: - printf("Function"); + *s << "Function"; break; case CompilerContextKind::Variable: - printf("Variable"); + *s << "Variable"; break; case CompilerContextKind::Enum: - printf("Enumeration"); + *s << "Enumeration"; break; case CompilerContextKind::Typedef: - printf("Typedef"); + *s << "Typedef"; break; case CompilerContextKind::AnyModule: - printf("AnyModule"); + *s << "AnyModule"; break; case CompilerContextKind::AnyType: - printf("AnyType"); + *s << "AnyType"; break; } - printf("(\"%s\")\n", name.GetCString()); + *s << "(" << name << ")"; } class TypeAppendVisitor { diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/find-basic-function.cpp b/lldb/test/Shell/SymbolFile/DWARF/x86/find-basic-function.cpp index c4fdee113eab9a4..204568a446d0a49 100644 --- a/lldb/test/Shell/SymbolFile/DWARF/x86/find-basic-function.cpp +++ b/lldb/test/Shell/SymbolFile/DWARF/x86/find-basic-function.cpp @@ -82,7 +82,7 @@ // FULL-MANGLED-METHOD-DAG: name = "sbar::foo(int)", mangled = "_ZN4sbar3fooEi" // CONTEXT: Found 1 functions: -// CONTEXT-DAG: name = "bar::foo()", mangled = "_ZN3bar3fooEv" +// CONTEXT-DAG: name = "bar::foo()", mangled = "_ZN3bar3fooEv", decl_context = {Namespace(bar)} // EMPTY: Found 0 functions: diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/module-ownership.mm b/lldb/test/Shell/SymbolFile/DWARF/x86/module-ownership.mm index a8dd6cf1d901aa9..4f39e2e5a9e170e 100644 --- a/lldb/test/Shell/SymbolFile/DWARF/x86/module-ownership.mm +++ b/lldb/test/Shell/SymbolFile/DWARF/x86/module-ownership.mm @@ -26,7 +26,7 @@ // CHECK-ANON-S1: CXXRecordDecl {{.*}} imported in A struct StructB s3; -// CHECK-ANON-S2: CXXRecordDecl {{.*}} imported in A.B {{.*}} struct +// CHECK-ANON-S2: CXXRecordDecl {{.*}} imported in A.B {{.*}}struct // CHECK-ANON-S2: -FieldDecl {{.*}} in A.B anon_field_b 'int' Nested s4; diff --git a/lldb/tools/lldb-test/lldb-test.cpp b/lldb/tools/lldb-test/lldb-test.cpp index d9c30b4f2ed8135..fa758bae5023348 100644 --- a/lldb/tools/lldb-test/lldb-test.cpp +++ b/lldb/tools/lldb-test/lldb-test.cpp @@ -322,10 +322,12 @@ std::vector<CompilerContext> parseCompilerContext() { } result.push_back({kind, ConstString{value}}); } - outs() << "Search context: {\n"; - for (auto entry: result) - entry.Dump(); - outs() << "}\n"; + outs() << "Search context: {"; + lldb_private::StreamString s; + llvm::interleave( + result.begin(), result.end(), [&](CompilerContext &ctx) { ctx.Dump(&s); }, + [&]() { s << ", "; }); + outs() << s.GetString().str() << "}\n"; return result; } @@ -816,6 +818,8 @@ Expected<Error (*)(lldb_private::Module &)> opts::symbols::getAction() { "Specify search type (-find) to use search options."); return dumpModule; + + case FindType::Function: if (!File.empty() + (Line != 0) == 1) return make_string_error("Both file name and line number must be " `````````` </details> https://github.com/llvm/llvm-project/pull/69981 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits