diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 9f565979..44c89e16 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -6598,6 +6598,8 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* // NOP; // } + bool isDelegateThunk = ((callFlags & (BfCreateCallFlags_DelegateThunkNonStatic | BfCreateCallFlags_DelegateThunkStatic)) != 0); + auto methodDef = methodInstance->mMethodDef; BfIRValue funcCallInst = func; @@ -6721,7 +6723,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* }; mModule->PopulateType(origReturnType, BfPopulateType_Data); - if (GetStructRetIdx(methodInstance) != -1) + if ((GetStructRetIdx(methodInstance) != -1) && (!isDelegateThunk)) { // We need to ensure that mReceivingValue has the correct type, otherwise it's possible that a conversion operator needs to be applied // This happens for returning Result's with a 'T' value @@ -7164,7 +7166,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* if (returnType->IsComposite()) mModule->mBfIRBuilder->PopulateType(returnType); - methodInstance->mMethodInstanceGroup->mHasEmittedReference = true; + methodInstance->mMethodInstanceGroup->mHasEmittedReference = true; BfIRValue callInst; int callIRArgCount = (int)irArgs.size(); @@ -7203,6 +7205,10 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* bool doingThis = methodInstance->HasThis(); int argIdx = 0; + if ((callFlags & BfCreateCallFlags_DelegateThunkStatic) != 0) + doingThis = false; + bool forceThisPtr = ((callFlags & BfCreateCallFlags_DelegateThunkNonStatic) != 0); + if (methodDef->mHasExplicitThis) paramIdx++; @@ -7213,7 +7219,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* if (methodInstance->mIsIntrinsic) break; - if (argIdx == GetStructRetIdx(methodInstance)) + if ((sret != NULL) && (argIdx == GetStructRetIdx(methodInstance))) { mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_StructRet); argIdx++; diff --git a/IDEHelper/Compiler/BfExprEvaluator.h b/IDEHelper/Compiler/BfExprEvaluator.h index 345cf366..8e54a346 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.h +++ b/IDEHelper/Compiler/BfExprEvaluator.h @@ -52,7 +52,9 @@ enum BfCreateCallFlags BfCreateCallFlags_SkipThis = 2, BfCreateCallFlags_AllowImplicitRef = 4, BfCreateCallFlags_TailCall = 8, - BfCreateCallFlags_GenericParamThis = 0x10 + BfCreateCallFlags_GenericParamThis = 0x10, + BfCreateCallFlags_DelegateThunkNonStatic = 0x20, + BfCreateCallFlags_DelegateThunkStatic = 0x40, }; class BfResolvedArg diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index cf22cacc..a5f7b2ab 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -17401,11 +17401,11 @@ void BfModule::CreateDelegateInvokeMethod() auto fieldPtr = mBfIRBuilder->CreateInBoundsGEP(multicastDelegate, 0, 1); // Load 'delegate.mFuncPtr' auto funcPtrPtr = mBfIRBuilder->CreateBitCast(fieldPtr, memberFuncPtrPtr); auto funcPtr = mBfIRBuilder->CreateAlignedLoad(funcPtrPtr, mSystem->mPtrSize); - nonStaticResult = mBfIRBuilder->CreateCall(funcPtr, memberFuncArgs); - if ((!mIsComptimeModule) && (mCurMethodInstance->GetStructRetIdx() != -1)) - mBfIRBuilder->Call_AddAttribute(nonStaticResult, mCurMethodInstance->GetStructRetIdx() + 1, BfIRAttribute_StructRet); - if (callingConv != BfIRCallingConv_CDecl) - mBfIRBuilder->SetCallCallingConv(nonStaticResult, callingConv); + + BfExprEvaluator exprEvaluator(this); + BfTypedValue nonStaticTypedResult = exprEvaluator.CreateCall(NULL, mCurMethodInstance, funcPtr, true, memberFuncArgs, NULL, BfCreateCallFlags_DelegateThunkNonStatic); + nonStaticResult = nonStaticTypedResult.mValue; + mCurMethodState->SetHadReturn(false); mCurMethodState->mLeftBlockUncond = false; mCurMethodState->mLeftBlockCond = false; @@ -17419,12 +17419,11 @@ void BfModule::CreateDelegateInvokeMethod() auto fieldPtr = mBfIRBuilder->CreateInBoundsGEP(multicastDelegate, 0, 1); // Load 'delegate.mFuncPtr' auto funcPtrPtr = mBfIRBuilder->CreateBitCast(fieldPtr, staticFuncPtrPtr); auto funcPtr = mBfIRBuilder->CreateAlignedLoad(funcPtrPtr, mSystem->mPtrSize); - staticResult = mBfIRBuilder->CreateCall(funcPtr, staticFuncArgs); - if ((!mIsComptimeModule) && (mCurMethodInstance->GetStructRetIdx(true) != -1)) - { - // Note: since this is a forced static invocation, we know the sret will be the first parameter - mBfIRBuilder->Call_AddAttribute(staticResult, 0 + 1, BfIRAttribute_StructRet); - } + + + BfExprEvaluator exprEvaluator(this); + BfTypedValue staticTypedResult = exprEvaluator.CreateCall(NULL, mCurMethodInstance, funcPtr, true, staticFuncArgs, NULL, BfCreateCallFlags_DelegateThunkStatic); + staticResult = staticTypedResult.mValue; // We had a sret for the non-static but no sret for the static (because we have a lowered return type there) if ((!mIsComptimeModule) && (mCurMethodInstance->GetStructRetIdx() != -1) && (mCurMethodInstance->GetStructRetIdx(true) == -1)) @@ -17434,10 +17433,6 @@ void BfModule::CreateDelegateInvokeMethod() mBfIRBuilder->CreateStore(staticResult, sretCastedPtr); } - if (callingConv == BfIRCallingConv_ThisCall) - callingConv = BfIRCallingConv_CDecl; - if (callingConv != BfIRCallingConv_CDecl) - mBfIRBuilder->SetCallCallingConv(staticResult, callingConv); mCurMethodState->SetHadReturn(false); mCurMethodState->mLeftBlockUncond = false; mCurMethodState->mLeftBlockCond = false;