Selaa lähdekoodia

Added [?] implied size for sized arrays with initializers

Brian Fiete 5 vuotta sitten
vanhempi
commit
08e38a03f9

+ 32 - 0
IDEHelper/Compiler/BfConstResolver.cpp

@@ -36,6 +36,38 @@ BfConstResolver::BfConstResolver(BfModule* bfModule) : BfExprEvaluator(bfModule)
 
 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 noCast = (flags & BfConstResolveFlag_NoCast) != 0;
 	bool allowSoftFail = (flags & BfConstResolveFlag_AllowSoftFail) != 0;

+ 3 - 2
IDEHelper/Compiler/BfConstResolver.h

@@ -15,7 +15,8 @@ enum BfConstResolveFlags
 	BfConstResolveFlag_ExplicitCast = 1,
 	BfConstResolveFlag_NoCast = 2,
 	BfConstResolveFlag_AllowSoftFail = 4,
-	BfConstResolveFlag_RemapFromStringId = 8
+	BfConstResolveFlag_RemapFromStringId = 8,
+	BfConstResolveFlag_ArrayInitSize = 0x10
 };
 
 class BfConstResolver : public BfExprEvaluator
@@ -31,7 +32,7 @@ public:
 	BfConstResolver(BfModule* bfModule);		
 
 	BfTypedValue Resolve(BfExpression* expr, BfType* wantType = NULL, BfConstResolveFlags flags = BfConstResolveFlag_None);
-	bool PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatcher* methodMatcher, Array<BfIRValue>& llvmArgs);		
+	bool PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatcher* methodMatcher, Array<BfIRValue>& llvmArgs);			
 };
 
 NS_BF_END

+ 7 - 0
IDEHelper/Compiler/BfContext.h

@@ -116,6 +116,7 @@ public:
 		ResolveKind_BuildingGenericParams,
 		ResolveKind_ResolvingVarType,
 		ResolveKind_UnionInnerType,
+		ResolveKind_LocalVariable,
 	};
 
 public:
@@ -131,6 +132,8 @@ public:
 	BfFieldDef* mCurFieldDef;	
 	BfTypeDef* mCurTypeDef;
 	ResolveKind mResolveKind;
+	BfAstNode* mCurVarInitializer;
+	int mArrayInitializerSize;
 
 public:
 	BfTypeState()
@@ -144,6 +147,8 @@ public:
 		mCurFieldDef = NULL;
 		mCurAttributeTypeRef = NULL;
 		mCurTypeDef = NULL;
+		mCurVarInitializer = NULL;
+		mArrayInitializerSize = -1;
 		mResolveKind = ResolveKind_None;
 	}
 
@@ -158,6 +163,8 @@ public:
 		mCurFieldDef = NULL;
 		mCurAttributeTypeRef = NULL;
 		mCurTypeDef = NULL;
+		mCurVarInitializer = NULL;
+		mArrayInitializerSize = -1;
 		mResolveKind = ResolveKind_None;
 	}
 };

+ 152 - 127
IDEHelper/Compiler/BfExprEvaluator.cpp

@@ -11796,174 +11796,193 @@ void BfExprEvaluator::Visit(BfObjectCreateExpression* objCreateExpr)
 		
 		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
 		{
-			int exprIdx = 0;			
-			int dimWriteIdx = 0;
-			bool isUninit = false;
-			
-			int dimLength = -1;
-			if (dimLengthVals[curDim].IsConst())
+		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)
 			{
-				auto constant = mModule->mBfIRBuilder->GetConstant(dimLengthVals[curDim]);
-				dimLength = constant->mInt32;
+
 			}
 
-			while (exprIdx < (int)valueExprs.size())
+			void Handle(BfIRValue addr, int curDim, const BfSizedArray<BfExpression*>& valueExprs)
 			{
-				auto initExpr = valueExprs[exprIdx];
-				exprIdx++;
-				if (!initExpr)
-					break;
-				if (auto unintExpr = BfNodeDynCastExact<BfUninitializedExpression>(initExpr))
+				int exprIdx = 0;
+				int dimWriteIdx = 0;
+				bool isUninit = false;
+
+				int dimLength = -1;
+				if (dimLengthVals[curDim].IsConst())
 				{
-					isUninit = true;
-					break;
+					auto constant = mModule->mBfIRBuilder->GetConstant(dimLengthVals[curDim]);
+					dimLength = constant->mInt32;
 				}
 
-				if (exprIdx > dimLength)
-					break;
-				
-				if (curDim < dimensions - 1)
-				{					
-					if (auto innerTupleExpr = BfNodeDynCast<BfTupleExpression>(initExpr))
-					{
-						_HandleInitExprs(addr, curDim + 1, innerTupleExpr->mValues);
-					}
-					else if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(initExpr))
+				while (exprIdx < (int)valueExprs.size())
+				{
+					auto initExpr = valueExprs[exprIdx];
+					exprIdx++;
+					if (!initExpr)
+						break;
+					if (auto unintExpr = BfNodeDynCastExact<BfUninitializedExpression>(initExpr))
 					{
-						SizedArray<BfExpression*, 1> values;
-						values.Add(parenExpr->mExpression);						
-						_HandleInitExprs(addr, curDim + 1, values);
+						isUninit = true;
+						break;
 					}
-					else if (auto innerInitExpr = BfNodeDynCast<BfCollectionInitializerExpression>(initExpr))
+
+					if (exprIdx > dimLength)
+						break;
+
+					if (curDim < dimensions - 1)
 					{
-						_HandleInitExprs(addr, curDim + 1, innerInitExpr->mValues);
+						if (auto innerTupleExpr = BfNodeDynCast<BfTupleExpression>(initExpr))
+						{
+							Handle(addr, curDim + 1, innerTupleExpr->mValues);
+						}
+						else if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(initExpr))
+						{
+							SizedArray<BfExpression*, 1> values;
+							values.Add(parenExpr->mExpression);
+							Handle(addr, curDim + 1, values);
+						}
+						else if (auto innerInitExpr = BfNodeDynCast<BfCollectionInitializerExpression>(initExpr))
+						{
+							Handle(addr, curDim + 1, innerInitExpr->mValues);
+						}
+
+						dimWriteIdx++;
+						continue;
 					}
 
+					auto elemAddr = mModule->CreateIndexedValue(resultType, addr, writeIdx);
+					writeIdx++;
 					dimWriteIdx++;
-					continue;
-				}
 
-				auto elemAddr = mModule->CreateIndexedValue(resultType, addr, writeIdx);
-				writeIdx++;
-				dimWriteIdx++;
+					BfTypedValue elemPtrTypedVal = BfTypedValue(elemAddr, resultType, BfTypedValueKind_Addr);
 
-				BfTypedValue elemPtrTypedVal = BfTypedValue(elemAddr, resultType, BfTypedValueKind_Addr);
-
-				BfExprEvaluator exprEvaluator(mModule);
-				exprEvaluator.mExpectingType = resultType;
-				exprEvaluator.mReceivingValue = &elemPtrTypedVal;
-				exprEvaluator.Evaluate(initExpr);
-				exprEvaluator.GetResult();
+					BfExprEvaluator exprEvaluator(mModule);
+					exprEvaluator.mExpectingType = resultType;
+					exprEvaluator.mReceivingValue = &elemPtrTypedVal;
+					exprEvaluator.Evaluate(initExpr);
+					exprEvaluator.GetResult();
 
-				if (exprEvaluator.mReceivingValue == NULL)
-				{
-					// We wrote directly to the array in-place, we're done with this element
-					continue;
-				}
-				auto storeValue = exprEvaluator.mResult;
-				if (!storeValue)
-					continue;
-				storeValue = mModule->Cast(initExpr, storeValue, resultType);
-				if (!storeValue)
-					continue;
-				if (!resultType->IsValuelessType())
-				{
-					storeValue = mModule->LoadValue(storeValue);
-					mModule->mBfIRBuilder->CreateStore(storeValue.mValue, elemAddr);
+					if (exprEvaluator.mReceivingValue == NULL)
+					{
+						// We wrote directly to the array in-place, we're done with this element
+						continue;
+					}
+					auto storeValue = exprEvaluator.mResult;
+					if (!storeValue)
+						continue;
+					storeValue = mModule->Cast(initExpr, storeValue, resultType);
+					if (!storeValue)
+						continue;
+					if (!resultType->IsValuelessType())
+					{
+						storeValue = mModule->LoadValue(storeValue);
+						mModule->mBfIRBuilder->CreateStore(storeValue.mValue, elemAddr);
+					}
 				}
-			}
 
-			int clearFromIdx = writeIdx;
-			int sectionElemCount = 1;
+				int clearFromIdx = writeIdx;
+				int sectionElemCount = 1;
 
-			BfIRValue numElemsLeft = arraySize;
-			if (dimLength != -1)
-			{
-				int clearCount = dimLength - dimWriteIdx;
-				if (clearCount > 0)
+				BfIRValue numElemsLeft = arraySize;
+				if (dimLength != -1)
 				{
-					for (int checkDim = curDim + 1; checkDim < (int)dimLengthVals.size(); checkDim++)
+					int clearCount = dimLength - dimWriteIdx;
+					if (clearCount > 0)
 					{
-						if (dimLengthVals[checkDim].IsConst())
+						for (int checkDim = curDim + 1; checkDim < (int)dimLengthVals.size(); checkDim++)
 						{
-							auto constant = mModule->mBfIRBuilder->GetConstant(dimLengthVals[checkDim]);
-							clearCount *= constant->mInt32;
-							sectionElemCount *= constant->mInt32;
+							if (dimLengthVals[checkDim].IsConst())
+							{
+								auto constant = mModule->mBfIRBuilder->GetConstant(dimLengthVals[checkDim]);
+								clearCount *= constant->mInt32;
+								sectionElemCount *= constant->mInt32;
+							}
 						}
 					}
-				}
 
-				writeIdx += clearCount;
-				numElemsLeft = mModule->GetConstValue(clearCount);
-			}
+					writeIdx += clearCount;
+					numElemsLeft = mModule->GetConstValue(clearCount);
+				}
 
-			// Actually leave it alone?
-			if ((isUninit) && (mModule->IsOptimized()))
-				return;
-			
-			bool doClear = true;
-			if (numElemsLeft.IsConst())
-			{
-				auto constant = mModule->mBfIRBuilder->GetConstant(numElemsLeft);
-				doClear = constant->mInt64 > 0;
-			}
-			if (doClear)
-			{
-				// We multiply by GetStride.  This relies on the fact that we over-allocate on the array allocation -- the last 
-				//  element doesn't need to be padded out to the element alignment, but we do anyway.  Otherwise this would be
-				//  a more complicated computation
-				auto clearBytes = mModule->mBfIRBuilder->CreateMul(numElemsLeft, mModule->GetConstValue(resultType->GetStride()));
+				// Actually leave it alone?
+				if ((isUninit) && (mModule->IsOptimized()))
+					return;
 
-				if (isUninit)
+				bool doClear = true;
+				if (numElemsLeft.IsConst())
 				{
-					// Limit to a reasonable number of bytes to stomp with 0xCC
-					int maxStompBytes = BF_MIN(128, resultType->GetStride() * sectionElemCount);
-					if (clearBytes.IsConst())
-					{
-						auto constant = mModule->mBfIRBuilder->GetConstant(clearBytes);
-						if (constant->mInt64 > maxStompBytes)
-							clearBytes = mModule->GetConstValue(maxStompBytes);
-					}
-					else
+					auto constant = mModule->mBfIRBuilder->GetConstant(numElemsLeft);
+					doClear = constant->mInt64 > 0;
+				}
+				if (doClear)
+				{
+					// We multiply by GetStride.  This relies on the fact that we over-allocate on the array allocation -- the last 
+					//  element doesn't need to be padded out to the element alignment, but we do anyway.  Otherwise this would be
+					//  a more complicated computation
+					auto clearBytes = mModule->mBfIRBuilder->CreateMul(numElemsLeft, mModule->GetConstValue(resultType->GetStride()));
+
+					if (isUninit)
 					{
-						auto insertBlock = mModule->mBfIRBuilder->GetInsertBlock();
+						// Limit to a reasonable number of bytes to stomp with 0xCC
+						int maxStompBytes = BF_MIN(128, resultType->GetStride() * sectionElemCount);
+						if (clearBytes.IsConst())
+						{
+							auto constant = mModule->mBfIRBuilder->GetConstant(clearBytes);
+							if (constant->mInt64 > maxStompBytes)
+								clearBytes = mModule->GetConstValue(maxStompBytes);
+						}
+						else
+						{
+							auto insertBlock = mModule->mBfIRBuilder->GetInsertBlock();
 
-						auto gtBlock = mModule->mBfIRBuilder->CreateBlock("unint.gt");
-						auto contBlock = mModule->mBfIRBuilder->CreateBlock("unint.cont");
-						
-						auto cmp = mModule->mBfIRBuilder->CreateCmpLTE(clearBytes, mModule->GetConstValue(maxStompBytes), true);
-						mModule->mBfIRBuilder->CreateCondBr(cmp, contBlock, gtBlock);
+							auto gtBlock = mModule->mBfIRBuilder->CreateBlock("unint.gt");
+							auto contBlock = mModule->mBfIRBuilder->CreateBlock("unint.cont");
 
-						mModule->mBfIRBuilder->AddBlock(gtBlock);
-						mModule->mBfIRBuilder->SetInsertPoint(gtBlock);
-						mModule->mBfIRBuilder->CreateBr(contBlock);
+							auto cmp = mModule->mBfIRBuilder->CreateCmpLTE(clearBytes, mModule->GetConstValue(maxStompBytes), true);
+							mModule->mBfIRBuilder->CreateCondBr(cmp, contBlock, gtBlock);
 
-						mModule->mBfIRBuilder->AddBlock(contBlock);
-						mModule->mBfIRBuilder->SetInsertPoint(contBlock);
-						auto phi = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(mModule->GetPrimitiveType(BfTypeCode_IntPtr)), 2);
-						mModule->mBfIRBuilder->AddPhiIncoming(phi, clearBytes, insertBlock);
-						mModule->mBfIRBuilder->AddPhiIncoming(phi, mModule->GetConstValue(maxStompBytes), gtBlock);
+							mModule->mBfIRBuilder->AddBlock(gtBlock);
+							mModule->mBfIRBuilder->SetInsertPoint(gtBlock);
+							mModule->mBfIRBuilder->CreateBr(contBlock);
 
-						clearBytes = phi;
+							mModule->mBfIRBuilder->AddBlock(contBlock);
+							mModule->mBfIRBuilder->SetInsertPoint(contBlock);
+							auto phi = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(mModule->GetPrimitiveType(BfTypeCode_IntPtr)), 2);
+							mModule->mBfIRBuilder->AddPhiIncoming(phi, clearBytes, insertBlock);
+							mModule->mBfIRBuilder->AddPhiIncoming(phi, mModule->GetConstValue(maxStompBytes), gtBlock);
+
+							clearBytes = phi;
+						}
 					}
-				}
 
-				mModule->mBfIRBuilder->PopulateType(resultType);
-				if (!resultType->IsValuelessType())
-				{
-					mModule->mBfIRBuilder->CreateMemSet(mModule->CreateIndexedValue(resultType, addr, clearFromIdx),
-						mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int8, isUninit ? 0xCC : 0), clearBytes, resultType->mAlign);
+					mModule->mBfIRBuilder->PopulateType(resultType);
+					if (!resultType->IsValuelessType())
+					{
+						mModule->mBfIRBuilder->CreateMemSet(mModule->CreateIndexedValue(resultType, addr, clearFromIdx),
+							mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int8, isUninit ? 0xCC : 0), clearBytes, resultType->mAlign);
+					}
 				}
 			}
 		};
+
+		BfInitContext initContext(mModule, resultType, dimensions, dimLengthVals, arraySize, writeIdx);
 		
 		if (resultType->IsVar())
 		{
 			SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
 			mResult = BfTypedValue(BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), mModule->GetPrimitiveType(BfTypeCode_Var)));
-			_HandleInitExprs(mResult.mValue, 0, objCreateExpr->mArguments);
+			initContext.Handle(mResult.mValue, 0, objCreateExpr->mArguments);
 			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);
 			}
 
-			_HandleInitExprs(arrayValue.mValue, 0, objCreateExpr->mArguments);
+			initContext.Handle(arrayValue.mValue, 0, objCreateExpr->mArguments);
 			
 			mResult = arrayValue;
 			return;
@@ -12073,7 +12092,8 @@ void BfExprEvaluator::Visit(BfObjectCreateExpression* objCreateExpr)
 			addr = mModule->mBfIRBuilder->GetFakeVal();
 		else
 			addr = mModule->mBfIRBuilder->CreateInBoundsGEP(arrayValue.mValue, 0, firstElementFieldInstance->mDataIdx);
-		_HandleInitExprs(addr, 0, objCreateExpr->mArguments);
+		
+		initContext.Handle(addr, 0, objCreateExpr->mArguments);
 		
 		return;
 	}
@@ -14370,13 +14390,18 @@ void BfExprEvaluator::Visit(BfInvocationExpression* invocationExpr)
 
 				int arrSize = 0;
 
+				BfTypeState typeState;
+				typeState.mArrayInitializerSize = (int)invocationExpr->mArguments.size();
+				SetAndRestoreValue<BfTypeState*> prevTypeState(mModule->mContext->mCurTypeState, &typeState);
+
 				if (indexerExpr->mArguments.size() != 0)
 				{
 					BfConstResolver constResolver(mModule);
 					auto arg = indexerExpr->mArguments[0];
+					constResolver.mExpectingType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
 
 					if (arg != NULL)
-						constResolver.Resolve(arg);
+						constResolver.Resolve(arg, NULL, BfConstResolveFlag_ArrayInitSize);
 
 					if (constResolver.mResult.mValue.IsConst())
 					{

+ 27 - 15
IDEHelper/Compiler/BfModule.cpp

@@ -3721,7 +3721,7 @@ bool BfModule::IsThreadLocal(BfFieldInstance * fieldInstance)
 	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)
 		fieldDef = fieldInstance->GetFieldDef();
@@ -3734,6 +3734,8 @@ BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance,
 		initializer = fieldDef->mInitializer;
 	}
 
+	BfTypedValue staticVarRef;
+
 	BfTypedValue result;
 	if (initializer == NULL)
 	{
@@ -3779,16 +3781,34 @@ BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance,
 				return constResolver.Resolve(initializer, fieldType, resolveFlags);
 			}
 		}
-		
+				
+		BfExprEvaluator exprEvaluator(this);
+		if (doStore)
+		{
+			staticVarRef = ReferenceStaticField(fieldInstance);
+			exprEvaluator.mReceivingValue = &staticVarRef;
+		}
 		if (fieldType->IsVar())
-			result = CreateValueFromExpression(initializer, NULL, (BfEvalExprFlags)(BfEvalExprFlags_NoValueAddr | BfEvalExprFlags_FieldInitializer));
+			result = CreateValueFromExpression(exprEvaluator, initializer, NULL, (BfEvalExprFlags)(BfEvalExprFlags_NoValueAddr | BfEvalExprFlags_FieldInitializer));
 		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)
 		MarkFieldInitialized(fieldInstance);
 
+	if (doStore)
+	{
+		result = LoadValue(result);
+		if (!result.mType->IsValuelessType())		
+			mBfIRBuilder->CreateStore(result.mValue, staticVarRef.mValue);		
+	}
+
 	return result;
 }
 
@@ -13893,16 +13913,8 @@ void BfModule::CreateStaticCtor()
 				{					
 					continue;
 				}
-				auto assignValue = GetFieldInitializerValue(fieldInst);
-				if (assignValue)
-				{
-					assignValue = LoadValue(assignValue);
-					if (!assignValue.mType->IsValuelessType())
-					{
-						auto staticVarRef = ReferenceStaticField(fieldInst).mValue;
-						mBfIRBuilder->CreateStore(assignValue.mValue, staticVarRef);
-					}
-				}
+				GetFieldInitializerValue(fieldInst, NULL, NULL, NULL, true);
+				
 			}
 		}
 	}
@@ -16457,7 +16469,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
 	}
 	
 	BfTypeState typeState(mCurTypeInstance);
-	SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);			
+	SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
 
 	bool isGenericVariation = (methodInstance->mIsUnspecializedVariation) || (mCurTypeInstance->IsUnspecializedTypeVariation());
 

+ 1 - 1
IDEHelper/Compiler/BfModule.h

@@ -1609,7 +1609,7 @@ public:
 	BfFieldInstance* GetFieldByName(BfTypeInstance* typeInstance, const StringImpl& fieldName, bool isRequired = true, BfAstNode* refNode = NULL);
 	void CreateStaticField(BfFieldInstance* fieldInstance, bool isThreadLocal = 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);
 	bool IsThreadLocal(BfFieldInstance* fieldInstance);
 	BfType* ResolveVarFieldType(BfTypeInstance* typeInst, BfFieldInstance* fieldInstance, BfFieldDef* field);	

+ 1 - 1
IDEHelper/Compiler/BfModuleTypeUtils.cpp

@@ -7870,7 +7870,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
 				BfTypedValue typedVal;
 				{
 					SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, true);
-					typedVal = constResolver.Resolve(sizeExpr);
+					typedVal = constResolver.Resolve(sizeExpr, NULL, BfConstResolveFlag_ArrayInitSize);
 				}
 				if (typedVal.mKind == BfTypedValueKind_GenericConstValue)
 				{

+ 2 - 2
IDEHelper/Compiler/BfResolvedTypeUtils.cpp

@@ -2654,7 +2654,7 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
 				BfType* intType = ctx->mModule->GetPrimitiveType(BfTypeCode_IntPtr);
 				constResolver.mAllowGenericConstValue = true;
 				constResolver.mExpectingType = intType;
-				BfTypedValue typedVal = constResolver.Resolve(sizeExpr);
+				BfTypedValue typedVal = constResolver.Resolve(sizeExpr, NULL, BfConstResolveFlag_ArrayInitSize);
 				if (typedVal.mKind == BfTypedValueKind_GenericConstValue)
 				{
 					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);
 			constResolver.mAllowGenericConstValue = true;
 			constResolver.mExpectingType = intType;			
-			BfTypedValue typedVal = constResolver.Resolve(sizeExpr);
+			BfTypedValue typedVal = constResolver.Resolve(sizeExpr, NULL, BfConstResolveFlag_ArrayInitSize);
 			if (typedVal.mKind == BfTypedValueKind_GenericConstValue)
 			{
 				if (!lhs->IsUnknownSizedArray())

+ 4 - 0
IDEHelper/Compiler/BfStmtEvaluator.cpp

@@ -1563,6 +1563,10 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD
 	}
 	else
 	{
+		BfTypeState typeState;
+		typeState.mCurVarInitializer = varDecl->mInitializer;
+		SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
+
 		unresolvedType = ResolveTypeRef(varDecl->mTypeRef, BfPopulateType_Data, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoResolveGenericParam | BfResolveTypeRefFlag_AllowRef));
 		if (unresolvedType == NULL)
 			unresolvedType = GetPrimitiveType(BfTypeCode_Var);													  

+ 7 - 0
IDEHelper/Tests/src/SizedArrays.bf

@@ -5,6 +5,7 @@ namespace Tests
 	class SizedArrays
 	{
 		public static int[8] iArr = .(123, 234, 345, );
+		public static int[?] iArr2 = .(12, 23, 34);
 
 		[Test]
 		static void TestBasics()
@@ -24,6 +25,12 @@ namespace Tests
 			val2[0][0] = 9;
 			Test.Assert(val0 != val2);
 			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]