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

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

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

/*******************************************
 * Merge function attributes pure, nothrow, @safe, @nogc, and @disable
 */
StorageClass mergeFuncAttrs(StorageClass s1, FuncDeclaration *f)
{
    if (!f)
        return s1;

    StorageClass s2 = (f->storage_class & STCdisable);
    TypeFunction *tf = (TypeFunction *)f->type;
    if (tf->trust == TRUSTsafe)
        s2 |= STCsafe;
    else if (tf->trust == TRUSTsystem)
        s2 |= STCsystem;
    else if (tf->trust == TRUSTtrusted)
        s2 |= STCtrusted;
    if (tf->purity != PUREimpure)
        s2 |= STCpure;
    if (tf->isnothrow)
        s2 |= STCnothrow;
    if (tf->isnogc)
        s2 |= STCnogc;

    StorageClass stc = 0;
    StorageClass sa = s1 & s2;
    StorageClass so = s1 | s2;

    if (so & STCsystem)
        stc |= STCsystem;
    else if (sa & STCtrusted)
        stc |= STCtrusted;
    else if ((so & (STCtrusted | STCsafe)) == (STCtrusted | STCsafe))
        stc |= STCtrusted;
    else if (sa & STCsafe)
        stc |= STCsafe;

    if (sa & STCpure)
        stc |= STCpure;

    if (sa & STCnothrow)
        stc |= STCnothrow;

    if (sa & STCnogc)
        stc |= STCnogc;

    if (so & STCdisable)
        stc |= STCdisable;

    return stc;
}

/*******************************************
 * Check given aggregate actually has an identity opAssign or not.
 * Params:
 *      ad = struct or class
 *      sc = current scope
 * Returns:
 *      if found, returns FuncDeclaration of opAssign, otherwise null
 */
FuncDeclaration *hasIdentityOpAssign(AggregateDeclaration *ad, Scope *sc)
{
    Dsymbol *assign = search_function(ad, Id::assign);
    if (assign)
    {
        /* check identity opAssign exists
         */
        UnionExp er; new(&er) NullExp(ad->loc, ad->type);    // dummy rvalue
        UnionExp el; new(&el) IdentifierExp(ad->loc, Id::p); // dummy lvalue
        el.exp()->type = ad->type;
        Expressions a;
        a.setDim(1);

        unsigned errors = global.startGagging();    // Do not report errors, even if the template opAssign fbody makes it.
        sc = sc->push();
        sc->tinst = NULL;
        sc->minst = NULL;

        a[0] = er.exp();
        FuncDeclaration *f = resolveFuncCall(ad->loc, sc, assign, NULL, ad->type, &a, 1);
        if (!f)
        {
            a[0] = el.exp();
            f = resolveFuncCall(ad->loc, sc, assign, NULL, ad->type, &a, 1);
        }

        sc = sc->pop();
        global.endGagging(errors);

        if (f)
        {
            if (f->errors)
                return NULL;
            ParameterList fparams = f->getParameterList();
            if (fparams.length())
            {
                Parameter *fparam0 = fparams[0];
                if (fparam0->type->toDsymbol(NULL) != ad)
                    f = NULL;
            }
        }
        // BUGS: This detection mechanism cannot find some opAssign-s like follows:
        // struct S { void opAssign(ref immutable S) const; }
        return f;
    }
    return NULL;
}

/*******************************************
 * We need an opAssign for the struct if
 * it has a destructor or a postblit.
 * We need to generate one if a user-specified one does not exist.
 */
bool needOpAssign(StructDeclaration *sd)
{
    //printf("StructDeclaration::needOpAssign() %s\n", sd->toChars());
    if (sd->isUnionDeclaration())
        return false;

    if (sd->hasIdentityAssign)
        goto Lneed;         // because has identity==elaborate opAssign

    if (sd->dtor || sd->postblit)
        goto Lneed;

    /* If any of the fields need an opAssign, then we
     * need it too.
     */
    for (size_t i = 0; i < sd->fields.length; i++)
    {
        VarDeclaration *v = sd->fields[i];
        if (v->storage_class & STCref)
            continue;
        if (v->overlapped)              // if field of a union
            continue;                   // user must handle it themselves
        Type *tv = v->type->baseElemOf();
        if (tv->ty == Tstruct)
        {
            TypeStruct *ts = (TypeStruct *)tv;
            if (ts->sym->isUnionDeclaration())
                continue;
            if (needOpAssign(ts->sym))
                goto Lneed;
        }
    }
    //printf("\tdontneed\n");
    return false;

Lneed:
    //printf("\tneed\n");
    return true;
}

/******************************************
 * Build opAssign for struct.
 *      ref S opAssign(S s) { ... }
 *
 * Note that s will be constructed onto the stack, and probably
 * copy-constructed in caller site.
 *
 * If S has copy copy construction and/or destructor,
 * the body will make bit-wise object swap:
 *          S __swap = this; // bit copy
 *          this = s;        // bit copy
 *          __swap.dtor();
 * Instead of running the destructor on s, run it on tmp instead.
 *
 * Otherwise, the body will make member-wise assignments:
 * Then, the body is:
 *          this.field1 = s.field1;
 *          this.field2 = s.field2;
 *          ...;
 */
