enum: set the return type of derived class functions returning enums defined in a base class.
This commit is contained in:
parent
de232268a3
commit
583b340034
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue