Просмотр исходного кода

Fixed type generic arg and PopulateType dependency bugs

Brian Fiete 3 лет назад
Родитель
Сommit
7e94abe43a

+ 8 - 8
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<BfTypeInstance*, 16> isSlotUsed;		
 	for (auto type : mContext->mResolvedTypes)
-	{		
+	{
 		if (!type->IsReified())
 			continue;
 

+ 31 - 12
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)
 		{

+ 36 - 20
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<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, typeInstance);
+	SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, NULL);
+	SetAndRestoreValue<BfMethodState*> 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<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, genericTypeInstance);
+	SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, NULL);
+	SetAndRestoreValue<BfMethodState*> 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()) &&

+ 1 - 1
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;
 		}
 	}

+ 1 - 0
IDEHelper/Compiler/BfResolvedTypeUtils.h

@@ -447,6 +447,7 @@ enum BfTypeRebuildFlags
 	BfTypeRebuildFlag_RebuildQueued = 0x20000,
 	BfTypeRebuildFlag_ConstEvalCancelled = 0x40000,
 	BfTypeRebuildFlag_ChangedMidCompile = 0x80000,
+	BfTypeRebuildFlag_PendingGenericArgDep = 0x100000
 };
 
 class BfTypeDIReplaceCallback;