Skip to content

Commit a0a03eb

Browse files
tromeynikic
authored andcommitted
Read template parameters for structure types
Read DW_TAG_template_type_parameter and apply to structure types.
1 parent 0da8ff0 commit a0a03eb

File tree

6 files changed

+83
-7
lines changed

6 files changed

+83
-7
lines changed

lldb/include/lldb/Symbol/RustASTContext.h

+9-2
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ class RustASTContext : public TypeSystem {
132132
bool is_default, uint64_t discriminant);
133133
void FinishAggregateInitialization(const CompilerType &type);
134134

135+
void AddTemplateParameter(const CompilerType &type, const CompilerType &param);
136+
135137
bool TypeHasDiscriminant(const CompilerType &type);
136138
bool IsTupleType(const CompilerType &type);
137139

@@ -327,10 +329,15 @@ class RustASTContext : public TypeSystem {
327329
const char *name, bool omit_empty_base_classes,
328330
std::vector<uint32_t> &child_indexes) override;
329331

330-
size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override {
331-
return 0;
332+
lldb::TemplateArgumentKind GetTemplateArgumentKind(lldb::opaque_compiler_type_t type,
333+
size_t idx) override {
334+
// Rust currently only has types.
335+
return lldb::eTemplateArgumentKindType;
332336
}
333337

338+
CompilerType GetTypeTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx) override;
339+
size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override;
340+
334341
//----------------------------------------------------------------------
335342
// Dumping types
336343
//----------------------------------------------------------------------

lldb/packages/Python/lldbsuite/test/lang/rust/types/TestRustASTContext.py

+8
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ def test_with_dsym_and_python_api(self):
2626
self.check_main_function()
2727
self.check_structs()
2828
self.check_enums()
29+
self.check_generics()
2930

3031
def setUp(self):
3132
# Call super's setUp().
@@ -167,7 +168,14 @@ def check_enums(self):
167168
# See https://github.com/rust-lang-nursery/lldb/issues/24
168169
# self.assertEqual(name, v.GetType().name)
169170
self.assertEqual(size, v.GetType().GetByteSize())
171+
self.assertEqual(0, v.GetType().num_template_args)
170172
# Some values can't really be checked.
171173
if value is not None:
172174
expected = "(" + name + ") " + vname + " = " + value
173175
self.assertEqual(expected, str(v.dynamic))
176+
177+
def check_generics(self):
178+
t = self.var('vgeneric').GetType()
179+
self.assertEqual(1, t.num_template_args)
180+
self.assertEqual('T', t.template_args[0].name)
181+
self.assertEqual('i32', t.template_args[0].GetTypedefedType().name)

lldb/packages/Python/lldbsuite/test/lang/rust/types/main.rs

+4
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ pub enum OptimizedEnum {
3232
NonNull(Box<u8>)
3333
}
3434

35+
pub struct Generic<T>(T);
36+
3537
fn main() {
3638
let vbool: bool = true;
3739

@@ -72,5 +74,7 @@ fn main() {
7274
let voptenum = OptimizedEnum::Null;
7375
let voptenum2 = OptimizedEnum::NonNull(Box::new(7));
7476

77+
let vgeneric = Generic(23i32);
78+
7579
do_nothing(); // breakpoint
7680
}

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

+14-4
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,7 @@ std::vector<DWARFASTParserRust::Field>
491491
DWARFASTParserRust::ParseFields(const DWARFDIE &die, std::vector<size_t> &discriminant_path,
492492
bool &is_tuple,
493493
uint64_t &discr_offset, uint64_t &discr_byte_size,
494-
bool &saw_discr) {
494+
bool &saw_discr, std::vector<CompilerType> &template_params) {
495495
SymbolFileDWARF *dwarf = die.GetDWARF();
496496

497497
// We construct a list of fields and then apply them later so that
@@ -631,8 +631,8 @@ DWARFASTParserRust::ParseFields(const DWARFDIE &die, std::vector<size_t> &discri
631631
// New-style enum representation -- nothing useful is in the
632632
// enclosing struct, so we can just recurse here.
633633
return ParseFields(child_die, discriminant_path, is_tuple,
634-
discr_offset, discr_byte_size, saw_discr);
635-
} else {
634+
discr_offset, discr_byte_size, saw_discr, template_params);
635+
} else if (child_die.Tag() == DW_TAG_member) {
636636
if (new_field.is_discriminant) {
637637
// Don't check this field name, and don't increment field_index.
638638
// When we see a tuple with fields like
@@ -650,6 +650,11 @@ DWARFASTParserRust::ParseFields(const DWARFDIE &die, std::vector<size_t> &discri
650650
}
651651

652652
fields.push_back(new_field);
653+
} else if (child_die.Tag() == DW_TAG_template_type_parameter) {
654+
Type *param_type = dwarf->ResolveTypeUID(child_die, true);
655+
if (param_type) {
656+
template_params.push_back(param_type->GetForwardCompilerType());
657+
}
653658
}
654659
}
655660

@@ -728,8 +733,10 @@ TypeSP DWARFASTParserRust::ParseStructureType(const DWARFDIE &die) {
728733
bool saw_discr = false;
729734
uint64_t discr_offset, discr_byte_size;
730735
std::vector<size_t> discriminant_path;
736+
std::vector<CompilerType> template_params;
731737
std::vector<Field> fields = ParseFields(die, discriminant_path, is_tuple,
732-
discr_offset, discr_byte_size, saw_discr);
738+
discr_offset, discr_byte_size, saw_discr,
739+
template_params);
733740

734741
// This is true if this is a union, there are multiple fields and
735742
// each field's type has a discriminant.
@@ -834,6 +841,9 @@ TypeSP DWARFASTParserRust::ParseStructureType(const DWARFDIE &die) {
834841
}
835842
}
836843

844+
for (const CompilerType &param_type : template_params)
845+
m_ast.AddTemplateParameter(compiler_type, param_type);
846+
837847
m_ast.FinishAggregateInitialization(compiler_type);
838848

839849
// Add our type to the unique type map so we don't

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ class DWARFASTParserRust : public DWARFASTParser {
104104
std::vector<size_t> &discriminant_path,
105105
bool &is_tuple,
106106
uint64_t &discr_offset, uint64_t &discr_byte_size,
107-
bool &saw_discr);
107+
bool &saw_discr,
108+
std::vector<lldb_private::CompilerType> &template_params);
108109

109110
lldb_private::RustASTContext &m_ast;
110111

lldb/source/Symbol/RustASTContext.cpp

+46
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,10 @@ class RustAggregateBase : public RustType {
400400
m_fields.emplace_back(name, type, offset);
401401
}
402402

403+
void AddTemplateParameter(const CompilerType &ctype) {
404+
m_template_args.push_back(ctype);
405+
}
406+
403407
virtual void FinishInitialization() {
404408
}
405409

@@ -423,6 +427,14 @@ class RustAggregateBase : public RustType {
423427
return &m_fields[idx];
424428
}
425429

430+
size_t GetNumTemplateArguments() const {
431+
return m_template_args.size();
432+
}
433+
434+
CompilerType GetTypeTemplateArgument(size_t idx) const {
435+
return m_template_args[idx];
436+
}
437+
426438
typedef std::vector<Field>::const_iterator const_iterator;
427439

428440
const_iterator begin() const {
@@ -472,6 +484,7 @@ class RustAggregateBase : public RustType {
472484
uint64_t m_byte_size;
473485
std::vector<Field> m_fields;
474486
bool m_has_discriminant;
487+
std::vector<CompilerType> m_template_args;
475488
};
476489

477490
class RustTuple : public RustAggregateBase {
@@ -2148,3 +2161,36 @@ bool RustASTContext::GetCABITypeDeclaration(CompilerType type, const std::string
21482161
*result = rtype->GetCABITypeDeclaration(name_map, varname);
21492162
return true;
21502163
}
2164+
2165+
CompilerType RustASTContext::GetTypeTemplateArgument(lldb::opaque_compiler_type_t type,
2166+
size_t idx) {
2167+
if (type) {
2168+
RustType *t = static_cast<RustType *>(type);
2169+
if (RustAggregateBase *a = t->AsAggregate()) {
2170+
return a->GetTypeTemplateArgument(idx);
2171+
}
2172+
}
2173+
return CompilerType();
2174+
}
2175+
2176+
size_t RustASTContext::GetNumTemplateArguments(lldb::opaque_compiler_type_t type) {
2177+
if (type) {
2178+
RustType *t = static_cast<RustType *>(type);
2179+
if (RustAggregateBase *a = t->AsAggregate()) {
2180+
return a->GetNumTemplateArguments();
2181+
}
2182+
}
2183+
return 0;
2184+
}
2185+
2186+
void RustASTContext::AddTemplateParameter(const CompilerType &type, const CompilerType &param) {
2187+
if (!type)
2188+
return;
2189+
RustASTContext *ast = llvm::dyn_cast_or_null<RustASTContext>(type.GetTypeSystem());
2190+
if (!ast)
2191+
return;
2192+
RustType *t = static_cast<RustType *>(type.GetOpaqueQualType());
2193+
if (RustAggregateBase *a = t->AsAggregate()) {
2194+
a->AddTemplateParameter(param);
2195+
}
2196+
}

0 commit comments

Comments
 (0)