diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 7964bb3c8..0a0ae30b9 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -100,7 +100,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() tok->progressValue()); // Locate next class if ((_tokenizer->isCPP() && ((Token::Match(tok, "class|struct|union|namespace ::| %name% {|:|::|<") && - !Token::Match(tok->previous(), "new|friend|const|enum|)|(|<")) || + !Token::Match(tok->previous(), "new|friend|const|enum|typedef|mutable|volatile|)|(|<")) || (Token::Match(tok, "enum class| %name% {") || Token::Match(tok, "enum class| %name% : %name% {")))) || (_tokenizer->isC() && Token::Match(tok, "struct|union|enum %name% {"))) { @@ -143,10 +143,23 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() else if (Token::Match(tok2, "%name% [")) continue; // skip template - else if (Token::Match(tok->previous(), "template class|struct") && - Token::simpleMatch(tok2->previous(), "> ;")) { + else if (Token::simpleMatch(tok2, ";") && + Token::Match(tok->previous(), "template|> class|struct")) { tok = tok2; continue; + } + // forward declaration + else if (Token::simpleMatch(tok2, ";") && + Token::Match(tok, "class|struct|union")) { + // TODO: see if it can be used + tok = tok2; + continue; + } + // skip constructor + else if (Token::simpleMatch(tok2, "(") && + Token::simpleMatch(tok2->link(), ") ;")) { + tok = tok2->link()->next(); + continue; } else throw InternalError(tok2, "SymbolDatabase bailout; unhandled code", InternalError::SYNTAX); continue; diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 9de5e9930..b67adb274 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -287,6 +287,7 @@ private: TEST_CASE(symboldatabase67); // #8538 TEST_CASE(symboldatabase68); // #8560 TEST_CASE(symboldatabase69); + TEST_CASE(symboldatabase70); TEST_CASE(enum1); TEST_CASE(enum2); @@ -3895,6 +3896,27 @@ private: ASSERT(f && f->function() && !f->function()->isConst()); } + void symboldatabase70() { + { + GET_SYMBOL_DB("class Map::Entry* e;"); + ASSERT(db != nullptr); + ASSERT(db && db->scopeList.size() == 1); + ASSERT(db && db->variableList().size() == 2); + } + { + GET_SYMBOL_DB("template class boost::token_iterator_generator::type; void foo() { }"); + ASSERT(db != nullptr); + ASSERT(db && db->scopeList.size() == 2); + } + { + GET_SYMBOL_DB("void foo() {\n" + " return class Arm_relocate_functions::thumb32_branch_offset(upper_insn, lower_insn);\n" + "}"); + ASSERT(db != nullptr); + ASSERT(db && db->scopeList.size() == 2); + } + } + void enum1() { GET_SYMBOL_DB("enum BOOL { FALSE, TRUE }; enum BOOL b;");