diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 209563ed0..1f322cd41 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -327,6 +327,15 @@ unsigned int TemplateSimplifier::templateParameters(const Token *tok) unsigned int level = 0; while (tok) { + // skip template template + if (level == 0 && Token::simpleMatch(tok, "template <")) { + const Token *closing = tok->next()->findClosingBracket(); + if (closing) + tok = closing->next(); + else + return 0; + } + // skip const/volatile if (Token::Match(tok, "const|volatile")) tok = tok->next(); @@ -2324,7 +2333,14 @@ const Token * TemplateSimplifier::getTemplateParametersInDeclaration( std::vector & typeParametersInDeclaration) { typeParametersInDeclaration.clear(); - for (; tok && tok->str() != ">"; tok = tok->next()) { + const Token *closing = tok->previous()->findClosingBracket(); + for (; tok && tok!= closing; tok = tok->next()) { + if (Token::simpleMatch(tok, "template <")) { + const Token *closing = tok->next()->findClosingBracket(); + if (closing) + tok = closing->next(); + } + if (Token::Match(tok, "%name% ,|>|=")) typeParametersInDeclaration.push_back(tok); } @@ -3009,8 +3025,7 @@ void TemplateSimplifier::simplifyTemplates( tok->deleteThis(); if (Token::simpleMatch(tok, "template <")) { - while (tok && tok->str() != ">") - tok = tok->next(); + tok = tok->next()->findClosingBracket(); if (!tok) break; } diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp index e92517ff8..36f87c21c 100644 --- a/test/testsimplifytemplate.cpp +++ b/test/testsimplifytemplate.cpp @@ -143,6 +143,7 @@ private: TEST_CASE(template103); TEST_CASE(template104); // #9021 TEST_CASE(template105); // #9076 + TEST_CASE(template106); 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) @@ -2398,6 +2399,27 @@ private: ASSERT_EQUALS(exp, tok(code)); } + void template106() { + const char code[] = "template class A {\n" + "public:\n" + " int x;\n" + "};\n" + "template class V> class B {\n" + " V i;\n" + "};\n" + "B c;"; + const char exp[] = "class A ; " + "class B ; " + "B c ; " + "class B { " + "A i ; " + "} ; class A { " + "public: " + "int x ; " + "} ;"; + 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" @@ -3386,7 +3408,7 @@ private: void templateParameterWithoutName() { ASSERT_EQUALS(1U, templateParameters("template struct s;")); ASSERT_EQUALS(1U, templateParameters("template typename T> struct A {\n" - " void f();n" + " void f();\n" " void g();\n" "};n")); } diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 19910b9fc..e82c726b3 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -2435,7 +2435,7 @@ private: "public:\n" " int f() { return C< ::D,int>::f(); }\n" "};"); - ASSERT_EQUALS("[test.cpp:6]: (debug) Failed to instantiate template \"C\". The checking continues anyway.\n", errout.str()); + ASSERT_EQUALS("", errout.str()); } void symboldatabase8() {