diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 1106dee78..2b3df5086 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -1723,8 +1723,11 @@ namespace { } if (tok1->strAt(-1) == ">") tok1 = tok1->previous()->findOpeningBracket(); - if (tok1 && Token::Match(tok1->tokAt(-3), "%name% :: %name%")) { + if (tok1 && (Token::Match(tok1->tokAt(-3), "%name% :: %name%") || + Token::Match(tok1->tokAt(-4), "%name% :: ~ %name%"))) { tok1 = tok1->tokAt(-2); + if (tok1->str() == "~") + tok1 = tok1->previous(); std::string scope = tok1->strAt(-1); while (Token::Match(tok1->tokAt(-2), ":: %name%")) { scope = tok1->strAt(-3) + " :: " + scope; @@ -1874,8 +1877,28 @@ namespace { return false; } + + std::string memberFunctionScope(const Token *tok) + { + std::string qualification; + const Token *qualTok = tok->strAt(-2) == "~" ? tok->tokAt(-4) : tok->tokAt(-3); + while (Token::Match(qualTok, "%type% ::")) { + if (!qualification.empty()) + qualification = " :: " + qualification; + qualification = qualTok->str() + qualification; + qualTok = qualTok->tokAt(-2); + } + return qualification; + } } // namespace +bool Tokenizer::isMemberFunction(const Token *openParen) const +{ + return (Token::Match(openParen->tokAt(-2), ":: %name% (") || + Token::Match(openParen->tokAt(-3), ":: ~ %name% (")) && + isFunctionHead(openParen, "{|:"); +} + bool Tokenizer::simplifyUsing() { bool substitute = false; @@ -2007,20 +2030,11 @@ bool Tokenizer::simplifyUsing() continue; } - // check for member function - if (Token::Match(tok1->tokAt(-2), ":: %name% (") && isFunctionHead(tok1, "{|:")) { - std::string qualification; - const Token *qualTok = tok1->tokAt(-3); - while (Token::Match(qualTok, "%type% ::")) { - if (!qualification.empty()) - qualification = " :: " + qualification; - qualification = qualTok->str() + qualification; - qualTok = qualTok->tokAt(-2); - } - + // check for member function and adjust scope + if (isMemberFunction(tok1)) { if (!scope1.empty()) scope1 += " :: "; - scope1 += qualification; + scope1 += memberFunctionScope(tok1); } if (!usingMatch(nameToken, scope, &tok1, scope1, scopeList1)) diff --git a/lib/tokenize.h b/lib/tokenize.h index 38667f22a..686a5afab 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -374,6 +374,10 @@ public: */ void simplifyTypedef(); + /** + */ + bool isMemberFunction(const Token *openParen) const; + /** */ bool simplifyUsing(); diff --git a/test/testsimplifyusing.cpp b/test/testsimplifyusing.cpp index 0241754e0..a959859a9 100644 --- a/test/testsimplifyusing.cpp +++ b/test/testsimplifyusing.cpp @@ -555,33 +555,49 @@ private: { const char code[] = "class A {\n" "public:\n" - " using Foo = Bar;\n" + " using Foo = int;\n" + " A(Foo foo);\n" + " ~A();\n" " void func(Foo foo);\n" "};\n" + "A::A(Foo) { }\n" + "A::~A() { Foo foo; }\n" "void A::func(Foo) { }"; const char exp[] = "class A { " "public: " - "void func ( Bar foo ) ; " + "A ( int foo ) ; " + "~ A ( ) ; " + "void func ( int foo ) ; " "} ; " - "void A :: func ( Bar ) { }"; + "A :: A ( int ) { } " + "A :: ~ A ( ) { int foo ; } " + "void A :: func ( int ) { }"; ASSERT_EQUALS(exp, tok(code, false)); } { const char code[] = "class A {\n" "public:\n" " struct B {\n" - " using Foo = Bar;\n" - " void func(Foo foo);\n" + " using Foo = int;\n" + " B(Foo foo);\n" + " ~B();\n" + " void func(Foo foo);\n" " };\n" "};\n" + "A::B::B(Foo) { }\n" + "A::B::~B() { Foo foo; }\n" "void A::B::func(Foo) { }"; const char exp[] = "class A { " "public: " "struct B { " - "void func ( Bar foo ) ; " + "B ( int foo ) ; " + "~ B ( ) ; " + "void func ( int foo ) ; " "} ; " "} ; " - "void A :: B :: func ( Bar ) { }"; + "A :: B :: B ( int ) { } " + "A :: B :: ~ B ( ) { int foo ; } " + "void A :: B :: func ( int ) { }"; ASSERT_EQUALS(exp, tok(code, false)); } }