
/* 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/expression.c
 */

#include "root/dsystem.h"
#include "root/rmem.h"
#include "root/root.h"

#include "errors.h"
#include "mtype.h"
#include "init.h"
#include "expression.h"
#include "template.h"
#include "utf.h"
#include "enum.h"
#include "scope.h"
#include "statement.h"
#include "declaration.h"
#include "aggregate.h"
#include "import.h"
#include "id.h"
#include "dsymbol.h"
#include "module.h"
#include "attrib.h"
#include "hdrgen.h"
#include "parse.h"
#include "doc.h"
#include "root/aav.h"
#include "nspace.h"
#include "ctfe.h"
#include "target.h"

bool walkPostorder(Expression *e, StoppableVisitor *v);
bool checkParamArgumentEscape(Scope *sc, FuncDeclaration *fdc, Identifier *par, Expression *arg, bool gag);
bool checkAccess(AggregateDeclaration *ad, Loc loc, Scope *sc, Dsymbol *smember);
VarDeclaration *copyToTemp(StorageClass stc, const char *name, Expression *e);
Expression *extractSideEffect(Scope *sc, const char *name, Expression **e0, Expression *e, bool alwaysCopy = false);
char *MODtoChars(MOD mod);
bool MODimplicitConv(MOD modfrom, MOD modto);
MOD MODmerge(MOD mod1, MOD mod2);
void MODMatchToBuffer(OutBuffer *buf, unsigned char lhsMod, unsigned char rhsMod);
Expression *trySemantic(Expression *e, Scope *sc);
Expression *semantic(Expression *e, Scope *sc);
Expression *semanticX(DotIdExp *exp, Scope *sc);
Expression *semanticY(DotIdExp *exp, Scope *sc, int flag);
Expression *semanticY(DotTemplateInstanceExp *exp, Scope *sc, int flag);
Expression *resolve(Loc loc, Scope *sc, Dsymbol *s, bool hasOverloads);
bool checkUnsafeAccess(Scope *sc, Expression *e, bool readonly, bool printmsg);

/*************************************************************
 * Given var, we need to get the
 * right 'this' pointer if var is in an outer class, but our
 * existing 'this' pointer is in an inner class.
 * Input:
 *      e1      existing 'this'
 *      ad      struct or class we need the correct 'this' for
 *      var     the specific member of ad we're accessing
 */

Expression *getRightThis(Loc loc, Scope *sc, AggregateDeclaration *ad,
        Expression *e1, Declaration *var, int flag = 0)
{
    //printf("\ngetRightThis(e1 = %s, ad = %s, var = %s)\n", e1->toChars(), ad->toChars(), var->toChars());
 L1:
    Type *t = e1->type->toBasetype();
    //printf("e1->type = %s, var->type = %s\n", e1->type->toChars(), var->type->toChars());

    /* If e1 is not the 'this' pointer for ad
     */
    if (ad &&
        !(t->ty == Tpointer && t->nextOf()->ty == Tstruct &&
          ((TypeStruct *)t->nextOf())->sym == ad)
        &&
        !(t->ty == Tstruct &&
          ((TypeStruct *)t)->sym == ad)
       )
    {
        ClassDeclaration *cd = ad->isClassDeclaration();
        ClassDeclaration *tcd = t->isClassHandle();

        /* e1 is the right this if ad is a base class of e1
         */
        if (!cd || !tcd ||
            !(tcd == cd || cd->isBaseOf(tcd, NULL))
           )
        {
            /* Only classes can be inner classes with an 'outer'
             * member pointing to the enclosing class instance
             */
            if (tcd && tcd->isNested())
            {
                /* e1 is the 'this' pointer for an inner class: tcd.
                 * Rewrite it as the 'this' pointer for the outer class.
                 */

                e1 = new DotVarExp(loc, e1, tcd->vthis);
                e1->type = tcd->vthis->type;
                e1->type = e1->type->addMod(t->mod);
                // Do not call checkNestedRef()
                //e1 = semantic(e1, sc);

                // Skip up over nested functions, and get the enclosing
                // class type.
                int n = 0;
                Dsymbol *s;
                for (s = tcd->toParent();
                     s && s->isFuncDeclaration();
                     s = s->toParent())
                {
                    FuncDeclaration *f = s->isFuncDeclaration();
                    if (f->vthis)
                    {
                        //printf("rewriting e1 to %s's this\n", f->toChars());
                        n++;
                        e1 = new VarExp(loc, f->vthis);
                    }
                    else
                    {
                        e1->error("need 'this' of type %s to access member %s"
                                  " from static function %s",
                            ad->toChars(), var->toChars(), f->toChars());
                        e1 = new ErrorExp();
                        return e1;
                    }
                }
                if (s && s->isClassDeclaration())
                {
                    e1->type = s->isClassDeclaration()->type;
                    e1->type = e1->type->addMod(t->mod);
                    if (n > 1)
                        e1 = semantic(e1, sc);
                }
                else
                    e1 = semantic(e1, sc);
                goto L1;
            }

            /* Can't find a path from e1 to ad
             */
            if (flag)
                return NULL;
            e1->error("this for %s needs to be type %s not type %s",
                var->toChars(), ad->toChars(), t->toChars());
            return new ErrorExp();
        }
    }
    return e1;
}

/*****************************************
 * Determine if 'this' is available.
 * If it is, return the FuncDeclaration that has it.
 */

FuncDeclaration *hasThis(Scope *sc)
{
    //printf("hasThis()\n");
    Dsymbol *p = sc->parent;
    while (p && p->isTemplateMixin())
        p = p->parent;
    FuncDeclaration *fdthis = p ? p->isFuncDeclaration() : NULL;
    //printf("fdthis = %p, '%s'\n", fdthis, fdthis ? fdthis->toChars() : "");

    // Go upwards until we find the enclosing member function
    FuncDeclaration *fd = fdthis;
    while (1)
    {
        if (!fd)
        {
            goto Lno;
        }
        if (!fd->isNested())
            break;

        Dsymbol *parent = fd->parent;
        while (1)
        {
            if (!parent)
                goto Lno;
            TemplateInstance *ti = parent->isTemplateInstance();
            if (ti)
                parent = ti->parent;
            else
                break;
        }
        fd = parent->isFuncDeclaration();
    }

    if (!fd->isThis())
    {   //printf("test '%s'\n", fd->toChars());
        goto Lno;
    }

    assert(fd->vthis);
    return fd;

Lno:
    return NULL;                // don't have 'this' available
}

bool isNeedThisScope(Scope *sc, Declaration *d)
{
    if (sc->intypeof == 1)
        return false;

    AggregateDeclaration *ad = d->isThis();
    if (!ad)
        return false;
    //printf("d = %s, ad = %s\n", d->toChars(), ad->toChars());

    for (Dsymbol *s = sc->parent; s; s = s->toParent2())
    {
        //printf("\ts = %s %s, toParent2() = %p\n", s->kind(), s->toChars(), s->toParent2());
        if (AggregateDeclaration *ad2 = s->isAggregateDeclaration())
        {
            if (ad2 == ad)
                return false;
            else if (ad2->isNested())
                continue;
            else
                return true;
        }
        if (FuncDeclaration *f = s->isFuncDeclaration())
        {
            if (f->isMember2())
                break;
        }
    }
    return true;
}

/***************************************
 * Pull out any properties.
 */

Expression *resolvePropertiesX(Scope *sc, Expression *e1, Expression *e2 = NULL)
{
    //printf("resolvePropertiesX, e1 = %s %s, e2 = %s\n", Token::toChars(e1->op), e1->toChars(), e2 ? e2->toChars() : NULL);
    Loc loc = e1->loc;

    OverloadSet *os;
    Dsymbol *s;
    Objects *tiargs;
    Type *tthis;
    if (e1->op == TOKdot)
    {
        DotExp *de = (DotExp *)e1;
        if (de->e2->op == TOKoverloadset)
        {
            tiargs = NULL;
            tthis  = de->e1->type;
            os = ((OverExp *)de->e2)->vars;
            goto Los;
        }
    }
    else if (e1->op == TOKoverloadset)
    {
        tiargs = NULL;
        tthis  = NULL;
        os = ((OverExp *)e1)->vars;
    Los:
        assert(os);
        FuncDeclaration *fd = NULL;
        if (e2)
        {
            e2 = semantic(e2, sc);
            if (e2->op == TOKerror)
                return new ErrorExp();
            e2 = resolveProperties(sc, e2);

            Expressions a;
            a.push(e2);

            for (size_t i = 0; i < os->a.dim; i++)
            {
                FuncDeclaration *f = resolveFuncCall(loc, sc, os->a[i], tiargs, tthis, &a, 1);
                if (f)
                {
                    if (f->errors)
                        return new ErrorExp();
                    fd = f;
                    assert(fd->type->ty == Tfunction);
                }
            }
            if (fd)
            {
                Expression *e = new CallExp(loc, e1, e2);
                return semantic(e, sc);
            }
        }
        {
            for (size_t i = 0; i < os->a.dim; i++)
            {
                FuncDeclaration *f = resolveFuncCall(loc, sc, os->a[i], tiargs, tthis, NULL, 1);
                if (f)
                {
                    if (f->errors)
                        return new ErrorExp();
                    fd = f;
                    assert(fd->type->ty == Tfunction);
                    TypeFunction *tf = (TypeFunction *)fd->type;
                    if (!tf->isref && e2)
                        goto Leproplvalue;
                }
            }
            if (fd)
            {
                Expression *e = new CallExp(loc, e1);
                if (e2)
                    e = new AssignExp(loc, e, e2);
                return semantic(e, sc);
            }
        }
        if (e2)
            goto Leprop;
    }
    else if (e1->op == TOKdotti)
    {
        DotTemplateInstanceExp* dti = (DotTemplateInstanceExp *)e1;
        if (!dti->findTempDecl(sc))
            goto Leprop;
        if (!dti->ti->semanticTiargs(sc))
            goto Leprop;
        tiargs = dti->ti->tiargs;
        tthis  = dti->e1->type;
        if ((os = dti->ti->tempdecl->isOverloadSet()) != NULL)
            goto Los;
        if ((s = dti->ti->tempdecl) != NULL)
            goto Lfd;
    }
    else if (e1->op == TOKdottd)
    {
        DotTemplateExp *dte = (DotTemplateExp *)e1;
        s      = dte->td;
        tiargs = NULL;
        tthis  = dte->e1->type;
        goto Lfd;
    }
    else if (e1->op == TOKscope)
    {
        s = ((ScopeExp *)e1)->sds;
        TemplateInstance *ti = s->isTemplateInstance();
        if (ti && !ti->semanticRun && ti->tempdecl)
        {
            //assert(ti->needsTypeInference(sc));
            if (!ti->semanticTiargs(sc))
                goto Leprop;
            tiargs = ti->tiargs;
            tthis  = NULL;
            if ((os = ti->tempdecl->isOverloadSet()) != NULL)
                goto Los;
            if ((s = ti->tempdecl) != NULL)
                goto Lfd;
        }
    }
    else if (e1->op == TOKtemplate)
    {
        s      = ((TemplateExp *)e1)->td;
        tiargs = NULL;
        tthis  = NULL;
        goto Lfd;
    }
    else if (e1->op == TOKdotvar && e1->type && e1->type->toBasetype()->ty == Tfunction)
    {
        DotVarExp *dve = (DotVarExp *)e1;
        s      = dve->var->isFuncDeclaration();
        tiargs = NULL;
        tthis  = dve->e1->type;
        goto Lfd;
    }
    else if (e1->op == TOKvar && e1->type && e1->type->toBasetype()->ty == Tfunction)
    {
        s      = ((VarExp *)e1)->var->isFuncDeclaration();
        tiargs = NULL;
        tthis  = NULL;
    Lfd:
        assert(s);
        if (e2)
        {
            e2 = semantic(e2, sc);
            if (e2->op == TOKerror)
                return new ErrorExp();
            e2 = resolveProperties(sc, e2);

            Expressions a;
            a.push(e2);

            FuncDeclaration *fd = resolveFuncCall(loc, sc, s, tiargs, tthis, &a, 1);
            if (fd && fd->type)
            {
                if (fd->errors)
                    return new ErrorExp();
                assert(fd->type->ty == Tfunction);
                Expression *e = new CallExp(loc, e1, e2);
                return semantic(e, sc);
            }
        }
        {
            FuncDeclaration *fd = resolveFuncCall(loc, sc, s, tiargs, tthis, NULL, 1);
            if (fd && fd->type)
            {
                if (fd->errors)
                    return new ErrorExp();
                assert(fd->type->ty == Tfunction);
                TypeFunction *tf = (TypeFunction *)fd->type;
                if (!e2 || tf->isref)
                {
                    Expression *e = new CallExp(loc, e1);
                    if (e2)
                        e = new AssignExp(loc, e, e2);
                    return semantic(e, sc);
                }
            }
        }
        if (FuncDeclaration *fd = s->isFuncDeclaration())
        {
            // Keep better diagnostic message for invalid property usage of functions
            assert(fd->type->ty == Tfunction);
            Expression *e = new CallExp(loc, e1, e2);
            return semantic(e, sc);
        }
        if (e2)
            goto Leprop;
    }
    if (e1->op == TOKvar)
    {
        VarExp *ve = (VarExp *)e1;
        VarDeclaration *v = ve->var->isVarDeclaration();
        if (v && ve->checkPurity(sc, v))
            return new ErrorExp();
    }
    if (e2)
        return NULL;

    if (e1->type &&
        e1->op != TOKtype)      // function type is not a property
    {
        /* Look for e1 being a lazy parameter; rewrite as delegate call
         */
        if (e1->op == TOKvar)
        {
            VarExp *ve = (VarExp *)e1;

            if (ve->var->storage_class & STClazy)
            {
                Expression *e = new CallExp(loc, e1);
                return semantic(e, sc);
            }
        }
        else if (e1->op == TOKdotvar)
        {
            // Check for reading overlapped pointer field in @safe code.
            if (checkUnsafeAccess(sc, e1, true, true))
                return new ErrorExp();
        }
        else if (e1->op == TOKdot)
        {
            e1->error("expression has no value");
            return new ErrorExp();
        }
        else if (e1->op == TOKcall)
        {
            CallExp *ce = (CallExp *)e1;
            // Check for reading overlapped pointer field in @safe code.
            if (checkUnsafeAccess(sc, ce->e1, true, true))
                return new ErrorExp();
        }
    }

    if (!e1->type)
    {
        error(loc, "cannot resolve type for %s", e1->toChars());
        e1 = new ErrorExp();
    }
    return e1;

Leprop:
    error(loc, "not a property %s", e1->toChars());
    return new ErrorExp();

Leproplvalue:
    error(loc, "%s is not an lvalue", e1->toChars());
    return new ErrorExp();
}

Expression *resolveProperties(Scope *sc, Expression *e)
{
    //printf("resolveProperties(%s)\n", e->toChars());

    e = resolvePropertiesX(sc, e);
    if (e->checkRightThis(sc))
        return new ErrorExp();
    return e;
}

/******************************
 * Check the tail CallExp is really property function call.
 */
static bool checkPropertyCall(Expression *e)
{
    while (e->op == TOKcomma)
        e = ((CommaExp *)e)->e2;

    if (e->op == TOKcall)
    {
        CallExp *ce = (CallExp *)e;
        TypeFunction *tf;
        if (ce->f)
        {
            tf = (TypeFunction *)ce->f->type;
            /* If a forward reference to ce->f, try to resolve it
             */
            if (!tf->deco && ce->f->_scope)
            {
                ce->f->semantic(ce->f->_scope);
                tf = (TypeFunction *)ce->f->type;
            }
        }
        else if (ce->e1->type->ty == Tfunction)
            tf = (TypeFunction *)ce->e1->type;
        else if (ce->e1->type->ty == Tdelegate)
            tf = (TypeFunction *)ce->e1->type->nextOf();
        else if (ce->e1->type->ty == Tpointer && ce->e1->type->nextOf()->ty == Tfunction)
            tf = (TypeFunction *)ce->e1->type->nextOf();
        else
            assert(0);
    }
    return false;
}

/******************************
 * If e1 is a property function (template), resolve it.
 */

Expression *resolvePropertiesOnly(Scope *sc, Expression *e1)
{
    //printf("e1 = %s %s\n", Token::toChars(e1->op), e1->toChars());
    OverloadSet *os;
    FuncDeclaration *fd;
    TemplateDeclaration *td;

    if (e1->op == TOKdot)
    {
        DotExp *de = (DotExp *)e1;
        if (de->e2->op == TOKoverloadset)
        {
            os = ((OverExp *)de->e2)->vars;
            goto Los;
        }
    }
    else if (e1->op == TOKoverloadset)
    {
        os = ((OverExp *)e1)->vars;
    Los:
        assert(os);
        for (size_t i = 0; i < os->a.dim; i++)
        {
            Dsymbol *s = os->a[i];
            fd = s->isFuncDeclaration();
            td = s->isTemplateDeclaration();
            if (fd)
            {
                if (((TypeFunction *)fd->type)->isproperty)
                    return resolveProperties(sc, e1);
            }
            else if (td && td->onemember &&
                     (fd = td->onemember->isFuncDeclaration()) != NULL)
            {
                if (((TypeFunction *)fd->type)->isproperty ||
                    (fd->storage_class2 & STCproperty) ||
                    (td->_scope->stc & STCproperty))
                {
                    return resolveProperties(sc, e1);
                }
            }
        }
    }
    else if (e1->op == TOKdotti)
    {
        DotTemplateInstanceExp* dti = (DotTemplateInstanceExp *)e1;
        if (dti->ti->tempdecl && (td = dti->ti->tempdecl->isTemplateDeclaration()) != NULL)
            goto Ltd;
    }
    else if (e1->op == TOKdottd)
    {
        td = ((DotTemplateExp *)e1)->td;
        goto Ltd;
    }
    else if (e1->op == TOKscope)
    {
        Dsymbol *s = ((ScopeExp *)e1)->sds;
        TemplateInstance *ti = s->isTemplateInstance();
        if (ti && !ti->semanticRun && ti->tempdecl)
        {
            if ((td = ti->tempdecl->isTemplateDeclaration()) != NULL)
                goto Ltd;
        }
    }
    else if (e1->op == TOKtemplate)
    {
        td = ((TemplateExp *)e1)->td;
    Ltd:
        assert(td);
        if (td->onemember &&
            (fd = td->onemember->isFuncDeclaration()) != NULL)
        {
            if (((TypeFunction *)fd->type)->isproperty ||
                (fd->storage_class2 & STCproperty) ||
                (td->_scope->stc & STCproperty))
            {
                return resolveProperties(sc, e1);
            }
        }
    }
    else if (e1->op == TOKdotvar && e1->type->ty == Tfunction)
    {
        DotVarExp *dve = (DotVarExp *)e1;
        fd = dve->var->isFuncDeclaration();
        goto Lfd;
    }
    else if (e1->op == TOKvar && e1->type->ty == Tfunction &&
        (sc->intypeof || !((VarExp *)e1)->var->needThis()))
    {
        fd = ((VarExp *)e1)->var->isFuncDeclaration();
    Lfd:
        assert(fd);
        if (((TypeFunction *)fd->type)->isproperty)
            return resolveProperties(sc, e1);
    }
    return e1;
}


// TODO: merge with Scope::search::searchScopes()
static Dsymbol *searchScopes(Scope *sc, Loc loc, Identifier *ident, int flags)
{
    Dsymbol *s = NULL;
    for (Scope *scx = sc; scx; scx = scx->enclosing)
    {
        if (!scx->scopesym)
            continue;
        if (scx->scopesym->isModule())
            flags |= SearchUnqualifiedModule;    // tell Module.search() that SearchLocalsOnly is to be obeyed
        s = scx->scopesym->search(loc, ident, flags);
        if (s)
        {
            // overload set contains only module scope symbols.
            if (s->isOverloadSet())
                break;
            // selective/renamed imports also be picked up
            if (AliasDeclaration *ad = s->isAliasDeclaration())
            {
                if (ad->_import)
                    break;
            }
            // See only module scope symbols for UFCS target.
            Dsymbol *p = s->toParent2();
            if (p && p->isModule())
                break;
        }
        s = NULL;

        // Stop when we hit a module, but keep going if that is not just under the global scope
        if (scx->scopesym->isModule() && !(scx->enclosing && !scx->enclosing->enclosing))
            break;
    }
    return s;
}

/******************************
 * Find symbol in accordance with the UFCS name look up rule
 */

Expression *searchUFCS(Scope *sc, UnaExp *ue, Identifier *ident)
{
    //printf("searchUFCS(ident = %s)\n", ident->toChars());
    Loc loc = ue->loc;
    int flags = 0;
    Dsymbol *s = NULL;

    if (sc->flags & SCOPEignoresymbolvisibility)
        flags |= IgnoreSymbolVisibility;

    Dsymbol *sold = NULL;
    if (global.params.bug10378 || global.params.check10378)
    {
        sold = searchScopes(sc, loc, ident, flags | IgnoreSymbolVisibility);
        if (!global.params.check10378)
        {
            s = sold;
            goto Lsearchdone;
        }
    }

    // First look in local scopes
    s = searchScopes(sc, loc, ident, flags | SearchLocalsOnly);
    if (!s)
    {
        // Second look in imported modules
        s = searchScopes(sc, loc, ident, flags | SearchImportsOnly);

        /** Still find private symbols, so that symbols that weren't access
         * checked by the compiler remain usable.  Once the deprecation is over,
         * this should be moved to search_correct instead.
         */
        if (!s && !(flags & IgnoreSymbolVisibility))
        {
            s = searchScopes(sc, loc, ident, flags | SearchLocalsOnly | IgnoreSymbolVisibility);
            if (!s)
                s = searchScopes(sc, loc, ident, flags | SearchImportsOnly | IgnoreSymbolVisibility);
            if (s)
                ::deprecation(loc, "%s is not visible from module %s", s->toPrettyChars(), sc->_module->toChars());
        }
    }
    if (global.params.check10378)
    {
        Dsymbol *snew = s;
        if (sold != snew)
            Scope::deprecation10378(loc, sold, snew);
        if (global.params.bug10378)
            s = sold;
    }
Lsearchdone:

    if (!s)
        return ue->e1->type->Type::getProperty(loc, ident, 0);

    FuncDeclaration *f = s->isFuncDeclaration();
    if (f)
    {
        TemplateDeclaration *td = getFuncTemplateDecl(f);
        if (td)
        {
            if (td->overroot)
                td = td->overroot;
            s = td;
        }
    }

    if (ue->op == TOKdotti)
    {
        DotTemplateInstanceExp *dti = (DotTemplateInstanceExp *)ue;
        TemplateInstance *ti = new TemplateInstance(loc, s->ident);
        ti->tiargs = dti->ti->tiargs;   // for better diagnostic message
        if (!ti->updateTempDecl(sc, s))
            return new ErrorExp();
        return new ScopeExp(loc, ti);
    }
    else
    {
        //printf("-searchUFCS() %s\n", s->toChars());
        return new DsymbolExp(loc, s);
    }
}

/******************************
 * check e is exp.opDispatch!(tiargs) or not
 * It's used to switch to UFCS the semantic analysis path
 */

bool isDotOpDispatch(Expression *e)
{
    return e->op == TOKdotti &&
           ((DotTemplateInstanceExp *)e)->ti->name == Id::opDispatch;
}

/******************************
 * Pull out callable entity with UFCS.
 */

Expression *resolveUFCS(Scope *sc, CallExp *ce)
{
    Loc loc = ce->loc;
    Expression *eleft;
    Expression *e;

    if (ce->e1->op == TOKdotid)
    {
        DotIdExp *die = (DotIdExp *)ce->e1;
        Identifier *ident = die->ident;

        Expression *ex = semanticX(die, sc);
        if (ex != die)
        {
            ce->e1 = ex;
            return NULL;
        }
        eleft = die->e1;

        Type *t = eleft->type->toBasetype();
        if (t->ty == Tarray || t->ty == Tsarray ||
            t->ty == Tnull  || (t->isTypeBasic() && t->ty != Tvoid))
        {
            /* Built-in types and arrays have no callable properties, so do shortcut.
             * It is necessary in: e.init()
             */
        }
        else if (t->ty == Taarray)
        {
            if (ident == Id::remove)
            {
                /* Transform:
                 *  aa.remove(arg) into delete aa[arg]
                 */
                if (!ce->arguments || ce->arguments->dim != 1)
                {
                    ce->error("expected key as argument to aa.remove()");
                    return new ErrorExp();
                }
                if (!eleft->type->isMutable())
                {
                    ce->error("cannot remove key from %s associative array %s",
                            MODtoChars(t->mod), eleft->toChars());
                    return new ErrorExp();
                }
                Expression *key = (*ce->arguments)[0];
                key = semantic(key, sc);
                key = resolveProperties(sc, key);

                TypeAArray *taa = (TypeAArray *)t;
                key = key->implicitCastTo(sc, taa->index);

                if (key->checkValue())
                    return new ErrorExp();

                semanticTypeInfo(sc, taa->index);

                return new RemoveExp(loc, eleft, key);
            }
        }
        else
        {
            if (Expression *ey = semanticY(die, sc, 1))
            {
                if (ey->op == TOKerror)
                    return ey;
                ce->e1 = ey;
                if (isDotOpDispatch(ey))
                {
                    unsigned errors = global.startGagging();
                    e = semantic(ce->syntaxCopy(), sc);
                    if (!global.endGagging(errors))
                        return e;
                    /* fall down to UFCS */
                }
                else
                    return NULL;
            }
        }
        e = searchUFCS(sc, die, ident);
    }
    else if (ce->e1->op == TOKdotti)
    {
        DotTemplateInstanceExp *dti = (DotTemplateInstanceExp *)ce->e1;
        if (Expression *ey = semanticY(dti, sc, 1))
        {
            ce->e1 = ey;
            return NULL;
        }
        eleft = dti->e1;
        e = searchUFCS(sc, dti, dti->ti->name);
    }
    else
        return NULL;

    // Rewrite
    ce->e1 = e;
    if (!ce->arguments)
        ce->arguments = new Expressions();
    ce->arguments->shift(eleft);

    return NULL;
}

