From c994508c3eec7d2206d20f7163361db024e65d2d Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Tue, 18 Jan 2011 07:32:06 +0100 Subject: [PATCH] Symbol database: Refactor the variables API. ticket: #2468 --- lib/checkclass.cpp | 26 +++--- lib/checkmemoryleak.cpp | 20 ++--- lib/symboldatabase.cpp | 8 +- lib/symboldatabase.h | 189 ++++++++++++++++++++++++++++++++++------ 4 files changed, 188 insertions(+), 55 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 56b0eaa5a..c95ddc43a 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -85,7 +85,7 @@ void CheckClass::constructors() std::list::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::list::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::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(); } } diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 52b7607d2..97b63c4ef 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -2713,27 +2713,27 @@ void CheckMemoryLeakInClass::check() std::list::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()); } } } diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index d10e64a48..366aa20ff 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -448,14 +448,14 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti std::list::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; } } diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 3897b6952..9f692abec 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -26,7 +26,8 @@ #include #include -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