"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "test/testsimplifytemplate.cpp" between
cppcheck-1.86.tar.gz and cppcheck-1.87.tar.gz

About: Cppcheck is a static analysis tool for C/C++ code. It checks for memory leaks, mismatching allocation-deallocation, buffer overrun, and many more.

testsimplifytemplate.cpp  (cppcheck-1.86):testsimplifytemplate.cpp  (cppcheck-1.87)
/* /*
* Cppcheck - A tool for static C/C++ code analysis * Cppcheck - A tool for static C/C++ code analysis
* Copyright (C) 2007-2018 Cppcheck team. * Copyright (C) 2007-2019 Cppcheck team.
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
skipping to change at line 37 skipping to change at line 37
struct InternalError; struct InternalError;
class TestSimplifyTemplate : public TestFixture { class TestSimplifyTemplate : public TestFixture {
public: public:
TestSimplifyTemplate() : TestFixture("TestSimplifyTemplate") { TestSimplifyTemplate() : TestFixture("TestSimplifyTemplate") {
} }
private: private:
Settings settings; Settings settings;
void run() override { void run() OVERRIDE {
settings.addEnabled("portability"); settings.addEnabled("portability");
TEST_CASE(template1); TEST_CASE(template1);
TEST_CASE(template2); TEST_CASE(template2);
TEST_CASE(template3); TEST_CASE(template3);
TEST_CASE(template4); TEST_CASE(template4);
TEST_CASE(template5); TEST_CASE(template5);
TEST_CASE(template6); TEST_CASE(template6);
TEST_CASE(template7); TEST_CASE(template7);
TEST_CASE(template8); TEST_CASE(template8);
skipping to change at line 123 skipping to change at line 123
TEST_CASE(template75); TEST_CASE(template75);
TEST_CASE(template76); TEST_CASE(template76);
TEST_CASE(template77); TEST_CASE(template77);
TEST_CASE(template78); TEST_CASE(template78);
TEST_CASE(template79); // #5133 TEST_CASE(template79); // #5133
TEST_CASE(template80); TEST_CASE(template80);
TEST_CASE(template81); TEST_CASE(template81);
TEST_CASE(template82); // 8603 TEST_CASE(template82); // 8603
TEST_CASE(template83); TEST_CASE(template83);
TEST_CASE(template84); // #8880 TEST_CASE(template84); // #8880
TEST_CASE(template85); // #8902 crash
TEST_CASE(template86); // crash
TEST_CASE(template87);
TEST_CASE(template88); // #6183
TEST_CASE(template89); // #8917
TEST_CASE(template90); // crash
TEST_CASE(template91);
TEST_CASE(template92);
TEST_CASE(template93); // crash
TEST_CASE(template94); // #8927 crash
TEST_CASE(template95); // #7417
TEST_CASE(template96); // #7854
TEST_CASE(template97);
TEST_CASE(template98); // #8959
TEST_CASE(template99); // #8960
TEST_CASE(template100); // #8967
TEST_CASE(template101); // #8968
TEST_CASE(template_specialization_1); // #7868 - template specializatio n template <typename T> struct S<C<T>> {..}; TEST_CASE(template_specialization_1); // #7868 - template specializatio n template <typename T> struct S<C<T>> {..};
TEST_CASE(template_specialization_2); // #7868 - template specializatio n template <typename T> struct S<C<T>> {..}; TEST_CASE(template_specialization_2); // #7868 - template specializatio n template <typename T> struct S<C<T>> {..};
TEST_CASE(template_enum); // #6299 Syntax error in complex enum declara tion (including template) TEST_CASE(template_enum); // #6299 Syntax error in complex enum declara tion (including template)
TEST_CASE(template_unhandled); TEST_CASE(template_unhandled);
TEST_CASE(template_default_parameter); TEST_CASE(template_default_parameter);
TEST_CASE(template_forward_declared_default_parameter); TEST_CASE(template_forward_declared_default_parameter);
TEST_CASE(template_default_type); TEST_CASE(template_default_type);
TEST_CASE(template_typename); TEST_CASE(template_typename);
TEST_CASE(template_constructor); // #3152 - template constructor is r emoved TEST_CASE(template_constructor); // #3152 - template constructor is r emoved
TEST_CASE(syntax_error_templates_1); TEST_CASE(syntax_error_templates_1);
skipping to change at line 477 skipping to change at line 494
void template14() { void template14() {
const char code[] = "template <> void foo<int *>()\n" const char code[] = "template <> void foo<int *>()\n"
"{ x(); }\n" "{ x(); }\n"
"\n" "\n"
"int main()\n" "int main()\n"
"{\n" "{\n"
"foo<int*>();\n" "foo<int*>();\n"
"}\n"; "}\n";
// The expected result.. // The expected result..
const char expected[] = "void foo<int*> ( ) " const char expected[] = "void foo<int*> ( ) ; "
"void foo<int*> ( ) "
"{ x ( ) ; } " "{ x ( ) ; } "
"int main ( ) " "int main ( ) "
"{ foo<int*> ( ) ; }"; "{ foo<int*> ( ) ; }";
ASSERT_EQUALS(expected, tok(code)); ASSERT_EQUALS(expected, tok(code));
} }
void template15() { // recursive templates #3130 etc void template15() { // recursive templates #3130 etc
const char code[] = "template <unsigned int i> void a()\n" const char code[] = "template <unsigned int i> void a()\n"
"{\n" "{\n"
skipping to change at line 501 skipping to change at line 519
"template <> void a<0>()\n" "template <> void a<0>()\n"
"{ }\n" "{ }\n"
"\n" "\n"
"int main()\n" "int main()\n"
"{\n" "{\n"
" a<2>();\n" " a<2>();\n"
" return 0;\n" " return 0;\n"
"}\n"; "}\n";
// The expected result.. // The expected result..
const char expected[] = "void a<2> ( ) ; " const char expected[] = "void a<0> ( ) ; "
"void a<2> ( ) ; "
"void a<1> ( ) ; " "void a<1> ( ) ; "
"void a<0> ( ) { } " "void a<0> ( ) { } "
"int main ( ) " "int main ( ) "
"{ a<2> ( ) ; return 0 ; } " "{ a<2> ( ) ; return 0 ; } "
"void a<2> ( ) { a<1> ( ) ; } " "void a<2> ( ) { a<1> ( ) ; } "
"void a<1> ( ) { a<0> ( ) ; }"; "void a<1> ( ) { a<0> ( ) ; }";
ASSERT_EQUALS(expected, tok(code)); ASSERT_EQUALS(expected, tok(code));
// #3130 // #3130
skipping to change at line 917 skipping to change at line 936
" const vector<int> vi = static_cast<vector<int>>(v );" " const vector<int> vi = static_cast<vector<int>>(v );"
"}"; "}";
tok(code); tok(code);
} }
void template40() { // #5055 - false negatives when there is template specia lization outside struct void template40() { // #5055 - false negatives when there is template specia lization outside struct
const char code[] = "struct A {" const char code[] = "struct A {"
" template<typename T> struct X { T t; };" " template<typename T> struct X { T t; };"
"};" "};"
"template<> struct A::X<int> { int *t; };"; "template<> struct A::X<int> { int *t; };";
ASSERT_EQUALS("struct A { template < typename T > struct X { T t ; } ; } ;", tok(code)); ASSERT_EQUALS("struct A { struct X<int> ; } ; struct A :: X<int> { int t ; } ;", tok(code));
} }
void template41() { // #4710 - const in template instantiation not handled p erfectly void template41() { // #4710 - const in template instantiation not handled p erfectly
const char code1[] = "template<class T> struct X { };\n" const char code1[] = "template<class T> struct X { };\n"
"void f(const X<int> x) { }"; "void f(const X<int> x) { }";
ASSERT_EQUALS("struct X<int> ; " ASSERT_EQUALS("struct X<int> ; "
"void f ( const X<int> x ) { } " "void f ( const X<int> x ) { } "
"struct X<int> { } ;", tok(code1)); "struct X<int> { } ;", tok(code1));
const char code2[] = "template<class T> T f(T t) { return t; }\n" const char code2[] = "template<class T> T f(T t) { return t; }\n"
skipping to change at line 1020 skipping to change at line 1039
void template49() { // #6237 void template49() { // #6237
const char code[] = "template <class T> class Fred { void f(); void g(); };\n" const char code[] = "template <class T> class Fred { void f(); void g(); };\n"
"template <class T> void Fred<T>::f() { }\n" "template <class T> void Fred<T>::f() { }\n"
"template <class T> void Fred<T>::g() { }\n" "template <class T> void Fred<T>::g() { }\n"
"template void Fred<float>::f();\n" "template void Fred<float>::f();\n"
"template void Fred<int>::g();\n"; "template void Fred<int>::g();\n";
const char expected[] = "class Fred<float> ; " const char expected[] = "class Fred<float> ; "
"class Fred<int> ; " "class Fred<int> ; "
"template void Fred<float> :: f ( ) ; "
"template void Fred<int> :: g ( ) ; "
"class Fred<float> { void f ( ) ; void g ( ) ; } ; " "class Fred<float> { void f ( ) ; void g ( ) ; } ; "
"void Fred<float> :: f ( ) { } " "void Fred<float> :: f ( ) { } "
"void Fred<float> :: g ( ) { } " "void Fred<float> :: g ( ) { } "
"class Fred<int> { void f ( ) ; void g ( ) ; } ; " "class Fred<int> { void f ( ) ; void g ( ) ; } ; "
"void Fred<int> :: f ( ) { } " "void Fred<int> :: f ( ) { } "
"void Fred<int> :: g ( ) { }"; "void Fred<int> :: g ( ) { }";
ASSERT_EQUALS(expected, tok(code)); ASSERT_EQUALS(expected, tok(code));
} }
void template50() { // #4272 void template50() { // #4272
const char code[] = "template <class T> class Fred { void f(); };\n" const char code[] = "template <class T> class Fred { void f(); };\n"
"template <class T> void Fred<T>::f() { }\n" "template <class T> void Fred<T>::f() { }\n"
"template<> void Fred<float>::f() { }\n" "template<> void Fred<float>::f() { }\n"
"template<> void Fred<int>::g() { }\n"; "template<> void Fred<int>::f() { }\n";
const char expected[] = "template < class T > class Fred { void f ( ) ; const char expected[] = "class Fred<float> ; "
} ; " "class Fred<int> ; "
"template < class T > void Fred < T > :: f ( ) { "template < > void Fred<float> :: f ( ) { } "
} " "template < > void Fred<int> :: f ( ) { } "
"template < > void Fred < float > :: f ( ) { } " "class Fred<float> { void f ( ) ; } ; "
"template < > void Fred < int > :: g ( ) { }"; "void Fred<float> :: f ( ) { } "
"class Fred<int> { void f ( ) ; } ; "
"void Fred<int> :: f ( ) { }";
ASSERT_EQUALS(expected, tok(code)); ASSERT_EQUALS(expected, tok(code));
} }
void template51() { // #6172 void template51() { // #6172
tok("template<int N, int ... M> struct A { " tok("template<int N, int ... M> struct A { "
" static void foo() { " " static void foo() { "
" int i = N; " " int i = N; "
" } " " } "
"}; " "}; "
skipping to change at line 1265 skipping to change at line 1286
"}\n" "}\n"
"void t_caller()\n" "void t_caller()\n"
"{\n" "{\n"
" t_func<0>();\n" " t_func<0>();\n"
" t_func<1>();\n" " t_func<1>();\n"
"}\n" "}\n"
"};"; "};";
tok(code); // don't crash tok(code); // don't crash
} }
void template65() { // #8321 void template65() { // #8321 (crash)
const char code[] = "namespace bpp\n" const char code[] = "namespace bpp\n"
"{\n" "{\n"
"template<class N, class E, class DAGraphImpl>\n" "template<class N, class E, class DAGraphImpl>\n"
"class AssociationDAGraphImplObserver :\n" "class AssociationDAGraphImplObserver :\n"
" public AssociationGraphImplObserver<N, E, DAGraph Impl>\n" " public AssociationGraphImplObserver<N, E, DAGraph Impl>\n"
"{};\n" "{};\n"
"template<class N, class E>\n" "template<class N, class E>\n"
"using AssociationDAGlobalGraphObserver = Associati onDAGraphImplObserver<N, E, DAGlobalGraph>;\n" "using AssociationDAGlobalGraphObserver = Associati onDAGraphImplObserver<N, E, DAGlobalGraph>;\n"
"}\n" "}\n"
"using namespace bpp;\n" "using namespace bpp;\n"
"using namespace std;\n" "using namespace std;\n"
"int main() {\n" "int main() {\n"
" AssociationDAGlobalGraphObserver<string,unsigned int> grObs;\n" " AssociationDAGlobalGraphObserver<string,unsigned int> grObs;\n"
" return 1;\n" " return 1;\n"
"}"; "}";
tok(code); // don't crash const char exp [] = "namespace bpp "
"{ "
"class AssociationDAGraphImplObserver<string,unsigne
dint,DAGlobalGraph> ; "
"} "
"using namespace bpp ; "
"int main ( ) { "
"bpp :: AssociationDAGraphImplObserver<string,unsign
edint,DAGlobalGraph> grObs ; "
"return 1 ; "
"} class bpp :: AssociationDAGraphImplObserver<strin
g,unsignedint,DAGlobalGraph> : "
"public AssociationGraphImplObserver < std :: string
, int , DAGlobalGraph > "
"{ } ;";
ASSERT_EQUALS(exp, tok(code));
} }
void template66() { // #8725 void template66() { // #8725
const char code[] = "template <class T> struct Fred {\n" const char code[] = "template <class T> struct Fred {\n"
" const int ** foo();\n" " const int ** foo();\n"
"};\n" "};\n"
"template <class T> const int ** Fred<T>::foo() { re turn nullptr; }\n" "template <class T> const int ** Fred<T>::foo() { re turn nullptr; }\n"
"Fred<int> fred;"; "Fred<int> fred;";
const char exp [] = "struct Fred<int> ; " const char exp [] = "struct Fred<int> ; "
"Fred<int> fred ; " "Fred<int> fred ; "
"struct Fred<int> { " "struct Fred<int> { "
"const int * * foo ( ) ; " "const int * * foo ( ) ; "
"} ; " "} ; "
"const int * * Fred<int> :: foo ( ) { return nullptr ; }"; "const int * * Fred<int> :: foo ( ) { return nullptr ; }";
ASSERT_EQUALS(exp, tok(code)); ASSERT_EQUALS(exp, tok(code));
} }
void template67() { // ticket #8122 void template67() { // ticket #8122
const char code[] = "template <class T> struct Containter {\n" const char code[] = "template <class T> struct Container {\n"
" Containter();\n" " Container();\n"
" Containter(const Containter &);\n" " Container(const Container &);\n"
" Containter & operator = (const Containter &);\n" " Container & operator = (const Container &);\n"
" ~Containter();\n" " ~Container();\n"
" T* mElements;\n" " T* mElements;\n"
" const Containter * c;\n" " const Container * c;\n"
"};\n" "};\n"
"template <class T> Containter<T>::Containter() : mE "template <class T> Container<T>::Container() : mEle
lements(nullptr), c(nullptr) {}\n" ments(nullptr), c(nullptr) {}\n"
"template <class T> Containter<T>::Containter(const "template <class T> Container<T>::Container(const Co
Containter & x) { nElements = x.nElements; c = x.c; }\n" ntainer & x) { nElements = x.nElements; c = x.c; }\n"
"template <class T> Containter<T> & Containter<T>::o "template <class T> Container<T> & Container<T>::ope
perator = (const Containter & x) { mElements = x.mElements; c = x.c; return *thi rator = (const Container & x) { mElements = x.mElements; c = x.c; return *this;
s; }\n" }\n"
"template <class T> Containter<T>::~Containter() {}\ "template <class T> Container<T>::~Container() {}\n"
n" "Container<int> intContainer;";
"Containter<int> intContainer;";
const char expected[] = "struct Container<int> ; "
const char expected[] = "struct Containter<int> ; " "Container<int> intContainer ; "
"Containter<int> intContainer ; " "struct Container<int> { "
"struct Containter<int> { " "Container<int> ( ) ; "
"Containter<int> ( ) ; " "Container<int> ( const Container<int> & ) ; "
"Containter<int> ( const Containter<int> & ) ; " "Container<int> & operator= ( const Container<in
"Containter<int> & operator= ( const Containter< t> & ) ; "
int> & ) ; " "~ Container<int> ( ) ; "
"~ Containter<int> ( ) ; "
"int * mElements ; " "int * mElements ; "
"const Containter<int> * c ; " "const Container<int> * c ; "
"} ; " "} ; "
"Containter<int> :: Containter<int> ( ) : mEleme "Container<int> :: Container<int> ( ) : mElement
nts ( nullptr ) , c ( nullptr ) { } " s ( nullptr ) , c ( nullptr ) { } "
"Containter<int> :: Containter<int> ( const Cont "Container<int> :: Container<int> ( const Contai
ainter<int> & x ) { nElements = x . nElements ; c = x . c ; } " ner<int> & x ) { nElements = x . nElements ; c = x . c ; } "
"Containter<int> & Containter<int> :: operator= "Container<int> & Container<int> :: operator= (
( const Containter<int> & x ) { mElements = x . mElements ; c = x . c ; return * const Container<int> & x ) { mElements = x . mElements ; c = x . c ; return * th
this ; } " is ; } "
"Containter<int> :: ~ Containter<int> ( ) { }"; "Container<int> :: ~ Container<int> ( ) { }";
ASSERT_EQUALS(expected, tok(code)); ASSERT_EQUALS(expected, tok(code));
} }
void template68() { void template68() {
const char code[] = "template <class T> union Fred {\n" const char code[] = "template <class T> union Fred {\n"
" char dummy[sizeof(T)];\n" " char dummy[sizeof(T)];\n"
" T value;\n" " T value;\n"
"};\n" "};\n"
"Fred<int> fred;"; "Fred<int> fred;";
skipping to change at line 1419 skipping to change at line 1451
"template < typename N , typename P > " "template < typename N , typename P > "
"Tokenizer < N , P > :: Tokenizer ( ) { }"; "Tokenizer < N , P > :: Tokenizer ( ) { }";
ASSERT_EQUALS(exp, tok(code)); ASSERT_EQUALS(exp, tok(code));
} }
void template73() { void template73() {
const char code[] = "template<typename T>\n" const char code[] = "template<typename T>\n"
"void keep_range(T& value, const T mini, const T max i){}\n" "void keep_range(T& value, const T mini, const T max i){}\n"
"template void keep_range<float>(float& v, const flo at l, const float u);\n" "template void keep_range<float>(float& v, const flo at l, const float u);\n"
"template void keep_range<int>(int& v, const int l, const int u);"; "template void keep_range<int>(int& v, const int l, const int u);";
const char exp[] = "void keep_range<float> ( float & v , const float l , const char exp[] = "void keep_range<float> ( float & value , const float
const float u ) ; " mini , const float maxi ) ; "
"void keep_range<int> ( int & v , const int l , const "void keep_range<int> ( int & value , const int mini
int u ) ; " , const int maxi ) ; "
"void keep_range<float> ( float & value , const float mini , const float maxi ) { } " "void keep_range<float> ( float & value , const float mini , const float maxi ) { } "
"void keep_range<int> ( int & value , const int mini , const int maxi ) { }"; "void keep_range<int> ( int & value , const int mini , const int maxi ) { }";
ASSERT_EQUALS(exp, tok(code)); ASSERT_EQUALS(exp, tok(code));
} }
void template74() { void template74() {
const char code[] = "template <class T> class BTlist { };\n" const char code[] = "template <class T> class BTlist { };\n"
"class PushBackStreamBuf {\n" "class PushBackStreamBuf {\n"
"public:\n" "public:\n"
" void pushBack(const BTlist<int> &vec);\n" " void pushBack(const BTlist<int> &vec);\n"
skipping to change at line 1445 skipping to change at line 1477
"void pushBack ( const BTlist<int> & vec ) ; " "void pushBack ( const BTlist<int> & vec ) ; "
"} ; " "} ; "
"class BTlist<int> { } ;"; "class BTlist<int> { } ;";
ASSERT_EQUALS(exp, tok(code)); ASSERT_EQUALS(exp, tok(code));
} }
void template75() { void template75() {
const char code[] = "template<typename T>\n" const char code[] = "template<typename T>\n"
"T foo(T& value){ return value; }\n" "T foo(T& value){ return value; }\n"
"template std::vector<std::vector<int>> foo<std::vec tor<std::vector<int>>>(std::vector<std::vector<int>>& v);"; "template std::vector<std::vector<int>> foo<std::vec tor<std::vector<int>>>(std::vector<std::vector<int>>& v);";
const char exp[] = "std :: vector < std :: vector < int > > foo<std::vec tor<std::vector<int>>> ( std :: vector < std :: vector < int > > & v ) ; " const char exp[] = "std :: vector < std :: vector < int > > foo<std::vec tor<std::vector<int>>> ( std :: vector < std :: vector < int > > & value ) ; "
"std :: vector < std :: vector < int > > foo<std::vec tor<std::vector<int>>> ( std :: vector < std :: vector < int > > & value ) { ret urn value ; }"; "std :: vector < std :: vector < int > > foo<std::vec tor<std::vector<int>>> ( std :: vector < std :: vector < int > > & value ) { ret urn value ; }";
ASSERT_EQUALS(exp, tok(code)); ASSERT_EQUALS(exp, tok(code));
} }
void template76() { void template76() {
const char code[] = "namespace NS {\n" const char code[] = "namespace NS {\n"
" template<typename T> T foo(T& value) { return v alue; }\n" " template<typename T> T foo(T& value) { return v alue; }\n"
" template std::vector<std::vector<int>> foo<std: :vector<std::vector<int>>>(std::vector<std::vector<int>>& v);\n" " template std::vector<std::vector<int>> foo<std: :vector<std::vector<int>>>(std::vector<std::vector<int>>& v);\n"
"}\n" "}\n"
"std::vector<std::vector<int>> v;\n" "std::vector<std::vector<int>> v;\n"
"v = foo<std::vector<std::vector<int>>>(v);\n"; "v = foo<std::vector<std::vector<int>>>(v);\n";
const char exp[] = "namespace NS { " const char exp[] = "namespace NS { "
"std :: vector < std :: vector < int > > foo<std::vec tor<std::vector<int>>> ( std :: vector < std :: vector < int > > & v ) ; " "std :: vector < std :: vector < int > > foo<std::vec tor<std::vector<int>>> ( std :: vector < std :: vector < int > > & value ) ; "
"} " "} "
"std :: vector < std :: vector < int > > v ; " "std :: vector < std :: vector < int > > v ; "
"v = foo<std::vector<std::vector<int>>> ( v ) ; " "v = foo<std::vector<std::vector<int>>> ( v ) ; "
"std :: vector < std :: vector < int > > NS :: foo<st d::vector<std::vector<int>>> ( std :: vector < std :: vector < int > > & value ) { return value ; }"; "std :: vector < std :: vector < int > > NS :: foo<st d::vector<std::vector<int>>> ( std :: vector < std :: vector < int > > & value ) { return value ; }";
ASSERT_EQUALS(exp, tok(code)); ASSERT_EQUALS(exp, tok(code));
} }
void template77() { void template77() {
const char code[] = "template<typename T>\n" const char code[] = "template<typename T>\n"
"struct is_void : std::false_type { };\n" "struct is_void : std::false_type { };\n"
skipping to change at line 1585 skipping to change at line 1617
"}"; "}";
const char exp[] = "class tvec2<f16> ; " const char exp[] = "class tvec2<f16> ; "
"class tvec3<f16> ; " "class tvec3<f16> ; "
"namespace swizzle { " "namespace swizzle { "
"void swizzle<1> ( tvec2<f16> v ) ; " "void swizzle<1> ( tvec2<f16> v ) ; "
"void swizzle<2,3> ( tvec3<f16> v ) ; " "void swizzle<2,3> ( tvec3<f16> v ) ; "
"} " "} "
"void foo ( ) { " "void foo ( ) { "
"using namespace swizzle ; " "using namespace swizzle ; "
"tvec2<f16> tt2 ; " "tvec2<f16> tt2 ; "
"swizzle<1> ( tt2 ) ; " "swizzle :: swizzle<1> ( tt2 ) ; "
"tvec3<f16> tt3 ; " "tvec3<f16> tt3 ; "
"swizzle<2,3> ( tt3 ) ; " "swizzle :: swizzle<2,3> ( tt3 ) ; "
"} " "} "
"void swizzle :: swizzle<2,3> ( tvec3<f16> v ) { } " "void swizzle :: swizzle<2,3> ( tvec3<f16> v ) { } "
"void swizzle :: swizzle<1> ( tvec2<f16> v ) { } " "void swizzle :: swizzle<1> ( tvec2<f16> v ) { } "
"class tvec3<f16> { } ; " "class tvec3<f16> { } ; "
"class tvec2<f16> { } ;"; "class tvec2<f16> { } ;";
ASSERT_EQUALS(exp, tok(code)); ASSERT_EQUALS(exp, tok(code));
} }
void template83() { void template83() {
const char code[] = "template<typename Task>\n" const char code[] = "template<typename Task>\n"
skipping to change at line 1622 skipping to change at line 1654
"auto d() -> typename a<decltype(b{})>::e {\n" "auto d() -> typename a<decltype(b{})>::e {\n"
" d<int, c, int>();\n" " d<int, c, int>();\n"
"}"; "}";
const char exp[] = "auto d<int,c,int> ( ) . a < decltype ( int { } ) > : : e ; " const char exp[] = "auto d<int,c,int> ( ) . a < decltype ( int { } ) > : : e ; "
"auto d<int,c,int> ( ) . a < decltype ( int { } ) > : : e { " "auto d<int,c,int> ( ) . a < decltype ( int { } ) > : : e { "
"d<int,c,int> ( ) ; " "d<int,c,int> ( ) ; "
"}"; "}";
ASSERT_EQUALS(exp, tok(code)); ASSERT_EQUALS(exp, tok(code));
} }
void template85() { // #8902 - crash
const char code[] = "template<typename T>\n"
"struct C\n"
"{\n"
" template<typename U, typename std::enable_if<(!st
d::is_fundamental<U>::value)>::type* = nullptr>\n"
" void foo();\n"
"};\n"
"extern template void C<int>::foo<int, nullptr>();\n
"
"template<typename T>\n"
"template<typename U, typename std::enable_if<(!std:
:is_fundamental<U>::value)>::type>\n"
"void C<T>::foo() {}";
// @todo the output is very wrong but we are only worried about the cras
h for now
tok(code);
}
void template86() { // crash
const char code[] = "struct S {\n"
" S();\n"
"};\n"
"template <typename T>\n"
"struct U {\n"
" static S<T> u;\n"
"};\n"
"template <typename T>\n"
"S<T> U<T>::u;\n"
"template S<int> U<int>::u;\n"
"S<int> &i = U<int>::u;";
tok(code);
}
void template87() {
const char code[] = "template<typename T>\n"
"T f1(T t) { return t; }\n"
"template const char * f1<const char *>();\n"
"template const char & f1<const char &>();";
const char exp[] = "const char * f1<constchar*> ( const char * t ) ; "
"const char & f1<constchar&> ( const char & t ) ; "
"const char * f1<constchar*> ( const char * t ) { ret
urn t ; } "
"const char & f1<constchar&> ( const char & t ) { ret
urn t ; }";
ASSERT_EQUALS(exp, tok(code));
}
void template88() { // #6183.cpp
const char code[] = "class CTest {\n"
"public:\n"
" template <typename T>\n"
" static void Greeting(T val) {\n"
" std::cout << val << std::endl;\n"
" }\n"
"private:\n"
" static void SayHello() {\n"
" std::cout << \"Hello World!\" << std::endl;
\n"
" }\n"
"};\n"
"template<>\n"
"void CTest::Greeting(bool) {\n"
" CTest::SayHello();\n"
"}\n"
"int main() {\n"
" CTest::Greeting<bool>(true);\n"
" return 0;\n"
"}";
const char exp[] = "class CTest { "
"public: "
"static void Greeting<bool> ( bool ) ; "
"template < typename T > "
"static void Greeting ( T val ) { "
"std :: cout << val << std :: endl ; "
"} "
"private: "
"static void SayHello ( ) { "
"std :: cout << \"Hello World!\" << std :: endl ; "
"} "
"} ; "
"void CTest :: Greeting<bool> ( bool ) { "
"CTest :: SayHello ( ) ; "
"} "
"int main ( ) { "
"CTest :: Greeting<bool> ( true ) ; "
"return 0 ; "
"}";
ASSERT_EQUALS(exp, tok(code));
}
void template89() { // #8917
const char code[] = "struct Fred {\n"
" template <typename T> static void foo() { }\n"
"};\n"
"template void Fred::foo<char>();\n"
"template void Fred::foo<float>();\n"
"template <> void Fred::foo<bool>() { }\n"
"template <> void Fred::foo<int>() { }";
const char exp[] = "struct Fred { "
"static void foo<int> ( ) ; "
"static void foo<bool> ( ) ; "
"static void foo<char> ( ) ; "
"static void foo<float> ( ) ; "
"} ; "
"void Fred :: foo<bool> ( ) { } "
"void Fred :: foo<int> ( ) { } "
"void Fred :: foo<char> ( ) { } "
"void Fred :: foo<float> ( ) { }";
ASSERT_EQUALS(exp, tok(code));
}
void template90() { // crash
const char code[] = "template <typename T> struct S1 {};\n"
"void f(S1<double>) {}\n"
"template <typename T>\n"
"decltype(S1<T>().~S1<T>()) fun1() {};";
const char exp[] = "struct S1<double> ; "
"void f ( S1<double> ) { } "
"template < typename T > "
"decltype ( S1 < T > ( ) . ~ S1 < T > ( ) ) fun1 ( )
{ } ; "
"struct S1<double> { } ;";
ASSERT_EQUALS(exp, tok(code));
}
void template91() {
{
const char code[] = "template<typename T> T foo(T t) { return t; }\n
"
"template<> char foo<char>(char a) { return a; }
\n"
"template<> int foo<int>(int a) { return a; }\n"
"template float foo<float>(float);\n"
"template double foo<double>(double);";
const char exp[] = "int foo<int> ( int a ) ; "
"char foo<char> ( char a ) ; "
"float foo<float> ( float t ) ; "
"double foo<double> ( double t ) ; "
"char foo<char> ( char a ) { return a ; } "
"int foo<int> ( int a ) { return a ; } "
"float foo<float> ( float t ) { return t ; } "
"double foo<double> ( double t ) { return t ; }";
ASSERT_EQUALS(exp, tok(code));
}
{
const char code[] = "struct Fred {\n"
" template<typename T> T foo(T t) { return t;
}\n"
" template<> char foo<char>(char a) { return
a; }\n"
" template<> int foo<int>(int a) { return a;
}\n"
"};\n"
"template float Fred::foo<float>(float);\n"
"template double Fred::foo<double>(double);";
const char exp[] = "struct Fred { "
"int foo<int> ( int a ) ; "
"char foo<char> ( char a ) ; "
"float foo<float> ( float t ) ; "
"double foo<double> ( double t ) ; "
"char foo<char> ( char a ) { return a ; } "
"int foo<int> ( int a ) { return a ; } "
"} ; "
"float Fred :: foo<float> ( float t ) { return t
; } "
"double Fred :: foo<double> ( double t ) { return
t ; }";
ASSERT_EQUALS(exp, tok(code));
}
{
const char code[] = "namespace NS1 {\n"
" namespace NS2 {\n"
" template<typename T> T foo(T t) { retur
n t; }\n"
" template<> char foo<char>(char a) { ret
urn a; }\n"
" template<> int foo<int>(int a) { return
a; }\n"
" }\n"
" template float NS2::foo<float>(float);\n"
"}\n"
"template double NS1::NS2::foo<double>(double);"
;
const char exp[] = "namespace NS1 { "
"namespace NS2 { "
"int foo<int> ( int a ) ; "
"char foo<char> ( char a ) ; "
"float foo<float> ( float t ) ; "
"double foo<double> ( double t ) ; "
"char foo<char> ( char a ) { return a ; } "
"int foo<int> ( int a ) { return a ; } "
"} "
"} "
"float NS1 :: NS2 :: foo<float> ( float t ) { ret
urn t ; } "
"double NS1 :: NS2 :: foo<double> ( double t ) {
return t ; }";
ASSERT_EQUALS(exp, tok(code));
}
}
void template92() {
const char code[] = "template<class T> void foo(T const& t) { }\n"
"template<> void foo<double>(double const& d) { }\n"
"template void foo<float>(float const& f);\n"
"int main() {\n"
" foo<int>(2);\n"
" foo<double>(3.14);\n"
" foo<float>(3.14f);\n"
"}";
const char exp[] = "void foo<double> ( const double & d ) ; "
"void foo<float> ( const float & t ) ; "
"void foo<int> ( const int & t ) ; "
"void foo<double> ( const double & d ) { } "
"int main ( ) { "
"foo<int> ( 2 ) ; "
"foo<double> ( 3.14 ) ; "
"foo<float> ( 3.14f ) ; "
"} "
"void foo<float> ( const float & t ) { } "
"void foo<int> ( const int & t ) { }";
ASSERT_EQUALS(exp, tok(code));
}
void template93() { // crash
const char code[] = "template <typename Iterator>\n"
"void ForEach() { }\n"
"template <typename Type>\n"
"class Vector2 : public Vector {\n"
" template <typename Iterator>\n"
" void ForEach();\n"
"public:\n"
" void process();\n"
"};\n"
"template <typename Type>\n"
"void Vector2<Type>::process() {\n"
" ForEach<iterator>();\n"
"}\n"
"Vector2<string> c;";
const char exp[] = "void ForEach<iterator> ( ) ; "
"class Vector2<string> ; "
"Vector2<string> c ; "
"class Vector2<string> : public Vector { "
"template < typename Iterator > "
"void ForEach ( ) ; "
"public: "
"void process ( ) ; "
"} ; "
"void Vector2<string> :: process ( ) { "
"ForEach<iterator> ( ) ; "
"} "
"void ForEach<iterator> ( ) { "
"}";
ASSERT_EQUALS(exp, tok(code));
}
void template94() { // #8927 crash
const char code[] = "template <typename T>\n"
"class Array { };\n"
"template<typename T>\n"
"Array<T> foo() {};\n"
"template <> Array<double> foo<double>() { }\n"
"template <> Array<std::complex<float>> foo<std::com
plex<float>>() { }\n"
"template <> Array<float> foo<float>() { }\n"
"template < typename T >\n"
"Array<T> matmul() {\n"
" return foo<T>( );\n"
"}\n"
"template Array<std::complex<float>> matmul<std::com
plex<float>>();";
const char exp[] = "class Array<double> ; "
"class Array<std::complex<float>> ; "
"class Array<float> ; "
"Array<float> foo<float> ( ) ; "
"Array<std::complex<float>> foo<std::complex<float>>
( ) ; "
"Array<double> foo<double> ( ) ; "
"template < typename T > "
"Array < T > foo ( ) { } ; "
"Array<double> foo<double> ( ) { } "
"Array<std::complex<float>> foo<std::complex<float>>
( ) { } "
"Array<float> foo<float> ( ) { } "
"Array<std::complex<float>> matmul<std::complex<float
>> ( ) ; "
"Array<std::complex<float>> matmul<std::complex<float
>> ( ) { "
"return foo<std::complex<float>> ( ) ; "
"} "
"class Array<double> { } ; "
"class Array<std::complex<float>> { } ; "
"class Array<float> { } ;";
ASSERT_EQUALS(exp, tok(code));
}
void template95() { // #7417
const char code[] = "template <typename T>\n"
"T Value = 123;\n"
"template<>\n"
"int Value<int> = 456;\n"
"float f = Value<float>;\n"
"int i = Value<int>;";
const char exp[] = "float Value<float> ; Value<float> = 123 ; "
"int Value<int> ; Value<int> = 456 ; "
"float f ; f = Value<float> ; "
"int i ; i = Value<int> ;";
ASSERT_EQUALS(exp, tok(code));
}
void template96() { // #7854
const char code[] = "template<unsigned int n>\n"
" constexpr long fib = fib<n-1> + fib<n-2>;\n"
"template<>\n"
" constexpr long fib<0> = 0;\n"
"template<>\n"
" constexpr long fib<1> = 1;\n"
"long f0 = fib<0>;\n"
"long f1 = fib<1>;\n"
"long f2 = fib<2>;\n"
"long f3 = fib<3>;";
const char act[] = "const long fib<2> = fib < 1 > + fib < 0 > ; "
"const long fib<3> = fib < 2 > + fib < 1 > ; "
"const long fib<0> = 0 ; "
"const long fib<1> = 1 ; "
"long f0 ; f0 = fib<0> ; "
"long f1 ; f1 = fib<1> ; "
"long f2 ; f2 = fib<2> ; "
"long f3 ; f3 = fib<3> ;";
const char exp[] = "const long fib<2> = fib<1> + fib<0> ; "
"const long fib<3> = fib<2> + fib<1> ; "
"const long fib<0> = 0 ; "
"const long fib<1> = 1 ; "
"long f0 ; f0 = fib<0> ; "
"long f1 ; f1 = fib<1> ; "
"long f2 ; f2 = fib<2> ; "
"long f3 ; f3 = fib<3> ;";
TODO_ASSERT_EQUALS(exp, act, tok(code, false));
}
void template97() {
const char code[] ="namespace NS1 {\n"
" namespace NS2 {\n"
" namespace NS3 {\n"
" namespace NS4 {\n"
" template<class T>\n"
" class Fred {\n"
" T * t;\n"
" public:\n"
" Fred<T>() : t(nullptr) {}\n"
" };\n"
" }\n"
" using namespace NS4;\n"
" Fred<bool> fred_bool;\n"
" NS4::Fred<char> fred_char;\n"
" }\n"
" using namespace NS3;\n"
" NS4::Fred<short> fred_short;\n"
" using namespace NS3::NS4;\n"
" Fred<int> fred_int;\n"
" NS3::NS4::Fred<long> fred_long;\n"
" NS2::NS3::NS4::Fred<float> fred_float;\n"
" NS1::NS2::NS3::NS4::Fred<double> fred_double
;\n"
" }\n"
" using namespace NS2;\n"
" NS3::NS4::Fred<float> fred_float1;\n"
" NS2::NS3::NS4::Fred<double> fred_double1;\n"
"}\n"
"using namespace NS1::NS2::NS3::NS4;\n"
"Fred<bool> fred_bool1;\n"
"NS1::NS2::NS3::NS4::Fred<int> fred_int1;";
const char exp[] = "namespace NS1 { "
"namespace NS2 { "
"namespace NS3 { "
"namespace NS4 { "
"class Fred<bool> ; "
"class Fred<char> ; "
"class Fred<short> ; "
"class Fred<int> ; "
"class Fred<long> ; "
"class Fred<float> ; "
"class Fred<double> ; "
"} "
"using namespace NS4 ; "
"NS4 :: Fred<bool> fred_bool ; "
"NS4 :: Fred<char> fred_char ; "
"} "
"using namespace NS3 ; "
"NS3 :: NS4 :: Fred<short> fred_short ; "
"using namespace NS3 :: NS4 ; "
"NS3 :: NS4 :: Fred<int> fred_int ; "
"NS3 :: NS4 :: Fred<long> fred_long ; "
"NS2 :: NS3 :: NS4 :: Fred<float> fred_float ; "
"NS1 :: NS2 :: NS3 :: NS4 :: Fred<double> fred_double
; "
"} "
"using namespace NS2 ; "
"NS2 :: NS3 :: NS4 :: Fred<float> fred_float1 ; "
"NS2 :: NS3 :: NS4 :: Fred<double> fred_double1 ; "
"} "
"using namespace NS1 :: NS2 :: NS3 :: NS4 ; "
"NS1 :: NS2 :: NS3 :: NS4 :: Fred<bool> fred_bool1 ;
"
"NS1 :: NS2 :: NS3 :: NS4 :: Fred<int> fred_int1 ; "
"class NS1 :: NS2 :: NS3 :: NS4 :: Fred<bool> { "
"bool * t ; "
"public: "
"Fred<bool> ( ) : t ( nullptr ) { } "
"} ; "
"class NS1 :: NS2 :: NS3 :: NS4 :: Fred<char> { "
"char * t ; "
"public: "
"Fred<char> ( ) : t ( nullptr ) { } "
"} ; "
"class NS1 :: NS2 :: NS3 :: NS4 :: Fred<short> { "
"short * t ; "
"public: "
"Fred<short> ( ) : t ( nullptr ) { } "
"} ; "
"class NS1 :: NS2 :: NS3 :: NS4 :: Fred<int> { "
"int * t ; "
"public: "
"Fred<int> ( ) : t ( nullptr ) { } "
"} ; "
"class NS1 :: NS2 :: NS3 :: NS4 :: Fred<long> { "
"long * t ; "
"public: "
"Fred<long> ( ) : t ( nullptr ) { } "
"} ; "
"class NS1 :: NS2 :: NS3 :: NS4 :: Fred<float> { "
"float * t ; "
"public: "
"Fred<float> ( ) : t ( nullptr ) { } "
"} ; "
"class NS1 :: NS2 :: NS3 :: NS4 :: Fred<double> { "
"double * t ; "
"public: "
"Fred<double> ( ) : t ( nullptr ) { } "
"} ;";
ASSERT_EQUALS(exp, tok(code));
}
void template98() { // #8959
const char code[] = "template <typename T>\n"
"using unique_ptr_with_deleter = std::unique_ptr<T,
std::function<void(T*)>>;\n"
"class A {};\n"
"static void func() {\n"
" unique_ptr_with_deleter<A> tmp(new A(), [](A* a
) {\n"
" delete a;\n"
" });\n"
"}";
const char exp[] = "; "
"class A { } ; "
"static void func ( ) { "
"std :: unique_ptr < A , std :: function < void ( A *
) > > tmp ( new A ( ) , [ ] ( A * a ) { "
"delete a ; "
"} ) ; "
"}";
ASSERT_EQUALS(exp, tok(code));
}
void template99() { // #8960
const char code[] = "template <typename T>\n"
"class Base {\n"
"public:\n"
" using ArrayType = std::vector<Base<T>>;\n"
"};\n"
"using A = Base<int>;\n"
"static A::ArrayType array;\n";
const char exp[] = "class Base<int> ; "
"static std :: vector < Base<int> > array ; "
"class Base<int> { "
"public: "
"} ;";
ASSERT_EQUALS(exp, tok(code));
}
void template100() { // #8967
const char code[] = "enum class Device { I2C0, I2C1 };\n"
"template <Device D>\n"
"const char* deviceFile;\n"
"template <>\n"
"const char* deviceFile<Device::I2C0> = \"/tmp/i2c-0
\";\n";
const char exp[] = "enum class Device { I2C0 , I2C1 } ; "
"template < Device D > "
"const char * deviceFile ; "
"const char * deviceFile<Device::I2C0> ; deviceFile<D
evice::I2C0> = \"/tmp/i2c-0\" ;";
ASSERT_EQUALS(exp, tok(code));
}
void template101() { // #8968
const char code[] = "class A {\n"
"public:\n"
" using ArrayType = std::vector<int>;\n"
" void func(typename ArrayType::size_type i) {\n"
" }\n"
"};";
const char exp[] = "class A { "
"public: "
"void func ( std :: vector < int > :: size_type i ) {
"
"} "
"} ;";
ASSERT_EQUALS(exp, tok(code));
ASSERT_EQUALS("", errout.str());
}
void template_specialization_1() { // #7868 - template specialization templ ate <typename T> struct S<C<T>> {..}; void template_specialization_1() { // #7868 - template specialization templ ate <typename T> struct S<C<T>> {..};
const char code[] = "template <typename T> struct C {};\n" const char code[] = "template <typename T> struct C {};\n"
"template <typename T> struct S {a};\n" "template <typename T> struct S {a};\n"
"template <typename T> struct S<C<T>> {b};\n" "template <typename T> struct S<C<T>> {b};\n"
"S<int> s;"; "S<int> s;";
const char exp[] = "template < typename T > struct C { } ; struct S<int > ; template < typename T > struct S < C < T > > { b } ; S<int> s ; struct S<int > { a } ;"; const char exp[] = "template < typename T > struct C { } ; struct S<int > ; template < typename T > struct S < C < T > > { b } ; S<int> s ; struct S<int > { a } ;";
ASSERT_EQUALS(exp, tok(code)); ASSERT_EQUALS(exp, tok(code));
} }
void template_specialization_2() { // #7868 - template specialization templ ate <typename T> struct S<C<T>> {..}; void template_specialization_2() { // #7868 - template specialization templ ate <typename T> struct S<C<T>> {..};
skipping to change at line 1801 skipping to change at line 2316
"template <class T, int n>\n" "template <class T, int n>\n"
"class A\n" "class A\n"
"{ T ar[n]; };\n" "{ T ar[n]; };\n"
"\n" "\n"
"void f()\n" "void f()\n"
"{\n" "{\n"
" A<int,2> a1;\n" " A<int,2> a1;\n"
" A<int> a2;\n" " A<int> a2;\n"
"}\n"; "}\n";
const char wanted[] = "class A<int,2> ; " const char exp[] = "class A<int,2> ; "
"class A<int,3> ; " "class A<int,3> ; "
"void f ( ) " "void f ( ) "
"{" "{"
" A<int,2> a1 ;" " A<int,2> a1 ;"
" A<int,3> a2 ; " " A<int,3> a2 ; "
"} " "} "
"class A<int,2> " "class A<int,2> "
"{ int ar [ 2 ] ; } ; " "{ int ar [ 2 ] ; } ; "
"class A<int,3> " "class A<int,3> "
"{ int ar [ 3 ] ; } ;"; "{ int ar [ 3 ] ; } ;";
const char current[] = "template < class T , int n = 3 > class A ; " ASSERT_EQUALS(exp, tok(code));
"class A<int,2> ; "
"class A<int,3> ; "
"void f ( ) "
"{"
" A<int,2> a1 ;"
" A<int,3> a2 ; "
"} "
"class A<int,2> "
"{ int ar [ 2 ] ; } ; "
"class A<int,3> "
"{ int ar [ 3 ] ; } ;";
TODO_ASSERT_EQUALS(wanted, current, tok(code));
} }
{ {
const char code[] = "template <class, int = 3> class A;\n" const char code[] = "template <class, int = 3> class A;\n"
"template <class T, int n>\n" "template <class T, int n>\n"
"class A\n" "class A\n"
"{ T ar[n]; };\n" "{ T ar[n]; };\n"
"\n" "\n"
"void f()\n" "void f()\n"
"{\n" "{\n"
" A<int,2> a1;\n" " A<int,2> a1;\n"
" A<int> a2;\n" " A<int> a2;\n"
"}\n"; "}\n";
const char wanted[] = "class A<int,2> ; " const char exp[] = "class A<int,2> ; "
"class A<int,3> ; " "class A<int,3> ; "
"void f ( ) " "void f ( ) "
"{" "{"
" A<int,2> a1 ;" " A<int,2> a1 ;"
" A<int,3> a2 ; " " A<int,3> a2 ; "
"} " "} "
"class A<int,2> " "class A<int,2> "
"{ int ar [ 2 ] ; } ; " "{ int ar [ 2 ] ; } ; "
"class A<int,3> " "class A<int,3> "
"{ int ar [ 3 ] ; } ;"; "{ int ar [ 3 ] ; } ;";
const char current[] = "template < class , int = 3 > class A ; " ASSERT_EQUALS(exp, tok(code));
"class A<int,2> ; " }
"class A<int,3> ; " {
"void f ( ) " const char code[] = "template<typename Lhs, int TriangularPart = (in
"{" t(Lhs::Flags) & LowerTriangularBit)>\n"
" A<int,2> a1 ;" "struct ei_solve_triangular_selector;\n"
" A<int,3> a2 ; " "template<typename Lhs, int UpLo>\n"
"} " "struct ei_solve_triangular_selector<Lhs,UpLo> {
"class A<int,2> " \n"
"{ int ar [ 2 ] ; } ; " "};\n"
"class A<int,3> " "template<typename Lhs, int TriangularPart>\n"
"{ int ar [ 3 ] ; } ;"; "struct ei_solve_triangular_selector { };";
TODO_ASSERT_EQUALS(wanted, current, tok(code));
const char exp[] = "template < typename Lhs , int TriangularPart = (
int ( Lhs :: Flags ) & LowerTriangularBit ) > "
"struct ei_solve_triangular_selector ; "
"template < typename Lhs , int UpLo > "
"struct ei_solve_triangular_selector < Lhs , UpLo
> { "
"} ; "
"template < typename Lhs , int TriangularPart = (
int ( Lhs :: Flags ) & LowerTriangularBit ) > "
"struct ei_solve_triangular_selector { } ;";
ASSERT_EQUALS(exp, tok(code));
} }
} }
void template_default_type() { void template_default_type() {
const char code[] = "template <typename T, typename U=T>\n" const char code[] = "template <typename T, typename U=T>\n"
"class A\n" "class A\n"
"{\n" "{\n"
"public:\n" "public:\n"
" void foo() {\n" " void foo() {\n"
" int a;\n" " int a;\n"
skipping to change at line 2191 skipping to change at line 2701
" Fred();\n" " Fred();\n"
"private:\n" "private:\n"
" Barney<type> m_data;\n" " Barney<type> m_data;\n"
"};\n" "};\n"
"template class Fred<1>;\n" "template class Fred<1>;\n"
"}\n"; "}\n";
ASSERT_EQUALS("namespace NS { " ASSERT_EQUALS("namespace NS { "
"template < int type > struct Barney ; " "template < int type > struct Barney ; "
"struct Barney<1> { } ; " "struct Barney<1> { } ; "
"class Fred<1> ; " "class Fred<1> ; "
"template class Fred<1> ; "
"} " "} "
"class NS :: Fred<1> { " "class NS :: Fred<1> { "
"public: " "public: "
"Fred<1> ( ) ; " "Fred<1> ( ) ; "
"private: " "private: "
"Barney<1> m_data ; " "Barney<1> m_data ; "
"} ;", tok(code)); "} ;", tok(code));
} }
void template_namespace_10() { void template_namespace_10() {
skipping to change at line 2232 skipping to change at line 2741
"Fred<int> ( ) : t ( nullptr ) { } " "Fred<int> ( ) : t ( nullptr ) { } "
"} ;", tok(code)); "} ;", tok(code));
} }
void template_namespace_11() {// #7145 void template_namespace_11() {// #7145
const char code[] = "namespace MyNamespace {\n" const char code[] = "namespace MyNamespace {\n"
"class TestClass {\n" "class TestClass {\n"
"public:\n" "public:\n"
" TestClass() {\n" " TestClass() {\n"
" SomeFunction();\n" " SomeFunction();\n"
" TemplatedMethod< int >();\n" " TemplatedMethod< int >( 0 );\n"
" }\n" " }\n"
" void SomeFunction() { }\n" " void SomeFunction() { }\n"
"private:\n" "private:\n"
" template< typename T > T TemplatedMethod(T);\n" " template< typename T > T TemplatedMethod(T);\n"
"};\n" "};\n"
"template< typename T > T TestClass::TemplatedMethod (T t) { return t; }\n" "template< typename T > T TestClass::TemplatedMethod (T t) { return t; }\n"
"}"; "}";
ASSERT_EQUALS("namespace MyNamespace { " ASSERT_EQUALS("namespace MyNamespace { "
"class TestClass { " "class TestClass { "
"public: " "public: "
"TestClass ( ) { " "TestClass ( ) { "
"SomeFunction ( ) ; " "SomeFunction ( ) ; "
"TemplatedMethod<int> ( ) ; " "TemplatedMethod<int> ( 0 ) ; "
"} " "} "
"void SomeFunction ( ) { } " "void SomeFunction ( ) { } "
"private: " "private: "
"int TemplatedMethod<int> ( int ) ; " "int TemplatedMethod<int> ( int ) ; "
"template < typename T > T TemplatedMethod ( T ) ; " // th is should be removed
"} ; " "} ; "
"} int MyNamespace :: TestClass :: TemplatedMethod<int> ( int t ) { return t ; }", tok(code)); "} int MyNamespace :: TestClass :: TemplatedMethod<int> ( int t ) { return t ; }", tok(code));
} }
unsigned int templateParameters(const char code[]) { unsigned int templateParameters(const char code[]) {
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this);
std::istringstream istr(code); std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp", ""); tokenizer.tokenize(istr, "test.cpp", "");
skipping to change at line 2289 skipping to change at line 2797
ASSERT_EQUALS(3U, templateParameters("X<char, int(*)(), bool> x;")); ASSERT_EQUALS(3U, templateParameters("X<char, int(*)(), bool> x;"));
TODO_ASSERT_EQUALS(1U, 0U, templateParameters("X<int...> x;")); // Misha ndled valid syntax TODO_ASSERT_EQUALS(1U, 0U, templateParameters("X<int...> x;")); // Misha ndled valid syntax
TODO_ASSERT_EQUALS(2U, 0U, templateParameters("X<class, typename...> x;" )); // Mishandled valid syntax TODO_ASSERT_EQUALS(2U, 0U, templateParameters("X<class, typename...> x;" )); // Mishandled valid syntax
ASSERT_EQUALS(2U, templateParameters("X<1, T> x;")); ASSERT_EQUALS(2U, templateParameters("X<1, T> x;"));
ASSERT_EQUALS(1U, templateParameters("X<i == 0> x;")); ASSERT_EQUALS(1U, templateParameters("X<i == 0> x;"));
ASSERT_EQUALS(2U, templateParameters("X<int, i>=0> x;")); ASSERT_EQUALS(2U, templateParameters("X<int, i>=0> x;"));
ASSERT_EQUALS(3U, templateParameters("X<int, i>=0, i - 2> x;")); ASSERT_EQUALS(3U, templateParameters("X<int, i>=0, i - 2> x;"));
} }
// Helper function to unit test TemplateSimplifier::getTemplateNamePosition // Helper function to unit test TemplateSimplifier::getTemplateNamePosition
int templateNamePositionHelper(const char code[], unsigned offset = 0, bool onlyCreateTokens = false) { int templateNamePositionHelper(const char code[], unsigned offset = 0) {
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this);
std::istringstream istr(code); std::istringstream istr(code);
if (onlyCreateTokens) tokenizer.tokenize(istr, "test.cpp", emptyString);
tokenizer.createTokens(istr, "test.cpp");
else
tokenizer.tokenize(istr, "test.cpp", emptyString);
const Token *_tok = tokenizer.tokens(); const Token *_tok = tokenizer.tokens();
for (unsigned i = 0 ; i < offset ; ++i) for (unsigned i = 0 ; i < offset ; ++i)
_tok = _tok->next(); _tok = _tok->next();
return TemplateSimplifier::getTemplateNamePosition(_tok); return tokenizer.mTemplateSimplifier->getTemplateNamePosition(_tok);
} }
void templateNamePosition() { void templateNamePosition() {
// Template class // Template class
ASSERT_EQUALS(2, templateNamePositionHelper("template<class T> class A { };", 4)); ASSERT_EQUALS(2, templateNamePositionHelper("template<class T> class A { };", 4));
ASSERT_EQUALS(2, templateNamePositionHelper("template<class T> struct A {};", 4)); ASSERT_EQUALS(2, templateNamePositionHelper("template<class T> struct A {};", 4));
ASSERT_EQUALS(2, templateNamePositionHelper("template<class T> class A : B {};", 4)); ASSERT_EQUALS(2, templateNamePositionHelper("template<class T> class A : B {};", 4));
ASSERT_EQUALS(2, templateNamePositionHelper("template<class T> struct A : B {};", 4)); ASSERT_EQUALS(2, templateNamePositionHelper("template<class T> struct A : B {};", 4));
// Template function definitions // Template function definitions
ASSERT_EQUALS(2, templateNamePositionHelper("template<class T> unsigned foo() { return 0; }", 4)); ASSERT_EQUALS(2, templateNamePositionHelper("template<class T> unsigned foo() { return 0; }", 4));
ASSERT_EQUALS(3, templateNamePositionHelper("template<class T> unsigned* foo() { return 0; }", 4)); ASSERT_EQUALS(3, templateNamePositionHelper("template<class T> unsigned* foo() { return 0; }", 4));
ASSERT_EQUALS(4, templateNamePositionHelper("template<class T> unsigned*
* foo() { return 0; }", 4));
ASSERT_EQUALS(3, templateNamePositionHelper("template<class T> const uns igned foo() { return 0; }", 4)); ASSERT_EQUALS(3, templateNamePositionHelper("template<class T> const uns igned foo() { return 0; }", 4));
ASSERT_EQUALS(4, templateNamePositionHelper("template<class T> const uns igned& foo() { return 0; }", 4)); ASSERT_EQUALS(4, templateNamePositionHelper("template<class T> const uns igned& foo() { return 0; }", 4));
ASSERT_EQUALS(5, templateNamePositionHelper("template<class T> const uns
igned** foo() { return 0; }", 4));
ASSERT_EQUALS(4, templateNamePositionHelper("template<class T> std::stri
ng foo() { static str::string str; return str; }", 4));
ASSERT_EQUALS(5, templateNamePositionHelper("template<class T> std::stri
ng & foo() { static str::string str; return str; }", 4));
ASSERT_EQUALS(6, templateNamePositionHelper("template<class T> const std
::string & foo() { static str::string str; return str; }", 4));
ASSERT_EQUALS(9, templateNamePositionHelper("template<class T> std::map<
int, int> foo() { static std::map<int, int> m; return m; }", 4));
ASSERT_EQUALS(10, templateNamePositionHelper("template<class T> std::map
<int, int> & foo() { static std::map<int, int> m; return m; }", 4));
ASSERT_EQUALS(11, templateNamePositionHelper("template<class T> const st
d::map<int, int> & foo() { static std::map<int, int> m; return m; }", 4));
// Class template members // Class template members
ASSERT_EQUALS(4, templateNamePositionHelper("class A { template<class T> ASSERT_EQUALS(4, templateNamePositionHelper(
unsigned foo(); }; " "class A { template<class T> unsigned foo(); }; "
"template<class T> unsigned A::foo() { return 0; }", 19)); "template<class T> unsigned A::foo() { return 0; }", 1
ASSERT_EQUALS(5, templateNamePositionHelper("class A { template<class T> 9));
const unsigned foo(); }; " ASSERT_EQUALS(5, templateNamePositionHelper(
"template<class T> const unsigned A::foo() { return 0; }", "class A { template<class T> const unsigned foo(); };
20)); "
TODO_ASSERT_EQUALS(7, -1, templateNamePositionHelper("class A { class B "template<class T> const unsigned A::foo() { return 0;
{ template<class T> const unsigned foo(); }; } ; " }", 20));
"template<class T> const unsigned A::B::foo() { retur ASSERT_EQUALS(7, templateNamePositionHelper(
n 0; }", 25)); "class A { class B { template<class T> const unsigned
foo(); }; } ; "
"template<class T> const unsigned A::B::foo() { return
0; }", 25));
ASSERT_EQUALS(8, templateNamePositionHelper(
"class A { class B { template<class T> const unsigned
* foo(); }; } ; "
"template<class T> const unsigned * A::B::foo() { retu
rn 0; }", 26));
ASSERT_EQUALS(9, templateNamePositionHelper(
"class A { class B { template<class T> const unsigned
** foo(); }; } ; "
"template<class T> const unsigned ** A::B::foo() { ret
urn 0; }", 27));
// Template class member // Template class member
ASSERT_EQUALS(6, templateNamePositionHelper("template<class T> class A { ASSERT_EQUALS(6, templateNamePositionHelper(
A(); }; " "template<class T> class A { A(); }; "
"template<class T> A<T>::A() {}", 18)); "template<class T> A<T>::A() {}", 18));
ASSERT_EQUALS(8, templateNamePositionHelper("template<class T, class U> ASSERT_EQUALS(8, templateNamePositionHelper(
class A { A(); }; " "template<class T, class U> class A { A(); }; "
"template<class T, class U> A<T, U>::A() {}", 24)); "template<class T, class U> A<T, U>::A() {}", 24));
ASSERT_EQUALS(7, templateNamePositionHelper("template<class T> class A { ASSERT_EQUALS(7, templateNamePositionHelper(
unsigned foo(); }; " "template<class T> class A { unsigned foo(); }; "
"template<class T> unsigned A<T>::foo() { return 0; }", 19 "template<class T> unsigned A<T>::foo() { return 0; }"
)); , 19));
ASSERT_EQUALS(9, templateNamePositionHelper("template<class T, class U> ASSERT_EQUALS(9, templateNamePositionHelper(
class A { unsigned foo(); }; " "template<class T, class U> class A { unsigned foo();
"template<class T, class U> unsigned A<T, U>::foo() { retu }; "
rn 0; }", 25)); "template<class T, class U> unsigned A<T, U>::foo() {
ASSERT_EQUALS(9, templateNamePositionHelper("template<class T, class U> return 0; }", 25));
class A { unsigned foo(); }; " ASSERT_EQUALS(12, templateNamePositionHelper(
"template<class T, class U> unsigned A<T, U>::foo() { retu "template<> unsigned A<int, v<char> >::foo() { return
rn 0; }", 25, /*onlyCreateTokens=*/true)); 0; }", 2));
ASSERT_EQUALS(12, templateNamePositionHelper("template<class T> class v
{}; "
"template<class T, class U> class A { unsigned foo(); }; "
"template<> unsigned A<int, v<char> >::foo() { return 0; }
", 30, /*onlyCreateTokens=*/true));
} }
void expandSpecialized1() { void expandSpecialized1() {
ASSERT_EQUALS("class A<int> { } ;", tok("template<> class A<int> {};")); ASSERT_EQUALS("class A<int> { } ;", tok("template<> class A<int> {};"));
ASSERT_EQUALS("class A<int> : public B { } ;", tok("template<> class A<i nt> : public B {};")); ASSERT_EQUALS("class A<int> : public B { } ;", tok("template<> class A<i nt> : public B {};"));
ASSERT_EQUALS("class A<int> { A<int> ( ) ; ~ A<int> ( ) ; } ;", tok("tem plate<> class A<int> { A(); ~A(); };")); ASSERT_EQUALS("class A<int> { A<int> ( ) ; ~ A<int> ( ) ; } ;", tok("tem plate<> class A<int> { A(); ~A(); };"));
ASSERT_EQUALS("class A<int> { A<int> ( ) { } ~ A<int> ( ) { } } ;", tok( "template<> class A<int> { A() {} ~A() {} };")); ASSERT_EQUALS("class A<int> { A<int> ( ) { } ~ A<int> ( ) { } } ;", tok( "template<> class A<int> { A() {} ~A() {} };"));
ASSERT_EQUALS("class A<int> { A<int> ( ) ; ~ A<int> ( ) ; } ; A<int> :: A<int> ( ) { } ~ A<int> :: A<int> ( ) { }", ASSERT_EQUALS("class A<int> { A<int> ( ) ; ~ A<int> ( ) ; } ; A<int> :: A<int> ( ) { } ~ A<int> :: A<int> ( ) { }",
tok("template<> class A<int> { A(); ~A(); }; A<int>::A() { } ~A<int>::A() {}")); tok("template<> class A<int> { A(); ~A(); }; A<int>::A() { } ~A<int>::A() {}"));
ASSERT_EQUALS("class A<int> { A<int> ( ) ; A<int> ( const A<int> & ) ; A <int> foo ( ) ; } ; A<int> :: A<int> ( ) { } A<int> :: A<int> ( const A<int> & ) { } A<int> A<int> :: foo ( ) { A<int> a ; return a ; }", ASSERT_EQUALS("class A<int> { A<int> ( ) ; A<int> ( const A<int> & ) ; A <int> foo ( ) ; } ; A<int> :: A<int> ( ) { } A<int> :: A<int> ( const A<int> & ) { } A<int> A<int> :: foo ( ) { A<int> a ; return a ; }",
 End of changes. 35 change blocks. 
150 lines changed or deleted 724 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)