/**
 * Perform constant folding of arithmetic expressions.
 *
 * The routines in this module are called from `optimize.d`.
 *
 * Specification: $(LINK2 https://dlang.org/spec/float.html#fp_const_folding, Floating Point Constant Folding)
 *
 * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
 * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
 * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
 * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/constfold.d, _constfold.d)
 * Documentation:  https://dlang.org/phobos/dmd_constfold.html
 * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/constfold.d
 */

module dmd.constfold;

import core.stdc.string;
import core.stdc.stdio;
import dmd.arraytypes;
import dmd.astenums;
import dmd.ctfeexpr;
import dmd.declaration;
import dmd.dstruct;
import dmd.errors;
import dmd.expression;
import dmd.globals;
import dmd.mtype;
import dmd.root.complex;
import dmd.root.ctfloat;
import dmd.root.port;
import dmd.root.rmem;
import dmd.root.utf;
import dmd.sideeffect;
import dmd.target;
import dmd.tokens;

private enum LOG = false;

private Expression expType(Type type, Expression e)
{
    if (type != e.type)
    {
        e = e.copy();
        e.type = type;
    }
    return e;
}

/************************************
 * Returns:
 *    true if e is a constant
 */
int isConst(Expression e)
{
    //printf("Expression::isConst(): %s\n", e.toChars());
    switch (e.op)
    {
    case EXP.int64:
    case EXP.float64:
    case EXP.complex80:
        return 1;
    case EXP.null_:
        return 0;
    case EXP.symbolOffset:
        return 2;
    default:
        return 0;
    }
    assert(0);
}

/**********************************
 * Initialize a EXP.cantExpression Expression.
 * Params:
 *      ue = where to write it
 */
void cantExp(out UnionExp ue)
{
    emplaceExp!(CTFEExp)(&ue, EXP.cantExpression);
}

/* =============================== constFold() ============================== */
/* The constFold() functions were redundant with the optimize() ones,
 * and so have been folded in with them.
 */
/* ========================================================================== */
UnionExp Neg(Type type, Expression e1)
{
    UnionExp ue = void;
    Loc loc = e1.loc;
    if (e1.type.isreal())
    {
        emplaceExp!(RealExp)(&ue, loc, -e1.toReal(), type);
    }
    else if (e1.type.isimaginary())
    {
        emplaceExp!(RealExp)(&ue, loc, -e1.toImaginary(), type);
    }
    else if (e1.type.iscomplex())
    {
        emplaceExp!(ComplexExp)(&ue, loc, -e1.toComplex(), type);
    }
    else
    {
        emplaceExp!(IntegerExp)(&ue, loc, -e1.toInteger(), type);
    }
    return ue;
}

UnionExp Com(Type type, Expression e1)
{
    UnionExp ue = void;
    Loc loc = e1.loc;
    emplaceExp!(IntegerExp)(&ue, loc, ~e1.toInteger(), type);
    return ue;
}

UnionExp Not(Type type, Expression e1)
{
    UnionExp ue = void;
    Loc loc = e1.loc;
    // BUG: Should be replaced with e1.toBool().get(), but this is apparently
    //      executed for some expressions that cannot be const-folded
    //      To be fixed in another PR
    emplaceExp!(IntegerExp)(&ue, loc, e1.toBool().hasValue(false) ? 1 : 0, type);
    return ue;
}

UnionExp Add(const ref Loc loc, Type type, Expression e1, Expression e2)
{
    UnionExp ue = void;
    static if (LOG)
    {
        printf("Add(e1 = %s, e2 = %s)\n", e1.toChars(), e2.toChars());
    }
    if (type.isreal())
    {
        emplaceExp!(RealExp)(&ue, loc, e1.toReal() + e2.toReal(), type);
    }
    else if (type.isimaginary())
    {
        emplaceExp!(RealExp)(&ue, loc, e1.toImaginary() + e2.toImaginary(), type);
    }
    else if (type.iscomplex())
    {
        // This rigamarole is necessary so that -0.0 doesn't get
        // converted to +0.0 by doing an extraneous add with +0.0
        auto c1 = complex_t(CTFloat.zero);
        real_t r1 = CTFloat.zero;
        real_t i1 = CTFloat.zero;
        auto c2 = complex_t(CTFloat.zero);
        real_t r2 = CTFloat.zero;
        real_t i2 = CTFloat.zero;
        auto v = complex_t(CTFloat.zero);
        int x;
        if (e1.type.isreal())
        {
            r1 = e1.toReal();
            x = 0;
        }
        else if (e1.type.isimaginary())
        {
            i1 = e1.toImaginary();
            x = 3;
        }
        else
        {
            c1 = e1.toComplex();
            x = 6;
        }
        if (e2.type.isreal())
        {
            r2 = e2.toReal();
        }
        else if (e2.type.isimaginary())
        {
            i2 = e2.toImaginary();
            x += 1;
        }
        else
        {
            c2 = e2.toComplex();
            x += 2;
        }
        switch (x)
        {
        case 0 + 0:
            v = complex_t(r1 + r2);
            break;
        case 0 + 1:
            v = complex_t(r1, i2);
            break;
        case 0 + 2:
            v = complex_t(r1 + creall(c2), cimagl(c2));
            break;
        case 3 + 0:
            v = complex_t(r2, i1);
            break;
        case 3 + 1:
            v = complex_t(CTFloat.zero, i1 + i2);
            break;
        case 3 + 2:
            v = complex_t(creall(c2), i1 + cimagl(c2));
            break;
        case 6 + 0:
            v = complex_t(creall(c1) + r2, cimagl(c2));
            break;
        case 6 + 1:
            v = complex_t(creall(c1), cimagl(c1) + i2);
            break;
        case 6 + 2:
            v = c1 + c2;
            break;
        default:
            assert(0);
        }
        emplaceExp!(ComplexExp)(&ue, loc, v, type);
    }
    else if (SymOffExp soe = e1.isSymOffExp())
    {
        emplaceExp!(SymOffExp)(&ue, loc, soe.var, soe.offset + e2.toInteger());
        ue.exp().type = type;
    }
    else if (SymOffExp soe = e2.isSymOffExp())
    {
        emplaceExp!(SymOffExp)(&ue, loc, soe.var, soe.offset + e1.toInteger());
        ue.exp().type = type;
    }
    else
        emplaceExp!(IntegerExp)(&ue, loc, e1.toInteger() + e2.toInteger(), type);
    return ue;
}