FuncDeclaration *buildOpAssign(StructDeclaration *sd, Scope *sc)
{
    if (FuncDeclaration *f = hasIdentityOpAssign(sd, sc))
    {
        sd->hasIdentityAssign = true;
        return f;
    }
    // Even if non-identity opAssign is defined, built-in identity opAssign
    // will be defined.

    if (!needOpAssign(sd))
        return NULL;

    //printf("StructDeclaration::buildOpAssign() %s\n", sd->toChars());
    StorageClass stc = STCsafe | STCnothrow | STCpure | STCnogc;
    Loc declLoc = sd->loc;
    Loc loc = Loc();    // internal code should have no loc to prevent coverage

    // One of our sub-field might have `@disable opAssign` so we need to
    // check for it.
    // In this event, it will be reflected by having `stc` (opAssign's
    // storage class) include `STCdisabled`.
    for (size_t i = 0; i < sd->fields.length; i++)
    {
        VarDeclaration *v = sd->fields[i];
        if (v->storage_class & STCref)
            continue;
        if (v->overlapped)
            continue;
        Type *tv = v->type->baseElemOf();
        if (tv->ty != Tstruct)
            continue;

        StructDeclaration *sdv = ((TypeStruct *)tv)->sym;
        stc = mergeFuncAttrs(stc, hasIdentityOpAssign(sdv, sc));
    }

    if (sd->dtor || sd->postblit)
    {
        if (!sd->type->isAssignable())  // Bugzilla 13044
            return NULL;
        stc = mergeFuncAttrs(stc, sd->dtor);
        if (stc & STCsafe)
            stc = (stc & ~STCsafe) | STCtrusted;
    }

    Parameters *fparams = new Parameters;
    fparams->push(new Parameter(STCnodtor, sd->type, Id::p, NULL, NULL));
    TypeFunction *tf = new TypeFunction(ParameterList(fparams), sd->handleType(), LINKd, stc | STCref);

    FuncDeclaration *fop = new FuncDeclaration(declLoc, Loc(), Id::assign, stc, tf);
    fop->storage_class |= STCinference;
    fop->generated = true;
    Expression *e = NULL;
    if (stc & STCdisable)
    {
    }
    else if (sd->dtor || sd->postblit)
    {
        /* Do swap this and rhs.
         *    __swap = this; this = s; __swap.dtor();
         */
        //printf("\tswap copy\n");
        Identifier *idtmp = Identifier::generateId("__swap");
        VarDeclaration *tmp = NULL;
        AssignExp *ec = NULL;
        if (sd->dtor)
        {
            tmp = new VarDeclaration(loc, sd->type, idtmp, new VoidInitializer(loc));
            tmp->storage_class |= STCnodtor | STCtemp | STCctfe;
            e = new DeclarationExp(loc, tmp);
            ec = new BlitExp(loc, new VarExp(loc, tmp), new ThisExp(loc));
            e = Expression::combine(e, ec);
        }
        ec = new BlitExp(loc, new ThisExp(loc), new IdentifierExp(loc, Id::p));
        e = Expression::combine(e, ec);
        if (sd->dtor)
        {
            /* Instead of running the destructor on s, run it
             * on tmp. This avoids needing to copy tmp back in to s.
             */
            Expression *ec2 = new DotVarExp(loc, new VarExp(loc, tmp), sd->dtor, false);
            ec2 = new CallExp(loc, ec2);
            e = Expression::combine(e, ec2);
        }
    }
    else
    {
        /* Do memberwise copy.
         *
         * If sd is a nested struct, its vthis field assignment is:
         * 1. If it's nested in a class, it's a rebind of class reference.
         * 2. If it's nested in a function or struct, it's an update of void*.
         * In both cases, it will change the parent context.
         */
        //printf("\tmemberwise copy\n");
        for (size_t i = 0; i < sd->fields.length; i++)
        {
            VarDeclaration *v = sd->fields[i];
            // this.v = s.v;
            AssignExp *ec = new AssignExp(loc,
                new DotVarExp(loc, new ThisExp(loc), v),
                new DotVarExp(loc, new IdentifierExp(loc, Id::p), v));
            e = Expression::combine(e, ec);
        }
    }
    if (e)
    {
        Statement *s1 = new ExpStatement(loc, e);

        /* Add:
         *   return this;
         */
        e = new ThisExp(loc);
        Statement *s2 = new ReturnStatement(loc, e);

        fop->fbody = new CompoundStatement(loc, s1, s2);
        tf->isreturn = true;
    }

    sd->members->push(fop);
    fop->addMember(sc, sd);
    sd->hasIdentityAssign = true;        // temporary mark identity assignable

    unsigned errors = global.startGagging();    // Do not report errors, even if the template opAssign fbody makes it.
    Scope *sc2 = sc->push();
    sc2->stc = 0;
    sc2->linkage = LINKd;

    dsymbolSemantic(fop, sc2);
    semantic2(fop, sc2);
    // Bugzilla 15044: fop->semantic3 isn't run here for lazy forward reference resolution.

    sc2->pop();
    if (global.endGagging(errors))    // if errors happened
    {
        // Disable generated opAssign, because some members forbid identity assignment.
        fop->storage_class |= STCdisable;
        fop->fbody = NULL;  // remove fbody which contains the error
    }

    //printf("-StructDeclaration::buildOpAssign() %s, errors = %d\n", sd->toChars(), (fop->storage_class & STCdisable) != 0);

    return fop;
}

/*******************************************
 * We need an opEquals for the struct if
 * any fields has an opEquals.
 * Generate one if a user-specified one does not exist.
 */
bool needOpEquals(StructDeclaration *sd)
{
    //printf("StructDeclaration::needOpEquals() %s\n", sd->toChars());
    if (sd->isUnionDeclaration())
        goto Ldontneed;

    if (sd->hasIdentityEquals)
        goto Lneed;

    /* If any of the fields has an opEquals, then we
     * need it too.
     */
    for (size_t i = 0; i < sd->fields.length; i++)
    {
        VarDeclaration *v = sd->fields[i];
        if (v->storage_class & STCref)
            continue;
        if (v->overlapped)
            continue;
        Type *tv = v->type->toBasetype();
        Type *tvbase = tv->baseElemOf();
        if (tvbase->ty == Tstruct)
        {
            TypeStruct *ts = (TypeStruct *)tvbase;
            if (ts->sym->isUnionDeclaration())
                continue;
            if (needOpEquals(ts->sym))
                goto Lneed;
            if (ts->sym->aliasthis)     // Bugzilla 14806
                goto Lneed;
        }
        if (tv->isfloating())
        {
            // This is necessray for:
            //  1. comparison of +0.0 and -0.0 should be true.
            //  2. comparison of NANs should be false always.
            goto Lneed;
        }
        if (tv->ty == Tarray)
            goto Lneed;
        if (tv->ty == Taarray)
            goto Lneed;
        if (tv->ty == Tclass)
            goto Lneed;
    }
Ldontneed:
    //printf("\tdontneed\n");
    return false;

Lneed:
    //printf("\tneed\n");
    return true;
}

/*******************************************
 * Check given aggregate actually has an identity opEquals or not.
 */
FuncDeclaration *hasIdentityOpEquals(AggregateDeclaration *ad,  Scope *sc)
{
    Dsymbol *eq = search_function(ad, Id::eq);
    if (eq)
    {
        /* check identity opEquals exists
         */
        UnionExp er; new(&er) NullExp(ad->loc, NULL);        // dummy rvalue
        UnionExp el; new(&el) IdentifierExp(ad->loc, Id::p); // dummy lvalue
        Expressions a;
        a.setDim(1);
        for (size_t i = 0; i < 5; i++)
        {
            Type *tthis = NULL;         // dead-store to prevent spurious warning
            switch (i)
            {
                case 0:  tthis = ad->type;                  break;
                case 1:  tthis = ad->type->constOf();       break;
                case 2:  tthis = ad->type->immutableOf();   break;
                case 3:  tthis = ad->type->sharedOf();      break;
                case 4:  tthis = ad->type->sharedConstOf(); break;
                default: assert(0);
            }
            FuncDeclaration *f = NULL;

            unsigned errors = global.startGagging();    // Do not report errors, even if the template opAssign fbody makes it.
            sc = sc->push();
            sc->tinst = NULL;
            sc->minst = NULL;

            for (size_t j = 0; j < 2; j++)
            {
                a[0] = (j == 0 ? er.exp() : el.exp());
                a[0]->type = tthis;
                f = resolveFuncCall(ad->loc, sc, eq, NULL, tthis, &a, 1);
                if (f)
                    break;
            }

            sc = sc->pop();
            global.endGagging(errors);

            if (f)
            {
                if (f->errors)
                    return NULL;
                return f;
            }
        }
    }
    return NULL;
}

/******************************************
 * Build opEquals for struct.
 *      const bool opEquals(const S s) { ... }
 *
 * By fixing bugzilla 3789, opEquals is changed to be never implicitly generated.
 * Now, struct objects comparison s1 == s2 is translated to:
 *      s1.tupleof == s2.tupleof
 * to calculate structural equality. See EqualExp::op_overload.
 */
FuncDeclaration *buildOpEquals(StructDeclaration *sd, Scope *sc)
{
    if (hasIdentityOpEquals(sd, sc))
    {
        sd->hasIdentityEquals = true;
    }
    return NULL;
}

/******************************************
 * Build __xopEquals for TypeInfo_Struct
 *      static bool __xopEquals(ref const S p, ref const S q)
 *      {
 *          return p == q;
 *      }
 *
 * This is called by TypeInfo.equals(p1, p2). If the struct does not support
 * const objects comparison, it will throw "not implemented" Error in runtime.
 */
FuncDeclaration *buildXopEquals(StructDeclaration *sd, Scope *sc)
{
    if (!needOpEquals(sd))
        return NULL;        // bitwise comparison would work

    //printf("StructDeclaration::buildXopEquals() %s\n", sd->toChars());
    if (Dsymbol *eq = search_function(sd, Id::eq))
    {
        if (FuncDeclaration *fd = eq->isFuncDeclaration())
        {
            TypeFunction *tfeqptr;
            {
                Scope scx;

                /* const bool opEquals(ref const S s);
                 */
                Parameters *parameters = new Parameters;
                parameters->push(new Parameter(STCref | STCconst, sd->type, NULL, NULL, NULL));
                tfeqptr = new TypeFunction(ParameterList(parameters), Type::tbool, LINKd);
                tfeqptr->mod = MODconst;
                tfeqptr = (TypeFunction *)typeSemantic(tfeqptr, Loc(), &scx);
            }
            fd = fd->overloadExactMatch(tfeqptr);
            if (fd)
                return fd;
        }
    }

    if (!sd->xerreq)
    {
        // object._xopEquals
        Identifier *id = Identifier::idPool("_xopEquals");
        Expression *e = new IdentifierExp(sd->loc, Id::empty);
        e = new DotIdExp(sd->loc, e, Id::object);
        e = new DotIdExp(sd->loc, e, id);
        e = expressionSemantic(e, sc);
        Dsymbol *s = getDsymbol(e);
        assert(s);
        sd->xerreq = s->isFuncDeclaration();
    }

    Loc declLoc = Loc();    // loc is unnecessary so __xopEquals is never called directly
    Loc loc = Loc();        // loc is unnecessary so errors are gagged

    Parameters *parameters = new Parameters;
    parameters->push(new Parameter(STCref | STCconst, sd->type, Id::p, NULL, NULL));
    parameters->push(new Parameter(STCref | STCconst, sd->type, Id::q, NULL, NULL));
    TypeFunction *tf = new TypeFunction(ParameterList(parameters), Type::tbool, LINKd);

    Identifier *id = Id::xopEquals;
    FuncDeclaration *fop = new FuncDeclaration(declLoc, Loc(), id, STCstatic, tf);
    fop->generated = true;
    Expression *e1 = new IdentifierExp(loc, Id::p);
    Expression *e2 = new IdentifierExp(loc, Id::q);
    Expression *e = new EqualExp(TOKequal, loc, e1, e2);

    fop->fbody = new ReturnStatement(loc, e);

    unsigned errors = global.startGagging();    // Do not report errors
    Scope *sc2 = sc->push();
    sc2->stc = 0;
    sc2->linkage = LINKd;

    dsymbolSemantic(fop, sc2);
    semantic2(fop, sc2);

    sc2->pop();
    if (global.endGagging(errors))    // if errors happened
        fop = sd->xerreq;

    return fop;
}

/******************************************
 * Build __xopCmp for TypeInfo_Struct
 *      static bool __xopCmp(ref const S p, ref const S q)
 *      {
 *          return p.opCmp(q);
 *      }
 *
 * This is called by TypeInfo.compare(p1, p2). If the struct does not support
 * const objects comparison, it will throw "not implemented" Error in runtime.
 */
FuncDeclaration *buildXopCmp(StructDeclaration *sd, Scope *sc)
{
    //printf("StructDeclaration::buildXopCmp() %s\n", toChars());
    if (Dsymbol *cmp = search_function(sd, Id::cmp))
    {
        if (FuncDeclaration *fd = cmp->isFuncDeclaration())
        {
            TypeFunction *tfcmpptr;
            {
                Scope scx;

                /* const int opCmp(ref const S s);
                 */
                Parameters *parameters = new Parameters;
                parameters->push(new Parameter(STCref | STCconst, sd->type, NULL, NULL, NULL));
                tfcmpptr = new TypeFunction(ParameterList(parameters), Type::tint32, LINKd);
                tfcmpptr->mod = MODconst;
                tfcmpptr = (TypeFunction *)typeSemantic(tfcmpptr, Loc(), &scx);
            }
            fd = fd->overloadExactMatch(tfcmpptr);
            if (fd)
                return fd;
        }
    }
    else
    {
        // FIXME: doesn't work for recursive alias this
        return NULL;
    }

    if (!sd->xerrcmp)
    {
        // object._xopCmp
        Identifier *id = Identifier::idPool("_xopCmp");
        Expression *e = new IdentifierExp(sd->loc, Id::empty);
        e = new DotIdExp(sd->loc, e, Id::object);
        e = new DotIdExp(sd->loc, e, id);
        e = expressionSemantic(e, sc);
        Dsymbol *s = getDsymbol(e);
        assert(s);
        sd->xerrcmp = s->isFuncDeclaration();
    }

    Loc declLoc = Loc();    // loc is unnecessary so __xopCmp is never called directly
    Loc loc = Loc();        // loc is unnecessary so errors are gagged

    Parameters *parameters = new Parameters;
    parameters->push(new Parameter(STCref | STCconst, sd->type, Id::p, NULL, NULL));
    parameters->push(new Parameter(STCref | STCconst, sd->type, Id::q, NULL, NULL));
    TypeFunction *tf = new TypeFunction(ParameterList(parameters), Type::tint32, LINKd);

    Identifier *id = Id::xopCmp;
    FuncDeclaration *fop = new FuncDeclaration(declLoc, Loc(), id, STCstatic, tf);
    fop->generated = true;
    Expression *e1 = new IdentifierExp(loc, Id::p);
    Expression *e2 = new IdentifierExp(loc, Id::q);
#ifdef IN_GCC
    Expression *e = new CallExp(loc, new DotIdExp(loc, e1, Id::cmp), e2);
#else
    Expression *e = new CallExp(loc, new DotIdExp(loc, e2, Id::cmp), e1);
#endif

    fop->fbody = new ReturnStatement(loc, e);

    unsigned errors = global.startGagging();    // Do not report errors
    Scope *sc2 = sc->push();
    sc2->stc = 0;
    sc2->linkage = LINKd;

    dsymbolSemantic(fop, sc2);
    semantic2(fop, sc2);

    sc2->pop();
    if (global.endGagging(errors))    // if errors happened
        fop = sd->xerrcmp;

    return fop;
}

/*******************************************
 * We need a toHash for the struct if
 * any fields has a toHash.
 * Generate one if a user-specified one does not exist.
 */
bool needToHash(StructDeclaration *sd)
{
    //printf("StructDeclaration::needToHash() %s\n", sd->toChars());
    if (sd->isUnionDeclaration())
        goto Ldontneed;

    if (sd->xhash)
        goto Lneed;

    /* If any of the fields has an opEquals, then we
     * need it too.
     */
    for (size_t i = 0; i < sd->fields.length; i++)
    {
        VarDeclaration *v = sd->fields[i];
        if (v->storage_class & STCref)
            continue;
        if (v->overlapped)
            continue;
        Type *tv = v->type->toBasetype();
        Type *tvbase = tv->baseElemOf();
        if (tvbase->ty == Tstruct)
        {
            TypeStruct *ts = (TypeStruct *)tvbase;
            if (ts->sym->isUnionDeclaration())
                continue;
            if (needToHash(ts->sym))
                goto Lneed;
            if (ts->sym->aliasthis)     // Bugzilla 14948
                goto Lneed;
        }
        if (tv->isfloating())
        {
            // This is necessray for:
            //  1. comparison of +0.0 and -0.0 should be true.
            goto Lneed;
        }
        if (tv->ty == Tarray)
            goto Lneed;
        if (tv->ty == Taarray)
            goto Lneed;
        if (tv->ty == Tclass)
            goto Lneed;
    }
Ldontneed:
    //printf("\tdontneed\n");
    return false;

Lneed:
    //printf("\tneed\n");
    return true;
}

/******************************************
 * Build __xtoHash for non-bitwise hashing
 *      static hash_t xtoHash(ref const S p) nothrow @trusted;
 */
FuncDeclaration *buildXtoHash(StructDeclaration *sd, Scope *sc)
{
    if (Dsymbol *s = search_function(sd, Id::tohash))
    {
        static TypeFunction *tftohash;
        if (!tftohash)
        {
            tftohash = new TypeFunction(ParameterList(), Type::thash_t, LINKd);
            tftohash->mod = MODconst;
            tftohash = (TypeFunction *)tftohash->merge();
        }

        if (FuncDeclaration *fd = s->isFuncDeclaration())
        {
            fd = fd->overloadExactMatch(tftohash);
            if (fd)
                return fd;
        }
    }

    if (!needToHash(sd))
        return NULL;

    //printf("StructDeclaration::buildXtoHash() %s\n", sd->toPrettyChars());
    Loc declLoc = Loc();    // loc is unnecessary so __xtoHash is never called directly
    Loc loc = Loc();        // internal code should have no loc to prevent coverage

    Parameters *parameters = new Parameters();
    parameters->push(new Parameter(STCref | STCconst, sd->type, Id::p, NULL, NULL));
    TypeFunction *tf = new TypeFunction(ParameterList(parameters), Type::thash_t,
                                        LINKd, STCnothrow | STCtrusted);

    Identifier *id = Id::xtoHash;
    FuncDeclaration *fop = new FuncDeclaration(declLoc, Loc(), id, STCstatic, tf);
    fop->generated = true;

    /* Do memberwise hashing.
     *
     * If sd is a nested struct, and if it's nested in a class, the calculated
     * hash value will also contain the result of parent class's toHash().
     */
    const char *code =
        "size_t h = 0;"
        "foreach (i, T; typeof(p.tupleof))"
        "    h += typeid(T).getHash(cast(const void*)&p.tupleof[i]);"
        "return h;";
    fop->fbody = new CompileStatement(loc, new StringExp(loc, const_cast<char *>(code)));

    Scope *sc2 = sc->push();
    sc2->stc = 0;
    sc2->linkage = LINKd;

    dsymbolSemantic(fop, sc2);
    semantic2(fop, sc2);

    sc2->pop();

    //printf("%s fop = %s %s\n", sd->toChars(), fop->toChars(), fop->type->toChars());
    return fop;
}

