summaryrefslogtreecommitdiff
path: root/src/libs/cplusplus/LookupContext.cpp
diff options
context:
space:
mode:
authorPrzemyslaw Gorszkowski <pgorszkowski@gmail.com>2013-04-15 12:50:36 +0200
committerErik Verbruggen <erik.verbruggen@digia.com>2013-04-19 12:19:20 +0200
commit13913ed3913eac8b5fd0d63e4706c44223f65e4b (patch)
tree7e3a6e8c5b642df9d761343c43925246823bf24f /src/libs/cplusplus/LookupContext.cpp
parent357ffaa8bc563442dee8c17d8298936b62b500c6 (diff)
downloadqt-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.cpp55
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);