Optimization: Speed up SymbolDatabase creation and Tokenizer::findGarbageCode() by using Token::isKeyword() for pre-checks
This commit is contained in:
parent
f6788c0472
commit
c155062cf2
|
@ -127,11 +127,12 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
|
|||
"SymbolDatabase",
|
||||
tok->progressValue());
|
||||
// Locate next class
|
||||
if ((mTokenizer->isCPP() && ((Token::Match(tok, "class|struct|union|namespace ::| %name% {|:|::|<") &&
|
||||
!Token::Match(tok->previous(), "new|friend|const|enum|typedef|mutable|volatile|using|)|(|<")) ||
|
||||
(Token::Match(tok, "enum class| %name% {") ||
|
||||
Token::Match(tok, "enum class| %name% : %name% {"))))
|
||||
|| (mTokenizer->isC() && Token::Match(tok, "struct|union|enum %name% {"))) {
|
||||
if ((mTokenizer->isCPP() && tok->isKeyword() &&
|
||||
((Token::Match(tok, "class|struct|union|namespace ::| %name% {|:|::|<") &&
|
||||
!Token::Match(tok->previous(), "new|friend|const|enum|typedef|mutable|volatile|using|)|(|<")) ||
|
||||
(Token::Match(tok, "enum class| %name% {") ||
|
||||
Token::Match(tok, "enum class| %name% : %name% {"))))
|
||||
|| (mTokenizer->isC() && tok->isKeyword() && Token::Match(tok, "struct|union|enum %name% {"))) {
|
||||
const Token *tok2 = tok->tokAt(2);
|
||||
|
||||
if (tok->strAt(1) == "::")
|
||||
|
@ -297,7 +298,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
|
|||
}
|
||||
|
||||
// Namespace and unknown macro (#3854)
|
||||
else if (mTokenizer->isCPP() &&
|
||||
else if (mTokenizer->isCPP() && tok->isKeyword() &&
|
||||
Token::Match(tok, "namespace %name% %type% (") &&
|
||||
tok->tokAt(2)->isUpperCaseName() &&
|
||||
Token::simpleMatch(tok->linkAt(3), ") {")) {
|
||||
|
@ -325,7 +326,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
|
|||
}
|
||||
|
||||
// forward declaration
|
||||
else if (Token::Match(tok, "class|struct|union %name% ;") &&
|
||||
else if (tok->isKeyword() && Token::Match(tok, "class|struct|union %name% ;") &&
|
||||
tok->strAt(-1) != "friend") {
|
||||
if (!findType(tok->next(), scope)) {
|
||||
// fill typeList..
|
||||
|
@ -337,7 +338,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
|
|||
}
|
||||
|
||||
// using namespace
|
||||
else if (mTokenizer->isCPP() && Token::Match(tok, "using namespace ::| %type% ;|::")) {
|
||||
else if (mTokenizer->isCPP() && tok->isKeyword() && Token::Match(tok, "using namespace ::| %type% ;|::")) {
|
||||
Scope::UsingInfo using_info;
|
||||
|
||||
using_info.start = tok; // save location
|
||||
|
@ -357,7 +358,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
|
|||
}
|
||||
|
||||
// using type alias
|
||||
else if (mTokenizer->isCPP() && Token::Match(tok, "using %name% =")) {
|
||||
else if (mTokenizer->isCPP() && tok->isKeyword() && Token::Match(tok, "using %name% =")) {
|
||||
if (tok->strAt(-1) != ">" && !findType(tok->next(), scope)) {
|
||||
// fill typeList..
|
||||
typeList.emplace_back(tok, nullptr, scope);
|
||||
|
@ -372,7 +373,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
|
|||
}
|
||||
|
||||
// unnamed struct and union
|
||||
else if (Token::Match(tok, "struct|union {") &&
|
||||
else if (tok->isKeyword() && Token::Match(tok, "struct|union {") &&
|
||||
Token::Match(tok->next()->link(), "} *|&| %name% ;|[|=")) {
|
||||
scopeList.emplace_back(this, tok, scope);
|
||||
|
||||
|
@ -414,9 +415,9 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
|
|||
}
|
||||
|
||||
// anonymous struct, union and namespace
|
||||
else if ((Token::Match(tok, "struct|union {") &&
|
||||
Token::simpleMatch(tok->next()->link(), "} ;")) ||
|
||||
Token::simpleMatch(tok, "namespace {")) {
|
||||
else if (tok->isKeyword() && ((Token::Match(tok, "struct|union {") &&
|
||||
Token::simpleMatch(tok->next()->link(), "} ;")) ||
|
||||
Token::simpleMatch(tok, "namespace {"))) {
|
||||
scopeList.emplace_back(this, tok, scope);
|
||||
|
||||
Scope *new_scope = &scopeList.back();
|
||||
|
@ -448,7 +449,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
|
|||
}
|
||||
|
||||
// forward declared enum
|
||||
else if (Token::Match(tok, "enum class| %name% ;") || Token::Match(tok, "enum class| %name% : %name% ;")) {
|
||||
else if (tok->isKeyword() && (Token::Match(tok, "enum class| %name% ;") || Token::Match(tok, "enum class| %name% : %name% ;"))) {
|
||||
typeList.emplace_back(tok, nullptr, scope);
|
||||
Type* new_type = &typeList.back();
|
||||
scope->definedTypesMap[new_type->name()] = new_type;
|
||||
|
@ -561,7 +562,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
|
|||
}
|
||||
|
||||
// friend class declaration?
|
||||
else if (mTokenizer->isCPP() && Token::Match(tok, "friend class| ::| %any% ;|::")) {
|
||||
else if (mTokenizer->isCPP() && tok->isKeyword() && Token::Match(tok, "friend class| ::| %any% ;|::")) {
|
||||
Type::FriendInfo friendInfo;
|
||||
|
||||
// save the name start
|
||||
|
@ -643,7 +644,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
|
|||
}
|
||||
}
|
||||
} else if (scope->isExecutable()) {
|
||||
if (Token::Match(tok, "else|try|do {")) {
|
||||
if (tok->isKeyword() && Token::Match(tok, "else|try|do {")) {
|
||||
const Token* tok1 = tok->next();
|
||||
if (tok->str() == "else")
|
||||
scopeList.emplace_back(this, tok, scope, Scope::eElse, tok1);
|
||||
|
@ -655,7 +656,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
|
|||
tok = tok1;
|
||||
scope->nestedList.push_back(&scopeList.back());
|
||||
scope = &scopeList.back();
|
||||
} else if (Token::Match(tok, "if|for|while|catch|switch (") && Token::simpleMatch(tok->next()->link(), ") {")) {
|
||||
} else if (tok->isKeyword() && Token::Match(tok, "if|for|while|catch|switch (") && Token::simpleMatch(tok->next()->link(), ") {")) {
|
||||
const Token *scopeStartTok = tok->next()->link()->next();
|
||||
if (tok->str() == "if")
|
||||
scopeList.emplace_back(this, tok, scope, Scope::eIf, scopeStartTok);
|
||||
|
@ -1055,7 +1056,7 @@ void SymbolDatabase::createSymbolDatabaseSetFunctionPointers(bool firstPass)
|
|||
|
||||
// Set function call pointers
|
||||
for (const Token* tok = mTokenizer->list.front(); tok != mTokenizer->list.back(); tok = tok->next()) {
|
||||
if (!tok->function() && tok->varId() == 0 && Token::Match(tok, "%name% (") && !isReservedName(tok->str())) {
|
||||
if (!tok->function() && tok->varId() == 0 && tok->linkAt(1) && Token::Match(tok, "%name% (") && !isReservedName(tok->str())) {
|
||||
const Function *function = findFunction(tok);
|
||||
if (function)
|
||||
const_cast<Token *>(tok)->function(function);
|
||||
|
@ -1575,6 +1576,9 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const
|
|||
}
|
||||
}
|
||||
|
||||
else if (!tok->isName() || !tok->next() || !tok->next()->link())
|
||||
return false;
|
||||
|
||||
// regular function?
|
||||
else if (Token::Match(tok, "%name% (") && !isReservedName(tok->str()) && tok->previous() &&
|
||||
(Token::Match(tok->previous(), "%name%|>|&|*|::|~") || // Either a return type or scope qualifier in front of tok
|
||||
|
@ -3840,7 +3844,7 @@ void Scope::getVariableList(const Settings* settings)
|
|||
}
|
||||
|
||||
// Is it a nested class or structure?
|
||||
else if (Token::Match(tok, "class|struct|union|namespace %type% :|{")) {
|
||||
else if (tok->isKeyword() && Token::Match(tok, "class|struct|union|namespace %type% :|{")) {
|
||||
tok = tok->tokAt(2);
|
||||
while (tok && tok->str() != "{")
|
||||
tok = tok->next();
|
||||
|
@ -3850,7 +3854,7 @@ void Scope::getVariableList(const Settings* settings)
|
|||
continue;
|
||||
} else
|
||||
break;
|
||||
} else if (Token::Match(tok, "struct|union {")) {
|
||||
} else if (tok->isKeyword() && Token::Match(tok, "struct|union {")) {
|
||||
if (Token::Match(tok->next()->link(), "} %name% ;|[")) {
|
||||
tok = tok->next()->link()->tokAt(2);
|
||||
continue;
|
||||
|
@ -3888,7 +3892,7 @@ void Scope::getVariableList(const Settings* settings)
|
|||
}
|
||||
|
||||
// Is it a forward declaration?
|
||||
else if (Token::Match(tok, "class|struct|union %name% ;")) {
|
||||
else if (tok->isKeyword() && Token::Match(tok, "class|struct|union %name% ;")) {
|
||||
tok = tok->tokAt(2);
|
||||
continue;
|
||||
}
|
||||
|
@ -3898,7 +3902,7 @@ void Scope::getVariableList(const Settings* settings)
|
|||
continue;
|
||||
|
||||
// skip return, goto and delete
|
||||
else if (Token::Match(tok, "return|delete|goto")) {
|
||||
else if (tok->isKeyword() && Token::Match(tok, "return|delete|goto")) {
|
||||
while (tok->next() &&
|
||||
tok->next()->str() != ";" &&
|
||||
tok->next()->str() != "}" /* ticket #4994 */) {
|
||||
|
@ -3908,7 +3912,7 @@ void Scope::getVariableList(const Settings* settings)
|
|||
}
|
||||
|
||||
// skip case/default
|
||||
if (Token::Match(tok, "case|default")) {
|
||||
if (tok->isKeyword() && Token::Match(tok, "case|default")) {
|
||||
while (tok->next() && !Token::Match(tok->next(), "[:;{}]"))
|
||||
tok = tok->next();
|
||||
continue;
|
||||
|
@ -3930,18 +3934,18 @@ void Scope::getVariableList(const Settings* settings)
|
|||
const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess, const Settings* settings)
|
||||
{
|
||||
// Is it a throw..?
|
||||
if (Token::Match(tok, "throw %any% (") &&
|
||||
if (tok->isKeyword() && Token::Match(tok, "throw %any% (") &&
|
||||
Token::simpleMatch(tok->linkAt(2), ") ;")) {
|
||||
return tok->linkAt(2);
|
||||
}
|
||||
|
||||
if ((Token::Match(tok, "throw %any% :: %any% (") &&
|
||||
Token::simpleMatch(tok->linkAt(4), ") ;"))) {
|
||||
if (tok->isKeyword() && Token::Match(tok, "throw %any% :: %any% (") &&
|
||||
Token::simpleMatch(tok->linkAt(4), ") ;")) {
|
||||
return tok->linkAt(4);
|
||||
}
|
||||
|
||||
// friend?
|
||||
if (Token::Match(tok, "friend %type%") && tok->next()->varId() == 0) {
|
||||
if (tok->isKeyword() && Token::Match(tok, "friend %type%") && tok->next()->varId() == 0) {
|
||||
const Token *next = Token::findmatch(tok->tokAt(2), ";|{");
|
||||
if (next && next->str() == "{")
|
||||
next = next->link();
|
||||
|
@ -3949,14 +3953,14 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess, con
|
|||
}
|
||||
|
||||
// skip const|volatile|static|mutable|extern
|
||||
while (Token::Match(tok, "const|volatile|static|mutable|extern")) {
|
||||
while (tok->isKeyword() && Token::Match(tok, "const|volatile|static|mutable|extern")) {
|
||||
tok = tok->next();
|
||||
}
|
||||
|
||||
// the start of the type tokens does not include the above modifiers
|
||||
const Token *typestart = tok;
|
||||
|
||||
if (Token::Match(tok, "class|struct|union|enum")) {
|
||||
if (tok->isKeyword() && Token::Match(tok, "class|struct|union|enum")) {
|
||||
tok = tok->next();
|
||||
}
|
||||
|
||||
|
@ -5875,7 +5879,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to
|
|||
valuetype.sign = ValueType::Sign::SIGNED;
|
||||
}
|
||||
setValueType(tok, valuetype);
|
||||
} else if (tok->str() == "(") {
|
||||
} else if (tok->link() && tok->str() == "(") {
|
||||
// cast
|
||||
if (tok->isCast() && !tok->astOperand2() && Token::Match(tok, "( %name%")) {
|
||||
ValueType valuetype;
|
||||
|
@ -6014,7 +6018,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to
|
|||
setValueType(tok, *tok->variable());
|
||||
} else if (tok->enumerator()) {
|
||||
setValueType(tok, *tok->enumerator());
|
||||
} else if (mIsCpp && tok->str() == "new") {
|
||||
} else if (tok->isKeyword() && tok->str() == "new") {
|
||||
const Token *typeTok = tok->next();
|
||||
if (Token::Match(typeTok, "( std| ::| nothrow )"))
|
||||
typeTok = typeTok->link()->next();
|
||||
|
@ -6053,7 +6057,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to
|
|||
vt.sign = (vt.type == ValueType::Type::CHAR) ? mDefaultSignedness : ValueType::Sign::SIGNED;
|
||||
}
|
||||
setValueType(tok, vt);
|
||||
} else if (tok->str() == "return" && tok->scope()) {
|
||||
} else if (tok->isKeyword() && tok->str() == "return" && tok->scope()) {
|
||||
const Scope* fscope = tok->scope();
|
||||
while (fscope && !fscope->function)
|
||||
fscope = fscope->nestedIn;
|
||||
|
|
|
@ -9401,7 +9401,7 @@ void Tokenizer::reportUnknownMacros()
|
|||
|
||||
void Tokenizer::findGarbageCode() const
|
||||
{
|
||||
const bool isCPP11 = isCPP() && mSettings->standards.cpp >= Standards::CPP11;
|
||||
const bool isCPP11 = isCPP() && mSettings->standards.cpp >= Standards::CPP11;
|
||||
|
||||
const std::set<std::string> nonConsecutiveKeywords{ "break",
|
||||
"continue",
|
||||
|
@ -9430,7 +9430,7 @@ void Tokenizer::findGarbageCode() const
|
|||
}
|
||||
|
||||
// UNKNOWN_MACRO(return)
|
||||
if (Token::Match(tok, "throw|return )") && Token::Match(tok->linkAt(1)->previous(), "%name% ("))
|
||||
if (tok->isKeyword() && Token::Match(tok, "throw|return )") && Token::Match(tok->linkAt(1)->previous(), "%name% ("))
|
||||
unknownMacroError(tok->linkAt(1)->previous());
|
||||
|
||||
// UNKNOWN_MACRO(return)
|
||||
|
@ -9465,7 +9465,7 @@ void Tokenizer::findGarbageCode() const
|
|||
}
|
||||
|
||||
// keyword keyword
|
||||
if (tok->isName() && nonConsecutiveKeywords.count(tok->str()) != 0) {
|
||||
if (tok->isKeyword() && nonConsecutiveKeywords.count(tok->str()) != 0) {
|
||||
if (Token::Match(tok, "%name% %name%") && nonConsecutiveKeywords.count(tok->next()->str()) == 1)
|
||||
syntaxError(tok);
|
||||
const Token* prev = tok;
|
||||
|
@ -9487,15 +9487,13 @@ void Tokenizer::findGarbageCode() const
|
|||
"if",
|
||||
"return",
|
||||
"switch",
|
||||
"while"};
|
||||
if (isCPP()) {
|
||||
nonGlobalKeywords.insert("try");
|
||||
nonGlobalKeywords.insert("catch");
|
||||
}
|
||||
"while",
|
||||
"try",
|
||||
"catch"};
|
||||
for (const Token *tok = tokens(); tok; tok = tok->next()) {
|
||||
if (tok->str() == "{")
|
||||
tok = tok->link();
|
||||
else if (tok->isName() && nonGlobalKeywords.count(tok->str()) && !Token::Match(tok->tokAt(-2), "operator %str%"))
|
||||
else if (tok->isKeyword() && nonGlobalKeywords.count(tok->str()) && !Token::Match(tok->tokAt(-2), "operator %str%"))
|
||||
syntaxError(tok, "keyword '" + tok->str() + "' is not allowed in global scope");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue