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