Skip to content

Commit 3fc0675

Browse files
committed
[lldb][dwarf] Compute fully qualified names on simplified template names with DWARFTypePrinter
1 parent e9eec14 commit 3fc0675

File tree

13 files changed

+170
-69
lines changed

13 files changed

+170
-69
lines changed

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

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include "clang/AST/DeclTemplate.h"
4545
#include "clang/AST/Type.h"
4646
#include "llvm/ADT/StringExtras.h"
47+
#include "llvm/DebugInfo/DWARF/DWARFTypePrinter.h"
4748
#include "llvm/Demangle/Demangle.h"
4849

4950
#include <map>
@@ -825,11 +826,11 @@ std::string DWARFASTParserClang::GetDIEClassTemplateParams(DWARFDIE die) {
825826
if (llvm::StringRef(die.GetName()).contains("<"))
826827
return {};
827828

828-
TypeSystemClang::TemplateParameterInfos template_param_infos;
829-
if (ParseTemplateParameterInfos(die, template_param_infos))
830-
return m_ast.PrintTemplateParams(template_param_infos);
831-
832-
return {};
829+
std::string name;
830+
llvm::raw_string_ostream os(name);
831+
llvm::DWARFTypePrinter<DWARFDIE> type_printer(os);
832+
type_printer.appendAndTerminateTemplateParameters(die);
833+
return name;
833834
}
834835

