| 11058 | } |
| 11059 | |
| 11060 | BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfType* toType, const BfAllocTarget& allocTarget, BfCastFlags castFlags) |
| 11061 | { |
| 11062 | bool callDtor = (castFlags & BfCastFlags_NoBoxDtor) == 0; |
| 11063 | bool wantConst = ((castFlags & BfCastFlags_WantsConst) != 0) && (typedVal.mValue.IsConst()); |
| 11064 | |
| 11065 | if ((mBfIRBuilder->mIgnoreWrites) && (!wantConst)) |
| 11066 | { |
| 11067 | if (toType == mContext->mBfObjectType) |
| 11068 | return BfTypedValue(mBfIRBuilder->GetFakeVal(), toType); |
| 11069 | if (toType->IsBoxed()) |
| 11070 | { |
| 11071 | BfBoxedType* boxedType = (BfBoxedType*)toType; |
| 11072 | if (boxedType->mElementType->IsGenericParam()) |
| 11073 | { |
| 11074 | if (typedVal.mType == boxedType->mElementType) |
| 11075 | return BfTypedValue(mBfIRBuilder->GetFakeVal(), toType); |
| 11076 | else |
| 11077 | return BfTypedValue(); |
| 11078 | } |
| 11079 | } |
| 11080 | } |
| 11081 | |
| 11082 | BP_ZONE("BoxValue"); |
| 11083 | |
| 11084 | BfTypeInstance* fromStructTypeInstance = typedVal.mType->ToTypeInstance(); |
| 11085 | if (typedVal.mType->IsNullable()) |
| 11086 | { |
| 11087 | typedVal = MakeAddressable(typedVal); |
| 11088 | |
| 11089 | auto innerType = typedVal.mType->GetUnderlyingType(); |
| 11090 | if (!innerType->IsValueType()) |
| 11091 | { |
| 11092 | if (!mIgnoreErrors) |
| 11093 | Fail("Only value types can be boxed", srcNode); |
| 11094 | return BfTypedValue(); |
| 11095 | } |
| 11096 | |
| 11097 | auto boxedType = CreateBoxedType(innerType); |
| 11098 | auto resultType = toType; |
| 11099 | if (resultType == NULL) |
| 11100 | resultType = boxedType; |
| 11101 | |
| 11102 | if (mBfIRBuilder->mIgnoreWrites) |
| 11103 | return BfTypedValue(mBfIRBuilder->GetFakeVal(), resultType); |
| 11104 | |
| 11105 | auto prevBB = mBfIRBuilder->GetInsertBlock(); |
| 11106 | auto boxBB = mBfIRBuilder->CreateBlock("boxedN.notNull"); |
| 11107 | auto endBB = mBfIRBuilder->CreateBlock("boxedN.end"); |
| 11108 | |
| 11109 | mBfIRBuilder->PopulateType(typedVal.mType); |
| 11110 | auto hasValueAddr = mBfIRBuilder->CreateInBoundsGEP(typedVal.mValue, 0, innerType->IsValuelessType() ? 1 : 2); // has_value |
| 11111 | auto hasValue = mBfIRBuilder->CreateLoad(hasValueAddr); |
| 11112 | |
| 11113 | mBfIRBuilder->CreateCondBr(hasValue, boxBB, endBB); |
| 11114 | |
| 11115 | AddDependency(boxedType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields); |
| 11116 | |
| 11117 | mBfIRBuilder->AddBlock(boxBB); |
no test coverage detected