BfResolvedTypeUtils.cpp 167 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881
  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 "CeMachine.h"
  9. #include "BeefySysLib/util/BeefPerf.h"
  10. #pragma warning(disable:4996)
  11. #pragma warning(disable:4267)
  12. USING_NS_BF;
  13. //void Beefy::DbgCheckType(llvm::Type* checkType)
  14. //{
  15. //#ifdef _DEBUG
  16. // /*while (auto ptrType = llvm::dyn_cast<llvm::PointerType>(checkType))
  17. // {
  18. // checkType = ptrType->getElementType();
  19. // }
  20. //
  21. // auto structType = llvm::dyn_cast<llvm::StructType>(checkType);
  22. // if (structType != NULL)
  23. // {
  24. // auto stringRef = structType->getName();
  25. // BF_ASSERT(strncmp(stringRef.data(), "DEAD", 4) != 0);
  26. // }*/
  27. //#endif
  28. //}
  29. void BfTypedValue::DbgCheckType() const
  30. {
  31. /*if (mType != NULL)
  32. {
  33. auto structType = llvm::dyn_cast<llvm::StructType>(mType->mIRType);
  34. if (structType != NULL)
  35. {
  36. auto stringRef = structType->getName();
  37. BF_ASSERT(strncmp(stringRef.data(), "DEAD", 4) != 0);
  38. }
  39. }*/
  40. #ifdef _DEBUG
  41. /*if (mValue != NULL)
  42. {
  43. auto checkType = mValue->getType();
  44. Beefy::DbgCheckType(checkType);
  45. }*/
  46. #endif
  47. }
  48. bool BfTypedValue::IsValuelessType() const
  49. {
  50. return mType->IsValuelessType();
  51. }
  52. bool BfTypedValue::CanModify() const
  53. {
  54. return (((IsAddr()) || (mType->IsValuelessType())) && (!IsReadOnly()));
  55. }
  56. //////////////////////////////////////////////////////////////////////////
  57. BfProtection BfUsingFieldData::MemberRef::GetProtection() const
  58. {
  59. switch (mKind)
  60. {
  61. case Kind_Field:
  62. return mTypeInstance->mTypeDef->mFields[mIdx]->mProtection;
  63. case Kind_Property:
  64. return mTypeInstance->mTypeDef->mProperties[mIdx]->mProtection;
  65. case Kind_Method:
  66. return mTypeInstance->mTypeDef->mMethods[mIdx]->mProtection;
  67. }
  68. return BfProtection_Public;
  69. }
  70. BfProtection BfUsingFieldData::MemberRef::GetUsingProtection() const
  71. {
  72. switch (mKind)
  73. {
  74. case Kind_Field:
  75. return mTypeInstance->mTypeDef->mFields[mIdx]->mUsingProtection;
  76. case Kind_Property:
  77. return mTypeInstance->mTypeDef->mProperties[mIdx]->mUsingProtection;
  78. case Kind_Method:
  79. return mTypeInstance->mTypeDef->mMethods[mIdx]->mProtection;
  80. }
  81. return BfProtection_Public;
  82. }
  83. BfTypeDef* BfUsingFieldData::MemberRef::GetDeclaringType(BfModule* curModule) const
  84. {
  85. switch (mKind)
  86. {
  87. case Kind_Field:
  88. return mTypeInstance->mTypeDef->mFields[mIdx]->mDeclaringType;
  89. case Kind_Property:
  90. return mTypeInstance->mTypeDef->mProperties[mIdx]->mDeclaringType;
  91. case Kind_Method:
  92. return mTypeInstance->mTypeDef->mMethods[mIdx]->mDeclaringType;
  93. case Kind_Local:
  94. return curModule->GetActiveTypeDef();
  95. }
  96. return NULL;
  97. }
  98. String BfUsingFieldData::MemberRef::GetFullName(BfModule* curModule) const
  99. {
  100. if (mKind == Kind_Local)
  101. return curModule->mCurMethodState->mLocals[mIdx]->mName;
  102. String result = curModule->TypeToString(mTypeInstance);
  103. if (!result.IsEmpty())
  104. result += ".";
  105. switch (mKind)
  106. {
  107. case Kind_Field:
  108. result += mTypeInstance->mTypeDef->mFields[mIdx]->mName;
  109. break;
  110. case Kind_Property:
  111. result += mTypeInstance->mTypeDef->mProperties[mIdx]->mName;
  112. break;
  113. case Kind_Method:
  114. result += mTypeInstance->mTypeDef->mMethods[mIdx]->mName;
  115. break;
  116. }
  117. return result;
  118. }
  119. String BfUsingFieldData::MemberRef::GetName(BfModule* curModule) const
  120. {
  121. switch (mKind)
  122. {
  123. case Kind_Field:
  124. return mTypeInstance->mTypeDef->mFields[mIdx]->mName;
  125. case Kind_Property:
  126. return mTypeInstance->mTypeDef->mProperties[mIdx]->mName;
  127. case Kind_Method:
  128. {
  129. auto methodInstance = curModule->GetRawMethodInstance(mTypeInstance, mTypeInstance->mTypeDef->mMethods[mIdx]);
  130. return curModule->MethodToString(methodInstance, BfMethodNameFlag_OmitTypeName);
  131. }
  132. case Kind_Local:
  133. return curModule->mCurMethodState->mLocals[mIdx]->mName;
  134. }
  135. return "";
  136. }
  137. BfAstNode* BfUsingFieldData::MemberRef::GetRefNode(BfModule* curModule) const
  138. {
  139. switch (mKind)
  140. {
  141. case Kind_Field:
  142. return mTypeInstance->mTypeDef->mFields[mIdx]->GetRefNode();
  143. case Kind_Property:
  144. return mTypeInstance->mTypeDef->mProperties[mIdx]->GetRefNode();
  145. case Kind_Method:
  146. return mTypeInstance->mTypeDef->mMethods[mIdx]->GetRefNode();
  147. case Kind_Local:
  148. return curModule->mCurMethodState->mLocals[mIdx]->mNameNode;
  149. }
  150. return NULL;
  151. }
  152. bool BfUsingFieldData::MemberRef::IsStatic() const
  153. {
  154. switch (mKind)
  155. {
  156. case Kind_Field:
  157. return mTypeInstance->mTypeDef->mFields[mIdx]->mIsStatic;
  158. case Kind_Property:
  159. return mTypeInstance->mTypeDef->mProperties[mIdx]->mIsStatic;
  160. case Kind_Method:
  161. return mTypeInstance->mTypeDef->mMethods[mIdx]->mIsStatic;
  162. }
  163. return false;
  164. }
  165. //////////////////////////////////////////////////////////////////////////
  166. bool BfGenericParamInstance::IsEnum()
  167. {
  168. if ((mGenericParamFlags & BfGenericParamFlag_Enum) != 0)
  169. return true;
  170. if (mTypeConstraint != NULL)
  171. {
  172. auto module = mTypeConstraint->GetModule();
  173. if ((module != NULL) && (mTypeConstraint->IsInstanceOf(module->mCompiler->mEnumTypeDef)))
  174. return true;
  175. }
  176. return true;
  177. return false;
  178. }
  179. //////////////////////////////////////////////////////////////////////////
  180. bool BfDependencyMap::AddUsedBy(BfType* dependentType, BfDependencyMap::DependencyFlags flags)
  181. {
  182. BF_ASSERT(dependentType != NULL);
  183. BF_ASSERT(dependentType->mRevision != -1);
  184. //auto itr = mTypeSet.insert(BfDependencyMap::TypeMap::value_type(dependentType, DependencyEntry(dependentType->mRevision, flags)));
  185. //if (!itr.second)
  186. DependencyEntry* dependencyEntry = NULL;
  187. if (mTypeSet.TryAddRaw(dependentType, NULL, &dependencyEntry))
  188. {
  189. if ((flags & ~DependencyFlag_UnspecializedType) != 0)
  190. {
  191. if (auto dependentDepType = dependentType->ToDependedType())
  192. {
  193. int tryDepth = dependentDepType->mDependencyMap.mMinDependDepth + 1;
  194. if (tryDepth < mMinDependDepth)
  195. mMinDependDepth = tryDepth;
  196. }
  197. }
  198. dependencyEntry->mRevision = dependentType->mRevision;
  199. dependencyEntry->mFlags = flags;
  200. return true;
  201. }
  202. else
  203. {
  204. if (dependencyEntry->mRevision != dependentType->mRevision)
  205. {
  206. dependencyEntry->mRevision = dependentType->mRevision;
  207. dependencyEntry->mFlags = flags;
  208. return true;
  209. }
  210. else
  211. {
  212. if ((dependencyEntry->mFlags & flags) == flags)
  213. return false;
  214. dependencyEntry->mFlags = (DependencyFlags)(dependencyEntry->mFlags | flags);
  215. return true;
  216. }
  217. }
  218. }
  219. bool BfDependencyMap::IsEmpty()
  220. {
  221. return mTypeSet.size() == 0;
  222. }
  223. BfDependencyMap::TypeMap::iterator BfDependencyMap::begin()
  224. {
  225. return mTypeSet.begin();
  226. }
  227. BfDependencyMap::TypeMap::iterator BfDependencyMap::end()
  228. {
  229. return mTypeSet.end();
  230. }
  231. BfDependencyMap::TypeMap::iterator BfDependencyMap::erase(BfDependencyMap::TypeMap::iterator& itr)
  232. {
  233. return mTypeSet.Remove(itr);
  234. }
  235. //////////////////////////////////////////////////////////////////////////
  236. BfFieldDef* BfFieldInstance::GetFieldDef()
  237. {
  238. if (mFieldIdx == -1)
  239. return NULL;
  240. return mOwner->mTypeDef->mFields[mFieldIdx];
  241. }
  242. //////////////////////////////////////////////////////////////////////////
  243. BfType::BfType()
  244. {
  245. mTypeId = -1;
  246. mContext = NULL;
  247. mRevision = -1;
  248. //mLastUsedRevision = -1;
  249. mDefineState = BfTypeDefineState_Undefined;
  250. //mDICallbackVH = NULL;
  251. //mInnerDICallbackVH = NULL;
  252. mRebuildFlags = BfTypeRebuildFlag_None;
  253. mAlign = -1;
  254. mSize = -1;
  255. //mDICallbackVH = NULL;
  256. //mInnerDICallbackVH = NULL;
  257. mDirty = true;
  258. }
  259. BfModule* BfType::GetModule()
  260. {
  261. if (mContext->mCompiler->mOptions.mCompileOnDemandKind == BfCompileOnDemandKind_AlwaysInclude)
  262. return mContext->mScratchModule;
  263. else
  264. return mContext->mUnreifiedModule;
  265. }
  266. BfTypeInstance* BfType::FindUnderlyingTypeInstance()
  267. {
  268. auto typeInstance = ToTypeInstance();
  269. if (typeInstance != NULL)
  270. return typeInstance;
  271. auto underlyingType = GetUnderlyingType();
  272. while (underlyingType != NULL)
  273. {
  274. auto underlyingTypeInst = underlyingType->ToTypeInstance();
  275. if (underlyingTypeInst != NULL)
  276. return underlyingTypeInst;
  277. underlyingType = underlyingType->GetUnderlyingType();
  278. }
  279. return NULL;
  280. }
  281. void BfType::ReportMemory(MemReporter* memReporter)
  282. {
  283. memReporter->Add(sizeof(BfType));
  284. }
  285. //////////////////////////////////////////////////////////////////////////
  286. BfNonGenericMethodRef::BfNonGenericMethodRef(BfMethodInstance* methodInstance)
  287. {
  288. *this = methodInstance;
  289. }
  290. BfNonGenericMethodRef::operator BfMethodInstance* () const
  291. {
  292. if (mTypeInstance == NULL)
  293. return NULL;
  294. if (mMethodNum < 0)
  295. return NULL;
  296. auto& methodSpecializationGroup = mTypeInstance->mMethodInstanceGroups[mMethodNum];
  297. BF_ASSERT((methodSpecializationGroup.mDefault != NULL) || (mTypeInstance->mTypeFailed));
  298. return methodSpecializationGroup.mDefault;
  299. }
  300. BfMethodInstance* BfNonGenericMethodRef::operator->() const
  301. {
  302. return *this;
  303. }
  304. BfNonGenericMethodRef& BfNonGenericMethodRef::operator=(BfMethodInstance* methodInstance)
  305. {
  306. if (methodInstance == NULL)
  307. {
  308. mTypeInstance = NULL;
  309. mMethodNum = 0;
  310. }
  311. else
  312. {
  313. mTypeInstance = methodInstance->mMethodInstanceGroup->mOwner;
  314. mMethodNum = methodInstance->mMethodInstanceGroup->mMethodIdx;
  315. BF_ASSERT((methodInstance->GetNumGenericArguments() == 0) ||
  316. ((methodInstance->mIsUnspecialized) && (!methodInstance->mIsUnspecializedVariation)));
  317. mSignatureHash = (int)mTypeInstance->mTypeDef->mSignatureHash;
  318. }
  319. return *this;
  320. }
  321. bool BfNonGenericMethodRef::operator==(const BfNonGenericMethodRef& methodRef) const
  322. {
  323. bool eq = ((methodRef.mKind == mKind) &&
  324. (methodRef.mTypeInstance == mTypeInstance) &&
  325. (methodRef.mMethodNum == mMethodNum));
  326. if (eq)
  327. {
  328. BF_ASSERT((methodRef.mSignatureHash == mSignatureHash) || (methodRef.mSignatureHash == 0) || (mSignatureHash == 0));
  329. }
  330. return eq;
  331. }
  332. bool BfNonGenericMethodRef::operator==(BfMethodInstance* methodInstance) const
  333. {
  334. if (mTypeInstance != methodInstance->GetOwner())
  335. return false;
  336. return methodInstance == (BfMethodInstance*)*this;
  337. }
  338. size_t BfNonGenericMethodRef::Hash::operator()(const BfNonGenericMethodRef& val) const
  339. {
  340. return (val.mTypeInstance->mTypeId << 10) ^ val.mMethodNum;
  341. }
  342. //////////////////////////////////////////////////////////////////////////
  343. BfMethodRef::BfMethodRef(BfMethodInstance* methodInstance)
  344. {
  345. *this = methodInstance;
  346. }
  347. BfMethodRef::operator BfMethodInstance* () const
  348. {
  349. if (mTypeInstance == NULL)
  350. return NULL;
  351. if (mMethodNum < 0)
  352. return NULL;
  353. auto& methodSpecializationGroup = mTypeInstance->mMethodInstanceGroups[mMethodNum];
  354. if (mMethodGenericArguments.size() != 0)
  355. {
  356. bool isSpecialied = false;
  357. int paramIdx = 0;
  358. for (auto genericArg : mMethodGenericArguments)
  359. {
  360. if (!genericArg->IsGenericParam())
  361. {
  362. isSpecialied = true;
  363. break;
  364. }
  365. auto genericParam = (BfGenericParamType*)genericArg;
  366. if ((genericParam->mGenericParamKind != BfGenericParamKind_Method) || (genericParam->mGenericParamIdx != paramIdx))
  367. {
  368. isSpecialied = true;
  369. break;
  370. }
  371. paramIdx++;
  372. }
  373. if (isSpecialied)
  374. {
  375. BfMethodInstance** methodInstancePtr = NULL;
  376. if (methodSpecializationGroup.mMethodSpecializationMap->TryGetValue(mMethodGenericArguments, &methodInstancePtr))
  377. return *methodInstancePtr;
  378. return NULL;
  379. }
  380. }
  381. BF_ASSERT(methodSpecializationGroup.mDefault != NULL);
  382. return methodSpecializationGroup.mDefault;
  383. }
  384. BfMethodInstance* BfMethodRef::operator->() const
  385. {
  386. return *this;
  387. }
  388. BfMethodRef& BfMethodRef::operator=(BfMethodInstance* methodInstance)
  389. {
  390. if (methodInstance == NULL)
  391. {
  392. mTypeInstance = NULL;
  393. mMethodNum = 0;
  394. mMethodRefFlags = BfMethodRefFlag_None;
  395. }
  396. else
  397. {
  398. mTypeInstance = methodInstance->mMethodInstanceGroup->mOwner;
  399. mMethodNum = methodInstance->mMethodInstanceGroup->mMethodIdx;
  400. if (methodInstance->mMethodInfoEx != NULL)
  401. {
  402. mMethodGenericArguments.Clear();
  403. for (auto type : methodInstance->mMethodInfoEx->mMethodGenericArguments)
  404. mMethodGenericArguments.Add(type);
  405. }
  406. mSignatureHash = (int)mTypeInstance->mTypeDef->mSignatureHash;
  407. if (methodInstance->mAlwaysInline)
  408. mMethodRefFlags = BfMethodRefFlag_AlwaysInclude;
  409. else
  410. mMethodRefFlags = BfMethodRefFlag_None;
  411. }
  412. return *this;
  413. }
  414. bool BfMethodRef::operator==(const BfMethodRef& methodRef) const
  415. {
  416. bool eq = ((methodRef.mKind == mKind) &&
  417. (methodRef.mTypeInstance == mTypeInstance) &&
  418. (methodRef.mMethodNum == mMethodNum) &&
  419. (methodRef.mMethodGenericArguments == mMethodGenericArguments) &&
  420. (methodRef.mMethodRefFlags == mMethodRefFlags));
  421. if (eq)
  422. {
  423. BF_ASSERT((methodRef.mSignatureHash == mSignatureHash) || (methodRef.mSignatureHash == 0) || (mSignatureHash == 0));
  424. }
  425. return eq;
  426. }
  427. bool BfMethodRef::operator==(BfMethodInstance* methodInstance) const
  428. {
  429. if (mTypeInstance != methodInstance->GetOwner())
  430. return false;
  431. return methodInstance == (BfMethodInstance*)*this;
  432. }
  433. size_t BfMethodRef::Hash::operator()(const BfMethodRef& val) const
  434. {
  435. return (val.mTypeInstance->mTypeId << 10) ^ (val.mMethodNum << 1) ^ (int)(val.mMethodRefFlags);
  436. }
  437. //////////////////////////////////////////////////////////////////////////
  438. BfFieldRef::BfFieldRef(BfTypeInstance* typeInst, BfFieldDef* fieldDef)
  439. {
  440. mTypeInstance = typeInst;
  441. mFieldIdx = fieldDef->mIdx;
  442. }
  443. BfFieldRef::BfFieldRef(BfFieldInstance* fieldInstance)
  444. {
  445. mTypeInstance = fieldInstance->mOwner;
  446. mFieldIdx = fieldInstance->mFieldIdx;
  447. }
  448. BfFieldRef::operator BfFieldInstance*() const
  449. {
  450. BF_ASSERT(!mTypeInstance->IsDataIncomplete());
  451. return &mTypeInstance->mFieldInstances[mFieldIdx];
  452. }
  453. BfFieldRef::operator BfFieldDef*() const
  454. {
  455. return mTypeInstance->mTypeDef->mFields[mFieldIdx];
  456. }
  457. //////////////////////////////////////////////////////////////////////////
  458. BfPropertyRef::BfPropertyRef(BfTypeInstance* typeInst, BfPropertyDef* propDef)
  459. {
  460. mTypeInstance = typeInst;
  461. mPropIdx = propDef->mIdx;
  462. }
  463. BfPropertyRef::operator BfPropertyDef*() const
  464. {
  465. return mTypeInstance->mTypeDef->mProperties[mPropIdx];
  466. }
  467. //////////////////////////////////////////////////////////////////////////
  468. /*BfMethodInstance* BfTypeInstance::GetVTableMethodInstance(int vtableIdx)
  469. {
  470. auto& methodSpecializationGroup = mVirtualMethodTable[vtableIdx].mTypeInstance->mMethodInstanceGroups[mVirtualMethodTable[vtableIdx].mMethodNum];
  471. return &methodSpecializationGroup.mMethodSpecializationMap.begin()->second;
  472. }*/
  473. static int gDelIdx = 0;
  474. BfType::~BfType()
  475. {
  476. if (mContext != NULL)
  477. BfLogSys(mContext->mSystem, "~BfType %p\n", this);
  478. /*gDelIdx++;
  479. auto typeInst = ToTypeInstance();
  480. OutputDebugStrF("%d Deleting %08X type %s\n", gDelIdx, this, (typeInst != NULL) ? typeInst->mTypeDef->mName.c_str() : "");*/
  481. //delete mDICallbackVH;
  482. //delete mInnerDICallbackVH;
  483. }
  484. BfFieldInstance::~BfFieldInstance()
  485. {
  486. delete mCustomAttributes;
  487. }
  488. BfType* BfFieldInstance::GetResolvedType()
  489. {
  490. return mResolvedType;
  491. }
  492. void BfFieldInstance::SetResolvedType(BfType* type)
  493. {
  494. mResolvedType = type;
  495. }
  496. void BfFieldInstance::GetDataRange(int& dataIdx, int& dataCount)
  497. {
  498. int minMergedDataIdx = mMergedDataIdx;
  499. int maxMergedDataIdx = minMergedDataIdx + 1;
  500. if (mResolvedType->IsStruct())
  501. maxMergedDataIdx = minMergedDataIdx + mResolvedType->ToTypeInstance()->mMergedFieldDataCount;
  502. if (mOwner->mIsUnion)
  503. {
  504. for (auto& checkFieldInstance : mOwner->mFieldInstances)
  505. {
  506. if (&checkFieldInstance == this)
  507. continue;
  508. if (checkFieldInstance.mDataIdx == mDataIdx)
  509. {
  510. int checkMinMergedDataIdx = checkFieldInstance.mMergedDataIdx;
  511. int checkMaxMergedDataIdx = checkMinMergedDataIdx + 1;
  512. if (checkFieldInstance.GetResolvedType()->IsStruct())
  513. checkMaxMergedDataIdx = checkMinMergedDataIdx + checkFieldInstance.mResolvedType->ToTypeInstance()->mMergedFieldDataCount;
  514. minMergedDataIdx = BF_MIN(minMergedDataIdx, checkMinMergedDataIdx);
  515. maxMergedDataIdx = BF_MAX(maxMergedDataIdx, checkMaxMergedDataIdx);
  516. }
  517. }
  518. }
  519. int fieldIdx = dataIdx - 1;
  520. if (fieldIdx == -1)
  521. {
  522. dataIdx = minMergedDataIdx + 1;
  523. }
  524. else
  525. {
  526. fieldIdx += minMergedDataIdx;
  527. dataIdx = fieldIdx + 1;
  528. }
  529. dataCount = maxMergedDataIdx - minMergedDataIdx;
  530. }
  531. int BfFieldInstance::GetAlign(int packing)
  532. {
  533. int align = mResolvedType->mAlign;
  534. if (IsAppendedObject())
  535. align = mResolvedType->ToTypeInstance()->mInstAlign;
  536. if (packing > 0)
  537. align = BF_MIN(align, packing);
  538. if (mCustomAttributes != NULL)
  539. {
  540. auto module = mOwner->mModule;
  541. for (auto& attrib : mCustomAttributes->mAttributes)
  542. {
  543. if (attrib.mType->IsInstanceOf(module->mCompiler->mAlignAttributeTypeDef))
  544. {
  545. align = 16; // System conservative default
  546. if (!attrib.mCtorArgs.IsEmpty())
  547. {
  548. BfIRConstHolder* constHolder = module->mCurTypeInstance->mConstHolder;
  549. auto constant = constHolder->GetConstant(attrib.mCtorArgs[0]);
  550. if (constant != NULL)
  551. {
  552. int alignOverride = (int)BF_MAX(1, constant->mInt64);
  553. if ((alignOverride & (alignOverride - 1)) == 0)
  554. align = alignOverride;
  555. else
  556. module->Fail("Alignment must be a power of 2", attrib.GetRefNode());
  557. }
  558. }
  559. }
  560. }
  561. }
  562. return align;
  563. }
  564. bool BfFieldInstance::IsAppendedObject()
  565. {
  566. auto fieldDef = GetFieldDef();
  567. return (fieldDef != NULL) && (fieldDef->mIsAppend) && (mResolvedType->IsObject()) && (mOwner->IsObject());
  568. }
  569. //////////////////////////////////////////////////////////////////////////
  570. int64 BfDeferredMethodCallData::GenerateMethodId(BfModule* module, int64 methodId)
  571. {
  572. // The mMethodId MUST be unique within a given deferred method processor. We are even more conservative, making it
  573. // unique per module
  574. if (module->mDeferredMethodIds.Add(methodId))
  575. {
  576. return methodId;
  577. }
  578. else
  579. {
  580. // Ideally the passed in methodId just works, otherwise --
  581. // We hope to create a hash that will hopefully be globally unique. If it isn't then it just means we will end up with two
  582. // conflicting debug info definitions for the same name, which is not an error but may cause a debugger to show the
  583. // wrong one to the user. Does not affect runtime correctness.
  584. int64 checkId = Hash64(module->mModuleName.c_str(), (int)module->mModuleName.length(), module->mDeferredMethodIds.size());
  585. while (true)
  586. {
  587. if (!module->mDeferredMethodIds.Contains(checkId))
  588. break;
  589. checkId += 0x100;
  590. }
  591. module->mDeferredMethodIds.Add(checkId);
  592. return checkId;
  593. }
  594. }
  595. //////////////////////////////////////////////////////////////////////////
  596. BfMethodCustomAttributes::~BfMethodCustomAttributes()
  597. {
  598. delete mCustomAttributes;
  599. delete mReturnCustomAttributes;
  600. for (auto paramCustomAttributes : mParamCustomAttributes)
  601. delete paramCustomAttributes;
  602. }
  603. BfMethodInstance* BfMethodParam::GetDelegateParamInvoke()
  604. {
  605. if (mResolvedType->IsMethodRef())
  606. {
  607. auto methodRefType = (BfMethodRefType*)mResolvedType;
  608. return methodRefType->mMethodRef;
  609. }
  610. else if (mResolvedType->IsTuple())
  611. return NULL;
  612. BF_ASSERT(mResolvedType->IsDelegate() || mResolvedType->IsFunction());
  613. auto bfModule = BfModule::GetModuleFor(mResolvedType);
  614. BfMethodInstance* invokeMethodInstance = bfModule->GetRawMethodInstanceAtIdx(mResolvedType->ToTypeInstance(), 0, "Invoke");
  615. return invokeMethodInstance;
  616. }
  617. BfMethodInfoEx::~BfMethodInfoEx()
  618. {
  619. for (auto genericParam : mGenericParams)
  620. genericParam->Release();
  621. delete mMethodCustomAttributes;
  622. delete mClosureInstanceInfo;
  623. }
  624. BfMethodInstance::~BfMethodInstance()
  625. {
  626. Dispose(true);
  627. if (mHasMethodRefType)
  628. {
  629. auto module = GetOwner()->mModule;
  630. if (!module->mContext->mDeleting)
  631. {
  632. auto methodRefType = module->CreateMethodRefType(this);
  633. module->mContext->DeleteType(methodRefType);
  634. }
  635. }
  636. delete mMethodInfoEx;
  637. }
  638. void BfMethodInstance::Dispose(bool isDeleting)
  639. {
  640. if (mIsDisposed)
  641. return;
  642. mIsDisposed = true;
  643. if (mMethodInstanceGroup != NULL)
  644. {
  645. BfLogSys(GetOwner()->mModule->mSystem, "BfMethodInstance::~BfMethodInstance %p Local:%d InCEMachine:%d Deleting:%d\n", this, mMethodDef->mIsLocalMethod, mInCEMachine, isDeleting);
  646. }
  647. else
  648. {
  649. BF_ASSERT(!mMethodDef->mIsLocalMethod);
  650. }
  651. if (mInCEMachine)
  652. {
  653. auto module = GetOwner()->mModule;
  654. if (module->mCompiler->mCeMachine != NULL)
  655. module->mCompiler->mCeMachine->RemoveMethod(this);
  656. }
  657. if (mMethodProcessRequest != NULL)
  658. {
  659. BF_ASSERT(mMethodProcessRequest->mMethodInstance == this);
  660. mMethodProcessRequest->mMethodInstance = NULL;
  661. }
  662. if (mHotMethod != NULL)
  663. {
  664. mHotMethod->mFlags = (BfHotDepDataFlags)(mHotMethod->mFlags & ~BfHotDepDataFlag_IsBound);
  665. mHotMethod->Deref();
  666. }
  667. }
  668. void BfMethodInstance::CopyFrom(BfMethodInstance* methodInstance)
  669. {
  670. *this = *methodInstance;
  671. if (mMethodInfoEx != NULL)
  672. {
  673. mMethodInfoEx = new BfMethodInfoEx();
  674. *mMethodInfoEx = *(methodInstance->mMethodInfoEx);
  675. for (auto genericParam : mMethodInfoEx->mGenericParams)
  676. genericParam->AddRef();
  677. mMethodInfoEx->mMethodCustomAttributes = NULL;
  678. if (mMethodInfoEx->mClosureInstanceInfo != NULL)
  679. {
  680. mMethodInfoEx->mClosureInstanceInfo = new BfClosureInstanceInfo();
  681. *mMethodInfoEx->mClosureInstanceInfo = *methodInstance->mMethodInfoEx->mClosureInstanceInfo;
  682. }
  683. }
  684. mHasMethodRefType = false;
  685. mHasBeenProcessed = false;
  686. mIRFunction = BfIRValue();
  687. mMethodProcessRequest = NULL;
  688. mHotMethod = NULL;
  689. }
  690. BfImportKind BfMethodInstance::GetImportKind()
  691. {
  692. if (mMethodDef->mImportKind != BfImportKind_Import_Unknown)
  693. return mMethodDef->mImportKind;
  694. auto module = GetOwner()->mModule;
  695. auto customAttributes = GetCustomAttributes();
  696. if (customAttributes == NULL)
  697. return BfImportKind_None;
  698. BfCustomAttribute* customAttribute = customAttributes->Get(module->mCompiler->mImportAttributeTypeDef);
  699. if (customAttribute == NULL)
  700. return BfImportKind_Import_Static;
  701. BfIRConstHolder* constHolder = GetOwner()->mConstHolder;
  702. String* filePath = module->GetStringPoolString(customAttribute->mCtorArgs[0], constHolder);
  703. if (filePath == NULL)
  704. return BfImportKind_Import_Static;
  705. return BfMethodDef::GetImportKindFromPath(*filePath);
  706. }
  707. BfMethodFlags BfMethodInstance::GetMethodFlags()
  708. {
  709. BfMethodFlags methodFlags = (BfMethodFlags)0;
  710. if (mMethodDef->mProtection == BfProtection_Protected)
  711. methodFlags = (BfMethodFlags)(methodFlags | BfMethodFlags_Protected);
  712. if (mMethodDef->mProtection == BfProtection_Public)
  713. methodFlags = (BfMethodFlags)(methodFlags | BfMethodFlags_Public);
  714. if (mMethodDef->mIsStatic)
  715. methodFlags = (BfMethodFlags)(methodFlags | BfMethodFlags_Static);
  716. if ((mMethodDef->mIsVirtual) || (mVirtualTableIdx != -1))
  717. methodFlags = (BfMethodFlags)(methodFlags | BfMethodFlags_Virtual);
  718. if (mMethodDef->mCallingConvention == BfCallingConvention_Fastcall)
  719. methodFlags = (BfMethodFlags)(methodFlags | BfMethodFlags_FastCall);
  720. if (mMethodDef->mIsMutating)
  721. methodFlags = (BfMethodFlags)(methodFlags | BfMethodFlags_Mutating);
  722. if (mMethodDef->mMethodType == BfMethodType_Ctor)
  723. methodFlags = (BfMethodFlags)(methodFlags | BfMethodFlags_Constructor);
  724. if (mMethodDef->mIsReadOnly)
  725. methodFlags = (BfMethodFlags)(methodFlags | BfMethodFlags_ReadOnly);
  726. if (mMethodDef->mMethodType == BfMethodType_Mixin)
  727. methodFlags = (BfMethodFlags)(methodFlags | BfMethodFlags_Mixin);
  728. auto callingConvention = GetOwner()->mModule->GetIRCallingConvention(this);
  729. if (callingConvention == BfIRCallingConv_ThisCall)
  730. methodFlags = (BfMethodFlags)(methodFlags | BfMethodFlags_ThisCall);
  731. else if (callingConvention == BfIRCallingConv_StdCall)
  732. methodFlags = (BfMethodFlags)(methodFlags | BfMethodFlags_StdCall);
  733. else if (callingConvention == BfIRCallingConv_FastCall)
  734. methodFlags = (BfMethodFlags)(methodFlags | BfMethodFlags_FastCall);
  735. methodFlags = (BfMethodFlags)(methodFlags | (mMethodDef->mAppendKind * BfMethodFlags_AppendBit0));
  736. methodFlags = (BfMethodFlags)(methodFlags | (mMethodDef->mCheckedKind * BfMethodFlags_CheckedBit0));
  737. return methodFlags;
  738. }
  739. BfComptimeMethodFlags BfMethodInstance::GetComptimeMethodFlags()
  740. {
  741. BfComptimeMethodFlags methodFlags = (BfComptimeMethodFlags)0;
  742. if (!mMethodDef->CanReflect())
  743. methodFlags = (BfComptimeMethodFlags)(methodFlags | BfComptimeMethodFlags_NoReflect);
  744. return methodFlags;
  745. }
  746. void BfMethodInstance::UndoDeclaration(bool keepIRFunction)
  747. {
  748. if (mMethodInfoEx != NULL)
  749. {
  750. for (auto genericParam : mMethodInfoEx->mGenericParams)
  751. genericParam->Release();
  752. mMethodInfoEx->mGenericParams.Clear();
  753. delete mMethodInfoEx->mMethodCustomAttributes;
  754. mMethodInfoEx->mMethodCustomAttributes = NULL;
  755. mMethodInfoEx->mGenericTypeBindings.Clear();
  756. }
  757. mReturnType = NULL;
  758. if (!keepIRFunction)
  759. mIRFunction = BfIRValue();
  760. mParams.Clear();
  761. mDefaultValues.Clear();
  762. if (mMethodProcessRequest != NULL)
  763. {
  764. BF_ASSERT(mMethodProcessRequest->mMethodInstance == this);
  765. mMethodProcessRequest->mMethodInstance = NULL;
  766. }
  767. mHasStartedDeclaration = false;
  768. mHasBeenDeclared = false;
  769. mHasBeenProcessed = false;
  770. mIsUnspecialized = false;
  771. mIsUnspecializedVariation = false;
  772. mDisallowCalling = false;
  773. mIsIntrinsic = false;
  774. mHasFailed = false;
  775. mFailedConstraints = false;
  776. }
  777. BfTypeInstance* BfMethodInstance::GetOwner()
  778. {
  779. return mMethodInstanceGroup->mOwner;
  780. }
  781. BfModule * BfMethodInstance::GetModule()
  782. {
  783. return mMethodInstanceGroup->mOwner->mModule;
  784. }
  785. bool BfMethodInstance::ForcingThisPtr()
  786. {
  787. if (mMethodDef->mHasExplicitThis)
  788. {
  789. auto thisType = mParams[0].mResolvedType;
  790. if (thisType->IsCRepr())
  791. return true;
  792. }
  793. else if (mMethodInstanceGroup->mOwner->IsCRepr())
  794. return true;
  795. return (mCallingConvention == BfCallingConvention_Cdecl);
  796. }
  797. bool Beefy::BfMethodInstance::IsSpecializedGenericMethod()
  798. {
  799. return (mMethodInfoEx != NULL) && (mMethodInfoEx->mGenericParams.size() != 0) && (!mIsUnspecialized);
  800. }
  801. bool Beefy::BfMethodInstance::IsSpecializedGenericMethodOrType()
  802. {
  803. if ((mMethodInfoEx != NULL) && (mMethodInfoEx->mGenericParams.size() != 0) && (!mIsUnspecialized))
  804. return true;
  805. auto owner = GetOwner();
  806. if (!owner->IsGenericTypeInstance())
  807. return false;
  808. BfTypeInstance* genericTypeInstance = (BfTypeInstance*)owner;
  809. return !genericTypeInstance->mGenericTypeInfo->mIsUnspecialized;
  810. }
  811. bool BfMethodInstance::IsSpecializedByAutoCompleteMethod()
  812. {
  813. if (mMethodInstanceGroup->mOwner->IsSpecializedByAutoCompleteMethod())
  814. return true;
  815. if (mMethodInfoEx != NULL)
  816. {
  817. for (auto methodArg : mMethodInfoEx->mMethodGenericArguments)
  818. {
  819. // If we are specialized by an autocompleted method reference
  820. if (methodArg->IsMethodRef())
  821. {
  822. auto methodRefType = (BfMethodRefType*)methodArg;
  823. if (methodRefType->mIsAutoCompleteMethod)
  824. return true;
  825. }
  826. }
  827. }
  828. return false;
  829. }
  830. bool BfMethodInstance::IsOrInUnspecializedVariation()
  831. {
  832. return (mIsUnspecializedVariation) || (GetOwner()->IsUnspecializedTypeVariation());
  833. }
  834. bool BfMethodInstance::HasExternConstraints()
  835. {
  836. return (mMethodInfoEx != NULL) && (mMethodInfoEx->mGenericParams.size() > mMethodInfoEx->mMethodGenericArguments.size());
  837. }
  838. bool BfMethodInstance::HasParamsArray()
  839. {
  840. if (mParams.size() == 0)
  841. return false;
  842. return GetParamKind((int)mParams.size() - 1) == BfParamKind_Params;
  843. }
  844. int BfMethodInstance::GetStructRetIdx(bool forceStatic)
  845. {
  846. if ((mReturnType->IsComposite()) && (!mReturnType->IsValuelessType()) && (!GetLoweredReturnType(NULL, NULL, forceStatic)) && (!mIsIntrinsic))
  847. {
  848. auto returnTypeInst = mReturnType->ToTypeInstance();
  849. if ((returnTypeInst != NULL) && (returnTypeInst->mHasUnderlyingArray))
  850. return -1;
  851. auto thisType = mMethodInstanceGroup->mOwner;
  852. if (thisType->mModule->mCompiler->mOptions.mPlatformType != BfPlatformType_Windows)
  853. return 0;
  854. if ((mMethodInfoEx != NULL) && (mMethodInfoEx->mClosureInstanceInfo != NULL) && (mMethodInfoEx->mClosureInstanceInfo->mThisOverride != NULL))
  855. thisType = mMethodInfoEx->mClosureInstanceInfo->mThisOverride;
  856. if ((!HasThis()) || (forceStatic))
  857. return 0;
  858. if (!thisType->IsValueType())
  859. return 1;
  860. if ((mMethodDef->mIsMutating) || (!thisType->IsSplattable()) || ((!AllowsSplatting(-1)) && (!thisType->GetLoweredType(BfTypeUsage_Parameter))))
  861. return 1;
  862. return 0;
  863. }
  864. return -1;
  865. }
  866. bool BfMethodInstance::HasSelf()
  867. {
  868. if (mReturnType->IsSelf())
  869. return true;
  870. for (int paramIdx = 0; paramIdx < GetParamCount(); paramIdx++)
  871. if (GetParamType(paramIdx)->IsSelf())
  872. return true;
  873. return false;
  874. }
  875. bool BfMethodInstance::GetLoweredReturnType(BfTypeCode* loweredTypeCode, BfTypeCode* loweredTypeCode2, bool forceStatic)
  876. {
  877. // Win32 handler
  878. if (((mMethodDef->mIsStatic) || (forceStatic)) &&
  879. (mReturnType->IsComposite()) &&
  880. ((mReturnType->mSize == 4) || (mReturnType->mSize == 8)))
  881. {
  882. auto returnTypeInst = mReturnType->ToTypeInstance();
  883. if ((returnTypeInst != NULL) && (returnTypeInst->mIsCRepr))
  884. {
  885. auto module = GetOwner()->mModule;
  886. auto compiler = module->mCompiler;
  887. if ((compiler->mOptions.mMachineType == BfMachineType_x86) && (compiler->mOptions.mPlatformType == BfPlatformType_Windows))
  888. {
  889. if (loweredTypeCode != NULL)
  890. {
  891. *loweredTypeCode = BfTypeCode_Int32;
  892. if (mReturnType->mSize == 8)
  893. *loweredTypeCode = BfTypeCode_Int64;
  894. }
  895. return true;
  896. }
  897. }
  898. }
  899. return mReturnType->GetLoweredType((mMethodDef->mIsStatic || forceStatic) ? BfTypeUsage_Return_Static : BfTypeUsage_Return_NonStatic, loweredTypeCode, loweredTypeCode2);
  900. }
  901. bool BfMethodInstance::WantsStructsAttribByVal(BfType* paramType)
  902. {
  903. auto owner = GetOwner();
  904. if ((owner->mModule->mCompiler->mOptions.mPlatformType == BfPlatformType_Windows) &&
  905. (owner->mModule->mCompiler->mOptions.mMachineType == BfMachineType_x64))
  906. return false;
  907. if (owner->mModule->mCompiler->mOptions.mMachineType == BfMachineType_AArch64)
  908. return false;
  909. auto typeInst = paramType->ToTypeInstance();
  910. return (typeInst != NULL) && (typeInst->mIsCRepr);
  911. }
  912. bool BfMethodInstance::IsSkipCall(bool bypassVirtual)
  913. {
  914. if ((mMethodDef->mIsSkipCall) &&
  915. ((!mMethodDef->mIsVirtual) || (bypassVirtual)))
  916. return true;
  917. return false;
  918. }
  919. bool BfMethodInstance::IsVarArgs()
  920. {
  921. if (mMethodDef->mParams.IsEmpty())
  922. return false;
  923. return mMethodDef->mParams.back()->mParamKind == BfParamKind_VarArgs;
  924. }
  925. bool BfMethodInstance::AlwaysInline()
  926. {
  927. return mAlwaysInline;
  928. }
  929. BfImportCallKind BfMethodInstance::GetImportCallKind()
  930. {
  931. if (GetImportKind() != BfImportKind_Import_Dynamic)
  932. return BfImportCallKind_None;
  933. if ((mHotMethod != NULL) && ((mHotMethod->mFlags & BfHotDepDataFlag_IsOriginalBuild) == 0))
  934. return BfImportCallKind_GlobalVar_Hot;
  935. return BfImportCallKind_GlobalVar;
  936. }
  937. bool BfMethodInstance::IsTestMethod()
  938. {
  939. return (mMethodInfoEx != NULL) && (mMethodInfoEx->mMethodCustomAttributes != NULL) && (mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes != NULL) &&
  940. (mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes != NULL) && (mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes->Contains(GetOwner()->mModule->mCompiler->mTestAttributeTypeDef));
  941. }
  942. bool BfMethodInstance::AllowsSplatting(int paramIdx)
  943. {
  944. if (paramIdx == -1)
  945. {
  946. if (mCallingConvention != BfCallingConvention_Unspecified)
  947. return false;
  948. if (ForcingThisPtr())
  949. return false;
  950. if (mMethodDef->mIsNoSplat)
  951. return false;
  952. return !mMethodDef->HasNoThisSplat();
  953. }
  954. else
  955. {
  956. if (mCallingConvention != BfCallingConvention_Unspecified)
  957. return false;
  958. if ((mMethodDef->mIsNoSplat) || (mMethodDef->mMethodType == BfMethodType_Mixin))
  959. {
  960. if (IsImplicitCapture(paramIdx))
  961. return true;
  962. return false;
  963. }
  964. return true;
  965. }
  966. }
  967. bool BfMethodInstance::HasThis()
  968. {
  969. if (mMethodDef->mIsStatic)
  970. return false;
  971. if ((mMethodInfoEx != NULL) && (mMethodInfoEx->mClosureInstanceInfo != NULL) && (mMethodInfoEx->mClosureInstanceInfo->mThisOverride != NULL))
  972. return !mMethodInfoEx->mClosureInstanceInfo->mThisOverride->IsValuelessNonOpaqueType();
  973. return (!mMethodInstanceGroup->mOwner->IsValuelessNonOpaqueType());
  974. }
  975. bool BfMethodInstance::IsVirtual()
  976. {
  977. return mMethodDef->mIsVirtual && !mIsInnerOverride;
  978. }
  979. BfType* BfMethodInstance::GetThisType()
  980. {
  981. BF_ASSERT(!mMethodDef->mIsStatic);
  982. if (mMethodDef->mHasExplicitThis)
  983. {
  984. auto thisType = mParams[0].mResolvedType;
  985. auto owner = GetOwner();
  986. if ((thisType->IsValueType()) && ((mMethodDef->mIsMutating) || (!AllowsSplatting(-1))) && (!thisType->GetLoweredType(BfTypeUsage_Parameter)))
  987. return owner->mModule->mContext->mUnreifiedModule->CreatePointerType(thisType);
  988. return thisType;
  989. }
  990. return GetParamType(-1);
  991. }
  992. int BfMethodInstance::GetThisIdx()
  993. {
  994. if (mMethodDef->mIsStatic)
  995. return -2;
  996. if (mMethodDef->mHasExplicitThis)
  997. return 0;
  998. return -1;
  999. }
  1000. bool BfMethodInstance::HasExplicitThis()
  1001. {
  1002. if (mMethodDef->mIsStatic)
  1003. return false;
  1004. return mMethodInstanceGroup->mOwner->IsFunction();
  1005. }
  1006. int BfMethodInstance::GetParamCount()
  1007. {
  1008. return (int)mParams.size();
  1009. }
  1010. int BfMethodInstance::GetImplicitParamCount()
  1011. {
  1012. if ((mMethodInfoEx != NULL) && (mMethodInfoEx->mClosureInstanceInfo != NULL) && (mMethodDef->mIsLocalMethod))
  1013. return (int)mMethodInfoEx->mClosureInstanceInfo->mCaptureEntries.size();
  1014. return 0;
  1015. }
  1016. void BfMethodInstance::GetParamName(int paramIdx, StringImpl& name, int& namePrefixCount)
  1017. {
  1018. if (paramIdx == -1)
  1019. {
  1020. BF_ASSERT(!mMethodDef->mIsStatic);
  1021. name = "this";
  1022. return;
  1023. }
  1024. if ((mMethodInfoEx != NULL) && (mMethodInfoEx->mClosureInstanceInfo != NULL) && (mMethodDef->mIsLocalMethod))
  1025. {
  1026. if (paramIdx < (int)mMethodInfoEx->mClosureInstanceInfo->mCaptureEntries.size())
  1027. {
  1028. name = mMethodInfoEx->mClosureInstanceInfo->mCaptureEntries[paramIdx].mName;
  1029. return;
  1030. }
  1031. }
  1032. BfMethodParam* methodParam = &mParams[paramIdx];
  1033. BfParameterDef* paramDef = mMethodDef->mParams[methodParam->mParamDefIdx];
  1034. if (methodParam->mDelegateParamIdx != -1)
  1035. {
  1036. if (methodParam->mResolvedType->IsTuple())
  1037. {
  1038. auto tupleType = (BfTupleType*)methodParam->mResolvedType;
  1039. auto& fieldInstance = tupleType->mFieldInstances[methodParam->mDelegateParamIdx];
  1040. if (methodParam->mDelegateParamNameCombine)
  1041. name = paramDef->mName + "__" + fieldInstance.GetFieldDef()->mName;
  1042. else
  1043. name = fieldInstance.GetFieldDef()->mName;
  1044. return;
  1045. }
  1046. BfMethodInstance* invokeMethodInstance = methodParam->GetDelegateParamInvoke();
  1047. if (methodParam->mDelegateParamNameCombine)
  1048. name = paramDef->mName + "__" + invokeMethodInstance->GetParamName(methodParam->mDelegateParamIdx);
  1049. else
  1050. invokeMethodInstance->GetParamName(methodParam->mDelegateParamIdx, name, namePrefixCount);
  1051. return;
  1052. }
  1053. name.Reference(paramDef->mName);
  1054. namePrefixCount = paramDef->mNamePrefixCount;
  1055. }
  1056. String BfMethodInstance::GetParamName(int paramIdx)
  1057. {
  1058. StringT<256> paramName;
  1059. int namePrefixCount = 0;
  1060. GetParamName(paramIdx, paramName, namePrefixCount);
  1061. return paramName;
  1062. }
  1063. String BfMethodInstance::GetParamName(int paramIdx, int& namePrefixCount)
  1064. {
  1065. StringT<256> paramName;
  1066. GetParamName(paramIdx, paramName, namePrefixCount);
  1067. return paramName;
  1068. }
  1069. BfType* BfMethodInstance::GetParamType(int paramIdx, bool returnUnderlyingParamsType)
  1070. {
  1071. if (paramIdx == -1)
  1072. {
  1073. if ((mMethodInfoEx != NULL) && (mMethodInfoEx->mClosureInstanceInfo != NULL) && (mMethodInfoEx->mClosureInstanceInfo->mThisOverride != NULL))
  1074. return mMethodInfoEx->mClosureInstanceInfo->mThisOverride;
  1075. BF_ASSERT(!mMethodDef->mIsStatic);
  1076. auto owner = mMethodInstanceGroup->mOwner;
  1077. BfType* thisType = owner;
  1078. if (owner->IsFunction())
  1079. {
  1080. BF_FATAL("Wrong 'this' index");
  1081. }
  1082. if ((thisType->IsValueType()) && ((mMethodDef->mIsMutating) || (!AllowsSplatting(paramIdx))) && (!thisType->GetLoweredType(BfTypeUsage_Parameter)))
  1083. return owner->mModule->CreatePointerType(thisType);
  1084. return thisType;
  1085. }
  1086. BfMethodParam* methodParam = &mParams[paramIdx];
  1087. if (methodParam->mDelegateParamIdx != -1)
  1088. {
  1089. if (methodParam->mResolvedType->IsTuple())
  1090. {
  1091. auto tupleType = (BfTupleType*)methodParam->mResolvedType;
  1092. return tupleType->mFieldInstances[methodParam->mDelegateParamIdx].mResolvedType;
  1093. }
  1094. BfMethodInstance* invokeMethodInstance = methodParam->GetDelegateParamInvoke();
  1095. return invokeMethodInstance->GetParamType(methodParam->mDelegateParamIdx, true);
  1096. }
  1097. if (returnUnderlyingParamsType)
  1098. {
  1099. BfParameterDef* paramDef = mMethodDef->mParams[methodParam->mParamDefIdx];
  1100. if (paramDef->mParamKind == BfParamKind_Params)
  1101. {
  1102. auto underlyingType = methodParam->mResolvedType->GetUnderlyingType();
  1103. if (underlyingType != NULL)
  1104. return underlyingType;
  1105. return methodParam->mResolvedType;
  1106. }
  1107. }
  1108. return methodParam->mResolvedType;
  1109. }
  1110. bool BfMethodInstance::GetParamIsSplat(int paramIdx)
  1111. {
  1112. if (paramIdx == -1)
  1113. {
  1114. BF_ASSERT(!mMethodDef->mIsStatic);
  1115. auto owner = mMethodInstanceGroup->mOwner;
  1116. if ((owner->IsValueType()) && (mMethodDef->mIsMutating || !AllowsSplatting(paramIdx)))
  1117. return false;
  1118. return owner->mIsSplattable;
  1119. }
  1120. BfMethodParam* methodParam = &mParams[paramIdx];
  1121. if (methodParam->mDelegateParamIdx != -1)
  1122. {
  1123. BfMethodInstance* invokeMethodInstance = methodParam->GetDelegateParamInvoke();
  1124. if (invokeMethodInstance == NULL)
  1125. return false;
  1126. return invokeMethodInstance->GetParamIsSplat(methodParam->mDelegateParamIdx);
  1127. }
  1128. return methodParam->mIsSplat;
  1129. }
  1130. BfParamKind BfMethodInstance::GetParamKind(int paramIdx)
  1131. {
  1132. if (paramIdx == -1)
  1133. return BfParamKind_Normal;
  1134. BfMethodParam* methodParam = &mParams[paramIdx];
  1135. if (methodParam->mParamDefIdx == -1)
  1136. return BfParamKind_ImplicitCapture;
  1137. BfParameterDef* paramDef = mMethodDef->mParams[methodParam->mParamDefIdx];
  1138. if (methodParam->mDelegateParamIdx != -1)
  1139. return BfParamKind_DelegateParam;
  1140. return paramDef->mParamKind;
  1141. }
  1142. bool BfMethodInstance::WasGenericParam(int paramIdx)
  1143. {
  1144. if (paramIdx == -1)
  1145. return false;
  1146. BfMethodParam* methodParam = &mParams[paramIdx];
  1147. return methodParam->mWasGenericParam;
  1148. }
  1149. bool BfMethodInstance::IsParamSkipped(int paramIdx)
  1150. {
  1151. auto resolveModule = GetModule()->mContext->mUnreifiedModule;
  1152. if (paramIdx == -1)
  1153. return false;
  1154. BfType* paramType = GetParamType(paramIdx);
  1155. if ((paramType->CanBeValuelessType()) && (paramType->IsDataIncomplete()))
  1156. resolveModule->PopulateType(paramType, BfPopulateType_Data);
  1157. if ((paramType->IsValuelessNonOpaqueType()) && (!paramType->IsMethodRef()))
  1158. return true;
  1159. return false;
  1160. }
  1161. bool BfMethodInstance::IsImplicitCapture(int paramIdx)
  1162. {
  1163. if (paramIdx == -1)
  1164. return false;
  1165. BfMethodParam* methodParam = &mParams[paramIdx];
  1166. if (methodParam->mParamDefIdx == -1)
  1167. return true;
  1168. return false;
  1169. }
  1170. BfExpression* BfMethodInstance::GetParamInitializer(int paramIdx)
  1171. {
  1172. if (paramIdx == -1)
  1173. return NULL;
  1174. BfMethodParam* methodParam = &mParams[paramIdx];
  1175. if (methodParam->mParamDefIdx == -1)
  1176. return NULL;
  1177. BfParameterDef* paramDef = mMethodDef->mParams[methodParam->mParamDefIdx];
  1178. if (paramDef->mParamDeclaration != NULL)
  1179. return paramDef->mParamDeclaration->mInitializer;
  1180. return NULL;
  1181. }
  1182. BfTypeReference* BfMethodInstance::GetParamTypeRef(int paramIdx)
  1183. {
  1184. if (paramIdx == -1)
  1185. return NULL;
  1186. BfMethodParam* methodParam = &mParams[paramIdx];
  1187. if (methodParam->mParamDefIdx == -1)
  1188. return NULL;
  1189. BfParameterDef* paramDef = mMethodDef->mParams[methodParam->mParamDefIdx];
  1190. if (paramDef->mParamDeclaration != NULL)
  1191. return paramDef->mParamDeclaration->mTypeRef;
  1192. return NULL;
  1193. }
  1194. BfIdentifierNode* BfMethodInstance::GetParamNameNode(int paramIdx)
  1195. {
  1196. if (paramIdx == -1)
  1197. return NULL;
  1198. if ((mMethodInfoEx != NULL) && (mMethodInfoEx->mClosureInstanceInfo != NULL) && (mMethodDef->mIsLocalMethod))
  1199. {
  1200. if (paramIdx < (int)mMethodInfoEx->mClosureInstanceInfo->mCaptureEntries.size())
  1201. return mMethodInfoEx->mClosureInstanceInfo->mCaptureEntries[paramIdx].mNameNode;
  1202. }
  1203. BfMethodParam* methodParam = &mParams[paramIdx];
  1204. BfParameterDef* paramDef = mMethodDef->mParams[methodParam->mParamDefIdx];
  1205. if (paramDef->mParamDeclaration != NULL)
  1206. return BfNodeDynCast<BfIdentifierNode>(paramDef->mParamDeclaration->mNameNode);
  1207. return NULL;
  1208. }
  1209. int BfMethodInstance::DbgGetVirtualMethodNum()
  1210. {
  1211. auto module = GetOwner()->mModule;
  1212. int vDataVal = -1;
  1213. if (mVirtualTableIdx != -1)
  1214. {
  1215. module->HadSlotCountDependency();
  1216. int vDataIdx = -1;
  1217. vDataIdx = module->mCompiler->GetVDataPrefixDataCount() + module->mCompiler->mMaxInterfaceSlots;
  1218. vDataIdx += module->mCompiler->GetDynCastVDataCount();
  1219. if ((module->mCompiler->mOptions.mHasVDataExtender) && (module->mCompiler->IsHotCompile()))
  1220. {
  1221. auto typeInst = mMethodInstanceGroup->mOwner;
  1222. int extMethodIdx = (mVirtualTableIdx - typeInst->GetImplBaseVTableSize()) - typeInst->GetOrigSelfVTableSize();
  1223. if (extMethodIdx >= 0)
  1224. {
  1225. // Extension?
  1226. int vExtOfs = typeInst->GetOrigImplBaseVTableSize();
  1227. vDataVal = ((vDataIdx + vExtOfs + 1) << 20) | (extMethodIdx);
  1228. }
  1229. else
  1230. {
  1231. // Map this new virtual index back to the original index
  1232. vDataIdx += (mVirtualTableIdx - typeInst->GetImplBaseVTableSize()) + typeInst->GetOrigImplBaseVTableSize();
  1233. }
  1234. }
  1235. else
  1236. {
  1237. vDataIdx += mVirtualTableIdx;
  1238. }
  1239. if (vDataVal == -1)
  1240. vDataVal = vDataIdx;
  1241. }
  1242. return vDataVal;
  1243. }
  1244. void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType, SizedArrayImpl<BfIRType>& paramTypes, bool forceStatic)
  1245. {
  1246. BfModule* resolveModule = module->mContext->mUnreifiedModule;
  1247. resolveModule->PopulateType(mReturnType);
  1248. BfTypeCode loweredReturnTypeCode = BfTypeCode_None;
  1249. BfTypeCode loweredReturnTypeCode2 = BfTypeCode_None;
  1250. if ((!module->mIsComptimeModule) && (GetLoweredReturnType(&loweredReturnTypeCode, &loweredReturnTypeCode2, forceStatic)) && (loweredReturnTypeCode != BfTypeCode_None))
  1251. {
  1252. auto irReturnType = module->GetIRLoweredType(loweredReturnTypeCode, loweredReturnTypeCode2);
  1253. returnType = irReturnType;
  1254. }
  1255. else if ((mReturnType->IsValuelessType()) || (mReturnType->IsVar()))
  1256. {
  1257. auto voidType = module->GetPrimitiveType(BfTypeCode_None);
  1258. returnType = module->mBfIRBuilder->MapType(voidType);
  1259. }
  1260. else if ((!module->mIsComptimeModule) && (GetStructRetIdx(forceStatic) != -1))
  1261. {
  1262. auto voidType = module->GetPrimitiveType(BfTypeCode_None);
  1263. returnType = module->mBfIRBuilder->MapType(voidType);
  1264. auto typeInst = mReturnType->ToTypeInstance();
  1265. if (typeInst != NULL)
  1266. {
  1267. paramTypes.push_back(module->mBfIRBuilder->MapTypeInstPtr(typeInst));
  1268. }
  1269. else
  1270. {
  1271. auto ptrType = module->CreatePointerType(mReturnType);
  1272. paramTypes.push_back(module->mBfIRBuilder->MapType(ptrType));
  1273. }
  1274. }
  1275. else
  1276. {
  1277. returnType = module->mBfIRBuilder->MapType(mReturnType);
  1278. }
  1279. for (int paramIdx = -1; paramIdx < GetParamCount(); paramIdx++)
  1280. {
  1281. BfType* checkType = NULL;
  1282. if (paramIdx == -1)
  1283. {
  1284. if ((mMethodDef->mIsStatic) || (forceStatic))
  1285. continue;
  1286. if (mIsClosure)
  1287. {
  1288. checkType = module->mCurMethodState->mClosureState->mClosureType;
  1289. }
  1290. else
  1291. {
  1292. if (HasExplicitThis())
  1293. checkType = GetParamType(0);
  1294. else
  1295. checkType = GetOwner();
  1296. }
  1297. }
  1298. else
  1299. {
  1300. if ((paramIdx == 0) && (mMethodDef->mHasExplicitThis))
  1301. continue; // Skip over the explicit 'this'
  1302. checkType = GetParamType(paramIdx);
  1303. }
  1304. /*if (GetParamName(paramIdx) == "this")
  1305. {
  1306. NOP;
  1307. }*/
  1308. bool checkLowered = false;
  1309. bool doSplat = false;
  1310. if (paramIdx == -1)
  1311. {
  1312. if (ForcingThisPtr())
  1313. {
  1314. // Pass by pointer even for typed primitives
  1315. }
  1316. else if ((!mMethodDef->mIsMutating) && (checkType->IsTypedPrimitive()))
  1317. {
  1318. checkType = checkType->GetUnderlyingType();
  1319. }
  1320. else if ((!module->mIsComptimeModule) && (checkType->IsSplattable()) && (AllowsSplatting(-1)))
  1321. {
  1322. doSplat = true;
  1323. }
  1324. else if ((!module->mIsComptimeModule) && (!mMethodDef->mIsMutating) && (mCallingConvention == BfCallingConvention_Unspecified))
  1325. checkLowered = true;
  1326. }
  1327. else
  1328. {
  1329. if ((checkType->IsComposite()) && (checkType->IsIncomplete()))
  1330. resolveModule->PopulateType(checkType, BfPopulateType_Data);
  1331. if (checkType->IsMethodRef())
  1332. {
  1333. doSplat = true;
  1334. }
  1335. else if (checkType->IsTypedPrimitive())
  1336. {
  1337. checkType = checkType->GetUnderlyingType();
  1338. }
  1339. else if ((!module->mIsComptimeModule) && (checkType->IsSplattable()) && (AllowsSplatting(paramIdx)))
  1340. {
  1341. doSplat = true;
  1342. }
  1343. else if (!module->mIsComptimeModule)
  1344. checkLowered = true;
  1345. }
  1346. BfType* checkType2 = NULL;
  1347. if (checkLowered)
  1348. {
  1349. BfTypeCode loweredTypeCode = BfTypeCode_None;
  1350. BfTypeCode loweredTypeCode2 = BfTypeCode_None;
  1351. if (checkType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2))
  1352. {
  1353. paramTypes.push_back(module->mBfIRBuilder->GetPrimitiveType(loweredTypeCode));
  1354. if (loweredTypeCode2 != BfTypeCode_None)
  1355. paramTypes.push_back(module->mBfIRBuilder->GetPrimitiveType(loweredTypeCode2));
  1356. continue;
  1357. }
  1358. }
  1359. if (checkType->CanBeValuelessType())
  1360. resolveModule->PopulateType(checkType, BfPopulateType_Data);
  1361. if ((checkType->IsValuelessNonOpaqueType()) && (!checkType->IsMethodRef()))
  1362. continue;
  1363. if ((doSplat) && (!checkType->IsMethodRef()))
  1364. {
  1365. int splatCount = checkType->GetSplatCount();
  1366. if ((int)paramTypes.size() + splatCount > module->mCompiler->mOptions.mMaxSplatRegs)
  1367. {
  1368. auto checkTypeInst = checkType->ToTypeInstance();
  1369. if ((checkTypeInst != NULL) && (checkTypeInst->mIsCRepr))
  1370. {
  1371. // CRepr splat means always splat
  1372. }
  1373. else
  1374. doSplat = false;
  1375. }
  1376. }
  1377. auto _AddType = [&](BfType* type)
  1378. {
  1379. if ((type->IsComposite()) || ((!doSplat) && (paramIdx == -1) && (type->IsTypedPrimitive())))
  1380. {
  1381. auto typeInst = type->ToTypeInstance();
  1382. if (typeInst != NULL)
  1383. paramTypes.push_back(module->mBfIRBuilder->MapTypeInstPtr(typeInst));
  1384. else
  1385. paramTypes.push_back(module->mBfIRBuilder->MapType(module->CreatePointerType(type)));
  1386. }
  1387. else
  1388. {
  1389. paramTypes.push_back(module->mBfIRBuilder->MapType(type));
  1390. }
  1391. };
  1392. if (doSplat)
  1393. {
  1394. BfTypeUtils::SplatIterate([&](BfType* checkType)
  1395. {
  1396. _AddType(checkType);
  1397. }, checkType);
  1398. }
  1399. else
  1400. _AddType(checkType);
  1401. if (checkType2 != NULL)
  1402. _AddType(checkType2);
  1403. }
  1404. if ((!module->mIsComptimeModule) && (GetStructRetIdx(forceStatic) == 1))
  1405. {
  1406. BF_SWAP(paramTypes[0], paramTypes[1]);
  1407. }
  1408. }
  1409. int BfMethodInstance::GetIRFunctionParamCount(BfModule* module)
  1410. {
  1411. //TODO: This is dumb, do this better
  1412. SizedArray<BfIRType, 8> params;
  1413. BfIRType returnType;
  1414. GetIRFunctionInfo(module, returnType, params);
  1415. return (int)params.size();
  1416. }
  1417. bool BfMethodInstance::IsExactMatch(BfMethodInstance* other, bool ignoreImplicitParams, bool checkThis)
  1418. {
  1419. if (mReturnType != other->mReturnType)
  1420. return false;
  1421. int implicitParamCountA = ignoreImplicitParams ? GetImplicitParamCount() : 0;
  1422. int implicitParamCountB = ignoreImplicitParams ? other->GetImplicitParamCount() : 0;
  1423. if (HasExplicitThis())
  1424. {
  1425. }
  1426. // if (other->HasExplicitThis())
  1427. // {
  1428. // if (!HasExplicitThis())
  1429. // return false;
  1430. // if (GetParamType(-1) != other->GetParamType(-1))
  1431. // return false;
  1432. // }
  1433. if (checkThis)
  1434. {
  1435. if (other->mMethodDef->mIsStatic != mMethodDef->mIsStatic)
  1436. return false;
  1437. // {
  1438. // // 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
  1439. //
  1440. // if (other->mMethodDef->mIsStatic)
  1441. // return false;
  1442. //
  1443. // if ((GetParamCount() > 0) && (GetParamName(0) == "this"))
  1444. // {
  1445. // auto thisType = GetParamType(0);
  1446. // auto otherThisType = other->GetParamType(-1);
  1447. // if (thisType != otherThisType)
  1448. // return false;
  1449. //
  1450. // implicitParamCountA++;
  1451. // }
  1452. // else
  1453. // {
  1454. // // Valueless types don't actually pass a 'this' anyway
  1455. // if (!other->GetOwner()->IsValuelessType())
  1456. // return false;
  1457. // }
  1458. // }
  1459. if (!mMethodDef->mIsStatic)
  1460. {
  1461. if (GetThisType() != other->GetThisType())
  1462. {
  1463. return false;
  1464. }
  1465. }
  1466. }
  1467. if (mMethodDef->mHasExplicitThis)
  1468. implicitParamCountA++;
  1469. if (other->mMethodDef->mHasExplicitThis)
  1470. implicitParamCountB++;
  1471. if (GetParamCount() - implicitParamCountA != other->GetParamCount() - implicitParamCountB)
  1472. return false;
  1473. for (int i = 0; i < (int)GetParamCount() - implicitParamCountA; i++)
  1474. {
  1475. auto paramA = GetParamType(i + implicitParamCountA);
  1476. auto paramB = other->GetParamType(i + implicitParamCountB);
  1477. if (paramA != paramB)
  1478. return false;
  1479. }
  1480. return true;
  1481. }
  1482. bool BfMethodInstance::IsReifiedAndImplemented()
  1483. {
  1484. return mIsReified && mMethodInstanceGroup->IsImplemented();
  1485. }
  1486. BfMethodInfoEx* BfMethodInstance::GetMethodInfoEx()
  1487. {
  1488. if (mMethodInfoEx == NULL)
  1489. mMethodInfoEx = new BfMethodInfoEx();
  1490. return mMethodInfoEx;
  1491. }
  1492. void BfMethodInstance::ReportMemory(MemReporter* memReporter)
  1493. {
  1494. memReporter->BeginSection("MethodInstance");
  1495. memReporter->Add(sizeof(BfMethodInstance));
  1496. if (mMethodInfoEx != NULL)
  1497. {
  1498. memReporter->BeginSection("MethodInfoEx");
  1499. memReporter->Add(sizeof(BfMethodInfoEx));
  1500. if (!mMethodInfoEx->mGenericParams.IsEmpty())
  1501. memReporter->AddVecPtr("GenericParams", mMethodInfoEx->mGenericParams, false);
  1502. if (!mMethodInfoEx->mGenericTypeBindings.IsEmpty())
  1503. memReporter->AddMap("GenericTypeBindings", mMethodInfoEx->mGenericTypeBindings, false);
  1504. if (mMethodInfoEx->mMethodCustomAttributes != NULL)
  1505. {
  1506. if (mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes != NULL)
  1507. mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes->ReportMemory(memReporter);
  1508. }
  1509. if (!mMethodInfoEx->mMethodGenericArguments.IsEmpty())
  1510. memReporter->AddVec("MethodGenericArguments", mMethodInfoEx->mMethodGenericArguments, false);
  1511. if (!mMethodInfoEx->mMangledName.IsEmpty())
  1512. memReporter->AddStr("MangledName", mMethodInfoEx->mMangledName);
  1513. memReporter->EndSection();
  1514. }
  1515. memReporter->AddVec("Params", mParams, false);
  1516. if (!mDefaultValues.IsEmpty())
  1517. memReporter->AddVec("DefaultValues", mDefaultValues, false);
  1518. memReporter->EndSection();
  1519. }
  1520. void BfCustomAttributes::ReportMemory(MemReporter* memReporter)
  1521. {
  1522. memReporter->BeginSection("CustomAttributes");
  1523. memReporter->Add(sizeof(BfCustomAttributes));
  1524. memReporter->AddVec(mAttributes);
  1525. memReporter->EndSection();
  1526. }
  1527. //////////////////////////////////////////////////////////////////////////
  1528. BfModuleMethodInstance::BfModuleMethodInstance(BfMethodInstance* methodInstance)
  1529. {
  1530. mMethodInstance = methodInstance;
  1531. if (methodInstance != NULL)
  1532. mFunc = mMethodInstance->mIRFunction;
  1533. else
  1534. mFunc = BfIRValue();
  1535. // if (methodInstance->GetImportCallKind() == BfImportCallKind_Thunk)
  1536. // {
  1537. // auto declModule = methodInstance->mDeclModule;
  1538. // BfIRValue* irFuncPtr = NULL;
  1539. // if (declModule->mFuncReferences.TryGetValue(methodInstance, &irFuncPtr))
  1540. // mFunc = *irFuncPtr;
  1541. // }
  1542. }
  1543. //////////////////////////////////////////////////////////////////////////
  1544. BfMethodRefType::~BfMethodRefType()
  1545. {
  1546. if (!mContext->mDeleting)
  1547. BF_ASSERT(mMethodRef == NULL);
  1548. }
  1549. BfMethodInstanceGroup::BfMethodInstanceGroup(BfMethodInstanceGroup&& prev) noexcept
  1550. {
  1551. mOwner = prev.mOwner;
  1552. mDefault = prev.mDefault;
  1553. mMethodSpecializationMap = prev.mMethodSpecializationMap;
  1554. mDefaultCustomAttributes = prev.mDefaultCustomAttributes;
  1555. mMethodIdx = prev.mMethodIdx;
  1556. mRefCount = prev.mRefCount;
  1557. mOnDemandKind = prev.mOnDemandKind;
  1558. mExplicitlyReflected = prev.mExplicitlyReflected;
  1559. mHasEmittedReference = prev.mHasEmittedReference;
  1560. if (mDefault != NULL)
  1561. mDefault->mMethodInstanceGroup = this;
  1562. if (mMethodSpecializationMap != NULL)
  1563. {
  1564. for (auto& pair : *mMethodSpecializationMap)
  1565. pair.mValue->mMethodInstanceGroup = this;
  1566. }
  1567. prev.mDefaultCustomAttributes = NULL;
  1568. prev.mRefCount = 0;
  1569. prev.mDefault = NULL;
  1570. prev.mMethodSpecializationMap = NULL;
  1571. }
  1572. BfMethodInstanceGroup::~BfMethodInstanceGroup()
  1573. {
  1574. if (mRefCount != 0)
  1575. {
  1576. BF_ASSERT(mOwner->mModule->mContext->mDeleting);
  1577. }
  1578. delete mDefault;
  1579. if (mMethodSpecializationMap != NULL)
  1580. {
  1581. for (auto& kv : *mMethodSpecializationMap)
  1582. delete kv.mValue;
  1583. delete mMethodSpecializationMap;
  1584. }
  1585. delete mDefaultCustomAttributes;
  1586. }
  1587. //////////////////////////////////////////////////////////////////////////
  1588. BfTypeInstance::~BfTypeInstance()
  1589. {
  1590. ReleaseData();
  1591. delete mTypeInfoEx;
  1592. delete mGenericTypeInfo;
  1593. delete mCeTypeInfo;
  1594. delete mCustomAttributes;
  1595. delete mAttributeData;
  1596. for (auto methodInst : mInternalMethods)
  1597. delete methodInst;
  1598. for (auto operatorInfo : mOperatorInfo)
  1599. delete operatorInfo;
  1600. for (auto localMethod : mOwnedLocalMethods)
  1601. delete localMethod;
  1602. delete mHotTypeData;
  1603. delete mConstHolder;
  1604. if ((mTypeDef != NULL) && (mTypeDef->mEmitParent != NULL))
  1605. {
  1606. mMethodInstanceGroups.Clear();
  1607. BfLogSys(mModule->mSystem, "Type %p dtor deleting typeDef %p\n", this, mTypeDef);
  1608. delete mTypeDef;
  1609. }
  1610. }
  1611. void BfTypeInstance::ReleaseData()
  1612. {
  1613. for (auto& kv : mInternalAccessMap)
  1614. {
  1615. auto& internalAcessSet = kv.mValue;
  1616. for (auto& namespaceComposite : internalAcessSet.mNamespaces)
  1617. mModule->mSystem->ReleaseAtomComposite(namespaceComposite);
  1618. }
  1619. mInternalAccessMap.Clear();
  1620. }
  1621. void BfTypeInstance::Dispose()
  1622. {
  1623. delete mGenericTypeInfo;
  1624. mGenericTypeInfo = NULL;
  1625. mTypeDef = NULL;
  1626. }
  1627. int BfTypeInstance::GetSplatCount(bool force)
  1628. {
  1629. if (IsValuelessType())
  1630. return 0;
  1631. if ((!mIsSplattable) && (!force))
  1632. return 1;
  1633. int splatCount = 0;
  1634. BfTypeUtils::SplatIterate([&](BfType* checkType) { splatCount++; }, this);
  1635. return splatCount;
  1636. }
  1637. bool BfTypeInstance::IsCRepr()
  1638. {
  1639. return mIsCRepr;
  1640. }
  1641. bool BfTypeInstance::IsString()
  1642. {
  1643. return IsInstanceOf(mContext->mCompiler->mStringTypeDef);
  1644. }
  1645. int BfTypeInstance::GetOrigVTableSize()
  1646. {
  1647. if (!mModule->mCompiler->mOptions.mHasVDataExtender)
  1648. {
  1649. BF_ASSERT(mHotTypeData == NULL);
  1650. return mVirtualMethodTableSize;
  1651. }
  1652. if (mHotTypeData != NULL)
  1653. {
  1654. // When we have a pending data change, treat it as a fresh vtable
  1655. if ((!mHotTypeData->mPendingDataChange) && (mHotTypeData->mVTableOrigLength != -1))
  1656. return mHotTypeData->mVTableOrigLength;
  1657. }
  1658. if (mBaseType != NULL)
  1659. return mBaseType->GetOrigVTableSize() + (mVirtualMethodTableSize - mBaseType->mVirtualMethodTableSize);
  1660. return mVirtualMethodTableSize;
  1661. }
  1662. int BfTypeInstance::GetSelfVTableSize()
  1663. {
  1664. if (mBaseType != NULL)
  1665. {
  1666. BF_ASSERT(mBaseType->mVirtualMethodTableSize > 0);
  1667. return mVirtualMethodTableSize - mBaseType->mVirtualMethodTableSize;
  1668. }
  1669. return mVirtualMethodTableSize;
  1670. }
  1671. int BfTypeInstance::GetOrigSelfVTableSize()
  1672. {
  1673. if (mBaseType != NULL)
  1674. return GetOrigVTableSize() - GetOrigImplBaseVTableSize();
  1675. return GetOrigVTableSize();
  1676. }
  1677. int BfTypeInstance::GetImplBaseVTableSize()
  1678. {
  1679. auto implBase = GetImplBaseType();
  1680. if (implBase != NULL)
  1681. return implBase->mVirtualMethodTableSize;
  1682. return 0;
  1683. }
  1684. int BfTypeInstance::GetOrigImplBaseVTableSize()
  1685. {
  1686. auto implBase = GetImplBaseType();
  1687. if (implBase != NULL)
  1688. return mBaseType->GetOrigVTableSize();
  1689. return 0;
  1690. }
  1691. int BfTypeInstance::GetIFaceVMethodSize()
  1692. {
  1693. int maxIFaceIdx = 0;
  1694. auto checkTypeInstance = this;
  1695. while (checkTypeInstance != NULL)
  1696. {
  1697. for (auto&& interfaceEntry : checkTypeInstance->mInterfaces)
  1698. {
  1699. maxIFaceIdx = BF_MAX(maxIFaceIdx, interfaceEntry.mStartVirtualIdx + interfaceEntry.mInterfaceType->mVirtualMethodTableSize);
  1700. }
  1701. checkTypeInstance = checkTypeInstance->mBaseType;
  1702. }
  1703. return maxIFaceIdx;
  1704. }
  1705. BfType* BfTypeInstance::GetUnionInnerType(bool* wantSplat)
  1706. {
  1707. if (wantSplat != NULL)
  1708. *wantSplat = false;
  1709. if (!mIsUnion)
  1710. return NULL;
  1711. BfTypeState typeState(this, mContext->mCurTypeState);
  1712. typeState.mPopulateType = BfPopulateType_Data;
  1713. SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
  1714. int unionSize = 0;
  1715. BfType* unionInnerType = NULL;
  1716. bool makeRaw = false;
  1717. for (int fieldIdx = 0; fieldIdx < (int)mFieldInstances.size(); fieldIdx++)
  1718. {
  1719. auto fieldInstance = (BfFieldInstance*)&mFieldInstances[fieldIdx];
  1720. auto fieldDef = fieldInstance->GetFieldDef();
  1721. BfType* checkInnerType = NULL;
  1722. if (fieldDef == NULL)
  1723. continue;
  1724. if ((fieldDef->mIsConst) && (fieldInstance->mIsEnumPayloadCase))
  1725. {
  1726. BF_ASSERT(mIsUnion);
  1727. checkInnerType = fieldInstance->mResolvedType;
  1728. }
  1729. if (fieldInstance->mDataIdx >= 0)
  1730. {
  1731. checkInnerType = fieldInstance->mResolvedType;
  1732. }
  1733. if (checkInnerType != NULL)
  1734. {
  1735. SetAndRestoreValue<BfFieldDef*> prevTypeRef(mContext->mCurTypeState->mCurFieldDef, fieldDef);
  1736. if (checkInnerType->IsDataIncomplete())
  1737. mModule->PopulateType(checkInnerType, checkInnerType->IsValueType() ? BfPopulateType_Data : BfPopulateType_Declaration);
  1738. if (checkInnerType->mSize > unionSize)
  1739. unionSize = checkInnerType->mSize;
  1740. if ((!checkInnerType->IsValuelessType()) && (checkInnerType != unionInnerType))
  1741. {
  1742. if (unionInnerType == NULL)
  1743. {
  1744. unionInnerType = checkInnerType;
  1745. }
  1746. else
  1747. {
  1748. if (checkInnerType->mSize > unionInnerType->mSize)
  1749. {
  1750. bool needsMemberCasting = false;
  1751. if (!mModule->AreSplatsCompatible(checkInnerType, unionInnerType, &needsMemberCasting))
  1752. {
  1753. unionInnerType = NULL;
  1754. makeRaw = true;
  1755. }
  1756. else
  1757. {
  1758. unionInnerType = checkInnerType;
  1759. }
  1760. }
  1761. else
  1762. {
  1763. bool needsMemberCasting = false;
  1764. if (!mModule->AreSplatsCompatible(unionInnerType, checkInnerType, &needsMemberCasting))
  1765. {
  1766. unionInnerType = NULL;
  1767. makeRaw = true;
  1768. }
  1769. }
  1770. }
  1771. }
  1772. }
  1773. }
  1774. BF_ASSERT(unionInnerType != this);
  1775. // Don't allow a float for the inner type -- to avoid invalid loading invalid FP bit patterns during copies
  1776. if ((unionInnerType != NULL) && (!makeRaw))
  1777. {
  1778. //TODO: How did splats make sense? It breaks CompactList
  1779. //if (wantSplat != NULL)
  1780. // *wantSplat = true;
  1781. }
  1782. else
  1783. {
  1784. switch (unionSize)
  1785. {
  1786. case 0: return mModule->CreateSizedArrayType(mModule->GetPrimitiveType(BfTypeCode_Int8), 0);
  1787. case 1: return mModule->GetPrimitiveType(BfTypeCode_Int8);
  1788. case 2: if (mInstAlign >= 2) return mModule->GetPrimitiveType(BfTypeCode_Int16);
  1789. case 4: if (mInstAlign >= 4) return mModule->GetPrimitiveType(BfTypeCode_Int32);
  1790. case 8: if (mInstAlign >= 8) return mModule->GetPrimitiveType(BfTypeCode_Int64);
  1791. }
  1792. if ((unionSize % 8 == 0) && (mInstAlign >= 8))
  1793. return mModule->CreateSizedArrayType(mModule->GetPrimitiveType(BfTypeCode_Int64), unionSize / 8);
  1794. if ((unionSize % 4 == 0) && (mInstAlign >= 4))
  1795. return mModule->CreateSizedArrayType(mModule->GetPrimitiveType(BfTypeCode_Int32), unionSize / 4);
  1796. if ((unionSize % 2 == 0) && (mInstAlign >= 2))
  1797. return mModule->CreateSizedArrayType(mModule->GetPrimitiveType(BfTypeCode_Int16), unionSize / 2);
  1798. return mModule->CreateSizedArrayType(mModule->GetPrimitiveType(BfTypeCode_Int8), unionSize);
  1799. }
  1800. return unionInnerType;
  1801. }
  1802. BfPrimitiveType* BfTypeInstance::GetDiscriminatorType(int* outDataIdx)
  1803. {
  1804. BF_ASSERT(IsPayloadEnum());
  1805. auto& fieldInstance = mFieldInstances.back();
  1806. BF_ASSERT(fieldInstance.GetFieldDef() == NULL);
  1807. if (fieldInstance.mResolvedType == NULL)
  1808. {
  1809. BF_ASSERT(IsIncomplete());
  1810. // Use Int64 as a placeholder until we determine the correct type...
  1811. return mModule->GetPrimitiveType(BfTypeCode_Int64);
  1812. }
  1813. BF_ASSERT(fieldInstance.mResolvedType != NULL);
  1814. BF_ASSERT(fieldInstance.mResolvedType->IsPrimitiveType());
  1815. if (outDataIdx != NULL)
  1816. *outDataIdx = fieldInstance.mDataIdx;
  1817. return (BfPrimitiveType*)fieldInstance.mResolvedType;
  1818. }
  1819. void BfTypeInstance::GetUnderlyingArray(BfType*& type, int& size, bool& isVector)
  1820. {
  1821. if (mCustomAttributes == NULL)
  1822. return;
  1823. auto attributes = mCustomAttributes->Get(mModule->mCompiler->mUnderlyingArrayAttributeTypeDef);
  1824. if (attributes == NULL)
  1825. return;
  1826. if (attributes->mCtorArgs.size() != 3)
  1827. return;
  1828. auto typeConstant = mConstHolder->GetConstant(attributes->mCtorArgs[0]);
  1829. auto sizeConstant = mConstHolder->GetConstant(attributes->mCtorArgs[1]);
  1830. auto isVectorConstant = mConstHolder->GetConstant(attributes->mCtorArgs[2]);
  1831. if ((typeConstant == NULL) || (sizeConstant == NULL) || (isVectorConstant == NULL))
  1832. return;
  1833. if (typeConstant->mConstType != BfConstType_TypeOf)
  1834. return;
  1835. type = (BfType*)(intptr)typeConstant->mInt64;
  1836. size = sizeConstant->mInt32;
  1837. isVector = isVectorConstant->mBool;
  1838. }
  1839. bool BfTypeInstance::GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCode, BfTypeCode* outTypeCode2)
  1840. {
  1841. if ((mTypeDef->mTypeCode != BfTypeCode_Struct) || (IsBoxed()) || (mIsSplattable))
  1842. return false;
  1843. if (mHasUnderlyingArray)
  1844. return false;
  1845. bool deepCheck = false;
  1846. if (mModule->mCompiler->mOptions.mMachineType == BfMachineType_Wasm32)
  1847. {
  1848. if (IsComposite())
  1849. {
  1850. if (GetSplatCount(true) == 1)
  1851. {
  1852. BfType* componentType = NULL;
  1853. BfTypeUtils::SplatIterate([&](BfType* checkType) { componentType = checkType; }, this);
  1854. if (componentType != NULL)
  1855. {
  1856. if (componentType->IsPrimitiveType())
  1857. {
  1858. auto primType = (BfPrimitiveType*)componentType;
  1859. if (outTypeCode != NULL)
  1860. *outTypeCode = primType->mTypeDef->mTypeCode;
  1861. return true;
  1862. }
  1863. }
  1864. }
  1865. else
  1866. return false;
  1867. }
  1868. }
  1869. if (mModule->mCompiler->mOptions.mPlatformType == BfPlatformType_Windows)
  1870. {
  1871. // Odd Windows rule: composite returns for non-static methods are always sret
  1872. if (typeUsage == BfTypeUsage_Return_NonStatic)
  1873. return false;
  1874. }
  1875. else
  1876. {
  1877. // Non-Win64 systems allow lowered splitting of composites over multiple params
  1878. if (mModule->mSystem->mPtrSize == 8)
  1879. deepCheck = true;
  1880. else
  1881. {
  1882. // We know this is correct for Linux x86 and Android armv7
  1883. if (mModule->mCompiler->mOptions.mPlatformType == BfPlatformType_Linux)
  1884. {
  1885. if ((typeUsage == BfTypeUsage_Return_NonStatic) || (typeUsage == BfTypeUsage_Return_Static))
  1886. return false;
  1887. }
  1888. }
  1889. }
  1890. int maxInstSize = 16;
  1891. if (mModule->mCompiler->mOptions.mMachineType == BfMachineType_AArch64)
  1892. maxInstSize = 32;
  1893. if (deepCheck)
  1894. {
  1895. if ((mInstSize >= 4) && (mInstSize <= maxInstSize))
  1896. {
  1897. BfTypeCode types[8] = { BfTypeCode_None };
  1898. std::function<void(BfType*, int)> _CheckType = [&](BfType* type, int offset)
  1899. {
  1900. if (auto typeInst = type->ToTypeInstance())
  1901. {
  1902. if (typeInst->IsValueType())
  1903. {
  1904. if (typeInst->mBaseType != NULL)
  1905. _CheckType(typeInst->mBaseType, offset);
  1906. for (auto& fieldInstance : typeInst->mFieldInstances)
  1907. {
  1908. if (fieldInstance.mDataOffset >= 0)
  1909. _CheckType(fieldInstance.mResolvedType, offset + fieldInstance.mDataOffset);
  1910. }
  1911. }
  1912. else
  1913. {
  1914. types[offset / 4] = BfTypeCode_Object;
  1915. }
  1916. }
  1917. else if (type->IsPrimitiveType())
  1918. {
  1919. auto primType = (BfPrimitiveType*)type;
  1920. types[offset / 4] = primType->mTypeDef->mTypeCode;
  1921. }
  1922. else if (type->IsSizedArray())
  1923. {
  1924. auto sizedArray = (BfSizedArrayType*)type;
  1925. for (int i = 0; i < sizedArray->mElementCount; i++)
  1926. _CheckType(sizedArray->mElementType, offset + i * sizedArray->mElementType->GetStride());
  1927. }
  1928. };
  1929. _CheckType(this, 0);
  1930. bool handled = false;
  1931. if (mModule->mCompiler->mOptions.mMachineType == BfMachineType_AArch64)
  1932. {
  1933. // For returns, we want to avoid sret but not actually lower
  1934. bool writeOutCode = (typeUsage != BfTypeUsage_Return_NonStatic) && (typeUsage != BfTypeUsage_Return_Static);
  1935. if ((types[0] == BfTypeCode_Float) &&
  1936. (types[1] == BfTypeCode_Float) &&
  1937. (types[2] == BfTypeCode_None))
  1938. {
  1939. if ((outTypeCode != NULL) && (writeOutCode))
  1940. *outTypeCode = BfTypeCode_FloatX2;
  1941. return true;
  1942. }
  1943. if ((types[0] == BfTypeCode_Float) &&
  1944. (types[1] == BfTypeCode_Float) &&
  1945. (types[2] == BfTypeCode_Float) &&
  1946. (types[3] == BfTypeCode_None))
  1947. {
  1948. if ((outTypeCode != NULL) && (writeOutCode))
  1949. *outTypeCode = BfTypeCode_FloatX3;
  1950. return true;
  1951. }
  1952. if ((types[0] == BfTypeCode_Float) &&
  1953. (types[1] == BfTypeCode_Float) &&
  1954. (types[2] == BfTypeCode_Float) &&
  1955. (types[3] == BfTypeCode_Float) &&
  1956. (types[4] == BfTypeCode_None))
  1957. {
  1958. if ((outTypeCode != NULL) && (writeOutCode))
  1959. *outTypeCode = BfTypeCode_FloatX4;
  1960. return true;
  1961. }
  1962. if ((types[0] == BfTypeCode_Double) &&
  1963. (types[2] == BfTypeCode_Double) &&
  1964. (types[4] == BfTypeCode_None))
  1965. {
  1966. if ((outTypeCode != NULL) && (writeOutCode))
  1967. *outTypeCode = BfTypeCode_DoubleX2;
  1968. return true;
  1969. }
  1970. if ((types[0] == BfTypeCode_Double) &&
  1971. (types[2] == BfTypeCode_Double) &&
  1972. (types[4] == BfTypeCode_Double) &&
  1973. (types[6] == BfTypeCode_None))
  1974. {
  1975. if ((outTypeCode != NULL) && (writeOutCode))
  1976. *outTypeCode = BfTypeCode_DoubleX3;
  1977. return true;
  1978. }
  1979. if ((types[0] == BfTypeCode_Double) &&
  1980. (types[2] == BfTypeCode_Double) &&
  1981. (types[4] == BfTypeCode_Double) &&
  1982. (types[6] == BfTypeCode_Double))
  1983. {
  1984. if ((outTypeCode != NULL) && (writeOutCode))
  1985. *outTypeCode = BfTypeCode_DoubleX4;
  1986. return true;
  1987. }
  1988. if (mInstSize <= 8)
  1989. {
  1990. if ((outTypeCode != NULL) && (writeOutCode))
  1991. *outTypeCode = BfTypeCode_Int64;
  1992. return true;
  1993. }
  1994. if (mInstSize <= 16)
  1995. {
  1996. if ((outTypeCode != NULL) && (writeOutCode))
  1997. *outTypeCode = BfTypeCode_Int64X2;
  1998. return true;
  1999. }
  2000. return false;
  2001. }
  2002. else if (mModule->mCompiler->mOptions.mPlatformType == BfPlatformType_Windows)
  2003. {
  2004. bool hasFloat = false;
  2005. for (int type = 0; type < 4; type++)
  2006. {
  2007. if ((types[type] == BfTypeCode_Float) ||
  2008. (types[type] == BfTypeCode_Double))
  2009. hasFloat = false;
  2010. }
  2011. if (!hasFloat)
  2012. {
  2013. if (mInstSize == 4)
  2014. {
  2015. if (outTypeCode != NULL)
  2016. *outTypeCode = BfTypeCode_Int32;
  2017. return true;
  2018. }
  2019. if (mInstSize == 8)
  2020. {
  2021. if (outTypeCode != NULL)
  2022. *outTypeCode = BfTypeCode_Int64;
  2023. return true;
  2024. }
  2025. }
  2026. }
  2027. else
  2028. {
  2029. if (mInstSize >= 8)
  2030. {
  2031. if (outTypeCode != NULL)
  2032. *outTypeCode = BfTypeCode_Int64;
  2033. }
  2034. if (mInstSize == 8)
  2035. {
  2036. handled = true;
  2037. }
  2038. if (mInstSize == 9)
  2039. {
  2040. handled = true;
  2041. if (outTypeCode2 != NULL)
  2042. *outTypeCode2 = BfTypeCode_Int8;
  2043. }
  2044. if (mInstSize == 10)
  2045. {
  2046. handled = true;
  2047. if (outTypeCode2 != NULL)
  2048. *outTypeCode2 = BfTypeCode_Int16;
  2049. }
  2050. if (mInstSize == 12)
  2051. {
  2052. handled = true;
  2053. if (outTypeCode2 != NULL)
  2054. *outTypeCode2 = BfTypeCode_Int32;
  2055. }
  2056. if (mInstSize == 16)
  2057. {
  2058. handled = true;
  2059. if (outTypeCode2 != NULL)
  2060. *outTypeCode2 = BfTypeCode_Int64;
  2061. }
  2062. if ((types[0] == BfTypeCode_Float) && (types[1] == BfTypeCode_None))
  2063. {
  2064. handled = true;
  2065. if (outTypeCode != NULL)
  2066. *outTypeCode = BfTypeCode_Float;
  2067. }
  2068. if ((types[0] == BfTypeCode_Float) && (types[1] == BfTypeCode_Float))
  2069. {
  2070. if (outTypeCode != NULL)
  2071. *outTypeCode = BfTypeCode_Float2;
  2072. }
  2073. if (types[0] == BfTypeCode_Double)
  2074. {
  2075. if (outTypeCode != NULL)
  2076. *outTypeCode = BfTypeCode_Double;
  2077. }
  2078. if ((types[2] == BfTypeCode_Float) && (mInstSize == 12))
  2079. {
  2080. if (outTypeCode2 != NULL)
  2081. *outTypeCode2 = BfTypeCode_Float;
  2082. }
  2083. if ((types[2] == BfTypeCode_Float) && (types[3] == BfTypeCode_Float))
  2084. {
  2085. if (outTypeCode2 != NULL)
  2086. *outTypeCode2 = BfTypeCode_Float2;
  2087. }
  2088. if (types[2] == BfTypeCode_Double)
  2089. {
  2090. if (outTypeCode2 != NULL)
  2091. *outTypeCode2 = BfTypeCode_Double;
  2092. }
  2093. if (handled)
  2094. return true;
  2095. }
  2096. }
  2097. }
  2098. BfTypeCode typeCode = BfTypeCode_None;
  2099. BfTypeCode pow2TypeCode = BfTypeCode_None;
  2100. switch (mInstSize)
  2101. {
  2102. case 1:
  2103. pow2TypeCode = BfTypeCode_Int8;
  2104. break;
  2105. case 2:
  2106. pow2TypeCode = BfTypeCode_Int16;
  2107. break;
  2108. case 3:
  2109. typeCode = BfTypeCode_Int24;
  2110. break;
  2111. case 4:
  2112. pow2TypeCode = BfTypeCode_Int32;
  2113. break;
  2114. case 5:
  2115. typeCode = BfTypeCode_Int40;
  2116. break;
  2117. case 6:
  2118. typeCode = BfTypeCode_Int48;
  2119. break;
  2120. case 7:
  2121. typeCode = BfTypeCode_Int56;
  2122. break;
  2123. case 8:
  2124. if (mModule->mSystem->mPtrSize == 8)
  2125. {
  2126. pow2TypeCode = BfTypeCode_Int64;
  2127. break;
  2128. }
  2129. if ((typeUsage == BfTypeUsage_Return_Static) && (mModule->mCompiler->mOptions.mPlatformType == BfPlatformType_Windows))
  2130. {
  2131. pow2TypeCode = BfTypeCode_Int64;
  2132. break;
  2133. }
  2134. break;
  2135. }
  2136. if (pow2TypeCode != BfTypeCode_None)
  2137. {
  2138. if (outTypeCode != NULL)
  2139. *outTypeCode = pow2TypeCode;
  2140. return true;
  2141. }
  2142. if ((mModule->mCompiler->mOptions.mPlatformType != BfPlatformType_Windows) && (mModule->mSystem->mPtrSize == 8))
  2143. {
  2144. if (typeCode != BfTypeCode_None)
  2145. {
  2146. if (outTypeCode != NULL)
  2147. *outTypeCode = typeCode;
  2148. return true;
  2149. }
  2150. }
  2151. return false;
  2152. }
  2153. bool BfTypeInstance::HasEquivalentLayout(BfTypeInstance* compareTo)
  2154. {
  2155. if (mFieldInstances.size() != compareTo->mFieldInstances.size())
  2156. return false;
  2157. for (int fieldIdx = 0; fieldIdx < (int)mFieldInstances.size(); fieldIdx++)
  2158. {
  2159. auto fieldInstance = &mFieldInstances[fieldIdx];
  2160. auto otherFieldInstance = &compareTo->mFieldInstances[fieldIdx];
  2161. if (fieldInstance->mResolvedType != otherFieldInstance->mResolvedType)
  2162. return false;
  2163. }
  2164. return true;
  2165. }
  2166. BfIRConstHolder* BfTypeInstance::GetOrCreateConstHolder()
  2167. {
  2168. if (mConstHolder == NULL)
  2169. mConstHolder = new BfIRConstHolder(mModule);
  2170. return mConstHolder;
  2171. }
  2172. BfIRValue BfTypeInstance::CreateConst(BfConstant* fromConst, BfIRConstHolder* fromHolder)
  2173. {
  2174. if (mConstHolder == NULL)
  2175. mConstHolder = new BfIRConstHolder(mModule);
  2176. return mConstHolder->CreateConst(fromConst, fromHolder);
  2177. }
  2178. bool BfTypeInstance::HasOverrideMethods()
  2179. {
  2180. if (mTypeDef->mHasOverrideMethods)
  2181. return true;
  2182. if (mBaseType != NULL)
  2183. return mBaseType->HasOverrideMethods();
  2184. return false;
  2185. }
  2186. bool BfTypeInstance::GetResultInfo(BfType*& valueType, int& okTagId)
  2187. {
  2188. BF_ASSERT(!IsDataIncomplete());
  2189. if (mFieldInstances.size() < 2)
  2190. return false;
  2191. for (auto& fieldInstance : mFieldInstances)
  2192. {
  2193. if (!fieldInstance.mIsEnumPayloadCase)
  2194. continue;
  2195. if ((fieldInstance.mIsEnumPayloadCase) && (fieldInstance.GetFieldDef()->mName == "Ok") && (fieldInstance.mResolvedType->IsTuple()))
  2196. {
  2197. auto tupleType = (BfTypeInstance*)fieldInstance.mResolvedType;
  2198. if (tupleType->mFieldInstances.size() == 1)
  2199. {
  2200. valueType = tupleType->mFieldInstances[0].mResolvedType;
  2201. okTagId = -fieldInstance.mDataIdx - 1;
  2202. return true;
  2203. }
  2204. }
  2205. break;
  2206. }
  2207. return false;
  2208. }
  2209. bool BfTypeInstance::IsAnonymous()
  2210. {
  2211. return (mTypeDef->mTypeDeclaration != NULL) && (mTypeDef->mTypeDeclaration->IsAnonymous());
  2212. }
  2213. bool BfTypeInstance::IsAnonymousInitializerType()
  2214. {
  2215. return (mTypeDef->mTypeDeclaration != NULL) && (mTypeDef->mTypeDeclaration->IsAnonymousInitializerType());
  2216. }
  2217. bool BfTypeInstance::HasAppendCtor()
  2218. {
  2219. return mTypeDef->mHasAppendCtor;
  2220. }
  2221. bool BfTypeInstance::BaseHasAppendCtor()
  2222. {
  2223. if (mBaseType != NULL)
  2224. {
  2225. if (mBaseType->HasAppendCtor())
  2226. return true;
  2227. return mBaseType->BaseHasAppendCtor();
  2228. }
  2229. return false;
  2230. }
  2231. bool BfTypeInstance::HasAppendedField(bool checkBase)
  2232. {
  2233. for (auto& fieldInstance : mFieldInstances)
  2234. {
  2235. if (fieldInstance.IsAppendedObject())
  2236. return true;
  2237. }
  2238. if ((checkBase) && (mBaseType != NULL))
  2239. return mBaseType->HasAppendedField(checkBase);
  2240. return false;
  2241. }
  2242. void BfTypeInstance::ReportMemory(MemReporter* memReporter)
  2243. {
  2244. if (mGenericTypeInfo != NULL)
  2245. mGenericTypeInfo->ReportMemory(memReporter);
  2246. memReporter->Add(sizeof(BfTypeInstance));
  2247. int depSize = 0;
  2248. depSize += sizeof((int)mDependencyMap.mTypeSet.mAllocSize * sizeof(BfDependencyMap::TypeMap::EntryPair));
  2249. memReporter->Add("DepMap", depSize);
  2250. memReporter->AddVec(mInterfaces, false);
  2251. memReporter->AddVec(mInterfaceMethodTable, false);
  2252. if (mCustomAttributes != NULL)
  2253. mCustomAttributes->ReportMemory(memReporter);
  2254. int methodCount = 0;
  2255. memReporter->BeginSection("MethodData");
  2256. for (auto& methodInstGroup : mMethodInstanceGroups)
  2257. {
  2258. memReporter->Add(sizeof(BfMethodInstanceGroup));
  2259. if (methodInstGroup.mDefault != NULL)
  2260. {
  2261. methodInstGroup.mDefault->ReportMemory(memReporter);
  2262. methodCount++;
  2263. }
  2264. if (methodInstGroup.mMethodSpecializationMap != NULL)
  2265. {
  2266. memReporter->Add((int)methodInstGroup.mMethodSpecializationMap->mAllocSize * sizeof(Dictionary<BfTypeVector, BfMethodInstance*>::EntryPair));
  2267. for (auto kv : *methodInstGroup.mMethodSpecializationMap)
  2268. {
  2269. methodCount++;
  2270. kv.mValue->ReportMemory(memReporter);
  2271. }
  2272. }
  2273. }
  2274. memReporter->EndSection();
  2275. memReporter->AddVec("VirtualMethodTable", mVirtualMethodTable, false);
  2276. memReporter->AddVec(mFieldInstances, false);
  2277. memReporter->AddVec(mInternalMethods, false);
  2278. memReporter->AddMap("SpecializedMethodReferences", mSpecializedMethodReferences, false);
  2279. memReporter->AddMap("LookupResults", mLookupResults, false);
  2280. if (mConstHolder != NULL)
  2281. memReporter->Add("ConstHolder", mConstHolder->mTempAlloc.GetTotalAllocSize());
  2282. if (mHotTypeData != NULL)
  2283. {
  2284. AutoMemReporter autoMemReporter(memReporter, "HotTypeData");
  2285. memReporter->Add(sizeof(BfHotTypeData));
  2286. memReporter->AddVec(mHotTypeData->mTypeVersions, false);
  2287. for (auto typeVersion : mHotTypeData->mTypeVersions)
  2288. {
  2289. memReporter->AddVec(typeVersion->mMembers, false);
  2290. memReporter->AddVec(typeVersion->mInterfaceMapping, false);
  2291. }
  2292. memReporter->AddVec(mHotTypeData->mVTableEntries, false);
  2293. for (auto& entry : mHotTypeData->mVTableEntries)
  2294. memReporter->AddStr(entry.mFuncName, false);
  2295. }
  2296. BfLog("%s\t%d\t%d\n", mContext->mScratchModule->TypeToString(this, BfTypeNameFlags_None).c_str(), IsGenericTypeInstance(), methodCount);
  2297. }
  2298. bool BfTypeInstance::IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfTypeDef* activeTypeDef)
  2299. {
  2300. if (activeTypeDef == NULL)
  2301. return false;
  2302. if (declaringTypeDef == activeTypeDef)
  2303. return true;
  2304. return activeTypeDef->mProject->ContainsReference(declaringTypeDef->mProject);
  2305. }
  2306. bool BfTypeInstance::IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfProject* curProject)
  2307. {
  2308. if (declaringTypeDef->mProject == curProject)
  2309. return true;
  2310. return curProject->ContainsReference(declaringTypeDef->mProject);
  2311. }
  2312. bool BfTypeInstance::IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfProjectSet* visibleProjectSet)
  2313. {
  2314. if (visibleProjectSet == NULL)
  2315. return false;
  2316. return visibleProjectSet->Contains(declaringTypeDef->mProject);
  2317. }
  2318. bool BfTypeInstance::WantsGCMarking()
  2319. {
  2320. BF_ASSERT(mTypeDef->mTypeCode != BfTypeCode_Extension);
  2321. if (IsObjectOrInterface())
  2322. return true;
  2323. if ((IsEnum()) && (!IsPayloadEnum()))
  2324. return false;
  2325. BF_ASSERT((mDefineState >= BfTypeDefineState_Defined) || (mTypeFailed));
  2326. return mWantsGCMarking;
  2327. }
  2328. ///
  2329. BfGenericExtensionEntry::~BfGenericExtensionEntry()
  2330. {
  2331. for (auto genericParamInstance : mGenericParams)
  2332. genericParamInstance->Release();
  2333. }
  2334. ///
  2335. BfGenericTypeInfo::~BfGenericTypeInfo()
  2336. {
  2337. for (auto genericParamInstance : mGenericParams)
  2338. genericParamInstance->Release();
  2339. delete mGenericExtensionInfo;
  2340. }
  2341. BfGenericTypeInfo::GenericParamsVector* BfTypeInstance::GetGenericParamsVector(BfTypeDef* declaringTypeDef)
  2342. {
  2343. if (mGenericTypeInfo == NULL)
  2344. return NULL;
  2345. if ((declaringTypeDef == mTypeDef) ||
  2346. (declaringTypeDef->mTypeDeclaration == mTypeDef->mTypeDeclaration))
  2347. return &mGenericTypeInfo->mGenericParams;
  2348. if (mGenericTypeInfo->mGenericExtensionInfo == NULL)
  2349. return NULL;
  2350. BfGenericExtensionEntry* genericExEntry = NULL;
  2351. if (mGenericTypeInfo->mGenericExtensionInfo->mExtensionMap.TryGetValue(declaringTypeDef, &genericExEntry))
  2352. return &genericExEntry->mGenericParams;
  2353. return &mGenericTypeInfo->mGenericParams;
  2354. }
  2355. void BfTypeInstance::GenerateProjectsReferenced()
  2356. {
  2357. if (mGenericTypeInfo == NULL)
  2358. return;
  2359. BF_ASSERT(mGenericTypeInfo->mProjectsReferenced.empty());
  2360. mGenericTypeInfo->mProjectsReferenced.push_back(mTypeDef->mProject);
  2361. for (auto genericArgType : mGenericTypeInfo->mTypeGenericArguments)
  2362. BfTypeUtils::GetProjectList(genericArgType, &mGenericTypeInfo->mProjectsReferenced, 0);
  2363. }
  2364. bool BfTypeInstance::IsAlwaysInclude()
  2365. {
  2366. bool alwaysInclude = mTypeDef->mIsAlwaysInclude || mTypeDef->mProject->mAlwaysIncludeAll;
  2367. if (mTypeOptionsIdx > 0)
  2368. {
  2369. auto typeOptions = mModule->mSystem->GetTypeOptions(mTypeOptionsIdx);
  2370. typeOptions->Apply(alwaysInclude, BfOptionFlags_ReflectAlwaysIncludeType);
  2371. }
  2372. if ((mAlwaysIncludeFlags & BfAlwaysIncludeFlag_Type) != 0)
  2373. alwaysInclude = true;
  2374. return alwaysInclude;
  2375. }
  2376. bool BfTypeInstance::IsSpecializedByAutoCompleteMethod()
  2377. {
  2378. if (mGenericTypeInfo == NULL)
  2379. return false;
  2380. for (auto methodArg : mGenericTypeInfo->mTypeGenericArguments)
  2381. {
  2382. // If we are specialized by an autocompleted method reference
  2383. if (methodArg->IsMethodRef())
  2384. {
  2385. auto methodRefType = (BfMethodRefType*)methodArg;
  2386. if (methodRefType->mIsAutoCompleteMethod)
  2387. return true;
  2388. }
  2389. }
  2390. return false;
  2391. }
  2392. bool BfTypeInstance::IsNullable()
  2393. {
  2394. return IsInstanceOf(mContext->mCompiler->mNullableTypeDef);
  2395. }
  2396. bool BfTypeInstance::HasVarConstraints()
  2397. {
  2398. if (mGenericTypeInfo == NULL)
  2399. return false;
  2400. for (auto genericParam : mGenericTypeInfo->mGenericParams)
  2401. {
  2402. if (genericParam->mGenericParamFlags & BfGenericParamFlag_Var)
  2403. return true;
  2404. }
  2405. return false;
  2406. }
  2407. bool BfTypeInstance::IsTypeMemberIncluded(BfTypeDef* typeDef, BfTypeDef* activeTypeDef, BfModule* module)
  2408. {
  2409. if (mGenericTypeInfo == NULL)
  2410. return true;
  2411. if (mGenericTypeInfo->mGenericExtensionInfo == NULL)
  2412. return true;
  2413. if ((typeDef == NULL) || (typeDef == activeTypeDef))
  2414. return true;
  2415. // The combined type declaration is the root type declaration, it's implicitly included
  2416. if (typeDef->mTypeDeclaration == mTypeDef->mTypeDeclaration)
  2417. return true;
  2418. BfGenericExtensionEntry* genericExEntry = NULL;
  2419. if (!mGenericTypeInfo->mGenericExtensionInfo->mExtensionMap.TryGetValue(typeDef, &genericExEntry))
  2420. return true;
  2421. if (mGenericTypeInfo->mIsUnspecialized)
  2422. {
  2423. if (module == NULL)
  2424. return true; // During population
  2425. auto declConstraints = &genericExEntry->mGenericParams;
  2426. for (int genericIdx = 0; genericIdx < (int)declConstraints->size(); genericIdx++)
  2427. {
  2428. auto declGenericParam = (*declConstraints)[genericIdx];
  2429. BfType* genericArg;
  2430. if (genericIdx < (int)mGenericTypeInfo->mTypeGenericArguments.size())
  2431. {
  2432. genericArg = mGenericTypeInfo->mTypeGenericArguments[genericIdx];
  2433. }
  2434. else
  2435. {
  2436. genericArg = declGenericParam->mExternType;
  2437. }
  2438. if ((genericArg == NULL) || (!module->CheckGenericConstraints(BfGenericParamSource(), genericArg, NULL, declGenericParam)))
  2439. return false;
  2440. }
  2441. return true;
  2442. }
  2443. return genericExEntry->mConstraintsPassed;
  2444. }
  2445. bool BfTypeInstance::IsZeroGap()
  2446. {
  2447. BF_ASSERT(mDefineState >= BfTypeDefineState_Defined);
  2448. for (int fieldIdx = mFieldInstances.mSize - 1; fieldIdx >= 0; fieldIdx--)
  2449. {
  2450. auto fieldInstance = &mFieldInstances[fieldIdx];
  2451. auto fieldDef = fieldInstance->GetFieldDef();
  2452. if (fieldDef == NULL)
  2453. continue;
  2454. if ((!fieldDef->mIsStatic) && (fieldDef->mDeclaringType->IsExtension()) && (!fieldInstance->mResolvedType->IsValuelessType()))
  2455. return false;
  2456. }
  2457. return true;
  2458. }
  2459. void BfGenericTypeInfo::ReportMemory(MemReporter* memReporter)
  2460. {
  2461. memReporter->Add(sizeof(BfGenericTypeInfo));
  2462. memReporter->AddVec(mTypeGenericArguments, false);
  2463. memReporter->AddVec(mGenericParams, false);
  2464. memReporter->AddVec(mProjectsReferenced, false);
  2465. }
  2466. BfType* BfTypeInstance::GetUnderlyingType()
  2467. {
  2468. if (!mIsTypedPrimitive)
  2469. {
  2470. if ((mGenericTypeInfo != NULL) && (!mGenericTypeInfo->mTypeGenericArguments.IsEmpty()))
  2471. return mGenericTypeInfo->mTypeGenericArguments[0];
  2472. return NULL;
  2473. }
  2474. if (mTypeInfoEx == NULL)
  2475. mTypeInfoEx = new BfTypeInfoEx();
  2476. if (mTypeInfoEx->mUnderlyingType != NULL)
  2477. return mTypeInfoEx->mUnderlyingType;
  2478. auto checkTypeInst = this;
  2479. while (checkTypeInst != NULL)
  2480. {
  2481. if (!checkTypeInst->mFieldInstances.empty())
  2482. {
  2483. auto& lastField = checkTypeInst->mFieldInstances.back();
  2484. if (lastField.mFieldIdx == -1)
  2485. {
  2486. auto underlyingType = lastField.mResolvedType;
  2487. BF_ASSERT(underlyingType != this);
  2488. mTypeInfoEx->mUnderlyingType = underlyingType;
  2489. return mTypeInfoEx->mUnderlyingType;
  2490. }
  2491. }
  2492. checkTypeInst = checkTypeInst->mBaseType;
  2493. if ((checkTypeInst != NULL) && (checkTypeInst->IsIncomplete()))
  2494. mModule->PopulateType(checkTypeInst, BfPopulateType_Data);
  2495. }
  2496. //BF_FATAL("Failed");
  2497. return mTypeInfoEx->mUnderlyingType;
  2498. }
  2499. bool BfTypeInstance::IsValuelessType()
  2500. {
  2501. BF_ASSERT(mTypeDef->mTypeCode != BfTypeCode_Extension);
  2502. if ((mTypeDef->mTypeCode == BfTypeCode_Object) || (mTypeDef->mTypeCode == BfTypeCode_Interface))
  2503. {
  2504. return false;
  2505. }
  2506. if (mTypeDef->mIsOpaque)
  2507. {
  2508. return true;
  2509. }
  2510. BF_ASSERT((mDefineState >= BfTypeDefineState_Defined) || (mTypeFailed));
  2511. BF_ASSERT(mInstSize >= 0);
  2512. if (mInstSize == 0)
  2513. {
  2514. return true;
  2515. }
  2516. return false;
  2517. }
  2518. bool BfTypeInstance::IsValuelessCReprType()
  2519. {
  2520. if (!mIsCRepr)
  2521. return false;
  2522. if (mInstSize > 1)
  2523. return false;
  2524. if ((mBaseType->mIsCRepr) && (!IsValuelessCReprType()))
  2525. return false;
  2526. BF_ASSERT((mDefineState >= BfTypeDefineState_Defined) || (mTypeFailed));
  2527. for (auto& fieldInst : mFieldInstances)
  2528. {
  2529. if (fieldInst.mDataIdx >= 0)
  2530. return false;
  2531. }
  2532. return true;
  2533. }
  2534. BfTypeInstance* BfTypeInstance::GetBaseType(bool remapValuelessCRepr)
  2535. {
  2536. if (!remapValuelessCRepr)
  2537. return mBaseType;
  2538. auto checkType = mBaseType;
  2539. while (checkType != NULL)
  2540. {
  2541. if (!checkType->IsValuelessCReprType())
  2542. break;
  2543. checkType = checkType->mBaseType;
  2544. }
  2545. return checkType;
  2546. }
  2547. bool BfTypeInstance::IsIRFuncUsed(BfIRFunction func)
  2548. {
  2549. for (auto& group : mMethodInstanceGroups)
  2550. {
  2551. if (group.mDefault != NULL)
  2552. if (group.mDefault->mIRFunction == func)
  2553. return true;
  2554. if (group.mMethodSpecializationMap != NULL)
  2555. {
  2556. for (auto& methodInstPair : *group.mMethodSpecializationMap)
  2557. {
  2558. auto methodInstance = methodInstPair.mValue;
  2559. if (methodInstance->mIRFunction == func)
  2560. return true;
  2561. }
  2562. }
  2563. }
  2564. return false;
  2565. }
  2566. void BfTypeInstance::CalcHotVirtualData(Array<int>* ifaceMapping)
  2567. {
  2568. if (IsIncomplete())
  2569. {
  2570. BF_ASSERT(mHotTypeData != NULL);
  2571. return;
  2572. }
  2573. if (ifaceMapping != NULL)
  2574. {
  2575. for (auto iface : mInterfaces)
  2576. {
  2577. int slotNum = iface.mInterfaceType->mSlotNum;
  2578. if (slotNum >= 0)
  2579. {
  2580. if (slotNum >= (int)ifaceMapping->size())
  2581. ifaceMapping->Resize(slotNum + 1);
  2582. (*ifaceMapping)[slotNum] = iface.mInterfaceType->mTypeId;
  2583. }
  2584. }
  2585. if (mBaseType != NULL)
  2586. mBaseType->CalcHotVirtualData(ifaceMapping);
  2587. }
  2588. }
  2589. //////////////////////////////////////////////////////////////////////////
  2590. BfClosureType::BfClosureType(BfTypeInstance* srcDelegate, Val128 closureHash) :
  2591. mSource(srcDelegate->mTypeDef->mSystem)
  2592. {
  2593. BF_ASSERT(srcDelegate->IsDelegate());
  2594. mSrcDelegate = srcDelegate;
  2595. mTypeDef = mSrcDelegate->mTypeDef;
  2596. mCreatedTypeDef = false;
  2597. mClosureHash = closureHash;
  2598. // Hash in 72 bits of closureHash (12 characters) - low does 60 bits, high does 12 bits
  2599. mNameAdd = "_" + BfTypeUtils::HashEncode64(mClosureHash.mLow) + BfTypeUtils::HashEncode64(mClosureHash.mHigh >> 52);
  2600. mIsUnique = false;
  2601. }
  2602. BfClosureType::~BfClosureType()
  2603. {
  2604. mMethodInstanceGroups.Clear();
  2605. if (mCreatedTypeDef)
  2606. {
  2607. delete mTypeDef;
  2608. mTypeDef = NULL;
  2609. }
  2610. for (auto directAllocNode : mDirectAllocNodes)
  2611. delete directAllocNode;
  2612. }
  2613. void BfClosureType::Init(BfProject* bfProject)
  2614. {
  2615. auto srcTypeDef = mSrcDelegate->mTypeDef;
  2616. auto system = mSrcDelegate->mModule->mSystem;
  2617. mTypeDef = new BfTypeDef();
  2618. mTypeDef->mSystem = system;
  2619. mTypeDef->mSource = &mSource;
  2620. mTypeDef->mSource->mRefCount++;
  2621. mTypeDef->mProject = bfProject;
  2622. mTypeDef->mTypeCode = srcTypeDef->mTypeCode;
  2623. mTypeDef->mName = system->GetAtom(srcTypeDef->mName->mString + mNameAdd);
  2624. // Purposely leave out 'mOuterType' - this fails if the outer type is generic
  2625. //mTypeDef->mOuterType = srcTypeDef->mOuterType;
  2626. mTypeDef->mNamespace = srcTypeDef->mNamespace;
  2627. system->AddNamespaceUsage(mTypeDef->mNamespace, mTypeDef->mProject);
  2628. mTypeDef->mHash = srcTypeDef->mHash;
  2629. mTypeDef->mSignatureHash = srcTypeDef->mSignatureHash;
  2630. // mTypeDef->mFullName = srcTypeDef->mFullName;
  2631. // if (!mTypeDef->mFullName.mParts.IsEmpty())
  2632. // mTypeDef->mFullName.mParts.pop_back();
  2633. // mTypeDef->mFullName.mParts.push_back(mTypeDef->mName);
  2634. if (srcTypeDef->mFullName.mSize > 0)
  2635. mTypeDef->mFullName.Set(srcTypeDef->mFullName.mParts, srcTypeDef->mFullName.mSize - 1, &mTypeDef->mName, 1);
  2636. else
  2637. mTypeDef->mFullName.Set(&mTypeDef->mName, 1, NULL, 0);
  2638. system->TrackName(mTypeDef);
  2639. mTypeDef->mTypeCode = BfTypeCode_Object;
  2640. mTypeDef->mIsDelegate = true;
  2641. mTypeDef->mIsClosure = true;
  2642. mTypeDef->mDefState = BfTypeDef::DefState_Defined;
  2643. auto baseDirectTypeRef = BfAstNode::ZeroedAlloc<BfDirectTypeReference>();
  2644. baseDirectTypeRef->Init(mSrcDelegate);
  2645. mDirectAllocNodes.push_back(baseDirectTypeRef);
  2646. mTypeDef->mBaseTypes.push_back(baseDirectTypeRef);
  2647. //mTypeDef->mBaseTypes.push_back(BfDefBuilder::AllocTypeReference(&mSource, mSrcDelegate));
  2648. mCreatedTypeDef = true;
  2649. //mTypeDef->mBaseTypes.push_back(srcTypeDef);
  2650. }
  2651. BfFieldDef* BfClosureType::AddField(BfType* type, const StringImpl& name)
  2652. {
  2653. auto directTypeRef = BfAstNode::ZeroedAlloc<BfDirectTypeReference>();
  2654. directTypeRef->Init(type);
  2655. mDirectAllocNodes.push_back(directTypeRef);
  2656. return BfDefBuilder::AddField(mTypeDef, directTypeRef, name);
  2657. }
  2658. BfMethodDef* BfClosureType::AddDtor()
  2659. {
  2660. return BfDefBuilder::AddDtor(mTypeDef);
  2661. }
  2662. void BfClosureType::Finish()
  2663. {
  2664. HASH128_MIXIN(mTypeDef->mSignatureHash, mClosureHash);
  2665. auto bfSource = mTypeDef->mSource;
  2666. auto bfSystem = bfSource->mSystem;
  2667. BfDefBuilder bfDefBuilder(bfSystem);
  2668. bfDefBuilder.mCurTypeDef = mTypeDef;
  2669. bfDefBuilder.FinishTypeDef(false);
  2670. }
  2671. //////////////////////////////////////////////////////////////////////////
  2672. BfDelegateType::~BfDelegateType()
  2673. {
  2674. mMethodInstanceGroups.Clear();
  2675. delete mTypeDef;
  2676. mTypeDef = NULL;
  2677. }
  2678. void BfDelegateType::Dispose()
  2679. {
  2680. delete mTypeDef;
  2681. mTypeDef = NULL;
  2682. BfTypeInstance::Dispose();
  2683. }
  2684. //////////////////////////////////////////////////////////////////////////
  2685. BfTupleType::BfTupleType()
  2686. {
  2687. mCreatedTypeDef = false;
  2688. mSource = NULL;
  2689. mTypeDef = NULL;
  2690. mIsUnspecializedType = false;
  2691. mIsUnspecializedTypeVariation = false;
  2692. mGenericDepth = 0;
  2693. }
  2694. BfTupleType::~BfTupleType()
  2695. {
  2696. mMethodInstanceGroups.Clear();
  2697. if (mCreatedTypeDef)
  2698. {
  2699. delete mTypeDef;
  2700. mTypeDef = NULL;
  2701. }
  2702. delete mSource;
  2703. }
  2704. void BfTupleType::Init(BfProject* bfProject, BfTypeInstance* valueTypeInstance)
  2705. {
  2706. auto srcTypeDef = valueTypeInstance->mTypeDef;
  2707. auto system = valueTypeInstance->mModule->mSystem;
  2708. if (mTypeDef == NULL)
  2709. mTypeDef = new BfTypeDef();
  2710. for (auto field : mTypeDef->mFields)
  2711. delete field;
  2712. mTypeDef->mFields.Clear();
  2713. mTypeDef->mSystem = system;
  2714. mTypeDef->mProject = bfProject;
  2715. mTypeDef->mTypeCode = srcTypeDef->mTypeCode;
  2716. mTypeDef->mName = system->mEmptyAtom;
  2717. mTypeDef->mSystem = system;
  2718. mTypeDef->mHash = srcTypeDef->mHash;
  2719. mTypeDef->mSignatureHash = srcTypeDef->mSignatureHash;
  2720. mTypeDef->mTypeCode = BfTypeCode_Struct;
  2721. mCreatedTypeDef = true;
  2722. }
  2723. void BfTupleType::Dispose()
  2724. {
  2725. if (mCreatedTypeDef)
  2726. {
  2727. delete mTypeDef;
  2728. mTypeDef = NULL;
  2729. mCreatedTypeDef = false;
  2730. }
  2731. BfTypeInstance::Dispose();
  2732. }
  2733. BfFieldDef* BfTupleType::AddField(const StringImpl& name)
  2734. {
  2735. return BfDefBuilder::AddField(mTypeDef, NULL, name);
  2736. }
  2737. void BfTupleType::Finish()
  2738. {
  2739. BF_ASSERT(!mTypeFailed);
  2740. auto bfSystem = mTypeDef->mSystem;
  2741. mSource = new BfSource(bfSystem);
  2742. mTypeDef->mSource = mSource;
  2743. mTypeDef->mSource->mRefCount++;
  2744. BfDefBuilder bfDefBuilder(bfSystem);
  2745. bfDefBuilder.mCurTypeDef = mTypeDef;
  2746. bfDefBuilder.mCurDeclaringTypeDef = mTypeDef;
  2747. bfDefBuilder.FinishTypeDef(true);
  2748. }
  2749. //////////////////////////////////////////////////////////////////////////
  2750. BfTagType::BfTagType()
  2751. {
  2752. mCreatedTypeDef = false;
  2753. mSource = NULL;
  2754. mTypeDef = NULL;
  2755. }
  2756. BfTagType::~BfTagType()
  2757. {
  2758. mMethodInstanceGroups.Clear();
  2759. if (mCreatedTypeDef)
  2760. {
  2761. delete mTypeDef;
  2762. mTypeDef = NULL;
  2763. }
  2764. delete mSource;
  2765. }
  2766. void BfTagType::Init(BfProject* bfProject, BfTypeInstance* valueTypeInstance, const StringImpl& name)
  2767. {
  2768. auto srcTypeDef = valueTypeInstance->mTypeDef;
  2769. auto system = valueTypeInstance->mModule->mSystem;
  2770. if (mTypeDef == NULL)
  2771. mTypeDef = new BfTypeDef();
  2772. for (auto field : mTypeDef->mFields)
  2773. delete field;
  2774. mTypeDef->mFields.Clear();
  2775. mTypeDef->mSystem = system;
  2776. mTypeDef->mProject = bfProject;
  2777. mTypeDef->mTypeCode = srcTypeDef->mTypeCode;
  2778. mTypeDef->mName = system->mEmptyAtom;
  2779. mTypeDef->mSystem = system;
  2780. mTypeDef->mHash = srcTypeDef->mHash;
  2781. mTypeDef->mSignatureHash = srcTypeDef->mSignatureHash;
  2782. mTypeDef->mTypeCode = BfTypeCode_Enum;
  2783. mCreatedTypeDef = true;
  2784. auto field = BfDefBuilder::AddField(mTypeDef, NULL, name);
  2785. field->mIsStatic = true;
  2786. field->mIsConst = true;
  2787. }
  2788. void BfTagType::Dispose()
  2789. {
  2790. if (mCreatedTypeDef)
  2791. {
  2792. delete mTypeDef;
  2793. mTypeDef = NULL;
  2794. mCreatedTypeDef = false;
  2795. }
  2796. BfTypeInstance::Dispose();
  2797. }
  2798. void BfTagType::Finish()
  2799. {
  2800. BF_ASSERT(!mTypeFailed);
  2801. auto bfSystem = mTypeDef->mSystem;
  2802. mSource = new BfSource(bfSystem);
  2803. mTypeDef->mSource = mSource;
  2804. mTypeDef->mSource->mRefCount++;
  2805. BfDefBuilder bfDefBuilder(bfSystem);
  2806. bfDefBuilder.mCurTypeDef = mTypeDef;
  2807. bfDefBuilder.mCurDeclaringTypeDef = mTypeDef;
  2808. bfDefBuilder.FinishTypeDef(true);
  2809. }
  2810. //////////////////////////////////////////////////////////////////////////
  2811. BfBoxedType::~BfBoxedType()
  2812. {
  2813. //if ((mTypeDef != NULL) && (mTypeDef->mEmitParent != NULL))
  2814. mTypeDef = NULL;
  2815. }
  2816. BfType* BfBoxedType::GetModifiedElementType()
  2817. {
  2818. if ((mBoxedFlags & BoxedFlags_StructPtr) != 0)
  2819. {
  2820. auto module = mModule;
  2821. if (module == NULL)
  2822. module = mContext->mUnreifiedModule;
  2823. return module->CreatePointerType(mElementType);
  2824. }
  2825. return mElementType;
  2826. }
  2827. //////////////////////////////////////////////////////////////////////////
  2828. int BfArrayType::GetLengthBitCount()
  2829. {
  2830. if (mBaseType == NULL)
  2831. mModule->PopulateType(mBaseType, BfPopulateType_BaseType);
  2832. mModule->PopulateType(mBaseType);
  2833. if ((mBaseType->mFieldInstances.size() == 0) || (mBaseType->mFieldInstances[0].GetFieldDef()->mName != "mLength"))
  2834. {
  2835. return 0;
  2836. }
  2837. return mBaseType->mFieldInstances[0].mResolvedType->mSize * 8;
  2838. }
  2839. //////////////////////////////////////////////////////////////////////////
  2840. int BfMethodRefType::GetCaptureDataCount()
  2841. {
  2842. if (mMethodRef == NULL)
  2843. return 0;
  2844. return (int)mDataToParamIdx.size();
  2845. }
  2846. BfType* BfMethodRefType::GetCaptureType(int captureDataIdx)
  2847. {
  2848. return mMethodRef->GetParamType(mDataToParamIdx[captureDataIdx]);
  2849. }
  2850. int BfMethodRefType::GetDataIdxFromParamIdx(int paramIdx)
  2851. {
  2852. if (paramIdx == -1)
  2853. {
  2854. if (mMethodRef->HasThis())
  2855. return 0;
  2856. return -1;
  2857. }
  2858. return mParamToDataIdx[paramIdx];
  2859. }
  2860. int BfMethodRefType::GetParamIdxFromDataIdx(int dataIdx)
  2861. {
  2862. return mDataToParamIdx[dataIdx];
  2863. }
  2864. bool BfMethodRefType::WantsDataPassedAsSplat(int dataIdx)
  2865. {
  2866. if (dataIdx != -1)
  2867. return false;
  2868. return mMethodRef->GetParamIsSplat(mDataToParamIdx[dataIdx]);
  2869. }
  2870. //////////////////////////////////////////////////////////////////////////
  2871. size_t BfTypeVectorHash::operator()(const BfTypeVector& typeVec) const
  2872. {
  2873. size_t hash = typeVec.size();
  2874. BfResolvedTypeSet::LookupContext ctx;
  2875. for (auto type : typeVec)
  2876. hash = ((hash ^ BfResolvedTypeSet::Hash(type, &ctx, Beefy::BfResolvedTypeSet::BfHashFlag_None, 0)) << 5) - hash;
  2877. return hash;
  2878. }
  2879. bool BfTypeVectorEquals::operator()(const BfTypeVector& lhs, const BfTypeVector& rhs) const
  2880. {
  2881. if (lhs.size() != rhs.size())
  2882. return false;
  2883. for (int i = 0; i < (int)lhs.size(); i++)
  2884. if (lhs[i] != rhs[i])
  2885. return false;
  2886. return true;
  2887. }
  2888. //////////////////////////////////////////////////////////////////////////
  2889. bool BfCustomAttributes::Contains(BfTypeDef* typeDef)
  2890. {
  2891. for (auto& customAttr : mAttributes)
  2892. if (customAttr.mType->mTypeDef->GetDefinition() == typeDef)
  2893. return true;
  2894. return false;
  2895. }
  2896. BfCustomAttribute* BfCustomAttributes::Get(BfTypeDef * typeDef)
  2897. {
  2898. for (auto& customAttr : mAttributes)
  2899. if (customAttr.mType->mTypeDef->GetDefinition() == typeDef)
  2900. return &customAttr;
  2901. return NULL;
  2902. }
  2903. BfCustomAttribute* BfCustomAttributes::Get(BfType* type)
  2904. {
  2905. for (auto& customAttr : mAttributes)
  2906. if (customAttr.mType == type)
  2907. return &customAttr;
  2908. return NULL;
  2909. }
  2910. BfCustomAttribute* BfCustomAttributes::Get(int idx)
  2911. {
  2912. if (idx >= mAttributes.size())
  2913. return NULL;
  2914. return &mAttributes[idx];
  2915. }
  2916. //////////////////////////////////////////////////////////////////////////
  2917. BfResolvedTypeSet::~BfResolvedTypeSet()
  2918. {
  2919. }
  2920. #define HASH_MIX(origHashVal, newHashVal) ((((origHashVal) << 5) - (origHashVal)) ^ (newHashVal))
  2921. #define HASH_VAL_PTR 1
  2922. #define HASH_VAL_BOXED 2
  2923. #define HASH_VAL_REF 3
  2924. #define HASH_VAL_OUT 4
  2925. #define HASH_VAL_MUT 5
  2926. #define HASH_MODTYPE 6
  2927. #define HASH_CONCRETE_INTERFACE 7
  2928. #define HASH_SIZED_ARRAY 8
  2929. #define HASH_CONSTTYPE 9
  2930. #define HASH_VAL_TUPLE 10
  2931. #define HASH_DELEGATE 11
  2932. #define HASH_CONSTEXPR 12
  2933. #define HASH_GLOBAL 13
  2934. #define HASH_DOTDOTDOT 14
  2935. #define HASH_TAG 15
  2936. BfVariant BfResolvedTypeSet::EvaluateToVariant(LookupContext* ctx, BfExpression* expr, BfType*& outType)
  2937. {
  2938. outType = NULL;
  2939. BfMethodState methodState;
  2940. methodState.mTempKind = BfMethodState::TempKind_Static;
  2941. SetAndRestoreValue<BfMethodState*> prevMethodState;
  2942. if (ctx->mModule->mCurMethodState == NULL)
  2943. prevMethodState.Init(ctx->mModule->mCurMethodState, &methodState);
  2944. BfConstResolver constResolver(ctx->mModule);
  2945. BfVariant variant;
  2946. constResolver.mBfEvalExprFlags = BfEvalExprFlags_NoCast;
  2947. constResolver.mBfEvalExprFlags = (BfEvalExprFlags)(constResolver.mBfEvalExprFlags | BfEvalExprFlags_AllowGenericConstValue);
  2948. constResolver.mExpectingType = ctx->mModule->GetPrimitiveType(BfTypeCode_Int64);
  2949. auto result = constResolver.Resolve(expr);
  2950. if (result)
  2951. {
  2952. // Limit the types of constants to prevent duplicate values with different types - we don't want to hash a typeref with an int32
  2953. // when the constraint requirement is int64 (but we don't know that at hash time)
  2954. if ((result.mType->IsInteger()) && ((result.mType->mSize < 8) || (result.mType->GetTypeCode() == BfTypeCode_IntPtr)))
  2955. result = ctx->mModule->Cast(expr, result, ctx->mModule->GetPrimitiveType(BfTypeCode_Int64));
  2956. else if ((result.mType->IsFloat()) && (result.mType->mSize < 8))
  2957. result = ctx->mModule->Cast(expr, result, ctx->mModule->GetPrimitiveType(BfTypeCode_Double));
  2958. else if ((result.mType->IsChar()) && (result.mType->mSize < 4))
  2959. result = ctx->mModule->Cast(expr, result, ctx->mModule->GetPrimitiveType(BfTypeCode_Char32));
  2960. outType = result.mType;
  2961. if (result.mKind == BfTypedValueKind_GenericConstValue)
  2962. {
  2963. return variant;
  2964. }
  2965. else
  2966. {
  2967. variant = ctx->mModule->TypedValueToVariant(expr, result, true);
  2968. }
  2969. }
  2970. return variant;
  2971. }
  2972. int BfResolvedTypeSet::DoHash(BfType* type, LookupContext* ctx, bool allowRef, int hashSeed)
  2973. {
  2974. //BP_ZONE("BfResolvedTypeSet::Hash");
  2975. // if (type->IsTypeAlias())
  2976. // {
  2977. // auto underlyingType = type->GetUnderlyingType();
  2978. // BF_ASSERT(underlyingType != NULL);
  2979. // if (underlyingType == NULL)
  2980. // {
  2981. // ctx->mFailed = true;
  2982. // return 0;
  2983. // }
  2984. // return Hash(underlyingType, ctx, allowRef);
  2985. // }
  2986. // else
  2987. if (type->IsBoxed())
  2988. {
  2989. BfBoxedType* boxedType = (BfBoxedType*)type;
  2990. int elemHash = Hash(boxedType->mElementType, ctx, BfHashFlag_None, hashSeed) ^ HASH_VAL_BOXED;
  2991. return (elemHash << 5) - elemHash;
  2992. }
  2993. else if (type->IsArray())
  2994. {
  2995. BfArrayType* arrayType = (BfArrayType*)type;
  2996. int elemHash = Hash(arrayType->mGenericTypeInfo->mTypeGenericArguments[0], ctx, BfHashFlag_None, hashSeed) ^ (arrayType->mDimensions << 8);
  2997. return (elemHash << 5) - elemHash;
  2998. }
  2999. else if (type->IsDelegateFromTypeRef() || type->IsFunctionFromTypeRef())
  3000. {
  3001. auto typeInst = (BfTypeInstance*)type;
  3002. int hashVal = HASH_DELEGATE;
  3003. auto delegateInfo = type->GetDelegateInfo();
  3004. hashVal = HASH_MIX(hashVal, Hash(delegateInfo->mReturnType, ctx, BfHashFlag_None, hashSeed + 1));
  3005. auto methodDef = typeInst->mTypeDef->mMethods[0];
  3006. BF_ASSERT(methodDef->mName == "Invoke");
  3007. int infoParamCount = (int)delegateInfo->mParams.size();
  3008. if (delegateInfo->mHasVarArgs)
  3009. infoParamCount++;
  3010. BF_ASSERT(infoParamCount == methodDef->mParams.size());
  3011. for (int paramIdx = 0; paramIdx < delegateInfo->mParams.size(); paramIdx++)
  3012. {
  3013. // Parse attributes?
  3014. hashVal = HASH_MIX(hashVal, Hash(delegateInfo->mParams[paramIdx], ctx, BfHashFlag_None, hashSeed + 1));
  3015. String paramName = methodDef->mParams[paramIdx]->mName;
  3016. int nameHash = (int)Hash64(paramName.c_str(), (int)paramName.length());
  3017. hashVal = HASH_MIX(hashVal, nameHash);
  3018. }
  3019. if (delegateInfo->mHasVarArgs)
  3020. hashVal = HASH_MIX(hashVal, HASH_DOTDOTDOT);
  3021. return hashVal;
  3022. }
  3023. else if ((type->IsEnum()) && (type->IsOnDemand()))
  3024. {
  3025. BfTypeInstance* typeInstance = type->ToTypeInstance();
  3026. auto fieldName = typeInstance->mTypeDef->mFields[0]->mName;
  3027. int nameHash = (int)Hash64(fieldName.c_str(), (int)fieldName.length());
  3028. return nameHash ^ HASH_TAG;
  3029. }
  3030. else if (type->IsTypeInstance())
  3031. {
  3032. BfTypeInstance* typeInst = (BfTypeInstance*)type;
  3033. int hashVal;
  3034. if (typeInst->mTypeDef != NULL)
  3035. hashVal = typeInst->mTypeDef->mHash;
  3036. if (type->IsClosure())
  3037. {
  3038. auto closureType = (BfClosureType*)type;
  3039. if (closureType->mIsUnique)
  3040. return false;
  3041. hashVal = ((hashVal ^ (int)closureType->mClosureHash.mLow) << 5) - hashVal;
  3042. }
  3043. else if (type->IsTuple())
  3044. {
  3045. hashVal = HASH_VAL_TUPLE;
  3046. BfTypeInstance* tupleType = (BfTypeInstance*)type;
  3047. for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
  3048. {
  3049. BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx];
  3050. auto fieldType = fieldInstance->mResolvedType;
  3051. hashVal = HASH_MIX(hashVal, Hash(fieldType, ctx, BfHashFlag_None, hashSeed + 1));
  3052. BfFieldDef* fieldDef = NULL;
  3053. if (tupleType->mTypeDef != NULL)
  3054. fieldDef = fieldInstance->GetFieldDef();
  3055. int nameHash = 0;
  3056. if (fieldDef == NULL)
  3057. {
  3058. char nameStr[64];
  3059. sprintf(nameStr, "%d", fieldIdx);
  3060. nameHash = (int)Hash64(nameStr, strlen(nameStr));
  3061. }
  3062. else
  3063. {
  3064. nameHash = (int)Hash64(fieldDef->mName.c_str(), (int)fieldDef->mName.length());
  3065. }
  3066. hashVal = HASH_MIX(hashVal, nameHash);
  3067. }
  3068. }
  3069. else if (type->IsGenericTypeInstance())
  3070. {
  3071. BfTypeInstance* genericType = (BfTypeInstance*)type;
  3072. for (auto genericArg : genericType->mGenericTypeInfo->mTypeGenericArguments)
  3073. hashVal = HASH_MIX(hashVal, Hash(genericArg, ctx, BfHashFlag_None, hashSeed + 1));
  3074. }
  3075. return hashVal;
  3076. }
  3077. else if (type->IsPrimitiveType())
  3078. {
  3079. BfPrimitiveType* primType = (BfPrimitiveType*)type;
  3080. return primType->mTypeDef->mHash;
  3081. }
  3082. else if (type->IsPointer())
  3083. {
  3084. BfPointerType* pointerType = (BfPointerType*) type;
  3085. int elemHash = Hash(pointerType->mElementType, ctx, BfHashFlag_None, hashSeed) ^ HASH_VAL_PTR;
  3086. return (elemHash << 5) - elemHash;
  3087. }
  3088. else if (type->IsGenericParam())
  3089. {
  3090. auto genericParam = (BfGenericParamType*)type;
  3091. return (((int)genericParam->mGenericParamKind + 0xB00) << 8) ^ (genericParam->mGenericParamIdx + 1);
  3092. }
  3093. else if (type->IsRef())
  3094. {
  3095. auto refType = (BfRefType*)type;
  3096. int elemHash = Hash(refType->mElementType, ctx, BfHashFlag_None, hashSeed) ^ (HASH_VAL_REF + (int)refType->mRefKind);
  3097. return (elemHash << 5) - elemHash;
  3098. }
  3099. else if (type->IsModifiedTypeType())
  3100. {
  3101. auto modifiedTypeType = (BfModifiedTypeType*)type;
  3102. int elemHash = Hash(modifiedTypeType->mElementType, ctx, BfHashFlag_None, hashSeed) ^ HASH_MODTYPE + (int)modifiedTypeType->mModifiedKind;
  3103. return (elemHash << 5) - elemHash;
  3104. }
  3105. else if (type->IsConcreteInterfaceType())
  3106. {
  3107. auto concreteInterfaceType = (BfConcreteInterfaceType*)type;
  3108. int elemHash = Hash(concreteInterfaceType->mInterface, ctx, BfHashFlag_None, hashSeed) ^ HASH_CONCRETE_INTERFACE;
  3109. return (elemHash << 5) - elemHash;
  3110. }
  3111. else if (type->IsSizedArray())
  3112. {
  3113. auto sizedArray = (BfSizedArrayType*)type;
  3114. int elemHash = Hash(sizedArray->mElementType, ctx, BfHashFlag_None, hashSeed) ^ HASH_SIZED_ARRAY;
  3115. int hashVal = (elemHash << 5) - elemHash;
  3116. if (type->IsUnknownSizedArrayType())
  3117. {
  3118. auto unknownSizedArray = (BfUnknownSizedArrayType*)type;
  3119. int elemHash = Hash(unknownSizedArray->mElementCountSource, ctx, BfHashFlag_None, hashSeed);
  3120. hashVal = ((hashVal ^ elemHash) << 5) - hashVal;
  3121. }
  3122. else
  3123. hashVal = ((hashVal ^ (int)sizedArray->mElementCount) << 5) - hashVal;
  3124. return hashVal;
  3125. }
  3126. else if (type->IsMethodRef())
  3127. {
  3128. auto methodRefType = (BfMethodRefType*)type;
  3129. if (methodRefType->IsNull())
  3130. return 0;
  3131. return (int)((int)(intptr)(methodRefType->mMethodRef) << 5) ^ (int)(intptr)(methodRefType->mOwner) ^ methodRefType->mOwnerRevision;
  3132. }
  3133. else if (type->IsConstExprValue())
  3134. {
  3135. BfConstExprValueType* constExprValueType = (BfConstExprValueType*)type;
  3136. int32 dataHash = BeefHash<BfVariant>()(constExprValueType->mValue);
  3137. int hashVal = ((int)constExprValueType->mValue.mTypeCode << 17) ^ (dataHash << 3) ^ HASH_CONSTTYPE;
  3138. hashVal = ((hashVal ^ (Hash(constExprValueType->mType, ctx, BfHashFlag_AllowRef, hashSeed))) << 5) - hashVal;
  3139. return hashVal;
  3140. }
  3141. else
  3142. {
  3143. BF_FATAL("Not handled");
  3144. }
  3145. return 0;
  3146. }
  3147. int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef, int hashSeed)
  3148. {
  3149. int hashVal = DoHash(type, ctx, allowRef, hashSeed);
  3150. if (hashSeed == 0)
  3151. return hashVal;
  3152. return HASH_MIX(hashVal, hashSeed);
  3153. }
  3154. void BfResolvedTypeSet::HashGenericArguments(BfTypeReference* typeRef, LookupContext* ctx, int& hashVal, int hashSeed)
  3155. {
  3156. if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef))
  3157. {
  3158. for (int genericIdx = 0; genericIdx < BF_MAX(genericTypeRef->mGenericArguments.mSize, genericTypeRef->mCommas.mSize + 1); genericIdx++)
  3159. {
  3160. bool allowUnboundGeneric = ((ctx->mResolveFlags & BfResolveTypeRefFlag_AllowUnboundGeneric) != 0) && (hashSeed == 0);
  3161. BfAstNode* genericArgTypeRef = NULL;
  3162. if (genericIdx < genericTypeRef->mGenericArguments.mSize)
  3163. genericArgTypeRef = genericTypeRef->mGenericArguments[genericIdx];
  3164. if (allowUnboundGeneric)
  3165. {
  3166. if (BfNodeIsExact<BfWildcardTypeReference>(genericArgTypeRef))
  3167. genericArgTypeRef = NULL;
  3168. }
  3169. int argHashVal = 0;
  3170. if (genericArgTypeRef != NULL)
  3171. {
  3172. argHashVal = Hash(genericArgTypeRef, ctx, BfHashFlag_AllowGenericParamConstValue, hashSeed + 1);
  3173. if ((allowUnboundGeneric) && ((ctx->mResolveFlags & BfResolveTypeRefFlag_ForceUnboundGeneric) != 0))
  3174. genericArgTypeRef = NULL;
  3175. }
  3176. if (genericArgTypeRef == NULL)
  3177. {
  3178. if (allowUnboundGeneric)
  3179. {
  3180. ctx->mIsUnboundGeneric = true;
  3181. argHashVal = (((int)BfGenericParamKind_Type + 0xB00) << 8) ^ (genericIdx + 1);
  3182. argHashVal = HASH_MIX(argHashVal, hashSeed + 1);
  3183. }
  3184. else
  3185. {
  3186. ctx->mModule->Fail("Generic argument expected", genericTypeRef->mOpenChevron);
  3187. ctx->mFailed = true;
  3188. return;
  3189. }
  3190. }
  3191. hashVal = HASH_MIX(hashVal, argHashVal);
  3192. }
  3193. }
  3194. }
  3195. static int HashNode(BfAstNode* node)
  3196. {
  3197. if (node == NULL)
  3198. return (int)Hash64(NULL, 0);
  3199. const char* nameStr = node->GetSourceData()->mSrc + node->GetSrcStart();
  3200. return (int)Hash64(nameStr, node->GetSrcLength());
  3201. }
  3202. BfResolveTypeRefFlags BfResolvedTypeSet::GetResolveFlags(BfAstNode* typeRef, LookupContext* ctx, BfHashFlags flags)
  3203. {
  3204. bool isHeadType = typeRef == ctx->mRootTypeRef;
  3205. BfResolveTypeRefFlags resolveFlags = ctx->mResolveFlags;
  3206. if ((flags & BfHashFlag_AllowGenericParamConstValue) != 0)
  3207. resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_AllowGenericParamConstValue);
  3208. if (!isHeadType)
  3209. resolveFlags = (BfResolveTypeRefFlags)(resolveFlags & ~BfResolveTypeRefFlag_Attribute);
  3210. return resolveFlags;
  3211. }
  3212. int BfResolvedTypeSet::DirectHash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags, int hashSeed)
  3213. {
  3214. auto resolvedType = ctx->mModule->ResolveTypeRef(typeRef, BfPopulateType_Identity, GetResolveFlags(typeRef, ctx, flags));
  3215. if (resolvedType == NULL)
  3216. {
  3217. ctx->mFailed = true;
  3218. return 0;
  3219. }
  3220. if (((flags & BfHashFlag_DisallowPointer) != 0) && (resolvedType->IsPointer()))
  3221. {
  3222. ShowThisPointerWarning(ctx, typeRef);
  3223. resolvedType = resolvedType->GetUnderlyingType();
  3224. }
  3225. return Hash(resolvedType, ctx, BfHashFlag_None, hashSeed);
  3226. }
  3227. void BfResolvedTypeSet::ShowThisPointerWarning(LookupContext* ctx, BfTypeReference* typeRef)
  3228. {
  3229. ctx->mModule->Warn(0, "Pointer types cannot be used as 'this'. If 'this' address is required, use 'mut' or [CRepr]", typeRef);
  3230. }
  3231. BfTypeDef* BfResolvedTypeSet::FindRootCommonOuterType(BfTypeDef* outerType, LookupContext* ctx, BfTypeInstance*& outOuterTypeInstance)
  3232. {
  3233. if (ctx->mModule->mCurTypeInstance == NULL)
  3234. return NULL;
  3235. BfTypeDef* commonOuterType = NULL;
  3236. auto checkOuterTypeInst = ctx->mModule->mCurTypeInstance;
  3237. while (checkOuterTypeInst != NULL)
  3238. {
  3239. commonOuterType = ctx->mModule->FindCommonOuterType(checkOuterTypeInst->mTypeDef, outerType);
  3240. if (commonOuterType != NULL)
  3241. {
  3242. outOuterTypeInstance = checkOuterTypeInst;
  3243. break;
  3244. }
  3245. checkOuterTypeInst = checkOuterTypeInst->mBaseType;
  3246. }
  3247. if ((commonOuterType == NULL) && (outerType != NULL))
  3248. {
  3249. auto staticSearch = ctx->mModule->GetStaticSearch();
  3250. if (staticSearch != NULL)
  3251. {
  3252. for (auto staticTypeInst : staticSearch->mStaticTypes)
  3253. {
  3254. auto foundOuterType = ctx->mModule->FindCommonOuterType(staticTypeInst->mTypeDef, outerType);
  3255. if ((foundOuterType != NULL) &&
  3256. ((commonOuterType == NULL) || (foundOuterType->mNestDepth > commonOuterType->mNestDepth)))
  3257. {
  3258. commonOuterType = foundOuterType;
  3259. outOuterTypeInstance = staticTypeInst;
  3260. }
  3261. }
  3262. }
  3263. }
  3264. if (outOuterTypeInstance != NULL)
  3265. ctx->mRootOuterTypeInstance = outOuterTypeInstance;
  3266. return commonOuterType;
  3267. }
  3268. int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags, int& hashSeed)
  3269. {
  3270. if ((typeRef == ctx->mRootTypeRef) && (ctx->mRootTypeDef != NULL) &&
  3271. ((typeRef->IsNamedTypeReference()) || (BfNodeIsA<BfDirectTypeDefReference>(typeRef))))
  3272. {
  3273. BfTypeDef* typeDef = ctx->mRootTypeDef;
  3274. int hashVal = typeDef->mHash;
  3275. if (typeDef->mGenericParamDefs.size() != 0)
  3276. {
  3277. BfTypeDef* commonOuterType = NULL;
  3278. auto checkTypeInstance = ctx->mModule->mCurTypeInstance;
  3279. if (checkTypeInstance != NULL)
  3280. {
  3281. if (checkTypeInstance->IsBoxed())
  3282. checkTypeInstance = checkTypeInstance->GetUnderlyingType()->ToTypeInstance();
  3283. auto outerType = ctx->mModule->mSystem->GetOuterTypeNonPartial(typeDef);
  3284. if (typeRef == ctx->mRootTypeRef)
  3285. {
  3286. commonOuterType = FindRootCommonOuterType(outerType, ctx, checkTypeInstance);
  3287. if ((checkTypeInstance != NULL) && (checkTypeInstance->IsBoxed()))
  3288. checkTypeInstance = checkTypeInstance->GetUnderlyingType()->ToTypeInstance();
  3289. }
  3290. else
  3291. commonOuterType = ctx->mModule->FindCommonOuterType(ctx->mModule->mCurTypeInstance->mTypeDef, outerType);
  3292. if ((commonOuterType == NULL) && (outerType != NULL))
  3293. {
  3294. auto staticSearch = ctx->mModule->GetStaticSearch();
  3295. if (staticSearch != NULL)
  3296. {
  3297. for (auto staticTypeInst : staticSearch->mStaticTypes)
  3298. {
  3299. auto foundOuterType = ctx->mModule->FindCommonOuterType(staticTypeInst->mTypeDef, outerType);
  3300. if ((foundOuterType != NULL) &&
  3301. ((commonOuterType == NULL) || (foundOuterType->mNestDepth > commonOuterType->mNestDepth)))
  3302. {
  3303. commonOuterType = foundOuterType;
  3304. checkTypeInstance = staticTypeInst;
  3305. }
  3306. }
  3307. }
  3308. }
  3309. }
  3310. if ((commonOuterType == NULL) || (commonOuterType->mGenericParamDefs.size() == 0))
  3311. {
  3312. ctx->mModule->Fail("Generic arguments expected", typeRef);
  3313. ctx->mFailed = true;
  3314. return 0;
  3315. }
  3316. BF_ASSERT(checkTypeInstance->IsGenericTypeInstance());
  3317. auto curGenericTypeInst = (BfTypeInstance*)checkTypeInstance;
  3318. int numParentGenericParams = (int)commonOuterType->mGenericParamDefs.size();
  3319. for (int i = 0; i < numParentGenericParams; i++)
  3320. {
  3321. hashVal = HASH_MIX(hashVal, Hash(curGenericTypeInst->mGenericTypeInfo->mTypeGenericArguments[i], ctx, BfHashFlag_None, hashSeed + 1));
  3322. }
  3323. }
  3324. return hashVal;
  3325. }
  3326. if (typeRef->IsNamedTypeReference())
  3327. {
  3328. int hashVal = DirectHash(typeRef, ctx, flags, hashSeed);
  3329. hashSeed = 0;
  3330. return hashVal;
  3331. }
  3332. if (auto genericInstTypeRef = BfNodeDynCastExact<BfGenericInstanceTypeRef>(typeRef))
  3333. {
  3334. //BfType* type = NULL;
  3335. BfTypeDef* elementTypeDef = ctx->mModule->ResolveGenericInstanceDef(genericInstTypeRef, NULL, GetResolveFlags(genericInstTypeRef, ctx, flags));
  3336. if (elementTypeDef == NULL)
  3337. {
  3338. ctx->mFailed = true;
  3339. return 0;
  3340. }
  3341. int typeAliasHash = 0;
  3342. bool isInnerTypeAlias = false;
  3343. // Don't translate aliases for the root type, just element types
  3344. if (ctx->mRootTypeRef == typeRef)
  3345. {
  3346. BF_ASSERT((ctx->mRootTypeDef == NULL) || (ctx->mRootTypeDef == elementTypeDef));
  3347. ctx->mRootTypeDef = elementTypeDef;
  3348. }
  3349. else if (elementTypeDef->mTypeCode == BfTypeCode_TypeAlias)
  3350. {
  3351. isInnerTypeAlias = true;
  3352. }
  3353. BfTypeVector typeAliasGenericArgs;
  3354. bool fullyQualified = false;
  3355. int hashVal = elementTypeDef->mHash;
  3356. BfTypeInstance* outerType = NULL;
  3357. int checkIdx = 0;
  3358. auto checkTypeRef = genericInstTypeRef->mElementType;
  3359. while (checkTypeRef != NULL)
  3360. {
  3361. checkIdx++;
  3362. if (checkIdx >= 2)
  3363. {
  3364. fullyQualified = true;
  3365. if ((elementTypeDef->mOuterType != NULL) && (!elementTypeDef->mOuterType->mGenericParamDefs.IsEmpty()))
  3366. {
  3367. auto resolvedType = ctx->mModule->ResolveTypeRef(checkTypeRef, BfPopulateType_Identity,
  3368. (BfResolveTypeRefFlags)(GetResolveFlags(checkTypeRef, ctx, flags) | BfResolveTypeRefFlag_IgnoreLookupError));
  3369. if (resolvedType == NULL)
  3370. {
  3371. ctx->mFailed = true;
  3372. return hashVal;
  3373. }
  3374. ctx->SetCachedResolvedType(checkTypeRef, resolvedType);
  3375. outerType = resolvedType->ToTypeInstance();
  3376. }
  3377. break;
  3378. }
  3379. if (auto elementedTypeRef = BfNodeDynCast<BfElementedTypeRef>(checkTypeRef))
  3380. {
  3381. checkTypeRef = elementedTypeRef->mElementType;
  3382. continue;
  3383. }
  3384. if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(checkTypeRef))
  3385. {
  3386. checkTypeRef = qualifiedTypeRef->mLeft;
  3387. continue;
  3388. }
  3389. break;
  3390. }
  3391. if (fullyQualified)
  3392. {
  3393. if (outerType != NULL)
  3394. {
  3395. for (auto genericArg : outerType->mGenericTypeInfo->mTypeGenericArguments)
  3396. {
  3397. if (isInnerTypeAlias)
  3398. typeAliasGenericArgs.Add(genericArg);
  3399. else
  3400. hashVal = HASH_MIX(hashVal, Hash(genericArg, ctx, Beefy::BfResolvedTypeSet::BfHashFlag_None, hashSeed + 1));
  3401. }
  3402. }
  3403. }
  3404. else
  3405. {
  3406. // Do we need to add generic arguments from an in-context outer class?
  3407. if ((elementTypeDef->mOuterType != NULL) && (ctx->mModule->mCurTypeInstance != NULL))
  3408. {
  3409. BfTypeInstance* checkTypeInstance = ctx->mModule->mCurTypeInstance;
  3410. BfTypeDef* commonOuterType;
  3411. if (typeRef == ctx->mRootTypeRef)
  3412. commonOuterType = FindRootCommonOuterType(elementTypeDef->mOuterType, ctx, checkTypeInstance);
  3413. else
  3414. commonOuterType = ctx->mModule->FindCommonOuterType(ctx->mModule->mCurTypeInstance->mTypeDef, elementTypeDef->mOuterType);
  3415. if ((commonOuterType != NULL) && (checkTypeInstance->IsGenericTypeInstance()))
  3416. {
  3417. auto parentTypeInstance = checkTypeInstance;
  3418. int numParentGenericParams = (int)commonOuterType->mGenericParamDefs.size();
  3419. for (int i = 0; i < numParentGenericParams; i++)
  3420. {
  3421. if (isInnerTypeAlias)
  3422. typeAliasGenericArgs.Add(parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i]);
  3423. else
  3424. hashVal = HASH_MIX(hashVal, Hash(parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i], ctx, Beefy::BfResolvedTypeSet::BfHashFlag_None, hashSeed + 1));
  3425. }
  3426. }
  3427. }
  3428. }
  3429. if (isInnerTypeAlias)
  3430. {
  3431. for (auto genericArgTypeRef : genericInstTypeRef->mGenericArguments)
  3432. {
  3433. auto argType = ctx->mModule->ResolveTypeRef(genericArgTypeRef, NULL, BfPopulateType_Identity, GetResolveFlags(genericArgTypeRef, ctx, flags));
  3434. if (argType != NULL)
  3435. typeAliasGenericArgs.Add(argType);
  3436. else
  3437. ctx->mFailed = true;
  3438. }
  3439. if (!ctx->mFailed)
  3440. {
  3441. auto resolvedType = ctx->mModule->ResolveTypeDef(elementTypeDef, typeAliasGenericArgs);
  3442. if (resolvedType != NULL)
  3443. {
  3444. auto underlyingType = resolvedType;
  3445. while ((underlyingType != NULL) && (underlyingType->IsTypeAlias()))
  3446. {
  3447. ctx->mModule->PopulateType(underlyingType);
  3448. underlyingType = underlyingType->GetUnderlyingType();
  3449. }
  3450. if (underlyingType == NULL)
  3451. {
  3452. ctx->mFailed = true;
  3453. return 0;
  3454. }
  3455. int hashVal = Hash(underlyingType, ctx, flags, hashSeed);
  3456. hashSeed = 0;
  3457. return hashVal;
  3458. }
  3459. }
  3460. }
  3461. else
  3462. HashGenericArguments(genericInstTypeRef, ctx, hashVal, hashSeed);
  3463. return hashVal;
  3464. }
  3465. else if (auto tupleTypeRef = BfNodeDynCastExact<BfTupleTypeRef>(typeRef))
  3466. {
  3467. int hashVal = HASH_VAL_TUPLE;
  3468. for (int fieldIdx = 0; fieldIdx < (int)tupleTypeRef->mFieldTypes.size(); fieldIdx++)
  3469. {
  3470. BfTypeReference* fieldType = tupleTypeRef->mFieldTypes[fieldIdx];
  3471. hashVal = HASH_MIX(hashVal, Hash(fieldType, ctx, BfHashFlag_None, hashSeed + 1));
  3472. int nameHash = 0;
  3473. BfIdentifierNode* fieldName = NULL;
  3474. if (fieldIdx < (int)tupleTypeRef->mFieldNames.size())
  3475. fieldName = tupleTypeRef->mFieldNames[fieldIdx];
  3476. if (fieldName != NULL)
  3477. {
  3478. const char* nameStr = fieldName->GetSourceData()->mSrc + fieldName->GetSrcStart();
  3479. nameHash = (int)Hash64(nameStr, fieldName->GetSrcLength());
  3480. }
  3481. else
  3482. {
  3483. char nameStr[64];
  3484. sprintf(nameStr, "%d", fieldIdx);
  3485. nameHash = (int)Hash64(nameStr, strlen(nameStr));
  3486. }
  3487. hashVal = HASH_MIX(hashVal, nameHash);
  3488. }
  3489. return hashVal;
  3490. }
  3491. else if (auto arrayType = BfNodeDynCastExact<BfArrayTypeRef>(typeRef))
  3492. {
  3493. if ((arrayType->mDimensions == 1) && (arrayType->mParams.size() != 0))
  3494. {
  3495. int rawElemHash = Hash(arrayType->mElementType, ctx, BfHashFlag_None, hashSeed);
  3496. int elemHash = rawElemHash ^ HASH_SIZED_ARRAY;
  3497. int hashVal = (elemHash << 5) - elemHash;
  3498. // Sized array
  3499. if (arrayType->mParams.size() != 1)
  3500. {
  3501. ctx->mFailed = true;
  3502. ctx->mModule->Fail("Only one size parameter expected", arrayType->mParams[1]);
  3503. return 0;
  3504. }
  3505. intptr elementCount = -1;
  3506. BfExpression* sizeExpr = BfNodeDynCast<BfExpression>(arrayType->mParams[0]);
  3507. BF_ASSERT(sizeExpr != NULL);
  3508. if (sizeExpr != NULL)
  3509. {
  3510. BfMethodState methodState;
  3511. methodState.mTempKind = BfMethodState::TempKind_Static;
  3512. SetAndRestoreValue<BfMethodState*> prevMethodState;
  3513. if (ctx->mModule->mCurMethodState == NULL)
  3514. prevMethodState.Init(ctx->mModule->mCurMethodState, &methodState);
  3515. BfConstResolver constResolver(ctx->mModule);
  3516. BfType* intType = ctx->mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  3517. constResolver.mBfEvalExprFlags = (BfEvalExprFlags)(constResolver.mBfEvalExprFlags | BfEvalExprFlags_AllowGenericConstValue);
  3518. constResolver.mExpectingType = intType;
  3519. BfTypedValue typedVal = constResolver.Resolve(sizeExpr, NULL, BfConstResolveFlag_ArrayInitSize);
  3520. if (typedVal.mKind == BfTypedValueKind_GenericConstValue)
  3521. {
  3522. ctx->mResolvedValueMap[sizeExpr] = typedVal;
  3523. int elemHash = Hash(typedVal.mType, ctx, BfHashFlag_None, hashSeed);
  3524. hashVal = ((hashVal ^ elemHash) << 5) - hashVal;
  3525. return hashVal;
  3526. }
  3527. if (!typedVal)
  3528. ctx->mFailed = true;
  3529. if (typedVal)
  3530. {
  3531. SetAndRestoreValue<bool> prevIgnoreWrites(ctx->mModule->mBfIRBuilder->mIgnoreWrites, true);
  3532. typedVal = ctx->mModule->Cast(sizeExpr, typedVal, intType);
  3533. }
  3534. ctx->mResolvedValueMap[sizeExpr] = typedVal;
  3535. if (typedVal)
  3536. {
  3537. auto constant = ctx->mModule->mBfIRBuilder->GetConstant(typedVal.mValue);
  3538. if (constant == NULL)
  3539. {
  3540. ctx->mFailed = true;
  3541. ctx->mModule->Fail("Array size not a constant value", arrayType->mParams[0]);
  3542. }
  3543. else if (constant->mConstType == BfConstType_Undef)
  3544. {
  3545. elementCount = -1; // Marker for undef
  3546. if ((arrayType->IsInferredSize()) && ((ctx->mResolveFlags & BfResolveTypeRefFlag_AllowInferredSizedArray) == 0))
  3547. {
  3548. ctx->mModule->Fail("Invalid use of inferred-sized array", sizeExpr);
  3549. }
  3550. }
  3551. else if (!BfIRBuilder::IsInt(constant->mTypeCode))
  3552. {
  3553. ctx->mFailed = true;
  3554. ctx->mModule->Fail("Array size not a constant value", arrayType->mParams[0]);
  3555. }
  3556. else
  3557. {
  3558. elementCount = (intptr)constant->mInt64;
  3559. if (elementCount < 0)
  3560. {
  3561. ctx->mFailed = true;
  3562. ctx->mModule->Fail("Arrays cannot have negative sizes", arrayType->mParams[0]);
  3563. return 0;
  3564. }
  3565. }
  3566. }
  3567. }
  3568. hashVal = ((hashVal ^ (int)elementCount) << 5) - hashVal;
  3569. return hashVal;
  3570. }
  3571. else
  3572. {
  3573. if (arrayType->mDimensions != (int)arrayType->mParams.size() + 1)
  3574. {
  3575. for (auto arg : arrayType->mParams)
  3576. {
  3577. if (auto tokenNode = BfNodeDynCastExact<BfTokenNode>(arg))
  3578. {
  3579. if (tokenNode->GetToken() == BfToken_Comma)
  3580. continue;
  3581. }
  3582. ctx->mFailed = true;
  3583. ctx->mModule->Fail("Multidimensional arrays cannot have explicit sizes. Consider using a strided array (ie: int[2][2]) instead.", arg);
  3584. return 0;
  3585. }
  3586. }
  3587. int elemHash = Hash(arrayType->mElementType, ctx, BfHashFlag_None, hashSeed) ^ (arrayType->mDimensions << 8);
  3588. return (elemHash << 5) - elemHash;
  3589. }
  3590. }
  3591. else if (auto pointerType = BfNodeDynCastExact<BfPointerTypeRef>(typeRef))
  3592. {
  3593. int elemHash = Hash(pointerType->mElementType, ctx, BfHashFlag_None, hashSeed) ^ HASH_VAL_PTR;
  3594. return (elemHash << 5) - elemHash;
  3595. }
  3596. else if (auto nullableType = BfNodeDynCastExact<BfNullableTypeRef>(typeRef))
  3597. {
  3598. if (ctx->mRootTypeRef == typeRef)
  3599. ctx->mRootTypeDef = ctx->mModule->mCompiler->mNullableTypeDef;
  3600. int hashVal = ctx->mModule->mCompiler->mNullableTypeDef->mHash;
  3601. hashVal = HASH_MIX(hashVal, Hash(nullableType->mElementType, ctx, BfHashFlag_None, hashSeed + 1));
  3602. return hashVal;
  3603. }
  3604. else if (auto refType = BfNodeDynCastExact<BfRefTypeRef>(typeRef))
  3605. {
  3606. if ((flags & BfHashFlag_AllowRef) != 0)
  3607. {
  3608. auto refKind = BfRefType::RefKind_Ref;
  3609. if (refType->mRefToken == NULL)
  3610. refKind = BfRefType::RefKind_Ref;
  3611. else if (refType->mRefToken->GetToken() == BfToken_In)
  3612. refKind = BfRefType::RefKind_In;
  3613. else if (refType->mRefToken->GetToken() == BfToken_Out)
  3614. refKind = BfRefType::RefKind_Out;
  3615. else if (refType->mRefToken->GetToken() == BfToken_Mut)
  3616. refKind = BfRefType::RefKind_Mut;
  3617. int elemHash = Hash(refType->mElementType, ctx, BfHashFlag_None, hashSeed) ^ (HASH_VAL_REF + (int)refKind);
  3618. return (elemHash << 5) - elemHash;
  3619. }
  3620. else
  3621. {
  3622. ctx->mModule->ResolveTypeRef(typeRef, BfPopulateType_Identity, GetResolveFlags(typeRef, ctx, flags)); // To throw an error...
  3623. ctx->mFailed = true;
  3624. return 0;
  3625. //return Hash(refType->mElementType, ctx);
  3626. }
  3627. }
  3628. else if (auto genericParamTypeRef = BfNodeDynCastExact<BfGenericParamTypeRef>(typeRef))
  3629. {
  3630. return (((int)genericParamTypeRef->mGenericParamKind) << 8) ^ (genericParamTypeRef->mGenericParamIdx + 1);
  3631. }
  3632. else if (auto qualifiedTypeRef = BfNodeDynCastExact<BfQualifiedTypeReference>(typeRef))
  3633. {
  3634. /*auto leftType = ctx->mModule->ResolveTypeRef(qualifiedTypeRef->mLeft, BfPopulateType_Identity);
  3635. if (leftType == NULL)
  3636. {
  3637. ctx->mFailed = true;
  3638. return 0;
  3639. }
  3640. if (qualifiedTypeRef->mRight == NULL)
  3641. {
  3642. ctx->mFailed = true;
  3643. return 0;
  3644. }
  3645. auto rightType = ctx->mModule->ResolveInnerType(leftType, qualifiedTypeRef->mRight);
  3646. if (rightType == NULL)
  3647. {
  3648. ctx->mFailed = true;
  3649. return 0;
  3650. }
  3651. return Hash(rightType, ctx);*/
  3652. auto resolvedType = ctx->mModule->ResolveTypeRef(typeRef, BfPopulateType_Identity, GetResolveFlags(typeRef, ctx, flags));
  3653. if (resolvedType == NULL)
  3654. {
  3655. ctx->mFailed = true;
  3656. return 0;
  3657. }
  3658. int hashVal = Hash(resolvedType, ctx, BfHashFlag_None, hashSeed);
  3659. hashSeed = 0;
  3660. return hashVal;
  3661. }
  3662. else if (auto varType = BfNodeDynCastExact<BfVarTypeReference>(typeRef))
  3663. {
  3664. // Don't allow 'var'
  3665. ctx->mModule->Fail("Invalid use of 'var'", typeRef);
  3666. ctx->mFailed = true;
  3667. return 0;
  3668. }
  3669. else if (auto letType = BfNodeDynCastExact<BfLetTypeReference>(typeRef))
  3670. {
  3671. // Don't allow 'let'
  3672. ctx->mModule->Fail("Invalid use of 'let'", typeRef);
  3673. ctx->mFailed = true;
  3674. return 0;
  3675. }
  3676. else if (auto retTypeTypeRef = BfNodeDynCastExact<BfModifiedTypeRef>(typeRef))
  3677. {
  3678. // Don't cause infinite loop, but if we have an inner 'rettype' then try to directly resolve that --
  3679. // Only use the HAS_RETTYPE for root-level rettype insertions
  3680. if (ctx->mRootTypeRef != retTypeTypeRef)
  3681. {
  3682. auto type = ctx->mModule->ResolveTypeRef(retTypeTypeRef, BfPopulateType_Identity, GetResolveFlags(retTypeTypeRef, ctx, flags));
  3683. if (type == NULL)
  3684. {
  3685. ctx->mFailed = true;
  3686. return 0;
  3687. }
  3688. if (type->IsRef())
  3689. type = type->GetUnderlyingType();
  3690. return DoHash(type, ctx, flags, hashSeed);
  3691. }
  3692. int elemHash = Hash(retTypeTypeRef->mElementType, ctx, BfHashFlag_None, hashSeed) ^ HASH_MODTYPE + retTypeTypeRef->mRetTypeToken->mToken;
  3693. return (elemHash << 5) - elemHash;
  3694. }
  3695. else if (auto resolvedTypeRef = BfNodeDynCastExact<BfResolvedTypeReference>(typeRef))
  3696. {
  3697. return Hash(resolvedTypeRef->mType, ctx, BfHashFlag_None, hashSeed);
  3698. }
  3699. else if (auto constTypeRef = BfNodeDynCastExact<BfConstTypeRef>(typeRef))
  3700. {
  3701. // 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
  3702. return Hash(constTypeRef->mElementType, ctx, flags, hashSeed);
  3703. }
  3704. else if (auto delegateTypeRef = BfNodeDynCastExact<BfDelegateTypeRef>(typeRef))
  3705. {
  3706. int hashVal = HASH_DELEGATE;
  3707. if (delegateTypeRef->mReturnType != NULL)
  3708. hashVal = HASH_MIX(hashVal, Hash(delegateTypeRef->mReturnType, ctx, BfHashFlag_AllowRef, hashSeed + 1));
  3709. else
  3710. ctx->mFailed = true;
  3711. bool isFirstParam = true;
  3712. for (int paramIdx = 0; paramIdx < delegateTypeRef->mParams.size(); paramIdx++)
  3713. {
  3714. auto param = delegateTypeRef->mParams[paramIdx];
  3715. // Parse attributes?
  3716. BfTypeReference* fieldType = param->mTypeRef;
  3717. auto hashFlags = (BfHashFlags)(BfHashFlag_AllowRef);
  3718. if (isFirstParam)
  3719. {
  3720. if ((param->mNameNode != NULL) && (param->mNameNode->Equals("this")))
  3721. {
  3722. hashFlags = (BfHashFlags)(hashFlags | BfHashFlag_DisallowPointer);
  3723. if (auto refNode = BfNodeDynCast<BfRefTypeRef>(fieldType))
  3724. fieldType = refNode->mElementType;
  3725. if (auto pointerType = BfNodeDynCast<BfPointerTypeRef>(fieldType))
  3726. {
  3727. ShowThisPointerWarning(ctx, pointerType);
  3728. fieldType = pointerType->mElementType;
  3729. }
  3730. }
  3731. }
  3732. if (paramIdx == delegateTypeRef->mParams.size() - 1)
  3733. {
  3734. if (auto dotTypeRef = BfNodeDynCastExact<BfDotTypeReference>(fieldType))
  3735. {
  3736. if (dotTypeRef->mDotToken->mToken == BfToken_DotDotDot)
  3737. {
  3738. hashVal = HASH_MIX(hashVal, HASH_DOTDOTDOT);
  3739. continue;
  3740. }
  3741. }
  3742. }
  3743. if (fieldType != NULL)
  3744. hashVal = HASH_MIX(hashVal, Hash(fieldType, ctx, hashFlags, hashSeed + 1));
  3745. hashVal = HASH_MIX(hashVal, HashNode(param->mNameNode));
  3746. isFirstParam = true;
  3747. }
  3748. return hashVal;
  3749. }
  3750. else if (auto exprModTypeRef = BfNodeDynCastExact<BfExprModTypeRef>(typeRef))
  3751. {
  3752. auto cachedResolvedType = ctx->GetCachedResolvedType(typeRef);
  3753. if (cachedResolvedType == NULL)
  3754. {
  3755. if (exprModTypeRef->mTarget != NULL)
  3756. {
  3757. BfTypedValue result;
  3758. //
  3759. {
  3760. BfMethodState methodState;
  3761. SetAndRestoreValue<BfMethodState*> prevMethodState(ctx->mModule->mCurMethodState, &methodState, false);
  3762. if (ctx->mModule->mCurMethodState == NULL)
  3763. prevMethodState.Set();
  3764. methodState.mTempKind = BfMethodState::TempKind_NonStatic;
  3765. SetAndRestoreValue<bool> ignoreWrites(ctx->mModule->mBfIRBuilder->mIgnoreWrites, true);
  3766. SetAndRestoreValue<bool> allowUninitReads(ctx->mModule->mCurMethodState->mAllowUinitReads, true);
  3767. BfEvalExprFlags exprFlags = BfEvalExprFlags_None;
  3768. if ((ctx->mResolveFlags & BfResolveTypeRefFlag_DisallowComptime) != 0)
  3769. {
  3770. exprFlags = (BfEvalExprFlags)(exprFlags | BfEvalExprFlags_DisallowComptime);
  3771. }
  3772. if (exprModTypeRef->mToken->mToken == BfToken_Comptype)
  3773. {
  3774. auto typeType = ctx->mModule->ResolveTypeDef(ctx->mModule->mCompiler->mTypeTypeDef);
  3775. exprFlags = (BfEvalExprFlags)(exprFlags | BfEvalExprFlags_Comptime | BfEvalExprFlags_NoCast);
  3776. result = ctx->mModule->CreateValueFromExpression(exprModTypeRef->mTarget, typeType, exprFlags);
  3777. if ((result.mType != NULL) && (!result.mType->IsInteger()) && (result.mType != typeType) &&
  3778. (!result.mType->IsInstanceOf(ctx->mModule->mCompiler->mReflectTypeIdTypeDef)))
  3779. result = ctx->mModule->Cast(exprModTypeRef->mTarget, result, typeType);
  3780. }
  3781. else
  3782. {
  3783. result = ctx->mModule->CreateValueFromExpression(exprModTypeRef->mTarget, NULL, BfEvalExprFlags_DeclType);
  3784. }
  3785. }
  3786. if ((result) && (exprModTypeRef->mToken->mToken == BfToken_Comptype))
  3787. {
  3788. auto constant = ctx->mModule->mBfIRBuilder->GetConstant(result.mValue);
  3789. if (constant != NULL)
  3790. {
  3791. if ((constant->mConstType == BfConstType_TypeOf) || (constant->mConstType == BfConstType_TypeOf_WithData))
  3792. {
  3793. auto typeOf = (BfTypeOf_Const*)constant;
  3794. cachedResolvedType = typeOf->mType;
  3795. }
  3796. else if (constant->mConstType == BfConstType_Undef)
  3797. {
  3798. ctx->mHadVar = true;
  3799. cachedResolvedType = ctx->mModule->GetPrimitiveType(BfTypeCode_Var);
  3800. auto typeState = ctx->mModule->mContext->mCurTypeState;
  3801. if ((typeState != NULL) && (typeState->mType != NULL) && (typeState->mType->IsTypeInstance()))
  3802. {
  3803. auto typeInst = typeState->mType->ToTypeInstance();
  3804. if (typeInst->mDefineState == BfTypeDefineState_ResolvingBaseType)
  3805. {
  3806. // Make sure we regenerate this type
  3807. ctx->mModule->mContext->mFailTypes.TryAdd(typeState->mType->ToTypeInstance(), BfFailKind_Deep);
  3808. }
  3809. }
  3810. }
  3811. else if (BfIRConstHolder::IsInt(constant->mTypeCode))
  3812. {
  3813. int typeId = constant->mInt32;
  3814. BfType* type = NULL;
  3815. if ((typeId >= 0) && (typeId < ctx->mModule->mContext->mTypes.mSize))
  3816. type = ctx->mModule->mContext->mTypes[typeId];
  3817. if (type != NULL)
  3818. {
  3819. cachedResolvedType = type;
  3820. }
  3821. else
  3822. {
  3823. ctx->mModule->Fail(StrFormat("Invalid type id '%d'", typeId), exprModTypeRef->mTarget);
  3824. ctx->mHadVar = true;
  3825. cachedResolvedType = ctx->mModule->GetPrimitiveType(BfTypeCode_Var);
  3826. }
  3827. }
  3828. }
  3829. if (cachedResolvedType == NULL)
  3830. ctx->mModule->Fail("Constant System.Type value required", exprModTypeRef->mTarget);
  3831. }
  3832. else
  3833. cachedResolvedType = result.mType;
  3834. if ((cachedResolvedType != NULL) && (cachedResolvedType->IsRef()))
  3835. cachedResolvedType = cachedResolvedType->GetUnderlyingType();
  3836. if (cachedResolvedType != NULL)
  3837. ctx->SetCachedResolvedType(typeRef, cachedResolvedType);
  3838. }
  3839. }
  3840. if (cachedResolvedType == NULL)
  3841. {
  3842. ctx->mFailed = true;
  3843. return 0;
  3844. }
  3845. int hashVal = Hash(cachedResolvedType, ctx, flags, hashSeed);
  3846. hashSeed = 0;
  3847. return hashVal;
  3848. }
  3849. else if (auto constExprTypeRef = BfNodeDynCastExact<BfConstExprTypeRef>(typeRef))
  3850. {
  3851. if ((flags & BfHashFlag_AllowGenericParamConstValue) == 0)
  3852. {
  3853. ctx->mModule->Fail("Invalid use of const expression", constExprTypeRef->mConstToken);
  3854. ctx->mFailed = true;
  3855. return 0;
  3856. }
  3857. BfVariant result;
  3858. BfType* resultType = NULL;
  3859. if (constExprTypeRef->mConstExpr != NULL)
  3860. {
  3861. result = EvaluateToVariant(ctx, constExprTypeRef->mConstExpr, resultType);
  3862. if ((resultType != NULL) && (resultType->IsGenericParam()))
  3863. {
  3864. int hashVal = Hash(resultType, ctx, BfHashFlag_None, hashSeed);
  3865. hashSeed = 0;
  3866. return hashVal;
  3867. }
  3868. }
  3869. if (resultType == NULL)
  3870. {
  3871. ctx->mFailed = true;
  3872. return 0;
  3873. }
  3874. int32 dataHash = BeefHash<BfVariant>()(result);
  3875. auto hashVal = ((int)result.mTypeCode << 17) ^ (dataHash << 3) ^ HASH_CONSTTYPE;
  3876. hashVal = ((hashVal ^ (Hash(resultType, ctx, BfHashFlag_AllowRef, hashSeed))) << 5) - hashVal;
  3877. return hashVal;
  3878. }
  3879. else if (auto dotTypeRef = BfNodeDynCastExact<BfDotTypeReference>(typeRef))
  3880. {
  3881. ctx->mModule->ResolveTypeRef(dotTypeRef, BfPopulateType_Identity, GetResolveFlags(dotTypeRef, ctx, flags));
  3882. ctx->mFailed = true;
  3883. return 0;
  3884. }
  3885. else if (auto wildcardTypeRef = BfNodeDynCastExact<BfWildcardTypeReference>(typeRef))
  3886. {
  3887. ctx->mFailed = true;
  3888. return 0;
  3889. }
  3890. else if (auto tagTypeRef = BfNodeDynCastExact<BfTagTypeRef>(typeRef))
  3891. {
  3892. int nameHash = 0;
  3893. if (tagTypeRef->mNameNode != NULL)
  3894. {
  3895. auto fieldName = tagTypeRef->mNameNode;
  3896. const char* nameStr = fieldName->GetSourceData()->mSrc + fieldName->GetSrcStart();
  3897. nameHash = (int)Hash64(nameStr, fieldName->GetSrcLength());
  3898. }
  3899. return nameHash ^ HASH_TAG;
  3900. }
  3901. // else if (auto inlineTypeRef = BfNodeDynCastExact<BfInlineTypeReference>(typeRef))
  3902. // {
  3903. // String name;
  3904. // inlineTypeRef->mTypeDeclaration->GetAnonymousName(name);
  3905. // int nameHash = (int)Hash64(name.c_str(), (int)name.length());
  3906. // return nameHash ^ HASH_TAG;
  3907. // }
  3908. else
  3909. {
  3910. BF_FATAL("Not handled");
  3911. }
  3912. return 0;
  3913. }
  3914. int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags, int hashSeed)
  3915. {
  3916. int hashVal = DoHash(typeRef, ctx, flags, hashSeed);
  3917. if (hashSeed == 0)
  3918. return hashVal;
  3919. return HASH_MIX(hashVal, hashSeed);
  3920. }
  3921. int BfResolvedTypeSet::Hash(BfAstNode* typeRefNode, LookupContext* ctx, BfHashFlags flags, int hashSeed)
  3922. {
  3923. if (auto typeRef = BfNodeDynCast<BfTypeReference>(typeRefNode))
  3924. return Hash(typeRef, ctx, flags, hashSeed);
  3925. auto result = ctx->mModule->ResolveTypeRef(typeRefNode, NULL, BfPopulateType_Identity, (BfResolveTypeRefFlags)(ctx->mResolveFlags | BfResolveTypeRefFlag_AllowImplicitConstExpr));
  3926. if (result == NULL)
  3927. {
  3928. ctx->mFailed = true;
  3929. return 0;
  3930. }
  3931. ctx->mResolvedTypeMap[typeRefNode] = result;
  3932. return Hash(result, ctx, false, hashSeed);
  3933. }
  3934. bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx)
  3935. {
  3936. if (lhs->IsBoxed())
  3937. {
  3938. if (!rhs->IsBoxed())
  3939. return false;
  3940. BfBoxedType* lhsBoxedType = (BfBoxedType*)lhs;
  3941. BfBoxedType* rhsBoxedType = (BfBoxedType*)rhs;
  3942. if (lhsBoxedType->mBoxedFlags != rhsBoxedType->mBoxedFlags)
  3943. return false;
  3944. return lhsBoxedType->mElementType == rhsBoxedType->mElementType;
  3945. }
  3946. else if (lhs->IsArray())
  3947. {
  3948. if (!rhs->IsArray())
  3949. return false;
  3950. BfArrayType* lhsArrayType = (BfArrayType*) lhs;
  3951. BfArrayType* rhsArrayType = (BfArrayType*) rhs;
  3952. if (lhsArrayType->mDimensions != rhsArrayType->mDimensions)
  3953. return false;
  3954. return lhsArrayType->mGenericTypeInfo->mTypeGenericArguments[0] == rhsArrayType->mGenericTypeInfo->mTypeGenericArguments[0];
  3955. }
  3956. else if (lhs->IsTypeInstance())
  3957. {
  3958. if ((!rhs->IsTypeInstance()) || (rhs->IsBoxed()))
  3959. return false;
  3960. BfTypeInstance* lhsInst = (BfTypeInstance*)lhs;
  3961. BfTypeInstance* rhsInst = (BfTypeInstance*)rhs;
  3962. if (lhs->IsClosure())
  3963. {
  3964. if (!rhs->IsClosure())
  3965. return false;
  3966. auto lhsClosure = (BfClosureType*)lhs;
  3967. auto rhsClosure = (BfClosureType*)rhs;
  3968. if ((lhsClosure->mIsUnique) || (rhsClosure->mIsUnique))
  3969. return false;
  3970. if (lhsClosure->mBaseType != rhsClosure->mBaseType)
  3971. return false;
  3972. return lhsClosure->mClosureHash == rhsClosure->mClosureHash;
  3973. }
  3974. if (lhs->IsDelegateFromTypeRef() || lhs->IsFunctionFromTypeRef())
  3975. {
  3976. if (!rhs->IsDelegateFromTypeRef() && !rhs->IsFunctionFromTypeRef())
  3977. return false;
  3978. if (lhs->IsDelegate() != rhs->IsDelegate())
  3979. return false;
  3980. BfDelegateInfo* lhsDelegateInfo = lhs->GetDelegateInfo();
  3981. BfDelegateInfo* rhsDelegateInfo = rhs->GetDelegateInfo();
  3982. if (lhsInst->mTypeDef->mIsDelegate != rhsInst->mTypeDef->mIsDelegate)
  3983. return false;
  3984. if (lhsDelegateInfo->mCallingConvention != rhsDelegateInfo->mCallingConvention)
  3985. return false;
  3986. if (lhsDelegateInfo->mHasParams != rhsDelegateInfo->mHasParams)
  3987. return false;
  3988. if (lhsDelegateInfo->mHasVarArgs != rhsDelegateInfo->mHasVarArgs)
  3989. return false;
  3990. if (lhsDelegateInfo->mHasExplicitThis != rhsDelegateInfo->mHasExplicitThis)
  3991. return false;
  3992. auto lhsMethodDef = lhsInst->mTypeDef->mMethods[0];
  3993. auto rhsMethodDef = rhsInst->mTypeDef->mMethods[0];
  3994. if (lhsMethodDef->mCallingConvention != rhsMethodDef->mCallingConvention)
  3995. return false;
  3996. if (lhsMethodDef->mIsMutating != rhsMethodDef->mIsMutating)
  3997. return false;
  3998. if (lhsDelegateInfo->mReturnType != rhsDelegateInfo->mReturnType)
  3999. return false;
  4000. if (lhsDelegateInfo->mParams.size() != rhsDelegateInfo->mParams.size())
  4001. return false;
  4002. for (int paramIdx = 0; paramIdx < lhsDelegateInfo->mParams.size(); paramIdx++)
  4003. {
  4004. if (lhsDelegateInfo->mParams[paramIdx] != rhsDelegateInfo->mParams[paramIdx])
  4005. return false;
  4006. if (lhsMethodDef->mParams[paramIdx]->mName != rhsMethodDef->mParams[paramIdx]->mName)
  4007. return false;
  4008. }
  4009. return true;
  4010. }
  4011. if (lhs->IsTuple())
  4012. {
  4013. if (!rhs->IsTuple())
  4014. return false;
  4015. BfTypeInstance* lhsTupleType = (BfTypeInstance*)lhs;
  4016. BfTypeInstance* rhsTupleType = (BfTypeInstance*)rhs;
  4017. if (lhsTupleType->mFieldInstances.size() != rhsTupleType->mFieldInstances.size())
  4018. return false;
  4019. for (int fieldIdx = 0; fieldIdx < (int)lhsTupleType->mFieldInstances.size(); fieldIdx++)
  4020. {
  4021. auto lhsFieldInstance = &lhsTupleType->mFieldInstances[fieldIdx];
  4022. auto rhsFieldInstance = &rhsTupleType->mFieldInstances[fieldIdx];
  4023. if (lhsFieldInstance->mResolvedType != rhsFieldInstance->mResolvedType)
  4024. return false;
  4025. auto lhsFieldDef = lhsFieldInstance->GetFieldDef();
  4026. if (rhsTupleType->mTypeDef == NULL)
  4027. {
  4028. char c = lhsFieldDef->mName[0];
  4029. if ((c < '0') || (c > '9'))
  4030. return false;
  4031. }
  4032. else
  4033. {
  4034. auto rhsFieldDef = rhsFieldInstance->GetFieldDef();
  4035. if (lhsFieldDef->mName != rhsFieldDef->mName)
  4036. return false;
  4037. }
  4038. }
  4039. return true;
  4040. }
  4041. if (lhs->IsGenericTypeInstance())
  4042. {
  4043. if (!rhs->IsGenericTypeInstance())
  4044. return false;
  4045. BfTypeInstance* lhsGenericType = (BfTypeInstance*)lhs;
  4046. BfTypeInstance* rhsGenericType = (BfTypeInstance*)rhs;
  4047. if (lhsGenericType->mGenericTypeInfo->mTypeGenericArguments.size() != rhsGenericType->mGenericTypeInfo->mTypeGenericArguments.size())
  4048. return false;
  4049. if (lhsGenericType->mTypeDef->GetDefinition() != rhsGenericType->mTypeDef->GetDefinition())
  4050. return false;
  4051. for (int i = 0; i < (int)lhsGenericType->mGenericTypeInfo->mTypeGenericArguments.size(); i++)
  4052. {
  4053. if (lhsGenericType->mGenericTypeInfo->mTypeGenericArguments[i] != rhsGenericType->mGenericTypeInfo->mTypeGenericArguments[i])
  4054. return false;
  4055. }
  4056. }
  4057. return lhsInst->mTypeDef->GetDefinition() == rhsInst->mTypeDef->GetDefinition();
  4058. }
  4059. else if (lhs->IsPrimitiveType())
  4060. {
  4061. if (!rhs->IsPrimitiveType())
  4062. return false;
  4063. BfPrimitiveType* lhsPrimType = (BfPrimitiveType*)lhs;
  4064. BfPrimitiveType* rhsPrimType = (BfPrimitiveType*)rhs;
  4065. return lhsPrimType->mTypeDef == rhsPrimType->mTypeDef;
  4066. }
  4067. else if (lhs->IsPointer())
  4068. {
  4069. if (!rhs->IsPointer())
  4070. return false;
  4071. BfPointerType* lhsPtrType = (BfPointerType*)lhs;
  4072. BfPointerType* rhsPtrType = (BfPointerType*)rhs;
  4073. return lhsPtrType->mElementType == rhsPtrType->mElementType;
  4074. }
  4075. else if (lhs->IsGenericParam())
  4076. {
  4077. if (!rhs->IsGenericParam())
  4078. return false;
  4079. BfGenericParamType* lhsGenericParamType = (BfGenericParamType*)lhs;
  4080. BfGenericParamType* rhsGenericParamType = (BfGenericParamType*)rhs;
  4081. return (lhsGenericParamType->mGenericParamKind == rhsGenericParamType->mGenericParamKind) &&
  4082. (lhsGenericParamType->mGenericParamIdx == rhsGenericParamType->mGenericParamIdx);
  4083. }
  4084. else if (lhs->IsRef())
  4085. {
  4086. if (!rhs->IsRef())
  4087. return false;
  4088. BfRefType* lhsRefType = (BfRefType*)lhs;
  4089. BfRefType* rhsRefType = (BfRefType*)rhs;
  4090. return (lhsRefType->mElementType == rhsRefType->mElementType) && (lhsRefType->mRefKind == rhsRefType->mRefKind);
  4091. }
  4092. else if (lhs->IsModifiedTypeType())
  4093. {
  4094. if (!rhs->IsModifiedTypeType())
  4095. return false;
  4096. BfModifiedTypeType* lhsRetTypeType = (BfModifiedTypeType*)lhs;
  4097. BfModifiedTypeType* rhsRetTypeType = (BfModifiedTypeType*)rhs;
  4098. return (lhsRetTypeType->mModifiedKind == rhsRetTypeType->mModifiedKind) &&
  4099. (lhsRetTypeType->mElementType == rhsRetTypeType->mElementType);
  4100. }
  4101. else if (lhs->IsConcreteInterfaceType())
  4102. {
  4103. if (!rhs->IsConcreteInterfaceType())
  4104. return false;
  4105. BfConcreteInterfaceType* lhsConcreteInterfaceType = (BfConcreteInterfaceType*)lhs;
  4106. BfConcreteInterfaceType* rhsConcreteInterfaceType = (BfConcreteInterfaceType*)rhs;
  4107. return (lhsConcreteInterfaceType->mInterface == rhsConcreteInterfaceType->mInterface);
  4108. }
  4109. else if (lhs->IsSizedArray())
  4110. {
  4111. if (!rhs->IsSizedArray())
  4112. return false;
  4113. BfSizedArrayType* lhsSizedArrayType = (BfSizedArrayType*)lhs;
  4114. BfSizedArrayType* rhsSizedArrayType = (BfSizedArrayType*)rhs;
  4115. return (lhsSizedArrayType->mElementType == rhsSizedArrayType->mElementType) &&
  4116. (lhsSizedArrayType->mElementCount == rhsSizedArrayType->mElementCount);
  4117. }
  4118. else if (lhs->IsMethodRef())
  4119. {
  4120. if (!rhs->IsMethodRef())
  4121. return false;
  4122. BfMethodRefType* lhsMethodRefType = (BfMethodRefType*)lhs;
  4123. BfMethodRefType* rhsMethodRefType = (BfMethodRefType*)rhs;
  4124. return (lhsMethodRefType->mMethodRef == rhsMethodRefType->mMethodRef) &&
  4125. (lhsMethodRefType->mOwner == rhsMethodRefType->mOwner) &&
  4126. (lhsMethodRefType->mOwnerRevision == rhsMethodRefType->mOwnerRevision);
  4127. }
  4128. else if ((lhs->IsConstExprValue()) || (rhs->IsConstExprValue()))
  4129. {
  4130. if (!lhs->IsConstExprValue() || !rhs->IsConstExprValue())
  4131. return false;
  4132. BfConstExprValueType* lhsConstExprValueType = (BfConstExprValueType*)lhs;
  4133. BfConstExprValueType* rhsConstExprValueType = (BfConstExprValueType*)rhs;
  4134. return (lhsConstExprValueType->mType == rhsConstExprValueType->mType) &&
  4135. (lhsConstExprValueType->mValue == rhsConstExprValueType->mValue);
  4136. }
  4137. else
  4138. {
  4139. BF_FATAL("Not handled");
  4140. }
  4141. return 0;
  4142. }
  4143. bool BfResolvedTypeSet::GenericTypeEquals(BfTypeInstance* lhsGenericType, BfTypeVector* lhsTypeGenericArguments, BfTypeReference* rhs, LookupContext* ctx, int& genericParamOffset, bool skipElement)
  4144. {
  4145. //BP_ZONE("BfResolvedTypeSet::GenericTypeEquals");
  4146. if (!skipElement)
  4147. {
  4148. if (auto elementedTypeRef = BfNodeDynCast<BfElementedTypeRef>(rhs))
  4149. {
  4150. if (!GenericTypeEquals(lhsGenericType, lhsTypeGenericArguments, elementedTypeRef->mElementType, ctx, genericParamOffset))
  4151. return false;
  4152. //_GetTypeRefs(elementedTypeRef->mElementType);
  4153. }
  4154. else if (auto qualifiedTypeRef = BfNodeDynCastExact<BfQualifiedTypeReference>(rhs))
  4155. {
  4156. //_GetTypeRefs(qualifiedTypeRef->mLeft);
  4157. if (!GenericTypeEquals(lhsGenericType, lhsTypeGenericArguments, qualifiedTypeRef->mLeft, ctx, genericParamOffset))
  4158. return false;
  4159. }
  4160. }
  4161. if (auto genericTypeRef = BfNodeDynCastExact<BfGenericInstanceTypeRef>(rhs))
  4162. {
  4163. int rhsGenericArgCount = BF_MAX(genericTypeRef->mGenericArguments.mSize, genericTypeRef->mCommas.mSize + 1);
  4164. if (genericTypeRef->mGenericArguments.size() > rhsGenericArgCount + genericParamOffset)
  4165. return false;
  4166. for (int genericIdx = 0; genericIdx < BF_MAX(genericTypeRef->mGenericArguments.mSize, genericTypeRef->mCommas.mSize + 1); genericIdx++)
  4167. {
  4168. BfType* lhsArgType = (*lhsTypeGenericArguments)[genericParamOffset++];
  4169. BfAstNode* genericArgTypeRef = NULL;
  4170. if (genericIdx < genericTypeRef->mGenericArguments.mSize)
  4171. genericArgTypeRef = genericTypeRef->mGenericArguments[genericIdx];
  4172. if ((ctx->mResolveFlags & BfResolveTypeRefFlag_ForceUnboundGeneric) != 0)
  4173. {
  4174. genericArgTypeRef = NULL;
  4175. }
  4176. else if ((ctx->mResolveFlags & BfResolveTypeRefFlag_AllowUnboundGeneric) != 0)
  4177. {
  4178. if (BfNodeIsExact<BfWildcardTypeReference>(genericArgTypeRef))
  4179. genericArgTypeRef = NULL;
  4180. }
  4181. if (genericArgTypeRef == NULL)
  4182. {
  4183. if (lhsArgType->IsGenericParam())
  4184. {
  4185. auto lhsGenericArgType = (BfGenericParamType*)lhsArgType;
  4186. if ((lhsGenericArgType->mGenericParamKind != BfGenericParamKind_Type) || (lhsGenericArgType->mGenericParamIdx != genericIdx))
  4187. return false;
  4188. }
  4189. else
  4190. return false;
  4191. }
  4192. else
  4193. {
  4194. if (!Equals(lhsArgType, genericArgTypeRef, ctx))
  4195. return false;
  4196. }
  4197. }
  4198. }
  4199. return true;
  4200. }
  4201. bool BfResolvedTypeSet::GenericTypeEquals(BfTypeInstance* lhsGenericType, BfTypeVector* lhsTypeGenericArguments, BfTypeReference* rhs, BfTypeDef* rhsTypeDef, LookupContext* ctx)
  4202. {
  4203. int genericParamOffset = 0;
  4204. bool isFullyQualified = false;
  4205. BfTypeInstance* outerType = NULL;
  4206. if (auto genericInstTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(rhs))
  4207. {
  4208. int checkIdx = 0;
  4209. auto checkTypeRef = genericInstTypeRef->mElementType;
  4210. while (checkTypeRef != NULL)
  4211. {
  4212. checkIdx++;
  4213. if (checkIdx >= 2)
  4214. {
  4215. isFullyQualified = true;
  4216. BfType* checkType = ctx->GetCachedResolvedType(checkTypeRef);
  4217. if (checkType != NULL)
  4218. outerType = checkType->ToTypeInstance();
  4219. if (outerType != NULL)
  4220. {
  4221. BfTypeInstance* lhsCheckType = lhsGenericType;
  4222. while (lhsCheckType->mTypeDef->mNestDepth > outerType->mTypeDef->mNestDepth)
  4223. {
  4224. lhsCheckType = ctx->mModule->GetOuterType(lhsCheckType);
  4225. }
  4226. if (lhsCheckType != outerType)
  4227. return false;
  4228. if (outerType->mGenericTypeInfo != NULL)
  4229. genericParamOffset = (int)outerType->mGenericTypeInfo->mTypeGenericArguments.mSize;
  4230. }
  4231. break;
  4232. }
  4233. if (auto elementedTypeRef = BfNodeDynCast<BfElementedTypeRef>(checkTypeRef))
  4234. {
  4235. checkTypeRef = elementedTypeRef->mElementType;
  4236. continue;
  4237. }
  4238. if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(checkTypeRef))
  4239. {
  4240. checkTypeRef = qualifiedTypeRef->mLeft;
  4241. continue;
  4242. }
  4243. break;
  4244. }
  4245. }
  4246. BfTypeInstance* rootOuterTypeInstance = NULL;
  4247. auto rhsGenericTypeInstRef = BfNodeDynCastExact<BfGenericInstanceTypeRef>(rhs);
  4248. if (!isFullyQualified)
  4249. {
  4250. rootOuterTypeInstance = ctx->mModule->mCurTypeInstance;
  4251. if ((rhsTypeDef == ctx->mRootTypeDef) && (ctx->mRootOuterTypeInstance != NULL))
  4252. rootOuterTypeInstance = ctx->mRootOuterTypeInstance;
  4253. if (rhsGenericTypeInstRef == NULL)
  4254. {
  4255. if (auto rhsNullableTypeRef = BfNodeDynCastExact<BfNullableTypeRef>(rhs))
  4256. {
  4257. if (rhsNullableTypeRef != NULL)
  4258. {
  4259. if (lhsGenericType->mTypeDef != ctx->mModule->mContext->mCompiler->mNullableTypeDef)
  4260. return false;
  4261. auto rhsElemType = ctx->mModule->ResolveTypeRef(rhsNullableTypeRef->mElementType, BfPopulateType_Identity, ctx->mResolveFlags);
  4262. return lhsGenericType->mGenericTypeInfo->mTypeGenericArguments[0] == rhsElemType;
  4263. }
  4264. }
  4265. if ((rhsTypeDef != NULL) && (rootOuterTypeInstance != NULL))
  4266. {
  4267. // See if we're referring to an non-generic inner type where the outer type is generic
  4268. if (lhsGenericType->mTypeDef->GetDefinition() != rhsTypeDef->GetDefinition())
  4269. return false;
  4270. BfTypeDef* commonOuterType = ctx->mModule->FindCommonOuterType(rootOuterTypeInstance->mTypeDef, rhsTypeDef->mOuterType);
  4271. if (commonOuterType != NULL)
  4272. {
  4273. BfTypeInstance* checkTypeInstance = rootOuterTypeInstance;
  4274. if (checkTypeInstance->IsBoxed())
  4275. checkTypeInstance = checkTypeInstance->GetUnderlyingType()->ToTypeInstance();
  4276. BF_ASSERT(checkTypeInstance->IsGenericTypeInstance());
  4277. int numParentGenericParams = (int)commonOuterType->mGenericParamDefs.size();
  4278. auto curTypeInstance = (BfTypeInstance*)checkTypeInstance;
  4279. if (lhsGenericType->mGenericTypeInfo->mTypeGenericArguments.size() != numParentGenericParams)
  4280. return false;
  4281. for (int i = 0; i < (int)numParentGenericParams; i++)
  4282. if ((*lhsTypeGenericArguments)[i] != curTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i])
  4283. return false;
  4284. return true;
  4285. }
  4286. }
  4287. if (auto rhsQualifiedTypeRef = BfNodeDynCastExact<BfQualifiedTypeReference>(rhs))
  4288. {
  4289. auto rhsRightType = ctx->mModule->ResolveTypeRef(rhs, BfPopulateType_Identity, ctx->mResolveFlags);
  4290. return rhsRightType == lhsGenericType;
  4291. }
  4292. return false;
  4293. }
  4294. }
  4295. if (rhsGenericTypeInstRef == NULL)
  4296. return true;
  4297. BfTypeDef* elementTypeDef = ctx->mModule->ResolveGenericInstanceDef(rhsGenericTypeInstRef, NULL, ctx->mResolveFlags);
  4298. if (elementTypeDef == NULL)
  4299. return false;
  4300. if (elementTypeDef->GetDefinition() != lhsGenericType->mTypeDef->GetDefinition())
  4301. return false;
  4302. // Do we need to add generic arguments from an in-context outer class?
  4303. if ((elementTypeDef->mOuterType != NULL) && (rootOuterTypeInstance != NULL) && (rootOuterTypeInstance->IsGenericTypeInstance()))
  4304. {
  4305. BfTypeDef* commonOuterType = ctx->mModule->FindCommonOuterType(rootOuterTypeInstance->mTypeDef, elementTypeDef->mOuterType);
  4306. if (commonOuterType != NULL)
  4307. {
  4308. auto parentTypeInstance = rootOuterTypeInstance;
  4309. genericParamOffset = (int) commonOuterType->mGenericParamDefs.size();
  4310. for (int i = 0; i < genericParamOffset; i++)
  4311. for (auto genericArg : parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments)
  4312. {
  4313. if (parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i] != (*lhsTypeGenericArguments)[i])
  4314. return false;
  4315. }
  4316. }
  4317. }
  4318. if (!GenericTypeEquals(lhsGenericType, lhsTypeGenericArguments, rhs, ctx, genericParamOffset, isFullyQualified))
  4319. return false;
  4320. return genericParamOffset == (int)lhsTypeGenericArguments->size();
  4321. }
  4322. BfType* BfResolvedTypeSet::LookupContext::GetCachedResolvedType(BfTypeReference* typeReference)
  4323. {
  4324. if (typeReference == mRootTypeRef)
  4325. return mRootResolvedType;
  4326. BfType** typePtr = NULL;
  4327. if (mResolvedTypeMap.TryGetValue(typeReference, &typePtr))
  4328. return *typePtr;
  4329. return NULL;
  4330. }
  4331. void BfResolvedTypeSet::LookupContext::SetCachedResolvedType(BfTypeReference* typeReference, BfType* type)
  4332. {
  4333. if (typeReference == mRootTypeRef)
  4334. mRootResolvedType = type;
  4335. else
  4336. mResolvedTypeMap[typeReference] = type;
  4337. }
  4338. BfType* BfResolvedTypeSet::LookupContext::ResolveTypeRef(BfTypeReference* typeReference)
  4339. {
  4340. return mModule->ResolveTypeRef(typeReference, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowGenericParamConstValue);
  4341. }
  4342. BfTypeDef* BfResolvedTypeSet::LookupContext::ResolveToTypeDef(BfTypeReference* typeReference, BfType** outType)
  4343. {
  4344. if (outType != NULL)
  4345. *outType = NULL;
  4346. if (typeReference == mRootTypeRef)
  4347. return mRootTypeDef;
  4348. if (auto typeDefTypeRef = BfNodeDynCast<BfDirectTypeDefReference>(typeReference))
  4349. {
  4350. return typeDefTypeRef->mTypeDef;
  4351. }
  4352. auto type = mModule->ResolveTypeRef(typeReference, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowGenericParamConstValue);
  4353. if (type == NULL)
  4354. return NULL;
  4355. if (outType != NULL)
  4356. *outType = type;
  4357. if (type->IsPrimitiveType())
  4358. return ((BfPrimitiveType*)type)->mTypeDef;
  4359. auto typeInst = type->ToTypeInstance();
  4360. if (typeInst == NULL)
  4361. return NULL;
  4362. return typeInst->mTypeDef->GetDefinition();
  4363. }
  4364. bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, BfTypeDef* rhsTypeDef, LookupContext* ctx)
  4365. {
  4366. auto rhsType = ctx->mModule->ResolveTypeDef(rhsTypeDef, BfPopulateType_Identity);
  4367. if (rhsType == NULL)
  4368. {
  4369. ctx->mFailed = true;
  4370. return false;
  4371. }
  4372. return BfResolvedTypeSet::Equals(lhs, rhsType, ctx);
  4373. }
  4374. bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* ctx)
  4375. {
  4376. //BP_ZONE("BfResolvedTypeSet::Equals");
  4377. if (ctx->mRootTypeRef != rhs)
  4378. {
  4379. if (auto retTypeRef = BfNodeDynCastExact<BfModifiedTypeRef>(rhs))
  4380. {
  4381. auto resolvedType = ctx->mModule->ResolveTypeRef(rhs);
  4382. if ((resolvedType != NULL) && (resolvedType->IsRef()))
  4383. resolvedType = resolvedType->GetUnderlyingType();
  4384. return lhs == resolvedType;
  4385. }
  4386. }
  4387. if ((rhs->IsNamedTypeReference()) || (rhs->IsA<BfGenericInstanceTypeRef>()) || (rhs->IsA<BfQualifiedTypeReference>()))
  4388. {
  4389. if ((ctx->mRootTypeRef != rhs) || (ctx->mRootTypeDef == NULL))
  4390. {
  4391. auto rhsResolvedType = ctx->ResolveTypeRef(rhs);
  4392. if (rhsResolvedType == NULL)
  4393. {
  4394. ctx->mFailed = true;
  4395. return false;
  4396. }
  4397. return lhs == rhsResolvedType;
  4398. }
  4399. }
  4400. if (auto declTypeRef = BfNodeDynCastExact<BfExprModTypeRef>(rhs))
  4401. {
  4402. auto cachedResolveType = ctx->GetCachedResolvedType(rhs);
  4403. BF_ASSERT(cachedResolveType != NULL);
  4404. return lhs == cachedResolveType;
  4405. }
  4406. // Strip off 'const' - it's just an error when applied to a typeRef in Beef
  4407. auto constTypeRef = BfNodeDynCastExact<BfConstTypeRef>(rhs);
  4408. if (constTypeRef != NULL)
  4409. return Equals(lhs, constTypeRef->mElementType, ctx);
  4410. if (lhs->IsBoxed())
  4411. {
  4412. return false;
  4413. }
  4414. else if (lhs->IsArray())
  4415. {
  4416. auto rhsArrayTypeRef = BfNodeDynCastExact<BfArrayTypeRef>(rhs);
  4417. if (rhsArrayTypeRef == NULL)
  4418. return false;
  4419. // Any non-comma param means it's a sized array
  4420. for (auto param : rhsArrayTypeRef->mParams)
  4421. {
  4422. bool isComma = false;
  4423. if (auto tokenNode = BfNodeDynCast<BfTokenNode>(param))
  4424. isComma = tokenNode->mToken == BfToken_Comma;
  4425. if (!isComma)
  4426. return false;
  4427. }
  4428. BfArrayType* lhsArrayType = (BfArrayType*) lhs;
  4429. if (lhsArrayType->mDimensions != rhsArrayTypeRef->mDimensions)
  4430. return false;
  4431. return Equals(lhsArrayType->mGenericTypeInfo->mTypeGenericArguments[0], rhsArrayTypeRef->mElementType, ctx);
  4432. }
  4433. else if (lhs->IsDelegateFromTypeRef() || lhs->IsFunctionFromTypeRef())
  4434. {
  4435. auto rhsDelegateType = BfNodeDynCastExact<BfDelegateTypeRef>(rhs);
  4436. if (rhsDelegateType == NULL)
  4437. return false;
  4438. bool wantGeneric = false;
  4439. BfDelegateInfo* lhsDelegateInfo = lhs->GetDelegateInfo();
  4440. auto lhsTypeInstance = lhs->ToTypeInstance();
  4441. BfMethodDef* invokeMethodDef = lhsTypeInstance->mTypeDef->mMethods[0];
  4442. BF_ASSERT(invokeMethodDef->mName == "Invoke");
  4443. bool rhsIsDelegate = rhsDelegateType->mTypeToken->GetToken() == BfToken_Delegate;
  4444. if ((lhs->IsDelegate()) != rhsIsDelegate)
  4445. return false;
  4446. auto _CheckType = [&](BfType* type)
  4447. {
  4448. if (type->IsTypeGenericParam())
  4449. wantGeneric = true;
  4450. };
  4451. BfCallingConvention rhsCallingConvention = BfCallingConvention_Unspecified;
  4452. if (ctx->mRootTypeRef == rhsDelegateType)
  4453. rhsCallingConvention = ctx->mCallingConvention;
  4454. else
  4455. ctx->mModule->GetDelegateTypeRefAttributes(rhsDelegateType, rhsCallingConvention);
  4456. if (lhsDelegateInfo->mCallingConvention != rhsCallingConvention)
  4457. return false;
  4458. if (!Equals(lhsDelegateInfo->mReturnType, rhsDelegateType->mReturnType, ctx))
  4459. return false;
  4460. _CheckType(lhsDelegateInfo->mReturnType);
  4461. bool isMutating = true;
  4462. int paramRefOfs = 0;
  4463. if ((!rhsDelegateType->mParams.IsEmpty()) && (lhs->IsFunction()))
  4464. {
  4465. auto param0 = rhsDelegateType->mParams[0];
  4466. if ((param0->mNameNode != NULL) && (param0->mNameNode->Equals("this")))
  4467. {
  4468. if (!lhsDelegateInfo->mHasExplicitThis)
  4469. return false;
  4470. bool handled = false;
  4471. auto lhsThisType = lhsDelegateInfo->mParams[0];
  4472. bool wantsMutating = false;
  4473. if (auto refTypeRef = BfNodeDynCast<BfRefTypeRef>(param0->mTypeRef))
  4474. {
  4475. // This catches `ref Foo*` cases (which generate warnings)
  4476. if ((refTypeRef->mRefToken != NULL) && (refTypeRef->mRefToken->mToken == BfToken_Mut))
  4477. wantsMutating = true;
  4478. }
  4479. auto rhsThisType = ctx->mModule->ResolveTypeRef(param0->mTypeRef, BfPopulateType_Identity, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoWarnOnMut | BfResolveTypeRefFlag_AllowRef));
  4480. if (rhsThisType == NULL)
  4481. return false;
  4482. if (rhsThisType->IsRef())
  4483. {
  4484. rhsThisType = rhsThisType->GetUnderlyingType();
  4485. if (rhsThisType->IsPointer())
  4486. rhsThisType = rhsThisType->GetUnderlyingType();
  4487. if (lhsThisType != rhsThisType)
  4488. return false;
  4489. wantsMutating = (lhsThisType->IsValueType()) || (lhsThisType->IsGenericParam());
  4490. }
  4491. else
  4492. {
  4493. if (rhsThisType->IsPointer())
  4494. rhsThisType = rhsThisType->GetUnderlyingType();
  4495. if (lhsThisType != rhsThisType)
  4496. return false;
  4497. }
  4498. if (invokeMethodDef->mIsMutating != wantsMutating)
  4499. return false;
  4500. paramRefOfs = 1;
  4501. }
  4502. }
  4503. int lhsParamsCount = (int)lhsDelegateInfo->mParams.size();
  4504. if (lhsDelegateInfo->mHasVarArgs)
  4505. lhsParamsCount++;
  4506. if (lhsParamsCount != (int)rhsDelegateType->mParams.size())
  4507. return false;
  4508. bool rhsHadParams = false;
  4509. for (int paramIdx = paramRefOfs; paramIdx < lhsDelegateInfo->mParams.size(); paramIdx++)
  4510. {
  4511. auto paramTypeRef = rhsDelegateType->mParams[paramIdx]->mTypeRef;
  4512. if (!Equals(lhsDelegateInfo->mParams[paramIdx], paramTypeRef, ctx))
  4513. return false;
  4514. _CheckType(lhsDelegateInfo->mParams[paramIdx]);
  4515. StringView rhsParamName;
  4516. if (rhsDelegateType->mParams[paramIdx]->mNameNode != NULL)
  4517. rhsParamName = rhsDelegateType->mParams[paramIdx]->mNameNode->ToStringView();
  4518. if (invokeMethodDef->mParams[paramIdx]->mName != rhsParamName)
  4519. return false;
  4520. if ((rhsDelegateType->mParams[paramIdx]->mModToken != NULL) && (rhsDelegateType->mParams[paramIdx]->mModToken->mToken == BfToken_Params))
  4521. rhsHadParams = true;
  4522. }
  4523. if (rhsHadParams != lhsDelegateInfo->mHasParams)
  4524. return false;
  4525. if ((ctx->mModule->mCurTypeInstance == NULL) || (!ctx->mModule->mCurTypeInstance->IsGenericTypeInstance()))
  4526. wantGeneric = false;
  4527. //TODO:
  4528. wantGeneric = false;
  4529. if (wantGeneric != lhsTypeInstance->IsGenericTypeInstance())
  4530. return false;
  4531. return true;
  4532. }
  4533. else if ((lhs->IsEnum()) && (lhs->IsOnDemand()))
  4534. {
  4535. BfTypeInstance* typeInstance = lhs->ToTypeInstance();
  4536. auto fieldName = typeInstance->mTypeDef->mFields[0]->mName;
  4537. auto tagTypeRef = BfNodeDynCastExact<BfTagTypeRef>(rhs);
  4538. if (tagTypeRef == NULL)
  4539. return false;
  4540. return tagTypeRef->mNameNode->Equals(fieldName);
  4541. }
  4542. else if (lhs->IsTypeInstance())
  4543. {
  4544. BfTypeInstance* lhsInst = (BfTypeInstance*) lhs;
  4545. if (lhs->IsTuple())
  4546. {
  4547. if (!rhs->IsA<BfTupleTypeRef>())
  4548. return false;
  4549. BfTupleTypeRef* rhsTupleTypeRef = (BfTupleTypeRef*)rhs;
  4550. BfTypeInstance* lhsTupleType = (BfTypeInstance*)lhs;
  4551. if (lhsTupleType->mFieldInstances.size() != rhsTupleTypeRef->mFieldTypes.size())
  4552. return false;
  4553. for (int fieldIdx = 0; fieldIdx < (int)lhsTupleType->mFieldInstances.size(); fieldIdx++)
  4554. {
  4555. BfFieldInstance* fieldInstance = &lhsTupleType->mFieldInstances[fieldIdx];
  4556. auto rhsResolvedType = ctx->mModule->ResolveTypeRef(rhsTupleTypeRef->mFieldTypes[fieldIdx], BfPopulateType_Identity);
  4557. if (rhsResolvedType != fieldInstance->mResolvedType)
  4558. return false;
  4559. BfFieldDef* fieldTypeDef = fieldInstance->GetFieldDef();
  4560. BfIdentifierNode* fieldName = NULL;
  4561. if (fieldIdx < (int)rhsTupleTypeRef->mFieldNames.size())
  4562. fieldName = rhsTupleTypeRef->mFieldNames[fieldIdx];
  4563. if (fieldName != NULL)
  4564. {
  4565. if (fieldName->ToString() != fieldTypeDef->mName)
  4566. return false;
  4567. }
  4568. else
  4569. {
  4570. char nameStr[64];
  4571. sprintf(nameStr, "%d", fieldIdx);
  4572. if (fieldTypeDef->mName != nameStr)
  4573. return false;
  4574. }
  4575. }
  4576. return true;
  4577. }
  4578. else if (lhs->IsGenericTypeInstance())
  4579. {
  4580. BfType* rhsType = NULL;
  4581. auto rhsTypeDef = ctx->ResolveToTypeDef(rhs, &rhsType);
  4582. if (rhsTypeDef == NULL)
  4583. return false;
  4584. if (rhsType != NULL)
  4585. return lhs == rhsType;
  4586. BfTypeInstance* lhsGenericType = (BfTypeInstance*) lhs;
  4587. return GenericTypeEquals(lhsGenericType, &lhsGenericType->mGenericTypeInfo->mTypeGenericArguments, rhs, rhsTypeDef, ctx);
  4588. }
  4589. else
  4590. {
  4591. if (rhs->IsA<BfElementedTypeRef>())
  4592. return false;
  4593. if (!rhs->IsTypeDefTypeReference())
  4594. {
  4595. if (rhs->IsA<BfDelegateTypeRef>())
  4596. return false; // Would have caught it before
  4597. if (rhs->IsA<BfQualifiedTypeReference>())
  4598. {
  4599. //TODO: Under what circumstances was this supposed to be used? This caused an infinite loop comparing
  4600. // 'var' against a delegate type instance
  4601. auto resolvedType = ctx->mModule->ResolveTypeRef(rhs, BfPopulateType_Identity);
  4602. if (resolvedType == lhsInst)
  4603. {
  4604. return true;
  4605. }
  4606. }
  4607. return false;
  4608. }
  4609. auto rhsTypeDef = ctx->ResolveToTypeDef(rhs);
  4610. if (rhsTypeDef == NULL)
  4611. return false;
  4612. return lhsInst->IsInstanceOf(rhsTypeDef);
  4613. }
  4614. }
  4615. else if (lhs->IsPrimitiveType())
  4616. {
  4617. if (lhs->IsDot())
  4618. {
  4619. auto varTypeReference = BfNodeDynCastExact<BfDotTypeReference>(rhs);
  4620. if (varTypeReference != NULL)
  4621. return true;
  4622. }
  4623. if (lhs->IsVar())
  4624. {
  4625. auto varTypeReference = BfNodeDynCastExact<BfVarTypeReference>(rhs);
  4626. if (varTypeReference != NULL)
  4627. return true;
  4628. }
  4629. if (lhs->IsLet())
  4630. {
  4631. auto letTypeReference = BfNodeDynCastExact<BfLetTypeReference>(rhs);
  4632. if (letTypeReference != NULL)
  4633. return true;
  4634. }
  4635. BfPrimitiveType* lhsPrimType = (BfPrimitiveType*)lhs;
  4636. auto rhsTypeDef = ctx->ResolveToTypeDef(rhs);
  4637. // if (rhsTypeDef->mTypeCode == BfTypeCode_TypeAlias)
  4638. // return Equals(lhs, rhs, rhsTypeDef, ctx);
  4639. return lhsPrimType->mTypeDef == rhsTypeDef;
  4640. }
  4641. else if (lhs->IsPointer())
  4642. {
  4643. auto rhsPointerTypeRef = BfNodeDynCastExact<BfPointerTypeRef>(rhs);
  4644. if (rhsPointerTypeRef == NULL)
  4645. return false;
  4646. BfPointerType* lhsPtrType = (BfPointerType*)lhs;
  4647. return Equals(lhsPtrType->mElementType, rhsPointerTypeRef->mElementType, ctx);
  4648. }
  4649. else if (lhs->IsGenericParam())
  4650. {
  4651. auto lhsGenericParamType = (BfGenericParamType*)lhs;
  4652. auto rhsGenericParamTypeRef = BfNodeDynCastExact<BfGenericParamTypeRef>(rhs);
  4653. if (rhsGenericParamTypeRef == NULL)
  4654. {
  4655. if (auto constExprTypeRef = BfNodeDynCastExact<BfConstExprTypeRef>(rhs))
  4656. {
  4657. BfVariant result;
  4658. if (constExprTypeRef->mConstExpr == NULL)
  4659. return false;
  4660. BfType* resultType = NULL;
  4661. result = EvaluateToVariant(ctx, constExprTypeRef->mConstExpr, resultType);
  4662. return resultType == lhs;
  4663. }
  4664. return false;
  4665. }
  4666. return (lhsGenericParamType->mGenericParamKind == rhsGenericParamTypeRef->mGenericParamKind) &&
  4667. (lhsGenericParamType->mGenericParamIdx == rhsGenericParamTypeRef->mGenericParamIdx);
  4668. }
  4669. else if (lhs->IsRef())
  4670. {
  4671. auto lhsRefType = (BfRefType*)lhs;
  4672. auto rhsRefTypeRef = BfNodeDynCastExact<BfRefTypeRef>(rhs);
  4673. if (rhsRefTypeRef == NULL)
  4674. return false;
  4675. auto refKind = BfRefType::RefKind_Ref;
  4676. if (rhsRefTypeRef->mRefToken == NULL)
  4677. refKind = BfRefType::RefKind_Ref;
  4678. else if (rhsRefTypeRef->mRefToken->GetToken() == BfToken_In)
  4679. refKind = BfRefType::RefKind_In;
  4680. else if (rhsRefTypeRef->mRefToken->GetToken() == BfToken_Out)
  4681. refKind = BfRefType::RefKind_Out;
  4682. else if (rhsRefTypeRef->mRefToken->GetToken() == BfToken_Mut)
  4683. refKind = BfRefType::RefKind_Mut;
  4684. return (lhsRefType->mRefKind == refKind) &&
  4685. Equals(lhsRefType->mElementType, rhsRefTypeRef->mElementType, ctx);
  4686. }
  4687. else if (lhs->IsModifiedTypeType())
  4688. {
  4689. auto lhsRetTypeType = (BfModifiedTypeType*)lhs;
  4690. auto rhsRetTypeTypeRef = BfNodeDynCastExact<BfModifiedTypeRef>(rhs);
  4691. if (rhsRetTypeTypeRef == NULL)
  4692. return false;
  4693. if (lhsRetTypeType->mModifiedKind != rhsRetTypeTypeRef->mRetTypeToken->mToken)
  4694. return false;
  4695. return Equals(lhsRetTypeType->mElementType, rhsRetTypeTypeRef->mElementType, ctx);
  4696. }
  4697. else if (lhs->IsConcreteInterfaceType())
  4698. {
  4699. // No way to create a reference to one of these
  4700. return false;
  4701. }
  4702. else if (lhs->IsSizedArray())
  4703. {
  4704. auto rhsArrayTypeRef = BfNodeDynCastExact<BfArrayTypeRef>(rhs);
  4705. if (rhsArrayTypeRef == NULL)
  4706. return false;
  4707. if ((rhsArrayTypeRef->mDimensions != 1) && (rhsArrayTypeRef->mParams.size() != 1))
  4708. return false;
  4709. BfSizedArrayType* lhsArrayType = (BfSizedArrayType*)lhs;
  4710. if (!Equals(lhsArrayType->mElementType, rhsArrayTypeRef->mElementType, ctx))
  4711. return false;
  4712. intptr elementCount = -1;
  4713. BfExpression* sizeExpr = BfNodeDynCast<BfExpression>(rhsArrayTypeRef->mParams[0]);
  4714. BF_ASSERT(sizeExpr != NULL);
  4715. if (sizeExpr != NULL)
  4716. {
  4717. BfType* intType = ctx->mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  4718. BfTypedValue typedVal;
  4719. ctx->mResolvedValueMap.TryGetValue(sizeExpr, &typedVal);
  4720. if (typedVal.mKind == BfTypedValueKind_GenericConstValue)
  4721. {
  4722. if (!lhs->IsUnknownSizedArrayType())
  4723. return false;
  4724. auto lhsUnknownSizedArray = (BfUnknownSizedArrayType*)lhs;
  4725. return lhsUnknownSizedArray->mElementCountSource = typedVal.mType;
  4726. }
  4727. if (typedVal)
  4728. typedVal = ctx->mModule->Cast(sizeExpr, typedVal, intType);
  4729. if (typedVal)
  4730. {
  4731. if (lhs->IsUnknownSizedArrayType())
  4732. return false;
  4733. auto constant = ctx->mModule->mBfIRBuilder->GetConstant(typedVal.mValue);
  4734. if ((constant->mConstType == BfConstType_Undef) || (!BfIRBuilder::IsInt(constant->mTypeCode)))
  4735. {
  4736. elementCount = -1; // Marker for undef
  4737. }
  4738. else
  4739. {
  4740. elementCount = (intptr)constant->mInt64;
  4741. BF_ASSERT(elementCount >= 0); // Should have been caught in hash
  4742. }
  4743. }
  4744. }
  4745. return lhsArrayType->mElementCount == elementCount;
  4746. }
  4747. else if (lhs->IsMethodRef())
  4748. {
  4749. // Always make these unique. The MethodInstance value will change on rebuild anyway
  4750. return false;
  4751. }
  4752. else if (lhs->IsConstExprValue())
  4753. {
  4754. auto constExprTypeRef = BfNodeDynCastExact<BfConstExprTypeRef>(rhs);
  4755. if (constExprTypeRef == NULL)
  4756. return false;
  4757. if (!lhs->IsConstExprValue())
  4758. return false;
  4759. BfConstExprValueType* lhsConstExprType = (BfConstExprValueType*)lhs;
  4760. BfVariant result;
  4761. if (constExprTypeRef->mConstExpr != NULL)
  4762. {
  4763. BfType* resultType = NULL;
  4764. result = EvaluateToVariant(ctx, constExprTypeRef->mConstExpr, resultType);
  4765. if (resultType != lhsConstExprType->mType)
  4766. return false;
  4767. }
  4768. return result == lhsConstExprType->mValue;
  4769. }
  4770. else
  4771. {
  4772. BF_FATAL("Not handled");
  4773. }
  4774. return false;
  4775. }
  4776. bool BfResolvedTypeSet::Equals(BfType* lhs, BfAstNode* rhs, LookupContext* ctx)
  4777. {
  4778. if (auto rhsTypeRef = BfNodeDynCast<BfTypeReference>(rhs))
  4779. return Equals(lhs, rhsTypeRef, ctx);
  4780. BfType* rhsResultType;
  4781. if (ctx->mResolvedTypeMap.TryGetValue(rhs, &rhsResultType))
  4782. return lhs == rhsResultType;
  4783. BF_FATAL("Invalid value in BfResolvedTypeSet::Equals");
  4784. return false;
  4785. }
  4786. void BfResolvedTypeSet::RemoveEntry(BfResolvedTypeSet::EntryRef entry)
  4787. {
  4788. int hashIdx = (entry->mHashCode & 0x7FFFFFFF) % mHashSize;
  4789. // if (entry->mPrev == NULL)
  4790. // {
  4791. // if (entry->mNext != NULL)
  4792. // entry->mNext->mPrev = NULL;
  4793. // BF_ASSERT(mHashHeads[bucket] == entry);
  4794. // mHashHeads[bucket] = entry->mNext;
  4795. // }
  4796. // else
  4797. // {
  4798. // entry->mPrev->mNext = entry->mNext;
  4799. // if (entry->mNext != NULL)
  4800. // entry->mNext->mPrev = entry->mPrev;
  4801. // }
  4802. //
  4803. // mSize--;
  4804. bool found = false;
  4805. int* srcCheckEntryPtr = &this->mHashHeads[hashIdx];
  4806. int checkEntryIdx = *srcCheckEntryPtr;
  4807. while (checkEntryIdx != -1)
  4808. {
  4809. auto checkEntry = &mEntries[checkEntryIdx];
  4810. if (checkEntryIdx == entry.mIndex)
  4811. {
  4812. *srcCheckEntryPtr = checkEntry->mNext;
  4813. found = true;
  4814. }
  4815. srcCheckEntryPtr = &checkEntry->mNext;
  4816. checkEntryIdx = checkEntry->mNext;
  4817. }
  4818. BF_ASSERT(found);
  4819. BF_ASSERT(entry->mValue == NULL);
  4820. FreeIdx(entry.mIndex);
  4821. }
  4822. // BfResolvedTypeSet::Iterator BfResolvedTypeSet::begin()
  4823. // {
  4824. // return ++Iterator(this);
  4825. // }
  4826. //
  4827. // BfResolvedTypeSet::Iterator BfResolvedTypeSet::end()
  4828. // {
  4829. // Iterator itr(this);
  4830. // itr.mCurBucket = HashSize;
  4831. // return itr;
  4832. // }
  4833. //
  4834. // BfResolvedTypeSet::Iterator BfResolvedTypeSet::erase(BfResolvedTypeSet::Iterator& itr)
  4835. // {
  4836. // auto next = itr;
  4837. // ++next;
  4838. //
  4839. // auto cur = itr.mCurEntry;
  4840. //
  4841. // auto& hashHead = itr.mTypeSet->mHashHeads[itr.mCurBucket];
  4842. //
  4843. // if (hashHead == cur)
  4844. // hashHead = cur->mNext;
  4845. // if (cur->mPrev != NULL)
  4846. // cur->mPrev->mNext = cur->mNext;
  4847. // if (cur->mNext != NULL)
  4848. // cur->mNext->mPrev = cur->mPrev;
  4849. // delete cur;
  4850. //
  4851. // //BfLogSys("Deleting node %@ from bucket %d\n", cur, itr.mCurBucket);
  4852. //
  4853. // mSize--;
  4854. // return next;
  4855. // }
  4856. //////////////////////////////////////////////////////////////////////////
  4857. BfHotTypeVersion::~BfHotTypeVersion()
  4858. {
  4859. for (auto member : mMembers)
  4860. member->Deref();
  4861. }
  4862. BfHotTypeData::~BfHotTypeData()
  4863. {
  4864. for (auto version : mTypeVersions)
  4865. {
  4866. version->Deref();
  4867. }
  4868. }
  4869. BfHotTypeVersion* BfHotTypeData::GetTypeVersion(int hotCommitedIdx)
  4870. {
  4871. for (int checkIdx = (int)mTypeVersions.size() - 1; checkIdx >= 0; checkIdx--)
  4872. {
  4873. BfHotTypeVersion* hotTypeVersion = mTypeVersions[checkIdx];
  4874. if (hotTypeVersion->mDeclHotCompileIdx <= hotCommitedIdx)
  4875. return hotTypeVersion;
  4876. }
  4877. return NULL;
  4878. }
  4879. BfHotTypeVersion* BfHotTypeData::GetLatestVersion()
  4880. {
  4881. return mTypeVersions.back();
  4882. }
  4883. BfHotTypeVersion* BfHotTypeData::GetLatestVersionHead()
  4884. {
  4885. auto lastestVersion = mTypeVersions.back();
  4886. for (int versionIdx = (int)mTypeVersions.size() - 1; versionIdx >= 0; versionIdx--)
  4887. {
  4888. auto checkVersion = mTypeVersions[versionIdx];
  4889. if (checkVersion->mDataHash != lastestVersion->mDataHash)
  4890. break;
  4891. lastestVersion = checkVersion;
  4892. }
  4893. return lastestVersion;
  4894. }
  4895. void BfHotTypeData::ClearVersionsAfter(int hotIdx)
  4896. {
  4897. while (!mTypeVersions.IsEmpty())
  4898. {
  4899. auto hotTypeVersion = mTypeVersions.back();
  4900. if (hotTypeVersion->mDeclHotCompileIdx > hotIdx)
  4901. {
  4902. hotTypeVersion->Deref();
  4903. mTypeVersions.pop_back();
  4904. }
  4905. else
  4906. break;
  4907. }
  4908. }
  4909. void BfHotDepData::Deref()
  4910. {
  4911. mRefCount--;
  4912. BF_ASSERT(mRefCount >= 0);
  4913. if (mRefCount == 0)
  4914. {
  4915. switch (mDataKind)
  4916. {
  4917. case BfHotDepDataKind_TypeVersion:
  4918. delete (BfHotTypeVersion*)this;
  4919. break;
  4920. case BfHotDepDataKind_ThisType:
  4921. delete (BfHotThisType*)this;
  4922. break;
  4923. case BfHotDepDataKind_Allocation:
  4924. delete (BfHotAllocation*)this;
  4925. break;
  4926. case BfHotDepDataKind_Method:
  4927. delete (BfHotMethod*)this;
  4928. break;
  4929. case BfHotDepDataKind_DupMethod:
  4930. delete (BfHotDupMethod*)this;
  4931. break;
  4932. case BfHotDepDataKind_DevirtualizedMethod:
  4933. delete (BfHotDevirtualizedMethod*)this;
  4934. break;
  4935. case BfHotDepDataKind_InnerMethod:
  4936. delete (BfHotInnerMethod*)this;
  4937. break;
  4938. case BfHotDepDataKind_FunctionPtr:
  4939. delete (BfHotFunctionReference*)this;
  4940. break;
  4941. case BfHotDepDataKind_VirtualDecl:
  4942. delete (BfHotVirtualDeclaration*)this;
  4943. break;
  4944. default:
  4945. BF_FATAL("Not handled");
  4946. }
  4947. }
  4948. }
  4949. void BfHotMethod::Clear(bool keepDupMethods)
  4950. {
  4951. if (mPrevVersion != NULL)
  4952. {
  4953. mPrevVersion->Deref();
  4954. mPrevVersion = NULL;
  4955. }
  4956. if (mSrcTypeVersion != NULL)
  4957. {
  4958. mSrcTypeVersion->Deref();
  4959. mSrcTypeVersion = NULL;
  4960. }
  4961. if ((keepDupMethods) && ((mFlags & BfHotDepDataFlag_HasDup) != 0))
  4962. {
  4963. int writeIdx = 0;
  4964. for (int i = 0; i < (int)mReferences.size(); i++)
  4965. {
  4966. auto depData = mReferences[i];
  4967. if (depData->mDataKind == BfHotDepDataKind_DupMethod)
  4968. {
  4969. mReferences[writeIdx++] = depData;
  4970. }
  4971. else
  4972. {
  4973. depData->Deref();
  4974. }
  4975. }
  4976. mReferences.mSize = writeIdx;
  4977. }
  4978. else
  4979. {
  4980. for (auto depData : mReferences)
  4981. {
  4982. depData->Deref();
  4983. }
  4984. mReferences.Clear();
  4985. }
  4986. }
  4987. BfHotMethod::~BfHotMethod()
  4988. {
  4989. Clear();
  4990. }
  4991. //////////////////////////////////////////////////////////////////////////
  4992. #pragma warning(disable:4146)
  4993. // Only 63 chars - skip zero
  4994. static const char cHash64bToChar[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
  4995. 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F',
  4996. 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
  4997. 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '_' };
  4998. String BfTypeUtils::HashEncode64(uint64 val)
  4999. {
  5000. String outStr;
  5001. if ((int64)val < 0)
  5002. {
  5003. uint64 flippedNum = (uint64)-(int64)val;
  5004. // Only flip if the encoded result would actually be shorter
  5005. if (flippedNum <= 0x00FFFFFFFFFFFFFFLL)
  5006. {
  5007. val = flippedNum;
  5008. outStr.Append('_');
  5009. }
  5010. }
  5011. while (val > 0)
  5012. {
  5013. int charIdx = val % 0x3F;
  5014. val /= 0x3F;
  5015. outStr.Append(cHash64bToChar[charIdx]);
  5016. }
  5017. return outStr;
  5018. }
  5019. BfPrimitiveType* BfTypeUtils::GetPrimitiveType(BfModule* module, BfTypeCode typeCode)
  5020. {
  5021. return module->GetPrimitiveType(typeCode);
  5022. }
  5023. void BfTypeUtils::PopulateType(BfModule* module, BfType* type)
  5024. {
  5025. module->PopulateType(type);
  5026. }
  5027. String BfTypeUtils::TypeToString(BfAstNode* typeRefNode)
  5028. {
  5029. if (auto identifierNode = BfNodeDynCast<BfIdentifierNode>(typeRefNode))
  5030. return identifierNode->ToString();
  5031. auto typeRef = BfNodeDynCast<BfTypeReference>(typeRefNode);
  5032. if (typeRef == NULL)
  5033. return "";
  5034. if (auto typeDefTypeRef = BfNodeDynCast<BfDirectTypeDefReference>(typeRef))
  5035. {
  5036. if (!typeDefTypeRef->mTypeDef->mNamespace.IsEmpty())
  5037. return typeDefTypeRef->mTypeDef->mNamespace.ToString() + "." + typeDefTypeRef->mTypeDef->mName->mString;
  5038. else
  5039. return String(typeDefTypeRef->mTypeDef->mName->mString);
  5040. }
  5041. if (typeRef->IsNamedTypeReference())
  5042. {
  5043. return typeRef->ToString();
  5044. }
  5045. if (auto ptrType = BfNodeDynCast<BfPointerTypeRef>(typeRef))
  5046. return TypeToString(ptrType->mElementType) + "*";
  5047. if (auto ptrType = BfNodeDynCast<BfArrayTypeRef>(typeRef))
  5048. {
  5049. String name = TypeToString(ptrType->mElementType) + "[";
  5050. for (int i = 1; i < ptrType->mDimensions; i++)
  5051. name += ",";
  5052. name += "]";
  5053. return name;
  5054. }
  5055. if (auto genericInstanceType = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef))
  5056. {
  5057. String name = TypeToString(genericInstanceType->mElementType);
  5058. name += "<";
  5059. for (int i = 0; i < (int)genericInstanceType->mGenericArguments.size(); i++)
  5060. {
  5061. if (i > 0)
  5062. name += ", ";
  5063. name += TypeToString(genericInstanceType->mGenericArguments[i]);
  5064. }
  5065. name += ">";
  5066. return name;
  5067. }
  5068. if (auto genericParamTypeRef = BfNodeDynCast<BfGenericParamTypeRef>(typeRef))
  5069. {
  5070. if (genericParamTypeRef->mGenericParamKind == BfGenericParamKind_Method)
  5071. return StrFormat("@M%d", genericParamTypeRef->mGenericParamIdx);
  5072. return StrFormat("@T%d", genericParamTypeRef->mGenericParamIdx);
  5073. }
  5074. if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(typeRef))
  5075. {
  5076. return TypeToString(qualifiedTypeRef->mLeft) + "." + TypeToString(qualifiedTypeRef->mRight);
  5077. }
  5078. if (auto refTypeRef = BfNodeDynCast<BfRefTypeRef>(typeRef))
  5079. {
  5080. String str = BfTokenToString(refTypeRef->mRefToken->GetToken());
  5081. str += " ";
  5082. str += TypeToString(refTypeRef->mElementType);
  5083. return str;
  5084. }
  5085. if (auto directStrTypeName = BfNodeDynCast<BfDirectStrTypeReference>(typeRef))
  5086. return directStrTypeName->mTypeName;
  5087. if (auto inlineTypeRef = BfNodeDynCast<BfInlineTypeReference>(typeRef))
  5088. return inlineTypeRef->mTypeDeclaration->mAnonymousName;
  5089. if (auto tupleTypeRef = BfNodeDynCast<BfTupleTypeRef>(typeRef))
  5090. {
  5091. String name = "(";
  5092. for (int i = 0; i < tupleTypeRef->mFieldTypes.size(); i++)
  5093. {
  5094. if (i > 0)
  5095. name += ", ";
  5096. name += TypeToString(tupleTypeRef->mFieldTypes[i]);
  5097. if ((i < tupleTypeRef->mFieldNames.size()) && (tupleTypeRef->mFieldNames[i] != NULL))
  5098. {
  5099. name += " ";
  5100. name += tupleTypeRef->mFieldNames[i]->ToString();
  5101. }
  5102. }
  5103. name += ")";
  5104. return name;
  5105. }
  5106. if (auto constTypeRef = BfNodeDynCast<BfConstExprTypeRef>(typeRef))
  5107. {
  5108. String name = "const ";
  5109. name += constTypeRef->mConstExpr->ToString();
  5110. return name;
  5111. }
  5112. //BF_DBG_FATAL("Not implemented");
  5113. return typeRef->ToString();
  5114. }
  5115. bool BfTypeUtils::TypeEquals(BfType* typeA, BfType* typeB, BfTypeInstance* selfType)
  5116. {
  5117. if (typeA->IsUnspecializedTypeVariation())
  5118. typeA = selfType->mModule->ResolveSelfType(typeA, selfType);
  5119. if (typeB->IsUnspecializedTypeVariation())
  5120. typeB = selfType->mModule->ResolveSelfType(typeB, selfType);
  5121. return typeA == typeB;
  5122. }
  5123. String BfTypeUtils::TypeToString(BfTypeDef* typeDef, BfTypeNameFlags typeNameFlags)
  5124. {
  5125. String str;
  5126. TypeToString(str, typeDef, typeNameFlags);
  5127. return str;
  5128. }
  5129. bool BfTypeUtils::TypeToString(StringImpl& str, BfTypeDef* typeDef, BfTypeNameFlags typeNameFlags)
  5130. {
  5131. auto checkTypeDef = typeDef;
  5132. char needsSep = 0;
  5133. if (checkTypeDef->mOuterType != NULL)
  5134. {
  5135. if (TypeToString(str, checkTypeDef->mOuterType, typeNameFlags))
  5136. {
  5137. if ((typeNameFlags & BfTypeNameFlag_InternalName) != 0)
  5138. needsSep = '+';
  5139. else
  5140. needsSep = '.';
  5141. }
  5142. }
  5143. else
  5144. {
  5145. if (((typeNameFlags & BfTypeNameFlag_OmitNamespace) == 0) && (!typeDef->mNamespace.IsEmpty()))
  5146. {
  5147. typeDef->mNamespace.ToString(str);
  5148. needsSep = '.';
  5149. }
  5150. }
  5151. if (needsSep != 0)
  5152. str += needsSep;
  5153. if (((typeNameFlags & BfTypeNameFlag_HideGlobalName) != 0) && (typeDef->IsGlobalsContainer()))
  5154. return false;
  5155. typeDef->mName->ToString(str);
  5156. if (typeDef->mGenericParamDefs.size() != 0)
  5157. {
  5158. int prevGenericParamCount = 0;
  5159. if (checkTypeDef->mOuterType != NULL)
  5160. prevGenericParamCount = (int)typeDef->mOuterType->mGenericParamDefs.size();
  5161. if (prevGenericParamCount != (int)checkTypeDef->mGenericParamDefs.size())
  5162. {
  5163. str += "<";
  5164. for (int i = prevGenericParamCount; i < (int)checkTypeDef->mGenericParamDefs.size(); i++)
  5165. {
  5166. if ((typeNameFlags & BfTypeNameFlag_InternalName) != 0)
  5167. {
  5168. if (i > prevGenericParamCount)
  5169. str += ",";
  5170. }
  5171. else
  5172. {
  5173. if (i > prevGenericParamCount)
  5174. str += ", ";
  5175. str += checkTypeDef->mGenericParamDefs[i]->mName;
  5176. }
  5177. }
  5178. str += ">";
  5179. }
  5180. }
  5181. return true;
  5182. }
  5183. int BfTypeUtils::GetSplatCount(BfType* type)
  5184. {
  5185. int splatCount = 0;
  5186. SplatIterate([&](BfType* checkType) { splatCount++; }, type);
  5187. return splatCount;
  5188. }
  5189. BfConstExprValueType::~BfConstExprValueType()
  5190. {
  5191. // mContext->mTypeConstExprCount--;
  5192. // BF_ASSERT(mContext->mTypeConstExprCount == 0);
  5193. }