diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h @@ -330,11 +330,15 @@ class TemplateParameterInfos { public: + struct ArgumentMetadata { + char const *const name = nullptr; + }; + TemplateParameterInfos() = default; - TemplateParameterInfos(llvm::ArrayRef names_in, + TemplateParameterInfos(llvm::ArrayRef metadata, llvm::ArrayRef args_in) - : names(names_in), args(args_in) { - assert(names.size() == args_in.size()); + : args_metadata(metadata), args(args_in) { + assert(metadata.size() == args_in.size()); } TemplateParameterInfos(TemplateParameterInfos const &) = delete; @@ -350,7 +354,7 @@ // these template parameters as invalid. if (pack_name && !packed_args) return false; - return args.size() == names.size() && + return args.size() == args_metadata.size() && (!packed_args || !packed_args->packed_args); } @@ -358,7 +362,9 @@ size_t Size() const { return args.size(); } llvm::ArrayRef GetArgs() const { return args; } - llvm::ArrayRef GetNames() const { return names; } + llvm::ArrayRef GetMetadata() const { + return args_metadata; + } clang::TemplateArgument const &Front() const { assert(!args.empty()); @@ -367,7 +373,7 @@ void InsertArg(char const *name, clang::TemplateArgument arg) { args.emplace_back(std::move(arg)); - names.push_back(name); + args_metadata.push_back({name}); } // Parameter pack related @@ -403,9 +409,9 @@ } private: - /// Element 'names[i]' holds the template argument name + /// Element 'args_metadata[i]' holds the template argument metadata /// of 'args[i]' - llvm::SmallVector names; + llvm::SmallVector args_metadata; llvm::SmallVector args; const char * pack_name = nullptr; diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -1382,9 +1382,9 @@ ast.getTranslationUnitDecl(); // Is this the right decl context?, auto const &args = template_param_infos.GetArgs(); - auto const &names = template_param_infos.GetNames(); + auto const &metadata = template_param_infos.GetMetadata(); for (size_t i = 0; i < num_template_params; ++i) { - const char *name = names[i]; + const char *name = metadata[i].name; IdentifierInfo *identifier_info = nullptr; if (name && name[0]) diff --git a/lldb/unittests/Symbol/TestTypeSystemClang.cpp b/lldb/unittests/Symbol/TestTypeSystemClang.cpp --- a/lldb/unittests/Symbol/TestTypeSystemClang.cpp +++ b/lldb/unittests/Symbol/TestTypeSystemClang.cpp @@ -615,47 +615,52 @@ // Test that with T = int creates a new template. ClassTemplateDecl *single_type_arg = - ExpectNewTemplate("", {{"T"}, {intArg1}}); + ExpectNewTemplate("", {{{"T"}}, {intArg1}}); // Test that changing the parameter name doesn't create a new class template. - ExpectReusedTemplate(" (A = int)", {{"A"}, {intArg1}}, + ExpectReusedTemplate(" (A = int)", {{{"A"}}, {intArg1}}, single_type_arg); // Test that changing the used type doesn't create a new class template. - ExpectReusedTemplate(" (A = float)", {{"A"}, {floatArg}}, + ExpectReusedTemplate(" (A = float)", {{{"A"}}, {floatArg}}, single_type_arg); // Test that creates a new template with A = int // and I = 47; ClassTemplateDecl *type_and_char_value = ExpectNewTemplate(" (I = 47)", - {{"A", "I"}, {floatArg, charArg1}}); + {{{"A"}, {"I"}}, {floatArg, charArg1}}); // Change the value of the I parameter to 123. The previously created // class template should still be reused. ExpectReusedTemplate(" (I = 123)", - {{"A", "I"}, {floatArg, charArg2}}, type_and_char_value); + {{{"A"}, {"I"}}, {floatArg, charArg2}}, + type_and_char_value); // Change the type of the I parameter to int so we have . // The class template from above can't be reused. ExpectNewTemplate(" (I = 123)", - {{"A", "I"}, {floatArg, intArg2}}); + {{{"A"}, {"I"}}, {floatArg, intArg2}}); // Test a second type parameter will also cause a new template to be created. // We now have . ClassTemplateDecl *type_and_char_value_and_type = ExpectNewTemplate("", - {{"A", "I", "B"}, {floatArg, intArg2, intArg1}}); + {{{"A"}, {"I"}, {"B"}}, {floatArg, intArg2, intArg1}}); // Remove all the names from the parameters which shouldn't influence the // way the templates get merged. ExpectReusedTemplate("", - {{"", "", ""}, {floatArg, intArg2, intArg1}}, + {{{""}, {""}, {""}}, {floatArg, intArg2, intArg1}}, type_and_char_value_and_type); } TEST_F(TestCreateClassTemplateDecl, FindExistingTemplatesWithParameterPack) { // The same as FindExistingTemplates but for templates with parameter packs. + + using ArgumentMetadata = + TypeSystemClang::TemplateParameterInfos::ArgumentMetadata; + TypeSystemClang::TemplateParameterInfos infos; clang::TemplateArgument intArg1(m_ast->getASTContext().IntTy); clang::TemplateArgument intArg2(m_ast->getASTContext(), @@ -671,7 +676,7 @@ infos.SetParameterPack( std::make_unique( - llvm::SmallVector{"", ""}, + llvm::SmallVector{{""}, {""}}, llvm::SmallVector{intArg1, intArg1})); ClassTemplateDecl *type_pack = @@ -687,42 +692,42 @@ // Change the type content of pack type values. infos.SetParameterPack( std::make_unique( - llvm::SmallVector{"", ""}, + llvm::SmallVector{{""}, {""}}, llvm::SmallVector{intArg1, longArg1})); ExpectReusedTemplate(" (int, long)", infos, type_pack); // Change the number of pack values. infos.SetParameterPack( std::make_unique( - llvm::SmallVector{""}, + llvm::SmallVector{{""}}, llvm::SmallVector{intArg1})); ExpectReusedTemplate(" (int)", infos, type_pack); // The names of the pack values shouldn't matter. infos.SetParameterPack( std::make_unique( - llvm::SmallVector{"A"}, + llvm::SmallVector{{"A"}}, llvm::SmallVector{intArg1})); ExpectReusedTemplate(" (int)", infos, type_pack); // Changing the kind of template argument will create a new template. infos.SetParameterPack( std::make_unique( - llvm::SmallVector{"A"}, + llvm::SmallVector{{"A"}}, llvm::SmallVector{intArg2})); ClassTemplateDecl *int_pack = ExpectNewTemplate(" (int = 1)", infos); // Changing the value of integral parameters will not create a new template. infos.SetParameterPack( std::make_unique( - llvm::SmallVector{"A"}, + llvm::SmallVector{{"A"}}, llvm::SmallVector{intArg3})); ExpectReusedTemplate(" (int = 123)", infos, int_pack); // Changing the integral type will create a new template. infos.SetParameterPack( std::make_unique( - llvm::SmallVector{"A"}, + llvm::SmallVector{{"A"}}, llvm::SmallVector{longArg2})); ExpectNewTemplate(" (long = 1)", infos);