
/* Compiler implementation of the D programming language
 * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved
 * written by Walter Bright
 * http://www.digitalmars.com
 * Distributed under the Boost Software License, Version 1.0.
 * http://www.boost.org/LICENSE_1_0.txt
 * https://github.com/D-Programming-Language/dmd/blob/master/src/opover.c
 */

#include "root/dsystem.h"               // memset()
#include "root/rmem.h"

#include "mars.h"
#include "mtype.h"
#include "init.h"
#include "expression.h"
#include "statement.h"
#include "scope.h"
#include "id.h"
#include "declaration.h"
#include "aggregate.h"
#include "template.h"
#include "tokens.h"

static Dsymbol *inferApplyArgTypesX(Expression *ethis, FuncDeclaration *fstart, Parameters *parameters);
static int inferApplyArgTypesY(TypeFunction *tf, Parameters *parameters, int flags = 0);
Expression *compare_overload(BinExp *e, Scope *sc, Identifier *id);
bool MODimplicitConv(MOD modfrom, MOD modto);
Expression *trySemantic(Expression *e, Scope *sc);
Expression *binSemanticProp(BinExp *e, Scope *sc);
Expression *semantic(Expression *e, Scope *sc);

/******************************** Expression **************************/


/***********************************
 * Determine if operands of binary op can be reversed
 * to fit operator overload.
 */

bool isCommutative(TOK op)
{
    switch (op)
    {
        case TOKadd:
        case TOKmul:
        case TOKand:
        case TOKor:
        case TOKxor:

        // EqualExp
        case TOKequal:
        case TOKnotequal:

        // CmpExp
        case TOKlt:
        case TOKle:
        case TOKgt:
        case TOKge:
            return true;

        default:
            break;
    }
    return false;
}

/***********************************
 * Get Identifier for operator overload.
 */

static Identifier *opId(Expression *e)
{
    class OpIdVisitor : public Visitor
    {
    public:
        Identifier *id;
        void visit(Expression *)    { assert(0); }
        void visit(UAddExp *)       { id = Id::uadd; }
        void visit(NegExp *)        { id = Id::neg; }
        void visit(ComExp *)        { id = Id::com; }
        void visit(CastExp *)       { id = Id::_cast; }
        void visit(InExp *)         { id = Id::opIn; }
        void visit(PostExp *e)      { id = (e->op == TOKplusplus) ? Id::postinc : Id::postdec; }
        void visit(AddExp *)        { id = Id::add; }
        void visit(MinExp *)        { id = Id::sub; }
        void visit(MulExp *)        { id = Id::mul; }
        void visit(DivExp *)        { id = Id::div; }
        void visit(ModExp *)        { id = Id::mod; }
        void visit(PowExp *)        { id = Id::pow; }
        void visit(ShlExp *)        { id = Id::shl; }
        void visit(ShrExp *)        { id = Id::shr; }
        void visit(UshrExp *)       { id = Id::ushr; }
        void visit(AndExp *)        { id = Id::iand; }
        void visit(OrExp *)         { id = Id::ior; }
        void visit(XorExp *)        { id = Id::ixor; }
        void visit(CatExp *)        { id = Id::cat; }
        void visit(AssignExp *)     { id = Id::assign; }
        void visit(AddAssignExp *)  { id = Id::addass; }
        void visit(MinAssignExp *)  { id = Id::subass; }
        void visit(MulAssignExp *)  { id = Id::mulass; }
        void visit(DivAssignExp *)  { id = Id::divass; }
        void visit(ModAssignExp *)  { id = Id::modass; }
        void visit(AndAssignExp *)  { id = Id::andass; }
        void visit(OrAssignExp *)   { id = Id::orass; }
        void visit(XorAssignExp *)  { id = Id::xorass; }
        void visit(ShlAssignExp *)  { id = Id::shlass; }
        void visit(ShrAssignExp *)  { id = Id::shrass; }
        void visit(UshrAssignExp *) { id = Id::ushrass; }
        void visit(CatAssignExp *)  { id = Id::catass; }
        void visit(PowAssignExp *)  { id = Id::powass; }
        void visit(EqualExp *)      { id = Id::eq; }
        void visit(CmpExp *)        { id = Id::cmp; }
        void visit(ArrayExp *)      { id = Id::index; }
        void visit(PtrExp *)        { id = Id::opStar; }
    };
    OpIdVisitor v;
    e->accept(&v);
    return v.id;
}

/***********************************
 * Get Identifier for reverse operator overload,
 * NULL if not supported for this operator.
 */

static Identifier *opId_r(Expression *e)
{
    class OpIdRVisitor : public Visitor
    {
    public:
        Identifier *id;
        void visit(Expression *) { id = NULL; }
        void visit(InExp *)      { id = Id::opIn_r; }
        void visit(AddExp *)     { id = Id::add_r; }
        void visit(MinExp *)     { id = Id::sub_r; }
        void visit(MulExp *)     { id = Id::mul_r; }
        void visit(DivExp *)     { id = Id::div_r; }
        void visit(ModExp *)     { id = Id::mod_r; }
        void visit(PowExp *)     { id = Id::pow_r; }
        void visit(ShlExp *)     { id = Id::shl_r; }
        void visit(ShrExp *)     { id = Id::shr_r; }
        void visit(UshrExp *)    { id = Id::ushr_r; }
        void visit(AndExp *)     { id = Id::iand_r; }
        void visit(OrExp *)      { id = Id::ior_r; }
        void visit(XorExp *)     { id = Id::ixor_r; }
        void visit(CatExp *)     { id = Id::cat_r; }
    };
    OpIdRVisitor v;
    e->accept(&v);
    return v.id;
}

/************************************
 * If type is a class or struct, return the symbol for it,
 * else NULL
 */
AggregateDeclaration *isAggregate(Type *t)
{
    t = t->toBasetype();
    if (t->ty == Tclass)
    {
        return ((TypeClass *)t)->sym;
    }
    else if (t->ty == Tstruct)
    {
        return ((TypeStruct *)t)->sym;
    }
    return NULL;
}

/*******************************************
 * Helper function to turn operator into template argument list
 */
Objects *opToArg(Scope *sc, TOK op)
{
    /* Remove the = from op=
     */
    switch (op)
    {
        case TOKaddass: op = TOKadd; break;
        case TOKminass: op = TOKmin; break;
        case TOKmulass: op = TOKmul; break;
        case TOKdivass: op = TOKdiv; break;
        case TOKmodass: op = TOKmod; break;
        case TOKandass: op = TOKand; break;
        case TOKorass:  op = TOKor;  break;
        case TOKxorass: op = TOKxor; break;
        case TOKshlass: op = TOKshl; break;
        case TOKshrass: op = TOKshr; break;
        case TOKushrass: op = TOKushr; break;
        case TOKcatass: op = TOKcat; break;
        case TOKpowass: op = TOKpow; break;
        default:                     break;
    }
    Expression *e = new StringExp(Loc(), const_cast<char *>(Token::toChars(op)));
    e = semantic(e, sc);
    Objects *tiargs = new Objects();
    tiargs->push(e);
    return tiargs;
}

/************************************
 * Operator overload.
 * Check for operator overload, if so, replace
 * with function call.
 * Return NULL if not an operator overload.
 */

