summaryrefslogtreecommitdiff
path: root/src/libs/cplusplus/LookupContext.cpp
diff options
context:
space:
mode:
authorRoberto Raggi <roberto.raggi@nokia.com>2010-05-21 15:44:04 +0200
committerRoberto Raggi <roberto.raggi@nokia.com>2010-05-25 17:15:21 +0200
commit744d294f3b45bb1332e440c19964fae5462ac719 (patch)
treec832e9251a8342cdfe677c5f7b27b555a048e612 /src/libs/cplusplus/LookupContext.cpp
parent3e9faabf9e36afd5320419ecd4aa67dd44243bd6 (diff)
downloadqt-creator-744d294f3b45bb1332e440c19964fae5462ac719.tar.gz
Improved lookup of qualified names.
Diffstat (limited to 'src/libs/cplusplus/LookupContext.cpp')
-rw-r--r--src/libs/cplusplus/LookupContext.cpp44
1 files changed, 39 insertions, 5 deletions
diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp
index ec1a086b45..ed61e1f8da 100644
--- a/src/libs/cplusplus/LookupContext.cpp
+++ b/src/libs/cplusplus/LookupContext.cpp
@@ -215,22 +215,48 @@ QList<Symbol *> LookupContext::lookup(const Name *name, Scope *scope) const
} else if (scope->isFunctionScope()) {
Function *fun = scope->owner()->asFunction();
bindings()->lookupInScope(name, fun->arguments(), &candidates, /*templateId = */ 0);
+
+ for (TemplateParameters *it = fun->templateParameters(); it && candidates.isEmpty(); it = it->previous())
+ bindings()->lookupInScope(name, it->scope(), &candidates, /* templateId = */ 0);
+
if (! candidates.isEmpty())
- break; // it's a formal argument.
+ break; // it's an argument or a template parameter.
if (fun->name() && fun->name()->isQualifiedNameId()) {
- if (ClassOrNamespace *binding = bindings()->lookupType(fun))
- return binding->lookup(name);
+ if (ClassOrNamespace *binding = bindings()->lookupType(fun)) {
+ candidates = binding->lookup(name);
+
+ if (! candidates.isEmpty())
+ return candidates;
+ }
}
+ // contunue, and look at the enclosing scope.
+
} else if (scope->isObjCMethodScope()) {
ObjCMethod *method = scope->owner()->asObjCMethod();
bindings()->lookupInScope(name, method->arguments(), &candidates, /*templateId = */ 0);
+
if (! candidates.isEmpty())
break; // it's a formal argument.
- } else if (scope->isClassScope() || scope->isNamespaceScope()
- || scope->isObjCClassScope() || scope->isObjCProtocolScope()) {
+ } else if (scope->isClassScope()) {
+ Class *klass = scope->owner()->asClass();
+
+ for (TemplateParameters *it = klass->templateParameters(); it && candidates.isEmpty(); it = it->previous())
+ bindings()->lookupInScope(name, it->scope(), &candidates, /* templateId = */ 0);
+
+ if (! candidates.isEmpty())
+ break; // it's an argument or a template parameter.
+
+ if (ClassOrNamespace *binding = bindings()->lookupType(klass)) {
+ candidates = binding->lookup(name);
+
+ if (! candidates.isEmpty())
+ return candidates;
+ }
+
+ } else if (scope->isNamespaceScope() || scope->isObjCClassScope() || scope->isObjCProtocolScope()) {
if (ClassOrNamespace *binding = bindings()->lookupType(scope->owner()))
return binding->lookup(name);
@@ -458,6 +484,14 @@ ClassOrNamespace *ClassOrNamespace::lookupType_helper(const Name *name,
if (ClassOrNamespace *e = nestedType(name))
return e;
+ else if (_templateId) {
+ Q_ASSERT(_usings.size() == 1);
+ ClassOrNamespace *delegate = _usings.first();
+
+ if (ClassOrNamespace *r = delegate->lookupType_helper(name, processed, /*searchInEnclosingScope = */ true))
+ return r;
+ }
+
foreach (ClassOrNamespace *u, usings()) {
if (ClassOrNamespace *r = u->lookupType_helper(name, processed, /*searchInEnclosingScope =*/ false))
return r;