diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index baac0b051..d279be177 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -1014,7 +1014,7 @@ bool TemplateSimplifier::simplifyTemplateInstantions( std::string typeForNewNameStr; std::string templateMatchPattern(name + " < "); unsigned int indentlevel = 0; - for (const Token *tok3 = tok2->tokAt(2); tok3 && tok3->str() != ">"; tok3 = tok3->next()) { + for (const Token *tok3 = tok2->tokAt(2); tok3 && (indentlevel > 0 || tok3->str() != ">"); tok3 = tok3->next()) { // #2648 - unhandled parenthesis => bail out // #2721 - unhandled [ => bail out if (tok3->str() == "(" || tok3->str() == "[") { @@ -1027,7 +1027,7 @@ bool TemplateSimplifier::simplifyTemplateInstantions( } if (tok3->str() == "<" && templateParameters(tok3) > 0) ++indentlevel; - else if (indentlevel > 0 && Token::simpleMatch(tok3, "> ,")) + else if (indentlevel > 0 && Token::simpleMatch(tok3, "> [,>]")) --indentlevel; templateMatchPattern += tok3->str(); templateMatchPattern += " "; diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 832d35c29..f1bf73bbb 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -126,6 +126,7 @@ private: TEST_CASE(template30); // #3529 - template < template < .. TEST_CASE(template31); // #4010 - reference type TEST_CASE(template32); // #3818 - mismatching template not handled well + TEST_CASE(template33); // #3818 - inner templates in template instantiation not handled well TEST_CASE(template_unhandled); TEST_CASE(template_default_parameter); TEST_CASE(template_default_type); @@ -2171,6 +2172,18 @@ private: "struct B { public: A < int , Pair < int , int > , int > a ; }", tok(code)); } + void template33() { + // #3818 - inner templates in template instantiation not handled well + const char code[] = "template struct A { };\n" + "template struct B { };\n" + "template struct C { A > > ab; };\n" + "C c;"; + ASSERT_EQUALS("template < class T > struct A { } ; " + "template < class T > struct B { } ; " + "C c ; " + "struct C { A < B < X < int > > > ab ; }", tok(code)); + } + void template_unhandled() { // An unhandled template usage should be simplified.. ASSERT_EQUALS("x ( ) ;", tok("x();"));