Expression *op_overload(Expression *e, Scope *sc)
{
    class OpOverload : public Visitor
    {
    public:
        Scope *sc;
        Expression *result;

        OpOverload(Scope *sc)
            : sc(sc)
        {
            result = NULL;
        }

        void visit(Expression *)
        {
            assert(0);
        }

        void visit(UnaExp *e)
        {
            //printf("UnaExp::op_overload() (%s)\n", e->toChars());

            if (e->e1->op == TOKarray)
            {
                ArrayExp *ae = (ArrayExp *)e->e1;
                ae->e1 = semantic(ae->e1, sc);
                ae->e1 = resolveProperties(sc, ae->e1);
                Expression *ae1old = ae->e1;

                const bool maybeSlice =
                    (ae->arguments->dim == 0 ||
                     (ae->arguments->dim == 1 && (*ae->arguments)[0]->op == TOKinterval));
                IntervalExp *ie = NULL;
                if (maybeSlice && ae->arguments->dim)
                {
                    assert((*ae->arguments)[0]->op == TOKinterval);
                    ie = (IntervalExp *)(*ae->arguments)[0];
                }

                while (true)
                {
                    if (ae->e1->op == TOKerror)
                    {
                        result = ae->e1;
                        return;
                    }
                    Expression *e0 = NULL;
                    Expression *ae1save = ae->e1;
                    ae->lengthVar = NULL;

                    Type *t1b = ae->e1->type->toBasetype();
                    AggregateDeclaration *ad = isAggregate(t1b);
                    if (!ad)
                        break;
                    if (search_function(ad, Id::opIndexUnary))
                    {
                        // Deal with $
                        result = resolveOpDollar(sc, ae, &e0);
                        if (!result)    // op(a[i..j]) might be: a.opSliceUnary!(op)(i, j)
                            goto Lfallback;
                        if (result->op == TOKerror)
                            return;

                        /* Rewrite op(a[arguments]) as:
                         *      a.opIndexUnary!(op)(arguments)
                         */
                        Expressions *a = (Expressions *)ae->arguments->copy();
                        Objects *tiargs = opToArg(sc, e->op);
                        result = new DotTemplateInstanceExp(e->loc, ae->e1, Id::opIndexUnary, tiargs);
                        result = new CallExp(e->loc, result, a);
                        if (maybeSlice) // op(a[]) might be: a.opSliceUnary!(op)()
                            result = trySemantic(result, sc);
                        else
                            result = semantic(result, sc);
                        if (result)
                        {
                            result = Expression::combine(e0, result);
                            return;
                        }
                    }
                Lfallback:
                    if (maybeSlice && search_function(ad, Id::opSliceUnary))
                    {
                        // Deal with $
                        result = resolveOpDollar(sc, ae, ie, &e0);
                        if (result->op == TOKerror)
                            return;

                        /* Rewrite op(a[i..j]) as:
                         *      a.opSliceUnary!(op)(i, j)
                         */
                        Expressions *a = new Expressions();
                        if (ie)
                        {
                            a->push(ie->lwr);
                            a->push(ie->upr);
                        }
                        Objects *tiargs = opToArg(sc, e->op);
                        result = new DotTemplateInstanceExp(e->loc, ae->e1, Id::opSliceUnary, tiargs);
                        result = new CallExp(e->loc, result, a);
                        result = semantic(result, sc);
                        result = Expression::combine(e0, result);
                        return;
                    }

                    // Didn't find it. Forward to aliasthis
                    if (ad->aliasthis && t1b != ae->att1)
                    {
                        if (!ae->att1 && t1b->checkAliasThisRec())
                            ae->att1 = t1b;

                        /* Rewrite op(a[arguments]) as:
                         *      op(a.aliasthis[arguments])
                         */
                        ae->e1 = resolveAliasThis(sc, ae1save, true);
                        if (ae->e1)
                            continue;
                    }
                    break;
                }
                ae->e1 = ae1old;    // recovery
                ae->lengthVar = NULL;
            }

            e->e1 = semantic(e->e1, sc);
            e->e1 = resolveProperties(sc, e->e1);
            if (e->e1->op == TOKerror)
            {
                result = e->e1;
                return;
            }

            AggregateDeclaration *ad = isAggregate(e->e1->type);
            if (ad)
            {
                Dsymbol *fd = NULL;
        #if 1 // Old way, kept for compatibility with D1
                if (e->op != TOKpreplusplus && e->op != TOKpreminusminus)
                {
                    fd = search_function(ad, opId(e));
                    if (fd)
                    {
                        // Rewrite +e1 as e1.add()
                        result = build_overload(e->loc, sc, e->e1, NULL, fd);
                        return;
                    }
                }
        #endif

                /* Rewrite as:
                 *      e1.opUnary!(op)()
                 */
                fd = search_function(ad, Id::opUnary);
                if (fd)
                {
                    Objects *tiargs = opToArg(sc, e->op);
                    result = new DotTemplateInstanceExp(e->loc, e->e1, fd->ident, tiargs);
                    result = new CallExp(e->loc, result);
                    result = semantic(result, sc);
                    return;
                }

                // Didn't find it. Forward to aliasthis
                if (ad->aliasthis && e->e1->type != e->att1)
                {
                    /* Rewrite op(e1) as:
                     *      op(e1.aliasthis)
                     */
                    //printf("att una %s e1 = %s\n", Token::toChars(op), this->e1->type->toChars());
                    Expression *e1 = new DotIdExp(e->loc, e->e1, ad->aliasthis->ident);
                    UnaExp *ue = (UnaExp *)e->copy();
                    if (!ue->att1 && e->e1->type->checkAliasThisRec())
                        ue->att1 = e->e1->type;
                    ue->e1 = e1;
                    result = trySemantic(ue, sc);
                    return;
                }
            }
        }

        void visit(ArrayExp *ae)
        {
            //printf("ArrayExp::op_overload() (%s)\n", ae->toChars());
            ae->e1 = semantic(ae->e1, sc);
            ae->e1 = resolveProperties(sc, ae->e1);
            Expression *ae1old = ae->e1;

            const bool maybeSlice =
                (ae->arguments->dim == 0 ||
                 (ae->arguments->dim == 1 && (*ae->arguments)[0]->op == TOKinterval));
            IntervalExp *ie = NULL;
            if (maybeSlice && ae->arguments->dim)
            {
                assert((*ae->arguments)[0]->op == TOKinterval);
                ie = (IntervalExp *)(*ae->arguments)[0];
            }

            while (true)
            {
                if (ae->e1->op == TOKerror)
                {
                    result = ae->e1;
                    return;
                }
                Expression *e0 = NULL;
                Expression *ae1save = ae->e1;
                ae->lengthVar = NULL;

                Type *t1b = ae->e1->type->toBasetype();
                AggregateDeclaration *ad = isAggregate(t1b);
                if (!ad)
                {
                    // If the non-aggregate expression ae->e1 is indexable or sliceable,
                    // convert it to the corresponding concrete expression.
                    if (t1b->ty == Tpointer ||
                        t1b->ty == Tsarray ||
                        t1b->ty == Tarray ||
                        t1b->ty == Taarray ||
                        t1b->ty == Ttuple ||
                        t1b->ty == Tvector ||
                        ae->e1->op == TOKtype)
                    {
                        // Convert to SliceExp
                        if (maybeSlice)
                        {
                            result = new SliceExp(ae->loc, ae->e1, ie);
                            result = semantic(result, sc);
                            return;
                        }
                        // Convert to IndexExp
                        if (ae->arguments->dim == 1)
                        {
                            result = new IndexExp(ae->loc, ae->e1, (*ae->arguments)[0]);
                            result = semantic(result, sc);
                            return;
                        }
                    }
                    break;
                }
                if (search_function(ad, Id::index))
                {
                    // Deal with $
                    result = resolveOpDollar(sc, ae, &e0);
                    if (!result)    // a[i..j] might be: a.opSlice(i, j)
                        goto Lfallback;
                    if (result->op == TOKerror)
                        return;

                    /* Rewrite e1[arguments] as:
                     *      e1.opIndex(arguments)
                     */
                    Expressions *a = (Expressions *)ae->arguments->copy();
                    result = new DotIdExp(ae->loc, ae->e1, Id::index);
                    result = new CallExp(ae->loc, result, a);
                    if (maybeSlice) // a[] might be: a.opSlice()
                        result = trySemantic(result, sc);
                    else
                        result = semantic(result, sc);
                    if (result)
                    {
                        result = Expression::combine(e0, result);
                        return;
                    }
                }
            Lfallback:
                if (maybeSlice && ae->e1->op == TOKtype)
                {
                    result = new SliceExp(ae->loc, ae->e1, ie);
                    result = semantic(result, sc);
                    result = Expression::combine(e0, result);
                    return;
                }
                if (maybeSlice && search_function(ad, Id::slice))
                {
                    // Deal with $
                    result = resolveOpDollar(sc, ae, ie, &e0);
                    if (result->op == TOKerror)
                        return;

                    /* Rewrite a[i..j] as:
                     *      a.opSlice(i, j)
                     */
                    Expressions *a = new Expressions();
                    if (ie)
                    {
                        a->push(ie->lwr);
                        a->push(ie->upr);
                    }
                    result = new DotIdExp(ae->loc, ae->e1, Id::slice);
                    result = new CallExp(ae->loc, result, a);
                    result = semantic(result, sc);
                    result = Expression::combine(e0, result);
                    return;
                }

                // Didn't find it. Forward to aliasthis
                if (ad->aliasthis && t1b != ae->att1)
                {
                    if (!ae->att1 && t1b->checkAliasThisRec())
                        ae->att1 = t1b;
                    //printf("att arr e1 = %s\n", this->e1->type->toChars());

                    /* Rewrite op(a[arguments]) as:
                     *      op(a.aliasthis[arguments])
                     */
                    ae->e1 = resolveAliasThis(sc, ae1save, true);
                    if (ae->e1)
                        continue;
                }
                break;
            }
            ae->e1 = ae1old;    // recovery
            ae->lengthVar = NULL;
        }

        /***********************************************
         * This is mostly the same as UnaryExp::op_overload(), but has
         * a different rewrite.
         */
        void visit(CastExp *e)
        {
            //printf("CastExp::op_overload() (%s)\n", e->toChars());
            AggregateDeclaration *ad = isAggregate(e->e1->type);
            if (ad)
            {
                Dsymbol *fd = NULL;
                /* Rewrite as:
                 *      e1.opCast!(T)()
                 */
                fd = search_function(ad, Id::_cast);
                if (fd)
                {
        #if 1 // Backwards compatibility with D1 if opCast is a function, not a template
                    if (fd->isFuncDeclaration())
                    {
                        // Rewrite as:  e1.opCast()
                        result = build_overload(e->loc, sc, e->e1, NULL, fd);
                        return;
                    }
        #endif
                    Objects *tiargs = new Objects();
                    tiargs->push(e->to);
                    result = new DotTemplateInstanceExp(e->loc, e->e1, fd->ident, tiargs);
                    result = new CallExp(e->loc, result);
                    result = semantic(result, sc);
                    return;
                }

                // Didn't find it. Forward to aliasthis
                if (ad->aliasthis)
                {
                    /* Rewrite op(e1) as:
                     *      op(e1.aliasthis)
                     */
                    Expression *e1 = new DotIdExp(e->loc, e->e1, ad->aliasthis->ident);
                    result = e->copy();
                    ((UnaExp *)result)->e1 = e1;
                    result = trySemantic(result, sc);
                    return;
                }
            }
        }

        void visit(BinExp *e)
        {
            //printf("BinExp::op_overload() (%s)\n", e->toChars());

            Identifier *id = opId(e);
            Identifier *id_r = opId_r(e);

            Expressions args1;
            Expressions args2;
            int argsset = 0;

            AggregateDeclaration *ad1 = isAggregate(e->e1->type);
            AggregateDeclaration *ad2 = isAggregate(e->e2->type);

            if (e->op == TOKassign && ad1 == ad2)
            {
                StructDeclaration *sd = ad1->isStructDeclaration();
                if (sd && !sd->hasIdentityAssign)
                {
                    /* This is bitwise struct assignment. */
                    return;
                }
            }

            Dsymbol *s = NULL;
            Dsymbol *s_r = NULL;

        #if 1 // the old D1 scheme
            if (ad1 && id)
            {
                s = search_function(ad1, id);
            }
            if (ad2 && id_r)
            {
                s_r = search_function(ad2, id_r);

                // Bugzilla 12778: If both x.opBinary(y) and y.opBinaryRight(x) found,
                // and they are exactly same symbol, x.opBinary(y) should be preferred.
                if (s_r && s_r == s)
                    s_r = NULL;
            }
        #endif

            Objects *tiargs = NULL;
            if (e->op == TOKplusplus || e->op == TOKminusminus)
            {
                // Bug4099 fix
                if (ad1 && search_function(ad1, Id::opUnary))
                    return;
            }
            if (!s && !s_r && e->op != TOKequal && e->op != TOKnotequal && e->op != TOKassign &&
                e->op != TOKplusplus && e->op != TOKminusminus)
            {
                /* Try the new D2 scheme, opBinary and opBinaryRight
                 */
                if (ad1)
                {
                    s = search_function(ad1, Id::opBinary);
                    if (s && !s->isTemplateDeclaration())
                    {
                        e->e1->error("%s.opBinary isn't a template", e->e1->toChars());
                        result = new ErrorExp();
                        return;
                    }
                }
                if (ad2)
                {
                    s_r = search_function(ad2, Id::opBinaryRight);
                    if (s_r && !s_r->isTemplateDeclaration())
                    {
                        e->e2->error("%s.opBinaryRight isn't a template", e->e2->toChars());
                        result = new ErrorExp();
                        return;
                    }
                    if (s_r && s_r == s)    // Bugzilla 12778
                        s_r = NULL;
                }

                // Set tiargs, the template argument list, which will be the operator string
                if (s || s_r)
                {
                    id = Id::opBinary;
                    id_r = Id::opBinaryRight;
                    tiargs = opToArg(sc, e->op);
                }
            }

            if (s || s_r)
            {
                /* Try:
                 *      a.opfunc(b)
                 *      b.opfunc_r(a)
                 * and see which is better.
                 */

                args1.setDim(1);
                args1[0] = e->e1;
                expandTuples(&args1);
                args2.setDim(1);
                args2[0] = e->e2;
                expandTuples(&args2);
                argsset = 1;

                Match m;
                memset(&m, 0, sizeof(m));
                m.last = MATCHnomatch;

                if (s)
                {
                    functionResolve(&m, s, e->loc, sc, tiargs, e->e1->type, &args2);
                    if (m.lastf && (m.lastf->errors || m.lastf->semantic3Errors))
                    {
                        result = new ErrorExp();
                        return;
                    }
                }

                FuncDeclaration *lastf = m.lastf;

                if (s_r)
                {
                    functionResolve(&m, s_r, e->loc, sc, tiargs, e->e2->type, &args1);
                    if (m.lastf && (m.lastf->errors || m.lastf->semantic3Errors))
                    {
                        result = new ErrorExp();
                        return;
                    }
                }

                if (m.count > 1)
                {
                    // Error, ambiguous
                    e->error("overloads %s and %s both match argument list for %s",
                            m.lastf->type->toChars(),
                            m.nextf->type->toChars(),
                            m.lastf->toChars());
                }
                else if (m.last <= MATCHnomatch)
                {
                    m.lastf = m.anyf;
                    if (tiargs)
                        goto L1;
                }

                if (e->op == TOKplusplus || e->op == TOKminusminus)
                {
                    // Kludge because operator overloading regards e++ and e--
                    // as unary, but it's implemented as a binary.
                    // Rewrite (e1 ++ e2) as e1.postinc()
                    // Rewrite (e1 -- e2) as e1.postdec()
                    result = build_overload(e->loc, sc, e->e1, NULL, m.lastf ? m.lastf : s);
                }
                else if ((lastf && m.lastf == lastf) || (!s_r && m.last <= MATCHnomatch))
                {
                    // Rewrite (e1 op e2) as e1.opfunc(e2)
                    result = build_overload(e->loc, sc, e->e1, e->e2, m.lastf ? m.lastf : s);
                }
                else
                {
                    // Rewrite (e1 op e2) as e2.opfunc_r(e1)
                    result = build_overload(e->loc, sc, e->e2, e->e1, m.lastf ? m.lastf : s_r);
                }
                return;
            }

        L1:
        #if 1 // Retained for D1 compatibility
            if (isCommutative(e->op) && !tiargs)
            {
                s = NULL;
                s_r = NULL;
                if (ad1 && id_r)
                {
                    s_r = search_function(ad1, id_r);
                }
                if (ad2 && id)
                {
                    s = search_function(ad2, id);
                    if (s && s == s_r)  // Bugzilla 12778
                        s = NULL;
                }

                if (s || s_r)
                {
                    /* Try:
                     *  a.opfunc_r(b)
                     *  b.opfunc(a)
                     * and see which is better.
                     */

                    if (!argsset)
                    {
                        args1.setDim(1);
                        args1[0] = e->e1;
                        expandTuples(&args1);
                        args2.setDim(1);
                        args2[0] = e->e2;
                        expandTuples(&args2);
                    }

                    Match m;
                    memset(&m, 0, sizeof(m));
                    m.last = MATCHnomatch;

                    if (s_r)
                    {
                        functionResolve(&m, s_r, e->loc, sc, tiargs, e->e1->type, &args2);
                        if (m.lastf && (m.lastf->errors || m.lastf->semantic3Errors))
                        {
                            result = new ErrorExp();
                            return;
                        }
                    }

                    FuncDeclaration *lastf = m.lastf;

                    if (s)
                    {
                        functionResolve(&m, s, e->loc, sc, tiargs, e->e2->type, &args1);
                        if (m.lastf && (m.lastf->errors || m.lastf->semantic3Errors))
                        {
                            result = new ErrorExp();
                            return;
                        }
                    }

                    if (m.count > 1)
                    {
                        // Error, ambiguous
                        e->error("overloads %s and %s both match argument list for %s",
                                m.lastf->type->toChars(),
                                m.nextf->type->toChars(),
                                m.lastf->toChars());
                    }
                    else if (m.last <= MATCHnomatch)
                    {
                        m.lastf = m.anyf;
                    }

                    if ((lastf && m.lastf == lastf) || (!s && m.last <= MATCHnomatch))
                    {
                        // Rewrite (e1 op e2) as e1.opfunc_r(e2)
                        result = build_overload(e->loc, sc, e->e1, e->e2, m.lastf ? m.lastf : s_r);
                    }
                    else
                    {
                        // Rewrite (e1 op e2) as e2.opfunc(e1)
                        result = build_overload(e->loc, sc, e->e2, e->e1, m.lastf ? m.lastf : s);
                    }

                    // When reversing operands of comparison operators,
                    // need to reverse the sense of the op
                    switch (e->op)
                    {
                        case TOKlt:     e->op = TOKgt;     break;
                        case TOKgt:     e->op = TOKlt;     break;
                        case TOKle:     e->op = TOKge;     break;
                        case TOKge:     e->op = TOKle;     break;
                        default:                           break;
                    }

                    return;
                }
            }
        #endif

            // Try alias this on first operand
            if (ad1 && ad1->aliasthis &&
                !(e->op == TOKassign && ad2 && ad1 == ad2))   // See Bugzilla 2943
            {
                /* Rewrite (e1 op e2) as:
                 *      (e1.aliasthis op e2)
                 */
                if (e->att1 && e->e1->type == e->att1)
                    return;
                //printf("att bin e1 = %s\n", this->e1->type->toChars());
                Expression *e1 = new DotIdExp(e->loc, e->e1, ad1->aliasthis->ident);
                BinExp *be = (BinExp *)e->copy();
                if (!be->att1 && e->e1->type->checkAliasThisRec())
                    be->att1 = e->e1->type;
                be->e1 = e1;
                result = trySemantic(be, sc);
                return;
            }

            // Try alias this on second operand
            /* Bugzilla 2943: make sure that when we're copying the struct, we don't
             * just copy the alias this member
             */
            if (ad2 && ad2->aliasthis &&
                !(e->op == TOKassign && ad1 && ad1 == ad2))
            {
                /* Rewrite (e1 op e2) as:
                 *      (e1 op e2.aliasthis)
                 */
                if (e->att2 && e->e2->type == e->att2)
                    return;
                //printf("att bin e2 = %s\n", e->e2->type->toChars());
                Expression *e2 = new DotIdExp(e->loc, e->e2, ad2->aliasthis->ident);
                BinExp *be = (BinExp *)e->copy();
                if (!be->att2 && e->e2->type->checkAliasThisRec())
                    be->att2 = e->e2->type;
                be->e2 = e2;
                result = trySemantic(be, sc);
                return;
            }
            return;
        }

        static bool needsDirectEq(Type *t1, Type *t2, Scope *sc)
        {
            Type *t1n = t1->nextOf()->toBasetype();
            Type *t2n = t2->nextOf()->toBasetype();
            if (((t1n->ty == Tchar || t1n->ty == Twchar || t1n->ty == Tdchar) &&
                 (t2n->ty == Tchar || t2n->ty == Twchar || t2n->ty == Tdchar)) ||
                (t1n->ty == Tvoid || t2n->ty == Tvoid))
            {
                return false;
            }
            if (t1n->constOf() != t2n->constOf())
                return true;

            Type *t = t1n;
            while (t->toBasetype()->nextOf())
                t = t->nextOf()->toBasetype();
            if (t->ty != Tstruct)
                return false;

            if (global.params.useTypeInfo && Type::dtypeinfo)
                semanticTypeInfo(sc, t);

            return ((TypeStruct *)t)->sym->hasIdentityEquals;
        }

        void visit(EqualExp *e)
        {
            //printf("EqualExp::op_overload() (%s)\n", e->toChars());

            Type *t1 = e->e1->type->toBasetype();
            Type *t2 = e->e2->type->toBasetype();

            /* Check for array equality.
             */
            if ((t1->ty == Tarray || t1->ty == Tsarray) &&
                (t2->ty == Tarray || t2->ty == Tsarray))
            {
                if (needsDirectEq(t1, t2, sc))
                {
                    /* Rewrite as:
                     *      __ArrayEq(e1, e2)
                     */
                    Expression *eeq = new IdentifierExp(e->loc, Id::__ArrayEq);
                    result = new CallExp(e->loc, eeq, e->e1, e->e2);
                    if (e->op == TOKnotequal)
                        result = new NotExp(e->loc, result);
                    result = trySemantic(result, sc); // for better error message
                    if (!result)
                    {
                        e->error("cannot compare %s and %s", t1->toChars(), t2->toChars());
                        result = new ErrorExp();
                    }
                    return;
                }
            }

            /* Check for class equality with null literal or typeof(null).
             */
            if ((t1->ty == Tclass && e->e2->op == TOKnull) ||
                (t2->ty == Tclass && e->e1->op == TOKnull))
            {
                e->error("use '%s' instead of '%s' when comparing with null",
                    Token::toChars(e->op == TOKequal ? TOKidentity : TOKnotidentity),
                    Token::toChars(e->op));
                result = new ErrorExp();
                return;
            }
            if ((t1->ty == Tclass && t2->ty == Tnull) ||
                (t1->ty == Tnull && t2->ty == Tclass))
            {
                // Comparing a class with typeof(null) should not call opEquals
                return;
            }

            /* Check for class equality.
             */
            if (t1->ty == Tclass && t2->ty == Tclass)
            {
                ClassDeclaration *cd1 = t1->isClassHandle();
                ClassDeclaration *cd2 = t2->isClassHandle();

                if (!(cd1->isCPPclass() || cd2->isCPPclass()))
                {
                    /* Rewrite as:
                     *      .object.opEquals(e1, e2)
                     */
                    Expression *e1x = e->e1;
                    Expression *e2x = e->e2;

                    /* The explicit cast is necessary for interfaces,
                     * see Bugzilla 4088.
                     */
                    Type *to = ClassDeclaration::object->getType();
                    if (cd1->isInterfaceDeclaration())
                        e1x = new CastExp(e->loc, e->e1, t1->isMutable() ? to : to->constOf());
                    if (cd2->isInterfaceDeclaration())
                        e2x = new CastExp(e->loc, e->e2, t2->isMutable() ? to : to->constOf());

                    result = new IdentifierExp(e->loc, Id::empty);
                    result = new DotIdExp(e->loc, result, Id::object);
                    result = new DotIdExp(e->loc, result, Id::eq);
                    result = new CallExp(e->loc, result, e1x, e2x);
                    if (e->op == TOKnotequal)
                        result = new NotExp(e->loc, result);
                    result = semantic(result, sc);
                    return;
                }
            }

            result = compare_overload(e, sc, Id::eq);
            if (result)
            {
                if (result->op == TOKcall && e->op == TOKnotequal)
                {
                    result = new NotExp(result->loc, result);
                    result = semantic(result, sc);
                }
                return;
            }

            /* Check for pointer equality.
             */
            if (t1->ty == Tpointer || t2->ty == Tpointer)
            {
                /* Rewrite:
                 *      ptr1 == ptr2
                 * as:
                 *      ptr1 is ptr2
                 *
                 * This is just a rewriting for deterministic AST representation
                 * as the backend input.
                 */
                TOK op2 = e->op == TOKequal ? TOKidentity : TOKnotidentity;
                result = new IdentityExp(op2, e->loc, e->e1, e->e2);
                result = semantic(result, sc);
                return;
            }

            /* Check for struct equality without opEquals.
             */
            if (t1->ty == Tstruct && t2->ty == Tstruct)
            {
                StructDeclaration *sd = ((TypeStruct *)t1)->sym;
                if (sd != ((TypeStruct *)t2)->sym)
                    return;

                if (!needOpEquals(sd))
                {
                    // Use bitwise equality.
                    TOK op2 = e->op == TOKequal ? TOKidentity : TOKnotidentity;
                    result = new IdentityExp(op2, e->loc, e->e1, e->e2);
                    result = semantic(result, sc);
                    return;
                }

                /* Do memberwise equality.
                 * Rewrite:
                 *      e1 == e2
                 * as:
                 *      e1.tupleof == e2.tupleof
                 *
                 * If sd is a nested struct, and if it's nested in a class, it will
                 * also compare the parent class's equality. Otherwise, compares
                 * the identity of parent context through void*.
                 */
                if (e->att1 && t1 == e->att1)
                    return;
                if (e->att2 && t2 == e->att2)
                    return;

                e = (EqualExp *)e->copy();
                if (!e->att1)
                    e->att1 = t1;
                if (!e->att2)
                    e->att2 = t2;
                e->e1 = new DotIdExp(e->loc, e->e1, Id::_tupleof);
                e->e2 = new DotIdExp(e->loc, e->e2, Id::_tupleof);
                result = semantic(e, sc);

                /* Bugzilla 15292, if the rewrite result is same with the original,
                 * the equality is unresolvable because it has recursive definition.
                 */
                if (result->op == e->op &&
                    ((EqualExp *)result)->e1->type->toBasetype() == t1)
                {
                    e->error("cannot compare %s because its auto generated member-wise equality has recursive definition",
                        t1->toChars());
                    result = new ErrorExp();
                }
                return;
            }

            /* Check for tuple equality.
             */
            if (e->e1->op == TOKtuple && e->e2->op == TOKtuple)
            {
                TupleExp *tup1 = (TupleExp *)e->e1;
                TupleExp *tup2 = (TupleExp *)e->e2;
                size_t dim = tup1->exps->dim;
                if (dim != tup2->exps->dim)
                {
                    e->error("mismatched tuple lengths, %d and %d",
                        (int)dim, (int)tup2->exps->dim);
                    result = new ErrorExp();
                    return;
                }

                if (dim == 0)
                {
                    // zero-length tuple comparison should always return true or false.
                    result = new IntegerExp(e->loc, (e->op == TOKequal), Type::tbool);
                }
                else
                {
                    for (size_t i = 0; i < dim; i++)
                    {
                        Expression *ex1 = (*tup1->exps)[i];
                        Expression *ex2 = (*tup2->exps)[i];
                        EqualExp *eeq = new EqualExp(e->op, e->loc, ex1, ex2);
                        eeq->att1 = e->att1;
                        eeq->att2 = e->att2;

                        if (!result)
                            result = eeq;
                        else if (e->op == TOKequal)
                            result = new AndAndExp(e->loc, result, eeq);
                        else
                            result = new OrOrExp(e->loc, result, eeq);
                    }
                    assert(result);
                }
                result = Expression::combine(Expression::combine(tup1->e0, tup2->e0), result);
                result = semantic(result, sc);
                return;
            }
        }

        void visit(CmpExp *e)
        {
            //printf("CmpExp::op_overload() (%s)\n", e->toChars());

            result = compare_overload(e, sc, Id::cmp);
        }

        /*********************************
         * Operator overloading for op=
         */
        void visit(BinAssignExp *e)
        {
            //printf("BinAssignExp::op_overload() (%s)\n", e->toChars());

            if (e->e1->op == TOKarray)
            {
                ArrayExp *ae = (ArrayExp *)e->e1;
                ae->e1 = semantic(ae->e1, sc);
                ae->e1 = resolveProperties(sc, ae->e1);
                Expression *ae1old = ae->e1;

                const bool maybeSlice =
                    (ae->arguments->dim == 0 ||
                     (ae->arguments->dim == 1 && (*ae->arguments)[0]->op == TOKinterval));
                IntervalExp *ie = NULL;
                if (maybeSlice && ae->arguments->dim)
                {
                    assert((*ae->arguments)[0]->op == TOKinterval);
                    ie = (IntervalExp *)(*ae->arguments)[0];
                }

                while (true)
                {
                    if (ae->e1->op == TOKerror)
                    {
                        result = ae->e1;
                        return;
                    }
                    Expression *e0 = NULL;
                    Expression *ae1save = ae->e1;
                    ae->lengthVar = NULL;

                    Type *t1b = ae->e1->type->toBasetype();
                    AggregateDeclaration *ad = isAggregate(t1b);
                    if (!ad)
                        break;
                    if (search_function(ad, Id::opIndexOpAssign))
                    {
                        // Deal with $
                        result = resolveOpDollar(sc, ae, &e0);
                        if (!result)    // (a[i..j] op= e2) might be: a.opSliceOpAssign!(op)(e2, i, j)
                            goto Lfallback;
                        if (result->op == TOKerror)
                            return;

                        result = semantic(e->e2, sc);
                        if (result->op == TOKerror)
                            return;
                        e->e2 = result;

                        /* Rewrite a[arguments] op= e2 as:
                         *      a.opIndexOpAssign!(op)(e2, arguments)
                         */
                        Expressions *a = (Expressions *)ae->arguments->copy();
                        a->insert(0, e->e2);
                        Objects *tiargs = opToArg(sc, e->op);
                        result = new DotTemplateInstanceExp(e->loc, ae->e1, Id::opIndexOpAssign, tiargs);
                        result = new CallExp(e->loc, result, a);
                        if (maybeSlice) // (a[] op= e2) might be: a.opSliceOpAssign!(op)(e2)
                            result = trySemantic(result, sc);
                        else
                            result = semantic(result, sc);
                        if (result)
                        {
                            result = Expression::combine(e0, result);
                            return;
                        }
                    }
                Lfallback:
                    if (maybeSlice && search_function(ad, Id::opSliceOpAssign))
                    {
                        // Deal with $
                        result = resolveOpDollar(sc, ae, ie, &e0);
                        if (result->op == TOKerror)
                            return;

                        result = semantic(e->e2, sc);
                        if (result->op == TOKerror)
                            return;
                        e->e2 = result;

                        /* Rewrite (a[i..j] op= e2) as:
                         *      a.opSliceOpAssign!(op)(e2, i, j)
                         */
                        Expressions *a = new Expressions();
                        a->push(e->e2);
                        if (ie)
                        {
                            a->push(ie->lwr);
                            a->push(ie->upr);
                        }
                        Objects *tiargs = opToArg(sc, e->op);
                        result = new DotTemplateInstanceExp(e->loc, ae->e1, Id::opSliceOpAssign, tiargs);
                        result = new CallExp(e->loc, result, a);
                        result = semantic(result, sc);
                        result = Expression::combine(e0, result);
                        return;
                    }

                    // Didn't find it. Forward to aliasthis
                    if (ad->aliasthis && t1b != ae->att1)
                    {
                        if (!ae->att1 && t1b->checkAliasThisRec())
                            ae->att1 = t1b;

                        /* Rewrite (a[arguments] op= e2) as:
                         *      a.aliasthis[arguments] op= e2
                         */
                        ae->e1 = resolveAliasThis(sc, ae1save, true);
                        if (ae->e1)
                            continue;
                    }
                    break;
                }
                ae->e1 = ae1old;    // recovery
                ae->lengthVar = NULL;
            }

            result = binSemanticProp(e, sc);
            if (result)
                return;

            // Don't attempt 'alias this' if an error occured
            if (e->e1->type->ty == Terror || e->e2->type->ty == Terror)
            {
                result = new ErrorExp();
                return;
            }

            Identifier *id = opId(e);

            Expressions args2;

            AggregateDeclaration *ad1 = isAggregate(e->e1->type);

            Dsymbol *s = NULL;

        #if 1 // the old D1 scheme
            if (ad1 && id)
            {
                s = search_function(ad1, id);
            }
        #endif

            Objects *tiargs = NULL;
            if (!s)
            {
                /* Try the new D2 scheme, opOpAssign
                 */
                if (ad1)
                {
                    s = search_function(ad1, Id::opOpAssign);
                    if (s && !s->isTemplateDeclaration())
                    {
                        e->error("%s.opOpAssign isn't a template", e->e1->toChars());
                        result = new ErrorExp();
                        return;
                    }
                }

                // Set tiargs, the template argument list, which will be the operator string
                if (s)
                {
                    id = Id::opOpAssign;
                    tiargs = opToArg(sc, e->op);
                }
            }

            if (s)
            {
                /* Try:
                 *      a.opOpAssign(b)
                 */

                args2.setDim(1);
                args2[0] = e->e2;
                expandTuples(&args2);

                Match m;
                memset(&m, 0, sizeof(m));
                m.last = MATCHnomatch;

                if (s)
                {
                    functionResolve(&m, s, e->loc, sc, tiargs, e->e1->type, &args2);
                    if (m.lastf && (m.lastf->errors || m.lastf->semantic3Errors))
                    {
                        result = new ErrorExp();
                        return;
                    }
                }

                if (m.count > 1)
                {
                    // Error, ambiguous
                    e->error("overloads %s and %s both match argument list for %s",
                            m.lastf->type->toChars(),
                            m.nextf->type->toChars(),
                            m.lastf->toChars());
                }
                else if (m.last <= MATCHnomatch)
                {
                    m.lastf = m.anyf;
                    if (tiargs)
                        goto L1;
                }

                // Rewrite (e1 op e2) as e1.opOpAssign(e2)
                result = build_overload(e->loc, sc, e->e1, e->e2, m.lastf ? m.lastf : s);
                return;
            }

        L1:

            // Try alias this on first operand
            if (ad1 && ad1->aliasthis)
            {
                /* Rewrite (e1 op e2) as:
                 *      (e1.aliasthis op e2)
                 */
                if (e->att1 && e->e1->type == e->att1)
                    return;
                //printf("att %s e1 = %s\n", Token::toChars(e->op), e->e1->type->toChars());
                Expression *e1 = new DotIdExp(e->loc, e->e1, ad1->aliasthis->ident);
                BinExp *be = (BinExp *)e->copy();
                if (!be->att1 && e->e1->type->checkAliasThisRec())
                    be->att1 = e->e1->type;
                be->e1 = e1;
                result = trySemantic(be, sc);
                return;
            }

            // Try alias this on second operand
            AggregateDeclaration *ad2 = isAggregate(e->e2->type);
            if (ad2 && ad2->aliasthis)
            {
                /* Rewrite (e1 op e2) as:
                 *      (e1 op e2.aliasthis)
                 */
                if (e->att2 && e->e2->type == e->att2)
                    return;
                //printf("att %s e2 = %s\n", Token::toChars(e->op), e->e2->type->toChars());
                Expression *e2 = new DotIdExp(e->loc, e->e2, ad2->aliasthis->ident);
                BinExp *be = (BinExp *)e->copy();
                if (!be->att2 && e->e2->type->checkAliasThisRec())
                    be->att2 = e->e2->type;
                be->e2 = e2;
                result = trySemantic(be, sc);
                return;
            }
        }
    };

    OpOverload v(sc);
    e->accept(&v);
    return v.result;
}

