From b67cf0a475f393fe82633f4485eb41300a22d61a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 9 Nov 2017 15:58:08 +0100 Subject: [PATCH] Improved handling of varid in complex scopes --- lib/tokenize.cpp | 36 +++++++++++++++++++++++------------- test/testvarid.cpp | 23 +++++++++++++++++++++++ 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index b25f0e67f..0041afc05 100755 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2880,17 +2880,17 @@ static std::string getScopeName(const std::list &scopeInfo) return ret; } -static Token * matchFunctionName(const Member &func, const std::list &scopeInfo) +static Token * matchMemberName(const Member &member, const std::list &scopeInfo) { if (scopeInfo.empty()) return nullptr; - std::list::const_iterator funcScopeIt = func.scope.begin(); - Token *tok2 = func.tok; + std::list::const_iterator memberScopeIt = member.scope.begin(); + Token *tok2 = member.tok; for (std::list::const_iterator it = scopeInfo.begin(); tok2 && it != scopeInfo.end(); ++it) { - if (funcScopeIt != func.scope.end()) { - if (it->name != *funcScopeIt) + if (memberScopeIt != member.scope.end()) { + if (it->name != *memberScopeIt) return nullptr; - ++funcScopeIt; + ++memberScopeIt; continue; } @@ -2905,7 +2905,19 @@ static Token * matchFunctionName(const Member &func, const std::list } tok2 = tok2->tokAt(2); } - return (funcScopeIt == func.scope.end() && Token::Match(tok2, "~| %name% (")) ? tok2 : nullptr; + return (memberScopeIt == member.scope.end() && Token::Match(tok2, "~| %name%")) ? tok2 : nullptr; +} + +static Token * matchMemberVarName(const Member &var, const std::list &scopeInfo) +{ + Token *tok = matchMemberName(var, scopeInfo); + return Token::Match(tok, "%name% !!(") ? tok : nullptr; +} + +static Token * matchMemberFunctionName(const Member &func, const std::list &scopeInfo) +{ + Token *tok = matchMemberName(func, scopeInfo); + return Token::Match(tok, "~| %name% (") ? tok : nullptr; } void Tokenizer::setVarIdPass2() @@ -3024,12 +3036,10 @@ void Tokenizer::setVarIdPass2() continue; // Member variables - for (std::list::iterator func = allMemberVars.begin(); func != allMemberVars.end(); ++func) { - if (!Token::simpleMatch(func->tok, classname.c_str())) + for (std::list::iterator var = allMemberVars.begin(); var != allMemberVars.end(); ++var) { + Token *tok2 = matchMemberVarName(*var, scopeInfo); + if (!tok2) continue; - - Token *tok2 = func->tok; - tok2 = tok2->tokAt(2); tok2->varId(thisClassVars[tok2->str()]); } @@ -3038,7 +3048,7 @@ void Tokenizer::setVarIdPass2() // Set variable ids in member functions for this class.. for (std::list::const_iterator func = allMemberFunctions.begin(); func != allMemberFunctions.end(); ++func) { - Token *tok2 = matchFunctionName(*func, scopeInfo); + Token *tok2 = matchMemberFunctionName(*func, scopeInfo); if (!tok2) continue; diff --git a/test/testvarid.cpp b/test/testvarid.cpp index b9010ed41..063eda248 100644 --- a/test/testvarid.cpp +++ b/test/testvarid.cpp @@ -179,6 +179,7 @@ private: TEST_CASE(varid_classnameshaddowsvariablename); // #3990 TEST_CASE(varidnamespace1); + TEST_CASE(varidnamespace2); } std::string tokenize(const char code[], bool simplify = false, const char filename[] = "test.cpp") { @@ -2826,6 +2827,28 @@ private: ASSERT_EQUALS(expected, tokenize(code)); } + + void varidnamespace2() { + const char code[] = "namespace A {\n" + " namespace B {\n" + " char buf[20];\n" + " }\n" + "}\n" + "int main() {\n" + " return foo(A::B::buf);\n" + "}"; + + const char expected[] = "1: namespace A {\n" + "2: namespace B {\n" + "3: char buf@1 [ 20 ] ;\n" + "4: }\n" + "5: }\n" + "6: int main ( ) {\n" + "7: return foo ( A :: B :: buf@1 ) ;\n" + "8: }\n"; + + ASSERT_EQUALS(expected, tokenize(code)); + } }; REGISTER_TEST(TestVarID)