diff --git a/src/lib_cxx/data/parser/cxx/CxxAstVisitor.cpp b/src/lib_cxx/data/parser/cxx/CxxAstVisitor.cpp index 98de6d3a..4ba2a61c 100644 --- a/src/lib_cxx/data/parser/cxx/CxxAstVisitor.cpp +++ b/src/lib_cxx/data/parser/cxx/CxxAstVisitor.cpp @@ -66,7 +66,6 @@ CanonicalFilePathCache* CxxAstVisitor::getCanonicalFilePathCache() const void CxxAstVisitor::indexDecl(clang::Decl* d) { LOG_INFO("starting AST traversal"); - //d->dump(); this->TraverseDecl(d); } diff --git a/src/lib_cxx/data/parser/cxx/name_resolver/CxxDeclNameResolver.cpp b/src/lib_cxx/data/parser/cxx/name_resolver/CxxDeclNameResolver.cpp index 83dc7f46..a84cc2ca 100644 --- a/src/lib_cxx/data/parser/cxx/name_resolver/CxxDeclNameResolver.cpp +++ b/src/lib_cxx/data/parser/cxx/name_resolver/CxxDeclNameResolver.cpp @@ -239,6 +239,17 @@ std::unique_ptr CxxDeclNameResolver::getDeclName(const clang::Named std::vector> parameterTypeNames; for (unsigned int i = 0; i < functionDecl->param_size(); i++) { + if (const clang::SubstTemplateTypeParmType* substType = clang::dyn_cast_or_null(functionDecl->parameters()[i]->getType().getTypePtr())) + { + if (const clang::TemplateTypeParmType* templateParamType = substType->getReplacedParameter()) + { + if (templateParamType->isParameterPack()) + { + parameterTypeNames.push_back(std::make_unique(L"...")); + break; + } + } + } parameterTypeNames.push_back( CxxTypeName::makeUnsolvedIfNull(typenNameResolver.getName(functionDecl->parameters()[i]->getType()))); } diff --git a/src/lib_cxx/data/parser/cxx/name_resolver/CxxTemplateArgumentNameResolver.cpp b/src/lib_cxx/data/parser/cxx/name_resolver/CxxTemplateArgumentNameResolver.cpp index 12d00f44..58cbd0b2 100644 --- a/src/lib_cxx/data/parser/cxx/name_resolver/CxxTemplateArgumentNameResolver.cpp +++ b/src/lib_cxx/data/parser/cxx/name_resolver/CxxTemplateArgumentNameResolver.cpp @@ -50,20 +50,7 @@ std::wstring CxxTemplateArgumentNameResolver::getTemplateArgumentName(const clan } case clang::TemplateArgument::Pack: { - std::wstringstream ss; - ss << L'<'; - llvm::ArrayRef pack = argument.getPackAsArray(); - for (size_t i = 0; i < pack.size(); i++) - { - if (i > 0) - { - ss << L", "; - } - ss << getTemplateArgumentName(pack[i]); - } - ss << L'>'; - - return ss.str(); + return L"<...>"; } } diff --git a/src/test/CxxParserTestSuite.h b/src/test/CxxParserTestSuite.h index d38191fd..98087715 100644 --- a/src/test/CxxParserTestSuite.h +++ b/src/test/CxxParserTestSuite.h @@ -15,6 +15,26 @@ class CxxParserTestSuite: public CxxTest::TestSuite { public: + void test_cxx_parser_creates_single_node_for_all_possible_parameter_pack_expansions_of_template_function() + { + std::shared_ptr client = parseCode( + "template\n" + "T adder(T v) { return v; }\n" + "\n" + "template\n" + "T adder(T first, Args... args) { return first + adder(args...); }\n" + "\n" + "void foo() { long sum = adder(1, 2, 3, 8, 7); }\n" + ); + + TS_ASSERT(utility::containsElement( + client->functions, L"int adder>(int, ...) <5:1 <5:1 <5:3 5:7> 5:30> 5:65>" + )); + TS_ASSERT(utility::containsElement( + client->calls, L"int adder>(int, ...) -> int adder>(int, ...) <5:49 5:53>" + )); + } + void test_record_base_class_of_implicit_template_class_specialization() { std::shared_ptr client = parseCode( @@ -3204,10 +3224,10 @@ public: ); TS_ASSERT(utility::containsElement( - client->typeUses, L"A<> -> int <7:6 7:8>" + client->typeUses, L"A<<...>> -> int <7:6 7:8>" )); TS_ASSERT(utility::containsElement( - client->typeUses, L"A<> -> float <7:11 7:15>" + client->typeUses, L"A<<...>> -> float <7:11 7:15>" )); TS_ASSERT(utility::containsElement( client->typeUses, L"int main() -> int <7:6 7:8>" @@ -3432,10 +3452,10 @@ public: ); TS_ASSERT(utility::containsElement( - client->typeUses, L"B<> -> A <11:4 11:4>" + client->typeUses, L"B<<...>> -> A <11:4 11:4>" )); TS_ASSERT(utility::containsElement( - client->typeUses, L"B<> -> A <11:7 11:7>" + client->typeUses, L"B<<...>> -> A <11:7 11:7>" )); TS_ASSERT(utility::containsElement( client->typeUses, L"int main() -> A <11:4 11:4>"