/******************************
 * Pull out property with UFCS.
 */

Expression *resolveUFCSProperties(Scope *sc, Expression *e1, Expression *e2 = NULL)
{
    Loc loc = e1->loc;
    Expression *eleft;
    Expression *e;

    if (e1->op == TOKdotid)
    {
        DotIdExp *die = (DotIdExp *)e1;
        eleft = die->e1;
        e = searchUFCS(sc, die, die->ident);
    }
    else if (e1->op == TOKdotti)
    {
        DotTemplateInstanceExp *dti;
        dti = (DotTemplateInstanceExp *)e1;
        eleft = dti->e1;
        e = searchUFCS(sc, dti, dti->ti->name);
    }
    else
        return NULL;

    if (e == NULL)
        return NULL;

    // Rewrite
    if (e2)
    {
        // run semantic without gagging
        e2 = semantic(e2, sc);

        /* f(e1) = e2
         */
        Expression *ex = e->copy();
        Expressions *a1 = new Expressions();
        a1->setDim(1);
        (*a1)[0] = eleft;
        ex = new CallExp(loc, ex, a1);
        ex = trySemantic(ex, sc);

        /* f(e1, e2)
         */
        Expressions *a2 = new Expressions();
        a2->setDim(2);
        (*a2)[0] = eleft;
        (*a2)[1] = e2;
        e = new CallExp(loc, e, a2);
        if (ex)
        {   // if fallback setter exists, gag errors
            e = trySemantic(e, sc);
            if (!e)
            {   checkPropertyCall(ex);
                ex = new AssignExp(loc, ex, e2);
                return semantic(ex, sc);
            }
        }
        else
        {   // strict setter prints errors if fails
            e = semantic(e, sc);
        }
        checkPropertyCall(e);
        return e;
    }
    else
    {
        /* f(e1)
         */
        Expressions *arguments = new Expressions();
        arguments->setDim(1);
        (*arguments)[0] = eleft;
        e = new CallExp(loc, e, arguments);
        e = semantic(e, sc);
        checkPropertyCall(e);
        return semantic(e, sc);
    }
}

/******************************
 * Perform semantic() on an array of Expressions.
 */

bool arrayExpressionSemantic(Expressions *exps, Scope *sc, bool preserveErrors)
{
    bool err = false;
    if (exps)
    {
        for (size_t i = 0; i < exps->dim; i++)
        {
            Expression *e = (*exps)[i];
            if (e)
            {
                e = semantic(e, sc);
                if (e->op == TOKerror)
                    err = true;
                if (preserveErrors || e->op != TOKerror)
                    (*exps)[i] = e;
            }
        }
    }
    return err;
}

/****************************************
 * Expand tuples.
 * Input:
 *      exps    aray of Expressions
 * Output:
 *      exps    rewritten in place
 */

void expandTuples(Expressions *exps)
{
    //printf("expandTuples()\n");
    if (exps)
    {
        for (size_t i = 0; i < exps->dim; i++)
        {
            Expression *arg = (*exps)[i];
            if (!arg)
                continue;

            // Look for tuple with 0 members
            if (arg->op == TOKtype)
            {
                TypeExp *e = (TypeExp *)arg;
                if (e->type->toBasetype()->ty == Ttuple)
                {
                    TypeTuple *tt = (TypeTuple *)e->type->toBasetype();

                    if (!tt->arguments || tt->arguments->dim == 0)
                    {
                        exps->remove(i);
                        if (i == exps->dim)
                            return;
                        i--;
                        continue;
                    }
                }
            }

            // Inline expand all the tuples
            while (arg->op == TOKtuple)
            {
                TupleExp *te = (TupleExp *)arg;
                exps->remove(i);                // remove arg
                exps->insert(i, te->exps);      // replace with tuple contents
                if (i == exps->dim)
                    return;             // empty tuple, no more arguments
                (*exps)[i] = Expression::combine(te->e0, (*exps)[i]);
                arg = (*exps)[i];
            }
        }
    }
}

/****************************************
 * Expand alias this tuples.
 */

TupleDeclaration *isAliasThisTuple(Expression *e)
{
    if (!e->type)
        return NULL;

    Type *t = e->type->toBasetype();
Lagain:
    if (Dsymbol *s = t->toDsymbol(NULL))
    {
        AggregateDeclaration *ad = s->isAggregateDeclaration();
        if (ad)
        {
            s = ad->aliasthis;
            if (s && s->isVarDeclaration())
            {
                TupleDeclaration *td = s->isVarDeclaration()->toAlias()->isTupleDeclaration();
                if (td && td->isexp)
                    return td;
            }
            if (Type *att = t->aliasthisOf())
            {
                t = att;
                goto Lagain;
            }
        }
    }
    return NULL;
}

int expandAliasThisTuples(Expressions *exps, size_t starti)
{
    if (!exps || exps->dim == 0)
        return -1;

    for (size_t u = starti; u < exps->dim; u++)
    {
        Expression *exp = (*exps)[u];
        TupleDeclaration *td = isAliasThisTuple(exp);
        if (td)
        {
            exps->remove(u);
            for (size_t i = 0; i<td->objects->dim; ++i)
            {
                Expression *e = isExpression((*td->objects)[i]);
                assert(e);
                assert(e->op == TOKdsymbol);
                DsymbolExp *se = (DsymbolExp *)e;
                Declaration *d = se->s->isDeclaration();
                assert(d);
                e = new DotVarExp(exp->loc, exp, d);
                assert(d->type);
                e->type = d->type;
                exps->insert(u + i, e);
            }
            return (int)u;
        }
    }

    return -1;
}

/****************************************
 * The common type is determined by applying ?: to each pair.
 * Output:
 *      exps[]  properties resolved, implicitly cast to common type, rewritten in place
 *      *pt     if pt is not NULL, set to the common type
 * Returns:
 *      true    a semantic error was detected
 */

bool arrayExpressionToCommonType(Scope *sc, Expressions *exps, Type **pt)
{
    /* Still have a problem with:
     *  ubyte[][] = [ cast(ubyte[])"hello", [1]];
     * which works if the array literal is initialized top down with the ubyte[][]
     * type, but fails with this function doing bottom up typing.
     */
    //printf("arrayExpressionToCommonType()\n");
    IntegerExp integerexp(0);
    CondExp condexp(Loc(), &integerexp, NULL, NULL);

    Type *t0 = NULL;
    Expression *e0 = NULL;      // dead-store to prevent spurious warning
    size_t j0 = ~0;             // dead-store to prevent spurious warning
    for (size_t i = 0; i < exps->dim; i++)
    {
        Expression *e = (*exps)[i];
        if (!e)
            continue;

        e = resolveProperties(sc, e);
        if (!e->type)
        {
            e->error("%s has no value", e->toChars());
            t0 = Type::terror;
            continue;
        }
        if (e->op == TOKtype)
        {
            e->checkValue();    // report an error "type T has no value"
            t0 = Type::terror;
            continue;
        }
        if (e->type->ty == Tvoid)
        {
            // void expressions do not concur to the determination of the common
            // type.
            continue;
        }
        if (checkNonAssignmentArrayOp(e))
        {
            t0 = Type::terror;
            continue;
        }

        e = doCopyOrMove(sc, e);

        if (t0 && !t0->equals(e->type))
        {
            /* This applies ?: to merge the types. It's backwards;
             * ?: should call this function to merge types.
             */
            condexp.type = NULL;
            condexp.e1 = e0;
            condexp.e2 = e;
            condexp.loc = e->loc;
            Expression *ex = semantic(&condexp, sc);
            if (ex->op == TOKerror)
                e = ex;
            else
            {
                (*exps)[j0] = condexp.e1;
                e = condexp.e2;
            }
        }
        j0 = i;
        e0 = e;
        t0 = e->type;
        if (e->op != TOKerror)
            (*exps)[i] = e;
    }

    if (!t0)
        t0 = Type::tvoid;               // [] is typed as void[]
    else if (t0->ty != Terror)
    {
        for (size_t i = 0; i < exps->dim; i++)
        {
            Expression *e = (*exps)[i];
            if (!e)
                continue;

            e = e->implicitCastTo(sc, t0);
            //assert(e->op != TOKerror);
            if (e->op == TOKerror)
            {
                /* Bugzilla 13024: a workaround for the bug in typeMerge -
                 * it should paint e1 and e2 by deduced common type,
                 * but doesn't in this particular case.
                 */
                t0 = Type::terror;
                break;
            }
            (*exps)[i] = e;
        }
    }
    if (pt)
        *pt = t0;

    return (t0 == Type::terror);
}

/****************************************
 * Get TemplateDeclaration enclosing FuncDeclaration.
 */

TemplateDeclaration *getFuncTemplateDecl(Dsymbol *s)
{
    FuncDeclaration *f = s->isFuncDeclaration();
    if (f && f->parent)
    {
        TemplateInstance *ti = f->parent->isTemplateInstance();
        if (ti && !ti->isTemplateMixin() &&
            ti->tempdecl && ((TemplateDeclaration *)ti->tempdecl)->onemember &&
            ti->tempdecl->ident == f->ident)
        {
            return (TemplateDeclaration *)ti->tempdecl;
        }
    }
    return NULL;
}

/************************************************
 * If we want the value of this expression, but do not want to call
 * the destructor on it.
 */

Expression *valueNoDtor(Expression *e)
{
    if (e->op == TOKcall)
    {
        /* The struct value returned from the function is transferred
         * so do not call the destructor on it.
         * Recognize:
         *       ((S _ctmp = S.init), _ctmp).this(...)
         * and make sure the destructor is not called on _ctmp
         * BUG: if e is a CommaExp, we should go down the right side.
         */
        CallExp *ce = (CallExp *)e;
        if (ce->e1->op == TOKdotvar)
        {
            DotVarExp *dve = (DotVarExp *)ce->e1;
            if (dve->var->isCtorDeclaration())
            {
                // It's a constructor call
                if (dve->e1->op == TOKcomma)
                {
                    CommaExp *comma = (CommaExp *)dve->e1;
                    if (comma->e2->op == TOKvar)
                    {
                        VarExp *ve = (VarExp *)comma->e2;
                        VarDeclaration *ctmp = ve->var->isVarDeclaration();
                        if (ctmp)
                        {
                            ctmp->storage_class |= STCnodtor;
                            assert(!ce->isLvalue());
                        }
                    }
                }
            }
        }
    }
    else if (e->op == TOKvar)
    {
        VarDeclaration *vtmp = ((VarExp *)e)->var->isVarDeclaration();
        if (vtmp && vtmp->storage_class & STCrvalue)
        {
            vtmp->storage_class |= STCnodtor;
        }
    }
    return e;
}

/********************************************
 * Issue an error if default construction is disabled for type t.
 * Default construction is required for arrays and 'out' parameters.
 * Returns:
 *      true    an error was issued
 */
bool checkDefCtor(Loc loc, Type *t)
{
    t = t->baseElemOf();
    if (t->ty == Tstruct)
    {
        StructDeclaration *sd = ((TypeStruct *)t)->sym;
        if (sd->noDefaultCtor)
        {
            sd->error(loc, "default construction is disabled");
            return true;
        }
    }
    return false;
}

/*********************************************
 * If e is an instance of a struct, and that struct has a copy constructor,
 * rewrite e as:
 *    (tmp = e),tmp
 * Input:
 *      sc      just used to specify the scope of created temporary variable
 */
Expression *callCpCtor(Scope *sc, Expression *e)
{
    Type *tv = e->type->baseElemOf();
    if (tv->ty == Tstruct)
    {
        StructDeclaration *sd = ((TypeStruct *)tv)->sym;
        if (sd->postblit)
        {
            /* Create a variable tmp, and replace the argument e with:
             *      (tmp = e),tmp
             * and let AssignExp() handle the construction.
             * This is not the most efficent, ideally tmp would be constructed
             * directly onto the stack.
             */
            VarDeclaration *tmp = copyToTemp(STCrvalue, "__copytmp", e);
            tmp->storage_class |= STCnodtor;
            tmp->semantic(sc);
            Expression *de = new DeclarationExp(e->loc, tmp);
            Expression *ve = new VarExp(e->loc, tmp);
            de->type = Type::tvoid;
            ve->type = e->type;
            e = Expression::combine(de, ve);
        }
    }
    return e;
}

/************************************************
 * Handle the postblit call on lvalue, or the move of rvalue.
 */
Expression *doCopyOrMove(Scope *sc, Expression *e)
{
    if (e->op == TOKquestion)
    {
        CondExp *ce = (CondExp *)e;
        ce->e1 = doCopyOrMove(sc, ce->e1);
        ce->e2 = doCopyOrMove(sc, ce->e2);
    }
    else
    {
        e = e->isLvalue() ? callCpCtor(sc, e) : valueNoDtor(e);
    }
    return e;
}

/****************************************
 * Now that we know the exact type of the function we're calling,
 * the arguments[] need to be adjusted:
 *      1. implicitly convert argument to the corresponding parameter type
 *      2. add default arguments for any missing arguments
 *      3. do default promotions on arguments corresponding to ...
 *      4. add hidden _arguments[] argument
 *      5. call copy constructor for struct value arguments
 * Input:
 *      tf      type of the function
 *      fd      the function being called, NULL if called indirectly
 * Output:
 *      *prettype return type of function
 *      *peprefix expression to execute before arguments[] are evaluated, NULL if none
 * Returns:
 *      true    errors happened
 */

bool functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
        Type *tthis, Expressions *arguments, FuncDeclaration *fd, Type **prettype, Expression **peprefix)
{
    //printf("functionParameters()\n");
    assert(arguments);
    assert(fd || tf->next);
    size_t nargs = arguments ? arguments->dim : 0;
    size_t nparams = Parameter::dim(tf->parameters);
    unsigned olderrors = global.errors;
    bool err = false;
    *prettype = Type::terror;
    Expression *eprefix = NULL;
    *peprefix = NULL;

    if (nargs > nparams && tf->varargs == 0)
    {
        error(loc, "expected %llu arguments, not %llu for non-variadic function type %s", (ulonglong)nparams, (ulonglong)nargs, tf->toChars());
        return true;
    }

    // If inferring return type, and semantic3() needs to be run if not already run
    if (!tf->next && fd->inferRetType)
    {
        fd->functionSemantic();
    }
    else if (fd && fd->parent)
    {
        TemplateInstance *ti = fd->parent->isTemplateInstance();
        if (ti && ti->tempdecl)
        {
            fd->functionSemantic3();
        }
    }
    bool isCtorCall = fd && fd->needThis() && fd->isCtorDeclaration();

    size_t n = (nargs > nparams) ? nargs : nparams;   // n = max(nargs, nparams)

    /* If the function return type has wildcards in it, we'll need to figure out the actual type
     * based on the actual argument types.
     */
    MOD wildmatch = 0;
    if (tthis && tf->isWild() && !isCtorCall)
    {
        Type *t = tthis;
        if (t->isImmutable())
            wildmatch = MODimmutable;
        else if (t->isWildConst())
            wildmatch = MODwildconst;
        else if (t->isWild())
            wildmatch = MODwild;
        else if (t->isConst())
            wildmatch = MODconst;
        else
            wildmatch = MODmutable;
    }

    int done = 0;
    for (size_t i = 0; i < n; i++)
    {
        Expression *arg;

        if (i < nargs)
            arg = (*arguments)[i];
        else
            arg = NULL;

        if (i < nparams)
        {
            Parameter *p = Parameter::getNth(tf->parameters, i);

            if (!arg)
            {
                if (!p->defaultArg)
                {
                    if (tf->varargs == 2 && i + 1 == nparams)
                        goto L2;
                    error(loc, "expected %llu function arguments, not %llu", (ulonglong)nparams, (ulonglong)nargs);
                    return true;
                }
                arg = p->defaultArg;
                arg = inlineCopy(arg, sc);
                // __FILE__, __LINE__, __MODULE__, __FUNCTION__, and __PRETTY_FUNCTION__
                arg = arg->resolveLoc(loc, sc);
                arguments->push(arg);
                nargs++;
            }

            if (tf->varargs == 2 && i + 1 == nparams)
            {
                //printf("\t\tvarargs == 2, p->type = '%s'\n", p->type->toChars());
                {
                    MATCH m;
                    if ((m = arg->implicitConvTo(p->type)) > MATCHnomatch)
                    {
                        if (p->type->nextOf() && arg->implicitConvTo(p->type->nextOf()) >= m)
                            goto L2;
                        else if (nargs != nparams)
                        {   error(loc, "expected %llu function arguments, not %llu", (ulonglong)nparams, (ulonglong)nargs);
                            return true;
                        }
                        goto L1;
                    }
                }
             L2:
                Type *tb = p->type->toBasetype();
                Type *tret = p->isLazyArray();
                switch (tb->ty)
                {
                    case Tsarray:
                    case Tarray:
                    {
                        /* Create a static array variable v of type arg->type:
                         *  T[dim] __arrayArg = [ arguments[i], ..., arguments[nargs-1] ];
                         *
                         * The array literal in the initializer of the hidden variable
                         * is now optimized. See Bugzilla 2356.
                         */
                        Type *tbn = ((TypeArray *)tb)->next;

                        Expressions *elements = new Expressions();
                        elements->setDim(nargs - i);
                        for (size_t u = 0; u < elements->dim; u++)
                        {
                            Expression *a = (*arguments)[i + u];
                            if (tret && a->implicitConvTo(tret))
                            {
                                a = a->implicitCastTo(sc, tret);
                                a = a->optimize(WANTvalue);
                                a = toDelegate(a, a->type, sc);
                            }
                            else
                                a = a->implicitCastTo(sc, tbn);
                            (*elements)[u] = a;
                        }
                        // Bugzilla 14395: Convert to a static array literal, or its slice.
                        arg = new ArrayLiteralExp(loc, tbn->sarrayOf(nargs - i), elements);
                        if (tb->ty == Tarray)
                        {
                            arg = new SliceExp(loc, arg, NULL, NULL);
                            arg->type = p->type;
                        }
                        break;
                    }
                    case Tclass:
                    {
                        /* Set arg to be:
                         *      new Tclass(arg0, arg1, ..., argn)
                         */
                        Expressions *args = new Expressions();
                        args->setDim(nargs - i);
                        for (size_t u = i; u < nargs; u++)
                            (*args)[u - i] = (*arguments)[u];
                        arg = new NewExp(loc, NULL, NULL, p->type, args);
                        break;
                    }
                    default:
                        if (!arg)
                        {
                            error(loc, "not enough arguments");
                            return true;
                        }
                        break;
                }
                arg = semantic(arg, sc);
                //printf("\targ = '%s'\n", arg->toChars());
                arguments->setDim(i + 1);
                (*arguments)[i] =  arg;
                nargs = i + 1;
                done = 1;
            }

        L1:
            if (!(p->storageClass & STClazy && p->type->ty == Tvoid))
            {
                bool isRef = (p->storageClass & (STCref | STCout)) != 0;
                if (unsigned char wm = arg->type->deduceWild(p->type, isRef))
                {
                    if (wildmatch)
                        wildmatch = MODmerge(wildmatch, wm);
                    else
                        wildmatch = wm;
                    //printf("[%d] p = %s, a = %s, wm = %d, wildmatch = %d\n", i, p->type->toChars(), arg->type->toChars(), wm, wildmatch);
                }
            }
        }
        if (done)
            break;
    }
    if ((wildmatch == MODmutable || wildmatch == MODimmutable) &&
        tf->next->hasWild() &&
        (tf->isref || !tf->next->implicitConvTo(tf->next->immutableOf())))
    {
        if (fd)
        {
            /* If the called function may return the reference to
             * outer inout data, it should be rejected.
             *
             * void foo(ref inout(int) x) {
             *   ref inout(int) bar(inout(int)) { return x; }
             *   struct S { ref inout(int) bar() inout { return x; } }
             *   bar(int.init) = 1;  // bad!
             *   S().bar() = 1;      // bad!
             * }
             */
            Dsymbol *s = NULL;
            if (fd->isThis() || fd->isNested())
                s = fd->toParent2();
            for (; s; s = s->toParent2())
            {
                if (AggregateDeclaration *ad = s->isAggregateDeclaration())
                {
                    if (ad->isNested())
                        continue;
                    break;
                }
                if (FuncDeclaration *ff = s->isFuncDeclaration())
                {
                    if (((TypeFunction *)ff->type)->iswild)
                        goto Linouterr;

                    if (ff->isNested() || ff->isThis())
                        continue;
                }
                break;
            }
        }
        else if (tf->isWild())
        {
        Linouterr:
            const char *s = wildmatch == MODmutable ? "mutable" : MODtoChars(wildmatch);
            error(loc, "modify inout to %s is not allowed inside inout function", s);
            return true;
        }
    }

    assert(nargs >= nparams);
    for (size_t i = 0; i < nargs; i++)
    {
        Expression *arg = (*arguments)[i];
        assert(arg);
        if (i < nparams)
        {
            Parameter *p = Parameter::getNth(tf->parameters, i);

            if (!(p->storageClass & STClazy && p->type->ty == Tvoid))
            {
                Type *tprm = p->type;
                if (p->type->hasWild())
                    tprm = p->type->substWildTo(wildmatch);
                if (!tprm->equals(arg->type))
                {
                    //printf("arg->type = %s, p->type = %s\n", arg->type->toChars(), p->type->toChars());
                    arg = arg->implicitCastTo(sc, tprm);
                    arg = arg->optimize(WANTvalue, (p->storageClass & (STCref | STCout)) != 0);
                }
            }
            if (p->storageClass & STCref)
            {
                arg = arg->toLvalue(sc, arg);

                // Look for mutable misaligned pointer, etc., in @safe mode
                err |= checkUnsafeAccess(sc, arg, false, true);
            }
            else if (p->storageClass & STCout)
            {
                Type *t = arg->type;
                if (!t->isMutable() || !t->isAssignable())  // check blit assignable
                {
                    arg->error("cannot modify struct %s with immutable members", arg->toChars());
                    err = true;
                }
                else
                {
                    // Look for misaligned pointer, etc., in @safe mode
                    err |= checkUnsafeAccess(sc, arg, false, true);
                    err |= checkDefCtor(arg->loc, t);   // t must be default constructible
                }
                arg = arg->toLvalue(sc, arg);
            }
            else if (p->storageClass & STClazy)
            {
                // Convert lazy argument to a delegate
                if (p->type->ty == Tvoid)
                    arg = toDelegate(arg, p->type, sc);
                else
                    arg = toDelegate(arg, arg->type, sc);
            }

            //printf("arg: %s\n", arg->toChars());
            //printf("type: %s\n", arg->type->toChars());
            if (tf->parameterEscapes(p))
            {
                /* Argument value can escape from the called function.
                 * Check arg to see if it matters.
                 */
                if (global.params.vsafe)
                    err |= checkParamArgumentEscape(sc, fd, p->ident, arg, false);
            }
            else
            {
                /* Argument value cannot escape from the called function.
                 */
                Expression *a = arg;
                if (a->op == TOKcast)
                    a = ((CastExp *)a)->e1;

                if (a->op == TOKfunction)
                {
                    /* Function literals can only appear once, so if this
                     * appearance was scoped, there cannot be any others.
                     */
                    FuncExp *fe = (FuncExp *)a;
                    fe->fd->tookAddressOf = 0;
                }
                else if (a->op == TOKdelegate)
                {
                    /* For passing a delegate to a scoped parameter,
                     * this doesn't count as taking the address of it.
                     * We only worry about 'escaping' references to the function.
                     */
                    DelegateExp *de = (DelegateExp *)a;
                    if (de->e1->op == TOKvar)
                    {   VarExp *ve = (VarExp *)de->e1;
                        FuncDeclaration *f = ve->var->isFuncDeclaration();
                        if (f)
                        {   f->tookAddressOf--;
                            //printf("tookAddressOf = %d\n", f->tookAddressOf);
                        }
                    }
                }
            }
            arg = arg->optimize(WANTvalue, (p->storageClass & (STCref | STCout)) != 0);
        }
        else
        {
            // These will be the trailing ... arguments

            // If not D linkage, do promotions
            if (tf->linkage != LINKd)
            {
                // Promote bytes, words, etc., to ints
                arg = integralPromotions(arg, sc);

                // Promote floats to doubles
                switch (arg->type->ty)
                {
                    case Tfloat32:
                        arg = arg->castTo(sc, Type::tfloat64);
                        break;

                    case Timaginary32:
                        arg = arg->castTo(sc, Type::timaginary64);
                        break;
                }

                if (tf->varargs == 1)
                {
                    const char *p = tf->linkage == LINKc ? "extern(C)" : "extern(C++)";
                    if (arg->type->ty == Tarray)
                    {
                        arg->error("cannot pass dynamic arrays to %s vararg functions", p);
                        err = true;
                    }
                    if (arg->type->ty == Tsarray)
                    {
                        arg->error("cannot pass static arrays to %s vararg functions", p);
                        err = true;
                    }
                }
            }

            // Do not allow types that need destructors
            if (arg->type->needsDestruction())
            {
                arg->error("cannot pass types that need destruction as variadic arguments");
                err = true;
            }

            // Convert static arrays to dynamic arrays
            // BUG: I don't think this is right for D2
            Type *tb = arg->type->toBasetype();
            if (tb->ty == Tsarray)
            {
                TypeSArray *ts = (TypeSArray *)tb;
                Type *ta = ts->next->arrayOf();
                if (ts->size(arg->loc) == 0)
                    arg = new NullExp(arg->loc, ta);
                else
                    arg = arg->castTo(sc, ta);
            }
            if (tb->ty == Tstruct)
            {
                //arg = callCpCtor(sc, arg);
            }

            // Give error for overloaded function addresses
            if (arg->op == TOKsymoff)
            {   SymOffExp *se = (SymOffExp *)arg;
                if (se->hasOverloads &&
                    !se->var->isFuncDeclaration()->isUnique())
                {   arg->error("function %s is overloaded", arg->toChars());
                    err = true;
                }
            }
            if (arg->checkValue())
                err = true;
            arg = arg->optimize(WANTvalue);
        }
        (*arguments)[i] = arg;
    }

    /* Remaining problems:
     * 1. order of evaluation - some function push L-to-R, others R-to-L. Until we resolve what array assignment does (which is
     *    implemented by calling a function) we'll defer this for now.
     * 2. value structs (or static arrays of them) that need to be copy constructed
     * 3. value structs (or static arrays of them) that have destructors, and subsequent arguments that may throw before the
     *    function gets called (functions normally destroy their parameters)
     * 2 and 3 are handled by doing the argument construction in 'eprefix' so that if a later argument throws, they are cleaned
     * up properly. Pushing arguments on the stack then cannot fail.
     */
    if (1)
    {
        /* TODO: tackle problem 1)
         */
        const bool leftToRight = true; // TODO: something like !fd.isArrayOp
        if (!leftToRight)
            assert(nargs == nparams); // no variadics for RTL order, as they would probably be evaluated LTR and so add complexity

        const ptrdiff_t start = (leftToRight ? 0 : (ptrdiff_t)nargs - 1);
        const ptrdiff_t end = (leftToRight ? (ptrdiff_t)nargs : -1);
        const ptrdiff_t step = (leftToRight ? 1 : -1);

        /* Compute indices of last throwing argument and first arg needing destruction.
         * Used to not set up destructors unless an arg needs destruction on a throw
         * in a later argument.
         */
        ptrdiff_t lastthrow = -1;
        ptrdiff_t firstdtor = -1;
        for (ptrdiff_t i = start; i != end; i += step)
        {
            Expression *arg = (*arguments)[i];
            if (canThrow(arg, sc->func, false))
                lastthrow = i;
            if (firstdtor == -1 && arg->type->needsDestruction())
            {
                Parameter *p = (i >= (ptrdiff_t)nparams ? NULL : Parameter::getNth(tf->parameters, i));
                if (!(p && (p->storageClass & (STClazy | STCref | STCout))))
                    firstdtor = i;
            }
        }

        /* Does problem 3) apply to this call?
         */
        const bool needsPrefix = (firstdtor >= 0 && lastthrow >= 0
            && (lastthrow - firstdtor) * step > 0);

        /* If so, initialize 'eprefix' by declaring the gate
         */
        VarDeclaration *gate = NULL;
        if (needsPrefix)
        {
            // eprefix => bool __gate [= false]
            Identifier *idtmp = Identifier::generateId("__gate");
            gate = new VarDeclaration(loc, Type::tbool, idtmp, NULL);
            gate->storage_class |= STCtemp | STCctfe | STCvolatile;
            gate->semantic(sc);

            Expression *ae = new DeclarationExp(loc, gate);
            eprefix = semantic(ae, sc);
        }

        for (ptrdiff_t i = start; i != end; i += step)
        {
            Expression *arg = (*arguments)[i];

            Parameter *parameter = (i >= (ptrdiff_t)nparams ? NULL : Parameter::getNth(tf->parameters, i));
            const bool isRef = (parameter && (parameter->storageClass & (STCref | STCout)));
            const bool isLazy = (parameter && (parameter->storageClass & STClazy));

            /* Skip lazy parameters
             */
            if (isLazy)
                continue;

            /* Do we have a gate? Then we have a prefix and we're not yet past the last throwing arg.
             * Declare a temporary variable for this arg and append that declaration to 'eprefix',
             * which will implicitly take care of potential problem 2) for this arg.
             * 'eprefix' will therefore finally contain all args up to and including the last
             * potentially throwing arg, excluding all lazy parameters.
             */
            if (gate)
            {
                const bool needsDtor = (!isRef && arg->type->needsDestruction() && i != lastthrow);

                /* Declare temporary 'auto __pfx = arg' (needsDtor) or 'auto __pfy = arg' (!needsDtor)
                 */
                VarDeclaration *tmp = copyToTemp(0,
                    needsDtor ? "__pfx" : "__pfy",
                    !isRef ? arg : arg->addressOf());
                tmp->semantic(sc);

                /* Modify the destructor so it only runs if gate==false, i.e.,
                 * only if there was a throw while constructing the args
                 */
                if (!needsDtor)
                {
                    if (tmp->edtor)
                    {
                        assert(i == lastthrow);
                        tmp->edtor = NULL;
                    }
                }
                else
                {
                    // edtor => (__gate || edtor)
                    assert(tmp->edtor);
                    Expression *e = tmp->edtor;
                    e = new OrOrExp(e->loc, new VarExp(e->loc, gate), e);
                    tmp->edtor = semantic(e, sc);
                    //printf("edtor: %s\n", tmp->edtor->toChars());
                }

                // eprefix => (eprefix, auto __pfx/y = arg)
                DeclarationExp *ae = new DeclarationExp(loc, tmp);
                eprefix = Expression::combine(eprefix, semantic(ae, sc));

                // arg => __pfx/y
                arg = new VarExp(loc, tmp);
                arg = semantic(arg, sc);
                if (isRef)
                {
                    arg = new PtrExp(loc, arg);
                    arg = semantic(arg, sc);
                }

                /* Last throwing arg? Then finalize eprefix => (eprefix, gate = true),
                 * i.e., disable the dtors right after constructing the last throwing arg.
                 * From now on, the callee will take care of destructing the args because
                 * the args are implicitly moved into function parameters.
                 *
                 * Set gate to null to let the next iterations know they don't need to
                 * append to eprefix anymore.
                 */
                if (i == lastthrow)
                {
                    Expression *e = new AssignExp(gate->loc, new VarExp(gate->loc, gate), new IntegerExp(gate->loc, 1, Type::tbool));
                    eprefix = Expression::combine(eprefix, semantic(e, sc));
                    gate = NULL;
                }
            }
            else
            {
                /* No gate, no prefix to append to.
                 * Handle problem 2) by calling the copy constructor for value structs
                 * (or static arrays of them) if appropriate.
                 */
                Type *tv = arg->type->baseElemOf();
                if (!isRef && tv->ty == Tstruct)
                    arg = doCopyOrMove(sc, arg);
            }

            (*arguments)[i] = arg;
        }
    }
    //if (eprefix) printf("eprefix: %s\n", eprefix->toChars());

    // If D linkage and variadic, add _arguments[] as first argument
    if (tf->linkage == LINKd && tf->varargs == 1)
    {
        assert(arguments->dim >= nparams);

        Parameters *args = new Parameters;
        args->setDim(arguments->dim - nparams);
        for (size_t i = 0; i < arguments->dim - nparams; i++)
        {
            Parameter *arg = new Parameter(STCin, (*arguments)[nparams + i]->type, NULL, NULL);
            (*args)[i] = arg;
        }

        TypeTuple *tup = new TypeTuple(args);
        Expression *e = new TypeidExp(loc, tup);
        e = semantic(e, sc);
        arguments->insert(0, e);
    }

    Type *tret = tf->next;
    if (isCtorCall)
    {
        //printf("[%s] fd = %s %s, %d %d %d\n", loc.toChars(), fd->toChars(), fd->type->toChars(),
        //    wildmatch, tf->isWild(), fd->isolateReturn());
        if (!tthis)
        {
            assert(sc->intypeof || global.errors);
            tthis = fd->isThis()->type->addMod(fd->type->mod);
        }
        if (tf->isWild() && !fd->isolateReturn())
        {
            if (wildmatch)
                tret = tret->substWildTo(wildmatch);
            int offset;
            if (!tret->implicitConvTo(tthis) &&
                !(MODimplicitConv(tret->mod, tthis->mod) && tret->isBaseOf(tthis, &offset) && offset == 0))
            {
                const char* s1 = tret ->isNaked() ? " mutable" : tret ->modToChars();
                const char* s2 = tthis->isNaked() ? " mutable" : tthis->modToChars();
                ::error(loc, "inout constructor %s creates%s object, not%s",
                        fd->toPrettyChars(), s1, s2);
                err = true;
            }
        }
        tret = tthis;
    }
    else if (wildmatch && tret)
    {
        /* Adjust function return type based on wildmatch
         */
        //printf("wildmatch = x%x, tret = %s\n", wildmatch, tret->toChars());
        tret = tret->substWildTo(wildmatch);
    }
    *prettype = tret;
    *peprefix = eprefix;
    return (err || olderrors != global.errors);
}

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

