
/* Compiler implementation of the D programming language
 * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved
 * written by Walter Bright
 * http://www.digitalmars.com
 * Distributed under the Boost Software License, Version 1.0.
 * http://www.boost.org/LICENSE_1_0.txt
 * https://github.com/D-Programming-Language/dmd/blob/master/src/struct.c
 */

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

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

Type *getTypeInfoType(Loc loc, Type *t, Scope *sc);
TypeTuple *toArgTypes(Type *t);
void unSpeculative(Scope *sc, RootObject *o);
bool MODimplicitConv(MOD modfrom, MOD modto);
Expression *resolve(Loc loc, Scope *sc, Dsymbol *s, bool hasOverloads);

FuncDeclaration *StructDeclaration::xerreq;     // object.xopEquals
FuncDeclaration *StructDeclaration::xerrcmp;    // object.xopCmp

/***************************************
 * Search toString member function for TypeInfo_Struct.
 *      string toString();
 */
FuncDeclaration *search_toString(StructDeclaration *sd)
{
    Dsymbol *s = search_function(sd, Id::tostring);
    FuncDeclaration *fd = s ? s->isFuncDeclaration() : NULL;
    if (fd)
    {
        static TypeFunction *tftostring;
        if (!tftostring)
        {
            tftostring = new TypeFunction(NULL, Type::tstring, 0, LINKd);
            tftostring = tftostring->merge()->toTypeFunction();
        }

        fd = fd->overloadExactMatch(tftostring);
    }
    return fd;
}

/***************************************
 * Request additonal semantic analysis for TypeInfo generation.
 */
void semanticTypeInfo(Scope *sc, Type *t)
{
    class FullTypeInfoVisitor : public Visitor
    {
    public:
        Scope *sc;

        void visit(Type *t)
        {
            Type *tb = t->toBasetype();
            if (tb != t)
                tb->accept(this);
        }
        void visit(TypeNext *t)
        {
            if (t->next)
                t->next->accept(this);
        }
        void visit(TypeBasic *) { }
        void visit(TypeVector *t)
        {
            t->basetype->accept(this);
        }
        void visit(TypeAArray *t)
        {
            t->index->accept(this);
            visit((TypeNext *)t);
        }
        void visit(TypeFunction *t)
        {
            visit((TypeNext *)t);
            // Currently TypeInfo_Function doesn't store parameter types.
        }
        void visit(TypeStruct *t)
        {
            //printf("semanticTypeInfo::visit(TypeStruct = %s)\n", t->toChars());
            StructDeclaration *sd = t->sym;

            /* Step 1: create TypeInfoDeclaration
             */
            if (!sc) // inline may request TypeInfo.
            {
                Scope scx;
                scx._module = sd->getModule();
                getTypeInfoType(sd->loc, t, &scx);
                sd->requestTypeInfo = true;
            }
            else if (!sc->minst)
            {
                // don't yet have to generate TypeInfo instance if
                // the typeid(T) expression exists in speculative scope.
            }
            else
            {
                getTypeInfoType(sd->loc, t, sc);
                sd->requestTypeInfo = true;

                // Bugzilla 15149, if the typeid operand type comes from a
                // result of auto function, it may be yet speculative.
                unSpeculative(sc, sd);
            }

            /* Step 2: If the TypeInfo generation requires sd.semantic3, run it later.
             * This should be done even if typeid(T) exists in speculative scope.
             * Because it may appear later in non-speculative scope.
             */
            if (!sd->members)
                return;     // opaque struct
            if (!sd->xeq && !sd->xcmp && !sd->postblit &&
                !sd->dtor && !sd->xhash && !search_toString(sd))
                return;     // none of TypeInfo-specific members

            // If the struct is in a non-root module, run semantic3 to get
            // correct symbols for the member function.
            if (sd->semanticRun >= PASSsemantic3)
            {
                // semantic3 is already done
            }
            else if (TemplateInstance *ti = sd->isInstantiated())
            {
                if (ti->minst && !ti->minst->isRoot())
                    Module::addDeferredSemantic3(sd);
            }
            else
            {
                if (sd->inNonRoot())
                {
                    //printf("deferred sem3 for TypeInfo - sd = %s, inNonRoot = %d\n", sd->toChars(), sd->inNonRoot());
                    Module::addDeferredSemantic3(sd);
                }
            }
        }
        void visit(TypeClass *) { }
        void visit(TypeTuple *t)
        {
            if (t->arguments)
            {
                for (size_t i = 0; i < t->arguments->dim; i++)
                {
                    Type *tprm = (*t->arguments)[i]->type;
                    if (tprm)
                        tprm->accept(this);
                }
            }
        }
    };

    if (sc)
    {
        if (!sc->func)
            return;
        if (sc->intypeof)
            return;
        if (sc->flags & (SCOPEctfe | SCOPEcompile))
            return;
    }

    FullTypeInfoVisitor v;
    v.sc = sc;
    t->accept(&v);
}

/********************************* AggregateDeclaration ****************************/

AggregateDeclaration::AggregateDeclaration(Loc loc, Identifier *id)
    : ScopeDsymbol(id)
{
    this->loc = loc;

    storage_class = 0;
    protection = Prot(PROTpublic);
    type = NULL;
    structsize = 0;             // size of struct
    alignsize = 0;              // size of struct for alignment purposes
    sizeok = SIZEOKnone;        // size not determined yet
    deferred = NULL;
    isdeprecated = false;
    inv = NULL;
    aggNew = NULL;
    aggDelete = NULL;

    stag = NULL;
    sinit = NULL;
    enclosing = NULL;
    vthis = NULL;

    ctor = NULL;
    defaultCtor = NULL;
    aliasthis = NULL;
    noDefaultCtor = false;
    dtor = NULL;
    getRTInfo = NULL;
}

Prot AggregateDeclaration::prot()
{
    return protection;
}

/***************************************
 * Create a new scope from sc.
 * semantic, semantic2 and semantic3 will use this for aggregate members.
 */
Scope *AggregateDeclaration::newScope(Scope *sc)
{
    Scope *sc2 = sc->push(this);
    sc2->stc &= STCsafe | STCtrusted | STCsystem;
    sc2->parent = this;
    if (isUnionDeclaration())
        sc2->inunion = 1;
    sc2->protection = Prot(PROTpublic);
    sc2->explicitProtection = 0;
    sc2->aligndecl = NULL;
    sc2->userAttribDecl = NULL;
    return sc2;
}

void AggregateDeclaration::setScope(Scope *sc)
{
    // Might need a scope to resolve forward references. The check for
    // semanticRun prevents unnecessary setting of _scope during deferred
    // setScope phases for aggregates which already finished semantic().
    // Also see https://issues.dlang.org/show_bug.cgi?id=16607
    if (semanticRun < PASSsemanticdone)
        ScopeDsymbol::setScope(sc);
}

void AggregateDeclaration::semantic2(Scope *sc)
{
    //printf("AggregateDeclaration::semantic2(%s) type = %s, errors = %d\n", toChars(), type->toChars(), errors);
    if (!members)
        return;

    if (_scope)
    {
        error("has forward references");
        return;
    }

    Scope *sc2 = newScope(sc);

    determineSize(loc);

    for (size_t i = 0; i < members->dim; i++)
    {
        Dsymbol *s = (*members)[i];
        //printf("\t[%d] %s\n", i, s->toChars());
        s->semantic2(sc2);
    }

    sc2->pop();
}

void AggregateDeclaration::semantic3(Scope *sc)
{
    //printf("AggregateDeclaration::semantic3(%s) type = %s, errors = %d\n", toChars(), type->toChars(), errors);
    if (!members)
        return;

    StructDeclaration *sd = isStructDeclaration();
    if (!sc)    // from runDeferredSemantic3 for TypeInfo generation
    {
        assert(sd);
        sd->semanticTypeInfoMembers();
        return;
    }

    Scope *sc2 = newScope(sc);

    for (size_t i = 0; i < members->dim; i++)
    {
        Dsymbol *s = (*members)[i];
        s->semantic3(sc2);
    }

    sc2->pop();

    // don't do it for unused deprecated types
    // or error types
    if (!getRTInfo && Type::rtinfo &&
        (!isDeprecated() || global.params.useDeprecated != DIAGNOSTICerror) &&
        (type && type->ty != Terror))
    {
        // Evaluate: RTinfo!type
        Objects *tiargs = new Objects();
        tiargs->push(type);
        TemplateInstance *ti = new TemplateInstance(loc, Type::rtinfo, tiargs);

        Scope *sc3 = ti->tempdecl->_scope->startCTFE();
        sc3->tinst = sc->tinst;
        sc3->minst = sc->minst;
        if (isDeprecated())
            sc3->stc |= STCdeprecated;

        ti->semantic(sc3);
        ti->semantic2(sc3);
        ti->semantic3(sc3);
        Expression *e = resolve(Loc(), sc3, ti->toAlias(), false);

        sc3->endCTFE();

        e = e->ctfeInterpret();
        getRTInfo = e;
    }

    if (sd)
        sd->semanticTypeInfoMembers();
}

/***************************************
 * Find all instance fields, then push them into `fields`.
 *
 * Runs semantic() for all instance field variables, but also
 * the field types can reamin yet not resolved forward references,
 * except direct recursive definitions.
 * After the process sizeok is set to SIZEOKfwd.
 *
 * Returns:
 *      false if any errors occur.
 */
