refactor symbol database and checks to use list of Scope rather than list of Scope pointers

This commit is contained in:
Robert Reif 2011-03-10 19:43:29 -05:00
parent 256e7dee21
commit 79f0fe7d1c
8 changed files with 191 additions and 219 deletions

View File

@ -136,12 +136,10 @@ void CheckAutoVariables::autoVariables()
{
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
std::list<Scope *>::const_iterator i;
std::list<Scope>::const_iterator scope;
for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i)
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope)
{
const Scope *scope = *i;
// only check functions
if (scope->type != Scope::eFunction)
continue;
@ -240,12 +238,10 @@ void CheckAutoVariables::returnPointerToLocalArray()
{
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
std::list<Scope *>::const_iterator i;
std::list<Scope>::const_iterator scope;
for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i)
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope)
{
const Scope *scope = *i;
// only check functions
if (scope->type != Scope::eFunction)
continue;
@ -325,12 +321,10 @@ void CheckAutoVariables::returnReference()
{
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
std::list<Scope *>::const_iterator i;
std::list<Scope>::const_iterator scope;
for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i)
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope)
{
const Scope *scope = *i;
// only check functions
if (scope->type != Scope::eFunction)
continue;
@ -407,12 +401,10 @@ void CheckAutoVariables::returncstr()
// locate function that returns a const char *..
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
std::list<Scope *>::const_iterator i;
std::list<Scope>::const_iterator scope;
for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i)
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope)
{
const Scope *scope = *i;
// only check functions
if (scope->type != Scope::eFunction)
continue;

View File

@ -68,12 +68,10 @@ void CheckClass::constructors()
createSymbolDatabase();
std::list<Scope *>::const_iterator i;
std::list<Scope>::const_iterator scope;
for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i)
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope)
{
const Scope *scope = *i;
// only check classes and structures
if (!scope->isClassOrStruct())
continue;
@ -107,7 +105,7 @@ void CheckClass::constructors()
clearAllVar(usage);
std::list<std::string> callstack;
initializeVarList(*func, callstack, scope, usage);
initializeVarList(*func, callstack, &(*scope), usage);
// Check if any variables are uninitialized
std::list<Variable>::const_iterator var;
@ -581,12 +579,10 @@ void CheckClass::privateFunctions()
createSymbolDatabase();
std::list<Scope *>::const_iterator i;
std::list<Scope>::const_iterator scope;
for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i)
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope)
{
const Scope *scope = *i;
// only check classes and structures
if (!scope->isClassOrStruct())
continue;
@ -832,18 +828,18 @@ void CheckClass::operatorEq()
createSymbolDatabase();
std::list<Scope *>::const_iterator i;
std::list<Scope>::const_iterator scope;
for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i)
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope)
{
std::list<Function>::const_iterator it;
std::list<Function>::const_iterator func;
for (it = (*i)->functionList.begin(); it != (*i)->functionList.end(); ++it)
for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func)
{
if (it->type == Function::eOperatorEqual && it->access != Private)
if (func->type == Function::eOperatorEqual && func->access != Private)
{
if (it->token->strAt(-1) == "void")
operatorEqReturnError(it->token->tokAt(-1));
if (func->token->strAt(-1) == "void")
operatorEqReturnError(func->token->tokAt(-1));
}
}
}
@ -927,12 +923,10 @@ void CheckClass::operatorEqRetRefThis()
createSymbolDatabase();
std::list<Scope *>::const_iterator i;
std::list<Scope>::const_iterator scope;
for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i)
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope)
{
const Scope *scope = *i;
// only check classes and structures
if (scope->isClassOrStruct())
{
@ -949,7 +943,7 @@ void CheckClass::operatorEqRetRefThis()
// find the ')'
const Token *tok = func->token->next()->link();
checkReturnPtrThis(scope, &(*func), tok->tokAt(2), tok->next()->link());
checkReturnPtrThis(&(*scope), &(*func), tok->tokAt(2), tok->next()->link());
}
}
}
@ -983,38 +977,37 @@ void CheckClass::operatorEqToSelf()
createSymbolDatabase();
std::list<Scope *>::const_iterator i;
std::list<Scope>::const_iterator scope;
for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i)
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope)
{
const Scope *scope = *i;
std::list<Function>::const_iterator it;
std::list<Function>::const_iterator func;
// skip classes with multiple inheritance
if (scope->derivedFrom.size() > 1)
continue;
for (it = scope->functionList.begin(); it != scope->functionList.end(); ++it)
for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func)
{
if (it->type == Function::eOperatorEqual && it->hasBody)
if (func->type == Function::eOperatorEqual && func->hasBody)
{
// make sure return signature is correct
if (Token::Match(it->tokenDef->tokAt(-3), ";|}|{|public:|protected:|private: %type% &") &&
it->tokenDef->strAt(-2) == scope->className)
if (Token::Match(func->tokenDef->tokAt(-3), ";|}|{|public:|protected:|private: %type% &") &&
func->tokenDef->strAt(-2) == scope->className)
{
// check for proper function parameter signature
if ((Token::Match(it->tokenDef->next(), "( const %var% & )") ||
Token::Match(it->tokenDef->next(), "( const %var% & %var% )")) &&
it->tokenDef->strAt(3) == scope->className)
if ((Token::Match(func->tokenDef->next(), "( const %var% & )") ||
Token::Match(func->tokenDef->next(), "( const %var% & %var% )")) &&
func->tokenDef->strAt(3) == scope->className)
{
// find the parameter name
const Token *rhs = it->token;
const Token *rhs = func->token;
while (rhs->str() != "&")
rhs = rhs->next();
rhs = rhs->next();
// find the ')'
const Token *tok = it->token->next()->link();
const Token *tok = func->token->next()->link();
const Token *tok1 = tok;
if (tok1 && tok1->tokAt(1) && tok1->tokAt(1)->str() == "{" && tok1->tokAt(1)->link())
@ -1160,12 +1153,10 @@ void CheckClass::virtualDestructor()
createSymbolDatabase();
std::list<Scope *>::const_iterator i;
std::list<Scope>::const_iterator scope;
for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i)
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope)
{
const Scope *scope = *i;
// Skip base classes and namespaces
if (scope->derivedFrom.empty())
continue;
@ -1279,12 +1270,10 @@ void CheckClass::checkConst()
createSymbolDatabase();
std::list<Scope *>::const_iterator it;
std::list<Scope>::const_iterator scope;
for (it = symbolDatabase->scopeList.begin(); it != symbolDatabase->scopeList.end(); ++it)
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope)
{
const Scope *scope = *it;
// only check classes and structures
if (!scope->isClassOrStruct())
continue;
@ -1354,12 +1343,12 @@ void CheckClass::checkConst()
// check if base class function is virtual
if (!scope->derivedFrom.empty())
{
if (isVirtualFunc(scope, func->tokenDef))
if (isVirtualFunc(&(*scope), func->tokenDef))
continue;
}
// if nothing non-const was found. write error..
if (checkConstFunc(scope, paramEnd))
if (checkConstFunc(&(*scope), paramEnd))
{
std::string classname = scope->className;
const Scope *nest = scope->nestedIn;

View File

@ -573,12 +573,10 @@ void CheckMemoryLeakInFunction::parse_noreturn()
noreturn.insert("errx");
noreturn.insert("verrx");
std::list<Scope *>::const_iterator i;
std::list<Scope>::const_iterator scope;
for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i)
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope)
{
const Scope *scope = *i;
// only check functions
if (scope->type != Scope::eFunction)
continue;
@ -2501,12 +2499,10 @@ void CheckMemoryLeakInFunction::checkScope(const Token *Tok1, const std::string
//---------------------------------------------------------------------------
void CheckMemoryLeakInFunction::checkReallocUsage()
{
std::list<Scope *>::const_iterator i;
std::list<Scope>::const_iterator scope;
for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i)
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope)
{
const Scope *scope = *i;
// only check functions
if (scope->type != Scope::eFunction)
continue;
@ -2654,12 +2650,10 @@ void CheckMemoryLeakInFunction::check()
// fill the "noreturn"
parse_noreturn();
std::list<Scope *>::const_iterator i;
std::list<Scope>::const_iterator scope;
for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i)
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope)
{
const Scope *scope = *i;
// only check functions
if (scope->type != Scope::eFunction)
continue;
@ -2711,12 +2705,10 @@ void CheckMemoryLeakInClass::check()
{
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
std::list<Scope *>::const_iterator i;
std::list<Scope>::const_iterator scope;
for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i)
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope)
{
const Scope *scope = *i;
// only check classes and structures
if (scope->isClassOrStruct())
{
@ -2729,9 +2721,9 @@ void CheckMemoryLeakInClass::check()
if (var->nameToken()->tokAt(-2)->isStandardType())
{
if (var->isPrivate())
checkPublicFunctions(scope, var->nameToken());
checkPublicFunctions(&(*scope), var->nameToken());
variable(scope, var->nameToken());
variable(&(*scope), var->nameToken());
}
// known class?
@ -2741,9 +2733,9 @@ void CheckMemoryLeakInClass::check()
if (var->type()->derivedFrom.empty())
{
if (var->isPrivate())
checkPublicFunctions(scope, var->nameToken());
checkPublicFunctions(&(*scope), var->nameToken());
variable(scope, var->nameToken());
variable(&(*scope), var->nameToken());
}
}
}
@ -3177,12 +3169,10 @@ void CheckMemoryLeakNoVar::check()
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
std::list<Scope *>::const_iterator i;
std::list<Scope>::const_iterator scope;
for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i)
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope)
{
Scope *scope = *i;
// only check functions
if (scope->type != Scope::eFunction)
continue;

View File

@ -1645,25 +1645,23 @@ void CheckOther::functionVariableUsage()
// Parse all executing scopes..
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
std::list<Scope *>::const_iterator i;
std::list<Scope>::const_iterator scope;
for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i)
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope)
{
const Scope *info = *i;
// only check functions
if (info->type != Scope::eFunction)
if (scope->type != Scope::eFunction)
continue;
// First token for the current scope..
const Token *const tok1 = info->classStart;
const Token *const tok1 = scope->classStart;
// varId, usage {read, write, modified}
Variables variables;
// scopes
ScopeInfo scopes;
ScopeInfo *scope = &scopes;
ScopeInfo *info = &scopes;
unsigned int indentlevel = 0;
for (const Token *tok = tok1; tok; tok = tok->next())
@ -1675,14 +1673,14 @@ void CheckOther::functionVariableUsage()
scopes = ScopeInfo(tok, NULL);
// add the new scope
else
scope = scope->addChild(tok);
info = info->addChild(tok);
++indentlevel;
}
else if (tok->str() == "}")
{
--indentlevel;
scope = scope->parent();
info = info->parent();
if (indentlevel == 0)
break;
@ -1713,7 +1711,7 @@ void CheckOther::functionVariableUsage()
if (tok->str() == "static")
tok = tok->next();
variables.addVar(tok->next(), Variables::standard, scope,
variables.addVar(tok->next(), Variables::standard, info,
tok->tokAt(2)->str() == "=" ||
tok->previous()->str() == "static");
tok = tok->next();
@ -1729,7 +1727,7 @@ void CheckOther::functionVariableUsage()
if (tok->str() == "static")
tok = tok->next();
variables.addVar(tok->next(), Variables::standard, scope, true);
variables.addVar(tok->next(), Variables::standard, info, true);
// check if a local variable is used to initialize this variable
if (tok->tokAt(3)->varId() > 0)
@ -1760,7 +1758,7 @@ void CheckOther::functionVariableUsage()
bool isPointer = bool(tok->strAt(1) == "*");
const Token * const nametok = tok->tokAt(isPointer ? 2 : 1);
variables.addVar(nametok, isPointer ? Variables::pointerArray : Variables::array, scope,
variables.addVar(nametok, isPointer ? Variables::pointerArray : Variables::array, info,
nametok->tokAt(4)->str() == "=" || isStatic);
// check for reading array size from local variable
@ -1814,13 +1812,13 @@ void CheckOther::functionVariableUsage()
bool written = tok->tokAt(3)->str() == "=";
variables.addVar(tok->tokAt(2), type, scope, written || isStatic);
variables.addVar(tok->tokAt(2), type, info, written || isStatic);
int offset = 0;
// check for assignment
if (written)
offset = doAssignment(variables, tok->tokAt(2), false, scope);
offset = doAssignment(variables, tok->tokAt(2), false, info);
tok = tok->tokAt(2 + offset);
}
@ -1847,13 +1845,13 @@ void CheckOther::functionVariableUsage()
{
bool written = tok->tokAt(4)->str() == "=";
variables.addVar(tok->tokAt(3), Variables::pointerPointer, scope, written || isStatic);
variables.addVar(tok->tokAt(3), Variables::pointerPointer, info, written || isStatic);
int offset = 0;
// check for assignment
if (written)
offset = doAssignment(variables, tok->tokAt(3), false, scope);
offset = doAssignment(variables, tok->tokAt(3), false, info);
tok = tok->tokAt(3 + offset);
}
@ -1884,13 +1882,13 @@ void CheckOther::functionVariableUsage()
const bool written = tok->strAt(4) == "=";
variables.addVar(tok->tokAt(3), type, scope, written || isStatic);
variables.addVar(tok->tokAt(3), type, info, written || isStatic);
int offset = 0;
// check for assignment
if (written)
offset = doAssignment(variables, tok->tokAt(3), false, scope);
offset = doAssignment(variables, tok->tokAt(3), false, info);
tok = tok->tokAt(3 + offset);
}
@ -1921,7 +1919,7 @@ void CheckOther::functionVariableUsage()
if (Token::Match(tok->tokAt(4), "%var%"))
varid = tok->tokAt(4)->varId();
variables.addVar(tok->tokAt(2), type, scope, true);
variables.addVar(tok->tokAt(2), type, info, true);
// check if a local variable is used to initialize this variable
if (varid > 0)
@ -1966,7 +1964,7 @@ void CheckOther::functionVariableUsage()
if (tok->str() != "return")
{
variables.addVar(tok->tokAt(2),
tok->next()->str() == "*" ? Variables::pointerArray : Variables::referenceArray, scope,
tok->next()->str() == "*" ? Variables::pointerArray : Variables::referenceArray, info,
tok->tokAt(6)->str() == "=" || isStatic);
// check for reading array size from local variable
@ -1995,7 +1993,7 @@ void CheckOther::functionVariableUsage()
tok = tok->next();
variables.addVar(tok->tokAt(3),
tok->tokAt(2)->str() == "*" ? Variables::pointerArray : Variables::referenceArray, scope,
tok->tokAt(2)->str() == "*" ? Variables::pointerArray : Variables::referenceArray, info,
tok->tokAt(7)->str() == "=" || isStatic);
// check for reading array size from local variable
@ -2069,7 +2067,7 @@ void CheckOther::functionVariableUsage()
const unsigned int varid1 = tok->varId();
const Token *start = tok;
tok = tok->tokAt(doAssignment(variables, tok, dereference, scope));
tok = tok->tokAt(doAssignment(variables, tok, dereference, info));
if (pre || post)
variables.use(varid1);
@ -2099,7 +2097,7 @@ void CheckOther::functionVariableUsage()
if (!start->tokAt(3)->isStandardType())
{
// lookup the type
const Scope *type = symbolDatabase->findVariableType(info, start->tokAt(3));
const Scope *type = symbolDatabase->findVariableType(&(*scope), start->tokAt(3));
// unknown type?
if (!type)
@ -2316,12 +2314,10 @@ void CheckOther::checkVariableScope()
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
std::list<Scope *>::const_iterator i;
std::list<Scope>::const_iterator scope;
for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i)
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope)
{
const Scope *scope = *i;
// only check functions
if (scope->type != Scope::eFunction)
continue;
@ -2957,12 +2953,10 @@ void CheckOther::checkMisusedScopedObject()
const SymbolDatabase * const symbolDatabase = _tokenizer->getSymbolDatabase();
std::list<Scope *>::const_iterator i;
std::list<Scope>::const_iterator scope;
for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i)
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope)
{
const Scope *scope = *i;
// only check functions
if (scope->type != Scope::eFunction)
continue;

View File

@ -38,30 +38,33 @@
SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
: _tokenizer(tokenizer), _settings(settings), _errorLogger(errorLogger)
{
// find all namespaces (class,struct and namespace)
Scope *scope = new Scope(this, NULL, NULL);
scopeList.push_back(scope);
// create global scope
scopeList.push_back(Scope(this, NULL, NULL));
// pointer to current scope
Scope *scope = &scopeList.back();
// find all scopes
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
{
// Locate next class
if (Token::Match(tok, "class|struct|namespace %var% [{:]"))
if (Token::Match(tok, "class|struct|union|namespace %var% [{:]"))
{
Scope *new_scope = new Scope(this, tok, scope);
scopeList.push_back(Scope(this, tok, scope));
Scope *new_scope = &scopeList.back();
const Token *tok2 = tok->tokAt(2);
// only create base list for classes and structures
if (new_scope->isClassOrStruct())
{
// fill the classAndStructTypes set..
classAndStructTypes.insert(new_scope->className);
// goto initial '{'
tok2 = initBaseInfo(new_scope, tok);
// make sure we have valid code
if (!tok2)
{
delete new_scope;
scopeList.pop_back();
break;
}
}
@ -72,14 +75,17 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
// make sure we have valid code
if (!new_scope->classEnd)
{
delete new_scope;
scopeList.pop_back();
break;
}
scope = new_scope;
// fill the classAndStructTypes set..
if (new_scope->isClassOrStruct())
classAndStructTypes.insert(new_scope->className);
// add namespace
scopeList.push_back(scope);
// make the new scope the current scope
scope = &scopeList.back();
scope->nestedIn->nestedList.push_back(scope);
tok = tok2;
}
@ -156,16 +162,23 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
// class constructor/destructor
else if (function.tokenDef->str() == scope->className)
{
// destructor
if (function.tokenDef->previous()->str() == "~")
function.type = Function::eDestructor;
// copy constructor
else if ((Token::Match(function.tokenDef, "%var% ( const %var% & )") ||
Token::Match(function.tokenDef, "%var% ( const %var% & %var% )")) &&
function.tokenDef->strAt(3) == scope->className)
function.type = Function::eCopyConstructor;
// copy constructor with non-const argument
else if ((Token::Match(function.tokenDef, "%var% ( %var% & )") ||
Token::Match(function.tokenDef, "%var% ( %var% & %var% )")) &&
function.tokenDef->strAt(2) == scope->className)
function.type = Function::eCopyConstructor;
// regular constructor
else
function.type = Function::eConstructor;
@ -404,60 +417,75 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
if (Token::simpleMatch(tok, "if (") &&
Token::simpleMatch(tok->next()->link(), ") {"))
{
scope = new Scope(this, tok, scope, Scope::eIf, tok->next()->link()->next());
tok = tok->next()->link()->next();
scopeList.push_back(scope);
const Token *tok1 = tok->next()->link()->next();
scopeList.push_back(Scope(this, tok, scope, Scope::eIf, tok1));
tok = tok1;
scope = &scopeList.back();
scope->nestedIn->nestedList.push_back(scope);
}
else if (Token::simpleMatch(tok, "else {"))
{
scope = new Scope(this, tok, scope, Scope::eElse, tok->next());
tok = tok->next();
scopeList.push_back(scope);
const Token *tok1 = tok->next();
scopeList.push_back(Scope(this, tok, scope, Scope::eElse, tok1));
tok = tok1;
scope = &scopeList.back();
scope->nestedIn->nestedList.push_back(scope);
}
else if (Token::simpleMatch(tok, "else if (") &&
Token::simpleMatch(tok->next()->next()->link(), ") {"))
{
scope = new Scope(this, tok, scope, Scope::eElseIf, tok->next()->next()->link()->next());
tok = tok->next()->next()->link()->next();
scopeList.push_back(scope);
const Token *tok1 = tok->next()->next()->link()->next();
scopeList.push_back(Scope(this, tok, scope, Scope::eElseIf, tok1));
tok = tok1;
scope = &scopeList.back();
scope->nestedIn->nestedList.push_back(scope);
}
else if (Token::simpleMatch(tok, "for (") &&
Token::simpleMatch(tok->next()->link(), ") {"))
{
// save location of initialization
const Token *tok1 = tok->tokAt(2);
scope = new Scope(this, tok, scope, Scope::eFor, tok->next()->link()->next());
tok = tok->next()->link()->next();
scopeList.push_back(scope);
const Token *tok1 = tok->next()->link()->next();
const Token *tok2 = tok->tokAt(2);
scopeList.push_back(Scope(this, tok, scope, Scope::eFor, tok1));
tok = tok1;
scope = &scopeList.back();
scope->nestedIn->nestedList.push_back(scope);
// check for variable declaration and add it to new scope if found
scope->checkVariable(tok1, Local);
scope->checkVariable(tok2, Local);
}
else if (Token::simpleMatch(tok, "while (") &&
Token::simpleMatch(tok->next()->link(), ") {"))
{
scope = new Scope(this, tok, scope, Scope::eWhile, tok->next()->link()->next());
tok = tok->next()->link()->next();
scopeList.push_back(scope);
const Token *tok1 = tok->next()->link()->next();
scopeList.push_back(Scope(this, tok, scope, Scope::eWhile, tok1));
tok = tok1;
scope = &scopeList.back();
scope->nestedIn->nestedList.push_back(scope);
}
else if (Token::simpleMatch(tok, "do {"))
{
scope = new Scope(this, tok, scope, Scope::eDo, tok->next());
tok = tok->next();
scopeList.push_back(scope);
const Token *tok1 = tok->next();
scopeList.push_back(Scope(this, tok, scope, Scope::eDo, tok1));
tok = tok1;
scope = &scopeList.back();
scope->nestedIn->nestedList.push_back(scope);
}
else if (Token::simpleMatch(tok, "switch (") &&
Token::simpleMatch(tok->next()->link(), ") {"))
{
scope = new Scope(this, tok, scope, Scope::eSwitch, tok->next()->link()->next());
tok = tok->next()->link()->next();
scopeList.push_back(scope);
const Token *tok1 = tok->next()->link()->next();
scopeList.push_back(Scope(this, tok, scope, Scope::eSwitch, tok1));
tok = tok1;
scope = &scopeList.back();
scope->nestedIn->nestedList.push_back(scope);
}
else if (tok->str() == "{")
{
if (!Token::Match(tok->previous(), "=|,|{"))
{
scope = new Scope(this, tok, scope, Scope::eUnconditional, tok);
scopeList.push_back(scope);
scopeList.push_back(Scope(this, tok, scope, Scope::eUnconditional, tok));
scope = &scopeList.back();
scope->nestedIn->nestedList.push_back(scope);
}
else
{
@ -468,12 +496,12 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
}
}
std::list<Scope *>::iterator it;
std::list<Scope>::iterator it;
// fill in base class info
for (it = scopeList.begin(); it != scopeList.end(); ++it)
{
scope = *it;
scope = &(*it);
// skip namespaces and functions
if (!scope->isClassOrStruct())
@ -482,11 +510,11 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
// finish filling in base class info
for (unsigned int i = 0; i < scope->derivedFrom.size(); ++i)
{
std::list<Scope *>::iterator it1;
std::list<Scope>::iterator it1;
for (it1 = scopeList.begin(); it1 != scopeList.end(); ++it1)
{
Scope *scope1 = *it1;
Scope *scope1 = &(*it1);
/** @todo handle derived base classes and namespaces */
if (scope1->type == Scope::eClass || scope1->type == Scope::eStruct)
@ -512,7 +540,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
// fill in variable info
for (it = scopeList.begin(); it != scopeList.end(); ++it)
{
scope = *it;
scope = &(*it);
// find variables
scope->getVariableList();
@ -521,7 +549,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
// fill in function arguments
for (it = scopeList.begin(); it != scopeList.end(); ++it)
{
scope = *it;
scope = &(*it);
std::list<Function>::iterator func;
@ -542,7 +570,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
for (it = scopeList.begin(); it != scopeList.end(); ++it)
{
scope = *it;
scope = &(*it);
if (scope->isClassOrStruct() && scope->needInitialization == Scope::Unknown)
{
@ -624,7 +652,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
{
for (it = scopeList.begin(); it != scopeList.end(); ++it)
{
scope = *it;
scope = &(*it);
if (scope->isClassOrStruct() && scope->needInitialization == Scope::Unknown)
debugMessage(scope->classDef, "SymbolDatabase::SymbolDatabase couldn't resolve all user defined types.");
@ -638,7 +666,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
// check all scopes for variables
for (it = scopeList.begin(); it != scopeList.end(); ++it)
{
scope = *it;
scope = &(*it);
// add all variables
std::list<Variable>::const_iterator var;
@ -646,7 +674,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
{
unsigned int varId = var->varId();
if (varId)
_variableList[varId] = &*var;
_variableList[varId] = &(*var);
}
// add all function paramaters
@ -665,21 +693,13 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
{
unsigned int varId = arg->varId();
if (varId)
_variableList[varId] = &*arg;
_variableList[varId] = &(*arg);
}
}
}
}
}
SymbolDatabase::~SymbolDatabase()
{
std::list<Scope *>::iterator it;
for (it = scopeList.begin(); it != scopeList.end(); ++it)
delete *it;
}
bool SymbolDatabase::isFunction(const Token *tok, const Token **funcStart, const Token **argStart) const
{
// function returning function pointer? '... ( ... %var% ( ... ))( ... ) {'
@ -826,12 +846,12 @@ void SymbolDatabase::addFunction(Scope **scope, const Token **tok, const Token *
path_length++;
}
std::list<Scope *>::iterator it1;
std::list<Scope>::iterator it1;
// search for match
for (it1 = scopeList.begin(); it1 != scopeList.end(); ++it1)
{
Scope *scope1 = *it1;
Scope *scope1 = &(*it1);
bool match = false;
if (scope1->className == tok1->str() && (scope1->type != Scope::eFunction))
@ -940,7 +960,8 @@ void SymbolDatabase::addFunction(Scope **scope, const Token **tok, const Token *
void SymbolDatabase::addNewFunction(Scope **scope, const Token **tok)
{
const Token *tok1 = *tok;
Scope *new_scope = new Scope(this, tok1, *scope);
scopeList.push_back(Scope(this, tok1, *scope));
Scope *new_scope = &scopeList.back();
// skip to start of function
while (tok1 && tok1->str() != "{")
@ -954,8 +975,7 @@ void SymbolDatabase::addNewFunction(Scope **scope, const Token **tok)
// syntax error?
if (!new_scope->classEnd)
{
(*scope)->nestedList.pop_back();
delete new_scope;
scopeList.pop_back();
while (tok1->next())
tok1 = tok1->next();
*scope = NULL;
@ -964,16 +984,12 @@ void SymbolDatabase::addNewFunction(Scope **scope, const Token **tok)
}
*scope = new_scope;
// add space
scopeList.push_back(new_scope);
*tok = tok1;
(*scope)->nestedIn->nestedList.push_back(*scope);
}
else
{
(*scope)->nestedList.pop_back();
delete new_scope;
scopeList.pop_back();
*scope = NULL;
*tok = NULL;
}
@ -1208,7 +1224,6 @@ Scope::Scope(SymbolDatabase *check_, const Token *classDef_, Scope *nestedIn_, S
needInitialization(Scope::Unknown),
functionOf(NULL)
{
nestedIn->nestedList.push_back(this);
}
Scope::Scope(SymbolDatabase *check_, const Token *classDef_, Scope *nestedIn_) :
@ -1256,9 +1271,6 @@ Scope::Scope(SymbolDatabase *check_, const Token *classDef_, Scope *nestedIn_) :
className = classDef->str();
access = Public;
}
if (nestedIn)
nestedIn->nestedList.push_back(this);
}
bool
@ -1587,12 +1599,10 @@ bool Scope::findClosingBracket(const Token* tok, const Token*& close) const
const Scope *SymbolDatabase::findVariableType(const Scope *start, const Token *type) const
{
std::list<Scope *>::const_iterator it;
std::list<Scope>::const_iterator scope;
for (it = scopeList.begin(); it != scopeList.end(); ++it)
for (scope = scopeList.begin(); scope != scopeList.end(); ++scope)
{
const Scope *scope = *it;
// skip namespaces and functions
if (scope->type == Scope::eNamespace || scope->type == Scope::eFunction || scope->type == Scope::eGlobal)
continue;
@ -1610,14 +1620,14 @@ const Scope *SymbolDatabase::findVariableType(const Scope *start, const Token *t
parent = parent->nestedIn;
if (scope->nestedIn == parent)
return scope;
return &(*scope);
}
// type has a namespace
else
{
// FIXME check if namespace path matches supplied path
return scope;
return &(*scope);
}
}
}
@ -1629,14 +1639,14 @@ const Scope *SymbolDatabase::findVariableType(const Scope *start, const Token *t
const Scope *SymbolDatabase::findFunctionScopeByToken(const Token *tok) const
{
std::list<Scope *>::const_iterator scope;
std::list<Scope>::const_iterator scope;
for (scope = scopeList.begin(); scope != scopeList.end(); ++scope)
{
if ((*scope)->type == Scope::eFunction)
if (scope->type == Scope::eFunction)
{
if ((*scope)->classDef == tok)
return (*scope);
if (scope->classDef == tok)
return &(*scope);
}
}
return 0;
@ -1646,16 +1656,16 @@ const Scope *SymbolDatabase::findFunctionScopeByToken(const Token *tok) const
const Function *SymbolDatabase::findFunctionByToken(const Token *tok) const
{
std::list<Scope *>::const_iterator scope;
std::list<Scope>::const_iterator scope;
for (scope = scopeList.begin(); scope != scopeList.end(); ++scope)
{
std::list<Function>::const_iterator func;
for (func = (*scope)->functionList.begin(); func != (*scope)->functionList.end(); ++func)
for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func)
{
if (func->token == tok)
return &*func;
return &(*func);
}
}
return 0;
@ -1704,7 +1714,7 @@ const Function *Scope::getDestructor() const
for (it = functionList.begin(); it != functionList.end(); ++it)
{
if (it->type == Function::eDestructor)
return &*it;
return &(*it);
}
return 0;
}

View File

@ -479,10 +479,9 @@ class SymbolDatabase
{
public:
SymbolDatabase(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger);
~SymbolDatabase();
/** @brief Information about all namespaces/classes/structrues */
std::list<Scope *> scopeList;
std::list<Scope> scopeList;
/**
* @brief find a variable type if it's a user defined type

View File

@ -8131,12 +8131,10 @@ const Token *Tokenizer::getFunctionTokenByName(const char funcname[]) const
{
getSymbolDatabase();
std::list<Scope *>::const_iterator i;
std::list<Scope>::const_iterator scope;
for (i = _symbolDatabase->scopeList.begin(); i != _symbolDatabase->scopeList.end(); ++i)
for (scope = _symbolDatabase->scopeList.begin(); scope != _symbolDatabase->scopeList.end(); ++scope)
{
const Scope *scope = *i;
if (scope->type == Scope::eFunction)
{
if (scope->classDef->str() == funcname)

View File

@ -558,11 +558,11 @@ private:
ASSERT(db && db->scopeList.size() == 1);
if (db && db->scopeList.size() == 1)
{
std::list<Scope *>::const_iterator it = db->scopeList.begin();
ASSERT((*it)->varlist.size() == 1);
if ((*it)->varlist.size() == 1)
std::list<Scope>::const_iterator it = db->scopeList.begin();
ASSERT(it->varlist.size() == 1);
if (it->varlist.size() == 1)
{
std::list<Variable>::const_iterator var = (*it)->varlist.begin();
std::list<Variable>::const_iterator var = it->varlist.begin();
ASSERT(var->name() == "i");
ASSERT(var->typeStartToken()->str() == "int");
}
@ -576,11 +576,11 @@ private:
ASSERT(db && db->scopeList.size() == 1);
if (db && db->scopeList.size() == 1)
{
std::list<Scope *>::const_iterator it = db->scopeList.begin();
ASSERT((*it)->varlist.size() == 1);
if ((*it)->varlist.size() == 1)
std::list<Scope>::const_iterator it = db->scopeList.begin();
ASSERT(it->varlist.size() == 1);
if (it->varlist.size() == 1)
{
std::list<Variable>::const_iterator var = (*it)->varlist.begin();
std::list<Variable>::const_iterator var = it->varlist.begin();
ASSERT(var->name() == "array");
ASSERT(var->typeStartToken()->str() == "int");
}
@ -594,11 +594,11 @@ private:
ASSERT(db && db->scopeList.size() == 1);
if (db && db->scopeList.size() == 1)
{
std::list<Scope *>::const_iterator it = db->scopeList.begin();
ASSERT((*it)->varlist.size() == 1);
if ((*it)->varlist.size() == 1)
std::list<Scope>::const_iterator it = db->scopeList.begin();
ASSERT(it->varlist.size() == 1);
if (it->varlist.size() == 1)
{
std::list<Variable>::const_iterator var = (*it)->varlist.begin();
std::list<Variable>::const_iterator var = it->varlist.begin();
ASSERT(var->name() == "array");
ASSERT(var->typeStartToken()->str() == "int");
}