Expression::Expression(Loc loc, TOK op, int size)
{
    //printf("Expression::Expression(op = %d) this = %p\n", op, this);
    this->loc = loc;
    this->op = op;
    this->size = (unsigned char)size;
    this->parens = 0;
    type = NULL;
}

void Expression::_init()
{
    CTFEExp::cantexp = new CTFEExp(TOKcantexp);
    CTFEExp::voidexp = new CTFEExp(TOKvoidexp);
    CTFEExp::breakexp = new CTFEExp(TOKbreak);
    CTFEExp::continueexp = new CTFEExp(TOKcontinue);
    CTFEExp::gotoexp = new CTFEExp(TOKgoto);
}

Expression *Expression::syntaxCopy()
{
    //printf("Expression::syntaxCopy()\n");
    //print();
    return copy();
}

/*********************************
 * Does *not* do a deep copy.
 */

Expression *Expression::copy()
{
    Expression *e;
    if (!size)
    {
        assert(0);
    }
    void *pe = mem.xmalloc(size);
    //printf("Expression::copy(op = %d) e = %p\n", op, pe);
    e = (Expression *)memcpy(pe, (void *)this, size);
    return e;
}

void Expression::print()
{
    fprintf(stderr, "%s\n", toChars());
    fflush(stderr);
}

const char *Expression::toChars()
{
    OutBuffer buf;
    HdrGenState hgs;
    toCBuffer(this, &buf, &hgs);
    return buf.extractString();
}

void Expression::error(const char *format, ...) const
{
    if (type != Type::terror)
    {
        va_list ap;
        va_start(ap, format);
        ::verror(loc, format, ap);
        va_end( ap );
    }
}

void Expression::warning(const char *format, ...) const
{
    if (type != Type::terror)
    {
        va_list ap;
        va_start(ap, format);
        ::vwarning(loc, format, ap);
        va_end( ap );
    }
}

void Expression::deprecation(const char *format, ...) const
{
    if (type != Type::terror)
    {
        va_list ap;
        va_start(ap, format);
        ::vdeprecation(loc, format, ap);
        va_end( ap );
    }
}

/**********************************
 * Combine e1 and e2 by CommaExp if both are not NULL.
 */
Expression *Expression::combine(Expression *e1, Expression *e2)
{
    if (e1)
    {
        if (e2)
        {
            e1 = new CommaExp(e1->loc, e1, e2);
            e1->type = e2->type;
        }
    }
    else
        e1 = e2;
    return e1;
}

/**********************************
 * If 'e' is a tree of commas, returns the leftmost expression
 * by stripping off it from the tree. The remained part of the tree
 * is returned via *pe0.
 * Otherwise 'e' is directly returned and *pe0 is set to NULL.
 */
Expression *Expression::extractLast(Expression *e, Expression **pe0)
{
    if (e->op != TOKcomma)
    {
        *pe0 = NULL;
        return e;
    }

    CommaExp *ce = (CommaExp *)e;
    if (ce->e2->op != TOKcomma)
    {
        *pe0 = ce->e1;
        return ce->e2;
    }
    else
    {
        *pe0 = e;

        Expression **pce = &ce->e2;
        while (((CommaExp *)(*pce))->e2->op == TOKcomma)
        {
            pce = &((CommaExp *)(*pce))->e2;
        }
        assert((*pce)->op == TOKcomma);
        ce = (CommaExp *)(*pce);
        *pce = ce->e1;

        return ce->e2;
    }
}

dinteger_t Expression::toInteger()
{
    //printf("Expression %s\n", Token::toChars(op));
    error("integer constant expression expected instead of %s", toChars());
    return 0;
}

uinteger_t Expression::toUInteger()
{
    //printf("Expression %s\n", Token::toChars(op));
    return (uinteger_t)toInteger();
}

real_t Expression::toReal()
{
    error("floating point constant expression expected instead of %s", toChars());
    return CTFloat::zero;
}

real_t Expression::toImaginary()
{
    error("floating point constant expression expected instead of %s", toChars());
    return CTFloat::zero;
}

complex_t Expression::toComplex()
{
    error("floating point constant expression expected instead of %s", toChars());
    return complex_t(CTFloat::zero);
}

StringExp *Expression::toStringExp()
{
    return NULL;
}

/***************************************
 * Return !=0 if expression is an lvalue.
 */

bool Expression::isLvalue()
{
    return false;
}

/*******************************
 * Give error if we're not an lvalue.
 * If we can, convert expression to be an lvalue.
 */

Expression *Expression::toLvalue(Scope *, Expression *e)
{
    if (!e)
        e = this;
    else if (!loc.filename)
        loc = e->loc;

    if (e->op == TOKtype)
        error("%s '%s' is a type, not an lvalue", e->type->kind(), e->type->toChars());
    else
        error("%s is not an lvalue", e->toChars());

    return new ErrorExp();
}

/***************************************
 * Parameters:
 *      sc:     scope
 *      flag:   1: do not issue error message for invalid modification
 * Returns:
 *      0:      is not modifiable
 *      1:      is modifiable in default == being related to type->isMutable()
 *      2:      is modifiable, because this is a part of initializing.
 */

int Expression::checkModifiable(Scope *, int)
{
    return type ? 1 : 0;    // default modifiable
}

Expression *Expression::modifiableLvalue(Scope *sc, Expression *e)
{
    //printf("Expression::modifiableLvalue() %s, type = %s\n", toChars(), type->toChars());

    // See if this expression is a modifiable lvalue (i.e. not const)
    if (checkModifiable(sc) == 1)
    {
        assert(type);
        if (!type->isMutable())
        {
            error("cannot modify %s expression %s", MODtoChars(type->mod), toChars());
            return new ErrorExp();
        }
        else if (!type->isAssignable())
        {
            error("cannot modify struct %s %s with immutable members", toChars(), type->toChars());
            return new ErrorExp();
        }
    }
    return toLvalue(sc, e);
}

/****************************************
 * Check that the expression has a valid type.
 * If not, generates an error "... has no type".
 * Returns:
 *      true if the expression is not valid.
 * Note:
 *      When this function returns true, `checkValue()` should also return true.
 */
bool Expression::checkType()
{
    return false;
}

/****************************************
 * Check that the expression has a valid value.
 * If not, generates an error "... has no value".
 * Returns:
 *      true if the expression is not valid or has void type.
 */
bool Expression::checkValue()
{
    if (type && type->toBasetype()->ty == Tvoid)
    {
        error("expression %s is void and has no value", toChars());
        //print(); halt();
        if (!global.gag)
            type = Type::terror;
        return true;
    }
    return false;
}

bool Expression::checkScalar()
{
    if (op == TOKerror)
        return true;
    if (type->toBasetype()->ty == Terror)
        return true;
    if (!type->isscalar())
    {
        error("'%s' is not a scalar, it is a %s", toChars(), type->toChars());
        return true;
    }
    return checkValue();
}

bool Expression::checkNoBool()
{
    if (op == TOKerror)
        return true;
    if (type->toBasetype()->ty == Terror)
        return true;
    if (type->toBasetype()->ty == Tbool)
    {
        error("operation not allowed on bool '%s'", toChars());
        return true;
    }
    return false;
}

bool Expression::checkIntegral()
{
    if (op == TOKerror)
        return true;
    if (type->toBasetype()->ty == Terror)
        return true;
    if (!type->isintegral())
    {
        error("'%s' is not of integral type, it is a %s", toChars(), type->toChars());
        return true;
    }
    return checkValue();
}

bool Expression::checkArithmetic()
{
    if (op == TOKerror)
        return true;
    if (type->toBasetype()->ty == Terror)
        return true;
    if (!type->isintegral() && !type->isfloating())
    {
        error("'%s' is not of arithmetic type, it is a %s", toChars(), type->toChars());
        return true;
    }
    return checkValue();
}

void Expression::checkDeprecated(Scope *sc, Dsymbol *s)
{
    s->checkDeprecated(loc, sc);
}

/*********************************************
 * Calling function f.
 * Check the purity, i.e. if we're in a pure function
 * we can only call other pure functions.
 * Returns true if error occurs.
 */
bool Expression::checkPurity(Scope *sc, FuncDeclaration *f)
{
    if (!sc->func)
        return false;
    if (sc->func == f)
        return false;
    if (sc->intypeof == 1)
        return false;
    if (sc->flags & (SCOPEctfe | SCOPEdebug))
        return false;

    /* Given:
     * void f() {
     *   pure void g() {
     *     /+pure+/ void h() {
     *       /+pure+/ void i() { }
     *     }
     *   }
     * }
     * g() can call h() but not f()
     * i() can call h() and g() but not f()
     */

    // Find the closest pure parent of the calling function
    FuncDeclaration *outerfunc = sc->func;
    FuncDeclaration *calledparent = f;

    if (outerfunc->isInstantiated())
    {
        // The attributes of outerfunc should be inferred from the call of f.
    }
    else if (f->isInstantiated())
    {
        // The attributes of f are inferred from its body.
    }
    else if (f->isFuncLiteralDeclaration())
    {
        // The attributes of f are always inferred in its declared place.
    }
    else
    {
        /* Today, static local functions are impure by default, but they cannot
         * violate purity of enclosing functions.
         *
         *  auto foo() pure {      // non instantiated funciton
         *    static auto bar() {  // static, without pure attribute
         *      impureFunc();      // impure call
         *      // Although impureFunc is called inside bar, f(= impureFunc)
         *      // is not callable inside pure outerfunc(= foo <- bar).
         *    }
         *
         *    bar();
         *    // Although bar is called inside foo, f(= bar) is callable
         *    // bacause calledparent(= foo) is same with outerfunc(= foo).
         *  }
         */

        while (outerfunc->toParent2() &&
               outerfunc->isPureBypassingInference() == PUREimpure &&
               outerfunc->toParent2()->isFuncDeclaration())
        {
            outerfunc = outerfunc->toParent2()->isFuncDeclaration();
            if (outerfunc->type->ty == Terror)
                return true;
        }
        while (calledparent->toParent2() &&
               calledparent->isPureBypassingInference() == PUREimpure &&
               calledparent->toParent2()->isFuncDeclaration())
        {
            calledparent = calledparent->toParent2()->isFuncDeclaration();
            if (calledparent->type->ty == Terror)
                return true;
        }
    }

    // If the caller has a pure parent, then either the called func must be pure,
    // OR, they must have the same pure parent.
    if (!f->isPure() && calledparent != outerfunc)
    {
        FuncDeclaration *ff = outerfunc;
        if (sc->flags & SCOPEcompile ? ff->isPureBypassingInference() >= PUREweak : ff->setImpure())
        {
            error("pure %s '%s' cannot call impure %s '%s'",
                ff->kind(), ff->toPrettyChars(), f->kind(), f->toPrettyChars());
            return true;
        }
    }
    return false;
}

/*******************************************
 * Accessing variable v.
 * Check for purity and safety violations.
 * Returns true if error occurs.
 */
bool Expression::checkPurity(Scope *sc, VarDeclaration *v)
{
    //printf("v = %s %s\n", v->type->toChars(), v->toChars());

    /* Look for purity and safety violations when accessing variable v
     * from current function.
     */
    if (!sc->func)
        return false;
    if (sc->intypeof == 1)
        return false;   // allow violations inside typeof(expression)
    if (sc->flags & (SCOPEctfe | SCOPEdebug))
        return false;   // allow violations inside compile-time evaluated expressions and debug conditionals
    if (v->ident == Id::ctfe)
        return false;   // magic variable never violates pure and safe
    if (v->isImmutable())
        return false;   // always safe and pure to access immutables...
    if (v->isConst() && !v->isRef() && (v->isDataseg() || v->isParameter()) &&
        v->type->implicitConvTo(v->type->immutableOf()))
        return false;   // or const global/parameter values which have no mutable indirections
    if (v->storage_class & STCmanifest)
        return false;   // ...or manifest constants

    bool err = false;
    if (v->isDataseg())
    {
        // Bugzilla 7533: Accessing implicit generated __gate is pure.
        if (v->ident == Id::gate)
            return false;

        /* Accessing global mutable state.
         * Therefore, this function and all its immediately enclosing
         * functions must be pure.
         */
        /* Today, static local functions are impure by default, but they cannot
         * violate purity of enclosing functions.
         *
         *  auto foo() pure {      // non instantiated funciton
         *    static auto bar() {  // static, without pure attribute
         *      globalData++;      // impure access
         *      // Although globalData is accessed inside bar,
         *      // it is not accessible inside pure foo.
         *    }
         *  }
         */
        for (Dsymbol *s = sc->func; s; s = s->toParent2())
        {
            FuncDeclaration *ff = s->isFuncDeclaration();
            if (!ff)
                break;
            if (sc->flags & SCOPEcompile ? ff->isPureBypassingInference() >= PUREweak : ff->setImpure())
            {
                error("pure %s '%s' cannot access mutable static data '%s'",
                    ff->kind(), ff->toPrettyChars(), v->toChars());
                err = true;
                break;
            }
            /* If the enclosing is an instantiated function or a lambda, its
             * attribute inference result is preferred.
             */
            if (ff->isInstantiated())
                break;
            if (ff->isFuncLiteralDeclaration())
                break;
        }
    }
    else
    {
        /* Given:
         * void f() {
         *   int fx;
         *   pure void g() {
         *     int gx;
         *     /+pure+/ void h() {
         *       int hx;
         *       /+pure+/ void i() { }
         *     }
         *   }
         * }
         * i() can modify hx and gx but not fx
         */

        Dsymbol *vparent = v->toParent2();
        for (Dsymbol *s = sc->func; !err && s; s = s->toParent2())
        {
            if (s == vparent)
                break;

            if (AggregateDeclaration *ad = s->isAggregateDeclaration())
            {
                if (ad->isNested())
                    continue;
                break;
            }
            FuncDeclaration *ff = s->isFuncDeclaration();
            if (!ff)
                break;
            if (ff->isNested() || ff->isThis())
            {
                if (ff->type->isImmutable() ||
                    (ff->type->isShared() && !MODimplicitConv(ff->type->mod, v->type->mod)))
                {
                    OutBuffer ffbuf;
                    OutBuffer vbuf;
                    MODMatchToBuffer(&ffbuf, ff->type->mod, v->type->mod);
                    MODMatchToBuffer(&vbuf, v->type->mod, ff->type->mod);
                    error("%s%s '%s' cannot access %sdata '%s'",
                        ffbuf.peekString(), ff->kind(), ff->toPrettyChars(), vbuf.peekString(), v->toChars());
                    err = true;
                    break;
                }
                continue;
            }
            break;
        }
    }

    /* Do not allow safe functions to access __gshared data
     */
    if (v->storage_class & STCgshared)
    {
        if (sc->func->setUnsafe())
        {
            error("safe %s '%s' cannot access __gshared data '%s'",
                sc->func->kind(), sc->func->toChars(), v->toChars());
            err = true;
        }
    }

    return err;
}

