2019-08-23 11:56:54 -07:00
# pragma once
# pragma warning(push)
# pragma warning(disable:4141)
# pragma warning(disable:4146)
# pragma warning(disable:4291)
# pragma warning(disable:4244)
# pragma warning(disable:4267)
# pragma warning(disable:4624)
# pragma warning(disable:4800)
# pragma warning(disable:4996)
# include "BeefySysLib/Common.h"
# include "BeefySysLib/util/CritSect.h"
# include "BeefySysLib/util/PerfTimer.h"
# include "BeefySysLib/util/Hash.h"
# include "BeefySysLib/util/HashSet.h"
# include "BeefySysLib/util/SizedArray.h"
2022-04-25 17:53:54 -07:00
# include "BeefySysLib/Span.h"
2019-08-23 11:56:54 -07:00
# include "BfSourceClassifier.h"
# include "BfAst.h"
# include "BfSystem.h"
# include "BfIRBuilder.h"
# include "BfResolvedTypeUtils.h"
# include "BfUtil.h"
# include <unordered_set>
# include <functional>
# pragma warning(pop)
NS_BF_BEGIN
class BfType ;
class BfResolvedType ;
class BfExprEvaluator ;
2021-01-08 16:21:03 -08:00
class CeEmitContext ;
2022-03-08 06:27:06 -08:00
class CeDbgState ;
2022-04-16 07:33:53 -07:00
enum BfCeTypeEmitSourceKind : int8 ;
2019-08-23 11:56:54 -07:00
enum BfPopulateType
2022-05-13 09:43:26 -07:00
{
2019-08-23 11:56:54 -07:00
BfPopulateType_TypeDef ,
BfPopulateType_Identity ,
BfPopulateType_IdentityNoRemapAlias ,
BfPopulateType_Declaration ,
BfPopulateType_BaseType ,
2022-05-13 09:43:26 -07:00
BfPopulateType_Interfaces_Direct ,
2021-01-04 11:24:25 -08:00
BfPopulateType_AllowStaticMethods ,
2022-05-13 09:43:26 -07:00
BfPopulateType_Interfaces_All ,
2022-07-15 08:37:04 -04:00
BfPopulateType_Data_Soft ,
2019-08-23 11:56:54 -07:00
BfPopulateType_Data ,
BfPopulateType_DataAndMethods ,
2020-11-11 05:46:52 -08:00
BfPopulateType_Full = BfPopulateType_DataAndMethods ,
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
BfPopulateType_Full_Force
} ;
2022-07-06 12:19:01 -07:00
enum BfEvalExprFlags : int64
2019-08-23 11:56:54 -07:00
{
BfEvalExprFlags_None = 0 ,
BfEvalExprFlags_ExplicitCast = 1 ,
2022-07-26 13:27:03 -04:00
BfEvalExprFlags_NoCast = 2 ,
BfEvalExprFlags_NoValueAddr = 4 ,
2019-08-23 11:56:54 -07:00
BfEvalExprFlags_PropogateNullConditional = 8 ,
BfEvalExprFlags_IgnoreNullConditional = 0x10 ,
BfEvalExprFlags_AllowSplat = 0x20 ,
BfEvalExprFlags_AllowEnumId = 0x40 ,
BfEvalExprFlags_AllowIntUnknown = 0x80 ,
BfEvalExprFlags_CreateConditionalScope = 0x100 ,
BfEvalExprFlags_PendingPropSet = 0x200 ,
BfEvalExprFlags_AllowParamsExpr = 0x400 ,
BfEvalExprFlags_AllowRefExpr = 0x800 ,
BfEvalExprFlags_AllowOutExpr = 0x1000 ,
BfEvalExprFlags_FieldInitializer = 0x2000 ,
2019-11-02 06:04:26 -07:00
BfEvalExprFlags_VariableDeclaration = 0x4000 ,
2019-11-26 13:11:17 -08:00
BfEvalExprFlags_NoAutoComplete = 0x8000 ,
2020-11-11 05:46:52 -08:00
BfEvalExprFlags_AllowNonConst = 0x10000 ,
2020-12-05 04:29:27 -08:00
BfEvalExprFlags_StringInterpolateFormat = 0x20000 ,
BfEvalExprFlags_NoLookupError = 0x40000 ,
2021-01-08 16:21:03 -08:00
BfEvalExprFlags_Comptime = 0x80000 ,
2021-01-16 06:26:55 -08:00
BfEvalExprFlags_DisallowComptime = 0x100000 ,
BfEvalExprFlags_InCascade = 0x200000 ,
BfEvalExprFlags_InferReturnType = 0x400000 ,
2021-01-18 14:09:16 -08:00
BfEvalExprFlags_WasMethodRef = 0x800000 ,
BfEvalExprFlags_DeclType = 0x1000000 ,
2021-11-15 15:01:48 -08:00
BfEvalExprFlags_AllowBase = 0x2000000 ,
2021-12-29 10:07:36 -05:00
BfEvalExprFlags_NoCeRebuildFlags = 0x4000000 ,
2022-01-17 16:14:40 -05:00
BfEvalExprFlags_FromConversionOp = 0x8000000 ,
BfEvalExprFlags_FromConversionOp_Explicit = 0x10000000 ,
2022-04-18 11:04:45 -07:00
BfEvalExprFlags_AllowGenericConstValue = 0x20000000 ,
2022-04-19 08:26:52 -07:00
BfEvalExprFlags_IsExpressionBody = 0x40000000 ,
2022-06-27 10:55:31 -07:00
BfEvalExprFlags_AppendFieldInitializer = 0x80000000 ,
2022-07-06 12:19:01 -07:00
BfEvalExprFlags_NameOf = 0x100000000LL ,
BfEvalExprFlags_NameOfSuccess = 0x200000000LL ,
2021-01-19 12:33:49 -08:00
BfEvalExprFlags_InheritFlags = BfEvalExprFlags_NoAutoComplete | BfEvalExprFlags_Comptime | BfEvalExprFlags_DeclType
2019-08-23 11:56:54 -07:00
} ;
enum BfCastFlags
{
BfCastFlags_None = 0 ,
BfCastFlags_Explicit = 1 ,
BfCastFlags_Unchecked = 2 ,
BfCastFlags_Internal = 4 ,
BfCastFlags_SilentFail = 8 ,
2020-05-27 09:46:09 -07:00
BfCastFlags_NoBox = 0x10 ,
BfCastFlags_NoBoxDtor = 0x20 ,
2022-02-01 17:28:13 -05:00
BfCastFlags_NoInterfaceImpl = 0x40 ,
BfCastFlags_NoConversionOperator = 0x80 ,
BfCastFlags_FromCompiler = 0x100 , // Not user specified
BfCastFlags_Force = 0x200 ,
BfCastFlags_PreferAddr = 0x400 ,
BfCastFlags_WarnOnBox = 0x800 ,
BfCastFlags_IsCastCheck = 0x1000 ,
2022-02-11 05:47:32 -05:00
BfCastFlags_IsConstraintCheck = 0x2000 ,
2022-06-23 11:53:21 -07:00
BfCastFlags_WantsConst = 0x4000 ,
BfCastFlags_FromComptimeReturn = 0x8000
2019-08-23 11:56:54 -07:00
} ;
2022-04-17 17:46:35 -07:00
enum BfCastResultFlags : int8
2019-08-23 11:56:54 -07:00
{
BfCastResultFlags_None = 0 ,
BfCastResultFlags_IsAddr = 1 ,
BfCastResultFlags_IsTemp = 2
} ;
2022-04-17 17:46:35 -07:00
enum BfAllocFlags : int8
2019-08-23 11:56:54 -07:00
{
BfAllocFlags_None = 0 ,
BfAllocFlags_RawArray = 1 ,
BfAllocFlags_ZeroMemory = 2 ,
BfAllocFlags_NoDtorCall = 4 ,
BfAllocFlags_NoDefaultToMalloc = 8
} ;
2022-04-17 17:46:35 -07:00
enum BfProtectionCheckFlags : int8
2019-08-23 11:56:54 -07:00
{
BfProtectionCheckFlag_None = 0 ,
BfProtectionCheckFlag_CheckedProtected = 1 ,
BfProtectionCheckFlag_CheckedPrivate = 2 ,
BfProtectionCheckFlag_AllowProtected = 4 ,
BfProtectionCheckFlag_AllowPrivate = 8 ,
2020-12-06 07:32:01 -08:00
BfProtectionCheckFlag_InstanceLookup = 0x10
2019-08-23 11:56:54 -07:00
} ;
2022-04-17 17:46:35 -07:00
enum BfEmbeddedStatementFlags : int8
2019-09-12 09:46:54 -07:00
{
BfEmbeddedStatementFlags_None = 0 ,
BfEmbeddedStatementFlags_IsConditional = 1 ,
2021-01-04 06:33:39 -08:00
BfEmbeddedStatementFlags_IsDeferredBlock = 2 ,
BfEmbeddedStatementFlags_Unscoped = 4
2019-09-12 09:46:54 -07:00
} ;
2022-04-17 17:46:35 -07:00
enum BfLocalVarAssignKind : int8
2020-09-21 13:58:00 -07:00
{
BfLocalVarAssignKind_None = 0 ,
BfLocalVarAssignKind_Conditional = 1 ,
2022-07-26 13:27:03 -04:00
BfLocalVarAssignKind_Unconditional = 2
2020-09-21 13:58:00 -07:00
} ;
2019-08-23 11:56:54 -07:00
class BfLocalVariable
{
public :
2022-07-26 13:27:03 -04:00
int64 mUnassignedFieldFlags ;
2019-08-23 11:56:54 -07:00
BfType * mResolvedType ;
BfIdentifierNode * mNameNode ;
String mName ;
BfIRValue mAddr ;
BfIRValue mConstValue ;
BfIRValue mValue ;
2022-07-26 13:27:03 -04:00
BfIRMDNode mDbgVarInst ;
BfIRValue mDbgDeclareInst ;
2019-08-23 11:56:54 -07:00
BfIRBlock mDeclBlock ;
int mLocalVarIdx ; // Index in mLocals
int mLocalVarId ; // Unique Id for identification (does not get reused, unlike mLocalVarIdx)
2022-07-26 13:27:03 -04:00
int mCompositeCount ;
2019-08-23 11:56:54 -07:00
int mWrittenToId ;
int mReadFromId ;
int mParamIdx ;
2021-11-29 08:38:42 -08:00
uint8 mNamePrefixCount ;
2019-08-23 11:56:54 -07:00
bool mIsThis ;
bool mHasLocalStructBacking ;
2022-07-26 13:27:03 -04:00
bool mIsStruct ;
2019-08-23 11:56:54 -07:00
bool mIsImplicitParam ;
bool mParamFailed ;
2020-09-21 13:58:00 -07:00
BfLocalVarAssignKind mAssignedKind ;
bool mHadExitBeforeAssign ;
2019-08-23 11:56:54 -07:00
bool mIsReadOnly ;
2022-02-11 10:38:57 -05:00
bool mIsStatic ;
2019-08-23 11:56:54 -07:00
bool mIsSplat ;
bool mIsLowered ;
bool mAllowAddr ;
bool mIsShadow ;
2022-07-26 13:27:03 -04:00
bool mUsedImplicitly ; // Passed implicitly to a local method, capture by ref if we can
2022-04-17 17:46:35 -07:00
bool mNotCaptured ;
bool mIsConst ;
2022-05-06 11:28:38 -07:00
bool mIsBumpAlloc ;
2019-08-23 11:56:54 -07:00
BfLocalVariable * mShadowedLocal ;
public :
BfLocalVariable ( )
2020-09-21 13:58:00 -07:00
{
2019-08-23 11:56:54 -07:00
mUnassignedFieldFlags = 0 ;
mResolvedType = NULL ;
2020-09-21 13:58:00 -07:00
mNameNode = NULL ;
2019-08-23 11:56:54 -07:00
mLocalVarIdx = - 1 ;
mLocalVarId = - 1 ;
mCompositeCount = - 1 ;
mParamIdx = - 2 ;
2021-11-29 08:38:42 -08:00
mNamePrefixCount = 0 ;
2019-08-23 11:56:54 -07:00
mIsThis = false ;
mHasLocalStructBacking = false ;
2020-09-21 13:58:00 -07:00
mIsStruct = false ;
2019-08-23 11:56:54 -07:00
mIsImplicitParam = false ;
mParamFailed = false ;
2020-09-21 13:58:00 -07:00
mAssignedKind = BfLocalVarAssignKind_None ;
mHadExitBeforeAssign = false ;
2019-08-23 11:56:54 -07:00
mWrittenToId = - 1 ;
mReadFromId = - 1 ;
mIsReadOnly = false ;
2022-02-11 10:38:57 -05:00
mIsStatic = false ;
2019-08-23 11:56:54 -07:00
mIsSplat = false ;
mIsLowered = false ;
mAllowAddr = false ;
mIsShadow = false ;
2022-04-17 17:46:35 -07:00
mUsedImplicitly = false ;
2019-11-26 13:11:17 -08:00
mNotCaptured = false ;
2022-04-17 17:46:35 -07:00
mIsConst = false ;
2022-05-06 11:28:38 -07:00
mIsBumpAlloc = false ;
2019-08-23 11:56:54 -07:00
mShadowedLocal = NULL ;
}
2022-07-26 13:27:03 -04:00
bool IsParam ( )
2019-08-23 11:56:54 -07:00
{
return mParamIdx ! = - 2 ;
}
2022-07-26 13:27:03 -04:00
void Init ( ) ;
2019-08-23 11:56:54 -07:00
} ;
class BfMethodState ;
class BfMixinState ;
class BfClosureState ;
class BfLocalMethod
{
public :
BfSystem * mSystem ;
2022-07-26 13:27:03 -04:00
BfModule * mModule ;
2019-08-23 11:56:54 -07:00
BfSource * mSource ;
BfMethodDeclaration * mMethodDeclaration ;
String mExpectedFullName ;
2022-07-26 13:27:03 -04:00
String mMethodName ;
BfMethodDef * mMethodDef ;
2019-08-23 11:56:54 -07:00
BfLocalMethod * mOuterLocalMethod ;
2022-07-26 13:27:03 -04:00
BfMethodInstanceGroup * mMethodInstanceGroup ;
BfMethodInstance * mLambdaInvokeMethodInstance ;
BfLambdaBindExpression * mLambdaBindExpr ;
2019-08-23 11:56:54 -07:00
BfMethodState * mDeclMethodState ;
BfIRMDNode mDeclDIScope ;
2022-07-26 13:27:03 -04:00
BfMixinState * mDeclMixinState ;
2019-08-23 11:56:54 -07:00
OwnedVector < BfDirectTypeReference > mDirectTypeRefs ;
bool mDeclOnly ;
2020-10-22 06:31:31 -07:00
bool mDidBodyErrorPass ;
2019-08-23 11:56:54 -07:00
BfLocalMethod * mNextWithSameName ;
public :
BfLocalMethod ( )
{
mModule = NULL ;
mSystem = NULL ;
mSource = NULL ;
mMethodDeclaration = NULL ;
mMethodDef = NULL ;
mOuterLocalMethod = NULL ;
mMethodInstanceGroup = NULL ;
mLambdaInvokeMethodInstance = NULL ;
2022-07-26 13:27:03 -04:00
mLambdaBindExpr = NULL ;
2019-08-23 11:56:54 -07:00
mDeclMethodState = NULL ;
2022-07-26 13:27:03 -04:00
mDeclMixinState = NULL ;
2019-08-23 11:56:54 -07:00
mDeclOnly = false ;
2020-10-22 06:31:31 -07:00
mDidBodyErrorPass = false ;
2019-08-23 11:56:54 -07:00
mNextWithSameName = NULL ;
}
~ BfLocalMethod ( ) ;
2020-12-29 12:41:43 -08:00
void Dispose ( ) ;
2019-08-23 11:56:54 -07:00
} ;
class BfDeferredCapture
{
public :
String mName ;
BfTypedValue mValue ;
} ;
class BfDeferredCallEntry
{
public :
BfDeferredCallEntry * mNext ;
BfAstNode * mSrcNode ;
BfTypedValue mTarget ;
BfModuleMethodInstance mModuleMethodInstance ;
BfIRValue mDeferredAlloca ;
2022-01-25 12:05:15 -05:00
SizedArray < BfIRValue , 2 > mOrigScopeArgs ;
SizedArray < BfIRValue , 2 > mScopeArgs ;
2022-07-26 13:27:03 -04:00
Array < BfDeferredCapture > mCaptures ;
2019-08-23 11:56:54 -07:00
BfBlock * mDeferredBlock ;
2021-01-13 05:09:09 -08:00
BfAstNode * mEmitRefNode ;
2019-12-13 14:22:23 -08:00
int64 mBlockId ;
2019-08-23 11:56:54 -07:00
int mHandlerCount ;
bool mBypassVirtual ;
bool mDoNullCheck ;
bool mCastThis ;
bool mArgsNeedLoad ;
bool mIgnored ;
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
SLIList < BfDeferredCallEntry * > mDynList ;
2022-07-26 13:27:03 -04:00
BfIRValue mDynCallTail ;
2019-08-23 11:56:54 -07:00
public :
BfDeferredCallEntry ( )
{
mBypassVirtual = false ;
mDoNullCheck = false ;
mNext = NULL ;
mSrcNode = NULL ;
mDeferredBlock = NULL ;
2021-01-13 05:09:09 -08:00
mEmitRefNode = NULL ;
2019-12-13 14:22:23 -08:00
mBlockId = - 1 ;
2019-08-23 11:56:54 -07:00
mHandlerCount = 0 ;
mArgsNeedLoad = false ;
mCastThis = false ;
mIgnored = false ;
}
~ BfDeferredCallEntry ( )
{
mDynList . DeleteAll ( ) ;
}
bool IsDynList ( )
{
return ( bool ) mDynCallTail ;
}
} ;
struct BfDeferredHandler
{
BfIRBlock mHandlerBlock ;
BfIRBlock mDoneBlock ;
} ;
2020-09-21 13:58:00 -07:00
class BfScopeData ;
struct BfAssignedLocal
{
BfLocalVariable * mLocalVar ;
int mLocalVarField ;
BfLocalVarAssignKind mAssignKind ;
bool operator = = ( const BfAssignedLocal & second ) const
{
return ( mLocalVar = = second . mLocalVar ) & & ( mLocalVarField = = second . mLocalVarField ) & & ( mAssignKind = = second . mAssignKind ) ;
}
} ;
// We use this structure in the case where we have multiple execution paths, then we merge the assigned variables together
// So when we have "if (check) { a = 1; } else {a = 2; }" we can know that a IS definitely assigned afterwards
class BfDeferredLocalAssignData
{
public :
BfScopeData * mScopeData ;
int mVarIdBarrier ;
SizedArray < BfAssignedLocal , 4 > mAssignedLocals ;
bool mIsChained ;
BfDeferredLocalAssignData * mChainedAssignData ;
bool mHadFallthrough ;
bool mHadReturn ;
2021-06-19 11:00:57 -07:00
bool mHadBreak ;
2020-09-21 13:58:00 -07:00
bool mIsUnconditional ;
bool mIsIfCondition ;
bool mIfMayBeSkipped ;
2022-07-26 13:27:03 -04:00
bool mLeftBlock ;
2022-07-05 08:04:38 -07:00
bool mLeftBlockUncond ;
2020-09-21 13:58:00 -07:00
public :
BfDeferredLocalAssignData ( BfScopeData * scopeData = NULL )
{
mScopeData = scopeData ;
mVarIdBarrier = - 1 ;
mHadFallthrough = false ;
mHadReturn = false ;
2021-06-19 11:00:57 -07:00
mHadBreak = false ;
2020-09-21 13:58:00 -07:00
mChainedAssignData = NULL ;
mIsChained = false ;
mIsUnconditional = false ;
mIsIfCondition = false ;
mIfMayBeSkipped = false ;
mLeftBlock = false ;
2022-07-05 08:04:38 -07:00
mLeftBlockUncond = false ;
2020-09-21 13:58:00 -07:00
}
2022-07-26 13:27:03 -04:00
2020-09-22 07:44:47 -07:00
bool Contains ( const BfAssignedLocal & val )
{
for ( int i = 0 ; i < ( int ) mAssignedLocals . mSize ; i + + )
{
auto & check = mAssignedLocals [ i ] ;
if ( ( check . mLocalVar = = val . mLocalVar ) & & ( check . mLocalVarField = = val . mLocalVarField ) & & ( check . mAssignKind > = val . mAssignKind ) )
return true ;
}
return false ;
}
2020-09-21 13:58:00 -07:00
void ExtendFrom ( BfDeferredLocalAssignData * outerLocalAssignData , bool doChain = false ) ;
void BreakExtendChain ( ) ;
void SetIntersection ( const BfDeferredLocalAssignData & otherLocalAssignData ) ;
void Validate ( ) const ;
void SetUnion ( const BfDeferredLocalAssignData & otherLocalAssignData ) ;
} ;
2020-09-21 17:53:22 -07:00
enum BfScopeKind
{
BfScopeKind_Normal ,
BfScopeKind_StatementTarget ,
BfScopeKind_StatementTarget_Conditional ,
} ;
2022-08-24 14:49:05 -07:00
class BfDeferredCallProcessorInstance
{
public :
BfDeferredCallEntry * mDeferredCallEntry ;
BfIRBlock mProcessorBlock ;
BfIRBlock mContinueBlock ;
} ;
2019-08-23 11:56:54 -07:00
// "Looped" means this scope will execute zero to many times, "Conditional" means zero or one.
// Looped and Conditional are mutually exclusive. "Dyn" means Looped OR Conditional.
class BfScopeData
{
public :
2022-07-26 13:27:03 -04:00
BfScopeData * mPrevScope ;
2020-09-21 17:53:22 -07:00
BfScopeKind mScopeKind ;
2019-08-23 11:56:54 -07:00
BfIRMDNode mDIScope ;
2022-07-26 13:27:03 -04:00
BfIRMDNode mDIInlinedAt ;
2019-08-23 11:56:54 -07:00
String mLabel ;
2020-05-29 16:58:47 -07:00
BfIdentifierNode * mLabelNode ;
2022-07-26 13:27:03 -04:00
int mLocalVarStart ;
2019-08-23 11:56:54 -07:00
int mScopeDepth ;
2020-05-29 16:58:47 -07:00
int mMixinDepth ;
int mScopeLocalId ;
2019-08-23 11:56:54 -07:00
bool mIsScopeHead ; // For first scope data or for inlined start
bool mIsLoop ;
bool mIsConditional ; // Rarely set - usually we rely on OuterIsConditional or InnerIsConditional
bool mOuterIsConditional ;
bool mInnerIsConditional ;
bool mHadOuterDynStack ;
2022-07-26 13:27:03 -04:00
bool mAllowTargeting ;
bool mHadScopeValueRetain ;
2019-09-12 09:46:54 -07:00
bool mIsDeferredBlock ;
2020-05-07 11:02:39 -07:00
bool mAllowVariableDeclarations ;
2020-12-04 06:29:25 -08:00
bool mInInitBlock ;
2022-03-19 09:16:51 -07:00
bool mSupressNextUnreachable ;
2022-05-30 11:40:49 -07:00
bool mInConstIgnore ;
2022-07-05 08:04:38 -07:00
bool mIsSharedTempBlock ;
2022-08-24 14:49:05 -07:00
bool mDone ;
2021-10-31 10:39:00 -07:00
BfMixinState * mMixinState ;
2019-08-23 11:56:54 -07:00
BfBlock * mAstBlock ;
BfAstNode * mCloseNode ;
BfExprEvaluator * mExprEvaluator ;
SLIList < BfDeferredCallEntry * > mDeferredCallEntries ;
2022-08-24 14:49:05 -07:00
Array < BfDeferredCallProcessorInstance > mDeferredCallProcessorInstances ;
2019-08-23 11:56:54 -07:00
BfIRValue mBlock ;
BfIRValue mValueScopeStart ;
2022-07-26 13:27:03 -04:00
BfIRValue mSavedStack ;
2019-09-18 13:00:44 -07:00
Array < BfIRValue > mSavedStackUses ;
2019-08-23 11:56:54 -07:00
Array < BfDeferredHandler > mDeferredHandlers ; // These get cleared when us our a parent gets new entries added into mDeferredCallEntries
Array < BfIRBlock > mAtEndBlocks ; // Move these to the end after we close scope
Array < BfIRValue > mDeferredLifetimeEnds ;
2020-09-21 13:58:00 -07:00
BfDeferredLocalAssignData * mExitLocalAssignData ;
2019-08-23 11:56:54 -07:00
BfIRMDNode mAltDIFile ;
2022-07-26 13:27:03 -04:00
BfIRMDNode mAltDIScope ;
2019-08-23 11:56:54 -07:00
2022-07-26 13:27:03 -04:00
public :
2019-08-23 11:56:54 -07:00
BfScopeData ( )
{
2020-09-21 17:53:22 -07:00
mScopeKind = BfScopeKind_Normal ;
2019-08-23 11:56:54 -07:00
mPrevScope = NULL ;
mLocalVarStart = 0 ;
mLabelNode = NULL ;
2021-10-31 10:39:00 -07:00
mMixinState = NULL ;
2019-08-23 11:56:54 -07:00
mAstBlock = NULL ;
mCloseNode = NULL ;
mExprEvaluator = NULL ;
mIsScopeHead = false ;
mIsLoop = false ;
mIsConditional = false ;
mOuterIsConditional = false ;
mInnerIsConditional = false ;
2022-07-26 13:27:03 -04:00
mHadOuterDynStack = false ;
2019-08-23 11:56:54 -07:00
mHadScopeValueRetain = false ;
2019-09-12 09:46:54 -07:00
mIsDeferredBlock = false ;
2022-03-19 09:16:51 -07:00
mSupressNextUnreachable = false ;
2022-07-26 13:27:03 -04:00
mAllowTargeting = true ;
2020-05-07 11:02:39 -07:00
mAllowVariableDeclarations = true ;
2020-12-04 06:29:25 -08:00
mInInitBlock = false ;
2022-05-30 11:40:49 -07:00
mInConstIgnore = false ;
2022-07-05 08:04:38 -07:00
mIsSharedTempBlock = false ;
2022-08-24 14:49:05 -07:00
mDone = false ;
2019-08-23 11:56:54 -07:00
mMixinDepth = 0 ;
mScopeDepth = 0 ;
2020-05-29 16:58:47 -07:00
mScopeLocalId = - 1 ;
2020-09-21 13:58:00 -07:00
mExitLocalAssignData = NULL ;
2022-07-26 13:27:03 -04:00
}
2019-08-23 11:56:54 -07:00
~ BfScopeData ( )
{
mDeferredCallEntries . DeleteAll ( ) ;
2020-09-21 13:58:00 -07:00
delete mExitLocalAssignData ;
2019-08-23 11:56:54 -07:00
}
BfScopeData * GetHead ( )
{
auto checkScope = this ;
while ( ! checkScope - > mIsScopeHead )
checkScope = checkScope - > mPrevScope ;
return checkScope ;
}
BfScopeData * GetTargetable ( )
{
if ( ! mAllowTargeting )
return mPrevScope - > GetTargetable ( ) ;
return this ;
}
bool IsLooped ( BfScopeData * scopeData )
{
auto checkScope = this ;
while ( checkScope ! = NULL )
{
if ( checkScope - > mIsLoop )
return true ;
if ( checkScope = = scopeData )
break ;
checkScope = checkScope - > mPrevScope ;
}
return false ;
}
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
bool IsDyn ( BfScopeData * scopeData )
{
auto checkScope = this ;
// Scoping to a loop is dynamic - it doesn't have to cross the loop boundary.
// Scoping to a loop _body_ is not necessarily dynamic, however.
while ( checkScope ! = NULL )
{
if ( checkScope - > mIsConditional )
return true ;
if ( ( checkScope - > mIsLoop ) | | ( checkScope - > mInnerIsConditional ) )
return true ;
if ( checkScope = = scopeData )
break ;
if ( checkScope - > mOuterIsConditional )
return true ;
checkScope = checkScope - > mPrevScope ;
}
return false ;
}
bool CrossesMixin ( BfScopeData * scopeData )
{
// Check for a transition for having an inlinedAt to not having one
if ( ! mDIInlinedAt )
return false ;
auto checkScope = this ;
while ( checkScope ! = scopeData )
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
checkScope = checkScope - > mPrevScope ;
if ( ! checkScope - > mDIInlinedAt )
return true ;
}
return false ;
}
void ClearHandlers ( BfScopeData * scopeData )
{
auto checkScope = this ;
while ( true )
{
checkScope - > mDeferredHandlers . Clear ( ) ;
if ( checkScope = = scopeData )
break ;
checkScope = checkScope - > mPrevScope ;
2022-07-26 13:27:03 -04:00
}
2019-08-23 11:56:54 -07:00
}
int GetDepth ( )
{
int depth = 0 ;
auto checkScopeData = this ;
while ( true )
{
checkScopeData = checkScopeData - > mPrevScope ;
if ( checkScopeData = = NULL )
break ;
depth + + ;
}
return depth ;
}
2022-06-16 07:21:19 -07:00
bool ExtendLifetime ( BfIRValue irValue )
{
if ( mDeferredLifetimeEnds . Remove ( irValue ) )
{
if ( mPrevScope ! = NULL )
mPrevScope - > mDeferredLifetimeEnds . Add ( irValue ) ;
return true ;
}
return false ;
}
2019-08-23 11:56:54 -07:00
} ;
2019-11-26 13:11:17 -08:00
struct BfCaptureInfo
{
public :
struct Entry
{
BfCaptureType mCaptureType ;
bool mUsed ;
BfIdentifierNode * mNameNode ;
Entry ( )
{
mCaptureType = BfCaptureType_Copy ;
mUsed = false ;
mNameNode = NULL ;
}
} ;
public :
Array < Entry > mCaptures ;
} ;
2019-08-23 11:56:54 -07:00
class BfAllocTarget
{
public :
BfScopeData * mScopeData ;
BfAstNode * mRefNode ;
BfTypedValue mCustomAllocator ;
BfScopedInvocationTarget * mScopedInvocationTarget ;
2019-11-26 13:11:17 -08:00
int mAlignOverride ;
2022-01-29 14:29:25 -05:00
BfCaptureInfo * mCaptureInfo ;
2020-03-09 06:34:16 -07:00
bool mIsFriend ;
2019-08-23 11:56:54 -07:00
public :
BfAllocTarget ( )
{
mScopeData = NULL ;
mRefNode = NULL ;
mCustomAllocator = NULL ;
mScopedInvocationTarget = NULL ;
2019-11-26 13:11:17 -08:00
mAlignOverride = - 1 ;
2020-03-09 06:34:16 -07:00
mIsFriend = false ;
2022-01-29 14:29:25 -05:00
mCaptureInfo = NULL ;
2019-08-23 11:56:54 -07:00
}
BfAllocTarget ( BfScopeData * scopeData )
{
mScopeData = scopeData ;
mRefNode = NULL ;
mCustomAllocator = NULL ;
mScopedInvocationTarget = NULL ;
2019-11-26 13:11:17 -08:00
mAlignOverride = - 1 ;
2019-08-23 11:56:54 -07:00
}
BfAllocTarget ( const BfTypedValue & customAllocator , BfAstNode * refNode )
{
mScopeData = NULL ;
mCustomAllocator = customAllocator ;
mRefNode = NULL ;
mScopedInvocationTarget = NULL ;
2019-11-26 13:11:17 -08:00
mAlignOverride = - 1 ;
2019-08-23 11:56:54 -07:00
}
} ;
class BfBreakData
{
public :
BfBreakData * mPrevBreakData ;
2022-07-26 13:27:03 -04:00
BfScopeData * mScope ;
2019-08-23 11:56:54 -07:00
BfIRBlock mIRContinueBlock ;
BfIRBlock mIRBreakBlock ;
BfIRBlock mIRFallthroughBlock ;
BfIRValue mInnerValueScopeStart ;
bool mHadBreak ;
public :
BfBreakData ( )
{
mPrevBreakData = NULL ;
mScope = NULL ;
mHadBreak = false ;
}
} ;
class BfMixinRecord
{
public :
BfAstNode * mSource ;
} ;
class BfDeferredLocalMethod
{
public :
BfLocalMethod * mLocalMethod ;
BfMethodInstance * mMethodInstance ;
Array < BfLocalMethod * > mLocalMethods ; // Local methods that were in scope at the time
Array < BfLocalVariable > mConstLocals ;
Array < BfMixinRecord > mMixinStateRecords ;
} ;
2021-01-14 06:24:34 -08:00
enum BfReturnTypeInferState
{
BfReturnTypeInferState_None ,
BfReturnTypeInferState_Inferring ,
BfReturnTypeInferState_Fail ,
} ;
2019-08-23 11:56:54 -07:00
class BfClosureState
{
public :
bool mCapturing ;
bool mCaptureVisitingBody ;
int mCaptureStartAccessId ;
// When we need to look into another local method to determine captures, but we don't want to process local variable declarations or cause infinite recursion
bool mBlindCapturing ;
2022-02-15 06:34:37 -05:00
bool mDeclaringMethodIsMutating ;
bool mCapturedDelegateSelf ;
2021-01-14 06:24:34 -08:00
BfReturnTypeInferState mReturnTypeInferState ;
2019-08-23 11:56:54 -07:00
BfLocalMethod * mLocalMethod ;
BfClosureInstanceInfo * mClosureInstanceInfo ;
BfMethodDef * mClosureMethodDef ;
BfType * mReturnType ;
2022-02-15 06:48:27 -05:00
BfTypeInstance * mDelegateType ;
2019-08-23 11:56:54 -07:00
BfTypeInstance * mClosureType ;
BfDeferredLocalMethod * mActiveDeferredLocalMethod ;
Array < BfLocalVariable > mConstLocals ; // Locals not inserted into the captured 'this'
2022-07-26 13:27:03 -04:00
HashSet < BfFieldInstance * > mReferencedOuterClosureMembers ;
2019-08-23 11:56:54 -07:00
HashSet < BfMethodInstance * > mLocalMethodRefSet ;
Array < BfMethodInstance * > mLocalMethodRefs ;
Array < BfMethodInstance * > mDeferredProcessLocalMethods ;
public :
BfClosureState ( )
{
mClosureMethodDef = NULL ;
mLocalMethod = NULL ;
mClosureInstanceInfo = NULL ;
mCapturing = false ;
mCaptureVisitingBody = false ;
mCaptureStartAccessId = - 1 ;
mBlindCapturing = false ;
mDeclaringMethodIsMutating = false ;
2022-02-15 06:34:37 -05:00
mCapturedDelegateSelf = false ;
2021-01-14 06:24:34 -08:00
mReturnTypeInferState = BfReturnTypeInferState_None ;
2022-07-26 13:27:03 -04:00
mActiveDeferredLocalMethod = NULL ;
2019-08-23 11:56:54 -07:00
mReturnType = NULL ;
2022-02-15 06:48:27 -05:00
mDelegateType = NULL ;
2022-07-26 13:27:03 -04:00
mClosureType = NULL ;
2019-08-23 11:56:54 -07:00
}
} ;
class BfIteratorClassState
{
public :
BfTypeInstance * mIteratorClass ;
bool mCapturing ;
public :
BfIteratorClassState ( )
{
mCapturing = false ;
}
} ;
class BfPendingNullConditional
{
public :
BfIRBlock mPrevBB ;
BfIRBlock mCheckBB ;
BfIRBlock mDoneBB ;
2019-12-03 17:35:53 -08:00
SizedArray < BfIRBlock , 4 > mNotNullBBs ;
2019-08-23 11:56:54 -07:00
} ;
class BfAttributeState
2022-07-26 13:27:03 -04:00
{
2020-08-16 08:33:51 -07:00
public :
enum Flags
{
Flag_None ,
Flag_StopOnError = 1 ,
Flag_HadError = 2
} ;
2022-07-26 13:27:03 -04:00
public :
2020-08-16 08:33:51 -07:00
Flags mFlags ;
BfAstNode * mSrc ;
2019-08-23 11:56:54 -07:00
BfAttributeTargets mTarget ;
2022-07-26 13:27:03 -04:00
BfCustomAttributes * mCustomAttributes ;
bool mUsed ;
2019-08-23 11:56:54 -07:00
BfAttributeState ( )
{
2020-08-16 08:33:51 -07:00
mSrc = NULL ;
mFlags = Flag_None ;
2019-08-23 11:56:54 -07:00
mTarget = BfAttributeTargets_None ;
2022-07-26 13:27:03 -04:00
mCustomAttributes = NULL ;
2019-08-23 11:56:54 -07:00
mUsed = false ;
}
~ BfAttributeState ( )
{
if ( mCustomAttributes ! = NULL )
delete mCustomAttributes ;
2022-07-26 13:27:03 -04:00
}
2019-08-23 11:56:54 -07:00
} ;
class BfMixinState
{
2022-07-26 13:27:03 -04:00
public :
2019-08-23 11:56:54 -07:00
BfMixinState * mPrevMixinState ;
BfAstNode * mSource ;
BfScopeData * mCallerScope ;
BfScopeData * mTargetScope ; // Equals caller scope unless user explicitly calls specifies scope override
2021-01-31 10:23:39 -08:00
BfFilePosition mInjectFilePosition ;
2019-08-23 11:56:54 -07:00
BfMethodInstance * mMixinMethodInstance ;
BfAstNode * mResultExpr ;
2022-05-30 11:40:49 -07:00
SizedArray < BfType * , 8 > mArgTypes ;
SizedArray < BfIRValue , 8 > mArgConsts ;
2019-08-23 11:56:54 -07:00
int mLocalsStartIdx ;
bool mUsedInvocationScope ;
bool mHasDeferredUsage ;
2022-05-30 11:40:49 -07:00
bool mCheckedCircularRef ;
bool mDoCircularVarResult ;
2022-07-14 14:08:37 -04:00
bool mUseMixinGenerics ;
2019-08-23 11:56:54 -07:00
BfTypedValue mTarget ;
int mLastTargetAccessId ;
public :
BfMixinState ( )
{
2022-05-30 11:40:49 -07:00
mPrevMixinState = NULL ;
mSource = NULL ;
mCallerScope = NULL ;
mTarget = NULL ;
mMixinMethodInstance = NULL ;
mResultExpr = NULL ;
mLocalsStartIdx = 0 ;
mUsedInvocationScope = false ;
mHasDeferredUsage = false ;
mCheckedCircularRef = false ;
mDoCircularVarResult = false ;
2022-07-14 14:08:37 -04:00
mUseMixinGenerics = false ;
2019-08-23 11:56:54 -07:00
mLastTargetAccessId = - 1 ;
}
BfMixinState * GetRoot ( )
{
auto curMixin = this ;
while ( curMixin - > mPrevMixinState ! = NULL )
curMixin = curMixin - > mPrevMixinState ;
return curMixin ;
}
} ;
class BfDeferredCallEmitState
{
public :
BfAstNode * mCloseNode ;
public :
BfDeferredCallEmitState ( )
{
mCloseNode = NULL ;
}
} ;
class BfTypeLookupError
{
public :
enum BfErrorKind
{
BfErrorKind_None ,
BfErrorKind_Ambiguous ,
BfErrorKind_Inaccessible
} ;
public :
BfErrorKind mErrorKind ;
BfAstNode * mRefNode ;
2022-07-26 13:27:03 -04:00
BfTypeDef * mAmbiguousTypeDef ;
2019-08-23 11:56:54 -07:00
public :
BfTypeLookupError ( )
{
mErrorKind = BfErrorKind_None ;
mRefNode = NULL ;
mAmbiguousTypeDef = NULL ;
}
} ;
/*struct BfSplatDecompHash
{
size_t operator ( ) ( const std : : pair < BfIRValue , int > & val ) const
{
return ( val . first . mId < < 4 ) + val . second ;
}
} ;
struct BfSplatDecompEquals
{
bool operator ( ) ( const std : : pair < BfIRValue , int > & lhs , const std : : pair < BfIRValue , int > & rhs ) const
{
return ( lhs . first . mFlags = = rhs . first . mFlags ) & & ( lhs . first . mId = = rhs . first . mId ) & & ( lhs . second = = rhs . second ) ;
}
} ; */
struct BfMethodRefHash
{
size_t operator ( ) ( const BfMethodRef & val ) const
{
if ( val . mTypeInstance = = NULL )
return 0 ;
return val . mTypeInstance - > mTypeId ^ ( val . mMethodNum < < 10 ) ;
}
} ;
class BfConstResolveState
{
public :
BfMethodInstance * mMethodInstance ;
BfConstResolveState * mPrevConstResolveState ;
2022-06-27 10:55:31 -07:00
bool mInCalcAppend ;
2022-06-27 11:28:38 -07:00
bool mFailed ;
2019-08-23 11:56:54 -07:00
BfConstResolveState ( )
{
mMethodInstance = NULL ;
mPrevConstResolveState = NULL ;
2022-06-27 10:55:31 -07:00
mInCalcAppend = false ;
2022-06-27 11:28:38 -07:00
mFailed = false ;
2019-08-23 11:56:54 -07:00
}
} ;
struct BfLocalVarEntry
{
BfLocalVariable * mLocalVar ;
BfLocalVarEntry ( BfLocalVariable * localVar )
{
mLocalVar = localVar ;
}
bool operator = = ( const BfLocalVarEntry & other ) const
{
return mLocalVar - > mName = = other . mLocalVar - > mName ;
}
bool operator = = ( const StringImpl & name ) const
{
return mLocalVar - > mName = = name ;
}
} ;
class BfLambdaCaptureInfo
{
public :
2022-07-26 13:27:03 -04:00
String mName ;
2019-08-23 11:56:54 -07:00
} ;
class BfLambdaInstance
{
public :
BfTypeInstance * mDelegateTypeInstance ;
BfTypeInstance * mUseTypeInstance ;
BfClosureType * mClosureTypeInstance ;
BfMixinState * mDeclMixinState ;
BfTypeInstance * mOuterClosure ;
BfIRValue mClosureFunc ;
BfIRValue mDtorFunc ;
bool mCopyOuterCaptures ;
2019-12-21 05:44:01 -08:00
bool mDeclaringMethodIsMutating ;
2019-08-23 11:56:54 -07:00
bool mIsStatic ;
Array < BfLambdaCaptureInfo > mCaptures ;
BfMethodInstance * mMethodInstance ;
BfMethodInstance * mDtorMethodInstance ;
Array < BfLocalVariable > mConstLocals ;
OwnedVector < BfParameterDeclaration > mParamDecls ;
public :
BfLambdaInstance ( )
{
mDelegateTypeInstance = NULL ;
mUseTypeInstance = NULL ;
mClosureTypeInstance = NULL ;
mDeclMixinState = NULL ;
mOuterClosure = NULL ;
mCopyOuterCaptures = false ;
2019-12-21 05:44:01 -08:00
mDeclaringMethodIsMutating = false ;
2019-08-23 11:56:54 -07:00
mIsStatic = false ;
mMethodInstance = NULL ;
mDtorMethodInstance = NULL ;
}
~ BfLambdaInstance ( )
{
2020-12-23 08:53:38 -08:00
auto methodDef = mMethodInstance - > mMethodDef ;
2019-08-23 11:56:54 -07:00
delete mMethodInstance ;
2022-07-26 13:27:03 -04:00
delete methodDef ;
2019-08-23 11:56:54 -07:00
if ( mDtorMethodInstance ! = NULL )
{
2020-12-23 08:53:38 -08:00
auto methodDef = mDtorMethodInstance - > mMethodDef ;
delete mDtorMethodInstance ;
delete methodDef ;
2019-08-23 11:56:54 -07:00
}
}
} ;
class BfParentNodeEntry
{
public :
BfAstNode * mNode ;
BfParentNodeEntry * mPrev ;
} ;
class BfMethodState
{
public :
enum TempKind
{
TempKind_None ,
TempKind_Static ,
TempKind_NonStatic
} ;
public :
2019-11-19 09:58:35 -08:00
BumpAllocator mBumpAlloc ;
2019-08-23 11:56:54 -07:00
BfMethodState * mPrevMethodState ; // Only non-null for things like local methods
2022-07-26 13:27:03 -04:00
BfConstResolveState * mConstResolveState ;
BfMethodInstance * mMethodInstance ;
2019-08-23 11:56:54 -07:00
BfHotDataReferenceBuilder * mHotDataReferenceBuilder ;
2022-07-26 13:27:03 -04:00
BfIRFunction mIRFunction ;
2019-08-23 11:56:54 -07:00
BfIRBlock mIRHeadBlock ;
BfIRBlock mIRInitBlock ;
BfIRBlock mIREntryBlock ;
2019-11-19 09:58:35 -08:00
Array < BfLocalVariable * , AllocatorBump < BfLocalVariable * > > mLocals ;
HashSet < BfLocalVarEntry , AllocatorBump < BfLocalVariable * > > mLocalVarSet ;
2022-07-26 13:27:03 -04:00
Array < BfLocalMethod * > mLocalMethods ;
2019-08-23 11:56:54 -07:00
Dictionary < String , BfLocalMethod * > mLocalMethodMap ;
2022-07-26 13:27:03 -04:00
Dictionary < String , BfLocalMethod * > mLocalMethodCache ; // So any lambda 'capturing' and 'processing' stages use the same local method
2019-08-23 11:56:54 -07:00
Array < BfDeferredLocalMethod * > mDeferredLocalMethods ;
OwnedVector < BfMixinState > mMixinStates ;
2020-10-30 09:03:36 -07:00
Dictionary < BfAstNodeList , BfLambdaInstance * > mLambdaCache ;
2019-08-23 11:56:54 -07:00
Array < BfLambdaInstance * > mDeferredLambdaInstances ;
2022-07-26 13:27:03 -04:00
Array < BfIRValue > mSplatDecompAddrs ;
2019-08-23 11:56:54 -07:00
BfDeferredLocalAssignData * mDeferredLocalAssignData ;
2020-07-01 12:06:28 -07:00
BfProjectSet mVisibleProjectSet ;
2019-08-23 11:56:54 -07:00
int mDeferredLoopListCount ;
2022-07-26 13:27:03 -04:00
int mDeferredLoopListEntryCount ;
2019-08-23 11:56:54 -07:00
HashSet < int > mSkipObjectAccessChecks ; // Indexed by BfIRValue value id
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
Dictionary < int64 , BfType * > * mGenericTypeBindings ;
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
BfIRMDNode mDIFile ;
bool mInHeadScope ; // Is in starting scope of code on entry, controls mStackAllocUncondCount
BfTypedValue mRetVal ;
2022-07-26 13:27:03 -04:00
BfIRValue mRetValAddr ;
2019-08-23 11:56:54 -07:00
int mCurAppendAlign ;
BfIRValue mDynStackRevIdx ; // Increments when we restore the stack, which can invalidate dynSize for dynamic looped allocs
BfIRBlock mIRExitBlock ;
BfBreakData * mBreakData ;
2022-07-26 13:27:03 -04:00
int mBlockNestLevel ; // 0 = top level
bool mIgnoreObjectAccessCheck ;
2019-11-28 09:11:54 -08:00
bool mDisableChecks ;
2019-08-23 11:56:54 -07:00
BfMixinState * mMixinState ;
BfClosureState * mClosureState ;
BfDeferredCallEmitState * mDeferredCallEmitState ;
BfIteratorClassState * mIteratorClassState ;
BfPendingNullConditional * mPendingNullConditional ;
2022-07-26 13:27:03 -04:00
BfTypeOptions * mMethodTypeOptions ; // for [Options] attribute
2019-08-23 11:56:54 -07:00
BfIRMDNode mDIRetVal ;
BfScopeData mHeadScope ;
BfScopeData * mCurScope ;
BfScopeData * mTailScope ; // Usually equals mCurScope
2019-11-28 09:11:54 -08:00
BfScopeData * mOverrideScope ;
2021-01-13 05:09:09 -08:00
BfAstNode * mEmitRefNode ;
2019-08-23 11:56:54 -07:00
TempKind mTempKind ; // Used for var inference, etc
2019-09-12 09:46:54 -07:00
bool mInDeferredBlock ;
2019-08-23 11:56:54 -07:00
bool mHadReturn ;
bool mHadContinue ;
bool mMayNeedThisAccessCheck ;
bool mLeftBlockUncond ; // Definitely left block. mHadReturn also sets mLeftBlock
bool mLeftBlockCond ; // May have left block.
2022-07-26 13:27:03 -04:00
bool mInPostReturn ; // Unreachable code
2019-08-23 11:56:54 -07:00
bool mCrossingMixin ; // ie: emitting dtors in response to a return in a mixin
bool mNoBind ;
2022-07-26 13:27:03 -04:00
bool mInConditionalBlock ; // IE: RHS of ((A) && (B)), indicates an allocation in 'B' won't be dominated by a dtor, for example
2019-08-23 11:56:54 -07:00
bool mAllowUinitReads ;
2022-01-29 15:02:19 -05:00
bool mDisableReturns ;
2022-07-26 13:27:03 -04:00
bool mCancelledDeferredCall ;
bool mNoObjectAccessChecks ;
2020-05-29 16:58:47 -07:00
int mCurLocalVarId ; // Can also refer to a label
2019-08-23 11:56:54 -07:00
int mCurAccessId ; // For checking to see if a block reads from or writes to a local
public :
BfMethodState ( )
2019-11-19 09:58:35 -08:00
{
mLocals . mAlloc = & mBumpAlloc ;
2022-07-26 13:27:03 -04:00
mLocalVarSet . mAlloc = & mBumpAlloc ;
mMethodInstance = NULL ;
2019-08-23 11:56:54 -07:00
mPrevMethodState = NULL ;
mConstResolveState = NULL ;
2022-07-26 13:27:03 -04:00
mHotDataReferenceBuilder = NULL ;
2019-08-23 11:56:54 -07:00
mHeadScope . mIsScopeHead = true ;
mCurScope = & mHeadScope ;
mTailScope = & mHeadScope ;
2021-01-13 05:09:09 -08:00
mEmitRefNode = NULL ;
2019-11-28 09:11:54 -08:00
mOverrideScope = NULL ;
2019-08-23 11:56:54 -07:00
mHadReturn = false ;
2022-07-26 13:27:03 -04:00
mLeftBlockUncond = false ;
2019-08-23 11:56:54 -07:00
mLeftBlockCond = false ;
2022-01-29 15:02:19 -05:00
mHadContinue = false ;
2019-08-23 11:56:54 -07:00
mMayNeedThisAccessCheck = false ;
2022-07-26 13:27:03 -04:00
mTempKind = TempKind_None ;
2019-08-23 11:56:54 -07:00
mInHeadScope = true ;
mBreakData = NULL ;
mBlockNestLevel = 0 ;
2022-07-26 13:27:03 -04:00
mInPostReturn = false ;
2019-08-23 11:56:54 -07:00
mCrossingMixin = false ;
2022-07-26 13:27:03 -04:00
mNoBind = false ;
2019-08-23 11:56:54 -07:00
mIgnoreObjectAccessCheck = false ;
2019-11-28 09:11:54 -08:00
mDisableChecks = false ;
2022-01-29 15:02:19 -05:00
mInConditionalBlock = false ;
2019-08-23 11:56:54 -07:00
mAllowUinitReads = false ;
2022-01-29 15:02:19 -05:00
mDisableReturns = false ;
2019-08-23 11:56:54 -07:00
mCancelledDeferredCall = false ;
2022-07-26 13:27:03 -04:00
mNoObjectAccessChecks = false ;
mInDeferredBlock = false ;
2019-08-23 11:56:54 -07:00
mDeferredLocalAssignData = NULL ;
mCurLocalVarId = 0 ;
mCurAccessId = 1 ;
mCurAppendAlign = 0 ;
mDeferredLoopListCount = 0 ;
2022-07-26 13:27:03 -04:00
mDeferredLoopListEntryCount = 0 ;
mClosureState = NULL ;
2019-08-23 11:56:54 -07:00
mDeferredCallEmitState = NULL ;
2022-07-26 13:27:03 -04:00
mIteratorClassState = NULL ;
2019-08-23 11:56:54 -07:00
mGenericTypeBindings = NULL ;
mMixinState = NULL ;
mPendingNullConditional = NULL ;
2022-07-26 13:27:03 -04:00
mMethodTypeOptions = NULL ;
2019-08-23 11:56:54 -07:00
}
~ BfMethodState ( ) ;
void AddScope ( BfScopeData * newScopeData )
{
BF_ASSERT ( newScopeData ! = mCurScope ) ;
mInHeadScope = false ;
newScopeData - > mDIScope = mCurScope - > mDIScope ;
newScopeData - > mDIInlinedAt = mCurScope - > mDIInlinedAt ;
2022-07-26 13:27:03 -04:00
newScopeData - > mLocalVarStart = mCurScope - > mLocalVarStart ;
2019-08-23 11:56:54 -07:00
newScopeData - > mExprEvaluator = mCurScope - > mExprEvaluator ;
newScopeData - > mAltDIFile = mCurScope - > mAltDIFile ;
2022-07-26 13:27:03 -04:00
newScopeData - > mPrevScope = mCurScope ;
newScopeData - > mMixinDepth = mCurScope - > mMixinDepth ;
2019-08-23 11:56:54 -07:00
newScopeData - > mScopeDepth = mCurScope - > mScopeDepth + 1 ;
2022-05-30 11:40:49 -07:00
newScopeData - > mInConstIgnore = mCurScope - > mInConstIgnore ;
2019-08-23 11:56:54 -07:00
mCurScope = newScopeData ;
mTailScope = mCurScope ;
}
void SetHadReturn ( bool hadReturn )
{
mHadReturn = hadReturn ;
if ( mDeferredLocalAssignData ! = NULL )
mDeferredLocalAssignData - > mHadReturn = hadReturn ;
}
BfMethodState * GetRootMethodState ( )
{
auto checkMethodState = this ;
while ( checkMethodState - > mPrevMethodState ! = NULL )
checkMethodState = checkMethodState - > mPrevMethodState ;
return checkMethodState ;
}
BfMethodState * GetNonCaptureState ( )
{
2020-02-19 06:35:52 -08:00
//TODO: Why did this require mLocalMethod to not be null? That means lambda captures we're not crossed over
2019-08-23 11:56:54 -07:00
auto checkMethodState = this ;
2022-07-26 13:27:03 -04:00
while ( ( checkMethodState - > mPrevMethodState ! = NULL ) & & ( checkMethodState - > mClosureState ! = NULL ) & &
2020-02-19 06:35:52 -08:00
( checkMethodState - > mClosureState - > mCapturing ) /*&& (checkMethodState->mClosureState->mLocalMethod != NULL)*/ )
2019-08-23 11:56:54 -07:00
checkMethodState = checkMethodState - > mPrevMethodState ;
return checkMethodState ;
}
BfMethodState * GetMethodStateForLocal ( BfLocalVariable * localVar ) ;
bool InMainMixinScope ( )
{
if ( mMixinState = = NULL )
return false ;
return mMixinState - > mCallerScope = = mCurScope - > mPrevScope ;
}
BfMixinState * GetRootMixinState ( )
{
BfMixinState * mixinState = mMixinState ;
while ( ( mixinState ! = NULL ) & & ( mixinState - > mPrevMixinState ! = NULL ) )
{
mixinState = mixinState - > mPrevMixinState ;
}
return mixinState ;
}
BfAstNode * GetRootMixinSource ( )
{
BfMixinState * mixinState = NULL ;
auto checkMethodState = this ;
while ( checkMethodState ! = NULL )
{
if ( checkMethodState - > mMixinState ! = NULL )
mixinState = checkMethodState - > mMixinState ;
if ( checkMethodState - > mClosureState ! = NULL )
{
auto activeLocalMethod = checkMethodState - > mClosureState - > mActiveDeferredLocalMethod ;
if ( activeLocalMethod ! = NULL )
{
if ( ! activeLocalMethod - > mMixinStateRecords . IsEmpty ( ) )
return activeLocalMethod - > mMixinStateRecords . back ( ) . mSource ;
}
}
checkMethodState = checkMethodState - > mPrevMethodState ;
}
if ( mixinState ! = NULL )
return mixinState - > GetRoot ( ) - > mSource ;
return NULL ;
}
bool HasMixin ( )
{
auto checkMethodState = this ;
while ( checkMethodState ! = NULL )
{
if ( checkMethodState - > mMixinState ! = NULL )
return true ;
checkMethodState = checkMethodState - > mPrevMethodState ;
}
return false ;
}
bool HasNonStaticMixin ( )
{
auto checkMethodState = this ;
while ( checkMethodState ! = NULL )
{
if ( ( checkMethodState - > mMixinState ! = NULL ) & & ( ! checkMethodState - > mMixinState - > mMixinMethodInstance - > mMethodDef - > mIsStatic ) )
return true ;
checkMethodState = checkMethodState - > mPrevMethodState ;
}
return false ;
}
2020-09-21 13:58:00 -07:00
void LocalDefined ( BfLocalVariable * localVar , int fieldIdx = - 1 , BfLocalVarAssignKind assignKind = BfLocalVarAssignKind_None , bool isFromDeferredAssignData = false ) ;
2022-07-26 13:27:03 -04:00
void ApplyDeferredLocalAssignData ( const BfDeferredLocalAssignData & deferredLocalAssignData ) ;
2019-08-23 11:56:54 -07:00
void Reset ( ) ;
int GetLocalStartIdx ( )
{
if ( mMixinState ! = NULL )
return mMixinState - > mLocalsStartIdx ;
return 0 ;
}
2020-06-15 09:00:57 -07:00
bool IsTemporary ( )
{
return mTempKind ! = TempKind_None ;
}
2019-08-23 11:56:54 -07:00
} ;
class BfDeferredMethodCallData ;
enum BfValueFlags
{
BfValueFlags_None = 0 ,
BfValueFlags_Boxed = 1 ,
} ;
enum BfBuiltInFuncType
{
BfBuiltInFuncType_PrintF ,
BfBuiltInFuncType_Malloc ,
2022-07-26 13:27:03 -04:00
BfBuiltInFuncType_Free ,
2019-08-23 11:56:54 -07:00
BfBuiltInFuncType_LoadSharedLibraries ,
BfBuiltInFuncType_Count
} ;
2022-07-26 13:27:03 -04:00
// These are the options that can be applied to individual methods that cause AltModules
// to be build, since they are exclusive to an LLVMModule; LLVM optimization-related
2019-08-23 11:56:54 -07:00
// options always apply to entire LLVM modules
struct BfModuleOptions
{
public :
2022-07-26 13:27:03 -04:00
BfSIMDSetting mSIMDSetting ;
2019-08-23 11:56:54 -07:00
int mEmitDebugInfo ;
BfOptLevel mOptLevel ;
bool operator = = ( const BfModuleOptions & other )
{
return ( mSIMDSetting = = other . mSIMDSetting ) & &
( mEmitDebugInfo = = other . mEmitDebugInfo ) & &
( mOptLevel = = other . mOptLevel ) ;
}
bool operator ! = ( const BfModuleOptions & other )
{
return ! ( * this = = other ) ;
}
2022-03-15 16:33:30 -07:00
BfModuleOptions ( )
{
mSIMDSetting = BfSIMDSetting_None ;
mEmitDebugInfo = false ;
mOptLevel = BfOptLevel_NotSet ;
}
2019-08-23 11:56:54 -07:00
} ;
struct BfGenericParamSource
{
public :
BfTypeInstance * mTypeInstance ;
BfMethodInstance * mMethodInstance ;
bool mCheckAccessibility ;
public :
BfGenericParamSource ( )
{
mTypeInstance = NULL ;
mMethodInstance = NULL ;
mCheckAccessibility = true ;
}
BfGenericParamSource ( BfTypeInstance * typeInstance )
{
mTypeInstance = typeInstance ;
mMethodInstance = NULL ;
mCheckAccessibility = true ;
}
BfGenericParamSource ( BfMethodInstance * methodInstance )
{
mTypeInstance = NULL ;
mMethodInstance = methodInstance ;
mCheckAccessibility = true ;
}
BfTypeInstance * GetTypeInstance ( ) const
{
if ( mTypeInstance ! = NULL )
return mTypeInstance ;
if ( mMethodInstance ! = NULL )
return mMethodInstance - > GetOwner ( ) ;
return NULL ;
}
} ;
class BfAmbiguityContext
{
2022-07-26 13:27:03 -04:00
public :
2019-08-23 11:56:54 -07:00
class Entry
{
public :
BfTypeInterfaceEntry * mInterfaceEntry ;
int mMethodIdx ;
Array < BfMethodInstance * > mCandidates ;
} ;
public :
BfModule * mModule ;
BfTypeInstance * mTypeInstance ;
bool mIsProjectSpecific ;
bool mIsReslotting ;
2022-07-26 13:27:03 -04:00
Dictionary < int , Entry > mEntries ;
2019-08-23 11:56:54 -07:00
public :
BfAmbiguityContext ( )
{
mModule = NULL ;
mTypeInstance = NULL ;
mIsProjectSpecific = false ;
mIsReslotting = false ;
}
void Add ( int id , BfTypeInterfaceEntry * ifaceEntry , int methodIdx , BfMethodInstance * candidateA , BfMethodInstance * candidateB ) ;
void Remove ( int id ) ;
void Finish ( ) ;
} ;
enum BfDefaultValueKind
{
BfDefaultValueKind_Const ,
BfDefaultValueKind_Value ,
BfDefaultValueKind_Addr ,
BfDefaultValueKind_Undef
} ;
class BfModuleFileName
{
public :
Array < BfProject * > mProjects ;
String mFileName ;
bool mModuleWritten ;
bool mWroteToLib ;
bool operator = = ( const BfModuleFileName & second ) const
{
return ( mProjects = = second . mProjects ) & & ( mFileName = = second . mFileName ) ;
}
} ;
class BfGlobalLookup
{
public :
enum Kind
{
Kind_All ,
Kind_Field ,
Kind_Method
} ;
public :
Kind mKind ;
String mName ;
} ;
enum BfSrcPosFlags
{
BfSrcPosFlag_None = 0 ,
BfSrcPosFlag_Expression = 1 ,
BfSrcPosFlag_NoSetDebugLoc = 2 ,
BfSrcPosFlag_Force = 4
} ;
enum BfDeferredBlockFlags
{
BfDeferredBlockFlag_None = 0 ,
BfDeferredBlockFlag_BypassVirtual = 1 ,
BfDeferredBlockFlag_DoNullChecks = 2 ,
BfDeferredBlockFlag_SkipObjectAccessCheck = 4 ,
BfDeferredBlockFlag_MoveNewBlocksToEnd = 8 ,
} ;
2021-12-27 12:55:14 -05:00
enum BfGetCustomAttributesFlags
{
BfGetCustomAttributesFlags_None = 0 ,
BfGetCustomAttributesFlags_AllowNonConstArgs = 1 ,
BfGetCustomAttributesFlags_KeepConstsInModule = 2
} ;
2019-08-23 11:56:54 -07:00
class BfVDataExtEntry
{
public :
BfTypeInstance * mDeclTypeInst ;
BfTypeInstance * mImplTypeInst ;
bool operator = = ( const BfVDataExtEntry & rhs )
{
return ( ( mDeclTypeInst = = rhs . mDeclTypeInst ) & & ( mImplTypeInst = = rhs . mImplTypeInst ) ) ;
}
} ;
2020-05-13 12:30:25 -07:00
# define BFMODULE_FATAL(module, msg) (module)->FatalError((msg), __FILE__, __LINE__)
2021-01-13 05:09:09 -08:00
struct BfCEParseContext
{
int mFailIdx ;
2022-07-26 13:27:03 -04:00
int mWarnIdx ;
2021-01-13 05:09:09 -08:00
} ;
2019-08-23 11:56:54 -07:00
class BfModule : public BfStructuralVisitor
{
public :
enum RebuildKind
{
RebuildKind_None ,
RebuildKind_SkipOnDemandTypes ,
RebuildKind_All
} ;
public :
Val128 mDataHash ;
2020-10-12 10:12:18 -07:00
# ifdef _DEBUG
StringT < 128 > mModuleName ;
# else
2019-08-23 11:56:54 -07:00
String mModuleName ;
2020-10-12 10:12:18 -07:00
# endif
2019-08-23 11:56:54 -07:00
Array < BfModuleFileName > mOutFileNames ;
2022-07-26 13:27:03 -04:00
// SpecializedModules contain method specializations with types that come from other projects
Dictionary < Array < BfProject * > , BfModule * > mSpecializedMethodModules ;
2019-08-23 11:56:54 -07:00
BfModule * mParentModule ;
2022-07-26 13:27:03 -04:00
BfModule * mNextAltModule ; // Linked
BfModuleOptions * mModuleOptions ; // Only in altModules
2019-08-23 11:56:54 -07:00
BfSystem * mSystem ;
BfCompiler * mCompiler ;
BfContext * mContext ;
BfProject * mProject ;
BfIRType mStringLiteralType ;
BfTypeInstance * mCurTypeInstance ;
Dictionary < BfParserData * , BfFileInstance * > mFileInstanceMap ;
Dictionary < String , BfFileInstance * > mNamedFileInstanceMap ;
2022-07-26 13:27:03 -04:00
Array < BfTypeInstance * > mOwnedTypeInstances ;
2019-08-23 11:56:54 -07:00
Dictionary < int , BfIRValue > mStringObjectPool ;
Dictionary < int , BfIRValue > mStringCharPtrPool ;
2022-07-26 13:27:03 -04:00
Array < int > mStringPoolRefs ;
2021-02-25 10:14:22 -08:00
HashSet < int > mUnreifiedStringPoolRefs ;
2022-07-26 13:27:03 -04:00
Array < BfIRBuilder * > mPrevIRBuilders ; // Before extensions
BfIRBuilder * mBfIRBuilder ;
BfMethodState * mCurMethodState ;
BfAttributeState * mAttributeState ;
2019-08-23 11:56:54 -07:00
BfFilePosition mCurFilePosition ;
BfMethodInstance * mCurMethodInstance ;
BfParentNodeEntry * mParentNodeEntry ;
2022-07-26 13:27:03 -04:00
BfIRFunction mBuiltInFuncs [ BfBuiltInFuncType_Count ] ;
2019-08-23 11:56:54 -07:00
Array < BfDllImportEntry > mDllImportEntries ;
Array < int > mImportFileNames ;
2022-07-26 13:27:03 -04:00
Dictionary < BfMethodRef , BfIRValue > mFuncReferences ;
2019-08-23 11:56:54 -07:00
Dictionary < BfFieldRef , BfIRValue > mStaticFieldRefs ;
2022-07-26 13:27:03 -04:00
Dictionary < BfTypeInstance * , BfIRValue > mInterfaceSlotRefs ;
2019-08-23 11:56:54 -07:00
Dictionary < BfTypeInstance * , BfIRValue > mClassVDataRefs ;
Dictionary < BfVDataExtEntry , BfIRValue > mClassVDataExtRefs ;
Dictionary < BfType * , BfIRValue > mTypeDataRefs ;
Dictionary < BfType * , BfIRValue > mDbgRawAllocDataRefs ;
Dictionary < BfMethodInstance * , BfDeferredMethodCallData * > mDeferredMethodCallData ;
HashSet < int64 > mDeferredMethodIds ;
2022-07-26 13:27:03 -04:00
HashSet < BfModule * > mModuleRefs ;
2019-08-23 11:56:54 -07:00
BfIRMDNode mDICompileUnit ;
int mRevision ;
int mRebuildIdx ;
int mLastUsedRevision ;
int mExtensionCount ;
int mIncompleteMethodCount ;
int mOnDemandMethodCount ;
int mLastModuleWrittenRevision ;
int mCurLocalMethodId ;
int16 mUsedSlotCount ; // -1 = not used, 0 = awaiting
bool mAddedToCount ;
bool mHasForceLinkMarker ;
bool mIsReified ;
2021-07-31 09:54:27 -07:00
bool mGeneratesCode ;
2019-08-23 11:56:54 -07:00
bool mReifyQueued ;
bool mWantsIRIgnoreWrites ;
bool mHasGenericMethods ;
bool mIsSpecialModule ; // vdata, unspecialized, external
2021-01-08 16:21:03 -08:00
bool mIsComptimeModule ;
2019-08-23 11:56:54 -07:00
bool mIsScratchModule ;
bool mIsSpecializedMethodModuleRoot ;
2022-07-26 13:27:03 -04:00
bool mIsModuleMutable ; // Set to false after writing module to disk, can be set back to true after doing extension module
2019-08-23 11:56:54 -07:00
bool mWroteToLib ;
bool mHadBuildError ;
2022-07-26 13:27:03 -04:00
bool mHadBuildWarning ;
bool mIgnoreErrors ;
2020-12-05 04:29:27 -08:00
bool mHadIgnoredError ;
2022-07-26 13:27:03 -04:00
bool mIgnoreWarnings ;
bool mSetIllegalSrcPosition ;
2019-08-23 11:56:54 -07:00
bool mReportErrors ; // Still puts system in error state when set to false
bool mIsInsideAutoComplete ;
bool mIsHotModule ;
bool mIsDeleting ;
bool mSkipInnerLookup ;
bool mAwaitingInitFinish ;
bool mAwaitingFinish ;
bool mHasFullDebugInfo ;
bool mNoResolveGenericParams ;
bool mHadHotObjectWrites ;
2022-07-26 13:27:03 -04:00
public :
2020-05-13 12:30:25 -07:00
void FatalError ( const StringImpl & error , const char * file = NULL , int line = - 1 ) ;
2022-07-26 13:27:03 -04:00
void NotImpl ( BfAstNode * astNode ) ;
2019-08-23 11:56:54 -07:00
void AddMethodReference ( const BfMethodRef & methodRef , BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None ) ;
2020-10-14 11:33:41 -07:00
bool CheckProtection ( BfProtection protection , BfTypeDef * checkType , bool allowProtected , bool allowPrivate ) ;
2019-08-23 11:56:54 -07:00
void GetAccessAllowed ( BfTypeInstance * checkType , bool & allowProtected , bool & allowPrivate ) ;
2020-03-09 06:34:16 -07:00
bool CheckProtection ( BfProtectionCheckFlags & flags , BfTypeInstance * memberOwner , BfProject * memberProject , BfProtection memberProtection , BfTypeInstance * lookupStartType ) ;
2022-07-26 13:27:03 -04:00
void SetElementType ( BfAstNode * astNode , BfSourceElementType elementType ) ;
2021-01-11 09:41:43 -08:00
bool PreFail ( ) ;
2020-09-11 10:33:16 -07:00
void SetFail ( ) ;
2021-01-05 13:50:57 -08:00
void VerifyOnDemandMethods ( ) ;
2020-12-13 08:04:42 -08:00
bool IsSkippingExtraResolveChecks ( ) ;
2022-05-26 15:39:32 -07:00
bool AddErrorContext ( StringImpl & errorString , BfAstNode * refNode , BfWhileSpecializingFlags & isWhileSpecializing , bool isWarning ) ;
2022-03-08 06:27:06 -08:00
CeDbgState * GetCeDbgState ( ) ;
2021-01-11 09:41:43 -08:00
BfError * Fail ( const StringImpl & error , BfAstNode * refNode = NULL , bool isPersistent = false , bool deferError = false ) ;
2020-04-04 12:14:52 -07:00
BfError * FailInternal ( const StringImpl & error , BfAstNode * refNode = NULL ) ;
2022-07-26 13:27:03 -04:00
BfError * FailAfter ( const StringImpl & error , BfAstNode * refNode ) ;
2021-11-01 13:46:24 -07:00
BfError * Warn ( int warningNum , const StringImpl & warning , BfAstNode * refNode = NULL , bool isPersistent = false , bool showInSpecialized = false ) ;
2022-08-27 09:23:31 -07:00
void CheckErrorAttributes ( BfTypeInstance * typeInstance , BfMethodInstance * methodInstance , BfFieldInstance * fieldInstance , BfCustomAttributes * customAttributes , BfAstNode * targetSrc ) ;
2019-08-23 11:56:54 -07:00
void CheckRangeError ( BfType * type , BfAstNode * refNode ) ;
2022-07-15 08:37:04 -04:00
bool CheckCircularDataError ( bool failTypes = true ) ;
2019-08-23 11:56:54 -07:00
BfFileInstance * GetFileFromNode ( BfAstNode * astNode ) ;
2022-07-26 13:27:03 -04:00
//void UpdateSrcPos(BfAstNode* astNode, bool setDebugLoc = true, int debugLocOffset = 0, bool force = false);
2019-08-23 11:56:54 -07:00
void UpdateSrcPos ( BfAstNode * astNode , BfSrcPosFlags flags = BfSrcPosFlag_None , int debugLocOffset = 0 ) ;
2022-07-26 13:27:03 -04:00
void UseDefaultSrcPos ( BfSrcPosFlags flags = BfSrcPosFlag_None , int debugLocOffset = 0 ) ;
2019-08-23 11:56:54 -07:00
void UpdateExprSrcPos ( BfAstNode * astNode , BfSrcPosFlags flags = BfSrcPosFlag_None ) ;
void SetIllegalSrcPos ( BfSrcPosFlags flags = BfSrcPosFlag_None ) ;
void SetIllegalExprSrcPos ( BfSrcPosFlags flags = BfSrcPosFlag_None ) ;
2022-07-26 13:27:03 -04:00
void GetConstClassValueParam ( BfIRValue classVData , SizedArrayImpl < BfIRValue > & typeValueParams ) ;
2019-08-23 11:56:54 -07:00
BfIRValue GetConstValue ( int64 val ) ;
BfIRValue GetConstValue ( int64 val , BfType * type ) ;
BfIRValue GetConstValue8 ( int val ) ;
BfIRValue GetConstValue32 ( int32 val ) ;
2022-07-26 13:27:03 -04:00
BfIRValue GetConstValue64 ( int64 val ) ;
BfIRValue GetDefaultValue ( BfType * type ) ;
2019-08-23 11:56:54 -07:00
BfTypedValue GetFakeTypedValue ( BfType * type ) ;
2022-07-26 13:27:03 -04:00
BfTypedValue GetDefaultTypedValue ( BfType * type , bool allowRef = false , BfDefaultValueKind defaultValueKind = BfDefaultValueKind_Const ) ;
2022-02-12 08:05:47 -05:00
void FixConstValueParams ( BfTypeInstance * typeInst , SizedArrayImpl < BfIRValue > & valueParams , bool fillInPadding = false ) ;
2019-08-23 11:56:54 -07:00
BfIRValue CreateStringObjectValue ( const StringImpl & str , int stringId , bool define ) ;
BfIRValue CreateStringCharPtr ( const StringImpl & str , int stringId , bool define ) ;
int GetStringPoolIdx ( BfIRValue constantStr , BfIRConstHolder * constHolder = NULL ) ;
2019-10-09 16:16:01 -07:00
String * GetStringPoolString ( BfIRValue constantStr , BfIRConstHolder * constHolder = NULL ) ;
2021-02-25 10:14:22 -08:00
BfIRValue GetStringCharPtr ( int stringId , bool force = false ) ;
BfIRValue GetStringCharPtr ( BfIRValue strValue , bool force = false ) ;
BfIRValue GetStringCharPtr ( const StringImpl & str , bool force = false ) ;
BfIRValue GetStringObjectValue ( int idx , bool define , bool force ) ;
BfIRValue GetStringObjectValue ( const StringImpl & str , bool define = false , bool force = false ) ;
2022-07-26 13:27:03 -04:00
BfIRValue CreateGlobalConstValue ( const StringImpl & name , BfIRValue constant , BfIRType type , bool external ) ;
2019-08-23 11:56:54 -07:00
void VariantToString ( StringImpl & str , const BfVariant & variant ) ;
2020-02-18 08:43:29 -08:00
StringT < 128 > TypeToString ( BfType * resolvedType , Array < String > * genericMethodParamNameOverrides = NULL ) ;
2022-07-26 13:27:03 -04:00
StringT < 128 > TypeToString ( BfType * resolvedType , BfTypeNameFlags typeNameFlags , Array < String > * genericMethodParamNameOverrides = NULL ) ;
2019-08-23 11:56:54 -07:00
void DoTypeToString ( StringImpl & str , BfType * resolvedType , BfTypeNameFlags typeNameFlags = BfTypeNameFlags_None , Array < String > * genericMethodParamNameOverrides = NULL ) ;
2022-08-27 09:23:31 -07:00
String FieldToString ( BfFieldInstance * fieldInstance ) ;
2021-01-01 15:33:00 -08:00
StringT < 128 > MethodToString ( BfMethodInstance * methodInst , BfMethodNameFlags methodNameFlags = BfMethodNameFlag_ResolveGenericParamNames , BfTypeVector * typeGenericArgs = NULL , BfTypeVector * methodGenericArgs = NULL ) ;
2021-01-13 05:09:09 -08:00
void pt ( BfType * type ) ;
void pm ( BfMethodInstance * type ) ;
2022-06-23 05:20:54 -07:00
BfIRType CurrentAddToConstHolder ( BfIRType irType ) ;
2019-08-23 11:56:54 -07:00
void CurrentAddToConstHolder ( BfIRValue & irVal ) ;
void ClearConstData ( ) ;
2021-02-25 10:14:22 -08:00
bool HasUnactializedConstant ( BfConstant * constant , BfIRConstHolder * constHolder ) ;
2022-07-26 13:27:03 -04:00
BfTypedValue GetTypedValueFromConstant ( BfConstant * constant , BfIRConstHolder * constHolder , BfType * wantType ) ;
2021-02-25 10:14:22 -08:00
BfIRValue ConstantToCurrent ( BfConstant * constant , BfIRConstHolder * constHolder , BfType * wantType , bool allowUnactualized = false ) ;
2019-08-23 11:56:54 -07:00
void ValidateCustomAttributes ( BfCustomAttributes * customAttributes , BfAttributeTargets attrTarget ) ;
2021-12-27 12:55:14 -05:00
void GetCustomAttributes ( BfCustomAttributes * customAttributes , BfAttributeDirective * attributesDirective , BfAttributeTargets attrType , BfGetCustomAttributesFlags flags = BfGetCustomAttributesFlags_None , BfCaptureInfo * captureInfo = NULL ) ;
BfCustomAttributes * GetCustomAttributes ( BfAttributeDirective * attributesDirective , BfAttributeTargets attrType , BfGetCustomAttributesFlags flags = BfGetCustomAttributesFlags_None , BfCaptureInfo * captureInfo = NULL ) ;
2021-01-30 08:08:30 -08:00
BfCustomAttributes * GetCustomAttributes ( BfTypeDef * typeDef ) ;
2020-08-16 15:56:09 -07:00
void FinishAttributeState ( BfAttributeState * attributeState ) ;
2022-02-06 10:49:35 -05:00
void ProcessTypeInstCustomAttributes ( int & packing , bool & isUnion , bool & isCRepr , bool & isOrdered , int & alignOverride , BfType * & underlyingArrayType , int & underlyingArraySize ) ;
2022-07-26 13:27:03 -04:00
void ProcessCustomAttributeData ( ) ;
2019-08-23 11:56:54 -07:00
bool TryGetConstString ( BfIRConstHolder * constHolder , BfIRValue irValue , StringImpl & str ) ;
BfVariant TypedValueToVariant ( BfAstNode * refNode , const BfTypedValue & value , bool allowUndef = false ) ;
2022-07-26 13:27:03 -04:00
BfTypedValue FlushNullConditional ( BfTypedValue result , bool ignoreNullable = false ) ;
void NewScopeState ( bool createLexicalBlock = true , bool flushValueScope = true ) ; // returns prev scope data
2019-08-23 11:56:54 -07:00
BfIRValue CreateAlloca ( BfType * type , bool addLifetime = true , const char * name = NULL , BfIRValue arraySize = BfIRValue ( ) ) ;
BfIRValue CreateAllocaInst ( BfTypeInstance * typeInst , bool addLifetime = true , const char * name = NULL ) ;
2022-01-25 11:43:06 -05:00
BfDeferredCallEntry * AddStackAlloc ( BfTypedValue val , BfIRValue arraySize , BfAstNode * refNode , BfScopeData * scope , bool condAlloca = false , bool mayEscape = false , BfIRBlock valBlock = BfIRBlock ( ) ) ;
2019-08-23 11:56:54 -07:00
void RestoreScoreState_LocalVariables ( ) ;
2022-07-26 13:27:03 -04:00
void RestoreScopeState ( ) ;
2019-08-23 11:56:54 -07:00
void MarkDynStack ( BfScopeData * scope ) ;
void SaveStackState ( BfScopeData * scope ) ;
BfIRValue ValueScopeStart ( ) ;
void ValueScopeEnd ( BfIRValue valueScopeStart ) ;
2020-07-01 12:06:28 -07:00
BfProjectSet * GetVisibleProjectSet ( ) ;
2019-08-23 11:56:54 -07:00
2022-07-26 13:27:03 -04:00
void AddBasicBlock ( BfIRBlock bb , bool activate = true ) ;
2019-09-12 09:46:54 -07:00
void VisitEmbeddedStatement ( BfAstNode * stmt , BfExprEvaluator * exprEvaluator = NULL , BfEmbeddedStatementFlags flags = BfEmbeddedStatementFlags_None ) ;
2019-08-23 11:56:54 -07:00
void VisitCodeBlock ( BfBlock * block ) ;
2022-07-05 08:04:38 -07:00
void VisitCodeBlock ( BfBlock * block , BfIRBlock continueBlock , BfIRBlock breakBlock , BfIRBlock fallthroughBlock , bool defaultBreak , bool * hadReturn = NULL , BfLabelNode * labelNode = NULL , bool closeScope = false , BfEmbeddedStatementFlags flags = BfEmbeddedStatementFlags_None ) ;
2019-08-23 11:56:54 -07:00
void DoForLess ( BfForEachStatement * forEachStmt ) ;
// Util
2022-07-26 13:27:03 -04:00
void CreateReturn ( BfIRValue val ) ;
2020-12-30 13:24:13 -08:00
void EmitReturn ( const BfTypedValue & val ) ;
2019-08-23 11:56:54 -07:00
void EmitDefaultReturn ( ) ;
void EmitDeferredCall ( BfModuleMethodInstance moduleMethodInstance , SizedArrayImpl < BfIRValue > & llvmArgs , BfDeferredBlockFlags flags = BfDeferredBlockFlag_None ) ;
bool AddDeferredCallEntry ( BfDeferredCallEntry * deferredCallEntry , BfScopeData * scope ) ;
2021-01-13 05:09:09 -08:00
BfDeferredCallEntry * AddDeferredBlock ( BfBlock * block , BfScopeData * scope , Array < BfDeferredCapture > * captures = NULL ) ;
2022-07-26 13:27:03 -04:00
BfDeferredCallEntry * AddDeferredCall ( const BfModuleMethodInstance & moduleMethodInstance , SizedArrayImpl < BfIRValue > & llvmArgs , BfScopeData * scope , BfAstNode * srcNode = NULL , bool bypassVirtual = false , bool doNullCheck = false ) ;
2022-08-24 14:49:05 -07:00
void EmitDeferredCall ( BfScopeData * scopeData , BfDeferredCallEntry & deferredCallEntry , bool moveBlocks ) ;
void EmitDeferredCallProcessor ( BfScopeData * scopeData , SLIList < BfDeferredCallEntry * > & callEntries , BfIRValue callTail ) ;
void EmitDeferredCallProcessorInstances ( BfScopeData * scopeData ) ;
2020-01-24 10:36:22 -08:00
bool CanCast ( BfTypedValue typedVal , BfType * toType , BfCastFlags castFlags = BfCastFlags_None ) ;
2019-08-23 11:56:54 -07:00
bool AreSplatsCompatible ( BfType * fromType , BfType * toType , bool * outNeedsMemberCasting ) ;
2022-05-15 17:56:39 -07:00
BfType * GetClosestNumericCastType ( const BfTypedValue & typedVal , BfType * wantType ) ;
2022-02-13 07:41:31 -05:00
BfTypedValue BoxValue ( BfAstNode * srcNode , BfTypedValue typedVal , BfType * toType /*Can be System.Object or interface*/ , const BfAllocTarget & allocTarget , BfCastFlags castFlags = BfCastFlags_None ) ;
2021-07-05 14:36:39 -07:00
BfIRValue CastToFunction ( BfAstNode * srcNode , const BfTypedValue & targetValue , BfMethodInstance * methodInstance , BfType * toType , BfCastFlags castFlags = BfCastFlags_None , BfIRValue irFunc = BfIRValue ( ) ) ;
2019-08-23 11:56:54 -07:00
BfIRValue CastToValue ( BfAstNode * srcNode , BfTypedValue val , BfType * toType , BfCastFlags castFlags = BfCastFlags_None , BfCastResultFlags * resultFlags = NULL ) ;
BfTypedValue Cast ( BfAstNode * srcNode , const BfTypedValue & val , BfType * toType , BfCastFlags castFlags = BfCastFlags_None ) ;
BfPrimitiveType * GetIntCoercibleType ( BfType * type ) ;
BfTypedValue GetIntCoercible ( const BfTypedValue & typedValue ) ;
bool WantsDebugInfo ( ) ;
BfTypeOptions * GetTypeOptions ( ) ;
2020-09-14 11:18:24 -07:00
BfReflectKind GetUserReflectKind ( BfTypeInstance * attrType ) ;
BfReflectKind GetReflectKind ( BfReflectKind reflectKind , BfTypeInstance * typeInstance ) ;
2019-08-23 11:56:54 -07:00
void CleanupFileInstances ( ) ;
void AssertErrorState ( ) ;
void AssertParseErrorState ( ) ;
2022-07-26 13:27:03 -04:00
void InitTypeInst ( BfTypedValue typedValue , BfScopeData * scope , bool zeroMemory , BfIRValue dataSize ) ;
2022-07-16 06:03:35 -04:00
bool IsAllocatorAligned ( ) ;
2019-08-23 11:56:54 -07:00
BfIRValue AllocBytes ( BfAstNode * refNode , const BfAllocTarget & allocTarget , BfType * type , BfIRValue sizeValue , BfIRValue alignValue , BfAllocFlags allocFlags /*bool zeroMemory, bool defaultToMalloc*/ ) ;
BfIRValue GetMarkFuncPtr ( BfType * type ) ;
BfIRValue GetDbgRawAllocData ( BfType * type ) ;
BfIRValue AllocFromType ( BfType * type , const BfAllocTarget & allocTarget , BfIRValue appendSizeValue = BfIRValue ( ) , BfIRValue arraySize = BfIRValue ( ) , int arrayDim = 0 , /*bool isRawArrayAlloc = false, bool zeroMemory = true*/ BfAllocFlags allocFlags = BfAllocFlags_ZeroMemory , int alignOverride = - 1 ) ;
void ValidateAllocation ( BfType * type , BfAstNode * refNode ) ;
2022-07-26 13:27:03 -04:00
bool IsOptimized ( ) ;
2019-08-23 11:56:54 -07:00
void EmitAppendAlign ( int align , int sizeMultiple = 0 ) ;
2022-07-26 13:27:03 -04:00
BfIRValue AppendAllocFromType ( BfType * type , BfIRValue appendSizeValue = BfIRValue ( ) , int appendAllocAlign = 0 , BfIRValue arraySize = BfIRValue ( ) , int arrayDim = 0 , bool isRawArrayAlloc = false , bool zeroMemory = true ) ;
2019-08-23 11:56:54 -07:00
bool IsTargetingBeefBackend ( ) ;
2019-09-18 08:14:38 -07:00
bool WantsLifetimes ( ) ;
2019-08-23 11:56:54 -07:00
bool HasCompiledOutput ( ) ;
2021-12-11 09:08:42 -08:00
bool HasExecutedOutput ( ) ;
2019-08-23 11:56:54 -07:00
void SkipObjectAccessCheck ( BfTypedValue typedVal ) ;
2022-07-26 13:27:03 -04:00
void EmitObjectAccessCheck ( BfTypedValue typedVal ) ;
2019-08-23 11:56:54 -07:00
void EmitEnsureInstructionAt ( ) ;
void EmitDynamicCastCheck ( const BfTypedValue & targetValue , BfType * targetType , BfIRBlock trueBlock , BfIRBlock falseBlock , bool nullSucceeds = false ) ;
void EmitDynamicCastCheck ( BfTypedValue typedVal , BfType * type , bool allowNull ) ;
2022-07-26 13:27:03 -04:00
void CheckStaticAccess ( BfTypeInstance * typeInstance ) ;
2019-08-23 11:56:54 -07:00
BfTypedValue RemoveRef ( BfTypedValue typedValue ) ;
2022-06-15 06:45:53 -07:00
BfTypedValue SanitizeAddr ( BfTypedValue typedValue ) ;
2021-01-26 11:06:17 -08:00
BfTypedValue ToRef ( BfTypedValue typedValue , BfRefType * refType = NULL ) ;
2019-08-23 11:56:54 -07:00
BfTypedValue LoadOrAggregateValue ( BfTypedValue typedValue ) ;
2022-07-26 13:27:03 -04:00
BfTypedValue LoadValue ( BfTypedValue typedValue , BfAstNode * refNode = NULL , bool isVolatile = false ) ;
2020-12-22 04:50:37 -08:00
BfTypedValue PrepareConst ( BfTypedValue & typedValue ) ;
2019-08-23 11:56:54 -07:00
void AggregateSplatIntoAddr ( BfTypedValue typedValue , BfIRValue addrVal ) ;
2022-07-26 13:27:03 -04:00
BfTypedValue AggregateSplat ( BfTypedValue typedValue , BfIRValue * valueArrPtr = NULL ) ;
2022-01-22 07:57:02 -05:00
BfTypedValue MakeAddressable ( BfTypedValue typedValue , bool forceMutable = false , bool forceAddressable = false ) ;
2019-08-23 11:56:54 -07:00
BfTypedValue RemoveReadOnly ( BfTypedValue typedValue ) ;
2021-01-20 08:53:43 -08:00
BfTypedValue CopyValue ( const BfTypedValue & typedValue ) ;
2019-08-23 11:56:54 -07:00
BfIRValue ExtractSplatValue ( BfTypedValue typedValue , int componentIdx , BfType * wantType = NULL , bool * isAddr = NULL ) ;
BfTypedValue ExtractValue ( BfTypedValue typedValue , BfFieldInstance * fieldInst , int fieldIdx ) ;
BfIRValue ExtractValue ( BfTypedValue typedValue , int dataIdx ) ;
BfIRValue CreateIndexedValue ( BfType * elementType , BfIRValue value , BfIRValue indexValue , bool isElementIndex = false ) ;
BfIRValue CreateIndexedValue ( BfType * elementType , BfIRValue value , int indexValue , bool isElementIndex = false ) ;
bool CheckModifyValue ( BfTypedValue & typedValue , BfAstNode * refNode , const char * modifyType = NULL ) ;
BfIRValue GetInterfaceSlotNum ( BfTypeInstance * ifaceType ) ;
void HadSlotCountDependency ( ) ;
2020-09-04 08:09:04 -07:00
BfTypedValue GetCompilerFieldValue ( const StringImpl & str ) ;
2022-03-19 09:16:51 -07:00
BfTypedValue GetCompilerFieldValue ( const BfTypedValue typedVal ) ;
2019-08-23 11:56:54 -07:00
BfTypedValue ReferenceStaticField ( BfFieldInstance * fieldInstance ) ;
2022-04-16 13:22:32 -07:00
BfFieldInstance * GetFieldInstance ( BfTypeInstance * typeInst , int fieldIdx , const char * fieldName = NULL ) ;
2022-02-11 10:38:57 -05:00
BfTypedValue GetThis ( bool markUsing = true ) ;
void MarkUsingThis ( ) ;
2019-08-23 11:56:54 -07:00
BfLocalVariable * GetThisVariable ( ) ;
bool IsInGeneric ( ) ;
2020-04-28 07:30:45 -07:00
bool InDefinitionSection ( ) ;
2019-08-23 11:56:54 -07:00
bool IsInSpecializedGeneric ( ) ;
bool IsInSpecializedSection ( ) ; // Either a specialized generic or an injected mixin
bool IsInUnspecializedGeneric ( ) ;
// BfStmtEvaluator.cpp
virtual void Visit ( BfAstNode * astNode ) override ;
virtual void Visit ( BfIdentifierNode * identifierNode ) override ;
virtual void Visit ( BfTypeReference * typeRef ) override ;
virtual void Visit ( BfEmptyStatement * astNode ) override ;
2022-07-26 13:27:03 -04:00
virtual void Visit ( BfExpression * expressionStmt ) override ;
2019-08-23 11:56:54 -07:00
virtual void Visit ( BfExpressionStatement * expressionStmt ) override ;
virtual void Visit ( BfVariableDeclaration * varDecl ) override ;
virtual void Visit ( BfLocalMethodDeclaration * methodDecl ) override ;
2020-08-16 08:33:51 -07:00
virtual void Visit ( BfAttributedStatement * attribStmt ) override ;
2019-08-23 11:56:54 -07:00
virtual void Visit ( BfThrowStatement * throwStmt ) override ;
2022-07-26 13:27:03 -04:00
virtual void Visit ( BfDeleteStatement * deleteStmt ) override ;
2019-08-23 11:56:54 -07:00
virtual void Visit ( BfSwitchStatement * switchStmt ) override ;
virtual void Visit ( BfTryStatement * tryStmt ) override ;
virtual void Visit ( BfCatchStatement * catchStmt ) override ;
virtual void Visit ( BfFinallyStatement * finallyStmt ) override ;
virtual void Visit ( BfCheckedStatement * checkedStmt ) override ;
virtual void Visit ( BfUncheckedStatement * uncheckedStmt ) override ;
void DoIfStatement ( BfIfStatement * ifStmt , bool includeTrueStmt , bool includeFalseStmt ) ;
2022-07-26 13:27:03 -04:00
virtual void Visit ( BfIfStatement * ifStmt ) override ;
2019-08-23 11:56:54 -07:00
virtual void Visit ( BfReturnStatement * returnStmt ) override ;
virtual void Visit ( BfYieldStatement * yieldStmt ) override ;
virtual void Visit ( BfBreakStatement * breakStmt ) override ;
virtual void Visit ( BfContinueStatement * continueStmt ) override ;
virtual void Visit ( BfFallthroughStatement * fallthroughStmt ) override ;
virtual void Visit ( BfUsingStatement * usingStmt ) override ;
virtual void Visit ( BfDoStatement * doStmt ) override ;
virtual void Visit ( BfRepeatStatement * doStmt ) override ;
virtual void Visit ( BfWhileStatement * whileStmt ) override ;
virtual void Visit ( BfForStatement * forStmt ) override ;
virtual void Visit ( BfForEachStatement * forEachStmt ) override ;
virtual void Visit ( BfDeferStatement * deferStmt ) override ;
virtual void Visit ( BfBlock * block ) override ;
2021-01-04 06:33:39 -08:00
virtual void Visit ( BfUnscopedBlock * block ) override ;
2019-10-14 14:08:29 -07:00
virtual void Visit ( BfLabeledBlock * labeledBlock ) override ;
2019-08-23 11:56:54 -07:00
virtual void Visit ( BfRootNode * rootNode ) override ;
virtual void Visit ( BfInlineAsmStatement * asmStmt ) override ;
2022-07-26 13:27:03 -04:00
// Type helpers
2020-06-05 07:01:58 -07:00
BfGenericExtensionEntry * BuildGenericExtensionInfo ( BfTypeInstance * genericTypeInst , BfTypeDef * partialTypeDef ) ;
2020-09-18 17:00:33 -07:00
bool InitGenericParams ( BfType * resolvedTypeRef ) ;
bool FinishGenericParams ( BfType * resolvedTypeRef ) ;
2022-02-04 12:00:43 -05:00
bool ValidateGenericConstraints ( BfAstNode * typeRef , BfTypeInstance * genericTypeInstance , bool ignoreErrors ) ;
2021-11-23 09:12:10 -08:00
BfType * ResolveGenericMethodTypeRef ( BfTypeReference * typeRef , BfMethodInstance * methodInstance , BfGenericParamInstance * genericParamInstance , BfTypeVector * methodGenericArgsOverride ) ;
2019-08-23 11:56:54 -07:00
bool AreConstraintsSubset ( BfGenericParamInstance * checkInner , BfGenericParamInstance * checkOuter ) ;
2019-11-21 08:23:18 -08:00
bool CheckConstraintState ( BfAstNode * refNode ) ;
2022-04-25 17:53:54 -07:00
void ValidateGenericParams ( BfGenericParamKind genericParamKind , Span < BfGenericParamInstance * > genericParams ) ;
2019-08-23 11:56:54 -07:00
bool ShouldAllowMultipleDefinitions ( BfTypeInstance * typeInst , BfTypeDef * firstDeclaringTypeDef , BfTypeDef * secondDeclaringTypeDef ) ;
2019-11-17 09:28:39 -08:00
void CheckInjectNewRevision ( BfTypeInstance * typeInstance ) ;
2020-08-12 07:42:13 -07:00
void InitType ( BfType * resolvedTypeRef , BfPopulateType populateType ) ;
2020-03-09 06:34:16 -07:00
BfProtection FixProtection ( BfProtection protection , BfProject * defProject ) ;
2020-10-14 11:33:41 -07:00
bool CheckAccessMemberProtection ( BfProtection protection , BfTypeInstance * memberType ) ;
2022-07-26 13:27:03 -04:00
bool CheckDefineMemberProtection ( BfProtection protection , BfType * memberType ) ;
void CheckMemberNames ( BfTypeInstance * typeInst ) ;
2022-03-19 12:24:56 -07:00
void AddDependency ( BfType * usedType , BfType * userType , BfDependencyMap : : DependencyFlags flags , BfDepContext * depContext = NULL ) ;
2022-01-01 10:39:25 -05:00
void AddDependency ( BfGenericParamInstance * genericParam , BfTypeInstance * usingType ) ;
2019-08-23 11:56:54 -07:00
void AddCallDependency ( BfMethodInstance * methodInstance , bool devirtualized = false ) ;
2022-07-26 13:27:03 -04:00
void AddFieldDependency ( BfTypeInstance * typeInstance , BfFieldInstance * fieldInstance , BfType * fieldType ) ;
2019-08-23 11:56:54 -07:00
void TypeFailed ( BfTypeInstance * typeInstance ) ;
bool IsAttribute ( BfTypeInstance * typeInst ) ;
void PopulateGlobalContainersList ( const BfGlobalLookup & globalLookup ) ;
2020-06-02 05:46:56 -07:00
BfStaticSearch * GetStaticSearch ( ) ;
2020-10-14 11:33:41 -07:00
BfInternalAccessSet * GetInternalAccessSet ( ) ;
bool CheckInternalProtection ( BfTypeDef * usingTypeDef ) ;
2019-08-23 11:56:54 -07:00
void AddFailType ( BfTypeInstance * typeInstance ) ;
2021-01-08 16:21:03 -08:00
void DeferRebuildType ( BfTypeInstance * typeInstance ) ;
2019-08-23 11:56:54 -07:00
void MarkDerivedDirty ( BfTypeInstance * typeInst ) ;
void CheckAddFailType ( ) ;
2020-08-12 07:42:13 -07:00
void PopulateType ( BfType * resolvedTypeRef , BfPopulateType populateType = BfPopulateType_Data ) ;
2020-07-11 16:24:07 -07:00
BfTypeOptions * GetTypeOptions ( BfTypeDef * typeDef ) ;
2020-07-14 08:27:25 -07:00
bool ApplyTypeOptionMethodFilters ( bool includeMethod , BfMethodDef * methodDef , BfTypeOptions * typeOptions ) ;
2019-08-23 11:56:54 -07:00
int GenerateTypeOptions ( BfCustomAttributes * customAttributes , BfTypeInstance * typeInstance , bool checkTypeName ) ;
void SetTypeOptions ( BfTypeInstance * typeInstance ) ;
BfModuleOptions GetModuleOptions ( ) ;
BfCheckedKind GetDefaultCheckedKind ( ) ;
2021-01-13 05:09:09 -08:00
void FinishCEParseContext ( BfAstNode * refNode , BfTypeInstance * typeInstance , BfCEParseContext * ceParseContext ) ;
2022-04-16 06:27:54 -07:00
BfCEParseContext CEEmitParse ( BfTypeInstance * typeInstance , BfTypeDef * declaringType , const StringImpl & src , BfAstNode * refNode , BfCeTypeEmitSourceKind emitSourceKind ) ;
void UpdateCEEmit ( CeEmitContext * ceEmitContext , BfTypeInstance * typeInstance , BfTypeDef * declaringType , const StringImpl & ctxString , BfAstNode * refNode , BfCeTypeEmitSourceKind emitSourceKind ) ;
2022-02-11 05:47:32 -05:00
void HandleCEAttributes ( CeEmitContext * ceEmitContext , BfTypeInstance * typeInst , BfFieldInstance * fieldInstance , BfCustomAttributes * customAttributes , Dictionary < BfTypeInstance * , BfIRValue > & foundAttributes , bool underlyingTypeDeferred ) ;
2021-01-13 05:09:09 -08:00
void CEMixin ( BfAstNode * refNode , const StringImpl & src ) ;
2021-12-21 12:52:51 -05:00
void ExecuteCEOnCompile ( CeEmitContext * ceEmitContext , BfTypeInstance * typeInst , BfCEOnCompileKind onCompileKind , bool underlyingTypeDeferred ) ;
void DoCEEmit ( BfTypeInstance * typeInstance , bool & hadNewMembers , bool underlyingTypeDeferred ) ;
2021-01-13 05:09:09 -08:00
void DoCEEmit ( BfMethodInstance * methodInstance ) ;
2022-07-10 07:50:08 -04:00
void PopulateUsingFieldData ( BfTypeInstance * typeInstance ) ;
2022-02-16 18:28:23 -05:00
void DoPopulateType_TypeAlias ( BfTypeAliasType * typeAlias ) ;
2022-01-14 07:30:26 -05:00
void DoPopulateType_InitSearches ( BfTypeInstance * typeInstance ) ;
2022-07-26 13:27:03 -04:00
void DoPopulateType_SetGenericDependencies ( BfTypeInstance * genericTypeInstance ) ;
2021-12-21 12:52:51 -05:00
void DoPopulateType_FinishEnum ( BfTypeInstance * typeInstance , bool underlyingTypeDeferred , HashContext * dataMemberHashCtx , BfType * unionInnerType ) ;
2022-07-26 13:27:03 -04:00
void DoPopulateType_CeCheckEnum ( BfTypeInstance * typeInstance , bool underlyingTypeDeferred ) ;
2020-08-12 07:42:13 -07:00
void DoPopulateType ( BfType * resolvedTypeRef , BfPopulateType populateType = BfPopulateType_Data ) ;
2019-08-23 11:56:54 -07:00
static BfModule * GetModuleFor ( BfType * type ) ;
void DoTypeInstanceMethodProcessing ( BfTypeInstance * typeInstance ) ;
void RebuildMethods ( BfTypeInstance * typeInstance ) ;
2020-04-04 12:14:52 -07:00
BfFieldInstance * GetFieldByName ( BfTypeInstance * typeInstance , const StringImpl & fieldName , bool isRequired = true , BfAstNode * refNode = NULL ) ;
2019-08-23 11:56:54 -07:00
void CreateStaticField ( BfFieldInstance * fieldInstance , bool isThreadLocal = false ) ;
void ResolveConstField ( BfTypeInstance * typeInst , BfFieldInstance * fieldInstance , BfFieldDef * field , bool forceResolve = false ) ;
2020-06-13 08:36:39 -07:00
BfTypedValue GetFieldInitializerValue ( BfFieldInstance * fieldInstance , BfExpression * initializer = NULL , BfFieldDef * fieldDef = NULL , BfType * fieldType = NULL , bool doStore = false ) ;
2022-06-27 10:55:31 -07:00
void AppendedObjectInit ( BfFieldInstance * fieldInstance ) ;
2019-08-23 11:56:54 -07:00
void MarkFieldInitialized ( BfFieldInstance * fieldInstance ) ;
bool IsThreadLocal ( BfFieldInstance * fieldInstance ) ;
2022-07-26 13:27:03 -04:00
BfType * ResolveVarFieldType ( BfTypeInstance * typeInst , BfFieldInstance * fieldInstance , BfFieldDef * field ) ;
2019-08-23 11:56:54 -07:00
void FindSubTypes ( BfTypeInstance * classType , SizedArrayImpl < int > * outVals , SizedArrayImpl < BfTypeInstance * > * exChecks , bool isInterfacePass ) ;
2020-06-05 07:01:58 -07:00
BfType * CheckUnspecializedGenericType ( BfTypeInstance * genericTypeInst , BfPopulateType populateType ) ;
2019-08-23 11:56:54 -07:00
BfTypeInstance * GetUnspecializedTypeInstance ( BfTypeInstance * typeInst ) ;
BfArrayType * CreateArrayType ( BfType * resolvedType , int dimensions ) ;
BfSizedArrayType * CreateSizedArrayType ( BfType * resolvedType , int size ) ;
BfUnknownSizedArrayType * CreateUnknownSizedArrayType ( BfType * resolvedType , BfType * sizeParam ) ;
BfPointerType * CreatePointerType ( BfType * resolvedType ) ;
BfPointerType * CreatePointerType ( BfTypeReference * typeRef ) ;
2020-09-15 14:06:10 -07:00
BfConstExprValueType * CreateConstExprValueType ( const BfTypedValue & typedValue , bool allowCreate = true ) ;
2022-02-05 09:23:44 -05:00
BfConstExprValueType * CreateConstExprValueType ( const BfVariant & variant , BfType * type , bool allowCreate = true ) ;
2020-09-14 06:54:49 -07:00
BfBoxedType * CreateBoxedType ( BfType * resolvedTypeRef , bool allowCreate = true ) ;
2020-07-20 07:17:33 -07:00
BfTypeInstance * CreateTupleType ( const BfTypeVector & fieldTypes , const Array < String > & fieldNames , bool allowVar = false ) ;
2020-06-04 15:02:46 -07:00
BfTypeInstance * SantizeTupleType ( BfTypeInstance * tupleType ) ;
2019-08-23 11:56:54 -07:00
BfRefType * CreateRefType ( BfType * resolvedTypeRef , BfRefType : : RefKind refKind = BfRefType : : RefKind_Ref ) ;
2020-04-27 15:09:10 -07:00
BfModifiedTypeType * CreateModifiedTypeType ( BfType * resolvedTypeRef , BfToken modifiedKind ) ;
2019-08-23 11:56:54 -07:00
BfConcreteInterfaceType * CreateConcreteInterfaceType ( BfTypeInstance * interfaceType ) ;
BfTypeInstance * GetWrappedStructType ( BfType * type , bool allowSpecialized = true ) ;
BfTypeInstance * GetPrimitiveStructType ( BfTypeCode typeCode ) ;
2022-07-26 13:27:03 -04:00
BfPrimitiveType * GetPrimitiveType ( BfTypeCode typeCode ) ;
2020-06-10 07:12:07 -07:00
BfIRType GetIRLoweredType ( BfTypeCode loweredTypeCode , BfTypeCode loweredTypeCode2 ) ;
2019-08-23 11:56:54 -07:00
BfMethodRefType * CreateMethodRefType ( BfMethodInstance * methodInstance , bool mustAlreadyExist = false ) ;
BfType * FixIntUnknown ( BfType * type ) ;
2022-05-15 17:56:39 -07:00
void FixIntUnknown ( BfTypedValue & typedVal , BfType * matchType = NULL ) ;
void FixIntUnknown ( BfTypedValue & lhs , BfTypedValue & rhs ) ;
2021-02-25 10:14:22 -08:00
void FixValueActualization ( BfTypedValue & typedVal , bool force = false ) ;
2020-05-29 16:10:16 -07:00
bool TypeEquals ( BfTypedValue & val , BfType * type ) ;
2020-09-03 10:24:42 -07:00
BfTypeDef * ResolveGenericInstanceDef ( BfGenericInstanceTypeRef * genericTypeRef , BfType * * outType = NULL , BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None ) ;
2020-09-14 06:54:49 -07:00
BfType * ResolveType ( BfType * lookupType , BfPopulateType populateType = BfPopulateType_Data , BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None ) ;
2021-02-25 10:14:22 -08:00
void ResolveGenericParamConstraints ( BfGenericParamInstance * genericParamInstance , bool isUnspecialized , Array < BfTypeReference * > * deferredResolveTypes = NULL ) ;
2019-08-23 11:56:54 -07:00
String GenericParamSourceToString ( const BfGenericParamSource & genericParamSource ) ;
bool CheckGenericConstraints ( const BfGenericParamSource & genericParamSource , BfType * checkArgType , BfAstNode * checkArgTypeRef , BfGenericParamInstance * genericParamInst , BfTypeVector * methodGenericArgs = NULL , BfError * * errorOut = NULL ) ;
BfIRValue AllocLocalVariable ( BfType * type , const StringImpl & name , bool doLifetimeEnd = true ) ;
void DoAddLocalVariable ( BfLocalVariable * localVar ) ;
2020-06-20 17:25:37 -07:00
void DoLocalVariableDebugInfo ( BfLocalVariable * localVar , bool doAliasValue = false , BfIRValue declareBefore = BfIRValue ( ) , BfIRInitType initType = BfIRInitType_NotSet ) ;
2022-07-26 13:27:03 -04:00
BfLocalVariable * AddLocalVariableDef ( BfLocalVariable * localVarDef , bool addDebugInfo = false , bool doAliasValue = false , BfIRValue declareBefore = BfIRValue ( ) , BfIRInitType initType = BfIRInitType_NotSet ) ;
2019-08-23 11:56:54 -07:00
bool TryLocalVariableInit ( BfLocalVariable * localVar ) ;
void LocalVariableDone ( BfLocalVariable * localVar , bool isMethodExit ) ;
2021-01-16 12:35:51 -08:00
void CreateRetValLocal ( ) ;
2019-08-23 11:56:54 -07:00
void CreateDIRetVal ( ) ;
2021-01-02 08:11:07 -08:00
BfTypedValue CreateTuple ( const Array < BfTypedValue > & values , const Array < String > & fieldNames ) ;
2019-08-23 11:56:54 -07:00
void CheckTupleVariableDeclaration ( BfTupleExpression * tupleExpr , BfType * initType ) ;
void HandleTupleVariableDeclaration ( BfVariableDeclaration * varDecl , BfTupleExpression * tupleExpr , BfTypedValue initTupleValue , bool isReadOnly , bool isConst , bool forceAddr , BfIRBlock * declBlock = NULL ) ;
void HandleTupleVariableDeclaration ( BfVariableDeclaration * varDecl ) ;
2022-07-26 13:27:03 -04:00
void HandleCaseEnumMatch_Tuple ( BfTypedValue tupleVal , const BfSizedArray < BfExpression * > & arguments , BfAstNode * tooFewRef , BfIRValue phiVal , BfIRBlock & matchedBlockStart ,
2022-05-24 06:52:28 -07:00
BfIRBlock & matchedBlockEnd , BfIRBlock & falseBlockStart , BfIRBlock & falseBlockEnd , bool & hadConditional , bool clearOutOnMismatch , bool prevHadFallthrough ) ;
BfTypedValue TryCaseTupleMatch ( BfTypedValue tupleVal , BfTupleExpression * tupleExpr , BfIRBlock * eqBlock , BfIRBlock * notEqBlock , BfIRBlock * matchBlock , bool & hadConditional , bool clearOutOnMismatch , bool prevHadFallthrough ) ;
BfTypedValue TryCaseEnumMatch ( BfTypedValue enumVal , BfTypedValue tagVal , BfExpression * expr , BfIRBlock * eqBlock , BfIRBlock * notEqBlock , BfIRBlock * matchBlock , int & uncondTagId , bool & hadConditional , bool clearOutOnMismatch , bool prevHadFallthrough ) ;
2019-08-23 11:56:54 -07:00
BfTypedValue HandleCaseBind ( BfTypedValue enumVal , const BfTypedValue & tagVal , BfEnumCaseBindExpression * bindExpr , BfIRBlock * eqBlock = NULL , BfIRBlock * notEqBlock = NULL , BfIRBlock * matchBlock = NULL , int * outEnumIdx = NULL ) ;
void TryInitVar ( BfAstNode * checkNode , BfLocalVariable * varDecl , BfTypedValue initValue , BfTypedValue & checkResult ) ;
BfLocalVariable * HandleVariableDeclaration ( BfVariableDeclaration * varDecl , BfExprEvaluator * exprEvaluator = NULL ) ;
2022-06-24 09:25:43 -07:00
BfLocalVariable * HandleVariableDeclaration ( BfType * type , BfAstNode * nameNode , BfTypedValue val , bool updateSrcLoc = true , bool forceAddr = false ) ;
2019-08-23 11:56:54 -07:00
BfLocalVariable * HandleVariableDeclaration ( BfVariableDeclaration * varDecl , BfTypedValue val , bool updateSrcLoc = true , bool forceAddr = false ) ;
2022-07-26 13:27:03 -04:00
void CheckVariableDef ( BfLocalVariable * variableDef ) ;
2019-09-12 09:46:54 -07:00
BfScopeData * FindScope ( BfAstNode * scopeName , BfMixinState * curMixinState , bool allowAcrossDeferredBlock ) ;
BfScopeData * FindScope ( BfAstNode * scopeName , bool allowAcrossDeferredBlock ) ;
2019-08-23 11:56:54 -07:00
BfBreakData * FindBreakData ( BfAstNode * scopeName ) ;
void EmitLifetimeEnds ( BfScopeData * scopeData ) ;
void ClearLifetimeEnds ( ) ;
2022-07-26 13:27:03 -04:00
bool HasDeferredScopeCalls ( BfScopeData * scope ) ;
void EmitDeferredScopeCalls ( bool useSrcPositions , BfScopeData * scope , BfIRBlock doneBlock = BfIRBlock ( ) ) ;
2022-02-14 07:25:20 -05:00
void MarkScopeLeft ( BfScopeData * scopeData , bool isNoReturn = false ) ;
2019-08-23 11:56:54 -07:00
BfGenericParamType * GetGenericParamType ( BfGenericParamKind paramKind , int paramIdx ) ;
2022-04-30 08:10:57 -07:00
BfType * ResolveGenericType ( BfType * unspecializedType , BfTypeVector * typeGenericArguments , BfTypeVector * methodGenericArguments , BfType * selfType , bool allowFail = false ) ;
BfType * ResolveSelfType ( BfType * type , BfType * selfType ) ;
2019-08-23 11:56:54 -07:00
bool IsUnboundGeneric ( BfType * type ) ;
2019-11-17 09:28:39 -08:00
BfGenericParamInstance * GetGenericTypeParamInstance ( int paramIdx ) ;
2022-07-14 07:44:19 -04:00
BfGenericParamInstance * GetGenericParamInstance ( BfGenericParamType * type , bool checkMixinBind = false ) ;
2020-08-10 13:29:05 -07:00
void GetActiveTypeGenericParamInstances ( SizedArray < BfGenericParamInstance * , 4 > & genericParamInstance ) ;
2021-10-31 08:21:30 -07:00
BfGenericParamInstance * GetMergedGenericParamData ( BfGenericParamType * type , BfGenericParamFlags & outFlags , BfType * & outTypeConstraint ) ;
2019-08-23 11:56:54 -07:00
BfTypeInstance * GetBaseType ( BfTypeInstance * typeInst ) ;
void HandleTypeGenericParamRef ( BfAstNode * refNode , BfTypeDef * typeDef , int typeGenericParamIdx ) ;
void HandleMethodGenericParamRef ( BfAstNode * refNode , BfTypeDef * typeDef , BfMethodDef * methodDef , int typeGenericParamIdx ) ;
2022-03-19 10:09:14 -07:00
BfType * SafeResolveAliasType ( BfTypeAliasType * aliasType ) ;
2022-02-04 12:00:43 -05:00
bool ResolveTypeResult_Validate ( BfAstNode * typeRef , BfType * resolvedTypeRef ) ;
2019-08-23 11:56:54 -07:00
BfType * ResolveTypeResult ( BfTypeReference * typeRef , BfType * resolvedTypeRef , BfPopulateType populateType , BfResolveTypeRefFlags resolveFlags ) ;
void ShowAmbiguousTypeError ( BfAstNode * refNode , BfTypeDef * typeDef , BfTypeDef * otherTypeDef ) ;
2022-07-26 13:27:03 -04:00
void ShowGenericArgCountError ( BfAstNode * typeRef , int wantedGenericParams ) ;
BfTypeDef * GetActiveTypeDef ( BfTypeInstance * typeInstanceOverride = NULL , bool useMixinDecl = false ) ; // useMixinDecl is useful for type lookup, but we don't want the decl project to limit what methods the user can call
2021-07-15 12:50:42 -07:00
BfTypeDef * FindTypeDefRaw ( const BfAtomComposite & findName , int numGenericArgs , BfTypeInstance * typeInstance , BfTypeDef * useTypeDef , BfTypeLookupError * error , BfTypeLookupResultCtx * lookupResultCtx = NULL , BfResolveTypeRefFlags resolveFlags = ( BfResolveTypeRefFlags ) 0 ) ;
BfTypeDef * FindTypeDef ( const BfAtomComposite & findName , int numGenericArgs = 0 , BfTypeInstance * typeInstanceOverride = NULL , BfTypeLookupError * error = NULL , BfResolveTypeRefFlags resolveFlags = ( BfResolveTypeRefFlags ) 0 ) ;
BfTypeDef * FindTypeDef ( const StringImpl & typeName , int numGenericArgs = 0 , BfTypeInstance * typeInstanceOverride = NULL , BfTypeLookupError * error = NULL , BfResolveTypeRefFlags resolveFlags = ( BfResolveTypeRefFlags ) 0 ) ;
2020-05-18 13:12:18 -07:00
BfTypeDef * FindTypeDef ( BfTypeReference * typeRef , BfTypeInstance * typeInstanceOverride = NULL , BfTypeLookupError * error = NULL , int numGenericParams = 0 , BfResolveTypeRefFlags resolveFlags = ( BfResolveTypeRefFlags ) 0 ) ;
2019-08-23 11:56:54 -07:00
BfTypedValue TryLookupGenericConstVaue ( BfIdentifierNode * identifierNode , BfType * expectingType ) ;
void CheckTypeRefFixit ( BfAstNode * typeRef , const char * appendName = NULL ) ;
void CheckIdentifierFixit ( BfAstNode * node ) ;
void TypeRefNotFound ( BfTypeReference * typeRef , const char * appendName = NULL ) ;
2022-07-26 13:27:03 -04:00
bool ValidateTypeWildcard ( BfAstNode * typeRef , bool isAttributeRef ) ;
2021-12-27 12:55:14 -05:00
void GetDelegateTypeRefAttributes ( BfDelegateTypeRef * delegateTypeRef , BfCallingConvention & callingConvention ) ;
2020-07-07 10:46:53 -07:00
BfType * ResolveTypeRef ( BfTypeReference * typeRef , BfPopulateType populateType = BfPopulateType_Data , BfResolveTypeRefFlags resolveFlags = ( BfResolveTypeRefFlags ) 0 , int numGenericArgs = 0 ) ;
2019-08-23 11:56:54 -07:00
BfType * ResolveTypeRefAllowUnboundGenerics ( BfTypeReference * typeRef , BfPopulateType populateType = BfPopulateType_Data , bool resolveGenericParam = true ) ;
2022-02-05 09:23:44 -05:00
BfType * ResolveTypeRef_Type ( BfAstNode * astNode , const BfSizedArray < BfAstNode * > * genericArgs , BfPopulateType populateType = BfPopulateType_Data , BfResolveTypeRefFlags resolveFlags = ( BfResolveTypeRefFlags ) 0 ) ;
BfType * ResolveTypeRef ( BfAstNode * astNode , const BfSizedArray < BfAstNode * > * genericArgs , BfPopulateType populateType = BfPopulateType_Data , BfResolveTypeRefFlags resolveFlags = ( BfResolveTypeRefFlags ) 0 ) ;
2020-09-14 06:54:49 -07:00
BfType * ResolveTypeDef ( BfTypeDef * typeDef , BfPopulateType populateType = BfPopulateType_Data , BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None ) ;
BfType * ResolveTypeDef ( BfTypeDef * typeDef , const BfTypeVector & genericArgs , BfPopulateType populateType = BfPopulateType_Data , BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None ) ;
2022-07-06 12:19:01 -07:00
BfType * ResolveInnerType ( BfType * outerType , BfAstNode * typeRef , BfPopulateType populateType = BfPopulateType_Data , bool ignoreErrors = false , int numGenericArgs = 0 , BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None ) ;
2019-08-23 11:56:54 -07:00
BfTypeDef * GetCombinedPartialTypeDef ( BfTypeDef * type ) ;
BfTypeInstance * GetOuterType ( BfType * type ) ;
2022-07-26 13:27:03 -04:00
bool IsInnerType ( BfType * checkInnerType , BfType * checkOuterType ) ;
2019-08-23 11:56:54 -07:00
bool IsInnerType ( BfTypeDef * checkInnerType , BfTypeDef * checkOuterType ) ;
2020-06-23 11:54:28 -07:00
bool TypeHasParentOrEquals ( BfTypeDef * checkChildTypeDef , BfTypeDef * checkParentTypeDef ) ;
2022-07-26 13:27:03 -04:00
BfTypeDef * FindCommonOuterType ( BfTypeDef * type , BfTypeDef * type2 ) ;
2019-08-23 11:56:54 -07:00
bool TypeIsSubTypeOf ( BfTypeInstance * srcType , BfTypeInstance * wantType , bool checkAccessibility = true ) ;
2022-03-03 12:55:56 -08:00
bool TypeIsSubTypeOf ( BfTypeInstance * srcType , BfTypeDef * wantType ) ;
2019-08-23 11:56:54 -07:00
int GetTypeDistance ( BfType * fromType , BfType * toType ) ;
2022-07-26 13:27:03 -04:00
bool IsTypeMoreSpecific ( BfType * leftType , BfType * rightType ) ;
2019-08-23 11:56:54 -07:00
bool GetBasePropertyDef ( BfPropertyDef * & propDef , BfTypeInstance * & typeInst ) ;
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
// Method helpers
2022-07-26 13:27:03 -04:00
void CheckInterfaceMethod ( BfMethodInstance * methodInstance ) ;
2019-08-23 11:56:54 -07:00
void CreateDelegateInvokeMethod ( ) ;
2022-07-26 13:27:03 -04:00
BfType * GetDelegateReturnType ( BfType * delegateType ) ;
2019-08-23 11:56:54 -07:00
BfMethodInstance * GetDelegateInvokeMethod ( BfTypeInstance * typeInstance ) ;
String GetLocalMethodName ( const StringImpl & baseName , BfAstNode * anchorNode , BfMethodState * declMethodState , BfMixinState * declMixinState ) ;
BfMethodDef * GetLocalMethodDef ( BfLocalMethod * localMethod ) ;
BfModuleMethodInstance GetLocalMethodInstance ( BfLocalMethod * localMethod , const BfTypeVector & methodGenericArguments , BfMethodInstance * methodInstance = NULL , bool force = false ) ;
int GetLocalInferrableGenericArgCount ( BfMethodDef * methodDef ) ;
void GetMethodCustomAttributes ( BfMethodInstance * methodInstance ) ;
void SetupIRFunction ( BfMethodInstance * methodInstance , StringImpl & mangledName , bool isTemporaryFunc , bool * outIsIntrinsic ) ;
void CheckHotMethod ( BfMethodInstance * methodInstance , const StringImpl & mangledName ) ;
2022-01-16 07:59:51 -05:00
void StartMethodDeclaration ( BfMethodInstance * methodInstance , BfMethodState * prevMethodState ) ;
2019-08-23 11:56:54 -07:00
void DoMethodDeclaration ( BfMethodDeclaration * methodDeclaration , bool isTemporaryFunc , bool addToWorkList = true ) ;
void AddMethodToWorkList ( BfMethodInstance * methodInstance ) ;
bool IsInterestedInMethod ( BfTypeInstance * typeInstance , BfMethodDef * methodDef ) ;
void CalcAppendAlign ( BfMethodInstance * methodInst ) ;
2022-06-27 10:55:31 -07:00
BfTypedValue TryConstCalcAppend ( BfMethodInstance * methodInst , SizedArrayImpl < BfIRValue > & args , bool force = false ) ;
2019-08-23 11:56:54 -07:00
BfTypedValue CallBaseCtorCalc ( bool constOnly ) ;
2022-07-26 13:27:03 -04:00
void EmitCtorCalcAppend ( ) ;
void CreateStaticCtor ( ) ;
2019-08-23 11:56:54 -07:00
BfIRValue CreateDllImportGlobalVar ( BfMethodInstance * methodInstance , bool define = false ) ;
2022-07-26 13:27:03 -04:00
void CreateDllImportMethod ( ) ;
2019-12-21 05:44:01 -08:00
BfIRCallingConv GetIRCallingConvention ( BfMethodInstance * methodInstance ) ;
2019-09-26 08:29:34 -07:00
void SetupIRMethod ( BfMethodInstance * methodInstance , BfIRFunction func , bool isInlined ) ;
2020-12-26 11:41:31 -08:00
void EmitInitBlocks ( const std : : function < void ( BfAstNode * ) > & initBlockCallback ) ;
2019-08-23 11:56:54 -07:00
void EmitCtorBody ( bool & skipBody ) ;
void EmitDtorBody ( ) ;
void EmitEnumToStringBody ( ) ;
2022-07-26 13:27:03 -04:00
void EmitTupleToStringBody ( ) ;
2022-06-27 10:55:31 -07:00
void EmitGCMarkAppended ( BfTypedValue markVal ) ;
void EmitGCMarkValue ( BfTypedValue & thisValue , BfType * checkType , int memberDepth , int curOffset , HashSet < int > & objectOffsets , BfModuleMethodInstance markFromGCThreadMethodInstance , bool isAppendObject = false ) ;
2019-08-23 11:56:54 -07:00
void EmitGCMarkValue ( BfTypedValue markVal , BfModuleMethodInstance markFromGCThreadMethodInstance ) ;
void EmitGCMarkMembers ( ) ;
void EmitGCFindTLSMembers ( ) ;
void EmitIteratorBlock ( bool & skipBody ) ;
2020-06-17 05:13:53 -07:00
void EmitEquals ( BfTypedValue leftValue , BfTypedValue rightValue , BfIRBlock exitBB , bool strictEquals ) ;
2019-08-23 11:56:54 -07:00
void CreateFakeCallerMethod ( const String & funcName ) ;
void CallChainedMethods ( BfMethodInstance * methodInstance , bool reverse = false ) ;
void AddHotDataReferences ( BfHotDataReferenceBuilder * builder ) ;
void ProcessMethod_SetupParams ( BfMethodInstance * methodInstance , BfType * thisType , bool wantsDIData , SizedArrayImpl < BfIRMDNode > * diParams ) ;
void ProcessMethod_ProcessDeferredLocals ( int startIdx = 0 ) ;
2022-01-16 07:59:51 -05:00
void ProcessMethod ( BfMethodInstance * methodInstance , bool isInlineDup = false , bool forceIRWrites = false ) ;
2019-08-23 11:56:54 -07:00
void CreateDynamicCastMethod ( ) ;
2022-02-15 09:31:23 -05:00
void CreateDelegateEqualsMethod ( ) ;
2020-06-17 05:13:53 -07:00
void CreateValueTypeEqualsMethod ( bool strictEquals ) ;
2019-08-23 11:56:54 -07:00
BfIRFunction GetIntrinsic ( BfMethodInstance * methodInstance , bool reportFailure = false ) ;
BfIRFunction GetBuiltInFunc ( BfBuiltInFuncType funcType ) ;
2022-07-26 13:27:03 -04:00
BfIRValue CreateFunctionFrom ( BfMethodInstance * methodInstance , bool tryExisting , bool isInlined ) ;
2022-02-16 08:28:05 -05:00
void EvaluateWithNewConditionalScope ( BfExprEvaluator & exprEvaluator , BfExpression * expr , BfEvalExprFlags flags ) ;
2019-08-23 11:56:54 -07:00
BfTypedValue CreateValueFromExpression ( BfExprEvaluator & exprEvaluator , BfExpression * expr , BfType * wantTypeRef = NULL , BfEvalExprFlags flags = BfEvalExprFlags_None , BfType * * outOrigType = NULL ) ;
BfTypedValue CreateValueFromExpression ( BfExpression * expr , BfType * wantTypeRef = NULL , BfEvalExprFlags flags = BfEvalExprFlags_None , BfType * * outOrigType = NULL ) ;
BfTypedValue GetOrCreateVarAddr ( BfExpression * expr ) ;
2021-01-05 13:50:57 -08:00
BfMethodInstance * GetRawMethodInstanceAtIdx ( BfTypeInstance * typeInstance , int methodIdx , const char * assertName = NULL ) ;
2019-08-23 11:56:54 -07:00
BfMethodInstance * GetRawMethodInstance ( BfTypeInstance * typeInstance , BfMethodDef * methodDef ) ;
BfMethodInstance * GetRawMethodByName ( BfTypeInstance * typeInstance , const StringImpl & methodName , int paramCount = - 1 , bool checkBase = false , bool allowMixin = false ) ;
2022-07-26 13:27:03 -04:00
BfMethodInstance * GetUnspecializedMethodInstance ( BfMethodInstance * methodInstance , bool useUnspecializedType = true ) ; // Unspecialized owner type and unspecialized method type
int GetGenericParamAndReturnCount ( BfMethodInstance * methodInstance ) ;
BfModule * GetSpecializedMethodModule ( const SizedArrayImpl < BfProject * > & projectList ) ;
2020-05-25 05:37:12 -07:00
BfModuleMethodInstance GetMethodInstanceAtIdx ( BfTypeInstance * typeInstance , int methodIdx , const char * assertName = NULL , BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None ) ;
2019-08-23 11:56:54 -07:00
BfModuleMethodInstance GetMethodByName ( BfTypeInstance * typeInstance , const StringImpl & methodName , int paramCount = - 1 , bool checkBase = false ) ;
BfModuleMethodInstance GetMethodByName ( BfTypeInstance * typeInstance , const StringImpl & methodName , const Array < BfType * > & paramTypes , bool checkBase = false ) ;
BfModuleMethodInstance GetInternalMethod ( const StringImpl & methodName , int paramCount = - 1 ) ;
2020-09-18 17:00:33 -07:00
BfOperatorInfo * GetOperatorInfo ( BfTypeInstance * typeInstance , BfOperatorDef * operatorDef ) ;
BfType * CheckOperator ( BfTypeInstance * typeInstance , BfOperatorDef * operatorDef , const BfTypedValue & lhs , const BfTypedValue & rhs ) ;
2019-08-23 11:56:54 -07:00
bool IsMethodImplementedAndReified ( BfTypeInstance * typeInstance , const StringImpl & methodName , int paramCount = - 1 , bool checkBase = false ) ;
bool HasMixin ( BfTypeInstance * typeInstance , const StringImpl & methodName , int paramCount , bool checkBase = false ) ;
2020-05-27 09:46:09 -07:00
bool CompareMethodSignatures ( BfMethodInstance * methodA , BfMethodInstance * methodB ) ; // Doesn't compare return types nor static
bool StrictCompareMethodSignatures ( BfMethodInstance * methodA , BfMethodInstance * methodB ) ; // Compares return types and static
2019-08-23 11:56:54 -07:00
bool IsCompatibleInterfaceMethod ( BfMethodInstance * methodA , BfMethodInstance * methodB ) ;
2022-07-26 13:27:03 -04:00
void UniqueSlotVirtualMethod ( BfMethodInstance * methodInstance ) ;
2022-07-04 10:21:31 -07:00
void CompareDeclTypes ( BfTypeInstance * typeInst , BfTypeDef * newDeclType , BfTypeDef * prevDeclType , bool & isBetter , bool & isWorse ) ;
2022-07-26 13:27:03 -04:00
bool SlotVirtualMethod ( BfMethodInstance * methodInstance , BfAmbiguityContext * ambiguityContext = NULL ) ;
2020-10-23 11:48:37 -07:00
void CheckOverridenMethod ( BfMethodInstance * methodInstance , BfMethodInstance * methodOverriden ) ;
2022-07-26 13:27:03 -04:00
bool SlotInterfaceMethod ( BfMethodInstance * methodInstance ) ;
2020-09-28 12:41:42 -07:00
void SetMethodDependency ( BfMethodInstance * methodInstance ) ;
2019-08-23 11:56:54 -07:00
BfModuleMethodInstance ReferenceExternalMethodInstance ( BfMethodInstance * methodInstance , BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None ) ;
BfModule * GetOrCreateMethodModule ( BfMethodInstance * methodInstance ) ;
2022-07-26 13:27:03 -04:00
BfModuleMethodInstance GetMethodInstance ( BfTypeInstance * typeInst , BfMethodDef * methodDef , const BfTypeVector & methodGenericArguments , BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None , BfTypeInstance * foreignType = NULL ) ;
2019-08-23 11:56:54 -07:00
BfModuleMethodInstance GetMethodInstance ( BfMethodInstance * methodInstance , BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None ) ;
BfMethodInstance * GetOuterMethodInstance ( BfMethodInstance * methodInstance ) ; // Only useful for local methods
void SetupMethodIdHash ( BfMethodInstance * methodInstance ) ;
2021-01-18 14:09:16 -08:00
bool CheckUseMethodInstance ( BfMethodInstance * methodInstance , BfAstNode * refNode ) ;
2019-08-23 11:56:54 -07:00
// Type Data
BfIRValue CreateClassVDataGlobal ( BfTypeInstance * typeInstance , int * outNumElements = NULL , String * outMangledName = NULL ) ;
BfIRValue GetClassVDataPtr ( BfTypeInstance * typeInstance ) ;
BfIRValue CreateClassVDataExtGlobal ( BfTypeInstance * declTypeInst , BfTypeInstance * implTypeInst , int startVirtIdx ) ;
BfIRValue CreateTypeDataRef ( BfType * type ) ;
2021-11-02 11:32:06 -07:00
void EncodeAttributeData ( BfTypeInstance * typeInstance , BfType * argType , BfIRValue arg , SizedArrayImpl < uint8 > & data , Dictionary < int , int > & usedStringIdMap ) ;
2022-02-12 08:05:47 -05:00
BfIRValue CreateFieldData ( BfFieldInstance * fieldInstance , int customAttrIdx ) ;
2019-08-23 11:56:54 -07:00
BfIRValue CreateTypeData ( BfType * type , Dictionary < int , int > & usedStringIdMap , bool forceReflectFields , bool needsTypeData , bool needsTypeNames , bool needsVData ) ;
BfIRValue FixClassVData ( BfIRValue value ) ;
public :
BfModule ( BfContext * context , const StringImpl & moduleName ) ;
virtual ~ BfModule ( ) ;
2022-07-26 13:27:03 -04:00
void Init ( bool isFullRebuild = true ) ;
2019-08-23 11:56:54 -07:00
bool WantsFinishModule ( ) ;
2022-01-13 11:40:14 -05:00
bool IsHotCompile ( ) ;
2019-08-23 11:56:54 -07:00
void FinishInit ( ) ;
2021-07-31 09:54:27 -07:00
void CalcGeneratesCode ( ) ;
2019-08-23 11:56:54 -07:00
void ReifyModule ( ) ;
void UnreifyModule ( ) ;
void Cleanup ( ) ;
void StartNewRevision ( RebuildKind rebuildKind = RebuildKind_All , bool force = false ) ;
2019-09-07 15:18:56 -07:00
void PrepareForIRWriting ( BfTypeInstance * typeInst ) ;
2021-01-30 08:08:30 -08:00
void SetupIRBuilder ( bool dbgVerifyCodeGen ) ;
2019-08-23 11:56:54 -07:00
void EnsureIRBuilder ( bool dbgVerifyCodeGen = false ) ;
void DbgFinish ( ) ;
BfIRValue CreateForceLinkMarker ( BfModule * module , String * outName ) ;
2020-10-22 17:25:19 -07:00
void ClearModuleData ( bool clearTransientData = true ) ;
2019-08-23 11:56:54 -07:00
void DisownMethods ( ) ;
2022-07-26 13:27:03 -04:00
void ClearModule ( ) ;
2019-08-23 11:56:54 -07:00
void StartExtension ( ) ; // For new method specializations
bool Finish ( ) ;
void RemoveModuleData ( ) ;
void ReportMemory ( MemReporter * memReporter ) ;
} ;
class BfAutoParentNodeEntry
{
public :
BfModule * mModule ;
BfParentNodeEntry mParentNodeEntry ;
BfAutoParentNodeEntry ( BfModule * module , BfAstNode * node )
{
mModule = module ;
mParentNodeEntry . mNode = node ;
mParentNodeEntry . mPrev = module - > mParentNodeEntry ;
module - > mParentNodeEntry = & mParentNodeEntry ;
}
~ BfAutoParentNodeEntry ( )
{
mModule - > mParentNodeEntry = mParentNodeEntry . mPrev ;
}
} ;
class BfVDataModule : public BfModule
{
public :
HashSet < int > mDefinedStrings ;
public :
2019-09-03 11:17:13 -07:00
BfVDataModule ( BfContext * context ) : BfModule ( context , StringImpl : : MakeRef ( " vdata " ) )
2019-08-23 11:56:54 -07:00
{
}
} ;
NS_BF_END
namespace std
{
template < >
struct hash < Beefy : : BfMethodRef >
{
size_t operator ( ) ( const Beefy : : BfMethodRef & val ) const
{
if ( val . mTypeInstance = = NULL )
return 0 ;
return val . mTypeInstance - > mTypeId ^ ( val . mMethodNum < < 10 ) ;
}
} ;
template < >
struct hash < Beefy : : BfVDataExtEntry >
{
size_t operator ( ) ( const Beefy : : BfVDataExtEntry & val ) const
{
return ( ( size_t ) ( val . mDeclTypeInst ) * 17 ) ^ ( size_t ) ( val . mDeclTypeInst ) ;
}
} ;
template < >
struct hash < Beefy : : BfLocalVarEntry >
{
size_t operator ( ) ( const Beefy : : BfLocalVarEntry & val ) const
{
return std : : hash < Beefy : : String > ( ) ( val . mLocalVar - > mName ) ;
}
2022-07-26 13:27:03 -04:00
} ;
2019-08-23 11:56:54 -07:00
}