diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index b8b77a50e..3e4404b35 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -2356,11 +2356,15 @@ bool Function::argsMatch(const Scope *scope, const Token *first, const Token *se int arg_path_length = path_length; int offset = 0; + int openParen = 0; while (first->str() == second->str() && first->isLong() == second->isLong() && first->isUnsigned() == second->isUnsigned()) { + if (first->str() == "(") + openParen++; + // skip optional type information if (Token::Match(first->next(), "struct|enum|union|class")) first = first->next(); @@ -2377,7 +2381,10 @@ bool Function::argsMatch(const Scope *scope, const Token *first, const Token *se // at end of argument list if (first->str() == ")") { - return true; + if (openParen == 1) + return true; + else + --openParen; } // skip default value assignment @@ -2483,8 +2490,11 @@ bool Function::argsMatch(const Scope *scope, const Token *first, const Token *se std::string param = path; if (Token::simpleMatch(second->next(), param.c_str(), param.size())) { - second = second->tokAt(int(arg_path_length)); - arg_path_length = 0; + // check for redundant qualification before skipping it + if (!Token::simpleMatch(first->next(), param.c_str(), param.size())) { + second = second->tokAt(int(arg_path_length)); + arg_path_length = 0; + } } // nested or base class variable diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index feb685125..9d9a2763a 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -343,6 +343,7 @@ private: TEST_CASE(symboldatabase88); // #10040 (using namespace) TEST_CASE(symboldatabase89); // valuetype name TEST_CASE(symboldatabase90); + TEST_CASE(symboldatabase91); TEST_CASE(createSymbolDatabaseFindAllScopes1); @@ -4658,6 +4659,20 @@ private: ASSERT(functok->function()->name() == "foo"); } + void symboldatabase91() { + GET_SYMBOL_DB("namespace Fred {\n" + " struct Value {};\n" + " void foo(const std::vector> &callbacks);\n" + "}\n" + "void Fred::foo(const std::vector> &callbacks) { }"); + ASSERT_EQUALS("", errout.str()); + const Token *functok = Token::findsimplematch(tokenizer.tokens(), + "foo ( const std :: vector < std :: function < void ( const Fred :: Value & ) > > & callbacks ) { }"); + ASSERT(functok); + ASSERT(functok->function()); + ASSERT(functok->function()->name() == "foo"); + } + void createSymbolDatabaseFindAllScopes1() { GET_SYMBOL_DB("void f() { union {int x; char *p;} a={0}; }"); ASSERT(db->scopeList.size() == 3);