ldc::DIType ldc::DIBuilder::CreateVectorType(Type *type) { LLType *T = DtoType(type); Type *t = type->toBasetype(); assert(t->ty == Tvector && "Only vectors allowed for debug info in DIBuilder::CreateVectorType"); TypeVector *tv = static_cast<TypeVector *>(t); Type *te = tv->elementType(); // translate void vectors to byte vectors if (te->toBasetype()->ty == Tvoid) te = Type::tuns8; int64_t Dim = tv->size(Loc()) / te->size(Loc()); LLMetadata *subscripts[] = {DBuilder.getOrCreateSubrange(0, Dim)}; return DBuilder.createVectorType( getTypeAllocSize(T) * 8, // size (bits) getABITypeAlign(T) * 8, // align (bits) CreateTypeDescription(te, false), // element type DBuilder.getOrCreateArray(subscripts) // subscripts ); }
llvm::DIType ldc::DIBuilder::CreateVectorType(Type *type) { LLType* T = DtoType(type); Type* t = type->toBasetype(); assert(t->ty == Tvector && "Only vectors allowed for debug info in DIBuilder::CreateVectorType"); TypeVector *tv = static_cast<TypeVector *>(t); Type *te = tv->elementType(); int64_t Dim = tv->size(Loc()) / te->size(Loc()); llvm::Value *subscripts[] = { DBuilder.getOrCreateSubrange(0, Dim) }; llvm::DIType basetype = CreateTypeDescription(te, NULL); return DBuilder.createVectorType( getTypeBitSize(T), // size (bits) getABITypeAlign(T)*8, // align (bits) basetype, // element type DBuilder.getOrCreateArray(subscripts) // subscripts ); }
unsigned totym(Type *tx) { unsigned t; switch (tx->ty) { case Tvoid: t = TYvoid; break; case Tint8: t = TYschar; break; case Tuns8: t = TYuchar; break; case Tint16: t = TYshort; break; case Tuns16: t = TYushort; break; case Tint32: t = TYint; break; case Tuns32: t = TYuint; break; case Tint64: t = TYllong; break; case Tuns64: t = TYullong; break; case Tfloat32: t = TYfloat; break; case Tfloat64: t = TYdouble; break; case Tfloat80: t = TYldouble; break; case Timaginary32: t = TYifloat; break; case Timaginary64: t = TYidouble; break; case Timaginary80: t = TYildouble; break; case Tcomplex32: t = TYcfloat; break; case Tcomplex64: t = TYcdouble; break; case Tcomplex80: t = TYcldouble; break; case Tbool: t = TYbool; break; case Tchar: t = TYchar; break; case Twchar: t = TYwchar_t; break; #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS case Tdchar: t = TYdchar; break; #else case Tdchar: t = (global.params.symdebug == 1) ? TYdchar : TYulong; break; #endif case Taarray: t = TYaarray; break; case Tclass: case Treference: case Tpointer: t = TYnptr; break; case Tdelegate: t = TYdelegate; break; case Tarray: t = TYdarray; break; case Tsarray: t = TYstruct; break; case Tstruct: t = TYstruct; if (tx->toDsymbol(NULL)->ident == Id::__c_long_double) t = TYdouble; break; case Tenum: t = totym(tx->toBasetype()); break; case Tident: case Ttypeof: #ifdef DEBUG printf("ty = %d, '%s'\n", tx->ty, tx->toChars()); #endif error(Loc(), "forward reference of %s", tx->toChars()); t = TYint; break; case Tnull: t = TYnptr; break; case Tvector: { TypeVector *tv = (TypeVector *)tx; TypeBasic *tb = tv->elementType(); switch (tb->ty) { case Tvoid: case Tint8: t = TYschar16; break; case Tuns8: t = TYuchar16; break; case Tint16: t = TYshort8; break; case Tuns16: t = TYushort8; break; case Tint32: t = TYlong4; break; case Tuns32: t = TYulong4; break; case Tint64: t = TYllong2; break; case Tuns64: t = TYullong2; break; case Tfloat32: t = TYfloat4; break; case Tfloat64: t = TYdouble2; break; default: assert(0); break; } assert(global.params.is64bit || global.params.isOSX); break; } case Tfunction: { TypeFunction *tf = (TypeFunction *)tx; switch (tf->linkage) { case LINKwindows: if (global.params.is64bit) goto Lc; t = (tf->varargs == 1) ? TYnfunc : TYnsfunc; break; case LINKpascal: t = (tf->varargs == 1) ? TYnfunc : TYnpfunc; break; case LINKc: case LINKcpp: Lc: t = TYnfunc; #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS if (I32 && retStyle(tf) == RETstack) t = TYhfunc; #endif break; case LINKd: t = (tf->varargs == 1) ? TYnfunc : TYjfunc; break; default: printf("linkage = %d\n", tf->linkage); assert(0); } if (tf->isnothrow) t |= mTYnothrow; return t; } default: #ifdef DEBUG printf("ty = %d, '%s'\n", tx->ty, tx->toChars()); halt(); #endif assert(0); } // Add modifiers switch (tx->mod) { case 0: break; case MODconst: case MODwild: case MODwildconst: t |= mTYconst; break; case MODshared: t |= mTYshared; break; case MODshared | MODconst: case MODshared | MODwild: case MODshared | MODwildconst: t |= mTYshared | mTYconst; break; case MODimmutable: t |= mTYimmutable; break; default: assert(0); } return t; }
unsigned Type::totym() { unsigned t; switch (ty) { case Tvoid: t = TYvoid; break; case Tint8: t = TYschar; break; case Tuns8: t = TYuchar; break; case Tint16: t = TYshort; break; case Tuns16: t = TYushort; break; case Tint32: t = TYint; break; case Tuns32: t = TYuint; break; case Tint64: t = TYllong; break; case Tuns64: t = TYullong; break; case Tfloat32: t = TYfloat; break; case Tfloat64: t = TYdouble; break; case Tfloat80: t = TYldouble; break; case Timaginary32: t = TYifloat; break; case Timaginary64: t = TYidouble; break; case Timaginary80: t = TYildouble; break; case Tcomplex32: t = TYcfloat; break; case Tcomplex64: t = TYcdouble; break; case Tcomplex80: t = TYcldouble; break; case Tbool: t = TYbool; break; case Tchar: t = TYchar; break; #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS case Twchar: t = TYwchar_t; break; case Tdchar: t = TYdchar; break; #else case Twchar: t = TYwchar_t; break; case Tdchar: t = (global.params.symdebug == 1) ? TYdchar : TYulong; break; #endif case Taarray: t = TYaarray; break; case Tclass: case Treference: case Tpointer: t = TYnptr; break; case Tdelegate: t = TYdelegate; break; case Tarray: t = TYdarray; break; #if SARRAYVALUE case Tsarray: t = TYstruct; break; #else case Tsarray: t = TYarray; break; #endif case Tstruct: t = TYstruct; break; case Tenum: case Ttypedef: t = toBasetype()->totym(); break; case Tident: case Ttypeof: error(0, "forward reference of %s", toChars()); t = TYint; break; case Tnull: t = TYnptr; break; case Tvector: { TypeVector *tv = (TypeVector *)this; TypeBasic *tb = tv->elementType(); switch (tb->ty) { case Tvoid: case Tint8: t = TYschar16; break; case Tuns8: t = TYuchar16; break; case Tint16: t = TYshort8; break; case Tuns16: t = TYushort8; break; case Tint32: t = TYlong4; break; case Tuns32: t = TYulong4; break; case Tint64: t = TYllong2; break; case Tuns64: t = TYullong2; break; case Tfloat32: t = TYfloat4; break; case Tfloat64: t = TYdouble2; break; default: assert(0); break; } if (tv->size(0) == 32) error(0, "AVX vector types not supported"); break; } default: #ifdef DEBUG printf("ty = %d, '%s'\n", ty, toChars()); halt(); #endif assert(0); } #if DMDV2 // Add modifiers switch (mod) { case 0: break; case MODconst: case MODwild: t |= mTYconst; break; case MODimmutable: t |= mTYimmutable; break; case MODshared: t |= mTYshared; break; case MODshared | MODwild: case MODshared | MODconst: t |= mTYshared | mTYconst; break; default: assert(0); } #endif return t; }
MATCH ArrayLiteralExp::implicitConvTo(Type *t) { MATCH result = MATCHexact; #if 0 printf("ArrayLiteralExp::implicitConvTo(this=%s, type=%s, t=%s)\n", toChars(), type->toChars(), t->toChars()); #endif Type *typeb = type->toBasetype(); Type *tb = t->toBasetype(); if ((tb->ty == Tarray || tb->ty == Tsarray) && (typeb->ty == Tarray || typeb->ty == Tsarray)) { if (tb->ty == Tsarray) { TypeSArray *tsa = (TypeSArray *)tb; if (elements->dim != tsa->dim->toInteger()) result = MATCHnomatch; } if (!elements->dim && typeb->nextOf()->toBasetype()->ty != Tvoid) result = MATCHnomatch; Type *telement = tb->nextOf(); for (size_t i = 0; i < elements->dim; i++) { Expression *e = (*elements)[i]; if (result == MATCHnomatch) break; // no need to check for worse MATCH m = (MATCH)e->implicitConvTo(telement); if (m < result) result = m; // remember worst match } if (!result) result = type->implicitConvTo(t); return result; } #if DMDV2 else if (tb->ty == Tvector && (typeb->ty == Tarray || typeb->ty == Tsarray)) { // Convert array literal to vector type TypeVector *tv = (TypeVector *)tb; TypeSArray *tbase = (TypeSArray *)tv->basetype; assert(tbase->ty == Tsarray); if (elements->dim != tbase->dim->toInteger()) return MATCHnomatch; Type *telement = tv->elementType(); for (size_t i = 0; i < elements->dim; i++) { Expression *e = (*elements)[i]; MATCH m = (MATCH)e->implicitConvTo(telement); if (m < result) result = m; // remember worst match if (result == MATCHnomatch) break; // no need to check for worse } return result; } #endif else return Expression::implicitConvTo(t); }
Expression *ArrayLiteralExp::castTo(Scope *sc, Type *t) { #if 0 printf("ArrayLiteralExp::castTo(this=%s, type=%s, => %s)\n", toChars(), type->toChars(), t->toChars()); #endif if (type == t) return this; ArrayLiteralExp *e = this; Type *typeb = type->toBasetype(); Type *tb = t->toBasetype(); if ((tb->ty == Tarray || tb->ty == Tsarray) && (typeb->ty == Tarray || typeb->ty == Tsarray) && // Not trying to convert non-void[] to void[] !(tb->nextOf()->toBasetype()->ty == Tvoid && typeb->nextOf()->toBasetype()->ty != Tvoid)) { if (tb->ty == Tsarray) { TypeSArray *tsa = (TypeSArray *)tb; if (elements->dim != tsa->dim->toInteger()) goto L1; } e = (ArrayLiteralExp *)copy(); e->elements = (Expressions *)elements->copy(); for (size_t i = 0; i < elements->dim; i++) { Expression *ex = (*elements)[i]; ex = ex->castTo(sc, tb->nextOf()); (*e->elements)[i] = ex; } e->type = t; return e; } if (tb->ty == Tpointer && typeb->ty == Tsarray) { e = (ArrayLiteralExp *)copy(); e->type = typeb->nextOf()->pointerTo(); } #if DMDV2 else if (tb->ty == Tvector && (typeb->ty == Tarray || typeb->ty == Tsarray)) { // Convert array literal to vector type TypeVector *tv = (TypeVector *)tb; TypeSArray *tbase = (TypeSArray *)tv->basetype; assert(tbase->ty == Tsarray); if (elements->dim != tbase->dim->toInteger()) goto L1; e = (ArrayLiteralExp *)copy(); e->elements = (Expressions *)elements->copy(); Type *telement = tv->elementType(); for (size_t i = 0; i < elements->dim; i++) { Expression *ex = (*elements)[i]; ex = ex->castTo(sc, telement); (*e->elements)[i] = ex; } Expression *ev = new VectorExp(loc, e, tb); ev = ev->semantic(sc); return ev; } #endif L1: return e->Expression::castTo(sc, t); }