-
Notifications
You must be signed in to change notification settings - Fork 14.3k
Expose DWARFDIE::GetDeclContext() in lldb_private::Function. #69981
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-lldb Author: Adrian Prantl (adrian-prantl) ChangesI 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:
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 "
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
overall LGTM, few questions though
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
Outdated
Show resolved
Hide resolved
✅ With the latest revision this PR passed the C/C++ code formatter. |
037a18f
to
8ef2fc7
Compare
@@ -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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In case someone asks about this: before we force-parsed the DIE by calling GetDeclContext() there used to be an <undeserialized declaration>
output here that is irrelevant to the test.
8ef2fc7
to
367431f
Compare
I need this API in the Swift plugin, but it seems generally useful enough to expose it in the main branch.
367431f
to
b60b12b
Compare
I need this API in the Swift plugin, but it seems generally useful enough to expose it in the main branch.