From 401ab0c98e84aa1d1c4cefb94ef3ed42b4333250 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Mon, 12 Jul 2021 07:55:36 -0700 Subject: [PATCH] Fixed delegates with lowered return types --- IDEHelper/Compiler/BfModule.cpp | 24 ++++++++++++++++------ IDEHelper/Compiler/BfResolvedTypeUtils.cpp | 11 +++++----- IDEHelper/Compiler/BfResolvedTypeUtils.h | 2 +- IDEHelper/Tests/src/Delegates.bf | 15 ++++++++++++++ 4 files changed, 40 insertions(+), 12 deletions(-) diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index bbf6ad94..8fee4256 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -1135,7 +1135,7 @@ void BfModule::SetupIRBuilder(bool dbgVerifyCodeGen) { // We almost always want this to be 'false' unless we need need to be able to inspect the generated LLVM // code as we walk the AST - //mBfIRBuilder->mDbgVerifyCodeGen = true; + //mBfIRBuilder->mDbgVerifyCodeGen = true; if ( (mModuleName == "-") //|| (mModuleName == "BeefTest2_ClearColorValue") @@ -15160,6 +15160,7 @@ void BfModule::CreateDelegateInvokeMethod() SizedArray origParamTypes; BfIRType origReturnType; + BfIRType staticReturnType; mCurMethodInstance->GetIRFunctionInfo(this, origReturnType, origParamTypes); if (mCurMethodInstance->mReturnType->IsValueType()) @@ -15171,15 +15172,17 @@ void BfModule::CreateDelegateInvokeMethod() int thisIdx = 0; if ((!mIsComptimeModule) && (mCurMethodInstance->GetStructRetIdx() != -1)) { - thisIdx = mCurMethodInstance->GetStructRetIdx() ^ 1; - staticFuncArgs.push_back(mBfIRBuilder->GetArgument(mCurMethodInstance->GetStructRetIdx())); + thisIdx = mCurMethodInstance->GetStructRetIdx() ^ 1; memberFuncArgs.push_back(mBfIRBuilder->GetArgument(mCurMethodInstance->GetStructRetIdx())); } + if ((!mIsComptimeModule) && (mCurMethodInstance->GetStructRetIdx(true) != -1)) + staticFuncArgs.push_back(mBfIRBuilder->GetArgument(mCurMethodInstance->GetStructRetIdx())); + if ((!mIsComptimeModule) && (mCurMethodInstance->GetStructRetIdx() == 0)) memberFuncArgs.push_back(BfIRValue()); // Push 'target' - mCurMethodInstance->GetIRFunctionInfo(this, origReturnType, staticParamTypes, true); + mCurMethodInstance->GetIRFunctionInfo(this, staticReturnType, staticParamTypes, true); for (int i = 1; i < (int)mCurMethodState->mLocals.size(); i++) { @@ -15188,7 +15191,7 @@ void BfModule::CreateDelegateInvokeMethod() exprEvaluator.PushArg(localVal, memberFuncArgs); } - auto staticFunc = mBfIRBuilder->CreateFunctionType(origReturnType, staticParamTypes, false); + auto staticFunc = mBfIRBuilder->CreateFunctionType(staticReturnType, staticParamTypes, false); auto staticFuncPtr = mBfIRBuilder->GetPointerTo(staticFunc); auto staticFuncPtrPtr = mBfIRBuilder->GetPointerTo(staticFuncPtr); @@ -15233,11 +15236,20 @@ void BfModule::CreateDelegateInvokeMethod() auto funcPtrPtr = mBfIRBuilder->CreateBitCast(fieldPtr, staticFuncPtrPtr); auto funcPtr = mBfIRBuilder->CreateLoad(funcPtrPtr); staticResult = mBfIRBuilder->CreateCall(funcPtr, staticFuncArgs); - if ((!mIsComptimeModule) && (mCurMethodInstance->GetStructRetIdx() != -1)) + 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); } + + // 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)) + { + auto sretToType = mBfIRBuilder->GetPointerTo(staticReturnType); + auto sretCastedPtr = mBfIRBuilder->CreateBitCast(mBfIRBuilder->GetArgument(mCurMethodInstance->GetStructRetIdx()), sretToType); + mBfIRBuilder->CreateStore(staticResult, sretCastedPtr); + } + if (callingConv == BfIRCallingConv_ThisCall) callingConv = BfIRCallingConv_CDecl; if (callingConv != BfIRCallingConv_CDecl) diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp index 581a04e7..01b282e7 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp @@ -758,7 +758,7 @@ bool BfMethodInstance::HasParamsArray() int BfMethodInstance::GetStructRetIdx(bool forceStatic) { - if ((mReturnType->IsComposite()) && (!mReturnType->IsValuelessType()) && (!GetLoweredReturnType()) && (!mIsIntrinsic)) + if ((mReturnType->IsComposite()) && (!mReturnType->IsValuelessType()) && (!GetLoweredReturnType(NULL, NULL, forceStatic)) && (!mIsIntrinsic)) { auto returnTypeInst = mReturnType->ToTypeInstance(); if ((returnTypeInst != NULL) && (returnTypeInst->mHasUnderlyingArray)) @@ -792,10 +792,11 @@ bool BfMethodInstance::HasSelf() return false; } -bool BfMethodInstance::GetLoweredReturnType(BfTypeCode* loweredTypeCode, BfTypeCode* loweredTypeCode2) +bool BfMethodInstance::GetLoweredReturnType(BfTypeCode* loweredTypeCode, BfTypeCode* loweredTypeCode2, bool forceStatic) { // Win32 handler - if ((mMethodDef->mIsStatic) && (mReturnType->IsComposite()) && + if (((mMethodDef->mIsStatic) || (forceStatic)) && + (mReturnType->IsComposite()) && ((mReturnType->mSize == 4) || (mReturnType->mSize == 8))) { auto returnTypeInst = mReturnType->ToTypeInstance(); @@ -816,7 +817,7 @@ bool BfMethodInstance::GetLoweredReturnType(BfTypeCode* loweredTypeCode, BfTypeC } } - return mReturnType->GetLoweredType(mMethodDef->mIsStatic ? BfTypeUsage_Return_Static : BfTypeUsage_Return_NonStatic, loweredTypeCode, loweredTypeCode2); + return mReturnType->GetLoweredType((mMethodDef->mIsStatic || forceStatic) ? BfTypeUsage_Return_Static : BfTypeUsage_Return_NonStatic, loweredTypeCode, loweredTypeCode2); } bool BfMethodInstance::WantsStructsAttribByVal() @@ -1179,7 +1180,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType, BfTypeCode loweredReturnTypeCode = BfTypeCode_None; BfTypeCode loweredReturnTypeCode2 = BfTypeCode_None; - if ((!module->mIsComptimeModule) && (GetLoweredReturnType(&loweredReturnTypeCode, &loweredReturnTypeCode2))) + if ((!module->mIsComptimeModule) && (GetLoweredReturnType(&loweredReturnTypeCode, &loweredReturnTypeCode2, forceStatic))) { auto irReturnType = module->GetIRLoweredType(loweredReturnTypeCode, loweredReturnTypeCode2); returnType = irReturnType; diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.h b/IDEHelper/Compiler/BfResolvedTypeUtils.h index 7a02ee55..7fc11280 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.h +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.h @@ -929,7 +929,7 @@ public: bool HasParamsArray(); int GetStructRetIdx(bool forceStatic = false); bool HasSelf(); - bool GetLoweredReturnType(BfTypeCode* loweredTypeCode = NULL, BfTypeCode* loweredTypeCode2 = NULL); + bool GetLoweredReturnType(BfTypeCode* loweredTypeCode = NULL, BfTypeCode* loweredTypeCode2 = NULL, bool forceStatic = false); bool WantsStructsAttribByVal(); bool IsAutocompleteMethod() { /*return mIdHash == -1;*/ return mIsAutocompleteMethod; } bool IsSkipCall(bool bypassVirtual = false); diff --git a/IDEHelper/Tests/src/Delegates.bf b/IDEHelper/Tests/src/Delegates.bf index d191e847..639fadb0 100644 --- a/IDEHelper/Tests/src/Delegates.bf +++ b/IDEHelper/Tests/src/Delegates.bf @@ -114,6 +114,18 @@ namespace Tests public delegate int DelegateB(T val); } + [CRepr] + struct Vector3f + { + public float mX; + public float mY; + } + + static Vector3f GetVector3f() + { + return .() { mX = 101, mY = 102 }; + } + [Test] public static void TestBasics() { @@ -167,6 +179,9 @@ namespace Tests e += new (sender, e) => {}; e += new => LocalEventHandler; e.Dispose(); + + delegate Vector3f() vecDlg = scope => GetVector3f; + Test.Assert(vecDlg().mX == 101); } public static void Modify(ref int a, ref Splattable b)