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 <iomanip>
|
||||||
#include <cctype>
|
#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)
|
SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
||||||
@ -892,11 +907,14 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
|||||||
const Token *type = func->retDef;
|
const Token *type = func->retDef;
|
||||||
while (Token::Match(type, "static|const|struct|union|enum"))
|
while (Token::Match(type, "static|const|struct|union|enum"))
|
||||||
type = type->next();
|
type = type->next();
|
||||||
if (type)
|
if (type) {
|
||||||
|
func->retType = findVariableTypeInBase(&*it, type);
|
||||||
|
if (!func->retType)
|
||||||
func->retType = findTypeInNested(type, func->nestedIn);
|
func->retType = findTypeInNested(type, func->nestedIn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (tokenizer->isC()) {
|
if (tokenizer->isC()) {
|
||||||
// For C code it is easy, as there are no constructors and no default values
|
// For C code it is easy, as there are no constructors and no default values
|
||||||
@ -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
|
const Type* SymbolDatabase::findVariableType(const Scope *start, const Token *typeTok) const
|
||||||
{
|
{
|
||||||
// check if type does not have a namespace
|
// check if type does not have a namespace
|
||||||
|
@ -247,6 +247,7 @@ private:
|
|||||||
TEST_CASE(enum3);
|
TEST_CASE(enum3);
|
||||||
TEST_CASE(enum4);
|
TEST_CASE(enum4);
|
||||||
TEST_CASE(enum5);
|
TEST_CASE(enum5);
|
||||||
|
TEST_CASE(enum6);
|
||||||
|
|
||||||
TEST_CASE(isImplicitlyVirtual);
|
TEST_CASE(isImplicitlyVirtual);
|
||||||
TEST_CASE(isPure);
|
TEST_CASE(isPure);
|
||||||
@ -2445,6 +2446,29 @@ private:
|
|||||||
ASSERT_EQUALS(12U, v->dimension(0));
|
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() {
|
void isImplicitlyVirtual() {
|
||||||
{
|
{
|
||||||
GET_SYMBOL_DB("class Base {\n"
|
GET_SYMBOL_DB("class Base {\n"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user