Skip to content

Commit 220585e

Browse files
labathAlexisPerry
authored andcommitted
[lldb/DWARF] Fix type definition search with simple template names (llvm#95905)
With simple template names the template arguments aren't embedded in the DW_AT_name attribute of the type. The code in FindDefinitionTypeForDWARFDeclContext was comparing the synthesized template arguments on the leaf (most deeply nested) DIE, but was not sufficient, as the difference get be at any level above that (Foo<T>::Bar vs. Foo<U>::Bar). This patch makes sure we compare the entire context. As a drive-by I also remove the completely unnecessary ConstStringification of the GetDIEClassTemplateParams result.
1 parent 5186ed2 commit 220585e

File tree

5 files changed

+48
-46
lines changed

5 files changed

+48
-46
lines changed

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class DWARFASTParser {
5858
virtual void EnsureAllDIEsInDeclContextHaveBeenParsed(
5959
CompilerDeclContext decl_context) = 0;
6060

61-
virtual ConstString GetDIEClassTemplateParams(const DWARFDIE &die) = 0;
61+
virtual std::string GetDIEClassTemplateParams(const DWARFDIE &die) = 0;
6262

6363
static std::optional<SymbolFile::ArrayInfo>
6464
ParseChildArrayInfo(const DWARFDIE &parent_die,

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

+8-8
Original file line numberDiff line numberDiff line change
@@ -838,16 +838,16 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
838838
return type_sp;
839839
}
840840

841-
ConstString
841+
std::string
842842
DWARFASTParserClang::GetDIEClassTemplateParams(const DWARFDIE &die) {
843843
if (llvm::StringRef(die.GetName()).contains("<"))
844-
return ConstString();
844+
return {};
845845

846846
TypeSystemClang::TemplateParameterInfos template_param_infos;
847-
if (ParseTemplateParameterInfos(die, template_param_infos)) {
848-
return ConstString(m_ast.PrintTemplateParams(template_param_infos));
849-
}
850-
return ConstString();
847+
if (ParseTemplateParameterInfos(die, template_param_infos))
848+
return m_ast.PrintTemplateParams(template_param_infos);
849+
850+
return {};
851851
}
852852

853853
TypeSP DWARFASTParserClang::ParseEnum(const SymbolContext &sc,
@@ -1632,7 +1632,7 @@ DWARFASTParserClang::GetCPlusPlusQualifiedName(const DWARFDIE &die) {
16321632
case DW_TAG_union_type: {
16331633
if (const char *class_union_struct_name = parent_decl_ctx_die.GetName()) {
16341634
qualified_name.insert(
1635-
0, GetDIEClassTemplateParams(parent_decl_ctx_die).AsCString(""));
1635+
0, GetDIEClassTemplateParams(parent_decl_ctx_die));
16361636
qualified_name.insert(0, "::");
16371637
qualified_name.insert(0, class_union_struct_name);
16381638
}
@@ -1650,7 +1650,7 @@ DWARFASTParserClang::GetCPlusPlusQualifiedName(const DWARFDIE &die) {
16501650
qualified_name.append("::");
16511651

16521652
qualified_name.append(name);
1653-
qualified_name.append(GetDIEClassTemplateParams(die).AsCString(""));
1653+
qualified_name.append(GetDIEClassTemplateParams(die));
16541654

16551655
return qualified_name;
16561656
}

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,9 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser {
104104
///
105105
/// \param die The struct/class DWARFDIE containing template parameters.
106106
/// \return A string, including surrounding '<>', of the template parameters.
107-
/// If the DIE's name already has '<>', returns an empty ConstString because
107+
/// If the DIE's name already has '<>', returns an empty string because
108108
/// it's assumed that the caller is using the DIE name anyway.
109-
lldb_private::ConstString GetDIEClassTemplateParams(
109+
std::string GetDIEClassTemplateParams(
110110
const lldb_private::plugin::dwarf::DWARFDIE &die) override;
111111

112112
protected:

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

+36-34
Original file line numberDiff line numberDiff line change
@@ -3072,14 +3072,43 @@ SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(const DWARFDIE &die) {
30723072

30733073
// See comments below about -gsimple-template-names for why we attempt to
30743074
// compute missing template parameter names.
3075-
ConstString template_params;
3076-
if (type_system) {
3077-
DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
3078-
if (dwarf_ast)
3079-
template_params = dwarf_ast->GetDIEClassTemplateParams(die);
3075+
std::vector<std::string> template_params;
3076+
DWARFDeclContext die_dwarf_decl_ctx;
3077+
DWARFASTParser *dwarf_ast = type_system ? type_system->GetDWARFParser() : nullptr;
3078+
for (DWARFDIE ctx_die = die; ctx_die && !isUnitType(ctx_die.Tag());
3079+
ctx_die = ctx_die.GetParentDeclContextDIE()) {
3080+
die_dwarf_decl_ctx.AppendDeclContext(ctx_die.Tag(), ctx_die.GetName());
3081+
template_params.push_back(
3082+
(ctx_die.IsStructUnionOrClass() && dwarf_ast)
3083+
? dwarf_ast->GetDIEClassTemplateParams(ctx_die)
3084+
: "");
30803085
}
3086+
const bool any_template_params = llvm::any_of(
3087+
template_params, [](llvm::StringRef p) { return !p.empty(); });
30813088

3082-
const DWARFDeclContext die_dwarf_decl_ctx = die.GetDWARFDeclContext();
3089+
auto die_matches = [&](DWARFDIE type_die) {
3090+
// Resolve the type if both have the same tag or {class, struct} tags.
3091+
const bool tag_matches =
3092+
type_die.Tag() == tag ||
3093+
(IsStructOrClassTag(type_die.Tag()) && IsStructOrClassTag(tag));
3094+
if (!tag_matches)
3095+
return false;
3096+
if (any_template_params) {
3097+
size_t pos = 0;
3098+
for (DWARFDIE ctx_die = type_die;
3099+
ctx_die && !isUnitType(ctx_die.Tag()) &&
3100+
pos < template_params.size();
3101+
ctx_die = ctx_die.GetParentDeclContextDIE(), ++pos) {
3102+
if (template_params[pos].empty())
3103+
continue;
3104+
if (template_params[pos] != dwarf_ast->GetDIEClassTemplateParams(ctx_die))
3105+
return false;
3106+
}
3107+
if (pos != template_params.size())
3108+
return false;
3109+
}
3110+
return true;
3111+
};
30833112
m_index->GetFullyQualifiedType(die_dwarf_decl_ctx, [&](DWARFDIE type_die) {
30843113
// Make sure type_die's language matches the type system we are
30853114
// looking for. We don't want to find a "Foo" type from Java if we
@@ -3088,13 +3117,7 @@ SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(const DWARFDIE &die) {
30883117
!type_system->SupportsLanguage(GetLanguage(*type_die.GetCU())))
30893118
return true;
30903119

3091-
const dw_tag_t type_tag = type_die.Tag();
3092-
// Resolve the type if both have the same tag or {class, struct} tags.
3093-
const bool try_resolving_type =
3094-
type_tag == tag ||
3095-
(IsStructOrClassTag(type_tag) && IsStructOrClassTag(tag));
3096-
3097-
if (!try_resolving_type) {
3120+
if (!die_matches(type_die)) {
30983121
if (log) {
30993122
GetObjectFile()->GetModule()->LogMessage(
31003123
log,
@@ -3122,27 +3145,6 @@ SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(const DWARFDIE &die) {
31223145
if (!resolved_type || resolved_type == DIE_IS_BEING_PARSED)
31233146
return true;
31243147

3125-
// With -gsimple-template-names, the DIE name may not contain the template
3126-
// parameters. If the declaration has template parameters but doesn't
3127-
// contain '<', check that the child template parameters match.
3128-
if (template_params) {
3129-
llvm::StringRef test_base_name =
3130-
GetTypeForDIE(type_die)->GetBaseName().GetStringRef();
3131-
auto i = test_base_name.find('<');
3132-
3133-
// Full name from clang AST doesn't contain '<' so this type_die isn't
3134-
// a template parameter, but we're expecting template parameters, so
3135-
// bail.
3136-
if (i == llvm::StringRef::npos)
3137-
return true;
3138-
3139-
llvm::StringRef test_template_params =
3140-
test_base_name.slice(i, test_base_name.size());
3141-
// Bail if template parameters don't match.
3142-
if (test_template_params != template_params.GetStringRef())
3143-
return true;
3144-
}
3145-
31463148
type_sp = resolved_type->shared_from_this();
31473149
return false;
31483150
});

lldb/test/Shell/SymbolFile/DWARF/x86/simple-template-names-context.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// CHECK: (lldb) target variable
1313
// CHECK-NEXT: (ReferencesBoth<'A'>) both_a = {
1414
// CHECK-NEXT: (Outer<'A'>::Inner *) a = 0x{{[0-9A-Fa-f]*}} {}
15-
// CHECK-NEXT: (Outer<'A'>::Inner *) b = 0x{{[0-9A-Fa-f]*}} {}
15+
// CHECK-NEXT: (Outer<'B'>::Inner *) b = 0x{{[0-9A-Fa-f]*}} {}
1616
// CHECK-NEXT: }
1717
// CHECK-NEXT: (ReferencesBoth<'B'>) both_b = {
1818
// CHECK-NEXT: (Outer<'A'>::Inner *) a = 0x{{[0-9A-Fa-f]*}} {}

0 commit comments

Comments
 (0)