diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 1bf98c9dc..9183accbf 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -31,6 +31,38 @@ #include #include +#ifdef GDB_HELPERS + +#include + +static void printlist(const std::list &list) +{ + for (std::list::const_iterator it = list.begin(); it != list.end(); it++) { + const Token *token = *it; + std::cout << " "; + while (token && !Token::Match(token, "[{};]")) { + std::cout << " " << token->str(); + token = token->next(); + } + std::cout << std::endl; + } +} + +static void printvector(const std::vector &v) +{ + for (unsigned int i = 0; i < v.size(); i++) { + const Token *token = v[i]; + std::cout << " " << i << ":"; + while (token && !Token::Match(token, "[{};]")) { + std::cout << " " << token->str(); + token = token->next(); + } + std::cout << std::endl; + } +} + +#endif + //--------------------------------------------------------------------------- void TemplateSimplifier::cleanupAfterSimplify(Token *tokens) @@ -620,9 +652,16 @@ void TemplateSimplifier::expandTemplate( // replace type with given type.. if (itype < typeParametersInDeclaration.size()) { + unsigned int typeindentlevel = 0; for (const Token *typetok = typesUsedInTemplateInstantiation[itype]; - typetok && !Token::Match(typetok, "[,>]"); + typetok && (typeindentlevel>0 || !Token::Match(typetok, "[,>]")); typetok = typetok->next()) { + if (Token::Match(typetok, "%var% <") && templateParameters(typetok->next()) > 0) + ++typeindentlevel; + else if (typeindentlevel > 0 && typetok->str() == ">") + --typeindentlevel; + else if (typeindentlevel > 0 && typetok->str() == ">>") + typeindentlevel -= (typeindentlevel > 1) ? 2 : 1; tokenlist.addtoken(typetok, tok3->linenr(), tok3->fileIndex()); } continue; diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 954b155a5..78b42781b 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -127,6 +127,7 @@ private: TEST_CASE(template33); // #3818 - inner templates in template instantiation not handled well TEST_CASE(template34); // #3706 - namespace => hang TEST_CASE(template35); // #4074 - A<'x'> a; + TEST_CASE(template36); // #4310 - passing unknown template instantiation as template argument TEST_CASE(template_unhandled); TEST_CASE(template_default_parameter); TEST_CASE(template_default_type); @@ -2241,6 +2242,16 @@ private: ASSERT_EQUALS("A<'x'> a ; class A<'x'> { }", tok(code)); } + void template36() { // #4310 - Passing unknown template instantiation as template argument + const char code[] = "template struct X { T t; };\n" + "template struct Y { Foo < X< Bar > > _foo; };\n" // <- Bar is unknown + "Y bar;"; + ASSERT_EQUALS("Y bar ; " + "struct Y { Foo < X> > _foo ; } " + "struct X> { Bar < int > t ; }", + tok(code)); + } + void template_unhandled() { // An unhandled template usage should be simplified.. ASSERT_EQUALS("x ( ) ;", tok("x();"));