/*
* Cppcheck - A tool for static C/C++ code analysis
* Copyright (C) 2007-2015 Daniel Marjamki and Cppcheck team.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include "testsuite.h"
#include "tokenize.h"
#include "token.h"
#include "settings.h"
#include
extern std::ostringstream errout;
class TestVarID : public TestFixture {
public:
TestVarID() : TestFixture("TestVarID") {
}
private:
void run() {
TEST_CASE(varid1);
TEST_CASE(varid2);
TEST_CASE(varid3);
TEST_CASE(varid4);
TEST_CASE(varid5);
TEST_CASE(varid6);
TEST_CASE(varid7);
TEST_CASE(varidReturn1);
TEST_CASE(varidReturn2);
TEST_CASE(varid8);
TEST_CASE(varid9);
TEST_CASE(varid10);
TEST_CASE(varid11);
TEST_CASE(varid12);
TEST_CASE(varid13);
TEST_CASE(varid14);
TEST_CASE(varid15);
TEST_CASE(varid16);
TEST_CASE(varid17); // ticket #1810
TEST_CASE(varid18);
TEST_CASE(varid19);
TEST_CASE(varid20);
TEST_CASE(varid24);
TEST_CASE(varid25);
TEST_CASE(varid26); // ticket #1967 (list of function pointers)
TEST_CASE(varid27); // Ticket #2280 (same name for namespace and variable)
TEST_CASE(varid28); // ticket #2630
TEST_CASE(varid29); // ticket #1974
TEST_CASE(varid30); // ticket #2614
TEST_CASE(varid31); // ticket #2831 (segmentation fault)
TEST_CASE(varid32); // ticket #2835 (segmentation fault)
TEST_CASE(varid33); // ticket #2875 (segmentation fault)
TEST_CASE(varid34); // ticket #2825
TEST_CASE(varid35); // ticket #2937
TEST_CASE(varid36); // ticket #2980 (segmentation fault)
TEST_CASE(varid37); // ticket #3092 (varid for 'Bar bar(*this);')
TEST_CASE(varid38); // ticket #3272 (varid for 'FOO class C;')
TEST_CASE(varid39); // ticket #3279 (varid for 'FOO::BAR const')
TEST_CASE(varid40); // ticket #3279
TEST_CASE(varid41); // ticket #3340 (varid for union type)
TEST_CASE(varid42); // ticket #3316 (varid for array)
TEST_CASE(varid43);
TEST_CASE(varid44);
TEST_CASE(varid45); // #3466
TEST_CASE(varid46); // struct varname
TEST_CASE(varid47); // function parameters
TEST_CASE(varid48); // #3785 - return (a*b)
TEST_CASE(varid49); // #3799 - void f(std::vector)
TEST_CASE(varid50); // #3760 - explicit
TEST_CASE(varid51); // don't set varid for template function
TEST_CASE(varid52); // Set varid for nested templates
TEST_CASE(varid53); // #4172 - Template instantiation: T list[4];
TEST_CASE(varid54); // hang
TEST_CASE(varid55); // #5868: Function::addArgument with varid 0 for argument named the same as a typedef
TEST_CASE(varid_cpp_keywords_in_c_code);
TEST_CASE(varid_cpp_keywords_in_c_code2); // #5373: varid=0 for argument called "delete"
TEST_CASE(varidFunctionCall1);
TEST_CASE(varidFunctionCall2);
TEST_CASE(varidFunctionCall3);
TEST_CASE(varidFunctionCall4); // ticket #3280
TEST_CASE(varidStl);
TEST_CASE(varid_newauto); // not declaration: new const auto(0);
TEST_CASE(varid_delete);
TEST_CASE(varid_functions);
TEST_CASE(varid_sizeof);
TEST_CASE(varid_reference_to_containers);
TEST_CASE(varid_in_class1);
TEST_CASE(varid_in_class2);
TEST_CASE(varid_in_class3); // #3092 - shadow variable in member function
TEST_CASE(varid_in_class4); // #3271 - public: class C;
TEST_CASE(varid_in_class5); // #3584 - std::vector b;
TEST_CASE(varid_in_class6); // #3755
TEST_CASE(varid_in_class7); // set variable id for struct members
TEST_CASE(varid_in_class8); // unknown macro in class
TEST_CASE(varid_in_class9); // #4291 - id for variables accessed through 'this'
TEST_CASE(varid_in_class10);
TEST_CASE(varid_in_class11); // #4277 - anonymous union
TEST_CASE(varid_in_class12); // #4637 - method
TEST_CASE(varid_in_class13); // #4637 - method
TEST_CASE(varid_in_class14);
TEST_CASE(varid_in_class15); // #5533 - functions
TEST_CASE(varid_in_class16);
TEST_CASE(varid_in_class17); // #6056 - no varid for member functions
TEST_CASE(varid_initList);
TEST_CASE(varid_operator);
TEST_CASE(varid_throw);
TEST_CASE(varid_unknown_macro); // #2638 - unknown macro is not type
TEST_CASE(varid_using); // ticket #3648
TEST_CASE(varid_catch);
TEST_CASE(varid_functionPrototypeTemplate);
TEST_CASE(varid_templatePtr); // #4319
TEST_CASE(varid_templateNamespaceFuncPtr); // #4172
TEST_CASE(varid_templateArray);
TEST_CASE(varid_cppcast); // #6190
TEST_CASE(varid_variadicFunc);
TEST_CASE(varid_typename); // #4644
TEST_CASE(varid_rvalueref);
TEST_CASE(varid_arrayFuncPar); // #5294
TEST_CASE(varid_sizeofPassed); // #5295
TEST_CASE(varid_classInFunction); // #5293
TEST_CASE(varid_pointerToArray); // #2645
TEST_CASE(varid_cpp11initialization); // #4344
TEST_CASE(varid_inheritedMembers); // #4101
TEST_CASE(varid_header); // #6386
TEST_CASE(varidclass1);
TEST_CASE(varidclass2);
TEST_CASE(varidclass3);
TEST_CASE(varidclass4);
TEST_CASE(varidclass5);
TEST_CASE(varidclass6);
TEST_CASE(varidclass7);
TEST_CASE(varidclass8);
TEST_CASE(varidclass9);
TEST_CASE(varidclass10); // variable declaration below usage
TEST_CASE(varidclass11); // variable declaration below usage
TEST_CASE(varidclass12);
TEST_CASE(varidclass13);
TEST_CASE(varidclass14);
TEST_CASE(varidclass15); // initializer list
TEST_CASE(varidclass16); // #4577
TEST_CASE(varidclass17); // #6073
TEST_CASE(varid_classnameshaddowsvariablename); // #3990
TEST_CASE(varidnamespace1);
}
std::string tokenize(const char code[], bool simplify = false, const char filename[] = "test.cpp") {
errout.str("");
Settings settings;
settings.standards.c = Standards::C89;
settings.standards.cpp = Standards::CPP11;
Tokenizer tokenizer(&settings, this);
std::istringstream istr(code);
tokenizer.tokenize(istr, filename);
if (simplify)
tokenizer.simplifyTokenList2();
// result..
return tokenizer.tokens()->stringifyList(true);
}
void varid1() {
{
const std::string actual = tokenize(
"static int i = 1;\n"
"void f()\n"
"{\n"
" int i = 2;\n"
" for (int i = 0; i < 10; ++i)\n"
" i = 3;\n"
" i = 4;\n"
"}\n", false, "test.c");
const std::string expected("\n\n##file 0\n"
"1: static int i@1 = 1 ;\n"
"2: void f ( )\n"
"3: {\n"
"4: int i@2 ; i@2 = 2 ;\n"
"5: for ( int i@3 = 0 ; i@3 < 10 ; ++ i@3 ) {\n"
"6: i@3 = 3 ; }\n"
"7: i@2 = 4 ;\n"
"8: }\n");
ASSERT_EQUALS(expected, actual);
}
{
const std::string actual = tokenize(
"static int i = 1;\n"
"void f()\n"
"{\n"
" int i = 2;\n"
" for (int i = 0; i < 10; ++i)\n"
" {\n"
" i = 3;\n"
" }\n"
" i = 4;\n"
"}\n", false, "test.c");
const std::string expected("\n\n##file 0\n"
"1: static int i@1 = 1 ;\n"
"2: void f ( )\n"
"3: {\n"
"4: int i@2 ; i@2 = 2 ;\n"
"5: for ( int i@3 = 0 ; i@3 < 10 ; ++ i@3 )\n"
"6: {\n"
"7: i@3 = 3 ;\n"
"8: }\n"
"9: i@2 = 4 ;\n"
"10: }\n");
ASSERT_EQUALS(expected, actual);
}
}
void varid2() {
const std::string actual = tokenize(
"void f()\n"
"{\n"
" struct ABC abc;\n"
" abc.a = 3;\n"
" i = abc.a;\n"
"}\n", false, "test.c");
const std::string expected("\n\n##file 0\n"
"1: void f ( )\n"
"2: {\n"
"3: struct ABC abc@1 ;\n"
"4: abc@1 . a@2 = 3 ;\n"
"5: i = abc@1 . a@2 ;\n"
"6: }\n");
ASSERT_EQUALS(expected, actual);
}
void varid3() {
const std::string actual = tokenize(
"static char str[4];\n"
"void f()\n"
"{\n"
" char str[10];\n"
" str[0] = 0;\n"
"}\n", false, "test.c");
const std::string expected("\n\n##file 0\n"
"1: static char str@1 [ 4 ] ;\n"
"2: void f ( )\n"
"3: {\n"
"4: char str@2 [ 10 ] ;\n"
"5: str@2 [ 0 ] = 0 ;\n"
"6: }\n");
ASSERT_EQUALS(expected, actual);
}
void varid4() {
const std::string actual = tokenize(
"void f(const unsigned int a[])\n"
"{\n"
" int i = *(a+10);\n"
"}\n", false, "test.c");
const std::string expected("\n\n##file 0\n"
"1: void f ( const int a@1 [ ] )\n"
"2: {\n"
"3: int i@2 ; i@2 = * ( a@1 + 10 ) ;\n"
"4: }\n");
ASSERT_EQUALS(expected, actual);
}
void varid5() {
const std::string actual = tokenize(
"void f()\n"
"{\n"
" int a,b;\n"
"}\n", false, "test.c");
const std::string expected("\n\n##file 0\n"
"1: void f ( )\n"
"2: {\n"
"3: int a@1 ; int b@2 ;\n"
"4: }\n");
ASSERT_EQUALS(expected, actual);
}
void varid6() {
const std::string actual = tokenize(
"int f(int a, int b)\n"
"{\n"
" return a+b;\n"
"}\n", false, "test.c");
const std::string expected("\n\n##file 0\n"
"1: int f ( int a@1 , int b@2 )\n"
"2: {\n"
"3: return a@1 + b@2 ;\n"
"4: }\n");
ASSERT_EQUALS(expected, actual);
}
void varid7() {
const std::string actual = tokenize(
"void func() {\n"
" char a[256] = \"test\";\n"
" {\n"
" char b[256] = \"test\";\n"
" }\n"
"}\n", false, "test.c");
const std::string expected("\n\n##file 0\n"
"1: void func ( ) {\n"
"2: char a@1 [ 256 ] = \"test\" ;\n"
"3: {\n"
"4: char b@2 [ 256 ] = \"test\" ;\n"
"5: }\n"
"6: }\n");
ASSERT_EQUALS(expected, actual);
}
void varidReturn1() {
const std::string actual = tokenize(
"int f()\n"
"{\n"
" int a;\n"
" return a;\n"
"}\n", false, "test.c");
const std::string expected("\n\n##file 0\n"
"1: int f ( )\n"
"2: {\n"
"3: int a@1 ;\n"
"4: return a@1 ;\n"
"5: }\n");
ASSERT_EQUALS(expected, actual);
}
void varidReturn2() {
const std::string actual = tokenize(
"void foo()\n"
"{\n"
" unsigned long mask = (1UL x@1 ;\n"
"4: }\n");
ASSERT_EQUALS(expected, tokenize(code));
}
void varid20() {
const char code[] ="void foo()\n"
"{\n"
" pair x;\n"
"}\n";
const std::string expected("\n\n##file 0\n"
"1: void foo ( )\n"
"2: {\n"
"3: pair < vector < int > , vector < double > > x@1 ;\n"
"4: }\n");
ASSERT_EQUALS(expected, tokenize(code));
}
void varid24() {
const char code[] ="class foo()\n"
"{\n"
"public:\n"
" ;\n"
"private:\n"
" static int i;\n"
"};\n";
const std::string expected("\n\n##file 0\n"
"1: class foo ( )\n"
"2: {\n"
"3: public:\n"
"4: ;\n"
"5: private:\n"
"6: static int i@1 ;\n"
"7: } ;\n");
ASSERT_EQUALS(expected, tokenize(code));
}
void varid25() {
const char code[] ="class foo()\n"
"{\n"
"public:\n"
" ;\n"
"private:\n"
" mutable int i;\n"
"};\n";
const std::string expected("\n\n##file 0\n"
"1: class foo ( )\n"
"2: {\n"
"3: public:\n"
"4: ;\n"
"5: private:\n"
"6: mutable int i@1 ;\n"
"7: } ;\n");
ASSERT_EQUALS(expected, tokenize(code));
}
void varid26() {
const char code[] ="list functions;\n";
const std::string expected("\n\n##file 0\n"
"1: list < int ( * ) ( ) > functions@1 ;\n");
ASSERT_EQUALS(expected, tokenize(code));
}
void varid27() {
const char code[] ="int fooled_ya;\n"
"fooled_ya::iterator iter;\n";
const std::string expected("\n\n##file 0\n"
"1: int fooled_ya@1 ;\n"
"2: fooled_ya :: iterator iter@2 ;\n");
ASSERT_EQUALS(expected, tokenize(code));
}
void varid28() { // ticket #2630 (segmentation fault)
tokenize("template \n");
ASSERT_EQUALS("", errout.str());
}
void varid29() {
const char code[] ="class A {\n"
" B b;\n"
"};\n";
const std::string expected("\n\n##file 0\n"
"1: class A {\n"
"2: B < C < 1 > , 1 > b@1 ;\n"
"3: } ;\n");
ASSERT_EQUALS(expected, tokenize(code));
}
void varid30() { // ticket #2614
const char code1[] = "void f(EventPtr *eventP, ActionPtr **actionsP)\n"
"{\n"
" EventPtr event = *eventP;\n"
" *actionsP = &event->actions;\n"
"}\n";
const std::string expected1("\n\n##file 0\n"
"1: void f ( EventPtr * eventP@1 , ActionPtr * * actionsP@2 )\n"
"2: {\n"
"3: EventPtr event@3 ; event@3 = * eventP@1 ;\n"
"4: * actionsP@2 = & event@3 . actions@4 ;\n"
"5: }\n");
ASSERT_EQUALS(expected1, tokenize(code1, false, "test.c"));
const char code2[] = "void f(int b, int c) {\n"
" x(a*b*c,10);\n"
"}\n";
const std::string expected2("\n\n##file 0\n"
"1: void f ( int b@1 , int c@2 ) {\n"
"2: x ( a * b@1 * c@2 , 10 ) ;\n"
"3: }\n");
ASSERT_EQUALS(expected2, tokenize(code2, false, "test.c"));
const char code3[] = "class Nullpointer : public ExecutionPath\n"
" {\n"
" Nullpointer(Check *c, const unsigned int id, const std::string &name)\n"
" : ExecutionPath(c, id)\n"
" {\n"
" }\n"
"}\n";
const std::string expected3("\n\n##file 0\n"
"1: class Nullpointer : public ExecutionPath\n"
"2: {\n"
"3: Nullpointer ( Check * c@1 , const int id@2 , const std :: string & name@3 )\n"
"4: : ExecutionPath ( c@1 , id@2 )\n"
"5: {\n"
"6: }\n"
"7: }\n");
ASSERT_EQUALS(expected3, tokenize(code3));
}
void varid31() { // ticket #2831 (segmentation fault)
const char code[] ="z b[10];\n"
"B c[10];";
ASSERT_EQUALS("\n\n##file 0\n"
"1: A < B < C > :: D > e@1 ;\n"
"2: B < C < > > b@2 [ 10 ] ;\n"
"3: B < C < > > c@3 [ 10 ] ;\n",
tokenize(code, false, "test.cpp"));
}
void varid53() { // #4172 - Template instantiation: T list[4];
ASSERT_EQUALS("\n\n##file 0\n"
"1: A < & f > list@1 [ 4 ] ;\n",
tokenize("A list[4];", false, "test.cpp"));
}
void varid54() { // hang
// Original source code: libgc
tokenize("STATIC ptr_t GC_approx_sp(void) { word sp; sp = (word)&sp; return((ptr_t)sp); }",true);
}
void varid55() { // Ticket #5868
const char code[] = "typedef struct foo {} foo; "
"void bar1(struct foo foo) {} "
"void baz1(foo foo) {} "
"void bar2(struct foo& foo) {} "
"void baz2(foo& foo) {} "
"void bar3(struct foo* foo) {} "
"void baz3(foo* foo) {}";
const char expected[] = "\n\n##file 0\n1: struct foo { } ; "
"void bar1 ( struct foo foo@1 ) { } "
"void baz1 ( struct foo foo@2 ) { } "
"void bar2 ( struct foo & foo@3 ) { } "
"void baz2 ( struct foo & foo@4 ) { } "
"void bar3 ( struct foo * foo@5 ) { } "
"void baz3 ( struct foo * foo@6 ) { }\n";
ASSERT_EQUALS(expected, tokenize(code, false, "test.cpp"));
}
void varid_cpp_keywords_in_c_code() {
const char code[] = "void f() {\n"
" delete d;\n"
" throw t;\n"
"}";
const char expected[] = "\n\n##file 0\n"
"1: void f ( ) {\n"
"2: delete d@1 ;\n"
"3: throw t@2 ;\n"
"4: }\n";
ASSERT_EQUALS(expected, tokenize(code,false,"test.c"));
}
void varid_cpp_keywords_in_c_code2() { // #5373
const char code[] = "int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, "
"unsigned long bits, int wake, int delete, struct extent_state **cached_state, "
"gfp_t mask) {\n"
" struct extent_state *state;\n"
"}"
"int clear_extent_dirty() {\n"
" return clear_extent_bit(tree, start, end, EXTENT_DIRTY | EXTENT_DELALLOC | "
" EXTENT_DO_ACCOUNTING, 0, 0, NULL, mask);\n"
"}";
tokenize(code, false, "test.c");
}
void varidFunctionCall1() {
const char code[] ="void f() {\n"
" int x;\n"
" x = a(y*x,10);\n"
"}";
const std::string expected("\n\n##file 0\n"
"1: void f ( ) {\n"
"2: int x@1 ;\n"
"3: x@1 = a ( y * x@1 , 10 ) ;\n"
"4: }\n");
ASSERT_EQUALS(expected, tokenize(code, false, "test.c"));
}
void varidFunctionCall2() {
// #2491
const char code[] ="void f(int b) {\n"
" x(a*b,10);\n"
"}";
const std::string expected1("\n\n##file 0\n"
"1: void f ( int b@1 ) {\n"
"2: x ( a * b");
const std::string expected2(" , 10 ) ;\n"
"3: }\n");
ASSERT_EQUALS(expected1+"@1"+expected2, tokenize(code,false,"test.c"));
}
void varidFunctionCall3() {
// Ticket #2339
const char code[] ="void f() {\n"
" int a = 0;\n"
" int b = c - (foo::bar * a);\n"
"}";
const std::string expected("\n\n##file 0\n"
"1: void f ( ) {\n"
"2: int a@1 ; a@1 = 0 ;\n"
"3: int b@2 ; b@2 = c - ( foo :: bar * a@1 ) ;\n"
"4: }\n");
ASSERT_EQUALS(expected, tokenize(code));
}
void varidFunctionCall4() {
// Ticket #3280
const char code1[] = "void f() { int x; fun(a,b*x); }";
ASSERT_EQUALS("\n\n##file 0\n"
"1: void f ( ) { int x@1 ; fun ( a , b * x@1 ) ; }\n",
tokenize(code1, false, "test.c"));
const char code2[] = "void f(int a) { int x; fun(a,b*x); }";
ASSERT_EQUALS("\n\n##file 0\n"
"1: void f ( int a@1 ) { int x@2 ; fun ( a@1 , b * x@2 ) ; }\n",
tokenize(code2, false, "test.c"));
}
void varidStl() {
const std::string actual = tokenize(
"list ints;\n"
"list::iterator it;\n"
"std::vector dirs;\n"
"std::map coords;\n"
"std::tr1::unordered_map xy;\n"
"std::list tokens;\n"
"static std::vector ex1;\n"
"extern std::vector ex2;\n"
"std::map m;\n"
);
const std::string expected("\n\n##file 0\n"
"1: list < int > ints@1 ;\n"
"2: list < int > :: iterator it@2 ;\n"
"3: std :: vector < std :: string > dirs@3 ;\n"
"4: std :: map < int , int > coords@4 ;\n"
"5: std :: unordered_map < int , int > xy@5 ;\n"
"6: std :: list < boost :: wave :: token_id > tokens@6 ;\n"
"7: static std :: vector < CvsProcess * > ex1@7 ;\n"
"8: extern std :: vector < CvsProcess * > ex2@8 ;\n"
"9: std :: map < int , 1 > m@9 ;\n"
);
ASSERT_EQUALS(expected, actual);
}
void varid_newauto() {
ASSERT_EQUALS("\n\n##file 0\n"
"1: void f ( ) { const new auto ( 0 ) ; }\n",
tokenize("void f(){new const auto(0);}"));
}
void varid_delete() {
const std::string actual = tokenize(
"void f()\n"
"{\n"
" int *a;\n"
" delete a;\n"
"}\n");
const std::string expected("\n\n##file 0\n"
"1: void f ( )\n"
"2: {\n"
"3: int * a@1 ;\n"
"4: delete a@1 ;\n"
"5: }\n");
ASSERT_EQUALS(expected, actual);
}
void varid_functions() {
{
const std::string actual = tokenize(
"void f();\n"
"void f(){}\n", false, "test.c");
const std::string expected("\n\n##file 0\n"
"1: void f ( ) ;\n"
"2: void f ( ) { }\n");
ASSERT_EQUALS(expected, actual);
}
{
const std::string actual = tokenize(
"A f(3);\n"
"A f2(true);\n"
"A g();\n"
"A e(int c);\n", false, "test.c");
const std::string expected("\n\n##file 0\n"
"1: A f@1 ( 3 ) ;\n"
"2: A f2@2 ( true ) ;\n"
"3: A g ( ) ;\n"
"4: A e ( int c@3 ) ;\n");
ASSERT_EQUALS(expected, actual);
}
{
const std::string actual = tokenize(
"void f1(int &p)\n"
"{\n"
" p = 0;\n"
"}\n"
"void f2(std::string &str)\n"
"{\n"
" str.clear();\n"
"}\n"
"void f3(const std::string &s)\n"
"{\n"
" s.size();\n"
"}\n");
const std::string expected("\n\n##file 0\n"
"1: void f1 ( int & p@1 )\n"
"2: {\n"
"3: p@1 = 0 ;\n"
"4: }\n"
"5: void f2 ( std :: string & str@2 )\n"
"6: {\n"
"7: str@2 . clear ( ) ;\n"
"8: }\n"
"9: void f3 ( const std :: string & s@3 )\n"
"10: {\n"
"11: s@3 . size ( ) ;\n"
"12: }\n");
ASSERT_EQUALS(expected, actual);
}
{
const std::string actual = tokenize("void f(struct foobar);", false, "test.c");
const std::string expected("\n\n##file 0\n"
"1: void f ( struct foobar ) ;\n");
ASSERT_EQUALS(expected, actual);
}
{
const std::string actual = tokenize("bool f(X x, int=3);", false, "test.cpp");
const std::string expected("\n\n##file 0\n"
"1: bool f ( X x@1 , int = 3 ) ;\n");
ASSERT_EQUALS(expected, actual);
}
}
void varid_sizeof() {
const char code[] = "x = sizeof(a*b);";
const char expected[] = "\n\n##file 0\n"
"1: x = sizeof ( a * b ) ;\n";
ASSERT_EQUALS(expected, tokenize(code,false,"test.c"));
}
void varid_reference_to_containers() {
const std::string actual = tokenize(
"void f()\n"
"{\n"
" std::vector b;\n"
" std::vector &a = b;\n"
" std::vector *c = &b;\n"
"}\n");
const std::string expected("\n\n##file 0\n"
"1: void f ( )\n"
"2: {\n"
"3: std :: vector < int > b@1 ;\n"
"4: std :: vector < int > & a@2 = b@1 ;\n"
"5: std :: vector < int > * c@3 ; c@3 = & b@1 ;\n"
"6: }\n");
ASSERT_EQUALS(expected, actual);
}
void varid_in_class1() {
{
const std::string actual = tokenize(
"class Foo\n"
"{\n"
"public:\n"
" std::string name1;\n"
" std::string name2;\n"
"};\n");
const std::string expected("\n\n##file 0\n"
"1: class Foo\n"
"2: {\n"
"3: public:\n"
"4: std :: string name1@1 ;\n"
"5: std :: string name2@2 ;\n"
"6: } ;\n");
ASSERT_EQUALS(expected, actual);
}
{
const std::string actual = tokenize(
"class foo\n"
"{\n"
"public:\n"
" void do_something(const int x, const int y);\n"
" void bar();\n"
"};\n"
"\n"
"void foo::bar()\n"
"{\n"
" POINT pOutput = { 0 , 0 };\n"
" int x = pOutput.x;\n"
" int y = pOutput.y;\n"
"}\n");
const std::string expected("\n\n##file 0\n"
"1: class foo\n"
"2: {\n"
"3: public:\n"
"4: void do_something ( const int x@1 , const int y@2 ) ;\n"
"5: void bar ( ) ;\n"
"6: } ;\n"
"7:\n"
"8: void foo :: bar ( )\n"
"9: {\n"
"10: POINT pOutput@3 ; pOutput@3 = { 0 , 0 } ;\n"
"11: int x@4 ; x@4 = pOutput@3 . x@5 ;\n"
"12: int y@6 ; y@6 = pOutput@3 . y@7 ;\n"
"13: }\n");
ASSERT_EQUALS(expected, actual);
}
}
void varid_in_class2() {
const std::string actual = tokenize(
"struct Foo {\n"
" int x;\n"
"};\n"
"\n"
"struct Bar {\n"
" Foo foo;\n"
" int x;\n"
" void f();\n"
"};\n"
"\n"
"void Bar::f()\n"
"{\n"
" foo.x = x;\n"
"}\n");
const std::string expected("\n\n##file 0\n"
"1: struct Foo {\n"
"2: int x@1 ;\n"
"3: } ;\n"
"4:\n"
"5: struct Bar {\n"
"6: Foo foo@2 ;\n"
"7: int x@3 ;\n"
"8: void f ( ) ;\n"
"9: } ;\n"
"10:\n"
"11: void Bar :: f ( )\n"
"12: {\n"
"13: foo@2 . x@4 = x@3 ;\n"
"14: }\n");
ASSERT_EQUALS(expected, actual);
}
void varid_in_class3() {
const char code[] = "class Foo {\n"
" void blah() {\n"
" Bar x(*this);\n" //