Skip to content

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

Merged
merged 1 commit into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions lldb/include/lldb/Symbol/Function.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down
12 changes: 7 additions & 5 deletions lldb/include/lldb/Symbol/SymbolFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion lldb/include/lldb/Symbol/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -2286,15 +2285,15 @@ 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
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
Expand All @@ -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(
Expand Down
32 changes: 17 additions & 15 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
//
Expand Down
14 changes: 12 additions & 2 deletions lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;

Expand Down
3 changes: 3 additions & 0 deletions lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
23 changes: 18 additions & 5 deletions lldb/source/Symbol/Function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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() {
Expand Down
30 changes: 15 additions & 15 deletions lldb/source/Symbol/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down
2 changes: 1 addition & 1 deletion lldb/test/Shell/SymbolFile/DWARF/x86/module-ownership.mm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Collaborator Author

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.

// CHECK-ANON-S2: -FieldDecl {{.*}} in A.B anon_field_b 'int'

Nested s4;
Expand Down
8 changes: 4 additions & 4 deletions lldb/tools/lldb-test/lldb-test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down