mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 04:22:20 +02:00
Address-of immutable is now a warning instead of error, added [NoSplat]
This commit is contained in:
parent
557b13070c
commit
808a4438d7
7 changed files with 69 additions and 41 deletions
|
@ -230,6 +230,12 @@ namespace System
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[AttributeUsage(.Method /*2*/)]
|
||||||
|
public struct NoSplatAttribute : Attribute
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
[AttributeUsage(.Method /*2*/)]
|
[AttributeUsage(.Method /*2*/)]
|
||||||
public struct SkipCallAttribute : Attribute
|
public struct SkipCallAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
|
@ -795,13 +795,15 @@ void BfDefBuilder::ParseAttributes(BfAttributeDirective* attributes, BfMethodDef
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (typeRefName == "NoReturn")
|
else if (typeRefName == "NoReturn")
|
||||||
methodDef->mNoReturn = true;
|
methodDef->mIsNoReturn = true;
|
||||||
else if (typeRefName == "SkipCall")
|
else if (typeRefName == "SkipCall")
|
||||||
methodDef->mIsSkipCall = true;
|
methodDef->mIsSkipCall = true;
|
||||||
else if (typeRefName == "NoShow")
|
else if (typeRefName == "NoShow")
|
||||||
methodDef->mIsNoShow = true;
|
methodDef->mIsNoShow = true;
|
||||||
else if (typeRefName == "NoDiscard")
|
else if (typeRefName == "NoDiscard")
|
||||||
methodDef->mIsNoDiscard = true;
|
methodDef->mIsNoDiscard = true;
|
||||||
|
else if (typeRefName == "NoSplat")
|
||||||
|
methodDef->mIsNoSplat = true;
|
||||||
else if (typeRefName == "Commutable")
|
else if (typeRefName == "Commutable")
|
||||||
{
|
{
|
||||||
if (methodDef->mParams.size() != 2)
|
if (methodDef->mParams.size() != 2)
|
||||||
|
@ -1122,12 +1124,12 @@ BfMethodDef* BfDefBuilder::AddMethod(BfTypeDef* typeDef, BfMethodType methodType
|
||||||
else if (methodType == BfMethodType_CtorNoBody)
|
else if (methodType == BfMethodType_CtorNoBody)
|
||||||
{
|
{
|
||||||
methodDef->mName = "__BfCtorNoBody";
|
methodDef->mName = "__BfCtorNoBody";
|
||||||
methodDef->mNoReflect = true;
|
methodDef->mIsNoReflect = true;
|
||||||
}
|
}
|
||||||
else if (methodType == BfMethodType_CtorClear)
|
else if (methodType == BfMethodType_CtorClear)
|
||||||
{
|
{
|
||||||
methodDef->mName = "__BfCtorClear";
|
methodDef->mName = "__BfCtorClear";
|
||||||
methodDef->mNoReflect = true;
|
methodDef->mIsNoReflect = true;
|
||||||
}
|
}
|
||||||
else if (methodType == BfMethodType_Dtor)
|
else if (methodType == BfMethodType_Dtor)
|
||||||
{
|
{
|
||||||
|
@ -1191,7 +1193,7 @@ void BfDefBuilder::AddDynamicCastMethods(BfTypeDef* typeDef)
|
||||||
paramDef->mTypeRef = typeDef->mSystem->mDirectInt32TypeRef;
|
paramDef->mTypeRef = typeDef->mSystem->mDirectInt32TypeRef;
|
||||||
methodDef->mParams.push_back(paramDef);
|
methodDef->mParams.push_back(paramDef);
|
||||||
methodDef->mReturnTypeRef = typeDef->mSystem->mDirectObjectTypeRef;
|
methodDef->mReturnTypeRef = typeDef->mSystem->mDirectObjectTypeRef;
|
||||||
methodDef->mNoReflect = true;
|
methodDef->mIsNoReflect = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -1212,7 +1214,7 @@ void BfDefBuilder::AddDynamicCastMethods(BfTypeDef* typeDef)
|
||||||
paramDef->mTypeRef = typeDef->mSystem->mDirectInt32TypeRef;
|
paramDef->mTypeRef = typeDef->mSystem->mDirectInt32TypeRef;
|
||||||
methodDef->mParams.push_back(paramDef);
|
methodDef->mParams.push_back(paramDef);
|
||||||
methodDef->mReturnTypeRef = typeDef->mSystem->mDirectObjectTypeRef;
|
methodDef->mReturnTypeRef = typeDef->mSystem->mDirectObjectTypeRef;
|
||||||
methodDef->mNoReflect = true;
|
methodDef->mIsNoReflect = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2048,13 +2050,13 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
||||||
if ((hasStaticField) && (!hasStaticMarkMethod))
|
if ((hasStaticField) && (!hasStaticMarkMethod))
|
||||||
{
|
{
|
||||||
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Normal, BfProtection_Protected, true, BF_METHODNAME_MARKMEMBERS_STATIC);
|
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Normal, BfProtection_Protected, true, BF_METHODNAME_MARKMEMBERS_STATIC);
|
||||||
methodDef->mNoReflect = true;
|
methodDef->mIsNoReflect = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasThreadStatics)
|
if (hasThreadStatics)
|
||||||
{
|
{
|
||||||
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Normal, BfProtection_Protected, true, BF_METHODNAME_FIND_TLS_MEMBERS);
|
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Normal, BfProtection_Protected, true, BF_METHODNAME_FIND_TLS_MEMBERS);
|
||||||
methodDef->mNoReflect = true;
|
methodDef->mIsNoReflect = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((hasNonStaticField) && (!hasMarkMethod))
|
if ((hasNonStaticField) && (!hasMarkMethod))
|
||||||
|
@ -2062,7 +2064,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
||||||
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Normal, BfProtection_Protected, false, BF_METHODNAME_MARKMEMBERS);
|
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Normal, BfProtection_Protected, false, BF_METHODNAME_MARKMEMBERS);
|
||||||
methodDef->mIsVirtual = true;
|
methodDef->mIsVirtual = true;
|
||||||
methodDef->mIsOverride = true;
|
methodDef->mIsOverride = true;
|
||||||
methodDef->mNoReflect = true;
|
methodDef->mIsNoReflect = true;
|
||||||
methodDef->mCallingConvention = BfCallingConvention_Cdecl;
|
methodDef->mCallingConvention = BfCallingConvention_Cdecl;
|
||||||
mCurTypeDef->mHasOverrideMethods = true;
|
mCurTypeDef->mHasOverrideMethods = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4638,7 +4638,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
|
||||||
mModule->mCurMethodState->mCancelledDeferredCall = true;
|
mModule->mCurMethodState->mCancelledDeferredCall = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (methodDef->mNoReturn)
|
if (methodDef->mIsNoReturn)
|
||||||
{
|
{
|
||||||
mModule->mCurMethodState->SetHadReturn(true);
|
mModule->mCurMethodState->SetHadReturn(true);
|
||||||
mModule->mCurMethodState->mLeftBlockUncond = true;
|
mModule->mCurMethodState->mLeftBlockUncond = true;
|
||||||
|
@ -4984,7 +4984,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
|
||||||
if ((expectCallingConvention != BfIRCallingConv_CDecl) && (!methodInstance->mIsIntrinsic))
|
if ((expectCallingConvention != BfIRCallingConv_CDecl) && (!methodInstance->mIsIntrinsic))
|
||||||
mModule->mBfIRBuilder->SetCallCallingConv(callInst, expectCallingConvention);
|
mModule->mBfIRBuilder->SetCallCallingConv(callInst, expectCallingConvention);
|
||||||
|
|
||||||
if ((methodDef->mNoReturn) && (!methodInstance->mIsIntrinsic))
|
if ((methodDef->mIsNoReturn) && (!methodInstance->mIsIntrinsic))
|
||||||
mModule->mBfIRBuilder->Call_AddAttribute(callInst, -1, BfIRAttribute_NoReturn);
|
mModule->mBfIRBuilder->Call_AddAttribute(callInst, -1, BfIRAttribute_NoReturn);
|
||||||
|
|
||||||
bool hadAttrs = false;
|
bool hadAttrs = false;
|
||||||
|
@ -5146,7 +5146,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
|
||||||
if (isTailCall)
|
if (isTailCall)
|
||||||
mModule->mBfIRBuilder->SetTailCall(callInst);
|
mModule->mBfIRBuilder->SetTailCall(callInst);
|
||||||
|
|
||||||
if (methodDef->mNoReturn)
|
if (methodDef->mIsNoReturn)
|
||||||
{
|
{
|
||||||
mModule->mBfIRBuilder->CreateUnreachable();
|
mModule->mBfIRBuilder->CreateUnreachable();
|
||||||
// For debuggability when looking back at stack trace
|
// For debuggability when looking back at stack trace
|
||||||
|
@ -15737,7 +15737,7 @@ bool BfExprEvaluator::CheckIsBase(BfAstNode* checkNode)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BfExprEvaluator::CheckModifyResult(BfTypedValue typedVal, BfAstNode* refNode, const char* modifyType, bool onlyNeedsMut)
|
bool BfExprEvaluator::CheckModifyResult(BfTypedValue typedVal, BfAstNode* refNode, const char* modifyType, bool onlyNeedsMut, bool emitWarning)
|
||||||
{
|
{
|
||||||
BfLocalVariable* localVar = NULL;
|
BfLocalVariable* localVar = NULL;
|
||||||
bool isCapturedLocal = false;
|
bool isCapturedLocal = false;
|
||||||
|
@ -15774,6 +15774,14 @@ bool BfExprEvaluator::CheckModifyResult(BfTypedValue typedVal, BfAstNode* refNod
|
||||||
|
|
||||||
bool canModify = typedVal.CanModify();
|
bool canModify = typedVal.CanModify();
|
||||||
|
|
||||||
|
auto _Fail = [&](const StringImpl& error, BfAstNode* refNode)
|
||||||
|
{
|
||||||
|
if (emitWarning)
|
||||||
|
return mModule->Warn(BfWarning_BF4204_AddressOfReadOnly, error, refNode);
|
||||||
|
else
|
||||||
|
return mModule->Fail(error, refNode);
|
||||||
|
};
|
||||||
|
|
||||||
if (localVar != NULL)
|
if (localVar != NULL)
|
||||||
{
|
{
|
||||||
if (!canModify)
|
if (!canModify)
|
||||||
|
@ -15807,18 +15815,18 @@ bool BfExprEvaluator::CheckModifyResult(BfTypedValue typedVal, BfAstNode* refNod
|
||||||
if (isClosure)
|
if (isClosure)
|
||||||
{
|
{
|
||||||
if (!mModule->mCurMethodState->mClosureState->mDeclaringMethodIsMutating)
|
if (!mModule->mCurMethodState->mClosureState->mDeclaringMethodIsMutating)
|
||||||
error = mModule->Fail(StrFormat("Cannot %s 'this' within struct lambda. Consider adding 'mut' specifier to this method.", modifyType), refNode);
|
error = _Fail(StrFormat("Cannot %s 'this' within struct lambda. Consider adding 'mut' specifier to this method.", modifyType), refNode);
|
||||||
else
|
else
|
||||||
error = mModule->Fail(StrFormat("Cannot %s 'this' within struct lambda. Consider adding by-reference capture specifier [&] to lambda.", modifyType), refNode);
|
error = _Fail(StrFormat("Cannot %s 'this' within struct lambda. Consider adding by-reference capture specifier [&] to lambda.", modifyType), refNode);
|
||||||
}
|
}
|
||||||
else if (localVar->mResolvedType->IsValueType())
|
else if (localVar->mResolvedType->IsValueType())
|
||||||
{
|
{
|
||||||
error = mModule->Fail(StrFormat("Cannot %s 'this' within struct method '%s'. Consider adding 'mut' specifier to this method.", modifyType,
|
error = _Fail(StrFormat("Cannot %s 'this' within struct method '%s'. Consider adding 'mut' specifier to this method.", modifyType,
|
||||||
mModule->MethodToString(mModule->mCurMethodInstance).c_str()), refNode);
|
mModule->MethodToString(mModule->mCurMethodInstance).c_str()), refNode);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error = mModule->Fail(StrFormat("Cannot %s 'this' because '%s' is a reference type.", modifyType,
|
error = _Fail(StrFormat("Cannot %s 'this' because '%s' is a reference type.", modifyType,
|
||||||
mModule->TypeToString(localVar->mResolvedType).c_str()), refNode);
|
mModule->TypeToString(localVar->mResolvedType).c_str()), refNode);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -15827,21 +15835,21 @@ bool BfExprEvaluator::CheckModifyResult(BfTypedValue typedVal, BfAstNode* refNod
|
||||||
{
|
{
|
||||||
if (isCapturedLocal)
|
if (isCapturedLocal)
|
||||||
{
|
{
|
||||||
error = mModule->Fail(StrFormat("Cannot %s read-only captured local variable '%s'. Consider adding by-reference capture specifier [&] to lambda and ensuring that captured value is not read-only.", modifyType,
|
error = _Fail(StrFormat("Cannot %s read-only captured local variable '%s'. Consider adding by-reference capture specifier [&] to lambda and ensuring that captured value is not read-only.", modifyType,
|
||||||
mResultFieldInstance->GetFieldDef()->mName.c_str()), refNode);
|
mResultFieldInstance->GetFieldDef()->mName.c_str()), refNode);
|
||||||
}
|
}
|
||||||
else if (isClosure)
|
else if (isClosure)
|
||||||
{
|
{
|
||||||
if (!mModule->mCurMethodState->mClosureState->mDeclaringMethodIsMutating)
|
if (!mModule->mCurMethodState->mClosureState->mDeclaringMethodIsMutating)
|
||||||
error = mModule->Fail(StrFormat("Cannot %s field '%s.%s' within struct lambda. Consider adding 'mut' specifier to this method.", modifyType,
|
error = _Fail(StrFormat("Cannot %s field '%s.%s' within struct lambda. Consider adding 'mut' specifier to this method.", modifyType,
|
||||||
mModule->TypeToString(mResultFieldInstance->mOwner).c_str(), mResultFieldInstance->GetFieldDef()->mName.c_str()), refNode);
|
mModule->TypeToString(mResultFieldInstance->mOwner).c_str(), mResultFieldInstance->GetFieldDef()->mName.c_str()), refNode);
|
||||||
else
|
else
|
||||||
error = mModule->Fail(StrFormat("Cannot %s field '%s.%s' within struct lambda. Consider adding by-reference capture specifier [&] to lambda.", modifyType,
|
error = _Fail(StrFormat("Cannot %s field '%s.%s' within struct lambda. Consider adding by-reference capture specifier [&] to lambda.", modifyType,
|
||||||
mModule->TypeToString(mResultFieldInstance->mOwner).c_str(), mResultFieldInstance->GetFieldDef()->mName.c_str()), refNode);
|
mModule->TypeToString(mResultFieldInstance->mOwner).c_str(), mResultFieldInstance->GetFieldDef()->mName.c_str()), refNode);
|
||||||
}
|
}
|
||||||
else if (mResultFieldInstance->GetFieldDef()->mIsReadOnly)
|
else if (mResultFieldInstance->GetFieldDef()->mIsReadOnly)
|
||||||
{
|
{
|
||||||
error = mModule->Fail(StrFormat("Cannot %s readonly field '%s.%s' within method '%s'", modifyType,
|
error = _Fail(StrFormat("Cannot %s readonly field '%s.%s' within method '%s'", modifyType,
|
||||||
mModule->TypeToString(mResultFieldInstance->mOwner).c_str(), mResultFieldInstance->GetFieldDef()->mName.c_str(),
|
mModule->TypeToString(mResultFieldInstance->mOwner).c_str(), mResultFieldInstance->GetFieldDef()->mName.c_str(),
|
||||||
mModule->MethodToString(mModule->mCurMethodInstance).c_str()), refNode);
|
mModule->MethodToString(mModule->mCurMethodInstance).c_str()), refNode);
|
||||||
}
|
}
|
||||||
|
@ -15851,12 +15859,12 @@ bool BfExprEvaluator::CheckModifyResult(BfTypedValue typedVal, BfAstNode* refNod
|
||||||
if (propertyDeclaration->mNameNode != NULL)
|
if (propertyDeclaration->mNameNode != NULL)
|
||||||
propertyDeclaration->mNameNode->ToString(propNam);
|
propertyDeclaration->mNameNode->ToString(propNam);
|
||||||
|
|
||||||
error = mModule->Fail(StrFormat("Cannot %s auto-implemented property '%s.%s' without set accessor", modifyType,
|
error = _Fail(StrFormat("Cannot %s auto-implemented property '%s.%s' without set accessor", modifyType,
|
||||||
mModule->TypeToString(mResultFieldInstance->mOwner).c_str(), propNam.c_str()), refNode);
|
mModule->TypeToString(mResultFieldInstance->mOwner).c_str(), propNam.c_str()), refNode);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error = mModule->Fail(StrFormat("Cannot %s field '%s.%s' within struct method '%s'. Consider adding 'mut' specifier to this method.", modifyType,
|
error = _Fail(StrFormat("Cannot %s field '%s.%s' within struct method '%s'. Consider adding 'mut' specifier to this method.", modifyType,
|
||||||
mModule->TypeToString(mResultFieldInstance->mOwner).c_str(), mResultFieldInstance->GetFieldDef()->mName.c_str(),
|
mModule->TypeToString(mResultFieldInstance->mOwner).c_str(), mResultFieldInstance->GetFieldDef()->mName.c_str(),
|
||||||
mModule->MethodToString(mModule->mCurMethodInstance).c_str()), refNode);
|
mModule->MethodToString(mModule->mCurMethodInstance).c_str()), refNode);
|
||||||
}
|
}
|
||||||
|
@ -15868,13 +15876,13 @@ bool BfExprEvaluator::CheckModifyResult(BfTypedValue typedVal, BfAstNode* refNod
|
||||||
if (!mModule->mCurMethodInstance->IsMixin())
|
if (!mModule->mCurMethodInstance->IsMixin())
|
||||||
{
|
{
|
||||||
if (mModule->mCurMethodState->mMixinState != NULL)
|
if (mModule->mCurMethodState->mMixinState != NULL)
|
||||||
error = mModule->Fail(StrFormat("Cannot %s mixin parameter '%s'", modifyType,
|
error = _Fail(StrFormat("Cannot %s mixin parameter '%s'", modifyType,
|
||||||
localVar->mName.c_str(), mModule->MethodToString(mModule->mCurMethodInstance).c_str()), refNode);
|
localVar->mName.c_str(), mModule->MethodToString(mModule->mCurMethodInstance).c_str()), refNode);
|
||||||
else if ((localVar->mResolvedType->IsGenericParam()) && (onlyNeedsMut))
|
else if ((localVar->mResolvedType->IsGenericParam()) && (onlyNeedsMut))
|
||||||
error = mModule->Fail(StrFormat("Cannot %s parameter '%s'. Consider adding 'mut' or 'ref' specifier to parameter or copying to a local variable.", modifyType,
|
error = _Fail(StrFormat("Cannot %s parameter '%s'. Consider adding 'mut' or 'ref' specifier to parameter or copying to a local variable.", modifyType,
|
||||||
localVar->mName.c_str(), mModule->MethodToString(mModule->mCurMethodInstance).c_str()), refNode);
|
localVar->mName.c_str(), mModule->MethodToString(mModule->mCurMethodInstance).c_str()), refNode);
|
||||||
else
|
else
|
||||||
error = mModule->Fail(StrFormat("Cannot %s parameter '%s'. Consider adding 'ref' specifier to parameter or copying to a local variable.", modifyType,
|
error = _Fail(StrFormat("Cannot %s parameter '%s'. Consider adding 'ref' specifier to parameter or copying to a local variable.", modifyType,
|
||||||
localVar->mName.c_str(), mModule->MethodToString(mModule->mCurMethodInstance).c_str()), refNode);
|
localVar->mName.c_str(), mModule->MethodToString(mModule->mCurMethodInstance).c_str()), refNode);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -15891,7 +15899,7 @@ bool BfExprEvaluator::CheckModifyResult(BfTypedValue typedVal, BfAstNode* refNod
|
||||||
{
|
{
|
||||||
if (field.mDataIdx == dataIdx)
|
if (field.mDataIdx == dataIdx)
|
||||||
{
|
{
|
||||||
error = mModule->Fail(StrFormat("Cannot %s readonly field '%s.%s'.", modifyType,
|
error = _Fail(StrFormat("Cannot %s readonly field '%s.%s'.", modifyType,
|
||||||
mModule->TypeToString(typeInst).c_str(),
|
mModule->TypeToString(typeInst).c_str(),
|
||||||
field.GetFieldDef()->mName.c_str()), refNode);
|
field.GetFieldDef()->mName.c_str()), refNode);
|
||||||
break;
|
break;
|
||||||
|
@ -15904,7 +15912,7 @@ bool BfExprEvaluator::CheckModifyResult(BfTypedValue typedVal, BfAstNode* refNod
|
||||||
|
|
||||||
if (error == NULL)
|
if (error == NULL)
|
||||||
{
|
{
|
||||||
error = mModule->Fail(StrFormat("Cannot %s read-only local variable '%s'.", modifyType,
|
error = _Fail(StrFormat("Cannot %s read-only local variable '%s'.", modifyType,
|
||||||
localVar->mName.c_str()), refNode);
|
localVar->mName.c_str()), refNode);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -15919,14 +15927,13 @@ bool BfExprEvaluator::CheckModifyResult(BfTypedValue typedVal, BfAstNode* refNod
|
||||||
|
|
||||||
if ((mResultFieldInstance != NULL) && (mResultFieldInstance->GetFieldDef()->mIsReadOnly) && (!canModify))
|
if ((mResultFieldInstance != NULL) && (mResultFieldInstance->GetFieldDef()->mIsReadOnly) && (!canModify))
|
||||||
{
|
{
|
||||||
auto error = mModule->Fail(StrFormat("Cannot %s static readonly field '%s.%s' within method '%s'", modifyType,
|
auto error = _Fail(StrFormat("Cannot %s static readonly field '%s.%s' within method '%s'", modifyType,
|
||||||
mModule->TypeToString(mResultFieldInstance->mOwner).c_str(), mResultFieldInstance->GetFieldDef()->mName.c_str(),
|
mModule->TypeToString(mResultFieldInstance->mOwner).c_str(), mResultFieldInstance->GetFieldDef()->mName.c_str(),
|
||||||
mModule->MethodToString(mModule->mCurMethodInstance).c_str()), refNode);
|
mModule->MethodToString(mModule->mCurMethodInstance).c_str()), refNode);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return mModule->CheckModifyValue(typedVal, refNode, modifyType);
|
return mModule->CheckModifyValue(typedVal, refNode, modifyType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18367,12 +18374,18 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr,
|
||||||
mModule->FixIntUnknown(mResult);
|
mModule->FixIntUnknown(mResult);
|
||||||
mModule->PopulateType(mResult.mType);
|
mModule->PopulateType(mResult.mType);
|
||||||
auto ptrType = mModule->CreatePointerType(mResult.mType);
|
auto ptrType = mModule->CreatePointerType(mResult.mType);
|
||||||
if ((!CheckModifyResult(mResult, unaryOpExpr, "take address of")) || (mResult.mType->IsValuelessType()))
|
if (mResult.mType->IsValuelessType())
|
||||||
{
|
{
|
||||||
// Sentinel value
|
// Sentinel value
|
||||||
auto val = mModule->mBfIRBuilder->CreateIntToPtr(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 1), mModule->mBfIRBuilder->MapType(ptrType));
|
auto val = mModule->mBfIRBuilder->CreateIntToPtr(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 1), mModule->mBfIRBuilder->MapType(ptrType));
|
||||||
mResult = BfTypedValue(val, ptrType);
|
mResult = BfTypedValue(val, ptrType);
|
||||||
}
|
}
|
||||||
|
else if (!CheckModifyResult(mResult, unaryOpExpr, "take address of", false, true))
|
||||||
|
{
|
||||||
|
if (!mResult.IsAddr())
|
||||||
|
mResult = mModule->MakeAddressable(mResult);
|
||||||
|
mResult = BfTypedValue(mResult.mValue, ptrType, false);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
mResult = BfTypedValue(mResult.mValue, ptrType, false);
|
mResult = BfTypedValue(mResult.mValue, ptrType, false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -377,7 +377,7 @@ public:
|
||||||
void MarkResultAssigned();
|
void MarkResultAssigned();
|
||||||
void MakeResultAsValue();
|
void MakeResultAsValue();
|
||||||
bool CheckIsBase(BfAstNode* checkNode);
|
bool CheckIsBase(BfAstNode* checkNode);
|
||||||
bool CheckModifyResult(BfTypedValue typeValue, BfAstNode* refNode, const char* modifyType, bool onlyNeedsMut = false);
|
bool CheckModifyResult(BfTypedValue typeValue, BfAstNode* refNode, const char* modifyType, bool onlyNeedsMut = false, bool emitWarning = false);
|
||||||
bool CheckGenericCtor(BfGenericParamType* genericParamType, BfResolvedArgs& argValues, BfAstNode* targetSrc);
|
bool CheckGenericCtor(BfGenericParamType* genericParamType, BfResolvedArgs& argValues, BfAstNode* targetSrc);
|
||||||
BfTypedValue LookupField(BfAstNode* targetSrc, BfTypedValue target, const StringImpl& fieldName, BfLookupFieldFlags flags = BfLookupFieldFlag_None);
|
BfTypedValue LookupField(BfAstNode* targetSrc, BfTypedValue target, const StringImpl& fieldName, BfLookupFieldFlags flags = BfLookupFieldFlag_None);
|
||||||
void CheckObjectCreateTypeRef(BfType* expectingType, BfAstNode* afterNode);
|
void CheckObjectCreateTypeRef(BfType* expectingType, BfAstNode* afterNode);
|
||||||
|
|
|
@ -6113,7 +6113,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
if (!methodInstanceGroup->IsImplemented())
|
if (!methodInstanceGroup->IsImplemented())
|
||||||
continue;
|
continue;
|
||||||
auto methodDef = typeDef->mMethods[methodIdx];
|
auto methodDef = typeDef->mMethods[methodIdx];
|
||||||
if (methodDef->mNoReflect)
|
if (methodDef->mIsNoReflect)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto defaultMethod = methodInstanceGroup->mDefault;
|
auto defaultMethod = methodInstanceGroup->mDefault;
|
||||||
|
@ -15146,7 +15146,7 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func
|
||||||
|
|
||||||
if (methodDef->mImportKind == BfImportKind_Export)
|
if (methodDef->mImportKind == BfImportKind_Export)
|
||||||
mBfIRBuilder->Func_AddAttribute(func, -1, BFIRAttribute_DllExport);
|
mBfIRBuilder->Func_AddAttribute(func, -1, BFIRAttribute_DllExport);
|
||||||
if (methodDef->mNoReturn)
|
if (methodDef->mIsNoReturn)
|
||||||
mBfIRBuilder->Func_AddAttribute(func, -1, BfIRAttribute_NoReturn);
|
mBfIRBuilder->Func_AddAttribute(func, -1, BfIRAttribute_NoReturn);
|
||||||
auto callingConv = GetIRCallingConvention(methodInstance);
|
auto callingConv = GetIRCallingConvention(methodInstance);
|
||||||
if (callingConv != BfIRCallingConv_CDecl)
|
if (callingConv != BfIRCallingConv_CDecl)
|
||||||
|
|
|
@ -764,6 +764,8 @@ bool BfMethodInstance::AllowsSplatting()
|
||||||
{
|
{
|
||||||
if (mCallingConvention != BfCallingConvention_Unspecified)
|
if (mCallingConvention != BfCallingConvention_Unspecified)
|
||||||
return false;
|
return false;
|
||||||
|
if (mMethodDef->mIsNoSplat)
|
||||||
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -771,6 +773,8 @@ bool BfMethodInstance::AllowsThisSplatting()
|
||||||
{
|
{
|
||||||
if (mCallingConvention != BfCallingConvention_Unspecified)
|
if (mCallingConvention != BfCallingConvention_Unspecified)
|
||||||
return false;
|
return false;
|
||||||
|
if (mMethodDef->mIsNoSplat)
|
||||||
|
return false;
|
||||||
return !mMethodDef->HasNoThisSplat();
|
return !mMethodDef->HasNoThisSplat();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -720,9 +720,10 @@ public:
|
||||||
bool mCLink;
|
bool mCLink;
|
||||||
bool mHasAppend;
|
bool mHasAppend;
|
||||||
bool mAlwaysInline;
|
bool mAlwaysInline;
|
||||||
bool mNoReturn;
|
bool mIsNoReturn;
|
||||||
bool mIsMutating;
|
bool mIsMutating;
|
||||||
bool mNoReflect;
|
bool mIsNoSplat;
|
||||||
|
bool mIsNoReflect;
|
||||||
bool mIsSkipCall;
|
bool mIsSkipCall;
|
||||||
bool mIsOperator;
|
bool mIsOperator;
|
||||||
bool mIsExtern;
|
bool mIsExtern;
|
||||||
|
@ -747,9 +748,10 @@ public:
|
||||||
mIsNew = false;
|
mIsNew = false;
|
||||||
mIsPartial = false;
|
mIsPartial = false;
|
||||||
mCLink = false;
|
mCLink = false;
|
||||||
mNoReturn = false;
|
mIsNoReturn = false;
|
||||||
mIsMutating = false;
|
mIsMutating = false;
|
||||||
mNoReflect = false;
|
mIsNoSplat = false;
|
||||||
|
mIsNoReflect = false;
|
||||||
mIsSkipCall = false;
|
mIsSkipCall = false;
|
||||||
mIsOperator = false;
|
mIsOperator = false;
|
||||||
mIsExtern = false;
|
mIsExtern = false;
|
||||||
|
@ -774,7 +776,7 @@ public:
|
||||||
virtual ~BfMethodDef();
|
virtual ~BfMethodDef();
|
||||||
|
|
||||||
static BfImportKind GetImportKindFromPath(const StringImpl& filePath);
|
static BfImportKind GetImportKindFromPath(const StringImpl& filePath);
|
||||||
bool HasNoThisSplat() { return mIsMutating; }
|
bool HasNoThisSplat() { return mIsMutating || mIsNoSplat; }
|
||||||
void Reset();
|
void Reset();
|
||||||
void FreeMembers();
|
void FreeMembers();
|
||||||
BfMethodDeclaration* GetMethodDeclaration();
|
BfMethodDeclaration* GetMethodDeclaration();
|
||||||
|
@ -1103,6 +1105,7 @@ enum BfWarning
|
||||||
BfWarning_BF4201_Only7Hex = 4201,
|
BfWarning_BF4201_Only7Hex = 4201,
|
||||||
BfWarning_BF4202_TooManyHexForInt = 4202,
|
BfWarning_BF4202_TooManyHexForInt = 4202,
|
||||||
BfWarning_BF4203_UnnecessaryDynamicCast = 4203,
|
BfWarning_BF4203_UnnecessaryDynamicCast = 4203,
|
||||||
|
BfWarning_BF4204_AddressOfReadOnly = 4204,
|
||||||
BfWarning_C4554_PossiblePrecedenceError = 4554
|
BfWarning_C4554_PossiblePrecedenceError = 4554
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue