forked from qt-creator/qt-creator
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>
This commit is contained in:
@@ -361,7 +361,7 @@ ClassOrNamespace *LookupContext::lookupParent(Symbol *symbol) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
ClassOrNamespace::ClassOrNamespace(CreateBindings *factory, ClassOrNamespace *parent)
|
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;
|
return _templateId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClassOrNamespace *ClassOrNamespace::instantiationOrigin() const
|
||||||
|
{
|
||||||
|
return _instantiationOrigin;
|
||||||
|
}
|
||||||
|
|
||||||
ClassOrNamespace *ClassOrNamespace::parent() const
|
ClassOrNamespace *ClassOrNamespace::parent() const
|
||||||
{
|
{
|
||||||
return _parent;
|
return _parent;
|
||||||
@@ -541,26 +546,30 @@ ClassOrNamespace *ClassOrNamespace::lookupType(const Name *name)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
QSet<ClassOrNamespace *> processed;
|
QSet<ClassOrNamespace *> processed;
|
||||||
return lookupType_helper(name, &processed, /*searchInEnclosingScope =*/ true);
|
return lookupType_helper(name, &processed, /*searchInEnclosingScope =*/ true, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClassOrNamespace *ClassOrNamespace::findType(const Name *name)
|
ClassOrNamespace *ClassOrNamespace::findType(const Name *name)
|
||||||
{
|
{
|
||||||
QSet<ClassOrNamespace *> processed;
|
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,
|
ClassOrNamespace *ClassOrNamespace::lookupType_helper(const Name *name,
|
||||||
QSet<ClassOrNamespace *> *processed,
|
QSet<ClassOrNamespace *> *processed,
|
||||||
bool searchInEnclosingScope)
|
bool searchInEnclosingScope,
|
||||||
|
ClassOrNamespace *origin)
|
||||||
{
|
{
|
||||||
if (const QualifiedNameId *q = name->asQualifiedNameId()) {
|
if (const QualifiedNameId *q = name->asQualifiedNameId()) {
|
||||||
|
|
||||||
if (! q->base())
|
QSet<ClassOrNamespace *> innerProcessed;
|
||||||
return globalNamespace()->findType(q->name());
|
if (! q->base()) {
|
||||||
|
return globalNamespace()->lookupType_helper(q->name(), &innerProcessed, true, origin);
|
||||||
|
}
|
||||||
|
|
||||||
else if (ClassOrNamespace *binding = lookupType(q->base()))
|
if (ClassOrNamespace *binding = lookupType_helper(q->base(), processed, true, origin)) {
|
||||||
return binding->findType(q->name());
|
return binding->lookupType_helper(q->name(), &innerProcessed, false, origin);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
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;
|
return e;
|
||||||
|
|
||||||
else if (_templateId) {
|
else if (_templateId) {
|
||||||
if (_usings.size() == 1) {
|
if (_usings.size() == 1) {
|
||||||
ClassOrNamespace *delegate = _usings.first();
|
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;
|
return r;
|
||||||
} else {
|
} else {
|
||||||
if (debug)
|
if (debug)
|
||||||
@@ -593,19 +602,19 @@ ClassOrNamespace *ClassOrNamespace::lookupType_helper(const Name *name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach (ClassOrNamespace *u, usings()) {
|
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;
|
return r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_parent && searchInEnclosingScope)
|
if (_parent && searchInEnclosingScope)
|
||||||
return _parent->lookupType_helper(name, processed, searchInEnclosingScope);
|
return _parent->lookupType_helper(name, processed, searchInEnclosingScope, origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
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 != 0);
|
||||||
Q_ASSERT(name->isNameId() || name->isTemplateNameId());
|
Q_ASSERT(name->isNameId() || name->isTemplateNameId());
|
||||||
@@ -622,6 +631,7 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name) const
|
|||||||
if (const TemplateNameId *templId = name->asTemplateNameId()) {
|
if (const TemplateNameId *templId = name->asTemplateNameId()) {
|
||||||
ClassOrNamespace *i = _factory->allocClassOrNamespace(c);
|
ClassOrNamespace *i = _factory->allocClassOrNamespace(c);
|
||||||
i->_templateId = templId;
|
i->_templateId = templId;
|
||||||
|
i->_instantiationOrigin = origin;
|
||||||
i->_usings.append(c);
|
i->_usings.append(c);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
@@ -665,19 +675,21 @@ void ClassOrNamespace::addNestedType(const Name *alias, ClassOrNamespace *e)
|
|||||||
_classOrNamespaces[alias] = e;
|
_classOrNamespaces[alias] = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClassOrNamespace *ClassOrNamespace::findOrCreateType(const Name *name)
|
ClassOrNamespace *ClassOrNamespace::findOrCreateType(const Name *name, ClassOrNamespace *origin)
|
||||||
{
|
{
|
||||||
if (! name)
|
if (! name)
|
||||||
return this;
|
return this;
|
||||||
|
if (! origin)
|
||||||
|
origin = this;
|
||||||
|
|
||||||
if (const QualifiedNameId *q = name->asQualifiedNameId()) {
|
if (const QualifiedNameId *q = name->asQualifiedNameId()) {
|
||||||
if (! q->base())
|
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()) {
|
} else if (name->isNameId() || name->isTemplateNameId()) {
|
||||||
ClassOrNamespace *e = nestedType(name);
|
ClassOrNamespace *e = nestedType(name, origin);
|
||||||
|
|
||||||
if (! e) {
|
if (! e) {
|
||||||
e = _factory->allocClassOrNamespace(this);
|
e = _factory->allocClassOrNamespace(this);
|
||||||
|
@@ -54,6 +54,8 @@ public:
|
|||||||
ClassOrNamespace(CreateBindings *factory, ClassOrNamespace *parent);
|
ClassOrNamespace(CreateBindings *factory, ClassOrNamespace *parent);
|
||||||
|
|
||||||
const TemplateNameId *templateId() const;
|
const TemplateNameId *templateId() const;
|
||||||
|
ClassOrNamespace *instantiationOrigin() const;
|
||||||
|
|
||||||
ClassOrNamespace *parent() const;
|
ClassOrNamespace *parent() const;
|
||||||
QList<ClassOrNamespace *> usings() const;
|
QList<ClassOrNamespace *> usings() const;
|
||||||
QList<Enum *> enums() const;
|
QList<Enum *> enums() const;
|
||||||
@@ -72,7 +74,7 @@ private:
|
|||||||
void flush();
|
void flush();
|
||||||
|
|
||||||
/// \internal
|
/// \internal
|
||||||
ClassOrNamespace *findOrCreateType(const Name *name);
|
ClassOrNamespace *findOrCreateType(const Name *name, ClassOrNamespace *origin = 0);
|
||||||
|
|
||||||
void addTodo(Symbol *symbol);
|
void addTodo(Symbol *symbol);
|
||||||
void addSymbol(Symbol *symbol);
|
void addSymbol(Symbol *symbol);
|
||||||
@@ -88,9 +90,9 @@ private:
|
|||||||
const TemplateNameId *templateId);
|
const TemplateNameId *templateId);
|
||||||
|
|
||||||
ClassOrNamespace *lookupType_helper(const Name *name, QSet<ClassOrNamespace *> *processed,
|
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:
|
private:
|
||||||
struct CompareName: std::binary_function<const Name *, const Name *, bool> {
|
struct CompareName: std::binary_function<const Name *, const Name *, bool> {
|
||||||
@@ -109,6 +111,7 @@ private:
|
|||||||
|
|
||||||
// it's an instantiation.
|
// it's an instantiation.
|
||||||
const TemplateNameId *_templateId;
|
const TemplateNameId *_templateId;
|
||||||
|
ClassOrNamespace *_instantiationOrigin;
|
||||||
|
|
||||||
friend class CreateBindings;
|
friend class CreateBindings;
|
||||||
};
|
};
|
||||||
|
@@ -712,10 +712,20 @@ ClassOrNamespace *ResolveExpression::baseExpression(const QList<LookupItem> &bas
|
|||||||
if (ClassOrNamespace *retBinding = findClass(ptrTy->elementType(), overload->enclosingScope()))
|
if (ClassOrNamespace *retBinding = findClass(ptrTy->elementType(), overload->enclosingScope()))
|
||||||
return retBinding;
|
return retBinding;
|
||||||
|
|
||||||
else if (scope != overload->enclosingScope()) {
|
if (scope != overload->enclosingScope()) {
|
||||||
if (ClassOrNamespace *retBinding = findClass(ptrTy->elementType(), scope))
|
if (ClassOrNamespace *retBinding = findClass(ptrTy->elementType(), scope))
|
||||||
return retBinding;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user