diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 15f524419..db31c0b0c 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -729,6 +729,7 @@ void Tokenizer::simplifyTypedef() Token *arrayEnd = 0; Token *typeDef = tok; int offset = 1; + bool function = false; bool functionPtr = false; bool functionRef = false; @@ -747,7 +748,7 @@ void Tokenizer::simplifyTypedef() typeEnd = tok->tokAt(offset++); if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "%type%") && - tok->tokAt(offset + 1) && !Token::Match(tok->tokAt(offset + 1), "[|;|,")) + tok->tokAt(offset + 1) && !Token::Match(tok->tokAt(offset + 1), "[|;|,|(")) typeEnd = tok->tokAt(offset++); else atEnd = true; @@ -833,6 +834,23 @@ void Tokenizer::simplifyTypedef() // check for end or another if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), ";|,")) tok = tok->tokAt(offset); + + // or a function typedef + else if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "(")) + { + function = true; + if (tok->tokAt(offset)->link()->next()) + { + argStart = tok->tokAt(offset); + argEnd = tok->tokAt(offset)->link(); + tok = argEnd->next(); + } + else + { + // internal error + continue; + } + } else { // unhandled typedef, skip it and continue @@ -840,15 +858,18 @@ void Tokenizer::simplifyTypedef() continue; } } - else if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "( *|& %type% ) (")) + else if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "( *|&| %type% ) (")) { - if (tok->tokAt(offset + 4)->link()->next()) + functionPtr = tok->tokAt(offset + 1)->str() == "*"; + functionRef = tok->tokAt(offset + 1)->str() == "&"; + function = tok->tokAt(offset + 2)->str() == ")"; + if (!function) + offset++; + if (tok->tokAt(offset + 3)->link()->next()) { - functionPtr = tok->tokAt(offset + 1)->str() == "*"; - functionRef = tok->tokAt(offset + 1)->str() == "&"; - typeName = tok->tokAt(offset + 2); - argStart = tok->tokAt(offset + 4); - argEnd = tok->tokAt(offset + 4)->link(); + typeName = tok->tokAt(offset + 1); + argStart = tok->tokAt(offset + 3); + argEnd = tok->tokAt(offset + 3)->link(); tok = argEnd->next(); } else @@ -1009,14 +1030,14 @@ void Tokenizer::simplifyTypedef() tok2 = tok2->next(); } - if (functionPtr || functionRef) + if (functionPtr || functionRef || function) { tok2->insertToken("("); tok2 = tok2->next(); Token *tok3 = tok2; if (functionPtr) tok2->insertToken("*"); - else + else if (functionRef) tok2->insertToken("&"); tok2 = tok2->next(); diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index a2f3ea89e..94f4a68f5 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -186,6 +186,8 @@ private: TEST_CASE(simplifyTypedef45); // ticket #1613 TEST_CASE(simplifyTypedef46); // ticket #1615 + TEST_CASE(simplifyTypedefFunction); + TEST_CASE(reverseArraySyntax) TEST_CASE(simplify_numeric_condition) @@ -3909,6 +3911,29 @@ private: ASSERT_EQUALS("", errout.str()); } + void simplifyTypedefFunction() + { + { + const char code[] = "typedef void (my_func)(arg_class*);\n" + "std::queue func_queue;"; + + // The expected result.. + const std::string expected("; " + "std :: queue < void ( * ) ( arg_class * ) > func_queue ;"); + ASSERT_EQUALS(expected, sizeof_(code)); + } + + { + const char code[] = "typedef void my_func(arg_class*);\n" + "std::queue func_queue;"; + + // The expected result.. + const std::string expected("; " + "std :: queue < void ( * ) ( arg_class * ) > func_queue ;"); + ASSERT_EQUALS(expected, sizeof_(code)); + } + } + void reverseArraySyntax() { ASSERT_EQUALS("a [ 13 ]", tok("13[a]"));