/*********************************************
 * Calling function f.
 * Check the safety, i.e. if we're in a @safe function
 * we can only call @safe or @trusted functions.
 * Returns true if error occurs.
 */
bool Expression::checkSafety(Scope *sc, FuncDeclaration *f)
{
    if (!sc->func)
        return false;
    if (sc->func == f)
        return false;
    if (sc->intypeof == 1)
        return false;
    if (sc->flags & SCOPEctfe)
        return false;

    if (!f->isSafe() && !f->isTrusted())
    {
        if (sc->flags & SCOPEcompile ? sc->func->isSafeBypassingInference() : sc->func->setUnsafe())
        {
            if (loc.linnum == 0)  // e.g. implicitly generated dtor
                loc = sc->func->loc;

            error("@safe %s '%s' cannot call @system %s '%s'",
                sc->func->kind(), sc->func->toPrettyChars(), f->kind(), f->toPrettyChars());
            return true;
        }
    }
    return false;
}

/*********************************************
 * Calling function f.
 * Check the @nogc-ness, i.e. if we're in a @nogc function
 * we can only call other @nogc functions.
 * Returns true if error occurs.
 */
bool Expression::checkNogc(Scope *sc, FuncDeclaration *f)
{
    if (!sc->func)
        return false;
    if (sc->func == f)
        return false;
    if (sc->intypeof == 1)
        return false;
    if (sc->flags & SCOPEctfe)
        return false;

    if (!f->isNogc())
    {
        if (sc->flags & SCOPEcompile ? sc->func->isNogcBypassingInference() : sc->func->setGC())
        {
            if (loc.linnum == 0)  // e.g. implicitly generated dtor
                loc = sc->func->loc;

            error("@nogc %s '%s' cannot call non-@nogc %s '%s'",
                sc->func->kind(), sc->func->toPrettyChars(), f->kind(), f->toPrettyChars());
            return true;
        }
    }
    return false;
}

/********************************************
 * Check that the postblit is callable if t is an array of structs.
 * Returns true if error happens.
 */
bool Expression::checkPostblit(Scope *sc, Type *t)
{
    t = t->baseElemOf();
    if (t->ty == Tstruct)
    {
        if (global.params.useTypeInfo)
        {
            // Bugzilla 11395: Require TypeInfo generation for array concatenation
            semanticTypeInfo(sc, t);
        }

        StructDeclaration *sd = ((TypeStruct *)t)->sym;
        if (sd->postblit)
        {
            if (sd->postblit->storage_class & STCdisable)
            {
                sd->error(loc, "is not copyable because it is annotated with @disable");
                return true;
            }
            //checkDeprecated(sc, sd->postblit);        // necessary?
            checkPurity(sc, sd->postblit);
            checkSafety(sc, sd->postblit);
            checkNogc(sc, sd->postblit);
            //checkAccess(sd, loc, sc, sd->postblit);   // necessary?
            return false;
        }
    }
    return false;
}

bool Expression::checkRightThis(Scope *sc)
{
    if (op == TOKerror)
        return true;
    if (op == TOKvar && type->ty != Terror)
    {
        VarExp *ve = (VarExp *)this;
        if (isNeedThisScope(sc, ve->var))
        {
            //printf("checkRightThis sc->intypeof = %d, ad = %p, func = %p, fdthis = %p\n",
            //        sc->intypeof, sc->getStructClassScope(), func, fdthis);
            error("need 'this' for '%s' of type '%s'", ve->var->toChars(), ve->var->type->toChars());
            return true;
        }
    }
    return false;
}

/*******************************
 * Check whether the expression allows RMW operations, error with rmw operator diagnostic if not.
 * ex is the RHS expression, or NULL if ++/-- is used (for diagnostics)
 * Returns true if error occurs.
 */
bool Expression::checkReadModifyWrite(TOK rmwOp, Expression *ex)
{
    //printf("Expression::checkReadModifyWrite() %s %s", toChars(), ex ? ex->toChars() : "");
    if (!type || !type->isShared())
        return false;

    // atomicOp uses opAssign (+=/-=) rather than opOp (++/--) for the CT string literal.
    switch (rmwOp)
    {
        case TOKplusplus:
        case TOKpreplusplus:
            rmwOp = TOKaddass;
            break;

        case TOKminusminus:
        case TOKpreminusminus:
            rmwOp = TOKminass;
            break;

        default:
            break;
    }

    deprecation("read-modify-write operations are not allowed for shared variables. "
                "Use core.atomic.atomicOp!\"%s\"(%s, %s) instead.",
                Token::tochars[rmwOp], toChars(), ex ? ex->toChars() : "1");
    return false;

    // note: enable when deprecation becomes an error.
    // return true;
}

/*****************************
 * If expression can be tested for true or false,
 * returns the modified expression.
 * Otherwise returns ErrorExp.
 */
Expression *Expression::toBoolean(Scope *sc)
{
    // Default is 'yes' - do nothing
    Expression *e = this;
    Type *t = type;
    Type *tb = type->toBasetype();
    Type *att = NULL;
Lagain:
    // Structs can be converted to bool using opCast(bool)()
    if (tb->ty == Tstruct)
    {
        AggregateDeclaration *ad = ((TypeStruct *)tb)->sym;
        /* Don't really need to check for opCast first, but by doing so we
         * get better error messages if it isn't there.
         */
        Dsymbol *fd = search_function(ad, Id::_cast);
        if (fd)
        {
            e = new CastExp(loc, e, Type::tbool);
            e = semantic(e, sc);
            return e;
        }

        // Forward to aliasthis.
        if (ad->aliasthis && tb != att)
        {
            if (!att && tb->checkAliasThisRec())
                att = tb;
            e = resolveAliasThis(sc, e);
            t = e->type;
            tb = e->type->toBasetype();
            goto Lagain;
        }
    }

    if (!t->isBoolean())
    {
        if (tb != Type::terror)
            error("expression %s of type %s does not have a boolean value", toChars(), t->toChars());
        return new ErrorExp();
    }
    return e;
}

/******************************
 * Take address of expression.
 */

Expression *Expression::addressOf()
{
    //printf("Expression::addressOf()\n");
    Expression *e = new AddrExp(loc, this);
    e->type = type->pointerTo();
    return e;
}

/******************************
 * If this is a reference, dereference it.
 */

Expression *Expression::deref()
{
    //printf("Expression::deref()\n");
    // type could be null if forward referencing an 'auto' variable
    if (type && type->ty == Treference)
    {
        Expression *e = new PtrExp(loc, this);
        e->type = ((TypeReference *)type)->next;
        return e;
    }
    return this;
}

/********************************
 * Does this expression statically evaluate to a boolean 'result' (true or false)?
 */
bool Expression::isBool(bool)
{
    return false;
}

/****************************************
 * Resolve __FILE__, __LINE__, __MODULE__, __FUNCTION__, __PRETTY_FUNCTION__ to loc.
 */

Expression *Expression::resolveLoc(Loc, Scope *)
{
    return this;
}

Expressions *Expression::arraySyntaxCopy(Expressions *exps)
{
    Expressions *a = NULL;
    if (exps)
    {
        a = new Expressions();
        a->setDim(exps->dim);
        for (size_t i = 0; i < a->dim; i++)
        {
            Expression *e = (*exps)[i];
            (*a)[i] = e ? e->syntaxCopy() : NULL;
        }
    }
    return a;
}

/************************************************
 * Destructors are attached to VarDeclarations.
 * Hence, if expression returns a temp that needs a destructor,
 * make sure and create a VarDeclaration for that temp.
 */

Expression *Expression::addDtorHook(Scope *)
{
    return this;
}

/******************************** IntegerExp **************************/

IntegerExp::IntegerExp(Loc loc, dinteger_t value, Type *type)
        : Expression(loc, TOKint64, sizeof(IntegerExp))
{
    //printf("IntegerExp(value = %lld, type = '%s')\n", value, type ? type->toChars() : "");
    assert(type);
    if (!type->isscalar())
    {
        //printf("%s, loc = %d\n", toChars(), loc.linnum);
        if (type->ty != Terror)
            error("integral constant must be scalar type, not %s", type->toChars());
        type = Type::terror;
    }
    this->type = type;
    setInteger(value);
}

IntegerExp::IntegerExp(dinteger_t value)
        : Expression(Loc(), TOKint64, sizeof(IntegerExp))
{
    this->type = Type::tint32;
    this->value = (d_int32) value;
}

IntegerExp *IntegerExp::create(Loc loc, dinteger_t value, Type *type)
{
    return new IntegerExp(loc, value, type);
}

bool IntegerExp::equals(RootObject *o)
{
    if (this == o)
        return true;
    if (((Expression *)o)->op == TOKint64)
    {
        IntegerExp *ne = (IntegerExp *)o;
        if (type->toHeadMutable()->equals(ne->type->toHeadMutable()) &&
            value == ne->value)
        {
            return true;
        }
    }
    return false;
}

void IntegerExp::setInteger(dinteger_t value)
{
    this->value = value;
    normalize();
}

void IntegerExp::normalize()
{
    /* 'Normalize' the value of the integer to be in range of the type
     */
    switch (type->toBasetype()->ty)
    {
        case Tbool:         value = (value != 0);           break;
        case Tint8:         value = (d_int8)  value;        break;
        case Tchar:
        case Tuns8:         value = (d_uns8)  value;        break;
        case Tint16:        value = (d_int16) value;        break;
        case Twchar:
        case Tuns16:        value = (d_uns16) value;        break;
        case Tint32:        value = (d_int32) value;        break;
        case Tdchar:
        case Tuns32:        value = (d_uns32) value;        break;
        case Tint64:        value = (d_int64) value;        break;
        case Tuns64:        value = (d_uns64) value;        break;
        case Tpointer:
            if (Target::ptrsize == 4)
                value = (d_uns32) value;
            else if (Target::ptrsize == 8)
                value = (d_uns64) value;
            else
                assert(0);
            break;
        default:
            break;
    }
}

dinteger_t IntegerExp::toInteger()
{
    normalize();   // necessary until we fix all the paints of 'type'
    return value;
}

real_t IntegerExp::toReal()
{
    normalize();   // necessary until we fix all the paints of 'type'
    Type *t = type->toBasetype();
    if (t->ty == Tuns64)
        return ldouble((d_uns64)value);
    else
        return ldouble((d_int64)value);
}

real_t IntegerExp::toImaginary()
{
    return CTFloat::zero;
}

complex_t IntegerExp::toComplex()
{
    return (complex_t)toReal();
}

bool IntegerExp::isBool(bool result)
{
    bool r = toInteger() != 0;
    return result ? r : !r;
}

Expression *IntegerExp::toLvalue(Scope *, Expression *e)
{
    if (!e)
        e = this;
    else if (!loc.filename)
        loc = e->loc;
    e->error("constant %s is not an lvalue", e->toChars());
    return new ErrorExp();
}

/******************************** ErrorExp **************************/

/* Use this expression for error recovery.
 * It should behave as a 'sink' to prevent further cascaded error messages.
 */

ErrorExp::ErrorExp()
    : Expression(Loc(), TOKerror, sizeof(ErrorExp))
{
    type = Type::terror;
}

Expression *ErrorExp::toLvalue(Scope *, Expression *)
{
    return this;
}

/******************************** RealExp **************************/

RealExp::RealExp(Loc loc, real_t value, Type *type)
        : Expression(loc, TOKfloat64, sizeof(RealExp))
{
    //printf("RealExp::RealExp(%Lg)\n", value);
    this->value = value;
    this->type = type;
}

RealExp *RealExp::create(Loc loc, real_t value, Type *type)
{
    return new RealExp(loc, value,type);
}

dinteger_t RealExp::toInteger()
{
    return (sinteger_t) toReal();
}

uinteger_t RealExp::toUInteger()
{
    return (uinteger_t) toReal();
}

real_t RealExp::toReal()
{
    return type->isreal() ? value : CTFloat::zero;
}

real_t RealExp::toImaginary()
{
    return type->isreal() ? CTFloat::zero : value;
}

complex_t RealExp::toComplex()
{
    return complex_t(toReal(), toImaginary());
}

/********************************
 * Test to see if two reals are the same.
 * Regard NaN's as equivalent.
 * Regard +0 and -0 as different.
 */

int RealEquals(real_t x1, real_t x2)
{
    return (CTFloat::isNaN(x1) && CTFloat::isNaN(x2)) ||
        CTFloat::isIdentical(x1, x2);
}

bool RealExp::equals(RootObject *o)
{
    if (this == o)
        return true;
    if (((Expression *)o)->op == TOKfloat64)
    {
        RealExp *ne = (RealExp *)o;
        if (type->toHeadMutable()->equals(ne->type->toHeadMutable()) &&
            RealEquals(value, ne->value))
        {
            return true;
        }
    }
    return false;
}

bool RealExp::isBool(bool result)
{
    return result ? (bool)value : !(bool)value;
}

/******************************** ComplexExp **************************/

ComplexExp::ComplexExp(Loc loc, complex_t value, Type *type)
        : Expression(loc, TOKcomplex80, sizeof(ComplexExp)), value(value)
{
    this->type = type;
    //printf("ComplexExp::ComplexExp(%s)\n", toChars());
}

ComplexExp *ComplexExp::create(Loc loc, complex_t value, Type *type)
{
    return new ComplexExp(loc, value, type);
}

dinteger_t ComplexExp::toInteger()
{
    return (sinteger_t) toReal();
}

uinteger_t ComplexExp::toUInteger()
{
    return (uinteger_t) toReal();
}

real_t ComplexExp::toReal()
{
    return creall(value);
}

real_t ComplexExp::toImaginary()
{
    return cimagl(value);
}

complex_t ComplexExp::toComplex()
{
    return value;
}

bool ComplexExp::equals(RootObject *o)
{
    if (this == o)
        return true;
    if (((Expression *)o)->op == TOKcomplex80)
    {
        ComplexExp *ne = (ComplexExp *)o;
        if (type->toHeadMutable()->equals(ne->type->toHeadMutable()) &&
            RealEquals(creall(value), creall(ne->value)) &&
            RealEquals(cimagl(value), cimagl(ne->value)))
        {
            return true;
        }
    }
    return false;
}

bool ComplexExp::isBool(bool result)
{
    if (result)
        return (bool)(value);
    else
        return !value;
}

/******************************** IdentifierExp **************************/

IdentifierExp::IdentifierExp(Loc loc, Identifier *ident)
        : Expression(loc, TOKidentifier, sizeof(IdentifierExp))
{
    this->ident = ident;
}

IdentifierExp *IdentifierExp::create(Loc loc, Identifier *ident)
{
    return new IdentifierExp(loc, ident);
}

bool IdentifierExp::isLvalue()
{
    return true;
}

Expression *IdentifierExp::toLvalue(Scope *, Expression *)
{
    return this;
}

/******************************** DollarExp **************************/

DollarExp::DollarExp(Loc loc)
        : IdentifierExp(loc, Id::dollar)
{
}

/******************************** DsymbolExp **************************/

DsymbolExp::DsymbolExp(Loc loc, Dsymbol *s, bool hasOverloads)
        : Expression(loc, TOKdsymbol, sizeof(DsymbolExp))
{
    this->s = s;
    this->hasOverloads = hasOverloads;
}

/****************************************
 * Resolve a symbol `s` and wraps it in an expression object.
 * Params:
 *      hasOverloads = works if the aliased symbol is a function.
 *          true:  it's overloaded and will be resolved later.
 *          false: it's exact function symbol.
 */
Expression *resolve(Loc loc, Scope *sc, Dsymbol *s, bool hasOverloads)
{
Lagain:
    Expression *e;

    //printf("DsymbolExp:: %p '%s' is a symbol\n", this, toChars());
    //printf("s = '%s', s->kind = '%s'\n", s->toChars(), s->kind());
    Dsymbol *olds = s;
    Declaration *d = s->isDeclaration();
    if (d && (d->storage_class & STCtemplateparameter))
    {
        s = s->toAlias();
    }
    else
    {
        if (!s->isFuncDeclaration())        // functions are checked after overloading
            s->checkDeprecated(loc, sc);

        // Bugzilla 12023: if 's' is a tuple variable, the tuple is returned.
        s = s->toAlias();

        //printf("s = '%s', s->kind = '%s', s->needThis() = %p\n", s->toChars(), s->kind(), s->needThis());
        if (s != olds && !s->isFuncDeclaration())
            s->checkDeprecated(loc, sc);
    }

    if (EnumMember *em = s->isEnumMember())
    {
        return em->getVarExp(loc, sc);
    }
    if (VarDeclaration *v = s->isVarDeclaration())
    {
        //printf("Identifier '%s' is a variable, type '%s'\n", toChars(), v->type->toChars());
        if (!v->type ||                    // during variable type inference
            (!v->type->deco && v->inuse))  // during variable type semantic
        {
            if (v->inuse)    // variable type depends on the variable itself
                ::error(loc, "circular reference to %s '%s'", v->kind(), v->toPrettyChars());
            else             // variable type cannot be determined
                ::error(loc, "forward reference to %s '%s'", v->kind(), v->toPrettyChars());
            return new ErrorExp();
        }
        if (v->type->ty == Terror)
            return new ErrorExp();

        if ((v->storage_class & STCmanifest) && v->_init)
        {
            if (v->inuse)
            {
                ::error(loc, "circular initialization of %s '%s'", v->kind(), v->toPrettyChars());
                return new ErrorExp();
            }

            e = v->expandInitializer(loc);
            v->inuse++;
            e = semantic(e, sc);
            v->inuse--;
            return e;
        }

        // Change the ancestor lambdas to delegate before hasThis(sc) call.
        if (v->checkNestedReference(sc, loc))
            return new ErrorExp();

        if (v->needThis() && hasThis(sc))
            e = new DotVarExp(loc, new ThisExp(loc), v);
        else
            e = new VarExp(loc, v);
        e = semantic(e, sc);
        return e;
    }
    if (FuncLiteralDeclaration *fld = s->isFuncLiteralDeclaration())
    {
        //printf("'%s' is a function literal\n", fld->toChars());
        e = new FuncExp(loc, fld);
        return semantic(e, sc);
    }
    if (FuncDeclaration *f = s->isFuncDeclaration())
    {
        f = f->toAliasFunc();
        if (!f->functionSemantic())
            return new ErrorExp();

        if (!hasOverloads && f->checkForwardRef(loc))
            return new ErrorExp();

        FuncDeclaration *fd = s->isFuncDeclaration();
        fd->type = f->type;
        return new VarExp(loc, fd, hasOverloads);
    }
    if (OverDeclaration *od = s->isOverDeclaration())
    {
        e = new VarExp(loc, od, true);
        e->type = Type::tvoid;
        return e;
    }
    if (OverloadSet *o = s->isOverloadSet())
    {
        //printf("'%s' is an overload set\n", o->toChars());
        return new OverExp(loc, o);
    }

    if (Import *imp = s->isImport())
    {
        if (!imp->pkg)
        {
            ::error(loc, "forward reference of import %s", imp->toChars());
            return new ErrorExp();
        }
        ScopeExp *ie = new ScopeExp(loc, imp->pkg);
        return semantic(ie, sc);
    }
    if (Package *pkg = s->isPackage())
    {
        ScopeExp *ie = new ScopeExp(loc, pkg);
        return semantic(ie, sc);
    }
    if (Module *mod = s->isModule())
    {
        ScopeExp *ie = new ScopeExp(loc, mod);
        return semantic(ie, sc);
    }

    if (Nspace *ns = s->isNspace())
    {
        ScopeExp *ie = new ScopeExp(loc, ns);
        return semantic(ie, sc);
    }

    if (Type *t = s->getType())
    {
        return semantic(new TypeExp(loc, t), sc);
    }

    if (TupleDeclaration *tup = s->isTupleDeclaration())
    {
        if (tup->needThis() && hasThis(sc))
            e = new DotVarExp(loc, new ThisExp(loc), tup);
        else
            e = new TupleExp(loc, tup);
        e = semantic(e, sc);
        return e;
    }

    if (TemplateInstance *ti = s->isTemplateInstance())
    {
        ti->semantic(sc);
        if (!ti->inst || ti->errors)
            return new ErrorExp();
        s = ti->toAlias();
        if (!s->isTemplateInstance())
            goto Lagain;
        e = new ScopeExp(loc, ti);
        e = semantic(e, sc);
        return e;
    }
    if (TemplateDeclaration *td = s->isTemplateDeclaration())
    {
        Dsymbol *p = td->toParent2();
        FuncDeclaration *fdthis = hasThis(sc);
        AggregateDeclaration *ad = p ? p->isAggregateDeclaration() : NULL;
        if (fdthis && ad && isAggregate(fdthis->vthis->type) == ad &&
            (td->_scope->stc & STCstatic) == 0)
        {
            e = new DotTemplateExp(loc, new ThisExp(loc), td);
        }
        else
            e = new TemplateExp(loc, td);
        e = semantic(e, sc);
        return e;
    }

    ::error(loc, "%s '%s' is not a variable", s->kind(), s->toChars());
    return new ErrorExp();
}

bool DsymbolExp::isLvalue()
{
    return true;
}

Expression *DsymbolExp::toLvalue(Scope *, Expression *)
{
    return this;
}

/******************************** ThisExp **************************/

ThisExp::ThisExp(Loc loc)
        : Expression(loc, TOKthis, sizeof(ThisExp))
{
    //printf("ThisExp::ThisExp() loc = %d\n", loc.linnum);
    var = NULL;
}

bool ThisExp::isBool(bool result)
{
    return result ? true : false;
}

bool ThisExp::isLvalue()
{
    // Class `this` should be an rvalue; struct `this` should be an lvalue.
    return type->toBasetype()->ty != Tclass;
}

Expression *ThisExp::toLvalue(Scope *sc, Expression *e)
{
    if (type->toBasetype()->ty == Tclass)
    {
        // Class `this` is an rvalue; struct `this` is an lvalue.
        return Expression::toLvalue(sc, e);
    }
    return this;
}

/******************************** SuperExp **************************/

SuperExp::SuperExp(Loc loc)
        : ThisExp(loc)
{
    op = TOKsuper;
}

/******************************** NullExp **************************/

NullExp::NullExp(Loc loc, Type *type)
        : Expression(loc, TOKnull, sizeof(NullExp))
{
    committed = 0;
    this->type = type;
}

bool NullExp::equals(RootObject *o)
{
    if (o && o->dyncast() == DYNCAST_EXPRESSION)
    {
        Expression *e = (Expression *)o;
        if (e->op == TOKnull &&
            type->equals(e->type))
        {
            return true;
        }
    }
    return false;
}

bool NullExp::isBool(bool result)
{
    return result ? false : true;
}

StringExp *NullExp::toStringExp()
{
    if (implicitConvTo(Type::tstring))
    {
        StringExp *se = new StringExp(loc, (char*)mem.xcalloc(1, 1), 0);
        se->type = Type::tstring;
        return se;
    }
    return NULL;
}

/******************************** StringExp **************************/

StringExp::StringExp(Loc loc, char *string)
        : Expression(loc, TOKstring, sizeof(StringExp))
{
    this->string = string;
    this->len = strlen(string);
    this->sz = 1;
    this->committed = 0;
    this->postfix = 0;
    this->ownedByCtfe = OWNEDcode;
}

StringExp::StringExp(Loc loc, void *string, size_t len)
        : Expression(loc, TOKstring, sizeof(StringExp))
{
    this->string = string;
    this->len = len;
    this->sz = 1;
    this->committed = 0;
    this->postfix = 0;
    this->ownedByCtfe = OWNEDcode;
}

StringExp::StringExp(Loc loc, void *string, size_t len, utf8_t postfix)
        : Expression(loc, TOKstring, sizeof(StringExp))
{
    this->string = string;
    this->len = len;
    this->sz = 1;
    this->committed = 0;
    this->postfix = postfix;
    this->ownedByCtfe = OWNEDcode;
}

StringExp *StringExp::create(Loc loc, char *s)
{
    return new StringExp(loc, s);
}

StringExp *StringExp::create(Loc loc, void *string, size_t len)
{
    return new StringExp(loc, string, len);
}

bool StringExp::equals(RootObject *o)
{
    //printf("StringExp::equals('%s') %s\n", o->toChars(), toChars());
    if (o && o->dyncast() == DYNCAST_EXPRESSION)
    {
        Expression *e = (Expression *)o;
        if (e->op == TOKstring)
        {
            return compare(o) == 0;
        }
    }
    return false;
}

/**********************************
 * Return the number of code units the string would be if it were re-encoded
 * as tynto.
 * Params:
 *      tynto = code unit type of the target encoding
 * Returns:
 *      number of code units
 */