UnionExp Min(const ref Loc loc, Type type, Expression e1, Expression e2)
{
    UnionExp ue = void;
    if (type.isreal())
    {
        emplaceExp!(RealExp)(&ue, loc, e1.toReal() - e2.toReal(), type);
    }
    else if (type.isimaginary())
    {
        emplaceExp!(RealExp)(&ue, loc, e1.toImaginary() - e2.toImaginary(), type);
    }
    else if (type.iscomplex())
    {
        // This rigamarole is necessary so that -0.0 doesn't get
        // converted to +0.0 by doing an extraneous add with +0.0
        auto c1 = complex_t(CTFloat.zero);
        real_t r1 = CTFloat.zero;
        real_t i1 = CTFloat.zero;
        auto c2 = complex_t(CTFloat.zero);
        real_t r2 = CTFloat.zero;
        real_t i2 = CTFloat.zero;
        auto v = complex_t(CTFloat.zero);
        int x;
        if (e1.type.isreal())
        {
            r1 = e1.toReal();
            x = 0;
        }
        else if (e1.type.isimaginary())
        {
            i1 = e1.toImaginary();
            x = 3;
        }
        else
        {
            c1 = e1.toComplex();
            x = 6;
        }
        if (e2.type.isreal())
        {
            r2 = e2.toReal();
        }
        else if (e2.type.isimaginary())
        {
            i2 = e2.toImaginary();
            x += 1;
        }
        else
        {
            c2 = e2.toComplex();
            x += 2;
        }
        switch (x)
        {
        case 0 + 0:
            v = complex_t(r1 - r2);
            break;
        case 0 + 1:
            v = complex_t(r1, -i2);
            break;
        case 0 + 2:
            v = complex_t(r1 - creall(c2), -cimagl(c2));
            break;
        case 3 + 0:
            v = complex_t(-r2, i1);
            break;
        case 3 + 1:
            v = complex_t(CTFloat.zero, i1 - i2);
            break;
        case 3 + 2:
            v = complex_t(-creall(c2), i1 - cimagl(c2));
            break;
        case 6 + 0:
            v = complex_t(creall(c1) - r2, cimagl(c1));
            break;
        case 6 + 1:
            v = complex_t(creall(c1), cimagl(c1) - i2);
            break;
        case 6 + 2:
            v = c1 - c2;
            break;
        default:
            assert(0);
        }
        emplaceExp!(ComplexExp)(&ue, loc, v, type);
    }
    else if (SymOffExp soe = e1.isSymOffExp())
    {
        emplaceExp!(SymOffExp)(&ue, loc, soe.var, soe.offset - e2.toInteger());
        ue.exp().type = type;
    }
    else
    {
        emplaceExp!(IntegerExp)(&ue, loc, e1.toInteger() - e2.toInteger(), type);
    }
    return ue;
}

UnionExp Mul(const ref Loc loc, Type type, Expression e1, Expression e2)
{
    UnionExp ue = void;
    if (type.isfloating())
    {
        auto c = complex_t(CTFloat.zero);
        real_t r = CTFloat.zero;
        if (e1.type.isreal())
        {
            r = e1.toReal();
            c = e2.toComplex();
            c = complex_t(r * creall(c), r * cimagl(c));
        }
        else if (e1.type.isimaginary())
        {
            r = e1.toImaginary();
            c = e2.toComplex();
            c = complex_t(-r * cimagl(c), r * creall(c));
        }
        else if (e2.type.isreal())
        {
            r = e2.toReal();
            c = e1.toComplex();
            c = complex_t(r * creall(c), r * cimagl(c));
        }
        else if (e2.type.isimaginary())
        {
            r = e2.toImaginary();
            c = e1.toComplex();
            c = complex_t(-r * cimagl(c), r * creall(c));
        }
        else
            c = e1.toComplex() * e2.toComplex();
        if (type.isreal())
            emplaceExp!(RealExp)(&ue, loc, creall(c), type);
        else if (type.isimaginary())
            emplaceExp!(RealExp)(&ue, loc, cimagl(c), type);
        else if (type.iscomplex())
            emplaceExp!(ComplexExp)(&ue, loc, c, type);
        else
            assert(0);
    }
    else
    {
        emplaceExp!(IntegerExp)(&ue, loc, e1.toInteger() * e2.toInteger(), type);
    }
    return ue;
}

UnionExp Div(const ref Loc loc, Type type, Expression e1, Expression e2)
{
    UnionExp ue = void;
    if (type.isfloating())
    {
        auto c = complex_t(CTFloat.zero);
        if (e2.type.isreal())
        {
            if (e1.type.isreal())
            {
                emplaceExp!(RealExp)(&ue, loc, e1.toReal() / e2.toReal(), type);
                return ue;
            }
            const r = e2.toReal();
            c = e1.toComplex();
            c = complex_t(creall(c) / r, cimagl(c) / r);
        }
        else if (e2.type.isimaginary())
        {
            const r = e2.toImaginary();
            c = e1.toComplex();
            c = complex_t(cimagl(c) / r, -creall(c) / r);
        }
        else
        {
            c = e1.toComplex() / e2.toComplex();
        }

        if (type.isreal())
            emplaceExp!(RealExp)(&ue, loc, creall(c), type);
        else if (type.isimaginary())
            emplaceExp!(RealExp)(&ue, loc, cimagl(c), type);
        else if (type.iscomplex())
            emplaceExp!(ComplexExp)(&ue, loc, c, type);
        else
            assert(0);
    }
    else
    {
        sinteger_t n1;
        sinteger_t n2;
        sinteger_t n;
        n1 = e1.toInteger();
        n2 = e2.toInteger();
        if (n2 == 0)
        {
            e2.error("divide by 0");
            emplaceExp!(ErrorExp)(&ue);
            return ue;
        }
        if (n2 == -1 && !type.isunsigned())
        {
            // Check for int.min / -1
            if (n1 == 0xFFFFFFFF80000000UL && type.toBasetype().ty != Tint64)
            {
                e2.error("integer overflow: `int.min / -1`");
                emplaceExp!(ErrorExp)(&ue);
                return ue;
            }
            else if (n1 == 0x8000000000000000L) // long.min / -1
            {
                e2.error("integer overflow: `long.min / -1L`");
                emplaceExp!(ErrorExp)(&ue);
                return ue;
            }
        }
        if (e1.type.isunsigned() || e2.type.isunsigned())
            n = (cast(dinteger_t)n1) / (cast(dinteger_t)n2);
        else
            n = n1 / n2;
        emplaceExp!(IntegerExp)(&ue, loc, n, type);
    }
    return ue;
}

UnionExp Mod(const ref Loc loc, Type type, Expression e1, Expression e2)
{
    UnionExp ue = void;
    if (type.isfloating())
    {
        auto c = complex_t(CTFloat.zero);
        if (e2.type.isreal())
        {
            const r2 = e2.toReal();
            c = complex_t(e1.toReal() % r2, e1.toImaginary() % r2);
        }
        else if (e2.type.isimaginary())
        {
            const i2 = e2.toImaginary();
            c = complex_t(e1.toReal() % i2, e1.toImaginary() % i2);
        }
        else
            assert(0);
        if (type.isreal())
            emplaceExp!(RealExp)(&ue, loc, creall(c), type);
        else if (type.isimaginary())
            emplaceExp!(RealExp)(&ue, loc, cimagl(c), type);
        else if (type.iscomplex())
            emplaceExp!(ComplexExp)(&ue, loc, c, type);
        else
            assert(0);
    }
    else
    {
        sinteger_t n1;
        sinteger_t n2;
        sinteger_t n;
        n1 = e1.toInteger();
        n2 = e2.toInteger();
        if (n2 == 0)
        {
            e2.error("divide by 0");
            emplaceExp!(ErrorExp)(&ue);
            return ue;
        }
        if (n2 == -1 && !type.isunsigned())
        {
            // Check for int.min % -1
            if (n1 == 0xFFFFFFFF80000000UL && type.toBasetype().ty != Tint64)
            {
                e2.error("integer overflow: `int.min %% -1`");
                emplaceExp!(ErrorExp)(&ue);
                return ue;
            }
            else if (n1 == 0x8000000000000000L) // long.min % -1
            {
                e2.error("integer overflow: `long.min %% -1L`");
                emplaceExp!(ErrorExp)(&ue);
                return ue;
            }
        }
        if (e1.type.isunsigned() || e2.type.isunsigned())
            n = (cast(dinteger_t)n1) % (cast(dinteger_t)n2);
        else
            n = n1 % n2;
        emplaceExp!(IntegerExp)(&ue, loc, n, type);
    }
    return ue;
}