835836
void DWARFASTParserClang::MapDeclDIEToDefDIE(
@@ -1617,9 +1618,9 @@ void DWARFASTParserClang::GetUniqueTypeNameAndDeclaration(
16171618
case DW_TAG_structure_type:
16181619
case DW_TAG_union_type: {
16191620
if (const char *class_union_struct_name = parent_decl_ctx_die.GetName()) {
1620-
qualified_name.insert(
1621-
0, GetDIEClassTemplateParams(parent_decl_ctx_die));
16221621
qualified_name.insert(0, "::");
1622+
qualified_name.insert(0,
1623+
GetDIEClassTemplateParams(parent_decl_ctx_die));
16231624
qualified_name.insert(0, class_union_struct_name);
16241625
}
16251626
parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE();
@@ -1672,6 +1673,12 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
16721673
if (attrs.name) {
16731674
GetUniqueTypeNameAndDeclaration(die, cu_language, unique_typename,
16741675
unique_decl);
1676+
if (log) {
1677+
dwarf->GetObjectFile()->GetModule()->LogMessage(
1678+
log, "SymbolFileDWARF({0:p}) - {1:x16}: {2} has unique name: {3} ",
1679+
static_cast<void *>(this), die.GetID(), DW_TAG_value_to_name(tag),
1680+
unique_typename.AsCString());
1681+
}
16751682
if (UniqueDWARFASTType *unique_ast_entry_type =
16761683
dwarf->GetUniqueDWARFASTTypeMap().Find(
16771684
unique_typename, die, unique_decl, byte_size,

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@ class DWARFUnit;
2424
class DWARFDebugInfoEntry;
2525
class DWARFDeclContext;
2626
class SymbolFileDWARF;
27+
class DWARFFormValue;
2728

2829
class DWARFBaseDIE {
2930
public:
31+
using DWARFFormValue = dwarf::DWARFFormValue;
3032
DWARFBaseDIE() = default;
3133

3234
DWARFBaseDIE(DWARFUnit *cu, DWARFDebugInfoEntry *die)
@@ -46,6 +48,7 @@ class DWARFBaseDIE {
4648
explicit operator bool() const { return IsValid(); }
4749

4850
bool IsValid() const { return m_cu && m_die; }
51+
bool isValid() const { return IsValid(); }
4952

5053
bool HasChildren() const;
5154

@@ -85,6 +88,8 @@ class DWARFBaseDIE {
8588
// Accessing information about a DIE
8689
dw_tag_t Tag() const;
8790

91+
dw_tag_t getTag() const { return Tag(); }
92+
8893
dw_offset_t GetOffset() const;
8994

9095
// Get the LLDB user ID for this DIE. This is often just the DIE offset,
@@ -95,6 +100,8 @@ class DWARFBaseDIE {
95100

96101
const char *GetName() const;
97102

103+
const char *getShortName() const { return GetName(); }
104+
98105
lldb::ModuleSP GetModule() const;
99106

100107
// Getting attribute values from the DIE.

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,12 @@ elaborating_dies(const DWARFDIE &die) {
8686
}
8787
} // namespace
8888

89+
std::optional<uint64_t> DWARFDIE::getLanguage() const {
90+
if (IsValid())
91+
return m_cu->GetDWARFLanguageType();
92+
return std::nullopt;
93+
}
94+
8995
DWARFDIE
9096
DWARFDIE::GetParent() const {
9197
if (IsValid())
@@ -118,6 +124,22 @@ DWARFDIE::GetReferencedDIE(const dw_attr_t attr) const {
118124
return {};
119125
}
120126

127+
DWARFDIE DWARFDIE::resolveReferencedType(dw_attr_t attr) const {
128+
return GetReferencedDIE(attr);
129+
}
130+
131+
DWARFDIE DWARFDIE::resolveReferencedType(DWARFFormValue v) const {
132+
if (IsValid())
133+
return v.Reference();
134+
return {};
135+
}
136+
137+
DWARFDIE DWARFDIE::resolveTypeUnitReference() const {
138+
if (DWARFDIE reference = GetReferencedDIE(DW_AT_signature))
139+
return reference;
140+
return *this;
141+
}
142+
121143
DWARFDIE
122144
DWARFDIE::GetDIE(dw_offset_t die_offset) const {
123145
if (IsValid())
@@ -575,3 +597,16 @@ bool DWARFDIE::GetDIENamesAndRanges(
575597
llvm::iterator_range<DWARFDIE::child_iterator> DWARFDIE::children() const {
576598
return llvm::make_range(child_iterator(*this), child_iterator());
577599
}
600+
601+
DWARFDIE::child_iterator DWARFDIE::begin() const {
602+
return child_iterator(*this);
603+
}
604+
605+
DWARFDIE::child_iterator DWARFDIE::end() const { return child_iterator(); }
606+
607+
std::optional<DWARFFormValue> DWARFDIE::find(const dw_attr_t attr) const {
608+
DWARFFormValue form_value;
609+
if (m_die->GetAttributeValue(m_cu, attr, form_value, nullptr, false))
610+
return form_value;
611+
return std::nullopt;
612+
}

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,13 @@ class DWARFDIE : public DWARFBaseDIE {
4444

4545
// Functions for obtaining DIE relations and references
4646

47+
std::optional<uint64_t> getLanguage() const;
48+
4749
DWARFDIE
4850
GetParent() const;
4951

52+
DWARFDIE getParent() const { return GetParent(); }
53+
5054
DWARFDIE
5155
GetFirstChild() const;
5256

@@ -56,6 +60,12 @@ class DWARFDIE : public DWARFBaseDIE {
5660
DWARFDIE
5761
GetReferencedDIE(const dw_attr_t attr) const;
5862

63+
DWARFDIE resolveReferencedType(dw_attr_t attr) const;
64+
65+
DWARFDIE resolveReferencedType(DWARFFormValue v) const;
66+
67+
DWARFDIE resolveTypeUnitReference() const;
68+
5969
// Get a another DIE from the same DWARF file as this DIE. This will
6070
// check the current DIE's compile unit first to see if "die_offset" is
6171
// in the same compile unit, and fall back to checking the DWARF file.
@@ -96,6 +106,8 @@ class DWARFDIE : public DWARFBaseDIE {
96106
DWARFDIE
97107
GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const;
98108

109+
std::optional<DWARFFormValue> find(const dw_attr_t attr) const;
110+
99111
bool GetDIENamesAndRanges(
100112
const char *&name, const char *&mangled, DWARFRangeList &ranges,
101113
std::optional<int> &decl_file, std::optional<int> &decl_line,
@@ -105,6 +117,9 @@ class DWARFDIE : public DWARFBaseDIE {
105117

106118
/// The range of all the children of this DIE.
107119
llvm::iterator_range<child_iterator> children() const;
120+
121+
child_iterator begin() const;
122+
child_iterator end() const;
108123
};
109124

110125
class DWARFDIE::child_iterator

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,31 @@ uint64_t DWARFFormValue::Reference(dw_offset_t base_offset) const {
569569
}
570570
}
571571

572+
std::optional<uint64_t> DWARFFormValue::getAsUnsignedConstant() const {
573+
if ((!IsDataForm(m_form)) || m_form == lldb_private::dwarf::DW_FORM_sdata)
574+
return std::nullopt;
575+
return m_value.uval;
576+
}
577+
578+
std::optional<int64_t> DWARFFormValue::getAsSignedConstant() const {
579+
if ((!IsDataForm(m_form)) ||
580+
(m_form == lldb_private::dwarf::DW_FORM_udata &&
581+
uint64_t(std::numeric_limits<int64_t>::max()) < m_value.uval))
582+
return std::nullopt;
583+
switch (m_form) {
584+
case lldb_private::dwarf::DW_FORM_data4:
585+
return int32_t(m_value.uval);
586+
case lldb_private::dwarf::DW_FORM_data2:
587+
return int16_t(m_value.uval);
588+
case lldb_private::dwarf::DW_FORM_data1:
589+
return int8_t(m_value.uval);
590+
case lldb_private::dwarf::DW_FORM_sdata:
591+
case lldb_private::dwarf::DW_FORM_data8:
592+
default:
593+
return m_value.sval;
594+
}
595+
}
596+
572597
const uint8_t *DWARFFormValue::BlockData() const { return m_value.data; }
573598

574599
bool DWARFFormValue::IsBlockForm(const dw_form_t form) {

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,14 @@ class DWARFFormValue {
5858

5959
uint64_t Reference(dw_offset_t offset) const;
6060
bool Boolean() const { return m_value.uval != 0; }
61+
std::optional<uint64_t> getAsUnsignedConstant() const;
62+
std::optional<int64_t> getAsSignedConstant() const;
6163
uint64_t Unsigned() const { return m_value.uval; }
6264
void SetUnsigned(uint64_t uval) { m_value.uval = uval; }
6365
int64_t Signed() const { return m_value.sval; }
6466
void SetSigned(int64_t sval) { m_value.sval = sval; }
6567
const char *AsCString() const;
68+
const char *getAsCString() const { return AsCString(); }
6669
dw_addr_t Address() const;
6770
bool IsValid() const { return m_form != 0; }
6871
bool SkipValue(const DWARFDataExtractor &debug_info_data,

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

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "SymbolFileDWARF.h"
1010

1111
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
12+
#include "llvm/DebugInfo/DWARF/DWARFTypePrinter.h"
1213
#include "llvm/Support/Casting.h"
1314
#include "llvm/Support/FileUtilities.h"
1415
#include "llvm/Support/Format.h"
@@ -2821,33 +2822,14 @@ void SymbolFileDWARF::FindTypes(const TypeQuery &query, TypeResults &results) {
28212822
return true; // Keep iterating over index types, language mismatch.
28222823
}
28232824

2824-
// Check the context matches
2825-
std::vector<lldb_private::CompilerContext> die_context;
2826-
if (query.GetModuleSearch())
2827-
die_context = die.GetDeclContext();
2828-
else
2829-
die_context = die.GetTypeLookupContext();
2830-
assert(!die_context.empty());
2831-
if (!query_simple.ContextMatches(die_context))
2832-
return true; // Keep iterating over index types, context mismatch.
2833-
2834-
// Try to resolve the type.
2835-
if (Type *matching_type = ResolveType(die, true, true)) {
2836-
ConstString name = matching_type->GetQualifiedName();
2837-
// We have found a type that still might not match due to template
2838-
// parameters. If we create a new TypeQuery that uses the new type's
2839-
// fully qualified name, we can find out if this type matches at all
2840-
// context levels. We can't use just the "match_simple" context
2841-
// because all template parameters were stripped off. The fully
2842-
// qualified name of the type will have the template parameters and
2843-
// will allow us to make sure it matches correctly.
2844-
TypeQuery die_query(name.GetStringRef(),
2845-
TypeQueryOptions::e_exact_match);
2846-
if (!query.ContextMatches(die_query.GetContextRef()))
2847-
return true; // Keep iterating over index types, context mismatch.
2848-
2849-
results.InsertUnique(matching_type->shared_from_this());
2850-
}
2825+
std::string qualified_name;
2826+
llvm::raw_string_ostream os(qualified_name);
2827+
llvm::DWARFTypePrinter<DWARFDIE> type_printer(os);
2828+
type_printer.appendQualifiedName(die);
2829+
TypeQuery die_query(qualified_name, e_exact_match);
2830+
if (query.ContextMatches(die_query.GetContextRef()))
2831+
if (Type *matching_type = ResolveType(die, true, true))
2832+
results.InsertUnique(matching_type->shared_from_this());
28512833
return !results.Done(query); // Keep iterating if we aren't done.
28522834
});
28532835
if (results.Done(query)) {

lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1403,26 +1403,6 @@ static TemplateParameterList *CreateTemplateParameterList(
14031403
return template_param_list;
14041404
}
14051405

1406-
std::string TypeSystemClang::PrintTemplateParams(
1407-
const TemplateParameterInfos &template_param_infos) {
1408-
llvm::SmallVector<NamedDecl *, 8> ignore;
1409-
clang::TemplateParameterList *template_param_list =
1410-
CreateTemplateParameterList(getASTContext(), template_param_infos,
1411-
ignore);
1412-
llvm::SmallVector<clang::TemplateArgument, 2> args(
1413-
template_param_infos.GetArgs());
1414-
if (template_param_infos.hasParameterPack()) {
1415-
llvm::ArrayRef<TemplateArgument> pack_args =
1416-
template_param_infos.GetParameterPackArgs();
1417-
args.append(pack_args.begin(), pack_args.end());
1418-
}
1419-
std::string str;
1420-
llvm::raw_string_ostream os(str);
1421-
clang::printTemplateArgumentList(os, args, GetTypePrintingPolicy(),
1422-
template_param_list);
1423-
return str;
1424-
}
1425-
14261406
clang::FunctionTemplateDecl *TypeSystemClang::CreateFunctionTemplateDecl(
14271407
clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
14281408
clang::FunctionDecl *func_decl,

lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,10 +1148,6 @@ class TypeSystemClang : public TypeSystem {
11481148

11491149
bool SetDeclIsForcefullyCompleted(const clang::TagDecl *td);
11501150

1151-
/// Return the template parameters (including surrounding <>) in string form.
1152-
std::string
1153-
PrintTemplateParams(const TemplateParameterInfos &template_param_infos);
1154-
11551151
private:
11561152
/// Returns the PrintingPolicy used when generating the internal type names.
11571153
/// These type names are mostly used for the formatter selection.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Test lldb is able to compute the fully qualified names on templates with
2+
// -gsimple-template-names and -fdebug-types-section.
3+
4+
// REQUIRES: lld
5+
6+
// Test against logging to see if we print the fully qualified names correctly.
7+
// RUN: %clangxx --target=x86_64-pc-linux -g -gsimple-template-names %s -o %t
8+
// RUN: %lldb %t -o "log enable dwarf comp" -o "target variable v1 v2" -o exit | FileCheck %s --check-prefix=LOG
9+
10+
// Test that we following DW_AT_signature correctly. If not, lldb might confuse the types of v1 and v2.
11+
// RUN: %clangxx --target=x86_64-pc-linux -g -gsimple-template-names -fdebug-types-section %s -o %t
12+
// RUN: %lldb %t -o "target variable v1 v2" -o exit | FileCheck %s --check-prefix=TYPE
13+
14+
// LOG: unique name: ::t2<outer_struct1::t1<int> >
15+
// LOG: unique name: ::t2<outer_struct2::t1<int> >
16+
17+
// TYPE: (t2<outer_struct1::t1<int> >) v1 = {}
18+
// TYPE-NEXT: (t2<outer_struct2::t1<int> >) v2 = {}
19+
20+
struct outer_struct1 {
21+
template <typename> struct t1 {};
22+
};
23+
24+
struct outer_struct2 {
25+
template <typename> struct t1 {};
26+
};
27+
28+
template <typename> struct t2 {};
29+
t2<outer_struct1::t1<int>> v1;
30+
t2<outer_struct2::t1<int>> v2;
31+
int main() {}

llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,8 @@ class DWARFDie {
226226

227227
bool addressRangeContainsAddress(const uint64_t Address) const;
228228

229+
std::optional<uint64_t> getLanguage() const;
230+
229231
Expected<DWARFLocationExpressionsVector>
230232
getLocations(dwarf::Attribute Attr) const;
231233

0 commit comments

Comments
 (0)