Skip to content

Commit e1b25a0

Browse files
tromeyggreif
authored andcommitted
Read template parameters for structure types
Read DW_TAG_template_type_parameter and apply to structure types. Signed-off-by: Gabor Greif <[email protected]>
1 parent 92c48ef commit e1b25a0

File tree

6 files changed

+83
-7
lines changed

6 files changed

+83
-7
lines changed

lldb/include/lldb/Symbol/RustASTContext.h

Lines changed: 9 additions & 2 deletions
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

@@ -333,10 +335,15 @@ class RustASTContext : public TypeSystem {
333335
const char *name, bool omit_empty_base_classes,
334336
std::vector<uint32_t> &child_indexes) override;
335337

336-
size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override {
337-
return 0;
338+
lldb::TemplateArgumentKind GetTemplateArgumentKind(lldb::opaque_compiler_type_t type,
339+
size_t idx) override {
340+
// Rust currently only has types.
341+
return lldb::eTemplateArgumentKindType;
338342
}
339343

344+
CompilerType GetTypeTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx) override;
345+
size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override;
346+
340347
//----------------------------------------------------------------------
341348
// Dumping types
342349
//----------------------------------------------------------------------

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

Lines changed: 8 additions & 0 deletions
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

Lines changed: 4 additions & 0 deletions
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

Lines changed: 14 additions & 4 deletions
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
@@ -632,8 +632,8 @@ DWARFASTParserRust::ParseFields(const DWARFDIE &die, std::vector<size_t> &discri
632632
// New-style enum representation -- nothing useful is in the
633633
// enclosing struct, so we can just recurse here.
634634
return ParseFields(child_die, discriminant_path, is_tuple,
635-
discr_offset, discr_byte_size, saw_discr);
636-
} else {
635+
discr_offset, discr_byte_size, saw_discr, template_params);
636+
} else if (child_die.Tag() == DW_TAG_member) {
637637
if (new_field.is_discriminant) {
638638
// Don't check this field name, and don't increment field_index.
639639
// When we see a tuple with fields like
@@ -651,6 +651,11 @@ DWARFASTParserRust::ParseFields(const DWARFDIE &die, std::vector<size_t> &discri
651651
}
652652

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

@@ -729,8 +734,10 @@ TypeSP DWARFASTParserRust::ParseStructureType(const DWARFDIE &die) {
729734
bool saw_discr = false;
730735
uint64_t discr_offset, discr_byte_size;
731736
std::vector<size_t> discriminant_path;
737+
std::vector<CompilerType> template_params;
732738
std::vector<Field> fields = ParseFields(die, discriminant_path, is_tuple,
733-
discr_offset, discr_byte_size, saw_discr);
739+
discr_offset, discr_byte_size, saw_discr,
740+
template_params);
734741

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

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

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

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ class DWARFASTParserRust : public DWARFASTParser {
107107
std::vector<size_t> &discriminant_path,
108108
bool &is_tuple,
109109
uint64_t &discr_offset, uint64_t &discr_byte_size,
110-
bool &saw_discr);
110+
bool &saw_discr,
111+
std::vector<lldb_private::CompilerType> &template_params);
111112

112113
lldb_private::RustASTContext &m_ast;
113114

lldb/source/Symbol/RustASTContext.cpp

Lines changed: 46 additions & 0 deletions
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 {
@@ -2213,3 +2226,36 @@ bool RustASTContext::GetCABITypeDeclaration(CompilerType type, const std::string
22132226
*result = rtype->GetCABITypeDeclaration(name_map, varname);
22142227
return true;
22152228
}
2229+
2230+
CompilerType RustASTContext::GetTypeTemplateArgument(lldb::opaque_compiler_type_t type,
2231+
size_t idx) {
2232+
if (type) {
2233+
RustType *t = static_cast<RustType *>(type);
2234+
if (RustAggregateBase *a = t->AsAggregate()) {
2235+
return a->GetTypeTemplateArgument(idx);
2236+
}
2237+
}
2238+
return CompilerType();
2239+
}
2240+
2241+
size_t RustASTContext::GetNumTemplateArguments(lldb::opaque_compiler_type_t type) {
2242+
if (type) {
2243+
RustType *t = static_cast<RustType *>(type);
2244+
if (RustAggregateBase *a = t->AsAggregate()) {
2245+
return a->GetNumTemplateArguments();
2246+
}
2247+
}
2248+
return 0;
2249+
}
2250+
2251+
void RustASTContext::AddTemplateParameter(const CompilerType &type, const CompilerType &param) {
2252+
if (!type)
2253+
return;
2254+
RustASTContext *ast = llvm::dyn_cast_or_null<RustASTContext>(type.GetTypeSystem());
2255+
if (!ast)
2256+
return;
2257+
RustType *t = static_cast<RustType *>(type.GetOpaqueQualType());
2258+
if (RustAggregateBase *a = t->AsAggregate()) {
2259+
a->AddTemplateParameter(param);
2260+
}
2261+
}

0 commit comments

Comments
 (0)