Symbol database: renamed classes. ticket: #2468
This commit is contained in:
parent
bf9528558e
commit
959e10cee5
|
@ -68,51 +68,51 @@ void CheckClass::constructors()
|
||||||
|
|
||||||
createSymbolDatabase();
|
createSymbolDatabase();
|
||||||
|
|
||||||
std::list<SpaceInfo *>::const_iterator i;
|
std::list<Scope *>::const_iterator i;
|
||||||
|
|
||||||
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
|
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
|
||||||
{
|
{
|
||||||
const SpaceInfo *info = *i;
|
const Scope *scope = *i;
|
||||||
|
|
||||||
// only check classes and structures
|
// only check classes and structures
|
||||||
if (!info->isClassOrStruct())
|
if (!scope->isClassOrStruct())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// There are no constructors.
|
// There are no constructors.
|
||||||
if (info->numConstructors == 0)
|
if (scope->numConstructors == 0)
|
||||||
{
|
{
|
||||||
// If there is a private variable, there should be a constructor..
|
// If there is a private variable, there should be a constructor..
|
||||||
std::list<Var>::const_iterator var;
|
std::list<Variable>::const_iterator var;
|
||||||
for (var = info->varlist.begin(); var != info->varlist.end(); ++var)
|
for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var)
|
||||||
{
|
{
|
||||||
if (var->access == Private && !var->isClass && !var->isStatic)
|
if (var->access == Private && !var->isClass && !var->isStatic)
|
||||||
{
|
{
|
||||||
noConstructorError(info->classDef, info->className, info->classDef->str() == "struct");
|
noConstructorError(scope->classDef, scope->className, scope->classDef->str() == "struct");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::list<Func>::const_iterator func;
|
std::list<Function>::const_iterator func;
|
||||||
std::vector<Usage> usage(info->varlist.size());
|
std::vector<Usage> usage(scope->varlist.size());
|
||||||
|
|
||||||
for (func = info->functionList.begin(); func != info->functionList.end(); ++func)
|
for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func)
|
||||||
{
|
{
|
||||||
if (!func->hasBody || !(func->type == Func::Constructor ||
|
if (!func->hasBody || !(func->type == Function::eConstructor ||
|
||||||
func->type == Func::CopyConstructor ||
|
func->type == Function::eCopyConstructor ||
|
||||||
func->type == Func::OperatorEqual))
|
func->type == Function::eOperatorEqual))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Mark all variables not used
|
// Mark all variables not used
|
||||||
clearAllVar(usage);
|
clearAllVar(usage);
|
||||||
|
|
||||||
std::list<std::string> callstack;
|
std::list<std::string> callstack;
|
||||||
initializeVarList(*func, callstack, info, usage);
|
initializeVarList(*func, callstack, scope, usage);
|
||||||
|
|
||||||
// Check if any variables are uninitialized
|
// Check if any variables are uninitialized
|
||||||
std::list<Var>::const_iterator var;
|
std::list<Variable>::const_iterator var;
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
for (var = info->varlist.begin(); var != info->varlist.end(); ++var, ++count)
|
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;
|
continue;
|
||||||
|
@ -121,7 +121,7 @@ void CheckClass::constructors()
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Check if this is a class constructor
|
// Check if this is a class constructor
|
||||||
if (var->isClass && func->type == Func::Constructor)
|
if (var->isClass && func->type == Function::eConstructor)
|
||||||
{
|
{
|
||||||
// Unknown type so assume it is initialized
|
// Unknown type so assume it is initialized
|
||||||
if (!var->type)
|
if (!var->type)
|
||||||
|
@ -129,12 +129,12 @@ void CheckClass::constructors()
|
||||||
|
|
||||||
// Known type that doesn't need initialization or
|
// Known type that doesn't need initialization or
|
||||||
// known type that has member variables of an unknown type
|
// known type that has member variables of an unknown type
|
||||||
else if (var->type->needInitialization != SpaceInfo::True)
|
else if (var->type->needInitialization != Scope::True)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// It's non-static and it's not initialized => error
|
// It's non-static and it's not initialized => error
|
||||||
if (func->type == Func::OperatorEqual)
|
if (func->type == Function::eOperatorEqual)
|
||||||
{
|
{
|
||||||
const Token *operStart = 0;
|
const Token *operStart = 0;
|
||||||
if (func->token->str() == "=")
|
if (func->token->str() == "=")
|
||||||
|
@ -145,7 +145,7 @@ void CheckClass::constructors()
|
||||||
bool classNameUsed = false;
|
bool classNameUsed = false;
|
||||||
for (const Token *operTok = operStart; operTok != operStart->link(); operTok = operTok->next())
|
for (const Token *operTok = operStart; operTok != operStart->link(); operTok = operTok->next())
|
||||||
{
|
{
|
||||||
if (operTok->str() == info->className)
|
if (operTok->str() == scope->className)
|
||||||
{
|
{
|
||||||
classNameUsed = true;
|
classNameUsed = true;
|
||||||
break;
|
break;
|
||||||
|
@ -153,21 +153,21 @@ void CheckClass::constructors()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (classNameUsed)
|
if (classNameUsed)
|
||||||
operatorEqVarError(func->token, info->className, var->token->str());
|
operatorEqVarError(func->token, scope->className, var->token->str());
|
||||||
}
|
}
|
||||||
else if (func->access != Private)
|
else if (func->access != Private)
|
||||||
uninitVarError(func->token, info->className, var->token->str());
|
uninitVarError(func->token, scope->className, var->token->str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckClass::assignVar(const std::string &varname, const SpaceInfo *info, std::vector<Usage> &usage)
|
void CheckClass::assignVar(const std::string &varname, const Scope *scope, std::vector<Usage> &usage)
|
||||||
{
|
{
|
||||||
std::list<Var>::const_iterator var;
|
std::list<Variable>::const_iterator var;
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
|
|
||||||
for (var = info->varlist.begin(); var != info->varlist.end(); ++var, ++count)
|
for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var, ++count)
|
||||||
{
|
{
|
||||||
if (var->token->str() == varname)
|
if (var->token->str() == varname)
|
||||||
{
|
{
|
||||||
|
@ -177,12 +177,12 @@ void CheckClass::assignVar(const std::string &varname, const SpaceInfo *info, st
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckClass::initVar(const std::string &varname, const SpaceInfo *info, std::vector<Usage> &usage)
|
void CheckClass::initVar(const std::string &varname, const Scope *scope, std::vector<Usage> &usage)
|
||||||
{
|
{
|
||||||
std::list<Var>::const_iterator var;
|
std::list<Variable>::const_iterator var;
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
|
|
||||||
for (var = info->varlist.begin(); var != info->varlist.end(); ++var, ++count)
|
for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var, ++count)
|
||||||
{
|
{
|
||||||
if (var->token->str() == varname)
|
if (var->token->str() == varname)
|
||||||
{
|
{
|
||||||
|
@ -207,17 +207,17 @@ void CheckClass::clearAllVar(std::vector<Usage> &usage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckClass::isBaseClassFunc(const Token *tok, const SpaceInfo *info)
|
bool CheckClass::isBaseClassFunc(const Token *tok, const Scope *scope)
|
||||||
{
|
{
|
||||||
// Iterate through each base class...
|
// Iterate through each base class...
|
||||||
for (size_t i = 0; i < info->derivedFrom.size(); ++i)
|
for (size_t i = 0; i < scope->derivedFrom.size(); ++i)
|
||||||
{
|
{
|
||||||
const SpaceInfo *derivedFrom = info->derivedFrom[i].spaceInfo;
|
const Scope *derivedFrom = scope->derivedFrom[i].spaceInfo;
|
||||||
|
|
||||||
// Check if base class exists in database
|
// Check if base class exists in database
|
||||||
if (derivedFrom)
|
if (derivedFrom)
|
||||||
{
|
{
|
||||||
std::list<Func>::const_iterator func;
|
std::list<Function>::const_iterator func;
|
||||||
|
|
||||||
for (func = derivedFrom->functionList.begin(); func != derivedFrom->functionList.end(); ++func)
|
for (func = derivedFrom->functionList.begin(); func != derivedFrom->functionList.end(); ++func)
|
||||||
{
|
{
|
||||||
|
@ -234,7 +234,7 @@ bool CheckClass::isBaseClassFunc(const Token *tok, const SpaceInfo *info)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckClass::initializeVarList(const Func &func, std::list<std::string> &callstack, const SpaceInfo *info, std::vector<Usage> &usage)
|
void CheckClass::initializeVarList(const Function &func, std::list<std::string> &callstack, const Scope *scope, std::vector<Usage> &usage)
|
||||||
{
|
{
|
||||||
bool Assign = false;
|
bool Assign = false;
|
||||||
unsigned int indentlevel = 0;
|
unsigned int indentlevel = 0;
|
||||||
|
@ -251,12 +251,12 @@ void CheckClass::initializeVarList(const Func &func, std::list<std::string> &cal
|
||||||
{
|
{
|
||||||
if (Assign && Token::Match(ftok, "%var% ("))
|
if (Assign && Token::Match(ftok, "%var% ("))
|
||||||
{
|
{
|
||||||
initVar(ftok->str(), info, usage);
|
initVar(ftok->str(), scope, usage);
|
||||||
|
|
||||||
// assignment in the initializer..
|
// assignment in the initializer..
|
||||||
// : var(value = x)
|
// : var(value = x)
|
||||||
if (Token::Match(ftok->tokAt(2), "%var% ="))
|
if (Token::Match(ftok->tokAt(2), "%var% ="))
|
||||||
assignVar(ftok->strAt(2), info, usage);
|
assignVar(ftok->strAt(2), scope, usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
Assign |= (ftok->str() == ":");
|
Assign |= (ftok->str() == ":");
|
||||||
|
@ -282,7 +282,7 @@ void CheckClass::initializeVarList(const Func &func, std::list<std::string> &cal
|
||||||
// Variable getting value from stream?
|
// Variable getting value from stream?
|
||||||
if (Token::Match(ftok, ">> %var%"))
|
if (Token::Match(ftok, ">> %var%"))
|
||||||
{
|
{
|
||||||
assignVar(ftok->strAt(1), info, usage);
|
assignVar(ftok->strAt(1), scope, usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Before a new statement there is "[{};)=]"
|
// Before a new statement there is "[{};)=]"
|
||||||
|
@ -302,13 +302,13 @@ void CheckClass::initializeVarList(const Func &func, std::list<std::string> &cal
|
||||||
// Calling member variable function?
|
// Calling member variable function?
|
||||||
if (Token::Match(ftok->next(), "%var% . %var% ("))
|
if (Token::Match(ftok->next(), "%var% . %var% ("))
|
||||||
{
|
{
|
||||||
std::list<Var>::const_iterator var;
|
std::list<Variable>::const_iterator var;
|
||||||
for (var = info->varlist.begin(); var != info->varlist.end(); ++var)
|
for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var)
|
||||||
{
|
{
|
||||||
if (var->token->varId() == ftok->next()->varId())
|
if (var->token->varId() == ftok->next()->varId())
|
||||||
{
|
{
|
||||||
/** @todo false negative: we assume function changes variable state */
|
/** @todo false negative: we assume function changes variable state */
|
||||||
assignVar(ftok->next()->str(), info, usage);
|
assignVar(ftok->next()->str(), scope, usage);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -349,7 +349,7 @@ void CheckClass::initializeVarList(const Func &func, std::list<std::string> &cal
|
||||||
// Clearing array..
|
// Clearing array..
|
||||||
else if (Token::Match(ftok, "memset ( %var% ,"))
|
else if (Token::Match(ftok, "memset ( %var% ,"))
|
||||||
{
|
{
|
||||||
assignVar(ftok->strAt(2), info, usage);
|
assignVar(ftok->strAt(2), scope, usage);
|
||||||
ftok = ftok->next()->link();
|
ftok = ftok->next()->link();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -359,22 +359,22 @@ void CheckClass::initializeVarList(const Func &func, std::list<std::string> &cal
|
||||||
ftok->previous()->str() != "::")
|
ftok->previous()->str() != "::")
|
||||||
{
|
{
|
||||||
// check if member function exists
|
// check if member function exists
|
||||||
std::list<Func>::const_iterator it;
|
std::list<Function>::const_iterator it;
|
||||||
for (it = info->functionList.begin(); it != info->functionList.end(); ++it)
|
for (it = scope->functionList.begin(); it != scope->functionList.end(); ++it)
|
||||||
{
|
{
|
||||||
if (ftok->next()->str() == it->tokenDef->str() && it->type != Func::Constructor)
|
if (ftok->next()->str() == it->tokenDef->str() && it->type != Function::eConstructor)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// member function found
|
// member function found
|
||||||
if (it != info->functionList.end())
|
if (it != scope->functionList.end())
|
||||||
{
|
{
|
||||||
// member function has implementation
|
// member function has implementation
|
||||||
if (it->hasBody)
|
if (it->hasBody)
|
||||||
{
|
{
|
||||||
// initialize variable use list using member function
|
// initialize variable use list using member function
|
||||||
callstack.push_back(ftok->str());
|
callstack.push_back(ftok->str());
|
||||||
initializeVarList(*it, callstack, info, usage);
|
initializeVarList(*it, callstack, scope, usage);
|
||||||
callstack.pop_back();
|
callstack.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,22 +412,22 @@ void CheckClass::initializeVarList(const Func &func, std::list<std::string> &cal
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if member function
|
// check if member function
|
||||||
std::list<Func>::const_iterator it;
|
std::list<Function>::const_iterator it;
|
||||||
for (it = info->functionList.begin(); it != info->functionList.end(); ++it)
|
for (it = scope->functionList.begin(); it != scope->functionList.end(); ++it)
|
||||||
{
|
{
|
||||||
if (ftok->str() == it->tokenDef->str() && it->type != Func::Constructor)
|
if (ftok->str() == it->tokenDef->str() && it->type != Function::eConstructor)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// member function found
|
// member function found
|
||||||
if (it != info->functionList.end())
|
if (it != scope->functionList.end())
|
||||||
{
|
{
|
||||||
// member function has implementation
|
// member function has implementation
|
||||||
if (it->hasBody)
|
if (it->hasBody)
|
||||||
{
|
{
|
||||||
// initialize variable use list using member function
|
// initialize variable use list using member function
|
||||||
callstack.push_back(ftok->str());
|
callstack.push_back(ftok->str());
|
||||||
initializeVarList(*it, callstack, info, usage);
|
initializeVarList(*it, callstack, scope, usage);
|
||||||
callstack.pop_back();
|
callstack.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,7 +442,7 @@ void CheckClass::initializeVarList(const Func &func, std::list<std::string> &cal
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// could be a base class virtual function, so we assume it initializes everything
|
// could be a base class virtual function, so we assume it initializes everything
|
||||||
if (func.type != Func::Constructor && isBaseClassFunc(ftok, info))
|
if (func.type != Function::eConstructor && isBaseClassFunc(ftok, scope))
|
||||||
{
|
{
|
||||||
/** @todo False Negative: we should look at the base class functions to see if they
|
/** @todo False Negative: we should look at the base class functions to see if they
|
||||||
* call any derived class virtual functions that change the derived class state
|
* call any derived class virtual functions that change the derived class state
|
||||||
|
@ -451,7 +451,7 @@ void CheckClass::initializeVarList(const Func &func, std::list<std::string> &cal
|
||||||
}
|
}
|
||||||
|
|
||||||
// has friends, so we assume it initializes everything
|
// has friends, so we assume it initializes everything
|
||||||
if (!info->friendList.empty())
|
if (!scope->friendList.empty())
|
||||||
assignAllVar(usage);
|
assignAllVar(usage);
|
||||||
|
|
||||||
// the function is external and it's neither friend nor inherited virtual function.
|
// the function is external and it's neither friend nor inherited virtual function.
|
||||||
|
@ -471,7 +471,7 @@ void CheckClass::initializeVarList(const Func &func, std::list<std::string> &cal
|
||||||
}
|
}
|
||||||
if (tok->isName())
|
if (tok->isName())
|
||||||
{
|
{
|
||||||
assignVar(tok->str(), info, usage);
|
assignVar(tok->str(), scope, usage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -481,44 +481,44 @@ void CheckClass::initializeVarList(const Func &func, std::list<std::string> &cal
|
||||||
// Assignment of member variable?
|
// Assignment of member variable?
|
||||||
else if (Token::Match(ftok, "%var% ="))
|
else if (Token::Match(ftok, "%var% ="))
|
||||||
{
|
{
|
||||||
assignVar(ftok->str(), info, usage);
|
assignVar(ftok->str(), scope, usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assignment of array item of member variable?
|
// Assignment of array item of member variable?
|
||||||
else if (Token::Match(ftok, "%var% [ %any% ] ="))
|
else if (Token::Match(ftok, "%var% [ %any% ] ="))
|
||||||
{
|
{
|
||||||
assignVar(ftok->str(), info, usage);
|
assignVar(ftok->str(), scope, usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assignment of member of array item of member variable?
|
// Assignment of member of array item of member variable?
|
||||||
else if (Token::Match(ftok, "%var% [ %any% ] . %var% =") ||
|
else if (Token::Match(ftok, "%var% [ %any% ] . %var% =") ||
|
||||||
Token::Match(ftok, "%var% [ %any% ] . %var% . %var% ="))
|
Token::Match(ftok, "%var% [ %any% ] . %var% . %var% ="))
|
||||||
{
|
{
|
||||||
assignVar(ftok->str(), info, usage);
|
assignVar(ftok->str(), scope, usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assignment of array item of member variable?
|
// Assignment of array item of member variable?
|
||||||
else if (Token::Match(ftok, "%var% [ %any% ] [ %any% ] ="))
|
else if (Token::Match(ftok, "%var% [ %any% ] [ %any% ] ="))
|
||||||
{
|
{
|
||||||
assignVar(ftok->str(), info, usage);
|
assignVar(ftok->str(), scope, usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assignment of array item of member variable?
|
// Assignment of array item of member variable?
|
||||||
else if (Token::Match(ftok, "* %var% ="))
|
else if (Token::Match(ftok, "* %var% ="))
|
||||||
{
|
{
|
||||||
assignVar(ftok->next()->str(), info, usage);
|
assignVar(ftok->next()->str(), scope, usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assignment of struct member of member variable?
|
// Assignment of struct member of member variable?
|
||||||
else if (Token::Match(ftok, "%var% . %any% ="))
|
else if (Token::Match(ftok, "%var% . %any% ="))
|
||||||
{
|
{
|
||||||
assignVar(ftok->str(), info, usage);
|
assignVar(ftok->str(), scope, usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The functions 'clear' and 'Clear' are supposed to initialize variable.
|
// The functions 'clear' and 'Clear' are supposed to initialize variable.
|
||||||
if (Token::Match(ftok, "%var% . clear|Clear ("))
|
if (Token::Match(ftok, "%var% . clear|Clear ("))
|
||||||
{
|
{
|
||||||
assignVar(ftok->str(), info, usage);
|
assignVar(ftok->str(), scope, usage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -569,32 +569,32 @@ void CheckClass::privateFunctions()
|
||||||
|
|
||||||
createSymbolDatabase();
|
createSymbolDatabase();
|
||||||
|
|
||||||
std::list<SpaceInfo *>::const_iterator i;
|
std::list<Scope *>::const_iterator i;
|
||||||
|
|
||||||
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
|
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
|
||||||
{
|
{
|
||||||
const SpaceInfo *info = *i;
|
const Scope *scope = *i;
|
||||||
|
|
||||||
// only check classes and structures
|
// only check classes and structures
|
||||||
if (!info->isClassOrStruct())
|
if (!scope->isClassOrStruct())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// don’t check derived classes
|
// don’t check derived classes
|
||||||
if (!info->derivedFrom.empty())
|
if (!scope->derivedFrom.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Locate some class
|
// Locate some class
|
||||||
const Token *tok1 = info->classDef;
|
const Token *tok1 = scope->classDef;
|
||||||
|
|
||||||
// check that the whole class implementation is seen
|
// check that the whole class implementation is seen
|
||||||
bool whole = true;
|
bool whole = true;
|
||||||
std::list<Func>::const_iterator func;
|
std::list<Function>::const_iterator func;
|
||||||
for (func = info->functionList.begin(); func != info->functionList.end(); ++func)
|
for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func)
|
||||||
{
|
{
|
||||||
if (!func->hasBody)
|
if (!func->hasBody)
|
||||||
{
|
{
|
||||||
// empty private copy constructors and assignment operators are OK
|
// empty private copy constructors and assignment operators are OK
|
||||||
if ((func->type == Func::CopyConstructor || func->type == Func::OperatorEqual) && func->access == Private)
|
if ((func->type == Function::eCopyConstructor || func->type == Function::eOperatorEqual) && func->access == Private)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
whole = false;
|
whole = false;
|
||||||
|
@ -609,12 +609,12 @@ void CheckClass::privateFunctions()
|
||||||
|
|
||||||
std::list<const Token *> FuncList;
|
std::list<const Token *> FuncList;
|
||||||
/** @todo embedded class have access to private functions */
|
/** @todo embedded class have access to private functions */
|
||||||
if (!info->getNestedNonFunctions())
|
if (!scope->getNestedNonFunctions())
|
||||||
{
|
{
|
||||||
for (func = info->functionList.begin(); func != info->functionList.end(); ++func)
|
for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func)
|
||||||
{
|
{
|
||||||
// Get private functions..
|
// Get private functions..
|
||||||
if (func->type == Func::Function &&
|
if (func->type == Function::eFunction &&
|
||||||
func->access == Private && func->hasBody)
|
func->access == Private && func->hasBody)
|
||||||
FuncList.push_back(func->tokenDef);
|
FuncList.push_back(func->tokenDef);
|
||||||
}
|
}
|
||||||
|
@ -834,15 +834,15 @@ void CheckClass::operatorEq()
|
||||||
|
|
||||||
createSymbolDatabase();
|
createSymbolDatabase();
|
||||||
|
|
||||||
std::list<SpaceInfo *>::const_iterator i;
|
std::list<Scope *>::const_iterator i;
|
||||||
|
|
||||||
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
|
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
|
||||||
{
|
{
|
||||||
std::list<Func>::const_iterator it;
|
std::list<Function>::const_iterator it;
|
||||||
|
|
||||||
for (it = (*i)->functionList.begin(); it != (*i)->functionList.end(); ++it)
|
for (it = (*i)->functionList.begin(); it != (*i)->functionList.end(); ++it)
|
||||||
{
|
{
|
||||||
if (it->type == Func::OperatorEqual && it->access != Private)
|
if (it->type == Function::eOperatorEqual && it->access != Private)
|
||||||
{
|
{
|
||||||
if (it->token->strAt(-2) == "void")
|
if (it->token->strAt(-2) == "void")
|
||||||
operatorEqReturnError(it->token->tokAt(-2));
|
operatorEqReturnError(it->token->tokAt(-2));
|
||||||
|
@ -861,7 +861,7 @@ void CheckClass::operatorEqReturnError(const Token *tok)
|
||||||
// operator= should return a reference to *this
|
// operator= should return a reference to *this
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
void CheckClass::checkReturnPtrThis(const SpaceInfo *info, const Func *func, const Token *tok, const Token *last)
|
void CheckClass::checkReturnPtrThis(const Scope *scope, const Function *func, const Token *tok, const Token *last)
|
||||||
{
|
{
|
||||||
bool foundReturn = false;
|
bool foundReturn = false;
|
||||||
|
|
||||||
|
@ -871,7 +871,7 @@ void CheckClass::checkReturnPtrThis(const SpaceInfo *info, const Func *func, con
|
||||||
if (tok->str() == "return")
|
if (tok->str() == "return")
|
||||||
{
|
{
|
||||||
foundReturn = true;
|
foundReturn = true;
|
||||||
std::string cast("( " + info->className + " & )");
|
std::string cast("( " + scope->className + " & )");
|
||||||
if (Token::Match(tok->next(), cast.c_str()))
|
if (Token::Match(tok->next(), cast.c_str()))
|
||||||
tok = tok->tokAt(4);
|
tok = tok->tokAt(4);
|
||||||
|
|
||||||
|
@ -879,22 +879,22 @@ void CheckClass::checkReturnPtrThis(const SpaceInfo *info, const Func *func, con
|
||||||
if (Token::Match(tok->tokAt(1), "%any% (") &&
|
if (Token::Match(tok->tokAt(1), "%any% (") &&
|
||||||
tok->tokAt(2)->link()->next()->str() == ";")
|
tok->tokAt(2)->link()->next()->str() == ";")
|
||||||
{
|
{
|
||||||
std::list<Func>::const_iterator it;
|
std::list<Function>::const_iterator it;
|
||||||
|
|
||||||
// check if it is a member function
|
// check if it is a member function
|
||||||
for (it = info->functionList.begin(); it != info->functionList.end(); ++it)
|
for (it = scope->functionList.begin(); it != scope->functionList.end(); ++it)
|
||||||
{
|
{
|
||||||
// check for a regular function with the same name and a bofy
|
// check for a regular function with the same name and a bofy
|
||||||
if (it->type == Func::Function && it->hasBody &&
|
if (it->type == Function::eFunction && it->hasBody &&
|
||||||
it->token->str() == tok->next()->str())
|
it->token->str() == tok->next()->str())
|
||||||
{
|
{
|
||||||
// check for the proper return type
|
// check for the proper return type
|
||||||
if (it->tokenDef->previous()->str() == "&" &&
|
if (it->tokenDef->previous()->str() == "&" &&
|
||||||
it->tokenDef->strAt(-2) == info->className)
|
it->tokenDef->strAt(-2) == scope->className)
|
||||||
{
|
{
|
||||||
// make sure it's not a const function
|
// make sure it's not a const function
|
||||||
if (it->arg->link()->next()->str() != "const")
|
if (it->arg->link()->next()->str() != "const")
|
||||||
checkReturnPtrThis(info, &*it, it->arg->link()->next(), it->arg->link()->next()->link());
|
checkReturnPtrThis(scope, &*it, it->arg->link()->next(), it->arg->link()->next()->link());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -918,29 +918,29 @@ void CheckClass::operatorEqRetRefThis()
|
||||||
|
|
||||||
createSymbolDatabase();
|
createSymbolDatabase();
|
||||||
|
|
||||||
std::list<SpaceInfo *>::const_iterator i;
|
std::list<Scope *>::const_iterator i;
|
||||||
|
|
||||||
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
|
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
|
||||||
{
|
{
|
||||||
const SpaceInfo *info = *i;
|
const Scope *scope = *i;
|
||||||
|
|
||||||
// only check classes and structures
|
// only check classes and structures
|
||||||
if (info->isClassOrStruct())
|
if (scope->isClassOrStruct())
|
||||||
{
|
{
|
||||||
std::list<Func>::const_iterator func;
|
std::list<Function>::const_iterator func;
|
||||||
|
|
||||||
for (func = info->functionList.begin(); func != info->functionList.end(); ++func)
|
for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func)
|
||||||
{
|
{
|
||||||
if (func->type == Func::OperatorEqual && func->hasBody)
|
if (func->type == Function::eOperatorEqual && func->hasBody)
|
||||||
{
|
{
|
||||||
// make sure return signature is correct
|
// make sure return signature is correct
|
||||||
if (Token::Match(func->tokenDef->tokAt(-4), ";|}|{|public:|protected:|private: %type% &") &&
|
if (Token::Match(func->tokenDef->tokAt(-4), ";|}|{|public:|protected:|private: %type% &") &&
|
||||||
func->tokenDef->strAt(-3) == info->className)
|
func->tokenDef->strAt(-3) == scope->className)
|
||||||
{
|
{
|
||||||
// find the ')'
|
// find the ')'
|
||||||
const Token *tok = func->token->next()->link();
|
const Token *tok = func->token->next()->link();
|
||||||
|
|
||||||
checkReturnPtrThis(info, &(*func), tok->tokAt(2), tok->next()->link());
|
checkReturnPtrThis(scope, &(*func), tok->tokAt(2), tok->next()->link());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -974,29 +974,29 @@ void CheckClass::operatorEqToSelf()
|
||||||
|
|
||||||
createSymbolDatabase();
|
createSymbolDatabase();
|
||||||
|
|
||||||
std::list<SpaceInfo *>::const_iterator i;
|
std::list<Scope *>::const_iterator i;
|
||||||
|
|
||||||
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
|
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
|
||||||
{
|
{
|
||||||
const SpaceInfo *info = *i;
|
const Scope *scope = *i;
|
||||||
std::list<Func>::const_iterator it;
|
std::list<Function>::const_iterator it;
|
||||||
|
|
||||||
// skip classes with multiple inheritance
|
// skip classes with multiple inheritance
|
||||||
if (info->derivedFrom.size() > 1)
|
if (scope->derivedFrom.size() > 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (it = info->functionList.begin(); it != info->functionList.end(); ++it)
|
for (it = scope->functionList.begin(); it != scope->functionList.end(); ++it)
|
||||||
{
|
{
|
||||||
if (it->type == Func::OperatorEqual && it->hasBody)
|
if (it->type == Function::eOperatorEqual && it->hasBody)
|
||||||
{
|
{
|
||||||
// make sure return signature is correct
|
// make sure return signature is correct
|
||||||
if (Token::Match(it->tokenDef->tokAt(-4), ";|}|{|public:|protected:|private: %type% &") &&
|
if (Token::Match(it->tokenDef->tokAt(-4), ";|}|{|public:|protected:|private: %type% &") &&
|
||||||
it->tokenDef->strAt(-3) == info->className)
|
it->tokenDef->strAt(-3) == scope->className)
|
||||||
{
|
{
|
||||||
// check for proper function parameter signature
|
// check for proper function parameter signature
|
||||||
if ((Token::Match(it->tokenDef->next(), "( const %var% & )") ||
|
if ((Token::Match(it->tokenDef->next(), "( const %var% & )") ||
|
||||||
Token::Match(it->tokenDef->next(), "( const %var% & %var% )")) &&
|
Token::Match(it->tokenDef->next(), "( const %var% & %var% )")) &&
|
||||||
it->tokenDef->strAt(3) == info->className)
|
it->tokenDef->strAt(3) == scope->className)
|
||||||
{
|
{
|
||||||
// find the parameter name
|
// find the parameter name
|
||||||
const Token *rhs = it->token;
|
const Token *rhs = it->token;
|
||||||
|
@ -1151,18 +1151,18 @@ void CheckClass::virtualDestructor()
|
||||||
|
|
||||||
createSymbolDatabase();
|
createSymbolDatabase();
|
||||||
|
|
||||||
std::list<SpaceInfo *>::const_iterator i;
|
std::list<Scope *>::const_iterator i;
|
||||||
|
|
||||||
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
|
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
|
||||||
{
|
{
|
||||||
const SpaceInfo *info = *i;
|
const Scope *scope = *i;
|
||||||
|
|
||||||
// Skip base classes and namespaces
|
// Skip base classes and namespaces
|
||||||
if (info->derivedFrom.empty())
|
if (scope->derivedFrom.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Find the destructor
|
// Find the destructor
|
||||||
const Func *destructor = info->getDestructor();
|
const Function *destructor = scope->getDestructor();
|
||||||
|
|
||||||
// Check for destructor with implementation
|
// Check for destructor with implementation
|
||||||
if (!destructor || !destructor->hasBody)
|
if (!destructor || !destructor->hasBody)
|
||||||
|
@ -1172,22 +1172,22 @@ void CheckClass::virtualDestructor()
|
||||||
if (destructor->token->tokAt(3)->link() == destructor->token->tokAt(4))
|
if (destructor->token->tokAt(3)->link() == destructor->token->tokAt(4))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const Token *derived = info->classDef;
|
const Token *derived = scope->classDef;
|
||||||
const Token *derivedClass = derived->tokAt(1);
|
const Token *derivedClass = derived->tokAt(1);
|
||||||
|
|
||||||
// Iterate through each base class...
|
// Iterate through each base class...
|
||||||
for (unsigned int j = 0; j < info->derivedFrom.size(); ++j)
|
for (unsigned int j = 0; j < scope->derivedFrom.size(); ++j)
|
||||||
{
|
{
|
||||||
// Check if base class is public and exists in database
|
// Check if base class is public and exists in database
|
||||||
if (info->derivedFrom[j].access != Private && info->derivedFrom[j].spaceInfo)
|
if (scope->derivedFrom[j].access != Private && scope->derivedFrom[j].spaceInfo)
|
||||||
{
|
{
|
||||||
const SpaceInfo *spaceInfo = info->derivedFrom[j].spaceInfo;
|
const Scope *spaceInfo = scope->derivedFrom[j].spaceInfo;
|
||||||
|
|
||||||
// Name of base class..
|
// Name of base class..
|
||||||
const std::string baseName = spaceInfo->className;
|
const std::string baseName = spaceInfo->className;
|
||||||
|
|
||||||
// Find the destructor declaration for the base class.
|
// Find the destructor declaration for the base class.
|
||||||
const Func *base_destructor = spaceInfo->getDestructor();
|
const Function *base_destructor = spaceInfo->getDestructor();
|
||||||
const Token *base = 0;
|
const Token *base = 0;
|
||||||
if (base_destructor)
|
if (base_destructor)
|
||||||
base = base_destructor->token;
|
base = base_destructor->token;
|
||||||
|
@ -1270,22 +1270,22 @@ void CheckClass::checkConst()
|
||||||
|
|
||||||
createSymbolDatabase();
|
createSymbolDatabase();
|
||||||
|
|
||||||
std::list<SpaceInfo *>::const_iterator it;
|
std::list<Scope *>::const_iterator it;
|
||||||
|
|
||||||
for (it = symbolDatabase->spaceInfoList.begin(); it != symbolDatabase->spaceInfoList.end(); ++it)
|
for (it = symbolDatabase->spaceInfoList.begin(); it != symbolDatabase->spaceInfoList.end(); ++it)
|
||||||
{
|
{
|
||||||
const SpaceInfo *info = *it;
|
const Scope *scope = *it;
|
||||||
|
|
||||||
// only check classes and structures
|
// only check classes and structures
|
||||||
if (!info->isClassOrStruct())
|
if (!scope->isClassOrStruct())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
std::list<Func>::const_iterator func;
|
std::list<Function>::const_iterator func;
|
||||||
|
|
||||||
for (func = info->functionList.begin(); func != info->functionList.end(); ++func)
|
for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func)
|
||||||
{
|
{
|
||||||
// does the function have a body?
|
// does the function have a body?
|
||||||
if (func->type == Func::Function && func->hasBody && !func->isFriend && !func->isStatic && !func->isConst && !func->isVirtual)
|
if (func->type == Function::eFunction && func->hasBody && !func->isFriend && !func->isStatic && !func->isConst && !func->isVirtual)
|
||||||
{
|
{
|
||||||
// get last token of return type
|
// get last token of return type
|
||||||
const Token *previous = func->tokenDef->isName() ? func->token->previous() : func->token->tokAt(-2);
|
const Token *previous = func->tokenDef->isName() ? func->token->previous() : func->token->tokAt(-2);
|
||||||
|
@ -1343,18 +1343,18 @@ void CheckClass::checkConst()
|
||||||
const Token *paramEnd = func->arg->link();
|
const Token *paramEnd = func->arg->link();
|
||||||
|
|
||||||
// check if base class function is virtual
|
// check if base class function is virtual
|
||||||
if (!info->derivedFrom.empty())
|
if (!scope->derivedFrom.empty())
|
||||||
{
|
{
|
||||||
if (isVirtualFunc(info, func->tokenDef))
|
if (isVirtualFunc(scope, func->tokenDef))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if nothing non-const was found. write error..
|
// if nothing non-const was found. write error..
|
||||||
if (checkConstFunc(info, paramEnd))
|
if (checkConstFunc(scope, paramEnd))
|
||||||
{
|
{
|
||||||
std::string classname = info->className;
|
std::string classname = scope->className;
|
||||||
const SpaceInfo *nest = info->nestedIn;
|
const Scope *nest = scope->nestedIn;
|
||||||
while (nest && nest->type != SpaceInfo::Global)
|
while (nest && nest->type != Scope::eGlobal)
|
||||||
{
|
{
|
||||||
classname = std::string(nest->className + "::" + classname);
|
classname = std::string(nest->className + "::" + classname);
|
||||||
nest = nest->nestedIn;
|
nest = nest->nestedIn;
|
||||||
|
@ -1378,7 +1378,7 @@ void CheckClass::checkConst()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckClass::isMemberVar(const SpaceInfo *info, const Token *tok)
|
bool CheckClass::isMemberVar(const Scope *scope, const Token *tok)
|
||||||
{
|
{
|
||||||
const Token *tok1 = tok;
|
const Token *tok1 = tok;
|
||||||
|
|
||||||
|
@ -1397,11 +1397,11 @@ bool CheckClass::isMemberVar(const SpaceInfo *info, const Token *tok)
|
||||||
tok = tok->tokAt(2);
|
tok = tok->tokAt(2);
|
||||||
|
|
||||||
// ignore class namespace
|
// ignore class namespace
|
||||||
if (tok->str() == info->className && tok->next()->str() == "::")
|
if (tok->str() == scope->className && tok->next()->str() == "::")
|
||||||
tok = tok->tokAt(2);
|
tok = tok->tokAt(2);
|
||||||
|
|
||||||
std::list<Var>::const_iterator var;
|
std::list<Variable>::const_iterator var;
|
||||||
for (var = info->varlist.begin(); var != info->varlist.end(); ++var)
|
for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var)
|
||||||
{
|
{
|
||||||
if (var->token->str() == tok->str())
|
if (var->token->str() == tok->str())
|
||||||
{
|
{
|
||||||
|
@ -1410,13 +1410,13 @@ bool CheckClass::isMemberVar(const SpaceInfo *info, const Token *tok)
|
||||||
}
|
}
|
||||||
|
|
||||||
// not found in this class
|
// not found in this class
|
||||||
if (!info->derivedFrom.empty())
|
if (!scope->derivedFrom.empty())
|
||||||
{
|
{
|
||||||
// check each base class
|
// check each base class
|
||||||
for (unsigned int i = 0; i < info->derivedFrom.size(); ++i)
|
for (unsigned int i = 0; i < scope->derivedFrom.size(); ++i)
|
||||||
{
|
{
|
||||||
// find the base class
|
// find the base class
|
||||||
const SpaceInfo *spaceInfo = info->derivedFrom[i].spaceInfo;
|
const Scope *spaceInfo = scope->derivedFrom[i].spaceInfo;
|
||||||
|
|
||||||
// find the function in the base class
|
// find the function in the base class
|
||||||
if (spaceInfo)
|
if (spaceInfo)
|
||||||
|
@ -1430,24 +1430,24 @@ bool CheckClass::isMemberVar(const SpaceInfo *info, const Token *tok)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckClass::isConstMemberFunc(const SpaceInfo *info, const Token *tok)
|
bool CheckClass::isConstMemberFunc(const Scope *scope, const Token *tok)
|
||||||
{
|
{
|
||||||
std::list<Func>::const_iterator func;
|
std::list<Function>::const_iterator func;
|
||||||
|
|
||||||
for (func = info->functionList.begin(); func != info->functionList.end(); ++func)
|
for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func)
|
||||||
{
|
{
|
||||||
if (func->tokenDef->str() == tok->str() && func->isConst)
|
if (func->tokenDef->str() == tok->str() && func->isConst)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// not found in this class
|
// not found in this class
|
||||||
if (!info->derivedFrom.empty())
|
if (!scope->derivedFrom.empty())
|
||||||
{
|
{
|
||||||
// check each base class
|
// check each base class
|
||||||
for (unsigned int i = 0; i < info->derivedFrom.size(); ++i)
|
for (unsigned int i = 0; i < scope->derivedFrom.size(); ++i)
|
||||||
{
|
{
|
||||||
// find the base class
|
// find the base class
|
||||||
const SpaceInfo *spaceInfo = info->derivedFrom[i].spaceInfo;
|
const Scope *spaceInfo = scope->derivedFrom[i].spaceInfo;
|
||||||
|
|
||||||
// find the function in the base class
|
// find the function in the base class
|
||||||
if (spaceInfo)
|
if (spaceInfo)
|
||||||
|
@ -1461,7 +1461,7 @@ bool CheckClass::isConstMemberFunc(const SpaceInfo *info, const Token *tok)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckClass::checkConstFunc(const SpaceInfo *info, const Token *tok)
|
bool CheckClass::checkConstFunc(const Scope *scope, const Token *tok)
|
||||||
{
|
{
|
||||||
// if the function doesn't have any assignment nor function call,
|
// if the function doesn't have any assignment nor function call,
|
||||||
// it can be a const function..
|
// it can be a const function..
|
||||||
|
@ -1483,12 +1483,12 @@ bool CheckClass::checkConstFunc(const SpaceInfo *info, const Token *tok)
|
||||||
(tok1->str().find("=") == 1 &&
|
(tok1->str().find("=") == 1 &&
|
||||||
tok1->str().find_first_of("<!>") == std::string::npos))
|
tok1->str().find_first_of("<!>") == std::string::npos))
|
||||||
{
|
{
|
||||||
if (tok1->previous()->varId() == 0 && !info->derivedFrom.empty())
|
if (tok1->previous()->varId() == 0 && !scope->derivedFrom.empty())
|
||||||
{
|
{
|
||||||
isconst = false;
|
isconst = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (isMemberVar(info, tok1->previous()))
|
else if (isMemberVar(scope, tok1->previous()))
|
||||||
{
|
{
|
||||||
isconst = false;
|
isconst = false;
|
||||||
break;
|
break;
|
||||||
|
@ -1515,7 +1515,7 @@ bool CheckClass::checkConstFunc(const SpaceInfo *info, const Token *tok)
|
||||||
}
|
}
|
||||||
|
|
||||||
// streaming: <<
|
// streaming: <<
|
||||||
else if (tok1->str() == "<<" && isMemberVar(info, tok1->previous()))
|
else if (tok1->str() == "<<" && isMemberVar(scope, tok1->previous()))
|
||||||
{
|
{
|
||||||
isconst = false;
|
isconst = false;
|
||||||
break;
|
break;
|
||||||
|
@ -1532,7 +1532,7 @@ bool CheckClass::checkConstFunc(const SpaceInfo *info, const Token *tok)
|
||||||
else if (Token::Match(tok1, "%var% (") &&
|
else if (Token::Match(tok1, "%var% (") &&
|
||||||
!(Token::Match(tok1, "return|c_str|if|string") || tok1->isStandardType()))
|
!(Token::Match(tok1, "return|c_str|if|string") || tok1->isStandardType()))
|
||||||
{
|
{
|
||||||
if (!isConstMemberFunc(info, tok1))
|
if (!isConstMemberFunc(scope, tok1))
|
||||||
{
|
{
|
||||||
isconst = false;
|
isconst = false;
|
||||||
break;
|
break;
|
||||||
|
@ -1558,17 +1558,17 @@ bool CheckClass::checkConstFunc(const SpaceInfo *info, const Token *tok)
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
// check if this function is defined virtual in the base classes
|
// check if this function is defined virtual in the base classes
|
||||||
bool CheckClass::isVirtualFunc(const SpaceInfo *info, const Token *functionToken) const
|
bool CheckClass::isVirtualFunc(const Scope *scope, const Token *functionToken) const
|
||||||
{
|
{
|
||||||
// check each base class
|
// check each base class
|
||||||
for (unsigned int i = 0; i < info->derivedFrom.size(); ++i)
|
for (unsigned int i = 0; i < scope->derivedFrom.size(); ++i)
|
||||||
{
|
{
|
||||||
// check if base class exists in database
|
// check if base class exists in database
|
||||||
if (info->derivedFrom[i].spaceInfo)
|
if (scope->derivedFrom[i].spaceInfo)
|
||||||
{
|
{
|
||||||
const SpaceInfo *derivedFrom = info->derivedFrom[i].spaceInfo;
|
const Scope *derivedFrom = scope->derivedFrom[i].spaceInfo;
|
||||||
|
|
||||||
std::list<Func>::const_iterator func;
|
std::list<Function>::const_iterator func;
|
||||||
|
|
||||||
// check if function defined in base class
|
// check if function defined in base class
|
||||||
for (func = derivedFrom->functionList.begin(); func != derivedFrom->functionList.end(); ++func)
|
for (func = derivedFrom->functionList.begin(); func != derivedFrom->functionList.end(); ++func)
|
||||||
|
@ -1597,7 +1597,7 @@ bool CheckClass::isVirtualFunc(const SpaceInfo *info, const Token *functionToken
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for matching function parameters
|
// check for matching function parameters
|
||||||
if (returnMatch && symbolDatabase->argsMatch(info, tok->tokAt(2), functionToken->tokAt(2), std::string(""), 0))
|
if (returnMatch && symbolDatabase->argsMatch(scope, tok->tokAt(2), functionToken->tokAt(2), std::string(""), 0))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,18 +163,18 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
// operatorEqRetRefThis helper function
|
// operatorEqRetRefThis helper function
|
||||||
void checkReturnPtrThis(const SpaceInfo *info, const Func *func, const Token *tok, const Token *last);
|
void checkReturnPtrThis(const Scope *scope, const Function *func, const Token *tok, const Token *last);
|
||||||
|
|
||||||
// operatorEqToSelf helper functions
|
// operatorEqToSelf helper functions
|
||||||
bool hasDeallocation(const Token *first, const Token *last);
|
bool hasDeallocation(const Token *first, const Token *last);
|
||||||
bool hasAssignSelf(const Token *first, const Token *last, const Token *rhs);
|
bool hasAssignSelf(const Token *first, const Token *last, const Token *rhs);
|
||||||
|
|
||||||
// checkConst helper functions
|
// checkConst helper functions
|
||||||
bool isMemberVar(const SpaceInfo *info, const Token *tok);
|
bool isMemberVar(const Scope *scope, const Token *tok);
|
||||||
bool isConstMemberFunc(const SpaceInfo *info, const Token *tok);
|
bool isConstMemberFunc(const Scope *scope, const Token *tok);
|
||||||
bool checkConstFunc(const SpaceInfo *info, const Token *tok);
|
bool checkConstFunc(const Scope *scope, const Token *tok);
|
||||||
/** @brief check if this function is virtual in the base classes */
|
/** @brief check if this function is virtual in the base classes */
|
||||||
bool isVirtualFunc(const SpaceInfo *info, const Token *functionToken) const;
|
bool isVirtualFunc(const Scope *scope, const Token *functionToken) const;
|
||||||
|
|
||||||
// constructors helper function
|
// constructors helper function
|
||||||
/** @brief Information about a member variable. Used when checking for uninitialized variables */
|
/** @brief Information about a member variable. Used when checking for uninitialized variables */
|
||||||
|
@ -189,23 +189,23 @@ private:
|
||||||
bool init;
|
bool init;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool isBaseClassFunc(const Token *tok, const SpaceInfo *info);
|
bool isBaseClassFunc(const Token *tok, const Scope *scope);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief assign a variable in the varlist
|
* @brief assign a variable in the varlist
|
||||||
* @param varname name of variable to mark assigned
|
* @param varname name of variable to mark assigned
|
||||||
* @param info pointer to variable SpaceInfo
|
* @param scope pointer to variable Scope
|
||||||
* @param usage reference to usage vector
|
* @param usage reference to usage vector
|
||||||
*/
|
*/
|
||||||
void assignVar(const std::string &varname, const SpaceInfo *info, std::vector<Usage> &usage);
|
void assignVar(const std::string &varname, const Scope *scope, std::vector<Usage> &usage);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief initialize a variable in the varlist
|
* @brief initialize a variable in the varlist
|
||||||
* @param varname name of variable to mark initialized
|
* @param varname name of variable to mark initialized
|
||||||
* @param info pointer to variable SpaceInfo
|
* @param scope pointer to variable Scope
|
||||||
* @param usage reference to usage vector
|
* @param usage reference to usage vector
|
||||||
*/
|
*/
|
||||||
void initVar(const std::string &varname, const SpaceInfo *info, std::vector<Usage> &usage);
|
void initVar(const std::string &varname, const Scope *scope, std::vector<Usage> &usage);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief set all variables in list assigned
|
* @brief set all variables in list assigned
|
||||||
|
@ -223,10 +223,10 @@ private:
|
||||||
* @brief parse a scope for a constructor or member function and set the "init" flags in the provided varlist
|
* @brief parse a scope for a constructor or member function and set the "init" flags in the provided varlist
|
||||||
* @param func reference to the function that should be checked
|
* @param func reference to the function that should be checked
|
||||||
* @param callstack the function doesn't look into recursive function calls.
|
* @param callstack the function doesn't look into recursive function calls.
|
||||||
* @param info pointer to variable SpaceInfo
|
* @param scope pointer to variable Scope
|
||||||
* @param usage reference to usage vector
|
* @param usage reference to usage vector
|
||||||
*/
|
*/
|
||||||
void initializeVarList(const Func &func, std::list<std::string> &callstack, const SpaceInfo *info, std::vector<Usage> &usage);
|
void initializeVarList(const Function &func, std::list<std::string> &callstack, const Scope *scope, std::vector<Usage> &usage);
|
||||||
};
|
};
|
||||||
/// @}
|
/// @}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
|
@ -565,19 +565,19 @@ void CheckMemoryLeakInFunction::parse_noreturn()
|
||||||
noreturn.insert("errx");
|
noreturn.insert("errx");
|
||||||
noreturn.insert("verrx");
|
noreturn.insert("verrx");
|
||||||
|
|
||||||
std::list<SpaceInfo *>::const_iterator i;
|
std::list<Scope *>::const_iterator i;
|
||||||
|
|
||||||
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
|
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
|
||||||
{
|
{
|
||||||
const SpaceInfo *info = *i;
|
const Scope *scope = *i;
|
||||||
|
|
||||||
// only check functions
|
// only check functions
|
||||||
if (info->type != SpaceInfo::Function)
|
if (scope->type != Scope::eFunction)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// parse this function to check if it contains an "exit" call..
|
// parse this function to check if it contains an "exit" call..
|
||||||
unsigned int indentlevel = 1;
|
unsigned int indentlevel = 1;
|
||||||
for (const Token *tok2 = info->classStart->next(); tok2; tok2 = tok2->next())
|
for (const Token *tok2 = scope->classStart->next(); tok2; tok2 = tok2->next())
|
||||||
{
|
{
|
||||||
if (tok2->str() == "{")
|
if (tok2->str() == "{")
|
||||||
++indentlevel;
|
++indentlevel;
|
||||||
|
@ -589,7 +589,7 @@ void CheckMemoryLeakInFunction::parse_noreturn()
|
||||||
}
|
}
|
||||||
if (Token::Match(tok2->previous(), "[;{}] exit ("))
|
if (Token::Match(tok2->previous(), "[;{}] exit ("))
|
||||||
{
|
{
|
||||||
noreturn.insert(info->className);
|
noreturn.insert(scope->className);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -597,7 +597,7 @@ void CheckMemoryLeakInFunction::parse_noreturn()
|
||||||
// This function is not a noreturn function
|
// This function is not a noreturn function
|
||||||
if (indentlevel == 0)
|
if (indentlevel == 0)
|
||||||
{
|
{
|
||||||
notnoreturn.insert(info->className);
|
notnoreturn.insert(scope->className);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2491,25 +2491,25 @@ void CheckMemoryLeakInFunction::checkScope(const Token *Tok1, const std::string
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
void CheckMemoryLeakInFunction::checkReallocUsage()
|
void CheckMemoryLeakInFunction::checkReallocUsage()
|
||||||
{
|
{
|
||||||
std::list<SpaceInfo *>::const_iterator i;
|
std::list<Scope *>::const_iterator i;
|
||||||
|
|
||||||
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
|
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
|
||||||
{
|
{
|
||||||
const SpaceInfo *info = *i;
|
const Scope *scope = *i;
|
||||||
|
|
||||||
// only check functions
|
// only check functions
|
||||||
if (info->type != SpaceInfo::Function)
|
if (scope->type != Scope::eFunction)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Record the varid's of the function parameters
|
// Record the varid's of the function parameters
|
||||||
std::set<unsigned int> parameterVarIds;
|
std::set<unsigned int> parameterVarIds;
|
||||||
for (const Token *tok2 = info->classDef->next(); tok2 && tok2->str() != ")"; tok2 = tok2->next())
|
for (const Token *tok2 = scope->classDef->next(); tok2 && tok2->str() != ")"; tok2 = tok2->next())
|
||||||
{
|
{
|
||||||
if (tok2->varId() != 0)
|
if (tok2->varId() != 0)
|
||||||
parameterVarIds.insert(tok2->varId());
|
parameterVarIds.insert(tok2->varId());
|
||||||
}
|
}
|
||||||
|
|
||||||
const Token *tok = info->classStart;
|
const Token *tok = scope->classStart;
|
||||||
const Token *startOfFunction = tok;
|
const Token *startOfFunction = tok;
|
||||||
|
|
||||||
// Search for the "var = realloc(var, 100);" pattern within this function
|
// Search for the "var = realloc(var, 100);" pattern within this function
|
||||||
|
@ -2644,19 +2644,19 @@ void CheckMemoryLeakInFunction::check()
|
||||||
// fill the "noreturn"
|
// fill the "noreturn"
|
||||||
parse_noreturn();
|
parse_noreturn();
|
||||||
|
|
||||||
std::list<SpaceInfo *>::const_iterator i;
|
std::list<Scope *>::const_iterator i;
|
||||||
|
|
||||||
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
|
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
|
||||||
{
|
{
|
||||||
const SpaceInfo *info = *i;
|
const Scope *scope = *i;
|
||||||
|
|
||||||
// only check functions
|
// only check functions
|
||||||
if (info->type != SpaceInfo::Function)
|
if (scope->type != Scope::eFunction)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const Token *tok = info->classStart;
|
const Token *tok = scope->classStart;
|
||||||
const Token *tok1 = info->classDef->next();
|
const Token *tok1 = scope->classDef->next();
|
||||||
bool classmember = info->functionOf != NULL;
|
bool classmember = scope->functionOf != NULL;
|
||||||
|
|
||||||
parseFunctionScope(tok, tok1, classmember);
|
parseFunctionScope(tok, tok1, classmember);
|
||||||
}
|
}
|
||||||
|
@ -2701,17 +2701,17 @@ void CheckMemoryLeakInClass::check()
|
||||||
{
|
{
|
||||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||||
|
|
||||||
std::list<SpaceInfo *>::const_iterator i;
|
std::list<Scope *>::const_iterator i;
|
||||||
|
|
||||||
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
|
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
|
||||||
{
|
{
|
||||||
const SpaceInfo *info = *i;
|
const Scope *scope = *i;
|
||||||
|
|
||||||
// only check classes and structures
|
// only check classes and structures
|
||||||
if (info->type == SpaceInfo::Class)
|
if (scope->type == Scope::eClass)
|
||||||
{
|
{
|
||||||
std::list<Var>::const_iterator var;
|
std::list<Variable>::const_iterator var;
|
||||||
for (var = info->varlist.begin(); var != info->varlist.end(); ++var)
|
for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var)
|
||||||
{
|
{
|
||||||
if (!var->isStatic && var->token->previous()->str() == "*")
|
if (!var->isStatic && var->token->previous()->str() == "*")
|
||||||
{
|
{
|
||||||
|
@ -2719,9 +2719,9 @@ void CheckMemoryLeakInClass::check()
|
||||||
if (var->token->tokAt(-2)->isStandardType())
|
if (var->token->tokAt(-2)->isStandardType())
|
||||||
{
|
{
|
||||||
if (var->access == Private)
|
if (var->access == Private)
|
||||||
checkPublicFunctions(info, var->token);
|
checkPublicFunctions(scope, var->token);
|
||||||
|
|
||||||
variable(info, var->token);
|
variable(scope, var->token);
|
||||||
}
|
}
|
||||||
|
|
||||||
// known class?
|
// known class?
|
||||||
|
@ -2731,9 +2731,9 @@ void CheckMemoryLeakInClass::check()
|
||||||
if (var->type->derivedFrom.empty() && var->type->numConstructors == 0)
|
if (var->type->derivedFrom.empty() && var->type->numConstructors == 0)
|
||||||
{
|
{
|
||||||
if (var->access == Private)
|
if (var->access == Private)
|
||||||
checkPublicFunctions(info, var->token);
|
checkPublicFunctions(scope, var->token);
|
||||||
|
|
||||||
variable(info, var->token);
|
variable(scope, var->token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2743,10 +2743,10 @@ void CheckMemoryLeakInClass::check()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CheckMemoryLeakInClass::variable(const SpaceInfo *classinfo, const Token *tokVarname)
|
void CheckMemoryLeakInClass::variable(const Scope *scope, const Token *tokVarname)
|
||||||
{
|
{
|
||||||
const std::string varname = tokVarname->strAt(0);
|
const std::string varname = tokVarname->strAt(0);
|
||||||
const std::string classname = classinfo->className;
|
const std::string classname = scope->className;
|
||||||
|
|
||||||
// Check if member variable has been allocated and deallocated..
|
// Check if member variable has been allocated and deallocated..
|
||||||
CheckMemoryLeak::AllocType Alloc = CheckMemoryLeak::No;
|
CheckMemoryLeak::AllocType Alloc = CheckMemoryLeak::No;
|
||||||
|
@ -2756,12 +2756,12 @@ void CheckMemoryLeakInClass::variable(const SpaceInfo *classinfo, const Token *t
|
||||||
bool deallocInDestructor = false;
|
bool deallocInDestructor = false;
|
||||||
|
|
||||||
// Inspect member functions
|
// Inspect member functions
|
||||||
std::list<Func>::const_iterator func;
|
std::list<Function>::const_iterator func;
|
||||||
for (func = classinfo->functionList.begin(); func != classinfo->functionList.end(); ++func)
|
for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func)
|
||||||
{
|
{
|
||||||
const Token *functionToken = func->token;
|
const Token *functionToken = func->token;
|
||||||
const bool constructor = func->type == Func::Constructor;
|
const bool constructor = func->type == Function::eConstructor;
|
||||||
const bool destructor = func->type == Func::Destructor;
|
const bool destructor = func->type == Function::eDestructor;
|
||||||
unsigned int indent = 0;
|
unsigned int indent = 0;
|
||||||
bool initlist = false;
|
bool initlist = false;
|
||||||
for (const Token *tok = functionToken; tok; tok = tok->next())
|
for (const Token *tok = functionToken; tok; tok = tok->next())
|
||||||
|
@ -2795,7 +2795,7 @@ void CheckMemoryLeakInClass::variable(const SpaceInfo *classinfo, const Token *t
|
||||||
// Foo::var1 = ..
|
// Foo::var1 = ..
|
||||||
// bail out when not same class
|
// bail out when not same class
|
||||||
if (Token::simpleMatch(tok->previous(), "::") &&
|
if (Token::simpleMatch(tok->previous(), "::") &&
|
||||||
tok->strAt(-2) != classinfo->className)
|
tok->strAt(-2) != scope->className)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
AllocType alloc = getAllocationType(tok->tokAt((indent > 0) ? 2 : 3), 0);
|
AllocType alloc = getAllocationType(tok->tokAt((indent > 0) ? 2 : 3), 0);
|
||||||
|
@ -2826,7 +2826,7 @@ void CheckMemoryLeakInClass::variable(const SpaceInfo *classinfo, const Token *t
|
||||||
AllocType dealloc = getDeallocationType(tok, varname);
|
AllocType dealloc = getDeallocationType(tok, varname);
|
||||||
if (dealloc == No)
|
if (dealloc == No)
|
||||||
{
|
{
|
||||||
std::string temp = classinfo->className + " :: " + varname;
|
std::string temp = scope->className + " :: " + varname;
|
||||||
dealloc = getDeallocationType(tok, temp);
|
dealloc = getDeallocationType(tok, temp);
|
||||||
}
|
}
|
||||||
if (dealloc == No)
|
if (dealloc == No)
|
||||||
|
@ -2879,7 +2879,7 @@ void CheckMemoryLeakInClass::variable(const SpaceInfo *classinfo, const Token *t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CheckMemoryLeakInClass::checkPublicFunctions(const SpaceInfo *spaceinfo, const Token *classtok)
|
void CheckMemoryLeakInClass::checkPublicFunctions(const Scope *scope, const Token *classtok)
|
||||||
{
|
{
|
||||||
// Check that public functions deallocate the pointers that they allocate.
|
// Check that public functions deallocate the pointers that they allocate.
|
||||||
// There is no checking how these functions are used and therefore it
|
// There is no checking how these functions are used and therefore it
|
||||||
|
@ -2891,11 +2891,11 @@ void CheckMemoryLeakInClass::checkPublicFunctions(const SpaceInfo *spaceinfo, co
|
||||||
|
|
||||||
// Parse public functions..
|
// Parse public functions..
|
||||||
// If they allocate member variables, they should also deallocate
|
// If they allocate member variables, they should also deallocate
|
||||||
std::list<Func>::const_iterator func;
|
std::list<Function>::const_iterator func;
|
||||||
|
|
||||||
for (func = spaceinfo->functionList.begin(); func != spaceinfo->functionList.end(); ++func)
|
for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func)
|
||||||
{
|
{
|
||||||
if (func->type != Func::Constructor &&
|
if (func->type != Function::eConstructor &&
|
||||||
func->access == Public && func->hasBody)
|
func->access == Public && func->hasBody)
|
||||||
{
|
{
|
||||||
const Token *tok2 = func->token;
|
const Token *tok2 = func->token;
|
||||||
|
@ -2908,7 +2908,7 @@ void CheckMemoryLeakInClass::checkPublicFunctions(const SpaceInfo *spaceinfo, co
|
||||||
publicAllocationError(tok2, tok2->strAt(1));
|
publicAllocationError(tok2, tok2->strAt(1));
|
||||||
}
|
}
|
||||||
else if (Token::Match(tok2, "{|}|; %type% :: %varid% =", varid) &&
|
else if (Token::Match(tok2, "{|}|; %type% :: %varid% =", varid) &&
|
||||||
tok2->next()->str() == spaceinfo->className)
|
tok2->next()->str() == scope->className)
|
||||||
{
|
{
|
||||||
const CheckMemoryLeak::AllocType alloc = getAllocationType(tok2->tokAt(5), varid);
|
const CheckMemoryLeak::AllocType alloc = getAllocationType(tok2->tokAt(5), varid);
|
||||||
if (alloc != CheckMemoryLeak::No)
|
if (alloc != CheckMemoryLeak::No)
|
||||||
|
@ -3166,18 +3166,18 @@ void CheckMemoryLeakNoVar::check()
|
||||||
|
|
||||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||||
|
|
||||||
std::list<SpaceInfo *>::const_iterator i;
|
std::list<Scope *>::const_iterator i;
|
||||||
|
|
||||||
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
|
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
|
||||||
{
|
{
|
||||||
SpaceInfo *info = *i;
|
Scope *scope = *i;
|
||||||
|
|
||||||
// only check functions
|
// only check functions
|
||||||
if (info->type != SpaceInfo::Function)
|
if (scope->type != Scope::eFunction)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// goto the "}" that ends the executable scope..
|
// goto the "}" that ends the executable scope..
|
||||||
const Token *tok = info->classEnd;
|
const Token *tok = scope->classEnd;
|
||||||
|
|
||||||
// parse the executable scope until tok is reached...
|
// parse the executable scope until tok is reached...
|
||||||
for (const Token *tok2 = tok->link(); tok2 && tok2 != tok; tok2 = tok2->next())
|
for (const Token *tok2 = tok->link(); tok2 && tok2 != tok; tok2 = tok2->next())
|
||||||
|
|
|
@ -387,10 +387,10 @@ public:
|
||||||
void check();
|
void check();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void variable(const SpaceInfo *spaceinfo, const Token *tokVarname);
|
void variable(const Scope *scope, const Token *tokVarname);
|
||||||
|
|
||||||
/** Public functions: possible double-allocation */
|
/** Public functions: possible double-allocation */
|
||||||
void checkPublicFunctions(const SpaceInfo *spaceinfo, const Token *classtok);
|
void checkPublicFunctions(const Scope *scope, const Token *classtok);
|
||||||
void publicAllocationError(const Token *tok, const std::string &varname);
|
void publicAllocationError(const Token *tok, const std::string &varname);
|
||||||
|
|
||||||
void getErrorMessages(ErrorLogger * /*errorLogger*/, const Settings * /*settings*/)
|
void getErrorMessages(ErrorLogger * /*errorLogger*/, const Settings * /*settings*/)
|
||||||
|
|
|
@ -562,27 +562,27 @@ static bool isOp(const Token *tok)
|
||||||
/**
|
/**
|
||||||
* @brief This class is used to capture the control flow within a function.
|
* @brief This class is used to capture the control flow within a function.
|
||||||
*/
|
*/
|
||||||
class Scope
|
class ScopeInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Scope() : _token(NULL), _parent(NULL) { }
|
ScopeInfo() : _token(NULL), _parent(NULL) { }
|
||||||
Scope(const Token *token, Scope *parent_) : _token(token), _parent(parent_) { }
|
ScopeInfo(const Token *token, ScopeInfo *parent_) : _token(token), _parent(parent_) { }
|
||||||
~Scope();
|
~ScopeInfo();
|
||||||
|
|
||||||
Scope *parent()
|
ScopeInfo *parent()
|
||||||
{
|
{
|
||||||
return _parent;
|
return _parent;
|
||||||
}
|
}
|
||||||
Scope *addChild(const Token *token);
|
ScopeInfo *addChild(const Token *token);
|
||||||
void remove(Scope *scope);
|
void remove(ScopeInfo *scope);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Token *_token;
|
const Token *_token;
|
||||||
Scope *_parent;
|
ScopeInfo *_parent;
|
||||||
std::list<Scope *> _children;
|
std::list<ScopeInfo *> _children;
|
||||||
};
|
};
|
||||||
|
|
||||||
Scope::~Scope()
|
ScopeInfo::~ScopeInfo()
|
||||||
{
|
{
|
||||||
while (!_children.empty())
|
while (!_children.empty())
|
||||||
{
|
{
|
||||||
|
@ -591,18 +591,18 @@ Scope::~Scope()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Scope *Scope::addChild(const Token *token)
|
ScopeInfo *ScopeInfo::addChild(const Token *token)
|
||||||
{
|
{
|
||||||
Scope *temp = new Scope(token, this);
|
ScopeInfo *temp = new ScopeInfo(token, this);
|
||||||
|
|
||||||
_children.push_back(temp);
|
_children.push_back(temp);
|
||||||
|
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scope::remove(Scope *scope)
|
void ScopeInfo::remove(ScopeInfo *scope)
|
||||||
{
|
{
|
||||||
std::list<Scope *>::iterator it;
|
std::list<ScopeInfo *>::iterator it;
|
||||||
|
|
||||||
for (it = _children.begin(); it != _children.end(); ++it)
|
for (it = _children.begin(); it != _children.end(); ++it)
|
||||||
{
|
{
|
||||||
|
@ -629,7 +629,7 @@ public:
|
||||||
public:
|
public:
|
||||||
VariableUsage(const Token *name = 0,
|
VariableUsage(const Token *name = 0,
|
||||||
VariableType type = standard,
|
VariableType type = standard,
|
||||||
Scope *scope = NULL,
|
ScopeInfo *scope = NULL,
|
||||||
bool read = false,
|
bool read = false,
|
||||||
bool write = false,
|
bool write = false,
|
||||||
bool modified = false,
|
bool modified = false,
|
||||||
|
@ -659,13 +659,13 @@ public:
|
||||||
|
|
||||||
const Token *_name;
|
const Token *_name;
|
||||||
VariableType _type;
|
VariableType _type;
|
||||||
Scope *_scope;
|
ScopeInfo *_scope;
|
||||||
bool _read;
|
bool _read;
|
||||||
bool _write;
|
bool _write;
|
||||||
bool _modified; // read/modify/write
|
bool _modified; // read/modify/write
|
||||||
bool _allocateMemory;
|
bool _allocateMemory;
|
||||||
std::set<unsigned int> _aliases;
|
std::set<unsigned int> _aliases;
|
||||||
std::set<Scope *> _assignments;
|
std::set<ScopeInfo *> _assignments;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<unsigned int, VariableUsage> VariableMap;
|
typedef std::map<unsigned int, VariableUsage> VariableMap;
|
||||||
|
@ -678,7 +678,7 @@ public:
|
||||||
{
|
{
|
||||||
return _varUsage;
|
return _varUsage;
|
||||||
}
|
}
|
||||||
void addVar(const Token *name, VariableType type, Scope *scope, bool write_);
|
void addVar(const Token *name, VariableType type, ScopeInfo *scope, bool write_);
|
||||||
void allocateMemory(unsigned int varid);
|
void allocateMemory(unsigned int varid);
|
||||||
void read(unsigned int varid);
|
void read(unsigned int varid);
|
||||||
void readAliases(unsigned int varid);
|
void readAliases(unsigned int varid);
|
||||||
|
@ -797,7 +797,7 @@ void Variables::eraseAll(unsigned int varid)
|
||||||
|
|
||||||
void Variables::addVar(const Token *name,
|
void Variables::addVar(const Token *name,
|
||||||
VariableType type,
|
VariableType type,
|
||||||
Scope *scope,
|
ScopeInfo *scope,
|
||||||
bool write_)
|
bool write_)
|
||||||
{
|
{
|
||||||
if (name->varId() > 0)
|
if (name->varId() > 0)
|
||||||
|
@ -955,7 +955,7 @@ Variables::VariableUsage *Variables::find(unsigned int varid)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int doAssignment(Variables &variables, const Token *tok, bool dereference, Scope *scope)
|
static int doAssignment(Variables &variables, const Token *tok, bool dereference, ScopeInfo *scope)
|
||||||
{
|
{
|
||||||
int next = 0;
|
int next = 0;
|
||||||
|
|
||||||
|
@ -1090,7 +1090,7 @@ static int doAssignment(Variables &variables, const Token *tok, bool dereference
|
||||||
// not in same scope as declaration
|
// not in same scope as declaration
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::set<Scope *>::iterator assignment;
|
std::set<ScopeInfo *>::iterator assignment;
|
||||||
|
|
||||||
// check for an assignment in this scope
|
// check for an assignment in this scope
|
||||||
assignment = var1->_assignments.find(scope);
|
assignment = var1->_assignments.find(scope);
|
||||||
|
@ -1158,7 +1158,7 @@ static int doAssignment(Variables &variables, const Token *tok, bool dereference
|
||||||
variables.clearAliases(varid1);
|
variables.clearAliases(varid1);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::set<Scope *>::iterator assignment;
|
std::set<ScopeInfo *>::iterator assignment;
|
||||||
|
|
||||||
// check for an assignment in this scope
|
// check for an assignment in this scope
|
||||||
assignment = var1->_assignments.find(scope);
|
assignment = var1->_assignments.find(scope);
|
||||||
|
@ -1240,14 +1240,14 @@ void CheckOther::functionVariableUsage()
|
||||||
// Parse all executing scopes..
|
// Parse all executing scopes..
|
||||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||||
|
|
||||||
std::list<SpaceInfo *>::const_iterator i;
|
std::list<Scope *>::const_iterator i;
|
||||||
|
|
||||||
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
|
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
|
||||||
{
|
{
|
||||||
const SpaceInfo *info = *i;
|
const Scope *info = *i;
|
||||||
|
|
||||||
// only check functions
|
// only check functions
|
||||||
if (info->type != SpaceInfo::Function)
|
if (info->type != Scope::eFunction)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// First token for the current scope..
|
// First token for the current scope..
|
||||||
|
@ -1257,8 +1257,8 @@ void CheckOther::functionVariableUsage()
|
||||||
Variables variables;
|
Variables variables;
|
||||||
|
|
||||||
// scopes
|
// scopes
|
||||||
Scope scopes;
|
ScopeInfo scopes;
|
||||||
Scope *scope = &scopes;
|
ScopeInfo *scope = &scopes;
|
||||||
|
|
||||||
unsigned int indentlevel = 0;
|
unsigned int indentlevel = 0;
|
||||||
for (const Token *tok = tok1; tok; tok = tok->next())
|
for (const Token *tok = tok1; tok; tok = tok->next())
|
||||||
|
@ -1267,7 +1267,7 @@ void CheckOther::functionVariableUsage()
|
||||||
{
|
{
|
||||||
// replace the head node when found
|
// replace the head node when found
|
||||||
if (indentlevel == 0)
|
if (indentlevel == 0)
|
||||||
scopes = Scope(tok, NULL);
|
scopes = ScopeInfo(tok, NULL);
|
||||||
// add the new scope
|
// add the new scope
|
||||||
else
|
else
|
||||||
scope = scope->addChild(tok);
|
scope = scope->addChild(tok);
|
||||||
|
@ -1694,7 +1694,7 @@ void CheckOther::functionVariableUsage()
|
||||||
if (!start->tokAt(3)->isStandardType())
|
if (!start->tokAt(3)->isStandardType())
|
||||||
{
|
{
|
||||||
// lookup the type
|
// lookup the type
|
||||||
const SpaceInfo *type = symbolDatabase->findVarType(info, start->tokAt(3));
|
const Scope *type = symbolDatabase->findVariableType(info, start->tokAt(3));
|
||||||
|
|
||||||
// unknown type?
|
// unknown type?
|
||||||
if (!type)
|
if (!type)
|
||||||
|
@ -1702,7 +1702,7 @@ void CheckOther::functionVariableUsage()
|
||||||
|
|
||||||
// has default constructor or
|
// has default constructor or
|
||||||
// has members with unknown type or default constructor
|
// has members with unknown type or default constructor
|
||||||
else if (type->needInitialization == SpaceInfo::False)
|
else if (type->needInitialization == Scope::False)
|
||||||
allocate = false;
|
allocate = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1908,19 +1908,19 @@ void CheckOther::checkVariableScope()
|
||||||
|
|
||||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||||
|
|
||||||
std::list<SpaceInfo *>::const_iterator i;
|
std::list<Scope *>::const_iterator i;
|
||||||
|
|
||||||
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
|
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
|
||||||
{
|
{
|
||||||
const SpaceInfo *info = *i;
|
const Scope *scope = *i;
|
||||||
|
|
||||||
// only check functions
|
// only check functions
|
||||||
if (info->type != SpaceInfo::Function)
|
if (scope->type != Scope::eFunction)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Walk through all tokens..
|
// Walk through all tokens..
|
||||||
int indentlevel = 0;
|
int indentlevel = 0;
|
||||||
for (const Token *tok = info->classStart; tok; tok = tok->next())
|
for (const Token *tok = scope->classStart; tok; tok = tok->next())
|
||||||
{
|
{
|
||||||
// Skip function local class and struct declarations..
|
// Skip function local class and struct declarations..
|
||||||
if ((tok->str() == "class") || (tok->str() == "struct") || (tok->str() == "union"))
|
if ((tok->str() == "class") || (tok->str() == "struct") || (tok->str() == "union"))
|
||||||
|
@ -2536,19 +2536,19 @@ void CheckOther::checkMisusedScopedObject()
|
||||||
|
|
||||||
const SymbolDatabase * const symbolDatabase = _tokenizer->getSymbolDatabase();
|
const SymbolDatabase * const symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||||
|
|
||||||
std::list<SpaceInfo *>::const_iterator i;
|
std::list<Scope *>::const_iterator i;
|
||||||
|
|
||||||
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
|
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
|
||||||
{
|
{
|
||||||
const SpaceInfo *info = *i;
|
const Scope *scope = *i;
|
||||||
|
|
||||||
// only check functions
|
// only check functions
|
||||||
if (info->type != SpaceInfo::Function)
|
if (scope->type != Scope::eFunction)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
unsigned int depth = 0;
|
unsigned int depth = 0;
|
||||||
|
|
||||||
for (const Token *tok = info->classStart; tok; tok = tok->next())
|
for (const Token *tok = scope->classStart; tok; tok = tok->next())
|
||||||
{
|
{
|
||||||
if (tok->str() == "{")
|
if (tok->str() == "{")
|
||||||
{
|
{
|
||||||
|
|
|
@ -46,14 +46,14 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
}
|
}
|
||||||
|
|
||||||
// find all namespaces (class,struct and namespace)
|
// find all namespaces (class,struct and namespace)
|
||||||
SpaceInfo *info = new SpaceInfo(this, NULL, NULL);
|
Scope *info = new Scope(this, NULL, NULL);
|
||||||
spaceInfoList.push_back(info);
|
spaceInfoList.push_back(info);
|
||||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
||||||
{
|
{
|
||||||
// Locate next class
|
// Locate next class
|
||||||
if (Token::Match(tok, "class|struct|namespace %var% [{:]"))
|
if (Token::Match(tok, "class|struct|namespace %var% [{:]"))
|
||||||
{
|
{
|
||||||
SpaceInfo *new_info = new SpaceInfo(this, tok, info);
|
Scope *new_info = new Scope(this, tok, info);
|
||||||
const Token *tok2 = tok->tokAt(2);
|
const Token *tok2 = tok->tokAt(2);
|
||||||
|
|
||||||
// only create base list for classes and structures
|
// only create base list for classes and structures
|
||||||
|
@ -91,7 +91,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if in class or structure
|
// check if in class or structure
|
||||||
else if (info->type == SpaceInfo::Class || info->type == SpaceInfo::Struct)
|
else if (info->type == Scope::eClass || info->type == Scope::eStruct)
|
||||||
{
|
{
|
||||||
const Token *funcStart = 0;
|
const Token *funcStart = 0;
|
||||||
const Token *argStart = 0;
|
const Token *argStart = 0;
|
||||||
|
@ -118,7 +118,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
// class function?
|
// class function?
|
||||||
else if (tok->previous()->str() != "::" && isFunction(tok, &funcStart, &argStart))
|
else if (tok->previous()->str() != "::" && isFunction(tok, &funcStart, &argStart))
|
||||||
{
|
{
|
||||||
Func function;
|
Function function;
|
||||||
|
|
||||||
// save the function definition argument start '('
|
// save the function definition argument start '('
|
||||||
function.argDef = argStart;
|
function.argDef = argStart;
|
||||||
|
@ -136,20 +136,20 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
|
|
||||||
// 'operator =' is special
|
// 'operator =' is special
|
||||||
if (function.tokenDef->str() == "=")
|
if (function.tokenDef->str() == "=")
|
||||||
function.type = Func::OperatorEqual;
|
function.type = Function::eOperatorEqual;
|
||||||
}
|
}
|
||||||
|
|
||||||
// class constructor/destructor
|
// class constructor/destructor
|
||||||
else if (function.tokenDef->str() == info->className)
|
else if (function.tokenDef->str() == info->className)
|
||||||
{
|
{
|
||||||
if (function.tokenDef->previous()->str() == "~")
|
if (function.tokenDef->previous()->str() == "~")
|
||||||
function.type = Func::Destructor;
|
function.type = Function::eDestructor;
|
||||||
else if ((Token::Match(function.tokenDef, "%var% ( const %var% & )") ||
|
else if ((Token::Match(function.tokenDef, "%var% ( const %var% & )") ||
|
||||||
Token::Match(function.tokenDef, "%var% ( const %var% & %var% )")) &&
|
Token::Match(function.tokenDef, "%var% ( const %var% & %var% )")) &&
|
||||||
function.tokenDef->strAt(3) == info->className)
|
function.tokenDef->strAt(3) == info->className)
|
||||||
function.type = Func::CopyConstructor;
|
function.type = Function::eCopyConstructor;
|
||||||
else
|
else
|
||||||
function.type = Func::Constructor;
|
function.type = Function::eConstructor;
|
||||||
|
|
||||||
if (function.tokenDef->previous()->str() == "explicit")
|
if (function.tokenDef->previous()->str() == "explicit")
|
||||||
function.isExplicit = true;
|
function.isExplicit = true;
|
||||||
|
@ -206,7 +206,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
function.isPure = true;
|
function.isPure = true;
|
||||||
|
|
||||||
// count the number of constructors
|
// count the number of constructors
|
||||||
if (function.type == Func::Constructor || function.type == Func::CopyConstructor)
|
if (function.type == Function::eConstructor || function.type == Function::eCopyConstructor)
|
||||||
info->numConstructors++;
|
info->numConstructors++;
|
||||||
|
|
||||||
// assume implementation is inline (definition and implementation same)
|
// assume implementation is inline (definition and implementation same)
|
||||||
|
@ -232,7 +232,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
info->functionList.push_back(function);
|
info->functionList.push_back(function);
|
||||||
|
|
||||||
const Token *tok2 = funcStart;
|
const Token *tok2 = funcStart;
|
||||||
SpaceInfo *functionOf = info;
|
Scope *functionOf = info;
|
||||||
|
|
||||||
addNewFunction(&info, &tok2);
|
addNewFunction(&info, &tok2);
|
||||||
if (info)
|
if (info)
|
||||||
|
@ -249,7 +249,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
// friend class declaration?
|
// friend class declaration?
|
||||||
else if (Token::Match(tok, "friend class| %any% ;"))
|
else if (Token::Match(tok, "friend class| %any% ;"))
|
||||||
{
|
{
|
||||||
SpaceInfo::FriendInfo friendInfo;
|
Scope::FriendInfo friendInfo;
|
||||||
|
|
||||||
friendInfo.name = tok->strAt(1) == "class" ? tok->strAt(2) : tok->strAt(1);
|
friendInfo.name = tok->strAt(1) == "class" ? tok->strAt(2) : tok->strAt(1);
|
||||||
/** @todo fill this in later after parsing is complete */
|
/** @todo fill this in later after parsing is complete */
|
||||||
|
@ -258,7 +258,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
info->friendList.push_back(friendInfo);
|
info->friendList.push_back(friendInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (info->type == SpaceInfo::Namespace || info->type == SpaceInfo::Global)
|
else if (info->type == Scope::eNamespace || info->type == Scope::eGlobal)
|
||||||
{
|
{
|
||||||
const Token *funcStart = 0;
|
const Token *funcStart = 0;
|
||||||
const Token *argStart = 0;
|
const Token *argStart = 0;
|
||||||
|
@ -281,7 +281,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
// regular function
|
// regular function
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Func function;
|
Function function;
|
||||||
|
|
||||||
// save the function definition argument start '('
|
// save the function definition argument start '('
|
||||||
function.argDef = argStart;
|
function.argDef = argStart;
|
||||||
|
@ -296,9 +296,9 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
function.isInline = false;
|
function.isInline = false;
|
||||||
function.hasBody = true;
|
function.hasBody = true;
|
||||||
function.arg = function.argDef;
|
function.arg = function.argDef;
|
||||||
function.type = Func::Function;
|
function.type = Function::eFunction;
|
||||||
|
|
||||||
SpaceInfo *old_info = info;
|
Scope *old_info = info;
|
||||||
|
|
||||||
addNewFunction(&info, &tok);
|
addNewFunction(&info, &tok);
|
||||||
|
|
||||||
|
@ -319,7 +319,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
Token::Match(argStart->link()->tokAt(2)->link(), ") const| {"))
|
Token::Match(argStart->link()->tokAt(2)->link(), ") const| {"))
|
||||||
{
|
{
|
||||||
const Token *tok1 = funcStart;
|
const Token *tok1 = funcStart;
|
||||||
SpaceInfo *old_info = info;
|
Scope *old_info = info;
|
||||||
|
|
||||||
// class function
|
// class function
|
||||||
if (tok1->previous()->str() == "::")
|
if (tok1->previous()->str() == "::")
|
||||||
|
@ -340,7 +340,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::list<SpaceInfo *>::iterator it;
|
std::list<Scope *>::iterator it;
|
||||||
|
|
||||||
// fill in base class info
|
// fill in base class info
|
||||||
for (it = spaceInfoList.begin(); it != spaceInfoList.end(); ++it)
|
for (it = spaceInfoList.begin(); it != spaceInfoList.end(); ++it)
|
||||||
|
@ -354,22 +354,22 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
// finish filling in base class info
|
// finish filling in base class info
|
||||||
for (unsigned int i = 0; i < info->derivedFrom.size(); ++i)
|
for (unsigned int i = 0; i < info->derivedFrom.size(); ++i)
|
||||||
{
|
{
|
||||||
std::list<SpaceInfo *>::iterator it1;
|
std::list<Scope *>::iterator it1;
|
||||||
|
|
||||||
for (it1 = spaceInfoList.begin(); it1 != spaceInfoList.end(); ++it1)
|
for (it1 = spaceInfoList.begin(); it1 != spaceInfoList.end(); ++it1)
|
||||||
{
|
{
|
||||||
SpaceInfo *spaceInfo = *it1;
|
Scope *spaceInfo = *it1;
|
||||||
|
|
||||||
/** @todo handle derived base classes and namespaces */
|
/** @todo handle derived base classes and namespaces */
|
||||||
if (spaceInfo->type == SpaceInfo::Class || spaceInfo->type == SpaceInfo::Struct)
|
if (spaceInfo->type == Scope::eClass || spaceInfo->type == Scope::eStruct)
|
||||||
{
|
{
|
||||||
// do class names match?
|
// do class names match?
|
||||||
if (spaceInfo->className == info->derivedFrom[i].name)
|
if (spaceInfo->className == info->derivedFrom[i].name)
|
||||||
{
|
{
|
||||||
// are they in the same namespace or different namespaces with same name?
|
// are they in the same namespace or different namespaces with same name?
|
||||||
if ((spaceInfo->nestedIn == info->nestedIn) ||
|
if ((spaceInfo->nestedIn == info->nestedIn) ||
|
||||||
((spaceInfo->nestedIn && spaceInfo->nestedIn->type == SpaceInfo::Namespace) &&
|
((spaceInfo->nestedIn && spaceInfo->nestedIn->type == Scope::eNamespace) &&
|
||||||
(info->nestedIn && info->nestedIn->type == SpaceInfo::Namespace) &&
|
(info->nestedIn && info->nestedIn->type == Scope::eNamespace) &&
|
||||||
(spaceInfo->nestedIn->className == info->nestedIn->className)))
|
(spaceInfo->nestedIn->className == info->nestedIn->className)))
|
||||||
{
|
{
|
||||||
info->derivedFrom[i].spaceInfo = spaceInfo;
|
info->derivedFrom[i].spaceInfo = spaceInfo;
|
||||||
|
@ -387,10 +387,10 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
info = *it;
|
info = *it;
|
||||||
|
|
||||||
// skip functions
|
// skip functions
|
||||||
if (info->type != SpaceInfo::Function)
|
if (info->type != Scope::eFunction)
|
||||||
{
|
{
|
||||||
// find variables
|
// find variables
|
||||||
info->getVarList();
|
info->getVariableList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,16 +406,16 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
{
|
{
|
||||||
info = *it;
|
info = *it;
|
||||||
|
|
||||||
if (info->isClassOrStruct() && info->needInitialization == SpaceInfo::Unknown)
|
if (info->isClassOrStruct() && info->needInitialization == Scope::Unknown)
|
||||||
{
|
{
|
||||||
// check for default constructor
|
// check for default constructor
|
||||||
bool hasDefaultConstructor = false;
|
bool hasDefaultConstructor = false;
|
||||||
|
|
||||||
std::list<Func>::const_iterator func;
|
std::list<Function>::const_iterator func;
|
||||||
|
|
||||||
for (func = info->functionList.begin(); func != info->functionList.end(); ++func)
|
for (func = info->functionList.begin(); func != info->functionList.end(); ++func)
|
||||||
{
|
{
|
||||||
if (func->type == Func::Constructor)
|
if (func->type == Function::eConstructor)
|
||||||
{
|
{
|
||||||
// check for no arguments: func ( )
|
// check for no arguments: func ( )
|
||||||
if (func->argDef->next() == func->argDef->link())
|
if (func->argDef->next() == func->argDef->link())
|
||||||
|
@ -437,7 +437,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
// We assume the default constructor initializes everything.
|
// We assume the default constructor initializes everything.
|
||||||
// Another check will figure out if the constructor actually initializes everything.
|
// Another check will figure out if the constructor actually initializes everything.
|
||||||
if (hasDefaultConstructor)
|
if (hasDefaultConstructor)
|
||||||
info->needInitialization = SpaceInfo::False;
|
info->needInitialization = Scope::False;
|
||||||
|
|
||||||
// check each member variable to see if it needs initialization
|
// check each member variable to see if it needs initialization
|
||||||
else
|
else
|
||||||
|
@ -445,7 +445,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
bool needInitialization = false;
|
bool needInitialization = false;
|
||||||
bool unknown = false;
|
bool unknown = false;
|
||||||
|
|
||||||
std::list<Var>::const_iterator var;
|
std::list<Variable>::const_iterator var;
|
||||||
for (var = info->varlist.begin(); var != info->varlist.end(); ++var)
|
for (var = info->varlist.begin(); var != info->varlist.end(); ++var)
|
||||||
{
|
{
|
||||||
if (var->isClass)
|
if (var->isClass)
|
||||||
|
@ -453,9 +453,9 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
if (var->type)
|
if (var->type)
|
||||||
{
|
{
|
||||||
// does this type need initialization?
|
// does this type need initialization?
|
||||||
if (var->type->needInitialization == SpaceInfo::True)
|
if (var->type->needInitialization == Scope::True)
|
||||||
needInitialization = true;
|
needInitialization = true;
|
||||||
else if (var->type->needInitialization == SpaceInfo::Unknown)
|
else if (var->type->needInitialization == Scope::Unknown)
|
||||||
unknown = true;
|
unknown = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -466,12 +466,12 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
if (!unknown)
|
if (!unknown)
|
||||||
{
|
{
|
||||||
if (needInitialization)
|
if (needInitialization)
|
||||||
info->needInitialization = SpaceInfo::True;
|
info->needInitialization = Scope::True;
|
||||||
else
|
else
|
||||||
info->needInitialization = SpaceInfo::False;
|
info->needInitialization = Scope::False;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info->needInitialization == SpaceInfo::Unknown)
|
if (info->needInitialization == Scope::Unknown)
|
||||||
unknowns++;
|
unknowns++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -488,7 +488,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
{
|
{
|
||||||
info = *it;
|
info = *it;
|
||||||
|
|
||||||
if (info->isClassOrStruct() && info->needInitialization == SpaceInfo::Unknown)
|
if (info->isClassOrStruct() && info->needInitialization == Scope::Unknown)
|
||||||
{
|
{
|
||||||
std::list<ErrorLogger::ErrorMessage::FileLocation> locationList;
|
std::list<ErrorLogger::ErrorMessage::FileLocation> locationList;
|
||||||
ErrorLogger::ErrorMessage::FileLocation loc;
|
ErrorLogger::ErrorMessage::FileLocation loc;
|
||||||
|
@ -511,7 +511,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
|
|
||||||
SymbolDatabase::~SymbolDatabase()
|
SymbolDatabase::~SymbolDatabase()
|
||||||
{
|
{
|
||||||
std::list<SpaceInfo *>::iterator it;
|
std::list<Scope *>::iterator it;
|
||||||
|
|
||||||
for (it = spaceInfoList.begin(); it != spaceInfoList.end(); ++it)
|
for (it = spaceInfoList.begin(); it != spaceInfoList.end(); ++it)
|
||||||
delete *it;
|
delete *it;
|
||||||
|
@ -575,7 +575,7 @@ bool SymbolDatabase::isFunction(const Token *tok, const Token **funcStart, const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SymbolDatabase::argsMatch(const SpaceInfo *info, const Token *first, const Token *second, const std::string &path, unsigned int depth) const
|
bool SymbolDatabase::argsMatch(const Scope *info, const Token *first, const Token *second, const std::string &path, unsigned int depth) const
|
||||||
{
|
{
|
||||||
bool match = false;
|
bool match = false;
|
||||||
while (first->str() == second->str())
|
while (first->str() == second->str())
|
||||||
|
@ -664,7 +664,7 @@ bool SymbolDatabase::argsMatch(const SpaceInfo *info, const Token *first, const
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SymbolDatabase::addFunction(SpaceInfo **info, const Token **tok, const Token *argStart)
|
void SymbolDatabase::addFunction(Scope **info, const Token **tok, const Token *argStart)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
bool added = false;
|
bool added = false;
|
||||||
|
@ -693,15 +693,15 @@ void SymbolDatabase::addFunction(SpaceInfo **info, const Token **tok, const Toke
|
||||||
path_length++;
|
path_length++;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::list<SpaceInfo *>::iterator it1;
|
std::list<Scope *>::iterator it1;
|
||||||
|
|
||||||
// search for match
|
// search for match
|
||||||
for (it1 = spaceInfoList.begin(); it1 != spaceInfoList.end(); ++it1)
|
for (it1 = spaceInfoList.begin(); it1 != spaceInfoList.end(); ++it1)
|
||||||
{
|
{
|
||||||
SpaceInfo *info1 = *it1;
|
Scope *info1 = *it1;
|
||||||
|
|
||||||
bool match = false;
|
bool match = false;
|
||||||
if (info1->className == tok1->str() && (info1->type != SpaceInfo::Function))
|
if (info1->className == tok1->str() && (info1->type != Scope::eFunction))
|
||||||
{
|
{
|
||||||
// do the spaces match (same space) or do their names match (multiple namespaces)
|
// do the spaces match (same space) or do their names match (multiple namespaces)
|
||||||
if ((*info == info1->nestedIn) || (*info && info1 &&
|
if ((*info == info1->nestedIn) || (*info && info1 &&
|
||||||
|
@ -709,7 +709,7 @@ void SymbolDatabase::addFunction(SpaceInfo **info, const Token **tok, const Toke
|
||||||
!(*info)->className.empty() &&
|
!(*info)->className.empty() &&
|
||||||
(*info)->type == info1->nestedIn->type))
|
(*info)->type == info1->nestedIn->type))
|
||||||
{
|
{
|
||||||
SpaceInfo *info2 = info1;
|
Scope *info2 = info1;
|
||||||
|
|
||||||
while (info2 && count > 0)
|
while (info2 && count > 0)
|
||||||
{
|
{
|
||||||
|
@ -728,7 +728,7 @@ void SymbolDatabase::addFunction(SpaceInfo **info, const Token **tok, const Toke
|
||||||
|
|
||||||
if (match)
|
if (match)
|
||||||
{
|
{
|
||||||
std::list<Func>::iterator func;
|
std::list<Function>::iterator func;
|
||||||
|
|
||||||
for (func = info1->functionList.begin(); func != info1->functionList.end(); ++func)
|
for (func = info1->functionList.begin(); func != info1->functionList.end(); ++func)
|
||||||
{
|
{
|
||||||
|
@ -745,7 +745,7 @@ void SymbolDatabase::addFunction(SpaceInfo **info, const Token **tok, const Toke
|
||||||
func->arg = argStart;
|
func->arg = argStart;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (func->type == Func::Destructor &&
|
else if (func->type == Function::eDestructor &&
|
||||||
(*tok)->previous()->str() == "~" &&
|
(*tok)->previous()->str() == "~" &&
|
||||||
func->tokenDef->str() == (*tok)->str())
|
func->tokenDef->str() == (*tok)->str())
|
||||||
{
|
{
|
||||||
|
@ -803,10 +803,10 @@ void SymbolDatabase::addFunction(SpaceInfo **info, const Token **tok, const Toke
|
||||||
addNewFunction(info, tok);
|
addNewFunction(info, tok);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SymbolDatabase::addNewFunction(SpaceInfo **info, const Token **tok)
|
void SymbolDatabase::addNewFunction(Scope **info, const Token **tok)
|
||||||
{
|
{
|
||||||
const Token *tok1 = *tok;
|
const Token *tok1 = *tok;
|
||||||
SpaceInfo *new_info = new SpaceInfo(this, tok1, *info);
|
Scope *new_info = new Scope(this, tok1, *info);
|
||||||
|
|
||||||
// skip to start of function
|
// skip to start of function
|
||||||
while (tok1 && tok1->str() != "{")
|
while (tok1 && tok1->str() != "{")
|
||||||
|
@ -837,7 +837,7 @@ void SymbolDatabase::addNewFunction(SpaceInfo **info, const Token **tok)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Token *SymbolDatabase::initBaseInfo(SpaceInfo *info, const Token *tok)
|
const Token *SymbolDatabase::initBaseInfo(Scope *info, const Token *tok)
|
||||||
{
|
{
|
||||||
// goto initial '{'
|
// goto initial '{'
|
||||||
const Token *tok2 = tok->tokAt(2);
|
const Token *tok2 = tok->tokAt(2);
|
||||||
|
@ -853,7 +853,7 @@ const Token *SymbolDatabase::initBaseInfo(SpaceInfo *info, const Token *tok)
|
||||||
// check for base classes
|
// check for base classes
|
||||||
else if (level == 0 && Token::Match(tok2, ":|,"))
|
else if (level == 0 && Token::Match(tok2, ":|,"))
|
||||||
{
|
{
|
||||||
SpaceInfo::BaseInfo base;
|
Scope::BaseInfo base;
|
||||||
|
|
||||||
tok2 = tok2->next();
|
tok2 = tok2->next();
|
||||||
|
|
||||||
|
@ -924,7 +924,7 @@ const Token *SymbolDatabase::initBaseInfo(SpaceInfo *info, const Token *tok)
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
unsigned int Func::argCount() const
|
unsigned int Function::argCount() const
|
||||||
{
|
{
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
|
|
||||||
|
@ -942,7 +942,7 @@ unsigned int Func::argCount() const
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Func::initializedArgCount() const
|
unsigned int Function::initializedArgCount() const
|
||||||
{
|
{
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
|
|
||||||
|
@ -960,48 +960,48 @@ unsigned int Func::initializedArgCount() const
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
SpaceInfo::SpaceInfo(SymbolDatabase *check_, const Token *classDef_, SpaceInfo *nestedIn_) :
|
Scope::Scope(SymbolDatabase *check_, const Token *classDef_, Scope *nestedIn_) :
|
||||||
check(check_),
|
check(check_),
|
||||||
classDef(classDef_),
|
classDef(classDef_),
|
||||||
classStart(NULL),
|
classStart(NULL),
|
||||||
classEnd(NULL),
|
classEnd(NULL),
|
||||||
nestedIn(nestedIn_),
|
nestedIn(nestedIn_),
|
||||||
numConstructors(0),
|
numConstructors(0),
|
||||||
needInitialization(SpaceInfo::Unknown),
|
needInitialization(Scope::Unknown),
|
||||||
functionOf(NULL)
|
functionOf(NULL)
|
||||||
{
|
{
|
||||||
if (!classDef)
|
if (!classDef)
|
||||||
{
|
{
|
||||||
type = SpaceInfo::Global;
|
type = Scope::eGlobal;
|
||||||
access = Public;
|
access = Public;
|
||||||
}
|
}
|
||||||
else if (classDef->str() == "class")
|
else if (classDef->str() == "class")
|
||||||
{
|
{
|
||||||
type = SpaceInfo::Class;
|
type = Scope::eClass;
|
||||||
className = classDef->next()->str();
|
className = classDef->next()->str();
|
||||||
access = Private;
|
access = Private;
|
||||||
}
|
}
|
||||||
else if (classDef->str() == "struct")
|
else if (classDef->str() == "struct")
|
||||||
{
|
{
|
||||||
type = SpaceInfo::Struct;
|
type = Scope::eStruct;
|
||||||
className = classDef->next()->str();
|
className = classDef->next()->str();
|
||||||
access = Public;
|
access = Public;
|
||||||
}
|
}
|
||||||
else if (classDef->str() == "union")
|
else if (classDef->str() == "union")
|
||||||
{
|
{
|
||||||
type = SpaceInfo::Union;
|
type = Scope::eUnion;
|
||||||
className = classDef->next()->str();
|
className = classDef->next()->str();
|
||||||
access = Public;
|
access = Public;
|
||||||
}
|
}
|
||||||
else if (classDef->str() == "namespace")
|
else if (classDef->str() == "namespace")
|
||||||
{
|
{
|
||||||
type = SpaceInfo::Namespace;
|
type = Scope::eNamespace;
|
||||||
className = classDef->next()->str();
|
className = classDef->next()->str();
|
||||||
access = Public;
|
access = Public;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
type = SpaceInfo::Function;
|
type = Scope::eFunction;
|
||||||
className = classDef->str();
|
className = classDef->str();
|
||||||
access = Public;
|
access = Public;
|
||||||
}
|
}
|
||||||
|
@ -1011,15 +1011,15 @@ SpaceInfo::SpaceInfo(SymbolDatabase *check_, const Token *classDef_, SpaceInfo *
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
SpaceInfo::hasDefaultConstructor() const
|
Scope::hasDefaultConstructor() const
|
||||||
{
|
{
|
||||||
if (numConstructors)
|
if (numConstructors)
|
||||||
{
|
{
|
||||||
std::list<Func>::const_iterator func;
|
std::list<Function>::const_iterator func;
|
||||||
|
|
||||||
for (func = functionList.begin(); func != functionList.end(); ++func)
|
for (func = functionList.begin(); func != functionList.end(); ++func)
|
||||||
{
|
{
|
||||||
if (func->type == Func::Constructor &&
|
if (func->type == Function::eConstructor &&
|
||||||
func->argDef->link() == func->argDef->next())
|
func->argDef->link() == func->argDef->next())
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1028,9 +1028,9 @@ SpaceInfo::hasDefaultConstructor() const
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get variable list..
|
// Get variable list..
|
||||||
void SpaceInfo::getVarList()
|
void Scope::getVariableList()
|
||||||
{
|
{
|
||||||
AccessControl varaccess = type == Class ? Private : Public;
|
AccessControl varaccess = type == eClass ? Private : Public;
|
||||||
const Token *start;
|
const Token *start;
|
||||||
|
|
||||||
if (classStart)
|
if (classStart)
|
||||||
|
@ -1184,7 +1184,7 @@ void SpaceInfo::getVarList()
|
||||||
|
|
||||||
const ErrorLogger::ErrorMessage errmsg(locationList,
|
const ErrorLogger::ErrorMessage errmsg(locationList,
|
||||||
Severity::debug,
|
Severity::debug,
|
||||||
"SymbolDatabase::SpaceInfo::getVarList found variable \'" + vartok->str() + "\' with varid 0.",
|
"Scope::getVariableList found variable \'" + vartok->str() + "\' with varid 0.",
|
||||||
"debug");
|
"debug");
|
||||||
if (check->_errorLogger)
|
if (check->_errorLogger)
|
||||||
check->_errorLogger->reportErr(errmsg);
|
check->_errorLogger->reportErr(errmsg);
|
||||||
|
@ -1192,12 +1192,12 @@ void SpaceInfo::getVarList()
|
||||||
Check::reportError(errmsg);
|
Check::reportError(errmsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
const SpaceInfo *spaceInfo = NULL;
|
const Scope *spaceInfo = NULL;
|
||||||
|
|
||||||
if (typetok)
|
if (typetok)
|
||||||
spaceInfo = check->findVarType(this, typetok);
|
spaceInfo = check->findVariableType(this, typetok);
|
||||||
|
|
||||||
addVar(vartok, varaccess, isMutable, isStatic, isConst, isClass, spaceInfo);
|
addVariable(vartok, varaccess, isMutable, isStatic, isConst, isClass, spaceInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1230,7 +1230,7 @@ const Token* skipPointers(const Token* tok)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SpaceInfo::isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok) const
|
bool Scope::isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok) const
|
||||||
{
|
{
|
||||||
const Token* localTypeTok = skipScopeIdentifiers(tok);
|
const Token* localTypeTok = skipScopeIdentifiers(tok);
|
||||||
|
|
||||||
|
@ -1271,17 +1271,17 @@ bool SpaceInfo::isVariableDeclaration(const Token* tok, const Token*& vartok, co
|
||||||
return NULL != vartok;
|
return NULL != vartok;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SpaceInfo::isSimpleVariable(const Token* tok) const
|
bool Scope::isSimpleVariable(const Token* tok) const
|
||||||
{
|
{
|
||||||
return Token::Match(tok, "%var% ;");
|
return Token::Match(tok, "%var% ;");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SpaceInfo::isArrayVariable(const Token* tok) const
|
bool Scope::isArrayVariable(const Token* tok) const
|
||||||
{
|
{
|
||||||
return Token::Match(tok, "%var% [") && tok->next()->str() != "operator";
|
return Token::Match(tok, "%var% [") && tok->next()->str() != "operator";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SpaceInfo::findClosingBracket(const Token* tok, const Token*& close) const
|
bool Scope::findClosingBracket(const Token* tok, const Token*& close) const
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
if (NULL != tok && tok->str() == "<")
|
if (NULL != tok && tok->str() == "<")
|
||||||
|
@ -1310,16 +1310,16 @@ bool SpaceInfo::findClosingBracket(const Token* tok, const Token*& close) const
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
const SpaceInfo *SymbolDatabase::findVarType(const SpaceInfo *start, const Token *type) const
|
const Scope *SymbolDatabase::findVariableType(const Scope *start, const Token *type) const
|
||||||
{
|
{
|
||||||
std::list<SpaceInfo *>::const_iterator it;
|
std::list<Scope *>::const_iterator it;
|
||||||
|
|
||||||
for (it = spaceInfoList.begin(); it != spaceInfoList.end(); ++it)
|
for (it = spaceInfoList.begin(); it != spaceInfoList.end(); ++it)
|
||||||
{
|
{
|
||||||
const SpaceInfo *info = *it;
|
const Scope *info = *it;
|
||||||
|
|
||||||
// skip namespaces and functions
|
// skip namespaces and functions
|
||||||
if (info->type == SpaceInfo::Namespace || info->type == SpaceInfo::Function || info->type == SpaceInfo::Global)
|
if (info->type == Scope::eNamespace || info->type == Scope::eFunction || info->type == Scope::eGlobal)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// do the names match?
|
// do the names match?
|
||||||
|
@ -1328,7 +1328,7 @@ const SpaceInfo *SymbolDatabase::findVarType(const SpaceInfo *start, const Token
|
||||||
// check if type does not have a namespace
|
// check if type does not have a namespace
|
||||||
if (type->previous()->str() != "::")
|
if (type->previous()->str() != "::")
|
||||||
{
|
{
|
||||||
const SpaceInfo *parent = start;
|
const Scope *parent = start;
|
||||||
|
|
||||||
// check if in same namespace
|
// check if in same namespace
|
||||||
while (parent && parent != info->nestedIn)
|
while (parent && parent != info->nestedIn)
|
||||||
|
@ -1352,9 +1352,9 @@ const SpaceInfo *SymbolDatabase::findVarType(const SpaceInfo *start, const Token
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
SpaceInfo * SpaceInfo::findInNestedList(const std::string & name)
|
Scope * Scope::findInNestedList(const std::string & name)
|
||||||
{
|
{
|
||||||
std::list<SpaceInfo *>::iterator it;
|
std::list<Scope *>::iterator it;
|
||||||
|
|
||||||
for (it = nestedList.begin(); it != nestedList.end(); ++it)
|
for (it = nestedList.begin(); it != nestedList.end(); ++it)
|
||||||
{
|
{
|
||||||
|
@ -1366,12 +1366,12 @@ SpaceInfo * SpaceInfo::findInNestedList(const std::string & name)
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
const Func *SpaceInfo::getDestructor() const
|
const Function *Scope::getDestructor() const
|
||||||
{
|
{
|
||||||
std::list<Func>::const_iterator it;
|
std::list<Function>::const_iterator it;
|
||||||
for (it = functionList.begin(); it != functionList.end(); ++it)
|
for (it = functionList.begin(); it != functionList.end(); ++it)
|
||||||
{
|
{
|
||||||
if (it->type == Func::Destructor)
|
if (it->type == Function::eDestructor)
|
||||||
return &*it;
|
return &*it;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1379,13 +1379,13 @@ const Func *SpaceInfo::getDestructor() const
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
unsigned int SpaceInfo::getNestedNonFunctions() const
|
unsigned int Scope::getNestedNonFunctions() const
|
||||||
{
|
{
|
||||||
unsigned int nested = 0;
|
unsigned int nested = 0;
|
||||||
std::list<SpaceInfo *>::const_iterator ni;
|
std::list<Scope *>::const_iterator ni;
|
||||||
for (ni = nestedList.begin(); ni != nestedList.end(); ++ni)
|
for (ni = nestedList.begin(); ni != nestedList.end(); ++ni)
|
||||||
{
|
{
|
||||||
if ((*ni)->type != SpaceInfo::Function)
|
if ((*ni)->type != Scope::eFunction)
|
||||||
nested++;
|
nested++;
|
||||||
}
|
}
|
||||||
return nested;
|
return nested;
|
||||||
|
|
|
@ -31,7 +31,7 @@ class Tokenizer;
|
||||||
class Settings;
|
class Settings;
|
||||||
class ErrorLogger;
|
class ErrorLogger;
|
||||||
|
|
||||||
class SpaceInfo;
|
class Scope;
|
||||||
class SymbolDatabase;
|
class SymbolDatabase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,10 +40,10 @@ class SymbolDatabase;
|
||||||
enum AccessControl { Public, Protected, Private };
|
enum AccessControl { Public, Protected, Private };
|
||||||
|
|
||||||
/** @brief Information about a member variable. */
|
/** @brief Information about a member variable. */
|
||||||
class Var
|
class Variable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Var(const Token *token_, std::size_t index_, AccessControl access_, bool mutable_, bool static_, bool const_, bool class_, const SpaceInfo *type_)
|
Variable(const Token *token_, std::size_t index_, AccessControl access_, bool mutable_, bool static_, bool const_, bool class_, const Scope *type_)
|
||||||
: token(token_),
|
: token(token_),
|
||||||
index(index_),
|
index(index_),
|
||||||
access(access_),
|
access(access_),
|
||||||
|
@ -77,15 +77,15 @@ public:
|
||||||
bool isClass;
|
bool isClass;
|
||||||
|
|
||||||
/** @brief pointer to user defined type info (for known types) */
|
/** @brief pointer to user defined type info (for known types) */
|
||||||
const SpaceInfo *type;
|
const Scope *type;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Func
|
class Function
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum Type { Constructor, CopyConstructor, OperatorEqual, Destructor, Function };
|
enum Type { eConstructor, eCopyConstructor, eOperatorEqual, eDestructor, eFunction };
|
||||||
|
|
||||||
Func()
|
Function()
|
||||||
: tokenDef(NULL),
|
: tokenDef(NULL),
|
||||||
argDef(NULL),
|
argDef(NULL),
|
||||||
token(NULL),
|
token(NULL),
|
||||||
|
@ -101,7 +101,7 @@ public:
|
||||||
isExplicit(false),
|
isExplicit(false),
|
||||||
isOperator(false),
|
isOperator(false),
|
||||||
retFuncPtr(false),
|
retFuncPtr(false),
|
||||||
type(Function)
|
type(eFunction)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,26 +126,29 @@ public:
|
||||||
Type type; // constructor, destructor, ...
|
Type type; // constructor, destructor, ...
|
||||||
};
|
};
|
||||||
|
|
||||||
class SpaceInfo
|
class Scope
|
||||||
{
|
{
|
||||||
|
// let tests access private function for testing
|
||||||
|
friend class TestSymbolDatabase;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct BaseInfo
|
struct BaseInfo
|
||||||
{
|
{
|
||||||
AccessControl access; // public/protected/private
|
AccessControl access; // public/protected/private
|
||||||
std::string name;
|
std::string name;
|
||||||
SpaceInfo *spaceInfo;
|
Scope *spaceInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FriendInfo
|
struct FriendInfo
|
||||||
{
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
SpaceInfo *spaceInfo;
|
Scope *spaceInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SpaceType { Global, Class, Struct, Union, Namespace, Function };
|
enum SpaceType { eGlobal, eClass, eStruct, eUnion, eNamespace, eFunction };
|
||||||
enum NeedInitialization { Unknown, True, False };
|
enum NeedInitialization { Unknown, True, False };
|
||||||
|
|
||||||
SpaceInfo(SymbolDatabase *check_, const Token *classDef_, SpaceInfo *nestedIn_);
|
Scope(SymbolDatabase *check_, const Token *classDef_, Scope *nestedIn_);
|
||||||
|
|
||||||
SymbolDatabase *check;
|
SymbolDatabase *check;
|
||||||
SpaceType type;
|
SpaceType type;
|
||||||
|
@ -153,37 +156,37 @@ public:
|
||||||
const Token *classDef; // class/struct/union/namespace token
|
const Token *classDef; // class/struct/union/namespace token
|
||||||
const Token *classStart; // '{' token
|
const Token *classStart; // '{' token
|
||||||
const Token *classEnd; // '}' token
|
const Token *classEnd; // '}' token
|
||||||
std::list<Func> functionList;
|
std::list<Function> functionList;
|
||||||
std::list<Var> varlist;
|
std::list<Variable> varlist;
|
||||||
std::vector<BaseInfo> derivedFrom;
|
std::vector<BaseInfo> derivedFrom;
|
||||||
std::list<FriendInfo> friendList;
|
std::list<FriendInfo> friendList;
|
||||||
SpaceInfo *nestedIn;
|
Scope *nestedIn;
|
||||||
std::list<SpaceInfo *> nestedList;
|
std::list<Scope *> nestedList;
|
||||||
AccessControl access;
|
AccessControl access;
|
||||||
unsigned int numConstructors;
|
unsigned int numConstructors;
|
||||||
NeedInitialization needInitialization;
|
NeedInitialization needInitialization;
|
||||||
SpaceInfo * functionOf; // class/struct this function belongs to
|
Scope * functionOf; // class/struct this function belongs to
|
||||||
|
|
||||||
bool isClassOrStruct() const
|
bool isClassOrStruct() const
|
||||||
{
|
{
|
||||||
return (type == Class || type == Struct);
|
return (type == eClass || type == eStruct);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief find if name is in nested list
|
* @brief find if name is in nested list
|
||||||
* @param name name of nested space
|
* @param name name of nested space
|
||||||
*/
|
*/
|
||||||
SpaceInfo * findInNestedList(const std::string & name);
|
Scope * findInNestedList(const std::string & name);
|
||||||
|
|
||||||
void addVar(const Token *token_, AccessControl access_, bool mutable_, bool static_, bool const_, bool class_, const SpaceInfo *type_)
|
void addVariable(const Token *token_, AccessControl access_, bool mutable_, bool static_, bool const_, bool class_, const Scope *type_)
|
||||||
{
|
{
|
||||||
varlist.push_back(Var(token_, varlist.size(), access_, mutable_, static_, const_, class_, type_));
|
varlist.push_back(Variable(token_, varlist.size(), access_, mutable_, static_, const_, class_, type_));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief initialize varlist */
|
/** @brief initialize varlist */
|
||||||
void getVarList();
|
void getVariableList();
|
||||||
|
|
||||||
const Func *getDestructor() const;
|
const Function *getDestructor() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief get the number of nested spaces that are not functions
|
* @brief get the number of nested spaces that are not functions
|
||||||
|
@ -197,7 +200,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* @brief helper function for getVarList()
|
* @brief helper function for getVariableList()
|
||||||
* @param tok pointer to token to check
|
* @param tok pointer to token to check
|
||||||
* @param vartok populated with pointer to the variable token, if found
|
* @param vartok populated with pointer to the variable token, if found
|
||||||
* @param typetok populated with pointer to the type token, if found
|
* @param typetok populated with pointer to the type token, if found
|
||||||
|
@ -216,7 +219,7 @@ public:
|
||||||
~SymbolDatabase();
|
~SymbolDatabase();
|
||||||
|
|
||||||
/** @brief Information about all namespaces/classes/structrues */
|
/** @brief Information about all namespaces/classes/structrues */
|
||||||
std::list<SpaceInfo *> spaceInfoList;
|
std::list<Scope *> spaceInfoList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief find a variable type if it's a user defined type
|
* @brief find a variable type if it's a user defined type
|
||||||
|
@ -224,9 +227,9 @@ public:
|
||||||
* @param type token containing variable type
|
* @param type token containing variable type
|
||||||
* @return pointer to type if found or NULL if not found
|
* @return pointer to type if found or NULL if not found
|
||||||
*/
|
*/
|
||||||
const SpaceInfo *findVarType(const SpaceInfo *start, const Token *type) const;
|
const Scope *findVariableType(const Scope *start, const Token *type) const;
|
||||||
|
|
||||||
bool argsMatch(const SpaceInfo *info, const Token *first, const Token *second, const std::string &path, unsigned int depth) const;
|
bool argsMatch(const Scope *info, const Token *first, const Token *second, const std::string &path, unsigned int depth) const;
|
||||||
|
|
||||||
bool isClassOrStruct(const std::string &type) const
|
bool isClassOrStruct(const std::string &type) const
|
||||||
{
|
{
|
||||||
|
@ -236,11 +239,11 @@ public:
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// Needed by Borland C++:
|
// Needed by Borland C++:
|
||||||
friend class SpaceInfo;
|
friend class Scope;
|
||||||
|
|
||||||
void addFunction(SpaceInfo **info, const Token **tok, const Token *argStart);
|
void addFunction(Scope **info, const Token **tok, const Token *argStart);
|
||||||
void addNewFunction(SpaceInfo **info, const Token **tok);
|
void addNewFunction(Scope **info, const Token **tok);
|
||||||
const Token *initBaseInfo(SpaceInfo *info, const Token *tok);
|
const Token *initBaseInfo(Scope *info, const Token *tok);
|
||||||
bool isFunction(const Token *tok, const Token **funcStart, const Token **argStart) const;
|
bool isFunction(const Token *tok, const Token **funcStart, const Token **argStart) const;
|
||||||
|
|
||||||
/** class/struct types */
|
/** class/struct types */
|
||||||
|
|
|
@ -7954,16 +7954,16 @@ const Token *Tokenizer::getFunctionTokenByName(const char funcname[]) const
|
||||||
if (_symbolDatabase == NULL)
|
if (_symbolDatabase == NULL)
|
||||||
getSymbolDatabase();
|
getSymbolDatabase();
|
||||||
|
|
||||||
std::list<SpaceInfo *>::const_iterator i;
|
std::list<Scope *>::const_iterator i;
|
||||||
|
|
||||||
for (i = _symbolDatabase->spaceInfoList.begin(); i != _symbolDatabase->spaceInfoList.end(); ++i)
|
for (i = _symbolDatabase->spaceInfoList.begin(); i != _symbolDatabase->spaceInfoList.end(); ++i)
|
||||||
{
|
{
|
||||||
const SpaceInfo *info = *i;
|
const Scope *scope = *i;
|
||||||
|
|
||||||
if (info->type == SpaceInfo::Function)
|
if (scope->type == Scope::eFunction)
|
||||||
{
|
{
|
||||||
if (info->classDef->str() == funcname)
|
if (scope->classDef->str() == funcname)
|
||||||
return info->classDef;
|
return scope->classDef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
|
|
||||||
#include "testsuite.h"
|
#include "testsuite.h"
|
||||||
#include "testutils.h"
|
#include "testutils.h"
|
||||||
#define private public
|
|
||||||
#include "symboldatabase.h"
|
#include "symboldatabase.h"
|
||||||
|
|
||||||
class TestSymbolDatabase: public TestFixture
|
class TestSymbolDatabase: public TestFixture
|
||||||
|
@ -32,7 +31,7 @@ public:
|
||||||
{}
|
{}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const SpaceInfo si;
|
const Scope si;
|
||||||
const Token* vartok;
|
const Token* vartok;
|
||||||
const Token* typetok;
|
const Token* typetok;
|
||||||
const Token* t;
|
const Token* t;
|
||||||
|
|
Loading…
Reference in New Issue