#pragma once #pragma warning(push) #pragma warning(disable:4141) #pragma warning(disable:4146) #pragma warning(disable:4291) #pragma warning(disable:4244) #pragma warning(disable:4267) #pragma warning(disable:4624) #pragma warning(disable:4800) #include "BeefySysLib/Common.h" #include "BeefySysLib/util/CritSect.h" #include "BeefySysLib/util/PerfTimer.h" #include "BeefySysLib/util/String.h" #include "BfAst.h" #include "BfSystem.h" /*#include "llvm/Support/Compiler.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Type.h" #include "llvm/IR/DIBuilder.h" #include "llvm/IR/DebugInfo.h" #include "llvm/IR/Argument.h" #include "llvm/IR/Constants.h"*/ #include "BfResolvedTypeUtils.h" #include #include "BfContext.h" #include "BfCodeGen.h" #include "BfMangler.h" #pragma warning(pop) NS_BF_BEGIN class BfType; class BfResolvedType; class BfTypeInstance; class BfModule; class BfFileInstance; class BfAutoComplete; class BfMethodInstance; class BfSourceClassifier; class BfResolvePassData; class CeMachine; enum BfCompileOnDemandKind { BfCompileOnDemandKind_AlwaysInclude, BfCompileOnDemandKind_ResolveUnused, BfCompileOnDemandKind_SkipUnused }; class BfCompiler { public: enum CompileState { CompileState_None, CompileState_Normal, CompileState_Unreified, CompileState_VData, CompileState_Cleanup }; struct Stats { int mTotalTypes; int mMethodDeclarations; int mTypesPopulated; int mMethodsProcessed; int mUnreifiedMethodsProcessed; int mQueuedTypesProcessed; int mTypesQueued; int mTypesDeleted; int mMethodsQueued; int mModulesStarted; int mModulesFinished; int mModulesReified; int mModulesUnreified; int mReifiedModuleCount; int mIRBytes; int mConstBytes; int mMidCompileRebuilds; }; Stats mStats; struct Options { BfProject* mHotProject; int mHotCompileIdx; int32 mForceRebuildIdx; BfCompileOnDemandKind mCompileOnDemandKind; String mTargetTriple; String mTargetCPU; BfPlatformType mPlatformType; BfMachineType mMachineType; int mCLongSize; BfToolsetType mToolsetType; BfSIMDSetting mSIMDSetting; String mMallocLinkName; String mFreeLinkName; bool mIncrementalBuild; bool mEmitDebugInfo; bool mEmitLineInfo; bool mNoFramePointerElim; bool mInitLocalVariables; bool mRuntimeChecks; bool mAllowStructByVal; bool mEmitDynamicCastCheck; bool mAllowHotSwapping; bool mObjectHasDebugFlags; bool mEnableRealtimeLeakCheck; bool mEmitObjectAccessCheck; // Only valid with mObjectHasDebugFlags bool mArithmeticChecks; bool mEnableCustodian; bool mEnableSideStack; bool mHasVDataExtender; bool mDebugAlloc; bool mOmitDebugHelpers; bool mUseDebugBackingParams; bool mWriteIR; bool mGenerateObj; bool mGenerateBitcode; int mAllocStackCount; bool mExtraResolveChecks; int mMaxSplatRegs; String mErrorString; Options() { mMallocLinkName = "malloc"; mFreeLinkName = "free"; mHotCompileIdx = 0; mForceRebuildIdx = 0; mCompileOnDemandKind = BfCompileOnDemandKind_AlwaysInclude; mPlatformType = BfPlatformType_Unknown; mMachineType = BfMachineType_x86; mCLongSize = 4; mToolsetType = BfToolsetType_Microsoft; mSIMDSetting = BfSIMDSetting_None; mHotProject = NULL; mDebugAlloc = false; mOmitDebugHelpers = false; mIncrementalBuild = true; mEmitDebugInfo = false; mEmitLineInfo = false; mNoFramePointerElim = true; mInitLocalVariables = false; mRuntimeChecks = true; mAllowStructByVal = false; mEmitDynamicCastCheck = true; mAllowHotSwapping = false; mEmitObjectAccessCheck = false; mArithmeticChecks = false; mObjectHasDebugFlags = false; mEnableRealtimeLeakCheck = false; mWriteIR = false; mGenerateObj = true; mGenerateBitcode = false; mEnableCustodian = false; mEnableSideStack = false; mHasVDataExtender = false; mUseDebugBackingParams = true; mAllocStackCount = 1; mExtraResolveChecks = false; #ifdef _DEBUG mExtraResolveChecks = false; #endif mMaxSplatRegs = 4; } bool IsCodeView() { #ifdef BF_PLATFORM_WINDOWS return mToolsetType != BfToolsetType_GNU; #else return false; #endif } }; Options mOptions; enum HotTypeFlags { HotTypeFlag_None = 0, HotTypeFlag_UserNotUsed = 1, HotTypeFlag_UserUsed = 2, HotTypeFlag_Heap = 4, HotTypeFlag_ActiveFunction = 8, // Only set for a type version mismatch HotTypeFlag_Delegate = 0x10, // Only set for a type version mismatch HotTypeFlag_FuncPtr = 0x20, // Only set for a type version mismatch HotTypeFlag_CanAllocate = 0x40 }; enum HotResolveFlags { HotResolveFlag_None = 0, HotResolveFlag_HadDataChanges = 1 }; struct HotReachableData { HotTypeFlags mTypeFlags; bool mHadNonDevirtualizedCall; HotReachableData() { mTypeFlags = HotTypeFlag_None; mHadNonDevirtualizedCall = false; } }; class HotResolveData { public: HotResolveFlags mFlags; Dictionary mReachableMethods; HashSet mActiveMethods; Dictionary mHotTypeFlags; Array mHotTypeIdFlags; Array mReasons; HashSet mDeferredThisCheckMethods; ~HotResolveData(); }; class HotData { public: BfCompiler* mCompiler; Dictionary mMethodMap; Dictionary mMethodNameMap; Dictionary mThisType; Dictionary mAllocation; Dictionary mDevirtualizedMethods; Dictionary mFuncPtrs; Dictionary mVirtualDecls; Dictionary mInnerMethods; public: ~HotData(); void ClearUnused(bool isHotCompile); BfHotThisType* GetThisType(BfHotTypeVersion* hotVersion); BfHotAllocation* GetAllocation(BfHotTypeVersion* hotVersion); BfHotDevirtualizedMethod* GetDevirtualizedMethod(BfHotMethod* hotMethod); BfHotFunctionReference* GetFunctionReference(BfHotMethod* hotMethod); BfHotVirtualDeclaration* GetVirtualDeclaration(BfHotMethod* hotMethod); BfHotInnerMethod* GetInnerMethod(BfHotMethod* hotMethod); }; class HotState { public: BfProject* mHotProject; int mLastStringId; int mCommittedHotCompileIdx; bool mHasNewTypes; bool mHasNewInterfaceTypes; Array mQueuedOutFiles; // Queues up when we have failed hot compiles HashSet mSlotDefineTypeIds; HashSet mNewlySlottedTypeIds; HashSet mPendingDataChanges; HashSet mPendingFailedSlottings; Dictionary mDeletedTypeNameMap; Val128 mVDataHashEx; public: HotState() { mHotProject = NULL; mLastStringId = -1; mCommittedHotCompileIdx = 0; mHasNewTypes = false; mHasNewInterfaceTypes = false; } ~HotState(); bool HasPendingChanges(BfTypeInstance* type); void RemovePendingChanges(BfTypeInstance* type); }; HotData* mHotData; HotState* mHotState; HotResolveData* mHotResolveData; struct StringValueEntry { int mId; BfIRValue mStringVal; }; struct TestMethod { String mName; BfMethodInstance* mMethodInstance; }; public: BfPassInstance* mPassInstance; FILE* mCompileLogFP; CeMachine* mCeMachine; int mCurCEExecuteId; BfSystem* mSystem; bool mIsResolveOnly; BfResolvePassData* mResolvePassData; Dictionary> mAttributeTypeOptionMap; int mRevision; int64 mUniqueId; bool mLastRevisionAborted; BfContext* mContext; BfCodeGen mCodeGen; String mOutputDirectory; int mLastMidCompileRefreshRevision; bool mCanceling; bool mHasRequiredTypes; bool mNeedsFullRefresh; bool mFastFinish; bool mHasQueuedTypeRebuilds; // Infers we had a fast finish that requires a type rebuild bool mHadCancel; bool mWantsDeferMethodDecls; bool mLastHadComptimeRebuilds; bool mHasComptimeRebuilds; bool mInInvalidState; bool mDepsMayHaveDeletedTypes; float mCompletionPct; int mHSPreserveIdx; BfModule* mLastAutocompleteModule; CompileState mCompileState; HashSet mRebuildFileSet; HashSet mRebuildChangedFileSet; // Files we had actual changes from Array mVDataModules; BfTypeDef* mBfObjectTypeDef; BfTypeDef* mChar32TypeDef; BfTypeDef* mFloatTypeDef; BfTypeDef* mDoubleTypeDef; BfTypeDef* mMathTypeDef; BfTypeDef* mArray1TypeDef; BfTypeDef* mArray2TypeDef; BfTypeDef* mArray3TypeDef; BfTypeDef* mArray4TypeDef; BfTypeDef* mSpanTypeDef; BfTypeDef* mRangeTypeDef; BfTypeDef* mClosedRangeTypeDef; BfTypeDef* mIndexTypeDef; BfTypeDef* mIndexRangeTypeDef; BfTypeDef* mClassVDataTypeDef; BfTypeDef* mDbgRawAllocDataTypeDef; BfTypeDef* mDeferredCallTypeDef; BfTypeDef* mDelegateTypeDef; BfTypeDef* mFunctionTypeDef; BfTypeDef* mActionTypeDef; BfTypeDef* mEnumTypeDef; BfTypeDef* mStringTypeDef; BfTypeDef* mStringViewTypeDef; BfTypeDef* mTypeTypeDeclDef; BfTypeDef* mTypeTypeDef; BfTypeDef* mValueTypeTypeDef; BfTypeDef* mResultTypeDef; BfTypeDef* mGCTypeDef; BfTypeDef* mGenericIEnumerableTypeDef; BfTypeDef* mGenericIEnumeratorTypeDef; BfTypeDef* mGenericIRefEnumeratorTypeDef; BfTypeDef* mThreadTypeDef; BfTypeDef* mInternalTypeDef; BfTypeDef* mPlatformTypeDef; BfTypeDef* mCompilerTypeDef; BfTypeDef* mCompilerGeneratorTypeDef; BfTypeDef* mDiagnosticsDebugTypeDef; BfTypeDef* mIDisposableTypeDef; BfTypeDef* mIIntegerTypeDef; BfTypeDef* mIPrintableTypeDef; BfTypeDef* mIHashableTypeDef; BfTypeDef* mIComptimeTypeApply; BfTypeDef* mIComptimeMethodApply; BfTypeDef* mIOnTypeInitTypeDef; BfTypeDef* mIOnTypeDoneTypeDef; BfTypeDef* mIOnFieldInitTypeDef; BfTypeDef* mIOnMethodInitTypeDef; BfTypeDef* mMethodRefTypeDef; BfTypeDef* mNullableTypeDef; BfTypeDef* mPointerTTypeDef; BfTypeDef* mPointerTypeDef; BfTypeDef* mReflectTypeIdTypeDef; BfTypeDef* mReflectArrayType; BfTypeDef* mReflectGenericParamType; BfTypeDef* mReflectFieldDataDef; BfTypeDef* mReflectFieldSplatDataDef; BfTypeDef* mReflectMethodDataDef; BfTypeDef* mReflectParamDataDef; BfTypeDef* mReflectInterfaceDataDef; BfTypeDef* mReflectPointerType; BfTypeDef* mReflectRefType; BfTypeDef* mReflectSizedArrayType; BfTypeDef* mReflectConstExprType; BfTypeDef* mReflectSpecializedGenericType; BfTypeDef* mReflectTypeInstanceTypeDef; BfTypeDef* mReflectUnspecializedGenericType; BfTypeDef* mReflectFieldInfoTypeDef; BfTypeDef* mReflectMethodInfoTypeDef; BfTypeDef* mSizedArrayTypeDef; BfTypeDef* mAttributeTypeDef; BfTypeDef* mAttributeUsageAttributeTypeDef; BfTypeDef* mLinkNameAttributeTypeDef; BfTypeDef* mCallingConventionAttributeTypeDef; BfTypeDef* mOrderedAttributeTypeDef; BfTypeDef* mInlineAttributeTypeDef; BfTypeDef* mCLinkAttributeTypeDef; BfTypeDef* mImportAttributeTypeDef; BfTypeDef* mExportAttributeTypeDef; BfTypeDef* mCReprAttributeTypeDef; BfTypeDef* mUnderlyingArrayAttributeTypeDef; BfTypeDef* mAlignAttributeTypeDef; BfTypeDef* mAllowDuplicatesAttributeTypeDef; BfTypeDef* mNoDiscardAttributeTypeDef; BfTypeDef* mDisableChecksAttributeTypeDef; BfTypeDef* mDisableObjectAccessChecksAttributeTypeDef; BfTypeDef* mFriendAttributeTypeDef; BfTypeDef* mNoStaticCtorAttributeTypeDef; BfTypeDef* mComptimeAttributeTypeDef; BfTypeDef* mConstEvalAttributeTypeDef; BfTypeDef* mNoExtensionAttributeTypeDef; BfTypeDef* mCheckedAttributeTypeDef; BfTypeDef* mUncheckedAttributeTypeDef; BfTypeDef* mStaticInitAfterAttributeTypeDef; BfTypeDef* mStaticInitPriorityAttributeTypeDef; BfTypeDef* mTestAttributeTypeDef; BfTypeDef* mThreadStaticAttributeTypeDef; BfTypeDef* mUnboundAttributeTypeDef; BfTypeDef* mObsoleteAttributeTypeDef; BfTypeDef* mErrorAttributeTypeDef; BfTypeDef* mWarnAttributeTypeDef; BfTypeDef* mConstSkipAttributeTypeDef; BfTypeDef* mIgnoreErrorsAttributeTypeDef; BfTypeDef* mReflectAttributeTypeDef; BfTypeDef* mOnCompileAttributeTypeDef; int mCurTypeId; int mTypeInitCount; String mOutputPath; Array mGenericInstancePurgatory; Array mTypeIdFreeList; int mMaxInterfaceSlots; bool mInterfaceSlotCountChanged; public: bool IsTypeAccessible(BfType* checkType, BfProject* curProject); bool IsTypeUsed(BfType* checkType, BfProject* curProject); bool IsModuleAccessible(BfModule* module, BfProject* curProject); void FixVDataHash(BfModule* bfModule); void CheckModuleStringRefs(BfModule* module, BfVDataModule* vdataModule, int lastModuleRevision, HashSet& foundStringIds, HashSet& dllNameSet, Array& dllMethods, Array& stringValueEntries); void HashModuleVData(BfModule* module, HashContext& hash); 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 UpdateDependencyMap(bool deleteUnusued, bool& didWork); void SanitizeDependencyMap(); bool ProcessPurgatory(bool reifiedOnly); bool VerifySlotNums(); bool QuickGenerateSlotNums(); bool SlowGenerateSlotNums(); void GenerateSlotNums(); void GenerateDynCastData(); void UpdateRevisedTypes(); void VisitAutocompleteExteriorIdentifiers(); void VisitSourceExteriorNodes(); void UpdateCompletion(); bool DoWorkLoop(bool onlyReifiedTypes = false, bool onlyReifiedMethods = false); BfMangler::MangleKind GetMangleKind(); BfTypeDef* GetArrayTypeDef(int dimensions); void GenerateAutocompleteInfo(); void MarkStringPool(BfModule* module); void MarkStringPool(BfIRConstHolder* constHolder, BfIRValue irValue); void ClearUnusedStringPoolEntries(); void ClearBuildCache(); int GetVDataPrefixDataCount(); int GetDynCastVDataCount(); bool IsAutocomplete(); bool IsDataResolvePass(); bool WantsClassifyNode(BfAstNode* node); BfAutoComplete* GetAutoComplete(); bool IsHotCompile(); bool IsSkippingExtraResolveChecks(); int GetVTableMethodOffset(); BfType* CheckSymbolReferenceTypeRef(BfModule* module, BfTypeReference* typeRef); void AddToRebuildTypeList(BfTypeInstance* typeInst, HashSet& rebuildTypeInstList); void AddDepsToRebuildTypeList(BfTypeInstance* typeInst, HashSet& rebuildTypeInstList); void CompileReified(); void PopulateReified(); bool IsCePaused(); bool EnsureCeUnpaused(BfType* refType); void HotCommit(); void HotResolve_Start(HotResolveFlags flags); void HotResolve_PopulateMethodNameMap(); bool HotResolve_AddReachableMethod(BfHotMethod* hotMethod, HotTypeFlags flags, bool devirtualized, bool forceProcess = false); void HotResolve_AddReachableMethod(const StringImpl& methodName); void HotResolve_AddActiveMethod(BfHotMethod* hotMethod); void HotResolve_AddActiveMethod(const StringImpl& methodName); void HotResolve_AddDelegateMethod(const StringImpl& methodName); void HotResolve_ReportType(BfHotTypeVersion* hotTypeVersion, HotTypeFlags flags, BfHotDepData* reason); void HotResolve_ReportType(int typeId, HotTypeFlags flags); String HotResolve_Finish(); void ClearOldHotData(); public: BfCompiler(BfSystem* bfSystem, bool isResolveOnly); ~BfCompiler(); bool Compile(const StringImpl& outputPath); bool DoCompile(const StringImpl& outputPath); void ClearResults(); void ProcessAutocompleteTempType(); void GetSymbolReferences(); void Cancel(); void RequestFastFinish(); String GetTypeDefList(bool includeLocation); String GetGeneratorString(BfTypeDef* typeDef, BfTypeInstance* typeInst, const StringImpl& generatorMethodName, const StringImpl* args); void HandleGeneratorErrors(StringImpl& result); String GetGeneratorTypeDefList(); String GetGeneratorInitData(const StringImpl& typeName, const StringImpl& args); String GetGeneratorGenData(const StringImpl& typeName, const StringImpl& args); String GetTypeDefMatches(const StringImpl& searchSrc, bool includeLocation); void GetTypeDefs(const StringImpl& typeName, Array& typeDefs); String GetTypeDefInfo(const StringImpl& typeName); int GetTypeId(const StringImpl& typeName); BfType* GetType(const StringImpl& typeName); int GetEmitSource(const StringImpl& fileName, StringImpl* outBuffer); String GetEmitLocation(const StringImpl& typeName, int line, int& outEmbedLine, int& outEmbedLineChar, uint64& outHash); bool WriteEmitData(const StringImpl& filePath, BfProject* project); void CompileLog(const char* fmt ...); void ReportMemory(MemReporter* memReporter); }; NS_BF_END