UnionExp Pow(const ref Loc loc, Type type, Expression e1, Expression e2)
{
    //printf("Pow()\n");
    UnionExp ue;
    // Handle integer power operations.
    if (e2.type.isintegral())
    {
        dinteger_t n = e2.toInteger();
        bool neg;
        if (!e2.type.isunsigned() && cast(sinteger_t)n < 0)
        {
            if (e1.type.isintegral())
            {
                cantExp(ue);
                return ue;
            }
            // Don't worry about overflow, from now on n is unsigned.
            neg = true;
            n = -n;
        }
        else
            neg = false;
        UnionExp ur, uv;
        if (e1.type.iscomplex())
        {
            emplaceExp!(ComplexExp)(&ur, loc, e1.toComplex(), e1.type);
            emplaceExp!(ComplexExp)(&uv, loc, complex_t(CTFloat.one), e1.type);
        }
        else if (e1.type.isfloating())
        {
            emplaceExp!(RealExp)(&ur, loc, e1.toReal(), e1.type);
            emplaceExp!(RealExp)(&uv, loc, CTFloat.one, e1.type);
        }
        else
        {
            emplaceExp!(IntegerExp)(&ur, loc, e1.toInteger(), e1.type);
            emplaceExp!(IntegerExp)(&uv, loc, 1, e1.type);
        }
        Expression r = ur.exp();
        Expression v = uv.exp();
        while (n != 0)
        {
            if (n & 1)
            {
                // v = v * r;
                uv = Mul(loc, v.type, v, r);
            }
            n >>= 1;
            // r = r * r
            ur = Mul(loc, r.type, r, r);
        }
        if (neg)
        {
            // ue = 1.0 / v
            UnionExp one;
            emplaceExp!(RealExp)(&one, loc, CTFloat.one, v.type);
            uv = Div(loc, v.type, one.exp(), v);
        }
        if (type.iscomplex())
            emplaceExp!(ComplexExp)(&ue, loc, v.toComplex(), type);
        else if (type.isintegral())
            emplaceExp!(IntegerExp)(&ue, loc, v.toInteger(), type);
        else
            emplaceExp!(RealExp)(&ue, loc, v.toReal(), type);
    }
    else if (e2.type.isfloating())
    {
        // x ^^ y for x < 0 and y not an integer is not defined; so set result as NaN
        if (e1.toReal() < CTFloat.zero)
        {
            emplaceExp!(RealExp)(&ue, loc, target.RealProperties.nan, type);
        }
        else
            cantExp(ue);
    }
    else
        cantExp(ue);
    return ue;
}

UnionExp Shl(const ref Loc loc, Type type, Expression e1, Expression e2)
{
    UnionExp ue = void;
    emplaceExp!(IntegerExp)(&ue, loc, e1.toInteger() << e2.toInteger(), type);
    return ue;
}

UnionExp Shr(const ref Loc loc, Type type, Expression e1, Expression e2)
{
    UnionExp ue = void;
    dinteger_t value = e1.toInteger();
    dinteger_t dcount = e2.toInteger();
    assert(dcount <= 0xFFFFFFFF);
    uint count = cast(uint)dcount;
    switch (e1.type.toBasetype().ty)
    {
    case Tint8:
        value = cast(byte)value >> count;
        break;
    case Tuns8:
    case Tchar:
        value = cast(ubyte)value >> count;
        break;
    case Tint16:
        value = cast(short)value >> count;
        break;
    case Tuns16:
    case Twchar:
        value = cast(ushort)value >> count;
        break;
    case Tint32:
        value = cast(int)value >> count;
        break;
    case Tuns32:
    case Tdchar:
        value = cast(uint)value >> count;
        break;
    case Tint64:
        value = cast(long)value >> count;
        break;
    case Tuns64:
        value = cast(ulong)value >> count;
        break;
    case Terror:
        emplaceExp!(ErrorExp)(&ue);
        return ue;
    default:
        assert(0);
    }
    emplaceExp!(IntegerExp)(&ue, loc, value, type);
    return ue;
}

UnionExp Ushr(const ref Loc loc, Type type, Expression e1, Expression e2)
{
    UnionExp ue = void;
    dinteger_t value = e1.toInteger();
    dinteger_t dcount = e2.toInteger();
    assert(dcount <= 0xFFFFFFFF);
    uint count = cast(uint)dcount;
    switch (e1.type.toBasetype().ty)
    {
    case Tint8:
    case Tuns8:
    case Tchar:
        // Possible only with >>>=. >>> always gets promoted to int.
        value = (value & 0xFF) >>> count;
        break;
    case Tint16:
    case Tuns16:
    case Twchar:
        // Possible only with >>>=. >>> always gets promoted to int.
        value = (value & 0xFFFF) >>> count;
        break;
    case Tint32:
    case Tuns32:
    case Tdchar:
        value = (value & 0xFFFFFFFF) >>> count;
        break;
    case Tint64:
    case Tuns64:
        value = value >>> count;
        break;
    case Terror:
        emplaceExp!(ErrorExp)(&ue);
        return ue;
    default:
        assert(0);
    }
    emplaceExp!(IntegerExp)(&ue, loc, value, type);
    return ue;
}

UnionExp And(const ref Loc loc, Type type, Expression e1, Expression e2)
{
    UnionExp ue = void;
    emplaceExp!(IntegerExp)(&ue, loc, e1.toInteger() & e2.toInteger(), type);
    return ue;
}

UnionExp Or(const ref Loc loc, Type type, Expression e1, Expression e2)
{
    UnionExp ue = void;
    emplaceExp!(IntegerExp)(&ue, loc, e1.toInteger() | e2.toInteger(), type);
    return ue;
}

UnionExp Xor(const ref Loc loc, Type type, Expression e1, Expression e2)
{
    //printf("Xor(linnum = %d, e1 = %s, e2 = %s)\n", loc.linnum, e1.toChars(), e2.toChars());
    UnionExp ue = void;
    emplaceExp!(IntegerExp)(&ue, loc, e1.toInteger() ^ e2.toInteger(), type);
    return ue;
}

/* Also returns EXP.cantExpression if cannot be computed.
 */