/******************************************
 * Common code for overloading of EqualExp and CmpExp
 */
Expression *compare_overload(BinExp *e, Scope *sc, Identifier *id)
{
    //printf("BinExp::compare_overload(id = %s) %s\n", id->toChars(), e->toChars());

    AggregateDeclaration *ad1 = isAggregate(e->e1->type);
    AggregateDeclaration *ad2 = isAggregate(e->e2->type);

    Dsymbol *s = NULL;
    Dsymbol *s_r = NULL;

    if (ad1)
    {
        s = search_function(ad1, id);
    }
    if (ad2)
    {
        s_r = search_function(ad2, id);
        if (s == s_r)
            s_r = NULL;
    }

    Objects *tiargs = NULL;

    if (s || s_r)
    {
        /* Try:
         *      a.opEquals(b)
         *      b.opEquals(a)
         * and see which is better.
         */

        Expressions args1;
        Expressions args2;

        args1.setDim(1);
        args1[0] = e->e1;
        expandTuples(&args1);
        args2.setDim(1);
        args2[0] = e->e2;
        expandTuples(&args2);

        Match m;
        memset(&m, 0, sizeof(m));
        m.last = MATCHnomatch;

        if (0 && s && s_r)
        {
            printf("s  : %s\n", s->toPrettyChars());
            printf("s_r: %s\n", s_r->toPrettyChars());
        }

        if (s)
        {
            functionResolve(&m, s, e->loc, sc, tiargs, e->e1->type, &args2);
            if (m.lastf && (m.lastf->errors || m.lastf->semantic3Errors))
                return new ErrorExp();
        }

        FuncDeclaration *lastf = m.lastf;
        int count = m.count;

        if (s_r)
        {
            functionResolve(&m, s_r, e->loc, sc, tiargs, e->e2->type, &args1);
            if (m.lastf && (m.lastf->errors || m.lastf->semantic3Errors))
                return new ErrorExp();
        }

        if (m.count > 1)
        {
            /* The following if says "not ambiguous" if there's one match
             * from s and one from s_r, in which case we pick s.
             * This doesn't follow the spec, but is a workaround for the case
             * where opEquals was generated from templates and we cannot figure
             * out if both s and s_r came from the same declaration or not.
             * The test case is:
             *   import std.typecons;
             *   void main() {
             *    assert(tuple("has a", 2u) == tuple("has a", 1));
             *   }
             */
            if (!(m.lastf == lastf && m.count == 2 && count == 1))
            {
                // Error, ambiguous
                e->error("overloads %s and %s both match argument list for %s",
                    m.lastf->type->toChars(),
                    m.nextf->type->toChars(),
                    m.lastf->toChars());
            }
        }
        else if (m.last <= MATCHnomatch)
        {
            m.lastf = m.anyf;
        }

        Expression *result;
        if ((lastf && m.lastf == lastf) || (!s_r && m.last <= MATCHnomatch))
        {
            // Rewrite (e1 op e2) as e1.opfunc(e2)
            result = build_overload(e->loc, sc, e->e1, e->e2, m.lastf ? m.lastf : s);
        }
        else
        {
            // Rewrite (e1 op e2) as e2.opfunc_r(e1)
            result = build_overload(e->loc, sc, e->e2, e->e1, m.lastf ? m.lastf : s_r);

            // When reversing operands of comparison operators,
            // need to reverse the sense of the op
            switch (e->op)
            {
                case TOKlt:     e->op = TOKgt;     break;
                case TOKgt:     e->op = TOKlt;     break;
                case TOKle:     e->op = TOKge;     break;
                case TOKge:     e->op = TOKle;     break;

                // The rest are symmetric
                default:
                    break;
            }
        }

        return result;
    }

    // Try alias this on first operand
    if (ad1 && ad1->aliasthis)
    {
        /* Rewrite (e1 op e2) as:
         *      (e1.aliasthis op e2)
         */
        if (e->att1 && e->e1->type == e->att1)
            return NULL;
        //printf("att cmp_bin e1 = %s\n", e->e1->type->toChars());
        Expression *e1 = new DotIdExp(e->loc, e->e1, ad1->aliasthis->ident);
        BinExp *be = (BinExp *)e->copy();
        if (!be->att1 && e->e1->type->checkAliasThisRec())
            be->att1 = e->e1->type;
        be->e1 = e1;
        return trySemantic(be, sc);
    }

    // Try alias this on second operand
    if (ad2 && ad2->aliasthis)
    {
        /* Rewrite (e1 op e2) as:
         *      (e1 op e2.aliasthis)
         */
        if (e->att2 && e->e2->type == e->att2)
            return NULL;
        //printf("att cmp_bin e2 = %s\n", e->e2->type->toChars());
        Expression *e2 = new DotIdExp(e->loc, e->e2, ad2->aliasthis->ident);
        BinExp *be = (BinExp *)e->copy();
        if (!be->att2 && e->e2->type->checkAliasThisRec())
            be->att2 = e->e2->type;
        be->e2 = e2;
        return trySemantic(be, sc);
    }

    return NULL;
}

