diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 6102b940c..f12c7c542 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -732,6 +732,8 @@ void Tokenizer::simplifyTypedef() Token *typeDef = tok; Token *argFuncRetStart = 0; Token *argFuncRetEnd = 0; + Token *const1= 0; + Token *const2= 0; int offset = 1; bool function = false; bool functionPtr = false; @@ -876,13 +878,25 @@ 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), "( *|&| const|volatile| const|volatile| %type% ) (")) { functionPtr = tok->tokAt(offset + 1)->str() == "*"; functionRef = tok->tokAt(offset + 1)->str() == "&"; function = tok->tokAt(offset + 2)->str() == ")"; if (!function) + { offset++; + if (Token::Match(tok->tokAt(offset + 1), "const|volatile")) + { + const1= tok->tokAt(offset + 1); + offset++; + if (Token::Match(tok->tokAt(offset + 1), "const|volatile")) + { + const2 = tok->tokAt(offset + 1); + offset++; + } + } + } if (tok->tokAt(offset + 3)->link()->next()) { typeName = tok->tokAt(offset + 1); @@ -908,14 +922,26 @@ void Tokenizer::simplifyTypedef() tok = specEnd->next(); } } - else if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "( %var% :: *|&| %type% ) (")) + else if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "( %var% :: *|&| const|volatile| const|volatile| %type% ) (")) { functionNamespace = tok->tokAt(offset + 1); functionPtr = tok->tokAt(offset + 3)->str() == "*"; functionRef = tok->tokAt(offset + 3)->str() == "&"; function = tok->tokAt(offset + 4)->str() == ")"; if (!function) + { offset++; + if (Token::Match(tok->tokAt(offset + 3), "const|volatile")) + { + const1 = tok->tokAt(offset + 3); + offset++; + if (Token::Match(tok->tokAt(offset + 3), "const|volatile")) + { + const2 = tok->tokAt(offset + 3); + offset++; + } + } + } if (tok->tokAt(offset + 5)->link()->next()) { typeName = tok->tokAt(offset + 3); @@ -1182,6 +1208,17 @@ void Tokenizer::simplifyTypedef() tok2->insertToken("&"); tok2 = tok2->next(); + if (const1) + { + tok2->insertToken(const1->str()); + tok2 = tok2->next(); + if (const2) + { + tok2->insertToken(const2->str()); + tok2 = tok2->next(); + } + } + if (!inCast) { if (tok2->next() && tok2->next()->str() != ")" && tok2->next()->str() != ",") diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 0c2e014d3..6e695371c 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -197,6 +197,7 @@ private: TEST_CASE(simplifyTypedefFunction2); // ticket #1685 TEST_CASE(simplifyTypedefFunction3); TEST_CASE(simplifyTypedefFunction4); + TEST_CASE(simplifyTypedefFunction5); TEST_CASE(reverseArraySyntax) TEST_CASE(simplify_numeric_condition) @@ -4264,6 +4265,41 @@ private: ASSERT_EQUALS("", errout.str()); } + void simplifyTypedefFunction5() + { + const char code[] = "typedef int ( * type1 ) ( float ) ;\n" + "typedef int ( * const type2 ) ( float ) ;\n" + "typedef int ( * volatile type3 ) ( float ) ;\n" + "typedef int ( * const volatile type4 ) ( float ) ;\n" + "typedef int ( C :: * type5 ) ( float ) ;\n" + "typedef int ( C :: * const type6 ) ( float ) ;\n" + "typedef int ( C :: * volatile type7 ) ( float ) ;\n" + "typedef int ( C :: * const volatile type8 ) ( float ) ;\n" + "type1 t1;\n" + "type2 t2;\n" + "type3 t3;\n" + "type4 t4;\n" + "type5 t5;\n" + "type6 t6;\n" + "type7 t7;\n" + "type8 t8;"; + + // The expected result.. + const std::string expected("; ; ; ; ; ; ; ; " + "int * t1 ; " // simplified to regular pointer + "int ( * const t2 ) ( float ) ; " + "int * t3 ; " // volatile removed, gets simplified to regular pointer + "int ( * const t4 ) ( float ) ; " // volatile removed + "int ( C :: * t5 ) ( float ) ; " + "int ( C :: * const t6 ) ( float ) ; " + "int ( C :: * t7 ) ( float ) ; " // volatile removed + "int ( C :: * const t8 ) ( float ) ;"); // volatile removed + ASSERT_EQUALS(expected, tok(code, false)); + + checkSimplifyTypedef(code); + ASSERT_EQUALS("", errout.str()); + } + void reverseArraySyntax() { ASSERT_EQUALS("a [ 13 ]", tok("13[a]"));