bool AggregateDeclaration::determineFields()
{
    if (sizeok != SIZEOKnone)
        return true;

    //printf("determineFields() %s, fields.dim = %d\n", toChars(), fields.dim);
    fields.setDim(0);

    struct SV
    {
        AggregateDeclaration *agg;

        static int func(Dsymbol *s, void *param)
        {
            VarDeclaration *v = s->isVarDeclaration();
            if (!v)
                return 0;
            if (v->storage_class & STCmanifest)
                return 0;

            AggregateDeclaration *ad = ((SV *)param)->agg;

            if (v->_scope)
                v->semantic(NULL);
            // Note: Aggregate fields or size could have determined during v->semantic.
            if (ad->sizeok != SIZEOKnone)
                return 1;

            if (v->aliassym)
                return 0;   // If this variable was really a tuple, skip it.

            if (v->storage_class & (STCstatic | STCextern | STCtls | STCgshared | STCmanifest | STCctfe | STCtemplateparameter))
                return 0;
            if (!v->isField() || v->semanticRun < PASSsemanticdone)
                return 1;   // unresolvable forward reference

            ad->fields.push(v);

            if (v->storage_class & STCref)
                return 0;
            Type *tv = v->type->baseElemOf();
            if (tv->ty != Tstruct)
                return 0;
            if (ad == ((TypeStruct *)tv)->sym)
            {
                const char *psz = (v->type->toBasetype()->ty == Tsarray) ? "static array of " : "";
                ad->error("cannot have field %s with %ssame struct type", v->toChars(), psz);
                ad->type = Type::terror;
                ad->errors = true;
                return 1;
            }
            return 0;
        }
    };
    SV sv;
    sv.agg = this;

    for (size_t i = 0; i < members->dim; i++)
    {
        Dsymbol *s = (*members)[i];
        if (s->apply(&SV::func, &sv))
        {
            if (sizeok != SIZEOKnone)
                return true;
            return false;
        }
    }

    if (sizeok != SIZEOKdone)
        sizeok = SIZEOKfwd;

    return true;
}

/***************************************
 * Collect all instance fields, then determine instance size.
 * Returns:
 *      false if failed to determine the size.
 */
bool AggregateDeclaration::determineSize(Loc loc)
{
    //printf("AggregateDeclaration::determineSize() %s, sizeok = %d\n", toChars(), sizeok);

    // The previous instance size finalizing had:
    if (type->ty == Terror)
        return false;   // failed already
    if (sizeok == SIZEOKdone)
        return true;    // succeeded

    if (!members)
    {
        error(loc, "unknown size");
        return false;
    }

    if (_scope)
        semantic(NULL);

    // Determine the instance size of base class first.
    if (ClassDeclaration *cd = isClassDeclaration())
    {
        cd = cd->baseClass;
        if (cd && !cd->determineSize(loc))
            goto Lfail;
    }

    // Determine instance fields when sizeok == SIZEOKnone
    if (!determineFields())
        goto Lfail;
    if (sizeok != SIZEOKdone)
        finalizeSize();

    // this aggregate type has:
    if (type->ty == Terror)
        return false;   // marked as invalid during the finalizing.
    if (sizeok == SIZEOKdone)
        return true;    // succeeded to calculate instance size.

Lfail:
    // There's unresolvable forward reference.
    if (type != Type::terror)
        error(loc, "no size because of forward reference");
    // Don't cache errors from speculative semantic, might be resolvable later.
    // https://issues.dlang.org/show_bug.cgi?id=16574
    if (!global.gag)
    {
        type = Type::terror;
        errors = true;
    }
    return false;
}

void StructDeclaration::semanticTypeInfoMembers()
{
    if (xeq &&
        xeq->_scope &&
        xeq->semanticRun < PASSsemantic3done)
    {
        unsigned errors = global.startGagging();
        xeq->semantic3(xeq->_scope);
        if (global.endGagging(errors))
            xeq = xerreq;
    }

    if (xcmp &&
        xcmp->_scope &&
        xcmp->semanticRun < PASSsemantic3done)
    {
        unsigned errors = global.startGagging();
        xcmp->semantic3(xcmp->_scope);
        if (global.endGagging(errors))
            xcmp = xerrcmp;
    }

    FuncDeclaration *ftostr = search_toString(this);
    if (ftostr &&
        ftostr->_scope &&
        ftostr->semanticRun < PASSsemantic3done)
    {
        ftostr->semantic3(ftostr->_scope);
    }

    if (xhash &&
        xhash->_scope &&
        xhash->semanticRun < PASSsemantic3done)
    {
        xhash->semantic3(xhash->_scope);
    }

    if (postblit &&
        postblit->_scope &&
        postblit->semanticRun < PASSsemantic3done)
    {
        postblit->semantic3(postblit->_scope);
    }

    if (dtor &&
        dtor->_scope &&
        dtor->semanticRun < PASSsemantic3done)
    {
        dtor->semantic3(dtor->_scope);
    }
}

d_uns64 AggregateDeclaration::size(Loc loc)
{
    //printf("+AggregateDeclaration::size() %s, scope = %p, sizeok = %d\n", toChars(), _scope, sizeok);
    bool ok = determineSize(loc);
    //printf("-AggregateDeclaration::size() %s, scope = %p, sizeok = %d\n", toChars(), _scope, sizeok);
    return ok ? structsize : SIZE_INVALID;
}

Type *AggregateDeclaration::getType()
{
    return type;
}

bool AggregateDeclaration::isDeprecated()
{
    return isdeprecated;
}

bool AggregateDeclaration::isExport() const
{
    return protection.kind == PROTexport;
}

/***************************************
 * Calculate field[i].overlapped and overlapUnsafe, and check that all of explicit
 * field initializers have unique memory space on instance.
 * Returns:
 *      true if any errors happen.
 */

bool AggregateDeclaration::checkOverlappedFields()
{
    //printf("AggregateDeclaration::checkOverlappedFields() %s\n", toChars());
    assert(sizeok == SIZEOKdone);
    size_t nfields = fields.dim;
    if (isNested())
    {
        ClassDeclaration *cd = isClassDeclaration();
        if (!cd || !cd->baseClass || !cd->baseClass->isNested())
            nfields--;
    }
    bool errors = false;

    // Fill in missing any elements with default initializers
    for (size_t i = 0; i < nfields; i++)
    {
        VarDeclaration *vd = fields[i];
        if (vd->errors)
        {
            errors = true;
            continue;
        }

        VarDeclaration *vx = vd;
        if (vd->_init && vd->_init->isVoidInitializer())
            vx = NULL;

        // Find overlapped fields with the hole [vd->offset .. vd->offset->size()].
        for (size_t j = 0; j < nfields; j++)
        {
            if (i == j)
                continue;
            VarDeclaration *v2 = fields[j];
            if (v2->errors)
            {
                errors = true;
                continue;
            }
            if (!vd->isOverlappedWith(v2))
                continue;

            // vd and v2 are overlapping.
            vd->overlapped = true;
            v2->overlapped = true;

            if (!MODimplicitConv(vd->type->mod, v2->type->mod))
                v2->overlapUnsafe = true;
            if (!MODimplicitConv(v2->type->mod, vd->type->mod))
                vd->overlapUnsafe = true;

            if (!vx)
                continue;
            if (v2->_init && v2->_init->isVoidInitializer())
                continue;

            if (vx->_init && v2->_init)
            {
                ::error(loc, "overlapping default initialization for field %s and %s", v2->toChars(), vd->toChars());
                errors = true;
            }
        }
    }
    return errors;
}

/***************************************
 * Fill out remainder of elements[] with default initializers for fields[].
 * Input:
 *      loc:        location
 *      elements:   explicit arguments which given to construct object.
 *      ctorinit:   true if the elements will be used for default initialization.
 * Returns:
 *      false if any errors occur.
 *      Otherwise, returns true and the missing arguments will be pushed in elements[].
 */
bool AggregateDeclaration::fill(Loc loc, Expressions *elements, bool ctorinit)
{
    //printf("AggregateDeclaration::fill() %s\n", toChars());
    assert(sizeok == SIZEOKdone);
    assert(elements);
    size_t nfields = fields.dim - isNested();
    bool errors = false;

    size_t dim = elements->dim;
    elements->setDim(nfields);
    for (size_t i = dim; i < nfields; i++)
        (*elements)[i] = NULL;

    // Fill in missing any elements with default initializers
    for (size_t i = 0; i < nfields; i++)
    {
        if ((*elements)[i])
            continue;

        VarDeclaration *vd = fields[i];
        VarDeclaration *vx = vd;
        if (vd->_init && vd->_init->isVoidInitializer())
            vx = NULL;

        // Find overlapped fields with the hole [vd->offset .. vd->offset->size()].
        size_t fieldi = i;
        for (size_t j = 0; j < nfields; j++)
        {
            if (i == j)
                continue;
            VarDeclaration *v2 = fields[j];
            if (!vd->isOverlappedWith(v2))
                continue;

            if ((*elements)[j])
            {
                vx = NULL;
                break;
            }
            if (v2->_init && v2->_init->isVoidInitializer())
                continue;

            if (1)
            {
                /* Prefer first found non-void-initialized field
                 * union U { int a; int b = 2; }
                 * U u;    // Error: overlapping initialization for field a and b
                 */
                if (!vx)
                {
                    vx = v2;
                    fieldi = j;
                }
                else if (v2->_init)
                {
                    ::error(loc, "overlapping initialization for field %s and %s",
                        v2->toChars(), vd->toChars());
                    errors = true;
                }
            }
            else
            {
                // Will fix Bugzilla 1432 by enabling this path always

                /* Prefer explicitly initialized field
                 * union U { int a; int b = 2; }
                 * U u;    // OK (u.b == 2)
                 */
                if (!vx || (!vx->_init && v2->_init))
                {
                    vx = v2;
                    fieldi = j;
                }
                else if (vx != vd && !vx->isOverlappedWith(v2))
                {
                    // Both vx and v2 fills vd, but vx and v2 does not overlap
                }
                else if (vx->_init && v2->_init)
                {
                    ::error(loc, "overlapping default initialization for field %s and %s",
                        v2->toChars(), vd->toChars());
                    errors = true;
                }
                else
                    assert(vx->_init || (!vx->_init && !v2->_init));
            }
        }
        if (vx)
        {
            Expression *e;
            if (vx->type->size() == 0)
            {
                e = NULL;
            }
            else if (vx->_init)
            {
                assert(!vx->_init->isVoidInitializer());
                if (vx->inuse)   // https://issues.dlang.org/show_bug.cgi?id=18057
                {
                    vx->error(loc, "recursive initialization of field");
                    errors = true;
                    e = NULL;
                }
                else
                    e = vx->getConstInitializer(false);
            }
            else
            {
                if ((vx->storage_class & STCnodefaultctor) && !ctorinit)
                {
                    ::error(loc, "field %s.%s must be initialized because it has no default constructor",
                            type->toChars(), vx->toChars());
                    errors = true;
                }

                /* Bugzilla 12509: Get the element of static array type.
                 */
                Type *telem = vx->type;
                if (telem->ty == Tsarray)
                {
                    /* We cannot use Type::baseElemOf() here.
                     * If the bottom of the Tsarray is an enum type, baseElemOf()
                     * will return the base of the enum, and its default initializer
                     * would be different from the enum's.
                     */
                    while (telem->toBasetype()->ty == Tsarray)
                        telem = ((TypeSArray *)telem->toBasetype())->next;

                    if (telem->ty == Tvoid)
                        telem = Type::tuns8->addMod(telem->mod);
                }
                if (telem->needsNested() && ctorinit)
                    e = telem->defaultInit(loc);
                else
                    e = telem->defaultInitLiteral(loc);
            }
            (*elements)[fieldi] = e;
        }
    }

    for (size_t i = 0; i < elements->dim; i++)
    {
        Expression *e = (*elements)[i];
        if (e && e->op == TOKerror)
            return false;
    }

    return !errors;
}

