https://github.com/adrian-prantl updated https://github.com/llvm/llvm-project/pull/69981
>From b60b12b15d431d291032427a76473eb5f3661cb4 Mon Sep 17 00:00:00 2001 From: Adrian Prantl <apra...@apple.com> Date: Mon, 23 Oct 2023 15:55:40 -0700 Subject: [PATCH] Expose DWARFDIE::GetDeclContext() in lldb_private::Function. I need this API in the Swift plugin, but it seems generally useful enough to expose it in the main branch. --- lldb/include/lldb/Symbol/Function.h | 6 ++++ lldb/include/lldb/Symbol/SymbolFile.h | 12 ++++--- lldb/include/lldb/Symbol/Type.h | 2 +- .../SymbolFile/DWARF/DWARFASTParserClang.cpp | 9 +++--- .../Plugins/SymbolFile/DWARF/DWARFDIE.cpp | 32 ++++++++++--------- .../Plugins/SymbolFile/DWARF/DWARFDIE.h | 2 +- .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 14 ++++++-- .../SymbolFile/DWARF/SymbolFileDWARF.h | 3 ++ .../DWARF/SymbolFileDWARFDebugMap.cpp | 18 +++++++---- .../DWARF/SymbolFileDWARFDebugMap.h | 2 ++ lldb/source/Symbol/Function.cpp | 23 ++++++++++--- lldb/source/Symbol/Type.cpp | 30 ++++++++--------- .../DWARF/x86/find-basic-function.cpp | 2 +- .../SymbolFile/DWARF/x86/module-ownership.mm | 2 +- lldb/tools/lldb-test/lldb-test.cpp | 8 ++--- 15 files changed, 104 insertions(+), 61 deletions(-) diff --git a/lldb/include/lldb/Symbol/Function.h b/lldb/include/lldb/Symbol/Function.h index 28afdbff1eb233e..8255c2baea77001 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 an empty vector if none is available. + 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..c5ef1f53021207a 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..1f9524f8add982f 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..d275c2cdf91c532 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -1379,19 +1379,25 @@ void SymbolFileDWARFDebugMap::SetCompileUnit(SymbolFileDWARF *oso_dwarf, CompilerDeclContext SymbolFileDWARFDebugMap::GetDeclContextForUID(lldb::user_id_t type_uid) { const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid); - SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx); - if (oso_dwarf) + if (SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx)) return oso_dwarf->GetDeclContextForUID(type_uid); - return CompilerDeclContext(); + return {}; } CompilerDeclContext SymbolFileDWARFDebugMap::GetDeclContextContainingUID(lldb::user_id_t type_uid) { const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid); - SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx); - if (oso_dwarf) + if (SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx)) 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); + if (SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx)) + 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..fdc090355771c6a 100644 --- a/lldb/source/Symbol/Function.cpp +++ b/lldb/source/Symbol/Function.cpp @@ -396,6 +396,15 @@ 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::interleaveComma(decl_context, *s, [&](auto &ctx) { ctx.Dump(*s); }); + *s << "}"; + } *s << ", range = "; Address::DumpStyle fallback_style; if (level == eDescriptionLevelVerbose) @@ -513,13 +522,17 @@ ConstString Function::GetDisplayName() const { } CompilerDeclContext Function::GetDeclContext() { - ModuleSP module_sp = CalculateSymbolContextModule(); - - if (module_sp) { + if (ModuleSP module_sp = CalculateSymbolContextModule()) if (SymbolFile *sym_file = module_sp->GetSymbolFile()) return sym_file->GetDeclContextForUID(GetID()); - } - return CompilerDeclContext(); + return {}; +} + +std::vector<CompilerContext> Function::GetCompilerContext() { + if (ModuleSP module_sp = CalculateSymbolContextModule()) + 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..006a843bacd2e12 100644 --- a/lldb/source/Symbol/Type.cpp +++ b/lldb/source/Symbol/Type.cpp @@ -64,49 +64,49 @@ bool lldb_private::contextMatches(llvm::ArrayRef<CompilerContext> context_chain, return true; } -void CompilerContext::Dump() const { +void CompilerContext::Dump(Stream &s) const { 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..45911b9065c2f8d 100644 --- a/lldb/tools/lldb-test/lldb-test.cpp +++ b/lldb/tools/lldb-test/lldb-test.cpp @@ -322,10 +322,10 @@ 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::interleaveComma(result, s, [&](auto &ctx) { ctx.Dump(s); }); + outs() << s.GetString().str() << "}\n"; return result; } _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits