diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index 121f1181..2575b7d3 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -364,6 +364,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly) mInterfaceSlotCountChanged = false; mLastHadComptimeRebuilds = false; mHasComptimeRebuilds = false; + mDepsMayHaveDeletedTypes = false; mHSPreserveIdx = 0; mCompileLogFP = NULL; @@ -482,7 +483,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly) mContext = new BfContext(this); mCeMachine = new CeMachine(this); mCurCEExecuteId = -1; - mLastMidCompileRefreshRevision = -1; + mLastMidCompileRefreshRevision = -1; } BfCompiler::~BfCompiler() @@ -2529,6 +2530,39 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork) } mContext->mQueuedSpecializedMethodRebuildTypes.Clear(); + mDepsMayHaveDeletedTypes = false; +} + +void BfCompiler::SanitizeDependencyMap() +{ + BfLogSysM("SanitizeDependencyMap\n"); + + for (auto type : mContext->mResolvedTypes) + { + if (type == NULL) + continue; + + 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();) + { + auto dependentType = itr->mKey; + auto depTypeInst = dependentType->ToTypeInstance(); + if (dependentType->IsDeleting()) + { + BfLogSysM("SanitizeDependencyMap removing old dependent %p from %p\n", dependentType, depType); + itr = depType->mDependencyMap.erase(itr); + } + else + ++itr; + } + } + + mContext->RemoveInvalidWorkItems(); + mDepsMayHaveDeletedTypes = false; } // When we are unsure of whether an old generic instance will survive, we RebuildType but don't put it in any worklist. @@ -2538,7 +2572,7 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork) // 3) It stays undefined and we need to build it here void BfCompiler::ProcessPurgatory(bool reifiedOnly) { - BP_ZONE("BfCompiler::ProcessPuragory"); + BP_ZONE("BfCompiler::ProcessPurgatory"); while (true) { @@ -7432,7 +7466,13 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) } ProcessPurgatory(false); + // ProcessPurgatory MAY cause type rebuilds which we need to handle + DoWorkLoop(); + BfLogSysM("Checking mDepsMayHaveDeletedTypes for SanitizeDependencyMap\n"); + if (mDepsMayHaveDeletedTypes) + SanitizeDependencyMap(); + // Old Mark used modules if (!mIsResolveOnly) @@ -7735,7 +7775,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) if (didCancel) mLastHadComptimeRebuilds = mHasComptimeRebuilds || mLastHadComptimeRebuilds; else - mLastHadComptimeRebuilds = mHasComptimeRebuilds; + mLastHadComptimeRebuilds = mHasComptimeRebuilds; return !didCancel && !mHasQueuedTypeRebuilds; } diff --git a/IDEHelper/Compiler/BfCompiler.h b/IDEHelper/Compiler/BfCompiler.h index 14f7209a..ee5069f6 100644 --- a/IDEHelper/Compiler/BfCompiler.h +++ b/IDEHelper/Compiler/BfCompiler.h @@ -337,6 +337,7 @@ public: bool mLastHadComptimeRebuilds; bool mHasComptimeRebuilds; bool mInInvalidState; + bool mDepsMayHaveDeletedTypes; float mCompletionPct; int mHSPreserveIdx; BfModule* mLastAutocompleteModule; @@ -474,8 +475,9 @@ public: BfIRFunction CreateLoadSharedLibraries(BfVDataModule* bfModule, Array& dllMethods); void GetTestMethods(BfVDataModule* bfModule, Array& testMethods, HashContext& vdataHashCtx); void EmitTestMethod(BfVDataModule* bfModule, Array& testMethods, BfIRValue& retValue); - void CreateVData(BfVDataModule* bfModule); + void CreateVData(BfVDataModule* bfModule); void UpdateDependencyMap(bool deleteUnusued, bool& didWork); + void SanitizeDependencyMap(); void ProcessPurgatory(bool reifiedOnly); bool VerifySlotNums(); bool QuickGenerateSlotNums(); diff --git a/IDEHelper/Compiler/BfContext.cpp b/IDEHelper/Compiler/BfContext.cpp index a7a2ea2d..dc779256 100644 --- a/IDEHelper/Compiler/BfContext.cpp +++ b/IDEHelper/Compiler/BfContext.cpp @@ -1690,6 +1690,7 @@ void BfContext::DeleteType(BfType* type, bool deferDepRebuilds) if (type->mRebuildFlags & BfTypeRebuildFlag_Deleted) return; + mCompiler->mDepsMayHaveDeletedTypes = true; mCompiler->mStats.mTypesDeleted++; BfDependedType* dType = type->ToDependedType(); diff --git a/IDEHelper/Compiler/BfIRCodeGen.cpp b/IDEHelper/Compiler/BfIRCodeGen.cpp index 4f26bf2c..99ccd65d 100644 --- a/IDEHelper/Compiler/BfIRCodeGen.cpp +++ b/IDEHelper/Compiler/BfIRCodeGen.cpp @@ -3959,7 +3959,13 @@ void BfIRCodeGen::HandleNextCmd() CMD_PARAM(int, argIdx); CMD_PARAM(String, name); - auto argItr = ((llvm::Function*)func)->arg_begin(); + if (argIdx >= func->arg_size()) + { + Fail("BfIRCmd_Func_SetParamName argIdx error"); + break; + } + + auto argItr = func->arg_begin(); for (int i = 1; i < argIdx; i++) ++argItr; argItr->setName(name.c_str());