aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/cplusplus/ResolveExpression.cpp
diff options
context:
space:
mode:
authorRoberto Raggi <[email protected]>2010-07-16 11:03:39 +0200
committerRoberto Raggi <[email protected]>2010-07-16 11:04:52 +0200
commitfff4203a46559e0afc751785e25eb702d8c8a608 (patch)
tree53e4a813426e6f2d4fc4603936e34601c8e30c11 /src/libs/cplusplus/ResolveExpression.cpp
parent41236d29d328950d9240d4e3a5e2c98d3214b65b (diff)
Introduced helpers to rewrite types and names.
Done-with: Erik Verbruggen
Diffstat (limited to 'src/libs/cplusplus/ResolveExpression.cpp')
-rw-r--r--src/libs/cplusplus/ResolveExpression.cpp84
1 files changed, 72 insertions, 12 deletions
diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp
index b02b7ecf5d1..3f2ae7ac82e 100644
--- a/src/libs/cplusplus/ResolveExpression.cpp
+++ b/src/libs/cplusplus/ResolveExpression.cpp
@@ -31,6 +31,7 @@
#include "LookupContext.h"
#include "Overview.h"
#include "DeprecatedGenTemplateInstance.h"
+#include "CppRewriter.h"
#include <Control.h>
#include <AST.h>
@@ -121,6 +122,11 @@ void ResolveExpression::addResults(const QList<Symbol *> &symbols)
}
}
+void ResolveExpression::addResults(const QList<LookupItem> &items)
+{
+ _results += items;
+}
+
void ResolveExpression::addResult(const FullySpecifiedType &ty, Scope *scope)
{
LookupItem item;
@@ -395,7 +401,7 @@ bool ResolveExpression::visit(CompoundLiteralAST *ast)
bool ResolveExpression::visit(QualifiedNameAST *ast)
{
if (const Name *name = ast->name) {
- const QList<Symbol *> candidates = _context.lookup(name, _scope);
+ const QList<LookupItem> candidates = _context.lookup(name, _scope);
addResults(candidates);
}
@@ -404,14 +410,14 @@ bool ResolveExpression::visit(QualifiedNameAST *ast)
bool ResolveExpression::visit(SimpleNameAST *ast)
{
- const QList<Symbol *> candidates = _context.lookup(ast->name, _scope);
+ const QList<LookupItem> candidates = _context.lookup(ast->name, _scope);
addResults(candidates);
return false;
}
bool ResolveExpression::visit(TemplateIdAST *ast)
{
- const QList<Symbol *> candidates = _context.lookup(ast->name, _scope);
+ const QList<LookupItem> candidates = _context.lookup(ast->name, _scope);
addResults(candidates);
return false;
}
@@ -477,7 +483,8 @@ bool ResolveExpression::visit(CallAST *ast)
if (NamedType *namedTy = ty->asNamedType()) {
if (ClassOrNamespace *b = _context.lookupType(namedTy->name(), scope)) {
- foreach (Symbol *overload, b->find(functionCallOp)) {
+ foreach (const LookupItem &r, b->find(functionCallOp)) {
+ Symbol *overload = r.declaration();
if (Function *funTy = overload->type()->asFunctionType()) {
if (maybeValidPrototype(funTy, actualArgumentCount)) {
if (Function *proto = instantiate(namedTy->name(), funTy)->asFunctionType())
@@ -520,7 +527,8 @@ bool ResolveExpression::visit(ArrayAccessAST *ast)
} else if (NamedType *namedTy = ty->asNamedType()) {
if (ClassOrNamespace *b = _context.lookupType(namedTy->name(), scope)) {
- foreach (Symbol *overload, b->find(arrayAccessOp)) {
+ foreach (const LookupItem &r, b->find(arrayAccessOp)) {
+ Symbol *overload = r.declaration();
if (Function *funTy = overload->type()->asFunctionType()) {
if (Function *proto = instantiate(namedTy->name(), funTy)->asFunctionType())
// ### TODO: check the actual arguments
@@ -534,6 +542,56 @@ bool ResolveExpression::visit(ArrayAccessAST *ast)
return false;
}
+QList<LookupItem> ResolveExpression::getMembers(ClassOrNamespace *binding, const Name *memberName) const
+{
+ QList<LookupItem> members;
+
+ const QList<LookupItem> originalMembers = binding->find(memberName);
+
+ foreach (const LookupItem &m, originalMembers) {
+ if (! m.binding() || ! m.binding()->templateId()) {
+ members.append(m);
+ continue;
+ }
+
+ Symbol *decl = m.declaration();
+
+ if (Class *klass = decl->enclosingSymbol()->asClass()) {
+ if (klass->templateParameters() != 0) {
+ SubstitutionMap map;
+
+ const TemplateNameId *templateId = m.binding()->templateId();
+ unsigned count = qMin(klass->templateParameterCount(), templateId->templateArgumentCount());
+
+ for (unsigned i = 0; i < count; ++i) {
+ map.bind(klass->templateParameterAt(i)->name(), templateId->templateArgumentAt(i));
+ }
+
+ SubstitutionEnvironment env;
+ ContextSubstitution ctxSubst(_context, m.scope());
+
+ env.enter(&ctxSubst);
+ env.enter(&map);
+ FullySpecifiedType instantiatedTy = rewriteType(decl->type(), env, _context.control().data());
+
+ Overview oo;
+ oo.setShowReturnTypes(true);
+ oo.setShowFunctionSignatures(true);
+
+ qDebug() << "original:" << oo(decl->type(), decl->name()) << "inst:" << oo(instantiatedTy, decl->name());
+
+ LookupItem newItem;
+ newItem = m;
+ newItem.setType(instantiatedTy);
+ members.append(newItem);
+ }
+ }
+ }
+
+
+ return members;
+}
+
bool ResolveExpression::visit(MemberAccessAST *ast)
{
// The candidate types for the base expression are stored in
@@ -586,9 +644,13 @@ ClassOrNamespace *ResolveExpression::baseExpression(const QList<LookupItem> &bas
} else if (ClassOrNamespace *binding = findClass(ty, scope)) {
// lookup for overloads of operator->
+
const OperatorNameId *arrowOp = control()->operatorNameId(OperatorNameId::ArrowOp);
+ foreach (const LookupItem &r, binding->find(arrowOp)) {
+ Symbol *overload = r.declaration();
+ if (! overload)
+ continue;
- foreach (Symbol *overload, binding->find(arrowOp)) {
if (overload->type()->isFunctionType()) {
FullySpecifiedType overloadTy = instantiate(binding->templateId(), overload);
Function *instantiatedFunction = overloadTy->asFunctionType();
@@ -604,14 +666,10 @@ ClassOrNamespace *ResolveExpression::baseExpression(const QList<LookupItem> &bas
if (ClassOrNamespace *retBinding = findClass(ptrTy->elementType(), scope))
return retBinding;
}
-
- if (debug) {
- Overview oo;
- qDebug() << "no class for:" << oo(ptrTy->elementType());
- }
}
}
}
+
}
} else if (accessOp == T_DOT) {
if (replacedDotOperator) {
@@ -663,9 +721,11 @@ bool ResolveExpression::visit(ObjCMessageExpressionAST *ast)
}
if (binding) {
- foreach (Symbol *s, binding->lookup(ast->selector->name))
+ foreach (const LookupItem &r, binding->lookup(ast->selector->name)) {
+ Symbol *s = r.declaration();
if (ObjCMethod *m = s->asObjCMethod())
addResult(m->returnType(), result.scope());
+ }
}
}