From aaafa72bc8a2388663e286f855e9b0e3e04b0335 Mon Sep 17 00:00:00 2001 From: Sign Bit Date: Wed, 18 Oct 2017 12:01:36 -0400 Subject: [PATCH] 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. --- lib/symboldatabase.cpp | 24 +++++++++++++++++------- lib/symboldatabase.h | 3 +++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 672348892..2d013c6c0 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -3645,6 +3645,13 @@ const Enumerator * SymbolDatabase::findEnumerator(const Token * tok) const { const Scope * scope = tok->scope(); + const std::string tokStr = tok->str(); + + if (tokensThatAreNotEnumeratorValues.find(tokStr) != tokensThatAreNotEnumeratorValues.end()) + { + return nullptr; + } + // check for qualified name if (tok->strAt(-1) == "::") { // find first scope @@ -3676,14 +3683,14 @@ const Enumerator * SymbolDatabase::findEnumerator(const Token * tok) const } if (scope) { - const Enumerator * enumerator = scope->findEnumerator(tok->str()); + const Enumerator * enumerator = scope->findEnumerator(tokStr); if (enumerator) // enum class return enumerator; // enum else { for (std::list::const_iterator it = scope->nestedList.begin(), end = scope->nestedList.end(); it != end; ++it) { - enumerator = (*it)->findEnumerator(tok->str()); + enumerator = (*it)->findEnumerator(tokStr); if (enumerator) return enumerator; @@ -3692,13 +3699,13 @@ const Enumerator * SymbolDatabase::findEnumerator(const Token * tok) const } } } else { - const Enumerator * enumerator = scope->findEnumerator(tok->str()); + const Enumerator * enumerator = scope->findEnumerator(tokStr); if (enumerator) return enumerator; for (std::list::const_iterator s = scope->nestedList.begin(); s != scope->nestedList.end(); ++s) { - enumerator = (*s)->findEnumerator(tok->str()); + enumerator = (*s)->findEnumerator(tokStr); if (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) { const Type *derivedFromType = derivedFrom[i].type; if (derivedFromType && derivedFromType ->classScope) { - enumerator = derivedFromType->classScope->findEnumerator(tok->str()); + enumerator = derivedFromType->classScope->findEnumerator(tokStr); if (enumerator) return enumerator; @@ -3723,13 +3730,13 @@ const Enumerator * SymbolDatabase::findEnumerator(const Token * tok) const else scope = scope->nestedIn; - enumerator = scope->findEnumerator(tok->str()); + enumerator = scope->findEnumerator(tokStr); if (enumerator) return enumerator; for (std::list::const_iterator s = scope->nestedList.begin(); s != scope->nestedList.end(); ++s) { - enumerator = (*s)->findEnumerator(tok->str()); + enumerator = (*s)->findEnumerator(tokStr); if (enumerator) return enumerator; @@ -3737,6 +3744,8 @@ const Enumerator * SymbolDatabase::findEnumerator(const Token * tok) const } } + tokensThatAreNotEnumeratorValues.insert(tokStr); + return nullptr; } @@ -3758,6 +3767,7 @@ const Type* SymbolDatabase::findVariableTypeInBase(const Scope* scope, const Tok } } } + return nullptr; } diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 7b494db88..1ef6cfb85 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -1211,6 +1211,9 @@ private: bool cpp; ValueType::Sign defaultSignedness; + + /** "negative cache" list of tokens that we find are not enumeration values */ + mutable std::set tokensThatAreNotEnumeratorValues; };