Symbol database: Refactor the variables API. ticket: #2468

This commit is contained in:
Robert Reif 2011-01-18 07:32:06 +01:00 committed by Daniel Marjamäki
parent 965c1a94fd
commit c994508c3e
4 changed files with 188 additions and 55 deletions

View File

@ -85,7 +85,7 @@ void CheckClass::constructors()
std::list<Variable>::const_iterator var;
for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var)
{
if (var->access == Private && !var->isClass && !var->isStatic)
if (var->isPrivate() && !var->isClass() && !var->isStatic())
{
noConstructorError(scope->classDef, scope->className, scope->classDef->str() == "struct");
break;
@ -114,22 +114,22 @@ void CheckClass::constructors()
unsigned int count = 0;
for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var, ++count)
{
if (usage[count].assign || usage[count].init || var->isStatic)
if (usage[count].assign || usage[count].init || var->isStatic())
continue;
if (var->isConst && var->token->previous()->str() != "*")
if (var->isConst() && var->nameToken()->previous()->str() != "*")
continue;
// Check if this is a class constructor
if (var->isClass && func->type == Function::eConstructor)
if (var->isClass() && func->type == Function::eConstructor)
{
// Unknown type so assume it is initialized
if (!var->type)
if (!var->type())
continue;
// Known type that doesn't need initialization or
// known type that has member variables of an unknown type
else if (var->type->needInitialization != Scope::True)
else if (var->type()->needInitialization != Scope::True)
continue;
}
@ -153,10 +153,10 @@ void CheckClass::constructors()
}
if (classNameUsed)
operatorEqVarError(func->token, scope->className, var->token->str());
operatorEqVarError(func->token, scope->className, var->name());
}
else if (func->access != Private)
uninitVarError(func->token, scope->className, var->token->str());
uninitVarError(func->token, scope->className, var->name());
}
}
}
@ -169,7 +169,7 @@ void CheckClass::assignVar(const std::string &varname, const Scope *scope, std::
for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var, ++count)
{
if (var->token->str() == varname)
if (var->name() == varname)
{
usage[count].assign = true;
return;
@ -184,7 +184,7 @@ void CheckClass::initVar(const std::string &varname, const Scope *scope, std::ve
for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var, ++count)
{
if (var->token->str() == varname)
if (var->name() == varname)
{
usage[count].init = true;
return;
@ -305,7 +305,7 @@ void CheckClass::initializeVarList(const Function &func, std::list<std::string>
std::list<Variable>::const_iterator var;
for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var)
{
if (var->token->varId() == ftok->next()->varId())
if (var->varId() == ftok->next()->varId())
{
/** @todo false negative: we assume function changes variable state */
assignVar(ftok->next()->str(), scope, usage);
@ -1403,9 +1403,9 @@ bool CheckClass::isMemberVar(const Scope *scope, const Token *tok)
std::list<Variable>::const_iterator var;
for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var)
{
if (var->token->str() == tok->str())
if (var->name() == tok->str())
{
return !var->isMutable;
return !var->isMutable();
}
}

View File

@ -2713,27 +2713,27 @@ void CheckMemoryLeakInClass::check()
std::list<Variable>::const_iterator var;
for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var)
{
if (!var->isStatic && var->token->previous()->str() == "*")
if (!var->isStatic() && var->nameToken()->previous()->str() == "*")
{
// allocation but no deallocation of private variables in public function..
if (var->token->tokAt(-2)->isStandardType())
if (var->nameToken()->tokAt(-2)->isStandardType())
{
if (var->access == Private)
checkPublicFunctions(scope, var->token);
if (var->isPrivate())
checkPublicFunctions(scope, var->nameToken());
variable(scope, var->token);
variable(scope, var->nameToken());
}
// known class?
else if (var->type)
else if (var->type())
{
// not derived and no constructor?
if (var->type->derivedFrom.empty() && var->type->numConstructors == 0)
if (var->type()->derivedFrom.empty() && var->type()->numConstructors == 0)
{
if (var->access == Private)
checkPublicFunctions(scope, var->token);
if (var->isPrivate())
checkPublicFunctions(scope, var->nameToken());
variable(scope, var->token);
variable(scope, var->nameToken());
}
}
}

View File

@ -448,14 +448,14 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
std::list<Variable>::const_iterator var;
for (var = info->varlist.begin(); var != info->varlist.end(); ++var)
{
if (var->isClass)
if (var->isClass())
{
if (var->type)
if (var->type())
{
// does this type need initialization?
if (var->type->needInitialization == Scope::True)
if (var->type()->needInitialization == Scope::True)
needInitialization = true;
else if (var->type->needInitialization == Scope::Unknown)
else if (var->type()->needInitialization == Scope::Unknown)
unknown = true;
}
}

View File

@ -26,7 +26,8 @@
#include <vector>
#include <set>
class Token;
#include "token.h"
class Tokenizer;
class Settings;
class ErrorLogger;
@ -35,49 +36,181 @@ class Scope;
class SymbolDatabase;
/**
* @brief Access control.
* @brief Access control enumerations.
*/
enum AccessControl { Public, Protected, Private };
/** @brief Information about a member variable. */
class Variable
{
public:
Variable(const Token *token_, std::size_t index_, AccessControl access_, bool mutable_, bool static_, bool const_, bool class_, const Scope *type_)
: token(token_),
index(index_),
access(access_),
isMutable(mutable_),
isStatic(static_),
isConst(const_),
isClass(class_),
type(type_)
/** @brief flags mask used to access specific bit. */
enum
{
fIsMutable = (1 << 0), /** @brief mutable variable */
fIsStatic = (1 << 1), /** @brief static variable */
fIsConst = (1 << 2), /** @brief const variable */
fIsClass = (1 << 3) /** @brief user defined type */
};
/**
* Get specified flag state.
* @param flag_ flag to get state of
* @return true if flag set or false in flag not set
*/
bool getFlag(int flag_) const
{
return bool(_flags & flag_);
}
/** @brief variable token */
const Token *token;
/**
* Set specified flag state.
* @param flag_ flag to set state
* @param state_ new state of flag
*/
void setFlag(int flag_, bool state_)
{
_flags = state_ ? _flags | flag_ : _flags & ~flag_;
}
public:
Variable(const Token *name_, std::size_t index_, AccessControl access_,
bool mutable_, bool static_, bool const_, bool class_,
const Scope *type_)
: _name(name_),
_index(index_),
_access(access_),
_flags(0),
_type(type_)
{
setFlag(fIsMutable, mutable_);
setFlag(fIsStatic, static_);
setFlag(fIsConst, const_);
setFlag(fIsClass, class_);
}
/**
* Get name token.
* @return name token
*/
const Token *nameToken() const
{
return _name;
}
/**
* Get name string.
* @return name string
*/
const std::string &name() const
{
return _name->str();
}
/**
* Get variable ID.
* @return variable ID
*/
unsigned int varId() const
{
return _name->varId();
}
/**
* Get index of variable in declared order.
* @return varaible index
*/
std::size_t index() const
{
return _index;
}
/**
* Is variable public.
* @return true if public, false if not
*/
bool isPublic() const
{
return _access == Public;
}
/**
* Is variable protected.
* @return true if protected, false if not
*/
bool isProtected() const
{
return _access == Protected;
}
/**
* Is variable private.
* @return true if private, false if not
*/
bool isPrivate() const
{
return _access == Private;
}
/**
* Is variable mutable.
* @return true if mutable, false if not
*/
bool isMutable() const
{
return getFlag(fIsMutable);
}
/**
* Is variable static.
* @return true if static, false if not
*/
bool isStatic() const
{
return getFlag(fIsStatic);
}
/**
* Is variable const.
* @return true if const, false if not
*/
bool isConst() const
{
return getFlag(fIsConst);
}
/**
* Is variable a user defined (or unknown) type.
* @return true if user defined type, false if not
*/
bool isClass() const
{
return getFlag(fIsClass);
}
/**
* Get Scope pointer of known type.
* @return pointer to type if known, NULL if not known
*/
const Scope *type() const
{
return _type;
}
private:
/** @brief variable name token */
const Token *_name;
/** @brief order declared */
std::size_t index;
std::size_t _index;
/** @brief what section is this variable declared in? */
AccessControl access; // public/protected/private
AccessControl _access; // public/protected/private
/** @brief is this variable mutable? */
bool isMutable;
/** @brief is this variable static? */
bool isStatic;
/** @brief is this variable const? */
bool isConst;
/** @brief is this variable a class (or unknown type)? */
bool isClass;
/** @brief flags */
int _flags;
/** @brief pointer to user defined type info (for known types) */
const Scope *type;
const Scope *_type;
};
class Function