1 /* 2 * Cppcheck - A tool for static C/C++ code analysis 3 * Copyright (C) 2007-2021 Cppcheck team. 4 * 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 20 #include "config.h" 21 #include "platform.h" 22 #include "settings.h" 23 #include "templatesimplifier.h" 24 #include "testsuite.h" 25 #include "token.h" 26 #include "tokenize.h" 27 28 #include <cstring> 29 30 struct InternalError; 31 32 33 class TestSimplifyTemplate : public TestFixture { 34 public: TestSimplifyTemplate()35 TestSimplifyTemplate() : TestFixture("TestSimplifyTemplate") {} 36 37 private: 38 Settings settings; 39 run()40 void run() OVERRIDE { 41 settings.severity.enable(Severity::portability); 42 43 // If there are unused templates, keep those 44 settings.checkUnusedTemplates = true; 45 46 TEST_CASE(template1); 47 TEST_CASE(template2); 48 TEST_CASE(template3); 49 TEST_CASE(template4); 50 TEST_CASE(template5); 51 TEST_CASE(template6); 52 TEST_CASE(template7); 53 TEST_CASE(template8); 54 TEST_CASE(template9); 55 TEST_CASE(template10); 56 TEST_CASE(template11); 57 TEST_CASE(template12); 58 TEST_CASE(template13); 59 TEST_CASE(template14); 60 TEST_CASE(template15); // recursive templates 61 TEST_CASE(template16); 62 TEST_CASE(template17); 63 TEST_CASE(template18); 64 TEST_CASE(template19); 65 TEST_CASE(template20); 66 TEST_CASE(template21); 67 TEST_CASE(template22); 68 TEST_CASE(template23); 69 TEST_CASE(template24); // #2648 - using sizeof in template parameter 70 TEST_CASE(template25); // #2648 - another test for sizeof template parameter 71 TEST_CASE(template26); // #2721 - passing 'char[2]' as template parameter 72 TEST_CASE(template27); // #3350 - removing unused template in macro call 73 TEST_CASE(template28); 74 TEST_CASE(template30); // #3529 - template < template < .. 75 TEST_CASE(template31); // #4010 - reference type 76 TEST_CASE(template32); // #3818 - mismatching template not handled well 77 TEST_CASE(template33); // #3818,#4544 - inner templates in template instantiation not handled well 78 TEST_CASE(template34); // #3706 - namespace => hang 79 TEST_CASE(template35); // #4074 - A<'x'> a; 80 TEST_CASE(template36); // #4310 - passing unknown template instantiation as template argument 81 TEST_CASE(template37); // #4544 - A<class B> a; 82 TEST_CASE(template38); // #4832 - crash on C++11 right angle brackets 83 TEST_CASE(template39); // #4742 - freeze 84 TEST_CASE(template40); // #5055 - template specialization outside struct 85 TEST_CASE(template41); // #4710 - const in instantiation not handled perfectly 86 TEST_CASE(template42); // #4878 - variadic templates 87 TEST_CASE(template43); // #5097 - assert due to '>>' not treated as end of template instantiation 88 TEST_CASE(template44); // #5297 - TemplateSimplifier::simplifyCalculations not eager enough 89 TEST_CASE(template45); // #5814 - syntax error reported for valid code 90 TEST_CASE(template46); // #5816 - syntax error reported for valid code 91 TEST_CASE(template47); // #6023 - syntax error reported for valid code 92 TEST_CASE(template48); // #6134 - 100% CPU upon invalid code 93 TEST_CASE(template49); // #6237 - template instantiation 94 TEST_CASE(template50); // #4272 - simple partial specialization 95 TEST_CASE(template52); // #6437 - crash upon valid code 96 TEST_CASE(template53); // #4335 - bail out for valid code 97 TEST_CASE(template54); // #6587 - memory corruption upon valid code 98 TEST_CASE(template55); // #6604 - simplify "const const" to "const" in template instantiations 99 TEST_CASE(template56); // #7117 - const ternary operator simplification as template parameter 100 TEST_CASE(template57); // #7891 101 TEST_CASE(template58); // #6021 - use after free (deleted tokens in simplifyCalculations) 102 TEST_CASE(template59); // #8051 - TemplateSimplifier::simplifyTemplateInstantiation failure 103 TEST_CASE(template60); // handling of methods outside template definition 104 TEST_CASE(template61); // daca2, kodi 105 TEST_CASE(template62); // #8314 - inner template instantiation 106 TEST_CASE(template63); // #8576 - qualified type 107 TEST_CASE(template64); // #8683 108 TEST_CASE(template65); // #8321 109 TEST_CASE(template66); // #8725 110 TEST_CASE(template67); // #8122 111 TEST_CASE(template68); // union 112 TEST_CASE(template69); // #8791 113 TEST_CASE(template70); // #5289 114 TEST_CASE(template71); // #8821 115 TEST_CASE(template72); 116 TEST_CASE(template73); 117 TEST_CASE(template74); 118 TEST_CASE(template75); 119 TEST_CASE(template76); 120 TEST_CASE(template77); 121 TEST_CASE(template78); 122 TEST_CASE(template79); // #5133 123 TEST_CASE(template80); 124 TEST_CASE(template81); 125 TEST_CASE(template82); // #8603 126 TEST_CASE(template83); // #8867 127 TEST_CASE(template84); // #8880 128 TEST_CASE(template85); // #8902 crash 129 TEST_CASE(template86); // crash 130 TEST_CASE(template87); 131 TEST_CASE(template88); // #6183 132 TEST_CASE(template89); // #8917 133 TEST_CASE(template90); // crash 134 TEST_CASE(template91); 135 TEST_CASE(template92); 136 TEST_CASE(template93); // crash 137 TEST_CASE(template94); // #8927 crash 138 TEST_CASE(template95); // #7417 139 TEST_CASE(template96); // #7854 140 TEST_CASE(template97); 141 TEST_CASE(template98); // #8959 142 TEST_CASE(template99); // #8960 143 TEST_CASE(template100); // #8967 144 TEST_CASE(template101); // #8968 145 TEST_CASE(template102); // #9005 146 TEST_CASE(template103); 147 TEST_CASE(template104); // #9021 148 TEST_CASE(template105); // #9076 149 TEST_CASE(template106); 150 TEST_CASE(template107); // #8663 151 TEST_CASE(template108); // #9109 152 TEST_CASE(template109); // #9144 153 TEST_CASE(template110); 154 TEST_CASE(template111); // crash 155 TEST_CASE(template112); // #9146 syntax error 156 TEST_CASE(template113); 157 TEST_CASE(template114); // #9155 158 TEST_CASE(template115); // #9153 159 TEST_CASE(template116); // #9178 160 TEST_CASE(template117); 161 TEST_CASE(template118); 162 TEST_CASE(template119); // #9186 163 TEST_CASE(template120); 164 TEST_CASE(template121); // #9193 165 TEST_CASE(template122); // #9147 166 TEST_CASE(template123); // #9183 167 TEST_CASE(template124); // #9197 168 TEST_CASE(template125); 169 TEST_CASE(template126); // #9217 170 TEST_CASE(template127); // #9225 171 TEST_CASE(template128); // #9224 172 TEST_CASE(template129); 173 TEST_CASE(template130); // #9246 174 TEST_CASE(template131); // #9249 175 TEST_CASE(template132); // #9250 176 TEST_CASE(template133); 177 TEST_CASE(template134); 178 TEST_CASE(template135); 179 TEST_CASE(template136); // #9287 180 TEST_CASE(template137); // #9288 181 TEST_CASE(template138); 182 TEST_CASE(template139); 183 TEST_CASE(template140); 184 TEST_CASE(template141); // #9337 185 TEST_CASE(template142); // #9338 186 TEST_CASE(template143); 187 TEST_CASE(template144); // #9046 188 TEST_CASE(template145); // syntax error 189 TEST_CASE(template146); // syntax error 190 TEST_CASE(template147); // syntax error 191 TEST_CASE(template148); // syntax error 192 TEST_CASE(template149); // unknown macro 193 TEST_CASE(template150); // syntax error 194 TEST_CASE(template151); // crash 195 TEST_CASE(template152); // #9467 196 TEST_CASE(template153); // #9483 197 TEST_CASE(template154); // #9495 198 TEST_CASE(template155); // #9539 199 TEST_CASE(template156); 200 TEST_CASE(template157); // #9854 201 TEST_CASE(template158); // daca crash 202 TEST_CASE(template159); // #9886 203 TEST_CASE(template160); 204 TEST_CASE(template161); 205 TEST_CASE(template162); 206 TEST_CASE(template163); // #9685 syntax error 207 TEST_CASE(template164); // #9394 208 TEST_CASE(template165); // #10032 syntax error 209 TEST_CASE(template166); // #10081 hang 210 TEST_CASE(template167); 211 TEST_CASE(template168); 212 TEST_CASE(template169); 213 TEST_CASE(template170); // crash 214 TEST_CASE(template171); // crash 215 TEST_CASE(template172); // #10258 crash 216 TEST_CASE(template173); // #10332 crash 217 TEST_CASE(template174); // #10506 hang 218 TEST_CASE(template_specialization_1); // #7868 - template specialization template <typename T> struct S<C<T>> {..}; 219 TEST_CASE(template_specialization_2); // #7868 - template specialization template <typename T> struct S<C<T>> {..}; 220 TEST_CASE(template_enum); // #6299 Syntax error in complex enum declaration (including template) 221 TEST_CASE(template_unhandled); 222 TEST_CASE(template_default_parameter); 223 TEST_CASE(template_forward_declared_default_parameter); 224 TEST_CASE(template_default_type); 225 TEST_CASE(template_typename); 226 TEST_CASE(template_constructor); // #3152 - template constructor is removed 227 TEST_CASE(syntax_error_templates_1); 228 TEST_CASE(template_member_ptr); // Ticket #5786 - crash upon valid code 229 TEST_CASE(template_namespace_1); 230 TEST_CASE(template_namespace_2); 231 TEST_CASE(template_namespace_3); 232 TEST_CASE(template_namespace_4); 233 TEST_CASE(template_namespace_5); 234 TEST_CASE(template_namespace_6); 235 TEST_CASE(template_namespace_7); // #8768 236 TEST_CASE(template_namespace_8); 237 TEST_CASE(template_namespace_9); 238 TEST_CASE(template_namespace_10); 239 TEST_CASE(template_namespace_11); // #7145 240 TEST_CASE(template_pointer_type); 241 TEST_CASE(template_array_type); 242 243 // Test TemplateSimplifier::templateParameters 244 TEST_CASE(templateParameters); 245 246 TEST_CASE(templateNamePosition); 247 248 TEST_CASE(findTemplateDeclarationEnd); 249 250 TEST_CASE(getTemplateParametersInDeclaration); 251 252 TEST_CASE(expandSpecialized1); 253 TEST_CASE(expandSpecialized2); 254 TEST_CASE(expandSpecialized3); // #8671 255 TEST_CASE(expandSpecialized4); 256 257 TEST_CASE(templateAlias1); 258 TEST_CASE(templateAlias2); 259 TEST_CASE(templateAlias3); // #8315 260 TEST_CASE(templateAlias4); // #9070 261 TEST_CASE(templateAlias5); 262 263 // Test TemplateSimplifier::instantiateMatch 264 TEST_CASE(instantiateMatch); 265 TEST_CASE(templateParameterWithoutName); // #8602 Template default parameter without name yields syntax error 266 267 TEST_CASE(templateTypeDeduction1); // #8962 268 TEST_CASE(templateTypeDeduction2); 269 TEST_CASE(templateTypeDeduction3); 270 TEST_CASE(templateTypeDeduction4); // #9983 271 TEST_CASE(templateTypeDeduction5); 272 273 TEST_CASE(simplifyTemplateArgs1); 274 TEST_CASE(simplifyTemplateArgs2); 275 276 TEST_CASE(template_variadic_1); // #9144 277 TEST_CASE(template_variadic_2); // #4349 278 TEST_CASE(template_variadic_3); // #6172 279 280 TEST_CASE(template_variable_1); 281 TEST_CASE(template_variable_2); 282 TEST_CASE(template_variable_3); 283 TEST_CASE(template_variable_4); 284 285 TEST_CASE(simplifyDecltype); 286 287 TEST_CASE(castInExpansion); 288 289 TEST_CASE(fold_expression_1); 290 TEST_CASE(fold_expression_2); 291 TEST_CASE(fold_expression_3); 292 TEST_CASE(fold_expression_4); 293 294 TEST_CASE(concepts1); 295 TEST_CASE(requires1); 296 TEST_CASE(requires2); 297 TEST_CASE(requires3); 298 TEST_CASE(requires4); 299 TEST_CASE(requires5); 300 301 TEST_CASE(explicitBool1); 302 TEST_CASE(explicitBool2); 303 } 304 tok(const char code[],bool debugwarnings=false,Settings::PlatformType type=Settings::Native)305 std::string tok(const char code[], bool debugwarnings = false, Settings::PlatformType type = Settings::Native) { 306 errout.str(""); 307 308 settings.debugwarnings = debugwarnings; 309 settings.platform(type); 310 Tokenizer tokenizer(&settings, this); 311 312 std::istringstream istr(code); 313 tokenizer.tokenize(istr, "test.cpp"); 314 315 return tokenizer.tokens()->stringifyList(nullptr, true); 316 } 317 template1()318 void template1() { 319 const char code[] = "template <class T> T f(T val) { T a; }\n" 320 "f<int>(10);"; 321 322 const char expected[] = "int f<int> ( int val ) ; " 323 "f<int> ( 10 ) ; " 324 "int f<int> ( int val ) { int a ; }"; 325 326 ASSERT_EQUALS(expected, tok(code)); 327 } 328 template2()329 void template2() { 330 const char code[] = "template <class T> class Fred { T a; };\n" 331 "Fred<int> fred;"; 332 333 const char expected[] = "class Fred<int> ; " 334 "Fred<int> fred ; " 335 "class Fred<int> { int a ; } ;"; 336 337 ASSERT_EQUALS(expected, tok(code)); 338 } 339 template3()340 void template3() { 341 const char code[] = "template <class T, int sz> class Fred { T data[sz]; };\n" 342 "Fred<float,4> fred;"; 343 344 const char expected[] = "class Fred<float,4> ; " 345 "Fred<float,4> fred ; " 346 "class Fred<float,4> { float data [ 4 ] ; } ;"; 347 348 ASSERT_EQUALS(expected, tok(code)); 349 } 350 template4()351 void template4() { 352 const char code[] = "template <class T> class Fred { Fred(); };\n" 353 "Fred<float> fred;"; 354 355 const char expected[] = "class Fred<float> ; " 356 "Fred<float> fred ; " 357 "class Fred<float> { Fred<float> ( ) ; } ;"; 358 359 ASSERT_EQUALS(expected, tok(code)); 360 } 361 template5()362 void template5() { 363 const char code[] = "template <class T> class Fred { };\n" 364 "template <class T> Fred<T>::Fred() { }\n" 365 "Fred<float> fred;"; 366 367 const char expected[] = "class Fred<float> ; " 368 "Fred<float> fred ; " 369 "class Fred<float> { } ; " 370 "Fred<float> :: Fred<float> ( ) { }"; 371 372 ASSERT_EQUALS(expected, tok(code)); 373 } 374 template6()375 void template6() { 376 const char code[] = "template <class T> class Fred { };\n" 377 "Fred<float> fred1;\n" 378 "Fred<float> fred2;"; 379 380 const char expected[] = "class Fred<float> ; " 381 "Fred<float> fred1 ; " 382 "Fred<float> fred2 ; " 383 "class Fred<float> { } ;"; 384 385 ASSERT_EQUALS(expected, tok(code)); 386 } 387 template7()388 void template7() { 389 // A template class that is not used => no simplification 390 { 391 const char code[] = "template <class T>\n" 392 "class ABC\n" 393 "{\n" 394 "public:\n" 395 " typedef ABC<T> m;\n" 396 "};\n"; 397 398 const char expected[] = "template < class T > class ABC { public: } ;"; 399 400 ASSERT_EQUALS(expected, tok(code)); 401 } 402 403 { 404 const char code[] = "template <typename T> class ABC {\n" 405 "public:\n" 406 " typedef std::vector<T> type;\n" 407 "};\n" 408 "int main() {\n" 409 " ABC<int>::type v;\n" 410 " v.push_back(4);\n" 411 " return 0;\n" 412 "}\n"; 413 414 const char wanted[] = "class ABC<int> ; " 415 "int main ( ) { " 416 "std :: vector < int > v ; " 417 "v . push_back ( 4 ) ; " 418 "return 0 ; " 419 "} " 420 "class ABC<int> { public: } ;"; 421 422 const char current[] = "class ABC<int> ; " 423 "int main ( ) { " 424 "ABC<int> :: type v ; " 425 "v . push_back ( 4 ) ; " 426 "return 0 ; " 427 "} " 428 "class ABC<int> { public: } ;"; 429 430 TODO_ASSERT_EQUALS(wanted, current, tok(code)); 431 } 432 433 { 434 const char code[] = "template <typename T> class ABC {\n" 435 "public:\n" 436 " typedef std::vector<T> type;\n" 437 " void f()\n" 438 " {\n" 439 " ABC<int>::type v;\n" 440 " v.push_back(4);\n" 441 " }\n" 442 "};\n"; 443 444 const char expected[] = "template < typename T > class ABC { " 445 "public: void f ( ) { " 446 "ABC < int > :: type v ; " 447 "v . push_back ( 4 ) ; " 448 "} " 449 "} ;"; 450 451 ASSERT_EQUALS(expected, tok(code)); 452 } 453 } 454 455 // Template definitions but no usage => no expansion template8()456 void template8() { 457 const char code[] = "template<typename T> class A;\n" 458 "template<typename T> class B;\n" 459 "\n" 460 "typedef A<int> x;\n" 461 "typedef B<int> y;\n" 462 "\n" 463 "template<typename T> class A {\n" 464 " void f() {\n" 465 " B<T> a = B<T>::g();\n" 466 " T b = 0;\n" 467 " if (b)\n" 468 " b = 0;\n" 469 " }\n" 470 "};\n" 471 "\n" 472 "template<typename T> inline B<T> h() { return B<T>(); }\n"; 473 474 ASSERT_EQUALS("template < typename T > class A ; " 475 "template < typename T > class B ; " 476 "template < typename T > class A { void f ( ) { B < T > a ; a = B < T > :: g ( ) ; T b ; b = 0 ; if ( b ) { b = 0 ; } } } ; " 477 "template < typename T > B < T > h ( ) { return B < T > ( ) ; }", tok(code)); 478 479 ASSERT_EQUALS("class A { template < typename T > int foo ( T d ) ; } ;", tok("class A{ template<typename T> int foo(T d);};")); 480 } 481 template9()482 void template9() { 483 const char code[] = "template < typename T > class A { } ;\n" 484 "\n" 485 "void f ( ) {\n" 486 " A < int > a ;\n" 487 "}\n" 488 "\n" 489 "template < typename T >\n" 490 "class B {\n" 491 " void g ( ) {\n" 492 " A < T > b = A < T > :: h ( ) ;\n" 493 " }\n" 494 "} ;\n"; 495 496 // The expected result.. 497 const char expected[] = "class A<int> ; " 498 "void f ( ) { A<int> a ; } " 499 "template < typename T > class B { void g ( ) { A < T > b ; b = A < T > :: h ( ) ; } } ; " 500 "class A<int> { } ;"; 501 502 ASSERT_EQUALS(expected, tok(code)); 503 } 504 template10()505 void template10() { 506 const char code[] = "template <int ui, typename T> T * foo()\n" 507 "{ return new T[ui]; }\n" 508 "\n" 509 "void f ( )\n" 510 "{\n" 511 " foo<3,int>();\n" 512 "}\n"; 513 514 // The expected result.. 515 const char expected[] = "int * foo<3,int> ( ) ; " 516 "void f ( ) " 517 "{" 518 " foo<3,int> ( ) ; " 519 "} " 520 "int * foo<3,int> ( ) { return new int [ 3 ] ; }"; 521 ASSERT_EQUALS(expected, tok(code)); 522 } 523 template11()524 void template11() { 525 const char code[] = "template <int ui, typename T> T * foo()\n" 526 "{ return new T[ui]; }\n" 527 "\n" 528 "void f ( )\n" 529 "{\n" 530 " char * p = foo<3,char>();\n" 531 "}\n"; 532 533 // The expected result.. 534 const char expected[] = "char * foo<3,char> ( ) ; " 535 "void f ( ) " 536 "{" 537 " char * p ; p = foo<3,char> ( ) ; " 538 "} " 539 "char * foo<3,char> ( ) { return new char [ 3 ] ; }"; 540 ASSERT_EQUALS(expected, tok(code)); 541 } 542 template12()543 void template12() { 544 const char code[] = "template <int x, int y, int z>\n" 545 "class A : public B<x, y, (x - y) ? ((y < z) ? 1 : -1) : 0>\n" 546 "{ };\n" 547 "\n" 548 "void f()\n" 549 "{\n" 550 " A<12,12,11> a;\n" 551 "}\n"; 552 const char expected[] = "class A<12,12,11> ; " 553 "void f ( ) " 554 "{" 555 " A<12,12,11> a ; " 556 "} " 557 "class A<12,12,11> : public B < 12 , 12 , 0 > " 558 "{ } ;"; 559 ASSERT_EQUALS(expected, tok(code)); 560 } 561 template13()562 void template13() { 563 const char code[] = "class BB {};\n" 564 "\n" 565 "template <class T>\n" 566 "class AA {\n" 567 "public:\n" 568 " static AA<T> create(T* newObject);\n" 569 " static int size();\n" 570 "};\n" 571 "\n" 572 "class CC { public: CC(AA<BB>, int) {} };\n" 573 "\n" 574 "class XX {\n" 575 " AA<CC> y;\n" 576 "public:\n" 577 " XX();\n" 578 "};\n" 579 "\n" 580 "XX::XX():\n" 581 " y(AA<CC>::create(new CC(AA<BB>(), 0)))\n" 582 " {}\n" 583 "\n" 584 "int yy[AA<CC>::size()];"; 585 const char expected[] = "class BB { } ; " 586 "class AA<BB> ; " 587 "class AA<CC> ; " 588 "class CC { public: CC ( AA<BB> , int ) { } } ; " 589 "class XX { " 590 "AA<CC> y ; " 591 "public: " 592 "XX ( ) ; " 593 "} ; " 594 "XX :: XX ( ) : " 595 "y ( AA<CC> :: create ( new CC ( AA<BB> ( ) , 0 ) ) ) " 596 "{ } " 597 "int yy [ AA<CC> :: size ( ) ] ; " 598 "class AA<BB> { " 599 "public: " 600 "static AA<BB> create ( BB * newObject ) ; " 601 "static int size ( ) ; " 602 "} ; " 603 "class AA<CC> { " 604 "public: " 605 "static AA<CC> create ( CC * newObject ) ; " 606 "static int size ( ) ; " 607 "} ;"; 608 ASSERT_EQUALS(expected, tok(code)); 609 } 610 template14()611 void template14() { 612 const char code[] = "template <> void foo<int *>()\n" 613 "{ x(); }\n" 614 "\n" 615 "int main()\n" 616 "{\n" 617 "foo<int*>();\n" 618 "}\n"; 619 const char expected[] = "void foo<int*> ( ) ; " 620 "void foo<int*> ( ) " 621 "{ x ( ) ; } " 622 "int main ( ) " 623 "{ foo<int*> ( ) ; }"; 624 ASSERT_EQUALS(expected, tok(code)); 625 } 626 template15()627 void template15() { // recursive templates #3130 etc 628 const char code[] = "template <unsigned int i> void a()\n" 629 "{\n" 630 " a<i-1>();\n" 631 "}\n" 632 "\n" 633 "template <> void a<0>()\n" 634 "{ }\n" 635 "\n" 636 "int main()\n" 637 "{\n" 638 " a<2>();\n" 639 " return 0;\n" 640 "}\n"; 641 642 // The expected result.. 643 const char expected[] = "void a<0> ( ) ; " 644 "void a<2> ( ) ; " 645 "void a<1> ( ) ; " 646 "void a<0> ( ) { } " 647 "int main ( ) " 648 "{ a<2> ( ) ; return 0 ; } " 649 "void a<2> ( ) { a<1> ( ) ; } " 650 "void a<1> ( ) { a<0> ( ) ; }"; 651 652 ASSERT_EQUALS(expected, tok(code)); 653 654 // #3130 655 const char code2[] = "template <int n> struct vec {\n" 656 " vec() {}\n" 657 " vec(const vec<n-1>& v) {}\n" // <- never used don't instantiate 658 "};\n" 659 "\n" 660 "vec<4> v;"; 661 const char expected2[] = "struct vec<4> ; " 662 "vec<4> v ; " 663 "struct vec<4> { " 664 "vec<4> ( ) { } " 665 "vec<4> ( const vec < 4 - 1 > & v ) { } " 666 "} ;"; 667 668 ASSERT_EQUALS(expected2, tok(code2)); 669 } 670 template16()671 void template16() { 672 const char code[] = "template <unsigned int i> void a()\n" 673 "{ }\n" 674 "\n" 675 "template <unsigned int i> void b()\n" 676 "{ a<i>(); }\n" 677 "\n" 678 "int main()\n" 679 "{\n" 680 " b<2>();\n" 681 " return 0;\n" 682 "}\n"; 683 684 const char expected[] = "void a<2> ( ) ; " 685 "void b<2> ( ) ; " 686 "int main ( ) { b<2> ( ) ; return 0 ; } " 687 "void b<2> ( ) { a<2> ( ) ; } " 688 "void a<2> ( ) { }"; 689 690 ASSERT_EQUALS(expected, tok(code)); 691 } 692 template17()693 void template17() { 694 const char code[] = "template<class T>\n" 695 "class Fred\n" 696 "{\n" 697 " template<class T>\n" 698 " static shared_ptr< Fred<T> > CreateFred()\n" 699 " {\n" 700 " }\n" 701 "};\n" 702 "\n" 703 "shared_ptr<int> i;\n"; 704 const char expected[] = "template < class T > " 705 "class Fred " 706 "{ " 707 "template < class T > " 708 "static shared_ptr < Fred < T > > CreateFred ( ) " 709 "{ " 710 "} " 711 "} ; " 712 "shared_ptr < int > i ;"; 713 ASSERT_EQUALS(expected, tok(code)); 714 } 715 template18()716 void template18() { 717 const char code[] = "template <class T> class foo { T a; };\n" 718 "foo<int> *f;"; 719 720 const char expected[] = "class foo<int> ; " 721 "foo<int> * f ; " 722 "class foo<int> { int a ; } ;"; 723 724 ASSERT_EQUALS(expected, tok(code)); 725 } 726 template19()727 void template19() { 728 const char code[] = "template <typename T> T & foo()\n" 729 "{ static T temp; return temp; }\n" 730 "\n" 731 "void f ( )\n" 732 "{\n" 733 " char p = foo<char>();\n" 734 "}\n"; 735 736 // The expected result.. 737 const char expected[] = "char & foo<char> ( ) ; " 738 "void f ( ) " 739 "{" 740 " char p ; p = foo<char> ( ) ; " 741 "} " 742 "char & foo<char> ( ) { static char temp ; return temp ; }"; 743 ASSERT_EQUALS(expected, tok(code)); 744 } 745 template20()746 void template20() { 747 // Ticket #1788 - the destructor implementation is lost 748 const char code[] = "template <class T> class A { public: ~A(); };\n" 749 "template <class T> A<T>::~A() {}\n" 750 "A<int> a;\n"; 751 752 // The expected result.. 753 const char expected[] = "class A<int> ; " 754 "A<int> a ; " 755 "class A<int> { public: ~ A<int> ( ) ; } ; " 756 "A<int> :: ~ A<int> ( ) { }"; 757 ASSERT_EQUALS(expected, tok(code)); 758 } 759 template21()760 void template21() { 761 { 762 const char code[] = "template <class T> struct Fred { T a; };\n" 763 "Fred<int> fred;"; 764 765 const char expected[] = "struct Fred<int> ; " 766 "Fred<int> fred ; " 767 "struct Fred<int> { int a ; } ;"; 768 769 ASSERT_EQUALS(expected, tok(code)); 770 } 771 772 { 773 const char code[] = "template <class T, int sz> struct Fred { T data[sz]; };\n" 774 "Fred<float,4> fred;"; 775 776 const char expected[] = "struct Fred<float,4> ; " 777 "Fred<float,4> fred ; " 778 "struct Fred<float,4> { float data [ 4 ] ; } ;"; 779 780 ASSERT_EQUALS(expected, tok(code)); 781 } 782 783 { 784 const char code[] = "template <class T> struct Fred { Fred(); };\n" 785 "Fred<float> fred;"; 786 787 const char expected[] = "struct Fred<float> ; " 788 "Fred<float> fred ; " 789 "struct Fred<float> { Fred<float> ( ) ; } ;"; 790 791 ASSERT_EQUALS(expected, tok(code)); 792 } 793 794 { 795 const char code[] = "template <class T> struct Fred { };\n" 796 "Fred<float> fred1;\n" 797 "Fred<float> fred2;"; 798 799 const char expected[] = "struct Fred<float> ; " 800 "Fred<float> fred1 ; " 801 "Fred<float> fred2 ; " 802 "struct Fred<float> { } ;"; 803 804 ASSERT_EQUALS(expected, tok(code)); 805 } 806 } 807 template22()808 void template22() { 809 const char code[] = "template <class T> struct Fred { T a; };\n" 810 "Fred<std::string> fred;"; 811 812 const char expected[] = "struct Fred<std::string> ; " 813 "Fred<std::string> fred ; " 814 "struct Fred<std::string> { std :: string a ; } ;"; 815 816 ASSERT_EQUALS(expected, tok(code)); 817 } 818 template23()819 void template23() { 820 const char code[] = "template <class T> void foo() { }\n" 821 "void bar() {\n" 822 " std::cout << (foo<double>());\n" 823 "}"; 824 825 const char expected[] = "void foo<double> ( ) ; " 826 "void bar ( ) {" 827 " std :: cout << ( foo<double> ( ) ) ; " 828 "} " 829 "void foo<double> ( ) { }"; 830 831 ASSERT_EQUALS(expected, tok(code)); 832 } 833 template24()834 void template24() { 835 // #2648 836 const char code[] = "template<int n> struct B\n" 837 "{\n" 838 " int a[n];\n" 839 "};\n" 840 "\n" 841 "template<int x> class bitset: B<sizeof(int)>\n" 842 "{};\n" 843 "\n" 844 "bitset<1> z;"; 845 const char expected[] = "struct B<4> ; " 846 "class bitset<1> ; " 847 "bitset<1> z ; " 848 "class bitset<1> : B<4> { } ; " 849 "struct B<4> { int a [ 4 ] ; } ;"; 850 ASSERT_EQUALS(expected, tok(code)); 851 } 852 template25()853 void template25() { 854 const char code[] = "template<int n> struct B\n" 855 "{\n" 856 " int a[n];\n" 857 "};\n" 858 "\n" 859 "template<int x> class bitset: B<((sizeof(int)) ? : 1)>\n" 860 "{};\n" 861 "\n" 862 "bitset<1> z;"; 863 const char expected[] = "struct B<4> ; " 864 "class bitset<1> ; " 865 "bitset<1> z ; " 866 "class bitset<1> : B<4> { } ; " 867 "struct B<4> { int a [ 4 ] ; } ;"; 868 ASSERT_EQUALS(expected, tok(code)); 869 } 870 template26()871 void template26() { 872 // #2721 873 const char code[] = "template<class T>\n" 874 "class A { public: T x; };\n" 875 "\n" 876 "template<class M>\n" 877 "class C: public A<char[M]> {};\n" 878 "\n" 879 "C<2> a;\n"; 880 ASSERT_EQUALS("class A<char[2]> ; class C<2> ; C<2> a ; class C<2> : public A<char[2]> { } ; class A<char[2]> { public: char [ 2 ] x ; } ;", tok(code)); 881 } 882 template27()883 void template27() { 884 // #3350 - template inside macro call 885 const char code[] = "X(template<class T> class Fred);"; 886 ASSERT_THROW(tok(code), InternalError); 887 } 888 template28()889 void template28() { 890 // #3226 - inner template 891 const char code[] = "template<class A, class B> class Fred {};\n" 892 "Fred<int,Fred<int,int> > x;\n"; 893 ASSERT_EQUALS("class Fred<int,int> ; " 894 "class Fred<int,Fred<int,int>> ; " 895 "Fred<int,Fred<int,int>> x ; " 896 "class Fred<int,int> { } ; " 897 "class Fred<int,Fred<int,int>> { } ;", tok(code)); 898 } 899 template30()900 void template30() { 901 // #3529 - template < template < .. 902 const char code[] = "template<template<class> class A, class B> void f(){}"; 903 ASSERT_EQUALS("template < template < class > class A , class B > void f ( ) { }", tok(code)); 904 } 905 template31()906 void template31() { 907 // #4010 - template reference type 908 const char code[] = "template<class T> struct A{}; A<int&> a;"; 909 ASSERT_EQUALS("struct A<int&> ; " 910 "A<int&> a ; " 911 "struct A<int&> { } ;", tok(code)); 912 913 // #7409 - rvalue 914 const char code2[] = "template<class T> struct A{}; A<int&&> a;"; 915 ASSERT_EQUALS("struct A<int&&> ; " 916 "A<int&&> a ; " 917 "struct A<int&&> { } ;", tok(code2)); 918 } 919 template32()920 void template32() { 921 // #3818 - mismatching template not handled well 922 const char code[] = "template <class T1, class T2, class T3, class T4 > struct A { };\n" 923 "\n" 924 "template <class T>\n" 925 "struct B\n" 926 "{\n" 927 " public:\n" 928 " A < int, Pair<T, int>, int > a;\n" // mismatching parameters => don't instantiate 929 "};\n" 930 "\n" 931 "B<int> b;\n"; 932 ASSERT_EQUALS("template < class T1 , class T2 , class T3 , class T4 > struct A { } ; " 933 "struct B<int> ; " 934 "B<int> b ; " 935 "struct B<int> { public: A < int , Pair < int , int > , int > a ; } ;", tok(code)); 936 } 937 template33()938 void template33() { 939 { 940 // #3818 - inner templates in template instantiation not handled well 941 const char code[] = "template<class T> struct A { };\n" 942 "template<class T> struct B { };\n" 943 "template<class T> struct C { A<B<X<T> > > ab; };\n" 944 "C<int> c;"; 945 ASSERT_EQUALS("struct A<B<X<int>>> ; " 946 "struct B<X<int>> ; " 947 "struct C<int> ; " 948 "C<int> c ; " 949 "struct C<int> { A<B<X<int>>> ab ; } ; " 950 "struct B<X<int>> { } ; " // <- redundant.. but nevermind 951 "struct A<B<X<int>>> { } ;", tok(code)); 952 } 953 954 { 955 // #4544 956 const char code[] = "struct A { };\n" 957 "template<class T> struct B { };\n" 958 "template<class T> struct C { };\n" 959 "C< B<A> > c;"; 960 ASSERT_EQUALS("struct A { } ; " 961 "template < class T > struct B { } ; " // <- redundant.. but nevermind 962 "struct C<B<A>> ; " 963 "C<B<A>> c ; " 964 "struct C<B<A>> { } ;", 965 tok(code)); 966 } 967 } 968 template34()969 void template34() { 970 // #3706 - namespace => hang 971 const char code[] = "namespace abc {\n" 972 "template <typename T> struct X { void f(X<T> &x) {} };\n" 973 "}\n" 974 "template <> int X<int>::Y(0);"; 975 tok(code); 976 } 977 template35()978 void template35() { // #4074 - "A<'x'> a;" is not recognized as template instantiation 979 const char code[] = "template <char c> class A {};\n" 980 "A <'x'> a;"; 981 ASSERT_EQUALS("class A<'x'> ; " 982 "A<'x'> a ; " 983 "class A<'x'> { } ;", tok(code)); 984 } 985 template36()986 void template36() { // #4310 - Passing unknown template instantiation as template argument 987 const char code[] = "template <class T> struct X { T t; };\n" 988 "template <class C> struct Y { Foo < X< Bar<C> > > _foo; };\n" // <- Bar is unknown 989 "Y<int> bar;"; 990 ASSERT_EQUALS("struct X<Bar<int>> ; " 991 "struct Y<int> ; " 992 "Y<int> bar ; " 993 "struct Y<int> { Foo < X<Bar<int>> > _foo ; } ; " 994 "struct X<Bar<int>> { Bar < int > t ; } ;", 995 tok(code)); 996 } 997 template37()998 void template37() { // #4544 - A<class B> a; 999 { 1000 const char code[] = "class A { };\n" 1001 "template<class T> class B {};\n" 1002 "B<class A> b1;\n" 1003 "B<A> b2;"; 1004 ASSERT_EQUALS("class A { } ; class B<A> ; B<A> b1 ; B<A> b2 ; class B<A> { } ;", 1005 tok(code)); 1006 } 1007 { 1008 const char code[] = "struct A { };\n" 1009 "template<class T> class B {};\n" 1010 "B<struct A> b1;\n" 1011 "B<A> b2;"; 1012 ASSERT_EQUALS("struct A { } ; class B<A> ; B<A> b1 ; B<A> b2 ; class B<A> { } ;", 1013 tok(code)); 1014 } 1015 { 1016 const char code[] = "enum A { };\n" 1017 "template<class T> class B {};\n" 1018 "B<enum A> b1;\n" 1019 "B<A> b2;"; 1020 ASSERT_EQUALS("enum A { } ; class B<A> ; B<A> b1 ; B<A> b2 ; class B<A> { } ;", 1021 tok(code)); 1022 } 1023 } 1024 template_unhandled()1025 void template_unhandled() { 1026 // An unhandled template usage should not be simplified.. 1027 ASSERT_EQUALS("x < int > ( ) ;", tok("x<int>();")); 1028 } 1029 template38()1030 void template38() { // #4832 - Crash on C++11 right angle brackets 1031 const char code[] = "template <class T> class A {\n" 1032 " T mT;\n" 1033 "public:\n" 1034 " void foo() {}\n" 1035 "};\n" 1036 "\n" 1037 "int main() {\n" 1038 " A<A<BLA>> gna1;\n" 1039 " A<BLA> gna2;\n" 1040 "}\n"; 1041 const char expected[] = "class A<BLA> ; " 1042 "class A<A<BLA>> ; " 1043 "int main ( ) { " 1044 "A<A<BLA>> gna1 ; " 1045 "A<BLA> gna2 ; " 1046 "} " 1047 "class A<BLA> { " 1048 "BLA mT ; " 1049 "public: " 1050 "void foo ( ) { } " 1051 "} ; " 1052 "class A<A<BLA>> { " 1053 "A<BLA> mT ; " 1054 "public: " 1055 "void foo ( ) { } " 1056 "} ;"; 1057 ASSERT_EQUALS(expected, tok(code)); 1058 } 1059 template39()1060 void template39() { // #4742 - Used to freeze in 1.60 1061 const char code[] = "template<typename T> struct vector {" 1062 " operator T() const;" 1063 "};" 1064 "void f() {" 1065 " vector<vector<int>> v;" 1066 " const vector<int> vi = static_cast<vector<int>>(v);" 1067 "}"; 1068 tok(code); 1069 } 1070 template40()1071 void template40() { // #5055 - false negatives when there is template specialization outside struct 1072 const char code[] = "struct A {" 1073 " template<typename T> struct X { T t; };" 1074 "};" 1075 "template<> struct A::X<int> { int *t; };"; 1076 const char expected[] = "struct A { " 1077 "struct X<int> ; " 1078 "template < typename T > struct X { T t ; } ; " 1079 "} ; " 1080 "struct A :: X<int> { int * t ; } ;"; 1081 ASSERT_EQUALS(expected, tok(code)); 1082 } 1083 template41()1084 void template41() { // #4710 - const in template instantiation not handled perfectly 1085 const char code1[] = "template<class T> struct X { };\n" 1086 "void f(const X<int> x) { }"; 1087 ASSERT_EQUALS("struct X<int> ; " 1088 "void f ( const X<int> x ) { } " 1089 "struct X<int> { } ;", tok(code1)); 1090 1091 const char code2[] = "template<class T> T f(T t) { return t; }\n" 1092 "int x() { return f<int>(123); }"; 1093 ASSERT_EQUALS("int f<int> ( int t ) ; " 1094 "int x ( ) { return f<int> ( 123 ) ; } " 1095 "int f<int> ( int t ) { return t ; }", tok(code2)); 1096 } 1097 template42()1098 void template42() { // #4878 cppcheck aborts in ext-blocks.cpp (clang testcode) 1099 const char code[] = "template<typename ...Args>\n" 1100 "int f0(Args ...args) {\n" 1101 " return ^ {\n" 1102 " return sizeof...(Args);\n" 1103 " }() + ^ {\n" 1104 " return sizeof...(args);\n" 1105 " }();\n" 1106 "}"; 1107 ASSERT_THROW(tok(code), InternalError); 1108 } 1109 template43()1110 void template43() { // #5097 - Assert due to '>>' in 'B<A<C>>' not being treated as end of template instantiation 1111 const char code[] = "template <typename T> struct E { typedef int Int; };\n" 1112 "template <typename T> struct C { };\n" 1113 "template <typename T> struct D { static int f() { return C<T>::f(); } };\n" 1114 "template <typename T> inline int f2() { return D<T>::f(); }\n" 1115 "template <typename T> int f1 (int x, T *) { int id = f2<T>(); return id; }\n" 1116 "template <typename T> struct B { void f3(B<T> & other) { } };\n" 1117 "struct A { };\n" 1118 "template <> struct C<B<A>> {\n" 1119 " static int f() { return f1<B<A>>(0, reinterpret_cast<B<A>*>(E<void*>::Int(-1))); }\n" 1120 "};\n" 1121 "int main(void) {\n" 1122 " C<A> ca;\n" 1123 " return 0;\n" 1124 "}"; 1125 const char expected[] = "struct E<void*> ; " 1126 "struct C<B<A>> ; " 1127 "struct C<A> ; " 1128 "struct D<B<A>> ; " 1129 "int f2<B<A>> ( ) ; " 1130 "int f1<B<A>> ( int x , B<A> * ) ; " 1131 "struct B<A> ; " 1132 "struct A { } ; " 1133 "struct C<B<A>> { " 1134 "static int f ( ) { " 1135 "return f1<B<A>> ( 0 , reinterpret_cast < B<A> * > ( E<void*> :: Int ( -1 ) ) ) ; " 1136 "} " 1137 "} ; " 1138 "int main ( void ) { " 1139 "C<A> ca ; " 1140 "return 0 ; " 1141 "} " 1142 "struct B<A> { " 1143 "void f3 ( B<A> & other ) { } " 1144 "} ; " 1145 "int f1<B<A>> ( int x , B<A> * ) { " 1146 "int id ; id = f2<B<A>> ( ) ; " 1147 "return id ; " 1148 "} " 1149 "int f2<B<A>> ( ) { " 1150 "return D<B<A>> :: f ( ) ; " 1151 "} " 1152 "struct D<B<A>> { " 1153 "static int f ( ) { " 1154 "return C<B<A>> :: f ( ) ; " 1155 "} " 1156 "} ; " 1157 "struct C<A> { } ; struct E<void*> { " 1158 "} ;"; 1159 ASSERT_EQUALS(expected, tok(code)); 1160 } 1161 template44()1162 void template44() { // #5297 1163 const char code[] = "template<class T> struct StackContainer {" 1164 " void foo(int i) {" 1165 " if (0 >= 1 && i<0) {}" 1166 " }" 1167 "};" 1168 "template<class T> class ZContainer : public StackContainer<T> {};" 1169 "struct FGSTensor {};" 1170 "class FoldedZContainer : public ZContainer<FGSTensor> {};"; 1171 const char expected[] = "struct StackContainer<FGSTensor> ; " 1172 "class ZContainer<FGSTensor> ; " 1173 "struct FGSTensor { } ; " 1174 "class FoldedZContainer : public ZContainer<FGSTensor> { } ; " 1175 "class ZContainer<FGSTensor> : public StackContainer<FGSTensor> { } ; " 1176 "struct StackContainer<FGSTensor> { " 1177 "void foo ( int i ) { " 1178 "if ( 0 >= 1 && i < 0 ) { } " 1179 "} " 1180 "} ;"; 1181 ASSERT_EQUALS(expected, tok(code)); 1182 } 1183 template45()1184 void template45() { // #5814 1185 const char code[] = "namespace Constants { const int fourtytwo = 42; } " 1186 "template <class T, int U> struct TypeMath { " 1187 " static const int mult = sizeof(T) * U; " 1188 "}; " 1189 "template <class T> struct FOO { " 1190 " enum { value = TypeMath<T, Constants::fourtytwo>::mult }; " 1191 "}; " 1192 "FOO<int> foo;"; 1193 const char expected[] = "namespace Constants { const int fourtytwo = 42 ; } " 1194 "struct TypeMath<int,Constants::fourtytwo> ; " 1195 "struct FOO<int> ; " 1196 "FOO<int> foo ; " 1197 "struct FOO<int> { " 1198 "enum Anonymous0 { value = TypeMath<int,Constants::fourtytwo> :: mult } ; " 1199 "} ; " 1200 "struct TypeMath<int,Constants::fourtytwo> { " 1201 "static const int mult = sizeof ( int ) * Constants :: fourtytwo ; " 1202 "} ;"; 1203 ASSERT_EQUALS(expected, tok(code, true)); 1204 ASSERT_EQUALS("", errout.str()); 1205 } 1206 template46()1207 void template46() { // #5816 1208 tok("template<class T, class U> struct A { static const int value = 0; }; " 1209 "template <class T> struct B { " 1210 " enum { value = A<typename T::type, int>::value }; " 1211 "};"); 1212 ASSERT_EQUALS("", errout.str()); 1213 tok("template <class T, class U> struct A {}; " 1214 "enum { e = sizeof(A<int, int>) }; " 1215 "template <class T, class U> struct B {};"); 1216 ASSERT_EQUALS("", errout.str()); 1217 tok("template<class T, class U> struct A { static const int value = 0; }; " 1218 "template<class T> struct B { typedef int type; }; " 1219 "template <class T> struct C { " 1220 " enum { value = A<typename B<T>::type, int>::value }; " 1221 "};"); 1222 ASSERT_EQUALS("", errout.str()); 1223 } 1224 template47()1225 void template47() { // #6023 1226 tok("template <typename T1, typename T2 = T3<T1> > class C1 {}; " 1227 "class C2 : public C1<C2> {};"); 1228 ASSERT_EQUALS("", errout.str()); 1229 } 1230 template48()1231 void template48() { // #6134 1232 tok("template <int> int f( { } ); " 1233 "int foo = f<1>(0);"); 1234 ASSERT_EQUALS("", errout.str()); 1235 } 1236 template49()1237 void template49() { // #6237 1238 const char code[] = "template <class T> class Fred { void f(); void g(); };\n" 1239 "template <class T> void Fred<T>::f() { }\n" 1240 "template <class T> void Fred<T>::g() { }\n" 1241 "template void Fred<float>::f();\n" 1242 "template void Fred<int>::g();\n"; 1243 1244 const char expected[] = "class Fred<float> ; " 1245 "class Fred<int> ; " 1246 "class Fred<float> { void f ( ) ; void g ( ) ; } ; " 1247 "void Fred<float> :: f ( ) { } " 1248 "void Fred<float> :: g ( ) { } " 1249 "class Fred<int> { void f ( ) ; void g ( ) ; } ; " 1250 "void Fred<int> :: f ( ) { } " 1251 "void Fred<int> :: g ( ) { }"; 1252 1253 ASSERT_EQUALS(expected, tok(code)); 1254 } 1255 template50()1256 void template50() { // #4272 1257 const char code[] = "template <class T> class Fred { void f(); };\n" 1258 "template <class T> void Fred<T>::f() { }\n" 1259 "template<> void Fred<float>::f() { }\n" 1260 "template<> void Fred<int>::f() { }\n"; 1261 1262 const char expected[] = "class Fred<float> ; " 1263 "class Fred<int> ; " 1264 "template < > void Fred<float> :: f ( ) { } " 1265 "template < > void Fred<int> :: f ( ) { } " 1266 "class Fred<float> { void f ( ) ; } ; " 1267 "void Fred<float> :: f ( ) { } " 1268 "class Fred<int> { void f ( ) ; } ; " 1269 "void Fred<int> :: f ( ) { }"; 1270 1271 ASSERT_EQUALS(expected, tok(code)); 1272 } 1273 template52()1274 void template52() { // #6437 1275 const char code[] = "template <int value> int sum() { " 1276 " return value + sum<value/2>(); " 1277 "} " 1278 "template<int x, int y> int calculate_value() { " 1279 " if (x != y) { " 1280 " return sum<x - y>(); " 1281 " } else { " 1282 " return 0; " 1283 " } " 1284 "} " 1285 "int value = calculate_value<1,1>();"; 1286 const char expected[] = "int sum<0> ( ) ; " 1287 "int calculate_value<1,1> ( ) ; " 1288 "int value ; value = calculate_value<1,1> ( ) ; " 1289 "int calculate_value<1,1> ( ) { " 1290 "if ( 1 != 1 ) { " 1291 "return sum<0> ( ) ; " 1292 "} else { " 1293 "return 0 ; " 1294 "} " 1295 "} " 1296 "int sum<0> ( ) { " 1297 "return 0 + sum<0> ( ) ; " 1298 "}"; 1299 ASSERT_EQUALS(expected, tok(code)); 1300 } 1301 template53()1302 void template53() { // #4335 1303 const char code[] = "template<int N> struct Factorial { " 1304 " enum { value = N * Factorial<N - 1>::value }; " 1305 "};" 1306 "template <> struct Factorial<0> { " 1307 " enum { value = 1 }; " 1308 "};" 1309 "const int x = Factorial<4>::value;"; 1310 const char expected[] = "struct Factorial<0> ; " 1311 "struct Factorial<4> ; " 1312 "struct Factorial<3> ; " 1313 "struct Factorial<2> ; " 1314 "struct Factorial<1> ; " 1315 "struct Factorial<0> { " 1316 "enum Anonymous1 { value = 1 } ; " 1317 "} ; " 1318 "const int x = Factorial<4> :: value ; " 1319 "struct Factorial<4> { " 1320 "enum Anonymous0 { value = 4 * Factorial<3> :: value } ; " 1321 "} ; " 1322 "struct Factorial<3> { " 1323 "enum Anonymous0 { value = 3 * Factorial<2> :: value } ; " 1324 "} ; " 1325 "struct Factorial<2> { " 1326 "enum Anonymous0 { value = 2 * Factorial<1> :: value } ; " 1327 "} ; " 1328 "struct Factorial<1> { " 1329 "enum Anonymous0 { value = 1 * Factorial<0> :: value } ; " 1330 "} ;"; 1331 ASSERT_EQUALS(expected, tok(code, true)); 1332 ASSERT_EQUALS("", errout.str()); 1333 } 1334 template54()1335 void template54() { // #6587 1336 tok("template<typename _Tp> _Tp* fn(); " 1337 "template <class T> struct A { " 1338 " template <class U, class S = decltype(fn<T>())> " 1339 " struct B { }; " 1340 "}; " 1341 "A<int> a;"); 1342 } 1343 template55()1344 void template55() { // #6604 1345 // Avoid constconstconst in macro instantiations 1346 ASSERT_EQUALS( 1347 "template < class T > class AtSmartPtr : public ConstCastHelper < AtSmartPtr < const T > , T > { " 1348 "friend struct ConstCastHelper < AtSmartPtr < const T > , T > ; " 1349 "AtSmartPtr ( const AtSmartPtr < T > & r ) ; " 1350 "} ;", 1351 tok("template<class T> class AtSmartPtr : public ConstCastHelper<AtSmartPtr<const T>, T>\n" 1352 "{\n" 1353 " friend struct ConstCastHelper<AtSmartPtr<const T>, T>;\n" 1354 " AtSmartPtr(const AtSmartPtr<T>& r);\n" 1355 "};")); 1356 1357 // Similar problem can also happen with ... 1358 ASSERT_EQUALS( 1359 "struct A<int> ; " 1360 "struct A<int...> ; " 1361 "A<int> a ( 0 ) ; " 1362 "struct A<int> { " 1363 "A<int> ( int * p ) { ( A<int...> * ) ( p ) ; } " 1364 "} ; " 1365 "struct A<int...> { " 1366 "A<int...> ( int * p ) { " 1367 "( A<int...> * ) ( p ) ; " 1368 "} } ;", 1369 tok("template <typename... T> struct A\n" 1370 "{\n" 1371 " A(T* p) {\n" 1372 " (A<T...>*)(p);\n" 1373 " }\n" 1374 "};\n" 1375 "A<int> a(0);")); 1376 } 1377 template56()1378 void template56() { // #7117 1379 const char code[] = "template<bool B> struct Foo { " 1380 " std::array<int, B ? 1 : 2> mfoo; " 1381 "}; " 1382 "void foo() { " 1383 " Foo<true> myFoo; " 1384 "}"; 1385 const char expected[] = "struct Foo<true> ; " 1386 "void foo ( ) { " 1387 "Foo<true> myFoo ; " 1388 "} struct Foo<true> { " 1389 "std :: array < int , 1 > mfoo ; " 1390 "} ;"; 1391 ASSERT_EQUALS(expected, tok(code, true)); 1392 ASSERT_EQUALS("", errout.str()); 1393 } 1394 template57()1395 void template57() { // #7891 1396 const char code[] = "template<class T> struct Test { Test(T); };\n" 1397 "Test<unsigned long> test( 0 );"; 1398 const char exp[] = "struct Test<unsignedlong> ; " 1399 "Test<unsignedlong> test ( 0 ) ; " 1400 "struct Test<unsignedlong> { Test<unsignedlong> ( unsigned long ) ; } ;"; 1401 ASSERT_EQUALS(exp, tok(code)); 1402 } 1403 template58()1404 void template58() { // #6021 1405 const char code[] = "template <typename A>\n" 1406 "void TestArithmetic() {\n" 1407 " x(1 * CheckedNumeric<A>());\n" 1408 "}\n" 1409 "void foo() {\n" 1410 " TestArithmetic<int>();\n" 1411 "}"; 1412 const char exp[] = "void TestArithmetic<int> ( ) ; " 1413 "void foo ( ) {" 1414 " TestArithmetic<int> ( ) ; " 1415 "} " 1416 "void TestArithmetic<int> ( ) {" 1417 " x ( 1 * CheckedNumeric < int > ( ) ) ; " 1418 "}"; 1419 ASSERT_EQUALS(exp, tok(code)); 1420 } 1421 template59()1422 void template59() { // #8051 1423 const char code[] = "template<int N>\n" 1424 "struct Factorial {\n" 1425 " enum FacHelper { value = N * Factorial<N - 1>::value };\n" 1426 "};\n" 1427 "template <>\n" 1428 "struct Factorial<0> {\n" 1429 " enum FacHelper { value = 1 };\n" 1430 "};\n" 1431 "template<int DiagonalDegree>\n" 1432 "int diagonalGroupTest() {\n" 1433 " return Factorial<DiagonalDegree>::value;\n" 1434 "}\n" 1435 "int main () {\n" 1436 " return diagonalGroupTest<4>();\n" 1437 "}"; 1438 const char exp[] = "struct Factorial<0> ; " 1439 "struct Factorial<4> ; " 1440 "struct Factorial<3> ; " 1441 "struct Factorial<2> ; " 1442 "struct Factorial<1> ; " 1443 "struct Factorial<0> { enum FacHelper { value = 1 } ; } ; " 1444 "int diagonalGroupTest<4> ( ) ; " 1445 "int main ( ) { return diagonalGroupTest<4> ( ) ; } " 1446 "int diagonalGroupTest<4> ( ) { return Factorial<4> :: value ; } " 1447 "struct Factorial<4> { enum FacHelper { value = 4 * Factorial<3> :: value } ; } ; " 1448 "struct Factorial<3> { enum FacHelper { value = 3 * Factorial<2> :: value } ; } ; " 1449 "struct Factorial<2> { enum FacHelper { value = 2 * Factorial<1> :: value } ; } ; " 1450 "struct Factorial<1> { enum FacHelper { value = 1 * Factorial<0> :: value } ; } ;"; 1451 ASSERT_EQUALS(exp, tok(code)); 1452 } 1453 template60()1454 void template60() { // Extracted from Clang testfile 1455 const char code[] = "template <typename T> struct S { typedef int type; };\n" 1456 "template <typename T> void f() {}\n" 1457 "template <typename T> void h() { f<typename S<T>::type(0)>(); }\n" 1458 "\n" 1459 "void j() { h<int>(); }"; 1460 const char exp[] = "struct S<int> ; " 1461 "void f<S<int>::type(0)> ( ) ; " 1462 "void h<int> ( ) ; " 1463 "void j ( ) { h<int> ( ) ; } " 1464 "void h<int> ( ) { f<S<int>::type(0)> ( ) ; } " 1465 "struct S<int> { } ; " 1466 "void f<S<int>::type(0)> ( ) { }"; 1467 const char act[] = "template < typename T > struct S { } ; " 1468 "void f<S<int>::type(0)> ( ) ; " 1469 "void h<int> ( ) ; " 1470 "void j ( ) { h<int> ( ) ; } " 1471 "void h<int> ( ) { f<S<int>::type(0)> ( ) ; } " 1472 "void f<S<int>::type(0)> ( ) { }"; 1473 TODO_ASSERT_EQUALS(exp, act, tok(code)); 1474 } 1475 template61()1476 void template61() { // hang in daca, code extracted from kodi 1477 const char code[] = "template <typename T> struct Foo {};\n" 1478 "template <typename T> struct Bar {\n" 1479 " void f1(Bar<T> x) {}\n" 1480 " Foo<Bar<T>> f2() { }\n" 1481 "};\n" 1482 "Bar<int> c;"; 1483 const char exp[] = "struct Foo<Bar<int>> ; " 1484 "struct Bar<int> ; " 1485 "Bar<int> c ; " 1486 "struct Bar<int> {" 1487 " void f1 ( Bar<int> x ) { }" 1488 " Foo<Bar<int>> f2 ( ) { } " 1489 "} ; " 1490 "struct Foo<Bar<int>> { } ;"; 1491 ASSERT_EQUALS(exp, tok(code)); 1492 } 1493 template62()1494 void template62() { // #8314 1495 const char code[] = "template <class T> struct C1 {};\n" 1496 "template <class T> void f() { x = y ? C1<int>::allocate(1) : 0; }\n" 1497 "template <class T, unsigned S> class C3 {};\n" 1498 "template <class T, unsigned S> C3<T, S>::C3(const C3<T, S> &v) { C1<T *> c1; }\n" 1499 "C3<int,6> c3;"; 1500 const char exp[] = "struct C1<int*> ; " 1501 "template < class T > void f ( ) { x = y ? ( C1 < int > :: allocate ( 1 ) ) : 0 ; } " 1502 "class C3<int,6> ; " 1503 "C3<int,6> c3 ; " 1504 "class C3<int,6> { } ; " 1505 "C3<int,6> :: C3<int,6> ( const C3<int,6> & v ) { C1<int*> c1 ; } " 1506 "struct C1<int*> { } ;"; 1507 ASSERT_EQUALS(exp, tok(code)); 1508 } 1509 template63()1510 void template63() { // #8576 1511 const char code[] = "template<class T> struct TestClass { T m_hi; };" 1512 "TestClass<std::auto_ptr<v>> objTest3;"; 1513 const char exp[] = "struct TestClass<std::auto_ptr<v>> ; " 1514 "TestClass<std::auto_ptr<v>> objTest3 ; " 1515 "struct TestClass<std::auto_ptr<v>> { std :: auto_ptr < v > m_hi ; } ;"; 1516 ASSERT_EQUALS(exp, tok(code)); 1517 } 1518 template64()1519 void template64() { // #8683 1520 const char code[] = "template <typename T>\n" 1521 "bool foo(){return true;}\n" 1522 "struct A {\n" 1523 "template<int n>\n" 1524 "void t_func()\n" 1525 "{\n" 1526 " if( n != 0 || foo<int>());\n" 1527 "}\n" 1528 "void t_caller()\n" 1529 "{\n" 1530 " t_func<0>();\n" 1531 " t_func<1>();\n" 1532 "}\n" 1533 "};"; 1534 const char exp[] = "bool foo<int> ( ) ; " 1535 "struct A { " 1536 "void t_func<0> ( ) ; " 1537 "void t_func<1> ( ) ; " 1538 "void t_caller ( ) " 1539 "{ " 1540 "t_func<0> ( ) ; " 1541 "t_func<1> ( ) ; " 1542 "} " 1543 "} ; " 1544 "void A :: t_func<0> ( ) " 1545 "{ " 1546 "if ( 0 != 0 || foo<int> ( ) ) { ; } " 1547 "} " 1548 "void A :: t_func<1> ( ) " 1549 "{ " 1550 "if ( 1 != 0 || foo<int> ( ) ) { ; } " 1551 "} " 1552 "bool foo<int> ( ) { return true ; }"; 1553 ASSERT_EQUALS(exp, tok(code)); 1554 } 1555 template65()1556 void template65() { // #8321 (crash) 1557 const char code[] = "namespace bpp\n" 1558 "{\n" 1559 "template<class N, class E, class DAGraphImpl>\n" 1560 "class AssociationDAGraphImplObserver :\n" 1561 " public AssociationGraphImplObserver<N, E, DAGraphImpl>\n" 1562 "{};\n" 1563 "template<class N, class E>\n" 1564 "using AssociationDAGlobalGraphObserver = AssociationDAGraphImplObserver<N, E, DAGlobalGraph>;\n" 1565 "}\n" 1566 "using namespace bpp;\n" 1567 "using namespace std;\n" 1568 "int main() {\n" 1569 " AssociationDAGlobalGraphObserver<string,unsigned int> grObs;\n" 1570 " return 1;\n" 1571 "}"; 1572 const char exp[] = "namespace bpp " 1573 "{ " 1574 "class AssociationDAGraphImplObserver<string,unsignedint,DAGlobalGraph> ; " 1575 "} " 1576 "using namespace bpp ; " 1577 "int main ( ) { " 1578 "bpp :: AssociationDAGraphImplObserver<string,unsignedint,DAGlobalGraph> grObs ; " 1579 "return 1 ; " 1580 "} class bpp :: AssociationDAGraphImplObserver<string,unsignedint,DAGlobalGraph> : " 1581 "public AssociationGraphImplObserver < std :: string , unsigned int , DAGlobalGraph > " 1582 "{ } ;"; 1583 ASSERT_EQUALS(exp, tok(code)); 1584 } 1585 template66()1586 void template66() { // #8725 1587 const char code[] = "template <class T> struct Fred {\n" 1588 " const int ** foo();\n" 1589 "};\n" 1590 "template <class T> const int ** Fred<T>::foo() { return nullptr; }\n" 1591 "Fred<int> fred;"; 1592 const char exp[] = "struct Fred<int> ; " 1593 "Fred<int> fred ; " 1594 "struct Fred<int> { " 1595 "const int * * foo ( ) ; " 1596 "} ; " 1597 "const int * * Fred<int> :: foo ( ) { return nullptr ; }"; 1598 ASSERT_EQUALS(exp, tok(code)); 1599 } 1600 template67()1601 void template67() { // ticket #8122 1602 const char code[] = "template <class T> struct Container {\n" 1603 " Container();\n" 1604 " Container(const Container &);\n" 1605 " Container & operator = (const Container &);\n" 1606 " ~Container();\n" 1607 " T* mElements;\n" 1608 " const Container * c;\n" 1609 "};\n" 1610 "template <class T> Container<T>::Container() : mElements(nullptr), c(nullptr) {}\n" 1611 "template <class T> Container<T>::Container(const Container & x) { nElements = x.nElements; c = x.c; }\n" 1612 "template <class T> Container<T> & Container<T>::operator = (const Container & x) { mElements = x.mElements; c = x.c; return *this; }\n" 1613 "template <class T> Container<T>::~Container() {}\n" 1614 "Container<int> intContainer;"; 1615 1616 const char expected[] = "struct Container<int> ; " 1617 "Container<int> intContainer ; " 1618 "struct Container<int> { " 1619 "Container<int> ( ) ; " 1620 "Container<int> ( const Container<int> & ) ; " 1621 "Container<int> & operator= ( const Container<int> & ) ; " 1622 "~ Container<int> ( ) ; " 1623 "int * mElements ; " 1624 "const Container<int> * c ; " 1625 "} ; " 1626 "Container<int> :: Container<int> ( ) : mElements ( nullptr ) , c ( nullptr ) { } " 1627 "Container<int> :: Container<int> ( const Container<int> & x ) { nElements = x . nElements ; c = x . c ; } " 1628 "Container<int> & Container<int> :: operator= ( const Container<int> & x ) { mElements = x . mElements ; c = x . c ; return * this ; } " 1629 "Container<int> :: ~ Container<int> ( ) { }"; 1630 1631 ASSERT_EQUALS(expected, tok(code)); 1632 } 1633 template68()1634 void template68() { 1635 const char code[] = "template <class T> union Fred {\n" 1636 " char dummy[sizeof(T)];\n" 1637 " T value;\n" 1638 "};\n" 1639 "Fred<int> fred;"; 1640 const char exp[] = "union Fred<int> ; " 1641 "Fred<int> fred ; " 1642 "union Fred<int> { " 1643 "char dummy [ sizeof ( int ) ] ; " 1644 "int value ; " 1645 "} ;"; 1646 ASSERT_EQUALS(exp, tok(code)); 1647 } 1648 template69()1649 void template69() { // #8791 1650 const char code[] = "class Test {\n" 1651 " int test;\n" 1652 " template <class T> T lookup() { return test; }\n" 1653 " int Fun() { return lookup<int>(); }\n" 1654 "};"; 1655 const char exp[] = "class Test { " 1656 "int test ; " 1657 "int lookup<int> ( ) ; " 1658 "int Fun ( ) { return lookup<int> ( ) ; } " 1659 "} ; " 1660 "int Test :: lookup<int> ( ) { return test ; }"; 1661 ASSERT_EQUALS(exp, tok(code)); 1662 } 1663 template70()1664 void template70() { // #5289 1665 const char code[] = "template<typename T, typename V, int KeySize = 0> class Bar;\n" 1666 "template<>\n" 1667 "class Bar<void, void> {\n" 1668 "};\n" 1669 "template<typename K, typename V, int KeySize>\n" 1670 "class Bar : private Bar<void, void> {\n" 1671 " void foo() { }\n" 1672 "};"; 1673 const char exp[] = "template < typename T , typename V , int KeySize = 0 > class Bar ; " 1674 "class Bar<void,void> ; " 1675 "class Bar<void,void> { " 1676 "} ; " 1677 "template < typename K , typename V , int KeySize = 0 > " 1678 "class Bar : private Bar<void,void> { " 1679 "void foo ( ) { } " 1680 "} ;"; 1681 const char act[] = "template < typename T , typename V , int KeySize = 0 > class Bar ; " 1682 "class Bar<void,void> { " 1683 "} ; " 1684 "class Bar<void,void> ; " 1685 "template < typename K , typename V , int KeySize = 0 > " 1686 "class Bar : private Bar<void,void> { " 1687 "void foo ( ) { } " 1688 "} ;"; 1689 TODO_ASSERT_EQUALS(exp, act, tok(code)); 1690 } 1691 template71()1692 void template71() { // #8821 1693 const char code[] = "int f1(int * pInterface, int x) { return 0; }\n" 1694 "\n" 1695 "template< class interface_type > class Reference {\n" 1696 " template< class interface_type > int i();\n" 1697 " int *pInterface;\n" 1698 "};\n" 1699 "\n" 1700 "template< class interface_type > int Reference< interface_type >::i() {\n" 1701 " return f1(pInterface, interface_type::static_type());\n" 1702 "}\n" 1703 "\n" 1704 "Reference< class XPropertyList > dostuff();"; 1705 const char exp[] = "int f1 ( int * pInterface , int x ) { return 0 ; } " 1706 "class Reference<XPropertyList> ; " 1707 "Reference<XPropertyList> dostuff ( ) ; " 1708 "class Reference<XPropertyList> { template < class XPropertyList > int i ( ) ; int * pInterface ; } ; " 1709 "int Reference<XPropertyList> :: i ( ) { return f1 ( pInterface , XPropertyList :: static_type ( ) ) ; }"; 1710 ASSERT_EQUALS(exp, tok(code)); 1711 } 1712 template72()1713 void template72() { 1714 const char code[] = "template <typename N, typename P> class Tokenizer;\n" 1715 "const Tokenizer<Node, Path> *tokenizer() const;\n" 1716 "template <typename N, typename P>\n" 1717 "Tokenizer<N, P>::Tokenizer() { }"; 1718 const char exp[] = "template < typename N , typename P > class Tokenizer ; " 1719 "const Tokenizer < Node , Path > * tokenizer ( ) const ; " 1720 "template < typename N , typename P > " 1721 "Tokenizer < N , P > :: Tokenizer ( ) { }"; 1722 ASSERT_EQUALS(exp, tok(code)); 1723 } 1724 template73()1725 void template73() { 1726 const char code[] = "template<typename T>\n" 1727 "void keep_range(T& value, const T mini, const T maxi){}\n" 1728 "template void keep_range<float>(float& v, const float l, const float u);\n" 1729 "template void keep_range<int>(int& v, const int l, const int u);"; 1730 const char exp[] = "void keep_range<float> ( float & value , const float mini , const float maxi ) ; " 1731 "void keep_range<int> ( int & value , const int mini , const int maxi ) ; " 1732 "void keep_range<float> ( float & value , const float mini , const float maxi ) { } " 1733 "void keep_range<int> ( int & value , const int mini , const int maxi ) { }"; 1734 ASSERT_EQUALS(exp, tok(code)); 1735 } 1736 template74()1737 void template74() { 1738 const char code[] = "template <class T> class BTlist { };\n" 1739 "class PushBackStreamBuf {\n" 1740 "public:\n" 1741 " void pushBack(const BTlist<int> &vec);\n" 1742 "};"; 1743 const char exp[] = "class BTlist<int> ; " 1744 "class PushBackStreamBuf { " 1745 "public: " 1746 "void pushBack ( const BTlist<int> & vec ) ; " 1747 "} ; " 1748 "class BTlist<int> { } ;"; 1749 ASSERT_EQUALS(exp, tok(code)); 1750 } 1751 template75()1752 void template75() { 1753 const char code[] = "template<typename T>\n" 1754 "T foo(T& value){ return value; }\n" 1755 "template std::vector<std::vector<int>> foo<std::vector<std::vector<int>>>(std::vector<std::vector<int>>& v);"; 1756 const char exp[] = "std :: vector < std :: vector < int > > foo<std::vector<std::vector<int>>> ( std :: vector < std :: vector < int > > & value ) ; " 1757 "std :: vector < std :: vector < int > > foo<std::vector<std::vector<int>>> ( std :: vector < std :: vector < int > > & value ) { return value ; }"; 1758 ASSERT_EQUALS(exp, tok(code)); 1759 } 1760 template76()1761 void template76() { 1762 const char code[] = "namespace NS {\n" 1763 " template<typename T> T foo(T& value) { return value; }\n" 1764 " template std::vector<std::vector<int>> foo<std::vector<std::vector<int>>>(std::vector<std::vector<int>>& v);\n" 1765 "}\n" 1766 "std::vector<std::vector<int>> v;\n" 1767 "v = foo<std::vector<std::vector<int>>>(v);\n"; 1768 const char exp[] = "namespace NS { " 1769 "std :: vector < std :: vector < int > > foo<std::vector<std::vector<int>>> ( std :: vector < std :: vector < int > > & value ) ; " 1770 "} " 1771 "std :: vector < std :: vector < int > > v ; " 1772 "v = foo<std::vector<std::vector<int>>> ( v ) ; " 1773 "std :: vector < std :: vector < int > > NS :: foo<std::vector<std::vector<int>>> ( std :: vector < std :: vector < int > > & value ) { return value ; }"; 1774 ASSERT_EQUALS(exp, tok(code)); 1775 } 1776 template77()1777 void template77() { 1778 const char code[] = "template<typename T>\n" 1779 "struct is_void : std::false_type { };\n" 1780 "template<>\n" 1781 "struct is_void<void> : std::true_type { };\n" 1782 "int main() {\n" 1783 " std::cout << is_void<char>::value << std::endl;\n" 1784 " std::cout << is_void<void>::value << std::endl;\n" 1785 "}"; 1786 const char exp[] = "struct is_void<void> ; " 1787 "struct is_void<char> ; " 1788 "struct is_void<void> : std :: true_type { } ; " 1789 "int main ( ) { " 1790 "std :: cout << is_void<char> :: value << std :: endl ; " 1791 "std :: cout << is_void<void> :: value << std :: endl ; " 1792 "} " 1793 "struct is_void<char> : std :: false_type { } ;"; 1794 ASSERT_EQUALS(exp, tok(code)); 1795 } 1796 template78()1797 void template78() { 1798 const char code[] = "template <typename>\n" 1799 "struct Base { };\n" 1800 "struct S : Base <void>::Type { };"; 1801 const char exp[] = "struct Base<void> ; " 1802 "struct S : Base<void> :: Type { } ; " 1803 "struct Base<void> { } ;"; 1804 ASSERT_EQUALS(exp, tok(code)); 1805 } 1806 template79()1807 void template79() { // #5133 1808 const char code[] = "class Foo {\n" 1809 "public:\n" 1810 " template<typename T> void foo() { bar<T>(); }\n" 1811 "private:\n" 1812 " template<typename T> void bar() { bazz(); }\n" 1813 " void bazz() { }\n" 1814 "};\n" 1815 "void some_func() {\n" 1816 " Foo x;\n" 1817 " x.foo<int>();\n" 1818 "}"; 1819 const char exp[] = "class Foo { " 1820 "public: " 1821 "void foo<int> ( ) ; " 1822 "private: " 1823 "void bar<int> ( ) ; " 1824 "void bazz ( ) { } " 1825 "} ; " 1826 "void some_func ( ) { " 1827 "Foo x ; " 1828 "x . foo<int> ( ) ; " 1829 "} " 1830 "void Foo :: foo<int> ( ) { bar<int> ( ) ; } " 1831 "void Foo :: bar<int> ( ) { bazz ( ) ; }"; 1832 ASSERT_EQUALS(exp, tok(code)); 1833 } 1834 template80()1835 void template80() { 1836 const char code[] = "class Fred {\n" 1837 " template <typename T> T foo(T t) const { return t; }\n" 1838 "};\n" 1839 "const void * p = Fred::foo<const void *>(nullptr);"; 1840 const char exp[] = "class Fred { " 1841 "const void * foo<constvoid*> ( const void * t ) const ; " 1842 "} ; " 1843 "const void * p ; p = Fred :: foo<constvoid*> ( nullptr ) ; " 1844 "const void * Fred :: foo<constvoid*> ( const void * t ) const { return t ; }"; 1845 ASSERT_EQUALS(exp, tok(code)); 1846 } 1847 template81()1848 void template81() { 1849 const char code[] = "template <typename Type>\n" 1850 "struct SortWith {\n" 1851 " SortWith(Type);\n" 1852 "};\n" 1853 "template <typename Type>\n" 1854 "SortWith<Type>::SortWith(Type) {}\n" 1855 "int main() {\n" 1856 " SortWith<int>(0);\n" 1857 "}"; 1858 const char exp[] = "template < typename Type > " 1859 "struct SortWith { " 1860 "SortWith ( Type ) ; " 1861 "} ; " 1862 "SortWith<int> :: SortWith<int> ( int ) ; " 1863 "int main ( ) { " 1864 "SortWith<int> ( 0 ) ; " 1865 "} " 1866 "SortWith<int> :: SortWith<int> ( int ) { }"; 1867 ASSERT_EQUALS(exp, tok(code)); 1868 } 1869 template82()1870 void template82() { // 8603 1871 const char code[] = "typedef int comp;\n" 1872 "const int f16=16;\n" 1873 "template<int x>\n" 1874 "class tvec2 {};\n" 1875 "template<int x>\n" 1876 "class tvec3 {};\n" 1877 "namespace swizzle {\n" 1878 "template <comp> void swizzle(tvec2<f16> v) { }\n" 1879 "template <comp x, comp y> void swizzle(tvec3<f16> v) { }\n" 1880 "}\n" 1881 "void foo() {\n" 1882 " using namespace swizzle;\n" 1883 " tvec2<f16> tt2;\n" 1884 " swizzle<1>(tt2);\n" 1885 " tvec3<f16> tt3;\n" 1886 " swizzle<2,3>(tt3);\n" 1887 "}"; 1888 const char exp[] = "const int f16 = 16 ; " 1889 "class tvec2<f16> ; " 1890 "class tvec3<f16> ; " 1891 "namespace swizzle { " 1892 "void swizzle<1> ( tvec2<f16> v ) ; " 1893 "void swizzle<2,3> ( tvec3<f16> v ) ; " 1894 "} " 1895 "void foo ( ) { " 1896 "using namespace swizzle ; " 1897 "tvec2<f16> tt2 ; " 1898 "swizzle :: swizzle<1> ( tt2 ) ; " 1899 "tvec3<f16> tt3 ; " 1900 "swizzle :: swizzle<2,3> ( tt3 ) ; " 1901 "} " 1902 "void swizzle :: swizzle<2,3> ( tvec3<f16> v ) { } " 1903 "void swizzle :: swizzle<1> ( tvec2<f16> v ) { } " 1904 "class tvec3<f16> { } ; " 1905 "class tvec2<f16> { } ;"; 1906 ASSERT_EQUALS(exp, tok(code)); 1907 } 1908 template83()1909 void template83() { // #8867 1910 const char code[] = "template<typename Task>\n" 1911 "class MultiConsumer {\n" 1912 " MultiConsumer();\n" 1913 "};\n" 1914 "template<typename Task>\n" 1915 "MultiConsumer<Task>::MultiConsumer() : sizeBuffer(0) {}\n" 1916 "MultiReads::MultiReads() {\n" 1917 " mc = new MultiConsumer<reads_packet>();\n" 1918 "}"; 1919 const char exp[] = "template < typename Task > " // TODO: this should be expanded 1920 "class MultiConsumer { " 1921 "MultiConsumer ( ) ; " 1922 "} ; " 1923 "MultiConsumer<reads_packet> :: MultiConsumer<reads_packet> ( ) ; " 1924 "MultiReads :: MultiReads ( ) { " 1925 "mc = new MultiConsumer<reads_packet> ( ) ; " 1926 "} " 1927 "MultiConsumer<reads_packet> :: MultiConsumer<reads_packet> ( ) : sizeBuffer ( 0 ) { }"; 1928 ASSERT_EQUALS(exp, tok(code)); 1929 } 1930 template84()1931 void template84() { // #8880 1932 { 1933 const char code[] = "template <class b, int c, class>\n" 1934 "auto d() -> typename a<decltype(b{})>::e {\n" 1935 " d<int, c, int>();\n" 1936 "}"; 1937 const char exp[] = "template < class b , int c , class > " 1938 "auto d ( ) . a < decltype ( b { } ) > :: e { " 1939 "d < int , c , int > ( ) ; " 1940 "}"; 1941 ASSERT_EQUALS(exp, tok(code)); 1942 } 1943 { 1944 const char code[] = "template <class b, int c, class>\n" 1945 "auto d() -> typename a<decltype(b{})>::e {\n" 1946 " d<int, c, int>();\n" 1947 "}" 1948 "void foo() { d<char, 1, int>(); }"; 1949 const char exp[] = "auto d<char,1,int> ( ) . a < char > :: e ; " 1950 "auto d<int,1,int> ( ) . a < int > :: e ; " 1951 "void foo ( ) { d<char,1,int> ( ) ; } " 1952 "auto d<char,1,int> ( ) . a < char > :: e { " 1953 "d<int,1,int> ( ) ; " 1954 "} " 1955 "auto d<int,1,int> ( ) . a < int > :: e { " 1956 "d<int,1,int> ( ) ; " 1957 "}"; 1958 ASSERT_EQUALS(exp, tok(code)); 1959 } 1960 } 1961 template85()1962 void template85() { // #8902 - crash 1963 const char code[] = "template<typename T>\n" 1964 "struct C\n" 1965 "{\n" 1966 " template<typename U, typename std::enable_if<(!std::is_fundamental<U>::value)>::type* = nullptr>\n" 1967 " void foo();\n" 1968 "};\n" 1969 "extern template void C<int>::foo<int, nullptr>();\n" 1970 "template<typename T>\n" 1971 "template<typename U, typename std::enable_if<(!std::is_fundamental<U>::value)>::type>\n" 1972 "void C<T>::foo() {}"; 1973 // @todo the output is very wrong but we are only worried about the crash for now 1974 tok(code); 1975 } 1976 template86()1977 void template86() { // crash 1978 const char code[] = "struct S {\n" 1979 " S();\n" 1980 "};\n" 1981 "template <typename T>\n" 1982 "struct U {\n" 1983 " static S<T> u;\n" 1984 "};\n" 1985 "template <typename T>\n" 1986 "S<T> U<T>::u;\n" 1987 "template S<int> U<int>::u;\n" 1988 "S<int> &i = U<int>::u;"; 1989 tok(code); 1990 } 1991 template87()1992 void template87() { 1993 const char code[] = "template<typename T>\n" 1994 "T f1(T t) { return t; }\n" 1995 "template const char * f1<const char *>(const char *);\n" 1996 "template const char & f1<const char &>(const char &);"; 1997 const char exp[] = "const char * f1<constchar*> ( const char * t ) ; " 1998 "const char & f1<constchar&> ( const char & t ) ; " 1999 "const char * f1<constchar*> ( const char * t ) { return t ; } " 2000 "const char & f1<constchar&> ( const char & t ) { return t ; }"; 2001 ASSERT_EQUALS(exp, tok(code)); 2002 } 2003 template88()2004 void template88() { // #6183.cpp 2005 const char code[] = "class CTest {\n" 2006 "public:\n" 2007 " template <typename T>\n" 2008 " static void Greeting(T val) {\n" 2009 " std::cout << val << std::endl;\n" 2010 " }\n" 2011 "private:\n" 2012 " static void SayHello() {\n" 2013 " std::cout << \"Hello World!\" << std::endl;\n" 2014 " }\n" 2015 "};\n" 2016 "template<>\n" 2017 "void CTest::Greeting(bool) {\n" 2018 " CTest::SayHello();\n" 2019 "}\n" 2020 "int main() {\n" 2021 " CTest::Greeting<bool>(true);\n" 2022 " return 0;\n" 2023 "}"; 2024 const char exp[] = "class CTest { " 2025 "public: " 2026 "static void Greeting<bool> ( bool ) ; " 2027 "template < typename T > " 2028 "static void Greeting ( T val ) { " 2029 "std :: cout << val << std :: endl ; " 2030 "} " 2031 "private: " 2032 "static void SayHello ( ) { " 2033 "std :: cout << \"Hello World!\" << std :: endl ; " 2034 "} " 2035 "} ; " 2036 "void CTest :: Greeting<bool> ( bool ) { " 2037 "CTest :: SayHello ( ) ; " 2038 "} " 2039 "int main ( ) { " 2040 "CTest :: Greeting<bool> ( true ) ; " 2041 "return 0 ; " 2042 "}"; 2043 ASSERT_EQUALS(exp, tok(code)); 2044 } 2045 template89()2046 void template89() { // #8917 2047 const char code[] = "struct Fred {\n" 2048 " template <typename T> static void foo() { }\n" 2049 "};\n" 2050 "template void Fred::foo<char>();\n" 2051 "template void Fred::foo<float>();\n" 2052 "template <> void Fred::foo<bool>() { }\n" 2053 "template <> void Fred::foo<int>() { }"; 2054 const char exp[] = "struct Fred { " 2055 "static void foo<int> ( ) ; " 2056 "static void foo<bool> ( ) ; " 2057 "static void foo<char> ( ) ; " 2058 "static void foo<float> ( ) ; " 2059 "} ; " 2060 "void Fred :: foo<bool> ( ) { } " 2061 "void Fred :: foo<int> ( ) { } " 2062 "void Fred :: foo<char> ( ) { } " 2063 "void Fred :: foo<float> ( ) { }"; 2064 ASSERT_EQUALS(exp, tok(code)); 2065 } 2066 template90()2067 void template90() { // crash 2068 const char code[] = "template <typename T> struct S1 {};\n" 2069 "void f(S1<double>) {}\n" 2070 "template <typename T>\n" 2071 "decltype(S1<T>().~S1<T>()) fun1() {};"; 2072 const char exp[] = "struct S1<double> ; " 2073 "void f ( S1<double> ) { } " 2074 "template < typename T > " 2075 "decltype ( S1 < T > ( ) . ~ S1 < T > ( ) ) fun1 ( ) { } ; " 2076 "struct S1<double> { } ;"; 2077 ASSERT_EQUALS(exp, tok(code)); 2078 } 2079 template91()2080 void template91() { 2081 { 2082 const char code[] = "template<typename T> T foo(T t) { return t; }\n" 2083 "template<> char foo<char>(char a) { return a; }\n" 2084 "template<> int foo<int>(int a) { return a; }\n" 2085 "template float foo<float>(float);\n" 2086 "template double foo<double>(double);"; 2087 const char exp[] = "int foo<int> ( int a ) ; " 2088 "char foo<char> ( char a ) ; " 2089 "float foo<float> ( float t ) ; " 2090 "double foo<double> ( double t ) ; " 2091 "char foo<char> ( char a ) { return a ; } " 2092 "int foo<int> ( int a ) { return a ; } " 2093 "float foo<float> ( float t ) { return t ; } " 2094 "double foo<double> ( double t ) { return t ; }"; 2095 ASSERT_EQUALS(exp, tok(code)); 2096 } 2097 { 2098 const char code[] = "struct Fred {\n" 2099 " template<typename T> T foo(T t) { return t; }\n" 2100 " template<> char foo<char>(char a) { return a; }\n" 2101 " template<> int foo<int>(int a) { return a; }\n" 2102 "};\n" 2103 "template float Fred::foo<float>(float);\n" 2104 "template double Fred::foo<double>(double);"; 2105 const char exp[] = "struct Fred { " 2106 "int foo<int> ( int a ) ; " 2107 "char foo<char> ( char a ) ; " 2108 "float foo<float> ( float t ) ; " 2109 "double foo<double> ( double t ) ; " 2110 "char foo<char> ( char a ) { return a ; } " 2111 "int foo<int> ( int a ) { return a ; } " 2112 "} ; " 2113 "float Fred :: foo<float> ( float t ) { return t ; } " 2114 "double Fred :: foo<double> ( double t ) { return t ; }"; 2115 ASSERT_EQUALS(exp, tok(code)); 2116 } 2117 { 2118 const char code[] = "namespace NS1 {\n" 2119 " namespace NS2 {\n" 2120 " template<typename T> T foo(T t) { return t; }\n" 2121 " template<> char foo<char>(char a) { return a; }\n" 2122 " template<> int foo<int>(int a) { return a; }\n" 2123 " template short NS2::foo<short>(short);\n" 2124 " template long NS1::NS2::foo<long>(long);\n" 2125 " }\n" 2126 " template float NS2::foo<float>(float);\n" 2127 " template bool NS1::NS2::foo<bool>(bool);\n" 2128 "}\n" 2129 "template double NS1::NS2::foo<double>(double);"; 2130 const char exp[] = "namespace NS1 { " 2131 "namespace NS2 { " 2132 "int foo<int> ( int a ) ; " 2133 "char foo<char> ( char a ) ; " 2134 "short foo<short> ( short t ) ; " 2135 "long foo<long> ( long t ) ; " 2136 "float foo<float> ( float t ) ; " 2137 "bool foo<bool> ( bool t ) ; " 2138 "double foo<double> ( double t ) ; " 2139 "char foo<char> ( char a ) { return a ; } " 2140 "int foo<int> ( int a ) { return a ; } " 2141 "} " 2142 "} " 2143 "short NS1 :: NS2 :: foo<short> ( short t ) { return t ; } " 2144 "long NS1 :: NS2 :: foo<long> ( long t ) { return t ; } " 2145 "float NS1 :: NS2 :: foo<float> ( float t ) { return t ; } " 2146 "bool NS1 :: NS2 :: foo<bool> ( bool t ) { return t ; } " 2147 "double NS1 :: NS2 :: foo<double> ( double t ) { return t ; }"; 2148 ASSERT_EQUALS(exp, tok(code)); 2149 } 2150 { 2151 const char code[] = "namespace NS1 {\n" 2152 " namespace NS {\n" 2153 " template<typename T> T foo(T t) { return t; }\n" 2154 " template<> char foo<char>(char a) { return a; }\n" 2155 " template<> int foo<int>(int a) { return a; }\n" 2156 " template short NS::foo<short>(short);\n" 2157 " template long NS1::NS::foo<long>(long);\n" 2158 " }\n" 2159 " template float NS::foo<float>(float);\n" 2160 " template bool NS1::NS::foo<bool>(bool);\n" 2161 "}\n" 2162 "template double NS1::NS::foo<double>(double);"; 2163 const char exp[] = "namespace NS1 { " 2164 "namespace NS { " 2165 "int foo<int> ( int a ) ; " 2166 "char foo<char> ( char a ) ; " 2167 "short foo<short> ( short t ) ; " 2168 "long foo<long> ( long t ) ; " 2169 "float foo<float> ( float t ) ; " 2170 "bool foo<bool> ( bool t ) ; " 2171 "double foo<double> ( double t ) ; " 2172 "char foo<char> ( char a ) { return a ; } " 2173 "int foo<int> ( int a ) { return a ; } " 2174 "} " 2175 "} " 2176 "short NS1 :: NS :: foo<short> ( short t ) { return t ; } " 2177 "long NS1 :: NS :: foo<long> ( long t ) { return t ; } " 2178 "float NS1 :: NS :: foo<float> ( float t ) { return t ; } " 2179 "bool NS1 :: NS :: foo<bool> ( bool t ) { return t ; } " 2180 "double NS1 :: NS :: foo<double> ( double t ) { return t ; }"; 2181 ASSERT_EQUALS(exp, tok(code)); 2182 } 2183 } 2184 template92()2185 void template92() { 2186 const char code[] = "template<class T> void foo(T const& t) { }\n" 2187 "template<> void foo<double>(double const& d) { }\n" 2188 "template void foo<float>(float const& f);\n" 2189 "int main() {\n" 2190 " foo<int>(2);\n" 2191 " foo<double>(3.14);\n" 2192 " foo<float>(3.14f);\n" 2193 "}"; 2194 const char exp[] = "void foo<double> ( const double & d ) ; " 2195 "void foo<float> ( const float & t ) ; " 2196 "void foo<int> ( const int & t ) ; " 2197 "void foo<double> ( const double & d ) { } " 2198 "int main ( ) { " 2199 "foo<int> ( 2 ) ; " 2200 "foo<double> ( 3.14 ) ; " 2201 "foo<float> ( 3.14f ) ; " 2202 "} " 2203 "void foo<float> ( const float & t ) { } " 2204 "void foo<int> ( const int & t ) { }"; 2205 ASSERT_EQUALS(exp, tok(code)); 2206 } 2207 template93()2208 void template93() { // crash 2209 const char code[] = "template <typename Iterator>\n" 2210 "void ForEach() { }\n" 2211 "template <typename Type>\n" 2212 "class Vector2 : public Vector {\n" 2213 " template <typename Iterator>\n" 2214 " void ForEach();\n" 2215 "public:\n" 2216 " void process();\n" 2217 "};\n" 2218 "template <typename Type>\n" 2219 "void Vector2<Type>::process() {\n" 2220 " ForEach<iterator>();\n" 2221 "}\n" 2222 "Vector2<string> c;"; 2223 const char exp[] = "void ForEach<iterator> ( ) ; " 2224 "class Vector2<string> ; " 2225 "Vector2<string> c ; " 2226 "class Vector2<string> : public Vector { " 2227 "template < typename Iterator > " 2228 "void ForEach ( ) ; " 2229 "public: " 2230 "void process ( ) ; " 2231 "} ; " 2232 "void Vector2<string> :: process ( ) { " 2233 "ForEach<iterator> ( ) ; " 2234 "} " 2235 "void ForEach<iterator> ( ) { " 2236 "}"; 2237 ASSERT_EQUALS(exp, tok(code)); 2238 } 2239 template94()2240 void template94() { // #8927 crash 2241 const char code[] = "template <typename T>\n" 2242 "class Array { };\n" 2243 "template<typename T>\n" 2244 "Array<T> foo() {};\n" 2245 "template <> Array<double> foo<double>() { }\n" 2246 "template <> Array<std::complex<float>> foo<std::complex<float>>() { }\n" 2247 "template <> Array<float> foo<float>() { }\n" 2248 "template < typename T >\n" 2249 "Array<T> matmul() {\n" 2250 " return foo<T>( );\n" 2251 "}\n" 2252 "template Array<std::complex<float>> matmul<std::complex<float>>();"; 2253 const char exp[] = "class Array<double> ; " 2254 "class Array<std::complex<float>> ; " 2255 "class Array<float> ; " 2256 "Array<float> foo<float> ( ) ; " 2257 "Array<std::complex<float>> foo<std::complex<float>> ( ) ; " 2258 "Array<double> foo<double> ( ) ; " 2259 "template < typename T > " 2260 "Array < T > foo ( ) { } ; " 2261 "Array<double> foo<double> ( ) { } " 2262 "Array<std::complex<float>> foo<std::complex<float>> ( ) { } " 2263 "Array<float> foo<float> ( ) { } " 2264 "Array<std::complex<float>> matmul<std::complex<float>> ( ) ; " 2265 "Array<std::complex<float>> matmul<std::complex<float>> ( ) { " 2266 "return foo<std::complex<float>> ( ) ; " 2267 "} " 2268 "class Array<double> { } ; " 2269 "class Array<std::complex<float>> { } ; " 2270 "class Array<float> { } ;"; 2271 ASSERT_EQUALS(exp, tok(code)); 2272 } 2273 template95()2274 void template95() { // #7417 2275 const char code[] = "template <typename T>\n" 2276 "T Value = 123;\n" 2277 "template<>\n" 2278 "int Value<int> = 456;\n" 2279 "float f = Value<float>;\n" 2280 "int i = Value<int>;"; 2281 const char exp[] = "float Value<float> ; Value<float> = 123 ; " 2282 "int Value<int> ; Value<int> = 456 ; " 2283 "float f ; f = Value<float> ; " 2284 "int i ; i = Value<int> ;"; 2285 ASSERT_EQUALS(exp, tok(code)); 2286 } 2287 template96()2288 void template96() { // #7854 2289 { 2290 const char code[] = "template<unsigned int n>\n" 2291 " constexpr long fib = fib<n-1> + fib<n-2>;\n" 2292 "template<>\n" 2293 " constexpr long fib<0> = 0;\n" 2294 "template<>\n" 2295 " constexpr long fib<1> = 1;\n" 2296 "long f0 = fib<0>;\n" 2297 "long f1 = fib<1>;\n" 2298 "long f2 = fib<2>;\n" 2299 "long f3 = fib<3>;"; 2300 const char exp[] = "constexpr long fib<2> = fib<1> + fib<0> ; " 2301 "constexpr long fib<3> = fib<2> + fib<1> ; " 2302 "constexpr long fib<0> = 0 ; " 2303 "constexpr long fib<1> = 1 ; " 2304 "long f0 ; f0 = fib<0> ; " 2305 "long f1 ; f1 = fib<1> ; " 2306 "long f2 ; f2 = fib<2> ; " 2307 "long f3 ; f3 = fib<3> ;"; 2308 ASSERT_EQUALS(exp, tok(code)); 2309 } 2310 { 2311 const char code[] = "template<unsigned int n>\n" 2312 " constexpr long fib = fib<n-1> + fib<n-2>;\n" 2313 "template<>\n" 2314 " constexpr long fib<0> = 0;\n" 2315 "template<>\n" 2316 " constexpr long fib<1> = 1;\n" 2317 "long f5 = fib<5>;\n"; 2318 const char exp[] = "constexpr long fib<5> = fib<4> + fib<3> ; " 2319 "constexpr long fib<4> = fib<3> + fib<2> ; " 2320 "constexpr long fib<3> = fib<2> + fib<1> ; " 2321 "constexpr long fib<2> = fib<1> + fib<0> ; " 2322 "constexpr long fib<0> = 0 ; " 2323 "constexpr long fib<1> = 1 ; " 2324 "long f5 ; f5 = fib<5> ;"; 2325 ASSERT_EQUALS(exp, tok(code)); 2326 } 2327 } 2328 template97()2329 void template97() { 2330 const char code[] ="namespace NS1 {\n" 2331 " namespace NS2 {\n" 2332 " namespace NS3 {\n" 2333 " namespace NS4 {\n" 2334 " template<class T>\n" 2335 " class Fred {\n" 2336 " T * t;\n" 2337 " public:\n" 2338 " Fred<T>() : t(nullptr) {}\n" 2339 " };\n" 2340 " }\n" 2341 " using namespace NS4;\n" 2342 " Fred<bool> fred_bool;\n" 2343 " NS4::Fred<char> fred_char;\n" 2344 " }\n" 2345 " using namespace NS3;\n" 2346 " NS4::Fred<short> fred_short;\n" 2347 " using namespace NS3::NS4;\n" 2348 " Fred<int> fred_int;\n" 2349 " NS3::NS4::Fred<long> fred_long;\n" 2350 " NS2::NS3::NS4::Fred<float> fred_float;\n" 2351 " NS1::NS2::NS3::NS4::Fred<double> fred_double;\n" 2352 " }\n" 2353 " using namespace NS2;\n" 2354 " NS3::NS4::Fred<float> fred_float1;\n" 2355 " NS2::NS3::NS4::Fred<double> fred_double1;\n" 2356 "}\n" 2357 "using namespace NS1::NS2::NS3::NS4;\n" 2358 "Fred<bool> fred_bool1;\n" 2359 "NS1::NS2::NS3::NS4::Fred<int> fred_int1;"; 2360 const char exp[] = "namespace NS1 { " 2361 "namespace NS2 { " 2362 "namespace NS3 { " 2363 "namespace NS4 { " 2364 "class Fred<bool> ; " 2365 "class Fred<char> ; " 2366 "class Fred<short> ; " 2367 "class Fred<int> ; " 2368 "class Fred<long> ; " 2369 "class Fred<float> ; " 2370 "class Fred<double> ; " 2371 "} " 2372 "using namespace NS4 ; " 2373 "NS4 :: Fred<bool> fred_bool ; " 2374 "NS4 :: Fred<char> fred_char ; " 2375 "} " 2376 "using namespace NS3 ; " 2377 "NS3 :: NS4 :: Fred<short> fred_short ; " 2378 "using namespace NS3 :: NS4 ; " 2379 "NS3 :: NS4 :: Fred<int> fred_int ; " 2380 "NS3 :: NS4 :: Fred<long> fred_long ; " 2381 "NS2 :: NS3 :: NS4 :: Fred<float> fred_float ; " 2382 "NS1 :: NS2 :: NS3 :: NS4 :: Fred<double> fred_double ; " 2383 "} " 2384 "using namespace NS2 ; " 2385 "NS2 :: NS3 :: NS4 :: Fred<float> fred_float1 ; " 2386 "NS2 :: NS3 :: NS4 :: Fred<double> fred_double1 ; " 2387 "} " 2388 "using namespace NS1 :: NS2 :: NS3 :: NS4 ; " 2389 "NS1 :: NS2 :: NS3 :: NS4 :: Fred<bool> fred_bool1 ; " 2390 "NS1 :: NS2 :: NS3 :: NS4 :: Fred<int> fred_int1 ; " 2391 "class NS1 :: NS2 :: NS3 :: NS4 :: Fred<bool> { " 2392 "bool * t ; " 2393 "public: " 2394 "Fred<bool> ( ) : t ( nullptr ) { } " 2395 "} ; " 2396 "class NS1 :: NS2 :: NS3 :: NS4 :: Fred<char> { " 2397 "char * t ; " 2398 "public: " 2399 "Fred<char> ( ) : t ( nullptr ) { } " 2400 "} ; " 2401 "class NS1 :: NS2 :: NS3 :: NS4 :: Fred<short> { " 2402 "short * t ; " 2403 "public: " 2404 "Fred<short> ( ) : t ( nullptr ) { } " 2405 "} ; " 2406 "class NS1 :: NS2 :: NS3 :: NS4 :: Fred<int> { " 2407 "int * t ; " 2408 "public: " 2409 "Fred<int> ( ) : t ( nullptr ) { } " 2410 "} ; " 2411 "class NS1 :: NS2 :: NS3 :: NS4 :: Fred<long> { " 2412 "long * t ; " 2413 "public: " 2414 "Fred<long> ( ) : t ( nullptr ) { } " 2415 "} ; " 2416 "class NS1 :: NS2 :: NS3 :: NS4 :: Fred<float> { " 2417 "float * t ; " 2418 "public: " 2419 "Fred<float> ( ) : t ( nullptr ) { } " 2420 "} ; " 2421 "class NS1 :: NS2 :: NS3 :: NS4 :: Fred<double> { " 2422 "double * t ; " 2423 "public: " 2424 "Fred<double> ( ) : t ( nullptr ) { } " 2425 "} ;"; 2426 ASSERT_EQUALS(exp, tok(code)); 2427 } 2428 template98()2429 void template98() { // #8959 2430 const char code[] = "template <typename T>\n" 2431 "using unique_ptr_with_deleter = std::unique_ptr<T, std::function<void(T*)>>;\n" 2432 "class A {};\n" 2433 "static void func() {\n" 2434 " unique_ptr_with_deleter<A> tmp(new A(), [](A* a) {\n" 2435 " delete a;\n" 2436 " });\n" 2437 "}"; 2438 const char exp[] = "class A { } ; " 2439 "static void func ( ) { " 2440 "std :: unique_ptr < A , std :: function < void ( A * ) > > tmp ( new A ( ) , [ ] ( A * a ) { " 2441 "delete a ; " 2442 "} ) ; " 2443 "}"; 2444 ASSERT_EQUALS(exp, tok(code)); 2445 } 2446 template99()2447 void template99() { // #8960 2448 const char code[] = "template <typename T>\n" 2449 "class Base {\n" 2450 "public:\n" 2451 " using ArrayType = std::vector<Base<T>>;\n" 2452 "};\n" 2453 "using A = Base<int>;\n" 2454 "static A::ArrayType array;\n"; 2455 const char exp[] = "class Base<int> ; " 2456 "static std :: vector < Base<int> > array ; " 2457 "class Base<int> { " 2458 "public: " 2459 "} ;"; 2460 2461 ASSERT_EQUALS(exp, tok(code)); 2462 } 2463 template100()2464 void template100() { // #8967 2465 const char code[] = "enum class Device { I2C0, I2C1 };\n" 2466 "template <Device D>\n" 2467 "const char* deviceFile;\n" 2468 "template <>\n" 2469 "const char* deviceFile<Device::I2C0> = \"/tmp/i2c-0\";\n"; 2470 2471 const char exp[] = "enum class Device { I2C0 , I2C1 } ; " 2472 "template < Device D > " 2473 "const char * deviceFile ; " 2474 "const char * deviceFile<Device::I2C0> ; deviceFile<Device::I2C0> = \"/tmp/i2c-0\" ;"; 2475 2476 ASSERT_EQUALS(exp, tok(code)); 2477 } 2478 template101()2479 void template101() { // #8968 2480 const char code[] = "class A {\n" 2481 "public:\n" 2482 " using ArrayType = std::vector<int>;\n" 2483 " void func(typename ArrayType::size_type i) {\n" 2484 " }\n" 2485 "};"; 2486 2487 const char exp[] = "class A { " 2488 "public: " 2489 "void func ( std :: vector < int > :: size_type i ) { " 2490 "} " 2491 "} ;"; 2492 2493 ASSERT_EQUALS(exp, tok(code)); 2494 ASSERT_EQUALS("", errout.str()); 2495 } 2496 template102()2497 void template102() { // #9005 2498 const char code[] = "namespace ns {\n" 2499 "template <class T>\n" 2500 "struct is_floating_point\n" 2501 ": std::integral_constant<bool, std::is_floating_point<T>::value || true>\n" 2502 "{};\n" 2503 "}\n" 2504 "void f() {\n" 2505 " if(std::is_floating_point<float>::value) {}\n" 2506 "}"; 2507 const char exp[] = "namespace ns { " 2508 "template < class T > " 2509 "struct is_floating_point " 2510 ": std :: integral_constant < bool , std :: is_floating_point < T > :: value || true > " 2511 "{ } ; " 2512 "} " 2513 "void f ( ) { " 2514 "if ( std :: is_floating_point < float > :: value ) { } " 2515 "}"; 2516 ASSERT_EQUALS(exp, tok(code)); 2517 } 2518 template103()2519 void template103() { 2520 const char code[] = "namespace sample {\n" 2521 " template <typename T>\n" 2522 " class Sample {\n" 2523 " public:\n" 2524 " T function(T t);\n" 2525 " };\n" 2526 " template <typename T>\n" 2527 " T Sample<T>::function(T t) {\n" 2528 " return t;\n" 2529 " }\n" 2530 "}\n" 2531 "sample::Sample<int> s1;"; 2532 const char exp[] = "namespace sample { " 2533 "class Sample<int> ; " 2534 "} " 2535 "sample :: Sample<int> s1 ; " 2536 "class sample :: Sample<int> { " 2537 "public: " 2538 "int function ( int t ) ; " 2539 "} ; " 2540 "int sample :: Sample<int> :: function ( int t ) { " 2541 "return t ; " 2542 "}"; 2543 ASSERT_EQUALS(exp, tok(code)); 2544 } 2545 template104()2546 void template104() { // #9021 2547 const char code[] = "template < int i >\n" 2548 "auto key ( ) { return hana :: test :: ct_eq < i > { } ; }\n" 2549 "template < int i >\n" 2550 "auto val ( ) { return hana :: test :: ct_eq < - i > { } ; }\n" 2551 "template < int i , int j >\n" 2552 "auto p ( ) { return :: minimal_product ( key < i > ( ) , val < j > ( ) ) ; }\n" 2553 "int main ( ) {\n" 2554 " BOOST_HANA_CONSTANT_CHECK ( hana :: equal (\n" 2555 " hana :: at_key ( hana :: make_map ( p < 0 , 0 > ( ) ) , key < 0 > ( ) ) ,\n" 2556 " val < 0 > ( ) ) ) ;\n" 2557 "}"; 2558 const char exp[] = "auto key<0> ( ) ; " 2559 "auto val<0> ( ) ; " 2560 "auto p<0,0> ( ) ; " 2561 "int main ( ) { " 2562 "BOOST_HANA_CONSTANT_CHECK ( hana :: equal ( " 2563 "hana :: at_key ( hana :: make_map ( p<0,0> ( ) ) , key<0> ( ) ) , " 2564 "val<0> ( ) ) ) ; " 2565 "} " 2566 "auto p<0,0> ( ) { return :: minimal_product ( key<0> ( ) , val<0> ( ) ) ; } " 2567 "auto val<0> ( ) { return hana :: test :: ct_eq < - 0 > { } ; } " 2568 "auto key<0> ( ) { return hana :: test :: ct_eq < 0 > { } ; }"; 2569 ASSERT_EQUALS(exp, tok(code)); 2570 } 2571 template105()2572 void template105() { // #9076 2573 const char code[] = "template <template <typename> class TOUT> class ObjectCache;\n" 2574 "template <template <typename> class TOUT>\n" 2575 "class ObjectCache { };\n" 2576 "template <typename T> class Fred {};\n" 2577 "ObjectCache<Fred> _cache;"; 2578 const char exp[] = "class ObjectCache<Fred> ; " 2579 "template < typename T > class Fred { } ; " 2580 "ObjectCache<Fred> _cache ; class ObjectCache<Fred> { } ;"; 2581 ASSERT_EQUALS(exp, tok(code)); 2582 } 2583 template106()2584 void template106() { 2585 const char code[] = "template<class T, class U> class A {\n" 2586 "public:\n" 2587 " int x;\n" 2588 "};\n" 2589 "template<template<class T, class U> class V> class B {\n" 2590 " V<char, char> i;\n" 2591 "};\n" 2592 "B<A> c;"; 2593 const char exp[] = "class A<char,char> ; " 2594 "class B<A> ; " 2595 "B<A> c ; " 2596 "class B<A> { " 2597 "A<char,char> i ; " 2598 "} ; class A<char,char> { " 2599 "public: " 2600 "int x ; " 2601 "} ;"; 2602 ASSERT_EQUALS(exp, tok(code)); 2603 } 2604 template107()2605 void template107() { // #8663 2606 const char code[] = "template <class T1, class T2>\n" 2607 "void f() {\n" 2608 " using T3 = typename T1::template T3<T2>;\n" 2609 " T3 t;\n" 2610 "}\n" 2611 "struct C3 {\n" 2612 " template <typename T>\n" 2613 " class T3\n" 2614 " {};\n" 2615 "};\n" 2616 "void foo() {\n" 2617 " f<C3, long>();\n" 2618 "}"; 2619 const char exp[] = "void f<C3,long> ( ) ; " 2620 "struct C3 { " 2621 "class T3<long> ; " 2622 "} ; " 2623 "void foo ( ) { " 2624 "f<C3,long> ( ) ; " 2625 "} " 2626 "void f<C3,long> ( ) { " 2627 "C3 :: T3<long> t ; " 2628 "} " 2629 "class C3 :: T3<long> { } ;"; 2630 ASSERT_EQUALS(exp, tok(code)); 2631 } 2632 template108()2633 void template108() { // #9109 2634 { 2635 const char code[] = "template <typename> struct a;\n" 2636 "template <typename> struct b {};\n" 2637 "template <typename> struct c;\n" 2638 "template <typename d> struct e {\n" 2639 " using f = a<b<typename c<d>::g>>;\n" 2640 " bool h = f::h;\n" 2641 "};\n" 2642 "struct i {\n" 2643 " e<int> j();\n" 2644 "};\n"; 2645 const char exp[] = "template < typename > struct a ; " 2646 "struct b<c<int>::g> ; " 2647 "template < typename > struct c ; " 2648 "struct e<int> ; " 2649 "struct i { e<int> j ( ) ; " 2650 "} ; " 2651 "struct e<int> { bool h ; " 2652 "h = a < b<c<int>::g> > :: h ; " 2653 "} ; " 2654 "struct b<c<int>::g> { } ;"; 2655 ASSERT_EQUALS(exp, tok(code)); 2656 } 2657 { 2658 const char code[] = "namespace {\n" 2659 "template <typename> struct a;\n" 2660 "template <typename> struct b {};\n" 2661 "}\n" 2662 "namespace {\n" 2663 "template <typename> struct c;\n" 2664 "template <typename d> struct e {\n" 2665 " using f = a<b<typename c<d>::g>>;\n" 2666 " bool h = f::h;\n" 2667 "};\n" 2668 "template <typename i> using j = typename e<i>::g;\n" 2669 "}"; 2670 const char exp[] = "namespace { " 2671 "template < typename > struct a ; " 2672 "template < typename > struct b { } ; " 2673 "} " 2674 "namespace { " 2675 "template < typename > struct c ; " 2676 "template < typename d > struct e { " 2677 "using f = a < b < c < d > :: g > > ; " 2678 "bool h ; h = f :: h ; " 2679 "} ; " 2680 "template < typename i > using j = typename e < i > :: g ; " 2681 "}"; 2682 ASSERT_EQUALS(exp, tok(code)); 2683 } 2684 { 2685 const char code[] = "namespace {\n" 2686 "template <typename> struct a;\n" 2687 "template <typename> struct b {};\n" 2688 "}\n" 2689 "namespace {\n" 2690 "template <typename> struct c;\n" 2691 "template <typename d> struct e {\n" 2692 " using f = a<b<typename c<d>::g>>;\n" 2693 " bool h = f::h;\n" 2694 "};\n" 2695 "template <typename i> using j = typename e<i>::g;\n" 2696 "}\n" 2697 "j<int> foo;"; 2698 const char exp[] = "namespace { " 2699 "template < typename > struct a ; " 2700 "struct b<c<int>::g> ; " 2701 "} " 2702 "namespace { " 2703 "template < typename > struct c ; " 2704 "struct e<int> ; " 2705 "} " 2706 "e<int> :: g foo ; " 2707 "struct e<int> { " 2708 "bool h ; h = a < b<c<int>::g> > :: h ; " 2709 "} ; " 2710 "struct b<c<int>::g> { } ;"; 2711 ASSERT_EQUALS(exp, tok(code)); 2712 } 2713 } 2714 template109()2715 void template109() { // #9144 2716 { 2717 const char code[] = "namespace a {\n" 2718 "template <typename b, bool = __is_empty(b) && __is_final(b)> struct c;\n" 2719 "}\n" 2720 "template <typename...> struct e {};\n" 2721 "static_assert(sizeof(e<>) == sizeof(e<c<int>, c<int>, int>), \"\");\n"; 2722 const char exp[] = "namespace a { " 2723 "template < typename b , bool > struct c ; " 2724 "} " 2725 "struct e<> ; " 2726 "struct e<c<int>,c<int>,int> ; " 2727 "static_assert ( sizeof ( e<> ) == sizeof ( e<c<int>,c<int>,int> ) , \"\" ) ; " 2728 "struct e<> { } ; " 2729 "struct e<c<int>,c<int>,int> { } ;"; 2730 ASSERT_EQUALS(exp, tok(code)); 2731 } 2732 { 2733 const char code[] = "namespace a {\n" 2734 "template <typename b, bool = __is_empty(b) && __is_final(b)> struct c;\n" 2735 "}\n" 2736 "template <typename...> struct e {};\n" 2737 "static_assert(sizeof(e<>) == sizeof(e<a::c<int>, a::c<int>, int>), \"\");\n"; 2738 const char exp[] = "namespace a { " 2739 "template < typename b , bool > struct c ; " 2740 "} " 2741 "struct e<> ; " 2742 "struct e<a::c<int,std::is_empty<int>{}&&std::is_final<int>{}>,a::c<int,std::is_empty<int>{}&&std::is_final<int>{}>,int> ; " 2743 "static_assert ( sizeof ( e<> ) == sizeof ( e<a::c<int,std::is_empty<int>{}&&std::is_final<int>{}>,a::c<int,std::is_empty<int>{}&&std::is_final<int>{}>,int> ) , \"\" ) ; " 2744 "struct e<> { } ; " 2745 "struct e<a::c<int,std::is_empty<int>{}&&std::is_final<int>{}>,a::c<int,std::is_empty<int>{}&&std::is_final<int>{}>,int> { } ;"; 2746 ASSERT_EQUALS(exp, tok(code)); 2747 } 2748 { 2749 const char code[] = "template <typename b, bool = __is_empty(b) && __is_final(b)> struct c;\n" 2750 "template <typename...> struct e {};\n" 2751 "static_assert(sizeof(e<>) == sizeof(e<c<int>, c<int>, int>), \"\");\n"; 2752 const char exp[] = "template < typename b , bool > struct c ; " 2753 "struct e<> ; " 2754 "struct e<c<int,std::is_empty<int>{}&&std::is_final<int>{}>,c<int,std::is_empty<int>{}&&std::is_final<int>{}>,int> ; " 2755 "static_assert ( sizeof ( e<> ) == sizeof ( e<c<int,std::is_empty<int>{}&&std::is_final<int>{}>,c<int,std::is_empty<int>{}&&std::is_final<int>{}>,int> ) , \"\" ) ; " 2756 "struct e<> { } ; " 2757 "struct e<c<int,std::is_empty<int>{}&&std::is_final<int>{}>,c<int,std::is_empty<int>{}&&std::is_final<int>{}>,int> { } ;"; 2758 ASSERT_EQUALS(exp, tok(code)); 2759 } 2760 { 2761 const char code[] = "template <typename b, bool = __is_empty(b) && __is_final(b)> struct c{};\n" 2762 "c<int> cc;\n"; 2763 const char exp[] = "struct c<int,std::is_empty<int>{}&&std::is_final<int>{}> ; " 2764 "c<int,std::is_empty<int>{}&&std::is_final<int>{}> cc ; " 2765 "struct c<int,std::is_empty<int>{}&&std::is_final<int>{}> { } ;"; 2766 ASSERT_EQUALS(exp, tok(code)); 2767 } 2768 { 2769 const char code[] = "template <typename b, bool = unknown1(b) && unknown2(b)> struct c{};\n" 2770 "c<int> cc;\n"; 2771 const char exp[] = "struct c<int,unknown1(int)&&unknown2(int)> ; " 2772 "c<int,unknown1(int)&&unknown2(int)> cc ; " 2773 "struct c<int,unknown1(int)&&unknown2(int)> { } ;"; 2774 ASSERT_EQUALS(exp, tok(code)); 2775 } 2776 } 2777 template110()2778 void template110() { 2779 const char code[] = "template<typename T> using A = int;\n" 2780 "template<typename T> using A<T*> = char;\n" 2781 "template<> using A<char> = char;\n" 2782 "template using A<char> = char;\n" 2783 "using A<char> = char;"; 2784 const char exp[] = "template < typename T > using A = int ; " 2785 "template < typename T > using A < T * > = char ; " 2786 "template < > using A < char > = char ; " 2787 "template using A < char > = char ; " 2788 "using A < char > = char ;"; 2789 ASSERT_EQUALS(exp, tok(code)); 2790 } 2791 template111()2792 void template111() { // crash 2793 const char code[] = "template<typename T, typename U> struct pair;\n" 2794 "template<typename T> using cell = pair<T*, cell<T>*>;"; 2795 const char exp[] = "template < typename T , typename U > struct pair ; " 2796 "template < typename T > using cell = pair < T * , cell < T > * > ;"; 2797 ASSERT_EQUALS(exp, tok(code)); 2798 } 2799 template112()2800 void template112() { // #9146 syntax error 2801 const char code[] = "template <int> struct a;\n" 2802 "template <class, class b> using c = typename a<int{b::d}>::e;\n" 2803 "template <class> struct f;\n" 2804 "template <class b> using g = typename f<c<int, b>>::e;"; 2805 const char exp[] = "template < int > struct a ; " 2806 "template < class , class b > using c = typename a < int { b :: d } > :: e ; " 2807 "template < class > struct f ; " 2808 "template < class b > using g = typename f < c < int , b > > :: e ;"; 2809 ASSERT_EQUALS(exp, tok(code)); 2810 } 2811 template113()2812 void template113() { 2813 { 2814 const char code[] = "template <class> class A { void f(); };\n" 2815 "A<int> a;"; 2816 const char exp[] = "class A<int> ; " 2817 "A<int> a ; " 2818 "class A<int> { void f ( ) ; } ;"; 2819 ASSERT_EQUALS(exp, tok(code)); 2820 } 2821 { 2822 const char code[] = "template <struct> struct A { void f(); };\n" 2823 "A<int> a;"; 2824 const char exp[] = "struct A<int> ; " 2825 "A<int> a ; " 2826 "struct A<int> { void f ( ) ; } ;"; 2827 ASSERT_EQUALS(exp, tok(code)); 2828 } 2829 } 2830 template114()2831 void template114() { // #9155 2832 { 2833 const char code[] = "template <typename a, a> struct b {};\n" 2834 "template <typename> struct c;\n" 2835 "template <typename> struct d : b<bool, std::is_polymorphic<int>{}> {};\n" 2836 "template <bool> struct e;\n" 2837 "template <typename a> using f = typename e<c<d<a>>::g>::h;"; 2838 const char exp[] = "template < typename a , a > struct b { } ; " 2839 "template < typename > struct c ; " 2840 "template < typename > struct d : b < bool , std :: is_polymorphic < int > { } > { } ; " 2841 "template < bool > struct e ; " 2842 "template < typename a > using f = typename e < c < d < a > > :: g > :: h ;"; 2843 ASSERT_EQUALS(exp, tok(code)); 2844 } 2845 { 2846 const char code[] = "template <typename a, a> struct b;\n" 2847 "template <bool, typename> struct c;\n" 2848 "template <typename a> struct d : b<bool, std::is_empty<a>{}> {};\n" 2849 "template <typename a> using e = typename c<std::is_final<a>{}, d<a>>::f;\n"; 2850 const char exp[] = "template < typename a , a > struct b ; " 2851 "template < bool , typename > struct c ; " 2852 "template < typename a > struct d : b < bool , std :: is_empty < a > { } > { } ; " 2853 "template < typename a > using e = typename c < std :: is_final < a > { } , d < a > > :: f ;"; 2854 ASSERT_EQUALS(exp, tok(code)); 2855 } 2856 } 2857 template115()2858 void template115() { // #9153 2859 const char code[] = "namespace {\n" 2860 " namespace b {\n" 2861 " template <int c> struct B { using B<c / 2>::d; };\n" 2862 " }\n" 2863 " template <class, class> using e = typename b::B<int{}>;\n" 2864 " namespace b {\n" 2865 " template <class> struct f {};\n" 2866 " }\n" 2867 " template <class c> using g = b::f<e<int, c>>;\n" 2868 "}\n" 2869 "g<int> g1;"; 2870 const char exp[] = "namespace { " 2871 "namespace b { " 2872 "struct B<0> ; " 2873 "} " 2874 "namespace b { " 2875 "struct f<b::B<0>> ; " 2876 "} " 2877 "} " 2878 "b :: f<b::B<0>> g1 ; struct b :: B<0> { using B<0> :: d ; } ; " 2879 "struct b :: f<b::B<0>> { } ;"; 2880 ASSERT_EQUALS(exp, tok(code)); 2881 } 2882 template116()2883 void template116() { // #9178 2884 { 2885 const char code[] = "template <class, class a> auto b() -> decltype(a{}.template b<void(int, int)>);\n" 2886 "template <class, class a> auto b() -> decltype(a{}.template b<void(int, int)>){}"; 2887 const char exp[] = "template < class , class a > auto b ( ) . decltype ( a { } . template b < void ( int , int ) > ) ; " 2888 "template < class , class a > auto b ( ) . decltype ( a { } . template b < void ( int , int ) > ) { }"; 2889 ASSERT_EQUALS(exp, tok(code)); 2890 } 2891 { 2892 const char code[] = "template <class, class a>\n" 2893 "auto b() -> decltype(a{}.template b<void(int, int)>()) {}\n" 2894 "struct c {\n" 2895 " template <class> void b();\n" 2896 "};\n" 2897 "void d() { b<c, c>(); }"; 2898 const char exp[] = "auto b<c,c> ( ) . decltype ( c { } . template b < void ( int , int ) > ( ) ) ; " 2899 "struct c { " 2900 "template < class > void b ( ) ; " 2901 "} ; " 2902 "void d ( ) { b<c,c> ( ) ; } " 2903 "auto b<c,c> ( ) . decltype ( c { } . template b < void ( int , int ) > ( ) ) { }"; 2904 ASSERT_EQUALS(exp, tok(code)); 2905 } 2906 } 2907 template117()2908 void template117() { 2909 const char code[] = "template<typename T = void> struct X {};\n" 2910 "X<X<>> x;"; 2911 const char exp[] = "struct X<void> ; " 2912 "struct X<X<void>> ; " 2913 "X<X<void>> x ; " 2914 "struct X<void> { } ; " 2915 "struct X<X<void>> { } ;"; 2916 ASSERT_EQUALS(exp, tok(code)); 2917 } 2918 template118()2919 void template118() { 2920 const char code[] = "template<int> struct S { void f(int i); };\n" 2921 "S<1> s;"; 2922 const char exp[] = "struct S<1> ; " 2923 "S<1> s ; struct S<1> { " 2924 "void f ( int i ) ; " 2925 "} ;"; 2926 ASSERT_EQUALS(exp, tok(code)); 2927 } 2928 template119()2929 void template119() { // #9186 2930 { 2931 const char code[] = "template <typename T>\n" 2932 "constexpr auto func = [](auto x){ return T(x);};\n" 2933 "template <typename T>\n" 2934 "constexpr auto funcBraced = [](auto x){ return T{x};};\n" 2935 "double f(int x) { return func<double>(x); }\n" 2936 "double fBraced(int x) { return funcBraced<int>(x); }"; 2937 const char exp[] = "constexpr auto func<double> = [ ] ( auto x ) { return double ( x ) ; } ; " 2938 "constexpr auto funcBraced<int> = [ ] ( auto x ) { return int { x } ; } ; " 2939 "double f ( int x ) { return func<double> ( x ) ; } " 2940 "double fBraced ( int x ) { return funcBraced<int> ( x ) ; }"; 2941 ASSERT_EQUALS(exp, tok(code)); 2942 } 2943 { 2944 const char code[] = "template <typename T>\n" 2945 "constexpr auto func = [](auto x){ return T(x);};\n" 2946 "void foo() {\n" 2947 " func<int>(x);\n" 2948 " func<double>(x);\n" 2949 "}"; 2950 const char exp[] = "constexpr auto func<int> = [ ] ( auto x ) { return int ( x ) ; } ; " 2951 "constexpr auto func<double> = [ ] ( auto x ) { return double ( x ) ; } ; " 2952 "void foo ( ) { " 2953 "func<int> ( x ) ; " 2954 "func<double> ( x ) ; " 2955 "}"; 2956 ASSERT_EQUALS(exp, tok(code)); 2957 } 2958 } 2959 template120()2960 void template120() { 2961 const char code[] = "template<typename Tuple>\n" 2962 "struct lambda_context {\n" 2963 " template<typename Sig> struct result;\n" 2964 " template<typename This, typename I>\n" 2965 " struct result<This(terminal, placeholder)> : at<Tuple, I> {};\n" 2966 "};\n" 2967 "template<typename T>\n" 2968 "struct lambda {\n" 2969 " template<typename Sig> struct result;\n" 2970 " template<typename This>\n" 2971 " struct result<This()> : lambda_context<tuple<> > {};\n" 2972 "};\n" 2973 "lambda<int> l;"; 2974 const char exp[] = "template < typename Tuple > " 2975 "struct lambda_context { " 2976 "template < typename Sig > struct result ; " 2977 "template < typename This , typename I > " 2978 "struct result < This ( terminal , placeholder ) > : at < Tuple , I > { } ; " 2979 "} ; " 2980 "struct lambda<int> ; " 2981 "lambda<int> l ; struct lambda<int> { " 2982 "template < typename Sig > struct result ; " 2983 "template < typename This > " 2984 "struct result < This ( ) > : lambda_context < tuple < > > { } ; " 2985 "} ;"; 2986 ASSERT_EQUALS(exp, tok(code)); 2987 } 2988 template121()2989 void template121() { // #9193 2990 const char code[] = "template <class VALUE_T, class LIST_T = std::list<VALUE_T>>\n" 2991 "class TestList { };\n" 2992 "TestList<std::shared_ptr<int>> m_test;"; 2993 const char exp[] = "class TestList<std::shared_ptr<int>,std::list<std::shared_ptr<int>>> ; " 2994 "TestList<std::shared_ptr<int>,std::list<std::shared_ptr<int>>> m_test ; " 2995 "class TestList<std::shared_ptr<int>,std::list<std::shared_ptr<int>>> { } ;"; 2996 ASSERT_EQUALS(exp, tok(code)); 2997 } 2998 template122()2999 void template122() { // #9147 3000 const char code[] = "template <class...> struct a;\n" 3001 "namespace {\n" 3002 "template <class, class> struct b;\n" 3003 "template <template <class> class c, class... f, template <class...> class d>\n" 3004 "struct b<c<f...>, d<>>;\n" 3005 "}\n" 3006 "void e() { using c = a<>; }"; 3007 const char exp[] = "template < class ... > struct a ; " 3008 "namespace { " 3009 "template < class , class > struct b ; " 3010 "template < template < class > class c , class ... f , template < class ... > class d > " 3011 "struct b < c < f ... > , d < > > ; " 3012 "} " 3013 "void e ( ) { }"; 3014 ASSERT_EQUALS(exp, tok(code)); 3015 } 3016 template123()3017 void template123() { // #9183 3018 const char code[] = "template <class...> struct a;\n" 3019 "namespace {\n" 3020 "template <class, class, class, class>\n" 3021 "struct b;\n" 3022 "template <template <class> class c, class... d, template <class> class e, class... f>\n" 3023 "struct b<c<d...>, e<f...>>;\n" 3024 "}\n" 3025 "void fn1() {\n" 3026 " using c = a<>;\n" 3027 " using e = a<>;\n" 3028 "}"; 3029 const char exp[] = "template < class ... > struct a ; " 3030 "namespace { " 3031 "template < class , class , class , class > " 3032 "struct b ; " 3033 "template < template < class > class c , class ... d , template < class > class e , class ... f > " 3034 "struct b < c < d ... > , e < f ... > > ; " 3035 "} " 3036 "void fn1 ( ) { " 3037 "}"; 3038 ASSERT_EQUALS(exp, tok(code)); 3039 } 3040 template124()3041 void template124() { // #9197 3042 const char code[] = "template <bool> struct a;\n" 3043 "template <bool b> using c = typename a<b>::d;\n" 3044 "template <typename> struct e;\n" 3045 "template <typename> struct h {\n" 3046 " template <typename... f, c<h<e<typename f::d...>>::g>> void i();\n" 3047 "};"; 3048 const char exp[] = "template < bool > struct a ; " 3049 "template < bool b > using c = typename a < b > :: d ; " 3050 "template < typename > struct e ; " 3051 "template < typename > struct h { " 3052 "template < typename ... f , c < h < e < typename f :: d ... > > :: g > > void i ( ) ; " 3053 "} ;"; 3054 ASSERT_EQUALS(exp, tok(code)); 3055 } 3056 template125()3057 void template125() { 3058 ASSERT_THROW(tok("template<int M, int N>\n" 3059 "class GCD {\n" 3060 "public:\n" 3061 " enum { val = (N == 0) ? M : GCD<N, M % N>::val };\n" 3062 "};\n" 3063 "int main() {\n" 3064 " GCD< 1, 0 >::val;\n" 3065 "}"), InternalError); 3066 } 3067 template126()3068 void template126() { // #9217 3069 const char code[] = "template <typename b> using d = a<b>;\n" 3070 "static_assert(i<d<l<b>>>{}, \"\");"; 3071 const char exp[] = "static_assert ( i < a < l < b > > > { } , \"\" ) ;"; 3072 ASSERT_EQUALS(exp, tok(code)); 3073 } 3074 template127()3075 void template127() { // #9225 3076 { 3077 const char code[] = "template <typename> struct a {\n" 3078 " template <typename b> constexpr decltype(auto) operator()(b &&) const;\n" 3079 "};\n" 3080 "a<int> c;\n" 3081 "template <typename d>\n" 3082 "template <typename b>\n" 3083 "constexpr decltype(auto) a<d>::operator()(b &&) const {}"; 3084 const char exp[] = "struct a<int> ; " 3085 "a<int> c ; " 3086 "template < typename d > " 3087 "template < typename b > " 3088 "constexpr decltype ( auto ) a < d > :: operator() ( b && ) const { } " 3089 "struct a<int> { " 3090 "template < typename b > constexpr decltype ( auto ) operator() ( b && ) const ; " 3091 "} ;"; 3092 const char act[] = "struct a<int> ; " 3093 "a<int> c ; " 3094 "template < typename d > " 3095 "template < typename b > " 3096 "constexpr decltype ( auto ) a < d > :: operator() ( b && ) const { } " 3097 "struct a<int> { " 3098 "template < typename b > constexpr decltype ( auto ) operator() ( b && ) const ; " 3099 "} ; " 3100 "constexpr decltype ( auto ) a<int> :: operator() ( b && ) const { }"; 3101 TODO_ASSERT_EQUALS(exp, act, tok(code)); 3102 } 3103 { 3104 const char code[] = "template <typename> struct a {\n" 3105 " template <typename b> static void foo();\n" 3106 "};\n" 3107 "a<int> c;\n" 3108 "template <typename d>\n" 3109 "template <typename b>\n" 3110 "void a<d>::foo() {}\n" 3111 "void bar() { a<int>::foo<char>(); }"; 3112 const char exp[] = "struct a<int> ; " 3113 "a<int> c ; " 3114 "template < typename d > " 3115 "template < typename b > " 3116 "void a < d > :: foo ( ) { } " 3117 "void bar ( ) { a<int> :: foo < char > ( ) ; } " 3118 "struct a<int> { " 3119 "template < typename b > static void foo ( ) ; " 3120 "static void foo<char> ( ) ; " 3121 "} ; " 3122 "void a<int> :: foo<char> ( ) { }"; 3123 const char act[] = "struct a<int> ; " 3124 "a<int> c ; " 3125 "template < typename d > " 3126 "template < typename b > " 3127 "void a < d > :: foo ( ) { } " 3128 "void bar ( ) { a<int> :: foo < char > ( ) ; } " 3129 "struct a<int> { " 3130 "template < typename b > static void foo ( ) ; " 3131 "} ; " 3132 "void a<int> :: foo ( ) { }"; 3133 TODO_ASSERT_EQUALS(exp, act, tok(code)); 3134 } 3135 { 3136 const char code[] = "template <typename> struct a {\n" 3137 " template <typename b> static void foo();\n" 3138 "};\n" 3139 "template <typename d>\n" 3140 "template <typename b>\n" 3141 "void a<d>::foo() {}\n" 3142 "void bar() { a<int>::foo<char>(); }"; 3143 const char exp[] = "struct a<int> ; " 3144 "template < typename d > " 3145 "template < typename b > " 3146 "void a < d > :: foo ( ) { } " 3147 "void bar ( ) { a<int> :: foo < char > ( ) ; } " 3148 "struct a<int> { " 3149 "static void foo<char> ( ) ; " 3150 "} ; " 3151 "void a<int> :: foo<char> ( ) { }"; 3152 const char act[] = "struct a<int> ; " 3153 "template < typename d > " 3154 "template < typename b > " 3155 "void a < d > :: foo ( ) { } " 3156 "void bar ( ) { a<int> :: foo < char > ( ) ; } " 3157 "struct a<int> { " 3158 "template < typename b > static void foo ( ) ; " 3159 "} ; " 3160 "void a<int> :: foo ( ) { }"; 3161 TODO_ASSERT_EQUALS(exp, act, tok(code)); 3162 } 3163 } 3164 template128()3165 void template128() { // #9224 3166 const char code[] = "template <typename> struct a { };\n" 3167 "template <typename j> void h() { k.h<a<j>>; }\n" 3168 "void foo() { h<int>(); }"; 3169 const char exp[] = "struct a<int> ; " 3170 "void h<int> ( ) ; " 3171 "void foo ( ) { h<int> ( ) ; } " 3172 "void h<int> ( ) { k . h < a<int> > ; } " 3173 "struct a<int> { } ;"; 3174 ASSERT_EQUALS(exp, tok(code)); 3175 } 3176 template129()3177 void template129() { 3178 const char code[] = "class LuaContext {\n" 3179 "public:\n" 3180 " template <typename TFunctionType, typename TType>\n" 3181 " void registerFunction(TType fn) { }\n" 3182 "};\n" 3183 "void setupLuaBindingsDNSQuestion() {\n" 3184 " g_lua.registerFunction<void (DNSQuestion ::*)(std ::string, std ::string)>();\n" 3185 "}"; 3186 const char exp[] = "class LuaContext { " 3187 "public: " 3188 "template < typename TFunctionType , typename TType > " 3189 "void registerFunction ( TType fn ) { } " 3190 "} ; " 3191 "void setupLuaBindingsDNSQuestion ( ) { " 3192 "g_lua . registerFunction < void ( DNSQuestion :: * ) ( std :: string , std :: string ) > ( ) ; " 3193 "}"; 3194 ASSERT_EQUALS(exp, tok(code)); 3195 } 3196 template130()3197 void template130() { // #9246 3198 const char code[] = "template <typename...> using a = int;\n" 3199 "template <typename, typename> using b = a<>;\n" 3200 "template <typename, typename> void c();\n" 3201 "template <typename d, typename> void e() { c<b<d, int>, int>; }\n" 3202 "void f() { e<int(int, ...), int>(); }"; 3203 const char exp[] = "template < typename , typename > void c ( ) ; " 3204 "void e<int(int,...),int> ( ) ; " 3205 "void f ( ) { e<int(int,...),int> ( ) ; } " 3206 "void e<int(int,...),int> ( ) { c < int , int > ; }"; 3207 ASSERT_EQUALS(exp, tok(code)); 3208 } 3209 template131()3210 void template131() { // #9249 3211 { 3212 const char code[] = "template <long a, bool = 0 == a> struct b {};\n" 3213 "b<1> b1;"; 3214 const char exp[] = "struct b<1,false> ; " 3215 "b<1,false> b1 ; " 3216 "struct b<1,false> { } ;"; 3217 ASSERT_EQUALS(exp, tok(code)); 3218 } 3219 { 3220 const char code[] = "template <long a, bool = 0 != a> struct b {};\n" 3221 "b<1> b1;"; 3222 const char exp[] = "struct b<1,true> ; " 3223 "b<1,true> b1 ; " 3224 "struct b<1,true> { } ;"; 3225 ASSERT_EQUALS(exp, tok(code)); 3226 } 3227 { 3228 const char code[] = "template <long a, bool = a < 0> struct b {};\n" 3229 "b<1> b1;"; 3230 const char exp[] = "struct b<1,false> ; " 3231 "b<1,false> b1 ; " 3232 "struct b<1,false> { } ;"; 3233 ASSERT_EQUALS(exp, tok(code)); 3234 } 3235 { 3236 const char code[] = "template <long a, bool = 0 < a> struct b {};\n" 3237 "b<1> b1;"; 3238 const char exp[] = "struct b<1,true> ; " 3239 "b<1,true> b1 ; " 3240 "struct b<1,true> { } ;"; 3241 ASSERT_EQUALS(exp, tok(code)); 3242 } 3243 { 3244 const char code[] = "template <long a, bool = 0 <= a> struct b {};\n" 3245 "b<1> b1;"; 3246 const char exp[] = "struct b<1,true> ; " 3247 "b<1,true> b1 ; " 3248 "struct b<1,true> { } ;"; 3249 ASSERT_EQUALS(exp, tok(code)); 3250 } 3251 { 3252 const char code[] = "template <long a, bool = a >= 0> struct b {};\n" 3253 "b<1> b1;"; 3254 const char exp[] = "struct b<1,true> ; " 3255 "b<1,true> b1 ; " 3256 "struct b<1,true> { } ;"; 3257 ASSERT_EQUALS(exp, tok(code)); 3258 } 3259 } 3260 template132()3261 void template132() { // #9250 3262 const char code[] = "struct TrueFalse {\n" 3263 " static constexpr bool v() { return true; }\n" 3264 "};\n" 3265 "int global;\n" 3266 "template<typename T> int foo() {\n" 3267 " __transaction_atomic noexcept(T::v()) { global += 1; }\n" 3268 " return __transaction_atomic noexcept(T::v()) (global + 2);\n" 3269 "}\n" 3270 "int f1() {\n" 3271 " return foo<TrueFalse>();\n" 3272 "}"; 3273 const char exp[] = "struct TrueFalse { " 3274 "static constexpr bool v ( ) { return true ; } " 3275 "} ; " 3276 "int global ; " 3277 "int foo<TrueFalse> ( ) ; " 3278 "int f1 ( ) { " 3279 "return foo<TrueFalse> ( ) ; " 3280 "} " 3281 "int foo<TrueFalse> ( ) { " 3282 "__transaction_atomic noexcept ( TrueFalse :: v ( ) ) { global += 1 ; } " 3283 "return __transaction_atomic noexcept ( TrueFalse :: v ( ) ) ( global + 2 ) ; " 3284 "}"; 3285 ASSERT_EQUALS(exp, tok(code)); 3286 } 3287 template133()3288 void template133() { 3289 const char code[] = "template <typename a> struct bar {\n" 3290 " template <typename b> static bar foo(const bar<b> &c) {\n" 3291 " return bar();\n" 3292 " }\n" 3293 "};\n" 3294 "bar<short> bs;\n" 3295 "bar<std::array<int,4>> ba;\n" 3296 "bar<short> b1 = bar<short>::foo<std::array<int,4>>(ba);\n" 3297 "bar<std::array<int,4>> b2 = bar<std::array<int,4>>::foo<short>(bs);"; 3298 const char act[] = "struct bar<short> ; struct bar<std::array<int,4>> ; " 3299 "bar<short> bs ; " 3300 "bar<std::array<int,4>> ba ; " 3301 "bar<short> b1 ; b1 = bar<short> :: foo<std::array<int,4>> ( ba ) ; " 3302 "bar<std::array<int,4>> b2 ; b2 = bar<std::array<int,4>> :: foo<short> ( bs ) ; " 3303 "struct bar<short> { " 3304 "static bar<short> foo<std::array<int,4>> ( const bar < std :: array < int , 4 > > & c ) ; " 3305 "} ; " 3306 "struct bar<std::array<int,4>> { " 3307 "static bar<std::array<int,4>> foo<short> ( const bar < short > & c ) ; " 3308 "} ; " 3309 "bar<std::array<int,4>> bar<std::array<int,4>> :: foo<short> ( const bar < short > & c ) { " 3310 "return bar<std::array<int,4>> ( ) ; " 3311 "} " 3312 "bar<short> bar<short> :: foo<std::array<int,4>> ( const bar < std :: array < int , 4 > > & c ) { " 3313 "return bar<short> ( ) ; " 3314 "}"; 3315 const char exp[] = "struct bar<short> ; struct bar<std::array<int,4>> ; " 3316 "bar<short> bs ; " 3317 "bar<std::array<int,4>> ba ; " 3318 "bar<short> b1 ; b1 = bar<short> :: foo<std::array<int,4>> ( ba ) ; " 3319 "bar<std::array<int,4>> b2 ; b2 = bar<std::array<int,4>> :: foo<short> ( bs ) ; " 3320 "struct bar<short> { " 3321 "static bar<short> foo<std::array<int,4>> ( const bar<std::array<int,4>> & c ) ; " 3322 "} ; " 3323 "struct bar<std::array<int,4>> { " 3324 "static bar<std::array<int,4>> foo<short> ( const bar<short> & c ) ; " 3325 "} ; " 3326 "bar<std::array<int,4>> bar<std::array<int,4>> :: foo<short> ( const bar<short> & c ) { " 3327 "return bar<std::array<int,4>> ( ) ; " 3328 "} " 3329 "bar<short> bar<short> :: foo<std::array<int,4>> ( const bar<std::array<int,4>> & c ) { " 3330 "return bar<short> ( ) ; " 3331 "}"; 3332 TODO_ASSERT_EQUALS(exp, act, tok(code)); 3333 } 3334 template134()3335 void template134() { 3336 const char code[] = "template <int a> class e { };\n" 3337 "template <int a> class b { e<(c > a ? 1 : 0)> d; };\n" 3338 "b<0> b0;\n" 3339 "b<1> b1;"; 3340 const char exp[] = "class e<(c>0)> ; class e<(c>1)> ; " 3341 "class b<0> ; class b<1> ; " 3342 "b<0> b0 ; " 3343 "b<1> b1 ; " 3344 "class b<0> { e<(c>0)> d ; } ; class b<1> { e<(c>1)> d ; } ; " 3345 "class e<(c>0)> { } ; class e<(c>1)> { } ;"; 3346 ASSERT_EQUALS(exp, tok(code)); 3347 } 3348 template135()3349 void template135() { 3350 const char code[] = "template <int> struct a { template <int b> void c(a<b>); };\n" 3351 "a<2> d;"; 3352 const char exp[] = "struct a<2> ; " 3353 "a<2> d ; " 3354 "struct a<2> { template < int b > void c ( a < b > ) ; } ;"; 3355 ASSERT_EQUALS(exp, tok(code)); 3356 } 3357 template136()3358 void template136() { // #9287 3359 const char code[] = "namespace a {\n" 3360 "template <typename> struct b;\n" 3361 "template <int> struct c;\n" 3362 "template <typename> struct d;\n" 3363 "template <typename> struct f;\n" 3364 "template <typename> struct g;\n" 3365 "template <typename h>\n" 3366 "struct i : c<b<f<typename h ::j>>::k && b<g<typename h ::j>>::k> {};\n" 3367 "}\n" 3368 "namespace hana = a;\n" 3369 "using e = int;\n" 3370 "void l(hana::d<hana::i<e>>);"; 3371 const char exp[] = "namespace a { " 3372 "template < typename > struct b ; " 3373 "template < int > struct c ; " 3374 "template < typename > struct d ; " 3375 "template < typename > struct f ; " 3376 "template < typename > struct g ; " 3377 "struct i<int> ; " 3378 "} " 3379 "void l ( a :: d < a :: i<int> > ) ; " 3380 "struct a :: i<int> : c < b < f < int :: j > > :: k && b < g < int :: j > > :: k > { } ;"; 3381 ASSERT_EQUALS(exp, tok(code)); 3382 } 3383 template137()3384 void template137() { // #9288 3385 const char code[] = "template <bool> struct a;\n" 3386 "template <bool b, class> using c = typename a<b>::d;\n" 3387 "template <class, template <class> class, class> struct e;\n" 3388 "template <class f, class g, class... h>\n" 3389 "using i = typename e<f, g::template fn, h...>::d;\n" 3390 "template <class... j> struct k : c<sizeof...(j), int>::template fn<j...> {};"; 3391 const char exp[] = "template < bool > struct a ; " 3392 "template < bool b , class > using c = typename a < b > :: d ; " 3393 "template < class , template < class > class , class > struct e ; " 3394 "template < class f , class g , class ... h > " 3395 "using i = typename e < f , g :: fn , h ... > :: d ; " 3396 "template < class ... j > struct k : c < sizeof... ( j ) , int > :: fn < j ... > { } ;"; 3397 ASSERT_EQUALS(exp, tok(code)); 3398 } 3399 template138()3400 void template138() { 3401 { 3402 const char code[] = "struct inferior {\n" 3403 " using visitor = int;\n" 3404 " template <typename T>\n" 3405 " bool operator()(const T &a, const T &b) const {\n" 3406 " return 1 < b;\n" 3407 " }\n" 3408 "};\n" 3409 "int main() {\n" 3410 " return 0;\n" 3411 "}"; 3412 const char exp[] = "struct inferior { " 3413 "template < typename T > " 3414 "bool operator() ( const T & a , const T & b ) const { " 3415 "return 1 < b ; " 3416 "} " 3417 "} ; " 3418 "int main ( ) { " 3419 "return 0 ; " 3420 "}"; 3421 ASSERT_EQUALS(exp, tok(code)); 3422 } 3423 { 3424 const char code[] = "struct inferior {\n" 3425 " template <typename T>\n" 3426 " bool operator()(const T &a, const T &b) const {\n" 3427 " return 1 < b;\n" 3428 " }\n" 3429 "};\n" 3430 "int main() {\n" 3431 " return 0;\n" 3432 "}"; 3433 const char exp[] = "struct inferior { " 3434 "template < typename T > " 3435 "bool operator() ( const T & a , const T & b ) const { " 3436 "return 1 < b ; " 3437 "} " 3438 "} ; " 3439 "int main ( ) { " 3440 "return 0 ; " 3441 "}"; 3442 ASSERT_EQUALS(exp, tok(code)); 3443 } 3444 { 3445 const char code[] = "struct inferior {\n" 3446 " using visitor = int;\n" 3447 " template <typename T>\n" 3448 " bool operator()(const T &a, const T &b) const {\n" 3449 " return a < b;\n" 3450 " }\n" 3451 "};\n" 3452 "int main() {\n" 3453 " return 0;\n" 3454 "}"; 3455 const char exp[] = "struct inferior { " 3456 "template < typename T > " 3457 "bool operator() ( const T & a , const T & b ) const { " 3458 "return a < b ; " 3459 "} " 3460 "} ; " 3461 "int main ( ) { " 3462 "return 0 ; " 3463 "}"; 3464 ASSERT_EQUALS(exp, tok(code)); 3465 } 3466 { 3467 const char code[] = "struct inferior {\n" 3468 " template <typename T>\n" 3469 " bool operator()(const T &a, const T &b) const {\n" 3470 " return a < b;\n" 3471 " }\n" 3472 "};\n" 3473 "int main() {\n" 3474 " return 0;\n" 3475 "}"; 3476 const char exp[] = "struct inferior { " 3477 "template < typename T > " 3478 "bool operator() ( const T & a , const T & b ) const { " 3479 "return a < b ; " 3480 "} " 3481 "} ; " 3482 "int main ( ) { " 3483 "return 0 ; " 3484 "}"; 3485 ASSERT_EQUALS(exp, tok(code)); 3486 } 3487 } 3488 template139()3489 void template139() { 3490 { 3491 const char code[] = "template<typename T>\n" 3492 "struct Foo {\n" 3493 " template<typename> friend struct Foo;\n" 3494 "};"; 3495 const char exp[] = "template < typename T > " 3496 "struct Foo { " 3497 "template < typename > friend struct Foo ; " 3498 "} ;"; 3499 ASSERT_EQUALS(exp, tok(code)); 3500 } 3501 { 3502 const char code[] = "template<typename T>\n" 3503 "struct Foo {\n" 3504 " template<typename> friend struct Foo;\n" 3505 "} ;\n" 3506 "Foo<int> foo;"; 3507 const char exp[] = "struct Foo<int> ; " 3508 "Foo<int> foo ; " 3509 "struct Foo<int> { " 3510 "template < typename > friend struct Foo ; " 3511 "} ;"; 3512 ASSERT_EQUALS(exp, tok(code)); 3513 } 3514 } 3515 template140()3516 void template140() { 3517 { 3518 const char code[] = "template <typename> struct a { };\n" 3519 "template <typename b> struct d {\n" 3520 " d();\n" 3521 " d(d<a<b>> e);\n" 3522 "};\n" 3523 "void foo() { d<char> c; }"; 3524 const char exp[] = "struct a<char> ; " 3525 "struct d<char> ; " 3526 "void foo ( ) { d<char> c ; } " 3527 "struct d<char> { " 3528 "d<char> ( ) ; " 3529 "d<char> ( d < a<char> > e ) ; " 3530 "} ; " 3531 "struct a<char> { } ;"; 3532 ASSERT_EQUALS(exp, tok(code)); 3533 } 3534 { 3535 const char code[] = "namespace a {\n" 3536 "template <typename b> using c = typename b ::d;\n" 3537 "template <typename> constexpr bool e() { return false; }\n" 3538 "template <typename b> class f { f(f<c<b>>); };\n" 3539 "static_assert(!e<f<char>>());\n" 3540 "}"; 3541 const char exp[] = "namespace a { " 3542 "constexpr bool e<f<char>> ( ) ; " 3543 "class f<char> ; " 3544 "static_assert ( ! e<f<char>> ( ) ) ; } " 3545 "class a :: f<char> { f<char> ( a :: f < b :: d > ) ; } ; " 3546 "constexpr bool a :: e<f<char>> ( ) { return false ; }"; 3547 ASSERT_EQUALS(exp, tok(code)); 3548 } 3549 } 3550 template141()3551 void template141() { // #9337 3552 const char code[] = "struct a {\n" 3553 " int c;\n" 3554 " template <typename b> void d(b e) const { c < *e; }\n" 3555 "};"; 3556 const char exp[] = "struct a { " 3557 "int c ; " 3558 "template < typename b > void d ( b e ) const { c < * e ; } " 3559 "} ;"; 3560 ASSERT_EQUALS(exp, tok(code)); 3561 } 3562 template142()3563 void template142() { // #9338 3564 const char code[] = "template <typename...> struct a;\n" 3565 "template <typename b, typename c, typename... d> struct a<b c::*, d...> {\n" 3566 " using typename b ::e;\n" 3567 " static_assert(e::f ? sizeof...(d) : sizeof...(d), \"\");\n" 3568 "};"; 3569 const char exp[] = "template < typename ... > struct a ; " 3570 "template < typename b , typename c , typename ... d > struct a < b c :: * , d ... > { " 3571 "using b :: e ; " 3572 "static_assert ( e :: f ? sizeof... ( d ) : sizeof... ( d ) , \"\" ) ; " 3573 "} ;"; 3574 ASSERT_EQUALS(exp, tok(code)); 3575 } 3576 template143()3577 void template143() { 3578 const char code[] = "template<int N>\n" 3579 "using A1 = struct B1 { static auto constexpr value = N; };\n" 3580 "A1<0> a1;\n" 3581 "template<class T>\n" 3582 "using A2 = struct B2 { void f(T){} };\n" 3583 "A2<bool> a2;\n" 3584 "template<class T>\n" 3585 "using A3 = enum B3 {b = 0;};\n" 3586 "A3<int> a3;"; 3587 const char exp[] = "template < int N > " 3588 "using A1 = struct B1 { static auto constexpr value = N ; } ; " 3589 "A1 < 0 > a1 ; " 3590 "template < class T > " 3591 "using A2 = struct B2 { void f ( T ) { } } ; " 3592 "A2 < bool > a2 ; " 3593 "template < class T > " 3594 "using A3 = enum B3 { b = 0 ; } ; " 3595 "A3 < int > a3 ;"; 3596 ASSERT_EQUALS(exp, tok(code)); 3597 } 3598 template144()3599 void template144() { // #9046 3600 const char code[] = "namespace a {\n" 3601 "template <typename T, typename enable = void>\n" 3602 "struct promote {\n" 3603 " using type = T;\n" 3604 "};\n" 3605 "template <typename T>\n" 3606 "struct promote <T, typename std::enable_if< std::is_integral<T>::value && sizeof(T) < sizeof(int) >::type>{\n" 3607 "};\n" 3608 "}"; 3609 const char exp[] = "namespace a { " 3610 "template < typename T , typename enable = void > " 3611 "struct promote { " 3612 "using type = T ; " 3613 "} ; " 3614 "template < typename T > " 3615 "struct promote < T , std :: enable_if < std :: is_integral < T > :: value && sizeof ( T ) < sizeof ( int ) > :: type > { " 3616 "} ; " 3617 "}"; 3618 ASSERT_EQUALS(exp, tok(code)); 3619 } 3620 template145()3621 void template145() { // syntax error 3622 const char code[] = "template<template<typename, Ts = 0> class ...Cs, Cs<Ts> ...Vs> struct B { };"; 3623 const char exp[] = "template < template < typename , Ts = 0 > class ... Cs , Cs < Ts > ... Vs > struct B { } ;"; 3624 ASSERT_EQUALS(exp, tok(code)); 3625 } 3626 template146()3627 void template146() { // syntax error 3628 const char code[] = "template<class T> struct C { };\n" 3629 "template<class T, template<class TT_T0, template<class TT_T1> class TT_TT> class TT, class U = TT<int, C> >\n" 3630 "struct S {\n" 3631 " void foo(TT<T, C>);\n" 3632 "};"; 3633 const char exp[] = "template < class T > struct C { } ; " 3634 "template < class T , template < class TT_T0 , template < class TT_T1 > class TT_TT > class TT , class U = TT < int , C > > " 3635 "struct S { " 3636 "void foo ( TT < T , C > ) ; " 3637 "} ;"; 3638 ASSERT_EQUALS(exp, tok(code)); 3639 } 3640 template147()3641 void template147() { // syntax error 3642 const char code[] = "template <template <typename> class C, typename X, C<X>*> struct b { };"; 3643 const char exp[] = "template < template < typename > class C , typename X , C < X > * > struct b { } ;"; 3644 ASSERT_EQUALS(exp, tok(code)); 3645 } 3646 template148()3647 void template148() { // syntax error 3648 const char code[] = "static_assert(var<S1<11, 100>> == var<S1<199, 23>> / 2\n" 3649 " && var<S1<50, 120>> == var<S1<150, var<S1<10, 10>>>>\n" 3650 " && var<S1<53, 23>> != 222, \"\");"; 3651 const char exp[] = "static_assert ( var < S1 < 11 , 100 > > == var < S1 < 199 , 23 > > / 2 " 3652 "&& var < S1 < 50 , 120 > > == var < S1 < 150 , var < S1 < 10 , 10 > > > > " 3653 "&& var < S1 < 53 , 23 > > != 222 , \"\" ) ;"; 3654 ASSERT_EQUALS(exp, tok(code)); 3655 } 3656 template149()3657 void template149() { // unknown macro 3658 const char code[] = "BEGIN_VERSIONED_NAMESPACE_DECL\n" 3659 "template<typename T> class Fred { };\n" 3660 "END_VERSIONED_NAMESPACE_DECL"; 3661 ASSERT_THROW_EQUALS(tok(code), InternalError, "There is an unknown macro here somewhere. Configuration is required. If BEGIN_VERSIONED_NAMESPACE_DECL is a macro then please configure it."); 3662 } 3663 template150()3664 void template150() { // syntax error 3665 const char code[] = "struct Test {\n" 3666 " template <typename T>\n" 3667 " T &operator[] (T) {}\n" 3668 "};\n" 3669 "void foo() {\n" 3670 " Test test;\n" 3671 " const string type = test.operator[]<string>(\"type\");\n" 3672 "}"; 3673 const char exp[] = "struct Test { " 3674 "string & operator[]<string> ( string ) ; " 3675 "} ; " 3676 "void foo ( ) { " 3677 "Test test ; " 3678 "const string type = test . operator[]<string> ( \"type\" ) ; " 3679 "} string & Test :: operator[]<string> ( string ) { }"; 3680 ASSERT_EQUALS(exp, tok(code)); 3681 } 3682 template151()3683 void template151() { // crash 3684 { 3685 const char code[] = "class SimulationComponentGroupGenerator {\n" 3686 " std::list<int, std::allocator<int>> build() const;\n" 3687 "};\n" 3688 "template <\n" 3689 " class obj_type,\n" 3690 " template<class> class allocator = std::allocator,\n" 3691 " template<class, class> class data_container = std::list>\n" 3692 "class GenericConfigurationHandler {\n" 3693 " data_container<int, std::allocator<int>> m_target_configurations;\n" 3694 "};\n" 3695 "class TargetConfigurationHandler : public GenericConfigurationHandler<int> { };"; 3696 const char exp[] = "class SimulationComponentGroupGenerator { " 3697 "std :: list < int , std :: allocator < int > > build ( ) const ; " 3698 "} ; " 3699 "class GenericConfigurationHandler<int,std::allocator,std::list> ; " 3700 "class TargetConfigurationHandler : public GenericConfigurationHandler<int,std::allocator,std::list> { } ; " 3701 "class GenericConfigurationHandler<int,std::allocator,std::list> { " 3702 "std :: list < int , std :: std :: allocator < int > > m_target_configurations ; " 3703 "} ;"; 3704 ASSERT_EQUALS(exp, tok(code)); 3705 } 3706 { 3707 const char code[] = "std::list<std::allocator<int>> a;\n" 3708 "template <class, template <class> class allocator = std::allocator> class b {};\n" 3709 "class c : b<int> {};"; 3710 const char exp[] = "std :: list < std :: allocator < int > > a ; " 3711 "class b<int,std::allocator> ; " 3712 "class c : b<int,std::allocator> { } ; " 3713 "class b<int,std::allocator> { } ;"; 3714 ASSERT_EQUALS(exp, tok(code)); 3715 } 3716 { 3717 const char code[] = "template <typename> class a {};\n" 3718 "template class a<char>;\n" 3719 "template <class, template <class> class a = a> class b {};\n" 3720 "class c : b<int> {};"; 3721 const char exp[] = "class a<char> ; " 3722 "class b<int,a> ; " 3723 "class c : b<int,a> { } ; " 3724 "class b<int,a> { } ; " 3725 "class a<char> { } ;"; 3726 ASSERT_EQUALS(exp, tok(code)); 3727 } 3728 } 3729 template152()3730 void template152() { // #9467 3731 const char code[] = "class Foo {\n" 3732 " template <unsigned int i>\n" 3733 " bool bar() {\n" 3734 " return true;\n" 3735 " }\n" 3736 "};\n" 3737 "template <>\n" 3738 "bool Foo::bar<9>() {\n" 3739 " return true;\n" 3740 "}\n" 3741 "int global() {\n" 3742 " int bar = 1;\n" 3743 " return bar;\n" 3744 "}"; 3745 const char exp[] = "class Foo { " 3746 "bool bar<9> ( ) ; " 3747 "template < unsigned int i > " 3748 "bool bar ( ) { " 3749 "return true ; " 3750 "} " 3751 "} ; " 3752 "bool Foo :: bar<9> ( ) { " 3753 "return true ; " 3754 "} " 3755 "int global ( ) { " 3756 "int bar ; bar = 1 ; " 3757 "return bar ; " 3758 "}"; 3759 ASSERT_EQUALS(exp, tok(code)); 3760 } 3761 template153()3762 void template153() { // #9483 3763 const char code[] = "template <class = b<decltype(a<h>())...>> void i();"; 3764 const char exp[] = "template < class = b < decltype ( a < h > ( ) ) ... > > void i ( ) ;"; 3765 ASSERT_EQUALS(exp, tok(code)); 3766 } 3767 template154()3768 void template154() { // #9495 3769 const char code[] = "template <typename S, enable_if_t<(is_compile_string<S>::value), int>> void i(S s);"; 3770 const char exp[] = "template < typename S , enable_if_t < ( is_compile_string < S > :: value ) , int > > void i ( S s ) ;"; 3771 ASSERT_EQUALS(exp, tok(code)); 3772 } 3773 template155()3774 void template155() { // #9539 3775 const char code[] = "template <int> int a = 0;\n" 3776 "struct b {\n" 3777 " void operator[](int);\n" 3778 "};\n" 3779 "void c() {\n" 3780 " b d;\n" 3781 " d[a<0>];\n" 3782 "}"; 3783 const char exp[] = "int a<0> ; " 3784 "a<0> = 0 ; " 3785 "struct b { " 3786 "void operator[] ( int ) ; " 3787 "} ; " 3788 "void c ( ) { " 3789 "b d ; " 3790 "d [ a<0> ] ; " 3791 "}"; 3792 ASSERT_EQUALS(exp, tok(code)); 3793 } 3794 template156()3795 void template156() { 3796 const char code[] = "template <int a> struct c { static constexpr int d = a; };\n" 3797 "template <bool b> using e = c<b>;\n" 3798 "using f = e<false>;\n" 3799 "template <typename> struct g : f {};\n" 3800 "template <bool, class, class> using h = e<g<long>::d>;\n" 3801 "template <typename> using i = e<g<double>::d>;\n" 3802 "template <typename j> using k = e<i<j>::d>;\n" 3803 "template <typename j> using l = h<k<j>::d, e<1 < (j)0>, f>;\n" 3804 "template <typename> void m(int, int, int) { l<int> d; }\n" 3805 "void n() { m<int>(0, 4, 5); }"; 3806 tok(code); // don't crash 3807 } 3808 template157()3809 void template157() { // #9854 3810 const char code[] = "template <int a, bool c = a == int()> struct b1 { bool d = c; };\n" 3811 "template <int a, bool c = a != int()> struct b2 { bool d = c; };\n" 3812 "template <int a, bool c = a < int()> struct b3 { bool d = c; };\n" 3813 "template <int a, bool c = a <= int()> struct b4 { bool d = c; };\n" 3814 "template <int a, bool c = (a > int())> struct b5 { bool d = c; };\n" 3815 "template <int a, bool c = a >= int()> struct b6 { bool d = c; };\n" 3816 "b1<0> var1;\n" 3817 "b2<0> var2;\n" 3818 "b3<0> var3;\n" 3819 "b4<0> var4;\n" 3820 "b5<0> var5;\n" 3821 "b6<0> var6;"; 3822 const char exp[] = "struct b1<0,true> ; " 3823 "struct b2<0,false> ; " 3824 "struct b3<0,false> ; " 3825 "struct b4<0,true> ; " 3826 "struct b5<0,false> ; " 3827 "struct b6<0,true> ; " 3828 "b1<0,true> var1 ; " 3829 "b2<0,false> var2 ; " 3830 "b3<0,false> var3 ; " 3831 "b4<0,true> var4 ; " 3832 "b5<0,false> var5 ; " 3833 "b6<0,true> var6 ; " 3834 "struct b6<0,true> { bool d ; d = true ; } ; " 3835 "struct b5<0,false> { bool d ; d = false ; } ; " 3836 "struct b4<0,true> { bool d ; d = true ; } ; " 3837 "struct b3<0,false> { bool d ; d = false ; } ; " 3838 "struct b2<0,false> { bool d ; d = false ; } ; " 3839 "struct b1<0,true> { bool d ; d = true ; } ;"; 3840 ASSERT_EQUALS(exp, tok(code)); 3841 } 3842 template158()3843 void template158() { // daca crash 3844 const char code[] = "template <typename> class a0{};\n" 3845 "template <typename> class a1{};\n" 3846 "template <typename> class a2{};\n" 3847 "template <typename> class a3{};\n" 3848 "template <typename> class a4{};\n" 3849 "template <typename> class a5{};\n" 3850 "template <typename> class a6{};\n" 3851 "template <typename> class a7{};\n" 3852 "template <typename> class a8{};\n" 3853 "template <typename> class a9{};\n" 3854 "template <typename> class a10{};\n" 3855 "template <typename> class a11{};\n" 3856 "template <typename> class a12{};\n" 3857 "template <typename> class a13{};\n" 3858 "template <typename> class a14{};\n" 3859 "template <typename> class a15{};\n" 3860 "template <typename> class a16{};\n" 3861 "template <typename> class a17{};\n" 3862 "template <typename> class a18{};\n" 3863 "template <typename> class a19{};\n" 3864 "template <typename> class a20{};\n" 3865 "template <typename> class a21{};\n" 3866 "template <typename> class a22{};\n" 3867 "template <typename> class a23{};\n" 3868 "template <typename> class a24{};\n" 3869 "template <typename> class a25{};\n" 3870 "template <typename> class a26{};\n" 3871 "template <typename> class a27{};\n" 3872 "template <typename> class a28{};\n" 3873 "template <typename> class a29{};\n" 3874 "template <typename> class a30{};\n" 3875 "template <typename> class a31{};\n" 3876 "template <typename> class a32{};\n" 3877 "template <typename> class a33{};\n" 3878 "template <typename> class a34{};\n" 3879 "template <typename> class a35{};\n" 3880 "template <typename> class a36{};\n" 3881 "template <typename> class a37{};\n" 3882 "template <typename> class a38{};\n" 3883 "template <typename> class a39{};\n" 3884 "template <typename> class a40{};\n" 3885 "template <typename> class a41{};\n" 3886 "template <typename> class a42{};\n" 3887 "template <typename> class a43{};\n" 3888 "template <typename> class a44{};\n" 3889 "template <typename> class a45{};\n" 3890 "template <typename> class a46{};\n" 3891 "template <typename> class a47{};\n" 3892 "template <typename> class a48{};\n" 3893 "template <typename> class a49{};\n" 3894 "template <typename> class a50{};\n" 3895 "template <typename> class a51{};\n" 3896 "template <typename> class a52{};\n" 3897 "template <typename> class a53{};\n" 3898 "template <typename> class a54{};\n" 3899 "template <typename> class a55{};\n" 3900 "template <typename> class a56{};\n" 3901 "template <typename> class a57{};\n" 3902 "template <typename> class a58{};\n" 3903 "template <typename> class a59{};\n" 3904 "template <typename> class a60{};\n" 3905 "template <typename> class a61{};\n" 3906 "template <typename> class a62{};\n" 3907 "template <typename> class a63{};\n" 3908 "template <typename> class a64{};\n" 3909 "template <typename> class a65{};\n" 3910 "template <typename> class a66{};\n" 3911 "template <typename> class a67{};\n" 3912 "template <typename> class a68{};\n" 3913 "template <typename> class a69{};\n" 3914 "template <typename> class a70{};\n" 3915 "template <typename> class a71{};\n" 3916 "template <typename> class a72{};\n" 3917 "template <typename> class a73{};\n" 3918 "template <typename> class a74{};\n" 3919 "template <typename> class a75{};\n" 3920 "template <typename> class a76{};\n" 3921 "template <typename> class a77{};\n" 3922 "template <typename> class a78{};\n" 3923 "template <typename> class a79{};\n" 3924 "template <typename> class a80{};\n" 3925 "template <typename> class a81{};\n" 3926 "template <typename> class a82{};\n" 3927 "template <typename> class a83{};\n" 3928 "template <typename> class a84{};\n" 3929 "template <typename> class a85{};\n" 3930 "template <typename> class a86{};\n" 3931 "template <typename> class a87{};\n" 3932 "template <typename> class a88{};\n" 3933 "template <typename> class a89{};\n" 3934 "template <typename> class a90{};\n" 3935 "template <typename> class a91{};\n" 3936 "template <typename> class a92{};\n" 3937 "template <typename> class a93{};\n" 3938 "template <typename> class a94{};\n" 3939 "template <typename> class a95{};\n" 3940 "template <typename> class a96{};\n" 3941 "template <typename> class a97{};\n" 3942 "template <typename> class a98{};\n" 3943 "template <typename> class a99{};\n" 3944 "template <typename> class a100{};\n" 3945 "template <typename> class b {};\n" 3946 "b<a0<int>> d0;\n" 3947 "b<a1<int>> d1;\n" 3948 "b<a2<int>> d2;\n" 3949 "b<a3<int>> d3;\n" 3950 "b<a4<int>> d4;\n" 3951 "b<a5<int>> d5;\n" 3952 "b<a6<int>> d6;\n" 3953 "b<a7<int>> d7;\n" 3954 "b<a8<int>> d8;\n" 3955 "b<a9<int>> d9;\n" 3956 "b<a10<int>> d10;\n" 3957 "b<a11<int>> d11;\n" 3958 "b<a12<int>> d12;\n" 3959 "b<a13<int>> d13;\n" 3960 "b<a14<int>> d14;\n" 3961 "b<a15<int>> d15;\n" 3962 "b<a16<int>> d16;\n" 3963 "b<a17<int>> d17;\n" 3964 "b<a18<int>> d18;\n" 3965 "b<a19<int>> d19;\n" 3966 "b<a20<int>> d20;\n" 3967 "b<a21<int>> d21;\n" 3968 "b<a22<int>> d22;\n" 3969 "b<a23<int>> d23;\n" 3970 "b<a24<int>> d24;\n" 3971 "b<a25<int>> d25;\n" 3972 "b<a26<int>> d26;\n" 3973 "b<a27<int>> d27;\n" 3974 "b<a28<int>> d28;\n" 3975 "b<a29<int>> d29;\n" 3976 "b<a30<int>> d30;\n" 3977 "b<a31<int>> d31;\n" 3978 "b<a32<int>> d32;\n" 3979 "b<a33<int>> d33;\n" 3980 "b<a34<int>> d34;\n" 3981 "b<a35<int>> d35;\n" 3982 "b<a36<int>> d36;\n" 3983 "b<a37<int>> d37;\n" 3984 "b<a38<int>> d38;\n" 3985 "b<a39<int>> d39;\n" 3986 "b<a40<int>> d40;\n" 3987 "b<a41<int>> d41;\n" 3988 "b<a42<int>> d42;\n" 3989 "b<a43<int>> d43;\n" 3990 "b<a44<int>> d44;\n" 3991 "b<a45<int>> d45;\n" 3992 "b<a46<int>> d46;\n" 3993 "b<a47<int>> d47;\n" 3994 "b<a48<int>> d48;\n" 3995 "b<a49<int>> d49;\n" 3996 "b<a50<int>> d50;\n" 3997 "b<a51<int>> d51;\n" 3998 "b<a52<int>> d52;\n" 3999 "b<a53<int>> d53;\n" 4000 "b<a54<int>> d54;\n" 4001 "b<a55<int>> d55;\n" 4002 "b<a56<int>> d56;\n" 4003 "b<a57<int>> d57;\n" 4004 "b<a58<int>> d58;\n" 4005 "b<a59<int>> d59;\n" 4006 "b<a60<int>> d60;\n" 4007 "b<a61<int>> d61;\n" 4008 "b<a62<int>> d62;\n" 4009 "b<a63<int>> d63;\n" 4010 "b<a64<int>> d64;\n" 4011 "b<a65<int>> d65;\n" 4012 "b<a66<int>> d66;\n" 4013 "b<a67<int>> d67;\n" 4014 "b<a68<int>> d68;\n" 4015 "b<a69<int>> d69;\n" 4016 "b<a70<int>> d70;\n" 4017 "b<a71<int>> d71;\n" 4018 "b<a72<int>> d72;\n" 4019 "b<a73<int>> d73;\n" 4020 "b<a74<int>> d74;\n" 4021 "b<a75<int>> d75;\n" 4022 "b<a76<int>> d76;\n" 4023 "b<a77<int>> d77;\n" 4024 "b<a78<int>> d78;\n" 4025 "b<a79<int>> d79;\n" 4026 "b<a80<int>> d80;\n" 4027 "b<a81<int>> d81;\n" 4028 "b<a82<int>> d82;\n" 4029 "b<a83<int>> d83;\n" 4030 "b<a84<int>> d84;\n" 4031 "b<a85<int>> d85;\n" 4032 "b<a86<int>> d86;\n" 4033 "b<a87<int>> d87;\n" 4034 "b<a88<int>> d88;\n" 4035 "b<a89<int>> d89;\n" 4036 "b<a90<int>> d90;\n" 4037 "b<a91<int>> d91;\n" 4038 "b<a92<int>> d92;\n" 4039 "b<a93<int>> d93;\n" 4040 "b<a94<int>> d94;\n" 4041 "b<a95<int>> d95;\n" 4042 "b<a96<int>> d96;\n" 4043 "b<a97<int>> d97;\n" 4044 "b<a98<int>> d98;\n" 4045 "b<a99<int>> d99;\n" 4046 "b<a100<int>> d100;"; 4047 // don't bother checking the output because this is not instantiated properly 4048 tok(code); // don't crash 4049 } 4050 template159()4051 void template159() { // #9886 4052 const char code[] = "struct impl { template <class T> static T create(); };\n" 4053 "template<class T, class U, class = decltype(impl::create<T>()->impl::create<U>())>\n" 4054 "struct tester{};\n" 4055 "tester<impl*, int> ti;\n" 4056 "template<class T, class U, class = decltype(impl::create<T>()->impl::create<U>())>\n" 4057 "int test() { return 0; }\n" 4058 "int i = test<impl*, int>();"; 4059 const char exp[] = "struct impl { template < class T > static T create ( ) ; } ; " 4060 "struct tester<impl*,int,decltype(impl::create<impl*>().impl::create<int>())> ; " 4061 "tester<impl*,int,decltype(impl::create<impl*>().impl::create<int>())> ti ; " 4062 "int test<impl*,int,decltype(impl::create<impl*>().impl::create<int>())> ( ) ; " 4063 "int i ; i = test<impl*,int,decltype(impl::create<impl*>().impl::create<int>())> ( ) ; " 4064 "int test<impl*,int,decltype(impl::create<impl*>().impl::create<int>())> ( ) { return 0 ; } " 4065 "struct tester<impl*,int,decltype(impl::create<impl*>().impl::create<int>())> { } ;"; 4066 ASSERT_EQUALS(exp, tok(code)); 4067 } 4068 template160()4069 void template160() { 4070 const char code[] = "struct Fred {\n" 4071 " template <typename T> static void foo() { }\n" 4072 " template <typename T> static void foo(T) { }\n" 4073 "};\n" 4074 "template void Fred::foo<char>();\n" 4075 "template <> void Fred::foo<bool>() { }\n" 4076 "template void Fred::foo<float>(float);\n" 4077 "template <> void Fred::foo<int>(int) { }"; 4078 const char exp[] = "struct Fred { " 4079 "static void foo<bool> ( ) ; " 4080 "static void foo<char> ( ) ; " 4081 "static void foo<int> ( int ) ; " 4082 "static void foo<float> ( float ) ; " 4083 "} ; " 4084 "void Fred :: foo<bool> ( ) { } " 4085 "void Fred :: foo<int> ( int ) { } " 4086 "void Fred :: foo<float> ( float ) { } " 4087 "void Fred :: foo<char> ( ) { }"; 4088 ASSERT_EQUALS(exp, tok(code)); 4089 } 4090 template161()4091 void template161() { 4092 const char code[] = "struct JobEntry { };\n" 4093 "template<class T>\n" 4094 "struct adapter : public T {\n" 4095 " template<class... Args>\n" 4096 " adapter(Args&&... args) : T{ std::forward<Args>(args)... } {}\n" 4097 "};\n" 4098 "void foo() {\n" 4099 " auto notifyJob = std::make_shared<adapter<JobEntry>> ();\n" 4100 "}"; 4101 const char exp[] = "???"; 4102 const char act[] = "struct JobEntry { } ; " 4103 "struct adapter<JobEntry> ; " 4104 "void foo ( ) { " 4105 "auto notifyJob ; notifyJob = std :: make_shared < adapter<JobEntry> > ( ) ; " 4106 "} " 4107 "struct adapter<JobEntry> : public JobEntry { " 4108 "template < class ... Args > " 4109 "adapter<JobEntry> ( Args && ... args ) : JobEntry { std :: forward < Args > ( args ) ... } { } " 4110 "} ;"; 4111 TODO_ASSERT_EQUALS(exp, act, tok(code)); 4112 } 4113 template162()4114 void template162() { 4115 const char code[] = "template <std::size_t N>\n" 4116 "struct CountryCode {\n" 4117 " CountryCode(std::string cc);\n" 4118 "};" 4119 "template <std::size_t N>\n" 4120 "CountryCode<N>::CountryCode(std::string cc) : m_String{std::move(cc)} {\n" 4121 "}\n" 4122 "template class CountryCode<2>;\n" 4123 "template class CountryCode<3>;"; 4124 const char exp[] = "struct CountryCode<2> ; " 4125 "struct CountryCode<3> ; " 4126 "struct CountryCode<2> { " 4127 "CountryCode<2> ( std :: string cc ) ; " 4128 "} ; " 4129 "CountryCode<2> :: CountryCode<2> ( std :: string cc ) : m_String { std :: move ( cc ) } { " 4130 "} " 4131 "struct CountryCode<3> { " 4132 "CountryCode<3> ( std :: string cc ) ; " 4133 "} ; " 4134 "CountryCode<3> :: CountryCode<3> ( std :: string cc ) : m_String { std :: move ( cc ) } { " 4135 "}"; 4136 ASSERT_EQUALS(exp, tok(code)); 4137 } 4138 template163()4139 void template163() { // #9685 syntax error 4140 const char code[] = "extern \"C++\" template < typename T > T * test ( ) { return nullptr ; }"; 4141 ASSERT_EQUALS(code, tok(code)); 4142 } 4143 template164()4144 void template164() { // #9394 4145 const char code[] = "template <class TYPE>\n" 4146 "struct A {\n" 4147 " A();\n" 4148 " ~A();\n" 4149 " static void f();\n" 4150 "};\n" 4151 "template <class TYPE>\n" 4152 "A<TYPE>::A() { }\n" 4153 "template <class TYPE>\n" 4154 "A<TYPE>::~A() { }\n" 4155 "template <class TYPE>\n" 4156 "void A<TYPE>::f() { }\n" 4157 "template class A<int>;\n" 4158 "template class A<float>;"; 4159 const char exp[] = "struct A<int> ; " 4160 "struct A<float> ; " 4161 "struct A<int> { " 4162 "A<int> ( ) ; " 4163 "~ A<int> ( ) ; " 4164 "static void f ( ) ; " 4165 "} ; " 4166 "A<int> :: A<int> ( ) { } " 4167 "A<int> :: ~ A<int> ( ) { } " 4168 "void A<int> :: f ( ) { } " 4169 "struct A<float> { " 4170 "A<float> ( ) ; " 4171 "~ A<float> ( ) ; " 4172 "static void f ( ) ; " 4173 "} ; " 4174 "A<float> :: A<float> ( ) { } " 4175 "A<float> :: ~ A<float> ( ) { } " 4176 "void A<float> :: f ( ) { }"; 4177 ASSERT_EQUALS(exp, tok(code)); 4178 } 4179 template165()4180 void template165() { // #10032 syntax error 4181 const char code[] = "struct MyStruct {\n" 4182 " template<class T>\n" 4183 " bool operator()(const T& l, const T& r) const {\n" 4184 " return l.first < r.first;\n" 4185 " }\n" 4186 "};"; 4187 const char exp[] = "struct MyStruct { " 4188 "template < class T > " 4189 "bool operator() ( const T & l , const T & r ) const { " 4190 "return l . first < r . first ; " 4191 "} " 4192 "} ;"; 4193 ASSERT_EQUALS(exp, tok(code)); 4194 } 4195 template166()4196 void template166() { // #10081 hang 4197 const char code[] = "template <typename T, size_t k = (T::s < 3) ? 0 : 3>\n" 4198 "void foo() {}\n" 4199 "foo<T>();"; 4200 const char exp[] = "void foo<T,(T::s<3)?0:3> ( ) ; " 4201 "foo<T,(T::s<3)?0:3> ( ) ; " 4202 "void foo<T,(T::s<3)?0:3> ( ) { }"; 4203 ASSERT_EQUALS(exp, tok(code)); 4204 } 4205 template167()4206 void template167() { 4207 const char code[] = "struct MathLib {\n" 4208 " template<class T> static std::string toString(T value) {\n" 4209 " return std::string{};\n" 4210 " }\n" 4211 "};\n" 4212 "template<> std::string MathLib::toString(double value);\n" 4213 "template<> std::string MathLib::toString(double value) {\n" 4214 " return std::string{std::to_string(value)};\n" 4215 "}\n" 4216 "void foo() {\n" 4217 " std::string str = MathLib::toString(1.0);\n" 4218 "}"; 4219 const char exp[] = "struct MathLib { " 4220 "static std :: string toString<double> ( double value ) ; " 4221 "template < class T > static std :: string toString ( T value ) { " 4222 "return std :: string { } ; " 4223 "} " 4224 "} ; " 4225 "std :: string MathLib :: toString<double> ( double value ) { " 4226 "return std :: string { std :: to_string ( value ) } ; " 4227 "} " 4228 "void foo ( ) { " 4229 "std :: string str ; str = MathLib :: toString<double> ( 1.0 ) ; " 4230 "}"; 4231 ASSERT_EQUALS(exp, tok(code)); 4232 } 4233 template168()4234 void template168() { 4235 const char code[] = "template < typename T, typename U > struct type { };\n" 4236 "template < > struct type < bool, bool > {};\n" 4237 "template < > struct type < unsigned char, unsigned char > {};\n" 4238 "template < > struct type < char, char > {};\n" 4239 "template < > struct type < signed char, signed char > {};\n" 4240 "template < > struct type < unsigned short, unsigned short > {};\n" 4241 "template < > struct type < short, short > {};\n" 4242 "template < > struct type < unsigned int, unsigned int > {};\n" 4243 "template < > struct type < int, int > {};\n" 4244 "template < > struct type < unsigned long long, unsigned long long > {};\n" 4245 "template < > struct type < long long, long long > {};\n" 4246 "template < > struct type < double, double > {};\n" 4247 "template < > struct type < float, float > {};\n" 4248 "template < > struct type < long double, long double > {};"; 4249 const char exp[] = "struct type<longdouble,longdouble> ; " 4250 "struct type<float,float> ; " 4251 "struct type<double,double> ; " 4252 "struct type<longlong,longlong> ; " 4253 "struct type<unsignedlonglong,unsignedlonglong> ; " 4254 "struct type<int,int> ; " 4255 "struct type<unsignedint,unsignedint> ; " 4256 "struct type<short,short> ; " 4257 "struct type<unsignedshort,unsignedshort> ; " 4258 "struct type<signedchar,signedchar> ; " 4259 "struct type<char,char> ; " 4260 "struct type<unsignedchar,unsignedchar> ; " 4261 "struct type<bool,bool> ; " 4262 "template < typename T , typename U > struct type { } ; " 4263 "struct type<bool,bool> { } ; " 4264 "struct type<unsignedchar,unsignedchar> { } ; " 4265 "struct type<char,char> { } ; " 4266 "struct type<signedchar,signedchar> { } ; " 4267 "struct type<unsignedshort,unsignedshort> { } ; " 4268 "struct type<short,short> { } ; " 4269 "struct type<unsignedint,unsignedint> { } ; " 4270 "struct type<int,int> { } ; " 4271 "struct type<unsignedlonglong,unsignedlonglong> { } ; " 4272 "struct type<longlong,longlong> { } ; " 4273 "struct type<double,double> { } ; " 4274 "struct type<float,float> { } ; " 4275 "struct type<longdouble,longdouble> { } ;"; 4276 ASSERT_EQUALS(exp, tok(code)); 4277 } 4278 template169()4279 void template169() { 4280 const char code[] = "template < typename T> struct last { T t; };\n" 4281 "template < typename T > struct CImgList { T t; };\n" 4282 "CImgList < last < bool > > c1;\n" 4283 "CImgList < last < signed char > > c2;\n" 4284 "CImgList < last < unsigned char > > c3;\n" 4285 "CImgList < last < char > > c4;\n" 4286 "CImgList < last < unsigned short > > c5;\n" 4287 "CImgList < last < short > > c6;\n" 4288 "CImgList < last < unsigned int > > c7;\n" 4289 "CImgList < last < int > > c8;\n" 4290 "CImgList < last < unsigned long > > c9;\n" 4291 "CImgList < last < long > > c10;\n" 4292 "CImgList < last < unsigned long long > > c11;\n" 4293 "CImgList < last < long long > > c12;\n" 4294 "CImgList < last < float > > c13;\n" 4295 "CImgList < last < double > > c14;\n" 4296 "CImgList < last < long double > > c15;"; 4297 const char exp[] = "struct last<bool> ; " 4298 "struct last<signedchar> ; " 4299 "struct last<unsignedchar> ; " 4300 "struct last<char> ; " 4301 "struct last<unsignedshort> ; " 4302 "struct last<short> ; " 4303 "struct last<unsignedint> ; " 4304 "struct last<int> ; " 4305 "struct last<unsignedlong> ; " 4306 "struct last<long> ; " 4307 "struct last<unsignedlonglong> ; " 4308 "struct last<longlong> ; " 4309 "struct last<float> ; " 4310 "struct last<double> ; " 4311 "struct last<longdouble> ; " 4312 "struct CImgList<last<bool>> ; " 4313 "struct CImgList<last<signedchar>> ; " 4314 "struct CImgList<last<unsignedchar>> ; " 4315 "struct CImgList<last<char>> ; " 4316 "struct CImgList<last<unsignedshort>> ; " 4317 "struct CImgList<last<short>> ; " 4318 "struct CImgList<last<unsignedint>> ; " 4319 "struct CImgList<last<int>> ; " 4320 "struct CImgList<last<unsignedlong>> ; " 4321 "struct CImgList<last<long>> ; " 4322 "struct CImgList<last<unsignedlonglong>> ; " 4323 "struct CImgList<last<longlong>> ; " 4324 "struct CImgList<last<float>> ; " 4325 "struct CImgList<last<double>> ; " 4326 "struct CImgList<last<longdouble>> ; " 4327 "CImgList<last<bool>> c1 ; " 4328 "CImgList<last<signedchar>> c2 ; " 4329 "CImgList<last<unsignedchar>> c3 ; " 4330 "CImgList<last<char>> c4 ; " 4331 "CImgList<last<unsignedshort>> c5 ; " 4332 "CImgList<last<short>> c6 ; " 4333 "CImgList<last<unsignedint>> c7 ; " 4334 "CImgList<last<int>> c8 ; " 4335 "CImgList<last<unsignedlong>> c9 ; " 4336 "CImgList<last<long>> c10 ; " 4337 "CImgList<last<unsignedlonglong>> c11 ; " 4338 "CImgList<last<longlong>> c12 ; " 4339 "CImgList<last<float>> c13 ; " 4340 "CImgList<last<double>> c14 ; " 4341 "CImgList<last<longdouble>> c15 ; " 4342 "struct CImgList<last<bool>> { last<bool> t ; } ; " 4343 "struct CImgList<last<signedchar>> { last<signedchar> t ; } ; " 4344 "struct CImgList<last<unsignedchar>> { last<unsignedchar> t ; } ; " 4345 "struct CImgList<last<char>> { last<char> t ; } ; " 4346 "struct CImgList<last<unsignedshort>> { last<unsignedshort> t ; } ; " 4347 "struct CImgList<last<short>> { last<short> t ; } ; " 4348 "struct CImgList<last<unsignedint>> { last<unsignedint> t ; } ; " 4349 "struct CImgList<last<int>> { last<int> t ; } ; " 4350 "struct CImgList<last<unsignedlong>> { last<unsignedlong> t ; } ; " 4351 "struct CImgList<last<long>> { last<long> t ; } ; " 4352 "struct CImgList<last<unsignedlonglong>> { last<unsignedlonglong> t ; } ; " 4353 "struct CImgList<last<longlong>> { last<longlong> t ; } ; " 4354 "struct CImgList<last<float>> { last<float> t ; } ; " 4355 "struct CImgList<last<double>> { last<double> t ; } ; " 4356 "struct CImgList<last<longdouble>> { last<longdouble> t ; } ; " 4357 "struct last<bool> { bool t ; } ; " 4358 "struct last<signedchar> { signed char t ; } ; " 4359 "struct last<unsignedchar> { unsigned char t ; } ; " 4360 "struct last<char> { char t ; } ; " 4361 "struct last<unsignedshort> { unsigned short t ; } ; " 4362 "struct last<short> { short t ; } ; " 4363 "struct last<unsignedint> { unsigned int t ; } ; " 4364 "struct last<int> { int t ; } ; " 4365 "struct last<unsignedlong> { unsigned long t ; } ; " 4366 "struct last<long> { long t ; } ; " 4367 "struct last<unsignedlonglong> { unsigned long long t ; } ; " 4368 "struct last<longlong> { long long t ; } ; " 4369 "struct last<float> { float t ; } ; " 4370 "struct last<double> { double t ; } ; " 4371 "struct last<longdouble> { long double t ; } ;"; 4372 ASSERT_EQUALS(exp, tok(code)); 4373 } 4374 template170()4375 void template170() { // crash 4376 const char code[] = "template <int b> int a = 0;\n" 4377 "void c() {\n" 4378 " a<1>;\n" 4379 " [](auto b) {};\n" 4380 "}"; 4381 const char exp[] = "int a<1> ; a<1> = 0 ; " 4382 "void c ( ) { " 4383 "a<1> ; " 4384 "[ ] ( auto b ) { } ; " 4385 "}"; 4386 ASSERT_EQUALS(exp, tok(code)); 4387 } 4388 template171()4389 void template171() { // crash 4390 const char code[] = "template <int> struct c { enum { b }; };\n" 4391 "template <int> struct h { enum { d }; enum { e }; };\n" 4392 "template <int f, long = h<f>::d, int g = h<f>::e> class i { enum { e = c<g>::b }; };\n" 4393 "void j() { i<2> a; }"; 4394 const char exp[] = "struct c<h<2>::e> ; " 4395 "struct h<2> ; " 4396 "class i<2,h<2>::d,h<2>::e> ; " 4397 "void j ( ) { i<2,h<2>::d,h<2>::e> a ; } " 4398 "class i<2,h<2>::d,h<2>::e> { enum Anonymous3 { e = c<h<2>::e> :: b } ; } ; " 4399 "struct h<2> { enum Anonymous1 { d } ; enum Anonymous2 { e } ; } ; " 4400 "struct c<h<2>::e> { enum Anonymous0 { b } ; } ;"; 4401 const char act[] = "struct c<h<2>::e> ; " 4402 "template < int > struct h { enum Anonymous1 { d } ; enum Anonymous2 { e } ; } ; " 4403 "class i<2,h<2>::d,h<2>::e> ; " 4404 "void j ( ) { i<2,h<2>::d,h<2>::e> a ; } " 4405 "class i<2,h<2>::d,h<2>::e> { enum Anonymous3 { e = c<h<2>::e> :: b } ; } ; " 4406 "struct c<h<2>::e> { enum Anonymous0 { b } ; } ;"; 4407 TODO_ASSERT_EQUALS(exp, act, tok(code)); 4408 } 4409 template172()4410 void template172() { // #10258 crash 4411 const char code[] = "template<typename T, typename... Args>\n" 4412 "void bar(T t, Args&&... args) { }\n" 4413 "void foo() { bar<int>(0, 1); }"; 4414 const char exp[] = "void bar<int> ( int t , Args && ... args ) ; " 4415 "void foo ( ) { bar<int> ( 0 , 1 ) ; } " 4416 "void bar<int> ( int t , Args && ... args ) { }"; 4417 ASSERT_EQUALS(exp, tok(code)); 4418 } 4419 template173()4420 void template173() { // #10332 crash 4421 const char code[] = "namespace a {\n" 4422 "template <typename, typename> struct b;\n" 4423 "template <template <typename, typename> class = b> class c;\n" 4424 "using d = c<>;\n" 4425 "template <template <typename, typename = void> class> class c {};\n" 4426 "}\n" 4427 "namespace std {\n" 4428 "template <> void swap<a::d>(a::d &, a::d &) {}\n" 4429 "}"; 4430 const char exp[] = "namespace a { " 4431 "template < typename , typename > struct b ; " 4432 "template < template < typename , typename > class > class c ; " 4433 "class c<b> ; " 4434 "} " 4435 "namespace std { " 4436 "void swap<a::c<b>> ( a :: c<b> & , a :: c<b> & ) ; " 4437 "void swap<a::c<b>> ( a :: c<b> & , a :: c<b> & ) { } " 4438 "} " 4439 "class a :: c<b> { } ;"; 4440 ASSERT_EQUALS(exp, tok(code)); 4441 } 4442 template174()4443 void template174() 4444 { // #10506 hang 4445 const char code[] = "namespace a {\n" 4446 "template <typename> using b = int;\n" 4447 "template <typename c> c d() { return d<b<c>>(); }\n" 4448 "}\n" 4449 "void e() { a::d<int>(); }\n"; 4450 const char exp[] = "namespace a { int d<int> ( ) ; } " 4451 "void e ( ) { a :: d<int> ( ) ; } " 4452 "int a :: d<int> ( ) { return d < int > ( ) ; }"; 4453 ASSERT_EQUALS(exp, tok(code)); 4454 } 4455 template_specialization_1()4456 void template_specialization_1() { // #7868 - template specialization template <typename T> struct S<C<T>> {..}; 4457 const char code[] = "template <typename T> struct C {};\n" 4458 "template <typename T> struct S {a};\n" 4459 "template <typename T> struct S<C<T>> {b};\n" 4460 "S<int> s;"; 4461 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 } ;"; 4462 ASSERT_EQUALS(exp, tok(code)); 4463 } 4464 template_specialization_2()4465 void template_specialization_2() { // #7868 - template specialization template <typename T> struct S<C<T>> {..}; 4466 const char code[] = "template <typename T> struct C {};\n" 4467 "template <typename T> struct S {a};\n" 4468 "template <typename T> struct S<C<T>> {b};\n" 4469 "S<C<int>> s;"; 4470 const char exp[] = "template < typename T > struct C { } ; template < typename T > struct S { a } ; struct S<C<int>> ; S<C<int>> s ; struct S<C<int>> { b } ;"; 4471 ASSERT_EQUALS(exp, tok(code)); 4472 } 4473 template_enum()4474 void template_enum() { 4475 const char code1[] = "template <class T>\n" 4476 "struct Unconst {\n" 4477 " typedef T type;\n" 4478 "};\n" 4479 "template <class T>\n" 4480 "struct Unconst<const T> {\n" 4481 " typedef T type;\n" 4482 "};\n" 4483 "template <class T>\n" 4484 "struct Unconst<const T&> {\n" 4485 " typedef T& type;\n" 4486 "};\n" 4487 "template <class T>\n" 4488 "struct Unconst<T* const> {\n" 4489 " typedef T* type;\n" 4490 "};\n" 4491 "template <class T1, class T2>\n" 4492 "struct type_equal {\n" 4493 " enum { value = 0 };\n" 4494 "};\n" 4495 "template <class T>\n" 4496 "struct type_equal<T, T> {\n" 4497 " enum { value = 1 };\n" 4498 "};\n" 4499 "template<class T>\n" 4500 "struct template_is_const\n" 4501 "{\n" 4502 " enum {value = !type_equal<T, typename Unconst<T>::type>::value };\n" 4503 "};"; 4504 const char exp1[] = "template < class T > struct Unconst { } ; " 4505 "template < class T > struct Unconst < const T > { } ; " 4506 "template < class T > struct Unconst < const T & > { } ; " 4507 "template < class T > struct Unconst < T * const > { } ; " 4508 "template < class T1 , class T2 > struct type_equal { enum Anonymous0 { value = 0 } ; } ; " 4509 "template < class T > struct type_equal < T , T > { enum Anonymous1 { value = 1 } ; } ; " 4510 "template < class T > struct template_is_const { enum Anonymous2 { value = ! type_equal < T , Unconst < T > :: type > :: value } ; } ;"; 4511 ASSERT_EQUALS(exp1, tok(code1)); 4512 } 4513 template_default_parameter()4514 void template_default_parameter() { 4515 { 4516 const char code[] = "template <class T, int n=3>\n" 4517 "class A\n" 4518 "{ T ar[n]; };\n" 4519 "\n" 4520 "void f()\n" 4521 "{\n" 4522 " A<int,2> a1;\n" 4523 " A<int> a2;\n" 4524 "}\n"; 4525 const char expected[] = "class A<int,2> ; " 4526 "class A<int,3> ; " 4527 "void f ( ) " 4528 "{" 4529 " A<int,2> a1 ;" 4530 " A<int,3> a2 ; " 4531 "} " 4532 "class A<int,2> " 4533 "{ int ar [ 2 ] ; } ; " 4534 "class A<int,3> " 4535 "{ int ar [ 3 ] ; } ;"; 4536 ASSERT_EQUALS(expected, tok(code)); 4537 } 4538 { 4539 const char code[] = "template <class T, int n1=3, int n2=2>\n" 4540 "class A\n" 4541 "{ T ar[n1+n2]; };\n" 4542 "\n" 4543 "void f()\n" 4544 "{\n" 4545 " A<int> a1;\n" 4546 " A<int,3> a2;\n" 4547 "}\n"; 4548 4549 const char expected[] = "class A<int,3,2> ; " 4550 "void f ( ) " 4551 "{" 4552 " A<int,3,2> a1 ;" 4553 " A<int,3,2> a2 ; " 4554 "} " 4555 "class A<int,3,2> " 4556 "{ int ar [ 3 + 2 ] ; } ;"; 4557 ASSERT_EQUALS(expected, tok(code)); 4558 } 4559 { 4560 const char code[] = "template <class T, int n=3>\n" 4561 "class A\n" 4562 "{ T ar[n]; };\n" 4563 "\n" 4564 "void f()\n" 4565 "{\n" 4566 " A<int,(int)2> a1;\n" 4567 " A<int> a2;\n" 4568 "}\n"; 4569 const char expected[] = "class A<int,(int)2> ; " 4570 "class A<int,3> ; " 4571 "void f ( ) " 4572 "{ " 4573 "A<int,(int)2> a1 ; " 4574 "A<int,3> a2 ; " 4575 "} " 4576 "class A<int,(int)2> " 4577 "{ int ar [ ( int ) 2 ] ; } ; " 4578 "class A<int,3> " 4579 "{ int ar [ 3 ] ; } ;"; 4580 ASSERT_EQUALS(expected, tok(code)); 4581 } 4582 { 4583 const char code[] = "class A { }; " 4584 "template<class T> class B { }; " 4585 "template<class T1, class T2 = B<T1>> class C { }; " 4586 "template<class T1 = A, typename T2 = B<A>> class D { };"; 4587 ASSERT_EQUALS("class A { } ; " 4588 "template < class T > class B { } ; " 4589 "template < class T1 , class T2 = B < T1 > > class C { } ; " 4590 "template < class T1 = A , typename T2 = B < A > > class D { } ;", tok(code)); 4591 } 4592 { 4593 // #7548 4594 const char code[] = "template<class T, class U> class DefaultMemory {}; " 4595 "template<class Key, class Val, class Mem=DefaultMemory<Key,Val> > class thv_table_c {}; " 4596 "thv_table_c<void *,void *> id_table_m;"; 4597 const char exp[] = "template < class T , class U > class DefaultMemory { } ; " 4598 "class thv_table_c<void*,void*,DefaultMemory<void*,void*>> ; " 4599 "thv_table_c<void*,void*,DefaultMemory<void*,void*>> id_table_m ; " 4600 "class thv_table_c<void*,void*,DefaultMemory<void*,void*>> { } ;"; 4601 ASSERT_EQUALS(exp, tok(code)); 4602 } 4603 { 4604 // #8890 4605 const char code[] = "template <typename = void> struct a {\n" 4606 " void c();\n" 4607 "};\n" 4608 "void f() {\n" 4609 " a<> b;\n" 4610 " b.a<>::c();\n" 4611 "}"; 4612 ASSERT_EQUALS("struct a<void> ; " 4613 "void f ( ) { " 4614 "a<void> b ; " 4615 "b . a<void> :: c ( ) ; " 4616 "} " 4617 "struct a<void> { " 4618 "void c ( ) ; " 4619 "} ;", tok(code)); 4620 } 4621 { 4622 // #8890 4623 const char code[] = "template< typename T0 = void > class A;\n" 4624 "template<>\n" 4625 "class A< void > {\n" 4626 " public:\n" 4627 " A() { }\n" 4628 " ~A() { }\n" 4629 " void Print() { std::cout << \"A\" << std::endl; }\n" 4630 "};\n" 4631 "class B : public A<> {\n" 4632 " public:\n" 4633 " B() { }\n" 4634 " ~B() { }\n" 4635 "};\n" 4636 "int main( int argc, char* argv[] ) {\n" 4637 " B b;\n" 4638 " b.A<>::Print();\n" 4639 " return 0;\n" 4640 "}"; 4641 ASSERT_EQUALS("class A<void> ; " 4642 "template < typename T0 > class A ; " 4643 "class A<void> { " 4644 "public: " 4645 "A<void> ( ) { } " 4646 "~ A<void> ( ) { } " 4647 "void Print ( ) { std :: cout << \"A\" << std :: endl ; } " 4648 "} ; " 4649 "class B : public A<void> { " 4650 "public: " 4651 "B ( ) { } " 4652 "~ B ( ) { } " 4653 "} ; " 4654 "int main ( int argc , char * argv [ ] ) { " 4655 "B b ; " 4656 "b . A<void> :: Print ( ) ; " 4657 "return 0 ; " 4658 "}", tok(code)); 4659 } 4660 } 4661 template_forward_declared_default_parameter()4662 void template_forward_declared_default_parameter() { 4663 { 4664 const char code[] = "template <class T, int n=3> class A;\n" 4665 "template <class T, int n>\n" 4666 "class A\n" 4667 "{ T ar[n]; };\n" 4668 "\n" 4669 "void f()\n" 4670 "{\n" 4671 " A<int,2> a1;\n" 4672 " A<int> a2;\n" 4673 "}\n"; 4674 4675 const char exp[] = "class A<int,2> ; " 4676 "class A<int,3> ; " 4677 "void f ( ) " 4678 "{" 4679 " A<int,2> a1 ;" 4680 " A<int,3> a2 ; " 4681 "} " 4682 "class A<int,2> " 4683 "{ int ar [ 2 ] ; } ; " 4684 "class A<int,3> " 4685 "{ int ar [ 3 ] ; } ;"; 4686 ASSERT_EQUALS(exp, tok(code)); 4687 } 4688 { 4689 const char code[] = "template <class, int = 3> class A;\n" 4690 "template <class T, int n>\n" 4691 "class A\n" 4692 "{ T ar[n]; };\n" 4693 "\n" 4694 "void f()\n" 4695 "{\n" 4696 " A<int,2> a1;\n" 4697 " A<int> a2;\n" 4698 "}\n"; 4699 4700 const char exp[] = "class A<int,2> ; " 4701 "class A<int,3> ; " 4702 "void f ( ) " 4703 "{" 4704 " A<int,2> a1 ;" 4705 " A<int,3> a2 ; " 4706 "} " 4707 "class A<int,2> " 4708 "{ int ar [ 2 ] ; } ; " 4709 "class A<int,3> " 4710 "{ int ar [ 3 ] ; } ;"; 4711 ASSERT_EQUALS(exp, tok(code)); 4712 } 4713 { 4714 const char code[] = "template<typename Lhs, int TriangularPart = (int(Lhs::Flags) & LowerTriangularBit)>\n" 4715 "struct ei_solve_triangular_selector;\n" 4716 "template<typename Lhs, int UpLo>\n" 4717 "struct ei_solve_triangular_selector<Lhs,UpLo> {\n" 4718 "};\n" 4719 "template<typename Lhs, int TriangularPart>\n" 4720 "struct ei_solve_triangular_selector { };"; 4721 4722 const char exp[] = "template < typename Lhs , int TriangularPart = ( int ( Lhs :: Flags ) & LowerTriangularBit ) > " 4723 "struct ei_solve_triangular_selector ; " 4724 "template < typename Lhs , int UpLo > " 4725 "struct ei_solve_triangular_selector < Lhs , UpLo > { " 4726 "} ; " 4727 "template < typename Lhs , int TriangularPart = ( int ( Lhs :: Flags ) & LowerTriangularBit ) > " 4728 "struct ei_solve_triangular_selector { } ;"; 4729 4730 ASSERT_EQUALS(exp, tok(code)); 4731 } 4732 } 4733 template_default_type()4734 void template_default_type() { 4735 const char code[] = "template <typename T, typename U=T>\n" 4736 "class A\n" 4737 "{\n" 4738 "public:\n" 4739 " void foo() {\n" 4740 " int a;\n" 4741 " a = static_cast<U>(a);\n" 4742 " }\n" 4743 "};\n" 4744 "\n" 4745 "template <typename T>\n" 4746 "class B\n" 4747 "{\n" 4748 "protected:\n" 4749 " A<int> a;\n" 4750 "};\n" 4751 "\n" 4752 "class C\n" 4753 " : public B<int>\n" 4754 "{\n" 4755 "};\n"; 4756 4757 tok(code); 4758 4759 //ASSERT_EQUALS("[file1.cpp:15]: (error) Internal error: failed to instantiate template. The checking continues anyway.\n", errout.str()); 4760 ASSERT_EQUALS("", errout.str()); 4761 } 4762 template_typename()4763 void template_typename() { 4764 { 4765 const char code[] = "template <class T>\n" 4766 "void foo(typename T::t *)\n" 4767 "{ }"; 4768 4769 // The expected result.. 4770 const char expected[] = "template < class T > void foo ( T :: t * ) { }"; 4771 ASSERT_EQUALS(expected, tok(code)); 4772 } 4773 4774 { 4775 const char code[] = "void f() {\n" 4776 " x(sizeof typename);\n" 4777 " type = 0;\n" 4778 "}"; 4779 4780 ASSERT_EQUALS("void f ( ) { x ( sizeof ( typename ) ) ; type = 0 ; }", tok(code)); 4781 } 4782 } 4783 template_constructor()4784 void template_constructor() { 4785 // #3152 - if template constructor is removed then there might be 4786 // "no constructor" false positives 4787 const char code[] = "class Fred {\n" 4788 " template<class T> explicit Fred(T t) { }\n" 4789 "}"; 4790 ASSERT_EQUALS("class Fred { template < class T > explicit Fred ( T t ) { } }", tok(code)); 4791 4792 // #3532 4793 const char code2[] = "class Fred {\n" 4794 " template<class T> Fred(T t) { }\n" 4795 "}"; 4796 ASSERT_EQUALS("class Fred { template < class T > Fred ( T t ) { } }", tok(code2)); 4797 } 4798 syntax_error_templates_1()4799 void syntax_error_templates_1() { 4800 // ok code.. using ">" for a comparison 4801 tok("x<y>z> xyz;"); 4802 ASSERT_EQUALS("", errout.str()); 4803 4804 // ok code 4805 tok("template<class T> operator<(T a, T b) { }"); 4806 ASSERT_EQUALS("", errout.str()); 4807 4808 // ok code (ticket #1984) 4809 tok("void f(a) int a;\n" 4810 "{ ;x<y; }"); 4811 ASSERT_EQUALS("", errout.str()); 4812 4813 // ok code (ticket #1985) 4814 tok("void f()\n" 4815 "{ try { ;x<y; } }"); 4816 ASSERT_EQUALS("", errout.str()); 4817 4818 // ok code (ticket #3183) 4819 tok("MACRO(({ i < x }))"); 4820 ASSERT_EQUALS("", errout.str()); 4821 4822 // bad code.. missing ">" 4823 ASSERT_THROW(tok("x<y<int> xyz;\n"), InternalError); 4824 4825 // bad code 4826 ASSERT_THROW(tok("typedef\n" 4827 " typename boost::mpl::if_c<\n" 4828 " _visitableIndex < boost::mpl::size< typename _Visitables::ConcreteVisitables >::value\n" 4829 " , ConcreteVisitable\n" 4830 " , Dummy< _visitableIndex >\n" 4831 " >::type ConcreteVisitableOrDummy;\n"), InternalError); 4832 4833 // code is ok, don't show syntax error 4834 tok("struct A {int a;int b};\n" 4835 "class Fred {" 4836 "public:\n" 4837 " Fred() : a({1,2}) {\n" 4838 " for (int i=0;i<6;i++);\n" // <- no syntax error 4839 " }\n" 4840 "private:\n" 4841 " A a;\n" 4842 "};"); 4843 ASSERT_EQUALS("", errout.str()); 4844 4845 //both of these should work but in cppcheck 2.1 only the first option will work (ticket #9843) 4846 { 4847 const std::string expected = "template < long Num > constexpr bool foo < bar < Num > > = true ;"; 4848 ASSERT_EQUALS(expected, 4849 tok("template <long Num>\n" 4850 "constexpr bool foo<bar<Num> > = true;\n")); 4851 ASSERT_EQUALS("", errout.str()); 4852 ASSERT_EQUALS(expected, 4853 tok("template <long Num>\n" 4854 "constexpr bool foo<bar<Num>> = true;\n")); 4855 ASSERT_EQUALS("", errout.str()); 4856 } 4857 } 4858 template_member_ptr()4859 void template_member_ptr() { // Ticket #5786 4860 tok("struct A {}; " 4861 "struct B { " 4862 "template <void (A::*)() const> struct BB {}; " 4863 "template <bool BT> static bool foo(int) { return true; } " 4864 "void bar() { bool b = foo<true>(0); }" 4865 "};"); 4866 tok("struct A {}; " 4867 "struct B { " 4868 "template <void (A::*)() volatile> struct BB {}; " 4869 "template <bool BT> static bool foo(int) { return true; } " 4870 "void bar() { bool b = foo<true>(0); }" 4871 "};"); 4872 tok("struct A {}; " 4873 "struct B { " 4874 "template <void (A::*)() const volatile> struct BB {}; " 4875 "template <bool BT> static bool foo(int) { return true; } " 4876 "void bar() { bool b = foo<true>(0); }" 4877 "};"); 4878 tok("struct A {}; " 4879 "struct B { " 4880 "template <void (A::*)() volatile const> struct BB {}; " 4881 "template <bool BT> static bool foo(int) { return true; } " 4882 "void bar() { bool b = foo<true>(0); }" 4883 "};"); 4884 } 4885 template_namespace_1()4886 void template_namespace_1() { 4887 // #6570 4888 const char code[] = "namespace {\n" 4889 " template<class T> void Fred(T value) { }\n" 4890 "}\n" 4891 "Fred<int>(123);"; 4892 ASSERT_EQUALS("namespace { " 4893 "void Fred<int> ( int value ) ; " 4894 "} " 4895 "Fred<int> ( 123 ) ; " 4896 "void Fred<int> ( int value ) { }", tok(code)); 4897 } 4898 template_namespace_2()4899 void template_namespace_2() { 4900 // #8283 4901 const char code[] = "namespace X {\n" 4902 " template<class T> struct S { };\n" 4903 "}\n" 4904 "X::S<int> s;"; 4905 ASSERT_EQUALS("namespace X { " 4906 "struct S<int> ; " 4907 "} " 4908 "X :: S<int> s ; " 4909 "struct X :: S<int> { } ;", tok(code)); 4910 } 4911 template_namespace_3()4912 void template_namespace_3() { 4913 const char code[] = "namespace test16 {\n" 4914 " template <class T> struct foo {\n" 4915 " static void *bar();\n" 4916 " };\n" 4917 " void *test() { return foo<int>::bar(); }\n" 4918 "}"; 4919 ASSERT_EQUALS("namespace test16 {" 4920 " struct foo<int> ;" 4921 " void * test ( ) {" 4922 " return foo<int> :: bar ( ) ;" 4923 " } " 4924 "} " 4925 "struct test16 :: foo<int> {" 4926 " static void * bar ( ) ; " 4927 "} ;", tok(code)); 4928 } 4929 template_namespace_4()4930 void template_namespace_4() { 4931 const char code[] = "namespace foo {\n" 4932 " template<class T> class A { void dostuff() {} };\n" 4933 " struct S : public A<int> {\n" 4934 " void f() {\n" 4935 " A<int>::dostuff();\n" 4936 " }\n" 4937 " };\n" 4938 "}"; 4939 ASSERT_EQUALS("namespace foo {" 4940 " class A<int> ;" 4941 " struct S : public A<int> {" 4942 " void f ( ) {" 4943 " A<int> :: dostuff ( ) ;" 4944 " }" 4945 " } ; " 4946 "} " 4947 "class foo :: A<int> { void dostuff ( ) { } } ;", tok(code)); 4948 } 4949 template_namespace_5()4950 void template_namespace_5() { 4951 const char code[] = "template<class C> struct S {};\n" 4952 "namespace X { S<int> s; }"; 4953 ASSERT_EQUALS("struct S<int> ; " 4954 "namespace X { S<int> s ; } " 4955 "struct S<int> { } ;", tok(code)); 4956 } 4957 template_namespace_6()4958 void template_namespace_6() { 4959 const char code[] = "namespace NS {\n" 4960 "template <typename T> union C {\n" 4961 " char dummy[sizeof(T)];\n" 4962 " T value;\n" 4963 " C();\n" 4964 " ~C();\n" 4965 " C(const C &);\n" 4966 " C & operator = (const C &);\n" 4967 "};\n" 4968 "}\n" 4969 "NS::C<int> intC;\n" 4970 "template <typename T> NS::C<T>::C() {}\n" 4971 "template <typename T> NS::C<T>::~C() {}\n" 4972 "template <typename T> NS::C<T>::C(const NS::C<T> &) {}\n" 4973 "template <typename T> NS::C<T> & NS::C<T>::operator=(const NS::C<T> &) {}"; 4974 ASSERT_EQUALS("namespace NS { " 4975 "union C<int> ; " 4976 "} " 4977 "NS :: C<int> intC ; union NS :: C<int> { " 4978 "char dummy [ sizeof ( int ) ] ; " 4979 "int value ; " 4980 "C<int> ( ) ; " 4981 "~ C<int> ( ) ; " 4982 "C<int> ( const NS :: C<int> & ) ; " 4983 "NS :: C<int> & operator= ( const NS :: C<int> & ) ; " 4984 "} ; " 4985 "NS :: C<int> :: C<int> ( ) { } " 4986 "NS :: C<int> :: ~ C<int> ( ) { } " 4987 "NS :: C<int> :: C<int> ( const NS :: C<int> & ) { } " 4988 "NS :: C<int> & NS :: C<int> :: operator= ( const NS :: C<int> & ) { }", tok(code)); 4989 } 4990 template_namespace_7()4991 void template_namespace_7() { // #8768 4992 const char code[] = "namespace N1 {\n" 4993 "namespace N2 {\n" 4994 " struct C { };\n" 4995 " template <class T> struct CT { };\n" 4996 " C c1;\n" 4997 " CT<int> ct1;\n" 4998 "}\n" 4999 "N2::C c2;\n" 5000 "N2::CT<int> ct2;\n" 5001 "}\n" 5002 "N1::N2::C c3;\n" 5003 "N1::N2::CT<int> ct3;"; 5004 ASSERT_EQUALS("namespace N1 { " 5005 "namespace N2 { " 5006 "struct C { } ; " 5007 "struct CT<int> ; " 5008 "C c1 ; " 5009 "CT<int> ct1 ; " 5010 "} " 5011 "N2 :: C c2 ; " 5012 "N2 :: CT<int> ct2 ; " 5013 "} " 5014 "N1 :: N2 :: C c3 ; " 5015 "N1 :: N2 :: CT<int> ct3 ; struct N1 :: N2 :: CT<int> { } ;", tok(code)); 5016 } 5017 template_namespace_8()5018 void template_namespace_8() { // #8768 5019 const char code[] = "namespace NS1 {\n" 5020 "namespace NS2 {\n" 5021 " template <typename T>\n" 5022 " struct Fred {\n" 5023 " Fred();\n" 5024 " Fred(const Fred &);\n" 5025 " Fred & operator = (const Fred &);\n" 5026 " ~Fred();\n" 5027 " };\n" 5028 " template <typename T>\n" 5029 " Fred<T>::Fred() { }\n" 5030 " template <typename T>\n" 5031 " Fred<T>::Fred(const Fred<T> & f) { }\n" 5032 " template <typename T>\n" 5033 " Fred<T> & Fred<T>::operator = (const Fred<T> & f) { }\n" 5034 " template <typename T>\n" 5035 " Fred<T>::~Fred() { }\n" 5036 "}\n" 5037 "}\n" 5038 "NS1::NS2::Fred<int> fred;"; 5039 ASSERT_EQUALS("namespace NS1 { " 5040 "namespace NS2 { " 5041 "struct Fred<int> ; " 5042 "} " 5043 "} " 5044 "NS1 :: NS2 :: Fred<int> fred ; struct NS1 :: NS2 :: Fred<int> { " 5045 "Fred<int> ( ) ; " 5046 "Fred<int> ( const NS1 :: NS2 :: Fred<int> & ) ; " 5047 "NS1 :: NS2 :: Fred<int> & operator= ( const NS1 :: NS2 :: Fred<int> & ) ; " 5048 "~ Fred<int> ( ) ; " 5049 "} ; " 5050 "NS1 :: NS2 :: Fred<int> :: Fred<int> ( ) { } " 5051 "NS1 :: NS2 :: Fred<int> :: Fred<int> ( const NS1 :: NS2 :: Fred<int> & f ) { } " 5052 "NS1 :: NS2 :: Fred<int> & NS1 :: NS2 :: Fred<int> :: operator= ( const NS1 :: NS2 :: Fred<int> & f ) { } " 5053 "NS1 :: NS2 :: Fred<int> :: ~ Fred<int> ( ) { }", tok(code)); 5054 } 5055 template_namespace_9()5056 void template_namespace_9() { 5057 const char code[] = "namespace NS {\n" 5058 "template<int type> struct Barney;\n" 5059 "template<> struct Barney<1> { };\n" 5060 "template<int type>\n" 5061 "class Fred {\n" 5062 "public:\n" 5063 " Fred();\n" 5064 "private:\n" 5065 " Barney<type> m_data;\n" 5066 "};\n" 5067 "template class Fred<1>;\n" 5068 "}\n"; 5069 ASSERT_EQUALS("namespace NS { " 5070 "struct Barney<1> ; " 5071 "template < int type > struct Barney ; " 5072 "struct Barney<1> { } ; " 5073 "class Fred<1> ; " 5074 "} " 5075 "class NS :: Fred<1> { " 5076 "public: " 5077 "Fred<1> ( ) ; " 5078 "private: " 5079 "Barney<1> m_data ; " 5080 "} ;", tok(code)); 5081 } 5082 template_namespace_10()5083 void template_namespace_10() { 5084 const char code[] = "namespace NS1 {\n" 5085 "namespace NS2 {\n" 5086 "template<class T>\n" 5087 "class Fred {\n" 5088 " T * t;\n" 5089 "public:\n" 5090 " Fred<T>() : t(nullptr) {}\n" 5091 "};\n" 5092 "}\n" 5093 "}\n" 5094 "NS1::NS2::Fred<int> fred;"; 5095 ASSERT_EQUALS("namespace NS1 { " 5096 "namespace NS2 { " 5097 "class Fred<int> ; " 5098 "} " 5099 "} " 5100 "NS1 :: NS2 :: Fred<int> fred ; class NS1 :: NS2 :: Fred<int> " 5101 "{ " 5102 "int * t ; " 5103 "public: " 5104 "Fred<int> ( ) : t ( nullptr ) { } " 5105 "} ;", tok(code)); 5106 } 5107 template_namespace_11()5108 void template_namespace_11() {// #7145 5109 const char code[] = "namespace MyNamespace {\n" 5110 "class TestClass {\n" 5111 "public:\n" 5112 " TestClass() {\n" 5113 " SomeFunction();\n" 5114 " TemplatedMethod< int >( 0 );\n" 5115 " }\n" 5116 " void SomeFunction() { }\n" 5117 "private:\n" 5118 " template< typename T > T TemplatedMethod(T);\n" 5119 "};\n" 5120 "template< typename T > T TestClass::TemplatedMethod(T t) { return t; }\n" 5121 "}"; 5122 ASSERT_EQUALS("namespace MyNamespace { " 5123 "class TestClass { " 5124 "public: " 5125 "TestClass ( ) { " 5126 "SomeFunction ( ) ; " 5127 "TemplatedMethod<int> ( 0 ) ; " 5128 "} " 5129 "void SomeFunction ( ) { } " 5130 "private: " 5131 "int TemplatedMethod<int> ( int ) ; " 5132 "} ; " 5133 "} int MyNamespace :: TestClass :: TemplatedMethod<int> ( int t ) { return t ; }", tok(code)); 5134 } 5135 template_pointer_type()5136 void template_pointer_type() { 5137 const char code[] = "template<class T> void foo(const T x) {}\n" 5138 "void bar() { foo<int*>(0); }"; 5139 ASSERT_EQUALS("void foo<int*> ( int * const x ) ; " 5140 "void bar ( ) { foo<int*> ( 0 ) ; } " 5141 "void foo<int*> ( int * const x ) { }", tok(code)); 5142 } 5143 template_array_type()5144 void template_array_type() { 5145 ASSERT_EQUALS("void foo<int[]> ( int [ ] x ) ; " 5146 "void bar ( ) { int [ 3 ] y ; foo<int[]> ( y ) ; } " 5147 "void foo<int[]> ( int [ ] x ) { } ;", 5148 tok("template <class T> void foo(T x) {};\n" 5149 "void bar() {\n" 5150 " int[3] y;\n" 5151 " foo<int[]>(y);\n" 5152 "}")); 5153 ASSERT_EQUALS("struct A<int[2]> ; " 5154 "A<int[2]> y ; " 5155 "struct A<int[2]> { int [ 2 ] x ; } ;", 5156 tok("template <class T> struct A { T x; };\n" 5157 "A<int[2]> y;")); 5158 5159 // Previously resulted in: 5160 // test.cpp:2:33: error: Syntax Error: AST broken, binary operator '>' doesn't have two operands. [internalAstError] 5161 ASSERT_EQUALS("struct A<B<int>[]> ; " 5162 "struct B<B<int>> ; " 5163 "struct C<B<int>> ; " 5164 "C<B<int>> y ; " 5165 "struct C<B<int>> : B<B<int>> { } ; " 5166 "struct B<B<int>> { A<B<int>[]> x ; } ; " 5167 "struct A<B<int>[]> { } ;", 5168 tok("template <class > struct A {};\n" 5169 "template <class T> struct B { A<T[]> x; };\n" 5170 "template <class T> struct C : B<T> {};\n" 5171 "C<B<int>> y;")); 5172 } 5173 templateParameters(const char code[])5174 unsigned int templateParameters(const char code[]) { 5175 Tokenizer tokenizer(&settings, this); 5176 5177 std::istringstream istr(code); 5178 tokenizer.createTokens(istr, "test.cpp"); 5179 tokenizer.createLinks(); 5180 tokenizer.splitTemplateRightAngleBrackets(false); 5181 5182 for (const Token *tok1 = tokenizer.tokens(); tok1; tok1 = tok1->next()) { 5183 if (tok1->str() == "var1") 5184 (const_cast<Token *>(tok1))->varId(1); 5185 } 5186 5187 return TemplateSimplifier::templateParameters(tokenizer.tokens()->next()); 5188 } 5189 templateParameters()5190 void templateParameters() { 5191 // Test that the function TemplateSimplifier::templateParameters works 5192 ASSERT_EQUALS(1U, templateParameters("X<struct C> x;")); 5193 ASSERT_EQUALS(1U, templateParameters("X<union C> x;")); 5194 ASSERT_EQUALS(1U, templateParameters("X<const int> x;")); 5195 ASSERT_EQUALS(1U, templateParameters("X<int const *> x;")); 5196 ASSERT_EQUALS(1U, templateParameters("X<const struct C> x;")); 5197 ASSERT_EQUALS(0U, templateParameters("X<len>>x;")); 5198 ASSERT_EQUALS(1U, templateParameters("X<typename> x;")); 5199 ASSERT_EQUALS(0U, templateParameters("X<...> x;")); 5200 ASSERT_EQUALS(0U, templateParameters("X<class T...> x;")); // Invalid syntax 5201 ASSERT_EQUALS(1U, templateParameters("X<class... T> x;")); 5202 ASSERT_EQUALS(0U, templateParameters("X<class, typename T...> x;")); // Invalid syntax 5203 ASSERT_EQUALS(2U, templateParameters("X<class, typename... T> x;")); 5204 ASSERT_EQUALS(2U, templateParameters("X<int(&)(), class> x;")); 5205 ASSERT_EQUALS(3U, templateParameters("X<char, int(*)(), bool> x;")); 5206 ASSERT_EQUALS(1U, templateParameters("X<int...> x;")); 5207 ASSERT_EQUALS(2U, templateParameters("X<class, typename...> x;")); 5208 ASSERT_EQUALS(2U, templateParameters("X<1, T> x;")); 5209 ASSERT_EQUALS(1U, templateParameters("X<T[]> x;")); 5210 ASSERT_EQUALS(1U, templateParameters("X<T[2]> x;")); 5211 ASSERT_EQUALS(1U, templateParameters("X<i == 0> x;")); 5212 ASSERT_EQUALS(2U, templateParameters("X<int, i>=0> x;")); 5213 ASSERT_EQUALS(3U, templateParameters("X<int, i>=0, i - 2> x;")); 5214 ASSERT_EQUALS(0U, templateParameters("var1<1> x;")); 5215 ASSERT_EQUALS(0U, templateParameters("X<1>2;")); 5216 ASSERT_EQUALS(2U, templateParameters("template<typename...B,typename=SameSize<B...>> x;")); 5217 ASSERT_EQUALS(2U, templateParameters("template<typename...B,typename=SameSize<B...> > x;")); 5218 ASSERT_EQUALS(1U, templateParameters("template<template<typename>...Foo> x;")); 5219 ASSERT_EQUALS(1U, templateParameters("template<template<typename>> x;")); 5220 ASSERT_EQUALS(1U, templateParameters("template<template<template<typename>>> x;")); 5221 ASSERT_EQUALS(1U, templateParameters("template<template<template<template<typename>>>> x;")); 5222 ASSERT_EQUALS(1U, templateParameters("template<template<template<template<template<typename>>>>> x;")); 5223 ASSERT_EQUALS(2U, templateParameters("template<template<typename>,int> x;")); 5224 ASSERT_EQUALS(2U, templateParameters("template<template<template<typename>>,int> x;")); 5225 ASSERT_EQUALS(2U, templateParameters("template<template<template<template<typename>>>,int> x;")); 5226 ASSERT_EQUALS(2U, templateParameters("template<template<template<template<template<typename>>>>,int> x;")); 5227 ASSERT_EQUALS(2U, templateParameters("template<template<typename>...Foo,template<template<template<typename>>>> x;")); 5228 ASSERT_EQUALS(3U, templateParameters("template<template<typename>...Foo,int,template<template<template<typename>>>> x;")); 5229 ASSERT_EQUALS(4U, templateParameters("template<template<typename>...Foo,int,template<template<template<typename>>>,int> x;")); 5230 ASSERT_EQUALS(2U, templateParameters("template<typename S, enable_if_t<(is_compile_string<S>::value), int>> void i(S s);")); 5231 ASSERT_EQUALS(2U, templateParameters("template<typename c, b<(c::d), int>> void e();")); 5232 } 5233 5234 // Helper function to unit test TemplateSimplifier::getTemplateNamePosition templateNamePositionHelper(const char code[],unsigned offset=0)5235 int templateNamePositionHelper(const char code[], unsigned offset = 0) { 5236 Tokenizer tokenizer(&settings, this); 5237 5238 std::istringstream istr(code); 5239 tokenizer.createTokens(istr, "test.cpp"); 5240 tokenizer.createLinks(); 5241 tokenizer.splitTemplateRightAngleBrackets(false); 5242 5243 const Token *_tok = tokenizer.tokens(); 5244 for (unsigned i = 0; i < offset; ++i) 5245 _tok = _tok->next(); 5246 return tokenizer.mTemplateSimplifier->getTemplateNamePosition(_tok); 5247 } 5248 templateNamePosition()5249 void templateNamePosition() { 5250 // Template class 5251 ASSERT_EQUALS(2, templateNamePositionHelper("template<class T> class A {};", 4)); 5252 ASSERT_EQUALS(2, templateNamePositionHelper("template<class T> struct A {};", 4)); 5253 ASSERT_EQUALS(2, templateNamePositionHelper("template<class T> class A : B {};", 4)); 5254 ASSERT_EQUALS(2, templateNamePositionHelper("template<class T> struct A : B {};", 4)); 5255 // Template function definitions 5256 ASSERT_EQUALS(2, templateNamePositionHelper("template<class T> unsigned foo() { return 0; }", 4)); 5257 ASSERT_EQUALS(3, templateNamePositionHelper("template<class T> unsigned* foo() { return 0; }", 4)); 5258 ASSERT_EQUALS(4, templateNamePositionHelper("template<class T> unsigned** foo() { return 0; }", 4)); 5259 5260 ASSERT_EQUALS(3, templateNamePositionHelper("template<class T> const unsigned foo() { return 0; }", 4)); 5261 ASSERT_EQUALS(4, templateNamePositionHelper("template<class T> const unsigned& foo() { return 0; }", 4)); 5262 ASSERT_EQUALS(5, templateNamePositionHelper("template<class T> const unsigned** foo() { return 0; }", 4)); 5263 5264 ASSERT_EQUALS(4, templateNamePositionHelper("template<class T> std::string foo() { static str::string str; return str; }", 4)); 5265 ASSERT_EQUALS(5, templateNamePositionHelper("template<class T> std::string & foo() { static str::string str; return str; }", 4)); 5266 ASSERT_EQUALS(6, templateNamePositionHelper("template<class T> const std::string & foo() { static str::string str; return str; }", 4)); 5267 5268 ASSERT_EQUALS(9, templateNamePositionHelper("template<class T> std::map<int, int> foo() { static std::map<int, int> m; return m; }", 4)); 5269 ASSERT_EQUALS(10, templateNamePositionHelper("template<class T> std::map<int, int> & foo() { static std::map<int, int> m; return m; }", 4)); 5270 ASSERT_EQUALS(11, templateNamePositionHelper("template<class T> const std::map<int, int> & foo() { static std::map<int, int> m; return m; }", 4)); 5271 // Class template members 5272 ASSERT_EQUALS(4, templateNamePositionHelper( 5273 "class A { template<class T> unsigned foo(); }; " 5274 "template<class T> unsigned A::foo() { return 0; }", 19)); 5275 ASSERT_EQUALS(5, templateNamePositionHelper( 5276 "class A { template<class T> const unsigned foo(); }; " 5277 "template<class T> const unsigned A::foo() { return 0; }", 20)); 5278 ASSERT_EQUALS(7, templateNamePositionHelper( 5279 "class A { class B { template<class T> const unsigned foo(); }; } ; " 5280 "template<class T> const unsigned A::B::foo() { return 0; }", 25)); 5281 ASSERT_EQUALS(8, templateNamePositionHelper( 5282 "class A { class B { template<class T> const unsigned * foo(); }; } ; " 5283 "template<class T> const unsigned * A::B::foo() { return 0; }", 26)); 5284 ASSERT_EQUALS(9, templateNamePositionHelper( 5285 "class A { class B { template<class T> const unsigned ** foo(); }; } ; " 5286 "template<class T> const unsigned ** A::B::foo() { return 0; }", 27)); 5287 // Template class member 5288 ASSERT_EQUALS(6, templateNamePositionHelper( 5289 "template<class T> class A { A(); }; " 5290 "template<class T> A<T>::A() {}", 18)); 5291 ASSERT_EQUALS(8, templateNamePositionHelper( 5292 "template<class T, class U> class A { A(); }; " 5293 "template<class T, class U> A<T, U>::A() {}", 24)); 5294 ASSERT_EQUALS(7, templateNamePositionHelper( 5295 "template<class T> class A { unsigned foo(); }; " 5296 "template<class T> unsigned A<T>::foo() { return 0; }", 19)); 5297 ASSERT_EQUALS(9, templateNamePositionHelper( 5298 "template<class T, class U> class A { unsigned foo(); }; " 5299 "template<class T, class U> unsigned A<T, U>::foo() { return 0; }", 25)); 5300 ASSERT_EQUALS(12, templateNamePositionHelper( 5301 "template<> unsigned A<int, v<char> >::foo() { return 0; }", 2)); 5302 } 5303 5304 // Helper function to unit test TemplateSimplifier::findTemplateDeclarationEnd findTemplateDeclarationEndHelper(const char code[],const char pattern[],unsigned offset=0)5305 bool findTemplateDeclarationEndHelper(const char code[], const char pattern[], unsigned offset = 0) { 5306 Tokenizer tokenizer(&settings, this); 5307 5308 std::istringstream istr(code); 5309 tokenizer.createTokens(istr, "test.cpp"); 5310 tokenizer.createLinks(); 5311 tokenizer.splitTemplateRightAngleBrackets(false); 5312 5313 const Token *_tok = tokenizer.tokens(); 5314 for (unsigned i = 0; i < offset; ++i) 5315 _tok = _tok->next(); 5316 5317 const Token *tok1 = TemplateSimplifier::findTemplateDeclarationEnd(_tok); 5318 5319 return (tok1 == Token::findsimplematch(tokenizer.list.front(), pattern, strlen(pattern))); 5320 } 5321 findTemplateDeclarationEnd()5322 void findTemplateDeclarationEnd() { 5323 ASSERT(findTemplateDeclarationEndHelper("template <typename T> class Fred { }; int x;", "; int x ;")); 5324 ASSERT(findTemplateDeclarationEndHelper("template <typename T> void Fred() { } int x;", "} int x ;")); 5325 ASSERT(findTemplateDeclarationEndHelper("template <typename T> int Fred = 0; int x;", "; int x ;")); 5326 ASSERT(findTemplateDeclarationEndHelper("template <typename T> constexpr auto func = [](auto x){ return T(x);}; int x;", "; int x ;")); 5327 ASSERT(findTemplateDeclarationEndHelper("template <class, class a> auto b() -> decltype(a{}.template b<void(int, int)>); int x;", "; int x ;")); 5328 ASSERT(findTemplateDeclarationEndHelper("template <class, class a> auto b() -> decltype(a{}.template b<void(int, int)>){} int x;", "} int x ;")); 5329 ASSERT(findTemplateDeclarationEndHelper("template <typename... f, c<h<e<typename f::d...>>::g>> void i(); int x;", "; int x ;")); 5330 ASSERT(findTemplateDeclarationEndHelper("template <typename... f, c<h<e<typename f::d...>>::g>> void i(){} int x;", "} int x ;")); 5331 } 5332 5333 // Helper function to unit test TemplateSimplifier::getTemplateParametersInDeclaration getTemplateParametersInDeclarationHelper(const char code[],const std::vector<std::string> & params)5334 bool getTemplateParametersInDeclarationHelper(const char code[], const std::vector<std::string> & params) { 5335 Tokenizer tokenizer(&settings, this); 5336 5337 std::istringstream istr(code); 5338 tokenizer.createTokens(istr, "test.cpp"); 5339 tokenizer.createLinks(); 5340 tokenizer.splitTemplateRightAngleBrackets(false); 5341 5342 std::vector<const Token *> typeParametersInDeclaration; 5343 TemplateSimplifier::getTemplateParametersInDeclaration(tokenizer.tokens()->tokAt(2), typeParametersInDeclaration); 5344 5345 if (params.size() != typeParametersInDeclaration.size()) 5346 return false; 5347 5348 for (size_t i = 0; i < typeParametersInDeclaration.size(); ++i) { 5349 if (typeParametersInDeclaration[i]->str() != params[i]) 5350 return false; 5351 } 5352 return true; 5353 } 5354 getTemplateParametersInDeclaration()5355 void getTemplateParametersInDeclaration() { 5356 ASSERT(getTemplateParametersInDeclarationHelper("template<typename T> class Fred {};", std::vector<std::string> {"T"})); 5357 ASSERT(getTemplateParametersInDeclarationHelper("template<typename T=int> class Fred {};", std::vector<std::string> {"T"})); 5358 ASSERT(getTemplateParametersInDeclarationHelper("template<typename T,typename U> class Fred {};", std::vector<std::string> {"T","U"})); 5359 ASSERT(getTemplateParametersInDeclarationHelper("template<typename T,typename U=int> class Fred {};", std::vector<std::string> {"T","U"})); 5360 ASSERT(getTemplateParametersInDeclarationHelper("template<typename T=int,typename U=int> class Fred {};", std::vector<std::string> {"T","U"})); 5361 } 5362 expandSpecialized1()5363 void expandSpecialized1() { 5364 ASSERT_EQUALS("class A<int> { } ;", tok("template<> class A<int> {};")); 5365 ASSERT_EQUALS("class A<int> : public B { } ;", tok("template<> class A<int> : public B {};")); 5366 ASSERT_EQUALS("class A<int> { A<int> ( ) ; ~ A<int> ( ) ; } ;", tok("template<> class A<int> { A(); ~A(); };")); 5367 ASSERT_EQUALS("class A<int> { A<int> ( ) { } ~ A<int> ( ) { } } ;", tok("template<> class A<int> { A() {} ~A() {} };")); 5368 ASSERT_EQUALS("class A<int> { A<int> ( ) ; ~ A<int> ( ) ; } ; A<int> :: A<int> ( ) { } ~ A<int> :: A<int> ( ) { }", 5369 tok("template<> class A<int> { A(); ~A(); }; A<int>::A() { } ~A<int>::A() {}")); 5370 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 ; }", 5371 tok("template<> class A<int> { A(); A(const A &) ; A foo(); }; A<int>::A() { } A<int>::A(const A &) { } A<int> A<int>::foo() { A a; return a; }")); 5372 } 5373 expandSpecialized2()5374 void expandSpecialized2() { 5375 { 5376 const char code[] = "template <>\n" 5377 "class C<float> {\n" 5378 "public:\n" 5379 " C() { }\n" 5380 " C(const C &) { }\n" 5381 " ~C() { }\n" 5382 " C & operator=(const C &) { return *this; }\n" 5383 "};\n" 5384 "C<float> b;\n"; 5385 const char expected[] = "class C<float> { " 5386 "public: " 5387 "C<float> ( ) { } " 5388 "C<float> ( const C<float> & ) { } " 5389 "~ C<float> ( ) { } " 5390 "C<float> & operator= ( const C<float> & ) { return * this ; } " 5391 "} ; " 5392 "C<float> b ;"; 5393 ASSERT_EQUALS(expected, tok(code)); 5394 } 5395 { 5396 const char code[] = "template <>\n" 5397 "class C<float> {\n" 5398 "public:\n" 5399 " C() { }\n" 5400 " C(const C &) { }\n" 5401 " ~C() { }\n" 5402 " C & operator=(const C &) { return *this; }\n" 5403 "};"; 5404 const char expected[] = "class C<float> { " 5405 "public: " 5406 "C<float> ( ) { } " 5407 "C<float> ( const C<float> & ) { } " 5408 "~ C<float> ( ) { } " 5409 "C<float> & operator= ( const C<float> & ) { return * this ; } " 5410 "} ;"; 5411 ASSERT_EQUALS(expected, tok(code)); 5412 } 5413 { 5414 const char code[] = "template <>\n" 5415 "class C<float> {\n" 5416 "public:\n" 5417 " C();\n" 5418 " C(const C &);\n" 5419 " ~C();\n" 5420 " C & operator=(const C &);\n" 5421 "};\n" 5422 "C::C() { }\n" 5423 "C::C(const C &) { }\n" 5424 "C::~C() { }\n" 5425 "C & C::operator=(const C &) { return *this; }\n" 5426 "C<float> b;\n"; 5427 const char expected[] = "class C<float> { " 5428 "public: " 5429 "C<float> ( ) ; " 5430 "C<float> ( const C<float> & ) ; " 5431 "~ C<float> ( ) ; " 5432 "C<float> & operator= ( const C<float> & ) ; " 5433 "} ; " 5434 "C<float> :: C<float> ( ) { } " 5435 "C<float> :: C<float> ( const C<float> & ) { } " 5436 "C<float> :: ~ C<float> ( ) { } " 5437 "C<float> & C<float> :: operator= ( const C<float> & ) { return * this ; } " 5438 "C<float> b ;"; 5439 ASSERT_EQUALS(expected, tok(code)); 5440 } 5441 { 5442 const char code[] = "template <>\n" 5443 "class C<float> {\n" 5444 "public:\n" 5445 " C();\n" 5446 " C(const C &);\n" 5447 " ~C();\n" 5448 " C & operator=(const C &);\n" 5449 "};\n" 5450 "C::C() { }\n" 5451 "C::C(const C &) { }\n" 5452 "C::~C() { }\n" 5453 "C & C::operator=(const C &) { return *this; }"; 5454 const char expected[] = "class C<float> { " 5455 "public: " 5456 "C<float> ( ) ; " 5457 "C<float> ( const C<float> & ) ; " 5458 "~ C<float> ( ) ; " 5459 "C<float> & operator= ( const C<float> & ) ; " 5460 "} ; " 5461 "C<float> :: C<float> ( ) { } " 5462 "C<float> :: C<float> ( const C<float> & ) { } " 5463 "C<float> :: ~ C<float> ( ) { } " 5464 "C<float> & C<float> :: operator= ( const C<float> & ) { return * this ; }"; 5465 ASSERT_EQUALS(expected, tok(code)); 5466 } 5467 } 5468 expandSpecialized3()5469 void expandSpecialized3() { // #8671 5470 const char code[] = "template <> struct OutputU16<unsigned char> final {\n" 5471 " explicit OutputU16(std::basic_ostream<unsigned char> &t) : outputStream_(t) {}\n" 5472 " void operator()(unsigned short) const;\n" 5473 "private:\n" 5474 " std::basic_ostream<unsigned char> &outputStream_;\n" 5475 "};"; 5476 const char expected[] = "struct OutputU16<unsignedchar> final { " 5477 "explicit OutputU16<unsignedchar> ( std :: basic_ostream < unsigned char > & t ) : outputStream_ ( t ) { } " 5478 "void operator() ( unsigned short ) const ; " 5479 "private: " 5480 "std :: basic_ostream < unsigned char > & outputStream_ ; " 5481 "} ;"; 5482 ASSERT_EQUALS(expected, tok(code)); 5483 } 5484 expandSpecialized4()5485 void expandSpecialized4() { 5486 { 5487 const char code[] = "template<> class C<char> { };\n" 5488 "map<int> m;"; 5489 const char expected[] = "class C<char> { } ; " 5490 "map < int > m ;"; 5491 ASSERT_EQUALS(expected, tok(code)); 5492 } 5493 { 5494 const char code[] = "template<> class C<char> { };\n" 5495 "map<int> m;\n" 5496 "C<char> c;"; 5497 const char expected[] = "class C<char> { } ; " 5498 "map < int > m ; " 5499 "C<char> c ;"; 5500 ASSERT_EQUALS(expected, tok(code)); 5501 } 5502 { 5503 const char code[] = "template<typename T> class C { };\n" 5504 "template<> class C<char> { };\n" 5505 "map<int> m;\n"; 5506 const char expected[] = "class C<char> ; " 5507 "template < typename T > class C { } ; " 5508 "class C<char> { } ; " 5509 "map < int > m ;"; 5510 ASSERT_EQUALS(expected, tok(code)); 5511 } 5512 { 5513 const char code[] = "template<typename T> class C { };\n" 5514 "template<> class C<char> { };\n" 5515 "map<int> m;\n" 5516 "C<int> i;"; 5517 const char expected[] = "class C<char> ; " 5518 "class C<int> ; " 5519 "class C<char> { } ; " 5520 "map < int > m ; " 5521 "C<int> i ; " 5522 "class C<int> { } ;"; 5523 ASSERT_EQUALS(expected, tok(code)); 5524 } 5525 { 5526 const char code[] = "template<typename T> class C { };\n" 5527 "template<> class C<char> { };\n" 5528 "map<int> m;\n" 5529 "C<int> i;\n" 5530 "C<char> c;"; 5531 const char expected[] = "class C<char> ; " 5532 "class C<int> ; " 5533 "class C<char> { } ; " 5534 "map < int > m ; " 5535 "C<int> i ; " 5536 "C<char> c ; " 5537 "class C<int> { } ;"; 5538 ASSERT_EQUALS(expected, tok(code)); 5539 } 5540 } 5541 templateAlias1()5542 void templateAlias1() { 5543 const char code[] = "template<class T, int N> struct Foo {};\n" 5544 "template<class T> using Bar = Foo<T,3>;\n" 5545 "Bar<int> b;\n"; 5546 5547 const char expected[] = "struct Foo<int,3> ; " 5548 "Foo<int,3> b ; " 5549 "struct Foo<int,3> { } ;"; 5550 5551 ASSERT_EQUALS(expected, tok(code)); 5552 } 5553 templateAlias2()5554 void templateAlias2() { 5555 const char code[] = "namespace A { template<class T, int N> struct Foo {}; }\n" 5556 "template<class T> using Bar = A::Foo<T,3>;\n" 5557 "Bar<int> b;\n"; 5558 5559 const char expected[] = "namespace A { struct Foo<int,3> ; } " 5560 "A :: Foo<int,3> b ; " 5561 "struct A :: Foo<int,3> { } ;"; 5562 5563 ASSERT_EQUALS(expected, tok(code)); 5564 } 5565 templateAlias3()5566 void templateAlias3() { // #8315 5567 const char code[] = "template <int> struct Tag {};\n" 5568 "template <int ID> using SPtr = std::shared_ptr<void(Tag<ID>)>;\n" 5569 "SPtr<0> s;"; 5570 const char expected[] = "struct Tag<0> ; " 5571 "std :: shared_ptr < void ( Tag<0> ) > s ; " 5572 "struct Tag<0> { } ;"; 5573 ASSERT_EQUALS(expected, tok(code)); 5574 } 5575 templateAlias4()5576 void templateAlias4() { // #9070 5577 const char code[] = "template <class T>\n" 5578 "using IntrusivePtr = boost::intrusive_ptr<T>;\n" 5579 "template <class T> class Vertex { };\n" 5580 "IntrusivePtr<Vertex<int>> p;"; 5581 const char expected[] = "class Vertex<int> ; " 5582 "boost :: intrusive_ptr < Vertex<int> > p ; " 5583 "class Vertex<int> { } ;"; 5584 ASSERT_EQUALS(expected, tok(code)); 5585 } 5586 templateAlias5()5587 void templateAlias5() { 5588 const char code[] = "template<typename T> using A = int;\n" 5589 "template<typename T> using B = T;\n" 5590 "A<char> a;\n" 5591 "B<char> b;"; 5592 const char expected[] = "int a ; " 5593 "char b ;"; 5594 ASSERT_EQUALS(expected, tok(code)); 5595 } 5596 instantiateMatch(const char code[],const std::size_t numberOfArguments,const char patternAfter[])5597 bool instantiateMatch(const char code[], const std::size_t numberOfArguments, const char patternAfter[]) { 5598 Tokenizer tokenizer(&settings, this); 5599 5600 std::istringstream istr(code); 5601 tokenizer.tokenize(istr, "test.cpp", ""); 5602 5603 return TemplateSimplifier::instantiateMatch(tokenizer.tokens(), numberOfArguments, false, patternAfter); 5604 } 5605 instantiateMatch()5606 void instantiateMatch() { 5607 // Ticket #8175 5608 ASSERT_EQUALS(false, 5609 instantiateMatch("ConvertHelper < From, To > c ;", 5610 2, ":: %name% (")); 5611 ASSERT_EQUALS(true, 5612 instantiateMatch("ConvertHelper < From, To > :: Create ( ) ;", 5613 2, ":: %name% (")); 5614 ASSERT_EQUALS(false, 5615 instantiateMatch("integral_constant < bool, sizeof ( ConvertHelper < From, To > :: Create ( ) ) > ;", 5616 2, ":: %name% (")); 5617 ASSERT_EQUALS(false, 5618 instantiateMatch("integral_constant < bool, sizeof ( ns :: ConvertHelper < From, To > :: Create ( ) ) > ;", 5619 2, ":: %name% (")); 5620 } 5621 templateParameterWithoutName()5622 void templateParameterWithoutName() { 5623 ASSERT_EQUALS(1U, templateParameters("template<typename = void> struct s;")); 5624 ASSERT_EQUALS(1U, templateParameters("template<template<typename = float> typename T> struct A {\n" 5625 " void f();\n" 5626 " void g();\n" 5627 "};n")); 5628 } 5629 templateTypeDeduction1()5630 void templateTypeDeduction1() { // #8962 5631 const char code[] = "template<typename T>\n" 5632 "void f(T n) { (void)n; }\n" 5633 "static void func() {\n" 5634 " f(0);\n" 5635 " f(0u);\n" 5636 " f(0U);\n" 5637 " f(0l);\n" 5638 " f(0L);\n" 5639 " f(0ul);\n" 5640 " f(0UL);\n" 5641 " f(0ll);\n" 5642 " f(0LL);\n" 5643 " f(0ull);\n" 5644 " f(0ULL);\n" 5645 " f(0.0);\n" 5646 " f(0.0f);\n" 5647 " f(0.0F);\n" 5648 " f(0.0l);\n" 5649 " f(0.0L);\n" 5650 " f('c');\n" 5651 " f(L'c');\n" 5652 " f(\"string\");\n" 5653 " f(L\"string\");\n" 5654 " f(true);\n" 5655 " f(false);\n" 5656 "}"; 5657 const char expected[] = "void f<int> ( int n ) ; " 5658 "void f<unsignedint> ( unsigned int n ) ; " 5659 "void f<long> ( long n ) ; " 5660 "void f<unsignedlong> ( unsigned long n ) ; " 5661 "void f<longlong> ( long long n ) ; " 5662 "void f<unsignedlonglong> ( unsigned long long n ) ; " 5663 "void f<double> ( double n ) ; " 5664 "void f<float> ( float n ) ; " 5665 "void f<longdouble> ( long double n ) ; " 5666 "void f<char> ( char n ) ; " 5667 "void f<wchar_t> ( wchar_t n ) ; " 5668 "void f<constchar*> ( const char * n ) ; " 5669 "void f<constwchar_t*> ( const wchar_t * n ) ; " 5670 "void f<bool> ( bool n ) ; " 5671 "static void func ( ) { " 5672 "f<int> ( 0 ) ; " 5673 "f<unsignedint> ( 0u ) ; " 5674 "f<unsignedint> ( 0U ) ; " 5675 "f<long> ( 0l ) ; " 5676 "f<long> ( 0L ) ; " 5677 "f<unsignedlong> ( 0ul ) ; " 5678 "f<unsignedlong> ( 0UL ) ; " 5679 "f<longlong> ( 0ll ) ; " 5680 "f<longlong> ( 0LL ) ; " 5681 "f<unsignedlonglong> ( 0ull ) ; " 5682 "f<unsignedlonglong> ( 0ULL ) ; " 5683 "f<double> ( 0.0 ) ; " 5684 "f<float> ( 0.0f ) ; " 5685 "f<float> ( 0.0F ) ; " 5686 "f<longdouble> ( 0.0l ) ; " 5687 "f<longdouble> ( 0.0L ) ; " 5688 "f<char> ( 'c' ) ; " 5689 "f<wchar_t> ( L'c' ) ; " 5690 "f<constchar*> ( \"string\" ) ; " 5691 "f<constwchar_t*> ( L\"string\" ) ; " 5692 "f<bool> ( true ) ; " 5693 "f<bool> ( false ) ; " 5694 "} " 5695 "void f<int> ( int n ) { ( void ) n ; } " 5696 "void f<unsignedint> ( unsigned int n ) { ( void ) n ; } " 5697 "void f<long> ( long n ) { ( void ) n ; } " 5698 "void f<unsignedlong> ( unsigned long n ) { ( void ) n ; } " 5699 "void f<longlong> ( long long n ) { ( void ) n ; } " 5700 "void f<unsignedlonglong> ( unsigned long long n ) { ( void ) n ; } " 5701 "void f<double> ( double n ) { ( void ) n ; } " 5702 "void f<float> ( float n ) { ( void ) n ; } " 5703 "void f<longdouble> ( long double n ) { ( void ) n ; } " 5704 "void f<char> ( char n ) { ( void ) n ; } " 5705 "void f<wchar_t> ( wchar_t n ) { ( void ) n ; } " 5706 "void f<constchar*> ( const char * n ) { ( void ) n ; } " 5707 "void f<constwchar_t*> ( const wchar_t * n ) { ( void ) n ; } " 5708 "void f<bool> ( bool n ) { ( void ) n ; }"; 5709 5710 ASSERT_EQUALS(expected, tok(code)); 5711 ASSERT_EQUALS("", errout.str()); 5712 } 5713 templateTypeDeduction2()5714 void templateTypeDeduction2() { 5715 const char code[] = "template<typename T, typename U>\n" 5716 "void f(T t, U u) { }\n" 5717 "static void func() {\n" 5718 " f(0, 0.0);\n" 5719 " f(0.0, 0);\n" 5720 "}"; 5721 5722 const char expected[] = "void f<int,double> ( int t , double u ) ; " 5723 "void f<double,int> ( double t , int u ) ; " 5724 "static void func ( ) { " 5725 "f<int,double> ( 0 , 0.0 ) ; " 5726 "f<double,int> ( 0.0, 0 ) ; " 5727 "void f<int,double> ( int t , double u ) { } " 5728 "void f<double,int> ( double t , int u ) { } "; 5729 5730 const char actual[] = "template < typename T , typename U > " 5731 "void f ( T t , U u ) { } " 5732 "static void func ( ) { " 5733 "f ( 0 , 0.0 ) ; " 5734 "f ( 0.0 , 0 ) ; " 5735 "}"; 5736 5737 TODO_ASSERT_EQUALS(expected, actual, tok(code)); 5738 } 5739 templateTypeDeduction3()5740 void templateTypeDeduction3() { // #9975 5741 const char code[] = "struct A {\n" 5742 " int a = 1;\n" 5743 " void f() { g(1); }\n" 5744 " template <typename T> void g(T x) { a = 2; }\n" 5745 "};\n" 5746 "int main() {\n" 5747 " A a;\n" 5748 " a.f();\n" 5749 "}"; 5750 const char exp[] = "struct A { " 5751 "int a ; a = 1 ; " 5752 "void f ( ) { g<int> ( 1 ) ; } " 5753 "void g<int> ( int x ) ; " 5754 "} ; " 5755 "int main ( ) { " 5756 "A a ; " 5757 "a . f ( ) ; " 5758 "} void A :: g<int> ( int x ) { a = 2 ; }"; 5759 ASSERT_EQUALS(exp, tok(code)); 5760 } 5761 templateTypeDeduction4()5762 void templateTypeDeduction4() { // #9983 5763 { 5764 const char code[] = "int a = 1;\n" 5765 "template <typename T> void f(T x, T y) { a = x + y; }\n" 5766 "void test() { f(0, 0); }"; 5767 const char exp[] = "int a ; a = 1 ; " 5768 "void f<int> ( int x , int y ) ; " 5769 "void test ( ) { f<int> ( 0 , 0 ) ; } " 5770 "void f<int> ( int x , int y ) { a = x + y ; }"; 5771 ASSERT_EQUALS(exp, tok(code)); 5772 } 5773 { 5774 const char code[] = "int a = 1;\n" 5775 "template <typename T> void f(T x, double y) { a = x + y; }\n" 5776 "void test() { f(0, 0.0); }"; 5777 const char exp[] = "int a ; a = 1 ; " 5778 "void f<int> ( int x , double y ) ; " 5779 "void test ( ) { f<int> ( 0 , 0.0 ) ; } " 5780 "void f<int> ( int x , double y ) { a = x + y ; }"; 5781 ASSERT_EQUALS(exp, tok(code)); 5782 } 5783 { 5784 const char code[] = "int a = 1;\n" 5785 "template <typename T> void f(double x, T y) { a = x + y; }\n" 5786 "void test() { f(0.0, 0); }"; 5787 const char exp[] = "int a ; a = 1 ; " 5788 "void f<int> ( double x , int y ) ; " 5789 "void test ( ) { f<int> ( 0.0 , 0 ) ; } " 5790 "void f<int> ( double x , int y ) { a = x + y ; }"; 5791 ASSERT_EQUALS(exp, tok(code)); 5792 } 5793 5794 { 5795 const char code[] = "int a = 1;\n" 5796 "template <typename T> void f(double x, T y) { a = x + y; }\n" 5797 "template <typename T> void f(int x, T y) { a = x + y; }\n" 5798 "void test() {\n" 5799 " f(0, 0);\n" 5800 " f(0.0, 0);\n" 5801 " f(0, 0.0);\n" 5802 " f(0.0, 0.0);\n" 5803 "}"; 5804 const char exp[] = "int a ; a = 1 ; " 5805 "void f<int> ( int x , int y ) ; " 5806 "void f<int> ( double x , int y ) ; " 5807 "void f<double> ( int x , double y ) ; " 5808 "void f<double> ( double x , double y ) ; " 5809 "void test ( ) { " 5810 "f<int> ( 0 , 0 ) ; " 5811 "f<int> ( 0.0 , 0 ) ; " 5812 "f<double> ( 0 , 0.0 ) ; " 5813 "f<double> ( 0.0 , 0.0 ) ; " 5814 "} " 5815 "void f<int> ( int x , int y ) { a = x + y ; } " 5816 "void f<int> ( double x , int y ) { a = x + y ; } " 5817 "void f<double> ( int x , double y ) { a = x + y ; } " 5818 "void f<double> ( double x , double y ) { a = x + y ; }"; 5819 5820 const char act[] = "int a ; a = 1 ; " 5821 "template < typename T > void f ( double x , T y ) { a = x + y ; } " 5822 "void f<int> ( int x , int y ) ; void f<double> ( int x , double y ) ; " 5823 "void test ( ) { " 5824 "f<int> ( 0 , 0 ) ; " 5825 "f<int> ( 0.0 , 0 ) ; " 5826 "f<double> ( 0 , 0.0 ) ; " 5827 "f<double> ( 0.0 , 0.0 ) ; " 5828 "} " 5829 "void f<int> ( int x , int y ) { a = x + y ; } " 5830 "void f<double> ( int x , double y ) { a = x + y ; }"; 5831 TODO_ASSERT_EQUALS(exp, act, tok(code)); 5832 } 5833 { 5834 const char code[] = "int a = 1;\n" 5835 "template <typename T, typename U> void f(T x, U y) { a = x + y; }\n" 5836 "void test() { f(0, 0.0); }"; 5837 const char exp[] = "int a ; a = 1 ; " 5838 "void f<int,double> ( int x , double y ) ; " 5839 "void test ( ) { f<int,double> ( 0 , 0.0 ) ; } " 5840 "void f<int,double> ( int x , double y ) { a = x + y ; }"; 5841 const char act[] = "int a ; a = 1 ; " 5842 "template < typename T , typename U > void f ( T x , U y ) { a = x + y ; } " 5843 "void test ( ) { f ( 0 , 0.0 ) ; }"; 5844 TODO_ASSERT_EQUALS(exp, act, tok(code)); 5845 } 5846 } 5847 templateTypeDeduction5()5848 void templateTypeDeduction5() { 5849 { 5850 const char code[] = "class Fred {\n" 5851 "public:\n" 5852 " template <class T> Fred(T t) { }\n" 5853 "};\n" 5854 "Fred fred1 = Fred(0);\n" 5855 "Fred fred2 = Fred(0.0);\n" 5856 "Fred fred3 = Fred(\"zero\");\n" 5857 "Fred fred4 = Fred(false);"; 5858 const char exp[] = "class Fred { " 5859 "public: " 5860 "Fred<int> ( int t ) ; " 5861 "Fred<double> ( double t ) ; " 5862 "Fred<constchar*> ( const char * t ) ; " 5863 "Fred<bool> ( bool t ) ; " 5864 "} ; " 5865 "Fred fred1 ; fred1 = Fred<int> ( 0 ) ; " 5866 "Fred fred2 ; fred2 = Fred<double> ( 0.0 ) ; " 5867 "Fred fred3 ; fred3 = Fred<constchar*> ( \"zero\" ) ; " 5868 "Fred fred4 ; fred4 = Fred<bool> ( false ) ; " 5869 "Fred :: Fred<int> ( int t ) { } " 5870 "Fred :: Fred<double> ( double t ) { } " 5871 "Fred :: Fred<constchar*> ( const char * t ) { } " 5872 "Fred :: Fred<bool> ( bool t ) { }"; 5873 ASSERT_EQUALS(exp, tok(code)); 5874 } 5875 { 5876 const char code[] = "namespace NS {\n" 5877 "class Fred {\n" 5878 "public:\n" 5879 " template <class T> Fred(T t) { }\n" 5880 "};\n" 5881 "Fred fred1 = Fred(0);\n" 5882 "Fred fred2 = Fred(0.0);\n" 5883 "Fred fred3 = Fred(\"zero\");\n" 5884 "Fred fred4 = Fred(false);\n" 5885 "}\n" 5886 "NS::Fred fred1 = NS::Fred(0);\n" 5887 "NS::Fred fred2 = NS::Fred(0.0);\n" 5888 "NS::Fred fred3 = NS::Fred(\"zero\");\n" 5889 "NS::Fred fred4 = NS::Fred(false);\n"; 5890 const char exp[] = "namespace NS { " 5891 "class Fred { " 5892 "public: " 5893 "Fred<int> ( int t ) ; " 5894 "Fred<double> ( double t ) ; " 5895 "Fred<constchar*> ( const char * t ) ; " 5896 "Fred<bool> ( bool t ) ; " 5897 "} ; " 5898 "Fred fred1 ; fred1 = Fred<int> ( 0 ) ; " 5899 "Fred fred2 ; fred2 = Fred<double> ( 0.0 ) ; " 5900 "Fred fred3 ; fred3 = Fred<constchar*> ( \"zero\" ) ; " 5901 "Fred fred4 ; fred4 = Fred<bool> ( false ) ; " 5902 "} " 5903 "NS :: Fred fred1 ; fred1 = NS :: Fred<int> ( 0 ) ; " 5904 "NS :: Fred fred2 ; fred2 = NS :: Fred<double> ( 0.0 ) ; " 5905 "NS :: Fred fred3 ; fred3 = NS :: Fred<constchar*> ( \"zero\" ) ; " 5906 "NS :: Fred fred4 ; fred4 = NS :: Fred<bool> ( false ) ; " 5907 "NS :: Fred :: Fred<int> ( int t ) { } " 5908 "NS :: Fred :: Fred<double> ( double t ) { } " 5909 "NS :: Fred :: Fred<constchar*> ( const char * t ) { } " 5910 "NS :: Fred :: Fred<bool> ( bool t ) { }"; 5911 ASSERT_EQUALS(exp, tok(code)); 5912 } 5913 } 5914 simplifyTemplateArgs1()5915 void simplifyTemplateArgs1() { 5916 ASSERT_EQUALS("foo<2> = 2 ; foo<2> ;", tok("template<int N> foo = N; foo < ( 2 ) >;")); 5917 ASSERT_EQUALS("foo<2> = 2 ; foo<2> ;", tok("template<int N> foo = N; foo < 1 + 1 >;")); 5918 ASSERT_EQUALS("foo<2> = 2 ; foo<2> ;", tok("template<int N> foo = N; foo < ( 1 + 1 ) >;")); 5919 5920 ASSERT_EQUALS("foo<2,2> = 4 ; foo<2,2> ;", tok("template<int N, int M> foo = N * M; foo < ( 2 ), ( 2 ) >;")); 5921 ASSERT_EQUALS("foo<2,2> = 4 ; foo<2,2> ;", tok("template<int N, int M> foo = N * M; foo < 1 + 1, 1 + 1 >;")); 5922 ASSERT_EQUALS("foo<2,2> = 4 ; foo<2,2> ;", tok("template<int N, int M> foo = N * M; foo < ( 1 + 1 ), ( 1 + 1 ) >;")); 5923 5924 ASSERT_EQUALS("foo<true> = true ; foo<true> ;", tok("template<bool N> foo = N; foo < true ? true : false >;")); 5925 ASSERT_EQUALS("foo<false> = false ; foo<false> ;", tok("template<bool N> foo = N; foo < false ? true : false >;")); 5926 ASSERT_EQUALS("foo<true> = true ; foo<true> ;", tok("template<bool N> foo = N; foo < 1 ? true : false >;")); 5927 ASSERT_EQUALS("foo<false> = false ; foo<false> ;", tok("template<bool N> foo = N; foo < 0 ? true : false >;")); 5928 ASSERT_EQUALS("foo<true> = true ; foo<true> ;", tok("template<bool N> foo = N; foo < (1 + 1 ) ? true : false >;")); 5929 ASSERT_EQUALS("foo<false> = false ; foo<false> ;", tok("template<bool N> foo = N; foo < ( 1 - 1) ? true : false >;")); 5930 } 5931 simplifyTemplateArgs2()5932 void simplifyTemplateArgs2() { 5933 const char code[] = "template<bool T> struct a_t { static const bool t = T; };\n" 5934 "typedef a_t<sizeof(void*) == sizeof(char)> a;\n" 5935 "void foo() { bool b = a::t; }"; 5936 const char expected[] = "struct a_t<false> ; " 5937 "void foo ( ) { bool b ; b = a_t<false> :: t ; } " 5938 "struct a_t<false> { static const bool t = false ; } ;"; 5939 ASSERT_EQUALS(expected, tok(code)); 5940 } 5941 template_variadic_1()5942 void template_variadic_1() { // #9144 5943 const char code[] = "template <typename...> struct e {};\n" 5944 "static_assert(sizeof(e<>) == sizeof(e<int,int>), \"\");"; 5945 const char expected[] = "struct e<> ; struct e<int,int> ; " 5946 "static_assert ( sizeof ( e<> ) == sizeof ( e<int,int> ) , \"\" ) ; " 5947 "struct e<> { } ; struct e<int,int> { } ;"; 5948 ASSERT_EQUALS(expected, tok(code)); 5949 } 5950 template_variadic_2()5951 void template_variadic_2() { // #4349 5952 const char code[] = "template<typename T, typename... Args>\n" 5953 "void printf(const char *s, T value, Args... args) {}\n" 5954 "\n" 5955 "int main() {\n" 5956 " printf<int, float>(\"\", foo, bar);\n" 5957 "}"; 5958 const char expected[] = "void printf<int,float> ( const char * s , int value , float ) ; " 5959 "int main ( ) { printf<int,float> ( \"\" , foo , bar ) ; } " 5960 "void printf<int,float> ( const char * s , int value , float ) { }"; 5961 ASSERT_EQUALS(expected, tok(code)); 5962 } 5963 template_variadic_3()5964 void template_variadic_3() { // #6172 5965 const char code[] = "template<int N, int ... M> struct A { " 5966 " static void foo() { " 5967 " int i = N; " 5968 " } " 5969 "}; " 5970 "void bar() { " 5971 " A<0>::foo(); " 5972 "}"; 5973 const char expected[] = "struct A<0> ; " 5974 "void bar ( ) { A<0> :: foo ( ) ; } " 5975 "struct A<0> { static void foo ( ) { int i ; i = 0 ; } } ;"; 5976 ASSERT_EQUALS(expected, tok(code)); 5977 } 5978 template_variable_1()5979 void template_variable_1() { 5980 { 5981 const char code[] = "template <int N> const int foo = N*N;\n" 5982 "int x = foo<7>;"; 5983 const char expected[] = "const int foo<7> = 49 ; " 5984 "int x ; x = foo<7> ;"; 5985 ASSERT_EQUALS(expected, tok(code)); 5986 } 5987 { 5988 const char code[] = "template <int> const int foo = 7;\n" 5989 "int x = foo<7>;"; 5990 const char expected[] = "const int foo<7> = 7 ; " 5991 "int x ; x = foo<7> ;"; 5992 ASSERT_EQUALS(expected, tok(code)); 5993 } 5994 { 5995 const char code[] = "template <int N = 7> const int foo = N*N;\n" 5996 "int x = foo<7>;"; 5997 const char expected[] = "const int foo<7> = 49 ; " 5998 "int x ; x = foo<7> ;"; 5999 ASSERT_EQUALS(expected, tok(code)); 6000 } 6001 { 6002 const char code[] = "template <int N = 7> const int foo = N*N;\n" 6003 "int x = foo<>;"; 6004 const char expected[] = "const int foo<7> = 49 ; " 6005 "int x ; x = foo<7> ;"; 6006 ASSERT_EQUALS(expected, tok(code)); 6007 } 6008 } 6009 template_variable_2()6010 void template_variable_2() { 6011 { 6012 const char code[] = "template<class T> constexpr T pi = T(3.1415926535897932385L);\n" 6013 "float x = pi<float>;"; 6014 const char expected[] = "constexpr float pi<float> = float ( 3.1415926535897932385L ) ; " 6015 "float x ; x = pi<float> ;"; 6016 ASSERT_EQUALS(expected, tok(code)); 6017 } 6018 { 6019 const char code[] = "template<class> constexpr float pi = float(3.1415926535897932385L);\n" 6020 "float x = pi<float>;"; 6021 const char expected[] = "constexpr float pi<float> = float ( 3.1415926535897932385L ) ; " 6022 "float x ; x = pi<float> ;"; 6023 ASSERT_EQUALS(expected, tok(code)); 6024 } 6025 { 6026 const char code[] = "template<class T = float> constexpr T pi = T(3.1415926535897932385L);\n" 6027 "float x = pi<float>;"; 6028 const char expected[] = "constexpr float pi<float> = float ( 3.1415926535897932385L ) ; " 6029 "float x ; x = pi<float> ;"; 6030 ASSERT_EQUALS(expected, tok(code)); 6031 } 6032 { 6033 const char code[] = "template<class T = float> constexpr T pi = T(3.1415926535897932385L);\n" 6034 "float x = pi<>;"; 6035 const char expected[] = "constexpr float pi<float> = float ( 3.1415926535897932385L ) ; " 6036 "float x ; x = pi<float> ;"; 6037 ASSERT_EQUALS(expected, tok(code)); 6038 } 6039 } 6040 template_variable_3()6041 void template_variable_3() { 6042 { 6043 const char code[] = "template<class T, int N> constexpr T foo = T(N*N);\n" 6044 "float x = foo<float,7>;"; 6045 const char expected[] = "constexpr float foo<float,7> = float ( 49 ) ; " 6046 "float x ; x = foo<float,7> ;"; 6047 ASSERT_EQUALS(expected, tok(code)); 6048 } 6049 { 6050 const char code[] = "template<class,int> constexpr float foo = float(7);\n" 6051 "float x = foo<float,7>;"; 6052 const char expected[] = "constexpr float foo<float,7> = float ( 7 ) ; " 6053 "float x ; x = foo<float,7> ;"; 6054 ASSERT_EQUALS(expected, tok(code)); 6055 } 6056 { 6057 const char code[] = "template<class T = float, int N = 7> constexpr T foo = T(7);\n" 6058 "double x = foo<double, 14>;"; 6059 const char expected[] = "constexpr double foo<double,14> = double ( 7 ) ; " 6060 "double x ; x = foo<double,14> ;"; 6061 ASSERT_EQUALS(expected, tok(code)); 6062 } 6063 { 6064 const char code[] = "template<class T = float, int N = 7> constexpr T foo = T(7);\n" 6065 "float x = foo<>;"; 6066 const char expected[] = "constexpr float foo<float,7> = float ( 7 ) ; " 6067 "float x ; x = foo<float,7> ;"; 6068 ASSERT_EQUALS(expected, tok(code)); 6069 } 6070 { 6071 const char code[] = "template<class T = float, int N = 7> constexpr T foo = T(7);\n" 6072 "double x = foo<double>;"; 6073 const char expected[] = "constexpr double foo<double,7> = double ( 7 ) ; " 6074 "double x ; x = foo<double,7> ;"; 6075 ASSERT_EQUALS(expected, tok(code)); 6076 } 6077 } 6078 template_variable_4()6079 void template_variable_4() { 6080 const char code[] = "template<typename T> void test() { }\n" 6081 "template<typename T> decltype(test<T>)* foo = &(test<T>);\n" 6082 "void bar() { foo<int>(); }"; 6083 const char expected[] = "void test<int> ( ) ; " 6084 "decltype ( test<int> ) * foo<int> = & ( test<int> ) ; " 6085 "void bar ( ) { foo<int> ( ) ; } " 6086 "void test<int> ( ) { }"; 6087 ASSERT_EQUALS(expected, tok(code)); 6088 } 6089 simplifyDecltype()6090 void simplifyDecltype() { 6091 const char code[] = "template<typename T> class type { };\n" 6092 "type<decltype(true)> b;\n" 6093 "type<decltype(0)> i;\n" 6094 "type<decltype(0U)> ui;\n" 6095 "type<decltype(0L)> l;\n" 6096 "type<decltype(0UL)> ul;\n" 6097 "type<decltype(0LL)> ll;\n" 6098 "type<decltype(0ULL)> ull;\n" 6099 "type<decltype(0.0)> d;\n" 6100 "type<decltype(0.0F)> f;\n" 6101 "type<decltype(0.0L)> ld;"; 6102 const char expected[] = "class type<bool> ; " 6103 "class type<int> ; " 6104 "class type<unsignedint> ; " 6105 "class type<long> ; " 6106 "class type<unsignedlong> ; " 6107 "class type<longlong> ; " 6108 "class type<unsignedlonglong> ; " 6109 "class type<double> ; " 6110 "class type<float> ; " 6111 "class type<longdouble> ; " 6112 "type<bool> b ; " 6113 "type<int> i ; " 6114 "type<unsignedint> ui ; " 6115 "type<long> l ; " 6116 "type<unsignedlong> ul ; " 6117 "type<longlong> ll ; " 6118 "type<unsignedlonglong> ull ; " 6119 "type<double> d ; " 6120 "type<float> f ; " 6121 "type<longdouble> ld ; " 6122 "class type<bool> { } ; " 6123 "class type<int> { } ; " 6124 "class type<unsignedint> { } ; " 6125 "class type<long> { } ; " 6126 "class type<unsignedlong> { } ; " 6127 "class type<longlong> { } ; " 6128 "class type<unsignedlonglong> { } ; " 6129 "class type<double> { } ; " 6130 "class type<float> { } ; " 6131 "class type<longdouble> { } ;"; 6132 ASSERT_EQUALS(expected, tok(code)); 6133 } 6134 castInExpansion()6135 void castInExpansion() { 6136 const char code[] = "template <int N> class C { };\n" 6137 "template <typename TC> class Base {};\n" 6138 "template <typename TC> class Derived : private Base<TC> {};\n" 6139 "typedef Derived<C<static_cast<int>(-1)> > C_;\n" 6140 "class C3 { C_ c; };"; 6141 const char expected[] = "template < int N > class C { } ; " 6142 "class Base<C<static_cast<int>-1>> ; " 6143 "class Derived<C<static_cast<int>-1>> ; " 6144 "class C3 { Derived<C<static_cast<int>-1>> c ; } ; " 6145 "class Derived<C<static_cast<int>-1>> : private Base<C<static_cast<int>-1>> { } ; " 6146 "class Base<C<static_cast<int>-1>> { } ;"; 6147 ASSERT_EQUALS(expected, tok(code)); 6148 } 6149 fold_expression_1()6150 void fold_expression_1() { 6151 const char code[] = "template<typename... Args> bool all(Args... args) { return (... && args); }\n" 6152 "x=all(true,false,true,true);"; 6153 const char expected[] = "template < typename ... Args > bool all ( Args ... args ) { return ( __cppcheck_fold_&&__ ( args ... ) ) ; } x = all ( true , false , true , true ) ;"; 6154 ASSERT_EQUALS(expected, tok(code)); 6155 } 6156 fold_expression_2()6157 void fold_expression_2() { 6158 const char code[] = "template<typename... Args> bool all(Args... args) { return (args && ...); }\n" 6159 "x=all(true,false,true,true);"; 6160 const char expected[] = "template < typename ... Args > bool all ( Args ... args ) { return ( __cppcheck_fold_&&__ ( args ... ) ) ; } x = all ( true , false , true , true ) ;"; 6161 ASSERT_EQUALS(expected, tok(code)); 6162 } 6163 fold_expression_3()6164 void fold_expression_3() { 6165 const char code[] = "template<typename... Args> int foo(Args... args) { return (12 * ... * args); }\n" 6166 "x=foo(1,2);"; 6167 const char expected[] = "template < typename ... Args > int foo ( Args ... args ) { return ( __cppcheck_fold_*__ ( args ... ) ) ; } x = foo ( 1 , 2 ) ;"; 6168 ASSERT_EQUALS(expected, tok(code)); 6169 } 6170 fold_expression_4()6171 void fold_expression_4() { 6172 const char code[] = "template<typename... Args> int foo(Args... args) { return (args * ... * 123); }\n" 6173 "x=foo(1,2);"; 6174 const char expected[] = "template < typename ... Args > int foo ( Args ... args ) { return ( __cppcheck_fold_*__ ( args ... ) ) ; } x = foo ( 1 , 2 ) ;"; 6175 ASSERT_EQUALS(expected, tok(code)); 6176 } 6177 concepts1()6178 void concepts1() { 6179 const char code[] = "template <my_concept T> void f(T v) {}\n" 6180 "f<int>(123);"; 6181 const char expected[] = "void f<int> ( int v ) ; f<int> ( 123 ) ; void f<int> ( int v ) { }"; 6182 ASSERT_EQUALS(expected, tok(code)); 6183 } 6184 requires1()6185 void requires1() { 6186 const char code[] = "template <class T> requires my_concept<T> void f(T v) {}\n" 6187 "f<int>(123);"; 6188 const char expected[] = "void f<int> ( int v ) ; f<int> ( 123 ) ; void f<int> ( int v ) { }"; 6189 ASSERT_EQUALS(expected, tok(code)); 6190 } 6191 requires2()6192 void requires2() { 6193 const char code[] = "template<class T> requires (sizeof(T) > 1 && get_value<T>()) void f(T v){}\n" 6194 "f<int>(123);"; 6195 const char expected[] = "void f<int> ( int v ) ; f<int> ( 123 ) ; void f<int> ( int v ) { }"; 6196 ASSERT_EQUALS(expected, tok(code)); 6197 } 6198 requires3()6199 void requires3() { 6200 const char code[] = "template<class T> requires c1<T> && c2<T> void f(T v){}\n" 6201 "f<int>(123);"; 6202 const char expected[] = "void f<int> ( int v ) ; f<int> ( 123 ) ; void f<int> ( int v ) { }"; 6203 ASSERT_EQUALS(expected, tok(code)); 6204 } 6205 requires4()6206 void requires4() { 6207 const char code[] = "template <class T> void f(T v) requires my_concept<T> {}\n" 6208 "f<int>(123);"; 6209 const char expected[] = "void f<int> ( int v ) ; f<int> ( 123 ) ; void f<int> ( int v ) { }"; 6210 ASSERT_EQUALS(expected, tok(code)); 6211 } 6212 requires5()6213 void requires5() { 6214 const char code[] = "template <class T>\n" 6215 " requires requires (T x) { x + x; }\n" 6216 " T add(T a, T b) { return a + b; }\n" 6217 "add<int>(123,456);"; 6218 const char expected[] = "int add<int> ( int a , int b ) ; add<int> ( 123 , 456 ) ; int add<int> ( int a , int b ) { return a + b ; }"; 6219 ASSERT_EQUALS(expected, tok(code)); 6220 } 6221 explicitBool1()6222 void explicitBool1() { 6223 const char code[] = "class Fred { explicit(true) Fred(int); };"; 6224 ASSERT_EQUALS("class Fred { explicit Fred ( int ) ; } ;", tok(code)); 6225 } 6226 explicitBool2()6227 void explicitBool2() { 6228 const char code[] = "class Fred { explicit(false) Fred(int); };"; 6229 ASSERT_EQUALS("class Fred { Fred ( int ) ; } ;", tok(code)); 6230 } 6231 }; 6232 6233 REGISTER_TEST(TestSimplifyTemplate) 6234