/*****************************************
 * Create inclusive postblit for struct by aggregating
 * all the postblits in postblits[] with the postblits for
 * all the members.
 * Note the close similarity with AggregateDeclaration::buildDtor(),
 * and the ordering changes (runs forward instead of backwards).
 */
FuncDeclaration *buildPostBlit(StructDeclaration *sd, Scope *sc)
{
    //printf("StructDeclaration::buildPostBlit() %s\n", sd->toChars());
    if (sd->isUnionDeclaration())
        return NULL;

    StorageClass stc = STCsafe | STCnothrow | STCpure | STCnogc;
    Loc declLoc = sd->postblits.length ? sd->postblits[0]->loc : sd->loc;
    Loc loc = Loc();    // internal code should have no loc to prevent coverage

    for (size_t i = 0; i < sd->postblits.length; i++)
    {
        stc |= sd->postblits[i]->storage_class & STCdisable;
    }

    Statements *a = new Statements();
    for (size_t i = 0; i < sd->fields.length && !(stc & STCdisable); i++)
    {
        VarDeclaration *v = sd->fields[i];
        if (v->storage_class & STCref)
            continue;
        if (v->overlapped)
            continue;
        Type *tv = v->type->baseElemOf();
        if (tv->ty != Tstruct)
            continue;
        StructDeclaration *sdv = ((TypeStruct *)tv)->sym;
        if (!sdv->postblit)
            continue;
        assert(!sdv->isUnionDeclaration());
        sdv->postblit->functionSemantic();

        stc = mergeFuncAttrs(stc, sdv->postblit);
        stc = mergeFuncAttrs(stc, sdv->dtor);
        if (stc & STCdisable)
        {
            a->setDim(0);
            break;
        }

        Expression *ex = NULL;
        tv = v->type->toBasetype();
        if (tv->ty == Tstruct)
        {
            // this.v.__xpostblit()

            ex = new ThisExp(loc);
            ex = new DotVarExp(loc, ex, v);

            // This is a hack so we can call postblits on const/immutable objects.
            ex = new AddrExp(loc, ex);
            ex = new CastExp(loc, ex, v->type->mutableOf()->pointerTo());
            ex = new PtrExp(loc, ex);
            if (stc & STCsafe)
                stc = (stc & ~STCsafe) | STCtrusted;

            ex = new DotVarExp(loc, ex, sdv->postblit, false);
            ex = new CallExp(loc, ex);
        }
        else
        {
            // __ArrayPostblit((cast(S*)this.v.ptr)[0 .. n])

            uinteger_t n = tv->numberOfElems(loc);
            if (n == 0)
                continue;

            ex = new ThisExp(loc);
            ex = new DotVarExp(loc, ex, v);

            // This is a hack so we can call postblits on const/immutable objects.
            ex = new DotIdExp(loc, ex, Id::ptr);
            ex = new CastExp(loc, ex, sdv->type->pointerTo());
            if (stc & STCsafe)
                stc = (stc & ~STCsafe) | STCtrusted;

            ex = new SliceExp(loc, ex, new IntegerExp(loc, 0, Type::tsize_t),
                                       new IntegerExp(loc, n, Type::tsize_t));
            // Prevent redundant bounds check
            ((SliceExp *)ex)->upperIsInBounds = true;
            ((SliceExp *)ex)->lowerIsLessThanUpper = true;

            ex = new CallExp(loc, new IdentifierExp(loc, Id::__ArrayPostblit), ex);
        }
        a->push(new ExpStatement(loc, ex)); // combine in forward order

        /* Bugzilla 10972: When the following field postblit calls fail,
         * this field should be destructed for Exception Safety.
         */
        if (!sdv->dtor)
            continue;
        sdv->dtor->functionSemantic();

        tv = v->type->toBasetype();
        if (v->type->toBasetype()->ty == Tstruct)
        {
            // this.v.__xdtor()

            ex = new ThisExp(loc);
            ex = new DotVarExp(loc, ex, v);

            // This is a hack so we can call destructors on const/immutable objects.
            ex = new AddrExp(loc, ex);
            ex = new CastExp(loc, ex, v->type->mutableOf()->pointerTo());
            ex = new PtrExp(loc, ex);
            if (stc & STCsafe)
                stc = (stc & ~STCsafe) | STCtrusted;

            ex = new DotVarExp(loc, ex, sdv->dtor, false);
            ex = new CallExp(loc, ex);
        }
        else
        {
            // __ArrayDtor((cast(S*)this.v.ptr)[0 .. n])

            uinteger_t n = tv->numberOfElems(loc);
            //if (n == 0)
            //    continue;

            ex = new ThisExp(loc);
            ex = new DotVarExp(loc, ex, v);

            // This is a hack so we can call destructors on const/immutable objects.
            ex = new DotIdExp(loc, ex, Id::ptr);
            ex = new CastExp(loc, ex, sdv->type->pointerTo());
            if (stc & STCsafe)
                stc = (stc & ~STCsafe) | STCtrusted;

            ex = new SliceExp(loc, ex, new IntegerExp(loc, 0, Type::tsize_t),
                                       new IntegerExp(loc, n, Type::tsize_t));
            // Prevent redundant bounds check
            ((SliceExp *)ex)->upperIsInBounds = true;
            ((SliceExp *)ex)->lowerIsLessThanUpper = true;

            ex = new CallExp(loc, new IdentifierExp(loc, Id::__ArrayDtor), ex);
        }
        a->push(new ScopeGuardStatement(loc, TOKon_scope_failure, new ExpStatement(loc, ex)));
    }

    // Build our own "postblit" which executes a, but only if needed.
    if (a->length || (stc & STCdisable))
    {
        //printf("Building __fieldPostBlit()\n");
        PostBlitDeclaration *dd = new PostBlitDeclaration(declLoc, Loc(), stc, Id::__fieldPostblit);
        dd->generated = true;
        dd->storage_class |= STCinference;
        dd->fbody = (stc & STCdisable) ? NULL : new CompoundStatement(loc, a);
        sd->postblits.shift(dd);
        sd->members->push(dd);
        dsymbolSemantic(dd, sc);
    }

    FuncDeclaration *xpostblit = NULL;
    switch (sd->postblits.length)
    {
        case 0:
            break;

        case 1:
            xpostblit = sd->postblits[0];
            break;

        default:
            Expression *e = NULL;
            stc = STCsafe | STCnothrow | STCpure | STCnogc;
            for (size_t i = 0; i < sd->postblits.length; i++)
            {
                FuncDeclaration *fd = sd->postblits[i];
                stc = mergeFuncAttrs(stc, fd);
                if (stc & STCdisable)
                {
                    e = NULL;
                    break;
                }
                Expression *ex = new ThisExp(loc);
                ex = new DotVarExp(loc, ex, fd, false);
                ex = new CallExp(loc, ex);
                e = Expression::combine(e, ex);
            }
            PostBlitDeclaration *dd = new PostBlitDeclaration(declLoc, Loc(), stc, Id::__aggrPostblit);
            dd->storage_class |= STCinference;
            dd->fbody = new ExpStatement(loc, e);
            sd->members->push(dd);
            dsymbolSemantic(dd, sc);
            xpostblit = dd;
            break;
    }
    // Add an __xpostblit alias to make the inclusive postblit accessible
    if (xpostblit)
    {
        AliasDeclaration *alias = new AliasDeclaration(Loc(), Id::__xpostblit, xpostblit);
        dsymbolSemantic(alias, sc);
        sd->members->push(alias);
        alias->addMember(sc, sd); // add to symbol table
    }
    return xpostblit;
}