/****************************
 * Do byte or word alignment as necessary.
 * Align sizes of 0, as we may not know array sizes yet.
 *
 * alignment: struct alignment that is in effect
 * size: alignment requirement of field
 */

void AggregateDeclaration::alignmember(
        structalign_t alignment,
        unsigned size,
        unsigned *poffset)
{
    //printf("alignment = %d, size = %d, offset = %d\n",alignment,size,offset);
    switch (alignment)
    {
        case (structalign_t) 1:
            // No alignment
            break;

        case (structalign_t) STRUCTALIGN_DEFAULT:
            // Alignment in Target::fieldalignsize must match what the
            // corresponding C compiler's default alignment behavior is.
            assert(size > 0 && !(size & (size - 1)));
            *poffset = (*poffset + size - 1) & ~(size - 1);
            break;

        default:
            // Align on alignment boundary, which must be a positive power of 2
            assert(alignment > 0 && !(alignment & (alignment - 1)));
            *poffset = (*poffset + alignment - 1) & ~(alignment - 1);
            break;
    }
}

/****************************************
 * Place a member (mem) into an aggregate (agg), which can be a struct, union or class
 * Returns:
 *      offset to place field at
 *
 * nextoffset:    next location in aggregate
 * memsize:       size of member
 * memalignsize:  natural alignment of member
 * alignment:     alignment in effect for this member
 * paggsize:      size of aggregate (updated)
 * paggalignsize: alignment of aggregate (updated)
 * isunion:       the aggregate is a union
 */
unsigned AggregateDeclaration::placeField(
        unsigned *nextoffset,
        unsigned memsize,
        unsigned memalignsize,
        structalign_t alignment,
        unsigned *paggsize,
        unsigned *paggalignsize,
        bool isunion
        )
{
    unsigned ofs = *nextoffset;

    const unsigned actualAlignment =
        alignment == STRUCTALIGN_DEFAULT ? memalignsize : alignment;

    alignmember(alignment, memalignsize, &ofs);
    unsigned memoffset = ofs;
    ofs += memsize;
    if (ofs > *paggsize)
        *paggsize = ofs;
    if (!isunion)
        *nextoffset = ofs;

    if (*paggalignsize < actualAlignment)
        *paggalignsize = actualAlignment;

    return memoffset;
}


/****************************************
 * Returns true if there's an extra member which is the 'this'
 * pointer to the enclosing context (enclosing aggregate or function)
 */

bool AggregateDeclaration::isNested()
{
    return enclosing != NULL;
}

/* Append vthis field (this->tupleof[$-1]) to make this aggregate type nested.
 */
void AggregateDeclaration::makeNested()
{
    if (enclosing)  // if already nested
        return;
    if (sizeok == SIZEOKdone)
        return;
    if (isUnionDeclaration() || isInterfaceDeclaration())
        return;
    if (storage_class & STCstatic)
        return;

    // If nested struct, add in hidden 'this' pointer to outer scope
    Dsymbol *s = toParent2();
    if (!s)
        return;
    Type *t = NULL;
    if (FuncDeclaration *fd = s->isFuncDeclaration())
    {
        enclosing = fd;

        /* Bugzilla 14422: If a nested class parent is a function, its
         * context pointer (== `outer`) should be void* always.
         */
        t = Type::tvoidptr;
    }
    else if (AggregateDeclaration *ad = s->isAggregateDeclaration())
    {
        if (isClassDeclaration() && ad->isClassDeclaration())
        {
            enclosing = ad;
        }
        else if (isStructDeclaration())
        {
            if (TemplateInstance *ti = ad->parent->isTemplateInstance())
            {
                enclosing = ti->enclosing;
            }
        }

        t = ad->handleType();
    }
    if (enclosing)
    {
        //printf("makeNested %s, enclosing = %s\n", toChars(), enclosing->toChars());
        assert(t);
        if (t->ty == Tstruct)
            t = Type::tvoidptr;     // t should not be a ref type
        assert(!vthis);
        vthis = new ThisDeclaration(loc, t);
        //vthis->storage_class |= STCref;

        // Emulate vthis->addMember()
        members->push(vthis);

        // Emulate vthis->semantic()
        vthis->storage_class |= STCfield;
        vthis->parent = this;
        vthis->protection = Prot(PROTpublic);
        vthis->alignment = t->alignment();
        vthis->semanticRun = PASSsemanticdone;

        if (sizeok == SIZEOKfwd)
            fields.push(vthis);
    }
}

