| 17143 | } |
| 17144 | |
| 17145 | void BfModule::EmitReturn(const BfTypedValue& val) |
| 17146 | { |
| 17147 | if (mCurMethodState->mIRExitBlock) |
| 17148 | { |
| 17149 | if (!mCurMethodInstance->mReturnType->IsValuelessType()) |
| 17150 | { |
| 17151 | if (val) // We allow for val to be empty if we know we've already written the value to mRetVal |
| 17152 | { |
| 17153 | if ((mCurMethodState->mRetValAddr) || (mCurMethodState->mRetVal)) |
| 17154 | { |
| 17155 | BfIRValue retVal = mCurMethodState->mRetVal.mValue; |
| 17156 | if (!mCurMethodState->mRetVal) |
| 17157 | retVal = mBfIRBuilder->CreateAlignedLoad(mCurMethodState->mRetValAddr, mCurMethodInstance->mReturnType->mAlign); |
| 17158 | |
| 17159 | mBfIRBuilder->CreateAlignedStore(val.mValue, retVal, mCurMethodInstance->mReturnType->mAlign); |
| 17160 | } |
| 17161 | else if (mIsComptimeModule) |
| 17162 | { |
| 17163 | if (!val.mType->IsValuelessType()) |
| 17164 | mBfIRBuilder->CreateSetRet(val.mValue, val.mType->mTypeId); |
| 17165 | else |
| 17166 | mBfIRBuilder->CreateSetRet(BfIRValue(), val.mType->mTypeId); |
| 17167 | } |
| 17168 | else |
| 17169 | { |
| 17170 | // Just ignore |
| 17171 | BF_ASSERT(mCurMethodInstance->mReturnType->IsVar()); |
| 17172 | } |
| 17173 | } |
| 17174 | } |
| 17175 | EmitDeferredScopeCalls(true, NULL, mCurMethodState->mIRExitBlock); |
| 17176 | } |
| 17177 | else |
| 17178 | { |
| 17179 | EmitDeferredScopeCalls(false, NULL); |
| 17180 | if (val) |
| 17181 | { |
| 17182 | BF_ASSERT(mBfIRBuilder->mIgnoreWrites); |
| 17183 | } |
| 17184 | } |
| 17185 | |
| 17186 | mCurMethodState->SetHadReturn(true); |
| 17187 | mCurMethodState->mLeftBlockUncond = true; |
| 17188 | } |
| 17189 | |
| 17190 | void BfModule::EmitDefaultReturn() |
| 17191 | { |
nothing calls this directly
no test coverage detected