UnionExp Equal(EXP op, const ref Loc loc, Type type, Expression e1, Expression e2)
{
    UnionExp ue = void;
    int cmp = 0;
    real_t r1 = CTFloat.zero;
    real_t r2 = CTFloat.zero;
    //printf("Equal(e1 = %s, e2 = %s)\n", e1.toChars(), e2.toChars());
    assert(op == EXP.equal || op == EXP.notEqual);
    if (e1.op == EXP.null_)
    {
        if (e2.op == EXP.null_)
            cmp = 1;
        else if (StringExp es2 = e2.isStringExp())
        {
            cmp = (0 == es2.len);
        }
        else if (ArrayLiteralExp es2 = e2.isArrayLiteralExp())
        {
            cmp = !es2.elements || (0 == es2.elements.dim);
        }
        else
        {
            cantExp(ue);
            return ue;
        }
    }
    else if (e2.op == EXP.null_)
    {
        if (StringExp es1 = e1.isStringExp())
        {
            cmp = (0 == es1.len);
        }
        else if (ArrayLiteralExp es1 = e1.isArrayLiteralExp())
        {
            cmp = !es1.elements || (0 == es1.elements.dim);
        }
        else
        {
            cantExp(ue);
            return ue;
        }
    }
    else if (e1.op == EXP.string_ && e2.op == EXP.string_)
    {
        StringExp es1 = e1.isStringExp();
        StringExp es2 = e2.isStringExp();
        if (es1.sz != es2.sz)
        {
            assert(global.errors);
            cantExp(ue);
            return ue;
        }
        const data1 = es1.peekData();
        const data2 = es2.peekData();
        if (es1.len == es2.len && memcmp(data1.ptr, data2.ptr, es1.sz * es1.len) == 0)
            cmp = 1;
        else
            cmp = 0;
    }
    else if (e1.op == EXP.arrayLiteral && e2.op == EXP.arrayLiteral)
    {
        ArrayLiteralExp es1 = e1.isArrayLiteralExp();
        ArrayLiteralExp es2 = e2.isArrayLiteralExp();
        if ((!es1.elements || !es1.elements.dim) && (!es2.elements || !es2.elements.dim))
            cmp = 1; // both arrays are empty
        else if (!es1.elements || !es2.elements)
            cmp = 0;
        else if (es1.elements.dim != es2.elements.dim)
            cmp = 0;
        else
        {
            for (size_t i = 0; i < es1.elements.dim; i++)
            {
                auto ee1 = es1[i];
                auto ee2 = es2[i];
                ue = Equal(EXP.equal, loc, Type.tint32, ee1, ee2);
                if (CTFEExp.isCantExp(ue.exp()))
                    return ue;
                cmp = cast(int)ue.exp().toInteger();
                if (cmp == 0)
                    break;
            }
        }
    }
    else if (e1.op == EXP.arrayLiteral && e2.op == EXP.string_)
    {
        // Swap operands and use common code
        Expression etmp = e1;
        e1 = e2;
        e2 = etmp;
        goto Lsa;
    }
    else if (e1.op == EXP.string_ && e2.op == EXP.arrayLiteral)
    {
    Lsa:
        StringExp es1 = e1.isStringExp();
        ArrayLiteralExp es2 = e2.isArrayLiteralExp();
        size_t dim1 = es1.len;
        size_t dim2 = es2.elements ? es2.elements.dim : 0;
        if (dim1 != dim2)
            cmp = 0;
        else
        {
            cmp = 1; // if dim1 winds up being 0
            foreach (i; 0 .. dim1)
            {
                uinteger_t c = es1.getCodeUnit(i);
                auto ee2 = es2[i];
                if (ee2.isConst() != 1)
                {
                    cantExp(ue);
                    return ue;
                }
                cmp = (c == ee2.toInteger());
                if (cmp == 0)
                    break;
            }
        }
    }
    else if (e1.op == EXP.structLiteral && e2.op == EXP.structLiteral)
    {
        StructLiteralExp es1 = e1.isStructLiteralExp();
        StructLiteralExp es2 = e2.isStructLiteralExp();
        if (es1.sd != es2.sd)
            cmp = 0;
        else if ((!es1.elements || !es1.elements.dim) && (!es2.elements || !es2.elements.dim))
            cmp = 1; // both arrays are empty
        else if (!es1.elements || !es2.elements)
            cmp = 0;
        else if (es1.elements.dim != es2.elements.dim)
            cmp = 0;
        else
        {
            cmp = 1;
            for (size_t i = 0; i < es1.elements.dim; i++)
            {
                Expression ee1 = (*es1.elements)[i];
                Expression ee2 = (*es2.elements)[i];
                if (ee1 == ee2)
                    continue;
                if (!ee1 || !ee2)
                {
                    cmp = 0;
                    break;
                }
                ue = Equal(EXP.equal, loc, Type.tint32, ee1, ee2);
                if (ue.exp().op == EXP.cantExpression)
                    return ue;
                cmp = cast(int)ue.exp().toInteger();
                if (cmp == 0)
                    break;
            }
        }
    }
    else if (e1.isConst() != 1 || e2.isConst() != 1)
    {
        cantExp(ue);
        return ue;
    }
    else if (e1.type.isreal())
    {
        r1 = e1.toReal();
        r2 = e2.toReal();
        goto L1;
    }
    else if (e1.type.isimaginary())
    {
        r1 = e1.toImaginary();
        r2 = e2.toImaginary();
    L1:
        if (CTFloat.isNaN(r1) || CTFloat.isNaN(r2)) // if unordered
        {
            cmp = 0;
        }
        else
        {
            cmp = (r1 == r2);
        }
    }
    else if (e1.type.iscomplex())
    {
        cmp = e1.toComplex() == e2.toComplex();
    }
    else if (e1.type.isintegral() || e1.type.toBasetype().ty == Tpointer)
    {
        cmp = (e1.toInteger() == e2.toInteger());
    }
    else
    {
        cantExp(ue);
        return ue;
    }
    if (op == EXP.notEqual)
        cmp ^= 1;
    emplaceExp!(IntegerExp)(&ue, loc, cmp, type);
    return ue;
}

UnionExp Identity(EXP op, const ref Loc loc, Type type, Expression e1, Expression e2)
{
    UnionExp ue = void;
    int cmp;
    if (e1.op == EXP.null_)
    {
        cmp = (e2.op == EXP.null_);
    }
    else if (e2.op == EXP.null_)
    {
        cmp = 0;
    }
    else if (e1.op == EXP.symbolOffset && e2.op == EXP.symbolOffset)
    {
        SymOffExp es1 = e1.isSymOffExp();
        SymOffExp es2 = e2.isSymOffExp();
        cmp = (es1.var == es2.var && es1.offset == es2.offset);
    }
    else
    {
        if (e1.type.isreal())
        {
            cmp = RealIdentical(e1.toReal(), e2.toReal());
        }
        else if (e1.type.isimaginary())
        {
            cmp = RealIdentical(e1.toImaginary(), e2.toImaginary());
        }
        else if (e1.type.iscomplex())
        {
            complex_t v1 = e1.toComplex();
            complex_t v2 = e2.toComplex();
            cmp = RealIdentical(creall(v1), creall(v2)) && RealIdentical(cimagl(v1), cimagl(v1));
        }
        else
        {
            ue = Equal((op == EXP.identity) ? EXP.equal : EXP.notEqual, loc, type, e1, e2);
            return ue;
        }
    }
    if (op == EXP.notIdentity)
        cmp ^= 1;
    emplaceExp!(IntegerExp)(&ue, loc, cmp, type);
    return ue;
}

UnionExp Cmp(EXP op, const ref Loc loc, Type type, Expression e1, Expression e2)
{
    UnionExp ue = void;
    dinteger_t n;
    real_t r1 = CTFloat.zero;
    real_t r2 = CTFloat.zero;
    //printf("Cmp(e1 = %s, e2 = %s)\n", e1.toChars(), e2.toChars());
    if (e1.op == EXP.string_ && e2.op == EXP.string_)
    {
        StringExp es1 = e1.isStringExp();
        StringExp es2 = e2.isStringExp();
        size_t sz = es1.sz;
        assert(sz == es2.sz);
        size_t len = es1.len;
        if (es2.len < len)
            len = es2.len;
        const data1 = es1.peekData();
        const data2 = es1.peekData();
        int rawCmp = memcmp(data1.ptr, data2.ptr, sz * len);
        if (rawCmp == 0)
            rawCmp = cast(int)(es1.len - es2.len);
        n = specificCmp(op, rawCmp);
    }
    else if (e1.isConst() != 1 || e2.isConst() != 1)
    {
        cantExp(ue);
        return ue;
    }
    else if (e1.type.isreal())
    {
        r1 = e1.toReal();
        r2 = e2.toReal();
        goto L1;
    }
    else if (e1.type.isimaginary())
    {
        r1 = e1.toImaginary();
        r2 = e2.toImaginary();
    L1:
        n = realCmp(op, r1, r2);
    }
    else if (e1.type.iscomplex())
    {
        assert(0);
    }
    else
    {
        sinteger_t n1;
        sinteger_t n2;
        n1 = e1.toInteger();
        n2 = e2.toInteger();
        if (e1.type.isunsigned() || e2.type.isunsigned())
            n = intUnsignedCmp(op, n1, n2);
        else
            n = intSignedCmp(op, n1, n2);
    }
    emplaceExp!(IntegerExp)(&ue, loc, n, type);
    return ue;
}

/* Also returns EXP.cantExpression if cannot be computed.
 *  to: type to cast to
 *  type: type to paint the result
 */
UnionExp Cast(const ref Loc loc, Type type, Type to, Expression e1)
{
    UnionExp ue = void;
    Type tb = to.toBasetype();
    Type typeb = type.toBasetype();
    //printf("Cast(type = %s, to = %s, e1 = %s)\n", type.toChars(), to.toChars(), e1.toChars());
    //printf("\te1.type = %s\n", e1.type.toChars());
    if (e1.type.equals(type) && type.equals(to))
    {
        emplaceExp!(UnionExp)(&ue, e1);
        return ue;
    }
    if (e1.op == EXP.vector && (cast(TypeVector)e1.type).basetype.equals(type) && type.equals(to))
    {
        Expression ex = e1.isVectorExp().e1;
        emplaceExp!(UnionExp)(&ue, ex);
        return ue;
    }
    if (e1.type.toBasetype.equals(type) && type.equals(to))
    {
        emplaceExp!(UnionExp)(&ue, e1);
        ue.exp().type = type;
        return ue;
    }
    if (e1.type.implicitConvTo(to) >= MATCH.constant || to.implicitConvTo(e1.type) >= MATCH.constant)
    {
        goto L1;
    }
    // Allow covariant converions of delegates
    // (Perhaps implicit conversion from pure to impure should be a MATCH.constant,
    // then we wouldn't need this extra check.)
    if (e1.type.toBasetype().ty == Tdelegate && e1.type.implicitConvTo(to) == MATCH.convert)
    {
        goto L1;
    }
    /* Allow casting from one string type to another
     */
    if (e1.op == EXP.string_)
    {
        if (tb.ty == Tarray && typeb.ty == Tarray && tb.nextOf().size() == typeb.nextOf().size())
        {
            goto L1;
        }
    }
    if (e1.op == EXP.arrayLiteral && typeb == tb)
    {
    L1:
        Expression ex = expType(to, e1);
        emplaceExp!(UnionExp)(&ue, ex);
        return ue;
    }
    if (e1.isConst() != 1)
    {
        cantExp(ue);
    }
    else if (tb.ty == Tbool)
    {
        const opt = e1.toBool();
        if (opt.isEmpty())
        {
            cantExp(ue);
            return ue;
        }

        emplaceExp!(IntegerExp)(&ue, loc, opt.get(), type);
    }
    else if (type.isintegral())
    {
        if (e1.type.isfloating())
        {
            dinteger_t result;
            real_t r = e1.toReal();
            switch (typeb.ty)
            {
            case Tint8:
                result = cast(byte)cast(sinteger_t)r;
                break;
            case Tchar:
            case Tuns8:
                result = cast(ubyte)cast(dinteger_t)r;
                break;
            case Tint16:
                result = cast(short)cast(sinteger_t)r;
                break;
            case Twchar:
            case Tuns16:
                result = cast(ushort)cast(dinteger_t)r;
                break;
            case Tint32:
                result = cast(int)r;
                break;
            case Tdchar:
            case Tuns32:
                result = cast(uint)r;
                break;
            case Tint64:
                result = cast(long)r;
                break;
            case Tuns64:
                result = cast(ulong)r;
                break;
            default:
                assert(0);
            }
            emplaceExp!(IntegerExp)(&ue, loc, result, type);
        }
        else if (type.isunsigned())
            emplaceExp!(IntegerExp)(&ue, loc, e1.toUInteger(), type);
        else
            emplaceExp!(IntegerExp)(&ue, loc, e1.toInteger(), type);
    }
    else if (tb.isreal())
    {
        real_t value = e1.toReal();
        emplaceExp!(RealExp)(&ue, loc, value, type);
    }
    else if (tb.isimaginary())
    {
        real_t value = e1.toImaginary();
        emplaceExp!(RealExp)(&ue, loc, value, type);
    }
    else if (tb.iscomplex())
    {
        complex_t value = e1.toComplex();
        emplaceExp!(ComplexExp)(&ue, loc, value, type);
    }
    else if (tb.isscalar())
    {
        emplaceExp!(IntegerExp)(&ue, loc, e1.toInteger(), type);
    }
    else if (tb.ty == Tvoid)
    {
        cantExp(ue);
    }
    else if (tb.ty == Tstruct && e1.op == EXP.int64)
    {
        // Struct = 0;
        StructDeclaration sd = tb.toDsymbol(null).isStructDeclaration();
        assert(sd);
        auto elements = new Expressions();
        for (size_t i = 0; i < sd.fields.dim; i++)
        {
            VarDeclaration v = sd.fields[i];
            UnionExp zero;
            emplaceExp!(IntegerExp)(&zero, 0);
            ue = Cast(loc, v.type, v.type, zero.exp());
            if (ue.exp().op == EXP.cantExpression)
                return ue;
            elements.push(ue.exp().copy());
        }
        emplaceExp!(StructLiteralExp)(&ue, loc, sd, elements);
        ue.exp().type = type;
    }
    else
    {
        if (type != Type.terror)
        {
            // have to change to Internal Compiler Error
            // all invalid casts should be handled already in Expression::castTo().
            error(loc, "cannot cast `%s` to `%s`", e1.type.toChars(), type.toChars());
        }
        emplaceExp!(ErrorExp)(&ue);
    }
    return ue;
}

