forked from qt-creator/qt-creator
C++: fix support for typedef of templated typedefs
Fix: * code completion * follow symbols * find usages Task-number: QTCREATORBUG-8375 Change-Id: I6f35e809ba15f224c5a6d9b2fcfc18dbfba55411 Reviewed-by: Sergey Shambir <sergey.shambir.auto@gmail.com> Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
This commit is contained in:
committed by
Erik Verbruggen
parent
357ffaa8bc
commit
13913ed391
@@ -719,10 +719,43 @@ ClassOrNamespace *ClassOrNamespace::lookupType_helper(const Name *name,
|
||||
if (name->isNameId() || name->isTemplateNameId() || name->isAnonymousNameId()) {
|
||||
flush();
|
||||
|
||||
if (name->isTemplateNameId()) {
|
||||
// if it is a base specialization, the 'name' could be an instantiation
|
||||
QMap<const TemplateNameId *, ClassOrNamespace *>::iterator it
|
||||
= _instantiations.find(name->asTemplateNameId());
|
||||
if (it != _instantiations.end())
|
||||
return it.value();
|
||||
}
|
||||
|
||||
foreach (Symbol *s, symbols()) {
|
||||
if (Class *klass = s->asClass()) {
|
||||
if (klass->identifier() && klass->identifier()->isEqualTo(name->identifier()))
|
||||
return this;
|
||||
|
||||
// it can be a typedef
|
||||
const unsigned memberClassCount = klass->memberCount();
|
||||
for (unsigned i = 0; i < memberClassCount; ++i) {
|
||||
Symbol *memberClassAsSymbol = klass->memberAt(i);
|
||||
if (Declaration *declaration = memberClassAsSymbol->asDeclaration()) {
|
||||
if (declaration->isTypedef()
|
||||
&& name->identifier()->isEqualTo(declaration->name()->identifier
|
||||
())) {
|
||||
if (NamedType *namedType = declaration->type()->asNamedType()) {
|
||||
QSet<ClassOrNamespace *> innerProcessed;
|
||||
const Name *namedTypeName = namedType->name();
|
||||
const QualifiedNameId *q = namedTypeName->asQualifiedNameId();
|
||||
if (q && name->isEqualTo(q->base())
|
||||
&& name->isEqualTo(q->name())) {
|
||||
return lookupType_helper_inParent(name, &innerProcessed,
|
||||
searchInEnclosingScope,
|
||||
origin);
|
||||
}
|
||||
return lookupType_helper(namedTypeName, &innerProcessed,
|
||||
true, origin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -746,6 +779,9 @@ ClassOrNamespace *ClassOrNamespace::lookupType_helper(const Name *name,
|
||||
}
|
||||
|
||||
foreach (ClassOrNamespace *u, usings()) {
|
||||
// usings are not instantiated for templates
|
||||
if (_templateId && u->_templateId)
|
||||
continue;
|
||||
if (ClassOrNamespace *r = u->lookupType_helper(name,
|
||||
processed,
|
||||
/*searchInEnclosingScope =*/ false,
|
||||
@@ -754,8 +790,21 @@ ClassOrNamespace *ClassOrNamespace::lookupType_helper(const Name *name,
|
||||
}
|
||||
}
|
||||
|
||||
if (_parent && searchInEnclosingScope)
|
||||
return _parent->lookupType_helper(name, processed, searchInEnclosingScope, origin);
|
||||
return lookupType_helper_inParent(name, processed, searchInEnclosingScope, origin);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ClassOrNamespace *ClassOrNamespace::lookupType_helper_inParent(const Name *name, QSet<ClassOrNamespace *> *processed,
|
||||
bool searchInEnclosingScope, ClassOrNamespace *origin)
|
||||
{
|
||||
if (_parent && searchInEnclosingScope) {
|
||||
// for templates _parent is a base specialization,
|
||||
// so we should take here rather _parent of this base specialization
|
||||
ClassOrNamespace *parent = _templateId ? _parent->_parent : _parent;
|
||||
if (parent)
|
||||
return parent->lookupType_helper(name, processed, searchInEnclosingScope, origin);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -959,7 +1008,7 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac
|
||||
oo.showReturnTypes = true;
|
||||
oo.showTemplateParameters = true;
|
||||
qDebug()<<"cloned"<<oo(clone->type());
|
||||
if (Class *klass = s->asClass()) {
|
||||
if (Class *klass = clone->asClass()) {
|
||||
const unsigned klassMemberCount = klass->memberCount();
|
||||
for (unsigned i = 0; i < klassMemberCount; ++i){
|
||||
Symbol *klassMemberAsSymbol = klass->memberAt(i);
|
||||
|
||||
@@ -111,6 +111,9 @@ private:
|
||||
ClassOrNamespace *lookupType_helper(const Name *name, QSet<ClassOrNamespace *> *processed,
|
||||
bool searchInEnclosingScope, ClassOrNamespace *origin);
|
||||
|
||||
ClassOrNamespace *lookupType_helper_inParent(const Name *name, QSet<ClassOrNamespace *> *processed,
|
||||
bool searchInEnclosingScope, ClassOrNamespace *origin);
|
||||
|
||||
ClassOrNamespace *nestedType(const Name *name, ClassOrNamespace *origin);
|
||||
|
||||
void instantiateNestedClasses(ClassOrNamespace *enclosingTemplateClass,
|
||||
|
||||
@@ -690,8 +690,15 @@ bool ResolveExpression::visit(CallAST *ast)
|
||||
}
|
||||
|
||||
} else if (Function *funTy = ty->asFunctionType()) {
|
||||
if (maybeValidPrototype(funTy, actualArgumentCount))
|
||||
addResult(funTy->returnType().simplified(), scope);
|
||||
if (maybeValidPrototype(funTy, actualArgumentCount)) {
|
||||
LookupItem item;
|
||||
item.setType(funTy->returnType().simplified());
|
||||
item.setScope(scope);
|
||||
// we have to remember a binding because it can be a template instantiation
|
||||
item.setBinding(result.binding());
|
||||
|
||||
_results.append(item);
|
||||
}
|
||||
|
||||
} else if (Class *classTy = ty->asClassType()) {
|
||||
// Constructor call
|
||||
|
||||
Reference in New Issue
Block a user