diff --git a/src/tokenize.cpp b/src/tokenize.cpp index d6f9c7c1d..c2a077f2f 100644 --- a/src/tokenize.cpp +++ b/src/tokenize.cpp @@ -593,8 +593,14 @@ void Tokenizer::simplifyTemplates() const std::string name2(name + "<" + type2 + ">"); // Copy template.. + int _indentlevel = 0; for (const Token *tok3 = _tokens; tok3; tok3 = tok3->next()) { + if (tok3->str() == "{") + ++_indentlevel; + else if (tok3->str() == "}") + --_indentlevel; + // Start of template.. if (tok3 == tok) { @@ -602,7 +608,7 @@ void Tokenizer::simplifyTemplates() } // member function implemented outside class definition - else if (Token::Match(tok3, (pattern + " :: %var% (").c_str())) + else if (_indentlevel == 0 && Token::Match(tok3, (pattern + " :: %var% (").c_str())) { addtoken(name2.c_str(), tok3->linenr(), tok3->fileIndex()); while (tok3->str() != "::") @@ -616,6 +622,23 @@ void Tokenizer::simplifyTemplates() int indentlevel = 0; for (; tok3; tok3 = tok3->next()) { + if (tok3->str() == "{") + ++indentlevel; + + else if (tok3->str() == "}") + { + if (indentlevel <= 1) + { + // there is a bug if indentlevel is 0 + // the "}" token should only be added if indentlevel is 1 but I add it always intentionally + // if indentlevel ever becomes 0, cppcheck will write: + // ### Error: Invalid number of character { + addtoken("}", tok3->linenr(), tok3->fileIndex()); + break; + } + --indentlevel; + } + { // search for this token in the type vector unsigned int itype = 0; @@ -634,16 +657,6 @@ void Tokenizer::simplifyTemplates() else addtoken(tok3->str().c_str(), tok3->linenr(), tok3->fileIndex()); } - - if (tok3->str() == "{") - ++indentlevel; - - else if (tok3->str() == "}") - { - if (indentlevel <= 1) - break; - --indentlevel; - } } } diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 7138cc4d9..dce6610c8 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -86,6 +86,7 @@ private: TEST_CASE(template6); TEST_CASE(template7); TEST_CASE(template8); + TEST_CASE(template9); TEST_CASE(namespaces); @@ -692,6 +693,32 @@ private: ASSERT_EQUALS(expected, sizeof_(code)); } + void template9() + { + const char code[] = "template < typename T > class A { } ;\n" + "\n" + "void f ( ) {\n" + " A a ;\n" + "}\n" + "\n" + "template < typename T >\n" + "class B {\n" + " void g ( ) {\n" + " A < T > b = A < T > :: h ( ) ;\n" + " }\n" + "} ;\n"; + + // The expected result.. + std::string expected(std::string(" ") + code + " class A { }"); + std::string::size_type pos; + while ((pos = expected.find("\n")) != std::string::npos) + expected[pos] = ' '; + while ((pos = expected.find(" ")) != std::string::npos) + expected.erase(pos, 1); + + ASSERT_EQUALS(expected, sizeof_(code)); + } +