diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index ab42fc04c..d9d83af8a 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -632,6 +632,66 @@ void Tokenizer::simplifyTemplates() } } + // Locate specialized templates.. + for (Token *tok = _tokens; tok; tok = tok->next()) + { + if (tok->str() != "template") + continue; + if (!Token::simpleMatch(tok->next(), "< >")) + continue; + + // what kind of template is this? + Token *tok2 = tok->tokAt(3); + while (tok2 && (tok2->isName() || tok2->str() == "*")) + tok2 = tok2->next(); + + // unknown template.. bail out + if (!tok2 || !tok2->previous()->isName()) + continue; + + tok2 = tok2->previous(); + std::string s(tok2->str()); + { + const Token *tok3 = tok2->next(); + while (Token::Match(tok3, "<|, %type%")) + { + s += " " + tok3->str() + " " + tok3->strAt(1); + tok3 = tok3->tokAt(2); + if (tok3->str() == "*") + { + tok3 = tok3->next(); + s += " *"; + } + } + if (!Token::Match(tok3, "> (")) + continue; + } + + // save search pattern.. + const std::string pattern(s + " > ("); + + // remove spaces to create new name + while (s.find(" ") != std::string::npos) + s.erase(s.find(" "), 1); + const std::string name(s + ">"); + + // Rename template.. + Token::eraseTokens(tok2, Token::findmatch(tok2, "(")); + tok2->str(name); + + // delete the "template < >" + tok->deleteThis(); + tok->deleteThis(); + tok->deleteThis(); + + // Use this special template in the code.. + while (0 != (tok2 = const_cast(Token::findmatch(tok2, pattern.c_str())))) + { + Token::eraseTokens(tok2, Token::findmatch(tok2, "(")); + tok2->str(name); + } + } + // Locate templates.. std::list templates; for (Token *tok = _tokens; tok; tok = tok->next()) diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 9d46ac121..34c9d3fec 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -84,6 +84,7 @@ private: TEST_CASE(template11); TEST_CASE(template12); TEST_CASE(template13); + TEST_CASE(template14); TEST_CASE(template_default_parameter); TEST_CASE(template_typename); @@ -1219,6 +1220,25 @@ private: sizeof_(code); } + void template14() + { + const char code[] = "template <> void foo()\n" + "{ x(); }\n" + "\n" + "int main()\n" + "{\n" + "foo();\n" + "}\n"; + + // The expected result.. + const std::string expected("void foo ( ) " + "{ x ( ) ; } " + "int main ( ) " + "{ foo ( ) ; }"); + + ASSERT_EQUALS(expected, sizeof_(code)); + } + void template_default_parameter() { {