diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index bf5f1f476..b8f6b538b 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1932,8 +1932,16 @@ const Scope *SymbolDatabase::findVariableType(const Scope *start, const Token *t const Scope *parent = start; // check if in same namespace - while (parent && parent != scope->nestedIn) - parent = parent->nestedIn; + while (parent) + { + // out of line class function belongs to class + if (parent->type == Scope::eFunction && parent->functionOf) + parent = parent->functionOf; + else if (parent != scope->nestedIn) + parent = parent->nestedIn; + else + break; + } if (scope->nestedIn == parent) return &(*scope); diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index d3904df16..e5f744615 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -41,6 +41,11 @@ public: ,isArray(false) {} + virtual void reportOut(const std::string &outmsg) + { + errout << outmsg << std::endl; + } + private: const Scope si; const Token* vartok; @@ -124,6 +129,7 @@ private: TEST_CASE(symboldatabase18); // ticket #2865 TEST_CASE(symboldatabase19); // ticket #2991 (segmentation fault) TEST_CASE(symboldatabase20); // ticket #3013 (segmentation fault) + TEST_CASE(symboldatabase21); } void test_isVariableDeclarationCanHandleNull() @@ -629,14 +635,14 @@ private: } } - void check(const char code[]) + void check(const char code[], bool debug = true) { // Clear the error log errout.str(""); // Check.. Settings settings; - settings.debugwarnings = true; + settings.debugwarnings = debug; // Tokenize.. Tokenizer tokenizer(&settings, this); @@ -756,7 +762,7 @@ private: "template class Y { };\n" "Y> x3;\n" "Y>1>> x4;\n" - "Y>1)>> x5;\n"); + "Y>1)>> x5;\n", false); ASSERT_EQUALS("", errout.str()); } @@ -801,7 +807,7 @@ private: " CString::operator=(lpsz);\n" " return *this;\n" " }\n" - "};\n"); + "};\n", false); ASSERT_EQUALS("", errout.str()); } @@ -907,6 +913,19 @@ private: ASSERT_EQUALS("", errout.str()); } + void symboldatabase21() + { + check("class Fred {\n" + " class Foo { };\n" + " void func() const;\n" + "};\n" + "Fred::func() const {\n" + " Foo foo;\n" + "}\n"); + + ASSERT_EQUALS("", errout.str()); + } + }; REGISTER_TEST(TestSymbolDatabase)