diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index f4b7706d6..1fa2dacd2 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -1080,8 +1080,34 @@ void TemplateSimplifier::expandTemplate( dst->insertToken(newName, "", true); if (start->strAt(1) == "<") start = start->next()->findClosingBracket(); - } else - dst->insertToken(start->str(), "", true); + } else { + // check if type is a template + if (start->strAt(1) == "<") { + // get the instantiated name + Token * closing = start->next()->findClosingBracket(); + std::string name; + const Token * type = start; + while (type && type != closing->next()) { + if (!name.empty()) + name += " "; + name += type->str(); + type = type->next(); + } + // check if type is instantiated + for (const auto & inst : mTemplateInstantiations) { + if (Token::simpleMatch(inst.nameToken, name.c_str())) { + // use the instantiated name + dst->insertToken(name, "", true); + start = closing; + break; + } + } + // just copy the token if it wasn't instantiated + if (start != closing) + dst->insertToken(start->str(), "", true); + } else + dst->insertToken(start->str(), "", true); + } if (start->link()) { if (Token::Match(start, "[|{|(")) { links[start->link()] = dst->previous(); diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp index 786ec42cb..adafba8db 100644 --- a/test/testsimplifytemplate.cpp +++ b/test/testsimplifytemplate.cpp @@ -119,6 +119,7 @@ private: TEST_CASE(template79); // #5133 TEST_CASE(template80); TEST_CASE(template81); + TEST_CASE(template82); // 8603 TEST_CASE(template_specialization_1); // #7868 - template specialization template struct S> {..}; TEST_CASE(template_specialization_2); // #7868 - template specialization template struct S> {..}; TEST_CASE(template_enum); // #6299 Syntax error in complex enum declaration (including template) @@ -1554,6 +1555,44 @@ private: ASSERT_EQUALS(exp, tok(code)); } + void template82() { // 8603 + const char code[] = "typedef int comp;\n" + "const int f16=16;\n" + "template\n" + "class tvec2 {};\n" + "template\n" + "class tvec3 {};\n" + "namespace swizzle {\n" + "template void swizzle(tvec2 v) { }\n" + "template void swizzle(tvec3 v) { }\n" + "}\n" + "void foo() {\n" + " using namespace swizzle;\n" + " tvec2 tt2;\n" + " swizzle<1>(tt2);\n" + " tvec3 tt3;\n" + " swizzle<2,3>(tt3);\n" + "}"; + const char exp[] = "class tvec2 ; " + "class tvec3 ; " + "namespace swizzle { " + "void swizzle<1> ( tvec2 v ) ; " + "void swizzle<2,3> ( tvec3 v ) ; " + "} " + "void foo ( ) { " + "using namespace swizzle ; " + "tvec2 tt2 ; " + "swizzle<1> ( tt2 ) ; " + "tvec3 tt3 ; " + "swizzle<2,3> ( tt3 ) ; " + "} " + "void swizzle :: swizzle<2,3> ( tvec3 v ) { } " + "void swizzle :: swizzle<1> ( tvec2 v ) { } " + "class tvec3 { } ; " + "class tvec2 { } ;"; + ASSERT_EQUALS(exp, tok(code)); + } + void template_specialization_1() { // #7868 - template specialization template struct S> {..}; const char code[] = "template struct C {};\n" "template struct S {a};\n"