Skip to content

Commit 7e00e3a

Browse files
authored
[lldb] Fix lookup of types in anonymous namespaces with -gsimple-template-names (#123054)
Anonymous namespaces are supposed to be optional when looking up types. This was not working in combination with -gsimple-template-names, because the way it was constructing the complete (with template args) name scope (i.e., by generating thescope as a string and then reparsing it) did not preserve the information about the scope kinds. Essentially what the code wants here is to call `GetTypeLookupContext` (that's the function used to get the context in the "regular" code path), but to embelish each name with the template arguments (if they don't have them already). This PR implements exactly that by adding an argument to control which kind of names are we interested in. This should also make the lookup faster as it avoids parsing of the long string, but I haven't attempted to benchmark that. I believe this function can also be used in some other places where we're manually appending template names, but I'm leaving that for another patch.
1 parent 0d6b4cb commit 7e00e3a

File tree

5 files changed

+72
-30
lines changed

5 files changed

+72
-30
lines changed

lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#include "llvm/ADT/iterator.h"
2020
#include "llvm/BinaryFormat/Dwarf.h"
2121
#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
22+
#include "llvm/DebugInfo/DWARF/DWARFTypePrinter.h"
23+
#include "llvm/Support/raw_ostream.h"
2224

2325
using namespace lldb_private;
2426
using namespace lldb_private::dwarf;
@@ -376,7 +378,8 @@ lldb_private::Type *DWARFDIE::ResolveTypeUID(const DWARFDIE &die) const {
376378
return nullptr;
377379
}
378380

379-
static CompilerContext GetContextEntry(DWARFDIE die) {
381+
static CompilerContext GetContextEntry(DWARFDIE die,
382+
bool derive_template_names) {
380383
auto ctx = [die](CompilerContextKind kind) {
381384
return CompilerContext(kind, ConstString(die.GetName()));
382385
};
@@ -386,11 +389,6 @@ static CompilerContext GetContextEntry(DWARFDIE die) {
386389
return ctx(CompilerContextKind::Module);
387390
case DW_TAG_namespace:
388391
return ctx(CompilerContextKind::Namespace);
389-
case DW_TAG_class_type:
390-
case DW_TAG_structure_type:
391-
return ctx(CompilerContextKind::ClassOrStruct);
392-
case DW_TAG_union_type:
393-
return ctx(CompilerContextKind::Union);
394392
case DW_TAG_enumeration_type:
395393
return ctx(CompilerContextKind::Enum);
396394
case DW_TAG_subprogram:
@@ -401,12 +399,28 @@ static CompilerContext GetContextEntry(DWARFDIE die) {
401399
return ctx(CompilerContextKind::Typedef);
402400
case DW_TAG_base_type:
403401
return ctx(CompilerContextKind::Builtin);
402+
case DW_TAG_class_type:
403+
case DW_TAG_structure_type:
404+
case DW_TAG_union_type: {
405+
CompilerContextKind kind = die.Tag() == DW_TAG_union_type
406+
? CompilerContextKind::Union
407+
: CompilerContextKind::ClassOrStruct;
408+
llvm::StringRef name = die.GetName();
409+
if (!derive_template_names || name.contains('<'))
410+
return CompilerContext(kind, ConstString(name));
411+
412+
std::string name_storage = name.str();
413+
llvm::raw_string_ostream os(name_storage);
414+
llvm::DWARFTypePrinter<DWARFDIE>(os).appendAndTerminateTemplateParameters(
415+
die);
416+
return CompilerContext(kind, ConstString(os.str()));
417+
}
404418
default:
405419
llvm_unreachable("Check tag type in the caller!");
406420
}
407421
}
408422

409-
static void GetDeclContextImpl(DWARFDIE die,
423+
static void GetDeclContextImpl(DWARFDIE die, bool derive_template_names,
410424
llvm::SmallSet<lldb::user_id_t, 4> &seen,
411425
std::vector<CompilerContext> &context) {
412426
// Stop if we hit a cycle.
@@ -428,7 +442,7 @@ static void GetDeclContextImpl(DWARFDIE die,
428442
case DW_TAG_subprogram:
429443
case DW_TAG_variable:
430444
case DW_TAG_typedef:
431-
context.push_back(GetContextEntry(die));
445+
context.push_back(GetContextEntry(die, derive_template_names));
432446
break;
433447
default:
434448
break;
@@ -438,15 +452,16 @@ static void GetDeclContextImpl(DWARFDIE die,
438452
}
439453
}
440454

441-
std::vector<CompilerContext> DWARFDIE::GetDeclContext() const {
455+
std::vector<CompilerContext>
456+
DWARFDIE::GetDeclContext(bool derive_template_names) const {
442457
llvm::SmallSet<lldb::user_id_t, 4> seen;
443458
std::vector<CompilerContext> context;
444-
GetDeclContextImpl(*this, seen, context);
459+
GetDeclContextImpl(*this, derive_template_names, seen, context);
445460
std::reverse(context.begin(), context.end());
446461
return context;
447462
}
448463

449-
static void GetTypeLookupContextImpl(DWARFDIE die,
464+
static void GetTypeLookupContextImpl(DWARFDIE die, bool derive_template_names,
450465
llvm::SmallSet<lldb::user_id_t, 4> &seen,
451466
std::vector<CompilerContext> &context) {
452467
// Stop if we hit a cycle.
@@ -461,7 +476,7 @@ static void GetTypeLookupContextImpl(DWARFDIE die,
461476
case DW_TAG_variable:
462477
case DW_TAG_typedef:
463478
case DW_TAG_base_type:
464-
context.push_back(GetContextEntry(die));
479+
context.push_back(GetContextEntry(die, derive_template_names));
465480
break;
466481

467482
// If any of the tags below appear in the parent chain, stop the decl
@@ -484,10 +499,11 @@ static void GetTypeLookupContextImpl(DWARFDIE die,
484499
}
485500
}
486501

487-
std::vector<CompilerContext> DWARFDIE::GetTypeLookupContext() const {
502+
std::vector<CompilerContext>
503+
DWARFDIE::GetTypeLookupContext(bool derive_template_names) const {
488504
llvm::SmallSet<lldb::user_id_t, 4> seen;
489505
std::vector<CompilerContext> context;
490-
GetTypeLookupContextImpl(*this, seen, context);
506+
GetTypeLookupContextImpl(*this, derive_template_names, seen, context);
491507
std::reverse(context.begin(), context.end());
492508
return context;
493509
}

lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,15 @@ class DWARFDIE : public DWARFBaseDIE {
7373
/// Return this DIE's decl context as it is needed to look up types
7474
/// in Clang modules. This context will include any modules or functions that
7575
/// the type is declared in so an exact module match can be efficiently made.
76-
std::vector<CompilerContext> GetDeclContext() const;
76+
///
77+
/// \param[in] derive_template_names
78+
/// If true, augments the returned names with template arguments derived
79+
/// from the child DIEs, if the names don't contained template arguments
80+
/// already. If false, the returned context will contain the names exactly
81+
/// as they are spelled in the debug info, regardless of whether that
82+
/// includes template arguments or not.
83+
std::vector<CompilerContext>
84+
GetDeclContext(bool derive_template_names = false) const;
7785

7886
/// Get a context to a type so it can be looked up.
7987
///
@@ -85,7 +93,15 @@ class DWARFDIE : public DWARFBaseDIE {
8593
/// appropriate time, like either the translation unit or at a function
8694
/// context. This is designed to allow users to efficiently look for types
8795
/// using a full or partial CompilerContext array.
88-
std::vector<CompilerContext> GetTypeLookupContext() const;
96+
///
97+
/// \param[in] derive_template_names
98+
/// If true, augments the returned names with template arguments derived
99+
/// from the child DIEs, if the names don't contained template arguments
100+
/// already. If false, the returned context will contain the names exactly
101+
/// as they are spelled in the debug info, regardless of whether that
102+
/// includes template arguments or not.
103+
std::vector<CompilerContext>
104+
GetTypeLookupContext(bool derive_template_names = false) const;
89105

90106
DWARFDeclContext GetDWARFDeclContext() const;
91107

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,8 @@
1010
#include "llvm/ADT/STLExtras.h"
1111
#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
1212
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
13-
#include "llvm/DebugInfo/DWARF/DWARFTypePrinter.h"
1413
#include "llvm/Support/Casting.h"
1514
#include "llvm/Support/FileUtilities.h"
16-
#include "llvm/Support/Format.h"
1715
#include "llvm/Support/FormatAdapters.h"
1816
#include "llvm/Support/Threading.h"
1917

@@ -2740,18 +2738,11 @@ void SymbolFileDWARF::FindTypes(const TypeQuery &query, TypeResults &results) {
27402738
// Copy our match's context and update the basename we are looking for
27412739
// so we can use this only to compare the context correctly.
27422740
m_index->GetTypesWithQuery(query_simple, [&](DWARFDIE die) {
2743-
// Check the language, but only if we have a language filter.
2744-
if (query.HasLanguage()) {
2745-
if (!query.LanguageMatches(GetLanguageFamily(*die.GetCU())))
2746-
return true; // Keep iterating over index types, language mismatch.
2747-
}
2748-
2749-
std::string qualified_name;
2750-
llvm::raw_string_ostream os(qualified_name);
2751-
llvm::DWARFTypePrinter<DWARFDIE> type_printer(os);
2752-
type_printer.appendQualifiedName(die);
2753-
TypeQuery die_query(qualified_name, e_exact_match);
2754-
if (query.ContextMatches(die_query.GetContextRef()))
2741+
std::vector<CompilerContext> qualified_context =
2742+
query.GetModuleSearch()
2743+
? die.GetDeclContext(/*derive_template_names=*/true)
2744+
: die.GetTypeLookupContext(/*derive_template_names=*/true);
2745+
if (query.ContextMatches(qualified_context))
27552746
if (Type *matching_type = ResolveType(die, true, true))
27562747
results.InsertUnique(matching_type->shared_from_this());
27572748
return !results.Done(query); // Keep iterating if we aren't done.

lldb/test/API/lang/cpp/nested-template/TestNestedTemplate.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,16 @@ def do_test(self, debug_flags):
1717
DATA_TYPES_DISPLAYED_CORRECTLY,
1818
substrs=["1 match found"],
1919
)
20+
self.expect(
21+
"image lookup -A -t 'NS::Struct<int>'",
22+
DATA_TYPES_DISPLAYED_CORRECTLY,
23+
substrs=["1 match found"],
24+
)
25+
self.expect(
26+
"image lookup -A -t 'NS::Union<int>'",
27+
DATA_TYPES_DISPLAYED_CORRECTLY,
28+
substrs=["1 match found"],
29+
)
2030

2131
@skipIf(compiler=no_match("clang"))
2232
@skipIf(compiler_version=["<", "15.0"])

lldb/test/API/lang/cpp/nested-template/main.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@ struct Outer {
55
struct Inner {};
66
};
77

8+
namespace NS {
9+
namespace {
10+
template <typename T> struct Struct {};
11+
template <typename T> struct Union {};
12+
} // namespace
13+
} // namespace NS
14+
815
int main() {
916
Outer::Inner<int> oi;
17+
NS::Struct<int> ns_struct;
18+
NS::Union<int> ns_union;
1019
}

0 commit comments

Comments
 (0)