(std::forward(p))... {}\n"
"};\n"
"template \n"
"struct S {\n"
" D d;\n"
"};\n";
ASSERT_EQUALS("1: template < typename ... T >\n"
"2: struct B { } ;\n"
"3: template < typename ... T >\n"
"4: struct D : B < T > ... {\n"
"5: template < typename ... P >\n"
"6: D ( P && ... p@1 ) : B < T > ( std :: forward < P > ( p@1 ) ) ... { }\n"
"7: } ;\n"
"8: template < typename ... T >\n"
"9: struct S {\n"
"10: D < T ... > d@2 ;\n"
"11: } ;\n",
tokenize(code13));
}
void varid_initListWithBaseTemplate() {
const char code1[] = "class A : B {\n"
" A() : B(), x(0) {}\n"
" int x;\n"
"};";
ASSERT_EQUALS("1: class A : B < C , D > {\n"
"2: A ( ) : B < C , D > ( ) , x@1 ( 0 ) { }\n"
"3: int x@1 ;\n"
"4: } ;\n",
tokenize(code1));
const char code2[] = "class A : B {\n"
" A(int x) : x(x) {}\n"
" int x;\n"
"};";
ASSERT_EQUALS("1: class A : B < C , D > {\n"
"2: A ( int x@1 ) : x@2 ( x@1 ) { }\n"
"3: int x@2 ;\n"
"4: } ;\n",
tokenize(code2));
const char code3[] = "class A : B {\n"
" A(int x);\n"
" int x;\n"
"};\n"
"A::A(int x) : x(x) {}";
ASSERT_EQUALS("1: class A : B < C , D > {\n"
"2: A ( int x@1 ) ;\n"
"3: int x@2 ;\n"
"4: } ;\n"
"5: A :: A ( int x@3 ) : x@2 ( x@3 ) { }\n",
tokenize(code3));
const char code4[] = "struct A : B {\n"
" int x;\n"
" A(int x) : x(x) {}\n"
"};\n";
ASSERT_EQUALS("1: struct A : B < C , D > {\n"
"2: int x@1 ;\n"
"3: A ( int x@2 ) : x@1 ( x@2 ) { }\n"
"4: } ;\n",
tokenize(code4));
const char code5[] = "class BCLass : public Ticket {\n"
" BCLass();\n"
" PClass* member;\n"
"};\n"
"BCLass::BCLass() : Ticket() {\n"
" member = 0;\n"
"}";
ASSERT_EQUALS("1: class BCLass : public Ticket < void > {\n"
"2: BCLass ( ) ;\n"
"3: PClass * member@1 ;\n"
"4: } ;\n"
"5: BCLass :: BCLass ( ) : Ticket < void > ( ) {\n"
"6: member@1 = 0 ;\n"
"7: }\n",
tokenize(code5));
}
void varid_initListWithScope() {
const char code1[] = "class A : public B::C {\n"
" A() : B::C(), x(0) {}\n"
" int x;\n"
"};";
ASSERT_EQUALS("1: class A : public B :: C {\n"
"2: A ( ) : B :: C ( ) , x@1 ( 0 ) { }\n"
"3: int x@1 ;\n"
"4: } ;\n",
tokenize(code1));
}
void varid_operator() {
{
const std::string actual = tokenize(
"class Foo\n"
"{\n"
"public:\n"
" void operator=(const Foo &);\n"
"};");
const char expected[] = "1: class Foo\n"
"2: {\n"
"3: public:\n"
"4: void operator= ( const Foo & ) ;\n"
"5: } ;\n";
ASSERT_EQUALS(expected, actual);
}
{
const std::string actual = tokenize(
"struct Foo {\n"
" void * operator new [](int);\n"
"};");
const char expected[] = "1: struct Foo {\n"
"2: void * operatornew[] ( int ) ;\n"
"3: } ;\n";
ASSERT_EQUALS(expected, actual);
}
}
void varid_throw() { // ticket #1723
const std::string actual = tokenize(
"UserDefinedException* pe = new UserDefinedException();\n"
"throw pe;");
const char expected[] = "1: UserDefinedException * pe@1 ; pe@1 = new UserDefinedException ( ) ;\n"
"2: throw pe@1 ;\n";
ASSERT_EQUALS(expected, actual);
}
void varid_unknown_macro() {
// #2638 - unknown macro
const char code[] = "void f() {\n"
" int a[10];\n"
" AAA\n"
" a[0] = 0;\n"
"}";
const char expected[] = "1: void f ( ) {\n"
"2: int a@1 [ 10 ] ;\n"
"3: AAA\n"
"4: a@1 [ 0 ] = 0 ;\n"
"5: }\n";
ASSERT_EQUALS(expected, tokenize(code, dinit(TokenizeOptions, $.cpp = false)));
}
void varid_using() {
// #3648
const char code[] = "using std::size_t;";
const char expected[] = "1: using unsigned long ;\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void varid_catch() {
const char code[] = "void f() {\n"
" try { dostuff(); }\n"
" catch (exception &e) { }\n"
"}";
const char expected[] = "1: void f ( ) {\n"
"2: try { dostuff ( ) ; }\n"
"3: catch ( exception & e@1 ) { }\n"
"4: }\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void varid_functionPrototypeTemplate() {
ASSERT_EQUALS("1: function < void ( ) > fptr@1 ;\n", tokenize("function fptr;"));
}
void varid_templatePtr() {
ASSERT_EQUALS("1: std :: map < int , FooTemplate < int > * > dummy_member@1 [ 1 ] ;\n", tokenize("std::map*> dummy_member[1];"));
}
void varid_templateNamespaceFuncPtr() {
ASSERT_EQUALS("1: KeyListT < float , & NIFFile :: getFloat > mKeyList@1 [ 4 ] ;\n", tokenize("KeyListT mKeyList[4];"));
}
void varid_templateArray() {
ASSERT_EQUALS("1: VertexArrayIterator < float [ 2 ] > attrPos@1 ; attrPos@1 = m_AttributePos . GetIterator < float [ 2 ] > ( ) ;\n",
tokenize("VertexArrayIterator attrPos = m_AttributePos.GetIterator();"));
}
void varid_templateParameter() {
{
const char code[] = "const int X = 0;\n" // #7046 set varid for "X": std::array Y;
"std::array Y;\n";
ASSERT_EQUALS("1: const int X@1 = 0 ;\n"
"2: std :: array < int , X@1 > Y@2 ;\n",
tokenize(code));
}
{
const char code[] = "std::optional> Foo;\n"; // #11003
ASSERT_EQUALS("1: std :: optional < N :: Foo < A > > Foo@1 ;\n",
tokenize(code));
}
}
void varid_templateParameterFunctionPointer() {
{
const char code[] = "template \n"
"struct a;\n";
ASSERT_EQUALS("1: template < class , void ( * F ) ( ) >\n"
"2: struct a ;\n",
tokenize(code));
}
}
void varid_templateUsing() { // #5781 #7273
const char code[] = "template using X = Y;\n"
"X x;";
ASSERT_EQUALS("2: Y < int , 4 > x@1 ;\n",
tokenize(code));
}
void varid_templateSpecializationFinal() {
const char code[] = "template \n"
"struct S;\n"
"template <>\n"
"struct S final {};\n";
ASSERT_EQUALS("4: struct S ;\n"
"1: template < typename T >\n"
"2: struct S ;\n"
"3:\n"
"4: struct S { } ;\n",
tokenize(code));
}
void varid_not_template_in_condition() {
const char code1[] = "void f() { if (xb); }";
ASSERT_EQUALS("1: void f ( ) { if ( x < a || x > b ) { ; } }\n", tokenize(code1));
const char code2[] = "void f() { if (1+xb); }";
ASSERT_EQUALS("1: void f ( ) { if ( 1 + x < a || x > b ) { ; } }\n", tokenize(code2));
const char code3[] = "void f() { if (xb+1); }";
ASSERT_EQUALS("1: void f ( ) { if ( x < a || x > b + 1 ) { ; } }\n", tokenize(code3));
const char code4[] = "void f() { if ((x==13) && (xb)); }";
ASSERT_EQUALS("1: void f ( ) { if ( ( x == 13 ) && ( x < a || x > b ) ) { ; } }\n", tokenize(code4));
}
void varid_cppcast() {
ASSERT_EQUALS("1: const_cast < int * > ( code ) [ 0 ] = 0 ;\n",
tokenize("const_cast(code)[0] = 0;"));
ASSERT_EQUALS("1: dynamic_cast < int * > ( code ) [ 0 ] = 0 ;\n",
tokenize("dynamic_cast(code)[0] = 0;"));
ASSERT_EQUALS("1: reinterpret_cast < int * > ( code ) [ 0 ] = 0 ;\n",
tokenize("reinterpret_cast(code)[0] = 0;"));
ASSERT_EQUALS("1: static_cast < int * > ( code ) [ 0 ] = 0 ;\n",
tokenize("static_cast(code)[0] = 0;"));
}
void varid_variadicFunc() {
ASSERT_EQUALS("1: int foo ( ... ) ;\n", tokenize("int foo(...);"));
}
void varid_typename() {
ASSERT_EQUALS("1: template < int d , class A , class B > struct S { } ;\n", tokenize("template struct S {};"));
ASSERT_EQUALS("1: template < int d , typename A , typename B > struct S { } ;\n", tokenize("template struct S {};"));
ASSERT_EQUALS("1: A a@1 ;\n", tokenize("typename A a;"));
}
void varid_rvalueref() {
ASSERT_EQUALS("1: int && a@1 ;\n", tokenize("int&& a;"));
ASSERT_EQUALS("1: void foo ( int && a@1 ) { }\n", tokenize("void foo(int&& a) {}"));
ASSERT_EQUALS("1: class C {\n"
"2: C ( int && a@1 ) ;\n"
"3: } ;\n",
tokenize("class C {\n"
" C(int&& a);\n"
"};"));
ASSERT_EQUALS("1: void foo ( int && ) ;\n", tokenize("void foo(int&&);"));
}
void varid_arrayFuncPar() {
ASSERT_EQUALS("1: void check ( const char fname@1 [ ] = 0 ) { }\n", tokenize("void check( const char fname[] = 0) { }"));
}
void varid_sizeofPassed() {
ASSERT_EQUALS("1: void which_test ( ) {\n"
"2: const char * argv@1 [ 2 ] = { \"./test_runner\" , \"TestClass\" } ;\n"
"3: options args@2 ( sizeof ( argv@1 ) / sizeof ( argv@1 [ 0 ] ) , argv@1 ) ;\n"
"4: args@2 . which_test ( ) ;\n"
"5: }\n",
tokenize("void which_test() {\n"
" const char* argv[] = { \"./test_runner\", \"TestClass\" };\n"
" options args(sizeof argv / sizeof argv[0], argv);\n"
" args.which_test();\n"
"}"));
}
void varid_classInFunction() {
ASSERT_EQUALS("1: void AddSuppression ( ) {\n"
"2: class QErrorLogger {\n"
"3: void reportErr ( ErrorLogger :: ErrorMessage & msg@1 ) {\n"
"4: }\n"
"5: } ;\n"
"6: }\n",
tokenize("void AddSuppression() {\n"
" class QErrorLogger {\n"
" void reportErr(ErrorLogger::ErrorMessage &msg) {\n"
" }\n"
" };\n"
"}"));
}
void varid_pointerToArray() {
ASSERT_EQUALS("1: int ( * a1@1 ) [ 10 ] ;\n"
"2: void f1 ( ) {\n"
"3: int ( * a2@2 ) [ 10 ] ;\n"
"4: int ( & a3@3 ) [ 10 ] ;\n"
"5: }\n"
"6: struct A {\n"
"7: int ( & a4@4 ) [ 10 ] ;\n"
"8: int f2 ( int i@5 ) { return a4@4 [ i@5 ] ; }\n"
"9: int f3 ( int ( & a5@6 ) [ 10 ] , int i@7 ) { return a5@6 [ i@7 ] ; }\n"
"10: } ;\n"
"11: int f4 ( int ( & a6@8 ) [ 10 ] , int i@9 ) { return a6@8 [ i@9 ] ; }\n",
tokenize("int (*a1)[10];\n" // pointer to array of 10 ints
"void f1() {\n"
" int(*a2)[10];\n"
" int(&a3)[10];\n"
"}\n"
"struct A {\n"
" int(&a4)[10];\n"
" int f2(int i) { return a4[i]; }\n"
" int f3(int(&a5)[10], int i) { return a5[i]; }\n"
"};\n"
"int f4(int(&a6)[10], int i) { return a6[i]; }"));
}
void varid_cpp11initialization() {
ASSERT_EQUALS("1: int i@1 { 1 } ;\n"
"2: std :: vector < int > vec@2 { 1 , 2 , 3 } ;\n"
"3: namespace n { int z@3 ; } ;\n"
"4: int & j@4 { i@1 } ;\n"
"5: int k@5 { 1 } ; int l@6 { 2 } ;\n",
tokenize("int i{1};\n"
"std::vector vec{1, 2, 3};\n"
"namespace n { int z; };\n"
"int& j{i};\n"
"int k{1}, l{2};"));
// #6030
ASSERT_EQUALS("1: struct S3 : public S1 , public S2 { } ;\n",
tokenize("struct S3 : public S1, public S2 { };"));
// #6058
ASSERT_EQUALS("1: class Scope { } ;\n",
tokenize("class CPPCHECKLIB Scope { };"));
// #6073 #6253
ASSERT_EQUALS("1: class A : public B , public C :: D , public E < F > :: G < H > {\n"
"2: int i@1 ;\n"
"3: A ( int i@2 ) : B { i@2 } , C :: D { i@2 } , E < F > :: G < H > { i@2 } , i@1 { i@2 } {\n"
"4: int j@3 { i@2 } ;\n"
"5: }\n"
"6: } ;\n",
tokenize("class A: public B, public C::D, public E::G {\n"
" int i;\n"
" A(int i): B{i}, C::D{i}, E::G{i} ,i{i} {\n"
" int j{i};\n"
" }\n"
"};"));
ASSERT_EQUALS("1: struct Sx { int i@1 ; } ;\n" // #14733
"2: struct Sx sx@2 { 0 } ;\n",
tokenize("struct Sx { int i; };\n"
"struct Sx sx{ 0 }; \n"));
}
void varid_inheritedMembers() {
ASSERT_EQUALS("1: class A {\n"
"2: int a@1 ;\n"
"3: } ;\n"
"4: class B : public A {\n"
"5: void f ( ) ;\n"
"6: } ;\n"
"7: void B :: f ( ) {\n"
"8: a@1 = 0 ;\n"
"9: }\n",
tokenize("class A {\n"
" int a;\n"
"};\n"
"class B : public A {\n"
" void f();\n"
"};\n"
"void B::f() {\n"
" a = 0;\n"
"}"));
ASSERT_EQUALS("1: class A {\n"
"2: int a@1 ;\n"
"3: } ;\n"
"4: class B : A {\n"
"5: void f ( ) ;\n"
"6: } ;\n"
"7: void B :: f ( ) {\n"
"8: a@1 = 0 ;\n"
"9: }\n",
tokenize("class A {\n"
" int a;\n"
"};\n"
"class B : A {\n"
" void f();\n"
"};\n"
"void B::f() {\n"
" a = 0;\n"
"}"));
ASSERT_EQUALS("1: class A {\n"
"2: int a@1 ;\n"
"3: } ;\n"
"4: class B : protected B , public A {\n"
"5: void f ( ) ;\n"
"6: } ;\n"
"7: void B :: f ( ) {\n"
"8: a@1 = 0 ;\n"
"9: }\n",
tokenize("class A {\n"
" int a;\n"
"};\n"
"class B : protected B, public A {\n"
" void f();\n"
"};\n"
"void B::f() {\n"
" a = 0;\n"
"}"));
ASSERT_EQUALS("1: class A {\n"
"2: int a@1 ;\n"
"3: } ;\n"
"4: class B : public A {\n"
"5: void f ( ) {\n"
"6: a@1 = 0 ;\n"
"7: }\n"
"8: } ;\n",
tokenize("class A {\n"
" int a;\n"
"};\n"
"class B : public A {\n"
" void f() {\n"
" a = 0;\n"
" }\n"
"};"));
}
void varid_header() {
ASSERT_EQUALS("1: class A@1 ;\n"
"2: struct B {\n"
"3: void setData ( const A@1 & a ) ;\n"
"4: } ;\n",
tokenizeHeader("class A;\n"
"struct B {\n"
" void setData(const A & a);\n"
"}; ", "test.h"));
ASSERT_EQUALS("1: class A ;\n"
"2: struct B {\n"
"3: void setData ( const A & a@1 ) ;\n"
"4: } ;\n",
tokenizeHeader("class A;\n"
"struct B {\n"
" void setData(const A & a);\n"
"}; ", "test.hpp"));
ASSERT_EQUALS("1: void f ( )\n"
"2: {\n"
"3: int class@1 ;\n"
"4: }\n",
tokenizeHeader("void f()\n"
"{\n"
" int class;\n"
"}", "test.h"));
}
void varid_rangeBasedFor() {
ASSERT_EQUALS("1: void reset ( Foo array@1 ) {\n"
"2: for ( auto & e@2 : array@1 ) {\n"
"3: foo ( e@2 ) ; }\n"
"4: } ;\n",
tokenize("void reset(Foo array) {\n"
" for (auto& e : array)\n"
" foo(e);\n"
"};"));
ASSERT_EQUALS("1: void reset ( Foo array@1 ) {\n"
"2: for ( auto e@2 : array@1 ) {\n"
"3: foo ( e@2 ) ; }\n"
"4: } ;\n",
tokenize("void reset(Foo array) {\n"
" for (auto e : array)\n"
" foo(e);\n"
"};"));
// Labels are no variables
ASSERT_EQUALS("1: void foo ( ) {\n"
"2: switch ( event . key . keysym . sym ) {\n"
"3: case SDLK_LEFT : ;\n"
"4: break ;\n"
"5: case SDLK_RIGHT : ;\n"
"6: delta = 1 ;\n"
"7: break ;\n"
"8: }\n"
"9: }\n",
tokenize("void foo() {\n"
" switch (event.key.keysym.sym) {\n"
" case SDLK_LEFT:\n"
" break;\n"
" case SDLK_RIGHT:\n"
" delta = 1;\n"
" break;\n"
" }\n"
"}", dinit(TokenizeOptions, $.cpp = false)));
ASSERT_EQUALS("1: int * f ( ) {\n" // #11838
"2: int * label@1 ; label@1 = 0 ;\n"
"3: label : ;\n"
"4: return label@1 ;\n"
"5: }\n",
tokenize("int* f() {\n"
" int* label = 0;\n"
"label:\n"
" return label;\n"
"}"));
}
void varid_structinit() { // #6406
ASSERT_EQUALS("1: void foo ( ) {\n"
"2: struct ABC abc@1 ; abc@1 = { . a@2 = 0 , . b@3 = 1 } ;\n"
"3: }\n",
tokenize("void foo() {\n"
" struct ABC abc = {.a=0,.b=1};\n"
"}"));
ASSERT_EQUALS("1: void foo ( ) {\n"
"2: struct ABC abc@1 ; abc@1 = { . a@2 = abc@1 . a@2 , . b@3 = abc@1 . b@3 } ;\n"
"3: }\n",
tokenize("void foo() {\n"
" struct ABC abc = {.a=abc.a,.b=abc.b};\n"
"}"));
ASSERT_EQUALS("1: void foo ( ) {\n"
"2: struct ABC abc@1 ; abc@1 = { . a@2 { abc@1 . a@2 } , . b@3 = { abc@1 . b@3 } } ;\n"
"3: }\n",
tokenize("void foo() {\n"
" struct ABC abc = {.a { abc.a },.b= { abc.b } };\n"
"}"));
ASSERT_EQUALS("1: struct T { int a@1 ; } ;\n" // #13123
"2: void f ( int a@2 ) {\n"
"3: struct T t@3 ; t@3 = { . a@4 = 1 } ;\n"
"4: }\n",
tokenize("struct T { int a; };\n"
"void f(int a) {\n"
" struct T t = { .a = 1 };\n"
"}\n"));
ASSERT_EQUALS("1: struct S { int x@1 ; } ;\n" // TODO: set some varid for designated initializer?
"2: void f0 ( S s@2 ) ;\n"
"3: void f1 ( int n@3 ) {\n"
"4: if ( int x@4 = n@3 ) {\n"
"5: f0 ( S { . x = x@4 } ) ;\n"
"6: }\n"
"7: }\n",
tokenize("struct S { int x; };\n"
"void f0(S s);\n"
"void f1(int n) {\n"
" if (int x = n) {\n"
" f0(S{ .x = x });\n"
" }\n"
"}\n"));
}
void varid_arrayinit() {
// #7579 - no variable declaration in rhs
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] }; }"));
// #12402
ASSERT_EQUALS("1: void f ( ) { void ( * p@1 [ 1 ] ) ( int ) = { [ ] ( int i@2 ) { } } ; }\n", tokenize("void f() { void (*p[1])(int) = { [](int i) {} }; }"));
}
void varid_lambda_arg() {
// #8664
{
const char code[] = "static void func(int ec) {\n"
" func2([](const std::error_code& ec) { return ec; });\n"
"}";
const char exp[] = "1: static void func ( int ec@1 ) {\n"
"2: func2 ( [ ] ( const std :: error_code & ec@2 ) { return ec@2 ; } ) ;\n"
"3: }\n";
ASSERT_EQUALS(exp, tokenize(code));
}
{
const char code[] = "static void func(int ec) {\n"
" func2([](int x, const std::error_code& ec) { return x + ec; });\n"
"}";
const char exp[] = "1: static void func ( int ec@1 ) {\n"
"2: func2 ( [ ] ( int x@2 , const std :: error_code & ec@3 ) { return x@2 + ec@3 ; } ) ;\n"
"3: }\n";
ASSERT_EQUALS(exp, tokenize(code));
}
// #9384
{
const char code[] = "auto g = [](const std::string& s) -> std::string { return {}; };\n";
const char exp[] = "1: auto g@1 ; g@1 = [ ] ( const std :: string & s@2 ) . std :: string { return { } ; } ;\n";
ASSERT_EQUALS(exp, tokenize(code));
}
{
const char code[] = "auto g = [](std::function p) {};\n";
const char exp[] = "1: auto g@1 ; g@1 = [ ] ( std :: function < void ( ) > p@2 ) { } ;\n";
ASSERT_EQUALS(exp, tokenize(code));
}
// # 10849
{
const char code[] = "class T {};\n"
"auto g = [](const T* t) -> int {\n"
" const T* u{}, *v{};\n"
" return 0;\n"
"};\n";
const char exp[] = "1: class T { } ;\n"
"2: auto g@1 ; g@1 = [ ] ( const T * t@2 ) . int {\n"
"3: const T * u@3 { } ; const T * v@4 { } ;\n"
"4: return 0 ;\n"
"5: } ;\n";
ASSERT_EQUALS(exp, tokenize(code));
}
// # 11332
{
const char code[] = "auto a() {\n"
" return [](int, int b) {};\n"
"}\n";
const char exp[] = "1: auto a ( ) {\n"
"2: return [ ] ( int , int b@1 ) { } ;\n"
"3: }\n";
ASSERT_EQUALS(exp, tokenize(code));
}
}
void varid_lambda_mutable() {
// #8957
{
const char code[] = "static void func() {\n"
" auto x = []() mutable {};\n"
" dostuff(x);\n"
"}";
const char exp[] = "1: static void func ( ) {\n"
"2: auto x@1 ; x@1 = [ ] ( ) mutable { } ;\n"
"3: dostuff ( x@1 ) ;\n"
"4: }\n";
ASSERT_EQUALS(exp, tokenize(code));
}
// #9384
{
const char code[] = "auto g = [](int i) mutable {};\n";
const char exp[] = "1: auto g@1 ; g@1 = [ ] ( int i@2 ) mutable { } ;\n";
ASSERT_EQUALS(exp, tokenize(code));
}
}
void varid_trailing_return1() { // #8889
const char code[] = "struct Fred {\n"
" auto foo(const Fred & other) -> Fred &;\n"
" auto bar(const Fred & other) -> Fred & {\n"
" return *this;\n"
" }\n"
"};\n"
"auto Fred::foo(const Fred & other) -> Fred & {\n"
" return *this;\n"
"}";
const char exp[] = "1: struct Fred {\n"
"2: auto foo ( const Fred & other@1 ) . Fred & ;\n"
"3: auto bar ( const Fred & other@2 ) . Fred & {\n"
"4: return * this ;\n"
"5: }\n"
"6: } ;\n"
"7: auto Fred :: foo ( const Fred & other@3 ) . Fred & {\n"
"8: return * this ;\n"
"9: }\n";
ASSERT_EQUALS(exp, tokenize(code));
}
void varid_trailing_return2() { // #9066
const char code[] = "auto func(int arg) -> bar::quux {}";
const char exp[] = "1: auto func ( int arg@1 ) . bar :: quux { }\n";
ASSERT_EQUALS(exp, tokenize(code));
}
void varid_trailing_return3() { // #11423
const char code[] = "void f(int a, int b) {\n"
" auto g = [](int& a, const int b) -> void {};\n"
" auto h = [&a, &b]() { std::swap(a, b); };\n"
"}\n";
const char exp[] = "1: void f ( int a@1 , int b@2 ) {\n"
"2: auto g@3 ; g@3 = [ ] ( int & a@4 , const int b@5 ) . void { } ;\n"
"3: auto h@6 ; h@6 = [ & a@1 , & b@2 ] ( ) { std :: swap ( a@1 , b@2 ) ; } ;\n"
"4: }\n";
ASSERT_EQUALS(exp, tokenize(code));
}
void varid_parameter_pack() { // #9383
const char code[] = "template \n"
"void func(Rest... parameters) {\n"
" foo(parameters...);\n"
"}\n";
const char exp[] = "1: template < typename ... Rest >\n"
"2: void func ( Rest ... parameters@1 ) {\n"
"3: foo ( parameters@1 ... ) ;\n"
"4: }\n";
ASSERT_EQUALS(exp, tokenize(code));
}
void varid_for_auto_cpp17() {
const char code[] = "void f() {\n"
" for (auto [x,y,z]: xyz) {\n"
" x+y+z;\n"
" }\n"
" x+y+z;\n"
"}";
const char exp[] = "1: void f ( ) {\n"
"2: for ( auto [ x@1 , y@2 , z@3 ] : xyz ) {\n"
"3: x@1 + y@2 + z@3 ;\n"
"4: }\n"
"5: x + y + z ;\n"
"6: }\n";
ASSERT_EQUALS(exp, tokenize(code));
}
void varid_not() { // #9689 'not x'
const char code[] = "void foo(int x) const {\n"
" if (not x) {}\n"
"}";
const char exp[] = "1: void foo ( int x@1 ) const {\n"
"2: if ( ! x@1 ) { }\n"
"3: }\n";
ASSERT_EQUALS(exp, tokenize(code));
}
void varid_declInIfCondition() {
// if
ASSERT_EQUALS("1: void f ( int x@1 ) {\n"
"2: if ( int x@2 = 0 ) { x@2 ; }\n"
"3: x@1 ;\n"
"4: }\n",
tokenize("void f(int x) {\n"
" if (int x = 0) { x; }\n"
" x;\n"
"}"));
// if, else
ASSERT_EQUALS("1: void f ( int x@1 ) {\n"
"2: if ( int x@2 = 0 ) { x@2 ; }\n"
"3: else { x@2 ; }\n"
"4: x@1 ;\n"
"5: }\n",
tokenize("void f(int x) {\n"
" if (int x = 0) { x; }\n"
" else { x; }\n"
" x;\n"
"}"));
// if, else if
ASSERT_EQUALS("1: void f ( int x@1 ) {\n"
"2: if ( int x@2 = 0 ) { x@2 ; }\n"
"3: else { if ( void * x@3 = & x@3 ) { x@3 ; } }\n"
"4: x@1 ;\n"
"5: }\n",
tokenize("void f(int x) {\n"
" if (int x = 0) x;\n"
" else if (void* x = &x) x;\n"
" x;\n"
"}"));
// if, else if, else
ASSERT_EQUALS("1: void f ( int x@1 ) {\n"
"2: if ( int x@2 = 0 ) { x@2 ; }\n"
"3: else { if ( void * x@3 = & x@3 ) { x@3 ; }\n"
"4: else { x@3 ; } }\n"
"5: x@1 ;\n"
"6: }\n",
tokenize("void f(int x) {\n"
" if (int x = 0) x;\n"
" else if (void* x = &x) x;\n"
" else x;\n"
" x;\n"
"}"));
ASSERT_EQUALS("1: const char * f ( int * ) ;\n" // #12924
"2: void g ( int i@1 ) {\n"
"3: if ( f ( & i@1 ) [ 0 ] == 'm' ) { }\n"
"4: }\n",
tokenize("const char *f(int*);\n"
"void g(int i) {\n"
" if (f(&i)[0] == 'm') {}\n"
"}\n", dinit(TokenizeOptions, $.cpp = false)));
}
void varid_globalScope() {
const char code[] = "int a[5];\n"
"namespace Z { struct B { int a[5]; } b; }\n"
"void f() {\n"
" int a[5];\n"
" memset(a, 123, 5);\n"
" memset(::a, 123, 5);\n"
" memset(Z::b.a, 123, 5);\n"
" memset(::Z::b.a, 123, 5);\n"
"}";
const char exp[] = "1: int a@1 [ 5 ] ;\n"
"2: namespace Z { struct B { int a@2 [ 5 ] ; } ; struct B b@3 ; }\n"
"3: void f ( ) {\n"
"4: int a@4 [ 5 ] ;\n"
"5: memset ( a@4 , 123 , 5 ) ;\n"
"6: memset ( :: a@1 , 123 , 5 ) ;\n"
"7: memset ( Z :: b@3 . a , 123 , 5 ) ;\n"
"8: memset ( :: Z :: b@3 . a , 123 , 5 ) ;\n"
"9: }\n";
ASSERT_EQUALS(exp, tokenize(code));
}
void varid_function_pointer_args() {
const char code1[] = "void foo() {\n"
" char *text;\n"
" void (*cb)(char* text);\n"
"}\n";
ASSERT_EQUALS("1: void foo ( ) {\n"
"2: char * text@1 ;\n"
"3: void ( * cb@2 ) ( char * ) ;\n"
"4: }\n", tokenize(code1));
const char code2[] = "void foo() {\n"
" char *text;\n"
" void (*f)(int (*arg)(char* text));\n"
"}\n";
ASSERT_EQUALS("1: void foo ( ) {\n"
"2: char * text@1 ;\n"
"3: void ( * f@2 ) ( int ( * arg ) ( char * ) ) ;\n"
"4: }\n", tokenize(code2));
const char code3[] = "void f (void (*g) (int i, IN int n)) {}\n";
ASSERT_EQUALS("1: void f ( void ( * g@1 ) ( int , IN int ) ) { }\n", tokenize(code3));
const char code4[] = "void f() {\n" // #14439
" int* p;\n"
" void (*a[1])(int* p) = { 0 };\n"
"}\n";
ASSERT_EQUALS("1: void f ( ) {\n"
"2: int * p@1 ;\n"
"3: void ( * a@2 [ 1 ] ) ( int * ) = { 0 } ;\n"
"4: }\n",
tokenize(code4));
const char code5[] = "int *p;\n"
"void (*a[1])(int* p) = { 0 } ;\n";
ASSERT_EQUALS("1: int * p@1 ;\n"
"2: void ( * a@2 [ 1 ] ) ( int * ) = { 0 } ;\n"
, tokenize(code5));
}
void varid_alignas() {
const char code[] = "extern alignas(16) int x;\n"
"alignas(16) int x;";
const char expected[] = "1: extern alignas ( 16 ) int x@1 ;\n"
"2: alignas ( 16 ) int x@2 ;\n";
ASSERT_EQUALS(expected, tokenize(code, dinit(TokenizeOptions, $.cpp = false)));
}
void varidclass1() {
const std::string actual = tokenize(
"class Fred\n"
"{\n"
"private:\n"
" int i;\n"
"\n"
" void foo1();\n"
" void foo2()\n"
" {\n"
" ++i;\n"
" }\n"
"}\n"
"\n"
"Fred::foo1()\n"
"{\n"
" i = 0;\n"
"}");
const char expected[] = "1: class Fred\n"
"2: {\n"
"3: private:\n"
"4: int i@1 ;\n"
"5:\n"
"6: void foo1 ( ) ;\n"
"7: void foo2 ( )\n"
"8: {\n"
"9: ++ i@1 ;\n"
"10: }\n"
"11: }\n"
"12:\n"
"13: Fred :: foo1 ( )\n"
"14: {\n"
"15: i@1 = 0 ;\n"
"16: }\n";
ASSERT_EQUALS(expected, actual);
}
void varidclass2() {
const std::string actual = tokenize(
"class Fred\n"
"{ void f(); };\n"
"\n"
"void A::foo1()\n"
"{\n"
" int i = 0;\n"
"}\n"
"\n"
"void Fred::f()\n"
"{\n"
" i = 0;\n"
"}");
const char expected[] = "1: class Fred\n"
"2: { void f ( ) ; } ;\n"
"3:\n"
"4: void A :: foo1 ( )\n"
"5: {\n"
"6: int i@1 ; i@1 = 0 ;\n"
"7: }\n"
"8:\n"
"9: void Fred :: f ( )\n"
"10: {\n"
"11: i = 0 ;\n"
"12: }\n";
ASSERT_EQUALS(expected, actual);
}
void varidclass3() {
const std::string actual = tokenize(
"class Fred\n"
"{ int i; void f(); };\n"
"\n"
"void Fred::f()\n"
"{\n"
" i = 0;\n"
"}\n"
"\n"
"void A::f()\n"
"{\n"
" i = 0;\n"
"}");
const char expected[] = "1: class Fred\n"
"2: { int i@1 ; void f ( ) ; } ;\n"
"3:\n"
"4: void Fred :: f ( )\n"
"5: {\n"
"6: i@1 = 0 ;\n"
"7: }\n"
"8:\n"
"9: void A :: f ( )\n"
"10: {\n"
"11: i = 0 ;\n"
"12: }\n";
ASSERT_EQUALS(expected, actual);
}
void varidclass4() {
const std::string actual = tokenize(
"class Fred\n"
"{ int i; void f(); };\n"
"\n"
"void Fred::f()\n"
"{\n"
" if (i) { }\n"
" i = 0;\n"
"}");
const char expected[] = "1: class Fred\n"
"2: { int i@1 ; void f ( ) ; } ;\n"
"3:\n"
"4: void Fred :: f ( )\n"
"5: {\n"
"6: if ( i@1 ) { }\n"
"7: i@1 = 0 ;\n"
"8: }\n";
ASSERT_EQUALS(expected, actual);
}
void varidclass5() {
const std::string actual = tokenize(
"class A { };\n"
"class B\n"
"{\n"
" A *a;\n"
" B() : a(new A)\n"
" { }\n"
"};");
const char expected[] = "1: class A { } ;\n"
"2: class B\n"
"3: {\n"
"4: A * a@1 ;\n"
"5: B ( ) : a@1 ( new A )\n"
"6: { }\n"
"7: } ;\n";
ASSERT_EQUALS(expected, actual);
}
void varidclass6() {
const std::string actual = tokenize(
"class A\n"
"{\n"
" public:\n"
" static char buf[20];\n"
"};\n"
"char A::buf[20];\n"
"int main()\n"
"{\n"
" char buf[2];\n"
" A::buf[10] = 0;\n"
"}");
const char expected[] = "1: class A\n"
"2: {\n"
"3: public:\n"
"4: static char buf@1 [ 20 ] ;\n"
"5: } ;\n"
"6: char A :: buf@1 [ 20 ] ;\n"
"7: int main ( )\n"
"8: {\n"
"9: char buf@2 [ 2 ] ;\n"
"10: A :: buf@1 [ 10 ] = 0 ;\n"
"11: }\n";
ASSERT_EQUALS(expected, actual);
}
void varidclass7() {
const std::string actual = tokenize(
"int main()\n"
"{\n"
" char buf[2];\n"
" A::buf[10] = 0;\n"
"}");
const char expected[] = "1: int main ( )\n"
"2: {\n"
"3: char buf@1 [ 2 ] ;\n"
"4: A :: buf [ 10 ] = 0 ;\n"
"5: }\n";
ASSERT_EQUALS(expected, actual);
}
void varidclass8() {
const char code[] ="class Fred {\n"
"public:\n"
" void foo(int d) {\n"
" int i = bar(x * d);\n"
" }\n"
" int x;\n"
"}\n";
const char expected[] = "1: class Fred {\n"
"2: public:\n"
"3: void foo ( int d@1 ) {\n"
"4: int i@2 ; i@2 = bar ( x@3 * d@1 ) ;\n"
"5: }\n"
"6: int x@3 ;\n"
"7: }\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void varidclass9() {
const char code[] ="typedef char Str[10];"
"class A {\n"
"public:\n"
" void f(Str &cl);\n"
" void g(Str cl);\n"
"}\n"
"void Fred::f(Str &cl) {\n"
" sizeof(cl);\n"
"}";
const char expected[] = "1: class A {\n"
"2: public:\n"
"3: void f ( char ( & cl@1 ) [ 10 ] ) ;\n"
"4: void g ( char cl@2 [ 10 ] ) ;\n"
"5: }\n"
"6: void Fred :: f ( char ( & cl@3 ) [ 10 ] ) {\n"
"7: sizeof ( cl@3 ) ;\n"
"8: }\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void varidclass10() {
const char code[] ="class A {\n"
" void f() {\n"
" a = 3;\n"
" }\n"
" int a;\n"
"};\n";
const char expected[] = "1: class A {\n"
"2: void f ( ) {\n"
"3: a@1 = 3 ;\n"
"4: }\n"
"5: int a@1 ;\n"
"6: } ;\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void varidclass11() {
const char code[] ="class Fred {\n"
" int a;\n"
" void f();\n"
"};\n"
"class Wilma {\n"
" int a;\n"
" void f();\n"
"};\n"
"void Fred::f() { a = 0; }\n"
"void Wilma::f() { a = 0; }\n";
const char expected[] = "1: class Fred {\n"
"2: int a@1 ;\n"
"3: void f ( ) ;\n"
"4: } ;\n"
"5: class Wilma {\n"
"6: int a@2 ;\n"
"7: void f ( ) ;\n"
"8: } ;\n"
"9: void Fred :: f ( ) { a@1 = 0 ; }\n"
"10: void Wilma :: f ( ) { a@2 = 0 ; }\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void varidclass12() {
const char code[] ="class Fred {\n"
" int a;\n"
" void f() { Fred::a = 0; }\n"
"};\n";
const char expected[] = "1: class Fred {\n"
"2: int a@1 ;\n"
"3: void f ( ) { Fred :: a@1 = 0 ; }\n"
"4: } ;\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void varidclass13() {
const char code[] ="class Fred {\n"
" int a;\n"
" void f() { Foo::Fred::a = 0; }\n"
"};\n";
const char expected[] = "1: class Fred {\n"
"2: int a@1 ;\n"
"3: void f ( ) { Foo :: Fred :: a = 0 ; }\n"
"4: } ;\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void varidclass14() {
// don't give friend classes varid
{
const char code[] ="class A {\n"
"friend class B;\n"
"}";
const char expected[] = "1: class A {\n"
"2: friend class B ;\n"
"3: }\n";
ASSERT_EQUALS(expected, tokenize(code));
}
{
const char code[] ="class A {\n"
"private: friend class B;\n"
"}";
const char expected[] = "1: class A {\n"
"2: private: friend class B ;\n"
"3: }\n";
ASSERT_EQUALS(expected, tokenize(code));
}
}
void varidclass15() {
const char code[] = "class A {\n"
" int a;\n"
" int b;\n"
" A();\n"
"};\n"
"A::A() : a(0) { b = 1; }";
const char expected[] = "1: class A {\n"
"2: int a@1 ;\n"
"3: int b@2 ;\n"
"4: A ( ) ;\n"
"5: } ;\n"
"6: A :: A ( ) : a@1 ( 0 ) { b@2 = 1 ; }\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void varidclass16() {
const char code[] = "struct A;\n"
"typedef bool (A::* FuncPtr)();\n"
"struct A {\n"
" FuncPtr pFun;\n"
" void setPFun(int mode);\n"
" bool funcNorm();\n"
"};\n"
"void A::setPFun(int mode) {\n"
" pFun = &A::funcNorm;\n"
"}";
const char expected[] = "1: struct A ;\n"
"2:\n"
"3: struct A {\n"
"4: bool ( * pFun@1 ) ( ) ;\n"
"5: void setPFun ( int mode@2 ) ;\n"
"6: bool funcNorm ( ) ;\n"
"7: } ;\n"
"8: void A :: setPFun ( int mode@3 ) {\n"
"9: pFun@1 = & A :: funcNorm ;\n"
"10: }\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void varidclass17() {
const char code[] = "class A: public B, public C::D {\n"
" int i;\n"
" A(int i): B(i), C::D(i), i(i) {\n"
" int j(i);\n"
" }\n"
"};";
const char expected[] = "1: class A : public B , public C :: D {\n"
"2: int i@1 ;\n"
"3: A ( int i@2 ) : B ( i@2 ) , C :: D ( i@2 ) , i@1 ( i@2 ) {\n"
"4: int j@3 ( i@2 ) ;\n"
"5: }\n"
"6: } ;\n";
ASSERT_EQUALS(expected, tokenize(code));
const char code2[] = "struct S {\n" // #11411
" std::vector v;\n"
" int i;\n"
" S(int i) : v({ 0 }), i(i) {}\n"
"};";
const char expected2[] = "1: struct S {\n"
"2: std :: vector < int > v@1 ;\n"
"3: int i@2 ;\n"
"4: S ( int i@3 ) : v@1 ( { 0 } ) , i@2 ( i@3 ) { }\n"
"5: } ;\n";
ASSERT_EQUALS(expected2, tokenize(code2));
}
void varidclass18() {
const char code[] = "class A {\n"
" int a;\n"
" int b;\n"
" A();\n"
"};\n"
"A::A() : a{0} { b = 1; }";
const char expected[] = "1: class A {\n"
"2: int a@1 ;\n"
"3: int b@2 ;\n"
"4: A ( ) ;\n"
"5: } ;\n"
"6: A :: A ( ) : a@1 { 0 } { b@2 = 1 ; }\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void varidclass19() {
const char code[] = "class A : public ::B {\n"
" int a;\n"
" A();\n"
"};\n"
"A::A() : ::B(), a(0) {}";
const char expected[] = "1: class A : public :: B {\n"
"2: int a@1 ;\n"
"3: A ( ) ;\n"
"4: } ;\n"
"5: A :: A ( ) : :: B ( ) , a@1 ( 0 ) { }\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void varidclass20() { // #7578: int (*p)[2]
const char code[] = "struct S {\n"
" int (*p)[2];\n"
" S();\n"
"};\n"
"S::S() { p[0] = 0; }";
const char expected[] = "1: struct S {\n"
"2: int ( * p@1 ) [ 2 ] ;\n"
"3: S ( ) ;\n"
"4: } ;\n"
"5: S :: S ( ) { p@1 [ 0 ] = 0 ; }\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void varidenum1() {
const char code[] = "const int eStart = 6;\n"
"enum myEnum {\n"
" A = eStart\n"
"};\n";
const char expected[] = "1: const int eStart@1 = 6 ;\n"
"2: enum myEnum {\n"
"3: A = eStart@1\n"
"4: } ;\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void varidenum2() {
const char code[] = "const int eStart = 6;\n"
"enum myEnum {\n"
" A = f(eStart)\n"
"};\n";
const char expected[] = "1: const int eStart@1 = 6 ;\n"
"2: enum myEnum {\n"
"3: A = f ( eStart@1 )\n"
"4: } ;\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void varidenum3() {
const char code[] = "const int eStart = 6;\n"
"enum myEnum {\n"
" A = f(eStart, x)\n"
"};\n";
const char expected[] = "1: const int eStart@1 = 6 ;\n"
"2: enum myEnum {\n"
"3: A = f ( eStart@1 , x )\n"
"4: } ;\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void varidenum4() {
const char code[] = "const int eStart = 6;\n"
"enum myEnum {\n"
" A = f(x, eStart)\n"
"};\n";
const char expected[] = "1: const int eStart@1 = 6 ;\n"
"2: enum myEnum {\n"
"3: A = f ( x , eStart@1 )\n"
"4: } ;\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void varidenum5() {
const char code[] = "const int eStart = 6;\n"
"enum myEnum {\n"
" A = f(x, eStart, y)\n"
"};\n";
const char expected[] = "1: const int eStart@1 = 6 ;\n"
"2: enum myEnum {\n"
"3: A = f ( x , eStart@1 , y )\n"
"4: } ;\n";
const char current[] = "1: const int eStart@1 = 6 ;\n"
"2: enum myEnum {\n"
"3: A = f ( x , eStart , y )\n"
"4: } ;\n";
TODO_ASSERT_EQUALS(expected, current, tokenize(code));
}
void varidenum6() { // #9180
const char code[] = "const int IDL1 = 13;\n"
"enum class E { IDL1 = 16, };\n";
const char expected[] = "1: const int IDL1@1 = 13 ;\n"
"2: enum class E { IDL1 = 16 , } ;\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void varidenum7() { // #8991
const char code[] = "namespace N1 { const int c = 42; }\n"
"namespace N2 { const int c = 24; }\n"
"struct S {\n"
" enum { v1 = N1::c, v2 = N2::c };\n"
"};\n";
const char expected[] = "1: namespace N1 { const int c@1 = 42 ; }\n"
"2: namespace N2 { const int c@2 = 24 ; }\n"
"3: struct S {\n"
"4: enum Anonymous0 { v1 = N1 :: c@1 , v2 = N2 :: c@2 } ;\n"
"5: } ;\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void varid_classnameshaddowsvariablename() {
const char code[] = "class Data;\n"
"void strange_declarated(const Data& Data);\n"
"void handleData(const Data& data) {\n"
" strange_declarated(data);\n"
"}\n";
const char expected[] = "1: class Data ;\n"
"2: void strange_declarated ( const Data & Data@1 ) ;\n"
"3: void handleData ( const Data & data@2 ) {\n"
"4: strange_declarated ( data@2 ) ;\n"
"5: }\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void varid_classnametemplate() {
const char code[] = "template \n"
"struct BBB {\n"
" struct inner;\n"
"};\n"
"\n"
"template \n"
"struct BBB::inner {\n"
" inner(int x);\n"
" int x;\n"
"};\n"
"\n"
"template \n"
"BBB::inner::inner(int x): x(x) {}\n";
const char expected[] = "1: template < typename T >\n"
"2: struct BBB {\n"
"3: struct inner ;\n"
"4: } ;\n"
"5:\n"
"6: template < typename T >\n"
"7: struct BBB < T > :: inner {\n"
"8: inner ( int x@1 ) ;\n"
"9: int x@2 ;\n"
"10: } ;\n"
"11:\n"
"12: template < typename T >\n"
"13: BBB < T > :: inner :: inner ( int x@3 ) : x@2 ( x@3 ) { }\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void varidnamespace1() {
const char code[] = "namespace A {\n"
" char buf[20];\n"
"}\n"
"int main() {\n"
" return foo(A::buf);\n"
"}";
const char expected[] = "1: namespace A {\n"
"2: char buf@1 [ 20 ] ;\n"
"3: }\n"
"4: int main ( ) {\n"
"5: return foo ( A :: buf@1 ) ;\n"
"6: }\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void varidnamespace2() {
const char code[] = "namespace A {\n"
" namespace B {\n"
" char buf[20];\n"
" }\n"
"}\n"
"int main() {\n"
" return foo(A::B::buf);\n"
"}";
const char expected[] = "1: namespace A {\n"
"2: namespace B {\n"
"3: char buf@1 [ 20 ] ;\n"
"4: }\n"
"5: }\n"
"6: int main ( ) {\n"
"7: return foo ( A :: B :: buf@1 ) ;\n"
"8: }\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void usingNamespace1() {
const char code[] = "namespace NS {\n"
" class A { int x; void dostuff(); };\n"
"}\n"
"using namespace NS;\n"
"void A::dostuff() { x = 0; }\n";
const char expected[] = "1: namespace NS {\n"
"2: class A { int x@1 ; void dostuff ( ) ; } ;\n"
"3: }\n"
"4: using namespace NS ;\n"
"5: void A :: dostuff ( ) { x@1 = 0 ; }\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void usingNamespace2() {
const char code[] = "class A { int x; void dostuff(); };\n"
"using namespace NS;\n"
"void A::dostuff() { x = 0; }\n";
const char expected[] = "1: class A { int x@1 ; void dostuff ( ) ; } ;\n"
"2: using namespace NS ;\n"
"3: void A :: dostuff ( ) { x@1 = 0 ; }\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void usingNamespace3() {
const char code[] = "namespace A {\n"
" namespace B {\n"
" class C {\n"
" double m;\n"
" C();\n"
" };\n"
" }\n"
"}\n"
"using namespace A::B;\n"
"C::C() : m(42) {}";
const char expected[] = "1: namespace A {\n"
"2: namespace B {\n"
"3: class C {\n"
"4: double m@1 ;\n"
"5: C ( ) ;\n"
"6: } ;\n"
"7: }\n"
"8: }\n"
"9: using namespace A :: B ;\n"
"10: C :: C ( ) : m@1 ( 42 ) { }\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void setVarIdStructMembers1() {
const char code[] = "void f(Foo foo)\n"
"{\n"
" foo.size = 0;\n"
" return ((uint8_t)(foo).size);\n"
"}";
const char expected[] = "1: void f ( Foo foo@1 )\n"
"2: {\n"
"3: foo@1 . size@2 = 0 ;\n"
"4: return ( ( uint8_t ) ( foo@1 ) . size@2 ) ;\n"
"5: }\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void decltype1() {
const char code[] = "void foo(int x, decltype(A::b) *p);";
const char expected[] = "1: void foo ( int x@1 , decltype ( A :: b ) * p@2 ) ;\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void decltype2() {
const char code[] = "int x; decltype(x) y;";
const char expected[] = "1: int x@1 ; decltype ( x@1 ) y@2 ;\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void typeof1() {
const char code[] = "int x; typeof(x) y;";
const char expected[] = "1: int x@1 ; typeof ( x@1 ) y@2 ;\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void typeof2() {
const char code[] = "int x; typeof(x) *y;";
const char expected[] = "1: int x@1 ; typeof ( x@1 ) * y@2 ;\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void typeof3() {
const char code[] = "int x; const typeof(x) *const y;";
const char expected[] = "1: int x@1 ; const typeof ( x@1 ) * const y@2 ;\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void typeof4() {
const char code[] = "int x; __typeof(x) y;";
const char expected[] = "1: int x@1 ; __typeof ( x@1 ) y@2 ;\n";
TokenizeOptions options;
options.cpp = false;
ASSERT_EQUALS(expected, tokenize(code, options));
}
void exprid1() {
const std::string actual = tokenizeExpr(
"struct A {\n"
" int x, y;\n"
"};\n"
"int f(A a, A b) {\n"
" int x = a.x + b.x;\n"
" int y = b.x + a.x;\n"
" return x + y + a.y + b.y;\n"
"}\n");
const char expected[] =
"1: struct A {\n"
"2: int x ; int y ;\n"
"3: } ;\n"
"4: int f ( A a , A b ) {\n"
"5: int x@5 ; x@5 =@UNIQUE a@3 .@11 x@6 +@13 b@4 .@12 x@7 ;\n"
"6: int y@8 ; y@8 =@UNIQUE b@4 .@12 x@7 +@13 a@3 .@11 x@6 ;\n"
"7: return x@5 +@UNIQUE y@8 +@UNIQUE a@3 .@UNIQUE y@9 +@UNIQUE b@4 .@UNIQUE y@10 ;\n"
"8: }\n";
ASSERT_EQUALS(expected, actual);
}
void exprid2() {
const std::string actual = tokenizeExpr( // #11739
"struct S { std::unique_ptr u; };\n"
"auto f = [](const S& s) -> std::unique_ptr {\n"
" if (auto p = s.u.get())\n"
" return std::make_unique(*p);\n"
" return nullptr;\n"
"};\n");
const char expected[] = "1: struct S { std :: unique_ptr < int > u ; } ;\n"
"2: auto f ; f = [ ] ( const S & s ) . std :: unique_ptr < int > {\n"
"3: if ( auto p@4 =@UNIQUE s@3 .@UNIQUE u@5 .@UNIQUE get (@UNIQUE ) ) {\n"
"4: return std ::@UNIQUE make_unique < int > (@UNIQUE *@UNIQUE p@4 ) ; }\n"
"5: return nullptr ;\n"
"6: } ;\n";
ASSERT_EQUALS(expected, actual);
}
void exprid3() {
const char code[] = "void f(bool b, int y) {\n"
" if (b && y > 0) {}\n"
" while (b && y > 0) {}\n"
"}\n";
const char expected[] = "1: void f ( bool b , int y ) {\n"
"2: if ( b@1 &&@5 y@2 >@4 0 ) { }\n"
"3: while ( b@1 &&@5 y@2 >@4 0 ) { }\n"
"4: }\n";
ASSERT_EQUALS(expected, tokenizeExpr(code));
}
void exprid4() {
// expanded macro..
const char code[] = "#define ADD(x,y) x+y\n"
"int f(int a, int b) {\n"
" return ADD(a,b) + ADD(a,b);\n"
"}\n";
const char expected[] = "2: int f ( int a , int b ) {\n"
"3: return a@1 $+@UNIQUE b@2 +@UNIQUE a@1 $+@UNIQUE b@2 ;\n"
"4: }\n";
ASSERT_EQUALS(expected, tokenizeExpr(code));
}
void exprid5() {
// references..
const char code[] = "int foo(int a) {\n"
" int& r = a;\n"
" return (a+a)*(r+r);\n"
"}\n";
const char expected[] = "1: int foo ( int a ) {\n"
"2: int & r@2 =@UNIQUE a@1 ;\n"
"3: return ( a@1 +@4 a@1 ) *@UNIQUE ( r@2 +@4 r@2 ) ;\n"
"4: }\n";
ASSERT_EQUALS(expected, tokenizeExpr(code));
}
void exprid6() {
// ++ and -- should have UNIQUE exprid
const char code[] = "void foo(int *a) {\n"
" *a++ = 0;\n"
" if (*a++ == 32) {}\n"
"}\n";
const char expected[] = "1: void foo ( int * a ) {\n"
"2: *@UNIQUE a@1 ++@UNIQUE = 0 ;\n"
"3: if ( *@UNIQUE a@1 ++@UNIQUE ==@UNIQUE 32 ) { }\n"
"4: }\n";
ASSERT_EQUALS(expected, tokenizeExpr(code));
}
void exprid7() {
// different casts
const char code[] = "void foo(int a) {\n"
" if ((char)a == (short)a) {}\n"
" if ((char)a == (short)a) {}\n"
"}\n";
const char expected[] = "1: void foo ( int a ) {\n"
"2: if ( (@2 char ) a@1 ==@4 (@3 short ) a@1 ) { }\n"
"3: if ( (@2 char ) a@1 ==@4 (@3 short ) a@1 ) { }\n"
"4: }\n";
ASSERT_EQUALS(expected, tokenizeExpr(code));
}
void exprid8() {
const char code[] = "void f() {\n" // #12249
" std::string s;\n"
" (((s += \"--\") += std::string()) += \"=\");\n"
"}\n";
const char expected[] = "1: void f ( ) {\n"
"2: std ::@UNIQUE string s@1 ;\n"
"3: ( ( s@1 +=@UNIQUE \"--\"@UNIQUE ) +=@UNIQUE std ::@UNIQUE string (@UNIQUE ) ) +=@UNIQUE \"=\"@UNIQUE ;\n"
"4: }\n";
ASSERT_EQUALS(expected, tokenizeExpr(code));
const char code2[] = "struct S { std::function* p; };\n"
"S f() { return S{ std::make_unique>([]() {}).release()}; }";
const char expected2[] = "1: struct S { std :: function < void ( ) > * p ; } ;\n"
"2: S f ( ) { return S@UNIQUE {@UNIQUE std ::@UNIQUE make_unique < std :: function < void ( ) > > (@UNIQUE [ ] ( ) { } ) .@UNIQUE release (@UNIQUE ) } ; }\n";
ASSERT_EQUALS(expected2, tokenizeExpr(code2));
const char code3[] = "struct S { int* p; };\n"
"S f() { return S{ std::make_unique([]() { return 4; }()).release()}; }\n";
const char expected3[] = "1: struct S { int * p ; } ;\n"
"2: S f ( ) { return S@UNIQUE {@UNIQUE std ::@UNIQUE make_unique < int > (@UNIQUE [ ] ( ) { return 4 ; } ( ) ) .@UNIQUE release (@UNIQUE ) } ; }\n";
ASSERT_EQUALS(expected3, tokenizeExpr(code3));
const char code4[] = "std::unique_ptr g(int i) { return std::make_unique(i); }\n"
"void h(int*);\n"
"void f() {\n"
" h(g({}).get());\n"
"}\n";
const char expected4[] = "1: std :: unique_ptr < int > g ( int i ) { return std ::@UNIQUE make_unique < int > (@UNIQUE i@1 ) ; }\n"
"2: void h ( int * ) ;\n"
"3: void f ( ) {\n"
"4: h (@UNIQUE g (@UNIQUE { } ) .@UNIQUE get (@UNIQUE ) ) ;\n"
"5: }\n";
ASSERT_EQUALS(expected4, tokenizeExpr(code4));
const char code5[] = "int* g(std::map>& m) {\n"
" return m[{0}].get();\n"
"}\n";
const char expected5[] = "1: int * g ( std :: map < int , std :: unique_ptr < int > > & m ) {\n"
"2: return m@1 [@UNIQUE { 0 } ] .@UNIQUE get (@UNIQUE ) ;\n"
"3: }\n";
ASSERT_EQUALS(expected5, tokenizeExpr(code5));
}
void exprid9()
{
const char code[] = "void f(const std::type_info& type) {\n" // #12340
" if (type == typeid(unsigned int)) {}\n"
" else if (type == typeid(int)) {}\n"
"}\n";
const char expected[] = "1: void f ( const std :: type_info & type ) {\n"
"2: if ( type@1 ==@UNIQUE typeid (@UNIQUE unsigned int@UNIQUE ) ) { }\n"
"3: else { if ( type@1 ==@UNIQUE typeid (@UNIQUE int@UNIQUE ) ) { } }\n"
"4: }\n";
ASSERT_EQUALS(expected, tokenizeExpr(code));
}
void exprid10()
{
const char code[] = "void f(const std::string& p) {\n" // #12350
" std::string s;\n"
" ((s = \"abc\") += p) += \"def\";\n"
"}\n";
const char expected[] = "1: void f ( const std :: string & p ) {\n"
"2: std ::@UNIQUE string s@2 ;\n"
"3: ( ( s@2 =@UNIQUE \"abc\" ) +=@UNIQUE p@1 ) +=@UNIQUE \"def\"@UNIQUE ;\n"
"4: }\n";
ASSERT_EQUALS(expected, tokenizeExpr(code));
}
void exprid11()
{
const char code[] = "struct S { void f(); };\n" // #12713
"int g(int, S*);\n"
"int h(void (*)(), S*);\n"
"void S::f() {\n"
" std::make_unique(g({}, this)).release();\n"
" std::make_unique(h([]() {}, this)).release();\n"
"}\n";
const char* exp = "1: struct S { void f ( ) ; } ;\n"
"2: int g ( int , S * ) ;\n"
"3: int h ( void ( * ) ( ) , S * ) ;\n"
"4: void S :: f ( ) {\n"
"5: std ::@UNIQUE make_unique < int > (@UNIQUE g (@UNIQUE { } ,@6 this ) ) .@UNIQUE release (@UNIQUE ) ;\n"
"6: std ::@UNIQUE make_unique < int > (@UNIQUE h (@UNIQUE [ ] ( ) { } ,@6 this ) ) .@UNIQUE release (@UNIQUE ) ;\n"
"7: }\n";
ASSERT_EQUALS(exp, tokenizeExpr(code));
}
void exprid12()
{
const char code[] = "struct S { std::unique_ptr p; };\n" // #12765
"namespace N {\n"
" struct T { void (*f)(S*); };\n"
" const T t = {\n"
" [](S* s) { s->p.release(); }\n"
" };\n"
"}\n";
const char* exp = "1: struct S { std :: unique_ptr < int > p ; } ;\n"
"2: namespace N {\n"
"3: struct T { void ( * f@2 ) ( S * ) ; } ;\n"
"4: const T t@3 = {\n"
"5: [ ] ( S * s@4 ) { s@4 .@UNIQUE p@5 .@UNIQUE release (@UNIQUE ) ; }\n"
"6: } ;\n"
"7: }\n";
ASSERT_EQUALS(exp, tokenizeExpr(code));
}
void exprid13()
{
const char code[] = "struct S { int s; };\n" // #11488
"struct T { struct S s; };\n"
"struct U { struct T t; };\n"
"void f() {\n"
" struct U u = { .t = { .s = { .s = 1 } } };\n"
"}\n";
const char* exp = "1: struct S { int s ; } ;\n"
"2: struct T { struct S s ; } ;\n"
"3: struct U { struct T t ; } ;\n"
"4: void f ( ) {\n"
"5: struct U u@4 ; u@4 = { .@UNIQUE t@5 = { .@UNIQUE s@6 = { .@UNIQUE s@7 = 1 } } } ;\n"
"6: }\n";
ASSERT_EQUALS(exp, tokenizeExpr(code));
}
void exprid14()
{
const Settings s = settingsBuilder(settings).library("std.cfg").build();
const char code[] = "int f(double a, double b, double c) {\n" // #13578
" return static_cast(std::ceil((std::min)(a, (std::min)(b, c))));\n"
"}\n";
const char* exp = "1: int f ( double a@1 , double b@2 , double c@3 ) {\n"
"2: return static_cast < int > ( std :: ceil ( std :: min ( a@1 , std :: min ( b@2 , c@3 ) ) ) ) ;\n"
"3: }\n";
ASSERT_EQUALS(exp, tokenize(code, s)); // don't crash
}
void exprid15()
{
// #14717
const char code[] = "#define MAX(a, b) (((a) > (b)) ? (a) : (b))\n"
"\n"
"void f(char *d) {\n"
" const char *p = &d[0];\n"
" int a = 1 / MAX(1, p[0]);\n"
" a = 1 / MAX(1, p[1]);\n"
"}\n";
const char exp[] = "3: void f ( char * d ) {\n"
"4: const char * p@2 ; p@2 =@UNIQUE &@UNIQUE d@1 [@UNIQUE 0 ] ;\n"
"5: int a@3 ; a@3 =@UNIQUE 1 /@UNIQUE $( $( 1 $>@UNIQUE $( p@2 [@9 0 ] $) $) $?@UNIQUE $( 1 $) $:@UNIQUE $( p@2 [@9 0 ] $) $) ;\n"
"6: a@3 =@UNIQUE 1 /@UNIQUE $( $( 1 $>@UNIQUE $( p@2 [@15 1 ] $) $) $?@UNIQUE $( 1 $) $:@UNIQUE $( p@2 [@15 1 ] $) $) ;\n"
"7: }\n";
ASSERT_EQUALS(exp, tokenizeExpr(code));
}
void structuredBindings() {
const char code[] = "int foo() { auto [x,y] = xy(); return x+y; }";
ASSERT_EQUALS("1: int foo ( ) { auto [ x@1 , y@2 ] = xy ( ) ; return x@1 + y@2 ; }\n",
tokenize(code));
}
};
REGISTER_TEST(TestVarID)