Skip to content

Commit

Permalink
Read template parameters for function types
Browse files Browse the repository at this point in the history
Read DW_TAG_template_type_parameter and apply to function types.

Closes llvm#5

Signed-off-by: Gabor Greif <gabor@dfinity.org>
  • Loading branch information
tromey authored and ggreif committed Oct 9, 2020
1 parent e1b25a0 commit 118d4aa
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 8 deletions.
3 changes: 2 additions & 1 deletion lldb/include/lldb/Symbol/RustASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ class RustASTContext : public TypeSystem {

CompilerType CreateFunctionType(const lldb_private::ConstString &name,
const CompilerType &return_type,
const std::vector<CompilerType> &&params);
const std::vector<CompilerType> &&params,
const std::vector<CompilerType> &&template_params);

CompilerType CreateStructType(const ConstString &name, uint32_t byte_size,
bool has_discriminant);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,3 +179,7 @@ def check_generics(self):
self.assertEqual(1, t.num_template_args)
self.assertEqual('T', t.template_args[0].name)
self.assertEqual('i32', t.template_args[0].GetTypedefedType().name)
t = self.frame().EvaluateExpression("generic_function<i32>").GetType().GetPointeeType()
self.assertEqual(1, t.num_template_args)
self.assertEqual('T', t.template_args[0].name)
self.assertEqual('i32', t.template_args[0].GetTypedefedType().name)
3 changes: 3 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 @@ -34,6 +34,8 @@ pub enum OptimizedEnum {

pub struct Generic<T>(T);

fn generic_function<T>(arg: T) { }

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

Expand Down Expand Up @@ -75,6 +77,7 @@ fn main() {
let voptenum2 = OptimizedEnum::NonNull(Box::new(7));

let vgeneric = Generic(23i32);
generic_function(vgeneric.0);

do_nothing(); // breakpoint
}
3 changes: 2 additions & 1 deletion lldb/source/Plugins/ExpressionParser/Rust/RustParse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1283,7 +1283,8 @@ RustFunctionTypeExpression::Evaluate(ExecutionContext &exe_ctx, Status &error) {
args.push_back(argtype);
}

return context->CreateFunctionType(ConstString(""), ret, std::move(args));
std::vector<CompilerType> empty;
return context->CreateFunctionType(ConstString(""), ret, std::move(args), std::move(empty));
}

CompilerType
Expand Down
11 changes: 9 additions & 2 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserRust.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,9 @@ TypeSP DWARFASTParserRust::ParseFunctionType(const DWARFDIE &die) {
return_type = m_ast.CreateVoidType();
}

SymbolFileDWARF *dwarf = die.GetDWARF();
std::vector<CompilerType> function_param_types;
std::vector<CompilerType> template_params;
for (auto &&child_die : IterableDIEChildren(die)) {
if (child_die.Tag() == DW_TAG_formal_parameter) {
for (auto &&attr : IterableDIEAttrs(child_die)) {
Expand All @@ -384,13 +386,18 @@ TypeSP DWARFASTParserRust::ParseFunctionType(const DWARFDIE &die) {
break;
}
}
} 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());
}
}
}

CompilerType compiler_type = m_ast.CreateFunctionType(type_name_const_str, return_type,
std::move(function_param_types));
std::move(function_param_types),
std::move(template_params));

SymbolFileDWARF *dwarf = die.GetDWARF();
TypeSP type_sp(new Type(die.GetID(), dwarf, type_name_const_str, 0, NULL,
LLDB_INVALID_UID, Type::eEncodingIsUID, &decl,
compiler_type, Type::ResolveState::Full));
Expand Down
25 changes: 21 additions & 4 deletions lldb/source/Symbol/RustASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -712,11 +712,13 @@ class RustFunction : public RustType {
public:
RustFunction (const ConstString &name, uint64_t byte_size,
const CompilerType &return_type,
const std::vector<CompilerType> &&arguments)
const std::vector<CompilerType> &&arguments,
const std::vector<CompilerType> &&template_arguments)
: RustType(name),
m_byte_size(byte_size),
m_return_type(return_type),
m_arguments(std::move(arguments))
m_arguments(std::move(arguments)),
m_template_args(std::move(template_arguments))
{
}
DISALLOW_COPY_AND_ASSIGN(RustFunction);
Expand Down Expand Up @@ -763,11 +765,20 @@ class RustFunction : public RustType {
return result + ")";
}

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

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

private:

uint64_t m_byte_size;
CompilerType m_return_type;
std::vector<CompilerType> m_arguments;
std::vector<CompilerType> m_template_args;
};

class RustTypedef : public RustType {
Expand Down Expand Up @@ -1953,8 +1964,10 @@ void RustASTContext::AddFieldToStruct(const CompilerType &struct_type,
CompilerType
RustASTContext::CreateFunctionType(const lldb_private::ConstString &name,
const CompilerType &return_type,
const std::vector<CompilerType> &&params) {
RustType *type = new RustFunction(name, m_pointer_byte_size, return_type, std::move(params));
const std::vector<CompilerType> &&params,
const std::vector<CompilerType> &&template_params) {
RustType *type = new RustFunction(name, m_pointer_byte_size, return_type, std::move(params),
std::move(template_params));
return CacheType(type);
}

Expand Down Expand Up @@ -2233,6 +2246,8 @@ CompilerType RustASTContext::GetTypeTemplateArgument(lldb::opaque_compiler_type_
RustType *t = static_cast<RustType *>(type);
if (RustAggregateBase *a = t->AsAggregate()) {
return a->GetTypeTemplateArgument(idx);
} else if (RustFunction *f = t->AsFunction()) {
return f->GetTypeTemplateArgument(idx);
}
}
return CompilerType();
Expand All @@ -2243,6 +2258,8 @@ size_t RustASTContext::GetNumTemplateArguments(lldb::opaque_compiler_type_t type
RustType *t = static_cast<RustType *>(type);
if (RustAggregateBase *a = t->AsAggregate()) {
return a->GetNumTemplateArguments();
} else if (RustFunction *f = t->AsFunction()) {
return f->GetNumTemplateArguments();
}
}
return 0;
Expand Down

0 comments on commit 118d4aa

Please sign in to comment.