summaryrefslogtreecommitdiff
path: root/src/libs/cplusplus/LookupContext.cpp
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@me.com>2013-03-01 18:02:50 +0100
committerErik Verbruggen <erik.verbruggen@digia.com>2013-03-05 09:58:36 +0100
commitc3f907416fddd6ed93c0f5ad71856870577cdebb (patch)
treefb2dbb249a843e013178e3b59cd8c1d0ccdca5f7 /src/libs/cplusplus/LookupContext.cpp
parent413b153b30b786546c8a7bdb6c823435659053e4 (diff)
downloadqt-creator-c3f907416fddd6ed93c0f5ad71856870577cdebb.tar.gz
C++: cache fully qualified name lookupus in scopes.
Task-number: QTCREATORBUG-8724 Change-Id: I00b0712cf5514bcec04b674052ad4b5b66cca506 Reviewed-by: Przemyslaw Gorszkowski <pgorszkowski@gmail.com> Reviewed-by: Nikolai Kosjar <nikolai.kosjar@digia.com>
Diffstat (limited to 'src/libs/cplusplus/LookupContext.cpp')
-rw-r--r--src/libs/cplusplus/LookupContext.cpp78
1 files changed, 58 insertions, 20 deletions
diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp
index 4562d41346..d747481dca 100644
--- a/src/libs/cplusplus/LookupContext.cpp
+++ b/src/libs/cplusplus/LookupContext.cpp
@@ -92,7 +92,7 @@ static void path_helper(Symbol *symbol, QList<const Name *> *names)
namespace CPlusPlus {
-bool compareName(const Name *name, const Name *other)
+static inline bool compareName(const Name *name, const Name *other)
{
if (name == other)
return true;
@@ -123,6 +123,30 @@ bool compareFullyQualifiedName(const QList<const Name *> &path, const QList<cons
}
+namespace CPlusPlus {
+namespace Internal {
+
+bool operator==(const FullyQualifiedName &left, const FullyQualifiedName &right)
+{
+ return compareFullyQualifiedName(left.fqn, right.fqn);
+}
+
+uint qHash(const FullyQualifiedName &fullyQualifiedName)
+{
+ uint h = 0;
+ for (int i = 0; i < fullyQualifiedName.fqn.size(); ++i) {
+ if (const Name *n = fullyQualifiedName.fqn.at(i)) {
+ if (const Identifier *id = n->identifier()) {
+ h <<= 1;
+ h += id->hashCode();
+ }
+ }
+ }
+ return h;
+}
+}
+}
+
/////////////////////////////////////////////////////////////////////
// LookupContext
/////////////////////////////////////////////////////////////////////
@@ -393,13 +417,22 @@ ClassOrNamespace *LookupContext::lookupParent(Symbol *symbol) const
}
ClassOrNamespace::ClassOrNamespace(CreateBindings *factory, ClassOrNamespace *parent)
- : _factory(factory), _parent(parent), _templateId(0), _instantiationOrigin(0)
+ : _factory(factory)
+ , _parent(parent)
+ , _scopeLookupCache(0)
+ , _templateId(0)
+ , _instantiationOrigin(0)
#ifdef DEBUG_LOOKUP
, _name(0)
#endif // DEBUG_LOOKUP
{
}
+ClassOrNamespace::~ClassOrNamespace()
+{
+ delete _scopeLookupCache;
+}
+
const TemplateNameId *ClassOrNamespace::templateId() const
{
return _templateId;
@@ -464,7 +497,7 @@ QList<LookupItem> ClassOrNamespace::lookup_helper(const Name *name, bool searchI
if (name) {
if (const QualifiedNameId *q = name->asQualifiedNameId()) {
- if (! q->base())
+ if (! q->base()) // e.g. ::std::string
result = globalNamespace()->find(q->name());
else if (ClassOrNamespace *binding = lookupType(q->base())) {
@@ -477,23 +510,10 @@ QList<LookupItem> ClassOrNamespace::lookup_helper(const Name *name, bool searchI
// a qualified name. For instance, a nested class which is forward declared
// in the class but defined outside it - we should capture both.
Symbol *match = 0;
- ClassOrNamespace *parentBinding = binding->parent();
- while (parentBinding && !match) {
- for (int j = 0; j < parentBinding->symbols().size() && !match; ++j) {
- if (Scope *scope = parentBinding->symbols().at(j)->asScope()) {
- for (unsigned i = 0; i < scope->memberCount(); ++i) {
- Symbol *candidate = scope->memberAt(i);
- if (compareFullyQualifiedName(
- fullName,
- LookupContext::fullyQualifiedName(candidate))) {
- match = candidate;
- break;
- }
- }
- }
- }
- parentBinding = parentBinding->parent();
- }
+ for (ClassOrNamespace *parentBinding = binding->parent();
+ parentBinding && !match;
+ parentBinding = parentBinding->parent())
+ match = parentBinding->lookupInScope(fullName);
if (match) {
LookupItem item;
@@ -634,6 +654,24 @@ ClassOrNamespace *ClassOrNamespace::findType(const Name *name)
return lookupType_helper(name, &processed, /*searchInEnclosingScope =*/ false, this);
}
+Symbol *ClassOrNamespace::lookupInScope(const QList<const Name *> &fullName)
+{
+ if (!_scopeLookupCache) {
+ _scopeLookupCache = new QHash<Internal::FullyQualifiedName, Symbol *>;
+
+ for (int j = 0; j < symbols().size(); ++j) {
+ if (Scope *scope = symbols().at(j)->asScope()) {
+ for (unsigned i = 0; i < scope->memberCount(); ++i) {
+ Symbol *s = scope->memberAt(i);
+ _scopeLookupCache->insert(LookupContext::fullyQualifiedName(s), s);
+ }
+ }
+ }
+ }
+
+ return _scopeLookupCache->value(fullName, 0);
+}
+
ClassOrNamespace *ClassOrNamespace::lookupType_helper(const Name *name,
QSet<ClassOrNamespace *> *processed,
bool searchInEnclosingScope,