mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 04:22:20 +02:00
Fixed compond assignment operator overloads
This commit is contained in:
parent
0c7597fe60
commit
ca64ea1f28
3 changed files with 66 additions and 14 deletions
|
@ -522,12 +522,22 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio
|
|||
declError = "'public'";
|
||||
methodDef->mProtection = BfProtection_Public; // Fix it
|
||||
}
|
||||
if (!methodDef->mIsStatic)
|
||||
if (operatorDecl->mAssignOp != BfAssignmentOp_None)
|
||||
{
|
||||
if (!declError.empty())
|
||||
declError += " and ";
|
||||
declError += "'static'";
|
||||
methodDef->mIsStatic = true; // Fix it
|
||||
if (methodDef->mIsStatic)
|
||||
{
|
||||
Fail("Assignment operator must not be declared 'static'", operatorDecl->mStaticSpecifier);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!methodDef->mIsStatic)
|
||||
{
|
||||
if (!declError.empty())
|
||||
declError += " and ";
|
||||
declError += "'static'";
|
||||
methodDef->mIsStatic = true; // Fix it
|
||||
}
|
||||
}
|
||||
if (!declError.empty())
|
||||
{
|
||||
|
|
|
@ -14856,6 +14856,10 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool
|
|||
BfTypedValue convVal;
|
||||
if (binaryOp != BfBinaryOp_None)
|
||||
{
|
||||
CheckResultForReading(ptr);
|
||||
BfTypedValue leftValue = ptr;
|
||||
leftValue = mModule->LoadValue(leftValue);
|
||||
|
||||
auto expectedType = ptr.mType;
|
||||
if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift))
|
||||
expectedType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
|
||||
|
@ -14865,15 +14869,53 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool
|
|||
rightValue = mModule->CreateValueFromExpression(assignExpr->mRight, expectedType, (BfEvalExprFlags)(BfEvalExprFlags_AllowSplat | BfEvalExprFlags_NoCast));
|
||||
}
|
||||
|
||||
CheckResultForReading(ptr);
|
||||
BfTypedValue leftValue = ptr;
|
||||
leftValue = mModule->LoadValue(leftValue);
|
||||
bool handled = false;
|
||||
|
||||
if (rightValue)
|
||||
PerformBinaryOperation(assignExpr->mLeft, assignExpr->mRight, binaryOp, assignExpr->mOpToken, BfBinOpFlag_ForceLeftType, leftValue, rightValue);
|
||||
{
|
||||
auto checkTypeInst = leftValue.mType->ToTypeInstance();
|
||||
while (checkTypeInst != NULL)
|
||||
{
|
||||
for (auto operatorDef : checkTypeInst->mTypeDef->mOperators)
|
||||
{
|
||||
if (operatorDef->mOperatorDeclaration->mAssignOp != assignExpr->mOp)
|
||||
continue;
|
||||
|
||||
auto methodInst = mModule->GetRawMethodInstanceAtIdx(checkTypeInst, operatorDef->mIdx);
|
||||
if (methodInst->GetParamCount() != 1)
|
||||
continue;
|
||||
|
||||
auto paramType = methodInst->GetParamType(0);
|
||||
if (!mModule->CanCast(rightValue, paramType))
|
||||
continue;
|
||||
|
||||
auto moduleMethodInstance = mModule->GetMethodInstance(checkTypeInst, operatorDef, BfTypeVector());
|
||||
|
||||
BfExprEvaluator exprEvaluator(mModule);
|
||||
SizedArray<BfIRValue, 1> args;
|
||||
exprEvaluator.PushThis(assignExpr->mLeft, leftValue, moduleMethodInstance.mMethodInstance, args);
|
||||
exprEvaluator.PushArg(rightValue, args);
|
||||
exprEvaluator.CreateCall(moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, false, args);
|
||||
convVal = leftValue;
|
||||
handled = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (handled)
|
||||
break;
|
||||
checkTypeInst = mModule->GetBaseType(checkTypeInst);
|
||||
}
|
||||
|
||||
if (!handled)
|
||||
PerformBinaryOperation(assignExpr->mLeft, assignExpr->mRight, binaryOp, assignExpr->mOpToken, BfBinOpFlag_ForceLeftType, leftValue, rightValue);
|
||||
}
|
||||
|
||||
if (!handled)
|
||||
{
|
||||
convVal = mResult;
|
||||
mResult = BfTypedValue();
|
||||
}
|
||||
|
||||
convVal = mResult;
|
||||
mResult = BfTypedValue();
|
||||
if (!convVal)
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -16101,7 +16101,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
|||
Fail("Assignment operators must declare one parameter", paramErrorRefNode);
|
||||
}
|
||||
|
||||
if (mCurMethodInstance->mReturnType->IsVoid())
|
||||
if (!mCurMethodInstance->mReturnType->IsVoid())
|
||||
{
|
||||
Fail("The return type for assignment operator must be 'void'", operatorDef->mOperatorDeclaration->mReturnType);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue