/**
 * Builds struct member functions if needed and not defined by the user.
 * Includes `opEquals`, `opAssign`, post blit, copy constructor and destructor.
 *
 * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
 * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
 * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
 * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/clone.d, _clone.d)
 * Documentation:  https://dlang.org/phobos/dmd_clone.html
 * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/clone.d
 */

module dmd.clone;

import core.stdc.stdio;
import dmd.aggregate;
import dmd.arraytypes;
import dmd.astenums;
import dmd.dclass;
import dmd.declaration;
import dmd.dscope;
import dmd.dstruct;
import dmd.dsymbol;
import dmd.dsymbolsem;
import dmd.dtemplate;
import dmd.errors;
import dmd.expression;
import dmd.expressionsem;
import dmd.func;
import dmd.globals;
import dmd.id;
import dmd.identifier;
import dmd.init;
import dmd.location;
import dmd.mtype;
import dmd.opover;
import dmd.semantic2;
import dmd.semantic3;
import dmd.statement;
import dmd.target;
import dmd.typesem;
import dmd.tokens;

/*******************************************
 * Merge function attributes pure, nothrow, @safe, @nogc, and @disable
 * from f into s1.
 * Params:
 *      s1 = storage class to merge into
 *      f = function
 * Returns:
 *      merged storage class
 */
StorageClass mergeFuncAttrs(StorageClass s1, const FuncDeclaration f) pure
{
    if (!f)
        return s1;
    StorageClass s2 = (f.storage_class & STC.disable);

    TypeFunction tf = cast(TypeFunction)f.type;
    if (tf.trust == TRUST.safe)
        s2 |= STC.safe;
    else if (tf.trust == TRUST.system)
        s2 |= STC.system;
    else if (tf.trust == TRUST.trusted)
        s2 |= STC.trusted;

    if (tf.purity != PURE.impure)
        s2 |= STC.pure_;
    if (tf.isnothrow)
        s2 |= STC.nothrow_;
    if (tf.isnogc)
        s2 |= STC.nogc;

    const sa = s1 & s2;
    const so = s1 | s2;

    StorageClass stc = (sa & (STC.pure_ | STC.nothrow_ | STC.nogc)) | (so & STC.disable);

    if (so & STC.system)
        stc |= STC.system;
    else if (sa & STC.trusted)
        stc |= STC.trusted;
    else if ((so & (STC.trusted | STC.safe)) == (STC.trusted | STC.safe))
        stc |= STC.trusted;
    else if (sa & STC.safe)
        stc |= STC.safe;

    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
         */
        scope er = new NullExp(ad.loc, ad.type);    // dummy rvalue
        scope el = new IdentifierExp(ad.loc, Id.p); // dummy lvalue
        el.type = ad.type;
        auto a = Expressions(1);
        const 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;
        auto f = resolveFuncCall(ad.loc, sc, assign, null, ad.type, ArgumentList(&a), FuncResolveFlag.quiet);
        if (!f)
        {
            a[0] = el;
            f = resolveFuncCall(ad.loc, sc, assign, null, ad.type, ArgumentList(&a), FuncResolveFlag.quiet);
        }

        sc = sc.pop();
        global.endGagging(errors);
        if (f)
        {
            if (f.errors)
                return null;
            auto fparams = f.getParameterList();
            if (fparams.length)
            {
                auto 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.
 */
private bool needOpAssign(StructDeclaration sd)
{
    //printf("StructDeclaration::needOpAssign() %s\n", sd.toChars());

    static bool isNeeded()
    {
        //printf("\tneed\n");
        return true;
    }

    if (sd.isUnionDeclaration())
        return !isNeeded();

    if (sd.hasIdentityAssign || // because has identity==elaborate opAssign
        sd.dtor ||
        sd.postblit)
        return isNeeded();

    /* If any of the fields need an opAssign, then we
     * need it too.
     */
    foreach (v; sd.fields)
    {
        if (v.storage_class & STC.ref_)
            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 = cast(TypeStruct)tv;
            if (ts.sym.isUnionDeclaration())
                continue;
            if (needOpAssign(ts.sym))
                return isNeeded();
        }
    }
    return !isNeeded();
}

/******************************************
 * Build opAssign for a `struct`.
 *
 * The generated `opAssign` function has the following signature:
 *---
 *ref S opAssign(S s)    // S is the name of the `struct`
 *---
 *
 * The opAssign function will be built for a struct `S` if the
 * following constraints are met:
 *
 * 1. `S` does not have an identity `opAssign` defined.
 *
 * 2. `S` has at least one of the following members: a postblit (user-defined or
 * generated for fields that have a defined postblit), a destructor
 * (user-defined or generated for fields that have a defined destructor)
 * or at least one field that has a defined `opAssign`.
 *
 * 3. `S` does not have any non-mutable fields.
 *
 * If `S` has a disabled destructor or at least one field that has a disabled
 * `opAssign`, `S.opAssign` is going to be generated, but marked with `@disable`
 *
 * If `S` defines a destructor, the generated code for `opAssign` is:
 *
 *---
 *S __swap = void;
 *__swap = this;   // bit copy
 *this = s;        // bit copy
 *__swap.dtor();
 *---
 *
 * Otherwise, if `S` defines a postblit, the generated code for `opAssign` is:
 *
 *---
 *this = s;
 *---
 *
 * Note that the parameter to the generated `opAssign` is passed by value, which means
 * that the postblit is going to be called (if it is defined) in both  of the above
 * situations before entering the body of `opAssign`. The assignments in the above generated
 * function bodies are blit expressions, so they can be regarded as `memcpy`s
 * (`opAssign` is not called as this will result in an infinite recursion; the postblit
 * is not called because it has already been called when the parameter was passed by value).
 *
 * If `S` does not have a postblit or a destructor, but contains at least one field that defines
 * an `opAssign` function (which is not disabled), then the body will make member-wise
 * assignments:
 *
 *---
 *this.field1 = s.field1;
 *this.field2 = s.field2;
 *...;
 *---
 *
 * In this situation, the assignemnts are actual assign expressions (`opAssign` is used
 * if defined).
 *
 * References:
 *      https://dlang.org/spec/struct.html#assign-overload
 * Params:
 *      sd = struct to generate opAssign for
 *      sc = context
 * Returns:
 *      generated `opAssign` function
 */
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 = STC.safe | STC.nothrow_ | STC.pure_ | STC.nogc;
    Loc declLoc = sd.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 `STC.disabled`.
    foreach (v; sd.fields)
    {
        if (v.storage_class & STC.ref_)
            continue;
        if (v.overlapped)
            continue;
        Type tv = v.type.baseElemOf();
        if (tv.ty != Tstruct)
            continue;
        StructDeclaration sdv = (cast(TypeStruct)tv).sym;
        stc = mergeFuncAttrs(stc, hasIdentityOpAssign(sdv, sc));
    }

    if (sd.dtor || sd.postblit)
    {
        // if the type is not assignable, we cannot generate opAssign
        if (!sd.type.isAssignable()) // https://issues.dlang.org/show_bug.cgi?id=13044
            return null;
        stc = mergeFuncAttrs(stc, sd.dtor);
        if (stc & STC.safe)
            stc = (stc & ~STC.safe) | STC.trusted;
    }

    auto fparams = new Parameters();
    fparams.push(new Parameter(STC.nodtor, sd.type, Id.p, null, null));
    auto tf = new TypeFunction(ParameterList(fparams), sd.handleType(), LINK.d, stc | STC.ref_);
    auto fop = new FuncDeclaration(declLoc, Loc.initial, Id.assign, stc, tf);
    fop.storage_class |= STC.inference;
    fop.isGenerated = true;
    Expression e;
    if (stc & STC.disable)
    {
        e = null;
    }
    /* Do swap this and rhs.
     *    __swap = this; this = s; __swap.dtor();
     */
    else if (sd.dtor)
    {
        //printf("\tswap copy\n");
        TypeFunction tdtor = cast(TypeFunction)sd.dtor.type;
        assert(tdtor.ty == Tfunction);

        auto idswap = Identifier.generateId("__swap");
        auto swap = new VarDeclaration(loc, sd.type, idswap, new VoidInitializer(loc));
        swap.storage_class |= STC.nodtor | STC.temp | STC.ctfe;
        if (tdtor.isScopeQual)
            swap.storage_class |= STC.scope_;
        auto e1 = new DeclarationExp(loc, swap);

        auto e2 = new BlitExp(loc, new VarExp(loc, swap), new ThisExp(loc));
        auto e3 = new BlitExp(loc, new ThisExp(loc), new IdentifierExp(loc, Id.p));

        /* Instead of running the destructor on s, run it
         * on swap. This avoids needing to copy swap back in to s.
         */
        auto e4 = new CallExp(loc, new DotVarExp(loc, new VarExp(loc, swap), sd.dtor, false));

        e = Expression.combine(e1, e2, e3, e4);
    }
    /* postblit was called when the value was passed to opAssign, we just need to blit the result */
    else if (sd.postblit)
    {
        e = new BlitExp(loc, new ThisExp(loc), new IdentifierExp(loc, Id.p));
        sd.hasBlitAssign = true;
    }
    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");
        e = null;
        foreach (v; sd.fields)
        {
            // this.v = s.v;
            auto 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;
         */
        auto er = new ThisExp(loc);
        Statement s2 = new ReturnStatement(loc, er);
        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
    const errors = global.startGagging(); // Do not report errors, even if the template opAssign fbody makes it.
    Scope* sc2 = sc.push();
    sc2.stc = 0;
    sc2.linkage = LINK.d;
    fop.dsymbolSemantic(sc2);
    fop.semantic2(sc2);
    // https://issues.dlang.org/show_bug.cgi?id=15044
    //semantic3(fop, sc2); // 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 |= STC.disable;
        fop.fbody = null; // remove fbody which contains the error
    }

    //printf("-StructDeclaration::buildOpAssign() %s, errors = %d\n", sd.toChars(), (fop.storage_class & STC.disable) != 0);
    //printf("fop.type: %s\n", fop.type.toPrettyChars());
    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())
    {
        /* If a union has only one field, treat it like a struct
         */
        if (sd.fields.length != 1)
            goto Ldontneed;
    }
    if (sd.hasIdentityEquals)
        goto Lneed;
    /* If any of the fields has an opEquals, then we
     * need it too.
     */
    foreach (VarDeclaration v; sd.fields)
    {
        if (v.storage_class & STC.ref_)
            continue;
        if (v.overlapped)
            continue;
        Type tv = v.type.toBasetype();
        auto tvbase = tv.baseElemOf();
        if (tvbase.ty == Tstruct)
        {
            TypeStruct ts = cast(TypeStruct)tvbase;
            if (ts.sym.isUnionDeclaration() && ts.sym.fields.length != 1)
                continue;
            if (needOpEquals(ts.sym))
                goto Lneed;
        }
        if (tvbase.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 (tvbase.ty == Tarray)
            goto Lneed;
        if (tvbase.ty == Taarray)
            goto Lneed;
        if (tvbase.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.
 */
private FuncDeclaration hasIdentityOpEquals(AggregateDeclaration ad, Scope* sc)
{
    FuncDeclaration f;
    if (Dsymbol eq = search_function(ad, Id.eq))
    {
        /* check identity opEquals exists
         */
        scope er = new NullExp(ad.loc, null); // dummy rvalue
        scope el = new IdentifierExp(ad.loc, Id.p); // dummy lvalue
        auto a = Expressions(1);

        bool hasIt(Type tthis)
        {
            const errors = global.startGagging(); // Do not report errors, even if the template opAssign fbody makes it
            sc = sc.push();
            sc.tinst = null;
            sc.minst = null;

            FuncDeclaration rfc(Expression e)
            {
                a[0] = e;
                a[0].type = tthis;
                return resolveFuncCall(ad.loc, sc, eq, null, tthis, ArgumentList(&a), FuncResolveFlag.quiet);
            }

            f = rfc(er);
            if (!f)
                f = rfc(el);

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

            return f !is null;
        }

        if (hasIt(ad.type)               ||
            hasIt(ad.type.constOf())     ||
            hasIt(ad.type.immutableOf()) ||
            hasIt(ad.type.sharedOf())    ||
            hasIt(ad.type.sharedConstOf()))
        {
            if (f.errors)
                return null;
        }
    }
    return f;
}

/******************************************
 * Build opEquals for struct.
 *      const bool opEquals(const S s) { ... }
 *
 * By fixing https://issues.dlang.org/show_bug.cgi?id=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
 *      bool __xopEquals(ref const S p) const
 *      {
 *          return this == p;
 *      }
 *
 * 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);
                 */
                auto parameters = new Parameters();
                parameters.push(new Parameter(STC.ref_ | STC.const_, sd.type, null, null, null));
                tfeqptr = new TypeFunction(ParameterList(parameters), Type.tbool, LINK.d);
                tfeqptr.mod = MODFlags.const_;
                tfeqptr = cast(TypeFunction)tfeqptr.typeSemantic(Loc.initial, &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 = e.expressionSemantic(sc);
        if (!e.isErrorExp())
        {
            Dsymbol s = getDsymbol(e);
            assert(s);
            sd.xerreq = s.isFuncDeclaration();
        }
    }
    Loc declLoc; // loc is unnecessary so __xopEquals is never called directly
    Loc loc; // loc is unnecessary so errors are gagged
    auto parameters = new Parameters();
    parameters.push(new Parameter(STC.ref_ | STC.const_, sd.type, Id.p, null, null));
    auto tf = new TypeFunction(ParameterList(parameters), Type.tbool, LINK.d, STC.const_);
    tf = tf.addSTC(STC.const_).toTypeFunction();
    Identifier id = Id.xopEquals;
    auto fop = new FuncDeclaration(declLoc, Loc.initial, id, 0, tf);
    fop.isGenerated = true;
    fop.parent = sd;
    Expression e1 = new IdentifierExp(loc, Id.This);
    Expression e2 = new IdentifierExp(loc, Id.p);
    Expression e = new EqualExp(EXP.equal, loc, e1, e2);
    fop.fbody = new ReturnStatement(loc, e);
    uint errors = global.startGagging(); // Do not report errors
    Scope* sc2 = sc.push();
    sc2.stc = 0;
    sc2.linkage = LINK.d;
    fop.dsymbolSemantic(sc2);
    fop.semantic2(sc2);
    sc2.pop();
    if (global.endGagging(errors)) // if errors happened
        fop = sd.xerreq;
    return fop;
}

/******************************************
 * Build __xopCmp for TypeInfo_Struct
 *      int __xopCmp(ref const S p) const
 *      {
 *          return this.opCmp(p);
 *      }
 *
 * 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);
                 */
                auto parameters = new Parameters();
                parameters.push(new Parameter(STC.ref_ | STC.const_, sd.type, null, null, null));
                tfcmpptr = new TypeFunction(ParameterList(parameters), Type.tint32, LINK.d);
                tfcmpptr.mod = MODFlags.const_;
                tfcmpptr = cast(TypeFunction)tfcmpptr.typeSemantic(Loc.initial, &scx);
            }
            fd = fd.overloadExactMatch(tfcmpptr);
            if (fd)
                return fd;
        }
    }
    else
    {
        version (none) // FIXME: doesn't work for recursive alias this
        {
            /* Check opCmp member exists.
             * Consider 'alias this', but except opDispatch.
             */
            Expression e = new DsymbolExp(sd.loc, sd);
            e = new DotIdExp(sd.loc, e, Id.cmp);
            Scope* sc2 = sc.push();
            e = e.trySemantic(sc2);
            sc2.pop();
            if (e)
            {
                Dsymbol s = null;
                switch (e.op)
                {
                case EXP.overloadSet:
                    s = e.isOverExp().vars;
                    break;
                case EXP.scope_:
                    s = e.isScopeExp().sds;
                    break;
                case EXP.variable:
                    s = e.isVarExp().var;
                    break;
                default:
                    break;
                }
                if (!s || s.ident != Id.cmp)
                    e = null; // there's no valid member 'opCmp'
            }
            if (!e)
                return null; // bitwise comparison would work
            /* Essentially, a struct which does not define opCmp is not comparable.
             * At this time, typeid(S).compare might be correct that throwing "not implement" Error.
             * But implementing it would break existing code, such as:
             *
             * struct S { int value; }  // no opCmp
             * int[S] aa;   // Currently AA key uses bitwise comparison
             *              // (It's default behavior of TypeInfo_Strust.compare).
             *
             * Not sure we should fix this inconsistency, so just keep current behavior.
             */
        }
        else
        {
            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 = e.expressionSemantic(sc);
        if (!e.isErrorExp())
        {
            Dsymbol s = getDsymbol(e);
            assert(s);
            sd.xerrcmp = s.isFuncDeclaration();
        }
    }
    Loc declLoc; // loc is unnecessary so __xopCmp is never called directly
    Loc loc; // loc is unnecessary so errors are gagged
    auto parameters = new Parameters();
    parameters.push(new Parameter(STC.ref_ | STC.const_, sd.type, Id.p, null, null));
    auto tf = new TypeFunction(ParameterList(parameters), Type.tint32, LINK.d, STC.const_);
    tf = tf.addSTC(STC.const_).toTypeFunction();
    Identifier id = Id.xopCmp;
    auto fop = new FuncDeclaration(declLoc, Loc.initial, id, 0, tf);
    fop.isGenerated = true;
    fop.parent = sd;
    Expression e1 = new IdentifierExp(loc, Id.This);
    Expression e2 = new IdentifierExp(loc, Id.p);
    Expression e = new CallExp(loc, new DotIdExp(loc, e1, Id.cmp), e2);
    fop.fbody = new ReturnStatement(loc, e);
    uint errors = global.startGagging(); // Do not report errors
    Scope* sc2 = sc.push();
    sc2.stc = 0;
    sc2.linkage = LINK.d;
    fop.dsymbolSemantic(sc2);
    fop.semantic2(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.
 */
private 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 toHash, then we
     * need it too.
     */
    foreach (VarDeclaration v; sd.fields)
    {
        if (v.storage_class & STC.ref_)
            continue;
        if (v.overlapped)
            continue;
        Type tv = v.type.toBasetype();
        auto tvbase = tv.baseElemOf();
        if (tvbase.ty == Tstruct)
        {
            TypeStruct ts = cast(TypeStruct)tvbase;
            if (ts.sym.isUnionDeclaration())
                continue;
            if (needToHash(ts.sym))
                goto Lneed;
        }
        if (tvbase.isfloating())
        {
            /* This is necessary because comparison of +0.0 and -0.0 should be true,
             * i.e. not a bit compare.
             */
            goto Lneed;
        }
        if (tvbase.ty == Tarray)
            goto Lneed;
        if (tvbase.ty == Taarray)
            goto Lneed;
        if (tvbase.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))
    {
        __gshared TypeFunction tftohash;
        if (!tftohash)
        {
            tftohash = new TypeFunction(ParameterList(), Type.thash_t, LINK.d);
            tftohash.mod = MODFlags.const_;
            tftohash = cast(TypeFunction)tftohash.merge();
        }
        if (FuncDeclaration fd = s.isFuncDeclaration())
        {
            fd = fd.overloadExactMatch(tftohash);
            if (fd)
                return fd;
        }
    }
    if (!needToHash(sd))
        return null;

    /* The trouble is that the following code relies on .tupleof, but .tupleof
     * is not allowed for C files. If we allow it for C files, then that turns on
     * the other D properties, too, such as .dup which will then conflict with allowed
     * field names.
     * One way to fix it is to replace the following foreach and .tupleof with C
     * statements and expressions.
     * But, it's debatable whether C structs should even need toHash().
     * Note that it would only be necessary if it has floating point fields.
     * For now, we'll just not generate a toHash() for C files.
     */
    if (sc.flags & SCOPE.Cfile)
        return null;

    //printf("StructDeclaration::buildXtoHash() %s\n", sd.toPrettyChars());
    Loc declLoc; // loc is unnecessary so __xtoHash is never called directly
    Loc loc; // internal code should have no loc to prevent coverage
    auto parameters = new Parameters();
    parameters.push(new Parameter(STC.ref_ | STC.const_, sd.type, Id.p, null, null));
    auto tf = new TypeFunction(ParameterList(parameters), Type.thash_t, LINK.d, STC.nothrow_ | STC.trusted);
    Identifier id = Id.xtoHash;
    auto fop = new FuncDeclaration(declLoc, Loc.initial, id, STC.static_, tf);
    fop.isGenerated = 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 =
        ".object.size_t h = 0;" ~
        "foreach (i, T; typeof(p.tupleof))" ~
        // workaround https://issues.dlang.org/show_bug.cgi?id=17968
        "    static if(is(T* : const(.object.Object)*)) " ~
        "        h = h * 33 + typeid(const(.object.Object)).getHash(cast(const void*)&p.tupleof[i]);" ~
        "    else " ~
        "        h = h * 33 + typeid(T).getHash(cast(const void*)&p.tupleof[i]);" ~
        "return h;";
    fop.fbody = new CompileStatement(loc, new StringExp(loc, code));
    Scope* sc2 = sc.push();
    sc2.stc = 0;
    sc2.linkage = LINK.d;
    fop.dsymbolSemantic(sc2);
    fop.semantic2(sc2);
    sc2.pop();

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

/*****************************************
 * Create aggregate destructor for struct/class by aggregating
 * all the destructors in userDtors[] with the destructors for
 * all the members.
 * Sets ad's fieldDtor, aggrDtor, dtor and tidtor fields.
 * Params:
 *      ad = struct or class to build destructor for
 *      sc = context
 * Note:
 * Close similarity with StructDeclaration::buildPostBlit(),
 * and the ordering changes (runs backward instead of forwards).
 */
void buildDtors(AggregateDeclaration ad, Scope* sc)
{
    //printf("AggregateDeclaration::buildDtor() %s\n", ad.toChars());
    if (ad.isUnionDeclaration())
        return;                    // unions don't have destructors

    StorageClass stc = STC.safe | STC.nothrow_ | STC.pure_ | STC.nogc;
    Loc declLoc = ad.userDtors.length ? ad.userDtors[0].loc : ad.loc;
    Loc loc; // internal code should have no loc to prevent coverage
    FuncDeclaration xdtor_fwd = null;

    // Build the field destructor (`ad.fieldDtor`), if needed.
    // If the user dtor is an extern(C++) prototype, then we expect it performs a full-destruction and skip building.
    const bool dtorIsCppPrototype = ad.userDtors.length && ad.userDtors[0]._linkage == LINK.cpp && !ad.userDtors[0].fbody;
    if (!dtorIsCppPrototype)
    {
        Expression e = null;
        for (size_t i = 0; i < ad.fields.length; i++)
        {
            auto v = ad.fields[i];
            if (v.storage_class & STC.ref_)
                continue;
            if (v.overlapped)
                continue;
            auto tv = v.type.baseElemOf();
            if (tv.ty != Tstruct)
                continue;
            auto sdv = (cast(TypeStruct)tv).sym;
            if (!sdv.dtor)
                continue;

            // fix: https://issues.dlang.org/show_bug.cgi?id=17257
            // braces for shrink wrapping scope of a
            {
                xdtor_fwd = sdv.dtor; // this dtor is temporary it could be anything
                auto a = new AliasDeclaration(Loc.initial, Id.__xdtor, xdtor_fwd);
                a.addMember(sc, ad); // temporarily add to symbol table
            }

            sdv.dtor.functionSemantic();

            stc = mergeFuncAttrs(stc, sdv.dtor);
            if (stc & STC.disable)
            {
                e = null;
                break;
            }

            Expression ex;
            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.
                // Do it as a type 'paint', `cast()`
                ex = new CastExp(loc, ex, MODFlags.none);
                if (stc & STC.safe)
                    stc = (stc & ~STC.safe) | STC.trusted;

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

                const 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 & STC.safe)
                    stc = (stc & ~STC.safe) | STC.trusted;

                SliceExp se = new SliceExp(loc, ex, new IntegerExp(loc, 0, Type.tsize_t),
                                           new IntegerExp(loc, n, Type.tsize_t));
                // Prevent redundant bounds check
                se.upperIsInBounds = true;
                se.lowerIsLessThanUpper = true;

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

        if (e || (stc & STC.disable))
        {
            //printf("Building __fieldDtor(), %s\n", e.toChars());
            auto dd = new DtorDeclaration(declLoc, Loc.initial, stc, Id.__fieldDtor);
            dd.isGenerated = true;
            dd.storage_class |= STC.inference;
            dd.fbody = new ExpStatement(loc, e);
            ad.members.push(dd);
            dd.dsymbolSemantic(sc);
            ad.fieldDtor = dd;
        }
    }

    // Generate list of dtors to call in that order
    DtorDeclarations dtors;
    foreach_reverse (userDtor; ad.userDtors[])
        dtors.push(userDtor);
    if (ad.fieldDtor)
        dtors.push(ad.fieldDtor);
    if (!dtorIsCppPrototype)
    {
        // extern(C++) destructors call into super to destruct the full hierarchy
        ClassDeclaration cldec = ad.isClassDeclaration();
        if (cldec && cldec.classKind == ClassKind.cpp && cldec.baseClass && cldec.baseClass.aggrDtor)
            dtors.push(cldec.baseClass.aggrDtor);
    }

    // Set/build `ad.aggrDtor`
    switch (dtors.length)
    {
    case 0:
        break;

    case 1:
        // Use the single existing dtor directly as aggregate dtor.
        // Note that this might be `cldec.baseClass.aggrDtor`.
        ad.aggrDtor = dtors[0];
        break;

    default:
        // Build the aggregate destructor, calling all dtors in order.
        assert(!dtorIsCppPrototype);
        Expression e = null;
        e = null;
        stc = STC.safe | STC.nothrow_ | STC.pure_ | STC.nogc;
        foreach (FuncDeclaration fd; dtors)
        {
            stc = mergeFuncAttrs(stc, fd);
            if (stc & STC.disable)
            {
                e = null;
                break;
            }
            Expression ex = new ThisExp(loc);
            ex = new DotVarExp(loc, ex, fd, false);
            CallExp ce = new CallExp(loc, ex);
            ce.directcall = true;
            e = Expression.combine(e, ce);
        }
        auto dd = new DtorDeclaration(declLoc, Loc.initial, stc, Id.__aggrDtor);
        dd.isGenerated = true;
        dd.storage_class |= STC.inference;
        dd.fbody = new ExpStatement(loc, e);
        ad.members.push(dd);
        dd.dsymbolSemantic(sc);
        ad.aggrDtor = dd;
        break;
    }

    // Set/build `ad.dtor`.
    // On Windows, the dtor in the vtable is a shim with different signature.
    ad.dtor = (ad.aggrDtor && ad.aggrDtor._linkage == LINK.cpp && !target.cpp.twoDtorInVtable)
        ? buildWindowsCppDtor(ad, ad.aggrDtor, sc)
        : ad.aggrDtor;

    // Add an __xdtor alias to make `ad.dtor` accessible
    if (ad.dtor)
    {
        auto _alias = new AliasDeclaration(Loc.initial, Id.__xdtor, ad.dtor);
        _alias.dsymbolSemantic(sc);
        ad.members.push(_alias);
        if (xdtor_fwd)
            ad.symtab.update(_alias); // update forward dtor to correct one
        else
            _alias.addMember(sc, ad); // add to symbol table
    }

    // Set/build `ad.tidtor`
    ad.tidtor = buildExternDDtor(ad, sc);
}

/**
 * build a shim function around the compound dtor that accepts an argument
 *  that is used to implement the deleting C++ destructor
 *
 * Params:
 *  ad = the aggregate that contains the destructor to wrap
 *  dtor = the destructor to wrap
 *  sc = the scope in which to analyze the new function
 *
 * Returns:
 *  the shim destructor, semantically analyzed and added to the class as a member
 */
private DtorDeclaration buildWindowsCppDtor(AggregateDeclaration ad, DtorDeclaration dtor, Scope* sc)
{
    auto cldec = ad.isClassDeclaration();
    if (!cldec || cldec.cppDtorVtblIndex == -1) // scalar deleting dtor not built for non-virtual dtors
        return dtor;    // perhaps also do this if STC.scope_ is set

    // generate deleting C++ destructor corresponding to:
    // void* C::~C(int del)
    // {
    //   this->~C();
    //   // TODO: if (del) delete (char*)this;
    //   return (void*) this;
    // }
    Parameter delparam = new Parameter(STC.undefined_, Type.tuns32, Identifier.idPool("del"), new IntegerExp(dtor.loc, 0, Type.tuns32), null);
    Parameters* params = new Parameters;
    params.push(delparam);
    const stc = dtor.storage_class & ~STC.scope_; // because we add the `return this;` later
    auto ftype = new TypeFunction(ParameterList(params), Type.tvoidptr, LINK.cpp, stc);
    auto func = new DtorDeclaration(dtor.loc, dtor.loc, stc, Id.cppdtor);
    func.type = ftype;

    // Always generate the function with body, because it is not exported from DLLs.
    const loc = dtor.loc;
    auto stmts = new Statements;
    auto call = new CallExp(loc, dtor, null);
    call.directcall = true;
    stmts.push(new ExpStatement(loc, call));
    stmts.push(new ReturnStatement(loc, new CastExp(loc, new ThisExp(loc), Type.tvoidptr)));
    func.fbody = new CompoundStatement(loc, stmts);
    func.isGenerated = true;

    auto sc2 = sc.push();
    sc2.stc &= ~STC.static_; // not a static destructor
    sc2.linkage = LINK.cpp;

    ad.members.push(func);
    func.addMember(sc2, ad);
    func.dsymbolSemantic(sc2);

    sc2.pop();
    return func;
}

/**
 * build a shim function around the aggregate dtor that translates
 *  a C++ destructor to a destructor with extern(D) calling convention
 *
 * Params:
 *  ad = the aggregate that contains the destructor to wrap
 *  sc = the scope in which to analyze the new function
 *
 * Returns:
 *  the shim destructor, semantically analyzed and added to the class as a member
 */
private DtorDeclaration buildExternDDtor(AggregateDeclaration ad, Scope* sc)
{
    auto dtor = ad.aggrDtor;
    if (!dtor)
        return null;

    // Don't try to call `@disable`d dtors
    if (dtor.storage_class & STC.disable)
        return null;

    // Generate shim only when ABI incompatible on target platform
    if (ad.classKind != ClassKind.cpp || !target.cpp.wrapDtorInExternD)
        return dtor;

    // generate member function that adjusts calling convention
    // (EAX used for 'this' instead of ECX on Windows/stack on others):
    // extern(D) void __ticppdtor()
    // {
    //     Class.__dtor();
    // }
    auto ftype = new TypeFunction(ParameterList(), Type.tvoid, LINK.d, dtor.storage_class);
    auto func = new DtorDeclaration(dtor.loc, dtor.loc, dtor.storage_class, Id.ticppdtor);
    func.type = ftype;

    auto call = new CallExp(dtor.loc, dtor, null);
    call.directcall = true;                   // non-virtual call Class.__dtor();
    func.fbody = new ExpStatement(dtor.loc, call);
    func.isGenerated = true;
    func.storage_class |= STC.inference;

    auto sc2 = sc.push();
    sc2.stc &= ~STC.static_; // not a static destructor
    sc2.linkage = LINK.d;

    ad.members.push(func);
    func.addMember(sc2, ad);
    func.dsymbolSemantic(sc2);
    func.functionSemantic(); // to infer attributes

    sc2.pop();
    return func;
}

/******************************************
 * 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)
{
    switch (ad.invs.length)
    {
    case 0:
        return null;

    case 1:
        // Don't return invs[0] so it has uniquely generated name.
        goto default;

    default:
        Expression e = null;
        StorageClass stcx = 0;
        StorageClass stc = STC.safe | STC.nothrow_ | STC.pure_ | STC.nogc;
        foreach (i, inv; ad.invs)
        {
            stc = mergeFuncAttrs(stc, inv);
            if (stc & STC.disable)
            {
                // What should do?
            }
            const stcy = (inv.storage_class & STC.synchronized_) |
                         (inv.type.mod & MODFlags.shared_ ? STC.shared_ : 0);
            if (i == 0)
                stcx = stcy;
            else if (stcx ^ stcy)
            {
                version (all)
                {
                    // currently rejects
                    ad.error(inv.loc, "mixing invariants with different `shared`/`synchronized` qualifiers is not supported");
                    e = null;
                    break;
                }
            }
            e = Expression.combine(e, new CallExp(Loc.initial, new VarExp(Loc.initial, inv, false)));
        }
        auto inv = new InvariantDeclaration(ad.loc, Loc.initial, stc | stcx,
                Id.classInvariant, new ExpStatement(Loc.initial, e));
        ad.members.push(inv);
        inv.dsymbolSemantic(sc);
        return inv;
    }
}

/*****************************************
 * 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("buildPostBlit() %s\n", sd.toChars());
    if (sd.isUnionDeclaration())
        return null;

    const hasUserDefinedPosblit = sd.postblits.length && !sd.postblits[0].isDisabled ? true : false;

    // by default, the storage class of the created postblit
    StorageClass stc = STC.safe | STC.nothrow_ | STC.pure_ | STC.nogc;
    Loc declLoc = sd.postblits.length ? sd.postblits[0].loc : sd.loc;
    Loc loc; // internal code should have no loc to prevent coverage

    // if any of the postblits are disabled, then the generated postblit
    // will be disabled
    foreach (postblit; sd.postblits)
        stc |= postblit.storage_class & STC.disable;

    VarDeclaration[] fieldsToDestroy;
    auto postblitCalls = new Statements();
    // iterate through all the struct fields that are not disabled
    for (size_t i = 0; i < sd.fields.length && !(stc & STC.disable); i++)
    {
        auto structField = sd.fields[i];
        if (structField.storage_class & STC.ref_)
            continue;
        if (structField.overlapped)
            continue;
        // if it's a struct declaration or an array of structs
        Type tv = structField.type.baseElemOf();
        if (tv.ty != Tstruct)
            continue;
        auto sdv = (cast(TypeStruct)tv).sym;
        // which has a postblit declaration
        if (!sdv.postblit)
            continue;
        assert(!sdv.isUnionDeclaration());

        // if this field's postblit is not `nothrow`, add a `scope(failure)`
        // block to destroy any prior successfully postblitted fields should
        // this field's postblit fail
        if (fieldsToDestroy.length > 0 && !(cast(TypeFunction)sdv.postblit.type).isnothrow)
        {
             // create a list of destructors that need to be called
            Expression[] dtorCalls;
            foreach(sf; fieldsToDestroy)
            {
                Expression ex;
                tv = sf.type.toBasetype();
                if (tv.ty == Tstruct)
                {
                    // this.v.__xdtor()

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

                    // This is a hack so we can call destructors on const/immutable objects.
                    ex = new AddrExp(loc, ex);
                    ex = new CastExp(loc, ex, sf.type.mutableOf().pointerTo());
                    ex = new PtrExp(loc, ex);
                    if (stc & STC.safe)
                        stc = (stc & ~STC.safe) | STC.trusted;

                    auto sfv = (cast(TypeStruct)sf.type.baseElemOf()).sym;

                    ex = new DotVarExp(loc, ex, sfv.dtor, false);
                    ex = new CallExp(loc, ex);

                    dtorCalls ~= ex;
                }
                else
                {
                    // _ArrayDtor((cast(S*)this.v.ptr)[0 .. n])

                    const length = tv.numberOfElems(loc);

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

                    // 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 & STC.safe)
                        stc = (stc & ~STC.safe) | STC.trusted;

                    auto se = new SliceExp(loc, ex, new IntegerExp(loc, 0, Type.tsize_t),
                                                    new IntegerExp(loc, length, Type.tsize_t));
                    // Prevent redundant bounds check
                    se.upperIsInBounds = true;
                    se.lowerIsLessThanUpper = true;

                    ex = new CallExp(loc, new IdentifierExp(loc, Id.__ArrayDtor), se);

                    dtorCalls ~= ex;
                }
            }
            fieldsToDestroy = [];

            // aggregate the destructor calls
            auto dtors = new Statements();
            foreach_reverse(dc; dtorCalls)
            {
                dtors.push(new ExpStatement(loc, dc));
            }

            // put destructor calls in a `scope(failure)` block
            postblitCalls.push(new ScopeGuardStatement(loc, TOK.onScopeFailure, new CompoundStatement(loc, dtors)));
        }

        // perform semantic on the member postblit in order to
        // be able to aggregate it later on with the rest of the
        // postblits
        sdv.postblit.functionSemantic();

        stc = mergeFuncAttrs(stc, sdv.postblit);
        stc = mergeFuncAttrs(stc, sdv.dtor);

        // if any of the struct member fields has disabled
        // its postblit, then `sd` is not copyable, so no
        // postblit is generated
        if (stc & STC.disable)
        {
            postblitCalls.setDim(0);
            break;
        }

        Expression ex;
        tv = structField.type.toBasetype();
        if (tv.ty == Tstruct)
        {
            // this.v.__xpostblit()

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

            // This is a hack so we can call postblits on const/immutable objects.
            ex = new AddrExp(loc, ex);
            ex = new CastExp(loc, ex, structField.type.mutableOf().pointerTo());
            ex = new PtrExp(loc, ex);
            if (stc & STC.safe)
                stc = (stc & ~STC.safe) | STC.trusted;

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

            const length = tv.numberOfElems(loc);
            if (length == 0)
                continue;

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

            // 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 & STC.safe)
                stc = (stc & ~STC.safe) | STC.trusted;

            auto se = new SliceExp(loc, ex, new IntegerExp(loc, 0, Type.tsize_t),
                                            new IntegerExp(loc, length, Type.tsize_t));
            // Prevent redundant bounds check
            se.upperIsInBounds = true;
            se.lowerIsLessThanUpper = true;
            ex = new CallExp(loc, new IdentifierExp(loc, Id.__ArrayPostblit), se);
        }
        postblitCalls.push(new ExpStatement(loc, ex)); // combine in forward order

        /* https://issues.dlang.org/show_bug.cgi?id=10972
         * When subsequent field postblit calls fail,
         * this field should be destructed for Exception Safety.
         */
        if (sdv.dtor)
        {
            sdv.dtor.functionSemantic();

            // keep a list of fields that need to be destroyed in case
            // of a future postblit failure
            fieldsToDestroy ~= structField;
        }
    }

    void checkShared()
    {
        if (sd.type.isShared())
            stc |= STC.shared_;
    }

    // Build our own "postblit" which executes a, but only if needed.
    if (postblitCalls.length || (stc & STC.disable))
    {
        //printf("Building __fieldPostBlit()\n");
        checkShared();
        auto dd = new PostBlitDeclaration(declLoc, Loc.initial, stc, Id.__fieldPostblit);
        dd.isGenerated = true;
        dd.storage_class |= STC.inference | STC.scope_;
        dd.fbody = (stc & STC.disable) ? null : new CompoundStatement(loc, postblitCalls);
        sd.postblits.shift(dd);
        sd.members.push(dd);
        dd.dsymbolSemantic(sc);
    }

    // create __xpostblit, which is the generated postblit
    FuncDeclaration xpostblit = null;
    switch (sd.postblits.length)
    {
    case 0:
        break;

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

    default:
        Expression e = null;
        stc = STC.safe | STC.nothrow_ | STC.pure_ | STC.nogc;
        foreach (fd; sd.postblits)
        {
            stc = mergeFuncAttrs(stc, fd);
            if (stc & STC.disable)
            {
                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);
        }

        checkShared();
        auto dd = new PostBlitDeclaration(declLoc, Loc.initial, stc, Id.__aggrPostblit);
        dd.isGenerated = true;
        dd.storage_class |= STC.inference;
        dd.fbody = new ExpStatement(loc, e);
        sd.members.push(dd);
        dd.dsymbolSemantic(sc);
        xpostblit = dd;
        break;
    }

    // Add an __xpostblit alias to make the inclusive postblit accessible
    if (xpostblit)
    {
        auto _alias = new AliasDeclaration(Loc.initial, Id.__xpostblit, xpostblit);
        _alias.dsymbolSemantic(sc);
        sd.members.push(_alias);
        _alias.addMember(sc, sd); // add to symbol table
    }

    if (sd.hasCopyCtor)
    {
        // we have user defined postblit, so we prioritize it
        if (hasUserDefinedPosblit)
        {
            sd.hasCopyCtor = false;
            return xpostblit;
        }
        // we have fields with postblits, so print deprecations
        if (xpostblit && !xpostblit.isDisabled())
        {
            deprecation(sd.loc, "`struct %s` implicitly-generated postblit hides copy constructor.", sd.toChars);
            deprecationSupplemental(sd.loc, "The field postblit will have priority over the copy constructor.");
            deprecationSupplemental(sd.loc, "To change this, the postblit should be disabled for `struct %s`", sd.toChars());
            sd.hasCopyCtor = false;
        }
        else
            xpostblit = null;
    }

    return xpostblit;
}

/**
 * Generates a copy constructor declaration with the specified storage
 * class for the parameter and the function.
 *
 * Params:
 *  sd = the `struct` that contains the copy constructor
 *  paramStc = the storage class of the copy constructor parameter
 *  funcStc = the storage class for the copy constructor declaration
 *
 * Returns:
 *  The copy constructor declaration for struct `sd`.
 */
private CtorDeclaration generateCopyCtorDeclaration(StructDeclaration sd, const StorageClass paramStc, const StorageClass funcStc)
{
    auto fparams = new Parameters();
    auto structType = sd.type;
    fparams.push(new Parameter(paramStc | STC.ref_ | STC.return_ | STC.scope_, structType, Id.p, null, null));
    ParameterList pList = ParameterList(fparams);
    auto tf = new TypeFunction(pList, structType, LINK.d, STC.ref_);
    auto ccd = new CtorDeclaration(sd.loc, Loc.initial, STC.ref_, tf, true);
    ccd.storage_class |= funcStc;
    ccd.storage_class |= STC.inference;
    ccd.isGenerated = true;
    return ccd;
}

/**
 * Generates a trivial copy constructor body that simply does memberwise
 * initialization:
 *
 *    this.field1 = rhs.field1;
 *    this.field2 = rhs.field2;
 *    ...
 *
 * Params:
 *  sd = the `struct` declaration that contains the copy constructor
 *
 * Returns:
 *  A `CompoundStatement` containing the body of the copy constructor.
 */
