Symbol database: more function/variable cleanup. Ticket: #4494
This commit is contained in:
parent
fc42aa3a30
commit
ec1c86c152
|
@ -230,7 +230,7 @@ bool CheckAutoVariables::returnTemporary(const Token *tok) const
|
|||
bool retref = false; // is there such a function that returns a reference?
|
||||
bool retvalue = false; // is there such a function that returns a value?
|
||||
|
||||
const Function *function = symbolDatabase->findFunction(tok);
|
||||
const Function *function = tok->function();
|
||||
if (function) {
|
||||
retref = function->tokenDef->strAt(-1) == "&";
|
||||
if (!retref) {
|
||||
|
|
|
@ -625,7 +625,7 @@ void CheckBufferOverrun::checkFunctionParameter(const Token &tok, unsigned int p
|
|||
// Calling a user function?
|
||||
// only 1-dimensional arrays can be checked currently
|
||||
else if (arrayInfo.num().size() == 1) {
|
||||
const Function* func = _tokenizer->getSymbolDatabase()->findFunction(&tok);
|
||||
const Function* func = tok.function();
|
||||
|
||||
if (func && func->hasBody) {
|
||||
// Get corresponding parameter..
|
||||
|
@ -695,7 +695,7 @@ void CheckBufferOverrun::checkFunctionParameter(const Token &tok, unsigned int p
|
|||
|
||||
// Check 'float x[10]' arguments in declaration
|
||||
if (_settings->isEnabled("style")) {
|
||||
const Function* func = _tokenizer->getSymbolDatabase()->findFunction(&tok);
|
||||
const Function* func = tok.function();
|
||||
|
||||
// If argument is '%type% a[num]' then check bounds against num
|
||||
if (func) {
|
||||
|
|
|
@ -219,7 +219,7 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getAllocationType(const Token *tok2,
|
|||
tok2 = tok2->tokAt(2);
|
||||
|
||||
// User function
|
||||
const Function* func = tokenizer->getSymbolDatabase()->findFunction(tok2);
|
||||
const Function* func = tok2->function();
|
||||
if (func == NULL)
|
||||
return No;
|
||||
|
||||
|
@ -643,7 +643,7 @@ const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::list<co
|
|||
|
||||
// lock/unlock..
|
||||
if (varid == 0) {
|
||||
const Function* func = _tokenizer->getSymbolDatabase()->findFunction(tok);
|
||||
const Function* func = tok->function();
|
||||
if (!func || !func->hasBody)
|
||||
return 0;
|
||||
|
||||
|
@ -689,7 +689,7 @@ const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::list<co
|
|||
if (dot)
|
||||
return "use";
|
||||
|
||||
const Function* function = _tokenizer->getSymbolDatabase()->findFunction(functok);
|
||||
const Function* function = functok->function();
|
||||
if (!function)
|
||||
return "use";
|
||||
|
||||
|
@ -721,7 +721,7 @@ const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::list<co
|
|||
return ret;
|
||||
}
|
||||
if (varid > 0 && Token::Match(tok, "& %varid% [,()]", varid)) {
|
||||
const Function *func = _tokenizer->getSymbolDatabase()->findFunction(functok);
|
||||
const Function *func = functok->function();
|
||||
if (func == 0)
|
||||
continue;
|
||||
AllocType a;
|
||||
|
|
|
@ -450,7 +450,7 @@ bool CheckNullPointer::CanFunctionAssignPointer(const Token *functiontoken, unsi
|
|||
unsigned int argumentNumber = 0;
|
||||
for (const Token *arg = functiontoken->tokAt(2); arg; arg = arg->nextArgument()) {
|
||||
if (Token::Match(arg, "%varid% [,)]", varid)) {
|
||||
const Function* func = _tokenizer->getSymbolDatabase()->findFunction(functiontoken);
|
||||
const Function* func = functiontoken->function();
|
||||
if (!func) { // Unknown function
|
||||
unknown = true;
|
||||
return true; // assume that the function might assign the pointer
|
||||
|
|
|
@ -753,7 +753,7 @@ void CheckOther::checkRedundantAssignment()
|
|||
}
|
||||
}
|
||||
} else if (scope->type == Scope::eSwitch) { // Avoid false positives if noreturn function is called in switch
|
||||
const Function* func = symbolDatabase->findFunction(tok);
|
||||
const Function* func = tok->function();
|
||||
if (!func || !func->hasBody) {
|
||||
varAssignments.clear();
|
||||
memAssignments.clear();
|
||||
|
@ -2379,7 +2379,7 @@ void CheckOther::checkMisusedScopedObject()
|
|||
if (Token::Match(tok, "[;{}] %var% (")
|
||||
&& Token::simpleMatch(tok->linkAt(2), ") ;")
|
||||
&& symbolDatabase->isClassOrStruct(tok->next()->str())
|
||||
&& !symbolDatabase->findFunction(tok->next())) {
|
||||
&& !tok->next()->function()) {
|
||||
tok = tok->next();
|
||||
misusedScopeObjectError(tok, tok->str());
|
||||
tok = tok->next();
|
||||
|
@ -2422,7 +2422,7 @@ void CheckOther::checkComparisonOfFuncReturningBool()
|
|||
first_token = tok->previous();
|
||||
}
|
||||
if (Token::Match(first_token, "%var% (") && !Token::Match(first_token->previous(), "::|.")) {
|
||||
const Function* func = symbolDatabase->findFunction(first_token);
|
||||
const Function* func = first_token->function();
|
||||
if (func && func->tokenDef && func->tokenDef->strAt(-1) == "bool") {
|
||||
first_token_func_of_type_bool = true;
|
||||
}
|
||||
|
@ -2434,7 +2434,7 @@ void CheckOther::checkComparisonOfFuncReturningBool()
|
|||
second_token = second_token->next();
|
||||
}
|
||||
if (Token::Match(second_token, "%var% (") && !Token::Match(second_token->previous(), "::|.")) {
|
||||
const Function* func = symbolDatabase->findFunction(second_token);
|
||||
const Function* func = second_token->function();
|
||||
if (func && func->tokenDef && func->tokenDef->strAt(-1) == "bool") {
|
||||
second_token_func_of_type_bool = true;
|
||||
}
|
||||
|
@ -3657,7 +3657,7 @@ void CheckOther::checkRedundantCopy()
|
|||
const Token *match_end = (tok->next()->link()!=NULL)?tok->next()->link()->next():NULL;
|
||||
if (match_end==NULL || !Token::Match(match_end,expect_end_token)) //avoid usage like "const A a = getA()+3"
|
||||
break;
|
||||
const Function* func = _tokenizer->getSymbolDatabase()->findFunction(tok);
|
||||
const Function* func = tok->function();
|
||||
if (func && func->tokenDef->previous() && func->tokenDef->previous()->str() == "&") {
|
||||
redundantCopyError(var_tok,var_tok->str());
|
||||
}
|
||||
|
@ -3842,7 +3842,7 @@ void CheckOther::checkVarFuncNullUB()
|
|||
ftok = ftok ? ftok->previous() : NULL;
|
||||
if (ftok && ftok->isName()) {
|
||||
// If this is a variadic function then report error
|
||||
const Function *f = symbolDatabase->findFunction(ftok);
|
||||
const Function *f = ftok->function();
|
||||
if (f && f->argCount() <= argnr) {
|
||||
const Token *tok2 = f->argDef;
|
||||
tok2 = tok2 ? tok2->link() : NULL; // goto ')'
|
||||
|
|
|
@ -1211,7 +1211,7 @@ void CheckStl::string_c_str()
|
|||
Token::simpleMatch(tok->linkAt(4), ") . c_str ( ) ;")) {
|
||||
string_c_strError(tok);
|
||||
} else if (Token::Match(tok, "return %var% (") && Token::simpleMatch(tok->linkAt(2), ") . c_str ( ) ;")) {
|
||||
const Function* func =_tokenizer->getSymbolDatabase()->findFunction(tok->next());
|
||||
const Function* func = tok->next()->function();
|
||||
if (func && Token::Match(func->tokenDef->tokAt(-3), "std :: string|wstring"))
|
||||
string_c_strError(tok);
|
||||
} else if (Token::simpleMatch(tok, "return (") &&
|
||||
|
|
|
@ -1485,7 +1485,7 @@ bool CheckUninitVar::isVariableUsage(const Token *vartok, bool pointer) const
|
|||
// is this a function call?
|
||||
if (start && Token::Match(start->previous(), "%var% (")) {
|
||||
// check how function handle uninitialized data arguments..
|
||||
const Function *func = _tokenizer->getSymbolDatabase()->findFunction(start->previous());
|
||||
const Function *func = start->previous()->function();
|
||||
if (func) {
|
||||
const Variable *arg = func->getArgumentVar(argumentNumber);
|
||||
if (arg) {
|
||||
|
|
|
@ -34,6 +34,8 @@ Token::Token(Token **t) :
|
|||
_previous(0),
|
||||
_link(0),
|
||||
_scope(0),
|
||||
_function(0),
|
||||
_variable(0),
|
||||
_str(""),
|
||||
_varId(0),
|
||||
_fileIndex(0),
|
||||
|
@ -198,6 +200,8 @@ void Token::deleteThis()
|
|||
_linenr = _next->_linenr;
|
||||
_link = _next->_link;
|
||||
_scope = _next->_scope;
|
||||
_function = _next->_function;
|
||||
_variable = _next->_variable;
|
||||
if (_link)
|
||||
_link->link(this);
|
||||
|
||||
|
@ -217,6 +221,8 @@ void Token::deleteThis()
|
|||
_linenr = _previous->_linenr;
|
||||
_link = _previous->_link;
|
||||
_scope = _previous->_scope;
|
||||
_function = _previous->_function;
|
||||
_variable = _previous->_variable;
|
||||
if (_link)
|
||||
_link->link(this);
|
||||
|
||||
|
|
41
lib/token.h
41
lib/token.h
|
@ -25,6 +25,8 @@
|
|||
#include "config.h"
|
||||
|
||||
class Scope;
|
||||
class Function;
|
||||
class Variable;
|
||||
|
||||
/// @addtogroup Core
|
||||
/// @{
|
||||
|
@ -439,17 +441,47 @@ public:
|
|||
* Associate this token with given scope
|
||||
* @param s Scope to be associated
|
||||
*/
|
||||
void scope(Scope* s) {
|
||||
void scope(const Scope *s) {
|
||||
_scope = s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pointer to the scope containing this token.
|
||||
*/
|
||||
Scope* scope() const {
|
||||
const Scope *scope() const {
|
||||
return _scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate this token with given function
|
||||
* @param f Function to be associated
|
||||
*/
|
||||
void function(const Function *f) {
|
||||
_function = f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pointer to the Function associated with this token.
|
||||
*/
|
||||
const Function *function() const {
|
||||
return _function;
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate this token with given variable
|
||||
* @param v Variable to be associated
|
||||
*/
|
||||
void variable(const Variable *v) {
|
||||
_variable = v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pointer to the variable associated with this token.
|
||||
*/
|
||||
const Variable *variable() const {
|
||||
return _variable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Links two elements against each other.
|
||||
**/
|
||||
|
@ -541,7 +573,10 @@ private:
|
|||
Token *_previous;
|
||||
Token *_link;
|
||||
|
||||
Scope* _scope;
|
||||
// symbol database information
|
||||
const Scope *_scope;
|
||||
const Function *_function;
|
||||
const Variable *_variable;
|
||||
|
||||
std::string _str;
|
||||
unsigned int _varId;
|
||||
|
|
|
@ -9264,14 +9264,33 @@ void Tokenizer::createSymbolDatabase()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set function pointers
|
||||
const std::size_t functions = _symbolDatabase->functionScopes.size();
|
||||
for (std::size_t i = 0; i < functions; ++i) {
|
||||
const Scope * scope = _symbolDatabase->functionScopes[i];
|
||||
for (Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
|
||||
if (Token::Match(tok, "%var% (")) {
|
||||
tok->function(_symbolDatabase->findFunction(tok));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set variable pointers
|
||||
for (Token* tok = list.front(); tok != list.back(); tok = tok->next()) {
|
||||
if (tok->varId())
|
||||
tok->variable(_symbolDatabase->getVariableFromVarId(tok->varId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Tokenizer::deleteSymbolDatabase()
|
||||
{
|
||||
// Clear scope pointers
|
||||
// Clear scope, function, and variable pointers
|
||||
for (Token* tok = list.front(); tok != list.back(); tok = tok->next()) {
|
||||
tok->scope(0);
|
||||
tok->function(0);
|
||||
tok->variable(0);
|
||||
}
|
||||
|
||||
delete _symbolDatabase;
|
||||
|
|
Loading…
Reference in New Issue