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