/*******************************************
 * Look for constructor declaration.
 */
Dsymbol *AggregateDeclaration::searchCtor()
{
    Dsymbol *s = search(Loc(), Id::ctor);
    if (s)
    {
        if (!(s->isCtorDeclaration() ||
              s->isTemplateDeclaration() ||
              s->isOverloadSet()))
        {
            s->error("is not a constructor; identifiers starting with __ are reserved for the implementation");
            errors = true;
            s = NULL;
        }
    }
    if (s && s->toParent() != this)
        s = NULL; // search() looks through ancestor classes
    if (s)
    {
        // Finish all constructors semantics to determine this->noDefaultCtor.
        struct SearchCtor
        {
            static int fp(Dsymbol *s, void *)
            {
                CtorDeclaration *f = s->isCtorDeclaration();
                if (f && f->semanticRun == PASSinit)
                    f->semantic(NULL);
                return 0;
            }
        };

        for (size_t i = 0; i < members->dim; i++)
        {
            Dsymbol *sm = (*members)[i];
            sm->apply(&SearchCtor::fp, NULL);
        }
    }
    return s;
}

/********************************* StructDeclaration ****************************/

StructDeclaration::StructDeclaration(Loc loc, Identifier *id, bool inObject)
    : AggregateDeclaration(loc, id)
{
    zeroInit = 0;       // assume false until we do semantic processing
    hasIdentityAssign = false;
    hasIdentityEquals = false;
    postblit = NULL;

    xeq = NULL;
    xcmp = NULL;
    xhash = NULL;
    alignment = 0;
    ispod = ISPODfwd;
    arg1type = NULL;
    arg2type = NULL;
    requestTypeInfo = false;

    // For forward references
    type = new TypeStruct(this);

    if (inObject)
    {
        if (id == Id::ModuleInfo && !Module::moduleinfo)
            Module::moduleinfo = this;
    }
}

StructDeclaration *StructDeclaration::create(Loc loc, Identifier *id, bool inObject)
{
    return new StructDeclaration(loc, id, inObject);
}

Dsymbol *StructDeclaration::syntaxCopy(Dsymbol *s)
{
    StructDeclaration *sd =
        s ? (StructDeclaration *)s
          : new StructDeclaration(loc, ident, false);
    return ScopeDsymbol::syntaxCopy(sd);
}