UnionExp ArrayLength(Type type, Expression e1)
{
    UnionExp ue = void;
    Loc loc = e1.loc;
    if (StringExp es1 = e1.isStringExp())
    {
        emplaceExp!(IntegerExp)(&ue, loc, es1.len, type);
    }
    else if (ArrayLiteralExp ale = e1.isArrayLiteralExp())
    {
        size_t dim = ale.elements ? ale.elements.dim : 0;
        emplaceExp!(IntegerExp)(&ue, loc, dim, type);
    }
    else if (AssocArrayLiteralExp ale = e1.isAssocArrayLiteralExp)
    {
        size_t dim = ale.keys.dim;
        emplaceExp!(IntegerExp)(&ue, loc, dim, type);
    }
    else if (e1.type.toBasetype().ty == Tsarray)
    {
        Expression e = (cast(TypeSArray)e1.type.toBasetype()).dim;
        emplaceExp!(UnionExp)(&ue, e);
    }
    else
        cantExp(ue);
    return ue;
}

/* Also return EXP.cantExpression if this fails
 */
UnionExp Index(Type type, Expression e1, Expression e2, bool indexIsInBounds)
{
    UnionExp ue = void;
    Loc loc = e1.loc;
    //printf("Index(e1 = %s, e2 = %s)\n", e1.toChars(), e2.toChars());
    assert(e1.type);
    if (e1.op == EXP.string_ && e2.op == EXP.int64)
    {
        StringExp es1 = e1.isStringExp();
        uinteger_t i = e2.toInteger();
        if (i >= es1.len)
        {
            e1.error("string index %llu is out of bounds `[0 .. %llu]`", i, cast(ulong)es1.len);
            emplaceExp!(ErrorExp)(&ue);
        }
        else
        {
            emplaceExp!(IntegerExp)(&ue, loc, es1.getCodeUnit(cast(size_t) i), type);
        }
    }
    else if (e1.type.toBasetype().ty == Tsarray && e2.op == EXP.int64)
    {
        TypeSArray tsa = cast(TypeSArray)e1.type.toBasetype();
        uinteger_t length = tsa.dim.toInteger();
        uinteger_t i = e2.toInteger();
        if (i >= length && (e1.op == EXP.arrayLiteral || !indexIsInBounds))
        {
            // C code only checks bounds if an ArrayLiteralExp
            e1.error("array index %llu is out of bounds `%s[0 .. %llu]`", i, e1.toChars(), length);
            emplaceExp!(ErrorExp)(&ue);
        }
        else if (ArrayLiteralExp ale = e1.isArrayLiteralExp())
        {
            auto e = ale[cast(size_t)i];
            e.type = type;
            e.loc = loc;
            if (hasSideEffect(e))
                cantExp(ue);
            else
                emplaceExp!(UnionExp)(&ue, e);
        }
        else
            cantExp(ue);
    }
    else if (e1.type.toBasetype().ty == Tarray && e2.op == EXP.int64)
    {
        uinteger_t i = e2.toInteger();
        if (ArrayLiteralExp ale = e1.isArrayLiteralExp())
        {
            if (i >= ale.elements.dim)
            {
                e1.error("array index %llu is out of bounds `%s[0 .. %llu]`", i, e1.toChars(), cast(ulong) ale.elements.dim);
                emplaceExp!(ErrorExp)(&ue);
            }
            else
            {
                auto e = ale[cast(size_t)i];
                e.type = type;
                e.loc = loc;
                if (hasSideEffect(e))
                    cantExp(ue);
                else
                    emplaceExp!(UnionExp)(&ue, e);
            }
        }
        else
            cantExp(ue);
    }
    else if (AssocArrayLiteralExp ae = e1.isAssocArrayLiteralExp())
    {
        /* Search the keys backwards, in case there are duplicate keys
         */
        for (size_t i = ae.keys.dim; i;)
        {
            i--;
            Expression ekey = (*ae.keys)[i];
            ue = Equal(EXP.equal, loc, Type.tbool, ekey, e2);
            if (CTFEExp.isCantExp(ue.exp()))
                return ue;
            if (ue.exp().toBool().hasValue(true))
            {
                Expression e = (*ae.values)[i];
                e.type = type;
                e.loc = loc;
                if (hasSideEffect(e))
                    cantExp(ue);
                else
                    emplaceExp!(UnionExp)(&ue, e);
                return ue;
            }
        }
        cantExp(ue);
    }
    else
        cantExp(ue);
    return ue;
}

/* Also return EXP.cantExpression if this fails
 */
UnionExp Slice(Type type, Expression e1, Expression lwr, Expression upr)
{
    UnionExp ue = void;
    Loc loc = e1.loc;
    static if (LOG)
    {
        printf("Slice()\n");
        if (lwr)
        {
            printf("\te1 = %s\n", e1.toChars());
            printf("\tlwr = %s\n", lwr.toChars());
            printf("\tupr = %s\n", upr.toChars());
        }
    }

    if (e1.op == EXP.string_ && lwr.op == EXP.int64 && upr.op == EXP.int64)
    {
        StringExp es1 = e1.isStringExp();
        const uinteger_t ilwr = lwr.toInteger();
        const uinteger_t iupr = upr.toInteger();
        if (sliceBoundsCheck(0, es1.len, ilwr, iupr))
            cantExp(ue);   // https://issues.dlang.org/show_bug.cgi?id=18115
        else
        {
            const len = cast(size_t)(iupr - ilwr);
            const sz = es1.sz;
            void* s = mem.xmalloc(len * sz);
            const data1 = es1.peekData();
            memcpy(s, data1.ptr + ilwr * sz, len * sz);
            emplaceExp!(StringExp)(&ue, loc, s[0 .. len * sz], len, sz, es1.postfix);
            StringExp es = ue.exp().isStringExp();
            es.committed = es1.committed;
            es.type = type;
        }
    }
    else if (e1.op == EXP.arrayLiteral && lwr.op == EXP.int64 && upr.op == EXP.int64 && !hasSideEffect(e1))
    {
        ArrayLiteralExp es1 = e1.isArrayLiteralExp();
        const uinteger_t ilwr = lwr.toInteger();
        const uinteger_t iupr = upr.toInteger();
        if (sliceBoundsCheck(0, es1.elements.dim, ilwr, iupr))
            cantExp(ue);
        else
        {
            auto elements = new Expressions(cast(size_t)(iupr - ilwr));
            memcpy(elements.tdata(), es1.elements.tdata() + ilwr, cast(size_t)(iupr - ilwr) * ((*es1.elements)[0]).sizeof);
            emplaceExp!(ArrayLiteralExp)(&ue, e1.loc, type, elements);
        }
    }
    else
        cantExp(ue);
    return ue;
}

/* Check whether slice `[newlwr .. newupr]` is in the range `[lwr .. upr]`
 */
bool sliceBoundsCheck(uinteger_t lwr, uinteger_t upr, uinteger_t newlwr, uinteger_t newupr) pure
{
    assert(lwr <= upr);
    return !(newlwr <= newupr &&
             lwr <= newlwr &&
             newupr <= upr);
}

/* Set a slice of char/integer array literal 'existingAE' from a string 'newval'.
 * existingAE[firstIndex..firstIndex+newval.length] = newval.
 */
void sliceAssignArrayLiteralFromString(ArrayLiteralExp existingAE, const StringExp newval, size_t firstIndex)
{
    const len = newval.len;
    Type elemType = existingAE.type.nextOf();
    foreach (j; 0 .. len)
    {
        const val = newval.getCodeUnit(j);
        (*existingAE.elements)[j + firstIndex] = new IntegerExp(newval.loc, val, elemType);
    }
}

/* Set a slice of string 'existingSE' from a char array literal 'newae'.
 *   existingSE[firstIndex..firstIndex+newae.length] = newae.
 */
void sliceAssignStringFromArrayLiteral(StringExp existingSE, ArrayLiteralExp newae, size_t firstIndex)
{
    assert(existingSE.ownedByCtfe != OwnedBy.code);
    foreach (j; 0 .. newae.elements.dim)
    {
        existingSE.setCodeUnit(firstIndex + j, cast(dchar)newae[j].toInteger());
    }
}

/* Set a slice of string 'existingSE' from a string 'newstr'.
 *   existingSE[firstIndex..firstIndex+newstr.length] = newstr.
 */
void sliceAssignStringFromString(StringExp existingSE, const StringExp newstr, size_t firstIndex)
{
    assert(existingSE.ownedByCtfe != OwnedBy.code);
    size_t sz = existingSE.sz;
    assert(sz == newstr.sz);
    auto data1 = existingSE.borrowData();
    const data2 = newstr.peekData();
    memcpy(data1.ptr + firstIndex * sz, data2.ptr, data2.length);
}

/* Compare a string slice with another string slice.
 * Conceptually equivalent to memcmp( se1[lo1..lo1+len],  se2[lo2..lo2+len])
 */
int sliceCmpStringWithString(const StringExp se1, const StringExp se2, size_t lo1, size_t lo2, size_t len)
{
    size_t sz = se1.sz;
    assert(sz == se2.sz);
    const data1 = se1.peekData();
    const data2 = se2.peekData();
    return memcmp(data1.ptr + sz * lo1, data2.ptr + sz * lo2, sz * len);
}

/* Compare a string slice with an array literal slice
 * Conceptually equivalent to memcmp( se1[lo1..lo1+len],  ae2[lo2..lo2+len])
 */
int sliceCmpStringWithArray(const StringExp se1, ArrayLiteralExp ae2, size_t lo1, size_t lo2, size_t len)
{
    foreach (j; 0 .. len)
    {
        const val2 = cast(dchar)ae2[j + lo2].toInteger();
        const val1 = se1.getCodeUnit(j + lo1);
        const int c = val1 - val2;
        if (c)
            return c;
    }
    return 0;
}

/** 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.
 */
private Expressions* copyElements(Expression e1, Expression e2 = null)
{
    auto elems = new Expressions();

    void append(ArrayLiteralExp ale)
    {
        if (!ale.elements)
            return;
        auto d = elems.dim;
        elems.append(ale.elements);
        foreach (ref el; (*elems)[d .. elems.dim])
        {
            if (!el)
                el = ale.basis;
        }
    }

    if (auto ale = e1.isArrayLiteralExp())
        append(ale);
    else
        elems.push(e1);

    if (e2)
    {
        if (auto ale = e2.isArrayLiteralExp())
            append(ale);
        else
            elems.push(e2);
    }

    return elems;
}

/* Also return EXP.cantExpression if this fails
 */
