diff options
author | Christian Kamm <christian.d.kamm@nokia.com> | 2011-08-19 13:10:36 +0200 |
---|---|---|
committer | Christian Kamm <christian.d.kamm@nokia.com> | 2011-08-19 14:24:05 +0200 |
commit | d8c053b5254ea557b51c3b62be68d4a6752a79df (patch) | |
tree | c86c8750ad791e2e37079de0d7ed20ddc0b91670 /src/libs/cplusplus | |
parent | f51511a81d82eea9e02351b8a97bbc4111793d8b (diff) | |
download | qt-creator-d8c053b5254ea557b51c3b62be68d4a6752a79df.tar.gz |
C++: Fix completion for typedefs for templates in namespaces.
Change-Id: Ib96551388c94731d97eb8f9728613b120b0b86a9
Reviewed-on: http://codereview.qt.nokia.com/3262
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
Diffstat (limited to 'src/libs/cplusplus')
-rw-r--r-- | src/libs/cplusplus/LookupContext.cpp | 46 | ||||
-rw-r--r-- | src/libs/cplusplus/LookupContext.h | 9 | ||||
-rw-r--r-- | src/libs/cplusplus/ResolveExpression.cpp | 12 |
3 files changed, 46 insertions, 21 deletions
diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index 0a82859ee2..f4089d1bec 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -361,7 +361,7 @@ ClassOrNamespace *LookupContext::lookupParent(Symbol *symbol) const } ClassOrNamespace::ClassOrNamespace(CreateBindings *factory, ClassOrNamespace *parent) - : _factory(factory), _parent(parent), _templateId(0) + : _factory(factory), _parent(parent), _templateId(0), _instantiationOrigin(0) { } @@ -370,6 +370,11 @@ const TemplateNameId *ClassOrNamespace::templateId() const return _templateId; } +ClassOrNamespace *ClassOrNamespace::instantiationOrigin() const +{ + return _instantiationOrigin; +} + ClassOrNamespace *ClassOrNamespace::parent() const { return _parent; @@ -541,26 +546,30 @@ ClassOrNamespace *ClassOrNamespace::lookupType(const Name *name) return 0; QSet<ClassOrNamespace *> processed; - return lookupType_helper(name, &processed, /*searchInEnclosingScope =*/ true); + return lookupType_helper(name, &processed, /*searchInEnclosingScope =*/ true, this); } ClassOrNamespace *ClassOrNamespace::findType(const Name *name) { QSet<ClassOrNamespace *> processed; - return lookupType_helper(name, &processed, /*searchInEnclosingScope =*/ false); + return lookupType_helper(name, &processed, /*searchInEnclosingScope =*/ false, this); } ClassOrNamespace *ClassOrNamespace::lookupType_helper(const Name *name, QSet<ClassOrNamespace *> *processed, - bool searchInEnclosingScope) + bool searchInEnclosingScope, + ClassOrNamespace *origin) { if (const QualifiedNameId *q = name->asQualifiedNameId()) { - if (! q->base()) - return globalNamespace()->findType(q->name()); + QSet<ClassOrNamespace *> innerProcessed; + if (! q->base()) { + return globalNamespace()->lookupType_helper(q->name(), &innerProcessed, true, origin); + } - else if (ClassOrNamespace *binding = lookupType(q->base())) - return binding->findType(q->name()); + if (ClassOrNamespace *binding = lookupType_helper(q->base(), processed, true, origin)) { + return binding->lookupType_helper(q->name(), &innerProcessed, false, origin); + } return 0; @@ -577,14 +586,14 @@ ClassOrNamespace *ClassOrNamespace::lookupType_helper(const Name *name, } } - if (ClassOrNamespace *e = nestedType(name)) + if (ClassOrNamespace *e = nestedType(name, origin)) return e; else if (_templateId) { if (_usings.size() == 1) { ClassOrNamespace *delegate = _usings.first(); - if (ClassOrNamespace *r = delegate->lookupType_helper(name, processed, /*searchInEnclosingScope = */ true)) + if (ClassOrNamespace *r = delegate->lookupType_helper(name, processed, /*searchInEnclosingScope = */ true, origin)) return r; } else { if (debug) @@ -593,19 +602,19 @@ ClassOrNamespace *ClassOrNamespace::lookupType_helper(const Name *name, } foreach (ClassOrNamespace *u, usings()) { - if (ClassOrNamespace *r = u->lookupType_helper(name, processed, /*searchInEnclosingScope =*/ false)) + if (ClassOrNamespace *r = u->lookupType_helper(name, processed, /*searchInEnclosingScope =*/ false, origin)) return r; } } if (_parent && searchInEnclosingScope) - return _parent->lookupType_helper(name, processed, searchInEnclosingScope); + return _parent->lookupType_helper(name, processed, searchInEnclosingScope, origin); } return 0; } -ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name) const +ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespace *origin) const { Q_ASSERT(name != 0); Q_ASSERT(name->isNameId() || name->isTemplateNameId()); @@ -622,6 +631,7 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name) const if (const TemplateNameId *templId = name->asTemplateNameId()) { ClassOrNamespace *i = _factory->allocClassOrNamespace(c); i->_templateId = templId; + i->_instantiationOrigin = origin; i->_usings.append(c); return i; } @@ -665,19 +675,21 @@ void ClassOrNamespace::addNestedType(const Name *alias, ClassOrNamespace *e) _classOrNamespaces[alias] = e; } -ClassOrNamespace *ClassOrNamespace::findOrCreateType(const Name *name) +ClassOrNamespace *ClassOrNamespace::findOrCreateType(const Name *name, ClassOrNamespace *origin) { if (! name) return this; + if (! origin) + origin = this; if (const QualifiedNameId *q = name->asQualifiedNameId()) { if (! q->base()) - return globalNamespace()->findOrCreateType(q->name()); + return globalNamespace()->findOrCreateType(q->name(), origin); - return findOrCreateType(q->base())->findOrCreateType(q->name()); + return findOrCreateType(q->base(), origin)->findOrCreateType(q->name(), origin); } else if (name->isNameId() || name->isTemplateNameId()) { - ClassOrNamespace *e = nestedType(name); + ClassOrNamespace *e = nestedType(name, origin); if (! e) { e = _factory->allocClassOrNamespace(this); diff --git a/src/libs/cplusplus/LookupContext.h b/src/libs/cplusplus/LookupContext.h index a985a2402f..578e19b094 100644 --- a/src/libs/cplusplus/LookupContext.h +++ b/src/libs/cplusplus/LookupContext.h @@ -54,6 +54,8 @@ public: ClassOrNamespace(CreateBindings *factory, ClassOrNamespace *parent); const TemplateNameId *templateId() const; + ClassOrNamespace *instantiationOrigin() const; + ClassOrNamespace *parent() const; QList<ClassOrNamespace *> usings() const; QList<Enum *> enums() const; @@ -72,7 +74,7 @@ private: void flush(); /// \internal - ClassOrNamespace *findOrCreateType(const Name *name); + ClassOrNamespace *findOrCreateType(const Name *name, ClassOrNamespace *origin = 0); void addTodo(Symbol *symbol); void addSymbol(Symbol *symbol); @@ -88,9 +90,9 @@ private: const TemplateNameId *templateId); ClassOrNamespace *lookupType_helper(const Name *name, QSet<ClassOrNamespace *> *processed, - bool searchInEnclosingScope); + bool searchInEnclosingScope, ClassOrNamespace *origin); - ClassOrNamespace *nestedType(const Name *name) const; + ClassOrNamespace *nestedType(const Name *name, ClassOrNamespace *origin) const; private: struct CompareName: std::binary_function<const Name *, const Name *, bool> { @@ -109,6 +111,7 @@ private: // it's an instantiation. const TemplateNameId *_templateId; + ClassOrNamespace *_instantiationOrigin; friend class CreateBindings; }; diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp index aba01829ef..8fe431d5e6 100644 --- a/src/libs/cplusplus/ResolveExpression.cpp +++ b/src/libs/cplusplus/ResolveExpression.cpp @@ -712,10 +712,20 @@ ClassOrNamespace *ResolveExpression::baseExpression(const QList<LookupItem> &bas if (ClassOrNamespace *retBinding = findClass(ptrTy->elementType(), overload->enclosingScope())) return retBinding; - else if (scope != overload->enclosingScope()) { + if (scope != overload->enclosingScope()) { if (ClassOrNamespace *retBinding = findClass(ptrTy->elementType(), scope)) return retBinding; } + + if (ClassOrNamespace *origin = binding->instantiationOrigin()) { + foreach (Symbol *originSymbol, origin->symbols()) { + Scope *originScope = originSymbol->asScope(); + if (originScope && originScope != scope && originScope != overload->enclosingScope()) { + if (ClassOrNamespace *retBinding = findClass(ptrTy->elementType(), originScope)) + return retBinding; + } + } + } } } } |