
/* Compiler implementation of the D programming language
 * Copyright (C) 1999-2021 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/ctfeexpr.c
 */

#include "root/dsystem.h"               // mem{cpy|set}()
#include "root/rmem.h"

#include "mars.h"
#include "expression.h"
#include "declaration.h"
#include "aggregate.h"
// for AssocArray
#include "id.h"
#include "utf.h"
#include "template.h"
#include "ctfe.h"

int RealEquals(real_t x1, real_t x2);

/************** ClassReferenceExp ********************************************/

ClassReferenceExp::ClassReferenceExp(Loc loc, StructLiteralExp *lit, Type *type)
    : Expression(loc, TOKclassreference, sizeof(ClassReferenceExp))
{
    assert(lit && lit->sd && lit->sd->isClassDeclaration());
    this->value = lit;
    this->type = type;
}

ClassDeclaration *ClassReferenceExp::originalClass()
{
    return value->sd->isClassDeclaration();
}

// Return index of the field, or -1 if not found
int ClassReferenceExp::getFieldIndex(Type *fieldtype, unsigned fieldoffset)
{
    ClassDeclaration *cd = originalClass();
    unsigned fieldsSoFar = 0;
    for (size_t j = 0; j < value->elements->length; j++)
    {
        while (j - fieldsSoFar >= cd->fields.length)
        {
            fieldsSoFar += cd->fields.length;
            cd = cd->baseClass;
        }
        VarDeclaration *v2 = cd->fields[j - fieldsSoFar];
        if (fieldoffset == v2->offset &&
            fieldtype->size() == v2->type->size())
        {
            return (int)(value->elements->length - fieldsSoFar - cd->fields.length + (j-fieldsSoFar));
        }
    }
    return -1;
}

// Return index of the field, or -1 if not found
// Same as getFieldIndex, but checks for a direct match with the VarDeclaration
int ClassReferenceExp::findFieldIndexByName(VarDeclaration *v)
{
    ClassDeclaration *cd = originalClass();
    size_t fieldsSoFar = 0;
    for (size_t j = 0; j < value->elements->length; j++)
    {
        while (j - fieldsSoFar >= cd->fields.length)
        {
            fieldsSoFar += cd->fields.length;
            cd = cd->baseClass;
        }
        VarDeclaration *v2 = cd->fields[j - fieldsSoFar];
        if (v == v2)
        {
            return (int)(value->elements->length - fieldsSoFar - cd->fields.length + (j-fieldsSoFar));
        }
    }
    return -1;
}

/************** VoidInitExp ********************************************/

VoidInitExp::VoidInitExp(VarDeclaration *var, Type *)
    : Expression(var->loc, TOKvoid, sizeof(VoidInitExp))
{
    this->var = var;
    this->type = var->type;
}

const char *VoidInitExp::toChars()
{
    return "void";
}

// Return index of the field, or -1 if not found
// Same as getFieldIndex, but checks for a direct match with the VarDeclaration
int findFieldIndexByName(StructDeclaration *sd, VarDeclaration *v)
{
    for (size_t i = 0; i < sd->fields.length; ++i)
    {
        if (sd->fields[i] == v)
            return (int)i;
    }
    return -1;
}

/************** ThrownExceptionExp ********************************************/

ThrownExceptionExp::ThrownExceptionExp(Loc loc, ClassReferenceExp *victim) : Expression(loc, TOKthrownexception, sizeof(ThrownExceptionExp))
{
    this->thrown = victim;
    this->type = victim->type;
}

const char *ThrownExceptionExp::toChars()
{
    return "CTFE ThrownException";
}

// Generate an error message when this exception is not caught
void ThrownExceptionExp::generateUncaughtError()
{
    UnionExp ue;
    Expression *e = resolveSlice((*thrown->value->elements)[0], &ue);
    StringExp *se = e->toStringExp();
    thrown->error("uncaught CTFE exception %s(%s)", thrown->type->toChars(), se ? se->toChars() : e->toChars());

    /* Also give the line where the throw statement was. We won't have it
     * in the case where the ThrowStatement is generated internally
     * (eg, in ScopeStatement)
     */
    if (loc.filename && !loc.equals(thrown->loc))
        errorSupplemental(loc, "thrown from here");
}

// True if 'e' is CTFEExp::cantexp, or an exception
bool exceptionOrCantInterpret(Expression *e)
{
    return e && (e->op == TOKcantexp || e->op == TOKthrownexception);
}

/********************** CTFEExp ******************************************/

CTFEExp *CTFEExp::cantexp;
CTFEExp *CTFEExp::voidexp;
CTFEExp *CTFEExp::breakexp;
CTFEExp *CTFEExp::continueexp;
CTFEExp *CTFEExp::gotoexp;

CTFEExp::CTFEExp(TOK tok)
    : Expression(Loc(), tok, sizeof(CTFEExp))
{
    type = Type::tvoid;
}

const char *CTFEExp::toChars()
{
    switch (op)
    {
        case TOKcantexp:    return "<cant>";
        case TOKvoidexp:    return "cast(void)0";
        case TOKbreak:      return "<break>";
        case TOKcontinue:   return "<continue>";
        case TOKgoto:       return "<goto>";
        default:            assert(0);  return NULL;
    }
}

Expression *UnionExp::copy()
{
    Expression *e = exp();
    //if (e->size > sizeof(u)) printf("%s\n", Token::toChars(e->op));
    assert(e->size <= sizeof(u));
    if (e->op == TOKcantexp)    return CTFEExp::cantexp;
    if (e->op == TOKvoidexp)    return CTFEExp::voidexp;
    if (e->op == TOKbreak)      return CTFEExp::breakexp;
    if (e->op == TOKcontinue)   return CTFEExp::continueexp;
    if (e->op == TOKgoto)       return CTFEExp::gotoexp;
    return e->copy();
}

/************** Aggregate literals (AA/string/array/struct) ******************/

// Given expr, which evaluates to an array/AA/string literal,
// return true if it needs to be copied
bool needToCopyLiteral(Expression *expr)
{
    for (;;)
    {
        switch (expr->op)
        {
            case TOKarrayliteral:
                return ((ArrayLiteralExp *)expr)->ownedByCtfe == OWNEDcode;
            case TOKassocarrayliteral:
                return ((AssocArrayLiteralExp *)expr)->ownedByCtfe == OWNEDcode;
            case TOKstructliteral:
                return ((StructLiteralExp *)expr)->ownedByCtfe == OWNEDcode;
            case TOKstring:
            case TOKthis:
            case TOKvar:
                return false;
            case TOKassign:
                return false;
            case TOKindex:
            case TOKdotvar:
            case TOKslice:
            case TOKcast:
                expr = ((UnaExp *)expr)->e1;
                continue;
            case TOKcat:
                return needToCopyLiteral(((BinExp *)expr)->e1) ||
                    needToCopyLiteral(((BinExp *)expr)->e2);
            case TOKcatass:
                expr = ((BinExp *)expr)->e2;
                continue;
            default:
                return false;
        }
    }
}

Expressions *copyLiteralArray(Expressions *oldelems, Expression *basis = NULL)
{
    if (!oldelems)
        return oldelems;
    CtfeStatus::numArrayAllocs++;
    Expressions *newelems = new Expressions();
    newelems->setDim(oldelems->length);
    for (size_t i = 0; i < oldelems->length; i++)
    {
        Expression *el = (*oldelems)[i];
        if (!el)
            el = basis;
        (*newelems)[i] = copyLiteral(el).copy();
    }
    return newelems;
}

// Make a copy of the ArrayLiteral, AALiteral, String, or StructLiteral.
// This value will be used for in-place modification.
UnionExp copyLiteral(Expression *e)
{
    UnionExp ue;
    if (e->op == TOKstring) // syntaxCopy doesn't make a copy for StringExp!
    {
        StringExp *se = (StringExp *)e;
        utf8_t *s = (utf8_t *)mem.xcalloc(se->len + 1, se->sz);
        memcpy(s, se->string, se->len * se->sz);
        new(&ue) StringExp(se->loc, s, se->len);
        StringExp *se2 = (StringExp *)ue.exp();
        se2->committed = se->committed;
        se2->postfix = se->postfix;
        se2->type = se->type;
        se2->sz = se->sz;
        se2->ownedByCtfe = OWNEDctfe;
        return ue;
    }
    if (e->op == TOKarrayliteral)
    {
        ArrayLiteralExp *ale = (ArrayLiteralExp *)e;
        Expressions *elements = copyLiteralArray(ale->elements, ale->basis);

        new(&ue) ArrayLiteralExp(e->loc, e->type, elements);

        ArrayLiteralExp *r = (ArrayLiteralExp *)ue.exp();
        r->ownedByCtfe = OWNEDctfe;
        return ue;
    }
    if (e->op == TOKassocarrayliteral)
    {
        AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)e;
        new(&ue) AssocArrayLiteralExp(e->loc, copyLiteralArray(aae->keys), copyLiteralArray(aae->values));
        AssocArrayLiteralExp *r = (AssocArrayLiteralExp *)ue.exp();
        r->type = e->type;
        r->ownedByCtfe = OWNEDctfe;
        return ue;
    }
    if (e->op == TOKstructliteral)
    {
        /* syntaxCopy doesn't work for struct literals, because of a nasty special
         * case: block assignment is permitted inside struct literals, eg,
         * an int[4] array can be initialized with a single int.
         */
        StructLiteralExp *sle = (StructLiteralExp *)e;
        Expressions *oldelems = sle->elements;
        Expressions * newelems = new Expressions();
        newelems->setDim(oldelems->length);
        for (size_t i = 0; i < newelems->length; i++)
        {
            // We need the struct definition to detect block assignment
            VarDeclaration *v = sle->sd->fields[i];
            Expression *m = (*oldelems)[i];

            // If it is a void assignment, use the default initializer
            if (!m)
                m = voidInitLiteral(v->type, v).copy();

            if (v->type->ty == Tarray || v->type->ty == Taarray)
            {
                // Don't have to copy array references
            }
            else
            {
                // Buzilla 15681: Copy the source element always.
                m = copyLiteral(m).copy();

                // Block assignment from inside struct literals
                if (v->type->ty != m->type->ty && v->type->ty == Tsarray)
                {
                    TypeSArray *tsa = (TypeSArray *)v->type;
                    size_t len = (size_t)tsa->dim->toInteger();
                    UnionExp uex;
                    m = createBlockDuplicatedArrayLiteral(&uex, e->loc, v->type, m, len);
                    if (m == uex.exp())
                        m = uex.copy();
                }
            }
            (*newelems)[i] = m;
        }
        new(&ue) StructLiteralExp(e->loc, sle->sd, newelems, sle->stype);
        StructLiteralExp *r = (StructLiteralExp *)ue.exp();
        r->type = e->type;
        r->ownedByCtfe = OWNEDctfe;
        r->origin = ((StructLiteralExp *)e)->origin;
        return ue;
    }
    if (e->op == TOKfunction || e->op == TOKdelegate ||
        e->op == TOKsymoff || e->op == TOKnull ||
        e->op == TOKvar || e->op == TOKdotvar ||
        e->op == TOKint64 || e->op == TOKfloat64 ||
        e->op == TOKchar || e->op == TOKcomplex80 ||
        e->op == TOKvoid || e->op == TOKvector ||
        e->op == TOKtypeid)
    {
        // Simple value types
        // Keep e1 for DelegateExp and DotVarExp
        new(&ue) UnionExp(e);
        Expression *r = ue.exp();
        r->type = e->type;
        return ue;
    }
    if (e->op == TOKslice)
    {
        SliceExp *se = (SliceExp *)e;
        if (se->type->toBasetype()->ty == Tsarray)
        {
            // same with resolveSlice()
            if (se->e1->op == TOKnull)
            {
                new(&ue) NullExp(se->loc, se->type);
                return ue;
            }
            ue = Slice(se->type, se->e1, se->lwr, se->upr);
            assert(ue.exp()->op == TOKarrayliteral);
            ArrayLiteralExp *r = (ArrayLiteralExp *)ue.exp();
            r->elements = copyLiteralArray(r->elements);
            r->ownedByCtfe = OWNEDctfe;
            return ue;
        }
        else
        {
            // Array slices only do a shallow copy
            new(&ue) SliceExp(e->loc, se->e1, se->lwr, se->upr);
            Expression *r = ue.exp();
            r->type = e->type;
            return ue;
        }
    }
    if (isPointer(e->type))
    {
        // For pointers, we only do a shallow copy.
        if (e->op == TOKaddress)
            new(&ue) AddrExp(e->loc, ((AddrExp *)e)->e1);
        else if (e->op == TOKindex)
            new(&ue) IndexExp(e->loc, ((IndexExp *)e)->e1, ((IndexExp *)e)->e2);
        else if (e->op == TOKdotvar)
        {
            new(&ue) DotVarExp(e->loc, ((DotVarExp *)e)->e1,
                ((DotVarExp *)e)->var, ((DotVarExp *)e)->hasOverloads);
        }
        else
            assert(0);
        Expression *r = ue.exp();
        r->type = e->type;
        return ue;
    }
    if (e->op == TOKclassreference)
    {
        new(&ue) ClassReferenceExp(e->loc, ((ClassReferenceExp *)e)->value, e->type);
        return ue;
    }
    if (e->op == TOKerror)
    {
        new(&ue) UnionExp(e);
        return ue;
    }
    e->error("CTFE internal error: literal %s", e->toChars());
    assert(0);
    return ue;
}

/* Deal with type painting.
 * Type painting is a major nuisance: we can't just set
 * e->type = type, because that would change the original literal.
 * But, we can't simply copy the literal either, because that would change
 * the values of any pointers.
 */
Expression *paintTypeOntoLiteral(Type *type, Expression *lit)
{
    if (lit->type->equals(type))
        return lit;
    return paintTypeOntoLiteralCopy(type, lit).copy();
}

Expression *paintTypeOntoLiteral(UnionExp *pue, Type *type, Expression *lit)
{
    if (lit->type->equals(type))
        return lit;
    *pue = paintTypeOntoLiteralCopy(type, lit);
    return pue->exp();
}

UnionExp paintTypeOntoLiteralCopy(Type *type, Expression *lit)
{
    UnionExp ue;

    if (lit->type->equals(type))
    {
        new(&ue) UnionExp(lit);
        return ue;
    }

    // If it is a cast to inout, retain the original type of the referenced part.
    if (type->hasWild() && type->hasPointers())
    {
        new(&ue) UnionExp(lit);
        ue.exp()->type = type;
        return ue;
    }

    if (lit->op == TOKslice)
    {
        SliceExp *se = (SliceExp *)lit;
        new(&ue) SliceExp(lit->loc, se->e1, se->lwr, se->upr);
    }
    else if (lit->op == TOKindex)
    {
        IndexExp *ie = (IndexExp *)lit;
        new(&ue) IndexExp(lit->loc, ie->e1, ie->e2);
    }
    else if (lit->op == TOKarrayliteral)
    {
        new(&ue) SliceExp(lit->loc, lit,
            new IntegerExp(Loc(), 0, Type::tsize_t), ArrayLength(Type::tsize_t, lit).copy());
    }
    else if (lit->op == TOKstring)
    {
        // For strings, we need to introduce another level of indirection
        new(&ue) SliceExp(lit->loc, lit,
            new IntegerExp(Loc(), 0, Type::tsize_t), ArrayLength(Type::tsize_t, lit).copy());
    }
    else if (lit->op == TOKassocarrayliteral)
    {
        AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)lit;
        // TODO: we should be creating a reference to this AAExp, not
        // just a ref to the keys and values.
        OwnedBy wasOwned = aae->ownedByCtfe;
        new(&ue) AssocArrayLiteralExp(lit->loc, aae->keys, aae->values);
        aae = (AssocArrayLiteralExp *)ue.exp();
        aae->ownedByCtfe = wasOwned;
    }
    else
    {
        // Can't type paint from struct to struct*; this needs another
        // level of indirection
        if (lit->op == TOKstructliteral && isPointer(type))
            lit->error("CTFE internal error: painting %s", type->toChars());
        ue = copyLiteral(lit);
    }
    ue.exp()->type = type;
    return ue;
}

/*************************************
 * If e is a SliceExp, constant fold it.
 * Params:
 *      e = expression to resolve
 *      pue = if not null, store resulting expression here
 * Returns:
 *      resulting expression
 */
Expression *resolveSlice(Expression *e, UnionExp *pue)
{
    if (e->op != TOKslice)
        return e;
    SliceExp *se = (SliceExp *)e;
    if (se->e1->op == TOKnull)
        return se->e1;
    if (pue)
    {
        *pue = Slice(e->type, se->e1, se->lwr, se->upr);
        return pue->exp();
    }
    else
        return Slice(e->type, se->e1, se->lwr, se->upr).copy();
}

/* Determine the array length, without interpreting it.
 * e must be an array literal, or a slice
 * It's very wasteful to resolve the slice when we only
 * need the length.
 */
uinteger_t resolveArrayLength(Expression *e)
{
    if (e->op == TOKvector)
        return ((VectorExp *)e)->dim;

    if (e->op == TOKnull)
        return 0;
    if (e->op == TOKslice)
    {
        uinteger_t ilo = ((SliceExp *)e)->lwr->toInteger();
        uinteger_t iup = ((SliceExp *)e)->upr->toInteger();
        return iup - ilo;
    }
    if (e->op == TOKstring)
    {
        return ((StringExp *)e)->len;
    }
    if (e->op == TOKarrayliteral)
    {
        ArrayLiteralExp *ale = (ArrayLiteralExp *)e;
        return ale->elements ? ale->elements->length : 0;
    }
    if (e->op == TOKassocarrayliteral)
    {
        AssocArrayLiteralExp *ale = (AssocArrayLiteralExp *)e;
        return ale->keys->length;
    }
    assert(0);
    return 0;
}

/******************************
 * Helper for NewExp
 * Create an array literal consisting of 'elem' duplicated 'dim' times.
 * Params:
 *      pue = where to store result
 *      loc = source location where the interpretation occurs
 *      type = target type of the result
 *      elem = the source of array element, it will be owned by the result
 *      dim = element number of the result
 * Returns:
 *      Constructed ArrayLiteralExp
 */
ArrayLiteralExp *createBlockDuplicatedArrayLiteral(UnionExp *pue, Loc loc, Type *type,
        Expression *elem, size_t dim)
{
    if (type->ty == Tsarray && type->nextOf()->ty == Tsarray && elem->type->ty != Tsarray)
    {
        // If it is a multidimensional array literal, do it recursively
        TypeSArray *tsa = (TypeSArray *)type->nextOf();
        size_t len = (size_t)tsa->dim->toInteger();
        UnionExp ue;
        elem = createBlockDuplicatedArrayLiteral(&ue, loc, type->nextOf(), elem, len);
        if (elem == ue.exp())
            elem = ue.copy();
    }

    // Buzilla 15681
    Type *tb = elem->type->toBasetype();
    const bool mustCopy = tb->ty == Tstruct || tb->ty == Tsarray;

    Expressions *elements = new Expressions();
    elements->setDim(dim);
    for (size_t i = 0; i < dim; i++)
    {
        (*elements)[i] = mustCopy ? copyLiteral(elem).copy() : elem;
    }
    new(pue) ArrayLiteralExp(loc, type, elements);
    ArrayLiteralExp *ale = (ArrayLiteralExp *)pue->exp();
    ale->ownedByCtfe = OWNEDctfe;
    return ale;
}

/******************************
 * Helper for NewExp
 * Create a string literal consisting of 'value' duplicated 'dim' times.
 */
StringExp *createBlockDuplicatedStringLiteral(UnionExp *pue, Loc loc, Type *type,
        unsigned value, size_t dim, unsigned char sz)
{
    utf8_t *s = (utf8_t *)mem.xcalloc(dim + 1, sz);
    for (size_t elemi = 0; elemi < dim; ++elemi)
    {
        switch (sz)
        {
            case 1:     s[elemi] = (utf8_t)value; break;
            case 2:     ((unsigned short *)s)[elemi] = (unsigned short)value; break;
            case 4:     ((unsigned *)s)[elemi] = value; break;
            default:    assert(0);
        }
    }
    new(pue) StringExp(loc, s, dim);
    StringExp *se = (StringExp *)pue->exp();
    se->type = type;
    se->sz = sz;
    se->committed = true;
    se->ownedByCtfe = OWNEDctfe;
    return se;
}

// Return true if t is an AA
bool isAssocArray(Type *t)
{
    t = t->toBasetype();
    if (t->ty == Taarray)
        return true;
    return false;
}

// Given a template AA type, extract the corresponding built-in AA type
TypeAArray *toBuiltinAAType(Type *t)
{
    t = t->toBasetype();
    if (t->ty == Taarray)
        return (TypeAArray *)t;
    assert(0);
    return NULL;
}

/************** TypeInfo operations ************************************/

// Return true if type is TypeInfo_Class
bool isTypeInfo_Class(Type *type)
{
    return type->ty == Tclass &&
        (Type::dtypeinfo == ((TypeClass *)type)->sym ||
         Type::dtypeinfo->isBaseOf(((TypeClass *)type)->sym, NULL));
}

/************** Pointer operations ************************************/

// Return true if t is a pointer (not a function pointer)
bool isPointer(Type *t)
{
    Type * tb = t->toBasetype();
    return tb->ty == Tpointer && tb->nextOf()->ty != Tfunction;
}

// For CTFE only. Returns true if 'e' is true or a non-null pointer.
bool isTrueBool(Expression *e)
{
    return e->isBool(true) ||
           ((e->type->ty == Tpointer || e->type->ty == Tclass) && e->op != TOKnull);
}

/* Is it safe to convert from srcPointee* to destPointee* ?
 * srcPointee is the genuine type (never void).
 * destPointee may be void.
 */
bool isSafePointerCast(Type *srcPointee, Type *destPointee)
{
    // It's safe to cast S** to D** if it's OK to cast S* to D*
    while (srcPointee->ty == Tpointer && destPointee->ty == Tpointer)
    {
        srcPointee = srcPointee->nextOf();
        destPointee = destPointee->nextOf();
    }

    // It's OK if both are the same (modulo const)
    if (srcPointee->constConv(destPointee))
        return true;

    // It's OK if function pointers differ only in safe/pure/nothrow
    if (srcPointee->ty == Tfunction && destPointee->ty == Tfunction)
        return srcPointee->covariant(destPointee) == 1;

    // it's OK to cast to void*
    if (destPointee->ty == Tvoid)
        return true;

    // It's OK to cast from V[K] to void*
    if (srcPointee->ty == Taarray && destPointee == Type::tvoidptr)
        return true;

    // It's OK if they are the same size (static array of) integers, eg:
    //     int*     --> uint*
    //     int[5][] --> uint[5][]
    if (srcPointee->ty == Tsarray && destPointee->ty == Tsarray)
    {
        if (srcPointee->size() != destPointee->size())
            return false;
        srcPointee = srcPointee->baseElemOf();
        destPointee = destPointee->baseElemOf();
    }
    return srcPointee->isintegral() &&
           destPointee->isintegral() &&
           srcPointee->size() == destPointee->size();
}

Expression *getAggregateFromPointer(Expression *e, dinteger_t *ofs)
{
    *ofs = 0;
    if (e->op == TOKaddress)
        e = ((AddrExp *)e)->e1;
    if (e->op == TOKsymoff)
        *ofs = ((SymOffExp *)e)->offset;
    if (e->op == TOKdotvar)
    {
        Expression *ex = ((DotVarExp *)e)->e1;
        VarDeclaration *v = ((DotVarExp *)e)->var->isVarDeclaration();
        assert(v);
        StructLiteralExp *se = ex->op == TOKclassreference ? ((ClassReferenceExp *)ex)->value : (StructLiteralExp *)ex;
        // We can't use getField, because it makes a copy
        unsigned i;
        if (ex->op == TOKclassreference)
            i = ((ClassReferenceExp *)ex)->getFieldIndex(e->type, v->offset);
        else
            i = se->getFieldIndex(e->type, v->offset);
        e = (*se->elements)[i];
    }
    if (e->op == TOKindex)
    {
        IndexExp *ie = (IndexExp *)e;
        // Note that each AA element is part of its own memory block
        if ((ie->e1->type->ty == Tarray ||
             ie->e1->type->ty == Tsarray ||
             ie->e1->op == TOKstring ||
             ie->e1->op == TOKarrayliteral) &&
            ie->e2->op == TOKint64)
        {
            *ofs = ie->e2->toInteger();
            return ie->e1;
        }
    }
    if (e->op == TOKslice && e->type->toBasetype()->ty == Tsarray)
    {
        SliceExp *se = (SliceExp *)e;
        if ((se->e1->type->ty == Tarray ||
             se->e1->type->ty == Tsarray ||
             se->e1->op == TOKstring ||
             se->e1->op == TOKarrayliteral) &&
            se->lwr->op == TOKint64)
        {
            *ofs = se->lwr->toInteger();
            return se->e1;
        }
    }
    return e;
}

/** Return true if agg1 and agg2 are pointers to the same memory block
*/
bool pointToSameMemoryBlock(Expression *agg1, Expression *agg2)
{
    if (agg1 == agg2)
        return true;

    // For integers cast to pointers, we regard them as non-comparable
    // unless they are identical. (This may be overly strict).
    if (agg1->op == TOKint64 && agg2->op == TOKint64 &&
        agg1->toInteger() == agg2->toInteger())
    {
        return true;
    }

    // Note that type painting can occur with VarExp, so we
    // must compare the variables being pointed to.
    if (agg1->op == TOKvar && agg2->op == TOKvar &&
        ((VarExp *)agg1)->var == ((VarExp *)agg2)->var)
    {
        return true;
    }
    if (agg1->op == TOKsymoff && agg2->op == TOKsymoff &&
        ((SymOffExp *)agg1)->var == ((SymOffExp *)agg2)->var)
    {
        return true;
    }

    return false;
}

// return e1 - e2 as an integer, or error if not possible
UnionExp pointerDifference(Loc loc, Type *type, Expression *e1, Expression *e2)
{
    UnionExp ue;
    dinteger_t ofs1, ofs2;
    Expression *agg1 = getAggregateFromPointer(e1, &ofs1);
    Expression *agg2 = getAggregateFromPointer(e2, &ofs2);
    if (agg1 == agg2)
    {
        Type *pointee = ((TypePointer *)agg1->type)->next;
        dinteger_t sz = pointee->size();
        new(&ue) IntegerExp(loc, (ofs1 - ofs2) * sz, type);
    }
    else if (agg1->op == TOKstring && agg2->op == TOKstring)
    {
        if (((StringExp *)agg1)->string == ((StringExp *)agg2)->string)
        {
            Type *pointee = ((TypePointer *)agg1->type)->next;
            dinteger_t sz = pointee->size();
            new(&ue) IntegerExp(loc, (ofs1 - ofs2) * sz, type);
        }
    }
    else if (agg1->op == TOKsymoff && agg2->op == TOKsymoff &&
             ((SymOffExp *)agg1)->var == ((SymOffExp *)agg2)->var)
    {
        new(&ue) IntegerExp(loc, ofs1 - ofs2, type);
    }
    else
    {
        error(loc, "%s - %s cannot be interpreted at compile time: cannot subtract "
            "pointers to two different memory blocks",
            e1->toChars(), e2->toChars());
        new(&ue) CTFEExp(TOKcantexp);
    }
    return ue;
}

// Return eptr op e2, where eptr is a pointer, e2 is an integer,
// and op is TOKadd or TOKmin
UnionExp pointerArithmetic(Loc loc, TOK op, Type *type,
    Expression *eptr, Expression *e2)
{
    UnionExp ue;

    if (eptr->type->nextOf()->ty == Tvoid)
    {
        error(loc, "cannot perform arithmetic on void* pointers at compile time");
      Lcant:
        new(&ue) CTFEExp(TOKcantexp);
        return ue;
    }

    dinteger_t ofs1;
    if (eptr->op == TOKaddress)
        eptr = ((AddrExp *)eptr)->e1;
    Expression *agg1 = getAggregateFromPointer(eptr, &ofs1);
    if (agg1->op == TOKsymoff)
    {
        if (((SymOffExp *)agg1)->var->type->ty != Tsarray)
        {
            error(loc, "cannot perform pointer arithmetic on arrays of unknown length at compile time");
            goto Lcant;
        }
    }
    else if (agg1->op != TOKstring && agg1->op != TOKarrayliteral)
    {
        error(loc, "cannot perform pointer arithmetic on non-arrays at compile time");
        goto Lcant;
    }
    dinteger_t ofs2 = e2->toInteger();

    Type *pointee = ((TypeNext *)agg1->type->toBasetype())->next;
    dinteger_t sz = pointee->size();

    sinteger_t indx;
    dinteger_t len;
    if (agg1->op == TOKsymoff)
    {
        indx = ofs1 / sz;
        len = ((TypeSArray *)((SymOffExp *)agg1)->var->type)->dim->toInteger();
    }
    else
    {
        Expression *dollar = ArrayLength(Type::tsize_t, agg1).copy();
        assert(!CTFEExp::isCantExp(dollar));
        indx = ofs1;
        len = dollar->toInteger();
    }
    if (op == TOKadd || op == TOKaddass || op == TOKplusplus)
        indx += ofs2 / sz;
    else if (op == TOKmin || op == TOKminass || op == TOKminusminus)
        indx -= ofs2 / sz;
    else
    {
        error(loc, "CTFE internal error: bad pointer operation");
        goto Lcant;
    }

    if (indx < 0 || len < (dinteger_t)indx)
    {
        error(loc, "cannot assign pointer to index %lld inside memory block [0..%lld]", (ulonglong)indx, (ulonglong)len);
        goto Lcant;
    }

    if (agg1->op == TOKsymoff)
    {
        new(&ue) SymOffExp(loc, ((SymOffExp *)agg1)->var, indx * sz);
        SymOffExp *se = (SymOffExp *)ue.exp();
        se->type = type;
        return ue;
    }

    if (agg1->op != TOKarrayliteral && agg1->op != TOKstring)
    {
        error(loc, "CTFE internal error: pointer arithmetic %s", agg1->toChars());
        goto Lcant;
    }

    if (eptr->type->toBasetype()->ty == Tsarray)
    {
        dinteger_t dim = ((TypeSArray *)eptr->type->toBasetype())->dim->toInteger();

        // Create a CTFE pointer &agg1[indx .. indx+dim]
        SliceExp *se = new SliceExp(loc, agg1,
            new IntegerExp(loc, indx,       Type::tsize_t),
            new IntegerExp(loc, indx + dim, Type::tsize_t));
        se->type = type->toBasetype()->nextOf();
        new(&ue) AddrExp(loc, se);
        ue.exp()->type = type;
        return ue;
    }

    // Create a CTFE pointer &agg1[indx]
    IntegerExp *ofs = new IntegerExp(loc, indx, Type::tsize_t);
    Expression *ie = new IndexExp(loc, agg1, ofs);
    ie->type = type->toBasetype()->nextOf();    // Bugzilla 13992
    new(&ue) AddrExp(loc, ie);
    ue.exp()->type = type;
    return ue;
}

// Return 1 if true, 0 if false
// -1 if comparison is illegal because they point to non-comparable memory blocks
int comparePointers(TOK op, Expression *agg1, dinteger_t ofs1, Expression *agg2, dinteger_t ofs2)
{
    if (pointToSameMemoryBlock(agg1, agg2))
    {
        int n;
        switch (op)
        {
        case TOKlt:          n = (ofs1 <  ofs2); break;
        case TOKle:          n = (ofs1 <= ofs2); break;
        case TOKgt:          n = (ofs1 >  ofs2); break;
        case TOKge:          n = (ofs1 >= ofs2); break;
        case TOKidentity:
        case TOKequal:       n = (ofs1 == ofs2); break;
        case TOKnotidentity:
        case TOKnotequal:    n = (ofs1 != ofs2); break;
        default:
            assert(0);
        }
        return n;
    }
    bool null1 = (agg1->op == TOKnull);
    bool null2 = (agg2->op == TOKnull);

    int cmp;
    if (null1 || null2)
    {
        switch (op)
        {
        case TOKlt:   cmp =  null1 && !null2;   break;
        case TOKgt:   cmp = !null1 &&  null2;   break;
        case TOKle:   cmp = null1;              break;
        case TOKge:   cmp = null2;              break;
        case TOKidentity:
        case TOKequal:
        case TOKnotidentity: // 'cmp' gets inverted below
        case TOKnotequal:
            cmp = (null1 == null2);
            break;
        default:
            assert(0);
        }
    }
    else
    {
        switch (op)
        {
        case TOKidentity:
        case TOKequal:
        case TOKnotidentity: // 'cmp' gets inverted below
        case TOKnotequal:
            cmp = 0;
            break;
        default:
            return -1; // memory blocks are different
        }
    }
    if (op == TOKnotidentity || op == TOKnotequal)
        cmp ^= 1;
    return cmp;
}

// True if conversion from type 'from' to 'to' involves a reinterpret_cast
// floating point -> integer or integer -> floating point
bool isFloatIntPaint(Type *to, Type *from)
{
    return from->size() == to->size() &&
           ((from->isintegral() && to->isfloating()) ||
            (from->isfloating() && to->isintegral()));
}

// Reinterpret float/int value 'fromVal' as a float/integer of type 'to'.
Expression *paintFloatInt(UnionExp *pue, Expression *fromVal, Type *to)
{
    if (exceptionOrCantInterpret(fromVal))
        return fromVal;

    assert(to->size() == 4 || to->size() == 8);
    return Compiler::paintAsType(pue, fromVal, to);
}

/******** Constant folding, with support for CTFE ***************************/

/// Return true if non-pointer expression e can be compared
/// with >,is, ==, etc, using ctfeCmp, ctfeEqual, ctfeIdentity
bool isCtfeComparable(Expression *e)
{
    if (e->op == TOKslice)
        e = ((SliceExp *)e)->e1;

    if (e->isConst() != 1)
    {
        if (e->op == TOKnull ||
            e->op == TOKstring ||
            e->op == TOKfunction ||
            e->op == TOKdelegate ||
            e->op == TOKarrayliteral ||
            e->op == TOKstructliteral ||
            e->op == TOKassocarrayliteral ||
            e->op == TOKclassreference)
        {
            return true;
        }
        // Bugzilla 14123: TypeInfo object is comparable in CTFE
        if (e->op == TOKtypeid)
            return true;

        return false;
    }
    return true;
}

/// Map TOK comparison ops
template <typename N>
static bool numCmp(TOK op, N n1, N n2)
{
    switch (op)
    {
        case TOKlt:
            return n1 <  n2;
        case TOKle:
            return n1 <= n2;
        case TOKgt:
            return n1 >  n2;
        case TOKge:
            return n1 >= n2;

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

/// Returns cmp OP 0; where OP is ==, !=, <, >=, etc. Result is 0 or 1
int specificCmp(TOK op, int rawCmp)
{
    return numCmp<int>(op, rawCmp, 0);
}

/// Returns e1 OP e2; where OP is ==, !=, <, >=, etc. Result is 0 or 1
int intUnsignedCmp(TOK op, dinteger_t n1, dinteger_t n2)
{
    return numCmp<dinteger_t>(op, n1, n2);
}

/// Returns e1 OP e2; where OP is ==, !=, <, >=, etc. Result is 0 or 1
int intSignedCmp(TOK op, sinteger_t n1, sinteger_t n2)
{
    return numCmp<sinteger_t>(op, n1, n2);
}

/// Returns e1 OP e2; where OP is ==, !=, <, >=, etc. Result is 0 or 1
int realCmp(TOK op, real_t r1, real_t r2)
{
    // Don't rely on compiler, handle NAN arguments separately
    if (CTFloat::isNaN(r1) || CTFloat::isNaN(r2)) // if unordered
    {
        switch (op)
        {
            case TOKlt:
            case TOKle:
            case TOKgt:
            case TOKge:
                break;

            default:
                assert(0);
        }
        return 0;
    }
    else
    {
        return numCmp<real_t>(op, r1, r2);
    }
}

int ctfeRawCmp(Loc loc, Expression *e1, Expression *e2);

/* Conceptually the same as memcmp(e1, e2).
 * e1 and e2 may be strings, arrayliterals, or slices.
 * For string types, return <0 if e1 < e2, 0 if e1==e2, >0 if e1 > e2.
 * For all other types, return 0 if e1 == e2, !=0 if e1 != e2.
 */
int ctfeCmpArrays(Loc loc, Expression *e1, Expression *e2, uinteger_t len)
{
    // Resolve slices, if necessary
    uinteger_t lo1 = 0;
    uinteger_t lo2 = 0;

    Expression *x = e1;
    if (x->op == TOKslice)
    {
        lo1 = ((SliceExp *)x)->lwr->toInteger();
        x = ((SliceExp *)x)->e1;
    }
    StringExp *se1 = (x->op == TOKstring) ? (StringExp *)x : NULL;
    ArrayLiteralExp *ae1 = (x->op == TOKarrayliteral) ? (ArrayLiteralExp *)x : NULL;

    x = e2;
    if (x->op == TOKslice)
    {
        lo2 = ((SliceExp *)x)->lwr->toInteger();
        x = ((SliceExp *)x)->e1;
    }
    StringExp *se2 = (x->op == TOKstring) ? (StringExp *)x : NULL;
    ArrayLiteralExp *ae2 = (x->op == TOKarrayliteral) ? (ArrayLiteralExp *)x : NULL;

    // Now both must be either TOKarrayliteral or TOKstring
    if (se1 && se2)
        return sliceCmpStringWithString(se1, se2, (size_t)lo1, (size_t)lo2, (size_t)len);
    if (se1 && ae2)
        return sliceCmpStringWithArray(se1, ae2, (size_t)lo1, (size_t)lo2, (size_t)len);
    if (se2 && ae1)
        return -sliceCmpStringWithArray(se2, ae1, (size_t)lo2, (size_t)lo1, (size_t)len);

    assert (ae1 && ae2);
    // Comparing two array literals. This case is potentially recursive.
    // If they aren't strings, we just need an equality check rather than
    // a full cmp.
    bool needCmp = ae1->type->nextOf()->isintegral();
    for (size_t i = 0; i < (size_t)len; i++)
    {
        Expression *ee1 = (*ae1->elements)[(size_t)(lo1 + i)];
        Expression *ee2 = (*ae2->elements)[(size_t)(lo2 + i)];
        if (needCmp)
        {
            sinteger_t c = ee1->toInteger() - ee2->toInteger();
            if (c > 0)
                return 1;
            if (c < 0)
                return -1;
        }
        else
        {
            if (ctfeRawCmp(loc, ee1, ee2))
                return 1;
        }
    }
    return 0;
}

/* Given a delegate expression e, return .funcptr.
 * If e is NullExp, return NULL.
 */
FuncDeclaration *funcptrOf(Expression *e)
{
    assert(e->type->ty == Tdelegate);

    if (e->op == TOKdelegate)
        return ((DelegateExp *)e)->func;
    if (e->op == TOKfunction)
        return ((FuncExp *)e)->fd;
    assert(e->op == TOKnull);
    return NULL;
}

bool isArray(Expression *e)
{
    return e->op == TOKarrayliteral || e->op == TOKstring ||
           e->op == TOKslice || e->op == TOKnull;
}

/* For strings, return <0 if e1 < e2, 0 if e1==e2, >0 if e1 > e2.
 * For all other types, return 0 if e1 == e2, !=0 if e1 != e2.
 */
int ctfeRawCmp(Loc loc, Expression *e1, Expression *e2)
{
    if (e1->op == TOKclassreference || e2->op == TOKclassreference)
    {
        if (e1->op == TOKclassreference && e2->op == TOKclassreference &&
            ((ClassReferenceExp *)e1)->value == ((ClassReferenceExp *)e2)->value)
            return 0;
        return 1;
    }
    if (e1->op == TOKtypeid && e2->op == TOKtypeid)
    {
        // printf("e1: %s\n", e1->toChars());
        // printf("e2: %s\n", e2->toChars());
        Type *t1 = isType(((TypeidExp *)e1)->obj);
        Type *t2 = isType(((TypeidExp *)e2)->obj);
        assert(t1);
        assert(t2);
        return t1 != t2;
    }

    // null == null, regardless of type

    if (e1->op == TOKnull && e2->op == TOKnull)
        return 0;

    if (e1->type->ty == Tpointer && e2->type->ty == Tpointer)
    {
        // Can only be an equality test.

        dinteger_t ofs1, ofs2;
        Expression *agg1 = getAggregateFromPointer(e1, &ofs1);
        Expression *agg2 = getAggregateFromPointer(e2, &ofs2);
        if ((agg1 == agg2) || (agg1->op == TOKvar && agg2->op == TOKvar &&
            ((VarExp *)agg1)->var == ((VarExp *)agg2)->var))
        {
            if (ofs1 == ofs2)
                return 0;
        }
        return 1;
    }
    if (e1->type->ty == Tdelegate && e2->type->ty == Tdelegate)
    {
        // If .funcptr isn't the same, they are not equal

        if (funcptrOf(e1) != funcptrOf(e2))
            return 1;

        // If both are delegate literals, assume they have the
        // same closure pointer. TODO: We don't support closures yet!
        if (e1->op == TOKfunction && e2->op == TOKfunction)
            return 0;
        assert(e1->op == TOKdelegate && e2->op == TOKdelegate);

        // Same .funcptr. Do they have the same .ptr?
        Expression * ptr1 = ((DelegateExp *)e1)->e1;
        Expression * ptr2 = ((DelegateExp *)e2)->e1;

        dinteger_t ofs1, ofs2;
        Expression *agg1 = getAggregateFromPointer(ptr1, &ofs1);
        Expression *agg2 = getAggregateFromPointer(ptr2, &ofs2);
        // If they are TOKvar, it means they are FuncDeclarations
        if ((agg1 == agg2 && ofs1 == ofs2) ||
            (agg1->op == TOKvar && agg2->op == TOKvar &&
             ((VarExp *)agg1)->var == ((VarExp *)agg2)->var))
        {
            return 0;
        }
        return 1;
    }
    if (isArray(e1) && isArray(e2))
    {
        uinteger_t len1 = resolveArrayLength(e1);
        uinteger_t len2 = resolveArrayLength(e2);
        // workaround for dmc optimizer bug calculating wrong len for
        // uinteger_t len = (len1 < len2 ? len1 : len2);
        // if (len == 0) ...
        if (len1 > 0 && len2 > 0)
        {
            uinteger_t len = (len1 < len2 ? len1 : len2);
            int res = ctfeCmpArrays(loc, e1, e2, len);
            if (res != 0)
                return res;
        }
        return (int)(len1 - len2);
    }
    if (e1->type->isintegral())
    {
        return e1->toInteger() != e2->toInteger();
    }
    real_t r1;
    real_t r2;
    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
        {
            return 1;
        }
        else
        {
            return (r1 != r2);
        }
    }
    else if (e1->type->iscomplex())
    {
        return e1->toComplex() != e2->toComplex();
    }

    if (e1->op == TOKstructliteral && e2->op == TOKstructliteral)
    {
        StructLiteralExp *es1 = (StructLiteralExp *)e1;
        StructLiteralExp *es2 = (StructLiteralExp *)e2;
        // For structs, we only need to return 0 or 1 (< and > aren't legal).

        if (es1->sd != es2->sd)
            return 1;
        else if ((!es1->elements || !es1->elements->length) &&
            (!es2->elements || !es2->elements->length))
            return 0;            // both arrays are empty
        else if (!es1->elements || !es2->elements)
            return 1;
        else if (es1->elements->length != es2->elements->length)
            return 1;
        else
        {
            for (size_t i = 0; i < es1->elements->length; i++)
            {
                Expression *ee1 = (*es1->elements)[i];
                Expression *ee2 = (*es2->elements)[i];

                if (ee1 == ee2)
                    continue;
                if (!ee1 || !ee2)
                   return 1;
                int cmp = ctfeRawCmp(loc, ee1, ee2);
                if (cmp)
                    return 1;
            }
            return 0;   // All elements are equal
        }
    }
    if (e1->op == TOKassocarrayliteral && e2->op == TOKassocarrayliteral)
    {
        AssocArrayLiteralExp *es1 = (AssocArrayLiteralExp *)e1;
        AssocArrayLiteralExp *es2 = (AssocArrayLiteralExp *)e2;

        size_t dim = es1->keys->length;
        if (es2->keys->length != dim)
            return 1;

        bool *used = (bool *)mem.xmalloc(sizeof(bool) * dim);
        memset(used, 0, sizeof(bool) * dim);

        for (size_t i = 0; i < dim; ++i)
        {
            Expression *k1 = (*es1->keys)[i];
            Expression *v1 = (*es1->values)[i];
            Expression *v2 = NULL;
            for (size_t j = 0; j < dim; ++j)
            {
                if (used[j])
                    continue;
                Expression *k2 = (*es2->keys)[j];

                if (ctfeRawCmp(loc, k1, k2))
                    continue;
                used[j] = true;
                v2 = (*es2->values)[j];
                break;
            }
            if (!v2 || ctfeRawCmp(loc, v1, v2))
            {
                mem.xfree(used);
                return 1;
            }
        }
        mem.xfree(used);
        return 0;
    }
    error(loc, "CTFE internal error: bad compare of `%s` and `%s`", e1->toChars(), e2->toChars());
    assert(0);
    return 0;
}

/// Evaluate ==, !=.  Resolves slices before comparing. Returns 0 or 1
int ctfeEqual(Loc loc, TOK op, Expression *e1, Expression *e2)
{
    int cmp = !ctfeRawCmp(loc, e1, e2);
    if (op == TOKnotequal)
        cmp ^= 1;
    return cmp;
}

/// Evaluate is, !is.  Resolves slices before comparing. Returns 0 or 1
int ctfeIdentity(Loc loc, TOK op, Expression *e1, Expression *e2)
{
    //printf("ctfeIdentity op = '%s', e1 = %s %s, e2 = %s %s\n", Token::toChars(op),
    //    Token::toChars(e1->op), e1->toChars(), Token::toChars(e2->op), e1->toChars());
    int cmp;
    if (e1->op == TOKnull)
    {
        cmp = (e2->op == TOKnull);
    }
    else if (e2->op == TOKnull)
    {
        cmp = 0;
    }
    else if (e1->op == TOKsymoff && e2->op == TOKsymoff)
    {
        SymOffExp *es1 = (SymOffExp *)e1;
        SymOffExp *es2 = (SymOffExp *)e2;
        cmp = (es1->var == es2->var && es1->offset == es2->offset);
    }
    else if (e1->type->isreal())
        cmp = RealEquals(e1->toReal(), e2->toReal());
    else if (e1->type->isimaginary())
        cmp = RealEquals(e1->toImaginary(), e2->toImaginary());
    else if (e1->type->iscomplex())
    {
        complex_t v1 = e1->toComplex();
        complex_t v2 = e2->toComplex();
        cmp = RealEquals(creall(v1), creall(v2)) &&
                 RealEquals(cimagl(v1), cimagl(v1));
    }
    else
        cmp = !ctfeRawCmp(loc, e1, e2);

    if (op == TOKnotidentity || op == TOKnotequal)
        cmp ^= 1;
    return cmp;
}

/// Evaluate >,<=, etc. Resolves slices before comparing. Returns 0 or 1
int ctfeCmp(Loc loc, TOK op, Expression *e1, Expression *e2)
{
    Type *t1 = e1->type->toBasetype();
    Type *t2 = e2->type->toBasetype();

    if (t1->isString() && t2->isString())
        return specificCmp(op, ctfeRawCmp(loc, e1, e2));
    else if (t1->isreal())
        return realCmp(op, e1->toReal(), e2->toReal());
    else if (t1->isimaginary())
        return realCmp(op, e1->toImaginary(), e2->toImaginary());
    else if (t1->isunsigned() || t2->isunsigned())
        return intUnsignedCmp(op, e1->toInteger(), e2->toInteger());
    else
        return intSignedCmp(op, e1->toInteger(), e2->toInteger());
}

UnionExp ctfeCat(Loc loc, Type *type, Expression *e1, Expression *e2)
{
    Type *t1 = e1->type->toBasetype();
    Type *t2 = e2->type->toBasetype();
    UnionExp ue;
    if (e2->op == TOKstring && e1->op == TOKarrayliteral &&
        t1->nextOf()->isintegral())
    {
        // [chars] ~ string => string (only valid for CTFE)
        StringExp *es1 = (StringExp *)e2;
        ArrayLiteralExp *es2 = (ArrayLiteralExp *)e1;
        size_t len = es1->len + es2->elements->length;
        unsigned char sz = es1->sz;

        void *s = mem.xmalloc((len + 1) * sz);
        memcpy((char *)s + sz * es2->elements->length, es1->string, es1->len * sz);
        for (size_t i = 0; i < es2->elements->length; i++)
        {
            Expression *es2e = (*es2->elements)[i];
            if (es2e->op != TOKint64)
            {
                new(&ue) CTFEExp(TOKcantexp);
                return ue;
            }
            dinteger_t v = es2e->toInteger();
            Port::valcpy((utf8_t *)s + i * sz, v, sz);
        }

        // Add terminating 0
        memset((utf8_t *)s + len * sz, 0, sz);

        new(&ue) StringExp(loc, s, len);
        StringExp *es = (StringExp *)ue.exp();
        es->sz = sz;
        es->committed = 0;
        es->type = type;
        return ue;
    }
    if (e1->op == TOKstring && e2->op == TOKarrayliteral &&
        t2->nextOf()->isintegral())
    {
        // string ~ [chars] => string (only valid for CTFE)
        // Concatenate the strings
        StringExp *es1 = (StringExp *)e1;
        ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2;
        size_t len = es1->len + es2->elements->length;
        unsigned char sz = es1->sz;

        void *s = mem.xmalloc((len + 1) * sz);
        memcpy(s, es1->string, es1->len * sz);
        for (size_t i = 0; i < es2->elements->length; i++)
        {
            Expression *es2e = (*es2->elements)[i];
            if (es2e->op != TOKint64)
            {
                new(&ue) CTFEExp(TOKcantexp);
                return ue;
            }
            dinteger_t v = es2e->toInteger();
            Port::valcpy((utf8_t *)s + (es1->len + i) * sz, v, sz);
        }

        // Add terminating 0
        memset((utf8_t *)s + len * sz, 0, sz);

        new(&ue) StringExp(loc, s, len);
        StringExp *es = (StringExp *)ue.exp();
        es->sz = sz;
        es->committed = 0; //es1->committed;
        es->type = type;
        return ue;
    }
    if (e1->op == TOKarrayliteral && e2->op == TOKarrayliteral &&
        t1->nextOf()->equals(t2->nextOf()))
    {
        //  [ e1 ] ~ [ e2 ] ---> [ e1, e2 ]
        ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1;
        ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2;

        new(&ue) ArrayLiteralExp(es1->loc, type, copyLiteralArray(es1->elements));
        es1 = (ArrayLiteralExp *)ue.exp();
        es1->elements->insert(es1->elements->length, copyLiteralArray(es2->elements));
        return ue;
    }
    if (e1->op == TOKarrayliteral && e2->op == TOKnull &&
        t1->nextOf()->equals(t2->nextOf()))
    {
        //  [ e1 ] ~ null ----> [ e1 ].dup
        ue = paintTypeOntoLiteralCopy(type, copyLiteral(e1).copy());
        return ue;
    }
    if (e1->op == TOKnull && e2->op == TOKarrayliteral &&
        t1->nextOf()->equals(t2->nextOf()))
    {
        //  null ~ [ e2 ] ----> [ e2 ].dup
        ue = paintTypeOntoLiteralCopy(type, copyLiteral(e2).copy());
        return ue;
    }
    ue = Cat(type, e1, e2);
    return ue;
}

/*  Given an AA literal 'ae', and a key 'e2':
 *  Return ae[e2] if present, or NULL if not found.
 */
Expression *findKeyInAA(Loc loc, AssocArrayLiteralExp *ae, Expression *e2)
{
    /* Search the keys backwards, in case there are duplicate keys
     */
    for (size_t i = ae->keys->length; i;)
    {
        i--;
        Expression *ekey = (*ae->keys)[i];
        int eq = ctfeEqual(loc, TOKequal, ekey, e2);
        if (eq)
        {
            return (*ae->values)[i];
        }
    }
    return NULL;
}

/* Same as for constfold.Index, except that it only works for static arrays,
 * dynamic arrays, and strings. We know that e1 is an
 * interpreted CTFE expression, so it cannot have side-effects.
 */
Expression *ctfeIndex(Loc loc, Type *type, Expression *e1, uinteger_t indx)
{
    //printf("ctfeIndex(e1 = %s)\n", e1->toChars());
    assert(e1->type);
    if (e1->op == TOKstring)
    {
        StringExp *es1 = (StringExp *)e1;
        if (indx >= es1->len)
        {
            error(loc, "string index %llu is out of bounds [0 .. %llu]", (ulonglong)indx, (ulonglong)es1->len);
            return CTFEExp::cantexp;
        }
        return new IntegerExp(loc, es1->charAt(indx), type);
    }
    assert(e1->op == TOKarrayliteral);
    {
        ArrayLiteralExp *ale = (ArrayLiteralExp *)e1;
        if (indx >= ale->elements->length)
        {
            error(loc, "array index %llu is out of bounds %s[0 .. %llu]", (ulonglong)indx, e1->toChars(), (ulonglong)ale->elements->length);
            return CTFEExp::cantexp;
        }
        Expression *e = (*ale->elements)[(size_t)indx];
        return paintTypeOntoLiteral(type, e);
    }
}

Expression *ctfeCast(UnionExp *pue, Loc loc, Type *type, Type *to, Expression *e)
{
    if (e->op == TOKnull)
        return paintTypeOntoLiteral(pue, to, e);

    if (e->op == TOKclassreference)
    {
        // Disallow reinterpreting class casts. Do this by ensuring that
        // the original class can implicitly convert to the target class
        ClassDeclaration *originalClass = ((ClassReferenceExp *)e)->originalClass();
        if (originalClass->type->implicitConvTo(to->mutableOf()))
            return paintTypeOntoLiteral(pue, to, e);
        else
        {
            new(pue) NullExp(loc, to);
            return pue->exp();
        }
    }

    // Allow TypeInfo type painting
    if (isTypeInfo_Class(e->type) && e->type->implicitConvTo(to))
        return paintTypeOntoLiteral(pue, to, e);

    // Allow casting away const for struct literals
    if (e->op == TOKstructliteral &&
        e->type->toBasetype()->castMod(0) == to->toBasetype()->castMod(0))
        return paintTypeOntoLiteral(pue, to, e);

    Expression *r;
    if (e->type->equals(type) && type->equals(to))
    {
        // necessary not to change e's address for pointer comparisons
        r = e;
    }
    else if (to->toBasetype()->ty == Tarray &&
             type->toBasetype()->ty == Tarray &&
             to->toBasetype()->nextOf()->size() == type->toBasetype()->nextOf()->size())
    {
        // Bugzilla 12495: Array reinterpret casts: eg. string to immutable(ubyte)[]
        return paintTypeOntoLiteral(pue, to, e);
    }
    else
    {
        *pue = Cast(loc, type, to, e);
        r = pue->exp();
    }

    if (CTFEExp::isCantExp(r))
        error(loc, "cannot cast %s to %s at compile time", e->toChars(), to->toChars());

    if (e->op == TOKarrayliteral)
        ((ArrayLiteralExp *)e)->ownedByCtfe = OWNEDctfe;

    if (e->op == TOKstring)
        ((StringExp *)e)->ownedByCtfe = OWNEDctfe;

    return r;
}

/******** Assignment helper functions ***************************/

/* Set dest = src, where both dest and src are container value literals
 * (ie, struct literals, or static arrays (can be an array literal or a string))
 * Assignment is recursively in-place.
 * Purpose: any reference to a member of 'dest' will remain valid after the
 * assignment.
 */
void assignInPlace(Expression *dest, Expression *src)
{
    assert(dest->op == TOKstructliteral ||
           dest->op == TOKarrayliteral ||
           dest->op == TOKstring);
    Expressions *oldelems;
    Expressions *newelems;
    if (dest->op == TOKstructliteral)
    {
        assert(dest->op == src->op);
        oldelems = ((StructLiteralExp *)dest)->elements;
        newelems = ((StructLiteralExp *)src)->elements;
        if (((StructLiteralExp *)dest)->sd->isNested() && oldelems->length == newelems->length - 1)
            oldelems->push(NULL);
    }
    else if (dest->op == TOKarrayliteral && src->op==TOKarrayliteral)
    {
        oldelems = ((ArrayLiteralExp *)dest)->elements;
        newelems = ((ArrayLiteralExp *)src)->elements;
    }
    else if (dest->op == TOKstring && src->op == TOKstring)
    {
        sliceAssignStringFromString((StringExp *)dest, (StringExp *)src, 0);
        return;
    }
    else if (dest->op == TOKarrayliteral && src->op == TOKstring)
    {
        sliceAssignArrayLiteralFromString((ArrayLiteralExp *)dest, (StringExp *)src, 0);
        return;
    }
    else if (src->op == TOKarrayliteral && dest->op == TOKstring)
    {
        sliceAssignStringFromArrayLiteral((StringExp *)dest, (ArrayLiteralExp *)src, 0);
        return;
    }
    else
        assert(0);

    assert(oldelems->length == newelems->length);

    for (size_t i= 0; i < oldelems->length; ++i)
    {
        Expression *e = (*newelems)[i];
        Expression *o = (*oldelems)[i];
        if (e->op == TOKstructliteral)
        {
            assert(o->op == e->op);
            assignInPlace(o, e);
        }
        else if (e->type->ty == Tsarray && e->op != TOKvoid &&
                 o->type->ty == Tsarray)
        {
            assignInPlace(o, e);
        }
        else
        {
            (*oldelems)[i] = (*newelems)[i];
        }
    }
}

// Duplicate the elements array, then set field 'indexToChange' = newelem.
Expressions *changeOneElement(Expressions *oldelems, size_t indexToChange, Expression *newelem)
{
    Expressions *expsx = new Expressions();
    ++CtfeStatus::numArrayAllocs;
    expsx->setDim(oldelems->length);
    for (size_t j = 0; j < expsx->length; j++)
    {
        if (j == indexToChange)
            (*expsx)[j] = newelem;
        else
            (*expsx)[j] = (*oldelems)[j];
    }
    return expsx;
}

// Given an AA literal aae,  set aae[index] = newval and return newval.
Expression *assignAssocArrayElement(Loc loc, AssocArrayLiteralExp *aae,
    Expression *index, Expression *newval)
{
    /* Create new associative array literal reflecting updated key/value
     */
    Expressions *keysx = aae->keys;
    Expressions *valuesx = aae->values;
    int updated = 0;
    for (size_t j = valuesx->length; j; )
    {
        j--;
        Expression *ekey = (*aae->keys)[j];
        int eq = ctfeEqual(loc, TOKequal, ekey, index);
        if (eq)
        {
            (*valuesx)[j] = newval;
            updated = 1;
        }
    }
    if (!updated)
    {
        // Append index/newval to keysx[]/valuesx[]
        valuesx->push(newval);
        keysx->push(index);
    }
    return newval;
}

/// Given array literal oldval of type ArrayLiteralExp or StringExp, of length
/// oldlen, change its length to newlen. If the newlen is longer than oldlen,
/// all new elements will be set to the default initializer for the element type.
UnionExp changeArrayLiteralLength(Loc loc, TypeArray *arrayType,
    Expression *oldval,  size_t oldlen, size_t newlen)
{
    UnionExp ue;
    Type *elemType = arrayType->next;
    assert(elemType);
    Expression *defaultElem = elemType->defaultInitLiteral(loc);
    Expressions *elements = new Expressions();
    elements->setDim(newlen);

    // Resolve slices
    size_t indxlo = 0;
    if (oldval->op == TOKslice)
    {
        indxlo = (size_t)((SliceExp *)oldval)->lwr->toInteger();
        oldval = ((SliceExp *)oldval)->e1;
    }
    size_t copylen = oldlen < newlen ? oldlen : newlen;
    if (oldval->op == TOKstring)
    {
        StringExp *oldse = (StringExp *)oldval;
        void *s = mem.xcalloc(newlen + 1, oldse->sz);
        memcpy(s, oldse->string, copylen * oldse->sz);
        unsigned defaultValue = (unsigned)(defaultElem->toInteger());
        for (size_t elemi = copylen; elemi < newlen; ++elemi)
        {
            switch (oldse->sz)
            {
                case 1:     (( utf8_t *)s)[(size_t)(indxlo + elemi)] = ( utf8_t)defaultValue;  break;
                case 2:     ((utf16_t *)s)[(size_t)(indxlo + elemi)] = (utf16_t)defaultValue;  break;
                case 4:     ((utf32_t *)s)[(size_t)(indxlo + elemi)] = (utf32_t)defaultValue;  break;
                default:    assert(0);
            }
        }
        new(&ue) StringExp(loc, s, newlen);
        StringExp *se = (StringExp *)ue.exp();
        se->type = arrayType;
        se->sz = oldse->sz;
        se->committed = oldse->committed;
        se->ownedByCtfe = OWNEDctfe;
    }
    else
    {
        if (oldlen != 0)
        {
            assert(oldval->op == TOKarrayliteral);
            ArrayLiteralExp *ae = (ArrayLiteralExp *)oldval;
            for (size_t i = 0; i < copylen; i++)
                (*elements)[i] = (*ae->elements)[indxlo + i];
        }
        if (elemType->ty == Tstruct || elemType->ty == Tsarray)
        {
            /* If it is an aggregate literal representing a value type,
             * we need to create a unique copy for each element
             */
            for (size_t i = copylen; i < newlen; i++)
                (*elements)[i] = copyLiteral(defaultElem).copy();
        }
        else
        {
            for (size_t i = copylen; i < newlen; i++)
                (*elements)[i] = defaultElem;
        }
        new(&ue) ArrayLiteralExp(loc, arrayType, elements);
        ArrayLiteralExp *aae = (ArrayLiteralExp *)ue.exp();
        aae->ownedByCtfe = OWNEDctfe;
    }
    return ue;
}

/*************************** CTFE Sanity Checks ***************************/

bool isCtfeValueValid(Expression *newval)
{
    Type *tb = newval->type->toBasetype();

    if (newval->op == TOKint64 ||
        newval->op == TOKfloat64 ||
        newval->op == TOKchar ||
        newval->op == TOKcomplex80)
    {
        return tb->isscalar();
    }
    if (newval->op == TOKnull)
    {
        return tb->ty == Tnull ||
               tb->ty == Tpointer ||
               tb->ty == Tarray ||
               tb->ty == Taarray ||
               tb->ty == Tclass ||
               tb->ty == Tdelegate;
    }

    if (newval->op == TOKstring)
        return true;    // CTFE would directly use the StringExp in AST.
    if (newval->op == TOKarrayliteral)
        return true;    //((ArrayLiteralExp *)newval)->ownedByCtfe;
    if (newval->op == TOKassocarrayliteral)
        return true;    //((AssocArrayLiteralExp *)newval)->ownedByCtfe;
    if (newval->op == TOKstructliteral)
        return true;    //((StructLiteralExp *)newval)->ownedByCtfe;
    if (newval->op == TOKclassreference)
        return true;

    if (newval->op == TOKvector)
        return true;    // vector literal

    if (newval->op == TOKfunction)
        return true;    // function literal or delegate literal
    if (newval->op == TOKdelegate)
    {
        // &struct.func or &clasinst.func
        // &nestedfunc
        Expression *ethis = ((DelegateExp *)newval)->e1;
        return (ethis->op == TOKstructliteral ||
                ethis->op == TOKclassreference ||
                (ethis->op == TOKvar && ((VarExp *)ethis)->var == ((DelegateExp *)newval)->func));
    }
    if (newval->op == TOKsymoff)
    {
        // function pointer, or pointer to static variable
        Declaration *d = ((SymOffExp *)newval)->var;
        return d->isFuncDeclaration() || d->isDataseg();
    }
    if (newval->op == TOKtypeid)
    {
        // always valid
        return true;
    }
    if (newval->op == TOKaddress)
    {
        // e1 should be a CTFE reference
        Expression *e1 = ((AddrExp *)newval)->e1;
        return tb->ty == Tpointer &&
               (((e1->op == TOKstructliteral || e1->op == TOKarrayliteral) && isCtfeValueValid(e1)) ||
                (e1->op == TOKvar) ||
                (e1->op == TOKdotvar && isCtfeReferenceValid(e1)) ||
                (e1->op == TOKindex && isCtfeReferenceValid(e1)) ||
                (e1->op == TOKslice && e1->type->toBasetype()->ty == Tsarray));
    }
    if (newval->op == TOKslice)
    {
        // e1 should be an array aggregate
        SliceExp *se = (SliceExp *)newval;
        assert(se->lwr && se->lwr->op == TOKint64);
        assert(se->upr && se->upr->op == TOKint64);
        return (tb->ty == Tarray ||
                tb->ty == Tsarray) &&
               (se->e1->op == TOKstring ||
                se->e1->op == TOKarrayliteral);
    }

    if (newval->op == TOKvoid)
        return true;    // uninitialized value

    newval->error("CTFE internal error: illegal CTFE value %s", newval->toChars());
    return false;
}

bool isCtfeReferenceValid(Expression *newval)
{
    if (newval->op == TOKthis)
        return true;
    if (newval->op == TOKvar)
    {
        VarDeclaration *v = ((VarExp *)newval)->var->isVarDeclaration();
        assert(v);
        // Must not be a reference to a reference
        return true;
    }
    if (newval->op == TOKindex)
    {
        Expression *eagg = ((IndexExp *)newval)->e1;
        return eagg->op == TOKstring ||
               eagg->op == TOKarrayliteral ||
               eagg->op == TOKassocarrayliteral;
    }
    if (newval->op == TOKdotvar)
    {
        Expression *eagg = ((DotVarExp *)newval)->e1;
        return  (eagg->op == TOKstructliteral || eagg->op == TOKclassreference) &&
                isCtfeValueValid(eagg);
    }

    // Internally a ref variable may directly point a stack memory.
    // e.g. ref int v = 1;
    return isCtfeValueValid(newval);
}

// Used for debugging only
void showCtfeExpr(Expression *e, int level)
{
    for (int i = level; i > 0; --i) printf(" ");
    Expressions *elements = NULL;
    // We need the struct definition to detect block assignment
    StructDeclaration *sd = NULL;
    ClassDeclaration *cd = NULL;
    if (e->op == TOKstructliteral)
    {
        elements = ((StructLiteralExp *)e)->elements;
        sd = ((StructLiteralExp *)e)->sd;
        printf("STRUCT type = %s %p:\n", e->type->toChars(),
            e);
    }
    else if (e->op == TOKclassreference)
    {
        elements = ((ClassReferenceExp *)e)->value->elements;
        cd = ((ClassReferenceExp *)e)->originalClass();
        printf("CLASS type = %s %p:\n", e->type->toChars(),
            ((ClassReferenceExp *)e)->value);
    }
    else if (e->op == TOKarrayliteral)
    {
        elements = ((ArrayLiteralExp *)e)->elements;
        printf("ARRAY LITERAL type=%s %p:\n", e->type->toChars(),
            e);
    }
    else if (e->op == TOKassocarrayliteral)
    {
        printf("AA LITERAL type=%s %p:\n", e->type->toChars(),
            e);
    }
    else if (e->op == TOKstring)
    {
        printf("STRING %s %p\n", e->toChars(),
            ((StringExp *)e)->string);
    }
    else if (e->op == TOKslice)
    {
        printf("SLICE %p: %s\n", e, e->toChars());
        showCtfeExpr(((SliceExp *)e)->e1, level + 1);
    }
    else if (e->op == TOKvar)
    {
        printf("VAR %p %s\n", e, e->toChars());
        VarDeclaration *v = ((VarExp *)e)->var->isVarDeclaration();
        if (v && getValue(v))
            showCtfeExpr(getValue(v), level + 1);
    }
    else if (e->op == TOKaddress)
    {
        // This is potentially recursive. We mustn't try to print the thing we're pointing to.
        printf("POINTER %p to %p: %s\n", e, ((AddrExp *)e)->e1, e->toChars());
    }
    else
        printf("VALUE %p: %s\n", e, e->toChars());

    if (elements)
    {
        size_t fieldsSoFar = 0;
        for (size_t i = 0; i < elements->length; i++)
        {
            Expression *z = NULL;
            VarDeclaration *v = NULL;
            if (i > 15)
            {
                printf("...(total %d elements)\n", (int)elements->length);
                return;
            }
            if (sd)
            {
                v = sd->fields[i];
                z = (*elements)[i];
            }
            else if (cd)
            {
                while (i - fieldsSoFar >= cd->fields.length)
                {
                    fieldsSoFar += cd->fields.length;
                    cd = cd->baseClass;
                    for (int j = level; j > 0; --j) printf(" ");
                    printf(" BASE CLASS: %s\n", cd->toChars());
                }
                v = cd->fields[i - fieldsSoFar];
                assert((elements->length + i) >= (fieldsSoFar + cd->fields.length));
                size_t indx = (elements->length - fieldsSoFar)- cd->fields.length + i;
                assert(indx < elements->length);
                z = (*elements)[indx];
            }
            if (!z)
            {
                for (int j = level; j > 0; --j) printf(" ");
                printf(" void\n");
                continue;
            }

            if (v)
            {
                // If it is a void assignment, use the default initializer
                if ((v->type->ty != z->type->ty) && v->type->ty == Tsarray)
                {
                    for (int j = level; --j; ) printf(" ");
                    printf(" field: block initalized static array\n");
                    continue;
                }
            }
            showCtfeExpr(z, level + 1);
        }
    }
}

/*************************** Void initialization ***************************/

UnionExp voidInitLiteral(Type *t, VarDeclaration *var)
{
    UnionExp ue;
    if (t->ty == Tsarray)
    {
        TypeSArray *tsa = (TypeSArray *)t;
        Expression *elem = voidInitLiteral(tsa->next, var).copy();

        // For aggregate value types (structs, static arrays) we must
        // create an a separate copy for each element.
        bool mustCopy = (elem->op == TOKarrayliteral || elem->op == TOKstructliteral);

        Expressions *elements = new Expressions();
        size_t d = (size_t)tsa->dim->toInteger();
        elements->setDim(d);
        for (size_t i = 0; i < d; i++)
        {
            if (mustCopy && i > 0)
                elem  = copyLiteral(elem).copy();
            (*elements)[i] = elem;
        }
        new(&ue) ArrayLiteralExp(var->loc, tsa, elements);
        ArrayLiteralExp *ae = (ArrayLiteralExp *)ue.exp();
        ae->ownedByCtfe = OWNEDctfe;
    }
    else if (t->ty == Tstruct)
    {
        TypeStruct *ts = (TypeStruct *)t;
        Expressions *exps = new Expressions();
        exps->setDim(ts->sym->fields.length);
        for (size_t i = 0; i < ts->sym->fields.length; i++)
        {
            (*exps)[i] = voidInitLiteral(ts->sym->fields[i]->type, ts->sym->fields[i]).copy();
        }
        new(&ue) StructLiteralExp(var->loc, ts->sym, exps);
        StructLiteralExp *se = (StructLiteralExp *)ue.exp();
        se->type = ts;
        se->ownedByCtfe = OWNEDctfe;
    }
    else
        new(&ue) VoidInitExp(var, t);
    return ue;
}