size_t StringExp::numberOfCodeUnits(int tynto) const
{
    int encSize;
    switch (tynto)
    {
        case 0:      return len;
        case Tchar:  encSize = 1; break;
        case Twchar: encSize = 2; break;
        case Tdchar: encSize = 4; break;
        default:
            assert(0);
    }
    if (sz == encSize)
        return len;

    size_t result = 0;
    dchar_t c;

    switch (sz)
    {
        case 1:
            for (size_t u = 0; u < len;)
            {
                if (const char *p = utf_decodeChar((utf8_t *)string, len, &u, &c))
                {
                    error("%s", p);
                    return 0;
                }
                result += utf_codeLength(encSize, c);
            }
            break;

        case 2:
            for (size_t u = 0; u < len;)
            {
                if (const char *p = utf_decodeWchar((utf16_t *)string, len, &u, &c))
                {
                    error("%s", p);
                    return 0;
                }
                result += utf_codeLength(encSize, c);
            }
            break;

        case 4:
            for (size_t u = 0; u < len;)
            {
                c = *((utf32_t *)((char *)string + u));
                u += 4;
                result += utf_codeLength(encSize, c);
            }
            break;

        default:
            assert(0);
    }
    return result;
}

/**********************************************
 * Write the contents of the string to dest.
 * Use numberOfCodeUnits() to determine size of result.
 * Params:
 *  dest = destination
 *  tyto = encoding type of the result
 *  zero = add terminating 0
 */
void StringExp::writeTo(void *dest, bool zero, int tyto) const
{
    int encSize;
    switch (tyto)
    {
        case 0:      encSize = sz; break;
        case Tchar:  encSize = 1; break;
        case Twchar: encSize = 2; break;
        case Tdchar: encSize = 4; break;
        default:
            assert(0);
    }
    if (sz == encSize)
    {
        memcpy(dest, string, len * sz);
        if (zero)
            memset((char *)dest + len * sz, 0, sz);
    }
    else
        assert(0);
}

/**************************************************
 * If the string data is UTF-8 and can be accessed directly,
 * return a pointer to it.
 * Do not assume a terminating 0.
 * Returns:
 *  pointer to string data if possible, null if not
 */
char *StringExp::toPtr()
{
    return (sz == 1) ? (char*)string : NULL;
}

StringExp *StringExp::toStringExp()
{
    return this;
}

/****************************************
 * Convert string to char[].
 */

StringExp *StringExp::toUTF8(Scope *sc)
{
    if (sz != 1)
    {   // Convert to UTF-8 string
        committed = 0;
        Expression *e = castTo(sc, Type::tchar->arrayOf());
        e = e->optimize(WANTvalue);
        assert(e->op == TOKstring);
        StringExp *se = (StringExp *)e;
        assert(se->sz == 1);
        return se;
    }
    return this;
}

int StringExp::compare(RootObject *obj)
{
    //printf("StringExp::compare()\n");
    // Used to sort case statement expressions so we can do an efficient lookup
    StringExp *se2 = (StringExp *)(obj);

    // This is a kludge so isExpression() in template.c will return 5
    // for StringExp's.
    if (!se2)
        return 5;

    assert(se2->op == TOKstring);

    size_t len1 = len;
    size_t len2 = se2->len;

    //printf("sz = %d, len1 = %d, len2 = %d\n", sz, (int)len1, (int)len2);
    if (len1 == len2)
    {
        switch (sz)
        {
            case 1:
                return memcmp((char *)string, (char *)se2->string, len1);

            case 2:
            {
                d_uns16 *s1 = (d_uns16 *)string;
                d_uns16 *s2 = (d_uns16 *)se2->string;

                for (size_t u = 0; u < len; u++)
                {
                    if (s1[u] != s2[u])
                        return s1[u] - s2[u];
                }
            }
            break;

            case 4:
            {
                d_uns32 *s1 = (d_uns32 *)string;
                d_uns32 *s2 = (d_uns32 *)se2->string;

                for (size_t u = 0; u < len; u++)
                {
                    if (s1[u] != s2[u])
                        return s1[u] - s2[u];
                }
            }
            break;

            default:
                assert(0);
        }
    }
    return (int)(len1 - len2);
}

bool StringExp::isBool(bool result)
{
    return result ? true : false;
}


bool StringExp::isLvalue()
{
    /* string literal is rvalue in default, but
     * conversion to reference of static array is only allowed.
     */
    return (type && type->toBasetype()->ty == Tsarray);
}

Expression *StringExp::toLvalue(Scope *sc, Expression *e)
{
    //printf("StringExp::toLvalue(%s) type = %s\n", toChars(), type ? type->toChars() : NULL);
    return (type && type->toBasetype()->ty == Tsarray)
            ? this : Expression::toLvalue(sc, e);
}

Expression *StringExp::modifiableLvalue(Scope *, Expression *)
{
    error("cannot modify string literal %s", toChars());
    return new ErrorExp();
}

unsigned StringExp::charAt(uinteger_t i) const
{   unsigned value;

    switch (sz)
    {
        case 1:
            value = ((utf8_t *)string)[(size_t)i];
            break;

        case 2:
            value = ((unsigned short *)string)[(size_t)i];
            break;

        case 4:
            value = ((unsigned int *)string)[(size_t)i];
            break;

        default:
            assert(0);
            break;
    }
    return value;
}

/************************ ArrayLiteralExp ************************************/

// [ e1, e2, e3, ... ]

ArrayLiteralExp::ArrayLiteralExp(Loc loc, Type *type, Expressions *elements)
    : Expression(loc, TOKarrayliteral, sizeof(ArrayLiteralExp))
{
    this->basis = NULL;
    this->type = type;
    this->elements = elements;
    this->ownedByCtfe = OWNEDcode;
}

ArrayLiteralExp::ArrayLiteralExp(Loc loc, Type *type, Expression *e)
    : Expression(loc, TOKarrayliteral, sizeof(ArrayLiteralExp))
{
    this->basis = NULL;
    this->type = type;
    elements = new Expressions;
    elements->push(e);
    this->ownedByCtfe = OWNEDcode;
}

ArrayLiteralExp::ArrayLiteralExp(Loc loc, Type *type, Expression *basis, Expressions *elements)
    : Expression(loc, TOKarrayliteral, sizeof(ArrayLiteralExp))
{
    this->basis = basis;
    this->type = type;
    this->elements = elements;
    this->ownedByCtfe = OWNEDcode;
}

ArrayLiteralExp *ArrayLiteralExp::create(Loc loc, Expressions *elements)
{
    return new ArrayLiteralExp(loc, NULL, elements);
}

bool ArrayLiteralExp::equals(RootObject *o)
{
    if (this == o)
        return true;
    if (o && o->dyncast() == DYNCAST_EXPRESSION &&
        ((Expression *)o)->op == TOKarrayliteral)
    {
        ArrayLiteralExp *ae = (ArrayLiteralExp *)o;
        if (elements->dim != ae->elements->dim)
            return false;
        if (elements->dim == 0 &&
            !type->equals(ae->type))
        {
            return false;
        }
        for (size_t i = 0; i < elements->dim; i++)
        {
            Expression *e1 = (*elements)[i];
            Expression *e2 = (*ae->elements)[i];
            if (!e1)
                e1 = basis;
            if (!e2)
                e2 = basis;
            if (e1 != e2 &&
                (!e1 || !e2 || !e1->equals(e2)))
                return false;
        }
        return true;
    }
    return false;
}

Expression *ArrayLiteralExp::syntaxCopy()
{
    return new ArrayLiteralExp(loc,
        NULL,
        basis ? basis->syntaxCopy() : NULL,
        arraySyntaxCopy(elements));
}

Expression *ArrayLiteralExp::getElement(d_size_t i)
{
    Expression *el = (*elements)[i];
    if (!el)
        el = basis;
    return el;
}

static void appendArrayLiteral(Expressions *elems, ArrayLiteralExp *ale)
{
    if (!ale->elements)
        return;
    size_t d = elems->dim;
    elems->append(ale->elements);
    for (size_t i = d; i < elems->dim; i++)
    {
        Expression *el = (*elems)[i];
        if (!el)
            (*elems)[i] = ale->basis;
    }
}

/* Copy element `Expressions` in the parameters when they're `ArrayLiteralExp`s.
 * Params:
 *      e1  = If it's ArrayLiteralExp, its `elements` will be copied.
 *            Otherwise, `e1` itself will be pushed into the new `Expressions`.
 *      e2  = If it's not `null`, it will be pushed/appended to the new
 *            `Expressions` by the same way with `e1`.
 * Returns:
 *      Newly allocated `Expressions`. Note that it points to the original
 *      `Expression` values in e1 and e2.
 */
Expressions* ArrayLiteralExp::copyElements(Expression *e1, Expression *e2)
{
    Expressions *elems = new Expressions();

    if (e1->op == TOKarrayliteral)
        appendArrayLiteral(elems, (ArrayLiteralExp *)e1);
    else
        elems->push(e1);

    if (e2)
    {
        if (e2->op == TOKarrayliteral)
            appendArrayLiteral(elems, (ArrayLiteralExp *)e2);
        else
            elems->push(e2);
    }

    return elems;
}

bool ArrayLiteralExp::isBool(bool result)
{
    size_t dim = elements ? elements->dim : 0;
    return result ? (dim != 0) : (dim == 0);
}

StringExp *ArrayLiteralExp::toStringExp()
{
    TY telem = type->nextOf()->toBasetype()->ty;

    if (telem == Tchar || telem == Twchar || telem == Tdchar ||
        (telem == Tvoid && (!elements || elements->dim == 0)))
    {
        unsigned char sz = 1;
        if (telem == Twchar) sz = 2;
        else if (telem == Tdchar) sz = 4;

        OutBuffer buf;
        if (elements)
        {
            for (size_t i = 0; i < elements->dim; ++i)
            {
                Expression *ch = getElement(i);
                if (ch->op != TOKint64)
                    return NULL;
                if (sz == 1)
                    buf.writeByte((unsigned)ch->toInteger());
                else if (sz == 2)
                    buf.writeword((unsigned)ch->toInteger());
                else
                    buf.write4((unsigned)ch->toInteger());
            }
        }
        char prefix;
             if (sz == 1) { prefix = 'c'; buf.writeByte(0); }
        else if (sz == 2) { prefix = 'w'; buf.writeword(0); }
        else              { prefix = 'd'; buf.write4(0); }

        const size_t len = buf.offset / sz - 1;
        StringExp *se = new StringExp(loc, buf.extractData(), len, prefix);
        se->sz = sz;
        se->type = type;
        return se;
    }
    return NULL;
}

/************************ AssocArrayLiteralExp ************************************/

// [ key0 : value0, key1 : value1, ... ]

AssocArrayLiteralExp::AssocArrayLiteralExp(Loc loc,
                Expressions *keys, Expressions *values)
    : Expression(loc, TOKassocarrayliteral, sizeof(AssocArrayLiteralExp))
{
    assert(keys->dim == values->dim);
    this->keys = keys;
    this->values = values;
    this->ownedByCtfe = OWNEDcode;
}

bool AssocArrayLiteralExp::equals(RootObject *o)
{
    if (this == o)
        return true;
    if (o && o->dyncast() == DYNCAST_EXPRESSION &&
        ((Expression *)o)->op == TOKassocarrayliteral)
    {
        AssocArrayLiteralExp *ae = (AssocArrayLiteralExp *)o;
        if (keys->dim != ae->keys->dim)
            return false;
        size_t count = 0;
        for (size_t i = 0; i < keys->dim; i++)
        {
            for (size_t j = 0; j < ae->keys->dim; j++)
            {
                if ((*keys)[i]->equals((*ae->keys)[j]))
                {
                    if (!(*values)[i]->equals((*ae->values)[j]))
                        return false;
                    ++count;
                }
            }
        }
        return count == keys->dim;
    }
    return false;
}

Expression *AssocArrayLiteralExp::syntaxCopy()
{
    return new AssocArrayLiteralExp(loc,
        arraySyntaxCopy(keys), arraySyntaxCopy(values));
}

bool AssocArrayLiteralExp::isBool(bool result)
{
    size_t dim = keys->dim;
    return result ? (dim != 0) : (dim == 0);
}

/************************ StructLiteralExp ************************************/

// sd( e1, e2, e3, ... )

StructLiteralExp::StructLiteralExp(Loc loc, StructDeclaration *sd, Expressions *elements, Type *stype)
    : Expression(loc, TOKstructliteral, sizeof(StructLiteralExp))
{
    this->sd = sd;
    if (!elements)
        elements = new Expressions();
    this->elements = elements;
    this->stype = stype;
    this->useStaticInit = false;
    this->sym = NULL;
    this->ownedByCtfe = OWNEDcode;
    this->origin = this;
    this->stageflags = 0;
    this->inlinecopy = NULL;
    //printf("StructLiteralExp::StructLiteralExp(%s)\n", toChars());
}

StructLiteralExp *StructLiteralExp::create(Loc loc, StructDeclaration *sd, void *elements, Type *stype)
{
    return new StructLiteralExp(loc, sd, (Expressions *)elements, stype);
}

bool StructLiteralExp::equals(RootObject *o)
{
    if (this == o)
        return true;
    if (o && o->dyncast() == DYNCAST_EXPRESSION &&
        ((Expression *)o)->op == TOKstructliteral)
    {
        StructLiteralExp *se = (StructLiteralExp *)o;
        if (!type->equals(se->type))
            return false;
        if (elements->dim != se->elements->dim)
            return false;
        for (size_t i = 0; i < elements->dim; i++)
        {
            Expression *e1 = (*elements)[i];
            Expression *e2 = (*se->elements)[i];
            if (e1 != e2 &&
                (!e1 || !e2 || !e1->equals(e2)))
                return false;
        }
        return true;
    }
    return false;
}

Expression *StructLiteralExp::syntaxCopy()
{
    StructLiteralExp *exp = new StructLiteralExp(loc, sd, arraySyntaxCopy(elements), type ? type : stype);
    exp->origin = this;
    return exp;
}

Expression *StructLiteralExp::addDtorHook(Scope *sc)
{
    /* If struct requires a destructor, rewrite as:
     *    (S tmp = S()),tmp
     * so that the destructor can be hung on tmp.
     */
    if (sd->dtor && sc->func)
    {
        /* Make an identifier for the temporary of the form:
         *   __sl%s%d, where %s is the struct name
         */
        const size_t len = 10;
        char buf[len + 1];
        buf[len] = 0;
        strcpy(buf, "__sl");
        strncat(buf, sd->ident->toChars(), len - 4 - 1);
        assert(buf[len] == 0);

        VarDeclaration *tmp = copyToTemp(0, buf, this);
        Expression *ae = new DeclarationExp(loc, tmp);
        Expression *e = new CommaExp(loc, ae, new VarExp(loc, tmp));
        e = semantic(e, sc);
        return e;
    }
    return this;
}

/**************************************
 * Gets expression at offset of type.
 * Returns NULL if not found.
 */

Expression *StructLiteralExp::getField(Type *type, unsigned offset)
{
    //printf("StructLiteralExp::getField(this = %s, type = %s, offset = %u)\n",
    //  /*toChars()*/"", type->toChars(), offset);
    Expression *e = NULL;
    int i = getFieldIndex(type, offset);

    if (i != -1)
    {
        //printf("\ti = %d\n", i);
        if (i == (int)sd->fields.dim - 1 && sd->isNested())
            return NULL;

        assert(i < (int)elements->dim);
        e = (*elements)[i];
        if (e)
        {
            //printf("e = %s, e->type = %s\n", e->toChars(), e->type->toChars());

            /* If type is a static array, and e is an initializer for that array,
             * then the field initializer should be an array literal of e.
             */
            if (e->type->castMod(0) != type->castMod(0) && type->ty == Tsarray)
            {   TypeSArray *tsa = (TypeSArray *)type;
                size_t length = (size_t)tsa->dim->toInteger();
                Expressions *z = new Expressions;
                z->setDim(length);
                for (size_t q = 0; q < length; ++q)
                    (*z)[q] = e->copy();
                e = new ArrayLiteralExp(loc, type, z);
            }
            else
            {
                e = e->copy();
                e->type = type;
            }
            if (useStaticInit && e->op == TOKstructliteral &&
                e->type->needsNested())
            {
                StructLiteralExp *se = (StructLiteralExp *)e;
                se->useStaticInit = true;
            }
        }
    }
    return e;
}

/************************************
 * Get index of field.
 * Returns -1 if not found.
 */

int StructLiteralExp::getFieldIndex(Type *type, unsigned offset)
{
    /* Find which field offset is by looking at the field offsets
     */
    if (elements->dim)
    {
        for (size_t i = 0; i < sd->fields.dim; i++)
        {
            VarDeclaration *v = sd->fields[i];

            if (offset == v->offset &&
                type->size() == v->type->size())
            {
                /* context field might not be filled. */
                if (i == sd->fields.dim - 1 && sd->isNested())
                    return (int)i;
                Expression *e = (*elements)[i];
                if (e)
                {
                    return (int)i;
                }
                break;
            }
        }
    }
    return -1;
}

/************************ TypeDotIdExp ************************************/

/* Things like:
 *      int.size
 *      foo.size
 *      (foo).size
 *      cast(foo).size
 */

DotIdExp *typeDotIdExp(Loc loc, Type *type, Identifier *ident)
{
    return new DotIdExp(loc, new TypeExp(loc, type), ident);
}


/************************************************************/

// Mainly just a placeholder

TypeExp::TypeExp(Loc loc, Type *type)
    : Expression(loc, TOKtype, sizeof(TypeExp))
{
    //printf("TypeExp::TypeExp(%s)\n", type->toChars());
    this->type = type;
}

Expression *TypeExp::syntaxCopy()
{
    return new TypeExp(loc, type->syntaxCopy());
}

bool TypeExp::checkType()
{
    error("type %s is not an expression", toChars());
    return true;
}

bool TypeExp::checkValue()
{
    error("type %s has no value", toChars());
    return true;
}

/************************************************************/

/***********************************************************
 * Mainly just a placeholder of
 *  Package, Module, Nspace, and TemplateInstance (including TemplateMixin)
 *
 * A template instance that requires IFTI:
 *      foo!tiargs(fargs)       // foo!tiargs
 * is left until CallExp::semantic() or resolveProperties()
 */
ScopeExp::ScopeExp(Loc loc, ScopeDsymbol *sds)
    : Expression(loc, TOKscope, sizeof(ScopeExp))
{
    //printf("ScopeExp::ScopeExp(sds = '%s')\n", sds->toChars());
    //static int count; if (++count == 38) *(char*)0=0;
    this->sds = sds;
    assert(!sds->isTemplateDeclaration());   // instead, you should use TemplateExp
}

Expression *ScopeExp::syntaxCopy()
{
    return new ScopeExp(loc, (ScopeDsymbol *)sds->syntaxCopy(NULL));
}

bool ScopeExp::checkType()
{
    if (sds->isPackage())
    {
        error("%s %s has no type", sds->kind(), sds->toChars());
        return true;
    }
    if (TemplateInstance *ti = sds->isTemplateInstance())
    {
        //assert(ti->needsTypeInference(sc));
        if (ti->tempdecl &&
            ti->semantictiargsdone &&
            ti->semanticRun == PASSinit)
        {
            error("partial %s %s has no type", sds->kind(), toChars());
            return true;
        }
    }
    return false;
}

bool ScopeExp::checkValue()
{
    error("%s %s has no value", sds->kind(), sds->toChars());
    return true;
}

/********************** TemplateExp **************************************/

// Mainly just a placeholder

TemplateExp::TemplateExp(Loc loc, TemplateDeclaration *td, FuncDeclaration *fd)
    : Expression(loc, TOKtemplate, sizeof(TemplateExp))
{
    //printf("TemplateExp(): %s\n", td->toChars());
    this->td = td;
    this->fd = fd;
}

bool TemplateExp::checkType()
{
    error("%s %s has no type", td->kind(), toChars());
    return true;
}

bool TemplateExp::checkValue()
{
    error("%s %s has no value", td->kind(), toChars());
    return true;
}

bool TemplateExp::isLvalue()
{
    return fd != NULL;
}

Expression *TemplateExp::toLvalue(Scope *sc, Expression *e)
{
    if (!fd)
        return Expression::toLvalue(sc, e);

    assert(sc);
    return resolve(loc, sc, fd, true);
}

/********************** NewExp **************************************/

/* thisexp.new(newargs) newtype(arguments) */

NewExp::NewExp(Loc loc, Expression *thisexp, Expressions *newargs,
        Type *newtype, Expressions *arguments)
    : Expression(loc, TOKnew, sizeof(NewExp))
{
    this->thisexp = thisexp;
    this->newargs = newargs;
    this->newtype = newtype;
    this->arguments = arguments;
    argprefix = NULL;
    member = NULL;
    allocator = NULL;
    onstack = 0;
}

NewExp *NewExp::create(Loc loc, Expression *thisexp, Expressions *newargs,
        Type *newtype, Expressions *arguments)
{
    return new NewExp(loc, thisexp, newargs, newtype, arguments);
}

Expression *NewExp::syntaxCopy()
{
    return new NewExp(loc,
        thisexp ? thisexp->syntaxCopy() : NULL,
        arraySyntaxCopy(newargs),
        newtype->syntaxCopy(), arraySyntaxCopy(arguments));
}

/********************** NewAnonClassExp **************************************/

NewAnonClassExp::NewAnonClassExp(Loc loc, Expression *thisexp,
        Expressions *newargs, ClassDeclaration *cd, Expressions *arguments)
    : Expression(loc, TOKnewanonclass, sizeof(NewAnonClassExp))
{
    this->thisexp = thisexp;
    this->newargs = newargs;
    this->cd = cd;
    this->arguments = arguments;
}

Expression *NewAnonClassExp::syntaxCopy()
{
    return new NewAnonClassExp(loc,
        thisexp ? thisexp->syntaxCopy() : NULL,
        arraySyntaxCopy(newargs),
        (ClassDeclaration *)cd->syntaxCopy(NULL),
        arraySyntaxCopy(arguments));
}

/********************** SymbolExp **************************************/

SymbolExp::SymbolExp(Loc loc, TOK op, int size, Declaration *var, bool hasOverloads)
    : Expression(loc, op, size)
{
    assert(var);
    this->var = var;
    this->hasOverloads = hasOverloads;
}

/********************** SymOffExp **************************************/

SymOffExp::SymOffExp(Loc loc, Declaration *var, dinteger_t offset, bool hasOverloads)
    : SymbolExp(loc, TOKsymoff, sizeof(SymOffExp), var,
                var->isVarDeclaration() ? false : hasOverloads)
{
    if (VarDeclaration *v = var->isVarDeclaration())
    {
        // FIXME: This error report will never be handled anyone.
        // It should be done before the SymOffExp construction.
        if (v->needThis())
            ::error(loc, "need 'this' for address of %s", v->toChars());
    }
    this->offset = offset;
}

bool SymOffExp::isBool(bool result)
{
    return result ? true : false;
}

/******************************** VarExp **************************/

VarExp::VarExp(Loc loc, Declaration *var, bool hasOverloads)
    : SymbolExp(loc, TOKvar, sizeof(VarExp), var,
                var->isVarDeclaration() ? false : hasOverloads)
{
    //printf("VarExp(this = %p, '%s', loc = %s)\n", this, var->toChars(), loc.toChars());
    //if (strcmp(var->ident->toChars(), "func") == 0) halt();
    this->type = var->type;
}

VarExp *VarExp::create(Loc loc, Declaration *var, bool hasOverloads)
{
    return new VarExp(loc, var, hasOverloads);
}

bool VarExp::equals(RootObject *o)
{
    if (this == o)
        return true;
    if (((Expression *)o)->op == TOKvar)
    {
        VarExp *ne = (VarExp *)o;
        if (type->toHeadMutable()->equals(ne->type->toHeadMutable()) &&
            var == ne->var)
        {
            return true;
        }
    }
    return false;
}

bool VarExp::isLvalue()
{
    if (var->storage_class & (STClazy | STCrvalue | STCmanifest))
        return false;
    return true;
}

Expression *VarExp::toLvalue(Scope *, Expression *)
{
    if (var->storage_class & STCmanifest)
    {
        error("manifest constant '%s' is not lvalue", var->toChars());
        return new ErrorExp();
    }
    if (var->storage_class & STClazy)
    {
        error("lazy variables cannot be lvalues");
        return new ErrorExp();
    }
    if (var->ident == Id::ctfe)
    {
        error("compiler-generated variable __ctfe is not an lvalue");
        return new ErrorExp();
    }
    if (var->ident == Id::dollar)   // Bugzilla 13574
    {
        error("'$' is not an lvalue");
        return new ErrorExp();
    }
    return this;
}

int VarExp::checkModifiable(Scope *sc, int flag)
{
    //printf("VarExp::checkModifiable %s", toChars());
    assert(type);
    return var->checkModify(loc, sc, type, NULL, flag);
}

Expression *VarExp::modifiableLvalue(Scope *sc, Expression *e)
{
    //printf("VarExp::modifiableLvalue('%s')\n", var->toChars());
    if (var->storage_class & STCmanifest)
    {
        error("cannot modify manifest constant '%s'", toChars());
        return new ErrorExp();
    }
    // See if this expression is a modifiable lvalue (i.e. not const)
    return Expression::modifiableLvalue(sc, e);
}