void StructDeclaration::semantic(Scope *sc)
{
    //printf("StructDeclaration::semantic(this=%p, %s '%s', sizeok = %d)\n", this, parent->toChars(), toChars(), sizeok);

    //static int count; if (++count == 20) halt();

    if (semanticRun >= PASSsemanticdone)
        return;
    unsigned errors = global.errors;

    //printf("+StructDeclaration::semantic(this=%p, %s '%s', sizeok = %d)\n", this, parent->toChars(), toChars(), sizeok);
    Scope *scx = NULL;
    if (_scope)
    {
        sc = _scope;
        scx = _scope;            // save so we don't make redundant copies
        _scope = NULL;
    }

    if (!parent)
    {
        assert(sc->parent && sc->func);
        parent = sc->parent;
    }
    assert(parent && !isAnonymous());

    if (this->errors)
        type = Type::terror;
    if (semanticRun == PASSinit)
        type = type->addSTC(sc->stc | storage_class);
    type = type->semantic(loc, sc);

    if (type->ty == Tstruct && ((TypeStruct *)type)->sym != this)
    {
        TemplateInstance *ti = ((TypeStruct *)type)->sym->isInstantiated();
        if (ti && isError(ti))
            ((TypeStruct *)type)->sym = this;
    }

    // Ungag errors when not speculative
    Ungag ungag = ungagSpeculative();

    if (semanticRun == PASSinit)
    {
        protection = sc->protection;

        alignment = sc->alignment();

        storage_class |= sc->stc;
        if (storage_class & STCdeprecated)
            isdeprecated = true;
        if (storage_class & STCabstract)
            error("structs, unions cannot be abstract");
        userAttribDecl = sc->userAttribDecl;
    }
    else if (symtab && !scx)
    {
        return;
    }
    semanticRun = PASSsemantic;

    if (!members)               // if opaque declaration
    {
        semanticRun = PASSsemanticdone;
        return;
    }
    if (!symtab)
    {
        symtab = new DsymbolTable();

        for (size_t i = 0; i < members->dim; i++)
        {
            Dsymbol *s = (*members)[i];
            //printf("adding member '%s' to '%s'\n", s->toChars(), this->toChars());
            s->addMember(sc, this);
        }
    }

    Scope *sc2 = newScope(sc);

    /* Set scope so if there are forward references, we still might be able to
     * resolve individual members like enums.
     */
    for (size_t i = 0; i < members->dim; i++)
    {
        Dsymbol *s = (*members)[i];
        //printf("struct: setScope %s %s\n", s->kind(), s->toChars());
        s->setScope(sc2);
    }

    for (size_t i = 0; i < members->dim; i++)
    {
        Dsymbol *s = (*members)[i];
        s->importAll(sc2);
    }

    for (size_t i = 0; i < members->dim; i++)
    {
        Dsymbol *s = (*members)[i];
        s->semantic(sc2);
    }

    if (!determineFields())
    {
        assert(type->ty == Terror);
        sc2->pop();
        semanticRun = PASSsemanticdone;
        return;
    }

    /* Following special member functions creation needs semantic analysis
     * completion of sub-structs in each field types. For example, buildDtor
     * needs to check existence of elaborate dtor in type of each fields.
     * See the case in compilable/test14838.d
     */
    for (size_t i = 0; i < fields.dim; i++)
    {
        VarDeclaration *v = fields[i];
        Type *tb = v->type->baseElemOf();
        if (tb->ty != Tstruct)
            continue;
        StructDeclaration *sd = ((TypeStruct *)tb)->sym;
        if (sd->semanticRun >= PASSsemanticdone)
            continue;

        sc2->pop();

        _scope = scx ? scx : sc->copy();
        _scope->setNoFree();
        _scope->_module->addDeferredSemantic(this);

        //printf("\tdeferring %s\n", toChars());
        return;
    }

    /* Look for special member functions.
     */
    aggNew =       (NewDeclaration *)search(Loc(), Id::classNew);
    aggDelete = (DeleteDeclaration *)search(Loc(), Id::classDelete);

    // Look for the constructor
    ctor = searchCtor();

    dtor = buildDtor(this, sc2);
    postblit = buildPostBlit(this, sc2);

    buildOpAssign(this, sc2);
    buildOpEquals(this, sc2);

    if (global.params.useTypeInfo && Type::dtypeinfo)  // these functions are used for TypeInfo
    {
        xeq = buildXopEquals(this, sc2);
        xcmp = buildXopCmp(this, sc2);
        xhash = buildXtoHash(this, sc2);
    }

    inv = buildInv(this, sc2);

    Module::dprogress++;
    semanticRun = PASSsemanticdone;
    //printf("-StructDeclaration::semantic(this=%p, '%s')\n", this, toChars());

    sc2->pop();

    if (ctor)
    {
        Dsymbol *scall = search(Loc(), Id::call);
        if (scall)
        {
            unsigned xerrors = global.startGagging();
            sc = sc->push();
            sc->tinst = NULL;
            sc->minst = NULL;
            FuncDeclaration *fcall = resolveFuncCall(loc, sc, scall, NULL, NULL, NULL, 1);
            sc = sc->pop();
            global.endGagging(xerrors);

            if (fcall && fcall->isStatic())
            {
                error(fcall->loc, "static opCall is hidden by constructors and can never be called");
                errorSupplemental(fcall->loc, "Please use a factory method instead, or replace all constructors with static opCall.");
            }
        }
    }

    if (global.errors != errors)
    {
        // The type is no good.
        type = Type::terror;
        this->errors = true;
        if (deferred)
            deferred->errors = true;
    }

    if (deferred && !global.gag)
    {
        deferred->semantic2(sc);
        deferred->semantic3(sc);
    }

    assert(type->ty != Tstruct || ((TypeStruct *)type)->sym == this);
}

Dsymbol *StructDeclaration::search(const Loc &loc, Identifier *ident, int flags)
{
    //printf("%s.StructDeclaration::search('%s', flags = x%x)\n", toChars(), ident->toChars(), flags);

    if (_scope && !symtab)
        semantic(_scope);

    if (!members || !symtab)    // opaque or semantic() is not yet called
    {
        error("is forward referenced when looking for '%s'", ident->toChars());
        return NULL;
    }

    return ScopeDsymbol::search(loc, ident, flags);
}

void StructDeclaration::finalizeSize()
{
    //printf("StructDeclaration::finalizeSize() %s, sizeok = %d\n", toChars(), sizeok);
    assert(sizeok != SIZEOKdone);

    //printf("+StructDeclaration::finalizeSize() %s, fields.dim = %d, sizeok = %d\n", toChars(), fields.dim, sizeok);

    fields.setDim(0);   // workaround

    // Set the offsets of the fields and determine the size of the struct
    unsigned offset = 0;
    bool isunion = isUnionDeclaration() != NULL;
    for (size_t i = 0; i < members->dim; i++)
    {
        Dsymbol *s = (*members)[i];
        s->setFieldOffset(this, &offset, isunion);
    }
    if (type->ty == Terror)
        return;

    // 0 sized struct's are set to 1 byte
    if (structsize == 0)
    {
        structsize = 1;
        alignsize = 1;
    }

    // Round struct size up to next alignsize boundary.
    // This will ensure that arrays of structs will get their internals
    // aligned properly.
    if (alignment == STRUCTALIGN_DEFAULT)
        structsize = (structsize + alignsize - 1) & ~(alignsize - 1);
    else
        structsize = (structsize + alignment - 1) & ~(alignment - 1);

    sizeok = SIZEOKdone;

    //printf("-StructDeclaration::finalizeSize() %s, fields.dim = %d, structsize = %d\n", toChars(), fields.dim, structsize);

    if (errors)
        return;

    // Calculate fields[i]->overlapped
    if (checkOverlappedFields())
    {
        errors = true;
        return;
    }

    // Determine if struct is all zeros or not
    zeroInit = 1;
    for (size_t i = 0; i < fields.dim; i++)
    {
        VarDeclaration *vd = fields[i];
        if (vd->_init)
        {
            // Should examine init to see if it is really all 0's
            zeroInit = 0;
            break;
        }
        else if (!vd->type->isZeroInit(loc))
        {
            zeroInit = 0;
            break;
        }
    }

    TypeTuple *tt = toArgTypes(type);
    size_t dim = tt->arguments->dim;
    if (dim >= 1)
    {
        assert(dim <= 2);
        arg1type = (*tt->arguments)[0]->type;
        if (dim == 2)
            arg2type = (*tt->arguments)[1]->type;
    }
}

