예제 #1
0
static dt_t *createTsarrayDt(dt_t * dt, Type *t)
{
    assert(dt != NULL);
    size_t eoa_size = dt_size(dt);
    if (eoa_size == t->size())
        return dt;
    else
    {
        TypeSArray * tsa = (TypeSArray *) t->toBasetype();
        assert(tsa->ty == Tsarray);

        size_t dim = tsa->dim->toInteger();
        dt_t * adt = NULL;
        dt_t ** padt = & adt;

        if (eoa_size * dim == eoa_size)
        {
            for (size_t i = 0; i < dim; i++)
                padt = dtcontainer(padt, NULL, dt);
        }
        else
        {
            assert(tsa->size(0) % eoa_size == 0);
            for (size_t i = 0; i < dim; i++)
                padt = dtcontainer(padt, NULL,
                                   createTsarrayDt(dt, tsa->next));
        }
        dt_t * cdt = NULL;
        dtcontainer(& cdt, t, adt);
        return cdt;
    }
}
예제 #2
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);
}
예제 #3
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;
}
예제 #4
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;
}
예제 #5
0
파일: todt.c 프로젝트: MartinNowak/GDC
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;
}