Expression *Expression::castTo(Scope *sc, Type *t) { //printf("Expression::castTo(this=%s, t=%s)\n", toChars(), t->toChars()); #if 0 printf("Expression::castTo(this=%s, type=%s, t=%s)\n", toChars(), type->toChars(), t->toChars()); #endif if (type == t) return this; Expression *e = this; Type *tb = t->toBasetype(); Type *typeb = type->toBasetype(); if (tb != typeb) { // Do (type *) cast of (type [dim]) if (tb->ty == Tpointer && typeb->ty == Tsarray ) { //printf("Converting [dim] to *\n"); if (typeb->size(loc) == 0) e = new NullExp(loc); else e = new AddrExp(loc, e); } #if 0 else if (tb->ty == Tdelegate && type->ty != Tdelegate) { TypeDelegate *td = (TypeDelegate *)tb; TypeFunction *tf = (TypeFunction *)td->nextOf(); return toDelegate(sc, tf->nextOf()); } #endif else { e = new CastExp(loc, e, tb); } } else { e = e->copy(); // because of COW for assignment to e->type } assert(e != this); e->type = t; //printf("Returning: %s\n", e->toChars()); return e; }
Expression *NullExp::castTo(Scope *sc, Type *t) { NullExp *e; Type *tb; //printf("NullExp::castTo(t = %p)\n", t); if (type == t) { committed = 1; return this; } e = (NullExp *)copy(); e->committed = 1; tb = t->toBasetype(); e->type = type->toBasetype(); if (tb != e->type) { // NULL implicitly converts to any pointer type or dynamic array if (e->type->ty == Tpointer && e->type->nextOf()->ty == Tvoid && (tb->ty == Tpointer || tb->ty == Tarray || tb->ty == Taarray || tb->ty == Tdelegate)) { #if 0 if (tb->ty == Tdelegate) { TypeDelegate *td = (TypeDelegate *)tb; TypeFunction *tf = (TypeFunction *)td->nextOf(); if (!tf->varargs && !(tf->arguments && tf->arguments->dim) ) { return Expression::castTo(sc, t); } } #endif } else { return e->Expression::castTo(sc, t); } } e->type = t; return e; }
MATCH Expression::implicitConvTo(Type *t) { #if 0 printf("Expression::implicitConvTo(this=%s, type=%s, t=%s)\n", toChars(), type->toChars(), t->toChars()); #endif //static int nest; if (++nest == 10) halt(); if (t == Type::terror) return MATCHnomatch; if (!type) { error("%s is not an expression", toChars()); type = Type::terror; } if (t->ty == Tbit && isBit()) return MATCHconvert; Expression *e = optimize(WANTvalue | WANTflags); if (e != this) { //printf("optimzed to %s\n", e->toChars()); return e->implicitConvTo(t); } MATCH match = type->implicitConvTo(t); if (match) return match; #if 0 Type *tb = t->toBasetype(); if (tb->ty == Tdelegate) { TypeDelegate *td = (TypeDelegate *)tb; TypeFunction *tf = (TypeFunction *)td->nextOf(); if (!tf->varargs && !(tf->arguments && tf->arguments->dim) ) { match = type->implicitConvTo(tf->nextOf()); if (match) return match; if (tf->nextOf()->toBasetype()->ty == Tvoid) return MATCHconvert; } } #endif return MATCHnomatch; }
IrTypeDelegate* IrTypeDelegate::get(Type* t) { assert(!t->irtype); assert(t->ty == Tdelegate); assert(t->nextOf()->ty == Tfunction); TypeDelegate *dt = (TypeDelegate*)t; if (!dt->irtype) { TypeFunction* tf = static_cast<TypeFunction*>(dt->nextOf()); llvm::Type* ltf = DtoFunctionType(tf, dt->irFty, NULL, Type::tvoid->pointerTo()); llvm::Type *types[] = { getVoidPtrType(), getPtrToType(ltf) }; LLStructType* lt = LLStructType::get(gIR->context(), types, false); dt->irtype = new IrTypeDelegate(dt, lt); } return dt->irtype->isDelegate(); }