/*****************************************
 * Create inclusive destructor for struct/class by aggregating
 * all the destructors in dtors[] with the destructors for
 * all the members.
 * Note the close similarity with StructDeclaration::buildPostBlit(),
 * and the ordering changes (runs backward instead of forwards).
 */
FuncDeclaration *buildDtor(AggregateDeclaration *ad, Scope *sc)
{
    //printf("AggregateDeclaration::buildDtor() %s\n", ad->toChars());
    if (ad->isUnionDeclaration())
        return NULL;

    StorageClass stc = STCsafe | STCnothrow | STCpure | STCnogc;
    Loc declLoc = ad->dtors.length ? ad->dtors[0]->loc : ad->loc;
    Loc loc = Loc();    // internal code should have no loc to prevent coverage

    Expression *e = NULL;
    for (size_t i = 0; i < ad->fields.length; i++)
    {
        VarDeclaration *v = ad->fields[i];
        if (v->storage_class & STCref)
            continue;
        if (v->overlapped)
            continue;
        Type *tv = v->type->baseElemOf();
        if (tv->ty != Tstruct)
            continue;
        StructDeclaration *sdv = ((TypeStruct *)tv)->sym;
        if (!sdv->dtor)
            continue;
        sdv->dtor->functionSemantic();

        stc = mergeFuncAttrs(stc, sdv->dtor);
        if (stc & STCdisable)
        {
            e = NULL;
            break;
        }

        Expression *ex = NULL;
        tv = v->type->toBasetype();
        if (tv->ty == Tstruct)
        {
            // this.v.__xdtor()

            ex = new ThisExp(loc);
            ex = new DotVarExp(loc, ex, v);

            // This is a hack so we can call destructors on const/immutable objects.
            ex = new AddrExp(loc, ex);
            ex = new CastExp(loc, ex, v->type->mutableOf()->pointerTo());
            ex = new PtrExp(loc, ex);
            if (stc & STCsafe)
                stc = (stc & ~STCsafe) | STCtrusted;

            ex = new DotVarExp(loc, ex, sdv->dtor, false);
            ex = new CallExp(loc, ex);
        }
        else
        {
            // __ArrayDtor((cast(S*)this.v.ptr)[0 .. n])

            uinteger_t n = tv->numberOfElems(loc);
            if (n == 0)
                continue;

            ex = new ThisExp(loc);
            ex = new DotVarExp(loc, ex, v);

            // This is a hack so we can call destructors on const/immutable objects.
            ex = new DotIdExp(loc, ex, Id::ptr);
            ex = new CastExp(loc, ex, sdv->type->pointerTo());
            if (stc & STCsafe)
                stc = (stc & ~STCsafe) | STCtrusted;

            ex = new SliceExp(loc, ex, new IntegerExp(loc, 0, Type::tsize_t),
                                       new IntegerExp(loc, n, Type::tsize_t));
            // Prevent redundant bounds check
            ((SliceExp *)ex)->upperIsInBounds = true;
            ((SliceExp *)ex)->lowerIsLessThanUpper = true;

            ex = new CallExp(loc, new IdentifierExp(loc, Id::__ArrayDtor), ex);
        }
        e = Expression::combine(ex, e); // combine in reverse order
    }

    /* Build our own "destructor" which executes e
     */
    if (e || (stc & STCdisable))
    {
        //printf("Building __fieldDtor()\n");
        DtorDeclaration *dd = new DtorDeclaration(declLoc, Loc(), stc, Id::__fieldDtor);
        dd->generated = true;
        dd->storage_class |= STCinference;
        dd->fbody = new ExpStatement(loc, e);
        ad->dtors.shift(dd);
        ad->members->push(dd);
        dsymbolSemantic(dd, sc);
    }

    FuncDeclaration *xdtor = NULL;
    switch (ad->dtors.length)
    {
        case 0:
            break;

        case 1:
            xdtor = ad->dtors[0];
            break;

        default:
            e = NULL;
            stc = STCsafe | STCnothrow | STCpure | STCnogc;
            for (size_t i = 0; i < ad->dtors.length; i++)
            {
                FuncDeclaration *fd = ad->dtors[i];
                stc = mergeFuncAttrs(stc, fd);
                if (stc & STCdisable)
                {
                    e = NULL;
                    break;
                }
                Expression *ex = new ThisExp(loc);
                ex = new DotVarExp(loc, ex, fd, false);
                ex = new CallExp(loc, ex);
                e = Expression::combine(ex, e);
            }
            DtorDeclaration *dd = new DtorDeclaration(declLoc, Loc(), stc, Id::__aggrDtor);
            dd->generated = true;
            dd->storage_class |= STCinference;
            dd->fbody = new ExpStatement(loc, e);
            ad->members->push(dd);
            dsymbolSemantic(dd, sc);
            xdtor = dd;
            break;
    }
    // Add an __xdtor alias to make the inclusive dtor accessible
    if (xdtor)
    {
        AliasDeclaration *alias = new AliasDeclaration(Loc(), Id::__xdtor, xdtor);
        dsymbolSemantic(alias, sc);
        ad->members->push(alias);
        alias->addMember(sc, ad); // add to symbol table
    }
    return xdtor;
}

