Tokenizer: tweaked simplification of function pointers. Argument types are kept.
This commit is contained in:
parent
a0cc35e3fa
commit
65fc31cba9
|
@ -1181,6 +1181,8 @@ void CheckUnusedVar::checkFunctionVariableUsage()
|
||||||
const Token * eq = tok->next();
|
const Token * eq = tok->next();
|
||||||
while (Token::simpleMatch(eq, "["))
|
while (Token::simpleMatch(eq, "["))
|
||||||
eq = eq->link()->next();
|
eq = eq->link()->next();
|
||||||
|
if (Token::simpleMatch(eq, ") (") && Token::simpleMatch(eq->linkAt(1), ") ="))
|
||||||
|
eq = eq->linkAt(1)->next();
|
||||||
if (Token::simpleMatch(eq, "=")) {
|
if (Token::simpleMatch(eq, "=")) {
|
||||||
varDecl = tok;
|
varDecl = tok;
|
||||||
tok = eq;
|
tok = eq;
|
||||||
|
|
|
@ -6173,20 +6173,26 @@ void Tokenizer::simplifyFunctionPointers()
|
||||||
endTok->deleteNext();
|
endTok->deleteNext();
|
||||||
|
|
||||||
// ok simplify this function pointer to an ordinary pointer
|
// ok simplify this function pointer to an ordinary pointer
|
||||||
Token::eraseTokens(tok->link(), endTok->next());
|
|
||||||
if (Token::simpleMatch(tok->link()->previous(), ") )")) {
|
if (Token::simpleMatch(tok->link()->previous(), ") )")) {
|
||||||
// Function returning function pointer
|
// Function returning function pointer
|
||||||
// void (*dostuff(void))(void) {}
|
// void (*dostuff(void))(void) {}
|
||||||
|
Token::eraseTokens(tok->link(), endTok->next());
|
||||||
tok->link()->deleteThis();
|
tok->link()->deleteThis();
|
||||||
tok->deleteThis();
|
tok->deleteThis();
|
||||||
} else {
|
} else {
|
||||||
// Function pointer variable
|
Token::eraseTokens(tok->link()->linkAt(1), endTok->next());
|
||||||
// void (*p)(void) {}
|
|
||||||
tok->link()->insertToken("(");
|
// remove variable names
|
||||||
Token *par1 = tok->link()->next();
|
for (Token* tok3 = tok->link()->tokAt(2); Token::Match(tok3, "%name%|*|&|[|(|::|,|<"); tok3 = tok3->next()) {
|
||||||
par1->insertToken(")");
|
if (tok3->str() == "<" && tok3->link())
|
||||||
par1->link(par1->next());
|
tok3 = tok3->link();
|
||||||
par1->next()->link(par1);
|
else if (Token::Match(tok3, "[|("))
|
||||||
|
tok3 = tok3->link();
|
||||||
|
if (Token::Match(tok3, "%type%|*|&|> %name% [,)[]"))
|
||||||
|
tok3->deleteNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Keep this info
|
||||||
while (Token::Match(tok, "( %type% ::"))
|
while (Token::Match(tok, "( %type% ::"))
|
||||||
tok->deleteNext(2);
|
tok->deleteNext(2);
|
||||||
}
|
}
|
||||||
|
@ -6424,8 +6430,10 @@ void Tokenizer::simplifyVarDecl(Token * tokBegin, const Token * const tokEnd, co
|
||||||
varName = varName->next();
|
varName = varName->next();
|
||||||
}
|
}
|
||||||
// Function pointer
|
// Function pointer
|
||||||
if (Token::simpleMatch(varName, "( *") && Token::Match(varName->link()->previous(), "%name% ) ( ) =")) {
|
if (Token::simpleMatch(varName, "( *") &&
|
||||||
Token *endDecl = varName->link()->tokAt(2);
|
Token::Match(varName->link()->previous(), "%name% ) (") &&
|
||||||
|
Token::simpleMatch(varName->link()->linkAt(1), ") =")) {
|
||||||
|
Token *endDecl = varName->link()->linkAt(1);
|
||||||
varName = varName->link()->previous();
|
varName = varName->link()->previous();
|
||||||
endDecl->insertToken(";");
|
endDecl->insertToken(";");
|
||||||
endDecl = endDecl->next();
|
endDecl = endDecl->next();
|
||||||
|
|
|
@ -779,8 +779,8 @@ private:
|
||||||
"void addCallback1(Callback callback, int j) { }";
|
"void addCallback1(Callback callback, int j) { }";
|
||||||
|
|
||||||
const char expected[] =
|
const char expected[] =
|
||||||
"void addCallback ( bool ( * callback ) ( ) ) { } "
|
"void addCallback ( bool ( * callback ) ( int ) ) { } "
|
||||||
"void addCallback1 ( bool ( * callback ) ( ) , int j ) { }";
|
"void addCallback1 ( bool ( * callback ) ( int ) , int j ) { }";
|
||||||
|
|
||||||
ASSERT_EQUALS(expected, tok(code, false));
|
ASSERT_EQUALS(expected, tok(code, false));
|
||||||
}
|
}
|
||||||
|
@ -1132,7 +1132,7 @@ private:
|
||||||
"class X { } ; "
|
"class X { } ; "
|
||||||
"int main ( ) "
|
"int main ( ) "
|
||||||
"{ "
|
"{ "
|
||||||
"X ( * * Foo ) ( ) ; Foo = new X ( * ) ( const X & ) [ 2 ] ; "
|
"X ( * * Foo ) ( const X & ) ; Foo = new X ( * ) ( const X & ) [ 2 ] ; "
|
||||||
"}";
|
"}";
|
||||||
|
|
||||||
ASSERT_EQUALS(expected, tok(code, false));
|
ASSERT_EQUALS(expected, tok(code, false));
|
||||||
|
@ -1606,7 +1606,7 @@ private:
|
||||||
" localEntitiyAddFunc_t f;\n"
|
" localEntitiyAddFunc_t f;\n"
|
||||||
"}";
|
"}";
|
||||||
// The expected result..
|
// The expected result..
|
||||||
const char expected[] = "enum qboolean { qfalse , qtrue } ; void f ( ) { qboolean b ; qboolean ( * f ) ( ) ; }";
|
const char expected[] = "enum qboolean { qfalse , qtrue } ; void f ( ) { qboolean b ; qboolean ( * f ) ( struct le_s * , entity_t * ) ; }";
|
||||||
ASSERT_EQUALS(expected, tok(code, false));
|
ASSERT_EQUALS(expected, tok(code, false));
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
@ -2174,7 +2174,7 @@ private:
|
||||||
"};";
|
"};";
|
||||||
const char expected[] = "class symbol_table { "
|
const char expected[] = "class symbol_table { "
|
||||||
"public: "
|
"public: "
|
||||||
"expression_error :: error_code ( * f ) ( ) ; "
|
"expression_error :: error_code ( * f ) ( void * , const char * , expression_space ) ; "
|
||||||
"} ;";
|
"} ;";
|
||||||
ASSERT_EQUALS(expected, tok(code, true, Settings::Native, false));
|
ASSERT_EQUALS(expected, tok(code, true, Settings::Native, false));
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
@ -3518,14 +3518,14 @@ private:
|
||||||
"type12 t12;";
|
"type12 t12;";
|
||||||
|
|
||||||
// The expected result..
|
// The expected result..
|
||||||
const char expected[] = "int ( * t1 ) ( ) ; "
|
const char expected[] = "int ( * t1 ) ( float ) ; "
|
||||||
"int ( * const t2 ) ( ) ; "
|
"int ( * const t2 ) ( float ) ; "
|
||||||
"int ( * volatile t3 ) ( ) ; "
|
"int ( * volatile t3 ) ( float ) ; "
|
||||||
"int ( * const volatile t4 ) ( ) ; "
|
"int ( * const volatile t4 ) ( float ) ; "
|
||||||
"int ( * t5 ) ( ) ; "
|
"int ( * t5 ) ( float ) ; "
|
||||||
"int ( * const t6 ) ( ) ; "
|
"int ( * const t6 ) ( float ) ; "
|
||||||
"int ( * volatile t7 ) ( ) ; "
|
"int ( * volatile t7 ) ( float ) ; "
|
||||||
"int ( * const volatile t8 ) ( ) ; "
|
"int ( * const volatile t8 ) ( float ) ; "
|
||||||
"int ( :: C :: * t9 ) ( float ) ; "
|
"int ( :: C :: * t9 ) ( float ) ; "
|
||||||
"int ( :: C :: * const t10 ) ( float ) ; "
|
"int ( :: C :: * const t10 ) ( float ) ; "
|
||||||
"int ( :: C :: * volatile t11 ) ( float ) ; "
|
"int ( :: C :: * volatile t11 ) ( float ) ; "
|
||||||
|
|
|
@ -224,6 +224,7 @@ private:
|
||||||
TEST_CASE(vardecl28);
|
TEST_CASE(vardecl28);
|
||||||
TEST_CASE(vardecl29); // #9282
|
TEST_CASE(vardecl29); // #9282
|
||||||
TEST_CASE(vardecl30);
|
TEST_CASE(vardecl30);
|
||||||
|
TEST_CASE(vardecl31); // function pointer init
|
||||||
TEST_CASE(vardecl_stl_1);
|
TEST_CASE(vardecl_stl_1);
|
||||||
TEST_CASE(vardecl_stl_2);
|
TEST_CASE(vardecl_stl_2);
|
||||||
TEST_CASE(vardecl_stl_3);
|
TEST_CASE(vardecl_stl_3);
|
||||||
|
@ -2523,6 +2524,14 @@ private:
|
||||||
tokenizeAndStringify(code, true, Settings::Native, "test.c"));
|
tokenizeAndStringify(code, true, Settings::Native, "test.c"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vardecl31() {
|
||||||
|
const char code1[] = "void foo() { int (*fptr)() = 0; }";
|
||||||
|
ASSERT_EQUALS("void foo ( ) { int ( * fptr ) ( ) ; fptr = 0 ; }", tokenizeAndStringify(code1));
|
||||||
|
|
||||||
|
const char code2[] = "void foo() { int (*fptr)(int) = 0; }";
|
||||||
|
ASSERT_EQUALS("void foo ( ) { int ( * fptr ) ( int ) ; fptr = 0 ; }", tokenizeAndStringify(code2));
|
||||||
|
}
|
||||||
|
|
||||||
void volatile_variables() {
|
void volatile_variables() {
|
||||||
{
|
{
|
||||||
const char code[] = "volatile int a=0;\n"
|
const char code[] = "volatile int a=0;\n"
|
||||||
|
@ -3557,7 +3566,7 @@ private:
|
||||||
ASSERT_EQUALS("unsigned int ( * f ) ( ) ;", tokenizeAndStringify("unsigned int (*f)();"));
|
ASSERT_EQUALS("unsigned int ( * f ) ( ) ;", tokenizeAndStringify("unsigned int (*f)();"));
|
||||||
ASSERT_EQUALS("unsigned int * ( * f ) ( ) ;", tokenizeAndStringify("unsigned int * (*f)();"));
|
ASSERT_EQUALS("unsigned int * ( * f ) ( ) ;", tokenizeAndStringify("unsigned int * (*f)();"));
|
||||||
ASSERT_EQUALS("void ( * f [ 2 ] ) ( ) ;", tokenizeAndStringify("void (*f[2])();"));
|
ASSERT_EQUALS("void ( * f [ 2 ] ) ( ) ;", tokenizeAndStringify("void (*f[2])();"));
|
||||||
TODO_ASSERT_EQUALS("void ( * f [ 2 ] ) ( ) ;", "void ( * f ) ( ) [ 2 ] ;", tokenizeAndStringify("typedef void func_t(void); func_t *f[2];"));
|
TODO_ASSERT_EQUALS("void ( * f [ 2 ] ) ( ) ;", "void ( * f ) ( void ) [ 2 ] ;", tokenizeAndStringify("typedef void func_t(void); func_t *f[2];"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplifyFunctionPointers2() {
|
void simplifyFunctionPointers2() {
|
||||||
|
@ -3598,7 +3607,7 @@ private:
|
||||||
|
|
||||||
void simplifyFunctionPointers5() {
|
void simplifyFunctionPointers5() {
|
||||||
const char code[] = ";void (*fp[])(int a) = {0,0,0};";
|
const char code[] = ";void (*fp[])(int a) = {0,0,0};";
|
||||||
const char expected[] = "1: ; void ( * fp@1 [ ] ) ( ) = { 0 , 0 , 0 } ;\n"; // TODO: Array dimension
|
const char expected[] = "1: ; void ( * fp@1 [ ] ) ( int ) = { 0 , 0 , 0 } ;\n"; // TODO: Array dimension
|
||||||
ASSERT_EQUALS(expected, tokenizeDebugListing(code));
|
ASSERT_EQUALS(expected, tokenizeDebugListing(code));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3709,7 +3718,7 @@ private:
|
||||||
|
|
||||||
void functionAttributeBefore3() { // #10978
|
void functionAttributeBefore3() { // #10978
|
||||||
const char code[] = "void __attribute__((__noreturn__)) (*func_notret)(void);";
|
const char code[] = "void __attribute__((__noreturn__)) (*func_notret)(void);";
|
||||||
const char expected[] = "void ( * func_notret ) ( ) ;";
|
const char expected[] = "void ( * func_notret ) ( void ) ;";
|
||||||
|
|
||||||
errout.str("");
|
errout.str("");
|
||||||
|
|
||||||
|
|
|
@ -190,6 +190,7 @@ private:
|
||||||
TEST_CASE(varid_not); // #9689 'not x'
|
TEST_CASE(varid_not); // #9689 'not x'
|
||||||
TEST_CASE(varid_declInIfCondition);
|
TEST_CASE(varid_declInIfCondition);
|
||||||
TEST_CASE(varid_globalScope);
|
TEST_CASE(varid_globalScope);
|
||||||
|
TEST_CASE(varid_function_pointer_args);
|
||||||
|
|
||||||
TEST_CASE(varidclass1);
|
TEST_CASE(varidclass1);
|
||||||
TEST_CASE(varidclass2);
|
TEST_CASE(varidclass2);
|
||||||
|
@ -2996,6 +2997,17 @@ private:
|
||||||
ASSERT_EQUALS(exp1, tokenize(code1));
|
ASSERT_EQUALS(exp1, tokenize(code1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void varid_function_pointer_args() {
|
||||||
|
const char code[] = "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(code));
|
||||||
|
}
|
||||||
|
|
||||||
void varidclass1() {
|
void varidclass1() {
|
||||||
const std::string actual = tokenize(
|
const std::string actual = tokenize(
|
||||||
"class Fred\n"
|
"class Fred\n"
|
||||||
|
|
Loading…
Reference in New Issue