/***********************************
 * Utility to build a function call out of this reference and argument.
 */

Expression *build_overload(Loc loc, Scope *sc, Expression *ethis, Expression *earg,
        Dsymbol *d)
{
    assert(d);
    Expression *e;

    //printf("build_overload(id = '%s')\n", id->toChars());
    //earg->print();
    //earg->type->print();
    Declaration *decl = d->isDeclaration();
    if (decl)
        e = new DotVarExp(loc, ethis, decl, false);
    else
        e = new DotIdExp(loc, ethis, d->ident);
    e = new CallExp(loc, e, earg);

    e = semantic(e, sc);
    return e;
}

/***************************************
 * Search for function funcid in aggregate ad.
 */

Dsymbol *search_function(ScopeDsymbol *ad, Identifier *funcid)
{
    Dsymbol *s = ad->search(Loc(), funcid);
    if (s)
    {
        //printf("search_function: s = '%s'\n", s->kind());
        Dsymbol *s2 = s->toAlias();
        //printf("search_function: s2 = '%s'\n", s2->kind());
        FuncDeclaration *fd = s2->isFuncDeclaration();
        if (fd && fd->type->ty == Tfunction)
            return fd;

        TemplateDeclaration *td = s2->isTemplateDeclaration();
        if (td)
            return td;
    }
    return NULL;
}


