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(); 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 // only check functions
if (scope->type != Scope::eFunction) if (scope->type != Scope::eFunction)
continue; continue;
@ -240,12 +238,10 @@ void CheckAutoVariables::returnPointerToLocalArray()
{ {
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); 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 // only check functions
if (scope->type != Scope::eFunction) if (scope->type != Scope::eFunction)
continue; continue;
@ -325,12 +321,10 @@ void CheckAutoVariables::returnReference()
{ {
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); 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 // only check functions
if (scope->type != Scope::eFunction) if (scope->type != Scope::eFunction)
continue; continue;
@ -407,12 +401,10 @@ void CheckAutoVariables::returncstr()
// locate function that returns a const char *.. // locate function that returns a const char *..
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); 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 // only check functions
if (scope->type != Scope::eFunction) if (scope->type != Scope::eFunction)
continue; continue;

View File

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

View File

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

View File

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

View File

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

View File

@ -479,10 +479,9 @@ class SymbolDatabase
{ {
public: public:
SymbolDatabase(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger); SymbolDatabase(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger);
~SymbolDatabase();
/** @brief Information about all namespaces/classes/structrues */ /** @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 * @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(); 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->type == Scope::eFunction)
{ {
if (scope->classDef->str() == funcname) if (scope->classDef->str() == funcname)

View File

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