UnionExp Cat(const ref Loc loc, Type type, Expression e1, Expression e2)
{
    UnionExp ue = void;
    Expression e = CTFEExp.cantexp;
    Type t;
    Type t1 = e1.type.toBasetype();
    Type t2 = e2.type.toBasetype();
    //printf("Cat(e1 = %s, e2 = %s)\n", e1.toChars(), e2.toChars());
    //printf("\tt1 = %s, t2 = %s, type = %s\n", t1.toChars(), t2.toChars(), type.toChars());
    if (e1.op == EXP.null_ && (e2.op == EXP.int64 || e2.op == EXP.structLiteral))
    {
        e = e2;
        t = t1;
        goto L2;
    }
    else if ((e1.op == EXP.int64 || e1.op == EXP.structLiteral) && e2.op == EXP.null_)
    {
        e = e1;
        t = t2;
    L2:
        Type tn = e.type.toBasetype();
        if (tn.ty.isSomeChar)
        {
            // Create a StringExp
            if (t.nextOf())
                t = t.nextOf().toBasetype();
            const sz = cast(ubyte)t.size();
            dinteger_t v = e.toInteger();
            const len = (t.ty == tn.ty) ? 1 : utf_codeLength(sz, cast(dchar)v);
            void* s = mem.xmalloc(len * sz);
            if (t.ty == tn.ty)
                Port.valcpy(s, v, sz);
            else
                utf_encode(sz, s, cast(dchar)v);
            emplaceExp!(StringExp)(&ue, loc, s[0 .. len * sz], len, sz);
            StringExp es = ue.exp().isStringExp();
            es.type = type;
            es.committed = 1;
        }
        else
        {
            // Create an ArrayLiteralExp
            auto elements = new Expressions();
            elements.push(e);
            emplaceExp!(ArrayLiteralExp)(&ue, e.loc, type, elements);
        }
        assert(ue.exp().type);
        return ue;
    }
    else if (e1.op == EXP.null_ && e2.op == EXP.null_)
    {
        if (type == e1.type)
        {
            // Handle null ~= null
            if (t1.ty == Tarray && t2 == t1.nextOf())
            {
                emplaceExp!(ArrayLiteralExp)(&ue, e1.loc, type, e2);
                assert(ue.exp().type);
                return ue;
            }
            else
            {
                emplaceExp!(UnionExp)(&ue, e1);
                assert(ue.exp().type);
                return ue;
            }
        }
        if (type == e2.type)
        {
            emplaceExp!(UnionExp)(&ue, e2);
            assert(ue.exp().type);
            return ue;
        }
        emplaceExp!(NullExp)(&ue, e1.loc, type);
        assert(ue.exp().type);
        return ue;
    }
    else if (e1.op == EXP.string_ && e2.op == EXP.string_)
    {
        // Concatenate the strings
        StringExp es1 = e1.isStringExp();
        StringExp es2 = e2.isStringExp();
        size_t len = es1.len + es2.len;
        ubyte sz = es1.sz;
        if (sz != es2.sz)
        {
            /* Can happen with:
             *   auto s = "foo"d ~ "bar"c;
             */
            assert(global.errors);
            cantExp(ue);
            assert(ue.exp().type);
            return ue;
        }
        void* s = mem.xmalloc(len * sz);
        const data1 = es1.peekData();
        const data2 = es2.peekData();
        memcpy(cast(char*)s, data1.ptr, es1.len * sz);
        memcpy(cast(char*)s + es1.len * sz, data2.ptr, es2.len * sz);
        emplaceExp!(StringExp)(&ue, loc, s[0 .. len * sz], len, sz);
        StringExp es = ue.exp().isStringExp();
        es.committed = es1.committed | es2.committed;
        es.type = type;
        assert(ue.exp().type);
        return ue;
    }
    else if (e2.op == EXP.string_ && e1.op == EXP.arrayLiteral && t1.nextOf().isintegral())
    {
        // [chars] ~ string --> [chars]
        StringExp es = e2.isStringExp();
        ArrayLiteralExp ea = e1.isArrayLiteralExp();
        size_t len = es.len + ea.elements.dim;
        auto elems = new Expressions(len);
        for (size_t i = 0; i < ea.elements.dim; ++i)
        {
            (*elems)[i] = ea[i];
        }
        emplaceExp!(ArrayLiteralExp)(&ue, e1.loc, type, elems);
        ArrayLiteralExp dest = ue.exp().isArrayLiteralExp();
        sliceAssignArrayLiteralFromString(dest, es, ea.elements.dim);
        assert(ue.exp().type);
        return ue;
    }
    else if (e1.op == EXP.string_ && e2.op == EXP.arrayLiteral && t2.nextOf().isintegral())
    {
        // string ~ [chars] --> [chars]
        StringExp es = e1.isStringExp();
        ArrayLiteralExp ea = e2.isArrayLiteralExp();
        size_t len = es.len + ea.elements.dim;
        auto elems = new Expressions(len);
        for (size_t i = 0; i < ea.elements.dim; ++i)
        {
            (*elems)[es.len + i] = ea[i];
        }
        emplaceExp!(ArrayLiteralExp)(&ue, e1.loc, type, elems);
        ArrayLiteralExp dest = ue.exp().isArrayLiteralExp();
        sliceAssignArrayLiteralFromString(dest, es, 0);
        assert(ue.exp().type);
        return ue;
    }
    else if (e1.op == EXP.string_ && e2.op == EXP.int64)
    {
        // string ~ char --> string
        StringExp es1 = e1.isStringExp();
        StringExp es;
        const sz = es1.sz;
        dinteger_t v = e2.toInteger();
        // Is it a concatenation of homogenous types?
        // (char[] ~ char, wchar[]~wchar, or dchar[]~dchar)
        bool homoConcat = (sz == t2.size());
        const len = es1.len + (homoConcat ? 1 : utf_codeLength(sz, cast(dchar)v));
        void* s = mem.xmalloc(len * sz);
        const data1 = es1.peekData();
        memcpy(s, data1.ptr, data1.length);
        if (homoConcat)
            Port.valcpy(cast(char*)s + (sz * es1.len), v, sz);
        else
            utf_encode(sz, cast(char*)s + (sz * es1.len), cast(dchar)v);
        emplaceExp!(StringExp)(&ue, loc, s[0 .. len * sz], len, sz);
        es = ue.exp().isStringExp();
        es.committed = es1.committed;
        es.type = type;
        assert(ue.exp().type);
        return ue;
    }
    else if (e1.op == EXP.int64 && e2.op == EXP.string_)
    {
        // [w|d]?char ~ string --> string
        // We assume that we only ever prepend one char of the same type
        // (wchar,dchar) as the string's characters.
        StringExp es2 = e2.isStringExp();
        const len = 1 + es2.len;
        const sz = es2.sz;
        dinteger_t v = e1.toInteger();
        void* s = mem.xmalloc(len * sz);
        Port.valcpy(cast(char*)s, v, sz);
        const data2 = es2.peekData();
        memcpy(cast(char*)s + sz, data2.ptr, data2.length);
        emplaceExp!(StringExp)(&ue, loc, s[0 .. len * sz], len, sz);
        StringExp es = ue.exp().isStringExp();
        es.sz = sz;
        es.committed = es2.committed;
        es.type = type;
        assert(ue.exp().type);
        return ue;
    }
    else if (e1.op == EXP.arrayLiteral && e2.op == EXP.arrayLiteral && t1.nextOf().equals(t2.nextOf()))
    {
        // Concatenate the arrays
        auto elems = copyElements(e1, e2);

        emplaceExp!(ArrayLiteralExp)(&ue, e1.loc, cast(Type)null, elems);

        e = ue.exp();
        if (type.toBasetype().ty == Tsarray)
        {
            e.type = t1.nextOf().sarrayOf(elems.dim);
        }
        else
            e.type = type;
        assert(ue.exp().type);
        return ue;
    }
    else if (e1.op == EXP.arrayLiteral && e2.op == EXP.null_ && t1.nextOf().equals(t2.nextOf()))
    {
        e = e1;
        goto L3;
    }
    else if (e1.op == EXP.null_ && e2.op == EXP.arrayLiteral && t1.nextOf().equals(t2.nextOf()))
    {
        e = e2;
    L3:
        // Concatenate the array with null
        auto elems = copyElements(e);

        emplaceExp!(ArrayLiteralExp)(&ue, e.loc, cast(Type)null, elems);

        e = ue.exp();
        if (type.toBasetype().ty == Tsarray)
        {
            e.type = t1.nextOf().sarrayOf(elems.dim);
        }
        else
            e.type = type;
        assert(ue.exp().type);
        return ue;
    }
    else if ((e1.op == EXP.arrayLiteral || e1.op == EXP.null_) && e1.type.toBasetype().nextOf() && e1.type.toBasetype().nextOf().equals(e2.type))
    {
        auto elems = (e1.op == EXP.arrayLiteral)
                ? copyElements(e1) : new Expressions();
        elems.push(e2);

        emplaceExp!(ArrayLiteralExp)(&ue, loc, cast(Type)null, elems);

        e = ue.exp();
        if (type.toBasetype().ty == Tsarray)
        {
            e.type = e2.type.sarrayOf(elems.dim);
        }
        else
            e.type = type;
        assert(ue.exp().type);
        return ue;
    }
    else if (e2.op == EXP.arrayLiteral && e2.type.toBasetype().nextOf().equals(e1.type))
    {
        auto elems = copyElements(e1, e2);

        emplaceExp!(ArrayLiteralExp)(&ue, loc, cast(Type)null, elems);

        e = ue.exp();
        if (type.toBasetype().ty == Tsarray)
        {
            e.type = e1.type.sarrayOf(elems.dim);
        }
        else
            e.type = type;
        assert(ue.exp().type);
        return ue;
    }
    else if (e1.op == EXP.null_ && e2.op == EXP.string_)
    {
        t = e1.type;
        e = e2;
        goto L1;
    }
    else if (e1.op == EXP.string_ && e2.op == EXP.null_)
    {
        e = e1;
        t = e2.type;
    L1:
        Type tb = t.toBasetype();
        if (tb.ty == Tarray && tb.nextOf().equivalent(e.type))
        {
            auto expressions = new Expressions();
            expressions.push(e);
            emplaceExp!(ArrayLiteralExp)(&ue, loc, t, expressions);
            e = ue.exp();
        }
        else
        {
            emplaceExp!(UnionExp)(&ue, e);
            e = ue.exp();
        }
        if (!e.type.equals(type))
        {
            StringExp se = e.copy().isStringExp();
            e = se.castTo(null, type);
            emplaceExp!(UnionExp)(&ue, e);
            e = ue.exp();
        }
    }
    else
        cantExp(ue);
    assert(ue.exp().type);
    return ue;
}

UnionExp Ptr(Type type, Expression e1)
{
    //printf("Ptr(e1 = %s)\n", e1.toChars());
    UnionExp ue = void;
    if (AddExp ae = e1.isAddExp())
    {
        if (AddrExp ade = ae.e1.isAddrExp())
        {
            if (ae.e2.op == EXP.int64)
                if (StructLiteralExp se = ade.e1.isStructLiteralExp())
                {
                    uint offset = cast(uint)ae.e2.toInteger();
                    Expression e = se.getField(type, offset);
                    if (e)
                    {
                        emplaceExp!(UnionExp)(&ue, e);
                        return ue;
                    }
                }
        }
    }
    cantExp(ue);
    return ue;
}