/******************************** OverExp **************************/

OverExp::OverExp(Loc loc, OverloadSet *s)
        : Expression(loc, TOKoverloadset, sizeof(OverExp))
{
    //printf("OverExp(this = %p, '%s')\n", this, var->toChars());
    vars = s;
    type = Type::tvoid;
}

bool OverExp::isLvalue()
{
    return true;
}

Expression *OverExp::toLvalue(Scope *, Expression *)
{
    return this;
}

/******************************** TupleExp **************************/

TupleExp::TupleExp(Loc loc, Expression *e0, Expressions *exps)
        : Expression(loc, TOKtuple, sizeof(TupleExp))
{
    //printf("TupleExp(this = %p)\n", this);
    this->e0 = e0;
    this->exps = exps;
}

TupleExp::TupleExp(Loc loc, Expressions *exps)
        : Expression(loc, TOKtuple, sizeof(TupleExp))
{
    //printf("TupleExp(this = %p)\n", this);
    this->e0 = NULL;
    this->exps = exps;
}

TupleExp::TupleExp(Loc loc, TupleDeclaration *tup)
        : Expression(loc, TOKtuple, sizeof(TupleExp))
{
    this->e0 = NULL;
    this->exps = new Expressions();

    this->exps->reserve(tup->objects->dim);
    for (size_t i = 0; i < tup->objects->dim; i++)
    {   RootObject *o = (*tup->objects)[i];
        if (Dsymbol *s = getDsymbol(o))
        {
            /* If tuple element represents a symbol, translate to DsymbolExp
             * to supply implicit 'this' if needed later.
             */
            Expression *e = new DsymbolExp(loc, s);
            this->exps->push(e);
        }
        else if (o->dyncast() == DYNCAST_EXPRESSION)
        {
            Expression *e = ((Expression *)o)->copy();
            e->loc = loc;    // Bugzilla 15669
            this->exps->push(e);
        }
        else if (o->dyncast() == DYNCAST_TYPE)
        {
            Type *t = (Type *)o;
            Expression *e = new TypeExp(loc, t);
            this->exps->push(e);
        }
        else
        {
            error("%s is not an expression", o->toChars());
        }
    }
}

bool TupleExp::equals(RootObject *o)
{
    if (this == o)
        return true;
    if (((Expression *)o)->op == TOKtuple)
    {
        TupleExp *te = (TupleExp *)o;
        if (exps->dim != te->exps->dim)
            return false;
        if ((e0 && !e0->equals(te->e0)) || (!e0 && te->e0))
            return false;
        for (size_t i = 0; i < exps->dim; i++)
        {
            Expression *e1 = (*exps)[i];
            Expression *e2 = (*te->exps)[i];
            if (!e1->equals(e2))
                return false;
        }
        return true;
    }
    return false;
}

Expression *TupleExp::syntaxCopy()
{
    return new TupleExp(loc, e0 ? e0->syntaxCopy() : NULL, arraySyntaxCopy(exps));
}

/******************************** FuncExp *********************************/

FuncExp::FuncExp(Loc loc, Dsymbol *s)
        : Expression(loc, TOKfunction, sizeof(FuncExp))
{
    this->td = s->isTemplateDeclaration();
    this->fd = s->isFuncLiteralDeclaration();
    if (td)
    {
        assert(td->literal);
        assert(td->members && td->members->dim == 1);
        fd = (*td->members)[0]->isFuncLiteralDeclaration();
    }
    tok = fd->tok;  // save original kind of function/delegate/(infer)
    assert(fd->fbody);
}

bool FuncExp::equals(RootObject *o)
{
    if (this == o)
        return true;
    if (o->dyncast() != DYNCAST_EXPRESSION)
        return false;
    if (((Expression *)o)->op == TOKfunction)
    {
        FuncExp *fe = (FuncExp *)o;
        return fd == fe->fd;
    }
    return false;
}

void FuncExp::genIdent(Scope *sc)
{
    if (fd->ident == Id::empty)
    {
        const char *s;
        if (fd->fes)                        s = "__foreachbody";
        else if (fd->tok == TOKreserved)    s = "__lambda";
        else if (fd->tok == TOKdelegate)    s = "__dgliteral";
        else                                s = "__funcliteral";

        DsymbolTable *symtab;
        if (FuncDeclaration *func = sc->parent->isFuncDeclaration())
        {
            if (func->localsymtab == NULL)
            {
                // Inside template constraint, symtab is not set yet.
                // Initialize it lazily.
                func->localsymtab = new DsymbolTable();
            }
            symtab = func->localsymtab;
        }
        else
        {
            ScopeDsymbol *sds = sc->parent->isScopeDsymbol();
            if (!sds->symtab)
            {
                // Inside template constraint, symtab may not be set yet.
                // Initialize it lazily.
                assert(sds->isTemplateInstance());
                sds->symtab = new DsymbolTable();
            }
            symtab = sds->symtab;
        }
        assert(symtab);
        int num = (int)dmd_aaLen(symtab->tab) + 1;
        Identifier *id = Identifier::generateId(s, num);
        fd->ident = id;
        if (td) td->ident = id;
        symtab->insert(td ? (Dsymbol *)td : (Dsymbol *)fd);
    }
}

Expression *FuncExp::syntaxCopy()
{
    if (td)
        return new FuncExp(loc, td->syntaxCopy(NULL));
    else if (fd->semanticRun == PASSinit)
        return new FuncExp(loc, fd->syntaxCopy(NULL));
    else    // Bugzilla 13481: Prevent multiple semantic analysis of lambda body.
        return new FuncExp(loc, fd);
}

MATCH FuncExp::matchType(Type *to, Scope *sc, FuncExp **presult, int flag)
{
    //printf("FuncExp::matchType('%s'), to=%s\n", type ? type->toChars() : "null", to->toChars());
    if (presult)
        *presult = NULL;

    TypeFunction *tof = NULL;
    if (to->ty == Tdelegate)
    {
        if (tok == TOKfunction)
        {
            if (!flag)
                error("cannot match function literal to delegate type '%s'", to->toChars());
            return MATCHnomatch;
        }
        tof = (TypeFunction *)to->nextOf();
    }
    else if (to->ty == Tpointer && to->nextOf()->ty == Tfunction)
    {
        if (tok == TOKdelegate)
        {
            if (!flag)
                error("cannot match delegate literal to function pointer type '%s'", to->toChars());
            return MATCHnomatch;
        }
        tof = (TypeFunction *)to->nextOf();
    }

    if (td)
    {
        if (!tof)
        {
        L1:
            if (!flag)
                error("cannot infer parameter types from %s", to->toChars());
            return MATCHnomatch;
        }

        // Parameter types inference from 'tof'
        assert(td->_scope);
        TypeFunction *tf = (TypeFunction *)fd->type;
        //printf("\ttof = %s\n", tof->toChars());
        //printf("\ttf  = %s\n", tf->toChars());
        size_t dim = Parameter::dim(tf->parameters);

        if (Parameter::dim(tof->parameters) != dim ||
            tof->varargs != tf->varargs)
            goto L1;

        Objects *tiargs = new Objects();
        tiargs->reserve(td->parameters->dim);

        for (size_t i = 0; i < td->parameters->dim; i++)
        {
            TemplateParameter *tp = (*td->parameters)[i];
            size_t u = 0;
            for (; u < dim; u++)
            {
                Parameter *p = Parameter::getNth(tf->parameters, u);
                if (p->type->ty == Tident &&
                    ((TypeIdentifier *)p->type)->ident == tp->ident)
                {
                    break;
                }
            }
            assert(u < dim);
            Parameter *pto = Parameter::getNth(tof->parameters, u);
            Type *t = pto->type;
            if (t->ty == Terror)
                goto L1;
            tiargs->push(t);
        }

        // Set target of return type inference
        if (!tf->next && tof->next)
            fd->treq = to;

        TemplateInstance *ti = new TemplateInstance(loc, td, tiargs);
        Expression *ex = new ScopeExp(loc, ti);
        ex = ::semantic(ex, td->_scope);

        // Reset inference target for the later re-semantic
        fd->treq = NULL;

        if (ex->op == TOKerror)
            return MATCHnomatch;
        if (ex->op != TOKfunction)
            goto L1;
        return ((FuncExp *)ex)->matchType(to, sc, presult, flag);
    }

    if (!tof || !tof->next)
        return MATCHnomatch;

    assert(type && type != Type::tvoid);
    TypeFunction *tfx = (TypeFunction *)fd->type;
    bool convertMatch = (type->ty != to->ty);

    if (fd->inferRetType && tfx->next->implicitConvTo(tof->next) == MATCHconvert)
    {
        /* If return type is inferred and covariant return,
         * tweak return statements to required return type.
         *
         * interface I {}
         * class C : Object, I{}
         *
         * I delegate() dg = delegate() { return new class C(); }
         */
        convertMatch = true;

        TypeFunction *tfy = new TypeFunction(tfx->parameters, tof->next, tfx->varargs, tfx->linkage, STCundefined);
        tfy->mod = tfx->mod;
        tfy->isnothrow  = tfx->isnothrow;
        tfy->isnogc     = tfx->isnogc;
        tfy->purity     = tfx->purity;
        tfy->isproperty = tfx->isproperty;
        tfy->isref      = tfx->isref;
        tfy->iswild     = tfx->iswild;
        tfy->deco = tfy->merge()->deco;

        tfx = tfy;
    }

    Type *tx;
    if (tok == TOKdelegate ||
        (tok == TOKreserved && (type->ty == Tdelegate ||
                                (type->ty == Tpointer && to->ty == Tdelegate))))
    {
        // Allow conversion from implicit function pointer to delegate
        tx = new TypeDelegate(tfx);
        tx->deco = tx->merge()->deco;
    }
    else
    {
        assert(tok == TOKfunction ||
               (tok == TOKreserved && type->ty == Tpointer));
        tx = tfx->pointerTo();
    }
    //printf("\ttx = %s, to = %s\n", tx->toChars(), to->toChars());

    MATCH m = tx->implicitConvTo(to);
    if (m > MATCHnomatch)
    {
        // MATCHexact:      exact type match
        // MATCHconst:      covairiant type match (eg. attributes difference)
        // MATCHconvert:    context conversion
        m = convertMatch ? MATCHconvert : tx->equals(to) ? MATCHexact : MATCHconst;

        if (presult)
        {
            (*presult) = (FuncExp *)copy();
            (*presult)->type = to;

            // Bugzilla 12508: Tweak function body for covariant returns.
            (*presult)->fd->modifyReturns(sc, tof->next);
        }
    }
    else if (!flag)
    {
        error("cannot implicitly convert expression (%s) of type %s to %s",
                toChars(), tx->toChars(), to->toChars());
    }
    return m;
}

const char *FuncExp::toChars()
{
    return fd->toChars();
}

bool FuncExp::checkType()
{
    if (td)
    {
        error("template lambda has no type");
        return true;
    }
    return false;
}

bool FuncExp::checkValue()
{
    if (td)
    {
        error("template lambda has no value");
        return true;
    }
    return false;
}

/******************************** DeclarationExp **************************/

DeclarationExp::DeclarationExp(Loc loc, Dsymbol *declaration)
        : Expression(loc, TOKdeclaration, sizeof(DeclarationExp))
{
    this->declaration = declaration;
}

Expression *DeclarationExp::syntaxCopy()
{
    return new DeclarationExp(loc, declaration->syntaxCopy(NULL));
}

bool DeclarationExp::hasCode()
{
    if (VarDeclaration *vd = declaration->isVarDeclaration())
    {
        return !(vd->storage_class & (STCmanifest | STCstatic));
    }
    return false;
}

/************************ TypeidExp ************************************/

/*
 *      typeid(int)
 */

TypeidExp::TypeidExp(Loc loc, RootObject *o)
    : Expression(loc, TOKtypeid, sizeof(TypeidExp))
{
    this->obj = o;
}

Expression *TypeidExp::syntaxCopy()
{
    return new TypeidExp(loc, objectSyntaxCopy(obj));
}

/************************ TraitsExp ************************************/
/*
 *      __traits(identifier, args...)
 */

TraitsExp::TraitsExp(Loc loc, Identifier *ident, Objects *args)
    : Expression(loc, TOKtraits, sizeof(TraitsExp))
{
    this->ident = ident;
    this->args = args;
}

Expression *TraitsExp::syntaxCopy()
{
    return new TraitsExp(loc, ident, TemplateInstance::arraySyntaxCopy(args));
}

/************************************************************/

HaltExp::HaltExp(Loc loc)
        : Expression(loc, TOKhalt, sizeof(HaltExp))
{
}

/************************************************************/

IsExp::IsExp(Loc loc, Type *targ, Identifier *id, TOK tok,
        Type *tspec, TOK tok2, TemplateParameters *parameters)
        : Expression(loc, TOKis, sizeof(IsExp))
{
    this->targ = targ;
    this->id = id;
    this->tok = tok;
    this->tspec = tspec;
    this->tok2 = tok2;
    this->parameters = parameters;
}

Expression *IsExp::syntaxCopy()
{
    // This section is identical to that in TemplateDeclaration::syntaxCopy()
    TemplateParameters *p = NULL;
    if (parameters)
    {
        p = new TemplateParameters();
        p->setDim(parameters->dim);
        for (size_t i = 0; i < p->dim; i++)
            (*p)[i] = (*parameters)[i]->syntaxCopy();
    }
    return new IsExp(loc,
        targ->syntaxCopy(),
        id,
        tok,
        tspec ? tspec->syntaxCopy() : NULL,
        tok2,
        p);
}

void unSpeculative(Scope *sc, RootObject *o);

/************************************************************/

UnaExp::UnaExp(Loc loc, TOK op, int size, Expression *e1)
        : Expression(loc, op, size)
{
    this->e1 = e1;
    this->att1 = NULL;
}

Expression *UnaExp::syntaxCopy()
{
    UnaExp *e = (UnaExp *)copy();
    e->type = NULL;
    e->e1 = e->e1->syntaxCopy();
    return e;
}

/********************************
 * The type for a unary expression is incompatible.
 * Print error message.
 * Returns:
 *  ErrorExp
 */
Expression *UnaExp::incompatibleTypes()
{
    if (e1->type->toBasetype() == Type::terror)
        return e1;

    if (e1->op == TOKtype)
    {
        error("incompatible type for (%s(%s)): cannot use '%s' with types",
              Token::toChars(op), e1->toChars(), Token::toChars(op));
    }
    else
    {
        error("incompatible type for (%s(%s)): '%s'",
              Token::toChars(op), e1->toChars(), e1->type->toChars());
    }
    return new ErrorExp();
}

Expression *UnaExp::resolveLoc(Loc loc, Scope *sc)
{
    e1 = e1->resolveLoc(loc, sc);
    return this;
}

/************************************************************/

BinExp::BinExp(Loc loc, TOK op, int size, Expression *e1, Expression *e2)
        : Expression(loc, op, size)
{
    this->e1 = e1;
    this->e2 = e2;

    this->att1 = NULL;
    this->att2 = NULL;
}

Expression *BinExp::syntaxCopy()
{
    BinExp *e = (BinExp *)copy();
    e->type = NULL;
    e->e1 = e->e1->syntaxCopy();
    e->e2 = e->e2->syntaxCopy();
    return e;
}

Expression *BinExp::checkOpAssignTypes(Scope *sc)
{
    // At that point t1 and t2 are the merged types. type is the original type of the lhs.
    Type *t1 = e1->type;
    Type *t2 = e2->type;

    // T opAssign floating yields a floating. Prevent truncating conversions (float to int).
    // See issue 3841.
    // Should we also prevent double to float (type->isfloating() && type->size() < t2 ->size()) ?
    if (op == TOKaddass || op == TOKminass ||
        op == TOKmulass || op == TOKdivass || op == TOKmodass ||
        op == TOKpowass)
    {
        if ((type->isintegral() && t2->isfloating()))
        {
            warning("%s %s %s is performing truncating conversion",
                    type->toChars(), Token::toChars(op), t2->toChars());
        }
    }

    // generate an error if this is a nonsensical *=,/=, or %=, eg real *= imaginary
    if (op == TOKmulass || op == TOKdivass || op == TOKmodass)
    {
        // Any multiplication by an imaginary or complex number yields a complex result.
        // r *= c, i*=c, r*=i, i*=i are all forbidden operations.
        const char *opstr = Token::toChars(op);
        if (t1->isreal() && t2->iscomplex())
        {
            error("%s %s %s is undefined. Did you mean %s %s %s.re ?",
                t1->toChars(), opstr, t2->toChars(),
                t1->toChars(), opstr, t2->toChars());
            return new ErrorExp();
        }
        else if (t1->isimaginary() && t2->iscomplex())
        {
            error("%s %s %s is undefined. Did you mean %s %s %s.im ?",
                t1->toChars(), opstr, t2->toChars(),
                t1->toChars(), opstr, t2->toChars());
            return new ErrorExp();
        }
        else if ((t1->isreal() || t1->isimaginary()) &&
            t2->isimaginary())
        {
            error("%s %s %s is an undefined operation", t1->toChars(), opstr, t2->toChars());
            return new ErrorExp();
        }
    }

    // generate an error if this is a nonsensical += or -=, eg real += imaginary
    if (op == TOKaddass || op == TOKminass)
    {
        // Addition or subtraction of a real and an imaginary is a complex result.
        // Thus, r+=i, r+=c, i+=r, i+=c are all forbidden operations.
        if ((t1->isreal() && (t2->isimaginary() || t2->iscomplex())) ||
            (t1->isimaginary() && (t2->isreal() || t2->iscomplex())))
        {
            error("%s %s %s is undefined (result is complex)",
                t1->toChars(), Token::toChars(op), t2->toChars());
            return new ErrorExp();
        }
        if (type->isreal() || type->isimaginary())
        {
            assert(global.errors || t2->isfloating());
            e2 = e2->castTo(sc, t1);
        }
    }

    if (op == TOKmulass)
    {
        if (t2->isfloating())
        {
            if (t1->isreal())
            {
                if (t2->isimaginary() || t2->iscomplex())
                {
                    e2 = e2->castTo(sc, t1);
                }
            }
            else if (t1->isimaginary())
            {
                if (t2->isimaginary() || t2->iscomplex())
                {
                    switch (t1->ty)
                    {
                        case Timaginary32: t2 = Type::tfloat32; break;
                        case Timaginary64: t2 = Type::tfloat64; break;
                        case Timaginary80: t2 = Type::tfloat80; break;
                        default:
                            assert(0);
                    }
                    e2 = e2->castTo(sc, t2);
                }
            }
        }
    }
    else if (op == TOKdivass)
    {
        if (t2->isimaginary())
        {
            if (t1->isreal())
            {
                // x/iv = i(-x/v)
                // Therefore, the result is 0
                e2 = new CommaExp(loc, e2, new RealExp(loc, CTFloat::zero, t1));
                e2->type = t1;
                Expression *e = new AssignExp(loc, e1, e2);
                e->type = t1;
                return e;
            }
            else if (t1->isimaginary())
            {
                Type *t3;
                switch (t1->ty)
                {
                    case Timaginary32: t3 = Type::tfloat32; break;
                    case Timaginary64: t3 = Type::tfloat64; break;
                    case Timaginary80: t3 = Type::tfloat80; break;
                    default:
                        assert(0);
                }
                e2 = e2->castTo(sc, t3);
                Expression *e = new AssignExp(loc, e1, e2);
                e->type = t1;
                return e;
            }
        }
    }
    else if (op == TOKmodass)
    {
        if (t2->iscomplex())
        {
            error("cannot perform modulo complex arithmetic");
            return new ErrorExp();
        }
    }
    return this;
}

/********************************
 * The types for a binary expression are incompatible.
 * Print error message.
 * Returns:
 *  ErrorExp
 */
Expression *BinExp::incompatibleTypes()
{
    if (e1->type->toBasetype() == Type::terror)
        return e1;
    if (e2->type->toBasetype() == Type::terror)
        return e2;

    // CondExp uses 'a ? b : c' but we're comparing 'b : c'
    TOK thisOp = (op == TOKquestion) ? TOKcolon : op;
    if (e1->op == TOKtype || e2->op == TOKtype)
    {
        error("incompatible types for ((%s) %s (%s)): cannot use '%s' with types",
            e1->toChars(), Token::toChars(thisOp), e2->toChars(), Token::toChars(op));
    }
    else
    {
        error("incompatible types for ((%s) %s (%s)): '%s' and '%s'",
            e1->toChars(), Token::toChars(thisOp), e2->toChars(),
            e1->type->toChars(), e2->type->toChars());
    }
    return new ErrorExp();
}

bool BinExp::checkIntegralBin()
{
    bool r1 = e1->checkIntegral();
    bool r2 = e2->checkIntegral();
    return (r1 || r2);
}

bool BinExp::checkArithmeticBin()
{
    bool r1 = e1->checkArithmetic();
    bool r2 = e2->checkArithmetic();
    return (r1 || r2);
}

/********************** BinAssignExp **************************************/

BinAssignExp::BinAssignExp(Loc loc, TOK op, int size, Expression *e1, Expression *e2)
        : BinExp(loc, op, size, e1, e2)
{
}

bool BinAssignExp::isLvalue()
{
    return true;
}

Expression *BinAssignExp::toLvalue(Scope *, Expression *)
{
    // Lvalue-ness will be handled in glue layer.
    return this;
}

Expression *BinAssignExp::modifiableLvalue(Scope *sc, Expression *)
{
    // should check e1->checkModifiable() ?
    return toLvalue(sc, this);
}

/************************************************************/

CompileExp::CompileExp(Loc loc, Expression *e)
        : UnaExp(loc, TOKmixin, sizeof(CompileExp), e)
{
}

/************************************************************/

ImportExp::ImportExp(Loc loc, Expression *e)
        : UnaExp(loc, TOKimport, sizeof(ImportExp), e)
{
}

/************************************************************/

AssertExp::AssertExp(Loc loc, Expression *e, Expression *msg)
        : UnaExp(loc, TOKassert, sizeof(AssertExp), e)
{
    this->msg = msg;
}

Expression *AssertExp::syntaxCopy()
{
    return new AssertExp(loc, e1->syntaxCopy(), msg ? msg->syntaxCopy() : NULL);
}

/************************************************************/

DotIdExp::DotIdExp(Loc loc, Expression *e, Identifier *ident)
        : UnaExp(loc, TOKdotid, sizeof(DotIdExp), e)
{
    this->ident = ident;
    this->wantsym = false;
    this->noderef = false;
}

DotIdExp *DotIdExp::create(Loc loc, Expression *e, Identifier *ident)
{
    return new DotIdExp(loc, e, ident);
}

/********************** DotTemplateExp ***********************************/

// Mainly just a placeholder

DotTemplateExp::DotTemplateExp(Loc loc, Expression *e, TemplateDeclaration *td)
        : UnaExp(loc, TOKdottd, sizeof(DotTemplateExp), e)

{
    this->td = td;
}

/************************************************************/

DotVarExp::DotVarExp(Loc loc, Expression *e, Declaration *var, bool hasOverloads)
        : UnaExp(loc, TOKdotvar, sizeof(DotVarExp), e)
{
    //printf("DotVarExp()\n");
    this->var = var;
    this->hasOverloads = var->isVarDeclaration() ? false : hasOverloads;
}

bool DotVarExp::isLvalue()
{
    return true;
}

Expression *DotVarExp::toLvalue(Scope *, Expression *)
{
    //printf("DotVarExp::toLvalue(%s)\n", toChars());
    return this;
}

/***********************************************
 * Mark variable v as modified if it is inside a constructor that var
 * is a field in.
 */
