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); }
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); }
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 }
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; }
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; }
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; }
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; }
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; }