| 15066 | } |
| 15067 | |
| 15068 | BfTypedValue BfModule::Cast(BfAstNode* srcNode, const BfTypedValue& typedVal, BfType* toType, BfCastFlags castFlags) |
| 15069 | { |
| 15070 | bool explicitCast = (castFlags & BfCastFlags_Explicit) != 0; |
| 15071 | |
| 15072 | if (typedVal.mType == toType) |
| 15073 | return typedVal; |
| 15074 | |
| 15075 | if ((toType->IsSizedArray()) && (typedVal.mType->IsSizedArray())) |
| 15076 | { |
| 15077 | // Retain our type if we're casting from a known-sized array to an unknown-sized arrays |
| 15078 | if ((toType->IsUndefSizedArray()) && ((typedVal.mType->GetUnderlyingType()) == (toType->GetUnderlyingType()))) |
| 15079 | { |
| 15080 | return typedVal; |
| 15081 | } |
| 15082 | } |
| 15083 | |
| 15084 | if ((castFlags & BfCastFlags_Force) != 0) |
| 15085 | { |
| 15086 | PopulateType(toType, BfPopulateType_Data); |
| 15087 | if (toType->IsValuelessType()) |
| 15088 | return BfTypedValue(mBfIRBuilder->GetFakeVal(), toType); |
| 15089 | |
| 15090 | if ((typedVal.mType->IsValueType()) && (!typedVal.IsAddr()) && (typedVal.IsSplat()) && (toType->IsValueType())) |
| 15091 | { |
| 15092 | bool needsMemberCasting = false; |
| 15093 | if (AreSplatsCompatible(typedVal.mType, toType, &needsMemberCasting)) |
| 15094 | { |
| 15095 | return BfTypedValue(typedVal.mValue, toType, needsMemberCasting ? BfTypedValueKind_SplatHead_NeedsCasting : BfTypedValueKind_SplatHead); |
| 15096 | } |
| 15097 | } |
| 15098 | |
| 15099 | if (typedVal.mType->IsValueType()) |
| 15100 | { |
| 15101 | auto addrTypedValue = MakeAddressable(typedVal); |
| 15102 | auto toPtrType = CreatePointerType(toType); |
| 15103 | return BfTypedValue(mBfIRBuilder->CreateBitCast(addrTypedValue.mValue, mBfIRBuilder->MapType(toPtrType)), toType, BfTypedValueKind_Addr); |
| 15104 | } |
| 15105 | return BfTypedValue(mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType)), toType); |
| 15106 | } |
| 15107 | |
| 15108 | // This tuple cast may create a new type if the toType contains 'var' entries |
| 15109 | if ((typedVal.mType->IsTuple()) && (toType->IsTuple())) |
| 15110 | { |
| 15111 | PopulateType(toType); |
| 15112 | |
| 15113 | auto fromTupleType = (BfTypeInstance*)typedVal.mType; |
| 15114 | auto toTupleType = (BfTypeInstance*)toType; |
| 15115 | if (fromTupleType == toTupleType) |
| 15116 | return typedVal; |
| 15117 | |
| 15118 | if (fromTupleType->mFieldInstances.size() == toTupleType->mFieldInstances.size()) |
| 15119 | { |
| 15120 | BfTypeVector fieldTypes; |
| 15121 | Array<String> fieldNames; |
| 15122 | bool isCompatible = true; |
| 15123 | bool isExactTypeMatch = true; |
| 15124 | |
| 15125 | for (int fieldIdx = 0; fieldIdx < (int)fromTupleType->mFieldInstances.size(); fieldIdx++) |
no test coverage detected