From fff4203a46559e0afc751785e25eb702d8c8a608 Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Fri, 16 Jul 2010 11:03:39 +0200 Subject: Introduced helpers to rewrite types and names. Done-with: Erik Verbruggen --- src/libs/cplusplus/ResolveExpression.cpp | 84 +++++++++++++++++++++++++++----- 1 file changed, 72 insertions(+), 12 deletions(-) (limited to 'src/libs/cplusplus/ResolveExpression.cpp') 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 #include @@ -121,6 +122,11 @@ void ResolveExpression::addResults(const QList &symbols) } } +void ResolveExpression::addResults(const QList &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 candidates = _context.lookup(name, _scope); + const QList candidates = _context.lookup(name, _scope); addResults(candidates); } @@ -404,14 +410,14 @@ bool ResolveExpression::visit(QualifiedNameAST *ast) bool ResolveExpression::visit(SimpleNameAST *ast) { - const QList candidates = _context.lookup(ast->name, _scope); + const QList candidates = _context.lookup(ast->name, _scope); addResults(candidates); return false; } bool ResolveExpression::visit(TemplateIdAST *ast) { - const QList candidates = _context.lookup(ast->name, _scope); + const QList 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 ResolveExpression::getMembers(ClassOrNamespace *binding, const Name *memberName) const +{ + QList members; + + const QList 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 &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 &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()); + } } } -- cgit v1.2.3