int modifyFieldVar(Loc loc, Scope *sc, VarDeclaration *var, Expression *e1)
{
    //printf("modifyFieldVar(var = %s)\n", var->toChars());
    Dsymbol *s = sc->func;
    while (1)
    {
        FuncDeclaration *fd = NULL;
        if (s)
            fd = s->isFuncDeclaration();
        if (fd &&
            ((fd->isCtorDeclaration() && var->isField()) ||
             (fd->isStaticCtorDeclaration() && !var->isField())) &&
            fd->toParent2() == var->toParent2() &&
            (!e1 || e1->op == TOKthis)
           )
        {
            bool result = true;

            var->ctorinit = true;
            //printf("setting ctorinit\n");

            if (var->isField() && sc->fieldinit && !sc->intypeof)
            {
                assert(e1);
                bool mustInit = ((var->storage_class & STCnodefaultctor) != 0 ||
                                 var->type->needsNested());

                size_t dim = sc->fieldinit_dim;
                AggregateDeclaration *ad = fd->isMember2();
                assert(ad);
                size_t i;
                for (i = 0; i < dim; i++)   // same as findFieldIndexByName in ctfeexp.c ?
                {
                    if (ad->fields[i] == var)
                        break;
                }
                assert(i < dim);
                unsigned fi = sc->fieldinit[i];

                if (fi & CSXthis_ctor)
                {
                    if (var->type->isMutable() && e1->type->isMutable())
                        result = false;
                    else
                    {
                        const char *modStr = !var->type->isMutable() ? MODtoChars(var->type->mod) : MODtoChars(e1->type->mod);
                        ::error(loc, "%s field '%s' initialized multiple times", modStr, var->toChars());
                    }
                }
                else if (sc->noctor || (fi & CSXlabel))
                {
                    if (!mustInit && var->type->isMutable() && e1->type->isMutable())
                        result = false;
                    else
                    {
                        const char *modStr = !var->type->isMutable() ? MODtoChars(var->type->mod) : MODtoChars(e1->type->mod);
                        ::error(loc, "%s field '%s' initialization is not allowed in loops or after labels", modStr, var->toChars());
                    }
                }
                sc->fieldinit[i] |= CSXthis_ctor;
                if (var->overlapped) // Bugzilla 15258
                {
                    for (size_t j = 0; j < ad->fields.dim; j++)
                    {
                        VarDeclaration *v = ad->fields[j];
                        if (v == var || !var->isOverlappedWith(v))
                            continue;
                        v->ctorinit = true;
                        sc->fieldinit[j] = CSXthis_ctor;
                    }
                }
            }
            else if (fd != sc->func)
            {
                if (var->type->isMutable())
                    result = false;
                else if (sc->func->fes)
                {
                    const char *p = var->isField() ? "field" : var->kind();
                    ::error(loc, "%s %s '%s' initialization is not allowed in foreach loop",
                        MODtoChars(var->type->mod), p, var->toChars());
                }
                else
                {
                    const char *p = var->isField() ? "field" : var->kind();
                    ::error(loc, "%s %s '%s' initialization is not allowed in nested function '%s'",
                        MODtoChars(var->type->mod), p, var->toChars(), sc->func->toChars());
                }
            }
            return result;
        }
        else
        {
            if (s)
            {
                s = s->toParent2();
                continue;
            }
        }
        break;
    }
    return false;
}

int DotVarExp::checkModifiable(Scope *sc, int flag)
{
    //printf("DotVarExp::checkModifiable %s %s\n", toChars(), type->toChars());
    if (checkUnsafeAccess(sc, this, false, !flag))
        return 2;

    if (e1->op == TOKthis)
        return var->checkModify(loc, sc, type, e1, flag);

    //printf("\te1 = %s\n", e1->toChars());
    return e1->checkModifiable(sc, flag);
}

Expression *DotVarExp::modifiableLvalue(Scope *sc, Expression *e)
{
    return Expression::modifiableLvalue(sc, e);
}

/************************************************************/

/* Things like:
 *      foo.bar!(args)
 */

DotTemplateInstanceExp::DotTemplateInstanceExp(Loc loc, Expression *e, Identifier *name, Objects *tiargs)
        : UnaExp(loc, TOKdotti, sizeof(DotTemplateInstanceExp), e)
{
    //printf("DotTemplateInstanceExp()\n");
    this->ti = new TemplateInstance(loc, name);
    this->ti->tiargs = tiargs;
}

DotTemplateInstanceExp::DotTemplateInstanceExp(Loc loc, Expression *e, TemplateInstance *ti)
        : UnaExp(loc, TOKdotti, sizeof(DotTemplateInstanceExp), e)
{
    this->ti = ti;
}

Expression *DotTemplateInstanceExp::syntaxCopy()
{
    return new DotTemplateInstanceExp(loc,
        e1->syntaxCopy(),
        ti->name,
        TemplateInstance::arraySyntaxCopy(ti->tiargs));
}

bool DotTemplateInstanceExp::findTempDecl(Scope *sc)
{
    if (ti->tempdecl)
        return true;

    Expression *e = new DotIdExp(loc, e1, ti->name);
    e = semantic(e, sc);
    if (e->op == TOKdot)
        e = ((DotExp *)e)->e2;

    Dsymbol *s = NULL;
    switch (e->op)
    {
        case TOKoverloadset:    s = ((OverExp *)e)->vars;       break;
        case TOKdottd:          s = ((DotTemplateExp *)e)->td;  break;
        case TOKscope:          s = ((ScopeExp *)e)->sds;       break;
        case TOKdotvar:         s = ((DotVarExp *)e)->var;      break;
        case TOKvar:            s = ((VarExp *)e)->var;         break;
        default:                return false;
    }
    return ti->updateTempDecl(sc, s);
}

/************************************************************/

DelegateExp::DelegateExp(Loc loc, Expression *e, FuncDeclaration *f, bool hasOverloads)
        : UnaExp(loc, TOKdelegate, sizeof(DelegateExp), e)
{
    this->func = f;
    this->hasOverloads = hasOverloads;
}

/************************************************************/

DotTypeExp::DotTypeExp(Loc loc, Expression *e, Dsymbol *s)
        : UnaExp(loc, TOKdottype, sizeof(DotTypeExp), e)
{
    this->sym = s;
    this->type = NULL;
}

/************************************************************/

CallExp::CallExp(Loc loc, Expression *e, Expressions *exps)
        : UnaExp(loc, TOKcall, sizeof(CallExp), e)
{
    this->arguments = exps;
    this->f = NULL;
    this->directcall = false;
}

CallExp::CallExp(Loc loc, Expression *e)
        : UnaExp(loc, TOKcall, sizeof(CallExp), e)
{
    this->arguments = NULL;
    this->f = NULL;
    this->directcall = false;
}

CallExp::CallExp(Loc loc, Expression *e, Expression *earg1)
        : UnaExp(loc, TOKcall, sizeof(CallExp), e)
{
    Expressions *arguments = new Expressions();
    if (earg1)
    {
        arguments->setDim(1);
        (*arguments)[0] = earg1;
    }
    this->arguments = arguments;
    this->f = NULL;
    this->directcall = false;
}

CallExp::CallExp(Loc loc, Expression *e, Expression *earg1, Expression *earg2)
        : UnaExp(loc, TOKcall, sizeof(CallExp), e)
{
    Expressions *arguments = new Expressions();
    arguments->setDim(2);
    (*arguments)[0] = earg1;
    (*arguments)[1] = earg2;

    this->arguments = arguments;
    this->f = NULL;
    this->directcall = false;
}

CallExp *CallExp::create(Loc loc, Expression *e, Expressions *exps)
{
    return new CallExp(loc, e, exps);
}

CallExp *CallExp::create(Loc loc, Expression *e)
{
    return new CallExp(loc, e);
}

CallExp *CallExp::create(Loc loc, Expression *e, Expression *earg1)
{
    return new CallExp(loc, e, earg1);
}

Expression *CallExp::syntaxCopy()
{
    return new CallExp(loc, e1->syntaxCopy(), arraySyntaxCopy(arguments));
}

bool CallExp::isLvalue()
{
    Type *tb = e1->type->toBasetype();
    if (tb->ty == Tdelegate || tb->ty == Tpointer)
        tb = tb->nextOf();
    if (tb->ty == Tfunction && ((TypeFunction *)tb)->isref)
    {
        if (e1->op == TOKdotvar)
            if (((DotVarExp *)e1)->var->isCtorDeclaration())
                return false;
        return true;               // function returns a reference
    }
    return false;
}

Expression *CallExp::toLvalue(Scope *sc, Expression *e)
{
    if (isLvalue())
        return this;
    return Expression::toLvalue(sc, e);
}

Expression *CallExp::addDtorHook(Scope *sc)
{
    /* Only need to add dtor hook if it's a type that needs destruction.
     * Use same logic as VarDeclaration::callScopeDtor()
     */

    if (e1->type && e1->type->ty == Tfunction)
    {
        TypeFunction *tf = (TypeFunction *)e1->type;
        if (tf->isref)
            return this;
    }

    Type *tv = type->baseElemOf();
    if (tv->ty == Tstruct)
    {
        TypeStruct *ts = (TypeStruct *)tv;
        StructDeclaration *sd = ts->sym;
        if (sd->dtor)
        {
            /* Type needs destruction, so declare a tmp
             * which the back end will recognize and call dtor on
             */
            VarDeclaration *tmp = copyToTemp(0, "__tmpfordtor", this);
            DeclarationExp *de = new DeclarationExp(loc, tmp);
            VarExp *ve = new VarExp(loc, tmp);
            Expression *e = new CommaExp(loc, de, ve);
            e = semantic(e, sc);
            return e;
        }
    }
    return this;
}

FuncDeclaration *isFuncAddress(Expression *e, bool *hasOverloads = NULL)
{
    if (e->op == TOKaddress)
    {
        Expression *ae1 = ((AddrExp *)e)->e1;
        if (ae1->op == TOKvar)
        {
            VarExp *ve = (VarExp *)ae1;
            if (hasOverloads)
                *hasOverloads = ve->hasOverloads;
            return ve->var->isFuncDeclaration();
        }
        if (ae1->op == TOKdotvar)
        {
            DotVarExp *dve = (DotVarExp *)ae1;
            if (hasOverloads)
                *hasOverloads = dve->hasOverloads;
            return dve->var->isFuncDeclaration();
        }
    }
    else
    {
        if (e->op == TOKsymoff)
        {
            SymOffExp *soe = (SymOffExp *)e;
            if (hasOverloads)
                *hasOverloads = soe->hasOverloads;
            return soe->var->isFuncDeclaration();
        }
        if (e->op == TOKdelegate)
        {
            DelegateExp *dge = (DelegateExp *)e;
            if (hasOverloads)
                *hasOverloads = dge->hasOverloads;
            return dge->func->isFuncDeclaration();
        }
    }
    return NULL;
}

/************************************************************/

AddrExp::AddrExp(Loc loc, Expression *e)
        : UnaExp(loc, TOKaddress, sizeof(AddrExp), e)
{
}

AddrExp::AddrExp(Loc loc, Expression *e, Type *t)
        : UnaExp(loc, TOKaddress, sizeof(AddrExp), e)
{
    type = t;
}

/************************************************************/

PtrExp::PtrExp(Loc loc, Expression *e)
        : UnaExp(loc, TOKstar, sizeof(PtrExp), e)
{
//    if (e->type)
//      type = ((TypePointer *)e->type)->next;
}

PtrExp::PtrExp(Loc loc, Expression *e, Type *t)
        : UnaExp(loc, TOKstar, sizeof(PtrExp), e)
{
    type = t;
}

bool PtrExp::isLvalue()
{
    return true;
}

Expression *PtrExp::toLvalue(Scope *, Expression *)
{
    return this;
}

int PtrExp::checkModifiable(Scope *sc, int flag)
{
    if (e1->op == TOKsymoff)
    {   SymOffExp *se = (SymOffExp *)e1;
        return se->var->checkModify(loc, sc, type, NULL, flag);
    }
    else if (e1->op == TOKaddress)
    {
        AddrExp *ae = (AddrExp *)e1;
        return ae->e1->checkModifiable(sc, flag);
    }
    return 1;
}

Expression *PtrExp::modifiableLvalue(Scope *sc, Expression *e)
{
    //printf("PtrExp::modifiableLvalue() %s, type %s\n", toChars(), type->toChars());
    return Expression::modifiableLvalue(sc, e);
}

/************************************************************/

NegExp::NegExp(Loc loc, Expression *e)
        : UnaExp(loc, TOKneg, sizeof(NegExp), e)
{
}

/************************************************************/

UAddExp::UAddExp(Loc loc, Expression *e)
        : UnaExp(loc, TOKuadd, sizeof(UAddExp), e)
{
}

/************************************************************/

ComExp::ComExp(Loc loc, Expression *e)
        : UnaExp(loc, TOKtilde, sizeof(ComExp), e)
{
}

/************************************************************/

NotExp::NotExp(Loc loc, Expression *e)
        : UnaExp(loc, TOKnot, sizeof(NotExp), e)
{
}

/************************************************************/

DeleteExp::DeleteExp(Loc loc, Expression *e, bool isRAII)
        : UnaExp(loc, TOKdelete, sizeof(DeleteExp), e)
{
    this->isRAII = isRAII;
}

Expression *DeleteExp::toBoolean(Scope *)
{
    error("delete does not give a boolean result");
    return new ErrorExp();
}

/************************************************************/

CastExp::CastExp(Loc loc, Expression *e, Type *t)
        : UnaExp(loc, TOKcast, sizeof(CastExp), e)
{
    this->to = t;
    this->mod = (unsigned char)~0;
}

/* For cast(const) and cast(immutable)
 */
CastExp::CastExp(Loc loc, Expression *e, unsigned char mod)
        : UnaExp(loc, TOKcast, sizeof(CastExp), e)
{
    this->to = NULL;
    this->mod = mod;
}

Expression *CastExp::syntaxCopy()
{
    return to ? new CastExp(loc, e1->syntaxCopy(), to->syntaxCopy())
              : new CastExp(loc, e1->syntaxCopy(), mod);
}

/************************************************************/

VectorExp::VectorExp(Loc loc, Expression *e, Type *t)
        : UnaExp(loc, TOKvector, sizeof(VectorExp), e)
{
    assert(t->ty == Tvector);
    to = (TypeVector *)t;
    dim = ~0;
    ownedByCtfe = OWNEDcode;
}

VectorExp *VectorExp::create(Loc loc, Expression *e, Type *t)
{
    return new VectorExp(loc, e, t);
}

Expression *VectorExp::syntaxCopy()
{
    return new VectorExp(loc, e1->syntaxCopy(), to->syntaxCopy());
}

/************************************************************/

VectorArrayExp::VectorArrayExp(Loc loc, Expression *e1)
        : UnaExp(loc, TOKvectorarray, sizeof(VectorExp), e1)
{
}

bool VectorArrayExp::isLvalue()
{
    return e1->isLvalue();
}

Expression *VectorArrayExp::toLvalue(Scope *sc, Expression *e)
{
    e1 = e1->toLvalue(sc, e);
    return this;
}

/************************************************************/

SliceExp::SliceExp(Loc loc, Expression *e1, IntervalExp *ie)
        : UnaExp(loc, TOKslice, sizeof(SliceExp), e1)
{
    this->upr = ie ? ie->upr : NULL;
    this->lwr = ie ? ie->lwr : NULL;
    lengthVar = NULL;
    upperIsInBounds = false;
    lowerIsLessThanUpper = false;
    arrayop = false;
}

SliceExp::SliceExp(Loc loc, Expression *e1, Expression *lwr, Expression *upr)
        : UnaExp(loc, TOKslice, sizeof(SliceExp), e1)
{
    this->upr = upr;
    this->lwr = lwr;
    lengthVar = NULL;
    upperIsInBounds = false;
    lowerIsLessThanUpper = false;
    arrayop = false;
}

Expression *SliceExp::syntaxCopy()
{
    SliceExp *se = new SliceExp(loc, e1->syntaxCopy(),
        lwr ? lwr->syntaxCopy() : NULL,
        upr ? upr->syntaxCopy() : NULL);
    se->lengthVar = this->lengthVar;    // bug7871
    return se;
}

int SliceExp::checkModifiable(Scope *sc, int flag)
{
    //printf("SliceExp::checkModifiable %s\n", toChars());
    if (e1->type->ty == Tsarray ||
        (e1->op == TOKindex && e1->type->ty != Tarray) ||
        e1->op == TOKslice)
    {
        return e1->checkModifiable(sc, flag);
    }
    return 1;
}

bool SliceExp::isLvalue()
{
    /* slice expression is rvalue in default, but
     * conversion to reference of static array is only allowed.
     */
    return (type && type->toBasetype()->ty == Tsarray);
}

Expression *SliceExp::toLvalue(Scope *sc, Expression *e)
{
    //printf("SliceExp::toLvalue(%s) type = %s\n", toChars(), type ? type->toChars() : NULL);
    return (type && type->toBasetype()->ty == Tsarray)
            ? this : Expression::toLvalue(sc, e);
}

Expression *SliceExp::modifiableLvalue(Scope *, Expression *)
{
    error("slice expression %s is not a modifiable lvalue", toChars());
    return this;
}

bool SliceExp::isBool(bool result)
{
    return e1->isBool(result);
}

/********************** ArrayLength **************************************/

ArrayLengthExp::ArrayLengthExp(Loc loc, Expression *e1)
        : UnaExp(loc, TOKarraylength, sizeof(ArrayLengthExp), e1)
{
}

Expression *opAssignToOp(Loc loc, TOK op, Expression *e1, Expression *e2)
{   Expression *e;

    switch (op)
    {
        case TOKaddass:   e = new AddExp(loc, e1, e2);  break;
        case TOKminass:   e = new MinExp(loc, e1, e2);  break;
        case TOKmulass:   e = new MulExp(loc, e1, e2);  break;
        case TOKdivass:   e = new DivExp(loc, e1, e2);  break;
        case TOKmodass:   e = new ModExp(loc, e1, e2);  break;
        case TOKandass:   e = new AndExp(loc, e1, e2);  break;
        case TOKorass:    e = new OrExp (loc, e1, e2);  break;
        case TOKxorass:   e = new XorExp(loc, e1, e2);  break;
        case TOKshlass:   e = new ShlExp(loc, e1, e2);  break;
        case TOKshrass:   e = new ShrExp(loc, e1, e2);  break;
        case TOKushrass:  e = new UshrExp(loc, e1, e2); break;
        default:        assert(0);
    }
    return e;
}

/*********************
 * Rewrite:
 *    array.length op= e2
 * as:
 *    array.length = array.length op e2
 * or:
 *    auto tmp = &array;
 *    (*tmp).length = (*tmp).length op e2
 */

Expression *ArrayLengthExp::rewriteOpAssign(BinExp *exp)
{
    Expression *e;

    assert(exp->e1->op == TOKarraylength);
    ArrayLengthExp *ale = (ArrayLengthExp *)exp->e1;
    if (ale->e1->op == TOKvar)
    {
        e = opAssignToOp(exp->loc, exp->op, ale, exp->e2);
        e = new AssignExp(exp->loc, ale->syntaxCopy(), e);
    }
    else
    {
        /*    auto tmp = &array;
         *    (*tmp).length = (*tmp).length op e2
         */
        VarDeclaration *tmp = copyToTemp(0, "__arraylength", new AddrExp(ale->loc, ale->e1));

        Expression *e1 = new ArrayLengthExp(ale->loc, new PtrExp(ale->loc, new VarExp(ale->loc, tmp)));
        Expression *elvalue = e1->syntaxCopy();
        e = opAssignToOp(exp->loc, exp->op, e1, exp->e2);
        e = new AssignExp(exp->loc, elvalue, e);
        e = new CommaExp(exp->loc, new DeclarationExp(ale->loc, tmp), e);
    }
    return e;
}

/*********************** IntervalExp ********************************/

// Mainly just a placeholder

IntervalExp::IntervalExp(Loc loc, Expression *lwr, Expression *upr)
        : Expression(loc, TOKinterval, sizeof(IntervalExp))
{
    this->lwr = lwr;
    this->upr = upr;
}

Expression *IntervalExp::syntaxCopy()
{
    return new IntervalExp(loc, lwr->syntaxCopy(), upr->syntaxCopy());
}

/********************** DelegatePtrExp **************************************/

DelegatePtrExp::DelegatePtrExp(Loc loc, Expression *e1)
        : UnaExp(loc, TOKdelegateptr, sizeof(DelegatePtrExp), e1)
{
}

bool DelegatePtrExp::isLvalue()
{
    return e1->isLvalue();
}

Expression *DelegatePtrExp::toLvalue(Scope *sc, Expression *e)
{
    e1 = e1->toLvalue(sc, e);
    return this;
}

Expression *DelegatePtrExp::modifiableLvalue(Scope *sc, Expression *e)
{
    if (sc->func->setUnsafe())
    {
        error("cannot modify delegate pointer in @safe code %s", toChars());
        return new ErrorExp();
    }
    return Expression::modifiableLvalue(sc, e);
}

/********************** DelegateFuncptrExp **************************************/

DelegateFuncptrExp::DelegateFuncptrExp(Loc loc, Expression *e1)
        : UnaExp(loc, TOKdelegatefuncptr, sizeof(DelegateFuncptrExp), e1)
{
}

bool DelegateFuncptrExp::isLvalue()
{
    return e1->isLvalue();
}

Expression *DelegateFuncptrExp::toLvalue(Scope *sc, Expression *e)
{
    e1 = e1->toLvalue(sc, e);
    return this;
}

Expression *DelegateFuncptrExp::modifiableLvalue(Scope *sc, Expression *e)
{
    if (sc->func->setUnsafe())
    {
        error("cannot modify delegate function pointer in @safe code %s", toChars());
        return new ErrorExp();
    }
    return Expression::modifiableLvalue(sc, e);
}

/*********************** ArrayExp *************************************/

// e1 [ i1, i2, i3, ... ]

ArrayExp::ArrayExp(Loc loc, Expression *e1, Expression *index)
        : UnaExp(loc, TOKarray, sizeof(ArrayExp), e1)
{
    arguments = new Expressions();
    if (index)
        arguments->push(index);
    lengthVar = NULL;
    currentDimension = 0;
}

ArrayExp::ArrayExp(Loc loc, Expression *e1, Expressions *args)
        : UnaExp(loc, TOKarray, sizeof(ArrayExp), e1)
{
    arguments = args;
    lengthVar = NULL;
    currentDimension = 0;
}

Expression *ArrayExp::syntaxCopy()
{
    ArrayExp *ae = new ArrayExp(loc, e1->syntaxCopy(), arraySyntaxCopy(arguments));
    ae->lengthVar = this->lengthVar;    // bug7871
    return ae;
}

bool ArrayExp::isLvalue()
{
    if (type && type->toBasetype()->ty == Tvoid)
        return false;
    return true;
}

Expression *ArrayExp::toLvalue(Scope *, Expression *)
{
    if (type && type->toBasetype()->ty == Tvoid)
        error("voids have no value");
    return this;
}

/************************* DotExp ***********************************/

DotExp::DotExp(Loc loc, Expression *e1, Expression *e2)
        : BinExp(loc, TOKdot, sizeof(DotExp), e1, e2)
{
}

/************************* CommaExp ***********************************/

CommaExp::CommaExp(Loc loc, Expression *e1, Expression *e2, bool generated)
        : BinExp(loc, TOKcomma, sizeof(CommaExp), e1, e2)
{
    isGenerated = generated;
    allowCommaExp = generated;
}

bool CommaExp::isLvalue()
{
    return e2->isLvalue();
}

Expression *CommaExp::toLvalue(Scope *sc, Expression *)
{
    e2 = e2->toLvalue(sc, NULL);
    return this;
}

int CommaExp::checkModifiable(Scope *sc, int flag)
{
    return e2->checkModifiable(sc, flag);
}

Expression *CommaExp::modifiableLvalue(Scope *sc, Expression *e)
{
    e2 = e2->modifiableLvalue(sc, e);
    return this;
}

bool CommaExp::isBool(bool result)
{
    return e2->isBool(result);
}

Expression *CommaExp::toBoolean(Scope *sc)
{
    Expression *ex2 = e2->toBoolean(sc);
    if (ex2->op == TOKerror)
        return ex2;
    e2 = ex2;
    type = e2->type;
    return this;
}

Expression *CommaExp::addDtorHook(Scope *sc)
{
    e2 = e2->addDtorHook(sc);
    return this;
}

/************************** IndexExp **********************************/

// e1 [ e2 ]

IndexExp::IndexExp(Loc loc, Expression *e1, Expression *e2)
        : BinExp(loc, TOKindex, sizeof(IndexExp), e1, e2)
{
    //printf("IndexExp::IndexExp('%s')\n", toChars());
    lengthVar = NULL;
    modifiable = false;     // assume it is an rvalue
    indexIsInBounds = false;
}

Expression *IndexExp::syntaxCopy()
{
    IndexExp *ie = new IndexExp(loc, e1->syntaxCopy(), e2->syntaxCopy());
    ie->lengthVar = this->lengthVar;    // bug7871
    return ie;
}

bool IndexExp::isLvalue()
{
    return true;
}

Expression *IndexExp::toLvalue(Scope *, Expression *)
{
    return this;
}

int IndexExp::checkModifiable(Scope *sc, int flag)
{
    if (e1->type->ty == Tsarray ||
        e1->type->ty == Taarray ||
        (e1->op == TOKindex && e1->type->ty != Tarray) ||
        e1->op == TOKslice)
    {
        return e1->checkModifiable(sc, flag);
    }
    return 1;
}

Expression *IndexExp::modifiableLvalue(Scope *sc, Expression *e)
{
    //printf("IndexExp::modifiableLvalue(%s)\n", toChars());
    Expression *ex = markSettingAAElem();
    if (ex->op == TOKerror)
        return ex;

    return Expression::modifiableLvalue(sc, e);
}

