diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 465a28207..e9aa3ddff 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -1149,10 +1149,11 @@ void TemplateSimplifier::expandTemplate( // replace name.. if (tok3->str() == lastName) { if (Token::simpleMatch(tok3->next(), "<")) { - // replace multi token name with single token name - if (tok3 == templateDeclarationNameToken || Token::Match(tok3, newName.c_str())) { - Token *closingBracket = tok3->next()->findClosingBracket(); - if (closingBracket) { + Token *closingBracket = tok3->next()->findClosingBracket(); + if (closingBracket) { + // replace multi token name with single token name + if (tok3 == templateDeclarationNameToken || + Token::Match(tok3, newName.c_str())) { if (copy) { mTokenList.addtoken(newName, tok3->linenr(), tok3->fileIndex()); tok3 = closingBracket; @@ -1161,11 +1162,12 @@ void TemplateSimplifier::expandTemplate( eraseTokens(tok3, closingBracket->next()); } continue; + } else if (!templateDeclaration.scope.empty() && + !alreadyHasNamespace(templateDeclaration, tok3) && + closingBracket->strAt(1) != "(") { + if (copy) + addNamespace(templateDeclaration, tok3); } - } else if (!templateDeclaration.scope.empty() && - !alreadyHasNamespace(templateDeclaration, tok3)) { - if (copy) - addNamespace(templateDeclaration, tok3); } } else { if (copy) { diff --git a/lib/token.cpp b/lib/token.cpp index bce14ced5..43ab57d67 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -950,10 +950,6 @@ const Token *Token::findmatch(const Token * const startTok, const char pattern[] void Token::insertToken(const std::string &tokenStr, const std::string &originalNameStr, bool prepend) { - //TODO: Find a solution for the first token on the list - if (prepend && !this->previous()) - return; - Token *newToken; if (mStr.empty()) newToken = this; @@ -969,12 +965,12 @@ void Token::insertToken(const std::string &tokenStr, const std::string &original newToken->mProgressValue = mProgressValue; if (prepend) { - /*if (this->previous())*/ { + if (this->previous()) { newToken->previous(this->previous()); newToken->previous()->next(newToken); - } /*else if (tokensFront?) { - *tokensFront? = newToken; - }*/ + } else if (mTokensFrontBack) { + mTokensFrontBack->front = newToken; + } this->previous(newToken); newToken->next(this); } else { diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp index 08d77bc76..93937c873 100644 --- a/test/testsimplifytemplate.cpp +++ b/test/testsimplifytemplate.cpp @@ -129,6 +129,7 @@ private: TEST_CASE(template_namespace_7); // #8768 TEST_CASE(template_namespace_8); TEST_CASE(template_namespace_9); + TEST_CASE(template_namespace_10); // Test TemplateSimplifier::templateParameters TEST_CASE(templateParameters); @@ -192,7 +193,8 @@ private: const char code[] = "template class Fred { T a; };\n" "Fred fred;"; - const char expected[] = "Fred fred ; " + const char expected[] = "class Fred ; " + "Fred fred ; " "class Fred { int a ; } ;"; ASSERT_EQUALS(expected, tok(code)); @@ -202,7 +204,8 @@ private: const char code[] = "template class Fred { T data[sz]; };\n" "Fred fred;"; - const char expected[] = "Fred fred ; " + const char expected[] = "class Fred ; " + "Fred fred ; " "class Fred { float data [ 4 ] ; } ;"; ASSERT_EQUALS(expected, tok(code)); @@ -212,7 +215,8 @@ private: const char code[] = "template class Fred { Fred(); };\n" "Fred fred;"; - const char expected[] = "Fred fred ; " + const char expected[] = "class Fred ; " + "Fred fred ; " "class Fred { Fred ( ) ; } ;"; ASSERT_EQUALS(expected, tok(code)); @@ -223,7 +227,8 @@ private: "template Fred::Fred() { }\n" "Fred fred;"; - const char expected[] = "Fred fred ; " + const char expected[] = "class Fred ; " + "Fred fred ; " "class Fred { } ; " "Fred :: Fred ( ) { }"; @@ -235,7 +240,8 @@ private: "Fred fred1;\n" "Fred fred2;"; - const char expected[] = "Fred fred1 ; " + const char expected[] = "class Fred ; " + "Fred fred1 ; " "Fred fred2 ; " "class Fred { } ;"; @@ -349,7 +355,8 @@ private: "} ;\n"; // The expected result.. - const char expected[] = "void f ( ) { A a ; } " + const char expected[] = "class A ; " + "void f ( ) { A a ; } " "template < typename T > class B { void g ( ) { A < T > b ; b = A < T > :: h ( ) ; } } ; " "class A { } ;"; @@ -403,7 +410,8 @@ private: "}\n"; // The expected result.. - const char expected[] = "void f ( ) " + const char expected[] = "class A<12,12,11> ; " + "void f ( ) " "{" " A<12,12,11> a ; " "} " @@ -490,7 +498,8 @@ private: "};\n" "\n" "vec<4> v;"; - const char expected2[] = "vec<4> v ; " + const char expected2[] = "struct vec<4> ; " + "vec<4> v ; " "struct vec<4> { " "vec<4> ( ) { } " "vec<4> ( const vec < 4 - 1 > & v ) { } " @@ -539,7 +548,8 @@ private: const char code[] = "template class foo { T a; };\n" "foo *f;"; - const char expected[] = "foo * f ; " + const char expected[] = "class foo ; " + "foo * f ; " "class foo { int a ; } ;"; ASSERT_EQUALS(expected, tok(code)); @@ -570,7 +580,8 @@ private: "A a;\n"; // The expected result.. - const char expected[] = "A a ; " + const char expected[] = "class A ; " + "A a ; " "class A { public: ~ A ( ) ; } ; " "A :: ~ A ( ) { }"; ASSERT_EQUALS(expected, tok(code)); @@ -581,7 +592,8 @@ private: const char code[] = "template struct Fred { T a; };\n" "Fred fred;"; - const char expected[] = "Fred fred ; " + const char expected[] = "struct Fred ; " + "Fred fred ; " "struct Fred { int a ; } ;"; ASSERT_EQUALS(expected, tok(code)); @@ -591,7 +603,8 @@ private: const char code[] = "template struct Fred { T data[sz]; };\n" "Fred fred;"; - const char expected[] = "Fred fred ; " + const char expected[] = "struct Fred ; " + "Fred fred ; " "struct Fred { float data [ 4 ] ; } ;"; ASSERT_EQUALS(expected, tok(code)); @@ -601,7 +614,8 @@ private: const char code[] = "template struct Fred { Fred(); };\n" "Fred fred;"; - const char expected[] = "Fred fred ; " + const char expected[] = "struct Fred ; " + "Fred fred ; " "struct Fred { Fred ( ) ; } ;"; ASSERT_EQUALS(expected, tok(code)); @@ -612,7 +626,8 @@ private: "Fred fred1;\n" "Fred fred2;"; - const char expected[] = "Fred fred1 ; " + const char expected[] = "struct Fred ; " + "Fred fred1 ; " "Fred fred2 ; " "struct Fred { } ;"; @@ -624,7 +639,8 @@ private: const char code[] = "template struct Fred { T a; };\n" "Fred fred;"; - const char expected[] = "Fred fred ; " + const char expected[] = "struct Fred ; " + "Fred fred ; " "struct Fred { std :: string a ; } ;"; ASSERT_EQUALS(expected, tok(code)); @@ -655,7 +671,8 @@ private: "{};\n" "\n" "bitset<1> z;"; - const char expected[] = "class bitset<1> ; " + const char expected[] = "struct B<4> ; " + "class bitset<1> ; " "bitset<1> z ; " "class bitset<1> : B<4> { } ; " "struct B<4> { int a [ 4 ] ; } ;"; @@ -709,7 +726,11 @@ private: // #3226 - inner template const char code[] = "template class Fred {};\n" "Fred > x;\n"; - ASSERT_EQUALS("Fred> x ; class Fred { } ; class Fred> { } ;", tok(code)); + ASSERT_EQUALS("class Fred ; " + "class Fred> ; " + "Fred> x ; " + "class Fred { } ; " + "class Fred> { } ;", tok(code)); } void template30() { @@ -721,11 +742,15 @@ private: void template31() { // #4010 - template reference type const char code[] = "template struct A{}; A a;"; - ASSERT_EQUALS("A a ; struct A { } ;", tok(code)); + ASSERT_EQUALS("struct A ; " + "A a ; " + "struct A { } ;", tok(code)); // #7409 - rvalue const char code2[] = "template struct A{}; A a;"; - ASSERT_EQUALS("A a ; struct A { } ;", tok(code2)); + ASSERT_EQUALS("struct A ; " + "A a ; " + "struct A { } ;", tok(code2)); } void template32() { @@ -753,7 +778,8 @@ private: "template struct B { };\n" "template struct C { A > > ab; };\n" "C c;"; - ASSERT_EQUALS("struct B> ; " + ASSERT_EQUALS("struct A>> ; " + "struct B> ; " "struct C ; " "C c ; " "struct C { A>> ab ; } ; " @@ -788,14 +814,17 @@ private: void template35() { // #4074 - "A<'x'> a;" is not recognized as template instantiation const char code[] = "template class A {};\n" "A <'x'> a;"; - ASSERT_EQUALS("A<'x'> a ; class A<'x'> { } ;", tok(code)); + ASSERT_EQUALS("class A<'x'> ; " + "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("struct Y ; " + ASSERT_EQUALS("struct X> ; " + "struct Y ; " "Y bar ; " "struct Y { Foo < X> > _foo ; } ; " "struct X> { Bar < int > t ; } ;", @@ -870,7 +899,9 @@ private: void template41() { // #4710 - const in template instantiation not handled perfectly const char code1[] = "template struct X { };\n" "void f(const X x) { }"; - ASSERT_EQUALS("void f ( const X x ) { } struct X { } ;", tok(code1)); + ASSERT_EQUALS("struct X ; " + "void f ( const X x ) { } " + "struct X { } ;", tok(code1)); const char code2[] = "template T f(T t) { return t; }\n" "int x() { return f(123); }"; @@ -961,7 +992,9 @@ private: "template void Fred::f();\n" "template void Fred::g();\n"; - const char expected[] = "template void Fred :: f ( ) ; " + const char expected[] = "class Fred ; " + "class Fred ; " + "template void Fred :: f ( ) ; " "template void Fred :: g ( ) ; " "class Fred { void f ( ) ; void g ( ) ; } ; " "void Fred :: f ( ) { } " @@ -1043,7 +1076,10 @@ private: // Similar problem can also happen with ... ASSERT_EQUALS( - "A a ( 0 ) ; struct A { " + "struct A ; " + "struct A ; " + "A a ( 0 ) ; " + "struct A { " "A ( int * p ) { p ; } " "} ; " "struct A { " @@ -1072,7 +1108,8 @@ private: void template57() { // #7891 const char code[] = "template struct Test { Test(T); };\n" "Test test( 0 );"; - const char exp [] = "Test test ( 0 ) ; " + const char exp [] = "struct Test ; " + "Test test ( 0 ) ; " "struct Test { Test ( long ) ; } ;"; ASSERT_EQUALS(exp, tok(code)); } @@ -1110,7 +1147,11 @@ private: "int main () {\n" " return diagonalGroupTest<4>();\n" "}"; - const char exp[] = "struct Factorial<0> { enum FacHelper { value = 1 } ; } ; " + const char exp[] = "struct Factorial<4> ; " + "struct Factorial<3> ; " + "struct Factorial<2> ; " + "struct Factorial<1> ; " + "struct Factorial<0> { enum FacHelper { value = 1 } ; } ; " "int main ( ) { return diagonalGroupTest<4> ( ) ; } " "int diagonalGroupTest<4> ( ) { return Factorial<4> :: value ; } " "struct Factorial<4> { enum FacHelper { value = 4 * Factorial<3> :: value } ; } ; " @@ -1126,7 +1167,8 @@ private: "template void h() { f::type(0)>(); }\n" "\n" "void j() { h(); }"; - const char exp[] = "template < typename T > void f ( ) { } " // <- TODO: This template is not expanded + const char exp[] = "struct S ; " + "template < typename T > void f ( ) { } " // <- TODO: This template is not expanded "void j ( ) { h ( ) ; } " "void h ( ) { f < S :: type ( 0 ) > ( ) ; } " "struct S { } ;"; @@ -1140,7 +1182,8 @@ private: " Foo> f2() { }\n" "};\n" "Bar c;"; - const char exp[] = "struct Bar ; " + const char exp[] = "struct Foo> ; " + "struct Bar ; " "Bar c ; " "struct Bar {" " void f1 ( Bar x ) { }" @@ -1156,7 +1199,8 @@ private: "template class C3 {};\n" "template C3::C3(const C3 &v) { C1 c1; }\n" "C3 c3;"; - const char exp[] = "template < class T > void f ( ) { x = y ? ( C1 < int > :: allocate ( 1 ) ) : 0 ; } " + const char exp[] = "struct C1 ; " + "template < class T > void f ( ) { x = y ? ( C1 < int > :: allocate ( 1 ) ) : 0 ; } " "class C3 ; " "C3 c3 ; " "class C3 { } ; " @@ -1166,8 +1210,11 @@ private: } void template63() { // #8576 - const char code[] = "template struct TestClass { T m_hi; }; TestClass> objTest3;"; - const char exp[] = "TestClass> objTest3 ; struct TestClass> { std :: auto_ptr < v > m_hi ; } ;"; + const char code[] = "template struct TestClass { T m_hi; };" + "TestClass> objTest3;"; + const char exp[] = "struct TestClass> ; " + "TestClass> objTest3 ; " + "struct TestClass> { std :: auto_ptr < v > m_hi ; } ;"; ASSERT_EQUALS(exp, tok(code)); } @@ -1214,7 +1261,9 @@ private: "};\n" "template const int ** Fred::foo() { return nullptr; }\n" "Fred fred;"; - const char exp [] = "Fred fred ; struct Fred { " + const char exp [] = "struct Fred ; " + "Fred fred ; " + "struct Fred { " "const int * * foo ( ) ; " "} ; " "const int * * Fred :: foo ( ) { return nullptr ; }"; @@ -1236,7 +1285,8 @@ private: "template Containter::~Containter() {}\n" "Containter intContainer;"; - const char expected[] = "Containter intContainer ; " + const char expected[] = "struct Containter ; " + "Containter intContainer ; " "struct Containter { " "Containter ( ) ; " "Containter ( const Containter & ) ; " @@ -1259,7 +1309,9 @@ private: " T value;\n" "};\n" "Fred fred;"; - const char exp [] = "Fred fred ; union Fred { " + const char exp [] = "union Fred ; " + "Fred fred ; " + "union Fred { " "char dummy [ 4 ] ; " "int value ; " "} ;"; @@ -1391,7 +1443,9 @@ private: "}\n"; // The expected result.. - const char expected[] = "void f ( ) " + const char expected[] = "class A ; " + "class A ; " + "void f ( ) " "{" " A a1 ;" " A a2 ; " @@ -1414,7 +1468,8 @@ private: "}\n"; // The expected result.. - const char expected[] = "void f ( ) " + const char expected[] = "class A ; " + "void f ( ) " "{" " A a1 ;" " A a2 ; " @@ -1447,7 +1502,8 @@ private: " class A" " { int ar [ 3 ] ; }"; - const char current[] = "void f ( ) " + const char current[] = "class A ; " + "void f ( ) " "{ " "A < int , ( int ) 2 > a1 ; " "A a2 ; " @@ -1763,7 +1819,9 @@ private: void template_namespace_5() { const char code[] = "template struct S {};\n" "namespace X { S s; }"; - ASSERT_EQUALS("namespace X { S s ; } struct S { } ;", tok(code)); + ASSERT_EQUALS("struct S ; " + "namespace X { S s ; } " + "struct S { } ;", tok(code)); } void template_namespace_6() { @@ -1891,6 +1949,31 @@ private: "} ;", tok(code)); } + void template_namespace_10() { + const char code[] = "namespace NS1 {\n" + "namespace NS2 {\n" + "template\n" + "class Fred {\n" + " T * t;\n" + "public:\n" + " Fred() : t(nullptr) {}\n" + "};\n" + "}\n" + "}\n" + "NS1::NS2::Fred fred;"; + ASSERT_EQUALS("namespace NS1 { " + "namespace NS2 { " + "class Fred ; " + "} " + "} " + "NS1 :: NS2 :: Fred fred ; class NS1 :: NS2 :: Fred " + "{ " + "int * t ; " + "public: " + "Fred ( ) : t ( nullptr ) { } " + "} ;", tok(code)); + } + unsigned int templateParameters(const char code[]) { Tokenizer tokenizer(&settings, this); @@ -2127,7 +2210,8 @@ private: "template<> class C { };\n" "map m;\n" "C i;"; - const char expected[] = "class C { } ; " + const char expected[] = "class C ; " + "class C { } ; " "map < int > m ; " "C i ; " "class C { } ;"; @@ -2139,7 +2223,8 @@ private: "map m;\n" "C i;\n" "C c;"; - const char expected[] = "class C { } ; " + const char expected[] = "class C ; " + "class C { } ; " "map < int > m ; " "C i ; " "C c ; " @@ -2153,7 +2238,9 @@ private: "template using Bar = Foo;\n" "Bar b;\n"; - const char expected[] = "; Foo b ; struct Foo { } ;"; + const char expected[] = "struct Foo ; " + "Foo b ; " + "struct Foo { } ;"; ASSERT_EQUALS(expected, tok(code)); } @@ -2175,7 +2262,9 @@ private: const char code[] = "template struct Tag {};\n" "template using SPtr = std::shared_ptr)>;\n" "SPtr<0> s;"; - const char expected[] = "; std :: shared_ptr < void ( Tag<0> ) > s ; struct Tag<0> { } ;"; + const char expected[] = "struct Tag<0> ; " + "std :: shared_ptr < void ( Tag<0> ) > s ; " + "struct Tag<0> { } ;"; ASSERT_EQUALS(expected, tok(code)); } diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index dfc37643c..c80caf2bd 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -840,7 +840,11 @@ private: "};\n" "template Containter::Containter() : mElements(nullptr) {}\n" "Containter intContainer;"; - const char exp [] = "6: Containter intContainer@1 ; struct Containter {\n" + const char exp [] = "1: struct Containter ;\n" + "2:\n" + "|\n" + "5:\n" + "6: Containter intContainer@1 ; struct Containter {\n" "2: Containter ( ) ;\n" "3: int * mElements@2 ;\n" "4: } ;\n"