diff options
author | Przemyslaw Gorszkowski <pgorszkowski@gmail.com> | 2013-04-15 12:50:36 +0200 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@digia.com> | 2013-04-19 12:19:20 +0200 |
commit | 13913ed3913eac8b5fd0d63e4706c44223f65e4b (patch) | |
tree | 7e3a6e8c5b642df9d761343c43925246823bf24f /src/libs/cplusplus/LookupContext.cpp | |
parent | 357ffaa8bc563442dee8c17d8298936b62b500c6 (diff) | |
download | qt-creator-13913ed3913eac8b5fd0d63e4706c44223f65e4b.tar.gz |
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>
Diffstat (limited to 'src/libs/cplusplus/LookupContext.cpp')
-rw-r--r-- | src/libs/cplusplus/LookupContext.cpp | 55 |
1 files changed, 52 insertions, 3 deletions
diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index dde50df687..6df4b43cf3 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -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); |