From f94e9c544710473c0438ca84e86060c189e50fb7 Mon Sep 17 00:00:00 2001 From: IOBYTE Date: Fri, 4 May 2018 01:56:20 -0400 Subject: [PATCH] Fix #8540 (Syntax error involving forward-declared 'enum class') (#1203) --- lib/symboldatabase.cpp | 13 ++++++++++--- test/testsymboldatabase.cpp | 10 ++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 7fd7c6ad3..fb04d65fb 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|)|(|<")) || + !Token::Match(tok->previous(), "new|friend|const|enum|)|(|<")) || (Token::Match(tok, "enum class| %name% {") || Token::Match(tok, "enum class| %name% : %name% {")))) || (_tokenizer->isC() && Token::Match(tok, "struct|union|enum %name% {"))) { @@ -154,7 +154,12 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() break; // bail } - Scope *new_scope = findScope(tok->next(), scope); + const Token * name = tok->next(); + + if (name->str() == "class" && name->strAt(-1) == "enum") + name = name->next(); + + Scope *new_scope = findScope(name, scope); if (new_scope) { // only create base list for classes and structures @@ -198,7 +203,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() // fill typeList... if (new_scope->isClassOrStructOrUnion() || new_scope->type == Scope::eEnum) { - Type* new_type = findType(tok->next(), scope); + Type* new_type = findType(name, scope); if (!new_type) { typeList.emplace_back(new_scope->classDef, new_scope, scope); new_type = &typeList.back(); @@ -2329,6 +2334,8 @@ const std::string& Type::name() const const Token* next = classDef->next(); if (classScope && classScope->enumClass && isEnumType()) return next->strAt(1); + else if (next->str() == "class") + return next->strAt(1); else if (next->isName()) return next->str(); return emptyString; diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 9ffd78404..22002a989 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -283,6 +283,7 @@ private: TEST_CASE(symboldatabase63); TEST_CASE(symboldatabase64); TEST_CASE(symboldatabase65); + TEST_CASE(symboldatabase66); // #8540 TEST_CASE(enum1); TEST_CASE(enum2); @@ -3817,6 +3818,15 @@ private: ASSERT_EQUALS("[test.cpp:1]: (debug) SymbolDatabase::findFunction found '>' without link.\n", errout.str()); } + void symboldatabase66() { // #8540 + GET_SYMBOL_DB("enum class ENUM1;\n" + "enum class ENUM2 { MEMBER2 };\n" + "enum class ENUM3 : int { MEMBER1, };"); + ASSERT(db != nullptr); + ASSERT(db && db->scopeList.size() == 3); + ASSERT(db && db->typeList.size() == 3); + } + void enum1() { GET_SYMBOL_DB("enum BOOL { FALSE, TRUE }; enum BOOL b;");