2019-08-23 11:56:54 -07:00
# pragma once
# pragma once
# include "BfAst.h"
# include <unordered_map>
# include "BfSource.h"
# include "BfIRBuilder.h"
# include "BeefySysLib/util/MultiHashSet.h"
2022-02-16 18:28:23 -05:00
# include "BeefySysLib/util/BitSet.h"
2019-08-23 11:56:54 -07:00
NS_BF_BEGIN
class BfModule ;
class BfType ;
class BfTypeInstance ;
class BfContext ;
class BfCustomAttributes ;
2020-06-04 11:47:55 -07:00
enum BfResolveTypeRefFlags
{
BfResolveTypeRefFlag_None = 0 ,
BfResolveTypeRefFlag_NoResolveGenericParam = 1 ,
BfResolveTypeRefFlag_AllowRef = 2 ,
BfResolveTypeRefFlag_AllowRefGeneric = 4 ,
BfResolveTypeRefFlag_IgnoreLookupError = 8 ,
BfResolveTypeRefFlag_AllowGenericTypeParamConstValue = 0x10 ,
BfResolveTypeRefFlag_AllowGenericMethodParamConstValue = 0x20 ,
BfResolveTypeRefFlag_AllowGenericParamConstValue = 0x10 | 0x20 ,
BfResolveTypeRefFlag_AutoComplete = 0x40 ,
BfResolveTypeRefFlag_FromIndirectSource = 0x80 , // Such as a type alias or a generic parameter
BfResolveTypeRefFlag_Attribute = 0x100 ,
BfResolveTypeRefFlag_NoReify = 0x200 ,
2020-07-10 06:40:24 -07:00
BfResolveTypeRefFlag_NoCreate = 0x400 ,
2021-01-16 06:26:55 -08:00
BfResolveTypeRefFlag_NoWarnOnMut = 0x800 ,
2021-02-02 07:08:55 -08:00
BfResolveTypeRefFlag_DisallowComptime = 0x1000 ,
2021-07-15 12:50:42 -07:00
BfResolveTypeRefFlag_AllowDotDotDot = 0x2000 ,
2021-07-19 08:19:50 -07:00
BfResolveTypeRefFlag_AllowGlobalContainer = 0x4000 ,
2021-11-27 08:01:08 -08:00
BfResolveTypeRefFlag_AllowInferredSizedArray = 0x8000 ,
BfResolveTypeRefFlag_AllowGlobalsSelf = 0x10000 ,
2022-02-21 18:32:23 -08:00
BfResolveTypeRefFlag_AllowImplicitConstExpr = 0x20000 ,
BfResolveTypeRefFlag_AllowUnboundGeneric = 0x40000 ,
2022-07-06 12:19:01 -07:00
BfResolveTypeRefFlag_ForceUnboundGeneric = 0x80000 ,
BfResolveTypeRefFlag_IgnoreProtection = 0x100000
2020-06-04 11:47:55 -07:00
} ;
2019-08-23 11:56:54 -07:00
enum BfTypeNameFlags : uint16
{
BfTypeNameFlags_None = 0 ,
BfTypeNameFlag_ResolveGenericParamNames = 1 ,
2020-04-29 09:53:48 -07:00
BfTypeNameFlag_UseUnspecializedGenericParamNames = 2 ,
BfTypeNameFlag_OmitNamespace = 4 ,
BfTypeNameFlag_OmitOuterType = 8 ,
BfTypeNameFlag_ReduceName = 0x10 ,
BfTypeNameFlag_UseArrayImplType = 0x20 ,
BfTypeNameFlag_DisambiguateDups = 0x40 , // Add a disambiguation if mDupDetectedRevision is set
BfTypeNameFlag_AddGlobalContainerName = 0x80 ,
BfTypeNameFlag_InternalName = 0x100 , // Use special delimiters to remove ambiguities (ie: '+' for inner types)
BfTypeNameFlag_HideGlobalName = 0x200 ,
2022-02-05 09:23:44 -05:00
BfTypeNameFlag_ExtendedInfo = 0x400 ,
2022-06-01 11:00:33 -07:00
BfTypeNameFlag_ShortConst = 0x800 ,
BfTypeNameFlag_AddProjectName = 0x1000
2019-08-23 11:56:54 -07:00
} ;
enum BfMethodNameFlags : uint8
{
BfMethodNameFlag_None = 0 ,
BfMethodNameFlag_ResolveGenericParamNames = 1 ,
2020-10-08 09:41:05 -07:00
BfMethodNameFlag_OmitTypeName = 2 ,
2020-12-17 04:51:05 -08:00
BfMethodNameFlag_IncludeReturnType = 4 ,
2021-12-15 10:48:42 -05:00
BfMethodNameFlag_OmitParams = 8 ,
2022-01-22 07:57:02 -05:00
BfMethodNameFlag_IncludeMut = 0x10 ,
BfMethodNameFlag_NoAst = 0x20
2019-08-23 11:56:54 -07:00
} ;
2019-12-01 14:40:17 -08:00
enum BfGetMethodInstanceFlags : uint16
2019-08-23 11:56:54 -07:00
{
BfGetMethodInstanceFlag_None = 0 ,
BfGetMethodInstanceFlag_UnspecializedPass = 1 ,
BfGetMethodInstanceFlag_ExplicitSpecializedModule = 2 ,
BfGetMethodInstanceFlag_ExplicitResolveOnlyPass = 4 ,
BfGetMethodInstanceFlag_ForeignMethodDef = 8 ,
BfGetMethodInstanceFlag_Unreified = 0x10 ,
BfGetMethodInstanceFlag_NoForceReification = 0x20 ,
BfGetMethodInstanceFlag_ResultNotUsed = 0x40 ,
2019-12-01 14:40:17 -08:00
BfGetMethodInstanceFlag_ForceInline = 0x80 ,
BfGetMethodInstanceFlag_Friend = 0x100 ,
BfGetMethodInstanceFlag_DisableObjectAccessChecks = 0x200 ,
2020-09-28 12:41:42 -07:00
BfGetMethodInstanceFlag_NoInline = 0x400 ,
2020-12-23 14:04:35 -08:00
BfGetMethodInstanceFlag_DepthExceeded = 0x800 ,
2020-12-27 10:56:14 -08:00
BfGetMethodInstanceFlag_NoReference = 0x1000 ,
BfGetMethodInstanceFlag_MethodInstanceOnly = 0x2000
2019-08-23 11:56:54 -07:00
} ;
class BfDependencyMap
{
public :
2020-07-21 13:14:09 -07:00
enum DependencyFlags
2019-08-23 11:56:54 -07:00
{
2020-07-21 13:14:09 -07:00
DependencyFlag_None = 0 ,
2019-08-23 11:56:54 -07:00
DependencyFlag_Calls = 1 ,
DependencyFlag_InlinedCall = 2 ,
DependencyFlag_ReadFields = 4 ,
DependencyFlag_DerivedFrom = 8 ,
DependencyFlag_OuterType = 0x10 ,
DependencyFlag_ImplementsInterface = 0x20 ,
DependencyFlag_ValueTypeMemberData = 0x40 ,
DependencyFlag_PtrMemberData = 0x80 ,
DependencyFlag_StaticValue = 0x100 ,
DependencyFlag_ConstValue = 0x200 ,
2021-01-02 15:46:29 -08:00
DependencyFlag_ConstEvalConstField = 0x400 , // Used a field that was CE-generated
DependencyFlag_ConstEval = 0x800 ,
DependencyFlag_MethodGenericArg = 0x1000 ,
DependencyFlag_LocalUsage = 0x2000 ,
DependencyFlag_ExprTypeReference = 0x4000 ,
DependencyFlag_TypeGenericArg = 0x8000 ,
DependencyFlag_UnspecializedType = 0x10000 ,
DependencyFlag_GenericArgRef = 0x20000 ,
DependencyFlag_ParamOrReturnValue = 0x40000 ,
DependencyFlag_CustomAttribute = 0x80000 ,
DependencyFlag_Constraint = 0x100000 ,
DependencyFlag_StructElementType = 0x200000 ,
DependencyFlag_TypeReference = 0x400000 , // Explicit type reference for things like tuples, so all referencing types get passed over on symbol reference
DependencyFlag_Allocates = 0x800000 ,
DependencyFlag_NameReference = 0x1000000 ,
DependencyFlag_VirtualCall = 0x2000000 ,
DependencyFlag_WeakReference = 0x4000000 , // Keeps alive but won't rebuild
2021-10-13 12:09:12 -07:00
DependencyFlag_ValueTypeSizeDep = 0x8000000 , // IE: int32[DepType.cVal]
2020-07-21 13:14:09 -07:00
DependencyFlag_DependentUsageMask = ~ ( DependencyFlag_UnspecializedType | DependencyFlag_MethodGenericArg | DependencyFlag_GenericArgRef )
2019-08-23 11:56:54 -07:00
} ;
struct DependencyEntry
{
2020-09-28 12:41:42 -07:00
int mRevision ;
2020-07-21 13:14:09 -07:00
DependencyFlags mFlags ;
2019-08-23 11:56:54 -07:00
2020-07-21 13:14:09 -07:00
DependencyEntry ( int revision , DependencyFlags flags )
2019-08-23 11:56:54 -07:00
{
2020-09-28 12:41:42 -07:00
mRevision = revision ;
2019-08-23 11:56:54 -07:00
mFlags = flags ;
}
} ;
public :
2020-07-21 13:14:09 -07:00
typedef Dictionary < BfType * , DependencyEntry > TypeMap ;
2020-12-31 11:31:19 -08:00
DependencyFlags mFlagsUnion ;
2019-08-23 11:56:54 -07:00
TypeMap mTypeSet ;
2020-09-28 12:41:42 -07:00
int mMinDependDepth ;
2019-08-23 11:56:54 -07:00
public :
2020-09-28 12:41:42 -07:00
BfDependencyMap ( )
{
mMinDependDepth = 0 ;
2020-12-31 11:31:19 -08:00
mFlagsUnion = DependencyFlag_None ;
2020-09-28 12:41:42 -07:00
}
2020-07-21 13:14:09 -07:00
bool AddUsedBy ( BfType * dependentType , DependencyFlags flags ) ;
2019-08-23 11:56:54 -07:00
bool IsEmpty ( ) ;
TypeMap : : iterator begin ( ) ;
TypeMap : : iterator end ( ) ;
TypeMap : : iterator erase ( TypeMap : : iterator & itr ) ;
} ;
2022-03-19 12:24:56 -07:00
class BfDepContext
{
public :
HashSet < BfType * > mDeepSeenAliases ;
int mAliasDepth ;
public :
BfDepContext ( )
{
mAliasDepth = 0 ;
}
} ;
2019-08-23 11:56:54 -07:00
enum BfHotDepDataKind : int8
{
BfHotDepDataKind_Unknown ,
BfHotDepDataKind_TypeVersion ,
BfHotDepDataKind_ThisType ,
BfHotDepDataKind_Allocation ,
BfHotDepDataKind_Method ,
BfHotDepDataKind_DupMethod ,
BfHotDepDataKind_DevirtualizedMethod ,
BfHotDepDataKind_InnerMethod ,
BfHotDepDataKind_FunctionPtr ,
BfHotDepDataKind_VirtualDecl
} ;
enum BfHotDepDataFlags : int8
{
BfHotDepDataFlag_None = 0 ,
BfHotDepDataFlag_AlwaysCalled = 1 ,
BfHotDepDataFlag_NotReified = 2 ,
BfHotDepDataFlag_IsOriginalBuild = 4 ,
BfHotDepDataFlag_IsBound = 8 ,
BfHotDepDataFlag_HasDup = 0x10 ,
BfHotDepDataFlag_RetainMethodWithoutBinding = 0x20 ,
} ;
class BfHotDepData
{
public :
BfHotDepDataKind mDataKind ;
BfHotDepDataFlags mFlags ;
int32 mRefCount ;
BfHotDepData ( )
{
mDataKind = BfHotDepDataKind_Unknown ;
mFlags = BfHotDepDataFlag_None ;
mRefCount = 0 ;
}
void Deref ( ) ;
# ifdef _DEBUG
virtual ~ BfHotDepData ( )
{
BF_ASSERT ( mRefCount = = 0 ) ;
}
# endif
} ;
struct BfHotTypeDataEntry
{
public :
String mFuncName ; // Name of original virtual function, not overrides
} ;
class BfHotTypeVersion : public BfHotDepData
{
public :
Val128 mDataHash ; // Determines when the user's declaration changed - changes do not cascade into including types
BfHotTypeVersion * mBaseType ;
Array < BfHotTypeVersion * > mMembers ; // Struct members directly included (not via pointers)
int mDeclHotCompileIdx ;
int mCommittedHotCompileIdx ;
int mTypeId ;
Array < int > mInterfaceMapping ;
bool mPopulatedInterfaceMapping ;
BfHotTypeVersion ( )
{
mBaseType = NULL ;
mDataKind = BfHotDepDataKind_TypeVersion ;
mPopulatedInterfaceMapping = 0 ;
}
~ BfHotTypeVersion ( ) ;
} ;
class BfHotThisType : public BfHotDepData
{
public :
BfHotTypeVersion * mTypeVersion ;
BfHotThisType ( BfHotTypeVersion * typeVersion )
{
mDataKind = BfHotDepDataKind_ThisType ;
mTypeVersion = typeVersion ;
mTypeVersion - > mRefCount + + ;
}
~ BfHotThisType ( )
{
mTypeVersion - > Deref ( ) ;
}
} ;
class BfHotAllocation : public BfHotDepData
{
public :
BfHotTypeVersion * mTypeVersion ;
BfHotAllocation ( BfHotTypeVersion * typeVersion )
{
mDataKind = BfHotDepDataKind_Allocation ;
mTypeVersion = typeVersion ;
mTypeVersion - > mRefCount + + ;
}
~ BfHotAllocation ( )
{
mTypeVersion - > Deref ( ) ;
}
} ;
//#define BF_DBG_HOTMETHOD_NAME
//#define BF_DBG_HOTMETHOD_IDX
class BfHotMethod : public BfHotDepData
{
public :
# ifdef BF_DBG_HOTMETHOD_NAME
String mMangledName ;
# endif
# ifdef BF_DBG_HOTMETHOD_IDX
int mMethodIdx ;
# endif
BfHotTypeVersion * mSrcTypeVersion ;
Array < BfHotDepData * > mReferences ;
BfHotMethod * mPrevVersion ;
BfHotMethod ( )
{
# ifdef BF_DBG_HOTMETHOD_IDX
mMethodIdx = - 1 ;
# endif
mDataKind = BfHotDepDataKind_Method ;
mSrcTypeVersion = NULL ;
mPrevVersion = NULL ;
}
void Clear ( bool keepDupMethods = false ) ;
~ BfHotMethod ( ) ;
} ;
class BfHotDupMethod : public BfHotDepData
{
public :
BfHotMethod * mMethod ;
public :
BfHotDupMethod ( BfHotMethod * hotMethod )
{
mDataKind = BfHotDepDataKind_DupMethod ;
mMethod = hotMethod ;
mMethod - > mRefCount + + ;
}
~ BfHotDupMethod ( )
{
mMethod - > Deref ( ) ;
}
} ;
class BfHotDevirtualizedMethod : public BfHotDepData
{
public :
BfHotMethod * mMethod ;
BfHotDevirtualizedMethod ( BfHotMethod * method )
{
mDataKind = BfHotDepDataKind_DevirtualizedMethod ;
mMethod = method ;
mMethod - > mRefCount + + ;
}
~ BfHotDevirtualizedMethod ( )
{
mMethod - > Deref ( ) ;
}
} ;
class BfHotFunctionReference : public BfHotDepData
{
public :
BfHotMethod * mMethod ;
BfHotFunctionReference ( BfHotMethod * method )
{
mDataKind = BfHotDepDataKind_FunctionPtr ;
mMethod = method ;
mMethod - > mRefCount + + ;
}
~ BfHotFunctionReference ( )
{
mMethod - > Deref ( ) ;
}
} ;
class BfHotInnerMethod : public BfHotDepData
{
public :
BfHotMethod * mMethod ;
BfHotInnerMethod ( BfHotMethod * method )
{
mDataKind = BfHotDepDataKind_InnerMethod ;
mMethod = method ;
mMethod - > mRefCount + + ;
}
~ BfHotInnerMethod ( )
{
mMethod - > Deref ( ) ;
}
} ;
class BfHotVirtualDeclaration : public BfHotDepData
{
public :
BfHotMethod * mMethod ;
BfHotVirtualDeclaration ( BfHotMethod * method )
{
mDataKind = BfHotDepDataKind_VirtualDecl ;
mMethod = method ;
mMethod - > mRefCount + + ;
}
~ BfHotVirtualDeclaration ( )
{
mMethod - > Deref ( ) ;
}
} ;
class BfHotDataReferenceBuilder
{
public :
HashSet < BfHotTypeVersion * > mAllocatedData ; // Any usage that depends on size or layout
HashSet < BfHotTypeVersion * > mUsedData ; // Any usage that depends on size or layout
HashSet < BfHotMethod * > mCalledMethods ;
HashSet < BfHotMethod * > mDevirtualizedCalledMethods ;
HashSet < BfHotMethod * > mFunctionPtrs ;
HashSet < BfHotMethod * > mInnerMethods ;
} ;
class BfDependedType ;
class BfTypeInstance ;
class BfPrimitiveType ;
enum BfTypeRebuildFlags
{
BfTypeRebuildFlag_None = 0 ,
BfTypeRebuildFlag_StaticChange = 1 ,
BfTypeRebuildFlag_NonStaticChange = 2 ,
BfTypeRebuildFlag_MethodInlineInternalsChange = 4 ,
BfTypeRebuildFlag_MethodSignatureChange = 8 ,
2020-12-31 11:31:19 -08:00
BfTypeRebuildFlag_ConstEvalChange = 0x10 ,
2021-01-02 15:46:29 -08:00
BfTypeRebuildFlag_ConstEvalFieldChange = 0x20 ,
BfTypeRebuildFlag_DeleteQueued = 0x40 ,
BfTypeRebuildFlag_Deleted = 0x80 ,
BfTypeRebuildFlag_AddedToWorkList = 0x100 ,
BfTypeRebuildFlag_AwaitingReference = 0x200 ,
BfTypeRebuildFlag_SpecializedMethodRebuild = 0x400 , // Temporarily set
BfTypeRebuildFlag_SpecializedByAutocompleteMethod = 0x800 ,
BfTypeRebuildFlag_UnderlyingTypeDeferred = 0x1000 ,
BfTypeRebuildFlag_TypeDataSaved = 0x2000 ,
BfTypeRebuildFlag_InTempPool = 0x4000 ,
2021-01-08 16:21:03 -08:00
BfTypeRebuildFlag_ResolvingBase = 0x8000 ,
BfTypeRebuildFlag_InFailTypes = 0x10000 ,
BfTypeRebuildFlag_RebuildQueued = 0x20000 ,
2022-02-16 18:28:23 -05:00
BfTypeRebuildFlag_ConstEvalCancelled = 0x40000 ,
BfTypeRebuildFlag_ChangedMidCompile = 0x80000 ,
2022-06-02 07:06:31 -07:00
BfTypeRebuildFlag_PendingGenericArgDep = 0x100000
2019-08-23 11:56:54 -07:00
} ;
class BfTypeDIReplaceCallback ;
enum BfTypeDefineState : uint8
{
BfTypeDefineState_Undefined ,
2021-10-23 08:46:17 -07:00
BfTypeDefineState_Declaring ,
2019-08-23 11:56:54 -07:00
BfTypeDefineState_Declared ,
2021-01-08 16:21:03 -08:00
BfTypeDefineState_ResolvingBaseType ,
2022-05-13 09:43:26 -07:00
BfTypeDefineState_HasInterfaces_Direct ,
2021-01-08 16:21:03 -08:00
BfTypeDefineState_CETypeInit ,
BfTypeDefineState_CEPostTypeInit ,
2022-05-13 09:43:26 -07:00
BfTypeDefineState_HasInterfaces_All ,
2019-08-23 11:56:54 -07:00
BfTypeDefineState_Defined ,
2021-01-08 16:21:03 -08:00
BfTypeDefineState_CEAfterFields ,
2021-08-02 10:44:39 -07:00
BfTypeDefineState_DefinedAndMethodsSlotting ,
2019-08-23 11:56:54 -07:00
BfTypeDefineState_DefinedAndMethodsSlotted ,
} ;
2020-05-23 17:25:47 -07:00
class BfDelegateInfo
{
public :
Array < BfAstNode * > mDirectAllocNodes ;
2020-09-11 10:33:16 -07:00
BfType * mReturnType ;
2020-09-10 10:42:32 -07:00
Array < BfType * > mParams ;
2020-09-11 10:33:16 -07:00
bool mHasExplicitThis ;
2021-02-02 07:08:55 -08:00
bool mHasVarArgs ;
2021-12-27 12:55:14 -05:00
BfCallingConvention mCallingConvention ;
2020-05-23 17:25:47 -07:00
public :
BfDelegateInfo ( )
{
mReturnType = NULL ;
2020-09-11 10:33:16 -07:00
mHasExplicitThis = false ;
2021-02-02 07:08:55 -08:00
mHasVarArgs = false ;
2021-12-27 12:55:14 -05:00
mCallingConvention = BfCallingConvention_Unspecified ;
2020-05-23 17:25:47 -07:00
}
~ BfDelegateInfo ( )
{
for ( auto directAllocNode : mDirectAllocNodes )
delete directAllocNode ;
}
} ;
2020-06-10 07:12:07 -07:00
enum BfTypeUsage
{
BfTypeUsage_Unspecified ,
BfTypeUsage_Return_Static ,
BfTypeUsage_Return_NonStatic ,
BfTypeUsage_Parameter ,
} ;
2019-08-23 11:56:54 -07:00
class BfType
{
public :
BfTypeRebuildFlags mRebuildFlags ;
BfContext * mContext ;
int mTypeId ;
2022-02-16 18:28:23 -05:00
int mRevision ;
2019-08-23 11:56:54 -07:00
// For Objects, align and size is ref-sized (object*).
// Use mInstSize/mInstAlign for actual data size/align
int mSize ;
int16 mAlign ;
bool mDirty ;
BfTypeDefineState mDefineState ;
public :
BfType ( ) ;
virtual ~ BfType ( ) ;
BfTypeInstance * FindUnderlyingTypeInstance ( ) ;
virtual BfModule * GetModule ( ) ;
2020-02-28 09:20:43 -08:00
2019-08-23 11:56:54 -07:00
int GetStride ( ) { return BF_ALIGN ( mSize , mAlign ) ; }
2022-02-15 10:27:04 -05:00
bool IsSizeAligned ( ) { return ( mSize = = 0 ) | | ( mSize % mAlign = = 0 ) ; }
2020-02-28 09:20:43 -08:00
virtual bool IsInstanceOf ( BfTypeDef * typeDef ) { return false ; }
2019-08-23 11:56:54 -07:00
virtual bool HasBeenReferenced ( ) { return mDefineState ! = BfTypeDefineState_Undefined ; }
virtual bool HasTypeFailed ( ) { return false ; }
virtual bool IsDataIncomplete ( ) { return mDefineState = = BfTypeDefineState_Undefined ; }
2021-02-25 10:14:22 -08:00
virtual bool IsFinishingType ( ) { return false ; }
2019-08-23 11:56:54 -07:00
virtual bool IsIncomplete ( ) { return mDefineState < BfTypeDefineState_Defined ; }
virtual bool IsDeleting ( ) { return ( ( mRebuildFlags & ( BfTypeRebuildFlag_Deleted | BfTypeRebuildFlag_DeleteQueued ) ) ! = 0 ) ; }
virtual bool IsDeclared ( ) { return mDefineState > = BfTypeDefineState_Declared ; }
virtual BfDependedType * ToDependedType ( ) { return NULL ; }
virtual BfTypeInstance * ToTypeInstance ( ) { return NULL ; }
2020-06-05 07:01:58 -07:00
virtual BfTypeInstance * ToGenericTypeInstance ( ) { return NULL ; }
2019-08-23 11:56:54 -07:00
virtual BfPrimitiveType * ToPrimitiveType ( ) { return NULL ; }
virtual bool IsDependendType ( ) { return false ; }
2022-02-08 10:33:20 -05:00
virtual int GetGenericDepth ( ) { return 0 ; }
2019-08-23 11:56:54 -07:00
virtual bool IsTypeInstance ( ) { return false ; }
virtual bool IsGenericTypeInstance ( ) { return false ; }
virtual bool IsUnspecializedType ( ) { return false ; }
virtual bool IsReified ( ) { return true ; }
virtual bool IsSpecializedType ( ) { return false ; }
virtual bool IsSpecializedByAutoCompleteMethod ( ) { return false ; }
virtual bool IsUnspecializedTypeVariation ( ) { return false ; }
virtual bool IsSplattable ( ) { return false ; }
virtual int GetSplatCount ( ) { return 1 ; }
virtual bool IsVoid ( ) { return false ; }
virtual bool IsVoidPtr ( ) { return false ; }
virtual bool CanBeValuelessType ( ) { return false ; }
2020-04-20 14:54:27 -07:00
virtual bool IsValuelessType ( ) { BF_ASSERT ( mSize ! = - 1 ) ; BF_ASSERT ( mDefineState > = BfTypeDefineState_Defined ) ; return mSize = = 0 ; }
2019-08-23 11:56:54 -07:00
virtual bool IsSelf ( ) { return false ; }
virtual bool IsDot ( ) { return false ; }
2020-07-20 07:17:33 -07:00
virtual bool IsVar ( ) { return false ; }
2019-08-23 11:56:54 -07:00
virtual bool IsLet ( ) { return false ; }
virtual bool IsNull ( ) { return false ; }
virtual bool IsNullable ( ) { return false ; }
virtual bool IsBoxed ( ) { return false ; }
virtual bool IsInterface ( ) { return false ; }
virtual bool IsEnum ( ) { return false ; }
virtual bool IsPayloadEnum ( ) { return false ; }
virtual bool IsTypedPrimitive ( ) { return false ; }
virtual bool IsComposite ( ) { return IsStruct ( ) ; }
virtual bool IsStruct ( ) { return false ; }
2019-10-09 16:16:01 -07:00
virtual bool IsStructPtr ( ) { return false ; }
2019-08-23 11:56:54 -07:00
virtual bool IsUnion ( ) { return false ; }
virtual bool IsStructOrStructPtr ( ) { return false ; }
virtual bool IsObject ( ) { return false ; }
virtual bool IsObjectOrStruct ( ) { return false ; }
virtual bool IsObjectOrInterface ( ) { return false ; }
virtual bool IsString ( ) { return false ; }
virtual bool IsSizedArray ( ) { return false ; }
2020-12-22 04:50:37 -08:00
virtual bool IsUndefSizedArray ( ) { return false ; }
2020-12-24 10:29:09 -08:00
virtual bool IsUnknownSizedArrayType ( ) { return false ; }
2020-01-23 12:02:54 -08:00
virtual bool IsArray ( ) { return false ; }
2019-08-23 11:56:54 -07:00
virtual bool IsDelegate ( ) { return false ; }
virtual bool IsFunction ( ) { return false ; }
2021-01-19 13:52:36 -08:00
virtual bool IsDelegateOrFunction ( ) { return false ; }
2019-08-23 11:56:54 -07:00
virtual bool IsDelegateFromTypeRef ( ) { return false ; }
virtual bool IsFunctionFromTypeRef ( ) { return false ; }
2020-05-23 17:25:47 -07:00
virtual BfDelegateInfo * GetDelegateInfo ( ) { return NULL ; }
2019-08-23 11:56:54 -07:00
virtual bool IsValueType ( ) { return false ; }
2021-02-24 06:02:17 -08:00
virtual bool IsOpaque ( ) { return false ; }
2019-08-23 11:56:54 -07:00
virtual bool IsValueTypeOrValueTypePtr ( ) { return false ; }
virtual bool IsWrappableType ( ) { return false ; }
virtual bool IsPrimitiveType ( ) { return false ; }
2021-12-31 07:56:57 -05:00
virtual BfTypeCode GetTypeCode ( ) { return BfTypeCode_None ; }
2019-08-23 11:56:54 -07:00
virtual bool IsBoolean ( ) { return false ; }
virtual bool IsInteger ( ) { return false ; }
virtual bool IsIntegral ( ) { return false ; }
2021-12-28 09:44:25 -05:00
virtual bool IsIntegralOrBool ( ) { return false ; }
2019-08-23 11:56:54 -07:00
virtual bool IsIntPtr ( ) { return false ; }
virtual bool IsSigned ( ) { return false ; }
virtual bool IsSignedInt ( ) { return false ; }
virtual bool IsIntUnknown ( ) { return false ; }
virtual bool IsChar ( ) { return false ; }
virtual bool IsFloat ( ) { return false ; }
virtual bool IsPointer ( ) { return false ; }
2020-08-12 15:07:56 -07:00
virtual bool IsAllocType ( ) { return false ; }
2019-08-23 11:56:54 -07:00
virtual bool IsIntPtrable ( ) { return false ; }
2020-05-01 09:11:13 -07:00
virtual bool IsRef ( ) { return false ; }
2021-01-26 11:06:17 -08:00
virtual bool IsMut ( ) { return false ; }
2021-01-27 09:01:47 -08:00
virtual bool IsIn ( ) { return false ; }
2021-01-26 11:06:17 -08:00
virtual bool IsOut ( ) { return false ; }
2019-08-23 11:56:54 -07:00
virtual bool IsGenericParam ( ) { return false ; }
2022-01-01 06:36:48 -05:00
virtual bool IsTypeGenericParam ( ) { return false ; }
virtual bool IsMethodGenericParam ( ) { return false ; }
2019-08-23 11:56:54 -07:00
virtual bool IsClosure ( ) { return false ; }
virtual bool IsMethodRef ( ) { return false ; }
virtual bool IsTuple ( ) { return false ; }
virtual bool IsOnDemand ( ) { return false ; }
virtual bool IsTemporary ( ) { return false ; }
2020-04-27 15:09:10 -07:00
virtual bool IsModifiedTypeType ( ) { return false ; }
2019-08-23 11:56:54 -07:00
virtual bool IsConcreteInterfaceType ( ) { return false ; }
virtual bool IsTypeAlias ( ) { return false ; }
virtual bool HasPackingHoles ( ) { return false ; }
virtual bool IsConstExprValue ( ) { return false ; }
virtual bool IsDependentOnUnderlyingType ( ) { return false ; }
virtual bool WantsGCMarking ( ) { return false ; }
2020-06-10 07:12:07 -07:00
virtual bool GetLoweredType ( BfTypeUsage typeUsage , BfTypeCode * outTypeCode = NULL , BfTypeCode * outTypeCode2 = NULL ) { return false ; }
2019-08-23 11:56:54 -07:00
virtual BfType * GetUnderlyingType ( ) { return NULL ; }
2019-10-09 16:16:01 -07:00
virtual bool HasWrappedRepresentation ( ) { return IsWrappableType ( ) ; }
2019-08-23 11:56:54 -07:00
virtual bool IsTypeMemberIncluded ( BfTypeDef * declaringTypeDef , BfTypeDef * activeTypeDef = NULL , BfModule * module = NULL ) { return true ; } // May be 'false' only for generic extensions with constraints
virtual bool IsTypeMemberAccessible ( BfTypeDef * declaringTypeDef , BfTypeDef * activeTypeDef ) { return true ; }
2020-07-01 12:06:28 -07:00
virtual bool IsTypeMemberAccessible ( BfTypeDef * declaringTypeDef , BfProject * curProject ) { return true ; }
virtual bool IsTypeMemberAccessible ( BfTypeDef * declaringTypeDef , BfProjectSet * visibleProjectSet ) { return true ; }
2019-08-23 11:56:54 -07:00
virtual void ReportMemory ( MemReporter * memReporter ) ;
} ;
2022-02-08 10:33:20 -05:00
class BfElementedType : public BfType
{
public :
int mGenericDepth ;
public :
BfElementedType ( )
{
mGenericDepth = 0 ;
}
virtual int GetGenericDepth ( ) override { return mGenericDepth ; }
} ;
2019-08-23 11:56:54 -07:00
// This is explicitly used for generics
typedef SizedArray < BfType * , 2 > BfTypeVector ;
typedef SizedArray < BfTypeReference * , 2 > BfTypeRefVector ;
class BfPrimitiveType : public BfType
{
public :
BfTypeDef * mTypeDef ;
public :
virtual bool IsPrimitiveType ( ) override { return true ; }
2021-12-31 07:56:57 -05:00
virtual BfTypeCode GetTypeCode ( ) override { return mTypeDef - > mTypeCode ; }
2022-01-11 11:25:52 -05:00
virtual bool IsWrappableType ( ) override { return ( ( mTypeDef - > mTypeCode > = BfTypeCode_Boolean ) & & ( mTypeDef - > mTypeCode < = BfTypeCode_Double ) ) | | ( mTypeDef - > mTypeCode = = BfTypeCode_None ) ; }
2019-08-23 11:56:54 -07:00
virtual BfPrimitiveType * ToPrimitiveType ( ) override { return this ; }
//virtual bool IsValueType() override { return mTypeDef->mTypeCode != BfTypeCode_None; }
//virtual bool IsValueTypeOrValueTypePtr() override { return mTypeDef->mTypeCode != BfTypeCode_None; }
virtual bool IsValueType ( ) override { return true ; }
virtual bool IsValueTypeOrValueTypePtr ( ) override { return true ; }
virtual bool IsBoolean ( ) override { return mTypeDef - > mTypeCode = = BfTypeCode_Boolean ; }
virtual bool IsIntegral ( ) override { return ( mTypeDef - > mTypeCode > = BfTypeCode_Int8 ) & & ( mTypeDef - > mTypeCode < = BfTypeCode_Char32 ) ; }
2021-12-28 09:44:25 -05:00
virtual bool IsIntegralOrBool ( ) override { return ( mTypeDef - > mTypeCode > = BfTypeCode_Boolean ) & & ( mTypeDef - > mTypeCode < = BfTypeCode_Char32 ) ; }
2019-08-23 11:56:54 -07:00
virtual bool IsInteger ( ) override { return ( mTypeDef - > mTypeCode > = BfTypeCode_Int8 ) & & ( mTypeDef - > mTypeCode < = BfTypeCode_UIntUnknown ) ; }
virtual bool IsIntPtr ( ) override { return ( mTypeDef - > mTypeCode = = BfTypeCode_IntPtr ) | | ( mTypeDef - > mTypeCode = = BfTypeCode_UIntPtr ) ; }
virtual bool IsIntPtrable ( ) override
{
return ( mTypeDef - > mTypeCode = = BfTypeCode_IntPtr ) | | ( mTypeDef - > mTypeCode = = BfTypeCode_UIntPtr ) | |
( ( mTypeDef - > mSystem - > mPtrSize = = 8 ) & & ( ( mTypeDef - > mTypeCode = = BfTypeCode_Int64 ) | | ( mTypeDef - > mTypeCode = = BfTypeCode_UInt64 ) ) ) | |
( ( mTypeDef - > mSystem - > mPtrSize = = 4 ) & & ( ( mTypeDef - > mTypeCode = = BfTypeCode_Int32 ) | | ( mTypeDef - > mTypeCode = = BfTypeCode_UInt32 ) ) ) ;
}
virtual bool IsSigned ( ) override { return ( mTypeDef - > mTypeCode = = BfTypeCode_Int8 ) | | ( mTypeDef - > mTypeCode = = BfTypeCode_Int16 ) | |
( mTypeDef - > mTypeCode = = BfTypeCode_Int32 ) | | ( mTypeDef - > mTypeCode = = BfTypeCode_Int64 ) | | ( mTypeDef - > mTypeCode = = BfTypeCode_IntPtr ) | |
( mTypeDef - > mTypeCode = = BfTypeCode_IntUnknown ) | |
2020-07-03 13:54:45 -07:00
( mTypeDef - > mTypeCode = = BfTypeCode_Float ) | | ( mTypeDef - > mTypeCode = = BfTypeCode_Double ) ; }
2019-08-23 11:56:54 -07:00
virtual bool IsSignedInt ( ) override { return ( mTypeDef - > mTypeCode = = BfTypeCode_Int8 ) | | ( mTypeDef - > mTypeCode = = BfTypeCode_Int16 ) | |
( mTypeDef - > mTypeCode = = BfTypeCode_Int32 ) | | ( mTypeDef - > mTypeCode = = BfTypeCode_Int64 ) | | ( mTypeDef - > mTypeCode = = BfTypeCode_IntPtr ) | |
( mTypeDef - > mTypeCode = = BfTypeCode_IntUnknown ) ; }
virtual bool IsIntUnknown ( ) override { return ( mTypeDef - > mTypeCode = = BfTypeCode_IntUnknown ) | | ( mTypeDef - > mTypeCode = = BfTypeCode_UIntUnknown ) ; }
2019-10-14 14:08:29 -07:00
virtual bool IsChar ( ) override { return ( mTypeDef - > mTypeCode = = BfTypeCode_Char8 ) | | ( mTypeDef - > mTypeCode = = BfTypeCode_Char16 ) | | ( mTypeDef - > mTypeCode = = BfTypeCode_Char32 ) ; }
2020-07-03 13:54:45 -07:00
virtual bool IsFloat ( ) override { return ( mTypeDef - > mTypeCode = = BfTypeCode_Float ) | | ( mTypeDef - > mTypeCode = = BfTypeCode_Double ) ; }
2019-08-23 11:56:54 -07:00
virtual bool IsNull ( ) override { return mTypeDef - > mTypeCode = = BfTypeCode_NullPtr ; }
virtual bool IsVoid ( ) override { return mTypeDef - > mTypeCode = = BfTypeCode_None ; }
2019-10-14 14:08:29 -07:00
virtual bool CanBeValuelessType ( ) override { return mTypeDef - > mTypeCode = = BfTypeCode_None ; }
2019-08-23 11:56:54 -07:00
virtual bool IsValuelessType ( ) override { return mTypeDef - > mTypeCode = = BfTypeCode_None ; }
virtual bool IsSelf ( ) override { return mTypeDef - > mTypeCode = = BfTypeCode_Self ; }
virtual bool IsDot ( ) override { return mTypeDef - > mTypeCode = = BfTypeCode_Dot ; }
2020-07-20 07:17:33 -07:00
virtual bool IsVar ( ) override { return mTypeDef - > mTypeCode = = BfTypeCode_Var ; }
2019-08-23 11:56:54 -07:00
virtual bool IsLet ( ) override { return mTypeDef - > mTypeCode = = BfTypeCode_Let ; }
2022-01-08 09:28:48 -05:00
virtual bool IsUnspecializedType ( ) override { return mTypeDef - > mTypeCode = = BfTypeCode_Self ; }
virtual bool IsUnspecializedTypeVariation ( ) override { return mTypeDef - > mTypeCode = = BfTypeCode_Self ; }
2019-08-23 11:56:54 -07:00
} ;
class BfTypeInstance ;
class BfMethodInstanceGroup ;
class BfGenericParamInstance ;
class BfGenericMethodParamInstance ;
class BfDeferredMethodCallData
{
public :
// void* mPrev, int mMethodId, <method params>
BfIRType mDeferType ;
BfIRType mDeferTypePtr ;
BfIRMDNode mDeferDIType ;
int mAlign ;
int mSize ;
int64 mMethodId ; // Usually matches methodInstance mIdHash unless there's a collision
public :
BfDeferredMethodCallData ( )
2020-09-14 06:54:49 -07:00
{
2019-08-23 11:56:54 -07:00
mAlign = 0 ;
mSize = 0 ;
mMethodId = 0 ;
}
2019-12-11 12:55:50 -08:00
static int64 GenerateMethodId ( BfModule * module , int64 methodId ) ;
2019-08-23 11:56:54 -07:00
} ;
class BfMethodCustomAttributes
{
public :
BfCustomAttributes * mCustomAttributes ;
BfCustomAttributes * mReturnCustomAttributes ;
Array < BfCustomAttributes * > mParamCustomAttributes ;
public :
BfMethodCustomAttributes ( )
{
mCustomAttributes = NULL ;
mReturnCustomAttributes = NULL ;
}
~ BfMethodCustomAttributes ( ) ;
} ;
class BfMethodParam
{
public :
BfType * mResolvedType ;
int16 mParamDefIdx ;
int16 mDelegateParamIdx ;
bool mDelegateParamNameCombine ; // 'false' means to directly use param name (if we can), otherwise name as <baseParamName>__<delegateParamName>
bool mWasGenericParam ;
bool mIsSplat ;
bool mReferencedInConstPass ;
public :
BfMethodParam ( )
{
mResolvedType = NULL ;
mParamDefIdx = - 1 ;
mDelegateParamIdx = - 1 ;
mDelegateParamNameCombine = false ;
mWasGenericParam = false ;
mIsSplat = false ;
mReferencedInConstPass = false ;
}
BfMethodInstance * GetDelegateParamInvoke ( ) ;
} ;
enum BfMethodOnDemandKind : int8
{
BfMethodOnDemandKind_NotSet ,
BfMethodOnDemandKind_AlwaysInclude ,
BfMethodOnDemandKind_NoDecl_AwaitingReference , // Won't be declared until we reference
BfMethodOnDemandKind_Decl_AwaitingReference , // Will be declared immediately but not processed until referenced
BfMethodOnDemandKind_Decl_AwaitingDecl , // Temporary state before we switch to BfMethodOnDemandKind_Decl_AwaitingReference
BfMethodOnDemandKind_InWorkList ,
BfMethodOnDemandKind_Referenced
} ;
enum BfMethodChainType : int8
{
BfMethodChainType_None ,
BfMethodChainType_ChainHead ,
BfMethodChainType_ChainMember ,
BfMethodChainType_ChainSkip ,
} ;
class BfMethodProcessRequest ;
class BfLocalMethod ;
class BfClosureState ;
struct BfClosureCapturedEntry
{
BfType * mType ;
String mName ;
BfIdentifierNode * mNameNode ;
bool mExplicitlyByReference ;
2020-09-01 15:57:08 -07:00
int mShadowIdx ; // Only relative to matching nameNodes
2019-08-23 11:56:54 -07:00
BfClosureCapturedEntry ( )
{
mNameNode = NULL ;
mType = NULL ;
mExplicitlyByReference = false ;
2020-09-01 15:57:08 -07:00
mShadowIdx = 0 ;
2019-08-23 11:56:54 -07:00
}
bool operator < ( const BfClosureCapturedEntry & other ) const
{
if ( mName = = " __this " )
return true ;
else if ( other . mName = = " __this " )
return false ;
return mName < other . mName ;
}
} ;
class BfClosureInstanceInfo
{
public :
BfTypeInstance * mThisOverride ;
BfLocalMethod * mLocalMethod ;
Dictionary < int64 , BfMethodDef * > mLocalMethodBindings ; // We create binding during capture and use it during mDeferredLocalMethods processing
BfClosureState * mCaptureClosureState ;
Array < BfClosureCapturedEntry > mCaptureEntries ;
public :
BfClosureInstanceInfo ( )
{
mThisOverride = NULL ;
mLocalMethod = NULL ;
mCaptureClosureState = NULL ;
}
} ;
class BfMethodInfoEx
{
public :
StringT < 0 > mMangledName ; // Only populated during hot loading for virtual methods
BfTypeInstance * mExplicitInterface ;
BfTypeInstance * mForeignType ;
BfClosureInstanceInfo * mClosureInstanceInfo ;
Array < BfGenericMethodParamInstance * > mGenericParams ;
BfTypeVector mMethodGenericArguments ;
Dictionary < int64 , BfType * > mGenericTypeBindings ;
BfMethodCustomAttributes * mMethodCustomAttributes ;
2020-12-19 14:19:33 -08:00
int mMinDependDepth ;
2019-08-23 11:56:54 -07:00
BfMethodInfoEx ( )
{
mExplicitInterface = NULL ;
mForeignType = NULL ;
mClosureInstanceInfo = NULL ;
mMethodCustomAttributes = NULL ;
2020-12-19 14:19:33 -08:00
mMinDependDepth = - 1 ;
2019-08-23 11:56:54 -07:00
}
2020-12-19 14:19:33 -08:00
~ BfMethodInfoEx ( ) ;
2019-08-23 11:56:54 -07:00
} ;
enum BfImportCallKind
{
BfImportCallKind_None ,
BfImportCallKind_GlobalVar ,
BfImportCallKind_GlobalVar_Hot // We need to check against NULL in this case
} ;
class BfMethodInstance
{
public :
int mVirtualTableIdx ;
BfIRFunction mIRFunction ; // Only valid for owning module
int16 mAppendAllocAlign ;
int16 mEndingAppendAllocAlign ;
bool mIsUnspecialized : 1 ;
bool mIsUnspecializedVariation : 1 ;
bool mIsReified : 1 ;
2022-01-16 07:59:51 -05:00
bool mHasStartedDeclaration : 1 ;
2021-01-18 14:09:16 -08:00
bool mHasBeenDeclared : 1 ;
bool mHasBeenProcessed : 1 ;
2019-08-23 11:56:54 -07:00
bool mHasFailed : 1 ;
2021-12-30 11:27:17 -05:00
bool mHasWarning : 1 ;
2019-08-23 11:56:54 -07:00
bool mFailedConstraints : 1 ;
bool mMangleWithIdx : 1 ;
bool mHadGenericDelegateParams : 1 ;
bool mIgnoreBody : 1 ;
bool mIsAutocompleteMethod : 1 ;
2020-07-21 13:14:09 -07:00
bool mRequestedByAutocomplete : 1 ;
2019-08-23 11:56:54 -07:00
bool mIsClosure : 1 ;
bool mMayBeConst : 1 ; // Only used for calcAppend currently
bool mIsForeignMethodDef : 1 ;
bool mAlwaysInline : 1 ;
bool mIsIntrinsic : 1 ;
bool mHasMethodRefType : 1 ;
2020-07-20 07:17:33 -07:00
bool mDisallowCalling : 1 ;
2020-10-23 11:48:37 -07:00
bool mIsInnerOverride : 1 ;
2020-12-13 08:04:42 -08:00
bool mInCEMachine : 1 ;
2021-02-01 05:21:41 -08:00
bool mCeCancelled : 1 ;
2020-12-29 12:41:43 -08:00
bool mIsDisposed : 1 ;
2019-08-23 11:56:54 -07:00
BfMethodChainType mChainType ;
2021-01-08 16:21:03 -08:00
BfComptimeFlags mComptimeFlags ;
2020-05-04 07:15:38 -07:00
BfCallingConvention mCallingConvention ;
2019-08-23 11:56:54 -07:00
BfMethodInstanceGroup * mMethodInstanceGroup ;
BfMethodDef * mMethodDef ;
BfType * mReturnType ;
Array < BfMethodParam > mParams ;
2020-05-07 13:19:02 -07:00
Array < BfTypedValue > mDefaultValues ;
2019-08-23 11:56:54 -07:00
BfModule * mDeclModule ;
BfMethodProcessRequest * mMethodProcessRequest ;
BfMethodInfoEx * mMethodInfoEx ;
int64 mIdHash ; // Collisions are (essentially) benign
BfHotMethod * mHotMethod ;
public :
BfMethodInstance ( )
{
mVirtualTableIdx = - 1 ;
mIsUnspecialized = false ;
mIsUnspecializedVariation = false ;
mIsReified = true ;
2022-01-16 07:59:51 -05:00
mHasStartedDeclaration = false ;
2021-01-18 14:09:16 -08:00
mHasBeenDeclared = false ;
2019-08-23 11:56:54 -07:00
mHasBeenProcessed = false ;
mHasFailed = false ;
2021-12-30 11:27:17 -05:00
mHasWarning = false ;
2019-08-23 11:56:54 -07:00
mFailedConstraints = false ;
mMangleWithIdx = false ;
mHadGenericDelegateParams = false ;
mIgnoreBody = false ;
mIsAutocompleteMethod = false ;
2020-07-21 13:14:09 -07:00
mRequestedByAutocomplete = false ;
2019-08-23 11:56:54 -07:00
mIsClosure = false ;
mMayBeConst = true ;
mIsForeignMethodDef = false ;
mAlwaysInline = false ;
mIsIntrinsic = false ;
mHasMethodRefType = false ;
2020-10-23 11:48:37 -07:00
mDisallowCalling = false ;
mIsInnerOverride = false ;
2020-12-13 08:04:42 -08:00
mInCEMachine = false ;
2021-02-01 05:21:41 -08:00
mCeCancelled = false ;
2020-12-29 12:41:43 -08:00
mIsDisposed = false ;
2019-08-23 11:56:54 -07:00
mChainType = BfMethodChainType_None ;
2021-01-08 16:21:03 -08:00
mComptimeFlags = BfComptimeFlag_None ;
2020-05-04 07:15:38 -07:00
mCallingConvention = BfCallingConvention_Unspecified ;
2019-08-23 11:56:54 -07:00
mMethodInstanceGroup = NULL ;
mMethodDef = NULL ;
mReturnType = NULL ;
mIdHash = 0 ;
mAppendAllocAlign = - 1 ;
mEndingAppendAllocAlign = - 1 ;
mDeclModule = NULL ;
mMethodProcessRequest = NULL ;
mMethodInfoEx = NULL ;
mHotMethod = NULL ;
}
~ BfMethodInstance ( ) ;
2020-12-29 12:41:43 -08:00
void Dispose ( bool isDeleting = false ) ;
2019-08-23 11:56:54 -07:00
2020-12-19 14:19:33 -08:00
void CopyFrom ( BfMethodInstance * methodInstance ) ;
2019-08-23 11:56:54 -07:00
bool IsMixin ( )
{
return mMethodDef - > mMethodType = = BfMethodType_Mixin ;
}
2019-12-21 05:44:01 -08:00
BfImportKind GetImportKind ( ) ;
2021-01-13 05:09:09 -08:00
BfMethodFlags GetMethodFlags ( ) ;
2019-08-23 11:56:54 -07:00
void UndoDeclaration ( bool keepIRFunction = false ) ;
BfTypeInstance * GetOwner ( ) ;
BfModule * GetModule ( ) ;
bool IsSpecializedGenericMethod ( ) ;
bool IsSpecializedGenericMethodOrType ( ) ;
bool IsSpecializedByAutoCompleteMethod ( ) ;
2020-09-19 05:12:15 -07:00
bool IsOrInUnspecializedVariation ( ) ;
2020-08-10 17:02:48 -07:00
bool HasExternConstraints ( ) ;
2019-12-21 05:44:01 -08:00
bool HasThis ( ) ;
2020-10-23 11:48:37 -07:00
bool IsVirtual ( ) ;
2020-09-11 10:33:16 -07:00
BfType * GetThisType ( ) ;
int GetThisIdx ( ) ;
2020-07-10 06:40:24 -07:00
bool HasExplicitThis ( ) ;
2019-08-23 11:56:54 -07:00
bool HasParamsArray ( ) ;
2020-09-01 15:57:08 -07:00
int GetStructRetIdx ( bool forceStatic = false ) ;
2019-08-23 11:56:54 -07:00
bool HasSelf ( ) ;
2021-07-12 07:55:36 -07:00
bool GetLoweredReturnType ( BfTypeCode * loweredTypeCode = NULL , BfTypeCode * loweredTypeCode2 = NULL , bool forceStatic = false ) ;
2021-09-16 07:56:55 -07:00
bool WantsStructsAttribByVal ( BfType * paramType ) ;
2019-08-23 11:56:54 -07:00
bool IsAutocompleteMethod ( ) { /*return mIdHash == -1;*/ return mIsAutocompleteMethod ; }
bool IsSkipCall ( bool bypassVirtual = false ) ;
2020-02-11 07:34:47 -08:00
bool IsVarArgs ( ) ;
2019-08-23 11:56:54 -07:00
bool AlwaysInline ( ) ;
BfImportCallKind GetImportCallKind ( ) ;
bool IsTestMethod ( ) ;
2020-12-26 10:16:51 -08:00
bool AllowsSplatting ( int paramIdx ) ;
2019-08-23 11:56:54 -07:00
int GetParamCount ( ) ;
2020-05-04 07:15:38 -07:00
int GetImplicitParamCount ( ) ;
2021-11-29 08:38:42 -08:00
void GetParamName ( int paramIdx , StringImpl & name , int & namePrefixCount ) ;
String GetParamName ( int paramIdx ) ;
String GetParamName ( int paramIdx , int & namePrefixCount ) ;
2020-10-08 12:09:04 -07:00
BfType * GetParamType ( int paramIdx , bool returnUnderlyingParamsType = false ) ;
2019-08-23 11:56:54 -07:00
bool GetParamIsSplat ( int paramIdx ) ;
BfParamKind GetParamKind ( int paramIdx ) ;
bool WasGenericParam ( int paramIdx ) ;
bool IsParamSkipped ( int paramIdx ) ; // void/zero-sized
bool IsImplicitCapture ( int paramIdx ) ;
BfExpression * GetParamInitializer ( int paramIdx ) ;
BfTypeReference * GetParamTypeRef ( int paramIdx ) ;
BfIdentifierNode * GetParamNameNode ( int paramIdx ) ;
int DbgGetVirtualMethodNum ( ) ;
void GetIRFunctionInfo ( BfModule * module , BfIRType & returnType , SizedArrayImpl < BfIRType > & paramTypes , bool forceStatic = false ) ;
int GetIRFunctionParamCount ( BfModule * module ) ;
bool IsExactMatch ( BfMethodInstance * other , bool ignoreImplicitParams = false , bool checkThis = false ) ;
2020-12-19 14:19:33 -08:00
bool IsReifiedAndImplemented ( ) ;
2019-08-23 11:56:54 -07:00
BfMethodInfoEx * GetMethodInfoEx ( ) ;
BfCustomAttributes * GetCustomAttributes ( )
{
if ( ( mMethodInfoEx ! = NULL ) & & ( mMethodInfoEx - > mMethodCustomAttributes ! = NULL ) )
return mMethodInfoEx - > mMethodCustomAttributes - > mCustomAttributes ;
return NULL ;
}
int GetNumGenericParams ( )
{
if ( mMethodInfoEx ! = NULL )
return ( int ) mMethodInfoEx - > mGenericParams . size ( ) ;
return 0 ;
}
int GetNumGenericArguments ( )
{
if ( mMethodInfoEx ! = NULL )
return ( int ) mMethodInfoEx - > mMethodGenericArguments . size ( ) ;
return 0 ;
}
BfTypeInstance * GetExplicitInterface ( )
{
if ( mMethodInfoEx ! = NULL )
return mMethodInfoEx - > mExplicitInterface ;
return NULL ;
}
BfTypeInstance * GetForeignType ( )
{
if ( mMethodInfoEx ! = NULL )
return mMethodInfoEx - > mForeignType ;
return NULL ;
}
void ReportMemory ( MemReporter * memReporter ) ;
} ;
2020-09-18 17:00:33 -07:00
class BfOperatorInfo
{
public :
BfMethodDef * mMethodDef ;
BfType * mReturnType ;
BfType * mLHSType ;
BfType * mRHSType ;
BfOperatorInfo ( )
{
mMethodDef = NULL ;
mReturnType = NULL ;
mLHSType = NULL ;
mRHSType = NULL ;
}
} ;
2019-08-23 11:56:54 -07:00
class BfDllImportEntry
{
public :
BfMethodInstance * mMethodInstance ;
BfIRValue mFuncVar ;
//BfIRFunctionType mFuncType;
} ;
class BfModuleMethodInstance
{
public :
BfMethodInstance * mMethodInstance ;
BfIRValue mFunc ;
public :
BfModuleMethodInstance ( )
{
mMethodInstance = NULL ;
}
BfModuleMethodInstance ( BfMethodInstance * methodInstance ) ;
BfModuleMethodInstance ( BfMethodInstance * methodInstance , BfIRValue func ) : mFunc ( func )
{
mMethodInstance = methodInstance ;
}
operator bool ( ) const
{
return mMethodInstance ! = NULL ;
}
} ;
// The way these work is a bit nuanced
// When we use these as keys, we allow collisions between genericParams from different type and
// method instances. That's okay, as the only constraint there is that they generate valid
// generic-pass methods, which will all be the same. Within the SCOPE of a given type and
// method instance, however, we cannot have collision between types (such as a List<T> and List<T2>)
// because that can cause false equalties in the type checker
class BfGenericParamType : public BfType
{
public :
BfGenericParamKind mGenericParamKind ;
int mGenericParamIdx ;
public :
bool IsGenericParam ( ) override { return true ; }
2022-01-01 06:36:48 -05:00
bool IsTypeGenericParam ( ) override { return mGenericParamKind = = BfGenericParamKind_Type ; }
2022-01-21 14:23:48 -05:00
bool IsMethodGenericParam ( ) override { return mGenericParamKind = = BfGenericParamKind_Method ; }
2019-08-23 11:56:54 -07:00
virtual bool IsUnspecializedType ( ) override { return true ; }
virtual bool IsReified ( ) override { return false ; }
} ;
2020-04-27 15:09:10 -07:00
// This just captures rettype(T)/nullable(T) since it can't be resolved directly
class BfModifiedTypeType : public BfType
2019-08-23 11:56:54 -07:00
{
public :
2020-04-27 15:09:10 -07:00
BfToken mModifiedKind ;
2019-08-23 11:56:54 -07:00
BfType * mElementType ;
2020-04-27 15:09:10 -07:00
virtual bool IsModifiedTypeType ( ) override { return true ; }
2019-10-14 14:08:29 -07:00
virtual bool CanBeValuelessType ( ) override { return true ; }
2019-08-23 11:56:54 -07:00
virtual bool IsValuelessType ( ) override { return true ; }
virtual bool IsUnspecializedType ( ) override { return mElementType - > IsUnspecializedType ( ) ; }
2020-08-12 15:07:56 -07:00
virtual bool IsUnspecializedTypeVariation ( ) override { return mElementType - > IsUnspecializedType ( ) ; }
2019-08-23 11:56:54 -07:00
virtual bool IsReified ( ) override { return mElementType - > IsReified ( ) ; }
virtual bool IsDependentOnUnderlyingType ( ) override { return true ; }
2020-08-25 07:33:55 -07:00
virtual bool IsAllocType ( ) override { return mModifiedKind = = BfToken_AllocType ; }
2019-08-23 11:56:54 -07:00
virtual BfType * GetUnderlyingType ( ) override { return mElementType ; }
} ;
2019-11-17 09:28:39 -08:00
class BfGenericOperatorConstraintInstance
{
public :
BfType * mLeftType ;
BfBinaryOp mBinaryOp ;
BfUnaryOp mUnaryOp ;
BfToken mCastToken ;
BfType * mRightType ;
public :
BfGenericOperatorConstraintInstance ( )
{
mLeftType = NULL ;
mBinaryOp = BfBinaryOp_None ;
mUnaryOp = BfUnaryOp_None ;
mCastToken = BfToken_None ;
mRightType = NULL ;
}
bool operator = = ( const BfGenericOperatorConstraintInstance & other ) const
{
return
( mLeftType = = other . mLeftType ) & &
( mBinaryOp = = other . mBinaryOp ) & &
( mUnaryOp = = other . mUnaryOp ) & &
( mCastToken = = other . mCastToken ) & &
( mRightType = = other . mRightType ) ;
}
} ;
2019-08-23 11:56:54 -07:00
class BfGenericParamInstance
{
public :
2021-10-31 08:21:30 -07:00
BfGenericParamFlags mGenericParamFlags ;
2019-11-17 09:28:39 -08:00
BfType * mExternType ;
2019-08-23 11:56:54 -07:00
Array < BfTypeInstance * > mInterfaceConstraints ;
2022-01-17 16:14:40 -05:00
HashSet < BfTypeInstance * > * mInterfaceConstraintSet ;
2019-11-17 09:28:39 -08:00
Array < BfGenericOperatorConstraintInstance > mOperatorConstraints ;
2021-01-15 14:28:21 -08:00
Array < BfTypeReference * > mComptypeConstraint ;
2019-08-23 11:56:54 -07:00
BfType * mTypeConstraint ;
int mRefCount ;
BfGenericParamInstance ( )
{
2019-11-17 09:28:39 -08:00
mExternType = NULL ;
2021-10-31 08:21:30 -07:00
mGenericParamFlags = BfGenericParamFlag_None ;
2019-08-23 11:56:54 -07:00
mTypeConstraint = NULL ;
2022-01-17 16:14:40 -05:00
mInterfaceConstraintSet = NULL ;
2019-08-23 11:56:54 -07:00
mRefCount = 1 ;
}
void Release ( )
{
if ( - - mRefCount = = 0 )
delete this ;
}
virtual ~ BfGenericParamInstance ( )
{
2022-01-17 16:14:40 -05:00
delete mInterfaceConstraintSet ;
2019-08-23 11:56:54 -07:00
}
2019-11-17 09:28:39 -08:00
virtual BfConstraintDef * GetConstraintDef ( ) = 0 ;
2019-08-23 11:56:54 -07:00
virtual BfGenericParamDef * GetGenericParamDef ( ) = 0 ;
2019-11-17 09:28:39 -08:00
virtual BfExternalConstraintDef * GetExternConstraintDef ( ) = 0 ;
2020-05-01 09:11:13 -07:00
virtual String GetName ( ) = 0 ;
2022-04-26 11:56:08 -07:00
virtual BfAstNode * GetRefNode ( ) = 0 ;
2022-01-03 07:30:03 -05:00
bool IsEnum ( ) ;
2019-08-23 11:56:54 -07:00
} ;
class BfGenericTypeParamInstance : public BfGenericParamInstance
{
public :
BfTypeDef * mTypeDef ;
int mGenericIdx ;
2019-11-17 09:28:39 -08:00
2019-08-23 11:56:54 -07:00
public :
BfGenericTypeParamInstance ( BfTypeDef * typeDef , int genericIdx )
{
mTypeDef = typeDef ;
mGenericIdx = genericIdx ;
2019-11-17 09:28:39 -08:00
mGenericParamFlags = GetConstraintDef ( ) - > mGenericParamFlags ;
2019-08-23 11:56:54 -07:00
mTypeConstraint = NULL ;
}
BfGenericTypeParamInstance * AddRef ( )
{
mRefCount + + ;
return this ;
}
2019-11-17 09:28:39 -08:00
virtual BfConstraintDef * GetConstraintDef ( ) override
{
if ( mGenericIdx < ( int ) mTypeDef - > mGenericParamDefs . size ( ) )
return mTypeDef - > mGenericParamDefs [ mGenericIdx ] ;
2020-08-05 05:34:32 -07:00
return & mTypeDef - > mExternalConstraints [ mGenericIdx - ( int ) mTypeDef - > mGenericParamDefs . size ( ) ] ;
2019-11-17 09:28:39 -08:00
}
2019-08-23 11:56:54 -07:00
virtual BfGenericParamDef * GetGenericParamDef ( ) override
{
2019-11-17 09:28:39 -08:00
if ( mGenericIdx < ( int ) mTypeDef - > mGenericParamDefs . size ( ) )
return mTypeDef - > mGenericParamDefs [ mGenericIdx ] ;
return NULL ;
}
virtual BfExternalConstraintDef * GetExternConstraintDef ( ) override
{
if ( mGenericIdx < ( int ) mTypeDef - > mGenericParamDefs . size ( ) )
return NULL ;
2020-08-05 05:34:32 -07:00
return & mTypeDef - > mExternalConstraints [ mGenericIdx - ( int ) mTypeDef - > mGenericParamDefs . size ( ) ] ;
2019-11-17 09:28:39 -08:00
}
virtual String GetName ( ) override
{
if ( mGenericIdx < ( int ) mTypeDef - > mGenericParamDefs . size ( ) )
return mTypeDef - > mGenericParamDefs [ mGenericIdx ] - > mName ;
2020-08-05 05:34:32 -07:00
return mTypeDef - > mExternalConstraints [ mGenericIdx - ( int ) mTypeDef - > mGenericParamDefs . size ( ) ] . mTypeRef - > ToString ( ) ;
2019-08-23 11:56:54 -07:00
}
2022-04-25 17:53:54 -07:00
virtual BfAstNode * GetRefNode ( ) override
{
if ( mGenericIdx < ( int ) mTypeDef - > mGenericParamDefs . size ( ) )
return mTypeDef - > mGenericParamDefs [ mGenericIdx ] - > mNameNodes [ 0 ] ;
return mTypeDef - > mExternalConstraints [ mGenericIdx - ( int ) mTypeDef - > mGenericParamDefs . size ( ) ] . mTypeRef ;
}
2019-08-23 11:56:54 -07:00
} ;
class BfGenericMethodParamInstance : public BfGenericParamInstance
{
public :
BfMethodDef * mMethodDef ;
int mGenericIdx ;
2019-11-17 09:28:39 -08:00
2019-08-23 11:56:54 -07:00
public :
BfGenericMethodParamInstance ( BfMethodDef * methodDef , int genericIdx )
{
mMethodDef = methodDef ;
mGenericIdx = genericIdx ;
2019-11-17 09:28:39 -08:00
mGenericParamFlags = GetConstraintDef ( ) - > mGenericParamFlags ;
2019-08-23 11:56:54 -07:00
mTypeConstraint = NULL ;
}
BfGenericMethodParamInstance * AddRef ( )
{
mRefCount + + ;
return this ;
}
2019-11-17 09:28:39 -08:00
virtual BfConstraintDef * GetConstraintDef ( ) override
{
if ( mGenericIdx < ( int ) mMethodDef - > mGenericParams . size ( ) )
return mMethodDef - > mGenericParams [ mGenericIdx ] ;
return & mMethodDef - > mExternalConstraints [ mGenericIdx - ( int ) mMethodDef - > mGenericParams . size ( ) ] ;
}
2019-08-23 11:56:54 -07:00
virtual BfGenericParamDef * GetGenericParamDef ( ) override
{
2019-11-17 09:28:39 -08:00
if ( mGenericIdx < ( int ) mMethodDef - > mGenericParams . size ( ) )
return mMethodDef - > mGenericParams [ mGenericIdx ] ;
return NULL ;
}
virtual BfExternalConstraintDef * GetExternConstraintDef ( ) override
{
if ( mGenericIdx < ( int ) mMethodDef - > mGenericParams . size ( ) )
return NULL ;
return & mMethodDef - > mExternalConstraints [ mGenericIdx - ( int ) mMethodDef - > mGenericParams . size ( ) ] ;
}
virtual String GetName ( ) override
{
if ( mGenericIdx < ( int ) mMethodDef - > mGenericParams . size ( ) )
return mMethodDef - > mGenericParams [ mGenericIdx ] - > mName ;
return mMethodDef - > mExternalConstraints [ mGenericIdx - ( int ) mMethodDef - > mGenericParams . size ( ) ] . mTypeRef - > ToString ( ) ;
2019-08-23 11:56:54 -07:00
}
2022-04-25 17:53:54 -07:00
virtual BfAstNode * GetRefNode ( ) override
{
if ( mGenericIdx < ( int ) mMethodDef - > mGenericParams . size ( ) )
return mMethodDef - > mGenericParams [ mGenericIdx ] - > mNameNodes [ 0 ] ;
return mMethodDef - > mExternalConstraints [ mGenericIdx - ( int ) mMethodDef - > mGenericParams . size ( ) ] . mTypeRef ;
}
2019-08-23 11:56:54 -07:00
} ;
# define BF_VALCOMP(val) if (val != 0) return val
struct BfTypeVectorHash
{
size_t operator ( ) ( const BfTypeVector & val ) const ;
} ;
struct BfTypeVectorEquals
{
bool operator ( ) ( const BfTypeVector & lhs , const BfTypeVector & rhs ) const ;
} ;
// Specialized for Class<T> but not Method<T>
class BfMethodInstanceGroup
{
public :
BfTypeInstance * mOwner ;
BfMethodInstance * mDefault ;
typedef Dictionary < BfTypeVector , BfMethodInstance * > MapType ;
MapType * mMethodSpecializationMap ;
2022-02-23 17:19:56 -08:00
BfCustomAttributes * mDefaultCustomAttributes ;
2019-08-23 11:56:54 -07:00
int mMethodIdx ;
int mRefCount ; // External references from BfMethodRefType
BfMethodOnDemandKind mOnDemandKind ;
2020-09-14 11:18:24 -07:00
bool mExplicitlyReflected ;
2021-01-18 14:09:16 -08:00
bool mHasEmittedReference ;
2019-08-23 11:56:54 -07:00
public :
BfMethodInstanceGroup ( )
{
mOwner = NULL ;
mDefault = NULL ;
mMethodSpecializationMap = NULL ;
2022-02-23 17:19:56 -08:00
mDefaultCustomAttributes = NULL ;
2019-08-23 11:56:54 -07:00
mMethodIdx = - 1 ;
mOnDemandKind = BfMethodOnDemandKind_NotSet ;
mRefCount = 0 ;
2020-09-14 11:18:24 -07:00
mExplicitlyReflected = false ;
2021-01-18 14:09:16 -08:00
mHasEmittedReference = false ;
2019-08-23 11:56:54 -07:00
}
2022-02-23 17:19:56 -08:00
BfMethodInstanceGroup ( BfMethodInstanceGroup & & prev ) noexcept ;
~ BfMethodInstanceGroup ( ) ;
2019-08-23 11:56:54 -07:00
bool IsImplemented ( )
{
return ( mOnDemandKind = = BfMethodOnDemandKind_AlwaysInclude ) | |
( mOnDemandKind = = BfMethodOnDemandKind_Referenced ) | |
( mOnDemandKind = = BfMethodOnDemandKind_InWorkList ) ;
}
} ;
class BfFieldInstance
{
public :
BfTypeInstance * mOwner ;
BfType * mResolvedType ;
BfCustomAttributes * mCustomAttributes ;
int mConstIdx ;
int mFieldIdx ;
int mDataIdx ; // mFieldIdx includes statics & consts, mDataIdx does not
int mMergedDataIdx ; // Like mDataIdx but contains base class's data
int mDataOffset ;
int mDataSize ;
bool mFieldIncluded ;
bool mIsEnumPayloadCase ;
bool mIsThreadLocal ;
2021-01-02 15:46:29 -08:00
bool mIsInferredType ;
bool mHadConstEval ;
2019-08-23 11:56:54 -07:00
int mLastRevisionReferenced ;
public :
BfFieldDef * GetFieldDef ( ) ;
2022-02-11 05:47:32 -05:00
BfFieldInstance ( BfFieldInstance & & copyFrom )
2019-08-23 11:56:54 -07:00
{
2022-02-11 05:47:32 -05:00
mCustomAttributes = copyFrom . mCustomAttributes ;
copyFrom . mCustomAttributes = NULL ;
2019-08-23 11:56:54 -07:00
mOwner = copyFrom . mOwner ;
mResolvedType = copyFrom . mResolvedType ;
mCustomAttributes = copyFrom . mCustomAttributes ;
mConstIdx = copyFrom . mConstIdx ;
mFieldIdx = copyFrom . mFieldIdx ;
mDataIdx = copyFrom . mDataIdx ;
mMergedDataIdx = copyFrom . mMergedDataIdx ;
mDataOffset = copyFrom . mDataOffset ;
mDataSize = copyFrom . mDataSize ;
mFieldIncluded = copyFrom . mFieldIncluded ;
mIsEnumPayloadCase = copyFrom . mIsEnumPayloadCase ;
mIsThreadLocal = copyFrom . mIsThreadLocal ;
2020-12-19 14:19:33 -08:00
mIsInferredType = copyFrom . mIsInferredType ;
2021-01-02 15:46:29 -08:00
mHadConstEval = copyFrom . mHadConstEval ;
2019-10-04 10:38:36 -07:00
mLastRevisionReferenced = copyFrom . mLastRevisionReferenced ;
2019-08-23 11:56:54 -07:00
}
2022-02-11 05:47:32 -05:00
BfFieldInstance ( const BfFieldInstance & copyFrom )
{
BF_ASSERT ( copyFrom . mCustomAttributes = = NULL ) ;
mOwner = copyFrom . mOwner ;
mResolvedType = copyFrom . mResolvedType ;
mCustomAttributes = copyFrom . mCustomAttributes ;
mConstIdx = copyFrom . mConstIdx ;
mFieldIdx = copyFrom . mFieldIdx ;
mDataIdx = copyFrom . mDataIdx ;
mMergedDataIdx = copyFrom . mMergedDataIdx ;
mDataOffset = copyFrom . mDataOffset ;
mDataSize = copyFrom . mDataSize ;
mFieldIncluded = copyFrom . mFieldIncluded ;
mIsEnumPayloadCase = copyFrom . mIsEnumPayloadCase ;
mIsThreadLocal = copyFrom . mIsThreadLocal ;
mIsInferredType = copyFrom . mIsInferredType ;
mHadConstEval = copyFrom . mHadConstEval ;
mLastRevisionReferenced = copyFrom . mLastRevisionReferenced ;
}
2019-08-23 11:56:54 -07:00
BfFieldInstance ( )
{
mFieldIdx = - 1 ;
mOwner = NULL ;
mResolvedType = NULL ;
mIsEnumPayloadCase = false ;
mCustomAttributes = NULL ;
mConstIdx = - 1 ;
mDataIdx = - 1 ;
mMergedDataIdx = - 1 ;
mDataOffset = - 1 ;
mDataSize = 0 ;
mFieldIncluded = true ;
mIsThreadLocal = false ;
2019-10-04 10:38:36 -07:00
mIsInferredType = false ;
2021-01-02 15:46:29 -08:00
mHadConstEval = false ;
2019-08-23 11:56:54 -07:00
mLastRevisionReferenced = - 1 ;
}
~ BfFieldInstance ( ) ;
BfType * GetResolvedType ( ) ;
void SetResolvedType ( BfType * type ) ;
2020-07-18 06:51:00 -07:00
void GetDataRange ( int & dataIdx , int & dataCount ) ;
2022-02-06 10:49:35 -05:00
int GetAlign ( int packing ) ;
2022-06-27 10:55:31 -07:00
bool IsAppendedObject ( ) ;
2019-08-23 11:56:54 -07:00
} ;
enum BfMethodRefKind
{
BfMethodRefKind_VExtMarker = - 1 ,
BfMethodRefKind_AmbiguousRef = - 2
} ;
class BfNonGenericMethodRef
{
public :
BfTypeInstance * mTypeInstance ;
union
{
int mMethodNum ;
BfMethodRefKind mKind ;
} ;
int mSignatureHash ;
BfNonGenericMethodRef ( )
{
mTypeInstance = NULL ;
mMethodNum = 0 ;
mSignatureHash = 0 ;
}
BfNonGenericMethodRef ( BfMethodInstance * methodInstance ) ;
operator BfMethodInstance * ( ) const ;
bool IsNull ( ) { return mTypeInstance = = NULL ; } ;
BfMethodInstance * operator - > ( ) const ;
BfNonGenericMethodRef & operator = ( BfMethodInstance * methodInstance ) ;
bool operator = = ( const BfNonGenericMethodRef & methodRef ) const ;
bool operator = = ( BfMethodInstance * methodInstance ) const ;
struct Hash
{
size_t operator ( ) ( const BfNonGenericMethodRef & val ) const ;
} ;
struct Equals
{
bool operator ( ) ( const BfNonGenericMethodRef & lhs , const BfNonGenericMethodRef & rhs ) const
{
return lhs = = rhs ;
}
} ;
} ;
enum BfMethodRefFlags : uint8
{
BfMethodRefFlag_None = 0 ,
BfMethodRefFlag_AlwaysInclude = 1
} ;
class BfMethodRef
{
public :
BfTypeInstance * mTypeInstance ;
union
{
int mMethodNum ;
BfMethodRefKind mKind ;
} ;
Array < BfType * > mMethodGenericArguments ;
int mSignatureHash ;
BfMethodRefFlags mMethodRefFlags ;
BfMethodRef ( )
{
mTypeInstance = NULL ;
mMethodNum = 0 ;
mSignatureHash = 0 ;
mMethodRefFlags = BfMethodRefFlag_None ;
}
2020-12-17 04:51:05 -08:00
BfMethodRef ( BfMethodInstance * methodInstance ) ;
2019-08-23 11:56:54 -07:00
operator BfMethodInstance * ( ) const ;
bool IsNull ( ) { return mTypeInstance = = NULL ; } ;
BfMethodInstance * operator - > ( ) const ;
BfMethodRef & operator = ( BfMethodInstance * methodInstance ) ;
bool operator = = ( const BfMethodRef & methodRef ) const ;
bool operator = = ( BfMethodInstance * methodInstance ) const ;
struct Hash
{
size_t operator ( ) ( const BfMethodRef & val ) const ;
} ;
struct Equals
{
bool operator ( ) ( const BfMethodRef & lhs , const BfMethodRef & rhs ) const
{
return lhs = = rhs ;
}
} ;
} ;
class BfFieldRef
{
public :
BfTypeInstance * mTypeInstance ;
int mFieldIdx ;
public :
BfFieldRef ( )
{
mTypeInstance = NULL ;
mFieldIdx = 0 ;
}
BfFieldRef ( BfTypeInstance * typeInst , BfFieldDef * fieldDef ) ;
BfFieldRef ( BfFieldInstance * fieldInstance ) ;
bool operator = = ( const BfFieldRef & other ) const
{
return ( mTypeInstance = = other . mTypeInstance ) & & ( mFieldIdx = = other . mFieldIdx ) ;
}
operator BfFieldInstance * ( ) const ;
operator BfFieldDef * ( ) const ;
operator BfPropertyDef * ( ) const ;
} ;
class BfPropertyRef
{
public :
BfTypeInstance * mTypeInstance ;
int mPropIdx ;
public :
BfPropertyRef ( )
{
mTypeInstance = NULL ;
mPropIdx = 0 ;
}
BfPropertyRef ( BfTypeInstance * typeInst , BfPropertyDef * propDef ) ;
operator BfPropertyDef * ( ) const ;
} ;
class BfTypeInterfaceEntry
{
public :
BfTypeDef * mDeclaringType ;
BfTypeInstance * mInterfaceType ;
int mStartInterfaceTableIdx ;
int mStartVirtualIdx ; // Relative to start of virtual interface methods
bool mIsRedeclared ;
} ;
class BfTypeInterfaceMethodEntry
{
public :
BfNonGenericMethodRef mMethodRef ;
//int mVirtualIdx;
public :
BfTypeInterfaceMethodEntry ( )
{
//mVirtualIdx = -1;
}
} ;
enum BfAttributeTargets : int32
{
BfAttributeTargets_SkipValidate = - 1 ,
2020-04-29 09:53:48 -07:00
BfAttributeTargets_None = 0 ,
BfAttributeTargets_Assembly = 0x0001 ,
BfAttributeTargets_Module = 0x0002 ,
BfAttributeTargets_Class = 0x0004 ,
BfAttributeTargets_Struct = 0x0008 ,
BfAttributeTargets_Enum = 0x0010 ,
BfAttributeTargets_Constructor = 0x0020 ,
BfAttributeTargets_Method = 0x0040 ,
BfAttributeTargets_Property = 0x0080 ,
BfAttributeTargets_Field = 0x0100 ,
BfAttributeTargets_StaticField = 0x0200 ,
BfAttributeTargets_Interface = 0x0400 ,
BfAttributeTargets_Parameter = 0x0800 ,
BfAttributeTargets_Delegate = 0x1000 ,
BfAttributeTargets_Function = 0x2000 ,
BfAttributeTargets_ReturnValue = 0x4000 ,
2019-08-23 11:56:54 -07:00
BfAttributeTargets_GenericParameter = 0x8000 ,
2020-04-29 09:53:48 -07:00
BfAttributeTargets_Invocation = 0x10000 ,
2019-08-23 11:56:54 -07:00
BfAttributeTargets_MemberAccess = 0x20000 ,
2020-04-29 09:53:48 -07:00
BfAttributeTargets_Alloc = 0x40000 ,
BfAttributeTargets_Delete = 0x80000 ,
BfAttributeTargets_Alias = 0x100000 ,
2020-08-16 08:33:51 -07:00
BfAttributeTargets_Block = 0x200000 ,
2021-12-27 12:55:14 -05:00
BfAttributeTargets_DelegateTypeRef = 0x400000 ,
BfAttributeTargets_FunctionTypeRef = 0x800000 ,
BfAttributeTargets_All = 0xFFFFFF
2019-08-23 11:56:54 -07:00
} ;
2021-01-30 08:08:30 -08:00
enum BfAttributeFlags : int8
{
BfAttributeFlag_None ,
BfAttributeFlag_DisallowAllowMultiple = 1 ,
BfAttributeFlag_NotInherited = 2 ,
BfAttributeFlag_ReflectAttribute = 4 ,
BfAttributeFlag_AlwaysIncludeTarget = 8
} ;
2019-08-23 11:56:54 -07:00
class BfAttributeData
{
public :
BfAttributeTargets mAttributeTargets ;
2020-12-29 12:41:43 -08:00
BfAlwaysIncludeFlags mAlwaysIncludeUser ;
2021-01-30 08:08:30 -08:00
BfAttributeFlags mFlags ;
2019-08-23 11:56:54 -07:00
public :
BfAttributeData ( )
{
mAttributeTargets = BfAttributeTargets_All ;
2020-12-29 12:41:43 -08:00
mAlwaysIncludeUser = BfAlwaysIncludeFlag_None ;
2021-01-30 08:08:30 -08:00
mFlags = BfAttributeFlag_None ;
2019-08-23 11:56:54 -07:00
}
} ;
class BfHotTypeData
{
public :
Array < BfHotTypeVersion * > mTypeVersions ;
Array < BfHotTypeDataEntry > mVTableEntries ; // Doesn't fill in until we rebuild or delete type
int mVTableOrigLength ;
int mOrigInterfaceMethodsLength ;
bool mPendingDataChange ;
bool mHadDataChange ; // True if we have EVER had a hot data change
public :
BfHotTypeData ( )
{
mVTableOrigLength = - 1 ;
mOrigInterfaceMethodsLength = - 1 ;
mPendingDataChange = false ;
mHadDataChange = false ;
}
~ BfHotTypeData ( ) ;
BfHotTypeVersion * GetTypeVersion ( int hotCommitedIdx ) ;
BfHotTypeVersion * GetLatestVersion ( ) ;
BfHotTypeVersion * GetLatestVersionHead ( ) ; // The oldest version that has the same data
void ClearVersionsAfter ( int hotIdx ) ;
} ;
struct BfTypeLookupEntry
{
BfAtomComposite mName ;
int mNumGenericParams ;
uint32 mAtomUpdateIdx ;
BfTypeDef * mUseTypeDef ;
bool operator = = ( const BfTypeLookupEntry & rhs ) const
{
return ( mName = = rhs . mName ) & &
( mNumGenericParams = = rhs . mNumGenericParams ) & &
( mUseTypeDef = = rhs . mUseTypeDef ) ;
}
} ;
NS_BF_END ;
namespace std
{
template < >
struct hash < Beefy : : BfTypeLookupEntry >
{
size_t operator ( ) ( const Beefy : : BfTypeLookupEntry & entry ) const
{
int curHash = 0 ;
for ( int i = 0 ; i < entry . mName . mSize ; i + + )
curHash = ( ( curHash ^ ( int ) ( intptr ) entry . mName . mParts [ i ] ) < < 5 ) - curHash ;
curHash = ( ( curHash ^ entry . mNumGenericParams ) < < 5 ) - curHash ;
curHash ^ = ( intptr ) entry . mUseTypeDef ;
return curHash ;
}
} ;
}
NS_BF_BEGIN ;
struct BfTypeLookupResult
{
BfTypeDef * mTypeDef ;
bool mForceLookup ;
2021-02-28 11:41:00 -08:00
bool mFoundInnerType ;
2019-08-23 11:56:54 -07:00
BfTypeLookupResult ( )
{
mTypeDef = NULL ;
mForceLookup = false ;
2021-02-28 11:41:00 -08:00
mFoundInnerType = false ;
}
} ;
struct BfTypeLookupResultCtx
{
BfTypeLookupResult * mResult ;
bool mIsVerify ;
BfTypeLookupResultCtx ( )
{
mResult = NULL ;
mIsVerify = false ;
2019-08-23 11:56:54 -07:00
}
} ;
class BfDependedType : public BfType
{
public :
BfDependencyMap mDependencyMap ; // This is a list of types that depend on THIS type
public :
virtual bool IsDependendType ( ) override { return true ; }
virtual BfDependedType * ToDependedType ( ) override { return this ; }
} ;
struct BfVirtualMethodEntry
{
BfNonGenericMethodRef mDeclaringMethod ;
BfNonGenericMethodRef mImplementingMethod ;
} ;
struct BfSpecializedMethodRefInfo
{
bool mHasReifiedRef ;
BfSpecializedMethodRefInfo ( )
{
mHasReifiedRef = false ;
}
} ;
class BfStaticSearch
{
public :
Array < BfTypeInstance * > mStaticTypes ;
} ;
2020-10-14 11:33:41 -07:00
class BfInternalAccessSet
{
public :
Array < BfTypeInstance * > mTypes ;
Array < BfAtomComposite > mNamespaces ;
} ;
2019-10-09 16:16:01 -07:00
class BfTypeInfoEx
{
public :
BfType * mUnderlyingType ;
int64 mMinValue ;
int64 mMaxValue ;
BfTypeInfoEx ( )
{
mUnderlyingType = NULL ;
mMinValue = 0 ;
mMaxValue = 0 ;
}
} ;
2020-06-05 07:01:58 -07:00
class BfGenericExtensionEntry
{
public :
Array < BfGenericTypeParamInstance * > mGenericParams ;
bool mConstraintsPassed ;
public :
BfGenericExtensionEntry ( BfGenericExtensionEntry & & prev ) :
mGenericParams ( std : : move ( prev . mGenericParams ) ) ,
mConstraintsPassed ( prev . mConstraintsPassed )
{
}
BfGenericExtensionEntry ( )
{
mConstraintsPassed = true ;
}
~ BfGenericExtensionEntry ( ) ;
} ;
class BfGenericExtensionInfo
{
public :
Dictionary < BfTypeDef * , BfGenericExtensionEntry > mExtensionMap ;
2022-02-16 18:28:23 -05:00
BitSet mConstraintsPassedSet ;
void Clear ( )
{
mExtensionMap . Clear ( ) ;
}
2020-06-05 07:01:58 -07:00
} ;
// Note on nested generic types- mGenericParams is the accumulation of all generic params from outer to inner, so
// class ClassA<T> { class ClassB<T2> {} } will create a ClassA.ClassB<T, T2>
class BfGenericTypeInfo
{
public :
typedef Array < BfGenericTypeParamInstance * > GenericParamsVector ;
BfTypeVector mTypeGenericArguments ;
GenericParamsVector mGenericParams ;
BfGenericExtensionInfo * mGenericExtensionInfo ;
bool mIsUnspecialized ;
bool mIsUnspecializedVariation ;
bool mValidatedGenericConstraints ;
bool mHadValidateErrors ;
2020-09-18 17:00:33 -07:00
bool mInitializedGenericParams ;
2020-09-28 12:41:42 -07:00
bool mFinishedGenericParams ;
2020-06-05 07:01:58 -07:00
Array < BfProject * > mProjectsReferenced ; // Generic methods that only refer to these projects don't need a specialized extension
2021-02-25 10:14:22 -08:00
int32 mMaxGenericDepth ;
2020-06-05 07:01:58 -07:00
public :
BfGenericTypeInfo ( )
{
mGenericExtensionInfo = NULL ;
mHadValidateErrors = false ;
mIsUnspecialized = false ;
mIsUnspecializedVariation = false ;
mValidatedGenericConstraints = false ;
2020-09-18 17:00:33 -07:00
mInitializedGenericParams = false ;
mFinishedGenericParams = false ;
2021-02-25 10:14:22 -08:00
mMaxGenericDepth = - 1 ;
2020-06-05 07:01:58 -07:00
}
~ BfGenericTypeInfo ( ) ;
void ReportMemory ( MemReporter * memReporter ) ;
} ;
2021-12-20 09:39:39 -05:00
class BfCeTypeInfo ;
2020-06-05 07:01:58 -07:00
2022-05-07 11:40:55 -07:00
struct BfReifyMethodDependency
{
public :
BfNonGenericMethodRef mDepMethod ;
int mMethodIdx ;
} ;
2019-08-23 11:56:54 -07:00
// Instance of struct or class
class BfTypeInstance : public BfDependedType
{
2022-05-07 11:40:55 -07:00
public :
2019-08-23 11:56:54 -07:00
int mSignatureRevision ;
int mLastNonGenericUsedRevision ;
int mInheritanceId ;
int mInheritanceCount ;
BfModule * mModule ;
BfTypeDef * mTypeDef ;
BfTypeInstance * mBaseType ;
BfCustomAttributes * mCustomAttributes ;
BfAttributeData * mAttributeData ;
2019-10-09 16:16:01 -07:00
BfTypeInfoEx * mTypeInfoEx ;
2020-06-05 07:01:58 -07:00
BfGenericTypeInfo * mGenericTypeInfo ;
2021-02-01 05:21:41 -08:00
BfCeTypeInfo * mCeTypeInfo ;
2019-08-23 11:56:54 -07:00
Array < BfTypeInterfaceEntry > mInterfaces ;
2022-05-07 11:40:55 -07:00
Array < BfTypeInterfaceMethodEntry > mInterfaceMethodTable ;
2019-08-23 11:56:54 -07:00
Array < BfMethodInstanceGroup > mMethodInstanceGroups ;
2020-09-18 17:00:33 -07:00
Array < BfOperatorInfo * > mOperatorInfo ;
2022-05-07 11:40:55 -07:00
Array < BfVirtualMethodEntry > mVirtualMethodTable ;
Array < BfReifyMethodDependency > mReifyMethodDependencies ;
2019-08-23 11:56:54 -07:00
BfHotTypeData * mHotTypeData ;
int mVirtualMethodTableSize ; // With hot reloading, mVirtualMethodTableSize can be larger than mInterfaceMethodTable (live vtable versioning)
2020-01-30 07:06:16 -08:00
Array < BfFieldInstance > mFieldInstances ;
2019-08-23 11:56:54 -07:00
Array < BfMethodInstance * > mInternalMethods ;
Dictionary < BfTypeDef * , BfStaticSearch > mStaticSearchMap ;
2020-10-14 11:33:41 -07:00
Dictionary < BfTypeDef * , BfInternalAccessSet > mInternalAccessMap ;
2021-01-08 16:21:03 -08:00
Array < BfLocalMethod * > mOwnedLocalMethods ; // Local methods in CEMachine
2019-08-23 11:56:54 -07:00
bool mHasStaticInitMethod ;
bool mHasStaticDtorMethod ;
bool mHasStaticMarkMethod ;
bool mHasTLSFindMethod ;
BfIRConstHolder * mConstHolder ;
Dictionary < BfMethodRef , BfSpecializedMethodRefInfo > mSpecializedMethodReferences ; // Includes both specialized methods and OnDemand methods
// We store lookup results so we can rebuild this type if a name resolves differently due to a new type being created (ie: a type name found first in
Dictionary < BfTypeLookupEntry , BfTypeLookupResult > mLookupResults ;
int mTypeOptionsIdx ;
int mMergedFieldDataCount ;
int mInstAlign ;
int mInstSize ;
int16 mInheritDepth ;
int16 mSlotNum ;
2020-12-29 12:41:43 -08:00
BfAlwaysIncludeFlags mAlwaysIncludeFlags ;
2019-08-23 11:56:54 -07:00
bool mHasBeenInstantiated ;
bool mIsReified ;
bool mIsTypedPrimitive ;
bool mIsCRepr ;
bool mIsUnion ;
2022-02-06 10:49:35 -05:00
uint8 mPacking ;
2019-08-23 11:56:54 -07:00
bool mIsSplattable ;
2020-08-23 05:42:42 -07:00
bool mHasUnderlyingArray ;
2019-08-23 11:56:54 -07:00
bool mTypeIncomplete ;
bool mTypeFailed ;
bool mTypeWarned ;
bool mResolvingVarField ;
bool mResolvingConstField ;
bool mSkipTypeProtectionChecks ;
bool mNeedsMethodProcessing ;
bool mBaseTypeMayBeIncomplete ;
bool mHasParameterizedBase ; // Generic, array, etc
bool mIsFinishingType ;
bool mHasPackingHoles ;
bool mWantsGCMarking ;
2020-12-31 11:31:19 -08:00
bool mHasDeclError ;
2019-08-23 11:56:54 -07:00
public :
BfTypeInstance ( )
{
mModule = NULL ;
mSignatureRevision = - 1 ;
mLastNonGenericUsedRevision = - 1 ;
mInheritanceId = 0 ;
mInheritanceCount = 0 ;
mTypeDef = NULL ;
mRevision = - 1 ;
mIsReified = true ;
mIsSplattable = false ;
2020-08-23 05:42:42 -07:00
mHasUnderlyingArray = false ;
2022-02-06 10:49:35 -05:00
mPacking = 0 ;
2019-08-23 11:56:54 -07:00
mBaseType = NULL ;
mCustomAttributes = NULL ;
mAttributeData = NULL ;
2019-10-09 16:16:01 -07:00
mTypeInfoEx = NULL ;
2020-06-05 07:01:58 -07:00
mGenericTypeInfo = NULL ;
2021-02-01 05:21:41 -08:00
mCeTypeInfo = NULL ;
2019-08-23 11:56:54 -07:00
//mClassVData = NULL;
mVirtualMethodTableSize = 0 ;
mHotTypeData = NULL ;
mHasStaticInitMethod = false ;
mHasStaticMarkMethod = false ;
mHasStaticDtorMethod = false ;
mHasTLSFindMethod = false ;
mSlotNum = - 1 ;
mTypeOptionsIdx = - 2 ; // -2 = not checked, -1 = none
mInstSize = - 1 ;
mInstAlign = - 1 ;
mInheritDepth = 0 ;
mIsTypedPrimitive = false ;
mTypeIncomplete = true ;
mIsCRepr = false ;
mIsUnion = false ;
mTypeFailed = false ;
mTypeWarned = false ;
mResolvingVarField = false ;
mSkipTypeProtectionChecks = false ;
mNeedsMethodProcessing = false ;
mBaseTypeMayBeIncomplete = false ;
mIsFinishingType = false ;
mResolvingConstField = false ;
2020-12-29 12:41:43 -08:00
mHasPackingHoles = false ;
mAlwaysIncludeFlags = BfAlwaysIncludeFlag_None ;
mHasBeenInstantiated = false ;
2019-08-23 11:56:54 -07:00
mWantsGCMarking = false ;
mHasParameterizedBase = false ;
2020-10-13 10:32:56 -07:00
mHasDeclError = false ;
2019-08-23 11:56:54 -07:00
mMergedFieldDataCount = 0 ;
mConstHolder = NULL ;
}
~ BfTypeInstance ( ) ;
2020-10-14 11:33:41 -07:00
2022-03-18 18:06:14 -07:00
virtual void Dispose ( ) ;
2021-10-28 08:05:14 -07:00
void ReleaseData ( ) ;
2019-08-23 11:56:54 -07:00
2021-11-02 09:57:16 -07:00
virtual bool IsInstanceOf ( BfTypeDef * typeDef ) override { if ( typeDef = = NULL ) return false ; return typeDef - > GetDefinition ( ) = = mTypeDef - > GetDefinition ( ) ; }
2019-10-14 14:08:29 -07:00
virtual BfModule * GetModule ( ) override { return mModule ; }
2019-08-23 11:56:54 -07:00
virtual BfTypeInstance * ToTypeInstance ( ) override { return this ; }
virtual bool IsDependentOnUnderlyingType ( ) override { return true ; }
2022-02-05 09:23:44 -05:00
virtual BfPrimitiveType * ToPrimitiveType ( ) override { return IsBoxed ( ) ? GetUnderlyingType ( ) - > ToPrimitiveType ( ) : NULL ; }
2019-10-14 14:08:29 -07:00
virtual bool HasWrappedRepresentation ( ) override { return IsTypedPrimitive ( ) ; }
2019-10-09 16:16:01 -07:00
2021-12-31 07:56:57 -05:00
int GetEndingInstanceAlignment ( ) { if ( mInstSize % mInstAlign = = 0 ) return mInstAlign ; return mInstSize % mInstAlign ; }
2019-08-23 11:56:54 -07:00
virtual bool HasTypeFailed ( ) override { return mTypeFailed ; }
2022-02-15 10:27:04 -05:00
virtual bool IsReified ( ) override { return mIsReified ; }
2019-08-23 11:56:54 -07:00
virtual bool IsDataIncomplete ( ) override { return ( ( mTypeIncomplete ) | | ( mBaseTypeMayBeIncomplete ) ) & & ( ! mNeedsMethodProcessing ) ; }
2021-02-25 10:14:22 -08:00
virtual bool IsFinishingType ( ) override { return mIsFinishingType ; }
2019-08-23 11:56:54 -07:00
virtual bool IsIncomplete ( ) override { return ( mTypeIncomplete ) | | ( mBaseTypeMayBeIncomplete ) ; }
virtual bool IsSplattable ( ) override { BF_ASSERT ( ( mInstSize > = 0 ) | | ( ! IsComposite ( ) ) ) ; return mIsSplattable ; }
virtual int GetSplatCount ( ) override ;
virtual bool IsTypeInstance ( ) override { return true ; }
2021-12-31 07:56:57 -05:00
virtual BfTypeCode GetTypeCode ( ) override { return mTypeDef - > mTypeCode ; }
2019-08-23 11:56:54 -07:00
virtual bool IsInterface ( ) override { return mTypeDef - > mTypeCode = = BfTypeCode_Interface ; }
virtual bool IsValueType ( ) override { return ( mTypeDef - > mTypeCode = = BfTypeCode_Struct ) | | ( mTypeDef - > mTypeCode = = BfTypeCode_Enum ) ; }
2021-02-24 06:02:17 -08:00
virtual bool IsOpaque ( ) override { return mTypeDef - > mIsOpaque ; }
2019-08-23 11:56:54 -07:00
virtual bool IsStruct ( ) override { return ( ( mTypeDef - > mTypeCode = = BfTypeCode_Struct ) | | ( mTypeDef - > mTypeCode = = BfTypeCode_Enum ) ) & & ( ! mIsTypedPrimitive ) ; }
virtual bool IsUnion ( ) override { return mIsUnion ; }
virtual bool IsDelegate ( ) override { return mTypeDef - > mIsDelegate ; }
virtual bool IsFunction ( ) override { return mTypeDef - > mIsFunction ; }
2021-01-19 13:52:36 -08:00
virtual bool IsDelegateOrFunction ( ) override { return mTypeDef - > mIsDelegate | | mTypeDef - > mIsFunction ; }
2019-08-23 11:56:54 -07:00
virtual bool IsString ( ) override ;
virtual bool IsIntPtrable ( ) override { return ( mTypeDef - > mTypeCode = = BfTypeCode_Object ) | | ( mTypeDef - > mTypeCode = = BfTypeCode_Interface ) ; } ;
virtual bool IsEnum ( ) override { return mTypeDef - > mTypeCode = = BfTypeCode_Enum ; }
virtual bool IsPayloadEnum ( ) override { return ( mTypeDef - > mTypeCode = = BfTypeCode_Enum ) & & ( ! mIsTypedPrimitive ) ; }
virtual bool IsTypedPrimitive ( ) override { return mIsTypedPrimitive ; }
virtual bool IsStructOrStructPtr ( ) override { return mTypeDef - > mTypeCode = = BfTypeCode_Struct ; }
virtual bool IsValueTypeOrValueTypePtr ( ) override { return ( mTypeDef - > mTypeCode = = BfTypeCode_Struct ) | | ( mTypeDef - > mTypeCode = = BfTypeCode_Enum ) ; }
virtual bool IsObject ( ) override { return mTypeDef - > mTypeCode = = BfTypeCode_Object ; }
virtual bool IsObjectOrStruct ( ) override { return ( mTypeDef - > mTypeCode = = BfTypeCode_Object ) | | ( mTypeDef - > mTypeCode = = BfTypeCode_Struct ) ; }
virtual bool IsObjectOrInterface ( ) override { return ( mTypeDef - > mTypeCode = = BfTypeCode_Object ) | | ( mTypeDef - > mTypeCode = = BfTypeCode_Interface ) ; }
virtual BfType * GetUnderlyingType ( ) override ;
//virtual bool IsValuelessType() override { return (mIsTypedPrimitive) && (mInstSize == 0); }
virtual bool CanBeValuelessType ( ) override { return ( mTypeDef - > mTypeCode = = BfTypeCode_Struct ) | | ( mTypeDef - > mTypeCode = = BfTypeCode_Enum ) ; }
virtual bool IsValuelessType ( ) override ;
2019-10-14 14:08:29 -07:00
virtual bool HasPackingHoles ( ) override { return mHasPackingHoles ; }
2019-08-23 11:56:54 -07:00
virtual bool IsTypeMemberAccessible ( BfTypeDef * declaringTypeDef , BfTypeDef * activeTypeDef ) override ;
virtual bool IsTypeMemberAccessible ( BfTypeDef * declaringTypeDef , BfProject * curProject ) override ;
2020-07-01 12:06:28 -07:00
virtual bool IsTypeMemberAccessible ( BfTypeDef * declaringTypeDef , BfProjectSet * visibleProjectSet ) override ;
2019-08-23 11:56:54 -07:00
virtual bool WantsGCMarking ( ) override ;
2020-06-10 07:12:07 -07:00
virtual bool GetLoweredType ( BfTypeUsage typeUsage , BfTypeCode * outTypeCode = NULL , BfTypeCode * outTypeCode2 = NULL ) override ;
2019-08-23 11:56:54 -07:00
2020-06-05 07:01:58 -07:00
BfGenericTypeInfo * GetGenericTypeInfo ( ) { return mGenericTypeInfo ; }
2022-02-08 10:33:20 -05:00
virtual int GetGenericDepth ( ) { return ( mGenericTypeInfo ! = NULL ) ? mGenericTypeInfo - > mMaxGenericDepth : 0 ; }
2020-06-05 07:01:58 -07:00
2020-06-10 07:12:07 -07:00
virtual BfTypeInstance * ToGenericTypeInstance ( ) override { return ( mGenericTypeInfo ! = NULL ) ? this : NULL ; }
2020-06-05 07:01:58 -07:00
virtual bool IsGenericTypeInstance ( ) override { return mGenericTypeInfo ! = NULL ; }
virtual bool IsSpecializedType ( ) override { return ( mGenericTypeInfo ! = NULL ) & & ( ! mGenericTypeInfo - > mIsUnspecialized ) ; }
virtual bool IsSpecializedByAutoCompleteMethod ( ) override ;
virtual bool IsUnspecializedType ( ) override { return ( mGenericTypeInfo ! = NULL ) & & ( mGenericTypeInfo - > mIsUnspecialized ) ; }
virtual bool IsUnspecializedTypeVariation ( ) override { return ( mGenericTypeInfo ! = NULL ) & & ( mGenericTypeInfo - > mIsUnspecializedVariation ) ; }
virtual bool IsNullable ( ) override ;
virtual bool HasVarConstraints ( ) ;
virtual bool IsTypeMemberIncluded ( BfTypeDef * declaringTypeDef , BfTypeDef * activeTypeDef = NULL , BfModule * module = NULL ) override ;
2019-10-09 16:16:01 -07:00
virtual BfTypeInstance * GetImplBaseType ( ) { return mBaseType ; }
2019-08-23 11:56:54 -07:00
virtual bool IsIRFuncUsed ( BfIRFunction func ) ;
void CalcHotVirtualData ( /*Val128& vtHash, */ Array < int > * ifaceMapping ) ;
int GetOrigVTableSize ( ) ;
int GetSelfVTableSize ( ) ;
int GetOrigSelfVTableSize ( ) ;
2020-01-15 08:34:09 -08:00
int GetImplBaseVTableSize ( ) ;
int GetOrigImplBaseVTableSize ( ) ;
2019-08-23 11:56:54 -07:00
int GetIFaceVMethodSize ( ) ;
BfType * GetUnionInnerType ( bool * wantSplat = NULL ) ;
BfPrimitiveType * GetDiscriminatorType ( int * outDataIdx = NULL ) ;
2020-08-23 05:42:42 -07:00
void GetUnderlyingArray ( BfType * & type , int & size , bool & isVector ) ;
2019-08-23 11:56:54 -07:00
bool HasEquivalentLayout ( BfTypeInstance * compareTo ) ;
BfIRConstHolder * GetOrCreateConstHolder ( ) ;
BfIRValue CreateConst ( BfConstant * fromConst , BfIRConstHolder * fromHolder ) ;
int GetInstStride ( ) { return BF_ALIGN ( mInstSize , mInstAlign ) ; }
bool HasOverrideMethods ( ) ;
bool GetResultInfo ( BfType * & valueType , int & okTagId ) ;
2020-06-05 07:01:58 -07:00
BfGenericTypeInfo : : GenericParamsVector * GetGenericParamsVector ( BfTypeDef * declaringTypeDef ) ;
void GenerateProjectsReferenced ( ) ;
2020-12-29 12:41:43 -08:00
bool IsAlwaysInclude ( ) ;
bool HasBeenInstantiated ( ) { return mHasBeenInstantiated | | ( ( mAlwaysIncludeFlags & BfAlwaysIncludeFlag_AssumeInstantiated ) ! = 0 ) ; }
bool IncludeAllMethods ( ) { return ( ( mAlwaysIncludeFlags & BfAlwaysIncludeFlag_IncludeAllMethods ) ! = 0 ) ; }
2022-05-13 09:43:26 -07:00
bool DefineStateAllowsStaticMethods ( ) { return mDefineState > = BfTypeDefineState_HasInterfaces_Direct ; }
2019-08-23 11:56:54 -07:00
virtual void ReportMemory ( MemReporter * memReporter ) override ;
} ;
2020-05-14 14:56:25 -07:00
template < typename T >
class LogAlloc
{
public :
T * allocate ( intptr count )
{
auto ptr = ( T * ) malloc ( sizeof ( T ) * count ) ;
OutputDebugStrF ( " LogAlloc.allocate: %p \n " , ptr ) ;
return ptr ;
}
void deallocate ( T * ptr )
{
OutputDebugStrF ( " LogAlloc.deallocate: %p \n " , ptr ) ;
free ( ptr ) ;
}
void * rawAllocate ( intptr size )
{
auto ptr = malloc ( size ) ;
OutputDebugStrF ( " LogAlloc.rawAllocate: %p \n " , ptr ) ;
return ptr ;
}
void rawDeallocate ( void * ptr )
{
OutputDebugStrF ( " LogAlloc.rawFree: %p \n " , ptr ) ;
free ( ptr ) ;
}
} ;
2019-08-23 11:56:54 -07:00
class BfBoxedType : public BfTypeInstance
{
2019-10-09 16:16:01 -07:00
public :
enum BoxedFlags
{
BoxedFlags_None = 0 ,
BoxedFlags_StructPtr = 1
} ;
2019-08-23 11:56:54 -07:00
public :
2020-01-30 07:06:16 -08:00
BfType * mElementType ;
2019-10-09 16:16:01 -07:00
BfBoxedType * mBoxedBaseType ;
BoxedFlags mBoxedFlags ;
2019-08-23 11:56:54 -07:00
public :
2019-10-09 16:16:01 -07:00
BfBoxedType ( )
{
mElementType = NULL ;
mBoxedBaseType = NULL ;
mBoxedFlags = BoxedFlags_None ;
}
2021-12-16 07:28:03 -05:00
~ BfBoxedType ( ) ;
2019-10-09 16:16:01 -07:00
2019-08-23 11:56:54 -07:00
virtual bool IsBoxed ( ) override { return true ; }
virtual bool IsValueType ( ) override { return false ; }
virtual bool IsStruct ( ) override { return false ; }
virtual bool IsEnum ( ) override { return false ; }
virtual bool IsStructOrStructPtr ( ) override { return false ; }
virtual bool IsObject ( ) override { return true ; }
virtual bool IsObjectOrStruct ( ) override { return true ; }
virtual bool IsObjectOrInterface ( ) override { return true ; }
virtual bool IsDependentOnUnderlyingType ( ) override { return true ; }
virtual BfType * GetUnderlyingType ( ) override { return mElementType ; }
2020-06-05 07:01:58 -07:00
virtual BfTypeInstance * ToGenericTypeInstance ( ) override { return mElementType - > ToGenericTypeInstance ( ) ; }
2019-08-23 11:56:54 -07:00
virtual bool IsSpecializedType ( ) override { return ! mElementType - > IsUnspecializedType ( ) ; }
virtual bool IsUnspecializedType ( ) override { return mElementType - > IsUnspecializedType ( ) ; }
virtual bool IsUnspecializedTypeVariation ( ) override { return mElementType - > IsUnspecializedTypeVariation ( ) ; }
2019-10-09 16:16:01 -07:00
2019-10-14 14:08:29 -07:00
virtual BfTypeInstance * GetImplBaseType ( ) override { return ( mBoxedBaseType ! = NULL ) ? mBoxedBaseType : mBaseType ; }
2019-10-09 16:16:01 -07:00
bool IsBoxedStructPtr ( )
{
return ( mBoxedFlags & BoxedFlags_StructPtr ) ! = 0 ;
}
BfType * GetModifiedElementType ( ) ;
2019-08-23 11:56:54 -07:00
} ;
class BfTypeAliasType : public BfTypeInstance
{
public :
BfType * mAliasToType ;
public :
BfTypeAliasType ( )
{
mAliasToType = NULL ;
}
virtual bool IsTypeAlias ( ) override { return true ; }
virtual BfType * GetUnderlyingType ( ) override { return mAliasToType ; }
virtual bool WantsGCMarking ( ) override { return mAliasToType - > WantsGCMarking ( ) ; }
} ;
enum BfCaptureType
{
2019-11-26 13:11:17 -08:00
BfCaptureType_None ,
BfCaptureType_Copy ,
BfCaptureType_Reference ,
2019-08-23 11:56:54 -07:00
} ;
class BfClosureType : public BfTypeInstance
{
public :
Val128 mClosureHash ; // Includes base type and capture info
BfTypeInstance * mSrcDelegate ;
bool mCreatedTypeDef ;
String mNameAdd ;
BfSource mSource ;
Array < BfAstNode * > mDirectAllocNodes ;
bool mIsUnique ;
public :
BfClosureType ( BfTypeInstance * srcDelegate , Val128 closureHash ) ;
~ BfClosureType ( ) ;
void Init ( BfProject * bfProject ) ;
BfFieldDef * AddField ( BfType * type , const StringImpl & name ) ;
BfMethodDef * AddDtor ( ) ;
void Finish ( ) ;
virtual bool IsClosure ( ) override { return true ; }
virtual bool IsOnDemand ( ) override { return true ; }
} ;
class BfDelegateType : public BfTypeInstance
{
2020-05-23 17:25:47 -07:00
public :
BfDelegateInfo mDelegateInfo ;
2019-08-23 11:56:54 -07:00
bool mIsUnspecializedType ;
2020-05-23 17:25:47 -07:00
bool mIsUnspecializedTypeVariation ;
2022-02-08 10:33:20 -05:00
int mGenericDepth ;
2019-08-23 11:56:54 -07:00
public :
BfDelegateType ( )
{
mIsUnspecializedType = false ;
2020-05-23 17:25:47 -07:00
mIsUnspecializedTypeVariation = false ;
2022-02-08 10:33:20 -05:00
mGenericDepth = 0 ;
2019-08-23 11:56:54 -07:00
}
~ BfDelegateType ( ) ;
2020-01-23 12:02:54 -08:00
2022-03-18 18:06:14 -07:00
virtual void Dispose ( ) override ;
2020-01-23 12:02:54 -08:00
virtual bool IsOnDemand ( ) override { return true ; }
2019-08-23 11:56:54 -07:00
virtual bool IsDelegate ( ) override { return mTypeDef - > mIsDelegate ; }
virtual bool IsDelegateFromTypeRef ( ) override { return mTypeDef - > mIsDelegate ; }
virtual bool IsFunction ( ) override { return ! mTypeDef - > mIsDelegate ; }
virtual bool IsFunctionFromTypeRef ( ) override { return ! mTypeDef - > mIsDelegate ; }
2021-01-19 13:52:36 -08:00
virtual bool IsDelegateOrFunction ( ) override { return mTypeDef - > mIsDelegate | | mTypeDef - > mIsFunction ; }
2019-08-23 11:56:54 -07:00
virtual bool IsUnspecializedType ( ) override { return mIsUnspecializedType ; }
virtual bool IsUnspecializedTypeVariation ( ) override { return mIsUnspecializedTypeVariation ; }
2020-05-23 17:25:47 -07:00
2020-06-10 07:12:07 -07:00
virtual BfDelegateInfo * GetDelegateInfo ( ) override { return & mDelegateInfo ; }
2022-02-08 10:33:20 -05:00
virtual int GetGenericDepth ( ) override { return mGenericDepth ; }
2020-05-23 17:25:47 -07:00
} ;
2019-08-23 11:56:54 -07:00
class BfTupleType : public BfTypeInstance
{
2022-02-08 10:33:20 -05:00
public :
2019-08-23 11:56:54 -07:00
bool mCreatedTypeDef ;
String mNameAdd ;
BfSource * mSource ;
2020-06-04 15:02:46 -07:00
bool mIsUnspecializedType ;
bool mIsUnspecializedTypeVariation ;
2022-02-08 10:33:20 -05:00
int mGenericDepth ;
2020-06-04 15:02:46 -07:00
2019-08-23 11:56:54 -07:00
public :
2020-06-04 15:02:46 -07:00
BfTupleType ( ) ;
2019-08-23 11:56:54 -07:00
~ BfTupleType ( ) ;
void Init ( BfProject * bfProject , BfTypeInstance * valueTypeInstance ) ;
2022-03-18 18:06:14 -07:00
virtual void Dispose ( ) override ;
2019-08-23 11:56:54 -07:00
BfFieldDef * AddField ( const StringImpl & name ) ;
void Finish ( ) ;
virtual bool IsOnDemand ( ) override { return true ; }
2020-07-20 07:17:33 -07:00
virtual bool IsTuple ( ) override { return true ; }
2019-08-23 11:56:54 -07:00
2020-06-04 15:02:46 -07:00
virtual bool IsUnspecializedType ( ) override { return mIsUnspecializedType ; }
virtual bool IsUnspecializedTypeVariation ( ) override { return mIsUnspecializedTypeVariation ; }
2022-02-08 10:33:20 -05:00
virtual int GetGenericDepth ( ) override { return mGenericDepth ; }
2020-06-04 15:02:46 -07:00
} ;
2019-08-23 11:56:54 -07:00
class BfConcreteInterfaceType : public BfType
{
public :
BfTypeInstance * mInterface ;
virtual bool IsConcreteInterfaceType ( ) override { return true ; }
virtual bool IsDependentOnUnderlyingType ( ) override { return true ; }
virtual BfType * GetUnderlyingType ( ) override { return mInterface ; }
2021-01-20 06:34:49 -08:00
virtual bool IsUnspecializedType ( ) override { return mInterface - > IsUnspecializedType ( ) ; }
virtual bool IsUnspecializedTypeVariation ( ) override { return mInterface - > IsUnspecializedTypeVariation ( ) ; }
2019-08-23 11:56:54 -07:00
} ;
2022-02-08 10:33:20 -05:00
class BfPointerType : public BfElementedType
2019-08-23 11:56:54 -07:00
{
public :
BfType * mElementType ;
public :
virtual bool IsWrappableType ( ) override { return true ; }
2019-10-14 14:08:29 -07:00
virtual bool IsReified ( ) override { return mElementType - > IsReified ( ) ; }
2019-08-23 11:56:54 -07:00
virtual bool IsPointer ( ) override { return true ; }
virtual bool IsIntPtrable ( ) override { return true ; }
2019-10-09 16:16:01 -07:00
virtual bool IsStructPtr ( ) override { return mElementType - > IsStruct ( ) ; }
2019-08-23 11:56:54 -07:00
virtual bool IsStructOrStructPtr ( ) override { return mElementType - > IsStruct ( ) ; }
virtual bool IsValueTypeOrValueTypePtr ( ) override { return mElementType - > IsValueType ( ) ; }
virtual bool IsDependentOnUnderlyingType ( ) override { return true ; }
virtual BfType * GetUnderlyingType ( ) override { return mElementType ; }
virtual bool IsUnspecializedType ( ) override { return mElementType - > IsUnspecializedType ( ) ; }
virtual bool IsUnspecializedTypeVariation ( ) override { return mElementType - > IsUnspecializedTypeVariation ( ) ; }
virtual bool IsVoidPtr ( ) override { return mElementType - > IsVoid ( ) ; }
} ;
// This is used for direct method references for generics so we can directly call methods rather than indirectly through delegates
class BfMethodRefType : public BfDependedType
{
public :
BfMethodInstance * mMethodRef ;
String mMangledMethodName ;
BfTypeInstance * mOwner ;
int mOwnerRevision ;
bool mIsAutoCompleteMethod ;
Array < int > mParamToDataIdx ;
Array < int > mDataToParamIdx ;
bool mIsUnspecialized ;
bool mIsUnspecializedVariation ;
public :
BfMethodRefType ( )
{
mMethodRef = NULL ;
mOwner = NULL ;
mOwnerRevision = - 1 ;
mIsAutoCompleteMethod = false ;
mIsUnspecialized = false ;
mIsUnspecializedVariation = false ;
}
~ BfMethodRefType ( ) ;
//virtual bool IsValuelessType() override { return mSize != 0; }
virtual bool IsValueType ( ) override { return true ; }
virtual bool IsComposite ( ) override { return true ; }
virtual bool IsMethodRef ( ) override { return true ; }
virtual bool IsSplattable ( ) override { return true ; }
2019-10-14 14:08:29 -07:00
virtual int GetSplatCount ( ) override { return ( int ) mDataToParamIdx . mSize ; }
2019-08-23 11:56:54 -07:00
virtual bool IsOnDemand ( ) override { return true ; }
virtual bool IsTemporary ( ) override { return true ; }
virtual bool IsUnspecializedType ( ) override { return mIsUnspecialized ; }
virtual bool IsUnspecializedTypeVariation ( ) override { return mIsUnspecializedVariation ; }
int GetCaptureDataCount ( ) ;
BfType * GetCaptureType ( int captureDataIdx ) ;
int GetDataIdxFromParamIdx ( int paramIdx ) ;
int GetParamIdxFromDataIdx ( int dataIdx ) ;
bool WantsDataPassedAsSplat ( int dataIdx ) ;
//virtual BfType* GetUnderlyingType() override { return mOwner; }
} ;
class BfRefType : public BfType
{
public :
enum RefKind
{
RefKind_Ref ,
2021-01-27 09:01:47 -08:00
RefKind_In ,
2019-08-23 11:56:54 -07:00
RefKind_Out ,
RefKind_Mut
} ;
BfType * mElementType ;
RefKind mRefKind ;
// When an element gets rebuild, it may become valueless which makes us valueless
void CheckElement ( )
{
if ( ( mDefineState > = BfTypeDefineState_Defined ) & & ( mElementType - > mDefineState < BfTypeDefineState_Defined ) & & ( mElementType - > CanBeValuelessType ( ) ) )
mDefineState = BfTypeDefineState_Declared ;
}
virtual bool IsDataIncomplete ( ) override { CheckElement ( ) ; return mDefineState < BfTypeDefineState_Defined ; }
virtual bool IsIncomplete ( ) override { CheckElement ( ) ; return mDefineState < BfTypeDefineState_Defined ; }
2019-10-14 14:08:29 -07:00
virtual bool IsReified ( ) override { return mElementType - > IsReified ( ) ; }
2019-08-23 11:56:54 -07:00
2020-05-01 09:11:13 -07:00
virtual bool IsRef ( ) override { return true ; }
2021-01-26 11:06:17 -08:00
virtual bool IsMut ( ) override { return mRefKind = = RefKind_Mut ; }
2021-01-27 09:01:47 -08:00
virtual bool IsIn ( ) override { return mRefKind = = RefKind_In ; }
2021-01-26 11:06:17 -08:00
virtual bool IsOut ( ) override { return mRefKind = = RefKind_Out ; }
2019-08-23 11:56:54 -07:00
virtual bool IsDependentOnUnderlyingType ( ) override { return true ; }
virtual BfType * GetUnderlyingType ( ) override { return mElementType ; }
virtual bool IsUnspecializedType ( ) override { return mElementType - > IsUnspecializedType ( ) ; }
virtual bool IsUnspecializedTypeVariation ( ) override { return mElementType - > IsUnspecializedTypeVariation ( ) ; }
virtual bool CanBeValuelessType ( ) override { return mElementType - > CanBeValuelessType ( ) ; }
virtual bool IsValuelessType ( ) override { return mElementType - > IsValuelessType ( ) ; }
} ;
2020-06-05 07:01:58 -07:00
class BfArrayType : public BfTypeInstance
2019-08-23 11:56:54 -07:00
{
public :
int mDimensions ;
public :
virtual bool IsArray ( ) override { return true ; }
virtual bool IsValueType ( ) override { return false ; }
virtual bool IsStruct ( ) override { return false ; }
virtual bool IsStructOrStructPtr ( ) override { return false ; }
virtual bool IsObject ( ) override { return true ; }
virtual bool IsObjectOrStruct ( ) override { return true ; }
virtual bool IsObjectOrInterface ( ) override { return true ; }
int GetLengthBitCount ( ) ;
} ;
class BfSizedArrayType : public BfDependedType
{
public :
BfType * mElementType ;
intptr mElementCount ;
2022-02-08 10:33:20 -05:00
int mGenericDepth ;
2019-08-23 11:56:54 -07:00
bool mWantsGCMarking ;
public :
2022-02-08 10:33:20 -05:00
BfSizedArrayType ( )
{
mElementType = NULL ;
mElementCount = 0 ;
mGenericDepth = 0 ;
mWantsGCMarking = false ;
2022-02-15 10:27:04 -05:00
}
2019-08-23 11:56:54 -07:00
virtual bool IsSizedArray ( ) override { return true ; }
2020-12-22 04:50:37 -08:00
virtual bool IsUndefSizedArray ( ) override { return mElementCount = = - 1 ; }
2019-08-23 11:56:54 -07:00
virtual bool IsWrappableType ( ) override { return true ; }
virtual bool IsValueType ( ) override { return true ; } // Is a type of struct
2019-10-14 14:08:29 -07:00
virtual bool IsValueTypeOrValueTypePtr ( ) override { return true ; }
2019-08-23 11:56:54 -07:00
virtual bool IsComposite ( ) override { return true ; }
virtual bool IsStruct ( ) override { return false ; } // But IsStruct infers a definition, which it does not have
virtual bool IsStructOrStructPtr ( ) override { return false ; }
2019-10-14 14:08:29 -07:00
virtual bool IsReified ( ) override { return mElementType - > IsReified ( ) ; }
2019-08-23 11:56:54 -07:00
virtual bool IsDependentOnUnderlyingType ( ) override { return true ; }
virtual BfType * GetUnderlyingType ( ) override { return mElementType ; }
virtual bool IsUnspecializedType ( ) override { return mElementType - > IsUnspecializedType ( ) ; }
virtual bool IsUnspecializedTypeVariation ( ) override { return mElementType - > IsUnspecializedTypeVariation ( ) ; }
virtual bool CanBeValuelessType ( ) override { return true ; }
virtual bool WantsGCMarking ( ) override { BF_ASSERT ( mDefineState > = BfTypeDefineState_Defined ) ; return mWantsGCMarking ; }
2022-02-08 10:33:20 -05:00
virtual int GetGenericDepth ( ) override { return mGenericDepth ; }
2019-08-23 11:56:54 -07:00
// Leave the default "zero sized" definition
//virtual bool IsValuelessType() override { return mElementType->IsValuelessType(); }
} ;
// This is used when a sized array is sized by a const generic argument
class BfUnknownSizedArrayType : public BfSizedArrayType
{
public :
BfType * mElementCountSource ;
public :
2020-12-24 10:29:09 -08:00
virtual bool IsUnknownSizedArrayType ( ) override { return true ; }
2019-08-23 11:56:54 -07:00
virtual bool IsWrappableType ( ) override { return true ; }
virtual bool IsValueType ( ) override { return true ; } // Is a type of struct
2019-10-14 14:08:29 -07:00
virtual bool IsValueTypeOrValueTypePtr ( ) override { return true ; }
2019-08-23 11:56:54 -07:00
virtual bool IsComposite ( ) override { return true ; }
virtual bool IsStruct ( ) override { return false ; } // But IsStruct infers a definition, which it does not have
virtual bool IsStructOrStructPtr ( ) override { return false ; }
2019-10-14 14:08:29 -07:00
virtual bool IsReified ( ) override { return mElementType - > IsReified ( ) ; }
2019-08-23 11:56:54 -07:00
virtual bool IsDependentOnUnderlyingType ( ) override { return true ; }
virtual BfType * GetUnderlyingType ( ) override { return mElementType ; }
2019-11-28 09:11:54 -08:00
virtual bool IsUnspecializedType ( ) override { return mElementType - > IsUnspecializedType ( ) | | mElementCountSource - > IsUnspecializedType ( ) ; }
virtual bool IsUnspecializedTypeVariation ( ) override { return mElementType - > IsUnspecializedTypeVariation ( ) | | mElementCountSource - > IsUnspecializedTypeVariation ( ) ; }
2019-08-23 11:56:54 -07:00
virtual bool CanBeValuelessType ( ) override { return true ; }
// Leave the default "zero sized" definition
//virtual bool IsValuelessType() override { return mElementType->IsValuelessType(); }
} ;
class BfConstExprValueType : public BfDependedType
{
public :
BfType * mType ;
BfVariant mValue ;
public :
2020-09-28 12:41:42 -07:00
~ BfConstExprValueType ( ) ;
2019-08-23 11:56:54 -07:00
virtual bool IsConstExprValue ( ) override { return true ; }
virtual BfType * GetUnderlyingType ( ) override { return mType ; }
2022-04-18 07:57:15 -07:00
virtual bool IsUnspecializedType ( ) { return mValue . mTypeCode = = BfTypeCode_Let ; }
virtual bool IsUnspecializedTypeVariation ( ) { return mValue . mTypeCode = = BfTypeCode_Let ; }
2019-08-23 11:56:54 -07:00
} ;
/*class BfCustomAttributeArgument
{
public :
llvm : : Constant * mConstParam ;
} ; */
class BfCustomAttributeSetProperty
{
public :
BfPropertyRef mPropertyRef ;
BfTypedValue mParam ;
} ;
class BfCustomAttributeSetField
{
public :
BfFieldRef mFieldRef ;
BfTypedValue mParam ;
} ;
class BfCustomAttribute
{
public :
BfAttributeDirective * mRef ;
2022-04-16 06:27:54 -07:00
BfTypeDef * mDeclaringType ;
2019-08-23 11:56:54 -07:00
BfTypeInstance * mType ;
BfMethodDef * mCtor ;
Array < BfIRValue > mCtorArgs ;
Array < BfCustomAttributeSetProperty > mSetProperties ;
Array < BfCustomAttributeSetField > mSetField ;
bool mAwaitingValidation ;
2019-12-01 14:40:17 -08:00
BfAstNode * GetRefNode ( )
{
if ( mRef - > mAttributeTypeRef ! = NULL )
return mRef - > mAttributeTypeRef ;
return mRef ;
}
2019-08-23 11:56:54 -07:00
} ;
class BfCustomAttributes
{
public :
Array < BfCustomAttribute > mAttributes ;
bool Contains ( BfTypeDef * typeDef ) ;
BfCustomAttribute * Get ( BfTypeDef * typeDef ) ;
2021-01-11 09:41:43 -08:00
BfCustomAttribute * Get ( BfType * type ) ;
2022-02-26 22:31:32 -03:00
BfCustomAttribute * Get ( int idx ) ;
2019-08-23 11:56:54 -07:00
void ReportMemory ( MemReporter * memReporter ) ;
} ;
class BfResolvedTypeSetFuncs : public MultiHashSetFuncs
{
} ;
class BfResolvedTypeSet : public MultiHashSet < BfType * , BfResolvedTypeSetFuncs >
{
public :
enum BfHashFlags
{
BfHashFlag_None = 0 ,
BfHashFlag_AllowRef = 1 ,
2021-02-02 07:08:55 -08:00
BfHashFlag_AllowGenericParamConstValue = 2 ,
BfHashFlag_AllowDotDotDot = 4 ,
2019-08-23 11:56:54 -07:00
} ;
2020-02-28 13:58:12 -08:00
2022-02-05 09:23:44 -05:00
struct BfExprResult
{
BfVariant mValue ;
BfType * mResultType ;
} ;
2019-08-23 11:56:54 -07:00
class LookupContext
2020-02-28 13:58:12 -08:00
{
2019-08-23 11:56:54 -07:00
public :
BfModule * mModule ;
BfTypeReference * mRootTypeRef ;
2020-05-23 17:25:47 -07:00
BfTypeDef * mRootTypeDef ;
2020-07-07 10:46:53 -07:00
BfTypeInstance * mRootOuterTypeInstance ;
2021-02-01 06:17:26 -08:00
BfType * mRootResolvedType ;
2022-02-05 09:23:44 -05:00
Dictionary < BfAstNode * , BfType * > mResolvedTypeMap ;
2022-06-24 07:35:02 -07:00
Dictionary < BfAstNode * , BfTypedValue > mResolvedValueMap ;
2020-09-14 06:54:49 -07:00
BfResolveTypeRefFlags mResolveFlags ;
2021-12-27 12:55:14 -05:00
BfCallingConvention mCallingConvention ;
2021-01-15 14:28:21 -08:00
bool mHadVar ;
2022-02-22 08:42:41 -08:00
bool mFailed ;
bool mIsUnboundGeneric ;
2019-08-23 11:56:54 -07:00
public :
LookupContext ( )
2020-06-04 11:47:55 -07:00
{
2019-08-23 11:56:54 -07:00
mRootTypeRef = NULL ;
2020-07-07 10:46:53 -07:00
mRootTypeDef = NULL ;
mRootOuterTypeInstance = NULL ;
2019-08-23 11:56:54 -07:00
mModule = NULL ;
2021-02-01 06:17:26 -08:00
mRootResolvedType = NULL ;
2019-08-23 11:56:54 -07:00
mFailed = false ;
2021-01-15 14:28:21 -08:00
mHadVar = false ;
2022-02-22 08:42:41 -08:00
mIsUnboundGeneric = false ;
2020-06-04 11:47:55 -07:00
mResolveFlags = BfResolveTypeRefFlag_None ;
2021-12-27 12:55:14 -05:00
mCallingConvention = BfCallingConvention_Unspecified ;
2019-08-23 11:56:54 -07:00
}
2021-02-01 06:17:26 -08:00
BfType * GetCachedResolvedType ( BfTypeReference * typeReference ) ;
void SetCachedResolvedType ( BfTypeReference * typeReference , BfType * type ) ;
2019-08-23 11:56:54 -07:00
BfType * ResolveTypeRef ( BfTypeReference * typeReference ) ;
2021-02-01 06:17:26 -08:00
BfTypeDef * ResolveToTypeDef ( BfTypeReference * typeReference , BfType * * outType = NULL ) ;
2019-08-23 11:56:54 -07:00
} ;
public :
2020-07-07 10:46:53 -07:00
static BfTypeDef * FindRootCommonOuterType ( BfTypeDef * outerType , LookupContext * ctx , BfTypeInstance * & outCheckTypeInstance ) ;
2020-09-28 12:41:42 -07:00
static BfVariant EvaluateToVariant ( LookupContext * ctx , BfExpression * expr , BfType * & outType ) ;
2022-02-22 17:58:45 -08:00
static bool GenericTypeEquals ( BfTypeInstance * lhsGenericType , BfTypeVector * lhsTypeGenericArguments , BfTypeReference * rhs , LookupContext * ctx , int & genericParamOffset , bool skipElement = false ) ;
2020-06-05 07:01:58 -07:00
static bool GenericTypeEquals ( BfTypeInstance * lhsGenericType , BfTypeVector * typeGenericArguments , BfTypeReference * rhs , BfTypeDef * rhsTypeDef , LookupContext * ctx ) ;
2021-02-25 10:14:22 -08:00
static void HashGenericArguments ( BfTypeReference * typeRef , LookupContext * ctx , int & hash , int hashSeed ) ;
static int DoHash ( BfType * type , LookupContext * ctx , bool allowRef , int hashSeed ) ;
static int Hash ( BfType * type , LookupContext * ctx , bool allowRef = false , int hashSeed = 0 ) ;
static int DirectHash ( BfTypeReference * typeRef , LookupContext * ctx , BfHashFlags flags = BfHashFlag_None , int hashSeed = 0 ) ;
2022-04-29 08:19:24 -07:00
static BfResolveTypeRefFlags GetResolveFlags ( BfAstNode * typeRef , LookupContext * ctx , BfHashFlags flags = BfHashFlag_None ) ;
2021-02-25 10:14:22 -08:00
static int DoHash ( BfTypeReference * typeRef , LookupContext * ctx , BfHashFlags flags , int & hashSeed ) ;
static int Hash ( BfTypeReference * typeRef , LookupContext * ctx , BfHashFlags flags = BfHashFlag_None , int hashSeed = 0 ) ;
2022-02-04 12:00:43 -05:00
static int Hash ( BfAstNode * typeRefNode , LookupContext * ctx , BfHashFlags flags = BfHashFlag_None , int hashSeed = 0 ) ;
2022-02-05 09:23:44 -05:00
static bool Equals ( BfType * lhs , BfType * rhs , LookupContext * ctx ) ;
2019-08-23 11:56:54 -07:00
static bool Equals ( BfType * lhs , BfTypeReference * rhs , LookupContext * ctx ) ;
2022-02-04 12:00:43 -05:00
static bool Equals ( BfType * lhs , BfAstNode * rhs , LookupContext * ctx ) ;
2020-05-23 17:25:47 -07:00
static bool Equals ( BfType * lhs , BfTypeReference * rhs , BfTypeDef * rhsTypeDef , LookupContext * ctx ) ;
2019-08-23 11:56:54 -07:00
public :
BfResolvedTypeSet ( )
{
2022-05-06 11:28:38 -07:00
Rehash ( 9973 ) ;
2019-08-23 11:56:54 -07:00
}
~ BfResolvedTypeSet ( ) ;
template < typename T >
2022-05-06 11:28:38 -07:00
bool Insert ( T * findType , LookupContext * ctx , BfResolvedTypeSet : : EntryRef * entryPtr )
2019-08-23 11:56:54 -07:00
{
CheckRehash ( ) ;
int tryCount = 0 ;
ctx - > mFailed = false ;
2022-04-18 07:16:45 -07:00
BfHashFlags hashFlags = BfHashFlag_AllowRef ;
2022-04-28 11:52:58 -07:00
if ( ( ctx - > mResolveFlags & ( BfResolveTypeRefFlag_AllowGenericParamConstValue | BfResolveTypeRefFlag_AllowImplicitConstExpr ) ) ! = 0 )
2022-04-18 07:16:45 -07:00
{
2022-04-28 11:52:58 -07:00
ctx - > mResolveFlags = ( BfResolveTypeRefFlags ) ( ctx - > mResolveFlags & ~ ( BfResolveTypeRefFlag_AllowGenericParamConstValue | BfResolveTypeRefFlag_AllowImplicitConstExpr ) ) ;
2022-04-18 07:16:45 -07:00
hashFlags = ( BfHashFlags ) ( hashFlags | BfHashFlag_AllowGenericParamConstValue ) ;
}
int hashVal = Hash ( findType , ctx , hashFlags ) ;
2021-01-15 14:28:21 -08:00
if ( ( ctx - > mFailed ) | | ( ctx - > mHadVar ) )
2019-08-23 11:56:54 -07:00
{
return false ;
2021-01-15 14:28:21 -08:00
}
2019-08-23 11:56:54 -07:00
int bucket = ( hashVal & 0x7FFFFFFF ) % mHashSize ;
2022-05-06 11:28:38 -07:00
auto checkEntryIdx = mHashHeads [ bucket ] ;
while ( checkEntryIdx ! = - 1 )
{
auto checkEntry = & mEntries [ checkEntryIdx ] ;
2019-08-23 11:56:54 -07:00
// checkEntry->mType can be NULL if we're in the process of filling it in (and this Insert is from an element type)
// OR if the type resolution failed after node insertion
2022-05-06 11:28:38 -07:00
if ( ( checkEntry - > mValue ! = NULL ) & & ( hashVal = = checkEntry - > mHashCode ) & & ( Equals ( checkEntry - > mValue , findType , ctx ) ) )
2019-08-23 11:56:54 -07:00
{
2022-05-06 11:28:38 -07:00
* entryPtr = EntryRef ( this , checkEntryIdx ) ;
2019-08-23 11:56:54 -07:00
return false ;
}
2022-05-06 11:28:38 -07:00
checkEntryIdx = checkEntry - > mNext ;
2019-08-23 11:56:54 -07:00
tryCount + + ;
// If this fires off, this may indicate that our hashes are equivalent but Equals fails
if ( tryCount > = 10 )
{
NOP ;
}
BF_ASSERT ( tryCount < 10 ) ;
}
2020-09-14 06:54:49 -07:00
if ( ( ctx - > mResolveFlags & BfResolveTypeRefFlag_NoCreate ) ! = 0 )
return false ;
2022-05-06 11:28:38 -07:00
* entryPtr = AddRaw ( hashVal ) ;
2019-08-23 11:56:54 -07:00
return true ;
}
// Iterator begin();
// Iterator end();
// Iterator erase(Iterator& itr);
2022-05-06 11:28:38 -07:00
void RemoveEntry ( EntryRef entry ) ;
2019-08-23 11:56:54 -07:00
} ;
class BfTypeUtils
{
public :
static String HashEncode64 ( uint64 val ) ; // Note: this only encodes 60 bits
2021-01-22 08:50:21 -08:00
static String TypeToString ( BfAstNode * typeRef ) ;
2019-08-23 11:56:54 -07:00
static String TypeToString ( BfTypeDef * typeDef , BfTypeNameFlags typeNameFlags = BfTypeNameFlags_None ) ;
static bool TypeToString ( StringImpl & str , BfTypeDef * typeDef , BfTypeNameFlags typeNameFlags = BfTypeNameFlags_None ) ;
2022-01-16 07:59:51 -05:00
static bool TypeEquals ( BfType * typeA , BfType * typeB , BfTypeInstance * selfType ) ;
2019-08-23 11:56:54 -07:00
2019-11-19 09:58:35 -08:00
template < typename T >
static void GetProjectList ( BfType * checkType , T * projectList , int immutableLength )
{
if ( checkType - > IsBoxed ( ) )
GetProjectList ( ( ( BfBoxedType * ) checkType ) - > mElementType , projectList , immutableLength ) ;
BfTypeInstance * typeInst = checkType - > ToTypeInstance ( ) ;
if ( typeInst ! = NULL )
{
auto genericTypeInst = typeInst - > ToGenericTypeInstance ( ) ;
if ( genericTypeInst ! = NULL )
{
2020-06-05 07:01:58 -07:00
for ( auto genericArg : genericTypeInst - > mGenericTypeInfo - > mTypeGenericArguments )
2019-11-19 09:58:35 -08:00
GetProjectList ( genericArg , projectList , immutableLength ) ;
}
BfProject * bfProject = typeInst - > mTypeDef - > mProject ;
if ( ! projectList - > Contains ( bfProject ) )
{
bool handled = false ;
for ( int idx = 0 ; idx < ( int ) projectList - > size ( ) ; idx + + )
{
auto checkProject = ( * projectList ) [ idx ] ;
bool isBetter = bfProject - > ContainsReference ( checkProject ) ;
bool isWorse = checkProject - > ContainsReference ( bfProject ) ;
if ( isBetter = = isWorse )
continue ;
if ( isBetter )
{
if ( idx > = immutableLength )
{
// This is even more specific, so replace with this one
( * projectList ) [ idx ] = bfProject ;
handled = true ;
}
}
else
{
// This is less specific, ignore
handled = true ;
}
break ;
}
if ( ! handled )
{
projectList - > Add ( bfProject ) ;
}
}
2020-12-14 07:41:27 -08:00
if ( checkType - > IsTuple ( ) )
{
auto tupleType = ( BfTupleType * ) checkType ;
for ( auto & fieldInstance : tupleType - > mFieldInstances )
GetProjectList ( fieldInstance . mResolvedType , projectList , immutableLength ) ;
}
auto delegateInfo = checkType - > GetDelegateInfo ( ) ;
if ( delegateInfo ! = NULL )
{
GetProjectList ( delegateInfo - > mReturnType , projectList , immutableLength ) ;
for ( auto param : delegateInfo - > mParams )
GetProjectList ( param , projectList , immutableLength ) ;
}
2019-11-19 09:58:35 -08:00
}
else if ( checkType - > IsPointer ( ) )
GetProjectList ( ( ( BfPointerType * ) checkType ) - > mElementType , projectList , immutableLength ) ;
else if ( checkType - > IsRef ( ) )
2022-02-08 10:33:20 -05:00
GetProjectList ( ( ( BfRefType * ) checkType ) - > mElementType , projectList , immutableLength ) ;
2019-11-19 09:58:35 -08:00
else if ( checkType - > IsSizedArray ( ) )
GetProjectList ( ( ( BfSizedArrayType * ) checkType ) - > mElementType , projectList , immutableLength ) ;
else if ( checkType - > IsMethodRef ( ) )
2020-12-14 07:41:27 -08:00
GetProjectList ( ( ( BfMethodRefType * ) checkType ) - > mOwner , projectList , immutableLength ) ;
2019-11-19 09:58:35 -08:00
}
2019-08-23 11:56:54 -07:00
static BfPrimitiveType * GetPrimitiveType ( BfModule * module , BfTypeCode typeCode ) ;
static void PopulateType ( BfModule * module , BfType * type ) ;
template < typename T >
static void SplatIterate ( const T & dataLambda , BfType * checkType )
{
auto checkTypeInstance = checkType - > ToTypeInstance ( ) ;
if ( ( checkTypeInstance ! = NULL ) & & ( checkTypeInstance - > IsValueType ( ) ) & & ( checkTypeInstance - > IsDataIncomplete ( ) ) )
PopulateType ( checkTypeInstance - > mModule , checkTypeInstance ) ;
if ( checkType - > IsStruct ( ) )
{
if ( checkTypeInstance - > mBaseType ! = NULL )
SplatIterate < T > ( dataLambda , checkTypeInstance - > mBaseType ) ;
if ( checkTypeInstance - > mIsUnion )
{
BfType * unionInnerType = checkTypeInstance - > GetUnionInnerType ( ) ;
SplatIterate < T > ( dataLambda , unionInnerType ) ;
}
else
{
for ( int fieldIdx = 0 ; fieldIdx < ( int ) checkTypeInstance - > mFieldInstances . size ( ) ; fieldIdx + + )
{
auto fieldInstance = ( BfFieldInstance * ) & checkTypeInstance - > mFieldInstances [ fieldIdx ] ;
if ( fieldInstance - > mDataIdx > = 0 )
{
SplatIterate < T > ( dataLambda , fieldInstance - > GetResolvedType ( ) ) ;
}
}
}
if ( checkTypeInstance - > IsEnum ( ) )
{
// Add discriminator
auto dscrType = checkTypeInstance - > GetDiscriminatorType ( ) ;
dataLambda ( dscrType ) ;
}
}
else if ( checkType - > IsMethodRef ( ) )
{
auto methodRefType = ( BfMethodRefType * ) checkType ;
for ( int dataIdx = 0 ; dataIdx < methodRefType - > GetCaptureDataCount ( ) ; dataIdx + + )
{
if ( methodRefType - > WantsDataPassedAsSplat ( dataIdx ) )
SplatIterate < T > ( dataLambda , methodRefType - > GetCaptureType ( dataIdx ) ) ;
else
dataLambda ( methodRefType - > GetCaptureType ( dataIdx ) ) ;
}
}
else if ( ! checkType - > IsValuelessType ( ) )
{
dataLambda ( checkType ) ;
}
}
static int GetSplatCount ( BfType * type ) ;
} ;
//void DbgCheckType(llvm::Type* checkType);
NS_BF_END
namespace std
{
template < >
struct hash < Beefy : : BfTypeVector >
{
size_t operator ( ) ( const Beefy : : BfTypeVector & val ) const
{
int curHash = 0 ;
for ( auto type : val )
curHash = ( ( curHash ^ type - > mTypeId ) < < 5 ) - curHash ;
return curHash ;
}
} ;
template < >
struct hash < Beefy : : BfFieldRef >
{
size_t operator ( ) ( const Beefy : : BfFieldRef & fieldRef ) const
{
return ( size_t ) fieldRef . mTypeInstance + fieldRef . mFieldIdx ;
}
} ;
template < >
struct hash < Beefy : : BfHotDevirtualizedMethod >
{
size_t operator ( ) ( const Beefy : : BfHotDevirtualizedMethod & val ) const
{
return ( size_t ) val . mMethod ;
}
} ;
template < >
struct hash < Beefy : : BfHotFunctionReference >
{
size_t operator ( ) ( const Beefy : : BfHotFunctionReference & val ) const
{
return ( size_t ) val . mMethod ;
}
} ;
}