bool inferAggregate(ForeachStatement *fes, Scope *sc, Dsymbol *&sapply)
{
    //printf("inferAggregate(%s)\n", fes->aggr->toChars());
    Identifier *idapply = (fes->op == TOKforeach) ? Id::apply : Id::applyReverse;
    Identifier *idfront = (fes->op == TOKforeach) ? Id::Ffront : Id::Fback;
    int sliced = 0;
    Type *tab;
    Type *att = NULL;
    Expression *aggr = fes->aggr;
    AggregateDeclaration *ad;

    while (1)
    {
        aggr = semantic(aggr, sc);
        aggr = resolveProperties(sc, aggr);
        aggr = aggr->optimize(WANTvalue);
        if (!aggr->type || aggr->op == TOKerror)
            goto Lerr;

        tab = aggr->type->toBasetype();
        switch (tab->ty)
        {
            case Tarray:
            case Tsarray:
            case Ttuple:
            case Taarray:
                break;

            case Tclass:
                ad = ((TypeClass *)tab)->sym;
                goto Laggr;

            case Tstruct:
                ad = ((TypeStruct *)tab)->sym;
                goto Laggr;

            Laggr:
                if (!sliced)
                {
                    sapply = search_function(ad, idapply);
                    if (sapply)
                    {
                        // opApply aggregate
                        break;
                    }

                    if (fes->aggr->op != TOKtype)
                    {
                        Expression *rinit = new ArrayExp(fes->aggr->loc, fes->aggr);
                        rinit = trySemantic(rinit, sc);
                        if (rinit)                  // if application of [] succeeded
                        {
                            aggr = rinit;
                            sliced = 1;
                            continue;
                        }
                    }
                }

                if (ad->search(Loc(), idfront))
                {
                    // range aggregate
                    break;
                }

                if (ad->aliasthis)
                {
                    if (att == tab)
                        goto Lerr;
                    if (!att && tab->checkAliasThisRec())
                        att = tab;
                    aggr = resolveAliasThis(sc, aggr);
                    continue;
                }
                goto Lerr;

            case Tdelegate:
                if (aggr->op == TOKdelegate)
                {
                    sapply = ((DelegateExp *)aggr)->func;
                }
                break;

            case Terror:
                break;

            default:
                goto Lerr;
        }
        break;
    }
    fes->aggr = aggr;
    return true;

Lerr:
    return false;
}

