#pragma once //#define BFIR_RENTRY_CHECK #include "BeefySysLib/Common.h" #include "BeefySysLib/util/BumpAllocator.h" #include "BeefySysLib/util/ChunkedDataBuffer.h" #include "BeefySysLib/util/Dictionary.h" #include "BfAstAllocator.h" #include //#include "BfSystem.h" #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) #pragma warning(disable:4996) #include "llvm/IR/DebugLoc.h" #include "llvm/IR/IRBuilder.h" #pragma warning(pop) NS_BF_BEGIN typedef int addr_ce; class BfModule; class BfType; class BfTypeInstance; class BfIRConstHolder; class BfIRCodeGen; class BeIRCodeGen; class BfMethodInstance; class BfFieldInstance; class BfMethodRef; class BfFileInstance; class BfParser; class BfParserData; class Val128; class BfFilePosition { public: BfFileInstance* mFileInstance; int mCurSrcPos; int mCurLine; int mCurColumn; public: BfFilePosition() { mFileInstance = NULL; mCurSrcPos = 0; mCurLine = 0; mCurColumn = 0; } }; enum BfTypeCode : uint8 { BfTypeCode_None, BfTypeCode_CharPtr, BfTypeCode_StringId, BfTypeCode_Pointer, BfTypeCode_NullPtr, BfTypeCode_Self, BfTypeCode_Dot, BfTypeCode_Var, BfTypeCode_Let, BfTypeCode_Boolean, BfTypeCode_Int8, BfTypeCode_UInt8, BfTypeCode_Int16, BfTypeCode_UInt16, BfTypeCode_Int24, BfTypeCode_UInt24, BfTypeCode_Int32, BfTypeCode_UInt32, BfTypeCode_Int40, BfTypeCode_UInt40, BfTypeCode_Int48, BfTypeCode_UInt48, BfTypeCode_Int56, BfTypeCode_UInt56, BfTypeCode_Int64, BfTypeCode_UInt64, BfTypeCode_Int128, BfTypeCode_UInt128, BfTypeCode_IntPtr, BfTypeCode_UIntPtr, BfTypeCode_IntUnknown, BfTypeCode_UIntUnknown, BfTypeCode_Char8, BfTypeCode_Char16, BfTypeCode_Char32, BfTypeCode_Float, BfTypeCode_Double, BfTypeCode_Float2, BfTypeCode_Object, BfTypeCode_Interface, BfTypeCode_Struct, BfTypeCode_Enum, BfTypeCode_TypeAlias, BfTypeCode_Extension, BfTypeCode_FloatX2, BfTypeCode_FloatX3, BfTypeCode_FloatX4, BfTypeCode_DoubleX2, BfTypeCode_DoubleX3, BfTypeCode_DoubleX4, BfTypeCode_Int64X2, BfTypeCode_Int64X3, BfTypeCode_Int64X4, BfTypeCode_Length, BfTypeCode_Inferred }; enum BfConstType { BfConstType_GlobalVar = BfTypeCode_Length, BfConstType_BitCast, BfConstType_BitCastNull, BfConstType_GEP32_1, BfConstType_GEP32_2, BfConstType_ExtractValue, BfConstType_PtrToInt, BfConstType_IntToPtr, BfConstType_TypeOf, BfConstType_TypeOf_WithData, BfConstType_TypeOf_Comptime, BfConstType_AggZero, BfConstType_Agg, BfConstType_AggCE, BfConstType_ArrayZero, BfConstType_ArrayZero8, BfConstType_Undef, BfConstType_SizedArrayType, BfConstType_Box }; enum BfIRValueFlags : uint8 { BfIRValueFlags_None, BfIRValueFlags_Value = 1, BfIRValueFlags_Arg = 2, BfIRValueFlags_Const = 4, BfIRValueFlags_FromLLVM = 8, BfIRValueFlags_Block = 16, BfIRValueFlags_Func = 32 }; enum BfIRCmd : uint8 { BfIRCmd_Module_Start, BfIRCmd_Module_SetTargetTriple, BfIRCmd_Module_AddModuleFlag, BfIRCmd_WriteIR, BfIRCmd_Abort, BfIRCmd_SetType, BfIRCmd_SetInstType, BfIRCmd_PrimitiveType, BfIRCmd_CreateAnonymousStruct, BfIRCmd_CreateStruct, BfIRCmd_StructSetBody, BfIRCmd_Type, BfIRCmd_TypeInst, BfIRCmd_TypeInstPtr, BfIRCmd_GetType, BfIRCmd_GetPointerToFuncType, BfIRCmd_GetPointerToType, BfIRCmd_GetSizedArrayType, BfIRCmd_GetVectorType, BfIRCmd_CreateConstStructZero, BfIRCmd_CreateConstAgg, BfIRCmd_CreateConstArrayZero, BfIRCmd_CreateConstString, BfIRCmd_ConfigConst, BfIRCmd_SetName, BfIRCmd_CreateUndefValue, BfIRCmd_NumericCast, BfIRCmd_CmpEQ, BfIRCmd_CmpNE, BfIRCmd_CmpSLT, BfIRCmd_CmpULT, BfIRCmd_CmpSLE, BfIRCmd_CmpULE, BfIRCmd_CmpSGT, BfIRCmd_CmpUGT, BfIRCmd_CmpSGE, BfIRCmd_CmpUGE, BfIRCmd_Add, BfIRCmd_Sub, BfIRCmd_Mul, BfIRCmd_SDiv, BfIRCmd_UDiv, BfIRCmd_SRem, BfIRCmd_URem, BfIRCmd_And, BfIRCmd_Or, BfIRCmd_Xor, BfIRCmd_Shl, BfIRCmd_AShr, BfIRCmd_LShr, BfIRCmd_Neg, BfIRCmd_Not, BfIRCmd_BitCast, BfIRCmd_PtrToInt, BfIRCmd_IntToPtr, BfIRCmd_InboundsGEP1_32, BfIRCmd_InboundsGEP2_32, BfIRCmd_InBoundsGEP1, BfIRCmd_InBoundsGEP2, BfIRCmd_IsNull, BfIRCmd_IsNotNull, BfIRCmd_ExtractValue, BfIRCmd_InsertValue, BfIRCmd_Alloca, BfIRCmd_AllocaArray, BfIRCmd_SetAllocaAlignment, BfIRCmd_SetAllocaNoChkStkHint, BfIRCmd_SetAllocaForceMem, BfIRCmd_AliasValue, BfIRCmd_LifetimeStart, BfIRCmd_LifetimeEnd, BfIRCmd_LifetimeSoftEnd, BfIRCmd_LifetimeExtend, BfIRCmd_ValueScopeStart, BfIRCmd_ValueScopeRetain, BfIRCmd_ValueScopeSoftEnd, BfIRCmd_ValueScopeHardEnd, BfIRCmd_Load, BfIRCmd_AlignedLoad, BfIRCmd_Store, BfIRCmd_AlignedStore, BfIRCmd_MemSet, BfIRCmd_Fence, BfIRCmd_StackSave, BfIRCmd_StackRestore, BfIRCmd_GlobalVariable, BfIRCmd_GlobalVar_SetUnnamedAddr, BfIRCmd_GlobalVar_SetInitializer, BfIRCmd_GlobalVar_SetAlignment, BfIRCmd_GlobalVar_SetStorageKind, BfIRCmd_GlobalStringPtr, BfIRCmd_SetReflectTypeData, BfIRCmd_CreateBlock, BfIRCmd_MaybeChainNewBlock, BfIRCmd_AddBlock, BfIRCmd_DropBlocks, BfIRCmd_MergeBlockDown, BfIRCmd_GetInsertBlock, BfIRCmd_SetInsertPoint, BfIRCmd_SetInsertPointAtStart, BfIRCmd_EraseFromParent, BfIRCmd_DeleteBlock, BfIRCmd_EraseInstFromParent, BfIRCmd_CreateBr, BfIRCmd_CreateBr_Fake, BfIRCmd_CreateBr_NoCollapse, BfIRCmd_CreateCondBr, BfIRCmd_MoveBlockToEnd, BfIRCmd_CreateSwitch, BfIRCmd_AddSwitchCase, BfIRCmd_SetSwitchDefaultDest, BfIRCmd_CreatePhi, BfIRCmd_AddPhiIncoming, BfIRCmd_GetIntrinsic, BfIRCmd_CreateFunctionType, BfIRCmd_CreateFunction, BfIRCmd_SetFunctionName, BfIRCmd_EnsureFunctionPatchable, BfIRCmd_RemapBindFunction, BfIRCmd_SetActiveFunction, BfIRCmd_CreateCall, BfIRCmd_SetCallCallingConv, BfIRCmd_SetFuncCallingConv, BfIRCmd_SetTailCall, BfIRCmd_SetCallAttribute, BfIRCmd_CreateRet, BfIRCmd_CreateSetRet, BfIRCmd_CreateRetVoid, BfIRCmd_CreateUnreachable, BfIRCmd_Call_AddAttribute, BfIRCmd_Call_AddAttribute1, BfIRCmd_Func_AddAttribute, BfIRCmd_Func_AddAttribute1, BfIRCmd_Func_SetParamName, BfIRCmd_Func_DeleteBody, BfIRCmd_Func_SafeRename, BfIRCmd_Func_SafeRenameFrom, BfIRCmd_Func_SetLinkage, BfIRCmd_Comptime_Error, BfIRCmd_Comptime_GetBfType, BfIRCmd_Comptime_GetReflectType, BfIRCmd_Comptime_DynamicCastCheck, BfIRCmd_Comptime_GetVirtualFunc, BfIRCmd_Comptime_GetInterfaceFunc, BfIRCmd_SaveDebugLocation, BfIRCmd_RestoreDebugLocation, BfIRCmd_DupDebugLocation, BfIRCmd_ClearDebugLocation, BfIRCmd_ClearDebugLocationInst, BfIRCmd_ClearDebugLocationInstLast, BfIRCmd_UpdateDebugLocation, BfIRCmd_SetCurrentDebugLocation, BfIRCmd_Nop, BfIRCmd_EnsureInstructionAt, BfIRCmd_StatementStart, BfIRCmd_ObjectAccessCheck, BfIRCmd_DbgInit, BfIRCmd_DbgFinalize, BfIRCmd_DbgCreateCompileUnit, BfIRCmd_DbgCreateFile, BfIRCmd_ConstValueI64, BfIRCmd_DbgGetCurrentLocation, BfIRCmd_DbgSetType, BfIRCmd_DbgSetInstType, BfIRCmd_DbgGetType, BfIRCmd_DbgGetTypeInst, BfIRCmd_DbgTrackDITypes, BfIRCmd_DbgCreateNamespace, BfIRCmd_DbgCreateImportedModule, BfIRCmd_DbgCreateBasicType, BfIRCmd_DbgCreateStructType, BfIRCmd_DbgCreateEnumerationType, BfIRCmd_DbgCreatePointerType, BfIRCmd_DbgCreateReferenceType, BfIRCmd_DbgCreateConstType, BfIRCmd_DbgCreateArtificialType, BfIRCmd_DbgCreateArrayType, BfIRCmd_DbgCreateReplaceableCompositeType, BfIRCmd_DbgCreateForwardDecl, BfIRCmd_DbgCreateSizedForwardDecl, BeIRCmd_DbgSetTypeSize, BfIRCmd_DbgReplaceAllUses, BfIRCmd_DbgDeleteTemporary, BfIRCmd_DbgMakePermanent, BfIRCmd_CreateEnumerator, BfIRCmd_DbgCreateMemberType, BfIRCmd_DbgStaticCreateMemberType, BfIRCmd_DbgCreateInheritance, BfIRCmd_DbgCreateMethod, BfIRCmd_DbgCreateFunction, BfIRCmd_DbgCreateParameterVariable, BfIRCmd_DbgCreateSubroutineType, BfIRCmd_DbgCreateAutoVariable, BfIRCmd_DbgInsertValueIntrinsic, BfIRCmd_DbgInsertDeclare, BfIRCmd_DbgLifetimeEnd, BfIRCmd_DbgCreateGlobalVariable, BfIRCmd_DbgCreateLexicalBlock, BfIRCmd_DbgCreateLexicalBlockFile, BfIRCmd_DbgCreateAnnotation, BfIRCmd_COUNT }; enum BfIRCallingConv { BfIRCallingConv_ThisCall, BfIRCallingConv_StdCall, BfIRCallingConv_CDecl, BfIRCallingConv_FastCall }; enum BfIRParamType : uint8 { BfIRParamType_None, BfIRParamType_Const, BfIRParamType_Arg, BfIRParamType_StreamId_Abs8, BfIRParamType_StreamId_Rel, BfIRParamType_StreamId_Back1, BfIRParamType_StreamId_Back_LAST = 0xFF, // Use remaining encoding }; enum BfIRLinkageType : uint8 { BfIRLinkageType_External, BfIRLinkageType_Internal }; enum BfIRInitType : uint8 { BfIRInitType_NotSet, // Not specified BfIRInitType_NotNeeded, // Explicitly disable BfIRInitType_NotNeeded_AliveOnDecl, // Explicitly disable, treat variable as alive at declaration BfIRInitType_Uninitialized, // May set to 0xCC for debug BfIRInitType_Zero, // Must be zero }; enum BfIRFenceType : uint8 { BfIRFenceType_AcquireRelease }; enum BfIRConfigConst : uint8 { BfIRConfigConst_VirtualMethodOfs, BfIRConfigConst_DynSlotOfs }; enum BfIRIntrinsic : uint8 { BfIRIntrinsic__PLATFORM, BfIRIntrinsic_Abs, BfIRIntrinsic_Add, BfIRIntrinsic_And, BfIRIntrinsic_AtomicAdd, BfIRIntrinsic_AtomicAnd, BfIRIntrinsic_AtomicCmpStore, BfIRIntrinsic_AtomicCmpStore_Weak, BfIRIntrinsic_AtomicCmpXChg, BfIRIntrinsic_AtomicFence, BfIRIntrinsic_AtomicLoad, BfIRIntrinsic_AtomicMax, BfIRIntrinsic_AtomicMin, BfIRIntrinsic_AtomicNAnd, BfIRIntrinsic_AtomicOr, BfIRIntrinsic_AtomicStore, BfIRIntrinsic_AtomicSub, BfIRIntrinsic_AtomicUMax, BfIRIntrinsic_AtomicUMin, BfIRIntrinsic_AtomicXChg, BfIRIntrinsic_AtomicXor, BfIRIntrinsic_BSwap, BfIRIntrinsic_Cast, BfIRIntrinsic_Cos, BfIRIntrinsic_Cpuid, BfIRIntrinsic_DebugTrap, BfIRIntrinsic_Div, BfIRIntrinsic_Eq, BfIRIntrinsic_Floor, BfIRIntrinsic_Free, BfIRIntrinsic_Gt, BfIRIntrinsic_GtE, BfIRIntrinsic_Index, BfIRIntrinsic_Log, BfIRIntrinsic_Log10, BfIRIntrinsic_Log2, BfIRIntrinsic_Lt, BfIRIntrinsic_LtE, BfIRIntrinsic_Malloc, BfIRIntrinsic_Max, BfIRIntrinsic_MemCpy, BfIRIntrinsic_MemMove, BfIRIntrinsic_MemSet, BfIRIntrinsic_Min, BfIRIntrinsic_Mod, BfIRIntrinsic_Mul, BfIRIntrinsic_Neq, BfIRIntrinsic_Not, BfIRIntrinsic_Or, BfIRIntrinsic_Pow, BfIRIntrinsic_PowI, BfIRIntrinsic_ReturnAddress, BfIRIntrinsic_Round, BfIRIntrinsic_SAR, BfIRIntrinsic_SHL, BfIRIntrinsic_SHR, BfIRIntrinsic_Shuffle, BfIRIntrinsic_Sin, BfIRIntrinsic_Sqrt, BfIRIntrinsic_Sub, BfIRIntrinsic_VAArg, BfIRIntrinsic_VAEnd, BfIRIntrinsic_VAStart, BfIRIntrinsic_Xgetbv, BfIRIntrinsic_Xor, BfIRIntrinsic_COUNT, BfIRIntrinsic_Atomic_FIRST = BfIRIntrinsic_AtomicAdd, BfIRIntrinsic_Atomic_LAST = BfIRIntrinsic_AtomicXor }; enum BfIRAtomicOrdering : uint8 { BfIRAtomicOrdering_Unordered, BfIRAtomicOrdering_Relaxed, BfIRAtomicOrdering_Acquire, BfIRAtomicOrdering_Release, BfIRAtomicOrdering_AcqRel, BfIRAtomicOrdering_SeqCst, BfIRAtomicOrdering_ORDERMASK = 7, BfIRAtomicOrdering_Volatile = 8, BfIRAtomicOrdering_ReturnModified = 0x10 // Generally atomic instructions return original value, this overrides that }; enum BfIRStorageKind : uint8 { BfIRStorageKind_Normal, BfIRStorageKind_Import, BfIRStorageKind_Export }; //#define CHECK_CONSTHOLDER struct BfIRRawValue { public: int mId; BfIRRawValue() { mId = -1; } operator bool() const { return mId != -1; } bool IsFake() const { return mId < -1; } }; struct BfIRValue { public: // Reserved 'fake' Ids enum { ID_IMPLICIT = -3 }; public: int mId; BfIRValueFlags mFlags; static BfIRValue sValueless; #ifdef CHECK_CONSTHOLDER BfIRConstHolder* mHolder; #endif public: BfIRValue() { mId = -1; mFlags = BfIRValueFlags_None; #ifdef CHECK_CONSTHOLDER mHolder = NULL; #endif } BfIRValue(const BfIRValue& from) { mFlags = from.mFlags; mId = from.mId; #ifdef CHECK_CONSTHOLDER mHolder = from.mHolder; #endif } BfIRValue(BfIRValueFlags flags, int id) { mFlags = flags; mId = id; } operator bool() const { return mFlags != BfIRValueFlags_None; } bool IsFake() const; bool IsConst() const; bool IsArg() const; bool IsFromLLVM() const; bool operator==(const BfIRValue& rhs) const { if (mFlags != rhs.mFlags) return false; if (mId != rhs.mId) return false; return true; } bool operator!=(const BfIRValue& rhs) const { if (mFlags != rhs.mFlags) return true; if (mId != rhs.mId) return true; return false; } }; struct BfIRTypeData { enum TypeKind { TypeKind_None, TypeKind_TypeId, TypeKind_TypeCode, TypeKind_TypeInstId, TypeKind_TypeInstPtrId, TypeKind_Stream, TypeKind_SizedArray }; TypeKind mKind; int mId; operator bool() { return (mId != -1); } }; struct BfIRType : public BfIRTypeData { public: BfIRType() { mKind = TypeKind_None; mId = -1; } BfIRType(BfIRTypeData typeData) { mKind = typeData.mKind; mId = typeData.mId; } BfIRType(const BfIRValue& val) { mKind = TypeKind_Stream; mId = val.mId; } }; struct BfIRBlock : public BfIRValue { public: BfIRBlock(); BfIRBlock(const BfIRValue& fromVal) : BfIRValue(fromVal) {} }; enum BfIRAttribute { BfIRAttribute_NoReturn, BfIRAttribute_NoAlias, BfIRAttribute_NoCapture, BfIRAttribute_StructRet, BfIRAttribute_VarRet, BfIRAttribute_ZExt, BfIRAttribute_ByVal, BfIRAttribute_Dereferencable, BFIRAttribute_NoUnwind, BFIRAttribute_UWTable, BFIRAttribute_AlwaysInline, BFIRAttribute_NoFramePointerElim, BFIRAttribute_DllImport, BFIRAttribute_DllExport, BFIRAttribute_NoRecurse, BFIRAttribute_Constructor, BFIRAttribute_Destructor, }; struct BfIRFunctionType { public: int mId; public: BfIRFunctionType(); BfIRFunctionType(const BfIRValue& val) { mId = val.mId; } operator bool() const { return mId != -1; } }; struct BfIRFunction : public BfIRRawValue { public: BfIRFunction(); BfIRFunction(const BfIRValue& val) { BF_ASSERT((val.mFlags == BfIRValueFlags_None) || (val.mFlags == BfIRValueFlags_Value)); mId = val.mId; } //: BfIRValue(val) {} bool operator==(const BfIRFunction& rhs) const { if (mId != rhs.mId) return false; return true; } bool operator!=(const BfIRFunction& rhs) const { if (mId == rhs.mId) return false; return true; } operator bool() const { return mId != -1; } operator BfIRValue() const { return BfIRValue((mId == -1) ? BfIRValueFlags_None : BfIRValueFlags_Value, mId); } }; struct BfIRMDNode { public: int mId; BfIRMDNode() { mId = -1; } BfIRMDNode(const BfIRValue& val) { mId = val.mId; } operator bool() const { return mId != -1; } bool operator==(const BfIRMDNode& rhs) const { if (mId != rhs.mId) return false; return true; } bool operator!=(const BfIRMDNode& rhs) const { if (mId == rhs.mId) return false; return true; } }; class BfFileInstance { public: BfParserData* mParser; BfIRMDNode mDIFile; BfFilePosition mPrevPosition; public: BfFileInstance() { mParser = NULL; } }; struct BfGlobalVar { BfConstType mConstType; const char* mName; BfIRType mType; bool mIsConst; BfIRLinkageType mLinkageType; int mStreamId; BfIRValue mInitializer; bool mIsTLS; int mAlignment; }; struct BfGlobalVar_TypeInst { BfConstType mConstType; const char* mName; BfTypeInstance* mTypeInst; bool mIsConst; BfIRLinkageType mLinkageType; int mStreamId; BfIRValue mInitializer; bool mIsTLS; }; struct BfTypeOf_Const { BfConstType mConstType; BfType* mType; BfIRValue mTypeData; }; struct BfTypeOf_WithData_Const { BfConstType mConstType; BfType* mType; BfIRValue mTypeData; }; struct BfConstant { public: union { BfTypeCode mTypeCode; BfConstType mConstType; }; union { bool mBool; int64 mInt64; int32 mInt32; int16 mInt16; int8 mInt8; uint64 mUInt64; uint32 mUInt32; uint16 mUInt16; uint8 mUInt8; uint8 mChar; uint32 mChar32; double mDouble; BfIRTypeData mIRType; }; bool IsNull() { if (mTypeCode == BfTypeCode_NullPtr) return true; if (mConstType == BfConstType_BitCastNull) return true; return false; } }; struct BfConstantSizedArrayType { BfConstType mConstType; BfIRType mType; intptr mLength; }; struct BfConstantUndef { BfConstType mConstType; BfIRType mType; }; struct BfConstantBitCast { BfConstType mConstType; int mTarget; BfIRType mToType; }; struct BfConstantBox { BfConstType mConstType; int mTarget; BfIRType mToType; }; struct BfConstantPtrToInt { BfConstType mConstType; int mTarget; BfTypeCode mToTypeCode; }; struct BfConstantIntToPtr { BfConstType mConstType; int mTarget; BfIRType mToType; }; struct BfConstantGEP32_1 { BfConstType mConstType; int mTarget; int mIdx0; }; struct BfConstantGEP32_2 { BfConstType mConstType; int mTarget; int mIdx0; int mIdx1; }; struct BfConstantExtractValue { BfConstType mConstType; int mTarget; int mIdx0; }; struct BfConstantAgg { BfConstType mConstType; BfIRType mType; BfSizedArray mValues; }; struct BfConstantAggCE { BfConstType mConstType; BfIRType mType; addr_ce mCEAddr; }; struct BfConstantArrayZero { BfConstType mConstType; BfIRType mType; int mCount; }; class BfIRConstHolder { public: BumpAllocatorT<256> mTempAlloc; BfModule* mModule; Dictionary mGlobalVarMap; public: void FixTypeCode(BfTypeCode& typeCode); int GetSize(BfTypeCode typeCode); static int GetSize(BfTypeCode typeCode, int ptrSize); static bool IsInt(BfTypeCode typeCode); static bool IsChar(BfTypeCode typeCode); static bool IsIntable(BfTypeCode typeCode); static bool IsSigned(BfTypeCode typeCode); static bool IsFloat(BfTypeCode typeCode); const char* AllocStr(const StringImpl& str); public: BfIRConstHolder(BfModule* module); virtual ~BfIRConstHolder(); String ToString(BfIRValue irValue); String ToString(BfIRType irType); void pv(const BfIRValue& irValue); BfConstant* GetConstantById(int id); BfConstant* GetConstant(BfIRValue id); bool TryGetBool(BfIRValue id, bool& boolVal); int IsZero(BfIRValue val); bool IsConstValue(BfIRValue val); int CheckConstEquality(BfIRValue lhs, BfIRValue rhs); // -1 = fail, 0 = false, 1 = true //void WriteConstant(void* data, BeConstant* constVal); BfIRType GetSizedArrayType(BfIRType elementType, int length); BfIRValue CreateConst(BfTypeCode typeCode, uint64 val); BfIRValue CreateConst(BfTypeCode typeCode, int val); BfIRValue CreateConst(BfTypeCode typeCode, double val); BfIRValue CreateConst(BfConstant* fromConst, BfIRConstHolder* fromHolder); BfIRValue CreateConstNull(); BfIRValue CreateConstNull(BfIRType nullType); BfIRValue CreateConstAggZero(BfIRType aggType); BfIRValue CreateConstAgg(BfIRType type, const BfSizedArray& values); BfIRValue CreateConstAggCE(BfIRType type, addr_ce ptr); BfIRValue CreateConstArrayZero(BfIRType type, int count); BfIRValue CreateConstArrayZero(int count); BfIRValue CreateConstBitCast(BfIRValue val, BfIRType type); BfIRValue CreateConstBox(BfIRValue val, BfIRType type); BfIRValue CreateTypeOf(BfType* type); BfIRValue CreateTypeOfComptime(BfType* type); BfIRValue CreateTypeOf(BfType* type, BfIRValue typeData); BfIRValue GetUndefConstValue(BfIRType type); BfIRValue CreateGlobalVariableConstant(BfIRType varType, bool isConstant, BfIRLinkageType linkageType, BfIRValue initializer, const StringImpl& name, bool isTLS = false); bool WriteConstant(BfIRValue val, void* ptr, BfType* type); BfIRValue ReadConstant(void* ptr, BfType* type); }; enum BfIRPopulateType { BfIRPopulateType_Identity, BfIRPopulateType_Declaration, BfIRPopulateType_Eventually_Full, BfIRPopulateType_Full, BfIRPopulateType_Full_ForceDefinition }; struct BfIRState { BfIRBlock mActualInsertBlock; // Only when not ignoring writes BfIRBlock mInsertBlock; BfIRFunction mActiveFunction; bool mActiveFunctionHasBody; Array mSavedDebugLocs; }; enum BfOverflowCheckKind : int8 { BfOverflowCheckKind_None = 0, BfOverflowCheckKind_Signed = 1, BfOverflowCheckKind_Unsigned = 2, BfOverflowCheckKind_Flag_UseAsm = 4 }; class BfIRBuilder : public BfIRConstHolder { public: bool mIgnoreWrites; bool mDbgVerifyCodeGen; int mCurFakeId; bool mHasGlobalDefs; bool mIsBeefBackend; int mNumFunctionsWithBodies; int mBlockCount; bool mHasStarted; int mCmdCount; ChunkedDataBuffer mStream; BfIRBlock mActualInsertBlock; // Only when not ignoring writes BfIRBlock mInsertBlock; bool mHasDebugLoc; bool mHasDebugInfo; bool mHasDebugLineInfo; Dictionary mMethodTypeMap; Dictionary mFunctionMap; Dictionary mTypeMap; Dictionary mConstMemMap; Array mDITemporaryTypes; BfIRFunction mActiveFunction; bool mActiveFunctionHasBody; Array mSavedDebugLocs; Array mDeferredDbgTypeDefs; BfIRCodeGenBase* mIRCodeGen; BfIRCodeGen* mBfIRCodeGen; BeIRCodeGen* mBeIRCodeGen; #ifdef BFIR_RENTRY_CHECK std::set mDeclReentrySet; std::set mDefReentrySet; #endif bool mOpFailed; public: ~BfIRBuilder(); void WriteSLEB128(int64 val); void WriteSLEB128(int32 val); void Write(uint8 val); void Write(bool val); void Write(int val); void Write(int64 val); void Write(Val128 val); void Write(const StringImpl& str); void Write(const BfIRValue& irValue); void Write(BfTypeCode typeCode); void Write(const BfIRTypeData& type); void Write(BfIRFunctionType func); void Write(BfIRFunction funcType); void Write(BfIRBlock block); void Write(BfIRMDNode node); template void Write(const BfSizedArray& sizedArray) { WriteSLEB128(sizedArray.mSize); for (int i = 0; i < sizedArray.mSize; i++) Write(sizedArray.mVals[i]); } BfIRValue WriteCmd(BfIRCmd cmd); template void WriteArg(const T& first) { Write(first); } template void WriteArg(const T& first, const Args&... args) { Write(first); WriteArg(args...); } template BfIRValue WriteCmd(BfIRCmd cmd, const Args&... args) { if (mIgnoreWrites) return GetFakeVal(); //int dataPos = mStream.GetSize(); auto result = WriteCmd(cmd); WriteArg(args...); return result; //return BfIRValue(BfIRValueFlags_Value, dataPos); } public: void NewCmdInserted(); BfIRMDNode CreateNamespaceScope(BfType* type, BfIRMDNode fileDIScope); String GetDebugTypeName(BfTypeInstance* typeInstance, bool includeOuterTypeName); void CreateDbgTypeDefinition(BfType* type); bool WantsDbgDefinition(BfType * type); void CreateTypeDeclaration(BfType* type, bool forceDbgDefine); void CreateTypeDefinition_Data(BfModule* populateModule, BfTypeInstance* typeInstance, bool forceDbgDefine); void CreateTypeDefinition(BfType* type, bool forceDbgDefine); void ReplaceDITemporaryTypes(); void PushDbgLoc(BfTypeInstance* typeInst); BfIRPopulateType GetPopulateTypeState(BfType* type); void PopulateType(BfType* type, BfIRPopulateType populateType = BfIRPopulateType_Full); void SetType(BfType* type, BfIRType irType); void SetInstType(BfType* type, BfIRType irType); int GetFakeId(); BfIRValue GetFakeVal(); BfIRValue GetFakeConst(); BfIRType GetFakeType(); BfIRType GetFakeBlock(); BfIRFunctionType GetFakeFunctionType(); BfIRFunction GetFakeFunction(); public: void OpFailed(); uint8 CheckedAdd(uint8 a, uint8 b); uint16 CheckedAdd(uint16 a, uint16 b); uint32 CheckedAdd(uint32 a, uint32 b); uint64 CheckedAdd(uint64 a, uint64 b); int8 CheckedAdd(int8 a, int8 b); int16 CheckedAdd(int16 a, int16 b); int32 CheckedAdd(int32 a, int32 b); int64 CheckedAdd(int64 a, int64 b); float CheckedAdd(float a, float b) { return a + b; } double CheckedAdd(double a, double b) { return a + b; } uint8 CheckedSub(uint8 a, uint8 b); uint16 CheckedSub(uint16 a, uint16 b); uint32 CheckedSub(uint32 a, uint32 b); uint64 CheckedSub(uint64 a, uint64 b); int8 CheckedSub(int8 a, int8 b); int16 CheckedSub(int16 a, int16 b); int32 CheckedSub(int32 a, int32 b); int64 CheckedSub(int64 a, int64 b); float CheckedSub(float a, float b) { return a - b; } double CheckedSub(double a, double b) { return a - b; } uint8 CheckedMul(uint8 a, uint8 b); uint16 CheckedMul(uint16 a, uint16 b); uint32 CheckedMul(uint32 a, uint32 b); uint64 CheckedMul(uint64 a, uint64 b); int8 CheckedMul(int8 a, int8 b); int16 CheckedMul(int16 a, int16 b); int32 CheckedMul(int32 a, int32 b); int64 CheckedMul(int64 a, int64 b); float CheckedMul(float a, float b) { return a * b; } double CheckedMul(double a, double b) { return a * b; } uint8 CheckedShl(uint8 a, uint8 b); uint16 CheckedShl(uint16 a, uint16 b); uint32 CheckedShl(uint32 a, uint32 b); uint64 CheckedShl(uint64 a, uint64 b); int8 CheckedShl(int8 a, int8 b); int16 CheckedShl(int16 a, int16 b); int32 CheckedShl(int32 a, int32 b); int64 CheckedShl(int64 a, int64 b); public: BfIRBuilder(BfModule* module); bool HasExports(); // Contains non-empty functions and/or non-empty globals String ToString(BfIRValue irValue); String ToString(BfIRType irType); String ToString(BfIRFunction irFunc); String ToString(BfIRFunctionType irType); String ToString(BfIRMDNode irMDNode); String ActiveFuncToString(); void PrintActiveFunc(); void pv(const BfIRValue& irValue); void pt(const BfIRType& irType); void pbft(BfType* type); void pt(const BfIRFunction& irFun); void pft(const BfIRFunctionType& irType); void pmd(const BfIRMDNode& irMDNode); void GetBufferData(Array& outBuffer); void ClearConstData(); void ClearNonConstData(); void Start(const StringImpl& moduleName, int ptrSize, bool isOptimized); void SetBackend(bool isBeefBackend); void RemoveIRCodeGen(); void WriteIR(const StringImpl& fileName); void AbortStream(); void Module_SetTargetTriple(const StringImpl& targetTriple, const StringImpl& targetCPU); void Module_AddModuleFlag(const StringImpl& flag, int val); BfIRType GetPrimitiveType(BfTypeCode typeCode); BfIRType CreateStructType(const StringImpl& name); BfIRType CreateStructType(const BfSizedArray& memberTypes); void StructSetBody(BfIRType type, const BfSizedArray& memberTypes, int size, int align, bool isPacked); BfIRType MapType(BfType* type, BfIRPopulateType populateType = BfIRPopulateType_Declaration); BfIRType MapTypeInst(BfTypeInstance* typeInst, BfIRPopulateType populateType = BfIRPopulateType_Declaration); BfIRType MapTypeInstPtr(BfTypeInstance* typeInst); BfIRType GetType(BfIRValue val); BfIRType GetPointerTo(BfIRFunctionType funcType); BfIRType GetPointerTo(BfIRType type); BfIRType GetSizedArrayType(BfIRType elementType, int length); BfIRType GetVectorType(BfIRType elementType, int length); BfIRValue CreateConstAgg_Value(BfIRType type, const BfSizedArray& values); BfIRValue CreateConstString(const StringImpl& string); BfIRValue ConstToMemory(BfIRValue constVal); BfIRValue GetConfigConst(BfIRConfigConst constType, BfTypeCode typeCode); BfIRValue GetArgument(int argIdx); void SetName(BfIRValue val, const StringImpl& name); BfIRValue CreateUndefValue(BfIRType type); BfIRValue CreateNumericCast(BfIRValue val, bool valIsSigned, BfTypeCode typeCode); BfIRValue CreateCmpEQ(BfIRValue lhs, BfIRValue rhs); BfIRValue CreateCmpNE(BfIRValue lhs, BfIRValue rhs); BfIRValue CreateCmpLT(BfIRValue lhs, BfIRValue rhs, bool isSigned); BfIRValue CreateCmpLTE(BfIRValue lhs, BfIRValue rhs, bool isSigned); BfIRValue CreateCmpGT(BfIRValue lhs, BfIRValue rhs, bool isSigned); BfIRValue CreateCmpGTE(BfIRValue lhs, BfIRValue rhs, bool isSigned); BfIRValue CreateAdd(BfIRValue lhs, BfIRValue rhs, BfOverflowCheckKind overflowCheckKind = BfOverflowCheckKind_None); BfIRValue CreateSub(BfIRValue lhs, BfIRValue rhs, BfOverflowCheckKind overflowCheckKind = BfOverflowCheckKind_None); BfIRValue CreateMul(BfIRValue lhs, BfIRValue rhs, BfOverflowCheckKind overflowCheckKind = BfOverflowCheckKind_None); BfIRValue CreateDiv(BfIRValue lhs, BfIRValue rhs, bool isSigned); BfIRValue CreateRem(BfIRValue lhs, BfIRValue rhs, bool isSigned); BfIRValue CreateAnd(BfIRValue lhs, BfIRValue rhs); BfIRValue CreateOr(BfIRValue lhs, BfIRValue rhs); BfIRValue CreateXor(BfIRValue lhs, BfIRValue rhs); BfIRValue CreateShl(BfIRValue lhs, BfIRValue rhs); BfIRValue CreateShr(BfIRValue lhs, BfIRValue rhs, bool isSigned); BfIRValue CreateNeg(BfIRValue val); BfIRValue CreateNot(BfIRValue val); BfIRValue CreateBitCast(BfIRValue val, BfIRType type); BfIRValue CreatePtrToInt(BfIRValue val, BfTypeCode typeCode); BfIRValue CreateIntToPtr(BfIRValue val, BfIRType type); BfIRValue CreateIntToPtr(uint64 val, BfIRType type); BfIRValue CreateInBoundsGEP(BfIRValue val, int idx0); BfIRValue CreateInBoundsGEP(BfIRValue val, int idx0, int idx1); BfIRValue CreateInBoundsGEP(BfIRValue val, BfIRValue idx0); BfIRValue CreateInBoundsGEP(BfIRValue val, BfIRValue idx0, BfIRValue idx1); BfIRValue CreateIsNull(BfIRValue val); BfIRValue CreateIsNotNull(BfIRValue val); BfIRValue CreateExtractValue(BfIRValue val, int idx); BfIRValue CreateExtractValue(BfIRValue val, BfIRValue idx); BfIRValue CreateInsertValue(BfIRValue agg, BfIRValue val, int idx); BfIRValue CreateAlloca(BfIRType type); BfIRValue CreateAlloca(BfIRType type, BfIRValue arraySize); void SetAllocaAlignment(BfIRValue val, int alignment); // When we do a dynamic alloca where we know the memory access patterns will not cause a page fault, we can omit the __chkstk call // Generally, this is when we allocate less than 4k and we know there will be a write on this memory before the next alloca void SetAllocaNoChkStkHint(BfIRValue val); void SetAllocaForceMem(BfIRValue val); BfIRValue CreateAliasValue(BfIRValue val); BfIRValue CreateLifetimeStart(BfIRValue val); BfIRValue CreateLifetimeEnd(BfIRValue val); BfIRValue CreateLifetimeSoftEnd(BfIRValue val); BfIRValue CreateLifetimeExtend(BfIRValue val); BfIRValue CreateValueScopeStart(); void CreateValueScopeRetain(BfIRValue val); // When a value is held by a variable -- don't release until we have a HardValueScopeEnd void CreateValueScopeSoftEnd(BfIRValue scopeStart); void CreateValueScopeHardEnd(BfIRValue scopeStart); BfIRValue CreateLoad(BfIRValue val, bool isVolatile = false); BfIRValue CreateAlignedLoad(BfIRValue val, int align, bool isVolatile = false); BfIRValue CreateStore(BfIRValue val, BfIRValue ptr, bool isVolatile = false); BfIRValue CreateAlignedStore(BfIRValue val, BfIRValue ptr, int align, bool isVolatile = false); BfIRValue CreateMemSet(BfIRValue addr, BfIRValue val, BfIRValue size, int align); void CreateFence(BfIRFenceType fenceType); BfIRValue CreateStackSave(); BfIRValue CreateStackRestore(BfIRValue stackVal); BfIRValue CreateGlobalVariable(BfIRType varType, bool isConstant, BfIRLinkageType linkageType, BfIRValue initializer, const StringImpl& name, bool isTLS = false); void CreateGlobalVariable(BfIRValue irValue); void GlobalVar_SetUnnamedAddr(BfIRValue val, bool unnamedAddr); void GlobalVar_SetInitializer(BfIRValue globalVar, BfIRValue initVal); void GlobalVar_SetAlignment(BfIRValue globalVar, int alignment); void GlobalVar_SetStorageKind(BfIRValue globalVar, BfIRStorageKind storageKind); BfIRValue CreateGlobalStringPtr(const StringImpl& str); void SetReflectTypeData(BfIRType type, BfIRValue globalVar); BfIRBlock CreateBlock(const StringImpl& name, bool addNow = false); BfIRBlock MaybeChainNewBlock(const StringImpl& name); // Creates new block if current block isn't empty void AddBlock(BfIRBlock block); void DropBlocks(BfIRBlock block); void MergeBlockDown(BfIRBlock fromBlock, BfIRBlock intoBlock); void SetInsertPoint(BfIRValue value); void SetInsertPoint(BfIRBlock block); void SetInsertPointAtStart(BfIRBlock block); void EraseFromParent(BfIRBlock block); void DeleteBlock(BfIRBlock block); void EraseInstFromParent(BfIRValue val); BfIRValue CreateBr(BfIRBlock block); BfIRValue CreateBr_Fake(BfIRBlock block); BfIRValue CreateBr_NoCollapse(BfIRBlock block); void CreateCondBr(BfIRValue val, BfIRBlock trueBlock, BfIRBlock falseBlock); BfIRBlock GetInsertBlock(); void MoveBlockToEnd(BfIRBlock block); BfIRValue CreateSwitch(BfIRValue value, BfIRBlock dest, int numCases); BfIRValue AddSwitchCase(BfIRValue switchVal, BfIRValue caseVal, BfIRBlock caseBlock); void SetSwitchDefaultDest(BfIRValue switchVal, BfIRBlock caseBlock); BfIRValue CreatePhi(BfIRType type, int incomingCount); void AddPhiIncoming(BfIRValue phi, BfIRValue value, BfIRBlock comingFrom); BfIRFunction GetIntrinsic(String intrinName, int intrinId, BfIRType returnType, const BfSizedArray& paramTypes); BfIRFunctionType MapMethod(BfMethodInstance* methodInstance); BfIRFunctionType CreateFunctionType(BfIRType resultType, const BfSizedArray& paramTypes, bool isVarArg = false); BfIRFunction CreateFunction(BfIRFunctionType funcType, BfIRLinkageType linkageType, const StringImpl& name); void SetFunctionName(BfIRValue func, const StringImpl& name); void EnsureFunctionPatchable(); BfIRValue RemapBindFunction(BfIRValue func); void SetActiveFunction(BfIRFunction func); BfIRFunction GetActiveFunction(); BfIRFunction GetFunction(const StringImpl& name); BfIRValue CreateCall(BfIRValue func, const BfSizedArray& params); void SetCallCallingConv(BfIRValue callInst, BfIRCallingConv callingConv); void SetFuncCallingConv(BfIRFunction func, BfIRCallingConv callingConv); void SetTailCall(BfIRValue callInst); void SetCallAttribute(BfIRValue callInst, int paramIdx, BfIRAttribute attribute); BfIRValue CreateRet(BfIRValue val); BfIRValue CreateSetRet(BfIRValue val, int returnTypeId); void CreateRetVoid(); void CreateUnreachable(); void Call_AddAttribute(BfIRValue callInst, int argIdx, BfIRAttribute attr); void Call_AddAttribute(BfIRValue callInst, int argIdx, BfIRAttribute attr, int arg); void Func_AddAttribute(BfIRFunction func, int argIdx, BfIRAttribute attr); void Func_AddAttribute(BfIRFunction func, int argIdx, BfIRAttribute attr, int arg); void Func_SetParamName(BfIRFunction func, int argIdx, const StringImpl& name); void Func_DeleteBody(BfIRFunction func); void Func_SafeRename(BfIRFunction func); void Func_SafeRenameFrom(BfIRFunction func, const StringImpl& prevName); void Func_SetLinkage(BfIRFunction func, BfIRLinkageType linkage); void Comptime_Error(int errorKind); BfIRValue Comptime_GetBfType(int typeId, BfIRType resultType); BfIRValue Comptime_GetReflectType(int typeId, BfIRType resultType); BfIRValue Comptime_DynamicCastCheck(BfIRValue value, int typeId, BfIRType resultType); BfIRValue Comptime_GetVirtualFunc(BfIRValue value, int virtualTableId, BfIRType resultType); BfIRValue Comptime_GetInterfaceFunc(BfIRValue value, int typeId, int methodIdx, BfIRType resultType); void SaveDebugLocation(); void RestoreDebugLocation(); void DupDebugLocation(); bool HasDebugLocation(); void ClearDebugLocation(); void ClearDebugLocation(BfIRValue inst); void ClearDebugLocation_Last(); void UpdateDebugLocation(BfIRValue inst); void SetCurrentDebugLocation(int line, int column, BfIRMDNode diScope, BfIRMDNode diInlinedAt); void CreateNop(); void CreateEnsureInstructionAt(); void CreateStatementStart(); void CreateObjectAccessCheck(BfIRValue value, bool useAsm); void DbgInit(); void DbgFinalize(); bool DbgHasInfo(); bool DbgHasLineInfo(); String DbgGetStaticFieldName(BfFieldInstance* fieldInstance); void DbgAddPrefix(String& name); BfIRMDNode DbgCreateCompileUnit(int lang, const StringImpl& filename, const StringImpl& directory, const StringImpl& producer, bool isOptimized, const StringImpl& flags, int runtimeVer, bool linesOnly); BfIRMDNode DbgCreateFile(const StringImpl& fileName, const StringImpl& directory, const Val128& md5Hash); BfIRMDNode DbgGetCurrentLocation(); void DbgSetType(BfType * type, BfIRMDNode diType); void DbgSetInstType(BfType * type, BfIRMDNode diType); BfIRMDNode DbgCreateConstValue(int64 val); BfIRMDNode DbgGetType(BfType* type, BfIRPopulateType populateType = BfIRPopulateType_Declaration); BfIRMDNode DbgGetTypeInst(BfTypeInstance* typeInst, BfIRPopulateType populateType = BfIRPopulateType_Declaration); void DbgTrackDITypes(BfType* type); BfIRMDNode DbgCreateNameSpace(BfIRMDNode scope, const StringImpl& name, BfIRMDNode file, int lineNum); BfIRMDNode DbgCreateImportedModule(BfIRMDNode context, BfIRMDNode namespaceNode, int line); BfIRMDNode DbgCreateBasicType(const StringImpl& name, int64 sizeInBits, int64 alignInBits, int encoding); BfIRMDNode DbgCreateStructType(BfIRMDNode context, const StringImpl& name, BfIRMDNode file, int lineNum, int64 sizeInBits, int64 alignInBits, int flags, BfIRMDNode derivedFrom, const BfSizedArray& elements); BfIRMDNode DbgCreateEnumerationType(BfIRMDNode scope, const StringImpl& name, BfIRMDNode file, int lineNumber, int64 SizeInBits, int64 alignInBits, const BfSizedArray& elements, BfIRMDNode underlyingType); BfIRMDNode DbgCreatePointerType(BfIRMDNode diType); BfIRMDNode DbgCreateReferenceType(BfIRMDNode diType); BfIRMDNode DbgCreateConstType(BfIRMDNode diType); BfIRMDNode DbgCreateArtificialType(BfIRMDNode diType); BfIRMDNode DbgCreateArrayType(int64 sizeInBits, int64 alignInBits, BfIRMDNode elementType, int64 numElements); BfIRMDNode DbgCreateReplaceableCompositeType(int tag, const StringImpl& name, BfIRMDNode scope, BfIRMDNode F, int line, int64 sizeInBits = 0, int64 alignInBits = 0, int flags = 0); void DbgSetTypeSize(BfIRMDNode diType, int64 sizeInBits, int alignInBits); BfIRMDNode DbgCreateForwardDecl(int tag, const StringImpl& name, BfIRMDNode scope, BfIRMDNode F, int line); BfIRMDNode DbgCreateSizedForwardDecl(int tag, const StringImpl& name, BfIRMDNode scope, BfIRMDNode F, int line, int64 sizeInBits, int64 alignInBits); BfIRMDNode DbgReplaceAllUses(BfIRMDNode diPrevNode, BfIRMDNode diNewNode); void DbgDeleteTemporary(BfIRMDNode diNode); BfIRMDNode DbgMakePermanent(BfIRMDNode diNode, BfIRMDNode diBaseType, const BfSizedArray& elements); BfIRMDNode DbgCreateEnumerator(const StringImpl& name, int64 val); BfIRMDNode DbgCreateMemberType(BfIRMDNode scope, const StringImpl& name, BfIRMDNode file, int lineNumber, int64 sizeInBits, int64 alignInBits, int64 offsetInBits, int flags, BfIRMDNode type); BfIRMDNode DbgCreateStaticMemberType(BfIRMDNode scope, const StringImpl& name, BfIRMDNode file, int lineNumber, BfIRMDNode type, int flags, BfIRValue val); BfIRMDNode DbgCreateInheritance(BfIRMDNode type, BfIRMDNode baseType, int64 baseOffset, int flags); BfIRMDNode DbgCreateMethod(BfIRMDNode context, const StringImpl& name, const StringImpl& linkageName, BfIRMDNode file, int lineNum, BfIRMDNode type, bool isLocalToUnit, bool isDefinition, int vk, int vIndex, BfIRMDNode vTableHolder, int flags, bool isOptimized, BfIRValue fn, const BfSizedArray& genericArgs, const BfSizedArray& genericConstValueArgs); BfIRMDNode DbgCreateFunction(BfIRMDNode context, const StringImpl& name, const StringImpl& linkageName, BfIRMDNode file, int lineNum, BfIRMDNode type, bool isLocalToUnit, bool isDefinition, int scopeLine, int flags, bool isOptimized, BfIRValue fn); BfIRMDNode DbgCreateParameterVariable(BfIRMDNode scope, const StringImpl& name, int argNo, BfIRMDNode file, int lineNum, BfIRMDNode type, bool AlwaysPreserve = false, int flags = 0); BfIRMDNode DbgCreateSubroutineType(BfMethodInstance* methodInstance); BfIRMDNode DbgCreateSubroutineType(const BfSizedArray& elements); BfIRMDNode DbgCreateAutoVariable(BfIRMDNode scope, const StringImpl& name, BfIRMDNode file, int lineNo, BfIRMDNode type, BfIRInitType initType = BfIRInitType_NotSet); BfIRValue DbgInsertValueIntrinsic(BfIRValue val, BfIRMDNode varInfo); BfIRValue DbgInsertDeclare(BfIRValue val, BfIRMDNode varInfo, BfIRValue declareBefore = BfIRValue()); BfIRValue DbgLifetimeEnd(BfIRMDNode varInfo); void DbgCreateGlobalVariable(BfIRMDNode context, const StringImpl& name, const StringImpl& linkageName, BfIRMDNode file, int lineNumber, BfIRMDNode type, bool isLocalToUnit, BfIRValue val, BfIRMDNode Decl = BfIRMDNode()); BfIRMDNode DbgCreateLexicalBlock(BfIRMDNode scope, BfIRMDNode file, int line, int col); void DbgCreateAnnotation(BfIRMDNode scope, const StringImpl& name, BfIRValue value); BfIRState GetState(); void SetState(const BfIRState& state); }; NS_BF_END