diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index a07ad9c48..dc770111e 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -546,6 +546,23 @@ Token *Tokenizer::processFunc(Token *tok2, bool inOperator) const return tok2; } +void Tokenizer::simplifyUsingToTypedef() +{ + for (Token *tok = list.front(); tok; tok = tok->next()) { + // using a::b; => typedef a::b b; + if (Token::Match(tok, "[;{}] using %name% :: %name% ::|;") && !tok->tokAt(2)->isKeyword()) { + Token *endtok = tok->tokAt(5); + while (Token::Match(endtok, ":: %name%")) + endtok = endtok->tokAt(2); + if (endtok && endtok->str() == ";") { + tok->next()->str("typedef"); + endtok = endtok->previous(); + endtok->insertToken(endtok->str()); + } + } + } +} + void Tokenizer::simplifyTypedef() { std::vector spaceInfo; @@ -553,6 +570,10 @@ void Tokenizer::simplifyTypedef() std::string className; bool hasClass = false; bool goback = false; + + // Convert "using a::b;" to corresponding typedef statements + simplifyUsingToTypedef(); + for (Token *tok = list.front(); tok; tok = tok->next()) { if (mErrorLogger && !list.getFiles().empty()) mErrorLogger->reportProgress(list.getFiles()[0], "Tokenize (typedef)", tok->progressValue()); diff --git a/lib/tokenize.h b/lib/tokenize.h index 9c327fd59..da236ecf4 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -367,6 +367,9 @@ public: */ Token * simplifyAddBracesPair(Token *tok, bool commandWithCondition); + // Convert "using ...;" to corresponding typedef + void simplifyUsingToTypedef(); + /** * typedef A mytype; * mytype c; diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp index c6ea9f8c8..2e4984f56 100644 --- a/test/testsimplifytypedef.cpp +++ b/test/testsimplifytypedef.cpp @@ -167,6 +167,7 @@ private: TEST_CASE(simplifyTypedef129); TEST_CASE(simplifyTypedef130); // ticket #9446 TEST_CASE(simplifyTypedef131); // ticket #9446 + TEST_CASE(simplifyTypedef132); // ticket #9739 - using TEST_CASE(simplifyTypedefFunction1); TEST_CASE(simplifyTypedefFunction2); // ticket #1685 @@ -2630,6 +2631,27 @@ private: ASSERT_EQUALS(exp, tok(code, false)); } + void simplifyTypedef132() { + const char code[] = "namespace NamespaceA {\n" + " typedef int MySpecialType;\n" + "}\n" + "\n" + "class A {\n" + " void DoSomething( NamespaceA::MySpecialType special );\n" + "};\n" + "\n" + "using NamespaceA::MySpecialType;\n" + "\n" + "void A::DoSomething( MySpecialType wrongName ) {}"; + + const char exp [] = "class A { " + "void DoSomething ( int special ) ; " + "} ; " + "void A :: DoSomething ( int wrongName ) { }"; + + ASSERT_EQUALS(exp, tok(code, false)); + } + void simplifyTypedefFunction1() { { const char code[] = "typedef void (*my_func)();\n"