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 #include "platform.h"
20 #include "settings.h"
21 #include "standards.h"
22 #include "testsuite.h"
23 #include "token.h"
24 #include "tokenize.h"
25 
26 #include <string>
27 
28 struct InternalError;
29 
30 
31 class TestVarID : public TestFixture {
32 public:
TestVarID()33     TestVarID() : TestFixture("TestVarID") {}
34 
35 private:
run()36     void run() OVERRIDE {
37         TEST_CASE(varid1);
38         TEST_CASE(varid2);
39         TEST_CASE(varid3);
40         TEST_CASE(varid4);
41         TEST_CASE(varid5);
42         TEST_CASE(varid6);
43         TEST_CASE(varid7);
44         TEST_CASE(varidReturn1);
45         TEST_CASE(varidReturn2);
46         TEST_CASE(varid8);
47         TEST_CASE(varid9);
48         TEST_CASE(varid10);
49         TEST_CASE(varid11);
50         TEST_CASE(varid12);
51         TEST_CASE(varid13);
52         TEST_CASE(varid14);
53         TEST_CASE(varid15);
54         TEST_CASE(varid16);
55         TEST_CASE(varid17);   // ticket #1810
56         TEST_CASE(varid18);
57         TEST_CASE(varid19);
58         TEST_CASE(varid20);
59         TEST_CASE(varid24);
60         TEST_CASE(varid25);
61         TEST_CASE(varid26);   // ticket #1967 (list of function pointers)
62         TEST_CASE(varid27);   // Ticket #2280 (same name for namespace and variable)
63         TEST_CASE(varid28);   // ticket #2630
64         TEST_CASE(varid29);   // ticket #1974
65         TEST_CASE(varid30);   // ticket #2614
66         TEST_CASE(varid34);   // ticket #2825
67         TEST_CASE(varid35);   // function declaration inside function body
68         TEST_CASE(varid36);   // ticket #2980 (segmentation fault)
69         TEST_CASE(varid37);   // ticket #3092 (varid for 'Bar bar(*this);')
70         TEST_CASE(varid38);   // ticket #3272 (varid for 'FOO class C;')
71         TEST_CASE(varid39);   // ticket #3279 (varid for 'FOO::BAR const')
72         TEST_CASE(varid40);   // ticket #3279
73         TEST_CASE(varid41);   // ticket #3340 (varid for union type)
74         TEST_CASE(varid42);   // ticket #3316 (varid for array)
75         TEST_CASE(varid43);
76         TEST_CASE(varid44);
77         TEST_CASE(varid45); // #3466
78         TEST_CASE(varid46); // struct varname
79         TEST_CASE(varid47); // function parameters
80         TEST_CASE(varid48); // #3785 - return (a*b)
81         TEST_CASE(varid49); // #3799 - void f(std::vector<int>)
82         TEST_CASE(varid50); // #3760 - explicit
83         TEST_CASE(varid51); // don't set varid for template function
84         TEST_CASE(varid52); // Set varid for nested templates
85         TEST_CASE(varid53); // #4172 - Template instantiation: T<&functionName> list[4];
86         TEST_CASE(varid54); // hang
87         TEST_CASE(varid55); // #5868: Function::addArgument with varid 0 for argument named the same as a typedef
88         TEST_CASE(varid56); // function with a throw()
89         TEST_CASE(varid57); // #6636: new scope by {}
90         TEST_CASE(varid58); // #6638: for loop in for condition
91         TEST_CASE(varid59); // #6696
92         TEST_CASE(varid60); // #7267 cast '(unsigned x)10'
93         TEST_CASE(varid61); // #4988 inline function
94         TEST_CASE(varid62);
95         TEST_CASE(varid63);
96         TEST_CASE(varid64); // #9928 - extern const char (*x[256])
97         TEST_CASE(varid_for_1);
98         TEST_CASE(varid_for_2);
99         TEST_CASE(varid_cpp_keywords_in_c_code);
100         TEST_CASE(varid_cpp_keywords_in_c_code2); // #5373: varid=0 for argument called "delete"
101         TEST_CASE(varidFunctionCall1);
102         TEST_CASE(varidFunctionCall2);
103         TEST_CASE(varidFunctionCall3);
104         TEST_CASE(varidFunctionCall4);  // ticket #3280
105         TEST_CASE(varidFunctionCall5);
106         TEST_CASE(varidStl);
107         TEST_CASE(varidStl2);
108         TEST_CASE(varid_newauto);       // not declaration: new const auto(0);
109         TEST_CASE(varid_delete);
110         TEST_CASE(varid_functions);
111         TEST_CASE(varid_sizeof);
112         TEST_CASE(varid_reference_to_containers);
113         TEST_CASE(varid_in_class1);
114         TEST_CASE(varid_in_class2);
115         TEST_CASE(varid_in_class3);     // #3092 - shadow variable in member function
116         TEST_CASE(varid_in_class4);     // #3271 - public: class C;
117         TEST_CASE(varid_in_class5);     // #3584 - std::vector<::FOO::B> b;
118         TEST_CASE(varid_in_class6);     // #3755
119         TEST_CASE(varid_in_class7);     // set variable id for struct members
120         TEST_CASE(varid_in_class8);     // unknown macro in class
121         TEST_CASE(varid_in_class9);     // #4291 - id for variables accessed through 'this'
122         TEST_CASE(varid_in_class10);
123         TEST_CASE(varid_in_class11);    // #4277 - anonymous union
124         TEST_CASE(varid_in_class12);    // #4637 - method
125         TEST_CASE(varid_in_class13);    // #4637 - method
126         TEST_CASE(varid_in_class14);
127         TEST_CASE(varid_in_class15);    // #5533 - functions
128         TEST_CASE(varid_in_class16);
129         TEST_CASE(varid_in_class17);    // #6056 - no varid for member functions
130         TEST_CASE(varid_in_class18);    // #7127
131         TEST_CASE(varid_in_class19);
132         TEST_CASE(varid_in_class20);    // #7267
133         TEST_CASE(varid_in_class21);    // #7788
134         TEST_CASE(varid_namespace_1);   // #7272
135         TEST_CASE(varid_namespace_2);   // #7000
136         TEST_CASE(varid_namespace_3);   // #8627
137         TEST_CASE(varid_namespace_4);
138         TEST_CASE(varid_namespace_5);
139         TEST_CASE(varid_initList);
140         TEST_CASE(varid_initListWithBaseTemplate);
141         TEST_CASE(varid_initListWithScope);
142         TEST_CASE(varid_operator);
143         TEST_CASE(varid_throw);
144         TEST_CASE(varid_unknown_macro);     // #2638 - unknown macro is not type
145         TEST_CASE(varid_using);  // ticket #3648
146         TEST_CASE(varid_catch);
147         TEST_CASE(varid_functionPrototypeTemplate);
148         TEST_CASE(varid_templatePtr); // #4319
149         TEST_CASE(varid_templateNamespaceFuncPtr); // #4172
150         TEST_CASE(varid_templateArray);
151         TEST_CASE(varid_templateParameter); // #7046 set varid for "X":  std::array<int,X> Y;
152         TEST_CASE(varid_templateUsing); // #5781 #7273
153         TEST_CASE(varid_not_template_in_condition); // #7988
154         TEST_CASE(varid_cppcast); // #6190
155         TEST_CASE(varid_variadicFunc);
156         TEST_CASE(varid_typename); // #4644
157         TEST_CASE(varid_rvalueref);
158         TEST_CASE(varid_arrayFuncPar); // #5294
159         TEST_CASE(varid_sizeofPassed); // #5295
160         TEST_CASE(varid_classInFunction); // #5293
161         TEST_CASE(varid_pointerToArray); // #2645
162         TEST_CASE(varid_cpp11initialization); // #4344
163         TEST_CASE(varid_inheritedMembers); // #4101
164         TEST_CASE(varid_header); // #6386
165         TEST_CASE(varid_rangeBasedFor);
166         TEST_CASE(varid_structinit); // #6406
167         TEST_CASE(varid_arrayinit); // #7579
168         TEST_CASE(varid_lambda_arg);
169         TEST_CASE(varid_lambda_mutable);
170         TEST_CASE(varid_trailing_return1); // #8889
171         TEST_CASE(varid_trailing_return2); // #9066
172         TEST_CASE(varid_parameter_pack); // #9383
173         TEST_CASE(varid_for_auto_cpp17);
174         TEST_CASE(varid_not); // #9689 'not x'
175         TEST_CASE(varid_declInIfCondition);
176 
177         TEST_CASE(varidclass1);
178         TEST_CASE(varidclass2);
179         TEST_CASE(varidclass3);
180         TEST_CASE(varidclass4);
181         TEST_CASE(varidclass5);
182         TEST_CASE(varidclass6);
183         TEST_CASE(varidclass7);
184         TEST_CASE(varidclass8);
185         TEST_CASE(varidclass9);
186         TEST_CASE(varidclass10);  // variable declaration below usage
187         TEST_CASE(varidclass11);  // variable declaration below usage
188         TEST_CASE(varidclass12);
189         TEST_CASE(varidclass13);
190         TEST_CASE(varidclass14);
191         TEST_CASE(varidclass15);  // initializer list
192         TEST_CASE(varidclass16);  // #4577
193         TEST_CASE(varidclass17);  // #6073
194         TEST_CASE(varidclass18);
195         TEST_CASE(varidclass19);  // initializer list
196         TEST_CASE(varidclass20);   // #7578: int (*p)[2]
197         TEST_CASE(varid_classnameshaddowsvariablename); // #3990
198         TEST_CASE(varid_classnametemplate); // #10221
199 
200         TEST_CASE(varidenum1);
201         TEST_CASE(varidenum2);
202         TEST_CASE(varidenum3);
203         TEST_CASE(varidenum4);
204         TEST_CASE(varidenum5);
205 
206         TEST_CASE(varidnamespace1);
207         TEST_CASE(varidnamespace2);
208         TEST_CASE(usingNamespace1);
209         TEST_CASE(usingNamespace2);
210         TEST_CASE(usingNamespace3);
211 
212         TEST_CASE(setVarIdStructMembers1);
213 
214         TEST_CASE(decltype1);
215         TEST_CASE(decltype2);
216 
217         TEST_CASE(exprid1);
218 
219         TEST_CASE(structuredBindings);
220     }
221 
tokenize(const char code[],const char filename[]="test.cpp")222     std::string tokenize(const char code[], const char filename[] = "test.cpp") {
223         errout.str("");
224 
225         Settings settings;
226         settings.platform(Settings::Unix64);
227         settings.standards.c   = Standards::C89;
228         settings.standards.cpp = Standards::CPPLatest;
229         settings.checkUnusedTemplates = true;
230 
231         Tokenizer tokenizer(&settings, this);
232         std::istringstream istr(code);
233         tokenizer.tokenize(istr, filename);
234 
235         // result..
236         Token::stringifyOptions options = Token::stringifyOptions::forDebugVarId();
237         options.files = false;
238         return tokenizer.tokens()->stringifyList(options);
239     }
240 
tokenizeExpr(const char code[],const char filename[]="test.cpp")241     std::string tokenizeExpr(const char code[], const char filename[] = "test.cpp") {
242         errout.str("");
243 
244         Settings settings;
245         settings.platform(Settings::Unix64);
246         settings.standards.c   = Standards::C89;
247         settings.standards.cpp = Standards::CPPLatest;
248         settings.checkUnusedTemplates = true;
249 
250         Tokenizer tokenizer(&settings, this);
251         std::istringstream istr(code);
252         tokenizer.tokenize(istr, filename);
253 
254         // result..
255         Token::stringifyOptions options = Token::stringifyOptions::forDebugExprId();
256         options.files = false;
257         return tokenizer.tokens()->stringifyList(options);
258     }
259 
compareVaridsForVariable(const char code[],const char varname[],const char filename[]="test.cpp")260     std::string compareVaridsForVariable(const char code[], const char varname[], const char filename[] = "test.cpp") {
261         errout.str("");
262 
263         Settings settings;
264         settings.platform(Settings::Unix64);
265         settings.standards.c   = Standards::C89;
266         settings.standards.cpp = Standards::CPP11;
267         settings.checkUnusedTemplates = true;
268 
269         Tokenizer tokenizer(&settings, this);
270         std::istringstream istr(code);
271         tokenizer.tokenize(istr, filename);
272 
273         unsigned int varid = ~0U;
274         for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
275             if (tok->str() == varname) {
276                 if (varid == ~0U)
277                     varid = tok->varId();
278                 else if (varid != tok->varId())
279                     return std::string("Variable ") + varname + " has different varids:\n" + tokenizer.tokens()->stringifyList(true,true,true,true,false);
280             }
281         }
282 
283         return "same varid";
284     }
285 
varid1()286     void varid1() {
287         {
288             const std::string actual = tokenize(
289                 "static int i = 1;\n"
290                 "void f()\n"
291                 "{\n"
292                 "    int i = 2;\n"
293                 "    for (int i = 0; i < 10; ++i)\n"
294                 "        i = 3;\n"
295                 "    i = 4;\n"
296                 "}\n", "test.c");
297 
298             const char expected[] = "1: static int i@1 = 1 ;\n"
299                                     "2: void f ( )\n"
300                                     "3: {\n"
301                                     "4: int i@2 ; i@2 = 2 ;\n"
302                                     "5: for ( int i@3 = 0 ; i@3 < 10 ; ++ i@3 ) {\n"
303                                     "6: i@3 = 3 ; }\n"
304                                     "7: i@2 = 4 ;\n"
305                                     "8: }\n";
306 
307             ASSERT_EQUALS(expected, actual);
308         }
309 
310         {
311             const std::string actual = tokenize(
312                 "static int i = 1;\n"
313                 "void f()\n"
314                 "{\n"
315                 "    int i = 2;\n"
316                 "    for (int i = 0; i < 10; ++i)\n"
317                 "    {\n"
318                 "      i = 3;\n"
319                 "    }\n"
320                 "    i = 4;\n"
321                 "}\n", "test.c");
322 
323             const char expected[] = "1: static int i@1 = 1 ;\n"
324                                     "2: void f ( )\n"
325                                     "3: {\n"
326                                     "4: int i@2 ; i@2 = 2 ;\n"
327                                     "5: for ( int i@3 = 0 ; i@3 < 10 ; ++ i@3 )\n"
328                                     "6: {\n"
329                                     "7: i@3 = 3 ;\n"
330                                     "8: }\n"
331                                     "9: i@2 = 4 ;\n"
332                                     "10: }\n";
333 
334             ASSERT_EQUALS(expected, actual);
335         }
336     }
337 
varid2()338     void varid2() {
339         const std::string actual = tokenize(
340             "void f()\n"
341             "{\n"
342             "    struct ABC abc;\n"
343             "    abc.a = 3;\n"
344             "    i = abc.a;\n"
345             "}\n", "test.c");
346 
347         const char expected[] = "1: void f ( )\n"
348                                 "2: {\n"
349                                 "3: struct ABC abc@1 ;\n"
350                                 "4: abc@1 . a@2 = 3 ;\n"
351                                 "5: i = abc@1 . a@2 ;\n"
352                                 "6: }\n";
353 
354         ASSERT_EQUALS(expected, actual);
355     }
356 
varid3()357     void varid3() {
358         const std::string actual = tokenize(
359             "static char str[4];\n"
360             "void f()\n"
361             "{\n"
362             "    char str[10];\n"
363             "    str[0] = 0;\n"
364             "}\n", "test.c");
365 
366         const char expected[] = "1: static char str@1 [ 4 ] ;\n"
367                                 "2: void f ( )\n"
368                                 "3: {\n"
369                                 "4: char str@2 [ 10 ] ;\n"
370                                 "5: str@2 [ 0 ] = 0 ;\n"
371                                 "6: }\n";
372 
373         ASSERT_EQUALS(expected, actual);
374     }
375 
varid4()376     void varid4() {
377         const std::string actual = tokenize(
378             "void f(const unsigned int a[])\n"
379             "{\n"
380             "    int i = *(a+10);\n"
381             "}\n", "test.c");
382 
383         const char expected[] = "1: void f ( const unsigned int a@1 [ ] )\n"
384                                 "2: {\n"
385                                 "3: int i@2 ; i@2 = * ( a@1 + 10 ) ;\n"
386                                 "4: }\n";
387 
388         ASSERT_EQUALS(expected, actual);
389     }
390 
varid5()391     void varid5() {
392         const std::string actual = tokenize(
393             "void f()\n"
394             "{\n"
395             "    int a,b;\n"
396             "}\n", "test.c");
397 
398         const char expected[] = "1: void f ( )\n"
399                                 "2: {\n"
400                                 "3: int a@1 ; int b@2 ;\n"
401                                 "4: }\n";
402 
403         ASSERT_EQUALS(expected, actual);
404     }
405 
406 
varid6()407     void varid6() {
408         const std::string actual = tokenize(
409             "int f(int a, int b)\n"
410             "{\n"
411             "    return a+b;\n"
412             "}\n", "test.c");
413 
414         const char expected[] = "1: int f ( int a@1 , int b@2 )\n"
415                                 "2: {\n"
416                                 "3: return a@1 + b@2 ;\n"
417                                 "4: }\n";
418 
419         ASSERT_EQUALS(expected, actual);
420     }
421 
422 
varid7()423     void varid7() {
424         const std::string actual = tokenize(
425             "void func() {\n"
426             "    char a[256] = \"test\";\n"
427             "    {\n"
428             "        char b[256] = \"test\";\n"
429             "    }\n"
430             "}\n", "test.c");
431 
432         const char expected[] = "1: void func ( ) {\n"
433                                 "2: char a@1 [ 256 ] = \"test\" ;\n"
434                                 "3: {\n"
435                                 "4: char b@2 [ 256 ] = \"test\" ;\n"
436                                 "5: }\n"
437                                 "6: }\n";
438 
439         ASSERT_EQUALS(expected, actual);
440     }
441 
varidReturn1()442     void varidReturn1() {
443         const std::string actual = tokenize(
444             "int f()\n"
445             "{\n"
446             "    int a;\n"
447             "    return a;\n"
448             "}\n", "test.c");
449 
450         const char expected[] = "1: int f ( )\n"
451                                 "2: {\n"
452                                 "3: int a@1 ;\n"
453                                 "4: return a@1 ;\n"
454                                 "5: }\n";
455 
456         ASSERT_EQUALS(expected, actual);
457     }
458 
varidReturn2()459     void varidReturn2() {
460         const std::string actual = tokenize(
461             "void foo()\n"
462             "{\n"
463             "    unsigned long mask = (1UL << size_) - 1;\n"
464             "    return (abits_val_ & mask);\n"
465             "}\n", "test.c");
466 
467         const char expected[] = "1: void foo ( )\n"
468                                 "2: {\n"
469                                 "3: unsigned long mask@1 ; mask@1 = ( 1UL << size_ ) - 1 ;\n"
470                                 "4: return ( abits_val_ & mask@1 ) ;\n"
471                                 "5: }\n";
472 
473         ASSERT_EQUALS(expected, actual);
474     }
475 
varid8()476     void varid8() {
477         const std::string actual = tokenize(
478             "void func()\n"
479             "{\n"
480             "    std::string str(\"test\");\n"
481             "    str.clear();\n"
482             "}");
483 
484         const char expected[] = "1: void func ( )\n"
485                                 "2: {\n"
486                                 "3: std :: string str@1 ( \"test\" ) ;\n"
487                                 "4: str@1 . clear ( ) ;\n"
488                                 "5: }\n";
489 
490         ASSERT_EQUALS(expected, actual);
491     }
492 
varid9()493     void varid9() {
494         const std::string actual = tokenize(
495             "typedef int INT32;\n", "test.c");
496 
497         const char expected[] = "1: ;\n";
498 
499         ASSERT_EQUALS(expected, actual);
500     }
501 
varid10()502     void varid10() {
503         const std::string actual = tokenize(
504             "void foo()\n"
505             "{\n"
506             "    int abc;\n"
507             "    struct abc abc1;\n"
508             "}", "test.c");
509 
510         const char expected[] = "1: void foo ( )\n"
511                                 "2: {\n"
512                                 "3: int abc@1 ;\n"
513                                 "4: struct abc abc1@2 ;\n"
514                                 "5: }\n";
515 
516         ASSERT_EQUALS(expected, actual);
517     }
518 
varid11()519     void varid11() {
520         const std::string actual = tokenize("class Foo;");
521 
522         const char expected[] = "1: class Foo ;\n";
523 
524         ASSERT_EQUALS(expected, actual);
525     }
526 
varid12()527     void varid12() {
528         const std::string actual = tokenize(
529             "static void a()\n"
530             "{\n"
531             "    class Foo *foo;\n"
532             "}");
533 
534         const char expected[] = "1: static void a ( )\n"
535                                 "2: {\n"
536                                 "3: class Foo * foo@1 ;\n"
537                                 "4: }\n";
538 
539         ASSERT_EQUALS(expected, actual);
540     }
541 
varid13()542     void varid13() {
543         const std::string actual = tokenize(
544             "void f()\n"
545             "{\n"
546             "    int a; int b;\n"
547             "    a = a;\n"
548             "}\n", "test.c");
549 
550         const char expected[] = "1: void f ( )\n"
551                                 "2: {\n"
552                                 "3: int a@1 ; int b@2 ;\n"
553                                 "4: a@1 = a@1 ;\n"
554                                 "5: }\n";
555 
556         ASSERT_EQUALS(expected, actual);
557     }
558 
varid14()559     void varid14() {
560         // Overloaded operator*
561         const std::string actual = tokenize(
562             "void foo()\n"
563             "{\n"
564             "A a;\n"
565             "B b;\n"
566             "b * a;\n"
567             "}", "test.c");
568 
569         const char expected[] = "1: void foo ( )\n"
570                                 "2: {\n"
571                                 "3: A a@1 ;\n"
572                                 "4: B b@2 ;\n"
573                                 "5: b@2 * a@1 ;\n"
574                                 "6: }\n";
575 
576         ASSERT_EQUALS(expected, actual);
577     }
578 
varid15()579     void varid15() {
580         {
581             const std::string actual = tokenize(
582                 "struct S {\n"
583                 "    struct T {\n"
584                 "    } t;\n"
585                 "} s;", "test.c");
586 
587             const char expected[] = "1: struct S {\n"
588                                     "2: struct T {\n"
589                                     "3: } ; struct T t@1 ;\n"
590                                     "4: } ; struct S s@2 ;\n";
591 
592             ASSERT_EQUALS(expected, actual);
593         }
594 
595         {
596             const std::string actual = tokenize(
597                 "struct S {\n"
598                 "    struct T {\n"
599                 "    } t;\n"
600                 "};", "test.c");
601 
602             const char expected[] = "1: struct S {\n"
603                                     "2: struct T {\n"
604                                     "3: } ; struct T t@1 ;\n"
605                                     "4: } ;\n";
606 
607             ASSERT_EQUALS(expected, actual);
608         }
609     }
610 
varid16()611     void varid16() {
612         const char code[] ="void foo()\n"
613                             "{\n"
614                             "    int x = 1;\n"
615                             "    y = (z * x);\n"
616                             "}\n";
617 
618         const char expected[] = "1: void foo ( )\n"
619                                 "2: {\n"
620                                 "3: int x@1 ; x@1 = 1 ;\n"
621                                 "4: y = z * x@1 ;\n"
622                                 "5: }\n";
623 
624         ASSERT_EQUALS(expected, tokenize(code, "test.c"));
625     }
626 
varid17()627     void varid17() { // ticket #1810
628         const char code[] ="char foo()\n"
629                             "{\n"
630                             "    char c('c');\n"
631                             "    return c;\n"
632                             "}\n";
633 
634         const char expected[] = "1: char foo ( )\n"
635                                 "2: {\n"
636                                 "3: char c@1 ( 'c' ) ;\n"
637                                 "4: return c@1 ;\n"
638                                 "5: }\n";
639 
640         ASSERT_EQUALS(expected, tokenize(code, "test.c"));
641     }
642 
varid18()643     void varid18() {
644         const char code[] ="char foo(char c)\n"
645                             "{\n"
646                             "    bar::c = c;\n"
647                             "}\n";
648 
649         const char expected[] = "1: char foo ( char c@1 )\n"
650                                 "2: {\n"
651                                 "3: bar :: c = c@1 ;\n"
652                                 "4: }\n";
653 
654         ASSERT_EQUALS(expected, tokenize(code));
655     }
656 
varid19()657     void varid19() {
658         const char code[] ="void foo()\n"
659                             "{\n"
660                             "    std::pair<std::vector<double>, int> x;\n"
661                             "}\n";
662 
663         const char expected[] = "1: void foo ( )\n"
664                                 "2: {\n"
665                                 "3: std :: pair < std :: vector < double > , int > x@1 ;\n"
666                                 "4: }\n";
667 
668         ASSERT_EQUALS(expected, tokenize(code));
669     }
670 
varid20()671     void varid20() {
672         const char code[] ="void foo()\n"
673                             "{\n"
674                             "    pair<vector<int>, vector<double> > x;\n"
675                             "}\n";
676 
677         const char expected[] = "1: void foo ( )\n"
678                                 "2: {\n"
679                                 "3: pair < vector < int > , vector < double > > x@1 ;\n"
680                                 "4: }\n";
681 
682         ASSERT_EQUALS(expected, tokenize(code));
683     }
684 
varid24()685     void varid24() {
686         const char code[] ="class foo()\n"
687                             "{\n"
688                             "public:\n"
689                             "    ;\n"
690                             "private:\n"
691                             "    static int i;\n"
692                             "};\n";
693 
694         const char expected[] = "1: class foo ( )\n"
695                                 "2: {\n"
696                                 "3: public:\n"
697                                 "4: ;\n"
698                                 "5: private:\n"
699                                 "6: static int i@1 ;\n"
700                                 "7: } ;\n";
701 
702         ASSERT_EQUALS(expected, tokenize(code));
703     }
704 
varid25()705     void varid25() {
706         const char code[] ="class foo()\n"
707                             "{\n"
708                             "public:\n"
709                             "    ;\n"
710                             "private:\n"
711                             "    mutable int i;\n"
712                             "};\n";
713 
714         const char expected[] = "1: class foo ( )\n"
715                                 "2: {\n"
716                                 "3: public:\n"
717                                 "4: ;\n"
718                                 "5: private:\n"
719                                 "6: mutable int i@1 ;\n"
720                                 "7: } ;\n";
721 
722         ASSERT_EQUALS(expected, tokenize(code));
723     }
724 
varid26()725     void varid26() {
726         const char code[] ="list<int (*)()> functions;\n";
727         const char expected[] = "1: list < int ( * ) ( ) > functions@1 ;\n";
728         ASSERT_EQUALS(expected, tokenize(code));
729     }
730 
varid27()731     void varid27() {
732         const char code[] ="int fooled_ya;\n"
733                             "fooled_ya::iterator iter;\n";
734         const char expected[] = "1: int fooled_ya@1 ;\n"
735                                 "2: fooled_ya :: iterator iter@2 ;\n";
736         ASSERT_EQUALS(expected, tokenize(code));
737     }
738 
varid28()739     void varid28() { // ticket #2630 (segmentation fault)
740         ASSERT_THROW(tokenize("template <typedef A>\n"), InternalError);
741     }
742 
varid29()743     void varid29() {
744         const char code[] ="class A {\n"
745                             "    B<C<1>,1> b;\n"
746                             "};\n";
747         const char expected[] = "1: class A {\n"
748                                 "2: B < C < 1 > , 1 > b@1 ;\n"
749                                 "3: } ;\n";
750         ASSERT_EQUALS(expected, tokenize(code));
751     }
752 
varid30()753     void varid30() { // ticket #2614
754         const char code1[] = "void f(EventPtr *eventP, ActionPtr **actionsP)\n"
755                              "{\n"
756                              "    EventPtr event = *eventP;\n"
757                              "    *actionsP = &event->actions;\n"
758                              "}\n";
759         const char expected1[] = "1: void f ( EventPtr * eventP@1 , ActionPtr * * actionsP@2 )\n"
760                                  "2: {\n"
761                                  "3: EventPtr event@3 ; event@3 = * eventP@1 ;\n"
762                                  "4: * actionsP@2 = & event@3 . actions@4 ;\n"
763                                  "5: }\n";
764         ASSERT_EQUALS(expected1, tokenize(code1, "test.c"));
765 
766         const char code2[] = "void f(int b, int c) {\n"
767                              "    x(a*b*c,10);\n"
768                              "}\n";
769         const char expected2[] = "1: void f ( int b@1 , int c@2 ) {\n"
770                                  "2: x ( a * b@1 * c@2 , 10 ) ;\n"
771                                  "3: }\n";
772         ASSERT_EQUALS(expected2, tokenize(code2, "test.c"));
773 
774         const char code3[] = "class Nullpointer : public ExecutionPath\n"
775                              " {\n"
776                              "    Nullpointer(Check *c, const unsigned int id, const std::string &name)\n"
777                              "        : ExecutionPath(c, id)\n"
778                              "    {\n"
779                              "    }\n"
780                              "}\n";
781         const char expected3[] = "1: class Nullpointer : public ExecutionPath\n"
782                                  "2: {\n"
783                                  "3: Nullpointer ( Check * c@1 , const unsigned int id@2 , const std :: string & name@3 )\n"
784                                  "4: : ExecutionPath ( c@1 , id@2 )\n"
785                                  "5: {\n"
786                                  "6: }\n"
787                                  "7: }\n";
788         ASSERT_EQUALS(expected3, tokenize(code3));
789     }
790 
varid34()791     void varid34() { // ticket #2825
792         const char code[] ="class Fred : public B1, public B2\n"
793                             "{\n"
794                             "public:\n"
795                             "    Fred() { a = 0; }\n"
796                             "private:\n"
797                             "    int a;\n"
798                             "};\n";
799         const char expected[] = "1: class Fred : public B1 , public B2\n"
800                                 "2: {\n"
801                                 "3: public:\n"
802                                 "4: Fred ( ) { a@1 = 0 ; }\n"
803                                 "5: private:\n"
804                                 "6: int a@1 ;\n"
805                                 "7: } ;\n";
806         ASSERT_EQUALS(expected, tokenize(code));
807         ASSERT_EQUALS("", errout.str());
808     }
809 
varid35()810     void varid35() { // function declaration inside function body
811         // #2937
812         const char code[] ="int foo() {\n"
813                             "    int f(x);\n"
814                             "    return f;\n"
815                             "}\n";
816         const char expected[] = "1: int foo ( ) {\n"
817                                 "2: int f@1 ( x ) ;\n"
818                                 "3: return f@1 ;\n"
819                                 "4: }\n";
820         ASSERT_EQUALS(expected, tokenize(code));
821 
822         // #4627
823         const char code2[] = "void f() {\n"
824                              "  int  *p;\n"
825                              "  void bar(int *p);\n"
826                              "}";
827         const char expected2[] = "1: void f ( ) {\n"
828                                  "2: int * p@1 ;\n"
829                                  "3: void bar ( int * p ) ;\n"
830                                  "4: }\n";
831         ASSERT_EQUALS(expected2, tokenize(code2));
832 
833         // #7740
834         const char code3[] = "Float f(float scale) {\n"
835                              "    return Float(val * scale);\n"
836                              "}\n";
837         const char expected3[] = "1: Float f ( float scale@1 ) {\n"
838                                  "2: return Float ( val * scale@1 ) ;\n"
839                                  "3: }\n";
840         ASSERT_EQUALS(expected3, tokenize(code3));
841     }
842 
varid36()843     void varid36() { // ticket #2980 (segmentation fault)
844         const char code[] ="#elif A\n"
845                             "A,a<b<x0\n";
846         tokenize(code);
847         ASSERT_EQUALS("", errout.str());
848     }
849 
varid37()850     void varid37() {
851         {
852             const char code[] = "void blah() {"
853                                 "    Bar bar(*x);"
854                                 "}";
855             ASSERT_EQUALS("1: void blah ( ) { Bar bar@1 ( * x ) ; }\n",
856                           tokenize(code));
857         }
858         {
859             const char code[] = "void blah() {"
860                                 "    Bar bar(&x);"
861                                 "}";
862             ASSERT_EQUALS("1: void blah ( ) { Bar bar@1 ( & x ) ; }\n",
863                           tokenize(code));
864         }
865     }
866 
varid38()867     void varid38() {
868         const char code[] = "FOO class C;\n";
869         ASSERT_EQUALS("1: FOO class C ;\n",
870                       tokenize(code));
871     }
872 
varid39()873     void varid39() {
874         // const..
875         {
876             const char code[] = "void f(FOO::BAR const);\n";
877             ASSERT_EQUALS("1: void f ( const FOO :: BAR ) ;\n",
878                           tokenize(code));
879         }
880         {
881             const char code[] = "static int const SZ = 22;\n";
882             ASSERT_EQUALS("1: static const int SZ@1 = 22 ;\n",
883                           tokenize(code, "test.c"));
884         }
885     }
886 
varid40()887     void varid40() {
888         const char code[] ="extern \"C\" int (*a())();";
889         ASSERT_EQUALS("1: int * a ( ) ;\n",
890                       tokenize(code));
891     }
892 
varid41()893     void varid41() {
894         const char code1[] = "union evt; void f(const evt & event);";
895         ASSERT_EQUALS("1: union evt ; void f ( const evt & event@1 ) ;\n",
896                       tokenize(code1, "test.c"));
897 
898         const char code2[] = "struct evt; void f(const evt & event);";
899         ASSERT_EQUALS("1: struct evt ; void f ( const evt & event@1 ) ;\n",
900                       tokenize(code2, "test.c"));
901     }
902 
varid42()903     void varid42() {
904         const char code[] ="namespace fruit { struct banana {}; };\n"
905                             "class Fred {\n"
906                             "public:\n"
907                             "     struct fruit::banana Bananas[25];\n"
908                             "};";
909         ASSERT_EQUALS("1: namespace fruit { struct banana { } ; } ;\n"
910                       "2: class Fred {\n"
911                       "3: public:\n"
912                       "4: struct fruit :: banana Bananas@1 [ 25 ] ;\n"
913                       "5: } ;\n",
914                       tokenize(code));
915     }
916 
varid43()917     void varid43() {
918         const char code[] ="int main(int flag) { if(a & flag) { return 1; } }";
919         ASSERT_EQUALS("1: int main ( int flag@1 ) { if ( a & flag@1 ) { return 1 ; } }\n",
920                       tokenize(code, "test.c"));
921     }
922 
varid44()923     void varid44() {
924         const char code[] ="class A:public B,public C,public D {};";
925         ASSERT_EQUALS("1: class A : public B , public C , public D { } ;\n",
926                       tokenize(code));
927     }
928 
varid45()929     void varid45() { // #3466
930         const char code[] ="void foo() { B b(this); A a(this, b); }";
931         ASSERT_EQUALS("1: void foo ( ) { B b@1 ( this ) ; A a@2 ( this , b@1 ) ; }\n",
932                       tokenize(code));
933     }
934 
varid46()935     void varid46() { // #3756
936         const char code[] ="void foo() { int t; x = (struct t *)malloc(); f(t); }";
937         ASSERT_EQUALS("1: void foo ( ) { int t@1 ; x = ( struct t * ) malloc ( ) ; f ( t@1 ) ; }\n",
938                       tokenize(code, "test.c"));
939     }
940 
varid47()941     void varid47() { // function parameters
942         // #3768
943         {
944             const char code[] ="void f(std::string &string, std::string &len) {}";
945             ASSERT_EQUALS("1: void f ( std :: string & string@1 , std :: string & len@2 ) { }\n",
946                           tokenize(code, "test.cpp"));
947         }
948 
949         // #4729
950         {
951             const char code[] = "int x;\n"
952                                 "void a(int x);\n"
953                                 "void b() { x = 0; }\n";
954             ASSERT_EQUALS("1: int x@1 ;\n"
955                           "2: void a ( int x@2 ) ;\n"
956                           "3: void b ( ) { x@1 = 0 ; }\n",
957                           tokenize(code));
958         }
959     }
960 
varid48()961     void varid48() {  // #3785 - return (a*b)
962         const char code[] ="int X::f(int b) const { return(a*b); }";
963         ASSERT_EQUALS("1: int X :: f ( int b@1 ) const { return ( a * b@1 ) ; }\n",
964                       tokenize(code));
965     }
966 
varid49()967     void varid49() {  // #3799 - void f(std::vector<int>)
968         const char code[] ="void f(std::vector<int>)";
969         ASSERT_EQUALS("1: void f ( std :: vector < int > )\n",
970                       tokenize(code, "test.cpp"));
971     }
972 
varid50()973     void varid50() {  // #3760 - explicit
974         const char code[] ="class A { explicit A(const A&); };";
975         ASSERT_EQUALS("1: class A { explicit A ( const A & ) ; } ;\n",
976                       tokenize(code, "test.cpp"));
977     }
978 
varid51()979     void varid51() {  // don't set varid on template function
980         const char code[] ="T t; t.x<0>();";
981         ASSERT_EQUALS("1: T t@1 ; t@1 . x < 0 > ( ) ;\n",
982                       tokenize(code, "test.cpp"));
983     }
984 
varid52()985     void varid52() {
986         const char code[] ="A<B<C>::D> e;\n"
987                             "B< C<> > b[10];\n"
988                             "B<C<>> c[10];";
989         ASSERT_EQUALS("1: A < B < C > :: D > e@1 ;\n"
990                       "2: B < C < > > b@2 [ 10 ] ;\n"
991                       "3: B < C < > > c@3 [ 10 ] ;\n",
992                       tokenize(code, "test.cpp"));
993     }
994 
varid53()995     void varid53() { // #4172 - Template instantiation: T<&functionName> list[4];
996         ASSERT_EQUALS("1: A < & f > list@1 [ 4 ] ;\n",
997                       tokenize("A<&f> list[4];", "test.cpp"));
998     }
999 
varid54()1000     void varid54() { // hang
1001         // Original source code: libgc
1002         tokenize("STATIC ptr_t GC_approx_sp(void) { word sp; sp = (word)&sp; return((ptr_t)sp); }");
1003     }
1004 
varid55()1005     void varid55() { // Ticket #5868
1006         const char code[] =     "typedef struct foo {} foo; "
1007                             "void bar1(struct foo foo) {} "
1008                             "void baz1(foo foo) {} "
1009                             "void bar2(struct foo& foo) {} "
1010                             "void baz2(foo& foo) {} "
1011                             "void bar3(struct foo* foo) {} "
1012                             "void baz3(foo* foo) {}";
1013         const char expected[] = "1: "
1014                                 "struct foo { } ; "
1015                                 "void bar1 ( struct foo foo@1 ) { } "
1016                                 "void baz1 ( struct foo foo@2 ) { } "
1017                                 "void bar2 ( struct foo & foo@3 ) { } "
1018                                 "void baz2 ( struct foo & foo@4 ) { } "
1019                                 "void bar3 ( struct foo * foo@5 ) { } "
1020                                 "void baz3 ( struct foo * foo@6 ) { }\n";
1021         ASSERT_EQUALS(expected, tokenize(code, "test.cpp"));
1022     }
1023 
varid56()1024     void varid56() { // Ticket #6548 - function with a throw()
1025         const char code1[] = "void fred(int x) throw() {}"
1026                              "void wilma() { x++; }";
1027         const char expected1[] = "1: "
1028                                  "void fred ( int x@1 ) throw ( ) { } "
1029                                  "void wilma ( ) { x ++ ; }\n";
1030         ASSERT_EQUALS(expected1, tokenize(code1, "test.cpp"));
1031 
1032         const char code2[] = "void fred(int x) const throw(EXCEPT) {}"
1033                              "void wilma() { x++; }";
1034         const char expected2[] = "1: "
1035                                  "void fred ( int x@1 ) const throw ( EXCEPT ) { } "
1036                                  "void wilma ( ) { x ++ ; }\n";
1037         ASSERT_EQUALS(expected2, tokenize(code2, "test.cpp"));
1038 
1039         const char code3[] = "void fred(int x) throw() ABCD {}"
1040                              "void wilma() { x++; }";
1041         const char expected3[] = "1: "
1042                                  "void fred ( int x@1 ) throw ( ) { } "
1043                                  "void wilma ( ) { x ++ ; }\n";
1044         ASSERT_EQUALS(expected3, tokenize(code3, "test.cpp"));
1045 
1046         const char code4[] = "void fred(int x) noexcept() {}"
1047                              "void wilma() { x++; }";
1048         const char expected4[] = "1: "
1049                                  "void fred ( int x@1 ) noexcept ( ) { } "
1050                                  "void wilma ( ) { x ++ ; }\n";
1051         ASSERT_EQUALS(expected4, tokenize(code4, "test.cpp"));
1052 
1053         const char code5[] = "void fred(int x) noexcept {}"
1054                              "void wilma() { x++; }";
1055         const char expected5[] = "1: "
1056                                  "void fred ( int x@1 ) noexcept ( true ) { } "
1057                                  "void wilma ( ) { x ++ ; }\n";
1058         ASSERT_EQUALS(expected5, tokenize(code5, "test.cpp"));
1059 
1060         const char code6[] = "void fred(int x) noexcept ( false ) {}"
1061                              "void wilma() { x++; }";
1062         const char expected6[] = "1: "
1063                                  "void fred ( int x@1 ) noexcept ( false ) { } "
1064                                  "void wilma ( ) { x ++ ; }\n";
1065         ASSERT_EQUALS(expected6, tokenize(code6, "test.cpp"));
1066     }
1067 
varid57()1068     void varid57() { // #6636: new scope by {}
1069         const char code1[] = "void SmoothPath() {\n"
1070                              "    {\n" // new scope
1071                              "        float dfx = (p2p0.x > 0.0f)?\n"
1072                              "                    ((n0->xmax() * SQUARE_SIZE) - p0.x):\n"
1073                              "                    ((n0->xmin() * SQUARE_SIZE) - p0.x);\n"
1074                              "        float tx = dfx / dx;\n"
1075                              "        if (hEdge) {\n"
1076                              "        }\n"
1077                              "        if (vEdge) {\n"
1078                              "            pi.z = tx;\n"
1079                              "        }\n"
1080                              "    }\n"
1081                              "}\n";
1082         const char expected1[] = "1: void SmoothPath ( ) {\n"
1083                                  "2:\n"
1084                                  "3: float dfx@1 ; dfx@1 = ( p2p0 . x > 0.0f ) ?\n"
1085                                  "4: ( ( n0 . xmax ( ) * SQUARE_SIZE ) - p0 . x ) :\n"
1086                                  "5: ( ( n0 . xmin ( ) * SQUARE_SIZE ) - p0 . x ) ;\n"
1087                                  "6: float tx@2 ; tx@2 = dfx@1 / dx ;\n"
1088                                  "7: if ( hEdge ) {\n"
1089                                  "8: }\n"
1090                                  "9: if ( vEdge ) {\n"
1091                                  "10: pi . z = tx@2 ;\n"
1092                                  "11: }\n"
1093                                  "12:\n"
1094                                  "13: }\n";
1095         ASSERT_EQUALS(expected1, tokenize(code1, "test.cpp"));
1096     }
1097 
varid58()1098     void varid58() { // #6638: for loop in for condition
1099         const char code1[] = "void f() {\n"
1100                              "    for (int i;\n"
1101                              "         ({for(int i;i;++i){i++;}i++;}),i;\n"
1102                              "         ({for(int i;i;++i){i++;}i++;}),i++) {\n"
1103                              "         i++;\n"
1104                              "    }\n"
1105                              "}\n";
1106         const char expected1[] = "1: void f ( ) {\n"
1107                                  "2: for ( int i@1 ;\n"
1108                                  "3: ( { for ( int i@2 ; i@2 ; ++ i@2 ) { i@2 ++ ; } i@1 ++ ; } ) , i@1 ;\n"
1109                                  "4: ( { for ( int i@3 ; i@3 ; ++ i@3 ) { i@3 ++ ; } i@1 ++ ; } ) , i@1 ++ ) {\n"
1110                                  "5: i@1 ++ ;\n"
1111                                  "6: }\n"
1112                                  "7: }\n";
1113         ASSERT_EQUALS(expected1, tokenize(code1, "test.cpp"));
1114     }
1115 
varid59()1116     void varid59() { // #6696
1117         const char code[] = "class DLLSYM B;\n"
1118                             "struct B {\n"
1119                             "    ~B() {}\n"
1120                             "};";
1121         const char expected[] = "1: class DLLSYM B@1 ;\n" // In this line, we cannot really do better...
1122                                 "2: struct B {\n"
1123                                 "3: ~ B@1 ( ) { }\n" // ...but here we could
1124                                 "4: } ;\n";
1125         const char wanted[] = "1: class DLLSYM B@1 ;\n"
1126                               "2: struct B {\n"
1127                               "3: ~ B ( ) { }\n"
1128                               "4: } ;\n";
1129         TODO_ASSERT_EQUALS(wanted, expected, tokenize(code, "test.cpp"));
1130     }
1131 
varid60()1132     void varid60() { // #7267 - cast
1133         ASSERT_EQUALS("1: a = ( x y ) 10 ;\n",
1134                       tokenize("a=(x y)10;"));
1135     }
1136 
varid61()1137     void varid61() {
1138         const char code[] = "void foo(int b) {\n"
1139                             "  void bar(int a, int b) {}\n"
1140                             "}";
1141         const char expected[] = "1: void foo ( int b@1 ) {\n"
1142                                 "2: void bar ( int a@2 , int b@3 ) { }\n"
1143                                 "3: }\n";
1144         ASSERT_EQUALS(expected, tokenize(code));
1145     }
1146 
varid62()1147     void varid62() {
1148         const char code[] = "void bar(int,int);\n"
1149                             "void f() {\n"
1150                             "    for (size_t c = 0; c < 42; ++c) {\n"
1151                             "        int x;\n"
1152                             "        bar(r, r * x);\n"
1153                             "    }\n"
1154                             "}";
1155         // Ensure that there is only one variable id for "x"
1156         ASSERT_EQUALS("same varid", compareVaridsForVariable(code, "x"));
1157     }
1158 
varid63()1159     void varid63() {
1160         const char code[] = "void f(boost::optional<int> const& x) {}";
1161         const char expected[] = "1: void f ( boost :: optional < int > const & x@1 ) { }\n";
1162         ASSERT_EQUALS(expected, tokenize(code));
1163     }
1164 
varid64()1165     void varid64() {
1166         const char code[] = "extern const char (*x[256]);";
1167         const char expected[] = "1: extern const char ( * x@1 [ 256 ] ) ;\n";
1168         ASSERT_EQUALS(expected, tokenize(code));
1169     }
1170 
varid_for_1()1171     void varid_for_1() {
1172         const char code[] = "void foo(int a, int b) {\n"
1173                             "  for (int a=1,b=2;;) {}\n"
1174                             "}";
1175         const char expected[] = "1: void foo ( int a@1 , int b@2 ) {\n"
1176                                 "2: for ( int a@3 = 1 , b@4 = 2 ; ; ) { }\n"
1177                                 "3: }\n";
1178         ASSERT_EQUALS(expected, tokenize(code));
1179     }
1180 
varid_for_2()1181     void varid_for_2() {
1182         const char code[] = "void foo(int a, int b) {\n"
1183                             "  for (int a=f(x,y,z),b=2;;) {}\n"
1184                             "}";
1185         const char expected[] = "1: void foo ( int a@1 , int b@2 ) {\n"
1186                                 "2: for ( int a@3 = f ( x , y , z ) , b@4 = 2 ; ; ) { }\n"
1187                                 "3: }\n";
1188         ASSERT_EQUALS(expected, tokenize(code));
1189     }
1190 
varid_cpp_keywords_in_c_code()1191     void varid_cpp_keywords_in_c_code() {
1192         const char code[] = "void f() {\n"
1193                             "    delete d;\n"
1194                             "    throw t;\n"
1195                             "}";
1196 
1197         const char expected[] = "1: void f ( ) {\n"
1198                                 "2: delete d@1 ;\n"
1199                                 "3: throw t@2 ;\n"
1200                                 "4: }\n";
1201 
1202         ASSERT_EQUALS(expected, tokenize(code, "test.c"));
1203     }
1204 
varid_cpp_keywords_in_c_code2()1205     void varid_cpp_keywords_in_c_code2() { // #5373
1206         const char code[] = "int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, "
1207                             "unsigned long bits, int wake, int delete, struct extent_state **cached_state, "
1208                             "gfp_t mask) {\n"
1209                             "  struct extent_state *state;\n"
1210                             "}"
1211                             "int clear_extent_dirty() {\n"
1212                             "  return clear_extent_bit(tree, start, end, EXTENT_DIRTY | EXTENT_DELALLOC | "
1213                             "                          EXTENT_DO_ACCOUNTING, 0, 0, NULL, mask);\n"
1214                             "}";
1215         tokenize(code, "test.c");
1216     }
1217 
varidFunctionCall1()1218     void varidFunctionCall1() {
1219         const char code[] ="void f() {\n"
1220                             "    int x;\n"
1221                             "    x = a(y*x,10);\n"
1222                             "}";
1223         const char expected[] = "1: void f ( ) {\n"
1224                                 "2: int x@1 ;\n"
1225                                 "3: x@1 = a ( y * x@1 , 10 ) ;\n"
1226                                 "4: }\n";
1227         ASSERT_EQUALS(expected, tokenize(code, "test.c"));
1228     }
1229 
varidFunctionCall2()1230     void varidFunctionCall2() {
1231         // #2491
1232         const char code[] ="void f(int b) {\n"
1233                             "    x(a*b,10);\n"
1234                             "}";
1235         const std::string expected1("1: void f ( int b@1 ) {\n"
1236                                     "2: x ( a * b");
1237         const std::string expected2(" , 10 ) ;\n"
1238                                     "3: }\n");
1239         ASSERT_EQUALS(expected1+"@1"+expected2, tokenize(code, "test.c"));
1240     }
1241 
varidFunctionCall3()1242     void varidFunctionCall3() {
1243         // Ticket #2339
1244         const char code[] ="void f() {\n"
1245                             "    int a = 0;\n"
1246                             "    int b = c - (foo::bar * a);\n"
1247                             "}";
1248 
1249         const char expected[] = "1: void f ( ) {\n"
1250                                 "2: int a@1 ; a@1 = 0 ;\n"
1251                                 "3: int b@2 ; b@2 = c - ( foo :: bar * a@1 ) ;\n"
1252                                 "4: }\n";
1253 
1254         ASSERT_EQUALS(expected, tokenize(code));
1255     }
1256 
varidFunctionCall4()1257     void varidFunctionCall4() {
1258         // Ticket #3280
1259         const char code1[] = "void f() { int x; fun(a,b*x); }";
1260         ASSERT_EQUALS("1: void f ( ) { int x@1 ; fun ( a , b * x@1 ) ; }\n",
1261                       tokenize(code1, "test.c"));
1262         const char code2[] = "void f(int a) { int x; fun(a,b*x); }";
1263         ASSERT_EQUALS("1: void f ( int a@1 ) { int x@2 ; fun ( a@1 , b * x@2 ) ; }\n",
1264                       tokenize(code2, "test.c"));
1265     }
1266 
varidFunctionCall5()1267     void varidFunctionCall5() {
1268         const char code[] = "void foo() { (f(x[2]))(x[2]); }";
1269         ASSERT_EQUALS("1: void foo ( ) { f ( x [ 2 ] ) ( x [ 2 ] ) ; }\n",
1270                       tokenize(code, "test.c"));
1271     }
1272 
varidStl()1273     void varidStl() {
1274         const std::string actual = tokenize(
1275             "list<int> ints;\n"
1276             "list<int>::iterator it;\n"
1277             "std::vector<std::string> dirs;\n"
1278             "std::map<int, int> coords;\n"
1279             "std::tr1::unordered_map<int, int> xy;\n"
1280             "std::list<boost::wave::token_id> tokens;\n"
1281             "static std::vector<CvsProcess*> ex1;\n"
1282             "extern std::vector<CvsProcess*> ex2;\n"
1283             "std::map<int, 1> m;");
1284 
1285         const char expected[] = "1: list < int > ints@1 ;\n"
1286                                 "2: list < int > :: iterator it@2 ;\n"
1287                                 "3: std :: vector < std :: string > dirs@3 ;\n"
1288                                 "4: std :: map < int , int > coords@4 ;\n"
1289                                 "5: std :: tr1 :: unordered_map < int , int > xy@5 ;\n"
1290                                 "6: std :: list < boost :: wave :: token_id > tokens@6 ;\n"
1291                                 "7: static std :: vector < CvsProcess * > ex1@7 ;\n"
1292                                 "8: extern std :: vector < CvsProcess * > ex2@8 ;\n"
1293                                 "9: std :: map < int , 1 > m@9 ;\n";
1294 
1295         ASSERT_EQUALS(expected, actual);
1296     }
1297 
varidStl2()1298     void varidStl2() {
1299         const std::string actual = tokenize("std::bitset<static_cast<int>(2)> x;");
1300 
1301         const char expected[] = "1: std :: bitset < static_cast < int > ( 2 ) > x@1 ;\n";
1302 
1303         ASSERT_EQUALS(expected, actual);
1304     }
1305 
varid_newauto()1306     void varid_newauto() {
1307         ASSERT_EQUALS("1: void f ( ) { const new auto ( 0 ) ; }\n",
1308                       tokenize("void f(){new const auto(0);}"));
1309     }
1310 
varid_delete()1311     void varid_delete() {
1312         const std::string actual = tokenize(
1313             "void f()\n"
1314             "{\n"
1315             "  int *a;\n"
1316             "  delete a;\n"
1317             "}");
1318 
1319         const char expected[] = "1: void f ( )\n"
1320                                 "2: {\n"
1321                                 "3: int * a@1 ;\n"
1322                                 "4: delete a@1 ;\n"
1323                                 "5: }\n";
1324 
1325         ASSERT_EQUALS(expected, actual);
1326     }
1327 
varid_functions()1328     void varid_functions() {
1329         {
1330             const std::string actual = tokenize(
1331                 "void f();\n"
1332                 "void f(){}\n", "test.c");
1333 
1334             const char expected[] = "1: void f ( ) ;\n"
1335                                     "2: void f ( ) { }\n";
1336 
1337             ASSERT_EQUALS(expected, actual);
1338         }
1339 
1340         {
1341             const std::string actual = tokenize(
1342                 "A f(3);\n"
1343                 "A f2(true);\n"
1344                 "A g();\n"
1345                 "A e(int c);\n", "test.c");
1346 
1347             const char expected[] = "1: A f@1 ( 3 ) ;\n"
1348                                     "2: A f2@2 ( true ) ;\n"
1349                                     "3: A g ( ) ;\n"
1350                                     "4: A e ( int c@3 ) ;\n";
1351 
1352             ASSERT_EQUALS(expected, actual);
1353         }
1354 
1355         {
1356             const std::string actual = tokenize(
1357                 "void f1(int &p)\n"
1358                 "{\n"
1359                 "    p = 0;\n"
1360                 "}\n"
1361                 "void f2(std::string &str)\n"
1362                 "{\n"
1363                 "   str.clear();\n"
1364                 "}\n"
1365                 "void f3(const std::string &s)\n"
1366                 "{\n"
1367                 "    s.size();\n"
1368                 "}");
1369 
1370             const char expected[] = "1: void f1 ( int & p@1 )\n"
1371                                     "2: {\n"
1372                                     "3: p@1 = 0 ;\n"
1373                                     "4: }\n"
1374                                     "5: void f2 ( std :: string & str@2 )\n"
1375                                     "6: {\n"
1376                                     "7: str@2 . clear ( ) ;\n"
1377                                     "8: }\n"
1378                                     "9: void f3 ( const std :: string & s@3 )\n"
1379                                     "10: {\n"
1380                                     "11: s@3 . size ( ) ;\n"
1381                                     "12: }\n";
1382 
1383             ASSERT_EQUALS(expected, actual);
1384         }
1385 
1386         {
1387             const std::string actual = tokenize("void f(struct foobar);", "test.c");
1388             const char expected[] = "1: void f ( struct foobar ) ;\n";
1389             ASSERT_EQUALS(expected, actual);
1390         }
1391 
1392         {
1393             const std::string actual = tokenize("bool f(X x, int=3);", "test.cpp");
1394             const char expected[] = "1: bool f ( X x@1 , int = 3 ) ;\n";
1395             ASSERT_EQUALS(expected, actual);
1396         }
1397     }
1398 
varid_sizeof()1399     void varid_sizeof() {
1400         const char code[] = "x = sizeof(a*b);";
1401         const char expected[] = "1: x = sizeof ( a * b ) ;\n";
1402         ASSERT_EQUALS(expected, tokenize(code, "test.c"));
1403     }
1404 
varid_reference_to_containers()1405     void varid_reference_to_containers() {
1406         const std::string actual = tokenize(
1407             "void f()\n"
1408             "{\n"
1409             "    std::vector<int> b;\n"
1410             "    std::vector<int> &a = b;\n"
1411             "    std::vector<int> *c = &b;\n"
1412             "}");
1413 
1414         const char expected[] = "1: void f ( )\n"
1415                                 "2: {\n"
1416                                 "3: std :: vector < int > b@1 ;\n"
1417                                 "4: std :: vector < int > & a@2 = b@1 ;\n"
1418                                 "5: std :: vector < int > * c@3 ; c@3 = & b@1 ;\n"
1419                                 "6: }\n";
1420 
1421         ASSERT_EQUALS(expected, actual);
1422     }
1423 
varid_in_class1()1424     void varid_in_class1() {
1425         {
1426             const std::string actual = tokenize(
1427                 "class Foo\n"
1428                 "{\n"
1429                 "public:\n"
1430                 "    std::string name1;\n"
1431                 "    std::string name2;\n"
1432                 "};");
1433 
1434             const char expected[] = "1: class Foo\n"
1435                                     "2: {\n"
1436                                     "3: public:\n"
1437                                     "4: std :: string name1@1 ;\n"
1438                                     "5: std :: string name2@2 ;\n"
1439                                     "6: } ;\n";
1440 
1441             ASSERT_EQUALS(expected, actual);
1442         }
1443 
1444         {
1445             const std::string actual = tokenize(
1446                 "class foo\n"
1447                 "{\n"
1448                 "public:\n"
1449                 "    void do_something(const int x, const int y);\n"
1450                 "    void bar();\n"
1451                 "};\n"
1452                 "\n"
1453                 "void foo::bar()\n"
1454                 "{\n"
1455                 "    POINT pOutput = { 0 , 0 };\n"
1456                 "    int x = pOutput.x;\n"
1457                 "    int y = pOutput.y;\n"
1458                 "}");
1459 
1460             const char expected[] = "1: class foo\n"
1461                                     "2: {\n"
1462                                     "3: public:\n"
1463                                     "4: void do_something ( const int x@1 , const int y@2 ) ;\n"
1464                                     "5: void bar ( ) ;\n"
1465                                     "6: } ;\n"
1466                                     "7:\n"
1467                                     "8: void foo :: bar ( )\n"
1468                                     "9: {\n"
1469                                     "10: POINT pOutput@3 ; pOutput@3 = { 0 , 0 } ;\n"
1470                                     "11: int x@4 ; x@4 = pOutput@3 . x@5 ;\n"
1471                                     "12: int y@6 ; y@6 = pOutput@3 . y@7 ;\n"
1472                                     "13: }\n";
1473 
1474             ASSERT_EQUALS(expected, actual);
1475         }
1476     }
1477 
varid_in_class2()1478     void varid_in_class2() {
1479         const std::string actual = tokenize(
1480             "struct Foo {\n"
1481             "    int x;\n"
1482             "};\n"
1483             "\n"
1484             "struct Bar {\n"
1485             "    Foo foo;\n"
1486             "    int x;\n"
1487             "    void f();\n"
1488             "};\n"
1489             "\n"
1490             "void Bar::f()\n"
1491             "{\n"
1492             "    foo.x = x;\n"
1493             "}");
1494         const char expected[] = "1: struct Foo {\n"
1495                                 "2: int x@1 ;\n"
1496                                 "3: } ;\n"
1497                                 "4:\n"
1498                                 "5: struct Bar {\n"
1499                                 "6: Foo foo@2 ;\n"
1500                                 "7: int x@3 ;\n"
1501                                 "8: void f ( ) ;\n"
1502                                 "9: } ;\n"
1503                                 "10:\n"
1504                                 "11: void Bar :: f ( )\n"
1505                                 "12: {\n"
1506                                 "13: foo@2 . x@4 = x@3 ;\n"
1507                                 "14: }\n";
1508         ASSERT_EQUALS(expected, actual);
1509     }
1510 
varid_in_class3()1511     void varid_in_class3() {
1512         const char code[] = "class Foo {\n"
1513                             "    void blah() {\n"
1514                             "        Bar x(*this);\n"  // <- ..
1515                             "    }\n"
1516                             "    int x;\n"   // <- .. don't assign same varid
1517                             "};";
1518         ASSERT_EQUALS("1: class Foo {\n"
1519                       "2: void blah ( ) {\n"
1520                       "3: Bar x@1 ( * this ) ;\n"
1521                       "4: }\n"
1522                       "5: int x@2 ;\n"
1523                       "6: } ;\n", tokenize(code));
1524     }
1525 
varid_in_class4()1526     void varid_in_class4() {
1527         const char code[] = "class Foo {\n"
1528                             "public: class C;\n"
1529                             "};";
1530         ASSERT_EQUALS("1: class Foo {\n"
1531                       "2: public: class C ;\n"
1532                       "3: } ;\n",
1533                       tokenize(code));
1534     }
1535 
varid_in_class5()1536     void varid_in_class5() {
1537         const char code[] = "struct Foo {\n"
1538                             "    std::vector<::X> v;\n"
1539                             "}";
1540         ASSERT_EQUALS("1: struct Foo {\n"
1541                       "2: std :: vector < :: X > v@1 ;\n"
1542                       "3: }\n",
1543                       tokenize(code));
1544     }
1545 
varid_in_class6()1546     void varid_in_class6() {
1547         const char code[] = "class A {\n"
1548                             "    void f(const char *str) const {\n"
1549                             "        std::stringstream sst;\n"
1550                             "        sst.str();\n"
1551                             "    }\n"
1552                             "};";
1553         ASSERT_EQUALS("1: class A {\n"
1554                       "2: void f ( const char * str@1 ) const {\n"
1555                       "3: std :: stringstream sst@2 ;\n"
1556                       "4: sst@2 . str ( ) ;\n"
1557                       "5: }\n"
1558                       "6: } ;\n",
1559                       tokenize(code));
1560     }
1561 
varid_in_class7()1562     void varid_in_class7() {
1563         const char code[] = "class A {\n"
1564                             "    void f() {\n"
1565                             "        abc.a = 0;\n"
1566                             "    }\n"
1567                             "    struct ABC abc;\n"
1568                             "};";
1569         ASSERT_EQUALS("1: class A {\n"
1570                       "2: void f ( ) {\n"
1571                       "3: abc@1 . a@2 = 0 ;\n"
1572                       "4: }\n"
1573                       "5: struct ABC abc@1 ;\n"
1574                       "6: } ;\n",
1575                       tokenize(code));
1576     }
1577 
varid_in_class8()1578     void varid_in_class8() {  // #3776 - unknown macro
1579         const char code[] = "class A {\n"
1580                             "  UNKNOWN_MACRO(A)\n"
1581                             "private:\n"
1582                             "  int x;\n"
1583                             "};";
1584         ASSERT_EQUALS("1: class A {\n"
1585                       "2: UNKNOWN_MACRO ( A )\n"
1586                       "3: private:\n"
1587                       "4: int x@1 ;\n"
1588                       "5: } ;\n",
1589                       tokenize(code));
1590     }
1591 
varid_in_class9()1592     void varid_in_class9() {  // #4291 - id for variables accessed through 'this'
1593         const char code1[] = "class A {\n"
1594                              "  int var;\n"
1595                              "public:\n"
1596                              "  void setVar();\n"
1597                              "};\n"
1598                              "void A::setVar() {\n"
1599                              "  this->var = var;\n"
1600                              "}";
1601         ASSERT_EQUALS("1: class A {\n"
1602                       "2: int var@1 ;\n"
1603                       "3: public:\n"
1604                       "4: void setVar ( ) ;\n"
1605                       "5: } ;\n"
1606                       "6: void A :: setVar ( ) {\n"
1607                       "7: this . var@1 = var@1 ;\n"
1608                       "8: }\n",
1609                       tokenize(code1));
1610 
1611         const char code2[] = "class Foo : public FooBase {\n"
1612                              "    void Clone(FooBase& g);\n"
1613                              "    short m_bar;\n"
1614                              "};\n"
1615                              "void Foo::Clone(FooBase& g) {\n"
1616                              "    g->m_bar = m_bar;\n"
1617                              "}";
1618         ASSERT_EQUALS("1: class Foo : public FooBase {\n"
1619                       "2: void Clone ( FooBase & g@1 ) ;\n"
1620                       "3: short m_bar@2 ;\n"
1621                       "4: } ;\n"
1622                       "5: void Foo :: Clone ( FooBase & g@3 ) {\n"
1623                       "6: g@3 . m_bar@4 = m_bar@2 ;\n"
1624                       "7: }\n",
1625                       tokenize(code2)); // #4311
1626     }
1627 
varid_in_class10()1628     void varid_in_class10() {
1629         const char code[] = "class Foo : public FooBase {\n"
1630                             "    void Clone(FooBase& g);\n"
1631                             "    short m_bar;\n"
1632                             "};\n"
1633                             "void Foo::Clone(FooBase& g) {\n"
1634                             "    ((FooBase)g)->m_bar = m_bar;\n"
1635                             "}";
1636         ASSERT_EQUALS("1: class Foo : public FooBase {\n"
1637                       "2: void Clone ( FooBase & g@1 ) ;\n"
1638                       "3: short m_bar@2 ;\n"
1639                       "4: } ;\n"
1640                       "5: void Foo :: Clone ( FooBase & g@3 ) {\n"
1641                       "6: ( ( FooBase ) g@3 ) . m_bar@4 = m_bar@2 ;\n"
1642                       "7: }\n",
1643                       tokenize(code));
1644     }
1645 
varid_in_class11()1646     void varid_in_class11() { // #4277 - anonymous union
1647         const char code1[] = "class Foo {\n"
1648                              "    union { float a; int b; };\n"
1649                              "    void f() { a=0; }\n"
1650                              "};";
1651         ASSERT_EQUALS("1: class Foo {\n"
1652                       "2: union { float a@1 ; int b@2 ; } ;\n"
1653                       "3: void f ( ) { a@1 = 0 ; }\n"
1654                       "4: } ;\n",
1655                       tokenize(code1));
1656 
1657         const char code2[] = "class Foo {\n"
1658                              "    void f() { a=0; }\n"
1659                              "    union { float a; int b; };\n"
1660                              "};";
1661         ASSERT_EQUALS("1: class Foo {\n"
1662                       "2: void f ( ) { a@1 = 0 ; }\n"
1663                       "3: union { float a@1 ; int b@2 ; } ;\n"
1664                       "4: } ;\n",
1665                       tokenize(code2));
1666 
1667         const char code3[] = "void f() {\n"
1668                              "    union {\n"
1669                              "        struct {\n"
1670                              "            char a, b, c, d;\n"
1671                              "        };\n"
1672                              "        int abcd;\n"
1673                              "    };\n"
1674                              "    g(abcd);\n"
1675                              "    h(a, b, c, d);\n"
1676                              "}";
1677         ASSERT_EQUALS("1: void f ( ) {\n"
1678                       "2: union {\n"
1679                       "3: struct {\n"
1680                       "4: char a@1 ; char b@2 ; char c@3 ; char d@4 ;\n"
1681                       "5: } ;\n"
1682                       "6: int abcd@5 ;\n"
1683                       "7: } ;\n"
1684                       "8: g ( abcd@5 ) ;\n"
1685                       "9: h ( a@1 , b@2 , c@3 , d@4 ) ;\n"
1686                       "10: }\n",
1687                       tokenize(code3));
1688 
1689         // #7444
1690         const char code4[] = "class Foo {\n"
1691                              "    void f(float a) { this->a = a; }\n"
1692                              "    union { float a; int b; };\n"
1693                              "};";
1694         ASSERT_EQUALS("1: class Foo {\n"
1695                       "2: void f ( float a@1 ) { this . a@2 = a@1 ; }\n"
1696                       "3: union { float a@2 ; int b@3 ; } ;\n"
1697                       "4: } ;\n",
1698                       tokenize(code4));
1699     }
1700 
varid_in_class12()1701     void varid_in_class12() { // #4637 - method
1702         const char code[] = "class Foo {\n"
1703                             "private:\n"
1704                             "    void f(void);\n"
1705                             "};";
1706         ASSERT_EQUALS("1: class Foo {\n"
1707                       "2: private:\n"
1708                       "3: void f ( void ) ;\n"
1709                       "4: } ;\n",
1710                       tokenize(code));
1711     }
1712 
varid_in_class13()1713     void varid_in_class13() {
1714         const char code1[] = "struct a { char typename; };";
1715         ASSERT_EQUALS("1: struct a { char typename@1 ; } ;\n",
1716                       tokenize(code1, "test.c"));
1717         ASSERT_EQUALS("1: struct a { char typename ; } ;\n",  // not valid C++ code
1718                       tokenize(code1, "test.cpp"));
1719 
1720         const char code2[] = "struct a { char typename[2]; };";
1721         ASSERT_EQUALS("1: struct a { char typename@1 [ 2 ] ; } ;\n",
1722                       tokenize(code2, "test.c"));
1723         ASSERT_EQUALS("1: struct a { char typename [ 2 ] ; } ;\n",  // not valid C++ code
1724                       tokenize(code2, "test.cpp"));
1725     }
1726 
varid_in_class14()1727     void varid_in_class14() {
1728         const char code[] = "class Tokenizer { TokenList list; };\n"
1729                             "\n"
1730                             "void Tokenizer::f() {\n"
1731                             "  std::list<int> x;\n"               // <- not member variable
1732                             "  list.do_something();\n"            // <- member variable
1733                             "  Tokenizer::list.do_something();\n" // <- redundant scope info
1734                             "}\n";
1735         ASSERT_EQUALS("1: class Tokenizer { TokenList list@1 ; } ;\n"
1736                       "2:\n"
1737                       "3: void Tokenizer :: f ( ) {\n"
1738                       "4: std :: list < int > x@2 ;\n"
1739                       "5: list@1 . do_something ( ) ;\n"
1740                       "6: Tokenizer :: list@1 . do_something ( ) ;\n"
1741                       "7: }\n", tokenize(code, "test.cpp"));
1742     }
1743 
varid_in_class15()1744     void varid_in_class15() { // #5533 - functions
1745         const char code[] = "class Fred {\n"
1746                             "  void x(int a) const;\n"
1747                             "  void y() { a=0; }\n" // <- unknown variable
1748                             "}\n";
1749         ASSERT_EQUALS("1: class Fred {\n"
1750                       "2: void x ( int a@1 ) const ;\n"
1751                       "3: void y ( ) { a = 0 ; }\n"
1752                       "4: }\n", tokenize(code, "test.cpp"));
1753     }
1754 
varid_in_class16()1755     void varid_in_class16() { // Set varId for inline member functions
1756         {
1757             const char code[] = "class Fred {\n"
1758                                 "    int x;\n"
1759                                 "    void foo(int x) { this->x = x; }\n"
1760                                 "};\n";
1761             ASSERT_EQUALS("1: class Fred {\n"
1762                           "2: int x@1 ;\n"
1763                           "3: void foo ( int x@2 ) { this . x@1 = x@2 ; }\n"
1764                           "4: } ;\n", tokenize(code, "test.cpp"));
1765         }
1766         {
1767             const char code[] = "class Fred {\n"
1768                                 "    void foo(int x) { this->x = x; }\n"
1769                                 "    int x;\n"
1770                                 "};\n";
1771             ASSERT_EQUALS("1: class Fred {\n"
1772                           "2: void foo ( int x@1 ) { this . x@2 = x@1 ; }\n"
1773                           "3: int x@2 ;\n"
1774                           "4: } ;\n", tokenize(code, "test.cpp"));
1775         }
1776         {
1777             const char code[] = "class Fred {\n"
1778                                 "    void foo(int x) { (*this).x = x; }\n"
1779                                 "    int x;\n"
1780                                 "};\n";
1781             ASSERT_EQUALS("1: class Fred {\n"
1782                           "2: void foo ( int x@1 ) { ( * this ) . x@2 = x@1 ; }\n"
1783                           "3: int x@2 ;\n"
1784                           "4: } ;\n", tokenize(code, "test.cpp"));
1785         }
1786     }
1787 
varid_in_class17()1788     void varid_in_class17() { // #6056 - Set no varid for member functions
1789         const char code1[] = "class Fred {\n"
1790                              "    int method_with_internal(X&);\n"
1791                              "    int method_with_internal(X*);\n"
1792                              "    int method_with_internal(int&);\n"
1793                              "    int method_with_internal(A* b, X&);\n"
1794                              "    int method_with_internal(X&, A* b);\n"
1795                              "    int method_with_internal(const B &, int);\n"
1796                              "    void Set(BAR);\n"
1797                              "    FOO Set(BAR);\n"
1798                              "    int method_with_class(B<B> b);\n"
1799                              "    bool function(std::map<int, int, MYless> & m);\n"
1800                              "};";
1801         ASSERT_EQUALS("1: class Fred {\n"
1802                       "2: int method_with_internal ( X & ) ;\n"
1803                       "3: int method_with_internal ( X * ) ;\n"
1804                       "4: int method_with_internal ( int & ) ;\n"
1805                       "5: int method_with_internal ( A * b@1 , X & ) ;\n"
1806                       "6: int method_with_internal ( X & , A * b@2 ) ;\n"
1807                       "7: int method_with_internal ( const B & , int ) ;\n"
1808                       "8: void Set ( BAR ) ;\n"
1809                       "9: FOO Set ( BAR ) ;\n"
1810                       "10: int method_with_class ( B < B > b@3 ) ;\n"
1811                       "11: bool function ( std :: map < int , int , MYless > & m@4 ) ;\n"
1812                       "12: } ;\n", tokenize(code1, "test.cpp"));
1813 
1814         const char code2[] = "int i;\n"
1815                              "SomeType someVar1(i, i);\n"
1816                              "SomeType someVar2(j, j);\n"
1817                              "SomeType someVar3(j, 1);\n"
1818                              "SomeType someVar4(new bar);";
1819         ASSERT_EQUALS("1: int i@1 ;\n"
1820                       "2: SomeType someVar1@2 ( i@1 , i@1 ) ;\n"
1821                       "3: SomeType someVar2 ( j , j ) ;\n" // This one could be a function
1822                       "4: SomeType someVar3@3 ( j , 1 ) ;\n"
1823                       "5: SomeType someVar4@4 ( new bar ) ;\n", tokenize(code2, "test.cpp"));
1824     }
1825 
varid_in_class18()1826     void varid_in_class18() {
1827         const char code[] = "class A {\n"
1828                             "    class B;\n"
1829                             "};\n"
1830                             "class A::B {\n"
1831                             "    B();\n"
1832                             "    int* i;\n"
1833                             "};\n"
1834                             "A::B::B() :\n"
1835                             "    i(0)\n"
1836                             "{}";
1837         ASSERT_EQUALS("1: class A {\n"
1838                       "2: class B ;\n"
1839                       "3: } ;\n"
1840                       "4: class A :: B {\n"
1841                       "5: B ( ) ;\n"
1842                       "6: int * i@1 ;\n"
1843                       "7: } ;\n"
1844                       "8: A :: B :: B ( ) :\n"
1845                       "9: i@1 ( 0 )\n"
1846                       "10: { }\n", tokenize(code, "test.cpp"));
1847     }
1848 
varid_in_class19()1849     void varid_in_class19() {
1850         const char code[] = "class Fred {\n"
1851                             "    char *str1;\n"
1852                             "    ~Fred();\n"
1853                             "};\n"
1854                             "Fred::~Fred() {\n"
1855                             "    free(str1);\n"
1856                             "}";
1857         ASSERT_EQUALS("1: class Fred {\n"
1858                       "2: char * str1@1 ;\n"
1859                       "3: ~ Fred ( ) ;\n"
1860                       "4: } ;\n"
1861                       "5: Fred :: ~ Fred ( ) {\n"
1862                       "6: free ( str1@1 ) ;\n"
1863                       "7: }\n", tokenize(code, "test.cpp"));
1864     }
1865 
varid_in_class20()1866     void varid_in_class20() {
1867         const char code[] = "template<class C> class cacheEntry {\n"
1868                             "protected:\n"
1869                             "    int m_key;\n"
1870                             "public:\n"
1871                             "    cacheEntry();\n"
1872                             "};\n"
1873                             "\n"
1874                             "template<class C> cacheEntry<C>::cacheEntry() : m_key() {}";
1875 
1876         ASSERT_EQUALS("1: template < class C > class cacheEntry {\n"
1877                       "2: protected:\n"
1878                       "3: int m_key@1 ;\n"
1879                       "4: public:\n"
1880                       "5: cacheEntry ( ) ;\n"
1881                       "6: } ;\n"
1882                       "7:\n"
1883                       "8: template < class C > cacheEntry < C > :: cacheEntry ( ) : m_key@1 ( ) { }\n", tokenize(code, "test.cpp"));
1884     }
1885 
varid_in_class21()1886     void varid_in_class21() {
1887         const char code[] = "template <typename t1,typename t2>\n"
1888                             "class A::B {\n"
1889                             "    B();\n"
1890                             "    int x;\n"
1891                             "};\n"
1892                             "\n"
1893                             "template <typename t1,typename t2>\n"
1894                             "A::B<t1,t2>::B() : x(9) {}";
1895 
1896         const char expected[] = "1: template < typename t1 , typename t2 >\n"
1897                                 "2: class A :: B {\n"
1898                                 "3: B ( ) ;\n"
1899                                 "4: int x@1 ;\n"
1900                                 "5: } ;\n"
1901                                 "6:\n"
1902                                 "7: template < typename t1 , typename t2 >\n"
1903                                 "8: A :: B < t1 , t2 > :: B ( ) : x@1 ( 9 ) { }\n";
1904 
1905         ASSERT_EQUALS(expected, tokenize(code, "test.cpp"));
1906     }
1907 
varid_namespace_1()1908     void varid_namespace_1() { // #7272
1909         const char code[] = "namespace Blah {\n"
1910                             "  struct foo { int x;};\n"
1911                             "  struct bar {\n"
1912                             "    int x;\n"
1913                             "    union { char y; };\n"
1914                             "  };\n"
1915                             "}";
1916         ASSERT_EQUALS("1: namespace Blah {\n"
1917                       "2: struct foo { int x@1 ; } ;\n"
1918                       "3: struct bar {\n"
1919                       "4: int x@2 ;\n"
1920                       "5: union { char y@3 ; } ;\n"
1921                       "6: } ;\n"
1922                       "7: }\n", tokenize(code, "test.cpp"));
1923     }
1924 
varid_namespace_2()1925     void varid_namespace_2() { // #7000
1926         const char code[] = "namespace Ui {\n"
1927                             "    class C { int X; };\n"  // X@1
1928                             "}\n"
1929                             "\n"
1930                             "class C {\n"
1931                             "   void dostuff();\n"
1932                             "   int X;\n"  // X@2
1933                             "};\n"
1934                             "\n"
1935                             "void C::dostuff() {\n"
1936                             "   X = 0;\n"  // X@2
1937                             "}";
1938 
1939         const std::string actual = tokenize(code, "test.cpp");
1940 
1941         ASSERT(actual.find("X@2 = 0") != std::string::npos);
1942     }
1943 
getLine(const std::string & code,int lineNumber)1944     std::string getLine(const std::string &code, int lineNumber) {
1945         std::string nr = MathLib::toString(lineNumber);
1946         const std::string::size_type pos1 = code.find('\n' + nr + ": ");
1947         if (pos1 == std::string::npos)
1948             return "";
1949         const std::string::size_type pos2 = code.find('\n', pos1+1);
1950         if (pos2 == std::string::npos)
1951             return "";
1952         return code.substr(pos1+1, pos2-pos1-1);
1953     }
1954 
varid_namespace_3()1955     void varid_namespace_3() { // #8627
1956         const char code[] = "namespace foo {\n"
1957                             "struct Bar {\n"
1958                             "  explicit Bar(int type);\n"
1959                             "  void f();\n"
1960                             "  int type;\n"  // <- Same varid here ...
1961                             "};\n"
1962                             "\n"
1963                             "Bar::Bar(int type) : type(type) {}\n"
1964                             "\n"
1965                             "void Bar::f() {\n"
1966                             "  type = 0;\n"  // <- ... and here
1967                             "}\n"
1968                             "}";
1969 
1970         const std::string actual = tokenize(code, "test.cpp");
1971 
1972         ASSERT_EQUALS("5: int type@2 ;", getLine(actual,5));
1973         ASSERT_EQUALS("11: type@2 = 0 ;", getLine(actual,11));
1974     }
1975 
varid_namespace_4()1976     void varid_namespace_4() {
1977         const char code[] = "namespace X {\n"
1978                             "  struct foo { int x;};\n"
1979                             "  struct bar: public foo {\n"
1980                             "    void dostuff();\n"
1981                             "  };\n"
1982                             "  void bar::dostuff() { int x2 = x * 2; }\n"
1983                             "}";
1984         ASSERT_EQUALS("1: namespace X {\n"
1985                       "2: struct foo { int x@1 ; } ;\n"
1986                       "3: struct bar : public foo {\n"
1987                       "4: void dostuff ( ) ;\n"
1988                       "5: } ;\n"
1989                       "6: void bar :: dostuff ( ) { int x2@2 ; x2@2 = x@1 * 2 ; }\n"
1990                       "7: }\n", tokenize(code, "test.cpp"));
1991     }
1992 
varid_namespace_5()1993     void varid_namespace_5() {
1994         const char code[] = "namespace X {\n"
1995                             "  struct foo { int x;};\n"
1996                             "  namespace Y {\n"
1997                             "    struct bar: public foo {\n"
1998                             "      void dostuff();\n"
1999                             "    };\n"
2000                             "    void bar::dostuff() { int x2 = x * 2; }\n"
2001                             "  }\n"
2002                             "}";
2003         ASSERT_EQUALS("1: namespace X {\n"
2004                       "2: struct foo { int x@1 ; } ;\n"
2005                       "3: namespace Y {\n"
2006                       "4: struct bar : public foo {\n"
2007                       "5: void dostuff ( ) ;\n"
2008                       "6: } ;\n"
2009                       "7: void bar :: dostuff ( ) { int x2@2 ; x2@2 = x@1 * 2 ; }\n"
2010                       "8: }\n"
2011                       "9: }\n", tokenize(code, "test.cpp"));
2012     }
2013 
varid_initList()2014     void varid_initList() {
2015         const char code1[] = "class A {\n"
2016                              "  A() : x(0) {}\n"
2017                              "  int x;\n"
2018                              "};";
2019         ASSERT_EQUALS("1: class A {\n"
2020                       "2: A ( ) : x@1 ( 0 ) { }\n"
2021                       "3: int x@1 ;\n"
2022                       "4: } ;\n",
2023                       tokenize(code1));
2024 
2025         const char code2[] = "class A {\n"
2026                              "  A(int x) : x(x) {}\n"
2027                              "  int x;\n"
2028                              "};";
2029         ASSERT_EQUALS("1: class A {\n"
2030                       "2: A ( int x@1 ) : x@2 ( x@1 ) { }\n"
2031                       "3: int x@2 ;\n"
2032                       "4: } ;\n",
2033                       tokenize(code2));
2034 
2035         const char code3[] = "class A {\n"
2036                              "  A(int x);\n"
2037                              "  int x;\n"
2038                              "};\n"
2039                              "A::A(int x) : x(x) {}";
2040         ASSERT_EQUALS("1: class A {\n"
2041                       "2: A ( int x@1 ) ;\n"
2042                       "3: int x@2 ;\n"
2043                       "4: } ;\n"
2044                       "5: A :: A ( int x@3 ) : x@2 ( x@3 ) { }\n",
2045                       tokenize(code3));
2046 
2047         const char code4[] = "struct A {\n"
2048                              "  int x;\n"
2049                              "  A(int x) : x(x) {}\n"
2050                              "};\n";
2051         ASSERT_EQUALS("1: struct A {\n"
2052                       "2: int x@1 ;\n"
2053                       "3: A ( int x@2 ) : x@1 ( x@2 ) { }\n"
2054                       "4: } ;\n",
2055                       tokenize(code4));
2056 
2057         const char code5[] = "class A {\n"
2058                              "  A(int x) noexcept : x(x) {}\n"
2059                              "  int x;\n"
2060                              "};";
2061         ASSERT_EQUALS("1: class A {\n"
2062                       "2: A ( int x@1 ) noexcept ( true ) : x@2 ( x@1 ) { }\n"
2063                       "3: int x@2 ;\n"
2064                       "4: } ;\n",
2065                       tokenize(code5));
2066 
2067         const char code6[] = "class A {\n"
2068                              "  A(int x) noexcept(true) : x(x) {}\n"
2069                              "  int x;\n"
2070                              "};";
2071         ASSERT_EQUALS("1: class A {\n"
2072                       "2: A ( int x@1 ) noexcept ( true ) : x@2 ( x@1 ) { }\n"
2073                       "3: int x@2 ;\n"
2074                       "4: } ;\n",
2075                       tokenize(code6));
2076 
2077         const char code7[] = "class A {\n"
2078                              "  A(int x) noexcept(false) : x(x) {}\n"
2079                              "  int x;\n"
2080                              "};";
2081         ASSERT_EQUALS("1: class A {\n"
2082                       "2: A ( int x@1 ) noexcept ( false ) : x@2 ( x@1 ) { }\n"
2083                       "3: int x@2 ;\n"
2084                       "4: } ;\n",
2085                       tokenize(code7));
2086 
2087         const char code8[] = "class Foo : public Bar {\n"
2088                              "  explicit Foo(int i) : Bar(mi = i) { }\n"
2089                              "  int mi;\n"
2090                              "};";
2091         ASSERT_EQUALS("1: class Foo : public Bar {\n"
2092                       "2: explicit Foo ( int i@1 ) : Bar ( mi@2 = i@1 ) { }\n"
2093                       "3: int mi@2 ;\n"
2094                       "4: } ;\n",
2095                       tokenize(code8));
2096 
2097         // #6520
2098         const char code9[] = "class A {\n"
2099                              "  A(int x) : y(a?0:1), x(x) {}\n"
2100                              "  int x, y;\n"
2101                              "};";
2102         ASSERT_EQUALS("1: class A {\n"
2103                       "2: A ( int x@1 ) : y@3 ( a ? 0 : 1 ) , x@2 ( x@1 ) { }\n"
2104                       "3: int x@2 ; int y@3 ;\n"
2105                       "4: } ;\n",
2106                       tokenize(code9));
2107 
2108         // #7123
2109         const char code10[] = "class A {\n"
2110                               "  double *work;\n"
2111                               "  A(const Matrix &m) throw (e);\n"
2112                               "};\n"
2113                               "A::A(const Matrix &m) throw (e) : work(0)\n"
2114                               "{}";
2115         ASSERT_EQUALS("1: class A {\n"
2116                       "2: double * work@1 ;\n"
2117                       "3: A ( const Matrix & m@2 ) throw ( e ) ;\n"
2118                       "4: } ;\n"
2119                       "5: A :: A ( const Matrix & m@3 ) throw ( e ) : work@1 ( 0 )\n"
2120                       "6: { }\n",
2121                       tokenize(code10));
2122     }
2123 
varid_initListWithBaseTemplate()2124     void varid_initListWithBaseTemplate() {
2125         const char code1[] = "class A : B<C,D> {\n"
2126                              "  A() : B<C,D>(), x(0) {}\n"
2127                              "  int x;\n"
2128                              "};";
2129         ASSERT_EQUALS("1: class A : B < C , D > {\n"
2130                       "2: A ( ) : B < C , D > ( ) , x@1 ( 0 ) { }\n"
2131                       "3: int x@1 ;\n"
2132                       "4: } ;\n",
2133                       tokenize(code1));
2134 
2135         const char code2[] = "class A : B<C,D> {\n"
2136                              "  A(int x) : x(x) {}\n"
2137                              "  int x;\n"
2138                              "};";
2139         ASSERT_EQUALS("1: class A : B < C , D > {\n"
2140                       "2: A ( int x@1 ) : x@2 ( x@1 ) { }\n"
2141                       "3: int x@2 ;\n"
2142                       "4: } ;\n",
2143                       tokenize(code2));
2144 
2145         const char code3[] = "class A : B<C,D> {\n"
2146                              "  A(int x);\n"
2147                              "  int x;\n"
2148                              "};\n"
2149                              "A::A(int x) : x(x) {}";
2150         ASSERT_EQUALS("1: class A : B < C , D > {\n"
2151                       "2: A ( int x@1 ) ;\n"
2152                       "3: int x@2 ;\n"
2153                       "4: } ;\n"
2154                       "5: A :: A ( int x@3 ) : x@2 ( x@3 ) { }\n",
2155                       tokenize(code3));
2156 
2157         const char code4[] = "struct A : B<C,D> {\n"
2158                              "  int x;\n"
2159                              "  A(int x) : x(x) {}\n"
2160                              "};\n";
2161         ASSERT_EQUALS("1: struct A : B < C , D > {\n"
2162                       "2: int x@1 ;\n"
2163                       "3: A ( int x@2 ) : x@1 ( x@2 ) { }\n"
2164                       "4: } ;\n",
2165                       tokenize(code4));
2166 
2167         const char code5[] = "class BCLass : public Ticket<void> {\n"
2168                              "  BCLass();\n"
2169                              "  PClass* member;\n"
2170                              "};\n"
2171                              "BCLass::BCLass() : Ticket<void>() {\n"
2172                              "  member = 0;\n"
2173                              "}";
2174         ASSERT_EQUALS("1: class BCLass : public Ticket < void > {\n"
2175                       "2: BCLass ( ) ;\n"
2176                       "3: PClass * member@1 ;\n"
2177                       "4: } ;\n"
2178                       "5: BCLass :: BCLass ( ) : Ticket < void > ( ) {\n"
2179                       "6: member@1 = 0 ;\n"
2180                       "7: }\n",
2181                       tokenize(code5));
2182     }
2183 
varid_initListWithScope()2184     void varid_initListWithScope() {
2185         const char code1[] = "class A : public B::C {\n"
2186                              "  A() : B::C(), x(0) {}\n"
2187                              "  int x;\n"
2188                              "};";
2189         ASSERT_EQUALS("1: class A : public B :: C {\n"
2190                       "2: A ( ) : B :: C ( ) , x@1 ( 0 ) { }\n"
2191                       "3: int x@1 ;\n"
2192                       "4: } ;\n",
2193                       tokenize(code1));
2194     }
2195 
varid_operator()2196     void varid_operator() {
2197         {
2198             const std::string actual = tokenize(
2199                 "class Foo\n"
2200                 "{\n"
2201                 "public:\n"
2202                 "    void operator=(const Foo &);\n"
2203                 "};");
2204 
2205             const char expected[] = "1: class Foo\n"
2206                                     "2: {\n"
2207                                     "3: public:\n"
2208                                     "4: void operator= ( const Foo & ) ;\n"
2209                                     "5: } ;\n";
2210 
2211             ASSERT_EQUALS(expected, actual);
2212         }
2213         {
2214             const std::string actual = tokenize(
2215                 "struct Foo {\n"
2216                 "    void * operator new [](int);\n"
2217                 "};");
2218             const char expected[] = "1: struct Foo {\n"
2219                                     "2: void * operatornew[] ( int ) ;\n"
2220                                     "3: } ;\n";
2221 
2222             ASSERT_EQUALS(expected, actual);
2223         }
2224     }
2225 
varid_throw()2226     void varid_throw() {  // ticket #1723
2227         const std::string actual = tokenize(
2228             "UserDefinedException* pe = new UserDefinedException();\n"
2229             "throw pe;");
2230 
2231         const char expected[] = "1: UserDefinedException * pe@1 ; pe@1 = new UserDefinedException ( ) ;\n"
2232                                 "2: throw pe@1 ;\n";
2233 
2234         ASSERT_EQUALS(expected, actual);
2235     }
2236 
varid_unknown_macro()2237     void varid_unknown_macro() {
2238         // #2638 - unknown macro
2239         const char code[] = "void f() {\n"
2240                             "    int a[10];\n"
2241                             "    AAA\n"
2242                             "    a[0] = 0;\n"
2243                             "}";
2244         const char expected[] = "1: void f ( ) {\n"
2245                                 "2: int a@1 [ 10 ] ;\n"
2246                                 "3: AAA\n"
2247                                 "4: a@1 [ 0 ] = 0 ;\n"
2248                                 "5: }\n";
2249         ASSERT_EQUALS(expected, tokenize(code, "test.c"));
2250     }
2251 
varid_using()2252     void varid_using() {
2253         // #3648
2254         const char code[] = "using std::size_t;";
2255         const char expected[] = "1: using unsigned long ;\n";
2256         ASSERT_EQUALS(expected, tokenize(code));
2257     }
2258 
varid_catch()2259     void varid_catch() {
2260         const char code[] = "void f() {\n"
2261                             "    try { dostuff(); }\n"
2262                             "    catch (exception &e) { }\n"
2263                             "}";
2264         const char expected[] = "1: void f ( ) {\n"
2265                                 "2: try { dostuff ( ) ; }\n"
2266                                 "3: catch ( exception & e@1 ) { }\n"
2267                                 "4: }\n";
2268         ASSERT_EQUALS(expected, tokenize(code));
2269     }
2270 
varid_functionPrototypeTemplate()2271     void varid_functionPrototypeTemplate() {
2272         ASSERT_EQUALS("1: function < void ( ) > fptr@1 ;\n", tokenize("function<void(void)> fptr;"));
2273     }
2274 
varid_templatePtr()2275     void varid_templatePtr() {
2276         ASSERT_EQUALS("1: std :: map < int , FooTemplate < int > * > dummy_member@1 [ 1 ] ;\n", tokenize("std::map<int, FooTemplate<int>*> dummy_member[1];"));
2277     }
2278 
varid_templateNamespaceFuncPtr()2279     void varid_templateNamespaceFuncPtr() {
2280         ASSERT_EQUALS("1: KeyListT < float , & NIFFile :: getFloat > mKeyList@1 [ 4 ] ;\n", tokenize("KeyListT<float, &NIFFile::getFloat> mKeyList[4];"));
2281     }
2282 
varid_templateArray()2283     void varid_templateArray() {
2284         ASSERT_EQUALS("1: VertexArrayIterator < float [ 2 ] > attrPos@1 ; attrPos@1 = m_AttributePos . GetIterator < float [ 2 ] > ( ) ;\n",
2285                       tokenize("VertexArrayIterator<float[2]> attrPos = m_AttributePos.GetIterator<float[2]>();"));
2286     }
2287 
varid_templateParameter()2288     void varid_templateParameter() { // #7046 set varid for "X":  std::array<int,X> Y;
2289         const char code[] = "const int X = 0;\n"
2290                             "std::array<int,X> Y;\n";
2291 
2292         ASSERT_EQUALS("1: const int X@1 = 0 ;\n"
2293                       "2: std :: array < int , X@1 > Y@2 ;\n",
2294                       tokenize(code));
2295     }
2296 
varid_templateUsing()2297     void varid_templateUsing() { // #5781 #7273
2298         const char code[] = "template<class T> using X = Y<T,4>;\n"
2299                             "X<int> x;";
2300         ASSERT_EQUALS("2: Y < int , 4 > x@1 ;\n",
2301                       tokenize(code));
2302     }
2303 
varid_not_template_in_condition()2304     void varid_not_template_in_condition() {
2305         const char code1[] = "void f() { if (x<a||x>b); }";
2306         ASSERT_EQUALS("1: void f ( ) { if ( x < a || x > b ) { ; } }\n", tokenize(code1));
2307 
2308         const char code2[] = "void f() { if (1+x<a||x>b); }";
2309         ASSERT_EQUALS("1: void f ( ) { if ( 1 + x < a || x > b ) { ; } }\n", tokenize(code2));
2310 
2311         const char code3[] = "void f() { if (x<a||x>b+1); }";
2312         ASSERT_EQUALS("1: void f ( ) { if ( x < a || x > b + 1 ) { ; } }\n", tokenize(code3));
2313 
2314         const char code4[] = "void f() { if ((x==13) && (x<a||x>b)); }";
2315         ASSERT_EQUALS("1: void f ( ) { if ( ( x == 13 ) && ( x < a || x > b ) ) { ; } }\n", tokenize(code4));
2316     }
2317 
varid_cppcast()2318     void varid_cppcast() {
2319         ASSERT_EQUALS("1: const_cast < int * > ( code ) [ 0 ] = 0 ;\n",
2320                       tokenize("const_cast<int *>(code)[0] = 0;"));
2321 
2322         ASSERT_EQUALS("1: dynamic_cast < int * > ( code ) [ 0 ] = 0 ;\n",
2323                       tokenize("dynamic_cast<int *>(code)[0] = 0;"));
2324 
2325         ASSERT_EQUALS("1: reinterpret_cast < int * > ( code ) [ 0 ] = 0 ;\n",
2326                       tokenize("reinterpret_cast<int *>(code)[0] = 0;"));
2327 
2328         ASSERT_EQUALS("1: static_cast < int * > ( code ) [ 0 ] = 0 ;\n",
2329                       tokenize("static_cast<int *>(code)[0] = 0;"));
2330     }
2331 
varid_variadicFunc()2332     void varid_variadicFunc() {
2333         ASSERT_EQUALS("1: int foo ( ... ) ;\n", tokenize("int foo(...);"));
2334     }
2335 
varid_typename()2336     void varid_typename() {
2337         ASSERT_EQUALS("1: template < int d , class A , class B > struct S { } ;\n", tokenize("template<int d, class A, class B> struct S {};"));
2338 
2339         ASSERT_EQUALS("1: template < int d , typename A , typename B > struct S { } ;\n", tokenize("template<int d, typename A, typename B> struct S {};"));
2340 
2341         ASSERT_EQUALS("1: A a@1 ;\n", tokenize("typename A a;"));
2342     }
2343 
varid_rvalueref()2344     void varid_rvalueref() {
2345         ASSERT_EQUALS("1: int && a@1 ;\n", tokenize("int&& a;"));
2346 
2347         ASSERT_EQUALS("1: void foo ( int && a@1 ) { }\n", tokenize("void foo(int&& a) {}"));
2348 
2349         ASSERT_EQUALS("1: class C {\n"
2350                       "2: C ( int && a@1 ) ;\n"
2351                       "3: } ;\n",
2352                       tokenize("class C {\n"
2353                                "    C(int&& a);\n"
2354                                "};"));
2355 
2356         ASSERT_EQUALS("1: void foo ( int && ) ;\n", tokenize("void foo(int&&);"));
2357     }
2358 
varid_arrayFuncPar()2359     void varid_arrayFuncPar() {
2360         ASSERT_EQUALS("1: void check ( const char fname@1 [ ] = 0 ) { }\n", tokenize("void check( const char fname[] = 0) { }"));
2361     }
2362 
varid_sizeofPassed()2363     void varid_sizeofPassed() {
2364         ASSERT_EQUALS("1: void which_test ( ) {\n"
2365                       "2: const char * argv@1 [ 2 ] = { \"./test_runner\" , \"TestClass\" } ;\n"
2366                       "3: options args@2 ( sizeof ( argv@1 ) / sizeof ( argv@1 [ 0 ] ) , argv@1 ) ;\n"
2367                       "4: args@2 . which_test ( ) ;\n"
2368                       "5: }\n",
2369                       tokenize("void which_test() {\n"
2370                                "    const char* argv[] = { \"./test_runner\", \"TestClass\" };\n"
2371                                "    options args(sizeof argv / sizeof argv[0], argv);\n"
2372                                "    args.which_test();\n"
2373                                "}"));
2374     }
2375 
varid_classInFunction()2376     void varid_classInFunction() {
2377         ASSERT_EQUALS("1: void AddSuppression ( ) {\n"
2378                       "2: class QErrorLogger {\n"
2379                       "3: void reportErr ( ErrorLogger :: ErrorMessage & msg@1 ) {\n"
2380                       "4: }\n"
2381                       "5: } ;\n"
2382                       "6: }\n",
2383                       tokenize("void AddSuppression() {\n"
2384                                "    class QErrorLogger {\n"
2385                                "        void reportErr(ErrorLogger::ErrorMessage &msg) {\n"
2386                                "        }\n"
2387                                "    };\n"
2388                                "}"));
2389     }
2390 
varid_pointerToArray()2391     void varid_pointerToArray() {
2392         ASSERT_EQUALS("1: int ( * a1@1 ) [ 10 ] ;\n"
2393                       "2: void f1 ( ) {\n"
2394                       "3: int ( * a2@2 ) [ 10 ] ;\n"
2395                       "4: int ( & a3@3 ) [ 10 ] ;\n"
2396                       "5: }\n"
2397                       "6: struct A {\n"
2398                       "7: int ( & a4@4 ) [ 10 ] ;\n"
2399                       "8: int f2 ( int i@5 ) { return a4@4 [ i@5 ] ; }\n"
2400                       "9: int f3 ( int ( & a5@6 ) [ 10 ] , int i@7 ) { return a5@6 [ i@7 ] ; }\n"
2401                       "10: } ;\n"
2402                       "11: int f4 ( int ( & a6@8 ) [ 10 ] , int i@9 ) { return a6@8 [ i@9 ] ; }\n",
2403                       tokenize("int (*a1)[10];\n" // pointer to array of 10 ints
2404                                "void f1() {\n"
2405                                "    int(*a2)[10];\n"
2406                                "    int(&a3)[10];\n"
2407                                "}\n"
2408                                "struct A {\n"
2409                                "    int(&a4)[10];\n"
2410                                "    int f2(int i) { return a4[i]; }\n"
2411                                "    int f3(int(&a5)[10], int i) { return a5[i]; }\n"
2412                                "};\n"
2413                                "int f4(int(&a6)[10], int i) { return a6[i]; }"));
2414     }
2415 
varid_cpp11initialization()2416     void varid_cpp11initialization() {
2417         ASSERT_EQUALS("1: int i@1 { 1 } ;\n"
2418                       "2: std :: vector < int > vec@2 { 1 , 2 , 3 } ;\n"
2419                       "3: namespace n { int z@3 ; } ;\n"
2420                       "4: int & j@4 { i@1 } ;\n"
2421                       "5: int k@5 { 1 } ; int l@6 { 2 } ;\n",
2422                       tokenize("int i{1};\n"
2423                                "std::vector<int> vec{1, 2, 3};\n"
2424                                "namespace n { int z; };\n"
2425                                "int& j{i};\n"
2426                                "int k{1}, l{2};"));
2427 
2428         // #6030
2429         ASSERT_EQUALS("1: struct S3 : public S1 , public S2 { } ;\n",
2430                       tokenize("struct S3 : public S1, public S2 { };"));
2431 
2432         // #6058
2433         ASSERT_EQUALS("1: class Scope { } ;\n",
2434                       tokenize("class CPPCHECKLIB Scope { };"));
2435 
2436         // #6073 #6253
2437         ASSERT_EQUALS("1: class A : public B , public C :: D , public E < F > :: G < H > {\n"
2438                       "2: int i@1 ;\n"
2439                       "3: A ( int i@2 ) : B { i@2 } , C :: D { i@2 } , E < F > :: G < H > { i@2 } , i@1 { i@2 } {\n"
2440                       "4: int j@3 { i@2 } ;\n"
2441                       "5: }\n"
2442                       "6: } ;\n",
2443                       tokenize("class A: public B, public C::D, public E<F>::G<H> {\n"
2444                                "    int i;\n"
2445                                "    A(int i): B{i}, C::D{i}, E<F>::G<H>{i} ,i{i} {\n"
2446                                "        int j{i};\n"
2447                                "    }\n"
2448                                "};"));
2449     }
2450 
varid_inheritedMembers()2451     void varid_inheritedMembers() {
2452         ASSERT_EQUALS("1: class A {\n"
2453                       "2: int a@1 ;\n"
2454                       "3: } ;\n"
2455                       "4: class B : public A {\n"
2456                       "5: void f ( ) ;\n"
2457                       "6: } ;\n"
2458                       "7: void B :: f ( ) {\n"
2459                       "8: a@1 = 0 ;\n"
2460                       "9: }\n",
2461                       tokenize("class A {\n"
2462                                "    int a;\n"
2463                                "};\n"
2464                                "class B : public A {\n"
2465                                "    void f();\n"
2466                                "};\n"
2467                                "void B::f() {\n"
2468                                "    a = 0;\n"
2469                                "}"));
2470 
2471         ASSERT_EQUALS("1: class A {\n"
2472                       "2: int a@1 ;\n"
2473                       "3: } ;\n"
2474                       "4: class B : A {\n"
2475                       "5: void f ( ) ;\n"
2476                       "6: } ;\n"
2477                       "7: void B :: f ( ) {\n"
2478                       "8: a@1 = 0 ;\n"
2479                       "9: }\n",
2480                       tokenize("class A {\n"
2481                                "    int a;\n"
2482                                "};\n"
2483                                "class B : A {\n"
2484                                "    void f();\n"
2485                                "};\n"
2486                                "void B::f() {\n"
2487                                "    a = 0;\n"
2488                                "}"));
2489 
2490         ASSERT_EQUALS("1: class A {\n"
2491                       "2: int a@1 ;\n"
2492                       "3: } ;\n"
2493                       "4: class B : protected B , public A {\n"
2494                       "5: void f ( ) ;\n"
2495                       "6: } ;\n"
2496                       "7: void B :: f ( ) {\n"
2497                       "8: a@1 = 0 ;\n"
2498                       "9: }\n",
2499                       tokenize("class A {\n"
2500                                "    int a;\n"
2501                                "};\n"
2502                                "class B : protected B, public A {\n"
2503                                "    void f();\n"
2504                                "};\n"
2505                                "void B::f() {\n"
2506                                "    a = 0;\n"
2507                                "}"));
2508 
2509         ASSERT_EQUALS("1: class A {\n"
2510                       "2: int a@1 ;\n"
2511                       "3: } ;\n"
2512                       "4: class B : public A {\n"
2513                       "5: void f ( ) {\n"
2514                       "6: a@1 = 0 ;\n"
2515                       "7: }\n"
2516                       "8: } ;\n",
2517                       tokenize("class A {\n"
2518                                "    int a;\n"
2519                                "};\n"
2520                                "class B : public A {\n"
2521                                "    void f() {\n"
2522                                "        a = 0;\n"
2523                                "    }\n"
2524                                "};"));
2525     }
2526 
varid_header()2527     void varid_header() {
2528         ASSERT_EQUALS("1: class A ;\n"
2529                       "2: struct B {\n"
2530                       "3: void setData ( const A & a@1 ) ;\n"
2531                       "4: } ;\n",
2532                       tokenize("class A;\n"
2533                                "struct B {\n"
2534                                "    void setData(const A & a);\n"
2535                                "}; ", "test.h"));
2536     }
2537 
varid_rangeBasedFor()2538     void varid_rangeBasedFor() {
2539         ASSERT_EQUALS("1: void reset ( Foo array@1 ) {\n"
2540                       "2: for ( auto & e@2 : array@1 ) {\n"
2541                       "3: foo ( e@2 ) ; }\n"
2542                       "4: } ;\n",
2543                       tokenize("void reset(Foo array) {\n"
2544                                "    for (auto& e : array)\n"
2545                                "        foo(e);\n"
2546                                "};"));
2547 
2548         ASSERT_EQUALS("1: void reset ( Foo array@1 ) {\n"
2549                       "2: for ( auto e@2 : array@1 ) {\n"
2550                       "3: foo ( e@2 ) ; }\n"
2551                       "4: } ;\n",
2552                       tokenize("void reset(Foo array) {\n"
2553                                "    for (auto e : array)\n"
2554                                "        foo(e);\n"
2555                                "};"));
2556 
2557         // Labels are no variables
2558         ASSERT_EQUALS("1: void foo ( ) {\n"
2559                       "2: switch ( event . key . keysym . sym ) {\n"
2560                       "3: case SDLK_LEFT : ;\n"
2561                       "4: break ;\n"
2562                       "5: case SDLK_RIGHT : ;\n"
2563                       "6: delta = 1 ;\n"
2564                       "7: break ;\n"
2565                       "8: }\n"
2566                       "9: }\n",
2567                       tokenize("void foo() {\n"
2568                                "    switch (event.key.keysym.sym) {\n"
2569                                "    case SDLK_LEFT:\n"
2570                                "        break;\n"
2571                                "    case SDLK_RIGHT:\n"
2572                                "        delta = 1;\n"
2573                                "        break;\n"
2574                                "    }\n"
2575                                "}", "test.c"));
2576     }
2577 
varid_structinit()2578     void varid_structinit() { // #6406
2579         ASSERT_EQUALS("1: void foo ( ) {\n"
2580                       "2: struct ABC abc@1 ; abc@1 = { . a@2 = 0 , . b@3 = 1 } ;\n"
2581                       "3: }\n",
2582                       tokenize("void foo() {\n"
2583                                "  struct ABC abc = {.a=0,.b=1};\n"
2584                                "}"));
2585 
2586         ASSERT_EQUALS("1: void foo ( ) {\n"
2587                       "2: struct ABC abc@1 ; abc@1 = { . a@2 = abc@1 . a@2 , . b@3 = abc@1 . b@3 } ;\n"
2588                       "3: }\n",
2589                       tokenize("void foo() {\n"
2590                                "  struct ABC abc = {.a=abc.a,.b=abc.b};\n"
2591                                "}"));
2592 
2593         ASSERT_EQUALS("1: void foo ( ) {\n"
2594                       "2: struct ABC abc@1 ; abc@1 = { . a@2 { abc@1 . a@2 } , . b@3 = { abc@1 . b@3 } } ;\n"
2595                       "3: }\n",
2596                       tokenize("void foo() {\n"
2597                                "  struct ABC abc = {.a { abc.a },.b= { abc.b } };\n"
2598                                "}"));
2599     }
2600 
varid_arrayinit()2601     void varid_arrayinit() { // #7579 - no variable declaration in rhs
2602         ASSERT_EQUALS("1: void foo ( int * a@1 ) { int b@2 [ 1 ] = { x * a@1 [ 0 ] } ; }\n", tokenize("void foo(int*a) { int b[] = { x*a[0] }; }"));
2603     }
2604 
varid_lambda_arg()2605     void varid_lambda_arg() {
2606         // #8664
2607         const char code1[] = "static void func(int ec) {\n"
2608                              "    func2([](const std::error_code& ec) { return ec; });\n"
2609                              "}";
2610         const char exp1[] = "1: static void func ( int ec@1 ) {\n"
2611                             "2: func2 ( [ ] ( const std :: error_code & ec@2 ) { return ec@2 ; } ) ;\n"
2612                             "3: }\n";
2613         ASSERT_EQUALS(exp1, tokenize(code1));
2614 
2615         const char code2[] = "static void func(int ec) {\n"
2616                              "    func2([](int x, const std::error_code& ec) { return x + ec; });\n"
2617                              "}";
2618         const char exp2[] = "1: static void func ( int ec@1 ) {\n"
2619                             "2: func2 ( [ ] ( int x@2 , const std :: error_code & ec@3 ) { return x@2 + ec@3 ; } ) ;\n"
2620                             "3: }\n";
2621         ASSERT_EQUALS(exp2, tokenize(code2));
2622     }
2623 
varid_lambda_mutable()2624     void varid_lambda_mutable() {
2625         // #8957
2626         const char code1[] = "static void func() {\n"
2627                              "    auto x = []() mutable {};\n"
2628                              "    dostuff(x);\n"
2629                              "}";
2630         const char exp1[] = "1: static void func ( ) {\n"
2631                             "2: auto x@1 ; x@1 = [ ] ( ) mutable { } ;\n"
2632                             "3: dostuff ( x@1 ) ;\n"
2633                             "4: }\n";
2634         ASSERT_EQUALS(exp1, tokenize(code1));
2635     }
2636 
varid_trailing_return1()2637     void varid_trailing_return1() { // #8889
2638         const char code1[] = "struct Fred {\n"
2639                              "    auto foo(const Fred & other) -> Fred &;\n"
2640                              "    auto bar(const Fred & other) -> Fred & {\n"
2641                              "        return *this;\n"
2642                              "    }\n"
2643                              "};\n"
2644                              "auto Fred::foo(const Fred & other) -> Fred & {\n"
2645                              "    return *this;\n"
2646                              "}";
2647         const char exp1[] = "1: struct Fred {\n"
2648                             "2: auto foo ( const Fred & other@1 ) . Fred & ;\n"
2649                             "3: auto bar ( const Fred & other@2 ) . Fred & {\n"
2650                             "4: return * this ;\n"
2651                             "5: }\n"
2652                             "6: } ;\n"
2653                             "7: auto Fred :: foo ( const Fred & other@3 ) . Fred & {\n"
2654                             "8: return * this ;\n"
2655                             "9: }\n";
2656         ASSERT_EQUALS(exp1, tokenize(code1));
2657     }
2658 
varid_trailing_return2()2659     void varid_trailing_return2() { // #9066
2660         const char code1[] = "auto func(int arg) -> bar::quux {}";
2661         const char exp1[] = "1: auto func ( int arg@1 ) . bar :: quux { }\n";
2662         ASSERT_EQUALS(exp1, tokenize(code1));
2663     }
2664 
varid_parameter_pack()2665     void varid_parameter_pack() { // #9383
2666         const char code1[] = "template <typename... Rest>\n"
2667                              "void func(Rest... parameters) {\n"
2668                              "    foo(parameters...);\n"
2669                              "}\n";
2670         const char exp1[] = "1: template < typename ... Rest >\n"
2671                             "2: void func ( Rest ... parameters@1 ) {\n"
2672                             "3: foo ( parameters@1 ... ) ;\n"
2673                             "4: }\n";
2674         ASSERT_EQUALS(exp1, tokenize(code1));
2675     }
2676 
varid_for_auto_cpp17()2677     void varid_for_auto_cpp17() {
2678         const char code[] = "void f() {\n"
2679                             "  for (auto [x,y,z]: xyz) {\n"
2680                             "    x+y+z;\n"
2681                             "  }\n"
2682                             "  x+y+z;\n"
2683                             "}";
2684         const char exp1[] = "1: void f ( ) {\n"
2685                             "2: for ( auto [ x@1 , y@2 , z@3 ] : xyz ) {\n"
2686                             "3: x@1 + y@2 + z@3 ;\n"
2687                             "4: }\n"
2688                             "5: x + y + z ;\n"
2689                             "6: }\n";
2690         ASSERT_EQUALS(exp1, tokenize(code));
2691     }
2692 
varid_not()2693     void varid_not() { // #9689 'not x'
2694         const char code1[] = "void foo(int x) const {\n"
2695                              "  if (not x) {}\n"
2696                              "}";
2697         const char exp1[] = "1: void foo ( int x@1 ) const {\n"
2698                             "2: if ( ! x@1 ) { }\n"
2699                             "3: }\n";
2700         ASSERT_EQUALS(exp1, tokenize(code1));
2701     }
2702 
varid_declInIfCondition()2703     void varid_declInIfCondition() {
2704         // if
2705         ASSERT_EQUALS("1: void f ( int x@1 ) {\n"
2706                       "2: if ( int x@2 = 0 ) { x@2 ; }\n"
2707                       "3: x@1 ;\n"
2708                       "4: }\n",
2709                       tokenize("void f(int x) {\n"
2710                                "  if (int x = 0) { x; }\n"
2711                                "  x;\n"
2712                                "}"));
2713         // if, else
2714         ASSERT_EQUALS("1: void f ( int x@1 ) {\n"
2715                       "2: if ( int x@2 = 0 ) { x@2 ; }\n"
2716                       "3: else { x@2 ; }\n"
2717                       "4: x@1 ;\n"
2718                       "5: }\n",
2719                       tokenize("void f(int x) {\n"
2720                                "  if (int x = 0) { x; }\n"
2721                                "  else { x; }\n"
2722                                "  x;\n"
2723                                "}"));
2724         // if, else if
2725         ASSERT_EQUALS("1: void f ( int x@1 ) {\n"
2726                       "2: if ( int x@2 = 0 ) { x@2 ; }\n"
2727                       "3: else { if ( void * x@3 = & x@3 ) { x@3 ; } }\n"
2728                       "4: x@1 ;\n"
2729                       "5: }\n",
2730                       tokenize("void f(int x) {\n"
2731                                "  if (int x = 0) x;\n"
2732                                "  else if (void* x = &x) x;\n"
2733                                "  x;\n"
2734                                "}"));
2735         // if, else if, else
2736         ASSERT_EQUALS("1: void f ( int x@1 ) {\n"
2737                       "2: if ( int x@2 = 0 ) { x@2 ; }\n"
2738                       "3: else { if ( void * x@3 = & x@3 ) { x@3 ; }\n"
2739                       "4: else { x@3 ; } }\n"
2740                       "5: x@1 ;\n"
2741                       "6: }\n",
2742                       tokenize("void f(int x) {\n"
2743                                "  if (int x = 0) x;\n"
2744                                "  else if (void* x = &x) x;\n"
2745                                "  else x;\n"
2746                                "  x;\n"
2747                                "}"));
2748     }
2749 
varidclass1()2750     void varidclass1() {
2751         const std::string actual = tokenize(
2752             "class Fred\n"
2753             "{\n"
2754             "private:\n"
2755             "    int i;\n"
2756             "\n"
2757             "    void foo1();\n"
2758             "    void foo2()\n"
2759             "    {\n"
2760             "        ++i;\n"
2761             "    }\n"
2762             "}\n"
2763             "\n"
2764             "Fred::foo1()\n"
2765             "{\n"
2766             "    i = 0;\n"
2767             "}");
2768 
2769         const char expected[] = "1: class Fred\n"
2770                                 "2: {\n"
2771                                 "3: private:\n"
2772                                 "4: int i@1 ;\n"
2773                                 "5:\n"
2774                                 "6: void foo1 ( ) ;\n"
2775                                 "7: void foo2 ( )\n"
2776                                 "8: {\n"
2777                                 "9: ++ i@1 ;\n"
2778                                 "10: }\n"
2779                                 "11: }\n"
2780                                 "12:\n"
2781                                 "13: Fred :: foo1 ( )\n"
2782                                 "14: {\n"
2783                                 "15: i@1 = 0 ;\n"
2784                                 "16: }\n";
2785 
2786         ASSERT_EQUALS(expected, actual);
2787     }
2788 
2789 
varidclass2()2790     void varidclass2() {
2791         const std::string actual = tokenize(
2792             "class Fred\n"
2793             "{ void f(); };\n"
2794             "\n"
2795             "void A::foo1()\n"
2796             "{\n"
2797             "    int i = 0;\n"
2798             "}\n"
2799             "\n"
2800             "void Fred::f()\n"
2801             "{\n"
2802             "    i = 0;\n"
2803             "}");
2804 
2805         const char expected[] = "1: class Fred\n"
2806                                 "2: { void f ( ) ; } ;\n"
2807                                 "3:\n"
2808                                 "4: void A :: foo1 ( )\n"
2809                                 "5: {\n"
2810                                 "6: int i@1 ; i@1 = 0 ;\n"
2811                                 "7: }\n"
2812                                 "8:\n"
2813                                 "9: void Fred :: f ( )\n"
2814                                 "10: {\n"
2815                                 "11: i = 0 ;\n"
2816                                 "12: }\n";
2817 
2818         ASSERT_EQUALS(expected, actual);
2819     }
2820 
2821 
varidclass3()2822     void varidclass3() {
2823         const std::string actual = tokenize(
2824             "class Fred\n"
2825             "{ int i; void f(); };\n"
2826             "\n"
2827             "void Fred::f()\n"
2828             "{\n"
2829             "    i = 0;\n"
2830             "}\n"
2831             "\n"
2832             "void A::f()\n"
2833             "{\n"
2834             "    i = 0;\n"
2835             "}");
2836 
2837         const char expected[] = "1: class Fred\n"
2838                                 "2: { int i@1 ; void f ( ) ; } ;\n"
2839                                 "3:\n"
2840                                 "4: void Fred :: f ( )\n"
2841                                 "5: {\n"
2842                                 "6: i@1 = 0 ;\n"
2843                                 "7: }\n"
2844                                 "8:\n"
2845                                 "9: void A :: f ( )\n"
2846                                 "10: {\n"
2847                                 "11: i = 0 ;\n"
2848                                 "12: }\n";
2849 
2850         ASSERT_EQUALS(expected, actual);
2851     }
2852 
2853 
varidclass4()2854     void varidclass4() {
2855         const std::string actual = tokenize(
2856             "class Fred\n"
2857             "{ int i; void f(); };\n"
2858             "\n"
2859             "void Fred::f()\n"
2860             "{\n"
2861             "    if (i) { }\n"
2862             "    i = 0;\n"
2863             "}");
2864 
2865         const char expected[] = "1: class Fred\n"
2866                                 "2: { int i@1 ; void f ( ) ; } ;\n"
2867                                 "3:\n"
2868                                 "4: void Fred :: f ( )\n"
2869                                 "5: {\n"
2870                                 "6: if ( i@1 ) { }\n"
2871                                 "7: i@1 = 0 ;\n"
2872                                 "8: }\n";
2873 
2874         ASSERT_EQUALS(expected, actual);
2875     }
2876 
varidclass5()2877     void varidclass5() {
2878         const std::string actual = tokenize(
2879             "class A { };\n"
2880             "class B\n"
2881             "{\n"
2882             "    A *a;\n"
2883             "    B() : a(new A)\n"
2884             "    { }\n"
2885             "};");
2886 
2887         const char expected[] = "1: class A { } ;\n"
2888                                 "2: class B\n"
2889                                 "3: {\n"
2890                                 "4: A * a@1 ;\n"
2891                                 "5: B ( ) : a@1 ( new A )\n"
2892                                 "6: { }\n"
2893                                 "7: } ;\n";
2894 
2895         ASSERT_EQUALS(expected, actual);
2896     }
2897 
varidclass6()2898     void varidclass6() {
2899         const std::string actual = tokenize(
2900             "class A\n"
2901             "{\n"
2902             "  public:\n"
2903             "  static char buf[20];\n"
2904             "};\n"
2905             "char A::buf[20];\n"
2906             "int main()\n"
2907             "{\n"
2908             "  char buf[2];\n"
2909             "  A::buf[10] = 0;\n"
2910             "}");
2911 
2912         const char expected[] = "1: class A\n"
2913                                 "2: {\n"
2914                                 "3: public:\n"
2915                                 "4: static char buf@1 [ 20 ] ;\n"
2916                                 "5: } ;\n"
2917                                 "6: char A :: buf@1 [ 20 ] ;\n"
2918                                 "7: int main ( )\n"
2919                                 "8: {\n"
2920                                 "9: char buf@2 [ 2 ] ;\n"
2921                                 "10: A :: buf@1 [ 10 ] = 0 ;\n"
2922                                 "11: }\n";
2923 
2924         ASSERT_EQUALS(expected, actual);
2925     }
2926 
varidclass7()2927     void varidclass7() {
2928         const std::string actual = tokenize(
2929             "int main()\n"
2930             "{\n"
2931             "  char buf[2];\n"
2932             "  A::buf[10] = 0;\n"
2933             "}");
2934 
2935         const char expected[] = "1: int main ( )\n"
2936                                 "2: {\n"
2937                                 "3: char buf@1 [ 2 ] ;\n"
2938                                 "4: A :: buf [ 10 ] = 0 ;\n"
2939                                 "5: }\n";
2940 
2941         ASSERT_EQUALS(expected, actual);
2942     }
2943 
varidclass8()2944     void varidclass8() {
2945         const char code[] ="class Fred {\n"
2946                             "public:\n"
2947                             "    void foo(int d) {\n"
2948                             "        int i = bar(x * d);\n"
2949                             "    }\n"
2950                             "    int x;\n"
2951                             "}\n";
2952 
2953         const char expected[] = "1: class Fred {\n"
2954                                 "2: public:\n"
2955                                 "3: void foo ( int d@1 ) {\n"
2956                                 "4: int i@2 ; i@2 = bar ( x@3 * d@1 ) ;\n"
2957                                 "5: }\n"
2958                                 "6: int x@3 ;\n"
2959                                 "7: }\n";
2960 
2961         ASSERT_EQUALS(expected, tokenize(code));
2962     }
2963 
varidclass9()2964     void varidclass9() {
2965         const char code[] ="typedef char Str[10];"
2966                             "class A {\n"
2967                             "public:\n"
2968                             "    void f(Str &cl);\n"
2969                             "    void g(Str cl);\n"
2970                             "}\n"
2971                             "void Fred::f(Str &cl) {\n"
2972                             "    sizeof(cl);\n"
2973                             "}";
2974 
2975         const char expected[] = "1: class A {\n"
2976                                 "2: public:\n"
2977                                 "3: void f ( char ( & cl@1 ) [ 10 ] ) ;\n"
2978                                 "4: void g ( char cl@2 [ 10 ] ) ;\n"
2979                                 "5: }\n"
2980                                 "6: void Fred :: f ( char ( & cl@3 ) [ 10 ] ) {\n"
2981                                 "7: sizeof ( cl@3 ) ;\n"
2982                                 "8: }\n";
2983 
2984         ASSERT_EQUALS(expected, tokenize(code));
2985     }
2986 
varidclass10()2987     void varidclass10() {
2988         const char code[] ="class A {\n"
2989                             "    void f() {\n"
2990                             "        a = 3;\n"
2991                             "    }\n"
2992                             "    int a;\n"
2993                             "};\n";
2994 
2995         const char expected[] = "1: class A {\n"
2996                                 "2: void f ( ) {\n"
2997                                 "3: a@1 = 3 ;\n"
2998                                 "4: }\n"
2999                                 "5: int a@1 ;\n"
3000                                 "6: } ;\n";
3001         ASSERT_EQUALS(expected, tokenize(code));
3002     }
3003 
varidclass11()3004     void varidclass11() {
3005         const char code[] ="class Fred {\n"
3006                             "    int a;\n"
3007                             "    void f();\n"
3008                             "};\n"
3009                             "class Wilma {\n"
3010                             "    int a;\n"
3011                             "    void f();\n"
3012                             "};\n"
3013                             "void Fred::f() { a = 0; }\n"
3014                             "void Wilma::f() { a = 0; }\n";
3015 
3016         const char expected[] = "1: class Fred {\n"
3017                                 "2: int a@1 ;\n"
3018                                 "3: void f ( ) ;\n"
3019                                 "4: } ;\n"
3020                                 "5: class Wilma {\n"
3021                                 "6: int a@2 ;\n"
3022                                 "7: void f ( ) ;\n"
3023                                 "8: } ;\n"
3024                                 "9: void Fred :: f ( ) { a@1 = 0 ; }\n"
3025                                 "10: void Wilma :: f ( ) { a@2 = 0 ; }\n";
3026 
3027         ASSERT_EQUALS(expected, tokenize(code));
3028     }
3029 
varidclass12()3030     void varidclass12() {
3031         const char code[] ="class Fred {\n"
3032                             "    int a;\n"
3033                             "    void f() { Fred::a = 0; }\n"
3034                             "};\n";
3035 
3036         const char expected[] = "1: class Fred {\n"
3037                                 "2: int a@1 ;\n"
3038                                 "3: void f ( ) { Fred :: a@1 = 0 ; }\n"
3039                                 "4: } ;\n";
3040 
3041         ASSERT_EQUALS(expected, tokenize(code));
3042     }
3043 
varidclass13()3044     void varidclass13() {
3045         const char code[] ="class Fred {\n"
3046                             "    int a;\n"
3047                             "    void f() { Foo::Fred::a = 0; }\n"
3048                             "};\n";
3049 
3050         const char expected[] = "1: class Fred {\n"
3051                                 "2: int a@1 ;\n"
3052                                 "3: void f ( ) { Foo :: Fred :: a = 0 ; }\n"
3053                                 "4: } ;\n";
3054 
3055         ASSERT_EQUALS(expected, tokenize(code));
3056     }
3057 
varidclass14()3058     void varidclass14() {
3059         // don't give friend classes varid
3060         {
3061             const char code[] ="class A {\n"
3062                                 "friend class B;\n"
3063                                 "}";
3064 
3065             const char expected[] = "1: class A {\n"
3066                                     "2: friend class B ;\n"
3067                                     "3: }\n";
3068 
3069             ASSERT_EQUALS(expected, tokenize(code));
3070         }
3071 
3072         {
3073             const char code[] ="class A {\n"
3074                                 "private: friend class B;\n"
3075                                 "}";
3076 
3077             const char expected[] = "1: class A {\n"
3078                                     "2: private: friend class B ;\n"
3079                                     "3: }\n";
3080 
3081             ASSERT_EQUALS(expected, tokenize(code));
3082         }
3083     }
3084 
varidclass15()3085     void varidclass15() {
3086         const char code[] = "class A {\n"
3087                             "    int a;\n"
3088                             "    int b;\n"
3089                             "    A();\n"
3090                             "};\n"
3091                             "A::A() : a(0) { b = 1; }";
3092         const char expected[] = "1: class A {\n"
3093                                 "2: int a@1 ;\n"
3094                                 "3: int b@2 ;\n"
3095                                 "4: A ( ) ;\n"
3096                                 "5: } ;\n"
3097                                 "6: A :: A ( ) : a@1 ( 0 ) { b@2 = 1 ; }\n";
3098         ASSERT_EQUALS(expected, tokenize(code));
3099     }
3100 
varidclass16()3101     void varidclass16() {
3102         const char code[] = "struct A;\n"
3103                             "typedef bool (A::* FuncPtr)();\n"
3104                             "struct A {\n"
3105                             "    FuncPtr pFun;\n"
3106                             "    void setPFun(int mode);\n"
3107                             "    bool funcNorm();\n"
3108                             "};\n"
3109                             "void A::setPFun(int mode) {\n"
3110                             "    pFun = &A::funcNorm;\n"
3111                             "}";
3112         const char expected[] = "1: struct A ;\n"
3113                                 "2:\n"
3114                                 "3: struct A {\n"
3115                                 "4: bool ( * pFun@1 ) ( ) ;\n"
3116                                 "5: void setPFun ( int mode@2 ) ;\n"
3117                                 "6: bool funcNorm ( ) ;\n"
3118                                 "7: } ;\n"
3119                                 "8: void A :: setPFun ( int mode@3 ) {\n"
3120                                 "9: pFun@1 = & A :: funcNorm ;\n"
3121                                 "10: }\n";
3122         ASSERT_EQUALS(expected, tokenize(code));
3123     }
3124 
varidclass17()3125     void varidclass17() {
3126         const char code[] = "class A: public B, public C::D {\n"
3127                             "    int i;\n"
3128                             "    A(int i): B(i), C::D(i), i(i) {\n"
3129                             "        int j(i);\n"
3130                             "    }\n"
3131                             "};";
3132         const char expected[] = "1: class A : public B , public C :: D {\n"
3133                                 "2: int i@1 ;\n"
3134                                 "3: A ( int i@2 ) : B ( i@2 ) , C :: D ( i@2 ) , i@1 ( i@2 ) {\n"
3135                                 "4: int j@3 ; j@3 = i@2 ;\n"
3136                                 "5: }\n"
3137                                 "6: } ;\n";
3138         ASSERT_EQUALS(expected, tokenize(code));
3139     }
3140 
varidclass18()3141     void varidclass18() {
3142         const char code[] = "class A {\n"
3143                             "    int a;\n"
3144                             "    int b;\n"
3145                             "    A();\n"
3146                             "};\n"
3147                             "A::A() : a{0} { b = 1; }";
3148         const char expected[] = "1: class A {\n"
3149                                 "2: int a@1 ;\n"
3150                                 "3: int b@2 ;\n"
3151                                 "4: A ( ) ;\n"
3152                                 "5: } ;\n"
3153                                 "6: A :: A ( ) : a@1 { 0 } { b@2 = 1 ; }\n";
3154         ASSERT_EQUALS(expected, tokenize(code));
3155     }
3156 
varidclass19()3157     void varidclass19() {
3158         const char code[] = "class A : public ::B {\n"
3159                             "  int a;\n"
3160                             "  A();\n"
3161                             "};\n"
3162                             "A::A() : ::B(), a(0) {}";
3163         const char expected[] = "1: class A : public :: B {\n"
3164                                 "2: int a@1 ;\n"
3165                                 "3: A ( ) ;\n"
3166                                 "4: } ;\n"
3167                                 "5: A :: A ( ) : :: B ( ) , a@1 ( 0 ) { }\n";
3168         ASSERT_EQUALS(expected, tokenize(code));
3169     }
3170 
varidclass20()3171     void varidclass20() { // #7578: int (*p)[2]
3172         const char code[] = "struct S {\n"
3173                             "  int (*p)[2];\n"
3174                             "  S();\n"
3175                             "};\n"
3176                             "S::S() { p[0] = 0; }";
3177         const char expected[] = "1: struct S {\n"
3178                                 "2: int ( * p@1 ) [ 2 ] ;\n"
3179                                 "3: S ( ) ;\n"
3180                                 "4: } ;\n"
3181                                 "5: S :: S ( ) { p@1 [ 0 ] = 0 ; }\n";
3182         ASSERT_EQUALS(expected, tokenize(code));
3183     }
3184 
varidenum1()3185     void varidenum1() {
3186         const char code[] = "const int eStart = 6;\n"
3187                             "enum myEnum {\n"
3188                             "  A = eStart;\n"
3189                             "};\n";
3190         const char expected[] = "1: const int eStart@1 = 6 ;\n"
3191                                 "2: enum myEnum {\n"
3192                                 "3: A = eStart@1 ;\n"
3193                                 "4: } ;\n";
3194         ASSERT_EQUALS(expected, tokenize(code));
3195     }
3196 
varidenum2()3197     void varidenum2() {
3198         const char code[] = "const int eStart = 6;\n"
3199                             "enum myEnum {\n"
3200                             "  A = f(eStart);\n"
3201                             "};\n";
3202         const char expected[] = "1: const int eStart@1 = 6 ;\n"
3203                                 "2: enum myEnum {\n"
3204                                 "3: A = f ( eStart@1 ) ;\n"
3205                                 "4: } ;\n";
3206         ASSERT_EQUALS(expected, tokenize(code));
3207     }
3208 
varidenum3()3209     void varidenum3() {
3210         const char code[] = "const int eStart = 6;\n"
3211                             "enum myEnum {\n"
3212                             "  A = f(eStart, x);\n"
3213                             "};\n";
3214         const char expected[] = "1: const int eStart@1 = 6 ;\n"
3215                                 "2: enum myEnum {\n"
3216                                 "3: A = f ( eStart@1 , x ) ;\n"
3217                                 "4: } ;\n";
3218         ASSERT_EQUALS(expected, tokenize(code));
3219     }
3220 
varidenum4()3221     void varidenum4() {
3222         const char code[] = "const int eStart = 6;\n"
3223                             "enum myEnum {\n"
3224                             "  A = f(x, eStart);\n"
3225                             "};\n";
3226         const char expected[] = "1: const int eStart@1 = 6 ;\n"
3227                                 "2: enum myEnum {\n"
3228                                 "3: A = f ( x , eStart@1 ) ;\n"
3229                                 "4: } ;\n";
3230         ASSERT_EQUALS(expected, tokenize(code));
3231     }
3232 
varidenum5()3233     void varidenum5() {
3234         const char code[] = "const int eStart = 6;\n"
3235                             "enum myEnum {\n"
3236                             "  A = f(x, eStart, y);\n"
3237                             "};\n";
3238         const char expected[] = "1: const int eStart@1 = 6 ;\n"
3239                                 "2: enum myEnum {\n"
3240                                 "3: A = f ( x , eStart@1 , y ) ;\n"
3241                                 "4: } ;\n";
3242         const char current[] = "1: const int eStart@1 = 6 ;\n"
3243                                "2: enum myEnum {\n"
3244                                "3: A = f ( x , eStart , y ) ;\n"
3245                                "4: } ;\n";
3246         TODO_ASSERT_EQUALS(expected, current, tokenize(code));
3247     }
3248 
varid_classnameshaddowsvariablename()3249     void varid_classnameshaddowsvariablename() {
3250         const char code[] = "class Data;\n"
3251                             "void strange_declarated(const Data& Data);\n"
3252                             "void handleData(const Data& data) {\n"
3253                             "    strange_declarated(data);\n"
3254                             "}\n";
3255         const char expected[] = "1: class Data ;\n"
3256                                 "2: void strange_declarated ( const Data & Data@1 ) ;\n"
3257                                 "3: void handleData ( const Data & data@2 ) {\n"
3258                                 "4: strange_declarated ( data@2 ) ;\n"
3259                                 "5: }\n";
3260         ASSERT_EQUALS(expected, tokenize(code));
3261 
3262     }
3263 
varid_classnametemplate()3264     void varid_classnametemplate() {
3265         const char code[] = "template <typename T>\n"
3266                             "struct BBB {\n"
3267                             "  struct inner;\n"
3268                             "};\n"
3269                             "\n"
3270                             "template <typename T>\n"
3271                             "struct BBB<T>::inner {\n"
3272                             "  inner(int x);\n"
3273                             "  int x;\n"
3274                             "};\n"
3275                             "\n"
3276                             "template <typename T>\n"
3277                             "BBB<T>::inner::inner(int x): x(x) {}\n";
3278         const char expected[] = "1: template < typename T >\n"
3279                                 "2: struct BBB {\n"
3280                                 "3: struct inner ;\n"
3281                                 "4: } ;\n"
3282                                 "5:\n"
3283                                 "6: template < typename T >\n"
3284                                 "7: struct BBB < T > :: inner {\n"
3285                                 "8: inner ( int x@1 ) ;\n"
3286                                 "9: int x@2 ;\n"
3287                                 "10: } ;\n"
3288                                 "11:\n"
3289                                 "12: template < typename T >\n"
3290                                 "13: BBB < T > :: inner :: inner ( int x@3 ) : x@2 ( x@3 ) { }\n";
3291         ASSERT_EQUALS(expected, tokenize(code));
3292 
3293     }
3294 
varidnamespace1()3295     void varidnamespace1() {
3296         const char code[] = "namespace A {\n"
3297                             "    char buf[20];\n"
3298                             "}\n"
3299                             "int main() {\n"
3300                             "    return foo(A::buf);\n"
3301                             "}";
3302 
3303         const char expected[] = "1: namespace A {\n"
3304                                 "2: char buf@1 [ 20 ] ;\n"
3305                                 "3: }\n"
3306                                 "4: int main ( ) {\n"
3307                                 "5: return foo ( A :: buf@1 ) ;\n"
3308                                 "6: }\n";
3309 
3310         ASSERT_EQUALS(expected, tokenize(code));
3311     }
3312 
varidnamespace2()3313     void varidnamespace2() {
3314         const char code[] = "namespace A {\n"
3315                             "  namespace B {\n"
3316                             "    char buf[20];\n"
3317                             "  }\n"
3318                             "}\n"
3319                             "int main() {\n"
3320                             "  return foo(A::B::buf);\n"
3321                             "}";
3322 
3323         const char expected[] = "1: namespace A {\n"
3324                                 "2: namespace B {\n"
3325                                 "3: char buf@1 [ 20 ] ;\n"
3326                                 "4: }\n"
3327                                 "5: }\n"
3328                                 "6: int main ( ) {\n"
3329                                 "7: return foo ( A :: B :: buf@1 ) ;\n"
3330                                 "8: }\n";
3331 
3332         ASSERT_EQUALS(expected, tokenize(code));
3333     }
3334 
usingNamespace1()3335     void usingNamespace1() {
3336         const char code[] = "namespace NS {\n"
3337                             "  class A { int x; void dostuff(); };\n"
3338                             "}\n"
3339                             "using namespace NS;\n"
3340                             "void A::dostuff() { x = 0; }\n";
3341         const char expected[] = "1: namespace NS {\n"
3342                                 "2: class A { int x@1 ; void dostuff ( ) ; } ;\n"
3343                                 "3: }\n"
3344                                 "4: using namespace NS ;\n"
3345                                 "5: void A :: dostuff ( ) { x@1 = 0 ; }\n";
3346         ASSERT_EQUALS(expected, tokenize(code));
3347     }
3348 
usingNamespace2()3349     void usingNamespace2() {
3350         const char code[] = "class A { int x; void dostuff(); };\n"
3351                             "using namespace NS;\n"
3352                             "void A::dostuff() { x = 0; }\n";
3353         const char expected[] = "1: class A { int x@1 ; void dostuff ( ) ; } ;\n"
3354                                 "2: using namespace NS ;\n"
3355                                 "3: void A :: dostuff ( ) { x@1 = 0 ; }\n";
3356         ASSERT_EQUALS(expected, tokenize(code));
3357     }
3358 
usingNamespace3()3359     void usingNamespace3() {
3360         const char code[] = "namespace A {\n"
3361                             "    namespace B {\n"
3362                             "        class C {\n"
3363                             "            double m;\n"
3364                             "            C();\n"
3365                             "        };\n"
3366                             "    }\n"
3367                             "}\n"
3368                             "using namespace A::B;\n"
3369                             "C::C() : m(42) {}";
3370 
3371         const char expected[] = "1: namespace A {\n"
3372                                 "2: namespace B {\n"
3373                                 "3: class C {\n"
3374                                 "4: double m@1 ;\n"
3375                                 "5: C ( ) ;\n"
3376                                 "6: } ;\n"
3377                                 "7: }\n"
3378                                 "8: }\n"
3379                                 "9: using namespace A :: B ;\n"
3380                                 "10: C :: C ( ) : m@1 ( 42 ) { }\n";
3381 
3382         ASSERT_EQUALS(expected, tokenize(code));
3383     }
3384 
setVarIdStructMembers1()3385     void setVarIdStructMembers1() {
3386         const char code[] = "void f(Foo foo)\n"
3387                             "{\n"
3388                             "    foo.size = 0;\n"
3389                             "    return ((uint8_t)(foo).size);\n"
3390                             "}";
3391         const char expected[] = "1: void f ( Foo foo@1 )\n"
3392                                 "2: {\n"
3393                                 "3: foo@1 . size@2 = 0 ;\n"
3394                                 "4: return ( ( uint8_t ) ( foo@1 ) . size@2 ) ;\n"
3395                                 "5: }\n";
3396         ASSERT_EQUALS(expected, tokenize(code));
3397     }
3398 
decltype1()3399     void decltype1() {
3400         const char code[] = "void foo(int x, decltype(A::b) *p);";
3401         const char expected[] = "1: void foo ( int x@1 , decltype ( A :: b ) * p@2 ) ;\n";
3402         ASSERT_EQUALS(expected, tokenize(code));
3403     }
3404 
decltype2()3405     void decltype2() {
3406         const char code[] = "int x; decltype(x) y;";
3407         const char expected[] = "1: int x@1 ; decltype ( x@1 ) y@2 ;\n";
3408         ASSERT_EQUALS(expected, tokenize(code));
3409     }
3410 
exprid1()3411     void exprid1() {
3412         const std::string actual = tokenizeExpr(
3413             "struct A {\n"
3414             "    int x, y;\n"
3415             "};\n"
3416             "int f(A a, A b) {\n"
3417             "    int x = a.x + b.x;\n"
3418             "    int y = b.x + a.x;\n"
3419             "    return x + y + a.y + b.y;\n"
3420             "}\n");
3421 
3422         const char expected[] = "1: struct A {\n"
3423                                 "2: int x ; int y ;\n"
3424                                 "3: } ;\n"
3425                                 "4: int f ( A a , A b ) {\n"
3426                                 "5: int x@5 ; x@5 = a@3 .@9 x@6 +@10 b@4 .@11 x@7 ;\n"
3427                                 "6: int y@8 ; y@8 = b@4 .@11 x@7 +@10 a@3 .@9 x@6 ;\n"
3428                                 "7: return x@5 +@15 y@8 +@16 a@3 .@17 y@9 +@18 b@4 .@19 y@10 ;\n"
3429                                 "8: }\n";
3430 
3431         ASSERT_EQUALS(expected, actual);
3432     }
3433 
structuredBindings()3434     void structuredBindings() {
3435         const char code[] = "int foo() { auto [x,y] = xy(); return x+y; }";
3436         ASSERT_EQUALS("1: int foo ( ) { auto [ x@1 , y@2 ] = xy ( ) ; return x@1 + y@2 ; }\n",
3437                       tokenize(code));
3438     }
3439 };
3440 
3441 REGISTER_TEST(TestVarID)
3442