mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 03:52:19 +02:00
Added [?] implied size for sized arrays with initializers
This commit is contained in:
parent
82d2963a9e
commit
08e38a03f9
10 changed files with 250 additions and 162 deletions
|
@ -36,6 +36,38 @@ BfConstResolver::BfConstResolver(BfModule* bfModule) : BfExprEvaluator(bfModule)
|
||||||
|
|
||||||
BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfConstResolveFlags flags)
|
BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfConstResolveFlags flags)
|
||||||
{
|
{
|
||||||
|
// Handle the 'int[?] val = .(1, 2, 3)' case
|
||||||
|
if ((flags & BfConstResolveFlag_ArrayInitSize) != 0)
|
||||||
|
{
|
||||||
|
if (auto uninitExpr = BfNodeDynCast<BfUninitializedExpression>(expr))
|
||||||
|
{
|
||||||
|
BfAstNode* initializer = NULL;
|
||||||
|
int arraySize = -1;
|
||||||
|
|
||||||
|
if (mModule->mContext->mCurTypeState != NULL)
|
||||||
|
{
|
||||||
|
if (mModule->mContext->mCurTypeState->mCurFieldDef != NULL)
|
||||||
|
initializer = mModule->mContext->mCurTypeState->mCurFieldDef->mInitializer;
|
||||||
|
if (mModule->mContext->mCurTypeState->mCurVarInitializer != NULL)
|
||||||
|
initializer = mModule->mContext->mCurTypeState->mCurVarInitializer;
|
||||||
|
if (mModule->mContext->mCurTypeState->mArrayInitializerSize != -1)
|
||||||
|
arraySize = mModule->mContext->mCurTypeState->mArrayInitializerSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (initializer != NULL)
|
||||||
|
{
|
||||||
|
if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(initializer))
|
||||||
|
arraySize = (int)invocationExpr->mArguments.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arraySize != -1)
|
||||||
|
{
|
||||||
|
mResult = BfTypedValue(mModule->GetConstValue(arraySize), mModule->GetPrimitiveType(BfTypeCode_IntPtr));
|
||||||
|
return mResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool explicitCast = (flags & BfConstResolveFlag_ExplicitCast) != 0;
|
bool explicitCast = (flags & BfConstResolveFlag_ExplicitCast) != 0;
|
||||||
bool noCast = (flags & BfConstResolveFlag_NoCast) != 0;
|
bool noCast = (flags & BfConstResolveFlag_NoCast) != 0;
|
||||||
bool allowSoftFail = (flags & BfConstResolveFlag_AllowSoftFail) != 0;
|
bool allowSoftFail = (flags & BfConstResolveFlag_AllowSoftFail) != 0;
|
||||||
|
|
|
@ -15,7 +15,8 @@ enum BfConstResolveFlags
|
||||||
BfConstResolveFlag_ExplicitCast = 1,
|
BfConstResolveFlag_ExplicitCast = 1,
|
||||||
BfConstResolveFlag_NoCast = 2,
|
BfConstResolveFlag_NoCast = 2,
|
||||||
BfConstResolveFlag_AllowSoftFail = 4,
|
BfConstResolveFlag_AllowSoftFail = 4,
|
||||||
BfConstResolveFlag_RemapFromStringId = 8
|
BfConstResolveFlag_RemapFromStringId = 8,
|
||||||
|
BfConstResolveFlag_ArrayInitSize = 0x10
|
||||||
};
|
};
|
||||||
|
|
||||||
class BfConstResolver : public BfExprEvaluator
|
class BfConstResolver : public BfExprEvaluator
|
||||||
|
|
|
@ -116,6 +116,7 @@ public:
|
||||||
ResolveKind_BuildingGenericParams,
|
ResolveKind_BuildingGenericParams,
|
||||||
ResolveKind_ResolvingVarType,
|
ResolveKind_ResolvingVarType,
|
||||||
ResolveKind_UnionInnerType,
|
ResolveKind_UnionInnerType,
|
||||||
|
ResolveKind_LocalVariable,
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -131,6 +132,8 @@ public:
|
||||||
BfFieldDef* mCurFieldDef;
|
BfFieldDef* mCurFieldDef;
|
||||||
BfTypeDef* mCurTypeDef;
|
BfTypeDef* mCurTypeDef;
|
||||||
ResolveKind mResolveKind;
|
ResolveKind mResolveKind;
|
||||||
|
BfAstNode* mCurVarInitializer;
|
||||||
|
int mArrayInitializerSize;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BfTypeState()
|
BfTypeState()
|
||||||
|
@ -144,6 +147,8 @@ public:
|
||||||
mCurFieldDef = NULL;
|
mCurFieldDef = NULL;
|
||||||
mCurAttributeTypeRef = NULL;
|
mCurAttributeTypeRef = NULL;
|
||||||
mCurTypeDef = NULL;
|
mCurTypeDef = NULL;
|
||||||
|
mCurVarInitializer = NULL;
|
||||||
|
mArrayInitializerSize = -1;
|
||||||
mResolveKind = ResolveKind_None;
|
mResolveKind = ResolveKind_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,6 +163,8 @@ public:
|
||||||
mCurFieldDef = NULL;
|
mCurFieldDef = NULL;
|
||||||
mCurAttributeTypeRef = NULL;
|
mCurAttributeTypeRef = NULL;
|
||||||
mCurTypeDef = NULL;
|
mCurTypeDef = NULL;
|
||||||
|
mCurVarInitializer = NULL;
|
||||||
|
mArrayInitializerSize = -1;
|
||||||
mResolveKind = ResolveKind_None;
|
mResolveKind = ResolveKind_None;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -11796,7 +11796,23 @@ void BfExprEvaluator::Visit(BfObjectCreateExpression* objCreateExpr)
|
||||||
|
|
||||||
int writeIdx = 0;
|
int writeIdx = 0;
|
||||||
|
|
||||||
std::function<void(BfIRValue addr, int curDim, const BfSizedArray<BfExpression*>& valueExprs)> _HandleInitExprs = [&](BfIRValue addr, int curDim, const BfSizedArray<BfExpression*>& valueExprs)
|
struct BfInitContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BfModule* mModule;
|
||||||
|
BfType* resultType;
|
||||||
|
int dimensions;
|
||||||
|
SizedArray<BfIRValue, 2>& dimLengthVals;
|
||||||
|
BfIRValue arraySize;
|
||||||
|
int& writeIdx;
|
||||||
|
|
||||||
|
BfInitContext(BfModule* module, BfType* resultType, int dimensions, SizedArray<BfIRValue, 2>& dimLengthVals, BfIRValue arraySize, int& writeIdx) :
|
||||||
|
mModule(module), resultType(resultType), dimensions(dimensions), dimLengthVals(dimLengthVals), arraySize(arraySize), writeIdx(writeIdx)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Handle(BfIRValue addr, int curDim, const BfSizedArray<BfExpression*>& valueExprs)
|
||||||
{
|
{
|
||||||
int exprIdx = 0;
|
int exprIdx = 0;
|
||||||
int dimWriteIdx = 0;
|
int dimWriteIdx = 0;
|
||||||
|
@ -11828,17 +11844,17 @@ void BfExprEvaluator::Visit(BfObjectCreateExpression* objCreateExpr)
|
||||||
{
|
{
|
||||||
if (auto innerTupleExpr = BfNodeDynCast<BfTupleExpression>(initExpr))
|
if (auto innerTupleExpr = BfNodeDynCast<BfTupleExpression>(initExpr))
|
||||||
{
|
{
|
||||||
_HandleInitExprs(addr, curDim + 1, innerTupleExpr->mValues);
|
Handle(addr, curDim + 1, innerTupleExpr->mValues);
|
||||||
}
|
}
|
||||||
else if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(initExpr))
|
else if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(initExpr))
|
||||||
{
|
{
|
||||||
SizedArray<BfExpression*, 1> values;
|
SizedArray<BfExpression*, 1> values;
|
||||||
values.Add(parenExpr->mExpression);
|
values.Add(parenExpr->mExpression);
|
||||||
_HandleInitExprs(addr, curDim + 1, values);
|
Handle(addr, curDim + 1, values);
|
||||||
}
|
}
|
||||||
else if (auto innerInitExpr = BfNodeDynCast<BfCollectionInitializerExpression>(initExpr))
|
else if (auto innerInitExpr = BfNodeDynCast<BfCollectionInitializerExpression>(initExpr))
|
||||||
{
|
{
|
||||||
_HandleInitExprs(addr, curDim + 1, innerInitExpr->mValues);
|
Handle(addr, curDim + 1, innerInitExpr->mValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
dimWriteIdx++;
|
dimWriteIdx++;
|
||||||
|
@ -11957,13 +11973,16 @@ void BfExprEvaluator::Visit(BfObjectCreateExpression* objCreateExpr)
|
||||||
mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int8, isUninit ? 0xCC : 0), clearBytes, resultType->mAlign);
|
mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int8, isUninit ? 0xCC : 0), clearBytes, resultType->mAlign);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BfInitContext initContext(mModule, resultType, dimensions, dimLengthVals, arraySize, writeIdx);
|
||||||
|
|
||||||
if (resultType->IsVar())
|
if (resultType->IsVar())
|
||||||
{
|
{
|
||||||
SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
|
SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
|
||||||
mResult = BfTypedValue(BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), mModule->GetPrimitiveType(BfTypeCode_Var)));
|
mResult = BfTypedValue(BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), mModule->GetPrimitiveType(BfTypeCode_Var)));
|
||||||
_HandleInitExprs(mResult.mValue, 0, objCreateExpr->mArguments);
|
initContext.Handle(mResult.mValue, 0, objCreateExpr->mArguments);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11978,7 +11997,7 @@ void BfExprEvaluator::Visit(BfObjectCreateExpression* objCreateExpr)
|
||||||
arrayValue = BfTypedValue(mModule->AllocFromType(resultType, allocTarget, BfIRValue(), arraySize, (int)dimLengthVals.size(), allocFlags, allocTarget.mAlignOverride), ptrType);
|
arrayValue = BfTypedValue(mModule->AllocFromType(resultType, allocTarget, BfIRValue(), arraySize, (int)dimLengthVals.size(), allocFlags, allocTarget.mAlignOverride), ptrType);
|
||||||
}
|
}
|
||||||
|
|
||||||
_HandleInitExprs(arrayValue.mValue, 0, objCreateExpr->mArguments);
|
initContext.Handle(arrayValue.mValue, 0, objCreateExpr->mArguments);
|
||||||
|
|
||||||
mResult = arrayValue;
|
mResult = arrayValue;
|
||||||
return;
|
return;
|
||||||
|
@ -12073,7 +12092,8 @@ void BfExprEvaluator::Visit(BfObjectCreateExpression* objCreateExpr)
|
||||||
addr = mModule->mBfIRBuilder->GetFakeVal();
|
addr = mModule->mBfIRBuilder->GetFakeVal();
|
||||||
else
|
else
|
||||||
addr = mModule->mBfIRBuilder->CreateInBoundsGEP(arrayValue.mValue, 0, firstElementFieldInstance->mDataIdx);
|
addr = mModule->mBfIRBuilder->CreateInBoundsGEP(arrayValue.mValue, 0, firstElementFieldInstance->mDataIdx);
|
||||||
_HandleInitExprs(addr, 0, objCreateExpr->mArguments);
|
|
||||||
|
initContext.Handle(addr, 0, objCreateExpr->mArguments);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -14370,13 +14390,18 @@ void BfExprEvaluator::Visit(BfInvocationExpression* invocationExpr)
|
||||||
|
|
||||||
int arrSize = 0;
|
int arrSize = 0;
|
||||||
|
|
||||||
|
BfTypeState typeState;
|
||||||
|
typeState.mArrayInitializerSize = (int)invocationExpr->mArguments.size();
|
||||||
|
SetAndRestoreValue<BfTypeState*> prevTypeState(mModule->mContext->mCurTypeState, &typeState);
|
||||||
|
|
||||||
if (indexerExpr->mArguments.size() != 0)
|
if (indexerExpr->mArguments.size() != 0)
|
||||||
{
|
{
|
||||||
BfConstResolver constResolver(mModule);
|
BfConstResolver constResolver(mModule);
|
||||||
auto arg = indexerExpr->mArguments[0];
|
auto arg = indexerExpr->mArguments[0];
|
||||||
|
constResolver.mExpectingType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
|
||||||
|
|
||||||
if (arg != NULL)
|
if (arg != NULL)
|
||||||
constResolver.Resolve(arg);
|
constResolver.Resolve(arg, NULL, BfConstResolveFlag_ArrayInitSize);
|
||||||
|
|
||||||
if (constResolver.mResult.mValue.IsConst())
|
if (constResolver.mResult.mValue.IsConst())
|
||||||
{
|
{
|
||||||
|
|
|
@ -3721,7 +3721,7 @@ bool BfModule::IsThreadLocal(BfFieldInstance * fieldInstance)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance, BfExpression* initializer, BfFieldDef* fieldDef, BfType* fieldType)
|
BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance, BfExpression* initializer, BfFieldDef* fieldDef, BfType* fieldType, bool doStore)
|
||||||
{
|
{
|
||||||
if (fieldDef == NULL)
|
if (fieldDef == NULL)
|
||||||
fieldDef = fieldInstance->GetFieldDef();
|
fieldDef = fieldInstance->GetFieldDef();
|
||||||
|
@ -3734,6 +3734,8 @@ BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance,
|
||||||
initializer = fieldDef->mInitializer;
|
initializer = fieldDef->mInitializer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BfTypedValue staticVarRef;
|
||||||
|
|
||||||
BfTypedValue result;
|
BfTypedValue result;
|
||||||
if (initializer == NULL)
|
if (initializer == NULL)
|
||||||
{
|
{
|
||||||
|
@ -3780,15 +3782,33 @@ BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BfExprEvaluator exprEvaluator(this);
|
||||||
|
if (doStore)
|
||||||
|
{
|
||||||
|
staticVarRef = ReferenceStaticField(fieldInstance);
|
||||||
|
exprEvaluator.mReceivingValue = &staticVarRef;
|
||||||
|
}
|
||||||
if (fieldType->IsVar())
|
if (fieldType->IsVar())
|
||||||
result = CreateValueFromExpression(initializer, NULL, (BfEvalExprFlags)(BfEvalExprFlags_NoValueAddr | BfEvalExprFlags_FieldInitializer));
|
result = CreateValueFromExpression(exprEvaluator, initializer, NULL, (BfEvalExprFlags)(BfEvalExprFlags_NoValueAddr | BfEvalExprFlags_FieldInitializer));
|
||||||
else
|
else
|
||||||
result = CreateValueFromExpression(initializer, fieldType, (BfEvalExprFlags)(BfEvalExprFlags_NoValueAddr | BfEvalExprFlags_FieldInitializer));
|
result = CreateValueFromExpression(exprEvaluator, initializer, fieldType, (BfEvalExprFlags)(BfEvalExprFlags_NoValueAddr | BfEvalExprFlags_FieldInitializer));
|
||||||
|
if (doStore)
|
||||||
|
{
|
||||||
|
if (exprEvaluator.mReceivingValue == NULL)
|
||||||
|
doStore = false; // Already stored
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fieldInstance != NULL)
|
if (fieldInstance != NULL)
|
||||||
MarkFieldInitialized(fieldInstance);
|
MarkFieldInitialized(fieldInstance);
|
||||||
|
|
||||||
|
if (doStore)
|
||||||
|
{
|
||||||
|
result = LoadValue(result);
|
||||||
|
if (!result.mType->IsValuelessType())
|
||||||
|
mBfIRBuilder->CreateStore(result.mValue, staticVarRef.mValue);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13893,16 +13913,8 @@ void BfModule::CreateStaticCtor()
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto assignValue = GetFieldInitializerValue(fieldInst);
|
GetFieldInitializerValue(fieldInst, NULL, NULL, NULL, true);
|
||||||
if (assignValue)
|
|
||||||
{
|
|
||||||
assignValue = LoadValue(assignValue);
|
|
||||||
if (!assignValue.mType->IsValuelessType())
|
|
||||||
{
|
|
||||||
auto staticVarRef = ReferenceStaticField(fieldInst).mValue;
|
|
||||||
mBfIRBuilder->CreateStore(assignValue.mValue, staticVarRef);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1609,7 +1609,7 @@ public:
|
||||||
BfFieldInstance* GetFieldByName(BfTypeInstance* typeInstance, const StringImpl& fieldName, bool isRequired = true, BfAstNode* refNode = NULL);
|
BfFieldInstance* GetFieldByName(BfTypeInstance* typeInstance, const StringImpl& fieldName, bool isRequired = true, BfAstNode* refNode = NULL);
|
||||||
void CreateStaticField(BfFieldInstance* fieldInstance, bool isThreadLocal = false);
|
void CreateStaticField(BfFieldInstance* fieldInstance, bool isThreadLocal = false);
|
||||||
void ResolveConstField(BfTypeInstance* typeInst, BfFieldInstance* fieldInstance, BfFieldDef* field, bool forceResolve = false);
|
void ResolveConstField(BfTypeInstance* typeInst, BfFieldInstance* fieldInstance, BfFieldDef* field, bool forceResolve = false);
|
||||||
BfTypedValue GetFieldInitializerValue(BfFieldInstance* fieldInstance, BfExpression* initializer = NULL, BfFieldDef* fieldDef = NULL, BfType* fieldType = NULL);
|
BfTypedValue GetFieldInitializerValue(BfFieldInstance* fieldInstance, BfExpression* initializer = NULL, BfFieldDef* fieldDef = NULL, BfType* fieldType = NULL, bool doStore = false);
|
||||||
void MarkFieldInitialized(BfFieldInstance* fieldInstance);
|
void MarkFieldInitialized(BfFieldInstance* fieldInstance);
|
||||||
bool IsThreadLocal(BfFieldInstance* fieldInstance);
|
bool IsThreadLocal(BfFieldInstance* fieldInstance);
|
||||||
BfType* ResolveVarFieldType(BfTypeInstance* typeInst, BfFieldInstance* fieldInstance, BfFieldDef* field);
|
BfType* ResolveVarFieldType(BfTypeInstance* typeInst, BfFieldInstance* fieldInstance, BfFieldDef* field);
|
||||||
|
|
|
@ -7870,7 +7870,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
BfTypedValue typedVal;
|
BfTypedValue typedVal;
|
||||||
{
|
{
|
||||||
SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, true);
|
SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, true);
|
||||||
typedVal = constResolver.Resolve(sizeExpr);
|
typedVal = constResolver.Resolve(sizeExpr, NULL, BfConstResolveFlag_ArrayInitSize);
|
||||||
}
|
}
|
||||||
if (typedVal.mKind == BfTypedValueKind_GenericConstValue)
|
if (typedVal.mKind == BfTypedValueKind_GenericConstValue)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2654,7 +2654,7 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
||||||
BfType* intType = ctx->mModule->GetPrimitiveType(BfTypeCode_IntPtr);
|
BfType* intType = ctx->mModule->GetPrimitiveType(BfTypeCode_IntPtr);
|
||||||
constResolver.mAllowGenericConstValue = true;
|
constResolver.mAllowGenericConstValue = true;
|
||||||
constResolver.mExpectingType = intType;
|
constResolver.mExpectingType = intType;
|
||||||
BfTypedValue typedVal = constResolver.Resolve(sizeExpr);
|
BfTypedValue typedVal = constResolver.Resolve(sizeExpr, NULL, BfConstResolveFlag_ArrayInitSize);
|
||||||
if (typedVal.mKind == BfTypedValueKind_GenericConstValue)
|
if (typedVal.mKind == BfTypedValueKind_GenericConstValue)
|
||||||
{
|
{
|
||||||
int elemHash = Hash(typedVal.mType, ctx);
|
int elemHash = Hash(typedVal.mType, ctx);
|
||||||
|
@ -3550,7 +3550,7 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext*
|
||||||
BfType* intType = ctx->mModule->GetPrimitiveType(BfTypeCode_IntPtr);
|
BfType* intType = ctx->mModule->GetPrimitiveType(BfTypeCode_IntPtr);
|
||||||
constResolver.mAllowGenericConstValue = true;
|
constResolver.mAllowGenericConstValue = true;
|
||||||
constResolver.mExpectingType = intType;
|
constResolver.mExpectingType = intType;
|
||||||
BfTypedValue typedVal = constResolver.Resolve(sizeExpr);
|
BfTypedValue typedVal = constResolver.Resolve(sizeExpr, NULL, BfConstResolveFlag_ArrayInitSize);
|
||||||
if (typedVal.mKind == BfTypedValueKind_GenericConstValue)
|
if (typedVal.mKind == BfTypedValueKind_GenericConstValue)
|
||||||
{
|
{
|
||||||
if (!lhs->IsUnknownSizedArray())
|
if (!lhs->IsUnknownSizedArray())
|
||||||
|
|
|
@ -1563,6 +1563,10 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
BfTypeState typeState;
|
||||||
|
typeState.mCurVarInitializer = varDecl->mInitializer;
|
||||||
|
SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
|
||||||
|
|
||||||
unresolvedType = ResolveTypeRef(varDecl->mTypeRef, BfPopulateType_Data, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoResolveGenericParam | BfResolveTypeRefFlag_AllowRef));
|
unresolvedType = ResolveTypeRef(varDecl->mTypeRef, BfPopulateType_Data, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoResolveGenericParam | BfResolveTypeRefFlag_AllowRef));
|
||||||
if (unresolvedType == NULL)
|
if (unresolvedType == NULL)
|
||||||
unresolvedType = GetPrimitiveType(BfTypeCode_Var);
|
unresolvedType = GetPrimitiveType(BfTypeCode_Var);
|
||||||
|
|
|
@ -5,6 +5,7 @@ namespace Tests
|
||||||
class SizedArrays
|
class SizedArrays
|
||||||
{
|
{
|
||||||
public static int[8] iArr = .(123, 234, 345, );
|
public static int[8] iArr = .(123, 234, 345, );
|
||||||
|
public static int[?] iArr2 = .(12, 23, 34);
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
static void TestBasics()
|
static void TestBasics()
|
||||||
|
@ -24,6 +25,12 @@ namespace Tests
|
||||||
val2[0][0] = 9;
|
val2[0][0] = 9;
|
||||||
Test.Assert(val0 != val2);
|
Test.Assert(val0 != val2);
|
||||||
Test.Assert(val2[1] == val1);
|
Test.Assert(val2[1] == val1);
|
||||||
|
|
||||||
|
int[?] val3 = .(9, 10);
|
||||||
|
Test.Assert(val3[0] == 9);
|
||||||
|
|
||||||
|
var val4 = int[?](11, 12);
|
||||||
|
Test.Assert(val4[0] == 11);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue