Symbol database: reuse in CheckOther. Ticket: #2318
This commit is contained in:
parent
bf136f0123
commit
f2d69acbfd
|
@ -20,6 +20,7 @@
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
#include "checkother.h"
|
#include "checkother.h"
|
||||||
#include "mathlib.h"
|
#include "mathlib.h"
|
||||||
|
#include "symboldatabase.h"
|
||||||
|
|
||||||
#include <cctype> // std::isupper
|
#include <cctype> // std::isupper
|
||||||
#include <cmath> // fabs()
|
#include <cmath> // fabs()
|
||||||
|
@ -1192,17 +1193,20 @@ void CheckOther::functionVariableUsage()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Parse all executing scopes..
|
// Parse all executing scopes..
|
||||||
for (const Token *token = Token::findmatch(_tokenizer->tokens(), ") const| {"); token;)
|
SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||||
|
|
||||||
|
std::list<SymbolDatabase::SpaceInfo *>::const_iterator i;
|
||||||
|
|
||||||
|
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
|
||||||
{
|
{
|
||||||
// goto "{"
|
SymbolDatabase::SpaceInfo *info = *i;
|
||||||
while (token->str() != "{")
|
|
||||||
token = token->next();
|
// only check functions
|
||||||
|
if (info->type != SymbolDatabase::SpaceInfo::Function)
|
||||||
|
continue;
|
||||||
|
|
||||||
// First token for the current scope..
|
// First token for the current scope..
|
||||||
const Token *const tok1 = token;
|
const Token *const tok1 = info->classStart;
|
||||||
|
|
||||||
// Find next scope that will be checked next time..
|
|
||||||
token = Token::findmatch(token->link(), ") const| {");
|
|
||||||
|
|
||||||
// varId, usage {read, write, modified}
|
// varId, usage {read, write, modified}
|
||||||
Variables variables;
|
Variables variables;
|
||||||
|
@ -1820,74 +1824,83 @@ void CheckOther::checkVariableScope()
|
||||||
if (!_settings->_checkCodingStyle)
|
if (!_settings->_checkCodingStyle)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Walk through all tokens..
|
SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||||
bool func = false;
|
|
||||||
int indentlevel = 0;
|
std::list<SymbolDatabase::SpaceInfo *>::const_iterator i;
|
||||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
|
||||||
|
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
|
||||||
{
|
{
|
||||||
// Skip class and struct declarations..
|
SymbolDatabase::SpaceInfo *info = *i;
|
||||||
if ((tok->str() == "class") || (tok->str() == "struct"))
|
|
||||||
|
// only check functions
|
||||||
|
if (info->type != SymbolDatabase::SpaceInfo::Function)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Walk through all tokens..
|
||||||
|
int indentlevel = 0;
|
||||||
|
for (const Token *tok = info->classStart; tok; tok = tok->next())
|
||||||
{
|
{
|
||||||
for (const Token *tok2 = tok; tok2; tok2 = tok2->next())
|
// Skip function local class and struct declarations..
|
||||||
|
if ((tok->str() == "class") || (tok->str() == "struct") || (tok->str() == "union"))
|
||||||
{
|
{
|
||||||
if (tok2->str() == "{")
|
for (const Token *tok2 = tok; tok2; tok2 = tok2->next())
|
||||||
{
|
{
|
||||||
tok = tok2->link();
|
if (tok2->str() == "{")
|
||||||
|
{
|
||||||
|
tok = tok2->link();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (Token::Match(tok2, "[,);]"))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (! tok)
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
if (Token::Match(tok2, "[,);]"))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (! tok)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (tok->str() == "{")
|
else if (tok->str() == "{")
|
||||||
{
|
|
||||||
++indentlevel;
|
|
||||||
}
|
|
||||||
else if (tok->str() == "}")
|
|
||||||
{
|
|
||||||
--indentlevel;
|
|
||||||
if (indentlevel == 0)
|
|
||||||
func = false;
|
|
||||||
}
|
|
||||||
if (indentlevel == 0 && Token::simpleMatch(tok, ") {"))
|
|
||||||
{
|
|
||||||
func = true;
|
|
||||||
}
|
|
||||||
if (indentlevel > 0 && func && Token::Match(tok, "[{};]"))
|
|
||||||
{
|
|
||||||
// First token of statement..
|
|
||||||
const Token *tok1 = tok->next();
|
|
||||||
if (! tok1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ((tok1->str() == "return") ||
|
|
||||||
(tok1->str() == "throw") ||
|
|
||||||
(tok1->str() == "delete") ||
|
|
||||||
(tok1->str() == "goto") ||
|
|
||||||
(tok1->str() == "else"))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Variable declaration?
|
|
||||||
if (Token::Match(tok1, "%type% %var% ; %var% = %num% ;"))
|
|
||||||
{
|
{
|
||||||
// Tokenizer modify "int i = 0;" to "int i; i = 0;",
|
++indentlevel;
|
||||||
// so to handle this situation we just skip
|
|
||||||
// initialization (see ticket #272).
|
|
||||||
const unsigned int firstVarId = tok1->next()->varId();
|
|
||||||
const unsigned int secondVarId = tok1->tokAt(3)->varId();
|
|
||||||
if (firstVarId > 0 && firstVarId == secondVarId)
|
|
||||||
{
|
|
||||||
lookupVar(tok1->tokAt(6), tok1->strAt(1));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (tok1->isStandardType() && Token::Match(tok1, "%type% %var% [;=]"))
|
else if (tok->str() == "}")
|
||||||
{
|
{
|
||||||
lookupVar(tok1, tok1->strAt(1));
|
--indentlevel;
|
||||||
|
if (indentlevel == 0)
|
||||||
|
break;;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (indentlevel > 0 && Token::Match(tok, "[{};]"))
|
||||||
|
{
|
||||||
|
// First token of statement..
|
||||||
|
const Token *tok1 = tok->next();
|
||||||
|
if (! tok1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((tok1->str() == "return") ||
|
||||||
|
(tok1->str() == "throw") ||
|
||||||
|
(tok1->str() == "delete") ||
|
||||||
|
(tok1->str() == "goto") ||
|
||||||
|
(tok1->str() == "else"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Variable declaration?
|
||||||
|
if (Token::Match(tok1, "%type% %var% ; %var% = %num% ;"))
|
||||||
|
{
|
||||||
|
// Tokenizer modify "int i = 0;" to "int i; i = 0;",
|
||||||
|
// so to handle this situation we just skip
|
||||||
|
// initialization (see ticket #272).
|
||||||
|
const unsigned int firstVarId = tok1->next()->varId();
|
||||||
|
const unsigned int secondVarId = tok1->tokAt(3)->varId();
|
||||||
|
if (firstVarId > 0 && firstVarId == secondVarId)
|
||||||
|
{
|
||||||
|
lookupVar(tok1->tokAt(6), tok1->strAt(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (tok1->isStandardType() && Token::Match(tok1, "%type% %var% [;=]"))
|
||||||
|
{
|
||||||
|
lookupVar(tok1, tok1->strAt(1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,13 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
new_info->classStart = tok2;
|
new_info->classStart = tok2;
|
||||||
new_info->classEnd = tok2->link();
|
new_info->classEnd = tok2->link();
|
||||||
|
|
||||||
|
// make sure we have valid code
|
||||||
|
if (!new_info->classEnd)
|
||||||
|
{
|
||||||
|
delete new_info;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
info = new_info;
|
info = new_info;
|
||||||
|
|
||||||
// add namespace
|
// add namespace
|
||||||
|
@ -221,7 +228,8 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
SpaceInfo *functionOf = info;
|
SpaceInfo *functionOf = info;
|
||||||
|
|
||||||
addNewFunction(&info, &tok2);
|
addNewFunction(&info, &tok2);
|
||||||
info->functionOf = functionOf;
|
if (info)
|
||||||
|
info->functionOf = functionOf;
|
||||||
|
|
||||||
tok = tok2;
|
tok = tok2;
|
||||||
}
|
}
|
||||||
|
@ -283,9 +291,19 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
function.arg = function.argDef;
|
function.arg = function.argDef;
|
||||||
function.type = Func::Function;
|
function.type = Func::Function;
|
||||||
|
|
||||||
info->functionList.push_back(function);
|
SpaceInfo *old_info = info;
|
||||||
|
|
||||||
addNewFunction(&info, &tok);
|
addNewFunction(&info, &tok);
|
||||||
|
|
||||||
|
if (info)
|
||||||
|
old_info->functionList.push_back(function);
|
||||||
|
|
||||||
|
// syntax error
|
||||||
|
else
|
||||||
|
{
|
||||||
|
info = old_info;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,6 +312,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;
|
||||||
|
|
||||||
// class function
|
// class function
|
||||||
if (tok1->previous()->str() == "::")
|
if (tok1->previous()->str() == "::")
|
||||||
|
@ -303,6 +322,10 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
else
|
else
|
||||||
addNewFunction(&info, &tok1);
|
addNewFunction(&info, &tok1);
|
||||||
|
|
||||||
|
// syntax error?
|
||||||
|
if (!info)
|
||||||
|
info = old_info;
|
||||||
|
|
||||||
tok = tok1;
|
tok = tok1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -747,8 +770,11 @@ void SymbolDatabase::addFunction(SpaceInfo **info, const Token **tok, const Toke
|
||||||
if (func->hasBody)
|
if (func->hasBody)
|
||||||
{
|
{
|
||||||
addNewFunction(info, tok);
|
addNewFunction(info, tok);
|
||||||
(*info)->functionOf = info1;
|
if (info)
|
||||||
added = true;
|
{
|
||||||
|
(*info)->functionOf = info1;
|
||||||
|
added = true;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -775,6 +801,17 @@ void SymbolDatabase::addNewFunction(SymbolDatabase::SpaceInfo **info, const Toke
|
||||||
new_info->classStart = tok1;
|
new_info->classStart = tok1;
|
||||||
new_info->classEnd = tok1->link();
|
new_info->classEnd = tok1->link();
|
||||||
|
|
||||||
|
// syntax error?
|
||||||
|
if (!new_info->classEnd)
|
||||||
|
{
|
||||||
|
delete new_info;
|
||||||
|
while (tok1->next())
|
||||||
|
tok1 = tok1->next();
|
||||||
|
*info = NULL;
|
||||||
|
*tok = tok1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
*info = new_info;
|
*info = new_info;
|
||||||
|
|
||||||
// add space
|
// add space
|
||||||
|
@ -933,13 +970,21 @@ void SymbolDatabase::SpaceInfo::getVarList()
|
||||||
|
|
||||||
for (const Token *tok = start; tok; tok = tok->next())
|
for (const Token *tok = start; tok; tok = tok->next())
|
||||||
{
|
{
|
||||||
|
// end of space?
|
||||||
if (tok->str() == "}")
|
if (tok->str() == "}")
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// syntax error?
|
||||||
|
else if (tok->next() == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
// Is it a function?
|
// Is it a function?
|
||||||
else if (tok->str() == "{")
|
else if (tok->str() == "{")
|
||||||
{
|
{
|
||||||
tok = tok->link();
|
tok = tok->link();
|
||||||
|
// syntax error?
|
||||||
|
if (!tok)
|
||||||
|
return;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue