From f2cf11682a28030c8baf7dd4bbcd663407bd0b6f Mon Sep 17 00:00:00 2001 From: IOBYTE Date: Fri, 18 Dec 2020 01:46:01 -0500 Subject: [PATCH] fix #10040 (symbolDatabaseWarning: debug: Executable scope 'x' with unknown function.) (#2955) --- lib/symboldatabase.cpp | 20 ++++++++++++++++++++ test/testsymboldatabase.cpp | 22 ++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 539b9b7bb..14bcb24c3 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -2286,6 +2286,24 @@ static std::string qualifiedName(const Scope *scope) static bool usingNamespace(const Scope *scope, const Token *first, const Token *second, int &offset) { + // check if qualifications match first before checking if using is needed + const Token *tok1 = first; + const Token *tok2 = second; + bool match = false; + while (Token::Match(tok1, "%type% :: %type%") && Token::Match(tok2, "%type% :: %type%")) { + if (tok1->str() == tok2->str()) { + tok1 = tok1->tokAt(2); + tok2 = tok2->tokAt(2); + match = true; + } else { + match = false; + break; + } + } + + if (match) + return false; + offset = 0; std::string name = first->str(); @@ -3155,6 +3173,8 @@ static std::string scopeToString(const Scope* scope, const Tokenizer* tokenizer) std::ostringstream oss; if (scope) { oss << scope->type << " "; + if (!scope->className.empty()) + oss << scope->className << " "; if (scope->classDef) oss << tokenizer->list.fileLine(scope->classDef) << " "; } diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index e768f5728..7cd724c5c 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -331,6 +331,7 @@ private: TEST_CASE(symboldatabase85); TEST_CASE(symboldatabase86); TEST_CASE(symboldatabase87); // #9922 'extern const char ( * x [ 256 ] ) ;' + TEST_CASE(symboldatabase88); // #10040 (using namespace) TEST_CASE(createSymbolDatabaseFindAllScopes1); @@ -4782,6 +4783,27 @@ private: ASSERT(xtok->variable()); } + void symboldatabase88() { // #10040 (using namespace) + check("namespace external {\n" + "namespace ns {\n" + "enum class s { O };\n" + "}\n" + "}\n" + "namespace internal {\n" + "namespace ns1 {\n" + "template \n" + "void make(external::ns::s) {\n" + "}\n" + "}\n" + "}\n" + "using namespace external::ns;\n" + "struct A { };\n" + "static void make(external::ns::s ss) {\n" + " internal::ns1::make(ss);\n" + "}\n", true); + ASSERT_EQUALS("", errout.str()); + } + void createSymbolDatabaseFindAllScopes1() { GET_SYMBOL_DB("void f() { union {int x; char *p;} a={0}; }"); ASSERT(db->scopeList.size() == 3);