BfResolvedTypeUtils.h 90 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100
  1. #pragma once
  2. #pragma once
  3. #include "BfAst.h"
  4. #include <unordered_map>
  5. #include "BfSource.h"
  6. #include "BfIRBuilder.h"
  7. #include "BeefySysLib/util/MultiHashSet.h"
  8. #include "BeefySysLib/util/BitSet.h"
  9. NS_BF_BEGIN
  10. class BfModule;
  11. class BfType;
  12. class BfTypeInstance;
  13. class BfContext;
  14. class BfCustomAttributes;
  15. enum BfResolveTypeRefFlags
  16. {
  17. BfResolveTypeRefFlag_None = 0,
  18. BfResolveTypeRefFlag_NoResolveGenericParam = 1,
  19. BfResolveTypeRefFlag_AllowRef = 2,
  20. BfResolveTypeRefFlag_AllowRefGeneric = 4,
  21. BfResolveTypeRefFlag_IgnoreLookupError = 8,
  22. BfResolveTypeRefFlag_AllowGenericTypeParamConstValue = 0x10,
  23. BfResolveTypeRefFlag_AllowGenericMethodParamConstValue = 0x20,
  24. BfResolveTypeRefFlag_AllowGenericParamConstValue = 0x10 | 0x20,
  25. BfResolveTypeRefFlag_AutoComplete = 0x40,
  26. BfResolveTypeRefFlag_FromIndirectSource = 0x80, // Such as a type alias or a generic parameter
  27. BfResolveTypeRefFlag_Attribute = 0x100,
  28. BfResolveTypeRefFlag_NoReify = 0x200,
  29. BfResolveTypeRefFlag_NoCreate = 0x400,
  30. BfResolveTypeRefFlag_NoWarnOnMut = 0x800,
  31. BfResolveTypeRefFlag_DisallowComptime = 0x1000,
  32. BfResolveTypeRefFlag_AllowDotDotDot = 0x2000,
  33. BfResolveTypeRefFlag_AllowGlobalContainer = 0x4000,
  34. BfResolveTypeRefFlag_AllowInferredSizedArray = 0x8000,
  35. BfResolveTypeRefFlag_AllowGlobalsSelf = 0x10000,
  36. BfResolveTypeRefFlag_AllowImplicitConstExpr = 0x20000,
  37. BfResolveTypeRefFlag_AllowUnboundGeneric = 0x40000,
  38. BfResolveTypeRefFlag_ForceUnboundGeneric = 0x80000,
  39. BfResolveTypeRefFlag_IgnoreProtection = 0x100000,
  40. BfResolveTypeRefFlag_SpecializedProject = 0x200000
  41. };
  42. enum BfTypeNameFlags : uint16
  43. {
  44. BfTypeNameFlags_None = 0,
  45. BfTypeNameFlag_ResolveGenericParamNames = 1,
  46. BfTypeNameFlag_UseUnspecializedGenericParamNames = 2,
  47. BfTypeNameFlag_OmitNamespace = 4,
  48. BfTypeNameFlag_OmitOuterType = 8,
  49. BfTypeNameFlag_ReduceName = 0x10,
  50. BfTypeNameFlag_UseArrayImplType = 0x20,
  51. BfTypeNameFlag_DisambiguateDups = 0x40, // Add a disambiguation if mDupDetectedRevision is set
  52. BfTypeNameFlag_AddGlobalContainerName = 0x80,
  53. BfTypeNameFlag_InternalName = 0x100, // Use special delimiters to remove ambiguities (ie: '+' for inner types)
  54. BfTypeNameFlag_HideGlobalName = 0x200,
  55. BfTypeNameFlag_ExtendedInfo = 0x400,
  56. BfTypeNameFlag_ShortConst = 0x800,
  57. BfTypeNameFlag_AddProjectName = 0x1000
  58. };
  59. enum BfMethodNameFlags : uint8
  60. {
  61. BfMethodNameFlag_None = 0,
  62. BfMethodNameFlag_ResolveGenericParamNames = 1,
  63. BfMethodNameFlag_OmitTypeName = 2,
  64. BfMethodNameFlag_IncludeReturnType = 4,
  65. BfMethodNameFlag_OmitParams = 8,
  66. BfMethodNameFlag_IncludeMut = 0x10,
  67. BfMethodNameFlag_NoAst = 0x20
  68. };
  69. enum BfGetMethodInstanceFlags : uint16
  70. {
  71. BfGetMethodInstanceFlag_None = 0,
  72. BfGetMethodInstanceFlag_UnspecializedPass = 1,
  73. BfGetMethodInstanceFlag_ExplicitSpecializedModule = 2,
  74. BfGetMethodInstanceFlag_ExplicitResolveOnlyPass = 4,
  75. BfGetMethodInstanceFlag_ForeignMethodDef = 8,
  76. BfGetMethodInstanceFlag_Unreified = 0x10,
  77. BfGetMethodInstanceFlag_NoForceReification = 0x20,
  78. BfGetMethodInstanceFlag_ResultNotUsed = 0x40,
  79. BfGetMethodInstanceFlag_ForceInline = 0x80,
  80. BfGetMethodInstanceFlag_Friend = 0x100,
  81. BfGetMethodInstanceFlag_DisableObjectAccessChecks = 0x200,
  82. BfGetMethodInstanceFlag_NoInline = 0x400,
  83. BfGetMethodInstanceFlag_DepthExceeded = 0x800,
  84. BfGetMethodInstanceFlag_NoReference = 0x1000,
  85. BfGetMethodInstanceFlag_MethodInstanceOnly = 0x2000
  86. };
  87. class BfDependencyMap
  88. {
  89. public:
  90. enum DependencyFlags
  91. {
  92. DependencyFlag_None = 0,
  93. DependencyFlag_Calls = 1,
  94. DependencyFlag_InlinedCall = 2,
  95. DependencyFlag_ReadFields = 4,
  96. DependencyFlag_DerivedFrom = 8,
  97. DependencyFlag_OuterType = 0x10,
  98. DependencyFlag_ImplementsInterface = 0x20,
  99. DependencyFlag_ValueTypeMemberData = 0x40,
  100. DependencyFlag_PtrMemberData = 0x80,
  101. DependencyFlag_StaticValue = 0x100,
  102. DependencyFlag_ConstValue = 0x200,
  103. DependencyFlag_ConstEvalConstField = 0x400, // Used a field that was CE-generated
  104. DependencyFlag_ConstEval = 0x800,
  105. DependencyFlag_MethodGenericArg = 0x1000,
  106. DependencyFlag_LocalUsage = 0x2000,
  107. DependencyFlag_ExprTypeReference = 0x4000,
  108. DependencyFlag_TypeGenericArg = 0x8000,
  109. DependencyFlag_UnspecializedType = 0x10000,
  110. DependencyFlag_GenericArgRef = 0x20000,
  111. DependencyFlag_ParamOrReturnValue = 0x40000,
  112. DependencyFlag_CustomAttribute = 0x80000,
  113. DependencyFlag_Constraint = 0x100000,
  114. DependencyFlag_StructElementType = 0x200000,
  115. DependencyFlag_TypeReference = 0x400000, // Explicit type reference for things like tuples, so all referencing types get passed over on symbol reference
  116. DependencyFlag_Allocates = 0x800000,
  117. DependencyFlag_NameReference = 0x1000000,
  118. DependencyFlag_VirtualCall = 0x2000000,
  119. DependencyFlag_WeakReference = 0x4000000, // Keeps alive but won't rebuild
  120. DependencyFlag_ValueTypeSizeDep = 0x8000000, // IE: int32[DepType.cVal]
  121. DependencyFlag_DependentUsageMask = ~(DependencyFlag_UnspecializedType | DependencyFlag_MethodGenericArg | DependencyFlag_GenericArgRef)
  122. };
  123. struct DependencyEntry
  124. {
  125. int mRevision;
  126. DependencyFlags mFlags;
  127. DependencyEntry(int revision, DependencyFlags flags)
  128. {
  129. mRevision = revision;
  130. mFlags = flags;
  131. }
  132. };
  133. public:
  134. typedef Dictionary<BfType*, DependencyEntry> TypeMap;
  135. DependencyFlags mFlagsUnion;
  136. TypeMap mTypeSet;
  137. int mMinDependDepth;
  138. public:
  139. BfDependencyMap()
  140. {
  141. mMinDependDepth = 0;
  142. mFlagsUnion = DependencyFlag_None;
  143. }
  144. bool AddUsedBy(BfType* dependentType, DependencyFlags flags);
  145. bool IsEmpty();
  146. TypeMap::iterator begin();
  147. TypeMap::iterator end();
  148. TypeMap::iterator erase(TypeMap::iterator& itr);
  149. };
  150. class BfDepContext
  151. {
  152. public:
  153. HashSet<BfType*> mDeepSeenAliases;
  154. int mAliasDepth;
  155. public:
  156. BfDepContext()
  157. {
  158. mAliasDepth = 0;
  159. }
  160. };
  161. enum BfHotDepDataKind : int8
  162. {
  163. BfHotDepDataKind_Unknown,
  164. BfHotDepDataKind_TypeVersion,
  165. BfHotDepDataKind_ThisType,
  166. BfHotDepDataKind_Allocation,
  167. BfHotDepDataKind_Method,
  168. BfHotDepDataKind_DupMethod,
  169. BfHotDepDataKind_DevirtualizedMethod,
  170. BfHotDepDataKind_InnerMethod,
  171. BfHotDepDataKind_FunctionPtr,
  172. BfHotDepDataKind_VirtualDecl
  173. };
  174. enum BfHotDepDataFlags : int8
  175. {
  176. BfHotDepDataFlag_None = 0,
  177. BfHotDepDataFlag_AlwaysCalled = 1,
  178. BfHotDepDataFlag_NotReified = 2,
  179. BfHotDepDataFlag_IsOriginalBuild = 4,
  180. BfHotDepDataFlag_IsBound = 8,
  181. BfHotDepDataFlag_HasDup = 0x10,
  182. BfHotDepDataFlag_RetainMethodWithoutBinding = 0x20,
  183. };
  184. class BfHotDepData
  185. {
  186. public:
  187. BfHotDepDataKind mDataKind;
  188. BfHotDepDataFlags mFlags;
  189. int32 mRefCount;
  190. BfHotDepData()
  191. {
  192. mDataKind = BfHotDepDataKind_Unknown;
  193. mFlags = BfHotDepDataFlag_None;
  194. mRefCount = 0;
  195. }
  196. void Deref();
  197. #ifdef _DEBUG
  198. virtual ~BfHotDepData()
  199. {
  200. BF_ASSERT(mRefCount == 0);
  201. }
  202. #endif
  203. };
  204. struct BfHotTypeDataEntry
  205. {
  206. public:
  207. String mFuncName; // Name of original virtual function, not overrides
  208. };
  209. class BfHotTypeVersion : public BfHotDepData
  210. {
  211. public:
  212. Val128 mDataHash; // Determines when the user's declaration changed - changes do not cascade into including types
  213. BfHotTypeVersion* mBaseType;
  214. Array<BfHotTypeVersion*> mMembers; // Struct members directly included (not via pointers)
  215. int mDeclHotCompileIdx;
  216. int mCommittedHotCompileIdx;
  217. int mTypeId;
  218. Array<int> mInterfaceMapping;
  219. bool mPopulatedInterfaceMapping;
  220. BfHotTypeVersion()
  221. {
  222. mBaseType = NULL;
  223. mDataKind = BfHotDepDataKind_TypeVersion;
  224. mPopulatedInterfaceMapping = 0;
  225. }
  226. ~BfHotTypeVersion();
  227. };
  228. class BfHotThisType : public BfHotDepData
  229. {
  230. public:
  231. BfHotTypeVersion* mTypeVersion;
  232. BfHotThisType(BfHotTypeVersion* typeVersion)
  233. {
  234. mDataKind = BfHotDepDataKind_ThisType;
  235. mTypeVersion = typeVersion;
  236. mTypeVersion->mRefCount++;
  237. }
  238. ~BfHotThisType()
  239. {
  240. mTypeVersion->Deref();
  241. }
  242. };
  243. class BfHotAllocation : public BfHotDepData
  244. {
  245. public:
  246. BfHotTypeVersion* mTypeVersion;
  247. BfHotAllocation(BfHotTypeVersion* typeVersion)
  248. {
  249. mDataKind = BfHotDepDataKind_Allocation;
  250. mTypeVersion = typeVersion;
  251. mTypeVersion->mRefCount++;
  252. }
  253. ~BfHotAllocation()
  254. {
  255. mTypeVersion->Deref();
  256. }
  257. };
  258. //#define BF_DBG_HOTMETHOD_NAME
  259. //#define BF_DBG_HOTMETHOD_IDX
  260. class BfHotMethod : public BfHotDepData
  261. {
  262. public:
  263. #ifdef BF_DBG_HOTMETHOD_NAME
  264. String mMangledName;
  265. #endif
  266. #ifdef BF_DBG_HOTMETHOD_IDX
  267. int mMethodIdx;
  268. #endif
  269. BfHotTypeVersion* mSrcTypeVersion;
  270. Array<BfHotDepData*> mReferences;
  271. BfHotMethod* mPrevVersion;
  272. BfHotMethod()
  273. {
  274. #ifdef BF_DBG_HOTMETHOD_IDX
  275. mMethodIdx = -1;
  276. #endif
  277. mDataKind = BfHotDepDataKind_Method;
  278. mSrcTypeVersion = NULL;
  279. mPrevVersion = NULL;
  280. }
  281. void Clear(bool keepDupMethods = false);
  282. ~BfHotMethod();
  283. };
  284. class BfHotDupMethod : public BfHotDepData
  285. {
  286. public:
  287. BfHotMethod* mMethod;
  288. public:
  289. BfHotDupMethod(BfHotMethod* hotMethod)
  290. {
  291. mDataKind = BfHotDepDataKind_DupMethod;
  292. mMethod = hotMethod;
  293. mMethod->mRefCount++;
  294. }
  295. ~BfHotDupMethod()
  296. {
  297. mMethod->Deref();
  298. }
  299. };
  300. class BfHotDevirtualizedMethod : public BfHotDepData
  301. {
  302. public:
  303. BfHotMethod* mMethod;
  304. BfHotDevirtualizedMethod(BfHotMethod* method)
  305. {
  306. mDataKind = BfHotDepDataKind_DevirtualizedMethod;
  307. mMethod = method;
  308. mMethod->mRefCount++;
  309. }
  310. ~BfHotDevirtualizedMethod()
  311. {
  312. mMethod->Deref();
  313. }
  314. };
  315. class BfHotFunctionReference : public BfHotDepData
  316. {
  317. public:
  318. BfHotMethod* mMethod;
  319. BfHotFunctionReference(BfHotMethod* method)
  320. {
  321. mDataKind = BfHotDepDataKind_FunctionPtr;
  322. mMethod = method;
  323. mMethod->mRefCount++;
  324. }
  325. ~BfHotFunctionReference()
  326. {
  327. mMethod->Deref();
  328. }
  329. };
  330. class BfHotInnerMethod : public BfHotDepData
  331. {
  332. public:
  333. BfHotMethod* mMethod;
  334. BfHotInnerMethod(BfHotMethod* method)
  335. {
  336. mDataKind = BfHotDepDataKind_InnerMethod;
  337. mMethod = method;
  338. mMethod->mRefCount++;
  339. }
  340. ~BfHotInnerMethod()
  341. {
  342. mMethod->Deref();
  343. }
  344. };
  345. class BfHotVirtualDeclaration : public BfHotDepData
  346. {
  347. public:
  348. BfHotMethod* mMethod;
  349. BfHotVirtualDeclaration(BfHotMethod* method)
  350. {
  351. mDataKind = BfHotDepDataKind_VirtualDecl;
  352. mMethod = method;
  353. mMethod->mRefCount++;
  354. }
  355. ~BfHotVirtualDeclaration()
  356. {
  357. mMethod->Deref();
  358. }
  359. };
  360. class BfHotDataReferenceBuilder
  361. {
  362. public:
  363. HashSet<BfHotTypeVersion*> mAllocatedData; // Any usage that depends on size or layout
  364. HashSet<BfHotTypeVersion*> mUsedData; // Any usage that depends on size or layout
  365. HashSet<BfHotMethod*> mCalledMethods;
  366. HashSet<BfHotMethod*> mDevirtualizedCalledMethods;
  367. HashSet<BfHotMethod*> mFunctionPtrs;
  368. HashSet<BfHotMethod*> mInnerMethods;
  369. };
  370. class BfDependedType;
  371. class BfTypeInstance;
  372. class BfPrimitiveType;
  373. enum BfTypeRebuildFlags
  374. {
  375. BfTypeRebuildFlag_None = 0,
  376. BfTypeRebuildFlag_StaticChange = 1,
  377. BfTypeRebuildFlag_NonStaticChange = 2,
  378. BfTypeRebuildFlag_MethodInlineInternalsChange = 4,
  379. BfTypeRebuildFlag_MethodSignatureChange = 8,
  380. BfTypeRebuildFlag_ConstEvalChange = 0x10,
  381. BfTypeRebuildFlag_ConstEvalFieldChange = 0x20,
  382. BfTypeRebuildFlag_DeleteQueued = 0x40,
  383. BfTypeRebuildFlag_Deleted = 0x80,
  384. BfTypeRebuildFlag_AddedToWorkList = 0x100,
  385. BfTypeRebuildFlag_AwaitingReference = 0x200,
  386. BfTypeRebuildFlag_SpecializedMethodRebuild = 0x400, // Temporarily set
  387. BfTypeRebuildFlag_SpecializedByAutocompleteMethod = 0x800,
  388. BfTypeRebuildFlag_UnderlyingTypeDeferred = 0x1000,
  389. BfTypeRebuildFlag_TypeDataSaved = 0x2000,
  390. BfTypeRebuildFlag_InTempPool = 0x4000,
  391. BfTypeRebuildFlag_ResolvingBase = 0x8000,
  392. BfTypeRebuildFlag_InFailTypes = 0x10000,
  393. BfTypeRebuildFlag_RebuildQueued = 0x20000,
  394. BfTypeRebuildFlag_ConstEvalCancelled = 0x40000,
  395. BfTypeRebuildFlag_ChangedMidCompile = 0x80000,
  396. BfTypeRebuildFlag_PendingGenericArgDep = 0x100000
  397. };
  398. class BfTypeDIReplaceCallback;
  399. enum BfTypeDefineState : uint8
  400. {
  401. BfTypeDefineState_Undefined,
  402. BfTypeDefineState_Declaring,
  403. BfTypeDefineState_Declared,
  404. BfTypeDefineState_ResolvingBaseType,
  405. BfTypeDefineState_HasInterfaces_Direct,
  406. BfTypeDefineState_CETypeInit,
  407. BfTypeDefineState_CEPostTypeInit,
  408. BfTypeDefineState_HasInterfaces_All,
  409. BfTypeDefineState_Defined,
  410. BfTypeDefineState_CEAfterFields,
  411. BfTypeDefineState_DefinedAndMethodsSlotting,
  412. BfTypeDefineState_DefinedAndMethodsSlotted,
  413. };
  414. class BfDelegateInfo
  415. {
  416. public:
  417. Array<BfAstNode*> mDirectAllocNodes;
  418. BfType* mReturnType;
  419. Array<BfType*> mParams;
  420. bool mHasExplicitThis;
  421. bool mHasVarArgs;
  422. BfCallingConvention mCallingConvention;
  423. public:
  424. BfDelegateInfo()
  425. {
  426. mReturnType = NULL;
  427. mHasExplicitThis = false;
  428. mHasVarArgs = false;
  429. mCallingConvention = BfCallingConvention_Unspecified;
  430. }
  431. ~BfDelegateInfo()
  432. {
  433. for (auto directAllocNode : mDirectAllocNodes)
  434. delete directAllocNode;
  435. }
  436. };
  437. enum BfTypeUsage
  438. {
  439. BfTypeUsage_Unspecified,
  440. BfTypeUsage_Return_Static,
  441. BfTypeUsage_Return_NonStatic,
  442. BfTypeUsage_Parameter,
  443. };
  444. class BfType
  445. {
  446. public:
  447. BfTypeRebuildFlags mRebuildFlags;
  448. BfContext* mContext;
  449. int mTypeId;
  450. int mRevision;
  451. // For Objects, align and size is ref-sized (object*).
  452. // Use mInstSize/mInstAlign for actual data size/align
  453. int mSize;
  454. int16 mAlign;
  455. bool mDirty;
  456. BfTypeDefineState mDefineState;
  457. public:
  458. BfType();
  459. virtual ~BfType();
  460. BfTypeInstance* FindUnderlyingTypeInstance();
  461. virtual BfModule* GetModule();
  462. int GetStride() { return BF_ALIGN(mSize, mAlign); }
  463. bool IsSizeAligned() { return (mSize == 0) || (mSize % mAlign == 0); }
  464. virtual bool IsInstanceOf(BfTypeDef* typeDef) { return false; }
  465. virtual bool HasBeenReferenced() { return mDefineState != BfTypeDefineState_Undefined; }
  466. virtual bool HasTypeFailed() { return false; }
  467. virtual bool IsDataIncomplete() { return mDefineState == BfTypeDefineState_Undefined; }
  468. virtual bool IsFinishingType() { return false; }
  469. virtual bool IsIncomplete() { return mDefineState < BfTypeDefineState_Defined; }
  470. virtual bool IsDeleting() { return ((mRebuildFlags & (BfTypeRebuildFlag_Deleted | BfTypeRebuildFlag_DeleteQueued)) != 0); }
  471. virtual bool IsDeclared() { return mDefineState >= BfTypeDefineState_Declared; }
  472. virtual BfDependedType* ToDependedType() { return NULL; }
  473. virtual BfTypeInstance* ToTypeInstance() { return NULL; }
  474. virtual BfTypeInstance* ToGenericTypeInstance() { return NULL; }
  475. virtual BfPrimitiveType* ToPrimitiveType() { return NULL; }
  476. virtual bool IsDependendType() { return false; }
  477. virtual int GetGenericDepth() { return 0; }
  478. virtual bool IsTypeInstance() { return false; }
  479. virtual bool IsGenericTypeInstance() { return false; }
  480. virtual bool IsUnspecializedType() { return false; }
  481. virtual bool IsReified() { return true; }
  482. virtual bool IsSpecializedType() { return false; }
  483. virtual bool IsSpecializedByAutoCompleteMethod() { return false; }
  484. virtual bool IsUnspecializedTypeVariation() { return false; }
  485. virtual bool IsSplattable() { return false; }
  486. virtual int GetSplatCount(bool force = false) { return 1; }
  487. virtual bool IsVoid() { return false; }
  488. virtual bool IsVoidPtr() { return false; }
  489. virtual bool CanBeValuelessType() { return false; }
  490. virtual bool IsValuelessType() { BF_ASSERT(mSize != -1); BF_ASSERT(mDefineState >= BfTypeDefineState_Defined); return mSize == 0; }
  491. virtual bool IsSelf() { return false; }
  492. virtual bool IsDot() { return false; }
  493. virtual bool IsVar() { return false; }
  494. virtual bool IsLet() { return false; }
  495. virtual bool IsNull(){ return false; }
  496. virtual bool IsNullable() { return false; }
  497. virtual bool IsBoxed() { return false; }
  498. virtual bool IsInterface() { return false; }
  499. virtual bool IsEnum() { return false; }
  500. virtual bool IsPayloadEnum() { return false; }
  501. virtual bool IsTypedPrimitive() { return false; }
  502. virtual bool IsComposite() { return IsStruct(); }
  503. virtual bool IsStruct() { return false; }
  504. virtual bool IsStructPtr() { return false; }
  505. virtual bool IsUnion() { return false; }
  506. virtual bool IsStructOrStructPtr() { return false; }
  507. virtual bool IsObject() { return false; }
  508. virtual bool IsObjectOrStruct() { return false; }
  509. virtual bool IsObjectOrInterface() { return false; }
  510. virtual bool IsString() { return false; }
  511. virtual bool IsSizedArray() { return false; }
  512. virtual bool IsUndefSizedArray() { return false; }
  513. virtual bool IsUnknownSizedArrayType() { return false; }
  514. virtual bool IsArray() { return false; }
  515. virtual bool IsDelegate() { return false; }
  516. virtual bool IsFunction() { return false; }
  517. virtual bool IsDelegateOrFunction() { return false; }
  518. virtual bool IsDelegateFromTypeRef() { return false; }
  519. virtual bool IsFunctionFromTypeRef() { return false; }
  520. virtual BfDelegateInfo* GetDelegateInfo() { return NULL; }
  521. virtual bool IsValueType() { return false; }
  522. virtual bool IsOpaque() { return false; }
  523. virtual bool IsValueTypeOrValueTypePtr() { return false; }
  524. virtual bool IsWrappableType() { return false; }
  525. virtual bool IsPrimitiveType() { return false; }
  526. virtual BfTypeCode GetTypeCode() { return BfTypeCode_None; }
  527. virtual bool IsBoolean() { return false; }
  528. virtual bool IsInteger() { return false; }
  529. virtual bool IsIntegral() { return false; }
  530. virtual bool IsIntegralOrBool() { return false; }
  531. virtual bool IsIntPtr() { return false; }
  532. virtual bool IsSigned() { return false; }
  533. virtual bool IsSignedInt() { return false; }
  534. virtual bool IsIntUnknown() { return false; }
  535. virtual bool IsChar() { return false; }
  536. virtual bool IsFloat() { return false; }
  537. virtual bool IsPointer() { return false; }
  538. virtual bool IsAllocType() { return false; }
  539. virtual bool IsIntPtrable() { return false; }
  540. virtual bool IsRef() { return false; }
  541. virtual bool IsMut() { return false; }
  542. virtual bool IsIn() { return false; }
  543. virtual bool IsOut() { return false; }
  544. virtual bool IsGenericParam() { return false; }
  545. virtual bool IsTypeGenericParam() { return false; }
  546. virtual bool IsMethodGenericParam() { return false; }
  547. virtual bool IsClosure() { return false; }
  548. virtual bool IsMethodRef() { return false; }
  549. virtual bool IsTuple() { return false; }
  550. virtual bool IsOnDemand() { return false; }
  551. virtual bool IsTemporary() { return false; }
  552. virtual bool IsModifiedTypeType() { return false; }
  553. virtual bool IsConcreteInterfaceType() { return false; }
  554. virtual bool IsTypeAlias() { return false; }
  555. virtual bool HasPackingHoles() { return false; }
  556. virtual bool IsConstExprValue() { return false; }
  557. virtual bool IsDependentOnUnderlyingType() { return false; }
  558. virtual bool WantsGCMarking() { return false; }
  559. virtual bool GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCode = NULL, BfTypeCode* outTypeCode2 = NULL) { return false; }
  560. virtual BfType* GetUnderlyingType() { return NULL; }
  561. virtual bool HasWrappedRepresentation() { return IsWrappableType(); }
  562. virtual bool IsTypeMemberIncluded(BfTypeDef* declaringTypeDef, BfTypeDef* activeTypeDef = NULL, BfModule* module = NULL) { return true; } // May be 'false' only for generic extensions with constraints
  563. virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfTypeDef* activeTypeDef) { return true; }
  564. virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfProject* curProject) { return true; }
  565. virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfProjectSet* visibleProjectSet) { return true; }
  566. virtual void ReportMemory(MemReporter* memReporter);
  567. };
  568. class BfElementedType : public BfType
  569. {
  570. public:
  571. int mGenericDepth;
  572. public:
  573. BfElementedType()
  574. {
  575. mGenericDepth = 0;
  576. }
  577. virtual int GetGenericDepth() override { return mGenericDepth; }
  578. };
  579. // This is explicitly used for generics
  580. typedef SizedArray<BfType*, 2> BfTypeVector;
  581. typedef SizedArray<BfTypeReference*, 2> BfTypeRefVector;
  582. class BfPrimitiveType : public BfType
  583. {
  584. public:
  585. BfTypeDef* mTypeDef;
  586. public:
  587. virtual bool IsPrimitiveType() override { return true; }
  588. virtual BfTypeCode GetTypeCode() override { return mTypeDef->mTypeCode; }
  589. virtual bool IsWrappableType() override { return ((mTypeDef->mTypeCode >= BfTypeCode_Boolean) && (mTypeDef->mTypeCode <= BfTypeCode_Double)) || (mTypeDef->mTypeCode == BfTypeCode_None); }
  590. virtual BfPrimitiveType* ToPrimitiveType() override { return this; }
  591. //virtual bool IsValueType() override { return mTypeDef->mTypeCode != BfTypeCode_None; }
  592. //virtual bool IsValueTypeOrValueTypePtr() override { return mTypeDef->mTypeCode != BfTypeCode_None; }
  593. virtual bool IsValueType() override { return true; }
  594. virtual bool IsValueTypeOrValueTypePtr() override { return true; }
  595. virtual bool IsBoolean() override { return mTypeDef->mTypeCode == BfTypeCode_Boolean; }
  596. virtual bool IsIntegral() override { return (mTypeDef->mTypeCode >= BfTypeCode_Int8) && (mTypeDef->mTypeCode <= BfTypeCode_Char32); }
  597. virtual bool IsIntegralOrBool() override { return (mTypeDef->mTypeCode >= BfTypeCode_Boolean) && (mTypeDef->mTypeCode <= BfTypeCode_Char32); }
  598. virtual bool IsInteger() override { return (mTypeDef->mTypeCode >= BfTypeCode_Int8) && (mTypeDef->mTypeCode <= BfTypeCode_UIntUnknown); }
  599. virtual bool IsIntPtr() override { return (mTypeDef->mTypeCode == BfTypeCode_IntPtr) || (mTypeDef->mTypeCode == BfTypeCode_UIntPtr); }
  600. virtual bool IsIntPtrable() override
  601. {
  602. return (mTypeDef->mTypeCode == BfTypeCode_IntPtr) || (mTypeDef->mTypeCode == BfTypeCode_UIntPtr) ||
  603. ((mTypeDef->mSystem->mPtrSize == 8) && ((mTypeDef->mTypeCode == BfTypeCode_Int64) || (mTypeDef->mTypeCode == BfTypeCode_UInt64))) ||
  604. ((mTypeDef->mSystem->mPtrSize == 4) && ((mTypeDef->mTypeCode == BfTypeCode_Int32) || (mTypeDef->mTypeCode == BfTypeCode_UInt32)));
  605. }
  606. virtual bool IsSigned() override { return (mTypeDef->mTypeCode == BfTypeCode_Int8) || (mTypeDef->mTypeCode == BfTypeCode_Int16) ||
  607. (mTypeDef->mTypeCode == BfTypeCode_Int32) || (mTypeDef->mTypeCode == BfTypeCode_Int64) || (mTypeDef->mTypeCode == BfTypeCode_IntPtr) ||
  608. (mTypeDef->mTypeCode == BfTypeCode_IntUnknown) ||
  609. (mTypeDef->mTypeCode == BfTypeCode_Float) || (mTypeDef->mTypeCode == BfTypeCode_Double); }
  610. virtual bool IsSignedInt() override { return (mTypeDef->mTypeCode == BfTypeCode_Int8) || (mTypeDef->mTypeCode == BfTypeCode_Int16) ||
  611. (mTypeDef->mTypeCode == BfTypeCode_Int32) || (mTypeDef->mTypeCode == BfTypeCode_Int64) || (mTypeDef->mTypeCode == BfTypeCode_IntPtr) ||
  612. (mTypeDef->mTypeCode == BfTypeCode_IntUnknown); }
  613. virtual bool IsIntUnknown() override { return (mTypeDef->mTypeCode == BfTypeCode_IntUnknown) || (mTypeDef->mTypeCode == BfTypeCode_UIntUnknown); }
  614. virtual bool IsChar() override { return (mTypeDef->mTypeCode == BfTypeCode_Char8) || (mTypeDef->mTypeCode == BfTypeCode_Char16) || (mTypeDef->mTypeCode == BfTypeCode_Char32); }
  615. virtual bool IsFloat() override { return (mTypeDef->mTypeCode == BfTypeCode_Float) || (mTypeDef->mTypeCode == BfTypeCode_Double); }
  616. virtual bool IsNull() override { return mTypeDef->mTypeCode == BfTypeCode_NullPtr; }
  617. virtual bool IsVoid() override { return mTypeDef->mTypeCode == BfTypeCode_None; }
  618. virtual bool CanBeValuelessType() override { return mTypeDef->mTypeCode == BfTypeCode_None; }
  619. virtual bool IsValuelessType() override { return mTypeDef->mTypeCode == BfTypeCode_None; }
  620. virtual bool IsSelf() override { return mTypeDef->mTypeCode == BfTypeCode_Self; }
  621. virtual bool IsDot() override { return mTypeDef->mTypeCode == BfTypeCode_Dot; }
  622. virtual bool IsVar() override { return mTypeDef->mTypeCode == BfTypeCode_Var; }
  623. virtual bool IsLet() override { return mTypeDef->mTypeCode == BfTypeCode_Let; }
  624. virtual bool IsUnspecializedType() override { return mTypeDef->mTypeCode == BfTypeCode_Self; }
  625. virtual bool IsUnspecializedTypeVariation() override { return mTypeDef->mTypeCode == BfTypeCode_Self; }
  626. };
  627. class BfTypeInstance;
  628. class BfMethodInstanceGroup;
  629. class BfGenericParamInstance;
  630. class BfGenericMethodParamInstance;
  631. class BfDeferredMethodCallData
  632. {
  633. public:
  634. // void* mPrev, int mMethodId, <method params>
  635. BfIRType mDeferType;
  636. BfIRType mDeferTypePtr;
  637. BfIRMDNode mDeferDIType;
  638. int mAlign;
  639. int mSize;
  640. int64 mMethodId; // Usually matches methodInstance mIdHash unless there's a collision
  641. public:
  642. BfDeferredMethodCallData()
  643. {
  644. mAlign = 0;
  645. mSize = 0;
  646. mMethodId = 0;
  647. }
  648. static int64 GenerateMethodId(BfModule* module, int64 methodId);
  649. };
  650. class BfMethodCustomAttributes
  651. {
  652. public:
  653. BfCustomAttributes* mCustomAttributes;
  654. BfCustomAttributes* mReturnCustomAttributes;
  655. Array<BfCustomAttributes*> mParamCustomAttributes;
  656. public:
  657. BfMethodCustomAttributes()
  658. {
  659. mCustomAttributes = NULL;
  660. mReturnCustomAttributes = NULL;
  661. }
  662. ~BfMethodCustomAttributes();
  663. };
  664. class BfMethodParam
  665. {
  666. public:
  667. BfType* mResolvedType;
  668. int16 mParamDefIdx;
  669. int16 mDelegateParamIdx;
  670. bool mDelegateParamNameCombine; // 'false' means to directly use param name (if we can), otherwise name as <baseParamName>__<delegateParamName>
  671. bool mWasGenericParam;
  672. bool mIsSplat;
  673. bool mReferencedInConstPass;
  674. public:
  675. BfMethodParam()
  676. {
  677. mResolvedType = NULL;
  678. mParamDefIdx = -1;
  679. mDelegateParamIdx = -1;
  680. mDelegateParamNameCombine = false;
  681. mWasGenericParam = false;
  682. mIsSplat = false;
  683. mReferencedInConstPass = false;
  684. }
  685. BfMethodInstance* GetDelegateParamInvoke();
  686. };
  687. enum BfMethodOnDemandKind : int8
  688. {
  689. BfMethodOnDemandKind_NotSet,
  690. BfMethodOnDemandKind_AlwaysInclude,
  691. BfMethodOnDemandKind_NoDecl_AwaitingReference, // Won't be declared until we reference
  692. BfMethodOnDemandKind_Decl_AwaitingReference, // Will be declared immediately but not processed until referenced
  693. BfMethodOnDemandKind_Decl_AwaitingDecl, // Temporary state before we switch to BfMethodOnDemandKind_Decl_AwaitingReference
  694. BfMethodOnDemandKind_InWorkList,
  695. BfMethodOnDemandKind_Referenced
  696. };
  697. enum BfMethodChainType : int8
  698. {
  699. BfMethodChainType_None,
  700. BfMethodChainType_ChainHead,
  701. BfMethodChainType_ChainMember,
  702. BfMethodChainType_ChainSkip,
  703. };
  704. class BfMethodProcessRequest;
  705. class BfLocalMethod;
  706. class BfClosureState;
  707. struct BfClosureCapturedEntry
  708. {
  709. BfType* mType;
  710. String mName;
  711. BfIdentifierNode* mNameNode;
  712. bool mExplicitlyByReference;
  713. int mShadowIdx; // Only relative to matching nameNodes
  714. BfClosureCapturedEntry()
  715. {
  716. mNameNode = NULL;
  717. mType = NULL;
  718. mExplicitlyByReference = false;
  719. mShadowIdx = 0;
  720. }
  721. bool operator<(const BfClosureCapturedEntry& other) const
  722. {
  723. if (mName == "__this")
  724. return true;
  725. else if (other.mName == "__this")
  726. return false;
  727. return mName < other.mName;
  728. }
  729. };
  730. class BfClosureInstanceInfo
  731. {
  732. public:
  733. BfTypeInstance* mThisOverride;
  734. BfLocalMethod* mLocalMethod;
  735. Dictionary<int64, BfMethodDef*> mLocalMethodBindings; // We create binding during capture and use it during mDeferredLocalMethods processing
  736. BfClosureState* mCaptureClosureState;
  737. Array<BfClosureCapturedEntry> mCaptureEntries;
  738. public:
  739. BfClosureInstanceInfo()
  740. {
  741. mThisOverride = NULL;
  742. mLocalMethod = NULL;
  743. mCaptureClosureState = NULL;
  744. }
  745. };
  746. class BfMethodInfoEx
  747. {
  748. public:
  749. StringT<0> mMangledName; // Only populated during hot loading for virtual methods
  750. BfTypeInstance* mExplicitInterface;
  751. BfTypeInstance* mForeignType;
  752. BfClosureInstanceInfo* mClosureInstanceInfo;
  753. Array<BfGenericMethodParamInstance*> mGenericParams;
  754. BfTypeVector mMethodGenericArguments;
  755. Dictionary<int64, BfType*> mGenericTypeBindings;
  756. BfMethodCustomAttributes* mMethodCustomAttributes;
  757. int mMinDependDepth;
  758. BfMethodInfoEx()
  759. {
  760. mExplicitInterface = NULL;
  761. mForeignType = NULL;
  762. mClosureInstanceInfo = NULL;
  763. mMethodCustomAttributes = NULL;
  764. mMinDependDepth = -1;
  765. }
  766. ~BfMethodInfoEx();
  767. };
  768. enum BfImportCallKind
  769. {
  770. BfImportCallKind_None,
  771. BfImportCallKind_GlobalVar,
  772. BfImportCallKind_GlobalVar_Hot // We need to check against NULL in this case
  773. };
  774. class BfMethodInstance
  775. {
  776. public:
  777. int mVirtualTableIdx;
  778. BfIRFunction mIRFunction; // Only valid for owning module
  779. int16 mAppendAllocAlign;
  780. int16 mEndingAppendAllocAlign;
  781. bool mIsUnspecialized:1;
  782. bool mIsUnspecializedVariation:1;
  783. bool mIsReified:1;
  784. bool mHasStartedDeclaration:1;
  785. bool mHasBeenDeclared:1;
  786. bool mHasBeenProcessed:1;
  787. bool mHasFailed:1;
  788. bool mHasWarning:1;
  789. bool mFailedConstraints:1;
  790. bool mMangleWithIdx:1;
  791. bool mHadGenericDelegateParams:1;
  792. bool mIgnoreBody:1;
  793. bool mIsAutocompleteMethod:1;
  794. bool mRequestedByAutocomplete : 1;
  795. bool mIsClosure:1;
  796. bool mMayBeConst:1; // Only used for calcAppend currently
  797. bool mIsForeignMethodDef:1;
  798. bool mAlwaysInline:1;
  799. bool mIsIntrinsic:1;
  800. bool mHasMethodRefType:1;
  801. bool mDisallowCalling:1;
  802. bool mIsInnerOverride:1;
  803. bool mInCEMachine:1;
  804. bool mCeCancelled:1;
  805. bool mIsDisposed:1;
  806. BfMethodChainType mChainType;
  807. BfComptimeFlags mComptimeFlags;
  808. BfCallingConvention mCallingConvention;
  809. BfMethodInstanceGroup* mMethodInstanceGroup;
  810. BfMethodDef* mMethodDef;
  811. BfType* mReturnType;
  812. Array<BfMethodParam> mParams;
  813. Array<BfTypedValue> mDefaultValues;
  814. BfModule* mDeclModule;
  815. BfMethodProcessRequest* mMethodProcessRequest;
  816. BfMethodInfoEx* mMethodInfoEx;
  817. int64 mIdHash; // Collisions are (essentially) benign
  818. BfHotMethod* mHotMethod;
  819. public:
  820. BfMethodInstance()
  821. {
  822. mVirtualTableIdx = -1;
  823. mIsUnspecialized = false;
  824. mIsUnspecializedVariation = false;
  825. mIsReified = true;
  826. mHasStartedDeclaration = false;
  827. mHasBeenDeclared = false;
  828. mHasBeenProcessed = false;
  829. mHasFailed = false;
  830. mHasWarning = false;
  831. mFailedConstraints = false;
  832. mMangleWithIdx = false;
  833. mHadGenericDelegateParams = false;
  834. mIgnoreBody = false;
  835. mIsAutocompleteMethod = false;
  836. mRequestedByAutocomplete = false;
  837. mIsClosure = false;
  838. mMayBeConst = true;
  839. mIsForeignMethodDef = false;
  840. mAlwaysInline = false;
  841. mIsIntrinsic = false;
  842. mHasMethodRefType = false;
  843. mDisallowCalling = false;
  844. mIsInnerOverride = false;
  845. mInCEMachine = false;
  846. mCeCancelled = false;
  847. mIsDisposed = false;
  848. mChainType = BfMethodChainType_None;
  849. mComptimeFlags = BfComptimeFlag_None;
  850. mCallingConvention = BfCallingConvention_Unspecified;
  851. mMethodInstanceGroup = NULL;
  852. mMethodDef = NULL;
  853. mReturnType = NULL;
  854. mIdHash = 0;
  855. mAppendAllocAlign = -1;
  856. mEndingAppendAllocAlign = -1;
  857. mDeclModule = NULL;
  858. mMethodProcessRequest = NULL;
  859. mMethodInfoEx = NULL;
  860. mHotMethod = NULL;
  861. }
  862. ~BfMethodInstance();
  863. void Dispose(bool isDeleting = false);
  864. void CopyFrom(BfMethodInstance* methodInstance);
  865. bool IsMixin()
  866. {
  867. return mMethodDef->mMethodType == BfMethodType_Mixin;
  868. }
  869. BfImportKind GetImportKind();
  870. BfMethodFlags GetMethodFlags();
  871. BfComptimeMethodFlags GetComptimeMethodFlags();
  872. void UndoDeclaration(bool keepIRFunction = false);
  873. BfTypeInstance* GetOwner();
  874. BfModule* GetModule();
  875. bool IsSpecializedGenericMethod();
  876. bool IsSpecializedGenericMethodOrType();
  877. bool IsSpecializedByAutoCompleteMethod();
  878. bool IsOrInUnspecializedVariation();
  879. bool HasExternConstraints();
  880. bool HasThis();
  881. bool IsVirtual();
  882. BfType* GetThisType();
  883. int GetThisIdx();
  884. bool HasExplicitThis();
  885. bool HasParamsArray();
  886. int GetStructRetIdx(bool forceStatic = false);
  887. bool HasSelf();
  888. bool GetLoweredReturnType(BfTypeCode* loweredTypeCode = NULL, BfTypeCode* loweredTypeCode2 = NULL, bool forceStatic = false);
  889. bool WantsStructsAttribByVal(BfType* paramType);
  890. bool IsAutocompleteMethod() { /*return mIdHash == -1;*/ return mIsAutocompleteMethod; }
  891. bool IsSkipCall(bool bypassVirtual = false);
  892. bool IsVarArgs();
  893. bool AlwaysInline();
  894. BfImportCallKind GetImportCallKind();
  895. bool IsTestMethod();
  896. bool AllowsSplatting(int paramIdx);
  897. int GetParamCount();
  898. int GetImplicitParamCount();
  899. void GetParamName(int paramIdx, StringImpl& name, int& namePrefixCount);
  900. String GetParamName(int paramIdx);
  901. String GetParamName(int paramIdx, int& namePrefixCount);
  902. BfType* GetParamType(int paramIdx, bool returnUnderlyingParamsType = false);
  903. bool GetParamIsSplat(int paramIdx);
  904. BfParamKind GetParamKind(int paramIdx);
  905. bool WasGenericParam(int paramIdx);
  906. bool IsParamSkipped(int paramIdx); // void/zero-sized
  907. bool IsImplicitCapture(int paramIdx);
  908. BfExpression* GetParamInitializer(int paramIdx);
  909. BfTypeReference* GetParamTypeRef(int paramIdx);
  910. BfIdentifierNode* GetParamNameNode(int paramIdx);
  911. int DbgGetVirtualMethodNum();
  912. void GetIRFunctionInfo(BfModule* module, BfIRType& returnType, SizedArrayImpl<BfIRType>& paramTypes, bool forceStatic = false);
  913. int GetIRFunctionParamCount(BfModule* module);
  914. bool IsExactMatch(BfMethodInstance* other, bool ignoreImplicitParams = false, bool checkThis = false);
  915. bool IsReifiedAndImplemented();
  916. BfMethodInfoEx* GetMethodInfoEx();
  917. BfCustomAttributes* GetCustomAttributes()
  918. {
  919. if ((mMethodInfoEx != NULL) && (mMethodInfoEx->mMethodCustomAttributes != NULL))
  920. return mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes;
  921. return NULL;
  922. }
  923. int GetNumGenericParams()
  924. {
  925. if (mMethodInfoEx != NULL)
  926. return (int)mMethodInfoEx->mGenericParams.size();
  927. return 0;
  928. }
  929. int GetNumGenericArguments()
  930. {
  931. if (mMethodInfoEx != NULL)
  932. return (int)mMethodInfoEx->mMethodGenericArguments.size();
  933. return 0;
  934. }
  935. BfTypeInstance* GetExplicitInterface()
  936. {
  937. if (mMethodInfoEx != NULL)
  938. return mMethodInfoEx->mExplicitInterface;
  939. return NULL;
  940. }
  941. BfTypeInstance* GetForeignType()
  942. {
  943. if (mMethodInfoEx != NULL)
  944. return mMethodInfoEx->mForeignType;
  945. return NULL;
  946. }
  947. void ReportMemory(MemReporter* memReporter);
  948. };
  949. class BfOperatorInfo
  950. {
  951. public:
  952. BfMethodDef* mMethodDef;
  953. BfType* mReturnType;
  954. BfType* mLHSType;
  955. BfType* mRHSType;
  956. BfOperatorInfo()
  957. {
  958. mMethodDef = NULL;
  959. mReturnType = NULL;
  960. mLHSType = NULL;
  961. mRHSType = NULL;
  962. }
  963. };
  964. class BfDllImportEntry
  965. {
  966. public:
  967. BfMethodInstance* mMethodInstance;
  968. BfIRValue mFuncVar;
  969. //BfIRFunctionType mFuncType;
  970. };
  971. class BfModuleMethodInstance
  972. {
  973. public:
  974. BfMethodInstance* mMethodInstance;
  975. BfIRValue mFunc;
  976. public:
  977. BfModuleMethodInstance()
  978. {
  979. mMethodInstance = NULL;
  980. }
  981. BfModuleMethodInstance(BfMethodInstance* methodInstance);
  982. BfModuleMethodInstance(BfMethodInstance* methodInstance, BfIRValue func) : mFunc(func)
  983. {
  984. mMethodInstance = methodInstance;
  985. }
  986. operator bool() const
  987. {
  988. return mMethodInstance != NULL;
  989. }
  990. };
  991. // The way these work is a bit nuanced
  992. // When we use these as keys, we allow collisions between genericParams from different type and
  993. // method instances. That's okay, as the only constraint there is that they generate valid
  994. // generic-pass methods, which will all be the same. Within the SCOPE of a given type and
  995. // method instance, however, we cannot have collision between types (such as a List<T> and List<T2>)
  996. // because that can cause false equalties in the type checker
  997. class BfGenericParamType : public BfType
  998. {
  999. public:
  1000. BfGenericParamKind mGenericParamKind;
  1001. int mGenericParamIdx;
  1002. public:
  1003. bool IsGenericParam() override { return true; }
  1004. bool IsTypeGenericParam() override { return mGenericParamKind == BfGenericParamKind_Type; }
  1005. bool IsMethodGenericParam() override { return mGenericParamKind == BfGenericParamKind_Method; }
  1006. virtual bool IsUnspecializedType() override { return true; }
  1007. virtual bool IsReified() override { return false; }
  1008. };
  1009. // This just captures rettype(T)/nullable(T) since it can't be resolved directly
  1010. class BfModifiedTypeType : public BfType
  1011. {
  1012. public:
  1013. BfToken mModifiedKind;
  1014. BfType* mElementType;
  1015. virtual bool IsModifiedTypeType() override { return true; }
  1016. virtual bool CanBeValuelessType() override { return true; }
  1017. virtual bool IsValuelessType() override { return true; }
  1018. virtual bool IsUnspecializedType() override { return mElementType->IsUnspecializedType(); }
  1019. virtual bool IsUnspecializedTypeVariation() override { return mElementType->IsUnspecializedType(); }
  1020. virtual bool IsReified() override { return mElementType->IsReified(); }
  1021. virtual bool IsDependentOnUnderlyingType() override { return true; }
  1022. virtual bool IsAllocType() override { return mModifiedKind == BfToken_AllocType; }
  1023. virtual BfType* GetUnderlyingType() override { return mElementType; }
  1024. };
  1025. class BfGenericOperatorConstraintInstance
  1026. {
  1027. public:
  1028. BfType* mLeftType;
  1029. BfBinaryOp mBinaryOp;
  1030. BfUnaryOp mUnaryOp;
  1031. BfToken mCastToken;
  1032. BfType* mRightType;
  1033. public:
  1034. BfGenericOperatorConstraintInstance()
  1035. {
  1036. mLeftType = NULL;
  1037. mBinaryOp = BfBinaryOp_None;
  1038. mUnaryOp = BfUnaryOp_None;
  1039. mCastToken = BfToken_None;
  1040. mRightType = NULL;
  1041. }
  1042. bool operator==(const BfGenericOperatorConstraintInstance& other) const
  1043. {
  1044. return
  1045. (mLeftType == other.mLeftType) &&
  1046. (mBinaryOp == other.mBinaryOp) &&
  1047. (mUnaryOp == other.mUnaryOp) &&
  1048. (mCastToken == other.mCastToken) &&
  1049. (mRightType == other.mRightType);
  1050. }
  1051. };
  1052. class BfGenericParamInstance
  1053. {
  1054. public:
  1055. BfGenericParamFlags mGenericParamFlags;
  1056. BfType* mExternType;
  1057. Array<BfTypeInstance*> mInterfaceConstraints;
  1058. HashSet<BfTypeInstance*>* mInterfaceConstraintSet;
  1059. Array<BfGenericOperatorConstraintInstance> mOperatorConstraints;
  1060. Array<BfTypeReference*> mComptypeConstraint;
  1061. BfType* mTypeConstraint;
  1062. int mRefCount;
  1063. BfGenericParamInstance()
  1064. {
  1065. mExternType = NULL;
  1066. mGenericParamFlags = BfGenericParamFlag_None;
  1067. mTypeConstraint = NULL;
  1068. mInterfaceConstraintSet = NULL;
  1069. mRefCount = 1;
  1070. }
  1071. void Release()
  1072. {
  1073. if (--mRefCount == 0)
  1074. delete this;
  1075. }
  1076. virtual ~BfGenericParamInstance()
  1077. {
  1078. delete mInterfaceConstraintSet;
  1079. }
  1080. virtual BfConstraintDef* GetConstraintDef() = 0;
  1081. virtual BfGenericParamDef* GetGenericParamDef() = 0;
  1082. virtual BfExternalConstraintDef* GetExternConstraintDef() = 0;
  1083. virtual String GetName() = 0;
  1084. virtual BfAstNode* GetRefNode() = 0;
  1085. bool IsEnum();
  1086. };
  1087. class BfGenericTypeParamInstance : public BfGenericParamInstance
  1088. {
  1089. public:
  1090. BfTypeDef* mTypeDef;
  1091. int mGenericIdx;
  1092. public:
  1093. BfGenericTypeParamInstance(BfTypeDef* typeDef, int genericIdx)
  1094. {
  1095. mTypeDef = typeDef;
  1096. mGenericIdx = genericIdx;
  1097. mGenericParamFlags = GetConstraintDef()->mGenericParamFlags;
  1098. mTypeConstraint = NULL;
  1099. }
  1100. BfGenericTypeParamInstance* AddRef()
  1101. {
  1102. mRefCount++;
  1103. return this;
  1104. }
  1105. virtual BfConstraintDef* GetConstraintDef() override
  1106. {
  1107. if (mGenericIdx < (int)mTypeDef->mGenericParamDefs.size())
  1108. return mTypeDef->mGenericParamDefs[mGenericIdx];
  1109. return &mTypeDef->mExternalConstraints[mGenericIdx - (int)mTypeDef->mGenericParamDefs.size()];
  1110. }
  1111. virtual BfGenericParamDef* GetGenericParamDef() override
  1112. {
  1113. if (mGenericIdx < (int)mTypeDef->mGenericParamDefs.size())
  1114. return mTypeDef->mGenericParamDefs[mGenericIdx];
  1115. return NULL;
  1116. }
  1117. virtual BfExternalConstraintDef* GetExternConstraintDef() override
  1118. {
  1119. if (mGenericIdx < (int)mTypeDef->mGenericParamDefs.size())
  1120. return NULL;
  1121. return &mTypeDef->mExternalConstraints[mGenericIdx - (int)mTypeDef->mGenericParamDefs.size()];
  1122. }
  1123. virtual String GetName() override
  1124. {
  1125. if (mGenericIdx < (int)mTypeDef->mGenericParamDefs.size())
  1126. return mTypeDef->mGenericParamDefs[mGenericIdx]->mName;
  1127. return mTypeDef->mExternalConstraints[mGenericIdx - (int)mTypeDef->mGenericParamDefs.size()].mTypeRef->ToString();
  1128. }
  1129. virtual BfAstNode* GetRefNode() override
  1130. {
  1131. if (mGenericIdx < (int)mTypeDef->mGenericParamDefs.size())
  1132. return mTypeDef->mGenericParamDefs[mGenericIdx]->mNameNodes[0];
  1133. return mTypeDef->mExternalConstraints[mGenericIdx - (int)mTypeDef->mGenericParamDefs.size()].mTypeRef;
  1134. }
  1135. };
  1136. class BfGenericMethodParamInstance : public BfGenericParamInstance
  1137. {
  1138. public:
  1139. BfMethodDef* mMethodDef;
  1140. int mGenericIdx;
  1141. public:
  1142. BfGenericMethodParamInstance(BfMethodDef* methodDef, int genericIdx)
  1143. {
  1144. mMethodDef = methodDef;
  1145. mGenericIdx = genericIdx;
  1146. mGenericParamFlags = GetConstraintDef()->mGenericParamFlags;
  1147. mTypeConstraint = NULL;
  1148. }
  1149. BfGenericMethodParamInstance* AddRef()
  1150. {
  1151. mRefCount++;
  1152. return this;
  1153. }
  1154. virtual BfConstraintDef* GetConstraintDef() override
  1155. {
  1156. if (mGenericIdx < (int)mMethodDef->mGenericParams.size())
  1157. return mMethodDef->mGenericParams[mGenericIdx];
  1158. return &mMethodDef->mExternalConstraints[mGenericIdx - (int)mMethodDef->mGenericParams.size()];
  1159. }
  1160. virtual BfGenericParamDef* GetGenericParamDef() override
  1161. {
  1162. if (mGenericIdx < (int)mMethodDef->mGenericParams.size())
  1163. return mMethodDef->mGenericParams[mGenericIdx];
  1164. return NULL;
  1165. }
  1166. virtual BfExternalConstraintDef* GetExternConstraintDef() override
  1167. {
  1168. if (mGenericIdx < (int)mMethodDef->mGenericParams.size())
  1169. return NULL;
  1170. return &mMethodDef->mExternalConstraints[mGenericIdx - (int)mMethodDef->mGenericParams.size()];
  1171. }
  1172. virtual String GetName() override
  1173. {
  1174. if (mGenericIdx < (int)mMethodDef->mGenericParams.size())
  1175. return mMethodDef->mGenericParams[mGenericIdx]->mName;
  1176. return mMethodDef->mExternalConstraints[mGenericIdx - (int)mMethodDef->mGenericParams.size()].mTypeRef->ToString();
  1177. }
  1178. virtual BfAstNode* GetRefNode() override
  1179. {
  1180. if (mGenericIdx < (int)mMethodDef->mGenericParams.size())
  1181. return mMethodDef->mGenericParams[mGenericIdx]->mNameNodes[0];
  1182. return mMethodDef->mExternalConstraints[mGenericIdx - (int)mMethodDef->mGenericParams.size()].mTypeRef;
  1183. }
  1184. };
  1185. #define BF_VALCOMP(val) if (val != 0) return val
  1186. struct BfTypeVectorHash
  1187. {
  1188. size_t operator()(const BfTypeVector& val) const;
  1189. };
  1190. struct BfTypeVectorEquals
  1191. {
  1192. bool operator()(const BfTypeVector& lhs, const BfTypeVector& rhs) const;
  1193. };
  1194. // Specialized for Class<T> but not Method<T>
  1195. class BfMethodInstanceGroup
  1196. {
  1197. public:
  1198. BfTypeInstance* mOwner;
  1199. BfMethodInstance* mDefault;
  1200. typedef Dictionary<BfTypeVector, BfMethodInstance*> MapType;
  1201. MapType* mMethodSpecializationMap;
  1202. BfCustomAttributes* mDefaultCustomAttributes;
  1203. int mMethodIdx;
  1204. int mRefCount; // External references from BfMethodRefType
  1205. BfMethodOnDemandKind mOnDemandKind;
  1206. bool mExplicitlyReflected;
  1207. bool mHasEmittedReference;
  1208. public:
  1209. BfMethodInstanceGroup()
  1210. {
  1211. mOwner = NULL;
  1212. mDefault = NULL;
  1213. mMethodSpecializationMap = NULL;
  1214. mDefaultCustomAttributes = NULL;
  1215. mMethodIdx = -1;
  1216. mOnDemandKind = BfMethodOnDemandKind_NotSet;
  1217. mRefCount = 0;
  1218. mExplicitlyReflected = false;
  1219. mHasEmittedReference = false;
  1220. }
  1221. BfMethodInstanceGroup(BfMethodInstanceGroup&& prev) noexcept;
  1222. ~BfMethodInstanceGroup();
  1223. bool IsImplemented()
  1224. {
  1225. return (mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude) ||
  1226. (mOnDemandKind == BfMethodOnDemandKind_Referenced) ||
  1227. (mOnDemandKind == BfMethodOnDemandKind_InWorkList);
  1228. }
  1229. };
  1230. class BfFieldInstance
  1231. {
  1232. public:
  1233. BfTypeInstance* mOwner;
  1234. BfType* mResolvedType;
  1235. BfCustomAttributes* mCustomAttributes;
  1236. int mConstIdx;
  1237. int mFieldIdx;
  1238. int mDataIdx; // mFieldIdx includes statics & consts, mDataIdx does not
  1239. int mMergedDataIdx; // Like mDataIdx but contains base class's data
  1240. int mDataOffset;
  1241. int mDataSize;
  1242. bool mFieldIncluded;
  1243. bool mIsEnumPayloadCase;
  1244. bool mIsInferredType;
  1245. bool mHadConstEval;
  1246. int mLastRevisionReferenced;
  1247. public:
  1248. BfFieldDef* GetFieldDef();
  1249. BfFieldInstance(BfFieldInstance&& copyFrom)
  1250. {
  1251. mCustomAttributes = copyFrom.mCustomAttributes;
  1252. copyFrom.mCustomAttributes = NULL;
  1253. mOwner = copyFrom.mOwner;
  1254. mResolvedType = copyFrom.mResolvedType;
  1255. mCustomAttributes = copyFrom.mCustomAttributes;
  1256. mConstIdx = copyFrom.mConstIdx;
  1257. mFieldIdx = copyFrom.mFieldIdx;
  1258. mDataIdx = copyFrom.mDataIdx;
  1259. mMergedDataIdx = copyFrom.mMergedDataIdx;
  1260. mDataOffset = copyFrom.mDataOffset;
  1261. mDataSize = copyFrom.mDataSize;
  1262. mFieldIncluded = copyFrom.mFieldIncluded;
  1263. mIsEnumPayloadCase = copyFrom.mIsEnumPayloadCase;
  1264. mIsInferredType = copyFrom.mIsInferredType;
  1265. mHadConstEval = copyFrom.mHadConstEval;
  1266. mLastRevisionReferenced = copyFrom.mLastRevisionReferenced;
  1267. }
  1268. BfFieldInstance(const BfFieldInstance& copyFrom)
  1269. {
  1270. BF_ASSERT(copyFrom.mCustomAttributes == NULL);
  1271. mOwner = copyFrom.mOwner;
  1272. mResolvedType = copyFrom.mResolvedType;
  1273. mCustomAttributes = copyFrom.mCustomAttributes;
  1274. mConstIdx = copyFrom.mConstIdx;
  1275. mFieldIdx = copyFrom.mFieldIdx;
  1276. mDataIdx = copyFrom.mDataIdx;
  1277. mMergedDataIdx = copyFrom.mMergedDataIdx;
  1278. mDataOffset = copyFrom.mDataOffset;
  1279. mDataSize = copyFrom.mDataSize;
  1280. mFieldIncluded = copyFrom.mFieldIncluded;
  1281. mIsEnumPayloadCase = copyFrom.mIsEnumPayloadCase;
  1282. mIsInferredType = copyFrom.mIsInferredType;
  1283. mHadConstEval = copyFrom.mHadConstEval;
  1284. mLastRevisionReferenced = copyFrom.mLastRevisionReferenced;
  1285. }
  1286. BfFieldInstance()
  1287. {
  1288. mFieldIdx = -1;
  1289. mOwner = NULL;
  1290. mResolvedType = NULL;
  1291. mIsEnumPayloadCase = false;
  1292. mCustomAttributes = NULL;
  1293. mConstIdx = -1;
  1294. mDataIdx = -1;
  1295. mMergedDataIdx = -1;
  1296. mDataOffset = -1;
  1297. mDataSize = 0;
  1298. mFieldIncluded = true;
  1299. mIsInferredType = false;
  1300. mHadConstEval = false;
  1301. mLastRevisionReferenced = -1;
  1302. }
  1303. ~BfFieldInstance();
  1304. BfType* GetResolvedType();
  1305. void SetResolvedType(BfType* type);
  1306. void GetDataRange(int& dataIdx, int& dataCount);
  1307. int GetAlign(int packing);
  1308. bool IsAppendedObject();
  1309. };
  1310. enum BfMethodRefKind
  1311. {
  1312. BfMethodRefKind_VExtMarker = -1,
  1313. BfMethodRefKind_AmbiguousRef = -2
  1314. };
  1315. class BfNonGenericMethodRef
  1316. {
  1317. public:
  1318. BfTypeInstance* mTypeInstance;
  1319. union
  1320. {
  1321. int mMethodNum;
  1322. BfMethodRefKind mKind;
  1323. };
  1324. int mSignatureHash;
  1325. BfNonGenericMethodRef()
  1326. {
  1327. mTypeInstance = NULL;
  1328. mMethodNum = 0;
  1329. mSignatureHash = 0;
  1330. }
  1331. BfNonGenericMethodRef(BfMethodInstance* methodInstance);
  1332. operator BfMethodInstance*() const;
  1333. bool IsNull() { return mTypeInstance == NULL; };
  1334. BfMethodInstance* operator->() const;
  1335. BfNonGenericMethodRef& operator=(BfMethodInstance* methodInstance);
  1336. bool operator==(const BfNonGenericMethodRef& methodRef) const;
  1337. bool operator==(BfMethodInstance* methodInstance) const;
  1338. struct Hash
  1339. {
  1340. size_t operator()(const BfNonGenericMethodRef& val) const;
  1341. };
  1342. struct Equals
  1343. {
  1344. bool operator()(const BfNonGenericMethodRef& lhs, const BfNonGenericMethodRef& rhs) const
  1345. {
  1346. return lhs == rhs;
  1347. }
  1348. };
  1349. };
  1350. enum BfMethodRefFlags : uint8
  1351. {
  1352. BfMethodRefFlag_None = 0,
  1353. BfMethodRefFlag_AlwaysInclude = 1
  1354. };
  1355. class BfMethodRef
  1356. {
  1357. public:
  1358. BfTypeInstance* mTypeInstance;
  1359. union
  1360. {
  1361. int mMethodNum;
  1362. BfMethodRefKind mKind;
  1363. };
  1364. Array<BfType*> mMethodGenericArguments;
  1365. int mSignatureHash;
  1366. BfMethodRefFlags mMethodRefFlags;
  1367. BfMethodRef()
  1368. {
  1369. mTypeInstance = NULL;
  1370. mMethodNum = 0;
  1371. mSignatureHash = 0;
  1372. mMethodRefFlags = BfMethodRefFlag_None;
  1373. }
  1374. BfMethodRef(BfMethodInstance* methodInstance);
  1375. operator BfMethodInstance*() const;
  1376. bool IsNull() { return mTypeInstance == NULL; };
  1377. BfMethodInstance* operator->() const;
  1378. BfMethodRef& operator=(BfMethodInstance* methodInstance);
  1379. bool operator==(const BfMethodRef& methodRef) const;
  1380. bool operator==(BfMethodInstance* methodInstance) const;
  1381. struct Hash
  1382. {
  1383. size_t operator()(const BfMethodRef& val) const;
  1384. };
  1385. struct Equals
  1386. {
  1387. bool operator()(const BfMethodRef& lhs, const BfMethodRef& rhs) const
  1388. {
  1389. return lhs == rhs;
  1390. }
  1391. };
  1392. };
  1393. class BfFieldRef
  1394. {
  1395. public:
  1396. BfTypeInstance* mTypeInstance;
  1397. int mFieldIdx;
  1398. public:
  1399. BfFieldRef()
  1400. {
  1401. mTypeInstance = NULL;
  1402. mFieldIdx = 0;
  1403. }
  1404. BfFieldRef(BfTypeInstance* typeInst, BfFieldDef* fieldDef);
  1405. BfFieldRef(BfFieldInstance* fieldInstance);
  1406. bool operator==(const BfFieldRef& other) const
  1407. {
  1408. return (mTypeInstance == other.mTypeInstance) && (mFieldIdx == other.mFieldIdx);
  1409. }
  1410. operator BfFieldInstance*() const;
  1411. operator BfFieldDef*() const;
  1412. operator BfPropertyDef*() const;
  1413. };
  1414. class BfPropertyRef
  1415. {
  1416. public:
  1417. BfTypeInstance* mTypeInstance;
  1418. int mPropIdx;
  1419. public:
  1420. BfPropertyRef()
  1421. {
  1422. mTypeInstance = NULL;
  1423. mPropIdx = 0;
  1424. }
  1425. BfPropertyRef(BfTypeInstance* typeInst, BfPropertyDef* propDef);
  1426. operator BfPropertyDef*() const;
  1427. };
  1428. class BfTypeInterfaceEntry
  1429. {
  1430. public:
  1431. BfTypeDef* mDeclaringType;
  1432. BfTypeInstance* mInterfaceType;
  1433. int mStartInterfaceTableIdx;
  1434. int mStartVirtualIdx; // Relative to start of virtual interface methods
  1435. bool mIsRedeclared;
  1436. };
  1437. class BfTypeInterfaceMethodEntry
  1438. {
  1439. public:
  1440. BfNonGenericMethodRef mMethodRef;
  1441. //int mVirtualIdx;
  1442. public:
  1443. BfTypeInterfaceMethodEntry()
  1444. {
  1445. //mVirtualIdx = -1;
  1446. }
  1447. };
  1448. enum BfAttributeTargets : int32
  1449. {
  1450. BfAttributeTargets_SkipValidate = -1,
  1451. BfAttributeTargets_None = 0,
  1452. BfAttributeTargets_Assembly = 0x0001,
  1453. BfAttributeTargets_Module = 0x0002,
  1454. BfAttributeTargets_Class = 0x0004,
  1455. BfAttributeTargets_Struct = 0x0008,
  1456. BfAttributeTargets_Enum = 0x0010,
  1457. BfAttributeTargets_Constructor = 0x0020,
  1458. BfAttributeTargets_Method = 0x0040,
  1459. BfAttributeTargets_Property = 0x0080,
  1460. BfAttributeTargets_Field = 0x0100,
  1461. BfAttributeTargets_StaticField = 0x0200,
  1462. BfAttributeTargets_Interface = 0x0400,
  1463. BfAttributeTargets_Parameter = 0x0800,
  1464. BfAttributeTargets_Delegate = 0x1000,
  1465. BfAttributeTargets_Function = 0x2000,
  1466. BfAttributeTargets_ReturnValue = 0x4000,
  1467. BfAttributeTargets_GenericParameter = 0x8000,
  1468. BfAttributeTargets_Invocation = 0x10000,
  1469. BfAttributeTargets_MemberAccess = 0x20000,
  1470. BfAttributeTargets_Alloc = 0x40000,
  1471. BfAttributeTargets_Delete = 0x80000,
  1472. BfAttributeTargets_Alias = 0x100000,
  1473. BfAttributeTargets_Block = 0x200000,
  1474. BfAttributeTargets_DelegateTypeRef = 0x400000,
  1475. BfAttributeTargets_FunctionTypeRef = 0x800000,
  1476. BfAttributeTargets_All = 0xFFFFFF
  1477. };
  1478. enum BfAttributeFlags : int8
  1479. {
  1480. BfAttributeFlag_None,
  1481. BfAttributeFlag_DisallowAllowMultiple = 1,
  1482. BfAttributeFlag_NotInherited = 2,
  1483. BfAttributeFlag_ReflectAttribute = 4,
  1484. BfAttributeFlag_AlwaysIncludeTarget = 8
  1485. };
  1486. class BfAttributeData
  1487. {
  1488. public:
  1489. BfAttributeTargets mAttributeTargets;
  1490. BfAlwaysIncludeFlags mAlwaysIncludeUser;
  1491. BfAttributeFlags mFlags;
  1492. public:
  1493. BfAttributeData()
  1494. {
  1495. mAttributeTargets = BfAttributeTargets_All;
  1496. mAlwaysIncludeUser = BfAlwaysIncludeFlag_None;
  1497. mFlags = BfAttributeFlag_None;
  1498. }
  1499. };
  1500. class BfHotTypeData
  1501. {
  1502. public:
  1503. Array<BfHotTypeVersion*> mTypeVersions;
  1504. Array<BfHotTypeDataEntry> mVTableEntries; // Doesn't fill in until we rebuild or delete type
  1505. int mVTableOrigLength;
  1506. int mOrigInterfaceMethodsLength;
  1507. bool mPendingDataChange;
  1508. bool mHadDataChange; // True if we have EVER had a hot data change
  1509. public:
  1510. BfHotTypeData()
  1511. {
  1512. mVTableOrigLength = -1;
  1513. mOrigInterfaceMethodsLength = -1;
  1514. mPendingDataChange = false;
  1515. mHadDataChange = false;
  1516. }
  1517. ~BfHotTypeData();
  1518. BfHotTypeVersion* GetTypeVersion(int hotCommitedIdx);
  1519. BfHotTypeVersion* GetLatestVersion();
  1520. BfHotTypeVersion* GetLatestVersionHead(); // The oldest version that has the same data
  1521. void ClearVersionsAfter(int hotIdx);
  1522. };
  1523. struct BfTypeLookupEntry
  1524. {
  1525. enum Flags : uint8
  1526. {
  1527. Flags_None,
  1528. Flags_SpecializedProject
  1529. };
  1530. BfAtomComposite mName;
  1531. int16 mNumGenericParams;
  1532. Flags mFlags;
  1533. uint32 mAtomUpdateIdx;
  1534. BfTypeDef* mUseTypeDef;
  1535. bool operator==(const BfTypeLookupEntry& rhs) const
  1536. {
  1537. return (mName == rhs.mName) &&
  1538. (mNumGenericParams == rhs.mNumGenericParams) &&
  1539. (mFlags == rhs.mFlags) &&
  1540. (mUseTypeDef == rhs.mUseTypeDef);
  1541. }
  1542. };
  1543. NS_BF_END;
  1544. namespace std
  1545. {
  1546. template<>
  1547. struct hash<Beefy::BfTypeLookupEntry>
  1548. {
  1549. size_t operator()(const Beefy::BfTypeLookupEntry& entry) const
  1550. {
  1551. int curHash = 0;
  1552. for (int i = 0; i < entry.mName.mSize; i++)
  1553. curHash = ((curHash ^ (int)(intptr)entry.mName.mParts[i]) << 5) - curHash;
  1554. curHash = ((curHash ^ entry.mNumGenericParams) << 5) - curHash;
  1555. curHash ^= (intptr)entry.mUseTypeDef;
  1556. return curHash;
  1557. }
  1558. };
  1559. }
  1560. NS_BF_BEGIN;
  1561. struct BfTypeLookupResult
  1562. {
  1563. BfTypeDef* mTypeDef;
  1564. bool mForceLookup;
  1565. bool mFoundInnerType;
  1566. BfTypeLookupResult()
  1567. {
  1568. mTypeDef = NULL;
  1569. mForceLookup = false;
  1570. mFoundInnerType = false;
  1571. }
  1572. };
  1573. struct BfTypeLookupResultCtx
  1574. {
  1575. BfTypeLookupResult* mResult;
  1576. bool mIsVerify;
  1577. BfTypeLookupResultCtx()
  1578. {
  1579. mResult = NULL;
  1580. mIsVerify = false;
  1581. }
  1582. };
  1583. class BfDependedType : public BfType
  1584. {
  1585. public:
  1586. BfDependencyMap mDependencyMap; // This is a list of types that depend on THIS type
  1587. public:
  1588. virtual bool IsDependendType() override { return true; }
  1589. virtual BfDependedType* ToDependedType() override { return this; }
  1590. };
  1591. struct BfVirtualMethodEntry
  1592. {
  1593. BfNonGenericMethodRef mDeclaringMethod;
  1594. BfNonGenericMethodRef mImplementingMethod;
  1595. };
  1596. struct BfSpecializedMethodRefInfo
  1597. {
  1598. bool mHasReifiedRef;
  1599. BfSpecializedMethodRefInfo()
  1600. {
  1601. mHasReifiedRef = false;
  1602. }
  1603. };
  1604. class BfStaticSearch
  1605. {
  1606. public:
  1607. Array<BfTypeInstance*> mStaticTypes;
  1608. };
  1609. class BfInternalAccessSet
  1610. {
  1611. public:
  1612. Array<BfTypeInstance*> mTypes;
  1613. Array<BfAtomComposite> mNamespaces;
  1614. };
  1615. class BfUsingFieldData
  1616. {
  1617. public:
  1618. struct MemberRef
  1619. {
  1620. enum Kind
  1621. {
  1622. Kind_None,
  1623. Kind_Field,
  1624. Kind_Property,
  1625. Kind_Method,
  1626. Kind_Local
  1627. };
  1628. BfTypeInstance* mTypeInstance;
  1629. Kind mKind;
  1630. int mIdx;
  1631. MemberRef()
  1632. {
  1633. mTypeInstance = NULL;
  1634. mKind = Kind_None;
  1635. mIdx = -1;
  1636. }
  1637. MemberRef(BfTypeInstance* typeInst, BfFieldDef* fieldDef)
  1638. {
  1639. mTypeInstance = typeInst;
  1640. mKind = Kind_Field;
  1641. mIdx = fieldDef->mIdx;
  1642. }
  1643. MemberRef(BfTypeInstance* typeInst, BfMethodDef* methodDef)
  1644. {
  1645. mTypeInstance = typeInst;
  1646. mKind = Kind_Method;
  1647. mIdx = methodDef->mIdx;
  1648. }
  1649. MemberRef(BfTypeInstance* typeInst, BfPropertyDef* propDef)
  1650. {
  1651. mTypeInstance = typeInst;
  1652. mKind = Kind_Property;
  1653. mIdx = propDef->mIdx;
  1654. }
  1655. BfProtection GetProtection() const;
  1656. BfProtection GetUsingProtection() const;
  1657. BfTypeDef* GetDeclaringType(BfModule* curModule) const;
  1658. String GetFullName(BfModule* curModule) const;
  1659. String GetName(BfModule* curModule) const;
  1660. BfAstNode* GetRefNode(BfModule* curModule) const;
  1661. bool IsStatic() const;
  1662. };
  1663. struct Entry
  1664. {
  1665. SizedArray<SizedArray<MemberRef, 1>, 1> mLookups;
  1666. };
  1667. public:
  1668. Dictionary<String, Entry> mEntries;
  1669. Dictionary<String, Entry> mMethods;
  1670. HashSet<BfTypeInstance*> mAwaitingPopulateSet;
  1671. };
  1672. class BfTypeInfoEx
  1673. {
  1674. public:
  1675. BfUsingFieldData* mUsingFieldData;
  1676. BfType* mUnderlyingType;
  1677. int64 mMinValue;
  1678. int64 mMaxValue;
  1679. BfTypeInfoEx()
  1680. {
  1681. mUsingFieldData = NULL;
  1682. mUnderlyingType = NULL;
  1683. mMinValue = 0;
  1684. mMaxValue = 0;
  1685. }
  1686. ~BfTypeInfoEx()
  1687. {
  1688. delete mUsingFieldData;
  1689. }
  1690. };
  1691. class BfGenericExtensionEntry
  1692. {
  1693. public:
  1694. Array<BfGenericTypeParamInstance*> mGenericParams;
  1695. bool mConstraintsPassed;
  1696. public:
  1697. BfGenericExtensionEntry(BfGenericExtensionEntry&& prev) :
  1698. mGenericParams(std::move(prev.mGenericParams)),
  1699. mConstraintsPassed(prev.mConstraintsPassed)
  1700. {
  1701. }
  1702. BfGenericExtensionEntry()
  1703. {
  1704. mConstraintsPassed = true;
  1705. }
  1706. ~BfGenericExtensionEntry();
  1707. };
  1708. class BfGenericExtensionInfo
  1709. {
  1710. public:
  1711. Dictionary<BfTypeDef*, BfGenericExtensionEntry> mExtensionMap;
  1712. BitSet mConstraintsPassedSet;
  1713. void Clear()
  1714. {
  1715. mExtensionMap.Clear();
  1716. }
  1717. };
  1718. // Note on nested generic types- mGenericParams is the accumulation of all generic params from outer to inner, so
  1719. // class ClassA<T> { class ClassB<T2> {} } will create a ClassA.ClassB<T, T2>
  1720. class BfGenericTypeInfo
  1721. {
  1722. public:
  1723. typedef Array<BfGenericTypeParamInstance*> GenericParamsVector;
  1724. BfTypeVector mTypeGenericArguments;
  1725. GenericParamsVector mGenericParams;
  1726. BfGenericExtensionInfo* mGenericExtensionInfo;
  1727. bool mIsUnspecialized;
  1728. bool mIsUnspecializedVariation;
  1729. bool mValidatedGenericConstraints;
  1730. bool mHadValidateErrors;
  1731. bool mInitializedGenericParams;
  1732. bool mFinishedGenericParams;
  1733. Array<BfProject*> mProjectsReferenced; // Generic methods that only refer to these projects don't need a specialized extension
  1734. int32 mMaxGenericDepth;
  1735. public:
  1736. BfGenericTypeInfo()
  1737. {
  1738. mGenericExtensionInfo = NULL;
  1739. mHadValidateErrors = false;
  1740. mIsUnspecialized = false;
  1741. mIsUnspecializedVariation = false;
  1742. mValidatedGenericConstraints = false;
  1743. mInitializedGenericParams = false;
  1744. mFinishedGenericParams = false;
  1745. mMaxGenericDepth = -1;
  1746. }
  1747. ~BfGenericTypeInfo();
  1748. void ReportMemory(MemReporter* memReporter);
  1749. };
  1750. class BfCeTypeInfo;
  1751. struct BfReifyMethodDependency
  1752. {
  1753. public:
  1754. BfNonGenericMethodRef mDepMethod;
  1755. int mMethodIdx;
  1756. };
  1757. // Instance of struct or class
  1758. class BfTypeInstance : public BfDependedType
  1759. {
  1760. public:
  1761. int mSignatureRevision;
  1762. int mLastNonGenericUsedRevision;
  1763. int mInheritanceId;
  1764. int mInheritanceCount;
  1765. BfModule* mModule;
  1766. BfTypeDef* mTypeDef;
  1767. BfTypeInstance* mBaseType;
  1768. BfCustomAttributes* mCustomAttributes;
  1769. BfAttributeData* mAttributeData;
  1770. BfTypeInfoEx* mTypeInfoEx;
  1771. BfGenericTypeInfo* mGenericTypeInfo;
  1772. BfCeTypeInfo* mCeTypeInfo;
  1773. Array<BfTypeInterfaceEntry> mInterfaces;
  1774. Array<BfTypeInterfaceMethodEntry> mInterfaceMethodTable;
  1775. Array<BfMethodInstanceGroup> mMethodInstanceGroups;
  1776. Array<BfOperatorInfo*> mOperatorInfo;
  1777. Array<BfVirtualMethodEntry> mVirtualMethodTable;
  1778. Array<BfReifyMethodDependency> mReifyMethodDependencies;
  1779. BfHotTypeData* mHotTypeData;
  1780. int mVirtualMethodTableSize; // With hot reloading, mVirtualMethodTableSize can be larger than mInterfaceMethodTable (live vtable versioning)
  1781. Array<BfFieldInstance> mFieldInstances;
  1782. Array<BfMethodInstance*> mInternalMethods;
  1783. Dictionary<BfTypeDef*, BfStaticSearch> mStaticSearchMap;
  1784. Dictionary<BfTypeDef*, BfInternalAccessSet> mInternalAccessMap;
  1785. Array<BfLocalMethod*> mOwnedLocalMethods; // Local methods in CEMachine
  1786. bool mHasStaticInitMethod;
  1787. bool mHasStaticDtorMethod;
  1788. bool mHasStaticMarkMethod;
  1789. bool mHasTLSFindMethod;
  1790. BfIRConstHolder* mConstHolder;
  1791. Dictionary<BfMethodRef, BfSpecializedMethodRefInfo> mSpecializedMethodReferences; // Includes both specialized methods and OnDemand methods
  1792. // We store lookup results so we can rebuild this type if a name resolves differently due to a new type being created (ie: a type name found first in
  1793. Dictionary<BfTypeLookupEntry, BfTypeLookupResult> mLookupResults;
  1794. int mTypeOptionsIdx;
  1795. int mMergedFieldDataCount;
  1796. int mInstAlign;
  1797. int mInstSize;
  1798. int16 mInheritDepth;
  1799. int16 mSlotNum;
  1800. BfAlwaysIncludeFlags mAlwaysIncludeFlags;
  1801. bool mHasBeenInstantiated;
  1802. bool mIsReified;
  1803. bool mIsTypedPrimitive;
  1804. bool mIsCRepr;
  1805. bool mIsUnion;
  1806. uint8 mPacking;
  1807. bool mIsSplattable;
  1808. bool mHasUnderlyingArray;
  1809. bool mTypeIncomplete;
  1810. bool mTypeFailed;
  1811. bool mTypeWarned;
  1812. bool mResolvingVarField;
  1813. bool mResolvingConstField;
  1814. bool mSkipTypeProtectionChecks;
  1815. bool mNeedsMethodProcessing;
  1816. bool mBaseTypeMayBeIncomplete;
  1817. bool mHasParameterizedBase; // Generic, array, etc
  1818. bool mIsFinishingType;
  1819. bool mHasPackingHoles;
  1820. bool mWantsGCMarking;
  1821. bool mHasDeclError;
  1822. public:
  1823. BfTypeInstance()
  1824. {
  1825. mModule = NULL;
  1826. mSignatureRevision = -1;
  1827. mLastNonGenericUsedRevision = -1;
  1828. mInheritanceId = 0;
  1829. mInheritanceCount = 0;
  1830. mTypeDef = NULL;
  1831. mRevision = -1;
  1832. mIsReified = true;
  1833. mIsSplattable = false;
  1834. mHasUnderlyingArray = false;
  1835. mPacking = 0;
  1836. mBaseType = NULL;
  1837. mCustomAttributes = NULL;
  1838. mAttributeData = NULL;
  1839. mTypeInfoEx = NULL;
  1840. mGenericTypeInfo = NULL;
  1841. mCeTypeInfo = NULL;
  1842. //mClassVData = NULL;
  1843. mVirtualMethodTableSize = 0;
  1844. mHotTypeData = NULL;
  1845. mHasStaticInitMethod = false;
  1846. mHasStaticMarkMethod = false;
  1847. mHasStaticDtorMethod = false;
  1848. mHasTLSFindMethod = false;
  1849. mSlotNum = -1;
  1850. mTypeOptionsIdx = -2; // -2 = not checked, -1 = none
  1851. mInstSize = -1;
  1852. mInstAlign = -1;
  1853. mInheritDepth = 0;
  1854. mIsTypedPrimitive = false;
  1855. mTypeIncomplete = true;
  1856. mIsCRepr = false;
  1857. mIsUnion = false;
  1858. mTypeFailed = false;
  1859. mTypeWarned = false;
  1860. mResolvingVarField = false;
  1861. mSkipTypeProtectionChecks = false;
  1862. mNeedsMethodProcessing = false;
  1863. mBaseTypeMayBeIncomplete = false;
  1864. mIsFinishingType = false;
  1865. mResolvingConstField = false;
  1866. mHasPackingHoles = false;
  1867. mAlwaysIncludeFlags = BfAlwaysIncludeFlag_None;
  1868. mHasBeenInstantiated = false;
  1869. mWantsGCMarking = false;
  1870. mHasParameterizedBase = false;
  1871. mHasDeclError = false;
  1872. mMergedFieldDataCount = 0;
  1873. mConstHolder = NULL;
  1874. }
  1875. ~BfTypeInstance();
  1876. virtual void Dispose();
  1877. void ReleaseData();
  1878. virtual bool IsInstanceOf(BfTypeDef* typeDef) override { if (typeDef == NULL) return false; return typeDef->GetDefinition() == mTypeDef->GetDefinition(); }
  1879. virtual BfModule* GetModule() override { return mModule; }
  1880. virtual BfTypeInstance* ToTypeInstance() override { return this; }
  1881. virtual bool IsDependentOnUnderlyingType() override { return true; }
  1882. virtual BfPrimitiveType* ToPrimitiveType() override { return IsBoxed() ? GetUnderlyingType()->ToPrimitiveType() : NULL; }
  1883. virtual bool HasWrappedRepresentation() override { return IsTypedPrimitive(); }
  1884. int GetEndingInstanceAlignment() { if (mInstSize % mInstAlign == 0) return mInstAlign; return mInstSize % mInstAlign; }
  1885. virtual bool HasTypeFailed() override { return mTypeFailed; }
  1886. virtual bool IsReified() override { return mIsReified; }
  1887. virtual bool IsDataIncomplete() override { return ((mTypeIncomplete) || (mBaseTypeMayBeIncomplete)) && (!mNeedsMethodProcessing); }
  1888. virtual bool IsFinishingType() override { return mIsFinishingType; }
  1889. virtual bool IsIncomplete() override { return (mTypeIncomplete) || (mBaseTypeMayBeIncomplete); }
  1890. virtual bool IsSplattable() override { BF_ASSERT((mInstSize >= 0) || (!IsComposite())); return mIsSplattable; }
  1891. virtual int GetSplatCount(bool force = false) override;
  1892. virtual bool IsTypeInstance() override { return true; }
  1893. virtual BfTypeCode GetTypeCode() override { return mTypeDef->mTypeCode; }
  1894. virtual bool IsInterface() override { return mTypeDef->mTypeCode == BfTypeCode_Interface; }
  1895. virtual bool IsValueType() override { return (mTypeDef->mTypeCode == BfTypeCode_Struct) || (mTypeDef->mTypeCode == BfTypeCode_Enum); }
  1896. virtual bool IsOpaque() override { return mTypeDef->mIsOpaque; }
  1897. virtual bool IsStruct() override { return ((mTypeDef->mTypeCode == BfTypeCode_Struct) || (mTypeDef->mTypeCode == BfTypeCode_Enum)) && (!mIsTypedPrimitive); }
  1898. virtual bool IsUnion() override { return mIsUnion; }
  1899. virtual bool IsDelegate() override { return mTypeDef->mIsDelegate; }
  1900. virtual bool IsFunction() override { return mTypeDef->mIsFunction; }
  1901. virtual bool IsDelegateOrFunction() override { return mTypeDef->mIsDelegate || mTypeDef->mIsFunction; }
  1902. virtual bool IsString() override;
  1903. virtual bool IsIntPtrable() override { return (mTypeDef->mTypeCode == BfTypeCode_Object) || (mTypeDef->mTypeCode == BfTypeCode_Interface); };
  1904. virtual bool IsEnum() override { return mTypeDef->mTypeCode == BfTypeCode_Enum; }
  1905. virtual bool IsPayloadEnum() override { return (mTypeDef->mTypeCode == BfTypeCode_Enum) && (!mIsTypedPrimitive); }
  1906. virtual bool IsTypedPrimitive() override { return mIsTypedPrimitive; }
  1907. virtual bool IsStructOrStructPtr() override { return mTypeDef->mTypeCode == BfTypeCode_Struct; }
  1908. virtual bool IsValueTypeOrValueTypePtr() override { return (mTypeDef->mTypeCode == BfTypeCode_Struct) || (mTypeDef->mTypeCode == BfTypeCode_Enum); }
  1909. virtual bool IsObject() override { return mTypeDef->mTypeCode == BfTypeCode_Object; }
  1910. virtual bool IsObjectOrStruct() override { return (mTypeDef->mTypeCode == BfTypeCode_Object) || (mTypeDef->mTypeCode == BfTypeCode_Struct); }
  1911. virtual bool IsObjectOrInterface() override { return (mTypeDef->mTypeCode == BfTypeCode_Object) || (mTypeDef->mTypeCode == BfTypeCode_Interface); }
  1912. virtual BfType* GetUnderlyingType() override;
  1913. //virtual bool IsValuelessType() override { return (mIsTypedPrimitive) && (mInstSize == 0); }
  1914. virtual bool CanBeValuelessType() override { return (mTypeDef->mTypeCode == BfTypeCode_Struct) || (mTypeDef->mTypeCode == BfTypeCode_Enum); }
  1915. virtual bool IsValuelessType() override;
  1916. virtual bool HasPackingHoles() override { return mHasPackingHoles; }
  1917. virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfTypeDef* activeTypeDef) override;
  1918. virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfProject* curProject) override;
  1919. virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfProjectSet* visibleProjectSet) override;
  1920. virtual bool WantsGCMarking() override;
  1921. virtual bool GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCode = NULL, BfTypeCode* outTypeCode2 = NULL) override;
  1922. BfGenericTypeInfo* GetGenericTypeInfo() { return mGenericTypeInfo; }
  1923. virtual int GetGenericDepth() { return (mGenericTypeInfo != NULL) ? mGenericTypeInfo->mMaxGenericDepth : 0; }
  1924. virtual BfTypeInstance* ToGenericTypeInstance() override { return (mGenericTypeInfo != NULL) ? this : NULL; }
  1925. virtual bool IsGenericTypeInstance() override { return mGenericTypeInfo != NULL; }
  1926. virtual bool IsSpecializedType() override { return (mGenericTypeInfo != NULL) && (!mGenericTypeInfo->mIsUnspecialized); }
  1927. virtual bool IsSpecializedByAutoCompleteMethod() override;
  1928. virtual bool IsUnspecializedType() override { return (mGenericTypeInfo != NULL) && (mGenericTypeInfo->mIsUnspecialized); }
  1929. virtual bool IsUnspecializedTypeVariation() override { return (mGenericTypeInfo != NULL) && (mGenericTypeInfo->mIsUnspecializedVariation); }
  1930. virtual bool IsNullable() override;
  1931. virtual bool HasVarConstraints();
  1932. virtual bool IsTypeMemberIncluded(BfTypeDef* declaringTypeDef, BfTypeDef* activeTypeDef = NULL, BfModule* module = NULL) override;
  1933. virtual BfTypeInstance* GetImplBaseType() { return mBaseType; }
  1934. virtual bool IsIRFuncUsed(BfIRFunction func);
  1935. void CalcHotVirtualData(/*Val128& vtHash, */Array<int>* ifaceMapping);
  1936. int GetOrigVTableSize();
  1937. int GetSelfVTableSize();
  1938. int GetOrigSelfVTableSize();
  1939. int GetImplBaseVTableSize();
  1940. int GetOrigImplBaseVTableSize();
  1941. int GetIFaceVMethodSize();
  1942. BfType* GetUnionInnerType(bool* wantSplat = NULL);
  1943. BfPrimitiveType* GetDiscriminatorType(int* outDataIdx = NULL);
  1944. void GetUnderlyingArray(BfType*& type, int& size, bool& isVector);
  1945. bool HasEquivalentLayout(BfTypeInstance* compareTo);
  1946. BfIRConstHolder* GetOrCreateConstHolder();
  1947. BfIRValue CreateConst(BfConstant* fromConst, BfIRConstHolder* fromHolder);
  1948. int GetInstStride() { return BF_ALIGN(mInstSize, mInstAlign); }
  1949. bool HasOverrideMethods();
  1950. bool GetResultInfo(BfType*& valueType, int& okTagId);
  1951. BfGenericTypeInfo::GenericParamsVector* GetGenericParamsVector(BfTypeDef* declaringTypeDef);
  1952. void GenerateProjectsReferenced();
  1953. bool IsAlwaysInclude();
  1954. bool HasBeenInstantiated() { return mHasBeenInstantiated || ((mAlwaysIncludeFlags & BfAlwaysIncludeFlag_AssumeInstantiated) != 0); }
  1955. bool IncludeAllMethods() { return ((mAlwaysIncludeFlags & BfAlwaysIncludeFlag_IncludeAllMethods) != 0); }
  1956. bool DefineStateAllowsStaticMethods() { return mDefineState >= BfTypeDefineState_HasInterfaces_Direct; }
  1957. bool IsAnonymous();
  1958. bool IsAnonymousInitializerType();
  1959. virtual void ReportMemory(MemReporter* memReporter) override;
  1960. };
  1961. template <typename T>
  1962. class LogAlloc
  1963. {
  1964. public:
  1965. T* allocate(intptr count)
  1966. {
  1967. auto ptr = (T*)malloc(sizeof(T) * count);
  1968. OutputDebugStrF("LogAlloc.allocate: %p\n", ptr);
  1969. return ptr;
  1970. }
  1971. void deallocate(T* ptr)
  1972. {
  1973. OutputDebugStrF("LogAlloc.deallocate: %p\n", ptr);
  1974. free(ptr);
  1975. }
  1976. void* rawAllocate(intptr size)
  1977. {
  1978. auto ptr = malloc(size);
  1979. OutputDebugStrF("LogAlloc.rawAllocate: %p\n", ptr);
  1980. return ptr;
  1981. }
  1982. void rawDeallocate(void* ptr)
  1983. {
  1984. OutputDebugStrF("LogAlloc.rawFree: %p\n", ptr);
  1985. free(ptr);
  1986. }
  1987. };
  1988. class BfBoxedType : public BfTypeInstance
  1989. {
  1990. public:
  1991. enum BoxedFlags
  1992. {
  1993. BoxedFlags_None = 0,
  1994. BoxedFlags_StructPtr = 1
  1995. };
  1996. public:
  1997. BfType* mElementType;
  1998. BfBoxedType* mBoxedBaseType;
  1999. BoxedFlags mBoxedFlags;
  2000. public:
  2001. BfBoxedType()
  2002. {
  2003. mElementType = NULL;
  2004. mBoxedBaseType = NULL;
  2005. mBoxedFlags = BoxedFlags_None;
  2006. }
  2007. ~BfBoxedType();
  2008. virtual bool IsBoxed() override { return true; }
  2009. virtual bool IsValueType() override { return false; }
  2010. virtual bool IsStruct() override { return false; }
  2011. virtual bool IsEnum() override { return false; }
  2012. virtual bool IsStructOrStructPtr() override { return false; }
  2013. virtual bool IsObject() override { return true; }
  2014. virtual bool IsObjectOrStruct() override { return true; }
  2015. virtual bool IsObjectOrInterface() override { return true; }
  2016. virtual bool IsDependentOnUnderlyingType() override { return true; }
  2017. virtual BfType* GetUnderlyingType() override { return mElementType; }
  2018. virtual BfTypeInstance* ToGenericTypeInstance() override { return mElementType->ToGenericTypeInstance(); }
  2019. virtual bool IsSpecializedType() override { return !mElementType->IsUnspecializedType(); }
  2020. virtual bool IsUnspecializedType() override { return mElementType->IsUnspecializedType(); }
  2021. virtual bool IsUnspecializedTypeVariation() override { return mElementType->IsUnspecializedTypeVariation(); }
  2022. virtual BfTypeInstance* GetImplBaseType() override { return (mBoxedBaseType != NULL) ? mBoxedBaseType : mBaseType; }
  2023. bool IsBoxedStructPtr()
  2024. {
  2025. return (mBoxedFlags & BoxedFlags_StructPtr) != 0;
  2026. }
  2027. BfType* GetModifiedElementType();
  2028. };
  2029. class BfTypeAliasType : public BfTypeInstance
  2030. {
  2031. public:
  2032. BfType* mAliasToType;
  2033. public:
  2034. BfTypeAliasType()
  2035. {
  2036. mAliasToType = NULL;
  2037. }
  2038. virtual bool IsTypeAlias() override { return true; }
  2039. virtual BfType* GetUnderlyingType() override { return mAliasToType; }
  2040. virtual bool WantsGCMarking() override { return mAliasToType->WantsGCMarking(); }
  2041. };
  2042. enum BfCaptureType
  2043. {
  2044. BfCaptureType_None,
  2045. BfCaptureType_Auto,
  2046. BfCaptureType_Copy,
  2047. BfCaptureType_Reference,
  2048. };
  2049. class BfClosureType : public BfTypeInstance
  2050. {
  2051. public:
  2052. Val128 mClosureHash; // Includes base type and capture info
  2053. BfTypeInstance* mSrcDelegate;
  2054. bool mCreatedTypeDef;
  2055. String mNameAdd;
  2056. BfSource mSource;
  2057. Array<BfAstNode*> mDirectAllocNodes;
  2058. bool mIsUnique;
  2059. public:
  2060. BfClosureType(BfTypeInstance* srcDelegate, Val128 closureHash);
  2061. ~BfClosureType();
  2062. void Init(BfProject* bfProject);
  2063. BfFieldDef* AddField(BfType* type, const StringImpl& name);
  2064. BfMethodDef* AddDtor();
  2065. void Finish();
  2066. virtual bool IsClosure() override { return true; }
  2067. virtual bool IsOnDemand() override { return true; }
  2068. };
  2069. class BfDelegateType : public BfTypeInstance
  2070. {
  2071. public:
  2072. BfDelegateInfo mDelegateInfo;
  2073. bool mIsUnspecializedType;
  2074. bool mIsUnspecializedTypeVariation;
  2075. int mGenericDepth;
  2076. public:
  2077. BfDelegateType()
  2078. {
  2079. mIsUnspecializedType = false;
  2080. mIsUnspecializedTypeVariation = false;
  2081. mGenericDepth = 0;
  2082. }
  2083. ~BfDelegateType();
  2084. virtual void Dispose() override;
  2085. virtual bool IsOnDemand() override { return true; }
  2086. virtual bool IsDelegate() override { return mTypeDef->mIsDelegate; }
  2087. virtual bool IsDelegateFromTypeRef() override { return mTypeDef->mIsDelegate; }
  2088. virtual bool IsFunction() override { return !mTypeDef->mIsDelegate; }
  2089. virtual bool IsFunctionFromTypeRef() override { return !mTypeDef->mIsDelegate; }
  2090. virtual bool IsDelegateOrFunction() override { return mTypeDef->mIsDelegate || mTypeDef->mIsFunction; }
  2091. virtual bool IsUnspecializedType() override { return mIsUnspecializedType; }
  2092. virtual bool IsUnspecializedTypeVariation() override { return mIsUnspecializedTypeVariation; }
  2093. virtual BfDelegateInfo* GetDelegateInfo() override { return &mDelegateInfo; }
  2094. virtual int GetGenericDepth() override { return mGenericDepth; }
  2095. };
  2096. class BfTupleType : public BfTypeInstance
  2097. {
  2098. public:
  2099. bool mCreatedTypeDef;
  2100. String mNameAdd;
  2101. BfSource* mSource;
  2102. bool mIsUnspecializedType;
  2103. bool mIsUnspecializedTypeVariation;
  2104. int mGenericDepth;
  2105. public:
  2106. BfTupleType();
  2107. ~BfTupleType();
  2108. void Init(BfProject* bfProject, BfTypeInstance* valueTypeInstance);
  2109. virtual void Dispose() override;
  2110. BfFieldDef* AddField(const StringImpl& name);
  2111. void Finish();
  2112. virtual bool IsOnDemand() override { return true; }
  2113. virtual bool IsTuple() override { return true; }
  2114. virtual bool IsUnspecializedType() override { return mIsUnspecializedType; }
  2115. virtual bool IsUnspecializedTypeVariation() override { return mIsUnspecializedTypeVariation; }
  2116. virtual int GetGenericDepth() override { return mGenericDepth; }
  2117. };
  2118. class BfTagType : public BfTypeInstance
  2119. {
  2120. public:
  2121. bool mCreatedTypeDef;
  2122. String mNameAdd;
  2123. BfSource* mSource;
  2124. public:
  2125. BfTagType();
  2126. ~BfTagType();
  2127. void Init(BfProject* bfProject, BfTypeInstance* valueTypeInstance, const StringImpl& name);
  2128. virtual void Dispose() override;
  2129. void Finish();
  2130. virtual bool IsOnDemand() override { return true; }
  2131. };
  2132. class BfConcreteInterfaceType : public BfType
  2133. {
  2134. public:
  2135. BfTypeInstance* mInterface;
  2136. virtual bool IsConcreteInterfaceType() override { return true; }
  2137. virtual bool IsDependentOnUnderlyingType() override { return true; }
  2138. virtual BfType* GetUnderlyingType() override { return mInterface; }
  2139. virtual bool IsUnspecializedType() override { return mInterface->IsUnspecializedType(); }
  2140. virtual bool IsUnspecializedTypeVariation() override { return mInterface->IsUnspecializedTypeVariation(); }
  2141. };
  2142. class BfPointerType : public BfElementedType
  2143. {
  2144. public:
  2145. BfType* mElementType;
  2146. public:
  2147. virtual bool IsWrappableType() override { return true; }
  2148. virtual bool IsReified() override { return mElementType->IsReified(); }
  2149. virtual bool IsPointer() override { return true; }
  2150. virtual bool IsIntPtrable() override { return true; }
  2151. virtual bool IsStructPtr() override { return mElementType->IsStruct(); }
  2152. virtual bool IsStructOrStructPtr() override { return mElementType->IsStruct(); }
  2153. virtual bool IsValueTypeOrValueTypePtr() override { return mElementType->IsValueType(); }
  2154. virtual bool IsDependentOnUnderlyingType() override { return true; }
  2155. virtual BfType* GetUnderlyingType() override { return mElementType; }
  2156. virtual bool IsUnspecializedType() override { return mElementType->IsUnspecializedType(); }
  2157. virtual bool IsUnspecializedTypeVariation() override { return mElementType->IsUnspecializedTypeVariation(); }
  2158. virtual bool IsVoidPtr() override { return mElementType->IsVoid(); }
  2159. };
  2160. // This is used for direct method references for generics so we can directly call methods rather than indirectly through delegates
  2161. class BfMethodRefType : public BfDependedType
  2162. {
  2163. public:
  2164. BfMethodInstance* mMethodRef;
  2165. String mMangledMethodName;
  2166. BfTypeInstance* mOwner;
  2167. int mOwnerRevision;
  2168. bool mIsAutoCompleteMethod;
  2169. Array<int> mParamToDataIdx;
  2170. Array<int> mDataToParamIdx;
  2171. bool mIsUnspecialized;
  2172. bool mIsUnspecializedVariation;
  2173. public:
  2174. BfMethodRefType()
  2175. {
  2176. mMethodRef = NULL;
  2177. mOwner = NULL;
  2178. mOwnerRevision = -1;
  2179. mIsAutoCompleteMethod = false;
  2180. mIsUnspecialized = false;
  2181. mIsUnspecializedVariation = false;
  2182. }
  2183. ~BfMethodRefType();
  2184. //virtual bool IsValuelessType() override { return mSize != 0; }
  2185. virtual bool IsValueType() override { return true; }
  2186. virtual bool IsComposite() override { return true; }
  2187. virtual bool IsMethodRef() override { return true; }
  2188. virtual bool IsSplattable() override { return true; }
  2189. virtual int GetSplatCount(bool force) override { return (int)mDataToParamIdx.mSize; }
  2190. virtual bool IsOnDemand() override { return true; }
  2191. virtual bool IsTemporary() override { return true; }
  2192. virtual bool IsUnspecializedType() override { return mIsUnspecialized; }
  2193. virtual bool IsUnspecializedTypeVariation() override { return mIsUnspecializedVariation; }
  2194. int GetCaptureDataCount();
  2195. BfType* GetCaptureType(int captureDataIdx);
  2196. int GetDataIdxFromParamIdx(int paramIdx);
  2197. int GetParamIdxFromDataIdx(int dataIdx);
  2198. bool WantsDataPassedAsSplat(int dataIdx);
  2199. //virtual BfType* GetUnderlyingType() override { return mOwner; }
  2200. };
  2201. class BfRefType : public BfType
  2202. {
  2203. public:
  2204. enum RefKind
  2205. {
  2206. RefKind_Ref,
  2207. RefKind_In,
  2208. RefKind_Out,
  2209. RefKind_Mut
  2210. };
  2211. BfType* mElementType;
  2212. RefKind mRefKind;
  2213. // When an element gets rebuild, it may become valueless which makes us valueless
  2214. void CheckElement()
  2215. {
  2216. if ((mDefineState >= BfTypeDefineState_Defined) && (mElementType->mDefineState < BfTypeDefineState_Defined) && (mElementType->CanBeValuelessType()))
  2217. mDefineState = BfTypeDefineState_Declared;
  2218. }
  2219. virtual bool IsDataIncomplete() override { CheckElement(); return mDefineState < BfTypeDefineState_Defined; }
  2220. virtual bool IsIncomplete() override { CheckElement(); return mDefineState < BfTypeDefineState_Defined; }
  2221. virtual bool IsReified() override { return mElementType->IsReified(); }
  2222. virtual bool IsRef() override { return true; }
  2223. virtual bool IsMut() override { return mRefKind == RefKind_Mut; }
  2224. virtual bool IsIn() override { return mRefKind == RefKind_In; }
  2225. virtual bool IsOut() override { return mRefKind == RefKind_Out; }
  2226. virtual bool IsDependentOnUnderlyingType() override { return true; }
  2227. virtual BfType* GetUnderlyingType() override { return mElementType; }
  2228. virtual bool IsUnspecializedType() override { return mElementType->IsUnspecializedType(); }
  2229. virtual bool IsUnspecializedTypeVariation() override { return mElementType->IsUnspecializedTypeVariation(); }
  2230. virtual bool CanBeValuelessType() override { return mElementType->CanBeValuelessType(); }
  2231. virtual bool IsValuelessType() override { return mElementType->IsValuelessType(); }
  2232. };
  2233. class BfArrayType : public BfTypeInstance
  2234. {
  2235. public:
  2236. int mDimensions;
  2237. public:
  2238. virtual bool IsArray() override { return true; }
  2239. virtual bool IsValueType() override { return false; }
  2240. virtual bool IsStruct() override { return false; }
  2241. virtual bool IsStructOrStructPtr() override { return false; }
  2242. virtual bool IsObject() override { return true; }
  2243. virtual bool IsObjectOrStruct() override { return true; }
  2244. virtual bool IsObjectOrInterface() override { return true; }
  2245. int GetLengthBitCount();
  2246. };
  2247. class BfSizedArrayType : public BfDependedType
  2248. {
  2249. public:
  2250. BfType* mElementType;
  2251. intptr mElementCount;
  2252. int mGenericDepth;
  2253. bool mWantsGCMarking;
  2254. public:
  2255. BfSizedArrayType()
  2256. {
  2257. mElementType = NULL;
  2258. mElementCount = 0;
  2259. mGenericDepth = 0;
  2260. mWantsGCMarking = false;
  2261. }
  2262. virtual bool IsSizedArray() override { return true; }
  2263. virtual bool IsUndefSizedArray() override { return mElementCount == -1; }
  2264. virtual bool IsWrappableType() override { return true; }
  2265. virtual bool IsValueType() override { return true; } // Is a type of struct
  2266. virtual bool IsValueTypeOrValueTypePtr() override { return true; }
  2267. virtual bool IsComposite() override { return true; }
  2268. virtual bool IsStruct() override { return false; } // But IsStruct infers a definition, which it does not have
  2269. virtual bool IsStructOrStructPtr() override { return false; }
  2270. virtual bool IsReified() override { return mElementType->IsReified(); }
  2271. virtual bool IsDependentOnUnderlyingType() override { return true; }
  2272. virtual BfType* GetUnderlyingType() override { return mElementType; }
  2273. virtual bool IsUnspecializedType() override { return mElementType->IsUnspecializedType(); }
  2274. virtual bool IsUnspecializedTypeVariation() override { return mElementType->IsUnspecializedTypeVariation(); }
  2275. virtual bool CanBeValuelessType() override { return true; }
  2276. virtual bool WantsGCMarking() override { BF_ASSERT(mDefineState >= BfTypeDefineState_Defined); return mWantsGCMarking; }
  2277. virtual int GetGenericDepth() override { return mGenericDepth; }
  2278. // Leave the default "zero sized" definition
  2279. //virtual bool IsValuelessType() override { return mElementType->IsValuelessType(); }
  2280. };
  2281. // This is used when a sized array is sized by a const generic argument
  2282. class BfUnknownSizedArrayType : public BfSizedArrayType
  2283. {
  2284. public:
  2285. BfType* mElementCountSource;
  2286. public:
  2287. virtual bool IsUnknownSizedArrayType() override { return true; }
  2288. virtual bool IsWrappableType() override { return true; }
  2289. virtual bool IsValueType() override { return true; } // Is a type of struct
  2290. virtual bool IsValueTypeOrValueTypePtr() override { return true; }
  2291. virtual bool IsComposite() override { return true; }
  2292. virtual bool IsStruct() override { return false; } // But IsStruct infers a definition, which it does not have
  2293. virtual bool IsStructOrStructPtr() override { return false; }
  2294. virtual bool IsReified() override { return mElementType->IsReified(); }
  2295. virtual bool IsDependentOnUnderlyingType() override { return true; }
  2296. virtual BfType* GetUnderlyingType() override { return mElementType; }
  2297. virtual bool IsUnspecializedType() override { return mElementType->IsUnspecializedType() || mElementCountSource->IsUnspecializedType(); }
  2298. virtual bool IsUnspecializedTypeVariation() override { return mElementType->IsUnspecializedTypeVariation() || mElementCountSource->IsUnspecializedTypeVariation(); }
  2299. virtual bool CanBeValuelessType() override { return true; }
  2300. // Leave the default "zero sized" definition
  2301. //virtual bool IsValuelessType() override { return mElementType->IsValuelessType(); }
  2302. };
  2303. class BfConstExprValueType : public BfDependedType
  2304. {
  2305. public:
  2306. BfType* mType;
  2307. BfVariant mValue;
  2308. String mValueString;
  2309. public:
  2310. ~BfConstExprValueType();
  2311. virtual bool IsOnDemand() override { return mValue.mTypeCode == BfTypeCode_Struct; }
  2312. virtual bool IsConstExprValue() override { return true; }
  2313. virtual BfType* GetUnderlyingType() override { return mType; }
  2314. virtual bool IsUnspecializedType() { return mValue.mTypeCode == BfTypeCode_Let; }
  2315. virtual bool IsUnspecializedTypeVariation() { return mValue.mTypeCode == BfTypeCode_Let; }
  2316. };
  2317. /*class BfCustomAttributeArgument
  2318. {
  2319. public:
  2320. llvm::Constant* mConstParam;
  2321. };*/
  2322. class BfCustomAttributeSetProperty
  2323. {
  2324. public:
  2325. BfPropertyRef mPropertyRef;
  2326. BfTypedValue mParam;
  2327. };
  2328. class BfCustomAttributeSetField
  2329. {
  2330. public:
  2331. BfFieldRef mFieldRef;
  2332. BfTypedValue mParam;
  2333. };
  2334. class BfCustomAttribute
  2335. {
  2336. public:
  2337. BfAttributeDirective* mRef;
  2338. BfTypeDef* mDeclaringType;
  2339. BfTypeInstance* mType;
  2340. BfMethodDef* mCtor;
  2341. Array<BfIRValue> mCtorArgs;
  2342. Array<BfCustomAttributeSetProperty> mSetProperties;
  2343. Array<BfCustomAttributeSetField> mSetField;
  2344. bool mAwaitingValidation;
  2345. bool mIsMultiUse;
  2346. BfAstNode* GetRefNode()
  2347. {
  2348. if (mRef->mAttributeTypeRef != NULL)
  2349. return mRef->mAttributeTypeRef;
  2350. return mRef;
  2351. }
  2352. };
  2353. class BfCustomAttributes
  2354. {
  2355. public:
  2356. Array<BfCustomAttribute> mAttributes;
  2357. bool Contains(BfTypeDef* typeDef);
  2358. BfCustomAttribute* Get(BfTypeDef* typeDef);
  2359. BfCustomAttribute* Get(BfType* type);
  2360. BfCustomAttribute* Get(int idx);
  2361. void ReportMemory(MemReporter* memReporter);
  2362. };
  2363. class BfResolvedTypeSet : public MultiHashSet<BfType*, AllocatorCLib>
  2364. {
  2365. public:
  2366. enum BfHashFlags
  2367. {
  2368. BfHashFlag_None = 0,
  2369. BfHashFlag_AllowRef = 1,
  2370. BfHashFlag_AllowGenericParamConstValue = 2,
  2371. BfHashFlag_AllowDotDotDot = 4,
  2372. };
  2373. struct BfExprResult
  2374. {
  2375. BfVariant mValue;
  2376. BfType* mResultType;
  2377. };
  2378. class LookupContext
  2379. {
  2380. public:
  2381. BfModule* mModule;
  2382. BfTypeReference* mRootTypeRef;
  2383. BfTypeDef* mRootTypeDef;
  2384. BfTypeInstance* mRootOuterTypeInstance;
  2385. BfType* mRootResolvedType;
  2386. Dictionary<BfAstNode*, BfType*> mResolvedTypeMap;
  2387. Dictionary<BfAstNode*, BfTypedValue> mResolvedValueMap;
  2388. BfResolveTypeRefFlags mResolveFlags;
  2389. BfCallingConvention mCallingConvention;
  2390. bool mHadVar;
  2391. bool mFailed;
  2392. bool mIsUnboundGeneric;
  2393. public:
  2394. LookupContext()
  2395. {
  2396. mRootTypeRef = NULL;
  2397. mRootTypeDef = NULL;
  2398. mRootOuterTypeInstance = NULL;
  2399. mModule = NULL;
  2400. mRootResolvedType = NULL;
  2401. mFailed = false;
  2402. mHadVar = false;
  2403. mIsUnboundGeneric = false;
  2404. mResolveFlags = BfResolveTypeRefFlag_None;
  2405. mCallingConvention = BfCallingConvention_Unspecified;
  2406. }
  2407. BfType* GetCachedResolvedType(BfTypeReference* typeReference);
  2408. void SetCachedResolvedType(BfTypeReference* typeReference, BfType* type);
  2409. BfType* ResolveTypeRef(BfTypeReference* typeReference);
  2410. BfTypeDef* ResolveToTypeDef(BfTypeReference* typeReference, BfType** outType = NULL);
  2411. };
  2412. class Iterator : public MultiHashSet<BfType*, AllocatorCLib>::Iterator
  2413. {
  2414. public:
  2415. Iterator(MultiHashSet* set) : MultiHashSet::Iterator(set)
  2416. {
  2417. }
  2418. Iterator(const MultiHashSet::Iterator& itr) : MultiHashSet::Iterator(itr.mSet)
  2419. {
  2420. *((MultiHashSet::Iterator*)this) = itr;
  2421. }
  2422. // NULLs can occur in rare instances since we insert a preliminary "NULL" during insertion up until we actually construct the final type
  2423. void MovePastNulls()
  2424. {
  2425. while (this->mCurEntry != -1)
  2426. {
  2427. BF_ASSERT(this->mCurEntry < this->mSet->mAllocSize);
  2428. if (this->mSet->mEntries[this->mCurEntry].mValue != NULL)
  2429. break;
  2430. ++(*((MultiHashSet::Iterator*)this));
  2431. }
  2432. }
  2433. Iterator& operator++()
  2434. {
  2435. ++(*((MultiHashSet::Iterator*)this));
  2436. MovePastNulls();
  2437. return *this;
  2438. }
  2439. Iterator& operator=(const MultiHashSet::Iterator& itr)
  2440. {
  2441. *((MultiHashSet::Iterator*)this) = itr;
  2442. return *this;
  2443. }
  2444. };
  2445. public:
  2446. static BfTypeDef* FindRootCommonOuterType(BfTypeDef* outerType, LookupContext* ctx, BfTypeInstance*& outCheckTypeInstance);
  2447. static BfVariant EvaluateToVariant(LookupContext* ctx, BfExpression* expr, BfType*& outType);
  2448. static bool GenericTypeEquals(BfTypeInstance* lhsGenericType, BfTypeVector* lhsTypeGenericArguments, BfTypeReference* rhs, LookupContext* ctx, int& genericParamOffset, bool skipElement = false);
  2449. static bool GenericTypeEquals(BfTypeInstance* lhsGenericType, BfTypeVector* typeGenericArguments, BfTypeReference* rhs, BfTypeDef* rhsTypeDef, LookupContext* ctx);
  2450. static void HashGenericArguments(BfTypeReference* typeRef, LookupContext* ctx, int& hash, int hashSeed);
  2451. static int DoHash(BfType* type, LookupContext* ctx, bool allowRef, int hashSeed);
  2452. static int Hash(BfType* type, LookupContext* ctx, bool allowRef = false, int hashSeed = 0);
  2453. static int DirectHash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags = BfHashFlag_None, int hashSeed = 0);
  2454. static BfResolveTypeRefFlags GetResolveFlags(BfAstNode* typeRef, LookupContext* ctx, BfHashFlags flags = BfHashFlag_None);
  2455. static int DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags, int& hashSeed);
  2456. static int Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags = BfHashFlag_None, int hashSeed = 0);
  2457. static int Hash(BfAstNode* typeRefNode, LookupContext* ctx, BfHashFlags flags = BfHashFlag_None, int hashSeed = 0);
  2458. static bool Equals(BfType* lhs, BfType* rhs, LookupContext* ctx);
  2459. static bool Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* ctx);
  2460. static bool Equals(BfType* lhs, BfAstNode* rhs, LookupContext* ctx);
  2461. static bool Equals(BfType* lhs, BfTypeReference* rhs, BfTypeDef* rhsTypeDef, LookupContext* ctx);
  2462. public:
  2463. BfResolvedTypeSet()
  2464. {
  2465. Rehash(9973);
  2466. }
  2467. ~BfResolvedTypeSet();
  2468. template <typename T>
  2469. bool Insert(T* findType, LookupContext* ctx, BfResolvedTypeSet::EntryRef* entryPtr)
  2470. {
  2471. CheckRehash();
  2472. int tryCount = 0;
  2473. ctx->mFailed = false;
  2474. BfHashFlags hashFlags = BfHashFlag_AllowRef;
  2475. if ((ctx->mResolveFlags & (BfResolveTypeRefFlag_AllowGenericParamConstValue | BfResolveTypeRefFlag_AllowImplicitConstExpr)) != 0)
  2476. {
  2477. ctx->mResolveFlags = (BfResolveTypeRefFlags)(ctx->mResolveFlags & ~(BfResolveTypeRefFlag_AllowGenericParamConstValue | BfResolveTypeRefFlag_AllowImplicitConstExpr));
  2478. hashFlags = (BfHashFlags)(hashFlags | BfHashFlag_AllowGenericParamConstValue);
  2479. }
  2480. int hashVal = Hash(findType, ctx, hashFlags);
  2481. if ((ctx->mFailed) || (ctx->mHadVar))
  2482. {
  2483. return false;
  2484. }
  2485. while (true)
  2486. {
  2487. int startAllocSize = mAllocSize;
  2488. int bucket = (hashVal & 0x7FFFFFFF) % mHashSize;
  2489. auto startEntryIdx = mHashHeads[bucket];
  2490. auto checkEntryIdx = startEntryIdx;
  2491. bool needsRerun = false;
  2492. while (checkEntryIdx != -1)
  2493. {
  2494. auto checkEntry = &mEntries[checkEntryIdx];
  2495. // checkEntry->mType can be NULL if we're in the process of filling it in (and this Insert is from an element type)
  2496. // OR if the type resolution failed after node insertion
  2497. if ((checkEntry->mValue != NULL) && (hashVal == checkEntry->mHashCode) && (Equals(checkEntry->mValue, findType, ctx)))
  2498. {
  2499. *entryPtr = EntryRef(this, checkEntryIdx);
  2500. return false;
  2501. }
  2502. if ((mAllocSize != startAllocSize) || (startEntryIdx != mHashHeads[bucket]))
  2503. {
  2504. // It's possible for Equals to add types, buckets could be invalid or a new type could
  2505. // have been inserted at the start of our bucket
  2506. needsRerun = true;
  2507. break;
  2508. }
  2509. checkEntryIdx = checkEntry->mNext;
  2510. tryCount++;
  2511. // If this fires off, this may indicate that our hashes are equivalent but Equals fails
  2512. if (tryCount >= 10)
  2513. {
  2514. NOP;
  2515. }
  2516. BF_ASSERT(tryCount < 10);
  2517. }
  2518. if (!needsRerun)
  2519. {
  2520. // Retry if we added entries
  2521. break;
  2522. }
  2523. }
  2524. if ((ctx->mResolveFlags & BfResolveTypeRefFlag_NoCreate) != 0)
  2525. return false;
  2526. *entryPtr = AddRaw(hashVal);
  2527. return true;
  2528. }
  2529. Iterator begin()
  2530. {
  2531. return ++Iterator(this);
  2532. }
  2533. Iterator end()
  2534. {
  2535. Iterator itr(this);
  2536. itr.mCurBucket = this->mHashSize;
  2537. return itr;
  2538. }
  2539. Iterator Erase(const Iterator& itr)
  2540. {
  2541. auto result = Iterator(MultiHashSet::Erase(itr));
  2542. result.MovePastNulls();
  2543. return result;
  2544. }
  2545. void RemoveEntry(EntryRef entry);
  2546. };
  2547. class BfTypeUtils
  2548. {
  2549. public:
  2550. static String HashEncode64(uint64 val); // Note: this only encodes 60 bits
  2551. static String TypeToString(BfAstNode* typeRef);
  2552. static String TypeToString(BfTypeDef* typeDef, BfTypeNameFlags typeNameFlags = BfTypeNameFlags_None);
  2553. static bool TypeToString(StringImpl& str, BfTypeDef* typeDef, BfTypeNameFlags typeNameFlags = BfTypeNameFlags_None);
  2554. static bool TypeEquals(BfType* typeA, BfType* typeB, BfTypeInstance* selfType);
  2555. template <typename T>
  2556. static void GetProjectList(BfType* checkType, T* projectList, int immutableLength)
  2557. {
  2558. if (checkType->IsBoxed())
  2559. GetProjectList(((BfBoxedType*)checkType)->mElementType, projectList, immutableLength);
  2560. BfTypeInstance* typeInst = checkType->ToTypeInstance();
  2561. if (typeInst != NULL)
  2562. {
  2563. auto genericTypeInst = typeInst->ToGenericTypeInstance();
  2564. if (genericTypeInst != NULL)
  2565. {
  2566. for (auto genericArg : genericTypeInst->mGenericTypeInfo->mTypeGenericArguments)
  2567. GetProjectList(genericArg, projectList, immutableLength);
  2568. }
  2569. BfProject* bfProject = typeInst->mTypeDef->mProject;
  2570. if (!projectList->Contains(bfProject))
  2571. {
  2572. bool handled = false;
  2573. for (int idx = 0; idx < (int)projectList->size(); idx++)
  2574. {
  2575. auto checkProject = (*projectList)[idx];
  2576. bool isBetter = bfProject->ContainsReference(checkProject);
  2577. bool isWorse = checkProject->ContainsReference(bfProject);
  2578. if (isBetter == isWorse)
  2579. continue;
  2580. if (isBetter)
  2581. {
  2582. if (idx >= immutableLength)
  2583. {
  2584. // This is even more specific, so replace with this one
  2585. (*projectList)[idx] = bfProject;
  2586. handled = true;
  2587. }
  2588. }
  2589. else
  2590. {
  2591. // This is less specific, ignore
  2592. handled = true;
  2593. }
  2594. break;
  2595. }
  2596. if (!handled)
  2597. {
  2598. projectList->Add(bfProject);
  2599. }
  2600. }
  2601. if (checkType->IsTuple())
  2602. {
  2603. auto tupleType = (BfTupleType*)checkType;
  2604. for (auto& fieldInstance : tupleType->mFieldInstances)
  2605. GetProjectList(fieldInstance.mResolvedType, projectList, immutableLength);
  2606. }
  2607. auto delegateInfo = checkType->GetDelegateInfo();
  2608. if (delegateInfo != NULL)
  2609. {
  2610. GetProjectList(delegateInfo->mReturnType, projectList, immutableLength);
  2611. for (auto param : delegateInfo->mParams)
  2612. GetProjectList(param, projectList, immutableLength);
  2613. }
  2614. }
  2615. else if (checkType->IsPointer())
  2616. GetProjectList(((BfPointerType*)checkType)->mElementType, projectList, immutableLength);
  2617. else if (checkType->IsRef())
  2618. GetProjectList(((BfRefType*)checkType)->mElementType, projectList, immutableLength);
  2619. else if (checkType->IsSizedArray())
  2620. GetProjectList(((BfSizedArrayType*)checkType)->mElementType, projectList, immutableLength);
  2621. else if (checkType->IsMethodRef())
  2622. GetProjectList(((BfMethodRefType*)checkType)->mOwner, projectList, immutableLength);
  2623. }
  2624. static BfPrimitiveType* GetPrimitiveType(BfModule* module, BfTypeCode typeCode);
  2625. static void PopulateType(BfModule* module, BfType* type);
  2626. template <typename T>
  2627. static void SplatIterate(const T& dataLambda, BfType* checkType)
  2628. {
  2629. auto checkTypeInstance = checkType->ToTypeInstance();
  2630. if ((checkTypeInstance != NULL) && (checkTypeInstance->IsValueType()) && (checkTypeInstance->IsDataIncomplete()))
  2631. PopulateType(checkTypeInstance->mModule, checkTypeInstance);
  2632. if (checkType->IsStruct())
  2633. {
  2634. if (checkTypeInstance->mBaseType != NULL)
  2635. SplatIterate<T>(dataLambda, checkTypeInstance->mBaseType);
  2636. if (checkTypeInstance->mIsUnion)
  2637. {
  2638. BfType* unionInnerType = checkTypeInstance->GetUnionInnerType();
  2639. SplatIterate<T>(dataLambda, unionInnerType);
  2640. }
  2641. else
  2642. {
  2643. for (int fieldIdx = 0; fieldIdx < (int)checkTypeInstance->mFieldInstances.size(); fieldIdx++)
  2644. {
  2645. auto fieldInstance = (BfFieldInstance*)&checkTypeInstance->mFieldInstances[fieldIdx];
  2646. if (fieldInstance->mDataIdx >= 0)
  2647. {
  2648. SplatIterate<T>(dataLambda, fieldInstance->GetResolvedType());
  2649. }
  2650. }
  2651. }
  2652. if (checkTypeInstance->IsEnum())
  2653. {
  2654. // Add discriminator
  2655. auto dscrType = checkTypeInstance->GetDiscriminatorType();
  2656. dataLambda(dscrType);
  2657. }
  2658. }
  2659. else if (checkType->IsMethodRef())
  2660. {
  2661. auto methodRefType = (BfMethodRefType*)checkType;
  2662. for (int dataIdx = 0; dataIdx < methodRefType->GetCaptureDataCount(); dataIdx++)
  2663. {
  2664. if (methodRefType->WantsDataPassedAsSplat(dataIdx))
  2665. SplatIterate<T>(dataLambda, methodRefType->GetCaptureType(dataIdx));
  2666. else
  2667. dataLambda(methodRefType->GetCaptureType(dataIdx));
  2668. }
  2669. }
  2670. else if (!checkType->IsValuelessType())
  2671. {
  2672. dataLambda(checkType);
  2673. }
  2674. }
  2675. static int GetSplatCount(BfType* type);
  2676. };
  2677. //void DbgCheckType(llvm::Type* checkType);
  2678. NS_BF_END
  2679. namespace std
  2680. {
  2681. template<>
  2682. struct hash<Beefy::BfTypeVector>
  2683. {
  2684. size_t operator()(const Beefy::BfTypeVector& val) const
  2685. {
  2686. int curHash = 0;
  2687. for (auto type : val)
  2688. curHash = ((curHash ^ type->mTypeId) << 5) - curHash;
  2689. return curHash;
  2690. }
  2691. };
  2692. template<>
  2693. struct hash<Beefy::BfFieldRef>
  2694. {
  2695. size_t operator()(const Beefy::BfFieldRef& fieldRef) const
  2696. {
  2697. return (size_t)fieldRef.mTypeInstance + fieldRef.mFieldIdx;
  2698. }
  2699. };
  2700. template<>
  2701. struct hash<Beefy::BfHotDevirtualizedMethod>
  2702. {
  2703. size_t operator()(const Beefy::BfHotDevirtualizedMethod& val) const
  2704. {
  2705. return (size_t)val.mMethod;
  2706. }
  2707. };
  2708. template<>
  2709. struct hash<Beefy::BfHotFunctionReference>
  2710. {
  2711. size_t operator()(const Beefy::BfHotFunctionReference& val) const
  2712. {
  2713. return (size_t)val.mMethod;
  2714. }
  2715. };
  2716. }