diff --git a/lldb/include/lldb/Symbol/RustASTContext.h b/lldb/include/lldb/Symbol/RustASTContext.h index 390579c4a8872f..24b1e65bcda103 100644 --- a/lldb/include/lldb/Symbol/RustASTContext.h +++ b/lldb/include/lldb/Symbol/RustASTContext.h @@ -112,7 +112,8 @@ class RustASTContext : public TypeSystem { CompilerType CreateFunctionType(const lldb_private::ConstString &name, const CompilerType &return_type, - const std::vector &¶ms); + const std::vector &¶ms, + const std::vector &&template_params); CompilerType CreateStructType(const ConstString &name, uint32_t byte_size, bool has_discriminant); diff --git a/lldb/packages/Python/lldbsuite/test/lang/rust/types/TestRustASTContext.py b/lldb/packages/Python/lldbsuite/test/lang/rust/types/TestRustASTContext.py index 7e6f15867d8524..5f0832d68f7c25 100644 --- a/lldb/packages/Python/lldbsuite/test/lang/rust/types/TestRustASTContext.py +++ b/lldb/packages/Python/lldbsuite/test/lang/rust/types/TestRustASTContext.py @@ -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").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) diff --git a/lldb/packages/Python/lldbsuite/test/lang/rust/types/main.rs b/lldb/packages/Python/lldbsuite/test/lang/rust/types/main.rs index f294861d1600f0..30659b4b66d2c5 100644 --- a/lldb/packages/Python/lldbsuite/test/lang/rust/types/main.rs +++ b/lldb/packages/Python/lldbsuite/test/lang/rust/types/main.rs @@ -34,6 +34,8 @@ pub enum OptimizedEnum { pub struct Generic(T); +fn generic_function(arg: T) { } + fn main() { let vbool: bool = true; @@ -75,6 +77,7 @@ fn main() { let voptenum2 = OptimizedEnum::NonNull(Box::new(7)); let vgeneric = Generic(23i32); + generic_function(vgeneric.0); do_nothing(); // breakpoint } diff --git a/lldb/source/Plugins/ExpressionParser/Rust/RustParse.cpp b/lldb/source/Plugins/ExpressionParser/Rust/RustParse.cpp index 96f6942ec3ef0f..671429977cd572 100644 --- a/lldb/source/Plugins/ExpressionParser/Rust/RustParse.cpp +++ b/lldb/source/Plugins/ExpressionParser/Rust/RustParse.cpp @@ -1284,7 +1284,8 @@ RustFunctionTypeExpression::Evaluate(ExecutionContext &exe_ctx, Status &error) { args.push_back(argtype); } - return context->CreateFunctionType(ConstString(""), ret, std::move(args)); + std::vector empty; + return context->CreateFunctionType(ConstString(""), ret, std::move(args), std::move(empty)); } CompilerType diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserRust.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserRust.cpp index 7bd31a4be6034a..9815d82cb8bff3 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserRust.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserRust.cpp @@ -372,7 +372,9 @@ TypeSP DWARFASTParserRust::ParseFunctionType(const DWARFDIE &die) { return_type = m_ast.CreateVoidType(); } + SymbolFileDWARF *dwarf = die.GetDWARF(); std::vector function_param_types; + std::vector template_params; for (auto &&child_die : IterableDIEChildren(die)) { if (child_die.Tag() == DW_TAG_formal_parameter) { for (auto &&attr : IterableDIEAttrs(child_die)) { @@ -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::eResolveStateFull)); diff --git a/lldb/source/Symbol/RustASTContext.cpp b/lldb/source/Symbol/RustASTContext.cpp index 2b5277724bf728..c5b04608c7130d 100644 --- a/lldb/source/Symbol/RustASTContext.cpp +++ b/lldb/source/Symbol/RustASTContext.cpp @@ -712,11 +712,13 @@ class RustFunction : public RustType { public: RustFunction (const ConstString &name, uint64_t byte_size, const CompilerType &return_type, - const std::vector &&arguments) + const std::vector &&arguments, + const std::vector &&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); @@ -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 m_arguments; + std::vector m_template_args; }; class RustTypedef : public RustType { @@ -1921,8 +1932,10 @@ void RustASTContext::AddFieldToStruct(const CompilerType &struct_type, CompilerType RustASTContext::CreateFunctionType(const lldb_private::ConstString &name, const CompilerType &return_type, - const std::vector &¶ms) { - RustType *type = new RustFunction(name, m_pointer_byte_size, return_type, std::move(params)); + const std::vector &¶ms, + const std::vector &&template_params) { + RustType *type = new RustFunction(name, m_pointer_byte_size, return_type, std::move(params), + std::move(template_params)); return CacheType(type); } @@ -2168,6 +2181,8 @@ CompilerType RustASTContext::GetTypeTemplateArgument(lldb::opaque_compiler_type_ RustType *t = static_cast(type); if (RustAggregateBase *a = t->AsAggregate()) { return a->GetTypeTemplateArgument(idx); + } else if (RustFunction *f = t->AsFunction()) { + return f->GetTypeTemplateArgument(idx); } } return CompilerType(); @@ -2178,6 +2193,8 @@ size_t RustASTContext::GetNumTemplateArguments(lldb::opaque_compiler_type_t type RustType *t = static_cast(type); if (RustAggregateBase *a = t->AsAggregate()) { return a->GetNumTemplateArguments(); + } else if (RustFunction *f = t->AsFunction()) { + return f->GetNumTemplateArguments(); } } return 0;