Skip to content

Commit 583b340

Browse files
IOBYTEdanmar
authored andcommitted
enum: set the return type of derived class functions returning enums defined in a base class.
1 parent de23226 commit 583b340

2 files changed

Lines changed: 44 additions & 17 deletions

File tree

lib/symboldatabase.cpp

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,21 @@
3232
#include <iomanip>
3333
#include <cctype>
3434

35+
static const Type* findVariableTypeInBase(const Scope* scope, const Token* typeTok)
36+
{
37+
if (scope && scope->definedType && !scope->definedType->derivedFrom.empty()) {
38+
for (std::size_t i = 0; i < scope->definedType->derivedFrom.size(); ++i) {
39+
const Type *base = scope->definedType->derivedFrom[i].type;
40+
if (base && base->classScope) {
41+
const Type * type = base->classScope->findType(typeTok->str());
42+
if (type)
43+
return type;
44+
}
45+
}
46+
}
47+
return nullptr;
48+
}
49+
3550
//---------------------------------------------------------------------------
3651

3752
SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
@@ -892,8 +907,11 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
892907
const Token *type = func->retDef;
893908
while (Token::Match(type, "static|const|struct|union|enum"))
894909
type = type->next();
895-
if (type)
896-
func->retType = findTypeInNested(type, func->nestedIn);
910+
if (type) {
911+
func->retType = findVariableTypeInBase(&*it, type);
912+
if (!func->retType)
913+
func->retType = findTypeInNested(type, func->nestedIn);
914+
}
897915
}
898916
}
899917
}
@@ -3413,21 +3431,6 @@ const Enumerator * SymbolDatabase::findEnumerator(const Token * tok) const
34133431

34143432
//---------------------------------------------------------------------------
34153433

3416-
static const Type* findVariableTypeInBase(const Scope* scope, const Token* typeTok)
3417-
{
3418-
if (scope && scope->definedType && !scope->definedType->derivedFrom.empty()) {
3419-
for (std::size_t i = 0; i < scope->definedType->derivedFrom.size(); ++i) {
3420-
const Type *base = scope->definedType->derivedFrom[i].type;
3421-
if (base && base->classScope) {
3422-
const Type * type = base->classScope->findType(typeTok->str());
3423-
if (type)
3424-
return type;
3425-
}
3426-
}
3427-
}
3428-
return nullptr;
3429-
}
3430-
34313434
const Type* SymbolDatabase::findVariableType(const Scope *start, const Token *typeTok) const
34323435
{
34333436
// check if type does not have a namespace

test/testsymboldatabase.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ class TestSymbolDatabase: public TestFixture {
247247
TEST_CASE(enum3);
248248
TEST_CASE(enum4);
249249
TEST_CASE(enum5);
250+
TEST_CASE(enum6);
250251

251252
TEST_CASE(isImplicitlyVirtual);
252253
TEST_CASE(isPure);
@@ -2445,6 +2446,29 @@ class TestSymbolDatabase: public TestFixture {
24452446
ASSERT_EQUALS(12U, v->dimension(0));
24462447
}
24472448

2449+
void enum6() {
2450+
GET_SYMBOL_DB("struct Fred {\n"
2451+
" enum Enum { E0, E1 };\n"
2452+
"};\n"
2453+
"struct Barney : public Fred {\n"
2454+
" Enum func(Enum e) { return e; }\n"
2455+
"};");
2456+
ASSERT(db);
2457+
if (!db)
2458+
return;
2459+
const Token * const functionToken = Token::findsimplematch(tokenizer.tokens(), "func");
2460+
ASSERT(functionToken);
2461+
if (!functionToken)
2462+
return;
2463+
const Function *function = functionToken->function();
2464+
ASSERT(function);
2465+
if (!function)
2466+
return;
2467+
ASSERT(function->token->str() == "func");
2468+
ASSERT(function->retDef && function->retDef->str() == "Enum");
2469+
ASSERT(function->retType && function->retType->name() == "Enum");
2470+
}
2471+
24482472
void isImplicitlyVirtual() {
24492473
{
24502474
GET_SYMBOL_DB("class Base {\n"

0 commit comments

Comments
 (0)