enum: set the return type of derived class functions returning enums defined in a base class.

This commit is contained in:
Robert Reif 2016-06-05 14:08:33 +02:00 committed by Daniel Marjamäki
parent de232268a3
commit 583b340034
2 changed files with 44 additions and 17 deletions

View File

@ -32,6 +32,21 @@
#include <iomanip>
#include <cctype>
static const Type* findVariableTypeInBase(const Scope* scope, const Token* typeTok)
{
if (scope && scope->definedType && !scope->definedType->derivedFrom.empty()) {
for (std::size_t i = 0; i < scope->definedType->derivedFrom.size(); ++i) {
const Type *base = scope->definedType->derivedFrom[i].type;
if (base && base->classScope) {
const Type * type = base->classScope->findType(typeTok->str());
if (type)
return type;
}
}
}
return nullptr;
}
//---------------------------------------------------------------------------
SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
@ -892,8 +907,11 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
const Token *type = func->retDef;
while (Token::Match(type, "static|const|struct|union|enum"))
type = type->next();
if (type)
func->retType = findTypeInNested(type, func->nestedIn);
if (type) {
func->retType = findVariableTypeInBase(&*it, type);
if (!func->retType)
func->retType = findTypeInNested(type, func->nestedIn);
}
}
}
}
@ -3413,21 +3431,6 @@ const Enumerator * SymbolDatabase::findEnumerator(const Token * tok) const
//---------------------------------------------------------------------------
static const Type* findVariableTypeInBase(const Scope* scope, const Token* typeTok)
{
if (scope && scope->definedType && !scope->definedType->derivedFrom.empty()) {
for (std::size_t i = 0; i < scope->definedType->derivedFrom.size(); ++i) {
const Type *base = scope->definedType->derivedFrom[i].type;
if (base && base->classScope) {
const Type * type = base->classScope->findType(typeTok->str());
if (type)
return type;
}
}
}
return nullptr;
}
const Type* SymbolDatabase::findVariableType(const Scope *start, const Token *typeTok) const
{
// check if type does not have a namespace

View File

@ -247,6 +247,7 @@ private:
TEST_CASE(enum3);
TEST_CASE(enum4);
TEST_CASE(enum5);
TEST_CASE(enum6);
TEST_CASE(isImplicitlyVirtual);
TEST_CASE(isPure);
@ -2445,6 +2446,29 @@ private:
ASSERT_EQUALS(12U, v->dimension(0));
}
void enum6() {
GET_SYMBOL_DB("struct Fred {\n"
" enum Enum { E0, E1 };\n"
"};\n"
"struct Barney : public Fred {\n"
" Enum func(Enum e) { return e; }\n"
"};");
ASSERT(db);
if (!db)
return;
const Token * const functionToken = Token::findsimplematch(tokenizer.tokens(), "func");
ASSERT(functionToken);
if (!functionToken)
return;
const Function *function = functionToken->function();
ASSERT(function);
if (!function)
return;
ASSERT(function->token->str() == "func");
ASSERT(function->retDef && function->retDef->str() == "Enum");
ASSERT(function->retType && function->retType->name() == "Enum");
}
void isImplicitlyVirtual() {
{
GET_SYMBOL_DB("class Base {\n"