/*****************************************
 * Given array of parameters and an aggregate type,
 * if any of the parameter types are missing, attempt to infer
 * them from the aggregate type.
 */

bool inferApplyArgTypes(ForeachStatement *fes, Scope *sc, Dsymbol *&sapply)
{
    if (!fes->parameters || !fes->parameters->dim)
        return false;

    if (sapply)     // prefer opApply
    {
        for (size_t u = 0; u < fes->parameters->dim; u++)
        {
            Parameter *p = (*fes->parameters)[u];
            if (p->type)
            {
                p->type = p->type->semantic(fes->loc, sc);
                p->type = p->type->addStorageClass(p->storageClass);
            }
        }

        Expression *ethis;
        Type *tab = fes->aggr->type->toBasetype();
        if (tab->ty == Tclass || tab->ty == Tstruct)
            ethis = fes->aggr;
        else
        {   assert(tab->ty == Tdelegate && fes->aggr->op == TOKdelegate);
            ethis = ((DelegateExp *)fes->aggr)->e1;
        }

        /* Look for like an
         *  int opApply(int delegate(ref Type [, ...]) dg);
         * overload
         */
        FuncDeclaration *fd = sapply->isFuncDeclaration();
        if (fd)
        {
            sapply = inferApplyArgTypesX(ethis, fd, fes->parameters);
        }
        return sapply != NULL;
    }

    /* Return if no parameters need types.
     */
    for (size_t u = 0; u < fes->parameters->dim; u++)
    {
        Parameter *p = (*fes->parameters)[u];
        if (!p->type)
            break;
    }

    AggregateDeclaration *ad;

    Parameter *p = (*fes->parameters)[0];
    Type *taggr = fes->aggr->type;
    assert(taggr);
    Type *tab = taggr->toBasetype();
    switch (tab->ty)
    {
        case Tarray:
        case Tsarray:
        case Ttuple:
            if (fes->parameters->dim == 2)
            {
                if (!p->type)
                {
                    p->type = Type::tsize_t;    // key type
                    p->type = p->type->addStorageClass(p->storageClass);
                }
                p = (*fes->parameters)[1];
            }
            if (!p->type && tab->ty != Ttuple)
            {
                p->type = tab->nextOf();        // value type
                p->type = p->type->addStorageClass(p->storageClass);
            }
            break;

        case Taarray:
        {
            TypeAArray *taa = (TypeAArray *)tab;

            if (fes->parameters->dim == 2)
            {
                if (!p->type)
                {
                    p->type = taa->index;       // key type
                    p->type = p->type->addStorageClass(p->storageClass);
                    if (p->storageClass & STCref) // key must not be mutated via ref
                        p->type = p->type->addMod(MODconst);
                }
                p = (*fes->parameters)[1];
            }
            if (!p->type)
            {
                p->type = taa->next;            // value type
                p->type = p->type->addStorageClass(p->storageClass);
            }
            break;
        }

        case Tclass:
            ad = ((TypeClass *)tab)->sym;
            goto Laggr;

        case Tstruct:
            ad = ((TypeStruct *)tab)->sym;
            goto Laggr;

        Laggr:
            if (fes->parameters->dim == 1)
            {
                if (!p->type)
                {
                    /* Look for a front() or back() overload
                     */
                    Identifier *id = (fes->op == TOKforeach) ? Id::Ffront : Id::Fback;
                    Dsymbol *s = ad->search(Loc(), id);
                    FuncDeclaration *fd = s ? s->isFuncDeclaration() : NULL;
                    if (fd)
                    {
                        // Resolve inout qualifier of front type
                        p->type = fd->type->nextOf();
                        if (p->type)
                        {
                            p->type = p->type->substWildTo(tab->mod);
                            p->type = p->type->addStorageClass(p->storageClass);
                        }
                    }
                    else if (s && s->isTemplateDeclaration())
                        ;
                    else if (s && s->isDeclaration())
                        p->type = ((Declaration *)s)->type;
                    else
                        break;
                }
                break;
            }
            break;

        case Tdelegate:
        {
            if (!inferApplyArgTypesY((TypeFunction *)tab->nextOf(), fes->parameters))
                return false;
            break;
        }

        default:
            break;              // ignore error, caught later
    }
    return true;
}

static Dsymbol *inferApplyArgTypesX(Expression *ethis, FuncDeclaration *fstart, Parameters *parameters)
{
  struct ParamOpOver
  {
    Parameters *parameters;
    MOD mod;
    MATCH match;
    FuncDeclaration *fd_best;
    FuncDeclaration *fd_ambig;

    static int fp(void *param, Dsymbol *s)
    {
        FuncDeclaration *f = s->isFuncDeclaration();
        if (!f)
            return 0;
        ParamOpOver *p = (ParamOpOver *)param;
        TypeFunction *tf = (TypeFunction *)f->type;
        MATCH m = MATCHexact;

        if (f->isThis())
        {
            if (!MODimplicitConv(p->mod, tf->mod))
                m = MATCHnomatch;
            else if (p->mod != tf->mod)
                m = MATCHconst;
        }
        if (!inferApplyArgTypesY(tf, p->parameters, 1))
            m = MATCHnomatch;

        if (m > p->match)
        {
            p->fd_best = f;
            p->fd_ambig = NULL;
            p->match = m;
        }
        else if (m == p->match)
            p->fd_ambig = f;
        return 0;
    }
  };
    ParamOpOver p;
    p.parameters = parameters;
    p.mod = ethis->type->mod;
    p.match = MATCHnomatch;
    p.fd_best = NULL;
    p.fd_ambig = NULL;
    overloadApply(fstart, &p, &ParamOpOver::fp);
    if (p.fd_best)
    {
        inferApplyArgTypesY((TypeFunction *)p.fd_best->type, parameters);
        if (p.fd_ambig)
        {   ::error(ethis->loc, "%s.%s matches more than one declaration:\n%s:     %s\nand:\n%s:     %s",
                    ethis->toChars(), fstart->ident->toChars(),
                    p.fd_best ->loc.toChars(), p.fd_best ->type->toChars(),
                    p.fd_ambig->loc.toChars(), p.fd_ambig->type->toChars());
            p.fd_best = NULL;
        }
    }
    return p.fd_best;
}

/******************************
 * Infer parameters from type of function.
 * Returns:
 *      1 match for this function
 *      0 no match for this function
 */

static int inferApplyArgTypesY(TypeFunction *tf, Parameters *parameters, int flags)
{   size_t nparams;
    Parameter *p;

    if (Parameter::dim(tf->parameters) != 1)
        goto Lnomatch;
    p = Parameter::getNth(tf->parameters, 0);
    if (p->type->ty != Tdelegate)
        goto Lnomatch;
    tf = (TypeFunction *)p->type->nextOf();
    assert(tf->ty == Tfunction);

    /* We now have tf, the type of the delegate. Match it against
     * the parameters, filling in missing parameter types.
     */
    nparams = Parameter::dim(tf->parameters);
    if (nparams == 0 || tf->varargs)
        goto Lnomatch;          // not enough parameters
    if (parameters->dim != nparams)
        goto Lnomatch;          // not enough parameters

    for (size_t u = 0; u < nparams; u++)
    {
        p = (*parameters)[u];
        Parameter *param = Parameter::getNth(tf->parameters, u);
        if (p->type)
        {
            if (!p->type->equals(param->type))
                goto Lnomatch;
        }
        else if (!flags)
        {
            p->type = param->type;
            p->type = p->type->addStorageClass(p->storageClass);
        }
    }
    return 1;

Lnomatch:
    return 0;
}

