diff options
author | Erik Verbruggen <erik.verbruggen@me.com> | 2013-03-01 18:02:50 +0100 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@digia.com> | 2013-03-05 09:58:36 +0100 |
commit | c3f907416fddd6ed93c0f5ad71856870577cdebb (patch) | |
tree | fb2dbb249a843e013178e3b59cd8c1d0ccdca5f7 /src/libs/cplusplus/LookupContext.cpp | |
parent | 413b153b30b786546c8a7bdb6c823435659053e4 (diff) | |
download | qt-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.cpp | 78 |
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, |