Small refactoring to compile more matches

*** Timing of the test suite ***
Four runs were used to calculate the average run time.

Before: ~1,103s
After: ~1,066s
Speed up: 3,35%

*** Timing of internal projects using STL ***
Before: ~8,301s
After: ~8,207s
Speed up: 1,13%

So the real world speed up is roughly 1%.
This commit is contained in:
Thomas Jarosch 2013-01-17 10:15:01 +01:00
parent c8b619ef86
commit b1eec7c6b7
2 changed files with 33 additions and 23 deletions

View File

@ -823,14 +823,19 @@ void CheckOther::redundantAssignmentInSwitchError(const Token *tok1, const Token
// y = b; // <- case 2 falls through and sets y twice // y = b; // <- case 2 falls through and sets y twice
// } // }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static inline bool isFunctionOrBreakPattern(const Token *tok)
{
if (Token::Match(tok, "%var% (") || Token::Match(tok, "break|continue|return|exit|goto|throw"))
return true;
return false;
}
void CheckOther::checkRedundantAssignmentInSwitch() void CheckOther::checkRedundantAssignmentInSwitch()
{ {
if (!_settings->isEnabled("style")) if (!_settings->isEnabled("style"))
return; return;
const char breakPattern[] = "break|continue|return|exit|goto|throw";
const char functionPattern[] = "%var% (";
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
// Find the beginning of a switch. E.g.: // Find the beginning of a switch. E.g.:
@ -854,7 +859,7 @@ void CheckOther::checkRedundantAssignmentInSwitch()
if (tok3->varId() != 0) { if (tok3->varId() != 0) {
varsWithBitsSet.erase(tok3->varId()); varsWithBitsSet.erase(tok3->varId());
bitOperations.erase(tok3->varId()); bitOperations.erase(tok3->varId());
} else if (Token::Match(tok3, functionPattern) || Token::Match(tok3, breakPattern)) { } else if (isFunctionOrBreakPattern(tok3)) {
varsWithBitsSet.clear(); varsWithBitsSet.clear();
bitOperations.clear(); bitOperations.clear();
} }
@ -907,7 +912,7 @@ void CheckOther::checkRedundantAssignmentInSwitch()
// Reset our record of assignments if there is a break or function call. E.g.: // Reset our record of assignments if there is a break or function call. E.g.:
// case 3: b = 1; break; // case 3: b = 1; break;
if (Token::Match(tok2, functionPattern) || Token::Match(tok2, breakPattern)) { if (isFunctionOrBreakPattern(tok2)) {
varsWithBitsSet.clear(); varsWithBitsSet.clear();
bitOperations.clear(); bitOperations.clear();
} }
@ -931,8 +936,6 @@ void CheckOther::checkSwitchCaseFallThrough()
const SymbolDatabase* const symbolDatabase = _tokenizer->getSymbolDatabase(); const SymbolDatabase* const symbolDatabase = _tokenizer->getSymbolDatabase();
const char breakPattern[] = "break|continue|return|exit|goto|throw";
for (std::list<Scope>::const_iterator i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i) { for (std::list<Scope>::const_iterator i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i) {
if (i->type != Scope::eSwitch || !i->classStart) // Find the beginning of a switch if (i->type != Scope::eSwitch || !i->classStart) // Find the beginning of a switch
continue; continue;
@ -990,7 +993,7 @@ void CheckOther::checkSwitchCaseFallThrough()
} else if (Token::simpleMatch(tok2, "switch (")) { } else if (Token::simpleMatch(tok2, "switch (")) {
// skip over nested switch, we'll come to that soon // skip over nested switch, we'll come to that soon
tok2 = tok2->next()->link()->next()->link(); tok2 = tok2->next()->link()->next()->link();
} else if (Token::Match(tok2, breakPattern)) { } else if (Token::Match(tok2, "break|continue|return|exit|goto|throw")) {
if (loopnest.empty()) { if (loopnest.empty()) {
justbreak = true; justbreak = true;
} }
@ -1114,6 +1117,11 @@ static bool isTypeWithoutSideEffects(const Tokenizer *tokenizer, const Variable*
return ((var && (!var->isClass() || var->isPointer() || Token::simpleMatch(var->typeStartToken(), "std ::"))) || !tokenizer->isCPP()); return ((var && (!var->isClass() || var->isPointer() || Token::simpleMatch(var->typeStartToken(), "std ::"))) || !tokenizer->isCPP());
} }
static inline const Token *findSelfAssignPattern(const Token *start)
{
return Token::findmatch(start, "%var% = %var% ;|=|)");
}
void CheckOther::checkSelfAssignment() void CheckOther::checkSelfAssignment()
{ {
if (!_settings->isEnabled("style")) if (!_settings->isEnabled("style"))
@ -1121,8 +1129,7 @@ void CheckOther::checkSelfAssignment()
const SymbolDatabase* symbolDatabase = _tokenizer->getSymbolDatabase(); const SymbolDatabase* symbolDatabase = _tokenizer->getSymbolDatabase();
const char selfAssignmentPattern[] = "%var% = %var% ;|=|)"; const Token *tok = findSelfAssignPattern(_tokenizer->tokens());
const Token *tok = Token::findmatch(_tokenizer->tokens(), selfAssignmentPattern);
while (tok) { while (tok) {
if (Token::Match(tok->previous(), "[;{}.]") && if (Token::Match(tok->previous(), "[;{}.]") &&
tok->varId() && tok->varId() == tok->tokAt(2)->varId() && tok->varId() && tok->varId() == tok->tokAt(2)->varId() &&
@ -1148,7 +1155,7 @@ void CheckOther::checkSelfAssignment()
selfAssignmentError(tok, tok->str()); selfAssignmentError(tok, tok->str());
} }
tok = Token::findmatch(tok->next(), selfAssignmentPattern); tok = findSelfAssignPattern(tok->next());
} }
} }
@ -1162,13 +1169,17 @@ void CheckOther::selfAssignmentError(const Token *tok, const std::string &varnam
// int a = 1; // int a = 1;
// assert(a = 2); // <- assert should not have a side-effect // assert(a = 2); // <- assert should not have a side-effect
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static inline const Token *findAssertPattern(const Token *start)
{
return Token::findmatch(start, "assert ( %any%");
}
void CheckOther::checkAssignmentInAssert() void CheckOther::checkAssignmentInAssert()
{ {
if (!_settings->isEnabled("style")) if (!_settings->isEnabled("style"))
return; return;
const char assertPattern[] = "assert ( %any%"; const Token *tok = findAssertPattern(_tokenizer->tokens());
const Token *tok = Token::findmatch(_tokenizer->tokens(), assertPattern);
const Token *endTok = tok ? tok->next()->link() : NULL; const Token *endTok = tok ? tok->next()->link() : NULL;
while (tok && endTok) { while (tok && endTok) {
@ -1179,7 +1190,7 @@ void CheckOther::checkAssignmentInAssert()
assignmentInAssertError(tok, tok->strAt(1)); assignmentInAssertError(tok, tok->strAt(1));
} }
tok = Token::findmatch(endTok->next(), assertPattern); tok = findAssertPattern(endTok->next());
endTok = tok ? tok->next()->link() : NULL; endTok = tok ? tok->next()->link() : NULL;
} }
} }

View File

@ -707,16 +707,13 @@ void CheckStl::invalidPointerError(const Token *tok, const std::string &func, co
void CheckStl::stlBoundries() void CheckStl::stlBoundries()
{ {
// containers (not the vector)..
static const char STL_CONTAINER_LIST[] = "bitset|deque|list|forward_list|map|multimap|multiset|priority_queue|queue|set|stack|hash_map|hash_multimap|hash_set|unordered_map|unordered_multimap|unordered_set|unordered_multiset";
const SymbolDatabase* const symbolDatabase = _tokenizer->getSymbolDatabase(); const SymbolDatabase* const symbolDatabase = _tokenizer->getSymbolDatabase();
const std::size_t functions = symbolDatabase->functionScopes.size(); const std::size_t functions = symbolDatabase->functionScopes.size();
for (std::size_t i = 0; i < functions; ++i) { for (std::size_t i = 0; i < functions; ++i) {
const Scope * scope = symbolDatabase->functionScopes[i]; const Scope * scope = symbolDatabase->functionScopes[i];
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) { for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
// Declaring iterator.. // Declaring iterator..
if (tok->str() == "<" && Token::Match(tok->previous(), STL_CONTAINER_LIST)) { if (tok->str() == "<" && Token::Match(tok->previous(), "bitset|deque|list|forward_list|map|multimap|multiset|priority_queue|queue|set|stack|hash_map|hash_multimap|hash_set|unordered_map|unordered_multimap|unordered_set|unordered_multiset")) {
const std::string& container_name(tok->strAt(-1)); const std::string& container_name(tok->strAt(-1));
if (tok->link()) if (tok->link())
tok = tok->link(); tok = tok->link();
@ -1004,12 +1001,14 @@ void CheckStl::sizeError(const Token *tok)
"guaranteed to take constant time."); "guaranteed to take constant time.");
} }
static inline const Token *findRedundantCondition(const Token *start)
{
return Token::findmatch(start, "if ( %var% . find ( %any% ) != %var% . end|rend|cend|crend ( ) ) { %var% . remove ( %any% ) ;");
}
void CheckStl::redundantCondition() void CheckStl::redundantCondition()
{ {
const char pattern[] = "if ( %var% . find ( %any% ) != %var% . end|rend|cend|crend ( ) ) " const Token *tok = findRedundantCondition(_tokenizer->tokens());
"{"
" %var% . remove ( %any% ) ;";
const Token *tok = Token::findmatch(_tokenizer->tokens(), pattern);
while (tok) { while (tok) {
// Get tokens for the fields %var% and %any% // Get tokens for the fields %var% and %any%
const Token *var1 = tok->tokAt(2); const Token *var1 = tok->tokAt(2);
@ -1025,7 +1024,7 @@ void CheckStl::redundantCondition()
redundantIfRemoveError(tok); redundantIfRemoveError(tok);
} }
tok = Token::findmatch(tok->next(), pattern); tok = findRedundantCondition(tok->next());
} }
} }