[Lldb-commits] [lldb] [lldb] DWARFDIE: Follow DW_AT_specification when computing CompilerCo… (PR #77157)
Adrian Prantl via lldb-commits
lldb-commits at lists.llvm.org
Fri Jan 5 15:16:37 PST 2024
https://github.com/adrian-prantl created https://github.com/llvm/llvm-project/pull/77157
…ntext
Following the specification chain seems to be clearly the expected behavior of GetDeclContext(). Otherwise C++ methods have an empty CompilerContext instead of being nested in their struct/class.
Theprimary motivation for this functionality is the Swift plugin. In order to test the change I added a proof-of-concept implementation of a Module::FindFunction() variant that takes a CompilerContext, expesed via lldb-test.
rdar://120553412
>From 7f759420236078c01bec7c1b8a9673c74343be98 Mon Sep 17 00:00:00 2001
From: Adrian Prantl <aprantl at apple.com>
Date: Fri, 5 Jan 2024 15:11:24 -0800
Subject: [PATCH] [lldb] DWARFDIE: Follow DW_AT_specification when computing
CompilerContext
Following the specification chain seems to be clearly the expected
behavior of GetDeclContext(). Otherwise C++ methods have an empty
CompilerContext instead of being nested in their struct/class.
Theprimary motivation for this functionality is the Swift plugin. In
order to test the change I added a proof-of-concept implementation of
a Module::FindFunction() variant that takes a CompilerContext, expesed
via lldb-test.
rdar://120553412
---
lldb/include/lldb/Core/Module.h | 6 ++++++
lldb/source/Core/Module.cpp | 17 +++++++++++++++++
.../Plugins/SymbolFile/DWARF/DWARFDIE.cpp | 17 +++++++++++------
.../SymbolFile/DWARF/SymbolFileDWARF.cpp | 11 ++++++-----
.../DWARF/x86/find-basic-function.cpp | 6 ++++++
lldb/tools/lldb-test/lldb-test.cpp | 4 ++++
6 files changed, 50 insertions(+), 11 deletions(-)
diff --git a/lldb/include/lldb/Core/Module.h b/lldb/include/lldb/Core/Module.h
index f4973cdda1efcc..0188057247a68b 100644
--- a/lldb/include/lldb/Core/Module.h
+++ b/lldb/include/lldb/Core/Module.h
@@ -337,6 +337,12 @@ class Module : public std::enable_shared_from_this<Module>,
const ModuleFunctionSearchOptions &options,
SymbolContextList &sc_list);
+ /// Find functions by compiler context.
+ void FindFunctions(llvm::ArrayRef<CompilerContext> compiler_ctx,
+ lldb::FunctionNameType name_type_mask,
+ const ModuleFunctionSearchOptions &options,
+ SymbolContextList &sc_list);
+
/// Find functions by name.
///
/// If the function is an inlined function, it will have a block,
diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index c0574b724ace7b..4d2fa18c55b1d7 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -855,6 +855,23 @@ void Module::FindFunctions(ConstString name,
}
}
+void Module::FindFunctions(llvm::ArrayRef<CompilerContext> compiler_ctx,
+ FunctionNameType name_type_mask,
+ const ModuleFunctionSearchOptions &options,
+ SymbolContextList &sc_list) {
+ if (compiler_ctx.empty() ||
+ compiler_ctx.back().kind != CompilerContextKind::Function)
+ return;
+ ConstString name = compiler_ctx.back().name;
+ CompilerDeclContext dc;
+ SymbolContextList unfiltered;
+ FindFunctions(name, dc,name_type_mask, options, unfiltered);
+ // Filter by context.
+ for (auto sc : unfiltered)
+ if (sc.function && compiler_ctx.equals(sc.function->GetCompilerContext()))
+ sc_list.Append(sc);
+}
+
void Module::FindFunctions(const RegularExpression ®ex,
const ModuleFunctionSearchOptions &options,
SymbolContextList &sc_list) {
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
index bed68f45426f67..64211da37e7802 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -375,16 +375,21 @@ std::vector<DWARFDIE> DWARFDIE::GetDeclContextDIEs() 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 context;
DWARFDIE parent = GetParent();
- if (parent)
+ if (parent) {
+ const dw_tag_t parent_tag = parent.Tag();
+ if (parent_tag == DW_TAG_compile_unit || parent_tag == DW_TAG_partial_unit)
+ // Handle top-level DIEs by following the specification if any.
+ if (DWARFDIE spec = GetReferencedDIE(DW_AT_specification))
+ if (spec != *this)
+ return spec.GetDeclContext();
+
context = parent.GetDeclContext();
+ }
auto push_ctx = [&](CompilerContextKind kind, llvm::StringRef name) {
context.push_back({kind, ConstString(name)});
};
- switch (tag) {
+ switch (Tag()) {
case DW_TAG_module:
push_ctx(CompilerContextKind::Module, GetName());
break;
@@ -404,7 +409,7 @@ std::vector<lldb_private::CompilerContext> DWARFDIE::GetDeclContext() const {
push_ctx(CompilerContextKind::Enum, GetName());
break;
case DW_TAG_subprogram:
- push_ctx(CompilerContextKind::Function, GetPubname());
+ push_ctx(CompilerContextKind::Function, GetName());
break;
case DW_TAG_variable:
push_ctx(CompilerContextKind::Variable, GetPubname());
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 447930ffe07b3f..f539ed5d2ae570 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -2574,11 +2574,12 @@ void SymbolFileDWARF::FindFunctions(const Module::LookupInfo &lookup_info,
Module::LookupInfo no_tp_lookup_info(lookup_info);
no_tp_lookup_info.SetLookupName(ConstString(name_no_template_params));
- m_index->GetFunctions(no_tp_lookup_info, *this, parent_decl_ctx, [&](DWARFDIE die) {
- if (resolved_dies.insert(die.GetDIE()).second)
- ResolveFunction(die, include_inlines, sc_list);
- return true;
- });
+ m_index->GetFunctions(no_tp_lookup_info, *this, parent_decl_ctx,
+ [&](DWARFDIE die) {
+ if (resolved_dies.insert(die.GetDIE()).second)
+ ResolveFunction(die, include_inlines, sc_list);
+ return true;
+ });
}
}
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 204568a446d0a4..30143a41d5e734 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/x86/find-basic-function.cpp
+++ b/lldb/test/Shell/SymbolFile/DWARF/x86/find-basic-function.cpp
@@ -34,6 +34,8 @@
// RUN: FileCheck --check-prefix=FULL-MANGLED-METHOD %s
// RUN: lldb-test symbols --name=foo --context=context --find=function --function-flags=base %t | \
// RUN: FileCheck --check-prefix=CONTEXT %s
+// RUN: lldb-test symbols --compiler-context=Struct:sbar,Function:foo -language=c++ -find=function -function-flags=method %t | \
+// RUN: FileCheck --check-prefix=COMPILER-CONTEXT %s
// RUN: lldb-test symbols --name=not_there --find=function %t | \
// RUN: FileCheck --check-prefix=EMPTY %s
@@ -84,6 +86,10 @@
// CONTEXT: Found 1 functions:
// CONTEXT-DAG: name = "bar::foo()", mangled = "_ZN3bar3fooEv", decl_context = {Namespace(bar)}
+// COMPILER-CONTEXT: Found 2 functions:
+// COMPILER-CONTEXT-DAG: name = "sbar::foo()", mangled = "_ZN4sbar3fooEv"
+// COMPILER-CONTEXT-DAG: name = "sbar::foo(int)", mangled = "_ZN4sbar3fooEi"
+
// EMPTY: Found 0 functions:
void foo() {}
diff --git a/lldb/tools/lldb-test/lldb-test.cpp b/lldb/tools/lldb-test/lldb-test.cpp
index e326a84c1dbd2f..33281cfb150747 100644
--- a/lldb/tools/lldb-test/lldb-test.cpp
+++ b/lldb/tools/lldb-test/lldb-test.cpp
@@ -466,6 +466,7 @@ static lldb::DescriptionLevel GetDescriptionLevel() {
Error opts::symbols::findFunctions(lldb_private::Module &Module) {
SymbolFile &Symfile = *Module.GetSymbolFile();
SymbolContextList List;
+ auto compiler_context = parseCompilerContext();
if (!File.empty()) {
assert(Line != 0);
@@ -498,6 +499,9 @@ Error opts::symbols::findFunctions(lldb_private::Module &Module) {
assert(RE.IsValid());
List.Clear();
Symfile.FindFunctions(RE, true, List);
+ } else if (!compiler_context.empty()) {
+ List.Clear();
+ Module.FindFunctions(compiler_context, getFunctionNameFlags(), {}, List);
} else {
Expected<CompilerDeclContext> ContextOr = getDeclContext(Symfile);
if (!ContextOr)
More information about the lldb-commits
mailing list