Expression *IndexExp::markSettingAAElem()
{
    if (e1->type->toBasetype()->ty == Taarray)
    {
        Type *t2b = e2->type->toBasetype();
        if (t2b->ty == Tarray && t2b->nextOf()->isMutable())
        {
            error("associative arrays can only be assigned values with immutable keys, not %s", e2->type->toChars());
            return new ErrorExp();
        }
        modifiable = true;

        if (e1->op == TOKindex)
        {
            Expression *ex = ((IndexExp *)e1)->markSettingAAElem();
            if (ex->op == TOKerror)
                return ex;
            assert(ex == e1);
        }
    }
    return this;
}

/************************* PostExp ***********************************/

PostExp::PostExp(TOK op, Loc loc, Expression *e)
        : BinExp(loc, op, sizeof(PostExp), e,
          new IntegerExp(loc, 1, Type::tint32))
{
}

/************************* PreExp ***********************************/

PreExp::PreExp(TOK op, Loc loc, Expression *e)
        : UnaExp(loc, op, sizeof(PreExp), e)
{
}

/************************************************************/

/* op can be TOKassign, TOKconstruct, or TOKblit */

AssignExp::AssignExp(Loc loc, Expression *e1, Expression *e2)
        : BinExp(loc, TOKassign, sizeof(AssignExp), e1, e2)
{
    memset = 0;
}

bool AssignExp::isLvalue()
{
    // Array-op 'x[] = y[]' should make an rvalue.
    // Setting array length 'x.length = v' should make an rvalue.
    if (e1->op == TOKslice ||
        e1->op == TOKarraylength)
    {
        return false;
    }
    return true;
}

Expression *AssignExp::toLvalue(Scope *sc, Expression *ex)
{
    if (e1->op == TOKslice ||
        e1->op == TOKarraylength)
    {
        return Expression::toLvalue(sc, ex);
    }

    /* In front-end level, AssignExp should make an lvalue of e1.
     * Taking the address of e1 will be handled in low level layer,
     * so this function does nothing.
     */
    return this;
}

Expression *AssignExp::toBoolean(Scope *)
{
    // Things like:
    //  if (a = b) ...
    // are usually mistakes.

    error("assignment cannot be used as a condition, perhaps == was meant?");
    return new ErrorExp();
}

/************************************************************/

ConstructExp::ConstructExp(Loc loc, Expression *e1, Expression *e2)
    : AssignExp(loc, e1, e2)
{
    op = TOKconstruct;
}

ConstructExp::ConstructExp(Loc loc, VarDeclaration *v, Expression *e2)
    : AssignExp(loc, new VarExp(loc, v), e2)
{
    assert(v->type && e1->type);
    op = TOKconstruct;

    if (v->storage_class & (STCref | STCout))
        memset |= referenceInit;
}

/************************************************************/

BlitExp::BlitExp(Loc loc, Expression *e1, Expression *e2)
    : AssignExp(loc, e1, e2)
{
    op = TOKblit;
}

BlitExp::BlitExp(Loc loc, VarDeclaration *v, Expression *e2)
    : AssignExp(loc, new VarExp(loc, v), e2)
{
    assert(v->type && e1->type);
    op = TOKblit;

    if (v->storage_class & (STCref | STCout))
        memset |= referenceInit;
}

/************************************************************/

AddAssignExp::AddAssignExp(Loc loc, Expression *e1, Expression *e2)
        : BinAssignExp(loc, TOKaddass, sizeof(AddAssignExp), e1, e2)
{
}

/************************************************************/

MinAssignExp::MinAssignExp(Loc loc, Expression *e1, Expression *e2)
        : BinAssignExp(loc, TOKminass, sizeof(MinAssignExp), e1, e2)
{
}

/************************************************************/

CatAssignExp::CatAssignExp(Loc loc, Expression *e1, Expression *e2)
        : BinAssignExp(loc, TOKcatass, sizeof(CatAssignExp), e1, e2)
{
}

/************************************************************/

MulAssignExp::MulAssignExp(Loc loc, Expression *e1, Expression *e2)
        : BinAssignExp(loc, TOKmulass, sizeof(MulAssignExp), e1, e2)
{
}

/************************************************************/

DivAssignExp::DivAssignExp(Loc loc, Expression *e1, Expression *e2)
        : BinAssignExp(loc, TOKdivass, sizeof(DivAssignExp), e1, e2)
{
}

/************************************************************/

ModAssignExp::ModAssignExp(Loc loc, Expression *e1, Expression *e2)
        : BinAssignExp(loc, TOKmodass, sizeof(ModAssignExp), e1, e2)
{
}

/************************************************************/

ShlAssignExp::ShlAssignExp(Loc loc, Expression *e1, Expression *e2)
        : BinAssignExp(loc, TOKshlass, sizeof(ShlAssignExp), e1, e2)
{
}

/************************************************************/

ShrAssignExp::ShrAssignExp(Loc loc, Expression *e1, Expression *e2)
        : BinAssignExp(loc, TOKshrass, sizeof(ShrAssignExp), e1, e2)
{
}

/************************************************************/

UshrAssignExp::UshrAssignExp(Loc loc, Expression *e1, Expression *e2)
        : BinAssignExp(loc, TOKushrass, sizeof(UshrAssignExp), e1, e2)
{
}

/************************************************************/

AndAssignExp::AndAssignExp(Loc loc, Expression *e1, Expression *e2)
        : BinAssignExp(loc, TOKandass, sizeof(AndAssignExp), e1, e2)
{
}

/************************************************************/

OrAssignExp::OrAssignExp(Loc loc, Expression *e1, Expression *e2)
        : BinAssignExp(loc, TOKorass, sizeof(OrAssignExp), e1, e2)
{
}

/************************************************************/

XorAssignExp::XorAssignExp(Loc loc, Expression *e1, Expression *e2)
        : BinAssignExp(loc, TOKxorass, sizeof(XorAssignExp), e1, e2)
{
}

/***************** PowAssignExp *******************************************/

PowAssignExp::PowAssignExp(Loc loc, Expression *e1, Expression *e2)
        : BinAssignExp(loc, TOKpowass, sizeof(PowAssignExp), e1, e2)
{
}

/************************* AddExp *****************************/

AddExp::AddExp(Loc loc, Expression *e1, Expression *e2)
        : BinExp(loc, TOKadd, sizeof(AddExp), e1, e2)
{
}

/************************************************************/

MinExp::MinExp(Loc loc, Expression *e1, Expression *e2)
        : BinExp(loc, TOKmin, sizeof(MinExp), e1, e2)
{
}

/************************* CatExp *****************************/

CatExp::CatExp(Loc loc, Expression *e1, Expression *e2)
        : BinExp(loc, TOKcat, sizeof(CatExp), e1, e2)
{
}

/************************************************************/

MulExp::MulExp(Loc loc, Expression *e1, Expression *e2)
        : BinExp(loc, TOKmul, sizeof(MulExp), e1, e2)
{
}

/************************************************************/

DivExp::DivExp(Loc loc, Expression *e1, Expression *e2)
        : BinExp(loc, TOKdiv, sizeof(DivExp), e1, e2)
{
}

/************************************************************/

ModExp::ModExp(Loc loc, Expression *e1, Expression *e2)
        : BinExp(loc, TOKmod, sizeof(ModExp), e1, e2)
{
}

/************************************************************/

PowExp::PowExp(Loc loc, Expression *e1, Expression *e2)
        : BinExp(loc, TOKpow, sizeof(PowExp), e1, e2)
{
}

/************************************************************/

ShlExp::ShlExp(Loc loc, Expression *e1, Expression *e2)
        : BinExp(loc, TOKshl, sizeof(ShlExp), e1, e2)
{
}

/************************************************************/

ShrExp::ShrExp(Loc loc, Expression *e1, Expression *e2)
        : BinExp(loc, TOKshr, sizeof(ShrExp), e1, e2)
{
}

/************************************************************/

UshrExp::UshrExp(Loc loc, Expression *e1, Expression *e2)
        : BinExp(loc, TOKushr, sizeof(UshrExp), e1, e2)
{
}

/************************************************************/

AndExp::AndExp(Loc loc, Expression *e1, Expression *e2)
        : BinExp(loc, TOKand, sizeof(AndExp), e1, e2)
{
}

/************************************************************/

OrExp::OrExp(Loc loc, Expression *e1, Expression *e2)
        : BinExp(loc, TOKor, sizeof(OrExp), e1, e2)
{
}

/************************************************************/

XorExp::XorExp(Loc loc, Expression *e1, Expression *e2)
        : BinExp(loc, TOKxor, sizeof(XorExp), e1, e2)
{
}

/************************************************************/

OrOrExp::OrOrExp(Loc loc, Expression *e1, Expression *e2)
        : BinExp(loc, TOKoror, sizeof(OrOrExp), e1, e2)
{
}

Expression *OrOrExp::toBoolean(Scope *sc)
{
    Expression *ex2 = e2->toBoolean(sc);
    if (ex2->op == TOKerror)
        return ex2;
    e2 = ex2;
    return this;
}

/************************************************************/

AndAndExp::AndAndExp(Loc loc, Expression *e1, Expression *e2)
        : BinExp(loc, TOKandand, sizeof(AndAndExp), e1, e2)
{
}

Expression *AndAndExp::toBoolean(Scope *sc)
{
    Expression *ex2 = e2->toBoolean(sc);
    if (ex2->op == TOKerror)
        return ex2;
    e2 = ex2;
    return this;
}

/************************************************************/

InExp::InExp(Loc loc, Expression *e1, Expression *e2)
        : BinExp(loc, TOKin, sizeof(InExp), e1, e2)
{
}

/************************************************************/

/* This deletes the key e1 from the associative array e2
 */

RemoveExp::RemoveExp(Loc loc, Expression *e1, Expression *e2)
        : BinExp(loc, TOKremove, sizeof(RemoveExp), e1, e2)
{
    type = Type::tbool;
}

/************************************************************/

CmpExp::CmpExp(TOK op, Loc loc, Expression *e1, Expression *e2)
        : BinExp(loc, op, sizeof(CmpExp), e1, e2)
{
}

/************************************************************/

EqualExp::EqualExp(TOK op, Loc loc, Expression *e1, Expression *e2)
        : BinExp(loc, op, sizeof(EqualExp), e1, e2)
{
    assert(op == TOKequal || op == TOKnotequal);
}

/************************************************************/

IdentityExp::IdentityExp(TOK op, Loc loc, Expression *e1, Expression *e2)
        : BinExp(loc, op, sizeof(IdentityExp), e1, e2)
{
}

/****************************************************************/

CondExp::CondExp(Loc loc, Expression *econd, Expression *e1, Expression *e2)
        : BinExp(loc, TOKquestion, sizeof(CondExp), e1, e2)
{
    this->econd = econd;
}

Expression *CondExp::syntaxCopy()
{
    return new CondExp(loc, econd->syntaxCopy(), e1->syntaxCopy(), e2->syntaxCopy());
}

void CondExp::hookDtors(Scope *sc)
{
    class DtorVisitor : public StoppableVisitor
    {
    public:
        Scope *sc;
        CondExp *ce;
        VarDeclaration *vcond;
        bool isThen;

        DtorVisitor(Scope *sc, CondExp *ce)
        {
            this->sc = sc;
            this->ce = ce;
            this->vcond = NULL;
        }

        void visit(Expression *)
        {
            //printf("(e = %s)\n", e->toChars());
        }

        void visit(DeclarationExp *e)
        {
            VarDeclaration *v = e->declaration->isVarDeclaration();
            if (v && !v->isDataseg())
            {
                if (v->_init)
                {
                    ExpInitializer *ei = v->_init->isExpInitializer();
                    if (ei)
                        ei->exp->accept(this);
                }

                if (v->needsScopeDtor())
                {
                    if (!vcond)
                    {
                        vcond = copyToTemp(STCvolatile, "__cond", ce->econd);
                        vcond->semantic(sc);

                        Expression *de = new DeclarationExp(ce->econd->loc, vcond);
                        de = semantic(de, sc);

                        Expression *ve = new VarExp(ce->econd->loc, vcond);
                        ce->econd = Expression::combine(de, ve);
                    }

                    //printf("\t++v = %s, v->edtor = %s\n", v->toChars(), v->edtor->toChars());
                    Expression *ve = new VarExp(vcond->loc, vcond);
                    if (isThen)
                        v->edtor = new AndAndExp(v->edtor->loc, ve, v->edtor);
                    else
                        v->edtor = new OrOrExp(v->edtor->loc, ve, v->edtor);
                    v->edtor = semantic(v->edtor, sc);
                    //printf("\t--v = %s, v->edtor = %s\n", v->toChars(), v->edtor->toChars());
                }
            }
        }
    };

    DtorVisitor v(sc, this);
    //printf("+%s\n", toChars());
    v.isThen = true;    walkPostorder(e1, &v);
    v.isThen = false;   walkPostorder(e2, &v);
    //printf("-%s\n", toChars());
}

bool CondExp::isLvalue()
{
    return e1->isLvalue() && e2->isLvalue();
}


Expression *CondExp::toLvalue(Scope *sc, Expression *)
{
    // convert (econd ? e1 : e2) to *(econd ? &e1 : &e2)
    CondExp *e = (CondExp *)copy();
    e->e1 = e1->toLvalue(sc, NULL)->addressOf();
    e->e2 = e2->toLvalue(sc, NULL)->addressOf();
    e->type = type->pointerTo();
    return new PtrExp(loc, e, type);
}

int CondExp::checkModifiable(Scope *sc, int flag)
{
    return e1->checkModifiable(sc, flag) && e2->checkModifiable(sc, flag);
}

Expression *CondExp::modifiableLvalue(Scope *sc, Expression *)
{
    //error("conditional expression %s is not a modifiable lvalue", toChars());
    e1 = e1->modifiableLvalue(sc, e1);
    e2 = e2->modifiableLvalue(sc, e2);
    return toLvalue(sc, this);
}

Expression *CondExp::toBoolean(Scope *sc)
{
    Expression *ex1 = e1->toBoolean(sc);
    Expression *ex2 = e2->toBoolean(sc);
    if (ex1->op == TOKerror)
        return ex1;
    if (ex2->op == TOKerror)
        return ex2;
    e1 = ex1;
    e2 = ex2;
    return this;
}

/****************************************************************/

DefaultInitExp::DefaultInitExp(Loc loc, TOK subop, int size)
    : Expression(loc, TOKdefault, size)
{
    this->subop = subop;
}

/****************************************************************/

FileInitExp::FileInitExp(Loc loc, TOK tok)
    : DefaultInitExp(loc, tok, sizeof(FileInitExp))
{
}

Expression *FileInitExp::resolveLoc(Loc loc, Scope *sc)
{
    //printf("FileInitExp::resolve() %s\n", toChars());
    const char *s = loc.filename ? loc.filename : sc->_module->ident->toChars();
    if (subop == TOKfilefullpath)
        s = FileName::combine(sc->_module->srcfilePath, s);
    Expression *e = new StringExp(loc, const_cast<char *>(s));
    e = semantic(e, sc);
    e = e->castTo(sc, type);
    return e;
}

/****************************************************************/

LineInitExp::LineInitExp(Loc loc)
    : DefaultInitExp(loc, TOKline, sizeof(LineInitExp))
{
}

Expression *LineInitExp::resolveLoc(Loc loc, Scope *sc)
{
    Expression *e = new IntegerExp(loc, loc.linnum, Type::tint32);
    e = e->castTo(sc, type);
    return e;
}

/****************************************************************/

ModuleInitExp::ModuleInitExp(Loc loc)
    : DefaultInitExp(loc, TOKmodulestring, sizeof(ModuleInitExp))
{
}

Expression *ModuleInitExp::resolveLoc(Loc loc, Scope *sc)
{
    const char *s;
    if (sc->callsc)
        s = sc->callsc->_module->toPrettyChars();
    else
        s = sc->_module->toPrettyChars();
    Expression *e = new StringExp(loc, const_cast<char *>(s));
    e = semantic(e, sc);
    e = e->castTo(sc, type);
    return e;
}

/****************************************************************/

FuncInitExp::FuncInitExp(Loc loc)
    : DefaultInitExp(loc, TOKfuncstring, sizeof(FuncInitExp))
{
}

Expression *FuncInitExp::resolveLoc(Loc loc, Scope *sc)
{
    const char *s;
    if (sc->callsc && sc->callsc->func)
        s = sc->callsc->func->Dsymbol::toPrettyChars();
    else if (sc->func)
        s = sc->func->Dsymbol::toPrettyChars();
    else
        s = "";
    Expression *e = new StringExp(loc, const_cast<char *>(s));
    e = semantic(e, sc);
    e->type = Type::tstring;
    return e;
}

/****************************************************************/

PrettyFuncInitExp::PrettyFuncInitExp(Loc loc)
    : DefaultInitExp(loc, TOKprettyfunc, sizeof(PrettyFuncInitExp))
{
}

Expression *PrettyFuncInitExp::resolveLoc(Loc loc, Scope *sc)
{
    FuncDeclaration *fd;
    if (sc->callsc && sc->callsc->func)
        fd = sc->callsc->func;
    else
        fd = sc->func;

    const char *s;
    if (fd)
    {
        const char *funcStr = fd->Dsymbol::toPrettyChars();
        OutBuffer buf;
        functionToBufferWithIdent((TypeFunction *)fd->type, &buf, funcStr);
        s = buf.extractString();
    }
    else
    {
        s = "";
    }

    Expression *e = new StringExp(loc, const_cast<char *>(s));
    e = semantic(e, sc);
    e->type = Type::tstring;
    return e;
}

/****************************************************************/

Expression *extractOpDollarSideEffect(Scope *sc, UnaExp *ue)
{
    Expression *e0;
    Expression *e1 = Expression::extractLast(ue->e1, &e0);
    // Bugzilla 12585: Extract the side effect part if ue->e1 is comma.

    if (!isTrivialExp(e1))
    {
        /* Even if opDollar is needed, 'e1' should be evaluate only once. So
         * Rewrite:
         *      e1.opIndex( ... use of $ ... )
         *      e1.opSlice( ... use of $ ... )
         * as:
         *      (ref __dop = e1, __dop).opIndex( ... __dop.opDollar ...)
         *      (ref __dop = e1, __dop).opSlice( ... __dop.opDollar ...)
         */
        e1 = extractSideEffect(sc, "__dop", &e0, e1, false);
        assert(e1->op == TOKvar);
        VarExp *ve = (VarExp *)e1;
        ve->var->storage_class |= STCexptemp;     // lifetime limited to expression
    }
    ue->e1 = e1;
    return e0;
}

/**************************************
 * Runs semantic on ae->arguments. Declares temporary variables
 * if '$' was used.
 */
Expression *resolveOpDollar(Scope *sc, ArrayExp *ae, Expression **pe0)
{
    assert(!ae->lengthVar);

    *pe0 = NULL;

    AggregateDeclaration *ad = isAggregate(ae->e1->type);
    Dsymbol *slice = search_function(ad, Id::slice);
    //printf("slice = %s %s\n", slice->kind(), slice->toChars());

    for (size_t i = 0; i < ae->arguments->dim; i++)
    {
        if (i == 0)
            *pe0 = extractOpDollarSideEffect(sc, ae);

        Expression *e = (*ae->arguments)[i];
        if (e->op == TOKinterval && !(slice && slice->isTemplateDeclaration()))
        {
        Lfallback:
            if (ae->arguments->dim == 1)
                return NULL;
            ae->error("multi-dimensional slicing requires template opSlice");
            return new ErrorExp();
        }
        //printf("[%d] e = %s\n", i, e->toChars());

        // Create scope for '$' variable for this dimension
        ArrayScopeSymbol *sym = new ArrayScopeSymbol(sc, ae);
        sym->loc = ae->loc;
        sym->parent = sc->scopesym;
        sc = sc->push(sym);
        ae->lengthVar = NULL;       // Create it only if required
        ae->currentDimension = i;   // Dimension for $, if required

        e = semantic(e, sc);
        e = resolveProperties(sc, e);

        if (ae->lengthVar && sc->func)
        {
            // If $ was used, declare it now
            Expression *de = new DeclarationExp(ae->loc, ae->lengthVar);
            de = semantic(de, sc);
            *pe0 = Expression::combine(*pe0, de);
        }
        sc = sc->pop();

        if (e->op == TOKinterval)
        {
            IntervalExp *ie = (IntervalExp *)e;

            Objects *tiargs = new Objects();
            Expression *edim = new IntegerExp(ae->loc, i, Type::tsize_t);
            edim = semantic(edim, sc);
            tiargs->push(edim);

            Expressions *fargs = new Expressions();
            fargs->push(ie->lwr);
            fargs->push(ie->upr);

            unsigned xerrors = global.startGagging();
            sc = sc->push();
            FuncDeclaration *fslice = resolveFuncCall(ae->loc, sc, slice, tiargs, ae->e1->type, fargs, 1);
            sc = sc->pop();
            global.endGagging(xerrors);
            if (!fslice)
                goto Lfallback;

            e = new DotTemplateInstanceExp(ae->loc, ae->e1, slice->ident, tiargs);
            e = new CallExp(ae->loc, e, fargs);
            e = semantic(e, sc);
        }

        if (!e->type)
        {
            ae->error("%s has no value", e->toChars());
            e = new ErrorExp();
        }
        if (e->op == TOKerror)
            return e;

        (*ae->arguments)[i] = e;
    }

    return ae;
}

/***********************************************************
 * Resolve `exp` as a compile-time known string.
 * Params:
 *  sc  = scope
 *  exp = Expression which expected as a string
 *  s   = What the string is expected for, will be used in error diagnostic.
 * Returns:
 *  String literal, or `null` if error happens.
 */
StringExp *semanticString(Scope *sc, Expression *exp, const char *s)
{
    sc = sc->startCTFE();
    exp = semantic(exp, sc);
    exp = resolveProperties(sc, exp);
    sc = sc->endCTFE();

    if (exp->op == TOKerror)
        return NULL;

    Expression *e = exp;
    if (exp->type->isString())
    {
        e = e->ctfeInterpret();
        if (e->op == TOKerror)
            return NULL;
    }

    StringExp *se = e->toStringExp();
    if (!se)
    {
        exp->error("string expected for %s, not (%s) of type %s",
            s, exp->toChars(), exp->type->toChars());
        return NULL;
    }
    return se;
}

/**************************************
 * Runs semantic on se->lwr and se->upr. Declares a temporary variable
 * if '$' was used.
 */
Expression *resolveOpDollar(Scope *sc, ArrayExp *ae, IntervalExp *ie, Expression **pe0)
{
    //assert(!ae->lengthVar);
    if (!ie)
        return ae;

    VarDeclaration *lengthVar = ae->lengthVar;

    // create scope for '$'
    ArrayScopeSymbol *sym = new ArrayScopeSymbol(sc, ae);
    sym->loc = ae->loc;
    sym->parent = sc->scopesym;
    sc = sc->push(sym);

    for (size_t i = 0; i < 2; ++i)
    {
        Expression *e = i == 0 ? ie->lwr : ie->upr;
        e = semantic(e, sc);
        e = resolveProperties(sc, e);
        if (!e->type)
        {
            ae->error("%s has no value", e->toChars());
            return new ErrorExp();
        }
        (i == 0 ? ie->lwr : ie->upr) = e;
    }

    if (lengthVar != ae->lengthVar && sc->func)
    {
        // If $ was used, declare it now
        Expression *de = new DeclarationExp(ae->loc, ae->lengthVar);
        de = semantic(de, sc);
        *pe0 = Expression::combine(*pe0, de);
    }
    sc = sc->pop();

    return ae;
}

Expression *BinExp::reorderSettingAAElem(Scope *sc)
{
    BinExp *be = this;

    if (be->e1->op != TOKindex)
        return be;
    IndexExp *ie = (IndexExp *)be->e1;
    if (ie->e1->type->toBasetype()->ty != Taarray)
        return be;

    /* Fix evaluation order of setting AA element. (Bugzilla 3825)
     * Rewrite:
     *     aa[k1][k2][k3] op= val;
     * as:
     *     auto ref __aatmp = aa;
     *     auto ref __aakey3 = k1, __aakey2 = k2, __aakey1 = k3;
     *     auto ref __aaval = val;
     *     __aatmp[__aakey3][__aakey2][__aakey1] op= __aaval;  // assignment
     */

    Expression *e0 = NULL;
    while (1)
    {
        Expression *de = NULL;
        ie->e2 = extractSideEffect(sc, "__aakey", &de, ie->e2);
        e0 = Expression::combine(de, e0);

        Expression *ie1 = ie->e1;
        if (ie1->op != TOKindex ||
            ((IndexExp *)ie1)->e1->type->toBasetype()->ty != Taarray)
        {
            break;
        }
        ie = (IndexExp *)ie1;
    }
    assert(ie->e1->type->toBasetype()->ty == Taarray);

    Expression *de = NULL;
    ie->e1 = extractSideEffect(sc, "__aatmp", &de, ie->e1);
    e0 = Expression::combine(de, e0);

    be->e2 = extractSideEffect(sc, "__aaval", &e0, be->e2, true);

    //printf("-e0 = %s, be = %s\n", e0->toChars(), be->toChars());
    return Expression::combine(e0, be);
}
