mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 20:42:21 +02:00
Allow mixins and expression blocks to end in a ref expression
This commit is contained in:
parent
3cc0ba2ed6
commit
5268e103e9
6 changed files with 60 additions and 18 deletions
|
@ -3402,6 +3402,7 @@ void BfExprEvaluator::Visit(BfBlock* blockExpr)
|
|||
}
|
||||
|
||||
mModule->VisitEmbeddedStatement(blockExpr, this, BfNodeIsA<BfUnscopedBlock>(blockExpr) ? BfEmbeddedStatementFlags_Unscoped : BfEmbeddedStatementFlags_None);
|
||||
mResult = mModule->SanitizeAddr(mResult);
|
||||
}
|
||||
|
||||
bool BfExprEvaluator::CheckVariableDeclaration(BfAstNode* checkNode, bool requireSimpleIfExpr, bool exprMustBeTrue, bool silentFail)
|
||||
|
@ -17164,6 +17165,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo
|
|||
if (!exprNode->IsA<BfBlock>())
|
||||
{
|
||||
// Mixin expression result
|
||||
SetAndRestoreValue<BfEvalExprFlags> prevFlags(mBfEvalExprFlags, (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_AllowRefExpr));
|
||||
mModule->UpdateSrcPos(exprNode);
|
||||
VisitChild(exprNode);
|
||||
FinishExpressionResult();
|
||||
|
@ -17187,6 +17189,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo
|
|||
}
|
||||
|
||||
mResult = mModule->LoadValue(mResult);
|
||||
mResult = mModule->SanitizeAddr(mResult);
|
||||
|
||||
int localIdx = startLocalIdx;
|
||||
|
||||
|
@ -19497,7 +19500,7 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool
|
|||
}
|
||||
|
||||
ResolveGenericType();
|
||||
auto ptr = mResult;
|
||||
auto ptr = mModule->RemoveRef(mResult);
|
||||
mResult = BfTypedValue();
|
||||
|
||||
if (mPropDef != NULL)
|
||||
|
@ -21569,8 +21572,7 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr,
|
|||
if (!mResult)
|
||||
return;
|
||||
|
||||
if (mResult.mType->IsRef())
|
||||
mResult.mType = mResult.mType->GetUnderlyingType();
|
||||
mResult = mModule->RemoveRef(mResult);
|
||||
|
||||
if (mResult.mType->IsVar())
|
||||
{
|
||||
|
|
|
@ -8791,13 +8791,26 @@ BfTypedValue BfModule::CreateValueFromExpression(BfExprEvaluator& exprEvaluator,
|
|||
{
|
||||
// Only allow a 'ref' type if we have an explicit 'ref' operator
|
||||
bool allowRef = false;
|
||||
BfExpression* checkExpr = expr;
|
||||
while (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(checkExpr))
|
||||
checkExpr = parenExpr->mExpression;
|
||||
if (auto unaryOp = BfNodeDynCast<BfUnaryOperatorExpression>(checkExpr))
|
||||
BfAstNode* checkExpr = expr;
|
||||
|
||||
while (checkExpr != NULL)
|
||||
{
|
||||
if ((unaryOp->mOp == BfUnaryOp_Ref) || (unaryOp->mOp == BfUnaryOp_Mut))
|
||||
allowRef = true;
|
||||
if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(checkExpr))
|
||||
checkExpr = parenExpr->mExpression;
|
||||
else if (auto unaryOp = BfNodeDynCast<BfUnaryOperatorExpression>(checkExpr))
|
||||
{
|
||||
if ((unaryOp->mOp == BfUnaryOp_Ref) || (unaryOp->mOp == BfUnaryOp_Mut))
|
||||
allowRef = true;
|
||||
break;
|
||||
}
|
||||
if (auto block = BfNodeDynCast<BfBlock>(checkExpr))
|
||||
{
|
||||
if (block->mChildArr.mSize == 0)
|
||||
break;
|
||||
checkExpr = block->mChildArr.back();
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (!allowRef)
|
||||
typedVal = RemoveRef(typedVal);
|
||||
|
@ -12480,6 +12493,23 @@ BfTypedValue BfModule::RemoveRef(BfTypedValue typedValue)
|
|||
return typedValue;
|
||||
}
|
||||
|
||||
BfTypedValue BfModule::SanitizeAddr(BfTypedValue typedValue)
|
||||
{
|
||||
if (!typedValue)
|
||||
return typedValue;
|
||||
|
||||
if (typedValue.mType->IsRef())
|
||||
{
|
||||
typedValue = LoadValue(typedValue);
|
||||
|
||||
auto copiedVal = BfTypedValue(CreateAlloca(typedValue.mType), typedValue.mType, true);
|
||||
mBfIRBuilder->CreateStore(typedValue.mValue, copiedVal.mValue);
|
||||
return copiedVal;
|
||||
}
|
||||
|
||||
return typedValue;
|
||||
}
|
||||
|
||||
BfTypedValue BfModule::ToRef(BfTypedValue typedValue, BfRefType* refType)
|
||||
{
|
||||
if (refType == NULL)
|
||||
|
|
|
@ -1700,6 +1700,7 @@ public:
|
|||
void EmitDynamicCastCheck(BfTypedValue typedVal, BfType* type, bool allowNull);
|
||||
void CheckStaticAccess(BfTypeInstance* typeInstance);
|
||||
BfTypedValue RemoveRef(BfTypedValue typedValue);
|
||||
BfTypedValue SanitizeAddr(BfTypedValue typedValue);
|
||||
BfTypedValue ToRef(BfTypedValue typedValue, BfRefType* refType = NULL);
|
||||
BfTypedValue LoadOrAggregateValue(BfTypedValue typedValue);
|
||||
BfTypedValue LoadValue(BfTypedValue typedValue, BfAstNode* refNode = NULL, bool isVolatile = false);
|
||||
|
|
|
@ -4427,15 +4427,10 @@ BfAstNode* BfReducer::DoCreateStatement(BfAstNode* node, CreateStmtFlags createS
|
|||
(unaryOperatorExpr->mOp == BfUnaryOp_Decrement) ||
|
||||
(unaryOperatorExpr->mOp == BfUnaryOp_PostDecrement);
|
||||
|
||||
if ((unaryOperatorExpr->mOp == BfUnaryOp_Ref) || (unaryOperatorExpr->mOp == BfUnaryOp_Mut) || (unaryOperatorExpr->mOp == BfUnaryOp_Out))
|
||||
if (unaryOperatorExpr->mOp == BfUnaryOp_Out)
|
||||
{
|
||||
if (unaryOperatorExpr->mOp == BfUnaryOp_Ref)
|
||||
Fail("Cannot use 'ref' in this context", unaryOperatorExpr);
|
||||
else if (unaryOperatorExpr->mOp == BfUnaryOp_Mut)
|
||||
Fail("Cannot use 'mut' in this context", unaryOperatorExpr);
|
||||
else
|
||||
Fail("Cannot use 'out' in this context", unaryOperatorExpr);
|
||||
return NULL;
|
||||
unaryOperatorExpr->mOp = BfUnaryOp_Ref;
|
||||
Fail("Cannot use 'out' in this context", unaryOperatorExpr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3538,7 +3538,7 @@ void BfModule::VisitCodeBlock(BfBlock* block)
|
|||
else if ((mCurMethodInstance != NULL) && (mCurMethodInstance->IsMixin()) && (mCurMethodState->mCurScope == &mCurMethodState->mHeadScope))
|
||||
{
|
||||
// Only in mixin definition - result ignored
|
||||
CreateValueFromExpression(expr);
|
||||
CreateValueFromExpression(expr, NULL, BfEvalExprFlags_AllowRefExpr);
|
||||
break;
|
||||
}
|
||||
else
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue