From 0943b2145be0c949e713a84dc67fe15bf63b344f Mon Sep 17 00:00:00 2001 From: Simon Martin Date: Sun, 5 Feb 2017 17:30:24 +0100 Subject: [PATCH] Ticket #7891: Do not remove spaces in the internal representation for template instantiations. --- lib/templatesimplifier.cpp | 27 ++-- test/testclass.cpp | 2 +- test/testsimplifytemplate.cpp | 276 ++++++++++++++++++---------------- test/testsimplifytokens.cpp | 4 +- test/testtokenize.cpp | 2 +- 5 files changed, 165 insertions(+), 146 deletions(-) diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 8833e2b6e..a84f6361f 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -435,12 +435,8 @@ std::set TemplateSimplifier::expandSpecialized(Token *tokens) s = ostr.str(); } - // save search pattern.. - const std::string pattern(s + " >"); - // remove spaces to create new name - s.erase(std::remove(s.begin(), s.end(), ' '), s.end()); - const std::string name(s + ">"); + const std::string name(s + " >"); expandedtemplates.insert(name); // Rename template.. @@ -452,7 +448,7 @@ std::set TemplateSimplifier::expandSpecialized(Token *tokens) tok->deleteThis(); // Use this special template in the code.. - while (nullptr != (tok2 = const_cast(Token::findsimplematch(tok2, pattern.c_str())))) { + while (nullptr != (tok2 = const_cast(Token::findsimplematch(tok2, name.c_str())))) { Token::eraseTokens(tok2, Token::findsimplematch(tok2, "<")->findClosingBracket()->next()); tok2->str(name); } @@ -1264,7 +1260,7 @@ bool TemplateSimplifier::simplifyTemplateInstantiations( // New type.. std::vector typesUsedInTemplateInstantiation; std::string typeForNewName; - std::string templateMatchPattern(name + " < "); + std::string typeForPatternMatch; unsigned int indentlevel = 0; for (const Token *tok3 = tok2->tokAt(2); tok3 && (indentlevel > 0 || tok3->str() != ">"); tok3 = tok3->next()) { // #2648 - unhandled parentheses => bail out @@ -1281,13 +1277,14 @@ bool TemplateSimplifier::simplifyTemplateInstantiations( ++indentlevel; else if (indentlevel > 0 && Token::Match(tok3, "> [,>]")) --indentlevel; - bool constconst = tok3->str() == "const" && tok3->strAt(1) == "const"; - if (!constconst) { - templateMatchPattern += tok3->str(); - templateMatchPattern += ' '; - } if (indentlevel == 0 && Token::Match(tok3->previous(), "[<,]")) typesUsedInTemplateInstantiation.push_back(tok3); + const bool constconst = tok3->str() == "const" && tok3->strAt(1) == "const"; + if (!constconst) { + if (!typeForPatternMatch.empty()) + typeForPatternMatch += ' '; + typeForPatternMatch += tok3->str(); + } // add additional type information if (!constconst && tok3->str() != "class") { if (tok3->isUnsigned()) @@ -1296,10 +1293,12 @@ bool TemplateSimplifier::simplifyTemplateInstantiations( typeForNewName += "signed"; if (tok3->isLong()) typeForNewName += "long"; + if (!typeForNewName.empty()) + typeForNewName += ' '; typeForNewName += tok3->str(); } } - templateMatchPattern += ">"; + std::string templateMatchPattern(name + " < " + typeForPatternMatch + " >"); if (typeForNewName.empty() || typeParametersInDeclaration.size() != typesUsedInTemplateInstantiation.size()) { if (printDebug && errorlogger) { @@ -1313,7 +1312,7 @@ bool TemplateSimplifier::simplifyTemplateInstantiations( } // New classname/funcname.. - const std::string newName(name + "<" + typeForNewName + ">"); + const std::string newName(name + " < " + typeForNewName + " >"); if (expandedtemplates.find(newName) == expandedtemplates.end()) { expandedtemplates.insert(newName); diff --git a/test/testclass.cpp b/test/testclass.cpp index 107a811de..be786e327 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -2140,7 +2140,7 @@ private: "};\n" "\n" "AA *p = new B; delete p;"); - ASSERT_EQUALS("[test.cpp:9]: (error) Class 'AA' which is inherited by class 'B' does not have a virtual destructor.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:9]: (error) Class 'AA < double >' which is inherited by class 'B' does not have a virtual destructor.\n", errout.str()); } void virtualDestructorInconclusive() { diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp index fb1895a0c..5d82ba498 100644 --- a/test/testsimplifytemplate.cpp +++ b/test/testsimplifytemplate.cpp @@ -89,6 +89,7 @@ private: TEST_CASE(template54); // #6587 - memory corruption upon valid code TEST_CASE(template55); // #6604 - simplify "const const" to "const" in template instantiations TEST_CASE(template56); // #7117 - const ternary operator simplification as template parameter + TEST_CASE(template57); // #7891 TEST_CASE(template_enum); // #6299 Syntax error in complex enum declaration (including template) TEST_CASE(template_unhandled); TEST_CASE(template_default_parameter); @@ -139,8 +140,8 @@ private: const char code[] = "template void f(T val) { T a; }\n" "f(10);"; - const char expected[] = "f ( 10 ) ; " - "void f ( int val ) { }"; + const char expected[] = "f < int > ( 10 ) ; " + "void f < int > ( int val ) { }"; ASSERT_EQUALS(expected, tok(code)); } @@ -149,8 +150,8 @@ private: const char code[] = "template class Fred { T a; };\n" "Fred fred;"; - const char expected[] = "Fred fred ; " - "class Fred { int a ; } ;"; + const char expected[] = "Fred < int > fred ; " + "class Fred < int > { int a ; } ;"; ASSERT_EQUALS(expected, tok(code)); } @@ -159,8 +160,8 @@ private: const char code[] = "template class Fred { T data[sz]; };\n" "Fred fred;"; - const char expected[] = "Fred fred ; " - "class Fred { float data [ 4 ] ; } ;"; + const char expected[] = "Fred < float , 4 > fred ; " + "class Fred < float , 4 > { float data [ 4 ] ; } ;"; ASSERT_EQUALS(expected, tok(code)); } @@ -169,8 +170,8 @@ private: const char code[] = "template class Fred { Fred(); };\n" "Fred fred;"; - const char expected[] = "Fred fred ; " - "class Fred { Fred ( ) ; } ;"; + const char expected[] = "Fred < float > fred ; " + "class Fred < float > { Fred < float > ( ) ; } ;"; ASSERT_EQUALS(expected, tok(code)); } @@ -181,9 +182,9 @@ private: "Fred fred;"; const char expected[] = "template < class T > Fred < T > :: Fred ( ) { } " // <- TODO: this should be removed - "Fred fred ; " - "class Fred { } ; " - "Fred :: Fred ( ) { }"; + "Fred < float > fred ; " + "class Fred < float > { } ; " + "Fred < float > :: Fred < float > ( ) { }"; ASSERT_EQUALS(expected, tok(code)); } @@ -193,9 +194,9 @@ private: "Fred fred1;\n" "Fred fred2;"; - const char expected[] = "Fred fred1 ; " - "Fred fred2 ; " - "class Fred { } ;"; + const char expected[] = "Fred < float > fred1 ; " + "Fred < float > fred2 ; " + "class Fred < float > { } ;"; ASSERT_EQUALS(expected, tok(code)); } @@ -296,7 +297,7 @@ private: const char code[] = "template < typename T > class A { } ;\n" "\n" "void f ( ) {\n" - " A a ;\n" + " A < int > a ;\n" "}\n" "\n" "template < typename T >\n" @@ -307,9 +308,9 @@ private: "} ;\n"; // The expected result.. - const char expected[] = "void f ( ) { A a ; } " - "template < typename T > class B { void g ( ) { A b ; b = A :: h ( ) ; } } ; " - "class A { } ; class A { } ;"; + const char expected[] = "void f ( ) { A < int > a ; } " + "template < typename T > class B { void g ( ) { A < T > b ; b = A < T > :: h ( ) ; } } ; " + "class A < int > { } ; class A < T > { } ;"; ASSERT_EQUALS(expected, tok(code)); } @@ -326,9 +327,9 @@ private: // The expected result.. const char expected[] = "void f ( ) " "{" - " foo<3,int> ( ) ; " + " foo < 3 , int > ( ) ; " "} " - "int * foo<3,int> ( ) { return new int [ 3 ] ; }"; + "int * foo < 3 , int > ( ) { return new int [ 3 ] ; }"; ASSERT_EQUALS(expected, tok(code)); } @@ -344,9 +345,9 @@ private: // The expected result.. const char expected[] = "void f ( ) " "{" - " char * p ; p = foo<3,char> ( ) ; " + " char * p ; p = foo < 3 , char > ( ) ; " "} " - "char * foo<3,char> ( ) { return new char [ 3 ] ; }"; + "char * foo < 3 , char > ( ) { return new char [ 3 ] ; }"; ASSERT_EQUALS(expected, tok(code)); } @@ -363,9 +364,9 @@ private: // The expected result.. const char expected[] = "void f ( ) " "{" - " A<12,12,11> a ; " + " A < 12 , 12 , 11 > a ; " "} " - "class A<12,12,11> : public B < 12 , 12 , 0 > " + "class A < 12 , 12 , 11 > : public B < 12 , 12 , 0 > " "{ } ;"; ASSERT_EQUALS(expected, tok(code)); } @@ -409,10 +410,10 @@ private: "}\n"; // The expected result.. - const char expected[] = "void foo ( ) " + const char expected[] = "void foo < int * > ( ) " "{ x ( ) ; } " "int main ( ) " - "{ foo ( ) ; }"; + "{ foo < int * > ( ) ; }"; ASSERT_EQUALS(expected, tok(code)); } @@ -433,11 +434,11 @@ private: "}\n"; // The expected result.. - const char expected[] = "void a<0> ( ) { } " + const char expected[] = "void a < 0 > ( ) { } " "int main ( ) " - "{ a<2> ( ) ; return 0 ; } " - "void a<2> ( ) { a<1> ( ) ; } " - "void a<1> ( ) { a<0> ( ) ; }"; + "{ a < 2 > ( ) ; return 0 ; } " + "void a < 2 > ( ) { a < 1 > ( ) ; } " + "void a < 1 > ( ) { a < 0 > ( ) ; }"; ASSERT_EQUALS(expected, tok(code)); @@ -448,10 +449,10 @@ private: "};\n" "\n" "vec<4> v;"; - const char expected2[] = "vec<4> v ; " - "struct vec<4> { " - "vec<4> ( ) { } " - "vec<4> ( const vec < 4 - 1 > & v ) { } " + const char expected2[] = "vec < 4 > v ; " + "struct vec < 4 > { " + "vec < 4 > ( ) { } " + "vec < 4 > ( const vec < 4 - 1 > & v ) { } " "} ;"; ASSERT_EQUALS(expected2, tok(code2)); @@ -470,10 +471,10 @@ private: " return 0;\n" "}\n"; - const char expected[] = "int main ( ) { b<2> ( ) ; return 0 ; } " - "void b<2> ( ) { a<2> ( ) ; } " - "void a ( ) { } " - "void a<2> ( ) { }"; + const char expected[] = "int main ( ) { b < 2 > ( ) ; return 0 ; } " + "void b < 2 > ( ) { a < 2 > ( ) ; } " + "void a < i > ( ) { } " + "void a < 2 > ( ) { }"; ASSERT_EQUALS(expected, tok(code)); } @@ -498,8 +499,8 @@ private: const char code[] = "template class foo { T a; };\n" "foo *f;"; - const char expected[] = "foo * f ; " - "class foo { int a ; } ;"; + const char expected[] = "foo < int > * f ; " + "class foo < int > { int a ; } ;"; ASSERT_EQUALS(expected, tok(code)); } @@ -516,9 +517,9 @@ private: // The expected result.. const char expected[] = "void f ( ) " "{" - " char p ; p = foo ( ) ; " + " char p ; p = foo < char > ( ) ; " "} " - "char & foo ( ) { static char temp ; return temp ; }"; + "char & foo < char > ( ) { static char temp ; return temp ; }"; ASSERT_EQUALS(expected, tok(code)); } @@ -538,9 +539,9 @@ private: // The expected result.. const char expected[] = "template < class T > A < T > :: ~ A ( ) { } " // <- TODO: this should be removed - "A a ; " - "class A { public: ~ A ( ) ; } ; " - "A :: ~ A ( ) { }"; + "A < int > a ; " + "class A < int > { public: ~ A < int > ( ) ; } ; " + "A < int > :: ~ A < int > ( ) { }"; ASSERT_EQUALS(expected, tok(code)); } @@ -549,8 +550,8 @@ private: const char code[] = "template struct Fred { T a; };\n" "Fred fred;"; - const char expected[] = "Fred fred ; " - "struct Fred { int a ; } ;"; + const char expected[] = "Fred < int > fred ; " + "struct Fred < int > { int a ; } ;"; ASSERT_EQUALS(expected, tok(code)); } @@ -559,8 +560,8 @@ private: const char code[] = "template struct Fred { T data[sz]; };\n" "Fred fred;"; - const char expected[] = "Fred fred ; " - "struct Fred { float data [ 4 ] ; } ;"; + const char expected[] = "Fred < float , 4 > fred ; " + "struct Fred < float , 4 > { float data [ 4 ] ; } ;"; ASSERT_EQUALS(expected, tok(code)); } @@ -569,8 +570,8 @@ private: const char code[] = "template struct Fred { Fred(); };\n" "Fred fred;"; - const char expected[] = "Fred fred ; " - "struct Fred { Fred ( ) ; } ;"; + const char expected[] = "Fred < float > fred ; " + "struct Fred < float > { Fred < float > ( ) ; } ;"; ASSERT_EQUALS(expected, tok(code)); } @@ -580,9 +581,9 @@ private: "Fred fred1;\n" "Fred fred2;"; - const char expected[] = "Fred fred1 ; " - "Fred fred2 ; " - "struct Fred { } ;"; + const char expected[] = "Fred < float > fred1 ; " + "Fred < float > fred2 ; " + "struct Fred < float > { } ;"; ASSERT_EQUALS(expected, tok(code)); } @@ -592,8 +593,8 @@ private: const char code[] = "template struct Fred { T a; };\n" "Fred fred;"; - const char expected[] = "Fred fred ; " - "struct Fred { std :: string a ; } ;"; + const char expected[] = "Fred < std :: string > fred ; " + "struct Fred < std :: string > { std :: string a ; } ;"; ASSERT_EQUALS(expected, tok(code)); } @@ -605,9 +606,9 @@ private: "}"; const char expected[] = "void bar ( ) {" - " std :: cout << ( foo ( ) ) ; " + " std :: cout << ( foo < double > ( ) ) ; " "} " - "void foo ( ) { }"; + "void foo < double > ( ) { }"; ASSERT_EQUALS(expected, tok(code)); } @@ -623,9 +624,9 @@ private: "{};\n" "\n" "bitset<1> z;"; - const char expected[] = "bitset<1> z ; " - "class bitset<1> : B<4> { } ; " - "struct B<4> { int a [ 4 ] ; } ;"; + const char expected[] = "bitset < 1 > z ; " + "class bitset < 1 > : B < 4 > { } ; " + "struct B < 4 > { int a [ 4 ] ; } ;"; ASSERT_EQUALS(expected, tok(code)); } @@ -641,12 +642,12 @@ private: "bitset<1> z;"; const char actual[] = "template < int n > struct B { int a [ n ] ; } ; " - "bitset<1> z ; " - "class bitset<1> : B < 4 > { } ;"; + "bitset < 1 > z ; " + "class bitset < 1 > : B < 4 > { } ;"; - const char expected[] = "bitset<1> z ; " - "class bitset<1> : B<4> { } ; " - "struct B<4> { int a [ 4 ] ; } ;"; + const char expected[] = "bitset < 1 > z ; " + "class bitset < 1 > : B < 4 > { } ; " + "struct B < 4 > { int a [ 4 ] ; } ;"; TODO_ASSERT_EQUALS(expected, actual, tok(code)); @@ -662,7 +663,7 @@ private: "\n" "C<2> a;\n"; // TODO: expand A also - ASSERT_EQUALS("template < class T > class A { public: T x ; } ; C<2> a ; class C<2> : public A < char [ 2 ] > { } ;", tok(code)); + ASSERT_EQUALS("template < class T > class A { public: T x ; } ; C < 2 > a ; class C < 2 > : public A < char [ 2 ] > { } ;", tok(code)); } void template27() { @@ -675,7 +676,7 @@ 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("Fred < int , Fred < int , int > > x ; class Fred < int , int > { } ; class Fred < int , Fred < int , int > > { } ;", tok(code)); } void template30() { @@ -687,11 +688,11 @@ 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("A < int & > a ; struct A < int & > { } ;", tok(code)); // #7409 - rvalue const char code2[] = "template struct A{}; A a;"; - ASSERT_EQUALS("A a ; struct A { } ;", tok(code2)); + ASSERT_EQUALS("A < int && > a ; struct A < int && > { } ;", tok(code2)); } void template32() { @@ -707,8 +708,8 @@ private: "\n" "B b;\n"; ASSERT_EQUALS("template < class T1 , class T2 , class T3 , class T4 > struct A { } ; " - "B b ; " - "struct B { public: A < int , Pair < int , int > , int > a ; } ;", tok(code)); + "B < int > b ; " + "struct B < int > { public: A < int , Pair < int , int > , int > a ; } ;", tok(code)); } void template33() { @@ -718,11 +719,11 @@ private: "template struct B { };\n" "template struct C { A > > ab; };\n" "C c;"; - ASSERT_EQUALS("C c ; " - "struct C { A>> ab ; } ; " - "struct B> { } ; " // <- redundant.. but nevermind - "struct A>> { } ; " // <- redundant.. but nevermind - "struct A>> { } ;", tok(code)); + ASSERT_EQUALS("C < int > c ; " + "struct C < int > { A < B < X < int > > > ab ; } ; " + "struct B < X < int > > { } ; " // <- redundant.. but nevermind + "struct A < B < X < T > > > { } ; " // <- redundant.. but nevermind + "struct A < B < X < int > > > { } ;", tok(code)); } { @@ -733,7 +734,7 @@ private: "C< B > c;"; ASSERT_EQUALS("struct A { } ; " "template < class T > struct B { } ; " // <- redundant.. but nevermind - "C> c ; struct C> { } ;", + "C < B < A > > c ; struct C < B < A > > { } ;", tok(code)); } } @@ -752,17 +753,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)); + "A <'x'> a;"; + 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 ; } ;", + ASSERT_EQUALS("Y < int > bar ; " + "struct Y < int > { Foo < X < Bar < int > > > _foo ; } ; " + "struct X < Bar < int > > { Bar < int > t ; } ;", tok(code)); } @@ -771,7 +772,7 @@ private: "template class B {};\n" "B b1;\n" "B b2;"; - ASSERT_EQUALS("class A { } ; B b1 ; B b2 ; class B { } ;", + ASSERT_EQUALS("class A { } ; B < A > b1 ; B < A > b2 ; class B < A > { } ;", tok(code)); } @@ -816,11 +817,11 @@ 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("void f ( const X < int > x ) { } struct X < int > { } ;", tok(code1)); const char code2[] = "template T f(T t) { return t; }\n" "int x() { return f(123); }"; - ASSERT_EQUALS("int x ( ) { return f ( 123 ) ; } int f ( int t ) { return t ; }", tok(code2)); + ASSERT_EQUALS("int x ( ) { return f < int > ( 123 ) ; } int f < int > ( int t ) { return t ; }", tok(code2)); } void template42() { // #4878 cpcheck aborts in ext-blocks.cpp (clang testcode) @@ -907,15 +908,15 @@ private: "template void Fred::f();\n" "template void Fred::g();\n"; - const char expected[] = "template < class T > void Fred :: f ( ) { } " - "template < class T > void Fred :: g ( ) { } " - "template void Fred :: f ( ) ; " - "template void Fred :: g ( ) ; " - "class Fred { void f ( ) ; void g ( ) ; } ; " - "Fred :: f ( ) { } " - "Fred :: g ( ) { } " - "class Fred { void f ( ) ; void g ( ) ; } ; " - "class Fred { void f ( ) ; void g ( ) ; } ;"; + const char expected[] = "template < class T > void Fred < T > :: f ( ) { } " + "template < class T > void Fred < T > :: g ( ) { } " + "template void Fred < float > :: f ( ) ; " + "template void Fred < int > :: g ( ) ; " + "class Fred < T > { void f ( ) ; void g ( ) ; } ; " + "Fred < T > :: f ( ) { } " + "Fred < T > :: g ( ) { } " + "class Fred < float > { void f ( ) ; void g ( ) ; } ; " + "class Fred < int > { void f ( ) ; void g ( ) ; } ;"; ASSERT_EQUALS(expected, tok(code)); } @@ -926,13 +927,13 @@ private: "template<> void Fred::f() { }\n" "template<> void Fred::g() { }\n"; - const char expected[] = "template < class T > void Fred :: f ( ) { } " - "template < > void Fred :: f ( ) { } " - "template < > void Fred :: g ( ) { } " - "class Fred { void f ( ) ; } ; " - "Fred :: f ( ) { } " - "class Fred { void f ( ) ; } ; " - "class Fred { void f ( ) ; } ;"; + const char expected[] = "template < class T > void Fred < T > :: f ( ) { } " + "template < > void Fred < float > :: f ( ) { } " + "template < > void Fred < int > :: g ( ) { } " + "class Fred < T > { void f ( ) ; } ; " + "Fred < T > :: f ( ) { } " + "class Fred < float > { void f ( ) ; } ; " + "class Fred < int > { void f ( ) ; } ;"; ASSERT_EQUALS(expected, tok(code)); } @@ -981,13 +982,13 @@ private: void template55() { // #6604 // Avoid constconstconst in macro instantiations ASSERT_EQUALS( - "class AtSmartPtr : public ConstCastHelper < AtSmartPtr , T > { " - "friend struct ConstCastHelper < AtSmartPtr , T > ; " - "AtSmartPtr ( const AtSmartPtr & r ) ; " + "class AtSmartPtr < T > : public ConstCastHelper < AtSmartPtr < const T > , T > { " + "friend struct ConstCastHelper < AtSmartPtr < const T > , T > ; " + "AtSmartPtr < T > ( const AtSmartPtr < T > & r ) ; " "} ; " - "class AtSmartPtr : public ConstCastHelper < AtSmartPtr < const const T > , const T > { " + "class AtSmartPtr < const T > : public ConstCastHelper < AtSmartPtr < const const T > , const T > { " "friend struct ConstCastHelper < AtSmartPtr < const const T > , const T > ; " - "AtSmartPtr ( const AtSmartPtr & r ) ; } ;", + "AtSmartPtr < const T > ( const AtSmartPtr < T > & r ) ; } ;", tok("template class AtSmartPtr : public ConstCastHelper, T>\n" "{\n" " friend struct ConstCastHelper, T>;\n" @@ -996,11 +997,11 @@ private: // Similar problem can also happen with ... ASSERT_EQUALS( - "A a ( 0 ) ; struct A { " - "A ( int * p ) { p ; } " + "A < int > a ( 0 ) ; struct A < int > { " + "A < int > ( int * p ) { p ; } " "} ; " - "struct A { " - "A ( int * p ) { " + "struct A < int . . . > { " + "A < int . . . > ( int * p ) { " "p ; " "} } ;", tok("template struct A\n" @@ -1022,6 +1023,14 @@ private: ASSERT_EQUALS("", errout.str()); } + void template57() { // #7891 + const char code[] = "template struct Test { Test(T); };\n" + "Test test( 0 );"; + const char exp [] = "Test < unsigned long > test ( 0 ) ; " + "struct Test < unsigned long > { Test < unsigned long > ( long ) ; } ;"; + ASSERT_EQUALS(exp, tok(code)); + } + void template_enum() { const char code1[] = "template \n" "struct Unconst {\n" @@ -1052,8 +1061,19 @@ private: "{\n" " enum {value = !type_equal::type>::value };\n" "};"; - const char expected1[]="template < class T > struct Unconst { } ; template < class T > struct type_equal { enum Anonymous1 { value = 1 } ; } ; template < class T > struct template_is_const { enum Anonymous2 { value = ! type_equal < T , Unconst < T > :: type > :: value } ; } ; struct type_equal { enum Anonymous0 { value = 0 } ; } ; struct Unconst { } ; struct Unconst { } ; struct Unconst { } ; struct Unconst { } ; struct Unconst { } ; struct Unconst { } ; struct Unconst<};template { } ; struct Unconst<};template { } ;"; - ASSERT_EQUALS(expected1, tok(code1)); + const char exp1[] = "template < class T > struct Unconst { } ; " + "template < class T > struct type_equal < T , T > { enum Anonymous1 { value = 1 } ; } ; " + "template < class T > struct template_is_const { enum Anonymous2 { value = ! type_equal < T , Unconst < T > :: type > :: value } ; } ; " + "struct type_equal < T , T > { enum Anonymous0 { value = 0 } ; } ; " + "struct Unconst < const T * const > { } ; " + "struct Unconst < const T & * const > { } ; " + "struct Unconst < T * const * const > { } ; " + "struct Unconst < T * const > { } ; " + "struct Unconst < T * const > { } ; " + "struct Unconst < T * const > { } ; " + "struct Unconst < const T & > { } ; " + "struct Unconst < const T > { } ;"; + ASSERT_EQUALS(exp1, tok(code1)); } void template_default_parameter() { @@ -1071,12 +1091,12 @@ private: // The expected result.. const char expected[] = "void f ( ) " "{" - " A a1 ;" - " A a2 ; " + " A < int , 2 > a1 ;" + " A < int , 3 > a2 ; " "} " - "class A " + "class A < int , 2 > " "{ int ar [ 2 ] ; } ; " - "class A " + "class A < int , 3 > " "{ int ar [ 3 ] ; } ;"; ASSERT_EQUALS(expected, tok(code)); } @@ -1094,10 +1114,10 @@ private: // The expected result.. const char expected[] = "void f ( ) " "{" - " A a1 ;" - " A a2 ; " + " A < int , 3 , 2 > a1 ;" + " A < int , 3 , 2 > a2 ; " "} " - "class A " + "class A < int , 3 , 2 > " "{ int ar [ 5 ] ; } ;"; ASSERT_EQUALS(expected, tok(code)); } @@ -1128,9 +1148,9 @@ private: const char current[] = "void f ( ) " "{ " "A < int , ( int ) 2 > a1 ; " - "A a2 ; " + "A < int , 3 > a2 ; " "} " - "class A " + "class A < int , 3 > " "{ int ar [ 3 ] ; } ;"; TODO_ASSERT_EQUALS(wanted, current, tok(code)); } @@ -1150,11 +1170,11 @@ private: "template > class thv_table_c {}; " "thv_table_c id_table_m;"; const char exp [] = "template < class T , class U > class DefaultMemory { } ; " - "thv_table_c> id_table_m ; " - "class thv_table_c> { } ;"; + "thv_table_c> id_table_m ; " + "class thv_table_c> { } ;"; const char curr[] = "template < class T , class U > class DefaultMemory { } ; " - "thv_table_c> id_table_m ; " - "class thv_table_c> { } ;"; + "thv_table_c < void * , void * , DefaultMemory < Key , Val > > id_table_m ; " + "class thv_table_c < void * , void * , DefaultMemory < Key , Val > > { } ;"; TODO_ASSERT_EQUALS(exp, curr, tok(code)); } } @@ -1365,8 +1385,8 @@ private: } void expandSpecialized() { - ASSERT_EQUALS("class A { } ;", tok("template<> class A {};")); - ASSERT_EQUALS("class A : public B { } ;", tok("template<> class A : public B {};")); + ASSERT_EQUALS("class A < int > { } ;", tok("template<> class A {};")); + ASSERT_EQUALS("class A < int > : public B { } ;", tok("template<> class A : public B {};")); } }; diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 7e3ea5ec6..a4fb66208 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -2507,8 +2507,8 @@ private: "TClass :: TClass ( const TClass & other ) " "{ " "operator= ( other ) ; " - "} class SharedPtr { " - "SharedPtr & operator= ( SharedPtr const & r ) ; " + "} class SharedPtr < Y > { " + "SharedPtr < Y > & operator= ( SharedPtr < Y > const & r ) ; " "} ;", tok("template\n" " class SharedPtr {\n" diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 5e9b1edf4..fd5117267 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -4861,7 +4861,7 @@ private: "{\n" " fn2();\n" "}\n"; - ASSERT_EQUALS("int main ( )\n{\nfn2 ( ) ;\n} void fn2 ( int t = [ ] { return 1 ; } ( ) )\n{ }", tokenizeAndStringify(code)); + ASSERT_EQUALS("int main ( )\n{\nfn2 < int > ( ) ;\n} void fn2 < int > ( int t = [ ] { return 1 ; } ( ) )\n{ }", tokenizeAndStringify(code)); } void cpp0xtemplate2() {