/******************************************
 * Create inclusive invariant for struct/class by aggregating
 * all the invariants in invs[].
 *      void __invariant() const [pure nothrow @trusted]
 *      {
 *          invs[0](), invs[1](), ...;
 *      }
 */
FuncDeclaration *buildInv(AggregateDeclaration *ad, Scope *sc)
{
    StorageClass stc = STCsafe | STCnothrow | STCpure | STCnogc;
    Loc declLoc = ad->loc;
    Loc loc = Loc();    // internal code should have no loc to prevent coverage

    switch (ad->invs.length)
    {
        case 0:
            return NULL;

        case 1:
            // Don't return invs[0] so it has uniquely generated name.
            /* fall through */

        default:
            Expression *e = NULL;
            StorageClass stcx = 0;
            for (size_t i = 0; i < ad->invs.length; i++)
            {
                stc = mergeFuncAttrs(stc, ad->invs[i]);
                if (stc & STCdisable)
                {
                    // What should do?
                }
                StorageClass stcy = (ad->invs[i]->storage_class & STCsynchronized) |
                                    (ad->invs[i]->type->mod & MODshared ? STCshared : 0);
                if (i == 0)
                    stcx = stcy;
                else if (stcx ^ stcy)
                {
            #if 1   // currently rejects
                    ad->error(ad->invs[i]->loc, "mixing invariants with shared/synchronized differene is not supported");
                    e = NULL;
                    break;
            #endif
                }
                e = Expression::combine(e, new CallExp(loc, new VarExp(loc, ad->invs[i], false)));
            }
            InvariantDeclaration *inv;
            inv = new InvariantDeclaration(declLoc, Loc(), stc | stcx, Id::classInvariant);
            inv->fbody = new ExpStatement(loc, e);
            ad->members->push(inv);
            dsymbolSemantic(inv, sc);
            return inv;
    }
}
