speed up checks by caching commonly looked up stuff in the symbol database

This commit is contained in:
Robert Reif 2012-10-10 20:42:07 +02:00 committed by Daniel Marjamäki
parent e62e03ab31
commit bbfd676b4e
4 changed files with 95 additions and 111 deletions

View File

@ -53,12 +53,9 @@ void CheckClass::constructors()
if (!_settings->isEnabled("style"))
return;
std::list<Scope>::const_iterator scope;
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) {
// only check classes and structures
if (!scope->isClassOrStruct())
continue;
std::size_t classes = symbolDatabase->classAndStructScopes.size();
for (std::size_t i = 0; i < classes; ++i) {
const Scope * scope = symbolDatabase->classAndStructScopes[i];
// don't check uninstantiated template classes
if (scope->classDef->strAt(-1) == ">")
@ -180,10 +177,9 @@ void CheckClass::copyconstructors()
if (!_settings->isEnabled("style"))
return;
for (std::list<Scope>::const_iterator scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) {
if (!scope->isClassOrStruct()) // scope is class or structure
continue;
std::size_t classes = symbolDatabase->classAndStructScopes.size();
for (std::size_t i = 0; i < classes; ++i) {
const Scope * scope = symbolDatabase->classAndStructScopes[i];
std::map<unsigned int, const Token*> allocatedVars;
for (std::list<Function>::const_iterator func = scope->functionList.begin(); func != scope->functionList.end(); ++func) {
@ -234,8 +230,8 @@ void CheckClass::copyconstructors()
noCopyConstructorError(scope->classDef, scope->className, scope->type == Scope::eStruct);
} else {
if (!copiedVars.empty()) {
for (std::set<const Token*>::const_iterator i = copiedVars.begin(); i != copiedVars.end(); ++i) {
copyConstructorShallowCopyError(*i, (*i)->str());
for (std::set<const Token*>::const_iterator it = copiedVars.begin(); it != copiedVars.end(); ++it) {
copyConstructorShallowCopyError(*it, (*it)->str());
}
}
// throw error if count mismatch
@ -719,10 +715,9 @@ void CheckClass::privateFunctions()
if (!_settings->isEnabled("style"))
return;
for (std::list<Scope>::const_iterator scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) {
// only check classes and structures
if (!scope->isClassOrStruct())
continue;
std::size_t classes = symbolDatabase->classAndStructScopes.size();
for (std::size_t i = 0; i < classes; ++i) {
const Scope * scope = symbolDatabase->classAndStructScopes[i];
// dont check borland classes with properties..
if (Token::findsimplematch(scope->classStart, "; __property ;", scope->classEnd))
@ -758,11 +753,11 @@ void CheckClass::privateFunctions()
// Bailout for overriden virtual functions of base classes
if (!scope->derivedFrom.empty()) {
// Check virtual functions
for (std::list<const Function*>::iterator i = FuncList.begin(); i != FuncList.end();) {
if ((*i)->isImplicitlyVirtual(true)) // Give true as default value to be returned if we don't see all base classes
FuncList.erase(i++);
for (std::list<const Function*>::iterator it = FuncList.begin(); it != FuncList.end();) {
if ((*it)->isImplicitlyVirtual(true)) // Give true as default value to be returned if we don't see all base classes
FuncList.erase(it++);
else
++i;
++it;
}
}
@ -771,8 +766,8 @@ void CheckClass::privateFunctions()
// Check that all private functions are used
bool used = checkFunctionUsage(funcName, &*scope); // Usage in this class
// Check in friend classes
for (std::list<Scope::FriendInfo>::const_iterator i = scope->friendList.begin(); !used && i != scope->friendList.end(); ++i)
used = checkFunctionUsage(funcName, i->scope);
for (std::list<Scope::FriendInfo>::const_iterator it = scope->friendList.begin(); !used && it != scope->friendList.end(); ++it)
used = checkFunctionUsage(funcName, it->scope);
if (!used) {
// Final check; check if the function pointer is used somewhere..
@ -808,11 +803,9 @@ void CheckClass::unusedPrivateFunctionError(const Token *tok, const std::string
void CheckClass::noMemset()
{
std::list<Scope>::const_iterator scope;
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) {
if (scope->type == Scope::eFunction) {
// Locate all 'memset' tokens..
std::size_t functions = symbolDatabase->functionScopes.size();
for (std::size_t i = 0; i < functions; ++i) {
const Scope * scope = symbolDatabase->functionScopes[i];
for (const Token *tok = scope->classStart; tok && tok != scope->classEnd; tok = tok->next()) {
if (!Token::Match(tok, "memset|memcpy|memmove ( %any%"))
continue;
@ -852,7 +845,6 @@ void CheckClass::noMemset()
}
}
}
}
void CheckClass::checkMemsetType(const Scope *start, const Token *tok, const Scope *type)
{
@ -903,12 +895,9 @@ void CheckClass::operatorEq()
if (!_settings->isEnabled("style"))
return;
std::list<Scope>::const_iterator scope;
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) {
if (!scope->isClassOrStruct())
continue;
std::size_t classes = symbolDatabase->classAndStructScopes.size();
for (std::size_t i = 0; i < classes; ++i) {
const Scope * scope = symbolDatabase->classAndStructScopes[i];
std::list<Function>::const_iterator func;
for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func) {
@ -945,11 +934,9 @@ void CheckClass::operatorEqRetRefThis()
if (!_settings->isEnabled("style"))
return;
std::list<Scope>::const_iterator scope;
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) {
// only check classes and structures
if (scope->isClassOrStruct()) {
std::size_t classes = symbolDatabase->classAndStructScopes.size();
for (std::size_t i = 0; i < classes; ++i) {
const Scope * scope = symbolDatabase->classAndStructScopes[i];
std::list<Function>::const_iterator func;
for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func) {
@ -964,7 +951,6 @@ void CheckClass::operatorEqRetRefThis()
}
}
}
}
void CheckClass::checkReturnPtrThis(const Scope *scope, const Function *func, const Token *tok, const Token *last)
{
@ -1044,12 +1030,9 @@ void CheckClass::operatorEqToSelf()
if (!_settings->isEnabled("style"))
return;
std::list<Scope>::const_iterator scope;
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) {
if (!scope->isClassOrStruct())
continue;
std::size_t classes = symbolDatabase->classAndStructScopes.size();
for (std::size_t i = 0; i < classes; ++i) {
const Scope * scope = symbolDatabase->classAndStructScopes[i];
std::list<Function>::const_iterator func;
// skip classes with multiple inheritance
@ -1317,13 +1300,9 @@ void CheckClass::checkConst()
if (!_settings->isEnabled("style"))
return;
std::list<Scope>::const_iterator scope;
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) {
// only check classes and structures
if (!scope->isClassOrStruct())
continue;
std::size_t classes = symbolDatabase->classAndStructScopes.size();
for (std::size_t i = 0; i < classes; ++i) {
const Scope * scope = symbolDatabase->classAndStructScopes[i];
std::list<Function>::const_iterator func;
for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func) {
@ -1716,13 +1695,9 @@ void CheckClass::initializerListOrder()
if (!_settings->inconclusive)
return;
std::list<Scope>::const_iterator info;
// iterate through all scopes looking for classes and structures
for (info = symbolDatabase->scopeList.begin(); info != symbolDatabase->scopeList.end(); ++info) {
if (!info->isClassOrStruct())
continue;
std::size_t classes = symbolDatabase->classAndStructScopes.size();
for (std::size_t i = 0; i < classes; ++i) {
const Scope * info = symbolDatabase->classAndStructScopes[i];
std::list<Function>::const_iterator func;
// iterate through all member functions looking for constructors
@ -1755,10 +1730,10 @@ void CheckClass::initializerListOrder()
}
// need at least 2 members to have out of order initialization
for (unsigned int i = 1; i < vars.size(); i++) {
for (std::size_t j = 1; j < vars.size(); j++) {
// check for out of order initialization
if (vars[i].var->index() < vars[i - 1].var->index())
initializerListError(vars[i].tok,vars[i].var->nameToken(), info->className, vars[i].var->name());
if (vars[j].var->index() < vars[j - 1].var->index())
initializerListError(vars[j].tok,vars[j].var->nameToken(), info->className, vars[j].var->name());
}
}
}

View File

@ -2227,9 +2227,9 @@ void CheckOther::checkComparisonOfFuncReturningBool()
const SymbolDatabase * const symbolDatabase = _tokenizer->getSymbolDatabase();
size_t functions = symbolDatabase->functionScopeList.size();
for (size_t i = 0; i < functions; ++i) {
const Scope * scope = symbolDatabase->functionScopeList[i];
std::size_t functions = symbolDatabase->functionScopes.size();
for (std::size_t i = 0; i < functions; ++i) {
const Scope * scope = symbolDatabase->functionScopes[i];
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
if (tok->type() != Token::eComparisonOp || tok->str() == "==" || tok->str() == "!=")
continue;
@ -2307,9 +2307,9 @@ void CheckOther::checkComparisonOfBoolWithBool()
const SymbolDatabase* const symbolDatabase = _tokenizer->getSymbolDatabase();
size_t functions = symbolDatabase->functionScopeList.size();
for (size_t i = 0; i < functions; ++i) {
const Scope * scope = symbolDatabase->functionScopeList[i];
std::size_t functions = symbolDatabase->functionScopes.size();
for (std::size_t i = 0; i < functions; ++i) {
const Scope * scope = symbolDatabase->functionScopes[i];
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
if (tok->type() != Token::eComparisonOp || tok->str() == "==" || tok->str() == "!=")
continue;

View File

@ -623,10 +623,16 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
}
}
// fill in function list
// fill in function scopes
for (it = scopeList.begin(); it != scopeList.end(); ++it) {
if (it->type == Scope::eFunction)
functionScopeList.push_back(&*it);
functionScopes.push_back(&*it);
}
// fill in class and struct scopes
for (it = scopeList.begin(); it != scopeList.end(); ++it) {
if (it->isClassOrStruct())
classAndStructScopes.push_back(&*it);
}
// determine if user defined type needs initialization

View File

@ -561,7 +561,10 @@ public:
std::list<Scope> scopeList;
/** @brief Fast access to function scopes */
std::vector<Scope *> functionScopeList;
std::vector<Scope *> functionScopes;
/** @brief Fast access to class and struct scopes */
std::vector<Scope *> classAndStructScopes;
/**
* @brief find a variable type if it's a user defined type