diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index e440a558..1f3aea5e 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -2307,14 +2307,14 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork) for (auto type : mContext->mResolvedTypes) { if (type != NULL) - { - auto depType = type->ToDependedType(); + { + auto depType = type->ToDependedType(); auto typeInst = type->ToTypeInstance(); - + if (depType != NULL) { extern BfModule* gLastCreatedModule; - + #ifdef _DEBUG for (auto itr = depType->mDependencyMap.begin(); itr != depType->mDependencyMap.end(); ++itr) { @@ -2334,7 +2334,7 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork) auto dependentType = itr->mKey; auto depTypeInst = dependentType->ToTypeInstance(); auto& depData = itr->mValue; - + bool isInvalidVersion = (dependentType->mRevision > depData.mRevision);// && (deleteUnusued) && (madeFullPass); //TODO: Just to cause crash if dependentType is deleted @@ -2491,7 +2491,7 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork) { // This flag should be handled by now BF_ASSERT((type->mRebuildFlags & BfTypeRebuildFlag_AwaitingReference) == 0); - } + } } #endif @@ -2549,7 +2549,7 @@ void BfCompiler::SanitizeDependencyMap() auto depType = type->ToDependedType(); if (depType == NULL) continue; - + // Not combined with previous loop because PopulateType could modify typeInst->mDependencyMap for (auto itr = depType->mDependencyMap.begin(); itr != depType->mDependencyMap.end();) { @@ -2626,7 +2626,7 @@ bool BfCompiler::VerifySlotNums() SmallVector isSlotUsed; for (auto type : mContext->mResolvedTypes) - { + { if (!type->IsReified()) continue; diff --git a/IDEHelper/Compiler/BfContext.cpp b/IDEHelper/Compiler/BfContext.cpp index ccc694a9..1ba7550d 100644 --- a/IDEHelper/Compiler/BfContext.cpp +++ b/IDEHelper/Compiler/BfContext.cpp @@ -907,25 +907,30 @@ void BfContext::ValidateDependencies() // BfLogSysM("ValidateDependencies\n"); // // bool deletedNewTypes = false; -// auto itr = mResolvedTypes.begin(); -// while (itr != mResolvedTypes.end()) -// { -// auto type = itr.mCurEntry->mValue; -// if ((type->IsGenericTypeInstance()) && (type->mDefineState > BfTypeDefineState_Undefined)) +// for (auto type : mResolvedTypes) +// { +// if (type->IsDeleting()) +// continue; +// +// if (type->IsGenericTypeInstance()) // { // // We can't contain deleted generic arguments without being deleted ourselves // BfTypeInstance* genericType = (BfTypeInstance*)type; // -// for (auto genericTypeArg : genericType->mTypeGenericArguments) +// for (auto genericTypeArg : genericType->mGenericTypeInfo->mTypeGenericArguments) // { -// auto depType = genericTypeArg->ToDependedType(); -// if (depType != NULL) +// BF_ASSERT((!genericTypeArg->IsDeleting())); +// +// auto argDepType = genericTypeArg->ToDependedType(); +// if (argDepType != NULL) // { -// BF_ASSERT(depType->mDependencyMap.mTypeSet.ContainsKey(type)); +// BfDependencyMap::DependencyEntry* depEntry = NULL; +// argDepType->mDependencyMap.mTypeSet.TryGetValue(type, &depEntry); +// BF_ASSERT(depEntry != NULL); +// BF_ASSERT((depEntry->mFlags & BfDependencyMap::DependencyFlag_TypeGenericArg) != 0); // } // } -// } -// ++itr; +// } // } #endif } @@ -979,6 +984,11 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild { BfLogSysM("Setting revision. Type: %p Revision: %d\n", typeInst, mCompiler->mRevision); typeInst->mRevision = mCompiler->mRevision; + if (typeInst->IsGenericTypeInstance()) + { + BfLogSysM("Setting BfTypeRebuildFlag_PendingGenericArgDep for type %p\n", typeInst); + typeInst->mRebuildFlags = (BfTypeRebuildFlags)(typeInst->mRebuildFlags | BfTypeRebuildFlag_PendingGenericArgDep); + } } if ((typeInst->IsTypeAlias()) != (typeInst->mTypeDef->mTypeCode == BfTypeCode_TypeAlias)) @@ -1970,6 +1980,15 @@ void BfContext::UpdateAfterDeletingTypes() for (auto genericTypeArg : genericType->mGenericTypeInfo->mTypeGenericArguments) { BF_ASSERT((!genericTypeArg->IsDeleting())); + + auto argDepType = genericTypeArg->ToDependedType(); + if (argDepType != NULL) + { + BfDependencyMap::DependencyEntry* depEntry = NULL; + argDepType->mDependencyMap.mTypeSet.TryGetValue(type, &depEntry); + BF_ASSERT(depEntry != NULL); + BF_ASSERT((depEntry->mFlags & BfDependencyMap::DependencyFlag_TypeGenericArg) != 0); + } } } #endif @@ -2176,7 +2195,7 @@ void BfContext::UpdateRevisedTypes() } // Clear flags we don't want to propagate - typeInst->mRebuildFlags = (BfTypeRebuildFlags)(typeInst->mRebuildFlags & BfTypeRebuildFlag_UnderlyingTypeDeferred); + typeInst->mRebuildFlags = (BfTypeRebuildFlags)(typeInst->mRebuildFlags & (BfTypeRebuildFlag_UnderlyingTypeDeferred | BfTypeRebuildFlag_PendingGenericArgDep)); if (typeDef->mIsPartial) { diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 3f9e4d2b..b9ec5e06 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -1142,7 +1142,15 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType { if ((populateType == BfPopulateType_Declaration) && (resolvedTypeRef->mDefineState >= BfTypeDefineState_Declared)) return; - + + if ((resolvedTypeRef->mRebuildFlags & BfTypeRebuildFlag_PendingGenericArgDep) != 0) + { + BfLogSysM("PopulateType handling BfTypeRebuildFlag_PendingGenericArgDep for type %p\n", resolvedTypeRef); + // Reinit dependencies + resolvedTypeRef->mRebuildFlags = (BfTypeRebuildFlags)(resolvedTypeRef->mRebuildFlags & ~BfTypeRebuildFlag_PendingGenericArgDep); + DoPopulateType_SetGenericDependencies(resolvedTypeRef->ToTypeInstance()); + } + // Are we "demanding" to reify a type that is currently resolve-only? if ((mIsReified) && (populateType >= BfPopulateType_Declaration)) { @@ -1252,23 +1260,15 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType if (populateType <= BfPopulateType_TypeDef) return; - + auto typeInstance = resolvedTypeRef->ToTypeInstance(); CheckInjectNewRevision(typeInstance); - BF_ASSERT((resolvedTypeRef->mRebuildFlags & (BfTypeRebuildFlag_Deleted | BfTypeRebuildFlag_DeleteQueued)) == 0); + SetAndRestoreValue prevTypeInstance(mCurTypeInstance, typeInstance); + SetAndRestoreValue prevMethodInstance(mCurMethodInstance, NULL); + SetAndRestoreValue prevMethodState(mCurMethodState, NULL); - /*BfTypeRebuildFlags allowedFlags = (BfTypeRebuildFlags)(BfTypeRebuildFlag_AddedToWorkList | BfTypeRebuildFlag_AwaitingReference | BfTypeRebuildFlag_UnderlyingTypeDeferred); - if ((resolvedTypeRef->mRebuildFlags & ~allowedFlags) != 0) - { - // BfContext::UpdateAfterDeletingTypes should clear out all flags except for the Deleted flag - // If this type was deleted then we should never be able to reach PopulateType here. - // This may happen if dependent types were not properly rebuilt when a used type - // was deleted. - auto hadFlags = resolvedTypeRef->mRebuildFlags; - BF_ASSERT((resolvedTypeRef->mRebuildFlags & ~allowedFlags) == 0); - resolvedTypeRef->mRebuildFlags = (BfTypeRebuildFlags)(resolvedTypeRef->mRebuildFlags & ~allowedFlags); - }*/ + BF_ASSERT((resolvedTypeRef->mRebuildFlags & (BfTypeRebuildFlag_Deleted | BfTypeRebuildFlag_DeleteQueued)) == 0); bool isNew = resolvedTypeRef->mDefineState == BfTypeDefineState_Undefined; if (isNew) @@ -3076,15 +3076,31 @@ void BfModule::DoCEEmit(BfMethodInstance* methodInstance) void BfModule::DoPopulateType_SetGenericDependencies(BfTypeInstance* genericTypeInstance) { + SetAndRestoreValue prevTypeInstance(mCurTypeInstance, genericTypeInstance); + SetAndRestoreValue prevMethodInstance(mCurMethodInstance, NULL); + SetAndRestoreValue prevMethodState(mCurMethodState, NULL); + // Add generic dependencies if needed - for (auto genericType : genericTypeInstance->mGenericTypeInfo->mTypeGenericArguments) + for (auto genericArgType : genericTypeInstance->mGenericTypeInfo->mTypeGenericArguments) { - if (genericType->IsPrimitiveType()) - genericType = GetWrappedStructType(genericType); - if (genericType != NULL) + if (genericArgType->IsPrimitiveType()) + genericArgType = GetWrappedStructType(genericArgType); + if (genericArgType != NULL) { - AddDependency(genericType, genericTypeInstance, BfDependencyMap::DependencyFlag_TypeGenericArg); - BfLogSysM("Adding generic dependency of %p for type %p\n", genericType, genericTypeInstance); + AddDependency(genericArgType, genericTypeInstance, BfDependencyMap::DependencyFlag_TypeGenericArg); + BfLogSysM("Adding generic dependency of %p for type %p revision %d\n", genericArgType, genericTypeInstance, genericTypeInstance->mRevision); + +#ifdef _DEBUG +// auto argDepType = genericArgType->ToDependedType(); +// if (argDepType != NULL) +// { +// BfDependencyMap::DependencyEntry* depEntry = NULL; +// argDepType->mDependencyMap.mTypeSet.TryGetValue(genericTypeInstance, &depEntry); +// BF_ASSERT(depEntry != NULL); +// BF_ASSERT(depEntry->mRevision == genericTypeInstance->mRevision); +// BF_ASSERT((depEntry->mFlags & BfDependencyMap::DependencyFlag_TypeGenericArg) != 0); +// } +#endif } } if ((genericTypeInstance->IsSpecializedType()) && diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp index e9df8de2..f10f7037 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp @@ -117,7 +117,7 @@ bool BfDependencyMap::AddUsedBy(BfType* dependentType, BfDependencyMap::Dependen { if ((dependencyEntry->mFlags & flags) == flags) return false; - dependencyEntry->mFlags = (BfDependencyMap::DependencyFlags)(dependencyEntry->mFlags | flags); + dependencyEntry->mFlags = (DependencyFlags)(dependencyEntry->mFlags | flags); return true; } } diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.h b/IDEHelper/Compiler/BfResolvedTypeUtils.h index 0e6fb28a..f2f69ec6 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.h +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.h @@ -447,6 +447,7 @@ enum BfTypeRebuildFlags BfTypeRebuildFlag_RebuildQueued = 0x20000, BfTypeRebuildFlag_ConstEvalCancelled = 0x40000, BfTypeRebuildFlag_ChangedMidCompile = 0x80000, + BfTypeRebuildFlag_PendingGenericArgDep = 0x100000 }; class BfTypeDIReplaceCallback;