void TypeInfoTupleDeclaration::toDt(dt_t **pdt) { //printf("TypeInfoTupleDeclaration::toDt() %s\n", tinfo->toChars()); dtxoff(pdt, Type::typeinfotypelist->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface dtsize_t(pdt, 0); // monitor assert(tinfo->ty == Ttuple); TypeTuple *tu = (TypeTuple *)tinfo; size_t dim = tu->arguments->dim; dtsize_t(pdt, dim); // elements.length dt_t *d = NULL; for (size_t i = 0; i < dim; i++) { Parameter *arg = tu->arguments->tdata()[i]; Expression *e = arg->type->getTypeInfo(NULL); e = e->optimize(WANTvalue); e->toDt(&d); } Symbol *s; s = static_sym(); s->Sdt = d; outdata(s); dtxoff(pdt, s, 0, TYnptr); // elements.ptr }
dt_t *ArrayInitializer::toDtBit() { #if DMDV1 unsigned size; unsigned length; unsigned tadim; dt_t *d; dt_t **pdtend; Type *tb = type->toBasetype(); //printf("ArrayInitializer::toDtBit('%s')\n", toChars()); Bits databits; Bits initbits; if (tb->ty == Tsarray) { /* The 'dim' for ArrayInitializer is only the maximum dimension * seen in the initializer, not the type. So, for static arrays, * use instead the dimension of the type in order * to get the whole thing. */ dinteger_t value = ((TypeSArray*)tb)->dim->toInteger(); tadim = value; assert(tadim == value); // truncation overflow should already be checked databits.resize(tadim); initbits.resize(tadim); } else { databits.resize(dim); initbits.resize(dim); } /* The default initializer may be something other than zero. */ if (tb->next->defaultInit()->toInteger()) databits.set(); size = sizeof(databits.data[0]); length = 0; for (size_t i = 0; i < index.dim; i++) { Expression *idx; Initializer *val; Expression *eval; idx = (Expression *)index.data[i]; if (idx) { dinteger_t value; value = idx->toInteger(); length = value; if (length != value) { error(loc, "index overflow %llu", value); length = 0; } } assert(length < dim); val = (Initializer *)value.data[i]; eval = val->toExpression(); if (initbits.test(length)) error(loc, "duplicate initializations for index %d", length); initbits.set(length); if (eval->toInteger()) // any non-zero value is boolean 'true' databits.set(length); else databits.clear(length); // boolean 'false' length++; } d = NULL; #ifdef IN_GCC pdtend = dtnbits(&d, databits.allocdim * size, (char *)databits.data, sizeof(databits.data[0])); #else pdtend = dtnbytes(&d, databits.allocdim * size, (char *)databits.data); #endif switch (tb->ty) { case Tsarray: { if (dim > tadim) { error(loc, "too many initializers, %d, for array[%d]", dim, tadim); } else { tadim = (tadim + 31) / 32; if (databits.allocdim < tadim) pdtend = dtnzeros(pdtend, size * (tadim - databits.allocdim)); // pad out end of array } 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; #else return NULL; #endif }
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->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 *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; }