private Statement generateCopyCtorBody(StructDeclaration sd)
{
    Loc loc;
    Expression e;
    foreach (v; sd.fields)
    {
        auto 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);
        //printf("e.toChars = %s\n", e.toChars());
    }
    Statement s1 = new ExpStatement(loc, e);
    return new CompoundStatement(loc, s1);
}

/**
 * Determine if a copy constructor is needed for struct sd,
 * if the following conditions are met:
 *
 * 1. sd does not define a copy constructor
 * 2. at least one field of sd defines a copy constructor
 *
 * Params:
 *  sd = the `struct` for which the copy constructor is generated
 *  hasCpCtor = set to true if a copy constructor is already present
 *
 * Returns:
 *  `true` if one needs to be generated
 *  `false` otherwise
 */
private bool needCopyCtor(StructDeclaration sd, out bool hasCpCtor)
{
    if (global.errors)
        return false;

    auto ctor = sd.search(sd.loc, Id.ctor);
    if (ctor)
    {
        if (ctor.isOverloadSet())
            return false;
        if (auto td = ctor.isTemplateDeclaration())
            ctor = td.funcroot;
    }

    CtorDeclaration cpCtor;
    CtorDeclaration rvalueCtor;

    if (!ctor)
        goto LcheckFields;

    overloadApply(ctor, (Dsymbol s)
    {
        if (s.isTemplateDeclaration())
            return 0;
        auto ctorDecl = s.isCtorDeclaration();
        assert(ctorDecl);
        if (ctorDecl.isCpCtor)
        {
            if (!cpCtor)
                cpCtor = ctorDecl;
            return 0;
        }

        auto tf = ctorDecl.type.toTypeFunction();
        const dim = tf.parameterList.length;
        if (dim == 1 || (dim > 1 && tf.parameterList[1].defaultArg))
        {
            auto param = tf.parameterList[0];
            if (param.type.mutableOf().unSharedOf() == sd.type.mutableOf().unSharedOf())
            {
                rvalueCtor = ctorDecl;
            }
        }
        return 0;
    });

    if (cpCtor)
    {
        if (rvalueCtor)
        {
            .error(sd.loc, "`struct %s` may not define both a rvalue constructor and a copy constructor", sd.toChars());
            errorSupplemental(rvalueCtor.loc,"rvalue constructor defined here");
            errorSupplemental(cpCtor.loc, "copy constructor defined here");
        }
        hasCpCtor = true;
        return false;
    }

LcheckFields:
    VarDeclaration fieldWithCpCtor;
    // see if any struct members define a copy constructor
    foreach (v; sd.fields)
    {
        if (v.storage_class & STC.ref_)
            continue;
        if (v.overlapped)
            continue;

        auto ts = v.type.baseElemOf().isTypeStruct();
        if (!ts)
            continue;
        if (ts.sym.hasCopyCtor)
        {
            fieldWithCpCtor = v;
            break;
        }
    }

    if (fieldWithCpCtor && rvalueCtor)
    {
        .error(sd.loc, "`struct %s` may not define a rvalue constructor and have fields with copy constructors", sd.toChars());
        errorSupplemental(rvalueCtor.loc,"rvalue constructor defined here");
        errorSupplemental(fieldWithCpCtor.loc, "field with copy constructor defined here");
        return false;
    }
    else if (!fieldWithCpCtor)
        return false;
    return true;
}

