Skip to content

Commit

Permalink
Read template parameters for structure types
Browse files Browse the repository at this point in the history
Read DW_TAG_template_type_parameter and apply to structure types.
  • Loading branch information
tromey authored and cuviper committed Mar 18, 2019
1 parent 196b3a1 commit 5d04940
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 7 deletions.
11 changes: 9 additions & 2 deletions lldb/include/lldb/Symbol/RustASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ class RustASTContext : public TypeSystem {
bool is_default, uint64_t discriminant);
void FinishAggregateInitialization(const CompilerType &type);

void AddTemplateParameter(const CompilerType &type, const CompilerType &param);

bool TypeHasDiscriminant(const CompilerType &type);
bool IsTupleType(const CompilerType &type);

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

size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override {
return 0;
lldb::TemplateArgumentKind GetTemplateArgumentKind(lldb::opaque_compiler_type_t type,
size_t idx) override {
// Rust currently only has types.
return lldb::eTemplateArgumentKindType;
}

CompilerType GetTypeTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx) override;
size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override;

//----------------------------------------------------------------------
// Dumping types
//----------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def test_with_dsym_and_python_api(self):
self.check_main_function()
self.check_structs()
self.check_enums()
self.check_generics()

def setUp(self):
# Call super's setUp().
Expand Down Expand Up @@ -167,7 +168,14 @@ def check_enums(self):
# See https://github.com/rust-lang-nursery/lldb/issues/24
# self.assertEqual(name, v.GetType().name)
self.assertEqual(size, v.GetType().GetByteSize())
self.assertEqual(0, v.GetType().num_template_args)
# Some values can't really be checked.
if value is not None:
expected = "(" + name + ") " + vname + " = " + value
self.assertEqual(expected, str(v.dynamic))

def check_generics(self):
t = self.var('vgeneric').GetType()
self.assertEqual(1, t.num_template_args)
self.assertEqual('T', t.template_args[0].name)
self.assertEqual('i32', t.template_args[0].GetTypedefedType().name)
4 changes: 4 additions & 0 deletions lldb/packages/Python/lldbsuite/test/lang/rust/types/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ pub enum OptimizedEnum {
NonNull(Box<u8>)
}

pub struct Generic<T>(T);

fn main() {
let vbool: bool = true;

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

let vgeneric = Generic(23i32);

do_nothing(); // breakpoint
}
18 changes: 14 additions & 4 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserRust.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ std::vector<DWARFASTParserRust::Field>
DWARFASTParserRust::ParseFields(const DWARFDIE &die, std::vector<size_t> &discriminant_path,
bool &is_tuple,
uint64_t &discr_offset, uint64_t &discr_byte_size,
bool &saw_discr) {
bool &saw_discr, std::vector<CompilerType> &template_params) {
SymbolFileDWARF *dwarf = die.GetDWARF();

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

fields.push_back(new_field);
} else if (child_die.Tag() == DW_TAG_template_type_parameter) {
Type *param_type = dwarf->ResolveTypeUID(child_die, true);
if (param_type) {
template_params.push_back(param_type->GetForwardCompilerType());
}
}
}

Expand Down Expand Up @@ -728,8 +733,10 @@ TypeSP DWARFASTParserRust::ParseStructureType(const DWARFDIE &die) {
bool saw_discr = false;
uint64_t discr_offset, discr_byte_size;
std::vector<size_t> discriminant_path;
std::vector<CompilerType> template_params;
std::vector<Field> fields = ParseFields(die, discriminant_path, is_tuple,
discr_offset, discr_byte_size, saw_discr);
discr_offset, discr_byte_size, saw_discr,
template_params);

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

for (const CompilerType &param_type : template_params)
m_ast.AddTemplateParameter(compiler_type, param_type);

m_ast.FinishAggregateInitialization(compiler_type);

// Add our type to the unique type map so we don't
Expand Down
3 changes: 2 additions & 1 deletion lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserRust.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ class DWARFASTParserRust : public DWARFASTParser {
std::vector<size_t> &discriminant_path,
bool &is_tuple,
uint64_t &discr_offset, uint64_t &discr_byte_size,
bool &saw_discr);
bool &saw_discr,
std::vector<lldb_private::CompilerType> &template_params);

lldb_private::RustASTContext &m_ast;

Expand Down
46 changes: 46 additions & 0 deletions lldb/source/Symbol/RustASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,10 @@ class RustAggregateBase : public RustType {
m_fields.emplace_back(name, type, offset);
}

void AddTemplateParameter(const CompilerType &ctype) {
m_template_args.push_back(ctype);
}

virtual void FinishInitialization() {
}

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

size_t GetNumTemplateArguments() const {
return m_template_args.size();
}

CompilerType GetTypeTemplateArgument(size_t idx) const {
return m_template_args[idx];
}

typedef std::vector<Field>::const_iterator const_iterator;

const_iterator begin() const {
Expand Down Expand Up @@ -472,6 +484,7 @@ class RustAggregateBase : public RustType {
uint64_t m_byte_size;
std::vector<Field> m_fields;
bool m_has_discriminant;
std::vector<CompilerType> m_template_args;
};

class RustTuple : public RustAggregateBase {
Expand Down Expand Up @@ -2148,3 +2161,36 @@ bool RustASTContext::GetCABITypeDeclaration(CompilerType type, const std::string
*result = rtype->GetCABITypeDeclaration(name_map, varname);
return true;
}

CompilerType RustASTContext::GetTypeTemplateArgument(lldb::opaque_compiler_type_t type,
size_t idx) {
if (type) {
RustType *t = static_cast<RustType *>(type);
if (RustAggregateBase *a = t->AsAggregate()) {
return a->GetTypeTemplateArgument(idx);
}
}
return CompilerType();
}

size_t RustASTContext::GetNumTemplateArguments(lldb::opaque_compiler_type_t type) {
if (type) {
RustType *t = static_cast<RustType *>(type);
if (RustAggregateBase *a = t->AsAggregate()) {
return a->GetNumTemplateArguments();
}
}
return 0;
}

void RustASTContext::AddTemplateParameter(const CompilerType &type, const CompilerType &param) {
if (!type)
return;
RustASTContext *ast = llvm::dyn_cast_or_null<RustASTContext>(type.GetTypeSystem());
if (!ast)
return;
RustType *t = static_cast<RustType *>(type.GetOpaqueQualType());
if (RustAggregateBase *a = t->AsAggregate()) {
a->AddTemplateParameter(param);
}
}

0 comments on commit 5d04940

Please sign in to comment.