BfResolvedTypeUtils.cpp 110 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820
  1. #include "BeefySysLib/util/AllocDebug.h"
  2. #include "BfCompiler.h"
  3. #include "BfParser.h"
  4. #include "BfDefBuilder.h"
  5. #include "BfMangler.h"
  6. #include "BfConstResolver.h"
  7. #include "BfModule.h"
  8. #include "BeefySysLib/util/BeefPerf.h"
  9. #pragma warning(disable:4996)
  10. #pragma warning(disable:4267)
  11. USING_NS_BF;
  12. //void Beefy::DbgCheckType(llvm::Type* checkType)
  13. //{
  14. //#ifdef _DEBUG
  15. // /*while (auto ptrType = llvm::dyn_cast<llvm::PointerType>(checkType))
  16. // {
  17. // checkType = ptrType->getElementType();
  18. // }
  19. //
  20. // auto structType = llvm::dyn_cast<llvm::StructType>(checkType);
  21. // if (structType != NULL)
  22. // {
  23. // auto stringRef = structType->getName();
  24. // BF_ASSERT(strncmp(stringRef.data(), "DEAD", 4) != 0);
  25. // }*/
  26. //#endif
  27. //}
  28. void BfTypedValue::DbgCheckType() const
  29. {
  30. /*if (mType != NULL)
  31. {
  32. auto structType = llvm::dyn_cast<llvm::StructType>(mType->mIRType);
  33. if (structType != NULL)
  34. {
  35. auto stringRef = structType->getName();
  36. BF_ASSERT(strncmp(stringRef.data(), "DEAD", 4) != 0);
  37. }
  38. }*/
  39. #ifdef _DEBUG
  40. /*if (mValue != NULL)
  41. {
  42. auto checkType = mValue->getType();
  43. Beefy::DbgCheckType(checkType);
  44. }*/
  45. #endif
  46. }
  47. bool BfTypedValue::IsValuelessType() const
  48. {
  49. return mType->IsValuelessType();
  50. }
  51. //////////////////////////////////////////////////////////////////////////
  52. void BfDependencyMap::AddUsedBy(BfType* dependentType, BfDependencyMap::DependencyDependencyFlag flags)
  53. {
  54. BF_ASSERT(dependentType != NULL);
  55. BF_ASSERT(dependentType->mRevision != -1);
  56. //auto itr = mTypeSet.insert(BfDependencyMap::TypeMap::value_type(dependentType, DependencyEntry(dependentType->mRevision, flags)));
  57. //if (!itr.second)
  58. DependencyEntry* dependencyEntry = NULL;
  59. if (mTypeSet.TryAddRaw(dependentType, NULL, &dependencyEntry))
  60. {
  61. dependencyEntry->mRevision = dependentType->mRevision;
  62. dependencyEntry->mFlags = flags;
  63. }
  64. else
  65. {
  66. if (dependencyEntry->mRevision != dependentType->mRevision)
  67. {
  68. dependencyEntry->mRevision = dependentType->mRevision;
  69. dependencyEntry->mFlags = flags;
  70. }
  71. else
  72. {
  73. dependencyEntry->mFlags = (BfDependencyMap::DependencyDependencyFlag)(dependencyEntry->mFlags | flags);
  74. }
  75. }
  76. }
  77. bool BfDependencyMap::IsEmpty()
  78. {
  79. return mTypeSet.size() == 0;
  80. }
  81. BfDependencyMap::TypeMap::iterator BfDependencyMap::begin()
  82. {
  83. return mTypeSet.begin();
  84. }
  85. BfDependencyMap::TypeMap::iterator BfDependencyMap::end()
  86. {
  87. return mTypeSet.end();
  88. }
  89. BfDependencyMap::TypeMap::iterator BfDependencyMap::erase(BfDependencyMap::TypeMap::iterator& itr)
  90. {
  91. return mTypeSet.Remove(itr);
  92. }
  93. //////////////////////////////////////////////////////////////////////////
  94. BfFieldDef* BfFieldInstance::GetFieldDef()
  95. {
  96. if (mFieldIdx == -1)
  97. return NULL;
  98. return mOwner->mTypeDef->mFields[mFieldIdx];
  99. }
  100. //////////////////////////////////////////////////////////////////////////
  101. BfType::BfType()
  102. {
  103. mTypeId = -1;
  104. mContext = NULL;
  105. mRevision = -1;
  106. //mLastUsedRevision = -1;
  107. mDefineState = BfTypeDefineState_Undefined;
  108. //mDICallbackVH = NULL;
  109. //mInnerDICallbackVH = NULL;
  110. mRebuildFlags = BfTypeRebuildFlag_None;
  111. mAlign = -1;
  112. mSize = -1;
  113. //mDICallbackVH = NULL;
  114. //mInnerDICallbackVH = NULL;
  115. mDirty = true;
  116. }
  117. BfModule* BfType::GetModule()
  118. {
  119. if (mContext->mCompiler->mOptions.mCompileOnDemandKind == BfCompileOnDemandKind_AlwaysInclude)
  120. return mContext->mScratchModule;
  121. else
  122. return mContext->mUnreifiedModule;
  123. }
  124. BfTypeInstance* BfType::FindUnderlyingTypeInstance()
  125. {
  126. auto typeInstance = ToTypeInstance();
  127. if (typeInstance != NULL)
  128. return typeInstance;
  129. auto underlyingType = GetUnderlyingType();
  130. while (underlyingType != NULL)
  131. {
  132. auto underlyingTypeInst = underlyingType->ToTypeInstance();
  133. if (underlyingTypeInst != NULL)
  134. return underlyingTypeInst;
  135. underlyingType = underlyingType->GetUnderlyingType();
  136. }
  137. return NULL;
  138. }
  139. void BfType::ReportMemory(MemReporter* memReporter)
  140. {
  141. memReporter->Add(sizeof(BfType));
  142. }
  143. //////////////////////////////////////////////////////////////////////////
  144. BfNonGenericMethodRef::BfNonGenericMethodRef(BfMethodInstance* methodInstance)
  145. {
  146. *this = methodInstance;
  147. }
  148. BfNonGenericMethodRef::operator BfMethodInstance* () const
  149. {
  150. if (mTypeInstance == NULL)
  151. return NULL;
  152. if (mMethodNum < 0)
  153. return NULL;
  154. auto& methodSpecializationGroup = mTypeInstance->mMethodInstanceGroups[mMethodNum];
  155. BF_ASSERT(methodSpecializationGroup.mDefault != NULL);
  156. return methodSpecializationGroup.mDefault;
  157. }
  158. BfMethodInstance* BfNonGenericMethodRef::operator->() const
  159. {
  160. return *this;
  161. }
  162. BfNonGenericMethodRef& BfNonGenericMethodRef::operator=(BfMethodInstance* methodInstance)
  163. {
  164. if (methodInstance == NULL)
  165. {
  166. mTypeInstance = NULL;
  167. mMethodNum = 0;
  168. }
  169. else
  170. {
  171. mTypeInstance = methodInstance->mMethodInstanceGroup->mOwner;
  172. mMethodNum = methodInstance->mMethodInstanceGroup->mMethodIdx;
  173. BF_ASSERT(methodInstance->GetNumGenericArguments() == 0);
  174. mSignatureHash = (int)mTypeInstance->mTypeDef->mSignatureHash;
  175. }
  176. return *this;
  177. }
  178. bool BfNonGenericMethodRef::operator==(const BfNonGenericMethodRef& methodRef) const
  179. {
  180. bool eq = ((methodRef.mKind == mKind) &&
  181. (methodRef.mTypeInstance == mTypeInstance) &&
  182. (methodRef.mMethodNum == mMethodNum));
  183. if (eq)
  184. {
  185. BF_ASSERT((methodRef.mSignatureHash == mSignatureHash) || (methodRef.mSignatureHash == 0) || (mSignatureHash == 0));
  186. }
  187. return eq;
  188. }
  189. bool BfNonGenericMethodRef::operator==(BfMethodInstance* methodInstance) const
  190. {
  191. if (mTypeInstance != methodInstance->GetOwner())
  192. return false;
  193. return methodInstance == (BfMethodInstance*)*this;
  194. }
  195. size_t BfNonGenericMethodRef::Hash::operator()(const BfNonGenericMethodRef& val) const
  196. {
  197. return (val.mTypeInstance->mTypeId << 10) ^ val.mMethodNum;
  198. }
  199. //////////////////////////////////////////////////////////////////////////
  200. BfMethodRef::BfMethodRef(BfMethodInstance* methodInstance)
  201. {
  202. *this = methodInstance;
  203. }
  204. BfMethodRef::operator BfMethodInstance* () const
  205. {
  206. if (mTypeInstance == NULL)
  207. return NULL;
  208. if (mMethodNum < 0)
  209. return NULL;
  210. auto& methodSpecializationGroup = mTypeInstance->mMethodInstanceGroups[mMethodNum];
  211. if (mMethodGenericArguments.size() != 0)
  212. {
  213. bool isSpecialied = false;
  214. int paramIdx = 0;
  215. for (auto genericArg : mMethodGenericArguments)
  216. {
  217. if (!genericArg->IsGenericParam())
  218. {
  219. isSpecialied = true;
  220. break;
  221. }
  222. auto genericParam = (BfGenericParamType*)genericArg;
  223. if ((genericParam->mGenericParamKind != BfGenericParamKind_Method) || (genericParam->mGenericParamIdx != paramIdx))
  224. {
  225. isSpecialied = true;
  226. break;
  227. }
  228. paramIdx++;
  229. }
  230. if (isSpecialied)
  231. {
  232. BfMethodInstance** methodInstancePtr = NULL;
  233. if (methodSpecializationGroup.mMethodSpecializationMap->TryGetValue(mMethodGenericArguments, &methodInstancePtr))
  234. return *methodInstancePtr;
  235. return NULL;
  236. }
  237. }
  238. BF_ASSERT(methodSpecializationGroup.mDefault != NULL);
  239. return methodSpecializationGroup.mDefault;
  240. }
  241. BfMethodInstance* BfMethodRef::operator->() const
  242. {
  243. return *this;
  244. }
  245. BfMethodRef& BfMethodRef::operator=(BfMethodInstance* methodInstance)
  246. {
  247. if (methodInstance == NULL)
  248. {
  249. mTypeInstance = NULL;
  250. mMethodNum = 0;
  251. mMethodRefFlags = BfMethodRefFlag_None;
  252. }
  253. else
  254. {
  255. mTypeInstance = methodInstance->mMethodInstanceGroup->mOwner;
  256. mMethodNum = methodInstance->mMethodInstanceGroup->mMethodIdx;
  257. if (methodInstance->mMethodInfoEx != NULL)
  258. {
  259. mMethodGenericArguments.Clear();
  260. for (auto type : methodInstance->mMethodInfoEx->mMethodGenericArguments)
  261. mMethodGenericArguments.Add(type);
  262. }
  263. mSignatureHash = (int)mTypeInstance->mTypeDef->mSignatureHash;
  264. if (methodInstance->mAlwaysInline)
  265. mMethodRefFlags = BfMethodRefFlag_AlwaysInclude;
  266. else
  267. mMethodRefFlags = BfMethodRefFlag_None;
  268. }
  269. return *this;
  270. }
  271. bool BfMethodRef::operator==(const BfMethodRef& methodRef) const
  272. {
  273. bool eq = ((methodRef.mKind == mKind) &&
  274. (methodRef.mTypeInstance == mTypeInstance) &&
  275. (methodRef.mMethodNum == mMethodNum) &&
  276. (methodRef.mMethodGenericArguments == mMethodGenericArguments) &&
  277. (methodRef.mMethodRefFlags == mMethodRefFlags));
  278. if (eq)
  279. {
  280. BF_ASSERT((methodRef.mSignatureHash == mSignatureHash) || (methodRef.mSignatureHash == 0) || (mSignatureHash == 0));
  281. }
  282. return eq;
  283. }
  284. bool BfMethodRef::operator==(BfMethodInstance* methodInstance) const
  285. {
  286. if (mTypeInstance != methodInstance->GetOwner())
  287. return false;
  288. return methodInstance == (BfMethodInstance*)*this;
  289. }
  290. size_t BfMethodRef::Hash::operator()(const BfMethodRef& val) const
  291. {
  292. return (val.mTypeInstance->mTypeId << 10) ^ (val.mMethodNum << 1) ^ (int)(val.mMethodRefFlags);
  293. }
  294. //////////////////////////////////////////////////////////////////////////
  295. BfFieldRef::BfFieldRef(BfTypeInstance* typeInst, BfFieldDef* fieldDef)
  296. {
  297. mTypeInstance = typeInst;
  298. mFieldIdx = fieldDef->mIdx;
  299. }
  300. BfFieldRef::BfFieldRef(BfFieldInstance* fieldInstance)
  301. {
  302. mTypeInstance = fieldInstance->mOwner;
  303. mFieldIdx = fieldInstance->mFieldIdx;
  304. }
  305. BfFieldRef::operator BfFieldInstance*() const
  306. {
  307. BF_ASSERT(!mTypeInstance->IsDataIncomplete());
  308. return &mTypeInstance->mFieldInstances[mFieldIdx];
  309. }
  310. BfFieldRef::operator BfFieldDef*() const
  311. {
  312. return mTypeInstance->mTypeDef->mFields[mFieldIdx];
  313. }
  314. //////////////////////////////////////////////////////////////////////////
  315. BfPropertyRef::BfPropertyRef(BfTypeInstance* typeInst, BfPropertyDef* propDef)
  316. {
  317. mTypeInstance = typeInst;
  318. mPropIdx = propDef->mIdx;
  319. }
  320. BfPropertyRef::operator BfPropertyDef*() const
  321. {
  322. return mTypeInstance->mTypeDef->mProperties[mPropIdx];
  323. }
  324. //////////////////////////////////////////////////////////////////////////
  325. /*BfMethodInstance* BfTypeInstance::GetVTableMethodInstance(int vtableIdx)
  326. {
  327. auto& methodSpecializationGroup = mVirtualMethodTable[vtableIdx].mTypeInstance->mMethodInstanceGroups[mVirtualMethodTable[vtableIdx].mMethodNum];
  328. return &methodSpecializationGroup.mMethodSpecializationMap.begin()->second;
  329. }*/
  330. static int gDelIdx = 0;
  331. BfType::~BfType()
  332. {
  333. BfLogSys(mContext->mSystem, "~BfType %p\n", this);
  334. /*gDelIdx++;
  335. auto typeInst = ToTypeInstance();
  336. OutputDebugStrF("%d Deleting %08X type %s\n", gDelIdx, this, (typeInst != NULL) ? typeInst->mTypeDef->mName.c_str() : "");*/
  337. //delete mDICallbackVH;
  338. //delete mInnerDICallbackVH;
  339. }
  340. BfFieldInstance::~BfFieldInstance()
  341. {
  342. delete mCustomAttributes;
  343. }
  344. BfType* BfFieldInstance::GetResolvedType()
  345. {
  346. return mResolvedType;
  347. /*if (mType == NULL)
  348. return NULL;
  349. if (!mType->IsGenericParam())
  350. return mType;
  351. if (!mOwner->IsGenericTypeInstance())
  352. return mType;
  353. auto genericParamType = (BfGenericParamType*)mType;
  354. auto genericTypeInst = (BfGenericTypeInstance*)mOwner;
  355. if (genericTypeInst->mIsUnspecialized)
  356. return mType;
  357. if (genericParamType->mGenericParamKind == BfGenericParamKind_Type)
  358. return genericTypeInst->mTypeGenericArguments[genericParamType->mGenericParamIdx];
  359. return mType;*/
  360. }
  361. void BfFieldInstance::SetResolvedType(BfType* type)
  362. {
  363. mResolvedType = type;
  364. }
  365. BfMethodCustomAttributes::~BfMethodCustomAttributes()
  366. {
  367. delete mCustomAttributes;
  368. delete mReturnCustomAttributes;
  369. for (auto paramCustomAttributes : mParamCustomAttributes)
  370. delete paramCustomAttributes;
  371. }
  372. BfMethodInstance* BfMethodParam::GetDelegateParamInvoke()
  373. {
  374. BF_ASSERT(mResolvedType->IsDelegate() || mResolvedType->IsFunction());
  375. auto bfModule = BfModule::GetModuleFor(mResolvedType);
  376. BfMethodInstance* invokeMethodInstance = bfModule->GetRawMethodInstanceAtIdx(mResolvedType->ToTypeInstance(), 0, "Invoke");
  377. return invokeMethodInstance;
  378. }
  379. BfMethodInfoEx::~BfMethodInfoEx()
  380. {
  381. for (auto genericParam : mGenericParams)
  382. genericParam->Release();
  383. delete mMethodCustomAttributes;
  384. delete mClosureInstanceInfo;
  385. }
  386. BfMethodInstance::~BfMethodInstance()
  387. {
  388. if (mHasMethodRefType)
  389. {
  390. auto module = GetOwner()->mModule;
  391. if (!module->mContext->mDeleting)
  392. {
  393. auto methodRefType = module->CreateMethodRefType(this);
  394. module->mContext->DeleteType(methodRefType);
  395. }
  396. }
  397. if (mMethodProcessRequest != NULL)
  398. {
  399. BF_ASSERT(mMethodProcessRequest->mMethodInstance == this);
  400. mMethodProcessRequest->mMethodInstance = NULL;
  401. }
  402. if (mHotMethod != NULL)
  403. {
  404. mHotMethod->mFlags = (BfHotDepDataFlags)(mHotMethod->mFlags & ~BfHotDepDataFlag_IsBound);
  405. mHotMethod->Deref();
  406. }
  407. delete mMethodInfoEx;
  408. }
  409. void BfMethodInstance::UndoDeclaration(bool keepIRFunction)
  410. {
  411. if (mMethodInfoEx != NULL)
  412. {
  413. for (auto genericParam : mMethodInfoEx->mGenericParams)
  414. genericParam->Release();
  415. mMethodInfoEx->mGenericParams.Clear();
  416. delete mMethodInfoEx->mMethodCustomAttributes;
  417. mMethodInfoEx->mMethodCustomAttributes = NULL;
  418. mMethodInfoEx->mGenericTypeBindings.Clear();
  419. }
  420. mReturnType = NULL;
  421. if (!keepIRFunction)
  422. mIRFunction = BfIRValue();
  423. mParams.Clear();
  424. mDefaultValues.Clear();
  425. if (mMethodProcessRequest != NULL)
  426. {
  427. BF_ASSERT(mMethodProcessRequest->mMethodInstance == this);
  428. mMethodProcessRequest->mMethodInstance = NULL;
  429. }
  430. mHasBeenProcessed = false;
  431. mIsUnspecialized = false;
  432. mIsUnspecializedVariation = false;
  433. mDisallowCalling = false;
  434. mIsIntrinsic = false;
  435. mHasFailed = false;
  436. mFailedConstraints = false;
  437. }
  438. BfTypeInstance* BfMethodInstance::GetOwner()
  439. {
  440. return mMethodInstanceGroup->mOwner;
  441. }
  442. BfModule * BfMethodInstance::GetModule()
  443. {
  444. return mMethodInstanceGroup->mOwner->mModule;
  445. }
  446. bool Beefy::BfMethodInstance::IsSpecializedGenericMethod()
  447. {
  448. return (mMethodInfoEx != NULL) && (mMethodInfoEx->mGenericParams.size() != 0) && (!mIsUnspecialized);
  449. }
  450. bool Beefy::BfMethodInstance::IsSpecializedGenericMethodOrType()
  451. {
  452. if ((mMethodInfoEx != NULL) && (mMethodInfoEx->mGenericParams.size() != 0) && (!mIsUnspecialized))
  453. return true;
  454. auto owner = GetOwner();
  455. if (!owner->IsGenericTypeInstance())
  456. return false;
  457. BfGenericTypeInstance* genericTypeInstance = (BfGenericTypeInstance*)owner;
  458. return !genericTypeInstance->mIsUnspecialized;
  459. }
  460. bool BfMethodInstance::IsSpecializedByAutoCompleteMethod()
  461. {
  462. if (mMethodInstanceGroup->mOwner->IsSpecializedByAutoCompleteMethod())
  463. return true;
  464. if (mMethodInfoEx != NULL)
  465. {
  466. for (auto methodArg : mMethodInfoEx->mMethodGenericArguments)
  467. {
  468. // If we are specialized by an autocompleted method reference
  469. if (methodArg->IsMethodRef())
  470. {
  471. auto methodRefType = (BfMethodRefType*)methodArg;
  472. if (methodRefType->mIsAutoCompleteMethod)
  473. return true;
  474. }
  475. }
  476. }
  477. return false;
  478. }
  479. bool BfMethodInstance::HasParamsArray()
  480. {
  481. if (mParams.size() == 0)
  482. return false;
  483. return GetParamKind((int)mParams.size() - 1) == BfParamKind_Params;
  484. }
  485. bool BfMethodInstance::HasStructRet()
  486. {
  487. return (mReturnType->IsComposite()) && (!mReturnType->IsValuelessType());
  488. }
  489. bool BfMethodInstance::HasSelf()
  490. {
  491. if (mReturnType->IsSelf())
  492. return true;
  493. for (int paramIdx = 0; paramIdx < GetParamCount(); paramIdx++)
  494. if (GetParamType(paramIdx)->IsSelf())
  495. return true;
  496. return false;
  497. }
  498. bool BfMethodInstance::IsSkipCall(bool bypassVirtual)
  499. {
  500. if ((mMethodDef->mIsSkipCall) &&
  501. ((!mMethodDef->mIsVirtual) || (bypassVirtual)))
  502. return true;
  503. return false;
  504. }
  505. bool BfMethodInstance::AlwaysInline()
  506. {
  507. return mAlwaysInline;
  508. }
  509. BfImportCallKind BfMethodInstance::GetImportCallKind()
  510. {
  511. if (mMethodDef->mImportKind != BfImportKind_Dynamic)
  512. return BfImportCallKind_None;
  513. if ((mHotMethod != NULL) && ((mHotMethod->mFlags & BfHotDepDataFlag_IsOriginalBuild) == 0))
  514. return BfImportCallKind_GlobalVar_Hot;
  515. return BfImportCallKind_GlobalVar;
  516. }
  517. bool BfMethodInstance::IsTestMethod()
  518. {
  519. return (mMethodInfoEx != NULL) && (mMethodInfoEx->mMethodCustomAttributes != NULL) && (mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes != NULL) &&
  520. (mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes != NULL) && (mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes->Contains(GetOwner()->mModule->mCompiler->mTestAttributeTypeDef));
  521. }
  522. bool BfMethodInstance::HasThis()
  523. {
  524. if (mMethodDef->mIsStatic)
  525. return false;
  526. if ((mMethodInfoEx != NULL) && (mMethodInfoEx->mClosureInstanceInfo != NULL) && (mMethodInfoEx->mClosureInstanceInfo->mThisOverride != NULL))
  527. return !mMethodInfoEx->mClosureInstanceInfo->mThisOverride->IsValuelessType();
  528. return (!mMethodInstanceGroup->mOwner->IsValuelessType());
  529. }
  530. int BfMethodInstance::GetParamCount()
  531. {
  532. return (int)mParams.size();
  533. }
  534. int BfMethodInstance::GetImplicitParamCount()
  535. {
  536. if ((mMethodInfoEx != NULL) && (mMethodInfoEx->mClosureInstanceInfo != NULL) && (mMethodDef->mIsLocalMethod))
  537. return (int)mMethodInfoEx->mClosureInstanceInfo->mCaptureEntries.size();
  538. return 0;
  539. }
  540. String BfMethodInstance::GetParamName(int paramIdx)
  541. {
  542. if (paramIdx == -1)
  543. {
  544. BF_ASSERT(!mMethodDef->mIsStatic);
  545. return "this";
  546. }
  547. if ((mMethodInfoEx != NULL) && (mMethodInfoEx->mClosureInstanceInfo != NULL) && (mMethodDef->mIsLocalMethod))
  548. {
  549. if (paramIdx < (int)mMethodInfoEx->mClosureInstanceInfo->mCaptureEntries.size())
  550. return mMethodInfoEx->mClosureInstanceInfo->mCaptureEntries[paramIdx].mName;
  551. }
  552. BfMethodParam* methodParam = &mParams[paramIdx];
  553. BfParameterDef* paramDef = mMethodDef->mParams[methodParam->mParamDefIdx];
  554. if (methodParam->mDelegateParamIdx != -1)
  555. {
  556. BfMethodInstance* invokeMethodInstance = methodParam->GetDelegateParamInvoke();
  557. if (methodParam->mDelegateParamNameCombine)
  558. return paramDef->mName + "__" + invokeMethodInstance->GetParamName(methodParam->mDelegateParamIdx);
  559. else
  560. return invokeMethodInstance->GetParamName(methodParam->mDelegateParamIdx);
  561. }
  562. return paramDef->mName;
  563. }
  564. BfType* BfMethodInstance::GetParamType(int paramIdx, bool useResolvedType)
  565. {
  566. if (paramIdx == -1)
  567. {
  568. if ((mMethodInfoEx != NULL) && (mMethodInfoEx->mClosureInstanceInfo != NULL) && (mMethodInfoEx->mClosureInstanceInfo->mThisOverride != NULL))
  569. return mMethodInfoEx->mClosureInstanceInfo->mThisOverride;
  570. BF_ASSERT(!mMethodDef->mIsStatic);
  571. auto owner = mMethodInstanceGroup->mOwner;
  572. if ((owner->IsValueType()) && ((mMethodDef->mIsMutating) || (mMethodDef->mNoSplat)))
  573. return owner->mModule->CreatePointerType(owner);
  574. return owner;
  575. }
  576. BfMethodParam* methodParam = &mParams[paramIdx];
  577. if (methodParam->mDelegateParamIdx != -1)
  578. {
  579. BfMethodInstance* invokeMethodInstance = methodParam->GetDelegateParamInvoke();
  580. return invokeMethodInstance->GetParamType(methodParam->mDelegateParamIdx, true);
  581. }
  582. return methodParam->mResolvedType;
  583. }
  584. bool BfMethodInstance::GetParamIsSplat(int paramIdx)
  585. {
  586. if (paramIdx == -1)
  587. {
  588. BF_ASSERT(!mMethodDef->mIsStatic);
  589. auto owner = mMethodInstanceGroup->mOwner;
  590. if ((owner->IsValueType()) && (mMethodDef->mIsMutating || mMethodDef->mNoSplat))
  591. return false;
  592. return owner->mIsSplattable;
  593. }
  594. BfMethodParam* methodParam = &mParams[paramIdx];
  595. if (methodParam->mDelegateParamIdx != -1)
  596. {
  597. BfMethodInstance* invokeMethodInstance = methodParam->GetDelegateParamInvoke();
  598. return invokeMethodInstance->GetParamIsSplat(methodParam->mDelegateParamIdx);
  599. }
  600. return methodParam->mIsSplat;
  601. }
  602. BfParamKind BfMethodInstance::GetParamKind(int paramIdx)
  603. {
  604. BfMethodParam* methodParam = &mParams[paramIdx];
  605. if (methodParam->mParamDefIdx == -1)
  606. return BfParamKind_ImplicitCapture;
  607. BfParameterDef* paramDef = mMethodDef->mParams[methodParam->mParamDefIdx];
  608. if (methodParam->mDelegateParamIdx != -1)
  609. return BfParamKind_DelegateParam;
  610. return paramDef->mParamKind;
  611. }
  612. bool BfMethodInstance::WasGenericParam(int paramIdx)
  613. {
  614. BfMethodParam* methodParam = &mParams[paramIdx];
  615. return methodParam->mWasGenericParam;
  616. }
  617. bool BfMethodInstance::IsParamSkipped(int paramIdx)
  618. {
  619. BfType* paramType = GetParamType(paramIdx);
  620. if ((paramType->CanBeValuelessType()) && (paramType->IsDataIncomplete()))
  621. GetModule()->PopulateType(paramType, BfPopulateType_Data);
  622. if ((paramType->IsValuelessType()) && (!paramType->IsMethodRef()))
  623. return true;
  624. return false;
  625. }
  626. bool BfMethodInstance::IsImplicitCapture(int paramIdx)
  627. {
  628. BfMethodParam* methodParam = &mParams[paramIdx];
  629. if (methodParam->mParamDefIdx == -1)
  630. return true;
  631. return false;
  632. }
  633. BfExpression* BfMethodInstance::GetParamInitializer(int paramIdx)
  634. {
  635. BfMethodParam* methodParam = &mParams[paramIdx];
  636. if (methodParam->mParamDefIdx == -1)
  637. return NULL;
  638. BfParameterDef* paramDef = mMethodDef->mParams[methodParam->mParamDefIdx];
  639. if (paramDef->mParamDeclaration != NULL)
  640. return paramDef->mParamDeclaration->mInitializer;
  641. return NULL;
  642. }
  643. BfTypeReference* BfMethodInstance::GetParamTypeRef(int paramIdx)
  644. {
  645. BfMethodParam* methodParam = &mParams[paramIdx];
  646. if (methodParam->mParamDefIdx == -1)
  647. return NULL;
  648. BfParameterDef* paramDef = mMethodDef->mParams[methodParam->mParamDefIdx];
  649. if (paramDef->mParamDeclaration != NULL)
  650. return paramDef->mParamDeclaration->mTypeRef;
  651. return NULL;
  652. }
  653. BfIdentifierNode* BfMethodInstance::GetParamNameNode(int paramIdx)
  654. {
  655. if (paramIdx == -1)
  656. return NULL;
  657. if ((mMethodInfoEx != NULL) && (mMethodInfoEx->mClosureInstanceInfo != NULL) && (mMethodDef->mIsLocalMethod))
  658. {
  659. if (paramIdx < (int)mMethodInfoEx->mClosureInstanceInfo->mCaptureEntries.size())
  660. return mMethodInfoEx->mClosureInstanceInfo->mCaptureEntries[paramIdx].mNameNode;
  661. }
  662. BfMethodParam* methodParam = &mParams[paramIdx];
  663. BfParameterDef* paramDef = mMethodDef->mParams[methodParam->mParamDefIdx];
  664. if (paramDef->mParamDeclaration != NULL)
  665. return BfNodeDynCast<BfIdentifierNode>(paramDef->mParamDeclaration->mNameNode);
  666. // else if ((mClosureInstanceInfo != NULL) && (paramIdx < (int)mClosureInstanceInfo->mCaptureNodes.size()))
  667. // return mClosureInstanceInfo->mCaptureNodes[paramIdx];
  668. return NULL;
  669. }
  670. int BfMethodInstance::DbgGetVirtualMethodNum()
  671. {
  672. auto module = GetOwner()->mModule;
  673. int vDataVal = -1;
  674. if (mVirtualTableIdx != -1)
  675. {
  676. module->HadSlotCountDependency();
  677. int vDataIdx = -1;
  678. vDataIdx = 1 + module->mCompiler->mMaxInterfaceSlots;
  679. vDataIdx += module->mCompiler->GetDynCastVDataCount();
  680. if ((module->mCompiler->mOptions.mHasVDataExtender) && (module->mCompiler->IsHotCompile()))
  681. {
  682. auto typeInst = mMethodInstanceGroup->mOwner;
  683. int extMethodIdx = (mVirtualTableIdx - typeInst->GetBaseVTableSize()) - typeInst->GetOrigSelfVTableSize();
  684. if (extMethodIdx >= 0)
  685. {
  686. // Extension?
  687. int vExtOfs = typeInst->GetOrigBaseVTableSize();
  688. vDataVal = ((vDataIdx + vExtOfs + 1) << 20) | (extMethodIdx);
  689. }
  690. else
  691. {
  692. // Map this new virtual index back to the original index
  693. vDataIdx += (mVirtualTableIdx - typeInst->GetBaseVTableSize()) + typeInst->GetOrigBaseVTableSize();
  694. }
  695. }
  696. else
  697. {
  698. vDataIdx += mVirtualTableIdx;
  699. }
  700. if (vDataVal == -1)
  701. vDataVal = vDataIdx;
  702. }
  703. return vDataVal;
  704. }
  705. void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType, SizedArrayImpl<BfIRType>& paramTypes, bool forceStatic)
  706. {
  707. if ((mMethodDef->mNoSplat) && (GetOwner()->GetLoweredType() != BfTypeCode_None))
  708. {
  709. NOP;
  710. }
  711. module->PopulateType(mReturnType);
  712. if (mReturnType->IsValuelessType())
  713. {
  714. auto voidType = module->GetPrimitiveType(BfTypeCode_None);
  715. returnType = module->mBfIRBuilder->MapType(voidType);
  716. }
  717. else if (mReturnType->IsComposite())
  718. {
  719. auto voidType = module->GetPrimitiveType(BfTypeCode_None);
  720. returnType = module->mBfIRBuilder->MapType(voidType);
  721. auto typeInst = mReturnType->ToTypeInstance();
  722. if (typeInst != NULL)
  723. {
  724. paramTypes.push_back(module->mBfIRBuilder->MapTypeInstPtr(typeInst));
  725. }
  726. else
  727. {
  728. auto ptrType = module->CreatePointerType(mReturnType);
  729. paramTypes.push_back(module->mBfIRBuilder->MapType(ptrType));
  730. }
  731. }
  732. else
  733. {
  734. returnType = module->mBfIRBuilder->MapType(mReturnType);
  735. }
  736. for (int paramIdx = -1; paramIdx < GetParamCount(); paramIdx++)
  737. {
  738. BfType* checkType = NULL;
  739. if (paramIdx == -1)
  740. {
  741. if ((mMethodDef->mIsStatic) || (forceStatic))
  742. continue;
  743. if (mIsClosure)
  744. {
  745. checkType = module->mCurMethodState->mClosureState->mClosureType;
  746. }
  747. else
  748. checkType = GetOwner();
  749. }
  750. else
  751. {
  752. checkType = GetParamType(paramIdx);
  753. }
  754. if ((paramIdx != -1) || (!mMethodDef->mNoSplat && !mMethodDef->mIsMutating))
  755. {
  756. auto loweredTypeCode = checkType->GetLoweredType();
  757. if (loweredTypeCode != BfTypeCode_None)
  758. checkType = module->GetPrimitiveType(loweredTypeCode);
  759. }
  760. if ((paramIdx == 0) && (GetParamName(0) == "this") && (checkType->IsPointer()))
  761. {
  762. // We don't actually pass a this pointer for mut methods in valueless structs
  763. auto underlyingType = checkType->GetUnderlyingType();
  764. module->PopulateType(underlyingType, BfPopulateType_Data);
  765. if (underlyingType->IsValuelessType())
  766. continue;
  767. }
  768. if (checkType->CanBeValuelessType())
  769. module->PopulateType(checkType, BfPopulateType_Data);
  770. if ((checkType->IsValuelessType()) && (!checkType->IsMethodRef()))
  771. continue;
  772. bool doSplat = true;
  773. if (checkType->IsMethodRef())
  774. {
  775. doSplat = true;
  776. }
  777. else if (mMethodDef->mNoSplat)
  778. {
  779. doSplat = false;
  780. }
  781. else
  782. {
  783. int splatCount = checkType->GetSplatCount();
  784. doSplat = ((checkType->IsSplattable()) && ((paramIdx != -1) || (!mMethodDef->mIsMutating)));
  785. if ((int)paramTypes.size() + splatCount > module->mCompiler->mOptions.mMaxSplatRegs)
  786. doSplat = false;
  787. }
  788. auto _AddType = [&](BfType* type)
  789. {
  790. if ((type->IsComposite()) || ((!doSplat) && (paramIdx == -1) && (type->IsTypedPrimitive())))
  791. {
  792. auto typeInst = type->ToTypeInstance();
  793. if (typeInst != NULL)
  794. paramTypes.push_back(module->mBfIRBuilder->MapTypeInstPtr(typeInst));
  795. else
  796. paramTypes.push_back(module->mBfIRBuilder->MapType(module->CreatePointerType(type)));
  797. }
  798. else
  799. {
  800. paramTypes.push_back(module->mBfIRBuilder->MapType(type));
  801. }
  802. };
  803. if (doSplat)
  804. {
  805. BfTypeUtils::SplatIterate([&](BfType* checkType)
  806. {
  807. _AddType(checkType);
  808. }, checkType);
  809. }
  810. else
  811. _AddType(checkType);
  812. }
  813. }
  814. int BfMethodInstance::GetIRFunctionParamCount(BfModule* module)
  815. {
  816. //TODO: This is dumb, do this better
  817. SizedArray<BfIRType, 8> params;
  818. BfIRType returnType;
  819. GetIRFunctionInfo(module, returnType, params);
  820. return (int)params.size();
  821. }
  822. bool BfMethodInstance::IsExactMatch(BfMethodInstance* other, bool ignoreImplicitParams, bool checkThis)
  823. {
  824. if (mReturnType != other->mReturnType)
  825. return false;
  826. int implicitParamCountA = ignoreImplicitParams ? GetImplicitParamCount() : 0;
  827. int implicitParamCountB = ignoreImplicitParams ? other->GetImplicitParamCount() : 0;
  828. if (checkThis)
  829. {
  830. if (other->mMethodDef->mIsStatic != mMethodDef->mIsStatic)
  831. {
  832. // If we are static and we have to match a non-static method, allow us to do so if we have an explicitly defined 'this' param that matches
  833. if (other->mMethodDef->mIsStatic)
  834. return false;
  835. if ((GetParamCount() > 0) && (GetParamName(0) == "this"))
  836. {
  837. auto thisType = GetParamType(0);
  838. auto otherThisType = other->GetParamType(-1);
  839. if (thisType != otherThisType)
  840. return false;
  841. implicitParamCountA++;
  842. }
  843. else
  844. {
  845. // Valueless types don't actually pass a 'this' anyway
  846. if (!other->GetOwner()->IsValuelessType())
  847. return false;
  848. }
  849. }
  850. }
  851. if (GetParamCount() - implicitParamCountA != other->GetParamCount() - implicitParamCountB)
  852. return false;
  853. for (int i = 0; i < (int)GetParamCount() - implicitParamCountA; i++)
  854. {
  855. auto paramA = GetParamType(i + implicitParamCountA);
  856. auto paramB = other->GetParamType(i + implicitParamCountB);
  857. if (paramA != paramB)
  858. return false;
  859. }
  860. return true;
  861. }
  862. bool BfMethodInstance::IsReifiedAndImplemented()
  863. {
  864. return mIsReified && mMethodInstanceGroup->IsImplemented();
  865. }
  866. BfMethodInfoEx* BfMethodInstance::GetMethodInfoEx()
  867. {
  868. if (mMethodInfoEx == NULL)
  869. mMethodInfoEx = new BfMethodInfoEx();
  870. return mMethodInfoEx;
  871. }
  872. void BfMethodInstance::ReportMemory(MemReporter* memReporter)
  873. {
  874. memReporter->BeginSection("MethodInstance");
  875. memReporter->Add(sizeof(BfMethodInstance));
  876. if (mMethodInfoEx != NULL)
  877. {
  878. memReporter->BeginSection("MethodInfoEx");
  879. memReporter->Add(sizeof(BfMethodInfoEx));
  880. if (!mMethodInfoEx->mGenericParams.IsEmpty())
  881. memReporter->AddVecPtr("GenericParams", mMethodInfoEx->mGenericParams, false);
  882. if (!mMethodInfoEx->mGenericTypeBindings.IsEmpty())
  883. memReporter->AddMap("GenericTypeBindings", mMethodInfoEx->mGenericTypeBindings, false);
  884. if (mMethodInfoEx->mMethodCustomAttributes != NULL)
  885. {
  886. if (mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes != NULL)
  887. mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes->ReportMemory(memReporter);
  888. }
  889. if (!mMethodInfoEx->mMethodGenericArguments.IsEmpty())
  890. memReporter->AddVec("MethodGenericArguments", mMethodInfoEx->mMethodGenericArguments, false);
  891. if (!mMethodInfoEx->mMangledName.IsEmpty())
  892. memReporter->AddStr("MangledName", mMethodInfoEx->mMangledName);
  893. memReporter->EndSection();
  894. }
  895. memReporter->AddVec("Params", mParams, false);
  896. if (!mDefaultValues.IsEmpty())
  897. memReporter->AddVec("DefaultValues", mDefaultValues, false);
  898. memReporter->EndSection();
  899. }
  900. void BfCustomAttributes::ReportMemory(MemReporter* memReporter)
  901. {
  902. memReporter->BeginSection("CustomAttributes");
  903. memReporter->Add(sizeof(BfCustomAttributes));
  904. memReporter->AddVec(mAttributes);
  905. memReporter->EndSection();
  906. }
  907. //////////////////////////////////////////////////////////////////////////
  908. BfModuleMethodInstance::BfModuleMethodInstance(BfMethodInstance* methodInstance)
  909. {
  910. mMethodInstance = methodInstance;
  911. mFunc = mMethodInstance->mIRFunction;
  912. // if (methodInstance->GetImportCallKind() == BfImportCallKind_Thunk)
  913. // {
  914. // auto declModule = methodInstance->mDeclModule;
  915. // BfIRValue* irFuncPtr = NULL;
  916. // if (declModule->mFuncReferences.TryGetValue(methodInstance, &irFuncPtr))
  917. // mFunc = *irFuncPtr;
  918. // }
  919. }
  920. //////////////////////////////////////////////////////////////////////////
  921. BfMethodRefType::~BfMethodRefType()
  922. {
  923. if (!mContext->mDeleting)
  924. BF_ASSERT(mMethodRef == NULL);
  925. }
  926. BfMethodInstanceGroup::~BfMethodInstanceGroup()
  927. {
  928. if (mRefCount != 0)
  929. {
  930. BF_ASSERT(mOwner->mModule->mContext->mDeleting);
  931. }
  932. delete mDefault;
  933. if (mMethodSpecializationMap != NULL)
  934. {
  935. for (auto& kv : *mMethodSpecializationMap)
  936. delete kv.mValue;
  937. delete mMethodSpecializationMap;
  938. }
  939. }
  940. //////////////////////////////////////////////////////////////////////////
  941. BfTypeInstance::~BfTypeInstance()
  942. {
  943. delete mCustomAttributes;
  944. delete mAttributeData;
  945. for (auto methodInst : mInternalMethods)
  946. delete methodInst;
  947. delete mHotTypeData;
  948. delete mConstHolder;
  949. }
  950. int BfTypeInstance::GetSplatCount()
  951. {
  952. if (IsValuelessType())
  953. return 0;
  954. if (!mIsSplattable)
  955. return 1;
  956. int splatCount = 0;
  957. BfTypeUtils::SplatIterate([&](BfType* checkType) { splatCount++; }, this);
  958. return splatCount;
  959. }
  960. bool BfTypeInstance::IsString()
  961. {
  962. return mTypeDef == mContext->mCompiler->mStringTypeDef;
  963. }
  964. int BfTypeInstance::GetOrigVTableSize()
  965. {
  966. if (!mModule->mCompiler->mOptions.mHasVDataExtender)
  967. {
  968. BF_ASSERT(mHotTypeData == NULL);
  969. return mVirtualMethodTableSize;
  970. }
  971. if (mHotTypeData != NULL)
  972. {
  973. // When we have a pending data change, treat it as a fresh vtable
  974. if ((!mHotTypeData->mPendingDataChange) && (mHotTypeData->mVTableOrigLength != -1))
  975. return mHotTypeData->mVTableOrigLength;
  976. }
  977. if (mBaseType != NULL)
  978. return mBaseType->GetOrigVTableSize() + (mVirtualMethodTableSize - mBaseType->mVirtualMethodTableSize);
  979. return mVirtualMethodTableSize;
  980. }
  981. int BfTypeInstance::GetSelfVTableSize()
  982. {
  983. if (mBaseType != NULL)
  984. {
  985. BF_ASSERT(mBaseType->mVirtualMethodTableSize > 0);
  986. return mVirtualMethodTableSize - mBaseType->mVirtualMethodTableSize;
  987. }
  988. return mVirtualMethodTableSize;
  989. }
  990. int BfTypeInstance::GetOrigSelfVTableSize()
  991. {
  992. if (mBaseType != NULL)
  993. return GetOrigVTableSize() - GetOrigBaseVTableSize();
  994. return GetOrigVTableSize();
  995. }
  996. int BfTypeInstance::GetBaseVTableSize()
  997. {
  998. if (mBaseType != NULL)
  999. return mBaseType->mVirtualMethodTableSize;
  1000. return 0;
  1001. }
  1002. int BfTypeInstance::GetOrigBaseVTableSize()
  1003. {
  1004. if (mBaseType != NULL)
  1005. return mBaseType->GetOrigVTableSize();
  1006. return 0;
  1007. }
  1008. int BfTypeInstance::GetIFaceVMethodSize()
  1009. {
  1010. int maxIFaceIdx = 0;
  1011. auto checkTypeInstance = this;
  1012. while (checkTypeInstance != NULL)
  1013. {
  1014. for (auto&& interfaceEntry : checkTypeInstance->mInterfaces)
  1015. {
  1016. maxIFaceIdx = BF_MAX(maxIFaceIdx, interfaceEntry.mStartVirtualIdx + interfaceEntry.mInterfaceType->mVirtualMethodTableSize);
  1017. }
  1018. checkTypeInstance = checkTypeInstance->mBaseType;
  1019. }
  1020. return maxIFaceIdx;
  1021. }
  1022. BfType* BfTypeInstance::GetUnionInnerType(bool* wantSplat)
  1023. {
  1024. if (wantSplat != NULL)
  1025. *wantSplat = false;
  1026. if (!mIsUnion)
  1027. return NULL;
  1028. int unionSize = 0;
  1029. BfType* unionInnerType = NULL;
  1030. bool makeRaw = false;
  1031. for (int fieldIdx = 0; fieldIdx < (int)mFieldInstances.size(); fieldIdx++)
  1032. {
  1033. auto fieldInstance = (BfFieldInstance*)&mFieldInstances[fieldIdx];
  1034. auto fieldDef = fieldInstance->GetFieldDef();
  1035. BfType* checkInnerType = NULL;
  1036. if (fieldDef == NULL)
  1037. continue;
  1038. if ((fieldDef->mIsConst) && (fieldInstance->mIsEnumPayloadCase))
  1039. {
  1040. BF_ASSERT(mIsUnion);
  1041. checkInnerType = fieldInstance->mResolvedType;
  1042. }
  1043. if (fieldInstance->mDataIdx >= 0)
  1044. {
  1045. checkInnerType = fieldInstance->mResolvedType;
  1046. }
  1047. if (checkInnerType != NULL)
  1048. {
  1049. mModule->PopulateType(checkInnerType);
  1050. if (checkInnerType->mSize > unionSize)
  1051. unionSize = checkInnerType->mSize;
  1052. if ((!checkInnerType->IsValuelessType()) && (checkInnerType != unionInnerType))
  1053. {
  1054. if (unionInnerType == NULL)
  1055. {
  1056. unionInnerType = checkInnerType;
  1057. }
  1058. else
  1059. {
  1060. if (checkInnerType->mSize > unionInnerType->mSize)
  1061. {
  1062. bool needsMemberCasting = false;
  1063. if (!mModule->AreSplatsCompatible(checkInnerType, unionInnerType, &needsMemberCasting))
  1064. {
  1065. unionInnerType = NULL;
  1066. makeRaw = true;
  1067. }
  1068. else
  1069. {
  1070. unionInnerType = checkInnerType;
  1071. }
  1072. }
  1073. else
  1074. {
  1075. bool needsMemberCasting = false;
  1076. if (!mModule->AreSplatsCompatible(unionInnerType, checkInnerType, &needsMemberCasting))
  1077. {
  1078. unionInnerType = NULL;
  1079. makeRaw = true;
  1080. }
  1081. }
  1082. }
  1083. }
  1084. }
  1085. }
  1086. unionSize = BF_ALIGN(unionSize, mInstAlign);
  1087. BF_ASSERT(unionInnerType != this);
  1088. // Don't allow a float for the inner type -- to avoid invalid loading invalid FP bit patterns during copies
  1089. if ((unionInnerType != NULL) && (!makeRaw))
  1090. {
  1091. if (wantSplat != NULL)
  1092. *wantSplat = true;
  1093. }
  1094. else
  1095. {
  1096. switch (unionSize)
  1097. {
  1098. case 0: return mModule->CreateSizedArrayType(mModule->GetPrimitiveType(BfTypeCode_Int8), 0);
  1099. case 1: return mModule->GetPrimitiveType(BfTypeCode_Int8);
  1100. case 2: if (mInstAlign >= 2) return mModule->GetPrimitiveType(BfTypeCode_Int16);
  1101. case 4: if (mInstAlign >= 4) return mModule->GetPrimitiveType(BfTypeCode_Int32);
  1102. case 8: if (mInstAlign >= 8) return mModule->GetPrimitiveType(BfTypeCode_Int64);
  1103. }
  1104. if ((unionSize % 8 == 0) && (mInstAlign >= 8))
  1105. return mModule->CreateSizedArrayType(mModule->GetPrimitiveType(BfTypeCode_Int64), unionSize / 8);
  1106. if ((unionSize % 4 == 0) && (mInstAlign >= 4))
  1107. return mModule->CreateSizedArrayType(mModule->GetPrimitiveType(BfTypeCode_Int32), unionSize / 4);
  1108. if ((unionSize % 2 == 0) && (mInstAlign >= 2))
  1109. return mModule->CreateSizedArrayType(mModule->GetPrimitiveType(BfTypeCode_Int16), unionSize / 2);
  1110. return mModule->CreateSizedArrayType(mModule->GetPrimitiveType(BfTypeCode_Int8), unionSize);
  1111. }
  1112. return unionInnerType;
  1113. }
  1114. BfPrimitiveType* BfTypeInstance::GetDiscriminatorType(int* outDataIdx)
  1115. {
  1116. BF_ASSERT(IsPayloadEnum());
  1117. auto& fieldInstance = mFieldInstances.back();
  1118. BF_ASSERT(fieldInstance.GetFieldDef() == NULL);
  1119. if (fieldInstance.mResolvedType == NULL)
  1120. {
  1121. BF_ASSERT(IsIncomplete());
  1122. // Use Int64 as a placeholder until we determine the correct type...
  1123. return mModule->GetPrimitiveType(BfTypeCode_Int64);
  1124. }
  1125. BF_ASSERT(fieldInstance.mResolvedType != NULL);
  1126. BF_ASSERT(fieldInstance.mResolvedType->IsPrimitiveType());
  1127. if (outDataIdx != NULL)
  1128. *outDataIdx = fieldInstance.mDataIdx;
  1129. return (BfPrimitiveType*)fieldInstance.mResolvedType;
  1130. }
  1131. BfTypeCode BfTypeInstance::GetLoweredType()
  1132. {
  1133. if ((mTypeDef->mTypeCode != BfTypeCode_Struct) || (mIsSplattable))
  1134. return BfTypeCode_None;
  1135. switch (mInstSize)
  1136. {
  1137. case 1: return BfTypeCode_Int8;
  1138. case 2: return BfTypeCode_Int16;
  1139. case 4: return BfTypeCode_Int32;
  1140. case 8: if (mModule->mSystem->mPtrSize == 8) return BfTypeCode_Int64;
  1141. }
  1142. return BfTypeCode_None;
  1143. }
  1144. bool BfTypeInstance::HasEquivalentLayout(BfTypeInstance* compareTo)
  1145. {
  1146. if (mFieldInstances.size() != compareTo->mFieldInstances.size())
  1147. return false;
  1148. for (int fieldIdx = 0; fieldIdx < (int)mFieldInstances.size(); fieldIdx++)
  1149. {
  1150. auto fieldInstance = &mFieldInstances[fieldIdx];
  1151. auto otherFieldInstance = &compareTo->mFieldInstances[fieldIdx];
  1152. if (fieldInstance->mResolvedType != otherFieldInstance->mResolvedType)
  1153. return false;
  1154. }
  1155. return true;
  1156. }
  1157. BfIRConstHolder* BfTypeInstance::GetOrCreateConstHolder()
  1158. {
  1159. if (mConstHolder == NULL)
  1160. mConstHolder = new BfIRConstHolder(mModule);
  1161. return mConstHolder;
  1162. }
  1163. BfIRValue BfTypeInstance::CreateConst(BfConstant* fromConst, BfIRConstHolder* fromHolder)
  1164. {
  1165. if (mConstHolder == NULL)
  1166. mConstHolder = new BfIRConstHolder(mModule);
  1167. return mConstHolder->CreateConst(fromConst, fromHolder);
  1168. }
  1169. bool BfTypeInstance::HasOverrideMethods()
  1170. {
  1171. if (mTypeDef->mHasOverrideMethods)
  1172. return true;
  1173. if (mBaseType != NULL)
  1174. return mBaseType->HasOverrideMethods();
  1175. return false;
  1176. }
  1177. bool BfTypeInstance::GetResultInfo(BfType*& valueType, int& okTagId)
  1178. {
  1179. BF_ASSERT(!IsDataIncomplete());
  1180. if (mFieldInstances.size() < 2)
  1181. return false;
  1182. for (auto& fieldInstance : mFieldInstances)
  1183. {
  1184. if (!fieldInstance.mIsEnumPayloadCase)
  1185. continue;
  1186. if ((fieldInstance.mIsEnumPayloadCase) && (fieldInstance.GetFieldDef()->mName == "Ok") && (fieldInstance.mResolvedType->IsTuple()))
  1187. {
  1188. auto tupleType = (BfTupleType*)fieldInstance.mResolvedType;
  1189. if (tupleType->mFieldInstances.size() == 1)
  1190. {
  1191. valueType = tupleType->mFieldInstances[0].mResolvedType;
  1192. okTagId = -fieldInstance.mDataIdx - 1;
  1193. return true;
  1194. }
  1195. }
  1196. break;
  1197. }
  1198. return false;
  1199. }
  1200. void BfTypeInstance::ReportMemory(MemReporter* memReporter)
  1201. {
  1202. memReporter->Add(sizeof(BfTypeInstance));
  1203. int depSize = 0;
  1204. depSize += sizeof((int)mDependencyMap.mTypeSet.mAllocSize * sizeof(BfDependencyMap::TypeMap::EntryPair));
  1205. memReporter->Add("DepMap", depSize);
  1206. memReporter->AddVec(mInterfaces, false);
  1207. memReporter->AddVec(mInterfaceMethodTable, false);
  1208. if (mCustomAttributes != NULL)
  1209. mCustomAttributes->ReportMemory(memReporter);
  1210. int methodCount = 0;
  1211. memReporter->BeginSection("MethodData");
  1212. for (auto& methodInstGroup : mMethodInstanceGroups)
  1213. {
  1214. memReporter->Add(sizeof(BfMethodInstanceGroup));
  1215. if (methodInstGroup.mDefault != NULL)
  1216. {
  1217. methodInstGroup.mDefault->ReportMemory(memReporter);
  1218. methodCount++;
  1219. }
  1220. if (methodInstGroup.mMethodSpecializationMap != NULL)
  1221. {
  1222. memReporter->Add((int)methodInstGroup.mMethodSpecializationMap->mAllocSize * sizeof(Dictionary<BfTypeVector, BfMethodInstance*>::EntryPair));
  1223. for (auto kv : *methodInstGroup.mMethodSpecializationMap)
  1224. {
  1225. methodCount++;
  1226. kv.mValue->ReportMemory(memReporter);
  1227. }
  1228. }
  1229. }
  1230. memReporter->EndSection();
  1231. memReporter->AddVec("VirtualMethodTable", mVirtualMethodTable, false);
  1232. memReporter->AddVec(mFieldInstances, false);
  1233. memReporter->AddVec(mInternalMethods, false);
  1234. memReporter->AddMap("SpecializedMethodReferences", mSpecializedMethodReferences, false);
  1235. memReporter->AddMap("LookupResults", mLookupResults, false);
  1236. if (mConstHolder != NULL)
  1237. memReporter->Add("ConstHolder", mConstHolder->mTempAlloc.GetTotalAllocSize());
  1238. if (mHotTypeData != NULL)
  1239. {
  1240. AutoMemReporter autoMemReporter(memReporter, "HotTypeData");
  1241. memReporter->Add(sizeof(BfHotTypeData));
  1242. memReporter->AddVec(mHotTypeData->mTypeVersions, false);
  1243. for (auto typeVersion : mHotTypeData->mTypeVersions)
  1244. {
  1245. memReporter->AddVec(typeVersion->mMembers, false);
  1246. memReporter->AddVec(typeVersion->mInterfaceMapping, false);
  1247. }
  1248. memReporter->AddVec(mHotTypeData->mVTableEntries, false);
  1249. for (auto& entry : mHotTypeData->mVTableEntries)
  1250. memReporter->AddStr(entry.mFuncName, false);
  1251. }
  1252. BfLog("%s\t%d\t%d\n", mContext->mScratchModule->TypeToString(this, BfTypeNameFlags_None).c_str(), IsGenericTypeInstance(), methodCount);
  1253. }
  1254. bool BfTypeInstance::IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfTypeDef* activeTypeDef)
  1255. {
  1256. if (activeTypeDef == NULL)
  1257. return false;
  1258. if (declaringTypeDef == activeTypeDef)
  1259. return true;
  1260. return activeTypeDef->mProject->ContainsReference(declaringTypeDef->mProject);
  1261. }
  1262. bool BfTypeInstance::IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfProject* curProject)
  1263. {
  1264. if (declaringTypeDef->mProject == curProject)
  1265. return true;
  1266. return curProject->ContainsReference(declaringTypeDef->mProject);
  1267. }
  1268. bool BfTypeInstance::WantsGCMarking()
  1269. {
  1270. if (IsObjectOrInterface())
  1271. return true;
  1272. if ((IsEnum()) && (!IsPayloadEnum()))
  1273. return false;
  1274. BF_ASSERT(mDefineState >= BfTypeDefineState_Defined);
  1275. return mWantsGCMarking;
  1276. }
  1277. ///
  1278. BfGenericExtensionEntry::~BfGenericExtensionEntry()
  1279. {
  1280. for (auto genericParamInstance : mGenericParams)
  1281. genericParamInstance->Release();
  1282. }
  1283. ///
  1284. BfGenericTypeInstance::~BfGenericTypeInstance()
  1285. {
  1286. for (auto genericParamInstance : mGenericParams)
  1287. genericParamInstance->Release();
  1288. delete mGenericExtensionInfo;
  1289. }
  1290. BfGenericTypeInstance::GenericParamsVector* BfGenericTypeInstance::GetGenericParamsVector(BfTypeDef* declaringTypeDef)
  1291. {
  1292. if ((declaringTypeDef == mTypeDef) ||
  1293. (declaringTypeDef->mTypeDeclaration == mTypeDef->mTypeDeclaration))
  1294. return &mGenericParams;
  1295. if (mGenericExtensionInfo == NULL)
  1296. return NULL;
  1297. BfGenericExtensionEntry* genericExEntry = NULL;
  1298. if (mGenericExtensionInfo->mExtensionMap.TryGetValue(declaringTypeDef, &genericExEntry))
  1299. return &genericExEntry->mGenericParams;
  1300. return &mGenericParams;
  1301. }
  1302. void BfGenericTypeInstance::GenerateProjectsReferenced()
  1303. {
  1304. BF_ASSERT(mProjectsReferenced.empty());
  1305. mProjectsReferenced.push_back(mTypeDef->mProject);
  1306. for (auto genericArgType : mTypeGenericArguments)
  1307. BfTypeUtils::GetProjectList(genericArgType, &mProjectsReferenced, 0);
  1308. }
  1309. bool BfGenericTypeInstance::IsSpecializedByAutoCompleteMethod()
  1310. {
  1311. for (auto methodArg : mTypeGenericArguments)
  1312. {
  1313. // If we are specialized by an autocompleted method reference
  1314. if (methodArg->IsMethodRef())
  1315. {
  1316. auto methodRefType = (BfMethodRefType*)methodArg;
  1317. if (methodRefType->mIsAutoCompleteMethod)
  1318. return true;
  1319. }
  1320. }
  1321. return false;
  1322. }
  1323. bool BfGenericTypeInstance::IsNullable()
  1324. {
  1325. return (mTypeDef == mContext->mCompiler->mNullableTypeDef);
  1326. }
  1327. bool BfGenericTypeInstance::HasVarConstraints()
  1328. {
  1329. for (auto genericParam : mGenericParams)
  1330. {
  1331. if (genericParam->mGenericParamFlags & BfGenericParamFlag_Var)
  1332. return true;
  1333. }
  1334. return false;
  1335. }
  1336. bool BfGenericTypeInstance::IsTypeMemberIncluded(BfTypeDef* typeDef, BfTypeDef* activeTypeDef, BfModule* module)
  1337. {
  1338. if (mGenericExtensionInfo == NULL)
  1339. return true;
  1340. if ((typeDef == NULL) || (typeDef == activeTypeDef))
  1341. return true;
  1342. if (typeDef->mTypeDeclaration == mTypeDef->mTypeDeclaration)
  1343. return true;
  1344. // The combined type declaration is the root type declaration, it's implicitly included
  1345. if (typeDef->mTypeDeclaration == mTypeDef->mTypeDeclaration)
  1346. return true;
  1347. BfGenericExtensionEntry* genericExEntry = NULL;
  1348. if (!mGenericExtensionInfo->mExtensionMap.TryGetValue(typeDef, &genericExEntry))
  1349. return true;
  1350. if (mIsUnspecialized)
  1351. {
  1352. if (module == NULL)
  1353. return true; // During population
  1354. auto declConstraints = &genericExEntry->mGenericParams;
  1355. for (int genericIdx = 0; genericIdx < (int)declConstraints->size(); genericIdx++)
  1356. {
  1357. auto genericType = mTypeGenericArguments[genericIdx];
  1358. auto declGenericParam = (*declConstraints)[genericIdx];
  1359. if (!module->CheckGenericConstraints(BfGenericParamSource(), genericType, NULL, declGenericParam))
  1360. return false;
  1361. //if (!mModule->AreConstraintsSubset((*declConstraints)[genericIdx], (*activeConstraints)[genericIdx]))
  1362. //isSubset = false;
  1363. }
  1364. return true;
  1365. }
  1366. /*else if ((mIsUnspecialized) && (activeTypeDef != NULL))
  1367. {
  1368. auto subsetItr = genericExEntry->mConstraintSubsetMap.find(activeTypeDef);
  1369. if (subsetItr != genericExEntry->mConstraintSubsetMap.end())
  1370. {
  1371. return subsetItr->second;
  1372. }
  1373. auto declConstraints = &genericExEntry->mGenericParams;
  1374. auto activeConstraints = GetGenericParamsVector(activeTypeDef);
  1375. bool isSubset = true;
  1376. for (int genericIdx = 0; genericIdx < (int)declConstraints->size(); genericIdx++)
  1377. {
  1378. if (!mModule->AreConstraintsSubset((*declConstraints)[genericIdx], (*activeConstraints)[genericIdx]))
  1379. isSubset = false;
  1380. }
  1381. // We can't cache this because the meaning of the params may change, IE: TypeName<@M0> needs to consider the
  1382. // constraints of @M0 for each method it is checked against
  1383. if (!IsUnspecializedTypeVariation())
  1384. genericExEntry->mConstraintSubsetMap[activeTypeDef] = isSubset;
  1385. return isSubset;
  1386. }*/
  1387. return genericExEntry->mConstraintsPassed;
  1388. }
  1389. void BfGenericTypeInstance::ReportMemory(MemReporter* memReporter)
  1390. {
  1391. BfTypeInstance::ReportMemory(memReporter);
  1392. memReporter->Add(sizeof(BfGenericTypeInstance) - sizeof(BfTypeInstance));
  1393. memReporter->AddVec(mTypeGenericArgumentRefs, false);
  1394. memReporter->AddVec(mTypeGenericArguments, false);
  1395. memReporter->AddVec(mGenericParams, false);
  1396. memReporter->AddVec(mProjectsReferenced, false);
  1397. }
  1398. BfType* BfTypeInstance::GetUnderlyingType()
  1399. {
  1400. if (!mIsTypedPrimitive)
  1401. return NULL;
  1402. auto checkTypeInst = this;
  1403. while (checkTypeInst != NULL)
  1404. {
  1405. if (!checkTypeInst->mFieldInstances.empty())
  1406. return checkTypeInst->mFieldInstances.back().mResolvedType;
  1407. checkTypeInst = checkTypeInst->mBaseType;
  1408. if (checkTypeInst->IsIncomplete())
  1409. mModule->PopulateType(checkTypeInst, BfPopulateType_Data);
  1410. }
  1411. BF_FATAL("Failed");
  1412. return NULL;
  1413. }
  1414. bool BfTypeInstance::IsValuelessType()
  1415. {
  1416. if ((mTypeDef->mTypeCode == BfTypeCode_Object) || (mTypeDef->mTypeCode == BfTypeCode_Interface))
  1417. {
  1418. return false;
  1419. }
  1420. if (mTypeDef->mIsOpaque)
  1421. return false;
  1422. BF_ASSERT(mInstSize >= 0);
  1423. if (mInstSize == 0)
  1424. {
  1425. return true;
  1426. }
  1427. return false;
  1428. }
  1429. bool BfTypeInstance::IsIRFuncUsed(BfIRFunction func)
  1430. {
  1431. for (auto& group : mMethodInstanceGroups)
  1432. {
  1433. if (group.mDefault != NULL)
  1434. if (group.mDefault->mIRFunction == func)
  1435. return true;
  1436. if (group.mMethodSpecializationMap != NULL)
  1437. {
  1438. for (auto& methodInstPair : *group.mMethodSpecializationMap)
  1439. {
  1440. auto methodInstance = methodInstPair.mValue;
  1441. if (methodInstance->mIRFunction == func)
  1442. return true;
  1443. }
  1444. }
  1445. }
  1446. return false;
  1447. }
  1448. void BfTypeInstance::CalcHotVirtualData(Array<int>* ifaceMapping)
  1449. {
  1450. if (IsIncomplete())
  1451. {
  1452. BF_ASSERT(mHotTypeData != NULL);
  1453. return;
  1454. }
  1455. if (ifaceMapping != NULL)
  1456. {
  1457. for (auto iface : mInterfaces)
  1458. {
  1459. int slotNum = iface.mInterfaceType->mSlotNum;
  1460. if (slotNum >= 0)
  1461. {
  1462. if (slotNum >= (int)ifaceMapping->size())
  1463. ifaceMapping->Resize(slotNum + 1);
  1464. (*ifaceMapping)[slotNum] = iface.mInterfaceType->mTypeId;
  1465. }
  1466. }
  1467. if (mBaseType != NULL)
  1468. mBaseType->CalcHotVirtualData(ifaceMapping);
  1469. }
  1470. }
  1471. //////////////////////////////////////////////////////////////////////////
  1472. BfClosureType::BfClosureType(BfTypeInstance* srcDelegate, Val128 closureHash) :
  1473. mSource(srcDelegate->mTypeDef->mSystem)
  1474. {
  1475. mSrcDelegate = srcDelegate;
  1476. mTypeDef = mSrcDelegate->mTypeDef;
  1477. mCreatedTypeDef = false;
  1478. mClosureHash = closureHash;
  1479. // Hash in 72 bits of closureHash (12 characters) - low does 60 bits, high does 12 bits
  1480. mNameAdd = "_" + BfTypeUtils::HashEncode64(mClosureHash.mLow) + BfTypeUtils::HashEncode64(mClosureHash.mHigh >> 52);
  1481. mIsUnique = false;
  1482. }
  1483. BfClosureType::~BfClosureType()
  1484. {
  1485. if (mCreatedTypeDef)
  1486. delete mTypeDef;
  1487. for (auto directAllocNode : mDirectAllocNodes)
  1488. delete directAllocNode;
  1489. }
  1490. void BfClosureType::Init(BfProject* bfProject)
  1491. {
  1492. auto srcTypeDef = mSrcDelegate->mTypeDef;
  1493. auto system = mSrcDelegate->mModule->mSystem;
  1494. mTypeDef = new BfTypeDef();
  1495. mTypeDef->mSystem = system;
  1496. mTypeDef->mSource = &mSource;
  1497. mTypeDef->mSource->mRefCount++;
  1498. mTypeDef->mProject = bfProject;
  1499. mTypeDef->mTypeCode = srcTypeDef->mTypeCode;
  1500. mTypeDef->mName = system->GetAtom(srcTypeDef->mName->mString + mNameAdd);
  1501. mTypeDef->mOuterType = srcTypeDef->mOuterType;
  1502. mTypeDef->mNamespace = srcTypeDef->mNamespace;
  1503. system->AddNamespaceUsage(mTypeDef->mNamespace, mTypeDef->mProject);
  1504. mTypeDef->mHash = srcTypeDef->mHash;
  1505. mTypeDef->mSignatureHash = srcTypeDef->mSignatureHash;
  1506. // mTypeDef->mFullName = srcTypeDef->mFullName;
  1507. // if (!mTypeDef->mFullName.mParts.IsEmpty())
  1508. // mTypeDef->mFullName.mParts.pop_back();
  1509. // mTypeDef->mFullName.mParts.push_back(mTypeDef->mName);
  1510. if (srcTypeDef->mFullName.mSize > 0)
  1511. mTypeDef->mFullName.Set(srcTypeDef->mFullName.mParts, srcTypeDef->mFullName.mSize - 1, &mTypeDef->mName, 1);
  1512. else
  1513. mTypeDef->mFullName.Set(&mTypeDef->mName, 1, NULL, 0);
  1514. system->TrackName(mTypeDef);
  1515. mTypeDef->mTypeCode = BfTypeCode_Object;
  1516. mTypeDef->mIsDelegate = true;
  1517. mTypeDef->mIsClosure = true;
  1518. mTypeDef->mDefState = BfTypeDef::DefState_Defined;
  1519. auto baseDirectTypeRef = BfAstNode::ZeroedAlloc<BfDirectTypeReference>();
  1520. baseDirectTypeRef->Init(mSrcDelegate);
  1521. mDirectAllocNodes.push_back(baseDirectTypeRef);
  1522. mTypeDef->mBaseTypes.push_back(baseDirectTypeRef);
  1523. //mTypeDef->mBaseTypes.push_back(BfDefBuilder::AllocTypeReference(&mSource, mSrcDelegate));
  1524. mCreatedTypeDef = true;
  1525. //mTypeDef->mBaseTypes.push_back(srcTypeDef);
  1526. }
  1527. BfFieldDef* BfClosureType::AddField(BfType* type, const StringImpl& name)
  1528. {
  1529. auto directTypeRef = BfAstNode::ZeroedAlloc<BfDirectTypeReference>();
  1530. directTypeRef->Init(type);
  1531. mDirectAllocNodes.push_back(directTypeRef);
  1532. return BfDefBuilder::AddField(mTypeDef, directTypeRef, name);
  1533. }
  1534. BfMethodDef* BfClosureType::AddDtor()
  1535. {
  1536. return BfDefBuilder::AddDtor(mTypeDef);
  1537. }
  1538. void BfClosureType::Finish()
  1539. {
  1540. HASH128_MIXIN(mTypeDef->mSignatureHash, mClosureHash);
  1541. auto bfSource = mTypeDef->mSource;
  1542. auto bfSystem = bfSource->mSystem;
  1543. BfDefBuilder bfDefBuilder(bfSystem);
  1544. bfDefBuilder.mCurTypeDef = mTypeDef;
  1545. bfDefBuilder.FinishTypeDef(false);
  1546. }
  1547. //////////////////////////////////////////////////////////////////////////
  1548. BfDelegateType::~BfDelegateType()
  1549. {
  1550. delete mTypeDef;
  1551. for (auto directAllocNode : mDirectAllocNodes)
  1552. delete directAllocNode;
  1553. }
  1554. //////////////////////////////////////////////////////////////////////////
  1555. BfTupleType::BfTupleType()
  1556. {
  1557. mCreatedTypeDef = false;
  1558. mSource = NULL;
  1559. mTypeDef = NULL;
  1560. mHasUnspecializedMembers = false;
  1561. }
  1562. BfTupleType::~BfTupleType()
  1563. {
  1564. if (mCreatedTypeDef)
  1565. delete mTypeDef;
  1566. delete mSource;
  1567. }
  1568. void BfTupleType::Init(BfProject* bfProject, BfTypeInstance* valueTypeInstance)
  1569. {
  1570. auto srcTypeDef = valueTypeInstance->mTypeDef;
  1571. auto system = valueTypeInstance->mModule->mSystem;
  1572. if (mTypeDef == NULL)
  1573. mTypeDef = new BfTypeDef();
  1574. for (auto field : mTypeDef->mFields)
  1575. delete field;
  1576. mTypeDef->mFields.Clear();
  1577. mTypeDef->mSystem = system;
  1578. mTypeDef->mProject = bfProject;
  1579. mTypeDef->mTypeCode = srcTypeDef->mTypeCode;
  1580. mTypeDef->mName = system->mEmptyAtom;
  1581. mTypeDef->mSystem = system;
  1582. mTypeDef->mHash = srcTypeDef->mHash;
  1583. mTypeDef->mSignatureHash = srcTypeDef->mSignatureHash;
  1584. mTypeDef->mTypeCode = BfTypeCode_Struct;
  1585. mCreatedTypeDef = true;
  1586. }
  1587. BfFieldDef* BfTupleType::AddField(const StringImpl& name)
  1588. {
  1589. return BfDefBuilder::AddField(mTypeDef, NULL, name);
  1590. }
  1591. void BfTupleType::Finish()
  1592. {
  1593. auto bfSystem = mTypeDef->mSystem;
  1594. mSource = new BfSource(bfSystem);
  1595. mTypeDef->mSource = mSource;
  1596. mTypeDef->mSource->mRefCount++;
  1597. BfDefBuilder bfDefBuilder(bfSystem);
  1598. bfDefBuilder.mCurTypeDef = mTypeDef;
  1599. bfDefBuilder.FinishTypeDef(true);
  1600. mHasUnspecializedMembers = false;
  1601. }
  1602. //////////////////////////////////////////////////////////////////////////
  1603. int BfArrayType::GetLengthBitCount()
  1604. {
  1605. if (mBaseType == NULL)
  1606. mModule->PopulateType(mBaseType, BfPopulateType_BaseType);
  1607. mModule->PopulateType(mBaseType);
  1608. if ((mBaseType->mFieldInstances.size() == 0) || (mBaseType->mFieldInstances[0].GetFieldDef()->mName != "mLength"))
  1609. {
  1610. return 0;
  1611. }
  1612. return mBaseType->mFieldInstances[0].mResolvedType->mSize * 8;
  1613. }
  1614. //////////////////////////////////////////////////////////////////////////
  1615. int BfMethodRefType::GetCaptureDataCount()
  1616. {
  1617. return (int)mDataToParamIdx.size();
  1618. }
  1619. BfType* BfMethodRefType::GetCaptureType(int captureDataIdx)
  1620. {
  1621. return mMethodRef->GetParamType(mDataToParamIdx[captureDataIdx]);
  1622. }
  1623. int BfMethodRefType::GetDataIdxFromParamIdx(int paramIdx)
  1624. {
  1625. if (paramIdx == -1)
  1626. {
  1627. if (mMethodRef->HasThis())
  1628. return 0;
  1629. return -1;
  1630. }
  1631. return mParamToDataIdx[paramIdx];
  1632. }
  1633. int BfMethodRefType::GetParamIdxFromDataIdx(int dataIdx)
  1634. {
  1635. return mDataToParamIdx[dataIdx];
  1636. }
  1637. bool BfMethodRefType::WantsDataPassedAsSplat(int dataIdx)
  1638. {
  1639. if (dataIdx != -1)
  1640. return false;
  1641. return mMethodRef->GetParamIsSplat(mDataToParamIdx[dataIdx]);
  1642. }
  1643. //////////////////////////////////////////////////////////////////////////
  1644. size_t BfTypeVectorHash::operator()(const BfTypeVector& typeVec) const
  1645. {
  1646. size_t hash = typeVec.size();
  1647. BfResolvedTypeSet::LookupContext ctx;
  1648. for (auto type : typeVec)
  1649. hash = ((hash ^ BfResolvedTypeSet::Hash(type, &ctx)) << 5) - hash;
  1650. return hash;
  1651. }
  1652. bool BfTypeVectorEquals::operator()(const BfTypeVector& lhs, const BfTypeVector& rhs) const
  1653. {
  1654. if (lhs.size() != rhs.size())
  1655. return false;
  1656. for (int i = 0; i < (int)lhs.size(); i++)
  1657. if (lhs[i] != rhs[i])
  1658. return false;
  1659. return true;
  1660. }
  1661. //////////////////////////////////////////////////////////////////////////
  1662. bool BfCustomAttributes::Contains(BfTypeDef* typeDef)
  1663. {
  1664. for (auto& customAttr : mAttributes)
  1665. if (customAttr.mType->mTypeDef == typeDef)
  1666. return true;
  1667. return false;
  1668. }
  1669. BfCustomAttribute* BfCustomAttributes::Get(BfTypeDef * typeDef)
  1670. {
  1671. for (auto& customAttr : mAttributes)
  1672. if (customAttr.mType->mTypeDef == typeDef)
  1673. return &customAttr;
  1674. return NULL;
  1675. }
  1676. //////////////////////////////////////////////////////////////////////////
  1677. BfResolvedTypeSet::~BfResolvedTypeSet()
  1678. {
  1679. }
  1680. #define HASH_VAL_PTR 1
  1681. #define HASH_VAL_BOXED 2
  1682. #define HASH_VAL_REF 3
  1683. #define HASH_VAL_OUT 4
  1684. #define HASH_VAL_MUT 5
  1685. #define HASH_RETTYPE 6
  1686. #define HASH_CONCRETE_INTERFACE 7
  1687. #define HASH_SIZED_ARRAY 8
  1688. #define HASH_CONSTTYPE 9
  1689. #define HASH_VAL_TUPLE 10
  1690. #define HASH_DELEGATE 11
  1691. #define HASH_CONSTEXPR 12
  1692. #define HASH_GLOBAL 13
  1693. BfVariant BfResolvedTypeSet::EvaluateToVariant(LookupContext* ctx, BfExpression* expr, BfType*& constGenericParam)
  1694. {
  1695. BfConstResolver constResolver(ctx->mModule);
  1696. BfVariant variant = { BfTypeCode_None };
  1697. constResolver.Evaluate(expr);
  1698. if (constResolver.mResult)
  1699. {
  1700. auto result = constResolver.mResult;
  1701. if (result.mKind == BfTypedValueKind_GenericConstValue)
  1702. {
  1703. constGenericParam = result.mType;
  1704. return variant;
  1705. }
  1706. else
  1707. {
  1708. variant = ctx->mModule->TypedValueToVariant(expr, result, true);
  1709. // Limit the types of constants to prevent duplicate values with different types - we don't want to hash a typeref with an int32
  1710. // when the constraint requirement is int64 (but we don't know that at hash time)
  1711. if (BfIRConstHolder::IsInt(variant.mTypeCode))
  1712. variant.mTypeCode = BfTypeCode_Int64;
  1713. else if (variant.mTypeCode == BfTypeCode_Single)
  1714. {
  1715. variant.mTypeCode = BfTypeCode_Double;
  1716. variant.mDouble = variant.mSingle;
  1717. }
  1718. }
  1719. }
  1720. return variant;
  1721. }
  1722. int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef)
  1723. {
  1724. //BP_ZONE("BfResolvedTypeSet::Hash");
  1725. if (type->IsBoxed())
  1726. {
  1727. BfBoxedType* boxedType = (BfBoxedType*)type;
  1728. int elemHash = Hash(boxedType->mElementType, ctx) ^ HASH_VAL_BOXED;
  1729. return (elemHash << 5) - elemHash;
  1730. }
  1731. else if (type->IsArray())
  1732. {
  1733. BfArrayType* arrayType = (BfArrayType*)type;
  1734. int elemHash = Hash(arrayType->mTypeGenericArguments[0], ctx) ^ (arrayType->mDimensions << 8);
  1735. return (elemHash << 5) - elemHash;
  1736. }
  1737. else if (type->IsDelegateFromTypeRef() || type->IsFunctionFromTypeRef())
  1738. {
  1739. int hashVal = HASH_DELEGATE;
  1740. BfMethodInstance* invokeMethodInstance = ctx->mModule->GetRawMethodInstanceAtIdx(type->ToTypeInstance(), 0, "Invoke");
  1741. hashVal = ((hashVal ^ (Hash(invokeMethodInstance->mReturnType, ctx))) << 5) - hashVal;
  1742. for (int paramIdx = 0; paramIdx < invokeMethodInstance->mParams.size(); paramIdx++)
  1743. {
  1744. // Parse attributes?
  1745. hashVal = ((hashVal ^ (Hash(invokeMethodInstance->GetParamType(paramIdx), ctx))) << 5) - hashVal;
  1746. String paramName = invokeMethodInstance->GetParamName(paramIdx);
  1747. int nameHash = (int)Hash64(paramName.c_str(), (int)paramName.length());
  1748. hashVal = ((hashVal ^ (nameHash)) << 5) - hashVal;
  1749. }
  1750. return hashVal;
  1751. }
  1752. else if (type->IsTypeInstance())
  1753. {
  1754. BfTypeInstance* typeInst = (BfTypeInstance*)type;
  1755. int hashVal;
  1756. if (typeInst->mTypeDef != NULL)
  1757. hashVal = typeInst->mTypeDef->mHash;
  1758. if (type->IsClosure())
  1759. {
  1760. auto closureType = (BfClosureType*)type;
  1761. if (closureType->mIsUnique)
  1762. return false;
  1763. hashVal = ((hashVal ^ (int)closureType->mClosureHash.mLow) << 5) - hashVal;
  1764. }
  1765. else if (type->IsGenericTypeInstance())
  1766. {
  1767. BfGenericTypeInstance* genericType = (BfGenericTypeInstance*)type;
  1768. for (auto genericArg : genericType->mTypeGenericArguments)
  1769. hashVal = ((hashVal ^ (Hash(genericArg, ctx))) << 5) - hashVal;
  1770. }
  1771. else if (type->IsTuple())
  1772. {
  1773. hashVal = HASH_VAL_TUPLE;
  1774. BfTupleType* tupleType = (BfTupleType*)type;
  1775. for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
  1776. {
  1777. BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx];
  1778. auto fieldType = fieldInstance->mResolvedType;
  1779. hashVal = ((hashVal ^ (Hash(fieldType, ctx))) << 5) - hashVal;
  1780. BfFieldDef* fieldDef = NULL;
  1781. if (tupleType->mTypeDef != NULL)
  1782. fieldDef = fieldInstance->GetFieldDef();
  1783. int nameHash = 0;
  1784. if (fieldDef == NULL)
  1785. {
  1786. char nameStr[64];
  1787. sprintf(nameStr, "%d", fieldIdx);
  1788. nameHash = (int)Hash64(nameStr, strlen(nameStr));
  1789. }
  1790. else
  1791. {
  1792. nameHash = (int)Hash64(fieldDef->mName.c_str(), (int)fieldDef->mName.length());
  1793. }
  1794. hashVal = ((hashVal ^ (nameHash)) << 5) - hashVal;
  1795. }
  1796. }
  1797. return hashVal;
  1798. }
  1799. else if (type->IsPrimitiveType())
  1800. {
  1801. BfPrimitiveType* primType = (BfPrimitiveType*)type;
  1802. return primType->mTypeDef->mHash;
  1803. }
  1804. else if (type->IsPointer())
  1805. {
  1806. BfPointerType* pointerType = (BfPointerType*) type;
  1807. int elemHash = Hash(pointerType->mElementType, ctx) ^ HASH_VAL_PTR;
  1808. return (elemHash << 5) - elemHash;
  1809. }
  1810. else if (type->IsGenericParam())
  1811. {
  1812. auto genericParam = (BfGenericParamType*)type;
  1813. return (((int)genericParam->mGenericParamKind + 0xB00) << 8) ^ (genericParam->mGenericParamIdx + 1);
  1814. }
  1815. else if (type->IsRef())
  1816. {
  1817. auto refType = (BfRefType*)type;
  1818. int elemHash = Hash(refType->mElementType, ctx) ^ (HASH_VAL_REF + (int)refType->mRefKind);
  1819. return (elemHash << 5) - elemHash;
  1820. }
  1821. else if (type->IsRetTypeType())
  1822. {
  1823. auto retTypeType = (BfRetTypeType*)type;
  1824. int elemHash = Hash(retTypeType->mElementType, ctx) ^ HASH_RETTYPE;
  1825. return (elemHash << 5) - elemHash;
  1826. }
  1827. else if (type->IsConcreteInterfaceType())
  1828. {
  1829. auto concreteInterfaceType = (BfConcreteInterfaceType*)type;
  1830. int elemHash = Hash(concreteInterfaceType->mInterface, ctx) ^ HASH_CONCRETE_INTERFACE;
  1831. return (elemHash << 5) - elemHash;
  1832. }
  1833. else if (type->IsSizedArray())
  1834. {
  1835. auto sizedArray = (BfSizedArrayType*)type;
  1836. int elemHash = Hash(sizedArray->mElementType, ctx) ^ HASH_SIZED_ARRAY;
  1837. int hashVal = (elemHash << 5) - elemHash;
  1838. if (type->IsUnknownSizedArray())
  1839. {
  1840. auto unknownSizedArray = (BfUnknownSizedArrayType*)type;
  1841. int elemHash = Hash(unknownSizedArray->mElementCountSource, ctx);
  1842. hashVal = ((hashVal ^ elemHash) << 5) - hashVal;
  1843. }
  1844. else
  1845. hashVal = ((hashVal ^ (int)sizedArray->mElementCount) << 5) - hashVal;
  1846. return hashVal;
  1847. }
  1848. else if (type->IsMethodRef())
  1849. {
  1850. auto methodRefType = (BfMethodRefType*)type;
  1851. if (methodRefType->IsNull())
  1852. return 0;
  1853. return (int)((int)(intptr)(methodRefType->mMethodRef) << 5) ^ (int)(intptr)(methodRefType->mOwner) ^ methodRefType->mOwnerRevision;
  1854. }
  1855. else if (type->IsConstExprValue())
  1856. {
  1857. BfConstExprValueType* constExprValueType = (BfConstExprValueType*)type;
  1858. int hashVal = ((int)constExprValueType->mValue.mTypeCode << 17) ^ (constExprValueType->mValue.mInt32 << 3) ^ HASH_CONSTTYPE;
  1859. int elemHash = Hash(constExprValueType->mType, ctx);
  1860. hashVal = ((hashVal ^ elemHash) << 5) - hashVal;
  1861. return hashVal;
  1862. }
  1863. else
  1864. {
  1865. BF_FATAL("Not handled");
  1866. }
  1867. return 0;
  1868. }
  1869. void BfResolvedTypeSet::HashGenericArguments(BfTypeReference* typeRef, LookupContext* ctx, int& hashVal)
  1870. {
  1871. if (auto elementedTypeRef = BfNodeDynCast<BfElementedTypeRef>(typeRef))
  1872. {
  1873. HashGenericArguments(elementedTypeRef->mElementType, ctx, hashVal);
  1874. }
  1875. else if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(typeRef))
  1876. {
  1877. HashGenericArguments(qualifiedTypeRef->mLeft, ctx, hashVal);
  1878. }
  1879. if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef))
  1880. {
  1881. for (auto genericArg : genericTypeRef->mGenericArguments)
  1882. hashVal = ((hashVal ^ (Hash(genericArg, ctx, BfHashFlag_AllowGenericParamConstValue))) << 5) - hashVal;
  1883. }
  1884. }
  1885. static int HashNode(BfAstNode* node)
  1886. {
  1887. if (node == NULL)
  1888. return (int)Hash64(NULL, 0);
  1889. const char* nameStr = node->GetSourceData()->mSrc + node->GetSrcStart();
  1890. return (int)Hash64(nameStr, node->GetSrcLength());
  1891. }
  1892. int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags)
  1893. {
  1894. // if (auto typeDefTypeRef = BfNodeDynCast<BfTypeDefTypeReference>(typeRef))
  1895. // {
  1896. // if (typeDefTypeRef->mTypeDef != NULL)
  1897. // {
  1898. // int hashVal = typeDefTypeRef->mTypeDef->mHash;
  1899. //
  1900. // if (typeDefTypeRef->mTypeDef->mGenericParamDefs.size() != 0)
  1901. // {
  1902. // auto checkTypeInstance = ctx->mModule->mCurTypeInstance;
  1903. // if (checkTypeInstance->IsBoxed())
  1904. // checkTypeInstance = checkTypeInstance->GetUnderlyingType()->ToTypeInstance();
  1905. //
  1906. // //if (!module->TypeHasParent(module->mCurTypeInstance->mTypeDef, typeDefTypeRef->mTypeDef->mParentType))
  1907. // auto outerType = ctx->mModule->mSystem->GetOuterTypeNonPartial(typeDefTypeRef->mTypeDef);
  1908. // BfTypeDef* commonOuterType = ctx->mModule->FindCommonOuterType(ctx->mModule->mCurTypeInstance->mTypeDef, outerType);
  1909. // //BfTypeDef* commonOuterType = ctx->mModule->FindCommonOuterType(ctx->mModule->GetActiveTypeDef(), typeDefTypeRef->mTypeDef->mOuterType);
  1910. // if ((commonOuterType == NULL) || (commonOuterType->mGenericParamDefs.size() == 0))
  1911. // {
  1912. // ctx->mModule->Fail("Generic arguments expected", typeDefTypeRef);
  1913. // ctx->mFailed = true;
  1914. // return 0;
  1915. // }
  1916. //
  1917. // BF_ASSERT(checkTypeInstance->IsGenericTypeInstance());
  1918. // auto curGenericTypeInst = (BfGenericTypeInstance*)checkTypeInstance;
  1919. // //int numParentGenericParams = (int)typeDefTypeRef->mTypeDef->mGenericParams.size();
  1920. // int numParentGenericParams = (int)commonOuterType->mGenericParamDefs.size();
  1921. // for (int i = 0; i < numParentGenericParams; i++)
  1922. // {
  1923. // hashVal = ((hashVal ^ (Hash(curGenericTypeInst->mTypeGenericArguments[i], ctx))) << 5) - hashVal;
  1924. // }
  1925. // }
  1926. //
  1927. // return hashVal;
  1928. // }
  1929. //
  1930. // bool isHeadType = typeRef == ctx->mRootTypeRef;
  1931. //
  1932. // BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None;
  1933. // if ((flags & BfHashFlag_AllowGenericParamConstValue) != 0)
  1934. // resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_AllowGenericParamConstValue);
  1935. //
  1936. // auto resolvedType = ctx->mModule->ResolveTypeRef(typeRef, BfPopulateType_Identity, resolveFlags);
  1937. // if (resolvedType == NULL)
  1938. // {
  1939. // ctx->mFailed = true;
  1940. // return 0;
  1941. // }
  1942. // return Hash(resolvedType, ctx);
  1943. // }
  1944. if ((typeRef == ctx->mRootTypeRef) && (ctx->mRootTypeDef != NULL))
  1945. {
  1946. BfTypeDef* typeDef = ctx->mRootTypeDef;
  1947. int hashVal = typeDef->mHash;
  1948. if (typeDef->mGenericParamDefs.size() != 0)
  1949. {
  1950. auto checkTypeInstance = ctx->mModule->mCurTypeInstance;
  1951. if (checkTypeInstance->IsBoxed())
  1952. checkTypeInstance = checkTypeInstance->GetUnderlyingType()->ToTypeInstance();
  1953. auto outerType = ctx->mModule->mSystem->GetOuterTypeNonPartial(typeDef);
  1954. BfTypeDef* commonOuterType = ctx->mModule->FindCommonOuterType(ctx->mModule->mCurTypeInstance->mTypeDef, outerType);
  1955. if ((commonOuterType == NULL) || (commonOuterType->mGenericParamDefs.size() == 0))
  1956. {
  1957. ctx->mModule->Fail("Generic arguments expected", typeRef);
  1958. ctx->mFailed = true;
  1959. return 0;
  1960. }
  1961. BF_ASSERT(checkTypeInstance->IsGenericTypeInstance());
  1962. auto curGenericTypeInst = (BfGenericTypeInstance*)checkTypeInstance;
  1963. int numParentGenericParams = (int)commonOuterType->mGenericParamDefs.size();
  1964. for (int i = 0; i < numParentGenericParams; i++)
  1965. {
  1966. hashVal = ((hashVal ^ (Hash(curGenericTypeInst->mTypeGenericArguments[i], ctx))) << 5) - hashVal;
  1967. }
  1968. }
  1969. return hashVal;
  1970. }
  1971. if (typeRef->IsNamedTypeReference())
  1972. {
  1973. bool isHeadType = typeRef == ctx->mRootTypeRef;
  1974. BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None;
  1975. if ((flags & BfHashFlag_AllowGenericParamConstValue) != 0)
  1976. resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_AllowGenericParamConstValue);
  1977. auto resolvedType = ctx->mModule->ResolveTypeRef(typeRef, BfPopulateType_Identity, resolveFlags);
  1978. if (resolvedType == NULL)
  1979. {
  1980. ctx->mFailed = true;
  1981. return 0;
  1982. }
  1983. return Hash(resolvedType, ctx);
  1984. }
  1985. else if (auto genericInstTypeRef = BfNodeDynCastExact<BfGenericInstanceTypeRef>(typeRef))
  1986. {
  1987. //BfType* type = NULL;
  1988. BfTypeDef* elementTypeDef = ctx->mModule->ResolveGenericInstanceDef(genericInstTypeRef);
  1989. int hashVal;
  1990. /*if (type != NULL)
  1991. {
  1992. hashVal = Hash(type, ctx);
  1993. }
  1994. else */
  1995. {
  1996. if (elementTypeDef == NULL)
  1997. {
  1998. ctx->mFailed = true;
  1999. return 0;
  2000. }
  2001. if (ctx->mRootTypeRef == typeRef)
  2002. {
  2003. BF_ASSERT((ctx->mRootTypeDef == NULL) || (ctx->mRootTypeDef == elementTypeDef));
  2004. ctx->mRootTypeDef = elementTypeDef;
  2005. }
  2006. hashVal = elementTypeDef->mHash;
  2007. }
  2008. // Do we need to add generic arguments from an in-context outer class?
  2009. if ((elementTypeDef->mOuterType != NULL) && (ctx->mModule->mCurTypeInstance != NULL) && (ctx->mModule->mCurTypeInstance->IsGenericTypeInstance()))
  2010. {
  2011. BfTypeDef* commonOuterType = ctx->mModule->FindCommonOuterType(ctx->mModule->mCurTypeInstance->mTypeDef, elementTypeDef->mOuterType);
  2012. if (commonOuterType != NULL)
  2013. {
  2014. auto parentTypeInstance = (BfGenericTypeInstance*)ctx->mModule->mCurTypeInstance;
  2015. int numParentGenericParams = (int)commonOuterType->mGenericParamDefs.size();
  2016. for (int i = 0; i < numParentGenericParams; i++)
  2017. hashVal = ((hashVal ^ (Hash(parentTypeInstance->mTypeGenericArguments[i], ctx))) << 5) - hashVal;
  2018. }
  2019. }
  2020. HashGenericArguments(genericInstTypeRef, ctx, hashVal);
  2021. /*for (auto genericArg : genericInstTypeRef->mGenericArguments)
  2022. hashVal = ((hashVal ^ (Hash(genericArg, ctx))) << 5) - hashVal;*/
  2023. return hashVal;
  2024. }
  2025. else if (auto tupleTypeRef = BfNodeDynCastExact<BfTupleTypeRef>(typeRef))
  2026. {
  2027. int hashVal = HASH_VAL_TUPLE;
  2028. for (int fieldIdx = 0; fieldIdx < (int)tupleTypeRef->mFieldTypes.size(); fieldIdx++)
  2029. {
  2030. BfTypeReference* fieldType = tupleTypeRef->mFieldTypes[fieldIdx];
  2031. hashVal = ((hashVal ^ (Hash(fieldType, ctx))) << 5) - hashVal;
  2032. int nameHash = 0;
  2033. BfIdentifierNode* fieldName = NULL;
  2034. if (fieldIdx < (int)tupleTypeRef->mFieldNames.size())
  2035. fieldName = tupleTypeRef->mFieldNames[fieldIdx];
  2036. if (fieldName != NULL)
  2037. {
  2038. const char* nameStr = fieldName->GetSourceData()->mSrc + fieldName->GetSrcStart();
  2039. nameHash = (int)Hash64(nameStr, fieldName->GetSrcLength());
  2040. }
  2041. else
  2042. {
  2043. char nameStr[64];
  2044. sprintf(nameStr, "%d", fieldIdx);
  2045. nameHash = (int)Hash64(nameStr, strlen(nameStr));
  2046. }
  2047. hashVal = ((hashVal ^ (nameHash)) << 5) - hashVal;
  2048. }
  2049. return hashVal;
  2050. }
  2051. else if (auto arrayType = BfNodeDynCastExact<BfArrayTypeRef>(typeRef))
  2052. {
  2053. if ((arrayType->mDimensions == 1) && (arrayType->mParams.size() != 0))
  2054. {
  2055. int elemHash = Hash(arrayType->mElementType, ctx) ^ HASH_SIZED_ARRAY;
  2056. int hashVal = (elemHash << 5) - elemHash;
  2057. // Sized array
  2058. if (arrayType->mParams.size() != 1)
  2059. {
  2060. ctx->mFailed = true;
  2061. ctx->mModule->Fail("Only one size parameter expected", arrayType->mParams[1]);
  2062. return 0;
  2063. }
  2064. intptr elementCount = -1;
  2065. BfExpression* sizeExpr = BfNodeDynCast<BfExpression>(arrayType->mParams[0]);
  2066. BF_ASSERT(sizeExpr != NULL);
  2067. if (sizeExpr != NULL)
  2068. {
  2069. BfConstResolver constResolver(ctx->mModule);
  2070. BfType* intType = ctx->mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  2071. constResolver.mAllowGenericConstValue = true;
  2072. constResolver.mExpectingType = intType;
  2073. BfTypedValue typedVal = constResolver.Resolve(sizeExpr);
  2074. if (typedVal.mKind == BfTypedValueKind_GenericConstValue)
  2075. {
  2076. int elemHash = Hash(typedVal.mType, ctx);
  2077. /*BF_ASSERT(typedVal.mType->IsGenericParam());
  2078. auto genericParamInstance = ctx->mModule->GetGenericParamInstance((BfGenericParamType*)typedVal.mType);
  2079. if ((genericParamInstance->mTypeConstraint == NULL) ||
  2080. (!ctx->mModule->CanImplicitlyCast(BfTypedValue(ctx->mModule->mBfIRBuilder->GetFakeVal(), genericParamInstance->mTypeConstraint),
  2081. ctx->mModule->GetPrimitiveType(BfTypeCode_IntPtr))))
  2082. {
  2083. ctx->mModule->Fail(StrFormat("Generic constraint '%s' is not convertible to 'int'", ctx->mModule->TypeToString(typedVal.mType).c_str()), sizeExpr);
  2084. }*/
  2085. hashVal = ((hashVal ^ elemHash) << 5) - hashVal;
  2086. return hashVal;
  2087. }
  2088. if (!typedVal)
  2089. ctx->mFailed = true;
  2090. if (typedVal)
  2091. typedVal = ctx->mModule->Cast(sizeExpr, typedVal, intType);
  2092. if (typedVal)
  2093. {
  2094. auto constant = ctx->mModule->mBfIRBuilder->GetConstant(typedVal.mValue);
  2095. if (constant->mConstType == BfConstType_Undef)
  2096. {
  2097. elementCount = -1; // Marker for undef
  2098. }
  2099. else
  2100. {
  2101. BF_ASSERT(BfIRBuilder::IsInt(constant->mTypeCode));
  2102. elementCount = (intptr)constant->mInt64;
  2103. if (elementCount < 0)
  2104. {
  2105. ctx->mFailed = true;
  2106. ctx->mModule->Fail("Arrays cannot have negative sizes", arrayType->mParams[0]);
  2107. return 0;
  2108. }
  2109. }
  2110. }
  2111. }
  2112. hashVal = ((hashVal ^ (int)elementCount) << 5) - hashVal;
  2113. return hashVal;
  2114. }
  2115. else
  2116. {
  2117. if (arrayType->mDimensions != (int)arrayType->mParams.size() + 1)
  2118. {
  2119. for (auto arg : arrayType->mParams)
  2120. {
  2121. if (auto tokenNode = BfNodeDynCastExact<BfTokenNode>(arg))
  2122. {
  2123. if (tokenNode->GetToken() == BfToken_Comma)
  2124. continue;
  2125. }
  2126. ctx->mFailed = true;
  2127. ctx->mModule->Fail("Multidimensional arrays cannot have explicit sizes. Consider using a strided array (ie: int[2][2]) instead.", arg);
  2128. return 0;
  2129. }
  2130. }
  2131. int elemHash = Hash(arrayType->mElementType, ctx) ^ (arrayType->mDimensions << 8);
  2132. return (elemHash << 5) - elemHash;
  2133. }
  2134. }
  2135. else if (auto pointerType = BfNodeDynCastExact<BfPointerTypeRef>(typeRef))
  2136. {
  2137. int elemHash = Hash(pointerType->mElementType, ctx) ^ HASH_VAL_PTR;
  2138. return (elemHash << 5) - elemHash;
  2139. }
  2140. else if (auto nullableType = BfNodeDynCastExact<BfNullableTypeRef>(typeRef))
  2141. {
  2142. if (ctx->mRootTypeRef == typeRef)
  2143. ctx->mRootTypeDef = ctx->mModule->mCompiler->mNullableTypeDef;
  2144. int hashVal = ctx->mModule->mCompiler->mNullableTypeDef->mHash;
  2145. hashVal = ((hashVal ^ (Hash(nullableType->mElementType, ctx))) << 5) - hashVal;
  2146. return hashVal;
  2147. }
  2148. else if (auto boxedType = BfNodeDynCastExact<BfBoxedTypeRef>(typeRef))
  2149. {
  2150. int elemHash = Hash(boxedType->mElementType, ctx) ^ HASH_VAL_BOXED;
  2151. return (elemHash << 5) - elemHash;
  2152. }
  2153. else if (auto refType = BfNodeDynCastExact<BfRefTypeRef>(typeRef))
  2154. {
  2155. if ((flags & BfHashFlag_AllowRef) != 0)
  2156. {
  2157. auto refKind = BfRefType::RefKind_Ref;
  2158. if (refType->mRefToken == NULL)
  2159. refKind = BfRefType::RefKind_Ref;
  2160. else if (refType->mRefToken->GetToken() == BfToken_Out)
  2161. refKind = BfRefType::RefKind_Out;
  2162. else if (refType->mRefToken->GetToken() == BfToken_Mut)
  2163. refKind = BfRefType::RefKind_Mut;
  2164. int elemHash = Hash(refType->mElementType, ctx) ^ (HASH_VAL_REF + (int)refKind);
  2165. return (elemHash << 5) - elemHash;
  2166. }
  2167. else
  2168. {
  2169. ctx->mModule->ResolveTypeRef(typeRef); // To throw an error...
  2170. ctx->mFailed = true;
  2171. return 0;
  2172. //return Hash(refType->mElementType, ctx);
  2173. }
  2174. }
  2175. else if (auto genericParamTypeRef = BfNodeDynCastExact<BfGenericParamTypeRef>(typeRef))
  2176. {
  2177. return (((int)genericParamTypeRef->mGenericParamKind) << 8) ^ (genericParamTypeRef->mGenericParamIdx + 1);
  2178. }
  2179. else if (auto qualifiedTypeRef = BfNodeDynCastExact<BfQualifiedTypeReference>(typeRef))
  2180. {
  2181. /*auto leftType = ctx->mModule->ResolveTypeRef(qualifiedTypeRef->mLeft, BfPopulateType_Identity);
  2182. if (leftType == NULL)
  2183. {
  2184. ctx->mFailed = true;
  2185. return 0;
  2186. }
  2187. if (qualifiedTypeRef->mRight == NULL)
  2188. {
  2189. ctx->mFailed = true;
  2190. return 0;
  2191. }
  2192. auto rightType = ctx->mModule->ResolveInnerType(leftType, qualifiedTypeRef->mRight);
  2193. if (rightType == NULL)
  2194. {
  2195. ctx->mFailed = true;
  2196. return 0;
  2197. }
  2198. return Hash(rightType, ctx);*/
  2199. auto resolvedType = ctx->mModule->ResolveTypeRef(typeRef, BfPopulateType_Identity);
  2200. if (resolvedType == NULL)
  2201. {
  2202. ctx->mFailed = true;
  2203. return 0;
  2204. }
  2205. return Hash(resolvedType, ctx);
  2206. }
  2207. else if (auto varType = BfNodeDynCastExact<BfVarTypeReference>(typeRef))
  2208. {
  2209. // Don't allow 'var'
  2210. //*failed = true;
  2211. auto primType = ctx->mModule->GetPrimitiveType(BfTypeCode_Var);
  2212. return Hash(primType, ctx);
  2213. }
  2214. else if (auto letType = BfNodeDynCastExact<BfLetTypeReference>(typeRef))
  2215. {
  2216. // Don't allow 'let'
  2217. ctx->mFailed = true;
  2218. auto primType = ctx->mModule->GetPrimitiveType(BfTypeCode_Let);
  2219. return Hash(primType, ctx);
  2220. }
  2221. else if (auto retTypeTypeRef = BfNodeDynCastExact<BfRetTypeTypeRef>(typeRef))
  2222. {
  2223. // Don't cause infinite loop, but if we have an inner 'rettype' then try to directly resolve that --
  2224. // Only use the HAS_RETTYPE for root-level rettype insertions
  2225. if (ctx->mRootTypeRef != retTypeTypeRef)
  2226. {
  2227. auto type = ctx->mModule->ResolveTypeRef(retTypeTypeRef);
  2228. return Hash(type, ctx, flags);
  2229. }
  2230. int elemHash = Hash(retTypeTypeRef->mElementType, ctx) ^ HASH_RETTYPE;
  2231. return (elemHash << 5) - elemHash;
  2232. }
  2233. else if (auto resolvedTypeRef = BfNodeDynCastExact<BfResolvedTypeReference>(typeRef))
  2234. {
  2235. return Hash(resolvedTypeRef->mType, ctx);
  2236. }
  2237. else if (auto constTypeRef = BfNodeDynCastExact<BfConstTypeRef>(typeRef))
  2238. {
  2239. // We purposely don't mix in a HASH_CONSTTYPE because there's no such thing as a const type in Beef, so we just strip it
  2240. return Hash(constTypeRef->mElementType, ctx, flags);
  2241. }
  2242. else if (auto delegateTypeRef = BfNodeDynCastExact<BfDelegateTypeRef>(typeRef))
  2243. {
  2244. int hashVal = HASH_DELEGATE;
  2245. if (delegateTypeRef->mReturnType != NULL)
  2246. hashVal = ((hashVal ^ (Hash(delegateTypeRef->mReturnType, ctx))) << 5) - hashVal;
  2247. else
  2248. ctx->mFailed = true;
  2249. for (auto param : delegateTypeRef->mParams)
  2250. {
  2251. // Parse attributes?
  2252. BfTypeReference* fieldType = param->mTypeRef;
  2253. hashVal = ((hashVal ^ (Hash(fieldType, ctx, BfHashFlag_AllowRef))) << 5) - hashVal;
  2254. hashVal = ((hashVal ^ (HashNode(param->mNameNode))) << 5) - hashVal;
  2255. if (param->mNameNode == NULL)
  2256. {
  2257. ctx->mFailed = true;
  2258. }
  2259. }
  2260. return hashVal;
  2261. }
  2262. else if (auto declTypeRef = BfNodeDynCastExact<BfDeclTypeRef>(typeRef))
  2263. {
  2264. if (ctx->mResolvedType == NULL)
  2265. {
  2266. if (declTypeRef->mTarget != NULL)
  2267. {
  2268. BfTypedValue result;
  2269. //
  2270. {
  2271. BfMethodState methodState;
  2272. SetAndRestoreValue<BfMethodState*> prevMethodState(ctx->mModule->mCurMethodState, &methodState, false);
  2273. if (ctx->mModule->mCurMethodState == NULL)
  2274. prevMethodState.Set();
  2275. methodState.mTempKind = BfMethodState::TempKind_NonStatic;
  2276. SetAndRestoreValue<bool> ignoreWrites(ctx->mModule->mBfIRBuilder->mIgnoreWrites, true);
  2277. SetAndRestoreValue<bool> allowUninitReads(ctx->mModule->mCurMethodState->mAllowUinitReads, true);
  2278. result = ctx->mModule->CreateValueFromExpression(declTypeRef->mTarget);
  2279. }
  2280. ctx->mResolvedType = result.mType;
  2281. }
  2282. }
  2283. if (ctx->mResolvedType == NULL)
  2284. {
  2285. ctx->mFailed = true;
  2286. return 0;
  2287. }
  2288. return Hash(ctx->mResolvedType, ctx, flags);
  2289. }
  2290. else if (auto constExprTypeRef = BfNodeDynCastExact<BfConstExprTypeRef>(typeRef))
  2291. {
  2292. BfVariant result;
  2293. if (constExprTypeRef->mConstExpr != NULL)
  2294. {
  2295. BfType* constGenericParam = NULL;
  2296. result = EvaluateToVariant(ctx, constExprTypeRef->mConstExpr, constGenericParam);
  2297. if (constGenericParam != NULL)
  2298. return Hash(constGenericParam, ctx);
  2299. }
  2300. if (result.mTypeCode == BfTypeCode_None)
  2301. {
  2302. ctx->mFailed = true;
  2303. return 0;
  2304. }
  2305. return ((int)result.mTypeCode << 17) ^ (result.mInt32 << 3) ^ HASH_CONSTTYPE;
  2306. }
  2307. else if (auto dotTypeRef = BfNodeDynCastExact<BfDotTypeReference>(typeRef))
  2308. {
  2309. ctx->mModule->ResolveTypeRef(dotTypeRef);
  2310. ctx->mFailed = true;
  2311. return 0;
  2312. }
  2313. else
  2314. {
  2315. BF_FATAL("Not handled");
  2316. }
  2317. return 0;
  2318. }
  2319. // These types can be from different contexts ("foreign" types) so we can't just compare ptrs
  2320. bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx)
  2321. {
  2322. if (lhs->IsBoxed())
  2323. {
  2324. if (!rhs->IsBoxed())
  2325. return false;
  2326. BfBoxedType* lhsBoxedType = (BfBoxedType*) lhs;
  2327. BfBoxedType* rhsBoxedType = (BfBoxedType*) rhs;
  2328. return Equals(lhsBoxedType->mElementType, rhsBoxedType->mElementType, ctx);
  2329. }
  2330. else if (lhs->IsArray())
  2331. {
  2332. if (!rhs->IsArray())
  2333. return false;
  2334. BfArrayType* lhsArrayType = (BfArrayType*) lhs;
  2335. BfArrayType* rhsArrayType = (BfArrayType*) rhs;
  2336. if (lhsArrayType->mDimensions != rhsArrayType->mDimensions)
  2337. return false;
  2338. return Equals(lhsArrayType->mTypeGenericArguments[0], rhsArrayType->mTypeGenericArguments[0], ctx);
  2339. }
  2340. else if (lhs->IsTypeInstance())
  2341. {
  2342. if ((!rhs->IsTypeInstance()) || (rhs->IsBoxed()))
  2343. return false;
  2344. BfTypeInstance* lhsInst = (BfTypeInstance*)lhs;
  2345. BfTypeInstance* rhsInst = (BfTypeInstance*)rhs;
  2346. if (lhs->IsClosure())
  2347. {
  2348. if (!rhs->IsClosure())
  2349. return false;
  2350. auto lhsClosure = (BfClosureType*)lhs;
  2351. auto rhsClosure = (BfClosureType*)rhs;
  2352. if ((lhsClosure->mIsUnique) || (rhsClosure->mIsUnique))
  2353. return false;
  2354. if (lhsClosure->mBaseType != rhsClosure->mBaseType)
  2355. return false;
  2356. return lhsClosure->mClosureHash == rhsClosure->mClosureHash;
  2357. }
  2358. if (lhs->IsGenericTypeInstance())
  2359. {
  2360. if (!rhs->IsGenericTypeInstance())
  2361. return false;
  2362. BfGenericTypeInstance* lhsGenericType = (BfGenericTypeInstance*)lhs;
  2363. BfGenericTypeInstance* rhsGenericType = (BfGenericTypeInstance*)rhs;
  2364. if (lhsGenericType->mTypeGenericArguments.size() != rhsGenericType->mTypeGenericArguments.size())
  2365. return false;
  2366. if (lhsGenericType->mTypeDef != rhsGenericType->mTypeDef)
  2367. return false;
  2368. for (int i = 0; i < (int)lhsGenericType->mTypeGenericArguments.size(); i++)
  2369. {
  2370. if (!Equals(lhsGenericType->mTypeGenericArguments[i], rhsGenericType->mTypeGenericArguments[i], ctx))
  2371. return false;
  2372. }
  2373. }
  2374. if (lhs->IsTuple())
  2375. {
  2376. if (!rhs->IsTuple())
  2377. return false;
  2378. BfTupleType* lhsTupleType = (BfTupleType*)lhs;
  2379. BfTupleType* rhsTupleType = (BfTupleType*)rhs;
  2380. if (lhsTupleType->mFieldInstances.size() != rhsTupleType->mFieldInstances.size())
  2381. return false;
  2382. for (int fieldIdx = 0; fieldIdx < (int)lhsTupleType->mFieldInstances.size(); fieldIdx++)
  2383. {
  2384. auto lhsFieldInstance = &lhsTupleType->mFieldInstances[fieldIdx];
  2385. auto rhsFieldInstance = &rhsTupleType->mFieldInstances[fieldIdx];
  2386. if (lhsFieldInstance->mResolvedType != rhsFieldInstance->mResolvedType)
  2387. return false;
  2388. auto lhsFieldDef = lhsFieldInstance->GetFieldDef();
  2389. if (rhsTupleType->mTypeDef == NULL)
  2390. {
  2391. char c = lhsFieldDef->mName[0];
  2392. if ((c < '0') || (c > '9'))
  2393. return false;
  2394. }
  2395. else
  2396. {
  2397. auto rhsFieldDef = rhsFieldInstance->GetFieldDef();
  2398. if (lhsFieldDef->mName != rhsFieldDef->mName)
  2399. return false;
  2400. }
  2401. }
  2402. return true;
  2403. }
  2404. return lhsInst->mTypeDef == rhsInst->mTypeDef;
  2405. }
  2406. else if (lhs->IsPrimitiveType())
  2407. {
  2408. if (!rhs->IsPrimitiveType())
  2409. return false;
  2410. BfPrimitiveType* lhsPrimType = (BfPrimitiveType*)lhs;
  2411. BfPrimitiveType* rhsPrimType = (BfPrimitiveType*)rhs;
  2412. return lhsPrimType->mTypeDef == rhsPrimType->mTypeDef;
  2413. }
  2414. else if (lhs->IsPointer())
  2415. {
  2416. if (!rhs->IsPointer())
  2417. return false;
  2418. BfPointerType* lhsPtrType = (BfPointerType*)lhs;
  2419. BfPointerType* rhsPtrType = (BfPointerType*)rhs;
  2420. return Equals(lhsPtrType->mElementType, rhsPtrType->mElementType, ctx);
  2421. }
  2422. else if (lhs->IsGenericParam())
  2423. {
  2424. if (!rhs->IsGenericParam())
  2425. return false;
  2426. BfGenericParamType* lhsGenericParamType = (BfGenericParamType*)lhs;
  2427. BfGenericParamType* rhsGenericParamType = (BfGenericParamType*)rhs;
  2428. return (lhsGenericParamType->mGenericParamKind == rhsGenericParamType->mGenericParamKind) &&
  2429. (lhsGenericParamType->mGenericParamIdx == rhsGenericParamType->mGenericParamIdx);
  2430. }
  2431. else if (lhs->IsRef())
  2432. {
  2433. if (!rhs->IsRef())
  2434. return false;
  2435. BfRefType* lhsRefType = (BfRefType*)lhs;
  2436. BfRefType* rhsRefType = (BfRefType*)rhs;
  2437. return (lhsRefType->mElementType == rhsRefType->mElementType) && (lhsRefType->mRefKind == rhsRefType->mRefKind);
  2438. }
  2439. else if (lhs->IsRetTypeType())
  2440. {
  2441. if (!rhs->IsRetTypeType())
  2442. return false;
  2443. BfRetTypeType* lhsRetTypeType = (BfRetTypeType*)lhs;
  2444. BfRetTypeType* rhsRetTypeType = (BfRetTypeType*)rhs;
  2445. return (lhsRetTypeType->mElementType == rhsRetTypeType->mElementType);
  2446. }
  2447. else if (lhs->IsConcreteInterfaceType())
  2448. {
  2449. if (!rhs->IsConcreteInterfaceType())
  2450. return false;
  2451. BfConcreteInterfaceType* lhsConcreteInterfaceType = (BfConcreteInterfaceType*)lhs;
  2452. BfConcreteInterfaceType* rhsConcreteInterfaceType = (BfConcreteInterfaceType*)rhs;
  2453. return (lhsConcreteInterfaceType->mInterface == rhsConcreteInterfaceType->mInterface);
  2454. }
  2455. else if (lhs->IsSizedArray())
  2456. {
  2457. if (!rhs->IsSizedArray())
  2458. return false;
  2459. BfSizedArrayType* lhsSizedArrayType = (BfSizedArrayType*)lhs;
  2460. BfSizedArrayType* rhsSizedArrayType = (BfSizedArrayType*)rhs;
  2461. return (lhsSizedArrayType->mElementType == rhsSizedArrayType->mElementType) &&
  2462. (lhsSizedArrayType->mElementCount == rhsSizedArrayType->mElementCount);
  2463. }
  2464. else if (lhs->IsMethodRef())
  2465. {
  2466. if (!rhs->IsMethodRef())
  2467. return false;
  2468. BfMethodRefType* lhsMethodRefType = (BfMethodRefType*)lhs;
  2469. BfMethodRefType* rhsMethodRefType = (BfMethodRefType*)rhs;
  2470. return (lhsMethodRefType->mMethodRef == rhsMethodRefType->mMethodRef) &&
  2471. (lhsMethodRefType->mOwner == rhsMethodRefType->mOwner) &&
  2472. (lhsMethodRefType->mOwnerRevision == rhsMethodRefType->mOwnerRevision);
  2473. }
  2474. else if (lhs->IsDelegateFromTypeRef() || lhs->IsFunctionFromTypeRef())
  2475. {
  2476. if (!rhs->IsDelegateFromTypeRef() && !rhs->IsFunctionFromTypeRef())
  2477. return false;
  2478. if (lhs->IsDelegate() != rhs->IsDelegate())
  2479. return false;
  2480. BfDelegateType* lhsDelegateType = (BfDelegateType*)lhs;
  2481. BfDelegateType* rhsDelegateType = (BfDelegateType*)rhs;
  2482. if (lhsDelegateType->mTypeDef->mIsDelegate != rhsDelegateType->mTypeDef->mIsDelegate)
  2483. return false;
  2484. BfMethodInstance* lhsInvokeMethodInstance = ctx->mModule->GetRawMethodInstanceAtIdx(lhsDelegateType->ToTypeInstance(), 0, "Invoke");
  2485. BfMethodInstance* rhsInvokeMethodInstance = ctx->mModule->GetRawMethodInstanceAtIdx(rhsDelegateType->ToTypeInstance(), 0, "Invoke");
  2486. if (lhsInvokeMethodInstance->mReturnType != rhsInvokeMethodInstance->mReturnType)
  2487. return false;
  2488. if (lhsInvokeMethodInstance->GetParamCount() != rhsInvokeMethodInstance->GetParamCount())
  2489. return false;
  2490. for (int paramIdx = 0; paramIdx < lhsInvokeMethodInstance->GetParamCount(); paramIdx++)
  2491. {
  2492. if (lhsInvokeMethodInstance->GetParamType(paramIdx) != rhsInvokeMethodInstance->GetParamType(paramIdx))
  2493. return false;
  2494. if (lhsInvokeMethodInstance->GetParamName(paramIdx) != rhsInvokeMethodInstance->GetParamName(paramIdx))
  2495. return false;
  2496. }
  2497. return true;
  2498. }
  2499. else if ((lhs->IsConstExprValue()) || (rhs->IsConstExprValue()))
  2500. {
  2501. if (!lhs->IsConstExprValue() || !rhs->IsConstExprValue())
  2502. return false;
  2503. BfConstExprValueType* lhsConstExprValueType = (BfConstExprValueType*)lhs;
  2504. BfConstExprValueType* rhsConstExprValueType = (BfConstExprValueType*)rhs;
  2505. return (lhsConstExprValueType->mType == rhsConstExprValueType->mType) &&
  2506. (lhsConstExprValueType->mValue.mTypeCode == rhsConstExprValueType->mValue.mTypeCode) &&
  2507. (lhsConstExprValueType->mValue.mInt64 == rhsConstExprValueType->mValue.mInt64);
  2508. }
  2509. else
  2510. {
  2511. BF_FATAL("Not handled");
  2512. }
  2513. return 0;
  2514. }
  2515. bool BfResolvedTypeSet::GenericTypeEquals(BfGenericTypeInstance* lhsGenericType, BfTypeVector* lhsTypeGenericArguments, BfTypeReference* rhs, LookupContext* ctx, int& genericParamOffset)
  2516. {
  2517. //BP_ZONE("BfResolvedTypeSet::GenericTypeEquals");
  2518. if (auto elementedTypeRef = BfNodeDynCast<BfElementedTypeRef>(rhs))
  2519. {
  2520. if (!GenericTypeEquals(lhsGenericType, lhsTypeGenericArguments, elementedTypeRef->mElementType, ctx, genericParamOffset))
  2521. return false;
  2522. //_GetTypeRefs(elementedTypeRef->mElementType);
  2523. }
  2524. else if (auto qualifiedTypeRef = BfNodeDynCastExact<BfQualifiedTypeReference>(rhs))
  2525. {
  2526. //_GetTypeRefs(qualifiedTypeRef->mLeft);
  2527. if (!GenericTypeEquals(lhsGenericType, lhsTypeGenericArguments, qualifiedTypeRef->mLeft, ctx, genericParamOffset))
  2528. return false;
  2529. }
  2530. if (auto genericTypeRef = BfNodeDynCastExact<BfGenericInstanceTypeRef>(rhs))
  2531. {
  2532. if (genericTypeRef->mGenericArguments.size() > lhsTypeGenericArguments->size() + genericParamOffset)
  2533. return false;
  2534. for (auto genericArg : genericTypeRef->mGenericArguments)
  2535. {
  2536. if (!Equals((*lhsTypeGenericArguments)[genericParamOffset++], genericArg, ctx))
  2537. return false;
  2538. }
  2539. }
  2540. return true;
  2541. }
  2542. bool BfResolvedTypeSet::GenericTypeEquals(BfGenericTypeInstance* lhsGenericType, BfTypeVector* lhsTypeGenericArguments, BfTypeReference* rhs, BfTypeDef* rhsTypeDef, LookupContext* ctx)
  2543. {
  2544. auto rhsGenericTypeInstRef = BfNodeDynCastExact<BfGenericInstanceTypeRef>(rhs);
  2545. if (rhsGenericTypeInstRef == NULL)
  2546. {
  2547. if (auto rhsNullableTypeRef = BfNodeDynCastExact<BfNullableTypeRef>(rhs))
  2548. {
  2549. if (rhsNullableTypeRef != NULL)
  2550. {
  2551. if (lhsGenericType->mTypeDef != ctx->mModule->mContext->mCompiler->mNullableTypeDef)
  2552. return false;
  2553. return Equals(lhsGenericType->mTypeGenericArguments[0], rhsNullableTypeRef->mElementType, ctx);
  2554. }
  2555. }
  2556. if ((rhsTypeDef != NULL) && (ctx->mModule->mCurTypeInstance != NULL))
  2557. {
  2558. // See if we're referring to an non-generic inner type where the outer type is generic
  2559. if (lhsGenericType->mTypeDef != rhsTypeDef)
  2560. return false;
  2561. BfTypeDef* commonOuterType = ctx->mModule->FindCommonOuterType(ctx->mModule->mCurTypeInstance->mTypeDef, rhsTypeDef->mOuterType);
  2562. if (commonOuterType != NULL)
  2563. {
  2564. BfTypeInstance* checkTypeInstance = ctx->mModule->mCurTypeInstance;
  2565. if (checkTypeInstance->IsBoxed())
  2566. checkTypeInstance = checkTypeInstance->GetUnderlyingType()->ToTypeInstance();
  2567. BF_ASSERT(checkTypeInstance->IsGenericTypeInstance());
  2568. int numParentGenericParams = (int) commonOuterType->mGenericParamDefs.size();
  2569. auto curTypeInstance = (BfGenericTypeInstance*)checkTypeInstance;
  2570. if (lhsGenericType->mTypeGenericArguments.size() != numParentGenericParams)
  2571. return false;
  2572. for (int i = 0; i < (int) numParentGenericParams; i++)
  2573. if ((*lhsTypeGenericArguments)[i] != curTypeInstance->mTypeGenericArguments[i])
  2574. return false;
  2575. return true;
  2576. }
  2577. }
  2578. if (auto rhsQualifiedTypeRef = BfNodeDynCastExact<BfQualifiedTypeReference>(rhs))
  2579. {
  2580. /*auto rhsLeftType = ctx->mModule->ResolveTypeRef(rhsQualifiedTypeRef->mLeft, BfPopulateType_Identity);
  2581. if (rhsLeftType == NULL)
  2582. return false;
  2583. auto rhsRightType = ctx->mModule->ResolveInnerType(rhsLeftType, rhsQualifiedTypeRef->mRight);
  2584. if (rhsRightType == NULL)
  2585. return false;*/
  2586. auto rhsRightType = ctx->mModule->ResolveTypeRef(rhs, BfPopulateType_Identity);
  2587. return rhsRightType == lhsGenericType;
  2588. }
  2589. return false;
  2590. }
  2591. BfTypeDef* elementTypeDef = ctx->mModule->ResolveGenericInstanceDef(rhsGenericTypeInstRef);
  2592. if (elementTypeDef != lhsGenericType->mTypeDef)
  2593. return false;
  2594. int genericParamOffset = 0;
  2595. // Do we need to add generic arguments from an in-context outer class?
  2596. if ((elementTypeDef->mOuterType != NULL) && (ctx->mModule->mCurTypeInstance != NULL) && (ctx->mModule->mCurTypeInstance->IsGenericTypeInstance()))
  2597. {
  2598. BfTypeDef* commonOuterType = ctx->mModule->FindCommonOuterType(ctx->mModule->mCurTypeInstance->mTypeDef, elementTypeDef->mOuterType);
  2599. if (commonOuterType != NULL)
  2600. {
  2601. auto parentTypeInstance = (BfGenericTypeInstance*)ctx->mModule->mCurTypeInstance;
  2602. genericParamOffset = (int) commonOuterType->mGenericParamDefs.size();
  2603. for (int i = 0; i < genericParamOffset; i++)
  2604. for (auto genericArg : parentTypeInstance->mTypeGenericArguments)
  2605. {
  2606. if (parentTypeInstance->mTypeGenericArguments[i] != (*lhsTypeGenericArguments)[i])
  2607. return false;
  2608. }
  2609. }
  2610. }
  2611. /*if (lhsTypeGenericArguments->size() != rhsGenericTypeInstRef->mGenericArguments.size() + genericParamOffset)
  2612. {
  2613. return false;
  2614. }
  2615. for (int i = 0; i < (int) rhsGenericTypeInstRef->mGenericArguments.size(); i++)
  2616. {
  2617. if (!Equals(lhsGenericType->mTypeGenericArguments[i + genericParamOffset], rhsGenericTypeInstRef->mGenericArguments[i], module))
  2618. return false;
  2619. }*/
  2620. if (!GenericTypeEquals(lhsGenericType, lhsTypeGenericArguments, rhs, ctx, genericParamOffset))
  2621. return false;
  2622. return genericParamOffset == (int)lhsTypeGenericArguments->size();
  2623. }
  2624. BfType* BfResolvedTypeSet::LookupContext::ResolveTypeRef(BfTypeReference* typeReference)
  2625. {
  2626. return mModule->ResolveTypeRef(typeReference, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowGenericParamConstValue);
  2627. }
  2628. BfTypeDef* BfResolvedTypeSet::LookupContext::ResolveToTypeDef(BfTypeReference* typeReference)
  2629. {
  2630. if (typeReference == mRootTypeRef)
  2631. return mRootTypeDef;
  2632. if (auto typeDefTypeRef = BfNodeDynCast<BfDirectTypeDefReference>(typeReference))
  2633. {
  2634. return typeDefTypeRef->mTypeDef;
  2635. }
  2636. auto type = mModule->ResolveTypeRef(typeReference, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowGenericParamConstValue);
  2637. if (type == NULL)
  2638. return NULL;
  2639. auto typeInst = type->ToTypeInstance();
  2640. if (typeInst == NULL)
  2641. return NULL;
  2642. return typeInst->mTypeDef;
  2643. }
  2644. bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* ctx)
  2645. {
  2646. //BP_ZONE("BfResolvedTypeSet::Equals");
  2647. if (ctx->mRootTypeRef != rhs)
  2648. {
  2649. if (auto retTypeRef = BfNodeDynCastExact<BfRetTypeTypeRef>(rhs))
  2650. {
  2651. auto resolvedType = ctx->mModule->ResolveTypeRef(rhs);
  2652. return lhs == resolvedType;
  2653. }
  2654. }
  2655. if (rhs->IsNamedTypeReference())
  2656. {
  2657. if ((ctx->mRootTypeRef != rhs) || (ctx->mRootTypeDef == NULL))
  2658. {
  2659. auto rhsResolvedType = ctx->ResolveTypeRef(rhs);
  2660. return Equals(lhs, rhsResolvedType, ctx);
  2661. }
  2662. }
  2663. // auto rhsTypeDefTypeRef = BfNodeDynCast<BfTypeDefTypeReference>(rhs);
  2664. // if (rhsTypeDefTypeRef != NULL)
  2665. // {
  2666. // // mTypeDef not set, need to resolve in module
  2667. // if (rhsTypeDefTypeRef->mTypeDef == NULL)
  2668. // {
  2669. // auto rhsResolvedType = ctx->mModule->ResolveTypeRef(rhsTypeDefTypeRef, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowGenericParamConstValue);
  2670. // return Equals(lhs, rhsResolvedType, ctx);
  2671. // }
  2672. // }
  2673. if (auto declTypeRef = BfNodeDynCastExact<BfDeclTypeRef>(rhs))
  2674. {
  2675. BF_ASSERT(ctx->mResolvedType != NULL);
  2676. return lhs == ctx->mResolvedType;
  2677. }
  2678. // Strip off 'const' - it's just an error when applied to a typeRef in Beef
  2679. auto constTypeRef = BfNodeDynCastExact<BfConstTypeRef>(rhs);
  2680. if (constTypeRef != NULL)
  2681. return Equals(lhs, constTypeRef->mElementType, ctx);
  2682. if (lhs->IsBoxed())
  2683. {
  2684. auto rhsBoxedTypeRef = BfNodeDynCastExact<BfBoxedTypeRef>(rhs);
  2685. if (rhsBoxedTypeRef == NULL)
  2686. return false;
  2687. BfBoxedType* lhsBoxedType = (BfBoxedType*) lhs;
  2688. return Equals(lhsBoxedType->mElementType, rhsBoxedTypeRef->mElementType, ctx);
  2689. }
  2690. else if (lhs->IsArray())
  2691. {
  2692. auto rhsArrayTypeRef = BfNodeDynCastExact<BfArrayTypeRef>(rhs);
  2693. if (rhsArrayTypeRef == NULL)
  2694. return false;
  2695. BfArrayType* lhsArrayType = (BfArrayType*) lhs;
  2696. if (lhsArrayType->mDimensions != rhsArrayTypeRef->mDimensions)
  2697. return false;
  2698. return Equals(lhsArrayType->mTypeGenericArguments[0], rhsArrayTypeRef->mElementType, ctx);
  2699. }
  2700. else if (lhs->IsDelegateFromTypeRef() || lhs->IsFunctionFromTypeRef())
  2701. {
  2702. auto rhsDelegateType = BfNodeDynCastExact<BfDelegateTypeRef>(rhs);
  2703. if (rhsDelegateType == NULL)
  2704. return false;
  2705. BfDelegateType* lhsDelegateType = (BfDelegateType*)lhs;
  2706. BfMethodInstance* lhsInvokeMethodInstance = ctx->mModule->GetRawMethodInstanceAtIdx(lhsDelegateType->ToTypeInstance(), 0, "Invoke");
  2707. if ((lhs->IsDelegate()) != (rhsDelegateType->mTypeToken->GetToken() == BfToken_Delegate))
  2708. return false;
  2709. if (!Equals(lhsInvokeMethodInstance->mReturnType, rhsDelegateType->mReturnType, ctx))
  2710. return false;
  2711. if (lhsInvokeMethodInstance->GetParamCount() != (int)rhsDelegateType->mParams.size())
  2712. return false;
  2713. for (int paramIdx = 0; paramIdx < lhsInvokeMethodInstance->GetParamCount(); paramIdx++)
  2714. {
  2715. if (!Equals(lhsInvokeMethodInstance->GetParamType(paramIdx), rhsDelegateType->mParams[paramIdx]->mTypeRef, ctx))
  2716. return false;
  2717. if (lhsInvokeMethodInstance->GetParamName(paramIdx) != rhsDelegateType->mParams[paramIdx]->mNameNode->ToString())
  2718. return false;
  2719. }
  2720. return true;
  2721. }
  2722. else if (lhs->IsTypeInstance())
  2723. {
  2724. BfTypeInstance* lhsInst = (BfTypeInstance*) lhs;
  2725. if (lhs->IsGenericTypeInstance())
  2726. {
  2727. auto rhsTypeDef = ctx->ResolveToTypeDef(rhs);
  2728. if (rhsTypeDef == NULL)
  2729. return false;
  2730. BfGenericTypeInstance* lhsGenericType = (BfGenericTypeInstance*) lhs;
  2731. return GenericTypeEquals(lhsGenericType, &lhsGenericType->mTypeGenericArguments, rhs, rhsTypeDef, ctx);
  2732. }
  2733. if (lhs->IsTuple())
  2734. {
  2735. if (!rhs->IsA<BfTupleTypeRef>())
  2736. return false;
  2737. BfTupleTypeRef* rhsTupleTypeRef = (BfTupleTypeRef*)rhs;
  2738. BfTupleType* lhsTupleType = (BfTupleType*)lhs;
  2739. if (lhsTupleType->mFieldInstances.size() != rhsTupleTypeRef->mFieldTypes.size())
  2740. return false;
  2741. for (int fieldIdx = 0; fieldIdx < (int)lhsTupleType->mFieldInstances.size(); fieldIdx++)
  2742. {
  2743. BfFieldInstance* fieldInstance = &lhsTupleType->mFieldInstances[fieldIdx];
  2744. auto rhsResolvedType = ctx->mModule->ResolveTypeRef(rhsTupleTypeRef->mFieldTypes[fieldIdx], BfPopulateType_Identity);
  2745. if (rhsResolvedType != fieldInstance->mResolvedType)
  2746. return false;
  2747. BfFieldDef* fieldTypeDef = fieldInstance->GetFieldDef();
  2748. BfIdentifierNode* fieldName = NULL;
  2749. if (fieldIdx < (int)rhsTupleTypeRef->mFieldNames.size())
  2750. fieldName = rhsTupleTypeRef->mFieldNames[fieldIdx];
  2751. if (fieldName != NULL)
  2752. {
  2753. if (fieldName->ToString() != fieldTypeDef->mName)
  2754. return false;
  2755. }
  2756. else
  2757. {
  2758. char nameStr[64];
  2759. sprintf(nameStr, "%d", fieldIdx);
  2760. if (fieldTypeDef->mName != nameStr)
  2761. return false;
  2762. }
  2763. }
  2764. return true;
  2765. }
  2766. else
  2767. {
  2768. if (rhs->IsA<BfElementedTypeRef>())
  2769. return false;
  2770. if (!rhs->IsTypeDefTypeReference())
  2771. {
  2772. if (rhs->IsA<BfDelegateTypeRef>())
  2773. return false; // Would have caught it before
  2774. if (rhs->IsA<BfQualifiedTypeReference>())
  2775. {
  2776. //TODO: Under what circumstances was this supposed to be used? This caused an infinite loop comparing
  2777. // 'var' against a delegate type instance
  2778. auto resolvedType = ctx->mModule->ResolveTypeRef(rhs, BfPopulateType_Identity);
  2779. if (resolvedType == lhsInst)
  2780. {
  2781. return true;
  2782. }
  2783. }
  2784. return false;
  2785. }
  2786. auto rhsTypeDef = ctx->ResolveToTypeDef(rhs);
  2787. if (rhsTypeDef == NULL)
  2788. return false;
  2789. return lhsInst->mTypeDef == rhsTypeDef;
  2790. }
  2791. }
  2792. else if (lhs->IsPrimitiveType())
  2793. {
  2794. if (lhs->IsDot())
  2795. {
  2796. auto varTypeReference = BfNodeDynCastExact<BfDotTypeReference>(rhs);
  2797. if (varTypeReference != NULL)
  2798. return true;
  2799. }
  2800. if (lhs->IsVar())
  2801. {
  2802. auto varTypeReference = BfNodeDynCastExact<BfVarTypeReference>(rhs);
  2803. if (varTypeReference != NULL)
  2804. return true;
  2805. }
  2806. if (lhs->IsLet())
  2807. {
  2808. auto letTypeReference = BfNodeDynCastExact<BfLetTypeReference>(rhs);
  2809. if (letTypeReference != NULL)
  2810. return true;
  2811. }
  2812. if (!rhs->IsTypeDefTypeReference())
  2813. return false;
  2814. BfPrimitiveType* lhsPrimType = (BfPrimitiveType*)lhs;
  2815. auto rhsTypeDef = ctx->ResolveToTypeDef(rhs);
  2816. return lhsPrimType->mTypeDef == rhsTypeDef;
  2817. // auto rhsTypeDefTypeRef = BfNodeDynCast<BfTypeDefTypeReference>(rhs);
  2818. // if (rhsTypeDefTypeRef == NULL)
  2819. // return false;
  2820. // BfPrimitiveType* lhsPrimType = (BfPrimitiveType*)lhs;
  2821. // return lhsPrimType->mTypeDef == rhsTypeDefTypeRef->mTypeDef;
  2822. }
  2823. else if (lhs->IsPointer())
  2824. {
  2825. auto rhsPointerTypeRef = BfNodeDynCastExact<BfPointerTypeRef>(rhs);
  2826. if (rhsPointerTypeRef == NULL)
  2827. return false;
  2828. BfPointerType* lhsPtrType = (BfPointerType*)lhs;
  2829. return Equals(lhsPtrType->mElementType, rhsPointerTypeRef->mElementType, ctx);
  2830. }
  2831. else if (lhs->IsGenericParam())
  2832. {
  2833. auto lhsGenericParamType = (BfGenericParamType*)lhs;
  2834. auto rhsGenericParamTypeRef = BfNodeDynCastExact<BfGenericParamTypeRef>(rhs);
  2835. if (rhsGenericParamTypeRef == NULL)
  2836. {
  2837. if (auto constExprTypeRef = BfNodeDynCastExact<BfConstExprTypeRef>(rhs))
  2838. {
  2839. BfVariant result;
  2840. if (constExprTypeRef->mConstExpr == NULL)
  2841. return false;
  2842. BfType* constGenericParam = NULL;
  2843. result = EvaluateToVariant(ctx, constExprTypeRef->mConstExpr, constGenericParam);
  2844. return constGenericParam == lhs;
  2845. }
  2846. return false;
  2847. }
  2848. return (lhsGenericParamType->mGenericParamKind == rhsGenericParamTypeRef->mGenericParamKind) &&
  2849. (lhsGenericParamType->mGenericParamIdx == rhsGenericParamTypeRef->mGenericParamIdx);
  2850. }
  2851. else if (lhs->IsRef())
  2852. {
  2853. auto lhsRefType = (BfRefType*)lhs;
  2854. auto rhsRefTypeRef = BfNodeDynCastExact<BfRefTypeRef>(rhs);
  2855. if (rhsRefTypeRef == NULL)
  2856. return false;
  2857. auto refKind = BfRefType::RefKind_Ref;
  2858. if (rhsRefTypeRef->mRefToken == NULL)
  2859. refKind = BfRefType::RefKind_Ref;
  2860. else if (rhsRefTypeRef->mRefToken->GetToken() == BfToken_Out)
  2861. refKind = BfRefType::RefKind_Out;
  2862. else if (rhsRefTypeRef->mRefToken->GetToken() == BfToken_Mut)
  2863. refKind = BfRefType::RefKind_Mut;
  2864. return (lhsRefType->mRefKind == refKind) &&
  2865. Equals(lhsRefType->mElementType, rhsRefTypeRef->mElementType, ctx);
  2866. }
  2867. else if (lhs->IsRetTypeType())
  2868. {
  2869. auto lhsRetTypeType = (BfRetTypeType*)lhs;
  2870. auto rhsRetTypeTypeRef = BfNodeDynCastExact<BfRetTypeTypeRef>(rhs);
  2871. if (rhsRetTypeTypeRef == NULL)
  2872. return false;
  2873. return Equals(lhsRetTypeType->mElementType, rhsRetTypeTypeRef->mElementType, ctx);
  2874. }
  2875. else if (lhs->IsConcreteInterfaceType())
  2876. {
  2877. // No way to create a reference to one of these
  2878. return false;
  2879. }
  2880. else if (lhs->IsSizedArray())
  2881. {
  2882. auto rhsArrayTypeRef = BfNodeDynCastExact<BfArrayTypeRef>(rhs);
  2883. if (rhsArrayTypeRef == NULL)
  2884. return false;
  2885. if ((rhsArrayTypeRef->mDimensions != 1) && (rhsArrayTypeRef->mParams.size() != 1))
  2886. return false;
  2887. BfSizedArrayType* lhsArrayType = (BfSizedArrayType*)lhs;
  2888. if (!Equals(lhsArrayType->mElementType, rhsArrayTypeRef->mElementType, ctx))
  2889. return false;
  2890. intptr elementCount = -1;
  2891. BfExpression* sizeExpr = BfNodeDynCast<BfExpression>(rhsArrayTypeRef->mParams[0]);
  2892. BF_ASSERT(sizeExpr != NULL);
  2893. if (sizeExpr != NULL)
  2894. {
  2895. SetAndRestoreValue<bool> prevIgnoreError(ctx->mModule->mIgnoreErrors, true);
  2896. BfConstResolver constResolver(ctx->mModule);
  2897. BfType* intType = ctx->mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  2898. constResolver.mAllowGenericConstValue = true;
  2899. constResolver.mExpectingType = intType;
  2900. BfTypedValue typedVal = constResolver.Resolve(sizeExpr);
  2901. if (typedVal.mKind == BfTypedValueKind_GenericConstValue)
  2902. {
  2903. if (!lhs->IsUnknownSizedArray())
  2904. return false;
  2905. auto lhsUnknownSizedArray = (BfUnknownSizedArrayType*)lhs;
  2906. return lhsUnknownSizedArray->mElementCountSource = typedVal.mType;
  2907. }
  2908. if (typedVal)
  2909. typedVal = ctx->mModule->Cast(sizeExpr, typedVal, intType);
  2910. if (typedVal)
  2911. {
  2912. if (lhs->IsUnknownSizedArray())
  2913. return false;
  2914. auto constant = ctx->mModule->mBfIRBuilder->GetConstant(typedVal.mValue);
  2915. if (constant->mConstType == BfConstType_Undef)
  2916. {
  2917. elementCount = -1; // Marker for undef
  2918. }
  2919. else
  2920. {
  2921. BF_ASSERT(BfIRBuilder::IsInt(constant->mTypeCode));
  2922. elementCount = (intptr)constant->mInt64;
  2923. BF_ASSERT(elementCount >= 0); // Should have been caught in hash
  2924. }
  2925. }
  2926. }
  2927. return lhsArrayType->mElementCount == elementCount;
  2928. }
  2929. else if (lhs->IsMethodRef())
  2930. {
  2931. // Always make these unique. The MethodInstance value will change on rebuild anyway
  2932. return false;
  2933. }
  2934. else if (lhs->IsConstExprValue())
  2935. {
  2936. auto constExprTypeRef = BfNodeDynCastExact<BfConstExprTypeRef>(rhs);
  2937. if (constExprTypeRef == NULL)
  2938. return false;
  2939. if (!lhs->IsConstExprValue())
  2940. return false;
  2941. BfConstExprValueType* lhsConstExprType = (BfConstExprValueType*)lhs;
  2942. BfVariant result;
  2943. if (constExprTypeRef->mConstExpr != NULL)
  2944. {
  2945. BfType* constGenericParam = NULL;
  2946. result = EvaluateToVariant(ctx, constExprTypeRef->mConstExpr, constGenericParam);
  2947. if (constGenericParam != NULL)
  2948. return false;
  2949. }
  2950. return (result.mTypeCode == lhsConstExprType->mValue.mTypeCode) &&
  2951. (result.mInt64 == lhsConstExprType->mValue.mInt64);
  2952. }
  2953. else
  2954. {
  2955. BF_FATAL("Not handled");
  2956. }
  2957. return false;
  2958. }
  2959. void BfResolvedTypeSet::RemoveEntry(BfResolvedTypeSet::Entry* entry)
  2960. {
  2961. int hashIdx = (entry->mHash & 0x7FFFFFFF) % mHashSize;
  2962. // if (entry->mPrev == NULL)
  2963. // {
  2964. // if (entry->mNext != NULL)
  2965. // entry->mNext->mPrev = NULL;
  2966. // BF_ASSERT(mHashHeads[bucket] == entry);
  2967. // mHashHeads[bucket] = entry->mNext;
  2968. // }
  2969. // else
  2970. // {
  2971. // entry->mPrev->mNext = entry->mNext;
  2972. // if (entry->mNext != NULL)
  2973. // entry->mNext->mPrev = entry->mPrev;
  2974. // }
  2975. //
  2976. // mSize--;
  2977. bool found = false;
  2978. Entry** srcCheckEntryPtr = &this->mHashHeads[hashIdx];
  2979. Entry* checkEntry = *srcCheckEntryPtr;
  2980. while (checkEntry != NULL)
  2981. {
  2982. if (checkEntry == entry)
  2983. {
  2984. this->mCount--;
  2985. *srcCheckEntryPtr = checkEntry->mNext;
  2986. found = true;
  2987. }
  2988. srcCheckEntryPtr = &checkEntry->mNext;
  2989. checkEntry = checkEntry->mNext;
  2990. }
  2991. BF_ASSERT(found);
  2992. BF_ASSERT(entry->mValue == NULL);
  2993. Deallocate(entry);
  2994. }
  2995. // BfResolvedTypeSet::Iterator BfResolvedTypeSet::begin()
  2996. // {
  2997. // return ++Iterator(this);
  2998. // }
  2999. //
  3000. // BfResolvedTypeSet::Iterator BfResolvedTypeSet::end()
  3001. // {
  3002. // Iterator itr(this);
  3003. // itr.mCurBucket = HashSize;
  3004. // return itr;
  3005. // }
  3006. //
  3007. // BfResolvedTypeSet::Iterator BfResolvedTypeSet::erase(BfResolvedTypeSet::Iterator& itr)
  3008. // {
  3009. // auto next = itr;
  3010. // ++next;
  3011. //
  3012. // auto cur = itr.mCurEntry;
  3013. //
  3014. // auto& hashHead = itr.mTypeSet->mHashHeads[itr.mCurBucket];
  3015. //
  3016. // if (hashHead == cur)
  3017. // hashHead = cur->mNext;
  3018. // if (cur->mPrev != NULL)
  3019. // cur->mPrev->mNext = cur->mNext;
  3020. // if (cur->mNext != NULL)
  3021. // cur->mNext->mPrev = cur->mPrev;
  3022. // delete cur;
  3023. //
  3024. // //BfLogSys("Deleting node %@ from bucket %d\n", cur, itr.mCurBucket);
  3025. //
  3026. // mSize--;
  3027. // return next;
  3028. // }
  3029. //////////////////////////////////////////////////////////////////////////
  3030. BfHotTypeVersion::~BfHotTypeVersion()
  3031. {
  3032. for (auto member : mMembers)
  3033. member->Deref();
  3034. }
  3035. BfHotTypeData::~BfHotTypeData()
  3036. {
  3037. for (auto version : mTypeVersions)
  3038. {
  3039. version->Deref();
  3040. }
  3041. }
  3042. BfHotTypeVersion* BfHotTypeData::GetTypeVersion(int hotCommitedIdx)
  3043. {
  3044. for (int checkIdx = (int)mTypeVersions.size() - 1; checkIdx >= 0; checkIdx--)
  3045. {
  3046. BfHotTypeVersion* hotTypeVersion = mTypeVersions[checkIdx];
  3047. if (hotTypeVersion->mDeclHotCompileIdx <= hotCommitedIdx)
  3048. return hotTypeVersion;
  3049. }
  3050. return NULL;
  3051. }
  3052. BfHotTypeVersion* BfHotTypeData::GetLatestVersion()
  3053. {
  3054. return mTypeVersions.back();
  3055. }
  3056. BfHotTypeVersion* BfHotTypeData::GetLatestVersionHead()
  3057. {
  3058. auto lastestVersion = mTypeVersions.back();
  3059. for (int versionIdx = (int)mTypeVersions.size() - 1; versionIdx >= 0; versionIdx--)
  3060. {
  3061. auto checkVersion = mTypeVersions[versionIdx];
  3062. if (checkVersion->mDataHash != lastestVersion->mDataHash)
  3063. break;
  3064. lastestVersion = checkVersion;
  3065. }
  3066. return lastestVersion;
  3067. }
  3068. void BfHotTypeData::ClearVersionsAfter(int hotIdx)
  3069. {
  3070. while (!mTypeVersions.IsEmpty())
  3071. {
  3072. auto hotTypeVersion = mTypeVersions.back();
  3073. if (hotTypeVersion->mDeclHotCompileIdx > hotIdx)
  3074. {
  3075. hotTypeVersion->Deref();
  3076. mTypeVersions.pop_back();
  3077. }
  3078. else
  3079. break;
  3080. }
  3081. }
  3082. void BfHotDepData::Deref()
  3083. {
  3084. mRefCount--;
  3085. BF_ASSERT(mRefCount >= 0);
  3086. if (mRefCount == 0)
  3087. {
  3088. switch (mDataKind)
  3089. {
  3090. case BfHotDepDataKind_TypeVersion:
  3091. delete (BfHotTypeVersion*)this;
  3092. break;
  3093. case BfHotDepDataKind_ThisType:
  3094. delete (BfHotThisType*)this;
  3095. break;
  3096. case BfHotDepDataKind_Allocation:
  3097. delete (BfHotAllocation*)this;
  3098. break;
  3099. case BfHotDepDataKind_Method:
  3100. delete (BfHotMethod*)this;
  3101. break;
  3102. case BfHotDepDataKind_DupMethod:
  3103. delete (BfHotDupMethod*)this;
  3104. break;
  3105. case BfHotDepDataKind_DevirtualizedMethod:
  3106. delete (BfHotDevirtualizedMethod*)this;
  3107. break;
  3108. case BfHotDepDataKind_InnerMethod:
  3109. delete (BfHotInnerMethod*)this;
  3110. break;
  3111. case BfHotDepDataKind_FunctionPtr:
  3112. delete (BfHotFunctionReference*)this;
  3113. break;
  3114. case BfHotDepDataKind_VirtualDecl:
  3115. delete (BfHotVirtualDeclaration*)this;
  3116. break;
  3117. default:
  3118. BF_FATAL("Not handled");
  3119. }
  3120. }
  3121. }
  3122. void BfHotMethod::Clear(bool keepDupMethods)
  3123. {
  3124. if (mPrevVersion != NULL)
  3125. {
  3126. mPrevVersion->Deref();
  3127. mPrevVersion = NULL;
  3128. }
  3129. if (mSrcTypeVersion != NULL)
  3130. {
  3131. mSrcTypeVersion->Deref();
  3132. mSrcTypeVersion = NULL;
  3133. }
  3134. if ((keepDupMethods) && ((mFlags & BfHotDepDataFlag_HasDup) != 0))
  3135. {
  3136. int writeIdx = 0;
  3137. for (int i = 0; i < (int)mReferences.size(); i++)
  3138. {
  3139. auto depData = mReferences[i];
  3140. if (depData->mDataKind == BfHotDepDataKind_DupMethod)
  3141. {
  3142. mReferences[writeIdx++] = depData;
  3143. }
  3144. else
  3145. {
  3146. depData->Deref();
  3147. }
  3148. }
  3149. mReferences.mSize = writeIdx;
  3150. }
  3151. else
  3152. {
  3153. for (auto depData : mReferences)
  3154. {
  3155. depData->Deref();
  3156. }
  3157. mReferences.Clear();
  3158. }
  3159. }
  3160. BfHotMethod::~BfHotMethod()
  3161. {
  3162. Clear();
  3163. }
  3164. //////////////////////////////////////////////////////////////////////////
  3165. #pragma warning(disable:4146)
  3166. // Only 63 chars - skip zero
  3167. static const char cHash64bToChar[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
  3168. 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F',
  3169. 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
  3170. 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '_' };
  3171. String BfTypeUtils::HashEncode64(uint64 val)
  3172. {
  3173. String outStr;
  3174. if ((int64)val < 0)
  3175. {
  3176. uint64 flippedNum = (uint64)-(int64)val;
  3177. // Only flip if the encoded result would actually be shorter
  3178. if (flippedNum <= 0x00FFFFFFFFFFFFFFLL)
  3179. {
  3180. val = flippedNum;
  3181. outStr.Append('_');
  3182. }
  3183. }
  3184. for (int i = 0; i < 10; i++)
  3185. {
  3186. int charIdx = (int)((val >> (i * 6)) & 0x3F) - 1;
  3187. if (charIdx != -1)
  3188. outStr.Append(cHash64bToChar[charIdx]);
  3189. }
  3190. return outStr;
  3191. }
  3192. void BfTypeUtils::GetProjectList(BfType* checkType, Array<BfProject*>* projectList, int immutableLength)
  3193. {
  3194. if (checkType->IsBoxed())
  3195. GetProjectList(((BfBoxedType*)checkType)->mElementType, projectList, immutableLength);
  3196. BfTypeInstance* typeInst = checkType->ToTypeInstance();
  3197. if (typeInst != NULL)
  3198. {
  3199. auto genericTypeInst = typeInst->ToGenericTypeInstance();
  3200. if (genericTypeInst != NULL)
  3201. {
  3202. for (auto genericArg : genericTypeInst->mTypeGenericArguments)
  3203. GetProjectList(genericArg, projectList, immutableLength);
  3204. }
  3205. BfProject* bfProject = typeInst->mTypeDef->mProject;
  3206. if (std::find(projectList->begin(), projectList->end(), bfProject) == projectList->end())
  3207. {
  3208. bool handled = false;
  3209. for (int idx = 0; idx < (int)projectList->size(); idx++)
  3210. {
  3211. auto checkProject = (*projectList)[idx];
  3212. bool isBetter = bfProject->ContainsReference(checkProject);
  3213. bool isWorse = checkProject->ContainsReference(bfProject);
  3214. if (isBetter == isWorse)
  3215. continue;
  3216. if (isBetter)
  3217. {
  3218. if (idx >= immutableLength)
  3219. {
  3220. // This is even more specific, so replace with this one
  3221. (*projectList)[idx] = bfProject;
  3222. handled = true;
  3223. }
  3224. }
  3225. else
  3226. {
  3227. // This is less specific, ignore
  3228. handled = true;
  3229. }
  3230. break;
  3231. }
  3232. if (!handled)
  3233. {
  3234. projectList->push_back(bfProject);
  3235. }
  3236. }
  3237. }
  3238. else if (checkType->IsPointer())
  3239. GetProjectList(((BfPointerType*)checkType)->mElementType, projectList, immutableLength);
  3240. else if (checkType->IsRef())
  3241. GetProjectList(((BfPointerType*)checkType)->mElementType, projectList, immutableLength);
  3242. else if (checkType->IsSizedArray())
  3243. GetProjectList(((BfSizedArrayType*)checkType)->mElementType, projectList, immutableLength);
  3244. else if (checkType->IsMethodRef())
  3245. GetProjectList(((BfMethodRefType*)checkType)->mOwner, projectList, immutableLength);
  3246. }
  3247. BfPrimitiveType* BfTypeUtils::GetPrimitiveType(BfModule* module, BfTypeCode typeCode)
  3248. {
  3249. return module->GetPrimitiveType(typeCode);
  3250. }
  3251. void BfTypeUtils::PopulateType(BfModule* module, BfType* type)
  3252. {
  3253. module->PopulateType(type);
  3254. }
  3255. String BfTypeUtils::TypeToString(BfTypeReference* typeRef)
  3256. {
  3257. if (auto typeDefTypeRef = BfNodeDynCast<BfDirectTypeDefReference>(typeRef))
  3258. {
  3259. if (!typeDefTypeRef->mTypeDef->mNamespace.IsEmpty())
  3260. return typeDefTypeRef->mTypeDef->mNamespace.ToString() + "." + typeDefTypeRef->mTypeDef->mName->mString;
  3261. else
  3262. return String(typeDefTypeRef->mTypeDef->mName->mString);
  3263. }
  3264. if (typeRef->IsNamedTypeReference())
  3265. {
  3266. return typeRef->ToString();
  3267. }
  3268. if (auto ptrType = BfNodeDynCast<BfPointerTypeRef>(typeRef))
  3269. return TypeToString(ptrType->mElementType) + "*";
  3270. if (auto boxedType = BfNodeDynCast<BfBoxedTypeRef>(typeRef))
  3271. return "boxed " + TypeToString(boxedType->mElementType);
  3272. if (auto ptrType = BfNodeDynCast<BfArrayTypeRef>(typeRef))
  3273. {
  3274. String name = TypeToString(ptrType->mElementType) + "[";
  3275. for (int i = 1; i < ptrType->mDimensions; i++)
  3276. name += ",";
  3277. name += "]";
  3278. return name;
  3279. }
  3280. if (auto genericInstanceType = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef))
  3281. {
  3282. String name = TypeToString(genericInstanceType->mElementType);
  3283. name += "<";
  3284. for (int i = 0; i < (int)genericInstanceType->mGenericArguments.size(); i++)
  3285. {
  3286. if (i > 0)
  3287. name += ", ";
  3288. name += TypeToString(genericInstanceType->mGenericArguments[i]);
  3289. }
  3290. name += ">";
  3291. return name;
  3292. }
  3293. if (auto genericParamTypeRef = BfNodeDynCast<BfGenericParamTypeRef>(typeRef))
  3294. {
  3295. if (genericParamTypeRef->mGenericParamKind == BfGenericParamKind_Method)
  3296. return StrFormat("@M%d", genericParamTypeRef->mGenericParamIdx);
  3297. return StrFormat("@T%d", genericParamTypeRef->mGenericParamIdx);
  3298. }
  3299. if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(typeRef))
  3300. {
  3301. return TypeToString(qualifiedTypeRef->mLeft) + "." + TypeToString(qualifiedTypeRef->mRight);
  3302. }
  3303. if (auto refTypeRef = BfNodeDynCast<BfRefTypeRef>(typeRef))
  3304. {
  3305. return ((refTypeRef->mRefToken->GetToken() == BfToken_Out) ? "out " : "ref ") +
  3306. TypeToString(refTypeRef->mElementType);
  3307. }
  3308. if (auto directStrTypeName = BfNodeDynCast<BfDirectStrTypeReference>(typeRef))
  3309. return directStrTypeName->mTypeName;
  3310. BF_FATAL("Not implemented");
  3311. return "???";
  3312. }
  3313. String BfTypeUtils::TypeToString(BfTypeDef* typeDef, BfTypeNameFlags typeNameFlags)
  3314. {
  3315. String str;
  3316. TypeToString(str, typeDef, typeNameFlags);
  3317. return str;
  3318. }
  3319. bool BfTypeUtils::TypeToString(StringImpl& str, BfTypeDef* typeDef, BfTypeNameFlags typeNameFlags)
  3320. {
  3321. auto checkTypeDef = typeDef;
  3322. bool needsDot = false;
  3323. if (checkTypeDef->mOuterType != NULL)
  3324. {
  3325. if (TypeToString(str, checkTypeDef->mOuterType, typeNameFlags))
  3326. {
  3327. needsDot = true;
  3328. }
  3329. }
  3330. else
  3331. {
  3332. if (((typeNameFlags & BfTypeNameFlag_OmitNamespace) == 0) && (!typeDef->mNamespace.IsEmpty()))
  3333. {
  3334. typeDef->mNamespace.ToString(str);
  3335. needsDot = true;
  3336. }
  3337. }
  3338. if (((typeNameFlags & BfTypeNameFlag_HideGlobalName) != 0) && (typeDef->IsGlobalsContainer()))
  3339. return false;
  3340. if (needsDot)
  3341. str += ".";
  3342. typeDef->mName->ToString(str);
  3343. if (typeDef->mGenericParamDefs.size() != 0)
  3344. {
  3345. int prevGenericParamCount = 0;
  3346. if (checkTypeDef->mOuterType != NULL)
  3347. prevGenericParamCount = (int)typeDef->mOuterType->mGenericParamDefs.size();
  3348. if (prevGenericParamCount != (int)checkTypeDef->mGenericParamDefs.size())
  3349. {
  3350. str += "<";
  3351. for (int i = prevGenericParamCount; i < (int)checkTypeDef->mGenericParamDefs.size(); i++)
  3352. {
  3353. if ((typeNameFlags & BfTypeNameFlag_InternalName) != 0)
  3354. {
  3355. if (i > prevGenericParamCount)
  3356. str += ",";
  3357. }
  3358. else
  3359. {
  3360. if (i > prevGenericParamCount)
  3361. str += ", ";
  3362. str += checkTypeDef->mGenericParamDefs[i]->mName;
  3363. }
  3364. }
  3365. str += ">";
  3366. }
  3367. }
  3368. return true;
  3369. }
  3370. int BfTypeUtils::GetSplatCount(BfType* type)
  3371. {
  3372. int splatCount = 0;
  3373. SplatIterate([&](BfType* checkType) { splatCount++; }, type);
  3374. return splatCount;
  3375. }