/**
 * Generates a copy constructor if needCopyCtor() returns true.
 * The generated copy constructor will be of the form:
 *   this(ref return scope inout(S) rhs) inout
 *   {
 *      this.field1 = rhs.field1;
 *      this.field2 = rhs.field2;
 *      ...
 *   }
 *
 * Params:
 *  sd = the `struct` for which the copy constructor is generated
 *  sc = the scope where the copy constructor is generated
 *
 * Returns:
 *  `true` if `struct` sd defines a copy constructor (explicitly or generated),
 *  `false` otherwise.
 */
bool buildCopyCtor(StructDeclaration sd, Scope* sc)
{
    bool hasCpCtor;
    if (!needCopyCtor(sd, hasCpCtor))
        return hasCpCtor;

    //printf("generating copy constructor for %s\n", sd.toChars());
    const MOD paramMod = MODFlags.wild;
    const MOD funcMod = MODFlags.wild;
    auto ccd = generateCopyCtorDeclaration(sd, ModToStc(paramMod), ModToStc(funcMod));
    auto copyCtorBody = generateCopyCtorBody(sd);
    ccd.fbody = copyCtorBody;
    sd.members.push(ccd);
    ccd.addMember(sc, sd);
    const errors = global.startGagging();
    Scope* sc2 = sc.push();
    sc2.stc = 0;
    sc2.linkage = LINK.d;
    ccd.dsymbolSemantic(sc2);
    ccd.semantic2(sc2);
    ccd.semantic3(sc2);
    //printf("ccd semantic: %s\n", ccd.type.toChars());
    sc2.pop();
    if (global.endGagging(errors) || sd.isUnionDeclaration())
    {
        ccd.storage_class |= STC.disable;
        ccd.fbody = null;
    }
    return true;
}