/***************************************
 * Fit elements[] to the corresponding type of field[].
 * Input:
 *      loc
 *      sc
 *      elements    The explicit arguments that given to construct object.
 *      stype       The constructed object type.
 * Returns false if any errors occur.
 * Otherwise, returns true and elements[] are rewritten for the output.
 */
bool StructDeclaration::fit(Loc loc, Scope *sc, Expressions *elements, Type *stype)
{
    if (!elements)
        return true;

    size_t nfields = fields.dim - isNested();
    size_t offset = 0;
    for (size_t i = 0; i < elements->dim; i++)
    {
        Expression *e = (*elements)[i];
        if (!e)
            continue;

        e = resolveProperties(sc, e);
        if (i >= nfields)
        {
            if (i == fields.dim - 1 && isNested() && e->op == TOKnull)
            {
                // CTFE sometimes creates null as hidden pointer; we'll allow this.
                continue;
            }
            ::error(loc, "more initializers than fields (%d) of %s", (int)nfields, toChars());
            return false;
        }
        VarDeclaration *v = fields[i];
        if (v->offset < offset)
        {
            ::error(loc, "overlapping initialization for %s", v->toChars());
            return false;
        }
        offset = (unsigned)(v->offset + v->type->size());

        Type *t = v->type;
        if (stype)
            t = t->addMod(stype->mod);
        Type *origType = t;
        Type *tb = t->toBasetype();

        /* Look for case of initializing a static array with a too-short
         * string literal, such as:
         *  char[5] foo = "abc";
         * Allow this by doing an explicit cast, which will lengthen the string
         * literal.
         */
        if (e->op == TOKstring && tb->ty == Tsarray)
        {
            StringExp *se = (StringExp *)e;
            Type *typeb = se->type->toBasetype();
            TY tynto = tb->nextOf()->ty;
            if (!se->committed &&
                (typeb->ty == Tarray || typeb->ty == Tsarray) &&
                (tynto == Tchar || tynto == Twchar || tynto == Tdchar) &&
                se->numberOfCodeUnits(tynto) < ((TypeSArray *)tb)->dim->toInteger())
            {
                e = se->castTo(sc, t);
                goto L1;
            }
        }

        while (!e->implicitConvTo(t) && tb->ty == Tsarray)
        {
            /* Static array initialization, as in:
             *  T[3][5] = e;
             */
            t = tb->nextOf();
            tb = t->toBasetype();
        }
        if (!e->implicitConvTo(t))
            t = origType;  // restore type for better diagnostic

        e = e->implicitCastTo(sc, t);
    L1:
        if (e->op == TOKerror)
            return false;

        (*elements)[i] = doCopyOrMove(sc, e);
    }
    return true;
}

/***************************************
 * Return true if struct is POD (Plain Old Data).
 * This is defined as:
 *      not nested
 *      no postblits, destructors, or assignment operators
 *      no 'ref' fields or fields that are themselves non-POD
 * The idea being these are compatible with C structs.
 */
bool StructDeclaration::isPOD()
{
    // If we've already determined whether this struct is POD.
    if (ispod != ISPODfwd)
        return (ispod == ISPODyes);

    ispod = ISPODyes;

    if (enclosing || postblit || dtor)
        ispod = ISPODno;

    // Recursively check all fields are POD.
    for (size_t i = 0; i < fields.dim; i++)
    {
        VarDeclaration *v = fields[i];
        if (v->storage_class & STCref)
        {
            ispod = ISPODno;
            break;
        }

        Type *tv = v->type->baseElemOf();
        if (tv->ty == Tstruct)
        {
            TypeStruct *ts = (TypeStruct *)tv;
            StructDeclaration *sd = ts->sym;
            if (!sd->isPOD())
            {
                ispod = ISPODno;
                break;
            }
        }
    }

    return (ispod == ISPODyes);
}

const char *StructDeclaration::kind() const
{
    return "struct";
}

/********************************* UnionDeclaration ****************************/

UnionDeclaration::UnionDeclaration(Loc loc, Identifier *id)
    : StructDeclaration(loc, id, false)
{
}

Dsymbol *UnionDeclaration::syntaxCopy(Dsymbol *s)
{
    assert(!s);
    UnionDeclaration *ud = new UnionDeclaration(loc, ident);
    return StructDeclaration::syntaxCopy(ud);
}

const char *UnionDeclaration::kind() const
{
    return "union";
}
