Пример #1
0
void StructDeclaration::toDt(dt_t **pdt)
{
    if (zeroInit)
    {
        dtnzeros(pdt, structsize);
        return;
    }

    unsigned offset;
    dt_t *dt;
    dt_t *sdt = NULL;

    //printf("StructDeclaration::toDt(), this='%s'\n", toChars());
    offset = 0;

    // Note equivalence of this loop to class's
    for (size_t i = 0; i < fields.dim; i++)
    {
        VarDeclaration *v = (VarDeclaration *)fields.data[i];
        Initializer *init;

        //printf("\tfield '%s' voffset %d, offset = %d\n", v->toChars(), v->offset, offset);
        dt = NULL;
        init = v->init;
        if (init)
        {   //printf("\t\thas initializer %s\n", init->toChars());
            ExpInitializer *ei = init->isExpInitializer();
            Type *tb = v->type->toBasetype();
            if (ei && tb->ty == Tsarray)
                ((TypeSArray *)tb)->toDtElem(&dt, ei->exp);
            else
                dt = init->toDt();
        }
        else if (v->offset >= offset)
            v->type->toDt(&dt);
        if (dt)
        {
            if (v->offset < offset)
                error("overlapping initialization for struct %s.%s", toChars(), v->toChars());
            else
            {
                if (offset < v->offset)
                    dtnzeros(&sdt, v->offset - offset);
                dtcat(&sdt, dt);
                offset = v->offset + v->type->size();
            }
        }
    }

    if (offset < structsize)
        dtnzeros(&sdt, structsize - offset);
#ifdef IN_GCC
    dtcontainer(pdt, type, sdt);
#else
    dtcat(pdt, sdt);
#endif
    dt_optimize(*pdt);
}
Пример #2
0
Файл: todt.c Проект: torarin/dmd
void StructDeclaration::toDt(dt_t **pdt)
{
    unsigned offset;
    unsigned i;
    dt_t *dt;

    //printf("StructDeclaration::toDt(), this='%s'\n", toChars());
    offset = 0;

    // Note equivalence of this loop to class's
    for (i = 0; i < fields.dim; i++)
    {
        VarDeclaration *v = (VarDeclaration *)fields.data[i];
        //printf("\tfield '%s' voffset %d, offset = %d\n", v->toChars(), v->offset, offset);
        dt = NULL;
        int sz;

        if (v->storage_class & STCref)
        {
            sz = PTRSIZE;
            if (v->offset >= offset)
                dtnzeros(&dt, sz);
        }
        else
        {
            sz = v->type->size();
            Initializer *init = v->init;
            if (init)
            {   //printf("\t\thas initializer %s\n", init->toChars());
                ExpInitializer *ei = init->isExpInitializer();
                Type *tb = v->type->toBasetype();
                if (ei && tb->ty == Tsarray)
                    ((TypeSArray *)tb)->toDtElem(&dt, ei->exp);
                else
                    dt = init->toDt();
            }
            else if (v->offset >= offset)
                v->type->toDt(&dt);
        }
        if (dt)
        {
            if (v->offset < offset)
                error("overlapping initialization for struct %s.%s", toChars(), v->toChars());
            else
            {
                if (offset < v->offset)
                    dtnzeros(pdt, v->offset - offset);
                dtcat(pdt, dt);
                offset = v->offset + sz;
            }
        }
    }

    if (offset < structsize)
        dtnzeros(pdt, structsize - offset);

    dt_optimize(*pdt);
}
Пример #3
0
void ClassDeclaration::toDt2(dt_t **pdt, ClassDeclaration *cd)
{
    unsigned offset;
    dt_t *dt;
    unsigned csymoffset;

#define LOG 0

#if LOG
    printf("ClassDeclaration::toDt2(this = '%s', cd = '%s')\n", toChars(), cd->toChars());
#endif
    if (baseClass)
    {
        baseClass->toDt2(pdt, cd);
        offset = baseClass->structsize;
    }
    else
    {
        offset = PTRSIZE * 2;
    }

    // Note equivalence of this loop to struct's
    for (size_t i = 0; i < fields.dim; i++)
    {
        VarDeclaration *v = (VarDeclaration *)fields.data[i];
        Initializer *init;

        //printf("\t\tv = '%s' v->offset = %2d, offset = %2d\n", v->toChars(), v->offset, offset);
        dt = NULL;
        init = v->init;
        if (init)
        {   //printf("\t\t%s has initializer %s\n", v->toChars(), init->toChars());
            ExpInitializer *ei = init->isExpInitializer();
            Type *tb = v->type->toBasetype();
            if (ei && tb->ty == Tsarray)
                ((TypeSArray *)tb)->toDtElem(&dt, ei->exp);
            else
                dt = init->toDt();
        }
        else if (v->offset >= offset)
        {   //printf("\t\tdefault initializer\n");
            v->type->toDt(&dt);
        }
        if (dt)
        {
            if (v->offset < offset)
                error("duplicated union initialization for %s", v->toChars());
            else
            {
                if (offset < v->offset)
                    dtnzeros(pdt, v->offset - offset);
                dtcat(pdt, dt);
                offset = v->offset + v->type->size();
            }
        }
    }

    // Interface vptr initializations
    toSymbol();                                         // define csym

    for (size_t i = 0; i < vtblInterfaces->dim; i++)
    {   BaseClass *b = (BaseClass *)vtblInterfaces->data[i];

#if 1 || INTERFACE_VIRTUAL
        for (ClassDeclaration *cd2 = cd; 1; cd2 = cd2->baseClass)
        {
            assert(cd2);
            csymoffset = cd2->baseVtblOffset(b);
            if (csymoffset != ~0)
            {
                if (offset < b->offset)
                    dtnzeros(pdt, b->offset - offset);
                dtxoff(pdt, cd2->toSymbol(), csymoffset, TYnptr);
                break;
            }
        }
#else
        csymoffset = baseVtblOffset(b);
        assert(csymoffset != ~0);
        dtxoff(pdt, csym, csymoffset, TYnptr);
#endif
        offset = b->offset + PTRSIZE;
    }

    if (offset < structsize)
        dtnzeros(pdt, structsize - offset);

#undef LOG
}
Пример #4
0
dt_t *ArrayInitializer::toDt()
{
    //printf("ArrayInitializer::toDt('%s')\n", toChars());
    Type *tb = type->toBasetype();
    Type *tn = tb->next->toBasetype();

    if (tn->ty == Tbit)
        return toDtBit();

    Array dts;
    unsigned size;
    unsigned length;
    dt_t *dt;
    dt_t *d;
    dt_t **pdtend;

    //printf("\tdim = %d\n", dim);
    dts.setDim(dim);
    dts.zero();

    size = tn->size();

    length = 0;
    for (size_t i = 0; i < index.dim; i++)
    {   Expression *idx;
        Initializer *val;

        idx = (Expression *)index.data[i];
        if (idx)
            length = idx->toInteger();
        //printf("\tindex[%d] = %p, length = %u, dim = %u\n", i, idx, length, dim);

        assert(length < dim);
        val = (Initializer *)value.data[i];
        dt = val->toDt();
        if (dts.data[length])
            error(loc, "duplicate initializations for index %d", length);
        dts.data[length] = (void *)dt;
        length++;
    }

    Expression *edefault = tb->next->defaultInit();
#ifdef IN_GCC
    dt_t * sadefault = NULL;

    if (tn->ty == Tsarray)
        tn->toDt(& sadefault);
    else
        edefault->toDt(& sadefault);
#else
    unsigned n = 1;
    for (Type *tbn = tn; tbn->ty == Tsarray; tbn = tbn->next->toBasetype())
    {   TypeSArray *tsa = (TypeSArray *)tbn;

        n *= tsa->dim->toInteger();
    }
#endif

    d = NULL;
    pdtend = &d;
    for (size_t i = 0; i < dim; i++)
    {
        dt = (dt_t *)dts.data[i];
#ifdef IN_GCC
        pdtend = dtcontainer(pdtend, NULL, dt ? dt : sadefault);
#else
        if (dt)
            pdtend = dtcat(pdtend, dt);
        else
        {
            for (size_t j = 0; j < n; j++)
                pdtend = edefault->toDt(pdtend);
        }
#endif
    }
    switch (tb->ty)
    {
    case Tsarray:
    {   unsigned tadim;
        TypeSArray *ta = (TypeSArray *)tb;

        tadim = ta->dim->toInteger();
        if (dim < tadim)
        {
            if (edefault->isBool(FALSE))
                // pad out end of array
                // (ok for GDC as well)
                pdtend = dtnzeros(pdtend, size * (tadim - dim));
            else
            {
                for (size_t i = dim; i < tadim; i++)
#ifdef IN_GCC
                    pdtend = dtcontainer(pdtend, NULL, sadefault);
#else
                {   for (size_t j = 0; j < n; j++)
                        pdtend = edefault->toDt(pdtend);
                }
#endif
            }
        }
        else if (dim > tadim)
        {
#ifdef DEBUG
            printf("1: ");
#endif
            error(loc, "too many initializers, %d, for array[%d]", dim, tadim);
        }
#ifdef IN_GCC
        dt_t * cdt = NULL;
        dtcontainer(& cdt, type, d);
        d = cdt;
#endif
        break;
    }

    case Tpointer:
    case Tarray:
    {   // Create symbol, and then refer to it
        Symbol *s = static_sym();
        s->Sdt = d;
        outdata(s);

        d = NULL;
        if (tb->ty == Tarray)
            dtsize_t(&d, dim);
        dtxoff(&d, s, 0, TYnptr);
#ifdef IN_GCC
        dt_t * cdt;
        cdt = NULL;
        if (tb->ty == Tarray)
        {
            dtcontainer(& cdt, type, d);
            d = cdt;
        }
#endif
        break;
    }

    default:
        assert(0);
    }
    return d;
}
Пример #5
0
dt_t *StructInitializer::toDt()
{
    Array dts;
    dt_t *dt;
    dt_t *d;
    dt_t **pdtend;
    unsigned offset;

    //printf("StructInitializer::toDt('%s')\n", toChars());
    dts.setDim(ad->fields.dim);
    dts.zero();

    for (size_t i = 0; i < vars.dim; i++)
    {
        VarDeclaration *v = (VarDeclaration *)vars.data[i];
        Initializer *val = (Initializer *)value.data[i];

        //printf("vars[%d] = %s\n", i, v->toChars());

        for (size_t j = 0; 1; j++)
        {
            assert(j < dts.dim);
            //printf(" adfield[%d] = %s\n", j, ((VarDeclaration *)ad->fields.data[j])->toChars());
            if ((VarDeclaration *)ad->fields.data[j] == v)
            {
                if (dts.data[j])
                    error(loc, "field %s of %s already initialized", v->toChars(), ad->toChars());
                dts.data[j] = (void *)val->toDt();
                break;
            }
        }
    }

    dt = NULL;
    pdtend = &dt;
    offset = 0;
    for (size_t j = 0; j < dts.dim; j++)
    {
        VarDeclaration *v = (VarDeclaration *)ad->fields.data[j];

        d = (dt_t *)dts.data[j];
        if (!d)
        {   // An instance specific initializer was not provided.
            // Look to see if there's a default initializer from the
            // struct definition
            if (v->init)
            {
                d = v->init->toDt();
            }
            else if (v->offset >= offset)
            {
                unsigned k;
                unsigned offset2 = v->offset + v->type->size();
                // Make sure this field does not overlap any explicitly
                // initialized field.
                for (k = j + 1; 1; k++)
                {
                    if (k == dts.dim)           // didn't find any overlap
                    {
                        v->type->toDt(&d);
                        break;
                    }
                    VarDeclaration *v2 = (VarDeclaration *)ad->fields.data[k];

                    if (v2->offset < offset2 && dts.data[k])
                        break;                  // overlap
                }
            }
        }
        if (d)
        {
            if (v->offset < offset)
                error(loc, "duplicate union initialization for %s", v->toChars());
            else
            {   size_t sz = dt_size(d);
                size_t vsz = v->type->size();
                size_t voffset = v->offset;

                if (sz > vsz)
                {   assert(v->type->ty == Tsarray && vsz == 0);
                    error(loc, "zero length array %s has non-zero length initializer", v->toChars());
                }

                unsigned dim = 1;
                for (Type *vt = v->type->toBasetype();
                        vt->ty == Tsarray;
                        vt = vt->next->toBasetype())
                {   TypeSArray *tsa = (TypeSArray *)vt;
                    dim *= tsa->dim->toInteger();
                }
                //printf("sz = %d, dim = %d, vsz = %d\n", sz, dim, vsz);
                assert(sz == vsz || sz * dim <= vsz);

                for (size_t i = 0; i < dim; i++)
                {
                    if (offset < voffset)
                        pdtend = dtnzeros(pdtend, voffset - offset);
                    if (!d)
                    {
                        if (v->init)
                            d = v->init->toDt();
                        else
                            v->type->toDt(&d);
                    }
                    pdtend = dtcat(pdtend, d);
                    d = NULL;
                    offset = voffset + sz;
                    voffset += vsz / dim;
                    if (sz == vsz)
                        break;
                }
            }
        }
    }
    if (offset < ad->structsize)
        dtnzeros(pdtend, ad->structsize - offset);

#ifdef IN_GCC
    dt_t * cdt = NULL;
    dtcontainer(&cdt, ad->type, dt);
    dt = cdt;
#endif
    return dt;
}
Пример #6
0
dt_t *ArrayInitializer::toDt()
{
    //printf("ArrayInitializer::toDt('%s')\n", toChars());
    Type *tb = type->toBasetype();
    if (tb->ty == Tvector)
        tb = ((TypeVector *)tb)->basetype;

    Type *tn = tb->nextOf()->toBasetype();

    //printf("\tdim = %d\n", dim);
    Dts dts;
    dts.setDim(dim);
    dts.zero();

    unsigned size = tn->size();

    unsigned length = 0;
    for (size_t i = 0; i < index.dim; i++)
    {
        Expression *idx = index[i];
        if (idx)
            length = idx->toInteger();
        //printf("\tindex[%d] = %p, length = %u, dim = %u\n", i, idx, length, dim);

        assert(length < dim);
        Initializer *val = value[i];
        dt_t *dt = val->toDt();
        if (dts[length])
            error(loc, "duplicate initializations for index %d", length);
        dts[length] = dt;
        length++;
    }

    Expression *edefault = tb->nextOf()->defaultInit();

    size_t n = 1;
    for (Type *tbn = tn; tbn->ty == Tsarray; tbn = tbn->nextOf()->toBasetype())
    {   TypeSArray *tsa = (TypeSArray *)tbn;

        n *= tsa->dim->toInteger();
    }

    dt_t *d = NULL;
    dt_t **pdtend = &d;
    for (size_t i = 0; i < dim; i++)
    {
        dt_t *dt = dts[i];
        if (dt)
            pdtend = dtcat(pdtend, dt);
        else
        {
            for (size_t j = 0; j < n; j++)
                pdtend = edefault->toDt(pdtend);
        }
    }
    switch (tb->ty)
    {
        case Tsarray:
        {   size_t tadim;
            TypeSArray *ta = (TypeSArray *)tb;

            tadim = ta->dim->toInteger();
            if (dim < tadim)
            {
                if (edefault->isBool(false))
                    // pad out end of array
                    pdtend = dtnzeros(pdtend, size * (tadim - dim));
                else
                {
                    for (size_t i = dim; i < tadim; i++)
                    {   for (size_t j = 0; j < n; j++)
                            pdtend = edefault->toDt(pdtend);
                    }
                }
            }
            else if (dim > tadim)
            {
                error(loc, "too many initializers, %d, for array[%d]", dim, tadim);
            }
            break;
        }

        case Tpointer:
        case Tarray:
        {
            dt_t *dtarray = d;
            d = NULL;
            if (tb->ty == Tarray)
                dtsize_t(&d, dim);
            dtdtoff(&d, dtarray, 0);
            break;
        }

        default:
            assert(0);
    }
    return d;
}
Пример #7
0
dt_t *ArrayInitializer::toDt()
{
    //printf("ArrayInitializer::toDt('%s')\n", toChars());
    Type *tb = type->toBasetype();
    if (tb->ty == Tvector)
        tb = ((TypeVector *)tb)->basetype;

    Type *tn = tb->nextOf()->toBasetype();

    Dts dts;
    unsigned size;
    unsigned length;
    dt_t *dt;
    dt_t *d;
    dt_t **pdtend;

    //printf("\tdim = %d\n", dim);
    dts.setDim(dim);
    dts.zero();

    size = tn->size();

    length = 0;
    for (size_t i = 0; i < index.dim; i++)
    {   Expression *idx;
        Initializer *val;

        idx = index[i];
        if (idx)
            length = idx->toInteger();
        //printf("\tindex[%d] = %p, length = %u, dim = %u\n", i, idx, length, dim);

        assert(length < dim);
        val = value[i];
        dt = val->toDt();
        if (dts[length])
            error(loc, "duplicate initializations for index %d", length);
        if (tn->ty == Tsarray)
            dt = createTsarrayDt(dt, tb->nextOf());
        dts[length] = dt;
        length++;
    }

    Expression *edefault = tb->nextOf()->defaultInit();
#ifdef IN_GCC
    dt_t * sadefault = NULL;

    if (tn->ty == Tsarray)
        tn->toDt(& sadefault);
    else
        edefault->toDt(& sadefault);
#else
    unsigned n = 1;
    for (Type *tbn = tn; tbn->ty == Tsarray; tbn = tbn->nextOf()->toBasetype())
    {   TypeSArray *tsa = (TypeSArray *)tbn;

        n *= tsa->dim->toInteger();
    }
#endif

    d = NULL;
    pdtend = &d;
    for (size_t i = 0; i < dim; i++)
    {
        dt = dts[i];
#ifdef IN_GCC
        pdtend = dtcontainer(pdtend, NULL, dt ? dt : sadefault);
#else
        if (dt)
            pdtend = dtcat(pdtend, dt);
        else
        {
            for (size_t j = 0; j < n; j++)
                pdtend = edefault->toDt(pdtend);
        }
#endif
    }
    switch (tb->ty)
    {
        case Tsarray:
        {   unsigned tadim;
            TypeSArray *ta = (TypeSArray *)tb;

            tadim = ta->dim->toInteger();
            if (dim < tadim)
            {
 	

#ifdef IN_GCC
                // Pad out the rest of the array with single elements.
                // Otherwise breaks -fsection-anchors on ARM when
                // backend calculates field positions for array members.
                for (size_t i = dim; i < tadim; i++)
                    pdtend = dtcontainer(pdtend, NULL, sadefault);
#else
                if (edefault->isBool(FALSE))
                    // pad out end of array
                    pdtend = dtnzeros(pdtend, size * (tadim - dim));
                else
                {
                    for (size_t i = dim; i < tadim; i++)
                    {   for (size_t j = 0; j < n; j++)
                            pdtend = edefault->toDt(pdtend);
                    }
                }
#endif
            }
            else if (dim > tadim)
            {
                error(loc, "too many initializers, %d, for array[%d]", dim, tadim);
            }
#ifdef IN_GCC
            dt_t * cdt = NULL;
            dtcontainer(& cdt, type, d);
            d = cdt;
#endif
            break;
        }

        case Tpointer:
        case Tarray:
        {   // Create symbol, and then refer to it
            Symbol *s = static_sym();
            s->Sdt = d;
            outdata(s);

            d = NULL;
            if (tb->ty == Tarray)
                dtsize_t(&d, dim);
            dtxoff(&d, s, 0, TYnptr);
#ifdef IN_GCC
            dt_t * cdt;
            cdt = NULL;
            if (tb->ty == Tarray)
            {
                dtcontainer(& cdt, type, d);
                d = cdt;
            }
#endif
            break;
        }

        default:
            assert(0);
    }
    return d;
}
Пример #8
0
Файл: todt.c Проект: michelf/dmd
dt_t *ArrayInitializer::toDt()
{
    //printf("ArrayInitializer::toDt('%s')\n", toChars());
    Type *tb = type->toBasetype();
    Type *tn = tb->nextOf()->toBasetype();

    Dts dts;
    unsigned size;
    unsigned length;
    unsigned i;
    dt_t *dt;
    dt_t *d;
    dt_t **pdtend;

    //printf("\tdim = %d\n", dim);
    dts.setDim(dim);
    dts.zero();

    size = tn->size();

    length = 0;
    for (i = 0; i < index.dim; i++)
    {   Expression *idx;
        Initializer *val;

        idx = index.tdata()[i];
        if (idx)
            length = idx->toInteger();
        //printf("\tindex[%d] = %p, length = %u, dim = %u\n", i, idx, length, dim);

        assert(length < dim);
        val = value.tdata()[i];
        dt = val->toDt();
        if (dts.tdata()[length])
            error(loc, "duplicate initializations for index %d", length);
        dts.tdata()[length] = dt;
        length++;
    }

    Expression *edefault = tb->nextOf()->defaultInit();

    unsigned n = 1;
    for (Type *tbn = tn; tbn->ty == Tsarray; tbn = tbn->nextOf()->toBasetype())
    {   TypeSArray *tsa = (TypeSArray *)tbn;

        n *= tsa->dim->toInteger();
    }

    d = NULL;
    pdtend = &d;
    for (i = 0; i < dim; i++)
    {
        dt = dts.tdata()[i];
        if (dt)
            pdtend = dtcat(pdtend, dt);
        else
        {
            for (int j = 0; j < n; j++)
                pdtend = edefault->toDt(pdtend);
        }
    }
    switch (tb->ty)
    {
        case Tsarray:
        {   unsigned tadim;
            TypeSArray *ta = (TypeSArray *)tb;

            tadim = ta->dim->toInteger();
            if (dim < tadim)
            {
                if (edefault->isBool(FALSE))
                    // pad out end of array
                    pdtend = dtnzeros(pdtend, size * (tadim - dim));
                else
                {
                    for (i = dim; i < tadim; i++)
                    {   for (int j = 0; j < n; j++)
                            pdtend = edefault->toDt(pdtend);
                    }
                }
            }
            else if (dim > tadim)
            {
#ifdef DEBUG
                printf("1: ");
#endif
                error(loc, "too many initializers, %d, for array[%d]", dim, tadim);
            }
            break;
        }

        case Tpointer:
        case Tarray:
            // Create symbol, and then refer to it
            Symbol *s;
            s = static_sym();
            s->Sdt = d;
            outdata(s);

            d = NULL;
            if (tb->ty == Tarray)
                dtsize_t(&d, dim);
            dtxoff(&d, s, 0, TYnptr);
            break;

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