diff --git a/IDEHelper/Compiler/BfContext.cpp b/IDEHelper/Compiler/BfContext.cpp index 11e8e392..667099b8 100644 --- a/IDEHelper/Compiler/BfContext.cpp +++ b/IDEHelper/Compiler/BfContext.cpp @@ -1246,6 +1246,35 @@ void BfContext::TypeConstEvalChanged(BfTypeInstance* typeInst) TypeConstEvalChanged(depTypeInst); RebuildType(dependentType); } + else if ((dependencyFlags & BfDependencyMap::DependencyFlag_ConstEvalConstField) != 0) + { + auto depTypeInst = dependentType->ToTypeInstance(); + if (depTypeInst != NULL) + TypeConstEvalFieldChanged(depTypeInst); + RebuildType(dependentType); + } + } +} + +void BfContext::TypeConstEvalFieldChanged(BfTypeInstance* typeInst) +{ + if (typeInst->mRebuildFlags & BfTypeRebuildFlag_ConstEvalFieldChange) // Already did change? + return; + typeInst->mRebuildFlags = (BfTypeRebuildFlags)(typeInst->mRebuildFlags | BfTypeRebuildFlag_ConstEvalFieldChange); + + // These don't happen in TypeDataChanged because we don't need to cascade + for (auto& depItr : typeInst->mDependencyMap) + { + auto dependentType = depItr.mKey; + auto dependencyFlags = depItr.mValue.mFlags; + + if ((dependencyFlags & BfDependencyMap::DependencyFlag_ConstEvalConstField) != 0) + { + auto depTypeInst = dependentType->ToTypeInstance(); + if (depTypeInst != NULL) + TypeConstEvalFieldChanged(depTypeInst); + RebuildType(dependentType); + } } } diff --git a/IDEHelper/Compiler/BfContext.h b/IDEHelper/Compiler/BfContext.h index d4ea8b2a..ce1c0e83 100644 --- a/IDEHelper/Compiler/BfContext.h +++ b/IDEHelper/Compiler/BfContext.h @@ -442,6 +442,7 @@ public: void TypeMethodSignaturesChanged(BfTypeInstance* typeInst); void TypeInlineMethodInternalsChanged(BfTypeInstance* typeInst); void TypeConstEvalChanged(BfTypeInstance* typeInst); + void TypeConstEvalFieldChanged(BfTypeInstance* typeInst); void CheckSpecializedErrorData(); void TryUnreifyModules(); void MarkUsedModules(BfProject* project, BfModule* module); diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 84c29ce2..7861448d 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -4119,6 +4119,17 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar mModule->PopulateType(resolvedFieldType, BfPopulateType_Data); mModule->AddDependency(curCheckType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields); + if (fieldInstance->mHadConstEval) + { + mModule->AddDependency(curCheckType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ConstEvalConstField); + if ((mModule->mContext->mCurTypeState != NULL) && (mModule->mContext->mCurTypeState->mCurFieldDef != NULL)) + { + // If we're initializing another const field then + auto resolvingFieldInstance = &mModule->mContext->mCurTypeState->mTypeInstance->mFieldInstances[mModule->mContext->mCurTypeState->mCurFieldDef->mIdx]; + if (resolvingFieldInstance->GetFieldDef()->mIsConst) + resolvingFieldInstance->mHadConstEval = true; + } + } auto autoComplete = GetAutoComplete(); if (autoComplete != NULL) diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 1982b77a..6281edcb 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -4088,6 +4088,10 @@ BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance, } else if (fieldDef->mIsConst) { + int ceExecuteId = -1; + if (mCompiler->mCEMachine != NULL) + ceExecuteId = mCompiler->mCEMachine->mExecuteId; + BfTypeState typeState; typeState.mTypeInstance = mCurTypeInstance; typeState.mCurTypeDef = fieldDef->mDeclaringType; @@ -4108,8 +4112,14 @@ BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance, resolveFlags = BfConstResolveFlag_NoCast; } UpdateSrcPos(initializer); - return constResolver.Resolve(initializer, fieldType, resolveFlags); - } + auto result = constResolver.Resolve(initializer, fieldType, resolveFlags); + if (mCompiler->mCEMachine != NULL) + { + if (mCompiler->mCEMachine->mExecuteId != ceExecuteId) + fieldInstance->mHadConstEval = true; + } + return result; + } } BfExprEvaluator exprEvaluator(this); diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.h b/IDEHelper/Compiler/BfResolvedTypeUtils.h index 324c70a2..911cc143 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.h +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.h @@ -94,22 +94,23 @@ public: DependencyFlag_PtrMemberData = 0x80, DependencyFlag_StaticValue = 0x100, DependencyFlag_ConstValue = 0x200, - DependencyFlag_MethodGenericArg = 0x400, - DependencyFlag_LocalUsage = 0x800, - DependencyFlag_ExprTypeReference = 0x1000, - DependencyFlag_TypeGenericArg = 0x2000, - DependencyFlag_UnspecializedType = 0x4000, - DependencyFlag_GenericArgRef = 0x8000, - DependencyFlag_ParamOrReturnValue = 0x10000, - DependencyFlag_CustomAttribute = 0x20000, - DependencyFlag_Constraint = 0x40000, - DependencyFlag_StructElementType = 0x80000, - DependencyFlag_TypeReference = 0x100000, // Explicit type reference for things like tuples, so all referencing types get passed over on symbol reference - DependencyFlag_Allocates = 0x200000, - DependencyFlag_NameReference = 0x400000, - DependencyFlag_VirtualCall = 0x800000, - DependencyFlag_WeakReference = 0x1000000, // Keeps alive but won't rebuild - DependencyFlag_ConstEval = 0x2000000, + DependencyFlag_ConstEvalConstField = 0x400, // Used a field that was CE-generated + DependencyFlag_ConstEval = 0x800, + DependencyFlag_MethodGenericArg = 0x1000, + DependencyFlag_LocalUsage = 0x2000, + DependencyFlag_ExprTypeReference = 0x4000, + DependencyFlag_TypeGenericArg = 0x8000, + DependencyFlag_UnspecializedType = 0x10000, + DependencyFlag_GenericArgRef = 0x20000, + DependencyFlag_ParamOrReturnValue = 0x40000, + DependencyFlag_CustomAttribute = 0x80000, + DependencyFlag_Constraint = 0x100000, + DependencyFlag_StructElementType = 0x200000, + DependencyFlag_TypeReference = 0x400000, // Explicit type reference for things like tuples, so all referencing types get passed over on symbol reference + DependencyFlag_Allocates = 0x800000, + DependencyFlag_NameReference = 0x1000000, + DependencyFlag_VirtualCall = 0x2000000, + DependencyFlag_WeakReference = 0x4000000, // Keeps alive but won't rebuild DependencyFlag_DependentUsageMask = ~(DependencyFlag_UnspecializedType | DependencyFlag_MethodGenericArg | DependencyFlag_GenericArgRef) }; @@ -405,16 +406,17 @@ enum BfTypeRebuildFlags BfTypeRebuildFlag_MethodInlineInternalsChange = 4, BfTypeRebuildFlag_MethodSignatureChange = 8, BfTypeRebuildFlag_ConstEvalChange = 0x10, - BfTypeRebuildFlag_DeleteQueued = 0x20, - BfTypeRebuildFlag_Deleted = 0x40, - BfTypeRebuildFlag_AddedToWorkList = 0x80, - BfTypeRebuildFlag_AwaitingReference = 0x100, - BfTypeRebuildFlag_SpecializedMethodRebuild = 0x200, // Temporarily set - BfTypeRebuildFlag_SpecializedByAutocompleteMethod = 0x400, - BfTypeRebuildFlag_UnderlyingTypeDeferred = 0x800, - BfTypeRebuildFlag_TypeDataSaved = 0x1000, - BfTypeRebuildFlag_InTempPool = 0x2000, - BfTypeRebuildFlag_ResolvingBase = 0x4000 + BfTypeRebuildFlag_ConstEvalFieldChange = 0x20, + BfTypeRebuildFlag_DeleteQueued = 0x40, + BfTypeRebuildFlag_Deleted = 0x80, + BfTypeRebuildFlag_AddedToWorkList = 0x100, + BfTypeRebuildFlag_AwaitingReference = 0x200, + BfTypeRebuildFlag_SpecializedMethodRebuild = 0x400, // Temporarily set + BfTypeRebuildFlag_SpecializedByAutocompleteMethod = 0x800, + BfTypeRebuildFlag_UnderlyingTypeDeferred = 0x1000, + BfTypeRebuildFlag_TypeDataSaved = 0x2000, + BfTypeRebuildFlag_InTempPool = 0x4000, + BfTypeRebuildFlag_ResolvingBase = 0x8000 }; class BfTypeDIReplaceCallback; @@ -1303,7 +1305,8 @@ public: bool mFieldIncluded; bool mIsEnumPayloadCase; bool mIsThreadLocal; - bool mIsInferredType; + bool mIsInferredType; + bool mHadConstEval; int mLastRevisionReferenced; public: @@ -1326,6 +1329,7 @@ public: mIsEnumPayloadCase = copyFrom.mIsEnumPayloadCase; mIsThreadLocal = copyFrom.mIsThreadLocal; mIsInferredType = copyFrom.mIsInferredType; + mHadConstEval = copyFrom.mHadConstEval; mLastRevisionReferenced = copyFrom.mLastRevisionReferenced; } @@ -1344,6 +1348,7 @@ public: mFieldIncluded = true; mIsThreadLocal = false; mIsInferredType = false; + mHadConstEval = false; mLastRevisionReferenced = -1; }