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:
parent
975132bc62
commit
aaafa72bc8
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue