BfModuleTypeUtils.cpp 501 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595
  1. #include "BeefySysLib/util/AllocDebug.h"
  2. #include "BfCompiler.h"
  3. #include "BfSystem.h"
  4. #include "BfParser.h"
  5. #include "BfReducer.h"
  6. #include "BfCodeGen.h"
  7. #include "BfExprEvaluator.h"
  8. #include <fcntl.h>
  9. #include "BfConstResolver.h"
  10. #include "BfMangler.h"
  11. #include "BeefySysLib/util/PerfTimer.h"
  12. #include "BeefySysLib/util/BeefPerf.h"
  13. #include "BfSourceClassifier.h"
  14. #include "BfAutoComplete.h"
  15. #include "BfDemangler.h"
  16. #include "BfResolvePass.h"
  17. #include "BfFixits.h"
  18. #include "BfIRCodeGen.h"
  19. #include "BfDefBuilder.h"
  20. #include "CeMachine.h"
  21. //////////////////////////////////////////////////////////////////////////
  22. int32 GetNumLowZeroBits(int32 n)
  23. {
  24. if (n == 0)
  25. return 32;
  26. int i = 0;
  27. while ((n & 1) == 0)
  28. {
  29. n = (int32)((uint32)n >> 1);
  30. i++;
  31. }
  32. return i;
  33. }
  34. //////////////////////////////////////////////////////////////////////////
  35. USING_NS_BF;
  36. BfGenericExtensionEntry* BfModule::BuildGenericExtensionInfo(BfTypeInstance* genericTypeInst, BfTypeDef* partialTypeDef)
  37. {
  38. if (!partialTypeDef->IsExtension())
  39. return NULL;
  40. if (partialTypeDef->mGenericParamDefs.size() != genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size())
  41. {
  42. AssertErrorState();
  43. return NULL;
  44. }
  45. BfGenericExtensionInfo* genericExtensionInfo = genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo;
  46. if (genericExtensionInfo == NULL)
  47. {
  48. genericExtensionInfo = new BfGenericExtensionInfo();
  49. genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo = genericExtensionInfo;
  50. }
  51. BfTypeState typeState;
  52. typeState.mPrevState = mContext->mCurTypeState;
  53. typeState.mType = genericTypeInst;
  54. typeState.mCurTypeDef = partialTypeDef;
  55. SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
  56. BfGenericExtensionEntry* genericExEntry;
  57. genericExtensionInfo->mExtensionMap.TryAdd(partialTypeDef, NULL, &genericExEntry);
  58. int startDefGenericParamIdx = (int)genericExEntry->mGenericParams.size();
  59. for (int paramIdx = startDefGenericParamIdx; paramIdx < (int)genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size(); paramIdx++)
  60. {
  61. auto genericParamInstance = new BfGenericTypeParamInstance(partialTypeDef, paramIdx);
  62. genericParamInstance->mExternType = GetGenericParamType(BfGenericParamKind_Type, paramIdx);
  63. auto prevPtr = genericExEntry->mGenericParams.mVals;
  64. genericExEntry->mGenericParams.push_back(genericParamInstance);
  65. }
  66. for (int externConstraintIdx = 0; externConstraintIdx < (int)partialTypeDef->mExternalConstraints.size(); externConstraintIdx++)
  67. {
  68. auto& genericConstraint = partialTypeDef->mExternalConstraints[externConstraintIdx];
  69. auto genericParamInstance = new BfGenericTypeParamInstance(partialTypeDef, externConstraintIdx + (int)partialTypeDef->mGenericParamDefs.size());
  70. genericParamInstance->mExternType = ResolveTypeRef(genericConstraint.mTypeRef, BfPopulateType_Identity);
  71. auto autoComplete = mCompiler->GetAutoComplete();
  72. if (autoComplete != NULL)
  73. autoComplete->CheckTypeRef(genericConstraint.mTypeRef, false);
  74. if (genericParamInstance->mExternType == NULL)
  75. genericParamInstance->mExternType = GetPrimitiveType(BfTypeCode_Var);
  76. ResolveGenericParamConstraints(genericParamInstance, genericTypeInst->IsUnspecializedType());
  77. genericExEntry->mGenericParams.push_back(genericParamInstance);
  78. }
  79. for (int paramIdx = startDefGenericParamIdx; paramIdx < (int)genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size(); paramIdx++)
  80. {
  81. auto genericParamInstance = genericExEntry->mGenericParams[paramIdx];
  82. auto rootGenericParamInstance = genericTypeInst->mGenericTypeInfo->mGenericParams[paramIdx];
  83. genericParamInstance->mTypeConstraint = rootGenericParamInstance->mTypeConstraint;
  84. genericParamInstance->mInterfaceConstraints = rootGenericParamInstance->mInterfaceConstraints;
  85. genericParamInstance->mGenericParamFlags = (BfGenericParamFlags)(genericParamInstance->mGenericParamFlags | rootGenericParamInstance->mGenericParamFlags);
  86. ResolveGenericParamConstraints(genericParamInstance, genericTypeInst->IsUnspecializedType());
  87. }
  88. for (auto genericParam : genericExEntry->mGenericParams)
  89. AddDependency(genericParam, mCurTypeInstance);
  90. return genericExEntry;
  91. }
  92. bool BfModule::InitGenericParams(BfType* resolvedTypeRef)
  93. {
  94. BfTypeState typeState;
  95. typeState.mPrevState = mContext->mCurTypeState;
  96. typeState.mResolveKind = BfTypeState::ResolveKind_BuildingGenericParams;
  97. typeState.mType = resolvedTypeRef;
  98. SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
  99. BF_ASSERT(mCurMethodInstance == NULL);
  100. auto genericTypeInst = resolvedTypeRef->ToGenericTypeInstance();
  101. genericTypeInst->mGenericTypeInfo->mInitializedGenericParams = true;
  102. if (genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.IsEmpty())
  103. return true;
  104. if (genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[0]->IsGenericParam())
  105. {
  106. BF_ASSERT(genericTypeInst->mGenericTypeInfo->mIsUnspecialized);
  107. }
  108. auto typeDef = genericTypeInst->mTypeDef;
  109. int startDefGenericParamIdx = (int)genericTypeInst->mGenericTypeInfo->mGenericParams.size();
  110. for (int paramIdx = startDefGenericParamIdx; paramIdx < (int)genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size(); paramIdx++)
  111. {
  112. auto genericParamInstance = new BfGenericTypeParamInstance(typeDef, paramIdx);
  113. genericParamInstance->mExternType = GetGenericParamType(BfGenericParamKind_Type, paramIdx);
  114. genericTypeInst->mGenericTypeInfo->mGenericParams.push_back(genericParamInstance);
  115. }
  116. for (int externConstraintIdx = 0; externConstraintIdx < (int)typeDef->mExternalConstraints.size(); externConstraintIdx++)
  117. {
  118. auto genericParamInstance = new BfGenericTypeParamInstance(typeDef, externConstraintIdx + (int)typeDef->mGenericParamDefs.size());
  119. genericTypeInst->mGenericTypeInfo->mGenericParams.push_back(genericParamInstance);
  120. }
  121. return true;
  122. }
  123. bool BfModule::FinishGenericParams(BfType* resolvedTypeRef)
  124. {
  125. BfTypeState typeState;
  126. typeState.mPrevState = mContext->mCurTypeState;
  127. typeState.mResolveKind = BfTypeState::ResolveKind_BuildingGenericParams;
  128. typeState.mType = resolvedTypeRef;
  129. SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
  130. Array<BfTypeReference*> deferredResolveTypes;
  131. BF_ASSERT(mCurMethodInstance == NULL);
  132. auto genericTypeInst = resolvedTypeRef->ToGenericTypeInstance();
  133. genericTypeInst->mGenericTypeInfo->mFinishedGenericParams = true;
  134. if (genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[0]->IsGenericParam())
  135. {
  136. BF_ASSERT(genericTypeInst->mGenericTypeInfo->mIsUnspecialized);
  137. }
  138. auto typeDef = genericTypeInst->mTypeDef;
  139. int startDefGenericParamIdx = (int)genericTypeInst->mGenericTypeInfo->mGenericParams.size();
  140. if ((!resolvedTypeRef->IsTuple()) && (!resolvedTypeRef->IsDelegateFromTypeRef()) && (!resolvedTypeRef->IsFunctionFromTypeRef()))
  141. {
  142. startDefGenericParamIdx = startDefGenericParamIdx -
  143. (int)genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size() -
  144. (int)typeDef->mExternalConstraints.size();
  145. }
  146. BF_ASSERT(startDefGenericParamIdx >= 0);
  147. if (!typeDef->mPartials.empty())
  148. {
  149. BitSet prevConstraintsPassedSet;
  150. if (!genericTypeInst->IsUnspecializedType())
  151. {
  152. if (genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo != NULL)
  153. {
  154. auto genericExtensionInfo = genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo;
  155. prevConstraintsPassedSet = genericExtensionInfo->mConstraintsPassedSet;
  156. genericExtensionInfo->mConstraintsPassedSet.Clear();
  157. }
  158. }
  159. int extensionCount = 0;
  160. BfLogSysM("BfModule::FinishGenericParams %p\n", resolvedTypeRef);
  161. for (auto partialTypeDef : typeDef->mPartials)
  162. {
  163. if (!partialTypeDef->IsExtension())
  164. {
  165. typeState.mCurTypeDef = partialTypeDef;
  166. for (int paramIdx = startDefGenericParamIdx; paramIdx < (int)genericTypeInst->mGenericTypeInfo->mGenericParams.size(); paramIdx++)
  167. {
  168. auto genericParamInstance = genericTypeInst->mGenericTypeInfo->mGenericParams[paramIdx];
  169. auto genericParamDef = genericParamInstance->GetGenericParamDef();
  170. if (paramIdx < (int)typeDef->mGenericParamDefs.size())
  171. {
  172. genericParamInstance->mExternType = GetGenericParamType(BfGenericParamKind_Type, paramIdx);
  173. }
  174. else
  175. {
  176. auto externConstraintDef = genericParamInstance->GetExternConstraintDef();
  177. genericParamInstance->mExternType = ResolveTypeRef(externConstraintDef->mTypeRef);
  178. if (genericParamInstance->mExternType == NULL)
  179. genericParamInstance->mExternType = GetPrimitiveType(BfTypeCode_Var);
  180. }
  181. ResolveGenericParamConstraints(genericParamInstance, genericTypeInst->IsUnspecializedType(), &deferredResolveTypes);
  182. if (genericParamDef != NULL)
  183. {
  184. for (auto nameNode : genericParamDef->mNameNodes)
  185. {
  186. HandleTypeGenericParamRef(nameNode, typeDef, paramIdx);
  187. }
  188. }
  189. }
  190. }
  191. else
  192. {
  193. auto genericExEntry = BuildGenericExtensionInfo(genericTypeInst, partialTypeDef);
  194. if (genericExEntry == NULL)
  195. continue;
  196. auto genericExtensionInfo = genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo;
  197. if (extensionCount == 0)
  198. genericExtensionInfo->mConstraintsPassedSet.Resize(typeDef->mPartials.mSize);
  199. extensionCount++;
  200. if (!genericTypeInst->IsUnspecializedType())
  201. {
  202. SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, true);
  203. for (int paramIdx = 0; paramIdx < genericExEntry->mGenericParams.size(); paramIdx++)
  204. {
  205. auto genericParamInstance = genericExEntry->mGenericParams[paramIdx];
  206. BfGenericParamSource genericParamSource;
  207. genericParamSource.mCheckAccessibility = false;
  208. genericParamSource.mTypeInstance = genericTypeInst;
  209. BfError* error = NULL;
  210. BfType* genericArg;
  211. if (paramIdx < (int)genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size())
  212. {
  213. genericArg = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[paramIdx];
  214. }
  215. else
  216. {
  217. genericArg = genericParamInstance->mExternType;
  218. }
  219. if ((genericArg == NULL) || (!CheckGenericConstraints(genericParamSource, genericArg, NULL, genericParamInstance, NULL, &error)))
  220. {
  221. genericExEntry->mConstraintsPassed = false;
  222. }
  223. }
  224. }
  225. if (genericExEntry->mConstraintsPassed)
  226. genericExtensionInfo->mConstraintsPassedSet.Set(partialTypeDef->mPartialIdx);
  227. BfLogSysM("BfModule::FinishGenericParams %p partialTypeDef:%p passed:%d\n", resolvedTypeRef, partialTypeDef, genericExEntry->mConstraintsPassed);
  228. }
  229. }
  230. auto genericExtensionInfo = genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo;
  231. if ((extensionCount > 0) && (!prevConstraintsPassedSet.IsEmpty()) && (genericExtensionInfo->mConstraintsPassedSet != prevConstraintsPassedSet))
  232. {
  233. mContext->RebuildDependentTypes_MidCompile(genericTypeInst, "mConstraintsPassedSet changed");
  234. }
  235. }
  236. else
  237. {
  238. for (int paramIdx = startDefGenericParamIdx; paramIdx < (int)genericTypeInst->mGenericTypeInfo->mGenericParams.size(); paramIdx++)
  239. {
  240. auto genericParamInstance = genericTypeInst->mGenericTypeInfo->mGenericParams[paramIdx];
  241. if (paramIdx < (int)typeDef->mGenericParamDefs.size())
  242. {
  243. genericParamInstance->mExternType = GetGenericParamType(BfGenericParamKind_Type, paramIdx);
  244. }
  245. else
  246. {
  247. auto externConstraintDef = genericParamInstance->GetExternConstraintDef();
  248. genericParamInstance->mExternType = ResolveTypeRef(externConstraintDef->mTypeRef);
  249. auto autoComplete = mCompiler->GetAutoComplete();
  250. if (autoComplete != NULL)
  251. autoComplete->CheckTypeRef(externConstraintDef->mTypeRef, false);
  252. if (genericParamInstance->mExternType != NULL)
  253. {
  254. //
  255. }
  256. else
  257. genericParamInstance->mExternType = GetPrimitiveType(BfTypeCode_Var);
  258. }
  259. ResolveGenericParamConstraints(genericParamInstance, genericTypeInst->IsUnspecializedType(), &deferredResolveTypes);
  260. auto genericParamDef = genericParamInstance->GetGenericParamDef();
  261. if (genericParamDef != NULL)
  262. {
  263. for (auto nameNode : genericParamDef->mNameNodes)
  264. {
  265. HandleTypeGenericParamRef(nameNode, typeDef, paramIdx);
  266. }
  267. }
  268. }
  269. }
  270. for (auto typeRef : deferredResolveTypes)
  271. auto constraintType = ResolveTypeRef(typeRef, BfPopulateType_Declaration, BfResolveTypeRefFlag_None);
  272. for (auto genericParam : genericTypeInst->mGenericTypeInfo->mGenericParams)
  273. AddDependency(genericParam, mCurTypeInstance);
  274. return true;
  275. }
  276. bool BfModule::ValidateGenericConstraints(BfAstNode* typeRef, BfTypeInstance* genericTypeInst, bool ignoreErrors)
  277. {
  278. if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsTypeAlias()) && (mCurTypeInstance->IsGenericTypeInstance()))
  279. {
  280. // Don't validate constraints during the population of a concrete generic type alias instance, we want to
  281. // throw those errors at the usage sites
  282. return true;
  283. }
  284. // We don't validate constraints for things like Tuples/Delegates
  285. if (genericTypeInst->IsOnDemand())
  286. return true;
  287. SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, mIgnoreErrors || ignoreErrors);
  288. genericTypeInst->mGenericTypeInfo->mValidatedGenericConstraints = true;
  289. if (!genericTypeInst->mGenericTypeInfo->mFinishedGenericParams)
  290. PopulateType(genericTypeInst, BfPopulateType_Interfaces);
  291. if (genericTypeInst->IsTypeAlias())
  292. {
  293. auto underlyingType = genericTypeInst->GetUnderlyingType();
  294. if ((underlyingType != NULL) && (underlyingType->IsGenericTypeInstance()))
  295. {
  296. auto underlyingGenericType = underlyingType->ToGenericTypeInstance();
  297. PopulateType(underlyingType, BfPopulateType_Declaration);
  298. bool result = ValidateGenericConstraints(typeRef, underlyingGenericType, ignoreErrors);
  299. if (underlyingGenericType->mGenericTypeInfo->mHadValidateErrors)
  300. genericTypeInst->mGenericTypeInfo->mHadValidateErrors = true;
  301. return result;
  302. }
  303. return true;
  304. }
  305. for (auto typeArg : genericTypeInst->mGenericTypeInfo->mTypeGenericArguments)
  306. {
  307. auto genericArg = typeArg->ToGenericTypeInstance();
  308. if (genericArg != NULL)
  309. genericTypeInst->mGenericTypeInfo->mMaxGenericDepth = BF_MAX(genericTypeInst->mGenericTypeInfo->mMaxGenericDepth, genericArg->mGenericTypeInfo->mMaxGenericDepth + 1);
  310. }
  311. auto typeDef = genericTypeInst->mTypeDef;
  312. int startGenericParamIdx = 0;
  313. if (typeDef->mOuterType != NULL)
  314. {
  315. startGenericParamIdx = typeDef->mOuterType->mGenericParamDefs.mSize + typeDef->mOuterType->mExternalConstraints.mSize;
  316. auto outerType = GetOuterType(genericTypeInst);
  317. PopulateType(outerType, BfPopulateType_Declaration);
  318. if ((outerType->mGenericTypeInfo != NULL) && (outerType->mGenericTypeInfo->mHadValidateErrors))
  319. genericTypeInst->mGenericTypeInfo->mHadValidateErrors = true;
  320. }
  321. for (int paramIdx = startGenericParamIdx; paramIdx < (int)genericTypeInst->mGenericTypeInfo->mGenericParams.size(); paramIdx++)
  322. {
  323. auto genericParamInstance = genericTypeInst->mGenericTypeInfo->mGenericParams[paramIdx];
  324. BfType* genericArg;
  325. if (paramIdx < (int)genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size())
  326. {
  327. genericArg = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[paramIdx];
  328. }
  329. else
  330. {
  331. genericArg = genericParamInstance->mExternType;
  332. }
  333. BfError* error = NULL;
  334. if ((genericArg == NULL) || (!CheckGenericConstraints(BfGenericParamSource(genericTypeInst), genericArg, typeRef, genericParamInstance, NULL, &error)))
  335. {
  336. if (!genericTypeInst->IsUnspecializedTypeVariation())
  337. genericTypeInst->mGenericTypeInfo->mHadValidateErrors = true;
  338. return false;
  339. }
  340. }
  341. return true;
  342. }
  343. BfType* BfModule::ResolveGenericMethodTypeRef(BfTypeReference* typeRef, BfMethodInstance* methodInstance, BfGenericParamInstance* genericParamInstance, BfTypeVector* methodGenericArgsOverride)
  344. {
  345. BfConstraintState constraintSet;
  346. constraintSet.mPrevState = mContext->mCurConstraintState;
  347. constraintSet.mGenericParamInstance = genericParamInstance;
  348. constraintSet.mMethodInstance = methodInstance;
  349. constraintSet.mMethodGenericArgsOverride = methodGenericArgsOverride;
  350. SetAndRestoreValue<BfConstraintState*> prevConstraintSet(mContext->mCurConstraintState, &constraintSet);
  351. if (!CheckConstraintState(NULL))
  352. return NULL;
  353. SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, methodInstance);
  354. SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, methodInstance->GetOwner());
  355. SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, true);
  356. BfType* type = ResolveTypeRef(typeRef);
  357. if (type == NULL)
  358. type = GetPrimitiveType(BfTypeCode_Var);
  359. return type;
  360. }
  361. bool BfModule::AreConstraintsSubset(BfGenericParamInstance* checkInner, BfGenericParamInstance* checkOuter)
  362. {
  363. if (checkOuter == NULL)
  364. return false;
  365. if (checkInner == NULL)
  366. return true;
  367. // Added new flags?
  368. if ((checkInner->mGenericParamFlags | checkOuter->mGenericParamFlags) != checkOuter->mGenericParamFlags)
  369. {
  370. // If the outer had a type flag and the inner has a specific type constraint, then see if those are compatible
  371. auto outerFlags = checkOuter->mGenericParamFlags;
  372. if ((outerFlags & BfGenericParamFlag_Enum) != 0)
  373. outerFlags = (BfGenericParamFlags)(outerFlags | BfGenericParamFlag_Struct);
  374. if (checkOuter->mTypeConstraint != NULL)
  375. {
  376. if (checkOuter->mTypeConstraint->IsStruct())
  377. outerFlags = (BfGenericParamFlags)(outerFlags | BfGenericParamFlag_Struct);
  378. else if (checkOuter->mTypeConstraint->IsStructOrStructPtr())
  379. outerFlags = (BfGenericParamFlags)(outerFlags | BfGenericParamFlag_StructPtr);
  380. else if (checkOuter->mTypeConstraint->IsObject())
  381. outerFlags = (BfGenericParamFlags)(outerFlags | BfGenericParamFlag_Class);
  382. else if (checkOuter->mTypeConstraint->IsEnum())
  383. outerFlags = (BfGenericParamFlags)(outerFlags | BfGenericParamFlag_Enum | BfGenericParamFlag_Struct);
  384. else if (checkOuter->mTypeConstraint->IsInterface())
  385. outerFlags = (BfGenericParamFlags)(outerFlags | BfGenericParamFlag_Interface);
  386. }
  387. auto innerFlags = checkInner->mGenericParamFlags;
  388. if ((innerFlags & BfGenericParamFlag_Enum) != 0)
  389. innerFlags = (BfGenericParamFlags)(innerFlags | BfGenericParamFlag_Struct);
  390. if (((innerFlags | outerFlags) & ~BfGenericParamFlag_Var) != (outerFlags & ~BfGenericParamFlag_Var))
  391. return false;
  392. }
  393. if (checkInner->mTypeConstraint != NULL)
  394. {
  395. if (checkOuter->mTypeConstraint == NULL)
  396. return false;
  397. if (!TypeIsSubTypeOf(checkOuter->mTypeConstraint->ToTypeInstance(), checkInner->mTypeConstraint->ToTypeInstance()))
  398. return false;
  399. }
  400. for (auto innerIFace : checkInner->mInterfaceConstraints)
  401. {
  402. if (checkOuter->mInterfaceConstraints.IsEmpty())
  403. return false;
  404. if (checkOuter->mInterfaceConstraintSet == NULL)
  405. {
  406. std::function<void(BfTypeInstance*)> _AddInterface = [&](BfTypeInstance* ifaceType)
  407. {
  408. if (!checkOuter->mInterfaceConstraintSet->Add(ifaceType))
  409. return;
  410. if (ifaceType->mDefineState < BfTypeDefineState_HasInterfaces)
  411. PopulateType(ifaceType);
  412. for (auto& ifaceEntry : ifaceType->mInterfaces)
  413. _AddInterface(ifaceEntry.mInterfaceType);
  414. };
  415. checkOuter->mInterfaceConstraintSet = new HashSet<BfTypeInstance*>();
  416. for (auto outerIFace : checkOuter->mInterfaceConstraints)
  417. _AddInterface(outerIFace);
  418. }
  419. if (!checkOuter->mInterfaceConstraintSet->Contains(innerIFace))
  420. return false;
  421. }
  422. for (auto& innerOp : checkInner->mOperatorConstraints)
  423. {
  424. if (!checkOuter->mOperatorConstraints.Contains(innerOp))
  425. return false;
  426. }
  427. return true;
  428. }
  429. bool BfModule::CheckConstraintState(BfAstNode* refNode)
  430. {
  431. if (mContext->mCurConstraintState == NULL)
  432. return true;
  433. auto checkState = mContext->mCurConstraintState->mPrevState;
  434. while (checkState != NULL)
  435. {
  436. if (*checkState == *mContext->mCurConstraintState)
  437. {
  438. if (refNode != NULL)
  439. {
  440. Fail("Constraints cause circular operator invocations", refNode);
  441. }
  442. return false;
  443. }
  444. checkState = checkState->mPrevState;
  445. }
  446. return true;
  447. }
  448. bool BfModule::ShouldAllowMultipleDefinitions(BfTypeInstance* typeInst, BfTypeDef* firstDeclaringTypeDef, BfTypeDef* secondDeclaringTypeDef)
  449. {
  450. if (firstDeclaringTypeDef == secondDeclaringTypeDef)
  451. return false;
  452. // Since we will use shared debugging info, we won't be able to differentiate between these two fields.
  453. // If we created per-target debug info then we could "fix" this.
  454. // Can these projects even see each other?
  455. if ((!firstDeclaringTypeDef->mProject->ContainsReference(secondDeclaringTypeDef->mProject)) &&
  456. (!secondDeclaringTypeDef->mProject->ContainsReference(firstDeclaringTypeDef->mProject)))
  457. return true;
  458. if (typeInst->IsUnspecializedType())
  459. {
  460. bool alwaysCoincide = true;
  461. auto genericTypeInst = (BfTypeInstance*)typeInst;
  462. if (genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo != NULL)
  463. {
  464. auto firstConstraints = genericTypeInst->GetGenericParamsVector(firstDeclaringTypeDef);
  465. auto secondConstraints = genericTypeInst->GetGenericParamsVector(secondDeclaringTypeDef);
  466. for (int genericIdx = 0; genericIdx < (int)firstConstraints->size(); genericIdx++)
  467. {
  468. auto firstConstraint = (*firstConstraints)[genericIdx];
  469. auto secondConstraint = (*secondConstraints)[genericIdx];
  470. if ((!AreConstraintsSubset(firstConstraint, secondConstraint)) &&
  471. (!AreConstraintsSubset(secondConstraint, firstConstraint)))
  472. alwaysCoincide = false;
  473. }
  474. }
  475. // Only show an error if we are certain both members will always appear at the same time
  476. if (!alwaysCoincide)
  477. return true;
  478. }
  479. return false;
  480. }
  481. void BfModule::CheckInjectNewRevision(BfTypeInstance* typeInstance)
  482. {
  483. if ((typeInstance != NULL) && (typeInstance->mTypeDef != NULL))
  484. {
  485. auto typeDef = typeInstance->mTypeDef;
  486. if (typeDef->mEmitParent != NULL)
  487. typeDef = typeDef->mEmitParent;
  488. if (typeDef->mNextRevision != NULL)
  489. {
  490. // It's possible that our main compiler thread is generating a new typedef while we're autocompleting. This handles that case...
  491. if (typeInstance->mDefineState == BfTypeDefineState_Undefined)
  492. {
  493. if (typeInstance->IsBoxed())
  494. {
  495. BfBoxedType* boxedType = (BfBoxedType*)typeInstance;
  496. BfTypeInstance* innerType = boxedType->mElementType->ToTypeInstance();
  497. PopulateType(innerType, BfPopulateType_Data);
  498. }
  499. else
  500. {
  501. mContext->HandleChangedTypeDef(typeDef);
  502. mSystem->InjectNewRevision(typeDef);
  503. }
  504. }
  505. else
  506. {
  507. BF_ASSERT(mCompiler->IsAutocomplete());
  508. }
  509. }
  510. if ((!typeInstance->IsDeleting()) && (!mCompiler->IsAutocomplete()))
  511. BF_ASSERT((typeDef->mDefState == BfTypeDef::DefState_Defined) || (typeDef->mDefState == BfTypeDef::DefState_New));
  512. if ((typeInstance->mTypeDef->mDefState == BfTypeDef::DefState_EmittedDirty) && (typeInstance->mTypeDef->mEmitParent->mNextRevision == NULL))
  513. mSystem->UpdateEmittedTypeDef(typeInstance->mTypeDef);
  514. }
  515. }
  516. void BfModule::InitType(BfType* resolvedTypeRef, BfPopulateType populateType)
  517. {
  518. BP_ZONE("BfModule::InitType");
  519. if (auto depType = resolvedTypeRef->ToDependedType())
  520. {
  521. if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mMethodInfoEx != NULL))
  522. {
  523. depType->mDependencyMap.mMinDependDepth = mCurMethodInstance->mMethodInfoEx->mMinDependDepth + 1;
  524. }
  525. else if (mCurTypeInstance != NULL)
  526. {
  527. depType->mDependencyMap.mMinDependDepth = mCurTypeInstance->mDependencyMap.mMinDependDepth + 1;
  528. }
  529. }
  530. SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, resolvedTypeRef->ToTypeInstance());
  531. SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, NULL);
  532. if (mCompiler->mHotState != NULL)
  533. mCompiler->mHotState->mHasNewTypes = true;
  534. auto typeInst = resolvedTypeRef->ToTypeInstance();
  535. if (typeInst != NULL)
  536. {
  537. CheckInjectNewRevision(typeInst);
  538. BF_ASSERT(!typeInst->mTypeDef->IsEmitted());
  539. if (typeInst->mBaseType != NULL)
  540. BF_ASSERT((typeInst->mBaseType->mRebuildFlags & BfTypeRebuildFlag_Deleted) == 0);
  541. if ((typeInst->mTypeDef != NULL) && (typeInst->mTypeDef->mDefState == BfTypeDef::DefState_New) &&
  542. (typeInst->mTypeDef->mNextRevision == NULL))
  543. {
  544. mContext->HandleChangedTypeDef(typeInst->mTypeDef);
  545. typeInst->mTypeDef->mDefState = BfTypeDef::DefState_Defined;
  546. }
  547. typeInst->mIsReified = mIsReified;
  548. //BF_ASSERT(typeInst->mTypeDef->mTypeCode != BfTypeCode_Extension);
  549. typeInst->mRevision = mCompiler->mRevision;
  550. if (typeInst->mTypeDef != NULL)
  551. BF_ASSERT(typeInst->mTypeDef->mDefState != BfTypeDef::DefState_Deleted);
  552. if (resolvedTypeRef->IsTuple())
  553. {
  554. auto tupleType = (BfTypeInstance*)resolvedTypeRef;
  555. for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
  556. {
  557. auto fieldInstance = (BfFieldInstance*)&tupleType->mFieldInstances[fieldIdx];
  558. // We need to make sure dependencies get set immediately since we already resolved the types
  559. AddFieldDependency(typeInst, fieldInstance, fieldInstance->mResolvedType);
  560. }
  561. }
  562. }
  563. if (resolvedTypeRef->IsGenericTypeInstance())
  564. {
  565. auto genericTypeInst = (BfTypeInstance*)resolvedTypeRef;
  566. for (auto typeGenericArg : genericTypeInst->mGenericTypeInfo->mTypeGenericArguments)
  567. {
  568. BF_ASSERT((typeGenericArg->mRebuildFlags & BfTypeRebuildFlag_Deleted) == 0);
  569. if (mIsReified)
  570. {
  571. // Try to reify any generic args
  572. for (auto genericArg : typeInst->mGenericTypeInfo->mTypeGenericArguments)
  573. {
  574. if (!genericArg->IsReified())
  575. PopulateType(genericArg, BfPopulateType_Declaration);
  576. }
  577. }
  578. BF_ASSERT(!typeGenericArg->IsIntUnknown());
  579. }
  580. }
  581. if (!mContext->mSavedTypeDataMap.IsEmpty())
  582. {
  583. String typeName = BfSafeMangler::Mangle(resolvedTypeRef, this);
  584. BfSavedTypeData* savedTypeData;
  585. if (mContext->mSavedTypeDataMap.Remove(typeName, &savedTypeData))
  586. {
  587. mContext->mSavedTypeData[savedTypeData->mTypeId] = NULL;
  588. resolvedTypeRef->mTypeId = savedTypeData->mTypeId;
  589. BfLogSysM("Using mSavedTypeData for %p %s\n", resolvedTypeRef, typeName.c_str());
  590. if (typeInst != NULL)
  591. {
  592. if (IsHotCompile())
  593. {
  594. BfLogSysM("Using mSavedTypeData HotTypeData %p for %p\n", savedTypeData->mHotTypeData, resolvedTypeRef);
  595. typeInst->mHotTypeData = savedTypeData->mHotTypeData;
  596. savedTypeData->mHotTypeData = NULL;
  597. }
  598. }
  599. delete savedTypeData;
  600. mContext->mTypes[resolvedTypeRef->mTypeId] = resolvedTypeRef;
  601. }
  602. else
  603. {
  604. BfLogSysM("No mSavedTypeData entry for %p %s\n", resolvedTypeRef, typeName.c_str());
  605. }
  606. }
  607. resolvedTypeRef->mContext = mContext;
  608. if (resolvedTypeRef->IsGenericTypeInstance())
  609. {
  610. auto genericTypeInstance = (BfTypeInstance*)resolvedTypeRef;
  611. #ifdef _DEBUG
  612. for (auto genericArg : genericTypeInstance->mGenericTypeInfo->mTypeGenericArguments)
  613. BF_ASSERT(!genericArg->IsVar());
  614. #endif
  615. // Do it here so the location we attempted to specialize this type will throw the failure if there is one
  616. if (!InitGenericParams(resolvedTypeRef))
  617. return;
  618. }
  619. BfLogSysM("%p InitType: %s Type: %p TypeDef: %p Revision:%d\n", mContext, TypeToString(resolvedTypeRef).c_str(), resolvedTypeRef, (typeInst != NULL) ? typeInst->mTypeDef : NULL, mCompiler->mRevision);
  620. // When we're autocomplete, we can't do the method processing so we have to add this type to the type work list
  621. if (((populateType < BfPopulateType_Full) || (mCompiler->IsAutocomplete())) /*&& (!resolvedTypeRef->IsUnspecializedTypeVariation())*/ && (resolvedTypeRef->IsTypeInstance()) &&
  622. (!resolvedTypeRef->IsTypeAlias()))
  623. {
  624. BfTypeProcessRequest* typeProcessRequest = mContext->mPopulateTypeWorkList.Alloc();
  625. typeProcessRequest->mType = resolvedTypeRef;
  626. BF_ASSERT(resolvedTypeRef->mContext == mContext);
  627. mCompiler->mStats.mTypesQueued++;
  628. mCompiler->UpdateCompletion();
  629. }
  630. PopulateType(resolvedTypeRef, populateType);
  631. }
  632. void BfModule::AddFieldDependency(BfTypeInstance* typeInstance, BfFieldInstance* fieldInstance, BfType* fieldType)
  633. {
  634. auto depFlag = fieldType->IsValueType() ? BfDependencyMap::DependencyFlag_ValueTypeMemberData : BfDependencyMap::DependencyFlag_PtrMemberData;
  635. AddDependency(fieldType, typeInstance, depFlag);
  636. if ((fieldType->IsStruct()) && (fieldType->IsGenericTypeInstance()))
  637. {
  638. // When we're a generic struct, our data layout can depend on our generic parameters as well
  639. auto genericTypeInstance = (BfTypeInstance*)fieldType;
  640. for (auto typeGenericArg : genericTypeInstance->mGenericTypeInfo->mTypeGenericArguments)
  641. AddFieldDependency(typeInstance, fieldInstance, typeGenericArg);
  642. }
  643. }
  644. BfFieldInstance* BfModule::GetFieldByName(BfTypeInstance* typeInstance, const StringImpl& fieldName, bool isRequired, BfAstNode* refNode)
  645. {
  646. PopulateType(typeInstance);
  647. typeInstance->mTypeDef->PopulateMemberSets();
  648. BfMemberSetEntry* entry = NULL;
  649. BfFieldDef* fieldDef = NULL;
  650. if (typeInstance->mTypeDef->mFieldSet.TryGetWith(fieldName, &entry))
  651. {
  652. fieldDef = (BfFieldDef*)entry->mMemberDef;
  653. return &typeInstance->mFieldInstances[fieldDef->mIdx];
  654. }
  655. if (isRequired)
  656. {
  657. FailInternal(StrFormat("Field '%s' not found in '%s'", fieldName.c_str(), TypeToString(typeInstance).c_str()), refNode);
  658. }
  659. return NULL;
  660. }
  661. void BfModule::CheckMemberNames(BfTypeInstance* typeInst)
  662. {
  663. struct MemberRef
  664. {
  665. BfMemberDef* mMemberDef;
  666. String mName;
  667. String mKindName;
  668. BfTypeInstance* mTypeInst;
  669. BfAstNode* mNameNode;
  670. BfProtection mProtection;
  671. BfTypeDef* mDeclaringType;
  672. bool mIsOverride;
  673. };
  674. SizedArray<MemberRef, 64> memberList;
  675. // Check base types first and then current type
  676. auto checkType = typeInst;
  677. while (checkType != NULL)
  678. {
  679. for (auto prop : checkType->mTypeDef->mProperties)
  680. {
  681. BfPropertyDeclaration* propDecl = (BfPropertyDeclaration*)prop->mFieldDeclaration;
  682. if ((propDecl != NULL) && (propDecl->mExplicitInterface != NULL))
  683. continue;
  684. if (!typeInst->IsTypeMemberIncluded(prop->mDeclaringType))
  685. continue;
  686. MemberRef memberRef = { 0 };
  687. memberRef.mMemberDef = prop;
  688. memberRef.mTypeInst = checkType;
  689. memberRef.mProtection = prop->mProtection;
  690. memberRef.mName = prop->mName;
  691. memberRef.mKindName = "property";
  692. if (prop->mFieldDeclaration != NULL)
  693. memberRef.mNameNode = prop->mFieldDeclaration->mNameNode;
  694. memberRef.mDeclaringType = prop->mDeclaringType;
  695. auto propertyDeclaration = BfNodeDynCast<BfPropertyDeclaration>(prop->mFieldDeclaration);
  696. if (propertyDeclaration != NULL)
  697. memberRef.mIsOverride = (propertyDeclaration->mNewSpecifier != NULL) ||
  698. ((propertyDeclaration->mVirtualSpecifier != NULL) && (propertyDeclaration->mVirtualSpecifier->GetToken() == BfToken_Override));
  699. memberList.push_back(memberRef);
  700. }
  701. for (auto field : checkType->mTypeDef->mFields)
  702. {
  703. if (!typeInst->IsTypeMemberIncluded(field->mDeclaringType))
  704. continue;
  705. MemberRef memberRef = { 0 };
  706. memberRef.mMemberDef = field;
  707. memberRef.mTypeInst = checkType;
  708. memberRef.mProtection = field->mProtection;
  709. memberRef.mName = field->mName;
  710. memberRef.mKindName = "field";
  711. memberRef.mDeclaringType = field->mDeclaringType;
  712. if (field->mFieldDeclaration != NULL)
  713. {
  714. memberRef.mNameNode = field->mFieldDeclaration->mNameNode;
  715. memberRef.mIsOverride = field->mFieldDeclaration->mNewSpecifier != NULL;
  716. }
  717. memberList.push_back(memberRef);
  718. }
  719. checkType = checkType->mBaseType;
  720. }
  721. Dictionary<String, MemberRef> memberMap;
  722. memberMap.Reserve(memberList.size());
  723. for (int i = (int)memberList.size() - 1; i >= 0; i--)
  724. {
  725. MemberRef& memberRef = memberList[i];
  726. if (memberRef.mName.empty())
  727. continue;
  728. if ((memberRef.mTypeInst == typeInst) && (!memberRef.mIsOverride))
  729. {
  730. MemberRef* prevMemberRef = NULL;
  731. if (memberMap.TryGetValue(memberRef.mName, &prevMemberRef))
  732. {
  733. //auto& prevMemberRef = itr->second;
  734. MemberRef* firstMemberRef = &memberRef;
  735. MemberRef* secondMemberRef = prevMemberRef;
  736. bool showPrevious = false;
  737. BfError* error = NULL;
  738. if (prevMemberRef->mTypeInst != typeInst)
  739. {
  740. if ((prevMemberRef->mProtection != BfProtection_Private) && (memberRef.mNameNode != NULL))
  741. {
  742. error = Warn(BfWarning_CS0108_MemberHidesInherited, StrFormat("%s hides inherited member '%s'. Use the 'new' keyword if hiding was intentional.", prevMemberRef->mKindName.c_str(), memberRef.mName.c_str()), memberRef.mNameNode, true);
  743. showPrevious = true;
  744. }
  745. }
  746. else
  747. {
  748. if (ShouldAllowMultipleDefinitions(typeInst, firstMemberRef->mDeclaringType, secondMemberRef->mDeclaringType))
  749. {
  750. if (firstMemberRef->mMemberDef != NULL)
  751. {
  752. firstMemberRef->mMemberDef->mHasMultiDefs = true;
  753. secondMemberRef->mMemberDef->mHasMultiDefs = true;
  754. }
  755. continue;
  756. }
  757. bool wantsSwap = false;
  758. if ((secondMemberRef->mNameNode != NULL) && (firstMemberRef->mNameNode != NULL) &&
  759. (secondMemberRef->mNameNode->GetSourceData() == firstMemberRef->mNameNode->GetSourceData()) &&
  760. (secondMemberRef->mNameNode->GetSrcStart() < firstMemberRef->mNameNode->GetSrcStart()))
  761. {
  762. wantsSwap = true;
  763. }
  764. if (secondMemberRef->mDeclaringType->IsExtension() != firstMemberRef->mDeclaringType->IsExtension())
  765. {
  766. wantsSwap = firstMemberRef->mDeclaringType->IsExtension();
  767. }
  768. if (wantsSwap)
  769. {
  770. std::swap(firstMemberRef, secondMemberRef);
  771. }
  772. if (typeInst->mTypeDef->mIsCombinedPartial)
  773. {
  774. if ((firstMemberRef->mKindName == "property") && (secondMemberRef->mKindName == "property"))
  775. {
  776. auto firstPropertyDef = (BfPropertyDef*)firstMemberRef->mMemberDef;
  777. auto secondPropertyDef = (BfPropertyDef*)secondMemberRef->mMemberDef;
  778. if (auto secondPropertyDeclaration = BfNodeDynCast<BfPropertyDeclaration>(secondPropertyDef->mFieldDeclaration))
  779. {
  780. if ((secondPropertyDeclaration->mVirtualSpecifier != NULL) && (secondPropertyDeclaration->mVirtualSpecifier->mToken == BfToken_Override))
  781. continue;
  782. }
  783. }
  784. }
  785. if (secondMemberRef->mNameNode != NULL)
  786. error = Fail(StrFormat("A %s named '%s' has already been declared.", secondMemberRef->mKindName.c_str(), memberRef.mName.c_str()), secondMemberRef->mNameNode, true);
  787. showPrevious = true;
  788. typeInst->mHasDeclError = true;
  789. }
  790. if ((secondMemberRef->mNameNode != NULL) && (error != NULL))
  791. mCompiler->mPassInstance->MoreInfo("Previous declaration", firstMemberRef->mNameNode);
  792. }
  793. }
  794. memberMap.TryAdd(memberRef.mName, memberRef);
  795. }
  796. }
  797. void BfModule::TypeFailed(BfTypeInstance* typeInstance)
  798. {
  799. BfLogSysM("TypeFailed: %p\n", typeInstance);
  800. typeInstance->mTypeFailed = true;
  801. // Punt on field types - just substitute 'var' where we have NULLs
  802. for (auto& fieldInstance : typeInstance->mFieldInstances)
  803. {
  804. if ((fieldInstance.mResolvedType == NULL) || (fieldInstance.mResolvedType->IsNull()))
  805. {
  806. if (fieldInstance.mDataIdx >= 0)
  807. fieldInstance.mResolvedType = GetPrimitiveType(BfTypeCode_Var);
  808. }
  809. if (fieldInstance.mOwner == NULL)
  810. fieldInstance.mOwner = typeInstance;
  811. }
  812. if (typeInstance->mAlign == -1)
  813. typeInstance->mAlign = 1;
  814. if (typeInstance->mSize == -1)
  815. typeInstance->mSize = 1;
  816. mContext->mFailTypes.Add(typeInstance);
  817. mHadBuildError = true;
  818. }
  819. bool BfModule::CheckCircularDataError()
  820. {
  821. // Find two loops of mCurTypeInstance. Just finding one loop can give some false errors.
  822. BfTypeState* circularTypeStateEnd = NULL;
  823. int checkIdx = 0;
  824. auto checkTypeState = mContext->mCurTypeState;
  825. bool isPreBaseCheck = checkTypeState->mPopulateType == BfPopulateType_Declaration;
  826. while (true)
  827. {
  828. if (checkTypeState == NULL)
  829. return false;
  830. if (checkTypeState->mResolveKind == BfTypeState::ResolveKind_UnionInnerType)
  831. {
  832. checkTypeState = checkTypeState->mPrevState;
  833. continue;
  834. }
  835. if (isPreBaseCheck)
  836. {
  837. if (checkTypeState->mPopulateType != BfPopulateType_Declaration)
  838. return false;
  839. }
  840. else
  841. {
  842. if (checkTypeState->mPopulateType == BfPopulateType_Declaration)
  843. return false;
  844. if ((checkIdx > 0) && (checkTypeState->mCurBaseTypeRef == NULL) && (checkTypeState->mCurAttributeTypeRef == NULL) && (checkTypeState->mCurFieldDef == NULL) &&
  845. ((checkTypeState->mType == NULL) || (checkTypeState->mType->IsTypeInstance())))
  846. return false;
  847. }
  848. if ((checkTypeState->mType == mCurTypeInstance) && (checkIdx > 1))
  849. {
  850. if (circularTypeStateEnd == NULL)
  851. circularTypeStateEnd = checkTypeState;
  852. else
  853. break;
  854. }
  855. checkTypeState = checkTypeState->mPrevState;
  856. checkIdx++;
  857. }
  858. bool hadError = false;
  859. checkTypeState = mContext->mCurTypeState->mPrevState;
  860. while (true)
  861. {
  862. if (checkTypeState == NULL)
  863. return hadError;
  864. if (checkTypeState == circularTypeStateEnd)
  865. return hadError;
  866. if (checkTypeState->mResolveKind == BfTypeState::ResolveKind_UnionInnerType)
  867. {
  868. // Skip over this to actual data references
  869. checkTypeState = checkTypeState->mPrevState;
  870. continue;
  871. }
  872. if ((checkTypeState->mCurAttributeTypeRef == NULL) && (checkTypeState->mCurBaseTypeRef == NULL) && (checkTypeState->mCurFieldDef == NULL) &&
  873. ((checkTypeState->mType == NULL) || (checkTypeState->mType->IsTypeInstance())))
  874. return hadError;
  875. // We only get one chance to fire off these errors, they can't be ignored.
  876. SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, false);
  877. hadError = true;
  878. if (checkTypeState->mCurAttributeTypeRef != NULL)
  879. {
  880. Fail(StrFormat("Attribute type '%s' causes a data cycle", BfTypeUtils::TypeToString(checkTypeState->mCurAttributeTypeRef).c_str()), checkTypeState->mCurAttributeTypeRef, true);
  881. }
  882. else if (checkTypeState->mCurBaseTypeRef != NULL)
  883. {
  884. Fail(StrFormat("Base type '%s' causes a data cycle", BfTypeUtils::TypeToString(checkTypeState->mCurBaseTypeRef).c_str()), checkTypeState->mCurBaseTypeRef, true);
  885. }
  886. else if ((checkTypeState->mCurFieldDef != NULL) && (checkTypeState->mCurFieldDef->mFieldDeclaration != NULL))
  887. {
  888. Fail(StrFormat("Field '%s.%s' causes a data cycle", TypeToString(checkTypeState->mType).c_str(), checkTypeState->mCurFieldDef->mName.c_str()),
  889. checkTypeState->mCurFieldDef->mFieldDeclaration->mTypeRef, true);
  890. }
  891. else if (checkTypeState->mCurFieldDef != NULL)
  892. {
  893. Fail(StrFormat("Field '%s.%s' causes a data cycle", TypeToString(checkTypeState->mType).c_str(), checkTypeState->mCurFieldDef->mName.c_str()));
  894. }
  895. else
  896. {
  897. Fail(StrFormat("Type '%s' causes a data cycle", TypeToString(checkTypeState->mType).c_str()));
  898. }
  899. auto typeInstance = checkTypeState->mType->ToTypeInstance();
  900. auto module = GetModuleFor(checkTypeState->mType);
  901. if (module != NULL)
  902. module->TypeFailed(typeInstance);
  903. else if (typeInstance != NULL)
  904. typeInstance->mTypeFailed = true;
  905. checkTypeState = checkTypeState->mPrevState;
  906. }
  907. }
  908. void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType)
  909. {
  910. if ((populateType == BfPopulateType_Declaration) && (resolvedTypeRef->mDefineState >= BfTypeDefineState_Declared))
  911. return;
  912. // Are we "demanding" to reify a type that is currently resolve-only?
  913. if ((mIsReified) && (populateType >= BfPopulateType_Declaration))
  914. {
  915. if (resolvedTypeRef->IsTypeInstance())
  916. {
  917. auto typeModule = resolvedTypeRef->GetModule();
  918. if ((typeModule != NULL) && (typeModule->mIsSpecialModule))
  919. {
  920. auto typeInst = resolvedTypeRef->ToTypeInstance();
  921. if (!typeInst->mIsReified)
  922. {
  923. BfLogSysM("Reifying type %p in scratch module in PopulateType\n", resolvedTypeRef);
  924. // It's important for unspecialized types to be in the correct module --
  925. // when we process their methods, new types will be determined as
  926. // resolve-only or reified based on the module the unresolved type is in
  927. BF_ASSERT(typeInst->mModule == mContext->mUnreifiedModule);
  928. typeInst->mIsReified = true;
  929. typeInst->mModule = mContext->mScratchModule;
  930. // Why did we need to do this at all? Why is just marking the type as reified not enough?
  931. // This causes issues where we may delete a method instance that is currently being used as the generic bindings for
  932. // a method of a specialized generic type
  933. // if (typeInst->IsOnDemand())
  934. // {
  935. // RebuildMethods(typeInst);
  936. // }
  937. // else
  938. // mContext->RebuildType(typeInst, false, false);
  939. if (typeInst->mGenericTypeInfo != NULL)
  940. {
  941. for (auto genericArg : typeInst->mGenericTypeInfo->mTypeGenericArguments)
  942. {
  943. if (!genericArg->IsReified())
  944. PopulateType(genericArg, BfPopulateType_Declaration);
  945. }
  946. }
  947. }
  948. }
  949. else
  950. {
  951. if ((typeModule != NULL) && (!typeModule->mIsReified) && (!typeModule->mReifyQueued))
  952. {
  953. bool canFastReify = false;
  954. if (typeModule->mAwaitingInitFinish)
  955. {
  956. canFastReify = true;
  957. for (auto ownedTypes : typeModule->mOwnedTypeInstances)
  958. if (ownedTypes->mDefineState > BfTypeDefineState_HasInterfaces)
  959. canFastReify = false;
  960. }
  961. if (canFastReify)
  962. {
  963. BfLogSysM("Setting reified type %p in module %p in PopulateType on module awaiting finish\n", resolvedTypeRef, typeModule);
  964. typeModule->mIsReified = true;
  965. typeModule->CalcGeneratesCode();
  966. typeModule->mWantsIRIgnoreWrites = false;
  967. for (auto ownedTypes : typeModule->mOwnedTypeInstances)
  968. {
  969. ownedTypes->mIsReified = true;
  970. if (ownedTypes->mCustomAttributes != NULL)
  971. {
  972. for (auto& attr : ownedTypes->mCustomAttributes->mAttributes)
  973. {
  974. if ((attr.mType->mAttributeData != NULL) && ((attr.mType->mAttributeData->mFlags & BfCustomAttributeFlags_ReflectAttribute) != 0))
  975. {
  976. // Reify this attribute
  977. typeModule->PopulateType(attr.mType);
  978. }
  979. }
  980. }
  981. }
  982. mCompiler->mStats.mReifiedModuleCount++;
  983. if (typeModule->mBfIRBuilder != NULL)
  984. {
  985. typeModule->mBfIRBuilder->ClearNonConstData();
  986. typeModule->mBfIRBuilder->mIgnoreWrites = false;
  987. typeModule->SetupIRBuilder(false);
  988. }
  989. else
  990. typeModule->PrepareForIRWriting(resolvedTypeRef->ToTypeInstance());
  991. }
  992. else
  993. {
  994. BF_ASSERT((mCompiler->mCompileState != BfCompiler::CompileState_Unreified) && (mCompiler->mCompileState != BfCompiler::CompileState_VData));
  995. BfLogSysM("Queued reification of type %p in module %p in PopulateType\n", resolvedTypeRef, typeModule);
  996. BF_ASSERT((typeModule != mContext->mUnreifiedModule) && (typeModule != mContext->mScratchModule));
  997. BF_ASSERT(!typeModule->mIsSpecialModule);
  998. // This caused issues - we may need to reify a type and then request a method
  999. typeModule->mReifyQueued = true;
  1000. mContext->mReifyModuleWorkList.Add(typeModule);
  1001. //typeModule->ReifyModule();
  1002. }
  1003. }
  1004. }
  1005. }
  1006. }
  1007. if (!resolvedTypeRef->IsIncomplete())
  1008. return;
  1009. if (populateType <= BfPopulateType_TypeDef)
  1010. return;
  1011. auto typeInstance = resolvedTypeRef->ToTypeInstance();
  1012. CheckInjectNewRevision(typeInstance);
  1013. BF_ASSERT((resolvedTypeRef->mRebuildFlags & (BfTypeRebuildFlag_Deleted | BfTypeRebuildFlag_DeleteQueued)) == 0);
  1014. /*BfTypeRebuildFlags allowedFlags = (BfTypeRebuildFlags)(BfTypeRebuildFlag_AddedToWorkList | BfTypeRebuildFlag_AwaitingReference | BfTypeRebuildFlag_UnderlyingTypeDeferred);
  1015. if ((resolvedTypeRef->mRebuildFlags & ~allowedFlags) != 0)
  1016. {
  1017. // BfContext::UpdateAfterDeletingTypes should clear out all flags except for the Deleted flag
  1018. // If this type was deleted then we should never be able to reach PopulateType here.
  1019. // This may happen if dependent types were not properly rebuilt when a used type
  1020. // was deleted.
  1021. auto hadFlags = resolvedTypeRef->mRebuildFlags;
  1022. BF_ASSERT((resolvedTypeRef->mRebuildFlags & ~allowedFlags) == 0);
  1023. resolvedTypeRef->mRebuildFlags = (BfTypeRebuildFlags)(resolvedTypeRef->mRebuildFlags & ~allowedFlags);
  1024. }*/
  1025. bool isNew = resolvedTypeRef->mDefineState == BfTypeDefineState_Undefined;
  1026. if (isNew)
  1027. {
  1028. BP_ZONE("BfModule::PopulateType");
  1029. if (resolvedTypeRef->mTypeId == -1)
  1030. {
  1031. mCompiler->mTypeInitCount++;
  1032. auto typeInstance = resolvedTypeRef->ToTypeInstance();
  1033. if (!mCompiler->mTypeIdFreeList.IsEmpty())
  1034. {
  1035. resolvedTypeRef->mTypeId = mCompiler->mTypeIdFreeList.back();
  1036. mCompiler->mTypeIdFreeList.pop_back();
  1037. }
  1038. else
  1039. resolvedTypeRef->mTypeId = mCompiler->mCurTypeId++;
  1040. while (resolvedTypeRef->mTypeId >= (int)mContext->mTypes.size())
  1041. mContext->mTypes.Add(NULL);
  1042. mContext->mTypes[resolvedTypeRef->mTypeId] = resolvedTypeRef;
  1043. if (typeInstance != NULL)
  1044. {
  1045. typeInstance->mSignatureRevision = mCompiler->mRevision;
  1046. typeInstance->mLastNonGenericUsedRevision = mCompiler->mRevision;
  1047. }
  1048. }
  1049. BfTypeDef* typeDef = NULL;
  1050. if (typeInstance != NULL)
  1051. typeDef = typeInstance->mTypeDef;
  1052. BfLogSysM("PopulateType: %p %s populateType:%d ResolveOnly:%d Reified:%d AutoComplete:%d Ctx:%p Mod:%p TypeId:%d TypeDef:%p\n", resolvedTypeRef, TypeToString(resolvedTypeRef, BfTypeNameFlags_None).c_str(), populateType, mCompiler->mIsResolveOnly, mIsReified, mCompiler->IsAutocomplete(), mContext, this, resolvedTypeRef->mTypeId, typeDef);
  1053. BF_ASSERT(!resolvedTypeRef->IsDeleting());
  1054. }
  1055. if (resolvedTypeRef->IsRef())
  1056. {
  1057. BfRefType* refType = (BfRefType*)resolvedTypeRef;
  1058. if (refType->mElementType->IsValueType())
  1059. {
  1060. PopulateType(refType->mElementType, populateType);
  1061. resolvedTypeRef->mDefineState = refType->mElementType->mDefineState;
  1062. }
  1063. else
  1064. {
  1065. PopulateType(refType->mElementType, BfPopulateType_Identity);
  1066. resolvedTypeRef->mDefineState = BfTypeDefineState_Defined;
  1067. }
  1068. refType->mSize = refType->mAlign = mSystem->mPtrSize;
  1069. return;
  1070. }
  1071. if (resolvedTypeRef->IsTypeAlias())
  1072. {
  1073. // Always populate these all the way
  1074. if (populateType != BfPopulateType_IdentityNoRemapAlias)
  1075. populateType = BfPopulateType_Data;
  1076. }
  1077. if (resolvedTypeRef->IsSizedArray())
  1078. {
  1079. resolvedTypeRef->mRevision = mRevision;
  1080. bool typeFailed = false;
  1081. BfSizedArrayType* arrayType = (BfSizedArrayType*)resolvedTypeRef;
  1082. auto elementType = arrayType->mElementType;
  1083. if (elementType->IsValueType())
  1084. {
  1085. resolvedTypeRef->mDefineState = BfTypeDefineState_ResolvingBaseType;
  1086. BfTypeState typeState(arrayType, mContext->mCurTypeState);
  1087. typeState.mPopulateType = BfPopulateType_Data;
  1088. SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
  1089. SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, NULL);
  1090. if (!CheckCircularDataError())
  1091. {
  1092. PopulateType(arrayType->mElementType, BfPopulateType_Data);
  1093. }
  1094. else
  1095. {
  1096. typeFailed = true;
  1097. PopulateType(arrayType->mElementType, BfPopulateType_Identity);
  1098. }
  1099. resolvedTypeRef->mDefineState = arrayType->mElementType->mDefineState;
  1100. AddDependency(elementType, resolvedTypeRef, BfDependencyMap::DependencyFlag_ValueTypeMemberData);
  1101. }
  1102. else
  1103. {
  1104. PopulateType(arrayType->mElementType, BfPopulateType_Identity);
  1105. resolvedTypeRef->mDefineState = BfTypeDefineState_Defined;
  1106. AddDependency(elementType, resolvedTypeRef, BfDependencyMap::DependencyFlag_PtrMemberData);
  1107. }
  1108. if (arrayType->mElementCount > 0)
  1109. {
  1110. arrayType->mSize = (int)(arrayType->mElementType->GetStride() * arrayType->mElementCount);
  1111. if (arrayType->mElementType->mSize > 0)
  1112. {
  1113. int64 maxElements = 0x7FFFFFFF / arrayType->mElementType->GetStride();
  1114. if (arrayType->mElementCount > maxElements)
  1115. {
  1116. Fail(StrFormat("Array size overflow: %s", TypeToString(arrayType).c_str()));
  1117. arrayType->mSize = 0x7FFFFFFF;
  1118. }
  1119. }
  1120. arrayType->mAlign = std::max((int32)arrayType->mElementType->mAlign, 1);
  1121. }
  1122. else if (arrayType->mElementCount < 0)
  1123. {
  1124. // Unknown size, don't assume it's valueless
  1125. arrayType->mSize = 1;
  1126. arrayType->mAlign = 1;
  1127. }
  1128. else
  1129. {
  1130. arrayType->mSize = 0;
  1131. arrayType->mAlign = 1;
  1132. }
  1133. BF_ASSERT(arrayType->mSize >= 0);
  1134. if (!typeFailed)
  1135. arrayType->mWantsGCMarking = elementType->WantsGCMarking();
  1136. resolvedTypeRef->mDefineState = BfTypeDefineState_DefinedAndMethodsSlotted;
  1137. resolvedTypeRef->mRebuildFlags = BfTypeRebuildFlag_None;
  1138. bool isValueless = arrayType->IsValuelessType();
  1139. return;
  1140. }
  1141. if (isNew)
  1142. {
  1143. BfTypeDef* typeDef = NULL;
  1144. if (typeInstance != NULL)
  1145. {
  1146. if ((populateType == BfPopulateType_Data) && (typeInstance->mNeedsMethodProcessing))
  1147. return;
  1148. typeDef = typeInstance->mTypeDef;
  1149. }
  1150. if (resolvedTypeRef->IsMethodRef())
  1151. return;
  1152. if (resolvedTypeRef->IsPointer())
  1153. {
  1154. BfPointerType* pointerType = (BfPointerType*)resolvedTypeRef;
  1155. if (pointerType->mElementType->IsIncomplete())
  1156. PopulateType(pointerType->mElementType, BfPopulateType_Declaration);
  1157. pointerType->mSize = pointerType->mAlign = mSystem->mPtrSize;
  1158. resolvedTypeRef->mDefineState = BfTypeDefineState_Defined;
  1159. return;
  1160. }
  1161. if (resolvedTypeRef->IsGenericParam())
  1162. {
  1163. BfGenericParamType* genericParamType = (BfGenericParamType*)resolvedTypeRef;
  1164. PopulateType(mContext->mBfObjectType);
  1165. genericParamType->mSize = mContext->mBfObjectType->mSize;
  1166. genericParamType->mAlign = mContext->mBfObjectType->mAlign;
  1167. resolvedTypeRef->mDefineState = BfTypeDefineState_Defined;
  1168. return;
  1169. }
  1170. if (resolvedTypeRef->IsModifiedTypeType())
  1171. {
  1172. BfModifiedTypeType* retTypeType = (BfModifiedTypeType*)resolvedTypeRef;
  1173. BF_ASSERT(retTypeType->mElementType->IsGenericParam());
  1174. resolvedTypeRef->mSize = mContext->mBfObjectType->mSize;
  1175. resolvedTypeRef->mAlign = mContext->mBfObjectType->mAlign;
  1176. resolvedTypeRef->mDefineState = BfTypeDefineState_Defined;
  1177. return;
  1178. }
  1179. if (resolvedTypeRef->IsConcreteInterfaceType())
  1180. {
  1181. BfConcreteInterfaceType* concreteInterfaceType = (BfConcreteInterfaceType*)resolvedTypeRef;
  1182. BF_ASSERT(concreteInterfaceType->mInterface->IsInterface());
  1183. resolvedTypeRef->mSize = mContext->mBfObjectType->mSize;
  1184. resolvedTypeRef->mAlign = mContext->mBfObjectType->mAlign;
  1185. resolvedTypeRef->mDefineState = BfTypeDefineState_Defined;
  1186. return;
  1187. }
  1188. if (resolvedTypeRef->IsConstExprValue())
  1189. {
  1190. resolvedTypeRef->mSize = 0;
  1191. resolvedTypeRef->mAlign = 0;
  1192. resolvedTypeRef->mDefineState = BfTypeDefineState_Defined;
  1193. return;
  1194. }
  1195. // The autocomplete pass doesn't need to do the method processing, allow type to be (partially) incomplete
  1196. if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL) &&
  1197. (typeInstance != NULL) && (typeInstance->mNeedsMethodProcessing) && (!typeInstance->IsDelegate()))
  1198. return;
  1199. BfPrimitiveType* primitiveType = NULL;
  1200. if (typeInstance == NULL)
  1201. {
  1202. BF_ASSERT(resolvedTypeRef->IsPrimitiveType());
  1203. primitiveType = (BfPrimitiveType*)resolvedTypeRef;
  1204. typeDef = primitiveType->mTypeDef;
  1205. }
  1206. #define PRIMITIVE_TYPE(name, llvmType, size, dType) \
  1207. primitiveType->mSize = primitiveType->mAlign = size; \
  1208. primitiveType->mDefineState = BfTypeDefineState_Defined;
  1209. switch (typeDef->mTypeCode)
  1210. {
  1211. case BfTypeCode_None:
  1212. primitiveType->mSize = primitiveType->mAlign = 0;
  1213. resolvedTypeRef->mDefineState = BfTypeDefineState_Defined;
  1214. return;
  1215. case BfTypeCode_Self:
  1216. case BfTypeCode_Dot:
  1217. case BfTypeCode_Var:
  1218. case BfTypeCode_Let:
  1219. {
  1220. primitiveType->mSize = mSystem->mPtrSize;
  1221. primitiveType->mAlign = mSystem->mPtrSize;
  1222. resolvedTypeRef->mDefineState = BfTypeDefineState_Defined;
  1223. }
  1224. return;
  1225. case BfTypeCode_NullPtr:
  1226. primitiveType->mSize = primitiveType->mAlign = mSystem->mPtrSize;
  1227. primitiveType->mDefineState = BfTypeDefineState_Defined;
  1228. return;
  1229. case BfTypeCode_Boolean:
  1230. PRIMITIVE_TYPE("bool", Int1, 1, DW_ATE_boolean);
  1231. return;
  1232. case BfTypeCode_Int8:
  1233. PRIMITIVE_TYPE("sbyte", Int8, 1, DW_ATE_signed);
  1234. return;
  1235. case BfTypeCode_UInt8:
  1236. PRIMITIVE_TYPE("byte", Int8, 1, DW_ATE_unsigned);
  1237. return;
  1238. case BfTypeCode_Int16:
  1239. PRIMITIVE_TYPE("short", Int16, 2, DW_ATE_signed);
  1240. return;
  1241. case BfTypeCode_UInt16:
  1242. PRIMITIVE_TYPE("ushort", Int16, 2, DW_ATE_unsigned);
  1243. return;
  1244. case BfTypeCode_Int32:
  1245. PRIMITIVE_TYPE("int", Int32, 4, DW_ATE_signed);
  1246. return;
  1247. case BfTypeCode_UInt32:
  1248. PRIMITIVE_TYPE("uint", Int32, 4, DW_ATE_unsigned);
  1249. return;
  1250. case BfTypeCode_Int64:
  1251. PRIMITIVE_TYPE("long", Int64, 8, DW_ATE_signed);
  1252. return;
  1253. case BfTypeCode_UInt64:
  1254. PRIMITIVE_TYPE("ulong", Int64, 8, DW_ATE_unsigned);
  1255. return;
  1256. case BfTypeCode_IntPtr:
  1257. if (mSystem->mPtrSize == 4)
  1258. {
  1259. PRIMITIVE_TYPE("intptr", Int32, 4, DW_ATE_signed);
  1260. }
  1261. else
  1262. {
  1263. PRIMITIVE_TYPE("intptr", Int64, 8, DW_ATE_signed);
  1264. }
  1265. return;
  1266. case BfTypeCode_UIntPtr:
  1267. if (mSystem->mPtrSize == 4)
  1268. {
  1269. PRIMITIVE_TYPE("uintptr", Int32, 4, DW_ATE_unsigned);
  1270. }
  1271. else
  1272. {
  1273. PRIMITIVE_TYPE("uintptr", Int64, 8, DW_ATE_unsigned);
  1274. }
  1275. return;
  1276. case BfTypeCode_IntUnknown:
  1277. case BfTypeCode_UIntUnknown:
  1278. return;
  1279. case BfTypeCode_Char8:
  1280. PRIMITIVE_TYPE("char8", Int8, 1, DW_ATE_unsigned_char);
  1281. return;
  1282. case BfTypeCode_Char16:
  1283. PRIMITIVE_TYPE("char16", Int16, 2, DW_ATE_unsigned_char);
  1284. return;
  1285. case BfTypeCode_Char32:
  1286. PRIMITIVE_TYPE("char32", Int32, 4, DW_ATE_unsigned_char);
  1287. return;
  1288. case BfTypeCode_Float:
  1289. PRIMITIVE_TYPE("float", Float, 4, DW_ATE_float);
  1290. return;
  1291. case BfTypeCode_Double:
  1292. PRIMITIVE_TYPE("double", Double, 8, DW_ATE_float);
  1293. return;
  1294. case BfTypeCode_Object:
  1295. case BfTypeCode_Struct:
  1296. case BfTypeCode_Interface:
  1297. case BfTypeCode_Enum:
  1298. case BfTypeCode_TypeAlias:
  1299. // Implemented below
  1300. break;
  1301. case BfTypeCode_Extension:
  1302. // This can only happen if we didn't actually find the type the extension referred to
  1303. break;
  1304. default:
  1305. //NotImpl(resolvedTypeRef->mTypeRef);
  1306. BFMODULE_FATAL(this, "Invalid type");
  1307. return;
  1308. }
  1309. //////////////////////////////////////////////////////////////////////////
  1310. BF_ASSERT(typeInstance != NULL);
  1311. if (!typeInstance->IsArray())
  1312. {
  1313. BF_ASSERT(typeInstance->mTypeDef != mContext->mCompiler->mArray1TypeDef);
  1314. }
  1315. if (mContext->mBfObjectType == NULL)
  1316. {
  1317. if (typeInstance->IsInstanceOf(mCompiler->mBfObjectTypeDef))
  1318. mContext->mBfObjectType = typeInstance;
  1319. else if (mCompiler->mBfObjectTypeDef != NULL)
  1320. ResolveTypeDef(mCompiler->mBfObjectTypeDef);
  1321. }
  1322. if (typeInstance->mModule == NULL)
  1323. {
  1324. // Create a module for this type
  1325. mContext->HandleTypeWorkItem(resolvedTypeRef);
  1326. }
  1327. }
  1328. if (typeInstance == NULL)
  1329. return;
  1330. if (typeInstance->mModule == NULL)
  1331. {
  1332. BF_ASSERT(typeInstance->mTypeFailed);
  1333. return;
  1334. }
  1335. typeInstance->mModule->DoPopulateType(typeInstance, populateType);
  1336. }
  1337. BfTypeOptions* BfModule::GetTypeOptions(BfTypeDef* typeDef)
  1338. {
  1339. if (mContext->mSystem->mTypeOptions.size() == 0)
  1340. {
  1341. return NULL;
  1342. }
  1343. Array<int> matchedIndices;
  1344. if (!mCompiler->mAttributeTypeOptionMap.IsEmpty())
  1345. {
  1346. auto customAttributes = typeDef->mTypeDeclaration->mAttributes;
  1347. while (customAttributes != NULL)
  1348. {
  1349. if (!mCompiler->mAttributeTypeOptionMap.IsEmpty())
  1350. {
  1351. SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, true);
  1352. auto typeRef = customAttributes->mAttributeTypeRef;
  1353. // StringT<128> attrName;
  1354. // for (auto& customAttrs : customAttributes->mAttributeTypeRef)
  1355. // {
  1356. // attrName.Clear();
  1357. // customAttrs.mType->mTypeDef->mFullName.ToString(attrName);
  1358. // Array<int>* arrPtr;
  1359. // if (mCompiler->mAttributeTypeOptionMap.TryGetValue(attrName, &arrPtr))
  1360. // {
  1361. // for (auto optionsIdx : *arrPtr)
  1362. // {
  1363. // matchedIndices.Add(optionsIdx);
  1364. // }
  1365. // }
  1366. // }
  1367. }
  1368. customAttributes = customAttributes->mNextAttribute;
  1369. }
  1370. }
  1371. int typeOptionsCount = (int)mContext->mSystem->mTypeOptions.size();
  1372. auto _CheckTypeName = [&](const StringImpl& typeName)
  1373. {
  1374. for (int optionIdx = 0; optionIdx < (int)mContext->mSystem->mTypeOptions.size(); optionIdx++)
  1375. {
  1376. auto& typeOptions = mContext->mSystem->mTypeOptions[optionIdx];
  1377. bool matched = false;
  1378. for (auto& filter : typeOptions.mTypeFilters)
  1379. {
  1380. int filterIdx = 0;
  1381. int typeNameIdx = 0;
  1382. const char* filterPtr = filter.c_str();
  1383. const char* namePtr = typeName.c_str();
  1384. char prevFilterC = 0;
  1385. while (true)
  1386. {
  1387. char filterC;
  1388. while (true)
  1389. {
  1390. filterC = *(filterPtr++);
  1391. if (filterC != ' ')
  1392. break;
  1393. }
  1394. char nameC;
  1395. while (true)
  1396. {
  1397. nameC = *(namePtr++);
  1398. if (nameC != ' ')
  1399. break;
  1400. }
  1401. if ((filterC == 0) || (nameC == 0))
  1402. {
  1403. matched = (filterC == 0) && (nameC == 0);
  1404. break;
  1405. }
  1406. bool doWildcard = false;
  1407. if (nameC != filterC)
  1408. {
  1409. if (filterC == '*')
  1410. doWildcard = true;
  1411. else if (((filterC == ',') || (filterC == '>')) &&
  1412. ((prevFilterC == '<') || (prevFilterC == ',')))
  1413. {
  1414. doWildcard = true;
  1415. filterPtr--;
  1416. }
  1417. if (!doWildcard)
  1418. {
  1419. matched = false;
  1420. break;
  1421. }
  1422. }
  1423. if (doWildcard)
  1424. {
  1425. int openDepth = 0;
  1426. const char* startNamePtr = namePtr;
  1427. while (true)
  1428. {
  1429. nameC = *(namePtr++);
  1430. if (nameC == 0)
  1431. {
  1432. namePtr--;
  1433. if (openDepth != 0)
  1434. matched = false;
  1435. break;
  1436. }
  1437. if ((nameC == '>') && (openDepth == 0))
  1438. {
  1439. namePtr--;
  1440. break;
  1441. }
  1442. if (nameC == '<')
  1443. openDepth++;
  1444. else if (nameC == '>')
  1445. openDepth--;
  1446. else if ((nameC == ',') && (openDepth == 0))
  1447. {
  1448. namePtr--;
  1449. break;
  1450. }
  1451. }
  1452. if (!matched)
  1453. break;
  1454. }
  1455. prevFilterC = filterC;
  1456. }
  1457. }
  1458. if (matched)
  1459. matchedIndices.push_back(optionIdx);
  1460. }
  1461. };
  1462. // if (typeInstance->IsTypedPrimitive())
  1463. // {
  1464. // auto underlyingType = typeInstance->GetUnderlyingType();
  1465. // if (underlyingType != NULL)
  1466. // {
  1467. // String typeName = TypeToString(underlyingType);
  1468. // _CheckTypeName(typeName);
  1469. // }
  1470. // else
  1471. // {
  1472. // // Can this only happen for functions that are being extended?
  1473. // }
  1474. // }
  1475. //
  1476. // if ((!typeInstance->IsBoxed()) && (typeInstance->mTypeDef == mCompiler->mPointerTTypeDef))
  1477. // {
  1478. // BF_ASSERT(typeInstance->IsGenericTypeInstance());
  1479. // auto innerType = typeInstance->mGenericTypeInfo->mTypeGenericArguments[0];
  1480. // auto ptrType = CreatePointerType(innerType);
  1481. // String typeName = TypeToString(ptrType);
  1482. // _CheckTypeName(typeName);
  1483. // }
  1484. String typeName = BfTypeUtils::TypeToString(typeDef);
  1485. _CheckTypeName(typeName);
  1486. int matchedIdx = -1;
  1487. if (matchedIndices.size() == 1)
  1488. {
  1489. matchedIdx = matchedIndices[0];
  1490. }
  1491. else if (matchedIndices.size() > 1)
  1492. {
  1493. // Try to find a merged typeoptions with these indices
  1494. for (int mergedIdx = 0; mergedIdx < (int)mContext->mSystem->mMergedTypeOptions.size(); mergedIdx++)
  1495. {
  1496. auto& typeOptions = mContext->mSystem->mMergedTypeOptions[mergedIdx];
  1497. if (typeOptions.mMatchedIndices == matchedIndices)
  1498. {
  1499. matchedIdx = typeOptionsCount + mergedIdx;
  1500. break;
  1501. }
  1502. }
  1503. // Otherwise make one...
  1504. if (matchedIdx == -1)
  1505. {
  1506. auto& first = mContext->mSystem->mTypeOptions[matchedIndices[0]];
  1507. BfTypeOptions mergedTypeOptions;
  1508. mergedTypeOptions.mSIMDSetting = first.mSIMDSetting;
  1509. mergedTypeOptions.mOptimizationLevel = first.mOptimizationLevel;
  1510. mergedTypeOptions.mEmitDebugInfo = first.mEmitDebugInfo;
  1511. mergedTypeOptions.mAndFlags = first.mAndFlags;
  1512. mergedTypeOptions.mOrFlags = first.mOrFlags;
  1513. mergedTypeOptions.mAllocStackTraceDepth = first.mAllocStackTraceDepth;
  1514. mergedTypeOptions.mReflectMethodFilters = first.mReflectMethodFilters;
  1515. mergedTypeOptions.mReflectMethodAttributeFilters = first.mReflectMethodAttributeFilters;
  1516. mergedTypeOptions.mMatchedIndices = matchedIndices;
  1517. for (int idx = 1; idx < (int)matchedIndices.size(); idx++)
  1518. {
  1519. auto& typeOptions = mContext->mSystem->mTypeOptions[matchedIndices[idx]];
  1520. if (typeOptions.mSIMDSetting != -1)
  1521. mergedTypeOptions.mSIMDSetting = typeOptions.mSIMDSetting;
  1522. if (typeOptions.mOptimizationLevel != -1)
  1523. mergedTypeOptions.mOptimizationLevel = typeOptions.mOptimizationLevel;
  1524. if (typeOptions.mEmitDebugInfo != -1)
  1525. mergedTypeOptions.mEmitDebugInfo = typeOptions.mEmitDebugInfo;
  1526. mergedTypeOptions.mOrFlags = (BfOptionFlags)(mergedTypeOptions.mOrFlags | typeOptions.mOrFlags);
  1527. mergedTypeOptions.mAndFlags = (BfOptionFlags)(mergedTypeOptions.mAndFlags | typeOptions.mOrFlags);
  1528. mergedTypeOptions.mAndFlags = (BfOptionFlags)(mergedTypeOptions.mAndFlags & typeOptions.mAndFlags);
  1529. mergedTypeOptions.mOrFlags = (BfOptionFlags)(mergedTypeOptions.mOrFlags & typeOptions.mAndFlags);
  1530. if (mergedTypeOptions.HasReflectMethodFilters())
  1531. {
  1532. // If merging filter has non-default method flags but no filter then we need to append it as a filtered modification
  1533. if ((!typeOptions.HasReflectMethodFilters()) &&
  1534. (((typeOptions.mAndFlags & BfOptionFlags_Reflect_MethodMask) != BfOptionFlags_Reflect_MethodMask) ||
  1535. ((typeOptions.mOrFlags & BfOptionFlags_Reflect_MethodMask) != 0)))
  1536. {
  1537. mergedTypeOptions.mReflectMethodFilters.Add({"*", typeOptions.mAndFlags, typeOptions.mOrFlags});
  1538. }
  1539. mergedTypeOptions.mAndFlags = (BfOptionFlags)(mergedTypeOptions.mAndFlags | BfOptionFlags_Reflect_MethodMask);
  1540. mergedTypeOptions.mOrFlags = (BfOptionFlags)(mergedTypeOptions.mOrFlags & ~BfOptionFlags_Reflect_MethodMask);
  1541. }
  1542. if (typeOptions.mAllocStackTraceDepth != -1)
  1543. mergedTypeOptions.mAllocStackTraceDepth = typeOptions.mAllocStackTraceDepth;
  1544. for (auto filter : typeOptions.mReflectMethodFilters)
  1545. mergedTypeOptions.mReflectMethodFilters.Add(filter);
  1546. for (auto filter : typeOptions.mReflectMethodAttributeFilters)
  1547. mergedTypeOptions.mReflectMethodAttributeFilters.Add(filter);
  1548. }
  1549. matchedIdx = typeOptionsCount + (int)mContext->mSystem->mMergedTypeOptions.size();
  1550. mContext->mSystem->mMergedTypeOptions.push_back(mergedTypeOptions);
  1551. }
  1552. }
  1553. return mSystem->GetTypeOptions( matchedIdx);
  1554. }
  1555. bool BfModule::ApplyTypeOptionMethodFilters(bool includeMethod, BfMethodDef* methodDef, BfTypeOptions* typeOptions)
  1556. {
  1557. BfOptionFlags findFlag = BfOptionFlags_None;
  1558. if (methodDef->mMethodType == BfMethodType_Ctor)
  1559. findFlag = BfOptionFlags_ReflectConstructors;
  1560. else if (methodDef->mIsStatic)
  1561. findFlag = BfOptionFlags_ReflectStaticMethods;
  1562. else
  1563. findFlag = BfOptionFlags_ReflectNonStaticMethods;
  1564. if ((typeOptions->mAndFlags & findFlag) == 0)
  1565. includeMethod = false;
  1566. if ((typeOptions->mOrFlags & findFlag) != 0)
  1567. includeMethod = true;
  1568. if (!typeOptions->mReflectMethodFilters.IsEmpty())
  1569. {
  1570. for (auto& filter : typeOptions->mReflectMethodFilters)
  1571. {
  1572. if (BfCheckWildcard(filter.mFilter, methodDef->mName))
  1573. {
  1574. if ((filter.mAndFlags & findFlag) == 0)
  1575. includeMethod = false;
  1576. if ((filter.mAndFlags | findFlag) != 0)
  1577. includeMethod = true;
  1578. }
  1579. }
  1580. }
  1581. return includeMethod;
  1582. }
  1583. int BfModule::GenerateTypeOptions(BfCustomAttributes* customAttributes, BfTypeInstance* typeInstance, bool checkTypeName)
  1584. {
  1585. if (mContext->mSystem->mTypeOptions.size() == 0)
  1586. {
  1587. return -1;
  1588. }
  1589. Array<int> matchedIndices;
  1590. if ((!checkTypeName) && (typeInstance->mTypeOptionsIdx != -1))
  1591. {
  1592. // Methods should 'inherit' the owner's type options before applying type options from custom attributes
  1593. auto typeOptions = mSystem->GetTypeOptions(typeInstance->mTypeOptionsIdx);
  1594. if (typeOptions->mMatchedIndices.size() == 0)
  1595. matchedIndices.push_back(typeInstance->mTypeOptionsIdx);
  1596. else
  1597. matchedIndices = typeOptions->mMatchedIndices;
  1598. }
  1599. if (customAttributes != NULL)
  1600. {
  1601. if (!mCompiler->mAttributeTypeOptionMap.IsEmpty())
  1602. {
  1603. StringT<128> attrName;
  1604. for (auto& customAttrs : customAttributes->mAttributes)
  1605. {
  1606. attrName.Clear();
  1607. customAttrs.mType->mTypeDef->mFullName.ToString(attrName);
  1608. Array<int>* arrPtr;
  1609. if (mCompiler->mAttributeTypeOptionMap.TryGetValue(attrName, &arrPtr))
  1610. {
  1611. for (auto optionsIdx : *arrPtr)
  1612. {
  1613. matchedIndices.Add(optionsIdx);
  1614. }
  1615. }
  1616. }
  1617. }
  1618. }
  1619. int typeOptionsCount = (int)mContext->mSystem->mTypeOptions.size();
  1620. if (checkTypeName)
  1621. {
  1622. auto _CheckType = [&](BfType* type)
  1623. {
  1624. StringImpl typeName = TypeToString(type);
  1625. for (int optionIdx = 0; optionIdx < (int)mContext->mSystem->mTypeOptions.size(); optionIdx++)
  1626. {
  1627. auto& typeOptions = mContext->mSystem->mTypeOptions[optionIdx];
  1628. bool matched = false;
  1629. for (auto& filter : typeOptions.mTypeFilters)
  1630. {
  1631. int filterIdx = 0;
  1632. int typeNameIdx = 0;
  1633. if (filter.StartsWith(':'))
  1634. {
  1635. BfTypeInstance* typeInst = type->ToTypeInstance();
  1636. if (typeInst != NULL)
  1637. {
  1638. int startPos = 1;
  1639. for (; startPos < (int)filter.length(); startPos++)
  1640. if (filter[startPos] != ' ')
  1641. break;
  1642. String checkFilter;
  1643. checkFilter.Reference(filter.c_str() + startPos, filter.mLength - startPos);
  1644. BfTypeInstance* checkTypeInst = typeInst;
  1645. while (checkTypeInst != NULL)
  1646. {
  1647. for (auto& iface : checkTypeInst->mInterfaces)
  1648. {
  1649. StringT<128> ifaceName = TypeToString(iface.mInterfaceType);
  1650. if (BfCheckWildcard(checkFilter, ifaceName))
  1651. {
  1652. matched = true;
  1653. break;
  1654. }
  1655. }
  1656. checkTypeInst = checkTypeInst->mBaseType;
  1657. }
  1658. if (matched)
  1659. break;
  1660. }
  1661. }
  1662. else if (BfCheckWildcard(filter, typeName))
  1663. {
  1664. matched = true;
  1665. break;
  1666. }
  1667. }
  1668. if (matched)
  1669. matchedIndices.push_back(optionIdx);
  1670. }
  1671. };
  1672. if (typeInstance->IsTypedPrimitive())
  1673. {
  1674. auto underlyingType = typeInstance->GetUnderlyingType();
  1675. if (underlyingType != NULL)
  1676. {
  1677. _CheckType(underlyingType);
  1678. }
  1679. else
  1680. {
  1681. // Can this only happen for functions that are being extended?
  1682. }
  1683. }
  1684. if ((!typeInstance->IsBoxed()) && (typeInstance->IsInstanceOf(mCompiler->mPointerTTypeDef)))
  1685. {
  1686. BF_ASSERT(typeInstance->IsGenericTypeInstance());
  1687. auto innerType = typeInstance->mGenericTypeInfo->mTypeGenericArguments[0];
  1688. auto ptrType = CreatePointerType(innerType);
  1689. _CheckType(ptrType);
  1690. }
  1691. _CheckType(typeInstance);
  1692. }
  1693. int matchedIdx = -1;
  1694. if (matchedIndices.size() == 1)
  1695. {
  1696. matchedIdx = matchedIndices[0];
  1697. }
  1698. else if (matchedIndices.size() > 1)
  1699. {
  1700. // Try to find a merged typeoptions with these indices
  1701. for (int mergedIdx = 0; mergedIdx < (int)mContext->mSystem->mMergedTypeOptions.size(); mergedIdx++)
  1702. {
  1703. auto& typeOptions = mContext->mSystem->mMergedTypeOptions[mergedIdx];
  1704. if (typeOptions.mMatchedIndices == matchedIndices)
  1705. {
  1706. matchedIdx = typeOptionsCount + mergedIdx;
  1707. break;
  1708. }
  1709. }
  1710. // Otherwise make one...
  1711. if (matchedIdx == -1)
  1712. {
  1713. auto& first = mContext->mSystem->mTypeOptions[matchedIndices[0]];
  1714. BfTypeOptions mergedTypeOptions;
  1715. mergedTypeOptions.mSIMDSetting = first.mSIMDSetting;
  1716. mergedTypeOptions.mOptimizationLevel = first.mOptimizationLevel;
  1717. mergedTypeOptions.mEmitDebugInfo = first.mEmitDebugInfo;
  1718. mergedTypeOptions.mAndFlags = first.mAndFlags;
  1719. mergedTypeOptions.mOrFlags = first.mOrFlags;
  1720. mergedTypeOptions.mAllocStackTraceDepth = first.mAllocStackTraceDepth;
  1721. mergedTypeOptions.mReflectMethodFilters = first.mReflectMethodFilters;
  1722. mergedTypeOptions.mReflectMethodAttributeFilters = first.mReflectMethodAttributeFilters;
  1723. mergedTypeOptions.mMatchedIndices = matchedIndices;
  1724. for (int idx = 1; idx < (int)matchedIndices.size(); idx++)
  1725. {
  1726. auto& typeOptions = mContext->mSystem->mTypeOptions[matchedIndices[idx]];
  1727. if (typeOptions.mSIMDSetting != -1)
  1728. mergedTypeOptions.mSIMDSetting = typeOptions.mSIMDSetting;
  1729. if (typeOptions.mOptimizationLevel != -1)
  1730. mergedTypeOptions.mOptimizationLevel = typeOptions.mOptimizationLevel;
  1731. if (typeOptions.mEmitDebugInfo != -1)
  1732. mergedTypeOptions.mEmitDebugInfo = typeOptions.mEmitDebugInfo;
  1733. mergedTypeOptions.mOrFlags = (BfOptionFlags)(mergedTypeOptions.mOrFlags | typeOptions.mOrFlags);
  1734. mergedTypeOptions.mAndFlags = (BfOptionFlags)(mergedTypeOptions.mAndFlags | typeOptions.mOrFlags);
  1735. mergedTypeOptions.mAndFlags = (BfOptionFlags)(mergedTypeOptions.mAndFlags & typeOptions.mAndFlags);
  1736. mergedTypeOptions.mOrFlags = (BfOptionFlags)(mergedTypeOptions.mOrFlags & typeOptions.mAndFlags);
  1737. if (typeOptions.mAllocStackTraceDepth != -1)
  1738. mergedTypeOptions.mAllocStackTraceDepth = typeOptions.mAllocStackTraceDepth;
  1739. for (auto& filter : typeOptions.mReflectMethodFilters)
  1740. mergedTypeOptions.mReflectMethodFilters.Add(filter);
  1741. for (auto& filter : typeOptions.mReflectMethodAttributeFilters)
  1742. mergedTypeOptions.mReflectMethodAttributeFilters.Add(filter);
  1743. }
  1744. matchedIdx = typeOptionsCount + (int)mContext->mSystem->mMergedTypeOptions.size();
  1745. mContext->mSystem->mMergedTypeOptions.push_back(mergedTypeOptions);
  1746. }
  1747. }
  1748. return matchedIdx;
  1749. }
  1750. void BfModule::SetTypeOptions(BfTypeInstance* typeInstance)
  1751. {
  1752. typeInstance->mTypeOptionsIdx = GenerateTypeOptions(typeInstance->mCustomAttributes, typeInstance, true);
  1753. }
  1754. BfCEParseContext BfModule::CEEmitParse(BfTypeInstance* typeInstance, const StringImpl& src)
  1755. {
  1756. BfCEParseContext ceParseContext;
  1757. ceParseContext.mFailIdx = mCompiler->mPassInstance->mFailedIdx;
  1758. ceParseContext.mWarnIdx = mCompiler->mPassInstance->mWarnIdx;
  1759. bool createdParser = false;
  1760. int startSrcIdx = 0;
  1761. BfParser* emitParser = NULL;
  1762. if (typeInstance->mTypeDef->mEmitParent == NULL)
  1763. {
  1764. BF_ASSERT(typeInstance->mTypeDef->mNextRevision == NULL);
  1765. BfTypeDef* emitTypeDef = new BfTypeDef();
  1766. emitTypeDef->mEmitParent = typeInstance->mTypeDef;
  1767. mSystem->CopyTypeDef(emitTypeDef, typeInstance->mTypeDef);
  1768. emitTypeDef->mDefState = BfTypeDef::DefState_Emitted;
  1769. typeInstance->mTypeDef = emitTypeDef;
  1770. createdParser = true;
  1771. emitParser = new BfParser(mSystem, typeInstance->mTypeDef->mProject);
  1772. emitParser->mIsEmitted = true;
  1773. emitParser->mFileName = typeInstance->mTypeDef->mName->ToString();
  1774. BfLogSys(mSystem, "Emit typeDef for type %p created %p parser %p typeDecl %p\n", typeInstance, emitTypeDef, emitParser, emitTypeDef->mTypeDeclaration);
  1775. if (mCompiler->mIsResolveOnly)
  1776. emitParser->mFileName += "$EmitR$";
  1777. else
  1778. emitParser->mFileName += "$Emit$";
  1779. emitParser->mFileName += StrFormat("%d", typeInstance->mTypeId);
  1780. emitParser->mFileName += StrFormat(".bf|%d", typeInstance->mRevision);
  1781. emitTypeDef->mSource = emitParser;
  1782. emitParser->mRefCount++;
  1783. emitParser->SetSource(src.c_str(), src.mLength);
  1784. // If we emit only from method attributes then we will already have method instances created
  1785. auto _FixMethod = [&](BfMethodInstance* methodInstance)
  1786. {
  1787. if (methodInstance == NULL)
  1788. return;
  1789. methodInstance->mMethodDef = emitTypeDef->mMethods[methodInstance->mMethodDef->mIdx];
  1790. };
  1791. for (auto& methodInstanceGroup : typeInstance->mMethodInstanceGroups)
  1792. {
  1793. _FixMethod(methodInstanceGroup.mDefault);
  1794. if (methodInstanceGroup.mMethodSpecializationMap != NULL)
  1795. {
  1796. for (auto& kv : *methodInstanceGroup.mMethodSpecializationMap)
  1797. _FixMethod(kv.mValue);
  1798. }
  1799. };
  1800. }
  1801. else
  1802. {
  1803. emitParser = typeInstance->mTypeDef->mSource->ToParser();
  1804. int idx = emitParser->AllocChars(src.mLength + 1);
  1805. memcpy((uint8*)emitParser->mSrc + idx, src.c_str(), src.mLength + 1);
  1806. emitParser->mSrcIdx = idx;
  1807. emitParser->mSrcLength = idx + src.mLength;
  1808. emitParser->mParserData->mSrcLength = emitParser->mSrcLength;
  1809. }
  1810. emitParser->Parse(mCompiler->mPassInstance);
  1811. emitParser->FinishSideNodes();
  1812. if (createdParser)
  1813. {
  1814. AutoCrit crit(mSystem->mDataLock);
  1815. mSystem->mParsers.Add(emitParser);
  1816. }
  1817. return ceParseContext;
  1818. }
  1819. void BfModule::FinishCEParseContext(BfAstNode* refNode, BfTypeInstance* typeInstance, BfCEParseContext* ceParseContext)
  1820. {
  1821. if ((ceParseContext->mFailIdx != mCompiler->mPassInstance->mFailedIdx) && (refNode != NULL))
  1822. Fail("Emitted code had errors", refNode);
  1823. else if ((ceParseContext->mWarnIdx != mCompiler->mPassInstance->mWarnIdx) && (refNode != NULL))
  1824. Warn(0, "Emitted code had warnings", refNode);
  1825. else if ((ceParseContext->mFailIdx != mCompiler->mPassInstance->mFailedIdx) ||
  1826. (ceParseContext->mWarnIdx != mCompiler->mPassInstance->mWarnIdx))
  1827. {
  1828. AddFailType(typeInstance);
  1829. }
  1830. }
  1831. void BfModule::UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, const StringImpl& ctxString, BfAstNode* refNode)
  1832. {
  1833. for (int ifaceTypeId : ceEmitContext->mInterfaces)
  1834. typeInstance->mCeTypeInfo->mPendingInterfaces.Add(ifaceTypeId);
  1835. if (ceEmitContext->mEmitData.IsEmpty())
  1836. return;
  1837. String src;
  1838. if (typeInstance->mTypeDef->mEmitParent != NULL)
  1839. src += "\n\n";
  1840. src += "// Code emission in ";
  1841. src += ctxString;
  1842. src += "\n\n";
  1843. src += ceEmitContext->mEmitData;
  1844. ceEmitContext->mEmitData.Clear();
  1845. BfCEParseContext ceParseContext = CEEmitParse(typeInstance, src);
  1846. auto emitParser = typeInstance->mTypeDef->mSource->ToParser();
  1847. auto typeDeclaration = emitParser->mAlloc->Alloc<BfTypeDeclaration>();
  1848. BfReducer bfReducer;
  1849. bfReducer.mSource = emitParser;
  1850. bfReducer.mPassInstance = mCompiler->mPassInstance;
  1851. bfReducer.mAlloc = emitParser->mAlloc;
  1852. bfReducer.mSystem = mSystem;
  1853. bfReducer.mCurTypeDecl = typeDeclaration;
  1854. typeDeclaration->mDefineNode = emitParser->mRootNode;
  1855. bfReducer.HandleTypeDeclaration(typeDeclaration, NULL);
  1856. BfDefBuilder defBuilder(mSystem);
  1857. defBuilder.mCurSource = emitParser;
  1858. defBuilder.mCurTypeDef = typeInstance->mTypeDef;
  1859. defBuilder.mCurDeclaringTypeDef = typeInstance->mTypeDef;
  1860. if (typeInstance->mTypeDef->mIsCombinedPartial)
  1861. {
  1862. // Always define generated methods on the primary type declaration
  1863. defBuilder.mCurDeclaringTypeDef = typeInstance->mTypeDef->mPartials[0]->GetLatest();
  1864. }
  1865. defBuilder.mPassInstance = mCompiler->mPassInstance;
  1866. defBuilder.mIsComptime = true;
  1867. defBuilder.DoVisitChild(typeDeclaration->mDefineNode);
  1868. defBuilder.FinishTypeDef(typeInstance->mTypeDef->mTypeCode == BfTypeCode_Enum);
  1869. FinishCEParseContext(refNode, typeInstance, &ceParseContext);
  1870. if (typeInstance->mTypeDef->mEmitParent != NULL)
  1871. {
  1872. // Remove generated fields like the 'underlying type' enum field
  1873. typeInstance->mFieldInstances.Resize(typeInstance->mTypeDef->mEmitParent->mFields.mSize);
  1874. }
  1875. }
  1876. void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, BfFieldInstance* fieldInstance, BfCustomAttributes* customAttributes, Dictionary<BfTypeInstance*, BfIRValue>& prevAttrInstances, bool underlyingTypeDeferred)
  1877. {
  1878. for (auto& customAttribute : customAttributes->mAttributes)
  1879. {
  1880. auto attrType = customAttribute.mType;
  1881. BfMethodInstance* methodInstance = NULL;
  1882. bool isFieldApply = false;
  1883. BfIRValue irValue;
  1884. int checkDepth = 0;
  1885. auto checkAttrType = attrType;
  1886. while (checkAttrType != NULL)
  1887. {
  1888. mContext->mUnreifiedModule->PopulateType(checkAttrType, BfPopulateType_DataAndMethods);
  1889. if (checkAttrType->mDefineState < BfTypeDefineState_DefinedAndMethodsSlotted)
  1890. break;
  1891. for (auto& ifaceEntry : checkAttrType->mInterfaces)
  1892. {
  1893. isFieldApply = false;
  1894. isFieldApply = (ceEmitContext != NULL) && (ifaceEntry.mInterfaceType->IsInstanceOf(mCompiler->mIOnFieldInitTypeDef));
  1895. if ((isFieldApply) ||
  1896. ((ceEmitContext != NULL) && (ifaceEntry.mInterfaceType->IsInstanceOf(mCompiler->mIComptimeTypeApply))) ||
  1897. ((ceEmitContext != NULL) && (ifaceEntry.mInterfaceType->IsInstanceOf(mCompiler->mIOnTypeInitTypeDef))) ||
  1898. ((ceEmitContext == NULL) && (ifaceEntry.mInterfaceType->IsInstanceOf(mCompiler->mIOnTypeDoneTypeDef))))
  1899. {
  1900. // Passes
  1901. }
  1902. else
  1903. continue;
  1904. prevAttrInstances.TryGetValue(checkAttrType, &irValue);
  1905. methodInstance = checkAttrType->mInterfaceMethodTable[ifaceEntry.mStartInterfaceTableIdx].mMethodRef;
  1906. break;
  1907. }
  1908. if (methodInstance != NULL)
  1909. break;
  1910. checkAttrType = checkAttrType->mBaseType;
  1911. checkDepth++;
  1912. }
  1913. if (methodInstance == NULL)
  1914. continue;
  1915. SetAndRestoreValue<CeEmitContext*> prevEmitContext(mCompiler->mCEMachine->mCurEmitContext, ceEmitContext);
  1916. auto ceContext = mCompiler->mCEMachine->AllocContext();
  1917. BfIRValue attrVal = ceContext->CreateAttribute(customAttribute.mRef, this, typeInstance->mConstHolder, &customAttribute);
  1918. for (int baseIdx = 0; baseIdx < checkDepth; baseIdx++)
  1919. attrVal = mBfIRBuilder->CreateExtractValue(attrVal, 0);
  1920. SizedArray<BfIRValue, 1> args;
  1921. if (!attrType->IsValuelessType())
  1922. args.Add(attrVal);
  1923. if (isFieldApply)
  1924. {
  1925. auto fieldInfoType = ResolveTypeDef(mCompiler->mReflectFieldInfoTypeDef);
  1926. if (fieldInfoType != NULL)
  1927. {
  1928. SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, true);
  1929. SizedArray<BfIRValue, 9> fieldData =
  1930. {
  1931. mBfIRBuilder->CreateConstAggZero(mBfIRBuilder->MapType(fieldInfoType->ToTypeInstance()->mBaseType, BfIRPopulateType_Identity)),
  1932. mBfIRBuilder->CreateTypeOf(mCurTypeInstance), // mTypeInstance
  1933. CreateFieldData(fieldInstance, fieldInstance->GetFieldDef()->mIdx)
  1934. };
  1935. FixConstValueParams(fieldInfoType->ToTypeInstance(), fieldData);
  1936. auto fieldDataAgg = mBfIRBuilder->CreateConstAgg(mBfIRBuilder->MapType(fieldInfoType, BfIRPopulateType_Identity), fieldData);
  1937. args.Add(fieldDataAgg);
  1938. }
  1939. }
  1940. else
  1941. args.Add(mBfIRBuilder->CreateTypeOf(typeInstance));
  1942. if (methodInstance->GetParamCount() > 1)
  1943. {
  1944. if (irValue)
  1945. args.Add(irValue);
  1946. else
  1947. args.Add(mBfIRBuilder->CreateConstNull());
  1948. }
  1949. else
  1950. {
  1951. // Only allow a single instance
  1952. if (irValue)
  1953. continue;
  1954. }
  1955. DoPopulateType_CeCheckEnum(typeInstance, underlyingTypeDeferred);
  1956. if (fieldInstance != NULL)
  1957. mCompiler->mCEMachine->mFieldInstanceSet.Add(fieldInstance);
  1958. BfTypedValue result;
  1959. ///
  1960. {
  1961. SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, true);
  1962. result = ceContext->Call(customAttribute.mRef, this, methodInstance, args, CeEvalFlags_ForceReturnThis, NULL);
  1963. }
  1964. if (fieldInstance != NULL)
  1965. mCompiler->mCEMachine->mFieldInstanceSet.Remove(fieldInstance);
  1966. if (result.mType == methodInstance->GetOwner())
  1967. prevAttrInstances[methodInstance->GetOwner()] = result.mValue;
  1968. if (ceEmitContext == NULL)
  1969. continue;
  1970. if (typeInstance->mDefineState == BfTypeDefineState_DefinedAndMethodsSlotted)
  1971. return;
  1972. if (typeInstance->mDefineState != BfTypeDefineState_CETypeInit)
  1973. {
  1974. // We populated before we could finish
  1975. AssertErrorState();
  1976. }
  1977. else
  1978. {
  1979. auto owner = methodInstance->GetOwner();
  1980. int typeId = owner->mTypeId;
  1981. if ((!result) && (mCompiler->mFastFinish))
  1982. {
  1983. if ((typeInstance->mCeTypeInfo != NULL) && (typeInstance->mCeTypeInfo->mNext == NULL))
  1984. typeInstance->mCeTypeInfo->mNext = new BfCeTypeInfo();
  1985. if ((typeInstance->mCeTypeInfo != NULL) && (typeInstance->mCeTypeInfo->mNext != NULL))
  1986. typeInstance->mCeTypeInfo->mNext->mFailed = true;
  1987. if (typeInstance->mCeTypeInfo != NULL)
  1988. {
  1989. BfCeTypeEmitEntry* entry = NULL;
  1990. if (typeInstance->mCeTypeInfo->mTypeIFaceMap.TryGetValue(typeId, &entry))
  1991. {
  1992. ceEmitContext->mEmitData = entry->mEmitData;
  1993. }
  1994. }
  1995. }
  1996. else if (ceEmitContext->HasEmissions())
  1997. {
  1998. if (typeInstance->mCeTypeInfo == NULL)
  1999. typeInstance->mCeTypeInfo = new BfCeTypeInfo();
  2000. if (typeInstance->mCeTypeInfo->mNext == NULL)
  2001. typeInstance->mCeTypeInfo->mNext = new BfCeTypeInfo();
  2002. BfCeTypeEmitEntry entry;
  2003. entry.mEmitData = ceEmitContext->mEmitData;
  2004. typeInstance->mCeTypeInfo->mNext->mTypeIFaceMap[typeId] = entry;
  2005. }
  2006. if ((ceEmitContext->HasEmissions()) && (!mCompiler->mFastFinish))
  2007. {
  2008. String ctxStr = "comptime ";
  2009. ctxStr += methodInstance->mMethodDef->mName;
  2010. ctxStr += " of ";
  2011. ctxStr += TypeToString(attrType);
  2012. ctxStr += " to ";
  2013. ctxStr += TypeToString(typeInstance);
  2014. ctxStr += " ";
  2015. ctxStr += customAttribute.mRef->LocationToString();
  2016. UpdateCEEmit(ceEmitContext, typeInstance, ctxStr, customAttribute.mRef);
  2017. }
  2018. }
  2019. mCompiler->mCEMachine->ReleaseContext(ceContext);
  2020. }
  2021. }
  2022. void BfModule::CEMixin(BfAstNode* refNode, const StringImpl& code)
  2023. {
  2024. auto activeTypeDef = mCurMethodInstance->mMethodDef->mDeclaringType;
  2025. //auto emitParser = activeTypeDef->mEmitParser;
  2026. String src;
  2027. if (mCurTypeInstance->mTypeDef->mEmitParent != NULL)
  2028. src += "\n\n";
  2029. src += "// Code emission in ";
  2030. src += MethodToString(mCurMethodInstance);
  2031. src += "\n";
  2032. src += code;
  2033. BfReducer bfReducer;
  2034. bfReducer.mPassInstance = mCompiler->mPassInstance;
  2035. bfReducer.mSystem = mSystem;
  2036. bfReducer.mCurTypeDecl = activeTypeDef->mTypeDeclaration;
  2037. bfReducer.mCurMethodDecl = BfNodeDynCast<BfMethodDeclaration>(mCurMethodInstance->mMethodDef->mMethodDeclaration);
  2038. SetAndRestoreValue<BfAstNode*> prevCustomAttribute(mCurMethodState->mEmitRefNode, refNode);
  2039. EmitEnsureInstructionAt();
  2040. bool wantsDIData = (mBfIRBuilder->DbgHasInfo()) && (mHasFullDebugInfo);
  2041. mBfIRBuilder->SaveDebugLocation();
  2042. BfCEParseContext ceParseContext = CEEmitParse(mCurTypeInstance, src);
  2043. auto emitParser = mCurTypeInstance->mTypeDef->mSource->ToParser();
  2044. bfReducer.mSource = emitParser;
  2045. bfReducer.mAlloc = emitParser->mAlloc;
  2046. bfReducer.HandleBlock(emitParser->mRootNode, false);
  2047. SetAndRestoreValue<BfIRMDNode> prevInlinedAt(mCurMethodState->mCurScope->mDIInlinedAt);
  2048. SetAndRestoreValue<BfIRMDNode> prevDIScope(mCurMethodState->mCurScope->mDIScope);
  2049. SetAndRestoreValue<BfIRMDNode> prevAltDIFile(mCurMethodState->mCurScope->mAltDIFile);
  2050. if (wantsDIData)
  2051. {
  2052. llvm::SmallVector<BfIRMDNode, 8> diParams;
  2053. diParams.push_back(mBfIRBuilder->DbgGetType(GetPrimitiveType(BfTypeCode_None)));
  2054. BfIRMDNode diFuncType = mBfIRBuilder->DbgCreateSubroutineType(diParams);
  2055. //int defLine = mModule->mCurFilePosition.mCurLine;
  2056. int flags = 0;
  2057. mCurMethodState->mCurScope->mDIInlinedAt = mBfIRBuilder->DbgGetCurrentLocation();
  2058. // We used to have the "def" line be the inlining position, but the linker we de-duplicate instances of these functions without regard to their unique line
  2059. // definitions, so we need to be consistent and use the actual line
  2060. UpdateSrcPos(emitParser->mRootNode, BfSrcPosFlag_NoSetDebugLoc);
  2061. int defLine = mCurFilePosition.mCurLine;
  2062. auto diParentType = mBfIRBuilder->DbgGetTypeInst(mCurTypeInstance);
  2063. if (!mBfIRBuilder->mIgnoreWrites)
  2064. {
  2065. String methodName = "Comptime_Mixin";
  2066. mCurMethodState->mCurScope->mDIScope = mBfIRBuilder->DbgCreateFunction(diParentType, methodName, "", mCurFilePosition.mFileInstance->mDIFile,
  2067. defLine + 1, diFuncType, false, true, mCurFilePosition.mCurLine + 1, flags, false, BfIRValue());
  2068. mCurMethodState->mCurScope->mAltDIFile = mCurFilePosition.mFileInstance->mDIFile;
  2069. }
  2070. }
  2071. UpdateSrcPos(emitParser->mRootNode);
  2072. SetIllegalSrcPos();
  2073. Visit(emitParser->mRootNode);
  2074. mBfIRBuilder->RestoreDebugLocation();
  2075. mBfIRBuilder->DupDebugLocation();
  2076. FinishCEParseContext(refNode, mCurTypeInstance, &ceParseContext);
  2077. }
  2078. void BfModule::ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, BfCEOnCompileKind onCompileKind, bool underlyingTypeDeferred)
  2079. {
  2080. Dictionary<BfTypeInstance*, BfIRValue> prevAttrInstances;
  2081. if (typeInstance->mCustomAttributes != NULL)
  2082. HandleCEAttributes(ceEmitContext, typeInstance, NULL, typeInstance->mCustomAttributes, prevAttrInstances, underlyingTypeDeferred);
  2083. if (ceEmitContext != NULL)
  2084. {
  2085. for (auto& fieldInstance : typeInstance->mFieldInstances)
  2086. {
  2087. if (fieldInstance.mCustomAttributes != NULL)
  2088. HandleCEAttributes(ceEmitContext, typeInstance, &fieldInstance, fieldInstance.mCustomAttributes, prevAttrInstances, underlyingTypeDeferred);
  2089. }
  2090. }
  2091. int methodCount = (int)typeInstance->mTypeDef->mMethods.size();
  2092. for (int methodIdx = 0; methodIdx < methodCount; methodIdx++)
  2093. {
  2094. auto methodDef = typeInstance->mTypeDef->mMethods[methodIdx];
  2095. auto methodDeclaration = BfNodeDynCast<BfMethodDeclaration>(methodDef->mMethodDeclaration);
  2096. if (methodDeclaration == NULL)
  2097. continue;
  2098. if (methodDeclaration->mAttributes == NULL)
  2099. continue;
  2100. bool wantsAttributes = false;
  2101. BfAttributeDirective* checkAttributes = methodDeclaration->mAttributes;
  2102. while (checkAttributes != NULL)
  2103. {
  2104. SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, true);
  2105. BfType* attrType = ResolveTypeRef(checkAttributes->mAttributeTypeRef, BfPopulateType_Identity, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_Attribute | BfResolveTypeRefFlag_NoReify));
  2106. if (attrType != NULL)
  2107. {
  2108. if (attrType->IsInstanceOf(mCompiler->mOnCompileAttributeTypeDef))
  2109. wantsAttributes = true;
  2110. auto attrTypeInstance = attrType->ToTypeInstance();
  2111. if ((attrTypeInstance != NULL) && (!attrTypeInstance->mInterfaces.IsEmpty()))
  2112. wantsAttributes = true;
  2113. }
  2114. checkAttributes = checkAttributes->mNextAttribute;
  2115. }
  2116. if (!wantsAttributes)
  2117. return;
  2118. auto customAttributes = GetCustomAttributes(methodDeclaration->mAttributes, BfAttributeTargets_Method);
  2119. defer({ delete customAttributes; });
  2120. auto onCompileAttribute = customAttributes->Get(mCompiler->mOnCompileAttributeTypeDef);
  2121. if (onCompileAttribute == NULL)
  2122. continue;
  2123. HandleCEAttributes(ceEmitContext, typeInstance, NULL, customAttributes, prevAttrInstances, underlyingTypeDeferred);
  2124. if (onCompileAttribute->mCtorArgs.size() < 1)
  2125. continue;
  2126. auto constant = typeInstance->mConstHolder->GetConstant(onCompileAttribute->mCtorArgs[0]);
  2127. if (constant == NULL)
  2128. continue;
  2129. if (onCompileKind != (BfCEOnCompileKind)constant->mInt32)
  2130. continue;
  2131. if (!methodDef->mIsStatic)
  2132. {
  2133. Fail("OnCompile methods must be static", methodDeclaration);
  2134. continue;
  2135. }
  2136. if (!methodDef->mParams.IsEmpty())
  2137. {
  2138. Fail("OnCompile methods cannot declare parameters", methodDeclaration);
  2139. continue;
  2140. }
  2141. SetAndRestoreValue<CeEmitContext*> prevEmitContext(mCompiler->mCEMachine->mCurEmitContext);
  2142. if (onCompileKind == BfCEOnCompileKind_TypeInit)
  2143. {
  2144. mCompiler->mCEMachine->mCurEmitContext = ceEmitContext;
  2145. }
  2146. DoPopulateType_CeCheckEnum(typeInstance, underlyingTypeDeferred);
  2147. auto methodInstance = GetRawMethodInstanceAtIdx(typeInstance, methodDef->mIdx);
  2148. auto result = mCompiler->mCEMachine->Call(methodDef->GetRefNode(), this, methodInstance, {}, (CeEvalFlags)(CeEvalFlags_PersistantError | CeEvalFlags_DeferIfNotOnlyError), NULL);
  2149. if ((onCompileKind == BfCEOnCompileKind_TypeDone) && (typeInstance->mDefineState > BfTypeDefineState_CETypeInit))
  2150. {
  2151. // Type done, okay
  2152. }
  2153. else if (typeInstance->mDefineState != BfTypeDefineState_CETypeInit)
  2154. {
  2155. // We populated before we could finish
  2156. AssertErrorState();
  2157. }
  2158. else
  2159. {
  2160. if ((!result) && (mCompiler->mFastFinish))
  2161. {
  2162. if ((typeInstance->mCeTypeInfo != NULL) && (typeInstance->mCeTypeInfo->mNext == NULL))
  2163. typeInstance->mCeTypeInfo->mNext = new BfCeTypeInfo();
  2164. if ((typeInstance->mCeTypeInfo != NULL) && (typeInstance->mCeTypeInfo->mNext != NULL))
  2165. typeInstance->mCeTypeInfo->mNext->mFailed = true;
  2166. if (typeInstance->mCeTypeInfo != NULL)
  2167. {
  2168. BfCeTypeEmitEntry* entry = NULL;
  2169. if (typeInstance->mCeTypeInfo->mOnCompileMap.TryGetValue(methodDef->mIdx, &entry))
  2170. {
  2171. ceEmitContext->mEmitData = entry->mEmitData;
  2172. }
  2173. }
  2174. }
  2175. else if (!ceEmitContext->mEmitData.IsEmpty())
  2176. {
  2177. if (typeInstance->mCeTypeInfo == NULL)
  2178. typeInstance->mCeTypeInfo = new BfCeTypeInfo();
  2179. if (typeInstance->mCeTypeInfo->mNext == NULL)
  2180. typeInstance->mCeTypeInfo->mNext = new BfCeTypeInfo();
  2181. BfCeTypeEmitEntry entry;
  2182. entry.mEmitData = ceEmitContext->mEmitData;
  2183. typeInstance->mCeTypeInfo->mNext->mOnCompileMap[methodDef->mIdx] = entry;
  2184. }
  2185. if (!ceEmitContext->mEmitData.IsEmpty())
  2186. {
  2187. String ctxStr = "OnCompile execution of ";
  2188. ctxStr += MethodToString(methodInstance);
  2189. ctxStr += " ";
  2190. ctxStr += methodInstance->mMethodDef->GetRefNode()->LocationToString();
  2191. UpdateCEEmit(ceEmitContext, typeInstance, ctxStr, methodInstance->mMethodDef->GetRefNode());
  2192. }
  2193. }
  2194. if (mCompiler->mCanceling)
  2195. {
  2196. DeferRebuildType(typeInstance);
  2197. }
  2198. }
  2199. // if ((!typeInstance->IsInstanceOf(mCompiler->mValueTypeTypeDef)) &&
  2200. // (!typeInstance->IsInstanceOf(mCompiler->mBfObjectTypeDef)) &&
  2201. // (!typeInstance->IsBoxed()) &&
  2202. // (!typeInstance->IsDelegate()) &&
  2203. // (!typeInstance->IsTuple()))
  2204. // {
  2205. // //zTODO: TESTING, remove!
  2206. // CEEmitParse(typeInstance, "// Testing");
  2207. // }
  2208. }
  2209. void BfModule::DoCEEmit(BfTypeInstance* typeInstance, bool& hadNewMembers, bool underlyingTypeDeferred)
  2210. {
  2211. BfLogSysM("BfModule::DoCEEmit %p\n", typeInstance);
  2212. CeEmitContext ceEmitContext;
  2213. ceEmitContext.mType = typeInstance;
  2214. ExecuteCEOnCompile(&ceEmitContext, typeInstance, BfCEOnCompileKind_TypeInit, underlyingTypeDeferred);
  2215. hadNewMembers = (typeInstance->mTypeDef->mEmitParent != NULL);
  2216. if (ceEmitContext.mFailed)
  2217. TypeFailed(typeInstance);
  2218. }
  2219. void BfModule::DoCEEmit(BfMethodInstance* methodInstance)
  2220. {
  2221. auto customAttributes = methodInstance->GetCustomAttributes();
  2222. if (customAttributes == NULL)
  2223. return;
  2224. auto typeInstance = methodInstance->GetOwner();
  2225. CeEmitContext ceEmitContext;
  2226. ceEmitContext.mMethodInstance = methodInstance;
  2227. Dictionary<BfTypeInstance*, BfIRValue> prevAttrInstances;
  2228. for (auto& customAttribute : customAttributes->mAttributes)
  2229. {
  2230. auto attrType = customAttribute.mType;
  2231. BfMethodInstance* applyMethodInstance = NULL;
  2232. BfIRValue irValue;
  2233. int checkDepth = 0;
  2234. auto checkAttrType = attrType;
  2235. while (checkAttrType != NULL)
  2236. {
  2237. mContext->mUnreifiedModule->PopulateType(checkAttrType, BfPopulateType_DataAndMethods);
  2238. if (checkAttrType->mDefineState < BfTypeDefineState_DefinedAndMethodsSlotted)
  2239. break;
  2240. for (auto& ifaceEntry : checkAttrType->mInterfaces)
  2241. {
  2242. if ((!ifaceEntry.mInterfaceType->IsInstanceOf(mCompiler->mIComptimeMethodApply)) &&
  2243. (!ifaceEntry.mInterfaceType->IsInstanceOf(mCompiler->mIOnMethodInitTypeDef)))
  2244. continue;
  2245. prevAttrInstances.TryGetValue(checkAttrType, &irValue);
  2246. applyMethodInstance = checkAttrType->mInterfaceMethodTable[ifaceEntry.mStartInterfaceTableIdx].mMethodRef;
  2247. break;
  2248. }
  2249. if (applyMethodInstance != NULL)
  2250. break;
  2251. checkAttrType = checkAttrType->mBaseType;
  2252. checkDepth++;
  2253. }
  2254. if (applyMethodInstance == NULL)
  2255. continue;
  2256. SetAndRestoreValue<CeEmitContext*> prevEmitContext(mCompiler->mCEMachine->mCurEmitContext, &ceEmitContext);
  2257. auto ceContext = mCompiler->mCEMachine->AllocContext();
  2258. BfIRValue attrVal = ceContext->CreateAttribute(customAttribute.mRef, this, typeInstance->mConstHolder, &customAttribute);
  2259. for (int baseIdx = 0; baseIdx < checkDepth; baseIdx++)
  2260. attrVal = mBfIRBuilder->CreateExtractValue(attrVal, 0);
  2261. SizedArray<BfIRValue, 1> args;
  2262. if (!attrType->IsValuelessType())
  2263. args.Add(attrVal);
  2264. auto methodInfoType = ResolveTypeDef(mCompiler->mReflectMethodInfoTypeDef);
  2265. SizedArray<BfIRValue, 9> methodData =
  2266. {
  2267. mBfIRBuilder->CreateConstAggZero(mBfIRBuilder->MapType(methodInfoType->ToTypeInstance()->mBaseType, BfIRPopulateType_Identity)),
  2268. mBfIRBuilder->CreateTypeOf(mCurTypeInstance), // mTypeInstance
  2269. GetConstValue((int64)methodInstance, GetPrimitiveType(BfTypeCode_Int64)), // mNativeMethodInstance
  2270. };
  2271. FixConstValueParams(methodInfoType->ToTypeInstance(), methodData, true);
  2272. auto fieldDataAgg = mBfIRBuilder->CreateConstAgg(mBfIRBuilder->MapType(methodInfoType, BfIRPopulateType_Identity), methodData);
  2273. args.Add(fieldDataAgg);
  2274. if (applyMethodInstance->GetParamCount() > 1)
  2275. {
  2276. if (irValue)
  2277. args.Add(irValue);
  2278. else
  2279. args.Add(mBfIRBuilder->CreateConstNull());
  2280. }
  2281. else
  2282. {
  2283. // Only allow a single instance
  2284. if (irValue)
  2285. continue;
  2286. }
  2287. mCompiler->mCEMachine->mMethodInstanceSet.Add(methodInstance);
  2288. auto activeTypeDef = typeInstance->mTypeDef;
  2289. BfTypedValue result;
  2290. ///
  2291. {
  2292. SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, true);
  2293. result = ceContext->Call(customAttribute.mRef, this, applyMethodInstance, args, CeEvalFlags_ForceReturnThis, NULL);
  2294. }
  2295. if (result.mType == methodInstance->GetOwner())
  2296. prevAttrInstances[methodInstance->GetOwner()] = result.mValue;
  2297. if ((!result) && (mCompiler->mFastFinish))
  2298. {
  2299. methodInstance->mCeCancelled = true;
  2300. }
  2301. if ((!ceEmitContext.mEmitData.IsEmpty()) || (!ceEmitContext.mExitEmitData.IsEmpty()))
  2302. {
  2303. String src;
  2304. src += "// Code emission in comptime ApplyToMethod of ";
  2305. src += TypeToString(attrType);
  2306. src += " to ";
  2307. src += MethodToString(methodInstance);
  2308. src += " ";
  2309. src += customAttribute.mRef->LocationToString();
  2310. src += "\n";
  2311. //auto emitTypeDef = typeInstance->mCeTypeInfo->mNext->mTypeDef;
  2312. //auto emitParser = emitTypeDef->mSource->ToParser();
  2313. //auto emitParser = activeTypeDef->mEmitParser;
  2314. BfReducer bfReducer;
  2315. //bfReducer.mSource = emitParser;
  2316. bfReducer.mPassInstance = mCompiler->mPassInstance;
  2317. bfReducer.mSystem = mSystem;
  2318. bfReducer.mCurTypeDecl = activeTypeDef->mTypeDeclaration;
  2319. bfReducer.mCurMethodDecl = BfNodeDynCast<BfMethodDeclaration>(methodInstance->mMethodDef->mMethodDeclaration);
  2320. if (!ceEmitContext.mEmitData.IsEmpty())
  2321. {
  2322. SetAndRestoreValue<BfAstNode*> prevCustomAttribute(mCurMethodState->mEmitRefNode, customAttribute.mRef);
  2323. String entrySrc = src;
  2324. if (mCurTypeInstance->mTypeDef->mEmitParent != NULL)
  2325. entrySrc += "\n\n";
  2326. entrySrc += src;
  2327. entrySrc += ceEmitContext.mEmitData;
  2328. BfCEParseContext ceParseContext = CEEmitParse(typeInstance, entrySrc);
  2329. auto emitParser = mCurTypeInstance->mTypeDef->mSource->ToParser();
  2330. bfReducer.mSource = emitParser;
  2331. bfReducer.mAlloc = emitParser->mAlloc;
  2332. bfReducer.HandleBlock(emitParser->mRootNode, false);
  2333. Visit(emitParser->mRootNode);
  2334. FinishCEParseContext(customAttribute.mRef, typeInstance, &ceParseContext);
  2335. }
  2336. if (!ceEmitContext.mExitEmitData.IsEmpty())
  2337. {
  2338. String exitSrc;
  2339. if (mCurTypeInstance->mTypeDef->mEmitParent != NULL)
  2340. exitSrc += "\n\n";
  2341. exitSrc += src;
  2342. exitSrc += ceEmitContext.mExitEmitData;
  2343. BfCEParseContext ceParseContext = CEEmitParse(typeInstance, exitSrc);
  2344. auto emitParser = mCurTypeInstance->mTypeDef->mSource->ToParser();
  2345. bfReducer.mSource = emitParser;
  2346. bfReducer.mAlloc = emitParser->mAlloc;
  2347. bfReducer.HandleBlock(emitParser->mRootNode, false);
  2348. auto deferredBlock = AddDeferredBlock(emitParser->mRootNode, &mCurMethodState->mHeadScope);
  2349. deferredBlock->mEmitRefNode = customAttribute.mRef;
  2350. FinishCEParseContext(customAttribute.mRef, typeInstance, &ceParseContext);
  2351. }
  2352. }
  2353. mCompiler->mCEMachine->ReleaseContext(ceContext);
  2354. }
  2355. }
  2356. void BfModule::DoPopulateType_SetGenericDependencies(BfTypeInstance* genericTypeInstance)
  2357. {
  2358. // Add generic dependencies if needed
  2359. for (auto genericType : genericTypeInstance->mGenericTypeInfo->mTypeGenericArguments)
  2360. {
  2361. if (genericType->IsPrimitiveType())
  2362. genericType = GetWrappedStructType(genericType);
  2363. if (genericType != NULL)
  2364. {
  2365. AddDependency(genericType, genericTypeInstance, BfDependencyMap::DependencyFlag_TypeGenericArg);
  2366. BfLogSysM("Adding generic dependency of %p for type %p\n", genericType, genericTypeInstance);
  2367. }
  2368. }
  2369. if ((genericTypeInstance->IsSpecializedType()) &&
  2370. (!genericTypeInstance->IsDelegateFromTypeRef()) &&
  2371. (!genericTypeInstance->IsFunctionFromTypeRef()))
  2372. {
  2373. // This ensures we rebuild the unspecialized type whenever the specialized type rebuilds. This is important
  2374. // for generic type binding
  2375. auto unspecializedTypeInstance = GetUnspecializedTypeInstance(genericTypeInstance);
  2376. BF_ASSERT(!unspecializedTypeInstance->IsUnspecializedTypeVariation());
  2377. mContext->mScratchModule->AddDependency(genericTypeInstance, unspecializedTypeInstance, BfDependencyMap::DependencyFlag_UnspecializedType);
  2378. }
  2379. }
  2380. void BfModule::DoPopulateType_TypeAlias(BfTypeAliasType* typeAlias)
  2381. {
  2382. SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, typeAlias);
  2383. SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, NULL);
  2384. SetAndRestoreValue<BfMethodState*> prevMethodState(mCurMethodState, NULL);
  2385. BF_ASSERT(mCurMethodInstance == NULL);
  2386. auto typeDef = typeAlias->mTypeDef;
  2387. auto typeAliasDecl = (BfTypeAliasDeclaration*)typeDef->mTypeDeclaration;
  2388. BfType* aliasToType = NULL;
  2389. if (typeAlias->mBaseType == NULL)
  2390. typeAlias->mBaseType = ResolveTypeDef(mCompiler->mValueTypeTypeDef)->ToTypeInstance();
  2391. if ((typeAlias->mGenericTypeInfo != NULL) && (!typeAlias->mGenericTypeInfo->mFinishedGenericParams))
  2392. FinishGenericParams(typeAlias);
  2393. BfTypeState typeState(mCurTypeInstance, mContext->mCurTypeState);
  2394. typeState.mPopulateType = BfPopulateType_Data;
  2395. typeState.mCurBaseTypeRef = typeAliasDecl->mAliasToType;
  2396. SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
  2397. if (typeAlias->mDefineState < BfTypeDefineState_Declaring)
  2398. {
  2399. typeAlias->mDefineState = BfTypeDefineState_Declaring;
  2400. DoPopulateType_InitSearches(typeAlias);
  2401. }
  2402. typeAlias->mDefineState = BfTypeDefineState_ResolvingBaseType;
  2403. if (!CheckCircularDataError())
  2404. {
  2405. if (typeAliasDecl->mAliasToType != NULL)
  2406. aliasToType = ResolveTypeRef(typeAliasDecl->mAliasToType, BfPopulateType_IdentityNoRemapAlias);
  2407. }
  2408. BfLogSysM("DoPopulateType_TypeAlias %p %s = %p %s\n", typeAlias, TypeToString(typeAlias).c_str(), aliasToType, (aliasToType != NULL) ? TypeToString(aliasToType).c_str() : NULL);
  2409. if (aliasToType != NULL)
  2410. {
  2411. if (aliasToType->IsConstExprValue())
  2412. {
  2413. Fail(StrFormat("Illegal alias to type '%s'", TypeToString(aliasToType).c_str()), typeAlias->mTypeDef->GetRefNode());
  2414. aliasToType = NULL;
  2415. }
  2416. }
  2417. if (aliasToType != NULL)
  2418. {
  2419. AddDependency(aliasToType, typeAlias, BfDependencyMap::DependencyFlag_DerivedFrom);
  2420. }
  2421. else
  2422. mContext->mFailTypes.Add(typeAlias);
  2423. if (typeAlias->mTypeFailed)
  2424. aliasToType = NULL;
  2425. if ((typeAlias->mAliasToType != NULL) && (typeAlias->mAliasToType != aliasToType) && (!typeAlias->mDependencyMap.IsEmpty()))
  2426. mContext->RebuildDependentTypes_MidCompile(typeAlias, "type alias remapped");
  2427. typeAlias->mAliasToType = aliasToType;
  2428. if (aliasToType != NULL)
  2429. {
  2430. typeAlias->mSize = aliasToType->mSize;
  2431. typeAlias->mAlign = aliasToType->mAlign;
  2432. if (auto aliasToTypeInst = aliasToType->ToTypeInstance())
  2433. {
  2434. typeAlias->mInstSize = aliasToTypeInst->mInstSize;
  2435. typeAlias->mInstAlign = aliasToTypeInst->mInstAlign;
  2436. }
  2437. else
  2438. {
  2439. typeAlias->mInstSize = aliasToType->mSize;
  2440. typeAlias->mInstAlign = aliasToType->mAlign;
  2441. }
  2442. }
  2443. else
  2444. {
  2445. typeAlias->mSize = 0;
  2446. typeAlias->mAlign = 1;
  2447. typeAlias->mInstSize = 0;
  2448. typeAlias->mInstAlign = 1;
  2449. }
  2450. typeAlias->mDefineState = BfTypeDefineState_DefinedAndMethodsSlotted;
  2451. typeAlias->mRebuildFlags = BfTypeRebuildFlag_None;
  2452. if ((typeAlias->mCustomAttributes == NULL) && (typeDef->mTypeDeclaration != NULL) && (typeDef->mTypeDeclaration->mAttributes != NULL))
  2453. typeAlias->mCustomAttributes = GetCustomAttributes(typeDef->mTypeDeclaration->mAttributes, BfAttributeTargets_Alias);
  2454. if (typeAlias->mGenericTypeInfo != NULL)
  2455. {
  2456. DoPopulateType_SetGenericDependencies(typeAlias);
  2457. }
  2458. }
  2459. void BfModule::DoPopulateType_InitSearches(BfTypeInstance* typeInstance)
  2460. {
  2461. auto typeDef = typeInstance->mTypeDef;
  2462. if (typeInstance->IsGenericTypeInstance())
  2463. {
  2464. DoPopulateType_SetGenericDependencies(typeInstance);
  2465. }
  2466. auto _AddStaticSearch = [&](BfTypeDef* typeDef)
  2467. {
  2468. if (!typeDef->mStaticSearch.IsEmpty())
  2469. {
  2470. BfStaticSearch* staticSearch;
  2471. if (typeInstance->mStaticSearchMap.TryAdd(typeDef, NULL, &staticSearch))
  2472. {
  2473. SetAndRestoreValue<BfTypeDef*> prevTypeDef(mContext->mCurTypeState->mCurTypeDef, typeDef);
  2474. for (auto typeRef : typeDef->mStaticSearch)
  2475. {
  2476. auto staticType = ResolveTypeRef(typeRef, NULL, BfPopulateType_Identity);
  2477. if (staticType != NULL)
  2478. {
  2479. auto staticTypeInst = staticType->ToTypeInstance();
  2480. if (staticTypeInst == NULL)
  2481. {
  2482. Fail(StrFormat("Type '%s' cannot be used in a 'using static' declaration", TypeToString(staticType).c_str()), typeRef);
  2483. }
  2484. else
  2485. {
  2486. staticSearch->mStaticTypes.Add(staticTypeInst);
  2487. AddDependency(staticTypeInst, typeInstance, BfDependencyMap::DependencyFlag_StaticValue);
  2488. }
  2489. }
  2490. }
  2491. }
  2492. }
  2493. if (!typeDef->mInternalAccessSet.IsEmpty())
  2494. {
  2495. BfInternalAccessSet* internalAccessSet;
  2496. BF_ASSERT(!typeDef->IsEmitted());
  2497. if (typeInstance->mInternalAccessMap.TryAdd(typeDef, NULL, &internalAccessSet))
  2498. {
  2499. for (auto typeRef : typeDef->mInternalAccessSet)
  2500. {
  2501. if ((typeRef->IsA<BfNamedTypeReference>()) ||
  2502. (typeRef->IsA<BfQualifiedTypeReference>()))
  2503. {
  2504. String checkNamespaceStr;
  2505. typeRef->ToString(checkNamespaceStr);
  2506. BfAtomComposite checkNamespace;
  2507. if (mSystem->ParseAtomComposite(checkNamespaceStr, checkNamespace))
  2508. {
  2509. if (mSystem->ContainsNamespace(checkNamespace, typeDef->mProject))
  2510. {
  2511. mSystem->RefAtomComposite(checkNamespace);
  2512. internalAccessSet->mNamespaces.Add(checkNamespace);
  2513. continue;
  2514. }
  2515. }
  2516. }
  2517. BfType* internalType = NULL;
  2518. if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef))
  2519. internalType = mContext->mScratchModule->ResolveTypeRefAllowUnboundGenerics(typeRef, BfPopulateType_Identity);
  2520. else
  2521. internalType = ResolveTypeRef(typeRef, NULL, BfPopulateType_Identity);
  2522. if (internalType != NULL)
  2523. {
  2524. auto internalTypeInst = internalType->ToTypeInstance();
  2525. if (internalTypeInst == NULL)
  2526. {
  2527. Fail(StrFormat("Type '%s' cannot be used in a 'using internal' declaration", TypeToString(internalType).c_str()), typeRef);
  2528. }
  2529. else
  2530. {
  2531. internalAccessSet->mTypes.Add(internalTypeInst);
  2532. AddDependency(internalTypeInst, typeInstance, BfDependencyMap::DependencyFlag_StaticValue);
  2533. }
  2534. }
  2535. }
  2536. }
  2537. }
  2538. };
  2539. if (typeDef->mIsCombinedPartial)
  2540. {
  2541. for (auto partialTypeDef : typeDef->mPartials)
  2542. _AddStaticSearch(partialTypeDef);
  2543. }
  2544. else
  2545. _AddStaticSearch(typeDef);
  2546. }
  2547. void BfModule::DoPopulateType_FinishEnum(BfTypeInstance* typeInstance, bool underlyingTypeDeferred, HashContext* dataMemberHashCtx, BfType* unionInnerType)
  2548. {
  2549. if (typeInstance->IsEnum())
  2550. {
  2551. int64 min = 0;
  2552. int64 max = 0;
  2553. bool isFirst = true;
  2554. if (typeInstance->mTypeInfoEx == NULL)
  2555. typeInstance->mTypeInfoEx = new BfTypeInfoEx();
  2556. bool isAllInt64 = true;
  2557. for (auto& fieldInstanceRef : typeInstance->mFieldInstances)
  2558. {
  2559. auto fieldInstance = &fieldInstanceRef;
  2560. auto fieldDef = fieldInstance->GetFieldDef();
  2561. if ((fieldDef != NULL) && (fieldDef->IsEnumCaseEntry()))
  2562. {
  2563. if (fieldInstance->mConstIdx == -1)
  2564. continue;
  2565. auto constant = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
  2566. if (constant->mTypeCode != BfTypeCode_Int64)
  2567. isAllInt64 = false;
  2568. if (isFirst)
  2569. {
  2570. min = constant->mInt64;
  2571. max = constant->mInt64;
  2572. isFirst = false;
  2573. }
  2574. else
  2575. {
  2576. min = BF_MIN(constant->mInt64, min);
  2577. max = BF_MAX(constant->mInt64, max);
  2578. }
  2579. }
  2580. }
  2581. typeInstance->mTypeInfoEx->mMinValue = min;
  2582. typeInstance->mTypeInfoEx->mMaxValue = max;
  2583. if (underlyingTypeDeferred)
  2584. {
  2585. BfTypeCode typeCode;
  2586. if ((min >= -0x80) && (max <= 0x7F))
  2587. typeCode = BfTypeCode_Int8;
  2588. else if ((min >= 0) && (max <= 0xFF))
  2589. typeCode = BfTypeCode_UInt8;
  2590. else if ((min >= -0x8000) && (max <= 0x7FFF))
  2591. typeCode = BfTypeCode_Int16;
  2592. else if ((min >= 0) && (max <= 0xFFFF))
  2593. typeCode = BfTypeCode_UInt16;
  2594. else if ((min >= -0x80000000LL) && (max <= 0x7FFFFFFF))
  2595. typeCode = BfTypeCode_Int32;
  2596. else if ((min >= 0) && (max <= 0xFFFFFFFFLL))
  2597. typeCode = BfTypeCode_UInt32;
  2598. else
  2599. typeCode = BfTypeCode_Int64;
  2600. if (typeInstance->mIsCRepr)
  2601. typeCode = BfTypeCode_Int32;
  2602. if ((typeCode != BfTypeCode_Int64) || (!isAllInt64))
  2603. {
  2604. for (auto& fieldInstanceRef : typeInstance->mFieldInstances)
  2605. {
  2606. auto fieldInstance = &fieldInstanceRef;
  2607. if (fieldInstance->mConstIdx == -1)
  2608. continue;
  2609. if (!fieldInstance->GetFieldDef()->IsEnumCaseEntry())
  2610. continue;
  2611. auto constant = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
  2612. if (constant->mTypeCode == typeCode)
  2613. continue;
  2614. BfIRValue newConstant = typeInstance->mConstHolder->CreateConst(typeCode, constant->mUInt64);
  2615. fieldInstance->mConstIdx = newConstant.mId;
  2616. }
  2617. }
  2618. BfType* underlyingType = GetPrimitiveType(typeCode);
  2619. auto fieldInstance = &typeInstance->mFieldInstances.back();
  2620. fieldInstance->mResolvedType = underlyingType;
  2621. fieldInstance->mDataSize = underlyingType->mSize;
  2622. typeInstance->mTypeInfoEx->mUnderlyingType = underlyingType;
  2623. typeInstance->mSize = underlyingType->mSize;
  2624. typeInstance->mAlign = underlyingType->mAlign;
  2625. typeInstance->mInstSize = underlyingType->mSize;
  2626. typeInstance->mInstAlign = underlyingType->mAlign;
  2627. typeInstance->mRebuildFlags = (BfTypeRebuildFlags)(typeInstance->mRebuildFlags & ~BfTypeRebuildFlag_UnderlyingTypeDeferred);
  2628. }
  2629. }
  2630. else
  2631. {
  2632. BF_ASSERT(!underlyingTypeDeferred);
  2633. }
  2634. if ((typeInstance->IsPayloadEnum()) && (!typeInstance->IsBoxed()))
  2635. {
  2636. typeInstance->mAlign = unionInnerType->mAlign;
  2637. int lastTagId = -1;
  2638. for (auto& fieldInstanceRef : typeInstance->mFieldInstances)
  2639. {
  2640. auto fieldInstance = &fieldInstanceRef;
  2641. auto fieldDef = fieldInstance->GetFieldDef();
  2642. if ((fieldDef != NULL) && (fieldInstance->mDataIdx < 0))
  2643. {
  2644. BF_ASSERT(fieldInstance->mResolvedType->mAlign >= 1);
  2645. typeInstance->mAlign = BF_MAX(typeInstance->mAlign, fieldInstance->mResolvedType->mAlign);
  2646. lastTagId = -fieldInstance->mDataIdx - 1;
  2647. }
  2648. }
  2649. auto fieldInstance = &typeInstance->mFieldInstances.back();
  2650. //BF_ASSERT(fieldInstance->mResolvedType == NULL);
  2651. BfPrimitiveType* discriminatorType;
  2652. if (lastTagId > 0x7FFFFFFF) // HOW?
  2653. discriminatorType = GetPrimitiveType(BfTypeCode_Int64);
  2654. else if (lastTagId > 0x7FFF)
  2655. discriminatorType = GetPrimitiveType(BfTypeCode_Int32);
  2656. else if (lastTagId > 0x7F)
  2657. discriminatorType = GetPrimitiveType(BfTypeCode_Int16);
  2658. else
  2659. discriminatorType = GetPrimitiveType(BfTypeCode_Int8);
  2660. fieldInstance->mResolvedType = discriminatorType;
  2661. fieldInstance->mDataOffset = unionInnerType->mSize;
  2662. fieldInstance->mDataIdx = 2; // 0 = base, 1 = payload, 2 = discriminator
  2663. if (typeInstance->mPacking == 0)
  2664. {
  2665. if ((fieldInstance->mDataOffset % discriminatorType->mAlign) != 0)
  2666. {
  2667. fieldInstance->mDataOffset = BF_ALIGN(fieldInstance->mDataOffset, discriminatorType->mAlign);
  2668. fieldInstance->mDataIdx++; // Add room for explicit padding
  2669. }
  2670. }
  2671. typeInstance->mAlign = BF_MAX(typeInstance->mAlign, discriminatorType->mAlign);
  2672. typeInstance->mSize = fieldInstance->mDataOffset + discriminatorType->mSize;
  2673. typeInstance->mInstSize = typeInstance->mSize;
  2674. typeInstance->mInstAlign = typeInstance->mAlign;
  2675. if (dataMemberHashCtx != NULL)
  2676. {
  2677. dataMemberHashCtx->Mixin(unionInnerType->mTypeId);
  2678. dataMemberHashCtx->Mixin(discriminatorType->mTypeId);
  2679. }
  2680. typeInstance->mMergedFieldDataCount = 1; // Track it as a single entry
  2681. }
  2682. }
  2683. void BfModule::DoPopulateType_CeCheckEnum(BfTypeInstance* typeInstance, bool underlyingTypeDeferred)
  2684. {
  2685. if (!typeInstance->IsEnum())
  2686. return;
  2687. if ((!underlyingTypeDeferred) && (!typeInstance->IsPayloadEnum()))
  2688. return;
  2689. if ((typeInstance->mCeTypeInfo != NULL) && (typeInstance->mCeTypeInfo->mNext != NULL))
  2690. return;
  2691. BfType* unionInnerType = NULL;
  2692. if (typeInstance->mIsUnion)
  2693. {
  2694. SetAndRestoreValue<BfTypeState::ResolveKind> prevResolveKind(mContext->mCurTypeState->mResolveKind, BfTypeState::ResolveKind_UnionInnerType);
  2695. unionInnerType = typeInstance->GetUnionInnerType();
  2696. }
  2697. DoPopulateType_FinishEnum(typeInstance, underlyingTypeDeferred, NULL, unionInnerType);
  2698. }
  2699. void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateType)
  2700. {
  2701. if (populateType == BfPopulateType_Identity)
  2702. return;
  2703. auto typeInstance = resolvedTypeRef->ToTypeInstance();
  2704. auto typeDef = typeInstance->mTypeDef;
  2705. BF_ASSERT((typeInstance->mTypeDef->mNextRevision == NULL) || (mCompiler->IsAutocomplete()));
  2706. // This is a special case where our base type has been rebuilt but we haven't
  2707. if ((typeInstance->mBaseTypeMayBeIncomplete) && (!typeInstance->mTypeIncomplete))
  2708. {
  2709. BfLogSysM("BaseTypeMayBeIncomplete processing. Type:%p -> Base:%p\n", typeInstance, typeInstance->mBaseType);
  2710. PopulateType(typeInstance->mBaseType, populateType);
  2711. if (!typeInstance->mBaseType->IsIncomplete())
  2712. typeInstance->mBaseTypeMayBeIncomplete = false;
  2713. if (!typeInstance->mTypeIncomplete)
  2714. return;
  2715. }
  2716. typeInstance->mBaseTypeMayBeIncomplete = false;
  2717. BF_ASSERT(mIsModuleMutable);
  2718. // Don't do type instance method processing for an autocomplete pass - this will get handled later on during
  2719. // the PopulateType worklist pass in the full resolver. We do need to handle the methods for delegates, though,
  2720. // since those can affect method declarations of other methods
  2721. // TODO: Investigate this "Delegate" claim
  2722. bool canDoMethodProcessing = ((mCompiler->mResolvePassData == NULL) || (mCompiler->mResolvePassData->mAutoComplete == NULL) /*|| (typeInstance->IsDelegate())*/);
  2723. if (populateType == BfPopulateType_Full_Force)
  2724. canDoMethodProcessing = true;
  2725. if (typeInstance->mResolvingConstField)
  2726. return;
  2727. auto _CheckTypeDone = [&]()
  2728. {
  2729. if (typeInstance->mNeedsMethodProcessing)
  2730. {
  2731. BF_ASSERT(typeInstance->mDefineState >= BfTypeDefineState_Defined);
  2732. if ((canDoMethodProcessing) && (populateType >= BfPopulateType_DataAndMethods))
  2733. DoTypeInstanceMethodProcessing(typeInstance);
  2734. return true;
  2735. }
  2736. if (typeInstance->mDefineState == BfTypeDefineState_DefinedAndMethodsSlotted)
  2737. return true;
  2738. return false;
  2739. };
  2740. if (_CheckTypeDone())
  2741. return;
  2742. // Partial population break out point
  2743. if ((populateType >= BfPopulateType_Identity) && (populateType <= BfPopulateType_IdentityNoRemapAlias))
  2744. return;
  2745. if ((populateType <= BfPopulateType_AllowStaticMethods) && (typeInstance->mDefineState >= BfTypeDefineState_HasInterfaces))
  2746. return;
  2747. if (!resolvedTypeRef->IsValueType())
  2748. {
  2749. resolvedTypeRef->mSize = typeInstance->mAlign = mSystem->mPtrSize;
  2750. }
  2751. BF_ASSERT((typeInstance->mMethodInstanceGroups.size() == 0) || (typeInstance->mMethodInstanceGroups.size() == typeDef->mMethods.size()) || (typeInstance->mCeTypeInfo != NULL) || (typeInstance->IsBoxed()));
  2752. typeInstance->mMethodInstanceGroups.Resize(typeDef->mMethods.size());
  2753. for (int i = 0; i < (int)typeInstance->mMethodInstanceGroups.size(); i++)
  2754. {
  2755. typeInstance->mMethodInstanceGroups[i].mOwner = typeInstance;
  2756. typeInstance->mMethodInstanceGroups[i].mMethodIdx = i;
  2757. }
  2758. AutoDisallowYield disableYield(mSystem);
  2759. SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, typeInstance);
  2760. SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, NULL);
  2761. SetAndRestoreValue<BfMethodState*> prevMethodState(mCurMethodState, NULL);
  2762. // WHY were we clearing these values?
  2763. //SetAndRestoreValue<bool> prevHadError(mHadBuildError, false);
  2764. //SetAndRestoreValue<bool> prevHadWarning(mHadBuildWarning, false);
  2765. BfTypeState typeState(mCurTypeInstance, mContext->mCurTypeState);
  2766. typeState.mPopulateType = populateType;
  2767. SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
  2768. if (typeInstance->IsGenericTypeInstance())
  2769. {
  2770. auto genericTypeInst = (BfTypeInstance*)typeInstance;
  2771. if (!genericTypeInst->mGenericTypeInfo->mInitializedGenericParams)
  2772. InitGenericParams(resolvedTypeRef);
  2773. }
  2774. if (resolvedTypeRef->IsTypeAlias())
  2775. {
  2776. prevTypeState.Restore();
  2777. DoPopulateType_TypeAlias((BfTypeAliasType*)typeInstance);
  2778. typeInstance->mTypeIncomplete = false;
  2779. resolvedTypeRef->mRebuildFlags = BfTypeRebuildFlag_None;
  2780. resolvedTypeRef->mDefineState = BfTypeDefineState_DefinedAndMethodsSlotted;
  2781. return;
  2782. }
  2783. if (_CheckTypeDone())
  2784. return;
  2785. // Don't do TypeToString until down here. Otherwise we can infinitely loop on BuildGenericParams
  2786. bool isStruct = resolvedTypeRef->IsStruct();
  2787. bool reportErrors = true;
  2788. if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL))
  2789. reportErrors = true;
  2790. // If we're not the defining context then we don't report errors for this type, but errors will still put the system
  2791. // into an errored state
  2792. SetAndRestoreValue<bool> prevReportErrors(mReportErrors, reportErrors);
  2793. if (typeInstance->mIsFinishingType)
  2794. {
  2795. if (typeInstance->mTypeFailed)
  2796. return;
  2797. }
  2798. if (!typeInstance->mTypeFailed)
  2799. CheckCircularDataError();
  2800. if (typeInstance->mDefineState < BfTypeDefineState_Declaring)
  2801. {
  2802. typeInstance->mDefineState = BfTypeDefineState_Declaring;
  2803. DoPopulateType_InitSearches(typeInstance);
  2804. }
  2805. bool underlyingTypeDeferred = false;
  2806. BfType* underlyingType = NULL;
  2807. if (typeInstance->mBaseType != NULL)
  2808. {
  2809. if (typeInstance->IsTypedPrimitive())
  2810. underlyingType = typeInstance->GetUnderlyingType();
  2811. if ((typeInstance->mRebuildFlags & BfTypeRebuildFlag_UnderlyingTypeDeferred) != 0)
  2812. underlyingTypeDeferred = true;
  2813. }
  2814. else if (typeInstance->IsEnum())
  2815. {
  2816. bool hasPayloads = false;
  2817. for (auto fieldDef : typeDef->mFields)
  2818. {
  2819. if ((fieldDef->IsEnumCaseEntry()) && (fieldDef->mTypeRef != NULL))
  2820. {
  2821. hasPayloads = true;
  2822. break;
  2823. }
  2824. }
  2825. if (!hasPayloads)
  2826. {
  2827. bool hadType = false;
  2828. BfAstNode* deferredErrorNode = NULL;
  2829. char* deferredError = NULL;
  2830. for (auto baseTypeRef : typeDef->mBaseTypes)
  2831. {
  2832. SetAndRestoreValue<BfTypeReference*> prevTypeRef(mContext->mCurTypeState->mCurBaseTypeRef, baseTypeRef);
  2833. SetAndRestoreValue<BfTypeDefineState> prevDefineState(typeInstance->mDefineState, BfTypeDefineState_ResolvingBaseType);
  2834. SetAndRestoreValue<bool> prevIgnoreError(mIgnoreErrors, true);
  2835. SetAndRestoreValue<bool> prevSkipTypeProtectionChecks(typeInstance->mSkipTypeProtectionChecks, true);
  2836. auto baseType = ResolveTypeRef(baseTypeRef, BfPopulateType_Declaration);
  2837. if (baseType != NULL)
  2838. {
  2839. if (baseType->IsIntegral())
  2840. {
  2841. if (!hadType)
  2842. {
  2843. hadType = true;
  2844. underlyingType = baseType;
  2845. }
  2846. else
  2847. {
  2848. deferredError = "Underlying enum type already specified";
  2849. deferredErrorNode = baseTypeRef;
  2850. }
  2851. }
  2852. else
  2853. {
  2854. deferredError = "Invalid underlying enum type";
  2855. deferredErrorNode = baseTypeRef;
  2856. }
  2857. }
  2858. else
  2859. {
  2860. AssertErrorState();
  2861. TypeFailed(typeInstance);
  2862. }
  2863. }
  2864. if (deferredError != NULL)
  2865. Fail(deferredError, deferredErrorNode, true);
  2866. if (underlyingType == NULL)
  2867. {
  2868. underlyingType = GetPrimitiveType(BfTypeCode_Int64);
  2869. underlyingTypeDeferred = true;
  2870. }
  2871. }
  2872. }
  2873. // else if (typeInstance->IsFunction())
  2874. // {
  2875. // underlyingType = GetPrimitiveType(BfTypeCode_NullPtr);
  2876. // }
  2877. else if (((typeInstance->IsStruct()) || (typeInstance->IsTypedPrimitive())) &&
  2878. (!typeInstance->mTypeFailed))
  2879. {
  2880. for (auto baseTypeRef : typeDef->mBaseTypes)
  2881. {
  2882. auto declTypeDef = typeDef;
  2883. if (typeDef->mIsCombinedPartial)
  2884. declTypeDef = typeDef->mPartials.front();
  2885. SetAndRestoreValue<BfTypeDef*> prevTypeDef(mContext->mCurTypeState->mCurTypeDef, declTypeDef);
  2886. SetAndRestoreValue<BfTypeDefineState> prevDefineState(typeInstance->mDefineState, BfTypeDefineState_ResolvingBaseType);
  2887. SetAndRestoreValue<BfTypeReference*> prevTypeRef(mContext->mCurTypeState->mCurBaseTypeRef, baseTypeRef);
  2888. // We ignore errors here to avoid double-errors for type lookups, but this is where data cycles are detected
  2889. // but that type of error supersedes the mIgnoreErrors setting
  2890. SetAndRestoreValue<bool> prevIgnoreError(mIgnoreErrors, true);
  2891. // Temporarily allow us to derive from private classes, to avoid infinite loop from TypeIsSubTypeOf
  2892. SetAndRestoreValue<bool> prevSkipTypeProtectionChecks(typeInstance->mSkipTypeProtectionChecks, true);
  2893. auto baseType = ResolveTypeRef(baseTypeRef, BfPopulateType_Declaration);
  2894. if (baseType != NULL)
  2895. {
  2896. if (baseType->IsVar())
  2897. {
  2898. // Ignore
  2899. }
  2900. else if (baseType->IsPrimitiveType())
  2901. {
  2902. underlyingType = baseType;
  2903. }
  2904. else if (baseType->IsTypedPrimitive())
  2905. {
  2906. //PopulateType(baseType, true);
  2907. underlyingType = baseType->GetUnderlyingType();
  2908. BF_ASSERT(underlyingType != NULL);
  2909. }
  2910. }
  2911. else
  2912. {
  2913. AssertErrorState();
  2914. TypeFailed(typeInstance);
  2915. }
  2916. if (_CheckTypeDone())
  2917. {
  2918. prevDefineState.CancelRestore();
  2919. return;
  2920. }
  2921. }
  2922. // Incase we had re-entry, work this through ourselves again here
  2923. typeInstance->mIsTypedPrimitive = false;
  2924. }
  2925. if (underlyingTypeDeferred)
  2926. typeInstance->mRebuildFlags = (BfTypeRebuildFlags)(typeInstance->mRebuildFlags | BfTypeRebuildFlag_UnderlyingTypeDeferred);
  2927. typeInstance->mIsTypedPrimitive = underlyingType != NULL;
  2928. int wantFieldCount = (int)typeDef->mFields.size() + (((underlyingType != NULL) || (typeInstance->IsPayloadEnum())) ? 1 : 0);
  2929. if ((int)typeInstance->mFieldInstances.size() < wantFieldCount)
  2930. {
  2931. // Closures don't include the enclosed fields on their first pass through PopulateType, and they have no typeDef of their own
  2932. // so we need to take care not to truncate their fieldInstance vector here (thus the 'wantFieldCount' check above)
  2933. typeInstance->mFieldInstances.Resize(wantFieldCount);
  2934. }
  2935. if (underlyingType != NULL)
  2936. {
  2937. auto fieldInstance = &typeInstance->mFieldInstances.back();
  2938. fieldInstance->mDataOffset = 0;
  2939. fieldInstance->mDataSize = underlyingType->mSize;
  2940. fieldInstance->mOwner = typeInstance;
  2941. fieldInstance->mResolvedType = underlyingType;
  2942. typeInstance->mSize = underlyingType->mSize;
  2943. typeInstance->mAlign = underlyingType->mAlign;
  2944. typeInstance->mInstSize = underlyingType->mSize;
  2945. typeInstance->mInstAlign = underlyingType->mAlign;
  2946. typeInstance->mHasPackingHoles = underlyingType->HasPackingHoles();
  2947. }
  2948. // Partial population break out point
  2949. if (typeInstance->mDefineState < BfTypeDefineState_Declared)
  2950. typeInstance->mDefineState = BfTypeDefineState_Declared;
  2951. if (populateType == BfPopulateType_Declaration)
  2952. {
  2953. return;
  2954. }
  2955. if ((!mCompiler->mIsResolveOnly) && (!typeInstance->HasBeenInstantiated()))
  2956. {
  2957. for (auto& dep : typeInstance->mDependencyMap)
  2958. {
  2959. auto& depEntry = dep.mValue;
  2960. if ((depEntry.mFlags & BfDependencyMap::DependencyFlag_Allocates) != 0)
  2961. {
  2962. auto depType = dep.mKey;
  2963. if (depType->mRevision == depEntry.mRevision)
  2964. {
  2965. BfLogSysM("Setting mHasBeenInstantiated for %p instantiated from %p\n", typeInstance, depType);
  2966. typeInstance->mHasBeenInstantiated = true;
  2967. }
  2968. }
  2969. }
  2970. }
  2971. //BfLogSysM("Setting revision. Type: %p Revision: %d\n", typeInstance, mRevision);
  2972. //typeInstance->mRevision = mRevision;
  2973. // Temporarily allow us to derive from private classes, to avoid infinite loop from TypeIsSubTypeOf
  2974. SetAndRestoreValue<bool> prevSkipTypeProtectionChecks(typeInstance->mSkipTypeProtectionChecks, true);
  2975. if ((typeDef->mOuterType != NULL) && (typeDef->mOuterType->IsGlobalsContainer()))
  2976. {
  2977. if ((typeDef->mTypeDeclaration != NULL) && (typeDef->mTypeDeclaration->mTypeNode != NULL))
  2978. Fail("Global blocks cannot contain type declarations", typeDef->mTypeDeclaration->mTypeNode);
  2979. }
  2980. /// Create DI data
  2981. SizedArray<BfIRType, 8> llvmFieldTypes;
  2982. int curFieldDataIdx = 0;
  2983. typeInstance->mBaseType = NULL;
  2984. BfTypeInstance* defaultBaseTypeInst = NULL;
  2985. // Find base type
  2986. BfType* baseType = NULL;
  2987. struct BfInterfaceDecl
  2988. {
  2989. BfTypeInstance* mIFaceTypeInst;
  2990. BfTypeReference* mTypeRef;
  2991. BfTypeDef* mDeclaringType;
  2992. };
  2993. SizedArray<BfInterfaceDecl, 8> interfaces;
  2994. HashSet<BfTypeInstance*> ifaceSet;
  2995. typeInstance->mRebuildFlags = (BfTypeRebuildFlags)(typeInstance->mRebuildFlags | BfTypeRebuildFlag_ResolvingBase);
  2996. if (resolvedTypeRef == mContext->mBfObjectType)
  2997. {
  2998. baseType = NULL;
  2999. }
  3000. else if (typeInstance->IsEnum())
  3001. {
  3002. if (mCompiler->mEnumTypeDef == NULL)
  3003. {
  3004. Fail("Enum type required");
  3005. TypeFailed(typeInstance);
  3006. }
  3007. else
  3008. baseType = ResolveTypeDef(mCompiler->mEnumTypeDef)->ToTypeInstance();
  3009. }
  3010. else if (resolvedTypeRef->IsObject())
  3011. baseType = mContext->mBfObjectType;
  3012. else if (resolvedTypeRef->IsPointer())
  3013. {
  3014. baseType = ResolveTypeDef(mCompiler->mPointerTTypeDef, BfPopulateType_Data);
  3015. }
  3016. else if ((resolvedTypeRef->IsValueType()) && (typeDef != mCompiler->mValueTypeTypeDef))
  3017. {
  3018. baseType = ResolveTypeDef(mCompiler->mValueTypeTypeDef, BfPopulateType_Data)->ToTypeInstance();
  3019. }
  3020. if (baseType != NULL)
  3021. defaultBaseTypeInst = baseType->ToTypeInstance();
  3022. struct _DeferredValidate
  3023. {
  3024. BfTypeReference* mTypeRef;
  3025. BfTypeInstance* mGenericType;
  3026. bool mIgnoreErrors;
  3027. };
  3028. Array<_DeferredValidate> deferredTypeValidateList;
  3029. bool wantPopulateInterfaces = false;
  3030. BfTypeReference* baseTypeRef = NULL;
  3031. if ((typeDef->mIsDelegate) && (!typeInstance->IsClosure()))
  3032. {
  3033. if (mCompiler->mDelegateTypeDef == NULL)
  3034. {
  3035. Fail("Delegate type required");
  3036. TypeFailed(typeInstance);
  3037. }
  3038. else
  3039. baseType = ResolveTypeDef(mCompiler->mDelegateTypeDef)->ToTypeInstance();
  3040. }
  3041. else if (typeDef->mIsFunction)
  3042. {
  3043. if (mCompiler->mFunctionTypeDef == NULL)
  3044. {
  3045. Fail("Function type required");
  3046. TypeFailed(typeInstance);
  3047. }
  3048. else
  3049. baseType = ResolveTypeDef(mCompiler->mFunctionTypeDef)->ToTypeInstance();
  3050. }
  3051. else
  3052. {
  3053. for (auto checkTypeRef : typeDef->mBaseTypes)
  3054. {
  3055. if ((typeInstance->mDefineState == BfTypeDefineState_ResolvingBaseType) && (typeInstance->mTypeFailed))
  3056. break;
  3057. auto declTypeDef = typeDef;
  3058. if (typeDef->mIsCombinedPartial)
  3059. declTypeDef = typeDef->mPartials.front();
  3060. SetAndRestoreValue<BfTypeDef*> prevTypeDef(mContext->mCurTypeState->mCurTypeDef, declTypeDef);
  3061. SetAndRestoreValue<BfTypeReference*> prevTypeRef(mContext->mCurTypeState->mCurBaseTypeRef, checkTypeRef);
  3062. SetAndRestoreValue<BfTypeDefineState> prevDefineState(typeInstance->mDefineState, BfTypeDefineState_ResolvingBaseType);
  3063. bool populateBase = !typeInstance->mTypeFailed;
  3064. BfType* checkType = checkType = ResolveTypeRef(checkTypeRef, BfPopulateType_Declaration);
  3065. if ((checkType != NULL) && (!checkType->IsInterface()) && (populateBase))
  3066. {
  3067. SetAndRestoreValue<BfTypeInstance*> prevBaseType(mContext->mCurTypeState->mCurBaseType, checkType->ToTypeInstance());
  3068. PopulateType(checkType, BfPopulateType_Data);
  3069. }
  3070. if (typeInstance->mDefineState >= BfTypeDefineState_Defined)
  3071. {
  3072. prevDefineState.CancelRestore();
  3073. return;
  3074. }
  3075. if (checkType != NULL)
  3076. {
  3077. if (auto genericTypeInst = checkType->ToGenericTypeInstance())
  3078. {
  3079. // Specialized type variations don't need to validate their constraints
  3080. if (!typeInstance->IsUnspecializedTypeVariation())
  3081. deferredTypeValidateList.Add({ checkTypeRef, genericTypeInst, false });
  3082. }
  3083. auto checkTypeInst = checkType->ToTypeInstance();
  3084. bool canDeriveFrom = checkTypeInst != NULL;
  3085. if ((typeInstance->IsStruct()) || (typeInstance->IsTypedPrimitive()) || (typeInstance->IsBoxed()))
  3086. canDeriveFrom |= checkType->IsPrimitiveType();
  3087. if ((typeInstance->IsEnum()) && (!checkType->IsInterface()))
  3088. {
  3089. if (typeInstance->IsTypedPrimitive())
  3090. continue;
  3091. if (checkType->IsPrimitiveType())
  3092. Fail(StrFormat("Enum '%s' cannot be specified as '%s' because it has a payload",
  3093. TypeToString(typeInstance).c_str(), TypeToString(checkType).c_str()),
  3094. checkTypeRef, true);
  3095. else
  3096. Fail("Enums cannot derive from other types", checkTypeRef);
  3097. continue;
  3098. }
  3099. if ((checkTypeInst != NULL) && (checkTypeInst->mTypeFailed))
  3100. {
  3101. // To keep circular references from breaking type invariants (ie: base type loops)
  3102. continue;
  3103. }
  3104. if (!canDeriveFrom)
  3105. {
  3106. Fail("Cannot derive from this type", checkTypeRef);
  3107. continue;
  3108. }
  3109. if (checkType->IsVar())
  3110. {
  3111. // This can't explicitly be specified, but can occur from comptime
  3112. continue;
  3113. }
  3114. if (checkType->IsInterface())
  3115. {
  3116. auto ifaceInst = checkType->ToTypeInstance();
  3117. if (ifaceSet.Add(ifaceInst))
  3118. {
  3119. // Not base type
  3120. BfInterfaceDecl ifaceDecl;
  3121. ifaceDecl.mIFaceTypeInst = ifaceInst;
  3122. ifaceDecl.mTypeRef = checkTypeRef;
  3123. ifaceDecl.mDeclaringType = typeDef->GetDefinition();
  3124. interfaces.push_back(ifaceDecl);
  3125. }
  3126. else
  3127. {
  3128. Fail(StrFormat("Interface '%s' is already specified", TypeToString(checkType).c_str()), checkTypeRef);
  3129. }
  3130. }
  3131. else if (resolvedTypeRef == mContext->mBfObjectType)
  3132. {
  3133. Fail(StrFormat("Type '%s' cannot define a base type", TypeToString(baseType).c_str()), checkTypeRef);
  3134. }
  3135. else
  3136. {
  3137. if (baseTypeRef != NULL)
  3138. {
  3139. Fail(StrFormat("Base type '%s' already declared", TypeToString(baseType).c_str()), checkTypeRef);
  3140. }
  3141. else
  3142. {
  3143. baseTypeRef = checkTypeRef;
  3144. if (checkTypeInst != NULL)
  3145. {
  3146. auto checkOuter = checkTypeInst;
  3147. while (checkOuter != NULL)
  3148. {
  3149. if (checkOuter == typeInstance)
  3150. {
  3151. Fail(StrFormat("Type '%s' cannot be declare inner type '%s' as a base type",
  3152. TypeToString(typeInstance).c_str(),
  3153. TypeToString(checkTypeInst).c_str()), checkTypeRef, true);
  3154. checkTypeInst = NULL;
  3155. break;
  3156. }
  3157. checkOuter = GetOuterType(checkOuter);
  3158. }
  3159. }
  3160. if (checkTypeInst != NULL)
  3161. {
  3162. baseType = checkTypeInst;
  3163. }
  3164. }
  3165. }
  3166. if (_CheckTypeDone())
  3167. {
  3168. prevDefineState.CancelRestore();
  3169. return;
  3170. }
  3171. }
  3172. else
  3173. {
  3174. AssertErrorState();
  3175. // Why did we go around setting mTypeFailed on all these things?
  3176. //typeInstance->mTypeFailed = true;
  3177. }
  3178. }
  3179. wantPopulateInterfaces = true;
  3180. }
  3181. if ((typeInstance->mCeTypeInfo != NULL) && (!typeInstance->mCeTypeInfo->mPendingInterfaces.IsEmpty()))
  3182. {
  3183. for (auto ifaceTypeId : typeInstance->mCeTypeInfo->mPendingInterfaces)
  3184. {
  3185. auto ifaceType = mContext->mTypes[ifaceTypeId];
  3186. if ((ifaceType == NULL) || (!ifaceType->IsInterface()))
  3187. continue;
  3188. auto ifaceInst = ifaceType->ToTypeInstance();
  3189. if (ifaceSet.Add(ifaceInst))
  3190. {
  3191. // Not base type
  3192. BfInterfaceDecl ifaceDecl;
  3193. ifaceDecl.mIFaceTypeInst = ifaceInst;
  3194. ifaceDecl.mTypeRef = NULL;
  3195. ifaceDecl.mDeclaringType = typeDef->GetDefinition();
  3196. interfaces.Add(ifaceDecl);
  3197. }
  3198. }
  3199. }
  3200. if (_CheckTypeDone())
  3201. return;
  3202. if (resolvedTypeRef->IsBoxed())
  3203. {
  3204. BfBoxedType* boxedType = (BfBoxedType*)resolvedTypeRef;
  3205. if ((baseType != NULL) && (baseType->IsStruct()))
  3206. {
  3207. BfType* modifiedBaseType = baseType;
  3208. if (boxedType->IsBoxedStructPtr())
  3209. modifiedBaseType = CreatePointerType(modifiedBaseType);
  3210. boxedType->mBoxedBaseType = CreateBoxedType(modifiedBaseType);
  3211. PopulateType(boxedType->mBoxedBaseType);
  3212. // Use derivedFrom for both the boxed base type and the unboxed type
  3213. AddDependency(boxedType->mBoxedBaseType, typeInstance, BfDependencyMap::DependencyFlag_DerivedFrom);
  3214. }
  3215. AddDependency(boxedType->mElementType, typeInstance, BfDependencyMap::DependencyFlag_ValueTypeMemberData);
  3216. baseType = mContext->mBfObjectType;
  3217. }
  3218. BfTypeInstance* baseTypeInst = NULL;
  3219. if (baseType != NULL)
  3220. {
  3221. baseTypeInst = baseType->ToTypeInstance();
  3222. }
  3223. if (typeInstance->mBaseType != NULL)
  3224. {
  3225. BF_ASSERT(typeInstance->mBaseType == baseTypeInst);
  3226. }
  3227. if (auto genericTypeInst = typeInstance->ToGenericTypeInstance())
  3228. {
  3229. if ((genericTypeInst->IsSpecializedType()) && (!genericTypeInst->mGenericTypeInfo->mValidatedGenericConstraints) && (!typeInstance->IsBoxed()))
  3230. {
  3231. deferredTypeValidateList.Add({ NULL, genericTypeInst, true });
  3232. }
  3233. }
  3234. if (!typeInstance->IsBoxed())
  3235. {
  3236. BfType* outerType = GetOuterType(typeInstance);
  3237. if (outerType != NULL)
  3238. {
  3239. PopulateType(outerType, BfPopulateType_Identity);
  3240. AddDependency(outerType, typeInstance, BfDependencyMap::DependencyFlag_OuterType);
  3241. }
  3242. }
  3243. if ((baseTypeInst != NULL) && (typeInstance->mBaseType == NULL))
  3244. {
  3245. if (typeInstance->mTypeFailed)
  3246. {
  3247. if (baseTypeInst->IsDataIncomplete())
  3248. {
  3249. if (baseTypeInst->IsStruct())
  3250. baseTypeInst = ResolveTypeDef(mCompiler->mValueTypeTypeDef)->ToTypeInstance();
  3251. else if (baseTypeInst->IsObject())
  3252. baseTypeInst = ResolveTypeDef(mCompiler->mBfObjectTypeDef)->ToTypeInstance();
  3253. }
  3254. }
  3255. PopulateType(baseTypeInst, BfPopulateType_Data);
  3256. typeInstance->mBaseTypeMayBeIncomplete = false;
  3257. typeInstance->mMergedFieldDataCount = baseTypeInst->mMergedFieldDataCount;
  3258. if ((resolvedTypeRef->IsObject()) && (!baseTypeInst->IsObject()))
  3259. {
  3260. Fail("Class can only derive from another class", baseTypeRef, true);
  3261. //typeInstance->mTypeFailed = true;
  3262. baseTypeInst = defaultBaseTypeInst;
  3263. typeInstance->mBaseType = baseTypeInst;
  3264. }
  3265. else if ((resolvedTypeRef->IsStruct()) && (!baseTypeInst->IsValueType()))
  3266. {
  3267. Fail("Struct can only derive from another struct", baseTypeRef, true);
  3268. //typeInstance->mTypeFailed = true;
  3269. baseTypeInst = defaultBaseTypeInst;
  3270. typeInstance->mBaseType = baseTypeInst;
  3271. }
  3272. if (!typeInstance->IsIncomplete())
  3273. {
  3274. // Re-entry may cause this type to be completed already
  3275. return;
  3276. }
  3277. //BfLogSysM("Adding DerivedFrom dependency. Used:%p Using:%p\n", baseType, typeInstance);
  3278. auto checkBaseType = baseTypeInst;
  3279. while (checkBaseType != NULL)
  3280. {
  3281. // Add 'DerivedFrom' dependency all the way up the inheritance chain
  3282. AddDependency(checkBaseType, typeInstance, BfDependencyMap::DependencyFlag_DerivedFrom);
  3283. checkBaseType = checkBaseType->mBaseType;
  3284. }
  3285. typeInstance->mBaseType = baseTypeInst;
  3286. typeInstance->mInheritDepth = baseTypeInst->mInheritDepth + 1;
  3287. typeInstance->mHasParameterizedBase = baseTypeInst->mHasParameterizedBase;
  3288. if ((baseTypeInst->IsArray()) || (baseTypeInst->IsSizedArray()) || (baseTypeInst->IsGenericTypeInstance()))
  3289. typeInstance->mHasParameterizedBase = true;
  3290. if (underlyingType == NULL)
  3291. {
  3292. typeInstance->mInstSize = baseTypeInst->mInstSize;
  3293. typeInstance->mInstAlign = baseTypeInst->mInstAlign;
  3294. typeInstance->mAlign = baseTypeInst->mAlign;
  3295. typeInstance->mSize = baseTypeInst->mSize;
  3296. typeInstance->mHasPackingHoles = baseTypeInst->mHasPackingHoles;
  3297. if (baseTypeInst->mIsTypedPrimitive)
  3298. typeInstance->mIsTypedPrimitive = true;
  3299. }
  3300. }
  3301. typeInstance->mRebuildFlags = (BfTypeRebuildFlags)(typeInstance->mRebuildFlags & ~BfTypeRebuildFlag_ResolvingBase);
  3302. if (populateType <= BfPopulateType_BaseType)
  3303. return;
  3304. if (typeInstance->IsGenericTypeInstance())
  3305. {
  3306. auto genericTypeInst = (BfTypeInstance*)typeInstance;
  3307. // if (!genericTypeInst->mGenericTypeInfo->mInitializedGenericParams)
  3308. // InitGenericParams(resolvedTypeRef);
  3309. if (!genericTypeInst->mGenericTypeInfo->mFinishedGenericParams)
  3310. FinishGenericParams(resolvedTypeRef);
  3311. }
  3312. if (wantPopulateInterfaces)
  3313. {
  3314. for (auto partialTypeDef : typeDef->mPartials)
  3315. {
  3316. if (!typeInstance->IsTypeMemberIncluded(partialTypeDef))
  3317. continue;
  3318. if (partialTypeDef->mTypeDeclaration == typeInstance->mTypeDef->mTypeDeclaration)
  3319. continue;
  3320. for (auto checkTypeRef : partialTypeDef->mBaseTypes)
  3321. {
  3322. SetAndRestoreValue<BfTypeReference*> prevTypeRef(mContext->mCurTypeState->mCurBaseTypeRef, checkTypeRef);
  3323. SetAndRestoreValue<BfTypeDef*> prevTypeDef(mContext->mCurTypeState->mCurTypeDef, partialTypeDef);
  3324. bool populateBase = !typeInstance->mTypeFailed;
  3325. auto checkType = ResolveTypeRef(checkTypeRef, BfPopulateType_Declaration);
  3326. if (checkType != NULL)
  3327. {
  3328. if (checkType->IsInterface())
  3329. {
  3330. BfInterfaceDecl ifaceDecl;
  3331. ifaceDecl.mIFaceTypeInst = checkType->ToTypeInstance();
  3332. ifaceDecl.mTypeRef = checkTypeRef;
  3333. ifaceDecl.mDeclaringType = partialTypeDef;
  3334. interfaces.push_back(ifaceDecl);
  3335. }
  3336. else
  3337. {
  3338. Fail(StrFormat("Extensions can only specify new interfaces, type '%s' is not a valid ", TypeToString(checkType).c_str()), checkTypeRef);
  3339. }
  3340. }
  3341. }
  3342. }
  3343. }
  3344. if ((typeInstance->mBaseType != NULL) && (!typeInstance->IsTypedPrimitive()))
  3345. {
  3346. curFieldDataIdx++;
  3347. }
  3348. if (!interfaces.empty())
  3349. {
  3350. for (int iFaceIdx = 0; iFaceIdx < (int)interfaces.size(); iFaceIdx++)
  3351. {
  3352. auto checkInterface = interfaces[iFaceIdx].mIFaceTypeInst;
  3353. SetAndRestoreValue<BfTypeDef*> prevTypeDef(mContext->mCurTypeState->mCurTypeDef, interfaces[iFaceIdx].mDeclaringType);
  3354. SetAndRestoreValue<BfTypeReference*> prevTypeRef(mContext->mCurTypeState->mCurBaseTypeRef, interfaces[iFaceIdx].mTypeRef);
  3355. PopulateType(checkInterface, BfPopulateType_Data);
  3356. BfTypeInterfaceEntry* found = NULL;
  3357. bool foundExact = false;
  3358. for (auto& typeInterfaceInst : typeInstance->mInterfaces)
  3359. {
  3360. if (typeInterfaceInst.mInterfaceType == checkInterface)
  3361. {
  3362. if (typeInterfaceInst.mDeclaringType == interfaces[iFaceIdx].mDeclaringType)
  3363. {
  3364. foundExact = true;
  3365. break;
  3366. }
  3367. found = &typeInterfaceInst;
  3368. }
  3369. }
  3370. if (foundExact)
  3371. continue;
  3372. BfTypeInterfaceEntry typeInterfaceInst;
  3373. typeInterfaceInst.mDeclaringType = interfaces[iFaceIdx].mDeclaringType;
  3374. typeInterfaceInst.mInterfaceType = checkInterface;
  3375. typeInterfaceInst.mStartInterfaceTableIdx = -1;
  3376. typeInterfaceInst.mStartVirtualIdx = -1;
  3377. typeInterfaceInst.mIsRedeclared = false;
  3378. typeInstance->mInterfaces.push_back(typeInterfaceInst);
  3379. AddDependency(checkInterface, typeInstance, BfDependencyMap::DependencyFlag_ImplementsInterface);
  3380. // Interfaces can list other interfaces in their declaration, so pull those in too
  3381. for (auto depIFace : checkInterface->mInterfaces)
  3382. {
  3383. auto depIFaceEntry = interfaces[iFaceIdx];
  3384. depIFaceEntry.mIFaceTypeInst = depIFace.mInterfaceType;
  3385. interfaces.push_back(depIFaceEntry);
  3386. }
  3387. }
  3388. if (typeInstance->mTypeFailed)
  3389. {
  3390. // Circular references in interfaces - just clear them all out
  3391. typeInstance->mInterfaces.Clear();
  3392. interfaces.Clear();
  3393. }
  3394. if (_CheckTypeDone())
  3395. return;
  3396. }
  3397. if ((mCompiler->mOptions.mAllowHotSwapping) &&
  3398. (typeInstance->mDefineState < BfTypeDefineState_HasInterfaces) &&
  3399. (typeInstance->mDefineState != BfTypeDefineState_ResolvingBaseType))
  3400. {
  3401. if (typeInstance->mHotTypeData == NULL)
  3402. {
  3403. typeInstance->mHotTypeData = new BfHotTypeData();
  3404. BfLogSysM("Created HotTypeData %p created for type %p in DoPopulateType\n", typeInstance->mHotTypeData, typeInstance);
  3405. }
  3406. // Clear any unused versions (if we have errors, etc)
  3407. if (mCompiler->mHotState != NULL)
  3408. typeInstance->mHotTypeData->ClearVersionsAfter(mCompiler->mHotState->mCommittedHotCompileIdx);
  3409. else
  3410. BF_ASSERT(typeInstance->mHotTypeData->mTypeVersions.IsEmpty()); // We should have created a new HotTypeData when rebuilding the type
  3411. BfHotTypeVersion* hotTypeVersion = new BfHotTypeVersion();
  3412. hotTypeVersion->mTypeId = typeInstance->mTypeId;
  3413. if (typeInstance->mBaseType != NULL)
  3414. {
  3415. if (typeInstance->mBaseType->mHotTypeData != NULL)
  3416. hotTypeVersion->mBaseType = typeInstance->mBaseType->mHotTypeData->GetLatestVersion();
  3417. else
  3418. {
  3419. AssertErrorState();
  3420. }
  3421. }
  3422. hotTypeVersion->mDeclHotCompileIdx = mCompiler->mOptions.mHotCompileIdx;
  3423. if (mCompiler->IsHotCompile())
  3424. hotTypeVersion->mCommittedHotCompileIdx = -1;
  3425. else
  3426. hotTypeVersion->mCommittedHotCompileIdx = 0;
  3427. hotTypeVersion->mRefCount++;
  3428. typeInstance->mHotTypeData->mTypeVersions.Add(hotTypeVersion);
  3429. BfLogSysM("BfHotTypeVersion %p created for type %p\n", hotTypeVersion, typeInstance);
  3430. }
  3431. BF_ASSERT(!typeInstance->mNeedsMethodProcessing);
  3432. if (typeInstance->mDefineState < BfTypeDefineState_HasInterfaces)
  3433. typeInstance->mDefineState = BfTypeDefineState_HasInterfaces;
  3434. for (auto& validateEntry : deferredTypeValidateList)
  3435. {
  3436. SetAndRestoreValue<BfTypeReference*> prevAttributeTypeRef(typeState.mCurAttributeTypeRef, validateEntry.mTypeRef);
  3437. SetAndRestoreValue<bool> ignoreErrors(mIgnoreErrors, mIgnoreErrors | validateEntry.mIgnoreErrors);
  3438. ValidateGenericConstraints(validateEntry.mTypeRef, validateEntry.mGenericType, false);
  3439. }
  3440. if (!typeInstance->IsBoxed())
  3441. {
  3442. if ((typeInstance->mCustomAttributes == NULL) && (typeDef->mTypeDeclaration != NULL) && (typeDef->HasCustomAttributes()))
  3443. {
  3444. BfAttributeTargets attrTarget;
  3445. if ((typeDef->mIsDelegate) || (typeDef->mIsFunction))
  3446. attrTarget = BfAttributeTargets_Delegate;
  3447. else if (typeInstance->IsEnum())
  3448. attrTarget = BfAttributeTargets_Enum;
  3449. else if (typeInstance->IsInterface())
  3450. attrTarget = BfAttributeTargets_Interface;
  3451. else if ((typeInstance->IsStruct()) || (typeInstance->IsTypedPrimitive()))
  3452. attrTarget = BfAttributeTargets_Struct;
  3453. else
  3454. attrTarget = BfAttributeTargets_Class;
  3455. if (!typeInstance->mTypeFailed)
  3456. {
  3457. BfTypeState typeState;
  3458. typeState.mPrevState = mContext->mCurTypeState;
  3459. typeState.mResolveKind = BfTypeState::ResolveKind_Attributes;
  3460. typeState.mType = typeInstance;
  3461. SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
  3462. // This allows us to avoid reentrancy when checking for inner types
  3463. SetAndRestoreValue<bool> prevSkipTypeProtectionChecks(typeInstance->mSkipTypeProtectionChecks, true);
  3464. if (typeDef->mIsCombinedPartial)
  3465. {
  3466. for (auto partialTypeDef : typeDef->mPartials)
  3467. {
  3468. if (partialTypeDef->mTypeDeclaration->mAttributes == NULL)
  3469. continue;
  3470. typeState.mCurTypeDef = partialTypeDef;
  3471. if (typeInstance->mCustomAttributes == NULL)
  3472. typeInstance->mCustomAttributes = new BfCustomAttributes();
  3473. GetCustomAttributes(typeInstance->mCustomAttributes, partialTypeDef->mTypeDeclaration->mAttributes, attrTarget);
  3474. }
  3475. }
  3476. else
  3477. {
  3478. typeInstance->mCustomAttributes = GetCustomAttributes(typeDef->mTypeDeclaration->mAttributes, attrTarget);
  3479. }
  3480. }
  3481. }
  3482. }
  3483. if (typeInstance->mTypeOptionsIdx == -2)
  3484. {
  3485. SetTypeOptions(typeInstance);
  3486. }
  3487. if (populateType <= BfPopulateType_AllowStaticMethods)
  3488. return;
  3489. prevSkipTypeProtectionChecks.Restore();
  3490. typeInstance->mInstSize = std::max(0, typeInstance->mInstSize);
  3491. typeInstance->mInstAlign = std::max(0, typeInstance->mInstAlign);
  3492. ProcessCustomAttributeData();
  3493. int packing = 0;
  3494. bool isUnion = false;
  3495. bool isCRepr = false;
  3496. bool isOrdered = false;
  3497. int alignOverride = 0;
  3498. BfType* underlyingArrayType = NULL;
  3499. int underlyingArraySize = -1;
  3500. ProcessTypeInstCustomAttributes(packing, isUnion, isCRepr, isOrdered, alignOverride, underlyingArrayType, underlyingArraySize);
  3501. if (underlyingArraySize > 0)
  3502. {
  3503. typeInstance->mHasUnderlyingArray = true;
  3504. curFieldDataIdx = 0;
  3505. }
  3506. if (packing > 0) // Packed infers ordered
  3507. isOrdered = true;
  3508. typeInstance->mIsUnion = isUnion;
  3509. if ((typeInstance->IsEnum()) && (typeInstance->IsStruct()))
  3510. typeInstance->mIsUnion = true;
  3511. typeInstance->mPacking = (uint8)packing;
  3512. typeInstance->mIsCRepr = isCRepr;
  3513. if (typeInstance->mTypeOptionsIdx >= 0)
  3514. {
  3515. auto typeOptions = mSystem->GetTypeOptions(typeInstance->mTypeOptionsIdx);
  3516. if (typeOptions != NULL)
  3517. {
  3518. typeInstance->mHasBeenInstantiated = typeOptions->Apply(typeInstance->HasBeenInstantiated(), BfOptionFlags_ReflectAssumeInstantiated);
  3519. bool alwaysInclude = typeInstance->mAlwaysIncludeFlags != 0;
  3520. if ((typeOptions->Apply(alwaysInclude, BfOptionFlags_ReflectAlwaysIncludeType)) ||
  3521. (typeOptions->Apply(alwaysInclude, BfOptionFlags_ReflectAlwaysIncludeAll)))
  3522. {
  3523. typeInstance->mAlwaysIncludeFlags = (BfAlwaysIncludeFlags)(typeInstance->mAlwaysIncludeFlags | BfAlwaysIncludeFlag_Type);
  3524. }
  3525. else
  3526. {
  3527. typeInstance->mAlwaysIncludeFlags = BfAlwaysIncludeFlag_None;
  3528. }
  3529. }
  3530. }
  3531. BfType* unionInnerType = NULL;
  3532. bool hadDeferredVars = false;
  3533. int dataPos;
  3534. if (resolvedTypeRef->IsBoxed())
  3535. {
  3536. BfBoxedType* boxedType = (BfBoxedType*)resolvedTypeRef;
  3537. BfType* innerType = boxedType->mElementType;
  3538. if (boxedType->IsBoxedStructPtr())
  3539. innerType = CreatePointerType(innerType);
  3540. if (innerType->IsIncomplete())
  3541. PopulateType(innerType, BfPopulateType_Data);
  3542. auto innerTypeInst = innerType->ToTypeInstance();
  3543. if (innerTypeInst != NULL)
  3544. {
  3545. if (typeInstance->mTypeDef != innerTypeInst->mTypeDef)
  3546. {
  3547. // Rebuild with proper typedef (generally from inner type comptime emission)
  3548. BfLogSysM("Boxed type %p overriding typeDef to %p from inner type %p\n", typeInstance, innerTypeInst->mTypeDef, innerType);
  3549. typeInstance->mTypeDef = innerTypeInst->mTypeDef;
  3550. DoPopulateType(resolvedTypeRef, populateType);
  3551. return;
  3552. }
  3553. while (typeInstance->mInterfaces.mSize < innerTypeInst->mInterfaces.mSize)
  3554. {
  3555. auto ifaceEntry = innerTypeInst->mInterfaces[typeInstance->mInterfaces.mSize];
  3556. typeInstance->mInterfaces.Add(ifaceEntry);
  3557. AddDependency(ifaceEntry.mInterfaceType, typeInstance, BfDependencyMap::DependencyFlag_ImplementsInterface);
  3558. }
  3559. }
  3560. auto baseType = typeInstance->mBaseType;
  3561. dataPos = baseType->mInstSize;
  3562. int alignSize = BF_MAX(innerType->mAlign, baseType->mInstAlign);
  3563. if (alignSize > 1)
  3564. dataPos = (dataPos + (alignSize - 1)) & ~(alignSize - 1);
  3565. int dataSize = innerType->mSize;
  3566. typeInstance->mFieldInstances.push_back(BfFieldInstance());
  3567. BfFieldInstance* fieldInstance = &typeInstance->mFieldInstances.back();
  3568. fieldInstance->mDataOffset = dataPos;
  3569. fieldInstance->mDataSize = innerType->mSize;
  3570. fieldInstance->mOwner = typeInstance;
  3571. fieldInstance->mResolvedType = innerType;
  3572. if (!innerType->IsValuelessType())
  3573. {
  3574. curFieldDataIdx++;
  3575. }
  3576. dataPos += dataSize;
  3577. typeInstance->mInstAlign = std::max(baseType->mInstAlign, alignSize);
  3578. int instAlign = typeInstance->mInstAlign;
  3579. if (instAlign != 0)
  3580. {
  3581. int instSize = (dataPos + (instAlign - 1)) & ~(instAlign - 1);
  3582. if (instSize != typeInstance->mInstSize)
  3583. {
  3584. typeInstance->mInstSize = instSize;
  3585. typeInstance->mHasPackingHoles = true;
  3586. }
  3587. }
  3588. typeInstance->mInstSize = std::max(1, typeInstance->mInstSize);
  3589. }
  3590. else
  3591. {
  3592. dataPos = typeInstance->mInstSize;
  3593. if (underlyingType != NULL)
  3594. {
  3595. if (!underlyingType->IsValuelessType())
  3596. {
  3597. curFieldDataIdx++;
  3598. }
  3599. }
  3600. struct DeferredResolveEntry
  3601. {
  3602. BfFieldDef* mFieldDef;
  3603. int mTypeArrayIdx;
  3604. };
  3605. BfSizedVector<DeferredResolveEntry, 8> deferredVarResolves;
  3606. for (auto field : typeDef->mFields)
  3607. {
  3608. auto fieldInstance = &typeInstance->mFieldInstances[field->mIdx];
  3609. if (fieldInstance->mResolvedType != NULL)
  3610. continue;
  3611. if (!typeInstance->IsTypeMemberIncluded(field->mDeclaringType))
  3612. {
  3613. fieldInstance->mFieldIncluded = false;
  3614. continue;
  3615. }
  3616. fieldInstance->mOwner = typeInstance;
  3617. fieldInstance->mFieldIdx = field->mIdx;
  3618. if (typeInstance->IsInterface())
  3619. Fail("Interfaces cannot include fields. Consider making this a property", field->GetRefNode());
  3620. }
  3621. int enumCaseEntryIdx = 0;
  3622. for (int pass = 0; pass < 2; pass++)
  3623. {
  3624. for (auto field : typeDef->mFields)
  3625. {
  3626. // Do consts then non-consts. Somewhat of a hack for using consts as sized array size
  3627. if (field->mIsConst != (pass == 0))
  3628. continue;
  3629. auto fieldInstance = &typeInstance->mFieldInstances[field->mIdx];
  3630. if ((fieldInstance->mResolvedType != NULL) || (!fieldInstance->mFieldIncluded))
  3631. continue;
  3632. SetAndRestoreValue<BfFieldDef*> prevTypeRef(mContext->mCurTypeState->mCurFieldDef, field);
  3633. SetAndRestoreValue<BfTypeState::ResolveKind> prevResolveKind(mContext->mCurTypeState->mResolveKind, BfTypeState::ResolveKind_FieldType);
  3634. BfType* resolvedFieldType = NULL;
  3635. if (field->IsEnumCaseEntry())
  3636. {
  3637. if (typeInstance->IsEnum())
  3638. {
  3639. fieldInstance->mDataIdx = -(enumCaseEntryIdx++) - 1;
  3640. resolvedFieldType = typeInstance;
  3641. BfType* payloadType = NULL;
  3642. if (field->mTypeRef != NULL)
  3643. payloadType = ResolveTypeRef(field->mTypeRef, BfPopulateType_Data, BfResolveTypeRefFlag_NoResolveGenericParam);
  3644. if (payloadType == NULL)
  3645. {
  3646. if (!typeInstance->IsTypedPrimitive())
  3647. payloadType = CreateTupleType(BfTypeVector(), Array<String>());
  3648. }
  3649. if (payloadType != NULL)
  3650. {
  3651. AddDependency(payloadType, typeInstance, BfDependencyMap::DependencyFlag_ValueTypeMemberData);
  3652. BF_ASSERT(payloadType->IsTuple());
  3653. resolvedFieldType = payloadType;
  3654. fieldInstance->mIsEnumPayloadCase = true;
  3655. }
  3656. }
  3657. else
  3658. {
  3659. Fail("Enum cases can only be declared within enum types", field->GetRefNode(), true);
  3660. resolvedFieldType = typeInstance;
  3661. }
  3662. }
  3663. else if ((field->mTypeRef != NULL) && ((field->mTypeRef->IsExact<BfVarTypeReference>()) || (field->mTypeRef->IsExact<BfLetTypeReference>()) || (field->mTypeRef->IsExact<BfExprModTypeRef>())))
  3664. {
  3665. resolvedFieldType = GetPrimitiveType(BfTypeCode_Var);
  3666. DeferredResolveEntry resolveEntry;
  3667. resolveEntry.mFieldDef = field;
  3668. resolveEntry.mTypeArrayIdx = (int)llvmFieldTypes.size();
  3669. deferredVarResolves.push_back(resolveEntry);
  3670. fieldInstance->mIsInferredType = true;
  3671. // For 'let', make read-only
  3672. }
  3673. else
  3674. {
  3675. BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_NoResolveGenericParam;
  3676. if (field->mInitializer != NULL)
  3677. resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_AllowInferredSizedArray);
  3678. resolvedFieldType = ResolveTypeRef(field->mTypeRef, BfPopulateType_Declaration, resolveFlags);
  3679. if (resolvedFieldType == NULL)
  3680. {
  3681. // Failed, just put in placeholder 'var'
  3682. AssertErrorState();
  3683. resolvedFieldType = GetPrimitiveType(BfTypeCode_Var);
  3684. }
  3685. }
  3686. if (resolvedFieldType->IsUndefSizedArray())
  3687. {
  3688. if (auto arrayTypeRef = BfNodeDynCast<BfArrayTypeRef>(field->mTypeRef))
  3689. {
  3690. if (arrayTypeRef->IsInferredSize())
  3691. {
  3692. if (field->mInitializer != NULL)
  3693. {
  3694. DeferredResolveEntry resolveEntry;
  3695. resolveEntry.mFieldDef = field;
  3696. resolveEntry.mTypeArrayIdx = (int)llvmFieldTypes.size();
  3697. deferredVarResolves.push_back(resolveEntry);
  3698. fieldInstance->mIsInferredType = true;
  3699. }
  3700. else
  3701. {
  3702. AssertErrorState();
  3703. }
  3704. }
  3705. }
  3706. }
  3707. if (resolvedFieldType->IsMethodRef())
  3708. {
  3709. auto methodRefType = (BfMethodRefType*)resolvedFieldType;
  3710. }
  3711. if (fieldInstance->mResolvedType == NULL)
  3712. fieldInstance->mResolvedType = resolvedFieldType;
  3713. if (field->mIsConst)
  3714. {
  3715. // Resolve in ResolveConstField after we finish populating entire FieldInstance list
  3716. }
  3717. else if (field->mIsStatic)
  3718. {
  3719. // Don't allocate this until after we're finished populating entire FieldInstance list,
  3720. // because we may have re-entry and create multiple instances of this static field
  3721. }
  3722. }
  3723. }
  3724. if (!resolvedTypeRef->IsIncomplete())
  3725. {
  3726. // We finished resolving ourselves through a re-entry, so we're actually done here
  3727. return;
  3728. }
  3729. for (auto& resolveEntry : deferredVarResolves)
  3730. {
  3731. hadDeferredVars = true;
  3732. auto fieldType = ResolveVarFieldType(typeInstance, &typeInstance->mFieldInstances[resolveEntry.mFieldDef->mIdx], resolveEntry.mFieldDef);
  3733. if (fieldType == NULL)
  3734. {
  3735. fieldType = mContext->mBfObjectType;
  3736. // We used to set mTypeFailed, but mHasBuildError is enough to cause a type rebuild properly
  3737. mHadBuildError = true;
  3738. //typeInstance->mTypeFailed = true;
  3739. }
  3740. auto fieldInstance = &typeInstance->mFieldInstances[resolveEntry.mFieldDef->mIdx];
  3741. fieldInstance->SetResolvedType(fieldType);
  3742. }
  3743. if (typeInstance->mResolvingConstField)
  3744. return;
  3745. for (auto& fieldInstanceRef : typeInstance->mFieldInstances)
  3746. {
  3747. auto fieldInstance = &fieldInstanceRef;
  3748. auto fieldDef = fieldInstance->GetFieldDef();
  3749. auto resolvedFieldType = fieldInstance->GetResolvedType();
  3750. if (!fieldInstance->mFieldIncluded)
  3751. continue;
  3752. if (fieldInstance->mCustomAttributes != NULL)
  3753. {
  3754. // Already handled
  3755. }
  3756. else if ((fieldDef != NULL) && (fieldDef->mFieldDeclaration != NULL) && (fieldDef->mFieldDeclaration->mAttributes != NULL))
  3757. {
  3758. if (auto propDecl = BfNodeDynCast<BfPropertyDeclaration>(fieldDef->mFieldDeclaration))
  3759. {
  3760. // Handled elsewhere
  3761. }
  3762. else
  3763. {
  3764. BfTypeState typeState;
  3765. typeState.mPrevState = mContext->mCurTypeState;
  3766. typeState.mCurFieldDef = fieldDef;
  3767. typeState.mCurTypeDef = fieldDef->mDeclaringType;
  3768. typeState.mType = typeInstance;
  3769. SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
  3770. fieldInstance->mCustomAttributes = GetCustomAttributes(fieldDef->mFieldDeclaration->mAttributes, fieldDef->mIsStatic ? BfAttributeTargets_StaticField : BfAttributeTargets_Field);
  3771. for (auto customAttr : fieldInstance->mCustomAttributes->mAttributes)
  3772. {
  3773. if (TypeToString(customAttr.mType) == "System.ThreadStaticAttribute")
  3774. {
  3775. if ((!fieldDef->mIsStatic) || (fieldDef->mIsConst))
  3776. {
  3777. Fail("ThreadStatic attribute can only be used on static fields", fieldDef->mFieldDeclaration->mAttributes);
  3778. }
  3779. }
  3780. }
  3781. }
  3782. }
  3783. if (resolvedFieldType == NULL)
  3784. {
  3785. if ((underlyingType != NULL) || (typeInstance->IsPayloadEnum()))
  3786. continue;
  3787. }
  3788. if (fieldDef == NULL)
  3789. continue;
  3790. if ((!fieldDef->mIsStatic) && (resolvedFieldType->IsValueType()))
  3791. {
  3792. // We need that type finished up for alignment and data size
  3793. // But if the type has failed then we need to avoid stack overflow so we don't finish it
  3794. SetAndRestoreValue<BfFieldDef*> prevTypeRef(mContext->mCurTypeState->mCurFieldDef, fieldDef);
  3795. bool populateChildType = !typeInstance->mTypeFailed;
  3796. //bool populateChildType = true;
  3797. PopulateType(resolvedFieldType, populateChildType ? BfPopulateType_Data : BfPopulateType_Declaration);
  3798. if (populateChildType)
  3799. {
  3800. if (resolvedFieldType->IsFinishingType())
  3801. {
  3802. AssertErrorState();
  3803. }
  3804. else
  3805. BF_ASSERT(!resolvedFieldType->IsDataIncomplete());
  3806. }
  3807. else
  3808. {
  3809. if (resolvedFieldType->IsDataIncomplete())
  3810. {
  3811. AssertErrorState();
  3812. resolvedFieldType = mContext->mBfObjectType;
  3813. fieldInstance->SetResolvedType(resolvedFieldType);
  3814. // We used to set mTypeFailed, but mHasBuildError is enough to cause a type rebuild properly
  3815. mHadBuildError = true;
  3816. }
  3817. }
  3818. }
  3819. }
  3820. bool tryCE = true;
  3821. if (typeInstance->mDefineState == BfTypeDefineState_CETypeInit)
  3822. {
  3823. if (populateType <= BfPopulateType_AllowStaticMethods)
  3824. return;
  3825. int foundTypeCount = 0;
  3826. auto typeState = mContext->mCurTypeState;
  3827. while (typeState != NULL)
  3828. {
  3829. if (typeState->mType == typeInstance)
  3830. {
  3831. foundTypeCount++;
  3832. if (foundTypeCount == 2)
  3833. break;
  3834. }
  3835. typeState = typeState->mPrevState;
  3836. }
  3837. if ((foundTypeCount >= 2) || (typeInstance->mTypeDef->IsEmitted()))
  3838. {
  3839. String error = "OnCompile const evaluation creates a data dependency during TypeInit";
  3840. if (mCompiler->mCEMachine->mCurBuilder != NULL)
  3841. {
  3842. error += StrFormat(" during const-eval generation of '%s'", MethodToString(mCompiler->mCEMachine->mCurBuilder->mCeFunction->mMethodInstance).c_str());
  3843. }
  3844. auto refNode = typeDef->GetRefNode();
  3845. Fail(error, refNode);
  3846. if ((mCompiler->mCEMachine->mCurContext != NULL) && (mCompiler->mCEMachine->mCurContext->mCurFrame != NULL))
  3847. mCompiler->mCEMachine->mCurContext->Fail(*mCompiler->mCEMachine->mCurContext->mCurFrame, error);
  3848. else if (mCompiler->mCEMachine->mCurContext != NULL)
  3849. mCompiler->mCEMachine->mCurContext->Fail(error);
  3850. tryCE = false;
  3851. }
  3852. }
  3853. if ((typeInstance->mDefineState < BfTypeDefineState_CEPostTypeInit) && (tryCE))
  3854. {
  3855. BF_ASSERT(!typeInstance->mTypeDef->IsEmitted());
  3856. if (typeInstance->mCeTypeInfo != NULL)
  3857. typeInstance->mCeTypeInfo->mPendingInterfaces.Clear();
  3858. typeInstance->mDefineState = BfTypeDefineState_CETypeInit;
  3859. bool hadNewMembers = false;
  3860. DoCEEmit(typeInstance, hadNewMembers, underlyingTypeDeferred);
  3861. if (typeInstance->mDefineState < BfTypeDefineState_CEPostTypeInit)
  3862. typeInstance->mDefineState = BfTypeDefineState_CEPostTypeInit;
  3863. if (typeInstance->mCeTypeInfo != NULL)
  3864. {
  3865. if (typeInstance->mCeTypeInfo->mNext != NULL)
  3866. {
  3867. auto ceInfo = typeInstance->mCeTypeInfo->mNext;
  3868. HashContext hashCtx;
  3869. hashCtx.Mixin(ceInfo->mOnCompileMap.mCount);
  3870. for (auto& kv : ceInfo->mOnCompileMap)
  3871. {
  3872. hashCtx.Mixin(kv.mKey);
  3873. hashCtx.MixinStr(kv.mValue.mEmitData);
  3874. }
  3875. hashCtx.Mixin(ceInfo->mTypeIFaceMap.mCount);
  3876. for (auto& kv : ceInfo->mTypeIFaceMap)
  3877. {
  3878. hashCtx.Mixin(kv.mKey);
  3879. hashCtx.MixinStr(kv.mValue.mEmitData);
  3880. }
  3881. typeInstance->mCeTypeInfo->mNext->mHash = hashCtx.Finish128();
  3882. if (!typeInstance->mCeTypeInfo->mNext->mFailed)
  3883. {
  3884. if ((typeInstance->mCeTypeInfo->mHash != typeInstance->mCeTypeInfo->mNext->mHash) && (!typeInstance->mCeTypeInfo->mHash.IsZero()))
  3885. mContext->RebuildDependentTypes_MidCompile(typeInstance, "comptime hash changed");
  3886. typeInstance->mCeTypeInfo->mOnCompileMap = typeInstance->mCeTypeInfo->mNext->mOnCompileMap;
  3887. typeInstance->mCeTypeInfo->mTypeIFaceMap = typeInstance->mCeTypeInfo->mNext->mTypeIFaceMap;
  3888. typeInstance->mCeTypeInfo->mHash = typeInstance->mCeTypeInfo->mNext->mHash;
  3889. }
  3890. delete typeInstance->mCeTypeInfo->mNext;
  3891. typeInstance->mCeTypeInfo->mNext = NULL;
  3892. }
  3893. }
  3894. if ((typeInstance->mCeTypeInfo != NULL) && (!typeInstance->mCeTypeInfo->mPendingInterfaces.IsEmpty()))
  3895. hadNewMembers = true;
  3896. if ((typeInstance->mTypeDef->IsEmitted()) && (typeInstance->mCeTypeInfo == NULL))
  3897. {
  3898. BF_ASSERT(mCompiler->mCanceling);
  3899. if (mCompiler->mCanceling)
  3900. {
  3901. TypeFailed(typeInstance);
  3902. auto prevTypeDef = typeInstance->mTypeDef->mEmitParent;
  3903. delete typeInstance->mTypeDef;
  3904. typeInstance->mTypeDef = prevTypeDef;
  3905. hadNewMembers = false;
  3906. }
  3907. }
  3908. if (hadNewMembers)
  3909. {
  3910. DoPopulateType(resolvedTypeRef, populateType);
  3911. return;
  3912. }
  3913. if (_CheckTypeDone())
  3914. return;
  3915. }
  3916. }
  3917. if (_CheckTypeDone())
  3918. return;
  3919. BF_ASSERT(mContext->mCurTypeState == &typeState);
  3920. //BF_ASSERT(!typeInstance->mIsFinishingType);
  3921. typeInstance->mIsFinishingType = true;
  3922. // No re-entry is allowed below here -- we will run all the way to the end at this point
  3923. BfSizedVector<BfIRMDNode, 8> diFieldTypes;
  3924. HashContext dataMemberHashCtx;
  3925. if (!resolvedTypeRef->IsBoxed())
  3926. {
  3927. for (auto propDef : typeDef->mProperties)
  3928. {
  3929. if (!typeInstance->IsTypeMemberIncluded(propDef->mDeclaringType))
  3930. continue;
  3931. if (propDef->mFieldDeclaration != NULL)
  3932. {
  3933. BfTypeState typeState;
  3934. typeState.mPrevState = mContext->mCurTypeState;
  3935. typeState.mCurTypeDef = propDef->mDeclaringType;
  3936. typeState.mCurFieldDef = propDef;
  3937. typeState.mType = typeInstance;
  3938. SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
  3939. BfAttributeTargets target = BfAttributeTargets_Property;
  3940. if (propDef->IsExpressionBodied())
  3941. target = (BfAttributeTargets)(target | BfAttributeTargets_Method);
  3942. if (propDef->mFieldDeclaration->mAttributes != NULL)
  3943. {
  3944. auto customAttrs = GetCustomAttributes(propDef->mFieldDeclaration->mAttributes, target);
  3945. delete customAttrs;
  3946. }
  3947. auto propDecl = (BfPropertyDeclaration*)propDef->mFieldDeclaration;
  3948. if (propDecl->mExplicitInterface != NULL)
  3949. {
  3950. if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL))
  3951. mCompiler->mResolvePassData->mAutoComplete->CheckTypeRef(propDecl->mExplicitInterface, false);
  3952. auto explicitInterface = ResolveTypeRef(propDecl->mExplicitInterface, BfPopulateType_Declaration);
  3953. if (explicitInterface != NULL)
  3954. {
  3955. bool interfaceFound = false;
  3956. for (auto ifaceInst : typeInstance->mInterfaces)
  3957. interfaceFound |= ifaceInst.mInterfaceType == explicitInterface;
  3958. if (!interfaceFound)
  3959. {
  3960. Fail("Containing class has not declared to implement this interface", propDecl->mExplicitInterface, true);
  3961. }
  3962. }
  3963. }
  3964. }
  3965. if (propDef->mMethods.IsEmpty())
  3966. {
  3967. auto nameNode = ((BfPropertyDeclaration*)propDef->mFieldDeclaration)->mNameNode;
  3968. if (nameNode != NULL)
  3969. {
  3970. Fail(StrFormat("Property or indexer '%s.%s' must have at least one accessor", TypeToString(typeInstance).c_str(), propDef->mName.c_str()),
  3971. nameNode, true); // CS0548
  3972. }
  3973. }
  3974. }
  3975. bool isGlobalContainer = typeDef->IsGlobalsContainer();
  3976. if (typeInstance->mBaseType != NULL)
  3977. {
  3978. dataMemberHashCtx.Mixin(typeInstance->mBaseType->mTypeId);
  3979. if (typeInstance->mBaseType->mHotTypeData != NULL)
  3980. {
  3981. BfHotTypeVersion* ver = typeInstance->mBaseType->mHotTypeData->GetLatestVersion();
  3982. dataMemberHashCtx.Mixin(ver->mDataHash);
  3983. }
  3984. }
  3985. dataMemberHashCtx.Mixin(typeInstance->mPacking);
  3986. dataMemberHashCtx.Mixin(typeInstance->mIsCRepr);
  3987. dataMemberHashCtx.Mixin(typeInstance->mIsUnion);
  3988. int startDataPos = dataPos;
  3989. int maxDataPos = dataPos;
  3990. BfSizedVector<BfFieldInstance*, 16> dataFieldVec;
  3991. bool allowInstanceFields = (underlyingType == NULL);
  3992. if (typeInstance->IsTypedPrimitive())
  3993. allowInstanceFields = false;
  3994. // We've resolved all the 'var' entries, so now build the actual composite type
  3995. for (auto& fieldInstanceRef : typeInstance->mFieldInstances)
  3996. {
  3997. auto fieldInstance = &fieldInstanceRef;
  3998. if (!fieldInstance->mFieldIncluded)
  3999. continue;
  4000. auto resolvedFieldType = fieldInstance->GetResolvedType();
  4001. if (fieldInstance->mResolvedType == NULL)
  4002. {
  4003. if ((underlyingType == NULL) && (!typeInstance->IsPayloadEnum()))
  4004. BF_ASSERT(typeInstance->mTypeFailed);
  4005. continue;
  4006. }
  4007. if ((fieldInstance->GetFieldDef() != NULL) && (fieldInstance->GetFieldDef()->mIsConst))
  4008. {
  4009. // Resolve later
  4010. AddDependency(resolvedFieldType, typeInstance, BfDependencyMap::DependencyFlag_ConstValue);
  4011. }
  4012. else if (fieldInstance->GetFieldDef() != NULL)
  4013. {
  4014. if (!fieldInstance->GetFieldDef()->mIsStatic)
  4015. AddFieldDependency(typeInstance, fieldInstance, resolvedFieldType);
  4016. else
  4017. AddDependency(resolvedFieldType, typeInstance, BfDependencyMap::DependencyFlag_StaticValue);
  4018. }
  4019. auto fieldDef = fieldInstance->GetFieldDef();
  4020. if (fieldInstance->mResolvedType != NULL)
  4021. {
  4022. auto resolvedFieldType = fieldInstance->GetResolvedType();
  4023. if ((!typeInstance->IsBoxed()) && (fieldDef != NULL))
  4024. {
  4025. if (fieldInstance->mIsEnumPayloadCase)
  4026. {
  4027. PopulateType(resolvedFieldType, BfPopulateType_Data);
  4028. if (resolvedFieldType->WantsGCMarking())
  4029. typeInstance->mWantsGCMarking = true;
  4030. }
  4031. if ((!fieldDef->mIsConst) && (!fieldDef->mIsStatic))
  4032. {
  4033. PopulateType(resolvedFieldType, resolvedFieldType->IsValueType() ? BfPopulateType_Data : BfPopulateType_Declaration);
  4034. if (resolvedFieldType->WantsGCMarking())
  4035. typeInstance->mWantsGCMarking = true;
  4036. fieldInstance->mMergedDataIdx = typeInstance->mMergedFieldDataCount;
  4037. if (resolvedFieldType->IsStruct())
  4038. {
  4039. auto resolvedFieldTypeInstance = resolvedFieldType->ToTypeInstance();
  4040. typeInstance->mMergedFieldDataCount += resolvedFieldTypeInstance->mMergedFieldDataCount;
  4041. }
  4042. else if (!resolvedFieldType->IsValuelessType())
  4043. typeInstance->mMergedFieldDataCount++;
  4044. if (fieldDef->mIsExtern)
  4045. {
  4046. Fail("Cannot declare instance member as 'extern'", fieldDef->mFieldDeclaration->mExternSpecifier, true);
  4047. }
  4048. BfAstNode* nameRefNode = NULL;
  4049. if (fieldDef->mFieldDeclaration != NULL)
  4050. nameRefNode = fieldDef->mFieldDeclaration->mNameNode;
  4051. if (nameRefNode == NULL)
  4052. nameRefNode = fieldDef->mTypeRef;
  4053. if (!allowInstanceFields)
  4054. {
  4055. if (typeInstance->IsEnum())
  4056. Fail("Cannot declare instance members in an enum", nameRefNode, true);
  4057. else if (typeInstance->IsFunction())
  4058. Fail("Cannot declare instance members in a function", nameRefNode, true);
  4059. else
  4060. Fail("Cannot declare instance members in a typed primitive struct", nameRefNode, true);
  4061. TypeFailed(typeInstance);
  4062. fieldInstance->mDataIdx = -1;
  4063. continue;
  4064. }
  4065. if (typeDef->mIsStatic)
  4066. {
  4067. //CS0708
  4068. Fail("Cannot declare instance members in a static class", nameRefNode, true);
  4069. }
  4070. if (resolvedFieldType->IsValueType())
  4071. {
  4072. BF_ASSERT(!resolvedFieldType->IsDataIncomplete());
  4073. }
  4074. if (!mCompiler->mIsResolveOnly)
  4075. {
  4076. dataMemberHashCtx.MixinStr(fieldDef->mName);
  4077. dataMemberHashCtx.Mixin(resolvedFieldType->mTypeId);
  4078. }
  4079. int dataSize = resolvedFieldType->mSize;
  4080. int alignSize = resolvedFieldType->mAlign;
  4081. fieldInstance->mDataSize = dataSize;
  4082. if (!isUnion)
  4083. {
  4084. if (!resolvedFieldType->IsValuelessType())
  4085. {
  4086. dataFieldVec.push_back(fieldInstance);
  4087. }
  4088. }
  4089. else
  4090. {
  4091. BF_ASSERT(resolvedFieldType->mSize >= 0);
  4092. if (alignSize > 1)
  4093. dataPos = (dataPos + (alignSize - 1)) & ~(alignSize - 1);
  4094. fieldInstance->mDataOffset = dataPos;
  4095. typeInstance->mInstAlign = std::max(typeInstance->mInstAlign, alignSize);
  4096. dataPos += dataSize;
  4097. if (dataPos > maxDataPos)
  4098. {
  4099. maxDataPos = dataPos;
  4100. }
  4101. dataPos = startDataPos;
  4102. }
  4103. auto fieldTypeInst = resolvedFieldType->ToTypeInstance();
  4104. if (fieldTypeInst != NULL)
  4105. {
  4106. if ((fieldTypeInst->mRebuildFlags & BfTypeRebuildFlag_UnderlyingTypeDeferred) != 0)
  4107. {
  4108. BfAstNode* refNode = fieldDef->mFieldDeclaration;
  4109. String failStr;
  4110. failStr = StrFormat("Circular data reference detected between '%s' and '%s'", TypeToString(mCurTypeInstance).c_str(), TypeToString(fieldTypeInst).c_str());
  4111. if (!mContext->mFieldResolveReentrys.IsEmpty())
  4112. {
  4113. failStr += StrFormat(" with the following fields:", TypeToString(mCurTypeInstance).c_str());
  4114. for (int i = 0; i < (int)mContext->mFieldResolveReentrys.size(); i++)
  4115. {
  4116. auto checkField = mContext->mFieldResolveReentrys[i];
  4117. if (i > 0)
  4118. failStr += ",";
  4119. failStr += "\n '" + TypeToString(typeInstance) + "." + checkField->GetFieldDef()->mName + "'";
  4120. if (checkField->mOwner == fieldTypeInst)
  4121. refNode = checkField->GetFieldDef()->mFieldDeclaration;
  4122. }
  4123. }
  4124. BfError* err = Fail(failStr, refNode);
  4125. if (err)
  4126. err->mIsPersistent = true;
  4127. }
  4128. }
  4129. }
  4130. bool useForUnion = false;
  4131. if (fieldInstance->mIsEnumPayloadCase)
  4132. {
  4133. if (!typeInstance->IsEnum())
  4134. {
  4135. Fail("Cases can only be used in enum types", fieldDef->mFieldDeclaration);
  4136. }
  4137. else
  4138. {
  4139. BF_ASSERT(typeInstance->mIsUnion);
  4140. }
  4141. }
  4142. if ((!fieldDef->mIsStatic) && (!resolvedFieldType->IsValuelessType()))
  4143. {
  4144. if (isUnion)
  4145. {
  4146. fieldInstance->mDataIdx = curFieldDataIdx;
  4147. }
  4148. }
  4149. }
  4150. if ((!typeInstance->IsSpecializedType()) && (!typeInstance->IsOnDemand()) && (fieldDef != NULL) && (!CheckDefineMemberProtection(fieldDef->mProtection, resolvedFieldType)))
  4151. {
  4152. //CS0052
  4153. Fail(StrFormat("Inconsistent accessibility: field type '%s' is less accessible than field '%s.%s'",
  4154. TypeToString(resolvedFieldType).c_str(), TypeToString(mCurTypeInstance).c_str(), fieldDef->mName.c_str()),
  4155. fieldDef->mTypeRef, true);
  4156. }
  4157. }
  4158. }
  4159. if (typeInstance->mIsUnion)
  4160. {
  4161. SetAndRestoreValue<BfTypeState::ResolveKind> prevResolveKind(typeState.mResolveKind, BfTypeState::ResolveKind_UnionInnerType);
  4162. unionInnerType = typeInstance->GetUnionInnerType();
  4163. }
  4164. if (!isOrdered)
  4165. {
  4166. int dataFieldCount = (int)dataFieldVec.size();
  4167. Array<Deque<BfFieldInstance*>> alignBuckets;
  4168. for (auto fieldInst : dataFieldVec)
  4169. {
  4170. int alignBits = GetHighestBitSet(fieldInst->GetAlign(packing));
  4171. while (alignBits >= alignBuckets.size())
  4172. alignBuckets.Add({});
  4173. alignBuckets[alignBits].Add(fieldInst);
  4174. }
  4175. dataFieldVec.clear();
  4176. int curSize = typeInstance->mInstSize;
  4177. while (dataFieldVec.size() != dataFieldCount)
  4178. {
  4179. // Clear out completed buckets
  4180. while (alignBuckets[alignBuckets.size() - 1].IsEmpty())
  4181. {
  4182. alignBuckets.pop_back();
  4183. }
  4184. int alignBits = GetNumLowZeroBits(curSize) + 1;
  4185. alignBits = BF_MIN(alignBits, (int)alignBuckets.size() - 1);
  4186. bool foundEntry = false;
  4187. while (alignBits >= 0)
  4188. {
  4189. if (alignBuckets[alignBits].IsEmpty())
  4190. {
  4191. alignBits--;
  4192. continue;
  4193. }
  4194. bool isHighestBucket = alignBits == alignBuckets.size() - 1;
  4195. auto fieldInst = alignBuckets[alignBits][0];
  4196. alignBuckets[alignBits].RemoveAt(0);
  4197. dataFieldVec.push_back(fieldInst);
  4198. curSize = BF_ALIGN(curSize, fieldInst->GetAlign(packing));
  4199. curSize += fieldInst->mResolvedType->mSize;
  4200. foundEntry = true;
  4201. if (!isHighestBucket)
  4202. {
  4203. // We may have a larger type that can fit now...
  4204. break;
  4205. }
  4206. }
  4207. if (!foundEntry)
  4208. {
  4209. // If no entries will fit, then force an entry of the smallest alignment
  4210. for (int alignBits = 0; alignBits < alignBuckets.size(); alignBits++)
  4211. {
  4212. if (!alignBuckets[alignBits].IsEmpty())
  4213. {
  4214. auto fieldInst = alignBuckets[alignBits][0];
  4215. alignBuckets[alignBits].RemoveAt(0);
  4216. dataFieldVec.push_back(fieldInst);
  4217. curSize = BF_ALIGN(curSize, fieldInst->GetAlign(packing));
  4218. curSize += fieldInst->mResolvedType->mSize;
  4219. break;
  4220. }
  4221. }
  4222. }
  4223. }
  4224. }
  4225. bool needsExplicitAlignment = true;
  4226. for (int fieldIdx = 0; fieldIdx < (int)dataFieldVec.size(); fieldIdx++)
  4227. {
  4228. auto fieldInstance = dataFieldVec[fieldIdx];
  4229. auto resolvedFieldType = fieldInstance->GetResolvedType();
  4230. BF_ASSERT(resolvedFieldType->mSize >= 0);
  4231. int dataSize = resolvedFieldType->mSize;
  4232. int alignSize = fieldInstance->GetAlign(packing);
  4233. fieldInstance->mDataSize = dataSize;
  4234. int nextDataPos = dataPos;
  4235. nextDataPos = (dataPos + (alignSize - 1)) & ~(alignSize - 1);
  4236. int padding = nextDataPos - dataPos;
  4237. if ((alignSize > 1) && (needsExplicitAlignment) && (padding > 0))
  4238. {
  4239. curFieldDataIdx++;
  4240. }
  4241. dataPos = nextDataPos;
  4242. fieldInstance->mDataOffset = dataPos;
  4243. fieldInstance->mDataIdx = curFieldDataIdx++;
  4244. typeInstance->mInstAlign = std::max(typeInstance->mInstAlign, alignSize);
  4245. dataPos += dataSize;
  4246. }
  4247. if (unionInnerType != NULL)
  4248. {
  4249. dataPos = unionInnerType->mSize;
  4250. typeInstance->mInstAlign = BF_MAX(unionInnerType->mAlign, typeInstance->mInstAlign);
  4251. }
  4252. // Old dataMemberHash location
  4253. CheckMemberNames(typeInstance);
  4254. if (alignOverride > 0)
  4255. typeInstance->mInstAlign = alignOverride;
  4256. else
  4257. typeInstance->mInstAlign = std::max(1, typeInstance->mInstAlign);
  4258. int alignSize = typeInstance->mInstAlign;
  4259. if (isCRepr)
  4260. {
  4261. // Align size to alignment
  4262. if (alignSize >= 1)
  4263. typeInstance->mInstSize = (dataPos + (alignSize - 1)) & ~(alignSize - 1);
  4264. typeInstance->mIsCRepr = true;
  4265. }
  4266. else
  4267. {
  4268. typeInstance->mInstSize = dataPos;
  4269. typeInstance->mIsCRepr = false;
  4270. }
  4271. if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL))
  4272. {
  4273. for (auto propDef : typeInstance->mTypeDef->mProperties)
  4274. if (propDef->mFieldDeclaration != NULL)
  4275. mCompiler->mResolvePassData->mAutoComplete->CheckProperty(BfNodeDynCast<BfPropertyDeclaration>(propDef->mFieldDeclaration));
  4276. }
  4277. }
  4278. if (typeInstance->IsObjectOrInterface())
  4279. typeInstance->mWantsGCMarking = true;
  4280. if ((mCompiler->mOptions.mEnableRealtimeLeakCheck) && (!typeInstance->mWantsGCMarking))
  4281. {
  4282. typeInstance->mTypeDef->PopulateMemberSets();
  4283. BfMemberSetEntry* entry = NULL;
  4284. BfMethodDef* methodDef = NULL;
  4285. if (typeInstance->mTypeDef->mMethodSet.TryGetWith(String(BF_METHODNAME_MARKMEMBERS), &entry))
  4286. {
  4287. methodDef = (BfMethodDef*)entry->mMemberDef;
  4288. if (methodDef->HasBody())
  4289. typeInstance->mWantsGCMarking = true;
  4290. }
  4291. }
  4292. if (typeInstance->IsValueType())
  4293. {
  4294. typeInstance->mSize = typeInstance->mInstSize;
  4295. typeInstance->mAlign = typeInstance->mInstAlign;
  4296. }
  4297. if ((mCompiler->mOptions.mAllowHotSwapping) && (typeInstance->mDefineState < BfTypeDefineState_Defined))
  4298. {
  4299. if (typeInstance->mHotTypeData == NULL)
  4300. {
  4301. BF_ASSERT(typeInstance->mTypeFailed);
  4302. }
  4303. else
  4304. {
  4305. auto hotTypeVersion = typeInstance->mHotTypeData->mTypeVersions.back();
  4306. if ((typeInstance->mBaseType != NULL) && (typeInstance->mBaseType->mHotTypeData != NULL))
  4307. {
  4308. hotTypeVersion->mMembers.Add(typeInstance->mBaseType->mHotTypeData->GetLatestVersion());
  4309. }
  4310. for (auto& fieldInst : typeInstance->mFieldInstances)
  4311. {
  4312. auto fieldDef = fieldInst.GetFieldDef();
  4313. if ((fieldDef == NULL) || (fieldDef->mIsStatic))
  4314. continue;
  4315. auto depType = fieldInst.mResolvedType;
  4316. while (depType->IsSizedArray())
  4317. depType = ((BfSizedArrayType*)depType)->mElementType;
  4318. if (depType->IsStruct())
  4319. {
  4320. PopulateType(depType);
  4321. auto depTypeInst = depType->ToTypeInstance();
  4322. BF_ASSERT(depTypeInst->mHotTypeData != NULL);
  4323. if (depTypeInst->mHotTypeData != NULL)
  4324. hotTypeVersion->mMembers.Add(depTypeInst->mHotTypeData->GetLatestVersion());
  4325. }
  4326. }
  4327. for (auto member : hotTypeVersion->mMembers)
  4328. member->mRefCount++;
  4329. }
  4330. }
  4331. if (_CheckTypeDone())
  4332. return;
  4333. if (typeInstance->mDefineState < BfTypeDefineState_Defined)
  4334. {
  4335. typeInstance->mDefineState = BfTypeDefineState_Defined;
  4336. if (!typeInstance->IsBoxed())
  4337. {
  4338. ExecuteCEOnCompile(NULL, typeInstance, BfCEOnCompileKind_TypeDone, underlyingTypeDeferred);
  4339. if (typeInstance->mDefineState == BfTypeDefineState_DefinedAndMethodsSlotted)
  4340. return;
  4341. }
  4342. }
  4343. if (typeInstance->mTypeFailed)
  4344. mHadBuildError = true;
  4345. CheckAddFailType();
  4346. BF_ASSERT_REL(typeInstance->mDefineState != BfTypeDefineState_DefinedAndMethodsSlotting);
  4347. BF_ASSERT_REL(typeInstance->mDefineState != BfTypeDefineState_DefinedAndMethodsSlotted);
  4348. BfLogSysM("Setting mNeedsMethodProcessing=true on %p\n", typeInstance);
  4349. typeInstance->mNeedsMethodProcessing = true;
  4350. typeInstance->mIsFinishingType = false;
  4351. ///
  4352. // 'Splattable' means that we can be passed via 3 or fewer primitive/pointer values
  4353. if (typeInstance->mHasUnderlyingArray)
  4354. {
  4355. // Never splat
  4356. }
  4357. else if (typeInstance->IsStruct())
  4358. {
  4359. bool hadNonSplattable = false;
  4360. if (typeInstance->mBaseType != NULL)
  4361. PopulateType(typeInstance->mBaseType, BfPopulateType_Data);
  4362. if ((typeInstance->mBaseType == NULL) || (typeInstance->mBaseType->IsSplattable()))
  4363. {
  4364. int dataCount = 0;
  4365. std::function<void(BfType*)> splatIterate;
  4366. splatIterate = [&](BfType* checkType)
  4367. {
  4368. if (checkType->IsValueType())
  4369. PopulateType(checkType, BfPopulateType_Data);
  4370. if (checkType->IsMethodRef())
  4371. {
  4372. // For simplicity, any methodRef inside a struct makes the struct non-splattable. This reduces cases of needing to
  4373. // handle embedded methodRefs
  4374. hadNonSplattable = true;
  4375. }
  4376. else if (checkType->IsOpaque())
  4377. {
  4378. hadNonSplattable = true;
  4379. }
  4380. else if (checkType->IsStruct())
  4381. {
  4382. auto checkTypeInstance = checkType->ToTypeInstance();
  4383. if (checkTypeInstance->mBaseType != NULL)
  4384. splatIterate(checkTypeInstance->mBaseType);
  4385. if (checkTypeInstance->mIsUnion)
  4386. {
  4387. bool wantSplat = false;
  4388. auto unionInnerType = checkTypeInstance->GetUnionInnerType(&wantSplat);
  4389. if (!wantSplat)
  4390. hadNonSplattable = true;
  4391. splatIterate(unionInnerType);
  4392. if (checkTypeInstance->IsEnum())
  4393. dataCount++; // Discriminator
  4394. }
  4395. else
  4396. {
  4397. for (int fieldIdx = 0; fieldIdx < (int)checkTypeInstance->mFieldInstances.size(); fieldIdx++)
  4398. {
  4399. auto fieldInstance = (BfFieldInstance*)&checkTypeInstance->mFieldInstances[fieldIdx];
  4400. if (fieldInstance->mDataIdx >= 0)
  4401. splatIterate(fieldInstance->GetResolvedType());
  4402. }
  4403. }
  4404. }
  4405. else if (!checkType->IsValuelessType())
  4406. {
  4407. if (checkType->IsSizedArray())
  4408. hadNonSplattable = true;
  4409. dataCount += checkType->GetSplatCount();
  4410. }
  4411. };
  4412. splatIterate(typeInstance);
  4413. if (isCRepr)
  4414. {
  4415. if ((mCompiler->mOptions.mMachineType == BfMachineType_x86) && (mCompiler->mOptions.mPlatformType == BfPlatformType_Windows))
  4416. {
  4417. typeInstance->mIsSplattable = (dataCount <= 4) && (!hadNonSplattable) && (dataPos > 4);
  4418. }
  4419. else
  4420. typeInstance->mIsSplattable = false;
  4421. }
  4422. else
  4423. typeInstance->mIsSplattable = (dataCount <= 3) && (!hadNonSplattable);
  4424. }
  4425. }
  4426. if (typeInstance->IsTypedPrimitive())
  4427. typeInstance->mIsSplattable = true;
  4428. if (typeInstance->mTypeDef->mIsOpaque)
  4429. typeInstance->mIsSplattable = false;
  4430. BF_ASSERT(mContext->mCurTypeState == &typeState);
  4431. // This is only required for autocomplete and finding type references
  4432. if (!typeInstance->IsSpecializedType())
  4433. {
  4434. for (auto propDef : typeDef->mProperties)
  4435. {
  4436. if (propDef->mTypeRef == NULL)
  4437. continue;
  4438. BfTypeState typeState;
  4439. typeState.mPrevState = mContext->mCurTypeState;
  4440. typeState.mCurTypeDef = propDef->mDeclaringType;
  4441. typeState.mType = typeInstance;
  4442. SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
  4443. ResolveTypeRef(propDef->mTypeRef, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowRef);
  4444. }
  4445. }
  4446. // Const handling
  4447. {
  4448. Dictionary<int64, BfFieldDef*> valueMap;
  4449. for (auto& fieldInstanceRef : typeInstance->mFieldInstances)
  4450. {
  4451. auto fieldInstance = &fieldInstanceRef;
  4452. if (!fieldInstance->mFieldIncluded)
  4453. continue;
  4454. auto fieldDef = fieldInstance->GetFieldDef();
  4455. if (fieldDef == NULL)
  4456. continue;
  4457. if ((fieldInstance->mConstIdx == -1) && (fieldDef->mIsConst))
  4458. {
  4459. SetAndRestoreValue<BfFieldDef*> prevTypeRef(mContext->mCurTypeState->mCurFieldDef, fieldDef);
  4460. typeInstance->mModule->ResolveConstField(typeInstance, fieldInstance, fieldDef);
  4461. // Check enum cases for duplicates
  4462. if (mCurTypeInstance->IsEnum())
  4463. {
  4464. auto underlyingType = fieldInstance->mResolvedType->GetUnderlyingType();
  4465. if ((fieldDef->IsEnumCaseEntry()) && (fieldInstance->mConstIdx != -1) && (underlyingType->IsIntegral()))
  4466. {
  4467. auto foreignConst = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
  4468. BfFieldDef** fieldDefPtr;
  4469. if (valueMap.TryAdd(foreignConst->mInt64, NULL, &fieldDefPtr))
  4470. {
  4471. *fieldDefPtr = fieldDef;
  4472. }
  4473. else if ((typeInstance->mCustomAttributes == NULL) || (typeInstance->mCustomAttributes->Get(mCompiler->mAllowDuplicatesAttributeTypeDef) == NULL))
  4474. {
  4475. auto error = Warn(0, StrFormat("Enum value '%lld' for field '%s' is not unique. Considering adding [AllowDuplicates] to the type declaration.", foreignConst->mInt64, fieldDef->mName.c_str()), fieldDef->GetRefNode(), true);
  4476. if (error != NULL)
  4477. mCompiler->mPassInstance->MoreInfo(StrFormat("This value was previously used for field '%s'", (*fieldDefPtr)->mName.c_str()), (*fieldDefPtr)->GetRefNode());
  4478. }
  4479. }
  4480. }
  4481. }
  4482. }
  4483. }
  4484. if ((typeInstance->IsEnum()) && (!typeInstance->IsPayloadEnum()))
  4485. {
  4486. BfLogSysM("Setting underlying type %p %d\n", typeInstance, underlyingTypeDeferred);
  4487. }
  4488. DoPopulateType_FinishEnum(typeInstance, underlyingTypeDeferred, &dataMemberHashCtx, unionInnerType);
  4489. if (!typeInstance->IsBoxed())
  4490. {
  4491. if (typeInstance->IsTypedPrimitive())
  4492. {
  4493. auto underlyingType = typeInstance->GetUnderlyingType();
  4494. dataMemberHashCtx.Mixin(underlyingType->mTypeId);
  4495. }
  4496. Val128 dataMemberHash = dataMemberHashCtx.Finish128();
  4497. if (typeInstance->mHotTypeData != NULL)
  4498. {
  4499. auto newHotTypeVersion = typeInstance->mHotTypeData->GetLatestVersion();
  4500. newHotTypeVersion->mDataHash = dataMemberHash;
  4501. if (mCompiler->mHotState != NULL)
  4502. {
  4503. auto committedHotTypeVersion = typeInstance->mHotTypeData->GetTypeVersion(mCompiler->mHotState->mCommittedHotCompileIdx);
  4504. if (committedHotTypeVersion != NULL)
  4505. {
  4506. if ((newHotTypeVersion->mDataHash != committedHotTypeVersion->mDataHash) && (typeInstance->mIsReified))
  4507. {
  4508. BfLogSysM("Hot compile detected data changes in %p '%s'\n", resolvedTypeRef, TypeToString(typeInstance).c_str());
  4509. if (!typeInstance->mHotTypeData->mPendingDataChange)
  4510. {
  4511. mCompiler->mHotState->mPendingDataChanges.Add(typeInstance->mTypeId);
  4512. typeInstance->mHotTypeData->mPendingDataChange = true;
  4513. }
  4514. else
  4515. {
  4516. BF_ASSERT(mCompiler->mHotState->mPendingDataChanges.Contains(typeInstance->mTypeId));
  4517. }
  4518. bool baseHadChanges = (typeInstance->mBaseType != NULL) && (typeInstance->mBaseType->mHotTypeData != NULL) && (typeInstance->mBaseType->mHotTypeData->mPendingDataChange);
  4519. if (!baseHadChanges)
  4520. Warn(0, StrFormat("Hot compile detected data changes in '%s'", TypeToString(typeInstance).c_str()), typeDef->GetRefNode());
  4521. }
  4522. else if (typeInstance->mHotTypeData->mPendingDataChange)
  4523. {
  4524. BfLogSysM("Hot compile removed pending data change for %p '%s'\n", resolvedTypeRef, TypeToString(typeInstance).c_str());
  4525. mCompiler->mHotState->RemovePendingChanges(typeInstance);
  4526. }
  4527. }
  4528. }
  4529. }
  4530. }
  4531. if (typeInstance == mContext->mBfObjectType)
  4532. typeInstance->mHasBeenInstantiated = true;
  4533. auto _HandleTypeDeclaration = [&](BfTypeDeclaration* typeDeclaration)
  4534. {
  4535. if ((typeDeclaration != NULL) && (typeDeclaration->mNameNode != NULL))
  4536. {
  4537. auto typeRefSource = typeDeclaration->mNameNode->GetParserData();
  4538. if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mSourceClassifier != NULL) && (typeRefSource != NULL) && (typeRefSource == mCompiler->mResolvePassData->mParser->mSourceData))
  4539. {
  4540. BfSourceElementType elemType = BfSourceElementType_Type;
  4541. if (typeInstance->IsInterface())
  4542. elemType = BfSourceElementType_Interface;
  4543. else if (typeInstance->IsObject())
  4544. elemType = BfSourceElementType_RefType;
  4545. else if (typeInstance->IsStruct() || (typeInstance->IsTypedPrimitive() && !typeInstance->IsEnum()))
  4546. elemType = BfSourceElementType_Struct;
  4547. mCompiler->mResolvePassData->mSourceClassifier->SetElementType(typeDeclaration->mNameNode, elemType);
  4548. }
  4549. }
  4550. };
  4551. if (!typeInstance->IsBoxed())
  4552. {
  4553. _HandleTypeDeclaration(typeDef->mTypeDeclaration);
  4554. for (auto partial : typeDef->mPartials)
  4555. _HandleTypeDeclaration(partial->mTypeDeclaration);
  4556. }
  4557. if (typeInstance->IsGenericTypeInstance())
  4558. {
  4559. auto genericTypeInst = (BfTypeInstance*)typeInstance;
  4560. if (!genericTypeInst->mGenericTypeInfo->mFinishedGenericParams)
  4561. FinishGenericParams(resolvedTypeRef);
  4562. }
  4563. if (populateType <= BfPopulateType_Data)
  4564. return;
  4565. disableYield.Release();
  4566. prevTypeState.Restore();
  4567. if (canDoMethodProcessing)
  4568. {
  4569. if (typeInstance->mNeedsMethodProcessing) // May have been handled by GetRawMethodInstanceAtIdx above
  4570. DoTypeInstanceMethodProcessing(typeInstance);
  4571. }
  4572. }
  4573. void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
  4574. {
  4575. if (typeInstance->IsSpecializedByAutoCompleteMethod())
  4576. return;
  4577. if (typeInstance->mDefineState == BfTypeDefineState_DefinedAndMethodsSlotting)
  4578. {
  4579. BfLogSysM("DoTypeInstanceMethodProcessing %p re-entrancy exit\n", typeInstance);
  4580. return;
  4581. }
  4582. BF_ASSERT_REL(typeInstance->mNeedsMethodProcessing);
  4583. BF_ASSERT_REL(typeInstance->mDefineState == BfTypeDefineState_Defined);
  4584. typeInstance->mDefineState = BfTypeDefineState_DefinedAndMethodsSlotting;
  4585. BF_ASSERT(typeInstance->mModule == this);
  4586. //TODO: This is new, make sure this is in the right place
  4587. /*if (mAwaitingInitFinish)
  4588. FinishInit();*/
  4589. AutoDisallowYield disableYield(mSystem);
  4590. SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, typeInstance);
  4591. SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, NULL);
  4592. BfLogSysM("DoTypeInstanceMethodProcessing: %p %s Revision:%d DefineState:%d\n", typeInstance, TypeToString(typeInstance).c_str(), typeInstance->mRevision, typeInstance->mDefineState);
  4593. auto typeDef = typeInstance->mTypeDef;
  4594. BfTypeOptions* typeOptions = NULL;
  4595. if (typeInstance->mTypeOptionsIdx >= 0)
  4596. typeOptions = mSystem->GetTypeOptions(typeInstance->mTypeOptionsIdx);
  4597. // Generate all methods. Pass 0
  4598. for (auto methodDef : typeDef->mMethods)
  4599. {
  4600. auto methodInstanceGroup = &typeInstance->mMethodInstanceGroups[methodDef->mIdx];
  4601. // Don't set these pointers during resolve pass because they may become invalid if it's just a temporary autocomplete method
  4602. if (mCompiler->mResolvePassData == NULL)
  4603. {
  4604. if ((methodDef->mMethodType == BfMethodType_Ctor) && (methodDef->mIsStatic))
  4605. {
  4606. typeInstance->mHasStaticInitMethod = true;
  4607. }
  4608. if ((methodDef->mMethodType == BfMethodType_Dtor) && (methodDef->mIsStatic))
  4609. {
  4610. typeInstance->mHasStaticDtorMethod = true;
  4611. }
  4612. if ((methodDef->mMethodType == BfMethodType_Normal) && (methodDef->mIsStatic) && (methodDef->mName == BF_METHODNAME_MARKMEMBERS_STATIC))
  4613. {
  4614. typeInstance->mHasStaticMarkMethod = true;
  4615. }
  4616. if ((methodDef->mMethodType == BfMethodType_Normal) && (methodDef->mIsStatic) && (methodDef->mName == BF_METHODNAME_FIND_TLS_MEMBERS))
  4617. {
  4618. typeInstance->mHasTLSFindMethod = true;
  4619. }
  4620. }
  4621. // Thsi MAY be generated already
  4622. // This should still be set to the default value
  4623. //BF_ASSERT((methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet) || (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude));
  4624. }
  4625. if (typeInstance == mContext->mBfObjectType)
  4626. {
  4627. BF_ASSERT(typeInstance->mInterfaceMethodTable.size() == 0);
  4628. }
  4629. int newIntefaceStartIdx = 0;
  4630. auto implBaseType = typeInstance->GetImplBaseType();
  4631. if (implBaseType != NULL)
  4632. {
  4633. auto baseTypeInst = implBaseType->ToTypeInstance();
  4634. if (implBaseType->IsIncomplete())
  4635. PopulateType(implBaseType, BfPopulateType_Full_Force);
  4636. typeInstance->mInterfaceMethodTable = baseTypeInst->mInterfaceMethodTable;
  4637. typeInstance->mVirtualMethodTable = implBaseType->mVirtualMethodTable;
  4638. typeInstance->mVirtualMethodTableSize = implBaseType->mVirtualMethodTableSize;
  4639. if ((!mCompiler->IsHotCompile()) && (!mCompiler->mPassInstance->HasFailed()) && ((mCompiler->mResolvePassData == NULL) || (mCompiler->mResolvePassData->mAutoComplete == NULL)))
  4640. {
  4641. BF_ASSERT(typeInstance->mVirtualMethodTable.size() == typeInstance->mVirtualMethodTableSize);
  4642. }
  4643. else
  4644. {
  4645. BF_ASSERT(typeInstance->mVirtualMethodTableSize >= (int)typeInstance->mVirtualMethodTable.size());
  4646. }
  4647. }
  4648. // Add new interfaces
  4649. for (int iFaceIdx = 0; iFaceIdx < (int)typeInstance->mInterfaces.size(); iFaceIdx++)
  4650. {
  4651. BfTypeInterfaceEntry& typeInterfaceInst = typeInstance->mInterfaces[iFaceIdx];
  4652. auto checkInterface = typeInterfaceInst.mInterfaceType;
  4653. if (checkInterface->IsIncomplete())
  4654. PopulateType(checkInterface, BfPopulateType_Full_Force);
  4655. typeInterfaceInst.mStartInterfaceTableIdx = (int)typeInstance->mInterfaceMethodTable.size();
  4656. // We don't add to the vtable for interface declarations, we just reference the listed interfaces
  4657. if (!typeInstance->IsInterface())
  4658. {
  4659. auto interfaceTypeDef = checkInterface->mTypeDef;
  4660. BF_ASSERT(interfaceTypeDef->mMethods.size() == checkInterface->mMethodInstanceGroups.size());
  4661. // Reserve empty entries
  4662. for (int methodIdx = 0; methodIdx < (int)interfaceTypeDef->mMethods.size(); methodIdx++)
  4663. typeInstance->mInterfaceMethodTable.push_back(BfTypeInterfaceMethodEntry());
  4664. }
  4665. }
  4666. auto checkTypeInstance = typeInstance;
  4667. while (checkTypeInstance != NULL)
  4668. {
  4669. // These may have been already added
  4670. for (auto&& interfaceEntry : checkTypeInstance->mInterfaces)
  4671. AddDependency(interfaceEntry.mInterfaceType, typeInstance, BfDependencyMap::DependencyFlag_ImplementsInterface);
  4672. checkTypeInstance = checkTypeInstance->GetImplBaseType();
  4673. }
  4674. //for (auto& intefaceInst : typeInstance->mInterfaces)
  4675. if (typeInstance == mContext->mBfObjectType)
  4676. {
  4677. BF_ASSERT(typeInstance->mInterfaceMethodTable.size() == 1);
  4678. }
  4679. // Slot interfaces method blocks in vtable
  4680. {
  4681. int ifaceVirtIdx = 0;
  4682. std::unordered_map<BfTypeInstance*, BfTypeInterfaceEntry*> interfaceMap;
  4683. BfTypeInstance* checkType = typeInstance->GetImplBaseType();
  4684. while (checkType != NULL)
  4685. {
  4686. for (auto&& ifaceEntry : checkType->mInterfaces)
  4687. {
  4688. interfaceMap[ifaceEntry.mInterfaceType] = &ifaceEntry;
  4689. ifaceVirtIdx = std::max(ifaceVirtIdx, ifaceEntry.mStartVirtualIdx + ifaceEntry.mInterfaceType->mVirtualMethodTableSize);
  4690. }
  4691. checkType = checkType->GetImplBaseType();
  4692. }
  4693. for (int iFaceIdx = 0; iFaceIdx < (int)typeInstance->mInterfaces.size(); iFaceIdx++)
  4694. {
  4695. BfTypeInterfaceEntry& typeInterfaceInst = typeInstance->mInterfaces[iFaceIdx];
  4696. auto itr = interfaceMap.find(typeInterfaceInst.mInterfaceType);
  4697. if (itr != interfaceMap.end())
  4698. {
  4699. auto prevEntry = itr->second;
  4700. typeInterfaceInst.mStartVirtualIdx = prevEntry->mStartVirtualIdx;
  4701. }
  4702. else
  4703. {
  4704. typeInterfaceInst.mStartVirtualIdx = ifaceVirtIdx;
  4705. ifaceVirtIdx += typeInterfaceInst.mInterfaceType->mVirtualMethodTableSize;
  4706. interfaceMap[typeInterfaceInst.mInterfaceType] = &typeInterfaceInst;
  4707. }
  4708. }
  4709. }
  4710. auto isBoxed = typeInstance->IsBoxed();
  4711. BfLogSysM("Setting mTypeIncomplete = false on %p\n", typeInstance);
  4712. typeInstance->mNeedsMethodProcessing = false;
  4713. typeInstance->mTypeIncomplete = false;
  4714. auto checkBaseType = typeInstance->GetImplBaseType();
  4715. while (checkBaseType != NULL)
  4716. {
  4717. PopulateType(checkBaseType, BfPopulateType_Full_Force);
  4718. BF_ASSERT((!checkBaseType->IsIncomplete()) || (checkBaseType->mTypeFailed));
  4719. checkBaseType = checkBaseType->GetImplBaseType();
  4720. }
  4721. if ((mCompiler->mOptions.mHasVDataExtender) && (!typeInstance->IsInterface()))
  4722. {
  4723. // This is the vExt entry for this type instance
  4724. BfVirtualMethodEntry entry;
  4725. entry.mDeclaringMethod.mMethodNum = -1;
  4726. entry.mDeclaringMethod.mTypeInstance = typeInstance;
  4727. typeInstance->mVirtualMethodTable.push_back(entry);
  4728. typeInstance->mVirtualMethodTableSize++;
  4729. }
  4730. // Fill out to correct size
  4731. if (typeInstance->mHotTypeData != NULL)
  4732. {
  4733. //auto hotLatestVersionHead = typeInstance->mHotTypeData->GetLatestVersionHead();
  4734. int wantVTableSize = typeInstance->GetImplBaseVTableSize() + (int)typeInstance->mHotTypeData->mVTableEntries.size();
  4735. while ((int)typeInstance->mVirtualMethodTable.size() < wantVTableSize)
  4736. {
  4737. typeInstance->mVirtualMethodTable.push_back(BfVirtualMethodEntry());
  4738. typeInstance->mVirtualMethodTableSize++;
  4739. }
  4740. }
  4741. BfAmbiguityContext ambiguityContext;
  4742. ambiguityContext.mTypeInstance = typeInstance;
  4743. ambiguityContext.mModule = this;
  4744. ambiguityContext.mIsProjectSpecific = false;
  4745. bool wantsOnDemandMethods = false;
  4746. //TODO: Testing having interface methods be "on demand"...
  4747. //if (!typeInstance->IsInterface())
  4748. //
  4749. {
  4750. if ((typeInstance->IsSpecializedType()) || (typeInstance->IsUnspecializedTypeVariation()))
  4751. wantsOnDemandMethods = true;
  4752. else if ((mCompiler->mOptions.mCompileOnDemandKind != BfCompileOnDemandKind_AlwaysInclude) &&
  4753. (!typeInstance->IsUnspecializedTypeVariation()))
  4754. {
  4755. //if (typeDef->mName->ToString() != "AttributeUsageAttribute")
  4756. auto attributeDef = mCompiler->mAttributeTypeDef;
  4757. auto attributeType = mContext->mUnreifiedModule->ResolveTypeDef(attributeDef, BfPopulateType_Identity)->ToTypeInstance();
  4758. if (!TypeIsSubTypeOf(mCurTypeInstance, attributeType, false))
  4759. {
  4760. wantsOnDemandMethods = true;
  4761. }
  4762. }
  4763. }
  4764. //bool allDeclsRequired = (mIsReified) && (mCompiler->mOptions.mEmitDebugInfo) && ();
  4765. bool allDeclsRequired = false;
  4766. //if ((mIsReified) && (mCompiler->mOptions.mEmitDebugInfo) && (!mCompiler->mWantsDeferMethodDecls))
  4767. // if ((mIsReified) && (mCompiler->mOptions.mEmitDebugInfo))
  4768. // {
  4769. // allDeclsRequired = true;
  4770. // }
  4771. HashSet<String> ifaceMethodNameSet;
  4772. if (wantsOnDemandMethods)
  4773. {
  4774. for (int iFaceIdx = newIntefaceStartIdx; iFaceIdx < (int)typeInstance->mInterfaces.size(); iFaceIdx++)
  4775. {
  4776. BfTypeInterfaceEntry& typeInterfaceInst = typeInstance->mInterfaces[iFaceIdx];
  4777. for (auto checkMethodDef : typeInterfaceInst.mInterfaceType->mTypeDef->mMethods)
  4778. {
  4779. ifaceMethodNameSet.Add(checkMethodDef->mName);
  4780. }
  4781. }
  4782. }
  4783. bool isFailedType = mCurTypeInstance->mTypeFailed;
  4784. if (auto genericTypeInst = mCurTypeInstance->ToGenericTypeInstance())
  4785. {
  4786. if (genericTypeInst->mGenericTypeInfo->mHadValidateErrors)
  4787. isFailedType = true;
  4788. }
  4789. bool typeOptionsIncludeAll = false;
  4790. bool typeOptionsIncludeFiltered = false;
  4791. if (typeOptions != NULL)
  4792. {
  4793. typeOptionsIncludeAll = typeOptions->Apply(typeOptionsIncludeAll, BfOptionFlags_ReflectAlwaysIncludeAll);
  4794. typeOptionsIncludeFiltered = typeOptions->Apply(typeOptionsIncludeAll, BfOptionFlags_ReflectAlwaysIncludeFiltered);
  4795. }
  4796. // Generate all methods. Pass 1
  4797. for (auto methodDef : typeDef->mMethods)
  4798. {
  4799. auto methodInstanceGroup = &typeInstance->mMethodInstanceGroups[methodDef->mIdx];
  4800. if (typeOptions != NULL)
  4801. {
  4802. BfOptionFlags optionFlags = BfOptionFlags_ReflectNonStaticMethods;
  4803. if (methodDef->mMethodType == BfMethodType_Ctor)
  4804. optionFlags = BfOptionFlags_ReflectConstructors;
  4805. else if (methodDef->mIsStatic)
  4806. optionFlags = BfOptionFlags_ReflectStaticMethods;
  4807. methodInstanceGroup->mExplicitlyReflected = typeOptions->Apply(false, optionFlags);
  4808. methodInstanceGroup->mExplicitlyReflected = ApplyTypeOptionMethodFilters(methodInstanceGroup->mExplicitlyReflected, methodDef, typeOptions);
  4809. }
  4810. if ((typeInstance->mCustomAttributes != NULL) && (typeInstance->mCustomAttributes->Contains(mCompiler->mReflectAttributeTypeDef)))
  4811. methodInstanceGroup->mExplicitlyReflected = true;
  4812. if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude)
  4813. continue;
  4814. if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_InWorkList)
  4815. continue;
  4816. if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Referenced)
  4817. continue;
  4818. if (isFailedType)
  4819. {
  4820. // We don't want method decls from failed generic types to clog up our type system
  4821. continue;
  4822. }
  4823. BF_ASSERT((methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet) ||
  4824. (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingDecl) ||
  4825. (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingReference));
  4826. if ((isBoxed) && (!methodDef->mIsVirtual))
  4827. {
  4828. if (methodDef->mIsStatic)
  4829. continue;
  4830. bool boxedRequired = false;
  4831. if (((methodDef->mMethodType == BfMethodType_Ctor) && (methodDef->mParams.size() == 0)) ||
  4832. (methodDef->mMethodType == BfMethodType_Dtor) ||
  4833. ((methodDef->mName == BF_METHODNAME_MARKMEMBERS) || (methodDef->mName == BF_METHODNAME_MARKMEMBERS_STATIC) || (methodDef->mName == BF_METHODNAME_INVOKE) || (methodDef->mName == BF_METHODNAME_DYNAMICCAST)) ||
  4834. (methodDef->mGenericParams.size() != 0))
  4835. boxedRequired = true;
  4836. if (!boxedRequired)
  4837. {
  4838. if (wantsOnDemandMethods)
  4839. {
  4840. methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_NoDecl_AwaitingReference;
  4841. mOnDemandMethodCount++;
  4842. }
  4843. continue;
  4844. }
  4845. }
  4846. if (methodDef->mMethodType == BfMethodType_Ignore)
  4847. continue;
  4848. if ((methodDef->mName == BF_METHODNAME_DYNAMICCAST) && (typeInstance->IsValueType()))
  4849. continue; // This is just a placeholder for boxed types
  4850. bool doAlwaysInclude = false;
  4851. if (wantsOnDemandMethods)
  4852. {
  4853. bool implRequired = false;
  4854. bool declRequired = false;
  4855. if ((!typeInstance->IsGenericTypeInstance()) && (methodDef->mGenericParams.IsEmpty()))
  4856. {
  4857. // For non-generic methods, declare all methods. This is useful for debug info.
  4858. declRequired = true;
  4859. }
  4860. if (methodDef->mMethodType == BfMethodType_CtorNoBody)
  4861. declRequired = true;
  4862. if ((methodDef->mIsStatic) &&
  4863. ((methodDef->mMethodType == BfMethodType_Dtor) || (methodDef->mMethodType == BfMethodType_Ctor)))
  4864. {
  4865. implRequired = true;
  4866. }
  4867. if (mCompiler->mOptions.mEnableRealtimeLeakCheck)
  4868. {
  4869. if ((methodDef->mName == BF_METHODNAME_MARKMEMBERS_STATIC) ||
  4870. (methodDef->mName == BF_METHODNAME_FIND_TLS_MEMBERS) ||
  4871. ((methodDef->mName == BF_METHODNAME_MARKMEMBERS) && (typeInstance->IsObject())))
  4872. implRequired = true;
  4873. }
  4874. BfAttributeDirective* attributes = NULL;
  4875. if (auto methodDeclaration = methodDef->GetMethodDeclaration())
  4876. attributes = methodDeclaration->mAttributes;
  4877. if (auto propertyDeclaration = methodDef->GetPropertyDeclaration())
  4878. attributes = propertyDeclaration->mAttributes;
  4879. while (attributes != NULL)
  4880. {
  4881. if (attributes->mAttributeTypeRef != NULL)
  4882. {
  4883. auto typeRefName = attributes->mAttributeTypeRef->ToCleanAttributeString();
  4884. if (typeRefName == "AlwaysInclude")
  4885. implRequired = true;
  4886. else if (typeRefName == "Export")
  4887. implRequired = true;
  4888. else if (typeRefName == "Test")
  4889. implRequired = true;
  4890. else
  4891. declRequired = true; // We need to create so we can check for AlwaysInclude in included attributes
  4892. }
  4893. attributes = attributes->mNextAttribute;
  4894. }
  4895. if ((mProject != NULL) && (mProject->mAlwaysIncludeAll) && (methodDef->mBody != NULL))
  4896. {
  4897. implRequired = true;
  4898. declRequired = true;
  4899. }
  4900. if (typeInstance->IncludeAllMethods())
  4901. implRequired = true;
  4902. // "AssumeInstantiated" also forces default ctor
  4903. if (((typeInstance->mAlwaysIncludeFlags & BfAlwaysIncludeFlag_AssumeInstantiated) != 0) &&
  4904. (methodDef->IsDefaultCtor()))
  4905. implRequired = true;
  4906. if ((typeOptionsIncludeAll) && (ApplyTypeOptionMethodFilters(true, methodDef, typeOptions)))
  4907. if ((typeOptionsIncludeAll || typeOptionsIncludeFiltered) && (ApplyTypeOptionMethodFilters(typeOptionsIncludeAll, methodDef, typeOptions)))
  4908. implRequired = true;
  4909. // if ((typeOptions != NULL) && (CheckTypeOptionMethodFilters(typeOptions, methodDef)))
  4910. // implRequired = true;
  4911. if (typeInstance->IsInterface())
  4912. declRequired = true;
  4913. if (methodDef->mIsVirtual)
  4914. declRequired = true;
  4915. if (!implRequired)
  4916. {
  4917. // Any interface with the same name causes us to not be on-demand
  4918. if (ifaceMethodNameSet.Contains(methodDef->mName))
  4919. declRequired = true;
  4920. }
  4921. // Is this strictly necessary? It will reduce our compilation speed in order to ensure methods are available for debug info
  4922. if (allDeclsRequired)
  4923. declRequired = true;
  4924. if (methodDef->mMethodDeclaration == NULL)
  4925. {
  4926. // Internal methods don't need decls
  4927. if ((methodDef->mName == BF_METHODNAME_DEFAULT_EQUALS) ||
  4928. (methodDef->mName == BF_METHODNAME_DEFAULT_STRICT_EQUALS))
  4929. declRequired = false;
  4930. }
  4931. if (methodDef->mMethodType == BfMethodType_Init)
  4932. {
  4933. declRequired = false;
  4934. implRequired = false;
  4935. }
  4936. if (!implRequired)
  4937. {
  4938. if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet)
  4939. {
  4940. if (!mIsScratchModule)
  4941. mOnDemandMethodCount++;
  4942. }
  4943. if (!declRequired)
  4944. {
  4945. if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet)
  4946. methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_NoDecl_AwaitingReference;
  4947. continue;
  4948. }
  4949. else
  4950. {
  4951. if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet)
  4952. methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingDecl;
  4953. }
  4954. VerifyOnDemandMethods();
  4955. }
  4956. else
  4957. {
  4958. doAlwaysInclude = true;
  4959. }
  4960. }
  4961. else
  4962. doAlwaysInclude = true;
  4963. if (doAlwaysInclude)
  4964. {
  4965. bool wasDeclared = (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingDecl) ||
  4966. (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingReference);
  4967. methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_AlwaysInclude;
  4968. if (wasDeclared)
  4969. {
  4970. if (!mIsScratchModule)
  4971. mOnDemandMethodCount--;
  4972. if (methodInstanceGroup->mDefault != NULL)
  4973. AddMethodToWorkList(methodInstanceGroup->mDefault);
  4974. }
  4975. }
  4976. }
  4977. BF_ASSERT_REL(typeInstance->mDefineState < BfTypeDefineState_DefinedAndMethodsSlotted);
  4978. BfLogSysM("Starting DoTypeInstanceMethodProcessing %p GetMethodInstance pass. OnDemandMethods: %d\n", typeInstance, mOnDemandMethodCount);
  4979. // Def passes. First non-overrides then overrides (for in-place overrides in methods)
  4980. for (int pass = 0; pass < 2; pass++)
  4981. {
  4982. for (auto methodDef : typeDef->mMethods)
  4983. {
  4984. if ((pass == 1) != (methodDef->mIsOverride))
  4985. continue;
  4986. bool doGetMethodInstance = true;
  4987. auto methodInstanceGroup = &typeInstance->mMethodInstanceGroups[methodDef->mIdx];
  4988. if ((methodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_AlwaysInclude) &&
  4989. (methodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_Decl_AwaitingDecl))
  4990. {
  4991. BfLogSysM("Skipping GetMethodInstance on MethodDef: %p OnDemandKind: %d\n", methodDef, methodInstanceGroup->mOnDemandKind);
  4992. doGetMethodInstance = false;
  4993. }
  4994. if (methodDef->mMethodType == BfMethodType_Init)
  4995. doGetMethodInstance = false;
  4996. BfMethodInstance* methodInstance = NULL;
  4997. if (doGetMethodInstance)
  4998. {
  4999. int prevWorklistSize = (int)mContext->mMethodWorkList.size();
  5000. auto flags = ((methodDef->mGenericParams.size() != 0) || (typeInstance->IsUnspecializedType())) ? BfGetMethodInstanceFlag_UnspecializedPass : BfGetMethodInstanceFlag_None;
  5001. if (methodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_AlwaysInclude)
  5002. flags = (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_MethodInstanceOnly);
  5003. auto moduleMethodInstance = GetMethodInstance(typeInstance, methodDef, BfTypeVector(), flags);
  5004. methodInstance = moduleMethodInstance.mMethodInstance;
  5005. if (methodInstance == NULL)
  5006. {
  5007. BF_ASSERT(typeInstance->IsGenericTypeInstance() && (typeInstance->mTypeDef->mIsCombinedPartial));
  5008. continue;
  5009. }
  5010. if ((!mCompiler->mIsResolveOnly) &&
  5011. ((methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingReference) || (!typeInstance->IsReified())))
  5012. {
  5013. bool forceMethodImpl = false;
  5014. BfCustomAttributes* customAttributes = methodInstance->GetCustomAttributes();
  5015. if ((customAttributes != NULL) && (typeInstance->IsReified()))
  5016. {
  5017. for (auto& attr : customAttributes->mAttributes)
  5018. {
  5019. auto attrTypeInst = attr.mType->ToTypeInstance();
  5020. auto attrCustomAttributes = attrTypeInst->mCustomAttributes;
  5021. if (attrCustomAttributes == NULL)
  5022. continue;
  5023. for (auto& attrAttr : attrCustomAttributes->mAttributes)
  5024. {
  5025. if (attrAttr.mType->ToTypeInstance()->IsInstanceOf(mCompiler->mAttributeUsageAttributeTypeDef))
  5026. {
  5027. // Check for Flags arg
  5028. if (attrAttr.mCtorArgs.size() < 2)
  5029. continue;
  5030. auto constant = attrTypeInst->mConstHolder->GetConstant(attrAttr.mCtorArgs[1]);
  5031. if (constant == NULL)
  5032. continue;
  5033. if (constant->mTypeCode == BfTypeCode_Boolean)
  5034. continue;
  5035. if ((constant->mInt8 & BfCustomAttributeFlags_AlwaysIncludeTarget) != 0)
  5036. forceMethodImpl = true;
  5037. if (attrTypeInst->mAttributeData == NULL)
  5038. PopulateType(attrTypeInst);
  5039. BF_ASSERT(attrTypeInst->mAttributeData != NULL);
  5040. if (attrTypeInst->mAttributeData != NULL)
  5041. {
  5042. if ((attrTypeInst->mAttributeData->mAlwaysIncludeUser & BfAlwaysIncludeFlag_IncludeAllMethods) != 0)
  5043. forceMethodImpl = true;
  5044. // "AssumeInstantiated" also forces default ctor
  5045. if (((attrTypeInst->mAttributeData->mAlwaysIncludeUser & BfAlwaysIncludeFlag_AssumeInstantiated) != 0) &&
  5046. (methodDef->mMethodType == BfMethodType_Ctor) && (methodDef->mParams.IsEmpty()))
  5047. forceMethodImpl = true;
  5048. }
  5049. }
  5050. }
  5051. }
  5052. }
  5053. if (methodInstance->mMethodDef->mDeclaringType->mProject->mTargetType == BfTargetType_BeefTest)
  5054. {
  5055. if ((customAttributes != NULL) && (customAttributes->Contains(mCompiler->mTestAttributeTypeDef)))
  5056. {
  5057. forceMethodImpl = true;
  5058. }
  5059. }
  5060. if (forceMethodImpl)
  5061. {
  5062. if (!typeInstance->IsReified())
  5063. mContext->mScratchModule->PopulateType(typeInstance, BfPopulateType_Data);
  5064. // Reify method
  5065. mContext->mScratchModule->GetMethodInstance(typeInstance, methodDef, BfTypeVector());
  5066. BF_ASSERT(methodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_Decl_AwaitingReference);
  5067. }
  5068. }
  5069. }
  5070. else
  5071. {
  5072. methodInstance = methodInstanceGroup->mDefault;
  5073. if (methodInstance == NULL)
  5074. continue;
  5075. }
  5076. bool methodUsedVirtually = false;
  5077. if (typeInstance->IsInterface())
  5078. {
  5079. if ((!methodDef->mIsConcrete) && (!methodDef->mIsStatic) && (!methodInstance->HasSelf()))
  5080. SlotInterfaceMethod(methodInstance);
  5081. }
  5082. else if (!methodDef->IsEmptyPartial())
  5083. {
  5084. methodUsedVirtually = SlotVirtualMethod(methodInstance, &ambiguityContext);
  5085. }
  5086. // This is important for reducing latency of autocomplete popup, but it's important we don't allow the autocomplete
  5087. // thread to cause any reentry issues by re-populating a type at an "inopportune time". We do allow certain
  5088. // reentries in PopulateType, but not when we're resolving fields (for example)
  5089. if ((mContext->mFieldResolveReentrys.size() == 0) && (!mContext->mResolvingVarField))
  5090. {
  5091. disableYield.Release();
  5092. mContext->CheckLockYield();
  5093. disableYield.Acquire();
  5094. }
  5095. }
  5096. }
  5097. BF_ASSERT(typeInstance->mVirtualMethodTable.size() == typeInstance->mVirtualMethodTableSize);
  5098. if ((isBoxed) && (!typeInstance->IsUnspecializedTypeVariation()))
  5099. {
  5100. // Any interface method that can be called virtually via an interface pointer needs to go into the boxed type
  5101. auto underlyingType = typeInstance->GetUnderlyingType();
  5102. BfTypeInstance* underlyingTypeInstance;
  5103. if (underlyingType->IsPrimitiveType())
  5104. underlyingTypeInstance = GetPrimitiveStructType(((BfPrimitiveType*)underlyingType)->mTypeDef->mTypeCode);
  5105. else
  5106. underlyingTypeInstance = underlyingType->ToTypeInstance();
  5107. if (underlyingTypeInstance != NULL)
  5108. {
  5109. PopulateType(underlyingTypeInstance, BfPopulateType_Full_Force);
  5110. for (int ifaceIdx = 0; ifaceIdx < (int)underlyingTypeInstance->mInterfaces.size(); ifaceIdx++)
  5111. {
  5112. auto& underlyingIFaceTypeInst = underlyingTypeInstance->mInterfaces[ifaceIdx];
  5113. auto& boxedIFaceTypeInst = typeInstance->mInterfaces[ifaceIdx];
  5114. BF_ASSERT(underlyingIFaceTypeInst.mInterfaceType == boxedIFaceTypeInst.mInterfaceType);
  5115. auto ifaceInst = underlyingIFaceTypeInst.mInterfaceType;
  5116. int startIdx = underlyingIFaceTypeInst.mStartInterfaceTableIdx;
  5117. int boxedStartIdx = boxedIFaceTypeInst.mStartInterfaceTableIdx;
  5118. int iMethodCount = (int)ifaceInst->mMethodInstanceGroups.size();
  5119. for (int iMethodIdx = 0; iMethodIdx < iMethodCount; iMethodIdx++)
  5120. {
  5121. auto matchedMethodRef = &underlyingTypeInstance->mInterfaceMethodTable[iMethodIdx + startIdx].mMethodRef;
  5122. auto boxedMatchedMethodRef = &typeInstance->mInterfaceMethodTable[iMethodIdx + boxedStartIdx].mMethodRef;
  5123. BfMethodInstance* matchedMethod = *matchedMethodRef;
  5124. auto ifaceMethodInst = ifaceInst->mMethodInstanceGroups[iMethodIdx].mDefault;
  5125. if (ifaceMethodInst->mVirtualTableIdx != -1)
  5126. {
  5127. if (matchedMethod == NULL)
  5128. {
  5129. // Assert on base type?
  5130. //AssertErrorState();
  5131. }
  5132. else
  5133. {
  5134. auto matchedMethodDef = matchedMethod->mMethodDef;
  5135. if (!matchedMethod->mIsForeignMethodDef)
  5136. {
  5137. BfMethodInstanceGroup* boxedMethodInstanceGroup = &typeInstance->mMethodInstanceGroups[matchedMethod->mMethodDef->mIdx];
  5138. if (boxedMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NoDecl_AwaitingReference)
  5139. {
  5140. boxedMethodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingDecl;
  5141. VerifyOnDemandMethods();
  5142. }
  5143. }
  5144. auto methodFlags = matchedMethod->mIsForeignMethodDef ? BfGetMethodInstanceFlag_ForeignMethodDef : BfGetMethodInstanceFlag_None;
  5145. methodFlags = (BfGetMethodInstanceFlags)(methodFlags | BfGetMethodInstanceFlag_MethodInstanceOnly);
  5146. auto moduleMethodInstance = GetMethodInstance(typeInstance, matchedMethodDef, BfTypeVector(),
  5147. methodFlags,
  5148. matchedMethod->GetForeignType());
  5149. auto methodInstance = moduleMethodInstance.mMethodInstance;
  5150. UniqueSlotVirtualMethod(methodInstance);
  5151. *boxedMatchedMethodRef = methodInstance;
  5152. }
  5153. }
  5154. }
  5155. }
  5156. }
  5157. }
  5158. if (typeInstance->mHotTypeData != NULL)
  5159. {
  5160. auto latestVersion = typeInstance->mHotTypeData->GetLatestVersion();
  5161. auto latestVersionHead = typeInstance->mHotTypeData->GetLatestVersionHead();
  5162. if (typeInstance->mHotTypeData->mVTableOrigLength != -1)
  5163. {
  5164. bool hasSlotError = false;
  5165. BF_ASSERT(mCompiler->IsHotCompile());
  5166. //typeInstance->mHotTypeData->mDirty = true;
  5167. //Val128 vtHash;
  5168. Array<int> ifaceMapping;
  5169. ifaceMapping.Resize(latestVersionHead->mInterfaceMapping.size());
  5170. typeInstance->CalcHotVirtualData(&ifaceMapping);
  5171. // Hot swapping allows for interfaces to be added to types or removed from types, but it doesn't allow
  5172. // interfaces to be added when the slot number has already been used -- even if the interface using
  5173. // that slot has been removed.
  5174. for (int slotIdx = 0; slotIdx < (int)ifaceMapping.size(); slotIdx++)
  5175. {
  5176. int newId = ifaceMapping[slotIdx];
  5177. int oldId = 0;
  5178. if (slotIdx < (int)latestVersionHead->mInterfaceMapping.size())
  5179. oldId = latestVersionHead->mInterfaceMapping[slotIdx];
  5180. if ((newId != oldId) && (newId != 0) && (oldId != 0))
  5181. {
  5182. String interfaceName;
  5183. for (auto iface : typeInstance->mInterfaces)
  5184. {
  5185. if (iface.mInterfaceType->mTypeId == newId)
  5186. interfaceName = TypeToString(iface.mInterfaceType);
  5187. }
  5188. Warn(0, StrFormat("Hot swap detected resolvable interface slot collision with '%s'.", interfaceName.c_str()), typeDef->mTypeDeclaration);
  5189. BF_ASSERT(latestVersion != latestVersionHead);
  5190. if (!hasSlotError)
  5191. {
  5192. latestVersion->mInterfaceMapping = ifaceMapping;
  5193. }
  5194. hasSlotError = true;
  5195. }
  5196. else if (hasSlotError)
  5197. {
  5198. if (oldId != 0)
  5199. latestVersion->mInterfaceMapping[slotIdx] = oldId;
  5200. }
  5201. if (oldId != 0)
  5202. ifaceMapping[slotIdx] = oldId;
  5203. }
  5204. latestVersionHead->mInterfaceMapping = ifaceMapping;
  5205. if (hasSlotError)
  5206. mCompiler->mHotState->mPendingFailedSlottings.Add(typeInstance->mTypeId);
  5207. else
  5208. mCompiler->mHotState->mPendingFailedSlottings.Remove(typeInstance->mTypeId);
  5209. }
  5210. }
  5211. if ((typeInstance->IsInterface()) && (!typeInstance->IsUnspecializedType()) && (typeInstance->mIsReified) && (typeInstance->mSlotNum == -1) && (mCompiler->IsHotCompile()))
  5212. {
  5213. mCompiler->mHotState->mHasNewInterfaceTypes = true;
  5214. }
  5215. if ((!typeInstance->IsInterface()) && (!typeInstance->IsUnspecializedTypeVariation()) && (!isBoxed) && (!isFailedType))
  5216. {
  5217. if (!typeInstance->mTypeDef->mIsAbstract)
  5218. {
  5219. for (int methodIdx = 0; methodIdx < (int) typeInstance->mVirtualMethodTable.size(); methodIdx++)
  5220. {
  5221. auto& methodRef = typeInstance->mVirtualMethodTable[methodIdx].mImplementingMethod;
  5222. if (methodRef.mMethodNum == -1)
  5223. {
  5224. BF_ASSERT(mCompiler->mOptions.mHasVDataExtender);
  5225. if (methodRef.mTypeInstance == typeInstance)
  5226. {
  5227. if (typeInstance->GetImplBaseType() != NULL)
  5228. BF_ASSERT(methodIdx == (int)typeInstance->GetImplBaseType()->mVirtualMethodTableSize);
  5229. }
  5230. continue;
  5231. }
  5232. auto methodInstance = (BfMethodInstance*)methodRef;
  5233. if ((methodInstance != NULL) && (methodInstance->mMethodDef->mIsAbstract))
  5234. {
  5235. if (methodInstance->mMethodDef->mIsAbstract)
  5236. {
  5237. if (typeInstance->mVirtualMethodTable[methodIdx].mDeclaringMethod.mTypeInstance == typeInstance)
  5238. {
  5239. Fail("Method is abstract but it is declared in non-abstract class", methodInstance->mMethodDef->GetRefNode());
  5240. }
  5241. else if (!typeInstance->IsUnspecializedTypeVariation())
  5242. {
  5243. if (Fail(StrFormat("'%s' does not implement inherited abstract method '%s'", TypeToString(typeInstance).c_str(), MethodToString(methodInstance).c_str()), typeDef->mTypeDeclaration->mNameNode, true) != NULL)
  5244. mCompiler->mPassInstance->MoreInfo("Abstract method declared", methodInstance->mMethodDef->GetRefNode());
  5245. }
  5246. }
  5247. else
  5248. {
  5249. if (!typeInstance->IsUnspecializedType())
  5250. AssertErrorState();
  5251. }
  5252. }
  5253. }
  5254. }
  5255. std::unordered_set<String> missingIFaceMethodNames;
  5256. for (auto& ifaceTypeInst : typeInstance->mInterfaces)
  5257. {
  5258. auto ifaceInst = ifaceTypeInst.mInterfaceType;
  5259. int startIdx = ifaceTypeInst.mStartInterfaceTableIdx;
  5260. int iMethodCount = (int)ifaceInst->mMethodInstanceGroups.size();
  5261. auto declTypeDef = ifaceTypeInst.mDeclaringType;
  5262. for (int iMethodIdx = 0; iMethodIdx < iMethodCount; iMethodIdx++)
  5263. {
  5264. auto matchedMethodRef = &typeInstance->mInterfaceMethodTable[iMethodIdx + startIdx].mMethodRef;
  5265. BfMethodInstance* matchedMethod = *matchedMethodRef;
  5266. auto ifaceMethodInst = ifaceInst->mMethodInstanceGroups[iMethodIdx].mDefault;
  5267. if ((matchedMethod == NULL) && (ifaceMethodInst != NULL))
  5268. {
  5269. missingIFaceMethodNames.insert(ifaceMethodInst->mMethodDef->mName);
  5270. }
  5271. }
  5272. }
  5273. if (!missingIFaceMethodNames.empty())
  5274. {
  5275. // Attempt to find matching entries in base types
  5276. ambiguityContext.mIsReslotting = true;
  5277. auto checkType = typeInstance->GetImplBaseType();
  5278. while (checkType != NULL)
  5279. {
  5280. for (auto& methodGroup : checkType->mMethodInstanceGroups)
  5281. {
  5282. auto methodInstance = methodGroup.mDefault;
  5283. if (methodInstance != NULL)
  5284. {
  5285. if ((methodInstance->mMethodDef->mProtection != BfProtection_Private) &&
  5286. (!methodInstance->mMethodDef->mIsOverride) &&
  5287. (missingIFaceMethodNames.find(methodInstance->mMethodDef->mName) != missingIFaceMethodNames.end()))
  5288. {
  5289. SlotVirtualMethod(methodInstance, &ambiguityContext);
  5290. }
  5291. }
  5292. }
  5293. checkType = checkType->GetImplBaseType();
  5294. }
  5295. }
  5296. for (auto& ifaceTypeInst : typeInstance->mInterfaces)
  5297. {
  5298. auto ifaceInst = ifaceTypeInst.mInterfaceType;
  5299. int startIdx = ifaceTypeInst.mStartInterfaceTableIdx;
  5300. int iMethodCount = (int)ifaceInst->mMethodInstanceGroups.size();
  5301. auto declTypeDef = ifaceTypeInst.mDeclaringType;
  5302. for (int iMethodIdx = 0; iMethodIdx < iMethodCount; iMethodIdx++)
  5303. {
  5304. auto matchedMethodRef = &typeInstance->mInterfaceMethodTable[iMethodIdx + startIdx].mMethodRef;
  5305. BfMethodInstance* matchedMethod = *matchedMethodRef;
  5306. auto ifaceMethodInst = ifaceInst->mMethodInstanceGroups[iMethodIdx].mDefault;
  5307. if (ifaceMethodInst == NULL)
  5308. continue;
  5309. auto iReturnType = ifaceMethodInst->mReturnType;
  5310. if (iReturnType->IsUnspecializedTypeVariation())
  5311. {
  5312. BfType* resolvedType = ResolveGenericType(iReturnType, NULL, NULL);
  5313. if (resolvedType != NULL)
  5314. iReturnType = resolvedType;
  5315. else
  5316. iReturnType = typeInstance;
  5317. }
  5318. if (ifaceMethodInst->mMethodDef->mIsOverride)
  5319. continue; // Don't consider overrides here
  5320. // If we have "ProjA depends on LibBase", "ProjB depends on LibBase", then a type ClassC in LibBase implementing IFaceD,
  5321. // where IFaceD gets extended with MethodE in ProjA, an implementing MethodE is still required to exist on ClassC --
  5322. // the visibility is bidirectional. A type ClassF implementing IFaceD inside ProjB will not be required to implement
  5323. // MethodE, however
  5324. if ((!ifaceInst->IsTypeMemberAccessible(ifaceMethodInst->mMethodDef->mDeclaringType, ifaceTypeInst.mDeclaringType)) &&
  5325. (!ifaceInst->IsTypeMemberAccessible(ifaceTypeInst.mDeclaringType, ifaceMethodInst->mMethodDef->mDeclaringType)))
  5326. continue;
  5327. if (!ifaceInst->IsTypeMemberIncluded(ifaceMethodInst->mMethodDef->mDeclaringType, ifaceTypeInst.mDeclaringType))
  5328. continue;
  5329. bool hadMatch = matchedMethod != NULL;
  5330. bool hadPubFailure = false;
  5331. bool hadStaticFailure = false;
  5332. bool hadMutFailure = false;
  5333. if (hadMatch)
  5334. {
  5335. if ((matchedMethod->GetExplicitInterface() == NULL) && (matchedMethod->mMethodDef->mProtection != BfProtection_Public))
  5336. {
  5337. hadMatch = false;
  5338. hadPubFailure = true;
  5339. }
  5340. if (matchedMethod->mMethodDef->mIsStatic != ifaceMethodInst->mMethodDef->mIsStatic)
  5341. {
  5342. hadMatch = false;
  5343. hadStaticFailure = true;
  5344. }
  5345. if (ifaceMethodInst->mVirtualTableIdx != -1)
  5346. {
  5347. if (matchedMethod->mReturnType != iReturnType)
  5348. hadMatch = false;
  5349. }
  5350. else
  5351. {
  5352. // Concrete/generic
  5353. if (!CanCast(GetFakeTypedValue(matchedMethod->mReturnType), iReturnType))
  5354. hadMatch = false;
  5355. }
  5356. // If we have mExplicitInterface set then we already gave a mut error (if needed)
  5357. if ((typeInstance->IsValueType()) && (matchedMethod->GetExplicitInterface() == NULL) &&
  5358. (matchedMethod->mMethodDef->mIsMutating) && (!ifaceMethodInst->mMethodDef->mIsMutating))
  5359. {
  5360. hadMutFailure = true;
  5361. hadMatch = false;
  5362. }
  5363. }
  5364. if (!hadMatch)
  5365. {
  5366. if (!typeInstance->IsUnspecializedTypeVariation())
  5367. {
  5368. auto bestMethodInst = ifaceMethodInst;
  5369. auto bestInterface = ifaceInst;
  5370. if (matchedMethod == NULL)
  5371. {
  5372. bool searchFailed = false;
  5373. for (auto& checkIFaceTypeInst : typeInstance->mInterfaces)
  5374. {
  5375. auto checkIFaceInst = checkIFaceTypeInst.mInterfaceType;
  5376. int checkStartIdx = checkIFaceTypeInst.mStartInterfaceTableIdx;
  5377. int checkIMethodCount = (int)checkIFaceInst->mMethodInstanceGroups.size();
  5378. for (int checkIMethodIdx = 0; checkIMethodIdx < checkIMethodCount; checkIMethodIdx++)
  5379. {
  5380. auto checkIFaceMethodInst = checkIFaceInst->mMethodInstanceGroups[checkIMethodIdx].mDefault;
  5381. if ((checkIFaceMethodInst != NULL) && (checkIFaceMethodInst->mMethodDef->mIsOverride))
  5382. {
  5383. bool cmpResult = CompareMethodSignatures(checkIFaceMethodInst, ifaceMethodInst);
  5384. if (cmpResult)
  5385. {
  5386. bool isBetter = TypeIsSubTypeOf(checkIFaceInst, bestInterface);
  5387. bool isWorse = TypeIsSubTypeOf(bestInterface, checkIFaceInst);
  5388. if (isBetter == isWorse)
  5389. {
  5390. CompareDeclTypes(checkIFaceMethodInst->mMethodDef->mDeclaringType, bestMethodInst->mMethodDef->mDeclaringType, isBetter, isWorse);
  5391. }
  5392. if ((isBetter) && (!isWorse))
  5393. {
  5394. bestInterface = checkIFaceInst;
  5395. bestMethodInst = checkIFaceMethodInst;
  5396. }
  5397. else if (isBetter == isWorse)
  5398. {
  5399. if (!searchFailed)
  5400. {
  5401. searchFailed = true;
  5402. auto error = Fail(StrFormat("There is no most-specific default implementation of '%s'", MethodToString(ifaceMethodInst).c_str()), declTypeDef->mTypeDeclaration->mNameNode);
  5403. if (error != NULL)
  5404. {
  5405. mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' is a candidate",
  5406. MethodToString(bestMethodInst).c_str()), bestMethodInst->mMethodDef->GetRefNode());
  5407. mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' is a candidate",
  5408. MethodToString(checkIFaceMethodInst).c_str()), checkIFaceMethodInst->mMethodDef->GetRefNode());
  5409. }
  5410. //candidate implementations include '%s' and '%s'",
  5411. //TypeToString(checkIFaceInst).c_str(), TypeToString(bestInterface).c_str()), );
  5412. }
  5413. }
  5414. }
  5415. }
  5416. }
  5417. }
  5418. if (bestMethodInst->mReturnType != ifaceMethodInst->mReturnType)
  5419. {
  5420. auto error = Fail(StrFormat("Default interface method '%s' cannot be used because it doesn't have the return type '%s'",
  5421. MethodToString(bestMethodInst).c_str(), TypeToString(ifaceMethodInst->mReturnType).c_str()), declTypeDef->mTypeDeclaration->mNameNode);
  5422. if (error != NULL)
  5423. {
  5424. mCompiler->mPassInstance->MoreInfo("See original method declaration", ifaceMethodInst->mMethodDef->GetRefNode());
  5425. mCompiler->mPassInstance->MoreInfo("See override method declaration", bestMethodInst->mMethodDef->GetRefNode());
  5426. }
  5427. }
  5428. }
  5429. bool hasDefaultImpl = bestMethodInst->mMethodDef->HasBody() || bestMethodInst->mMethodDef->mIsAbstract;
  5430. if ((hasDefaultImpl) && (matchedMethod == NULL))
  5431. {
  5432. auto methodDef = bestMethodInst->mMethodDef;
  5433. BfGetMethodInstanceFlags flags = (BfGetMethodInstanceFlags)(BfGetMethodInstanceFlag_ForeignMethodDef | BfGetMethodInstanceFlag_MethodInstanceOnly);
  5434. if ((methodDef->mGenericParams.size() != 0) || (typeInstance->IsUnspecializedType()))
  5435. flags = (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_UnspecializedPass);
  5436. auto methodInst = GetMethodInstance(typeInstance, methodDef, BfTypeVector(), flags, ifaceInst);
  5437. if (methodInst)
  5438. {
  5439. *matchedMethodRef = methodInst.mMethodInstance;
  5440. BfMethodInstance* newMethodInstance = methodInst.mMethodInstance;
  5441. BF_ASSERT(newMethodInstance->mIsForeignMethodDef);
  5442. if (newMethodInstance->mMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingReference)
  5443. {
  5444. if (!mIsScratchModule)
  5445. mOnDemandMethodCount++;
  5446. }
  5447. continue;
  5448. }
  5449. }
  5450. if (typeInstance->IsBoxed())
  5451. {
  5452. if (ifaceMethodInst->mMethodDef->mIsStatic)
  5453. {
  5454. // Skip the statics, those can't be invoked
  5455. }
  5456. else
  5457. {
  5458. // The unboxed version should have had the same error
  5459. if (!typeInstance->GetUnderlyingType()->IsIncomplete())
  5460. AssertErrorState();
  5461. }
  5462. }
  5463. else if ((typeInstance->mRebuildFlags & BfTypeRebuildFlag_ConstEvalCancelled) != 0)
  5464. {
  5465. // It's possible const eval was supposed to generate this method. We're rebuilding the type anyway.
  5466. }
  5467. else
  5468. {
  5469. String methodString;
  5470. ///
  5471. {
  5472. BfTypeState typeState;
  5473. typeState.mPrevState = mContext->mCurTypeState;
  5474. typeState.mForceActiveTypeDef = declTypeDef;
  5475. SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
  5476. SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, ifaceMethodInst);
  5477. methodString = MethodToString(ifaceMethodInst);
  5478. }
  5479. BfTypeDeclaration* typeDecl = declTypeDef->mTypeDeclaration;
  5480. BfError* error = Fail(StrFormat("'%s' does not implement interface member '%s'", TypeToString(typeInstance).c_str(), methodString.c_str()), typeDecl->mNameNode, true);
  5481. if ((matchedMethod != NULL) && (error != NULL))
  5482. {
  5483. if (hadStaticFailure)
  5484. {
  5485. auto staticNodeRef = matchedMethod->mMethodDef->GetRefNode();
  5486. if (auto methodDecl = BfNodeDynCast<BfMethodDeclaration>(matchedMethod->mMethodDef->mMethodDeclaration))
  5487. if (methodDecl->mStaticSpecifier != NULL)
  5488. staticNodeRef = methodDecl->mStaticSpecifier;
  5489. if (matchedMethod->mMethodDef->mIsStatic)
  5490. mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' cannot match because it's static",
  5491. methodString.c_str()), staticNodeRef);
  5492. else
  5493. mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' cannot match because it's not static",
  5494. methodString.c_str()), staticNodeRef);
  5495. }
  5496. else if (hadPubFailure)
  5497. {
  5498. mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' cannot match because it's not public",
  5499. methodString.c_str()), matchedMethod->mMethodDef->mReturnTypeRef);
  5500. }
  5501. else if (ifaceMethodInst->mReturnType->IsConcreteInterfaceType())
  5502. {
  5503. mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' cannot match because it does not have a concrete return type that implements '%s'",
  5504. methodString.c_str(), TypeToString(ifaceMethodInst->mReturnType).c_str()), matchedMethod->mMethodDef->mReturnTypeRef);
  5505. }
  5506. else if (hadMutFailure)
  5507. {
  5508. mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' cannot match because it's market as 'mut' but interface method does not allow it",
  5509. methodString.c_str()), matchedMethod->mMethodDef->GetMutNode());
  5510. mCompiler->mPassInstance->MoreInfo(StrFormat("Declare the interface method as 'mut' to allow matching 'mut' implementations"), ifaceMethodInst->mMethodDef->mMethodDeclaration);
  5511. }
  5512. else
  5513. {
  5514. mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' cannot match because it does not have the return type '%s'",
  5515. methodString.c_str(), TypeToString(ifaceMethodInst->mReturnType).c_str()), matchedMethod->mMethodDef->mReturnTypeRef);
  5516. if ((ifaceMethodInst->mVirtualTableIdx != -1) && (ifaceMethodInst->mReturnType->IsInterface()))
  5517. mCompiler->mPassInstance->MoreInfo("Declare the interface method as 'concrete' to allow matching concrete return values", ifaceMethodInst->mMethodDef->GetMethodDeclaration()->mVirtualSpecifier);
  5518. }
  5519. }
  5520. }
  5521. }
  5522. // Clear out the entry
  5523. *matchedMethodRef = BfMethodRef();
  5524. }
  5525. }
  5526. }
  5527. }
  5528. VerifyOnDemandMethods();
  5529. ambiguityContext.Finish();
  5530. CheckAddFailType();
  5531. typeInstance->mDefineState = BfTypeDefineState_DefinedAndMethodsSlotted;
  5532. mCompiler->mStats.mTypesPopulated++;
  5533. mCompiler->UpdateCompletion();
  5534. BF_ASSERT_REL(!typeInstance->mNeedsMethodProcessing);
  5535. BfLogSysM("Finished DoTypeInstanceMethodProcessing %p. OnDemandMethods: %d Virtual Size: %d InterfaceMethodTableSize: %d\n", typeInstance, mOnDemandMethodCount, typeInstance->mVirtualMethodTable.size(), typeInstance->mInterfaceMethodTable.size());
  5536. }
  5537. void BfModule::RebuildMethods(BfTypeInstance* typeInstance)
  5538. {
  5539. if (typeInstance->IsIncomplete())
  5540. return;
  5541. BfLogSysM("RebuildMethods setting mNeedsMethodProcessing=true on %p\n", typeInstance);
  5542. BF_ASSERT_REL(typeInstance->mDefineState != BfTypeDefineState_DefinedAndMethodsSlotting);
  5543. typeInstance->mNeedsMethodProcessing = true;
  5544. typeInstance->mDefineState = BfTypeDefineState_Defined;
  5545. typeInstance->mTypeIncomplete = true;
  5546. for (auto& methodInstanceGroup : typeInstance->mMethodInstanceGroups)
  5547. {
  5548. delete methodInstanceGroup.mDefault;
  5549. methodInstanceGroup.mDefault = NULL;
  5550. delete methodInstanceGroup.mMethodSpecializationMap;
  5551. methodInstanceGroup.mMethodSpecializationMap = NULL;
  5552. methodInstanceGroup.mOnDemandKind = BfMethodOnDemandKind_NotSet;
  5553. }
  5554. BfTypeProcessRequest* typeProcessRequest = mContext->mPopulateTypeWorkList.Alloc();
  5555. typeProcessRequest->mType = typeInstance;
  5556. BF_ASSERT(typeInstance->mContext == mContext);
  5557. mCompiler->mStats.mTypesQueued++;
  5558. mCompiler->UpdateCompletion();
  5559. }
  5560. BfModule* BfModule::GetModuleFor(BfType* type)
  5561. {
  5562. auto typeInst = type->ToTypeInstance();
  5563. if (typeInst == NULL)
  5564. return NULL;
  5565. return typeInst->mModule;
  5566. }
  5567. void BfModule::AddMethodToWorkList(BfMethodInstance* methodInstance)
  5568. {
  5569. BF_ASSERT(!methodInstance->mMethodDef->mIsAbstract);
  5570. if (methodInstance->IsSpecializedByAutoCompleteMethod())
  5571. return;
  5572. BF_ASSERT(mCompiler->mCompileState != BfCompiler::CompileState_VData);
  5573. if ((methodInstance->mIsReified) && (!methodInstance->mIsUnspecialized))
  5574. {
  5575. BF_ASSERT(mCompiler->mCompileState != BfCompiler::CompileState_Unreified);
  5576. }
  5577. if (methodInstance->IsOrInUnspecializedVariation())
  5578. {
  5579. return;
  5580. }
  5581. BF_ASSERT(!methodInstance->GetOwner()->IsUnspecializedTypeVariation());
  5582. BF_ASSERT(methodInstance->mMethodProcessRequest == NULL);
  5583. auto defaultMethod = methodInstance->mMethodInstanceGroup->mDefault;
  5584. if (defaultMethod != methodInstance)
  5585. {
  5586. BF_ASSERT(defaultMethod != NULL);
  5587. if (methodInstance->mMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingReference)
  5588. {
  5589. if ((defaultMethod->mIsReified) && (!defaultMethod->mDeclModule->mIsModuleMutable))
  5590. {
  5591. defaultMethod->mDeclModule->PrepareForIRWriting(methodInstance->GetOwner());
  5592. }
  5593. AddMethodToWorkList(defaultMethod);
  5594. // This should put all the specialized methods in the worklist, including us
  5595. return;
  5596. }
  5597. }
  5598. if (methodInstance->mDeclModule != NULL)
  5599. {
  5600. if (methodInstance->mDeclModule != this)
  5601. {
  5602. methodInstance->mDeclModule->AddMethodToWorkList(methodInstance);
  5603. return;
  5604. }
  5605. }
  5606. else
  5607. {
  5608. auto module = GetOrCreateMethodModule(methodInstance);
  5609. methodInstance->mDeclModule = module;
  5610. BfIRValue func = CreateFunctionFrom(methodInstance, false, methodInstance->mAlwaysInline);
  5611. methodInstance->mIRFunction = func;
  5612. module->mFuncReferences[methodInstance] = func;
  5613. module->AddMethodToWorkList(methodInstance);
  5614. return;
  5615. }
  5616. if ((!methodInstance->mIRFunction) && (methodInstance->mIsReified) && (!methodInstance->mIsUnspecialized) &&
  5617. (methodInstance->GetImportCallKind() == BfImportCallKind_None))
  5618. {
  5619. if (!mIsModuleMutable)
  5620. PrepareForIRWriting(methodInstance->GetOwner());
  5621. SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, mWantsIRIgnoreWrites);
  5622. BfIRValue func = CreateFunctionFrom(methodInstance, false, methodInstance->mAlwaysInline);
  5623. if (func)
  5624. {
  5625. methodInstance->mIRFunction = func;
  5626. mFuncReferences[methodInstance] = func;
  5627. }
  5628. }
  5629. BF_ASSERT(methodInstance->mDeclModule == this);
  5630. if (defaultMethod == methodInstance)
  5631. {
  5632. if (methodInstance->mMethodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_AlwaysInclude)
  5633. {
  5634. auto owningModule = methodInstance->GetOwner()->GetModule();
  5635. BF_ASSERT(methodInstance->mMethodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_Referenced);
  5636. if (!mIsScratchModule)
  5637. {
  5638. auto onDemandModule = owningModule;
  5639. if (owningModule->mParentModule != NULL)
  5640. onDemandModule = owningModule->mParentModule;
  5641. owningModule->VerifyOnDemandMethods();
  5642. if (methodInstance->mMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet)
  5643. owningModule->mOnDemandMethodCount++;
  5644. BF_ASSERT(onDemandModule->mOnDemandMethodCount > 0);
  5645. VerifyOnDemandMethods();
  5646. }
  5647. methodInstance->mMethodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_InWorkList;
  5648. if (methodInstance->mMethodInstanceGroup->mMethodSpecializationMap != NULL)
  5649. {
  5650. for (auto& kv : *methodInstance->mMethodInstanceGroup->mMethodSpecializationMap)
  5651. {
  5652. auto specMethodInstance = kv.mValue;
  5653. if ((!specMethodInstance->mDeclModule->mIsModuleMutable) && (!specMethodInstance->mDeclModule->mReifyQueued))
  5654. {
  5655. specMethodInstance->mDeclModule->PrepareForIRWriting(specMethodInstance->GetOwner());
  5656. }
  5657. specMethodInstance->mDeclModule->AddMethodToWorkList(specMethodInstance);
  5658. }
  5659. }
  5660. }
  5661. }
  5662. else
  5663. {
  5664. BF_ASSERT(defaultMethod->mMethodInstanceGroup->IsImplemented());
  5665. }
  5666. BF_ASSERT(methodInstance->mDeclModule != NULL);
  5667. auto typeInstance = methodInstance->GetOwner();
  5668. BfMethodProcessRequest* methodProcessRequest = mContext->mMethodWorkList.Alloc();
  5669. if (mCompiler->mCompileState == BfCompiler::CompileState_Unreified)
  5670. {
  5671. if (methodInstance->mIsReified)
  5672. {
  5673. BfLogSysM("Marking method %d as unreified due to CompileState_Unreified\n", methodInstance);
  5674. methodInstance->mIsReified = false;
  5675. }
  5676. }
  5677. //BF_ASSERT(!methodInstance->mIsReified);
  5678. methodProcessRequest->mType = typeInstance;
  5679. methodProcessRequest->mMethodInstance = methodInstance;
  5680. methodProcessRequest->mRevision = typeInstance->mRevision;
  5681. methodProcessRequest->mFromModuleRebuildIdx = mRebuildIdx;
  5682. methodProcessRequest->mFromModule = this;
  5683. if ((!mCompiler->mIsResolveOnly) && (methodInstance->mIsReified))
  5684. {
  5685. if ((!mIsModuleMutable) && (!mIsScratchModule))
  5686. {
  5687. BF_ASSERT(!mGeneratesCode);
  5688. StartNewRevision(BfModule::RebuildKind_None);
  5689. }
  5690. BF_ASSERT(mIsModuleMutable || mReifyQueued);
  5691. }
  5692. BF_ASSERT((mBfIRBuilder != NULL) || (!methodInstance->mIsReified));
  5693. BfLogSysM("Adding to mMethodWorkList Module: %p IncompleteMethodCount: %d Type %p MethodInstance: %p Name:%s TypeRevision: %d ModuleRevision: %d ReqId:%d\n", this, mIncompleteMethodCount, typeInstance, methodInstance, methodInstance->mMethodDef->mName.c_str(), methodProcessRequest->mRevision, methodProcessRequest->mFromModuleRevision, methodProcessRequest->mReqId);
  5694. if (mAwaitingFinish)
  5695. {
  5696. BfLogSysM("Module: %p No longer awaiting finish\n", this);
  5697. mAwaitingFinish = false;
  5698. }
  5699. mCompiler->mStats.mMethodsQueued++;
  5700. mCompiler->UpdateCompletion();
  5701. mIncompleteMethodCount++;
  5702. if (methodInstance->GetNumGenericArguments() != 0)
  5703. mHasGenericMethods = true;
  5704. methodInstance->mMethodProcessRequest = methodProcessRequest;
  5705. }
  5706. BfArrayType* BfModule::CreateArrayType(BfType* resolvedType, int dimensions)
  5707. {
  5708. BF_ASSERT(!resolvedType->IsVar());
  5709. BF_ASSERT(!resolvedType->IsIntUnknown());
  5710. auto arrayTypeDef = mCompiler->GetArrayTypeDef(dimensions);
  5711. if (arrayTypeDef == NULL)
  5712. return NULL;
  5713. auto arrayType = mContext->mArrayTypePool.Get();
  5714. delete arrayType->mGenericTypeInfo;
  5715. arrayType->mGenericTypeInfo = new BfGenericTypeInfo();
  5716. arrayType->mContext = mContext;
  5717. arrayType->mTypeDef = arrayTypeDef;
  5718. arrayType->mDimensions = dimensions;
  5719. arrayType->mGenericTypeInfo->mTypeGenericArguments.clear();
  5720. arrayType->mGenericTypeInfo->mTypeGenericArguments.push_back(resolvedType);
  5721. auto resolvedArrayType = ResolveType(arrayType);
  5722. if (resolvedArrayType != arrayType)
  5723. {
  5724. arrayType->Dispose();
  5725. mContext->mArrayTypePool.GiveBack(arrayType);
  5726. }
  5727. return (BfArrayType*)resolvedArrayType;
  5728. }
  5729. BfSizedArrayType* BfModule::CreateSizedArrayType(BfType * resolvedType, int size)
  5730. {
  5731. BF_ASSERT(!resolvedType->IsVar());
  5732. auto arrayType = mContext->mSizedArrayTypePool.Get();
  5733. arrayType->mContext = mContext;
  5734. arrayType->mElementType = resolvedType;
  5735. arrayType->mElementCount = size;
  5736. auto resolvedArrayType = ResolveType(arrayType);
  5737. if (resolvedArrayType != arrayType)
  5738. mContext->mSizedArrayTypePool.GiveBack(arrayType);
  5739. return (BfSizedArrayType*)resolvedArrayType;
  5740. }
  5741. BfUnknownSizedArrayType* BfModule::CreateUnknownSizedArrayType(BfType* resolvedType, BfType* sizeParam)
  5742. {
  5743. BF_ASSERT(!resolvedType->IsVar());
  5744. BF_ASSERT(sizeParam->IsGenericParam());
  5745. auto arrayType = mContext->mUnknownSizedArrayTypePool.Get();
  5746. arrayType->mContext = mContext;
  5747. arrayType->mElementType = resolvedType;
  5748. arrayType->mElementCount = -1;
  5749. arrayType->mElementCountSource = sizeParam;
  5750. auto resolvedArrayType = ResolveType(arrayType);
  5751. if (resolvedArrayType != arrayType)
  5752. mContext->mUnknownSizedArrayTypePool.GiveBack(arrayType);
  5753. return (BfUnknownSizedArrayType*)resolvedArrayType;
  5754. }
  5755. BfPointerType* BfModule::CreatePointerType(BfType* resolvedType)
  5756. {
  5757. BF_ASSERT(!resolvedType->IsVar());
  5758. auto pointerType = mContext->mPointerTypePool.Get();
  5759. pointerType->mContext = mContext;
  5760. pointerType->mElementType = resolvedType;
  5761. auto resolvedPointerType = (BfPointerType*)ResolveType(pointerType);
  5762. if (resolvedPointerType != pointerType)
  5763. mContext->mPointerTypePool.GiveBack(pointerType);
  5764. BF_ASSERT(resolvedPointerType->mElementType == resolvedType);
  5765. return resolvedPointerType;
  5766. }
  5767. BfConstExprValueType* BfModule::CreateConstExprValueType(const BfTypedValue& typedValue, bool allowCreate)
  5768. {
  5769. BfPopulateType populateType = allowCreate ? BfPopulateType_Data : BfPopulateType_Identity;
  5770. BfResolveTypeRefFlags resolveFlags = allowCreate ? BfResolveTypeRefFlag_None : BfResolveTypeRefFlag_NoCreate;
  5771. auto variant = TypedValueToVariant(NULL, typedValue);
  5772. if (variant.mTypeCode == BfTypeCode_None)
  5773. return NULL;
  5774. auto constExprValueType = mContext->mConstExprValueTypePool.Get();
  5775. constExprValueType->mContext = mContext;
  5776. constExprValueType->mType = typedValue.mType;
  5777. constExprValueType->mValue = variant;
  5778. auto resolvedConstExprValueType = (BfConstExprValueType*)ResolveType(constExprValueType, populateType, resolveFlags);
  5779. if (resolvedConstExprValueType != constExprValueType)
  5780. mContext->mConstExprValueTypePool.GiveBack(constExprValueType);
  5781. if (resolvedConstExprValueType != NULL)
  5782. BF_ASSERT(resolvedConstExprValueType->mValue.mInt64 == constExprValueType->mValue.mInt64);
  5783. return resolvedConstExprValueType;
  5784. }
  5785. BfConstExprValueType* BfModule::CreateConstExprValueType(const BfVariant& variant, BfType* type, bool allowCreate)
  5786. {
  5787. BfPopulateType populateType = allowCreate ? BfPopulateType_Data : BfPopulateType_Identity;
  5788. BfResolveTypeRefFlags resolveFlags = allowCreate ? BfResolveTypeRefFlag_None : BfResolveTypeRefFlag_NoCreate;
  5789. if (variant.mTypeCode == BfTypeCode_None)
  5790. return NULL;
  5791. auto constExprValueType = mContext->mConstExprValueTypePool.Get();
  5792. constExprValueType->mContext = mContext;
  5793. constExprValueType->mType = type;
  5794. constExprValueType->mValue = variant;
  5795. auto resolvedConstExprValueType = (BfConstExprValueType*)ResolveType(constExprValueType, populateType, resolveFlags);
  5796. if (resolvedConstExprValueType != constExprValueType)
  5797. mContext->mConstExprValueTypePool.GiveBack(constExprValueType);
  5798. if (resolvedConstExprValueType != NULL)
  5799. BF_ASSERT(resolvedConstExprValueType->mValue.mInt64 == constExprValueType->mValue.mInt64);
  5800. return resolvedConstExprValueType;
  5801. }
  5802. BfTypeInstance* BfModule::GetWrappedStructType(BfType* type, bool allowSpecialized)
  5803. {
  5804. if (type->IsPointer())
  5805. {
  5806. if (allowSpecialized)
  5807. {
  5808. BfPointerType* pointerType = (BfPointerType*)type;
  5809. BfTypeVector typeVector;
  5810. typeVector.Add(pointerType->mElementType);
  5811. return ResolveTypeDef(mCompiler->mPointerTTypeDef, typeVector, BfPopulateType_Data)->ToTypeInstance();
  5812. }
  5813. else
  5814. return ResolveTypeDef(mCompiler->mPointerTTypeDef, BfPopulateType_Data)->ToTypeInstance();
  5815. }
  5816. else if (type->IsMethodRef())
  5817. {
  5818. if (allowSpecialized)
  5819. {
  5820. BfMethodRefType* methodRefType = (BfMethodRefType*)type;
  5821. BfTypeVector typeVector;
  5822. typeVector.Add(methodRefType);
  5823. return ResolveTypeDef(mCompiler->mMethodRefTypeDef, typeVector, BfPopulateType_Data)->ToTypeInstance();
  5824. }
  5825. else
  5826. return ResolveTypeDef(mCompiler->mMethodRefTypeDef, BfPopulateType_Data)->ToTypeInstance();
  5827. }
  5828. else if (type->IsSizedArray())
  5829. {
  5830. if (allowSpecialized)
  5831. {
  5832. if (type->IsUnknownSizedArrayType())
  5833. {
  5834. BfUnknownSizedArrayType* sizedArrayType = (BfUnknownSizedArrayType*)type;
  5835. BfTypeVector typeVector;
  5836. typeVector.Add(sizedArrayType->mElementType);
  5837. typeVector.Add(sizedArrayType->mElementCountSource);
  5838. return ResolveTypeDef(mCompiler->mSizedArrayTypeDef, typeVector, BfPopulateType_Data)->ToTypeInstance();
  5839. }
  5840. BfSizedArrayType* sizedArrayType = (BfSizedArrayType*)type;
  5841. BfTypeVector typeVector;
  5842. typeVector.Add(sizedArrayType->mElementType);
  5843. auto sizeValue = BfTypedValue(GetConstValue(BF_MAX(sizedArrayType->mElementCount, 0)), GetPrimitiveType(BfTypeCode_IntPtr));
  5844. typeVector.Add(CreateConstExprValueType(sizeValue));
  5845. return ResolveTypeDef(mCompiler->mSizedArrayTypeDef, typeVector, BfPopulateType_Data)->ToTypeInstance();
  5846. }
  5847. else
  5848. return ResolveTypeDef(mCompiler->mSizedArrayTypeDef, BfPopulateType_Data)->ToTypeInstance();
  5849. }
  5850. BF_ASSERT(type->IsPrimitiveType());
  5851. return GetPrimitiveStructType(((BfPrimitiveType*)type)->mTypeDef->mTypeCode);
  5852. }
  5853. BfPrimitiveType* BfModule::GetPrimitiveType(BfTypeCode typeCode)
  5854. {
  5855. BfPrimitiveType* primType = mContext->mPrimitiveTypes[typeCode];
  5856. if (primType == NULL)
  5857. {
  5858. switch (typeCode)
  5859. {
  5860. case BfTypeCode_NullPtr:
  5861. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeNullPtr);
  5862. break;
  5863. case BfTypeCode_Self:
  5864. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeSelf);
  5865. break;
  5866. case BfTypeCode_Dot:
  5867. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeDot);
  5868. break;
  5869. case BfTypeCode_Var:
  5870. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeVar);
  5871. break;
  5872. case BfTypeCode_Let:
  5873. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeLet);
  5874. break;
  5875. case BfTypeCode_None:
  5876. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeVoid);
  5877. break;
  5878. case BfTypeCode_Boolean:
  5879. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeBool);
  5880. break;
  5881. case BfTypeCode_Int8:
  5882. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeInt8);
  5883. break;
  5884. case BfTypeCode_UInt8:
  5885. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeUInt8);
  5886. break;
  5887. case BfTypeCode_Int16:
  5888. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeInt16);
  5889. break;
  5890. case BfTypeCode_UInt16:
  5891. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeUInt16);
  5892. break;
  5893. case BfTypeCode_Int32:
  5894. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeInt32);
  5895. break;
  5896. case BfTypeCode_UInt32:
  5897. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeUInt32);
  5898. break;
  5899. case BfTypeCode_Int64:
  5900. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeInt64);
  5901. break;
  5902. case BfTypeCode_UInt64:
  5903. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeUInt64);
  5904. break;
  5905. case BfTypeCode_Char8:
  5906. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeChar8);
  5907. break;
  5908. case BfTypeCode_Char16:
  5909. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeChar16);
  5910. break;
  5911. case BfTypeCode_Char32:
  5912. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeChar32);
  5913. break;
  5914. case BfTypeCode_Float:
  5915. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeSingle);
  5916. break;
  5917. case BfTypeCode_Double:
  5918. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeDouble);
  5919. break;
  5920. case BfTypeCode_IntPtr:
  5921. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeIntPtr);
  5922. break;
  5923. case BfTypeCode_UIntPtr:
  5924. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeUIntPtr);
  5925. break;
  5926. case BfTypeCode_IntUnknown:
  5927. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeIntUnknown);
  5928. break;
  5929. case BfTypeCode_UIntUnknown:
  5930. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeUIntUnknown);
  5931. break;
  5932. case BfTypeCode_StringId:
  5933. BFMODULE_FATAL(this, "Invalid use of StringId");
  5934. break;
  5935. default:
  5936. BF_DBG_FATAL("Invalid type");
  5937. break;
  5938. }
  5939. mContext->mPrimitiveTypes[typeCode] = primType;
  5940. }
  5941. return primType;
  5942. }
  5943. BfIRType BfModule::GetIRLoweredType(BfTypeCode loweredTypeCode, BfTypeCode loweredTypeCode2)
  5944. {
  5945. BF_ASSERT(!mIsComptimeModule);
  5946. BF_ASSERT(loweredTypeCode != BfTypeCode_None);
  5947. if (loweredTypeCode2 == BfTypeCode_None)
  5948. return mBfIRBuilder->GetPrimitiveType(loweredTypeCode);
  5949. SizedArray<BfIRType, 2> types;
  5950. types.push_back(mBfIRBuilder->GetPrimitiveType(loweredTypeCode));
  5951. types.push_back(mBfIRBuilder->GetPrimitiveType(loweredTypeCode2));
  5952. return mBfIRBuilder->CreateStructType(types);
  5953. }
  5954. BfMethodRefType* BfModule::CreateMethodRefType(BfMethodInstance* methodInstance, bool mustAlreadyExist)
  5955. {
  5956. // Make sure we don't have a partially-formed local method or lambda coming in, because those may be replaced
  5957. // after the capture phase
  5958. BF_ASSERT(!methodInstance->mDisallowCalling);
  5959. auto methodRefType = new BfMethodRefType();
  5960. methodRefType->mContext = mContext;
  5961. //methodRefType->mCaptureType = NULL;
  5962. methodRefType->mMethodRef = methodInstance;
  5963. methodRefType->mOwner = methodInstance->GetOwner();
  5964. methodRefType->mOwnerRevision = methodRefType->mOwner->mRevision;
  5965. //methodRefType->mMangledName = BfMangler::Mangle(mCompiler->GetMangleKind(), methodInstance);
  5966. methodRefType->mIsAutoCompleteMethod = methodInstance->mIsAutocompleteMethod;
  5967. methodRefType->mIsUnspecialized = methodInstance->mIsUnspecialized;
  5968. methodRefType->mIsUnspecializedVariation = methodInstance->mIsUnspecializedVariation;
  5969. methodRefType->mSize = 0;
  5970. BfResolvedTypeSet::LookupContext lookupCtx;
  5971. lookupCtx.mModule = this;
  5972. BfResolvedTypeSet::Entry* typeEntry = NULL;
  5973. auto inserted = mContext->mResolvedTypes.Insert(methodRefType, &lookupCtx, &typeEntry);
  5974. if (typeEntry->mValue == NULL)
  5975. {
  5976. BF_ASSERT(!mustAlreadyExist);
  5977. BF_ASSERT(!methodInstance->mHasMethodRefType);
  5978. InitType(methodRefType, BfPopulateType_Identity);
  5979. methodRefType->mDefineState = BfTypeDefineState_DefinedAndMethodsSlotted;
  5980. methodInstance->mHasMethodRefType = true;
  5981. methodInstance->mMethodInstanceGroup->mRefCount++;
  5982. typeEntry->mValue = methodRefType;
  5983. BfLogSysM("Create MethodRefType %p MethodInstance: %p\n", methodRefType, methodInstance);
  5984. methodRefType->mRevision = 0;
  5985. AddDependency(methodInstance->GetOwner(), methodRefType, BfDependencyMap::DependencyFlag_Calls);
  5986. BfTypeVector tupleTypes;
  5987. Array<String> tupleNames;
  5988. int offset = 0;
  5989. methodRefType->mAlign = 1;
  5990. int dataIdx = 0;
  5991. // CRepr, just because we're lazy (for now)
  5992. int implicitParamCount = methodInstance->GetImplicitParamCount();
  5993. for (int implicitParamIdx = methodInstance->HasThis() ? -1 : 0; implicitParamIdx < implicitParamCount; implicitParamIdx++)
  5994. {
  5995. auto paramType = methodInstance->GetParamType(implicitParamIdx);
  5996. if (!paramType->IsValuelessType())
  5997. {
  5998. methodRefType->mDataToParamIdx.Add(implicitParamIdx);
  5999. if (implicitParamIdx >= 0)
  6000. methodRefType->mParamToDataIdx.Add(dataIdx);
  6001. offset = BF_ALIGN(offset, paramType->mAlign);
  6002. offset += paramType->mSize;
  6003. methodRefType->mAlign = std::max(methodRefType->mAlign, paramType->mAlign);
  6004. dataIdx++;
  6005. }
  6006. else
  6007. {
  6008. methodRefType->mParamToDataIdx.Add(-1);
  6009. }
  6010. }
  6011. offset = BF_ALIGN(offset, methodRefType->mAlign);
  6012. methodRefType->mSize = offset;
  6013. // if (!tupleTypes.empty())
  6014. // {
  6015. // methodRefType->mCaptureType = CreateTupleType(tupleTypes, tupleNames);
  6016. // AddDependency(methodRefType->mCaptureType, methodRefType, BfDependencyMap::DependencyFlag_ReadFields);
  6017. //
  6018. // methodRefType->mSize = methodRefType->mCaptureType->mSize;
  6019. // methodRefType->mAlign = methodRefType->mCaptureType->mAlign;
  6020. // }
  6021. // else
  6022. // {
  6023. // methodRefType->mSize = 0;
  6024. // methodRefType->mAlign = 0;
  6025. // }
  6026. }
  6027. else
  6028. {
  6029. methodRefType->mMethodRef = NULL;
  6030. delete methodRefType;
  6031. methodRefType = (BfMethodRefType*)typeEntry->mValue;
  6032. }
  6033. return methodRefType;
  6034. }
  6035. BfType* BfModule::FixIntUnknown(BfType* type)
  6036. {
  6037. if ((type != NULL) && (type->IsPrimitiveType()))
  6038. {
  6039. auto primType = (BfPrimitiveType*)type;
  6040. if (primType->mTypeDef->mTypeCode == BfTypeCode_IntUnknown)
  6041. return GetPrimitiveType(BfTypeCode_IntPtr);
  6042. if (primType->mTypeDef->mTypeCode == BfTypeCode_UIntUnknown)
  6043. return GetPrimitiveType(BfTypeCode_UIntPtr);
  6044. }
  6045. return type;
  6046. }
  6047. void BfModule::FixIntUnknown(BfTypedValue& typedVal, BfType* matchType)
  6048. {
  6049. if (!typedVal.mValue.IsConst())
  6050. {
  6051. if ((typedVal.mType != NULL) && (typedVal.mType->IsPrimitiveType()))
  6052. {
  6053. auto primType = (BfPrimitiveType*)typedVal.mType;
  6054. BF_ASSERT((primType->mTypeDef->mTypeCode != BfTypeCode_IntUnknown) && (primType->mTypeDef->mTypeCode != BfTypeCode_UIntUnknown));
  6055. }
  6056. return;
  6057. }
  6058. if (!typedVal.mType->IsPrimitiveType())
  6059. return;
  6060. BfTypeCode wantTypeCode;
  6061. auto primType = (BfPrimitiveType*)typedVal.mType;
  6062. if (primType->mTypeDef->mTypeCode == BfTypeCode_IntUnknown)
  6063. wantTypeCode = BfTypeCode_IntPtr;
  6064. else if (primType->mTypeDef->mTypeCode == BfTypeCode_UIntUnknown)
  6065. wantTypeCode = BfTypeCode_UIntPtr;
  6066. else
  6067. return;
  6068. auto constant = mBfIRBuilder->GetConstant(typedVal.mValue);
  6069. if ((matchType != NULL) && (matchType->IsPrimitiveType()) && (mBfIRBuilder->IsInt(matchType->ToPrimitiveType()->mTypeDef->mTypeCode)))
  6070. {
  6071. auto wantTypeCode = matchType->ToPrimitiveType()->mTypeDef->mTypeCode;
  6072. if (matchType->mSize < 8)
  6073. {
  6074. int64 minVal = -(1LL << (8 * matchType->mSize - 1));
  6075. int64 maxVal = (1LL << (8 * matchType->mSize - 1)) - 1;
  6076. if ((constant->mInt64 >= minVal) && (constant->mInt64 <= maxVal))
  6077. {
  6078. typedVal.mValue = mBfIRBuilder->CreateNumericCast(typedVal.mValue, mBfIRBuilder->IsSigned(wantTypeCode), wantTypeCode);
  6079. typedVal.mType = GetPrimitiveType(wantTypeCode);
  6080. return;
  6081. }
  6082. }
  6083. }
  6084. if (mSystem->mPtrSize == 4)
  6085. {
  6086. if (primType->mTypeDef->mTypeCode == BfTypeCode_IntUnknown)
  6087. {
  6088. if ((constant->mInt64 >= -0x80000000LL) && (constant->mInt64 <= 0x7FFFFFFFLL))
  6089. {
  6090. typedVal.mValue = mBfIRBuilder->CreateNumericCast(typedVal.mValue, true, BfTypeCode_IntPtr);
  6091. typedVal.mType = GetPrimitiveType(BfTypeCode_IntPtr);
  6092. }
  6093. else
  6094. typedVal.mType = GetPrimitiveType(BfTypeCode_Int64);
  6095. return;
  6096. }
  6097. else
  6098. {
  6099. if ((constant->mInt64 >= 0) && (constant->mInt64 <= 0xFFFFFFFF))
  6100. {
  6101. typedVal.mValue = mBfIRBuilder->CreateNumericCast(typedVal.mValue, false, BfTypeCode_IntPtr);
  6102. typedVal.mType = GetPrimitiveType(BfTypeCode_UIntPtr);
  6103. }
  6104. else
  6105. typedVal.mType = GetPrimitiveType(BfTypeCode_UInt64);
  6106. return;
  6107. }
  6108. }
  6109. typedVal.mType = GetPrimitiveType(wantTypeCode);
  6110. }
  6111. void BfModule::FixIntUnknown(BfTypedValue& lhs, BfTypedValue& rhs)
  6112. {
  6113. if ((lhs.mType != NULL) && (lhs.mType->IsIntUnknown()) && (rhs.mType != NULL) && (rhs.mType->IsInteger()))
  6114. {
  6115. if (CanCast(lhs, rhs.mType))
  6116. {
  6117. lhs = Cast(NULL, lhs, rhs.mType, BfCastFlags_SilentFail);
  6118. if (!lhs)
  6119. lhs = GetDefaultTypedValue(GetPrimitiveType(BfTypeCode_IntPtr));
  6120. return;
  6121. }
  6122. }
  6123. if ((rhs.mType != NULL) && (rhs.mType->IsIntUnknown()) && (lhs.mType != NULL) && (lhs.mType->IsInteger()))
  6124. {
  6125. if (CanCast(rhs, lhs.mType))
  6126. {
  6127. rhs = Cast(NULL, rhs, lhs.mType, BfCastFlags_SilentFail);
  6128. if (!rhs)
  6129. rhs = GetDefaultTypedValue(GetPrimitiveType(BfTypeCode_IntPtr));
  6130. return;
  6131. }
  6132. }
  6133. FixIntUnknown(lhs);
  6134. FixIntUnknown(rhs);
  6135. }
  6136. void BfModule::FixValueActualization(BfTypedValue& typedVal, bool force)
  6137. {
  6138. if (!typedVal.mValue.IsConst())
  6139. return;
  6140. if ((mBfIRBuilder->mIgnoreWrites) && (!force))
  6141. return;
  6142. auto constant = mBfIRBuilder->GetConstant(typedVal.mValue);
  6143. if (!HasUnactializedConstant(constant, mBfIRBuilder))
  6144. return;
  6145. typedVal.mValue = ConstantToCurrent(constant, mBfIRBuilder, typedVal.mType, false);
  6146. }
  6147. BfTypeInstance* BfModule::GetPrimitiveStructType(BfTypeCode typeCode)
  6148. {
  6149. BfTypeInstance* typeInst = NULL;
  6150. switch (typeCode)
  6151. {
  6152. case BfTypeCode_None:
  6153. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.Void"), BfPopulateType_Identity)->ToTypeInstance(); break;
  6154. case BfTypeCode_Boolean:
  6155. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.Boolean"), BfPopulateType_Identity)->ToTypeInstance(); break;
  6156. case BfTypeCode_Int8:
  6157. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.Int8"), BfPopulateType_Identity)->ToTypeInstance(); break;
  6158. case BfTypeCode_UInt8:
  6159. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.UInt8"), BfPopulateType_Identity)->ToTypeInstance(); break;
  6160. case BfTypeCode_Int16:
  6161. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.Int16"), BfPopulateType_Identity)->ToTypeInstance(); break;
  6162. case BfTypeCode_UInt16:
  6163. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.UInt16"), BfPopulateType_Identity)->ToTypeInstance(); break;
  6164. case BfTypeCode_Int32:
  6165. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.Int32"), BfPopulateType_Identity)->ToTypeInstance(); break;
  6166. case BfTypeCode_UInt32:
  6167. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.UInt32"), BfPopulateType_Identity)->ToTypeInstance(); break;
  6168. case BfTypeCode_Int64:
  6169. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.Int64"), BfPopulateType_Identity)->ToTypeInstance(); break;
  6170. case BfTypeCode_UInt64:
  6171. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.UInt64"), BfPopulateType_Identity)->ToTypeInstance(); break;
  6172. case BfTypeCode_IntPtr:
  6173. case BfTypeCode_IntUnknown:
  6174. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.Int"), BfPopulateType_Identity)->ToTypeInstance(); break;
  6175. case BfTypeCode_UIntPtr:
  6176. case BfTypeCode_UIntUnknown:
  6177. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.UInt"), BfPopulateType_Identity)->ToTypeInstance(); break;
  6178. case BfTypeCode_Char8:
  6179. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.Char8"), BfPopulateType_Identity)->ToTypeInstance(); break;
  6180. case BfTypeCode_Char16:
  6181. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.Char16"), BfPopulateType_Identity)->ToTypeInstance(); break;
  6182. case BfTypeCode_Char32:
  6183. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.Char32"), BfPopulateType_Identity)->ToTypeInstance(); break;
  6184. case BfTypeCode_Float:
  6185. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.Float"), BfPopulateType_Identity)->ToTypeInstance(); break;
  6186. case BfTypeCode_Double:
  6187. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.Double"), BfPopulateType_Identity)->ToTypeInstance(); break;
  6188. default:
  6189. //BF_FATAL("not implemented");
  6190. break;
  6191. }
  6192. return typeInst;
  6193. }
  6194. BfBoxedType* BfModule::CreateBoxedType(BfType* resolvedTypeRef, bool allowCreate)
  6195. {
  6196. bool isStructPtr = false;
  6197. BfPopulateType populateType = allowCreate ? BfPopulateType_Data : BfPopulateType_Identity;
  6198. BfResolveTypeRefFlags resolveFlags = allowCreate ? BfResolveTypeRefFlag_None : BfResolveTypeRefFlag_NoCreate;
  6199. if (resolvedTypeRef->IsPrimitiveType())
  6200. {
  6201. auto primType = (BfPrimitiveType*)resolvedTypeRef;
  6202. resolvedTypeRef = GetPrimitiveStructType(primType->mTypeDef->mTypeCode);
  6203. if (resolvedTypeRef == NULL)
  6204. return NULL;
  6205. }
  6206. else if (resolvedTypeRef->IsPointer())
  6207. {
  6208. BfPointerType* pointerType = (BfPointerType*)resolvedTypeRef;
  6209. if (pointerType->mElementType->IsStruct())
  6210. {
  6211. resolvedTypeRef = pointerType->mElementType;
  6212. isStructPtr = true;
  6213. }
  6214. else
  6215. {
  6216. BfTypeVector typeVector;
  6217. typeVector.Add(pointerType->mElementType);
  6218. resolvedTypeRef = ResolveTypeDef(mCompiler->mPointerTTypeDef, typeVector, populateType, resolveFlags);
  6219. if (resolvedTypeRef == NULL)
  6220. return NULL;
  6221. }
  6222. }
  6223. else if (resolvedTypeRef->IsMethodRef())
  6224. {
  6225. BfMethodRefType* methodRefType = (BfMethodRefType*)resolvedTypeRef;
  6226. BfTypeVector typeVector;
  6227. typeVector.Add(methodRefType);
  6228. resolvedTypeRef = ResolveTypeDef(mCompiler->mMethodRefTypeDef, typeVector, populateType, resolveFlags);
  6229. if (resolvedTypeRef == NULL)
  6230. return NULL;
  6231. }
  6232. else if (resolvedTypeRef->IsSizedArray())
  6233. {
  6234. BfSizedArrayType* sizedArrayType = (BfSizedArrayType*)resolvedTypeRef;
  6235. BfTypeVector typeVector;
  6236. typeVector.Add(sizedArrayType->mElementType);
  6237. auto sizeValue = BfTypedValue(GetConstValue(sizedArrayType->mElementCount), GetPrimitiveType(BfTypeCode_IntPtr));
  6238. auto sizeValueType = CreateConstExprValueType(sizeValue, allowCreate);
  6239. if (sizeValueType == NULL)
  6240. return NULL;
  6241. typeVector.Add(sizeValueType);
  6242. resolvedTypeRef = ResolveTypeDef(mCompiler->mSizedArrayTypeDef, typeVector, populateType, resolveFlags);
  6243. if (resolvedTypeRef == NULL)
  6244. return NULL;
  6245. }
  6246. BfTypeInstance* typeInst = resolvedTypeRef->ToTypeInstance();
  6247. if ((typeInst == NULL) && (!resolvedTypeRef->IsGenericParam()))
  6248. return NULL;
  6249. auto boxedType = mContext->mBoxedTypePool.Get();
  6250. boxedType->mContext = mContext;
  6251. boxedType->mElementType = resolvedTypeRef;
  6252. if (typeInst != NULL)
  6253. boxedType->mTypeDef = typeInst->mTypeDef->GetDefinition();
  6254. else
  6255. boxedType->mTypeDef = mCompiler->mValueTypeTypeDef;
  6256. boxedType->mBoxedFlags = isStructPtr ? BfBoxedType::BoxedFlags_StructPtr : BfBoxedType::BoxedFlags_None;
  6257. auto resolvedBoxedType = ResolveType(boxedType, populateType, resolveFlags);
  6258. if (resolvedBoxedType != boxedType)
  6259. {
  6260. boxedType->Dispose();
  6261. mContext->mBoxedTypePool.GiveBack(boxedType);
  6262. }
  6263. return (BfBoxedType*)resolvedBoxedType;
  6264. }
  6265. BfTypeInstance* BfModule::CreateTupleType(const BfTypeVector& fieldTypes, const Array<String>& fieldNames, bool allowVar)
  6266. {
  6267. auto baseType = (BfTypeInstance*)ResolveTypeDef(mContext->mCompiler->mValueTypeTypeDef);
  6268. BfTupleType* tupleType = NULL;
  6269. auto actualTupleType = mContext->mTupleTypePool.Get();
  6270. actualTupleType->Init(baseType->mTypeDef->mProject, baseType);
  6271. bool isUnspecialzied = false;
  6272. for (int fieldIdx = 0; fieldIdx < (int)fieldTypes.size(); fieldIdx++)
  6273. {
  6274. String fieldName;
  6275. if (fieldIdx < (int)fieldNames.size())
  6276. fieldName = fieldNames[fieldIdx];
  6277. if (fieldName.empty())
  6278. fieldName = StrFormat("%d", fieldIdx);
  6279. BfFieldDef* fieldDef = actualTupleType->AddField(fieldName);
  6280. auto fieldType = fieldTypes[fieldIdx];
  6281. if ((fieldType->IsUnspecializedType()) || (fieldType->IsVar()))
  6282. isUnspecialzied = true;
  6283. }
  6284. tupleType = actualTupleType;
  6285. tupleType->mContext = mContext;
  6286. tupleType->mFieldInstances.Resize(fieldTypes.size());
  6287. for (int fieldIdx = 0; fieldIdx < (int)fieldTypes.size(); fieldIdx++)
  6288. {
  6289. BfFieldInstance* fieldInstance = (BfFieldInstance*)&tupleType->mFieldInstances[fieldIdx];
  6290. fieldInstance->mFieldIdx = fieldIdx;
  6291. BfType* fieldType = fieldTypes[fieldIdx];
  6292. if ((fieldType->IsVar()) && (!allowVar))
  6293. fieldType = mContext->mBfObjectType;
  6294. fieldInstance->SetResolvedType(fieldType);
  6295. fieldInstance->mOwner = tupleType;
  6296. }
  6297. tupleType->mIsUnspecializedType = false;
  6298. tupleType->mIsUnspecializedTypeVariation = false;
  6299. if (isUnspecialzied)
  6300. {
  6301. tupleType->mIsUnspecializedType = true;
  6302. tupleType->mIsUnspecializedTypeVariation = true;
  6303. }
  6304. auto resolvedTupleType = ResolveType(tupleType);
  6305. if (resolvedTupleType != tupleType)
  6306. {
  6307. BF_ASSERT(tupleType->mContext != NULL);
  6308. tupleType->Dispose();
  6309. mContext->mTupleTypePool.GiveBack((BfTupleType*)tupleType);
  6310. }
  6311. return (BfTupleType*)resolvedTupleType;
  6312. }
  6313. BfTypeInstance* BfModule::SantizeTupleType(BfTypeInstance* tupleType)
  6314. {
  6315. bool needsSanitize = false;
  6316. for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
  6317. {
  6318. BfFieldInstance* fieldInstance = (BfFieldInstance*)&tupleType->mFieldInstances[fieldIdx];
  6319. if ((fieldInstance->mResolvedType->IsVar()) || (fieldInstance->mResolvedType->IsLet()))
  6320. {
  6321. needsSanitize = true;
  6322. break;
  6323. }
  6324. }
  6325. if (!needsSanitize)
  6326. return tupleType;
  6327. BfTypeVector fieldTypes;
  6328. Array<String> fieldNames;
  6329. for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
  6330. {
  6331. BfFieldInstance* fieldInstance = (BfFieldInstance*)&tupleType->mFieldInstances[fieldIdx];
  6332. auto fieldDef = fieldInstance->GetFieldDef();
  6333. if ((fieldInstance->mResolvedType->IsVar()) || (fieldInstance->mResolvedType->IsLet()))
  6334. fieldTypes.Add(mContext->mBfObjectType);
  6335. else
  6336. fieldTypes.Add(fieldInstance->mResolvedType);
  6337. if (!fieldDef->IsUnnamedTupleField())
  6338. {
  6339. for (int i = 0; i < fieldIdx; i++)
  6340. fieldNames.Add(String());
  6341. fieldNames.Add(fieldDef->mName);
  6342. }
  6343. }
  6344. return CreateTupleType(fieldTypes, fieldNames);
  6345. }
  6346. BfRefType* BfModule::CreateRefType(BfType* resolvedTypeRef, BfRefType::RefKind refKind)
  6347. {
  6348. auto refType = mContext->mRefTypePool.Get();
  6349. refType->mContext = mContext;
  6350. refType->mElementType = resolvedTypeRef;
  6351. refType->mRefKind = refKind;
  6352. auto resolvedRefType = ResolveType(refType);
  6353. if (resolvedRefType != refType)
  6354. mContext->mRefTypePool.GiveBack(refType);
  6355. return (BfRefType*)resolvedRefType;
  6356. }
  6357. BfModifiedTypeType* BfModule::CreateModifiedTypeType(BfType* resolvedTypeRef, BfToken modifiedKind)
  6358. {
  6359. auto retTypeType = mContext->mModifiedTypeTypePool.Get();
  6360. retTypeType->mContext = mContext;
  6361. retTypeType->mModifiedKind = modifiedKind;
  6362. retTypeType->mElementType = resolvedTypeRef;
  6363. auto resolvedRetTypeType = ResolveType(retTypeType);
  6364. if (resolvedRetTypeType != retTypeType)
  6365. mContext->mModifiedTypeTypePool.GiveBack(retTypeType);
  6366. return (BfModifiedTypeType*)resolvedRetTypeType;
  6367. }
  6368. BfConcreteInterfaceType* BfModule::CreateConcreteInterfaceType(BfTypeInstance* interfaceType)
  6369. {
  6370. auto concreteInterfaceType = mContext->mConcreteInterfaceTypePool.Get();
  6371. concreteInterfaceType->mContext = mContext;
  6372. concreteInterfaceType->mInterface = interfaceType;
  6373. auto resolvedConcreteInterfaceType = ResolveType(concreteInterfaceType);
  6374. if (resolvedConcreteInterfaceType != concreteInterfaceType)
  6375. mContext->mConcreteInterfaceTypePool.GiveBack(concreteInterfaceType);
  6376. return (BfConcreteInterfaceType*)resolvedConcreteInterfaceType;
  6377. }
  6378. BfPointerType* BfModule::CreatePointerType(BfTypeReference* typeRef)
  6379. {
  6380. auto resolvedTypeRef = ResolveTypeRef(typeRef);
  6381. if (resolvedTypeRef == NULL)
  6382. return NULL;
  6383. return CreatePointerType(resolvedTypeRef);
  6384. }
  6385. BfType* BfModule::ResolveTypeDef(BfTypeDef* typeDef, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags)
  6386. {
  6387. BF_ASSERT(typeDef->mDefState != BfTypeDef::DefState_Emitted);
  6388. if (typeDef->mTypeDeclaration == NULL)
  6389. {
  6390. BF_ASSERT(!typeDef->mIsDelegate && !typeDef->mIsFunction);
  6391. }
  6392. //BF_ASSERT(typeDef->mTypeCode != BfTypeCode_Extension);
  6393. BF_ASSERT(!typeDef->mIsPartial || typeDef->mIsCombinedPartial);
  6394. BF_ASSERT(typeDef->mDefState != BfTypeDef::DefState_Deleted);
  6395. BF_ASSERT((typeDef->mOuterType == NULL) || (typeDef->mOuterType->mDefState != BfTypeDef::DefState_Deleted));
  6396. if (typeDef->mGenericParamDefs.size() != 0)
  6397. return ResolveTypeDef(typeDef, BfTypeVector(), populateType, resolveFlags);
  6398. auto typeDefTypeRef = mContext->mTypeDefTypeRefPool.Get();
  6399. typeDefTypeRef->mTypeDef = typeDef;
  6400. auto resolvedtypeDefType = ResolveTypeRef(typeDefTypeRef, populateType);
  6401. if (resolvedtypeDefType == NULL)
  6402. {
  6403. mContext->mTypeDefTypeRefPool.GiveBack(typeDefTypeRef);
  6404. return NULL;
  6405. }
  6406. mContext->mTypeDefTypeRefPool.GiveBack(typeDefTypeRef);
  6407. //BF_ASSERT(resolvedtypeDefType->IsTypeInstance() || resolvedtypeDefType->IsPrimitiveType());
  6408. return resolvedtypeDefType;
  6409. }
  6410. // Get BaseClass even when we haven't populated the type yet
  6411. BfTypeInstance* BfModule::GetBaseType(BfTypeInstance* typeInst)
  6412. {
  6413. if (typeInst->mBaseType == NULL)
  6414. {
  6415. auto checkTypeState = mContext->mCurTypeState;
  6416. while (checkTypeState != NULL)
  6417. {
  6418. if (checkTypeState->mType == typeInst)
  6419. return NULL;
  6420. checkTypeState = checkTypeState->mPrevState;
  6421. }
  6422. }
  6423. if ((typeInst->mBaseType == NULL) && (typeInst != mContext->mBfObjectType))
  6424. PopulateType(typeInst, BfPopulateType_BaseType);
  6425. return typeInst->mBaseType;
  6426. }
  6427. void BfModule::HandleTypeGenericParamRef(BfAstNode* refNode, BfTypeDef* typeDef, int typeGenericParamIdx)
  6428. {
  6429. if (mCompiler->IsAutocomplete())
  6430. {
  6431. BfAutoComplete* autoComplete = mCompiler->mResolvePassData->mAutoComplete;
  6432. if ((autoComplete != NULL) && (autoComplete->mIsGetDefinition) && (autoComplete->IsAutocompleteNode(refNode)))
  6433. {
  6434. if ((autoComplete->mDefMethod == NULL) && (autoComplete->mDefField == NULL) &&
  6435. (autoComplete->mDefProp == NULL))
  6436. {
  6437. autoComplete->mDefType = typeDef;
  6438. autoComplete->mDefTypeGenericParamIdx = typeGenericParamIdx;
  6439. autoComplete->SetDefinitionLocation(refNode);
  6440. }
  6441. }
  6442. }
  6443. if (mCompiler->mResolvePassData != NULL)
  6444. mCompiler->mResolvePassData->HandleTypeGenericParam(refNode, typeDef, typeGenericParamIdx);
  6445. }
  6446. void BfModule::HandleMethodGenericParamRef(BfAstNode* refNode, BfTypeDef* typeDef, BfMethodDef* methodDef, int methodGenericParamIdx)
  6447. {
  6448. if (mCompiler->IsAutocomplete())
  6449. {
  6450. BfAutoComplete* autoComplete = mCompiler->mResolvePassData->mAutoComplete;
  6451. if ((autoComplete != NULL) && (autoComplete->mIsGetDefinition) && (autoComplete->IsAutocompleteNode(refNode)))
  6452. {
  6453. if ((autoComplete->mDefMethod == NULL) && (autoComplete->mDefField == NULL) &&
  6454. (autoComplete->mDefProp == NULL))
  6455. {
  6456. autoComplete->mDefType = typeDef;
  6457. autoComplete->mDefMethod = methodDef;
  6458. autoComplete->mDefMethodGenericParamIdx = methodGenericParamIdx;
  6459. autoComplete->SetDefinitionLocation(refNode);
  6460. }
  6461. }
  6462. }
  6463. if (mCompiler->mResolvePassData != NULL)
  6464. mCompiler->mResolvePassData->HandleMethodGenericParam(refNode, typeDef, methodDef, methodGenericParamIdx);
  6465. }
  6466. BfType* BfModule::ResolveInnerType(BfType* outerType, BfAstNode* typeRef, BfPopulateType populateType, bool ignoreErrors, int numGenericArgs)
  6467. {
  6468. BfTypeDef* nestedTypeDef = NULL;
  6469. if (outerType->IsBoxed())
  6470. outerType = outerType->GetUnderlyingType();
  6471. BfNamedTypeReference* namedTypeRef = NULL;
  6472. BfGenericInstanceTypeRef* genericTypeRef = NULL;
  6473. BfDirectStrTypeReference* directStrTypeRef = NULL;
  6474. BfIdentifierNode* identifierNode = NULL;
  6475. if ((namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(typeRef)))
  6476. {
  6477. //TYPEDEF nestedTypeDef = namedTypeRef->mTypeDef;
  6478. }
  6479. else if ((genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef)))
  6480. {
  6481. namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(genericTypeRef->mElementType);
  6482. //TYPEDEF nestedTypeDef = namedTypeRef->mTypeDef;
  6483. }
  6484. else if ((identifierNode = BfNodeDynCast<BfIdentifierNode>(typeRef)))
  6485. {
  6486. //TYPEDEF nestedTypeDef = namedTypeRef->mTypeDef;
  6487. }
  6488. else if ((directStrTypeRef = BfNodeDynCast<BfDirectStrTypeReference>(typeRef)))
  6489. {
  6490. //
  6491. }
  6492. BF_ASSERT((identifierNode != NULL) || (namedTypeRef != NULL) || (directStrTypeRef != NULL));
  6493. auto usedOuterType = outerType;
  6494. if (nestedTypeDef == NULL)
  6495. {
  6496. StringView findName;
  6497. if (namedTypeRef != NULL)
  6498. findName = namedTypeRef->mNameNode->ToStringView();
  6499. else if (identifierNode != NULL)
  6500. findName = identifierNode->ToStringView();
  6501. else
  6502. findName = directStrTypeRef->mTypeName;
  6503. if (!findName.Contains('.'))
  6504. {
  6505. if (outerType->IsTypeInstance())
  6506. {
  6507. auto outerTypeInstance = outerType->ToTypeInstance();
  6508. for (int pass = 0; pass < 2; pass++)
  6509. {
  6510. bool isFailurePass = pass == 1;
  6511. bool allowPrivate = (mCurTypeInstance != NULL) &&
  6512. ((mCurTypeInstance == outerTypeInstance) || TypeHasParentOrEquals(mCurTypeInstance->mTypeDef, outerTypeInstance->mTypeDef));
  6513. bool allowProtected = allowPrivate;/*(mCurTypeInstance != NULL) &&
  6514. (allowPrivate || (mCurTypeInstance->mSkipTypeProtectionChecks) || TypeIsSubTypeOf(mCurTypeInstance, outerTypeInstance));*/
  6515. auto checkOuterType = outerTypeInstance;
  6516. while (checkOuterType != NULL)
  6517. {
  6518. for (auto checkType : checkOuterType->mTypeDef->mNestedTypes)
  6519. {
  6520. auto latestCheckType = checkType->GetLatest();
  6521. if ((!isFailurePass) && (!CheckProtection(latestCheckType->mProtection, latestCheckType, allowProtected, allowPrivate)))
  6522. continue;
  6523. if (checkType->mProject != checkOuterType->mTypeDef->mProject)
  6524. {
  6525. auto visibleProjectSet = GetVisibleProjectSet();
  6526. if ((visibleProjectSet == NULL) || (!visibleProjectSet->Contains(checkType->mProject)))
  6527. continue;
  6528. }
  6529. if ((checkType->mName->mString == findName) && (checkType->GetSelfGenericParamCount() == numGenericArgs))
  6530. {
  6531. if (isFailurePass)
  6532. {
  6533. // This is the one error we don't ignore when ignoreErrors is set
  6534. Fail(StrFormat("'%s.%s' is inaccessible due to its protection level", TypeToString(checkOuterType).c_str(), BfTypeUtils::TypeToString(typeRef).c_str()), typeRef); // CS0122
  6535. }
  6536. usedOuterType = checkOuterType;
  6537. nestedTypeDef = checkType;
  6538. break;
  6539. }
  6540. }
  6541. if (nestedTypeDef != NULL)
  6542. break;
  6543. allowPrivate = false;
  6544. checkOuterType = GetBaseType(checkOuterType);
  6545. }
  6546. if (nestedTypeDef != NULL)
  6547. break;
  6548. if ((outerTypeInstance->IsEnum()) && (findName == "UnderlyingType"))
  6549. {
  6550. auto underlyingType = outerTypeInstance->GetUnderlyingType();
  6551. if (underlyingType != NULL)
  6552. return underlyingType;
  6553. }
  6554. }
  6555. }
  6556. }
  6557. if (nestedTypeDef == NULL)
  6558. {
  6559. if (!mIgnoreErrors && !ignoreErrors)
  6560. {
  6561. StringT<64> name;
  6562. name.Append(findName);
  6563. Fail(StrFormat("'%s' does not contain a definition for '%s'", TypeToString(outerType).c_str(), name.c_str()), typeRef);
  6564. }
  6565. return NULL;
  6566. }
  6567. }
  6568. SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, ignoreErrors || mIgnoreErrors);
  6569. if ((genericTypeRef != NULL) || (usedOuterType->IsGenericTypeInstance()))
  6570. {
  6571. BfTypeVector genericArgs;
  6572. if (usedOuterType->IsGenericTypeInstance())
  6573. {
  6574. auto genericTypeInst = (BfTypeInstance*)usedOuterType;
  6575. genericArgs = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments;
  6576. }
  6577. if (genericTypeRef != NULL)
  6578. {
  6579. for (auto genericArgTypeRef : genericTypeRef->mGenericArguments)
  6580. {
  6581. auto genericArgType = ResolveTypeRef(genericArgTypeRef, NULL, BfPopulateType_IdentityNoRemapAlias);
  6582. if (genericArgType == NULL)
  6583. return NULL;
  6584. genericArgs.push_back(genericArgType);
  6585. }
  6586. }
  6587. if (genericArgs.size() != nestedTypeDef->mGenericParamDefs.size())
  6588. {
  6589. if (populateType == BfPopulateType_TypeDef)
  6590. {
  6591. // Probably from inside ResolveGenericInstanceDef, just return unresolved typedef
  6592. genericArgs.clear();
  6593. }
  6594. else
  6595. {
  6596. ShowGenericArgCountError(typeRef, (int)nestedTypeDef->mGenericParamDefs.size() - (int)nestedTypeDef->mOuterType->mGenericParamDefs.size());
  6597. return NULL;
  6598. }
  6599. }
  6600. if (nestedTypeDef->mIsPartial)
  6601. {
  6602. nestedTypeDef = GetCombinedPartialTypeDef(nestedTypeDef);
  6603. if (nestedTypeDef == NULL)
  6604. return NULL;
  6605. }
  6606. return ResolveTypeDef(nestedTypeDef, genericArgs, BfPopulateType_IdentityNoRemapAlias);
  6607. }
  6608. else
  6609. {
  6610. if (nestedTypeDef->mIsPartial)
  6611. {
  6612. nestedTypeDef = GetCombinedPartialTypeDef(nestedTypeDef);
  6613. if (nestedTypeDef == NULL)
  6614. return NULL;
  6615. }
  6616. return ResolveTypeDef(nestedTypeDef, BfPopulateType_IdentityNoRemapAlias);
  6617. }
  6618. return NULL;
  6619. }
  6620. BfTypeDef* BfModule::GetCombinedPartialTypeDef(BfTypeDef* typeDef)
  6621. {
  6622. BF_ASSERT(!typeDef->mIsExplicitPartial);
  6623. if (!typeDef->mIsPartial)
  6624. return typeDef;
  6625. auto result = mSystem->FindTypeDef(typeDef->mFullName.ToString(), (int)typeDef->mGenericParamDefs.size());
  6626. return result;
  6627. }
  6628. BfTypeInstance* BfModule::GetOuterType(BfType* type)
  6629. {
  6630. if (type == NULL)
  6631. return NULL;
  6632. if (type->IsBoxed())
  6633. return GetOuterType(((BfBoxedType*)type)->mElementType);
  6634. auto typeInst = type->ToTypeInstance();
  6635. if ((typeInst == NULL) || (typeInst->mTypeDef->mOuterType == NULL))
  6636. return NULL;
  6637. auto outerTypeDef = typeInst->mTypeDef->mOuterType;
  6638. if (outerTypeDef->mIsPartial)
  6639. {
  6640. outerTypeDef = GetCombinedPartialTypeDef(outerTypeDef);
  6641. if (outerTypeDef == NULL)
  6642. return NULL;
  6643. }
  6644. BfTypeVector typeGenericArguments;
  6645. if (type->IsGenericTypeInstance())
  6646. {
  6647. auto genericType = (BfTypeInstance*)type;
  6648. typeGenericArguments = genericType->mGenericTypeInfo->mTypeGenericArguments;
  6649. }
  6650. BF_ASSERT((intptr)typeGenericArguments.size() >= (intptr)outerTypeDef->mGenericParamDefs.size());
  6651. typeGenericArguments.resize(outerTypeDef->mGenericParamDefs.size());
  6652. //auto outerType = ResolveTypeDef(outerTypeDef, typeGenericArguments, BfPopulateType_Declaration);
  6653. auto outerType = ResolveTypeDef(outerTypeDef, typeGenericArguments, BfPopulateType_Identity);
  6654. if (outerType == NULL)
  6655. return NULL;
  6656. return outerType->ToTypeInstance();
  6657. }
  6658. bool BfModule::IsInnerType(BfType* checkInnerType, BfType* checkOuterType)
  6659. {
  6660. BfType* outerType = GetOuterType(checkInnerType);
  6661. if (outerType == NULL)
  6662. return false;
  6663. if (outerType == checkOuterType)
  6664. return true;
  6665. return IsInnerType(outerType, checkOuterType);
  6666. }
  6667. bool BfModule::IsInnerType(BfTypeDef* checkInnerType, BfTypeDef* checkOuterType)
  6668. {
  6669. BF_ASSERT(!checkOuterType->mIsPartial);
  6670. if (checkInnerType->mNestDepth <= checkOuterType->mNestDepth)
  6671. return false;
  6672. while (true)
  6673. {
  6674. BfTypeDef* outerType = checkInnerType->mOuterType;
  6675. if (outerType == NULL)
  6676. return false;
  6677. if (outerType->mIsPartial)
  6678. outerType = mSystem->GetCombinedPartial(outerType);
  6679. if (outerType->GetDefinition() == checkOuterType->GetDefinition())
  6680. return true;
  6681. checkInnerType = checkInnerType->mOuterType;
  6682. }
  6683. }
  6684. BfType* BfModule::ResolveTypeDef(BfTypeDef* typeDef, const BfTypeVector& genericArgs, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags)
  6685. {
  6686. BF_ASSERT(typeDef->mDefState != BfTypeDef::DefState_Emitted);
  6687. if (typeDef->mGenericParamDefs.size() == 0)
  6688. return ResolveTypeDef(typeDef, populateType, resolveFlags);
  6689. if ((typeDef == mCompiler->mArray1TypeDef) || (typeDef == mCompiler->mArray2TypeDef))
  6690. {
  6691. auto arrayInstType = mContext->mArrayTypeInstancePool.Get();
  6692. arrayInstType->mContext = mContext;
  6693. if (typeDef == mCompiler->mArray1TypeDef)
  6694. arrayInstType->mDimensions = 1;
  6695. else
  6696. arrayInstType->mDimensions = 2;
  6697. auto typeRef = mContext->mTypeDefTypeRefPool.Get();
  6698. typeRef->mTypeDef = typeDef;
  6699. delete arrayInstType->mGenericTypeInfo;
  6700. arrayInstType->mGenericTypeInfo = new BfGenericTypeInfo();
  6701. arrayInstType->mTypeDef = typeDef;
  6702. arrayInstType->mGenericTypeInfo->mIsUnspecialized = false;
  6703. arrayInstType->mGenericTypeInfo->mTypeGenericArguments.clear();
  6704. for (auto genericArg : genericArgs)
  6705. {
  6706. arrayInstType->mGenericTypeInfo->mIsUnspecialized |= genericArg->IsGenericParam();
  6707. arrayInstType->mGenericTypeInfo->mTypeGenericArguments.push_back(genericArg);
  6708. }
  6709. if (genericArgs.size() == 0)
  6710. {
  6711. for (int i = 0; i < (int)typeDef->mGenericParamDefs.size(); i++)
  6712. {
  6713. auto genericParamTypeRef = GetGenericParamType(BfGenericParamKind_Type, i);
  6714. arrayInstType->mGenericTypeInfo->mTypeGenericArguments.push_back(genericParamTypeRef);
  6715. arrayInstType->mGenericTypeInfo->mIsUnspecialized = true;
  6716. }
  6717. }
  6718. auto resolvedType = ResolveType(arrayInstType, populateType, resolveFlags);
  6719. if (resolvedType != arrayInstType)
  6720. {
  6721. delete arrayInstType->mGenericTypeInfo;
  6722. arrayInstType->mGenericTypeInfo = NULL;
  6723. arrayInstType->Dispose();
  6724. mContext->mArrayTypeInstancePool.GiveBack(arrayInstType);
  6725. mContext->mTypeDefTypeRefPool.GiveBack(typeRef);
  6726. }
  6727. BF_ASSERT((resolvedType == NULL) || resolvedType->IsTypeInstance() || resolvedType->IsPrimitiveType());
  6728. return resolvedType;
  6729. }
  6730. BfTypeInstance* genericInstType;
  6731. if (typeDef->mTypeCode == BfTypeCode_TypeAlias)
  6732. genericInstType = mContext->mAliasTypePool.Get();
  6733. else
  6734. genericInstType = mContext->mGenericTypeInstancePool.Get();
  6735. delete genericInstType->mGenericTypeInfo;
  6736. genericInstType->mGenericTypeInfo = new BfGenericTypeInfo();
  6737. BF_ASSERT(genericInstType->mGenericTypeInfo->mGenericParams.size() == 0);
  6738. BF_ASSERT((genericInstType->mRebuildFlags & BfTypeRebuildFlag_AddedToWorkList) == 0);
  6739. genericInstType->mRebuildFlags = (BfTypeRebuildFlags)(genericInstType->mRebuildFlags & ~BfTypeRebuildFlag_InTempPool);
  6740. genericInstType->mContext = mContext;
  6741. auto typeRef = mContext->mTypeDefTypeRefPool.Get();
  6742. typeRef->mTypeDef = typeDef;
  6743. genericInstType->mTypeDef = typeDef;
  6744. genericInstType->mGenericTypeInfo->mIsUnspecialized = false;
  6745. genericInstType->mGenericTypeInfo->mTypeGenericArguments.clear();
  6746. genericInstType->mTypeFailed = false;
  6747. for (auto genericArg : genericArgs)
  6748. {
  6749. genericInstType->mGenericTypeInfo->mIsUnspecialized |= genericArg->IsGenericParam();
  6750. genericInstType->mGenericTypeInfo->mTypeGenericArguments.push_back(genericArg);
  6751. }
  6752. if (genericArgs.size() == 0)
  6753. {
  6754. for (int i = 0; i < (int)typeDef->mGenericParamDefs.size(); i++)
  6755. {
  6756. auto genericParamTypeRef = GetGenericParamType(BfGenericParamKind_Type, i);
  6757. genericInstType->mGenericTypeInfo->mTypeGenericArguments.push_back(genericParamTypeRef);
  6758. genericInstType->mGenericTypeInfo->mIsUnspecialized = true;
  6759. }
  6760. }
  6761. BfType* resolvedType = NULL;
  6762. bool failed = false;
  6763. resolvedType = ResolveType(genericInstType, populateType, resolveFlags);
  6764. if (resolvedType != genericInstType)
  6765. {
  6766. BF_ASSERT(genericInstType->mGenericTypeInfo->mGenericParams.size() == 0);
  6767. BF_ASSERT((genericInstType->mRebuildFlags & BfTypeRebuildFlag_AddedToWorkList) == 0);
  6768. genericInstType->mRebuildFlags = (BfTypeRebuildFlags)(genericInstType->mRebuildFlags | BfTypeRebuildFlag_InTempPool);
  6769. delete genericInstType->mGenericTypeInfo;
  6770. genericInstType->mGenericTypeInfo = NULL;
  6771. if (typeDef->mTypeCode == BfTypeCode_TypeAlias)
  6772. mContext->mAliasTypePool.GiveBack((BfTypeAliasType*)genericInstType);
  6773. else
  6774. {
  6775. genericInstType->Dispose();
  6776. mContext->mGenericTypeInstancePool.GiveBack(genericInstType);
  6777. }
  6778. mContext->mTypeDefTypeRefPool.GiveBack(typeRef);
  6779. }
  6780. BF_ASSERT((resolvedType == NULL) || resolvedType->IsTypeInstance() || resolvedType->IsPrimitiveType());
  6781. return resolvedType;
  6782. }
  6783. int checkIdx = 0;
  6784. BfTypeDef* BfModule::ResolveGenericInstanceDef(BfGenericInstanceTypeRef* genericTypeRef, BfType** outType, BfResolveTypeRefFlags resolveFlags)
  6785. {
  6786. if (outType != NULL)
  6787. *outType = NULL;
  6788. BfTypeReference* typeRef = genericTypeRef->mElementType;
  6789. int numGenericParams = genericTypeRef->GetGenericArgCount();
  6790. BfTypeDef* curTypeDef = NULL;
  6791. if (mCurTypeInstance != NULL)
  6792. curTypeDef = mCurTypeInstance->mTypeDef->GetDefinition();
  6793. if (auto directTypeDef = BfNodeDynCast<BfDirectTypeReference>(typeRef))
  6794. {
  6795. auto typeInst = directTypeDef->mType->ToTypeInstance();
  6796. return typeInst->mTypeDef->GetDefinition();
  6797. }
  6798. auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(typeRef);
  6799. auto directStrTypeDef = BfNodeDynCastExact<BfDirectStrTypeReference>(typeRef);
  6800. if ((namedTypeRef != NULL) || (directStrTypeDef != NULL))
  6801. {
  6802. BfTypeLookupError error;
  6803. error.mRefNode = typeRef;
  6804. BfTypeDef* typeDef = FindTypeDef(typeRef, NULL, &error, numGenericParams, resolveFlags);
  6805. if (typeDef != NULL)
  6806. {
  6807. BfAutoComplete* autoComplete = NULL;
  6808. if (mCompiler->IsAutocomplete())
  6809. autoComplete = mCompiler->mResolvePassData->mAutoComplete;
  6810. if ((autoComplete != NULL) && (autoComplete->mIsGetDefinition) && (autoComplete->IsAutocompleteNode(typeRef)))
  6811. {
  6812. if ((autoComplete->mDefMethod == NULL) && (autoComplete->mDefField == NULL) &&
  6813. (autoComplete->mDefProp == NULL) && (typeDef->mTypeDeclaration != NULL))
  6814. {
  6815. autoComplete->mDefType = typeDef;
  6816. autoComplete->SetDefinitionLocation(typeDef->mTypeDeclaration->mNameNode);
  6817. }
  6818. }
  6819. if (mCompiler->mResolvePassData != NULL)
  6820. mCompiler->mResolvePassData->HandleTypeReference(typeRef, typeDef);
  6821. return typeDef;
  6822. }
  6823. if (mCurTypeInstance != NULL)
  6824. {
  6825. bool wasGenericParam = false;
  6826. // Check generics first
  6827. if (typeRef->IsA<BfNamedTypeReference>())
  6828. {
  6829. String findName = typeRef->ToString();
  6830. if ((resolveFlags & BfResolveTypeRefFlag_Attribute) != 0)
  6831. findName += "Attribute";
  6832. if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsGenericTypeInstance()))
  6833. {
  6834. auto genericTypeInst = (BfTypeInstance*)mCurTypeInstance;
  6835. for (int genericParamIdx = 0; genericParamIdx < (int)curTypeDef->mGenericParamDefs.size(); genericParamIdx++)
  6836. {
  6837. String genericName = curTypeDef->mGenericParamDefs[genericParamIdx]->mName;
  6838. if (genericName == findName)
  6839. wasGenericParam = true;
  6840. }
  6841. }
  6842. if (mCurMethodInstance != NULL)
  6843. {
  6844. for (int genericParamIdx = 0; genericParamIdx < (int)mCurMethodInstance->mMethodDef->mGenericParams.size(); genericParamIdx++)
  6845. {
  6846. String genericName = mCurMethodInstance->mMethodDef->mGenericParams[genericParamIdx]->mName;
  6847. if (genericName == findName)
  6848. wasGenericParam = true;
  6849. }
  6850. }
  6851. }
  6852. if ((wasGenericParam) && ((resolveFlags & BfResolveTypeRefFlag_IgnoreLookupError) == 0))
  6853. Fail("Cannot use generic param as generic instance type", typeRef);
  6854. }
  6855. if (typeDef == NULL)
  6856. {
  6857. if ((resolveFlags & BfResolveTypeRefFlag_IgnoreLookupError) == 0)
  6858. TypeRefNotFound(typeRef);
  6859. return NULL;
  6860. }
  6861. }
  6862. if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(typeRef))
  6863. {
  6864. BfAutoParentNodeEntry autoParentNodeEntry(this, genericTypeRef);
  6865. auto type = ResolveTypeRef(qualifiedTypeRef, BfPopulateType_TypeDef, BfResolveTypeRefFlag_None, numGenericParams);
  6866. if (type == NULL)
  6867. return NULL;
  6868. if (outType != NULL)
  6869. *outType = type;
  6870. auto typeInst = type->ToTypeInstance();
  6871. if (typeInst != NULL)
  6872. return typeInst->mTypeDef->GetDefinition();
  6873. }
  6874. if ((resolveFlags & BfResolveTypeRefFlag_IgnoreLookupError) == 0)
  6875. Fail("Invalid generic type", typeRef);
  6876. return NULL;
  6877. }
  6878. BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* typeGenericArguments, BfTypeVector* methodGenericArguments, bool allowFail)
  6879. {
  6880. if (unspecializedType->IsGenericParam())
  6881. {
  6882. auto genericParam = (BfGenericParamType*)unspecializedType;
  6883. if ((genericParam->mGenericParamKind == BfGenericParamKind_Type) && (typeGenericArguments != NULL))
  6884. {
  6885. if (genericParam->mGenericParamIdx < (int)typeGenericArguments->size())
  6886. return FixIntUnknown((*typeGenericArguments)[genericParam->mGenericParamIdx]);
  6887. BF_ASSERT(allowFail);
  6888. }
  6889. if ((genericParam->mGenericParamKind == BfGenericParamKind_Method) && (methodGenericArguments != NULL))
  6890. {
  6891. if (genericParam->mGenericParamIdx < (int)methodGenericArguments->size())
  6892. {
  6893. auto resolvedType = FixIntUnknown((*methodGenericArguments)[genericParam->mGenericParamIdx]);
  6894. if ((resolvedType != NULL) && (resolvedType->IsGenericParam()))
  6895. {
  6896. auto genericParamType = (BfGenericParamType*)resolvedType;
  6897. //BF_ASSERT(genericParamType->mGenericParamKind != BfGenericParamKind_Method);
  6898. }
  6899. return resolvedType;
  6900. }
  6901. BF_ASSERT(allowFail);
  6902. }
  6903. return unspecializedType;
  6904. }
  6905. if ((unspecializedType->IsSelf()) && (mCurTypeInstance != NULL))
  6906. return mCurTypeInstance;
  6907. if (!unspecializedType->IsUnspecializedType())
  6908. {
  6909. return unspecializedType;
  6910. }
  6911. if (unspecializedType->IsUnknownSizedArrayType())
  6912. {
  6913. auto* arrayType = (BfUnknownSizedArrayType*)unspecializedType;
  6914. auto elementType = ResolveGenericType(arrayType->mElementType, typeGenericArguments, methodGenericArguments, allowFail);
  6915. if (elementType == NULL)
  6916. return NULL;
  6917. if (elementType->IsVar())
  6918. return elementType;
  6919. auto sizeType = ResolveGenericType(arrayType->mElementCountSource, typeGenericArguments, methodGenericArguments, allowFail);
  6920. if (sizeType == NULL)
  6921. return NULL;
  6922. if (sizeType->IsConstExprValue())
  6923. {
  6924. return CreateSizedArrayType(elementType, ((BfConstExprValueType*)sizeType)->mValue.mInt32);
  6925. }
  6926. return CreateUnknownSizedArrayType(elementType, sizeType);
  6927. }
  6928. if (unspecializedType->IsSizedArray())
  6929. {
  6930. auto* arrayType = (BfSizedArrayType*)unspecializedType;
  6931. auto elementType = ResolveGenericType(arrayType->mElementType, typeGenericArguments, methodGenericArguments, allowFail);
  6932. if (elementType == NULL)
  6933. return NULL;
  6934. if (elementType->IsVar())
  6935. return elementType;
  6936. elementType = FixIntUnknown(elementType);
  6937. return CreateSizedArrayType(elementType, (int)arrayType->mElementCount);
  6938. }
  6939. if (unspecializedType->IsRef())
  6940. {
  6941. auto refType = (BfRefType*)unspecializedType;
  6942. auto elementType = ResolveGenericType(refType->GetUnderlyingType(), typeGenericArguments, methodGenericArguments, allowFail);
  6943. if (elementType == NULL)
  6944. return NULL;
  6945. if (elementType->IsVar())
  6946. return elementType;
  6947. elementType = FixIntUnknown(elementType);
  6948. return CreateRefType(elementType, refType->mRefKind);
  6949. }
  6950. if (unspecializedType->IsPointer())
  6951. {
  6952. auto ptrType = (BfPointerType*)unspecializedType;
  6953. auto elementType = ResolveGenericType(ptrType->GetUnderlyingType(), typeGenericArguments, methodGenericArguments, allowFail);
  6954. if (elementType == NULL)
  6955. return NULL;
  6956. if (elementType->IsVar())
  6957. return elementType;
  6958. elementType = FixIntUnknown(elementType);
  6959. return CreatePointerType(elementType);
  6960. }
  6961. if (unspecializedType->IsConcreteInterfaceType())
  6962. {
  6963. auto concreteType = (BfConcreteInterfaceType*)unspecializedType;
  6964. auto elementType = ResolveGenericType(concreteType->GetUnderlyingType(), typeGenericArguments, methodGenericArguments, allowFail);
  6965. if (elementType == NULL)
  6966. return NULL;
  6967. auto elementTypeInstance = elementType->ToTypeInstance();
  6968. if (elementTypeInstance == NULL)
  6969. return unspecializedType;
  6970. return CreateConcreteInterfaceType(elementTypeInstance);
  6971. }
  6972. if (unspecializedType->IsArray())
  6973. {
  6974. auto arrayType = (BfArrayType*)unspecializedType;
  6975. auto elementType = ResolveGenericType(arrayType->GetUnderlyingType(), typeGenericArguments, methodGenericArguments, allowFail);
  6976. if (elementType == NULL)
  6977. return NULL;
  6978. if (elementType->IsVar())
  6979. return elementType;
  6980. elementType = FixIntUnknown(elementType);
  6981. return CreateArrayType(elementType, arrayType->mDimensions);
  6982. }
  6983. if (unspecializedType->IsTuple())
  6984. {
  6985. bool wantGeneric = false;
  6986. bool isUnspecialized = false;
  6987. auto unspecializedTupleType = (BfTypeInstance*)unspecializedType;
  6988. auto unspecializedGenericTupleType = unspecializedTupleType->ToGenericTypeInstance();
  6989. Array<String> fieldNames;
  6990. BfTypeVector fieldTypes;
  6991. bool hadChange = false;
  6992. for (auto& fieldInstance : unspecializedTupleType->mFieldInstances)
  6993. {
  6994. fieldNames.push_back(fieldInstance.GetFieldDef()->mName);
  6995. auto origGenericArg = fieldInstance.mResolvedType;
  6996. auto newGenericArg = ResolveGenericType(origGenericArg, typeGenericArguments, methodGenericArguments, allowFail);
  6997. if (newGenericArg == NULL)
  6998. return NULL;
  6999. if (newGenericArg->IsVar())
  7000. return newGenericArg;
  7001. if (newGenericArg->IsTypeGenericParam())
  7002. wantGeneric = true;
  7003. if (newGenericArg->IsUnspecializedType())
  7004. isUnspecialized = true;
  7005. if (newGenericArg->IsVar())
  7006. wantGeneric = mContext->mBfObjectType;
  7007. //wantGeneric = true;
  7008. if (newGenericArg != origGenericArg)
  7009. hadChange = true;
  7010. fieldTypes.push_back(newGenericArg);
  7011. }
  7012. if (!hadChange)
  7013. return unspecializedType;
  7014. if (unspecializedGenericTupleType == NULL)
  7015. wantGeneric = false;
  7016. //TODO:
  7017. wantGeneric = false;
  7018. auto baseType = (BfTypeInstance*)ResolveTypeDef(mContext->mCompiler->mValueTypeTypeDef);
  7019. BfTupleType* tupleType = NULL;
  7020. if (wantGeneric)
  7021. {
  7022. Array<BfType*> genericArgs;
  7023. for (int genericArgIdx = 0; genericArgIdx < (int)unspecializedGenericTupleType->mGenericTypeInfo->mTypeGenericArguments.size(); genericArgIdx++)
  7024. {
  7025. BfType* resolvedArg = unspecializedGenericTupleType->mGenericTypeInfo->mTypeGenericArguments[genericArgIdx];
  7026. if (resolvedArg->IsUnspecializedType())
  7027. {
  7028. resolvedArg = ResolveGenericType(resolvedArg, typeGenericArguments, methodGenericArguments, allowFail);
  7029. if (resolvedArg == NULL)
  7030. return NULL;
  7031. if (resolvedArg->IsVar())
  7032. return resolvedArg;
  7033. }
  7034. genericArgs.push_back(resolvedArg);
  7035. }
  7036. auto actualTupleType = mContext->mTupleTypePool.Get();
  7037. delete actualTupleType->mGenericTypeInfo;
  7038. actualTupleType->mGenericDepth = 0;
  7039. actualTupleType->mGenericTypeInfo = new BfGenericTypeInfo();
  7040. actualTupleType->mGenericTypeInfo->mIsUnspecialized = false;
  7041. actualTupleType->mGenericTypeInfo->mIsUnspecializedVariation = false;
  7042. actualTupleType->mGenericTypeInfo->mTypeGenericArguments = genericArgs;
  7043. for (int genericArgIdx = 0; genericArgIdx < (int)unspecializedGenericTupleType->mGenericTypeInfo->mTypeGenericArguments.size(); genericArgIdx++)
  7044. {
  7045. auto typeGenericArg = genericArgs[genericArgIdx];
  7046. if ((typeGenericArg->IsGenericParam()) || (typeGenericArg->IsUnspecializedType()))
  7047. actualTupleType->mGenericTypeInfo->mIsUnspecialized = true;
  7048. actualTupleType->mGenericTypeInfo->mGenericParams.push_back(unspecializedGenericTupleType->mGenericTypeInfo->mGenericParams[genericArgIdx]->AddRef());
  7049. }
  7050. CheckUnspecializedGenericType(actualTupleType, BfPopulateType_Identity);
  7051. if (isUnspecialized)
  7052. {
  7053. actualTupleType->mGenericTypeInfo->mIsUnspecialized = true;
  7054. actualTupleType->mGenericTypeInfo->mIsUnspecializedVariation = true;
  7055. }
  7056. actualTupleType->mIsUnspecializedType = actualTupleType->mGenericTypeInfo->mIsUnspecialized;
  7057. actualTupleType->mIsUnspecializedTypeVariation = actualTupleType->mGenericTypeInfo->mIsUnspecializedVariation;
  7058. actualTupleType->Init(baseType->mTypeDef->mProject, baseType);
  7059. for (int fieldIdx = 0; fieldIdx < (int)fieldTypes.size(); fieldIdx++)
  7060. {
  7061. String fieldName = fieldNames[fieldIdx];
  7062. BfFieldDef* fieldDef = actualTupleType->AddField(fieldName);
  7063. }
  7064. tupleType = actualTupleType;
  7065. }
  7066. else
  7067. {
  7068. auto actualTupleType = new BfTupleType();
  7069. actualTupleType->mIsUnspecializedType = isUnspecialized;
  7070. actualTupleType->mIsUnspecializedTypeVariation = isUnspecialized;
  7071. actualTupleType->Init(baseType->mTypeDef->mProject, baseType);
  7072. for (int fieldIdx = 0; fieldIdx < (int)fieldTypes.size(); fieldIdx++)
  7073. {
  7074. String fieldName = fieldNames[fieldIdx];
  7075. BfFieldDef* fieldDef = actualTupleType->AddField(fieldName);
  7076. }
  7077. tupleType = actualTupleType;
  7078. }
  7079. tupleType->mContext = mContext;
  7080. tupleType->mFieldInstances.Resize(fieldTypes.size());
  7081. for (int fieldIdx = 0; fieldIdx < (int)fieldTypes.size(); fieldIdx++)
  7082. {
  7083. BfFieldInstance* fieldInstance = (BfFieldInstance*)&tupleType->mFieldInstances[fieldIdx];
  7084. fieldInstance->mFieldIdx = fieldIdx;
  7085. fieldInstance->SetResolvedType(fieldTypes[fieldIdx]);
  7086. fieldInstance->mOwner = tupleType;
  7087. tupleType->mGenericDepth = BF_MAX(tupleType->mGenericDepth, fieldInstance->mResolvedType->GetGenericDepth() + 1);
  7088. }
  7089. bool failed = false;
  7090. BfType* resolvedType = NULL;
  7091. if (!failed)
  7092. resolvedType = ResolveType(tupleType, BfPopulateType_Identity);
  7093. if (resolvedType != tupleType)
  7094. {
  7095. delete tupleType->mGenericTypeInfo;
  7096. tupleType->mGenericTypeInfo = NULL;
  7097. tupleType->Dispose();
  7098. mContext->mTupleTypePool.GiveBack((BfTupleType*)tupleType);
  7099. }
  7100. BF_ASSERT((resolvedType == NULL) || resolvedType->IsTypeInstance() || resolvedType->IsPrimitiveType());
  7101. return resolvedType;
  7102. }
  7103. if ((unspecializedType->IsDelegateFromTypeRef()) || (unspecializedType->IsFunctionFromTypeRef()))
  7104. {
  7105. BfTypeInstance* unspecializedDelegateType = (BfTypeInstance*)unspecializedType;
  7106. BfTypeInstance* unspecializedGenericDelegateType = unspecializedType->ToGenericTypeInstance();
  7107. BfDelegateInfo* unspecializedDelegateInfo = unspecializedType->GetDelegateInfo();
  7108. bool wantGeneric = false;
  7109. bool isUnspecialized = false;
  7110. auto _CheckType = [&](BfType* type)
  7111. {
  7112. if (type->IsTypeGenericParam())
  7113. wantGeneric = true;
  7114. if (type->IsUnspecializedType())
  7115. isUnspecialized = true;
  7116. };
  7117. bool failed = false;
  7118. bool hasTypeGenerics = false;
  7119. auto returnType = ResolveGenericType(unspecializedDelegateInfo->mReturnType, typeGenericArguments, methodGenericArguments, allowFail);
  7120. if (returnType == NULL)
  7121. return NULL;
  7122. if (returnType->IsVar())
  7123. return returnType;
  7124. _CheckType(returnType);
  7125. if (returnType->IsGenericParam())
  7126. hasTypeGenerics |= ((BfGenericParamType*)returnType)->mGenericParamKind == BfGenericParamKind_Type;
  7127. Array<BfType*> paramTypes;
  7128. for (auto param : unspecializedDelegateInfo->mParams)
  7129. {
  7130. auto paramType = ResolveGenericType(param, typeGenericArguments, methodGenericArguments, allowFail);
  7131. if (paramType == NULL)
  7132. return NULL;
  7133. if (paramType->IsVar())
  7134. return paramType;
  7135. paramTypes.Add(paramType);
  7136. _CheckType(paramType);
  7137. }
  7138. if (unspecializedGenericDelegateType == NULL)
  7139. wantGeneric = false;
  7140. //TODO:
  7141. wantGeneric = false;
  7142. BfTypeInstance* delegateType = NULL;
  7143. auto baseDelegateType = ResolveTypeDef(mCompiler->mDelegateTypeDef)->ToTypeInstance();
  7144. if (wantGeneric)
  7145. {
  7146. Array<BfType*> genericArgs;
  7147. for (int genericArgIdx = 0; genericArgIdx < (int)unspecializedGenericDelegateType->mGenericTypeInfo->mTypeGenericArguments.size(); genericArgIdx++)
  7148. {
  7149. BfType* resolvedArg = unspecializedGenericDelegateType->mGenericTypeInfo->mTypeGenericArguments[genericArgIdx];
  7150. if (resolvedArg->IsUnspecializedType())
  7151. {
  7152. resolvedArg = ResolveGenericType(resolvedArg, typeGenericArguments, methodGenericArguments, allowFail);
  7153. if (resolvedArg == NULL)
  7154. return NULL;
  7155. if (resolvedArg->IsVar())
  7156. return resolvedArg;
  7157. }
  7158. genericArgs.push_back(resolvedArg);
  7159. }
  7160. auto dlgType = mContext->mDelegateTypePool.Get();
  7161. delete dlgType->mGenericTypeInfo;
  7162. dlgType->mGenericTypeInfo = new BfGenericTypeInfo();
  7163. dlgType->mGenericTypeInfo->mFinishedGenericParams = true;
  7164. dlgType->mGenericTypeInfo->mIsUnspecialized = false;
  7165. dlgType->mGenericTypeInfo->mIsUnspecializedVariation = false;
  7166. dlgType->mGenericTypeInfo->mTypeGenericArguments = genericArgs;
  7167. for (int genericArgIdx = 0; genericArgIdx < (int)unspecializedGenericDelegateType->mGenericTypeInfo->mTypeGenericArguments.size(); genericArgIdx++)
  7168. {
  7169. auto typeGenericArg = genericArgs[genericArgIdx];
  7170. if ((typeGenericArg->IsGenericParam()) || (typeGenericArg->IsUnspecializedType()))
  7171. dlgType->mGenericTypeInfo->mIsUnspecialized = true;
  7172. dlgType->mGenericTypeInfo->mGenericParams.push_back(unspecializedGenericDelegateType->mGenericTypeInfo->mGenericParams[genericArgIdx]->AddRef());
  7173. }
  7174. CheckUnspecializedGenericType(dlgType, BfPopulateType_Identity);
  7175. if (isUnspecialized)
  7176. {
  7177. dlgType->mGenericTypeInfo->mIsUnspecialized = true;
  7178. dlgType->mGenericTypeInfo->mIsUnspecializedVariation = true;
  7179. }
  7180. dlgType->mIsUnspecializedType = dlgType->mGenericTypeInfo->mIsUnspecialized;
  7181. dlgType->mIsUnspecializedTypeVariation = dlgType->mGenericTypeInfo->mIsUnspecializedVariation;
  7182. delegateType = dlgType;
  7183. }
  7184. else
  7185. {
  7186. auto dlgType = mContext->mDelegateTypePool.Get();
  7187. dlgType->mIsUnspecializedType = isUnspecialized;
  7188. dlgType->mIsUnspecializedTypeVariation = isUnspecialized;
  7189. delegateType = dlgType;
  7190. }
  7191. delete delegateType->mTypeDef;
  7192. delegateType->mTypeDef = NULL;
  7193. BfDelegateInfo* delegateInfo = delegateType->GetDelegateInfo();
  7194. delegateInfo->mParams.Clear();
  7195. BfTypeDef* typeDef = new BfTypeDef();
  7196. typeDef->mProject = baseDelegateType->mTypeDef->mProject;
  7197. typeDef->mSystem = mCompiler->mSystem;
  7198. typeDef->mName = mSystem->mEmptyAtom;
  7199. typeDef->mTypeCode = unspecializedDelegateType->mTypeDef->mTypeCode;
  7200. typeDef->mIsDelegate = unspecializedDelegateType->mTypeDef->mIsDelegate;
  7201. typeDef->mIsFunction = unspecializedDelegateType->mTypeDef->mIsFunction;
  7202. BfMethodDef* unspecializedInvokeMethodDef = unspecializedDelegateType->mTypeDef->GetMethodByName("Invoke");
  7203. BfMethodDef* methodDef = new BfMethodDef();
  7204. methodDef->mDeclaringType = typeDef;
  7205. methodDef->mName = "Invoke";
  7206. methodDef->mProtection = BfProtection_Public;
  7207. methodDef->mIdx = 0;
  7208. methodDef->mIsStatic = !typeDef->mIsDelegate && !unspecializedDelegateInfo->mHasExplicitThis;
  7209. methodDef->mHasExplicitThis = unspecializedDelegateInfo->mHasExplicitThis;
  7210. auto directTypeRef = BfAstNode::ZeroedAlloc<BfDirectTypeReference>();
  7211. delegateInfo->mDirectAllocNodes.push_back(directTypeRef);
  7212. if (typeDef->mIsDelegate)
  7213. directTypeRef->Init(delegateType);
  7214. else
  7215. directTypeRef->Init(ResolveTypeDef(mCompiler->mFunctionTypeDef));
  7216. typeDef->mBaseTypes.push_back(directTypeRef);
  7217. directTypeRef = BfAstNode::ZeroedAlloc<BfDirectTypeReference>();
  7218. delegateInfo->mDirectAllocNodes.push_back(directTypeRef);
  7219. directTypeRef->Init(returnType);
  7220. methodDef->mReturnTypeRef = directTypeRef;
  7221. delegateInfo->mReturnType = returnType;
  7222. delegateInfo->mHasExplicitThis = unspecializedDelegateInfo->mHasExplicitThis;
  7223. delegateInfo->mHasVarArgs = unspecializedDelegateInfo->mHasVarArgs;
  7224. int paramIdx = 0;
  7225. for (int paramIdx = 0; paramIdx < (int)paramTypes.size(); paramIdx++)
  7226. {
  7227. auto paramType = paramTypes[paramIdx];
  7228. BfParameterDef* unspecializedParamDef = unspecializedInvokeMethodDef->mParams[paramIdx];
  7229. if (!paramType->IsReified())
  7230. delegateType->mIsReified = false;
  7231. auto directTypeRef = BfAstNode::ZeroedAlloc<BfDirectTypeReference>();
  7232. delegateInfo->mDirectAllocNodes.push_back(directTypeRef);
  7233. directTypeRef->Init(paramType);
  7234. BfParameterDef* paramDef = new BfParameterDef();
  7235. paramDef->mTypeRef = directTypeRef;
  7236. paramDef->mName = unspecializedParamDef->mName;
  7237. methodDef->mParams.push_back(paramDef);
  7238. delegateInfo->mParams.Add(paramType);
  7239. }
  7240. typeDef->mMethods.push_back(methodDef);
  7241. if (unspecializedInvokeMethodDef->mIsMutating)
  7242. {
  7243. if ((delegateInfo->mParams[0]->IsValueType()) || (delegateInfo->mParams[0]->IsGenericParam()))
  7244. methodDef->mIsMutating = unspecializedInvokeMethodDef->mIsMutating;
  7245. }
  7246. //
  7247. if (typeDef->mIsDelegate)
  7248. {
  7249. BfDefBuilder::AddMethod(typeDef, BfMethodType_Ctor, BfProtection_Public, false, "");
  7250. BfDefBuilder::AddDynamicCastMethods(typeDef);
  7251. }
  7252. delegateType->mContext = mContext;
  7253. delegateType->mTypeDef = typeDef;
  7254. BfType* resolvedType = NULL;
  7255. if (!failed)
  7256. resolvedType = ResolveType(delegateType, BfPopulateType_Identity);
  7257. if (resolvedType == delegateType)
  7258. {
  7259. AddDependency(directTypeRef->mType, delegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue);
  7260. for (auto paramType : paramTypes)
  7261. AddDependency(paramType, delegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue);
  7262. }
  7263. else
  7264. {
  7265. delegateType->Dispose();
  7266. mContext->mDelegateTypePool.GiveBack((BfDelegateType*)delegateType);
  7267. }
  7268. BF_ASSERT((resolvedType == NULL) || resolvedType->IsTypeInstance() || resolvedType->IsPrimitiveType());
  7269. return resolvedType;
  7270. }
  7271. if (unspecializedType->IsGenericTypeInstance())
  7272. {
  7273. auto genericTypeInst = (BfTypeInstance*)unspecializedType;
  7274. BfTypeVector genericArgs;
  7275. for (auto genericArg : genericTypeInst->mGenericTypeInfo->mTypeGenericArguments)
  7276. {
  7277. if (genericArg->IsUnspecializedType())
  7278. {
  7279. auto resolvedArg = ResolveGenericType(genericArg, typeGenericArguments, methodGenericArguments, allowFail);
  7280. if (resolvedArg == NULL)
  7281. return NULL;
  7282. if (resolvedArg->IsVar())
  7283. return resolvedArg;
  7284. genericArgs.push_back(resolvedArg);
  7285. }
  7286. else
  7287. genericArgs.push_back(genericArg);
  7288. }
  7289. auto resolvedType = ResolveTypeDef(genericTypeInst->mTypeDef->GetDefinition(), genericArgs, BfPopulateType_BaseType);
  7290. BfTypeInstance* specializedType = NULL;
  7291. if (resolvedType != NULL)
  7292. specializedType = resolvedType->ToGenericTypeInstance();
  7293. if (specializedType != NULL)
  7294. {
  7295. if (specializedType->mGenericTypeInfo->mHadValidateErrors)
  7296. return NULL;
  7297. }
  7298. return specializedType;
  7299. }
  7300. return unspecializedType;
  7301. }
  7302. BfType* BfModule::ResolveSelfType(BfType* type, BfTypeInstance* selfType)
  7303. {
  7304. if (!type->IsUnspecializedTypeVariation())
  7305. return type;
  7306. SetAndRestoreValue<BfTypeInstance*> prevCurTypeInst(mCurTypeInstance, selfType);
  7307. return ResolveGenericType(type, NULL, NULL);
  7308. }
  7309. BfType* BfModule::ResolveType(BfType* lookupType, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags)
  7310. {
  7311. BfResolvedTypeSet::LookupContext lookupCtx;
  7312. lookupCtx.mModule = this;
  7313. lookupCtx.mResolveFlags = resolveFlags;
  7314. BfResolvedTypeSet::Entry* resolvedEntry = NULL;
  7315. bool inserted = mContext->mResolvedTypes.Insert(lookupType, &lookupCtx, &resolvedEntry);
  7316. if (resolvedEntry == NULL)
  7317. return NULL;
  7318. if (!inserted)
  7319. {
  7320. auto resolvedTypeRef = resolvedEntry->mValue;
  7321. PopulateType(resolvedTypeRef, populateType);
  7322. return resolvedTypeRef;
  7323. }
  7324. if (lookupType->IsGenericTypeInstance())
  7325. CheckUnspecializedGenericType((BfTypeInstance*)lookupType, populateType);
  7326. if (lookupType->IsTuple())
  7327. {
  7328. auto tupleType = (BfTupleType*)lookupType;
  7329. tupleType->Finish();
  7330. }
  7331. resolvedEntry->mValue = lookupType;
  7332. InitType(lookupType, populateType);
  7333. return lookupType;
  7334. }
  7335. bool BfModule::IsUnboundGeneric(BfType* type)
  7336. {
  7337. if (type->IsVar())
  7338. return true;
  7339. if (!type->IsGenericParam())
  7340. return false;
  7341. auto genericParamInst = GetGenericParamInstance((BfGenericParamType*)type);
  7342. return (genericParamInst->mGenericParamFlags & BfGenericParamFlag_Var) != 0;
  7343. }
  7344. BfGenericParamInstance* BfModule::GetGenericTypeParamInstance(int genericParamIdx)
  7345. {
  7346. // When we're evaluating a method, make sure the params refer back to that method context
  7347. auto curTypeInstance = mCurTypeInstance;
  7348. //TODO: This caused MethodToString issues with interface "implementation method not found" errors
  7349. // if (mCurMethodInstance != NULL)
  7350. // curTypeInstance = mCurMethodInstance->mMethodInstanceGroup->mOwner;
  7351. BfTypeInstance* genericTypeInst = curTypeInstance->ToGenericTypeInstance();
  7352. if ((genericTypeInst->IsIncomplete()) && (genericTypeInst->mGenericTypeInfo->mGenericParams.size() == 0))
  7353. {
  7354. // Set this to NULL so we don't recurse infinitely
  7355. SetAndRestoreValue<BfTypeInstance*> prevTypeInst(mCurTypeInstance, NULL);
  7356. PopulateType(genericTypeInst, BfPopulateType_Declaration);
  7357. }
  7358. if (genericParamIdx >= (int)genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size())
  7359. {
  7360. if (genericParamIdx >= genericTypeInst->mGenericTypeInfo->mGenericParams.mSize)
  7361. FatalError("Invalid GetGenericTypeParamInstance");
  7362. // Extern constraints should always be directly used - they don't get extended
  7363. return genericTypeInst->mGenericTypeInfo->mGenericParams[genericParamIdx];
  7364. }
  7365. if (genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo != NULL)
  7366. {
  7367. auto activeTypeDef = GetActiveTypeDef(NULL, true);
  7368. if ((activeTypeDef->mTypeDeclaration != genericTypeInst->mTypeDef->mTypeDeclaration) && (activeTypeDef->IsExtension()))
  7369. {
  7370. BfTypeDef* lookupTypeDef = activeTypeDef;
  7371. while (lookupTypeDef->mNestDepth > genericTypeInst->mTypeDef->mNestDepth)
  7372. lookupTypeDef = lookupTypeDef->mOuterType;
  7373. BfGenericExtensionEntry* genericExEntry;
  7374. if (genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo->mExtensionMap.TryGetValue(lookupTypeDef, &genericExEntry))
  7375. {
  7376. return genericExEntry->mGenericParams[genericParamIdx];
  7377. }
  7378. else
  7379. {
  7380. if ((mCompiler->mResolvePassData == NULL) || (mCompiler->mResolvePassData->mAutoComplete == NULL))
  7381. {
  7382. FatalError("Invalid GetGenericParamInstance with extension");
  7383. }
  7384. }
  7385. }
  7386. }
  7387. BF_ASSERT(genericTypeInst != NULL);
  7388. return genericTypeInst->mGenericTypeInfo->mGenericParams[genericParamIdx];
  7389. }
  7390. void BfModule::GetActiveTypeGenericParamInstances(SizedArray<BfGenericParamInstance*, 4>& genericParamInstances)
  7391. {
  7392. // When we're evaluating a method, make sure the params refer back to that method context
  7393. auto curTypeInstance = mCurTypeInstance;
  7394. if (mCurMethodInstance != NULL)
  7395. curTypeInstance = mCurMethodInstance->mMethodInstanceGroup->mOwner;
  7396. BfTypeInstance* genericTypeInst = curTypeInstance->ToGenericTypeInstance();
  7397. if ((genericTypeInst->IsIncomplete()) && (genericTypeInst->mGenericTypeInfo->mGenericParams.size() == 0))
  7398. {
  7399. // Set this to NULL so we don't recurse infinitely
  7400. SetAndRestoreValue<BfTypeInstance*> prevTypeInst(mCurTypeInstance, NULL);
  7401. PopulateType(genericTypeInst, BfPopulateType_Declaration);
  7402. }
  7403. if (genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo != NULL)
  7404. {
  7405. auto activeTypeDef = GetActiveTypeDef(NULL, true);
  7406. if ((activeTypeDef->mTypeDeclaration != genericTypeInst->mTypeDef->mTypeDeclaration) && (activeTypeDef->IsExtension()))
  7407. {
  7408. BfTypeDef* lookupTypeDef = activeTypeDef;
  7409. while (lookupTypeDef->mNestDepth > genericTypeInst->mTypeDef->mNestDepth)
  7410. lookupTypeDef = lookupTypeDef->mOuterType;
  7411. BfGenericExtensionEntry* genericExEntry;
  7412. if (genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo->mExtensionMap.TryGetValue(lookupTypeDef, &genericExEntry))
  7413. {
  7414. for (auto entry : genericExEntry->mGenericParams)
  7415. genericParamInstances.Add(entry);
  7416. auto genericTypeInfo = genericTypeInst->mGenericTypeInfo;
  7417. // Add root extern constraints - they don't get extended
  7418. for (int genericParamIdx = (int)genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size(); genericParamIdx < genericTypeInst->mGenericTypeInfo->mGenericParams.size(); genericParamIdx++)
  7419. genericParamInstances.Add(genericTypeInst->mGenericTypeInfo->mGenericParams[genericParamIdx]);
  7420. return;
  7421. }
  7422. else
  7423. {
  7424. if ((mCompiler->mResolvePassData == NULL) || (mCompiler->mResolvePassData->mAutoComplete == NULL))
  7425. {
  7426. BFMODULE_FATAL(this, "Invalid GetGenericParamInstance with extension");
  7427. }
  7428. }
  7429. }
  7430. }
  7431. BF_ASSERT(genericTypeInst != NULL);
  7432. for (auto entry : genericTypeInst->mGenericTypeInfo->mGenericParams)
  7433. genericParamInstances.Add(entry);
  7434. }
  7435. BfGenericParamInstance* BfModule::GetMergedGenericParamData(BfGenericParamType* type, BfGenericParamFlags& outFlags, BfType*& outTypeConstraint)
  7436. {
  7437. BfGenericParamInstance* genericParam = GetGenericParamInstance(type);
  7438. outFlags = genericParam->mGenericParamFlags;
  7439. outTypeConstraint = genericParam->mTypeConstraint;
  7440. // Check method generic constraints
  7441. if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mIsUnspecialized) && (mCurMethodInstance->mMethodInfoEx != NULL))
  7442. {
  7443. for (int genericParamIdx = (int)mCurMethodInstance->mMethodInfoEx->mMethodGenericArguments.size();
  7444. genericParamIdx < mCurMethodInstance->mMethodInfoEx->mGenericParams.size(); genericParamIdx++)
  7445. {
  7446. auto genericParam = mCurMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
  7447. if (genericParam->mExternType == type)
  7448. {
  7449. outFlags = (BfGenericParamFlags)(outFlags | genericParam->mGenericParamFlags);
  7450. if (genericParam->mTypeConstraint != NULL)
  7451. outTypeConstraint = genericParam->mTypeConstraint;
  7452. }
  7453. }
  7454. }
  7455. return genericParam;
  7456. }
  7457. BfGenericParamInstance* BfModule::GetGenericParamInstance(BfGenericParamType* type)
  7458. {
  7459. if (type->mGenericParamKind == BfGenericParamKind_Method)
  7460. {
  7461. if ((mCurMethodInstance->mMethodInfoEx == NULL) || (type->mGenericParamIdx >= mCurMethodInstance->mMethodInfoEx->mGenericParams.mSize))
  7462. {
  7463. FatalError("Invalid GetGenericParamInstance method generic param");
  7464. return NULL;
  7465. }
  7466. return mCurMethodInstance->mMethodInfoEx->mGenericParams[type->mGenericParamIdx];
  7467. }
  7468. return GetGenericTypeParamInstance(type->mGenericParamIdx);
  7469. }
  7470. bool BfModule::ResolveTypeResult_Validate(BfAstNode* typeRef, BfType* resolvedTypeRef)
  7471. {
  7472. if ((typeRef == NULL) || (resolvedTypeRef == NULL))
  7473. return true;
  7474. BfTypeInstance* genericTypeInstance = resolvedTypeRef->ToGenericTypeInstance();
  7475. if ((genericTypeInstance != NULL) && (genericTypeInstance != mCurTypeInstance))
  7476. {
  7477. bool doValidate = (genericTypeInstance->mGenericTypeInfo->mHadValidateErrors) ||
  7478. (!genericTypeInstance->mGenericTypeInfo->mValidatedGenericConstraints) ||
  7479. (genericTypeInstance->mGenericTypeInfo->mIsUnspecializedVariation);
  7480. if ((mCurMethodInstance != NULL) && (mCurMethodInstance->IsOrInUnspecializedVariation()))
  7481. doValidate = false;
  7482. if (mCurTypeInstance != NULL)
  7483. {
  7484. if (mCurTypeInstance->IsUnspecializedTypeVariation())
  7485. doValidate = false;
  7486. if (auto curGenericTypeInstance = mCurTypeInstance->ToGenericTypeInstance())
  7487. {
  7488. if ((curGenericTypeInstance->mDependencyMap.mMinDependDepth > 32) &&
  7489. (genericTypeInstance->mDependencyMap.mMinDependDepth > 32))
  7490. {
  7491. Fail(StrFormat("Generic type dependency depth exceeded for type '%s'", TypeToString(genericTypeInstance).c_str()), typeRef);
  7492. return false;
  7493. }
  7494. if (curGenericTypeInstance->mGenericTypeInfo->mHadValidateErrors)
  7495. doValidate = false;
  7496. }
  7497. if ((mContext->mCurTypeState != NULL) && (mContext->mCurTypeState->mCurBaseTypeRef != NULL) && (!mContext->mCurTypeState->mType->IsTypeAlias())) // We validate constraints for base types later
  7498. doValidate = false;
  7499. }
  7500. if (doValidate)
  7501. ValidateGenericConstraints(typeRef, genericTypeInstance, false);
  7502. }
  7503. if (auto genericInstanceTypeRef = BfNodeDynCastExact<BfGenericInstanceTypeRef>(typeRef))
  7504. {
  7505. if (genericTypeInstance != NULL)
  7506. {
  7507. auto genericTypeInfo = genericTypeInstance->GetGenericTypeInfo();
  7508. for (int argIdx = 0; argIdx < (int)genericInstanceTypeRef->mGenericArguments.size(); argIdx++)
  7509. {
  7510. ResolveTypeResult_Validate(genericInstanceTypeRef->mGenericArguments[argIdx], genericTypeInfo->mTypeGenericArguments[argIdx]);
  7511. }
  7512. }
  7513. }
  7514. else if (auto elementedTypeRef = BfNodeDynCast<BfElementedTypeRef>(typeRef))
  7515. {
  7516. return ResolveTypeResult_Validate(elementedTypeRef, resolvedTypeRef->GetUnderlyingType());
  7517. }
  7518. return true;
  7519. }
  7520. BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTypeRef, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags)
  7521. {
  7522. if ((mCompiler->mIsResolveOnly) && (!IsInSpecializedSection()))
  7523. {
  7524. bool isGetDefinition = false;
  7525. BfAutoComplete* autoComplete = NULL;
  7526. if (mCompiler->IsAutocomplete())
  7527. {
  7528. autoComplete = mCompiler->mResolvePassData->mAutoComplete;
  7529. isGetDefinition = autoComplete->mIsGetDefinition || (autoComplete->mResolveType == BfResolveType_GetResultString);
  7530. }
  7531. BfSourceData* typeRefSource = NULL;
  7532. if (typeRef->IsTemporary())
  7533. {
  7534. BfTypeReference* checkTypeRef = typeRef;
  7535. if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(checkTypeRef))
  7536. checkTypeRef = genericTypeRef->mElementType;
  7537. if (auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(checkTypeRef))
  7538. typeRefSource = namedTypeRef->mNameNode->GetSourceData();
  7539. }
  7540. else
  7541. typeRefSource = typeRef->GetSourceData();
  7542. bool wantsFileNamespaceInfo = (((mCompiler->mResolvePassData->mSourceClassifier != NULL) || (isGetDefinition) || (mCompiler->mResolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Namespace)) &&
  7543. (typeRefSource != NULL) && (mCompiler->mResolvePassData->mParser != NULL) &&
  7544. (typeRefSource == mCompiler->mResolvePassData->mParser->mSourceData));
  7545. bool wantsAllNamespaceInfo = (mCompiler->mResolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Namespace) && (mCompiler->mResolvePassData->mParser == NULL);
  7546. if (wantsFileNamespaceInfo || wantsAllNamespaceInfo)
  7547. {
  7548. //TODO: By only breaking out for "mIgnoreErrors", we classified elements (below) even when a resolvedTypeRef was not found!
  7549. //Why did we have this mIgnoreErrors check in there?
  7550. // if ((resolvedTypeRef == NULL) && (mIgnoreErrors))
  7551. if (resolvedTypeRef == NULL)
  7552. {
  7553. return NULL;
  7554. }
  7555. BfTypeInstance* resolvedTypeInstance = NULL;
  7556. if (resolvedTypeRef != NULL)
  7557. resolvedTypeInstance = resolvedTypeRef->ToTypeInstance();
  7558. bool isNamespace = false;
  7559. auto checkTypeRef = typeRef;
  7560. if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(checkTypeRef))
  7561. checkTypeRef = genericTypeRef->mElementType;
  7562. auto headTypeRef = checkTypeRef;
  7563. if (auto elementedTypeRef = BfNodeDynCast<BfElementedTypeRef>(checkTypeRef))
  7564. checkTypeRef = elementedTypeRef->mElementType;
  7565. if (!mIsInsideAutoComplete)
  7566. {
  7567. if ((resolvedTypeInstance != NULL) && (resolvedTypeInstance->mTypeDef->IsGlobalsContainer()))
  7568. {
  7569. isNamespace = true;
  7570. }
  7571. else
  7572. {
  7573. //TODO: This broke colorizing of inner expressions for things like "T2[T3]"
  7574. //mCompiler->mResolvePassData->mSourceClassifier->VisitChildNoRef(typeRef);
  7575. }
  7576. }
  7577. BfSourceElementType elemType = BfSourceElementType_Type;
  7578. {
  7579. auto typeRef = resolvedTypeRef;
  7580. while (typeRef->IsTypeAlias())
  7581. {
  7582. typeRef = typeRef->GetUnderlyingType();
  7583. if (typeRef == NULL)
  7584. {
  7585. typeRef = resolvedTypeRef;
  7586. break;
  7587. }
  7588. }
  7589. if (typeRef->IsInterface())
  7590. elemType = BfSourceElementType_Interface;
  7591. else if (typeRef->IsObject())
  7592. elemType = BfSourceElementType_RefType;
  7593. else if (typeRef->IsGenericParam())
  7594. elemType = BfSourceElementType_GenericParam;
  7595. else if (typeRef->IsPrimitiveType())
  7596. elemType = BfSourceElementType_PrimitiveType;
  7597. else if (typeRef->IsStruct() || (typeRef->IsTypedPrimitive() && !typeRef->IsEnum()))
  7598. elemType = BfSourceElementType_Struct;
  7599. }
  7600. while (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(checkTypeRef))
  7601. {
  7602. if ((mCompiler->mResolvePassData->mSourceClassifier != NULL) && (checkTypeRef == headTypeRef) && (elemType != BfSourceElementType_Type))
  7603. mCompiler->mResolvePassData->mSourceClassifier->SetElementType(qualifiedTypeRef->mRight, elemType);
  7604. StringView leftString = qualifiedTypeRef->mLeft->ToStringView();
  7605. BfSizedAtomComposite leftComposite;
  7606. bool isValid = mSystem->ParseAtomComposite(leftString, leftComposite);
  7607. if (mCompiler->mResolvePassData->mSourceClassifier != NULL)
  7608. mCompiler->mResolvePassData->mSourceClassifier->SetHighestElementType(qualifiedTypeRef->mRight, isNamespace ? BfSourceElementType_Namespace : BfSourceElementType_Type);
  7609. if (resolvedTypeInstance == NULL)
  7610. {
  7611. if ((isValid) && (mCompiler->mSystem->ContainsNamespace(leftComposite, mCurTypeInstance->mTypeDef->mProject)))
  7612. isNamespace = true;
  7613. }
  7614. else if ((isValid) && (resolvedTypeInstance->mTypeDef->mNamespace.EndsWith(leftComposite)) && (resolvedTypeInstance->mTypeDef->mOuterType == NULL))
  7615. {
  7616. if (autoComplete != NULL)
  7617. {
  7618. if (autoComplete->CheckFixit(typeRef))
  7619. autoComplete->FixitCheckNamespace(GetActiveTypeDef(), qualifiedTypeRef->mLeft, qualifiedTypeRef->mDot);
  7620. autoComplete->CheckNamespace(qualifiedTypeRef->mLeft, resolvedTypeInstance->mTypeDef->mNamespace);
  7621. }
  7622. mCompiler->mResolvePassData->HandleNamespaceReference(qualifiedTypeRef->mLeft, resolvedTypeInstance->mTypeDef->mNamespace);
  7623. isNamespace = true;
  7624. }
  7625. checkTypeRef = qualifiedTypeRef->mLeft;
  7626. }
  7627. if (auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(checkTypeRef))
  7628. {
  7629. auto checkNameNode = namedTypeRef->mNameNode;
  7630. bool setType = false;
  7631. if ((mCompiler->mResolvePassData->mSourceClassifier != NULL) && (checkTypeRef == headTypeRef) && (elemType != BfSourceElementType_Type))
  7632. {
  7633. if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(checkNameNode))
  7634. {
  7635. mCompiler->mResolvePassData->mSourceClassifier->SetElementType(qualifiedNameNode->mRight, elemType);
  7636. }
  7637. else
  7638. {
  7639. setType = true;
  7640. mCompiler->mResolvePassData->mSourceClassifier->SetElementType(checkNameNode, elemType);
  7641. }
  7642. }
  7643. while (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(checkNameNode))
  7644. {
  7645. StringView leftString = qualifiedNameNode->mLeft->ToStringView();
  7646. BfSizedAtomComposite leftComposite;
  7647. bool isValid = mSystem->ParseAtomComposite(leftString, leftComposite);
  7648. if (mCompiler->mResolvePassData->mSourceClassifier != NULL)
  7649. mCompiler->mResolvePassData->mSourceClassifier->SetHighestElementType(qualifiedNameNode->mRight, isNamespace ? BfSourceElementType_Namespace : BfSourceElementType_Type);
  7650. if (resolvedTypeInstance == NULL)
  7651. {
  7652. if ((isValid) && (mCompiler->mSystem->ContainsNamespace(leftComposite, mCurTypeInstance->mTypeDef->mProject)))
  7653. isNamespace = true;
  7654. }
  7655. else if ((isValid) && (resolvedTypeInstance->mTypeDef->mOuterType == NULL) && (resolvedTypeInstance->mTypeDef->mNamespace.EndsWith(leftComposite)))
  7656. {
  7657. if (autoComplete != NULL)
  7658. {
  7659. if (autoComplete->CheckFixit(typeRef))
  7660. autoComplete->FixitCheckNamespace(GetActiveTypeDef(), qualifiedNameNode->mLeft, qualifiedNameNode->mDot);
  7661. autoComplete->CheckNamespace(qualifiedNameNode->mLeft, resolvedTypeInstance->mTypeDef->mNamespace);
  7662. }
  7663. mCompiler->mResolvePassData->HandleNamespaceReference(qualifiedNameNode->mLeft, resolvedTypeInstance->mTypeDef->mNamespace);
  7664. isNamespace = true;
  7665. }
  7666. checkNameNode = qualifiedNameNode->mLeft;
  7667. }
  7668. if ((mCompiler->mResolvePassData->mSourceClassifier != NULL) &&
  7669. ((!setType) || (checkNameNode != namedTypeRef->mNameNode)))
  7670. mCompiler->mResolvePassData->mSourceClassifier->SetHighestElementType(checkNameNode, isNamespace ? BfSourceElementType_Namespace : BfSourceElementType_Type);
  7671. }
  7672. }
  7673. if (((mCompiler->mResolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Type) || (isGetDefinition)) &&
  7674. ((resolveFlags & BfResolveTypeRefFlag_FromIndirectSource) == 0) && (resolvedTypeRef != NULL) && (typeRefSource != NULL))
  7675. {
  7676. BfAstNode* elementTypeRef = typeRef;
  7677. if (auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(elementTypeRef))
  7678. elementTypeRef = namedTypeRef->mNameNode;
  7679. if (elementTypeRef != NULL)
  7680. {
  7681. BfType* elementType = resolvedTypeRef;
  7682. if (BfTypeInstance* elementTypeInst = elementType->ToTypeInstance())
  7683. {
  7684. mCompiler->mResolvePassData->HandleTypeReference(elementTypeRef, elementTypeInst->mTypeDef);
  7685. if (mCompiler->IsAutocomplete())
  7686. {
  7687. BfAutoComplete* autoComplete = mCompiler->mResolvePassData->mAutoComplete;
  7688. if ((isGetDefinition) && (autoComplete->IsAutocompleteNode(elementTypeRef)))
  7689. {
  7690. BfAstNode* baseNode = elementTypeRef;
  7691. while (true)
  7692. {
  7693. if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(baseNode))
  7694. {
  7695. baseNode = qualifiedTypeRef->mRight;
  7696. }
  7697. else if (auto elementedTypeRef = BfNodeDynCast<BfElementedTypeRef>(baseNode))
  7698. {
  7699. baseNode = elementedTypeRef->mElementType;
  7700. }
  7701. else if (auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(baseNode))
  7702. {
  7703. baseNode = namedTypeRef->mNameNode;
  7704. }
  7705. else if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(baseNode))
  7706. {
  7707. baseNode = qualifiedNameNode->mRight;
  7708. }
  7709. else if (auto declTypeRef = BfNodeDynCast<BfExprModTypeRef>(baseNode))
  7710. {
  7711. baseNode = NULL;
  7712. break;
  7713. }
  7714. else
  7715. break;
  7716. }
  7717. if ((baseNode != NULL) && (autoComplete->IsAutocompleteNode(baseNode)))
  7718. {
  7719. // We didn't have this mDefType check before - why? We always want to catch the FIRST definition,
  7720. // so 'Type?' will catch on 'Type' and not 'Type?'
  7721. if ((autoComplete->mDefType == NULL) &&
  7722. (autoComplete->mDefMethod == NULL) && (autoComplete->mDefField == NULL) &&
  7723. (autoComplete->mDefProp == NULL) && (elementTypeInst->mTypeDef->mTypeDeclaration != NULL))
  7724. {
  7725. autoComplete->mDefType = elementTypeInst->mTypeDef;
  7726. autoComplete->SetDefinitionLocation(elementTypeInst->mTypeDef->mTypeDeclaration->mNameNode);
  7727. }
  7728. if ((autoComplete->mResolveType == BfResolveType_GetResultString) && (resolvedTypeRef != NULL))
  7729. {
  7730. autoComplete->SetResultStringType(resolvedTypeRef);
  7731. }
  7732. }
  7733. }
  7734. }
  7735. }
  7736. }
  7737. }
  7738. }
  7739. if (resolvedTypeRef == NULL)
  7740. return NULL;
  7741. if (mCurTypeInstance == NULL)
  7742. {
  7743. // No deps
  7744. }
  7745. else if (resolvedTypeRef->IsTuple())
  7746. {
  7747. // Add the fields from the tuple as references since those inner fields types would have been explicitly stated, so we need
  7748. // to make sure to record the current type instance as a referring type. This mostly matters for symbol renaming.
  7749. BfTypeInstance* payloadTupleType = (BfTypeInstance*)resolvedTypeRef;
  7750. for (auto& payloadFieldInst : payloadTupleType->mFieldInstances)
  7751. {
  7752. auto payloadFieldType = payloadFieldInst.mResolvedType;
  7753. AddDependency(payloadFieldType, mCurTypeInstance, BfDependencyMap::DependencyFlag_TypeReference);
  7754. }
  7755. }
  7756. else if (resolvedTypeRef->IsDelegateFromTypeRef() || resolvedTypeRef->IsFunctionFromTypeRef())
  7757. {
  7758. auto delegateInfo = resolvedTypeRef->GetDelegateInfo();
  7759. // if (delegateInfo->mFunctionThisType != NULL)
  7760. // AddDependency(delegateInfo->mFunctionThisType, mCurTypeInstance, BfDependencyMap::DependencyFlag_TypeReference);
  7761. AddDependency(delegateInfo->mReturnType, mCurTypeInstance, BfDependencyMap::DependencyFlag_TypeReference);
  7762. for (auto& param : delegateInfo->mParams)
  7763. AddDependency(param, mCurTypeInstance, BfDependencyMap::DependencyFlag_TypeReference);
  7764. }
  7765. BfTypeInstance* typeInstance = resolvedTypeRef->ToTypeInstance();
  7766. BfTypeInstance* genericTypeInstance = resolvedTypeRef->ToGenericTypeInstance();
  7767. auto populateModule = this;
  7768. if ((resolveFlags & BfResolveTypeRefFlag_NoReify) != 0)
  7769. populateModule = mContext->mUnreifiedModule;
  7770. populateModule->PopulateType(resolvedTypeRef, populateType);
  7771. if ((typeInstance != NULL) && (typeInstance->mTypeDef != NULL) && (typeInstance->mTypeDef->mProtection == BfProtection_Internal) &&
  7772. (typeInstance != mCurTypeInstance) && (typeInstance->mTypeDef->mOuterType == NULL) && (!typeRef->IsTemporary()))
  7773. {
  7774. if (!CheckProtection(typeInstance->mTypeDef->mProtection, typeInstance->mTypeDef, false, false))
  7775. Fail(StrFormat("'%s' is inaccessible due to its protection level", TypeToString(typeInstance).c_str()), typeRef); // CS0122
  7776. }
  7777. if ((populateType > BfPopulateType_IdentityNoRemapAlias) && (!ResolveTypeResult_Validate(typeRef, resolvedTypeRef)))
  7778. return NULL;
  7779. if (populateType != BfPopulateType_IdentityNoRemapAlias)
  7780. {
  7781. while ((resolvedTypeRef != NULL) && (resolvedTypeRef->IsTypeAlias()))
  7782. {
  7783. if (mCurTypeInstance != NULL)
  7784. AddDependency(resolvedTypeRef, mCurTypeInstance, BfDependencyMap::DependencyFlag_NameReference);
  7785. if (resolvedTypeRef->mDefineState == BfTypeDefineState_Undefined)
  7786. PopulateType(resolvedTypeRef);
  7787. if ((typeInstance->mCustomAttributes != NULL) && (!typeRef->IsTemporary()))
  7788. CheckErrorAttributes(typeInstance, NULL, typeInstance->mCustomAttributes, typeRef);
  7789. resolvedTypeRef = resolvedTypeRef->GetUnderlyingType();
  7790. if (resolvedTypeRef != NULL)
  7791. typeInstance = resolvedTypeRef->ToTypeInstance();
  7792. else
  7793. typeInstance = NULL;
  7794. }
  7795. }
  7796. if (typeInstance != NULL)
  7797. {
  7798. if ((!typeRef->IsTemporary()) && ((resolveFlags & BfResolveTypeRefFlag_FromIndirectSource) == 0))
  7799. {
  7800. if (typeInstance->mCustomAttributes != NULL)
  7801. CheckErrorAttributes(typeInstance, NULL, typeInstance->mCustomAttributes, typeRef);
  7802. else if ((typeInstance->mTypeDef->mTypeDeclaration != NULL) && (typeInstance->mTypeDef->mTypeDeclaration->mAttributes != NULL))
  7803. {
  7804. auto typeRefVerifyRequest = mContext->mTypeRefVerifyWorkList.Alloc();
  7805. typeRefVerifyRequest->mCurTypeInstance = mCurTypeInstance;
  7806. typeRefVerifyRequest->mRefNode = typeRef;
  7807. typeRefVerifyRequest->mType = typeInstance;
  7808. typeRefVerifyRequest->mFromModule = this;
  7809. typeRefVerifyRequest->mFromModuleRevision = mRevision;
  7810. }
  7811. }
  7812. if (typeInstance->IsTuple())
  7813. {
  7814. //TODO: This can cause circular reference issues. Is there a case this is needed?
  7815. //if (typeInstance->mDefineState < BfTypeDefineState_Defined)
  7816. // PopulateType(typeInstance);
  7817. if (typeInstance->mHasDeclError)
  7818. {
  7819. if (auto tupleTypeRef = BfNodeDynCast<BfTupleTypeRef>(typeRef))
  7820. {
  7821. HashSet<String> names;
  7822. for (auto nameIdentifier : tupleTypeRef->mFieldNames)
  7823. {
  7824. if (nameIdentifier == NULL)
  7825. continue;
  7826. StringT<64> fieldName;
  7827. nameIdentifier->ToString(fieldName);
  7828. if (!names.Add(fieldName))
  7829. {
  7830. Fail(StrFormat("A field named '%s' has already been declared", fieldName.c_str()), nameIdentifier);
  7831. }
  7832. }
  7833. }
  7834. }
  7835. }
  7836. }
  7837. return resolvedTypeRef;
  7838. }
  7839. void BfModule::ShowAmbiguousTypeError(BfAstNode* refNode, BfTypeDef* typeDef, BfTypeDef* otherTypeDef)
  7840. {
  7841. BfType* type = ResolveTypeDef(typeDef, BfPopulateType_Identity);
  7842. if (type == NULL)
  7843. return;
  7844. BfType* otherType = ResolveTypeDef(otherTypeDef, BfPopulateType_Identity);
  7845. if (otherType == NULL)
  7846. return;
  7847. auto error = Fail(StrFormat("'%s' is an ambiguous reference between '%s' and '%s'",
  7848. refNode->ToString().c_str(), TypeToString(type, BfTypeNameFlags_None).c_str(), TypeToString(otherType, BfTypeNameFlags_None).c_str()), refNode); // CS0104
  7849. if (error != NULL)
  7850. {
  7851. mCompiler->mPassInstance->MoreInfo("See first definition", typeDef->mTypeDeclaration->mNameNode);
  7852. mCompiler->mPassInstance->MoreInfo("See second definition", otherTypeDef->mTypeDeclaration->mNameNode);
  7853. }
  7854. }
  7855. void BfModule::ShowGenericArgCountError(BfAstNode* typeRef, int wantedGenericParams)
  7856. {
  7857. BfGenericInstanceTypeRef* genericTypeInstRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef);
  7858. BfAstNode* lastNode = typeRef;
  7859. int genericArgDiffCount;
  7860. if (genericTypeInstRef != NULL)
  7861. {
  7862. genericArgDiffCount = (int)genericTypeInstRef->mGenericArguments.size() - wantedGenericParams;
  7863. lastNode = genericTypeInstRef->mOpenChevron;
  7864. if (genericTypeInstRef->mCloseChevron != NULL)
  7865. lastNode = genericTypeInstRef->mCloseChevron;
  7866. if (genericTypeInstRef->mGenericArguments.size() > wantedGenericParams)
  7867. {
  7868. lastNode = genericTypeInstRef->mGenericArguments[wantedGenericParams];
  7869. if (genericArgDiffCount == 1)
  7870. Fail("Too many generic parameters, expected one fewer", lastNode);
  7871. else
  7872. Fail(StrFormat("Too many generic parameters, expected %d fewer", genericArgDiffCount), lastNode);
  7873. return;
  7874. }
  7875. }
  7876. else
  7877. genericArgDiffCount = -wantedGenericParams;
  7878. if (wantedGenericParams == 1)
  7879. Fail("Too few generic parameters, expected one more", lastNode);
  7880. else
  7881. Fail(StrFormat("Too few generic parameters, expected %d more", -genericArgDiffCount), lastNode);
  7882. }
  7883. BfTypeDef* BfModule::GetActiveTypeDef(BfTypeInstance* typeInstanceOverride, bool useMixinDecl)
  7884. {
  7885. BfTypeDef* useTypeDef = NULL;
  7886. BfTypeInstance* typeInstance = (typeInstanceOverride != NULL) ? typeInstanceOverride : mCurTypeInstance;
  7887. if ((mContext->mCurTypeState != NULL) && (mContext->mCurTypeState->mForceActiveTypeDef != NULL))
  7888. return mContext->mCurTypeState->mForceActiveTypeDef;
  7889. if (typeInstance != NULL)
  7890. useTypeDef = typeInstance->mTypeDef->GetDefinition();
  7891. if ((mCurMethodState != NULL) && (mCurMethodState->mMixinState != NULL) && (useMixinDecl))
  7892. useTypeDef = mCurMethodState->mMixinState->mMixinMethodInstance->mMethodDef->mDeclaringType->GetDefinition();
  7893. else if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mMethodDef->mDeclaringType != NULL))
  7894. useTypeDef = mCurMethodInstance->mMethodDef->mDeclaringType->GetDefinition();
  7895. else if (mContext->mCurTypeState != NULL)
  7896. {
  7897. if ((mContext->mCurTypeState->mCurFieldDef != NULL) && (mContext->mCurTypeState->mCurFieldDef->mDeclaringType != NULL))
  7898. useTypeDef = mContext->mCurTypeState->mCurFieldDef->mDeclaringType->GetDefinition();
  7899. else if (mContext->mCurTypeState->mCurTypeDef != NULL)
  7900. useTypeDef = mContext->mCurTypeState->mCurTypeDef->GetDefinition();
  7901. }
  7902. return useTypeDef;
  7903. }
  7904. BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGenericArgs, BfTypeInstance* typeInstance, BfTypeDef* useTypeDef, BfTypeLookupError* error, BfTypeLookupResultCtx* lookupResultCtx, BfResolveTypeRefFlags resolveFlags)
  7905. {
  7906. if ((findName.mSize == 1) && (findName.mParts[0]->mIsSystemType))
  7907. {
  7908. //BP_ZONE("BfModule::FindTypeDefRaw_1");
  7909. return mSystem->FindTypeDef(findName, 0, useTypeDef->mProject);
  7910. }
  7911. BfTypeInstance* skipCheckBaseType = NULL;
  7912. if (mContext->mCurTypeState != NULL)
  7913. {
  7914. if (mContext->mCurTypeState->mCurBaseTypeRef != NULL)
  7915. skipCheckBaseType = mContext->mCurTypeState->mType->ToTypeInstance();
  7916. if (mContext->mCurTypeState->mResolveKind == BfTypeState::ResolveKind_BuildingGenericParams)
  7917. skipCheckBaseType = mContext->mCurTypeState->mType->ToTypeInstance();
  7918. }
  7919. BfTypeDefLookupContext lookupCtx;
  7920. bool allowPrivate = true;
  7921. int curPri = 1000;
  7922. auto checkTypeInst = typeInstance;
  7923. BfTypeDef* protErrorTypeDef = NULL;
  7924. BfTypeInstance* protErrorOuterType = NULL;
  7925. BfTypeDef* foundInnerType = NULL;
  7926. if ((lookupResultCtx != NULL) && (lookupResultCtx->mIsVerify))
  7927. {
  7928. if (lookupResultCtx->mResult->mFoundInnerType)
  7929. return lookupCtx.mBestTypeDef;
  7930. }
  7931. else
  7932. {
  7933. if ((!lookupCtx.HasValidMatch()) && (typeInstance != NULL))
  7934. {
  7935. std::function<bool(BfTypeInstance*)> _CheckType = [&](BfTypeInstance* typeInstance)
  7936. {
  7937. auto checkTypeInst = typeInstance;
  7938. allowPrivate = true;
  7939. while (checkTypeInst != NULL)
  7940. {
  7941. if (!checkTypeInst->mTypeDef->mNestedTypes.IsEmpty())
  7942. {
  7943. if (mSystem->FindTypeDef(findName, numGenericArgs, useTypeDef->mProject, checkTypeInst->mTypeDef->mFullNameEx, allowPrivate, &lookupCtx))
  7944. {
  7945. foundInnerType = lookupCtx.mBestTypeDef;
  7946. if (lookupCtx.HasValidMatch())
  7947. return true;
  7948. if ((lookupCtx.mBestTypeDef->mProtection == BfProtection_Private) && (!allowPrivate))
  7949. {
  7950. protErrorTypeDef = lookupCtx.mBestTypeDef;
  7951. protErrorOuterType = checkTypeInst;
  7952. }
  7953. }
  7954. }
  7955. if (checkTypeInst == skipCheckBaseType)
  7956. break;
  7957. checkTypeInst = GetBaseType(checkTypeInst);
  7958. allowPrivate = false;
  7959. }
  7960. checkTypeInst = typeInstance;
  7961. allowPrivate = true;
  7962. while (checkTypeInst != NULL)
  7963. {
  7964. auto outerTypeInst = GetOuterType(checkTypeInst);
  7965. if (outerTypeInst != NULL)
  7966. {
  7967. if (_CheckType(outerTypeInst))
  7968. return true;
  7969. }
  7970. if (checkTypeInst == skipCheckBaseType)
  7971. break;
  7972. checkTypeInst = GetBaseType(checkTypeInst);
  7973. allowPrivate = false;
  7974. }
  7975. return false;
  7976. };
  7977. _CheckType(typeInstance);
  7978. }
  7979. }
  7980. if (!lookupCtx.HasValidMatch())
  7981. {
  7982. if (mSystem->mTypeDefs.TryGet(findName, NULL))
  7983. mSystem->FindTypeDef(findName, numGenericArgs, useTypeDef->mProject, BfAtomComposite(), allowPrivate, &lookupCtx);
  7984. for (auto& checkNamespace : useTypeDef->mNamespaceSearch)
  7985. {
  7986. BfAtom* atom = findName.mParts[0];
  7987. BfAtom* prevAtom = checkNamespace.mParts[checkNamespace.mSize - 1];
  7988. if (atom->mPrevNamesMap.ContainsKey(prevAtom))
  7989. mSystem->FindTypeDef(findName, numGenericArgs, useTypeDef->mProject, checkNamespace, allowPrivate, &lookupCtx);
  7990. }
  7991. }
  7992. if (!lookupCtx.HasValidMatch())
  7993. {
  7994. auto staticSearch = GetStaticSearch();
  7995. if (staticSearch != NULL)
  7996. {
  7997. for (auto staticTypeInstance : staticSearch->mStaticTypes)
  7998. {
  7999. if (mSystem->FindTypeDef(findName, numGenericArgs, useTypeDef->mProject, staticTypeInstance->mTypeDef->mFullNameEx, false, &lookupCtx))
  8000. {
  8001. if (lookupCtx.HasValidMatch())
  8002. break;
  8003. if (lookupCtx.mBestTypeDef->mProtection < BfProtection_Public)
  8004. {
  8005. protErrorTypeDef = lookupCtx.mBestTypeDef;
  8006. protErrorOuterType = staticTypeInstance;
  8007. }
  8008. }
  8009. }
  8010. }
  8011. }
  8012. if ((!lookupCtx.HasValidMatch()) && (typeInstance == NULL))
  8013. {
  8014. if (useTypeDef->mOuterType != NULL)
  8015. return FindTypeDefRaw(findName, numGenericArgs, typeInstance, useTypeDef->mOuterType, error);
  8016. }
  8017. if ((error != NULL) && (lookupCtx.mAmbiguousTypeDef != NULL))
  8018. {
  8019. if (error->mErrorKind == BfTypeLookupError::BfErrorKind_None)
  8020. error->mErrorKind = BfTypeLookupError::BfErrorKind_Ambiguous;
  8021. error->mAmbiguousTypeDef = lookupCtx.mAmbiguousTypeDef;
  8022. if (error->mRefNode != NULL)
  8023. ShowAmbiguousTypeError(error->mRefNode, lookupCtx.mBestTypeDef, lookupCtx.mAmbiguousTypeDef);
  8024. }
  8025. if ((protErrorTypeDef != NULL) && (lookupCtx.mBestTypeDef == protErrorTypeDef) && (error != NULL) && (error->mRefNode != NULL))
  8026. Fail(StrFormat("'%s.%s' is inaccessible due to its protection level", TypeToString(protErrorOuterType).c_str(), findName.ToString().c_str()), error->mRefNode); // CS0122
  8027. if ((lookupResultCtx != NULL) && (lookupResultCtx->mResult != NULL) && (!lookupResultCtx->mIsVerify) && (foundInnerType != NULL) && (foundInnerType == lookupCtx.mBestTypeDef))
  8028. lookupResultCtx->mResult->mFoundInnerType = true;
  8029. if (((resolveFlags & BfResolveTypeRefFlag_AllowGlobalContainer) == 0) && (lookupCtx.mBestTypeDef != NULL) && (lookupCtx.mBestTypeDef->IsGlobalsContainer()))
  8030. return NULL;
  8031. return lookupCtx.mBestTypeDef;
  8032. }
  8033. BfTypeDef* BfModule::FindTypeDef(const BfAtomComposite& findName, int numGenericArgs, BfTypeInstance* typeInstanceOverride, BfTypeLookupError* error, BfResolveTypeRefFlags resolveFlags)
  8034. {
  8035. BP_ZONE("BfModule::FindTypeDef_1");
  8036. BfTypeInstance* typeInstance = (typeInstanceOverride != NULL) ? typeInstanceOverride : mCurTypeInstance;
  8037. auto useTypeDef = GetActiveTypeDef(typeInstanceOverride, true);
  8038. if ((typeInstance == NULL) && (useTypeDef == NULL))
  8039. {
  8040. BfProject* project = NULL;
  8041. if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mParser != NULL))
  8042. project = mCompiler->mResolvePassData->mParser->mProject;
  8043. BP_ZONE("System.FindTypeDef_2");
  8044. Array<BfAtomComposite> namespaceSearch;
  8045. if (mContext->mCurNamespaceNodes != NULL)
  8046. {
  8047. String checkNamespace;
  8048. for (auto namespaceNode : *mContext->mCurNamespaceNodes)
  8049. {
  8050. if (namespaceNode->mNameNode != NULL)
  8051. {
  8052. if (!checkNamespace.IsEmpty())
  8053. checkNamespace += ".";
  8054. namespaceNode->mNameNode->ToString(checkNamespace);
  8055. }
  8056. }
  8057. if (!checkNamespace.IsEmpty())
  8058. {
  8059. BfAtomComposite atomComposite;
  8060. if (mSystem->ParseAtomComposite(checkNamespace, atomComposite))
  8061. namespaceSearch.Add(atomComposite);
  8062. }
  8063. }
  8064. BfTypeDef* ambiguousTypeDef = NULL;
  8065. BfTypeDef *result = mSystem->FindTypeDef(findName, numGenericArgs, project, namespaceSearch, &ambiguousTypeDef);
  8066. if ((ambiguousTypeDef != NULL) && (error != NULL))
  8067. {
  8068. error->mErrorKind = BfTypeLookupError::BfErrorKind_Ambiguous;
  8069. error->mAmbiguousTypeDef = ambiguousTypeDef;
  8070. if (error->mRefNode != NULL)
  8071. ShowAmbiguousTypeError(error->mRefNode, result, ambiguousTypeDef);
  8072. }
  8073. return result;
  8074. }
  8075. if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL) && (typeInstance != NULL))
  8076. {
  8077. if (mCompiler->mResolvePassData->mAutoCompleteTempTypes.Contains(useTypeDef))
  8078. return FindTypeDefRaw(findName, numGenericArgs, typeInstance, useTypeDef, error, NULL, resolveFlags);
  8079. }
  8080. BfTypeLookupEntry typeLookupEntry;
  8081. typeLookupEntry.mName = findName;
  8082. typeLookupEntry.mNumGenericParams = numGenericArgs;
  8083. typeLookupEntry.mUseTypeDef = useTypeDef;
  8084. BfTypeLookupEntry* typeLookupEntryPtr = NULL;
  8085. BfTypeLookupResult* resultPtr = NULL;
  8086. if ((typeInstance != NULL) && (typeInstance->mLookupResults.TryAdd(typeLookupEntry, &typeLookupEntryPtr, &resultPtr)))
  8087. {
  8088. typeLookupEntryPtr->mAtomUpdateIdx = typeLookupEntry.mName.GetAtomUpdateIdx();
  8089. // FindTypeDefRaw may re-enter when finding base types, so we need to expect that resultPtr can change
  8090. resultPtr->mForceLookup = true;
  8091. resultPtr->mTypeDef = NULL;
  8092. int prevAllocSize = (int)typeInstance->mLookupResults.size();
  8093. BfTypeLookupError localError;
  8094. BfTypeLookupError* errorPtr = (error != NULL) ? error : &localError;
  8095. BfTypeLookupResultCtx lookupResultCtx;
  8096. lookupResultCtx.mResult = resultPtr;
  8097. auto typeDef = FindTypeDefRaw(findName, numGenericArgs, typeInstance, useTypeDef, errorPtr, &lookupResultCtx, resolveFlags);
  8098. if (prevAllocSize != typeInstance->mLookupResults.size())
  8099. {
  8100. bool found = typeInstance->mLookupResults.TryGetValue(typeLookupEntry, &resultPtr);
  8101. BF_ASSERT(found);
  8102. }
  8103. resultPtr->mTypeDef = typeDef;
  8104. resultPtr->mForceLookup = errorPtr->mErrorKind != BfTypeLookupError::BfErrorKind_None;
  8105. return typeDef;
  8106. }
  8107. else
  8108. {
  8109. if ((resultPtr == NULL) || (resultPtr->mForceLookup))
  8110. return FindTypeDefRaw(findName, numGenericArgs, typeInstance, useTypeDef, error, NULL, resolveFlags);
  8111. else
  8112. return resultPtr->mTypeDef;
  8113. }
  8114. }
  8115. BfTypeDef* BfModule::FindTypeDef(const StringImpl& typeName, int numGenericArgs, BfTypeInstance* typeInstanceOverride, BfTypeLookupError* error, BfResolveTypeRefFlags resolveFlags)
  8116. {
  8117. BP_ZONE("BfModule::FindTypeDef_4");
  8118. BfSizedAtomComposite findName;
  8119. if (!mSystem->ParseAtomComposite(typeName, findName))
  8120. return NULL;
  8121. auto result = FindTypeDef(findName, numGenericArgs, typeInstanceOverride, error, resolveFlags);
  8122. // Don't allow just finding extensions here. This can happen in some 'using static' cases but generally shouldn't happen
  8123. if ((result != NULL) && (result->mTypeCode == BfTypeCode_Extension))
  8124. return NULL;
  8125. return result;
  8126. }
  8127. BfTypeDef* BfModule::FindTypeDef(BfTypeReference* typeRef, BfTypeInstance* typeInstanceOverride, BfTypeLookupError* error, int numGenericParams, BfResolveTypeRefFlags resolveFlags)
  8128. {
  8129. BP_ZONE("BfModule::FindTypeDef_5");
  8130. if (auto typeDefTypeRef = BfNodeDynCast<BfDirectTypeDefReference>(typeRef))
  8131. {
  8132. if (typeDefTypeRef->mTypeDef != NULL)
  8133. return mSystem->FilterDeletedTypeDef(typeDefTypeRef->mTypeDef);
  8134. }
  8135. //TODO: When does this get called?
  8136. if (auto elementedType = BfNodeDynCast<BfElementedTypeRef>(typeRef))
  8137. return FindTypeDef(elementedType->mElementType, typeInstanceOverride, error);
  8138. BF_ASSERT(typeRef->IsA<BfNamedTypeReference>() || typeRef->IsA<BfQualifiedTypeReference>() || typeRef->IsA<BfDirectStrTypeReference>());
  8139. auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(typeRef);
  8140. StringView findNameStr;
  8141. if (namedTypeRef != NULL)
  8142. findNameStr = namedTypeRef->mNameNode->ToStringView();
  8143. else
  8144. {
  8145. auto directStrTypeDef = BfNodeDynCastExact<BfDirectStrTypeReference>(typeRef);
  8146. if (directStrTypeDef != NULL)
  8147. findNameStr = directStrTypeDef->mTypeName;
  8148. else
  8149. BFMODULE_FATAL(this, "Error?");
  8150. }
  8151. if (findNameStr.mLength == 6)
  8152. {
  8153. if (findNameStr == "object")
  8154. {
  8155. findNameStr = "System.Object";
  8156. Fail("'object' alias not supported, use 'Object'", typeRef);
  8157. }
  8158. else if (findNameStr == "string")
  8159. {
  8160. findNameStr = "System.String";
  8161. Fail("'string' alias not supported, use 'String'", typeRef);
  8162. }
  8163. }
  8164. BfSizedAtomComposite findName;
  8165. if ((resolveFlags & BfResolveTypeRefFlag_Attribute) != 0)
  8166. {
  8167. String attributeName;
  8168. attributeName += findNameStr;
  8169. attributeName += "Attribute";
  8170. if (!mSystem->ParseAtomComposite(attributeName, findName))
  8171. return NULL;
  8172. }
  8173. else
  8174. {
  8175. if (!mSystem->ParseAtomComposite(findNameStr, findName))
  8176. return NULL;
  8177. }
  8178. #ifdef BF_AST_HAS_PARENT_MEMBER
  8179. if (auto parentGenericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef->mParent))
  8180. {
  8181. if (parentGenericTypeRef->mElementType == typeRef)
  8182. BF_ASSERT(numGenericParams == parentGenericTypeRef->GetGenericArgCount());
  8183. }
  8184. #endif
  8185. auto typeDef = FindTypeDef(findName, numGenericParams, typeInstanceOverride, error, resolveFlags);
  8186. //TYPEDEF if (namedTypeRef != NULL)
  8187. // namedTypeRef->mTypeDef = typeDef;
  8188. return typeDef;
  8189. }
  8190. void BfModule::CheckTypeRefFixit(BfAstNode* typeRef, const char* appendName)
  8191. {
  8192. if ((mCompiler->IsAutocomplete()) && (mCompiler->mResolvePassData->mAutoComplete->CheckFixit((typeRef))))
  8193. {
  8194. String typeName = typeRef->ToString();
  8195. if (appendName != NULL)
  8196. typeName += appendName;
  8197. std::set<String> fixitNamespaces;
  8198. //TODO: Do proper value for numGenericArgs
  8199. mSystem->FindFixitNamespaces(typeName, -1, mCompiler->mResolvePassData->mParser->mProject, fixitNamespaces);
  8200. int insertLoc = 0;
  8201. BfUsingFinder usingFinder;
  8202. usingFinder.VisitMembers(typeRef->GetSourceData()->mRootNode);
  8203. for (auto& namespaceStr : fixitNamespaces)
  8204. {
  8205. BfParserData* parser = typeRef->GetSourceData()->ToParserData();
  8206. if (parser != NULL)
  8207. mCompiler->mResolvePassData->mAutoComplete->AddEntry(AutoCompleteEntry("fixit", StrFormat("using %s;\t.using|%s|%d||using %s;", namespaceStr.c_str(), parser->mFileName.c_str(), usingFinder.mLastIdx, namespaceStr.c_str()).c_str()));
  8208. }
  8209. }
  8210. }
  8211. void BfModule::CheckIdentifierFixit(BfAstNode* node)
  8212. {
  8213. //TODO: Check globals, possibly spelling mistakes?
  8214. }
  8215. void BfModule::TypeRefNotFound(BfTypeReference* typeRef, const char* appendName)
  8216. {
  8217. if (typeRef->IsTemporary())
  8218. return;
  8219. if (PreFail())
  8220. Fail("Type could not be found (are you missing a using directive or library reference?)", typeRef);
  8221. if (!mIgnoreErrors)
  8222. {
  8223. while (auto elementedType = BfNodeDynCast<BfElementedTypeRef>(typeRef))
  8224. typeRef = elementedType->mElementType;
  8225. if (auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(typeRef))
  8226. {
  8227. String findNameStr = namedTypeRef->mNameNode->ToString();
  8228. if (appendName != NULL)
  8229. findNameStr += appendName;
  8230. BfSizedAtomComposite findName;
  8231. if ((!mSystem->ParseAtomComposite(findNameStr, findName)) && (mCurTypeInstance != NULL))
  8232. {
  8233. //BfTypeInstance* typeInstance = (typeInstanceOverride != NULL) ? typeInstanceOverride : mCurTypeInstance;
  8234. // We don't need a typeInstanceOverride because that is used to lookup references
  8235. // from mixins, but it's the type using the mixin (mCurTypeInstance) that needs
  8236. // rebuilding if the lookup fails
  8237. BfTypeInstance* typeInstance = mCurTypeInstance;
  8238. BfTypeLookupEntry typeLookupEntry;
  8239. typeLookupEntry.mNumGenericParams = 0;
  8240. typeLookupEntry.mAtomUpdateIdx = mSystem->mAtomUpdateIdx;
  8241. typeInstance->mLookupResults.TryAdd(typeLookupEntry, BfTypeLookupResult());
  8242. }
  8243. }
  8244. }
  8245. CheckTypeRefFixit(typeRef, appendName);
  8246. }
  8247. bool BfModule::ValidateTypeWildcard(BfAstNode* typeRef, bool isAttributeRef)
  8248. {
  8249. if (typeRef == NULL)
  8250. return false;
  8251. if (auto wildcardTypeRef = BfNodeDynCast<BfWildcardTypeReference>(typeRef))
  8252. return true;
  8253. StringT<128> nameStr;
  8254. typeRef->ToString(nameStr);
  8255. if (isAttributeRef)
  8256. nameStr.Append("Attribute");
  8257. auto typeDef = mSystem->FindTypeDef(nameStr, (BfProject*)NULL);
  8258. if ((typeDef != NULL) && (typeDef->mGenericParamDefs.IsEmpty()))
  8259. return true;
  8260. if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(typeRef))
  8261. {
  8262. if (qualifiedTypeRef->mLeft == NULL)
  8263. return false;
  8264. StringT<128> leftNameStr;
  8265. BfType* leftType = NULL;
  8266. BfAtomComposite leftComposite;
  8267. qualifiedTypeRef->mLeft->ToString(leftNameStr);
  8268. if (!mSystem->ParseAtomComposite(leftNameStr, leftComposite))
  8269. return false;
  8270. if (auto wildcardTypeRef = BfNodeDynCast<BfWildcardTypeReference>(qualifiedTypeRef->mRight))
  8271. {
  8272. if (mSystem->ContainsNamespace(leftComposite, NULL))
  8273. return true;
  8274. return ValidateTypeWildcard(qualifiedTypeRef->mLeft, false);
  8275. }
  8276. }
  8277. if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef))
  8278. {
  8279. StringT<128> nameStr;
  8280. genericTypeRef->mElementType->ToString(nameStr);
  8281. auto typeDef = mSystem->FindTypeDef(nameStr, (int)genericTypeRef->mGenericArguments.size(), NULL);
  8282. if (typeDef == NULL)
  8283. return false;
  8284. if (typeDef->mGenericParamDefs.size() != genericTypeRef->GetGenericArgCount())
  8285. return false;
  8286. for (auto genericArgTypeRef : genericTypeRef->mGenericArguments)
  8287. {
  8288. if ((genericTypeRef != NULL) && (!ValidateTypeWildcard(genericArgTypeRef, false)))
  8289. return false;
  8290. }
  8291. return true;
  8292. }
  8293. if (auto elementedTypeRef = BfNodeDynCast<BfElementedTypeRef>(typeRef))
  8294. {
  8295. return ValidateTypeWildcard(elementedTypeRef->mElementType, false);
  8296. }
  8297. return false;
  8298. }
  8299. //int sResolveTypeRefIdx = 0;
  8300. BfTypedValue BfModule::TryLookupGenericConstVaue(BfIdentifierNode* identifierNode, BfType* expectingType)
  8301. {
  8302. BfTypeInstance* contextTypeInstance = mCurTypeInstance;
  8303. BfMethodInstance* contextMethodInstance = mCurMethodInstance;
  8304. if ((mCurMethodState != NULL) && (mCurMethodState->mMixinState != NULL))
  8305. {
  8306. contextTypeInstance = mCurMethodState->mMixinState->mMixinMethodInstance->GetOwner();
  8307. contextMethodInstance = mCurMethodState->mMixinState->mMixinMethodInstance;
  8308. }
  8309. BfTypeDef* curTypeDef = NULL;
  8310. if (contextTypeInstance != NULL)
  8311. {
  8312. curTypeDef = contextTypeInstance->mTypeDef;
  8313. StringT<128> findName;
  8314. identifierNode->ToString(findName);
  8315. auto genericCheckTypeInstance = contextTypeInstance;
  8316. if (contextTypeInstance->IsBoxed())
  8317. genericCheckTypeInstance = contextTypeInstance->GetUnderlyingType()->ToTypeInstance();
  8318. bool doUndefVal = false;
  8319. if (genericCheckTypeInstance->IsUnspecializedTypeVariation())
  8320. {
  8321. genericCheckTypeInstance = GetUnspecializedTypeInstance(genericCheckTypeInstance);
  8322. doUndefVal = true;
  8323. }
  8324. BfGenericParamDef* genericParamDef = NULL;
  8325. BfGenericParamDef* origGenericParamDef = NULL;
  8326. BfType* genericParamResult = NULL;
  8327. BfType* genericTypeConstraint = NULL;
  8328. bool disallowConstExprValue = false;
  8329. if ((genericCheckTypeInstance != NULL) && (genericCheckTypeInstance->IsGenericTypeInstance()))
  8330. {
  8331. auto genericTypeInst = (BfTypeInstance*)genericCheckTypeInstance;
  8332. auto* genericParams = &curTypeDef->mGenericParamDefs;
  8333. auto* origGenericParams = &curTypeDef->mGenericParamDefs;
  8334. if (genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo != NULL)
  8335. {
  8336. auto activeTypeDef = GetActiveTypeDef(NULL, true);
  8337. genericParams = &activeTypeDef->mGenericParamDefs;
  8338. }
  8339. for (int genericParamIdx = (int)genericParams->size() - 1; genericParamIdx >= 0; genericParamIdx--)
  8340. {
  8341. auto checkGenericParamDef = (*genericParams)[genericParamIdx];
  8342. String genericName = checkGenericParamDef->mName;
  8343. if (genericName == findName)
  8344. {
  8345. genericParamDef = checkGenericParamDef;
  8346. origGenericParamDef = (*origGenericParams)[genericParamIdx];
  8347. genericParamResult = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[genericParamIdx];
  8348. genericTypeConstraint = genericTypeInst->mGenericTypeInfo->mGenericParams[genericParamIdx]->mTypeConstraint;
  8349. if (contextTypeInstance != genericCheckTypeInstance)
  8350. {
  8351. // Don't allow an 'unspecialized variation' generic param
  8352. auto checkResult = contextTypeInstance->mGenericTypeInfo->mTypeGenericArguments[genericParamIdx];
  8353. if (!checkResult->IsGenericParam())
  8354. genericParamResult = checkResult;
  8355. }
  8356. HandleTypeGenericParamRef(identifierNode, genericTypeInst->mTypeDef, genericParamIdx);
  8357. }
  8358. }
  8359. }
  8360. if ((contextMethodInstance != NULL) && (genericParamResult == NULL))
  8361. {
  8362. auto checkMethodInstance = contextMethodInstance;
  8363. if (checkMethodInstance->mIsUnspecializedVariation)
  8364. checkMethodInstance = GetUnspecializedMethodInstance(checkMethodInstance);
  8365. for (int genericParamIdx = (int)checkMethodInstance->mMethodDef->mGenericParams.size() - 1; genericParamIdx >= 0; genericParamIdx--)
  8366. {
  8367. auto checkGenericParamDef = checkMethodInstance->mMethodDef->mGenericParams[genericParamIdx];
  8368. String genericName = checkGenericParamDef->mName;
  8369. if (genericName == findName)
  8370. {
  8371. genericParamDef = checkGenericParamDef;
  8372. origGenericParamDef = checkGenericParamDef;
  8373. genericParamResult = checkMethodInstance->mMethodInfoEx->mMethodGenericArguments[genericParamIdx];
  8374. genericTypeConstraint = checkMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx]->mTypeConstraint;
  8375. if (contextMethodInstance != checkMethodInstance)
  8376. {
  8377. // Don't allow an 'unspecialized variation' generic param
  8378. auto checkResult = contextMethodInstance->mMethodInfoEx->mMethodGenericArguments[genericParamIdx];
  8379. if (!checkResult->IsGenericParam())
  8380. genericParamResult = checkResult;
  8381. }
  8382. HandleMethodGenericParamRef(identifierNode, contextMethodInstance->GetOwner()->mTypeDef, checkMethodInstance->mMethodDef, genericParamIdx);
  8383. }
  8384. }
  8385. }
  8386. if (genericParamResult != NULL)
  8387. {
  8388. auto typeRefSource = identifierNode->GetSourceData();
  8389. if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mSourceClassifier != NULL) && (typeRefSource != NULL) && (typeRefSource == mCompiler->mResolvePassData->mParser->mSourceData))
  8390. mCompiler->mResolvePassData->mSourceClassifier->SetElementType(identifierNode, BfSourceElementType_GenericParam);
  8391. if (genericParamResult->IsConstExprValue())
  8392. {
  8393. BfConstExprValueType* constExprValueType = (BfConstExprValueType*)genericParamResult;
  8394. auto constType = genericTypeConstraint;
  8395. if (constType == NULL)
  8396. constType = GetPrimitiveType(BfTypeCode_IntPtr);
  8397. BfExprEvaluator exprEvaluator(this);
  8398. exprEvaluator.mExpectingType = constType;
  8399. exprEvaluator.GetLiteral(identifierNode, constExprValueType->mValue);
  8400. if (exprEvaluator.mResult)
  8401. {
  8402. auto castedVal = CastToValue(identifierNode, exprEvaluator.mResult, constType, (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_SilentFail));
  8403. if (castedVal)
  8404. return BfTypedValue(castedVal, constType);
  8405. }
  8406. return exprEvaluator.mResult;
  8407. }
  8408. else if (genericParamResult->IsGenericParam())
  8409. {
  8410. if ((doUndefVal) && (genericTypeConstraint != NULL))
  8411. {
  8412. return GetDefaultTypedValue(genericTypeConstraint, false, BfDefaultValueKind_Undef);
  8413. }
  8414. if (((genericParamDef->mGenericParamFlags | origGenericParamDef->mGenericParamFlags) & BfGenericParamFlag_Const) != 0)
  8415. {
  8416. BfTypedValue result;
  8417. result.mType = genericParamResult;
  8418. result.mKind = BfTypedValueKind_GenericConstValue;
  8419. return result;
  8420. }
  8421. }
  8422. }
  8423. }
  8424. return BfTypedValue();
  8425. }
  8426. void BfModule::GetDelegateTypeRefAttributes(BfDelegateTypeRef* delegateTypeRef, BfCallingConvention& callingConvention)
  8427. {
  8428. if (delegateTypeRef->mAttributes == NULL)
  8429. return;
  8430. BfCaptureInfo captureInfo;
  8431. auto customAttributes = GetCustomAttributes(delegateTypeRef->mAttributes, (BfAttributeTargets)(BfAttributeTargets_DelegateTypeRef | BfAttributeTargets_FunctionTypeRef), BfGetCustomAttributesFlags_KeepConstsInModule);
  8432. if (customAttributes != NULL)
  8433. {
  8434. auto linkNameAttr = customAttributes->Get(mCompiler->mCallingConventionAttributeTypeDef);
  8435. if (linkNameAttr != NULL)
  8436. {
  8437. if (linkNameAttr->mCtorArgs.size() == 1)
  8438. {
  8439. auto constant = mBfIRBuilder->GetConstant(linkNameAttr->mCtorArgs[0]);
  8440. if (constant != NULL)
  8441. callingConvention = (BfCallingConvention)constant->mInt32;
  8442. }
  8443. }
  8444. }
  8445. }
  8446. BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags, int numGenericArgs)
  8447. {
  8448. BP_ZONE("BfModule::ResolveTypeRef");
  8449. if (typeRef == NULL)
  8450. {
  8451. AssertErrorState();
  8452. return NULL;
  8453. }
  8454. if (resolveFlags & BfResolveTypeRefFlag_AutoComplete)
  8455. {
  8456. resolveFlags = (BfResolveTypeRefFlags)(resolveFlags & ~BfResolveTypeRefFlag_AutoComplete);
  8457. auto autoComplete = mCompiler->GetAutoComplete();
  8458. if (autoComplete != NULL)
  8459. autoComplete->CheckTypeRef(typeRef, false);
  8460. }
  8461. if ((resolveFlags & BfResolveTypeRefFlag_AllowRef) == 0)
  8462. {
  8463. if (auto refTypeRef = BfNodeDynCast<BfRefTypeRef>(typeRef))
  8464. {
  8465. const char* refTypeStr = BfTokenToString(refTypeRef->mRefToken->mToken);
  8466. Fail(StrFormat("Invalid use of '%s'. Only method parameters, return types, and local variables can be declared as %s types", refTypeStr, refTypeStr), refTypeRef->mRefToken);
  8467. return ResolveTypeRef(refTypeRef->mElementType, populateType, resolveFlags, numGenericArgs);
  8468. }
  8469. }
  8470. if (auto directTypeRef = BfNodeDynCastExact<BfDirectTypeReference>(typeRef))
  8471. {
  8472. return directTypeRef->mType;
  8473. }
  8474. if (auto dotType = BfNodeDynCastExact<BfDotTypeReference>(typeRef))
  8475. {
  8476. Fail(StrFormat("Invalid use of '%s'", BfTokenToString(dotType->mDotToken->mToken)), typeRef);
  8477. return NULL;
  8478. }
  8479. if (auto varRefType = BfNodeDynCastExact<BfVarRefTypeReference>(typeRef))
  8480. {
  8481. Fail("Invalid use of 'var ref'. Generally references are generated with a 'var' declaration with 'ref' applied to the initializer", typeRef);
  8482. return NULL;
  8483. }
  8484. if (mNoResolveGenericParams)
  8485. resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_NoResolveGenericParam);
  8486. SetAndRestoreValue<bool> prevNoResolveGenericParams(mNoResolveGenericParams, (resolveFlags & BfResolveTypeRefFlag_NoResolveGenericParam) != 0);
  8487. //
  8488. resolveFlags = (BfResolveTypeRefFlags)(resolveFlags & ~BfResolveTypeRefFlag_NoResolveGenericParam);
  8489. BfTypeInstance* contextTypeInstance = mCurTypeInstance;
  8490. BfMethodInstance* contextMethodInstance = mCurMethodInstance;
  8491. if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mIsForeignMethodDef))
  8492. contextTypeInstance = mCurMethodInstance->mMethodInfoEx->mForeignType;
  8493. if ((mCurMethodState != NULL) && (mCurMethodState->mMixinState != NULL))
  8494. {
  8495. contextTypeInstance = mCurMethodState->mMixinState->mMixinMethodInstance->GetOwner();
  8496. contextMethodInstance = mCurMethodState->mMixinState->mMixinMethodInstance;
  8497. }
  8498. BfTypeDef* curTypeDef = NULL;
  8499. if (contextTypeInstance != NULL)
  8500. {
  8501. curTypeDef = contextTypeInstance->mTypeDef;
  8502. // Check generics first
  8503. auto namedTypeRef = BfNodeDynCastExact<BfNamedTypeReference>(typeRef);
  8504. auto directStrTypeRef = BfNodeDynCastExact<BfDirectStrTypeReference>(typeRef);
  8505. if (((namedTypeRef != NULL) && (namedTypeRef->mNameNode != NULL)) || (directStrTypeRef != NULL))
  8506. {
  8507. StringT<128> findName;
  8508. if (namedTypeRef != NULL)
  8509. namedTypeRef->mNameNode->ToString(findName);
  8510. else
  8511. findName = directStrTypeRef->mTypeName;
  8512. if (findName == "Self")
  8513. {
  8514. BfType* selfType = mCurTypeInstance;
  8515. if (selfType->IsTypeAlias())
  8516. selfType = GetOuterType(selfType);
  8517. if (selfType != NULL)
  8518. {
  8519. if (selfType->IsInterface()) // For interfaces, 'Self' refers to the identity of the implementing type, so we use a placeholder
  8520. return GetPrimitiveType(BfTypeCode_Self);
  8521. else
  8522. resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_FromIndirectSource);
  8523. if (selfType->IsBoxed())
  8524. selfType = selfType->GetUnderlyingType();
  8525. if ((resolveFlags & BfResolveTypeRefFlag_NoResolveGenericParam) != 0)
  8526. {
  8527. if ((selfType->IsSpecializedType()) || (selfType->IsUnspecializedTypeVariation()))
  8528. selfType = ResolveTypeDef(selfType->ToTypeInstance()->mTypeDef, populateType);
  8529. }
  8530. }
  8531. if (selfType != NULL)
  8532. {
  8533. auto selfTypeInst = selfType->ToTypeInstance();
  8534. if ((selfTypeInst != NULL) && (selfTypeInst->mTypeDef->IsGlobalsContainer()) && ((resolveFlags & BfResolveTypeRefFlag_AllowGlobalsSelf) == 0))
  8535. selfType = NULL;
  8536. }
  8537. if (selfType == NULL)
  8538. {
  8539. Fail("'Self' type is not usable here", typeRef);
  8540. }
  8541. return ResolveTypeResult(typeRef, selfType, populateType, resolveFlags);
  8542. }
  8543. else if (findName == "SelfBase")
  8544. {
  8545. BfType* selfType = mCurTypeInstance;
  8546. if (selfType->IsTypeAlias())
  8547. selfType = GetOuterType(selfType);
  8548. if (selfType != NULL)
  8549. {
  8550. resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_FromIndirectSource);
  8551. if (selfType->IsBoxed())
  8552. selfType = selfType->GetUnderlyingType();
  8553. if ((resolveFlags & BfResolveTypeRefFlag_NoResolveGenericParam) != 0)
  8554. {
  8555. if ((selfType->IsSpecializedType()) || (selfType->IsUnspecializedTypeVariation()))
  8556. selfType = ResolveTypeDef(selfType->ToTypeInstance()->mTypeDef, populateType);
  8557. }
  8558. }
  8559. BfType* baseType = NULL;
  8560. if (selfType != NULL)
  8561. {
  8562. if (selfType->IsTypedPrimitive())
  8563. baseType = selfType->GetUnderlyingType();
  8564. else
  8565. {
  8566. auto selfTypeInst = selfType->ToTypeInstance();
  8567. if (selfTypeInst != NULL)
  8568. {
  8569. baseType = selfTypeInst->mBaseType;
  8570. }
  8571. }
  8572. }
  8573. if (baseType == NULL)
  8574. {
  8575. Fail("'SelfBase' type is not usable here", typeRef);
  8576. }
  8577. return ResolveTypeResult(typeRef, baseType, populateType, resolveFlags);
  8578. }
  8579. else if (findName == "SelfOuter")
  8580. {
  8581. BfType* selfType = mCurTypeInstance;
  8582. if (selfType->IsTypeAlias())
  8583. selfType = GetOuterType(selfType);
  8584. if (selfType != NULL)
  8585. {
  8586. resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_FromIndirectSource);
  8587. if (selfType->IsBoxed())
  8588. selfType = selfType->GetUnderlyingType();
  8589. if ((resolveFlags & BfResolveTypeRefFlag_NoResolveGenericParam) != 0)
  8590. {
  8591. if ((selfType->IsSpecializedType()) || (selfType->IsUnspecializedTypeVariation()))
  8592. selfType = ResolveTypeDef(selfType->ToTypeInstance()->mTypeDef, populateType);
  8593. }
  8594. selfType = GetOuterType(selfType->ToTypeInstance());
  8595. }
  8596. if (selfType == NULL)
  8597. Fail("'SelfOuter' type is not usable here", typeRef);
  8598. return ResolveTypeResult(typeRef, selfType, populateType, resolveFlags);
  8599. }
  8600. else if (findName == "ExpectedType")
  8601. {
  8602. Fail("'ExpectedType' is not usable here", typeRef);
  8603. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  8604. }
  8605. auto genericCheckTypeInstance = contextTypeInstance;
  8606. if (contextTypeInstance->IsBoxed())
  8607. genericCheckTypeInstance = contextTypeInstance->GetUnderlyingType()->ToTypeInstance();
  8608. BfGenericParamDef* genericParamDef = NULL;
  8609. BfType* genericParamResult = NULL;
  8610. bool disallowConstExprValue = false;
  8611. if ((contextMethodInstance != NULL) && (genericParamResult == NULL))
  8612. {
  8613. BfMethodInstance* prevMethodInstance = NULL;
  8614. // If we're in a closure then use the outside method generic arguments
  8615. auto checkMethodInstance = contextMethodInstance;
  8616. if ((mCurMethodState != NULL) && (checkMethodInstance->mIsClosure))
  8617. {
  8618. auto checkMethodState = mCurMethodState;
  8619. while (checkMethodState != NULL)
  8620. {
  8621. if ((checkMethodState->mMethodInstance != NULL) && (checkMethodState->mMethodInstance->mIsClosure))
  8622. {
  8623. checkMethodInstance = checkMethodState->mPrevMethodState->mMethodInstance;
  8624. }
  8625. checkMethodState = checkMethodState->mPrevMethodState;
  8626. }
  8627. }
  8628. for (int genericParamIdx = (int)checkMethodInstance->mMethodDef->mGenericParams.size() - 1; genericParamIdx >= 0; genericParamIdx--)
  8629. {
  8630. auto checkGenericParamDef = checkMethodInstance->mMethodDef->mGenericParams[genericParamIdx];
  8631. String genericName = checkGenericParamDef->mName;
  8632. if (genericName == findName)
  8633. {
  8634. genericParamDef = checkGenericParamDef;
  8635. if (((genericParamDef->mGenericParamFlags & BfGenericParamFlag_Const) != 0) &&
  8636. ((resolveFlags & BfResolveTypeRefFlag_AllowGenericMethodParamConstValue) == 0))
  8637. disallowConstExprValue = true;
  8638. HandleMethodGenericParamRef(typeRef, checkMethodInstance->GetOwner()->mTypeDef, checkMethodInstance->mMethodDef, genericParamIdx);
  8639. if ((resolveFlags & BfResolveTypeRefFlag_NoResolveGenericParam) != 0)
  8640. return GetGenericParamType(BfGenericParamKind_Method, genericParamIdx);
  8641. else
  8642. {
  8643. if ((mContext->mCurConstraintState != NULL) && (mContext->mCurConstraintState->mMethodInstance == checkMethodInstance) &&
  8644. (mContext->mCurConstraintState->mMethodGenericArgsOverride != NULL))
  8645. {
  8646. return ResolveTypeResult(typeRef, (*mContext->mCurConstraintState->mMethodGenericArgsOverride)[genericParamIdx], populateType, resolveFlags);
  8647. }
  8648. SetAndRestoreValue<BfGetSymbolReferenceKind> prevSymbolRefKind;
  8649. if (mCompiler->mResolvePassData != NULL) // Don't add these typeRefs, they are indirect
  8650. prevSymbolRefKind.Init(mCompiler->mResolvePassData->mGetSymbolReferenceKind, BfGetSymbolReferenceKind_None);
  8651. genericParamResult = checkMethodInstance->mMethodInfoEx->mMethodGenericArguments[genericParamIdx];
  8652. if ((genericParamResult != NULL) &&
  8653. (genericParamResult->IsConstExprValue()) &&
  8654. ((resolveFlags & BfResolveTypeRefFlag_AllowGenericMethodParamConstValue) == 0))
  8655. disallowConstExprValue = true;
  8656. }
  8657. }
  8658. }
  8659. }
  8660. if ((genericCheckTypeInstance != NULL) && (genericCheckTypeInstance->IsGenericTypeInstance()) && (genericParamResult == NULL))
  8661. {
  8662. auto genericTypeInst = (BfTypeInstance*)genericCheckTypeInstance;
  8663. auto* genericParams = &curTypeDef->mGenericParamDefs;
  8664. if (genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo != NULL)
  8665. {
  8666. auto activeTypeDef = GetActiveTypeDef(NULL, true);
  8667. genericParams = &activeTypeDef->mGenericParamDefs;
  8668. }
  8669. for (int genericParamIdx = (int)genericParams->size() - 1; genericParamIdx >= 0; genericParamIdx--)
  8670. {
  8671. auto checkGenericParamDef = (*genericParams)[genericParamIdx];
  8672. String genericName = checkGenericParamDef->mName;
  8673. if (genericName == findName)
  8674. {
  8675. genericParamDef = checkGenericParamDef;
  8676. if (((genericParamDef->mGenericParamFlags & BfGenericParamFlag_Const) != 0) &&
  8677. ((resolveFlags & BfResolveTypeRefFlag_AllowGenericTypeParamConstValue) == 0))
  8678. disallowConstExprValue = true;
  8679. HandleTypeGenericParamRef(typeRef, curTypeDef, genericParamIdx);
  8680. if ((resolveFlags & BfResolveTypeRefFlag_NoResolveGenericParam) != 0)
  8681. return GetGenericParamType(BfGenericParamKind_Type, genericParamIdx);
  8682. else
  8683. {
  8684. SetAndRestoreValue<BfGetSymbolReferenceKind> prevSymbolRefKind;
  8685. if (mCompiler->mResolvePassData != NULL) // Don't add these typeRefs, they are indirect
  8686. prevSymbolRefKind.Init(mCompiler->mResolvePassData->mGetSymbolReferenceKind, BfGetSymbolReferenceKind_None);
  8687. genericParamResult = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[genericParamIdx];
  8688. if ((genericParamResult != NULL) &&
  8689. (genericParamResult->IsConstExprValue()) &&
  8690. ((resolveFlags & BfResolveTypeRefFlag_AllowGenericTypeParamConstValue) == 0))
  8691. disallowConstExprValue = true;
  8692. }
  8693. }
  8694. }
  8695. }
  8696. if (genericParamResult != NULL)
  8697. {
  8698. if (disallowConstExprValue)
  8699. {
  8700. Fail("Invalid use of constant generic value", typeRef);
  8701. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  8702. }
  8703. if (genericParamResult->IsRef())
  8704. {
  8705. if ((resolveFlags & BfResolveTypeRefFlag_AllowRefGeneric) == 0)
  8706. genericParamResult = genericParamResult->GetUnderlyingType();
  8707. }
  8708. return ResolveTypeResult(typeRef, genericParamResult, populateType, (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_FromIndirectSource));
  8709. }
  8710. }
  8711. }
  8712. BfTypeDef* typeDef = NULL;
  8713. if (typeRef->IsNamedTypeReference())
  8714. {
  8715. BfTypeLookupError error;
  8716. error.mRefNode = typeRef;
  8717. typeDef = FindTypeDef(typeRef, contextTypeInstance, &error, 0, resolveFlags);
  8718. if (auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(typeRef))
  8719. {
  8720. if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(namedTypeRef->mNameNode))
  8721. {
  8722. // This handles the case where we have an "BaseClass.InnerClass", but the name is qualified as "DerivedClass.InnerClass"
  8723. auto leftType = ResolveTypeRef(qualifiedNameNode->mLeft, NULL, BfPopulateType_Identity, (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_NoResolveGenericParam | BfResolveTypeRefFlag_AllowRef));
  8724. if ((leftType != NULL) && (qualifiedNameNode->mRight != NULL))
  8725. {
  8726. // Try searching within inner type
  8727. auto resolvedType = ResolveInnerType(leftType, qualifiedNameNode->mRight, populateType, true);
  8728. if (resolvedType != NULL)
  8729. {
  8730. if (mCurTypeInstance != NULL)
  8731. AddDependency(leftType, mCurTypeInstance, BfDependencyMap::DependencyFlag_NameReference);
  8732. return ResolveTypeResult(typeRef, resolvedType, populateType, resolveFlags);
  8733. }
  8734. }
  8735. }
  8736. }
  8737. if ((typeDef == NULL) && (mCurTypeInstance != NULL))
  8738. {
  8739. // Try searching within inner type
  8740. auto checkOuterType = mCurTypeInstance;
  8741. while (checkOuterType != NULL)
  8742. {
  8743. // We check for mBaseType to not be NULL because we can't inherit from an inner type, so don't even search there
  8744. // Causes reference cycles (bad).
  8745. if ((checkOuterType != mCurTypeInstance) || (checkOuterType->mBaseType != NULL))
  8746. {
  8747. auto resolvedType = ResolveInnerType(checkOuterType, typeRef, populateType, true);
  8748. if (resolvedType != NULL)
  8749. {
  8750. if (mCurTypeInstance != NULL)
  8751. AddDependency(checkOuterType, mCurTypeInstance, BfDependencyMap::DependencyFlag_NameReference);
  8752. return ResolveTypeResult(typeRef, resolvedType, populateType, resolveFlags);
  8753. }
  8754. }
  8755. checkOuterType = GetOuterType(checkOuterType);
  8756. }
  8757. }
  8758. if (typeDef == NULL)
  8759. {
  8760. auto staticSearch = GetStaticSearch();
  8761. if (staticSearch != NULL)
  8762. {
  8763. for (auto staticTypeInst : staticSearch->mStaticTypes)
  8764. {
  8765. auto resolvedType = ResolveInnerType(staticTypeInst, typeRef, populateType, true);
  8766. if (resolvedType != NULL)
  8767. {
  8768. if (mCurTypeInstance != NULL)
  8769. AddDependency(staticTypeInst, mCurTypeInstance, BfDependencyMap::DependencyFlag_NameReference);
  8770. return ResolveTypeResult(typeRef, resolvedType, populateType, resolveFlags);
  8771. }
  8772. }
  8773. }
  8774. }
  8775. if (typeDef == NULL)
  8776. {
  8777. #ifdef BF_AST_HAS_PARENT_MEMBER
  8778. if (auto parentQualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(typeRef->mParent))
  8779. {
  8780. BF_ASSERT(typeRef->mParent == mParentNodeEntry->mNode);
  8781. }
  8782. #endif
  8783. if (mParentNodeEntry != NULL)
  8784. {
  8785. if (auto parentQualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(mParentNodeEntry->mNode))
  8786. {
  8787. if (typeRef == parentQualifiedTypeRef->mLeft)
  8788. {
  8789. if ((resolveFlags & BfResolveTypeRefFlag_IgnoreLookupError) == 0)
  8790. TypeRefNotFound(typeRef);
  8791. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  8792. }
  8793. }
  8794. }
  8795. if ((resolveFlags & BfResolveTypeRefFlag_IgnoreLookupError) == 0)
  8796. {
  8797. TypeRefNotFound(typeRef, ((resolveFlags & Beefy::BfResolveTypeRefFlag_Attribute) != 0) ? "Attribute" : NULL);
  8798. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  8799. }
  8800. return NULL;
  8801. }
  8802. }
  8803. else if (auto typeDefTypeRef = BfNodeDynCastExact<BfDirectTypeDefReference>(typeRef))
  8804. {
  8805. typeDef = typeDefTypeRef->mTypeDef;
  8806. }
  8807. if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(typeRef))
  8808. {
  8809. //TODO: Determine why we had this prevIgnoreErrors set here. It causes things like IEnumerator<Hey.Test<INVALIDNAME>> not fail
  8810. // properly on INVALIDNAME
  8811. SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, /*true*/mIgnoreErrors);
  8812. StringView leftNameStr;
  8813. BfType* leftType = NULL;
  8814. BfSizedAtomComposite leftComposite;
  8815. bool leftIsValid = false;
  8816. //bool leftIsValid = (qualifiedTypeRef->mLeft != NULL) && mSystem->ParseAtomComposite(qualifiedTypeRef->mLeft->ToString(), leftComposite);
  8817. if (qualifiedTypeRef->mLeft != NULL)
  8818. {
  8819. leftNameStr = qualifiedTypeRef->mLeft->ToStringView();
  8820. if (mSystem->ParseAtomComposite(leftNameStr, leftComposite))
  8821. leftIsValid = true;
  8822. }
  8823. if ((leftIsValid) && (qualifiedTypeRef->mRight != NULL))
  8824. {
  8825. StringT<128> findName;
  8826. auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(qualifiedTypeRef->mRight);
  8827. auto activeTypeDef = GetActiveTypeDef();
  8828. BfProject* bfProject = NULL;
  8829. if (activeTypeDef != NULL)
  8830. bfProject = activeTypeDef->mProject;
  8831. if (mSystem->ContainsNamespace(leftComposite, bfProject))
  8832. {
  8833. qualifiedTypeRef->mLeft->ToString(findName);
  8834. findName.Append('.');
  8835. if (genericTypeRef != NULL)
  8836. genericTypeRef->mElementType->ToString(findName);
  8837. else
  8838. qualifiedTypeRef->mRight->ToString(findName);
  8839. }
  8840. else if ((activeTypeDef != NULL) && (activeTypeDef->mNamespace.EndsWith(leftComposite)))
  8841. {
  8842. // Partial namespace reference, extend to a full reference
  8843. findName += activeTypeDef->mNamespace.ToString();
  8844. findName.Append('.');
  8845. qualifiedTypeRef->mRight->ToString(findName);
  8846. }
  8847. if (!findName.IsEmpty())
  8848. {
  8849. int wantNumGenericArgs = 0;
  8850. #ifdef BF_AST_HAS_PARENT_MEMBER
  8851. if (auto genericTypeParent = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef->mParent))
  8852. {
  8853. BF_ASSERT(mParentNodeEntry->mNode == genericTypeParent);
  8854. //wantNumGenericArgs = (int)genericTypeParent->mGenericArguments.size();
  8855. //genericTypeRef = genericTypeParent;
  8856. }
  8857. #endif
  8858. if (mParentNodeEntry != NULL)
  8859. {
  8860. if (auto genericTypeParent = BfNodeDynCast<BfGenericInstanceTypeRef>(mParentNodeEntry->mNode))
  8861. {
  8862. wantNumGenericArgs = (int)genericTypeParent->mGenericArguments.size();
  8863. genericTypeRef = genericTypeParent;
  8864. }
  8865. }
  8866. BfTypeDef* ambiguousTypeDef = NULL;
  8867. //auto typeDef = mSystem->FindTypeDef(findName, wantNumGenericArgs, bfProject, {}, &ambiguousTypeDef);
  8868. //auto typeDef = mSystem->FindTypeDef(findName, wantNumGenericArgs, bfProject, {}, &ambiguousTypeDef);
  8869. BfTypeLookupError lookupError;
  8870. auto typeDef = FindTypeDef(findName, wantNumGenericArgs, NULL, &lookupError);
  8871. if (typeDef != NULL)
  8872. {
  8873. if (ambiguousTypeDef != NULL)
  8874. ShowAmbiguousTypeError(typeRef, typeDef, ambiguousTypeDef);
  8875. BfTypeVector genericArgs;
  8876. if (populateType != BfPopulateType_TypeDef)
  8877. {
  8878. if (genericTypeRef != NULL)
  8879. {
  8880. for (auto genericParamTypeRef : genericTypeRef->mGenericArguments)
  8881. {
  8882. auto genericParam = ResolveTypeRef(genericParamTypeRef, NULL, BfPopulateType_Declaration);
  8883. if (genericParam == NULL)
  8884. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  8885. genericArgs.push_back(genericParam);
  8886. }
  8887. }
  8888. if (typeDef->mGenericParamDefs.size() != genericArgs.size())
  8889. {
  8890. prevIgnoreErrors.Restore();
  8891. BfAstNode* refNode = typeRef;
  8892. if (genericTypeRef != NULL)
  8893. refNode = genericTypeRef->mOpenChevron;
  8894. int wantedGenericParams = (int)typeDef->mGenericParamDefs.size();
  8895. if (wantedGenericParams == 1)
  8896. Fail("Expected one generic argument", refNode);
  8897. else
  8898. Fail(StrFormat("Expected %d generic arguments", wantedGenericParams), refNode);
  8899. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  8900. }
  8901. }
  8902. return ResolveTypeResult(typeRef, ResolveTypeDef(typeDef, genericArgs, populateType), populateType, resolveFlags);
  8903. }
  8904. }
  8905. }
  8906. if (leftType == NULL)
  8907. {
  8908. BfAutoParentNodeEntry autoParentNodeEntry(this, qualifiedTypeRef);
  8909. leftType = ResolveTypeRef(qualifiedTypeRef->mLeft, BfPopulateType_Identity, (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_IgnoreLookupError)); // We throw an error below if we can't find the type
  8910. }
  8911. if (leftType == NULL)
  8912. {
  8913. mIgnoreErrors = prevIgnoreErrors.mPrevVal;
  8914. BfTypeReference* errorRefNode = qualifiedTypeRef->mLeft;
  8915. if ((leftIsValid) && (mCurTypeInstance != NULL) && (mSystem->ContainsNamespace(leftComposite, curTypeDef->mProject)))
  8916. {
  8917. // The left was a namespace name, so throw an error on the whole string
  8918. errorRefNode = qualifiedTypeRef;
  8919. }
  8920. TypeRefNotFound(errorRefNode);
  8921. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  8922. }
  8923. prevIgnoreErrors.Restore();
  8924. if (qualifiedTypeRef->mRight == NULL)
  8925. {
  8926. FailAfter("Expected identifier", qualifiedTypeRef->mDot);
  8927. //AssertErrorState();
  8928. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  8929. }
  8930. if (leftType->IsGenericParam())
  8931. {
  8932. auto genericParam = GetGenericParamInstance((BfGenericParamType*)leftType);
  8933. if ((genericParam->mGenericParamFlags & BfGenericParamFlag_Var) != 0)
  8934. return ResolveTypeResult(typeRef, GetPrimitiveType(BfTypeCode_Var), populateType, resolveFlags);
  8935. if ((genericParam->IsEnum()) && (qualifiedTypeRef->mRight != NULL))
  8936. {
  8937. StringView findNameRight = qualifiedTypeRef->mRight->ToStringView();
  8938. if (findNameRight == "UnderlyingType")
  8939. return ResolveTypeResult(typeRef, GetPrimitiveType(BfTypeCode_Var), populateType, resolveFlags);
  8940. }
  8941. }
  8942. auto resolvedType = ResolveInnerType(leftType, qualifiedTypeRef->mRight, populateType, false, numGenericArgs);
  8943. if ((resolvedType != NULL) && (mCurTypeInstance != NULL))
  8944. AddDependency(leftType, mCurTypeInstance, BfDependencyMap::DependencyFlag_NameReference);
  8945. return ResolveTypeResult(typeRef, resolvedType, populateType, resolveFlags);
  8946. // If we did a ResolveTypeResult, then that may process an alias as the alias-to type instead of the actual alias
  8947. //return ResolveInnerType(leftType, qualifiedTypeRef->mRight, populateType);
  8948. }
  8949. if (auto resolvedTypeRef = BfNodeDynCast<BfResolvedTypeReference>(typeRef))
  8950. {
  8951. return ResolveTypeResult(typeRef, resolvedTypeRef->mType, populateType, resolveFlags);
  8952. }
  8953. if (auto retTypeTypeRef = BfNodeDynCastExact<BfModifiedTypeRef>(typeRef))
  8954. {
  8955. if (retTypeTypeRef->mRetTypeToken->mToken == BfToken_RetType)
  8956. {
  8957. bool allowThrough = false;
  8958. BfType* resolvedType = NULL;
  8959. if (retTypeTypeRef->mElementType != NULL)
  8960. {
  8961. auto innerType = ResolveTypeRef(retTypeTypeRef->mElementType, BfPopulateType_Declaration, BfResolveTypeRefFlag_AllowGenericParamConstValue);
  8962. if (innerType != NULL)
  8963. {
  8964. if ((innerType->IsDelegate()) || (innerType->IsFunction()))
  8965. {
  8966. PopulateType(innerType, BfPopulateType_DataAndMethods);
  8967. BfMethodInstance* invokeMethodInstance = GetRawMethodInstanceAtIdx(innerType->ToTypeInstance(), 0, "Invoke");
  8968. if (invokeMethodInstance != NULL)
  8969. {
  8970. resolvedType = invokeMethodInstance->mReturnType;
  8971. if ((resolvedType != NULL) && (resolvedType->IsRef()))
  8972. resolvedType = resolvedType->GetUnderlyingType();
  8973. return ResolveTypeResult(typeRef, resolvedType, populateType, resolveFlags);
  8974. }
  8975. }
  8976. else if (innerType->IsGenericParam())
  8977. {
  8978. if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsUnspecializedTypeVariation()))
  8979. {
  8980. // We could have case where we have "rettype(@T0)" and @T0 gets a type variation of @M0, but we can't do a
  8981. // GetGenericParamInstance on that
  8982. allowThrough = true;
  8983. }
  8984. else
  8985. {
  8986. auto genericParamInstance = GetGenericParamInstance((BfGenericParamType*)innerType);
  8987. if (genericParamInstance->mTypeConstraint != NULL)
  8988. {
  8989. if ((genericParamInstance->mTypeConstraint->IsDelegate()) || (genericParamInstance->mTypeConstraint->IsFunction()))
  8990. {
  8991. resolvedType = GetDelegateReturnType(genericParamInstance->mTypeConstraint);
  8992. return ResolveTypeResult(typeRef, resolvedType, populateType, resolveFlags);
  8993. }
  8994. else if ((genericParamInstance->mTypeConstraint->IsInstanceOf(mCompiler->mDelegateTypeDef)) ||
  8995. (genericParamInstance->mTypeConstraint->IsInstanceOf(mCompiler->mFunctionTypeDef)))
  8996. {
  8997. allowThrough = true;
  8998. }
  8999. }
  9000. }
  9001. }
  9002. else if (innerType->IsMethodRef())
  9003. {
  9004. auto methodRefType = (BfMethodRefType*)innerType;
  9005. resolvedType = methodRefType->mMethodRef->mReturnType;
  9006. if ((resolvedType != NULL) && (resolvedType->IsRef()))
  9007. resolvedType = resolvedType->GetUnderlyingType();
  9008. return ResolveTypeResult(typeRef, resolvedType, populateType, resolveFlags);
  9009. }
  9010. }
  9011. }
  9012. if (!allowThrough)
  9013. {
  9014. Fail("'rettype' can only be used on delegate or function types", retTypeTypeRef->mRetTypeToken);
  9015. return ResolveTypeResult(typeRef, resolvedType, populateType, resolveFlags);
  9016. }
  9017. }
  9018. else if (retTypeTypeRef->mRetTypeToken->mToken == BfToken_AllocType)
  9019. {
  9020. BfType* resolvedType = NULL;
  9021. if (retTypeTypeRef->mElementType != NULL)
  9022. {
  9023. resolvedType = ResolveTypeRef(retTypeTypeRef->mElementType, BfPopulateType_Declaration, BfResolveTypeRefFlag_AllowGenericParamConstValue);
  9024. if (resolvedType != NULL)
  9025. {
  9026. if (resolvedType->IsGenericParam())
  9027. {
  9028. auto genericParam = GetGenericParamInstance((BfGenericParamType*)resolvedType);
  9029. if (((genericParam->mTypeConstraint != NULL) && (genericParam->mTypeConstraint->IsValueType())) ||
  9030. ((genericParam->mGenericParamFlags & (BfGenericParamFlag_Struct | BfGenericParamFlag_StructPtr | BfGenericParamFlag_Enum)) != 0))
  9031. {
  9032. resolvedType = CreatePointerType(resolvedType);
  9033. }
  9034. else if (((genericParam->mTypeConstraint != NULL) && (!genericParam->mTypeConstraint->IsValueType())) ||
  9035. ((genericParam->mGenericParamFlags & (BfGenericParamFlag_Class)) != 0))
  9036. {
  9037. // Leave as 'T'
  9038. }
  9039. else
  9040. resolvedType = CreateModifiedTypeType(resolvedType, BfToken_AllocType);
  9041. }
  9042. else if (resolvedType->IsValueType())
  9043. resolvedType = CreatePointerType(resolvedType);
  9044. }
  9045. }
  9046. return ResolveTypeResult(typeRef, resolvedType, populateType, resolveFlags);
  9047. }
  9048. else if (retTypeTypeRef->mRetTypeToken->mToken == BfToken_Nullable)
  9049. {
  9050. bool allowThrough = false;
  9051. BfType* resolvedType = NULL;
  9052. if (retTypeTypeRef->mElementType != NULL)
  9053. {
  9054. resolvedType = ResolveTypeRef(retTypeTypeRef->mElementType, BfPopulateType_Declaration, BfResolveTypeRefFlag_AllowGenericParamConstValue);
  9055. }
  9056. if ((resolvedType != NULL) && (resolvedType->IsGenericParam()))
  9057. {
  9058. //resolvedType = CreateModifiedTypeType(resolvedType, BfToken_Nullable);
  9059. BfTypeVector typeVec;
  9060. typeVec.push_back(resolvedType);
  9061. resolvedType = ResolveTypeDef(mCompiler->mNullableTypeDef, typeVec, BfPopulateType_Declaration);
  9062. }
  9063. else if (resolvedType != NULL)
  9064. {
  9065. if (resolvedType->IsValueType())
  9066. {
  9067. if (InDefinitionSection())
  9068. Warn(0, StrFormat("Consider using '%s?' instead of nullable modifier", TypeToString(resolvedType).c_str()), retTypeTypeRef);
  9069. BfTypeVector typeVec;
  9070. typeVec.push_back(resolvedType);
  9071. resolvedType = ResolveTypeDef(mCompiler->mNullableTypeDef, typeVec, BfPopulateType_Declaration);
  9072. }
  9073. else
  9074. {
  9075. if (InDefinitionSection())
  9076. Warn(0, StrFormat("Unneeded nullable modifier, %s is already nullable", TypeToString(resolvedType).c_str()), retTypeTypeRef->mRetTypeToken);
  9077. }
  9078. }
  9079. if (resolvedType != NULL)
  9080. PopulateType(resolvedType, populateType);
  9081. return resolvedType;
  9082. }
  9083. else
  9084. BFMODULE_FATAL(this, "Unhandled");
  9085. }
  9086. if (auto refTypeRef = BfNodeDynCastExact<BfRefTypeRef>(typeRef))
  9087. {
  9088. if ((refTypeRef->mRefToken != NULL) && (refTypeRef->mRefToken->GetToken() == BfToken_Mut) && (refTypeRef->mElementType != NULL))
  9089. {
  9090. bool needsRefWrap = false;
  9091. auto resolvedType = ResolveTypeRef(refTypeRef->mElementType, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowGenericParamConstValue);
  9092. if (resolvedType != NULL)
  9093. {
  9094. if ((resolvedType->IsValueType()) || (resolvedType->IsGenericParam()))
  9095. needsRefWrap = true;
  9096. if ((InDefinitionSection()) && (!resolvedType->IsGenericParam()) && ((resolveFlags & BfResolveTypeRefFlag_NoWarnOnMut) == 0))
  9097. {
  9098. if (!resolvedType->IsValueType())
  9099. Warn(0, StrFormat("Specified 'mut' has no effect on '%s' since reference types are always mutable", TypeToString(resolvedType).c_str()), refTypeRef->mRefToken);
  9100. else
  9101. Warn(0, "Use 'mut' for generic arguments which may or may not be reference types. Consider using 'ref' here, instead.", refTypeRef->mRefToken);
  9102. }
  9103. }
  9104. if (!needsRefWrap)
  9105. {
  9106. // Non-composites (including pointers) don't actually need ref-wrapping for 'mut'
  9107. return ResolveTypeResult(typeRef, resolvedType, populateType, resolveFlags);
  9108. }
  9109. }
  9110. }
  9111. static int sCallIdx = 0;
  9112. int callIdx = sCallIdx++;
  9113. if (callIdx == 0x00006CA4)
  9114. {
  9115. NOP;
  9116. }
  9117. BfResolvedTypeSet::LookupContext lookupCtx;
  9118. lookupCtx.mResolveFlags = (BfResolveTypeRefFlags)(resolveFlags & (BfResolveTypeRefFlag_NoCreate | BfResolveTypeRefFlag_IgnoreLookupError |
  9119. BfResolveTypeRefFlag_DisallowComptime | BfResolveTypeRefFlag_AllowInferredSizedArray | BfResolveTypeRefFlag_Attribute));
  9120. lookupCtx.mRootTypeRef = typeRef;
  9121. lookupCtx.mRootTypeDef = typeDef;
  9122. lookupCtx.mModule = this;
  9123. BfResolvedTypeSet::Entry* resolvedEntry = NULL;
  9124. if (auto delegateTypeRef = BfNodeDynCastExact<BfDelegateTypeRef>(typeRef))
  9125. GetDelegateTypeRefAttributes(delegateTypeRef, lookupCtx.mCallingConvention);
  9126. auto inserted = mContext->mResolvedTypes.Insert(typeRef, &lookupCtx, &resolvedEntry);
  9127. if (resolvedEntry == NULL)
  9128. {
  9129. if (lookupCtx.mHadVar)
  9130. return ResolveTypeResult(typeRef, GetPrimitiveType(BfTypeCode_Var), populateType, resolveFlags);
  9131. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  9132. }
  9133. if (!inserted)
  9134. {
  9135. BF_ASSERT(resolvedEntry->mValue != NULL);
  9136. BF_ASSERT(!resolvedEntry->mValue->IsDeleting());
  9137. return ResolveTypeResult(typeRef, resolvedEntry->mValue, populateType, resolveFlags);
  9138. }
  9139. if ((resolveFlags & BfResolveTypeRefFlag_NoCreate) != 0)
  9140. {
  9141. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  9142. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  9143. }
  9144. BfModule* populateModule = this;
  9145. if ((resolveFlags & BfResolveTypeRefFlag_NoReify) != 0)
  9146. populateModule = mContext->mUnreifiedModule;
  9147. if (typeRef->IsTypeDefTypeReference())
  9148. {
  9149. //BF_ASSERT(typeDefTypeRef->mTypeDef != NULL); // Resolved higher up
  9150. //auto typeDef = typeDefTypeRef->mTypeDef;
  9151. if ((typeDef->mTypeCode >= BfTypeCode_None) && (typeDef->mTypeCode <= BfTypeCode_Double))
  9152. {
  9153. BfPrimitiveType* primType = new BfPrimitiveType();
  9154. primType->mTypeDef = typeDef;
  9155. resolvedEntry->mValue = primType;
  9156. BF_ASSERT(BfResolvedTypeSet::Hash(primType, &lookupCtx, false) == resolvedEntry->mHash);
  9157. populateModule->InitType(primType, populateType);
  9158. return ResolveTypeResult(typeRef, primType, populateType, resolveFlags);
  9159. }
  9160. BfTypeInstance* outerTypeInstance = lookupCtx.mRootOuterTypeInstance;
  9161. if (outerTypeInstance == NULL)
  9162. outerTypeInstance = mCurTypeInstance;
  9163. if ((outerTypeInstance != NULL) && (typeDef->mGenericParamDefs.size() != 0))
  9164. {
  9165. // Try to inherit generic params from current parent
  9166. BfTypeDef* outerType = mSystem->GetCombinedPartial(typeDef->mOuterType);
  9167. BF_ASSERT(!outerType->mIsPartial);
  9168. if (TypeHasParentOrEquals(outerTypeInstance->mTypeDef, outerType))
  9169. {
  9170. BfType* checkCurType = outerTypeInstance;
  9171. if (checkCurType->IsBoxed())
  9172. checkCurType = checkCurType->GetUnderlyingType();
  9173. if (checkCurType->IsTypeAlias())
  9174. checkCurType = GetOuterType(checkCurType);
  9175. BF_ASSERT(checkCurType->IsGenericTypeInstance());
  9176. int numParentGenericParams = (int)outerType->mGenericParamDefs.size();
  9177. int wantedGenericParams = (int)typeDef->mGenericParamDefs.size() - numParentGenericParams;
  9178. if (wantedGenericParams != 0)
  9179. {
  9180. if (wantedGenericParams == 1)
  9181. Fail("Expected generic argument", typeRef);
  9182. else
  9183. Fail(StrFormat("Expected %d generic arguments", wantedGenericParams), typeRef);
  9184. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  9185. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  9186. }
  9187. auto parentGenericTypeInstance = (BfTypeInstance*)checkCurType;
  9188. BfTypeInstance* genericTypeInst;
  9189. if (typeDef->mTypeCode == BfTypeCode_TypeAlias)
  9190. {
  9191. auto typeAliasType = new BfTypeAliasType();
  9192. genericTypeInst = typeAliasType;
  9193. }
  9194. else
  9195. genericTypeInst = new BfTypeInstance();
  9196. genericTypeInst->mGenericTypeInfo = new BfGenericTypeInfo();
  9197. genericTypeInst->mTypeDef = typeDef;
  9198. if (parentGenericTypeInstance->mGenericTypeInfo->mGenericParams.IsEmpty())
  9199. PopulateType(parentGenericTypeInstance, BfPopulateType_Declaration);
  9200. for (int i = 0; i < numParentGenericParams; i++)
  9201. {
  9202. genericTypeInst->mGenericTypeInfo->mGenericParams.push_back(parentGenericTypeInstance->mGenericTypeInfo->mGenericParams[i]->AddRef());
  9203. genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.push_back(parentGenericTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i]);
  9204. }
  9205. CheckUnspecializedGenericType(genericTypeInst, populateType);
  9206. resolvedEntry->mValue = genericTypeInst;
  9207. populateModule->InitType(genericTypeInst, populateType);
  9208. #ifdef _DEBUG
  9209. if (BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) != resolvedEntry->mHash)
  9210. {
  9211. int refHash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx);
  9212. int typeHash = BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx);
  9213. BF_ASSERT(refHash == typeHash);
  9214. }
  9215. #endif
  9216. return ResolveTypeResult(typeRef, genericTypeInst, populateType, resolveFlags);
  9217. }
  9218. }
  9219. BfTypeInstance* typeInst;
  9220. if (typeDef->mTypeCode == BfTypeCode_TypeAlias)
  9221. {
  9222. auto typeAliasType = new BfTypeAliasType();
  9223. typeInst = typeAliasType;
  9224. }
  9225. else
  9226. {
  9227. typeInst = new BfTypeInstance();
  9228. }
  9229. typeInst->mTypeDef = typeDef;
  9230. if (((resolveFlags & BfResolveTypeRefFlag_NoReify) != 0) && (mCompiler->mOptions.mCompileOnDemandKind != BfCompileOnDemandKind_AlwaysInclude))
  9231. {
  9232. typeInst->mIsReified = false;
  9233. }
  9234. if (typeInst->mTypeDef->mGenericParamDefs.size() != 0)
  9235. {
  9236. Fail("Generic type arguments expected", typeRef);
  9237. delete typeInst;
  9238. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  9239. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  9240. }
  9241. resolvedEntry->mValue = typeInst;
  9242. #ifdef _DEBUG
  9243. int typeRefash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx);
  9244. #endif
  9245. populateModule->InitType(typeInst, populateType);
  9246. if (BfResolvedTypeSet::Hash(typeInst, &lookupCtx) != resolvedEntry->mHash)
  9247. {
  9248. int refHash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx);
  9249. int typeHash = BfResolvedTypeSet::Hash(typeInst, &lookupCtx);
  9250. BF_ASSERT(refHash == typeHash);
  9251. }
  9252. {
  9253. BF_ASSERT(BfResolvedTypeSet::Hash(typeInst, &lookupCtx) == resolvedEntry->mHash);
  9254. }
  9255. return ResolveTypeResult(typeRef, typeInst, populateType, resolveFlags);
  9256. }
  9257. else if (auto arrayTypeRef = BfNodeDynCast<BfArrayTypeRef>(typeRef))
  9258. {
  9259. if (arrayTypeRef->mDimensions > 4)
  9260. {
  9261. Fail("Too many array dimensions, consider using a jagged array.", arrayTypeRef);
  9262. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  9263. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  9264. }
  9265. auto elementType = ResolveTypeRef(arrayTypeRef->mElementType, BfPopulateType_Declaration, BfResolveTypeRefFlag_AllowGenericParamConstValue);
  9266. auto arrayTypeDef = mCompiler->GetArrayTypeDef(arrayTypeRef->mDimensions);
  9267. if ((elementType == NULL) || (arrayTypeDef == NULL))
  9268. {
  9269. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  9270. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  9271. }
  9272. if ((arrayTypeRef->mDimensions == 1) && (arrayTypeRef->mParams.size() == 1))
  9273. {
  9274. intptr elementCount = -1;
  9275. BfExpression* sizeExpr = BfNodeDynCast<BfExpression>(arrayTypeRef->mParams[0]);
  9276. BF_ASSERT(sizeExpr != NULL);
  9277. if (sizeExpr != NULL)
  9278. {
  9279. BfConstResolver constResolver(this);
  9280. BfType* intType = GetPrimitiveType(BfTypeCode_IntPtr);
  9281. constResolver.mExpectingType = intType;
  9282. constResolver.mAllowGenericConstValue = true;
  9283. BfTypedValue typedVal;
  9284. {
  9285. SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, true);
  9286. typedVal = constResolver.Resolve(sizeExpr, NULL, BfConstResolveFlag_ArrayInitSize);
  9287. }
  9288. if (typedVal.mKind == BfTypedValueKind_GenericConstValue)
  9289. {
  9290. BfUnknownSizedArrayType* arrayType = new BfUnknownSizedArrayType();
  9291. arrayType->mContext = mContext;
  9292. arrayType->mElementType = elementType;
  9293. arrayType->mElementCount = -1;
  9294. arrayType->mElementCountSource = typedVal.mType;
  9295. resolvedEntry->mValue = arrayType;
  9296. BF_ASSERT(BfResolvedTypeSet::Hash(arrayType, &lookupCtx) == resolvedEntry->mHash);
  9297. populateModule->InitType(arrayType, populateType);
  9298. return ResolveTypeResult(typeRef, arrayType, populateType, resolveFlags);
  9299. }
  9300. if (typedVal)
  9301. typedVal = Cast(sizeExpr, typedVal, intType);
  9302. if (typedVal)
  9303. {
  9304. auto constant = mBfIRBuilder->GetConstant(typedVal.mValue);
  9305. if (constant != NULL)
  9306. {
  9307. if (constant->mConstType == BfConstType_Undef)
  9308. elementCount = -1; // Undef marker
  9309. else if (BfIRBuilder::IsInt(constant->mTypeCode))
  9310. elementCount = (intptr)constant->mInt64;
  9311. }
  9312. }
  9313. }
  9314. /*if (elementCount < 0)
  9315. {
  9316. Fail(StrFormat("Array length '%d' is illegal", elementCount), arrayTypeRef->mParams[0]);
  9317. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  9318. return CreateSizedArrayType(elementType, 0);
  9319. }*/
  9320. BfSizedArrayType* arrayType = new BfSizedArrayType();
  9321. arrayType->mContext = mContext;
  9322. arrayType->mElementType = elementType;
  9323. arrayType->mElementCount = elementCount;
  9324. arrayType->mWantsGCMarking = false; // Fill in in InitType
  9325. arrayType->mGenericDepth = elementType->GetGenericDepth() + 1;
  9326. resolvedEntry->mValue = arrayType;
  9327. BF_ASSERT(BfResolvedTypeSet::Hash(arrayType, &lookupCtx) == resolvedEntry->mHash);
  9328. populateModule->InitType(arrayType, populateType);
  9329. return ResolveTypeResult(typeRef, arrayType, populateType, resolveFlags);
  9330. }
  9331. BfArrayType* arrayType = new BfArrayType();
  9332. arrayType->mGenericTypeInfo = new BfGenericTypeInfo();
  9333. arrayType->mContext = mContext;
  9334. arrayType->mDimensions = arrayTypeRef->mDimensions;
  9335. arrayType->mTypeDef = arrayTypeDef;
  9336. arrayType->mGenericTypeInfo->mTypeGenericArguments.push_back(elementType);
  9337. resolvedEntry->mValue = arrayType;
  9338. CheckUnspecializedGenericType(arrayType, populateType);
  9339. BF_ASSERT(BfResolvedTypeSet::Hash(arrayType, &lookupCtx) == resolvedEntry->mHash);
  9340. populateModule->InitType(arrayType, populateType);
  9341. return ResolveTypeResult(typeRef, arrayType, populateType, resolveFlags);
  9342. }
  9343. else if (auto genericTypeInstRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef))
  9344. {
  9345. int wantNumGenericParams = genericTypeInstRef->GetGenericArgCount();
  9346. BfTypeDef* ambiguousTypeDef = NULL;
  9347. Array<BfAstNode*> genericArguments;
  9348. std::function<void(BfTypeReference*)> _GetTypeRefs = [&](BfTypeReference* typeRef)
  9349. {
  9350. //TODO:GENERICS
  9351. if (auto elementedTypeRef = BfNodeDynCast<BfElementedTypeRef>(typeRef))
  9352. {
  9353. _GetTypeRefs(elementedTypeRef->mElementType);
  9354. }
  9355. else if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(typeRef))
  9356. {
  9357. _GetTypeRefs(qualifiedTypeRef->mLeft);
  9358. }
  9359. if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef))
  9360. {
  9361. for (auto genericArg : genericTypeRef->mGenericArguments)
  9362. genericArguments.push_back(genericArg);
  9363. }
  9364. };
  9365. _GetTypeRefs(genericTypeInstRef);
  9366. BfTypeVector genericArgs;
  9367. BfType* type = NULL;
  9368. BfTypeDef* typeDef = ResolveGenericInstanceDef(genericTypeInstRef, &type, resolveFlags);
  9369. if(ambiguousTypeDef != NULL)
  9370. ShowAmbiguousTypeError(typeRef, typeDef, ambiguousTypeDef);
  9371. if (typeDef == NULL)
  9372. {
  9373. Fail("Unable to resolve type", typeRef);
  9374. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  9375. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  9376. }
  9377. BfTypeInstance* outerTypeInstance = mCurTypeInstance;
  9378. auto outerType = typeDef->mOuterType;
  9379. BfTypeDef* commonOuterType = NULL;
  9380. int startDefGenericParamIdx = 0;
  9381. commonOuterType = BfResolvedTypeSet::FindRootCommonOuterType(outerType, &lookupCtx, outerTypeInstance);
  9382. if ((commonOuterType) && (outerTypeInstance->IsGenericTypeInstance()))
  9383. {
  9384. startDefGenericParamIdx = (int)commonOuterType->mGenericParamDefs.size();
  9385. auto parentTypeInstance = outerTypeInstance;
  9386. if (parentTypeInstance->IsTypeAlias())
  9387. parentTypeInstance = (BfTypeInstance*)GetOuterType(parentTypeInstance)->ToTypeInstance();
  9388. for (int i = 0; i < startDefGenericParamIdx; i++)
  9389. genericArgs.push_back(parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i]);
  9390. }
  9391. for (auto genericArgRef : genericArguments)
  9392. {
  9393. BfType* genericArg = NULL;
  9394. lookupCtx.mResolvedTypeMap.TryGetValue(genericArgRef, &genericArg);
  9395. if (genericArg == NULL)
  9396. genericArg = ResolveTypeRef(genericArgRef, NULL, BfPopulateType_Identity, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_AllowGenericTypeParamConstValue | BfResolveTypeRefFlag_AllowGenericMethodParamConstValue));
  9397. if ((genericArg == NULL) || (genericArg->IsVar()))
  9398. {
  9399. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  9400. return ResolveTypeResult(typeRef, ((genericArg != NULL) && (genericArg->IsVar())) ? genericArg : NULL, populateType, resolveFlags);
  9401. }
  9402. genericArgs.Add(genericArg);
  9403. }
  9404. BfTypeInstance* genericTypeInst;
  9405. if ((type != NULL) &&
  9406. ((type->IsDelegateFromTypeRef()) || (type->IsFunctionFromTypeRef())))
  9407. {
  9408. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  9409. return ResolveGenericType(type, &genericArgs, NULL);
  9410. }
  9411. else if ((type != NULL) && (type->IsTuple()))
  9412. {
  9413. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  9414. return ResolveGenericType(type, &genericArgs, NULL);
  9415. }
  9416. else if ((typeDef != NULL) && (typeDef->mTypeCode == BfTypeCode_TypeAlias))
  9417. {
  9418. auto typeAliasType = new BfTypeAliasType();
  9419. genericTypeInst = typeAliasType;
  9420. }
  9421. else
  9422. genericTypeInst = new BfTypeInstance();
  9423. genericTypeInst->mContext = mContext;
  9424. genericTypeInst->mGenericTypeInfo = new BfGenericTypeInfo();
  9425. BF_ASSERT(typeDef->mDefState != BfTypeDef::DefState_Deleted);
  9426. int genericParamCount = (int)typeDef->mGenericParamDefs.size();
  9427. if ((type != NULL) && (type->IsGenericTypeInstance()))
  9428. {
  9429. // Is a generic type for sure...
  9430. // We need this case for generic methods
  9431. genericParamCount = (int)((BfTypeInstance*)type)->mGenericTypeInfo->mTypeGenericArguments.size();
  9432. }
  9433. else if (typeDef->mGenericParamDefs.size() == 0)
  9434. {
  9435. Fail("Not a generic type", typeRef);
  9436. delete genericTypeInst;
  9437. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  9438. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  9439. }
  9440. genericTypeInst->mTypeDef = typeDef;
  9441. if (commonOuterType != NULL)
  9442. {
  9443. auto parentTypeInstance = outerTypeInstance;
  9444. if ((parentTypeInstance != NULL) && (parentTypeInstance->IsTypeAlias()))
  9445. parentTypeInstance = (BfTypeInstance*)GetOuterType(parentTypeInstance)->ToTypeInstance();
  9446. if ((parentTypeInstance != NULL) && (parentTypeInstance->IsGenericTypeInstance()))
  9447. {
  9448. genericTypeInst->mGenericTypeInfo->mMaxGenericDepth = BF_MAX(genericTypeInst->mGenericTypeInfo->mMaxGenericDepth, parentTypeInstance->mGenericTypeInfo->mMaxGenericDepth);
  9449. for (int i = 0; i < startDefGenericParamIdx; i++)
  9450. {
  9451. genericTypeInst->mGenericTypeInfo->mGenericParams.push_back(parentTypeInstance->mGenericTypeInfo->mGenericParams[i]->AddRef());
  9452. genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.push_back(parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i]);
  9453. auto typeGenericArg = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[i];
  9454. genericTypeInst->mGenericTypeInfo->mIsUnspecialized |= typeGenericArg->IsGenericParam() || typeGenericArg->IsUnspecializedType();
  9455. }
  9456. }
  9457. }
  9458. int wantedGenericParams = genericParamCount - startDefGenericParamIdx;
  9459. int genericArgDiffCount = (int)genericArguments.size() - wantedGenericParams;
  9460. if (genericArgDiffCount != 0)
  9461. {
  9462. int innerWantedGenericParams = genericParamCount;
  9463. if (typeDef->mOuterType != NULL)
  9464. innerWantedGenericParams -= (int)typeDef->mOuterType->mGenericParamDefs.size();
  9465. ShowGenericArgCountError(genericTypeInstRef, innerWantedGenericParams);
  9466. delete genericTypeInst;
  9467. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  9468. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  9469. }
  9470. int genericParamIdx = 0;
  9471. for (auto genericArgRef : genericArguments)
  9472. {
  9473. auto genericArg = genericArgs[genericParamIdx + startDefGenericParamIdx];
  9474. genericTypeInst->mGenericTypeInfo->mMaxGenericDepth = BF_MAX(genericTypeInst->mGenericTypeInfo->mMaxGenericDepth, genericArg->GetGenericDepth() + 1);
  9475. genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.push_back(genericArg);
  9476. genericTypeInst->mGenericTypeInfo->mTypeGenericArgumentRefs.push_back(genericArgRef);
  9477. genericParamIdx++;
  9478. }
  9479. if (genericTypeInst->mGenericTypeInfo->mMaxGenericDepth > 64)
  9480. {
  9481. Fail("Maximum generic depth exceeded", typeRef);
  9482. delete genericTypeInst;
  9483. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  9484. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  9485. }
  9486. resolvedEntry->mValue = genericTypeInst;
  9487. CheckUnspecializedGenericType(genericTypeInst, populateType);
  9488. populateModule->InitType(genericTypeInst, populateType);
  9489. #ifdef _DEBUG
  9490. if (BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) != resolvedEntry->mHash)
  9491. {
  9492. int refHash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx);
  9493. int typeHash = BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx);
  9494. BF_ASSERT(refHash == typeHash);
  9495. }
  9496. if (!BfResolvedTypeSet::Equals(genericTypeInst, typeRef, &lookupCtx))
  9497. {
  9498. BF_ASSERT(BfResolvedTypeSet::Equals(genericTypeInst, typeRef, &lookupCtx));
  9499. }
  9500. BfLogSysM("Generic type %p typeHash: %8X\n", genericTypeInst, resolvedEntry->mHash);
  9501. #endif
  9502. BF_ASSERT(BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) == resolvedEntry->mHash);
  9503. return ResolveTypeResult(typeRef, genericTypeInst, populateType, resolveFlags);
  9504. }
  9505. else if (auto tupleTypeRef = BfNodeDynCast<BfTupleTypeRef>(typeRef))
  9506. {
  9507. Array<BfType*> types;
  9508. Array<String> names;
  9509. bool wantGeneric = false;
  9510. bool isUnspecialized = false;
  9511. for (int fieldIdx = 0; fieldIdx < (int)tupleTypeRef->mFieldTypes.size(); fieldIdx++)
  9512. {
  9513. BfTypeReference* typeRef = tupleTypeRef->mFieldTypes[fieldIdx];
  9514. auto type = ResolveTypeRef(typeRef, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowGenericParamConstValue);
  9515. if (type == NULL)
  9516. {
  9517. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  9518. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  9519. }
  9520. String fieldName;
  9521. BfIdentifierNode* identifierNode = NULL;
  9522. if (fieldIdx < (int)tupleTypeRef->mFieldNames.size())
  9523. identifierNode = tupleTypeRef->mFieldNames[fieldIdx];
  9524. if (identifierNode != NULL)
  9525. fieldName = identifierNode->ToString();
  9526. else
  9527. fieldName = StrFormat("%d", fieldIdx);
  9528. if (type->IsTypeGenericParam())
  9529. wantGeneric = true;
  9530. if (type->IsUnspecializedType())
  9531. isUnspecialized = true;
  9532. if (type->IsVar())
  9533. {
  9534. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  9535. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  9536. }
  9537. types.push_back(type);
  9538. names.push_back(fieldName);
  9539. }
  9540. if ((mCurTypeInstance == NULL) || (!mCurTypeInstance->IsGenericTypeInstance()))
  9541. wantGeneric = false;
  9542. //TODO:
  9543. wantGeneric = false;
  9544. auto baseType = (BfTypeInstance*)ResolveTypeDef(mContext->mCompiler->mValueTypeTypeDef, BfPopulateType_Identity);
  9545. BfTupleType* tupleType = NULL;
  9546. if (wantGeneric)
  9547. {
  9548. BfTupleType* actualTupleType = new BfTupleType();
  9549. actualTupleType->mGenericTypeInfo = new BfGenericTypeInfo();
  9550. actualTupleType->mGenericTypeInfo->mFinishedGenericParams = true;
  9551. actualTupleType->Init(baseType->mTypeDef->mProject, baseType);
  9552. for (int fieldIdx = 0; fieldIdx < (int)types.size(); fieldIdx++)
  9553. {
  9554. BfFieldDef* fieldDef = actualTupleType->AddField(names[fieldIdx]);
  9555. fieldDef->mProtection = (names[fieldIdx][0] == '_') ? BfProtection_Private : BfProtection_Public;
  9556. }
  9557. actualTupleType->Finish();
  9558. auto parentTypeInstance = (BfTypeInstance*)mCurTypeInstance;
  9559. for (int i = 0; i < parentTypeInstance->mGenericTypeInfo->mGenericParams.size(); i++)
  9560. {
  9561. actualTupleType->mGenericTypeInfo->mGenericParams.push_back(parentTypeInstance->mGenericTypeInfo->mGenericParams[i]->AddRef());
  9562. }
  9563. for (int i = 0; i < parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments.size(); i++)
  9564. {
  9565. actualTupleType->mGenericTypeInfo->mTypeGenericArguments.push_back(parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i]);
  9566. auto typeGenericArg = actualTupleType->mGenericTypeInfo->mTypeGenericArguments[i];
  9567. actualTupleType->mGenericTypeInfo->mIsUnspecialized |= typeGenericArg->IsGenericParam() || typeGenericArg->IsUnspecializedType();
  9568. }
  9569. CheckUnspecializedGenericType(actualTupleType, populateType);
  9570. if (isUnspecialized)
  9571. {
  9572. actualTupleType->mGenericTypeInfo->mIsUnspecialized = true;
  9573. actualTupleType->mGenericTypeInfo->mIsUnspecializedVariation = true;
  9574. }
  9575. actualTupleType->mIsUnspecializedType = actualTupleType->mGenericTypeInfo->mIsUnspecialized;
  9576. actualTupleType->mIsUnspecializedTypeVariation = actualTupleType->mGenericTypeInfo->mIsUnspecializedVariation;
  9577. tupleType = actualTupleType;
  9578. }
  9579. else
  9580. {
  9581. BfTupleType* actualTupleType = new BfTupleType();
  9582. actualTupleType->Init(baseType->mTypeDef->mProject, baseType);
  9583. for (int fieldIdx = 0; fieldIdx < (int)types.size(); fieldIdx++)
  9584. {
  9585. BfFieldDef* fieldDef = actualTupleType->AddField(names[fieldIdx]);
  9586. fieldDef->mProtection = (names[fieldIdx][0] == '_') ? BfProtection_Private : BfProtection_Public;
  9587. }
  9588. actualTupleType->Finish();
  9589. tupleType = actualTupleType;
  9590. actualTupleType->mIsUnspecializedType = isUnspecialized;
  9591. actualTupleType->mIsUnspecializedTypeVariation = isUnspecialized;
  9592. }
  9593. tupleType->mFieldInstances.Resize(types.size());
  9594. for (int fieldIdx = 0; fieldIdx < (int)types.size(); fieldIdx++)
  9595. {
  9596. BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx];
  9597. fieldInstance->mFieldIdx = fieldIdx;
  9598. fieldInstance->SetResolvedType(types[fieldIdx]);
  9599. BF_ASSERT(!types[fieldIdx]->IsVar());
  9600. fieldInstance->mOwner = tupleType;
  9601. tupleType->mGenericDepth = BF_MAX(tupleType->mGenericDepth, fieldInstance->mResolvedType->GetGenericDepth() + 1);
  9602. }
  9603. resolvedEntry->mValue = tupleType;
  9604. BF_ASSERT(BfResolvedTypeSet::Hash(tupleType, &lookupCtx) == resolvedEntry->mHash);
  9605. populateModule->InitType(tupleType, populateType);
  9606. return ResolveTypeResult(typeRef, tupleType, populateType, resolveFlags);
  9607. }
  9608. else if (auto nullableTypeRef = BfNodeDynCast<BfNullableTypeRef>(typeRef))
  9609. {
  9610. BfTypeReference* elementTypeRef = nullableTypeRef->mElementType;
  9611. auto typeDef = mCompiler->mNullableTypeDef;
  9612. auto elementType = ResolveTypeRef(elementTypeRef, BfPopulateType_Declaration, BfResolveTypeRefFlag_AllowGenericParamConstValue);
  9613. if ((elementType == NULL) || (elementType->IsVar()))
  9614. {
  9615. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  9616. return ResolveTypeResult(typeRef, elementType, populateType, resolveFlags);
  9617. }
  9618. BfTypeInstance* genericTypeInst = new BfTypeInstance();
  9619. genericTypeInst->mGenericTypeInfo = new BfGenericTypeInfo();
  9620. genericTypeInst->mContext = mContext;
  9621. genericTypeInst->mTypeDef = typeDef;
  9622. auto genericParamInstance = new BfGenericTypeParamInstance(typeDef, 0);
  9623. genericTypeInst->mGenericTypeInfo->mGenericParams.push_back(genericParamInstance);
  9624. genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.push_back(elementType);
  9625. //genericTypeInst->mIsUnspecialized = elementType->IsGenericParam() || elementType->IsUnspecializedType();
  9626. CheckUnspecializedGenericType(genericTypeInst, populateType);
  9627. resolvedEntry->mValue = genericTypeInst;
  9628. #ifdef _DEBUG
  9629. if (BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) != resolvedEntry->mHash)
  9630. {
  9631. int refHash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx);
  9632. int typeHash = BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx);
  9633. BF_ASSERT(refHash == typeHash);
  9634. }
  9635. #endif
  9636. populateModule->InitType(genericTypeInst, populateType);
  9637. return ResolveTypeResult(typeRef, genericTypeInst, populateType, resolveFlags);
  9638. }
  9639. else if (auto pointerTypeRef = BfNodeDynCast<BfPointerTypeRef>(typeRef))
  9640. {
  9641. BfPointerType* pointerType = new BfPointerType();
  9642. auto elementType = ResolveTypeRef(pointerTypeRef->mElementType, BfPopulateType_Declaration, BfResolveTypeRefFlag_AllowGenericParamConstValue);
  9643. if ((elementType == NULL) || (elementType->IsVar()))
  9644. {
  9645. delete pointerType;
  9646. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  9647. return ResolveTypeResult(typeRef, elementType, populateType, resolveFlags);
  9648. }
  9649. pointerType->mGenericDepth = elementType->GetGenericDepth() + 1;
  9650. pointerType->mElementType = elementType;
  9651. pointerType->mContext = mContext;
  9652. resolvedEntry->mValue = pointerType;
  9653. //int hashVal = mContext->mResolvedTypes.Hash(typeRef, &lookupCtx);
  9654. BF_ASSERT(BfResolvedTypeSet::Hash(pointerType, &lookupCtx) == resolvedEntry->mHash);
  9655. populateModule->InitType(pointerType, populateType);
  9656. return ResolveTypeResult(typeRef, pointerType, populateType, resolveFlags);
  9657. }
  9658. else if (auto refTypeRef = BfNodeDynCast<BfRefTypeRef>(typeRef))
  9659. {
  9660. BfRefType* refType = new BfRefType();
  9661. refType->mRefKind = BfRefType::RefKind_Ref;
  9662. if (refTypeRef->mRefToken == NULL)
  9663. refType->mRefKind = BfRefType::RefKind_Ref;
  9664. else if (refTypeRef->mRefToken->GetToken() == BfToken_In)
  9665. refType->mRefKind = BfRefType::RefKind_In;
  9666. else if (refTypeRef->mRefToken->GetToken() == BfToken_Out)
  9667. refType->mRefKind = BfRefType::RefKind_Out;
  9668. else if (refTypeRef->mRefToken->GetToken() == BfToken_Mut)
  9669. refType->mRefKind = BfRefType::RefKind_Mut;
  9670. auto elementType = ResolveTypeRef(refTypeRef->mElementType, BfPopulateType_Declaration, BfResolveTypeRefFlag_AllowGenericParamConstValue);
  9671. if ((elementType == NULL) || (elementType->IsVar()))
  9672. {
  9673. delete refType;
  9674. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  9675. return ResolveTypeResult(typeRef, elementType, populateType, resolveFlags);
  9676. }
  9677. refType->mElementType = elementType;
  9678. resolvedEntry->mValue = refType;
  9679. #ifdef _DEBUG
  9680. if (BfResolvedTypeSet::Hash(refType, &lookupCtx) != resolvedEntry->mHash)
  9681. {
  9682. int refHash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx, BfResolvedTypeSet::BfHashFlag_AllowRef);
  9683. int typeHash = BfResolvedTypeSet::Hash(refType, &lookupCtx);
  9684. BF_ASSERT(refHash == typeHash);
  9685. }
  9686. BF_ASSERT(BfResolvedTypeSet::Equals(refType, typeRef, &lookupCtx));
  9687. #endif
  9688. populateModule->InitType(refType, populateType);
  9689. return ResolveTypeResult(typeRef, refType, populateType, resolveFlags);
  9690. }
  9691. else if (auto delegateTypeRef = BfNodeDynCast<BfDelegateTypeRef>(typeRef))
  9692. {
  9693. bool wantGeneric = false;
  9694. bool isUnspecialized = false;
  9695. auto _CheckType = [&](BfType* type)
  9696. {
  9697. if (type->IsTypeGenericParam())
  9698. wantGeneric = true;
  9699. if (type->IsUnspecializedType())
  9700. isUnspecialized = true;
  9701. };
  9702. bool failed = false;
  9703. auto returnType = ResolveTypeRef(delegateTypeRef->mReturnType, NULL, BfPopulateType_Declaration, BfResolveTypeRefFlag_AllowRef);
  9704. if (returnType == NULL)
  9705. {
  9706. failed = true;
  9707. returnType = GetPrimitiveType(BfTypeCode_Var);
  9708. }
  9709. _CheckType(returnType);
  9710. BfType* functionThisType = NULL;
  9711. bool hasMutSpecifier = false;
  9712. bool isFirst = true;
  9713. bool isDelegate = delegateTypeRef->mTypeToken->GetToken() == BfToken_Delegate;
  9714. bool hasVarArgs = false;
  9715. Array<BfType*> paramTypes;
  9716. for (int paramIdx = 0; paramIdx < delegateTypeRef->mParams.size(); paramIdx++)
  9717. {
  9718. auto param = delegateTypeRef->mParams[paramIdx];
  9719. BfResolveTypeRefFlags resolveTypeFlags = BfResolveTypeRefFlag_AllowRef;
  9720. if ((param->mNameNode != NULL) && (param->mNameNode->Equals("this")))
  9721. resolveTypeFlags = (BfResolveTypeRefFlags)(resolveTypeFlags | BfResolveTypeRefFlag_NoWarnOnMut);
  9722. if (paramIdx == delegateTypeRef->mParams.size() - 1)
  9723. {
  9724. if (auto dotTypeRef = BfNodeDynCast<BfDotTypeReference>(param->mTypeRef))
  9725. {
  9726. if (dotTypeRef->mDotToken->mToken == BfToken_DotDotDot)
  9727. {
  9728. hasVarArgs = true;
  9729. continue;
  9730. }
  9731. }
  9732. }
  9733. auto paramType = ResolveTypeRef(param->mTypeRef, BfPopulateType_Declaration, resolveTypeFlags);
  9734. if (paramType == NULL)
  9735. {
  9736. failed = true;
  9737. paramType = GetPrimitiveType(BfTypeCode_Var);
  9738. }
  9739. if ((!isDelegate) && (isFirst) && (param->mNameNode != NULL) && (param->mNameNode->Equals("this")))
  9740. {
  9741. functionThisType = paramType;
  9742. if (functionThisType->IsRef())
  9743. {
  9744. auto refType = (BfRefType*)functionThisType;
  9745. if (refType->mRefKind != BfRefType::RefKind_Mut)
  9746. {
  9747. if (auto refTypeRef = BfNodeDynCast<BfRefTypeRef>(param->mTypeRef))
  9748. {
  9749. failed = true;
  9750. Fail("Only 'mut' is allowed here", refTypeRef->mRefToken);
  9751. }
  9752. }
  9753. hasMutSpecifier = true;
  9754. functionThisType = refType->mElementType;
  9755. }
  9756. paramTypes.Add(functionThisType);
  9757. _CheckType(functionThisType);
  9758. }
  9759. else
  9760. {
  9761. paramTypes.Add(paramType);
  9762. _CheckType(paramType);
  9763. }
  9764. isFirst = false;
  9765. }
  9766. if ((mCurTypeInstance == NULL) || (!mCurTypeInstance->IsGenericTypeInstance()))
  9767. wantGeneric = false;
  9768. //TODO:
  9769. wantGeneric = false;
  9770. BfTypeInstance* baseDelegateType = NULL;
  9771. if (mCompiler->mDelegateTypeDef != NULL)
  9772. baseDelegateType = ResolveTypeDef(mCompiler->mDelegateTypeDef)->ToTypeInstance();
  9773. else
  9774. failed = true;
  9775. BfDelegateInfo* delegateInfo = NULL;
  9776. BfDelegateType* delegateType = NULL;
  9777. if (wantGeneric)
  9778. {
  9779. BfDelegateType* genericTypeInst = new BfDelegateType();
  9780. genericTypeInst->mGenericTypeInfo = new BfGenericTypeInfo();
  9781. genericTypeInst->mGenericTypeInfo->mFinishedGenericParams = true;
  9782. delegateType = genericTypeInst;
  9783. delegateInfo = delegateType->GetDelegateInfo();
  9784. auto parentTypeInstance = (BfTypeInstance*)mCurTypeInstance;
  9785. for (int i = 0; i < parentTypeInstance->mGenericTypeInfo->mGenericParams.size(); i++)
  9786. {
  9787. genericTypeInst->mGenericTypeInfo->mGenericParams.push_back(parentTypeInstance->mGenericTypeInfo->mGenericParams[i]->AddRef());
  9788. }
  9789. for (int i = 0; i < parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments.size(); i++)
  9790. {
  9791. genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.push_back(parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i]);
  9792. auto typeGenericArg = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[i];
  9793. genericTypeInst->mGenericTypeInfo->mIsUnspecialized |= typeGenericArg->IsGenericParam() || typeGenericArg->IsUnspecializedType();
  9794. }
  9795. CheckUnspecializedGenericType(genericTypeInst, populateType);
  9796. // We don't ever need to do an actual pass over generic delegate methods, so it's safe to set the 'unspecialized variation' flag
  9797. if (isUnspecialized)
  9798. {
  9799. genericTypeInst->mGenericTypeInfo->mIsUnspecialized = true;
  9800. genericTypeInst->mGenericTypeInfo->mIsUnspecializedVariation = true;
  9801. }
  9802. genericTypeInst->mIsUnspecializedType = genericTypeInst->mGenericTypeInfo->mIsUnspecialized;
  9803. genericTypeInst->mIsUnspecializedTypeVariation = genericTypeInst->mGenericTypeInfo->mIsUnspecializedVariation;
  9804. }
  9805. else
  9806. {
  9807. auto dlgType = new BfDelegateType();
  9808. delegateInfo = dlgType->GetDelegateInfo();
  9809. dlgType->mIsUnspecializedType = isUnspecialized;
  9810. dlgType->mIsUnspecializedTypeVariation = isUnspecialized;
  9811. delegateType = dlgType;
  9812. }
  9813. delegateInfo->mCallingConvention = lookupCtx.mCallingConvention;
  9814. Val128 hashContext;
  9815. BfTypeDef* typeDef = new BfTypeDef();
  9816. if (baseDelegateType != NULL)
  9817. typeDef->mProject = baseDelegateType->mTypeDef->mProject;
  9818. typeDef->mSystem = mCompiler->mSystem;
  9819. typeDef->mName = mSystem->mEmptyAtom;
  9820. if (delegateTypeRef->mTypeToken->GetToken() == BfToken_Delegate)
  9821. {
  9822. typeDef->mIsDelegate = true;
  9823. typeDef->mTypeCode = BfTypeCode_Object;
  9824. }
  9825. else
  9826. {
  9827. typeDef->mIsFunction = true;
  9828. typeDef->mTypeCode = BfTypeCode_Struct;
  9829. }
  9830. BfMethodDef* methodDef = new BfMethodDef();
  9831. methodDef->mDeclaringType = typeDef;
  9832. methodDef->mName = "Invoke";
  9833. methodDef->mProtection = BfProtection_Public;
  9834. methodDef->mIdx = 0;
  9835. methodDef->mIsStatic = !typeDef->mIsDelegate && (functionThisType == NULL);
  9836. methodDef->mHasExplicitThis = functionThisType != NULL;
  9837. if ((functionThisType != NULL) && (hasMutSpecifier))
  9838. {
  9839. if ((functionThisType->IsValueType()) || (functionThisType->IsGenericParam()))
  9840. methodDef->mIsMutating = true;
  9841. }
  9842. auto directTypeRef = BfAstNode::ZeroedAlloc<BfDirectTypeReference>();
  9843. delegateInfo->mDirectAllocNodes.push_back(directTypeRef);
  9844. if (typeDef->mIsDelegate)
  9845. directTypeRef->Init(delegateType);
  9846. else if (mCompiler->mFunctionTypeDef == NULL)
  9847. failed = true;
  9848. else
  9849. directTypeRef->Init(ResolveTypeDef(mCompiler->mFunctionTypeDef));
  9850. if (!failed)
  9851. typeDef->mBaseTypes.push_back(directTypeRef);
  9852. directTypeRef = BfAstNode::ZeroedAlloc<BfDirectTypeReference>();
  9853. delegateInfo->mDirectAllocNodes.push_back(directTypeRef);
  9854. directTypeRef->Init(returnType);
  9855. methodDef->mReturnTypeRef = directTypeRef;
  9856. delegateInfo->mReturnType = returnType;
  9857. delegateInfo->mHasExplicitThis = functionThisType != NULL;
  9858. delegateInfo->mHasVarArgs = hasVarArgs;
  9859. delegateType->mGenericDepth = BF_MAX(delegateType->mGenericDepth, returnType->GetGenericDepth() + 1);
  9860. auto hashVal = mContext->mResolvedTypes.Hash(typeRef, &lookupCtx);
  9861. //int paramSrcOfs = (functionThisType != NULL) ? 1 : 0;
  9862. int paramSrcOfs = 0;
  9863. for (int paramIdx = 0; paramIdx < (int)paramTypes.size(); paramIdx++)
  9864. {
  9865. auto param = delegateTypeRef->mParams[paramIdx + paramSrcOfs];
  9866. auto paramType = paramTypes[paramIdx];
  9867. if (paramType == NULL)
  9868. paramType = GetPrimitiveType(BfTypeCode_Var);
  9869. String paramName;
  9870. if (param->mNameNode != NULL)
  9871. paramName = param->mNameNode->ToString();
  9872. if (!paramType->IsReified())
  9873. delegateType->mIsReified = false;
  9874. auto directTypeRef = BfAstNode::ZeroedAlloc<BfDirectTypeReference>();
  9875. delegateInfo->mDirectAllocNodes.push_back(directTypeRef);
  9876. directTypeRef->Init(paramType);
  9877. BfParameterDef* paramDef = new BfParameterDef();
  9878. paramDef->mTypeRef = directTypeRef;
  9879. paramDef->mName = paramName;
  9880. if ((paramIdx == 0) && (functionThisType != NULL))
  9881. paramDef->mParamKind = BfParamKind_ExplicitThis;
  9882. methodDef->mParams.push_back(paramDef);
  9883. delegateInfo->mParams.Add(paramType);
  9884. delegateType->mGenericDepth = BF_MAX(delegateType->mGenericDepth, paramType->GetGenericDepth() + 1);
  9885. }
  9886. if (delegateInfo->mHasVarArgs)
  9887. {
  9888. BfParameterDef* paramDef = new BfParameterDef();
  9889. paramDef->mParamKind = BfParamKind_VarArgs;
  9890. methodDef->mParams.push_back(paramDef);
  9891. }
  9892. typeDef->mMethods.push_back(methodDef);
  9893. if (failed)
  9894. {
  9895. delete delegateType;
  9896. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  9897. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  9898. }
  9899. //
  9900. if (typeDef->mIsDelegate)
  9901. {
  9902. BfDefBuilder::AddMethod(typeDef, BfMethodType_Ctor, BfProtection_Public, false, "");
  9903. BfDefBuilder::AddDynamicCastMethods(typeDef);
  9904. }
  9905. delegateType->mContext = mContext;
  9906. delegateType->mTypeDef = typeDef;
  9907. populateModule->InitType(delegateType, populateType);
  9908. resolvedEntry->mValue = delegateType;
  9909. AddDependency(directTypeRef->mType, delegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue);
  9910. // if (delegateInfo->mFunctionThisType != NULL)
  9911. // AddDependency(delegateInfo->mFunctionThisType, delegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue);
  9912. for (auto paramType : paramTypes)
  9913. AddDependency(paramType, delegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue);
  9914. #ifdef _DEBUG
  9915. if (BfResolvedTypeSet::Hash(delegateType, &lookupCtx) != resolvedEntry->mHash)
  9916. {
  9917. int refHash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx);
  9918. int typeHash = BfResolvedTypeSet::Hash(delegateType, &lookupCtx);
  9919. BF_ASSERT(refHash == typeHash);
  9920. }
  9921. BF_ASSERT(BfResolvedTypeSet::Equals(delegateType, typeRef, &lookupCtx));
  9922. #endif
  9923. BF_ASSERT(BfResolvedTypeSet::Hash(delegateType, &lookupCtx) == resolvedEntry->mHash);
  9924. return ResolveTypeResult(typeRef, delegateType, populateType, resolveFlags);
  9925. }
  9926. else if (auto genericParamTypeRef = BfNodeDynCast<BfGenericParamTypeRef>(typeRef))
  9927. {
  9928. auto genericParamType = GetGenericParamType(genericParamTypeRef->mGenericParamKind, genericParamTypeRef->mGenericParamIdx);
  9929. resolvedEntry->mValue = genericParamType;
  9930. BF_ASSERT(BfResolvedTypeSet::Hash(genericParamType, &lookupCtx) == resolvedEntry->mHash);
  9931. return ResolveTypeResult(typeRef, genericParamType, populateType, resolveFlags);
  9932. }
  9933. else if (auto retTypeTypeRef = BfNodeDynCast<BfModifiedTypeRef>(typeRef))
  9934. {
  9935. auto retTypeType = new BfModifiedTypeType();
  9936. retTypeType->mModifiedKind = retTypeTypeRef->mRetTypeToken->mToken;
  9937. retTypeType->mElementType = ResolveTypeRef(retTypeTypeRef->mElementType, BfPopulateType_Declaration, BfResolveTypeRefFlag_AllowGenericParamConstValue);
  9938. // We know this is a generic param type, it can't fail to resolve
  9939. BF_ASSERT(retTypeType->mElementType);
  9940. resolvedEntry->mValue = retTypeType;
  9941. BF_ASSERT(BfResolvedTypeSet::Hash(retTypeType, &lookupCtx) == resolvedEntry->mHash);
  9942. populateModule->InitType(retTypeType, populateType);
  9943. return ResolveTypeResult(typeRef, retTypeType, populateType, resolveFlags);
  9944. }
  9945. else if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(typeRef))
  9946. {
  9947. auto leftType = ResolveTypeRef(qualifiedTypeRef->mLeft, BfPopulateType_Declaration, BfResolveTypeRefFlag_AllowGenericParamConstValue);
  9948. if (leftType == NULL)
  9949. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  9950. return ResolveTypeResult(typeRef, ResolveInnerType(leftType, qualifiedTypeRef->mRight), populateType, resolveFlags);
  9951. }
  9952. else if (auto constTypeRef = BfNodeDynCastExact<BfConstTypeRef>(typeRef))
  9953. {
  9954. return ResolveTypeRef(constTypeRef->mElementType, populateType, (BfResolveTypeRefFlags)(resolveFlags & BfResolveTypeRefFlag_NoResolveGenericParam));
  9955. }
  9956. else if (auto constExprTypeRef = BfNodeDynCastExact<BfConstExprTypeRef>(typeRef))
  9957. {
  9958. if ((mCurTypeInstance != NULL) && (mCurTypeInstance->mDependencyMap.mMinDependDepth > 32))
  9959. {
  9960. Fail("Generic type dependency depth exceeded", typeRef);
  9961. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  9962. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  9963. }
  9964. BfVariant result;
  9965. BfType* resultType = NULL;
  9966. if (constExprTypeRef->mConstExpr != NULL)
  9967. {
  9968. result = mContext->mResolvedTypes.EvaluateToVariant(&lookupCtx, constExprTypeRef->mConstExpr, resultType);
  9969. BF_ASSERT(resultType != NULL);
  9970. }
  9971. auto constExprType = new BfConstExprValueType();
  9972. constExprType->mContext = mContext;
  9973. constExprType->mType = resultType;
  9974. BF_ASSERT(constExprType->mType != NULL);
  9975. if (constExprType->mType == NULL)
  9976. constExprType->mType = GetPrimitiveType(BfTypeCode_Let);
  9977. constExprType->mValue = result;
  9978. resolvedEntry->mValue = constExprType;
  9979. #ifdef _DEBUG
  9980. if (BfResolvedTypeSet::Hash(constExprType, &lookupCtx) != resolvedEntry->mHash)
  9981. {
  9982. int refHash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx);
  9983. int typeHash = BfResolvedTypeSet::Hash(constExprType, &lookupCtx);
  9984. BF_ASSERT(refHash == typeHash);
  9985. }
  9986. BF_ASSERT(BfResolvedTypeSet::Equals(constExprType, typeRef, &lookupCtx));
  9987. #endif
  9988. populateModule->InitType(constExprType, populateType);
  9989. return constExprType;
  9990. }
  9991. else
  9992. {
  9993. BFMODULE_FATAL(this, "Not implemented!");
  9994. NotImpl(typeRef);
  9995. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  9996. }
  9997. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  9998. }
  9999. BfType* BfModule::ResolveTypeRefAllowUnboundGenerics(BfTypeReference* typeRef, BfPopulateType populateType, bool resolveGenericParam)
  10000. {
  10001. if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef))
  10002. {
  10003. if (genericTypeRef->mGenericArguments.size() == 0)
  10004. {
  10005. auto genericTypeDef = ResolveGenericInstanceDef(genericTypeRef);
  10006. if (genericTypeDef == NULL)
  10007. return NULL;
  10008. BfTypeVector typeVector;
  10009. for (int i = 0; i < (int)genericTypeDef->mGenericParamDefs.size(); i++)
  10010. typeVector.push_back(GetGenericParamType(BfGenericParamKind_Type, i));
  10011. auto result = ResolveTypeDef(genericTypeDef, typeVector, populateType);
  10012. if ((result != NULL) && (genericTypeRef->mCommas.size() + 1 != genericTypeDef->mGenericParamDefs.size()))
  10013. {
  10014. SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, result->ToTypeInstance());
  10015. SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, NULL);
  10016. Fail(StrFormat("Type '%s' requires %d generic arguments", TypeToString(result).c_str(), genericTypeDef->mGenericParamDefs.size()), typeRef);
  10017. }
  10018. return result;
  10019. }
  10020. }
  10021. return ResolveTypeRef(typeRef, populateType, resolveGenericParam ? (BfResolveTypeRefFlags)0 : BfResolveTypeRefFlag_NoResolveGenericParam);
  10022. }
  10023. // This finds non-default unspecialized generic type instances and converts them into a BfUnspecializedGenericTypeVariation
  10024. BfType* BfModule::CheckUnspecializedGenericType(BfTypeInstance* genericTypeInst, BfPopulateType populateType)
  10025. {
  10026. int argCount = (int)genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size();
  10027. bool isDefaultUnspecialized = true;
  10028. for (int argIdx = 0; argIdx < argCount; argIdx++)
  10029. {
  10030. auto argType = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[argIdx];
  10031. if (argType->IsGenericParam())
  10032. {
  10033. auto genericParamType = (BfGenericParamType*)argType;
  10034. if ((genericParamType->mGenericParamKind != BfGenericParamKind_Type) || (genericParamType->mGenericParamIdx != argIdx))
  10035. isDefaultUnspecialized = false;
  10036. genericTypeInst->mGenericTypeInfo->mIsUnspecialized = true;
  10037. }
  10038. else if (argType->IsUnspecializedType())
  10039. {
  10040. isDefaultUnspecialized = false;
  10041. genericTypeInst->mGenericTypeInfo->mIsUnspecialized = true;
  10042. }
  10043. else
  10044. isDefaultUnspecialized = false;
  10045. }
  10046. if (genericTypeInst->mGenericTypeInfo->mIsUnspecialized)
  10047. genericTypeInst->mGenericTypeInfo->mIsUnspecializedVariation = !isDefaultUnspecialized;
  10048. return genericTypeInst;
  10049. }
  10050. BfTypeInstance* BfModule::GetUnspecializedTypeInstance(BfTypeInstance* typeInst)
  10051. {
  10052. if (!typeInst->IsGenericTypeInstance())
  10053. return typeInst;
  10054. BF_ASSERT((!typeInst->IsDelegateFromTypeRef()) && (!typeInst->IsFunctionFromTypeRef()));
  10055. auto genericTypeInst = (BfTypeInstance*)typeInst;
  10056. auto result = ResolveTypeDef(genericTypeInst->mTypeDef->GetDefinition(), BfPopulateType_Declaration);
  10057. BF_ASSERT((result != NULL) && (result->IsUnspecializedType()));
  10058. if (result == NULL)
  10059. return NULL;
  10060. return result->ToTypeInstance();
  10061. }
  10062. BfType* BfModule::ResolveTypeRef_Type(BfAstNode* astNode, const BfSizedArray<BfAstNode*>* genericArgs, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags)
  10063. {
  10064. if ((genericArgs == NULL) || (genericArgs->size() == 0))
  10065. {
  10066. if (auto identifier = BfNodeDynCast<BfIdentifierNode>(astNode))
  10067. {
  10068. BfNamedTypeReference typeRef;
  10069. typeRef.mNameNode = identifier;
  10070. typeRef.mSrcEnd = 0;
  10071. typeRef.mToken = BfToken_None;
  10072. auto type = ResolveTypeRef(&typeRef, populateType, resolveFlags);
  10073. return type;
  10074. }
  10075. }
  10076. BfAstAllocator alloc;
  10077. alloc.mSourceData = astNode->GetSourceData();
  10078. std::function<BfTypeReference* (BfAstNode*)> _ConvType = [&](BfAstNode* astNode) -> BfTypeReference*
  10079. {
  10080. if (auto typeRef = BfNodeDynCast<BfTypeReference>(astNode))
  10081. return typeRef;
  10082. BfTypeReference* result = NULL;
  10083. if (auto identifier = BfNodeDynCast<BfIdentifierNode>(astNode))
  10084. {
  10085. auto* typeRef = alloc.Alloc<BfNamedTypeReference>();
  10086. typeRef->mNameNode = identifier;
  10087. result = typeRef;
  10088. }
  10089. else if (auto memberRefExpr = BfNodeDynCast<BfMemberReferenceExpression>(astNode))
  10090. {
  10091. auto qualifiedTypeRef = alloc.Alloc<BfQualifiedTypeReference>();
  10092. qualifiedTypeRef->mLeft = _ConvType(memberRefExpr->mTarget);
  10093. qualifiedTypeRef->mDot = memberRefExpr->mDotToken;
  10094. qualifiedTypeRef->mRight = _ConvType(memberRefExpr->mMemberName);
  10095. if ((qualifiedTypeRef->mLeft == NULL) || (qualifiedTypeRef->mRight == NULL))
  10096. return NULL;
  10097. result = qualifiedTypeRef;
  10098. }
  10099. if (result == NULL)
  10100. return NULL;
  10101. result->SetSrcStart(astNode->GetSrcStart());
  10102. result->SetSrcEnd(astNode->GetSrcEnd());
  10103. return result;
  10104. };
  10105. auto typeRef = _ConvType(astNode);
  10106. if (typeRef == NULL)
  10107. return NULL;
  10108. if ((genericArgs != NULL) && (genericArgs->size() != 0))
  10109. {
  10110. auto genericInstanceTypeRef = alloc.Alloc<BfGenericInstanceTypeRef>();
  10111. genericInstanceTypeRef->SetSrcStart(typeRef->GetSrcStart());
  10112. genericInstanceTypeRef->mElementType = typeRef;
  10113. #ifdef BF_AST_HAS_PARENT_MEMBER
  10114. typeRef->mParent = genericInstanceTypeRef;
  10115. #endif
  10116. BfDeferredAstSizedArray<BfAstNode*> arguments(genericInstanceTypeRef->mGenericArguments, &alloc);
  10117. for (auto genericArg : *genericArgs)
  10118. {
  10119. if (genericArg != NULL)
  10120. {
  10121. arguments.push_back(genericArg);
  10122. genericInstanceTypeRef->SetSrcEnd(genericArg->GetSrcEnd());
  10123. }
  10124. }
  10125. typeRef = genericInstanceTypeRef;
  10126. }
  10127. return ResolveTypeRef(typeRef, populateType, resolveFlags);
  10128. }
  10129. BfType* BfModule::ResolveTypeRef(BfAstNode* astNode, const BfSizedArray<BfAstNode*>* genericArgs, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags)
  10130. {
  10131. if (astNode == NULL)
  10132. {
  10133. AssertErrorState();
  10134. return NULL;
  10135. }
  10136. if (auto typeRef = BfNodeDynCast<BfTypeReference>(astNode))
  10137. return ResolveTypeRef(typeRef, populateType, resolveFlags);
  10138. if ((resolveFlags & BfResolveTypeRefFlag_AllowImplicitConstExpr) != 0)
  10139. {
  10140. if (auto expr = BfNodeDynCast<BfExpression>(astNode))
  10141. {
  10142. auto checkType = ResolveTypeRef_Type(astNode, genericArgs, populateType, (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_IgnoreLookupError));
  10143. if (checkType != NULL)
  10144. return checkType;
  10145. BfResolvedTypeSet::LookupContext lookupCtx;
  10146. lookupCtx.mModule = this;
  10147. BfResolvedTypeSet::Entry* typeEntry = NULL;
  10148. BfType* resultType = NULL;
  10149. auto result = mContext->mResolvedTypes.EvaluateToVariant(&lookupCtx, expr, resultType);
  10150. if (resultType != NULL)
  10151. {
  10152. auto constExprValue = CreateConstExprValueType(result, resultType);
  10153. return constExprValue;
  10154. }
  10155. }
  10156. }
  10157. return ResolveTypeRef_Type(astNode, genericArgs, populateType, resolveFlags);
  10158. }
  10159. // This flow should mirror CastToValue
  10160. bool BfModule::CanCast(BfTypedValue typedVal, BfType* toType, BfCastFlags castFlags)
  10161. {
  10162. BP_ZONE("BfModule::CanCast");
  10163. SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, true);
  10164. return CastToValue(NULL, typedVal, toType, (BfCastFlags)(castFlags | BfCastFlags_SilentFail | BfCastFlags_IsCastCheck));
  10165. }
  10166. bool BfModule::AreSplatsCompatible(BfType* fromType, BfType* toType, bool* outNeedsMemberCasting)
  10167. {
  10168. if ((fromType->IsTypeInstance()) && (!fromType->IsSplattable()))
  10169. return false;
  10170. if ((toType->IsTypeInstance()) && (!toType->IsSplattable()))
  10171. return false;
  10172. auto _GetTypes = [&](BfType* type, Array<BfType*>& types)
  10173. {
  10174. BfTypeUtils::SplatIterate([&](BfType* memberType) { types.Add(memberType); }, type);
  10175. };
  10176. Array<BfType*> fromTypes;
  10177. _GetTypes(fromType, fromTypes);
  10178. Array<BfType*> toTypes;
  10179. _GetTypes(toType, toTypes);
  10180. if (toTypes.size() > fromTypes.size())
  10181. return false;
  10182. for (int i = 0; i < toTypes.size(); i++)
  10183. {
  10184. BfType* fromMemberType = fromTypes[i];
  10185. BfType* toMemberType = toTypes[i];
  10186. if (fromMemberType != toMemberType)
  10187. {
  10188. if ((outNeedsMemberCasting != NULL) &&
  10189. (fromMemberType->IsIntPtrable()) && (toMemberType->IsIntPtrable()))
  10190. *outNeedsMemberCasting = true;
  10191. else
  10192. return false;
  10193. }
  10194. }
  10195. return true;
  10196. }
  10197. BfIRValue BfModule::CastToFunction(BfAstNode* srcNode, const BfTypedValue& targetValue, BfMethodInstance* methodInstance, BfType* toType, BfCastFlags castFlags, BfIRValue irFunc)
  10198. {
  10199. auto invokeMethodInstance = GetDelegateInvokeMethod(toType->ToTypeInstance());
  10200. bool methodsThisMatch = true;
  10201. if (invokeMethodInstance->mMethodDef->mIsStatic != methodInstance->mMethodDef->mIsStatic)
  10202. methodsThisMatch = false;
  10203. else
  10204. {
  10205. if (!methodInstance->mMethodDef->mIsStatic)
  10206. {
  10207. BfType* thisType = methodInstance->GetThisType();
  10208. if (thisType->IsPointer())
  10209. thisType = thisType->GetUnderlyingType();
  10210. BfType* invokeThisType = invokeMethodInstance->GetThisType();
  10211. if (invokeThisType->IsPointer())
  10212. invokeThisType = invokeThisType->GetUnderlyingType();
  10213. if (!TypeIsSubTypeOf(thisType->ToTypeInstance(), invokeThisType->ToTypeInstance()))
  10214. methodsThisMatch = false;
  10215. }
  10216. }
  10217. bool methodMatches = methodsThisMatch;
  10218. if (methodMatches)
  10219. methodMatches = invokeMethodInstance->IsExactMatch(methodInstance, false, false);
  10220. if (methodMatches)
  10221. {
  10222. if (methodInstance->GetOwner()->IsFunction())
  10223. {
  10224. BF_ASSERT(targetValue);
  10225. return targetValue.mValue;
  10226. }
  10227. BfIRFunction bindFuncVal = irFunc;
  10228. if (!bindFuncVal)
  10229. {
  10230. BfModuleMethodInstance methodRefMethod;
  10231. if (methodInstance->mDeclModule == this)
  10232. methodRefMethod = methodInstance;
  10233. else
  10234. methodRefMethod = ReferenceExternalMethodInstance(methodInstance);
  10235. auto dataType = GetPrimitiveType(BfTypeCode_IntPtr);
  10236. if (!methodRefMethod.mFunc)
  10237. {
  10238. if ((!methodInstance->mIsUnspecialized) && (HasCompiledOutput()))
  10239. AssertErrorState();
  10240. return GetDefaultValue(dataType);
  10241. }
  10242. bindFuncVal = methodRefMethod.mFunc;
  10243. }
  10244. if (mCompiler->mOptions.mAllowHotSwapping)
  10245. bindFuncVal = mBfIRBuilder->RemapBindFunction(bindFuncVal);
  10246. return mBfIRBuilder->CreatePtrToInt(bindFuncVal, BfTypeCode_IntPtr);
  10247. }
  10248. if ((castFlags & BfCastFlags_SilentFail) == 0)
  10249. {
  10250. if ((methodsThisMatch) && (invokeMethodInstance->IsExactMatch(methodInstance, true, false)))
  10251. {
  10252. Fail(StrFormat("Non-static method '%s' cannot match '%s' because it contains captured variables, consider using a delegate or removing captures", MethodToString(methodInstance).c_str(), TypeToString(toType).c_str()), srcNode);
  10253. }
  10254. else if (invokeMethodInstance->IsExactMatch(methodInstance, false, false))
  10255. {
  10256. bool handled = false;
  10257. if (methodInstance->HasThis())
  10258. {
  10259. auto thisType = methodInstance->GetThisType();
  10260. if (invokeMethodInstance->HasExplicitThis())
  10261. {
  10262. auto invokeThisType = invokeMethodInstance->GetThisType();
  10263. bool thisWasPtr = false;
  10264. if (thisType->IsPointer())
  10265. {
  10266. thisType = thisType->GetUnderlyingType();
  10267. thisWasPtr = true;
  10268. }
  10269. bool invokeThisWasPtr = false;
  10270. if (invokeThisType->IsPointer())
  10271. {
  10272. invokeThisType = invokeThisType->GetUnderlyingType();
  10273. invokeThisWasPtr = true;
  10274. }
  10275. if (TypeIsSubTypeOf(thisType->ToTypeInstance(), invokeThisType->ToTypeInstance()))
  10276. {
  10277. if (invokeThisWasPtr != thisWasPtr)
  10278. {
  10279. if (invokeThisWasPtr)
  10280. Fail(StrFormat("Non-static method '%s' cannot match '%s', consider removing 'mut' from 'mut %s this' in the function parameters", MethodToString(methodInstance).c_str(), TypeToString(toType).c_str(), TypeToString(thisType).c_str()), srcNode);
  10281. else
  10282. Fail(StrFormat("Non-static method '%s' cannot match '%s', consider adding 'mut' specifier to '%s this' in the function parameters", MethodToString(methodInstance).c_str(), TypeToString(toType).c_str(), TypeToString(thisType).c_str()), srcNode);
  10283. handled = true;
  10284. }
  10285. }
  10286. }
  10287. }
  10288. if ((!methodInstance->mMethodDef->mIsStatic) && (!invokeMethodInstance->HasExplicitThis()))
  10289. {
  10290. handled = true;
  10291. auto thisType = methodInstance->GetParamType(-1);
  10292. Fail(StrFormat("Non-static method '%s' cannot match '%s', consider adding '%s this' to the function parameters", MethodToString(methodInstance).c_str(), TypeToString(toType).c_str(), TypeToString(thisType).c_str()), srcNode);
  10293. }
  10294. if (!handled)
  10295. {
  10296. if (invokeMethodInstance->mMethodDef->mIsStatic)
  10297. Fail(StrFormat("Static method '%s' cannot match '%s'", MethodToString(methodInstance).c_str(), TypeToString(toType).c_str()).c_str(), srcNode);
  10298. else
  10299. Fail(StrFormat("Non-static method '%s' cannot match '%s'", MethodToString(methodInstance).c_str(), TypeToString(toType).c_str()).c_str(), srcNode);
  10300. }
  10301. }
  10302. }
  10303. return BfIRValue();
  10304. }
  10305. BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfType* toType, BfCastFlags castFlags, BfCastResultFlags* resultFlags)
  10306. {
  10307. bool silentFail = ((castFlags & BfCastFlags_SilentFail) != 0);
  10308. bool explicitCast = (castFlags & BfCastFlags_Explicit) != 0;
  10309. bool ignoreErrors = mIgnoreErrors || ((castFlags & BfCastFlags_SilentFail) != 0);
  10310. bool ignoreWrites = mBfIRBuilder->mIgnoreWrites;
  10311. if (typedVal.mType == toType)
  10312. {
  10313. if (resultFlags != NULL)
  10314. {
  10315. if (typedVal.IsAddr())
  10316. *resultFlags = (BfCastResultFlags)(*resultFlags | BfCastResultFlags_IsAddr);
  10317. if (typedVal.mKind == BfTypedValueKind_TempAddr)
  10318. *resultFlags = (BfCastResultFlags)(*resultFlags | BfCastResultFlags_IsTemp);
  10319. }
  10320. else if (typedVal.IsAddr())
  10321. typedVal = LoadValue(typedVal);
  10322. return typedVal.mValue;
  10323. }
  10324. BF_ASSERT(typedVal.mType->mContext == mContext);
  10325. BF_ASSERT(toType->mContext == mContext);
  10326. if ((typedVal.IsAddr()) && (!typedVal.mType->IsValueType()))
  10327. typedVal = LoadValue(typedVal);
  10328. //BF_ASSERT(!typedVal.IsAddr() || typedVal.mType->IsGenericParam() || typedVal.mType->IsValueType());
  10329. // Ref X to Ref Y, X* to Y*
  10330. {
  10331. bool checkUnderlying = false;
  10332. if (((typedVal.mType->IsRef()) && (toType->IsRef())))
  10333. {
  10334. auto fromRefType = (BfRefType*)typedVal.mType;
  10335. auto toRefType = (BfRefType*)toType;
  10336. if (fromRefType->mRefKind == toRefType->mRefKind)
  10337. checkUnderlying = true;
  10338. else if ((fromRefType->mRefKind == BfRefType::RefKind_Ref) && (toRefType->mRefKind == BfRefType::RefKind_Mut))
  10339. checkUnderlying = true; // Allow a ref-to-mut implicit conversion
  10340. }
  10341. if ((typedVal.mType->IsPointer()) && (toType->IsPointer()))
  10342. checkUnderlying = true;
  10343. if (checkUnderlying)
  10344. {
  10345. auto fromInner = typedVal.mType->GetUnderlyingType();
  10346. auto toInner = toType->GetUnderlyingType();
  10347. if (fromInner == toInner)
  10348. {
  10349. return typedVal.mValue;
  10350. }
  10351. if ((fromInner->IsTuple()) && (toInner->IsTuple()))
  10352. {
  10353. auto fromTuple = (BfTupleType*)fromInner;
  10354. auto toTuple = (BfTupleType*)toInner;
  10355. if (fromTuple->mFieldInstances.size() == toTuple->mFieldInstances.size())
  10356. {
  10357. bool matches = true;
  10358. for (int fieldIdx = 0; fieldIdx < (int)fromTuple->mFieldInstances.size(); fieldIdx++)
  10359. {
  10360. if (fromTuple->mFieldInstances[fieldIdx].mResolvedType != toTuple->mFieldInstances[fieldIdx].mResolvedType)
  10361. {
  10362. matches = false;
  10363. break;
  10364. }
  10365. }
  10366. if (matches)
  10367. {
  10368. // This is either a ref or a ptr so we don't need to set the "IsAddr" flag
  10369. typedVal = MakeAddressable(typedVal);
  10370. return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType));
  10371. }
  10372. }
  10373. }
  10374. // ref int <-> ref int64/int32 (of same size)
  10375. if (((fromInner->IsInteger()) && (toInner->IsInteger())) &&
  10376. (fromInner->mSize == toInner->mSize) &&
  10377. (fromInner->IsSigned() == toInner->IsSigned()))
  10378. return typedVal.mValue;
  10379. }
  10380. }
  10381. // Null -> ObjectInst|IFace|ptr
  10382. if ((typedVal.mType->IsNull()) &&
  10383. ((toType->IsObjectOrInterface()) || (toType->IsPointer() || (toType->IsFunction()) || (toType->IsAllocType()))))
  10384. {
  10385. return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType));
  10386. }
  10387. // Func -> void*
  10388. if ((typedVal.mType->IsFunction()) && (toType->IsVoidPtr()))
  10389. {
  10390. return mBfIRBuilder->CreateIntToPtr(typedVal.mValue, mBfIRBuilder->MapType(toType));
  10391. }
  10392. if (explicitCast)
  10393. {
  10394. // void* -> Func
  10395. if ((typedVal.mType->IsVoidPtr()) && (toType->IsFunction()))
  10396. {
  10397. return mBfIRBuilder->CreatePtrToInt(typedVal.mValue, BfTypeCode_IntPtr);
  10398. }
  10399. // * -> Valueless
  10400. if (toType->IsVoid())
  10401. return mBfIRBuilder->GetFakeVal();
  10402. // void* -> intptr
  10403. if ((typedVal.mType->IsPointer()) && (toType->IsIntPtr()))
  10404. {
  10405. if ((!typedVal.mType->GetUnderlyingType()->IsVoid()) && ((castFlags & BfCastFlags_FromCompiler) == 0))
  10406. {
  10407. if (!ignoreErrors)
  10408. Fail(StrFormat("Unable to cast directly from '%s' to '%s', consider casting to void* first", TypeToString(typedVal.mType).c_str(), TypeToString(toType).c_str()), srcNode);
  10409. else if (!silentFail)
  10410. SetFail();
  10411. }
  10412. auto toPrimitive = (BfPrimitiveType*)toType;
  10413. return mBfIRBuilder->CreatePtrToInt(typedVal.mValue, toPrimitive->mTypeDef->mTypeCode);
  10414. }
  10415. // intptr -> void*
  10416. if ((typedVal.mType->IsIntPtr()) && (toType->IsPointer()))
  10417. {
  10418. if ((!toType->GetUnderlyingType()->IsVoid()) && ((castFlags & BfCastFlags_FromCompiler) == 0))
  10419. {
  10420. if (!ignoreErrors)
  10421. Fail(StrFormat("Unable to cast directly from '%s' to '%s', consider casting to void* first", TypeToString(typedVal.mType).c_str(), TypeToString(toType).c_str()), srcNode);
  10422. else if (!silentFail)
  10423. SetFail();
  10424. }
  10425. return mBfIRBuilder->CreateIntToPtr(typedVal.mValue, mBfIRBuilder->MapType(toType));
  10426. }
  10427. }
  10428. // * <-> Var
  10429. if ((typedVal.mType->IsVar()) || (toType->IsVar()))
  10430. {
  10431. return mBfIRBuilder->CreateUndefValue(mBfIRBuilder->MapType(toType));
  10432. }
  10433. // Generic param -> *
  10434. if (typedVal.mType->IsGenericParam())
  10435. {
  10436. if (toType->IsGenericParam())
  10437. {
  10438. auto genericParamInst = GetGenericParamInstance((BfGenericParamType*)typedVal.mType);
  10439. if (genericParamInst->mTypeConstraint == toType)
  10440. return typedVal.mValue;
  10441. }
  10442. else
  10443. {
  10444. if ((typedVal.mKind != Beefy::BfTypedValueKind_GenericConstValue) && (toType == mContext->mBfObjectType))
  10445. {
  10446. // Always allow casting from generic to object
  10447. return typedVal.mValue;
  10448. }
  10449. auto _CheckGenericParamInstance = [&](BfGenericParamInstance* genericParamInst)
  10450. {
  10451. if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Var) != 0)
  10452. {
  10453. return typedVal.mValue;
  10454. }
  10455. if (toType->IsInterface())
  10456. {
  10457. for (auto iface : genericParamInst->mInterfaceConstraints)
  10458. if (TypeIsSubTypeOf(iface, toType->ToTypeInstance()))
  10459. return mBfIRBuilder->GetFakeVal();
  10460. }
  10461. if (genericParamInst->mTypeConstraint != NULL)
  10462. {
  10463. SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, true);
  10464. auto constraintTypeInst = genericParamInst->mTypeConstraint->ToTypeInstance();
  10465. if ((constraintTypeInst != NULL) && (constraintTypeInst->IsDelegateOrFunction()))
  10466. {
  10467. // Could be a methodref - can't cast to anything else
  10468. }
  10469. else
  10470. {
  10471. if ((constraintTypeInst != NULL) && (constraintTypeInst->IsInstanceOf(mCompiler->mEnumTypeDef)) && (explicitCast))
  10472. {
  10473. // Enum->int
  10474. if ((explicitCast) && (toType->IsInteger()))
  10475. return typedVal.mValue;
  10476. }
  10477. BfTypedValue fromTypedValue;
  10478. if (typedVal.mKind == BfTypedValueKind_GenericConstValue)
  10479. fromTypedValue = GetDefaultTypedValue(genericParamInst->mTypeConstraint, false, BfDefaultValueKind_Undef);
  10480. else
  10481. fromTypedValue = BfTypedValue(mBfIRBuilder->GetFakeVal(), genericParamInst->mTypeConstraint, genericParamInst->mTypeConstraint->IsValueType());
  10482. auto result = CastToValue(srcNode, fromTypedValue, toType, (BfCastFlags)(castFlags | BfCastFlags_SilentFail));
  10483. if (result)
  10484. {
  10485. if ((genericParamInst->mTypeConstraint->IsDelegate()) && (toType->IsDelegate()))
  10486. {
  10487. // Don't allow cast when we are constrained by a delegate type, because BfMethodRefs can match and we require an actual alloc
  10488. Fail(StrFormat("Unable to cast '%s' to '%s' because delegate constraints allow valueless direct method references", TypeToString(typedVal.mType).c_str(), TypeToString(toType).c_str()), srcNode);
  10489. return BfIRValue();
  10490. }
  10491. return result;
  10492. }
  10493. }
  10494. }
  10495. // Generic constrained with class or pointer type -> void*
  10496. if (toType->IsVoidPtr())
  10497. {
  10498. if (((genericParamInst->mGenericParamFlags & (BfGenericParamFlag_Class | BfGenericParamFlag_StructPtr | BfGenericParamFlag_Interface)) != 0) ||
  10499. ((genericParamInst->mTypeConstraint != NULL) &&
  10500. ((genericParamInst->mTypeConstraint->IsPointer()) ||
  10501. (genericParamInst->mTypeConstraint->IsInstanceOf(mCompiler->mFunctionTypeDef)) ||
  10502. (genericParamInst->mTypeConstraint->IsObjectOrInterface()))))
  10503. {
  10504. return typedVal.mValue;
  10505. }
  10506. }
  10507. if ((toType->IsInteger()) && (explicitCast))
  10508. {
  10509. if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Enum) != 0)
  10510. {
  10511. return typedVal.mValue;
  10512. }
  10513. }
  10514. return BfIRValue();
  10515. };
  10516. BfIRValue retVal;
  10517. // For these casts, it's just important we get *A* value to work with here,
  10518. // as this is just use for unspecialized parsing. We don't use the generated code
  10519. {
  10520. auto genericParamInst = GetGenericParamInstance((BfGenericParamType*)typedVal.mType);
  10521. retVal = _CheckGenericParamInstance(genericParamInst);
  10522. if (retVal)
  10523. return retVal;
  10524. }
  10525. // Check method generic constraints
  10526. if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mIsUnspecialized) && (mCurMethodInstance->mMethodInfoEx != NULL))
  10527. {
  10528. for (int genericParamIdx = (int)mCurMethodInstance->mMethodInfoEx->mMethodGenericArguments.size();
  10529. genericParamIdx < mCurMethodInstance->mMethodInfoEx->mGenericParams.size(); genericParamIdx++)
  10530. {
  10531. auto genericParamInst = mCurMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
  10532. if (genericParamInst->mExternType == typedVal.mType)
  10533. {
  10534. retVal = _CheckGenericParamInstance(genericParamInst);
  10535. if (retVal)
  10536. return retVal;
  10537. }
  10538. }
  10539. }
  10540. }
  10541. }
  10542. // * -> Generic param
  10543. if (toType->IsGenericParam())
  10544. {
  10545. if (explicitCast)
  10546. {
  10547. // Either an upcast or an unbox
  10548. if ((typedVal.mType == mContext->mBfObjectType) || (typedVal.mType->IsInterface()))
  10549. {
  10550. return GetDefaultValue(toType);
  10551. }
  10552. }
  10553. auto genericParamInst = GetGenericParamInstance((BfGenericParamType*)toType);
  10554. if (genericParamInst->mGenericParamFlags & BfGenericParamFlag_Var)
  10555. return GetDefaultValue(toType);
  10556. if (typedVal.mType->IsNull())
  10557. {
  10558. bool allowCast = (genericParamInst->mGenericParamFlags & (BfGenericParamFlag_Class | BfGenericParamFlag_StructPtr | BfGenericParamFlag_Interface)) != 0;
  10559. if ((!allowCast) && (genericParamInst->mTypeConstraint != NULL))
  10560. allowCast = genericParamInst->mTypeConstraint->IsObject() || genericParamInst->mTypeConstraint->IsPointer();
  10561. if (allowCast)
  10562. return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType));
  10563. }
  10564. if (genericParamInst->mTypeConstraint != NULL)
  10565. {
  10566. if (genericParamInst->mTypeConstraint->IsInstanceOf(mCompiler->mEnumTypeDef))
  10567. {
  10568. // int->Enum
  10569. if ((explicitCast) && (typedVal.mType->IsInteger()))
  10570. return mBfIRBuilder->GetFakeVal();
  10571. }
  10572. if ((genericParamInst->mTypeConstraint == toType) && (toType->IsUnspecializedType()))
  10573. return mBfIRBuilder->GetFakeVal();
  10574. auto castedVal = CastToValue(srcNode, typedVal, genericParamInst->mTypeConstraint, (BfCastFlags)(castFlags | BfCastFlags_SilentFail));
  10575. if (castedVal)
  10576. return castedVal;
  10577. }
  10578. if (explicitCast)
  10579. {
  10580. if (((genericParamInst->mGenericParamFlags & BfGenericParamFlag_StructPtr) != 0) ||
  10581. ((genericParamInst->mTypeConstraint != NULL) && genericParamInst->mTypeConstraint->IsInstanceOf(mCompiler->mFunctionTypeDef)))
  10582. {
  10583. auto voidPtrType = CreatePointerType(GetPrimitiveType(BfTypeCode_None));
  10584. auto castedVal = CastToValue(srcNode, typedVal, voidPtrType, (BfCastFlags)(castFlags | BfCastFlags_SilentFail));
  10585. if (castedVal)
  10586. return castedVal;
  10587. }
  10588. }
  10589. if ((typedVal.mType->IsIntegral()) && ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Enum) != 0))
  10590. {
  10591. bool allowCast = explicitCast;
  10592. if ((!allowCast) && (typedVal.mType->IsIntegral()))
  10593. {
  10594. // Allow implicit cast of zero
  10595. auto constant = mBfIRBuilder->GetConstant(typedVal.mValue);
  10596. if ((constant != NULL) && (mBfIRBuilder->IsInt(constant->mTypeCode)))
  10597. {
  10598. allowCast = constant->mInt64 == 0;
  10599. }
  10600. }
  10601. if (allowCast)
  10602. {
  10603. return mBfIRBuilder->GetFakeVal();
  10604. }
  10605. }
  10606. }
  10607. if ((typedVal.mType->IsTypeInstance()) && (toType->IsTypeInstance()))
  10608. {
  10609. auto fromTypeInstance = typedVal.mType->ToTypeInstance();
  10610. auto toTypeInstance = toType->ToTypeInstance();
  10611. if ((typedVal.mType->IsValueType()) && (toType->IsValueType()))
  10612. {
  10613. bool allowCast = false;
  10614. if (TypeIsSubTypeOf(fromTypeInstance, toTypeInstance))
  10615. allowCast = true;
  10616. if (allowCast)
  10617. {
  10618. PopulateType(toType);
  10619. if (toType->IsValuelessType())
  10620. return BfIRValue::sValueless;
  10621. if (ignoreWrites)
  10622. return mBfIRBuilder->GetFakeVal();
  10623. if (resultFlags != NULL)
  10624. *resultFlags = (BfCastResultFlags)(BfCastResultFlags_IsAddr);
  10625. typedVal = MakeAddressable(typedVal);
  10626. return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapTypeInstPtr(toTypeInstance));
  10627. }
  10628. }
  10629. // ObjectInst|IFace -> object|IFace
  10630. if ((typedVal.mType->IsObject() || (typedVal.mType->IsInterface())) && ((toType->IsObject() || (toType->IsInterface()))))
  10631. {
  10632. bool allowCast = false;
  10633. if (((castFlags & BfCastFlags_NoInterfaceImpl) != 0) && (toTypeInstance->IsInterface()))
  10634. {
  10635. // Don't allow
  10636. }
  10637. else if (TypeIsSubTypeOf(fromTypeInstance, toTypeInstance))
  10638. allowCast = true;
  10639. else if ((explicitCast) &&
  10640. ((toType->IsInterface()) || (TypeIsSubTypeOf(toTypeInstance, fromTypeInstance))))
  10641. {
  10642. if (toType->IsObjectOrInterface())
  10643. {
  10644. if ((castFlags & BfCastFlags_Unchecked) == 0)
  10645. EmitDynamicCastCheck(typedVal, toType, true);
  10646. }
  10647. allowCast = true;
  10648. }
  10649. if (allowCast)
  10650. {
  10651. if ((ignoreWrites) && (!typedVal.mValue.IsConst()))
  10652. return mBfIRBuilder->GetFakeVal();
  10653. return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType));
  10654. }
  10655. }
  10656. }
  10657. // MethodRef -> Function
  10658. if ((typedVal.mType->IsMethodRef()) && (toType->IsFunction()))
  10659. {
  10660. BfMethodInstance* methodInstance = ((BfMethodRefType*)typedVal.mType)->mMethodRef;
  10661. auto result = CastToFunction(srcNode, BfTypedValue(), methodInstance, toType, castFlags);
  10662. if (result)
  10663. return result;
  10664. }
  10665. // concrete IFace -> object|IFace
  10666. if ((typedVal.mType->IsConcreteInterfaceType()) && ((toType->IsObject() || (toType->IsInterface()))))
  10667. {
  10668. auto concreteInterfaceType = (BfConcreteInterfaceType*)typedVal.mType;
  10669. if ((toType->IsObject()) || (concreteInterfaceType->mInterface == toType))
  10670. return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType));
  10671. }
  10672. // IFace -> object
  10673. if ((typedVal.mType->IsInterface()) && (toType == mContext->mBfObjectType))
  10674. return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType));
  10675. // * -> Pointer
  10676. if (toType->IsPointer())
  10677. {
  10678. // Ptr -> Ptr
  10679. if (typedVal.mType->IsPointer())
  10680. {
  10681. bool allowCast = explicitCast;
  10682. auto fromPointerType = (BfPointerType*)typedVal.mType;
  10683. auto toPointerType = (BfPointerType*)toType;
  10684. auto fromUnderlying = fromPointerType->mElementType;
  10685. auto toUnderlying = toPointerType->mElementType;
  10686. // Allow cast from T[size]* to T* implicitly
  10687. // And from T* to T[size]* explicitly
  10688. while (fromUnderlying->IsSizedArray())
  10689. fromUnderlying = fromUnderlying->GetUnderlyingType();
  10690. while ((toUnderlying->IsSizedArray()) && (explicitCast))
  10691. toUnderlying = toUnderlying->GetUnderlyingType();
  10692. if ((fromUnderlying == toUnderlying) ||
  10693. (TypeIsSubTypeOf(fromUnderlying->ToTypeInstance(), toUnderlying->ToTypeInstance())) ||
  10694. (toUnderlying->IsVoid()))
  10695. allowCast = true;
  10696. if (allowCast)
  10697. {
  10698. if ((ignoreWrites) && (!typedVal.mValue.IsConst()))
  10699. return mBfIRBuilder->GetFakeVal();
  10700. return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType));
  10701. }
  10702. }
  10703. else if (typedVal.mType->IsObject())
  10704. {
  10705. // ???
  10706. }
  10707. /*else if (typedVal.mType->IsSizedArray())
  10708. {
  10709. if (typedVal.IsAddr())
  10710. {
  10711. BfSizedArrayType* arrayType = (BfSizedArrayType*)typedVal.mType;
  10712. auto ptrType = CreatePointerType(arrayType->mElementType);
  10713. BfTypedValue returnPointer(mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(ptrType)), ptrType);
  10714. return CastToValue(srcNode, returnPointer, toType, castFlags, silentFail);
  10715. }
  10716. }*/
  10717. }
  10718. // Boxing?
  10719. bool mayBeBox = false;
  10720. if (((typedVal.mType->IsValueType()) || (typedVal.mType->IsPointer()) || (typedVal.mType->IsValuelessType())) &&
  10721. ((toType->IsInterface()) || (toType == mContext->mBfObjectType)))
  10722. {
  10723. // Make sure there's no conversion operator before we box
  10724. if ((!typedVal.mType->IsRef()) && (!typedVal.mType->IsModifiedTypeType()))
  10725. mayBeBox = true;
  10726. }
  10727. //TODO: the IsGenericParam is not valid - why did we have that? The generic param could be a struct for example...
  10728. if ((explicitCast) && ((typedVal.mType->IsInterface()) || (typedVal.mType == mContext->mBfObjectType) /*|| (typedVal.mType->IsGenericParam())*/) &&
  10729. ((toType->IsValueType()) || (toType->IsPointer())))
  10730. {
  10731. if (toType->IsValuelessType())
  10732. return BfIRValue::sValueless;
  10733. if (ignoreWrites)
  10734. return mBfIRBuilder->GetFakeVal();
  10735. // Unbox!
  10736. if ((castFlags & BfCastFlags_Unchecked) == 0)
  10737. {
  10738. EmitDynamicCastCheck(typedVal, toType, false);
  10739. EmitObjectAccessCheck(typedVal);
  10740. }
  10741. if (toType->IsNullable())
  10742. {
  10743. auto toTypeInst = toType->ToTypeInstance();
  10744. int valueIdx = toTypeInst->mFieldInstances[0].mDataIdx;
  10745. int hasValueIdx = toTypeInst->mFieldInstances[1].mDataIdx;
  10746. typedVal = MakeAddressable(typedVal);
  10747. auto elementType = toType->GetUnderlyingType();
  10748. auto ptrElementType = CreatePointerType(elementType);
  10749. auto boolType = GetPrimitiveType(BfTypeCode_Boolean);
  10750. auto allocaInst = CreateAlloca(toType, true, "unboxN");
  10751. auto prevBB = mBfIRBuilder->GetInsertBlock();
  10752. auto nullBB = mBfIRBuilder->CreateBlock("unboxN.null");
  10753. auto notNullBB = mBfIRBuilder->CreateBlock("unboxN.notNull");
  10754. auto endBB = mBfIRBuilder->CreateBlock("unboxN.end");
  10755. auto isNull = mBfIRBuilder->CreateIsNull(typedVal.mValue);
  10756. mBfIRBuilder->CreateCondBr(isNull, nullBB, notNullBB);
  10757. int dataIdx = toTypeInst->mFieldInstances[1].mDataIdx;
  10758. mBfIRBuilder->AddBlock(nullBB);
  10759. mBfIRBuilder->SetInsertPoint(nullBB);
  10760. auto hasValueAddr = mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, hasValueIdx); // has_value
  10761. mBfIRBuilder->CreateStore(GetConstValue(0, boolType), hasValueAddr);
  10762. auto nullableValueAddr = mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, valueIdx); // value
  10763. auto nullableValueBits = mBfIRBuilder->CreateBitCast(nullableValueAddr, mBfIRBuilder->GetPrimitiveType(BfTypeCode_NullPtr));
  10764. mBfIRBuilder->CreateMemSet(nullableValueBits, GetConstValue(0, GetPrimitiveType(BfTypeCode_Int8)), GetConstValue(elementType->mSize), elementType->mAlign);
  10765. mBfIRBuilder->CreateBr(endBB);
  10766. mBfIRBuilder->AddBlock(notNullBB);
  10767. mBfIRBuilder->SetInsertPoint(notNullBB);
  10768. hasValueAddr = mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, hasValueIdx); // has_value
  10769. mBfIRBuilder->CreateStore(GetConstValue(1, boolType), hasValueAddr);
  10770. nullableValueAddr = mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, valueIdx); // value
  10771. auto srcObjBits = mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(ptrElementType));
  10772. auto boxedValueAddr = mBfIRBuilder->CreateInBoundsGEP(srcObjBits, 1); // Skip over vdata
  10773. auto boxedValue = mBfIRBuilder->CreateLoad(boxedValueAddr);
  10774. mBfIRBuilder->CreateStore(boxedValue, nullableValueAddr);
  10775. mBfIRBuilder->CreateBr(endBB);
  10776. mBfIRBuilder->AddBlock(endBB);
  10777. mBfIRBuilder->SetInsertPoint(endBB);
  10778. if (resultFlags != NULL)
  10779. *resultFlags = (BfCastResultFlags)(BfCastResultFlags_IsAddr | BfCastResultFlags_IsTemp);
  10780. return allocaInst;
  10781. }
  10782. auto boxedType = CreateBoxedType(toType);
  10783. mBfIRBuilder->PopulateType(boxedType);
  10784. AddDependency(boxedType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields);
  10785. auto boxedObj = mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(boxedType));
  10786. auto valPtr = mBfIRBuilder->CreateInBoundsGEP(boxedObj, 0, 1);
  10787. if ((toType->IsPrimitiveType()) || (toType->IsTypedPrimitive()) || (toType->IsPointer()) || (toType->IsSizedArray()) || (toType->IsMethodRef()))
  10788. {
  10789. valPtr = mBfIRBuilder->CreateBitCast(valPtr, mBfIRBuilder->GetPointerTo(mBfIRBuilder->MapType(toType)));
  10790. }
  10791. if ((toType->IsComposite()) && (resultFlags != NULL))
  10792. {
  10793. *resultFlags = BfCastResultFlags_IsAddr;
  10794. return valPtr;
  10795. }
  10796. else
  10797. return mBfIRBuilder->CreateLoad(valPtr, false);
  10798. }
  10799. // Null -> Nullable<T>
  10800. if ((typedVal.mType->IsNull()) && (toType->IsNullable()))
  10801. {
  10802. if (ignoreWrites)
  10803. return mBfIRBuilder->GetFakeVal();
  10804. if ((castFlags & BfCastFlags_PreferAddr) != 0)
  10805. {
  10806. auto boolType = GetPrimitiveType(BfTypeCode_Boolean);
  10807. auto toTypeInst = toType->ToTypeInstance();
  10808. int hasValueIdx = toTypeInst->mFieldInstances[1].mDataIdx;
  10809. auto allocaInst = CreateAlloca(toType);
  10810. auto hasValueAddr = mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, hasValueIdx); // has_value
  10811. mBfIRBuilder->CreateStore(GetConstValue(0, boolType), hasValueAddr);
  10812. auto typedValue = BfTypedValue(allocaInst, toType, true);
  10813. if (resultFlags != NULL)
  10814. *resultFlags = (BfCastResultFlags)(BfCastResultFlags_IsAddr | BfCastResultFlags_IsTemp);
  10815. return allocaInst;
  10816. }
  10817. auto zeroNullable = mBfIRBuilder->CreateConstAggZero(mBfIRBuilder->MapType(toType));
  10818. return zeroNullable;
  10819. }
  10820. // Nullable<A> -> Nullable<B>
  10821. if ((typedVal.mType->IsNullable()) && (toType->IsNullable()))
  10822. {
  10823. auto fromNullableType = (BfTypeInstance*)typedVal.mType;
  10824. auto toNullableType = (BfTypeInstance*)toType;
  10825. if (ignoreWrites)
  10826. {
  10827. auto toVal = CastToValue(srcNode, BfTypedValue(mBfIRBuilder->GetFakeVal(), fromNullableType->mGenericTypeInfo->mTypeGenericArguments[0]),
  10828. toNullableType->mGenericTypeInfo->mTypeGenericArguments[0], ignoreErrors ? BfCastFlags_SilentFail : BfCastFlags_None);
  10829. if (!toVal)
  10830. return BfIRValue();
  10831. return mBfIRBuilder->GetFakeVal();
  10832. }
  10833. BfIRValue srcPtr = typedVal.mValue;
  10834. if (!typedVal.IsAddr())
  10835. {
  10836. auto srcAlloca = CreateAllocaInst(fromNullableType);
  10837. mBfIRBuilder->CreateStore(typedVal.mValue, srcAlloca);
  10838. srcPtr = srcAlloca;
  10839. }
  10840. auto srcAddr = mBfIRBuilder->CreateInBoundsGEP(srcPtr, 0, 1); // mValue
  10841. auto srcVal = mBfIRBuilder->CreateLoad(srcAddr);
  10842. auto toVal = CastToValue(srcNode, BfTypedValue(srcVal, fromNullableType->mGenericTypeInfo->mTypeGenericArguments[0]),
  10843. toNullableType->mGenericTypeInfo->mTypeGenericArguments[0], ignoreErrors ? BfCastFlags_SilentFail : BfCastFlags_None);
  10844. if (!toVal)
  10845. return BfIRValue();
  10846. auto allocaInst = CreateAllocaInst(toNullableType);
  10847. auto destAddr = mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, 1); // mValue
  10848. mBfIRBuilder->CreateStore(toVal, destAddr);
  10849. srcAddr = mBfIRBuilder->CreateInBoundsGEP(srcPtr, 0, 2); // mHasValue
  10850. srcVal = mBfIRBuilder->CreateLoad(srcAddr);
  10851. destAddr = mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, 2); // mHasValue
  10852. mBfIRBuilder->CreateStore(srcVal, destAddr);
  10853. if (resultFlags != NULL)
  10854. *resultFlags = (BfCastResultFlags)(BfCastResultFlags_IsAddr | BfCastResultFlags_IsTemp);
  10855. return allocaInst;
  10856. }
  10857. // Tuple -> Tuple
  10858. if ((typedVal.mType->IsTuple()) && (toType->IsTuple()))
  10859. {
  10860. auto fromTupleType = (BfTypeInstance*)typedVal.mType;
  10861. auto toTupleType = (BfTypeInstance*)toType;
  10862. PopulateType(fromTupleType);
  10863. PopulateType(toTupleType);
  10864. if (fromTupleType->mFieldInstances.size() == toTupleType->mFieldInstances.size())
  10865. {
  10866. typedVal = LoadValue(typedVal);
  10867. BfIRValue curTupleValue = mBfIRBuilder->CreateUndefValue(mBfIRBuilder->MapType(toTupleType));
  10868. for (int valueIdx = 0; valueIdx < (int)fromTupleType->mFieldInstances.size(); valueIdx++)
  10869. {
  10870. BfFieldInstance* fromFieldInstance = &fromTupleType->mFieldInstances[valueIdx];
  10871. BfFieldInstance* toFieldInstance = &toTupleType->mFieldInstances[valueIdx];
  10872. if (!explicitCast)
  10873. {
  10874. BfFieldDef* fromFieldDef = fromFieldInstance->GetFieldDef();
  10875. BfFieldDef* toFieldDef = toFieldInstance->GetFieldDef();
  10876. // Either the names have to match or one has to be unnamed
  10877. if ((!fromFieldDef->IsUnnamedTupleField()) && (!toFieldDef->IsUnnamedTupleField()) &&
  10878. (fromFieldDef->mName != toFieldDef->mName))
  10879. {
  10880. curTupleValue = BfIRValue();
  10881. break;
  10882. }
  10883. }
  10884. auto fromFieldType = fromFieldInstance->GetResolvedType();
  10885. auto toFieldType = toFieldInstance->GetResolvedType();
  10886. if (toFieldType->IsVoid())
  10887. continue; // Allow sinking to void
  10888. BfIRValue fromFieldValue;
  10889. if (fromFieldInstance->mDataIdx >= 0)
  10890. fromFieldValue = mBfIRBuilder->CreateExtractValue(typedVal.mValue, fromFieldInstance->mDataIdx);
  10891. BfIRValue toFieldValue = CastToValue(srcNode, BfTypedValue(fromFieldValue, fromFieldType), toFieldType, (BfCastFlags)(castFlags | BfCastFlags_Explicit));
  10892. if (!toFieldValue)
  10893. {
  10894. curTupleValue = BfIRValue();
  10895. break;
  10896. }
  10897. if (toFieldInstance->mDataIdx >= 0)
  10898. curTupleValue = mBfIRBuilder->CreateInsertValue(curTupleValue, toFieldValue, toFieldInstance->mDataIdx);
  10899. }
  10900. if (curTupleValue)
  10901. return curTupleValue;
  10902. }
  10903. }
  10904. // -> const <value>
  10905. if (toType->IsConstExprValue())
  10906. {
  10907. auto constant = mBfIRBuilder->GetConstant(typedVal.mValue);
  10908. if (constant != NULL)
  10909. {
  10910. BfConstExprValueType* toConstExprValueType = (BfConstExprValueType*)toType;
  10911. auto variantVal = TypedValueToVariant(srcNode, typedVal);
  10912. if ((mBfIRBuilder->IsInt(variantVal.mTypeCode)) && (mBfIRBuilder->IsInt(toConstExprValueType->mValue.mTypeCode)))
  10913. {
  10914. if (variantVal.mInt64 == toConstExprValueType->mValue.mInt64)
  10915. return typedVal.mValue;
  10916. }
  10917. else if ((mBfIRBuilder->IsFloat(variantVal.mTypeCode)) && (mBfIRBuilder->IsFloat(toConstExprValueType->mValue.mTypeCode)))
  10918. {
  10919. if (variantVal.ToDouble() == toConstExprValueType->mValue.ToDouble())
  10920. return typedVal.mValue;
  10921. }
  10922. if (toConstExprValueType->mValue.mTypeCode == BfTypeCode_StringId)
  10923. {
  10924. int stringIdx = GetStringPoolIdx(typedVal.mValue, mBfIRBuilder);
  10925. if ((stringIdx != -1) && (stringIdx == toConstExprValueType->mValue.mInt32))
  10926. return typedVal.mValue;
  10927. }
  10928. if (!ignoreErrors)
  10929. {
  10930. String valStr;
  10931. VariantToString(valStr, variantVal);
  10932. Fail(StrFormat("Unable to cast '%s %s' to '%s'", TypeToString(typedVal.mType).c_str(), valStr.c_str(), TypeToString(toType).c_str()), srcNode);
  10933. }
  10934. else if (!silentFail)
  10935. SetFail();
  10936. }
  10937. }
  10938. if ((typedVal.mType->IsPrimitiveType()) && (toType->IsPrimitiveType()))
  10939. {
  10940. auto fromPrimType = (BfPrimitiveType*)typedVal.mType;
  10941. auto toPrimType = (BfPrimitiveType*)toType;
  10942. BfTypeCode fromTypeCode = fromPrimType->mTypeDef->mTypeCode;
  10943. BfTypeCode toTypeCode = toPrimType->mTypeDef->mTypeCode;
  10944. if (toType->IsIntegral())
  10945. {
  10946. // Allow constant ints to be implicitly casted to a smaller type if they fit
  10947. auto constant = mBfIRBuilder->GetConstant(typedVal.mValue);
  10948. if (constant != NULL)
  10949. {
  10950. if (mBfIRBuilder->IsInt(constant->mTypeCode))
  10951. {
  10952. int64 srcVal = constant->mInt64;
  10953. if (toPrimType->IsChar())
  10954. {
  10955. if (srcVal == 0)
  10956. explicitCast = true;
  10957. }
  10958. else if ((fromPrimType->IsChar()) && (!toPrimType->IsChar()))
  10959. {
  10960. // Never allow this
  10961. }
  10962. else if ((constant->mTypeCode == BfTypeCode_UInt64) && (srcVal < 0))
  10963. {
  10964. // There's nothing that this could fit into
  10965. }
  10966. else if (toType->IsSigned())
  10967. {
  10968. if (toType->mSize == 8) // int64
  10969. explicitCast = true;
  10970. else
  10971. {
  10972. int64 minVal = -(1LL << (8 * toType->mSize - 1));
  10973. int64 maxVal = (1LL << (8 * toType->mSize - 1)) - 1;
  10974. if ((srcVal >= minVal) && (srcVal <= maxVal))
  10975. explicitCast = true;
  10976. }
  10977. }
  10978. else if (toType->mSize == 8) // uint64
  10979. {
  10980. if (srcVal >= 0)
  10981. explicitCast = true;
  10982. }
  10983. else
  10984. {
  10985. int64 minVal = 0;
  10986. int64 maxVal = (1LL << (8 * toType->mSize)) - 1;
  10987. if ((srcVal >= minVal) && (srcVal <= maxVal))
  10988. explicitCast = true;
  10989. }
  10990. }
  10991. else if (constant->mConstType == BfConstType_Undef)
  10992. {
  10993. if (mIsComptimeModule)
  10994. return mBfIRBuilder->GetUndefConstValue(mBfIRBuilder->MapType(toType));
  10995. BF_ASSERT(mBfIRBuilder->mIgnoreWrites);
  10996. auto undefConst = (BfConstantUndef*)constant;
  10997. BF_ASSERT(undefConst->mType.mKind == BfIRTypeData::TypeKind_TypeId);
  10998. auto bfType = mContext->mTypes[undefConst->mType.mId];
  10999. auto fakeVal = GetFakeTypedValue(bfType);
  11000. auto val = CastToValue(srcNode, fakeVal, toType, castFlags);
  11001. if (val)
  11002. return mBfIRBuilder->GetUndefConstValue(mBfIRBuilder->MapType(toType));
  11003. }
  11004. }
  11005. }
  11006. bool allowCast = false;
  11007. switch (toTypeCode)
  11008. {
  11009. case BfTypeCode_Char16:
  11010. switch (fromTypeCode)
  11011. {
  11012. case BfTypeCode_Char8:
  11013. allowCast = true; break;
  11014. default: break;
  11015. }
  11016. break;
  11017. case BfTypeCode_Int16:
  11018. switch (fromTypeCode)
  11019. {
  11020. case BfTypeCode_Int8:
  11021. allowCast = true; break;
  11022. case BfTypeCode_UInt8:
  11023. allowCast = true; break;
  11024. default: break;
  11025. }
  11026. break;
  11027. case BfTypeCode_UInt16:
  11028. switch (fromTypeCode)
  11029. {
  11030. case BfTypeCode_UInt8:
  11031. allowCast = true; break;
  11032. default: break;
  11033. }
  11034. break;
  11035. case BfTypeCode_Int32:
  11036. switch (fromTypeCode)
  11037. {
  11038. case BfTypeCode_Int8:
  11039. case BfTypeCode_Int16:
  11040. allowCast = true; break;
  11041. case BfTypeCode_IntPtr:
  11042. if (mCompiler->mSystem->mPtrSize == 4)
  11043. allowCast = true;
  11044. break;
  11045. case BfTypeCode_UInt8:
  11046. case BfTypeCode_UInt16:
  11047. allowCast = true; break;
  11048. default: break;
  11049. }
  11050. break;
  11051. case BfTypeCode_Char32:
  11052. switch (fromTypeCode)
  11053. {
  11054. case BfTypeCode_Char8:
  11055. case BfTypeCode_Char16:
  11056. allowCast = true; break;
  11057. default: break;
  11058. }
  11059. break;
  11060. case BfTypeCode_UInt32:
  11061. switch (fromTypeCode)
  11062. {
  11063. case BfTypeCode_UInt8:
  11064. case BfTypeCode_UInt16:
  11065. case BfTypeCode_UInt32:
  11066. allowCast = true; break;
  11067. case BfTypeCode_UIntPtr:
  11068. if (mCompiler->mSystem->mPtrSize == 4)
  11069. allowCast = true;
  11070. break;
  11071. default: break;
  11072. }
  11073. break;
  11074. case BfTypeCode_Int64:
  11075. switch (fromTypeCode)
  11076. {
  11077. case BfTypeCode_Int8:
  11078. case BfTypeCode_Int16:
  11079. case BfTypeCode_Int32:
  11080. case BfTypeCode_IntPtr:
  11081. allowCast = true; break;
  11082. case BfTypeCode_UInt8:
  11083. case BfTypeCode_UInt16:
  11084. case BfTypeCode_UInt32:
  11085. allowCast = true; break;
  11086. default: break;
  11087. }
  11088. break;
  11089. case BfTypeCode_UInt64:
  11090. switch (fromTypeCode)
  11091. {
  11092. case BfTypeCode_UInt8:
  11093. case BfTypeCode_UInt16:
  11094. case BfTypeCode_UInt32:
  11095. case BfTypeCode_UIntPtr:
  11096. allowCast = true; break;
  11097. default: break;
  11098. }
  11099. break;
  11100. case BfTypeCode_IntPtr:
  11101. switch (fromTypeCode)
  11102. {
  11103. case BfTypeCode_Int8:
  11104. case BfTypeCode_Int16:
  11105. case BfTypeCode_Int32:
  11106. allowCast = true; break;
  11107. case BfTypeCode_UInt8:
  11108. case BfTypeCode_UInt16:
  11109. allowCast = true; break;
  11110. case BfTypeCode_UInt32:
  11111. case BfTypeCode_Int64:
  11112. // It may seem that we want this to require an explicit cast,
  11113. // but consider the case of
  11114. // int val = Math.Max(intA, intB)
  11115. // Math.Max has an int32 and int64 override, so we want the correct one to be chosen and
  11116. // to be able to have the int64 return value implicitly used in a 64-bit build
  11117. if (mCompiler->mSystem->mPtrSize == 8)
  11118. allowCast = true;
  11119. break;
  11120. default: break;
  11121. }
  11122. break;
  11123. case BfTypeCode_UIntPtr:
  11124. switch (fromTypeCode)
  11125. {
  11126. case BfTypeCode_UInt8:
  11127. case BfTypeCode_UInt16:
  11128. case BfTypeCode_UInt32:
  11129. allowCast = true; break;
  11130. case BfTypeCode_UInt64:
  11131. if (mCompiler->mSystem->mPtrSize == 8)
  11132. allowCast = true;
  11133. break;
  11134. default: break;
  11135. }
  11136. break;
  11137. case BfTypeCode_Float:
  11138. switch (fromTypeCode)
  11139. {
  11140. case BfTypeCode_Int8:
  11141. case BfTypeCode_Int16:
  11142. case BfTypeCode_Int32:
  11143. case BfTypeCode_Int64:
  11144. case BfTypeCode_IntPtr:
  11145. case BfTypeCode_IntUnknown:
  11146. allowCast = true; break;
  11147. case BfTypeCode_UInt8:
  11148. case BfTypeCode_UInt16:
  11149. case BfTypeCode_UInt32:
  11150. case BfTypeCode_UInt64:
  11151. case BfTypeCode_UIntPtr:
  11152. case BfTypeCode_UIntUnknown:
  11153. allowCast = true; break;
  11154. default: break;
  11155. }
  11156. break;
  11157. case BfTypeCode_Double:
  11158. switch (fromTypeCode)
  11159. {
  11160. case BfTypeCode_Int8:
  11161. case BfTypeCode_Int16:
  11162. case BfTypeCode_Int32:
  11163. case BfTypeCode_Int64:
  11164. case BfTypeCode_IntPtr:
  11165. case BfTypeCode_IntUnknown:
  11166. allowCast = true; break;
  11167. case BfTypeCode_UInt8:
  11168. case BfTypeCode_UInt16:
  11169. case BfTypeCode_UInt32:
  11170. case BfTypeCode_UInt64:
  11171. case BfTypeCode_UIntPtr:
  11172. case BfTypeCode_UIntUnknown:
  11173. allowCast = true; break;
  11174. case BfTypeCode_Float:
  11175. allowCast = true; break;
  11176. default: break;
  11177. }
  11178. break;
  11179. default: break;
  11180. }
  11181. if (explicitCast)
  11182. {
  11183. if (((fromPrimType->IsIntegral()) || (fromPrimType->IsFloat())) &&
  11184. ((toType->IsIntegral()) || (toType->IsFloat())))
  11185. allowCast = true;
  11186. }
  11187. if (allowCast)
  11188. {
  11189. if (typedVal.IsAddr())
  11190. typedVal = LoadValue(typedVal);
  11191. return mBfIRBuilder->CreateNumericCast(typedVal.mValue, typedVal.mType->IsSigned(), toTypeCode);
  11192. }
  11193. }
  11194. if (typedVal.mValue.IsConst())
  11195. {
  11196. if ((toType->IsPointer()) && (toType->GetUnderlyingType() == GetPrimitiveType(BfTypeCode_Char8)) && (typedVal.mType->IsInstanceOf(mCompiler->mStringTypeDef)))
  11197. {
  11198. int stringId = GetStringPoolIdx(typedVal.mValue, mBfIRBuilder);
  11199. if (stringId >= 0)
  11200. return GetStringCharPtr(stringId);
  11201. }
  11202. else if ((toType->IsInstanceOf(mCompiler->mStringViewTypeDef)))
  11203. {
  11204. int stringId = GetStringPoolIdx(typedVal.mValue, mBfIRBuilder);
  11205. bool isNull = false;
  11206. auto constant = mBfIRBuilder->GetConstant(typedVal.mValue);
  11207. if (constant->mTypeCode == BfTypeCode_NullPtr)
  11208. isNull = true;
  11209. if ((stringId >= 0) || (isNull))
  11210. {
  11211. int strLen = 0;
  11212. String str;
  11213. BfStringPoolEntry* entry = NULL;
  11214. if ((isNull) || (mContext->mStringObjectIdMap.TryGetValue(stringId, &entry)))
  11215. {
  11216. auto svTypeInst = toType->ToTypeInstance();
  11217. PopulateType(svTypeInst);
  11218. PopulateType(svTypeInst->mBaseType);
  11219. mBfIRBuilder->PopulateType(svTypeInst);
  11220. SizedArray<BfIRValue, 2> spanFieldVals;
  11221. spanFieldVals.Add(mBfIRBuilder->CreateConstAggZero(mBfIRBuilder->MapType(svTypeInst->mBaseType->mBaseType)));
  11222. if (isNull)
  11223. {
  11224. spanFieldVals.Add(mBfIRBuilder->CreateConstNull());
  11225. spanFieldVals.Add(mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0));
  11226. }
  11227. else
  11228. {
  11229. auto stringCharPtr = GetStringCharPtr(stringId);
  11230. spanFieldVals.Add(stringCharPtr);
  11231. spanFieldVals.Add(mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, entry->mString.mLength));
  11232. }
  11233. SizedArray<BfIRValue, 2> svFieldVals;
  11234. svFieldVals.Add(mBfIRBuilder->CreateConstAgg(mBfIRBuilder->MapType(svTypeInst->mBaseType), spanFieldVals));
  11235. return mBfIRBuilder->CreateConstAgg(mBfIRBuilder->MapType(svTypeInst), svFieldVals);
  11236. }
  11237. }
  11238. }
  11239. }
  11240. // Check user-defined operators
  11241. if (((castFlags & BfCastFlags_NoConversionOperator) == 0) && (toType != mContext->mBfObjectType))
  11242. {
  11243. BfType* walkFromType = typedVal.mType;
  11244. if (walkFromType->IsWrappableType())
  11245. walkFromType = GetWrappedStructType(walkFromType);
  11246. BfType* walkToType = toType;
  11247. if (walkToType->IsWrappableType())
  11248. walkToType = GetWrappedStructType(walkToType);
  11249. SizedArray<BfResolvedArg, 1> args;
  11250. BfResolvedArg resolvedArg;
  11251. resolvedArg.mTypedValue = typedVal;
  11252. if (resolvedArg.mTypedValue.IsParams())
  11253. {
  11254. resolvedArg.mTypedValue = LoadOrAggregateValue(resolvedArg.mTypedValue);
  11255. resolvedArg.mTypedValue.mKind = BfTypedValueKind_Value;
  11256. }
  11257. args.push_back(resolvedArg);
  11258. BfMethodMatcher methodMatcher(srcNode, this, "", args, BfMethodGenericArguments());
  11259. methodMatcher.mCheckReturnType = toType;
  11260. methodMatcher.mBfEvalExprFlags = (BfEvalExprFlags)(BfEvalExprFlags_NoAutoComplete | BfEvalExprFlags_FromConversionOp);
  11261. if ((castFlags & BfCastFlags_Explicit) != 0)
  11262. methodMatcher.mBfEvalExprFlags = (BfEvalExprFlags)(methodMatcher.mBfEvalExprFlags | BfEvalExprFlags_FromConversionOp_Explicit);
  11263. methodMatcher.mAllowImplicitRef = true;
  11264. methodMatcher.mAllowImplicitWrap = true;
  11265. BfBaseClassWalker baseClassWalker(walkFromType, walkToType, this);
  11266. bool isConstraintCheck = ((castFlags & BfCastFlags_IsConstraintCheck) != 0);
  11267. BfType* operatorConstraintReturnType = NULL;
  11268. BfType* bestSelfType = NULL;
  11269. while (true)
  11270. {
  11271. auto entry = baseClassWalker.Next();
  11272. auto checkType = entry.mTypeInstance;
  11273. if (checkType == NULL)
  11274. break;
  11275. for (auto operatorDef : checkType->mTypeDef->mOperators)
  11276. {
  11277. if (operatorDef->mOperatorDeclaration->mIsConvOperator)
  11278. {
  11279. if ((!explicitCast) && (operatorDef->IsExplicit()))
  11280. continue;
  11281. if (!methodMatcher.IsMemberAccessible(checkType, operatorDef->mDeclaringType))
  11282. continue;
  11283. int prevArgSize = (int)args.mSize;
  11284. if (!operatorDef->mIsStatic)
  11285. {
  11286. // Try without arg
  11287. args.mSize = 0;
  11288. }
  11289. if (isConstraintCheck)
  11290. {
  11291. auto returnType = CheckOperator(checkType, operatorDef, typedVal, BfTypedValue());
  11292. if (returnType != NULL)
  11293. {
  11294. operatorConstraintReturnType = returnType;
  11295. methodMatcher.mBestMethodDef = operatorDef;
  11296. }
  11297. }
  11298. else
  11299. {
  11300. if (methodMatcher.CheckMethod(NULL, checkType, operatorDef, false))
  11301. methodMatcher.mSelfType = entry.mSrcType;
  11302. }
  11303. args.mSize = prevArgSize;
  11304. }
  11305. }
  11306. }
  11307. if (methodMatcher.mBestMethodDef != NULL)
  11308. {
  11309. if (mayBeBox)
  11310. {
  11311. if (!ignoreErrors)
  11312. {
  11313. if (Fail("Ambiguous cast, may be conversion operator or may be boxing request", srcNode) != NULL)
  11314. mCompiler->mPassInstance->MoreInfo("See conversion operator", methodMatcher.mBestMethodDef->GetRefNode());
  11315. }
  11316. else if (!silentFail)
  11317. SetFail();
  11318. }
  11319. }
  11320. if (methodMatcher.mBestMethodDef == NULL)
  11321. {
  11322. // Check method generic constraints
  11323. if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mIsUnspecialized) && (mCurMethodInstance->mMethodInfoEx != NULL))
  11324. {
  11325. for (int genericParamIdx = 0; genericParamIdx < mCurMethodInstance->mMethodInfoEx->mGenericParams.size(); genericParamIdx++)
  11326. {
  11327. auto genericParam = mCurMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
  11328. for (auto& opConstraint : genericParam->mOperatorConstraints)
  11329. {
  11330. if ((opConstraint.mCastToken == BfToken_Implicit) ||
  11331. ((explicitCast) && (opConstraint.mCastToken == BfToken_Explicit)))
  11332. {
  11333. // If we can convert OUR fromVal to the constraint's fromVal then we may match
  11334. if (CanCast(typedVal, opConstraint.mRightType, BfCastFlags_NoConversionOperator))
  11335. {
  11336. // .. and we can convert the constraint's toType to OUR toType then we're good
  11337. auto opToVal = genericParam->mExternType;
  11338. if (CanCast(BfTypedValue(BfIRValue::sValueless, opToVal), toType, BfCastFlags_NoConversionOperator))
  11339. return mBfIRBuilder->GetFakeVal();
  11340. }
  11341. }
  11342. }
  11343. }
  11344. }
  11345. // Check type generic constraints
  11346. if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsGenericTypeInstance()) && (mCurTypeInstance->IsUnspecializedType()))
  11347. {
  11348. SizedArray<BfGenericParamInstance*, 4> genericParams;
  11349. GetActiveTypeGenericParamInstances(genericParams);
  11350. for (auto genericParam : genericParams)
  11351. {
  11352. for (auto& opConstraint : genericParam->mOperatorConstraints)
  11353. {
  11354. if ((opConstraint.mCastToken == BfToken_Implicit) ||
  11355. ((explicitCast) && (opConstraint.mCastToken == BfToken_Explicit)))
  11356. {
  11357. // If we can convert OUR fromVal to the constraint's fromVal then we may match
  11358. if (CanCast(typedVal, opConstraint.mRightType, BfCastFlags_NoConversionOperator))
  11359. {
  11360. // .. and we can convert the constraint's toType to OUR toType then we're good
  11361. auto opToVal = genericParam->mExternType;
  11362. if (CanCast(BfTypedValue(BfIRValue::sValueless, opToVal), toType, BfCastFlags_NoConversionOperator))
  11363. return mBfIRBuilder->GetFakeVal();
  11364. }
  11365. }
  11366. }
  11367. }
  11368. }
  11369. }
  11370. else if (isConstraintCheck)
  11371. {
  11372. auto result = BfTypedValue(mBfIRBuilder->GetFakeVal(), operatorConstraintReturnType);
  11373. if (result.mType != toType)
  11374. return CastToValue(srcNode, result, toType, (BfCastFlags)(castFlags | BfCastFlags_Explicit | BfCastFlags_NoConversionOperator), resultFlags);
  11375. if (result)
  11376. return result.mValue;
  11377. }
  11378. else
  11379. {
  11380. BfTypedValue result;
  11381. BfExprEvaluator exprEvaluator(this);
  11382. exprEvaluator.mBfEvalExprFlags = BfEvalExprFlags_FromConversionOp;
  11383. if ((castFlags & BfCastFlags_WantsConst) != 0)
  11384. exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | BfEvalExprFlags_Comptime);
  11385. auto methodDeclaration = BfNodeDynCast<BfMethodDeclaration>(methodMatcher.mBestMethodDef->mMethodDeclaration);
  11386. if ((methodDeclaration != NULL) && (methodDeclaration->mBody == NULL))
  11387. {
  11388. auto fromType = typedVal.mType;
  11389. // Handle the typedPrim<->underlying part implicitly
  11390. if (fromType->IsTypedPrimitive())
  11391. {
  11392. auto convTypedValue = BfTypedValue(typedVal.mValue, fromType->GetUnderlyingType());
  11393. return CastToValue(srcNode, convTypedValue, toType, (BfCastFlags)(castFlags & ~BfCastFlags_Explicit), NULL);
  11394. }
  11395. else if (toType->IsTypedPrimitive())
  11396. {
  11397. auto castedVal = CastToValue(srcNode, typedVal, toType->GetUnderlyingType(), (BfCastFlags)(castFlags & ~BfCastFlags_Explicit), NULL);
  11398. return castedVal;
  11399. }
  11400. }
  11401. bool doCall = true;
  11402. auto moduleMethodInstance = exprEvaluator.GetSelectedMethod(methodMatcher);
  11403. if (moduleMethodInstance.mMethodInstance != NULL)
  11404. {
  11405. auto returnType = moduleMethodInstance.mMethodInstance->mReturnType;
  11406. auto paramType = moduleMethodInstance.mMethodInstance->GetParamType(0);
  11407. BfCastFlags implicitCastFlags = (BfCastFlags)(castFlags & ~BfCastFlags_Explicit | BfCastFlags_NoConversionOperator);
  11408. // Check typedPrimitive->underlying cast
  11409. if ((explicitCast) && (typedVal.mType->IsTypedPrimitive()))
  11410. {
  11411. auto underlyingType = typedVal.mType->GetUnderlyingType();
  11412. if ((returnType == underlyingType) && (explicitCast))
  11413. {
  11414. doCall = false;
  11415. }
  11416. else if ((CanCast(GetFakeTypedValue(underlyingType), toType, (BfCastFlags)(castFlags | BfCastFlags_NoConversionOperator))))
  11417. {
  11418. float underlyingCanCast = CanCast(GetFakeTypedValue(underlyingType), toType, implicitCastFlags);
  11419. float returnCanCast = CanCast(GetFakeTypedValue(returnType), toType, implicitCastFlags);
  11420. if ((underlyingCanCast) &&
  11421. (!returnCanCast))
  11422. {
  11423. doCall = false;
  11424. }
  11425. else if ((returnCanCast) &&
  11426. (!underlyingCanCast))
  11427. {
  11428. // Can do
  11429. }
  11430. else if ((CanCast(GetFakeTypedValue(underlyingType), returnType, implicitCastFlags)) &&
  11431. (!CanCast(GetFakeTypedValue(returnType), underlyingType, implicitCastFlags)))
  11432. {
  11433. // Can do
  11434. }
  11435. else
  11436. doCall = false;
  11437. }
  11438. }
  11439. // Check underlying->typedPrimitive cast
  11440. if ((explicitCast) && (toType->IsTypedPrimitive()))
  11441. {
  11442. auto underlyingType = toType->GetUnderlyingType();
  11443. if ((paramType == underlyingType) && (explicitCast))
  11444. {
  11445. doCall = false;
  11446. }
  11447. else if (CanCast(typedVal, underlyingType, (BfCastFlags)(castFlags | BfCastFlags_NoConversionOperator)))
  11448. {
  11449. float underlyingCanCast = CanCast(typedVal, underlyingType, implicitCastFlags);
  11450. float paramCanCast = CanCast(typedVal, paramType, implicitCastFlags);
  11451. if ((underlyingType) &&
  11452. (!paramCanCast))
  11453. {
  11454. doCall = false;
  11455. }
  11456. else if ((paramCanCast) &&
  11457. (!underlyingCanCast))
  11458. {
  11459. // Can do
  11460. }
  11461. else if ((CanCast(GetFakeTypedValue(underlyingType), paramType, implicitCastFlags)) &&
  11462. (!CanCast(GetFakeTypedValue(paramType), underlyingType, implicitCastFlags)))
  11463. {
  11464. // Can do
  11465. }
  11466. else
  11467. doCall = false;
  11468. }
  11469. }
  11470. if (doCall)
  11471. {
  11472. if (!silentFail)
  11473. methodMatcher.FlushAmbiguityError();
  11474. auto wantType = paramType;
  11475. if (wantType->IsRef())
  11476. wantType = wantType->GetUnderlyingType();
  11477. auto convTypedVal = methodMatcher.mArguments[0].mTypedValue;
  11478. if (wantType != convTypedVal.mType)
  11479. {
  11480. if ((convTypedVal.mType->IsWrappableType()) && (wantType == GetWrappedStructType(convTypedVal.mType)))
  11481. {
  11482. convTypedVal = MakeAddressable(convTypedVal);
  11483. methodMatcher.mArguments[0].mTypedValue = BfTypedValue(mBfIRBuilder->CreateBitCast(convTypedVal.mValue, mBfIRBuilder->MapTypeInstPtr(wantType->ToTypeInstance())),
  11484. paramType, paramType->IsRef() ? BfTypedValueKind_Value : BfTypedValueKind_Addr);
  11485. }
  11486. else
  11487. {
  11488. methodMatcher.mArguments[0].mTypedValue = Cast(srcNode, convTypedVal, wantType, (BfCastFlags)(castFlags | BfCastFlags_Explicit | BfCastFlags_NoConversionOperator));
  11489. if (paramType->IsRef())
  11490. {
  11491. convTypedVal = MakeAddressable(convTypedVal);
  11492. convTypedVal.mKind = BfTypedValueKind_Addr;
  11493. }
  11494. }
  11495. }
  11496. }
  11497. }
  11498. if (doCall)
  11499. {
  11500. if ((castFlags & BfCastFlags_IsCastCheck) != 0)
  11501. {
  11502. // We've already verified that we can cast from the return type to toType in MethodMatcher.CheckMethod
  11503. return mBfIRBuilder->GetFakeVal();
  11504. }
  11505. result = exprEvaluator.CreateCall(&methodMatcher, BfTypedValue());
  11506. if (result.mType != toType)
  11507. return CastToValue(srcNode, result, toType, (BfCastFlags)(castFlags | BfCastFlags_Explicit | BfCastFlags_NoConversionOperator), resultFlags);
  11508. if (result)
  11509. {
  11510. if (resultFlags != NULL)
  11511. {
  11512. if (result.IsAddr())
  11513. *resultFlags = (BfCastResultFlags)(*resultFlags | BfCastResultFlags_IsAddr);
  11514. if (result.mKind == BfTypedValueKind_TempAddr)
  11515. *resultFlags = (BfCastResultFlags)(*resultFlags | BfCastResultFlags_IsTemp);
  11516. }
  11517. else if (result.IsAddr())
  11518. result = LoadValue(result);
  11519. return result.mValue;
  11520. }
  11521. }
  11522. }
  11523. }
  11524. // Default typed primitive 'underlying casts' happen after checking cast operators
  11525. if (explicitCast)
  11526. {
  11527. // TypedPrimitive -> Primitive
  11528. if ((typedVal.mType->IsTypedPrimitive()) && (!typedVal.mType->IsFunction()) && (toType->IsPrimitiveType()))
  11529. {
  11530. auto fromTypedPrimitiveType = typedVal.mType->ToTypeInstance();
  11531. auto primTypedVal = BfTypedValue(typedVal.mValue, fromTypedPrimitiveType->mFieldInstances.back().mResolvedType, typedVal.IsAddr());
  11532. primTypedVal = LoadValue(primTypedVal);
  11533. return CastToValue(srcNode, primTypedVal, toType, castFlags);
  11534. }
  11535. // TypedPrimitive -> TypedPrimitive
  11536. if ((typedVal.mType->IsTypedPrimitive()) && (!typedVal.mType->IsFunction()) && (toType->IsTypedPrimitive()))
  11537. {
  11538. auto fromTypedPrimitiveType = typedVal.mType->ToTypeInstance();
  11539. auto toTypedPrimitiveType = toType->ToTypeInstance();
  11540. auto fromUnderlyingType = fromTypedPrimitiveType->GetUnderlyingType();
  11541. auto toUnderlyingType = toTypedPrimitiveType->GetUnderlyingType();
  11542. BfTypedValue underlyingTypedValue(typedVal.mValue, fromUnderlyingType, typedVal.IsAddr());
  11543. underlyingTypedValue = LoadValue(underlyingTypedValue);
  11544. BfIRValue castedToValue = CastToValue(srcNode, underlyingTypedValue, toUnderlyingType, (BfCastFlags)(castFlags | BfCastFlags_Explicit));
  11545. if (castedToValue)
  11546. return castedToValue;
  11547. }
  11548. }
  11549. else if ((typedVal.mType->IsTypedPrimitive()) && (toType->IsTypedPrimitive()))
  11550. {
  11551. if (TypeIsSubTypeOf(typedVal.mType->ToTypeInstance(), toType->ToTypeInstance()))
  11552. {
  11553. // These have the same underlying primitive type, just keep it all the same
  11554. if ((resultFlags != NULL) && (typedVal.IsAddr()))
  11555. *resultFlags = BfCastResultFlags_IsAddr;
  11556. return typedVal.mValue;
  11557. }
  11558. }
  11559. // Prim -> TypedPrimitive
  11560. if ((typedVal.mType->IsPrimitiveType()) && (toType->IsTypedPrimitive()))
  11561. {
  11562. bool allowCast = explicitCast;
  11563. if (toType == mCurTypeInstance)
  11564. allowCast = true;
  11565. if ((!allowCast) && (typedVal.mType->IsIntegral()) /*&& (!toType->IsEnum())*/)
  11566. {
  11567. // Allow implicit cast of zero
  11568. auto constant = mBfIRBuilder->GetConstant(typedVal.mValue);
  11569. if ((constant != NULL) && (mBfIRBuilder->IsInt(constant->mTypeCode)))
  11570. {
  11571. allowCast = constant->mInt64 == 0;
  11572. }
  11573. }
  11574. if (allowCast)
  11575. {
  11576. return CastToValue(srcNode, typedVal, toType->GetUnderlyingType(), castFlags);
  11577. }
  11578. }
  11579. if (typedVal.mType->IsBoxed())
  11580. {
  11581. BfBoxedType* boxedType = (BfBoxedType*)typedVal.mType;
  11582. if (boxedType->mElementType->IsGenericParam())
  11583. {
  11584. // If we have a boxed generic param, the actual available interfaces constraints won't be
  11585. // handled, so we need to pass through again as the root generic param
  11586. BfTypedValue unboxedValue = typedVal;
  11587. unboxedValue.mType = boxedType->mElementType;
  11588. auto result = CastToValue(srcNode, unboxedValue, toType, (BfCastFlags)(castFlags | BfCastFlags_SilentFail), resultFlags);
  11589. if (result)
  11590. return result;
  11591. }
  11592. }
  11593. if ((mayBeBox) && ((castFlags & BfCastFlags_NoBox) == 0))
  11594. {
  11595. BfScopeData* scopeData = NULL;
  11596. if (mCurMethodState != NULL)
  11597. {
  11598. if (mCurMethodState->mOverrideScope)
  11599. scopeData = mCurMethodState->mOverrideScope;
  11600. else
  11601. scopeData = mCurMethodState->mCurScope;
  11602. }
  11603. if ((castFlags & BfCastFlags_WarnOnBox) != 0)
  11604. {
  11605. Warn(0, "This implicit boxing will only be in scope during the constructor. Consider using a longer-term allocation such as 'box new'", srcNode);
  11606. }
  11607. SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, ignoreWrites);
  11608. auto value = BoxValue(srcNode, typedVal, toType, scopeData, castFlags);
  11609. if (value)
  11610. return value.mValue;
  11611. }
  11612. if (!ignoreErrors)
  11613. {
  11614. const char* errStrF = explicitCast ?
  11615. "Unable to cast '%s' to '%s'" :
  11616. "Unable to implicitly cast '%s' to '%s'";
  11617. String errStr = StrFormat(errStrF, TypeToString(typedVal.mType).c_str(), TypeToString(toType).c_str());
  11618. auto error = Fail(errStr, srcNode);
  11619. if ((error != NULL) && (srcNode != NULL))
  11620. {
  11621. if ((mCompiler->IsAutocomplete()) && (mCompiler->mResolvePassData->mAutoComplete->CheckFixit((srcNode))))
  11622. {
  11623. SetAndRestoreValue<bool> ignoreWrites(mBfIRBuilder->mIgnoreWrites);
  11624. SetAndRestoreValue<bool> ignoreErrors(mIgnoreErrors, true);
  11625. if (CastToValue(srcNode, typedVal, toType, (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_SilentFail)))
  11626. {
  11627. bool doWrap = false;
  11628. if (auto unaryOpExpr = BfNodeDynCast<BfUnaryOperatorExpression>(srcNode))
  11629. {
  11630. if ((unaryOpExpr->mOp != BfUnaryOp_AddressOf) && (unaryOpExpr->mOp != BfUnaryOp_Dereference))
  11631. doWrap = true;
  11632. }
  11633. if ((srcNode->IsA<BfCastExpression>()) ||
  11634. (srcNode->IsA<BfBinaryOperatorExpression>()) ||
  11635. (srcNode->IsA<BfConditionalExpression>()))
  11636. doWrap = true;
  11637. BfParserData* parser = srcNode->GetSourceData()->ToParserData();
  11638. String typeName = TypeToString(toType);
  11639. if (doWrap)
  11640. {
  11641. mCompiler->mResolvePassData->mAutoComplete->AddEntry(AutoCompleteEntry("fixit",
  11642. StrFormat("(%s)\tcast|%s|%d|(%s)(|`%d|)", typeName.c_str(), parser->mFileName.c_str(), srcNode->GetSrcStart(), typeName.c_str(), srcNode->GetSrcLength()).c_str()));
  11643. }
  11644. else
  11645. {
  11646. mCompiler->mResolvePassData->mAutoComplete->AddEntry(AutoCompleteEntry("fixit",
  11647. StrFormat("(%s)\tcast|%s|%d|(%s)", typeName.c_str(), parser->mFileName.c_str(), srcNode->GetSrcStart(), typeName.c_str()).c_str()));
  11648. }
  11649. }
  11650. }
  11651. }
  11652. }
  11653. else if (!silentFail)
  11654. SetFail();
  11655. return BfIRValue();
  11656. }
  11657. BfTypedValue BfModule::Cast(BfAstNode* srcNode, const BfTypedValue& typedVal, BfType* toType, BfCastFlags castFlags)
  11658. {
  11659. bool explicitCast = (castFlags & BfCastFlags_Explicit) != 0;
  11660. if (typedVal.mType == toType)
  11661. return typedVal;
  11662. if ((toType->IsSizedArray()) && (typedVal.mType->IsSizedArray()))
  11663. {
  11664. // Retain our type if we're casting from a known-sized array to an unknown-sized arrays
  11665. if ((toType->IsUndefSizedArray()) && ((typedVal.mType->GetUnderlyingType()) == (toType->GetUnderlyingType())))
  11666. {
  11667. return typedVal;
  11668. }
  11669. }
  11670. if ((castFlags & BfCastFlags_Force) != 0)
  11671. {
  11672. PopulateType(toType, BfPopulateType_Data);
  11673. if (toType->IsValuelessType())
  11674. return BfTypedValue(mBfIRBuilder->GetFakeVal(), toType);
  11675. if ((typedVal.mType->IsValueType()) && (!typedVal.IsAddr()) && (typedVal.IsSplat()) && (toType->IsValueType()))
  11676. {
  11677. bool needsMemberCasting = false;
  11678. if (AreSplatsCompatible(typedVal.mType, toType, &needsMemberCasting))
  11679. {
  11680. return BfTypedValue(typedVal.mValue, toType, needsMemberCasting ? BfTypedValueKind_SplatHead_NeedsCasting : BfTypedValueKind_SplatHead);
  11681. }
  11682. }
  11683. if (typedVal.mType->IsValueType())
  11684. {
  11685. auto addrTypedValue = MakeAddressable(typedVal);
  11686. auto toPtrType = CreatePointerType(toType);
  11687. return BfTypedValue(mBfIRBuilder->CreateBitCast(addrTypedValue.mValue, mBfIRBuilder->MapType(toPtrType)), toType, BfTypedValueKind_Addr);
  11688. }
  11689. return BfTypedValue(mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType)), toType);
  11690. }
  11691. // This tuple cast may create a new type if the toType contains 'var' entries
  11692. if ((typedVal.mType->IsTuple()) && (toType->IsTuple()))
  11693. {
  11694. PopulateType(toType);
  11695. auto fromTupleType = (BfTypeInstance*)typedVal.mType;
  11696. auto toTupleType = (BfTypeInstance*)toType;
  11697. if (fromTupleType == toTupleType)
  11698. return typedVal;
  11699. if (fromTupleType->mFieldInstances.size() == toTupleType->mFieldInstances.size())
  11700. {
  11701. BfTypeVector fieldTypes;
  11702. Array<String> fieldNames;
  11703. bool isCompatible = true;
  11704. bool isExactTypeMatch = true;
  11705. for (int fieldIdx = 0; fieldIdx < (int)fromTupleType->mFieldInstances.size(); fieldIdx++)
  11706. {
  11707. auto fromFieldInst = &fromTupleType->mFieldInstances[fieldIdx];
  11708. auto toFieldInst = &toTupleType->mFieldInstances[fieldIdx];
  11709. auto fromFieldDef = fromFieldInst->GetFieldDef();
  11710. auto toFieldDef = toFieldInst->GetFieldDef();
  11711. if (!toFieldDef->IsUnnamedTupleField())
  11712. {
  11713. if ((!explicitCast) &&
  11714. (!fromFieldDef->IsUnnamedTupleField()) &&
  11715. (fromFieldDef->mName != toFieldDef->mName))
  11716. isCompatible = false;
  11717. fieldNames.push_back(toFieldDef->mName);
  11718. }
  11719. else
  11720. fieldNames.push_back("");
  11721. if (toFieldInst->mResolvedType->IsVar())
  11722. fieldTypes.push_back(fromFieldInst->mResolvedType);
  11723. else
  11724. {
  11725. if (fromFieldInst->mResolvedType != toFieldInst->mResolvedType)
  11726. isExactTypeMatch = false;
  11727. BfCastFlags tryCastFlags = BfCastFlags_SilentFail;
  11728. if (explicitCast)
  11729. tryCastFlags = (BfCastFlags)(tryCastFlags | BfCastFlags_Explicit);
  11730. // The unused-token '?' comes out as 'void', so we allow that to match here. We may want to wrap that with a different fake type
  11731. // so we can give normal implicit-cast-to-void errors
  11732. if ((fromFieldInst->mResolvedType != toFieldInst->mResolvedType) && (!toFieldInst->mResolvedType->IsVoid()) &&
  11733. (!CanCast(GetFakeTypedValue(fromFieldInst->mResolvedType), toFieldInst->mResolvedType, tryCastFlags)))
  11734. isCompatible = false;
  11735. fieldTypes.push_back(toFieldInst->mResolvedType);
  11736. }
  11737. }
  11738. auto tupleType = CreateTupleType(fieldTypes, fieldNames);
  11739. AddDependency(tupleType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields);
  11740. mBfIRBuilder->PopulateType(tupleType);
  11741. if (isCompatible)
  11742. {
  11743. if (isExactTypeMatch)
  11744. {
  11745. if (typedVal.mKind == BfTypedValueKind_TempAddr)
  11746. {
  11747. return BfTypedValue(mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapTypeInstPtr(tupleType)), tupleType, BfTypedValueKind_TempAddr);
  11748. }
  11749. else if (typedVal.IsAddr())
  11750. {
  11751. return BfTypedValue(mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapTypeInstPtr(tupleType)), tupleType, BfTypedValueKind_ReadOnlyAddr);
  11752. }
  11753. else if (typedVal.IsSplat())
  11754. {
  11755. BfTypedValue retTypedValue = typedVal;
  11756. retTypedValue.mType = tupleType;
  11757. return retTypedValue;
  11758. }
  11759. BfIRValue curTupleValue = CreateAlloca(tupleType);
  11760. auto loadedVal = LoadValue(typedVal);
  11761. mBfIRBuilder->CreateStore(loadedVal.mValue, mBfIRBuilder->CreateBitCast(curTupleValue, mBfIRBuilder->MapTypeInstPtr(fromTupleType)));
  11762. return BfTypedValue(curTupleValue, tupleType, BfTypedValueKind_TempAddr);
  11763. }
  11764. BfIRValue curTupleValue = CreateAlloca(tupleType);
  11765. for (int fieldIdx = 0; fieldIdx < (int)fromTupleType->mFieldInstances.size(); fieldIdx++)
  11766. {
  11767. BfFieldInstance* fromFieldInstance = &fromTupleType->mFieldInstances[fieldIdx];
  11768. BfFieldInstance* toFieldInstance = &tupleType->mFieldInstances[fieldIdx];
  11769. if (toFieldInstance->mDataIdx >= 0)
  11770. {
  11771. if (fromFieldInstance->mDataIdx >= 0)
  11772. {
  11773. auto elementVal = ExtractValue(typedVal, fromFieldInstance, fromFieldInstance->mDataIdx);
  11774. elementVal = LoadValue(elementVal);
  11775. auto castedElementVal = Cast(srcNode, elementVal, toFieldInstance->GetResolvedType(), castFlags);
  11776. if (!castedElementVal)
  11777. return BfTypedValue();
  11778. auto fieldRef = mBfIRBuilder->CreateInBoundsGEP(curTupleValue, 0, toFieldInstance->mDataIdx);
  11779. castedElementVal = LoadValue(castedElementVal);
  11780. mBfIRBuilder->CreateStore(castedElementVal.mValue, fieldRef);
  11781. }
  11782. else
  11783. isCompatible = false;
  11784. }
  11785. }
  11786. return BfTypedValue(curTupleValue, tupleType, BfTypedValueKind_TempAddr);
  11787. }
  11788. }
  11789. const char* errStr = explicitCast ?
  11790. "Unable to cast '%s' to '%s'" :
  11791. "Unable to implicitly cast '%s' to '%s'";
  11792. Fail(StrFormat(errStr, TypeToString(typedVal.mType).c_str(), TypeToString(toType).c_str()), srcNode);
  11793. return BfTypedValue();
  11794. }
  11795. // Function->Function and Delegate->Delegate where type is compatible but not exact
  11796. if (((typedVal.mType->IsDelegate()) || (typedVal.mType->IsFunction())) &&
  11797. (typedVal.mType != toType) && // Don't bother to check for exact match, let CastToValue handle this
  11798. ((typedVal.mType->IsDelegate()) == (toType->IsDelegate())) &&
  11799. ((typedVal.mType->IsFunction()) == (toType->IsFunction())))
  11800. {
  11801. auto fromTypeInst = typedVal.mType->ToTypeInstance();
  11802. auto toTypeInst = toType->ToTypeInstance();
  11803. auto fromMethodInst = GetRawMethodByName(fromTypeInst, "Invoke", -1, true);
  11804. auto toMethodInst = GetRawMethodByName(toTypeInst, "Invoke", -1, true);
  11805. auto toDelegateInfo = toTypeInst->GetDelegateInfo();
  11806. if ((fromMethodInst != NULL) && (toMethodInst != NULL) &&
  11807. (fromMethodInst->mCallingConvention == toMethodInst->mCallingConvention) &&
  11808. (fromMethodInst->mMethodDef->mIsMutating == toMethodInst->mMethodDef->mIsMutating) &&
  11809. (fromMethodInst->mReturnType == toMethodInst->mReturnType) &&
  11810. (fromMethodInst->GetParamCount() == toMethodInst->GetParamCount()))
  11811. {
  11812. bool matched = true;
  11813. StringT<64> fromParamName;
  11814. StringT<64> toParamName;
  11815. if (fromMethodInst->HasExplicitThis() != toMethodInst->HasExplicitThis())
  11816. {
  11817. matched = false;
  11818. }
  11819. else
  11820. {
  11821. for (int paramIdx = 0; paramIdx < (int)fromMethodInst->GetParamCount(); paramIdx++)
  11822. {
  11823. bool nameMatches = true;
  11824. if (!explicitCast)
  11825. {
  11826. int fromNamePrefixCount = 0;
  11827. int toNamePrefixCount = 0;
  11828. fromMethodInst->GetParamName(paramIdx, fromParamName, fromNamePrefixCount);
  11829. toMethodInst->GetParamName(paramIdx, toParamName, toNamePrefixCount);
  11830. if ((!fromParamName.IsEmpty()) && (!toParamName.IsEmpty()))
  11831. nameMatches = fromParamName == toParamName;
  11832. }
  11833. if ((fromMethodInst->GetParamKind(paramIdx) == toMethodInst->GetParamKind(paramIdx)) &&
  11834. (fromMethodInst->GetParamType(paramIdx) == toMethodInst->GetParamType(paramIdx)) &&
  11835. (nameMatches))
  11836. {
  11837. // Matched, required for implicit/explicit
  11838. }
  11839. else
  11840. {
  11841. matched = false;
  11842. break;
  11843. }
  11844. }
  11845. }
  11846. if (matched)
  11847. {
  11848. BfTypedValue loadedVal = LoadValue(typedVal);
  11849. return BfTypedValue(mBfIRBuilder->CreateBitCast(loadedVal.mValue, mBfIRBuilder->MapType(toType)), toType);
  11850. }
  11851. }
  11852. }
  11853. // Struct truncate
  11854. if ((typedVal.mType->IsStruct()) && (toType->IsStruct()))
  11855. {
  11856. auto fromStructTypeInstance = typedVal.mType->ToTypeInstance();
  11857. auto toStructTypeInstance = toType->ToTypeInstance();
  11858. if (TypeIsSubTypeOf(fromStructTypeInstance, toStructTypeInstance))
  11859. {
  11860. if (typedVal.IsSplat())
  11861. {
  11862. BF_ASSERT(toStructTypeInstance->IsSplattable() || (toStructTypeInstance->mInstSize == 0));
  11863. return BfTypedValue(typedVal.mValue, toStructTypeInstance, typedVal.IsThis() ? BfTypedValueKind_ThisSplatHead : BfTypedValueKind_SplatHead);
  11864. }
  11865. if (typedVal.IsAddr())
  11866. {
  11867. BfIRValue castedIRValue;
  11868. if (typedVal.mValue.IsFake())
  11869. castedIRValue = typedVal.mValue;
  11870. else
  11871. castedIRValue = mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapTypeInstPtr(toStructTypeInstance));
  11872. return BfTypedValue(castedIRValue, toType, typedVal.IsThis() ?
  11873. (typedVal.IsReadOnly() ? BfTypedValueKind_ReadOnlyThisAddr : BfTypedValueKind_ThisAddr) :
  11874. (typedVal.IsReadOnly() ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr));
  11875. }
  11876. BfTypedValue curTypedVal = typedVal;
  11877. while (curTypedVal.mType != toStructTypeInstance)
  11878. {
  11879. mBfIRBuilder->PopulateType(curTypedVal.mType);
  11880. auto curTypeInstance = curTypedVal.mType->ToTypeInstance();
  11881. BfIRValue extractedValue;
  11882. if (toStructTypeInstance->IsValuelessType())
  11883. extractedValue = mBfIRBuilder->GetFakeVal();
  11884. else
  11885. extractedValue = mBfIRBuilder->CreateExtractValue(curTypedVal.mValue, 0);
  11886. curTypedVal = BfTypedValue(extractedValue, curTypeInstance->mBaseType, typedVal.IsThis() ?
  11887. (typedVal.IsReadOnly() ? BfTypedValueKind_ReadOnlyThisValue : BfTypedValueKind_ThisValue) :
  11888. BfTypedValueKind_Value);
  11889. }
  11890. return curTypedVal;
  11891. }
  11892. }
  11893. /*if ((explicitCast) && (toType->IsValuelessType()))
  11894. {
  11895. return BfTypedValue(mBfIRBuilder->GetFakeVal(), toType);
  11896. }*/
  11897. BfCastResultFlags castResultFlags = BfCastResultFlags_None;
  11898. auto castedValue = CastToValue(srcNode, typedVal, toType, castFlags, &castResultFlags);
  11899. if (!castedValue)
  11900. return BfTypedValue();
  11901. if ((castResultFlags & BfCastResultFlags_IsAddr) != 0)
  11902. {
  11903. if ((castResultFlags & BfCastResultFlags_IsTemp) != 0)
  11904. return BfTypedValue(castedValue, toType, BfTypedValueKind_TempAddr);
  11905. return BfTypedValue(castedValue, toType, BfTypedValueKind_Addr);
  11906. }
  11907. return BfTypedValue(castedValue, toType, BfTypedValueKind_Value);
  11908. }
  11909. BfPrimitiveType* BfModule::GetIntCoercibleType(BfType* type)
  11910. {
  11911. if (type->IsSizedArray())
  11912. {
  11913. auto sizedArray = (BfSizedArrayType*)type;
  11914. if ((sizedArray->mElementType->IsChar()) && (sizedArray->mElementType->mSize == 1))
  11915. {
  11916. auto primType = (BfPrimitiveType*)sizedArray->mElementType;
  11917. if (sizedArray->mElementCount == 1)
  11918. return GetPrimitiveType(BfTypeCode_UInt8);
  11919. if (sizedArray->mElementCount == 2)
  11920. return GetPrimitiveType(BfTypeCode_UInt16);
  11921. if (sizedArray->mElementCount == 4)
  11922. return GetPrimitiveType(BfTypeCode_UInt32);
  11923. if (sizedArray->mElementCount == 8)
  11924. return GetPrimitiveType(BfTypeCode_UInt64);
  11925. }
  11926. }
  11927. return NULL;
  11928. }
  11929. BfTypedValue BfModule::GetIntCoercible(const BfTypedValue& typedValue)
  11930. {
  11931. auto intType = GetIntCoercibleType(typedValue.mType);
  11932. if (intType == NULL)
  11933. return BfTypedValue();
  11934. if (typedValue.mValue.IsConst())
  11935. {
  11936. auto constant = mBfIRBuilder->GetConstant(typedValue.mValue);
  11937. if (constant->mConstType == BfConstType_Agg)
  11938. {
  11939. uint64 intVal = 0;
  11940. auto constantArray = (BfConstantAgg*)constant;
  11941. int memberIdx = 0;
  11942. for (int memberIdx = 0; memberIdx < (int)constantArray->mValues.size(); memberIdx++)
  11943. {
  11944. auto memberConstant = mBfIRBuilder->GetConstant(constantArray->mValues[memberIdx]);
  11945. if (memberConstant->mTypeCode == BfTypeCode_Char8)
  11946. {
  11947. intVal |= (uint64)(memberConstant->mUInt8) << (8 * memberIdx);
  11948. //intVal = (intVal << 8) | memberConstant->mUInt8;
  11949. }
  11950. }
  11951. return BfTypedValue(mBfIRBuilder->CreateConst(intType->mTypeDef->mTypeCode, intVal), intType);
  11952. }
  11953. }
  11954. auto convTypedValue = typedValue;
  11955. convTypedValue = MakeAddressable(convTypedValue);
  11956. auto intPtrType = CreatePointerType(intType);
  11957. auto addrVal = mBfIRBuilder->CreateBitCast(convTypedValue.mValue, mBfIRBuilder->MapType(intPtrType));
  11958. auto val = mBfIRBuilder->CreateLoad(addrVal);
  11959. return BfTypedValue(val, intType);
  11960. }
  11961. bool BfModule::TypeHasParentOrEquals(BfTypeDef* checkChildTypeDef, BfTypeDef* checkParentTypeDef)
  11962. {
  11963. BfTypeDef* checkType = checkChildTypeDef;
  11964. if (checkType->mNestDepth < checkParentTypeDef->mNestDepth)
  11965. return false;
  11966. while (checkType->mNestDepth > checkParentTypeDef->mNestDepth)
  11967. checkType = checkType->mOuterType;
  11968. if (checkType->GetDefinition() == checkParentTypeDef->GetDefinition())
  11969. return true;
  11970. if (checkType->mNameEx != checkParentTypeDef->mNameEx)
  11971. return false;
  11972. if (checkType->mIsPartial)
  11973. {
  11974. for (auto partial : checkParentTypeDef->mPartials)
  11975. if (partial == checkType)
  11976. return true;
  11977. }
  11978. return false;
  11979. }
  11980. BfTypeDef* BfModule::FindCommonOuterType(BfTypeDef* type, BfTypeDef* type2)
  11981. {
  11982. if ((type == NULL) || (type2 == NULL))
  11983. return NULL;
  11984. int curNestDepth = BF_MIN(type->mNestDepth, type2->mNestDepth);
  11985. while (type->mNestDepth > curNestDepth)
  11986. type = type->mOuterType;
  11987. while (type2->mNestDepth > curNestDepth)
  11988. type2 = type2->mOuterType;
  11989. while (curNestDepth >= 0)
  11990. {
  11991. if ((!type->mIsPartial) && (!type2->mIsPartial))
  11992. {
  11993. if (type->GetDefinition() == type2->GetDefinition())
  11994. return type;
  11995. }
  11996. else
  11997. {
  11998. if (type->mFullNameEx == type2->mFullNameEx)
  11999. return type;
  12000. }
  12001. type = type->mOuterType;
  12002. type2 = type2->mOuterType;
  12003. curNestDepth--;
  12004. }
  12005. return NULL;
  12006. }
  12007. bool BfModule::TypeIsSubTypeOf(BfTypeInstance* srcType, BfTypeInstance* wantType, bool checkAccessibility)
  12008. {
  12009. if ((srcType == NULL) || (wantType == NULL))
  12010. return false;
  12011. if (srcType == wantType)
  12012. return true;
  12013. if (srcType->mDefineState < BfTypeDefineState_HasInterfaces)
  12014. {
  12015. if (srcType->mDefineState == BfTypeDefineState_ResolvingBaseType)
  12016. {
  12017. auto typeState = mContext->mCurTypeState;
  12018. while (typeState != NULL)
  12019. {
  12020. if ((typeState->mType == srcType) && (typeState->mCurBaseType != NULL))
  12021. {
  12022. return TypeIsSubTypeOf(typeState->mCurBaseType, wantType, checkAccessibility);
  12023. }
  12024. typeState = typeState->mPrevState;
  12025. }
  12026. }
  12027. // Type is incomplete. We don't do the IsIncomplete check here because of re-entry
  12028. // While handling 'var' resolution, we don't want to force a PopulateType reentry
  12029. // but we do have enough information for TypeIsSubTypeOf
  12030. PopulateType(srcType, BfPopulateType_Interfaces);
  12031. }
  12032. if (wantType->IsInterface())
  12033. {
  12034. BfTypeDef* checkActiveTypeDef = NULL;
  12035. bool checkAccessibility = true;
  12036. if (IsInSpecializedSection())
  12037. {
  12038. // When we have a specialized section, the generic params may not be considered "included"
  12039. // in the module that contains the generic type definition. We rely on any casting errors
  12040. // to be thrown on the unspecialized type pass. We have a similar issue with injecting mixins.
  12041. checkAccessibility = false;
  12042. }
  12043. auto checkType = srcType;
  12044. while (checkType != NULL)
  12045. {
  12046. for (auto ifaceInst : checkType->mInterfaces)
  12047. {
  12048. if (ifaceInst.mInterfaceType == wantType)
  12049. {
  12050. if (checkAccessibility)
  12051. {
  12052. if (checkActiveTypeDef == NULL)
  12053. checkActiveTypeDef = GetActiveTypeDef(NULL, false);
  12054. // We need to be lenient when validating generic constraints
  12055. // Otherwise "T<A> where T : IB" declared in a lib won't be able to match a type B in a using project 'C',
  12056. // because this check will see the lib using 'C', which it won't consider visible
  12057. if ((checkActiveTypeDef != NULL) &&
  12058. ((mCurMethodInstance != NULL) && (mContext->mCurTypeState != NULL) && (mContext->mCurTypeState->mResolveKind != BfTypeState::ResolveKind_BuildingGenericParams)))
  12059. {
  12060. if ((!srcType->IsTypeMemberAccessible(ifaceInst.mDeclaringType, checkActiveTypeDef)) ||
  12061. (!srcType->IsTypeMemberIncluded(ifaceInst.mDeclaringType, checkActiveTypeDef, this)))
  12062. {
  12063. continue;
  12064. }
  12065. }
  12066. }
  12067. return true;
  12068. }
  12069. }
  12070. checkType = checkType->GetImplBaseType();
  12071. if ((checkType != NULL) && (checkType->mDefineState < BfTypeDefineState_HasInterfaces))
  12072. {
  12073. PopulateType(checkType, BfPopulateType_Interfaces);
  12074. }
  12075. }
  12076. if (srcType->IsTypedPrimitive())
  12077. {
  12078. BfType* underlyingType = srcType->GetUnderlyingType();
  12079. if (underlyingType->IsWrappableType())
  12080. {
  12081. BfTypeInstance* wrappedType = GetWrappedStructType(underlyingType);
  12082. if ((wrappedType != NULL) && (wrappedType != srcType))
  12083. return TypeIsSubTypeOf(wrappedType, wantType, checkAccessibility);
  12084. }
  12085. }
  12086. return false;
  12087. }
  12088. auto srcBaseType = srcType->mBaseType;
  12089. return TypeIsSubTypeOf(srcBaseType, wantType);
  12090. }
  12091. // Positive value means that toType encompasses fromType, negative value means toType is encompassed by formType
  12092. // INT_MAX means the types are not related
  12093. int BfModule::GetTypeDistance(BfType* fromType, BfType* toType)
  12094. {
  12095. if (fromType == toType)
  12096. return 0;
  12097. if (fromType->IsPrimitiveType())
  12098. {
  12099. if (!toType->IsPrimitiveType())
  12100. return INT_MAX;
  12101. auto fromPrimType = (BfPrimitiveType*)fromType;
  12102. auto toPrimType = (BfPrimitiveType*)toType;
  12103. if ((fromPrimType->IsIntegral()) && (toPrimType->IsIntegral()))
  12104. {
  12105. int fromBitSize = fromPrimType->mSize * 8;
  12106. if (fromPrimType->IsSigned())
  12107. fromBitSize--;
  12108. int toBitSize = toPrimType->mSize * 8;
  12109. if (toPrimType->IsSigned())
  12110. toBitSize--;
  12111. return fromBitSize - toBitSize;
  12112. }
  12113. if ((fromPrimType->IsFloat()) && (toPrimType->IsFloat()))
  12114. {
  12115. return (fromPrimType->mSize * 8) - (toPrimType->mSize * 8);
  12116. }
  12117. if (((fromPrimType->IsIntegral()) || (fromPrimType->IsFloat())) &&
  12118. ((toPrimType->IsIntegral()) || (toPrimType->IsFloat())))
  12119. {
  12120. int sizeDiff = (fromPrimType->mSize * 8) - (toPrimType->mSize * 8);
  12121. if (sizeDiff < 0)
  12122. sizeDiff--;
  12123. else
  12124. sizeDiff++;
  12125. return sizeDiff;
  12126. }
  12127. return INT_MAX;
  12128. }
  12129. auto fromTypeInstance = fromType->ToTypeInstance();
  12130. auto toTypeInstance = toType->ToTypeInstance();
  12131. if ((fromTypeInstance != NULL) != (toTypeInstance != NULL))
  12132. return INT_MAX; // Ever valid?
  12133. if ((fromTypeInstance != NULL) && (toTypeInstance != NULL))
  12134. {
  12135. if ((fromTypeInstance->IsNullable()) && (toTypeInstance->IsNullable()))
  12136. return GetTypeDistance(fromTypeInstance->GetUnderlyingType(), toTypeInstance->GetUnderlyingType());
  12137. int inheritDistance = toTypeInstance->mInheritDepth - fromTypeInstance->mInheritDepth;
  12138. auto mostSpecificInstance = (inheritDistance < 0) ? fromTypeInstance : toTypeInstance;
  12139. auto leastSpecificInstance = (inheritDistance < 0) ? toTypeInstance : fromTypeInstance;
  12140. while (mostSpecificInstance != NULL)
  12141. {
  12142. if (mostSpecificInstance == leastSpecificInstance)
  12143. return inheritDistance;
  12144. mostSpecificInstance = mostSpecificInstance->mBaseType;
  12145. }
  12146. }
  12147. return INT_MAX;
  12148. }
  12149. bool BfModule::IsTypeMoreSpecific(BfType* leftType, BfType* rightType)
  12150. {
  12151. if (leftType->IsGenericTypeInstance())
  12152. {
  12153. if (!rightType->IsGenericTypeInstance())
  12154. return true;
  12155. auto leftGenericType = (BfTypeInstance*)leftType;
  12156. auto rightGenericType = (BfTypeInstance*)rightType;
  12157. if (leftGenericType->mTypeDef != rightGenericType->mTypeDef)
  12158. return false;
  12159. bool isBetter = false;
  12160. bool isWorse = false;
  12161. for (int argIdx = 0; argIdx < (int)leftGenericType->mGenericTypeInfo->mTypeGenericArguments.size(); argIdx++)
  12162. {
  12163. if (IsTypeMoreSpecific(leftGenericType->mGenericTypeInfo->mTypeGenericArguments[argIdx], rightGenericType->mGenericTypeInfo->mTypeGenericArguments[argIdx]))
  12164. isBetter = true;
  12165. if (IsTypeMoreSpecific(rightGenericType->mGenericTypeInfo->mTypeGenericArguments[argIdx], leftGenericType->mGenericTypeInfo->mTypeGenericArguments[argIdx]))
  12166. isWorse = true;
  12167. }
  12168. return (isBetter) && (!isWorse);
  12169. }
  12170. return false;
  12171. }
  12172. StringT<128> BfModule::TypeToString(BfType* resolvedType, Array<String>* genericMethodParamNameOverrides)
  12173. {
  12174. BfTypeNameFlags flags = BfTypeNameFlags_None;
  12175. if ((mCurTypeInstance == NULL) || (!mCurTypeInstance->IsUnspecializedTypeVariation()))
  12176. flags = BfTypeNameFlag_ResolveGenericParamNames;
  12177. StringT<128> str;
  12178. DoTypeToString(str, resolvedType, flags, genericMethodParamNameOverrides);
  12179. return str;
  12180. }
  12181. StringT<128> BfModule::TypeToString(BfType* resolvedType, BfTypeNameFlags typeNameFlags, Array<String>* genericMethodParamNameOverrides)
  12182. {
  12183. StringT<128> str;
  12184. DoTypeToString(str, resolvedType, typeNameFlags, genericMethodParamNameOverrides);
  12185. return str;
  12186. }
  12187. void BfModule::VariantToString(StringImpl& str, const BfVariant& variant)
  12188. {
  12189. switch (variant.mTypeCode)
  12190. {
  12191. case BfTypeCode_Boolean:
  12192. if (variant.mUInt64 == 0)
  12193. str += "false";
  12194. else if (variant.mUInt64 == 1)
  12195. str += "true";
  12196. else
  12197. str += StrFormat("%lld", variant.mInt64);
  12198. break;
  12199. case BfTypeCode_Int8:
  12200. case BfTypeCode_UInt8:
  12201. case BfTypeCode_Int16:
  12202. case BfTypeCode_UInt16:
  12203. case BfTypeCode_Int32:
  12204. str += StrFormat("%d", variant.mInt32);
  12205. break;
  12206. case BfTypeCode_Char8:
  12207. case BfTypeCode_Char16:
  12208. case BfTypeCode_Char32:
  12209. if ((variant.mUInt32 >= 32) && (variant.mUInt32 <= 0x7E))
  12210. str += StrFormat("'%c'", (char)variant.mUInt32);
  12211. else if (variant.mUInt32 <= 0xFF)
  12212. str += StrFormat("'\\x%2X'", variant.mUInt32);
  12213. else
  12214. str += StrFormat("'\\u{%X}'", variant.mUInt32);
  12215. break;
  12216. case BfTypeCode_UInt32:
  12217. str += StrFormat("%lu", variant.mUInt32);
  12218. break;
  12219. case BfTypeCode_Int64:
  12220. str += StrFormat("%lld", variant.mInt64);
  12221. break;
  12222. case BfTypeCode_UInt64:
  12223. str += StrFormat("%llu", variant.mInt64);
  12224. break;
  12225. case BfTypeCode_Float:
  12226. {
  12227. char cstr[64];
  12228. ExactMinimalFloatToStr(variant.mSingle, cstr);
  12229. str += cstr;
  12230. if (strchr(cstr, '.') == NULL)
  12231. str += ".0f";
  12232. else
  12233. str += "f";
  12234. }
  12235. break;
  12236. case BfTypeCode_Double:
  12237. {
  12238. char cstr[64];
  12239. ExactMinimalDoubleToStr(variant.mDouble, cstr);
  12240. str += cstr;
  12241. if (strchr(cstr, '.') == NULL)
  12242. str += ".0";
  12243. }
  12244. break;
  12245. case BfTypeCode_StringId:
  12246. {
  12247. int stringId = variant.mInt32;
  12248. auto stringPoolEntry = mContext->mStringObjectIdMap[stringId];
  12249. str += '"';
  12250. str += SlashString(stringPoolEntry.mString, false, false, true);
  12251. str += '"';
  12252. }
  12253. break;
  12254. case BfTypeCode_Let:
  12255. str += "?";
  12256. break;
  12257. default: break;
  12258. }
  12259. }
  12260. void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameFlags typeNameFlags, Array<String>* genericMethodNameOverrides)
  12261. {
  12262. BP_ZONE("BfModule::DoTypeToString");
  12263. // This is clearly wrong. If we pass in @T0 from a generic type, this would immediately disable the ability to get its name
  12264. /*if (resolvedType->IsUnspecializedType())
  12265. typeNameFlags = (BfTypeNameFlags)(typeNameFlags & ~BfTypeNameFlag_ResolveGenericParamNames);*/
  12266. if (resolvedType->IsBoxed())
  12267. {
  12268. auto boxedType = (BfBoxedType*)resolvedType;
  12269. str += "boxed ";
  12270. DoTypeToString(str, boxedType->mElementType, typeNameFlags, genericMethodNameOverrides);
  12271. if (boxedType->mBoxedFlags == BfBoxedType::BoxedFlags_StructPtr)
  12272. str += "*";
  12273. return;
  12274. }
  12275. else if ((resolvedType->IsArray()) && ((typeNameFlags & BfTypeNameFlag_UseArrayImplType) == 0))
  12276. {
  12277. auto arrayType = (BfArrayType*)resolvedType;
  12278. DoTypeToString(str, arrayType->mGenericTypeInfo->mTypeGenericArguments[0], typeNameFlags, genericMethodNameOverrides);
  12279. str += "[";
  12280. for (int i = 1; i < arrayType->mDimensions; i++)
  12281. str += ",";
  12282. str += "]";
  12283. return;
  12284. }
  12285. else if (resolvedType->IsNullable())
  12286. {
  12287. auto genericType = (BfTypeInstance*)resolvedType;
  12288. auto elementType = genericType->mGenericTypeInfo->mTypeGenericArguments[0];
  12289. DoTypeToString(str, elementType, typeNameFlags, genericMethodNameOverrides);
  12290. str += "?";
  12291. return;
  12292. }
  12293. else if (resolvedType->IsTuple())
  12294. {
  12295. BfTypeInstance* tupleType = (BfTypeInstance*)resolvedType;
  12296. str += "(";
  12297. for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
  12298. {
  12299. if (fieldIdx > 0)
  12300. str += ", ";
  12301. BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx];
  12302. BfFieldDef* fieldDef = fieldInstance->GetFieldDef();
  12303. BfTypeNameFlags innerFlags = (BfTypeNameFlags)(typeNameFlags & ~(BfTypeNameFlag_OmitNamespace | BfTypeNameFlag_OmitOuterType | BfTypeNameFlag_ExtendedInfo));
  12304. DoTypeToString(str, fieldInstance->GetResolvedType(), innerFlags, genericMethodNameOverrides);
  12305. char c = fieldDef->mName[0];
  12306. if ((c < '0') || (c > '9'))
  12307. {
  12308. str += " ";
  12309. str += fieldDef->mName;
  12310. }
  12311. }
  12312. str += ")";
  12313. return;
  12314. }
  12315. else if (resolvedType->IsDelegateFromTypeRef() || resolvedType->IsFunctionFromTypeRef())
  12316. {
  12317. SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance);
  12318. auto delegateType = (BfTypeInstance*)resolvedType;
  12319. auto delegateInfo = resolvedType->GetDelegateInfo();
  12320. if (mCurTypeInstance == delegateType)
  12321. {
  12322. // Don't try to use ourselves for generic param resolution. This should only happen for debug printings from
  12323. // within InitType and such, not actual user-facing display
  12324. mCurTypeInstance = NULL;
  12325. }
  12326. auto methodDef = delegateType->mTypeDef->mMethods[0];
  12327. switch (methodDef->mCallingConvention)
  12328. {
  12329. case BfCallingConvention_Stdcall:
  12330. str += "[StdCall] ";
  12331. break;
  12332. case BfCallingConvention_Fastcall:
  12333. str += "[FastCall] ";
  12334. break;
  12335. default:
  12336. break;
  12337. }
  12338. if (resolvedType->IsDelegateFromTypeRef())
  12339. str += "delegate ";
  12340. else
  12341. str += "function ";
  12342. if (delegateInfo->mCallingConvention != BfCallingConvention_Unspecified)
  12343. {
  12344. str += "[CallingConvention(";
  12345. switch (delegateInfo->mCallingConvention)
  12346. {
  12347. case BfCallingConvention_Cdecl:
  12348. str += ".Cdecl";
  12349. break;
  12350. case BfCallingConvention_Stdcall:
  12351. str += ".Stdcall";
  12352. break;
  12353. case BfCallingConvention_Fastcall:
  12354. str += ".Fastcall";
  12355. break;
  12356. }
  12357. str += ")] ";
  12358. }
  12359. DoTypeToString(str, delegateInfo->mReturnType, typeNameFlags, genericMethodNameOverrides);
  12360. str += "(";
  12361. bool isFirstParam = true;//
  12362. for (int paramIdx = 0; paramIdx < methodDef->mParams.size(); paramIdx++)
  12363. {
  12364. if (!isFirstParam)
  12365. str += ", ";
  12366. auto paramDef = methodDef->mParams[paramIdx];
  12367. BfTypeNameFlags innerFlags = (BfTypeNameFlags)(typeNameFlags & ~(BfTypeNameFlag_OmitNamespace | BfTypeNameFlag_OmitOuterType | BfTypeNameFlag_ExtendedInfo));
  12368. if (paramDef->mParamKind == BfParamKind_VarArgs)
  12369. {
  12370. str += "...";
  12371. continue;
  12372. }
  12373. auto paramType = delegateInfo->mParams[paramIdx];
  12374. if ((paramIdx == 0) && (delegateInfo->mHasExplicitThis))
  12375. {
  12376. if ((methodDef->mIsMutating) && (paramType->IsValueType()))
  12377. str += "mut ";
  12378. }
  12379. DoTypeToString(str, paramType, innerFlags, genericMethodNameOverrides);
  12380. if (!paramDef->mName.IsEmpty())
  12381. {
  12382. str += " ";
  12383. str += paramDef->mName;
  12384. }
  12385. isFirstParam = false;
  12386. }
  12387. str += ")";
  12388. return;
  12389. }
  12390. else if (resolvedType->IsMethodRef())
  12391. {
  12392. auto methodRefType = (BfMethodRefType*)resolvedType;
  12393. BfMethodInstance* methodInstance = methodRefType->mMethodRef;
  12394. if (methodRefType->IsDeleting())
  12395. {
  12396. str += "DELETED METHODREF";
  12397. return;
  12398. }
  12399. if (methodInstance == NULL)
  12400. {
  12401. str += "method reference NULL";
  12402. return;
  12403. }
  12404. str += "method reference ";
  12405. str += MethodToString(methodInstance, BfMethodNameFlag_NoAst);
  12406. return;
  12407. }
  12408. else if (resolvedType->IsTypeInstance())
  12409. {
  12410. BfTypeInstance* typeInstance = (BfTypeInstance*)resolvedType;
  12411. if ((typeNameFlags & BfTypeNameFlag_ExtendedInfo) != 0)
  12412. {
  12413. if (typeInstance->mTypeDef->mIsDelegate)
  12414. str += "delegate ";
  12415. else if (typeInstance->mTypeDef->mIsFunction)
  12416. str += "function ";
  12417. else if (typeInstance->mTypeDef->mTypeCode == BfTypeCode_Object)
  12418. str += "class ";
  12419. else if (typeInstance->mTypeDef->mTypeCode == BfTypeCode_Enum)
  12420. str += "enum ";
  12421. else if (typeInstance->mTypeDef->mTypeCode == BfTypeCode_Struct)
  12422. str += "struct ";
  12423. else if (typeInstance->mTypeDef->mTypeCode == BfTypeCode_TypeAlias)
  12424. str += "typealias ";
  12425. }
  12426. bool omitNamespace = (typeNameFlags & BfTypeNameFlag_OmitNamespace) != 0;
  12427. if ((typeNameFlags & BfTypeNameFlag_ReduceName) != 0)
  12428. {
  12429. for (auto& checkNamespace : mCurTypeInstance->mTypeDef->mNamespaceSearch)
  12430. {
  12431. if (checkNamespace == typeInstance->mTypeDef->mNamespace)
  12432. omitNamespace = true;
  12433. }
  12434. }
  12435. if ((!typeInstance->mTypeDef->mNamespace.IsEmpty()) && (!omitNamespace))
  12436. {
  12437. if (!typeInstance->mTypeDef->mNamespace.IsEmpty())
  12438. {
  12439. typeInstance->mTypeDef->mNamespace.ToString(str);
  12440. if (!typeInstance->mTypeDef->IsGlobalsContainer())
  12441. str += '.';
  12442. }
  12443. }
  12444. SizedArray<BfTypeDef*, 8> typeDefStack;
  12445. BfTypeDef* endTypeDef = NULL;
  12446. if (((typeNameFlags & BfTypeNameFlag_ReduceName) != 0) && (mCurTypeInstance != NULL))
  12447. {
  12448. auto checkTypeInst = typeInstance;
  12449. auto outerTypeInst = GetOuterType(checkTypeInst);
  12450. if (outerTypeInst != NULL)
  12451. {
  12452. checkTypeInst = outerTypeInst;
  12453. auto checkTypeDef = checkTypeInst->mTypeDef;
  12454. auto checkCurTypeInst = mCurTypeInstance; // Only used for ReduceName
  12455. BfTypeDef* checkCurTypeDef = NULL;
  12456. if (checkCurTypeInst != NULL)
  12457. checkCurTypeDef = checkCurTypeInst->mTypeDef;
  12458. while (checkCurTypeDef->mNestDepth > checkTypeDef->mNestDepth)
  12459. {
  12460. checkCurTypeInst = GetOuterType(checkCurTypeInst);
  12461. checkCurTypeDef = checkCurTypeInst->mTypeDef;
  12462. }
  12463. while (checkTypeDef != NULL)
  12464. {
  12465. if (TypeIsSubTypeOf(checkCurTypeInst, checkTypeInst))
  12466. {
  12467. endTypeDef = checkTypeDef;
  12468. break;
  12469. }
  12470. checkCurTypeInst = GetOuterType(checkCurTypeInst);
  12471. if (checkCurTypeInst == NULL)
  12472. break;
  12473. checkCurTypeDef = checkCurTypeInst->mTypeDef;
  12474. checkTypeInst = GetOuterType(checkTypeInst);
  12475. if (checkTypeInst == NULL)
  12476. break;
  12477. checkTypeDef = checkTypeInst->mTypeDef;
  12478. }
  12479. }
  12480. }
  12481. BfTypeDef* checkTypeDef = typeInstance->mTypeDef;
  12482. while (checkTypeDef != NULL)
  12483. {
  12484. typeDefStack.Add(checkTypeDef);
  12485. checkTypeDef = checkTypeDef->mOuterType;
  12486. if ((typeNameFlags & BfTypeNameFlag_OmitOuterType) != 0)
  12487. break;
  12488. if (checkTypeDef == endTypeDef)
  12489. break;
  12490. }
  12491. while (!typeDefStack.IsEmpty())
  12492. {
  12493. BfTypeDef* checkTypeDef = typeDefStack.back();
  12494. int depth = (int)typeDefStack.size() - 1;
  12495. typeDefStack.pop_back();
  12496. if (checkTypeDef->IsGlobalsContainer())
  12497. {
  12498. if ((typeNameFlags & BfTypeNameFlag_AddGlobalContainerName) != 0)
  12499. {
  12500. str += "G$";
  12501. str += checkTypeDef->mProject->mName;
  12502. }
  12503. }
  12504. else
  12505. {
  12506. checkTypeDef->mName->ToString(str);
  12507. if (!checkTypeDef->mGenericParamDefs.IsEmpty())
  12508. {
  12509. for (int ofs = 0; ofs < 3; ofs++)
  12510. {
  12511. int checkIdx = (int)str.length() - 1 - ofs;
  12512. if (checkIdx < 0)
  12513. break;
  12514. if (str[checkIdx] == '`')
  12515. {
  12516. str.RemoveToEnd(checkIdx);
  12517. break;
  12518. }
  12519. }
  12520. }
  12521. if (((typeNameFlags & BfTypeNameFlag_DisambiguateDups) != 0) && (checkTypeDef->mDupDetectedRevision != -1))
  12522. {
  12523. str += StrFormat("_%p", checkTypeDef);
  12524. }
  12525. }
  12526. int prevGenericParamCount = 0;
  12527. if (checkTypeDef->mOuterType != NULL)
  12528. {
  12529. prevGenericParamCount = (int)checkTypeDef->mOuterType->mGenericParamDefs.size();
  12530. }
  12531. if (resolvedType->IsGenericTypeInstance())
  12532. {
  12533. auto genericTypeInst = (BfTypeInstance*)resolvedType;
  12534. if (prevGenericParamCount != (int)checkTypeDef->mGenericParamDefs.size())
  12535. {
  12536. str += '<';
  12537. for (int i = prevGenericParamCount; i < (int)checkTypeDef->mGenericParamDefs.size(); i++)
  12538. {
  12539. BfType* typeGenericArg = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[i];
  12540. if (typeGenericArg->IsGenericParam())
  12541. {
  12542. if ((typeNameFlags & BfTypeNameFlag_ResolveGenericParamNames) == 0)
  12543. {
  12544. // We don't want the param names, just the commas (this is an unspecialized type reference)
  12545. if (i > prevGenericParamCount)
  12546. str += ',';
  12547. if ((typeNameFlags & BfTypeNameFlag_UseUnspecializedGenericParamNames) != 0)
  12548. {
  12549. str += checkTypeDef->mGenericParamDefs[i]->mName;
  12550. }
  12551. continue;
  12552. }
  12553. }
  12554. if (i > prevGenericParamCount)
  12555. str += ", ";
  12556. DoTypeToString(str, typeGenericArg, (BfTypeNameFlags)((typeNameFlags | BfTypeNameFlag_ShortConst) & ~(BfTypeNameFlag_OmitNamespace | BfTypeNameFlag_OmitOuterType | BfTypeNameFlag_ExtendedInfo)), genericMethodNameOverrides);
  12557. }
  12558. str += '>';
  12559. }
  12560. }
  12561. if (depth > 0)
  12562. str += '.';
  12563. };
  12564. if (typeInstance->IsTypeAlias())
  12565. {
  12566. if ((typeNameFlags & BfTypeNameFlag_ExtendedInfo) != 0)
  12567. {
  12568. auto underlyingType = typeInstance->GetUnderlyingType();
  12569. if (underlyingType != NULL)
  12570. {
  12571. str += " = ";
  12572. DoTypeToString(str, underlyingType, (BfTypeNameFlags)(typeNameFlags & ~(BfTypeNameFlag_OmitNamespace | BfTypeNameFlag_OmitOuterType | BfTypeNameFlag_ExtendedInfo)));
  12573. }
  12574. }
  12575. }
  12576. return;
  12577. }
  12578. else if (resolvedType->IsPrimitiveType())
  12579. {
  12580. auto primitiveType = (BfPrimitiveType*)resolvedType;
  12581. if (!primitiveType->mTypeDef->mNamespace.IsEmpty())
  12582. {
  12583. primitiveType->mTypeDef->mNamespace.ToString(str);
  12584. str += '.';
  12585. primitiveType->mTypeDef->mName->ToString(str);
  12586. return;
  12587. }
  12588. else
  12589. {
  12590. primitiveType->mTypeDef->mName->ToString(str);
  12591. return;
  12592. }
  12593. }
  12594. else if (resolvedType->IsPointer())
  12595. {
  12596. auto pointerType = (BfPointerType*)resolvedType;
  12597. DoTypeToString(str, pointerType->mElementType, typeNameFlags, genericMethodNameOverrides);
  12598. str += '*';
  12599. return;
  12600. }
  12601. else if (resolvedType->IsGenericParam())
  12602. {
  12603. bool doResolveGenericParams = (typeNameFlags & BfTypeNameFlag_ResolveGenericParamNames) != 0;
  12604. if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsUnspecializedTypeVariation()))
  12605. doResolveGenericParams = false;
  12606. auto genericParam = (BfGenericParamType*)resolvedType;
  12607. if (genericParam->mGenericParamKind == BfGenericParamKind_Method)
  12608. {
  12609. if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mIsUnspecializedVariation))
  12610. doResolveGenericParams = false;
  12611. }
  12612. if (!doResolveGenericParams)
  12613. {
  12614. if (genericParam->mGenericParamKind == BfGenericParamKind_Method)
  12615. {
  12616. if (genericMethodNameOverrides != NULL)
  12617. {
  12618. BF_ASSERT(genericParam->mGenericParamIdx < genericMethodNameOverrides->mSize);
  12619. if (genericParam->mGenericParamIdx < genericMethodNameOverrides->mSize)
  12620. {
  12621. str += (*genericMethodNameOverrides)[genericParam->mGenericParamIdx];
  12622. return;
  12623. }
  12624. }
  12625. str += StrFormat("@M%d", genericParam->mGenericParamIdx);
  12626. return;
  12627. }
  12628. str += StrFormat("@T%d", genericParam->mGenericParamIdx);
  12629. return;
  12630. }
  12631. if ((genericParam->mGenericParamKind == BfGenericParamKind_Type) && (mCurTypeInstance == NULL))
  12632. {
  12633. str += StrFormat("@T%d", genericParam->mGenericParamIdx);
  12634. return;
  12635. }
  12636. if (genericParam->mGenericParamKind == BfGenericParamKind_Method)
  12637. {
  12638. if (genericMethodNameOverrides != NULL)
  12639. {
  12640. str += (*genericMethodNameOverrides)[genericParam->mGenericParamIdx];
  12641. return;
  12642. }
  12643. if (mCurMethodInstance == NULL)
  12644. {
  12645. str += StrFormat("@M%d", genericParam->mGenericParamIdx);
  12646. return;
  12647. }
  12648. }
  12649. //TEMPORARY
  12650. if (genericParam->mGenericParamKind == BfGenericParamKind_Type)
  12651. {
  12652. auto curTypeInstance = mCurTypeInstance;
  12653. if (mCurMethodInstance != NULL)
  12654. curTypeInstance = mCurMethodInstance->mMethodInstanceGroup->mOwner;
  12655. if ((curTypeInstance == NULL) || (!curTypeInstance->IsGenericTypeInstance()))
  12656. {
  12657. str += StrFormat("@T%d", genericParam->mGenericParamIdx);
  12658. return;
  12659. }
  12660. }
  12661. auto genericParamInstance = GetGenericParamInstance(genericParam);
  12662. auto genericParamDef = genericParamInstance->GetGenericParamDef();
  12663. if (genericParamDef != NULL)
  12664. str += genericParamInstance->GetGenericParamDef()->mName;
  12665. else
  12666. str += "external generic " + TypeToString(genericParamInstance->mExternType, typeNameFlags, genericMethodNameOverrides);
  12667. return;
  12668. }
  12669. else if (resolvedType->IsRef())
  12670. {
  12671. auto refType = (BfRefType*)resolvedType;
  12672. if (refType->mRefKind == BfRefType::RefKind_Ref)
  12673. {
  12674. str += "ref ";
  12675. DoTypeToString(str, refType->mElementType, typeNameFlags, genericMethodNameOverrides);
  12676. return;
  12677. }
  12678. else if (refType->mRefKind == BfRefType::RefKind_In)
  12679. {
  12680. str += "in ";
  12681. DoTypeToString(str, refType->mElementType, typeNameFlags, genericMethodNameOverrides);
  12682. return;
  12683. }
  12684. else if (refType->mRefKind == BfRefType::RefKind_Out)
  12685. {
  12686. str += "out ";
  12687. DoTypeToString(str, refType->mElementType, typeNameFlags, genericMethodNameOverrides);
  12688. return;
  12689. }
  12690. else
  12691. {
  12692. str += "mut ";
  12693. DoTypeToString(str, refType->mElementType, typeNameFlags, genericMethodNameOverrides);
  12694. return;
  12695. }
  12696. }
  12697. else if (resolvedType->IsModifiedTypeType())
  12698. {
  12699. auto retTypeType = (BfModifiedTypeType*)resolvedType;
  12700. str += BfTokenToString(retTypeType->mModifiedKind);
  12701. str += "(";
  12702. DoTypeToString(str, retTypeType->mElementType, typeNameFlags, genericMethodNameOverrides);
  12703. str += ")";
  12704. return;
  12705. }
  12706. else if (resolvedType->IsConcreteInterfaceType())
  12707. {
  12708. auto concreteTypeType = (BfConcreteInterfaceType*)resolvedType;
  12709. str += "concrete ";
  12710. DoTypeToString(str, concreteTypeType->mInterface, typeNameFlags, genericMethodNameOverrides);
  12711. return;
  12712. }
  12713. else if (resolvedType->IsUnknownSizedArrayType())
  12714. {
  12715. auto arrayType = (BfUnknownSizedArrayType*)resolvedType;
  12716. DoTypeToString(str, arrayType->mElementType, typeNameFlags, genericMethodNameOverrides);
  12717. str += "[";
  12718. DoTypeToString(str, arrayType->mElementCountSource, typeNameFlags, genericMethodNameOverrides);
  12719. str += "]";
  12720. return;
  12721. }
  12722. else if (resolvedType->IsSizedArray())
  12723. {
  12724. auto arrayType = (BfSizedArrayType*)resolvedType;
  12725. if (arrayType->mElementCount == -1)
  12726. {
  12727. DoTypeToString(str, arrayType->mElementType, typeNameFlags, genericMethodNameOverrides);
  12728. str += "[?]";
  12729. return;
  12730. }
  12731. DoTypeToString(str, arrayType->mElementType, typeNameFlags, genericMethodNameOverrides);
  12732. str += StrFormat("[%d]", arrayType->mElementCount);
  12733. return;
  12734. }
  12735. else if (resolvedType->IsConstExprValue())
  12736. {
  12737. auto constExprValueType = (BfConstExprValueType*)resolvedType;
  12738. if ((typeNameFlags & BfTypeNameFlag_ShortConst) == 0)
  12739. {
  12740. str += "const ";
  12741. DoTypeToString(str, constExprValueType->mType, typeNameFlags, genericMethodNameOverrides);
  12742. str += " ";
  12743. }
  12744. VariantToString(str, constExprValueType->mValue);
  12745. return;
  12746. }
  12747. BFMODULE_FATAL(this, "Not implemented");
  12748. str += "???";
  12749. return;
  12750. }