Use a 'negative cache' for tokens / enumerator checks (#980)

Checking whether a token is an enumerator in all the available scopes
is expensive.  Once we determined that a token is not an enumerator,
skip all the expensive checks.
This commit is contained in:
Sign Bit 2017-10-18 12:01:36 -04:00 committed by Daniel Marjamäki
parent 975132bc62
commit aaafa72bc8
2 changed files with 20 additions and 7 deletions

View File

@ -3645,6 +3645,13 @@ const Enumerator * SymbolDatabase::findEnumerator(const Token * tok) const
{ {
const Scope * scope = tok->scope(); const Scope * scope = tok->scope();
const std::string tokStr = tok->str();
if (tokensThatAreNotEnumeratorValues.find(tokStr) != tokensThatAreNotEnumeratorValues.end())
{
return nullptr;
}
// check for qualified name // check for qualified name
if (tok->strAt(-1) == "::") { if (tok->strAt(-1) == "::") {
// find first scope // find first scope
@ -3676,14 +3683,14 @@ const Enumerator * SymbolDatabase::findEnumerator(const Token * tok) const
} }
if (scope) { if (scope) {
const Enumerator * enumerator = scope->findEnumerator(tok->str()); const Enumerator * enumerator = scope->findEnumerator(tokStr);
if (enumerator) // enum class if (enumerator) // enum class
return enumerator; return enumerator;
// enum // enum
else { else {
for (std::list<Scope *>::const_iterator it = scope->nestedList.begin(), end = scope->nestedList.end(); it != end; ++it) { for (std::list<Scope *>::const_iterator it = scope->nestedList.begin(), end = scope->nestedList.end(); it != end; ++it) {
enumerator = (*it)->findEnumerator(tok->str()); enumerator = (*it)->findEnumerator(tokStr);
if (enumerator) if (enumerator)
return enumerator; return enumerator;
@ -3692,13 +3699,13 @@ const Enumerator * SymbolDatabase::findEnumerator(const Token * tok) const
} }
} }
} else { } else {
const Enumerator * enumerator = scope->findEnumerator(tok->str()); const Enumerator * enumerator = scope->findEnumerator(tokStr);
if (enumerator) if (enumerator)
return enumerator; return enumerator;
for (std::list<Scope *>::const_iterator s = scope->nestedList.begin(); s != scope->nestedList.end(); ++s) { for (std::list<Scope *>::const_iterator s = scope->nestedList.begin(); s != scope->nestedList.end(); ++s) {
enumerator = (*s)->findEnumerator(tok->str()); enumerator = (*s)->findEnumerator(tokStr);
if (enumerator) if (enumerator)
return enumerator; return enumerator;
@ -3709,7 +3716,7 @@ const Enumerator * SymbolDatabase::findEnumerator(const Token * tok) const
for (size_t i = 0, end = derivedFrom.size(); i < end; ++i) { for (size_t i = 0, end = derivedFrom.size(); i < end; ++i) {
const Type *derivedFromType = derivedFrom[i].type; const Type *derivedFromType = derivedFrom[i].type;
if (derivedFromType && derivedFromType ->classScope) { if (derivedFromType && derivedFromType ->classScope) {
enumerator = derivedFromType->classScope->findEnumerator(tok->str()); enumerator = derivedFromType->classScope->findEnumerator(tokStr);
if (enumerator) if (enumerator)
return enumerator; return enumerator;
@ -3723,13 +3730,13 @@ const Enumerator * SymbolDatabase::findEnumerator(const Token * tok) const
else else
scope = scope->nestedIn; scope = scope->nestedIn;
enumerator = scope->findEnumerator(tok->str()); enumerator = scope->findEnumerator(tokStr);
if (enumerator) if (enumerator)
return enumerator; return enumerator;
for (std::list<Scope*>::const_iterator s = scope->nestedList.begin(); s != scope->nestedList.end(); ++s) { for (std::list<Scope*>::const_iterator s = scope->nestedList.begin(); s != scope->nestedList.end(); ++s) {
enumerator = (*s)->findEnumerator(tok->str()); enumerator = (*s)->findEnumerator(tokStr);
if (enumerator) if (enumerator)
return enumerator; return enumerator;
@ -3737,6 +3744,8 @@ const Enumerator * SymbolDatabase::findEnumerator(const Token * tok) const
} }
} }
tokensThatAreNotEnumeratorValues.insert(tokStr);
return nullptr; return nullptr;
} }
@ -3758,6 +3767,7 @@ const Type* SymbolDatabase::findVariableTypeInBase(const Scope* scope, const Tok
} }
} }
} }
return nullptr; return nullptr;
} }

View File

@ -1211,6 +1211,9 @@ private:
bool cpp; bool cpp;
ValueType::Sign defaultSignedness; ValueType::Sign defaultSignedness;
/** "negative cache" list of tokens that we find are not enumeration values */
mutable std::set<std::string> tokensThatAreNotEnumeratorValues;
}; };