BfExprEvaluator.cpp 900 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248202492025020251202522025320254202552025620257202582025920260202612026220263202642026520266202672026820269202702027120272202732027420275202762027720278202792028020281202822028320284202852028620287202882028920290202912029220293202942029520296202972029820299203002030120302203032030420305203062030720308203092031020311203122031320314203152031620317203182031920320203212032220323203242032520326203272032820329203302033120332203332033420335203362033720338203392034020341203422034320344203452034620347203482034920350203512035220353203542035520356203572035820359203602036120362203632036420365203662036720368203692037020371203722037320374203752037620377203782037920380203812038220383203842038520386203872038820389203902039120392203932039420395203962039720398203992040020401204022040320404204052040620407204082040920410204112041220413204142041520416204172041820419204202042120422204232042420425204262042720428204292043020431204322043320434204352043620437204382043920440204412044220443204442044520446204472044820449204502045120452204532045420455204562045720458204592046020461204622046320464204652046620467204682046920470204712047220473204742047520476204772047820479204802048120482204832048420485204862048720488204892049020491204922049320494204952049620497204982049920500205012050220503205042050520506205072050820509205102051120512205132051420515205162051720518205192052020521205222052320524205252052620527205282052920530205312053220533205342053520536205372053820539205402054120542205432054420545205462054720548205492055020551205522055320554205552055620557205582055920560205612056220563205642056520566205672056820569205702057120572205732057420575205762057720578205792058020581205822058320584205852058620587205882058920590205912059220593205942059520596205972059820599206002060120602206032060420605206062060720608206092061020611206122061320614206152061620617206182061920620206212062220623206242062520626206272062820629206302063120632206332063420635206362063720638206392064020641206422064320644206452064620647206482064920650206512065220653206542065520656206572065820659206602066120662206632066420665206662066720668206692067020671206722067320674206752067620677206782067920680206812068220683206842068520686206872068820689206902069120692206932069420695206962069720698206992070020701207022070320704207052070620707207082070920710207112071220713207142071520716207172071820719207202072120722207232072420725207262072720728207292073020731207322073320734207352073620737207382073920740207412074220743207442074520746207472074820749207502075120752207532075420755207562075720758207592076020761207622076320764207652076620767207682076920770207712077220773207742077520776207772077820779207802078120782207832078420785207862078720788207892079020791207922079320794207952079620797207982079920800208012080220803208042080520806208072080820809208102081120812208132081420815208162081720818208192082020821208222082320824208252082620827208282082920830208312083220833208342083520836208372083820839208402084120842208432084420845208462084720848208492085020851208522085320854208552085620857208582085920860208612086220863208642086520866208672086820869208702087120872208732087420875208762087720878208792088020881208822088320884208852088620887208882088920890208912089220893208942089520896208972089820899209002090120902209032090420905209062090720908209092091020911209122091320914209152091620917209182091920920209212092220923209242092520926209272092820929209302093120932209332093420935209362093720938209392094020941209422094320944209452094620947209482094920950209512095220953209542095520956209572095820959209602096120962209632096420965209662096720968209692097020971209722097320974209752097620977209782097920980209812098220983209842098520986209872098820989209902099120992209932099420995209962099720998209992100021001210022100321004210052100621007210082100921010210112101221013210142101521016210172101821019210202102121022210232102421025210262102721028210292103021031210322103321034210352103621037210382103921040210412104221043210442104521046210472104821049210502105121052210532105421055210562105721058210592106021061210622106321064210652106621067210682106921070210712107221073210742107521076210772107821079210802108121082210832108421085210862108721088210892109021091210922109321094210952109621097210982109921100211012110221103211042110521106211072110821109211102111121112211132111421115211162111721118211192112021121211222112321124211252112621127211282112921130211312113221133211342113521136211372113821139211402114121142211432114421145211462114721148211492115021151211522115321154211552115621157211582115921160211612116221163211642116521166211672116821169211702117121172211732117421175211762117721178211792118021181211822118321184211852118621187211882118921190211912119221193211942119521196211972119821199212002120121202212032120421205212062120721208212092121021211212122121321214212152121621217212182121921220212212122221223212242122521226212272122821229212302123121232212332123421235212362123721238212392124021241212422124321244212452124621247212482124921250212512125221253212542125521256212572125821259212602126121262212632126421265212662126721268212692127021271212722127321274212752127621277212782127921280212812128221283212842128521286212872128821289212902129121292212932129421295212962129721298212992130021301213022130321304213052130621307213082130921310213112131221313213142131521316213172131821319213202132121322213232132421325213262132721328213292133021331213322133321334213352133621337213382133921340213412134221343213442134521346213472134821349213502135121352213532135421355213562135721358213592136021361213622136321364213652136621367213682136921370213712137221373213742137521376213772137821379213802138121382213832138421385213862138721388213892139021391213922139321394213952139621397213982139921400214012140221403214042140521406214072140821409214102141121412214132141421415214162141721418214192142021421214222142321424214252142621427214282142921430214312143221433214342143521436214372143821439214402144121442214432144421445214462144721448214492145021451214522145321454214552145621457214582145921460214612146221463214642146521466214672146821469214702147121472214732147421475214762147721478214792148021481214822148321484214852148621487214882148921490214912149221493214942149521496214972149821499215002150121502215032150421505215062150721508215092151021511215122151321514215152151621517215182151921520215212152221523215242152521526215272152821529215302153121532215332153421535215362153721538215392154021541215422154321544215452154621547215482154921550215512155221553215542155521556215572155821559215602156121562215632156421565215662156721568215692157021571215722157321574215752157621577215782157921580215812158221583215842158521586215872158821589215902159121592215932159421595215962159721598215992160021601216022160321604216052160621607216082160921610216112161221613216142161521616216172161821619216202162121622216232162421625216262162721628216292163021631216322163321634216352163621637216382163921640216412164221643216442164521646216472164821649216502165121652216532165421655216562165721658216592166021661216622166321664216652166621667216682166921670216712167221673216742167521676216772167821679216802168121682216832168421685216862168721688216892169021691216922169321694216952169621697216982169921700217012170221703217042170521706217072170821709217102171121712217132171421715217162171721718217192172021721217222172321724217252172621727217282172921730217312173221733217342173521736217372173821739217402174121742217432174421745217462174721748217492175021751217522175321754217552175621757217582175921760217612176221763217642176521766217672176821769217702177121772217732177421775217762177721778217792178021781217822178321784217852178621787217882178921790217912179221793217942179521796217972179821799218002180121802218032180421805218062180721808218092181021811218122181321814218152181621817218182181921820218212182221823218242182521826218272182821829218302183121832218332183421835218362183721838218392184021841218422184321844218452184621847218482184921850218512185221853218542185521856218572185821859218602186121862218632186421865218662186721868218692187021871218722187321874218752187621877218782187921880218812188221883218842188521886218872188821889218902189121892218932189421895218962189721898218992190021901219022190321904219052190621907219082190921910219112191221913219142191521916219172191821919219202192121922219232192421925219262192721928219292193021931219322193321934219352193621937219382193921940219412194221943219442194521946219472194821949219502195121952219532195421955219562195721958219592196021961219622196321964219652196621967219682196921970219712197221973219742197521976219772197821979219802198121982219832198421985219862198721988219892199021991219922199321994219952199621997219982199922000220012200222003220042200522006220072200822009220102201122012220132201422015220162201722018220192202022021220222202322024220252202622027220282202922030220312203222033220342203522036220372203822039220402204122042220432204422045220462204722048220492205022051220522205322054220552205622057220582205922060220612206222063220642206522066220672206822069220702207122072220732207422075220762207722078220792208022081220822208322084220852208622087220882208922090220912209222093220942209522096220972209822099221002210122102221032210422105221062210722108221092211022111221122211322114221152211622117221182211922120221212212222123221242212522126221272212822129221302213122132221332213422135221362213722138221392214022141221422214322144221452214622147221482214922150221512215222153221542215522156221572215822159221602216122162221632216422165221662216722168221692217022171221722217322174221752217622177221782217922180221812218222183221842218522186221872218822189221902219122192221932219422195221962219722198221992220022201222022220322204222052220622207222082220922210222112221222213222142221522216222172221822219222202222122222222232222422225222262222722228222292223022231222322223322234222352223622237222382223922240222412224222243222442224522246222472224822249222502225122252222532225422255222562225722258222592226022261222622226322264222652226622267222682226922270222712227222273222742227522276222772227822279222802228122282222832228422285222862228722288222892229022291222922229322294222952229622297222982229922300223012230222303223042230522306223072230822309223102231122312223132231422315223162231722318223192232022321223222232322324223252232622327223282232922330223312233222333223342233522336223372233822339223402234122342223432234422345223462234722348223492235022351223522235322354223552235622357223582235922360223612236222363223642236522366223672236822369223702237122372223732237422375223762237722378223792238022381223822238322384223852238622387223882238922390223912239222393223942239522396223972239822399224002240122402224032240422405224062240722408224092241022411224122241322414224152241622417224182241922420224212242222423224242242522426224272242822429224302243122432224332243422435224362243722438224392244022441224422244322444224452244622447224482244922450224512245222453224542245522456224572245822459224602246122462224632246422465224662246722468224692247022471224722247322474224752247622477224782247922480224812248222483224842248522486224872248822489224902249122492224932249422495224962249722498224992250022501225022250322504225052250622507225082250922510225112251222513225142251522516225172251822519225202252122522225232252422525225262252722528225292253022531225322253322534225352253622537225382253922540225412254222543225442254522546225472254822549225502255122552225532255422555225562255722558225592256022561225622256322564225652256622567225682256922570225712257222573225742257522576225772257822579225802258122582225832258422585225862258722588225892259022591225922259322594225952259622597225982259922600226012260222603226042260522606226072260822609226102261122612226132261422615226162261722618226192262022621226222262322624226252262622627226282262922630226312263222633226342263522636226372263822639226402264122642226432264422645226462264722648226492265022651226522265322654226552265622657226582265922660226612266222663226642266522666226672266822669226702267122672226732267422675226762267722678226792268022681226822268322684226852268622687226882268922690226912269222693226942269522696226972269822699227002270122702227032270422705227062270722708227092271022711227122271322714227152271622717227182271922720227212272222723227242272522726227272272822729227302273122732227332273422735227362273722738227392274022741227422274322744227452274622747227482274922750227512275222753227542275522756227572275822759227602276122762227632276422765227662276722768227692277022771227722277322774227752277622777227782277922780227812278222783227842278522786227872278822789227902279122792227932279422795227962279722798227992280022801228022280322804228052280622807228082280922810228112281222813228142281522816228172281822819228202282122822228232282422825228262282722828228292283022831228322283322834228352283622837228382283922840228412284222843228442284522846228472284822849228502285122852228532285422855228562285722858228592286022861228622286322864228652286622867228682286922870228712287222873228742287522876228772287822879228802288122882228832288422885228862288722888228892289022891228922289322894228952289622897228982289922900229012290222903229042290522906229072290822909229102291122912229132291422915229162291722918229192292022921229222292322924229252292622927229282292922930229312293222933229342293522936229372293822939229402294122942229432294422945229462294722948229492295022951229522295322954229552295622957229582295922960229612296222963229642296522966229672296822969229702297122972229732297422975229762297722978229792298022981229822298322984229852298622987229882298922990229912299222993229942299522996229972299822999230002300123002230032300423005230062300723008230092301023011230122301323014230152301623017230182301923020230212302223023230242302523026230272302823029230302303123032230332303423035230362303723038230392304023041230422304323044230452304623047230482304923050230512305223053230542305523056230572305823059230602306123062230632306423065230662306723068230692307023071230722307323074230752307623077230782307923080230812308223083230842308523086230872308823089230902309123092230932309423095230962309723098230992310023101231022310323104231052310623107231082310923110231112311223113231142311523116231172311823119231202312123122231232312423125231262312723128231292313023131231322313323134231352313623137231382313923140231412314223143231442314523146231472314823149231502315123152231532315423155231562315723158231592316023161231622316323164231652316623167231682316923170231712317223173231742317523176231772317823179231802318123182231832318423185231862318723188231892319023191231922319323194231952319623197231982319923200232012320223203232042320523206232072320823209232102321123212232132321423215232162321723218232192322023221232222322323224232252322623227232282322923230232312323223233232342323523236232372323823239232402324123242232432324423245232462324723248232492325023251232522325323254232552325623257232582325923260232612326223263232642326523266232672326823269232702327123272232732327423275232762327723278232792328023281232822328323284232852328623287232882328923290232912329223293232942329523296232972329823299233002330123302233032330423305233062330723308233092331023311233122331323314233152331623317233182331923320233212332223323233242332523326233272332823329233302333123332233332333423335233362333723338233392334023341233422334323344233452334623347233482334923350233512335223353233542335523356233572335823359233602336123362233632336423365233662336723368233692337023371233722337323374233752337623377233782337923380233812338223383233842338523386233872338823389233902339123392233932339423395233962339723398233992340023401234022340323404234052340623407234082340923410234112341223413234142341523416234172341823419234202342123422234232342423425234262342723428234292343023431234322343323434234352343623437234382343923440234412344223443234442344523446234472344823449234502345123452234532345423455234562345723458234592346023461234622346323464234652346623467234682346923470234712347223473234742347523476234772347823479234802348123482234832348423485234862348723488234892349023491234922349323494234952349623497234982349923500235012350223503235042350523506235072350823509235102351123512235132351423515235162351723518235192352023521235222352323524235252352623527235282352923530235312353223533235342353523536235372353823539235402354123542235432354423545235462354723548235492355023551235522355323554235552355623557235582355923560235612356223563235642356523566235672356823569235702357123572235732357423575235762357723578235792358023581235822358323584235852358623587235882358923590235912359223593235942359523596235972359823599236002360123602236032360423605236062360723608236092361023611236122361323614236152361623617236182361923620236212362223623236242362523626236272362823629236302363123632236332363423635236362363723638236392364023641236422364323644236452364623647236482364923650236512365223653236542365523656236572365823659236602366123662236632366423665236662366723668236692367023671236722367323674236752367623677236782367923680236812368223683236842368523686236872368823689236902369123692236932369423695236962369723698236992370023701237022370323704237052370623707237082370923710237112371223713237142371523716237172371823719237202372123722237232372423725237262372723728237292373023731237322373323734237352373623737237382373923740237412374223743237442374523746237472374823749237502375123752237532375423755237562375723758237592376023761237622376323764237652376623767237682376923770237712377223773237742377523776237772377823779237802378123782237832378423785237862378723788237892379023791237922379323794237952379623797237982379923800238012380223803238042380523806238072380823809238102381123812238132381423815238162381723818238192382023821238222382323824238252382623827238282382923830238312383223833238342383523836238372383823839238402384123842238432384423845238462384723848238492385023851238522385323854238552385623857238582385923860238612386223863238642386523866238672386823869238702387123872238732387423875238762387723878238792388023881238822388323884238852388623887238882388923890238912389223893238942389523896238972389823899239002390123902239032390423905239062390723908239092391023911239122391323914239152391623917239182391923920239212392223923239242392523926239272392823929239302393123932239332393423935239362393723938239392394023941239422394323944239452394623947239482394923950239512395223953239542395523956239572395823959239602396123962239632396423965239662396723968239692397023971239722397323974239752397623977239782397923980239812398223983239842398523986239872398823989239902399123992239932399423995239962399723998239992400024001240022400324004240052400624007240082400924010240112401224013240142401524016240172401824019240202402124022240232402424025240262402724028240292403024031240322403324034240352403624037240382403924040240412404224043240442404524046240472404824049240502405124052240532405424055240562405724058240592406024061240622406324064240652406624067240682406924070240712407224073240742407524076240772407824079240802408124082240832408424085240862408724088240892409024091240922409324094240952409624097240982409924100241012410224103241042410524106241072410824109241102411124112241132411424115241162411724118241192412024121241222412324124241252412624127241282412924130241312413224133241342413524136241372413824139241402414124142241432414424145241462414724148241492415024151241522415324154241552415624157241582415924160241612416224163241642416524166241672416824169241702417124172241732417424175241762417724178241792418024181241822418324184241852418624187241882418924190241912419224193241942419524196241972419824199242002420124202242032420424205242062420724208242092421024211242122421324214242152421624217242182421924220242212422224223242242422524226242272422824229242302423124232242332423424235242362423724238242392424024241242422424324244242452424624247242482424924250242512425224253242542425524256242572425824259242602426124262242632426424265242662426724268242692427024271242722427324274242752427624277242782427924280242812428224283242842428524286242872428824289242902429124292242932429424295242962429724298242992430024301243022430324304243052430624307243082430924310243112431224313243142431524316243172431824319243202432124322243232432424325243262432724328243292433024331243322433324334243352433624337243382433924340243412434224343243442434524346243472434824349243502435124352243532435424355243562435724358243592436024361243622436324364243652436624367243682436924370243712437224373243742437524376243772437824379243802438124382243832438424385243862438724388243892439024391243922439324394243952439624397243982439924400244012440224403244042440524406244072440824409244102441124412244132441424415244162441724418244192442024421244222442324424244252442624427244282442924430244312443224433244342443524436244372443824439244402444124442244432444424445244462444724448244492445024451244522445324454244552445624457244582445924460244612446224463244642446524466244672446824469244702447124472244732447424475244762447724478244792448024481244822448324484244852448624487244882448924490244912449224493244942449524496244972449824499245002450124502245032450424505245062450724508245092451024511245122451324514245152451624517245182451924520245212452224523245242452524526245272452824529245302453124532245332453424535245362453724538245392454024541245422454324544245452454624547245482454924550245512455224553245542455524556245572455824559245602456124562245632456424565245662456724568245692457024571245722457324574245752457624577245782457924580245812458224583245842458524586245872458824589245902459124592245932459424595245962459724598245992460024601246022460324604246052460624607246082460924610246112461224613246142461524616246172461824619246202462124622246232462424625246262462724628246292463024631246322463324634246352463624637246382463924640246412464224643246442464524646246472464824649246502465124652246532465424655246562465724658246592466024661246622466324664246652466624667246682466924670246712467224673246742467524676246772467824679246802468124682246832468424685246862468724688246892469024691246922469324694246952469624697246982469924700247012470224703247042470524706247072470824709247102471124712247132471424715247162471724718247192472024721247222472324724247252472624727247282472924730247312473224733247342473524736247372473824739247402474124742247432474424745247462474724748247492475024751247522475324754247552475624757247582475924760247612476224763247642476524766247672476824769247702477124772247732477424775247762477724778247792478024781247822478324784247852478624787247882478924790247912479224793247942479524796247972479824799248002480124802248032480424805248062480724808248092481024811248122481324814248152481624817248182481924820248212482224823248242482524826248272482824829248302483124832248332483424835248362483724838248392484024841248422484324844248452484624847248482484924850248512485224853248542485524856248572485824859248602486124862248632486424865248662486724868248692487024871248722487324874248752487624877248782487924880248812488224883248842488524886248872488824889248902489124892248932489424895248962489724898248992490024901249022490324904249052490624907249082490924910249112491224913249142491524916249172491824919249202492124922249232492424925249262492724928249292493024931249322493324934249352493624937249382493924940249412494224943249442494524946249472494824949249502495124952249532495424955249562495724958249592496024961249622496324964249652496624967249682496924970249712497224973249742497524976249772497824979249802498124982249832498424985249862498724988249892499024991249922499324994249952499624997249982499925000250012500225003250042500525006250072500825009250102501125012250132501425015250162501725018250192502025021250222502325024250252502625027250282502925030250312503225033250342503525036250372503825039250402504125042250432504425045250462504725048250492505025051250522505325054250552505625057250582505925060250612506225063250642506525066250672506825069250702507125072250732507425075250762507725078250792508025081250822508325084250852508625087250882508925090250912509225093250942509525096250972509825099251002510125102251032510425105251062510725108251092511025111251122511325114251152511625117251182511925120251212512225123251242512525126251272512825129251302513125132251332513425135251362513725138251392514025141251422514325144251452514625147251482514925150251512515225153251542515525156251572515825159251602516125162251632516425165251662516725168251692517025171251722517325174251752517625177251782517925180251812518225183251842518525186251872518825189251902519125192251932519425195251962519725198251992520025201252022520325204252052520625207252082520925210252112521225213252142521525216252172521825219252202522125222252232522425225252262522725228252292523025231252322523325234252352523625237252382523925240252412524225243252442524525246252472524825249252502525125252252532525425255252562525725258252592526025261252622526325264252652526625267252682526925270252712527225273252742527525276252772527825279252802528125282252832528425285252862528725288252892529025291252922529325294252952529625297252982529925300253012530225303253042530525306253072530825309253102531125312253132531425315253162531725318253192532025321253222532325324253252532625327253282532925330253312533225333253342533525336253372533825339253402534125342253432534425345253462534725348253492535025351253522535325354253552535625357253582535925360253612536225363253642536525366253672536825369253702537125372253732537425375253762537725378253792538025381253822538325384253852538625387253882538925390253912539225393253942539525396253972539825399254002540125402254032540425405254062540725408254092541025411254122541325414254152541625417254182541925420254212542225423254242542525426254272542825429254302543125432254332543425435254362543725438254392544025441254422544325444254452544625447254482544925450254512545225453254542545525456254572545825459254602546125462254632546425465254662546725468254692547025471254722547325474254752547625477254782547925480254812548225483254842548525486254872548825489254902549125492254932549425495254962549725498254992550025501255022550325504255052550625507255082550925510255112551225513255142551525516255172551825519255202552125522255232552425525255262552725528255292553025531255322553325534255352553625537255382553925540255412554225543255442554525546255472554825549255502555125552255532555425555255562555725558255592556025561255622556325564255652556625567255682556925570255712557225573255742557525576255772557825579255802558125582255832558425585255862558725588255892559025591255922559325594255952559625597255982559925600256012560225603256042560525606256072560825609256102561125612256132561425615256162561725618256192562025621256222562325624256252562625627256282562925630256312563225633256342563525636256372563825639256402564125642256432564425645256462564725648256492565025651256522565325654256552565625657256582565925660256612566225663256642566525666256672566825669256702567125672256732567425675256762567725678256792568025681256822568325684256852568625687256882568925690256912569225693256942569525696256972569825699257002570125702257032570425705257062570725708257092571025711257122571325714257152571625717257182571925720257212572225723257242572525726257272572825729257302573125732257332573425735257362573725738257392574025741257422574325744257452574625747257482574925750257512575225753257542575525756257572575825759257602576125762257632576425765257662576725768257692577025771257722577325774257752577625777257782577925780257812578225783257842578525786257872578825789257902579125792257932579425795257962579725798257992580025801258022580325804258052580625807258082580925810258112581225813258142581525816258172581825819258202582125822258232582425825258262582725828258292583025831258322583325834258352583625837258382583925840258412584225843258442584525846258472584825849258502585125852258532585425855258562585725858258592586025861258622586325864258652586625867258682586925870258712587225873258742587525876258772587825879258802588125882258832588425885258862588725888258892589025891258922589325894258952589625897258982589925900259012590225903259042590525906259072590825909259102591125912259132591425915259162591725918259192592025921259222592325924259252592625927259282592925930259312593225933259342593525936259372593825939259402594125942259432594425945259462594725948259492595025951259522595325954259552595625957259582595925960259612596225963259642596525966259672596825969259702597125972259732597425975259762597725978259792598025981259822598325984259852598625987259882598925990259912599225993259942599525996259972599825999260002600126002260032600426005260062600726008260092601026011260122601326014260152601626017260182601926020260212602226023260242602526026260272602826029260302603126032260332603426035260362603726038260392604026041260422604326044260452604626047260482604926050260512605226053260542605526056260572605826059260602606126062260632606426065260662606726068260692607026071260722607326074260752607626077260782607926080260812608226083260842608526086260872608826089260902609126092260932609426095260962609726098260992610026101261022610326104261052610626107261082610926110261112611226113261142611526116261172611826119261202612126122261232612426125261262612726128261292613026131261322613326134261352613626137261382613926140261412614226143261442614526146261472614826149261502615126152261532615426155261562615726158261592616026161261622616326164261652616626167261682616926170261712617226173261742617526176261772617826179261802618126182261832618426185261862618726188261892619026191261922619326194261952619626197261982619926200262012620226203262042620526206262072620826209262102621126212262132621426215262162621726218262192622026221262222622326224262252622626227262282622926230262312623226233262342623526236262372623826239262402624126242262432624426245262462624726248262492625026251262522625326254262552625626257262582625926260262612626226263262642626526266262672626826269262702627126272262732627426275262762627726278262792628026281262822628326284262852628626287262882628926290262912629226293262942629526296262972629826299263002630126302263032630426305263062630726308263092631026311263122631326314263152631626317263182631926320263212632226323263242632526326263272632826329263302633126332263332633426335263362633726338263392634026341263422634326344263452634626347263482634926350263512635226353263542635526356263572635826359263602636126362263632636426365263662636726368263692637026371263722637326374263752637626377263782637926380263812638226383263842638526386263872638826389263902639126392263932639426395263962639726398263992640026401264022640326404264052640626407264082640926410264112641226413264142641526416264172641826419
  1. #pragma warning(push)
  2. #pragma warning(disable:4800)
  3. #pragma warning(disable:4244)
  4. #pragma warning(disable:4141)
  5. #pragma warning(disable:4624)
  6. #pragma warning(disable:4146)
  7. #pragma warning(disable:4267)
  8. #pragma warning(disable:4291)
  9. #include "BfExprEvaluator.h"
  10. #include "BfConstResolver.h"
  11. #include "BfAutoComplete.h"
  12. #include "BeefySysLib/util/PerfTimer.h"
  13. #include "BeefySysLib/util/BeefPerf.h"
  14. #include "BfParser.h"
  15. #include "BfMangler.h"
  16. #include "BfDemangler.h"
  17. #include "BfResolvePass.h"
  18. #include "BfUtil.h"
  19. #include "BfDeferEvalChecker.h"
  20. #include "BfVarDeclChecker.h"
  21. #include "BfFixits.h"
  22. #include "CeMachine.h"
  23. #include "BfDefBuilder.h"
  24. #include "CeMachine.h"
  25. #include "CeDebugger.h"
  26. #pragma warning(pop)
  27. #pragma warning(disable:4996)
  28. #include "BeefySysLib/util/AllocDebug.h"
  29. USING_NS_BF;
  30. using namespace llvm;
  31. //////////////////////////////////////////////////////////////////////////
  32. DeferredTupleAssignData::~DeferredTupleAssignData()
  33. {
  34. for (auto entry : mChildren)
  35. {
  36. delete entry.mExprEvaluator;
  37. delete entry.mInnerTuple;
  38. }
  39. }
  40. //////////////////////////////////////////////////////////////////////////
  41. BfBaseClassWalker::BfBaseClassWalker(BfType* typeA, BfType* typeB, BfModule* module, bool allowInterfaces)
  42. {
  43. mMayBeFromInterface = false;
  44. if (typeB == typeA)
  45. typeB = NULL;
  46. if ((typeA != NULL) &&
  47. ((!typeA->IsInterface()) || (allowInterfaces)))
  48. mTypes[0] = typeA->ToTypeInstance();
  49. else
  50. mTypes[0] = NULL;
  51. if ((typeB != NULL) &&
  52. ((!typeB->IsInterface()) || (allowInterfaces)))
  53. mTypes[1] = typeB->ToTypeInstance();
  54. else
  55. mTypes[1] = NULL;
  56. if ((typeA != NULL) && (typeA->IsGenericParam()))
  57. {
  58. mMayBeFromInterface = true;
  59. AddConstraints(typeA, module->GetGenericParamInstance((BfGenericParamType*)typeA));
  60. }
  61. if ((typeA != NULL) && (typeA->IsInterface()))
  62. {
  63. AddInterfaces(typeA, typeA->ToTypeInstance());
  64. }
  65. if ((typeB != NULL) && (typeB->IsGenericParam()))
  66. {
  67. mMayBeFromInterface = true;
  68. AddConstraints(typeB, module->GetGenericParamInstance((BfGenericParamType*)typeB));
  69. }
  70. if ((typeB != NULL) && (typeB->IsInterface()))
  71. {
  72. AddInterfaces(typeB, typeB->ToTypeInstance());
  73. }
  74. }
  75. /*BfBaseClassWalker::BfBaseClassWalker(BfTypeInstance* typeA, BfTypeInstance* typeB)
  76. {
  77. mTypes[0] = typeA;
  78. mTypes[1] = typeB;
  79. }*/
  80. BfBaseClassWalker::BfBaseClassWalker()
  81. {
  82. mMayBeFromInterface = false;
  83. mTypes[0] = NULL;
  84. mTypes[1] = NULL;
  85. }
  86. void BfBaseClassWalker::AddConstraints(BfType* srcType, BfGenericParamInstance* genericParam)
  87. {
  88. if (genericParam->mTypeConstraint != NULL)
  89. {
  90. auto typeInst = genericParam->mTypeConstraint->ToTypeInstance();
  91. if (typeInst != NULL)
  92. {
  93. if (typeInst->IsInterface())
  94. AddInterfaces(srcType, typeInst->ToTypeInstance());
  95. Entry entry(srcType, typeInst);
  96. if (!mManualList.Contains(entry))
  97. mManualList.Add(entry);
  98. }
  99. }
  100. for (auto typeInst : genericParam->mInterfaceConstraints)
  101. {
  102. if (typeInst != NULL)
  103. {
  104. if (typeInst->IsInterface())
  105. AddInterfaces(srcType, typeInst->ToTypeInstance());
  106. Entry entry(srcType, typeInst);
  107. if (!mManualList.Contains(entry))
  108. mManualList.Add(entry);
  109. }
  110. }
  111. }
  112. void BfBaseClassWalker::AddInterfaces(BfType* srcType, BfTypeInstance* typeInst)
  113. {
  114. for (auto ifaceEntry : typeInst->mInterfaces)
  115. {
  116. Entry entry(srcType, ifaceEntry.mInterfaceType);
  117. if ((typeInst != NULL) && (!mManualList.Contains(entry)))
  118. mManualList.Add(entry);
  119. }
  120. }
  121. BfBaseClassWalker::Entry BfBaseClassWalker::Next()
  122. {
  123. if (!mManualList.IsEmpty())
  124. {
  125. auto entry = mManualList.back();
  126. mManualList.pop_back();
  127. return entry;
  128. }
  129. // Check the most specific type instance first (highest inheritance level)
  130. auto checkInstance = mTypes[0];
  131. if (mTypes[0] == NULL)
  132. checkInstance = mTypes[1];
  133. else if ((mTypes[1] != NULL) && (mTypes[1]->mInheritDepth > mTypes[0]->mInheritDepth))
  134. checkInstance = mTypes[1];
  135. if (checkInstance == NULL)
  136. return Entry();
  137. // Do it this was so if we reach the same base class for both types that we only handle each base type once
  138. if (checkInstance == mTypes[0])
  139. mTypes[0] = checkInstance->mBaseType;
  140. if (checkInstance == mTypes[1])
  141. mTypes[1] = checkInstance->mBaseType;
  142. Entry entry;
  143. entry.mSrcType = checkInstance;
  144. entry.mTypeInstance = checkInstance;
  145. return entry;
  146. }
  147. //////////////////////////////////////////////////////////////////////////
  148. BfMethodMatcher::BfMethodMatcher(BfAstNode* targetSrc, BfModule* module, const StringImpl& methodName, SizedArrayImpl<BfResolvedArg>& arguments, const BfMethodGenericArguments& methodGenericArguments) :
  149. mArguments(arguments)
  150. {
  151. mTargetSrc = targetSrc;
  152. mModule = module;
  153. mMethodName = methodName;
  154. Init(/*arguments, */methodGenericArguments);
  155. }
  156. BfMethodMatcher::BfMethodMatcher(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* interfaceMethodInstance, SizedArrayImpl<BfResolvedArg>& arguments, const BfMethodGenericArguments& methodGenericArguments) :
  157. mArguments(arguments)
  158. {
  159. mTargetSrc = targetSrc;
  160. mModule = module;
  161. Init(/*arguments, */methodGenericArguments);
  162. mInterfaceMethodInstance = interfaceMethodInstance;
  163. mMethodName = mInterfaceMethodInstance->mMethodDef->mName;
  164. }
  165. void BfMethodMatcher::Init(const BfMethodGenericArguments& methodGenericArguments)
  166. {
  167. //mArguments = arguments;
  168. mUsingLists = NULL;
  169. mActiveTypeDef = NULL;
  170. mBestMethodDef = NULL;
  171. mBackupMethodDef = NULL;
  172. mBackupMatchKind = BackupMatchKind_None;
  173. mBestRawMethodInstance = NULL;
  174. mBestMethodTypeInstance = NULL;
  175. mExplicitInterfaceCheck = NULL;
  176. mSelfType = NULL;
  177. mMethodType = BfMethodType_Normal;
  178. mCheckReturnType = NULL;
  179. mHasArgNames = false;
  180. mHadExplicitGenericArguments = false;
  181. mHadOpenGenericArguments = methodGenericArguments.mIsOpen;
  182. mHadPartialGenericArguments = methodGenericArguments.mIsPartial;
  183. mHasVarArguments = false;
  184. mInterfaceMethodInstance = NULL;
  185. mFakeConcreteTarget = false;
  186. mBypassVirtual = false;
  187. mAllowStatic = true;
  188. mAllowNonStatic = true;
  189. mSkipImplicitParams = false;
  190. mAllowImplicitThis = false;
  191. mAllowImplicitRef = false;
  192. mAllowImplicitWrap = false;
  193. mHadVarConflictingReturnType = false;
  194. mAutoFlushAmbiguityErrors = true;
  195. mMethodCheckCount = 0;
  196. mCheckedKind = BfCheckedKind_NotSet;
  197. mAllowAppendKind = BfAllowAppendKind_No;
  198. mMatchFailKind = MatchFailKind_None;
  199. mBfEvalExprFlags = BfEvalExprFlags_None;
  200. for (auto& arg : mArguments)
  201. {
  202. auto bfType = arg.mTypedValue.mType;
  203. if (bfType != NULL)
  204. {
  205. mHasVarArguments |= bfType->IsVar();
  206. if (bfType->IsGenericParam())
  207. {
  208. BfType* typeConstraint = NULL;
  209. BfGenericParamFlags flags = BfGenericParamFlag_None;
  210. mModule->GetMergedGenericParamData(bfType, flags, typeConstraint);
  211. if ((flags & BfGenericParamFlag_Var) != 0)
  212. mHasVarArguments = true;
  213. }
  214. }
  215. if (arg.mNameNode != NULL)
  216. mHasArgNames = true;
  217. }
  218. if (methodGenericArguments.mArguments != NULL)
  219. {
  220. for (BfAstNode* genericArg : *(methodGenericArguments.mArguments))
  221. {
  222. BfType* genericArgType = NULL;
  223. if (BfNodeIsA<BfUninitializedExpression>(genericArg))
  224. {
  225. // Allow a null here
  226. BF_ASSERT(mHadPartialGenericArguments);
  227. }
  228. else
  229. {
  230. genericArgType = mModule->ResolveTypeRef(genericArg, NULL, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowImplicitConstExpr);
  231. if ((genericArgType != NULL) && (genericArgType->IsGenericParam()))
  232. {
  233. auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)genericArgType);
  234. if ((genericParamInstance->mGenericParamFlags & BfGenericParamFlag_Var) != 0)
  235. mHasVarArguments = true;
  236. }
  237. }
  238. mExplicitMethodGenericArguments.push_back(genericArgType);
  239. }
  240. mHadExplicitGenericArguments = true;
  241. }
  242. }
  243. bool BfMethodMatcher::IsMemberAccessible(BfTypeInstance* typeInst, BfTypeDef* declaringType)
  244. {
  245. if (!declaringType->mIsPartial)
  246. return true;
  247. if (mActiveTypeDef == NULL)
  248. mActiveTypeDef = mModule->GetActiveTypeDef();
  249. // Note that mActiveTypeDef does not pose a constraint here
  250. if (!typeInst->IsTypeMemberIncluded(declaringType, mActiveTypeDef, mModule))
  251. return false;
  252. auto visibleProjectSet = mModule->GetVisibleProjectSet();
  253. if ((visibleProjectSet != NULL) && (!typeInst->IsTypeMemberAccessible(declaringType, visibleProjectSet)))
  254. {
  255. return false;
  256. }
  257. return true;
  258. }
  259. bool BfGenericInferContext::AddToCheckedSet(BfType* argType, BfType* wantType)
  260. {
  261. int64 idPair = ((int64)argType->mTypeId << 32) | (wantType->mTypeId);
  262. return mCheckedTypeSet.Add(idPair);
  263. }
  264. bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstance, BfType* argType, BfType* wantType, BfIRValue argValue, bool checkCheckedSet)
  265. {
  266. if (argType == NULL)
  267. return false;
  268. if (!wantType->IsUnspecializedType())
  269. return true;
  270. if (checkCheckedSet)
  271. {
  272. if (!AddToCheckedSet(argType, wantType))
  273. return true;
  274. }
  275. if (wantType->IsGenericParam())
  276. {
  277. auto wantGenericParam = (BfGenericParamType*)wantType;
  278. BfType* methodGenericTypeConstraint = NULL;
  279. auto _SetGeneric = [&]()
  280. {
  281. if (argType != NULL)
  282. {
  283. // Disallow illegal types
  284. if (argType->IsRef())
  285. return;
  286. if (argType->IsNull())
  287. return;
  288. }
  289. if ((*mCheckMethodGenericArguments)[wantGenericParam->mGenericParamIdx] != argType)
  290. {
  291. if (methodGenericTypeConstraint != NULL)
  292. {
  293. if (methodGenericTypeConstraint->IsGenericTypeInstance())
  294. {
  295. auto wantGenericType = (BfTypeInstance*)methodGenericTypeConstraint;
  296. auto checkArgType = argType;
  297. while (checkArgType != NULL)
  298. {
  299. if (checkArgType->IsGenericTypeInstance())
  300. {
  301. auto argGenericType = (BfTypeInstance*)checkArgType;
  302. if (argGenericType->mTypeDef->GetLatest() == wantGenericType->mTypeDef->GetLatest())
  303. {
  304. for (int genericArgIdx = 0; genericArgIdx < (int)argGenericType->mGenericTypeInfo->mTypeGenericArguments.size(); genericArgIdx++)
  305. InferGenericArgument(methodInstance, argGenericType->mGenericTypeInfo->mTypeGenericArguments[genericArgIdx], wantGenericType->mGenericTypeInfo->mTypeGenericArguments[genericArgIdx], BfIRValue(), true);
  306. }
  307. }
  308. else if (checkArgType->IsSizedArray())
  309. {
  310. auto sizedArrayType = (BfSizedArrayType*)checkArgType;
  311. if (wantGenericType->IsInstanceOf(mModule->mCompiler->mSizedArrayTypeDef))
  312. {
  313. InferGenericArgument(methodInstance, sizedArrayType->mElementType, wantGenericType->mGenericTypeInfo->mTypeGenericArguments[0], BfIRValue());
  314. auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  315. BfTypedValue arraySize = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, (uint64)sizedArrayType->mElementCount), intType);
  316. InferGenericArgument(methodInstance, mModule->CreateConstExprValueType(arraySize), wantGenericType->mGenericTypeInfo->mTypeGenericArguments[1], BfIRValue(), true);
  317. }
  318. }
  319. else if (checkArgType->IsPointer())
  320. {
  321. auto pointerType = (BfPointerType*)checkArgType;
  322. if (wantGenericType->IsInstanceOf(mModule->mCompiler->mPointerTTypeDef))
  323. {
  324. InferGenericArgument(methodInstance, pointerType->mElementType, wantGenericType->mGenericTypeInfo->mTypeGenericArguments[0], BfIRValue(), true);
  325. }
  326. }
  327. auto checkTypeInst = checkArgType->ToTypeInstance();
  328. if ((checkTypeInst == NULL) || (!checkTypeInst->mHasParameterizedBase))
  329. break;
  330. checkArgType = checkTypeInst->mBaseType;
  331. }
  332. }
  333. }
  334. }
  335. if ((*mCheckMethodGenericArguments)[wantGenericParam->mGenericParamIdx] == NULL)
  336. mInferredCount++;
  337. (*mCheckMethodGenericArguments)[wantGenericParam->mGenericParamIdx] = argType;
  338. if (!mPrevArgValues.IsEmpty())
  339. mPrevArgValues[wantGenericParam->mGenericParamIdx] = argValue;
  340. };
  341. if (argType->IsVar())
  342. {
  343. _SetGeneric();
  344. return true;
  345. }
  346. if (wantGenericParam->mGenericParamKind == BfGenericParamKind_Method)
  347. {
  348. auto genericParamInst = methodInstance->mMethodInfoEx->mGenericParams[wantGenericParam->mGenericParamIdx];
  349. methodGenericTypeConstraint = genericParamInst->mTypeConstraint;
  350. if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Const) != 0)
  351. {
  352. if (argValue.IsConst())
  353. {
  354. argType = mModule->CreateConstExprValueType(BfTypedValue(argValue, argType));
  355. }
  356. else if (!argType->IsConstExprValue())
  357. {
  358. return false;
  359. }
  360. }
  361. if (argType == mModule->mContext->mBfObjectType)
  362. {
  363. if ((genericParamInst->mTypeConstraint != NULL) && (genericParamInst->mTypeConstraint->IsDelegate()))
  364. {
  365. argType = mModule->ResolveGenericType(genericParamInst->mTypeConstraint, NULL, mCheckMethodGenericArguments, mModule->mCurTypeInstance);
  366. if (argType == NULL)
  367. return true;
  368. }
  369. }
  370. if (mPrevArgValues.IsEmpty())
  371. {
  372. _SetGeneric();
  373. return true;
  374. }
  375. auto prevGenericMethodArg = (*mCheckMethodGenericArguments)[wantGenericParam->mGenericParamIdx];
  376. auto prevArgValue = mPrevArgValues[wantGenericParam->mGenericParamIdx];
  377. if (prevGenericMethodArg == NULL)
  378. {
  379. _SetGeneric();
  380. return true;
  381. }
  382. if ((prevGenericMethodArg->IsIntUnknown()) && (!argType->IsIntUnknown()))
  383. {
  384. // Old int fits into new argType, that's good
  385. if (mModule->CanCast(BfTypedValue(prevArgValue, prevGenericMethodArg), argType))
  386. {
  387. _SetGeneric();
  388. return true;
  389. }
  390. // Doesn't fit, upgrade type to 'int'
  391. argType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  392. if (mModule->CanCast(BfTypedValue(prevArgValue, prevGenericMethodArg), argType))
  393. {
  394. _SetGeneric();
  395. return true;
  396. }
  397. }
  398. if (argType->IsIntUnknown())
  399. {
  400. // New int fits into previous arg type, that's good
  401. if (mModule->CanCast(BfTypedValue(argValue, argType), prevGenericMethodArg))
  402. return true;
  403. // Doesn't fit, upgrade type to 'int'
  404. argType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  405. }
  406. else
  407. {
  408. // Prev is already best
  409. if (mModule->CanCast(mModule->GetFakeTypedValue(argType), prevGenericMethodArg))
  410. return true;
  411. }
  412. // New best?
  413. if (mModule->CanCast(mModule->GetFakeTypedValue(prevGenericMethodArg), argType))
  414. {
  415. _SetGeneric();
  416. return true;
  417. }
  418. // No implicit conversion, FAIL!
  419. (*mCheckMethodGenericArguments)[wantGenericParam->mGenericParamIdx] = NULL;
  420. return false;
  421. }
  422. return true;
  423. }
  424. if (wantType->IsTuple())
  425. {
  426. if (argType->IsTuple())
  427. {
  428. auto wantTupleType = (BfTupleType*)wantType;
  429. auto argTupleType = (BfTupleType*)argType;
  430. if (wantTupleType->mFieldInstances.size() == argTupleType->mFieldInstances.size())
  431. {
  432. for (int fieldIdx = 0; fieldIdx < (int)wantTupleType->mFieldInstances.size(); fieldIdx++)
  433. {
  434. InferGenericArgument(methodInstance, argTupleType->mFieldInstances[fieldIdx].mResolvedType,
  435. wantTupleType->mFieldInstances[fieldIdx].mResolvedType, BfIRValue());
  436. }
  437. }
  438. }
  439. }
  440. if ((wantType->IsGenericTypeInstance()) && (wantType->IsUnspecializedTypeVariation()))
  441. {
  442. auto wantGenericType = (BfTypeInstance*)wantType;
  443. if (argType->IsGenericParam())
  444. {
  445. auto genericParam = mModule->GetGenericParamInstance((BfGenericParamType*)argType);
  446. if ((genericParam->mGenericParamFlags & BfGenericParamFlag_Var) != 0)
  447. {
  448. InferGenericArgument(methodInstance, mModule->GetPrimitiveType(BfTypeCode_Var), wantType, BfIRValue());
  449. return true;
  450. }
  451. if ((genericParam->mTypeConstraint != NULL) && (genericParam->mTypeConstraint->IsGenericTypeInstance()))
  452. InferGenericArgument(methodInstance, genericParam->mTypeConstraint, wantType, BfIRValue());
  453. }
  454. if (argType->IsVar())
  455. {
  456. for (int genericArgIdx = 0; genericArgIdx < (int)wantGenericType->mGenericTypeInfo->mTypeGenericArguments.size(); genericArgIdx++)
  457. {
  458. BfType* wantGenericArgument = wantGenericType->mGenericTypeInfo->mTypeGenericArguments[genericArgIdx];
  459. if (!wantGenericArgument->IsUnspecializedType())
  460. continue;
  461. InferGenericArgument(methodInstance, mModule->GetPrimitiveType(BfTypeCode_Var), wantGenericArgument, BfIRValue());
  462. }
  463. return true;
  464. }
  465. auto typeInstance = argType->ToTypeInstance();
  466. if (typeInstance == NULL)
  467. return true;
  468. if (wantGenericType->IsInterface())
  469. {
  470. for (auto& ifaceEntry : typeInstance->mInterfaces)
  471. InferGenericArgument(methodInstance, ifaceEntry.mInterfaceType, wantType, BfIRValue());
  472. }
  473. else if (typeInstance->mBaseType != NULL)
  474. InferGenericArgument(methodInstance, typeInstance->mBaseType, wantType, BfIRValue());
  475. if (!argType->IsGenericTypeInstance())
  476. return true;
  477. auto argGenericType = (BfTypeInstance*)argType;
  478. if (argGenericType->mTypeDef->GetDefinition() != wantGenericType->mTypeDef->GetDefinition())
  479. return true;
  480. for (int genericArgIdx = 0; genericArgIdx < (int)argGenericType->mGenericTypeInfo->mTypeGenericArguments.size(); genericArgIdx++)
  481. {
  482. BfType* wantGenericArgument = wantGenericType->mGenericTypeInfo->mTypeGenericArguments[genericArgIdx];
  483. if (!wantGenericArgument->IsUnspecializedType())
  484. continue;
  485. InferGenericArgument(methodInstance, argGenericType->mGenericTypeInfo->mTypeGenericArguments[genericArgIdx], wantGenericArgument, BfIRValue(), true);
  486. }
  487. return true;
  488. }
  489. if (wantType->IsRef())
  490. {
  491. auto wantRefType = (BfRefType*)wantType;
  492. if (!argType->IsRef())
  493. {
  494. // Match to non-ref
  495. InferGenericArgument(methodInstance, argType, wantRefType->mElementType, BfIRValue());
  496. return true;
  497. }
  498. auto argRefType = (BfRefType*)argType;
  499. //TODO: We removed this check so we still infer even if we have the wrong ref kind
  500. //if (wantRefType->mRefKind != argRefType->mRefKind)
  501. //return true;
  502. return InferGenericArgument(methodInstance, argRefType->mElementType, wantRefType->mElementType, BfIRValue());
  503. }
  504. if (wantType->IsPointer())
  505. {
  506. if (!argType->IsPointer())
  507. return true;
  508. auto wantPointerType = (BfPointerType*) wantType;
  509. auto argPointerType = (BfPointerType*) argType;
  510. return InferGenericArgument(methodInstance, argPointerType->mElementType, wantPointerType->mElementType, BfIRValue());
  511. }
  512. if (wantType->IsUnknownSizedArrayType())
  513. {
  514. auto wantArrayType = (BfUnknownSizedArrayType*)wantType;
  515. if (argType->IsUnknownSizedArrayType())
  516. {
  517. auto argArrayType = (BfUnknownSizedArrayType*)argType;
  518. InferGenericArgument(methodInstance, argArrayType->mElementCountSource, wantArrayType->mElementCountSource, BfIRValue());
  519. }
  520. else if (argType->IsSizedArray())
  521. {
  522. auto argArrayType = (BfSizedArrayType*)argType;
  523. BfTypedValue sizeValue(mModule->GetConstValue(argArrayType->mElementCount), mModule->GetPrimitiveType(BfTypeCode_IntPtr));
  524. auto sizedType = mModule->CreateConstExprValueType(sizeValue);
  525. InferGenericArgument(methodInstance, sizedType, wantArrayType->mElementCountSource, BfIRValue());
  526. }
  527. }
  528. if (wantType->IsSizedArray())
  529. {
  530. if (argType->IsSizedArray())
  531. {
  532. auto wantArrayType = (BfSizedArrayType*)wantType;
  533. auto argArrayType = (BfSizedArrayType*)argType;
  534. InferGenericArgument(methodInstance, argArrayType->mElementType, wantArrayType->mElementType, BfIRValue());
  535. }
  536. }
  537. if ((wantType->IsDelegate()) || (wantType->IsFunction()))
  538. {
  539. if (((argType->IsDelegate()) || (argType->IsFunction())) &&
  540. (wantType->IsDelegate() == argType->IsDelegate()))
  541. {
  542. if (!AddToCheckedSet(argType, wantType))
  543. return true;
  544. auto argInvokeMethod = mModule->GetRawMethodByName(argType->ToTypeInstance(), "Invoke");
  545. auto wantInvokeMethod = mModule->GetRawMethodByName(wantType->ToTypeInstance(), "Invoke");
  546. if ((argInvokeMethod != NULL) && (wantInvokeMethod != NULL) && (argInvokeMethod->GetParamCount() == wantInvokeMethod->GetParamCount()))
  547. {
  548. InferGenericArgument(methodInstance, argInvokeMethod->mReturnType, wantInvokeMethod->mReturnType, BfIRValue());
  549. for (int argIdx = 0; argIdx < (int)argInvokeMethod->GetParamCount(); argIdx++)
  550. InferGenericArgument(methodInstance, argInvokeMethod->GetParamType(argIdx), wantInvokeMethod->GetParamType(argIdx), BfIRValue());
  551. }
  552. }
  553. else if (argType->IsMethodRef())
  554. {
  555. auto methodTypeRef = (BfMethodRefType*)argType;
  556. if (!AddToCheckedSet(argType, wantType))
  557. return true;
  558. auto argInvokeMethod = methodTypeRef->mMethodRef;
  559. auto delegateInfo = wantType->GetDelegateInfo();
  560. auto wantInvokeMethod = mModule->GetRawMethodByName(wantType->ToTypeInstance(), "Invoke");
  561. if ((delegateInfo->mHasExplicitThis) && (argInvokeMethod->HasThis()))
  562. InferGenericArgument(methodInstance, argInvokeMethod->GetParamType(-1), delegateInfo->mParams[0], BfIRValue());
  563. int wantInvokeOffset = delegateInfo->mHasExplicitThis ? 1 : 0;
  564. if ((argInvokeMethod != NULL) && (wantInvokeMethod != NULL) && (argInvokeMethod->GetParamCount() == wantInvokeMethod->GetParamCount() - wantInvokeOffset))
  565. {
  566. InferGenericArgument(methodInstance, argInvokeMethod->mReturnType, wantInvokeMethod->mReturnType, BfIRValue());
  567. for (int argIdx = 0; argIdx < (int)argInvokeMethod->GetParamCount(); argIdx++)
  568. InferGenericArgument(methodInstance, argInvokeMethod->GetParamType(argIdx), wantInvokeMethod->GetParamType(argIdx + wantInvokeOffset), BfIRValue());
  569. }
  570. }
  571. }
  572. return true;
  573. }
  574. bool BfGenericInferContext::InferGenericArguments(BfMethodInstance* methodInstance, int srcGenericIdx)
  575. {
  576. auto& srcGenericArg = (*mCheckMethodGenericArguments)[srcGenericIdx];
  577. if (srcGenericArg == NULL)
  578. return false;
  579. int startInferCount = mInferredCount;
  580. auto srcGenericParam = methodInstance->mMethodInfoEx->mGenericParams[srcGenericIdx];
  581. for (auto ifaceConstraint : srcGenericParam->mInterfaceConstraints)
  582. {
  583. if ((ifaceConstraint->IsUnspecializedTypeVariation()) && (ifaceConstraint->IsGenericTypeInstance()))
  584. {
  585. InferGenericArgument(methodInstance, srcGenericArg, ifaceConstraint, BfIRValue());
  586. auto typeInstance = srcGenericArg->ToTypeInstance();
  587. if ((typeInstance == NULL) && (srcGenericArg->IsWrappableType()))
  588. typeInstance = mModule->GetWrappedStructType(srcGenericArg);
  589. if (typeInstance != NULL)
  590. {
  591. for (auto ifaceEntry : typeInstance->mInterfaces)
  592. InferGenericArgument(methodInstance, ifaceEntry.mInterfaceType, ifaceConstraint, BfIRValue());
  593. }
  594. if (srcGenericArg->IsGenericParam())
  595. {
  596. auto genericParamType = (BfGenericParamType*)srcGenericArg;
  597. BfGenericParamInstance* genericParam = NULL;
  598. if (genericParamType->mGenericParamKind == BfGenericParamKind_Method)
  599. genericParam = mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams[genericParamType->mGenericParamIdx];
  600. else
  601. genericParam = mModule->GetGenericParamInstance(genericParamType);
  602. if (genericParam->mTypeConstraint != NULL)
  603. InferGenericArgument(methodInstance, genericParam->mTypeConstraint, ifaceConstraint, BfIRValue());
  604. for (auto argIfaceConstraint : genericParam->mInterfaceConstraints)
  605. InferGenericArgument(methodInstance, argIfaceConstraint, ifaceConstraint, BfIRValue());
  606. }
  607. }
  608. }
  609. return mInferredCount != startInferCount;
  610. }
  611. void BfGenericInferContext::InferGenericArguments(BfMethodInstance* methodInstance)
  612. {
  613. // Attempt to infer from other generic args
  614. for (int srcGenericIdx = 0; srcGenericIdx < (int)mCheckMethodGenericArguments->size(); srcGenericIdx++)
  615. {
  616. InferGenericArguments(methodInstance, srcGenericIdx);
  617. }
  618. }
  619. int BfMethodMatcher::GetMostSpecificType(BfType* lhs, BfType* rhs)
  620. {
  621. if ((lhs->IsRef()) && (rhs->IsRef()))
  622. return GetMostSpecificType(lhs->GetUnderlyingType(), rhs->GetUnderlyingType());
  623. if ((lhs->IsPointer()) && (rhs->IsPointer()))
  624. return GetMostSpecificType(lhs->GetUnderlyingType(), rhs->GetUnderlyingType());
  625. if ((lhs->IsSizedArray()) && (rhs->IsSizedArray()))
  626. return GetMostSpecificType(lhs->GetUnderlyingType(), rhs->GetUnderlyingType());
  627. if (lhs->IsGenericParam())
  628. return rhs->IsGenericParam() ? -1 : 1;
  629. if (rhs->IsGenericParam())
  630. return 0;
  631. if ((lhs->IsUnspecializedType()) && (lhs->IsGenericTypeInstance()))
  632. {
  633. if ((!rhs->IsUnspecializedType()) || (!rhs->IsGenericTypeInstance()))
  634. return 1;
  635. auto lhsTypeInst = lhs->ToTypeInstance();
  636. auto rhsTypeInst = rhs->ToTypeInstance();
  637. if ((rhsTypeInst == NULL) || (lhsTypeInst == NULL) || (lhsTypeInst->mTypeDef != rhsTypeInst->mTypeDef))
  638. return -1;
  639. bool hadLHSMoreSpecific = false;
  640. bool hadRHSMoreSpecific = false;
  641. for (int generigArgIdx = 0; generigArgIdx < (int)lhsTypeInst->mGenericTypeInfo->mTypeGenericArguments.size(); generigArgIdx++)
  642. {
  643. int argMoreSpecific = GetMostSpecificType(lhsTypeInst->mGenericTypeInfo->mTypeGenericArguments[generigArgIdx],
  644. rhsTypeInst->mGenericTypeInfo->mTypeGenericArguments[generigArgIdx]);
  645. if (argMoreSpecific == 0)
  646. hadLHSMoreSpecific = true;
  647. else if (argMoreSpecific == 1)
  648. hadRHSMoreSpecific = true;
  649. }
  650. if ((hadLHSMoreSpecific) && (!hadRHSMoreSpecific))
  651. return 0;
  652. if ((hadRHSMoreSpecific) && (!hadLHSMoreSpecific))
  653. return 1;
  654. return -1;
  655. }
  656. if (rhs->IsUnspecializedType())
  657. return 0;
  658. return -1;
  659. }
  660. void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTypeVector* prevGenericArgumentsSubstitute,
  661. BfMethodInstance* newMethodInstance, BfTypeVector* genericArgumentsSubstitute,
  662. bool* outNewIsBetter, bool* outNewIsWorse, bool allowSpecializeFail)
  663. {
  664. if (prevMethodInstance == newMethodInstance)
  665. {
  666. *outNewIsBetter = false;
  667. *outNewIsWorse = true;
  668. return;
  669. }
  670. #define SET_BETTER_OR_WORSE(lhs, rhs) \
  671. if ((!isBetter) && (lhs) && !(rhs)) isBetter = true; \
  672. if ((!isWorse) && !(lhs) && (rhs)) isWorse = true;
  673. #define RETURN_BETTER_OR_WORSE(lhs, rhs) \
  674. if ((!isBetter) && (lhs) && !(rhs)) { *outNewIsBetter = true; *outNewIsWorse = false; return; } \
  675. if ((!isWorse) && !(lhs) && (rhs)) { *outNewIsBetter = false; *outNewIsWorse = true; return; };
  676. #define RETURN_RESULTS \
  677. *outNewIsBetter = isBetter; \
  678. *outNewIsWorse = isWorse; \
  679. return;
  680. int numUsedParams = 0;
  681. int prevNumUsedParams = 0;
  682. bool usedExtendedForm = false;
  683. bool prevUsedExtendedForm = false;
  684. bool isBetter = false;
  685. bool isWorse = false;
  686. int argIdx;
  687. BfMethodDef* prevMethodDef = prevMethodInstance->mMethodDef;
  688. BfMethodDef* newMethodDef = newMethodInstance->mMethodDef;
  689. if (prevMethodDef == mBackupMethodDef)
  690. {
  691. // This can happen for extension methods and such
  692. *outNewIsBetter = true;
  693. *outNewIsWorse = false;
  694. return;
  695. }
  696. if (newMethodDef->mExplicitInterface != prevMethodDef->mExplicitInterface)
  697. {
  698. if (mModule->CompareMethodSignatures(newMethodInstance, prevMethodInstance))
  699. {
  700. SET_BETTER_OR_WORSE(newMethodDef->mExplicitInterface != NULL, prevMethodDef->mExplicitInterface != NULL);
  701. *outNewIsBetter = isBetter;
  702. *outNewIsWorse = isWorse;
  703. return;
  704. }
  705. }
  706. bool anyIsExtension = false;
  707. int newImplicitParamCount = newMethodInstance->GetImplicitParamCount();
  708. if (newMethodInstance->mMethodDef->HasAppend())
  709. newImplicitParamCount++;
  710. if (newMethodInstance->mMethodDef->mMethodType == BfMethodType_Extension)
  711. {
  712. newImplicitParamCount++;
  713. anyIsExtension = true;
  714. }
  715. int prevImplicitParamCount = prevMethodInstance->GetImplicitParamCount();
  716. if (prevMethodInstance->mMethodDef->HasAppend())
  717. prevImplicitParamCount++;
  718. if (prevMethodInstance->mMethodDef->mMethodType == BfMethodType_Extension)
  719. {
  720. prevImplicitParamCount++;
  721. anyIsExtension = true;
  722. }
  723. BfCastFlags implicitCastFlags = ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp) != 0) ? BfCastFlags_NoConversionOperator : BfCastFlags_None;
  724. int newMethodParamCount = newMethodInstance->GetParamCount();
  725. int prevMethodParamCount = prevMethodInstance->GetParamCount();
  726. bool hadEnoughArgs = newMethodParamCount - newImplicitParamCount < (int)mArguments.size();
  727. bool prevHadEnoughArgs = prevMethodParamCount - prevImplicitParamCount < (int)mArguments.size();
  728. RETURN_BETTER_OR_WORSE(hadEnoughArgs, prevHadEnoughArgs);
  729. bool chainSkip = (newMethodInstance->mChainType == BfMethodChainType_ChainMember) || (newMethodInstance->mChainType == BfMethodChainType_ChainSkip);
  730. bool prevChainSkip = (prevMethodInstance->mChainType == BfMethodChainType_ChainMember) || (prevMethodInstance->mChainType == BfMethodChainType_ChainSkip);
  731. RETURN_BETTER_OR_WORSE(!chainSkip, !prevChainSkip);
  732. if ((!isBetter) && (!isWorse))
  733. {
  734. bool betterByGenericParam = false;
  735. bool worseByGenericParam = false;
  736. bool betterByConstExprParam = false;
  737. bool worseByConstExprParam = false;
  738. bool someArgWasBetter = false;
  739. bool someArgWasWorse = false;
  740. for (argIdx = anyIsExtension ? -1 : 0; argIdx < (int)mArguments.size(); argIdx++)
  741. {
  742. BfTypedValue arg;
  743. BfResolvedArg* resolvedArg = NULL;
  744. bool wasArgDeferred = false;
  745. if (argIdx == -1)
  746. {
  747. arg = mTarget;
  748. }
  749. else
  750. {
  751. resolvedArg = &mArguments[argIdx];
  752. wasArgDeferred = resolvedArg->mArgFlags != 0;
  753. arg = resolvedArg->mTypedValue;
  754. }
  755. int newArgIdx = argIdx + newImplicitParamCount;
  756. int prevArgIdx = argIdx + prevImplicitParamCount;
  757. if (newArgIdx >= newMethodParamCount)
  758. break;
  759. if (prevArgIdx >= prevMethodParamCount)
  760. break;
  761. bool wasGenericParam = (newArgIdx >= 0) && newMethodInstance->WasGenericParam(newArgIdx);
  762. bool prevWasGenericParam = (prevArgIdx >= 0) && prevMethodInstance->WasGenericParam(prevArgIdx);
  763. BfType* paramType = newMethodInstance->GetParamType(newArgIdx, true);
  764. BfType* prevParamType = prevMethodInstance->GetParamType(prevArgIdx, true);
  765. numUsedParams++;
  766. prevNumUsedParams++;
  767. BfType* origParamType = paramType;
  768. BfType* origPrevParamType = prevParamType;
  769. bool paramWasConstExpr = false;
  770. bool prevParamWasConstExpr = false;
  771. bool paramWasUnspecialized = paramType->IsUnspecializedType();
  772. if ((genericArgumentsSubstitute != NULL) && (paramWasUnspecialized))
  773. {
  774. paramType = mModule->ResolveGenericType(paramType, NULL, genericArgumentsSubstitute, mModule->mCurTypeInstance, allowSpecializeFail);
  775. paramType = mModule->FixIntUnknown(paramType);
  776. }
  777. if ((paramType != NULL) && (paramType->IsConstExprValue()))
  778. {
  779. paramWasConstExpr = true;
  780. paramType = ((BfConstExprValueType*)paramType)->mType;
  781. }
  782. bool prevParamWasUnspecialized = prevParamType->IsUnspecializedType();
  783. if ((prevGenericArgumentsSubstitute != NULL) && (prevParamWasUnspecialized))
  784. {
  785. prevParamType = mModule->ResolveGenericType(prevParamType, NULL, prevGenericArgumentsSubstitute, mModule->mCurTypeInstance, allowSpecializeFail);
  786. prevParamType = mModule->FixIntUnknown(prevParamType);
  787. }
  788. if ((prevParamType != NULL) && (prevParamType->IsConstExprValue()))
  789. {
  790. prevParamWasConstExpr = true;
  791. prevParamType = ((BfConstExprValueType*)prevParamType)->mType;
  792. }
  793. bool paramsEquivalent = paramType == prevParamType;
  794. if ((prevParamType == NULL) || (paramType == NULL))
  795. {
  796. SET_BETTER_OR_WORSE(paramType != NULL, prevParamType != NULL);
  797. }
  798. else if (paramType != prevParamType)
  799. {
  800. bool isUnspecializedParam = paramType->IsUnspecializedType();
  801. bool isPrevUnspecializedParam = prevParamType->IsUnspecializedType();
  802. SET_BETTER_OR_WORSE((!isUnspecializedParam) && (!paramType->IsVar()),
  803. (!isPrevUnspecializedParam) && (!prevParamType->IsVar()));
  804. if ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp_Explicit) != 0)
  805. {
  806. // Pick the one that can implicitly cast
  807. SET_BETTER_OR_WORSE(
  808. mModule->CanCast(arg, paramType, implicitCastFlags),
  809. mModule->CanCast(arg, prevParamType, implicitCastFlags));
  810. }
  811. // Why did we have this !isUnspecializedParam check? We need the 'canCast' logic still
  812. if ((!isBetter) && (!isWorse) /*&& (!isUnspecializedParam) && (!isPrevUnspecializedParam)*/)
  813. {
  814. SET_BETTER_OR_WORSE((paramType != NULL) && (!paramType->IsUnspecializedType()),
  815. (prevParamType != NULL) && (!prevParamType->IsUnspecializedType()));
  816. if ((!isBetter) && (!isWorse))
  817. {
  818. // The resolved argument type may actually match for both considered functions. IE:
  819. // Method(int8 val) and Method(int16 val) called with Method(0) will create arguments that match their param types
  820. if ((!wasArgDeferred) && (!wasGenericParam) && (IsType(arg, paramType)) && ((resolvedArg == NULL) || (prevParamType != resolvedArg->mBestBoundType)))
  821. isBetter = true;
  822. //else if ((!prevWasGenericParam) && (IsType(arg, prevParamType)) && (!IsType(arg, paramType)))
  823. else if ((!wasArgDeferred) && (!prevWasGenericParam) && (IsType(arg, prevParamType)) && ((resolvedArg == NULL) || (paramType != resolvedArg->mBestBoundType)))
  824. isWorse = true;
  825. else if ((wasArgDeferred) && (paramType != prevParamType) && (paramType == arg.mType) && (paramType == resolvedArg->mBestBoundType))
  826. isBetter = true;
  827. else if ((wasArgDeferred) && (paramType != prevParamType) && (prevParamType == arg.mType) && (prevParamType == resolvedArg->mBestBoundType))
  828. isWorse = true;
  829. else if ((argIdx == -1) && (anyIsExtension))
  830. {
  831. if ((newMethodInstance->mMethodDef->mMethodType == BfMethodType_Extension) && (wasGenericParam) && (!prevWasGenericParam))
  832. isWorse = true;
  833. else if ((prevMethodInstance->mMethodDef->mMethodType == BfMethodType_Extension) && (prevWasGenericParam) && (!wasGenericParam))
  834. isBetter = true;
  835. }
  836. else
  837. {
  838. bool canCastFromCurToPrev = mModule->CanCast(mModule->GetFakeTypedValue(paramType), prevParamType, implicitCastFlags);
  839. bool canCastFromPrevToCur = mModule->CanCast(mModule->GetFakeTypedValue(prevParamType), paramType, implicitCastFlags);
  840. if ((canCastFromCurToPrev) && (canCastFromPrevToCur))
  841. paramsEquivalent = true;
  842. if ((canCastFromCurToPrev) && (!canCastFromPrevToCur))
  843. isBetter = true;
  844. else if ((canCastFromPrevToCur) && (!canCastFromCurToPrev))
  845. isWorse = true;
  846. else if ((paramType->IsIntegral()) && (prevParamType->IsIntegral()))
  847. {
  848. if (paramType == arg.mType)
  849. isBetter = true;
  850. else if (prevParamType == arg.mType)
  851. isWorse = true;
  852. else
  853. {
  854. if (paramType->mSize < prevParamType->mSize)
  855. isBetter = true;
  856. else if (paramType->mSize > prevParamType->mSize)
  857. isWorse = true;
  858. else if (paramType->IsSigned())
  859. isBetter = true;
  860. else
  861. isWorse = true;
  862. }
  863. }
  864. else if ((wasArgDeferred) && ((paramType->IsIntegral()) || (prevParamType->IsIntegral())))
  865. {
  866. SET_BETTER_OR_WORSE(paramType->IsIntegral(), prevParamType->IsIntegral());
  867. }
  868. }
  869. }
  870. }
  871. }
  872. if ((!isBetter) && (!isWorse) && (paramsEquivalent))
  873. {
  874. if ((origParamType != origPrevParamType) && (paramWasConstExpr) && (!prevParamWasConstExpr))
  875. betterByConstExprParam = true;
  876. else if ((origParamType != origPrevParamType) && (!paramWasConstExpr) && (prevParamWasConstExpr))
  877. worseByConstExprParam = true;
  878. else if (((paramWasUnspecialized) || (prevParamWasUnspecialized)))
  879. {
  880. int origTypeMoreSpecific = GetMostSpecificType(origParamType, origPrevParamType);
  881. if (origTypeMoreSpecific == 0)
  882. betterByGenericParam = true;
  883. else if (origTypeMoreSpecific == 1)
  884. worseByGenericParam = true;
  885. }
  886. }
  887. if ((!isBetter) && (!isWorse) && (paramType->IsRef()) && (prevParamType->IsRef()))
  888. {
  889. auto refType = (BfRefType*)paramType;
  890. auto prevRefType = (BfRefType*)prevParamType;
  891. // Prefer 'out' to 'ref'
  892. SET_BETTER_OR_WORSE(
  893. (refType->mRefKind == BfRefType::RefKind_Out) && (prevRefType->mRefKind == BfRefType::RefKind_Ref),
  894. (refType->mRefKind == BfRefType::RefKind_Ref) && (prevRefType->mRefKind == BfRefType::RefKind_Out));
  895. }
  896. if ((newArgIdx >= 0) && (newMethodInstance->GetParamKind(newArgIdx) == BfParamKind_Params))
  897. usedExtendedForm = true;
  898. if ((prevArgIdx >= 0) && (prevMethodInstance->GetParamKind(prevArgIdx) == BfParamKind_Params))
  899. prevUsedExtendedForm = true;
  900. if ((usedExtendedForm) || (prevUsedExtendedForm))
  901. break;
  902. someArgWasBetter |= isBetter;
  903. someArgWasWorse |= isWorse;
  904. isBetter = false;
  905. isWorse = false;
  906. }
  907. isBetter |= someArgWasBetter;
  908. isWorse |= someArgWasWorse;
  909. if ((!isBetter) && (!isWorse))
  910. {
  911. // Don't allow ambiguity
  912. if ((betterByGenericParam && !worseByGenericParam) ||
  913. (!betterByGenericParam && worseByGenericParam))
  914. {
  915. isBetter = betterByGenericParam;
  916. isWorse = worseByGenericParam;
  917. }
  918. }
  919. if ((!isBetter) && (!isWorse))
  920. {
  921. // Don't allow ambiguity
  922. if ((betterByConstExprParam && !worseByConstExprParam) ||
  923. (!betterByConstExprParam && worseByConstExprParam))
  924. {
  925. isBetter = betterByConstExprParam;
  926. isWorse = worseByConstExprParam;
  927. }
  928. }
  929. if ((isBetter) || (isWorse))
  930. {
  931. RETURN_RESULTS;
  932. }
  933. }
  934. // Choose by return type for conversion operators
  935. if (((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp) != 0) && (!isBetter) && (!isWorse))
  936. {
  937. auto returnType = newMethodInstance->mReturnType;
  938. auto prevReturnType = prevMethodInstance->mReturnType;
  939. if ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp_Explicit) != 0)
  940. {
  941. // Pick the one that can implicitly cast
  942. SET_BETTER_OR_WORSE(
  943. mModule->CanCast(mModule->GetFakeTypedValue(returnType), mCheckReturnType, implicitCastFlags),
  944. mModule->CanCast(mModule->GetFakeTypedValue(prevReturnType), mCheckReturnType, implicitCastFlags));
  945. }
  946. if ((!isBetter) && (!isWorse))
  947. {
  948. bool canCastFromCurToPrev = mModule->CanCast(mModule->GetFakeTypedValue(returnType), prevReturnType, implicitCastFlags);
  949. bool canCastFromPrevToCur = mModule->CanCast(mModule->GetFakeTypedValue(prevReturnType), returnType, implicitCastFlags);
  950. if ((canCastFromCurToPrev) && (!canCastFromPrevToCur))
  951. isWorse = true;
  952. else if ((canCastFromPrevToCur) && (!canCastFromCurToPrev))
  953. isBetter = true;
  954. }
  955. if ((isBetter) || (isWorse))
  956. {
  957. RETURN_RESULTS;
  958. }
  959. }
  960. // Check for unused extended params as next param - that still counts as using extended form
  961. usedExtendedForm = newMethodInstance->HasParamsArray();
  962. prevUsedExtendedForm = prevMethodInstance->HasParamsArray();
  963. RETURN_BETTER_OR_WORSE(newMethodInstance->GetNumGenericArguments() == 0, prevMethodInstance->GetNumGenericArguments() == 0);
  964. // Not using generic delegate params is better
  965. RETURN_BETTER_OR_WORSE(!newMethodInstance->mHadGenericDelegateParams, !prevMethodInstance->mHadGenericDelegateParams);
  966. // Normal form trumps extended form
  967. RETURN_BETTER_OR_WORSE(!usedExtendedForm, !prevUsedExtendedForm);
  968. // More used params trumps less params
  969. int paramDiff = (int) numUsedParams - (int) prevNumUsedParams;
  970. RETURN_BETTER_OR_WORSE(paramDiff > 0, paramDiff < 0);
  971. // Fewer defaults trumps more defaults
  972. // Since we know the number of used params is the same (previous check), we infer that the rest are defaults
  973. paramDiff = (int) newMethodInstance->GetParamCount() - (int) prevMethodInstance->GetParamCount();
  974. RETURN_BETTER_OR_WORSE(paramDiff < 0, paramDiff > 0);
  975. BfMethodInstance* typeUnspecNewMethodInstance = mModule->GetUnspecializedMethodInstance(newMethodInstance, true);
  976. BfMethodInstance* typeUnspecPrevMethodInstance = mModule->GetUnspecializedMethodInstance(prevMethodInstance, true);
  977. // Check specificity of args
  978. std::function<void(BfType*, BfType*)> _CompareParamTypes = [&](BfType* newType, BfType* prevType)
  979. {
  980. if ((newType->IsGenericParam()) && (prevType->IsGenericParam()))
  981. {
  982. auto newGenericParamType = (BfGenericParamType*)newType;
  983. auto prevGenericParamType = (BfGenericParamType*)prevType;
  984. if ((newGenericParamType->mGenericParamKind == BfGenericParamKind_Method) && (prevGenericParamType->mGenericParamKind == BfGenericParamKind_Method))
  985. {
  986. auto newMethodGenericParam = typeUnspecNewMethodInstance->mMethodInfoEx->mGenericParams[newGenericParamType->mGenericParamIdx];
  987. auto prevMethodGenericParam = typeUnspecPrevMethodInstance->mMethodInfoEx->mGenericParams[prevGenericParamType->mGenericParamIdx];
  988. SET_BETTER_OR_WORSE(mModule->AreConstraintsSubset(prevMethodGenericParam, newMethodGenericParam), mModule->AreConstraintsSubset(newMethodGenericParam, prevMethodGenericParam));
  989. }
  990. }
  991. else if (newType == prevType)
  992. {
  993. if ((newType->IsUnspecializedType()) && (newType->IsGenericTypeInstance()))
  994. {
  995. BfTypeInstance* newGenericType = (BfTypeInstance*)newType;
  996. BfTypeInstance* prevGenericType = (BfTypeInstance*)prevType;
  997. for (int genericArgIdx = 0; genericArgIdx < (int)newGenericType->mGenericTypeInfo->mTypeGenericArguments.size(); genericArgIdx++)
  998. {
  999. _CompareParamTypes(newGenericType->mGenericTypeInfo->mTypeGenericArguments[genericArgIdx], prevGenericType->mGenericTypeInfo->mTypeGenericArguments[genericArgIdx]);
  1000. }
  1001. }
  1002. }
  1003. else
  1004. {
  1005. //TODO: Why did we need this?
  1006. //isBetter |= mModule->IsTypeMoreSpecific(newType, prevType);
  1007. //isWorse |= mModule->IsTypeMoreSpecific(prevType, newType);
  1008. }
  1009. };
  1010. int paramCheckCount = (int)BF_MIN(newMethodInstance->GetParamCount() - newImplicitParamCount, prevMethodInstance->GetParamCount() - prevImplicitParamCount);
  1011. for (argIdx = 0; argIdx < (int)paramCheckCount/*mArguments.size()*/; argIdx++)
  1012. {
  1013. int newArgIdx = argIdx + newImplicitParamCount;
  1014. int prevArgIdx = argIdx + prevImplicitParamCount;
  1015. _CompareParamTypes(typeUnspecNewMethodInstance->GetParamType(newArgIdx), typeUnspecPrevMethodInstance->GetParamType(prevArgIdx));
  1016. }
  1017. // Do generic constraint subset test directly to handle cases like "NotDisposed<T>()" vs "NotDisposed<T>() where T : IDisposable"
  1018. if ((newMethodInstance->GetNumGenericArguments() > 0) && (newMethodInstance->GetNumGenericArguments() == prevMethodInstance->GetNumGenericArguments()))
  1019. {
  1020. for (int genericParamIdx = 0; genericParamIdx < (int)newMethodInstance->GetNumGenericArguments(); genericParamIdx++)
  1021. {
  1022. auto newMethodGenericParam = newMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
  1023. auto prevMethodGenericParam = prevMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
  1024. SET_BETTER_OR_WORSE(mModule->AreConstraintsSubset(prevMethodGenericParam, newMethodGenericParam), mModule->AreConstraintsSubset(newMethodGenericParam, prevMethodGenericParam));
  1025. }
  1026. if ((!isBetter) && (!isWorse))
  1027. {
  1028. SET_BETTER_OR_WORSE(newMethodInstance->HasExternConstraints(), prevMethodInstance->HasExternConstraints());
  1029. }
  1030. }
  1031. if ((isBetter) || (isWorse))
  1032. {
  1033. RETURN_RESULTS;
  1034. }
  1035. // For operators, prefer explicit comparison over '<=>' comparison operator
  1036. if ((!isBetter) && (!isWorse))
  1037. {
  1038. if ((prevMethodDef->mIsOperator) && (newMethodDef->mIsOperator))
  1039. {
  1040. bool newIsComparison = ((BfOperatorDeclaration*)newMethodDef->mMethodDeclaration)->mBinOp == BfBinaryOp_Compare;
  1041. bool prevIsComparison = ((BfOperatorDeclaration*)prevMethodDef->mMethodDeclaration)->mBinOp == BfBinaryOp_Compare;
  1042. RETURN_BETTER_OR_WORSE(!newIsComparison, !prevIsComparison);
  1043. }
  1044. }
  1045. if ((newMethodInstance->mMethodDef->mExternalConstraints.size() != 0) || (prevMethodInstance->mMethodDef->mExternalConstraints.size() != 0))
  1046. {
  1047. struct GenericParamPair
  1048. {
  1049. BfGenericMethodParamInstance* mParams[2];
  1050. GenericParamPair()
  1051. {
  1052. mParams[0] = NULL;
  1053. mParams[1] = NULL;
  1054. }
  1055. };
  1056. Dictionary<BfType*, GenericParamPair> externConstraints;
  1057. auto _GetParams = [&](int idx, BfMethodInstance* methodInstance)
  1058. {
  1059. for (int externConstraintIdx = 0; externConstraintIdx < (int)methodInstance->mMethodDef->mExternalConstraints.size(); externConstraintIdx++)
  1060. {
  1061. auto genericParam = methodInstance->mMethodInfoEx->mGenericParams[methodInstance->mMethodDef->mGenericParams.size() + externConstraintIdx];
  1062. BF_ASSERT(genericParam->mExternType != NULL);
  1063. GenericParamPair* pairPtr = NULL;
  1064. externConstraints.TryAdd(genericParam->mExternType, NULL, &pairPtr);
  1065. pairPtr->mParams[idx] = genericParam;
  1066. }
  1067. };
  1068. _GetParams(0, newMethodInstance);
  1069. _GetParams(1, prevMethodInstance);
  1070. for (auto kv : externConstraints)
  1071. {
  1072. SET_BETTER_OR_WORSE(mModule->AreConstraintsSubset(kv.mValue.mParams[1], kv.mValue.mParams[0]), mModule->AreConstraintsSubset(kv.mValue.mParams[0], kv.mValue.mParams[1]));
  1073. }
  1074. if ((isBetter) || (isWorse))
  1075. {
  1076. RETURN_RESULTS;
  1077. }
  1078. }
  1079. // Does one have a body and one doesn't? Obvious!
  1080. isBetter = prevMethodDef->IsEmptyPartial();
  1081. isWorse = newMethodDef->IsEmptyPartial();
  1082. if ((isBetter) && (isWorse))
  1083. {
  1084. // If both are empty partials then just bind to either
  1085. isWorse = true;
  1086. RETURN_RESULTS;
  1087. }
  1088. // For extensions, select the version in the most-specific project (only applicable for ctors)
  1089. if ((!isBetter) && (!isWorse))
  1090. {
  1091. auto newProject = newMethodDef->mDeclaringType->mProject;
  1092. auto prevProject = prevMethodDef->mDeclaringType->mProject;
  1093. if (newProject != prevProject)
  1094. {
  1095. RETURN_BETTER_OR_WORSE(newProject->ContainsReference(prevProject), prevProject->ContainsReference(newProject));
  1096. }
  1097. }
  1098. // If we have conditional type extensions that both define an implementation for a method, use the most-specific conditional extension constraints
  1099. auto owner = newMethodInstance->GetOwner();
  1100. if ((newMethodDef->mDeclaringType != prevMethodDef->mDeclaringType) && (owner->IsGenericTypeInstance()))
  1101. {
  1102. auto genericOwner = (BfTypeInstance*)owner;
  1103. if (genericOwner->mGenericTypeInfo->mGenericExtensionInfo != NULL)
  1104. {
  1105. BfGenericExtensionEntry* newGenericExtesionEntry = NULL;
  1106. BfGenericExtensionEntry* prevGenericExtesionEntry = NULL;
  1107. if ((genericOwner->mGenericTypeInfo->mGenericExtensionInfo->mExtensionMap.TryGetValue(newMethodDef->mDeclaringType, &newGenericExtesionEntry)) &&
  1108. (genericOwner->mGenericTypeInfo->mGenericExtensionInfo->mExtensionMap.TryGetValue(prevMethodDef->mDeclaringType, &prevGenericExtesionEntry)))
  1109. {
  1110. if ((newGenericExtesionEntry->mGenericParams.size() == prevGenericExtesionEntry->mGenericParams.size()))
  1111. {
  1112. for (int genericParamIdx = 0; genericParamIdx < (int)newGenericExtesionEntry->mGenericParams.size(); genericParamIdx++)
  1113. {
  1114. auto newMethodGenericParam = newGenericExtesionEntry->mGenericParams[genericParamIdx];
  1115. auto prevMethodGenericParam = prevGenericExtesionEntry->mGenericParams[genericParamIdx];
  1116. SET_BETTER_OR_WORSE(mModule->AreConstraintsSubset(prevMethodGenericParam, newMethodGenericParam), mModule->AreConstraintsSubset(newMethodGenericParam, prevMethodGenericParam));
  1117. }
  1118. }
  1119. if ((isBetter) || (isWorse))
  1120. {
  1121. RETURN_RESULTS;
  1122. }
  1123. }
  1124. }
  1125. }
  1126. RETURN_BETTER_OR_WORSE(newMethodDef->mCheckedKind == mCheckedKind, prevMethodDef->mCheckedKind == mCheckedKind);
  1127. RETURN_BETTER_OR_WORSE(newMethodDef->mAppendKind == mAllowAppendKind, prevMethodDef->mAppendKind == mAllowAppendKind);
  1128. RETURN_BETTER_OR_WORSE(newMethodDef->mCommutableKind != BfCommutableKind_Reverse, prevMethodDef->mCommutableKind != BfCommutableKind_Reverse);
  1129. // If one of these methods is local to the current extension then choose that one
  1130. auto activeDef = mModule->GetActiveTypeDef();
  1131. RETURN_BETTER_OR_WORSE(newMethodDef->mDeclaringType == activeDef, prevMethodDef->mDeclaringType == activeDef);
  1132. RETURN_BETTER_OR_WORSE(newMethodDef->mDeclaringType->IsExtension(), prevMethodDef->mDeclaringType->IsExtension());
  1133. RETURN_BETTER_OR_WORSE(newMethodDef->mIsMutating, prevMethodDef->mIsMutating);
  1134. if (newMethodDef->mHasComptime != prevMethodDef->mHasComptime)
  1135. {
  1136. bool isComptime = (mModule->mIsComptimeModule) || ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0);
  1137. RETURN_BETTER_OR_WORSE(newMethodDef->mHasComptime == isComptime, prevMethodDef->mHasComptime == isComptime);
  1138. }
  1139. RETURN_RESULTS;
  1140. }
  1141. BfTypedValue BfMethodMatcher::ResolveArgTypedValue(BfResolvedArg& resolvedArg, BfType* checkType, BfTypeVector* genericArgumentsSubstitute, BfType *origCheckType, BfResolveArgFlags flags)
  1142. {
  1143. BfTypedValue argTypedValue = resolvedArg.mTypedValue;
  1144. if ((resolvedArg.mArgFlags & BfArgFlag_DelegateBindAttempt) != 0)
  1145. {
  1146. BfExprEvaluator exprEvaluator(mModule);
  1147. exprEvaluator.mExpectingType = checkType;
  1148. BF_ASSERT(resolvedArg.mExpression->IsA<BfDelegateBindExpression>());
  1149. auto delegateBindExpr = BfNodeDynCast<BfDelegateBindExpression>(resolvedArg.mExpression);
  1150. BfMethodInstance* boundMethodInstance = NULL;
  1151. auto bindType = checkType;
  1152. if ((bindType == NULL) && (origCheckType != NULL) && (!origCheckType->IsUnspecializedTypeVariation()))
  1153. bindType = checkType;
  1154. if (exprEvaluator.CanBindDelegate(delegateBindExpr, &boundMethodInstance, bindType, genericArgumentsSubstitute))
  1155. {
  1156. if (delegateBindExpr->mNewToken == NULL)
  1157. {
  1158. if (boundMethodInstance->GetOwner()->IsFunction())
  1159. {
  1160. return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), boundMethodInstance->GetOwner());
  1161. }
  1162. else if ((boundMethodInstance->mDisallowCalling) || ((flags & BfResolveArgFlag_FromGeneric) == 0))
  1163. {
  1164. argTypedValue = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), checkType);
  1165. }
  1166. else
  1167. {
  1168. resolvedArg.mExpectedType = checkType;
  1169. auto methodRefType = mModule->CreateMethodRefType(boundMethodInstance);
  1170. mModule->AddDependency(methodRefType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_Calls);
  1171. mModule->AddCallDependency(boundMethodInstance);
  1172. argTypedValue = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), methodRefType);
  1173. }
  1174. }
  1175. else
  1176. argTypedValue = BfTypedValue(BfTypedValueKind_UntypedValue);
  1177. }
  1178. }
  1179. else if ((resolvedArg.mArgFlags & BfArgFlag_LambdaBindAttempt) != 0)
  1180. {
  1181. if ((argTypedValue) && (argTypedValue.mType->IsMethodRef()) &&
  1182. ((checkType == NULL) || (!checkType->IsMethodRef())))
  1183. {
  1184. // This may be from a previous checkMethod, clear it out
  1185. argTypedValue = BfTypedValue();
  1186. }
  1187. BfExprEvaluator exprEvaluator(mModule);
  1188. exprEvaluator.mExpectingType = checkType;
  1189. BF_ASSERT(resolvedArg.mExpression->IsA<BfLambdaBindExpression>());
  1190. auto lambdaBindExpr = (BfLambdaBindExpression*)resolvedArg.mExpression;
  1191. if ((checkType != NULL) && (checkType->IsDelegate()))
  1192. {
  1193. BfMethodInstance* methodInstance = mModule->GetRawMethodInstanceAtIdx(checkType->ToTypeInstance(), 0, "Invoke");
  1194. if (methodInstance != NULL)
  1195. {
  1196. if (methodInstance->GetParamCount() == (int)lambdaBindExpr->mParams.size())
  1197. {
  1198. if (lambdaBindExpr->mNewToken == NULL)
  1199. {
  1200. if (!resolvedArg.mTypedValue)
  1201. {
  1202. // Resolve for real
  1203. resolvedArg.mTypedValue = mModule->CreateValueFromExpression(lambdaBindExpr, checkType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_NoAutoComplete));
  1204. }
  1205. argTypedValue = resolvedArg.mTypedValue;
  1206. }
  1207. else
  1208. argTypedValue = BfTypedValue(BfTypedValueKind_UntypedValue);
  1209. //argTypedValue = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), checkType);
  1210. }
  1211. }
  1212. }
  1213. else if ((checkType == NULL) && (origCheckType != NULL) && (origCheckType->IsUnspecializedTypeVariation()) && (genericArgumentsSubstitute != NULL) && (origCheckType->IsDelegateOrFunction()))
  1214. {
  1215. BfMethodInstance* methodInstance = mModule->GetRawMethodInstanceAtIdx(origCheckType->ToTypeInstance(), 0, "Invoke");
  1216. if (methodInstance != NULL)
  1217. {
  1218. if ((methodInstance->mReturnType->IsGenericParam()) && (((BfGenericParamType*)methodInstance->mReturnType)->mGenericParamKind == BfGenericParamKind_Method))
  1219. {
  1220. bool isValid = true;
  1221. int returnMethodGenericArgIdx = ((BfGenericParamType*)methodInstance->mReturnType)->mGenericParamIdx;
  1222. if ((*genericArgumentsSubstitute)[returnMethodGenericArgIdx] != NULL)
  1223. {
  1224. isValid = false;
  1225. }
  1226. if (methodInstance->mParams.size() != (int)lambdaBindExpr->mParams.size())
  1227. isValid = false;
  1228. for (auto& param : methodInstance->mParams)
  1229. {
  1230. if (param.mResolvedType->IsGenericParam())
  1231. {
  1232. auto genericParamType = (BfGenericParamType*)param.mResolvedType;
  1233. if ((genericParamType->mGenericParamKind == BfGenericParamKind_Method) && ((*genericArgumentsSubstitute)[genericParamType->mGenericParamIdx] == NULL))
  1234. {
  1235. isValid = false;
  1236. }
  1237. }
  1238. }
  1239. if (isValid)
  1240. {
  1241. bool success = false;
  1242. (*genericArgumentsSubstitute)[returnMethodGenericArgIdx] = mModule->GetPrimitiveType(BfTypeCode_None);
  1243. auto tryType = mModule->ResolveGenericType(origCheckType, NULL, genericArgumentsSubstitute, mModule->mCurTypeInstance);
  1244. if (tryType != NULL)
  1245. {
  1246. auto inferredReturnType = mModule->CreateValueFromExpression(lambdaBindExpr, tryType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_InferReturnType | BfEvalExprFlags_NoAutoComplete));
  1247. if (inferredReturnType.mType != NULL)
  1248. {
  1249. (*genericArgumentsSubstitute)[returnMethodGenericArgIdx] = inferredReturnType.mType;
  1250. if (((flags & BfResolveArgFlag_FromGenericParam) != 0) && (lambdaBindExpr->mNewToken == NULL))
  1251. {
  1252. auto resolvedType = mModule->ResolveGenericType(origCheckType, NULL, genericArgumentsSubstitute, mModule->mCurTypeInstance);
  1253. if (resolvedType != NULL)
  1254. {
  1255. // Resolve for real
  1256. resolvedArg.mTypedValue = mModule->CreateValueFromExpression(lambdaBindExpr, resolvedType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_NoAutoComplete));
  1257. argTypedValue = resolvedArg.mTypedValue;
  1258. }
  1259. }
  1260. success = true;
  1261. }
  1262. }
  1263. if (!success)
  1264. {
  1265. // Put back
  1266. (*genericArgumentsSubstitute)[returnMethodGenericArgIdx] = NULL;
  1267. }
  1268. }
  1269. }
  1270. }
  1271. }
  1272. }
  1273. else if ((resolvedArg.mArgFlags & BfArgFlag_UnqualifiedDotAttempt) != 0)
  1274. {
  1275. if ((checkType != NULL) && (checkType->IsPayloadEnum()))
  1276. {
  1277. // Should we actually check the member name?
  1278. argTypedValue = BfTypedValue(BfTypedValueKind_UntypedValue);
  1279. }
  1280. }
  1281. else if ((resolvedArg.mArgFlags & BfArgFlag_UntypedDefault) != 0)
  1282. {
  1283. if (checkType != NULL)
  1284. argTypedValue = BfTypedValue(BfTypedValueKind_UntypedValue);
  1285. }
  1286. else if ((resolvedArg.mArgFlags & BfArgFlag_DeferredEval) != 0)
  1287. {
  1288. if (resolvedArg.mExpression != NULL)
  1289. {
  1290. if ((resolvedArg.mExpectedType != checkType) || (resolvedArg.mExpectedType == NULL)) // Did our last check match for this type?
  1291. {
  1292. SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
  1293. SetAndRestoreValue<bool> prevIgnoreError(mModule->mIgnoreErrors, true);
  1294. bool prevNoBind = false;
  1295. if (mModule->mCurMethodState != NULL)
  1296. {
  1297. prevNoBind = mModule->mCurMethodState->mNoBind;
  1298. mModule->mCurMethodState->mNoBind = true;
  1299. }
  1300. auto prevBlock = mModule->mBfIRBuilder->GetInsertBlock();
  1301. BfExprEvaluator exprEvaluator(mModule);
  1302. exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags);
  1303. exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | BfEvalExprFlags_AllowIntUnknown | BfEvalExprFlags_AllowRefExpr | BfEvalExprFlags_NoAutoComplete);
  1304. if ((resolvedArg.mArgFlags & BfArgFlag_ParamsExpr) != 0)
  1305. exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | BfEvalExprFlags_AllowParamsExpr);
  1306. auto expectType = checkType;
  1307. if (expectType != NULL)
  1308. {
  1309. if (expectType->IsRef())
  1310. {
  1311. auto refType = (BfRefType*)expectType;
  1312. expectType = refType->mElementType;
  1313. }
  1314. if ((genericArgumentsSubstitute != NULL) && (expectType->IsUnspecializedType()))
  1315. expectType = mModule->ResolveGenericType(expectType, NULL, genericArgumentsSubstitute, mModule->mCurTypeInstance, true);
  1316. }
  1317. exprEvaluator.mExpectingType = expectType;
  1318. exprEvaluator.Evaluate(resolvedArg.mExpression);
  1319. argTypedValue = exprEvaluator.GetResult();
  1320. if ((argTypedValue) && (argTypedValue.mType->IsVar()))
  1321. argTypedValue = BfTypedValue();
  1322. if (mModule->mCurMethodState != NULL)
  1323. mModule->mCurMethodState->mNoBind = prevNoBind;
  1324. if ((argTypedValue) && (!argTypedValue.mType->IsVar()))
  1325. {
  1326. if (checkType != NULL)
  1327. resolvedArg.mExpectedType = checkType;
  1328. auto storeTypedValue = argTypedValue;
  1329. if ((storeTypedValue.mValue) & (!storeTypedValue.mValue.IsFake()))
  1330. {
  1331. // We actually want to ensure that this cached value is a fake val. There are potential cases where a fake val
  1332. // won't be generated but we should throw an error, so we need to make sure we actually re-evaluate when the call
  1333. // is generated
  1334. //storeTypedValue.mValue = mModule->mBfIRBuilder->GetFakeVal();
  1335. resolvedArg.mWantsRecalc = true;
  1336. }
  1337. resolvedArg.mTypedValue = storeTypedValue;
  1338. //BF_ASSERT(argTypedValue.mValue.mId != -1);
  1339. }
  1340. mModule->mBfIRBuilder->SetInsertPoint(prevBlock);
  1341. }
  1342. }
  1343. }
  1344. else if ((resolvedArg.mArgFlags & BfArgFlag_VariableDeclaration) != 0)
  1345. {
  1346. if ((checkType != NULL) && (checkType->IsRef()))
  1347. argTypedValue = BfTypedValue(BfTypedValueKind_UntypedValue);
  1348. }
  1349. return argTypedValue;
  1350. }
  1351. bool BfMethodMatcher::WantsCheckMethod(BfProtectionCheckFlags& flags, BfTypeInstance* startTypeInstance, BfTypeInstance* checkTypeInstance, BfMethodDef* checkMethod)
  1352. {
  1353. MatchFailKind matchFailKind = MatchFailKind_None;
  1354. if (!mModule->CheckProtection(flags, checkTypeInstance, checkMethod->mDeclaringType->mProject, checkMethod->mProtection, startTypeInstance))
  1355. {
  1356. if ((mBypassVirtual) &&
  1357. ((checkMethod->mProtection == BfProtection_Protected) || (checkMethod->mProtection == BfProtection_ProtectedInternal)) &&
  1358. (mModule->TypeIsSubTypeOf(mModule->mCurTypeInstance, startTypeInstance)))
  1359. {
  1360. // Allow explicit 'base' call
  1361. }
  1362. else
  1363. {
  1364. return false;
  1365. }
  1366. }
  1367. if (mCheckedKind != checkMethod->mCheckedKind)
  1368. {
  1369. bool passes = true;
  1370. if (mCheckedKind != BfCheckedKind_NotSet)
  1371. {
  1372. passes = false;
  1373. }
  1374. else
  1375. {
  1376. auto defaultCheckedKind = mModule->GetDefaultCheckedKind();
  1377. if (defaultCheckedKind != checkMethod->mCheckedKind)
  1378. passes = false;
  1379. }
  1380. if (!passes)
  1381. {
  1382. return false;
  1383. }
  1384. }
  1385. return true;
  1386. }
  1387. bool BfMethodMatcher::InferFromGenericConstraints(BfMethodInstance* methodInstance, BfGenericParamInstance* genericParamInst, BfTypeVector* methodGenericArgs)
  1388. {
  1389. if (!genericParamInst->mExternType->IsGenericParam())
  1390. return false;
  1391. auto genericParamType = (BfGenericParamType*)genericParamInst->mExternType;
  1392. if (genericParamType->mGenericParamKind != BfGenericParamKind_Method)
  1393. return false;
  1394. BfType* checkArgType = NULL;
  1395. for (auto& checkOpConstraint : genericParamInst->mOperatorConstraints)
  1396. {
  1397. auto leftType = checkOpConstraint.mLeftType;
  1398. if ((leftType != NULL) && (leftType->IsUnspecializedType()))
  1399. leftType = mModule->ResolveGenericType(leftType, NULL, methodGenericArgs, mModule->mCurTypeInstance);
  1400. if (leftType != NULL)
  1401. leftType = mModule->FixIntUnknown(leftType);
  1402. auto rightType = checkOpConstraint.mRightType;
  1403. if ((rightType != NULL) && (rightType->IsUnspecializedType()))
  1404. rightType = mModule->ResolveGenericType(rightType, NULL, methodGenericArgs, mModule->mCurTypeInstance);
  1405. if (rightType != NULL)
  1406. rightType = mModule->FixIntUnknown(rightType);
  1407. BfConstraintState constraintSet;
  1408. constraintSet.mPrevState = mModule->mContext->mCurConstraintState;
  1409. constraintSet.mGenericParamInstance = genericParamInst;
  1410. constraintSet.mLeftType = leftType;
  1411. constraintSet.mRightType = rightType;
  1412. SetAndRestoreValue<BfConstraintState*> prevConstraintSet(mModule->mContext->mCurConstraintState, &constraintSet);
  1413. if (!mModule->CheckConstraintState(NULL))
  1414. return false;
  1415. if (checkOpConstraint.mBinaryOp != BfBinaryOp_None)
  1416. {
  1417. if ((leftType == NULL) || (rightType == NULL))
  1418. continue;
  1419. BfExprEvaluator exprEvaluator(mModule);
  1420. BfTypedValue leftValue(mModule->mBfIRBuilder->GetFakeVal(), leftType);
  1421. BfTypedValue rightValue(mModule->mBfIRBuilder->GetFakeVal(), rightType);
  1422. //
  1423. {
  1424. SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
  1425. SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
  1426. exprEvaluator.PerformBinaryOperation(NULL, NULL, checkOpConstraint.mBinaryOp, NULL, BfBinOpFlag_NoClassify, leftValue, rightValue);
  1427. }
  1428. if (exprEvaluator.mResult)
  1429. checkArgType = exprEvaluator.mResult.mType;
  1430. }
  1431. else
  1432. {
  1433. if (rightType == NULL)
  1434. continue;
  1435. BfTypedValue rightValue(mModule->mBfIRBuilder->GetFakeVal(), rightType);
  1436. StringT<128> failedOpName;
  1437. if (checkOpConstraint.mCastToken == BfToken_Implicit)
  1438. {
  1439. }
  1440. else
  1441. {
  1442. SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
  1443. SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
  1444. if (checkOpConstraint.mCastToken == BfToken_Explicit)
  1445. {
  1446. }
  1447. else
  1448. {
  1449. BfExprEvaluator exprEvaluator(mModule);
  1450. exprEvaluator.mResult = rightValue;
  1451. exprEvaluator.PerformUnaryOperation(NULL, checkOpConstraint.mUnaryOp, NULL, BfUnaryOpFlag_IsConstraintCheck);
  1452. if (exprEvaluator.mResult)
  1453. checkArgType = exprEvaluator.mResult.mType;
  1454. }
  1455. }
  1456. }
  1457. }
  1458. if ((checkArgType == NULL) && ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_ComptypeExpr) != 0))
  1459. {
  1460. for (auto comptypeConstraint : genericParamInst->mComptypeConstraint)
  1461. {
  1462. checkArgType = mModule->ResolveGenericMethodTypeRef(comptypeConstraint, methodInstance, genericParamInst, methodGenericArgs);
  1463. if (checkArgType == NULL)
  1464. return false;
  1465. }
  1466. }
  1467. if (checkArgType == NULL)
  1468. return false;
  1469. if (checkArgType->IsVar())
  1470. return false;
  1471. (*methodGenericArgs)[genericParamType->mGenericParamIdx] = checkArgType;
  1472. return true;
  1473. }
  1474. bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInstance* typeInstance, BfMethodDef* checkMethod, bool isFailurePass)
  1475. {
  1476. BP_ZONE("BfMethodMatcher::CheckMethod");
  1477. BackupMatchKind curMatchKind = BackupMatchKind_None;
  1478. bool hadMatch = false;
  1479. // Never consider overrides - they only get found at original method declaration
  1480. // mBypassVirtual gets set when we are doing an explicit "base" call, or when we are a struct --
  1481. // because on structs we know the exact type
  1482. if ((checkMethod->mIsOverride) && (!mBypassVirtual) && (!typeInstance->IsValueType()))
  1483. return false;
  1484. mMethodCheckCount++;
  1485. BfMethodInstance* methodInstance = mModule->GetRawMethodInstance(typeInstance, checkMethod);
  1486. if (methodInstance == NULL)
  1487. return false;
  1488. BfMethodInstance* typeUnspecMethodInstance = mModule->GetUnspecializedMethodInstance(methodInstance, true);
  1489. BfTypeVector* typeGenericArguments = NULL;
  1490. if (typeInstance->mGenericTypeInfo != NULL)
  1491. typeGenericArguments = &typeInstance->mGenericTypeInfo->mTypeGenericArguments;
  1492. if ((mInterfaceMethodInstance != NULL) && (methodInstance->GetExplicitInterface() != NULL))
  1493. {
  1494. BfTypeInstance* wantInterface = mInterfaceMethodInstance->mMethodInstanceGroup->mOwner;
  1495. if (wantInterface != methodInstance->GetExplicitInterface())
  1496. return false;
  1497. }
  1498. if ((checkMethod->mIsVirtual) && (!checkMethod->mIsOverride) && (!mBypassVirtual) &&
  1499. (targetTypeInstance != NULL) && (targetTypeInstance->IsObject()))
  1500. {
  1501. mModule->PopulateType(targetTypeInstance, BfPopulateType_DataAndMethods);
  1502. if ((methodInstance->mVirtualTableIdx < targetTypeInstance->mVirtualMethodTable.mSize) && (methodInstance->mVirtualTableIdx >= 0))
  1503. {
  1504. BfVirtualMethodEntry& vEntry = targetTypeInstance->mVirtualMethodTable[methodInstance->mVirtualTableIdx];
  1505. if ((vEntry.mImplementingMethod.mTypeInstance != NULL) && (vEntry.mImplementingMethod.mTypeInstance->mDefineState < BfTypeDefineState_DefinedAndMethodsSlotted) &&
  1506. (mModule->mCompiler->IsAutocomplete()))
  1507. {
  1508. // Silently ignore
  1509. }
  1510. else
  1511. {
  1512. auto implMethod = (BfMethodInstance*)vEntry.mImplementingMethod;
  1513. if ((implMethod != methodInstance) && (implMethod != NULL))
  1514. {
  1515. SetAndRestoreValue<bool> prevBypassVirtual(mBypassVirtual, true);
  1516. return CheckMethod(targetTypeInstance, implMethod->GetOwner(), implMethod->mMethodDef, isFailurePass);
  1517. }
  1518. }
  1519. }
  1520. else
  1521. {
  1522. // Being in autocomplete mode is the only excuse for not having the virtual method table slotted
  1523. if ((!mModule->mCompiler->IsAutocomplete()) && (!targetTypeInstance->mTypeFailed) && (!targetTypeInstance->IsUnspecializedTypeVariation()))
  1524. {
  1525. mModule->AssertErrorState();
  1526. }
  1527. }
  1528. }
  1529. BfGenericInferContext genericInferContext;
  1530. genericInferContext.mModule = mModule;
  1531. genericInferContext.mCheckMethodGenericArguments = &mCheckMethodGenericArguments;
  1532. HashSet<int> allowEmptyGenericSet;
  1533. BfAutoComplete* autoComplete = NULL;
  1534. if ((mModule->mCompiler->mResolvePassData != NULL) && (!isFailurePass) && ((mBfEvalExprFlags & BfEvalExprFlags_NoAutoComplete) == 0))
  1535. autoComplete = mModule->mCompiler->mResolvePassData->mAutoComplete;
  1536. if (checkMethod->mMethodType != BfMethodType_Extension)
  1537. {
  1538. if (((checkMethod->mIsStatic) && (!mAllowStatic)) ||
  1539. ((!checkMethod->mIsStatic) && (!mAllowNonStatic)))
  1540. {
  1541. if (!typeInstance->IsFunction())
  1542. autoComplete = NULL;
  1543. }
  1544. }
  1545. if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo))
  1546. {
  1547. BfAutoComplete::MethodMatchEntry methodMatchEntry;
  1548. methodMatchEntry.mMethodDef = checkMethod;
  1549. methodMatchEntry.mTypeInstance = typeInstance;
  1550. methodMatchEntry.mCurMethodInstance = mModule->mCurMethodInstance;
  1551. autoComplete->mMethodMatchInfo->mInstanceList.push_back(methodMatchEntry);
  1552. }
  1553. BfTypeVector* genericArgumentsSubstitute = NULL;
  1554. int argIdx = 0;
  1555. int argMatchCount = 0;
  1556. bool needInferGenericParams = (checkMethod->mGenericParams.size() != 0) &&
  1557. ((!mHadExplicitGenericArguments) || (mHadPartialGenericArguments));
  1558. int paramIdx = 0;
  1559. BfType* paramsElementType = NULL;
  1560. if (checkMethod->HasAppend())
  1561. paramIdx++;
  1562. int uniqueGenericStartIdx = mModule->GetLocalInferrableGenericArgCount(checkMethod);
  1563. if (mHadExplicitGenericArguments)
  1564. {
  1565. int genericArgDelta = (int)(checkMethod->mGenericParams.size() - (mExplicitMethodGenericArguments.size() + uniqueGenericStartIdx));
  1566. if (mHadOpenGenericArguments)
  1567. {
  1568. if (genericArgDelta <= 0)
  1569. goto NoMatch;
  1570. }
  1571. else
  1572. {
  1573. if (genericArgDelta != 0)
  1574. goto NoMatch;
  1575. }
  1576. }
  1577. for (auto& checkGenericArgRef : mCheckMethodGenericArguments)
  1578. checkGenericArgRef = NULL;
  1579. mCheckMethodGenericArguments.resize(checkMethod->mGenericParams.size());
  1580. for (auto& genericArgRef : mCheckMethodGenericArguments)
  1581. genericArgRef = NULL;
  1582. if (mHadExplicitGenericArguments)
  1583. {
  1584. if (uniqueGenericStartIdx > 0)
  1585. {
  1586. genericArgumentsSubstitute = &mCheckMethodGenericArguments;
  1587. mCheckMethodGenericArguments.clear();
  1588. mCheckMethodGenericArguments.reserve(mExplicitMethodGenericArguments.size() + uniqueGenericStartIdx);
  1589. for (int i = 0; i < uniqueGenericStartIdx; i++)
  1590. mCheckMethodGenericArguments.Add(NULL);
  1591. for (int i = 0; i < (int)mExplicitMethodGenericArguments.size(); i++)
  1592. mCheckMethodGenericArguments.Add(mExplicitMethodGenericArguments[i]);
  1593. }
  1594. else
  1595. {
  1596. genericArgumentsSubstitute = &mExplicitMethodGenericArguments;
  1597. }
  1598. if ((mHadPartialGenericArguments) && (needInferGenericParams))
  1599. {
  1600. genericArgumentsSubstitute = &mCheckMethodGenericArguments;
  1601. for (int i = 0; i < (int)mExplicitMethodGenericArguments.mSize; i++)
  1602. mCheckMethodGenericArguments[i] = mExplicitMethodGenericArguments[i];
  1603. }
  1604. }
  1605. else if (needInferGenericParams)
  1606. genericArgumentsSubstitute = &mCheckMethodGenericArguments;
  1607. if (mHasArgNames)
  1608. {
  1609. checkMethod->BuildParamNameMap();
  1610. bool prevWasNull = false;
  1611. for (int argIdx = (int)mArguments.mSize - 1; argIdx >= 0; argIdx--)
  1612. {
  1613. auto& arg = mArguments[argIdx];
  1614. if (arg.mNameNode != NULL)
  1615. {
  1616. if (prevWasNull)
  1617. {
  1618. if (argIdx >= checkMethod->mParams.mSize)
  1619. goto NoMatch;
  1620. if (checkMethod->mParams[argIdx]->mName != arg.mNameNode->ToStringView())
  1621. goto NoMatch;
  1622. }
  1623. else
  1624. {
  1625. if (!checkMethod->mParamNameMap->ContainsKey(arg.mNameNode->ToStringView()))
  1626. goto NoMatch;
  1627. }
  1628. prevWasNull = false;
  1629. }
  1630. else
  1631. {
  1632. prevWasNull = true;
  1633. }
  1634. }
  1635. }
  1636. if ((checkMethod->mIsMutating) && (targetTypeInstance != NULL) && (targetTypeInstance->IsValueType()) &&
  1637. ((mTarget.IsReadOnly()) || (!mTarget.IsAddr())) &&
  1638. (!targetTypeInstance->IsValuelessType()))
  1639. {
  1640. goto NoMatch;
  1641. }
  1642. if (mSkipImplicitParams)
  1643. {
  1644. //paramOfs = methodInstance->GetImplicitParamCount();
  1645. //paramIdx += paramOfs;
  1646. }
  1647. if (needInferGenericParams)
  1648. {
  1649. genericInferContext.mPrevArgValues.resize(checkMethod->mGenericParams.size());
  1650. int paramOfs = methodInstance->GetImplicitParamCount();
  1651. int paramCount = methodInstance->GetParamCount();
  1652. SizedArray<int, 8> deferredArgs;
  1653. int argIdx = 0;
  1654. int paramIdx = 0;
  1655. if (checkMethod->HasAppend())
  1656. paramIdx++;
  1657. if (checkMethod->mMethodType == BfMethodType_Extension)
  1658. {
  1659. argIdx--;
  1660. }
  1661. paramIdx += paramOfs;
  1662. bool hadInferFailure = false;
  1663. int inferParamOffset = paramOfs - argIdx;
  1664. int paramsParamIdx = -1;
  1665. enum ResultKind
  1666. {
  1667. ResultKind_Ok,
  1668. ResultKind_Failed,
  1669. ResultKind_Deferred,
  1670. };
  1671. auto _CheckArg = [&](int argIdx)
  1672. {
  1673. paramIdx = argIdx + inferParamOffset;
  1674. if ((paramsParamIdx != -1) && (paramIdx > paramsParamIdx))
  1675. paramIdx = paramsParamIdx;
  1676. auto wantType = methodInstance->GetParamType(paramIdx);
  1677. auto checkType = wantType;
  1678. auto origCheckType = checkType;
  1679. if (checkType->IsGenericParam())
  1680. {
  1681. BfGenericParamInstance* genericParamInstance = NULL;
  1682. auto genericParamType = (BfGenericParamType*)checkType;
  1683. checkType = NULL;
  1684. if (genericParamType->mGenericParamKind == BfGenericParamKind_Method)
  1685. {
  1686. if ((genericArgumentsSubstitute != NULL) && (genericParamType->mGenericParamIdx < (int)genericArgumentsSubstitute->size()))
  1687. checkType = (*genericArgumentsSubstitute)[genericParamType->mGenericParamIdx];
  1688. genericParamInstance = methodInstance->mMethodInfoEx->mGenericParams[genericParamType->mGenericParamIdx];
  1689. }
  1690. else
  1691. genericParamInstance = mModule->GetGenericParamInstance(genericParamType);
  1692. if (checkType == NULL)
  1693. {
  1694. checkType = genericParamInstance->mTypeConstraint;
  1695. origCheckType = checkType; // We can do "ResolveGenericType" on this type
  1696. }
  1697. }
  1698. bool attemptedGenericResolve = false;
  1699. if ((checkType != NULL) && (genericArgumentsSubstitute != NULL) && (checkType->IsUnspecializedType()))
  1700. {
  1701. attemptedGenericResolve = true;
  1702. checkType = mModule->ResolveGenericType(origCheckType, NULL, genericArgumentsSubstitute, mModule->mCurTypeInstance);
  1703. }
  1704. if (wantType->IsUnspecializedType())
  1705. {
  1706. BfTypedValue argTypedValue;
  1707. if (argIdx == -1)
  1708. {
  1709. if (mOrigTarget)
  1710. argTypedValue = mOrigTarget;
  1711. else
  1712. argTypedValue = mTarget;
  1713. }
  1714. else
  1715. {
  1716. BfResolveArgFlags flags = BfResolveArgFlag_FromGeneric;
  1717. if (wantType->IsGenericParam())
  1718. flags = (BfResolveArgFlags)(flags | BfResolveArgFlag_FromGenericParam);
  1719. argTypedValue = ResolveArgTypedValue(mArguments[argIdx], checkType, genericArgumentsSubstitute, origCheckType, flags);
  1720. }
  1721. if (!argTypedValue.IsUntypedValue())
  1722. {
  1723. auto type = argTypedValue.mType;
  1724. if (!argTypedValue)
  1725. {
  1726. if ((checkType == NULL) && (attemptedGenericResolve) && (genericInferContext.GetUnresolvedCount() >= 2))
  1727. {
  1728. deferredArgs.Add(argIdx);
  1729. return ResultKind_Deferred;
  1730. }
  1731. return ResultKind_Failed;
  1732. }
  1733. if (type->IsVar())
  1734. mHasVarArguments = true;
  1735. if (methodInstance->GetParamKind(paramIdx) == BfParamKind_Params)
  1736. {
  1737. if ((mArguments[argIdx].mArgFlags & BfArgFlag_ParamsExpr) != 0)
  1738. {
  1739. // Match to entire thing
  1740. }
  1741. else
  1742. {
  1743. paramsParamIdx = paramIdx;
  1744. if ((wantType->IsArray()) || (wantType->IsSizedArray()) || (wantType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef)))
  1745. wantType = wantType->GetUnderlyingType();
  1746. }
  1747. }
  1748. if (!genericInferContext.InferGenericArgument(methodInstance, type, wantType, argTypedValue.mValue))
  1749. return ResultKind_Failed;
  1750. }
  1751. }
  1752. return ResultKind_Ok;
  1753. };
  1754. for (; argIdx < (int)mArguments.size(); argIdx++)
  1755. {
  1756. paramIdx = argIdx + inferParamOffset;
  1757. if ((paramIdx >= paramCount) && (paramsParamIdx == -1))
  1758. break; // Possible for delegate 'params' type methods
  1759. auto resultKind = _CheckArg(argIdx);
  1760. if (resultKind == ResultKind_Failed)
  1761. goto NoMatch;
  1762. }
  1763. if ((methodInstance->mParams.mSize > 0) && (methodInstance->GetParamKind(methodInstance->mParams.mSize - 1) == BfParamKind_Params))
  1764. {
  1765. // Handle `params int[C]` generic sized array params case
  1766. auto paramsType = methodInstance->GetParamType(methodInstance->mParams.mSize - 1);
  1767. if (paramsType->IsUnknownSizedArrayType())
  1768. {
  1769. auto unknownSizedArray = (BfUnknownSizedArrayType*)paramsType;
  1770. if (unknownSizedArray->mElementCountSource->IsMethodGenericParam())
  1771. {
  1772. auto genericParam = (BfGenericParamType*)unknownSizedArray->mElementCountSource;
  1773. if ((*genericArgumentsSubstitute)[genericParam->mGenericParamIdx] == NULL)
  1774. {
  1775. int paramsCount = (int)mArguments.mSize - inferParamOffset;
  1776. (*genericArgumentsSubstitute)[genericParam->mGenericParamIdx] = mModule->CreateConstExprValueType(
  1777. BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, paramsCount), mModule->GetPrimitiveType(BfTypeCode_IntPtr)));
  1778. }
  1779. }
  1780. }
  1781. else if (paramsType->IsParamsType())
  1782. {
  1783. paramsType = paramsType->GetUnderlyingType();
  1784. if (paramsType->IsGenericParam())
  1785. {
  1786. auto genericParamType = (BfGenericParamType*)paramsType;
  1787. if (genericParamType->mGenericParamKind == BfGenericParamKind_Method)
  1788. {
  1789. auto genericParamInst = methodInstance->mMethodInfoEx->mGenericParams[genericParamType->mGenericParamIdx];
  1790. if ((genericParamInst->mTypeConstraint != NULL) && (genericParamInst->mTypeConstraint->IsInstanceOf(mModule->mCompiler->mTupleTypeDef)))
  1791. {
  1792. bool isValid = true;
  1793. BfTypeVector genericArgs;
  1794. for (int argIdx = methodInstance->mParams.mSize - 1 - inferParamOffset; argIdx < (int)mArguments.size(); argIdx++)
  1795. {
  1796. BfTypedValue argTypedValue = ResolveArgTypedValue(mArguments[argIdx], NULL, genericArgumentsSubstitute);
  1797. if (!argTypedValue)
  1798. {
  1799. isValid = false;
  1800. break;
  1801. }
  1802. genericArgs.Add(mModule->FixIntUnknown(argTypedValue.mType));
  1803. }
  1804. if (isValid)
  1805. {
  1806. (*genericArgumentsSubstitute)[genericParamType->mGenericParamIdx] = mModule->CreateTupleType(genericArgs, SubstituteList());
  1807. }
  1808. }
  1809. }
  1810. }
  1811. }
  1812. }
  1813. if (!deferredArgs.IsEmpty())
  1814. {
  1815. genericInferContext.InferGenericArguments(methodInstance);
  1816. }
  1817. while (!deferredArgs.IsEmpty())
  1818. {
  1819. int prevDeferredSize = (int)deferredArgs.size();
  1820. for (int i = 0; i < prevDeferredSize; i++)
  1821. {
  1822. auto resultKind = _CheckArg(deferredArgs[i]);
  1823. if (resultKind == ResultKind_Failed)
  1824. goto NoMatch;
  1825. }
  1826. deferredArgs.RemoveRange(0, prevDeferredSize);
  1827. if (prevDeferredSize == deferredArgs.size())
  1828. {
  1829. // No progress
  1830. goto NoMatch;
  1831. }
  1832. }
  1833. //
  1834. {
  1835. int paramIdx = (int)mArguments.size() + paramOfs;
  1836. while (paramIdx < checkMethod->mParams.size())
  1837. {
  1838. if ((paramIdx < methodInstance->mDefaultValues.size()) && (methodInstance->mDefaultValues[paramIdx]))
  1839. {
  1840. auto wantType = methodInstance->GetParamType(paramIdx);
  1841. auto checkType = wantType;
  1842. if (checkType->IsGenericParam())
  1843. {
  1844. BfGenericParamInstance* genericParamInstance = NULL;
  1845. auto genericParamType = (BfGenericParamType*)checkType;
  1846. if (genericParamType->mGenericParamKind == BfGenericParamKind_Method)
  1847. {
  1848. if ((genericArgumentsSubstitute != NULL) && (genericParamType->mGenericParamIdx < (int)genericArgumentsSubstitute->size()))
  1849. checkType = (*genericArgumentsSubstitute)[genericParamType->mGenericParamIdx];
  1850. genericParamInstance = methodInstance->mMethodInfoEx->mGenericParams[genericParamType->mGenericParamIdx];
  1851. if ((genericParamInstance->mGenericParamFlags & BfGenericParamFlag_Const) != 0)
  1852. {
  1853. if (mCheckMethodGenericArguments[genericParamType->mGenericParamIdx] == NULL)
  1854. allowEmptyGenericSet.Add(genericParamType->mGenericParamIdx);
  1855. }
  1856. }
  1857. }
  1858. }
  1859. paramIdx++;
  1860. }
  1861. }
  1862. if ((mCheckReturnType != NULL) && (methodInstance->mReturnType->IsUnspecializedType()))
  1863. {
  1864. if (!genericInferContext.InferGenericArgument(methodInstance, mCheckReturnType, methodInstance->mReturnType, BfIRValue()))
  1865. return ResultKind_Failed;
  1866. }
  1867. bool failed = false;
  1868. bool inferredAllGenericArguments = false;
  1869. for (int pass = 0; true; pass++)
  1870. {
  1871. bool madeProgress = false;
  1872. bool hasUninferred = false;
  1873. failed = false;
  1874. for (int genericArgIdx = uniqueGenericStartIdx; genericArgIdx < (int)checkMethod->mGenericParams.size(); genericArgIdx++)
  1875. {
  1876. if (genericArgIdx >= mCheckMethodGenericArguments.mSize)
  1877. {
  1878. failed = true;
  1879. }
  1880. else
  1881. {
  1882. auto& genericArg = mCheckMethodGenericArguments[genericArgIdx];
  1883. if (genericArg == NULL)
  1884. {
  1885. auto genericParam = methodInstance->mMethodInfoEx->mGenericParams[genericArgIdx];
  1886. InferFromGenericConstraints(methodInstance, genericParam, &mCheckMethodGenericArguments);
  1887. if (genericArg != NULL)
  1888. {
  1889. if (inferredAllGenericArguments)
  1890. genericInferContext.InferGenericArguments(methodInstance, genericArgIdx);
  1891. madeProgress = true;
  1892. }
  1893. hasUninferred = true;
  1894. if (!allowEmptyGenericSet.Contains(genericArgIdx))
  1895. failed = true;
  1896. }
  1897. }
  1898. }
  1899. if (!hasUninferred)
  1900. break;
  1901. if (inferredAllGenericArguments)
  1902. {
  1903. if (!madeProgress)
  1904. break;
  1905. }
  1906. genericInferContext.InferGenericArguments(methodInstance);
  1907. inferredAllGenericArguments = true;
  1908. }
  1909. if (failed)
  1910. goto NoMatch;
  1911. }
  1912. if (checkMethod->mMethodType == BfMethodType_Extension)
  1913. argIdx--;
  1914. // Iterate through params
  1915. while (true)
  1916. {
  1917. // Too many arguments
  1918. if (paramIdx >= (int)methodInstance->GetParamCount())
  1919. {
  1920. break;
  1921. }
  1922. bool isDeferredEval = false;
  1923. if ((argIdx >= 0) && (methodInstance->GetParamKind(paramIdx) == BfParamKind_Params) && (paramsElementType == NULL))
  1924. {
  1925. if (argIdx >= (int) mArguments.size())
  1926. break; // No params
  1927. BfTypedValue argTypedValue = ResolveArgTypedValue(mArguments[argIdx], NULL, genericArgumentsSubstitute);
  1928. if (!argTypedValue)
  1929. goto NoMatch;
  1930. if ((!argTypedValue.HasType()) && (!mArguments[argIdx].IsDeferredEval()))
  1931. goto NoMatch;
  1932. auto paramsArrayType = methodInstance->GetParamType(paramIdx);
  1933. paramsArrayType = mModule->ResolveGenericType(paramsArrayType, NULL, genericArgumentsSubstitute, mModule->mCurTypeInstance);
  1934. if (paramsArrayType == NULL)
  1935. goto NoMatch;
  1936. if ((mArguments[argIdx].mArgFlags & BfArgFlag_ParamsExpr) != 0)
  1937. {
  1938. // Direct-pass params
  1939. if ((argTypedValue.IsUntypedValue()) || (mModule->CanCast(argTypedValue, paramsArrayType)))
  1940. {
  1941. argIdx++;
  1942. argMatchCount++;
  1943. paramIdx++;
  1944. break;
  1945. }
  1946. goto NoMatch;
  1947. }
  1948. if ((paramsArrayType->IsArray()) || (paramsArrayType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef)))
  1949. {
  1950. paramsElementType = paramsArrayType->GetUnderlyingType();
  1951. while (argIdx < (int)mArguments.size())
  1952. {
  1953. argTypedValue = ResolveArgTypedValue(mArguments[argIdx], paramsElementType, genericArgumentsSubstitute);
  1954. if (!argTypedValue.HasType())
  1955. goto NoMatch;
  1956. BfCastFlags castFlags = ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp) != 0) ? BfCastFlags_NoConversionOperator : BfCastFlags_None;
  1957. if ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp_Explicit) != 0)
  1958. castFlags = (BfCastFlags)(castFlags | BfCastFlags_Explicit);
  1959. if (!mModule->CanCast(argTypedValue, paramsElementType, castFlags))
  1960. goto NoMatch;
  1961. argIdx++;
  1962. argMatchCount++;
  1963. }
  1964. }
  1965. else
  1966. goto NoMatch;
  1967. break;
  1968. }
  1969. if (methodInstance->IsImplicitCapture(paramIdx))
  1970. {
  1971. paramIdx++;
  1972. continue;
  1973. }
  1974. if (argIdx >= (int) mArguments.size())
  1975. {
  1976. // We have defaults the rest of the way, so that's cool
  1977. if (methodInstance->GetParamInitializer(paramIdx) != NULL)
  1978. break;
  1979. // We have unused params left over
  1980. goto NoMatch;
  1981. }
  1982. auto wantType = methodInstance->GetParamType(paramIdx);
  1983. if ((genericArgumentsSubstitute != NULL) && (wantType->IsUnspecializedType()))
  1984. {
  1985. wantType = typeUnspecMethodInstance->GetParamType(paramIdx);
  1986. auto resolvedType = mModule->ResolveGenericType(wantType, typeGenericArguments, genericArgumentsSubstitute, mModule->mCurTypeInstance, false);
  1987. if (resolvedType == NULL)
  1988. goto NoMatch;
  1989. wantType = resolvedType;
  1990. }
  1991. wantType = mModule->ResolveSelfType(wantType, typeInstance);
  1992. if ((argIdx >= 0) && ((mArguments[argIdx].mArgFlags & BfArgFlag_ParamsExpr) != 0))
  1993. {
  1994. // We had a 'params' expression but this method didn't have a params slot in this parameter
  1995. goto NoMatch;
  1996. }
  1997. BfTypedValue argTypedValue;
  1998. if (argIdx == -1)
  1999. argTypedValue = mTarget;
  2000. else
  2001. argTypedValue = ResolveArgTypedValue(mArguments[argIdx], wantType, genericArgumentsSubstitute);
  2002. if (!argTypedValue.IsUntypedValue())
  2003. {
  2004. if (!argTypedValue.HasType())
  2005. {
  2006. // Check to see if this is the last argument and that it's a potential enum match
  2007. if ((wantType->IsEnum()) && (argIdx == mArguments.size() - 1))
  2008. {
  2009. if (auto memberRefExpr = BfNodeDynCast<BfMemberReferenceExpression>(mArguments[argIdx].mExpression))
  2010. {
  2011. if (memberRefExpr->mTarget == NULL)
  2012. {
  2013. // Is dot expression
  2014. curMatchKind = BackupMatchKind_PartialLastArgMatch;
  2015. }
  2016. }
  2017. }
  2018. bool matches = false;
  2019. if (wantType->IsOut())
  2020. {
  2021. if (auto memberRefExpr = BfNodeDynCast<BfUninitializedExpression>(mArguments[argIdx].mExpression))
  2022. matches = true;
  2023. }
  2024. if (!matches)
  2025. goto NoMatch;
  2026. }
  2027. else
  2028. {
  2029. if ((checkMethod->mMethodType == BfMethodType_Extension) && (argIdx == -1))
  2030. {
  2031. if ((wantType->IsRef()) && (!argTypedValue.mType->IsRef()))
  2032. wantType = wantType->GetUnderlyingType();
  2033. }
  2034. if ((wantType->IsRef()) && (!argTypedValue.mType->IsRef()) &&
  2035. ((mAllowImplicitRef) || (wantType->IsIn())))
  2036. wantType = wantType->GetUnderlyingType();
  2037. BfCastFlags castFlags = ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp) != 0) ? BfCastFlags_NoConversionOperator : BfCastFlags_None;
  2038. if ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp_Explicit) != 0)
  2039. castFlags = (BfCastFlags)(castFlags | BfCastFlags_Explicit);
  2040. if ((mCheckReturnType != NULL) && (wantType->IsVar()))
  2041. {
  2042. // If we allowed this then it would allow too many matches (and allow conversion from any type during CastToValue)
  2043. goto NoMatch;
  2044. }
  2045. if (!mModule->CanCast(argTypedValue, wantType, castFlags))
  2046. {
  2047. if ((argIdx == -1) && (wantType->IsWrappableType()) && (mModule->GetWrappedStructType(wantType) == argTypedValue.mType))
  2048. {
  2049. // Extension target can be wrapped
  2050. }
  2051. else if ((mAllowImplicitWrap) && (argTypedValue.mType->IsWrappableType()) && (mModule->GetWrappedStructType(argTypedValue.mType) == wantType))
  2052. {
  2053. // Is wrapped type
  2054. }
  2055. else
  2056. goto NoMatch;
  2057. }
  2058. }
  2059. }
  2060. paramIdx++;
  2061. argIdx++;
  2062. argMatchCount++;
  2063. if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo))
  2064. {
  2065. auto methodMatchInfo = autoComplete->mMethodMatchInfo;
  2066. if (!methodMatchInfo->mHadExactMatch)
  2067. {
  2068. bool isBetter = false;
  2069. bool isWorse = false;
  2070. int methodIdx = (int)methodMatchInfo->mInstanceList.size() - 1;
  2071. if ((methodMatchInfo->mBestIdx != -1) && (methodMatchInfo->mBestIdx < (int)methodMatchInfo->mInstanceList.size()))
  2072. {
  2073. auto prevMethodMatchEntry = &methodMatchInfo->mInstanceList[methodMatchInfo->mBestIdx];
  2074. if (checkMethod->mParams.size() < mArguments.size())
  2075. {
  2076. isWorse = true;
  2077. }
  2078. else if ((prevMethodMatchEntry->mMethodDef != NULL) && (prevMethodMatchEntry->mMethodDef->mParams.size() < (int) mArguments.size()))
  2079. {
  2080. isBetter = true;
  2081. }
  2082. }
  2083. }
  2084. }
  2085. }
  2086. // Too many arguments (not all incoming arguments processed)
  2087. if (argIdx < (int)mArguments.size())
  2088. {
  2089. if (!methodInstance->IsVarArgs())
  2090. goto NoMatch;
  2091. }
  2092. if (mCheckReturnType != NULL)
  2093. {
  2094. auto returnType = methodInstance->mReturnType;
  2095. if (returnType->IsVar())
  2096. {
  2097. // If we allowed this then it would allow too many matches (and allow conversion to any type during CastToValue)
  2098. goto NoMatch;
  2099. }
  2100. bool doFullTypeResolve = false;
  2101. if (returnType->IsUnspecializedTypeVariation())
  2102. {
  2103. returnType = typeUnspecMethodInstance->mReturnType;
  2104. doFullTypeResolve = true;
  2105. }
  2106. if ((genericArgumentsSubstitute != NULL) && (returnType->IsUnspecializedType()))
  2107. doFullTypeResolve = true;
  2108. if (doFullTypeResolve)
  2109. {
  2110. auto resolvedType = mModule->ResolveGenericType(returnType, typeGenericArguments, genericArgumentsSubstitute, mModule->mCurTypeInstance, false);
  2111. if (resolvedType == NULL)
  2112. goto NoMatch;
  2113. returnType = resolvedType;
  2114. }
  2115. returnType = mModule->ResolveSelfType(returnType, typeInstance);
  2116. BfCastFlags castFlags = ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp) != 0) ? (BfCastFlags)(BfCastFlags_NoConversionOperator | BfCastFlags_NoInterfaceImpl) : BfCastFlags_None;
  2117. if ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp_Explicit) != 0)
  2118. castFlags = (BfCastFlags)(castFlags | BfCastFlags_Explicit);
  2119. if (!mModule->CanCast(mModule->GetFakeTypedValue(returnType), mCheckReturnType, castFlags))
  2120. goto NoMatch;
  2121. }
  2122. if ((genericArgumentsSubstitute != NULL) && (genericArgumentsSubstitute->size() != 0))
  2123. {
  2124. for (int checkGenericIdx = uniqueGenericStartIdx; checkGenericIdx < (int)genericArgumentsSubstitute->size(); checkGenericIdx++)
  2125. {
  2126. auto& genericParams = methodInstance->mMethodInfoEx->mGenericParams;
  2127. auto genericArg = (*genericArgumentsSubstitute)[checkGenericIdx];
  2128. if (genericArg == NULL)
  2129. {
  2130. if (allowEmptyGenericSet.Contains(checkGenericIdx))
  2131. continue;
  2132. goto NoMatch;
  2133. }
  2134. if (genericArg == NULL)
  2135. goto NoMatch;
  2136. if (!mModule->CheckGenericConstraints(BfGenericParamSource(methodInstance), genericArg, NULL, genericParams[checkGenericIdx], genericArgumentsSubstitute, NULL))
  2137. goto NoMatch;
  2138. }
  2139. }
  2140. for (int externConstraintIdx = 0; externConstraintIdx < (int)checkMethod->mExternalConstraints.size(); externConstraintIdx++)
  2141. {
  2142. auto genericParam = methodInstance->mMethodInfoEx->mGenericParams[checkMethod->mGenericParams.size() + externConstraintIdx];
  2143. BF_ASSERT(genericParam->mExternType != NULL);
  2144. auto externType = genericParam->mExternType;
  2145. BfTypeVector* externGenericArgumentsSubstitute = genericArgumentsSubstitute;
  2146. if (externType->IsVar())
  2147. {
  2148. auto& externConstraint = checkMethod->mExternalConstraints[externConstraintIdx];
  2149. if (externConstraint.mTypeRef != NULL)
  2150. {
  2151. externType = mModule->ResolveGenericMethodTypeRef(externConstraint.mTypeRef, methodInstance, genericParam, genericArgumentsSubstitute);
  2152. if (externType == NULL)
  2153. goto NoMatch;
  2154. }
  2155. }
  2156. if (externType->IsGenericParam())
  2157. {
  2158. auto genericParamType = (BfGenericParamType*)externType;
  2159. if (genericParamType->mGenericParamKind == BfGenericParamKind_Method)
  2160. {
  2161. if (genericArgumentsSubstitute != NULL)
  2162. {
  2163. auto genericArg = (*genericArgumentsSubstitute)[genericParamType->mGenericParamIdx];
  2164. if (genericArg == NULL)
  2165. {
  2166. if (allowEmptyGenericSet.Contains(genericParamType->mGenericParamIdx))
  2167. continue;
  2168. goto NoMatch;
  2169. }
  2170. externType = genericArg;
  2171. }
  2172. }
  2173. }
  2174. if (!mModule->CheckGenericConstraints(BfGenericParamSource(methodInstance), externType, NULL, genericParam, externGenericArgumentsSubstitute, NULL))
  2175. goto NoMatch;
  2176. }
  2177. // if (auto methodDecl = BfNodeDynCast<BfMethodDeclaration>(checkMethod->mMethodDeclaration))
  2178. // {
  2179. // if ((methodDecl->mGenericConstraintsDeclaration != NULL) && (methodDecl->mGenericConstraintsDeclaration->mHasExpressions))
  2180. // {
  2181. // for (auto genericConstraint : methodDecl->mGenericConstraintsDeclaration->mGenericConstraints)
  2182. // {
  2183. // if (auto genericConstraintExpr = BfNodeDynCast<BfGenericConstraintExpression>(genericConstraint))
  2184. // {
  2185. // if (genericConstraintExpr->mExpression == NULL)
  2186. // continue;
  2187. // BfConstResolver constResolver(mModule);
  2188. // constResolver.mExpectingType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  2189. // constResolver.Resolve(genericConstraintExpr->mExpression, constResolver.mExpectingType);
  2190. // }
  2191. // }
  2192. // }
  2193. // }
  2194. // Method is applicable, check to see which method is better
  2195. if (mBestMethodDef != NULL)
  2196. {
  2197. bool isBetter = false;
  2198. bool isWorse = false;
  2199. BfMethodInstance* prevMethodInstance = mModule->GetRawMethodInstance(mBestMethodTypeInstance, mBestMethodDef);
  2200. bool allowSpecializeFail = mModule->mCurTypeInstance->IsUnspecializedType();
  2201. if (mModule->mCurMethodInstance != NULL)
  2202. allowSpecializeFail = mModule->mCurMethodInstance->mIsUnspecialized;
  2203. CompareMethods(prevMethodInstance, &mBestMethodGenericArguments, methodInstance, genericArgumentsSubstitute, &isBetter, &isWorse, allowSpecializeFail);
  2204. // If we had both a 'better' and 'worse', that's ambiguous because the methods are each better in different ways (not allowed)
  2205. // And if neither better nor worse then they are equally good, which is not allowed either
  2206. if (((!isBetter) && (!isWorse)) || ((isBetter) && (isWorse)))
  2207. {
  2208. if (!mHasVarArguments)
  2209. {
  2210. // If we are ambiguous based on a subset of an extern 'var' constraint then don't throw an error
  2211. auto _CheckMethodInfo = [&](BfMethodInstance* checkMethodInstance)
  2212. {
  2213. if (checkMethodInstance->mMethodInfoEx == NULL)
  2214. return;
  2215. for (auto genericParam : checkMethodInstance->mMethodInfoEx->mGenericParams)
  2216. {
  2217. if ((genericParam->mExternType == NULL) || (!genericParam->mExternType->IsGenericParam()))
  2218. continue;
  2219. auto genericParamType = (BfGenericParamType*)genericParam->mExternType;
  2220. if (genericParamType->mGenericParamKind != BfGenericParamKind_Type)
  2221. continue;
  2222. auto externGenericParam = mModule->GetGenericParamInstance(genericParamType);
  2223. if ((externGenericParam->mGenericParamFlags & BfGenericParamFlag_Var) != 0)
  2224. mHasVarArguments = true;
  2225. }
  2226. };
  2227. _CheckMethodInfo(methodInstance);
  2228. _CheckMethodInfo(prevMethodInstance);
  2229. }
  2230. if (mHasVarArguments)
  2231. {
  2232. if (methodInstance->mReturnType != prevMethodInstance->mReturnType)
  2233. mHadVarConflictingReturnType = true;
  2234. }
  2235. else
  2236. {
  2237. BfAmbiguousEntry ambiguousEntry;
  2238. ambiguousEntry.mMethodInstance = methodInstance;
  2239. if (genericArgumentsSubstitute != NULL)
  2240. ambiguousEntry.mBestMethodGenericArguments = *genericArgumentsSubstitute;
  2241. if (methodInstance->mMethodDef->mGenericParams.size() != 0)
  2242. {
  2243. BF_ASSERT(!ambiguousEntry.mBestMethodGenericArguments.empty());
  2244. }
  2245. mAmbiguousEntries.push_back(ambiguousEntry);
  2246. goto Done;
  2247. }
  2248. }
  2249. if (!isBetter)
  2250. goto Done;
  2251. }
  2252. if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo))
  2253. {
  2254. auto methodMatchInfo = autoComplete->mMethodMatchInfo;
  2255. // Try to persist with previous partial match, if we have one - this keeps us from locking onto
  2256. // an incorrect method just because it had the current number of params that we've typed so far
  2257. if (methodMatchInfo->mPrevBestIdx == -1)
  2258. {
  2259. methodMatchInfo->mHadExactMatch = true;
  2260. methodMatchInfo->mBestIdx = (int) methodMatchInfo->mInstanceList.size() - 1;
  2261. }
  2262. }
  2263. mAmbiguousEntries.Clear();
  2264. hadMatch = true;
  2265. mBestMethodDef = checkMethod;
  2266. mBestRawMethodInstance = methodInstance;
  2267. for (auto& arg : mArguments)
  2268. arg.mBestBoundType = arg.mTypedValue.mType;
  2269. NoMatch:
  2270. if (!hadMatch)
  2271. {
  2272. if (mBestMethodDef != NULL)
  2273. return false;
  2274. if (checkMethod->mMethodType == BfMethodType_Extension)
  2275. {
  2276. auto thisParam = methodInstance->GetParamType(0);
  2277. auto resolveThisParam = mModule->ResolveGenericType(thisParam, NULL, &mCheckMethodGenericArguments, mModule->mCurTypeInstance);
  2278. if (resolveThisParam == NULL)
  2279. return false;
  2280. if (!mModule->CanCast(mTarget, resolveThisParam,
  2281. ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp) != 0) ? (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_NoConversionOperator) : BfCastFlags_Explicit))
  2282. return false;
  2283. }
  2284. if (mBackupMethodDef != NULL)
  2285. {
  2286. int prevParamDiff = (int)mBackupMethodDef->GetExplicitParamCount() - (int)mArguments.size();
  2287. int paramDiff = (int)checkMethod->GetExplicitParamCount() - (int)mArguments.size();
  2288. if ((prevParamDiff < 0) && (prevParamDiff > paramDiff))
  2289. return false;
  2290. if ((prevParamDiff >= 0) && (paramDiff < 0))
  2291. return false;
  2292. if (argMatchCount < mBackupArgMatchCount)
  2293. return false;
  2294. else if (argMatchCount == mBackupArgMatchCount)
  2295. {
  2296. if (curMatchKind < mBackupMatchKind)
  2297. return false;
  2298. // We search from the most specific type, so don't prefer a less specific type
  2299. if (mBestMethodTypeInstance != typeInstance)
  2300. return false;
  2301. }
  2302. }
  2303. if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo))
  2304. {
  2305. auto methodMatchInfo = autoComplete->mMethodMatchInfo;
  2306. if ((methodMatchInfo->mPrevBestIdx == -1) && (!methodMatchInfo->mHadExactMatch))
  2307. {
  2308. methodMatchInfo->mBestIdx = (int)methodMatchInfo->mInstanceList.size() - 1;
  2309. }
  2310. }
  2311. mBackupMatchKind = curMatchKind;
  2312. mBackupMethodDef = checkMethod;
  2313. mBackupArgMatchCount = argMatchCount;
  2314. // Lie temporarily to store at least one candidate (but mBestMethodDef is still NULL)
  2315. hadMatch = true;
  2316. }
  2317. if (hadMatch)
  2318. {
  2319. mBestMethodTypeInstance = typeInstance;
  2320. if (genericArgumentsSubstitute != &mBestMethodGenericArguments)
  2321. {
  2322. if (genericArgumentsSubstitute != NULL)
  2323. {
  2324. for (auto& genericArg : *genericArgumentsSubstitute)
  2325. genericArg = mModule->FixIntUnknown(genericArg);
  2326. mBestMethodGenericArguments = *genericArgumentsSubstitute;
  2327. // #ifdef _DEBUG
  2328. // for (auto arg : mBestMethodGenericArguments)
  2329. // BF_ASSERT((arg == NULL) || (!arg->IsVar()));
  2330. // #endif
  2331. }
  2332. else
  2333. mBestMethodGenericArguments.clear();
  2334. }
  2335. }
  2336. Done:
  2337. if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo))
  2338. {
  2339. auto methodMatchInfo = autoComplete->mMethodMatchInfo;
  2340. if (!methodMatchInfo->mInstanceList.IsEmpty())
  2341. {
  2342. auto& matchInstance = methodMatchInfo->mInstanceList[methodMatchInfo->mInstanceList.size() - 1];
  2343. matchInstance.mArgMatchCount = argMatchCount;
  2344. matchInstance.mIsMatch = hadMatch;
  2345. if (genericArgumentsSubstitute != NULL)
  2346. matchInstance.mGenericArguments = *genericArgumentsSubstitute;
  2347. }
  2348. }
  2349. return mBestMethodDef == checkMethod;
  2350. }
  2351. void BfMethodMatcher::FlushAmbiguityError(bool useWarning)
  2352. {
  2353. if (!mAmbiguousEntries.empty())
  2354. {
  2355. if (mModule->PreFail())
  2356. {
  2357. BfError* error;
  2358. if (!mMethodName.empty())
  2359. {
  2360. if (useWarning)
  2361. error = mModule->Warn(0, StrFormat("Ambiguous method call for '%s'", mMethodName.c_str()), mTargetSrc);
  2362. else
  2363. error = mModule->Fail(StrFormat("Ambiguous method call for '%s'", mMethodName.c_str()), mTargetSrc);
  2364. }
  2365. else
  2366. {
  2367. if (useWarning)
  2368. error = mModule->Warn(0, "Ambiguous method call", mTargetSrc);
  2369. else
  2370. error = mModule->Fail("Ambiguous method call", mTargetSrc);
  2371. }
  2372. if (error != NULL)
  2373. {
  2374. BfMethodInstance* bestMethodInstance = mModule->GetUnspecializedMethodInstance(mBestRawMethodInstance, true);
  2375. BfTypeVector* typeGenericArguments = NULL;
  2376. if (mBestMethodTypeInstance->mGenericTypeInfo != NULL)
  2377. typeGenericArguments = &mBestMethodTypeInstance->mGenericTypeInfo->mTypeGenericArguments;
  2378. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' is a candidate", mModule->MethodToString(bestMethodInstance, BfMethodNameFlag_ResolveGenericParamNames,
  2379. typeGenericArguments, mBestMethodGenericArguments.empty() ? NULL : &mBestMethodGenericArguments).c_str()),
  2380. bestMethodInstance->mMethodDef->GetRefNode());
  2381. for (auto& ambiguousEntry : mAmbiguousEntries)
  2382. {
  2383. auto typeInstance = ambiguousEntry.mMethodInstance->GetOwner();
  2384. auto unspecTypeMethodInstance = mModule->GetUnspecializedMethodInstance(ambiguousEntry.mMethodInstance, true);
  2385. BfTypeVector* typeGenericArguments = NULL;
  2386. if (typeInstance->mGenericTypeInfo != NULL)
  2387. typeGenericArguments = &typeInstance->mGenericTypeInfo->mTypeGenericArguments;
  2388. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' is a candidate", mModule->MethodToString(unspecTypeMethodInstance, BfMethodNameFlag_ResolveGenericParamNames,
  2389. typeGenericArguments, ambiguousEntry.mBestMethodGenericArguments.empty() ? NULL : &ambiguousEntry.mBestMethodGenericArguments).c_str()),
  2390. ambiguousEntry.mMethodInstance->mMethodDef->GetRefNode());
  2391. }
  2392. }
  2393. }
  2394. mAmbiguousEntries.Clear();
  2395. }
  2396. }
  2397. bool BfMethodMatcher::IsType(BfTypedValue& typedVal, BfType* type)
  2398. {
  2399. if (typedVal.mType == type)
  2400. return true;
  2401. if (!typedVal)
  2402. return false;
  2403. if (!typedVal.mType->IsPrimitiveType())
  2404. return false;
  2405. if (!type->IsPrimitiveType())
  2406. return false;
  2407. auto fromPrimType = typedVal.mType->ToPrimitiveType();
  2408. if ((fromPrimType->mTypeDef->mTypeCode != BfTypeCode_IntUnknown) &&
  2409. (fromPrimType->mTypeDef->mTypeCode != BfTypeCode_UIntUnknown))
  2410. return false;
  2411. auto constant = mModule->mBfIRBuilder->GetConstant(typedVal.mValue);
  2412. if (constant == NULL)
  2413. return false;
  2414. auto toPrimType = type->ToPrimitiveType();
  2415. if (!mModule->mBfIRBuilder->IsInt(toPrimType->mTypeDef->mTypeCode))
  2416. return false;
  2417. if (type->mSize == 8)
  2418. return false;
  2419. int64 minVal = -(1LL << (8 * type->mSize - 1));
  2420. int64 maxVal = (1LL << (8 * type->mSize - 1)) - 1;
  2421. if ((constant->mInt64 >= minVal) && (constant->mInt64 <= maxVal))
  2422. return true;
  2423. return false;
  2424. }
  2425. // This method checks all base classes before checking interfaces. Is that correct?
  2426. bool BfMethodMatcher::CheckType(BfTypeInstance* typeInstance, BfTypedValue target, bool isFailurePass, bool forceOuterCheck)
  2427. {
  2428. BfMethodDef* prevBestMethodDef = mBestMethodDef;
  2429. auto curTypeInst = typeInstance;
  2430. auto curTypeDef = typeInstance->mTypeDef;
  2431. int checkInterfaceIdx = 0;
  2432. bool targetIsBase = target.IsBase();
  2433. bool checkExtensionBase = false;
  2434. if (targetIsBase)
  2435. {
  2436. if ((curTypeInst == mModule->mCurTypeInstance) && (curTypeInst->mTypeDef->mIsCombinedPartial))
  2437. {
  2438. checkExtensionBase = true;
  2439. }
  2440. else
  2441. {
  2442. curTypeInst = curTypeInst->mBaseType;
  2443. }
  2444. }
  2445. BfTypeInstance* targetTypeInstance = NULL;
  2446. if (target.mType != NULL)
  2447. targetTypeInstance = target.mType->ToTypeInstance();
  2448. while (true)
  2449. {
  2450. bool doSearch = true;
  2451. if ((mMethodType == BfMethodType_Extension) && (!curTypeDef->mHasExtensionMethods))
  2452. doSearch = false;
  2453. BfMethodDef* nextMethodDef = NULL;
  2454. if (doSearch)
  2455. {
  2456. curTypeDef->PopulateMemberSets();
  2457. BfMemberSetEntry* entry;
  2458. if (curTypeDef->mMethodSet.TryGetWith(mMethodName, &entry))
  2459. nextMethodDef = (BfMethodDef*)entry->mMemberDef;
  2460. }
  2461. BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None;
  2462. if (target)
  2463. {
  2464. if (mBypassVirtual)
  2465. {
  2466. // Not an "instance lookup"
  2467. }
  2468. else
  2469. {
  2470. protectionCheckFlags = (BfProtectionCheckFlags)(protectionCheckFlags | BfProtectionCheckFlag_InstanceLookup);
  2471. }
  2472. }
  2473. while (nextMethodDef != NULL)
  2474. {
  2475. bool allowExplicitInterface = curTypeInst->IsInterface() && mBypassVirtual;
  2476. auto activeTypeDef = mModule->GetActiveTypeDef();
  2477. auto visibleProjectSet = mModule->GetVisibleProjectSet();
  2478. bool isDelegate = typeInstance->IsDelegate();
  2479. auto checkMethod = nextMethodDef;
  2480. nextMethodDef = nextMethodDef->mNextWithSameName;
  2481. if (mModule->mContext->mResolvingVarField)
  2482. {
  2483. bool isResolvingVarField = false;
  2484. auto checkTypeState = mModule->mContext->mCurTypeState;
  2485. while (checkTypeState != NULL)
  2486. {
  2487. if ((checkTypeState->mResolveKind == BfTypeState::ResolveKind_ResolvingVarType) &&
  2488. (checkTypeState->mType == typeInstance))
  2489. isResolvingVarField = true;
  2490. checkTypeState = checkTypeState->mPrevState;
  2491. }
  2492. if (isResolvingVarField)
  2493. {
  2494. BF_ASSERT(mModule->mBfIRBuilder->mIgnoreWrites);
  2495. // Don't even consider - we can't do method calls on ourselves when we are resolving var fields, because
  2496. // we are not allowed to generate methods when our field types are unknown. We may fix this in the future,
  2497. // but currently it breaks out expected order of operations. One issue is that our call signatures change
  2498. // depending on whether we are valueless or splattable, which depend on underlying type information
  2499. break;
  2500. }
  2501. }
  2502. if ((checkExtensionBase) && (curTypeInst == mModule->mCurTypeInstance))
  2503. {
  2504. // Accept either a method in the same project but that's the root definition, OR a method that's in a dependent project
  2505. bool accept = false;
  2506. if (activeTypeDef->mProject == checkMethod->mDeclaringType->mProject)
  2507. accept = (activeTypeDef->IsExtension()) && (!checkMethod->mDeclaringType->IsExtension());
  2508. else
  2509. accept = activeTypeDef->mProject->ContainsReference(checkMethod->mDeclaringType->mProject);
  2510. if (!accept)
  2511. continue;
  2512. }
  2513. if ((!allowExplicitInterface) && (checkMethod->mExplicitInterface != NULL) && (mInterfaceMethodInstance == NULL))
  2514. {
  2515. continue;
  2516. }
  2517. if (checkMethod->mMethodType != mMethodType)
  2518. continue;
  2519. // if (checkMethod->mName != mMethodName)
  2520. // continue;
  2521. if ((checkMethod->mDeclaringType->IsExtension()) && (mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) &&
  2522. (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mNoExtensionAttributeTypeDef)))
  2523. {
  2524. mModule->mAttributeState->mUsed = true;
  2525. continue;
  2526. }
  2527. if (!isDelegate)
  2528. {
  2529. if ((!curTypeInst->IsTypeMemberIncluded(checkMethod->mDeclaringType, activeTypeDef, mModule)) ||
  2530. (!curTypeInst->IsTypeMemberAccessible(checkMethod->mDeclaringType, visibleProjectSet)))
  2531. continue;
  2532. }
  2533. MatchFailKind matchFailKind = MatchFailKind_None;
  2534. if (!mModule->CheckProtection(protectionCheckFlags, curTypeInst, checkMethod->mDeclaringType->mProject, checkMethod->mProtection, typeInstance))
  2535. {
  2536. if ((mBypassVirtual) &&
  2537. ((checkMethod->mProtection == BfProtection_Protected) || (checkMethod->mProtection == BfProtection_ProtectedInternal)) &&
  2538. (mModule->TypeIsSubTypeOf(mModule->mCurTypeInstance, typeInstance)))
  2539. {
  2540. // Allow explicit 'base' call
  2541. }
  2542. else
  2543. {
  2544. if (!isFailurePass)
  2545. continue;
  2546. matchFailKind = MatchFailKind_Protection;
  2547. }
  2548. }
  2549. if (mCheckedKind != checkMethod->mCheckedKind)
  2550. {
  2551. bool passes = true;
  2552. if (mCheckedKind != BfCheckedKind_NotSet)
  2553. {
  2554. passes = false;
  2555. }
  2556. else
  2557. {
  2558. auto defaultCheckedKind = mModule->GetDefaultCheckedKind();
  2559. if (defaultCheckedKind != checkMethod->mCheckedKind)
  2560. passes = false;
  2561. }
  2562. if (!passes)
  2563. {
  2564. if (!isFailurePass)
  2565. continue;
  2566. matchFailKind = MatchFailKind_CheckedMismatch;
  2567. }
  2568. }
  2569. CheckMethod(targetTypeInstance, curTypeInst, checkMethod, isFailurePass);
  2570. if ((isFailurePass) &&
  2571. ((mBestMethodDef == checkMethod) || (mBackupMethodDef == checkMethod)))
  2572. mMatchFailKind = matchFailKind;
  2573. }
  2574. if ((mBestMethodDef != NULL) && (mMethodType != BfMethodType_Extension))
  2575. {
  2576. if ((mUsingLists != NULL) && (mUsingLists->mSize != 0))
  2577. mUsingLists->Clear();
  2578. if (mAutoFlushAmbiguityErrors)
  2579. FlushAmbiguityError();
  2580. return true;
  2581. }
  2582. if ((mUsingLists != NULL) && (curTypeInst->mTypeDef->mHasUsingFields))
  2583. mModule->PopulateUsingFieldData(curTypeInst);
  2584. if (mUsingLists != NULL)
  2585. {
  2586. auto _CheckUsingData = [&](BfUsingFieldData* usingData)
  2587. {
  2588. BfUsingFieldData::Entry* entry = NULL;
  2589. if (!usingData->mMethods.TryGetValue(mMethodName, &entry))
  2590. return;
  2591. for (int listIdx = 0; listIdx < entry->mLookups.mSize; listIdx++)
  2592. {
  2593. bool passesProtection = true;
  2594. auto& entryList = entry->mLookups[listIdx];
  2595. for (int entryIdx = 0; entryIdx < entryList.mSize; entryIdx++)
  2596. {
  2597. auto& entry = entryList[entryIdx];
  2598. BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None;
  2599. if (!mModule->CheckProtection(protectionCheckFlags, entry.mTypeInstance, entry.GetDeclaringType(mModule)->mProject,
  2600. (entryIdx < entryList.mSize - 1) ? entry.GetUsingProtection() : entry.GetProtection(), curTypeInst))
  2601. {
  2602. passesProtection = false;
  2603. break;
  2604. }
  2605. }
  2606. if (!passesProtection)
  2607. continue;
  2608. auto& entry = entryList.back();
  2609. BF_ASSERT(entry.mKind == BfUsingFieldData::MemberRef::Kind_Method);
  2610. auto methodDef = entry.mTypeInstance->mTypeDef->mMethods[entry.mIdx];
  2611. CheckMethod(curTypeInst, entry.mTypeInstance, methodDef, isFailurePass);
  2612. if ((mBestMethodDef != methodDef) && (mBackupMethodDef != methodDef))
  2613. {
  2614. bool foundAmbiguous = false;
  2615. for (int checkIdx = 0; checkIdx < mAmbiguousEntries.mSize; checkIdx++)
  2616. {
  2617. if (mAmbiguousEntries[checkIdx].mMethodInstance->mMethodDef == methodDef)
  2618. {
  2619. mAmbiguousEntries.RemoveAt(checkIdx);
  2620. foundAmbiguous = true;
  2621. break;
  2622. }
  2623. }
  2624. if (!foundAmbiguous)
  2625. continue;
  2626. }
  2627. if (mUsingLists->mSize == 0)
  2628. {
  2629. mUsingLists->Add(&entryList);
  2630. }
  2631. else
  2632. {
  2633. if (entryList.mSize < (*mUsingLists)[0]->mSize)
  2634. {
  2635. // New is shorter
  2636. mUsingLists->Clear();
  2637. mUsingLists->Add(&entryList);
  2638. }
  2639. else if (entryList.mSize > (*mUsingLists)[0]->mSize)
  2640. {
  2641. // Ignore longer
  2642. }
  2643. else
  2644. {
  2645. mUsingLists->Add(&entryList);
  2646. }
  2647. }
  2648. }
  2649. };
  2650. if ((curTypeInst->mTypeInfoEx != NULL) && (curTypeInst->mTypeInfoEx->mUsingFieldData != NULL))
  2651. _CheckUsingData(curTypeInst->mTypeInfoEx->mUsingFieldData);
  2652. if (mBestMethodDef != NULL)
  2653. break;
  2654. }
  2655. auto baseType = curTypeInst->mBaseType;
  2656. if (baseType == NULL)
  2657. {
  2658. //TODO: Why were we doing the interface checking?
  2659. if ((curTypeInst->IsInterface()) && (curTypeInst == target.mType))
  2660. {
  2661. // When we are directly calling on interfaces rather than indirectly matching through binding
  2662. baseType = mModule->mContext->mBfObjectType;
  2663. }
  2664. else if ((curTypeInst != mModule->mContext->mBfObjectType) && (!curTypeInst->IsInterface()))
  2665. {
  2666. // This can happen for structs
  2667. baseType = mModule->mContext->mBfObjectType;
  2668. }
  2669. else if ((typeInstance->IsInterface()) && (checkInterfaceIdx < (int)typeInstance->mInterfaces.size()))
  2670. {
  2671. baseType = typeInstance->mInterfaces[checkInterfaceIdx].mInterfaceType;
  2672. checkInterfaceIdx++;
  2673. }
  2674. else
  2675. {
  2676. break;
  2677. }
  2678. }
  2679. curTypeDef = baseType->mTypeDef;
  2680. curTypeInst = baseType;
  2681. if ((isFailurePass) && (mBackupMethodDef != NULL))
  2682. break;
  2683. }
  2684. if (mBestMethodDef == NULL)
  2685. {
  2686. // FAILED, but select the first method which will fire an actual error on param type matching
  2687. mBestMethodDef = mBackupMethodDef;
  2688. }
  2689. if (((mBestMethodDef == NULL) && (!target) && (mAllowImplicitThis)) ||
  2690. (forceOuterCheck))
  2691. {
  2692. // No explicit target - maybe this was a static call in the outer type?
  2693. auto outerType = mModule->GetOuterType(typeInstance);
  2694. if (outerType != NULL)
  2695. CheckOuterTypeStaticMethods(outerType, isFailurePass);
  2696. }
  2697. if (mAutoFlushAmbiguityErrors)
  2698. FlushAmbiguityError();
  2699. return mBestMethodDef != prevBestMethodDef;
  2700. }
  2701. void BfMethodMatcher::TryDevirtualizeCall(BfTypedValue target, BfTypedValue* origTarget, BfTypedValue* staticResult)
  2702. {
  2703. if ((mBestMethodDef == NULL) || (target.mType == NULL))
  2704. return;
  2705. if ((mModule->mCompiler->IsAutocomplete()) || (mModule->mContext->mResolvingVarField))
  2706. return;
  2707. if ((mModule->mBfIRBuilder->mIgnoreWrites) && (!mBestMethodDef->mIsConcrete) && (!mBestMethodTypeInstance->IsInterface()))
  2708. return;
  2709. if (mBestMethodTypeInstance->IsInterface())
  2710. {
  2711. mModule->PopulateType(mBestMethodTypeInstance, BfPopulateType_DataAndMethods);
  2712. auto activeTypeDef = mModule->GetActiveTypeDef();
  2713. // Statically map this call
  2714. auto checkType = target.mType;
  2715. if (checkType->IsPointer())
  2716. checkType = ((BfPointerType*)checkType)->mElementType;
  2717. if (checkType->IsWrappableType())
  2718. checkType = mModule->GetWrappedStructType(checkType);
  2719. if ((checkType != NULL) && (checkType->IsTypeInstance()) && (!checkType->IsInterface()))
  2720. {
  2721. BfTypeInterfaceEntry* bestIFaceEntry = NULL;
  2722. auto checkTypeInst = checkType->ToTypeInstance();
  2723. if (mBestMethodTypeInstance->IsInstanceOf(mModule->mCompiler->mIHashableTypeDef))
  2724. {
  2725. if ((origTarget != NULL) && (origTarget->mType->IsPointer()) && (staticResult != NULL))
  2726. {
  2727. BfTypedValue ptrVal = mModule->LoadValue(*origTarget);
  2728. *staticResult = BfTypedValue(mModule->mBfIRBuilder->CreatePtrToInt(ptrVal.mValue, BfTypeCode_IntPtr), mModule->GetPrimitiveType(BfTypeCode_IntPtr));
  2729. return;
  2730. }
  2731. }
  2732. while (checkTypeInst != NULL)
  2733. {
  2734. mModule->PopulateType(checkTypeInst, BfPopulateType_DataAndMethods);
  2735. if (checkTypeInst->mDefineState >= BfTypeDefineState_DefinedAndMethodsSlotted)
  2736. {
  2737. for (auto&& iface : checkTypeInst->mInterfaces)
  2738. {
  2739. //TODO: Why did we have this check? This caused Dictionary to not be able to devirtualize
  2740. // calls to TKey GetHashCode when TKey was from a user's project...
  2741. /*if (!checkTypeInst->IsTypeMemberAccessible(iface.mDeclaringType, activeTypeDef))
  2742. continue;*/
  2743. if (iface.mInterfaceType == mBestMethodTypeInstance)
  2744. {
  2745. if (bestIFaceEntry == NULL)
  2746. {
  2747. bestIFaceEntry = &iface;
  2748. continue;
  2749. }
  2750. bool isBetter;
  2751. bool isWorse;
  2752. mModule->CompareDeclTypes(NULL, iface.mDeclaringType, bestIFaceEntry->mDeclaringType, isBetter, isWorse);
  2753. if (isBetter == isWorse)
  2754. {
  2755. // Failed
  2756. }
  2757. else
  2758. {
  2759. if (isBetter)
  2760. bestIFaceEntry = &iface;
  2761. }
  2762. }
  2763. }
  2764. }
  2765. if (bestIFaceEntry != NULL)
  2766. break;
  2767. checkTypeInst = checkTypeInst->mBaseType;
  2768. if ((checkTypeInst == NULL) && (checkType->HasWrappedRepresentation()))
  2769. {
  2770. auto underlyingType = checkType->GetUnderlyingType();
  2771. if ((underlyingType != NULL) && (underlyingType->IsWrappableType()))
  2772. checkTypeInst = mModule->GetWrappedStructType(underlyingType);
  2773. if (checkTypeInst == checkType)
  2774. break;
  2775. }
  2776. }
  2777. if (bestIFaceEntry != NULL)
  2778. {
  2779. auto ifaceMethodEntry = checkTypeInst->mInterfaceMethodTable[bestIFaceEntry->mStartInterfaceTableIdx + mBestMethodDef->mIdx];
  2780. BfMethodInstance* bestMethodInstance = ifaceMethodEntry.mMethodRef;
  2781. if (bestMethodInstance != NULL)
  2782. {
  2783. bool isMissingArg = false;
  2784. for (auto genericArg : mBestMethodGenericArguments)
  2785. {
  2786. if (genericArg == NULL)
  2787. isMissingArg = true;
  2788. }
  2789. if (!isMissingArg)
  2790. {
  2791. // Assert error state?
  2792. mBestMethodTypeInstance = ifaceMethodEntry.mMethodRef.mTypeInstance;
  2793. mBestMethodDef = bestMethodInstance->mMethodDef;
  2794. mBestMethodInstance = mModule->GetMethodInstance(mBestMethodTypeInstance, bestMethodInstance->mMethodDef, mBestMethodGenericArguments,
  2795. bestMethodInstance->mIsForeignMethodDef ? BfGetMethodInstanceFlag_ForeignMethodDef : BfGetMethodInstanceFlag_None,
  2796. bestMethodInstance->GetForeignType());
  2797. }
  2798. }
  2799. else
  2800. {
  2801. // Failed
  2802. mFakeConcreteTarget = true;
  2803. }
  2804. }
  2805. }
  2806. }
  2807. if ((target.mType->IsValueType()) && (mBestMethodTypeInstance->IsObject()) && (mBestMethodDef->mIsVirtual))
  2808. {
  2809. auto structType = target.mType->ToTypeInstance();
  2810. if (structType == NULL)
  2811. {
  2812. mModule->InternalError("Invalid type in TryDevirtualizeCall");
  2813. return;
  2814. }
  2815. auto virtualMethodInstance = mModule->GetMethodInstance(mBestMethodTypeInstance, mBestMethodDef, BfTypeVector());
  2816. BF_ASSERT(virtualMethodInstance.mMethodInstance->mVirtualTableIdx != -1);
  2817. BfTypeInstance* boxedType;
  2818. if (structType->HasOverrideMethods())
  2819. {
  2820. // We don't actually need this boxed type, so just resolve it unreified
  2821. auto useModule = mModule->mContext->mUnreifiedModule;
  2822. boxedType = useModule->CreateBoxedType(target.mType);
  2823. useModule->PopulateType(boxedType, BfPopulateType_DataAndMethods);
  2824. useModule->AddDependency(boxedType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_WeakReference);
  2825. }
  2826. else
  2827. {
  2828. boxedType = mModule->mContext->mBfObjectType;
  2829. }
  2830. auto methodRef = boxedType->mVirtualMethodTable[virtualMethodInstance.mMethodInstance->mVirtualTableIdx];
  2831. if (methodRef.mImplementingMethod.mTypeInstance->IsBoxed())
  2832. {
  2833. auto useModule = mModule->mContext->mUnreifiedModule;
  2834. auto boxedMethodInstance = useModule->ReferenceExternalMethodInstance(methodRef.mImplementingMethod);
  2835. BfBoxedType* vBoxedType = (BfBoxedType*)methodRef.mImplementingMethod.mTypeInstance;
  2836. mBestMethodTypeInstance = vBoxedType->mElementType->ToTypeInstance();
  2837. mBestMethodInstance = mModule->GetMethodInstance(mBestMethodTypeInstance, boxedMethodInstance.mMethodInstance->mMethodDef, BfTypeVector());
  2838. mBestMethodDef = mBestMethodInstance.mMethodInstance->mMethodDef;
  2839. }
  2840. else
  2841. {
  2842. mBestMethodTypeInstance = methodRef.mImplementingMethod.mTypeInstance;
  2843. mBestMethodInstance = mModule->ReferenceExternalMethodInstance(methodRef.mImplementingMethod);
  2844. mBestMethodDef = mBestMethodInstance.mMethodInstance->mMethodDef;
  2845. }
  2846. mBypassVirtual = true;
  2847. }
  2848. }
  2849. bool BfMethodMatcher::HasVarGenerics()
  2850. {
  2851. for (auto genericArg : mBestMethodGenericArguments)
  2852. if (genericArg->IsVar())
  2853. return true;
  2854. for (auto genericArg : mExplicitMethodGenericArguments)
  2855. if (genericArg->IsVar())
  2856. return true;
  2857. return false;
  2858. }
  2859. void BfMethodMatcher::CheckOuterTypeStaticMethods(BfTypeInstance* typeInstance, bool isFailurePass)
  2860. {
  2861. bool allowPrivate = true;
  2862. bool allowProtected = true;
  2863. auto curTypeInst = typeInstance;
  2864. auto curTypeDef = typeInstance->mTypeDef;
  2865. while (true)
  2866. {
  2867. curTypeDef->PopulateMemberSets();
  2868. BfMethodDef* nextMethodDef = NULL;
  2869. BfMemberSetEntry* entry;
  2870. if (curTypeDef->mMethodSet.TryGetWith(mMethodName, &entry))
  2871. nextMethodDef = (BfMethodDef*)entry->mMemberDef;
  2872. while (nextMethodDef != NULL)
  2873. {
  2874. auto checkMethod = nextMethodDef;
  2875. nextMethodDef = nextMethodDef->mNextWithSameName;
  2876. // These can only be invoked when the target itself is the interface
  2877. if (checkMethod->mExplicitInterface != NULL)
  2878. continue;
  2879. if ((checkMethod->mMethodType != mMethodType) || (!checkMethod->mIsStatic))
  2880. continue;
  2881. if (checkMethod->mName != mMethodName)
  2882. continue;
  2883. if ((!isFailurePass) && (!mModule->CheckProtection(checkMethod->mProtection, NULL, allowProtected, allowPrivate)))
  2884. continue;
  2885. CheckMethod(typeInstance, curTypeInst, checkMethod, isFailurePass);
  2886. }
  2887. if (mBestMethodDef != NULL)
  2888. return;
  2889. auto baseType = curTypeInst->mBaseType;
  2890. if (baseType == NULL)
  2891. break;
  2892. curTypeDef = baseType->mTypeDef;
  2893. curTypeInst = baseType;
  2894. allowPrivate = false;
  2895. if ((isFailurePass) && (mBackupMethodDef != NULL))
  2896. break;
  2897. }
  2898. if (mBestMethodDef == NULL)
  2899. {
  2900. // FAILED, but select the first method which will fire an actual error on param type matching
  2901. mBestMethodDef = mBackupMethodDef;
  2902. }
  2903. if (mBestMethodDef == NULL)
  2904. {
  2905. // No explicit target - maybe this was a static call in the outer type?
  2906. auto outerType = mModule->GetOuterType(typeInstance);
  2907. if (outerType != NULL)
  2908. CheckOuterTypeStaticMethods(outerType, isFailurePass);
  2909. }
  2910. }
  2911. //////////////////////////////////////////////////////////////////////////
  2912. void BfResolvedArgs::HandleFixits(BfModule* module)
  2913. {
  2914. auto compiler = module->mCompiler;
  2915. if ((!compiler->IsAutocomplete()) || (compiler->mResolvePassData->mResolveType != BfResolveType_GetFixits))
  2916. return;
  2917. SetAndRestoreValue<bool> ignoreErrors(module->mIgnoreErrors, true);
  2918. for (int argIdx = 0; argIdx < (int)mResolvedArgs.size(); argIdx++)
  2919. {
  2920. auto& resolvedArg = mResolvedArgs[argIdx];
  2921. auto expr = BfNodeDynCast<BfExpression>(resolvedArg.mExpression);
  2922. if (expr != NULL)
  2923. {
  2924. module->CreateValueFromExpression(expr, resolvedArg.mExpectedType);
  2925. }
  2926. }
  2927. }
  2928. //////////////////////////////////////////////////////////////////////////
  2929. BfExprEvaluator::BfExprEvaluator(BfModule* module)
  2930. {
  2931. mBfEvalExprFlags = BfEvalExprFlags_None;
  2932. mModule = module;
  2933. mPropDef = NULL;
  2934. mPropSrc = NULL;
  2935. mPropGetMethodFlags = BfGetMethodInstanceFlag_None;
  2936. mPropCheckedKind = BfCheckedKind_NotSet;
  2937. mUsedAsStatement = false;
  2938. mPropDefBypassVirtual = false;
  2939. mExpectingType = NULL;
  2940. mFunctionBindResult = NULL;
  2941. mExplicitCast = false;
  2942. mDeferCallData = NULL;
  2943. mPrefixedAttributeState = NULL;
  2944. mResolveGenericParam = true;
  2945. mNoBind = false;
  2946. mResultLocalVar = NULL;
  2947. mResultFieldInstance = NULL;
  2948. mResultLocalVarField = 0;
  2949. mResultLocalVarFieldCount = 0;
  2950. mResultLocalVarRefNode = NULL;
  2951. mIsVolatileReference = false;
  2952. mIsHeapReference = false;
  2953. mResultIsTempComposite = false;
  2954. mAllowReadOnlyReference = false;
  2955. mInsidePendingNullable = false;
  2956. mReceivingValue = NULL;
  2957. }
  2958. BfExprEvaluator::~BfExprEvaluator()
  2959. {
  2960. }
  2961. BfAutoComplete* BfExprEvaluator::GetAutoComplete()
  2962. {
  2963. if (mModule->mCompiler->mResolvePassData == NULL)
  2964. return NULL;
  2965. if ((mBfEvalExprFlags & BfEvalExprFlags_NoAutoComplete) != 0)
  2966. return NULL;
  2967. // For local methods- only process autocomplete on capture phase
  2968. if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) && (!mModule->mCurMethodState->mClosureState->mCapturing))
  2969. return NULL;
  2970. // if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mMethodDef->mIsLocalMethod))
  2971. // return NULL;
  2972. return mModule->mCompiler->mResolvePassData->mAutoComplete;
  2973. }
  2974. bool BfExprEvaluator::IsComptime()
  2975. {
  2976. return (mModule->mIsComptimeModule) || ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0);
  2977. }
  2978. bool BfExprEvaluator::IsConstEval()
  2979. {
  2980. return ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0);
  2981. }
  2982. bool BfExprEvaluator::IsComptimeEntry()
  2983. {
  2984. if (mModule->mIsComptimeModule)
  2985. return false;
  2986. return ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0);
  2987. }
  2988. void BfExprEvaluator::EnsureResultNotConstant()
  2989. {
  2990. if ((mResult.mValue.IsConst()) && (!mResult.mType->IsValuelessType()))
  2991. {
  2992. auto newTypedValue = mModule->GetDefaultTypedValue(mResult.mType, true, Beefy::BfDefaultValueKind_Addr);
  2993. mModule->mBfIRBuilder->CreateStore(mResult.mValue, newTypedValue.mValue);
  2994. mResult = newTypedValue;
  2995. }
  2996. }
  2997. int BfExprEvaluator::GetStructRetIdx(BfMethodInstance* methodInstance, bool forceStatic)
  2998. {
  2999. if (IsComptime())
  3000. return -1;
  3001. return methodInstance->GetStructRetIdx(forceStatic);
  3002. }
  3003. BfType* BfExprEvaluator::BindGenericType(BfAstNode* node, BfType* bindType)
  3004. {
  3005. if ((mModule->mCurMethodState == NULL) || (mModule->mCurMethodInstance == NULL) || (bindType == NULL))
  3006. return bindType;
  3007. if ((mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mCapturing))
  3008. return bindType;
  3009. if ((mBfEvalExprFlags & BfEvalExprFlags_DeclType) != 0)
  3010. return bindType;
  3011. BF_ASSERT((!mModule->mCurMethodInstance->mIsUnspecializedVariation) || (mModule->mIsComptimeModule));
  3012. auto parser = node->GetSourceData()->ToParserData();
  3013. if (parser == NULL)
  3014. return bindType;
  3015. int64 nodeId = ((int64)parser->mDataId << 32) + node->GetSrcStart();
  3016. auto genericTypeBindings = mModule->mCurMethodState->GetRootMethodState()->mGenericTypeBindings;
  3017. auto methodInstance = mModule->mCurMethodInstance;
  3018. bool isMixinBind = false;
  3019. if (mModule->mCurMethodState->mMixinState != NULL)
  3020. {
  3021. auto mixinMethodInstance = mModule->mCurMethodState->mMixinState->mMixinMethodInstance;
  3022. if (!mixinMethodInstance->mMethodDef->mGenericParams.IsEmpty())
  3023. {
  3024. auto unspecMixinMethodInstance = mModule->GetUnspecializedMethodInstance(mixinMethodInstance, false);
  3025. if (!unspecMixinMethodInstance->mHasBeenProcessed)
  3026. {
  3027. // Make sure the unspecialized method is processed so we can take its bindings
  3028. // Clear mCurMethodState so we don't think we're in a local method
  3029. SetAndRestoreValue<BfMethodState*> prevMethodState_Unspec(mModule->mCurMethodState, NULL);
  3030. if (unspecMixinMethodInstance->mMethodProcessRequest == NULL)
  3031. unspecMixinMethodInstance->mDeclModule->mIncompleteMethodCount++;
  3032. mModule->mContext->ProcessMethod(unspecMixinMethodInstance);
  3033. }
  3034. isMixinBind = true;
  3035. methodInstance = mixinMethodInstance;
  3036. genericTypeBindings = &unspecMixinMethodInstance->mMethodInfoEx->mGenericTypeBindings;
  3037. }
  3038. }
  3039. if ((methodInstance->mIsUnspecialized) && (!methodInstance->mIsUnspecializedVariation))
  3040. {
  3041. if (isMixinBind)
  3042. return bindType;
  3043. if (!bindType->IsGenericParam())
  3044. return bindType;
  3045. if (genericTypeBindings == NULL)
  3046. return bindType;
  3047. (*genericTypeBindings)[nodeId] = bindType;
  3048. return bindType;
  3049. }
  3050. else
  3051. {
  3052. if (genericTypeBindings == NULL)
  3053. return bindType;
  3054. BfType** typePtr = NULL;
  3055. if (genericTypeBindings->TryGetValue(nodeId, &typePtr))
  3056. return *typePtr;
  3057. return bindType;
  3058. }
  3059. }
  3060. BfType * BfExprEvaluator::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags)
  3061. {
  3062. if (mExpectingType != NULL)
  3063. {
  3064. if (auto namedTypeRef = BfNodeDynCastExact<BfNamedTypeReference>(typeRef))
  3065. {
  3066. if (namedTypeRef->ToString() == "ExpectedType")
  3067. {
  3068. return mModule->ResolveTypeResult(typeRef, mExpectingType, populateType, resolveFlags);
  3069. }
  3070. }
  3071. }
  3072. return mModule->ResolveTypeRef(typeRef, populateType, resolveFlags);
  3073. }
  3074. void BfExprEvaluator::ResolveGenericType()
  3075. {
  3076. if (mResult)
  3077. {
  3078. if (mModule->IsUnboundGeneric(mResult.mType))
  3079. mResult.mType = mModule->GetPrimitiveType(BfTypeCode_Var);
  3080. //mResult.mType = mModule->ResolveGenericType(mResult.mType, true);
  3081. }
  3082. }
  3083. void BfExprEvaluator::Evaluate(BfAstNode* astNode, bool propogateNullConditional, bool ignoreNullConditional, bool allowSplat)
  3084. {
  3085. BP_ZONE("BfExprEvaluator::Evaluate");
  3086. // ParenthesizedExpression breaks null conditional chain
  3087. if (astNode->IsExact<BfParenthesizedExpression>())
  3088. propogateNullConditional = false;
  3089. bool scopeWasConditional = false;
  3090. BfPendingNullConditional* pendingNullCond = NULL;
  3091. mInsidePendingNullable = false;
  3092. if (mModule->mCurMethodState != NULL)
  3093. {
  3094. scopeWasConditional = mModule->mCurMethodState->mCurScope->mIsConditional;
  3095. pendingNullCond = mModule->mCurMethodState->mPendingNullConditional;
  3096. if (!propogateNullConditional)
  3097. mModule->mCurMethodState->mPendingNullConditional = NULL;
  3098. if (pendingNullCond != NULL)
  3099. {
  3100. mInsidePendingNullable = true;
  3101. mModule->mCurMethodState->mCurScope->mIsConditional = true;
  3102. }
  3103. }
  3104. astNode->Accept(this);
  3105. GetResult();
  3106. if ((mResultIsTempComposite) && (mResult.IsAddr()))
  3107. mResult.mKind = BfTypedValueKind_TempAddr;
  3108. if ((!allowSplat) && (mResult.IsSplat()))
  3109. mResult = mModule->AggregateSplat(mResult);
  3110. if ((mBfEvalExprFlags & BfEvalExprFlags_AllowIntUnknown) == 0)
  3111. mModule->FixIntUnknown(mResult);
  3112. if (!mModule->mBfIRBuilder->mIgnoreWrites)
  3113. {
  3114. if (mResult.mValue.IsConst())
  3115. {
  3116. auto constant = mModule->mBfIRBuilder->GetConstant(mResult.mValue);
  3117. if (constant->mConstType == BfConstType_TypeOf)
  3118. {
  3119. auto typeOfConst = (BfTypeOf_Const*)constant;
  3120. mResult.mValue = mModule->CreateTypeDataRef(typeOfConst->mType);
  3121. }
  3122. }
  3123. }
  3124. if (mModule->mCurMethodState != NULL)
  3125. {
  3126. if (mInsidePendingNullable)
  3127. mModule->mCurMethodState->mCurScope->mIsConditional = scopeWasConditional;
  3128. if (!propogateNullConditional)
  3129. {
  3130. if (mModule->mCurMethodState->mPendingNullConditional != NULL)
  3131. mResult = mModule->FlushNullConditional(mResult, ignoreNullConditional);
  3132. mModule->mCurMethodState->mPendingNullConditional = pendingNullCond;
  3133. }
  3134. }
  3135. }
  3136. void BfExprEvaluator::Visit(BfErrorNode* errorNode)
  3137. {
  3138. mModule->Fail("Invalid token", errorNode);
  3139. auto autoComplete = GetAutoComplete();
  3140. if (autoComplete != NULL)
  3141. {
  3142. if (auto tokenNode = BfNodeDynCast<BfTokenNode>(errorNode->mRefNode))
  3143. return;
  3144. autoComplete->CheckIdentifier(errorNode->mRefNode, true);
  3145. }
  3146. }
  3147. void BfExprEvaluator::Visit(BfTypeReference* typeRef)
  3148. {
  3149. mResult.mType = ResolveTypeRef(typeRef, BfPopulateType_Declaration);
  3150. }
  3151. void BfExprEvaluator::Visit(BfAttributedExpression* attribExpr)
  3152. {
  3153. BfAttributeState attributeState;
  3154. attributeState.mSrc = attribExpr->mAttributes;
  3155. attributeState.mTarget = (BfAttributeTargets)(BfAttributeTargets_Invocation | BfAttributeTargets_MemberAccess);
  3156. if (auto block = BfNodeDynCast<BfBlock>(attribExpr->mExpression))
  3157. attributeState.mTarget = BfAttributeTargets_Block;
  3158. attributeState.mCustomAttributes = mModule->GetCustomAttributes(attribExpr->mAttributes, attributeState.mTarget);
  3159. SetAndRestoreValue<BfAttributeState*> prevAttributeState(mModule->mAttributeState, &attributeState);
  3160. if (auto ignoreErrorsAttrib = attributeState.mCustomAttributes->Get(mModule->mCompiler->mIgnoreErrorsAttributeTypeDef))
  3161. {
  3162. SetAndRestoreValue<bool> ignoreErrors(mModule->mIgnoreErrors, true);
  3163. if (!ignoreErrorsAttrib->mCtorArgs.IsEmpty())
  3164. {
  3165. auto constant = mModule->mCurTypeInstance->mConstHolder->GetConstant(ignoreErrorsAttrib->mCtorArgs[0]);
  3166. if (constant->mBool)
  3167. attributeState.mFlags = BfAttributeState::Flag_StopOnError;
  3168. }
  3169. VisitChild(attribExpr->mExpression);
  3170. attributeState.mUsed = true;
  3171. if ((!mResult) ||
  3172. ((mResult) && (mResult.mType->IsVar())))
  3173. {
  3174. if (!mResult)
  3175. mModule->Fail("Expression did not result in a value", attribExpr->mExpression);
  3176. // Make empty or 'var' resolve as 'false' because var is only valid if we threw errors
  3177. mResult = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Boolean));
  3178. }
  3179. }
  3180. else if (attributeState.mCustomAttributes->Contains(mModule->mCompiler->mConstSkipAttributeTypeDef))
  3181. {
  3182. if ((mModule->mCurMethodState == NULL) || (mModule->mCurMethodState->mCurScope == NULL) || (!mModule->mCurMethodState->mCurScope->mInConstIgnore))
  3183. {
  3184. VisitChild(attribExpr->mExpression);
  3185. }
  3186. else
  3187. {
  3188. BF_ASSERT(mModule->mBfIRBuilder->mIgnoreWrites);
  3189. mResult = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Var));
  3190. }
  3191. attributeState.mUsed = true;
  3192. }
  3193. else
  3194. {
  3195. VisitChild(attribExpr->mExpression);
  3196. }
  3197. mModule->FinishAttributeState(&attributeState);
  3198. }
  3199. void BfExprEvaluator::Visit(BfNamedExpression* namedExpr)
  3200. {
  3201. if (namedExpr->mExpression != NULL)
  3202. VisitChild(namedExpr->mExpression);
  3203. }
  3204. void BfExprEvaluator::Visit(BfBlock* blockExpr)
  3205. {
  3206. if (mModule->mCurMethodState == NULL)
  3207. {
  3208. mModule->Fail("Illegal use of block expression", blockExpr);
  3209. return;
  3210. }
  3211. auto autoComplete = GetAutoComplete();
  3212. if ((autoComplete != NULL) && (autoComplete->mMethodMatchInfo != NULL) && (autoComplete->IsAutocompleteNode(blockExpr)))
  3213. {
  3214. // Don't show outer method match info when our cursor is inside a block (being passed as a parameter)
  3215. autoComplete->RemoveMethodMatchInfo();
  3216. }
  3217. if (blockExpr->mChildArr.IsEmpty())
  3218. {
  3219. mModule->Fail("An empty block cannot be used as an expression", blockExpr);
  3220. return;
  3221. }
  3222. bool lastWasResultExpr = false;
  3223. if (auto lastExpr = BfNodeDynCast<BfExpressionStatement>(blockExpr->mChildArr.GetLast()))
  3224. {
  3225. if (!lastExpr->IsMissingSemicolon())
  3226. mModule->Fail("Expression blocks must end in an expression which is missing its terminating semicolon", lastExpr->mTrailingSemicolon);
  3227. }
  3228. else if (blockExpr->mChildArr.GetLast()->IsExpression())
  3229. {
  3230. // Expression
  3231. }
  3232. else
  3233. {
  3234. mModule->Fail("Expression blocks must end with an expression", blockExpr);
  3235. }
  3236. mModule->VisitEmbeddedStatement(blockExpr, this, BfNodeIsA<BfUnscopedBlock>(blockExpr) ? BfEmbeddedStatementFlags_Unscoped : BfEmbeddedStatementFlags_None);
  3237. }
  3238. bool BfExprEvaluator::CheckVariableDeclaration(BfAstNode* checkNode, bool requireSimpleIfExpr, bool exprMustBeTrue, bool silentFail)
  3239. {
  3240. if (BfNodeIsA<BfUninitializedExpression>(checkNode))
  3241. return true;
  3242. BfAstNode* checkChild = checkNode;
  3243. bool childWasAndRHS = false;
  3244. bool foundIf = false;
  3245. auto parentNodeEntry = mModule->mParentNodeEntry;
  3246. if (parentNodeEntry != NULL)
  3247. {
  3248. if (BfNodeIsA<BfInvocationExpression>(parentNodeEntry->mNode))
  3249. {
  3250. checkChild = parentNodeEntry->mNode;
  3251. parentNodeEntry = parentNodeEntry->mPrev;
  3252. }
  3253. }
  3254. auto _Fail = [&](const StringImpl& errorStr, BfAstNode* node)
  3255. {
  3256. if (!silentFail)
  3257. {
  3258. auto error = mModule->Fail(errorStr, node);
  3259. if ((error != NULL) && (node != checkNode))
  3260. {
  3261. mModule->mCompiler->mPassInstance->MoreInfo("See variable declaration", checkNode);
  3262. }
  3263. }
  3264. return false;
  3265. };
  3266. while (parentNodeEntry != NULL)
  3267. {
  3268. BfAstNode* checkParent = parentNodeEntry->mNode;
  3269. if (auto binOpExpr = BfNodeDynCastExact<BfBinaryOperatorExpression>(checkParent))
  3270. {
  3271. if (binOpExpr->mOp == BfBinaryOp_ConditionalAnd)
  3272. {
  3273. // This is always okay
  3274. childWasAndRHS = (binOpExpr->mRight != NULL) && (binOpExpr->mRight->Contains(checkChild));
  3275. }
  3276. else if ((binOpExpr->mOp == BfBinaryOp_ConditionalOr) && (!exprMustBeTrue))
  3277. {
  3278. if ((binOpExpr->mRight != NULL) && (binOpExpr->mRight->Contains(checkChild)))
  3279. {
  3280. return _Fail("Conditional short-circuiting may skip variable initialization", binOpExpr->mOpToken);
  3281. }
  3282. }
  3283. else
  3284. {
  3285. if (exprMustBeTrue)
  3286. {
  3287. return _Fail("Operator cannot be used with variable initialization", binOpExpr->mOpToken);
  3288. }
  3289. }
  3290. }
  3291. else if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(checkParent))
  3292. {
  3293. // This is okay
  3294. }
  3295. else if (auto unaryOp = BfNodeDynCast<BfUnaryOperatorExpression>(checkParent))
  3296. {
  3297. if (exprMustBeTrue)
  3298. {
  3299. return _Fail("Operator cannot be used with variable initialization", unaryOp->mOpToken);
  3300. return false;
  3301. }
  3302. if (childWasAndRHS)
  3303. {
  3304. return _Fail("Operator may allow conditional short-circuiting to skip variable initialization", unaryOp->mOpToken);
  3305. }
  3306. }
  3307. else if (auto ifStmt = BfNodeDynCast<BfIfStatement>(checkParent))
  3308. {
  3309. // Done
  3310. foundIf = true;
  3311. break;
  3312. }
  3313. else
  3314. {
  3315. if (requireSimpleIfExpr)
  3316. {
  3317. return _Fail("Variable declaration expression can only be contained in simple 'if' expressions", checkNode);
  3318. }
  3319. break;
  3320. }
  3321. checkChild = parentNodeEntry->mNode;
  3322. parentNodeEntry = parentNodeEntry->mPrev;
  3323. }
  3324. return foundIf;
  3325. }
  3326. bool BfExprEvaluator::HasVariableDeclaration(BfAstNode* checkNode)
  3327. {
  3328. BfVarDeclChecker checker;
  3329. checker.VisitChild(checkNode);
  3330. return checker.mHasVarDecl;
  3331. }
  3332. void BfExprEvaluator::Visit(BfVariableDeclaration* varDecl)
  3333. {
  3334. mModule->UpdateExprSrcPos(varDecl);
  3335. if ((mModule->mCurMethodState == NULL) || (!mModule->mCurMethodState->mCurScope->mAllowVariableDeclarations))
  3336. {
  3337. mModule->Fail("Variable declarations are not allowed in this context", varDecl);
  3338. if (varDecl->mInitializer != NULL)
  3339. {
  3340. VisitChild(varDecl->mInitializer);
  3341. }
  3342. return;
  3343. }
  3344. CheckVariableDeclaration(varDecl, true, false, false);
  3345. if (varDecl->mInitializer == NULL)
  3346. {
  3347. mModule->Fail("Variable declarations used as expressions must have an initializer", varDecl);
  3348. }
  3349. BfTupleExpression* tupleVariableDeclaration = BfNodeDynCast<BfTupleExpression>(varDecl->mNameNode);
  3350. if (tupleVariableDeclaration != NULL)
  3351. {
  3352. mModule->Fail("Tuple variable declarations cannot be used as expressions", varDecl);
  3353. mModule->HandleTupleVariableDeclaration(varDecl);
  3354. }
  3355. else
  3356. mModule->HandleVariableDeclaration(varDecl, this);
  3357. }
  3358. void BfExprEvaluator::DoCaseExpression(BfTypedValue caseValAddr, BfCaseExpression* caseExpr)
  3359. {
  3360. if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mDeferredLocalAssignData != NULL))
  3361. mModule->mCurMethodState->mDeferredLocalAssignData->BreakExtendChain();
  3362. if (auto bindExpr = BfNodeDynCast<BfEnumCaseBindExpression>(caseExpr->mCaseExpression))
  3363. {
  3364. if (caseValAddr)
  3365. {
  3366. BfTypedValue enumTagVal;
  3367. if (caseValAddr.mType->IsPayloadEnum())
  3368. {
  3369. int dscrDataIdx;
  3370. auto dscrType = caseValAddr.mType->ToTypeInstance()->GetDiscriminatorType(&dscrDataIdx);
  3371. enumTagVal = BfTypedValue(mModule->ExtractValue(caseValAddr, dscrDataIdx), dscrType);
  3372. }
  3373. else
  3374. enumTagVal = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Int32));
  3375. mResult = mModule->HandleCaseBind(caseValAddr, enumTagVal, bindExpr);
  3376. return;
  3377. }
  3378. }
  3379. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  3380. bool isPayloadEnum = (caseValAddr.mType != NULL) && (caseValAddr.mType->IsPayloadEnum());
  3381. auto tupleExpr = BfNodeDynCast<BfTupleExpression>(caseExpr->mCaseExpression);
  3382. if ((caseValAddr) &&
  3383. ((isPayloadEnum) || (tupleExpr != NULL)))
  3384. {
  3385. bool hasVariable = false;
  3386. bool hasOut = false;
  3387. bool clearOutOnMismatch = false;
  3388. if (auto invocateExpr = BfNodeDynCast<BfInvocationExpression>(caseExpr->mCaseExpression))
  3389. {
  3390. for (auto arg : invocateExpr->mArguments)
  3391. {
  3392. if (auto varDecl = BfNodeDynCast<BfVariableDeclaration>(arg))
  3393. {
  3394. hasVariable = true;
  3395. }
  3396. else if (auto unaryOpExpr = BfNodeDynCast<BfUnaryOperatorExpression>(arg))
  3397. {
  3398. if ((unaryOpExpr->mOpToken != NULL) && (unaryOpExpr->mOpToken->mToken == BfToken_Out))
  3399. {
  3400. hasOut = true;
  3401. }
  3402. }
  3403. }
  3404. }
  3405. if (hasVariable)
  3406. {
  3407. CheckVariableDeclaration(caseExpr, false, false, false);
  3408. }
  3409. // We can avoid clearing on mismatch if we can be sure we ONLY enter the true block on a match.
  3410. // An example of requiring clearing is: if ((result case .Ok(out val)) || (force))
  3411. if (hasOut)
  3412. clearOutOnMismatch = !CheckVariableDeclaration(caseExpr, true, true, true);
  3413. bool hadConditional = false;
  3414. if (isPayloadEnum)
  3415. {
  3416. int dscrDataIdx;
  3417. auto dscrType = caseValAddr.mType->ToTypeInstance()->GetDiscriminatorType(&dscrDataIdx);
  3418. auto enumTagVal = mModule->LoadValue(mModule->ExtractValue(caseValAddr, NULL, 2));
  3419. int uncondTagId = -1;
  3420. mResult = mModule->TryCaseEnumMatch(caseValAddr, enumTagVal, caseExpr->mCaseExpression, NULL, NULL, NULL, uncondTagId, hadConditional, clearOutOnMismatch, false);
  3421. }
  3422. else
  3423. {
  3424. mResult = mModule->TryCaseTupleMatch(caseValAddr, tupleExpr, NULL, NULL, NULL, hadConditional, clearOutOnMismatch, false);
  3425. }
  3426. if (mResult)
  3427. return;
  3428. }
  3429. if ((caseValAddr) && (IsVar(caseValAddr.mType)))
  3430. {
  3431. auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(caseExpr->mCaseExpression);
  3432. if (invocationExpr != NULL)
  3433. {
  3434. for (auto expr : invocationExpr->mArguments)
  3435. {
  3436. if (expr == NULL)
  3437. continue;
  3438. if (auto varDecl = BfNodeDynCast<BfVariableDeclaration>(expr))
  3439. {
  3440. auto localVar = mModule->HandleVariableDeclaration(varDecl, BfTypedValue());
  3441. if (localVar != NULL)
  3442. localVar->mReadFromId = 0;
  3443. }
  3444. }
  3445. }
  3446. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  3447. mResult = mModule->GetDefaultTypedValue(boolType);
  3448. return;
  3449. }
  3450. BfTypedValue caseMatch;
  3451. if (caseExpr->mCaseExpression != NULL)
  3452. caseMatch = mModule->CreateValueFromExpression(caseExpr->mCaseExpression, caseValAddr.mType, BfEvalExprFlags_AllowEnumId);
  3453. if ((!caseMatch) || (!caseValAddr))
  3454. {
  3455. mResult = mModule->GetDefaultTypedValue(boolType);
  3456. return;
  3457. }
  3458. if (caseValAddr.mType == caseMatch.mType)
  3459. {
  3460. if (((caseValAddr.mType->IsEnum()) && (caseValAddr.mType->IsStruct())) &&
  3461. ((caseMatch) && (caseMatch.mType->IsPayloadEnum()) && (caseMatch.mValue.IsConst())))
  3462. {
  3463. BfTypedValue enumTagVal = mModule->LoadValue(mModule->ExtractValue(caseValAddr, NULL, 2));
  3464. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(enumTagVal.mValue, caseMatch.mValue), boolType);
  3465. return;
  3466. }
  3467. }
  3468. else
  3469. {
  3470. // We need to get rid of the int-const for the 'scalar match'. We get a full payload enum value so we can
  3471. // possibly use it in a user-defined comparison operator
  3472. if ((caseMatch.mType->IsStruct()) && (caseMatch.mValue.IsConst()))
  3473. {
  3474. // Is it possible this could throw an error twice? Hope not.
  3475. caseMatch = mModule->CreateValueFromExpression(caseExpr->mCaseExpression, NULL, (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags));
  3476. }
  3477. }
  3478. PerformBinaryOperation(caseExpr->mCaseExpression, caseExpr->mValueExpression, BfBinaryOp_Equality, caseExpr->mEqualsNode, BfBinOpFlag_None, caseValAddr, caseMatch);
  3479. }
  3480. void BfExprEvaluator::Visit(BfCaseExpression* caseExpr)
  3481. {
  3482. if (caseExpr->mEqualsNode != NULL)
  3483. {
  3484. mModule->Warn(0, "Deprecated case syntax", caseExpr->mEqualsNode);
  3485. }
  3486. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  3487. BfTypedValue caseValAddr;
  3488. if (caseExpr->mValueExpression != NULL)
  3489. caseValAddr = mModule->CreateValueFromExpression(caseExpr->mValueExpression, NULL, (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags));
  3490. if ((caseValAddr.mType != NULL) && (caseValAddr.mType->IsPointer()))
  3491. {
  3492. caseValAddr = mModule->LoadValue(caseValAddr);
  3493. caseValAddr = BfTypedValue(caseValAddr.mValue, caseValAddr.mType->GetUnderlyingType(), true);
  3494. }
  3495. BfIRValue hasValueValue;
  3496. if (caseValAddr.mType != NULL)
  3497. mModule->mBfIRBuilder->PopulateType(caseValAddr.mType);
  3498. if ((caseValAddr.mType != NULL) && (caseValAddr.mType->IsNullable()))
  3499. {
  3500. auto nullableElementType = caseValAddr.mType->GetUnderlyingType();
  3501. hasValueValue = mModule->ExtractValue(caseValAddr, nullableElementType->IsValuelessType() ? 1 : 2);
  3502. if (!nullableElementType->IsValuelessType())
  3503. caseValAddr = BfTypedValue(mModule->ExtractValue(caseValAddr, 1), nullableElementType); // value
  3504. else
  3505. caseValAddr = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), nullableElementType);
  3506. }
  3507. BfIRBlock nullBB;
  3508. BfIRBlock endBB;
  3509. if (hasValueValue)
  3510. {
  3511. auto caseBB = mModule->mBfIRBuilder->CreateBlock("caseexpr.case");
  3512. endBB = mModule->mBfIRBuilder->CreateBlock("caseexpr.end");
  3513. mModule->mBfIRBuilder->CreateCondBr(hasValueValue, caseBB, endBB);
  3514. nullBB = mModule->mBfIRBuilder->GetInsertBlock();
  3515. mModule->mBfIRBuilder->AddBlock(caseBB);
  3516. mModule->mBfIRBuilder->SetInsertPoint(caseBB);
  3517. }
  3518. DoCaseExpression(caseValAddr, caseExpr);
  3519. if (!mResult)
  3520. mResult = mModule->GetDefaultTypedValue(boolType);
  3521. else
  3522. {
  3523. BF_ASSERT(mResult.mType == boolType);
  3524. }
  3525. if (hasValueValue)
  3526. {
  3527. auto endCaseBB = mModule->mBfIRBuilder->GetInsertBlock();
  3528. mModule->mBfIRBuilder->CreateBr(endBB);
  3529. mModule->mBfIRBuilder->AddBlock(endBB);
  3530. mModule->mBfIRBuilder->SetInsertPoint(endBB);
  3531. auto phiValue = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(boolType), 2);
  3532. mModule->mBfIRBuilder->AddPhiIncoming(phiValue, mModule->GetDefaultValue(boolType), nullBB);
  3533. mModule->mBfIRBuilder->AddPhiIncoming(phiValue, mResult.mValue, endCaseBB);
  3534. mResult = BfTypedValue(phiValue, boolType);
  3535. }
  3536. if (caseExpr->mNotToken != NULL)
  3537. mResult.mValue = mModule->mBfIRBuilder->CreateNot(mResult.mValue);
  3538. }
  3539. void BfExprEvaluator::Visit(BfTypedValueExpression* typedValueExpr)
  3540. {
  3541. mResult = typedValueExpr->mTypedValue;
  3542. }
  3543. static bool IsCharType(BfTypeCode typeCode)
  3544. {
  3545. switch (typeCode)
  3546. {
  3547. case BfTypeCode_Char8:
  3548. case BfTypeCode_Char16:
  3549. case BfTypeCode_Char32:
  3550. return true;
  3551. default:
  3552. return false;
  3553. }
  3554. }
  3555. bool BfExprEvaluator::CheckForMethodName(BfAstNode* refNode, BfTypeInstance* typeInst, const StringImpl& findName)
  3556. {
  3557. BF_ASSERT((mBfEvalExprFlags & BfEvalExprFlags_NameOf) != 0);
  3558. auto autoComplete = GetAutoComplete();
  3559. while (typeInst != NULL)
  3560. {
  3561. auto typeDef = typeInst->mTypeDef;
  3562. typeDef->PopulateMemberSets();
  3563. BfMemberSetEntry* memberSetEntry;
  3564. if (typeDef->mMethodSet.TryGetWith(findName, &memberSetEntry))
  3565. {
  3566. if (mModule->mCompiler->mResolvePassData != NULL)
  3567. mModule->mCompiler->mResolvePassData->HandleMethodReference(refNode, typeDef, (BfMethodDef*)memberSetEntry->mMemberDef);
  3568. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(refNode)))
  3569. {
  3570. autoComplete->SetDefinitionLocation(((BfMethodDef*)memberSetEntry->mMemberDef)->GetRefNode());
  3571. if ((autoComplete->mResolveType == BfResolveType_GetSymbolInfo) && (autoComplete->mDefType == NULL))
  3572. {
  3573. autoComplete->mDefType = typeDef;
  3574. autoComplete->mDefMethod = (BfMethodDef*)memberSetEntry->mMemberDef;
  3575. }
  3576. }
  3577. if (mModule->mCompiler->mResolvePassData != NULL)
  3578. {
  3579. if (auto sourceClassifier = mModule->mCompiler->mResolvePassData->GetSourceClassifier(refNode))
  3580. sourceClassifier->SetElementType(refNode, BfSourceElementType_Method);
  3581. }
  3582. mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_NameOfSuccess);
  3583. return true;
  3584. }
  3585. typeInst = typeInst->mBaseType;
  3586. }
  3587. return false;
  3588. }
  3589. bool BfExprEvaluator::IsVar(BfType* type, bool forceIgnoreWrites)
  3590. {
  3591. if (type->IsVar())
  3592. return true;
  3593. if ((type->IsGenericParam()) && (!forceIgnoreWrites) && (!mModule->mBfIRBuilder->mIgnoreWrites))
  3594. {
  3595. BF_ASSERT(mModule->mIsComptimeModule);
  3596. return true;
  3597. }
  3598. return false;
  3599. }
  3600. void BfExprEvaluator::GetLiteral(BfAstNode* refNode, const BfVariant& variant, BfType* type)
  3601. {
  3602. switch (variant.mTypeCode)
  3603. {
  3604. case BfTypeCode_NullPtr:
  3605. {
  3606. auto nullType = mModule->ResolveTypeDef(mModule->mSystem->mTypeNullPtr);
  3607. /*mResult = BfTypedValue(ConstantPointerNull::get((PointerType*) nullType->mIRType), nullType);*/
  3608. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConstNull(), nullType);
  3609. }
  3610. break;
  3611. case BfTypeCode_CharPtr:
  3612. {
  3613. if ((mExpectingType != NULL) && (mExpectingType->IsSizedArray()))
  3614. {
  3615. auto sizedArray = (BfSizedArrayType*)mExpectingType;
  3616. if (sizedArray->mElementType == mModule->GetPrimitiveType(BfTypeCode_Char8))
  3617. {
  3618. if (sizedArray->IsUndefSizedArray())
  3619. sizedArray = mModule->CreateSizedArrayType(sizedArray->mElementType, variant.mString->GetLength());
  3620. if (variant.mString->GetLength() > sizedArray->mElementCount)
  3621. {
  3622. mModule->Fail(StrFormat("String literal is too long to fit into '%s'", mModule->TypeToString(sizedArray).c_str()), refNode);
  3623. }
  3624. Array<BfIRValue> charValues;
  3625. for (int i = 0; i < (int)BF_MIN(variant.mString->GetLength(), sizedArray->mElementCount); i++)
  3626. {
  3627. char c = (*variant.mString)[i];
  3628. charValues.Add(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Char8, (int)(uint8)c));
  3629. }
  3630. if (sizedArray->mElementCount > charValues.size())
  3631. charValues.Add(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Char8, 0));
  3632. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(sizedArray), charValues), sizedArray);
  3633. return;
  3634. }
  3635. }
  3636. if ((mExpectingType == NULL) || (!mExpectingType->IsPointer()))
  3637. {
  3638. mResult = BfTypedValue(mModule->GetStringObjectValue(*variant.mString),
  3639. mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
  3640. }
  3641. else
  3642. {
  3643. auto charType = mModule->GetPrimitiveType(BfTypeCode_Char8);
  3644. auto charPtrType = mModule->CreatePointerType(charType);
  3645. mResult = BfTypedValue(mModule->GetStringCharPtr(*variant.mString),
  3646. charPtrType);
  3647. }
  3648. }
  3649. break;
  3650. case BfTypeCode_Boolean:
  3651. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(variant.mTypeCode, variant.mUInt64), mModule->GetPrimitiveType(variant.mTypeCode));
  3652. break;
  3653. case BfTypeCode_Char8:
  3654. case BfTypeCode_Char16:
  3655. case BfTypeCode_Char32:
  3656. case BfTypeCode_Int8:
  3657. case BfTypeCode_UInt8:
  3658. case BfTypeCode_Int16:
  3659. case BfTypeCode_UInt16:
  3660. case BfTypeCode_Int32:
  3661. case BfTypeCode_UInt32:
  3662. case BfTypeCode_Int64:
  3663. case BfTypeCode_UInt64:
  3664. case BfTypeCode_IntPtr:
  3665. case BfTypeCode_UIntPtr:
  3666. case BfTypeCode_IntUnknown:
  3667. case BfTypeCode_UIntUnknown:
  3668. if ((mExpectingType != NULL) && (mExpectingType->IsIntegral()) && (mExpectingType->IsChar() == IsCharType(variant.mTypeCode)))
  3669. {
  3670. auto primType = (BfPrimitiveType*)mExpectingType;
  3671. if (mModule->mSystem->DoesLiteralFit(primType->mTypeDef->mTypeCode, variant.mUInt64))
  3672. {
  3673. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, variant.mUInt64), mExpectingType);
  3674. break;
  3675. }
  3676. }
  3677. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(variant.mTypeCode, variant.mUInt64), mModule->GetPrimitiveType(variant.mTypeCode));
  3678. break;
  3679. case BfTypeCode_Float:
  3680. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(variant.mTypeCode, variant.mSingle), mModule->GetPrimitiveType(variant.mTypeCode));
  3681. break;
  3682. case BfTypeCode_Double:
  3683. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(variant.mTypeCode, variant.mDouble), mModule->GetPrimitiveType(variant.mTypeCode));
  3684. break;
  3685. case BfTypeCode_StringId:
  3686. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(variant.mTypeCode, variant.mUInt64), mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
  3687. break;
  3688. case BfTypeCode_Let:
  3689. if (mExpectingType != NULL)
  3690. {
  3691. mResult = BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->MapType(mExpectingType)), mExpectingType);
  3692. break;
  3693. }
  3694. mModule->Fail("Invalid undef literal", refNode);
  3695. break;
  3696. case BfTypeCode_Struct:
  3697. if (type != NULL)
  3698. {
  3699. BfVariant::StructData* structData = (BfVariant::StructData*)variant.mPtr;
  3700. mResult = BfTypedValue(mModule->mBfIRBuilder->ReadConstant(structData->mData, type), type);
  3701. }
  3702. break;
  3703. default:
  3704. mModule->Fail("Invalid literal", refNode);
  3705. break;
  3706. }
  3707. }
  3708. void BfExprEvaluator::Visit(BfLiteralExpression* literalExpr)
  3709. {
  3710. switch (literalExpr->mValue.mWarnType)
  3711. {
  3712. case BfWarning_BF4201_Only7Hex:
  3713. mModule->Warn(BfWarning_BF4201_Only7Hex, "Only 7 hex digits specified. Add a leading zero to clarify intention.", literalExpr);
  3714. break;
  3715. case BfWarning_BF4202_TooManyHexForInt:
  3716. mModule->Warn(BfWarning_BF4202_TooManyHexForInt, "Nine hex digits specified. If an 8-digit hex literal was not intended then add a leading zero to clarify.", literalExpr);
  3717. break;
  3718. }
  3719. GetLiteral(literalExpr, literalExpr->mValue);
  3720. }
  3721. void BfExprEvaluator::Visit(BfStringInterpolationExpression* stringInterpolationExpression)
  3722. {
  3723. if ((mBfEvalExprFlags & BfEvalExprFlags_StringInterpolateFormat) != 0)
  3724. {
  3725. BfVariant variant;
  3726. variant.mTypeCode = BfTypeCode_CharPtr;
  3727. variant.mString = stringInterpolationExpression->mString;
  3728. GetLiteral(stringInterpolationExpression, variant);
  3729. return;
  3730. }
  3731. //
  3732. {
  3733. SetAndRestoreValue<BfEvalExprFlags> prevEvalExprFlag(mBfEvalExprFlags);
  3734. if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) && (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mConstEvalAttributeTypeDef)))
  3735. {
  3736. mModule->mAttributeState->mUsed = true;
  3737. mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_Comptime);
  3738. }
  3739. if (IsConstEval())
  3740. {
  3741. auto stringType = mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef);
  3742. if (stringType != NULL)
  3743. {
  3744. SetAndRestoreValue<bool> prevUsedAsStatement(mUsedAsStatement, true);
  3745. SizedArray<BfExpression*, 2> argExprs;
  3746. argExprs.Add(stringInterpolationExpression);
  3747. BfSizedArray<BfExpression*> sizedArgExprs(argExprs);
  3748. BfResolvedArgs argValues(&sizedArgExprs);
  3749. ResolveArgValues(argValues, BfResolveArgsFlag_InsideStringInterpolationAlloc);
  3750. auto result = MatchMethod(stringInterpolationExpression, NULL, BfTypedValue(stringType), false, false, "ConstF", argValues, BfMethodGenericArguments());
  3751. if (result.mType == stringType)
  3752. {
  3753. mResult = result;
  3754. return;
  3755. }
  3756. }
  3757. mModule->Fail("Const evaluation of string interpolation not allowed", stringInterpolationExpression);
  3758. }
  3759. }
  3760. if (stringInterpolationExpression->mAllocNode != NULL)
  3761. {
  3762. auto stringType = mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef)->ToTypeInstance();
  3763. BfTokenNode* newToken = NULL;
  3764. BfAllocTarget allocTarget;
  3765. ResolveAllocTarget(allocTarget, stringInterpolationExpression->mAllocNode, newToken);
  3766. //
  3767. {
  3768. SetAndRestoreValue<BfEvalExprFlags> prevFlags(mBfEvalExprFlags, (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_NoAutoComplete));
  3769. CreateObject(NULL, stringInterpolationExpression->mAllocNode, stringType, NULL);
  3770. }
  3771. BfTypedValue newString = mResult;
  3772. BF_ASSERT(newString);
  3773. SetAndRestoreValue<bool> prevUsedAsStatement(mUsedAsStatement, true);
  3774. SizedArray<BfExpression*, 2> argExprs;
  3775. argExprs.Add(stringInterpolationExpression);
  3776. BfSizedArray<BfExpression*> sizedArgExprs(argExprs);
  3777. BfResolvedArgs argValues(&sizedArgExprs);
  3778. ResolveArgValues(argValues, BfResolveArgsFlag_InsideStringInterpolationAlloc);
  3779. MatchMethod(stringInterpolationExpression, NULL, newString, false, false, "AppendF", argValues, BfMethodGenericArguments());
  3780. mResult = newString;
  3781. return;
  3782. }
  3783. mModule->Fail("Invalid use of string interpolation expression. Consider adding an allocation specifier such as 'scope'.", stringInterpolationExpression);
  3784. for (auto block : stringInterpolationExpression->mExpressions)
  3785. {
  3786. VisitChild(block);
  3787. }
  3788. }
  3789. BfTypedValue BfExprEvaluator::LoadLocal(BfLocalVariable* varDecl, bool allowRef)
  3790. {
  3791. if (!mModule->mIsInsideAutoComplete)
  3792. varDecl->mReadFromId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++;
  3793. // The Beef backend prefers readonly addrs since that reduces register pressure, whereas
  3794. // LLVM prefers values to avoid memory loads. This only applies to primitive types...
  3795. bool preferValue = (varDecl->mResolvedType->IsPrimitiveType()) && (!mModule->IsTargetingBeefBackend());
  3796. BfTypedValue localResult;
  3797. if (varDecl->mIsThis)
  3798. {
  3799. return mModule->GetThis();
  3800. }
  3801. else if (varDecl->mConstValue)
  3802. {
  3803. localResult = BfTypedValue(varDecl->mConstValue, varDecl->mResolvedType, false);
  3804. }
  3805. else if (varDecl->mIsSplat)
  3806. {
  3807. if (!varDecl->mResolvedType->IsValuelessType())
  3808. localResult = BfTypedValue(varDecl->mValue, varDecl->mResolvedType, BfTypedValueKind_SplatHead);
  3809. else if ((varDecl->mResolvedType->IsRef()) && (!allowRef))
  3810. {
  3811. BF_ASSERT(varDecl->mResolvedType->IsValuelessType());
  3812. localResult = BfTypedValue(varDecl->mValue, varDecl->mResolvedType->GetUnderlyingType());
  3813. }
  3814. else
  3815. localResult = BfTypedValue(varDecl->mValue, varDecl->mResolvedType);
  3816. //BF_ASSERT(varDecl->mValue.IsArg());
  3817. }
  3818. else if ((varDecl->mValue) && ((varDecl->mIsReadOnly && preferValue) || (!varDecl->mAddr)))
  3819. {
  3820. if ((varDecl->mResolvedType->IsRef()) && (!allowRef))
  3821. {
  3822. BfRefType* refType = (BfRefType*)varDecl->mResolvedType;
  3823. BfType* innerType = refType->mElementType;
  3824. if (innerType->IsGenericParam())
  3825. {
  3826. if (refType->mRefKind == BfRefType::RefKind_Mut)
  3827. {
  3828. localResult = BfTypedValue(varDecl->mValue, innerType, BfTypedValueKind_MutableValue);
  3829. return localResult;
  3830. }
  3831. else
  3832. {
  3833. localResult = BfTypedValue(varDecl->mValue, innerType, BfTypedValueKind_Addr);
  3834. return localResult;
  3835. }
  3836. }
  3837. localResult = BfTypedValue(varDecl->mValue, innerType, varDecl->mIsReadOnly ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
  3838. }
  3839. else
  3840. {
  3841. BfTypedValueKind kind;
  3842. if ((varDecl->mResolvedType->IsComposite()) && (varDecl->mValue.IsArg()))
  3843. {
  3844. kind = varDecl->mIsReadOnly ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr;
  3845. }
  3846. else
  3847. kind = BfTypedValueKind_Value;
  3848. localResult = BfTypedValue(varDecl->mValue, varDecl->mResolvedType, kind);
  3849. }
  3850. }
  3851. else if (varDecl->mAddr)
  3852. {
  3853. if ((!mModule->mBfIRBuilder->mIgnoreWrites) && (varDecl->mAddr.IsFake()) && (!varDecl->mResolvedType->IsValuelessType()))
  3854. {
  3855. // In an ignore case match we can may need to create a fake "out" when someone tries to read it
  3856. auto defaultTypedValue = mModule->GetDefaultTypedValue(varDecl->mResolvedType, true, BfDefaultValueKind_Addr);
  3857. varDecl->mAddr = defaultTypedValue.mValue;
  3858. }
  3859. if ((varDecl->mResolvedType->IsRef()) && (!allowRef))
  3860. {
  3861. BfRefType* refType = (BfRefType*)varDecl->mResolvedType;
  3862. BfType* innerType = refType->mElementType;
  3863. if (innerType->IsValuelessNonOpaqueType())
  3864. {
  3865. if (refType->mRefKind == BfRefType::RefKind_Mut)
  3866. return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), innerType, BfTypedValueKind_MutableValue);
  3867. return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), innerType, varDecl->mIsReadOnly ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
  3868. }
  3869. if (refType->mRefKind == BfRefType::RefKind_Mut)
  3870. {
  3871. if (innerType->IsGenericParam())
  3872. {
  3873. localResult = BfTypedValue(mModule->mBfIRBuilder->CreateAlignedLoad(varDecl->mAddr, varDecl->mResolvedType->mAlign), innerType, BfTypedValueKind_MutableValue);
  3874. return localResult;
  3875. }
  3876. }
  3877. localResult = BfTypedValue(mModule->mBfIRBuilder->CreateAlignedLoad(varDecl->mAddr, varDecl->mResolvedType->mAlign), innerType, varDecl->mIsReadOnly ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
  3878. }
  3879. else if (varDecl->mHasLocalStructBacking)
  3880. {
  3881. // varDecl->mAddr is a "struct**"
  3882. localResult = BfTypedValue(mModule->mBfIRBuilder->CreateAlignedLoad(varDecl->mAddr, varDecl->mResolvedType->mAlign), varDecl->mResolvedType, varDecl->mIsReadOnly ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
  3883. }
  3884. else
  3885. localResult = BfTypedValue(varDecl->mAddr, varDecl->mResolvedType, varDecl->mIsReadOnly ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
  3886. }
  3887. else if ((varDecl->mResolvedType->IsModifiedTypeType()) && (((BfModifiedTypeType*)varDecl->mResolvedType)->mModifiedKind == BfToken_Params))
  3888. {
  3889. localResult = BfTypedValue(BfIRValue(), varDecl->mResolvedType);
  3890. }
  3891. else if (varDecl->mResolvedType->IsValuelessNonOpaqueType())
  3892. {
  3893. if ((varDecl->mResolvedType->IsRef()) && (!allowRef))
  3894. {
  3895. BfRefType* refType = (BfRefType*)varDecl->mResolvedType;
  3896. BfType* innerType = refType->mElementType;
  3897. localResult = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), innerType, true);
  3898. return localResult;
  3899. }
  3900. localResult = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), varDecl->mResolvedType, true);
  3901. }
  3902. else if (varDecl->mCompositeCount >= 0)
  3903. {
  3904. if ((mBfEvalExprFlags & BfEvalExprFlags_InParamsExpr) != 0)
  3905. {
  3906. localResult = BfTypedValue(BfIRValue(), mModule->GetPrimitiveType(BfTypeCode_None));
  3907. }
  3908. else if (!varDecl->mAddr)
  3909. {
  3910. bool isValid = true;
  3911. Array<BfTypedValue> argVals;
  3912. auto methodState = mModule->mCurMethodState->GetMethodStateForLocal(varDecl);
  3913. for (int compositeIdx = 0; compositeIdx < varDecl->mCompositeCount; compositeIdx++)
  3914. {
  3915. BfResolvedArg compositeResolvedArg;
  3916. auto compositeLocalVar = methodState->mLocals[varDecl->mLocalVarIdx + compositeIdx + 1];
  3917. auto argValue = LoadLocal(compositeLocalVar, true);
  3918. if (argValue)
  3919. {
  3920. if (!argValue.mType->IsStruct())
  3921. argValue = mModule->LoadValue(argValue, NULL, mIsVolatileReference);
  3922. argVals.Add(argValue);
  3923. }
  3924. else
  3925. isValid = false;
  3926. }
  3927. if (isValid)
  3928. {
  3929. BfTypeInstance* tupleType = NULL;
  3930. if (varDecl->mResolvedType->IsTuple())
  3931. tupleType = (BfTupleType*)varDecl->mResolvedType;
  3932. else if ((varDecl->mResolvedType->IsDelegateOrFunction()))
  3933. {
  3934. auto invokeFunction = mModule->GetDelegateInvokeMethod(varDecl->mResolvedType->ToTypeInstance());
  3935. if (invokeFunction != NULL)
  3936. {
  3937. BfTypeVector fieldTypes;
  3938. SubstituteList fieldNames;
  3939. for (int paramIdx = 0; paramIdx < invokeFunction->GetParamCount(); paramIdx++)
  3940. {
  3941. fieldNames.Add(invokeFunction->GetParamName(paramIdx));
  3942. fieldTypes.Add(invokeFunction->GetParamType(paramIdx));
  3943. }
  3944. tupleType = mModule->CreateTupleType(fieldTypes, fieldNames);
  3945. }
  3946. }
  3947. if (tupleType == NULL)
  3948. {
  3949. isValid = false;
  3950. }
  3951. else if (tupleType->IsValuelessType())
  3952. {
  3953. localResult = mModule->GetDefaultTypedValue(tupleType);
  3954. }
  3955. else
  3956. {
  3957. BF_ASSERT(tupleType->mFieldInstances.mSize == argVals.mSize);
  3958. auto instAlloca = mModule->CreateAlloca(tupleType);
  3959. for (int i = 0; i < argVals.mSize; i++)
  3960. {
  3961. auto& fieldInstance = tupleType->mFieldInstances[i];
  3962. if (fieldInstance.mDataIdx >= 0)
  3963. {
  3964. auto val = mModule->Cast(varDecl->mNameNode, argVals[i], fieldInstance.mResolvedType);
  3965. if (val)
  3966. {
  3967. val = mModule->LoadOrAggregateValue(val);
  3968. if (!val.mType->IsValuelessType())
  3969. {
  3970. auto elemPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(instAlloca, 0, fieldInstance.mDataIdx);
  3971. mModule->mBfIRBuilder->CreateStore(val.mValue, elemPtr);
  3972. }
  3973. }
  3974. }
  3975. }
  3976. varDecl->mResolvedType = tupleType;
  3977. varDecl->mAddr = instAlloca;
  3978. varDecl->mIsReadOnly = true;
  3979. localResult = BfTypedValue(varDecl->mAddr, varDecl->mResolvedType, BfTypedValueKind_ReadOnlyAddr);
  3980. }
  3981. }
  3982. if (!isValid)
  3983. {
  3984. localResult = mModule->GetDefaultTypedValue(mModule->ResolveTypeDef(mModule->mCompiler->mTupleTypeDef));
  3985. }
  3986. }
  3987. }
  3988. else
  3989. {
  3990. BF_ASSERT((mModule->mCurMethodState->mClosureState != NULL) || (mModule->mBfIRBuilder->mIgnoreWrites));
  3991. // Just temporary
  3992. auto varType = varDecl->mResolvedType;
  3993. auto allocType = varType;
  3994. if (varType->IsRef())
  3995. {
  3996. BfRefType* refType = (BfRefType*)varType;
  3997. allocType = refType->mElementType;
  3998. }
  3999. auto declType = varDecl->mResolvedType;
  4000. if (declType->IsRef())
  4001. {
  4002. BfRefType* refType = (BfRefType*)declType;
  4003. declType = refType->mElementType;
  4004. }
  4005. mModule->PopulateType(allocType);
  4006. varDecl->mAddr = mModule->mBfIRBuilder->CreateAlloca(mModule->mBfIRBuilder->MapType(allocType));
  4007. localResult = BfTypedValue(varDecl->mAddr, declType, true);
  4008. return localResult;
  4009. }
  4010. if ((varDecl->mIsThis) && (localResult.mKind == BfTypedValueKind_Value))
  4011. localResult.mKind = BfTypedValueKind_ThisValue;
  4012. return localResult;
  4013. }
  4014. BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringImpl& findName, bool ignoreInitialError, bool* hadError)
  4015. {
  4016. int varSkipCount = 0;
  4017. StringT<128> wantName;
  4018. wantName.Reference(findName);
  4019. if (findName.StartsWith('@'))
  4020. {
  4021. wantName = findName;
  4022. while (wantName.StartsWith("@"))
  4023. {
  4024. if (wantName != "@return")
  4025. varSkipCount++;
  4026. wantName.Remove(0);
  4027. }
  4028. }
  4029. if (wantName.IsEmpty())
  4030. {
  4031. mModule->Fail("Shadowed variable name expected after '@'", refNode);
  4032. }
  4033. if ((mModule->mCompiler->mCeMachine != NULL) && (mModule->mCompiler->mCeMachine->mDebugger != NULL) && (mModule->mCompiler->mCeMachine->mDebugger->mCurDbgState != NULL))
  4034. {
  4035. auto ceDebugger = mModule->mCompiler->mCeMachine->mDebugger;
  4036. auto ceContext = ceDebugger->mCurDbgState->mCeContext;
  4037. auto activeFrame = ceDebugger->mCurDbgState->mActiveFrame;
  4038. if (activeFrame->mFunction->mDbgInfo != NULL)
  4039. {
  4040. int varSkipCountLeft = varSkipCount;
  4041. int instIdx = activeFrame->GetInstIdx();
  4042. for (int i = activeFrame->mFunction->mDbgInfo->mVariables.mSize - 1; i >= 0; i--)
  4043. {
  4044. auto& dbgVar = activeFrame->mFunction->mDbgInfo->mVariables[i];
  4045. if (dbgVar.mName == wantName)
  4046. {
  4047. if (varSkipCountLeft > 0)
  4048. {
  4049. varSkipCountLeft--;
  4050. }
  4051. else if ((dbgVar.mValue.mKind == CeOperandKind_AllocaAddr) || (dbgVar.mValue.mKind == CeOperandKind_FrameOfs))
  4052. {
  4053. if ((instIdx >= dbgVar.mStartCodePos) && (instIdx < dbgVar.mEndCodePos))
  4054. {
  4055. return BfTypedValue(mModule->mBfIRBuilder->CreateConstAggCE(mModule->mBfIRBuilder->MapType(dbgVar.mType), activeFrame->mFrameAddr + dbgVar.mValue.mFrameOfs),
  4056. dbgVar.mType, dbgVar.mIsConst ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
  4057. }
  4058. }
  4059. }
  4060. }
  4061. }
  4062. if (findName == "FR")
  4063. {
  4064. auto ptrType = mModule->CreatePointerType(mModule->GetPrimitiveType(BfTypeCode_UInt8));
  4065. auto intVal = mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, activeFrame->mFrameAddr);
  4066. auto ptrVal = mModule->mBfIRBuilder->CreateIntToPtr(intVal, mModule->mBfIRBuilder->MapType(ptrType));
  4067. return BfTypedValue(ptrVal, ptrType);
  4068. }
  4069. }
  4070. auto identifierNode = BfNodeDynCast<BfIdentifierNode>(refNode);
  4071. if (mModule->mCurMethodState != NULL)
  4072. {
  4073. auto rootMethodState = mModule->mCurMethodState->GetRootMethodState();
  4074. auto checkMethodState = mModule->mCurMethodState;
  4075. bool isMixinOuterVariablePass = false;
  4076. while (checkMethodState != NULL)
  4077. {
  4078. BP_ZONE("LookupIdentifier:LocalVar");
  4079. BfTypeInstance* closureTypeInst = NULL;
  4080. if ((checkMethodState->mClosureState != NULL) && (checkMethodState->mClosureState->mClosureType != NULL) && (!checkMethodState->mClosureState->mCapturing))
  4081. {
  4082. closureTypeInst = mModule->mCurMethodState->mClosureState->mClosureType;
  4083. }
  4084. int varSkipCountLeft = varSkipCount;
  4085. BfLocalVarEntry* entry;
  4086. if (checkMethodState->mLocalVarSet.TryGetWith<StringImpl&>(wantName, &entry))
  4087. {
  4088. auto varDecl = entry->mLocalVar;
  4089. if (varDecl != NULL)
  4090. varSkipCountLeft -= varDecl->mNamePrefixCount;
  4091. while ((varSkipCountLeft > 0) && (varDecl != NULL))
  4092. {
  4093. varDecl = varDecl->mShadowedLocal;
  4094. varSkipCountLeft--;
  4095. }
  4096. if ((varDecl != NULL) && (varDecl->mNotCaptured))
  4097. {
  4098. mModule->Fail("Local variable is not captured", refNode);
  4099. }
  4100. if ((varSkipCountLeft == 0) && (varDecl != NULL))
  4101. {
  4102. if ((closureTypeInst != NULL) && (wantName == "this"))
  4103. break;
  4104. if (varDecl->mResolvedType->IsVoid())
  4105. {
  4106. if ((varDecl->mIsReadOnly) && (varDecl->mParamIdx == -2) && (varDecl->mParamFailed))
  4107. {
  4108. BF_ASSERT(mModule->mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_CtorCalcAppend);
  4109. mModule->Fail("The result of append allocations cannot be used in append size calculation methods. Consider moving all append allocations to the start of this method body.", refNode);
  4110. }
  4111. }
  4112. if (!varDecl->mIsThis)
  4113. mModule->SetElementType(identifierNode, (varDecl->IsParam()) ? BfSourceElementType_Parameter : BfSourceElementType_Local);
  4114. BfTypedValue localResult = LoadLocal(varDecl);
  4115. if ((localResult) && (localResult.mType->IsParamsType()) && ((mBfEvalExprFlags & BfEvalExprFlags_AllowParamsExpr) == 0))
  4116. {
  4117. localResult = mModule->LoadOrAggregateValue(localResult);
  4118. }
  4119. auto autoComplete = GetAutoComplete();
  4120. if (identifierNode != NULL)
  4121. {
  4122. if (autoComplete != NULL)
  4123. autoComplete->CheckLocalRef(identifierNode, varDecl);
  4124. if (((mModule->mCurMethodState->mClosureState == NULL) || (mModule->mCurMethodState->mClosureState->mCapturing)) &&
  4125. (mModule->mCompiler->mResolvePassData != NULL) && (mModule->mCurMethodInstance != NULL) && (!mModule->mCurMethodState->IsTemporary()))
  4126. mModule->mCompiler->mResolvePassData->HandleLocalReference(identifierNode, varDecl->mNameNode, mModule->mCurTypeInstance->mTypeDef, rootMethodState->mMethodInstance->mMethodDef, varDecl->mLocalVarId);
  4127. }
  4128. if (!isMixinOuterVariablePass)
  4129. {
  4130. mResultLocalVar = varDecl;
  4131. mResultFieldInstance = NULL;
  4132. mResultLocalVarRefNode = identifierNode;
  4133. }
  4134. return localResult;
  4135. }
  4136. }
  4137. // Check for the captured locals. It's important we do it here so we get local-first precedence still
  4138. if (closureTypeInst != NULL)
  4139. {
  4140. int varSkipCountLeft = varSkipCount;
  4141. closureTypeInst->mTypeDef->PopulateMemberSets();
  4142. BfMemberSetEntry* memberSetEntry = NULL;
  4143. if (closureTypeInst->mTypeDef->mFieldSet.TryGetWith((StringImpl&)findName, &memberSetEntry))
  4144. {
  4145. auto fieldDef = (BfFieldDef*)memberSetEntry->mMemberDef;
  4146. auto& field = closureTypeInst->mFieldInstances[fieldDef->mIdx];
  4147. if (!field.mResolvedType->IsValuelessType())
  4148. {
  4149. if (mModule->mCurMethodState->mClosureState->mCapturing)
  4150. {
  4151. mModule->mCurMethodState->mClosureState->mReferencedOuterClosureMembers.Add(&field);
  4152. return mModule->GetDefaultTypedValue(field.mResolvedType);
  4153. }
  4154. auto localVar = mModule->mCurMethodState->mLocals[0];
  4155. auto thisValue = localVar->mValue;
  4156. mModule->mBfIRBuilder->PopulateType(localVar->mResolvedType);
  4157. BfTypedValue result = BfTypedValue(mModule->mBfIRBuilder->CreateInBoundsGEP(thisValue, 0, field.mDataIdx), field.mResolvedType, true);
  4158. if (field.mResolvedType->IsRef())
  4159. {
  4160. auto refType = (BfRefType*)field.mResolvedType;
  4161. auto underlyingType = refType->GetUnderlyingType();
  4162. result = BfTypedValue(mModule->mBfIRBuilder->CreateLoad(result.mValue), underlyingType, true);
  4163. }
  4164. else if (fieldDef->mIsReadOnly)
  4165. result = mModule->LoadValue(result);
  4166. //mModule->SetElementType(identifierNode, (localVar->IsParam()) ? BfSourceElementType_Parameter : BfSourceElementType_Local);
  4167. mResultLocalVar = localVar;
  4168. mResultFieldInstance = &field;
  4169. mResultLocalVarField = -(field.mMergedDataIdx + 1);
  4170. return result;
  4171. }
  4172. }
  4173. }
  4174. if ((checkMethodState->mClosureState != NULL) && (checkMethodState->mClosureState->mCapturing) /*&& (checkMethodState->mClosureState->mIsLocalMethod)*/)
  4175. {
  4176. checkMethodState = checkMethodState->mPrevMethodState;
  4177. continue;
  4178. }
  4179. // Allow local mixin to see outside variables during its processing -- since we don't actually "capture" those into params
  4180. bool isLocalMixinProcessing = false;
  4181. if ((checkMethodState->mClosureState != NULL) && (!checkMethodState->mClosureState->mCapturing) && (closureTypeInst == NULL) &&
  4182. (mModule->mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_Mixin))
  4183. isLocalMixinProcessing = true;
  4184. if (!isLocalMixinProcessing)
  4185. break;
  4186. isMixinOuterVariablePass = true;
  4187. checkMethodState = checkMethodState->mPrevMethodState;
  4188. }
  4189. }
  4190. if ((mModule->mCurMethodInstance == NULL) && (mModule->mCurTypeInstance != NULL) && (mModule->mCurTypeInstance->IsEnum()))
  4191. {
  4192. if (findName == "_")
  4193. {
  4194. BfFieldDef* resolvingFieldDef = NULL;
  4195. auto checkTypeState = mModule->mContext->mCurTypeState;
  4196. while (checkTypeState != NULL)
  4197. {
  4198. if (checkTypeState->mCurFieldDef != NULL)
  4199. {
  4200. if (checkTypeState->mType == mModule->mCurTypeInstance)
  4201. resolvingFieldDef = checkTypeState->mCurFieldDef;
  4202. }
  4203. checkTypeState = checkTypeState->mPrevState;
  4204. }
  4205. if ((resolvingFieldDef != NULL) &&
  4206. (mModule->mCompiler->mResolvePassData != NULL) &&
  4207. (!mModule->mCompiler->mResolvePassData->mParsers.IsEmpty()) &&
  4208. (mModule->mCompiler->mResolvePassData->mParsers[0] == resolvingFieldDef->mFieldDeclaration->GetParser()) &&
  4209. (GetAutoComplete() != NULL))
  4210. {
  4211. return mModule->GetDefaultTypedValue(mModule->mCurTypeInstance);
  4212. }
  4213. else if ((resolvingFieldDef != NULL) && (resolvingFieldDef->mIdx > 0))
  4214. {
  4215. auto enumType = mModule->mCurTypeInstance;
  4216. if (!enumType->mFieldInstances.IsEmpty())
  4217. {
  4218. auto fieldInstance = &mModule->mCurTypeInstance->mFieldInstances[resolvingFieldDef->mIdx - 1];
  4219. if ((fieldInstance->mConstIdx != -1) &&
  4220. (fieldInstance->mResolvedType == mModule->mCurTypeInstance))
  4221. {
  4222. auto foreignConst = enumType->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
  4223. auto retVal = mModule->ConstantToCurrent(foreignConst, enumType->mConstHolder, enumType);
  4224. return BfTypedValue(retVal, enumType);
  4225. }
  4226. }
  4227. }
  4228. }
  4229. }
  4230. BfTypedValue thisValue = mModule->GetThis(false);
  4231. bool forcedIFaceLookup = false;
  4232. if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsForeignMethodDef))
  4233. {
  4234. thisValue.mType = mModule->mCurMethodInstance->GetForeignType();
  4235. forcedIFaceLookup = true;
  4236. }
  4237. if (thisValue)
  4238. {
  4239. if (findName == "this")
  4240. {
  4241. mModule->MarkUsingThis();
  4242. return thisValue;
  4243. }
  4244. if (findName == "base")
  4245. {
  4246. auto baseValue = thisValue;
  4247. if (baseValue.IsThis())
  4248. baseValue.ToBase();
  4249. if (mModule->GetActiveTypeDef()->mTypeCode != BfTypeCode_Extension)
  4250. {
  4251. MakeBaseConcrete(baseValue);
  4252. }
  4253. mModule->MarkUsingThis();
  4254. return baseValue;
  4255. }
  4256. if (!mModule->mCurMethodState->HasNonStaticMixin())
  4257. {
  4258. mResultLocalVar = mModule->GetThisVariable();
  4259. mResultFieldInstance = NULL;
  4260. mResultLocalVarRefNode = identifierNode;
  4261. }
  4262. }
  4263. if (!thisValue.HasType())
  4264. {
  4265. if ((mModule->mContext->mCurTypeState != NULL) && (mModule->mContext->mCurTypeState->mType == mModule->mCurTypeInstance) &&
  4266. (mModule->mContext->mCurTypeState->mResolveKind == BfTypeState::ResolveKind_Attributes))
  4267. {
  4268. // Can't do static lookups yet
  4269. }
  4270. else
  4271. thisValue = BfTypedValue(mModule->mCurTypeInstance);
  4272. }
  4273. BfTypedValue result;
  4274. if (thisValue.HasType())
  4275. {
  4276. result = LookupField(identifierNode, thisValue, findName, BfLookupFieldFlag_IsImplicitThis);
  4277. if (mResultFieldInstance == NULL)
  4278. {
  4279. mResultLocalVar = NULL;
  4280. mResultLocalVarRefNode = NULL;
  4281. }
  4282. }
  4283. if (mPropDef != NULL)
  4284. {
  4285. if (forcedIFaceLookup)
  4286. {
  4287. if (mPropTarget == thisValue)
  4288. {
  4289. mPropDefBypassVirtual = true;
  4290. mOrigPropTarget = mModule->GetThis();
  4291. }
  4292. }
  4293. }
  4294. if ((!result) && (mPropDef == NULL))
  4295. {
  4296. if (mModule->mContext->mCurTypeState != NULL)
  4297. {
  4298. // This is not necessarily true since we changed ConstResolver
  4299. //BF_ASSERT(mModule->mCurTypeInstance == mModule->mContext->mCurTypeState->mTypeInstance);
  4300. BfGlobalLookup globalLookup;
  4301. globalLookup.mKind = BfGlobalLookup::Kind_Field;
  4302. globalLookup.mName = findName;
  4303. mModule->PopulateGlobalContainersList(globalLookup);
  4304. for (auto& globalContainer : mModule->mContext->mCurTypeState->mGlobalContainers)
  4305. {
  4306. if (globalContainer.mTypeInst == NULL)
  4307. continue;
  4308. thisValue = BfTypedValue(globalContainer.mTypeInst);
  4309. result = LookupField(identifierNode, thisValue, findName);
  4310. if ((result) || (mPropDef != NULL))
  4311. {
  4312. mModule->SetHighestElementType(identifierNode, BfSourceElementType_Member);
  4313. return result;
  4314. }
  4315. }
  4316. }
  4317. auto staticSearch = mModule->GetStaticSearch();
  4318. if (staticSearch != NULL)
  4319. {
  4320. for (auto typeInst : staticSearch->mStaticTypes)
  4321. {
  4322. thisValue = BfTypedValue(typeInst);
  4323. result = LookupField(identifierNode, thisValue, findName);
  4324. if ((result) || (mPropDef != NULL))
  4325. {
  4326. mModule->SetHighestElementType(identifierNode, BfSourceElementType_Member);
  4327. return result;
  4328. }
  4329. }
  4330. }
  4331. }
  4332. else
  4333. {
  4334. mModule->SetHighestElementType(identifierNode, BfSourceElementType_Member);
  4335. }
  4336. if ((!result) && (identifierNode != NULL))
  4337. {
  4338. result = mModule->TryLookupGenericConstVaue(identifierNode, mExpectingType);
  4339. if ((mBfEvalExprFlags & (BfEvalExprFlags_Comptime | BfEvalExprFlags_AllowGenericConstValue)) == BfEvalExprFlags_Comptime)
  4340. {
  4341. if (result.mKind == BfTypedValueKind_GenericConstValue)
  4342. {
  4343. auto genericParamDef = mModule->GetGenericParamInstance((BfGenericParamType*)result.mType);
  4344. if ((genericParamDef->mGenericParamFlags & BfGenericParamFlag_Const) != 0)
  4345. {
  4346. auto genericTypeConstraint = genericParamDef->mTypeConstraint;
  4347. if (genericTypeConstraint != NULL)
  4348. {
  4349. auto primType = genericTypeConstraint->ToPrimitiveType();
  4350. if (primType != NULL)
  4351. {
  4352. BfTypedValue result;
  4353. result.mKind = BfTypedValueKind_Value;
  4354. result.mType = genericTypeConstraint;
  4355. result.mValue = mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->GetPrimitiveType(primType->mTypeDef->mTypeCode));
  4356. return result;
  4357. }
  4358. }
  4359. else
  4360. {
  4361. BF_FATAL("Error");
  4362. }
  4363. }
  4364. }
  4365. }
  4366. mModule->FixValueActualization(result);
  4367. }
  4368. if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) && (findName == "@this"))
  4369. {
  4370. if (mModule->mCurMethodState->mClosureState->mCapturing)
  4371. {
  4372. if (mModule->mCurMethodState->mClosureState->mDelegateType != NULL)
  4373. {
  4374. mModule->mCurMethodState->mClosureState->mCapturedDelegateSelf = true;
  4375. return mModule->GetDefaultTypedValue(mModule->mCurMethodState->mClosureState->mDelegateType);
  4376. }
  4377. }
  4378. else
  4379. {
  4380. if (!mModule->mCurMethodState->mLocals.IsEmpty())
  4381. {
  4382. auto thisLocal = mModule->mCurMethodState->mLocals[0];
  4383. if (thisLocal->mIsThis)
  4384. {
  4385. if (thisLocal->mAddr)
  4386. return BfTypedValue(mModule->mBfIRBuilder->CreateLoad(thisLocal->mAddr), thisLocal->mResolvedType);
  4387. else
  4388. return BfTypedValue(thisLocal->mValue, thisLocal->mResolvedType);
  4389. }
  4390. }
  4391. }
  4392. }
  4393. return result;
  4394. }
  4395. BfTypedValue BfExprEvaluator::LookupIdentifier(BfIdentifierNode* identifierNode, bool ignoreInitialError, bool* hadError)
  4396. {
  4397. auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(identifierNode);
  4398. if (qualifiedNameNode != NULL)
  4399. {
  4400. LookupQualifiedName(qualifiedNameNode, ignoreInitialError, hadError);
  4401. auto qualifiedResult = mResult;
  4402. mResult = BfTypedValue();
  4403. return qualifiedResult;
  4404. }
  4405. StringT<128> identifierStr;
  4406. identifierNode->ToString(identifierStr);
  4407. return LookupIdentifier(identifierNode, identifierStr, ignoreInitialError, hadError);
  4408. }
  4409. void BfExprEvaluator::Visit(BfIdentifierNode* identifierNode)
  4410. {
  4411. auto autoComplete = GetAutoComplete();
  4412. if (autoComplete != NULL)
  4413. autoComplete->CheckIdentifier(identifierNode, true);
  4414. mResult = LookupIdentifier(identifierNode);
  4415. if ((!mResult) && (mPropDef == NULL))
  4416. {
  4417. mModule->CheckTypeRefFixit(identifierNode);
  4418. if ((autoComplete != NULL) && (autoComplete->CheckFixit(identifierNode)))
  4419. {
  4420. if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mCapturing))
  4421. {
  4422. // During this phase we don't have lambda and local method params available so they would result in erroneous fixits
  4423. }
  4424. else if (mModule->mCurMethodInstance != NULL)
  4425. {
  4426. BfType* fieldType = mExpectingType;
  4427. if (fieldType == NULL)
  4428. fieldType = mModule->mContext->mBfObjectType;
  4429. autoComplete->FixitAddMember(mModule->mCurTypeInstance, fieldType, identifierNode->ToString(), true, mModule->mCurTypeInstance);
  4430. if (!mModule->mCurMethodInstance->mMethodDef->mIsStatic)
  4431. autoComplete->FixitAddMember(mModule->mCurTypeInstance, fieldType, identifierNode->ToString(), false, mModule->mCurTypeInstance);
  4432. for (auto typeDef : mModule->mSystem->mTypeDefs)
  4433. {
  4434. if (!typeDef->mIsCombinedPartial)
  4435. continue;
  4436. if (!typeDef->IsGlobalsContainer())
  4437. continue;
  4438. typeDef->PopulateMemberSets();
  4439. String findName = identifierNode->ToString();
  4440. BfMemberSetEntry* memberSetEntry;
  4441. if ((typeDef->mMethodSet.TryGetWith(findName, &memberSetEntry)) ||
  4442. (typeDef->mFieldSet.TryGetWith(findName, &memberSetEntry)) ||
  4443. (typeDef->mPropertySet.TryGetWith(findName, &memberSetEntry)))
  4444. {
  4445. if (mModule->GetActiveTypeDef()->mProject->ContainsReference(typeDef->mProject))
  4446. autoComplete->FixitAddNamespace(identifierNode, typeDef->mNamespace.ToString());
  4447. }
  4448. }
  4449. }
  4450. }
  4451. if (((mBfEvalExprFlags & BfEvalExprFlags_NameOf) != 0) && (mModule->mCurTypeInstance != NULL) && (CheckForMethodName(identifierNode, mModule->mCurTypeInstance, identifierNode->ToString())))
  4452. return;
  4453. if ((mBfEvalExprFlags & BfEvalExprFlags_NoLookupError) == 0)
  4454. mModule->Fail("Identifier not found", identifierNode);
  4455. }
  4456. }
  4457. void BfExprEvaluator::Visit(BfAttributedIdentifierNode* attrIdentifierNode)
  4458. {
  4459. if ((mModule->mAttributeState != NULL))
  4460. {
  4461. mModule->mAttributeState->mCustomAttributes = mModule->GetCustomAttributes(attrIdentifierNode->mAttributes, mModule->mAttributeState->mTarget);
  4462. VisitChild(attrIdentifierNode->mIdentifier);
  4463. }
  4464. else
  4465. {
  4466. BfAttributeState attributeState;
  4467. attributeState.mTarget = (BfAttributeTargets)(BfAttributeTargets_MemberAccess);
  4468. SetAndRestoreValue<BfAttributeState*> prevAttributeState(mModule->mAttributeState, &attributeState);
  4469. mModule->mAttributeState->mCustomAttributes = mModule->GetCustomAttributes(attrIdentifierNode->mAttributes, mModule->mAttributeState->mTarget);
  4470. VisitChild(attrIdentifierNode->mIdentifier);
  4471. }
  4472. }
  4473. static int gPropIdx = 0;
  4474. void BfExprEvaluator::FixitAddMember(BfTypeInstance* typeInst, BfType* fieldType, const StringImpl& fieldName, bool isStatic)
  4475. {
  4476. if (fieldType == NULL)
  4477. {
  4478. fieldType = mExpectingType;
  4479. }
  4480. if (fieldType != NULL)
  4481. {
  4482. if (fieldType->IsRef())
  4483. fieldType = fieldType->GetUnderlyingType();
  4484. }
  4485. mModule->mCompiler->mResolvePassData->mAutoComplete->FixitAddMember(typeInst, fieldType, fieldName, isStatic, mModule->mCurTypeInstance);
  4486. }
  4487. BfTypedValue BfExprEvaluator::TryArrowLookup(BfTypedValue typedValue, BfTokenNode* arrowToken)
  4488. {
  4489. auto arrowValue = PerformUnaryOperation_TryOperator(typedValue, NULL, BfUnaryOp_Arrow, arrowToken, BfUnaryOpFlag_None);
  4490. if (arrowValue)
  4491. return arrowValue;
  4492. if (mModule->PreFail())
  4493. mModule->Fail(StrFormat("Type '%s' does not contain a '->' operator", mModule->TypeToString(typedValue.mType).c_str()), arrowToken);
  4494. return typedValue;
  4495. }
  4496. BfTypedValue BfExprEvaluator::LoadProperty(BfAstNode* targetSrc, BfTypedValue target, BfTypeInstance* typeInstance, BfPropertyDef* prop, BfLookupFieldFlags flags, BfCheckedKind checkedKind, bool isInlined)
  4497. {
  4498. BfTypedValue origTarget = target;
  4499. if ((target.mType != NULL) && (target.mType->IsStructPtr()))
  4500. {
  4501. target = mModule->LoadValue(target);
  4502. target = BfTypedValue(target.mValue, target.mType->GetUnderlyingType(), target.IsReadOnly() ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
  4503. }
  4504. if ((flags & BfLookupFieldFlag_IsAnonymous) == 0)
  4505. mModule->SetElementType(targetSrc, BfSourceElementType_Method);
  4506. if ((!prop->mIsStatic) && ((flags & BfLookupFieldFlag_IsImplicitThis) != 0))
  4507. mModule->MarkUsingThis();
  4508. mPropSrc = targetSrc;
  4509. mPropDef = prop;
  4510. mPropCheckedKind = checkedKind;
  4511. if (isInlined)
  4512. mPropGetMethodFlags = (BfGetMethodInstanceFlags)(mPropGetMethodFlags | BfGetMethodInstanceFlag_ForceInline);
  4513. if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL))
  4514. {
  4515. if (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mFriendAttributeTypeDef))
  4516. {
  4517. mPropGetMethodFlags = (BfGetMethodInstanceFlags)(mPropGetMethodFlags | BfGetMethodInstanceFlag_Friend);
  4518. mModule->mAttributeState->mUsed = true;
  4519. }
  4520. if (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mDisableObjectAccessChecksAttributeTypeDef))
  4521. {
  4522. mPropGetMethodFlags = (BfGetMethodInstanceFlags)(mPropGetMethodFlags | BfGetMethodInstanceFlag_DisableObjectAccessChecks);
  4523. mModule->mAttributeState->mUsed = true;
  4524. }
  4525. }
  4526. if (mPropDef->mIsStatic)
  4527. {
  4528. if ((target) && ((flags & BfLookupFieldFlag_IsImplicitThis) == 0) && (!typeInstance->mTypeDef->IsGlobalsContainer()))
  4529. {
  4530. //CS0176: Member 'Program.sVal' cannot be accessed with an instance reference; qualify it with a type name instead
  4531. mModule->Fail(StrFormat("Property '%s.%s' cannot be accessed with an instance reference; qualify it with a type name instead",
  4532. mModule->TypeToString(typeInstance).c_str(), mPropDef->mName.c_str()), targetSrc);
  4533. }
  4534. }
  4535. bool isBaseLookup = (target.mType) && (typeInstance != target.mType);
  4536. if ((isBaseLookup) && (target.mType->IsWrappableType()))
  4537. isBaseLookup = false;
  4538. if (prop->mIsStatic)
  4539. mPropTarget = BfTypedValue(typeInstance);
  4540. else if (isBaseLookup)
  4541. {
  4542. if (target.mValue.IsFake())
  4543. {
  4544. mPropTarget = BfTypedValue(target.mValue, typeInstance, target.mKind);
  4545. }
  4546. else
  4547. {
  4548. mPropTarget = mModule->Cast(targetSrc, target, typeInstance);
  4549. BF_ASSERT(mPropTarget);
  4550. }
  4551. }
  4552. else
  4553. mPropTarget = target;
  4554. mOrigPropTarget = mPropTarget;
  4555. if (prop->mIsStatic)
  4556. mOrigPropTarget = target;
  4557. #ifdef _DEBUG
  4558. if (mPropTarget)
  4559. {
  4560. auto propTargetTypeInst = mPropTarget.mType->ToTypeInstance();
  4561. if (propTargetTypeInst != NULL)
  4562. {
  4563. BF_ASSERT(prop->mDeclaringType->mFullNameEx == propTargetTypeInst->mTypeDef->mFullNameEx);
  4564. }
  4565. }
  4566. #endif
  4567. if ((flags & BfLookupFieldFlag_IsAnonymous) == 0)
  4568. {
  4569. auto autoComplete = GetAutoComplete();
  4570. auto resolvePassData = mModule->mCompiler->mResolvePassData;
  4571. if (((autoComplete != NULL) && (autoComplete->mIsGetDefinition)) ||
  4572. ((resolvePassData != NULL) && (resolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Property)))
  4573. {
  4574. BfPropertyDef* basePropDef = mPropDef;
  4575. BfTypeInstance* baseTypeInst = typeInstance;
  4576. mModule->GetBasePropertyDef(basePropDef, baseTypeInst);
  4577. resolvePassData->HandlePropertyReference(targetSrc, baseTypeInst->mTypeDef, basePropDef);
  4578. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(targetSrc)))
  4579. {
  4580. if (autoComplete->mIsGetDefinition)
  4581. {
  4582. //NOTE: passing 'force=true' in here causes https://github.com/beefytech/Beef/issues/1064
  4583. autoComplete->SetDefinitionLocation(basePropDef->GetRefNode());
  4584. }
  4585. autoComplete->mDefProp = basePropDef;
  4586. autoComplete->mDefType = baseTypeInst->mTypeDef;
  4587. }
  4588. }
  4589. if ((autoComplete != NULL) && (autoComplete->mResolveType == BfResolveType_GetResultString) && (autoComplete->IsAutocompleteNode(targetSrc)))
  4590. {
  4591. BfPropertyDef* basePropDef = mPropDef;
  4592. BfTypeInstance* baseTypeInst = typeInstance;
  4593. mModule->GetBasePropertyDef(basePropDef, baseTypeInst);
  4594. autoComplete->mResultString = ":";
  4595. autoComplete->mResultString += mModule->TypeToString(baseTypeInst);
  4596. autoComplete->mResultString += ".";
  4597. autoComplete->mResultString += basePropDef->mName;
  4598. }
  4599. }
  4600. // Check for direct auto-property access
  4601. if ((target.mType == mModule->mCurTypeInstance) && ((flags & BfLookupFieldFlag_BindOnly) == 0))
  4602. {
  4603. if (auto propertyDeclaration = BfNodeDynCast<BfPropertyDeclaration>(mPropDef->mFieldDeclaration))
  4604. {
  4605. if ((typeInstance->mTypeDef->HasAutoProperty(propertyDeclaration)) && (propertyDeclaration->mVirtualSpecifier == NULL))
  4606. {
  4607. BfMethodDef* getter = GetPropertyMethodDef(mPropDef, BfMethodType_PropertyGetter, BfCheckedKind_NotSet, mPropTarget);
  4608. BfMethodDef* setter = GetPropertyMethodDef(mPropDef, BfMethodType_PropertySetter, BfCheckedKind_NotSet, mPropTarget);
  4609. bool optAllowed = true;
  4610. if ((getter != NULL) && (getter->mBody != NULL))
  4611. optAllowed = false;
  4612. if ((setter != NULL) && (setter->mBody != NULL))
  4613. optAllowed = false;
  4614. if (optAllowed)
  4615. {
  4616. auto autoFieldName = typeInstance->mTypeDef->GetAutoPropertyName(propertyDeclaration);
  4617. auto result = LookupField(targetSrc, target, autoFieldName, (BfLookupFieldFlags)(BfLookupFieldFlag_IgnoreProtection | BfLookupFieldFlag_IsImplicitThis));
  4618. if (result)
  4619. {
  4620. bool needsCopy = true;
  4621. if (BfNodeIsA<BfRefTypeRef>(prop->mTypeRef))
  4622. {
  4623. // Allow full ref
  4624. }
  4625. else
  4626. {
  4627. if (setter == NULL)
  4628. {
  4629. if (((mModule->mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_Ctor)) &&
  4630. (target.mType == mModule->mCurTypeInstance))
  4631. {
  4632. // Allow writing inside ctor
  4633. }
  4634. else
  4635. {
  4636. result.MakeReadOnly();
  4637. needsCopy = false;
  4638. }
  4639. }
  4640. if (result.mKind == BfTypedValueKind_Addr)
  4641. result.mKind = BfTypedValueKind_CopyOnMutateAddr;
  4642. }
  4643. mPropDef = NULL;
  4644. mPropSrc = NULL;
  4645. mOrigPropTarget = BfTypedValue();
  4646. return result;
  4647. }
  4648. }
  4649. }
  4650. }
  4651. }
  4652. if (!mPropDef->mIsStatic)
  4653. {
  4654. SetAndRestoreValue<BfTypedValue> prevResult(mResult, target);
  4655. CheckResultForReading(mResult);
  4656. }
  4657. return BfTypedValue();
  4658. }
  4659. BfTypedValue BfExprEvaluator::LoadField(BfAstNode* targetSrc, BfTypedValue target, BfTypeInstance* typeInstance, BfFieldDef* fieldDef, BfLookupFieldFlags flags)
  4660. {
  4661. if (fieldDef->mIsProperty)
  4662. {
  4663. BfPropertyDef* propDef = (BfPropertyDef*)fieldDef;
  4664. return LoadProperty(targetSrc, target, typeInstance, propDef, flags, BfCheckedKind_NotSet, false);
  4665. }
  4666. bool isFailurePass = (flags & BfLookupFieldFlag_IsFailurePass) != 0;
  4667. auto fieldInstance = &typeInstance->mFieldInstances[fieldDef->mIdx];
  4668. bool isResolvingFields = typeInstance->mResolvingConstField || typeInstance->mResolvingVarField;
  4669. if (typeInstance->mDefineState < BfTypeDefineState_Defined)
  4670. {
  4671. // Check for cases like a member like 'uint8[sizeof(decltype(PrevMember))] NextMember;'
  4672. auto checkTypeState = mModule->mContext->mCurTypeState;
  4673. while (checkTypeState != NULL)
  4674. {
  4675. if ((checkTypeState->mType == typeInstance) && (checkTypeState->mResolveKind == BfTypeState::ResolveKind_FieldType))
  4676. isResolvingFields = true;
  4677. checkTypeState = checkTypeState->mPrevState;
  4678. }
  4679. }
  4680. if (fieldDef->mIsVolatile)
  4681. mIsVolatileReference = true;
  4682. if (fieldInstance->mCustomAttributes != NULL)
  4683. mModule->CheckErrorAttributes(fieldInstance->mOwner, NULL, fieldInstance, fieldInstance->mCustomAttributes, targetSrc);
  4684. if (isFailurePass)
  4685. {
  4686. if (mModule->GetCeDbgState() == NULL)
  4687. mModule->Fail(StrFormat("'%s.%s' is inaccessible due to its protection level", mModule->TypeToString(typeInstance).c_str(), fieldDef->mName.c_str()), targetSrc);
  4688. }
  4689. auto resolvePassData = mModule->mCompiler->mResolvePassData;
  4690. if ((resolvePassData != NULL) && (resolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Field) && ((flags & BfLookupFieldFlag_IsAnonymous) == 0))
  4691. {
  4692. resolvePassData->HandleFieldReference(targetSrc, typeInstance->mTypeDef, fieldDef);
  4693. }
  4694. if ((!typeInstance->mTypeFailed) && (!isResolvingFields) && (typeInstance->IsIncomplete()))
  4695. {
  4696. if ((fieldInstance->mResolvedType == NULL) ||
  4697. (!fieldDef->mIsStatic))
  4698. {
  4699. mModule->PopulateType(typeInstance, BfPopulateType_Data);
  4700. // Update fieldInstance pointer as it may have moved
  4701. fieldInstance = &typeInstance->mFieldInstances[fieldDef->mIdx];
  4702. }
  4703. }
  4704. if (fieldInstance->mResolvedType == NULL)
  4705. {
  4706. if (mModule->mCompiler->EnsureCeUnpaused(typeInstance))
  4707. {
  4708. BF_ASSERT((typeInstance->mTypeFailed) || (isResolvingFields));
  4709. }
  4710. return BfTypedValue();
  4711. }
  4712. if (fieldInstance->mFieldIdx == -1)
  4713. {
  4714. mModule->AssertErrorState();
  4715. return BfTypedValue();
  4716. }
  4717. if ((!fieldDef->mIsStatic) && ((flags & BfLookupFieldFlag_IsImplicitThis) != 0))
  4718. mModule->MarkUsingThis();
  4719. mResultFieldInstance = fieldInstance;
  4720. // Are we accessing a 'var' field that has not yet been resolved?
  4721. if (IsVar(fieldInstance->mResolvedType))
  4722. {
  4723. // This can happen if we have one var field referencing another var field
  4724. fieldInstance->mResolvedType = mModule->ResolveVarFieldType(typeInstance, fieldInstance, fieldDef);
  4725. if (fieldInstance->mResolvedType == NULL)
  4726. return BfTypedValue();
  4727. }
  4728. auto resolvedFieldType = fieldInstance->mResolvedType;
  4729. if (fieldInstance->mIsEnumPayloadCase)
  4730. {
  4731. resolvedFieldType = typeInstance;
  4732. }
  4733. mModule->PopulateType(resolvedFieldType, BfPopulateType_Data);
  4734. mModule->AddDependency(typeInstance, mModule->mCurTypeInstance, fieldDef->mIsConst ? BfDependencyMap::DependencyFlag_ConstValue : BfDependencyMap::DependencyFlag_ReadFields);
  4735. if (fieldInstance->mHadConstEval)
  4736. {
  4737. mModule->AddDependency(typeInstance, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ConstEvalConstField);
  4738. if ((mModule->mContext->mCurTypeState != NULL) && (mModule->mContext->mCurTypeState->mCurFieldDef != NULL))
  4739. {
  4740. // If we're initializing another const field then also set it as having const eval
  4741. auto resolvingFieldInstance = &mModule->mContext->mCurTypeState->mType->ToTypeInstance()->mFieldInstances[mModule->mContext->mCurTypeState->mCurFieldDef->mIdx];
  4742. if (resolvingFieldInstance->GetFieldDef()->mIsConst)
  4743. resolvingFieldInstance->mHadConstEval = true;
  4744. }
  4745. }
  4746. if ((flags & BfLookupFieldFlag_IsAnonymous) == 0)
  4747. {
  4748. auto autoComplete = GetAutoComplete();
  4749. if (autoComplete != NULL)
  4750. {
  4751. autoComplete->CheckFieldRef(BfNodeDynCast<BfIdentifierNode>(targetSrc), fieldInstance);
  4752. if ((autoComplete->mResolveType == BfResolveType_GetResultString) && (autoComplete->IsAutocompleteNode(targetSrc)))
  4753. {
  4754. autoComplete->mResultString = ":";
  4755. autoComplete->mResultString += mModule->TypeToString(fieldInstance->mResolvedType);
  4756. autoComplete->mResultString += " ";
  4757. autoComplete->mResultString += mModule->TypeToString(typeInstance);
  4758. autoComplete->mResultString += ".";
  4759. autoComplete->mResultString += fieldDef->mName;
  4760. if (fieldInstance->mConstIdx != -1)
  4761. {
  4762. String constStr = autoComplete->ConstantToString(typeInstance->mConstHolder, BfTypedValue(BfIRValue(BfIRValueFlags_Const, fieldInstance->mConstIdx), fieldInstance->mResolvedType));
  4763. if (!constStr.IsEmpty())
  4764. {
  4765. autoComplete->mResultString += " = ";
  4766. if (constStr.StartsWith(':'))
  4767. autoComplete->mResultString.Append(StringView(constStr, 1, constStr.mLength - 1));
  4768. else
  4769. autoComplete->mResultString += constStr;
  4770. }
  4771. }
  4772. auto fieldDecl = fieldInstance->GetFieldDef()->GetFieldDeclaration();
  4773. if ((fieldDecl != NULL) && (fieldDecl->mDocumentation != NULL))
  4774. {
  4775. String docString;
  4776. fieldDecl->mDocumentation->GetDocString(docString);
  4777. autoComplete->mResultString += "\x03";
  4778. autoComplete->mResultString += docString;
  4779. }
  4780. }
  4781. }
  4782. }
  4783. if (fieldDef->mIsStatic)
  4784. {
  4785. if (target)
  4786. {
  4787. //BF_ASSERT((flags & BfLookupFieldFlag_HasInstance) != 0);
  4788. flags = (BfLookupFieldFlags)(flags | BfLookupFieldFlag_HasInstance);
  4789. }
  4790. if (((flags & BfLookupFieldFlag_HasInstance) != 0) && ((flags & BfLookupFieldFlag_IsImplicitThis) == 0) && (!typeInstance->mTypeDef->IsGlobalsContainer()))
  4791. {
  4792. //CS0176: Member 'Program.sVal' cannot be accessed with an instance reference; qualify it with a type name instead
  4793. mModule->Fail(StrFormat("Member '%s.%s' cannot be accessed with an instance reference; qualify it with a type name instead",
  4794. mModule->TypeToString(typeInstance).c_str(), fieldDef->mName.c_str()), targetSrc);
  4795. }
  4796. // Target must be an implicit 'this', or an error (accessing a static with a non-static target).
  4797. // Not actually needed in either case since this is a static lookup.
  4798. mResultLocalVar = NULL;
  4799. }
  4800. bool isConst = false;
  4801. if (fieldDef->mIsConst)
  4802. {
  4803. isConst = true;
  4804. auto fieldDef = fieldInstance->GetFieldDef();
  4805. if ((resolvedFieldType->IsPointer()) && (fieldDef->mIsExtern))
  4806. isConst = false;
  4807. }
  4808. if (isConst)
  4809. {
  4810. if (fieldInstance->mIsEnumPayloadCase)
  4811. {
  4812. auto dscrType = typeInstance->GetDiscriminatorType();
  4813. mModule->mBfIRBuilder->PopulateType(typeInstance);
  4814. int tagIdx = -fieldInstance->mDataIdx - 1;
  4815. if ((mBfEvalExprFlags & BfEvalExprFlags_AllowEnumId) != 0)
  4816. {
  4817. return BfTypedValue(mModule->mBfIRBuilder->CreateConst(dscrType->mTypeDef->mTypeCode, tagIdx), fieldInstance->mOwner);
  4818. }
  4819. mModule->PopulateType(fieldInstance->mOwner, BfPopulateType_Data);
  4820. if (auto fieldTypeInstance = fieldInstance->mResolvedType->ToTypeInstance())
  4821. {
  4822. bool hasFields = false;
  4823. for (auto& fieldInstance : fieldTypeInstance->mFieldInstances)
  4824. {
  4825. if (!fieldInstance.mResolvedType->IsVoid())
  4826. hasFields = true;
  4827. }
  4828. if (hasFields)
  4829. mModule->FailAfter("Enum payload arguments expected", targetSrc);
  4830. }
  4831. SizedArray<BfIRValue, 3> values;
  4832. values.Add(mModule->mBfIRBuilder->CreateConstAggZero(mModule->mBfIRBuilder->MapType(typeInstance->mBaseType)));
  4833. values.Add(mModule->GetDefaultValue(typeInstance->GetUnionInnerType()));
  4834. values.Add(mModule->mBfIRBuilder->CreateConst(dscrType->mTypeDef->mTypeCode, tagIdx));
  4835. return BfTypedValue(mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(typeInstance), values), typeInstance);
  4836. }
  4837. if (fieldInstance->mConstIdx == -1)
  4838. {
  4839. if ((mBfEvalExprFlags & BfEvalExprFlags_DeclType) != 0)
  4840. {
  4841. // We don't need a real value
  4842. return BfTypedValue(mModule->GetDefaultValue(resolvedFieldType), resolvedFieldType);
  4843. }
  4844. typeInstance->mModule->ResolveConstField(typeInstance, fieldInstance, fieldDef);
  4845. if (fieldInstance->mConstIdx == -1)
  4846. return BfTypedValue(mModule->GetDefaultValue(resolvedFieldType), resolvedFieldType);
  4847. }
  4848. BF_ASSERT(fieldInstance->mConstIdx != -1);
  4849. auto foreignConst = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
  4850. auto retVal = mModule->ConstantToCurrent(foreignConst, typeInstance->mConstHolder, resolvedFieldType);
  4851. return BfTypedValue(retVal, resolvedFieldType);
  4852. }
  4853. else if (fieldDef->mIsStatic)
  4854. {
  4855. if ((mModule->mAttributeState == NULL) || (mModule->mAttributeState->mCustomAttributes == NULL) ||
  4856. (!mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mNoStaticCtorAttributeTypeDef)))
  4857. {
  4858. mModule->CheckStaticAccess(typeInstance);
  4859. }
  4860. auto retVal = mModule->ReferenceStaticField(fieldInstance);
  4861. bool isStaticCtor = (mModule->mCurMethodInstance != NULL) &&
  4862. (mModule->mCurMethodInstance->mMethodDef->IsCtorOrInit()) &&
  4863. (mModule->mCurMethodInstance->mMethodDef->mIsStatic);
  4864. if ((mModule->mCompiler->mOptions.mRuntimeChecks) && (fieldInstance->IsAppendedObject()) && (!fieldDef->mIsStatic) && (!mModule->mBfIRBuilder->mIgnoreWrites) &&
  4865. (!mModule->IsSkippingExtraResolveChecks()))
  4866. {
  4867. auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  4868. auto intPtrType = mModule->CreatePointerType(intType);
  4869. auto intPtrVal = mModule->mBfIRBuilder->CreateBitCast(retVal.mValue, mModule->mBfIRBuilder->MapType(intPtrType));
  4870. auto intVal = mModule->mBfIRBuilder->CreateLoad(intPtrVal);
  4871. auto oobBlock = mModule->mBfIRBuilder->CreateBlock("oob", true);
  4872. auto contBlock = mModule->mBfIRBuilder->CreateBlock("cont", true);
  4873. auto cmpRes = mModule->mBfIRBuilder->CreateCmpEQ(intVal, mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0));
  4874. mModule->mBfIRBuilder->CreateCondBr(cmpRes, oobBlock, contBlock);
  4875. mModule->mBfIRBuilder->SetInsertPoint(oobBlock);
  4876. auto internalType = mModule->ResolveTypeDef(mModule->mCompiler->mInternalTypeDef);
  4877. auto oobFunc = mModule->GetMethodByName(internalType->ToTypeInstance(), "ThrowObjectNotInitialized");
  4878. if (oobFunc.mFunc)
  4879. {
  4880. if (mModule->mIsComptimeModule)
  4881. mModule->mCompiler->mCeMachine->QueueMethod(oobFunc.mMethodInstance, oobFunc.mFunc);
  4882. SizedArray<BfIRValue, 1> args;
  4883. args.push_back(mModule->GetConstValue(0));
  4884. mModule->mBfIRBuilder->CreateCall(oobFunc.mFunc, args);
  4885. mModule->mBfIRBuilder->CreateUnreachable();
  4886. }
  4887. else
  4888. {
  4889. mModule->Fail("System.Internal class must contain method 'ThrowObjectNotInitialized'", fieldDef->GetRefNode());
  4890. }
  4891. mModule->mBfIRBuilder->SetInsertPoint(contBlock);
  4892. }
  4893. if ((fieldDef->mIsReadOnly) && (!isStaticCtor))
  4894. {
  4895. if (retVal.IsAddr())
  4896. retVal.mKind = BfTypedValueKind_ReadOnlyAddr;
  4897. }
  4898. else
  4899. mIsHeapReference = true;
  4900. return retVal;
  4901. }
  4902. else if (!target)
  4903. {
  4904. if (((mBfEvalExprFlags & (BfEvalExprFlags_NameOf | BfEvalExprFlags_DeclType)) == 0) && (mModule->PreFail()))
  4905. {
  4906. if ((flags & BfLookupFieldFlag_CheckingOuter) != 0)
  4907. mModule->Fail(StrFormat("An instance reference is required to reference non-static outer field '%s.%s'", mModule->TypeToString(typeInstance).c_str(), fieldDef->mName.c_str()),
  4908. targetSrc);
  4909. else if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_CtorCalcAppend))
  4910. {
  4911. if ((mBfEvalExprFlags & BfEvalExprFlags_DeclType) == 0)
  4912. mModule->Fail(StrFormat("Cannot reference field '%s' before append allocations", fieldDef->mName.c_str()), targetSrc);
  4913. }
  4914. else
  4915. mModule->Fail(StrFormat("Cannot reference non-static field '%s' from a static method", fieldDef->mName.c_str()), targetSrc);
  4916. }
  4917. return mModule->GetDefaultTypedValue(resolvedFieldType, false, BfDefaultValueKind_Addr);
  4918. }
  4919. if (resolvedFieldType->IsValuelessType())
  4920. {
  4921. return BfTypedValue(BfIRValue::sValueless, resolvedFieldType, true);
  4922. }
  4923. if ((mResultLocalVar != NULL) && (fieldInstance->mMergedDataIdx != -1))
  4924. {
  4925. if (mResultLocalVarFieldCount != 1)
  4926. {
  4927. fieldInstance->GetDataRange(mResultLocalVarField, mResultLocalVarFieldCount);
  4928. mResultLocalVarRefNode = targetSrc;
  4929. }
  4930. }
  4931. if ((typeInstance->IsIncomplete()) && (!typeInstance->mNeedsMethodProcessing))
  4932. {
  4933. BF_ASSERT(typeInstance->mTypeFailed || (mModule->mCurMethodState == NULL) || (mModule->mCurMethodState->mTempKind != BfMethodState::TempKind_None) || (mModule->mCompiler->IsAutocomplete()));
  4934. return mModule->GetDefaultTypedValue(resolvedFieldType);
  4935. }
  4936. bool isTemporary = target.IsTempAddr();
  4937. bool wantsLoadValue = false;
  4938. bool wantsReadOnly = false;
  4939. if ((fieldDef->mIsReadOnly) && (mModule->mCurMethodInstance != NULL) && ((!mModule->mCurMethodInstance->mMethodDef->IsCtorOrInit()) || (!target.IsThis())))
  4940. wantsReadOnly = true;
  4941. bool isComposite = target.mType->IsComposite();
  4942. if ((isComposite) && (!target.mType->IsTypedPrimitive()) && (!target.IsAddr()))
  4943. isTemporary = true;
  4944. if ((isComposite) && (!target.IsAddr()))
  4945. wantsLoadValue = true;
  4946. if ((target.mType->IsWrappableType()) && (!target.mType->IsPointer()))
  4947. {
  4948. BfTypeInstance* primStructType = mModule->GetWrappedStructType(target.mType);
  4949. BfIRValue allocaInst = mModule->CreateAlloca(primStructType, true, "tmpStruct");
  4950. BfIRValue elementAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, 1);
  4951. mModule->mBfIRBuilder->CreateStore(target.mValue, elementAddr);
  4952. target = BfTypedValue(allocaInst, primStructType, true);
  4953. }
  4954. BfTypedValue targetValue;
  4955. if ((target.mType != typeInstance) && (!target.IsSplat()))
  4956. {
  4957. if ((!isComposite) || (target.IsAddr()))
  4958. targetValue = BfTypedValue(mModule->mBfIRBuilder->CreateBitCast(target.mValue, mModule->mBfIRBuilder->MapTypeInstPtr(typeInstance)), typeInstance);
  4959. else
  4960. {
  4961. BfIRValue curVal = target.mValue;
  4962. auto baseCheckType = target.mType->ToTypeInstance();
  4963. while (baseCheckType != typeInstance)
  4964. {
  4965. curVal = mModule->mBfIRBuilder->CreateExtractValue(curVal, 0);
  4966. baseCheckType = baseCheckType->mBaseType;
  4967. }
  4968. targetValue = BfTypedValue(curVal, typeInstance);
  4969. }
  4970. }
  4971. else
  4972. targetValue = target;
  4973. bool doAccessCheck = true;
  4974. if ((flags & BfLookupFieldFlag_BindOnly) != 0)
  4975. doAccessCheck = false;
  4976. if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) && (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mDisableObjectAccessChecksAttributeTypeDef)))
  4977. doAccessCheck = false;
  4978. if (target.IsThis())
  4979. {
  4980. if (!mModule->mCurMethodState->mMayNeedThisAccessCheck)
  4981. doAccessCheck = false;
  4982. }
  4983. if (doAccessCheck)
  4984. mModule->EmitObjectAccessCheck(target);
  4985. if (fieldInstance->mDataIdx < 0)
  4986. {
  4987. mModule->mCompiler->RequestExtraCompile();
  4988. mModule->InternalError("LoadField field DataIdx<0 where InstSize>0");
  4989. mModule->DeferRebuildType(typeInstance);
  4990. return mModule->GetDefaultTypedValue(resolvedFieldType);
  4991. }
  4992. BfTypedValue retVal;
  4993. if (targetValue.IsSplat())
  4994. {
  4995. retVal = mModule->ExtractValue(targetValue, fieldInstance, fieldInstance->mDataIdx);
  4996. }
  4997. else if ((target.mType->IsStruct()) && (!target.IsAddr()))
  4998. {
  4999. mModule->mBfIRBuilder->PopulateType(targetValue.mType);
  5000. retVal = BfTypedValue(mModule->mBfIRBuilder->CreateExtractValue(targetValue.mValue, fieldInstance->mDataIdx/*, fieldDef->mName*/),
  5001. resolvedFieldType);
  5002. }
  5003. else
  5004. {
  5005. mModule->mBfIRBuilder->PopulateType(typeInstance);
  5006. if ((targetValue.IsAddr()) && (!typeInstance->IsValueType()))
  5007. targetValue = mModule->LoadValue(targetValue);
  5008. if (fieldInstance->IsAppendedObject())
  5009. {
  5010. auto elemPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(targetValue.mValue, 0, fieldInstance->mDataIdx);
  5011. retVal = BfTypedValue(mModule->mBfIRBuilder->CreateBitCast(elemPtr, mModule->mBfIRBuilder->MapType(resolvedFieldType)), resolvedFieldType);
  5012. }
  5013. else
  5014. {
  5015. retVal = BfTypedValue(mModule->mBfIRBuilder->CreateInBoundsGEP(targetValue.mValue, 0, fieldInstance->mDataIdx/*, fieldDef->mName*/),
  5016. resolvedFieldType, target.IsReadOnly() ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
  5017. }
  5018. }
  5019. if (typeInstance->mIsUnion)
  5020. {
  5021. auto unionInnerType = typeInstance->GetUnionInnerType();
  5022. if (unionInnerType != resolvedFieldType)
  5023. {
  5024. BfTypedValue unionTypedValue = retVal;
  5025. unionTypedValue.mType = unionInnerType;
  5026. if (!unionTypedValue.IsAddr())
  5027. unionTypedValue = mModule->MakeAddressable(unionTypedValue);
  5028. BfIRType llvmPtrType = mModule->mBfIRBuilder->GetPointerTo(mModule->mBfIRBuilder->MapType(resolvedFieldType));
  5029. retVal.mValue = mModule->mBfIRBuilder->CreateBitCast(unionTypedValue.mValue, llvmPtrType);
  5030. retVal.mKind = unionTypedValue.mKind;
  5031. }
  5032. }
  5033. if ((fieldDef->mIsVolatile) && (retVal.IsAddr()))
  5034. retVal.mKind = BfTypedValueKind_VolatileAddr;
  5035. if (wantsLoadValue)
  5036. retVal = mModule->LoadValue(retVal, NULL, mIsVolatileReference);
  5037. else
  5038. {
  5039. if ((wantsReadOnly) && (retVal.IsAddr()) && (!retVal.IsReadOnly()))
  5040. retVal.mKind = BfTypedValueKind_ReadOnlyAddr;
  5041. else if ((target.IsCopyOnMutate()) && (retVal.IsAddr()))
  5042. retVal.mKind = BfTypedValueKind_CopyOnMutateAddr_Derived;
  5043. mIsHeapReference = true;
  5044. }
  5045. if (isTemporary)
  5046. {
  5047. if (retVal.IsAddr())
  5048. retVal.mKind = BfTypedValueKind_TempAddr;
  5049. }
  5050. return retVal;
  5051. }
  5052. BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue target, const StringImpl& fieldName, BfLookupFieldFlags flags)
  5053. {
  5054. if (target)
  5055. flags = (BfLookupFieldFlags)(flags | BfLookupFieldFlag_HasInstance);
  5056. if ((target.mType != NULL && (target.mType->IsGenericParam())))
  5057. {
  5058. auto genericParamType = (BfGenericParamType*)target.mType;
  5059. auto genericParamInst = mModule->GetGenericParamInstance(genericParamType);
  5060. if (target.mValue)
  5061. {
  5062. for (auto iface : genericParamInst->mInterfaceConstraints)
  5063. {
  5064. auto result = LookupField(targetSrc, BfTypedValue(target.mValue, iface), fieldName, flags);
  5065. if ((result) || (mPropDef != NULL))
  5066. {
  5067. return result;
  5068. }
  5069. }
  5070. }
  5071. bool isUnspecializedSection = false;
  5072. if (genericParamType->mGenericParamKind == BfGenericParamKind_Method)
  5073. isUnspecializedSection = (mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsUnspecialized);
  5074. else
  5075. isUnspecializedSection = (mModule->mCurTypeInstance != NULL) && (mModule->mCurTypeInstance->IsUnspecializedType());
  5076. if (isUnspecializedSection)
  5077. {
  5078. auto origTarget = target;
  5079. if (genericParamInst->mTypeConstraint != NULL)
  5080. {
  5081. target.mType = genericParamInst->mTypeConstraint;
  5082. }
  5083. else
  5084. target.mType = mModule->mContext->mBfObjectType;
  5085. if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Var) != 0)
  5086. {
  5087. target.mType = mModule->GetPrimitiveType(BfTypeCode_Var);
  5088. }
  5089. if (origTarget.mType->IsTypeGenericParam())
  5090. {
  5091. // Check for extern constraint in method generic params
  5092. if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mMethodInfoEx != NULL))
  5093. {
  5094. for (auto genericParam : mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams)
  5095. {
  5096. if (genericParam->mExternType == origTarget.mType)
  5097. {
  5098. if (genericParam->mTypeConstraint != NULL)
  5099. {
  5100. target.mType = genericParam->mTypeConstraint;
  5101. break;
  5102. }
  5103. }
  5104. }
  5105. }
  5106. }
  5107. if (target.mType->IsWrappableType())
  5108. target.mType = mModule->GetWrappedStructType(target.mType);
  5109. }
  5110. else
  5111. {
  5112. if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Var) != 0)
  5113. {
  5114. //target.mType = mModule->ResolveGenericType(mResult.mType);
  5115. }
  5116. else if (genericParamInst->mTypeConstraint != NULL)
  5117. {
  5118. target = mModule->Cast(targetSrc, target, genericParamInst->mTypeConstraint);
  5119. BF_ASSERT(target);
  5120. }
  5121. else
  5122. {
  5123. // This shouldn't occur - this would infer that we are accessing a member of Object or something...
  5124. //target.mType = mModule->ResolveGenericType(mResult.mType);
  5125. }
  5126. }
  5127. }
  5128. if ((target.mType != NULL) && (IsVar(target.mType, (flags & BfLookupFieldFlag_BindOnly) != 0)))
  5129. return BfTypedValue(mModule->GetDefaultValue(target.mType), target.mType, true);
  5130. BfTypeInstance* startCheckType = mModule->mCurTypeInstance;
  5131. mPropDef = NULL;
  5132. mPropDefBypassVirtual = false;
  5133. if (target)
  5134. {
  5135. if ((!target.mType->IsValueType()) && (target.IsAddr()))
  5136. target = mModule->LoadValue(target);
  5137. if (target.mType->IsPrimitiveType())
  5138. {
  5139. auto primType = (BfPrimitiveType*)target.mType;
  5140. startCheckType = mModule->GetPrimitiveStructType(primType->mTypeDef->mTypeCode);
  5141. }
  5142. else
  5143. {
  5144. startCheckType = target.mType->ToTypeInstance();
  5145. if ((startCheckType == NULL) && (target.mType->IsPointer()))
  5146. {
  5147. startCheckType = ((BfPointerType*)target.mType)->mElementType->ToTypeInstance();
  5148. if ((startCheckType != NULL) && (!startCheckType->IsValueType()))
  5149. return BfTypedValue();
  5150. }
  5151. }
  5152. //BF_ASSERT(startCheckType != NULL);
  5153. }
  5154. else if (target.mType != NULL)
  5155. {
  5156. startCheckType = target.mType->ToTypeInstance();
  5157. }
  5158. if ((startCheckType != NULL) && (startCheckType->mBaseType == NULL))
  5159. {
  5160. if (startCheckType->mDefineState == BfTypeDefineState_ResolvingBaseType)
  5161. {
  5162. // Fixes cases where we have something like 'Base[Value]' as a base typeref
  5163. return BfTypedValue();
  5164. }
  5165. mModule->PopulateType(startCheckType, BfPopulateType_BaseType);
  5166. }
  5167. String findName;
  5168. int varSkipCount = 0;
  5169. if (fieldName.StartsWith('@'))
  5170. {
  5171. findName = fieldName;
  5172. while (findName.StartsWith('@'))
  5173. {
  5174. findName.Remove(0);
  5175. varSkipCount++;
  5176. }
  5177. }
  5178. else
  5179. findName.Reference(fieldName);
  5180. auto activeTypeDef = mModule->GetActiveTypeDef();
  5181. for (int pass = 0; pass < 2; pass++)
  5182. {
  5183. auto curCheckType = startCheckType;
  5184. bool isFailurePass = pass == 1;
  5185. if (isFailurePass)
  5186. flags = (BfLookupFieldFlags)(flags | BfLookupFieldFlag_IsFailurePass);
  5187. bool isBaseLookup = false;
  5188. int checkInterfaceIdx = 0;
  5189. while (curCheckType != NULL)
  5190. {
  5191. if (((flags & BfLookupFieldFlag_CheckingOuter) != 0) && ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0))
  5192. {
  5193. // Don't fully populateType for CheckingOuter - it carries a risk of an inadvertent data cycle
  5194. // Avoiding this could cause issues finding emitted statics/constants
  5195. }
  5196. else
  5197. {
  5198. bool isPopulatingType = false;
  5199. auto checkTypeState = mModule->mContext->mCurTypeState;
  5200. while (checkTypeState != NULL)
  5201. {
  5202. if (curCheckType == checkTypeState->mType)
  5203. {
  5204. isPopulatingType = true;
  5205. if (checkTypeState->mResolveKind == BfTypeState::ResolveKind_Attributes)
  5206. {
  5207. // Don't allow lookups yet
  5208. return BfTypedValue();
  5209. }
  5210. }
  5211. checkTypeState = checkTypeState->mPrevState;
  5212. }
  5213. if ((!isPopulatingType) && (curCheckType->mDefineState < Beefy::BfTypeDefineState_Defined))
  5214. {
  5215. // We MAY have emitted fields so we need to do this
  5216. mModule->mContext->mUnreifiedModule->PopulateType(curCheckType, Beefy::BfPopulateType_Interfaces_All);
  5217. }
  5218. }
  5219. curCheckType->mTypeDef->PopulateMemberSets();
  5220. BfFieldDef* nextField = NULL;
  5221. BfMemberSetEntry* entry;
  5222. if (curCheckType->mTypeDef->mFieldSet.TryGetWith(findName, &entry))
  5223. nextField = (BfFieldDef*)entry->mMemberDef;
  5224. if (nextField != NULL)
  5225. varSkipCount -= nextField->mNamePrefixCount;
  5226. while ((varSkipCount > 0) && (nextField != NULL))
  5227. {
  5228. nextField = nextField->mNextWithSameName;
  5229. varSkipCount--;
  5230. }
  5231. BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None;
  5232. if (target)
  5233. {
  5234. if ((flags & (BfLookupFieldFlag_IsImplicitThis | BfLookupFieldFlag_BaseLookup)) != 0)
  5235. {
  5236. // Not an "instance lookup"
  5237. }
  5238. else
  5239. {
  5240. protectionCheckFlags = (BfProtectionCheckFlags)(protectionCheckFlags | BfProtectionCheckFlag_InstanceLookup);
  5241. }
  5242. }
  5243. BfFieldDef* matchedField = NULL;
  5244. while (nextField != NULL)
  5245. {
  5246. if ((flags & BfLookupFieldFlag_BindOnly) != 0)
  5247. break;
  5248. auto field = nextField;
  5249. nextField = nextField->mNextWithSameName;
  5250. auto checkProtection = field->mProtection;
  5251. if (checkProtection == BfProtection_Hidden)
  5252. {
  5253. // Allow accessing hidden fields
  5254. checkProtection = BfProtection_Private;
  5255. }
  5256. if (((flags & BfLookupFieldFlag_IgnoreProtection) == 0) && (!isFailurePass) &&
  5257. (!mModule->CheckProtection(protectionCheckFlags, curCheckType, field->mDeclaringType->mProject, checkProtection, startCheckType)))
  5258. {
  5259. continue;
  5260. }
  5261. bool isResolvingFields = curCheckType->mResolvingConstField || curCheckType->mResolvingVarField;
  5262. if (curCheckType->mFieldInstances.IsEmpty())
  5263. {
  5264. mModule->PopulateType(curCheckType, BfPopulateType_Data);
  5265. }
  5266. if (field->mIdx >= (int)curCheckType->mFieldInstances.size())
  5267. {
  5268. if (mModule->mCompiler->EnsureCeUnpaused(curCheckType))
  5269. {
  5270. BF_DBG_FATAL("OOB in DoLookupField");
  5271. }
  5272. return mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Var));
  5273. }
  5274. BF_ASSERT(field->mIdx < (int)curCheckType->mFieldInstances.size());
  5275. auto fieldInstance = &curCheckType->mFieldInstances[field->mIdx];
  5276. if (!fieldInstance->mFieldIncluded)
  5277. continue;
  5278. if (curCheckType->IsUnspecializedType())
  5279. {
  5280. // The check for non-unspecialized types is already handled in mFieldIncluded
  5281. if (!curCheckType->IsTypeMemberIncluded(field->mDeclaringType, activeTypeDef, mModule))
  5282. continue;
  5283. }
  5284. if (!mModule->IsInSpecializedSection())
  5285. {
  5286. if (!curCheckType->IsTypeMemberAccessible(field->mDeclaringType, activeTypeDef))
  5287. continue;
  5288. }
  5289. if (matchedField != NULL)
  5290. {
  5291. auto error = mModule->Fail(StrFormat("Ambiguous reference to field '%s.%s'", mModule->TypeToString(curCheckType).c_str(), fieldName.c_str()), targetSrc);
  5292. if (error != NULL)
  5293. {
  5294. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See field declaration in project '%s'", matchedField->mDeclaringType->mProject->mName.c_str()), matchedField->mFieldDeclaration);
  5295. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See field declaration in project '%s'", field->mDeclaringType->mProject->mName.c_str()), field->mFieldDeclaration);
  5296. break;
  5297. }
  5298. }
  5299. matchedField = field;
  5300. }
  5301. if (matchedField != NULL)
  5302. return LoadField(targetSrc, target, curCheckType, matchedField, flags);
  5303. BfPropertyDef* nextProp = NULL;
  5304. if (curCheckType->mTypeDef->mPropertySet.TryGetWith(fieldName, &entry))
  5305. nextProp = (BfPropertyDef*)entry->mMemberDef;
  5306. if (nextProp != NULL)
  5307. {
  5308. BfCheckedKind checkedKind = BfCheckedKind_NotSet;
  5309. bool isInlined = false;
  5310. if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL))
  5311. {
  5312. if (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mInlineAttributeTypeDef))
  5313. {
  5314. isInlined = true;
  5315. mModule->mAttributeState->mUsed = true;
  5316. }
  5317. if (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mCheckedAttributeTypeDef))
  5318. {
  5319. checkedKind = BfCheckedKind_Checked;
  5320. mModule->mAttributeState->mUsed = true;
  5321. }
  5322. if (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mUncheckedAttributeTypeDef))
  5323. {
  5324. checkedKind = BfCheckedKind_Unchecked;
  5325. mModule->mAttributeState->mUsed = true;
  5326. }
  5327. }
  5328. BfPropertyDef* matchedProp = NULL;
  5329. while (nextProp != NULL)
  5330. {
  5331. auto prop = nextProp;
  5332. nextProp = nextProp->mNextWithSameName;
  5333. if ((!isFailurePass) && ((mBfEvalExprFlags & BfEvalExprFlags_NameOf) == 0) && (!mModule->CheckProtection(protectionCheckFlags, curCheckType, prop->mDeclaringType->mProject, prop->mProtection, startCheckType)))
  5334. {
  5335. continue;
  5336. }
  5337. if (!prop->mMethods.IsEmpty())
  5338. {
  5339. BfMethodDef* checkMethod = prop->mMethods[0];
  5340. // Properties with explicit interfaces or marked as overrides can only be called indirectly
  5341. if ((checkMethod->mExplicitInterface != NULL) || (checkMethod->mIsOverride))
  5342. continue;
  5343. }
  5344. if ((!target.IsStatic()) || (prop->mIsStatic) || ((mBfEvalExprFlags & BfEvalExprFlags_NameOf) != 0))
  5345. {
  5346. if (!curCheckType->IsTypeMemberIncluded(prop->mDeclaringType, activeTypeDef, mModule))
  5347. continue;
  5348. if (!mModule->IsInSpecializedSection())
  5349. {
  5350. if (!curCheckType->IsTypeMemberAccessible(prop->mDeclaringType, mModule->GetVisibleProjectSet()))
  5351. continue;
  5352. }
  5353. if (matchedProp != NULL)
  5354. {
  5355. if ((matchedProp->mDeclaringType->IsExtension()) && (!prop->mDeclaringType->IsExtension()))
  5356. {
  5357. // Prefer non-extension
  5358. continue;
  5359. }
  5360. else
  5361. {
  5362. if (mModule->PreFail())
  5363. {
  5364. auto error = mModule->Fail(StrFormat("Ambiguous reference to property '%s.%s'", mModule->TypeToString(curCheckType).c_str(), fieldName.c_str()), targetSrc);
  5365. if (error != NULL)
  5366. {
  5367. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See property declaration in project '%s'", matchedProp->mDeclaringType->mProject->mName.c_str()), matchedProp->mFieldDeclaration);
  5368. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See property declaration in project '%s'", prop->mDeclaringType->mProject->mName.c_str()), prop->mFieldDeclaration);
  5369. break;
  5370. }
  5371. }
  5372. }
  5373. }
  5374. matchedProp = prop;
  5375. }
  5376. }
  5377. if (matchedProp != NULL)
  5378. return LoadProperty(targetSrc, target, curCheckType, matchedProp, flags, checkedKind, isInlined);
  5379. }
  5380. if (curCheckType->mTypeDef->mHasUsingFields)
  5381. mModule->PopulateUsingFieldData(curCheckType);
  5382. ///
  5383. {
  5384. Array<SizedArray<BfUsingFieldData::MemberRef, 1>*> foundLists;
  5385. auto _CheckUsingData = [&](BfUsingFieldData* usingData)
  5386. {
  5387. BfUsingFieldData::Entry* entry = NULL;
  5388. if (!usingData->mEntries.TryGetValue(findName, &entry))
  5389. return;
  5390. for (int listIdx = 0; listIdx < entry->mLookups.mSize; listIdx++)
  5391. {
  5392. bool passesProtection = true;
  5393. auto& entryList = entry->mLookups[listIdx];
  5394. for (int entryIdx = 0; entryIdx < entryList.mSize; entryIdx++)
  5395. {
  5396. auto& entry = entryList[entryIdx];
  5397. BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None;
  5398. if (!mModule->CheckProtection(protectionCheckFlags, entry.mTypeInstance, entry.GetDeclaringType(mModule)->mProject,
  5399. (entryIdx < entryList.mSize - 1) ? entry.GetUsingProtection() : entry.GetProtection(), curCheckType))
  5400. {
  5401. passesProtection = false;
  5402. break;
  5403. }
  5404. }
  5405. if (!passesProtection)
  5406. continue;
  5407. if (foundLists.mSize == 0)
  5408. {
  5409. foundLists.Add(&entryList);
  5410. }
  5411. else
  5412. {
  5413. if (entryList.mSize < foundLists[0]->mSize)
  5414. {
  5415. // New is shorter
  5416. foundLists.Clear();
  5417. foundLists.Add(&entryList);
  5418. }
  5419. else if (entryList.mSize > foundLists[0]->mSize)
  5420. {
  5421. // Ignore longer
  5422. }
  5423. else
  5424. {
  5425. foundLists.Add(&entryList);
  5426. }
  5427. }
  5428. }
  5429. };
  5430. if ((curCheckType->mTypeInfoEx != NULL) && (curCheckType->mTypeInfoEx->mUsingFieldData != NULL))
  5431. _CheckUsingData(curCheckType->mTypeInfoEx->mUsingFieldData);
  5432. if (!foundLists.IsEmpty())
  5433. {
  5434. auto foundList = foundLists[0];
  5435. if (foundLists.mSize > 1)
  5436. {
  5437. BfError* error = mModule->Fail("Ambiguous 'using' field reference", targetSrc);
  5438. if (error != NULL)
  5439. {
  5440. for (auto checkList : foundLists)
  5441. {
  5442. String errorStr = "'";
  5443. for (int entryIdx = 0; entryIdx < checkList->mSize; entryIdx++)
  5444. {
  5445. if (entryIdx == 0)
  5446. errorStr += (*checkList)[entryIdx].GetFullName(mModule);
  5447. else
  5448. {
  5449. errorStr += ".";
  5450. errorStr += (*checkList)[entryIdx].GetName(mModule);
  5451. }
  5452. }
  5453. errorStr += "' is a candidate";
  5454. mModule->mCompiler->mPassInstance->MoreInfo(errorStr, (*checkList)[0].GetRefNode(mModule));
  5455. }
  5456. }
  5457. }
  5458. BfTypedValue curResult = target;
  5459. for (int entryIdx = 0; entryIdx < foundList->mSize; entryIdx++)
  5460. {
  5461. if ((entryIdx == 0) && (foundList->back().IsStatic()))
  5462. entryIdx = (int)foundList->mSize - 1;
  5463. auto& entry = (*foundList)[entryIdx];
  5464. if (mPropDef != NULL)
  5465. {
  5466. SetAndRestoreValue<BfTypedValue> prevResult(mResult, BfTypedValue());
  5467. mPropGetMethodFlags = (BfGetMethodInstanceFlags)(mPropGetMethodFlags | BfGetMethodInstanceFlag_Friend);
  5468. curResult = GetResult();
  5469. if (!curResult)
  5470. return curResult;
  5471. }
  5472. auto useFlags = flags;
  5473. if (entryIdx < foundList->mSize - 1)
  5474. useFlags = (BfLookupFieldFlags)(flags | BfLookupFieldFlag_IsAnonymous);
  5475. if (entry.mKind == BfUsingFieldData::MemberRef::Kind_Field)
  5476. {
  5477. curResult = LoadField(targetSrc, curResult, entry.mTypeInstance, entry.mTypeInstance->mTypeDef->mFields[entry.mIdx], useFlags);
  5478. }
  5479. else if (entry.mKind == BfUsingFieldData::MemberRef::Kind_Property)
  5480. {
  5481. curResult = LoadProperty(targetSrc, curResult, entry.mTypeInstance, entry.mTypeInstance->mTypeDef->mProperties[entry.mIdx], useFlags, BfCheckedKind_NotSet, false);
  5482. }
  5483. else if (entry.mKind == BfUsingFieldData::MemberRef::Kind_Local)
  5484. {
  5485. auto localDef = mModule->mCurMethodState->mLocals[entry.mIdx];
  5486. curResult = LoadLocal(localDef);
  5487. }
  5488. if ((!curResult) && (mPropDef == NULL))
  5489. return curResult;
  5490. if (entryIdx == foundList->mSize - 1)
  5491. {
  5492. auto autoComplete = GetAutoComplete();
  5493. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(targetSrc)))
  5494. autoComplete->SetDefinitionLocation(entry.GetRefNode(mModule));
  5495. if ((autoComplete != NULL) && (autoComplete->CheckFixit(targetSrc)))
  5496. autoComplete->FixitAddFullyQualify(targetSrc, findName, *foundList);
  5497. }
  5498. }
  5499. return curResult;
  5500. }
  5501. }
  5502. if ((!isBaseLookup) && (startCheckType->IsInterface() && (checkInterfaceIdx < (int)startCheckType->mInterfaces.size())))
  5503. {
  5504. curCheckType = startCheckType->mInterfaces[checkInterfaceIdx].mInterfaceType;
  5505. checkInterfaceIdx++;
  5506. }
  5507. else
  5508. {
  5509. isBaseLookup = true;
  5510. curCheckType = curCheckType->mBaseType;
  5511. }
  5512. }
  5513. }
  5514. auto outerTypeDef = mModule->GetOuterType(startCheckType);
  5515. if (outerTypeDef != NULL)
  5516. {
  5517. BfLookupFieldFlags newFlags = BfLookupFieldFlag_CheckingOuter;
  5518. if (((flags & BfLookupFieldFlag_HasInstance) != 0) &&
  5519. ((flags & BfLookupFieldFlag_IsImplicitThis) == 0))
  5520. newFlags = (BfLookupFieldFlags)(newFlags | BfLookupFieldFlag_HasInstance);
  5521. // Check statics in outer type
  5522. return LookupField(targetSrc, BfTypedValue(outerTypeDef), fieldName, newFlags);
  5523. }
  5524. return BfTypedValue();
  5525. }
  5526. void BfExprEvaluator::ResolveArgValues(BfResolvedArgs& resolvedArgs, BfResolveArgsFlags flags)
  5527. {
  5528. static int idx = 0;
  5529. idx++;
  5530. int curIdx = idx;
  5531. if (resolvedArgs.mArguments == NULL)
  5532. return;
  5533. int argCount = (int)resolvedArgs.mArguments->size();
  5534. if ((resolvedArgs.mCommas != NULL) && (resolvedArgs.mCommas->size() != 0) && (resolvedArgs.mCommas->size() >= resolvedArgs.mArguments->size()))
  5535. {
  5536. //mModule->FailAfter("Expression expected", resolvedArgs.mCommas->back());
  5537. argCount++;
  5538. }
  5539. BfAutoComplete* autoComplete = GetAutoComplete();
  5540. bool hadIgnoredFixits = false;
  5541. if (autoComplete != NULL)
  5542. {
  5543. hadIgnoredFixits = autoComplete->mIgnoreFixits;
  5544. if (flags & BfResolveArgsFlag_DeferFixits)
  5545. autoComplete->mIgnoreFixits = true;
  5546. }
  5547. int deferredArgIdx = 0;
  5548. SizedArray<BfExpression*, 8> deferredArgs;
  5549. int argIdx = 0;
  5550. while (true)
  5551. {
  5552. //printf("Args: %p %p %d\n", resolvedArgs.mArguments, resolvedArgs.mArguments->mVals, resolvedArgs.mArguments->mSize);
  5553. BfExpression* argExpr = NULL;
  5554. bool isDeferredArg = false;
  5555. int curArgIdx = -1;
  5556. if (deferredArgIdx < deferredArgs.size())
  5557. {
  5558. argExpr = deferredArgs[deferredArgIdx++];
  5559. isDeferredArg = true;
  5560. }
  5561. else if (argIdx >= argCount)
  5562. {
  5563. break;
  5564. }
  5565. else
  5566. {
  5567. curArgIdx = argIdx++;
  5568. if (curArgIdx < resolvedArgs.mArguments->size())
  5569. argExpr = (*resolvedArgs.mArguments)[curArgIdx];
  5570. }
  5571. if (argExpr == NULL)
  5572. {
  5573. if (curArgIdx == 0)
  5574. {
  5575. if (resolvedArgs.mOpenToken != NULL)
  5576. mModule->FailAfter("Expression expected", resolvedArgs.mOpenToken);
  5577. }
  5578. else if (resolvedArgs.mCommas != NULL)
  5579. mModule->FailAfter("Expression expected", (*resolvedArgs.mCommas)[curArgIdx - 1]);
  5580. }
  5581. if (auto typedValueExpr = BfNodeDynCast<BfTypedValueExpression>(argExpr))
  5582. {
  5583. BfResolvedArg resolvedArg;
  5584. resolvedArg.mTypedValue = typedValueExpr->mTypedValue;
  5585. if (resolvedArg.mTypedValue.IsParams())
  5586. resolvedArg.mArgFlags = BfArgFlag_ParamsExpr;
  5587. resolvedArg.mExpression = typedValueExpr->mRefNode;
  5588. resolvedArgs.mResolvedArgs.push_back(resolvedArg);
  5589. continue;
  5590. }
  5591. BfResolvedArg resolvedArg;
  5592. if (isDeferredArg)
  5593. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_StringInterpolateArg);
  5594. BfExprEvaluator exprEvaluator(mModule);
  5595. exprEvaluator.mResolveGenericParam = (flags & BfResolveArgsFlag_AllowUnresolvedTypes) == 0;
  5596. exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | BfEvalExprFlags_AllowRefExpr | BfEvalExprFlags_AllowOutExpr |
  5597. (mBfEvalExprFlags & (BfEvalExprFlags_Comptime)));
  5598. bool handled = false;
  5599. bool evaluated = false;
  5600. if (auto namedExpression = BfNodeDynCastExact<BfNamedExpression>(argExpr))
  5601. {
  5602. resolvedArg.mNameNode = namedExpression->mNameNode;
  5603. argExpr = namedExpression->mExpression;
  5604. }
  5605. if (auto interpolateExpr = BfNodeDynCastExact<BfStringInterpolationExpression>(argExpr))
  5606. {
  5607. if ((interpolateExpr->mAllocNode == NULL) || ((flags & BfResolveArgsFlag_InsideStringInterpolationAlloc) != 0))
  5608. {
  5609. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_StringInterpolateFormat);
  5610. for (auto innerExpr : interpolateExpr->mExpressions)
  5611. deferredArgs.Add(innerExpr);
  5612. }
  5613. }
  5614. if (auto unaryOpExpr = BfNodeDynCastExact<BfUnaryOperatorExpression>(argExpr))
  5615. {
  5616. if ((unaryOpExpr->mOp == BfUnaryOp_Cascade) && ((flags & BfResolveArgsFlag_FromIndexer) == 0))
  5617. {
  5618. if ((mBfEvalExprFlags & BfEvalExprFlags_InCascade) != 0)
  5619. mModule->Fail("Cascade already specified on call target", unaryOpExpr->mOpToken);
  5620. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_Cascade);
  5621. argExpr = unaryOpExpr->mExpression;
  5622. }
  5623. }
  5624. bool deferParamEval = false;
  5625. if ((flags & BfResolveArgsFlag_DeferParamEval) != 0)
  5626. {
  5627. if (argExpr != NULL)
  5628. {
  5629. BfDeferEvalChecker deferEvalChecker;
  5630. if ((flags & BfResolveArgsFlag_DeferStrings) != 0)
  5631. deferEvalChecker.mDeferStrings = true;
  5632. deferEvalChecker.mDeferDelegateBind = false;
  5633. deferEvalChecker.Check(argExpr);
  5634. deferParamEval = deferEvalChecker.mNeedsDeferEval;
  5635. }
  5636. }
  5637. if (deferParamEval)
  5638. {
  5639. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_DeferredEval);
  5640. handled = true;
  5641. }
  5642. else if (auto delegateBindExpression = BfNodeDynCast<BfDelegateBindExpression>(argExpr))
  5643. {
  5644. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_DelegateBindAttempt);
  5645. handled = true;
  5646. }
  5647. else if (auto lambdaBindExpression = BfNodeDynCast<BfLambdaBindExpression>(argExpr))
  5648. {
  5649. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_LambdaBindAttempt);
  5650. handled = true;
  5651. }
  5652. else if (auto defaultExpr = BfNodeDynCast<BfDefaultExpression>(argExpr))
  5653. {
  5654. if (defaultExpr->mTypeRef == NULL)
  5655. {
  5656. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_UntypedDefault);
  5657. handled = true;
  5658. }
  5659. }
  5660. else if (auto varDeclExpr = BfNodeDynCast<BfVariableDeclaration>(argExpr))
  5661. {
  5662. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_VariableDeclaration);
  5663. handled = true;
  5664. }
  5665. else if (auto unaryExpr = BfNodeDynCast<BfUnaryOperatorExpression>(argExpr))
  5666. {
  5667. if (unaryExpr->mOp == BfUnaryOp_Params)
  5668. {
  5669. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_ParamsExpr);
  5670. }
  5671. }
  5672. else if (auto uninitExpr = BfNodeDynCast<BfUninitializedExpression>(argExpr))
  5673. {
  5674. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_UninitializedExpr);
  5675. handled = true;
  5676. }
  5677. if (!handled)
  5678. {
  5679. BfAstNode* checkArgExpr = argExpr;
  5680. while (checkArgExpr != NULL)
  5681. {
  5682. if (auto memberRef = BfNodeDynCast<BfMemberReferenceExpression>(checkArgExpr))
  5683. {
  5684. if (memberRef->mTarget == NULL)
  5685. {
  5686. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_UnqualifiedDotAttempt);
  5687. handled = true;
  5688. break;
  5689. }
  5690. else
  5691. checkArgExpr = memberRef->mTarget;
  5692. }
  5693. else if (auto invokeExpr = BfNodeDynCast<BfInvocationExpression>(checkArgExpr))
  5694. {
  5695. checkArgExpr = invokeExpr->mTarget;
  5696. }
  5697. else if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(checkArgExpr))
  5698. {
  5699. checkArgExpr = parenExpr->mExpression;
  5700. }
  5701. else
  5702. break;
  5703. }
  5704. }
  5705. if ((argExpr != NULL) && (!handled))
  5706. {
  5707. bool deferParamValues = (flags & BfResolveArgsFlag_DeferParamValues) != 0;
  5708. SetAndRestoreValue<bool> ignoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, mModule->mBfIRBuilder->mIgnoreWrites || deferParamValues);
  5709. auto prevInsertBlock = mModule->mBfIRBuilder->GetInsertBlock();
  5710. if (deferParamValues)
  5711. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_DeferredValue);
  5712. if (!evaluated)
  5713. {
  5714. exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | BfEvalExprFlags_AllowParamsExpr);
  5715. if ((resolvedArg.mArgFlags & BfArgFlag_StringInterpolateFormat) != 0)
  5716. exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | BfEvalExprFlags_StringInterpolateFormat);
  5717. int lastLocalVarIdx = (mModule->mCurMethodState != NULL) ? mModule->mCurMethodState->mLocals.mSize : 0;
  5718. exprEvaluator.Evaluate(argExpr, false, false, true);
  5719. if ((deferParamValues) && (mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mLocals.mSize > lastLocalVarIdx))
  5720. {
  5721. // Remove any ignored locals
  5722. mModule->RestoreScoreState_LocalVariables(lastLocalVarIdx);
  5723. }
  5724. }
  5725. if ((mModule->mCurMethodState != NULL) && (exprEvaluator.mResultLocalVar != NULL) && (exprEvaluator.mResultLocalVarRefNode != NULL))
  5726. {
  5727. auto localVar = exprEvaluator.mResultLocalVar;
  5728. int fieldIdx = mResultLocalVarField - 1;
  5729. auto methodState = mModule->mCurMethodState->GetMethodStateForLocal(localVar);
  5730. if (localVar->mCompositeCount >= 0)
  5731. {
  5732. if ((resolvedArg.mArgFlags & BfArgFlag_ParamsExpr) != 0)
  5733. {
  5734. for (int compositeIdx = 0; compositeIdx < localVar->mCompositeCount; compositeIdx++)
  5735. {
  5736. BfResolvedArg compositeResolvedArg;
  5737. auto compositeLocalVar = methodState->mLocals[localVar->mLocalVarIdx + compositeIdx + 1];
  5738. auto argValue = exprEvaluator.LoadLocal(compositeLocalVar, true);
  5739. if (argValue)
  5740. {
  5741. if (!argValue.mType->IsStruct())
  5742. argValue = mModule->LoadValue(argValue, NULL, exprEvaluator.mIsVolatileReference);
  5743. }
  5744. resolvedArg.mTypedValue = argValue;
  5745. resolvedArg.mExpression = argExpr;
  5746. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_FromParamComposite);
  5747. resolvedArgs.mResolvedArgs.push_back(resolvedArg);
  5748. exprEvaluator.mIsVolatileReference = false;
  5749. }
  5750. if ((localVar->mResolvedType->IsModifiedTypeType()) && (((BfModifiedTypeType*)localVar->mResolvedType)->mModifiedKind == BfToken_Params))
  5751. {
  5752. // Is a 'params'
  5753. }
  5754. else
  5755. continue;
  5756. }
  5757. else
  5758. exprEvaluator.mResult = mModule->LoadOrAggregateValue(exprEvaluator.mResult);
  5759. }
  5760. }
  5761. exprEvaluator.CheckResultForReading(exprEvaluator.mResult);
  5762. auto argValue = exprEvaluator.mResult;
  5763. if (argValue)
  5764. {
  5765. mModule->mBfIRBuilder->PopulateType(argValue.mType);
  5766. resolvedArg.mResolvedType = argValue.mType;
  5767. if (resolvedArg.mResolvedType->IsRef())
  5768. argValue.mKind = BfTypedValueKind_Value;
  5769. if (exprEvaluator.mIsVolatileReference)
  5770. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_Volatile);
  5771. }
  5772. resolvedArg.mUncastedTypedValue = argValue;
  5773. resolvedArg.mTypedValue = argValue;
  5774. if (deferParamValues)
  5775. mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock);
  5776. }
  5777. resolvedArg.mExpression = argExpr;
  5778. resolvedArgs.mResolvedArgs.push_back(resolvedArg);
  5779. }
  5780. if (autoComplete != NULL)
  5781. autoComplete->mIgnoreFixits = hadIgnoredFixits;
  5782. }
  5783. void BfExprEvaluator::PerformCallChecks(BfMethodInstance* methodInstance, BfAstNode* targetSrc)
  5784. {
  5785. BfCustomAttributes* customAttributes = methodInstance->GetCustomAttributes();
  5786. if (customAttributes != NULL)
  5787. mModule->CheckErrorAttributes(methodInstance->GetOwner(), methodInstance, NULL, customAttributes, targetSrc);
  5788. }
  5789. void BfExprEvaluator::CheckSkipCall(BfAstNode* targetSrc, SizedArrayImpl<BfResolvedArg>& argValues)
  5790. {
  5791. for (auto& argValue : argValues)
  5792. {
  5793. if ((!argValue.IsDeferredValue()) && (argValue.mExpression != NULL))
  5794. {
  5795. mModule->Fail("Illegal SkipCall invocation", targetSrc);
  5796. return;
  5797. }
  5798. }
  5799. }
  5800. BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* methodInstance, BfIRValue func, bool bypassVirtual, SizedArrayImpl<BfIRValue>& irArgs, BfTypedValue* sret, BfCreateCallFlags callFlags, BfType* origTargetType)
  5801. {
  5802. // static int sCallIdx = 0;
  5803. // if (!mModule->mCompiler->mIsResolveOnly)
  5804. // sCallIdx++;
  5805. // int callIdx = sCallIdx;
  5806. // if (callIdx == 0x000000E8)
  5807. // {
  5808. // NOP;
  5809. // }
  5810. bool isDelegateThunk = ((callFlags & (BfCreateCallFlags_DelegateThunkNonStatic | BfCreateCallFlags_DelegateThunkStatic)) != 0);
  5811. auto methodDef = methodInstance->mMethodDef;
  5812. BfIRValue funcCallInst = func;
  5813. auto importCallKind = methodInstance->GetImportCallKind();
  5814. if ((funcCallInst) && (importCallKind != BfImportCallKind_None))
  5815. {
  5816. if ((funcCallInst.IsFake()) && (!mModule->mBfIRBuilder->mIgnoreWrites))
  5817. {
  5818. mModule->mFuncReferences.TryGetValue(methodInstance, &funcCallInst);
  5819. }
  5820. if ((importCallKind == BfImportCallKind_GlobalVar) &&
  5821. (methodInstance->mHotMethod == NULL) &&
  5822. (mModule->mCompiler->IsHotCompile()))
  5823. {
  5824. // This may actually be a BfImportCallKind_GlobalVar_Hot, so check it...
  5825. mModule->CheckHotMethod(methodInstance, "");
  5826. importCallKind = methodInstance->GetImportCallKind();
  5827. }
  5828. if (importCallKind == BfImportCallKind_GlobalVar_Hot)
  5829. {
  5830. //TODO: Check against NULL for calling BfLoadSharedLibraries
  5831. auto checkVal = mModule->mBfIRBuilder->CreateLoad(funcCallInst);
  5832. BfIRBlock nullBlock = mModule->mBfIRBuilder->CreateBlock("importNull");
  5833. BfIRBlock doneBlock = mModule->mBfIRBuilder->CreateBlock("importLoad");
  5834. auto condVal = mModule->mBfIRBuilder->CreateIsNull(checkVal);
  5835. mModule->mBfIRBuilder->CreateCondBr(condVal, nullBlock, doneBlock);
  5836. mModule->mBfIRBuilder->AddBlock(nullBlock);
  5837. mModule->mBfIRBuilder->SetInsertPoint(nullBlock);
  5838. auto loadSharedLibsFunc = mModule->GetBuiltInFunc(BfBuiltInFuncType_LoadSharedLibraries);
  5839. mModule->mBfIRBuilder->CreateCall(loadSharedLibsFunc, SizedArray<BfIRValue, 0>());
  5840. mModule->mBfIRBuilder->CreateBr(doneBlock);
  5841. mModule->mBfIRBuilder->AddBlock(doneBlock);
  5842. mModule->mBfIRBuilder->SetInsertPoint(doneBlock);
  5843. funcCallInst = mModule->mBfIRBuilder->CreateLoad(funcCallInst);
  5844. }
  5845. else
  5846. {
  5847. funcCallInst = mModule->mBfIRBuilder->CreateLoad(funcCallInst);
  5848. }
  5849. }
  5850. if ((methodInstance->GetOwner()->IsInstanceOf(mModule->mCompiler->mDeferredCallTypeDef)) &&
  5851. (methodInstance->mMethodDef->mName == "Cancel"))
  5852. {
  5853. if (mModule->mCurMethodState != NULL)
  5854. mModule->mCurMethodState->mCancelledDeferredCall = true;
  5855. }
  5856. if ((methodDef->mIsNoReturn) && ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) == 0))
  5857. {
  5858. mModule->mCurMethodState->SetHadReturn(true);
  5859. mModule->mCurMethodState->mLeftBlockUncond = true;
  5860. mModule->MarkScopeLeft(&mModule->mCurMethodState->mHeadScope, true);
  5861. }
  5862. if (mModule->mCurTypeInstance != NULL)
  5863. {
  5864. bool isVirtual = (methodInstance->mVirtualTableIdx != -1) && (!bypassVirtual);
  5865. mModule->AddDependency(methodInstance->mMethodInstanceGroup->mOwner, mModule->mCurTypeInstance, isVirtual ? BfDependencyMap::DependencyFlag_VirtualCall : BfDependencyMap::DependencyFlag_Calls);
  5866. mModule->AddCallDependency(methodInstance, bypassVirtual);
  5867. }
  5868. if (methodInstance->GetOwner()->IsUnspecializedType())
  5869. {
  5870. BF_ASSERT((!methodInstance->mIRFunction) || (methodInstance == mModule->mCurMethodInstance) || (methodInstance->mMethodDef->mIsLocalMethod));
  5871. }
  5872. if (mFunctionBindResult != NULL)
  5873. {
  5874. BF_ASSERT(mFunctionBindResult->mMethodInstance == NULL);
  5875. mFunctionBindResult->mMethodInstance = methodInstance;
  5876. for (auto arg : irArgs)
  5877. mFunctionBindResult->mIRArgs.push_back(arg);
  5878. }
  5879. BfType* origReturnType = methodInstance->mReturnType;
  5880. /*if (origReturnType->IsSelf())
  5881. {
  5882. origReturnType = methodInstance->GetOwner();
  5883. BF_ASSERT(origReturnType->IsInterface());
  5884. }*/
  5885. BfType* returnType = origReturnType;
  5886. BfTypedValue sretVal;
  5887. auto _GetDefaultReturnValue = [&]()
  5888. {
  5889. if (methodInstance->mVirtualTableIdx == -1)
  5890. {
  5891. if (methodInstance->GetOwner()->IsInterface())
  5892. {
  5893. // We're attempting to directly invoke a non-virtual interface method, if we're return an interface then
  5894. // it is a concrete interface
  5895. if (returnType->IsInterface())
  5896. returnType = mModule->CreateConcreteInterfaceType(returnType->ToTypeInstance());
  5897. }
  5898. }
  5899. if ((returnType->IsVar()) && (mExpectingType != NULL))
  5900. returnType = mExpectingType;
  5901. if (returnType->IsRef())
  5902. {
  5903. auto result = mModule->GetDefaultTypedValue(returnType->GetUnderlyingType(), true, BfDefaultValueKind_Addr);
  5904. if (methodDef->mIsReadOnly)
  5905. result.mKind = BfTypedValueKind_ReadOnlyAddr;
  5906. return result;
  5907. }
  5908. else
  5909. {
  5910. auto val = mModule->GetDefaultTypedValue(returnType, true, (GetStructRetIdx(methodInstance) != -1) ? BfDefaultValueKind_Addr : BfDefaultValueKind_Value);
  5911. if (val.mKind == BfTypedValueKind_Addr)
  5912. val.mKind = BfTypedValueKind_RestrictedTempAddr;
  5913. return val;
  5914. }
  5915. };
  5916. mModule->PopulateType(origReturnType, BfPopulateType_Data);
  5917. if ((GetStructRetIdx(methodInstance) != -1) && (!isDelegateThunk))
  5918. {
  5919. // We need to ensure that mReceivingValue has the correct type, otherwise it's possible that a conversion operator needs to be applied
  5920. // This happens for returning Result<T>'s with a 'T' value
  5921. if ((sret == NULL) && (mReceivingValue != NULL) && (mReceivingValue->mType == returnType))
  5922. {
  5923. sretVal = *mReceivingValue;
  5924. sret = &sretVal;
  5925. auto ptrType = mModule->CreatePointerType(returnType);
  5926. if (returnType != sret->mType)
  5927. {
  5928. sret->mValue = mModule->mBfIRBuilder->CreateBitCast(sret->mValue, mModule->mBfIRBuilder->MapType(ptrType));
  5929. sret->mType = returnType;
  5930. }
  5931. mReceivingValue = NULL;
  5932. }
  5933. if (sret == NULL)
  5934. {
  5935. sretVal = BfTypedValue(mModule->CreateAlloca(returnType), returnType, BfTypedValueKind_RestrictedTempAddr);
  5936. sret = &sretVal;
  5937. }
  5938. }
  5939. else
  5940. {
  5941. BF_ASSERT(sret == NULL);
  5942. }
  5943. if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mCapturing))
  5944. {
  5945. if ((methodInstance->mComptimeFlags & BfComptimeFlag_ConstEval) != 0)
  5946. {
  5947. // We need to perform call such as Compiler.Mixin and String.ConstF
  5948. }
  5949. else
  5950. return _GetDefaultReturnValue();
  5951. }
  5952. BF_ASSERT(!methodInstance->mDisallowCalling);
  5953. if ((mModule->mCompiler->mResolvePassData != NULL) && (mModule->mCompiler->mResolvePassData->mAutoComplete != NULL))
  5954. {
  5955. bool wantQuickEval = true;
  5956. if (IsComptime())
  5957. {
  5958. auto autoComplete = mModule->mCompiler->mResolvePassData->mAutoComplete;
  5959. wantQuickEval =
  5960. ((autoComplete->mResolveType != BfResolveType_Autocomplete) &&
  5961. (autoComplete->mResolveType != BfResolveType_Autocomplete_HighPri) &&
  5962. (autoComplete->mResolveType != BfResolveType_GetResultString));
  5963. for (auto& entry : mModule->mCompiler->mResolvePassData->mEmitEmbedEntries)
  5964. {
  5965. if (entry.mValue.mCursorIdx >= 0)
  5966. {
  5967. // Needed for Go To Definition in Compiler.Mixin
  5968. wantQuickEval = false;
  5969. }
  5970. }
  5971. }
  5972. if (wantQuickEval)
  5973. {
  5974. // In an autocomplete pass we may have stale method references that need to be resolved
  5975. // in the full classify pass, and in the full classify pass while just refreshing internals, we
  5976. // may have NULL funcs temporarily. We simply skip generating the method call here.
  5977. if ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0)
  5978. {
  5979. if (methodInstance->mReturnType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef))
  5980. {
  5981. if ((mExpectingType != NULL) && (mExpectingType->IsSizedArray()))
  5982. {
  5983. return BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->MapType(mExpectingType)), mExpectingType);
  5984. }
  5985. }
  5986. auto returnType = methodInstance->mReturnType;
  5987. if ((returnType->IsVar()) && (mExpectingType != NULL))
  5988. returnType = mExpectingType;
  5989. if (methodInstance->mReturnType->IsValuelessType())
  5990. return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), returnType);
  5991. return BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->MapType(returnType)), returnType);
  5992. }
  5993. BfTypedValue result;
  5994. if (sret != NULL)
  5995. result = *sret;
  5996. else
  5997. result = _GetDefaultReturnValue();
  5998. return result;
  5999. }
  6000. }
  6001. bool forceBind = false;
  6002. if (mModule->mCompiler->mCeMachine != NULL)
  6003. {
  6004. bool doConstReturn = false;
  6005. if ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0)
  6006. {
  6007. if (mFunctionBindResult != NULL)
  6008. {
  6009. forceBind = true;
  6010. }
  6011. else if ((mBfEvalExprFlags & BfEvalExprFlags_InCascade) != 0)
  6012. {
  6013. mModule->Fail("Const evaluation not allowed with cascade operator", targetSrc);
  6014. }
  6015. else if (((methodInstance->mComptimeFlags & BfComptimeFlag_OnlyFromComptime) != 0) && (!mModule->mIsComptimeModule))
  6016. {
  6017. // This either generated an error already or this is just the non-const type check pass for a comptime-only method
  6018. doConstReturn = true;
  6019. }
  6020. else if ((mBfEvalExprFlags & BfEvalExprFlags_DisallowComptime) != 0)
  6021. {
  6022. doConstReturn = true;
  6023. }
  6024. else if (((callFlags & BfCreateCallFlags_GenericParamThis) != 0) && (methodInstance->GetOwner()->IsInterface()))
  6025. {
  6026. mModule->Warn(0, "Concrete method may fail to comptime during specialization", targetSrc);
  6027. doConstReturn = true;
  6028. }
  6029. else if (methodDef->mIsVirtual)
  6030. {
  6031. // This could only really be the case for a Type, since no other 'this' could qualify as const
  6032. }
  6033. else
  6034. {
  6035. CeEvalFlags evalFlags = CeEvalFlags_None;
  6036. if ((mBfEvalExprFlags & BfEvalExprFlags_NoCeRebuildFlags) != 0)
  6037. evalFlags = (CeEvalFlags)(evalFlags | CeEvalFlags_NoRebuild);
  6038. if ((mModule->mIsComptimeModule) && (mModule->mCompiler->mCeMachine->mDebugger != NULL) && (mModule->mCompiler->mCeMachine->mDebugger->mCurDbgState != NULL))
  6039. {
  6040. auto ceDbgState = mModule->mCompiler->mCeMachine->mDebugger->mCurDbgState;
  6041. if ((ceDbgState->mDbgExpressionFlags & DwEvalExpressionFlag_AllowCalls) != 0)
  6042. {
  6043. ceDbgState->mHadSideEffects = true;
  6044. //SetAndRestoreValue<CeDebugger*> prevDebugger(mModule->mCompiler->mCeMachine->mDebugger, NULL);
  6045. evalFlags = (CeEvalFlags)(evalFlags | CeEvalFlags_DbgCall);
  6046. auto result = ceDbgState->mCeContext->Call(targetSrc, mModule, methodInstance, irArgs, evalFlags, mExpectingType);
  6047. if (result)
  6048. return result;
  6049. }
  6050. else
  6051. {
  6052. ceDbgState->mBlockedSideEffects = true;
  6053. }
  6054. }
  6055. else
  6056. {
  6057. CeCallSource ceCallSource(targetSrc);
  6058. ceCallSource.mOrigCalleeType = origTargetType;
  6059. auto constRet = mModule->mCompiler->mCeMachine->Call(ceCallSource, mModule, methodInstance, irArgs, evalFlags, mExpectingType);
  6060. if (constRet)
  6061. {
  6062. auto constant = mModule->mBfIRBuilder->GetConstant(constRet.mValue);
  6063. BF_ASSERT(!constRet.mType->IsVar());
  6064. return constRet;
  6065. }
  6066. if (mModule->mCompiler->mFastFinish)
  6067. {
  6068. if ((mModule->mCurMethodInstance == NULL) || (!mModule->mCurMethodInstance->mIsAutocompleteMethod))
  6069. {
  6070. // We didn't properly resolve this so queue for a rebuild later
  6071. mModule->DeferRebuildType(mModule->mCurTypeInstance);
  6072. }
  6073. }
  6074. doConstReturn = true;
  6075. }
  6076. }
  6077. }
  6078. else if (mModule->mIsComptimeModule)
  6079. {
  6080. //TODO: This meant that unspecialized types were not even allowed to have Init methods that called into themselves
  6081. // if (methodInstance->mIsUnspecialized)
  6082. // {
  6083. // doConstReturn = true;
  6084. // }
  6085. // else
  6086. {
  6087. mModule->mCompiler->mCeMachine->QueueMethod(methodInstance, func);
  6088. }
  6089. }
  6090. if (doConstReturn)
  6091. {
  6092. if ((returnType->IsVar()) && (mExpectingType != NULL))
  6093. returnType = mExpectingType;
  6094. if (returnType->IsRef())
  6095. {
  6096. return _GetDefaultReturnValue();
  6097. }
  6098. else
  6099. {
  6100. if (returnType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef))
  6101. {
  6102. if ((mExpectingType != NULL) && (mExpectingType->IsUndefSizedArray()))
  6103. {
  6104. if (returnType->GetUnderlyingType() == mExpectingType->GetUnderlyingType())
  6105. return mModule->GetDefaultTypedValue(mExpectingType, true, BfDefaultValueKind_Undef);
  6106. }
  6107. }
  6108. if (methodInstance->mReturnType->IsValuelessType())
  6109. return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), returnType);
  6110. return mModule->GetDefaultTypedValue(returnType, true, BfDefaultValueKind_Undef);
  6111. }
  6112. return _GetDefaultReturnValue();
  6113. }
  6114. }
  6115. if (!forceBind)
  6116. {
  6117. if (((!func) && (methodInstance->mIsUnspecialized)) || (mModule->mBfIRBuilder->mIgnoreWrites))
  6118. {
  6119. // We don't actually submit method calls for unspecialized methods
  6120. // - this includes all methods in unspecialized types
  6121. return _GetDefaultReturnValue();
  6122. }
  6123. }
  6124. if (methodInstance->mVirtualTableIdx != -1)
  6125. {
  6126. if ((!bypassVirtual) && (mDeferCallData == NULL))
  6127. {
  6128. if ((methodDef->mIsOverride) && (mModule->mCurMethodInstance->mIsReified))
  6129. {
  6130. // Ensure that declaring method gets referenced
  6131. auto typeInstance = methodInstance->GetOwner();
  6132. auto& vEntry = typeInstance->mVirtualMethodTable[methodInstance->mVirtualTableIdx];
  6133. BfMethodInstance* declaringMethodInstance = vEntry.mDeclaringMethod;
  6134. if ((declaringMethodInstance->mMethodInstanceGroup->mOnDemandKind < BfMethodOnDemandKind_InWorkList) || (!declaringMethodInstance->mIsReified))
  6135. mModule->GetMethodInstance(declaringMethodInstance);
  6136. }
  6137. auto funcType = mModule->mBfIRBuilder->MapMethod(methodInstance);
  6138. auto funcPtrType1 = mModule->mBfIRBuilder->GetPointerTo(funcType);
  6139. auto funcPtrType2 = mModule->mBfIRBuilder->GetPointerTo(funcPtrType1);
  6140. auto funcPtrType3 = mModule->mBfIRBuilder->GetPointerTo(funcPtrType2);
  6141. auto funcPtrType4 = mModule->mBfIRBuilder->GetPointerTo(funcPtrType3);
  6142. if (methodInstance->mMethodInstanceGroup->mOwner->IsInterface())
  6143. {
  6144. if (mModule->mIsComptimeModule)
  6145. {
  6146. funcCallInst = mModule->mBfIRBuilder->Comptime_GetInterfaceFunc(irArgs[0], methodInstance->mMethodInstanceGroup->mOwner->mTypeId, methodInstance->mMethodDef->mIdx, funcPtrType1);
  6147. }
  6148. else
  6149. {
  6150. // IFace dispatch
  6151. auto ifaceTypeInst = methodInstance->mMethodInstanceGroup->mOwner;
  6152. BfIRValue slotOfs = mModule->GetInterfaceSlotNum(methodInstance->mMethodInstanceGroup->mOwner);
  6153. auto vDataPtrPtr = mModule->mBfIRBuilder->CreateBitCast(irArgs[0], funcPtrType4);
  6154. auto vDataPtr = mModule->FixClassVData(mModule->mBfIRBuilder->CreateLoad(vDataPtrPtr/*, "vtable"*/));
  6155. auto ifacePtrPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(vDataPtr, slotOfs/*, "iface"*/);
  6156. auto ifacePtr = mModule->mBfIRBuilder->CreateLoad(ifacePtrPtr);
  6157. auto funcPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(ifacePtr, methodInstance->mVirtualTableIdx/*, "vfn"*/);
  6158. funcCallInst = mModule->mBfIRBuilder->CreateLoad(funcPtr);
  6159. }
  6160. }
  6161. else if (mModule->mIsComptimeModule)
  6162. {
  6163. funcCallInst = mModule->mBfIRBuilder->Comptime_GetVirtualFunc(irArgs[0], methodInstance->mVirtualTableIdx, funcPtrType1);
  6164. }
  6165. else
  6166. {
  6167. mModule->HadSlotCountDependency();
  6168. // Virtual dispatch
  6169. // int vDataIdx = 0;
  6170. // vDataIdx += 1 + methodInstance->GetOwner()->GetDynCastVDataCount() + mModule->mCompiler->mMaxInterfaceSlots;
  6171. BfIRValue vDataPtr;
  6172. BfIRValue vDataIdx;
  6173. if ((mModule->mCompiler->mOptions.mHasVDataExtender) && (mModule->mCompiler->IsHotCompile()))
  6174. {
  6175. auto typeInst = methodInstance->mMethodInstanceGroup->mOwner;
  6176. int extMethodIdx = (methodInstance->mVirtualTableIdx - typeInst->GetImplBaseVTableSize()) - typeInst->GetOrigSelfVTableSize();
  6177. if (extMethodIdx >= 0)
  6178. {
  6179. BF_ASSERT(mModule->mCompiler->IsHotCompile());
  6180. // We have grown outside our original virtual table, Load the new vdataPtr from the mHasVDataExtender
  6181. // vDataPtr = obj.vtable.extension.entry[curVersion]
  6182. BfIRValue vDataPtrPtr = mModule->mBfIRBuilder->CreateBitCast(irArgs[0], funcPtrType4);
  6183. vDataPtr = mModule->FixClassVData(mModule->mBfIRBuilder->CreateLoad(vDataPtrPtr));
  6184. // The offset of the vExt is one past the base vtable. When a base class extends its virtual table, an entry
  6185. // for that new method is inserted in mVirtualMethodTable (thus increasing the index relative to GetBaseVTableSize()),
  6186. // but the actual written vtable position doesn't change, hence offsetting from GetOrigBaseVTableSize()
  6187. #ifdef _DEBUG
  6188. int vExtIdx = typeInst->GetImplBaseVTableSize();
  6189. BF_ASSERT(typeInst->mVirtualMethodTable[vExtIdx].mDeclaringMethod.mMethodNum == -1); // A type entry with a -1 mMethodNum means it's a vtable ext slot
  6190. #endif
  6191. int vExtOfs = typeInst->GetOrigImplBaseVTableSize();
  6192. vDataIdx = mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, mModule->mCompiler->GetVDataPrefixDataCount() + mModule->mCompiler->GetDynCastVDataCount() + mModule->mCompiler->mMaxInterfaceSlots);
  6193. vDataIdx = mModule->mBfIRBuilder->CreateAdd(vDataIdx, mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, vExtOfs));
  6194. BfIRValue extendPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(vDataPtr, vDataIdx);
  6195. vDataPtr = mModule->mBfIRBuilder->CreateLoad(extendPtr);
  6196. vDataIdx = mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, extMethodIdx);
  6197. }
  6198. else
  6199. {
  6200. // Map this new virtual index back to the original index
  6201. // Find the type instance that declared the original method
  6202. auto declTypeInst = typeInst;
  6203. while (declTypeInst->mBaseType != NULL)
  6204. {
  6205. mModule->PopulateType(declTypeInst->mBaseType, BfPopulateType_DataAndMethods);
  6206. if (methodInstance->mVirtualTableIdx >= declTypeInst->mBaseType->mVirtualMethodTableSize)
  6207. break;
  6208. BF_ASSERT(methodInstance->mMethodDef->mIsOverride);
  6209. declTypeInst = declTypeInst->mBaseType;
  6210. }
  6211. vDataIdx = mModule->mBfIRBuilder->GetConfigConst(BfIRConfigConst_VirtualMethodOfs, BfTypeCode_Int32);
  6212. vDataIdx = mModule->mBfIRBuilder->CreateAdd(vDataIdx, mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32,
  6213. (methodInstance->mVirtualTableIdx - declTypeInst->GetImplBaseVTableSize()) + declTypeInst->GetOrigImplBaseVTableSize()));
  6214. }
  6215. }
  6216. else
  6217. {
  6218. vDataIdx = mModule->mBfIRBuilder->GetConfigConst(BfIRConfigConst_VirtualMethodOfs, BfTypeCode_Int32);
  6219. vDataIdx = mModule->mBfIRBuilder->CreateAdd(vDataIdx, mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, methodInstance->mVirtualTableIdx));
  6220. }
  6221. if (!vDataPtr)
  6222. {
  6223. BfIRValue vDataPtrPtr = mModule->mBfIRBuilder->CreateBitCast(irArgs[0], funcPtrType3);
  6224. vDataPtr = mModule->FixClassVData(mModule->mBfIRBuilder->CreateLoad(vDataPtrPtr/*, "vtable"*/));
  6225. }
  6226. auto funcPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(vDataPtr, vDataIdx/*, "vfn"*/);
  6227. funcCallInst = mModule->mBfIRBuilder->CreateLoad(funcPtr);
  6228. }
  6229. }
  6230. }
  6231. else // non-virtual
  6232. {
  6233. if (methodInstance->GetOwner()->IsInterface())
  6234. {
  6235. // We're attempting to directly invoke a non-virtual interface method, this will happen during the unspecialized pass
  6236. // OR if we had an error and didn't find an implementing member in the actual target
  6237. if (((mModule->mCurMethodInstance == NULL) || (!mModule->mCurMethodInstance->mIsUnspecialized)) &&
  6238. (!mModule->mCurTypeInstance->IsInterface()))
  6239. mModule->AssertErrorState();
  6240. if (returnType->IsInterface())
  6241. returnType = mModule->CreateConcreteInterfaceType(returnType->ToTypeInstance());
  6242. return _GetDefaultReturnValue();
  6243. }
  6244. }
  6245. if (mFunctionBindResult != NULL)
  6246. {
  6247. mFunctionBindResult->mFunc = funcCallInst;
  6248. if (irArgs.size() != 0)
  6249. {
  6250. auto targetType = methodInstance->mMethodInstanceGroup->mOwner;
  6251. if ((targetType->IsValueType()) && (targetType->IsSplattable()) && (!methodDef->HasNoThisSplat()) && (!IsComptime()))
  6252. mFunctionBindResult->mTarget = BfTypedValue(irArgs[0], targetType, BfTypedValueKind_SplatHead);
  6253. else
  6254. mFunctionBindResult->mTarget = BfTypedValue(irArgs[0], targetType, targetType->IsComposite() ? BfTypedValueKind_Addr : BfTypedValueKind_Value);
  6255. }
  6256. else
  6257. {
  6258. mFunctionBindResult->mTarget = BfTypedValue();
  6259. }
  6260. return BfTypedValue();
  6261. }
  6262. if (methodInstance->mReturnType == NULL)
  6263. {
  6264. mModule->AssertErrorState();
  6265. return BfTypedValue();
  6266. }
  6267. if (((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsUnspecialized)) && (mModule->mBfIRBuilder->mIgnoreWrites))
  6268. {
  6269. // Don't actually do the call - our target may be a generic param
  6270. return _GetDefaultReturnValue();
  6271. }
  6272. if (mDeferCallData != NULL)
  6273. {
  6274. if ((func) && (mDeferCallData->mFuncAlloca_Orig == func))
  6275. mModule->AddDeferredCall(BfModuleMethodInstance(methodInstance, mDeferCallData->mFuncAlloca), irArgs, mDeferCallData->mScopeAlloc, mDeferCallData->mRefNode, bypassVirtual, false, true);
  6276. else
  6277. mModule->AddDeferredCall(BfModuleMethodInstance(methodInstance, func), irArgs, mDeferCallData->mScopeAlloc, mDeferCallData->mRefNode, bypassVirtual);
  6278. return mModule->GetFakeTypedValue(returnType);
  6279. }
  6280. if (!funcCallInst)
  6281. {
  6282. if ((mModule->HasCompiledOutput()) || (mModule->mCompiler->mOptions.mExtraResolveChecks))
  6283. {
  6284. // This can happen either from an error, or from the resolver while doing Internals_Changed processing
  6285. mModule->AssertErrorState();
  6286. }
  6287. return _GetDefaultReturnValue();
  6288. }
  6289. bool hasResult = !methodInstance->mReturnType->IsValuelessType();
  6290. BfIRValue firstArg;
  6291. if (irArgs.size() != 0)
  6292. firstArg = irArgs[0];
  6293. auto methodInstOwner = methodInstance->GetOwner();
  6294. auto expectCallingConvention = mModule->GetIRCallingConvention(methodInstance);
  6295. if ((methodInstOwner->IsFunction()) && (methodInstance->GetParamCount() > 0) && (methodInstance->GetParamName(0) == "this"))
  6296. {
  6297. auto paramType = methodInstance->GetParamType(0);
  6298. if (!paramType->IsValueType())
  6299. expectCallingConvention = BfIRCallingConv_ThisCall;
  6300. }
  6301. if (((callFlags & BfCreateCallFlags_DelegateThunkStatic) != 0) && (expectCallingConvention == BfIRCallingConv_ThisCall))
  6302. expectCallingConvention = BfIRCallingConv_CDecl;
  6303. if ((methodInstance->mAlwaysInline) && (mModule->mCompiler->mOptions.mEmitLineInfo))
  6304. {
  6305. // Emit a NOP so we always have a "step over" point
  6306. mModule->EmitEnsureInstructionAt();
  6307. }
  6308. if (returnType->IsComposite())
  6309. mModule->mBfIRBuilder->PopulateType(returnType);
  6310. methodInstance->mMethodInstanceGroup->mHasEmittedReference = true;
  6311. BfIRValue callInst;
  6312. int callIRArgCount = (int)irArgs.size();
  6313. if (sret != NULL)
  6314. {
  6315. SizedArray<BfIRValue, 8> sretIRArgs;
  6316. int sretIdx = GetStructRetIdx(methodInstance);
  6317. int inIdx = 0;
  6318. for (int outIdx = 0; outIdx < irArgs.size() + 1; outIdx++)
  6319. {
  6320. if (outIdx == sretIdx)
  6321. {
  6322. sretIRArgs.Add(sret->mValue);
  6323. continue;
  6324. }
  6325. sretIRArgs.Add(irArgs[inIdx++]);
  6326. }
  6327. callInst = mModule->mBfIRBuilder->CreateCall(funcCallInst, sretIRArgs);
  6328. callIRArgCount++;
  6329. }
  6330. else
  6331. {
  6332. callInst = mModule->mBfIRBuilder->CreateCall(funcCallInst, irArgs);
  6333. if ((hasResult) && (!methodDef->mName.IsEmpty()) && (!methodInstance->mIsIntrinsic))
  6334. mModule->mBfIRBuilder->SetName(callInst, methodDef->mName);
  6335. }
  6336. if ((expectCallingConvention != BfIRCallingConv_CDecl) && (!methodInstance->mIsIntrinsic))
  6337. mModule->mBfIRBuilder->SetCallCallingConv(callInst, expectCallingConvention);
  6338. if ((methodDef->mIsNoReturn) && (!methodInstance->mIsIntrinsic))
  6339. mModule->mBfIRBuilder->Call_AddAttribute(callInst, -1, BfIRAttribute_NoReturn);
  6340. bool hadAttrs = false;
  6341. int paramIdx = 0;
  6342. bool doingThis = methodInstance->HasThis();
  6343. int argIdx = 0;
  6344. if ((callFlags & BfCreateCallFlags_DelegateThunkStatic) != 0)
  6345. doingThis = false;
  6346. bool forceThisPtr = ((callFlags & BfCreateCallFlags_DelegateThunkNonStatic) != 0);
  6347. if (methodDef->mHasExplicitThis)
  6348. paramIdx++;
  6349. int paramCount = methodInstance->GetParamCount();
  6350. for ( ; argIdx < callIRArgCount ; )
  6351. {
  6352. if (methodInstance->mIsIntrinsic)
  6353. break;
  6354. if ((sret != NULL) && (argIdx == GetStructRetIdx(methodInstance)))
  6355. {
  6356. mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_StructRet);
  6357. argIdx++;
  6358. continue;
  6359. }
  6360. auto _HandleParamType = [&] (BfType* paramType)
  6361. {
  6362. if (paramType->IsStruct())
  6363. {
  6364. if ((!doingThis) || (!methodDef->mIsMutating && methodInstance->AllowsSplatting(paramIdx)))
  6365. {
  6366. BfTypeCode loweredTypeCode = BfTypeCode_None;
  6367. BfTypeCode loweredTypeCode2 = BfTypeCode_None;
  6368. if (paramType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2))
  6369. {
  6370. argIdx++;
  6371. if (loweredTypeCode2 != BfTypeCode_None)
  6372. argIdx++;
  6373. return; // Lowering never requires attributes
  6374. }
  6375. }
  6376. }
  6377. int addDeref = -1;
  6378. if (paramType->IsRef())
  6379. {
  6380. auto refType = (BfRefType*)paramType;
  6381. auto elementType = refType->mElementType;
  6382. mModule->PopulateType(elementType, BfPopulateType_Data);
  6383. addDeref = elementType->mSize;
  6384. if ((addDeref <= 0) && (!elementType->IsValuelessType()))
  6385. mModule->AssertErrorState();
  6386. }
  6387. if ((paramType->IsComposite()) && (!paramType->IsTypedPrimitive()))
  6388. {
  6389. if (mModule->mCompiler->mOptions.mAllowStructByVal)
  6390. {
  6391. //byval
  6392. }
  6393. else
  6394. {
  6395. mModule->PopulateType(paramType, BfPopulateType_Data);
  6396. auto typeInst = paramType->ToTypeInstance();
  6397. if ((typeInst != NULL) && (typeInst->mIsCRepr) && (typeInst->IsSplattable()) && (!IsComptime()))
  6398. {
  6399. // We're splatting
  6400. }
  6401. else
  6402. {
  6403. if (doingThis)
  6404. {
  6405. mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_NoCapture);
  6406. addDeref = paramType->mSize;
  6407. }
  6408. else if (methodInstance->WantsStructsAttribByVal(paramType))
  6409. {
  6410. mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_ByVal, mModule->mSystem->mPtrSize);
  6411. }
  6412. }
  6413. }
  6414. }
  6415. else if (paramType->IsPrimitiveType())
  6416. {
  6417. auto primType = (BfPrimitiveType*)paramType;
  6418. if ((primType->mTypeDef->mTypeCode == BfTypeCode_Boolean) && (!methodInstance->mIsIntrinsic))
  6419. mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_ZExt);
  6420. }
  6421. if (addDeref >= 0)
  6422. {
  6423. mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_Dereferencable, addDeref);
  6424. }
  6425. argIdx++;
  6426. };
  6427. BfType* paramType = NULL;
  6428. if (doingThis)
  6429. {
  6430. int thisIdx = methodInstance->GetThisIdx();
  6431. paramType = methodInstance->GetThisType();
  6432. if (paramType->IsValuelessType())
  6433. {
  6434. doingThis = false;
  6435. continue;
  6436. }
  6437. bool isSplatted = methodInstance->GetParamIsSplat(thisIdx) && (!IsComptime()); // (resolvedTypeRef->IsSplattable()) && (!methodDef->mIsMutating);
  6438. if (isSplatted)
  6439. {
  6440. BfTypeUtils::SplatIterate(_HandleParamType, paramType);
  6441. doingThis = false;
  6442. continue;
  6443. }
  6444. else
  6445. _HandleParamType(paramType);
  6446. }
  6447. else
  6448. {
  6449. if (paramIdx >= methodInstance->GetParamCount())
  6450. break;
  6451. paramType = methodInstance->GetParamType(paramIdx);
  6452. BfTypeCode loweredTypeCode = BfTypeCode_None;
  6453. BfTypeCode loweredTypeCode2 = BfTypeCode_None;
  6454. if (paramType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2))
  6455. {
  6456. argIdx++;
  6457. paramIdx++;
  6458. if (loweredTypeCode2 != BfTypeCode_None)
  6459. argIdx++;
  6460. continue;
  6461. }
  6462. if ((paramType->IsValuelessType()) && (!paramType->IsMethodRef()))
  6463. {
  6464. paramIdx++;
  6465. continue;
  6466. }
  6467. if ((methodInstance->GetParamIsSplat(paramIdx)) && (!IsComptime()))
  6468. {
  6469. BfTypeUtils::SplatIterate(_HandleParamType, paramType);
  6470. paramIdx++;
  6471. continue;
  6472. }
  6473. else
  6474. _HandleParamType(methodInstance->GetParamType(paramIdx));
  6475. }
  6476. if (doingThis)
  6477. doingThis = false;
  6478. else
  6479. paramIdx++;
  6480. //argIdx++;
  6481. }
  6482. if ((callFlags & BfCreateCallFlags_TailCall) != 0)
  6483. mModule->mBfIRBuilder->SetTailCall(callInst);
  6484. if (methodDef->mIsNoReturn)
  6485. {
  6486. mModule->mBfIRBuilder->CreateUnreachable();
  6487. // For debuggability when looking back at stack trace
  6488. //mModule->ExtendLocalLifetimes(0);
  6489. if (mModule->IsTargetingBeefBackend())
  6490. {
  6491. auto checkScope = mModule->mCurMethodState->mCurScope;
  6492. while (checkScope != NULL)
  6493. {
  6494. mModule->EmitLifetimeEnds(checkScope);
  6495. checkScope = checkScope->mPrevScope;
  6496. }
  6497. // This 'fake' branch extends lifetimes of outer variable scopes
  6498. if (mModule->mCurMethodState->mIRExitBlock)
  6499. mModule->mBfIRBuilder->CreateBr_Fake(mModule->mCurMethodState->mIRExitBlock);
  6500. }
  6501. }
  6502. else
  6503. {
  6504. if (mModule->mCurMethodState != NULL)
  6505. mModule->mCurMethodState->mMayNeedThisAccessCheck = true;
  6506. }
  6507. if (isDelegateThunk)
  6508. return BfTypedValue(callInst, methodInstance->mReturnType);
  6509. BfTypedValue result;
  6510. if (sret != NULL)
  6511. result = *sret;
  6512. else if (hasResult)
  6513. {
  6514. BfTypeCode loweredRetType = BfTypeCode_None;
  6515. BfTypeCode loweredRetType2 = BfTypeCode_None;
  6516. if ((!IsComptime()) && (methodInstance->GetLoweredReturnType(&loweredRetType, &loweredRetType2)) && (loweredRetType != BfTypeCode_None))
  6517. {
  6518. auto retVal = mModule->CreateAlloca(methodInstance->mReturnType);
  6519. BfIRType loweredIRType = mModule->GetIRLoweredType(loweredRetType, loweredRetType2);
  6520. loweredIRType = mModule->mBfIRBuilder->GetPointerTo(loweredIRType);
  6521. auto castedRetVal = mModule->mBfIRBuilder->CreateBitCast(retVal, loweredIRType);
  6522. mModule->mBfIRBuilder->CreateStore(callInst, castedRetVal);
  6523. result = BfTypedValue(retVal, methodInstance->mReturnType, BfTypedValueKind_RestrictedTempAddr);
  6524. }
  6525. else
  6526. result = BfTypedValue(callInst, methodInstance->mReturnType);
  6527. }
  6528. else
  6529. result = mModule->GetFakeTypedValue(methodInstance->mReturnType);
  6530. if (result.mType->IsRef())
  6531. {
  6532. result = mModule->RemoveRef(result);
  6533. if (methodDef->mIsReadOnly)
  6534. {
  6535. if (result.mKind == BfTypedValueKind_Addr)
  6536. result.mKind = BfTypedValueKind_ReadOnlyAddr;
  6537. }
  6538. }
  6539. return result;
  6540. }
  6541. BfTypedValue BfExprEvaluator::CreateCall(BfMethodMatcher* methodMatcher, BfTypedValue target)
  6542. {
  6543. auto moduleMethodInstance = GetSelectedMethod(*methodMatcher);
  6544. if (moduleMethodInstance.mMethodInstance == NULL)
  6545. return BfTypedValue();
  6546. if ((target) && (target.mType != moduleMethodInstance.mMethodInstance->GetOwner()))
  6547. {
  6548. auto castedTarget = mModule->Cast(methodMatcher->mTargetSrc, target, moduleMethodInstance.mMethodInstance->GetOwner());
  6549. BF_ASSERT(castedTarget);
  6550. target = castedTarget;
  6551. }
  6552. PerformCallChecks(moduleMethodInstance.mMethodInstance, methodMatcher->mTargetSrc);
  6553. BfCreateCallFlags callFlags = BfCreateCallFlags_None;
  6554. if (methodMatcher->mAllowImplicitRef)
  6555. callFlags = (BfCreateCallFlags)(callFlags | BfCreateCallFlags_AllowImplicitRef);
  6556. return CreateCall(methodMatcher->mTargetSrc, target, BfTypedValue(), methodMatcher->mBestMethodDef, moduleMethodInstance, callFlags, methodMatcher->mArguments);
  6557. }
  6558. void BfExprEvaluator::MakeBaseConcrete(BfTypedValue& typedValue)
  6559. {
  6560. if (typedValue.IsBase())
  6561. {
  6562. auto baseType = mModule->mCurTypeInstance->mBaseType;
  6563. if (baseType == NULL)
  6564. baseType = mModule->mContext->mBfObjectType;
  6565. mModule->PopulateType(baseType, BfPopulateType_Data);
  6566. typedValue = mModule->Cast(NULL, typedValue, baseType, BfCastFlags_Explicit);
  6567. }
  6568. }
  6569. void BfExprEvaluator::SplatArgs(BfTypedValue value, SizedArrayImpl<BfIRValue>& irArgs)
  6570. {
  6571. if (value.IsSplat())
  6572. {
  6573. int componentIdx = 0;
  6574. BfTypeUtils::SplatIterate([&](BfType* checkType) { irArgs.push_back(mModule->ExtractSplatValue(value, componentIdx++, checkType)); }, value.mType);
  6575. return;
  6576. }
  6577. mModule->mBfIRBuilder->PopulateType(value.mType);
  6578. std::function<void(BfTypedValue)> checkTypeLambda = [&](BfTypedValue curValue)
  6579. {
  6580. BfType* checkType = curValue.mType;
  6581. if (checkType->IsStruct())
  6582. {
  6583. auto checkTypeInstance = checkType->ToTypeInstance();
  6584. if (checkTypeInstance->mBaseType != NULL)
  6585. mModule->PopulateType(checkTypeInstance->mBaseType);
  6586. if ((checkTypeInstance->mBaseType != NULL) && (!checkTypeInstance->mBaseType->IsValuelessType()))
  6587. {
  6588. BfTypedValue baseValue;
  6589. if (curValue.IsAddr())
  6590. baseValue = BfTypedValue((!curValue.mValue) ? BfIRValue() : mModule->mBfIRBuilder->CreateInBoundsGEP(curValue.mValue, 0, 0), checkTypeInstance->mBaseType, true);
  6591. else
  6592. baseValue = BfTypedValue((!curValue.mValue) ? BfIRValue() : mModule->mBfIRBuilder->CreateExtractValue(curValue.mValue, 0), checkTypeInstance->mBaseType);
  6593. checkTypeLambda(baseValue);
  6594. }
  6595. if (checkTypeInstance->mIsUnion)
  6596. {
  6597. auto unionInnerType = checkTypeInstance->GetUnionInnerType();
  6598. if (!unionInnerType->IsValuelessType())
  6599. {
  6600. BfTypedValue unionValue = mModule->ExtractValue(curValue, NULL, 1);
  6601. checkTypeLambda(unionValue);
  6602. }
  6603. if (checkTypeInstance->IsEnum())
  6604. {
  6605. BfTypedValue dscrValue = mModule->ExtractValue(curValue, NULL, 2);
  6606. checkTypeLambda(dscrValue);
  6607. }
  6608. }
  6609. else
  6610. {
  6611. for (int fieldIdx = 0; fieldIdx < (int)checkTypeInstance->mFieldInstances.size(); fieldIdx++)
  6612. {
  6613. auto fieldInstance = (BfFieldInstance*)&checkTypeInstance->mFieldInstances[fieldIdx];
  6614. if (fieldInstance->mDataIdx >= 0)
  6615. {
  6616. BfTypedValue fieldValue = mModule->ExtractValue(curValue, fieldInstance, fieldInstance->mDataIdx);
  6617. checkTypeLambda(fieldValue);
  6618. }
  6619. }
  6620. }
  6621. }
  6622. else if (checkType->IsMethodRef())
  6623. {
  6624. BF_ASSERT(curValue.IsAddr());
  6625. BfMethodRefType* methodRefType = (BfMethodRefType*)checkType;
  6626. for (int dataIdx = 0; dataIdx < methodRefType->GetCaptureDataCount(); dataIdx++)
  6627. {
  6628. auto checkType = methodRefType->GetCaptureType(dataIdx);
  6629. if (methodRefType->WantsDataPassedAsSplat(dataIdx))
  6630. {
  6631. BF_ASSERT(dataIdx == 0);
  6632. auto ptrType = mModule->CreatePointerType(checkType);
  6633. auto elemPtr = mModule->mBfIRBuilder->CreateBitCast(curValue.mValue, mModule->mBfIRBuilder->MapType(ptrType));
  6634. checkTypeLambda(BfTypedValue(elemPtr, checkType, BfTypedValueKind_Addr));
  6635. //BfTypedValue fieldValue = mModule->ExtractValue(curValue, fieldInstance, fieldInstance->mDataIdx);
  6636. //checkTypeLambda(fieldValue);
  6637. }
  6638. else
  6639. {
  6640. auto elemVal = mModule->mBfIRBuilder->CreateInBoundsGEP(curValue.mValue, 0, dataIdx);
  6641. if (!checkType->IsComposite())
  6642. elemVal = mModule->mBfIRBuilder->CreateLoad(elemVal);
  6643. irArgs.Add(elemVal);
  6644. //irArgs.Add(mModule->ExtractValue(curValue, dataIdx));
  6645. }
  6646. }
  6647. }
  6648. else if (!checkType->IsValuelessType())
  6649. {
  6650. auto loadedVal = mModule->LoadValue(curValue);
  6651. loadedVal = mModule->PrepareConst(loadedVal);
  6652. irArgs.push_back(loadedVal.mValue);
  6653. }
  6654. };
  6655. checkTypeLambda(value);
  6656. }
  6657. void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl<BfIRValue>& irArgs, bool disableSplat, bool disableLowering, bool isIntrinsic, bool createCompositeCopy)
  6658. {
  6659. MakeBaseConcrete(argVal);
  6660. if (IsVar(argVal.mType))
  6661. {
  6662. argVal = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  6663. }
  6664. if (argVal.mType->IsIncomplete())
  6665. mModule->PopulateType(argVal.mType);
  6666. if (argVal.mType->IsValuelessNonOpaqueType())
  6667. return;
  6668. bool wantSplat = false;
  6669. if ((argVal.mType->IsSplattable()) && (!disableSplat) && (!IsComptime()))
  6670. {
  6671. disableLowering = true;
  6672. auto argTypeInstance = argVal.mType->ToTypeInstance();
  6673. if (!disableSplat)
  6674. {
  6675. if ((argTypeInstance != NULL) && (argTypeInstance->mIsCRepr))
  6676. wantSplat = true;
  6677. else if ((int)irArgs.size() + argVal.mType->GetSplatCount() <= mModule->mCompiler->mOptions.mMaxSplatRegs)
  6678. wantSplat = true;
  6679. }
  6680. }
  6681. if (wantSplat)
  6682. {
  6683. SplatArgs(argVal, irArgs);
  6684. }
  6685. else
  6686. {
  6687. if (argVal.mType->IsComposite())
  6688. {
  6689. if ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0)
  6690. {
  6691. // Const eval entry - we want any incoming consts as they are
  6692. }
  6693. else if (isIntrinsic)
  6694. {
  6695. // We can handle composites either by value or not
  6696. }
  6697. else
  6698. argVal = mModule->MakeAddressable(argVal);
  6699. if ((!IsComptime()) && (!disableLowering) && (!isIntrinsic))
  6700. {
  6701. BfTypeCode loweredTypeCode = BfTypeCode_None;
  6702. BfTypeCode loweredTypeCode2 = BfTypeCode_None;
  6703. if (argVal.mType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2))
  6704. {
  6705. BfIRValue argPtrVal = argVal.mValue;
  6706. int loweredSize = mModule->mBfIRBuilder->GetSize(loweredTypeCode) + mModule->mBfIRBuilder->GetSize(loweredTypeCode2);
  6707. if (argVal.mType->mSize < loweredSize)
  6708. {
  6709. auto allocaVal = mModule->CreateAlloca(mModule->GetPrimitiveType(BfTypeCode_UInt8), true, NULL, mModule->GetConstValue(loweredSize));
  6710. mModule->mBfIRBuilder->SetAllocaAlignment(allocaVal,
  6711. BF_MAX(argVal.mType->mAlign,
  6712. BF_MAX(mModule->mBfIRBuilder->GetSize(loweredTypeCode), mModule->mBfIRBuilder->GetSize(loweredTypeCode2))));
  6713. auto castedPtr = mModule->mBfIRBuilder->CreateBitCast(allocaVal, mModule->mBfIRBuilder->MapType(mModule->CreatePointerType(argVal.mType)));
  6714. auto argIRVal = mModule->mBfIRBuilder->CreateAlignedLoad(argVal.mValue, argVal.mType->mAlign);
  6715. mModule->mBfIRBuilder->CreateAlignedStore(argIRVal, castedPtr, argVal.mType->mAlign);
  6716. argPtrVal = castedPtr;
  6717. }
  6718. auto primType = mModule->mBfIRBuilder->GetPrimitiveType(loweredTypeCode);
  6719. auto ptrType = mModule->mBfIRBuilder->GetPointerTo(primType);
  6720. BfIRValue primPtrVal = mModule->mBfIRBuilder->CreateBitCast(argPtrVal, ptrType);
  6721. auto primVal = mModule->mBfIRBuilder->CreateLoad(primPtrVal);
  6722. irArgs.push_back(primVal);
  6723. if (loweredTypeCode2 != BfTypeCode_None)
  6724. {
  6725. auto primType2 = mModule->mBfIRBuilder->GetPrimitiveType(loweredTypeCode2);
  6726. auto ptrType2 = mModule->mBfIRBuilder->GetPointerTo(primType2);
  6727. BfIRValue primPtrVal2;
  6728. if (mModule->mBfIRBuilder->GetSize(loweredTypeCode) < mModule->mBfIRBuilder->GetSize(loweredTypeCode2))
  6729. primPtrVal2 = mModule->mBfIRBuilder->CreateInBoundsGEP(mModule->mBfIRBuilder->CreateBitCast(primPtrVal, ptrType2), 1);
  6730. else
  6731. primPtrVal2 = mModule->mBfIRBuilder->CreateBitCast(mModule->mBfIRBuilder->CreateInBoundsGEP(primPtrVal, 1), ptrType2);
  6732. auto primVal2 = mModule->mBfIRBuilder->CreateLoad(primPtrVal2);
  6733. irArgs.Add(primVal2);
  6734. }
  6735. return;
  6736. }
  6737. }
  6738. if ((createCompositeCopy) && (!argVal.IsTempAddr()))
  6739. {
  6740. // Non-Beef calling conventions require copies of composites
  6741. auto copyAddr = mModule->CreateAlloca(argVal.mType);
  6742. mModule->mBfIRBuilder->CreateStore(mModule->LoadValue(argVal).mValue, copyAddr);
  6743. argVal = BfTypedValue(copyAddr, argVal.mType, BfTypedValueKind_TempAddr);
  6744. }
  6745. }
  6746. else
  6747. argVal = mModule->LoadValue(argVal);
  6748. irArgs.Add(argVal.mValue);
  6749. }
  6750. }
  6751. void BfExprEvaluator::PushThis(BfAstNode* targetSrc, BfTypedValue argVal, BfMethodInstance* methodInstance, SizedArrayImpl<BfIRValue>& irArgs, bool skipMutCheck)
  6752. {
  6753. MakeBaseConcrete(argVal);
  6754. auto methodDef = methodInstance->mMethodDef;
  6755. if (methodInstance->IsSkipCall())
  6756. return;
  6757. if (!argVal)
  6758. {
  6759. //BF_ASSERT(mFunctionBindResult != NULL);
  6760. return;
  6761. }
  6762. if (methodDef->mIsMutating)
  6763. {
  6764. bool checkMut = false;
  6765. if (argVal.mType->IsGenericParam())
  6766. {
  6767. // For capturing mutability
  6768. if (mResultLocalVar != NULL)
  6769. mResultLocalVar->mWrittenToId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++;
  6770. }
  6771. if (((argVal.mType->IsComposite()) || (argVal.mType->IsTypedPrimitive())))
  6772. {
  6773. if (argVal.IsCopyOnMutate())
  6774. argVal = mModule->CopyValue(argVal);
  6775. if ((argVal.IsReadOnly()) || (!argVal.IsAddr()))
  6776. {
  6777. if (!skipMutCheck)
  6778. {
  6779. String err = StrFormat("call mutating method '%s' on", mModule->MethodToString(methodInstance).c_str());
  6780. CheckModifyResult(argVal, targetSrc, err.c_str());
  6781. }
  6782. if (argVal.IsSplat())
  6783. {
  6784. argVal = mModule->AggregateSplat(argVal);
  6785. argVal = mModule->MakeAddressable(argVal);
  6786. }
  6787. }
  6788. else
  6789. {
  6790. if (mResultLocalVar != NULL)
  6791. {
  6792. // When we are capturing, we need to note that we require capturing by reference here
  6793. mResultLocalVar->mWrittenToId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++;
  6794. }
  6795. }
  6796. }
  6797. }
  6798. if (argVal.mType->IsValuelessNonOpaqueType())
  6799. return;
  6800. auto owner = methodInstance->GetOwner();
  6801. bool allowThisSplatting;
  6802. if (mModule->mIsComptimeModule)
  6803. allowThisSplatting = owner->IsTypedPrimitive() || owner->IsValuelessNonOpaqueType();
  6804. else
  6805. allowThisSplatting = methodInstance->AllowsSplatting(-1);
  6806. if ((!allowThisSplatting) || (methodDef->mIsMutating) || (methodInstance->ForcingThisPtr()))
  6807. {
  6808. argVal = mModule->MakeAddressable(argVal);
  6809. irArgs.push_back(argVal.mValue);
  6810. return;
  6811. }
  6812. auto thisType = methodInstance->GetThisType();
  6813. PushArg(argVal, irArgs, !methodInstance->AllowsSplatting(-1), thisType->IsPointer());
  6814. }
  6815. void BfExprEvaluator::FinishDeferredEvals(SizedArrayImpl<BfResolvedArg>& argValues)
  6816. {
  6817. for (int argIdx = 0; argIdx < argValues.size(); argIdx++)
  6818. {
  6819. auto& argValue = argValues[argIdx].mTypedValue;
  6820. if ((argValues[argIdx].mArgFlags & (BfArgFlag_DelegateBindAttempt | BfArgFlag_LambdaBindAttempt | BfArgFlag_UnqualifiedDotAttempt | BfArgFlag_DeferredEval)) != 0)
  6821. {
  6822. if (!argValue)
  6823. {
  6824. auto expr = BfNodeDynCast<BfExpression>(argValues[argIdx].mExpression);
  6825. if (expr != NULL)
  6826. argValue = mModule->CreateValueFromExpression(expr, argValues[argIdx].mExpectedType, BfEvalExprFlags_NoCast);
  6827. }
  6828. }
  6829. }
  6830. }
  6831. void BfExprEvaluator::FinishDeferredEvals(BfResolvedArgs& argValues)
  6832. {
  6833. for (int argIdx = 0; argIdx < (int)argValues.mResolvedArgs.size(); argIdx++)
  6834. {
  6835. auto& argValue = argValues.mResolvedArgs[argIdx].mTypedValue;
  6836. if ((argValues.mResolvedArgs[argIdx].mArgFlags & (BfArgFlag_VariableDeclaration)) != 0)
  6837. {
  6838. auto variableDeclaration = BfNodeDynCast<BfVariableDeclaration>((*argValues.mArguments)[argIdx]);
  6839. if ((variableDeclaration != NULL) && (variableDeclaration->mNameNode != NULL))
  6840. {
  6841. if (mModule->mCurMethodState == NULL)
  6842. {
  6843. mModule->Fail("Illegal local variable", variableDeclaration);
  6844. }
  6845. else
  6846. {
  6847. BfLocalVariable* localVar = new BfLocalVariable();
  6848. localVar->mName = variableDeclaration->mNameNode->ToString();
  6849. localVar->mResolvedType = mModule->GetPrimitiveType(BfTypeCode_Var);
  6850. localVar->mAddr = mModule->mBfIRBuilder->GetFakeVal();
  6851. localVar->mReadFromId = 0;
  6852. localVar->mWrittenToId = 0;
  6853. localVar->mAssignedKind = BfLocalVarAssignKind_Unconditional;
  6854. mModule->CheckVariableDef(localVar);
  6855. localVar->Init();
  6856. mModule->AddLocalVariableDef(localVar, true);
  6857. auto curScope = mModule->mCurMethodState->mCurScope;
  6858. if (curScope->mScopeKind == BfScopeKind_StatementTarget)
  6859. mModule->MoveLocalToParentScope(localVar);
  6860. }
  6861. }
  6862. }
  6863. }
  6864. FinishDeferredEvals(argValues.mResolvedArgs);
  6865. }
  6866. void BfExprEvaluator::AddCallDependencies(BfMethodInstance* methodInstance)
  6867. {
  6868. if (methodInstance->mReturnType != NULL)
  6869. mModule->AddDependency(methodInstance->mReturnType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage);
  6870. for (int paramIdx = 0; paramIdx < methodInstance->GetParamCount(); paramIdx++)
  6871. {
  6872. auto paramType = methodInstance->GetParamType(paramIdx);
  6873. mModule->AddDependency(paramType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage);
  6874. }
  6875. if (methodInstance->mMethodInfoEx != NULL)
  6876. {
  6877. for (auto genericArg : methodInstance->mMethodInfoEx->mMethodGenericArguments)
  6878. {
  6879. if (genericArg->IsWrappableType())
  6880. genericArg = mModule->GetWrappedStructType(genericArg);
  6881. if (genericArg != NULL)
  6882. mModule->AddDependency(genericArg, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage);
  6883. }
  6884. }
  6885. }
  6886. BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValue& inTarget, const BfTypedValue& origTarget, BfMethodDef* methodDef, BfModuleMethodInstance moduleMethodInstance, BfCreateCallFlags callFlags, SizedArrayImpl<BfResolvedArg>& argValues, BfTypedValue* argCascade)
  6887. {
  6888. SetAndRestoreValue<BfEvalExprFlags> prevEvalExprFlag(mBfEvalExprFlags);
  6889. if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) && (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mConstEvalAttributeTypeDef)))
  6890. {
  6891. mModule->mAttributeState->mUsed = true;
  6892. mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_Comptime);
  6893. }
  6894. else if ((moduleMethodInstance.mMethodInstance->mComptimeFlags & BfComptimeFlag_ConstEval) != 0)
  6895. {
  6896. mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_Comptime);
  6897. }
  6898. else if (((moduleMethodInstance.mMethodInstance->mComptimeFlags & BfComptimeFlag_Comptime) != 0) && (!mModule->mIsComptimeModule))
  6899. {
  6900. if ((mModule->mCurMethodInstance == NULL) || (mModule->mCurMethodInstance->mComptimeFlags == BfComptimeFlag_None))
  6901. mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_Comptime);
  6902. }
  6903. SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, mModule->mBfIRBuilder->mIgnoreWrites || IsConstEval());
  6904. if (((moduleMethodInstance.mMethodInstance->mComptimeFlags & BfComptimeFlag_OnlyFromComptime) != 0) &&
  6905. ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) &&
  6906. ((mModule->mCurMethodInstance == NULL) || (mModule->mCurMethodInstance->mComptimeFlags == BfComptimeFlag_None)) &&
  6907. (!mModule->mIsComptimeModule))
  6908. {
  6909. mModule->Fail(StrFormat("Method '%s' can only be invoked at comptime. Consider adding [Comptime] to the current method.", mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str()), targetSrc);
  6910. }
  6911. bool bypassVirtual = (callFlags & BfCreateCallFlags_BypassVirtual) != 0;
  6912. bool skipThis = (callFlags & BfCreateCallFlags_SkipThis) != 0;;
  6913. static int sCallIdx = 0;
  6914. if (!mModule->mCompiler->mIsResolveOnly)
  6915. sCallIdx++;
  6916. int callIdx = sCallIdx;
  6917. if (callIdx == 0x000015CB)
  6918. {
  6919. NOP;
  6920. }
  6921. // Temporarily disable so we don't capture calls in params
  6922. SetAndRestoreValue<BfFunctionBindResult*> prevBindResult(mFunctionBindResult, NULL);
  6923. SetAndRestoreValue<bool> prevAllowVariableDeclarations;
  6924. if (mModule->mCurMethodState != NULL)
  6925. prevAllowVariableDeclarations.Init(mModule->mCurMethodState->mCurScope->mAllowVariableDeclarations, false);
  6926. BfMethodInstance* methodInstance = moduleMethodInstance.mMethodInstance;
  6927. SizedArray<BfIRValue, 4> irArgs;
  6928. if ((methodDef->mIsAbstract) && (bypassVirtual))
  6929. {
  6930. mModule->Fail(StrFormat("Abstract base method '%s' cannot be invoked", mModule->MethodToString(methodInstance).c_str()), targetSrc);
  6931. }
  6932. bool isSkipCall = moduleMethodInstance.mMethodInstance->IsSkipCall(bypassVirtual);
  6933. BfType* returnType = methodInstance->mReturnType;
  6934. /*if (returnType->IsSelf())
  6935. {
  6936. returnType = methodInstance->GetOwner();
  6937. BF_ASSERT(returnType->IsInterface());
  6938. }*/
  6939. Array<BfTypedValue> argCascades;
  6940. BfTypedValue target = inTarget;
  6941. if (!skipThis)
  6942. {
  6943. if ((target) && (target.mType->IsFunction()) && (methodInstance->GetOwner() == target.mType))
  6944. {
  6945. CheckResultForReading(target);
  6946. target = mModule->LoadValue(target);
  6947. auto funcType = mModule->mBfIRBuilder->MapMethod(moduleMethodInstance.mMethodInstance);
  6948. auto funcPtrType = mModule->mBfIRBuilder->GetPointerTo(funcType);
  6949. moduleMethodInstance.mFunc = mModule->mBfIRBuilder->CreateIntToPtr(target.mValue, funcPtrType);
  6950. if (mDeferCallData != NULL)
  6951. {
  6952. mDeferCallData->mFuncAlloca_Orig = moduleMethodInstance.mFunc;
  6953. mDeferCallData->mFuncAlloca = mModule->CreateAlloca(funcPtrType, target.mType->mAlign, false, "FuncAlloca");
  6954. mModule->mBfIRBuilder->CreateStore(mDeferCallData->mFuncAlloca_Orig, mDeferCallData->mFuncAlloca);
  6955. }
  6956. }
  6957. else if (!methodDef->mIsStatic)
  6958. {
  6959. if ((!target) && (prevBindResult.mPrevVal != NULL))
  6960. {
  6961. auto bindResult = prevBindResult.mPrevVal;
  6962. if (bindResult->mBindType != NULL)
  6963. {
  6964. // Allow binding a function to a 'this' type even if no target is specified
  6965. auto delegateInfo = bindResult->mBindType->GetDelegateInfo();
  6966. if (delegateInfo != NULL)
  6967. {
  6968. if (delegateInfo->mHasExplicitThis)
  6969. {
  6970. target = mModule->GetDefaultTypedValue(delegateInfo->mParams[0], false, BfDefaultValueKind_Addr);
  6971. bypassVirtual = true;
  6972. }
  6973. }
  6974. else if (bindResult->mBindType->IsFunction())
  6975. {
  6976. BfMethodInstance* invokeMethodInstance = mModule->GetRawMethodInstanceAtIdx(bindResult->mBindType->ToTypeInstance(), 0, "Invoke");
  6977. if (!invokeMethodInstance->mMethodDef->mIsStatic)
  6978. {
  6979. target = mModule->GetDefaultTypedValue(invokeMethodInstance->GetThisType(), false, BfDefaultValueKind_Addr);
  6980. }
  6981. }
  6982. }
  6983. }
  6984. if (!target)
  6985. {
  6986. FinishDeferredEvals(argValues);
  6987. auto error = mModule->Fail(StrFormat("An instance reference is required to %s the non-static method '%s'",
  6988. (prevBindResult.mPrevVal != NULL) ? "bind" : "invoke",
  6989. mModule->MethodToString(methodInstance).c_str()), targetSrc);
  6990. if ((error != NULL) && (methodInstance->mMethodDef->GetRefNode() != NULL))
  6991. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
  6992. return mModule->GetDefaultTypedValue(returnType);
  6993. }
  6994. auto prevResult = mResult;
  6995. mResult = target;
  6996. CheckResultForReading(mResult);
  6997. mResult = prevResult;
  6998. if (methodDef->mMethodType != BfMethodType_Ctor)
  6999. {
  7000. bool doAccessCheck = true;
  7001. if (target.IsThis())
  7002. {
  7003. if (!mModule->mCurMethodState->mMayNeedThisAccessCheck)
  7004. doAccessCheck = false;
  7005. }
  7006. if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) && (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mDisableObjectAccessChecksAttributeTypeDef)))
  7007. doAccessCheck = false;
  7008. if ((doAccessCheck) && (!isSkipCall) && (prevBindResult.mPrevVal == NULL))
  7009. mModule->EmitObjectAccessCheck(target);
  7010. }
  7011. if (((prevBindResult.mPrevVal == NULL) || (!prevBindResult.mPrevVal->mSkipThis)) &&
  7012. (!isSkipCall))
  7013. {
  7014. bool skipMutCheck = false;
  7015. if ((prevBindResult.mPrevVal != NULL) && (prevBindResult.mPrevVal->mSkipMutCheck))
  7016. {
  7017. // If we are binding a delegate, then we will end up making a copy of the target anyway
  7018. // so we don't need to do a mutability check
  7019. skipMutCheck = true;
  7020. }
  7021. if (methodDef->mMethodType == BfMethodType_Extension)
  7022. PushArg(target, irArgs);
  7023. else
  7024. PushThis(targetSrc, target, moduleMethodInstance.mMethodInstance, irArgs, skipMutCheck);
  7025. }
  7026. }
  7027. else if (methodDef->mMethodType == BfMethodType_Extension)
  7028. {
  7029. // Handled in args
  7030. }
  7031. else
  7032. {
  7033. if (prevBindResult.mPrevVal == NULL)
  7034. {
  7035. if ((mModule->mAttributeState == NULL) || (mModule->mAttributeState->mCustomAttributes == NULL) ||
  7036. (!mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mNoStaticCtorAttributeTypeDef)))
  7037. {
  7038. mModule->CheckStaticAccess(methodInstance->mMethodInstanceGroup->mOwner);
  7039. }
  7040. }
  7041. if (target)
  7042. {
  7043. FinishDeferredEvals(argValues);
  7044. mModule->Fail(StrFormat("Method '%s' cannot be accessed with an instance reference; qualify it with a type name instead",
  7045. mModule->MethodToString(methodInstance).c_str()), targetSrc);
  7046. return mModule->GetDefaultTypedValue(returnType);
  7047. }
  7048. }
  7049. }
  7050. if (isSkipCall)
  7051. {
  7052. CheckSkipCall(targetSrc, argValues);
  7053. FinishDeferredEvals(argValues);
  7054. mModule->EmitEnsureInstructionAt();
  7055. return mModule->GetDefaultTypedValue(returnType);
  7056. }
  7057. bool hasNamedArgs = false;
  7058. for (auto& arg : argValues)
  7059. if (arg.mNameNode != NULL)
  7060. hasNamedArgs = true;
  7061. if (hasNamedArgs)
  7062. {
  7063. methodDef->BuildParamNameMap();
  7064. BfIdentifierNode* outOfPlaceName = NULL;
  7065. int curParamIdx = 0;
  7066. SizedArrayImpl<BfResolvedArg> origArgValues = argValues;
  7067. argValues.Clear();
  7068. for (int argIdx = 0; argIdx < origArgValues.mSize; argIdx++)
  7069. {
  7070. int paramIdx = curParamIdx;
  7071. auto& argValue = origArgValues[argIdx];
  7072. if (argValue.mNameNode != NULL)
  7073. {
  7074. int namedParamIdx = -1;
  7075. if (methodDef->mParamNameMap->TryGetValue(argValue.mNameNode->ToStringView(), &namedParamIdx))
  7076. {
  7077. paramIdx = namedParamIdx;
  7078. }
  7079. else
  7080. {
  7081. if (mModule->PreFail())
  7082. {
  7083. mModule->Fail(StrFormat("The best overload for '%s' does not have a parameter named '%s'", methodInstance->mMethodDef->mName.c_str(),
  7084. argValue.mNameNode->ToString().c_str()), argValue.mNameNode);
  7085. }
  7086. }
  7087. if (paramIdx != curParamIdx)
  7088. outOfPlaceName = argValue.mNameNode;
  7089. }
  7090. else if (outOfPlaceName != NULL)
  7091. {
  7092. if (mModule->PreFail())
  7093. mModule->Fail(StrFormat("Named argument '%s' is used out-of-position but is followed by an unnamed argument", outOfPlaceName->ToString().c_str()), outOfPlaceName);
  7094. outOfPlaceName = NULL;
  7095. }
  7096. if ((paramIdx < methodInstance->GetParamCount()) && (paramIdx != argIdx))
  7097. {
  7098. if (methodInstance->GetParamKind(paramIdx) == BfParamKind_Normal)
  7099. {
  7100. auto wantType = methodInstance->GetParamType(paramIdx);
  7101. auto resolvedValue = ResolveArgValue(argValue, wantType);
  7102. if (resolvedValue)
  7103. {
  7104. argValue.mTypedValue = resolvedValue;
  7105. argValue.mArgFlags = (BfArgFlags)(argValue.mArgFlags | BfArgFlag_Finalized);
  7106. }
  7107. }
  7108. }
  7109. while (paramIdx >= argValues.mSize)
  7110. argValues.Add(BfResolvedArg());
  7111. if (argValues[paramIdx].mExpression != NULL)
  7112. {
  7113. if (argValue.mNameNode != NULL)
  7114. {
  7115. if (mModule->PreFail())
  7116. mModule->Fail(StrFormat("Named argument '%s' cannot be specified multiple times", argValue.mNameNode->ToString().c_str()), argValue.mNameNode);
  7117. }
  7118. }
  7119. argValues[paramIdx] = argValue;
  7120. curParamIdx++;
  7121. }
  7122. }
  7123. int argIdx = 0;
  7124. int paramIdx = 0;
  7125. BfIRValue expandedParamAlloca;
  7126. BfTypedValue expandedParamsArray;
  7127. BfType* expandedParamsElementType = NULL;
  7128. bool hadDelegateParamIdx = false;
  7129. int extendedParamIdx = 0;
  7130. AddCallDependencies(methodInstance);
  7131. bool wasCapturingMatchInfo = false;
  7132. auto autoComplete = GetAutoComplete();
  7133. if (autoComplete != NULL)
  7134. {
  7135. // Set to false to make sure we don't capture method match info from 'params' array creation
  7136. wasCapturingMatchInfo = autoComplete->mIsCapturingMethodMatchInfo;
  7137. autoComplete->mIsCapturingMethodMatchInfo = false;
  7138. }
  7139. defer(
  7140. {
  7141. if (autoComplete != NULL)
  7142. autoComplete->mIsCapturingMethodMatchInfo = wasCapturingMatchInfo;
  7143. });
  7144. BfScopeData* boxScopeData = (mDeferCallData != NULL) ? mDeferCallData->mScopeAlloc : NULL;
  7145. if ((boxScopeData == NULL) && (mModule->mCurMethodState != NULL))
  7146. boxScopeData = mModule->mCurMethodState->mCurScope;
  7147. bool failed = false;
  7148. while (true)
  7149. {
  7150. int argExprIdx = argIdx;
  7151. if (methodDef->mMethodType == BfMethodType_Extension)
  7152. argExprIdx--;
  7153. bool isThis = (paramIdx == -1) || ((methodDef->mHasExplicitThis) && (paramIdx == 0));
  7154. bool isDirectPass = false;
  7155. if (paramIdx >= (int)methodInstance->GetParamCount())
  7156. {
  7157. if (methodInstance->IsVarArgs())
  7158. {
  7159. if (argExprIdx >= (int)argValues.size())
  7160. break;
  7161. BfTypedValue argValue = ResolveArgValue(argValues[argExprIdx], NULL);
  7162. if (argValue)
  7163. {
  7164. auto typeInst = argValue.mType->ToTypeInstance();
  7165. if (argValue.mType == mModule->GetPrimitiveType(BfTypeCode_Float))
  7166. argValue = mModule->Cast(argValues[argExprIdx].mExpression, argValue, mModule->GetPrimitiveType(BfTypeCode_Double));
  7167. if ((typeInst != NULL) && (typeInst->IsInstanceOf(mModule->mCompiler->mStringTypeDef)))
  7168. {
  7169. BfType* charType = mModule->GetPrimitiveType(BfTypeCode_Char8);
  7170. BfType* charPtrType = mModule->CreatePointerType(charType);
  7171. argValue = mModule->Cast(argValues[argExprIdx].mExpression, argValue, charPtrType);
  7172. }
  7173. PushArg(argValue, irArgs, true, false);
  7174. }
  7175. argIdx++;
  7176. continue;
  7177. }
  7178. if (argExprIdx < (int)argValues.size())
  7179. {
  7180. if (mModule->PreFail())
  7181. {
  7182. BfAstNode* errorRef = argValues[argExprIdx].mExpression;
  7183. if (errorRef == NULL)
  7184. errorRef = targetSrc;
  7185. BfError* error;
  7186. if ((argValues[argExprIdx].mArgFlags & BfArgFlag_StringInterpolateArg) != 0)
  7187. {
  7188. int checkIdx = argExprIdx - 1;
  7189. while (checkIdx >= 0)
  7190. {
  7191. if ((argValues[checkIdx].mArgFlags & BfArgFlag_StringInterpolateFormat) != 0)
  7192. {
  7193. errorRef = argValues[checkIdx].mExpression;
  7194. break;
  7195. }
  7196. checkIdx--;
  7197. }
  7198. error = mModule->Fail("Expanded string interpolation generates too many arguments. If string allocation was intended then consider adding a specifier such as 'scope'.", errorRef);
  7199. }
  7200. else if ((prevBindResult.mPrevVal != NULL) && (prevBindResult.mPrevVal->mBindType != NULL))
  7201. error = mModule->Fail(StrFormat("Method '%s' has too few parameters to bind to '%s'.", mModule->MethodToString(methodInstance).c_str(), mModule->TypeToString(prevBindResult.mPrevVal->mBindType).c_str()), errorRef);
  7202. else
  7203. error = mModule->Fail(StrFormat("Too many arguments, expected %d fewer.", (int)argValues.size() - argExprIdx), errorRef);
  7204. if ((error != NULL) && (methodInstance->mMethodDef->mMethodDeclaration != NULL))
  7205. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
  7206. }
  7207. failed = true;
  7208. break;
  7209. }
  7210. break;
  7211. }
  7212. // Only create actual params if we're not just trying to bind the function
  7213. if ((prevBindResult.mPrevVal != NULL) && (!prevBindResult.mPrevVal->mWantsArgs))
  7214. break;
  7215. BfType* wantType = NULL;
  7216. bool wantsSplat = false;
  7217. if (expandedParamsElementType != NULL)
  7218. {
  7219. wantType = expandedParamsElementType;
  7220. }
  7221. else
  7222. {
  7223. wantsSplat = methodInstance->GetParamIsSplat(paramIdx) && (!IsComptime());
  7224. if (methodInstance->IsImplicitCapture(paramIdx))
  7225. {
  7226. auto paramType = methodInstance->GetParamType(paramIdx);
  7227. if (mModule->mCurMethodInstance->IsMixin())
  7228. {
  7229. // Don't bother, also- can fail on captures
  7230. }
  7231. else
  7232. {
  7233. // static int captureIdx = 0;
  7234. // captureIdx++;
  7235. // int curCaptureIdx = captureIdx;
  7236. //
  7237. // if (curCaptureIdx == 0x91)
  7238. // {
  7239. // NOP;
  7240. // }
  7241. auto lookupVal = DoImplicitArgCapture(targetSrc, methodInstance, paramIdx, failed, BfImplicitParamKind_General, origTarget);
  7242. if (lookupVal)
  7243. {
  7244. if (wantsSplat)
  7245. {
  7246. SplatArgs(lookupVal, irArgs);
  7247. }
  7248. else if (paramType->IsRef())
  7249. {
  7250. irArgs.push_back(lookupVal.mValue);
  7251. }
  7252. else
  7253. PushArg(lookupVal, irArgs, true);
  7254. }
  7255. }
  7256. paramIdx++;
  7257. continue;
  7258. }
  7259. wantType = methodInstance->GetParamType(paramIdx);
  7260. if (!mModule->mCurTypeInstance->IsInterface())
  7261. {
  7262. // Resolve `Self` types
  7263. if (wantType->IsUnspecializedTypeVariation())
  7264. {
  7265. wantType = mModule->ResolveSelfType(wantType, methodInstance->GetOwner());
  7266. }
  7267. }
  7268. if (IsVar(wantType))
  7269. {
  7270. // Case happens when we can't find the argument type
  7271. failed = true;
  7272. }
  7273. BfParamKind paramKind = methodInstance->GetParamKind(paramIdx);
  7274. if (paramKind == BfParamKind_Params)
  7275. {
  7276. //TODO: Check to see if it's a direct array pass
  7277. if (argIdx < (int)argValues.size())
  7278. {
  7279. auto argValue = argValues[argIdx].mTypedValue;
  7280. if ((argValue.IsParams()) /*&& (mModule->CanCast(argValue, wantType))*/)
  7281. isDirectPass = true;
  7282. }
  7283. if (!isDirectPass)
  7284. {
  7285. int numElements = BF_MAX((int)argValues.size() - argIdx, 0);
  7286. if (methodDef->mMethodType == BfMethodType_Extension)
  7287. numElements++;
  7288. if (IsConstEval())
  7289. {
  7290. if ((wantType->IsArray()) || (wantType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef)))
  7291. {
  7292. auto genericTypeInst = wantType->ToGenericTypeInstance();
  7293. expandedParamsElementType = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[0];
  7294. auto irSizedArrayType = mModule->mBfIRBuilder->GetSizedArrayType(mModule->mBfIRBuilder->MapType(expandedParamsElementType), numElements);
  7295. Array<BfIRValue> values;
  7296. for (int i = 0; i < numElements; i++)
  7297. values.Add(mModule->mBfIRBuilder->GetFakeVal());
  7298. expandedParamsArray = BfTypedValue(mModule->mBfIRBuilder->CreateConstAgg(irSizedArrayType, values), wantType);
  7299. PushArg(expandedParamsArray, irArgs);
  7300. continue;
  7301. }
  7302. }
  7303. else if (wantType->IsArray())
  7304. {
  7305. BfArrayType* arrayType = (BfArrayType*)wantType;
  7306. mModule->PopulateType(arrayType, BfPopulateType_DataAndMethods);
  7307. expandedParamsElementType = arrayType->mGenericTypeInfo->mTypeGenericArguments[0];
  7308. int arrayClassSize = arrayType->mInstSize - expandedParamsElementType->mSize;
  7309. expandedParamsArray = BfTypedValue(mModule->AllocFromType(arrayType->GetUnderlyingType(), boxScopeData, BfIRValue(), mModule->GetConstValue(numElements), 1, BfAllocFlags_None),
  7310. arrayType, false);
  7311. BfResolvedArgs resolvedArgs;
  7312. MatchConstructor(targetSrc, NULL, expandedParamsArray, arrayType, resolvedArgs, false, BfMethodGenericArguments(), BfAllowAppendKind_No);
  7313. //TODO: Assert 'length' var is at slot 1
  7314. auto arrayBits = mModule->mBfIRBuilder->CreateBitCast(expandedParamsArray.mValue, mModule->mBfIRBuilder->MapType(arrayType->mBaseType));
  7315. int arrayLengthBitCount = arrayType->GetLengthBitCount();
  7316. if (arrayLengthBitCount == 0)
  7317. {
  7318. mModule->Fail("INTERNAL ERROR: Unable to find array 'length' field", targetSrc);
  7319. return BfTypedValue();
  7320. }
  7321. auto& fieldInstance = arrayType->mBaseType->mFieldInstances[0];
  7322. auto addr = mModule->mBfIRBuilder->CreateInBoundsGEP(arrayBits, 0, fieldInstance.mDataIdx);
  7323. if (arrayLengthBitCount == 64)
  7324. mModule->mBfIRBuilder->CreateAlignedStore(mModule->GetConstValue64(numElements), addr, 8);
  7325. else
  7326. mModule->mBfIRBuilder->CreateAlignedStore(mModule->GetConstValue32(numElements), addr, 4);
  7327. PushArg(expandedParamsArray, irArgs);
  7328. continue;
  7329. }
  7330. else if (wantType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef))
  7331. {
  7332. mModule->PopulateType(wantType);
  7333. mModule->mBfIRBuilder->PopulateType(wantType);
  7334. auto genericTypeInst = wantType->ToGenericTypeInstance();
  7335. expandedParamsElementType = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[0];
  7336. expandedParamsArray = BfTypedValue(mModule->CreateAlloca(wantType), wantType, true);
  7337. expandedParamAlloca = mModule->CreateAlloca(genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[0], true, NULL, mModule->GetConstValue(numElements));
  7338. mModule->mBfIRBuilder->CreateAlignedStore(expandedParamAlloca, mModule->mBfIRBuilder->CreateInBoundsGEP(expandedParamsArray.mValue, 0, 1), mModule->mSystem->mPtrSize);
  7339. mModule->mBfIRBuilder->CreateAlignedStore(mModule->GetConstValue(numElements), mModule->mBfIRBuilder->CreateInBoundsGEP(expandedParamsArray.mValue, 0, 2), mModule->mSystem->mPtrSize);
  7340. PushArg(expandedParamsArray, irArgs, !wantsSplat);
  7341. continue;
  7342. }
  7343. else if (wantType->IsSizedArray())
  7344. {
  7345. mModule->PopulateType(wantType);
  7346. mModule->mBfIRBuilder->PopulateType(wantType);
  7347. BfSizedArrayType* sizedArrayType = (BfSizedArrayType*)wantType;
  7348. expandedParamsElementType = wantType->GetUnderlyingType();
  7349. if (numElements != sizedArrayType->mElementCount)
  7350. {
  7351. BfAstNode* refNode = targetSrc;
  7352. if (argExprIdx < (int)argValues.size())
  7353. refNode = argValues[argExprIdx].mExpression;
  7354. mModule->Fail(StrFormat("Incorrect number of arguments to match params type '%s'", mModule->TypeToString(wantType).c_str()), refNode);
  7355. }
  7356. expandedParamsArray = BfTypedValue(mModule->CreateAlloca(wantType), wantType, true);
  7357. expandedParamAlloca = mModule->mBfIRBuilder->CreateBitCast(expandedParamsArray.mValue, mModule->mBfIRBuilder->GetPointerTo(mModule->mBfIRBuilder->MapType(expandedParamsElementType)));
  7358. PushArg(expandedParamsArray, irArgs, !wantsSplat);
  7359. continue;
  7360. }
  7361. }
  7362. }
  7363. else if (paramKind == BfParamKind_DelegateParam)
  7364. hadDelegateParamIdx = true;
  7365. }
  7366. BfAstNode* arg = NULL;
  7367. bool hadMissingArg = false;
  7368. if (argExprIdx == -1)
  7369. arg = targetSrc;
  7370. if (argExprIdx >= 0)
  7371. {
  7372. if (argExprIdx < (int)argValues.size())
  7373. {
  7374. arg = argValues[argExprIdx].mExpression;
  7375. if (((argValues[argExprIdx].mArgFlags & BfArgFlag_StringInterpolateArg) != 0) && (!expandedParamsArray) && (!hadDelegateParamIdx))
  7376. {
  7377. BfAstNode* errorRef = arg;
  7378. int checkIdx = argExprIdx - 1;
  7379. while (checkIdx >= 0)
  7380. {
  7381. if ((argValues[checkIdx].mArgFlags & BfArgFlag_StringInterpolateFormat) != 0)
  7382. {
  7383. errorRef = argValues[checkIdx].mExpression;
  7384. break;
  7385. }
  7386. checkIdx--;
  7387. }
  7388. mModule->Warn(BfWarning_BF4205_StringInterpolationParam, "Expanded string interpolation argument not used as 'params'. If string allocation was intended then consider adding a specifier such as 'scope'.", errorRef);
  7389. }
  7390. // if ((arg == NULL) && (argValues[argExprIdx].mExpression != NULL))
  7391. // hadMissingArg = true;
  7392. if ((arg == NULL) && (!argValues[argExprIdx].mTypedValue))
  7393. hadMissingArg = true;
  7394. }
  7395. else
  7396. hadMissingArg = true;
  7397. }
  7398. BfTypedValue argValue;
  7399. if (hadMissingArg)
  7400. {
  7401. if (expandedParamsArray)
  7402. break;
  7403. if ((argIdx >= (int) methodInstance->mDefaultValues.size()) || (!methodInstance->mDefaultValues[argIdx]))
  7404. {
  7405. BfAstNode* refNode = targetSrc;
  7406. if (argValues.size() > 0)
  7407. {
  7408. auto checkExpr = argValues.back().mExpression;
  7409. if (checkExpr != NULL)
  7410. refNode = checkExpr;
  7411. }
  7412. BfAstNode* prevNode = NULL;
  7413. if (targetSrc == NULL)
  7414. {
  7415. // We must be in BfModule::EmitCtorBody
  7416. }
  7417. else if (auto tupleExpr = BfNodeDynCastExact<BfTupleExpression>(targetSrc))
  7418. {
  7419. if (tupleExpr->mCommas.size() > 0)
  7420. prevNode = tupleExpr->mCommas.back();
  7421. else
  7422. prevNode = tupleExpr->mOpenParen;
  7423. if (tupleExpr->mCloseParen != NULL)
  7424. refNode = tupleExpr->mCloseParen;
  7425. }
  7426. else if (mModule->mParentNodeEntry != NULL)
  7427. {
  7428. if (auto objectCreateExpr = BfNodeDynCast<BfObjectCreateExpression>(mModule->mParentNodeEntry->mNode))
  7429. {
  7430. if (objectCreateExpr->mCommas.size() > 0)
  7431. prevNode = objectCreateExpr->mCommas.back();
  7432. else
  7433. prevNode = objectCreateExpr->mOpenToken;
  7434. if (objectCreateExpr->mCloseToken != NULL)
  7435. refNode = objectCreateExpr->mCloseToken;
  7436. if (auto newNode = BfNodeDynCast<BfNewNode>(objectCreateExpr->mNewNode))
  7437. {
  7438. if (newNode->mAllocNode == targetSrc)
  7439. refNode = targetSrc;
  7440. }
  7441. }
  7442. else if (auto invokeExpr = BfNodeDynCast<BfInvocationExpression>(mModule->mParentNodeEntry->mNode))
  7443. {
  7444. if (invokeExpr->mCommas.size() > 0)
  7445. prevNode = invokeExpr->mCommas.back();
  7446. else
  7447. prevNode = invokeExpr->mOpenParen;
  7448. if (invokeExpr->mCloseParen != NULL)
  7449. refNode = invokeExpr->mCloseParen;
  7450. }
  7451. }
  7452. if (refNode == NULL)
  7453. refNode = methodInstance->GetOwner()->mTypeDef->GetRefNode();
  7454. if ((autoComplete != NULL) && (prevNode != NULL))
  7455. autoComplete->CheckEmptyStart(prevNode, wantType);
  7456. BfError* error = NULL;
  7457. if (mModule->mParentNodeEntry != NULL)
  7458. {
  7459. bool showCtorError = false;
  7460. if (auto ctorDeclaration = BfNodeDynCast<BfConstructorDeclaration>(mModule->mParentNodeEntry->mNode))
  7461. {
  7462. if (ctorDeclaration->mInitializer == NULL)
  7463. showCtorError = true;
  7464. }
  7465. if (auto typerDecl = BfNodeDynCast<BfTypeDeclaration>(mModule->mParentNodeEntry->mNode))
  7466. showCtorError = true;
  7467. if (showCtorError)
  7468. {
  7469. if (mModule->PreFail())
  7470. {
  7471. error = mModule->Fail(StrFormat("No parameterless constructor is available for base class. Consider calling base constructor '%s'.",
  7472. mModule->MethodToString(methodInstance).c_str()), refNode);
  7473. }
  7474. auto srcNode = mModule->mCurMethodInstance->mMethodDef->GetRefNode();
  7475. if ((autoComplete != NULL) && (autoComplete->CheckFixit(srcNode)))
  7476. autoComplete->FixitAddConstructor(mModule->mCurTypeInstance);
  7477. }
  7478. }
  7479. if (mModule->PreFail())
  7480. {
  7481. if (error == NULL)
  7482. {
  7483. if (hasNamedArgs)
  7484. error = mModule->Fail(StrFormat("There is no argument given that corresponds to the required formal parameter '%s' of '%s'.",
  7485. methodInstance->GetParamName(paramIdx).c_str(), mModule->MethodToString(methodInstance).c_str()), refNode);
  7486. else
  7487. error = mModule->Fail(StrFormat("Not enough parameters specified, expected %d more.", methodInstance->GetParamCount() - paramIdx), refNode);
  7488. }
  7489. if ((error != NULL) && (methodInstance->mMethodDef->mMethodDeclaration != NULL))
  7490. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
  7491. }
  7492. failed = true;
  7493. break;
  7494. }
  7495. auto foreignDefaultVal = methodInstance->mDefaultValues[argIdx];
  7496. auto foreignConst = methodInstance->GetOwner()->mConstHolder->GetConstant(foreignDefaultVal.mValue);
  7497. if (foreignConst->mConstType == BfConstType_AggZero)
  7498. {
  7499. // Allow this
  7500. }
  7501. else if (foreignConst->mTypeCode == BfTypeCode_NullPtr)
  7502. {
  7503. if (wantType->IsNullable())
  7504. {
  7505. argValue = mModule->GetDefaultTypedValue(wantType, false, BfDefaultValueKind_Addr);
  7506. }
  7507. }
  7508. else if (foreignConst->mConstType == BfConstType_GlobalVar)
  7509. {
  7510. auto globalVar = (BfGlobalVar*)foreignConst;
  7511. if (globalVar->mName[0] == '#')
  7512. {
  7513. if (strcmp(globalVar->mName, "#CallerLineNum") == 0)
  7514. {
  7515. argValue = BfTypedValue(mModule->GetConstValue(mModule->mCurFilePosition.mCurLine + 1), mModule->GetPrimitiveType(BfTypeCode_Int32));
  7516. }
  7517. else if (strcmp(globalVar->mName, "#CallerFilePath") == 0)
  7518. {
  7519. String filePath = "";
  7520. if (mModule->mCurFilePosition.mFileInstance != NULL)
  7521. filePath = mModule->mCurFilePosition.mFileInstance->mParser->mFileName;
  7522. argValue = BfTypedValue(mModule->GetStringObjectValue(filePath),
  7523. mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
  7524. }
  7525. else if (strcmp(globalVar->mName, "#CallerFileName") == 0)
  7526. {
  7527. String filePath = "";
  7528. if (mModule->mCurFilePosition.mFileInstance != NULL)
  7529. filePath = mModule->mCurFilePosition.mFileInstance->mParser->mFileName;
  7530. argValue = BfTypedValue(mModule->GetStringObjectValue(GetFileName(filePath)),
  7531. mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
  7532. }
  7533. else if (strcmp(globalVar->mName, "#CallerFileDir") == 0)
  7534. {
  7535. String filePath = "";
  7536. if (mModule->mCurFilePosition.mFileInstance != NULL)
  7537. filePath = mModule->mCurFilePosition.mFileInstance->mParser->mFileName;
  7538. argValue = BfTypedValue(mModule->GetStringObjectValue(GetFileDir(filePath)),
  7539. mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
  7540. }
  7541. else if (strcmp(globalVar->mName, "#CallerTypeName") == 0)
  7542. {
  7543. String typeName = "";
  7544. if (mModule->mCurTypeInstance != NULL)
  7545. typeName = mModule->TypeToString(mModule->mCurTypeInstance);
  7546. argValue = BfTypedValue(mModule->GetStringObjectValue(typeName),
  7547. mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
  7548. }
  7549. else if (strcmp(globalVar->mName, "#CallerType") == 0)
  7550. {
  7551. auto typeType = mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef);
  7552. BfType* type = mModule->mCurTypeInstance;
  7553. if (type != NULL)
  7554. {
  7555. mModule->AddDependency(type, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
  7556. argValue = BfTypedValue(mModule->CreateTypeDataRef(type), typeType);
  7557. }
  7558. }
  7559. else if (strcmp(globalVar->mName, "#CallerMemberName") == 0)
  7560. {
  7561. String memberName = "";
  7562. if (mModule->mCurMethodInstance != NULL)
  7563. memberName = mModule->MethodToString(mModule->mCurMethodInstance);
  7564. argValue = BfTypedValue(mModule->GetStringObjectValue(memberName),
  7565. mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
  7566. }
  7567. else if (strcmp(globalVar->mName, "#CallerProject") == 0)
  7568. {
  7569. String projectName = "";
  7570. if (mModule->mCurMethodInstance != NULL)
  7571. projectName = mModule->mCurMethodInstance->mMethodDef->mDeclaringType->mProject->mName;
  7572. argValue = BfTypedValue(mModule->GetStringObjectValue(projectName),
  7573. mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
  7574. }
  7575. else if (strcmp(globalVar->mName, "#ProjectName") == 0)
  7576. {
  7577. String projectName = methodInstance->mMethodDef->mDeclaringType->mProject->mName;
  7578. argValue = BfTypedValue(mModule->GetStringObjectValue(projectName),
  7579. mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
  7580. }
  7581. else
  7582. {
  7583. argValue = mModule->GetCompilerFieldValue(globalVar->mName);
  7584. }
  7585. }
  7586. }
  7587. else if (foreignConst->mConstType == BfConstType_GEP32_2)
  7588. {
  7589. auto constGep32_2 = (BfConstantGEP32_2*)foreignConst;
  7590. auto gepTarget = methodInstance->GetOwner()->mConstHolder->GetConstantById(constGep32_2->mTarget);
  7591. if (gepTarget->mConstType == BfConstType_GlobalVar)
  7592. {
  7593. auto globalVar = (BfGlobalVar*)gepTarget;
  7594. if (globalVar->mName[0] == '#')
  7595. {
  7596. if (strcmp(globalVar->mName, "#CallerExpression") == 0)
  7597. {
  7598. int exprIdx = constGep32_2->mIdx1;
  7599. if ((exprIdx >= 0) && (exprIdx < (int)argValues.size()))
  7600. {
  7601. auto expr = argValues[exprIdx].mExpression;
  7602. if (expr != NULL)
  7603. {
  7604. argValue = BfTypedValue(mModule->GetStringObjectValue(expr->ToString()),
  7605. mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
  7606. }
  7607. }
  7608. else
  7609. {
  7610. mModule->Fail("CallerExpression index out of bounds", targetSrc);
  7611. argValue = BfTypedValue(mModule->GetStringObjectValue(""),
  7612. mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
  7613. }
  7614. }
  7615. }
  7616. }
  7617. }
  7618. if (!argValue)
  7619. {
  7620. argValue = mModule->GetTypedValueFromConstant(foreignConst, methodInstance->GetOwner()->mConstHolder, foreignDefaultVal.mType);
  7621. if (!argValue)
  7622. mModule->Fail("Default parameter value failed", targetSrc);
  7623. mModule->mBfIRBuilder->PopulateType(foreignDefaultVal.mType);
  7624. }
  7625. }
  7626. else
  7627. {
  7628. if (argExprIdx == -1)
  7629. argValue = target;
  7630. else
  7631. argValue = argValues[argExprIdx].mTypedValue;
  7632. if ((argValue.IsParams()) && (!isDirectPass))
  7633. {
  7634. BfAstNode* refNode = arg;
  7635. if (auto unaryOperatorExpr = BfNodeDynCast<BfUnaryOperatorExpression>(refNode))
  7636. refNode = unaryOperatorExpr->mOpToken;
  7637. mModule->Warn(0, "Unused 'params' expression", refNode);
  7638. }
  7639. if (wantType->IsMethodRef())
  7640. {
  7641. auto expr = argValues[argExprIdx].mExpression;
  7642. if (expr != NULL)
  7643. SetMethodElementType(expr);
  7644. if (!argValue)
  7645. argValue = mModule->CreateValueFromExpression(BfNodeDynCast<BfExpression>(arg), wantType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast));
  7646. // Add any implicit captures now
  7647. auto methodRefType = (BfMethodRefType*)wantType;
  7648. BfMethodInstance* useMethodInstance = methodRefType->mMethodRef;
  7649. for (int dataIdx = 0; dataIdx < methodRefType->GetCaptureDataCount(); dataIdx++)
  7650. {
  7651. int paramIdx = methodRefType->GetParamIdxFromDataIdx(dataIdx);
  7652. auto lookupVal = DoImplicitArgCapture(arg, useMethodInstance, paramIdx, failed, BfImplicitParamKind_General, argValue);
  7653. if (lookupVal)
  7654. {
  7655. if (methodRefType->WantsDataPassedAsSplat(dataIdx))
  7656. SplatArgs(lookupVal, irArgs);
  7657. else
  7658. {
  7659. if (lookupVal.mType->IsComposite())
  7660. lookupVal = mModule->MakeAddressable(lookupVal, false);
  7661. irArgs.push_back(lookupVal.mValue);
  7662. }
  7663. }
  7664. }
  7665. paramIdx++;
  7666. argIdx++;
  7667. continue;
  7668. }
  7669. else if (argExprIdx >= 0)
  7670. {
  7671. BfParamKind paramKind = BfParamKind_Normal;
  7672. BfIdentifierNode* paramNameNode = NULL;
  7673. if (paramIdx < methodInstance->GetParamCount())
  7674. {
  7675. paramKind = methodInstance->GetParamKind(paramIdx);
  7676. paramNameNode = methodInstance->GetParamNameNode(paramIdx);
  7677. }
  7678. argValues[argExprIdx].mExpectedType = wantType;
  7679. argValue = ResolveArgValue(argValues[argExprIdx], wantType, NULL, paramKind, paramNameNode);
  7680. }
  7681. }
  7682. if (!argValue)
  7683. {
  7684. failed = true;
  7685. }
  7686. if ((arg != NULL) && (autoComplete != NULL) && (autoComplete->mResolveType == BfResolveType_GetResultString) && (autoComplete->IsAutocompleteNode(arg)))
  7687. {
  7688. if (!autoComplete->mResultString.Contains('\r'))
  7689. {
  7690. String str;
  7691. str += methodInstance->GetParamName(paramIdx);
  7692. str += " @ ";
  7693. bool isCtor = methodInstance->mMethodDef->mMethodType == BfMethodType_Ctor;
  7694. if (isCtor)
  7695. str += methodInstance->GetOwner()->mTypeDef->mName->ToString();
  7696. else
  7697. str += methodInstance->mMethodDef->mName;
  7698. str += "(";
  7699. for (int i = isCtor ? 1 : 0; i < methodInstance->GetParamCount(); i++)
  7700. {
  7701. if (i > (isCtor ? 1 : 0))
  7702. str += ",";
  7703. if (i == paramIdx)
  7704. {
  7705. if (methodInstance->GetParamKind(paramIdx) == BfParamKind_Params)
  7706. str += "params ";
  7707. str += mModule->TypeToString(methodInstance->GetParamType(paramIdx));
  7708. }
  7709. }
  7710. str += ")";
  7711. if (!autoComplete->mResultString.StartsWith(":"))
  7712. autoComplete->mResultString.Clear();
  7713. int crPos = (int)autoComplete->mResultString.IndexOf('\n');
  7714. if (crPos == -1)
  7715. crPos = autoComplete->mResultString.mLength;
  7716. int insertPos = BF_MAX(1, crPos);
  7717. if (autoComplete->mResultString.IsEmpty())
  7718. autoComplete->mResultString += ":";
  7719. if (insertPos > 1)
  7720. str.Insert(0, '\r');
  7721. autoComplete->mResultString.Insert(insertPos, str);
  7722. }
  7723. }
  7724. if (argValue)
  7725. {
  7726. if ((isThis) && (argValue.mType->IsRef()))
  7727. {
  7728. // Convert a 'ref this' to a 'this*'
  7729. argValue.mType = mModule->CreatePointerType(argValue.mType->GetUnderlyingType());
  7730. }
  7731. BfAstNode* refNode = arg;
  7732. if (refNode == NULL)
  7733. refNode = targetSrc;
  7734. if ((wantType->IsRef()) && (!argValue.mType->IsRef()) &&
  7735. (((callFlags & BfCreateCallFlags_AllowImplicitRef) != 0) || (wantType->IsIn())))
  7736. {
  7737. auto underlyingType = wantType->GetUnderlyingType();
  7738. if (mModule->mCurMethodState != NULL)
  7739. {
  7740. SetAndRestoreValue<BfScopeData*> prevScopeData(mModule->mCurMethodState->mOverrideScope, boxScopeData);
  7741. argValue = mModule->Cast(refNode, argValue, underlyingType);
  7742. }
  7743. else
  7744. argValue = mModule->Cast(refNode, argValue, underlyingType, ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) ? BfCastFlags_WantsConst : BfCastFlags_None);
  7745. if (argValue)
  7746. argValue = mModule->ToRef(argValue, (BfRefType*)wantType);
  7747. }
  7748. else
  7749. {
  7750. if (mModule->mCurMethodState != NULL)
  7751. {
  7752. SetAndRestoreValue<BfScopeData*> prevScopeData(mModule->mCurMethodState->mOverrideScope, boxScopeData);
  7753. argValue = mModule->Cast(refNode, argValue, wantType, ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) ? BfCastFlags_WantsConst : BfCastFlags_None);
  7754. }
  7755. else
  7756. argValue = mModule->Cast(refNode, argValue, wantType, ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) ? BfCastFlags_WantsConst : BfCastFlags_None);
  7757. }
  7758. if (!argValue)
  7759. {
  7760. if ((argExprIdx < (int)argValues.size()) && ((argValues[argExprIdx].mArgFlags & BfArgFlag_StringInterpolateArg) != 0))
  7761. {
  7762. BfAstNode* errorRef = NULL;
  7763. int checkIdx = argExprIdx - 1;
  7764. while (checkIdx >= 0)
  7765. {
  7766. if ((argValues[checkIdx].mArgFlags & BfArgFlag_StringInterpolateFormat) != 0)
  7767. {
  7768. errorRef = argValues[checkIdx].mExpression;
  7769. break;
  7770. }
  7771. checkIdx--;
  7772. }
  7773. if (errorRef != NULL)
  7774. mModule->Warn(0, "If string allocation was intended then consider adding a specifier such as 'scope'.", errorRef);
  7775. }
  7776. failed = true;
  7777. }
  7778. else if ((wantType->IsComposite()) && (!expandedParamsArray))
  7779. {
  7780. if (methodInstance->mIsIntrinsic)
  7781. {
  7782. // Intrinsics can handle structs either by value or address
  7783. }
  7784. else
  7785. {
  7786. // We need to make a temp and get the addr of that
  7787. if ((!wantsSplat) && (!argValue.IsValuelessType()) && (!argValue.IsAddr()) && (!IsConstEval()))
  7788. {
  7789. argValue = mModule->MakeAddressable(argValue);
  7790. }
  7791. }
  7792. }
  7793. else if (!wantType->IsRef())
  7794. argValue = mModule->LoadValue(argValue);
  7795. }
  7796. if ((argExprIdx != -1) && (argExprIdx < (int)argValues.size()) && ((argValues[argExprIdx].mArgFlags & BfArgFlag_Cascade) != 0))
  7797. {
  7798. mUsedAsStatement = true;
  7799. if (argValues[argExprIdx].mUncastedTypedValue)
  7800. argCascades.Add(argValues[argExprIdx].mUncastedTypedValue);
  7801. else
  7802. argCascades.Add(argValue);
  7803. }
  7804. if (expandedParamsArray)
  7805. {
  7806. if (argValue)
  7807. {
  7808. if (argValue.mValue.IsFake())
  7809. {
  7810. if ((!mModule->IsInUnspecializedGeneric()) && (!mModule->mBfIRBuilder->mIgnoreWrites))
  7811. mModule->InternalError("Invalid expandedParamsArray value");
  7812. }
  7813. else if (IsConstEval())
  7814. {
  7815. auto constant = mModule->mBfIRBuilder->GetConstant(expandedParamsArray.mValue);
  7816. BF_ASSERT(constant->mConstType == BfConstType_Agg);
  7817. auto constAgg = (BfConstantAgg*)constant;
  7818. constAgg->mValues[extendedParamIdx] = argValue.mValue;
  7819. }
  7820. else if (expandedParamAlloca)
  7821. {
  7822. argValue = mModule->LoadOrAggregateValue(argValue);
  7823. auto addr = mModule->mBfIRBuilder->CreateInBoundsGEP(expandedParamAlloca, extendedParamIdx);
  7824. auto storeInst = mModule->mBfIRBuilder->CreateAlignedStore(argValue.mValue, addr, argValue.mType->mAlign);
  7825. }
  7826. else
  7827. {
  7828. auto firstElem = mModule->GetFieldByName(expandedParamsArray.mType->ToTypeInstance(), "mFirstElement");
  7829. if (firstElem != NULL)
  7830. {
  7831. argValue = mModule->LoadValue(argValue);
  7832. auto firstAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(expandedParamsArray.mValue, 0, firstElem->mDataIdx);
  7833. auto indexedAddr = mModule->CreateIndexedValue(argValue.mType, firstAddr, extendedParamIdx);
  7834. if (argValue.IsSplat())
  7835. mModule->AggregateSplatIntoAddr(argValue, indexedAddr);
  7836. else
  7837. mModule->mBfIRBuilder->CreateAlignedStore(argValue.mValue, indexedAddr, argValue.mType->mAlign);
  7838. }
  7839. }
  7840. }
  7841. extendedParamIdx++;
  7842. }
  7843. else
  7844. {
  7845. if ((paramIdx == 0) && (methodInstance->GetParamName(paramIdx) == "this") && (wantType->IsPointer()))
  7846. {
  7847. auto underlyingType = wantType->GetUnderlyingType();
  7848. mModule->PopulateType(underlyingType, BfPopulateType_Data);
  7849. if ((underlyingType->IsValuelessType()) && (!underlyingType->IsVoid()))
  7850. {
  7851. // We don't actually pass a 'this' pointer for mut methods on valueless structs
  7852. argIdx++;
  7853. paramIdx++;
  7854. continue;
  7855. }
  7856. }
  7857. if (argValue)
  7858. {
  7859. if (isThis)
  7860. PushThis(targetSrc, argValue, methodInstance, irArgs);
  7861. else if (wantsSplat)
  7862. SplatArgs(argValue, irArgs);
  7863. else
  7864. PushArg(argValue, irArgs, true, false, methodInstance->mIsIntrinsic, methodInstance->mCallingConvention != BfCallingConvention_Unspecified);
  7865. }
  7866. paramIdx++;
  7867. }
  7868. argIdx++;
  7869. }
  7870. if (failed)
  7871. {
  7872. // Process the other unused arguments
  7873. while (argIdx < argValues.size())
  7874. {
  7875. mModule->AssertErrorState();
  7876. auto argValue = argValues[argIdx].mTypedValue;
  7877. if ((argValues[argIdx].mArgFlags & (BfArgFlag_DelegateBindAttempt | BfArgFlag_LambdaBindAttempt | BfArgFlag_UnqualifiedDotAttempt | BfArgFlag_DeferredEval | BfArgFlag_VariableDeclaration | BfArgFlag_UninitializedExpr)) != 0)
  7878. {
  7879. if (!argValue)
  7880. {
  7881. auto expr = BfNodeDynCast<BfExpression>(argValues[argIdx].mExpression);
  7882. if (expr != NULL)
  7883. argValue = mModule->CreateValueFromExpression(expr);
  7884. }
  7885. }
  7886. argIdx++;
  7887. }
  7888. prevIgnoreWrites.Restore();
  7889. return mModule->GetDefaultTypedValue(returnType, false, BfDefaultValueKind_Addr);
  7890. }
  7891. prevBindResult.Restore();
  7892. if (!methodDef->mIsStatic)
  7893. {
  7894. bool ignoreVirtualError = (mModule->mBfIRBuilder->mIgnoreWrites) && (mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsForeignMethodDef);
  7895. if ((methodInstance->GetOwner()->IsInterface()) && (!target.mType->IsGenericParam()) && (!target.mType->IsConcreteInterfaceType()) &&
  7896. (!mModule->mCurTypeInstance->IsInterface()) && (!ignoreVirtualError))
  7897. {
  7898. if (methodInstance->mVirtualTableIdx == -1)
  7899. {
  7900. mModule->PopulateType(methodInstance->GetOwner(), BfPopulateType_DataAndMethods);
  7901. }
  7902. if (methodInstance->mVirtualTableIdx == -1)
  7903. {
  7904. if (methodInstance->mMethodDef->mIsConcrete)
  7905. {
  7906. mModule->Fail(StrFormat("The method '%s' cannot be invoked from an interface reference because its return value is declared as 'concrete'", mModule->MethodToString(methodInstance).c_str()), targetSrc);
  7907. }
  7908. else if (methodInstance->HasSelf())
  7909. {
  7910. mModule->Fail(StrFormat("The method '%s' cannot be invoked from an interface reference because it contains 'Self' type references", mModule->MethodToString(methodInstance).c_str()), targetSrc);
  7911. }
  7912. else
  7913. {
  7914. if ((bypassVirtual) && (mModule->mCurTypeInstance->IsInterface()))
  7915. {
  7916. // Allow a base call to be defined
  7917. }
  7918. else if ((methodInstance->IsSpecializedGenericMethod()) && (origTarget) && (!origTarget.mType->IsInterface()))
  7919. {
  7920. if (!mModule->mBfIRBuilder->mIgnoreWrites)
  7921. mModule->AssertErrorState();
  7922. }
  7923. else if ((!mModule->mCurMethodInstance->mIsUnspecialized))
  7924. {
  7925. // Compiler error?
  7926. String errorString = "Unable to dynamically dispatch '%s'";
  7927. if (methodInstance->IsSpecializedGenericMethod())
  7928. errorString = "Unable to dynamically dispatch '%s' because generic methods can only be directly dispatched";
  7929. if (methodInstance->mReturnType->IsConcreteInterfaceType())
  7930. errorString = "Unable to dynamically dispatch '%s' because the concrete return type is unknown";
  7931. mModule->Fail(StrFormat(errorString.c_str(), mModule->MethodToString(methodInstance).c_str()), targetSrc);
  7932. }
  7933. //BF_ASSERT(mModule->mCurMethodInstance->mIsUnspecialized);
  7934. }
  7935. if (mFunctionBindResult != NULL)
  7936. {
  7937. mFunctionBindResult->mMethodInstance = methodInstance;
  7938. mFunctionBindResult->mTarget = target;
  7939. mFunctionBindResult->mFunc = moduleMethodInstance.mFunc;
  7940. for (auto arg : irArgs)
  7941. mFunctionBindResult->mIRArgs.push_back(arg);
  7942. }
  7943. prevIgnoreWrites.Restore();
  7944. return mModule->GetDefaultTypedValue(returnType);
  7945. }
  7946. }
  7947. }
  7948. else
  7949. {
  7950. //BF_ASSERT(!methodInstance->GetOwner()->IsInterface());
  7951. }
  7952. prevIgnoreWrites.Restore();
  7953. if (target.mType != NULL)
  7954. {
  7955. // When we call a method from a static ctor, that method could access static fields so we need to make sure
  7956. // the type has been initialized
  7957. auto targetTypeInst = target.mType->ToTypeInstance();
  7958. if (targetTypeInst != NULL)
  7959. {
  7960. if (prevBindResult.mPrevVal == NULL)
  7961. {
  7962. if ((mModule->mAttributeState == NULL) || (mModule->mAttributeState->mCustomAttributes == NULL) ||
  7963. (!mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mNoStaticCtorAttributeTypeDef)))
  7964. {
  7965. mModule->CheckStaticAccess(targetTypeInst);
  7966. }
  7967. }
  7968. }
  7969. }
  7970. if (methodInstance->mReturnType == NULL)
  7971. {
  7972. mModule->AssertErrorState();
  7973. mModule->Fail("Circular reference in method instance", targetSrc);
  7974. return BfTypedValue();
  7975. }
  7976. BfCreateCallFlags physCallFlags = BfCreateCallFlags_None;
  7977. if ((origTarget.mType != NULL) && (origTarget.mType->IsGenericParam()))
  7978. physCallFlags = (BfCreateCallFlags)(physCallFlags | BfCreateCallFlags_GenericParamThis);
  7979. auto func = moduleMethodInstance.mFunc;
  7980. BfTypedValue callResult = CreateCall(targetSrc, methodInstance, func, bypassVirtual, irArgs, NULL, physCallFlags, origTarget.mType);
  7981. prevIgnoreWrites.Restore();
  7982. if ((methodInstance->mMethodDef->mIsNoReturn) && ((mBfEvalExprFlags & BfEvalExprFlags_IsExpressionBody) != 0) &&
  7983. (mExpectingType != NULL) && (callResult.mType != mExpectingType))
  7984. {
  7985. callResult = mModule->GetDefaultTypedValue(mExpectingType);
  7986. }
  7987. // This gets triggered for non-sret (ie: comptime) composite returns so they aren't considered readonly
  7988. if ((callResult.mKind == BfTypedValueKind_Value) && (!callResult.mValue.IsConst()) &&
  7989. (!callResult.mType->IsValuelessType()) && (callResult.mType->IsComposite()) && (!methodInstance->GetLoweredReturnType()))
  7990. {
  7991. bool makeAddressable = true;
  7992. auto typeInstance = callResult.mType->ToTypeInstance();
  7993. if ((typeInstance != NULL) && (typeInstance->mHasUnderlyingArray))
  7994. makeAddressable = false;
  7995. if (makeAddressable)
  7996. {
  7997. callResult = mModule->MakeAddressable(callResult, true);
  7998. }
  7999. }
  8000. if (argCascades.mSize == 1)
  8001. {
  8002. if (argCascade == NULL)
  8003. return argCascades[0];
  8004. *argCascade = argCascades[0];
  8005. }
  8006. if (argCascades.mSize > 1)
  8007. {
  8008. if (argCascade == NULL)
  8009. return mModule->CreateTuple(argCascades, {});
  8010. *argCascade = mModule->CreateTuple(argCascades, {});
  8011. }
  8012. return callResult;
  8013. }
  8014. BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBoundExpression* methodBoundExpr, BfTypedValue target, BfTypeInstance* targetType, BfResolvedArgs& argValues, bool callCtorBodyOnly,
  8015. const BfMethodGenericArguments& methodGenericArguments, BfAllowAppendKind allowAppendKind, BfTypedValue* appendIndexValue)
  8016. {
  8017. // Temporarily disable so we don't capture calls in params
  8018. SetAndRestoreValue<BfFunctionBindResult*> prevBindResult(mFunctionBindResult, NULL);
  8019. auto origAllowAppendKind = allowAppendKind;
  8020. if (allowAppendKind == BfAllowAppendKind_Infer)
  8021. {
  8022. mModule->PopulateType(targetType);
  8023. allowAppendKind = targetType->IsZeroGap() ? BfAllowAppendKind_ZeroGap : BfAllowAppendKind_Yes;
  8024. }
  8025. static int sCtorCount = 0;
  8026. sCtorCount++;
  8027. BfMethodMatcher methodMatcher(targetSrc, mModule, "", argValues.mResolvedArgs, methodGenericArguments);
  8028. methodMatcher.mAllowAppendKind = allowAppendKind;
  8029. methodMatcher.mBfEvalExprFlags = mBfEvalExprFlags;
  8030. BfTypeVector typeGenericArguments;
  8031. auto curTypeInst = targetType;
  8032. auto curTypeDef = targetType->mTypeDef;
  8033. BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None;
  8034. auto activeTypeDef = mModule->GetActiveTypeDef();
  8035. auto visibleProjectSet = mModule->GetVisibleProjectSet();
  8036. bool isFailurePass = false;
  8037. for (int pass = 0; pass < 2; pass++)
  8038. {
  8039. isFailurePass = pass == 1;
  8040. curTypeDef->PopulateMemberSets();
  8041. BfMethodDef* nextMethodDef = NULL;
  8042. BfMemberSetEntry* entry;
  8043. if (curTypeDef->mMethodSet.TryGetWith(String("__BfCtor"), &entry))
  8044. nextMethodDef = (BfMethodDef*)entry->mMemberDef;
  8045. while (nextMethodDef != NULL)
  8046. {
  8047. auto checkMethod = nextMethodDef;
  8048. nextMethodDef = nextMethodDef->mNextWithSameName;
  8049. if ((isFailurePass) && (checkMethod->mMethodDeclaration == NULL))
  8050. continue; // Don't match private default ctor if there's a user-defined one
  8051. if (checkMethod->mIsStatic)
  8052. continue;
  8053. if ((checkMethod->mDeclaringType->IsExtension()) && (mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) &&
  8054. (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mNoExtensionAttributeTypeDef)))
  8055. {
  8056. mModule->mAttributeState->mUsed = true;
  8057. continue;
  8058. }
  8059. if (!mModule->IsInSpecializedSection())
  8060. {
  8061. if ((!curTypeInst->IsTypeMemberIncluded(checkMethod->mDeclaringType, activeTypeDef, mModule)) ||
  8062. (!curTypeInst->IsTypeMemberAccessible(checkMethod->mDeclaringType, visibleProjectSet)))
  8063. continue;
  8064. }
  8065. auto checkProt = checkMethod->mProtection;
  8066. if (!isFailurePass)
  8067. {
  8068. if (callCtorBodyOnly)
  8069. {
  8070. if (curTypeDef != mModule->mCurTypeInstance->mTypeDef)
  8071. {
  8072. // We're calling the base class's ctor from a derived class
  8073. if (checkProt <= BfProtection_Private)
  8074. continue;
  8075. }
  8076. }
  8077. else
  8078. {
  8079. if ((checkProt == BfProtection_Protected) || (checkProt == BfProtection_ProtectedInternal)) // Treat protected constructors as private
  8080. checkProt = BfProtection_Private;
  8081. if (!mModule->CheckProtection(protectionCheckFlags, curTypeInst, checkMethod->mDeclaringType->mProject, checkProt, curTypeInst))
  8082. continue;
  8083. }
  8084. }
  8085. methodMatcher.CheckMethod(NULL, curTypeInst, checkMethod, isFailurePass);
  8086. }
  8087. if ((methodMatcher.mBestMethodDef != NULL) || (methodMatcher.mBackupMethodDef != NULL))
  8088. break;
  8089. }
  8090. if (methodMatcher.mBestMethodDef == NULL)
  8091. methodMatcher.mBestMethodDef = methodMatcher.mBackupMethodDef;
  8092. if (methodMatcher.mBestMethodDef == NULL)
  8093. {
  8094. mModule->Fail("No constructor available", targetSrc);
  8095. return BfTypedValue();
  8096. }
  8097. auto methodDef = methodMatcher.mBestMethodDef;
  8098. if (mModule->mCompiler->mResolvePassData != NULL)
  8099. mModule->mCompiler->mResolvePassData->HandleMethodReference(targetSrc, curTypeInst->mTypeDef->GetDefinition(), methodDef);
  8100. // There should always be a constructor
  8101. BF_ASSERT(methodMatcher.mBestMethodDef != NULL);
  8102. //auto moduleMethodInstance = mModule->GetMethodInstance(methodMatcher.mBestMethodTypeInstance, methodMatcher.mBestMethodDef, methodMatcher.mBestMethodGenericArguments);
  8103. auto moduleMethodInstance = GetSelectedMethod(methodMatcher);
  8104. if (!moduleMethodInstance)
  8105. return BfTypedValue();
  8106. if (!mModule->CheckUseMethodInstance(moduleMethodInstance.mMethodInstance, targetSrc))
  8107. return BfTypedValue();
  8108. BfAutoComplete* autoComplete = GetAutoComplete();
  8109. if (autoComplete != NULL)
  8110. {
  8111. BfTypeInstance* resolvedTypeInstance = target.mType->ToTypeInstance();
  8112. auto ctorDecl = BfNodeDynCast<BfConstructorDeclaration>(methodDef->mMethodDeclaration);
  8113. if ((autoComplete->mIsGetDefinition) && (autoComplete->IsAutocompleteNode(targetSrc)) && (!BfNodeIsA<BfDelegateBindExpression>(targetSrc)))
  8114. {
  8115. if ((autoComplete->mDefMethod == NULL) && (autoComplete->mDefField == NULL) &&
  8116. (autoComplete->mDefProp == NULL)
  8117. && ((autoComplete->mDefType == NULL) || (autoComplete->mDefType == resolvedTypeInstance->mTypeDef)))
  8118. {
  8119. // Do we need to do this mDefType setting? If we do, then make sure we only get the element type of generics and such
  8120. //autoComplete->mDefType = resolvedTypeInstance->mTypeDef;
  8121. if (ctorDecl != NULL)
  8122. autoComplete->SetDefinitionLocation(ctorDecl->mThisToken, true);
  8123. else if (resolvedTypeInstance->mTypeDef->mTypeDeclaration != NULL)
  8124. autoComplete->SetDefinitionLocation(resolvedTypeInstance->mTypeDef->mTypeDeclaration->mNameNode, true);
  8125. }
  8126. }
  8127. else if ((autoComplete->mResolveType == BfResolveType_GetResultString) && (autoComplete->IsAutocompleteNode(targetSrc)) &&
  8128. (moduleMethodInstance.mMethodInstance != NULL))
  8129. {
  8130. autoComplete->mResultString = ":";
  8131. autoComplete->mResultString += mModule->MethodToString(moduleMethodInstance.mMethodInstance);
  8132. }
  8133. }
  8134. BfConstructorDeclaration* ctorDecl = (BfConstructorDeclaration*)methodMatcher.mBestMethodDef->mMethodDeclaration;
  8135. if ((methodMatcher.mBestMethodDef->HasAppend()) && (targetType->IsObject()))
  8136. {
  8137. if (allowAppendKind == BfAllowAppendKind_No)
  8138. {
  8139. if (mModule->mCurMethodInstance->mMethodDef->mMethodDeclaration == NULL)
  8140. mModule->Fail("Constructors with append allocations cannot be called from a default constructor. Considering adding an explicit default constructor with the [AllowAppend] specifier.", targetSrc);
  8141. else
  8142. mModule->Fail("Constructors with append allocations cannot be called from a constructor without [AllowAppend] specified.", targetSrc);
  8143. }
  8144. else
  8145. {
  8146. if ((allowAppendKind == BfAllowAppendKind_Yes) && (methodMatcher.mBestMethodDef->mAppendKind == BfAllowAppendKind_ZeroGap))
  8147. {
  8148. BfError* error;
  8149. if (origAllowAppendKind == BfAllowAppendKind_Infer)
  8150. error = mModule->Fail(StrFormat("Cannot call ZeroGap constructor for type '%s' because of fields added from type extensions", mModule->TypeToString(targetType).c_str()), targetSrc);
  8151. else
  8152. error = mModule->Fail(StrFormat("Cannot call ZeroGap constructor for type '%s' from here", mModule->TypeToString(targetType).c_str()), targetSrc);
  8153. if ((error != NULL) && (methodMatcher.mBestMethodDef->mMethodDeclaration != NULL))
  8154. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodMatcher.mBestMethodDef->GetRefNode());
  8155. }
  8156. BfResolvedArg resolvedArg;
  8157. if (appendIndexValue != NULL)
  8158. {
  8159. resolvedArg.mTypedValue = *appendIndexValue;
  8160. }
  8161. else
  8162. {
  8163. auto intPtrType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  8164. auto intPtrRefType = mModule->CreateRefType(intPtrType);
  8165. if (target.mValue.IsFake())
  8166. {
  8167. resolvedArg.mTypedValue = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), intPtrRefType);
  8168. }
  8169. else
  8170. {
  8171. BFMODULE_FATAL(mModule, "Bad");
  8172. }
  8173. }
  8174. methodMatcher.mArguments.Insert(0, resolvedArg);
  8175. }
  8176. }
  8177. if (methodMatcher.mAutoFlushAmbiguityErrors)
  8178. methodMatcher.FlushAmbiguityError(true);
  8179. if (isFailurePass)
  8180. mModule->Fail(StrFormat("'%s' is inaccessible due to its protection level", mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str()), targetSrc);
  8181. prevBindResult.Restore();
  8182. return CreateCall(methodMatcher.mTargetSrc, target, BfTypedValue(), methodMatcher.mBestMethodDef, moduleMethodInstance, BfCreateCallFlags_None, methodMatcher.mArguments);
  8183. }
  8184. static int sInvocationIdx = 0;
  8185. BfTypedValue BfExprEvaluator::ResolveArgValue(BfResolvedArg& resolvedArg, BfType* wantType, BfTypedValue* receivingValue, BfParamKind paramKind, BfIdentifierNode* paramNameNode)
  8186. {
  8187. BfTypedValue argValue = resolvedArg.mTypedValue;
  8188. if ((resolvedArg.mArgFlags & BfArgFlag_Finalized) != 0)
  8189. return argValue;
  8190. if ((resolvedArg.mArgFlags & (BfArgFlag_DelegateBindAttempt | BfArgFlag_LambdaBindAttempt | BfArgFlag_UnqualifiedDotAttempt | BfArgFlag_DeferredEval)) != 0)
  8191. {
  8192. if ((!argValue) || (argValue.mValue.IsFake()) || (resolvedArg.mWantsRecalc))
  8193. {
  8194. resolvedArg.mWantsRecalc = false;
  8195. auto expr = BfNodeDynCast<BfExpression>(resolvedArg.mExpression);
  8196. if (expr != NULL)
  8197. {
  8198. BfExprEvaluator exprEvaluator(mModule);
  8199. exprEvaluator.mReceivingValue = receivingValue;
  8200. BfEvalExprFlags flags = (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_AllowRefExpr);
  8201. if ((paramKind == BfParamKind_Params) || (paramKind == BfParamKind_DelegateParam))
  8202. flags = (BfEvalExprFlags)(flags | BfEvalExprFlags_AllowParamsExpr);
  8203. argValue = mModule->CreateValueFromExpression(exprEvaluator, expr, wantType, flags);
  8204. if ((argValue) && (argValue.mType != wantType) && (wantType != NULL))
  8205. {
  8206. if ((mDeferCallData != NULL) && (wantType == mModule->mContext->mBfObjectType))
  8207. {
  8208. BfAllocTarget allocTarget(mDeferCallData->mScopeAlloc);
  8209. argValue = mModule->BoxValue(expr, argValue, wantType, allocTarget, ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) ? BfCastFlags_WantsConst : BfCastFlags_None);
  8210. }
  8211. else
  8212. argValue = mModule->Cast(expr, argValue, wantType, ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) ? BfCastFlags_WantsConst : BfCastFlags_None);
  8213. }
  8214. }
  8215. }
  8216. }
  8217. else if ((resolvedArg.mArgFlags & (BfArgFlag_DeferredValue)) != 0)
  8218. {
  8219. // We should have already had an error on the first call
  8220. SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, mModule->mHadBuildError);
  8221. auto expr = BfNodeDynCast<BfExpression>(resolvedArg.mExpression);
  8222. BF_ASSERT(expr != NULL);
  8223. argValue = mModule->CreateValueFromExpression(expr, wantType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_AllowRefExpr | BfEvalExprFlags_AllowOutExpr));
  8224. resolvedArg.mUncastedTypedValue = argValue;
  8225. if ((argValue) && (wantType != NULL))
  8226. argValue = mModule->Cast(expr, argValue, wantType);
  8227. }
  8228. else if ((resolvedArg.mArgFlags & (BfArgFlag_UntypedDefault)) != 0)
  8229. {
  8230. argValue = mModule->GetDefaultTypedValue(wantType);
  8231. }
  8232. else if ((resolvedArg.mArgFlags & (BfArgFlag_VariableDeclaration | BfArgFlag_UninitializedExpr)) != 0)
  8233. {
  8234. auto variableDeclaration = BfNodeDynCast<BfVariableDeclaration>(resolvedArg.mExpression);
  8235. auto variableType = wantType;
  8236. bool isLet = (variableDeclaration != NULL) && (variableDeclaration->mTypeRef->IsExact<BfLetTypeReference>());
  8237. bool isVar = (variableDeclaration == NULL) || (variableDeclaration->mTypeRef->IsExact<BfVarTypeReference>());
  8238. if (mModule->mCurMethodState->mPendingNullConditional != NULL)
  8239. {
  8240. mModule->Fail("Variables cannot be declared in method arguments inside null conditional expressions", variableDeclaration);
  8241. }
  8242. if ((!isLet) && (!isVar))
  8243. {
  8244. if (variableType->IsVar())
  8245. {
  8246. auto resolvedType = mModule->ResolveTypeRef(variableDeclaration->mTypeRef);
  8247. if (resolvedType != NULL)
  8248. variableType = resolvedType;
  8249. }
  8250. else
  8251. {
  8252. mModule->Fail("Only 'ref' or 'var' variables can be declared in method arguments", variableDeclaration);
  8253. auto autoComplete = GetAutoComplete();
  8254. if (autoComplete != NULL)
  8255. autoComplete->CheckTypeRef(variableDeclaration->mTypeRef, true, true);
  8256. }
  8257. }
  8258. else
  8259. {
  8260. if (variableType->IsVar())
  8261. {
  8262. mModule->Fail("Variable type required for 'var' parameter types", variableDeclaration);
  8263. }
  8264. }
  8265. if (wantType->IsRef())
  8266. {
  8267. auto refType = (BfRefType*)wantType;
  8268. variableType = refType->mElementType;
  8269. }
  8270. if ((variableDeclaration != NULL) && (variableDeclaration->mInitializer != NULL))
  8271. {
  8272. mModule->Fail("Initializers cannot be used when declaring variables for 'out' parameters", variableDeclaration->mEqualsNode);
  8273. mModule->CreateValueFromExpression(variableDeclaration->mInitializer, variableType, BfEvalExprFlags_NoCast);
  8274. }
  8275. argValue = mModule->CreateOutVariable(resolvedArg.mExpression, variableDeclaration, paramNameNode, variableType, BfTypedValue());
  8276. }
  8277. return argValue;
  8278. }
  8279. BfTypedValue BfExprEvaluator::CheckEnumCreation(BfAstNode* targetSrc, BfTypeInstance* enumType, const StringImpl& caseName, BfResolvedArgs& argValues)
  8280. {
  8281. auto activeTypeDef = mModule->GetActiveTypeDef();
  8282. mModule->PopulateType(enumType);
  8283. mModule->mBfIRBuilder->PopulateType(enumType);
  8284. auto resolvePassData = mModule->mCompiler->mResolvePassData;
  8285. // if (resolvePassData != NULL)
  8286. // {
  8287. // if (mModule->mParentNodeEntry != NULL)
  8288. // {
  8289. // if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(mModule->mParentNodeEntry->mNode))
  8290. // {
  8291. // if (auto memberRefExpr = BfNodeDynCast<BfMemberReferenceExpression>(invocationExpr->mTarget))
  8292. // {
  8293. // BfAstNode* dotNode = memberRefExpr->mDotToken;
  8294. // BfAstNode* nameNode = targetSrc;
  8295. // String filter;
  8296. // auto autoComplete = resolvePassData->mAutoComplete;
  8297. // if ((autoComplete != NULL) && (autoComplete->InitAutocomplete(dotNode, nameNode, filter)))
  8298. // autoComplete->AddEnumTypeMembers(enumType, caseName, false, enumType == mModule->mCurTypeInstance);
  8299. // }
  8300. // }
  8301. // }
  8302. // }
  8303. for (int fieldIdx = 0; fieldIdx < (int)enumType->mFieldInstances.size(); fieldIdx++)
  8304. {
  8305. auto fieldInstance = &enumType->mFieldInstances[fieldIdx];
  8306. auto fieldDef = fieldInstance->GetFieldDef();
  8307. if (fieldDef == NULL)
  8308. continue;
  8309. if ((fieldInstance->mIsEnumPayloadCase) && (fieldDef->mName == caseName))
  8310. {
  8311. if ((!enumType->IsTypeMemberIncluded(fieldDef->mDeclaringType, activeTypeDef, mModule)) ||
  8312. (!enumType->IsTypeMemberAccessible(fieldDef->mDeclaringType, activeTypeDef)))
  8313. continue;
  8314. auto autoComplete = GetAutoComplete();
  8315. if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo))
  8316. {
  8317. BfAutoComplete::MethodMatchEntry methodMatchEntry;
  8318. methodMatchEntry.mPayloadEnumField = fieldInstance;
  8319. methodMatchEntry.mTypeInstance = enumType;
  8320. methodMatchEntry.mCurMethodInstance = mModule->mCurMethodInstance;
  8321. autoComplete->mMethodMatchInfo->mInstanceList.push_back(methodMatchEntry);
  8322. }
  8323. if (resolvePassData != NULL)
  8324. {
  8325. BfAstNode* nameNode = targetSrc;
  8326. if (resolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Field)
  8327. resolvePassData->HandleFieldReference(nameNode, enumType->mTypeDef, fieldDef);
  8328. }
  8329. BfIRValue enumValue;
  8330. BfTypedValue result;
  8331. bool wantConst = IsConstEval();
  8332. if (wantConst)
  8333. {
  8334. //
  8335. }
  8336. else if ((mReceivingValue != NULL) && (mReceivingValue->mType == enumType) && (mReceivingValue->IsAddr()))
  8337. {
  8338. result = *mReceivingValue;
  8339. mReceivingValue = NULL;
  8340. enumValue = result.mValue;
  8341. }
  8342. else
  8343. {
  8344. mResultIsTempComposite = true;
  8345. enumValue = mModule->CreateAlloca(enumType);
  8346. result = BfTypedValue(enumValue, fieldInstance->mOwner, BfTypedValueKind_TempAddr);
  8347. }
  8348. BF_ASSERT(fieldInstance->mResolvedType->IsTuple());
  8349. auto tupleType = (BfTypeInstance*)fieldInstance->mResolvedType;
  8350. mModule->mBfIRBuilder->PopulateType(tupleType);
  8351. if (tupleType->IsDeleting())
  8352. {
  8353. mModule->FailInternal("Deleted tuple type found in CheckEnumCreation", targetSrc);
  8354. return BfTypedValue();
  8355. }
  8356. bool constFailed = false;
  8357. SizedArray<BfIRValue, 8> constTupleMembers;
  8358. BfIRValue fieldPtr;
  8359. BfIRValue tuplePtr;
  8360. if (wantConst)
  8361. {
  8362. constTupleMembers.Add(mModule->mBfIRBuilder->CreateConstAggZero(mModule->mBfIRBuilder->MapType(tupleType->mBaseType)));
  8363. }
  8364. else if (!tupleType->IsValuelessType())
  8365. {
  8366. fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(enumValue, 0, 1);
  8367. auto tuplePtrType = mModule->CreatePointerType(tupleType);
  8368. auto mappedPtrType = mModule->mBfIRBuilder->MapType(tuplePtrType);
  8369. tuplePtr = mModule->mBfIRBuilder->CreateBitCast(fieldPtr, mappedPtrType);
  8370. }
  8371. for (int tupleFieldIdx = 0; tupleFieldIdx < (int)tupleType->mFieldInstances.size(); tupleFieldIdx++)
  8372. {
  8373. auto tupleFieldInstance = &tupleType->mFieldInstances[tupleFieldIdx];
  8374. auto resolvedFieldType = tupleFieldInstance->GetResolvedType();
  8375. if (tupleFieldIdx >= argValues.mResolvedArgs.size())
  8376. {
  8377. BfAstNode* refNode = targetSrc;
  8378. BfAstNode* prevNode = NULL;
  8379. if (mModule->mParentNodeEntry != NULL)
  8380. {
  8381. if (auto invokeExpr = BfNodeDynCast<BfInvocationExpression>(mModule->mParentNodeEntry->mNode))
  8382. {
  8383. if (invokeExpr->mCloseParen != NULL)
  8384. refNode = invokeExpr->mCloseParen;
  8385. }
  8386. }
  8387. BfError* error = mModule->Fail(StrFormat("Not enough parameters specified, expected %d more.", tupleType->mFieldInstances.size() - (int)argValues.mArguments->size()), refNode);
  8388. if (error != NULL)
  8389. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See enum declaration"), fieldDef->mFieldDeclaration);
  8390. if (wantConst)
  8391. constFailed = true;
  8392. break;
  8393. }
  8394. BfTypedValue receivingValue;
  8395. BfIRValue tupleFieldPtr;
  8396. mModule->PopulateType(tupleFieldInstance->mResolvedType);
  8397. if (tupleFieldInstance->mResolvedType->IsValuelessType())
  8398. {
  8399. receivingValue = mModule->GetDefaultTypedValue(tupleFieldInstance->mResolvedType);
  8400. }
  8401. else if (tuplePtr)
  8402. {
  8403. tupleFieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(tuplePtr, 0, tupleFieldInstance->mDataIdx);
  8404. receivingValue = BfTypedValue(tupleFieldPtr, tupleFieldInstance->mResolvedType, true);
  8405. }
  8406. auto argValue = ResolveArgValue(argValues.mResolvedArgs[tupleFieldIdx], resolvedFieldType, &receivingValue);
  8407. if (!argValue)
  8408. {
  8409. if (wantConst)
  8410. constFailed = true;
  8411. continue;
  8412. }
  8413. if (resolvedFieldType->IsValuelessType())
  8414. continue;
  8415. // Used receiving value?
  8416. if (argValue.mValue == receivingValue.mValue)
  8417. continue;
  8418. argValue = mModule->AggregateSplat(argValue);
  8419. argValues.mResolvedArgs[tupleFieldIdx].mExpectedType = resolvedFieldType;
  8420. if (argValue)
  8421. {
  8422. if ((argValue.mType->IsRef()) && (argValue.mType->GetUnderlyingType() == resolvedFieldType))
  8423. {
  8424. if (auto unaryOperator = BfNodeDynCast<BfUnaryOperatorExpression>(argValues.mResolvedArgs[tupleFieldIdx].mExpression))
  8425. {
  8426. mModule->Fail(StrFormat("Invalid use of '%s'. Enum payloads can only be retrieved through 'case' expressions.", BfGetOpName(unaryOperator->mOp)), unaryOperator->mOpToken);
  8427. argValue = mModule->GetDefaultTypedValue(resolvedFieldType);
  8428. }
  8429. else if (auto varDecl = BfNodeDynCast<BfVariableDeclaration>(argValues.mResolvedArgs[tupleFieldIdx].mExpression))
  8430. {
  8431. mModule->Fail("Invalid variable declaration. Enum payloads can only be retrieved through 'case' expressions.", varDecl);
  8432. argValue = mModule->GetDefaultTypedValue(resolvedFieldType);
  8433. }
  8434. }
  8435. // argValue can have a value even if tuplePtr does not have a value. This can happen if we are assigning to a (void) tuple,
  8436. // but we have a value that needs to be attempted to be casted to void
  8437. argValue = mModule->Cast(argValues.mResolvedArgs[tupleFieldIdx].mExpression, argValue, resolvedFieldType, wantConst ? BfCastFlags_WantsConst : BfCastFlags_None);
  8438. if (wantConst)
  8439. {
  8440. if (!argValue.mValue.IsConst())
  8441. {
  8442. mModule->Fail("Field not const", argValues.mResolvedArgs[tupleFieldIdx].mExpression);
  8443. constFailed = true;
  8444. }
  8445. constTupleMembers.Add(argValue.mValue);
  8446. }
  8447. else if (tupleFieldPtr)
  8448. {
  8449. argValue = mModule->LoadValue(argValue);
  8450. if (argValue)
  8451. mModule->mBfIRBuilder->CreateAlignedStore(argValue.mValue, tupleFieldPtr, resolvedFieldType->mAlign);
  8452. }
  8453. }
  8454. else if (wantConst)
  8455. constFailed = true;
  8456. }
  8457. if ((intptr)argValues.mResolvedArgs.size() > tupleType->mFieldInstances.size())
  8458. {
  8459. BfAstNode* errorRef = argValues.mResolvedArgs[tupleType->mFieldInstances.size()].mExpression;
  8460. if (errorRef == NULL)
  8461. errorRef = targetSrc;
  8462. BfError* error = mModule->Fail(StrFormat("Too many arguments, expected %d fewer.", argValues.mResolvedArgs.size() - tupleType->mFieldInstances.size()), errorRef);
  8463. if (error != NULL)
  8464. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See enum declaration"), fieldDef->mFieldDeclaration);
  8465. if (wantConst)
  8466. constFailed = true;
  8467. }
  8468. auto dscrType = enumType->GetDiscriminatorType();
  8469. auto dscrField = &enumType->mFieldInstances.back();
  8470. int tagIdx = -fieldInstance->mDataIdx - 1;
  8471. if ((wantConst) && (!constFailed))
  8472. {
  8473. auto unionType = enumType->GetUnionInnerType();
  8474. auto constTuple = mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(tupleType, BfIRPopulateType_Full), constTupleMembers);
  8475. Array<uint8> memArr;
  8476. memArr.Resize(unionType->mSize);
  8477. if (!mModule->mBfIRBuilder->WriteConstant(constTuple, memArr.mVals, tupleType))
  8478. {
  8479. constFailed = true;
  8480. }
  8481. else
  8482. {
  8483. auto unionValue = mModule->mBfIRBuilder->ReadConstant(memArr.mVals, unionType);
  8484. if (!unionValue)
  8485. {
  8486. constFailed = true;
  8487. }
  8488. else
  8489. {
  8490. SizedArray<BfIRValue, 3> constEnumMembers;
  8491. constEnumMembers.Add(mModule->mBfIRBuilder->CreateConstAggZero(mModule->mBfIRBuilder->MapType(enumType->mBaseType, BfIRPopulateType_Full)));
  8492. constEnumMembers.Add(unionValue);
  8493. constEnumMembers.Add(mModule->mBfIRBuilder->CreateConst(dscrType->mTypeDef->mTypeCode, tagIdx));
  8494. return BfTypedValue(mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(enumType, BfIRPopulateType_Full), constEnumMembers), enumType);
  8495. }
  8496. }
  8497. }
  8498. if (constFailed)
  8499. {
  8500. return mModule->GetDefaultTypedValue(enumType, false, BfDefaultValueKind_Addr);
  8501. }
  8502. auto dscFieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(enumValue, 0, dscrField->mDataIdx);
  8503. mModule->mBfIRBuilder->CreateAlignedStore(mModule->mBfIRBuilder->CreateConst(dscrType->mTypeDef->mTypeCode, tagIdx), dscFieldPtr, 4);
  8504. return result;
  8505. }
  8506. }
  8507. return BfTypedValue();
  8508. }
  8509. bool BfExprEvaluator::CheckGenericCtor(BfGenericParamType* genericParamType, BfResolvedArgs& argValues, BfAstNode* targetSrc)
  8510. {
  8511. BfGenericParamFlags genericParamFlags = BfGenericParamFlag_None;
  8512. BfType* typeConstraint = NULL;
  8513. auto genericParam = mModule->GetMergedGenericParamData((BfGenericParamType*)genericParamType, genericParamFlags, typeConstraint);
  8514. bool success = true;
  8515. if ((argValues.mArguments != NULL) && (argValues.mArguments->size() != 0))
  8516. {
  8517. mModule->Fail(StrFormat("Only default parameterless constructors can be called on generic argument '%s'", genericParam->GetGenericParamDef()->mName.c_str()), targetSrc);
  8518. success = false;
  8519. }
  8520. else if ((genericParamFlags & (BfGenericParamFlag_New | BfGenericParamFlag_Struct | BfGenericParamFlag_Var)) == 0)
  8521. {
  8522. mModule->Fail(StrFormat("Must add 'where %s : new, struct' constraint to generic parameter to instantiate type", genericParam->GetGenericParamDef()->mName.c_str()), targetSrc);
  8523. success = false;
  8524. }
  8525. else if ((genericParamFlags & (BfGenericParamFlag_New | BfGenericParamFlag_Var)) == 0)
  8526. {
  8527. mModule->Fail(StrFormat("Must add 'where %s : new' constraint to generic parameter to instantiate type", genericParam->GetGenericParamDef()->mName.c_str()), targetSrc);
  8528. success = false;
  8529. }
  8530. else if ((genericParamFlags & (BfGenericParamFlag_Struct | BfGenericParamFlag_Var)) == 0)
  8531. {
  8532. mModule->Fail(StrFormat("Must add 'where %s : struct' constraint to generic parameter to instantiate type without allocator", genericParam->GetGenericParamDef()->mName.c_str()), targetSrc);
  8533. success = false;
  8534. }
  8535. else if ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0)
  8536. {
  8537. mModule->Fail(StrFormat("Generic parameter '%s' constructor cannot be guaranteed to be const-evaluable", genericParam->GetGenericParamDef()->mName.c_str()), targetSrc);
  8538. }
  8539. return success;
  8540. }
  8541. BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExpression* methodBoundExpr, BfTypedValue target, bool allowImplicitThis, bool bypassVirtual, const StringImpl& methodName,
  8542. BfResolvedArgs& argValues, const BfMethodGenericArguments& methodGenericArgs, BfCheckedKind checkedKind)
  8543. {
  8544. BP_ZONE("MatchMethod");
  8545. auto methodGenericArguments = methodGenericArgs.mArguments;
  8546. if (bypassVirtual)
  8547. {
  8548. // "bypassVirtual" means that we know for sure that the target is EXACTLY the specified target type,
  8549. // not derived from (or implementing) the target type. This cannot apply to interfaces.
  8550. BF_ASSERT(!target.mType->IsInterface());
  8551. }
  8552. auto origTarget = target;
  8553. if (mFunctionBindResult != NULL)
  8554. {
  8555. BF_ASSERT(!mFunctionBindResult->mOrigTarget);
  8556. mFunctionBindResult->mOrigTarget = origTarget;
  8557. }
  8558. if (target)
  8559. {
  8560. if (target.mType->IsConcreteInterfaceType())
  8561. target.mType = target.mType->GetUnderlyingType();
  8562. // Turn T* into a T, if we can
  8563. if ((target.mType->IsPointer()) && (target.mType->GetUnderlyingType()->IsGenericParam()))
  8564. {
  8565. auto underlyingType = target.mType->GetUnderlyingType();
  8566. auto genericParam = mModule->GetGenericParamInstance((BfGenericParamType*)underlyingType);
  8567. if (((genericParam->mTypeConstraint != NULL) && (genericParam->mTypeConstraint->IsValueType())) ||
  8568. ((genericParam->mGenericParamFlags & (BfGenericParamFlag_Struct)) != 0))
  8569. {
  8570. target.mType = underlyingType;
  8571. }
  8572. }
  8573. if ((!target.mType->IsGenericParam()) &&
  8574. ((!target.IsSplat()) || (target.mType->IsWrappableType())) &&
  8575. (!IsVar(target.mType)))
  8576. target = MakeCallableTarget(targetSrc, target);
  8577. }
  8578. // static int sCallIdx = 0;
  8579. // if (!mModule->mCompiler->mIsResolveOnly)
  8580. // sCallIdx++;
  8581. // int callIdx = sCallIdx;
  8582. // if (callIdx == 118)
  8583. // {
  8584. // NOP;
  8585. // }
  8586. bool prevAllowVariableDeclarations = true;
  8587. if (mModule->mCurMethodState != NULL)
  8588. {
  8589. // Don't allow variable declarations in arguments for this method call
  8590. prevAllowVariableDeclarations = mModule->mCurMethodState->mCurScope->mAllowVariableDeclarations;
  8591. mModule->mCurMethodState->mCurScope->mAllowVariableDeclarations = false;
  8592. }
  8593. defer
  8594. (
  8595. if (mModule->mCurMethodState != NULL)
  8596. mModule->mCurMethodState->mCurScope->mAllowVariableDeclarations = prevAllowVariableDeclarations;
  8597. );
  8598. // Temporarily disable so we don't capture calls in params
  8599. SetAndRestoreValue<BfFunctionBindResult*> prevBindResult(mFunctionBindResult, NULL);
  8600. sInvocationIdx++;
  8601. bool wantCtor = methodName.IsEmpty();
  8602. BfAutoComplete::MethodMatchInfo* restoreCapturingMethodMatchInfo = NULL;
  8603. auto autoComplete = GetAutoComplete();
  8604. if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo))
  8605. {
  8606. if ((!targetSrc->IsFromParser(mModule->mCompiler->mResolvePassData->mParsers[0])) ||
  8607. ((autoComplete->mMethodMatchInfo->mInvocationSrcIdx != -1) && (autoComplete->mMethodMatchInfo->mInvocationSrcIdx != targetSrc->GetSrcStart())))
  8608. {
  8609. autoComplete->mIsCapturingMethodMatchInfo = false;
  8610. restoreCapturingMethodMatchInfo = autoComplete->mMethodMatchInfo;
  8611. }
  8612. }
  8613. defer(
  8614. {
  8615. if ((restoreCapturingMethodMatchInfo != NULL) && (autoComplete->mMethodMatchInfo == restoreCapturingMethodMatchInfo))
  8616. autoComplete->mIsCapturingMethodMatchInfo = true;
  8617. });
  8618. /*if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo) && (autoComplete->mMethodMatchInfo->mInstanceList.size() != 0))
  8619. autoComplete->mIsCapturingMethodMatchInfo = false;*/
  8620. bool isUnboundCall = false;
  8621. if (target.mType != NULL)
  8622. {
  8623. if (target.mType->IsGenericParam())
  8624. {
  8625. auto genericParamTarget = (BfGenericParamType*) target.mType;
  8626. auto genericParamInstance = mModule->GetGenericParamInstance(genericParamTarget);
  8627. isUnboundCall = (genericParamInstance->mGenericParamFlags & BfGenericParamFlag_Var) != 0;
  8628. if (isUnboundCall)
  8629. {
  8630. if (mModule->mCurMethodInstance->mIsUnspecialized)
  8631. {
  8632. auto varType = mModule->GetPrimitiveType(BfTypeCode_Var);
  8633. target.mType = varType;
  8634. }
  8635. }
  8636. }
  8637. else if (IsVar(target.mType))
  8638. isUnboundCall = true;
  8639. }
  8640. /*if (mPrefixedAttributeState != NULL)
  8641. {
  8642. auto customAttr = mPrefixedAttributeState->mCustomAttributes->Get(mModule->mCompiler->mUnboundAttributeTypeDef);
  8643. if (customAttr != NULL)
  8644. {
  8645. if (!mModule->IsInGeneric())
  8646. {
  8647. mModule->Fail("'Unbound' can only be used within generics");
  8648. }
  8649. mPrefixedAttributeState->mUsed = true;
  8650. isUnboundCall = true;
  8651. }
  8652. }*/
  8653. if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL))
  8654. {
  8655. auto customAttr = mModule->mAttributeState->mCustomAttributes->Get(mModule->mCompiler->mUnboundAttributeTypeDef);
  8656. if (customAttr != NULL)
  8657. {
  8658. if (!mModule->IsInGeneric())
  8659. {
  8660. mModule->Fail("'Unbound' can only be used within generics");
  8661. }
  8662. mModule->mAttributeState->mUsed = true;
  8663. isUnboundCall = true;
  8664. }
  8665. }
  8666. if (isUnboundCall)
  8667. {
  8668. if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsUnspecialized))
  8669. {
  8670. auto varType = mModule->GetPrimitiveType(BfTypeCode_Var);
  8671. for (int argIdx = 0; argIdx < (int)argValues.mResolvedArgs.size(); argIdx++)
  8672. {
  8673. if ((argValues.mResolvedArgs[argIdx].mArgFlags & BfArgFlag_DeferredEval) != 0)
  8674. {
  8675. mModule->CreateValueFromExpression((*argValues.mArguments)[argIdx], varType);
  8676. }
  8677. }
  8678. return BfTypedValue(mModule->GetDefaultValue(varType), varType);
  8679. }
  8680. }
  8681. SetAndRestoreValue<bool> prevNoBind(mNoBind, mNoBind || isUnboundCall);
  8682. bool wantsExtensionCheck = target;
  8683. auto targetType = target.mType;
  8684. BfTypeDef* curTypeDef = NULL;
  8685. BfType* selfType = NULL;
  8686. BfTypeInstance* targetTypeInst = NULL;
  8687. bool checkNonStatic = true;
  8688. if (target)
  8689. {
  8690. if (IsVar(targetType))
  8691. return mModule->GetDefaultTypedValue(targetType);
  8692. targetTypeInst = targetType->ToTypeInstance();
  8693. if (targetTypeInst != NULL)
  8694. curTypeDef = targetTypeInst->mTypeDef;
  8695. }
  8696. else if (targetType != NULL) // Static targeted
  8697. {
  8698. if (targetType->IsWrappableType())
  8699. {
  8700. if ((targetType->IsPrimitiveType()) && (methodName.IsEmpty()))
  8701. {
  8702. if (argValues.mArguments->IsEmpty())
  8703. {
  8704. return mModule->GetDefaultTypedValue(targetType);
  8705. }
  8706. else if (argValues.mArguments->mSize == 1)
  8707. {
  8708. FinishDeferredEvals(argValues);
  8709. // This is just a primitive cast
  8710. auto& resolvedArg = argValues.mResolvedArgs[0];
  8711. BfTypedValue castedValue;
  8712. BfTypedValue castTarget = resolvedArg.mTypedValue;
  8713. if (resolvedArg.mTypedValue)
  8714. {
  8715. castTarget = mModule->LoadValue(castTarget);
  8716. castedValue = mModule->Cast(targetSrc, castTarget, targetType, BfCastFlags_Explicit);
  8717. }
  8718. if (!castedValue)
  8719. castedValue = mModule->GetDefaultTypedValue(targetType);
  8720. return castedValue;
  8721. }
  8722. }
  8723. targetTypeInst = mModule->GetWrappedStructType(targetType);
  8724. }
  8725. else if (targetType->IsGenericParam())
  8726. {
  8727. auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)targetType);
  8728. if (genericParamInstance->mTypeConstraint != NULL)
  8729. targetTypeInst = genericParamInstance->mTypeConstraint->ToTypeInstance();
  8730. if (genericParamInstance->mGenericParamFlags & BfGenericParamFlag_Var)
  8731. {
  8732. auto varType = mModule->GetPrimitiveType(BfTypeCode_Var);
  8733. return BfTypedValue(mModule->GetDefaultValue(varType), varType);
  8734. }
  8735. }
  8736. else
  8737. targetTypeInst = targetType->ToTypeInstance();
  8738. if (targetTypeInst == NULL)
  8739. {
  8740. //mModule->Fail("No static methods available", targetSrc);
  8741. //return BfTypedValue();
  8742. }
  8743. else
  8744. {
  8745. curTypeDef = targetTypeInst->mTypeDef;
  8746. checkNonStatic = false;
  8747. }
  8748. }
  8749. else // Current scopeData
  8750. {
  8751. if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsForeignMethodDef) && (mModule->mCurMethodInstance->mMethodInfoEx->mForeignType->IsInterface()))
  8752. {
  8753. targetTypeInst = mModule->mCurMethodInstance->mMethodInfoEx->mForeignType;
  8754. curTypeDef = targetTypeInst->mTypeDef;
  8755. checkNonStatic = true;
  8756. target = mModule->GetThis();
  8757. selfType = mModule->mCurTypeInstance;
  8758. //target.mType = targetTypeInst;
  8759. }
  8760. else
  8761. {
  8762. curTypeDef = mModule->mCurTypeInstance->mTypeDef;
  8763. targetTypeInst = mModule->mCurTypeInstance;
  8764. if (mModule->mCurMethodState == NULL)
  8765. {
  8766. checkNonStatic = false;
  8767. }
  8768. else
  8769. {
  8770. if (mModule->mCurMethodState->mMixinState != NULL)
  8771. {
  8772. targetTypeInst = mModule->mCurMethodState->mMixinState->mMixinMethodInstance->GetOwner();
  8773. curTypeDef = targetTypeInst->mTypeDef;
  8774. }
  8775. if (mModule->mCurMethodState->mTempKind != BfMethodState::TempKind_None)
  8776. {
  8777. checkNonStatic = mModule->mCurMethodState->mTempKind == BfMethodState::TempKind_NonStatic;
  8778. }
  8779. else
  8780. checkNonStatic = !mModule->mCurMethodInstance->mMethodDef->mIsStatic;
  8781. }
  8782. }
  8783. }
  8784. bool isIndirectMethodCall = false;
  8785. BfType* lookupType = targetType;
  8786. BfTypeInstance* lookupTypeInst = targetTypeInst;
  8787. if (targetType != NULL)
  8788. {
  8789. lookupType = BindGenericType(targetSrc, targetType);
  8790. if (lookupType->IsGenericParam())
  8791. lookupTypeInst = NULL;
  8792. }
  8793. if ((mModule->mIsReified) && (targetTypeInst != NULL) && (!targetTypeInst->mIsReified) && (!targetTypeInst->mModule->mReifyQueued))
  8794. mModule->PopulateType(targetTypeInst);
  8795. BfMethodDef* methodDef = NULL;
  8796. BfTypeVector checkMethodGenericArguments;
  8797. BfTypeInstance* curTypeInst = targetTypeInst;
  8798. Array<SizedArray<BfUsingFieldData::MemberRef, 1>*> methodUsingLists;
  8799. BfMethodMatcher methodMatcher(targetSrc, mModule, methodName, argValues.mResolvedArgs, methodGenericArgs);
  8800. methodMatcher.mUsingLists = &methodUsingLists;
  8801. methodMatcher.mOrigTarget = origTarget;
  8802. methodMatcher.mTarget = target;
  8803. methodMatcher.mCheckedKind = checkedKind;
  8804. methodMatcher.mAllowImplicitThis = allowImplicitThis;
  8805. methodMatcher.mAllowStatic = !target.mValue;
  8806. methodMatcher.mAllowNonStatic = !methodMatcher.mAllowStatic;
  8807. methodMatcher.mAutoFlushAmbiguityErrors = !wantsExtensionCheck;
  8808. if (allowImplicitThis)
  8809. {
  8810. if (mModule->mCurMethodState == NULL)
  8811. {
  8812. methodMatcher.mAllowStatic = true;
  8813. methodMatcher.mAllowNonStatic = false;
  8814. }
  8815. else if (mModule->mCurMethodState->mTempKind != BfMethodState::TempKind_None)
  8816. {
  8817. methodMatcher.mAllowNonStatic = mModule->mCurMethodState->mTempKind == BfMethodState::TempKind_NonStatic;
  8818. methodMatcher.mAllowStatic = true;
  8819. }
  8820. else
  8821. {
  8822. if (!mModule->mCurMethodInstance->mMethodDef->mIsStatic)
  8823. methodMatcher.mAllowNonStatic = true;
  8824. methodMatcher.mAllowStatic = true;
  8825. if (mModule->mCurMethodInstance->mMethodDef->mIsLocalMethod)
  8826. {
  8827. auto rootMethodState = mModule->mCurMethodState->GetRootMethodState();
  8828. methodMatcher.mAllowNonStatic = !rootMethodState->mMethodInstance->mMethodDef->mIsStatic;
  8829. }
  8830. }
  8831. }
  8832. if (methodName == BF_METHODNAME_CALCAPPEND)
  8833. methodMatcher.mMethodType = BfMethodType_CtorCalcAppend;
  8834. BF_ASSERT(methodMatcher.mBestMethodDef == NULL);
  8835. BfLocalMethod* matchedLocalMethod = NULL;
  8836. if (target.mType == NULL)
  8837. {
  8838. CheckLocalMethods(targetSrc, curTypeInst, methodName, methodMatcher, BfMethodType_Normal);
  8839. if (methodMatcher.mBestMethodDef == NULL)
  8840. methodMatcher.mBestMethodDef = methodMatcher.mBackupMethodDef;
  8841. if (methodMatcher.mBestMethodDef != NULL)
  8842. {
  8843. auto rootMethodState = mModule->mCurMethodState->GetRootMethodState();
  8844. auto methodDef = methodMatcher.mBestMethodDef;
  8845. if (mModule->mCompiler->mResolvePassData != NULL)
  8846. {
  8847. auto identifierNode = BfNodeDynCast<BfIdentifierNode>(targetSrc);
  8848. mModule->mCompiler->mResolvePassData->HandleLocalReference(identifierNode, curTypeInst->mTypeDef, rootMethodState->mMethodInstance->mMethodDef, ~methodDef->mIdx);
  8849. auto autoComplete = GetAutoComplete();
  8850. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(identifierNode)))
  8851. {
  8852. autoComplete->SetDefinitionLocation(methodDef->GetRefNode(), true);
  8853. if (autoComplete->mDefType == NULL)
  8854. {
  8855. autoComplete->mDefMethod = mModule->mCurMethodState->GetRootMethodState()->mMethodInstance->mMethodDef;
  8856. autoComplete->mDefType = curTypeDef;
  8857. autoComplete->mReplaceLocalId = ~methodDef->mIdx;
  8858. }
  8859. }
  8860. if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo))
  8861. {
  8862. BfAutoComplete::MethodMatchEntry methodMatchEntry;
  8863. methodMatchEntry.mMethodDef = methodDef;
  8864. methodMatchEntry.mTypeInstance = mModule->mCurTypeInstance;
  8865. methodMatchEntry.mCurMethodInstance = mModule->mCurMethodInstance;
  8866. autoComplete->mMethodMatchInfo->mInstanceList.push_back(methodMatchEntry);
  8867. }
  8868. }
  8869. if ((mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mCapturing))
  8870. {
  8871. auto methodInstance = mModule->GetRawMethodInstance(methodMatcher.mBestMethodTypeInstance, methodMatcher.mBestMethodDef);
  8872. if (methodInstance->mReturnType == NULL)
  8873. {
  8874. FinishDeferredEvals(argValues);
  8875. // If we are recursive then we won't even have a completed methodInstance yet to look at
  8876. return mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  8877. }
  8878. }
  8879. }
  8880. }
  8881. if (methodMatcher.mBestMethodDef == NULL)
  8882. {
  8883. if (lookupTypeInst == NULL)
  8884. {
  8885. if ((lookupType != NULL) && (lookupType->IsConcreteInterfaceType()))
  8886. {
  8887. auto concreteInterfaceType = (BfConcreteInterfaceType*)lookupType;
  8888. lookupTypeInst = concreteInterfaceType->mInterface;
  8889. }
  8890. else if (isUnboundCall)
  8891. {
  8892. //auto resolvedType = mModule->ResolveGenericType(lookupType);
  8893. }
  8894. else if (lookupType->IsGenericParam())
  8895. {
  8896. auto genericParamTarget = (BfGenericParamType*)lookupType;
  8897. auto _HandleGenericParamInstance = [&](BfGenericParamInstance* genericParamInstance)
  8898. {
  8899. if (genericParamInstance->mTypeConstraint != NULL)
  8900. lookupTypeInst = genericParamInstance->mTypeConstraint->ToTypeInstance();
  8901. else
  8902. lookupTypeInst = mModule->mContext->mBfObjectType;
  8903. for (BfType* ifaceInst : genericParamInstance->mInterfaceConstraints)
  8904. {
  8905. BfTypeInstance* typeInst = ifaceInst->ToTypeInstance();
  8906. BF_ASSERT(typeInst != NULL);
  8907. if (methodMatcher.CheckType(typeInst, target, false))
  8908. methodMatcher.mSelfType = lookupType;
  8909. }
  8910. };
  8911. auto genericParamInstance = mModule->GetGenericParamInstance(genericParamTarget, true);
  8912. _HandleGenericParamInstance(genericParamInstance);
  8913. // Check method generic constraints
  8914. if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsUnspecialized) && (mModule->mCurMethodInstance->mMethodInfoEx != NULL))
  8915. {
  8916. for (int genericParamIdx = (int)mModule->mCurMethodInstance->mMethodInfoEx->mMethodGenericArguments.size();
  8917. genericParamIdx < mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams.size(); genericParamIdx++)
  8918. {
  8919. auto genericParam = mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
  8920. if (genericParam->mExternType == lookupType)
  8921. _HandleGenericParamInstance(genericParam);
  8922. }
  8923. }
  8924. }
  8925. }
  8926. if ((lookupTypeInst != NULL) && (!wantCtor))
  8927. {
  8928. methodMatcher.mBypassVirtual = bypassVirtual;
  8929. methodMatcher.CheckType(lookupTypeInst, target, false);
  8930. }
  8931. if ((lookupType != NULL) && (lookupType->IsGenericParam()))
  8932. {
  8933. //lookupType = mModule->ResolveGenericType(lookupType);
  8934. if (!lookupType->IsGenericParam())
  8935. {
  8936. target = MakeCallableTarget(targetSrc, target);
  8937. if (target)
  8938. {
  8939. lookupTypeInst = lookupType->ToTypeInstance();
  8940. }
  8941. }
  8942. }
  8943. }
  8944. bool isFailurePass = false;
  8945. if (methodMatcher.mBestMethodDef == NULL)
  8946. {
  8947. isFailurePass = true;
  8948. if (lookupTypeInst != NULL)
  8949. methodMatcher.CheckType(lookupTypeInst, target, true);
  8950. }
  8951. BfTypedValue staticResult;
  8952. //
  8953. {
  8954. auto devirtTarget = target;
  8955. if ((devirtTarget.mType == NULL) && (selfType != NULL))
  8956. devirtTarget.mType = selfType;
  8957. methodMatcher.TryDevirtualizeCall(devirtTarget, &origTarget, &staticResult);
  8958. }
  8959. if (staticResult)
  8960. return staticResult;
  8961. bypassVirtual |= methodMatcher.mBypassVirtual;
  8962. if (methodMatcher.mBestMethodDef != NULL)
  8963. {
  8964. curTypeInst = methodMatcher.mBestMethodTypeInstance;
  8965. methodDef = methodMatcher.mBestMethodDef;
  8966. }
  8967. if ((methodDef) && (!methodDef->mIsStatic) && (!target) && (allowImplicitThis))
  8968. {
  8969. target = mModule->GetThis();
  8970. }
  8971. if (!methodUsingLists.IsEmpty())
  8972. {
  8973. auto foundList = methodUsingLists[0];
  8974. if (methodUsingLists.mSize > 1)
  8975. {
  8976. BfError* error = mModule->Fail("Ambiguous 'using' method reference", targetSrc);
  8977. if (error != NULL)
  8978. {
  8979. for (auto checkList : methodUsingLists)
  8980. {
  8981. String errorStr = "'";
  8982. for (int entryIdx = 0; entryIdx < checkList->mSize; entryIdx++)
  8983. {
  8984. if (entryIdx == 0)
  8985. errorStr += (*checkList)[entryIdx].GetFullName(mModule);
  8986. else
  8987. {
  8988. errorStr += ".";
  8989. errorStr += (*checkList)[entryIdx].GetName(mModule);
  8990. }
  8991. }
  8992. errorStr += "' is a candidate";
  8993. mModule->mCompiler->mPassInstance->MoreInfo(errorStr, (*checkList)[0].GetRefNode(mModule));
  8994. }
  8995. }
  8996. }
  8997. BfTypedValue curResult = target;
  8998. for (int entryIdx = 0; entryIdx < foundList->mSize; entryIdx++)
  8999. {
  9000. if ((entryIdx == 0) && (foundList->back().IsStatic()))
  9001. entryIdx = (int)foundList->mSize - 1;
  9002. auto& entry = (*foundList)[entryIdx];
  9003. if (mPropDef != NULL)
  9004. {
  9005. SetAndRestoreValue<BfTypedValue> prevResult(mResult, BfTypedValue());
  9006. mPropGetMethodFlags = (BfGetMethodInstanceFlags)(mPropGetMethodFlags | BfGetMethodInstanceFlag_Friend);
  9007. curResult = GetResult();
  9008. if (!curResult)
  9009. break;
  9010. }
  9011. auto useFlags = BfLookupFieldFlag_None;
  9012. if (entryIdx < foundList->mSize - 1)
  9013. useFlags = (BfLookupFieldFlags)(useFlags | BfLookupFieldFlag_IsAnonymous);
  9014. if (entry.mKind == BfUsingFieldData::MemberRef::Kind_Field)
  9015. {
  9016. curResult = LoadField(targetSrc, curResult, entry.mTypeInstance, entry.mTypeInstance->mTypeDef->mFields[entry.mIdx], useFlags);
  9017. }
  9018. else if (entry.mKind == BfUsingFieldData::MemberRef::Kind_Property)
  9019. {
  9020. curResult = LoadProperty(targetSrc, curResult, entry.mTypeInstance, entry.mTypeInstance->mTypeDef->mProperties[entry.mIdx], useFlags, BfCheckedKind_NotSet, false);
  9021. }
  9022. else if (entry.mKind == BfUsingFieldData::MemberRef::Kind_Local)
  9023. {
  9024. auto localDef = mModule->mCurMethodState->mLocals[entry.mIdx];
  9025. curResult = LoadLocal(localDef);
  9026. }
  9027. else if (entry.mKind == BfUsingFieldData::MemberRef::Kind_Local)
  9028. {
  9029. auto checkMethodDef = entry.mTypeInstance->mTypeDef->mMethods[entry.mIdx];
  9030. BF_ASSERT(methodDef == checkMethodDef);
  9031. break;
  9032. }
  9033. if ((!curResult) && (mPropDef == NULL))
  9034. break;
  9035. if (entryIdx == foundList->mSize - 1)
  9036. {
  9037. auto autoComplete = GetAutoComplete();
  9038. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(targetSrc)))
  9039. autoComplete->SetDefinitionLocation(entry.GetRefNode(mModule));
  9040. if ((autoComplete != NULL) && (autoComplete->CheckFixit(targetSrc)))
  9041. autoComplete->FixitAddFullyQualify(targetSrc, methodName, *foundList);
  9042. }
  9043. }
  9044. if (methodDef->mIsStatic)
  9045. target = BfTypedValue(curTypeInst);
  9046. else if (curResult)
  9047. target = curResult;
  9048. else if ((!methodDef->mIsStatic) && (curTypeInst != NULL))
  9049. target = mModule->GetDefaultTypedValue(curTypeInst);
  9050. }
  9051. // If we call "GetType" on a value type, statically determine the type rather than boxing and then dispatching
  9052. if ((methodDef) && (target) && (curTypeInst == mModule->mContext->mBfObjectType) &&
  9053. (methodDef->mName == "GetType") && (target.mType->IsValueType()) && (argValues.mArguments->IsEmpty()))
  9054. {
  9055. BfType* targetType = target.mType;
  9056. if (origTarget)
  9057. targetType = origTarget.mType;
  9058. auto typeType = mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef);
  9059. mModule->AddDependency(targetType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
  9060. return BfTypedValue(mModule->CreateTypeDataRef(targetType), typeType);
  9061. }
  9062. bool skipThis = false;
  9063. BfTypedValue fieldVal;
  9064. bool hasFieldVal = false;
  9065. // Fail, check for delegate field invocation
  9066. if ((methodDef == NULL) && ((methodGenericArguments == NULL) || (methodGenericArguments->size() == 0)))
  9067. {
  9068. // Check for payload enum initialization first
  9069. BfTypedValue enumResult;
  9070. BfTypeInstance* enumType = NULL;
  9071. if ((!target) && (target.HasType()) && (targetType->IsPayloadEnum()))
  9072. {
  9073. enumType = targetType->ToTypeInstance();
  9074. }
  9075. else if ((!target) && (!target.HasType()) && (mModule->mCurTypeInstance->IsPayloadEnum()))
  9076. {
  9077. enumType = mModule->mCurTypeInstance;
  9078. }
  9079. if (enumType != NULL)
  9080. {
  9081. enumResult = CheckEnumCreation(targetSrc, enumType, methodName, argValues);
  9082. }
  9083. if (enumResult)
  9084. {
  9085. if (mModule->mCompiler->mResolvePassData != NULL)
  9086. {
  9087. if (auto sourceClassifier = mModule->mCompiler->mResolvePassData->GetSourceClassifier(targetSrc))
  9088. {
  9089. sourceClassifier->SetElementType(targetSrc, BfSourceElementType_Normal);
  9090. }
  9091. }
  9092. return enumResult;
  9093. }
  9094. if (allowImplicitThis)
  9095. {
  9096. auto identifierNode = BfNodeDynCast<BfIdentifierNode>(targetSrc);
  9097. if (identifierNode != NULL)
  9098. fieldVal = LookupIdentifier(identifierNode);
  9099. }
  9100. else
  9101. {
  9102. SetAndRestoreValue<BfEvalExprFlags> prevFlags(mBfEvalExprFlags, (BfEvalExprFlags)(mBfEvalExprFlags & ~BfEvalExprFlags_AllowEnumId));
  9103. fieldVal = LookupField(targetSrc, target, methodName);
  9104. }
  9105. if (fieldVal)
  9106. {
  9107. hasFieldVal = true;
  9108. wantsExtensionCheck = !fieldVal.mType->IsDelegate() && !fieldVal.mType->IsFunction();
  9109. }
  9110. else if (mPropDef != NULL)
  9111. {
  9112. hasFieldVal = true;
  9113. BfMethodDef* matchedMethod = GetPropertyMethodDef(mPropDef, BfMethodType_PropertyGetter, mPropCheckedKind, mPropTarget);
  9114. if (matchedMethod != NULL)
  9115. {
  9116. auto getMethodInstance = mModule->GetRawMethodInstance(mPropTarget.mType->ToTypeInstance(), matchedMethod);
  9117. if ((getMethodInstance != NULL) &&
  9118. ((getMethodInstance->mReturnType->IsDelegate()) || (getMethodInstance->mReturnType->IsFunction())))
  9119. wantsExtensionCheck = false;
  9120. }
  9121. }
  9122. }
  9123. if ((!methodDef) && (!target.mValue))
  9124. {
  9125. // Check to see if we're constructing a struct via a call like: "Struct structVal = Struct()"
  9126. int wantNumGenericArgs = 0;
  9127. if ((methodGenericArguments != NULL) && (methodGenericArguments->size() > 0))
  9128. wantNumGenericArgs = (int)methodGenericArguments->size();
  9129. BfTypeInstance* resolvedTypeInstance = NULL;
  9130. BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None;
  9131. if (wantCtor)
  9132. {
  9133. resolvedTypeInstance = targetTypeInst;
  9134. }
  9135. else if (targetType != NULL)
  9136. {
  9137. if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(methodBoundExpr))
  9138. {
  9139. auto resolvedType = mModule->ResolveTypeRef_Ref(invocationExpr->mTarget, methodGenericArguments, BfPopulateType_Data, resolveFlags);
  9140. if (resolvedType != NULL)
  9141. resolvedTypeInstance = resolvedType->ToTypeInstance();
  9142. }
  9143. }
  9144. else
  9145. {
  9146. BfIdentifierNode* identifierNode = BfNodeDynCast<BfIdentifierNode>(targetSrc);
  9147. if (identifierNode != NULL)
  9148. {
  9149. SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
  9150. BfType* refType;
  9151. if (methodGenericArguments != NULL)
  9152. {
  9153. refType = mModule->ResolveTypeRef_Ref(identifierNode, methodGenericArguments, BfPopulateType_Data, resolveFlags);
  9154. }
  9155. else
  9156. refType = mModule->ResolveTypeRef_Ref(identifierNode, NULL, BfPopulateType_Data, resolveFlags);
  9157. prevIgnoreErrors.Restore();
  9158. if ((refType != NULL) && (refType->IsPrimitiveType()))
  9159. {
  9160. for (auto& resolvedArg : argValues.mResolvedArgs)
  9161. resolvedArg.mExpectedType = refType;
  9162. FinishDeferredEvals(argValues);
  9163. if (argValues.mResolvedArgs.IsEmpty())
  9164. return mModule->GetDefaultTypedValue(refType);
  9165. if (argValues.mResolvedArgs.size() != 1)
  9166. {
  9167. mModule->Fail("Cast requires one parameter", targetSrc);
  9168. return BfTypedValue();
  9169. }
  9170. // This is just a primitive cast
  9171. auto& resolvedArg = argValues.mResolvedArgs[0];
  9172. BfTypedValue castedValue;
  9173. BfTypedValue castTarget = resolvedArg.mTypedValue;
  9174. if (resolvedArg.mTypedValue)
  9175. {
  9176. castTarget = mModule->LoadValue(castTarget);
  9177. castedValue = mModule->Cast(targetSrc, castTarget, refType, BfCastFlags_Explicit);
  9178. }
  9179. if (!castedValue)
  9180. castedValue = mModule->GetDefaultTypedValue(refType);
  9181. return castedValue;
  9182. }
  9183. if (refType != NULL)
  9184. {
  9185. resolvedTypeInstance = refType->ToTypeInstance();
  9186. if (refType->IsGenericParam())
  9187. {
  9188. CheckGenericCtor((BfGenericParamType*)refType, argValues, targetSrc);
  9189. return mModule->GetDefaultTypedValue(refType);
  9190. }
  9191. }
  9192. }
  9193. }
  9194. if (resolvedTypeInstance != NULL)
  9195. {
  9196. auto origTypeInstance = resolvedTypeInstance;
  9197. if ((mBfEvalExprFlags & BfEvalExprFlags_AppendFieldInitializer) == 0)
  9198. {
  9199. if ((!resolvedTypeInstance->IsStruct()) && (!resolvedTypeInstance->IsTypedPrimitive()))
  9200. {
  9201. if (mModule->PreFail())
  9202. mModule->Fail("Objects must be allocated through 'new' or 'scope'", targetSrc);
  9203. return BfTypedValue();
  9204. }
  9205. }
  9206. if (auto identifier = BfNodeDynCastExact<BfIdentifierNode>(targetSrc))
  9207. {
  9208. auto elementType = resolvedTypeInstance->IsEnum() ? BfSourceElementType_Type : BfSourceElementType_Struct;
  9209. if (resolvedTypeInstance->IsObject())
  9210. elementType = BfSourceElementType_RefType;
  9211. mModule->SetElementType(identifier, elementType);
  9212. }
  9213. if (mModule->mCompiler->mResolvePassData != NULL)
  9214. {
  9215. if ((!BfNodeIsA<BfMemberReferenceExpression>(targetSrc)) && ((resolveFlags & BfResolveTypeRefFlag_FromIndirectSource) == 0))
  9216. mModule->mCompiler->mResolvePassData->HandleTypeReference(targetSrc, resolvedTypeInstance->mTypeDef);
  9217. }
  9218. BfTypedValue structInst;
  9219. mModule->PopulateType(resolvedTypeInstance);
  9220. if (!resolvedTypeInstance->IsValuelessType())
  9221. {
  9222. if ((mReceivingValue != NULL) && (mReceivingValue->mType == resolvedTypeInstance) && (mReceivingValue->IsAddr()))
  9223. {
  9224. structInst = *mReceivingValue;
  9225. mReceivingValue = NULL;
  9226. }
  9227. else
  9228. {
  9229. auto allocaInst = mModule->CreateAlloca(resolvedTypeInstance);
  9230. structInst = BfTypedValue(allocaInst, resolvedTypeInstance, true);
  9231. }
  9232. mResultIsTempComposite = true;
  9233. }
  9234. else
  9235. {
  9236. structInst = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), resolvedTypeInstance, true);
  9237. }
  9238. bool doBind = false;
  9239. mResultLocalVar = NULL;
  9240. mResultFieldInstance = NULL;
  9241. mResultLocalVarRefNode = NULL;
  9242. BfTypedValue result = MatchConstructor(targetSrc, methodBoundExpr, structInst, resolvedTypeInstance, argValues, false, BfMethodGenericArguments(),
  9243. resolvedTypeInstance->IsObject() ? BfAllowAppendKind_Infer : BfAllowAppendKind_No);
  9244. if ((result) && (!result.mType->IsVoid()))
  9245. return result;
  9246. mModule->ValidateAllocation(resolvedTypeInstance, targetSrc);
  9247. mModule->AddDependency(resolvedTypeInstance, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage);
  9248. if (mUsedAsStatement)
  9249. {
  9250. mModule->Warn(0, "Struct constructor being used as a statement", targetSrc);
  9251. }
  9252. return structInst;
  9253. }
  9254. }
  9255. // For for extensions in current type
  9256. if (wantsExtensionCheck)
  9257. {
  9258. auto checkTypeInst = mModule->mCurTypeInstance;
  9259. methodMatcher.mMethodType = BfMethodType_Extension;
  9260. if (methodMatcher.CheckType(checkTypeInst, BfTypedValue(), false, true))
  9261. {
  9262. isFailurePass = false;
  9263. curTypeInst = methodMatcher.mBestMethodTypeInstance;
  9264. methodDef = methodMatcher.mBestMethodDef;
  9265. }
  9266. }
  9267. // Look in globals. Always check for extension methods.
  9268. if ((((methodDef == NULL) && (!target.HasType())) ||
  9269. (wantsExtensionCheck)))
  9270. {
  9271. if (mModule->mContext->mCurTypeState != NULL)
  9272. {
  9273. BfGlobalLookup globalLookup;
  9274. globalLookup.mKind = BfGlobalLookup::Kind_Method;
  9275. globalLookup.mName = methodName;
  9276. mModule->PopulateGlobalContainersList(globalLookup);
  9277. for (auto& globalContainer : mModule->mContext->mCurTypeState->mGlobalContainers)
  9278. {
  9279. if (globalContainer.mTypeInst == NULL)
  9280. continue;
  9281. methodMatcher.mMethodType = wantsExtensionCheck ? BfMethodType_Extension : BfMethodType_Normal;
  9282. if (methodMatcher.CheckType(globalContainer.mTypeInst, BfTypedValue(), false))
  9283. {
  9284. isFailurePass = false;
  9285. curTypeInst = methodMatcher.mBestMethodTypeInstance;
  9286. methodDef = methodMatcher.mBestMethodDef;
  9287. }
  9288. }
  9289. }
  9290. }
  9291. // Look in static search. Always check for extension methods.
  9292. if ((methodDef == NULL) || (wantsExtensionCheck))
  9293. {
  9294. BfStaticSearch* staticSearch = mModule->GetStaticSearch();
  9295. if (staticSearch != NULL)
  9296. {
  9297. for (auto typeInst : staticSearch->mStaticTypes)
  9298. {
  9299. methodMatcher.mMethodType = wantsExtensionCheck ? BfMethodType_Extension : BfMethodType_Normal;
  9300. if (methodMatcher.CheckType(typeInst, BfTypedValue(), false))
  9301. {
  9302. isFailurePass = false;
  9303. curTypeInst = methodMatcher.mBestMethodTypeInstance;
  9304. methodDef = methodMatcher.mBestMethodDef;
  9305. }
  9306. }
  9307. }
  9308. }
  9309. if ((methodDef == NULL) && (hasFieldVal))
  9310. {
  9311. if (mPropDef != NULL)
  9312. fieldVal = GetResult();
  9313. if (fieldVal)
  9314. {
  9315. if (fieldVal.mType->IsGenericParam())
  9316. {
  9317. bool delegateFailed = true;
  9318. auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)fieldVal.mType);
  9319. BfTypeInstance* typeInstConstraint = NULL;
  9320. if (genericParamInstance->mTypeConstraint != NULL)
  9321. typeInstConstraint = genericParamInstance->mTypeConstraint->ToTypeInstance();
  9322. if ((typeInstConstraint != NULL) &&
  9323. ((typeInstConstraint->IsInstanceOf(mModule->mCompiler->mDelegateTypeDef)) || (typeInstConstraint->IsInstanceOf(mModule->mCompiler->mFunctionTypeDef))))
  9324. {
  9325. MarkResultUsed();
  9326. if (argValues.mArguments->size() == 1)
  9327. {
  9328. BfExprEvaluator exprEvaluator(mModule);
  9329. exprEvaluator.mBfEvalExprFlags = BfEvalExprFlags_AllowParamsExpr;
  9330. auto argExpr = (*argValues.mArguments)[0];
  9331. if (argExpr != NULL)
  9332. exprEvaluator.Evaluate(argExpr);
  9333. if ((mModule->mCurMethodState != NULL) && (exprEvaluator.mResultLocalVar != NULL) && (exprEvaluator.mResultLocalVarRefNode != NULL))
  9334. {
  9335. auto localVar = exprEvaluator.mResultLocalVar;
  9336. auto checkType = localVar->mResolvedType;
  9337. if (checkType->IsParamsType())
  9338. checkType = checkType->GetUnderlyingType();
  9339. if ((localVar->mCompositeCount >= 0) && (checkType == fieldVal.mType))
  9340. {
  9341. delegateFailed = false;
  9342. if (mModule->mCurMethodInstance->mIsUnspecialized)
  9343. {
  9344. auto retTypeType = mModule->CreateModifiedTypeType(fieldVal.mType, BfToken_RetType);
  9345. return mModule->GetFakeTypedValue(retTypeType);
  9346. }
  9347. }
  9348. }
  9349. }
  9350. if (delegateFailed)
  9351. {
  9352. mModule->Fail(StrFormat("Generic delegates can only be invoked with 'params %s' composite parameters", mModule->TypeToString(fieldVal.mType).c_str()), targetSrc);
  9353. return BfTypedValue();
  9354. }
  9355. }
  9356. }
  9357. if (fieldVal.mType->IsTypeInstance())
  9358. {
  9359. prevBindResult.Restore();
  9360. auto fieldTypeInst = fieldVal.mType->ToTypeInstance();
  9361. MarkResultUsed();
  9362. if (mFunctionBindResult != NULL)
  9363. {
  9364. mFunctionBindResult->mOrigTarget = BfTypedValue();
  9365. }
  9366. return MatchMethod(targetSrc, NULL, fieldVal, false, false, "Invoke", argValues, methodGenericArgs, checkedKind);
  9367. }
  9368. if (IsVar(fieldVal.mType))
  9369. {
  9370. FinishDeferredEvals(argValues);
  9371. return BfTypedValue(mModule->GetDefaultValue(fieldVal.mType), fieldVal.mType);
  9372. }
  9373. if (fieldVal.mType->IsGenericParam())
  9374. {
  9375. auto genericParam = mModule->GetGenericParamInstance((BfGenericParamType*)fieldVal.mType);
  9376. BfType* typeConstraint = genericParam->mTypeConstraint;
  9377. if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsUnspecialized) && (mModule->mCurMethodInstance->mMethodInfoEx != NULL))
  9378. {
  9379. for (int genericParamIdx = (int)mModule->mCurMethodInstance->mMethodInfoEx->mMethodGenericArguments.size();
  9380. genericParamIdx < mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams.size(); genericParamIdx++)
  9381. {
  9382. auto genericParam = mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
  9383. if ((genericParam->mExternType == fieldVal.mType) && (genericParam->mTypeConstraint != NULL))
  9384. typeConstraint = genericParam->mTypeConstraint;
  9385. }
  9386. }
  9387. if ((typeConstraint != NULL) &&
  9388. ((typeConstraint->IsDelegate()) || (typeConstraint->IsFunction())))
  9389. {
  9390. BfMethodInstance* invokeMethodInstance = mModule->GetRawMethodInstanceAtIdx(typeConstraint->ToTypeInstance(), 0, "Invoke");
  9391. if (invokeMethodInstance == NULL)
  9392. {
  9393. mModule->InternalError("Get Invoke failed", targetSrc);
  9394. return BfTypedValue();
  9395. }
  9396. methodDef = invokeMethodInstance->mMethodDef;
  9397. methodMatcher.mBestMethodInstance = invokeMethodInstance;
  9398. methodMatcher.mBestMethodTypeInstance = invokeMethodInstance->GetOwner();
  9399. methodMatcher.mBestMethodDef = invokeMethodInstance->mMethodDef;
  9400. target = mModule->GetDefaultTypedValue(methodMatcher.mBestMethodTypeInstance);
  9401. isFailurePass = false;
  9402. isIndirectMethodCall = true;
  9403. }
  9404. }
  9405. else if (fieldVal.mType->IsMethodRef())
  9406. {
  9407. auto functionBindResults = prevBindResult.mPrevVal;
  9408. if (functionBindResults != NULL)
  9409. {
  9410. functionBindResults->mOrigTarget = fieldVal;
  9411. }
  9412. origTarget = fieldVal;
  9413. auto methodRefType = (BfMethodRefType*)fieldVal.mType;
  9414. BfMethodInstance* methodInstance = methodRefType->mMethodRef;
  9415. methodDef = methodInstance->mMethodDef;
  9416. if (methodDef->mIsLocalMethod)
  9417. {
  9418. methodMatcher.mBestMethodInstance = mModule->ReferenceExternalMethodInstance(methodInstance);
  9419. }
  9420. else
  9421. {
  9422. BfTypeVector methodGenericArguments;
  9423. if (methodInstance->mMethodInfoEx != NULL)
  9424. methodGenericArguments = methodInstance->mMethodInfoEx->mMethodGenericArguments;
  9425. methodMatcher.mBestMethodInstance = mModule->GetMethodInstance(methodInstance->GetOwner(), methodInstance->mMethodDef, methodGenericArguments);
  9426. }
  9427. if (methodInstance->mMethodInfoEx != NULL)
  9428. {
  9429. methodMatcher.mBestMethodGenericArguments = methodInstance->mMethodInfoEx->mMethodGenericArguments;
  9430. }
  9431. methodMatcher.mBestMethodTypeInstance = methodInstance->GetOwner();
  9432. if (methodInstance->HasThis())
  9433. {
  9434. bool failed = false;
  9435. target = DoImplicitArgCapture(targetSrc, methodInstance, -1, failed, BfImplicitParamKind_General, origTarget);
  9436. }
  9437. else if (!methodDef->mIsStatic)
  9438. {
  9439. auto thisType = methodInstance->GetParamType(-1);
  9440. BF_ASSERT(thisType->IsValuelessType());
  9441. target = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), methodMatcher.mBestMethodTypeInstance);
  9442. }
  9443. else
  9444. target = BfTypedValue(methodMatcher.mBestMethodTypeInstance);
  9445. methodMatcher.mBypassVirtual = true;
  9446. bypassVirtual = true;
  9447. isFailurePass = false;
  9448. isIndirectMethodCall = true;
  9449. }
  9450. if (methodDef == NULL)
  9451. {
  9452. mModule->Fail(StrFormat("Cannot perform invocation on type '%s'", mModule->TypeToString(fieldVal.mType).c_str()), targetSrc);
  9453. return BfTypedValue();
  9454. }
  9455. }
  9456. }
  9457. if (methodDef == NULL)
  9458. {
  9459. }
  9460. // This will flush out any new ambiguity errors from extension methods
  9461. methodMatcher.FlushAmbiguityError();
  9462. if (methodDef == NULL)
  9463. {
  9464. FinishDeferredEvals(argValues);
  9465. auto compiler = mModule->mCompiler;
  9466. if ((autoComplete != NULL) && (autoComplete->CheckFixit(targetSrc)))
  9467. {
  9468. mModule->CheckTypeRefFixit(targetSrc);
  9469. bool wantStatic = !target.mValue;
  9470. if ((targetType == NULL) && (allowImplicitThis))
  9471. {
  9472. targetType = mModule->mCurTypeInstance;
  9473. if (mModule->mCurMethodInstance != NULL)
  9474. wantStatic = mModule->mCurMethodInstance->mMethodDef->mIsStatic;
  9475. }
  9476. if (targetType != NULL)
  9477. {
  9478. auto typeInst = targetType->ToTypeInstance();
  9479. if ((typeInst != NULL) && (!methodName.IsEmpty()))
  9480. {
  9481. BfTypeVector paramTypes;
  9482. for (int argIdx = 0; argIdx < (int)argValues.mResolvedArgs.size(); argIdx++)
  9483. {
  9484. auto& resolvedArg = argValues.mResolvedArgs[argIdx];
  9485. paramTypes.Add(resolvedArg.mTypedValue.mType);
  9486. }
  9487. autoComplete->FixitAddMethod(typeInst, methodName, mExpectingType, paramTypes, wantStatic);
  9488. }
  9489. }
  9490. }
  9491. if (methodName.IsEmpty())
  9492. {
  9493. // Would have caused a parsing error
  9494. }
  9495. else if ((target.mType != NULL) && (origTarget.mType != NULL))
  9496. {
  9497. if (mModule->PreFail())
  9498. {
  9499. if ((origTarget.mType->IsPointer()) && (origTarget.mType->GetUnderlyingType()->IsObjectOrInterface()))
  9500. {
  9501. mModule->Fail(StrFormat("Methods cannot be called on type '%s' because the type is a pointer to a reference type (ie: a double-reference).",
  9502. mModule->TypeToString(origTarget.mType).c_str()), targetSrc);
  9503. }
  9504. else
  9505. mModule->Fail(StrFormat("Method '%s' does not exist in type '%s'", methodName.c_str(), mModule->TypeToString(target.mType).c_str()), targetSrc);
  9506. }
  9507. }
  9508. else
  9509. {
  9510. if (mModule->PreFail())
  9511. mModule->Fail(StrFormat("Method '%s' does not exist", methodName.c_str()), targetSrc);
  9512. }
  9513. return BfTypedValue();
  9514. }
  9515. if ((prevBindResult.mPrevVal != NULL) && (methodMatcher.mMethodCheckCount > 1))
  9516. prevBindResult.mPrevVal->mCheckedMultipleMethods = true;
  9517. BfType* overrideReturnType = NULL;
  9518. BfModuleMethodInstance moduleMethodInstance = GetSelectedMethod(targetSrc, curTypeInst, methodDef, methodMatcher, &overrideReturnType);
  9519. if ((mModule->mAttributeState != NULL) && ((mModule->mAttributeState->mFlags & (BfAttributeState::Flag_StopOnError | BfAttributeState::Flag_HadError)) ==
  9520. (BfAttributeState::Flag_StopOnError | BfAttributeState::Flag_HadError)))
  9521. {
  9522. FinishDeferredEvals(argValues);
  9523. return BfTypedValue();
  9524. }
  9525. if ((moduleMethodInstance.mMethodInstance != NULL) && (!mModule->CheckUseMethodInstance(moduleMethodInstance.mMethodInstance, targetSrc)))
  9526. {
  9527. FinishDeferredEvals(argValues);
  9528. return BfTypedValue();
  9529. }
  9530. if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsUnspecialized))
  9531. {
  9532. if (methodMatcher.mHasVarArguments)
  9533. {
  9534. BfType* retType = mModule->GetPrimitiveType(BfTypeCode_Var);
  9535. if ((!methodMatcher.mHadVarConflictingReturnType) && (methodMatcher.mBestRawMethodInstance != NULL) && (!methodMatcher.mBestRawMethodInstance->mReturnType->IsUnspecializedTypeVariation()) &&
  9536. (prevBindResult.mPrevVal == NULL))
  9537. {
  9538. if ((!methodMatcher.mBestRawMethodInstance->mReturnType->IsGenericParam()) ||
  9539. (((BfGenericParamType*)methodMatcher.mBestRawMethodInstance->mReturnType)->mGenericParamKind != BfGenericParamKind_Method))
  9540. retType = methodMatcher.mBestRawMethodInstance->mReturnType;
  9541. }
  9542. return mModule->GetDefaultTypedValue(retType, true, BfDefaultValueKind_Addr);
  9543. }
  9544. }
  9545. if ((bypassVirtual) && (!target.mValue) && (target.mType->IsInterface()))
  9546. {
  9547. target = mModule->GetThis();
  9548. }
  9549. if (!moduleMethodInstance)
  9550. {
  9551. FinishDeferredEvals(argValues);
  9552. if (mModule->IsInUnspecializedGeneric())
  9553. return mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Var));
  9554. return BfTypedValue();
  9555. }
  9556. bool isSkipCall = moduleMethodInstance.mMethodInstance->IsSkipCall(bypassVirtual);
  9557. if ((moduleMethodInstance.mMethodInstance->IsOrInUnspecializedVariation()) && (!mModule->mBfIRBuilder->mIgnoreWrites))
  9558. {
  9559. // Invalid methods such as types with a HasVar tuple generic arg will be marked as mIsUnspecializedVariation and shouldn't actually be called
  9560. FinishDeferredEvals(argValues);
  9561. return mModule->GetDefaultTypedValue(moduleMethodInstance.mMethodInstance->mReturnType, true, BfDefaultValueKind_Addr);
  9562. }
  9563. if (methodDef->IsEmptyPartial())
  9564. {
  9565. // Ignore call
  9566. return mModule->GetDefaultTypedValue(moduleMethodInstance.mMethodInstance->mReturnType, true, BfDefaultValueKind_Addr);
  9567. }
  9568. if ((moduleMethodInstance.mMethodInstance->mMethodDef->mIsStatic) && (moduleMethodInstance.mMethodInstance->GetOwner()->IsInterface()))
  9569. {
  9570. bool isConstrained = false;
  9571. if (target.mType != NULL)
  9572. isConstrained = target.mType->IsGenericParam();
  9573. if ((target.mType == NULL) && ((mModule->mCurMethodInstance->mIsForeignMethodDef) || (mModule->mCurTypeInstance->IsInterface())))
  9574. isConstrained = true;
  9575. // If mIgnoreWrites is off then we skip devirtualization, so allow this
  9576. if ((target.mType != NULL) && (!target.mType->IsInterface()) && (mModule->mBfIRBuilder->mIgnoreWrites))
  9577. isConstrained = true;
  9578. if (!isConstrained)
  9579. {
  9580. if (mModule->mCurTypeInstance->IsInterface())
  9581. {
  9582. if (methodDef->mBody == NULL)
  9583. mModule->Fail(StrFormat("Interface method '%s' must provide a body to be explicitly invoked", mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str()), targetSrc);
  9584. }
  9585. else
  9586. mModule->Fail(StrFormat("Static interface method '%s' can only be dispatched from a concrete type, consider using this interface as a generic constraint", mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str()), targetSrc);
  9587. FinishDeferredEvals(argValues);
  9588. return mModule->GetDefaultTypedValue(moduleMethodInstance.mMethodInstance->mReturnType, true, BfDefaultValueKind_Addr);
  9589. }
  9590. }
  9591. // 'base' could really mean 'this' if we're in an extension
  9592. if ((target.IsBase()) && (targetTypeInst == mModule->mCurTypeInstance))
  9593. target.ToThis();
  9594. else
  9595. MakeBaseConcrete(target);
  9596. BfType* callTargetType = curTypeInst;
  9597. if (methodDef->mMethodType == BfMethodType_Extension)
  9598. {
  9599. callTargetType = moduleMethodInstance.mMethodInstance->GetParamType(0);
  9600. if ((callTargetType->IsRef()) && (target.IsAddr()) && (!target.IsReadOnly()) && (target.mType->IsValueType()))
  9601. {
  9602. auto refType = (BfRefType*)callTargetType;
  9603. target = BfTypedValue(target.mValue, mModule->CreateRefType(target.mType, refType->mRefKind));
  9604. }
  9605. }
  9606. BfTypedValue callTarget;
  9607. if (isSkipCall)
  9608. {
  9609. // Just a fake value so we can continue on without generating any code (boxing, conversion, etc)
  9610. if (target)
  9611. {
  9612. if (((target.mType->IsComposite()) || (target.mType->IsTypedPrimitive())))
  9613. {
  9614. if ((moduleMethodInstance.mMethodInstance->mMethodDef->mIsMutating) &&
  9615. ((target.IsReadOnly()) || (!target.IsAddr())))
  9616. {
  9617. String err = StrFormat("call mutating method '%s' on", mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str());
  9618. CheckModifyResult(target, targetSrc, err.c_str());
  9619. }
  9620. }
  9621. callTarget = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), targetTypeInst);
  9622. }
  9623. }
  9624. else if (targetTypeInst == callTargetType)
  9625. {
  9626. if ((target) && (methodDef->HasNoThisSplat()))
  9627. {
  9628. callTarget = mModule->MakeAddressable(target);
  9629. }
  9630. else
  9631. callTarget = target;
  9632. if ((callTarget) && (moduleMethodInstance.mMethodInstance->GetOwner()->IsInterface()))
  9633. {
  9634. auto wantThis = moduleMethodInstance.mMethodInstance->GetParamType(-1);
  9635. if ((callTarget.mType != wantThis) && (wantThis->IsInterface()))
  9636. callTarget = mModule->Cast(targetSrc, callTarget, wantThis, BfCastFlags_Explicit);
  9637. }
  9638. }
  9639. else if (target)
  9640. {
  9641. if (methodMatcher.mFakeConcreteTarget)
  9642. {
  9643. BF_ASSERT(callTargetType->IsInterface());
  9644. callTarget = mModule->GetDefaultTypedValue(mModule->CreateConcreteInterfaceType(callTargetType->ToTypeInstance()));
  9645. }
  9646. else if (((target.mType->IsGenericParam()) || (target.mType->IsConcreteInterfaceType())) && (callTargetType->IsInterface()))
  9647. {
  9648. // Leave as generic
  9649. callTarget = target;
  9650. }
  9651. else
  9652. {
  9653. bool handled = false;
  9654. if ((target.mType->IsTypedPrimitive()) && (callTargetType->IsTypedPrimitive()))
  9655. {
  9656. handled = true;
  9657. callTarget = target;
  9658. }
  9659. else if ((target.mType->IsStructOrStructPtr()) || (target.mType->IsTypedPrimitive()))
  9660. {
  9661. //BF_ASSERT(target.IsAddr());
  9662. if (callTargetType->IsObjectOrInterface())
  9663. {
  9664. // Box it
  9665. callTarget = mModule->Cast(targetSrc, target, callTargetType, BfCastFlags_Explicit);
  9666. handled = true;
  9667. }
  9668. else
  9669. {
  9670. //BF_ASSERT(target.IsAddr() || target.IsSplat() || target.mType->IsPointer());
  9671. }
  9672. }
  9673. else
  9674. target = mModule->LoadValue(target);
  9675. if (!handled)
  9676. {
  9677. // Could we have just unconditionally done this?
  9678. callTarget = mModule->Cast(targetSrc, target, callTargetType, BfCastFlags_Explicit);
  9679. }
  9680. }
  9681. }
  9682. if (isFailurePass)
  9683. {
  9684. BfError* error;
  9685. if (methodMatcher.mMatchFailKind == BfMethodMatcher::MatchFailKind_CheckedMismatch)
  9686. error = mModule->Fail(StrFormat("'%s' cannot be used because its 'checked' specifier does not match the requested specifier", mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str()), targetSrc);
  9687. else
  9688. error = mModule->Fail(StrFormat("'%s' is inaccessible due to its protection level", mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str()), targetSrc);
  9689. if (error != NULL)
  9690. {
  9691. if ((error != NULL) && (moduleMethodInstance.mMethodInstance->mMethodDef->mMethodDeclaration != NULL))
  9692. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), moduleMethodInstance.mMethodInstance->mMethodDef->GetRefNode());
  9693. }
  9694. }
  9695. if ((mModule->mCompiler->mResolvePassData != NULL) && (methodDef != NULL))
  9696. {
  9697. auto identifierNode = BfNodeDynCast<BfIdentifierNode>(targetSrc);
  9698. while (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(identifierNode))
  9699. identifierNode = qualifiedNameNode->mRight;
  9700. if ((identifierNode != NULL) && (methodDef->mIdx >= 0) && (!isIndirectMethodCall) &&
  9701. ((targetTypeInst == NULL) || (!targetTypeInst->IsDelegateOrFunction())))
  9702. {
  9703. auto refMethodInstance = moduleMethodInstance.mMethodInstance;
  9704. if (refMethodInstance->mVirtualTableIdx != -1)
  9705. {
  9706. auto& virtualEntry = refMethodInstance->GetOwner()->mVirtualMethodTable[refMethodInstance->mVirtualTableIdx];
  9707. refMethodInstance = virtualEntry.mDeclaringMethod;
  9708. }
  9709. mModule->mCompiler->mResolvePassData->HandleMethodReference(identifierNode, refMethodInstance->GetOwner()->mTypeDef, refMethodInstance->mMethodDef);
  9710. auto autoComplete = GetAutoComplete();
  9711. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(identifierNode)))
  9712. {
  9713. autoComplete->SetDefinitionLocation(methodDef->GetRefNode(), true);
  9714. int virtualIdx = moduleMethodInstance.mMethodInstance->mVirtualTableIdx;
  9715. if ((autoComplete->mResolveType == BfResolveType_GoToDefinition) &&
  9716. (virtualIdx != -1) && (targetTypeInst != NULL) && (!targetTypeInst->IsStruct()) && (!targetTypeInst->IsTypedPrimitive()) && (!targetTypeInst->IsInterface()) &&
  9717. // VirtualMethodTable can be empty if the non-autocomplete classifier hasn't completed yet. Allow failure, a PopulateType here can't force the method table to fill out
  9718. (targetTypeInst->mVirtualMethodTable.size() != 0))
  9719. {
  9720. auto methodEntry = targetTypeInst->mVirtualMethodTable[virtualIdx];
  9721. if (methodEntry.mImplementingMethod.mMethodNum != -1)
  9722. {
  9723. BfMethodInstance* callingMethodInstance = methodEntry.mImplementingMethod;
  9724. if (callingMethodInstance != NULL)
  9725. {
  9726. auto callingMethodDef = callingMethodInstance->mMethodDef;
  9727. auto callingMethodDeclaration = callingMethodDef->GetMethodDeclaration();
  9728. if ((callingMethodDeclaration != NULL) && (callingMethodDeclaration->mNameNode != NULL))
  9729. autoComplete->SetDefinitionLocation(callingMethodDeclaration->mNameNode, true);
  9730. }
  9731. }
  9732. }
  9733. if (autoComplete->mDefType == NULL)
  9734. {
  9735. autoComplete->mDefMethod = refMethodInstance->mMethodDef;
  9736. autoComplete->mDefType = refMethodInstance->GetOwner()->mTypeDef;
  9737. }
  9738. if (autoComplete->mResolveType == BfResolveType_GetResultString)
  9739. {
  9740. autoComplete->mResultString = ":";
  9741. autoComplete->mResultString += mModule->MethodToString(moduleMethodInstance.mMethodInstance);
  9742. auto methodDecl = moduleMethodInstance.mMethodInstance->mMethodDef->GetMethodDeclaration();
  9743. if ((methodDecl != NULL) && (methodDecl->mDocumentation != NULL))
  9744. {
  9745. autoComplete->mResultString += "\x03";
  9746. methodDecl->mDocumentation->GetDocString(autoComplete->mResultString);
  9747. }
  9748. }
  9749. }
  9750. }
  9751. }
  9752. // This was causing forward-backward-forward steps when we just used 'targetSrc'. Using closeParen is undesirable because most of the time
  9753. // we DO just want it to just go to the targetSrc... do we even need this?
  9754. /*if (auto invokeExpr = BfNodeDynCast<BfInvocationExpression>(targetSrc->mParent))
  9755. {
  9756. // We set the srcPos to the close paren right before the call so we keep a forward progression of src positions in the case
  9757. // where some of the params are method calls and such
  9758. if (invokeExpr->mCloseParen != NULL)
  9759. mModule->UpdateExprSrcPos(invokeExpr->mCloseParen);
  9760. else
  9761. mModule->UpdateExprSrcPos(targetSrc);
  9762. }
  9763. else
  9764. mModule->UpdateExprSrcPos(targetSrc);*/
  9765. if (!mModule->mBfIRBuilder->mIgnoreWrites)
  9766. {
  9767. //BF_ASSERT(!callTarget.mValue.IsFake());
  9768. }
  9769. prevBindResult.Restore();
  9770. // Check mut
  9771. if ((callTarget.mType != NULL) &&
  9772. (callTarget.mType->IsGenericParam()) &&
  9773. ((!callTarget.IsAddr()) || (callTarget.IsReadOnly())) &&
  9774. (callTarget.mKind != BfTypedValueKind_MutableValue) &&
  9775. (moduleMethodInstance.mMethodInstance->mMethodDef->mIsMutating))
  9776. {
  9777. auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)callTarget.mType);
  9778. bool needsMut = true;
  9779. if ((genericParamInstance->mGenericParamFlags & (BfGenericParamFlag_StructPtr | BfGenericParamFlag_Class | BfGenericParamFlag_Var)) != 0)
  9780. needsMut = false;
  9781. if (genericParamInstance->mTypeConstraint != NULL)
  9782. {
  9783. auto typeConstaintTypeInstance = genericParamInstance->mTypeConstraint->ToTypeInstance();
  9784. if ((typeConstaintTypeInstance != NULL) && (!typeConstaintTypeInstance->IsComposite()))
  9785. needsMut = false;
  9786. }
  9787. if ((mFunctionBindResult != NULL) && (mFunctionBindResult->mSkipMutCheck))
  9788. needsMut = false;
  9789. if (needsMut)
  9790. {
  9791. String err = StrFormat("call mutating method '%s' on", mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str());
  9792. CheckModifyResult(callTarget, targetSrc, err.c_str(), true);
  9793. }
  9794. }
  9795. // Check mut on interface
  9796. if ((callTarget.mType != NULL) &&
  9797. (callTarget.mType->IsInterface()) &&
  9798. (target.IsThis()) &&
  9799. (mModule->mCurTypeInstance) &&
  9800. (!mModule->mCurMethodInstance->mMethodDef->mIsMutating) &&
  9801. (methodDef->mIsMutating))
  9802. {
  9803. mModule->Fail(StrFormat("Cannot call mutating method '%s' within default interface method '%s'. Consider adding 'mut' specifier to this method.",
  9804. mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str(), mModule->MethodToString(mModule->mCurMethodInstance).c_str()), targetSrc);
  9805. }
  9806. BfTypedValue result;
  9807. BfTypedValue argCascade;
  9808. BfCreateCallFlags subCallFlags = BfCreateCallFlags_None;
  9809. if (bypassVirtual)
  9810. subCallFlags = (BfCreateCallFlags)(subCallFlags | BfCreateCallFlags_BypassVirtual);
  9811. if (skipThis)
  9812. subCallFlags = (BfCreateCallFlags)(subCallFlags | BfCreateCallFlags_SkipThis);
  9813. result = CreateCall(targetSrc, callTarget, origTarget, methodDef, moduleMethodInstance, subCallFlags, argValues.mResolvedArgs, &argCascade);
  9814. if (overrideReturnType != NULL)
  9815. {
  9816. BF_ASSERT(moduleMethodInstance.mMethodInstance->mIsUnspecializedVariation);
  9817. result = mModule->GetDefaultTypedValue(overrideReturnType, false, BfDefaultValueKind_Addr);
  9818. }
  9819. if (result)
  9820. {
  9821. if (result.mType->IsRef())
  9822. result = mModule->RemoveRef(result);
  9823. }
  9824. PerformCallChecks(moduleMethodInstance.mMethodInstance, targetSrc);
  9825. if (result)
  9826. {
  9827. bool discardedReturnValue = mUsedAsStatement;
  9828. if (discardedReturnValue)
  9829. {
  9830. auto _ShowDiscardWaring = [&](const String& text, BfCustomAttributes* customAttributes, BfIRConstHolder* constHolder, BfAstNode* refNode)
  9831. {
  9832. if (customAttributes != NULL)
  9833. {
  9834. auto customAttribute = customAttributes->Get(mModule->mCompiler->mNoDiscardAttributeTypeDef);
  9835. if (!customAttribute->mCtorArgs.IsEmpty())
  9836. {
  9837. String* str = mModule->GetStringPoolString(customAttribute->mCtorArgs[0], constHolder);
  9838. if ((str != NULL) && (!str->IsEmpty()))
  9839. {
  9840. mModule->Warn(0, text + ": " + *str, targetSrc);
  9841. return;
  9842. }
  9843. }
  9844. }
  9845. mModule->Warn(0, text, targetSrc);
  9846. };
  9847. bool showedWarning = false;
  9848. if (moduleMethodInstance.mMethodInstance->mMethodDef->mIsNoDiscard)
  9849. {
  9850. _ShowDiscardWaring("Discarding return value of method with [NoDiscard] attribute", moduleMethodInstance.mMethodInstance->GetCustomAttributes(),
  9851. moduleMethodInstance.mMethodInstance->GetOwner()->mConstHolder, targetSrc);
  9852. showedWarning = true;
  9853. }
  9854. auto typeInst = result.mType->ToTypeInstance();
  9855. if (typeInst != NULL)
  9856. {
  9857. if ((typeInst->mTypeDef->mIsNoDiscard) && (!showedWarning))
  9858. {
  9859. _ShowDiscardWaring("Discarding return value whose type has [NoDiscard] attribute", typeInst->mCustomAttributes, typeInst->mConstHolder, targetSrc);
  9860. }
  9861. BfModuleMethodInstance moduleMethodInstance = mModule->GetMethodByName(typeInst, "ReturnValueDiscarded", 0, true);
  9862. if (moduleMethodInstance)
  9863. {
  9864. bool wasCapturingMethodMatchInfo = false;
  9865. if (autoComplete != NULL)
  9866. {
  9867. wasCapturingMethodMatchInfo = autoComplete->mIsCapturingMethodMatchInfo;
  9868. autoComplete->mIsCapturingMethodMatchInfo = false;
  9869. }
  9870. defer
  9871. (
  9872. if (autoComplete != NULL)
  9873. autoComplete->mIsCapturingMethodMatchInfo = wasCapturingMethodMatchInfo;
  9874. );
  9875. auto wasGetDefinition = (autoComplete != NULL) && (autoComplete->mIsGetDefinition);
  9876. if (wasGetDefinition)
  9877. autoComplete->mIsGetDefinition = false;
  9878. result = mModule->MakeAddressable(result);
  9879. BfResolvedArgs resolvedArgs;
  9880. MatchMethod(targetSrc, NULL, result, false, false, "ReturnValueDiscarded", resolvedArgs, BfMethodGenericArguments());
  9881. if (wasGetDefinition)
  9882. autoComplete->mIsGetDefinition = true;
  9883. }
  9884. }
  9885. }
  9886. }
  9887. if (argCascade)
  9888. {
  9889. if (argCascade.mType->IsRef())
  9890. argCascade = mModule->RemoveRef(argCascade);
  9891. result = argCascade;
  9892. }
  9893. if (result)
  9894. {
  9895. if ((result.mType->IsUnspecializedTypeVariation()) && (moduleMethodInstance.mMethodInstance->GetOwner()->IsInterface()))
  9896. {
  9897. BfType* selfType = NULL;
  9898. if (methodMatcher.mSelfType != NULL)
  9899. {
  9900. BF_ASSERT(mModule->IsInGeneric());
  9901. selfType = methodMatcher.mSelfType;
  9902. }
  9903. else
  9904. {
  9905. // Will be an error
  9906. selfType = methodMatcher.mBestMethodTypeInstance;
  9907. }
  9908. if ((selfType != NULL) && (!selfType->IsInterface()))
  9909. {
  9910. auto resolvedType = mModule->ResolveSelfType(result.mType, selfType);
  9911. if ((resolvedType != NULL) && (resolvedType != result.mType))
  9912. result = mModule->GetDefaultTypedValue(resolvedType);
  9913. }
  9914. }
  9915. }
  9916. return result;
  9917. }
  9918. void BfExprEvaluator::LookupQualifiedName(BfQualifiedNameNode* nameNode, bool ignoreInitialError, bool* hadError)
  9919. {
  9920. BfIdentifierNode* nameLeft = nameNode->mLeft;
  9921. BfIdentifierNode* nameRight = nameNode->mRight;
  9922. StringT<64> fieldName;
  9923. if (nameNode->mRight != NULL)
  9924. nameNode->mRight->ToString(fieldName);
  9925. bool wasBaseLookup = false;
  9926. if (auto qualifiedLeftName = BfNodeDynCast<BfQualifiedNameNode>(nameNode->mLeft))
  9927. {
  9928. if (CheckIsBase(qualifiedLeftName->mRight))
  9929. {
  9930. wasBaseLookup = true;
  9931. auto type = mModule->ResolveTypeRef(qualifiedLeftName->mLeft, NULL);
  9932. if (type == NULL)
  9933. return;
  9934. auto fieldName = nameNode->mRight->ToString();
  9935. auto target = mModule->GetThis();
  9936. target.mType = type;
  9937. mResult = LookupField(nameNode->mRight, target, fieldName);
  9938. if ((mPropDef != NULL) && (mPropDef->IsVirtual()))
  9939. mPropDefBypassVirtual = true;
  9940. return;
  9941. }
  9942. }
  9943. if (!wasBaseLookup)
  9944. mResult = LookupIdentifier(nameNode->mLeft, ignoreInitialError, hadError);
  9945. GetResult();
  9946. if (!mResult)
  9947. {
  9948. if (!ignoreInitialError)
  9949. mModule->Fail("Identifier not found", nameNode->mLeft);
  9950. return;
  9951. }
  9952. if (mResult.mType->IsObject())
  9953. {
  9954. mResult = mModule->LoadValue(mResult, 0, mIsVolatileReference);
  9955. }
  9956. else if ((mResult.mType->IsPointer()) && mResult.mType->IsStructOrStructPtr())
  9957. {
  9958. BfPointerType* structPtrType = (BfPointerType*)mResult.mType;
  9959. mResult = mModule->LoadValue(mResult, 0, mIsVolatileReference);
  9960. mResult.mType = structPtrType->mElementType;
  9961. if (mResult.mKind == BfTypedValueKind_ThisValue)
  9962. mResult.mKind = BfTypedValueKind_ThisAddr;
  9963. else
  9964. mResult.mKind = BfTypedValueKind_Addr;
  9965. }
  9966. else if (mResult.mType->IsAllocType())
  9967. {
  9968. BF_ASSERT(mResult.mValue.IsFake());
  9969. mResult.mType = mResult.mType->GetUnderlyingType();
  9970. }
  9971. mIsVolatileReference = false;
  9972. mIsHeapReference = false;
  9973. if (!mResult)
  9974. return;
  9975. auto origResult = mResult;
  9976. auto lookupType = BindGenericType(nameNode, mResult.mType);
  9977. if (IsVar(mResult.mType))
  9978. {
  9979. mResult = BfTypedValue(mModule->GetDefaultValue(mResult.mType), mResult.mType, true);
  9980. return;
  9981. }
  9982. if ((!mResult.mType->IsTypeInstance()) && (!mResult.mType->IsGenericParam()))
  9983. {
  9984. if (hadError != NULL)
  9985. *hadError = true;
  9986. mModule->Fail(StrFormat("Type '%s' has no fields", mModule->TypeToString(mResult.mType).c_str()), nameNode->mLeft);
  9987. mResult = BfTypedValue();
  9988. return;
  9989. }
  9990. BfTypedValue lookupVal = mResult;
  9991. mResult = LookupField(nameNode->mRight, lookupVal, fieldName);
  9992. if ((!mResult) && (mPropDef == NULL) && (lookupType->IsGenericParam()))
  9993. {
  9994. auto genericParamInst = mModule->GetGenericParamInstance((BfGenericParamType*)lookupType, true);
  9995. SizedArray<BfTypeInstance*, 8> searchConstraints;
  9996. for (auto ifaceConstraint : genericParamInst->mInterfaceConstraints)
  9997. {
  9998. if (!searchConstraints.Contains(ifaceConstraint))
  9999. {
  10000. searchConstraints.push_back(ifaceConstraint);
  10001. for (auto& innerIFaceEntry : ifaceConstraint->mInterfaces)
  10002. {
  10003. auto innerIFace = innerIFaceEntry.mInterfaceType;
  10004. if (!searchConstraints.Contains(innerIFace))
  10005. {
  10006. searchConstraints.push_back(innerIFace);
  10007. }
  10008. }
  10009. }
  10010. }
  10011. BfTypedValue prevTarget;
  10012. BfPropertyDef* prevDef = NULL;
  10013. for (auto ifaceConstraint : searchConstraints)
  10014. {
  10015. BfTypedValue lookupVal = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), ifaceConstraint);
  10016. mResult = LookupField(nameNode->mRight, lookupVal, fieldName);
  10017. if (mPropDef != NULL)
  10018. {
  10019. if (prevDef != NULL)
  10020. {
  10021. bool isBetter = mModule->TypeIsSubTypeOf(mPropTarget.mType->ToTypeInstance(), prevTarget.mType->ToTypeInstance());
  10022. bool isWorse = mModule->TypeIsSubTypeOf(prevTarget.mType->ToTypeInstance(), mPropTarget.mType->ToTypeInstance());
  10023. if ((isWorse) && (!isBetter))
  10024. continue;
  10025. if (isBetter == isWorse)
  10026. {
  10027. auto error = mModule->Fail("Ambiguous property reference", nameNode->mRight);
  10028. if (error != NULL)
  10029. {
  10030. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' has a candidate", mModule->TypeToString(prevTarget.mType).c_str()), prevDef->GetRefNode());
  10031. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' has a candidate", mModule->TypeToString(mPropTarget.mType).c_str()), mPropDef->GetRefNode());
  10032. }
  10033. }
  10034. }
  10035. prevDef = mPropDef;
  10036. prevTarget = mPropTarget;
  10037. }
  10038. }
  10039. /*if ((mResult) || (mPropDef != NULL))
  10040. break;*/
  10041. }
  10042. if (mPropDef != NULL)
  10043. {
  10044. mOrigPropTarget = origResult;
  10045. if (((CheckIsBase(nameNode->mLeft)) || (wasBaseLookup)) && (mPropDef->IsVirtual()))
  10046. mPropDefBypassVirtual = true;
  10047. }
  10048. if ((mResult) || (mPropDef != NULL))
  10049. return;
  10050. if (hadError != NULL)
  10051. *hadError = true;
  10052. BfTypeInstance* typeInst = lookupType->ToTypeInstance();
  10053. auto compiler = mModule->mCompiler;
  10054. if ((typeInst != NULL) && (compiler->IsAutocomplete()) && (compiler->mResolvePassData->mAutoComplete->CheckFixit(nameNode->mRight)))
  10055. {
  10056. FixitAddMember(typeInst, mExpectingType, nameNode->mRight->ToString(), false);
  10057. }
  10058. mModule->Fail(StrFormat("Unable to find member '%s' in '%s'", fieldName.c_str(), mModule->TypeToString(lookupType).c_str()), nameNode->mRight);
  10059. }
  10060. void BfExprEvaluator::LookupQualifiedName(BfAstNode* nameNode, BfIdentifierNode* nameLeft, BfIdentifierNode* nameRight, bool ignoreInitialError, bool* hadError)
  10061. {
  10062. String fieldName;
  10063. if (nameRight != NULL)
  10064. fieldName = nameRight->ToString();
  10065. bool wasBaseLookup = false;
  10066. if (auto qualifiedLeftName = BfNodeDynCast<BfQualifiedNameNode>(nameLeft))
  10067. {
  10068. if (CheckIsBase(qualifiedLeftName->mRight))
  10069. {
  10070. wasBaseLookup = true;
  10071. auto type = mModule->ResolveTypeRef(qualifiedLeftName->mLeft, NULL);
  10072. if (type == NULL)
  10073. return;
  10074. auto fieldName = nameRight->ToString();
  10075. auto target = mModule->GetThis();
  10076. target.mType = type;
  10077. mResult = LookupField(nameRight, target, fieldName);
  10078. if ((mPropDef != NULL) && (mPropDef->IsVirtual()))
  10079. mPropDefBypassVirtual = true;
  10080. return;
  10081. }
  10082. }
  10083. if (!wasBaseLookup)
  10084. {
  10085. mResult = LookupIdentifier(nameLeft, ignoreInitialError, hadError);
  10086. if ((mResult) && (!mResult.mType->IsComposite()))
  10087. CheckResultForReading(mResult);
  10088. }
  10089. GetResult();
  10090. if (!mResult)
  10091. {
  10092. if (!ignoreInitialError)
  10093. mModule->Fail("Identifier not found", nameLeft);
  10094. return;
  10095. }
  10096. if (mResult.mType->IsObject())
  10097. {
  10098. mResult = mModule->LoadValue(mResult, 0, mIsVolatileReference);
  10099. }
  10100. else if ((mResult.mType->IsPointer()) && mResult.mType->IsStructOrStructPtr())
  10101. {
  10102. BfPointerType* structPtrType = (BfPointerType*)mResult.mType;
  10103. mResult = mModule->LoadValue(mResult, 0, mIsVolatileReference);
  10104. mResult.mType = structPtrType->mElementType;
  10105. if (mResult.mKind == BfTypedValueKind_ThisValue)
  10106. mResult.mKind = BfTypedValueKind_ThisAddr;
  10107. else
  10108. mResult.mKind = BfTypedValueKind_Addr;
  10109. }
  10110. mIsVolatileReference = false;
  10111. mIsHeapReference = false;
  10112. if (!mResult)
  10113. return;
  10114. if (mResult.mType->IsAllocType())
  10115. mResult.mType = mResult.mType->GetUnderlyingType();
  10116. auto origResult = mResult;
  10117. if (IsVar(mResult.mType))
  10118. {
  10119. auto varType = mModule->GetPrimitiveType(BfTypeCode_Var);
  10120. mResult = BfTypedValue(mModule->GetDefaultValue(varType), varType, true);
  10121. return;
  10122. }
  10123. if ((!mResult.mType->IsTypeInstance()) && (!mResult.mType->IsGenericParam()))
  10124. {
  10125. if (mResult.mType->IsSizedArray())
  10126. {
  10127. if (mResult.mType->IsValuelessType())
  10128. {
  10129. mResult.mType = mModule->GetWrappedStructType(mResult.mType);
  10130. mResult.mValue = mModule->mBfIRBuilder->GetFakeVal();
  10131. }
  10132. else
  10133. {
  10134. mResult = mModule->MakeAddressable(mResult);
  10135. mResult.mType = mModule->GetWrappedStructType(mResult.mType);
  10136. mResult.mValue = mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->MapTypeInstPtr(mResult.mType->ToTypeInstance()));
  10137. }
  10138. }
  10139. else if (mResult.mType->IsWrappableType())
  10140. {
  10141. mResult.mType = mModule->GetWrappedStructType(mResult.mType);
  10142. }
  10143. else
  10144. {
  10145. if (hadError != NULL)
  10146. *hadError = true;
  10147. mModule->Fail(StrFormat("Type '%s' has no fields", mModule->TypeToString(mResult.mType).c_str()), nameLeft);
  10148. mResult = BfTypedValue();
  10149. return;
  10150. }
  10151. }
  10152. BfTypedValue lookupVal = mResult;
  10153. auto lookupType = BindGenericType(nameNode, mResult.mType);
  10154. if ((lookupType->IsGenericParam()) && (!mResult.mType->IsGenericParam()))
  10155. {
  10156. bool prevUseMixinGenerics = false;
  10157. if (mModule->mCurMethodState->mMixinState != NULL)
  10158. {
  10159. prevUseMixinGenerics = mModule->mCurMethodState->mMixinState->mUseMixinGenerics;
  10160. mModule->mCurMethodState->mMixinState->mUseMixinGenerics = true;
  10161. }
  10162. // Try to lookup from generic binding
  10163. mResult = LookupField(nameRight, BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), lookupType), fieldName, BfLookupFieldFlag_BindOnly);
  10164. if (mModule->mCurMethodState->mMixinState != NULL)
  10165. mModule->mCurMethodState->mMixinState->mUseMixinGenerics = prevUseMixinGenerics;
  10166. if (mPropDef != NULL)
  10167. {
  10168. mOrigPropTarget = lookupVal;
  10169. return;
  10170. }
  10171. }
  10172. if (mPropDef == NULL)
  10173. mResult = LookupField(nameRight, lookupVal, fieldName, CheckIsBase(nameLeft) ? BfLookupFieldFlag_BaseLookup : BfLookupFieldFlag_None);
  10174. if ((!mResult) && (mPropDef == NULL) && (lookupType->IsGenericParam()))
  10175. {
  10176. auto genericParamInst = mModule->GetGenericParamInstance((BfGenericParamType*)lookupType, true);
  10177. SizedArray<BfTypeInstance*, 8> searchConstraints;
  10178. for (auto ifaceConstraint : genericParamInst->mInterfaceConstraints)
  10179. {
  10180. if (!searchConstraints.Contains(ifaceConstraint))
  10181. {
  10182. searchConstraints.push_back(ifaceConstraint);
  10183. for (auto& innerIFaceEntry : ifaceConstraint->mInterfaces)
  10184. {
  10185. auto innerIFace = innerIFaceEntry.mInterfaceType;
  10186. if (!searchConstraints.Contains(innerIFace))
  10187. {
  10188. searchConstraints.push_back(innerIFace);
  10189. }
  10190. }
  10191. }
  10192. }
  10193. BfTypedValue prevTarget;
  10194. BfPropertyDef* prevDef = NULL;
  10195. for (auto ifaceConstraint : searchConstraints)
  10196. {
  10197. BfTypedValue lookupVal = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), ifaceConstraint);
  10198. mResult = LookupField(nameRight, lookupVal, fieldName);
  10199. if (mPropDef != NULL)
  10200. {
  10201. if (prevDef != NULL)
  10202. {
  10203. bool isBetter = mModule->TypeIsSubTypeOf(mPropTarget.mType->ToTypeInstance(), prevTarget.mType->ToTypeInstance());
  10204. bool isWorse = mModule->TypeIsSubTypeOf(prevTarget.mType->ToTypeInstance(), mPropTarget.mType->ToTypeInstance());
  10205. if ((isWorse) && (!isBetter))
  10206. continue;
  10207. if (isBetter == isWorse)
  10208. {
  10209. auto error = mModule->Fail("Ambiguous property reference", nameRight);
  10210. if (error != NULL)
  10211. {
  10212. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' has a candidate", mModule->TypeToString(prevTarget.mType).c_str()), prevDef->GetRefNode());
  10213. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' has a candidate", mModule->TypeToString(mPropTarget.mType).c_str()), mPropDef->GetRefNode());
  10214. }
  10215. }
  10216. }
  10217. prevDef = mPropDef;
  10218. prevTarget = mPropTarget;
  10219. }
  10220. }
  10221. if ((mPropDef == NULL) && (genericParamInst->IsEnum()))
  10222. {
  10223. if ((fieldName == "Underlying") || (fieldName == "UnderlyingRef"))
  10224. {
  10225. mResult = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Var));
  10226. return;
  10227. }
  10228. }
  10229. }
  10230. if (mPropDef != NULL)
  10231. {
  10232. mOrigPropTarget = origResult;
  10233. if ((CheckIsBase(nameLeft)) || (wasBaseLookup))
  10234. {
  10235. if (mPropDef->IsVirtual())
  10236. mPropDefBypassVirtual = true;
  10237. }
  10238. }
  10239. if ((mResult) || (mPropDef != NULL))
  10240. return;
  10241. if (hadError != NULL)
  10242. *hadError = true;
  10243. BfTypeInstance* typeInst = lookupType->ToTypeInstance();
  10244. auto compiler = mModule->mCompiler;
  10245. if ((typeInst != NULL) && (compiler->IsAutocomplete()) && (compiler->mResolvePassData->mAutoComplete->CheckFixit(nameRight)))
  10246. {
  10247. FixitAddMember(typeInst, mExpectingType, nameRight->ToString(), false);
  10248. }
  10249. if (((mBfEvalExprFlags & BfEvalExprFlags_NameOf) != 0) && (typeInst != NULL) && (CheckForMethodName(nameRight, typeInst, fieldName)))
  10250. return;
  10251. mModule->Fail(StrFormat("Unable to find member '%s' in '%s'", fieldName.c_str(), mModule->TypeToString(lookupType).c_str()), nameRight);
  10252. }
  10253. void BfExprEvaluator::LookupQualifiedStaticField(BfQualifiedNameNode* nameNode, bool ignoreIdentifierNotFoundError)
  10254. {
  10255. // Lookup left side as a type
  10256. {
  10257. BfType* type = NULL;
  10258. {
  10259. type = mModule->ResolveTypeRef(nameNode->mLeft, NULL, BfPopulateType_Data, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_AllowRef | BfResolveTypeRefFlag_IgnoreLookupError));
  10260. mModule->CheckTypeRefFixit(nameNode->mLeft);
  10261. }
  10262. if (type != NULL)
  10263. {
  10264. BfTypedValue lookupType;
  10265. if (type->IsWrappableType())
  10266. lookupType = BfTypedValue(mModule->GetWrappedStructType(type));
  10267. else
  10268. lookupType = BfTypedValue(type);
  10269. auto findName = nameNode->mRight->ToString();
  10270. /*if (findName == "base")
  10271. {
  10272. mResult = BfTypedValue(lookupType);
  10273. return;
  10274. }*/
  10275. mResult = LookupField(nameNode->mRight, lookupType, findName);
  10276. if ((mResult) || (mPropDef != NULL))
  10277. return;
  10278. if (lookupType.mType != NULL)
  10279. {
  10280. BfTypeInstance* typeInst = lookupType.mType->ToTypeInstance();
  10281. auto compiler = mModule->mCompiler;
  10282. if ((typeInst != NULL) && (compiler->IsAutocomplete()) && (compiler->mResolvePassData->mAutoComplete->CheckFixit(nameNode->mRight)))
  10283. {
  10284. FixitAddMember(typeInst, mExpectingType, nameNode->mRight->ToString(), true);
  10285. }
  10286. }
  10287. if ((mBfEvalExprFlags & BfEvalExprFlags_NoLookupError) == 0)
  10288. mModule->Fail("Field not found", nameNode->mRight);
  10289. return;
  10290. }
  10291. }
  10292. String fieldName = nameNode->mRight->ToString();
  10293. if (auto qualifiedLeftName = BfNodeDynCast<BfQualifiedNameNode>(nameNode->mLeft))
  10294. LookupQualifiedStaticField(qualifiedLeftName, true);
  10295. else if (auto leftName = BfNodeDynCast<BfIdentifierNode>(nameNode->mLeft))
  10296. {
  10297. mResult = LookupIdentifier(leftName);
  10298. }
  10299. GetResult();
  10300. if (!mResult)
  10301. {
  10302. if (!ignoreIdentifierNotFoundError)
  10303. mModule->Fail("Identifier not found", nameNode->mLeft);
  10304. return;
  10305. }
  10306. if (mResult.mType->IsObject())
  10307. {
  10308. mResult = mModule->LoadValue(mResult);
  10309. }
  10310. else if ((mResult.mType->IsPointer()) && mResult.mType->IsStructOrStructPtr())
  10311. {
  10312. BfPointerType* structPtrType = (BfPointerType*) mResult.mType;
  10313. mResult = mModule->LoadValue(mResult);
  10314. mResult.mType = structPtrType->mElementType;
  10315. }
  10316. if (!mResult)
  10317. return;
  10318. if (!mResult.mType->IsTypeInstance())
  10319. {
  10320. mModule->Fail(StrFormat("Type '%s' has no fields", mModule->TypeToString(mResult.mType).c_str()), nameNode->mLeft);
  10321. return;
  10322. }
  10323. auto leftResult = mResult;
  10324. mResult = LookupField(nameNode->mRight, leftResult, fieldName);
  10325. if ((mResult) || (mPropDef != NULL))
  10326. return;
  10327. mModule->Fail(StrFormat("Unable to find member '%s' in '%s'", fieldName.c_str(), mModule->TypeToString(leftResult.mType).c_str()), nameNode->mRight);
  10328. }
  10329. void BfExprEvaluator::LookupQualifiedStaticField(BfAstNode* nameNode, BfIdentifierNode* nameLeft, BfIdentifierNode* nameRight, bool ignoreIdentifierNotFoundError)
  10330. {
  10331. // Lookup left side as a type
  10332. {
  10333. BfType* type = mModule->ResolveTypeRef(nameLeft, NULL, BfPopulateType_Declaration, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_IgnoreLookupError | BfResolveTypeRefFlag_AllowGlobalContainer));
  10334. if ((type != NULL) && (type->IsVar()) && (nameLeft->Equals("var")))
  10335. type = NULL;
  10336. if (type != NULL)
  10337. {
  10338. BfTypedValue lookupType;
  10339. if (type->IsWrappableType())
  10340. lookupType = BfTypedValue(mModule->GetWrappedStructType(type));
  10341. else
  10342. lookupType = BfTypedValue(type);
  10343. auto findName = nameRight->ToString();
  10344. if ((lookupType.mType != NULL) && (lookupType.mType->IsGenericParam()))
  10345. {
  10346. auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)lookupType.mType);
  10347. if (genericParamInstance->mTypeConstraint != NULL)
  10348. {
  10349. mResult = LookupField(nameRight, BfTypedValue(genericParamInstance->mTypeConstraint), findName);
  10350. if ((mResult) || (mPropDef != NULL))
  10351. {
  10352. mOrigPropTarget = lookupType;
  10353. return;
  10354. }
  10355. }
  10356. for (auto constraint : genericParamInstance->mInterfaceConstraints)
  10357. {
  10358. mResult = LookupField(nameRight, BfTypedValue(constraint), findName);
  10359. if ((mResult) || (mPropDef != NULL))
  10360. {
  10361. mOrigPropTarget = lookupType;
  10362. return;
  10363. }
  10364. }
  10365. }
  10366. /*if (findName == "base")
  10367. {
  10368. mResult = BfTypedValue(lookupType);
  10369. return;
  10370. }*/
  10371. mResult = LookupField(nameRight, lookupType, findName);
  10372. if ((mResult) || (mPropDef != NULL))
  10373. return;
  10374. if (lookupType.mType != NULL)
  10375. {
  10376. BfTypeInstance* typeInst = lookupType.mType->ToTypeInstance();
  10377. auto compiler = mModule->mCompiler;
  10378. if ((typeInst != NULL) && (compiler->IsAutocomplete()) && (compiler->mResolvePassData->mAutoComplete->CheckFixit(nameRight)))
  10379. {
  10380. FixitAddMember(typeInst, mExpectingType, nameRight->ToString(), true);
  10381. }
  10382. }
  10383. if ((mBfEvalExprFlags & BfEvalExprFlags_NameOf) != 0)
  10384. {
  10385. auto typeInst = lookupType.mType->ToTypeInstance();
  10386. if ((typeInst != NULL) && (CheckForMethodName(nameRight, typeInst, findName)))
  10387. return;
  10388. }
  10389. if ((mBfEvalExprFlags & BfEvalExprFlags_NoLookupError) == 0)
  10390. mModule->Fail("Field not found", nameRight);
  10391. return;
  10392. }
  10393. }
  10394. String fieldName = nameRight->ToString();
  10395. if (auto qualifiedLeftName = BfNodeDynCast<BfQualifiedNameNode>(nameLeft))
  10396. LookupQualifiedStaticField(qualifiedLeftName, qualifiedLeftName->mLeft, qualifiedLeftName->mRight, true);
  10397. else if (auto leftName = BfNodeDynCast<BfIdentifierNode>(nameLeft))
  10398. {
  10399. mResult = LookupIdentifier(leftName);
  10400. }
  10401. GetResult();
  10402. if (!mResult)
  10403. {
  10404. if (!ignoreIdentifierNotFoundError)
  10405. mModule->Fail("Identifier not found", nameLeft);
  10406. return;
  10407. }
  10408. if (mResult.mType->IsObject())
  10409. {
  10410. mResult = mModule->LoadValue(mResult);
  10411. }
  10412. else if ((mResult.mType->IsPointer()) && mResult.mType->IsStructOrStructPtr())
  10413. {
  10414. BfPointerType* structPtrType = (BfPointerType*)mResult.mType;
  10415. mResult = mModule->LoadValue(mResult);
  10416. mResult = BfTypedValue(mResult.mValue, structPtrType->mElementType, true);
  10417. }
  10418. if (!mResult)
  10419. return;
  10420. if (!mResult.mType->IsTypeInstance())
  10421. {
  10422. if (mResult.mType->IsSizedArray())
  10423. {
  10424. mResult.mType = mModule->GetWrappedStructType(mResult.mType);
  10425. mResult.mValue = mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->MapTypeInstPtr(mResult.mType->ToTypeInstance()));
  10426. }
  10427. else if (mResult.mType->IsWrappableType())
  10428. {
  10429. mResult.mType = mModule->GetWrappedStructType(mResult.mType);
  10430. }
  10431. else
  10432. {
  10433. mModule->Fail(StrFormat("Type '%s' has no fields", mModule->TypeToString(mResult.mType).c_str()), nameLeft);
  10434. return;
  10435. }
  10436. }
  10437. auto leftResult = mResult;
  10438. mResult = LookupField(nameRight, leftResult, fieldName);
  10439. if ((mResult) || (mPropDef != NULL))
  10440. return;
  10441. mModule->CheckTypeRefFixit(nameLeft);
  10442. mModule->Fail(StrFormat("Unable to find member '%s' in '%s'", fieldName.c_str(), mModule->TypeToString(leftResult.mType).c_str()), nameRight);
  10443. }
  10444. void BfExprEvaluator::Visit(BfQualifiedNameNode* nameNode)
  10445. {
  10446. auto autoComplete = GetAutoComplete();
  10447. if (autoComplete != NULL)
  10448. {
  10449. autoComplete->CheckMemberReference(nameNode->mLeft, nameNode->mDot, nameNode->mRight);
  10450. }
  10451. bool hadError = false;
  10452. LookupQualifiedName(nameNode, nameNode->mLeft, nameNode->mRight, true, &hadError);
  10453. if ((mResult) || (mPropDef != NULL))
  10454. return;
  10455. if (hadError)
  10456. return;
  10457. LookupQualifiedStaticField(nameNode, nameNode->mLeft, nameNode->mRight, false);
  10458. }
  10459. void BfExprEvaluator::Visit(BfThisExpression* thisExpr)
  10460. {
  10461. mResult = mModule->GetThis();
  10462. if (!mResult)
  10463. {
  10464. mModule->Fail("Static methods don't have 'this'", thisExpr);
  10465. return;
  10466. }
  10467. auto autoComplete = GetAutoComplete();
  10468. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(thisExpr)))
  10469. autoComplete->SetDefinitionLocation(mModule->mCurTypeInstance->mTypeDef->GetRefNode());
  10470. mResultLocalVar = mModule->GetThisVariable();
  10471. mResultFieldInstance = NULL;
  10472. }
  10473. void BfExprEvaluator::Visit(BfBaseExpression* baseExpr)
  10474. {
  10475. mResult = mModule->GetThis();
  10476. if (!mResult)
  10477. {
  10478. mModule->Fail("Static methods don't have 'base'", baseExpr);
  10479. return;
  10480. }
  10481. if ((mBfEvalExprFlags & BfEvalExprFlags_AllowBase) == 0)
  10482. mModule->Fail("Use of keyword 'base' is not valid in this context", baseExpr);
  10483. auto baseType = mModule->mCurTypeInstance->mBaseType;
  10484. if (baseType == NULL)
  10485. baseType = mModule->mContext->mBfObjectType;
  10486. auto autoComplete = GetAutoComplete();
  10487. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(baseExpr)))
  10488. autoComplete->SetDefinitionLocation(baseType->mTypeDef->GetRefNode());
  10489. mModule->PopulateType(baseType, BfPopulateType_Data);
  10490. mResult = mModule->Cast(baseExpr, mResult, baseType, BfCastFlags_Explicit);
  10491. if (mResult.IsSplat())
  10492. mResult.mKind = BfTypedValueKind_BaseSplatHead;
  10493. else if (mResult.IsAddr())
  10494. mResult.mKind = BfTypedValueKind_BaseAddr;
  10495. else if (mResult)
  10496. mResult.mKind = BfTypedValueKind_BaseValue;
  10497. }
  10498. void BfExprEvaluator::Visit(BfMixinExpression* mixinExpr)
  10499. {
  10500. if (mModule->mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_Mixin)
  10501. {
  10502. auto varType = mModule->GetPrimitiveType(BfTypeCode_Var);
  10503. auto newVar = mModule->AllocFromType(varType, mModule->mCurMethodState->mCurScope);
  10504. mResult = BfTypedValue(newVar, varType, true);
  10505. return;
  10506. }
  10507. auto curMethodState = mModule->mCurMethodState;
  10508. if (curMethodState->mMixinState == NULL)
  10509. {
  10510. mModule->Fail("Mixin references can only be used within mixins", mixinExpr);
  10511. return;
  10512. }
  10513. int localIdx = GetMixinVariable();
  10514. if (localIdx != -1)
  10515. {
  10516. auto varDecl = curMethodState->mLocals[localIdx];
  10517. if (varDecl != NULL)
  10518. {
  10519. BfTypedValue localResult = LoadLocal(varDecl);
  10520. mResult = localResult;
  10521. mResultLocalVar = varDecl;
  10522. mResultFieldInstance = NULL;
  10523. mResultLocalVarRefNode = mixinExpr;
  10524. return;
  10525. }
  10526. }
  10527. if (mModule->mCurMethodInstance->mIsUnspecialized)
  10528. {
  10529. mResult = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Var));
  10530. return;
  10531. }
  10532. mModule->Fail("Mixin value cannot be inferred", mixinExpr);
  10533. }
  10534. void BfExprEvaluator::Visit(BfSizedArrayCreateExpression* createExpr)
  10535. {
  10536. auto type = mModule->ResolveTypeRef(createExpr->mTypeRef, NULL, BfPopulateType_Data, BfResolveTypeRefFlag_AllowInferredSizedArray);
  10537. if (type == NULL)
  10538. return;
  10539. if (type->IsArray())
  10540. {
  10541. // If we have a case like 'int[] (1, 2)' then we infer the sized array size from the initializer
  10542. auto arrayType = (BfArrayType*)type;
  10543. if (arrayType->mDimensions == 1)
  10544. {
  10545. int arraySize = 0;
  10546. if (auto arrayInitExpr = BfNodeDynCast<BfCollectionInitializerExpression>(createExpr->mInitializer))
  10547. {
  10548. arraySize = (int)arrayInitExpr->mValues.size();
  10549. }
  10550. type = mModule->CreateSizedArrayType(arrayType->GetUnderlyingType(), arraySize);
  10551. }
  10552. }
  10553. if (!type->IsSizedArray())
  10554. {
  10555. mModule->Fail("Sized array expected", createExpr->mTypeRef);
  10556. return;
  10557. }
  10558. if (type->IsUndefSizedArray())
  10559. {
  10560. int arraySize = 0;
  10561. if (createExpr->mInitializer != NULL)
  10562. arraySize = (int)createExpr->mInitializer->mValues.size();
  10563. type = mModule->CreateSizedArrayType(type->GetUnderlyingType(), arraySize);
  10564. }
  10565. BfSizedArrayType* arrayType = (BfSizedArrayType*)type;
  10566. if (createExpr->mInitializer == NULL)
  10567. {
  10568. mModule->AssertErrorState();
  10569. mResult = mModule->GetDefaultTypedValue(arrayType);
  10570. return;
  10571. }
  10572. InitializedSizedArray(arrayType, createExpr->mInitializer->mOpenBrace, createExpr->mInitializer->mValues, createExpr->mInitializer->mCommas, createExpr->mInitializer->mCloseBrace);
  10573. }
  10574. void BfExprEvaluator::Visit(BfInitializerExpression* initExpr)
  10575. {
  10576. uint64 unassignedFieldFlags = 0;
  10577. if (auto typeRef = BfNodeDynCast<BfTypeReference>(initExpr->mTarget))
  10578. {
  10579. BfType* type = NULL;
  10580. if (auto typeRef = BfNodeDynCast<BfDotTypeReference>(initExpr->mTarget))
  10581. {
  10582. type = mExpectingType;
  10583. }
  10584. if (type == NULL)
  10585. type = mModule->ResolveTypeRef(typeRef);
  10586. if (type != NULL)
  10587. {
  10588. if (type->IsValueType())
  10589. {
  10590. if ((mReceivingValue != NULL) && (mReceivingValue->mType == type) && (mReceivingValue->IsAddr()))
  10591. {
  10592. mResult = *mReceivingValue;
  10593. mReceivingValue = NULL;
  10594. }
  10595. else
  10596. {
  10597. mResult = BfTypedValue(mModule->CreateAlloca(type), type, true);
  10598. }
  10599. auto typeInstance = type->ToTypeInstance();
  10600. if (typeInstance != NULL)
  10601. unassignedFieldFlags = (1 << typeInstance->mMergedFieldDataCount) - 1;
  10602. }
  10603. else
  10604. {
  10605. mModule->Fail("Initializer expressions can only be used on value types or allocated values", initExpr->mTarget);
  10606. }
  10607. }
  10608. }
  10609. else if (auto objCreateExpr = BfNodeDynCast<BfObjectCreateExpression>(initExpr->mTarget))
  10610. {
  10611. CreateObject(objCreateExpr, objCreateExpr->mNewNode, NULL, initExpr->mInlineTypeRef);
  10612. }
  10613. else
  10614. VisitChild(initExpr->mTarget);
  10615. if (!mResult)
  10616. mResult = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  10617. BfIRBlock initBlock = BfIRBlock();
  10618. if (unassignedFieldFlags != 0)
  10619. {
  10620. initBlock = mModule->mBfIRBuilder->CreateBlock("initStart", true);
  10621. mModule->mBfIRBuilder->CreateBr(initBlock);
  10622. mModule->mBfIRBuilder->SetInsertPoint(initBlock);
  10623. }
  10624. BfTypedValue origInitValue = GetResult(true);
  10625. BfTypedValue initValue = origInitValue;
  10626. if ((initValue) && (initValue.mType->IsRef()))
  10627. initValue = mModule->RemoveRef(initValue, false);
  10628. bool isFirstAdd = true;
  10629. SetAndRestoreValue<BfTypeInstance*> prevPrivateTypeInstance(mModule->mCurMethodState->mPrivateTypeInstance);
  10630. BfScopeData newScope;
  10631. if (initExpr->mInlineTypeRef != NULL)
  10632. mModule->mCurMethodState->mPrivateTypeInstance = initValue.mType->ToTypeInstance();
  10633. newScope.mAllowTargeting = false;
  10634. newScope.mInnerIsConditional = true;
  10635. newScope.mCloseNode = initExpr->mCloseBrace;
  10636. mModule->mCurMethodState->AddScope(&newScope);
  10637. mModule->NewScopeState();
  10638. BfLocalVariable* localDef = new BfLocalVariable();
  10639. localDef->mName = "_";
  10640. localDef->mResolvedType = initValue.mType;
  10641. localDef->mAssignedKind = BfLocalVarAssignKind_Unconditional;
  10642. if (initValue.IsAddr())
  10643. {
  10644. localDef->mAddr = initValue.mValue;
  10645. }
  10646. else
  10647. {
  10648. localDef->mValue = initValue.mValue;
  10649. localDef->mIsSplat = initValue.IsSplat();
  10650. }
  10651. if (!localDef->mResolvedType->IsVar())
  10652. mModule->AddLocalVariableDef(localDef, true, true);
  10653. auto autoComplete = mModule->mCompiler->GetAutoComplete();
  10654. for (auto elementExpr : initExpr->mValues)
  10655. {
  10656. if ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0)
  10657. {
  10658. mModule->Fail("Comptime cannot evaluate initializer expressions", elementExpr);
  10659. break;
  10660. }
  10661. bool wasValidInitKind = false;
  10662. if (auto assignExpr = BfNodeDynCast<BfAssignmentExpression>(elementExpr))
  10663. {
  10664. BfTypedValue fieldResult;
  10665. if (auto identifierNode = BfNodeDynCast<BfIdentifierNode>(assignExpr->mLeft))
  10666. {
  10667. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(identifierNode)))
  10668. {
  10669. auto type = initValue.mType;
  10670. if (type->IsPointer())
  10671. type = type->GetUnderlyingType();
  10672. if (auto typeInst = type->ToTypeInstance())
  10673. {
  10674. autoComplete->mInsertStartIdx = identifierNode->GetSrcStart();
  10675. autoComplete->mInsertEndIdx = identifierNode->GetSrcEnd();
  10676. autoComplete->AddTypeMembers(typeInst, false, true, identifierNode->ToString(), typeInst, false, true, false);
  10677. }
  10678. }
  10679. StringT<128> findName;
  10680. identifierNode->ToString(findName);
  10681. mResultFieldInstance = NULL;
  10682. fieldResult = LookupField(identifierNode, initValue, findName, BfLookupFieldFlag_IsImplicitThis);
  10683. if ((fieldResult.mKind == BfTypedValueKind_TempAddr) || (fieldResult.mKind == BfTypedValueKind_RestrictedTempAddr))
  10684. fieldResult.mKind = BfTypedValueKind_Addr;
  10685. if ((mResultFieldInstance != NULL) && (mResultFieldInstance->mMergedDataIdx != -1))
  10686. {
  10687. int resultLocalVarField = 0;
  10688. int resultLocalVarFieldCount = 0;
  10689. mResultFieldInstance->GetDataRange(resultLocalVarField, resultLocalVarFieldCount);
  10690. for (int i = 0; i < resultLocalVarFieldCount; i++)
  10691. unassignedFieldFlags &= ~((int64)1 << (resultLocalVarField - 1 + i));
  10692. }
  10693. wasValidInitKind = true;
  10694. if ((fieldResult) || (mPropDef != NULL))
  10695. {
  10696. if (mResultFieldInstance != NULL)
  10697. {
  10698. auto autoComplete = GetAutoComplete();
  10699. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(identifierNode)))
  10700. {
  10701. auto fieldDef = mResultFieldInstance->GetFieldDef();
  10702. if (fieldDef != NULL)
  10703. autoComplete->SetDefinitionLocation(fieldDef->GetRefNode());
  10704. }
  10705. }
  10706. mResult = fieldResult;
  10707. PerformAssignment(assignExpr, true, BfTypedValue());
  10708. mResult = BfTypedValue();
  10709. }
  10710. else
  10711. {
  10712. mModule->Fail(StrFormat("'%s' does not contain a definition for '%s'", mModule->TypeToString(initValue.mType).c_str(),
  10713. findName.c_str()), identifierNode);
  10714. }
  10715. }
  10716. else if (auto indexerExpression = BfNodeDynCast<BfIndexerExpression>(assignExpr->mLeft))
  10717. {
  10718. if (indexerExpression->mTarget == NULL)
  10719. {
  10720. if ((initValue.mType->IsValueType()) && (!initValue.IsAddr()))
  10721. {
  10722. initValue = mModule->MakeAddressable(initValue, true, true);
  10723. }
  10724. mResult = BfTypedValue();
  10725. HandleIndexerExpression(indexerExpression, initValue);
  10726. wasValidInitKind = true;
  10727. if ((mPropDef) || (mResult))
  10728. {
  10729. PerformAssignment(assignExpr, true, BfTypedValue());
  10730. mResult = BfTypedValue();
  10731. }
  10732. }
  10733. }
  10734. }
  10735. else
  10736. {
  10737. BfBlock* block = BfNodeDynCast<BfBlock>(elementExpr);
  10738. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(elementExpr)))
  10739. {
  10740. if (auto identiferNode = BfNodeDynCast<BfIdentifierNode>(elementExpr))
  10741. {
  10742. auto type = initValue.mType;
  10743. if (type->IsPointer())
  10744. type = type->GetUnderlyingType();
  10745. if (auto typeInst = type->ToTypeInstance())
  10746. {
  10747. String filter;
  10748. identiferNode->ToString(filter);
  10749. autoComplete->AddTypeMembers(typeInst, false, true, filter, typeInst, false, true, false);
  10750. }
  10751. }
  10752. }
  10753. if ((block != NULL) && (!block->IsExpression()))
  10754. {
  10755. mModule->VisitCodeBlock(block);
  10756. }
  10757. else
  10758. {
  10759. BfExprEvaluator exprEvaluator(mModule);
  10760. SizedArray<BfExpression*, 2> argExprs;
  10761. argExprs.push_back(elementExpr);
  10762. BfSizedArray<BfExpression*> sizedArgExprs(argExprs);
  10763. BfResolvedArgs argValues(&sizedArgExprs);
  10764. exprEvaluator.ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval);
  10765. exprEvaluator.MatchMethod(elementExpr, NULL, initValue, false, false, "Add", argValues, BfMethodGenericArguments());
  10766. }
  10767. wasValidInitKind = true;
  10768. }
  10769. if (!wasValidInitKind)
  10770. {
  10771. mModule->Fail("Invalid initializer member declarator", initExpr);
  10772. }
  10773. }
  10774. mModule->RestoreScopeState();
  10775. if (initExpr->mValues.IsEmpty())
  10776. {
  10777. // When we are first typing out 'override', we
  10778. if (initExpr->mInlineTypeRef != NULL)
  10779. {
  10780. if (auto defineBlock = BfNodeDynCast<BfBlock>(initExpr->mInlineTypeRef->mTypeDeclaration->mDefineNode))
  10781. {
  10782. if (defineBlock->mChildArr.mSize == 1)
  10783. {
  10784. auto lastNode = defineBlock->mChildArr[0];
  10785. if (lastNode->Equals("override"))
  10786. {
  10787. auto autoComplete = mModule->mCompiler->GetAutoComplete();
  10788. if (autoComplete != NULL)
  10789. {
  10790. int cursorIdx = autoComplete->GetCursorIdx(lastNode);
  10791. if ((autoComplete->IsAutocompleteNode(lastNode, 1)) && (cursorIdx == lastNode->GetSrcEnd()))
  10792. {
  10793. auto typeInst = initValue.mType->ToTypeInstance();
  10794. if (typeInst != NULL)
  10795. {
  10796. SetAndRestoreValue<BfTypeInstance*> prevTypeInst(mModule->mCurTypeInstance, typeInst);
  10797. SetAndRestoreValue<BfMethodInstance*> prevMethodInst(mModule->mCurMethodInstance, NULL);
  10798. autoComplete->AddOverrides("", true);
  10799. autoComplete->mInsertStartIdx = lastNode->mSrcStart;
  10800. autoComplete->mInsertEndIdx = lastNode->mSrcEnd;
  10801. }
  10802. }
  10803. }
  10804. }
  10805. }
  10806. }
  10807. }
  10808. }
  10809. else
  10810. {
  10811. auto lastNode = initExpr->mValues.back();
  10812. if (auto lastIdentifier = BfNodeDynCast<BfIdentifierNode>(lastNode))
  10813. {
  10814. auto autoComplete = mModule->mCompiler->GetAutoComplete();
  10815. if (autoComplete != NULL)
  10816. {
  10817. autoComplete->CheckIdentifier(lastIdentifier, false, false);
  10818. }
  10819. }
  10820. }
  10821. if (unassignedFieldFlags != 0)
  10822. {
  10823. auto curBlock = mModule->mBfIRBuilder->GetInsertBlock();
  10824. mModule->mBfIRBuilder->SetInsertPointAtStart(initBlock);
  10825. mModule->mBfIRBuilder->CreateMemSet(initValue.mValue, mModule->GetConstValue(0, mModule->GetPrimitiveType(BfTypeCode_Int8)),
  10826. mModule->GetConstValue(initValue.mType->mSize), initValue.mType->mAlign);
  10827. mModule->mBfIRBuilder->SetInsertPoint(curBlock);
  10828. }
  10829. mResult = origInitValue;
  10830. }
  10831. void BfExprEvaluator::Visit(BfCollectionInitializerExpression* arrayInitExpr)
  10832. {
  10833. mModule->Fail("Collection initializer not usable here", arrayInitExpr);
  10834. }
  10835. void BfExprEvaluator::Visit(BfTypeOfExpression* typeOfExpr)
  10836. {
  10837. auto typeType = mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef);
  10838. auto autoComplete = GetAutoComplete();
  10839. if ((autoComplete != NULL) && (typeOfExpr->mTypeRef != NULL))
  10840. {
  10841. autoComplete->CheckTypeRef(typeOfExpr->mTypeRef, false, true);
  10842. }
  10843. BfType* type;
  10844. if ((typeOfExpr->mTypeRef != NULL) && (typeOfExpr->mTypeRef->IsA<BfVarTypeReference>()))
  10845. {
  10846. type = mModule->GetPrimitiveType(BfTypeCode_Var);
  10847. }
  10848. else
  10849. {
  10850. type = ResolveTypeRef(typeOfExpr->mTypeRef, BfPopulateType_Identity, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_AllowGlobalsSelf | BfResolveTypeRefFlag_AllowUnboundGeneric));
  10851. }
  10852. if (type == NULL)
  10853. {
  10854. mResult = mModule->GetDefaultTypedValue(mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef));
  10855. return;
  10856. }
  10857. mModule->AddDependency(type, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
  10858. mResult = BfTypedValue(mModule->CreateTypeDataRef(type), typeType);
  10859. }
  10860. bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifierNode* propName)
  10861. {
  10862. auto typeType = mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef);
  10863. BfType* type;
  10864. //
  10865. {
  10866. // We ignore errors because we go through the normal Visit(BfTypeOfExpression) if this fails, which will throw the error again
  10867. SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
  10868. if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeOfExpr->mTypeRef))
  10869. {
  10870. SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
  10871. type = mModule->ResolveTypeRefAllowUnboundGenerics(typeOfExpr->mTypeRef, BfPopulateType_Identity);
  10872. }
  10873. else
  10874. {
  10875. type = ResolveTypeRef(typeOfExpr->mTypeRef, BfPopulateType_Identity, BfResolveTypeRefFlag_IgnoreLookupError);
  10876. }
  10877. }
  10878. if (type == NULL)
  10879. {
  10880. mResult = mModule->GetDefaultTypedValue(mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef));
  10881. return false;
  10882. }
  10883. bool success = true;
  10884. defer(
  10885. {
  10886. if (success)
  10887. mModule->AddDependency(type, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_TypeSignature);
  10888. });
  10889. // We want to try to avoid triggering OnTypeInit for basic info
  10890. mModule->PopulateType(type, BfPopulateType_Interfaces_Direct);
  10891. auto typeInstance = type->ToTypeInstance();
  10892. auto _BoolResult = [&](bool val)
  10893. {
  10894. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, val ? 1 : 0), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  10895. };
  10896. auto _Int32Result = [&](int32 val)
  10897. {
  10898. mResult = BfTypedValue(mModule->GetConstValue32(val), mModule->GetPrimitiveType(BfTypeCode_Int32));
  10899. };
  10900. String memberName;
  10901. propName->ToString(memberName);
  10902. bool handled = true;
  10903. if (memberName == "IsTypedPrimitive")
  10904. _BoolResult(type->IsPrimitiveType());
  10905. else if (memberName == "IsObject")
  10906. _BoolResult(type->IsObject());
  10907. else if (memberName == "IsValueType")
  10908. _BoolResult(type->IsValueType());
  10909. else if (memberName == "IsPrimitive")
  10910. _BoolResult(type->IsPrimitiveType());
  10911. else if (memberName == "IsInteger")
  10912. _BoolResult(type->IsInteger());
  10913. else if (memberName == "IsIntegral")
  10914. _BoolResult(type->IsIntegral());
  10915. else if (memberName == "IsSigned")
  10916. _BoolResult(type->IsSigned());
  10917. else if (memberName == "IsFloatingPoint")
  10918. _BoolResult(type->IsFloat());
  10919. else if (memberName == "IsPointer")
  10920. _BoolResult(type->IsPointer());
  10921. else if (memberName == "IsStruct")
  10922. _BoolResult(type->IsStruct());
  10923. else if (memberName == "IsSplattable")
  10924. _BoolResult(type->IsSplattable());
  10925. else if (memberName == "IsUnion")
  10926. _BoolResult(type->IsUnion());
  10927. else if (memberName == "IsBoxed")
  10928. _BoolResult(type->IsBoxed());
  10929. else if (memberName == "IsEnum")
  10930. _BoolResult(type->IsEnum());
  10931. else if (memberName == "IsTuple")
  10932. _BoolResult(type->IsTuple());
  10933. else if (memberName == "IsNullable")
  10934. _BoolResult(type->IsNullable());
  10935. else if (memberName == "IsGenericType")
  10936. _BoolResult(type->IsGenericTypeInstance());
  10937. else if (memberName == "IsGenericParam")
  10938. _BoolResult(type->IsGenericParam());
  10939. else if (memberName == "IsArray")
  10940. _BoolResult(type->IsArray());
  10941. else if (memberName == "IsSizedArray")
  10942. _BoolResult(type->IsSizedArray());
  10943. else if (memberName == "TypeId")
  10944. {
  10945. _Int32Result(type->mTypeId);
  10946. mResult.mType = mModule->ResolveTypeDef(mModule->mCompiler->mReflectTypeIdTypeDef);
  10947. }
  10948. else if (memberName == "GenericParamCount")
  10949. {
  10950. auto genericTypeInst = type->ToGenericTypeInstance();
  10951. _Int32Result((genericTypeInst != NULL) ? (int)genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size() : 0);
  10952. }
  10953. else
  10954. {
  10955. // We need full data
  10956. mModule->PopulateType(type, BfPopulateType_Data);
  10957. if (memberName == "Size")
  10958. _Int32Result(type->mSize);
  10959. else if (memberName == "Align")
  10960. _Int32Result(type->mAlign);
  10961. else if (memberName == "Stride")
  10962. _Int32Result(type->GetStride());
  10963. else if (memberName == "InstanceSize")
  10964. _Int32Result((typeInstance != NULL) ? typeInstance->mInstSize : type->mSize);
  10965. else if (memberName == "InstanceAlign")
  10966. _Int32Result((typeInstance != NULL) ? typeInstance->mInstAlign : type->mSize);
  10967. else if (memberName == "InstanceStride")
  10968. _Int32Result((typeInstance != NULL) ? typeInstance->GetInstStride() : type->GetStride());
  10969. else if (memberName == "UnderlyingType")
  10970. {
  10971. bool handled = false;
  10972. auto typeType = mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef);
  10973. if (type->IsGenericParam())
  10974. {
  10975. auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)type);
  10976. if (genericParamInstance->IsEnum())
  10977. {
  10978. handled = true;
  10979. mResult = BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->MapType(typeType)), typeType);
  10980. }
  10981. }
  10982. else if (type->IsEnum())
  10983. {
  10984. if (type->IsDataIncomplete())
  10985. mModule->PopulateType(type);
  10986. auto underlyingType = type->GetUnderlyingType();
  10987. if (underlyingType != NULL)
  10988. {
  10989. handled = true;
  10990. mModule->AddDependency(underlyingType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
  10991. mResult = BfTypedValue(mModule->CreateTypeDataRef(underlyingType), typeType);
  10992. }
  10993. }
  10994. if (!handled)
  10995. mResult = BfTypedValue(mModule->CreateTypeDataRef(mModule->GetPrimitiveType(BfTypeCode_None)), typeType);
  10996. }
  10997. else if (memberName == "BitSize")
  10998. {
  10999. auto int32Type = mModule->GetPrimitiveType(BfTypeCode_Int32);
  11000. BfType* checkType = type;
  11001. if (checkType->IsTypedPrimitive())
  11002. checkType = checkType->GetUnderlyingType();
  11003. if (checkType->IsGenericParam())
  11004. {
  11005. mResult = mModule->GetDefaultTypedValue(int32Type, false, Beefy::BfDefaultValueKind_Undef);
  11006. return true;
  11007. }
  11008. if ((typeInstance != NULL) && (typeInstance->IsEnum()))
  11009. {
  11010. if (typeInstance->mTypeInfoEx != NULL)
  11011. {
  11012. int64 minValue = typeInstance->mTypeInfoEx->mMinValue;
  11013. if (minValue < 0)
  11014. minValue = ~minValue;
  11015. int64 maxValue = typeInstance->mTypeInfoEx->mMaxValue;
  11016. if (maxValue < 0)
  11017. maxValue = ~maxValue;
  11018. uint64 value = (uint64)minValue | (uint64)maxValue;
  11019. int bitCount = 1;
  11020. if (typeInstance->mTypeInfoEx->mMinValue < 0)
  11021. bitCount++;
  11022. while (value >>= 1)
  11023. bitCount++;
  11024. mModule->AddDependency(typeInstance, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields);
  11025. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, bitCount), int32Type);
  11026. return true;
  11027. }
  11028. }
  11029. int bitSize = checkType->mSize * 8;
  11030. if (checkType->GetTypeCode() == BfTypeCode_Boolean)
  11031. bitSize = 1;
  11032. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, bitSize), int32Type);
  11033. return true;
  11034. }
  11035. else if ((memberName == "MinValue") || (memberName == "MaxValue"))
  11036. {
  11037. bool isMin = memberName == "MinValue";
  11038. bool isBitSize = memberName == "BitSize";
  11039. BfType* checkType = type;
  11040. if (checkType->IsTypedPrimitive())
  11041. checkType = checkType->GetUnderlyingType();
  11042. if (checkType->IsGenericParam())
  11043. {
  11044. bool foundMatch = false;
  11045. auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)checkType);
  11046. if (((genericParamInstance->mGenericParamFlags & BfGenericParamFlag_Enum) != 0) ||
  11047. ((genericParamInstance->mTypeConstraint != NULL) && (genericParamInstance->mTypeConstraint->IsInstanceOf(mModule->mCompiler->mEnumTypeDef))))
  11048. foundMatch = true;
  11049. else
  11050. {
  11051. for (auto constraint : genericParamInstance->mInterfaceConstraints)
  11052. {
  11053. if (constraint->IsInstanceOf(mModule->mCompiler->mIIntegerTypeDef))
  11054. foundMatch = true;
  11055. }
  11056. }
  11057. if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsUnspecialized) && (mModule->mCurMethodInstance->mMethodInfoEx != NULL))
  11058. {
  11059. for (int genericParamIdx = (int)mModule->mCurMethodInstance->mMethodInfoEx->mMethodGenericArguments.size();
  11060. genericParamIdx < mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams.size(); genericParamIdx++)
  11061. {
  11062. genericParamInstance = mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
  11063. if (genericParamInstance->mExternType == type)
  11064. {
  11065. if (((genericParamInstance->mGenericParamFlags & BfGenericParamFlag_Enum) != 0) ||
  11066. ((genericParamInstance->mTypeConstraint != NULL) && (genericParamInstance->mTypeConstraint->IsInstanceOf(mModule->mCompiler->mEnumTypeDef))))
  11067. foundMatch = true;
  11068. }
  11069. }
  11070. }
  11071. if (foundMatch)
  11072. {
  11073. mResult = mModule->GetDefaultTypedValue(type, false, Beefy::BfDefaultValueKind_Undef);
  11074. return true;
  11075. }
  11076. }
  11077. if (checkType->IsPrimitiveType())
  11078. {
  11079. auto primType = (BfPrimitiveType*)checkType;
  11080. if ((typeInstance != NULL) && (typeInstance->IsEnum()))
  11081. {
  11082. if (typeInstance->mTypeInfoEx != NULL)
  11083. {
  11084. mModule->AddDependency(typeInstance, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields);
  11085. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? (uint64)typeInstance->mTypeInfoEx->mMinValue : (uint64)typeInstance->mTypeInfoEx->mMaxValue), typeInstance);
  11086. return true;
  11087. }
  11088. }
  11089. else
  11090. {
  11091. switch (primType->mTypeDef->mTypeCode)
  11092. {
  11093. case BfTypeCode_Int8:
  11094. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? -0x80 : 0x7F), primType);
  11095. return true;
  11096. case BfTypeCode_Int16:
  11097. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? -0x8000 : 0x7FFF), primType);
  11098. return true;
  11099. case BfTypeCode_Int32:
  11100. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? (uint64)-0x80000000LL : 0x7FFFFFFF), primType);
  11101. return true;
  11102. case BfTypeCode_Int64:
  11103. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? (uint64)-0x8000000000000000LL : (uint64)0x7FFFFFFFFFFFFFFFLL), primType);
  11104. return true;
  11105. case BfTypeCode_UInt8:
  11106. case BfTypeCode_Char8:
  11107. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? 0 : 0xFF), primType);
  11108. return true;
  11109. case BfTypeCode_UInt16:
  11110. case BfTypeCode_Char16:
  11111. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? 0 : 0xFFFF), primType);
  11112. return true;
  11113. case BfTypeCode_UInt32:
  11114. case BfTypeCode_Char32:
  11115. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? 0 : (uint64)0xFFFFFFFFLL), primType);
  11116. return true;
  11117. case BfTypeCode_UInt64:
  11118. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? 0 : (uint64)0xFFFFFFFFFFFFFFFFLL), primType);
  11119. return true;
  11120. case BfTypeCode_IntPtr:
  11121. if (mModule->mSystem->mPtrSize == 8)
  11122. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? (uint64)-0x8000000000000000LL : (uint64)0x7FFFFFFFFFFFFFFFLL), primType);
  11123. else
  11124. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? (uint64)-0x80000000LL : 0x7FFFFFFF), primType);
  11125. return true;
  11126. case BfTypeCode_UIntPtr:
  11127. if (mModule->mSystem->mPtrSize == 8)
  11128. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? 0 : (uint64)0xFFFFFFFFFFFFFFFFLL), primType);
  11129. else
  11130. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? 0 : (uint64)0xFFFFFFFFLL), primType);
  11131. return true;
  11132. default: break;
  11133. }
  11134. }
  11135. }
  11136. if (type->IsEnum())
  11137. {
  11138. mModule->Fail(StrFormat("'MinValue' cannot be used on enum with payload '%s'", mModule->TypeToString(type).c_str()), propName);
  11139. }
  11140. else
  11141. {
  11142. mModule->Fail(StrFormat("'%s' cannot be used on type '%s'", memberName.c_str(), mModule->TypeToString(type).c_str()), propName);
  11143. }
  11144. }
  11145. else
  11146. {
  11147. success = false;
  11148. return false;
  11149. }
  11150. }
  11151. if ((type->IsGenericParam()) && (!mModule->mIsComptimeModule))
  11152. {
  11153. if (mResult.mType != NULL)
  11154. mResult = mModule->GetDefaultTypedValue(mResult.mType, false, Beefy::BfDefaultValueKind_Undef);
  11155. }
  11156. auto autoComplete = GetAutoComplete();
  11157. if ((autoComplete != NULL) && (typeOfExpr->mTypeRef != NULL))
  11158. {
  11159. autoComplete->CheckTypeRef(typeOfExpr->mTypeRef, false, true);
  11160. }
  11161. return true;
  11162. }
  11163. void BfExprEvaluator::DoTypeIntAttr(BfTypeReference* typeRef, BfTokenNode* commaToken, BfIdentifierNode* memberName, BfToken token)
  11164. {
  11165. auto autoComplete = GetAutoComplete();
  11166. auto type = mModule->ResolveTypeRef(typeRef, BfPopulateType_Data, BfResolveTypeRefFlag_AutoComplete);
  11167. if (type == NULL)
  11168. return;
  11169. mModule->AddDependency(type, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage); // Local usage ensures it changes when the type data changes
  11170. auto typeInst = type->ToTypeInstance();
  11171. if ((typeInst != NULL) && (typeInst->mTypeDef->mIsOpaque))
  11172. {
  11173. mModule->Fail(StrFormat("Unable to determine attributes for opaque type '%s'", mModule->TypeToString(type).c_str()), typeRef);
  11174. }
  11175. BfType* sizeType = mModule->GetPrimitiveType(BfTypeCode_Int32);
  11176. int attrVal = 0;
  11177. switch (token)
  11178. {
  11179. case BfToken_SizeOf: attrVal = type->mSize; break;
  11180. case BfToken_AlignOf: attrVal = type->mAlign; break;
  11181. case BfToken_StrideOf: attrVal = type->GetStride(); break;
  11182. default: break;
  11183. }
  11184. if (token == BfToken_OffsetOf)
  11185. {
  11186. bool found = false;
  11187. String findName;
  11188. if (memberName != NULL)
  11189. findName = memberName->ToString();
  11190. BfAstNode* refNode = typeRef;
  11191. if (memberName != NULL)
  11192. refNode = memberName;
  11193. auto checkTypeInst = typeInst;
  11194. while (checkTypeInst != NULL)
  11195. {
  11196. checkTypeInst->mTypeDef->PopulateMemberSets();
  11197. String filter;
  11198. if ((autoComplete != NULL) && (autoComplete->InitAutocomplete(commaToken, memberName, filter)))
  11199. {
  11200. auto activeTypeDef = mModule->GetActiveTypeDef();
  11201. mModule->PopulateType(checkTypeInst);
  11202. BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None;
  11203. for (auto fieldDef : checkTypeInst->mTypeDef->mFields)
  11204. {
  11205. if (fieldDef->mIsStatic)
  11206. continue;
  11207. if (!mModule->CheckProtection(protectionCheckFlags, typeInst, fieldDef->mDeclaringType->mProject, fieldDef->mProtection, typeInst))
  11208. continue;
  11209. if ((!typeInst->IsTypeMemberIncluded(fieldDef->mDeclaringType, activeTypeDef, mModule)) ||
  11210. (!typeInst->IsTypeMemberAccessible(fieldDef->mDeclaringType, activeTypeDef)))
  11211. continue;
  11212. auto& fieldInst = checkTypeInst->mFieldInstances[fieldDef->mIdx];
  11213. autoComplete->AddField(checkTypeInst, fieldDef, &fieldInst, filter);
  11214. }
  11215. }
  11216. BfMemberSetEntry* memberSetEntry = NULL;
  11217. if (checkTypeInst->mTypeDef->mFieldSet.TryGetWith(findName, &memberSetEntry))
  11218. {
  11219. auto fieldDef = (BfFieldDef*)memberSetEntry->mMemberDef;
  11220. if (fieldDef != NULL)
  11221. {
  11222. if (fieldDef->mIsStatic)
  11223. mModule->Fail(StrFormat("Cannot generate an offset from static field '%s.%s'", mModule->TypeToString(type).c_str(), fieldDef->mName.c_str()), refNode);
  11224. mModule->PopulateType(checkTypeInst);
  11225. auto& fieldInst = checkTypeInst->mFieldInstances[fieldDef->mIdx];
  11226. attrVal = fieldInst.mDataOffset;
  11227. found = true;
  11228. break;
  11229. }
  11230. }
  11231. checkTypeInst = checkTypeInst->mBaseType;
  11232. }
  11233. if (!found)
  11234. {
  11235. mModule->Fail(StrFormat("Unable to locate field '%s.%s'", mModule->TypeToString(type).c_str(), findName.c_str()), refNode);
  11236. }
  11237. }
  11238. bool isUndefVal = false;
  11239. if (type->IsGenericParam())
  11240. isUndefVal = true;
  11241. if (type->IsSizedArray())
  11242. {
  11243. auto sizedArray = (BfSizedArrayType*)type;
  11244. if (sizedArray->mElementCount == -1)
  11245. isUndefVal = true;
  11246. }
  11247. if (isUndefVal)
  11248. {
  11249. // We do this so we know it's a constant but we can't assume anything about its value
  11250. // We make the value an Int32 which doesn't match the IntPtr type, but it allows us to
  11251. // assume it can be implicitly cased to int32
  11252. mResult = BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->MapType(sizeType)), sizeType);
  11253. }
  11254. else
  11255. mResult = BfTypedValue(mModule->GetConstValue(attrVal, sizeType), sizeType);
  11256. }
  11257. void BfExprEvaluator::Visit(BfSizeOfExpression* sizeOfExpr)
  11258. {
  11259. DoTypeIntAttr(sizeOfExpr->mTypeRef, NULL, NULL, BfToken_SizeOf);
  11260. }
  11261. void BfExprEvaluator::Visit(BfAlignOfExpression* alignOfExpr)
  11262. {
  11263. DoTypeIntAttr(alignOfExpr->mTypeRef, NULL, NULL, BfToken_AlignOf);
  11264. }
  11265. void BfExprEvaluator::Visit(BfStrideOfExpression* strideOfExpr)
  11266. {
  11267. DoTypeIntAttr(strideOfExpr->mTypeRef, NULL, NULL, BfToken_StrideOf);
  11268. }
  11269. void BfExprEvaluator::Visit(BfOffsetOfExpression* offsetOfExpr)
  11270. {
  11271. DoTypeIntAttr(offsetOfExpr->mTypeRef, offsetOfExpr->mCommaToken, offsetOfExpr->mMemberName, BfToken_OffsetOf);
  11272. }
  11273. void BfExprEvaluator::Visit(BfNameOfExpression* nameOfExpr)
  11274. {
  11275. String name;
  11276. if (mModule->IsInSpecializedGeneric())
  11277. {
  11278. if (auto identifierNode = BfNodeDynCastExact<BfIdentifierNode>(nameOfExpr->mTarget))
  11279. {
  11280. // This is necessary so we don't resolve 'T' to the actual generic argument type
  11281. name = identifierNode->ToString();
  11282. }
  11283. }
  11284. if (name.IsEmpty())
  11285. {
  11286. auto type = mModule->ResolveTypeRef(nameOfExpr->mTarget, {}, BfPopulateType_IdentityNoRemapAlias,
  11287. (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_AllowUnboundGeneric | BfResolveTypeRefFlag_IgnoreLookupError | BfResolveTypeRefFlag_IgnoreProtection));
  11288. if (type != NULL)
  11289. {
  11290. auto typeInst = type->ToTypeInstance();
  11291. if (typeInst != NULL)
  11292. name = typeInst->mTypeDef->mName->ToString();
  11293. else
  11294. name = mModule->TypeToString(type);
  11295. mModule->AddDependency(type, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_NameReference);
  11296. // Just do this for autocomplete
  11297. SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
  11298. VisitChild(nameOfExpr->mTarget);
  11299. }
  11300. }
  11301. if (name.IsEmpty())
  11302. {
  11303. if (auto identifer = BfNodeDynCast<BfIdentifierNode>(nameOfExpr->mTarget))
  11304. {
  11305. String targetStr = nameOfExpr->mTarget->ToString();
  11306. BfAtomComposite targetComposite;
  11307. bool isValid = mModule->mSystem->ParseAtomComposite(targetStr, targetComposite);
  11308. bool namespaceExists = false;
  11309. BfProject* bfProject = NULL;
  11310. auto activeTypeDef = mModule->GetActiveTypeDef();
  11311. if (activeTypeDef != NULL)
  11312. bfProject = activeTypeDef->mProject;
  11313. auto _CheckProject = [&](BfProject* project)
  11314. {
  11315. if ((isValid) && (project->mNamespaces.ContainsKey(targetComposite)))
  11316. namespaceExists = true;
  11317. };
  11318. if (bfProject != NULL)
  11319. {
  11320. for (int depIdx = -1; depIdx < (int)bfProject->mDependencies.size(); depIdx++)
  11321. {
  11322. BfProject* depProject = (depIdx == -1) ? bfProject : bfProject->mDependencies[depIdx];
  11323. _CheckProject(depProject);
  11324. }
  11325. }
  11326. else
  11327. {
  11328. for (auto project : mModule->mSystem->mProjects)
  11329. _CheckProject(project);
  11330. }
  11331. if (namespaceExists)
  11332. {
  11333. if (mModule->mCompiler->mResolvePassData != NULL)
  11334. {
  11335. if (auto sourceClassifier = mModule->mCompiler->mResolvePassData->GetSourceClassifier(nameOfExpr->mTarget))
  11336. {
  11337. BfAstNode* checkIdentifier = identifer;
  11338. while (true)
  11339. {
  11340. auto qualifiedIdentifier = BfNodeDynCast<BfQualifiedNameNode>(checkIdentifier);
  11341. if (qualifiedIdentifier == NULL)
  11342. break;
  11343. sourceClassifier->SetElementType(qualifiedIdentifier->mRight, BfSourceElementType_Namespace);
  11344. checkIdentifier = qualifiedIdentifier->mLeft;
  11345. }
  11346. sourceClassifier->SetElementType(checkIdentifier, BfSourceElementType_Namespace);
  11347. }
  11348. }
  11349. name = targetComposite.mParts[targetComposite.mSize - 1]->ToString();
  11350. }
  11351. }
  11352. }
  11353. if (name.IsEmpty())
  11354. {
  11355. SetAndRestoreValue<BfEvalExprFlags> prevFlags(mBfEvalExprFlags, (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_NameOf));
  11356. SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mBfIRBuilder->mIgnoreWrites, true);
  11357. VisitChild(nameOfExpr->mTarget);
  11358. if ((mBfEvalExprFlags & BfEvalExprFlags_NameOfSuccess) != 0)
  11359. {
  11360. BfAstNode* nameNode = nameOfExpr->mTarget;
  11361. if (auto attributedIdentifierNode = BfNodeDynCast<BfAttributedIdentifierNode>(nameNode))
  11362. nameNode = attributedIdentifierNode->mIdentifier;
  11363. if (auto memberReferenceExpr = BfNodeDynCast<BfMemberReferenceExpression>(nameNode))
  11364. nameNode = memberReferenceExpr->mMemberName;
  11365. if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(nameNode))
  11366. nameNode = qualifiedNameNode->mRight;
  11367. name = nameNode->ToString();
  11368. }
  11369. else if (mResultFieldInstance != NULL)
  11370. {
  11371. auto fieldDef = mResultFieldInstance->GetFieldDef();
  11372. if (fieldDef != NULL)
  11373. name = fieldDef->mName;
  11374. }
  11375. else if (mResultLocalVar != NULL)
  11376. {
  11377. name = mResultLocalVar->mName;
  11378. }
  11379. else if (mPropDef != NULL)
  11380. {
  11381. name = mPropDef->mName;
  11382. }
  11383. }
  11384. if ((name.IsEmpty()) && (nameOfExpr->mTarget != NULL))
  11385. mModule->Fail("Expression does not have a name", nameOfExpr->mTarget);
  11386. mResult = BfTypedValue(mModule->GetStringObjectValue(name), mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
  11387. }
  11388. void BfExprEvaluator::Visit(BfIsConstExpression* isConstExpr)
  11389. {
  11390. if (isConstExpr->mExpression == NULL)
  11391. {
  11392. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 0), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  11393. return;
  11394. }
  11395. BfMethodState methodState;
  11396. SetAndRestoreValue<BfMethodState*> prevMethodState(mModule->mCurMethodState, &methodState, false);
  11397. if (mModule->mCurMethodState == NULL)
  11398. prevMethodState.Set();
  11399. methodState.mTempKind = BfMethodState::TempKind_NonStatic;
  11400. SetAndRestoreValue<bool> ignoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
  11401. SetAndRestoreValue<bool> allowUninitReads(mModule->mCurMethodState->mAllowUinitReads, true);
  11402. BfEvalExprFlags exprFlags = BfEvalExprFlags_None;
  11403. auto result = mModule->CreateValueFromExpression(isConstExpr->mExpression, NULL, BfEvalExprFlags_DeclType);
  11404. bool isConst = mModule->mBfIRBuilder->IsConstValue(result.mValue);
  11405. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, isConst ? 1 : 0), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  11406. }
  11407. void BfExprEvaluator::Visit(BfDefaultExpression* defaultExpr)
  11408. {
  11409. auto autoComplete = GetAutoComplete();
  11410. if (autoComplete != NULL)
  11411. autoComplete->CheckTypeRef(defaultExpr->mTypeRef, false, true);
  11412. BfType* type = NULL;
  11413. if (defaultExpr->mOpenParen == NULL)
  11414. {
  11415. if (mExpectingType)
  11416. {
  11417. type = mExpectingType;
  11418. }
  11419. else
  11420. {
  11421. mModule->Fail("Type cannot be inferred, consider adding explicit type name", defaultExpr);
  11422. return;
  11423. }
  11424. }
  11425. else
  11426. type = mModule->ResolveTypeRef(defaultExpr->mTypeRef);
  11427. if (type == NULL)
  11428. return;
  11429. BfDefaultValueKind defaultKind = BfDefaultValueKind_Const;
  11430. if (type->IsRef())
  11431. {
  11432. mModule->Fail(StrFormat("There is no default value for type '%s'", mModule->TypeToString(type).c_str()), defaultExpr);
  11433. defaultKind = BfDefaultValueKind_Addr;
  11434. }
  11435. mModule->ValidateAllocation(type, defaultExpr->mTypeRef);
  11436. mModule->AddDependency(type, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
  11437. mResult = mModule->GetDefaultTypedValue(type, true, defaultKind);
  11438. }
  11439. void BfExprEvaluator::Visit(BfUninitializedExpression* uninitialziedExpr)
  11440. {
  11441. mModule->Fail("Invalid use of the '?' uninitialized specifier", uninitialziedExpr);
  11442. }
  11443. void BfExprEvaluator::Visit(BfCheckTypeExpression* checkTypeExpr)
  11444. {
  11445. auto targetValue = mModule->CreateValueFromExpression(checkTypeExpr->mTarget, NULL, (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags));
  11446. if (!targetValue)
  11447. return;
  11448. if (checkTypeExpr->mTypeRef == NULL)
  11449. {
  11450. mModule->AssertErrorState();
  11451. return;
  11452. }
  11453. auto autoComplete = GetAutoComplete();
  11454. if (autoComplete != NULL)
  11455. autoComplete->CheckTypeRef(checkTypeExpr->mTypeRef, false, true);
  11456. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  11457. if (checkTypeExpr->mTypeRef->IsA<BfVarTypeReference>())
  11458. {
  11459. bool isVar = false;
  11460. if ((targetValue.mType != NULL) && (targetValue.mType->IsVar()))
  11461. {
  11462. auto irb = mModule->mBfIRBuilder;
  11463. BfIRValue boolResult = mModule->CreateAlloca(boolType);
  11464. irb->CreateAlignedStore(irb->CreateConst(BfTypeCode_Boolean, 1), boolResult, 1);
  11465. mResult = BfTypedValue(irb->CreateAlignedLoad(boolResult, 1), boolType);
  11466. }
  11467. else
  11468. mResult = BfTypedValue(mModule->GetConstValue(0, boolType), boolType);
  11469. return;
  11470. }
  11471. auto targetType = mModule->ResolveTypeRef(checkTypeExpr->mTypeRef, BfPopulateType_Declaration);
  11472. if (!targetType)
  11473. {
  11474. mModule->AssertErrorState();
  11475. return;
  11476. }
  11477. mModule->AddDependency(targetType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
  11478. if (targetValue.mType->IsVar())
  11479. {
  11480. mResult = mModule->GetDefaultTypedValue(boolType, false, BfDefaultValueKind_Undef);
  11481. return;
  11482. }
  11483. if (targetValue.mType->IsValueTypeOrValueTypePtr())
  11484. {
  11485. auto typeInstance = targetValue.mType->ToTypeInstance();
  11486. if (targetValue.mType->IsWrappableType())
  11487. typeInstance = mModule->GetWrappedStructType(targetValue.mType);
  11488. bool matches = (targetValue.mType == targetType) || (mModule->mContext->mBfObjectType == targetType);
  11489. if (!matches)
  11490. matches = mModule->TypeIsSubTypeOf(typeInstance, targetType->ToTypeInstance());
  11491. if (!typeInstance->IsGenericParam())
  11492. {
  11493. if (matches)
  11494. mModule->Warn(0, "The result of this operation is always 'true'", checkTypeExpr->mIsToken);
  11495. else
  11496. mModule->Warn(0, "The result of this operation is always 'false'", checkTypeExpr->mIsToken);
  11497. }
  11498. mResult = BfTypedValue(mModule->GetConstValue(matches ? 1 : 0, boolType), boolType);
  11499. return;
  11500. }
  11501. if (targetType->IsValueType())
  11502. {
  11503. if ((targetValue.mType != mModule->mContext->mBfObjectType) && (!targetValue.mType->IsInterface()))
  11504. {
  11505. mResult = BfTypedValue(mModule->GetConstValue(0, boolType), boolType);
  11506. return;
  11507. }
  11508. }
  11509. int wantTypeId = 0;
  11510. if (!targetType->IsGenericParam())
  11511. wantTypeId = targetType->mTypeId;
  11512. auto objectType = mModule->mContext->mBfObjectType;
  11513. mModule->PopulateType(objectType, BfPopulateType_Full);
  11514. targetValue = mModule->LoadValue(targetValue);
  11515. BfTypeInstance* srcTypeInstance = targetValue.mType->ToTypeInstance();
  11516. BfTypeInstance* targetTypeInstance = targetType->ToTypeInstance();
  11517. bool wasGenericParamType = false;
  11518. if ((srcTypeInstance != NULL) && (targetTypeInstance != NULL))
  11519. {
  11520. if (mModule->TypeIsSubTypeOf(srcTypeInstance, targetTypeInstance))
  11521. {
  11522. // We don't give this warning when we have wasGenericParmType set because that indicates we had a generic type constraint,
  11523. // and a type constraint infers that the ACTUAL type used will be equal to or derived from that type and therefore
  11524. // it may be a "necessary cast" indeed
  11525. if ((!wasGenericParamType) && (mModule->mCurMethodState->mMixinState == NULL))
  11526. {
  11527. if (srcTypeInstance == targetType)
  11528. mModule->Warn(BfWarning_BF4203_UnnecessaryDynamicCast, StrFormat("Unnecessary check, the value is already type '%s'",
  11529. mModule->TypeToString(srcTypeInstance).c_str()), checkTypeExpr->mIsToken);
  11530. else
  11531. mModule->Warn(BfWarning_BF4203_UnnecessaryDynamicCast, StrFormat("Unnecessary check, '%s' is a subtype of '%s'",
  11532. mModule->TypeToString(srcTypeInstance).c_str(), mModule->TypeToString(targetType).c_str()), checkTypeExpr->mIsToken);
  11533. }
  11534. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 1), boolType);
  11535. return;
  11536. }
  11537. else if ((!targetType->IsInterface()) && (srcTypeInstance != mModule->mContext->mBfObjectType) && (!mModule->TypeIsSubTypeOf(targetTypeInstance, srcTypeInstance)))
  11538. {
  11539. mModule->Fail(StrFormat("Cannot convert type '%s' to '%s' via any conversion",
  11540. mModule->TypeToString(targetValue.mType).c_str(), mModule->TypeToString(targetTypeInstance).c_str()), checkTypeExpr->mIsToken);
  11541. }
  11542. }
  11543. if (mModule->mCompiler->IsAutocomplete())
  11544. {
  11545. mResult = mModule->GetDefaultTypedValue(boolType, false, BfDefaultValueKind_Addr);
  11546. return;
  11547. }
  11548. auto irb = mModule->mBfIRBuilder;
  11549. auto prevBB = mModule->mBfIRBuilder->GetInsertBlock();
  11550. auto matchBB = mModule->mBfIRBuilder->CreateBlock("is.match");
  11551. auto endBB = mModule->mBfIRBuilder->CreateBlock("is.done");
  11552. BfIRValue boolResult = mModule->CreateAlloca(boolType);
  11553. irb->CreateAlignedStore(irb->CreateConst(BfTypeCode_Boolean, 0), boolResult, 1);
  11554. mModule->EmitDynamicCastCheck(targetValue, targetType, matchBB, endBB);
  11555. mModule->AddBasicBlock(matchBB);
  11556. irb->CreateAlignedStore(irb->CreateConst(BfTypeCode_Boolean, 1), boolResult, 1);
  11557. irb->CreateBr(endBB);
  11558. mModule->AddBasicBlock(endBB);
  11559. mResult = BfTypedValue(irb->CreateAlignedLoad(boolResult, 1), boolType);
  11560. }
  11561. void BfExprEvaluator::Visit(BfDynamicCastExpression* dynCastExpr)
  11562. {
  11563. auto targetValue = mModule->CreateValueFromExpression(dynCastExpr->mTarget);
  11564. auto targetType = mModule->ResolveTypeRefAllowUnboundGenerics(dynCastExpr->mTypeRef, BfPopulateType_Data, BfResolveTypeRefFlag_None, false);
  11565. auto autoComplete = GetAutoComplete();
  11566. if (autoComplete != NULL)
  11567. {
  11568. autoComplete->CheckTypeRef(dynCastExpr->mTypeRef, false, true);
  11569. }
  11570. auto origTargetType = targetType;
  11571. if (!targetValue)
  11572. return;
  11573. if (!targetType)
  11574. {
  11575. mModule->AssertErrorState();
  11576. return;
  11577. }
  11578. bool wasGenericParamType = false;
  11579. if (targetType->IsGenericParam())
  11580. {
  11581. //targetType = mModule->ResolveGenericType(targetType);
  11582. //wasGenericParamType = true;
  11583. }
  11584. if ((targetValue.mType->IsMethodRef()) || (targetType->IsMethodRef()))
  11585. {
  11586. // We can never cast a MethodRef to any class type
  11587. mResult = mModule->GetDefaultTypedValue(targetType);
  11588. return;
  11589. }
  11590. if (mModule->mContext->mResolvingVarField)
  11591. {
  11592. mResult = mModule->GetDefaultTypedValue(targetType);
  11593. return;
  11594. }
  11595. mModule->AddDependency(targetType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
  11596. if (targetType->IsGenericParam())
  11597. {
  11598. wasGenericParamType = true;
  11599. BfGenericParamInstance* origGenericParam = NULL;
  11600. int pass = 0;
  11601. while ((targetType != NULL) && (targetType->IsGenericParam()))
  11602. {
  11603. auto genericParamType = (BfGenericParamType*)targetType;
  11604. auto genericParam = mModule->GetGenericParamInstance(genericParamType);
  11605. if (pass == 0)
  11606. origGenericParam = genericParam;
  11607. auto typeConstraint = genericParam->mTypeConstraint;
  11608. if ((typeConstraint == NULL) && (genericParam->mGenericParamFlags & (BfGenericParamFlag_Class | BfGenericParamFlag_Interface)))
  11609. typeConstraint = mModule->mContext->mBfObjectType;
  11610. targetType = typeConstraint;
  11611. if (++pass >= 100) // Sanity - but we should have caught circular error before
  11612. break;
  11613. }
  11614. if ((targetType == NULL) || (!targetType->IsObjectOrInterface()))
  11615. {
  11616. mModule->Fail(StrFormat("The type parameter '%s' cannot be used with the 'as' operator because it does not have a class type constraint nor a 'class' or 'interface' constraint",
  11617. origGenericParam->GetGenericParamDef()->mName.c_str()), dynCastExpr->mTypeRef);
  11618. return;
  11619. }
  11620. }
  11621. if (targetType->IsVar())
  11622. {
  11623. mResult = mModule->GetDefaultTypedValue(targetType);
  11624. return;
  11625. }
  11626. if ((!targetType->IsObjectOrInterface()) && (!targetType->IsNullable()))
  11627. {
  11628. mModule->Fail(StrFormat("The as operator must be used with a reference type or nullable type ('%s' is a non-nullable value type)",
  11629. mModule->TypeToString(origTargetType).c_str()), dynCastExpr->mTypeRef);
  11630. return;
  11631. }
  11632. if (targetValue.mType->IsGenericParam())
  11633. {
  11634. auto genericParamType = (BfGenericParamType*)targetValue.mType;
  11635. auto genericParam = mModule->GetGenericParamInstance(genericParamType);
  11636. auto typeConstraint = genericParam->mTypeConstraint;
  11637. if (typeConstraint == NULL)
  11638. typeConstraint = mModule->mContext->mBfObjectType;
  11639. if ((typeConstraint->IsDelegate()) && (typeConstraint == targetType))
  11640. {
  11641. // Delegate constraints may be matched by valueless method references, so this won't always match (don't warn)
  11642. mResult = mModule->GetDefaultTypedValue(targetType);
  11643. return;
  11644. }
  11645. targetValue = mModule->GetDefaultTypedValue(typeConstraint);
  11646. }
  11647. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  11648. auto _CheckResult = [&]()
  11649. {
  11650. if ((mResult) && (origTargetType->IsGenericParam()))
  11651. mResult = mModule->GetDefaultTypedValue(origTargetType, false, BfDefaultValueKind_Undef);
  11652. };
  11653. if ((targetValue.mType->IsNullable()) && (targetType->IsInterface()))
  11654. {
  11655. mResult = mModule->Cast(dynCastExpr, targetValue, targetType, BfCastFlags_SilentFail);
  11656. if (!mResult)
  11657. {
  11658. mModule->Warn(0, StrFormat("Conversion from '%s' to '%s' will always be null",
  11659. mModule->TypeToString(targetValue.mType).c_str(), mModule->TypeToString(origTargetType).c_str()), dynCastExpr->mAsToken);
  11660. mResult = BfTypedValue(mModule->GetDefaultValue(origTargetType), origTargetType);
  11661. }
  11662. _CheckResult();
  11663. return;
  11664. }
  11665. if (targetValue.mType->IsVar())
  11666. {
  11667. mResult = mModule->GetDefaultTypedValue(targetType, false, BfDefaultValueKind_Undef);
  11668. return;
  11669. }
  11670. if (targetValue.mType->IsValueTypeOrValueTypePtr())
  11671. {
  11672. mModule->Warn(0, StrFormat("Type '%s' is not applicable for dynamic casting",
  11673. mModule->TypeToString(targetValue.mType).c_str()), dynCastExpr->mAsToken);
  11674. auto typeInstance = targetValue.mType->ToTypeInstance();
  11675. if (targetValue.mType->IsWrappableType())
  11676. typeInstance = mModule->GetWrappedStructType(targetValue.mType);
  11677. bool matches = (targetValue.mType == targetType) || (mModule->mContext->mBfObjectType == targetType);
  11678. if (targetType->IsNullable())
  11679. {
  11680. auto elementType = targetType->GetUnderlyingType();
  11681. if (elementType == targetValue.mType)
  11682. {
  11683. mModule->mBfIRBuilder->PopulateType(targetType);
  11684. // We match nullable element
  11685. auto allocaInst = mModule->CreateAlloca(targetType);
  11686. auto hasValueAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, 2); // has_value
  11687. mModule->mBfIRBuilder->CreateStore(mModule->GetConstValue(1, boolType), hasValueAddr);
  11688. hasValueAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, 1); // value
  11689. mModule->mBfIRBuilder->CreateStore(targetValue.mValue, hasValueAddr);
  11690. mResult = BfTypedValue(allocaInst, targetType, true);
  11691. _CheckResult();
  11692. return;
  11693. }
  11694. }
  11695. if (!matches)
  11696. matches = mModule->TypeIsSubTypeOf(typeInstance, targetType->ToTypeInstance());
  11697. if (matches)
  11698. mResult = mModule->Cast(dynCastExpr, targetValue, targetType, BfCastFlags_Explicit);
  11699. else if (targetType->IsNullable())
  11700. {
  11701. auto allocaInst = mModule->CreateAlloca(targetType);
  11702. auto allocaBits = mModule->mBfIRBuilder->CreateBitCast(allocaInst, mModule->mBfIRBuilder->GetPrimitiveType(BfTypeCode_NullPtr));
  11703. mModule->mBfIRBuilder->CreateMemSet(allocaBits, mModule->GetConstValue(0, mModule->GetPrimitiveType(BfTypeCode_Int8)),
  11704. mModule->GetConstValue(targetType->mSize), targetType->mAlign);
  11705. mResult = BfTypedValue(allocaInst, targetType, true);
  11706. }
  11707. else
  11708. mResult = BfTypedValue(mModule->GetDefaultValue(targetType), targetType);
  11709. _CheckResult();
  11710. return;
  11711. }
  11712. if (targetType->IsNullable())
  11713. {
  11714. if (autoComplete != NULL)
  11715. {
  11716. mResult = mModule->GetDefaultTypedValue(targetType);
  11717. return;
  11718. }
  11719. auto elementType = targetType->GetUnderlyingType();
  11720. auto allocaInst = mModule->CreateAlloca(targetType);
  11721. auto hasValueAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, elementType->IsValuelessType() ? 1 : 2); // has_value
  11722. mModule->mBfIRBuilder->CreateStore(mModule->GetConstValue(0, boolType), hasValueAddr);
  11723. auto objectType = mModule->mContext->mBfObjectType;
  11724. auto prevBB = mModule->mBfIRBuilder->GetInsertBlock();
  11725. auto matchBB = mModule->mBfIRBuilder->CreateBlock("as.match");
  11726. auto endBB = mModule->mBfIRBuilder->CreateBlock("as.end");
  11727. mModule->EmitDynamicCastCheck(targetValue, elementType, matchBB, endBB);
  11728. BfBoxedType* boxedType = mModule->CreateBoxedType(elementType);
  11729. mModule->AddBasicBlock(matchBB);
  11730. if (elementType->IsValuelessType())
  11731. {
  11732. auto hasValueAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, 1); // has_value
  11733. mModule->mBfIRBuilder->CreateStore(mModule->GetConstValue(1, boolType), hasValueAddr);
  11734. }
  11735. else
  11736. {
  11737. auto hasValueAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, 2); // has_value
  11738. mModule->mBfIRBuilder->CreateStore(mModule->GetConstValue(1, boolType), hasValueAddr);
  11739. auto nullableValueAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, 1); // value
  11740. auto srcBoxedType = mModule->mBfIRBuilder->CreateBitCast(targetValue.mValue, mModule->mBfIRBuilder->MapType(boxedType, BfIRPopulateType_Full));
  11741. auto boxedValueAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(srcBoxedType, 0, 1); // mValue
  11742. auto boxedValue = mModule->mBfIRBuilder->CreateLoad(boxedValueAddr);
  11743. mModule->mBfIRBuilder->CreateStore(boxedValue, nullableValueAddr);
  11744. }
  11745. mModule->mBfIRBuilder->CreateBr(endBB);
  11746. mModule->AddBasicBlock(endBB);
  11747. mResult = BfTypedValue(allocaInst, targetType, true);
  11748. _CheckResult();
  11749. return;
  11750. }
  11751. targetValue = mModule->LoadValue(targetValue);
  11752. if (targetType->IsValueType())
  11753. {
  11754. mModule->Fail("Invalid dynamic cast type", dynCastExpr->mTypeRef);
  11755. return;
  11756. }
  11757. BfTypeInstance* srcTypeInstance = targetValue.mType->ToTypeInstance();
  11758. BfTypeInstance* targetTypeInstance = targetType->ToTypeInstance();
  11759. if (mModule->TypeIsSubTypeOf(srcTypeInstance, targetTypeInstance))
  11760. {
  11761. // We don't give this warning when we have wasGenericParmType set because that indicates we had a generic type constraint,
  11762. // and a type constraint infers that the ACTUAL type used will be equal to or derived from that type and therefore
  11763. // it may be a "necessary cast" indeed
  11764. if ((!wasGenericParamType) && (mModule->mCurMethodState->mMixinState == NULL))
  11765. {
  11766. if (srcTypeInstance == targetType)
  11767. mModule->Warn(BfWarning_BF4203_UnnecessaryDynamicCast, StrFormat("Unnecessary cast, the value is already type '%s'",
  11768. mModule->TypeToString(srcTypeInstance).c_str()), dynCastExpr->mAsToken);
  11769. else
  11770. mModule->Warn(BfWarning_BF4203_UnnecessaryDynamicCast, StrFormat("Unnecessary cast, '%s' is a subtype of '%s'",
  11771. mModule->TypeToString(srcTypeInstance).c_str(), mModule->TypeToString(targetType).c_str()), dynCastExpr->mAsToken);
  11772. }
  11773. auto castedValue = mModule->mBfIRBuilder->CreateBitCast(targetValue.mValue, mModule->mBfIRBuilder->MapType(targetTypeInstance));
  11774. mResult = BfTypedValue(castedValue, targetTypeInstance);
  11775. _CheckResult();
  11776. return;
  11777. }
  11778. else if ((!targetType->IsInterface()) && (!mModule->TypeIsSubTypeOf(targetTypeInstance, srcTypeInstance)))
  11779. {
  11780. if (!mModule->IsInSpecializedSection())
  11781. {
  11782. mModule->Fail(StrFormat("Cannot convert type '%s' to '%s' via any conversion",
  11783. mModule->TypeToString(targetValue.mType).c_str(), mModule->TypeToString(targetTypeInstance).c_str()), dynCastExpr->mAsToken);
  11784. }
  11785. mResult = mModule->GetDefaultTypedValue(targetType);
  11786. return;
  11787. }
  11788. if (autoComplete != NULL)
  11789. {
  11790. mResult = mModule->GetDefaultTypedValue(targetType, false, BfDefaultValueKind_Addr);
  11791. _CheckResult();
  11792. return;
  11793. }
  11794. auto irb = mModule->mBfIRBuilder;
  11795. auto objectType = mModule->mContext->mBfObjectType;
  11796. mModule->PopulateType(objectType, BfPopulateType_Full);
  11797. auto prevBB = mModule->mBfIRBuilder->GetInsertBlock();
  11798. auto endBB = mModule->mBfIRBuilder->CreateBlock("as.end");
  11799. auto matchBlock = irb->CreateBlock("as.match");
  11800. BfIRValue targetVal = mModule->CreateAlloca(targetType);
  11801. irb->CreateAlignedStore(irb->CreateConstNull(irb->MapType(targetType)), targetVal, targetType->mAlign);
  11802. mModule->EmitDynamicCastCheck(targetValue, targetType, matchBlock, endBB);
  11803. mModule->AddBasicBlock(matchBlock);
  11804. BfIRValue castedCallResult = mModule->mBfIRBuilder->CreateBitCast(targetValue.mValue, mModule->mBfIRBuilder->MapType(targetType));
  11805. irb->CreateAlignedStore(castedCallResult, targetVal, targetValue.mType->mAlign);
  11806. irb->CreateBr(endBB);
  11807. mModule->AddBasicBlock(endBB);
  11808. mResult = BfTypedValue(irb->CreateAlignedLoad(targetVal, targetType->mAlign), targetType);
  11809. _CheckResult();
  11810. }
  11811. void BfExprEvaluator::Visit(BfCastExpression* castExpr)
  11812. {
  11813. auto autoComplete = GetAutoComplete();
  11814. if ((autoComplete != NULL) && (castExpr->mTypeRef != NULL))
  11815. {
  11816. // 'mayBeIdentifier' because this may be a misidentified cast - it could be a parenthesized expression
  11817. autoComplete->CheckTypeRef(castExpr->mTypeRef, true, true);
  11818. }
  11819. BfType* resolvedType = NULL;
  11820. if ((BfNodeDynCastExact<BfDotTypeReference>(castExpr->mTypeRef) != NULL) && (mExpectingType != NULL))
  11821. {
  11822. //mModule->SetElementType(castExpr->mTypeRef, BfSourceElementType_TypeRef);
  11823. resolvedType = mExpectingType;
  11824. }
  11825. else
  11826. resolvedType = ResolveTypeRef(castExpr->mTypeRef);
  11827. if (resolvedType != NULL)
  11828. mModule->AddDependency(resolvedType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage);
  11829. // If resolvedType is NULL then that's okay- we just leave the following expression uncasted
  11830. if (castExpr->mExpression == NULL)
  11831. {
  11832. mModule->AssertErrorState();
  11833. return;
  11834. }
  11835. auto exprFlags = (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_NoAutoComplete) | BfEvalExprFlags_ExplicitCast);
  11836. mResult = mModule->CreateValueFromExpression(castExpr->mExpression, resolvedType, exprFlags);
  11837. }
  11838. bool BfExprEvaluator::IsExactMethodMatch(BfMethodInstance* methodA, BfMethodInstance* methodB, bool ignoreImplicitParams)
  11839. {
  11840. if (methodA->mReturnType != methodB->mReturnType)
  11841. return false;
  11842. int implicitParamCountA = methodA->GetImplicitParamCount();
  11843. if (methodA->HasExplicitThis())
  11844. implicitParamCountA++;
  11845. int implicitParamCountB = methodB->GetImplicitParamCount();
  11846. if (methodB->HasExplicitThis())
  11847. implicitParamCountB++;
  11848. if (methodA->GetParamCount() - implicitParamCountA != methodB->GetParamCount() - implicitParamCountB)
  11849. return false;
  11850. for (int i = 0; i < (int)methodA->GetParamCount() - implicitParamCountA; i++)
  11851. {
  11852. auto paramA = methodA->GetParamType(i + implicitParamCountA);
  11853. auto paramB = methodB->GetParamType(i + implicitParamCountB);
  11854. if (paramA != paramB)
  11855. return false;
  11856. }
  11857. return true;
  11858. }
  11859. void BfExprEvaluator::ConstResolve(BfExpression* expr)
  11860. {
  11861. BfConstResolver constResolver(mModule);
  11862. constResolver.Resolve(expr);
  11863. mResult = constResolver.mResult;
  11864. }
  11865. BfTypeInstance* BfExprEvaluator::VerifyBaseDelegateType(BfTypeInstance* baseDelegateType)
  11866. {
  11867. mModule->PopulateType(baseDelegateType, BfPopulateType_DataAndMethods);
  11868. if (baseDelegateType->mFieldInstances.size() != 2)
  11869. {
  11870. mModule->AssertErrorState();
  11871. return NULL;
  11872. }
  11873. return baseDelegateType;
  11874. }
  11875. bool BfExprEvaluator::CanBindDelegate(BfDelegateBindExpression* delegateBindExpr, BfMethodInstance** boundMethod, BfType* origMethodExpectingType, BfTypeVector* methodGenericArgumentsSubstitute)
  11876. {
  11877. if ((mExpectingType == NULL) && (origMethodExpectingType == NULL))
  11878. {
  11879. return false;
  11880. }
  11881. bool isGenericMatch = mExpectingType == NULL;
  11882. auto expectingType = mExpectingType;
  11883. if (expectingType == NULL)
  11884. expectingType = origMethodExpectingType;
  11885. auto typeInstance = expectingType->ToTypeInstance();
  11886. if ((typeInstance == NULL) ||
  11887. ((!typeInstance->mTypeDef->mIsDelegate) && (!typeInstance->mTypeDef->mIsFunction)))
  11888. return false;
  11889. mModule->PopulateType(typeInstance, BfPopulateType_DataAndMethods);
  11890. auto methodInstance = mModule->GetRawMethodInstanceAtIdx(typeInstance, 0, "Invoke");
  11891. if (methodInstance == NULL)
  11892. {
  11893. BF_DBG_FATAL("Invoke not found");
  11894. return false;
  11895. }
  11896. if (delegateBindExpr->mTarget == NULL)
  11897. return false;
  11898. BfAutoParentNodeEntry autoParentNodeEntry(mModule, delegateBindExpr);
  11899. SizedArray<BfTypedValueExpression, 4> typedValueExprs;
  11900. typedValueExprs.resize(methodInstance->GetParamCount());
  11901. SizedArray<BfExpression*, 4> args;
  11902. args.resize(methodInstance->GetParamCount());
  11903. auto _FixType = [&](BfType* type)
  11904. {
  11905. if (!isGenericMatch)
  11906. return type;
  11907. auto fixedType = mModule->ResolveGenericType(type, NULL, methodGenericArgumentsSubstitute, mModule->mCurTypeInstance);
  11908. if (fixedType != NULL)
  11909. return fixedType;
  11910. return (BfType*)mModule->GetPrimitiveType(BfTypeCode_Var);
  11911. };
  11912. auto _TypeMatches = [&](BfType* lhs, BfType* rhs)
  11913. {
  11914. if (lhs == rhs)
  11915. return true;
  11916. return lhs->IsVar();
  11917. };
  11918. for (int i = 0; i < (int) methodInstance->GetParamCount(); i++)
  11919. {
  11920. auto typedValueExpr = &typedValueExprs[i];
  11921. typedValueExpr->mTypedValue.mValue = BfIRValue(BfIRValueFlags_Value, -1);
  11922. typedValueExpr->mTypedValue.mType = _FixType(methodInstance->GetParamType(i));
  11923. typedValueExpr->mRefNode = NULL;
  11924. args[i] = typedValueExpr;
  11925. }
  11926. BfMethodGenericArguments methodGenericArgs;
  11927. if (delegateBindExpr->mGenericArgs != NULL)
  11928. methodGenericArgs.mArguments = &delegateBindExpr->mGenericArgs->mGenericArgs;
  11929. BfFunctionBindResult bindResult;
  11930. bindResult.mSkipMutCheck = true; // Allow operating on copies
  11931. bindResult.mBindType = expectingType;
  11932. mFunctionBindResult = &bindResult;
  11933. SetAndRestoreValue<bool> ignoreError(mModule->mIgnoreErrors, true);
  11934. DoInvocation(delegateBindExpr->mTarget, delegateBindExpr, args, methodGenericArgs);
  11935. mFunctionBindResult = NULL;
  11936. if (bindResult.mMethodInstance == NULL)
  11937. return false;
  11938. if (boundMethod != NULL)
  11939. *boundMethod = bindResult.mMethodInstance;
  11940. auto matchedMethod = bindResult.mMethodInstance;
  11941. if (!_TypeMatches(_FixType(methodInstance->mReturnType), matchedMethod->mReturnType))
  11942. return false;
  11943. int implicitParamCountA = methodInstance->GetImplicitParamCount();
  11944. int implicitParamCountB = matchedMethod->GetImplicitParamCount();
  11945. if (methodInstance->GetParamCount() - implicitParamCountA != matchedMethod->GetParamCount() - implicitParamCountB)
  11946. return false;
  11947. for (int i = 0; i < (int)methodInstance->GetParamCount() - implicitParamCountA; i++)
  11948. {
  11949. auto paramA = _FixType(methodInstance->GetParamType(i + implicitParamCountA));
  11950. auto paramB = _FixType(matchedMethod->GetParamType(i + implicitParamCountB));
  11951. if (!_TypeMatches(paramA, paramB))
  11952. return false;
  11953. }
  11954. return true;
  11955. }
  11956. BfTypedValue BfExprEvaluator::DoImplicitArgCapture(BfAstNode* refNode, BfIdentifierNode* identifierNode, int shadowIdx)
  11957. {
  11958. String findName = identifierNode->ToString();
  11959. if (mModule->mCurMethodState != NULL)
  11960. {
  11961. auto rootMethodState = mModule->mCurMethodState->GetRootMethodState();
  11962. auto checkMethodState = mModule->mCurMethodState;
  11963. bool isMixinOuterVariablePass = false;
  11964. int shadowSkip = shadowIdx;
  11965. while (checkMethodState != NULL)
  11966. {
  11967. BP_ZONE("LookupIdentifier:DoImplicitArgCapture");
  11968. BfTypeInstance* closureTypeInst = NULL;
  11969. BfClosureInstanceInfo* closureInstanceInfo = NULL;
  11970. if ((checkMethodState->mClosureState != NULL) && (checkMethodState->mClosureState->mClosureType != NULL) && (!checkMethodState->mClosureState->mCapturing))
  11971. {
  11972. closureTypeInst = mModule->mCurMethodState->mClosureState->mClosureType;
  11973. }
  11974. BfLocalVarEntry* entry;
  11975. if (checkMethodState->mLocalVarSet.TryGetWith<StringImpl&>(findName, &entry))
  11976. {
  11977. auto varDecl = entry->mLocalVar;
  11978. while (varDecl != NULL)
  11979. {
  11980. if (varDecl->mNameNode == identifierNode)
  11981. {
  11982. if (shadowSkip > 0)
  11983. {
  11984. shadowSkip--;
  11985. }
  11986. else
  11987. {
  11988. BfTypedValue localResult = LoadLocal(varDecl);
  11989. if (!isMixinOuterVariablePass)
  11990. {
  11991. mResultLocalVar = varDecl;
  11992. mResultFieldInstance = NULL;
  11993. mResultLocalVarRefNode = identifierNode;
  11994. }
  11995. return localResult;
  11996. }
  11997. }
  11998. varDecl = varDecl->mShadowedLocal;
  11999. }
  12000. }
  12001. // Check for the captured locals. It's important we do it here so we get local-first precedence still
  12002. if (closureTypeInst != NULL)
  12003. {
  12004. closureTypeInst->mTypeDef->PopulateMemberSets();
  12005. BfMemberSetEntry* memberSetEntry = NULL;
  12006. if (closureTypeInst->mTypeDef->mFieldSet.TryGetWith(findName, &memberSetEntry))
  12007. {
  12008. auto fieldDef = (BfFieldDef*)memberSetEntry->mMemberDef;
  12009. while (fieldDef != NULL)
  12010. {
  12011. BfIdentifierNode* fieldNameNode = NULL;
  12012. if (fieldDef->mIdx < (int)checkMethodState->mClosureState->mClosureInstanceInfo->mCaptureEntries.size())
  12013. fieldNameNode = checkMethodState->mClosureState->mClosureInstanceInfo->mCaptureEntries[fieldDef->mIdx].mNameNode;
  12014. if (fieldNameNode == identifierNode)
  12015. {
  12016. auto& field = closureTypeInst->mFieldInstances[fieldDef->mIdx];
  12017. if (!field.mResolvedType->IsValuelessType())
  12018. {
  12019. if (mModule->mCurMethodState->mClosureState->mCapturing)
  12020. {
  12021. mModule->mCurMethodState->mClosureState->mReferencedOuterClosureMembers.Add(&field);
  12022. return mModule->GetDefaultTypedValue(field.mResolvedType);
  12023. }
  12024. auto localVar = mModule->mCurMethodState->mLocals[0];
  12025. auto thisValue = localVar->mValue;
  12026. mModule->mBfIRBuilder->PopulateType(localVar->mResolvedType);
  12027. BfTypedValue result = BfTypedValue(mModule->mBfIRBuilder->CreateInBoundsGEP(thisValue, 0, field.mDataIdx), field.mResolvedType, true);
  12028. if (field.mResolvedType->IsRef())
  12029. {
  12030. auto refType = (BfRefType*)field.mResolvedType;
  12031. auto underlyingType = refType->GetUnderlyingType();
  12032. result = BfTypedValue(mModule->mBfIRBuilder->CreateAlignedLoad(result.mValue, underlyingType->mAlign), underlyingType, true);
  12033. }
  12034. else if (fieldDef->mIsReadOnly)
  12035. result = mModule->LoadValue(result);
  12036. mResultLocalVar = localVar;
  12037. mResultFieldInstance = &field;
  12038. mResultLocalVarField = -(field.mMergedDataIdx + 1);
  12039. return result;
  12040. }
  12041. }
  12042. fieldDef = fieldDef->mNextWithSameName;
  12043. }
  12044. }
  12045. }
  12046. if ((checkMethodState->mClosureState != NULL) && (checkMethodState->mClosureState->mCapturing) /*&& (checkMethodState->mClosureState->mIsLocalMethod)*/)
  12047. {
  12048. checkMethodState = checkMethodState->mPrevMethodState;
  12049. continue;
  12050. }
  12051. // Allow local mixin to see outside variables during its processing -- since we don't actually "capture" those into params
  12052. bool isLocalMixinProcessing = false;
  12053. if ((checkMethodState->mClosureState != NULL) && (!checkMethodState->mClosureState->mCapturing) && (closureTypeInst == NULL) &&
  12054. (mModule->mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_Mixin))
  12055. isLocalMixinProcessing = true;
  12056. if (!isLocalMixinProcessing)
  12057. break;
  12058. isMixinOuterVariablePass = true;
  12059. checkMethodState = checkMethodState->mPrevMethodState;
  12060. }
  12061. }
  12062. return BfTypedValue();
  12063. }
  12064. BfTypedValue BfExprEvaluator::DoImplicitArgCapture(BfAstNode* refNode, BfMethodInstance* methodInstance, int paramIdx, bool& failed, BfImplicitParamKind paramKind, const BfTypedValue& methodRefTarget)
  12065. {
  12066. if ((methodRefTarget) && (methodRefTarget.mValue.mId != BfIRValue::ID_IMPLICIT))
  12067. {
  12068. if (methodRefTarget.mType->IsMethodRef())
  12069. {
  12070. BfMethodRefType* methodRefType = (BfMethodRefType*)methodRefTarget.mType;
  12071. BfMethodInstance* methodRefMethodInst = methodRefType->mMethodRef;
  12072. BF_ASSERT(methodRefMethodInst == methodInstance);
  12073. auto paramType = methodInstance->GetParamType(paramIdx);
  12074. int dataIdx = methodRefType->GetDataIdxFromParamIdx(paramIdx);
  12075. if (dataIdx == -1)
  12076. {
  12077. BF_ASSERT(paramType->IsValuelessType());
  12078. return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), paramType);
  12079. }
  12080. if (methodRefTarget.IsSplat())
  12081. {
  12082. if (methodRefType->WantsDataPassedAsSplat(dataIdx))
  12083. {
  12084. BF_ASSERT(paramIdx == -1);
  12085. return BfTypedValue(methodRefTarget.mValue, paramType, BfTypedValueKind_SplatHead);
  12086. }
  12087. else
  12088. {
  12089. int splatIdx = dataIdx;
  12090. if (dataIdx > 0)
  12091. {
  12092. if (methodRefType->WantsDataPassedAsSplat(0))
  12093. splatIdx += methodRefType->GetCaptureType(0)->GetSplatCount() - 1;
  12094. }
  12095. bool isAddr = false;
  12096. BfIRValue value = mModule->ExtractSplatValue(methodRefTarget, splatIdx, paramType, &isAddr);
  12097. // We moved the composite load from ExtractSplatValue to here. Hopefully this is correct.
  12098. // in LLVM backend we get a direct 'arg' back, in Beef we get backing for a pointer to the struct (and thus need to load)
  12099. // if ((paramType->IsComposite()) && (mModule->IsTargetingBeefBackend()))
  12100. // value = mModule->mBfIRBuilder->CreateLoad(value);
  12101. auto lookupVal = BfTypedValue(value, paramType, isAddr);
  12102. if ((isAddr) && (!lookupVal.mType->IsComposite()))
  12103. lookupVal = mModule->LoadValue(lookupVal);
  12104. return lookupVal;
  12105. }
  12106. }
  12107. if ((paramType->IsComposite()) && (methodRefTarget.IsAddr()))
  12108. return BfTypedValue(mModule->mBfIRBuilder->CreateInBoundsGEP(methodRefTarget.mValue, 0, dataIdx), paramType, true);
  12109. return BfTypedValue(mModule->ExtractValue(methodRefTarget, dataIdx), paramType);
  12110. }
  12111. }
  12112. // 'Default' implicit arg lookup, by identifier. May match field (for lambda), or local variable
  12113. if (paramKind == BfImplicitParamKind_General)
  12114. {
  12115. if (paramIdx == -1)
  12116. {
  12117. if (auto delegateBindExpr = BfNodeDynCast<BfDelegateBindExpression>(refNode))
  12118. {
  12119. BfAstNode* thisNode = NULL;
  12120. BfTypedValue thisValue;
  12121. if (auto memberReferenceExpr = BfNodeDynCast<BfMemberReferenceExpression>(delegateBindExpr->mTarget))
  12122. thisNode = memberReferenceExpr->mTarget;
  12123. else if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(delegateBindExpr->mTarget))
  12124. thisNode = qualifiedNameNode->mLeft;
  12125. else if (auto identifierNode = BfNodeDynCast<BfIdentifierNode>(delegateBindExpr->mTarget))
  12126. {
  12127. // Implicit
  12128. thisValue = mModule->GetThis();
  12129. }
  12130. if (auto thisExpr = BfNodeDynCast<BfExpression>(thisNode))
  12131. {
  12132. thisValue = mModule->CreateValueFromExpression(thisExpr);
  12133. if (!thisValue)
  12134. return BfTypedValue();
  12135. }
  12136. if (thisValue)
  12137. {
  12138. //TODO: handle 'mut', throw error if trying to capture from a non-mut, etc...
  12139. return thisValue;
  12140. }
  12141. }
  12142. }
  12143. String captureName = methodInstance->GetParamName(paramIdx);
  12144. BfIdentifierNode* identifierNode = methodInstance->GetParamNameNode(paramIdx);
  12145. BfTypedValue lookupVal;
  12146. if (identifierNode != NULL)
  12147. {
  12148. lookupVal = DoImplicitArgCapture(refNode, identifierNode, 0);
  12149. }
  12150. else
  12151. {
  12152. lookupVal = LookupIdentifier(NULL, captureName);
  12153. }
  12154. if (lookupVal)
  12155. {
  12156. auto paramType = methodInstance->GetParamType(paramIdx);
  12157. if (paramType->IsRef())
  12158. {
  12159. auto refType = (BfRefType*)paramType;
  12160. if (mResultLocalVar != NULL)
  12161. {
  12162. // When we are capturing, we need to note that we require capturing by reference here
  12163. auto localVar = mResultLocalVar;
  12164. localVar->mWrittenToId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++;
  12165. }
  12166. bool isValid = false;
  12167. if ((refType->mRefKind == BfRefType::RefKind_Mut) && (lookupVal.mKind == BfTypedValueKind_MutableValue))
  12168. isValid = true;
  12169. if ((lookupVal.mType->IsRef()) || (lookupVal.IsAddr()))
  12170. isValid = true;
  12171. if (!isValid)
  12172. {
  12173. // Is there another way this can fail than to be in a lambda?
  12174. auto error = mModule->Fail(StrFormat("Method '%s' requires that '%s' be captured by reference. Consider adding by-reference capture specifier [&] to lambda.",
  12175. mModule->MethodToString(methodInstance).c_str(), captureName.c_str()), refNode, true);
  12176. if ((error != NULL) && (methodInstance->mMethodDef->mMethodDeclaration != NULL))
  12177. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
  12178. failed = true;
  12179. }
  12180. }
  12181. else
  12182. {
  12183. if (lookupVal.mType->IsRef())
  12184. lookupVal = mModule->RemoveRef(lookupVal);
  12185. if (!lookupVal.mType->IsComposite())
  12186. lookupVal = mModule->LoadValue(lookupVal);
  12187. }
  12188. return lookupVal;
  12189. }
  12190. else
  12191. {
  12192. mModule->Fail(StrFormat("Failed to lookup implicit capture '%s'", captureName.c_str()), refNode, true);
  12193. failed = true;
  12194. return BfTypedValue();
  12195. }
  12196. }
  12197. return BfTypedValue();
  12198. }
  12199. void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
  12200. {
  12201. BfAutoParentNodeEntry autoParentNodeEntry(mModule, delegateBindExpr);
  12202. if (mExpectingType == NULL)
  12203. {
  12204. mModule->Fail("Cannot infer delegate type", delegateBindExpr);
  12205. return;
  12206. }
  12207. BfTokenNode* newToken = NULL;
  12208. BfAllocTarget allocTarget;
  12209. ResolveAllocTarget(allocTarget, delegateBindExpr->mNewToken, newToken);
  12210. SizedArray<BfTypedValueExpression, 4> typedValueExprs;
  12211. SizedArray<BfExpression*, 4> args;
  12212. BfTypeInstance* delegateTypeInstance = NULL;
  12213. BfMethodInstance* methodInstance = NULL;
  12214. const char* bindTypeName = NULL;
  12215. bool isMethodRefMatch = false;
  12216. if (mExpectingType->IsMethodRef())
  12217. {
  12218. auto methodRefType = (BfMethodRefType*)mExpectingType;
  12219. BF_ASSERT(delegateBindExpr->mNewToken == NULL);
  12220. methodInstance = methodRefType->mMethodRef;
  12221. isMethodRefMatch = true;
  12222. }
  12223. else
  12224. {
  12225. if (mExpectingType->IsGenericParam())
  12226. {
  12227. auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)mExpectingType);
  12228. if ((genericParamInstance->mTypeConstraint != NULL) && (genericParamInstance->mTypeConstraint->IsDelegate()))
  12229. {
  12230. delegateTypeInstance = genericParamInstance->mTypeConstraint->ToTypeInstance();
  12231. }
  12232. }
  12233. else
  12234. delegateTypeInstance = mExpectingType->ToTypeInstance();
  12235. if ((delegateTypeInstance == NULL) ||
  12236. ((!delegateTypeInstance->IsDelegate()) && (!delegateTypeInstance->IsFunction())))
  12237. {
  12238. mModule->Fail(StrFormat("Type '%s' cannot be used for method binding. Only delegate or function types are allowed.", mModule->TypeToString(mExpectingType).c_str()), delegateBindExpr);
  12239. return;
  12240. }
  12241. bindTypeName = (delegateTypeInstance->IsDelegate()) ? "delegate" : "function";
  12242. mModule->PopulateType(delegateTypeInstance, BfPopulateType_DataAndMethods);
  12243. methodInstance = mModule->GetRawMethodInstanceAtIdx(delegateTypeInstance, 0, "Invoke");
  12244. if (methodInstance == NULL)
  12245. {
  12246. BF_DBG_FATAL("Invoke not found");
  12247. return;
  12248. }
  12249. if (auto tokenNode = BfNodeDynCast<BfTokenNode>(delegateBindExpr->mNewToken))
  12250. {
  12251. if (delegateTypeInstance->IsFunction())
  12252. mModule->Fail("Function bindings are direct assignments, allocation specifier is not applicable", delegateBindExpr->mNewToken);
  12253. else if (tokenNode->GetToken() == BfToken_Append)
  12254. {
  12255. mModule->Fail("Append allocation on delegate bind not supported", delegateBindExpr->mNewToken);
  12256. }
  12257. }
  12258. }
  12259. int paramOffset = methodInstance->HasExplicitThis() ? 1 : 0;
  12260. typedValueExprs.resize(methodInstance->GetParamCount() - paramOffset);
  12261. args.resize(methodInstance->GetParamCount() - paramOffset);
  12262. for (int i = 0; i < (int)methodInstance->GetParamCount() - paramOffset; i++)
  12263. {
  12264. auto typedValueExpr = &typedValueExprs[i];
  12265. typedValueExpr->mTypedValue.mValue = BfIRValue(BfIRValueFlags_Value, -1);
  12266. typedValueExpr->mTypedValue.mType = methodInstance->GetParamType(i + paramOffset);
  12267. if (methodInstance->GetParamKind(i + paramOffset) == BfParamKind_Params)
  12268. typedValueExpr->mTypedValue.mKind = BfTypedValueKind_Params;
  12269. typedValueExpr->mRefNode = NULL;
  12270. args[i] = typedValueExpr;
  12271. }
  12272. BfMethodGenericArguments methodGenericArgs;
  12273. if (delegateBindExpr->mGenericArgs != NULL)
  12274. methodGenericArgs.mArguments = &delegateBindExpr->mGenericArgs->mGenericArgs;
  12275. if (delegateBindExpr->mTarget == NULL)
  12276. {
  12277. mModule->AssertErrorState();
  12278. return;
  12279. }
  12280. auto autoComplete = GetAutoComplete();
  12281. if (autoComplete != NULL)
  12282. {
  12283. SetAndRestoreValue<bool> prevForceAllowNonStatic(autoComplete->mForceAllowNonStatic, methodInstance->mMethodDef->mHasExplicitThis);
  12284. GetAutoComplete()->CheckNode(delegateBindExpr->mTarget, true);
  12285. }
  12286. if ((!delegateBindExpr->mTarget->IsA<BfIdentifierNode>()) &&
  12287. (!delegateBindExpr->mTarget->IsA<BfMemberReferenceExpression>()))
  12288. {
  12289. mModule->Fail(StrFormat("Invalid %s binding target, %s can only bind to method references. Consider wrapping expression in a lambda.", bindTypeName, bindTypeName), delegateBindExpr->mTarget);
  12290. mModule->CreateValueFromExpression(delegateBindExpr->mTarget);
  12291. return;
  12292. }
  12293. BfFunctionBindResult bindResult;
  12294. bindResult.mSkipMutCheck = true; // Allow operating on copies
  12295. bindResult.mBindType = delegateTypeInstance;
  12296. //
  12297. {
  12298. SetAndRestoreValue<BfType*> prevExpectingType(mExpectingType, methodInstance->mReturnType);
  12299. mFunctionBindResult = &bindResult;
  12300. DoInvocation(delegateBindExpr->mTarget, delegateBindExpr, args, methodGenericArgs);
  12301. mFunctionBindResult = NULL;
  12302. }
  12303. SetMethodElementType(delegateBindExpr->mTarget);
  12304. if (bindResult.mMethodInstance == NULL)
  12305. {
  12306. if ((mResult) && (IsVar(mResult.mType)))
  12307. return;
  12308. mResult = BfTypedValue();
  12309. return;
  12310. }
  12311. if (((bindResult.mMethodInstance->mComptimeFlags & BfComptimeFlag_Comptime) != 0) && ((mModule->mCurMethodInstance->mComptimeFlags & BfComptimeFlag_Comptime) == 0))
  12312. {
  12313. mModule->Fail(StrFormat("Cannot bind to const-eval method '%s', as this method is not available at runtime", mModule->MethodToString(bindResult.mMethodInstance).c_str()), delegateBindExpr->mTarget);
  12314. }
  12315. auto bindMethodInstance = bindResult.mMethodInstance;
  12316. if (isMethodRefMatch)
  12317. {
  12318. // WTF- this was always false, what was it supposed to catch?
  12319. // if (bindMethodInstance != bindResult.mMethodInstance)
  12320. // {
  12321. // mResult = BfTypedValue();
  12322. // return;
  12323. // }
  12324. }
  12325. else
  12326. {
  12327. bool isExactMethodMatch = IsExactMethodMatch(methodInstance, bindMethodInstance, true);
  12328. if ((mExpectingType != NULL) && (mExpectingType->IsFunction()) && (methodInstance->mMethodDef->mIsMutating != bindMethodInstance->mMethodDef->mIsMutating))
  12329. isExactMethodMatch = false;
  12330. if (!isExactMethodMatch)
  12331. {
  12332. if (bindResult.mCheckedMultipleMethods)
  12333. {
  12334. mModule->Fail(StrFormat("No overload for '%s' matches %s '%s'", bindMethodInstance->mMethodDef->mName.c_str(), bindTypeName,
  12335. mModule->TypeToString(delegateTypeInstance).c_str()), delegateBindExpr->mTarget);
  12336. }
  12337. else
  12338. {
  12339. mModule->Fail(StrFormat("Method '%s' does not match %s '%s'", mModule->MethodToString(bindMethodInstance, (BfMethodNameFlags)(BfMethodNameFlag_ResolveGenericParamNames | BfMethodNameFlag_IncludeReturnType | BfMethodNameFlag_IncludeMut)).c_str(), bindTypeName,
  12340. mModule->TypeToString(delegateTypeInstance).c_str()), delegateBindExpr->mTarget);
  12341. }
  12342. mResult = BfTypedValue();
  12343. return;
  12344. }
  12345. }
  12346. bool isDirectFunction = false;
  12347. if ((bindResult.mMethodInstance->GetOwner()->IsFunction()) && (bindResult.mFunc))
  12348. isDirectFunction = true;
  12349. if (bindMethodInstance->mIsIntrinsic)
  12350. {
  12351. mModule->Fail(StrFormat("Method '%s' is an intrinsic and therefore cannot be used as a method binding target. Intrinsics have no addresses.", mModule->MethodToString(bindMethodInstance).c_str()), delegateBindExpr->mTarget);
  12352. mResult = BfTypedValue();
  12353. return;
  12354. }
  12355. bool hasIncompatibleCallingConventions = !mModule->mSystem->IsCompatibleCallingConvention(methodInstance->mCallingConvention, bindMethodInstance->mCallingConvention);
  12356. auto _GetInvokeMethodName = [&]()
  12357. {
  12358. StringT<512> methodName = "Invoke$";
  12359. methodName += mModule->mCurMethodInstance->mMethodDef->mName;
  12360. int prevSepPos = (int)methodName.LastIndexOf('$');
  12361. if (prevSepPos > 6)
  12362. {
  12363. methodName.RemoveToEnd(prevSepPos);
  12364. }
  12365. auto rootMethodState = mModule->mCurMethodState->GetRootMethodState();
  12366. HashContext hashCtx;
  12367. if (mModule->mCurMethodInstance->mMethodDef->mDeclaringType->mPartialIdx != -1)
  12368. hashCtx.Mixin(mModule->mCurMethodInstance->mMethodDef->mDeclaringType->mPartialIdx);
  12369. if (delegateBindExpr->mFatArrowToken != NULL)
  12370. {
  12371. hashCtx.Mixin(delegateBindExpr->mFatArrowToken->GetStartCharId());
  12372. }
  12373. if (rootMethodState->mMethodInstance->mMethodInfoEx != NULL)
  12374. {
  12375. for (auto methodGenericArg : rootMethodState->mMethodInstance->mMethodInfoEx->mMethodGenericArguments)
  12376. {
  12377. StringT<128> genericTypeName;
  12378. BfMangler::Mangle(genericTypeName, mModule->mCompiler->GetMangleKind(), methodGenericArg);
  12379. hashCtx.MixinStr(genericTypeName);
  12380. }
  12381. }
  12382. Val128 hashVal = hashCtx.Finish128();
  12383. methodName += '$';
  12384. methodName += BfTypeUtils::HashEncode64(hashVal.mLow);
  12385. StringT<512> mangledName;
  12386. BfMangler::MangleMethodName(mangledName, mModule->mCompiler->GetMangleKind(), mModule->mCurTypeInstance, methodName);
  12387. return mangledName;
  12388. };
  12389. if ((delegateBindExpr->mNewToken == NULL) || (delegateTypeInstance->IsFunction()))
  12390. {
  12391. if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mHotDataReferenceBuilder != NULL))
  12392. {
  12393. BF_ASSERT(bindResult.mMethodInstance->mHotMethod != NULL);
  12394. mModule->mCurMethodState->mHotDataReferenceBuilder->mFunctionPtrs.Add(bindResult.mMethodInstance->mHotMethod);
  12395. }
  12396. if (isDirectFunction)
  12397. {
  12398. //if ((delegateTypeInstance != NULL) && (delegateTypeInstance->IsFunction()))
  12399. if (mExpectingType->IsFunction())
  12400. {
  12401. auto intPtrVal = mModule->mBfIRBuilder->CreatePtrToInt(bindResult.mFunc, BfTypeCode_IntPtr);
  12402. mResult = BfTypedValue(intPtrVal, mExpectingType);
  12403. return;
  12404. }
  12405. }
  12406. if (mExpectingType->IsFunction())
  12407. {
  12408. BfIRValue result;
  12409. if ((hasIncompatibleCallingConventions) && (mModule->HasExecutedOutput()))
  12410. {
  12411. //
  12412. {
  12413. SetAndRestoreValue<bool> prevIgnore(mModule->mBfIRBuilder->mIgnoreWrites, true);
  12414. result = mModule->CastToFunction(delegateBindExpr->mTarget, bindResult.mOrigTarget, bindResult.mMethodInstance, mExpectingType);
  12415. }
  12416. if (result)
  12417. {
  12418. String methodName = _GetInvokeMethodName();
  12419. SizedArray<BfIRType, 8> irParamTypes;
  12420. BfIRType irReturnType;
  12421. methodInstance->GetIRFunctionInfo(mModule, irReturnType, irParamTypes);
  12422. int thisFuncParamIdx = methodInstance->GetThisIdx();
  12423. int thisBindParamIdx = methodInstance->GetThisIdx();
  12424. auto prevActiveFunction = mModule->mBfIRBuilder->GetActiveFunction();
  12425. auto prevInsertBlock = mModule->mBfIRBuilder->GetInsertBlock();
  12426. mModule->mBfIRBuilder->SaveDebugLocation();
  12427. auto funcType = mModule->mBfIRBuilder->CreateFunctionType(irReturnType, irParamTypes);
  12428. auto funcValue = mModule->mBfIRBuilder->CreateFunction(funcType, BfIRLinkageType_External, methodName);
  12429. auto srcCallingConv = mModule->GetIRCallingConvention(methodInstance);
  12430. mModule->mBfIRBuilder->SetFuncCallingConv(funcValue, srcCallingConv);
  12431. mModule->mBfIRBuilder->SetActiveFunction(funcValue);
  12432. auto entryBlock = mModule->mBfIRBuilder->CreateBlock("entry", true);
  12433. mModule->mBfIRBuilder->SetInsertPoint(entryBlock);
  12434. SizedArray<BfIRValue, 8> irArgs;
  12435. for (int paramIdx = 0; paramIdx < irParamTypes.size(); paramIdx++)
  12436. {
  12437. irArgs.push_back(mModule->mBfIRBuilder->GetArgument(paramIdx));
  12438. }
  12439. auto bindFuncVal = bindResult.mFunc;
  12440. if ((mModule->mCompiler->mOptions.mAllowHotSwapping) && (!mModule->mIsComptimeModule))
  12441. bindFuncVal = mModule->mBfIRBuilder->RemapBindFunction(bindFuncVal);
  12442. auto callResult = mModule->mBfIRBuilder->CreateCall(bindFuncVal, irArgs);
  12443. auto destCallingConv = mModule->GetIRCallingConvention(bindMethodInstance);
  12444. if (destCallingConv != BfIRCallingConv_CDecl)
  12445. mModule->mBfIRBuilder->SetCallCallingConv(callResult, destCallingConv);
  12446. if (methodInstance->mReturnType->IsValuelessType())
  12447. mModule->mBfIRBuilder->CreateRetVoid();
  12448. else
  12449. mModule->mBfIRBuilder->CreateRet(callResult);
  12450. mModule->mBfIRBuilder->SetActiveFunction(prevActiveFunction);
  12451. mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock);
  12452. mModule->mBfIRBuilder->RestoreDebugLocation();
  12453. result = mModule->mBfIRBuilder->CreatePtrToInt(funcValue, BfTypeCode_IntPtr);
  12454. }
  12455. }
  12456. else
  12457. {
  12458. if ((bindResult.mOrigTarget) && (bindResult.mOrigTarget.mType->IsGenericParam()) && (bindResult.mMethodInstance->GetOwner()->IsInterface()))
  12459. {
  12460. bool matching = true;
  12461. if (methodInstance->HasExplicitThis())
  12462. {
  12463. auto thisType = methodInstance->GetParamType(0);
  12464. if (thisType->IsPointer())
  12465. thisType = thisType->GetUnderlyingType();
  12466. if (thisType->IsRef())
  12467. thisType = thisType->GetUnderlyingType();
  12468. matching = thisType == bindResult.mOrigTarget.mType;
  12469. }
  12470. if (matching)
  12471. {
  12472. mResult = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), mExpectingType);
  12473. return;
  12474. }
  12475. }
  12476. result = mModule->CastToFunction(delegateBindExpr->mTarget, bindResult.mOrigTarget, bindResult.mMethodInstance, mExpectingType, BfCastFlags_None, bindResult.mFunc);
  12477. }
  12478. if (result)
  12479. mResult = BfTypedValue(result, mExpectingType);
  12480. return;
  12481. }
  12482. if (bindResult.mMethodInstance->mDisallowCalling)
  12483. {
  12484. BF_ASSERT(mModule->mBfIRBuilder->mIgnoreWrites);
  12485. mResult = mModule->GetDefaultTypedValue(mExpectingType, false, BfDefaultValueKind_Addr);
  12486. return;
  12487. }
  12488. auto methodRefType = mModule->CreateMethodRefType(bindResult.mMethodInstance);
  12489. mModule->AddDependency(methodRefType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_Calls);
  12490. mModule->AddCallDependency(bindResult.mMethodInstance);
  12491. if ((bindResult.mOrigTarget) && (bindResult.mOrigTarget.mType->IsMethodRef()))
  12492. {
  12493. mResult = bindResult.mOrigTarget;
  12494. }
  12495. else
  12496. {
  12497. if ((bindResult.mMethodInstance->mMethodDef->mIsLocalMethod) || (!bindResult.mTarget))
  12498. mResult = BfTypedValue(BfIRValue(BfIRValueFlags_Value, BfIRValue::ID_IMPLICIT), methodRefType);
  12499. else
  12500. {
  12501. auto methodRefPtr = mModule->CreateAlloca(methodRefType, "bindResult");
  12502. auto elemPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(methodRefPtr, 0, 0);
  12503. BfTypedValue target;
  12504. if (bindResult.mTarget.IsSplat())
  12505. target = mModule->AggregateSplat(bindResult.mTarget, &bindResult.mIRArgs[0]);
  12506. else
  12507. target = bindResult.mTarget;
  12508. mModule->mBfIRBuilder->CreateStore(target.mValue, elemPtr);
  12509. mResult = BfTypedValue(methodRefPtr, methodRefType, true);
  12510. }
  12511. }
  12512. return;
  12513. }
  12514. int implicitParamCount = bindMethodInstance->GetImplicitParamCount();
  12515. BfTypeInstance* useTypeInstance = delegateTypeInstance;
  12516. BfClosureType* closureTypeInst = NULL;
  12517. auto origTarget = bindResult.mOrigTarget;
  12518. auto target = bindResult.mTarget;
  12519. BfTypedValue methodRefTarget;
  12520. if ((bindResult.mOrigTarget) && (bindResult.mOrigTarget.mType->IsMethodRef()))
  12521. methodRefTarget = bindResult.mOrigTarget;
  12522. bool isStructTarget = (target) && (target.mType->IsStruct());
  12523. bool bindCapturesThis = bindMethodInstance->HasThis() && !isStructTarget;
  12524. bool needsSplat = (isStructTarget) && (!bindMethodInstance->mMethodDef->mIsMutating) && (bindMethodInstance->AllowsSplatting(-1));
  12525. bool captureThisByValue = isStructTarget;
  12526. if (bindMethodInstance->mMethodDef->mIsLocalMethod)
  12527. {
  12528. // Local method captures always capture 'this' by reference
  12529. captureThisByValue = false;
  12530. }
  12531. if ((origTarget.mType != NULL) &&
  12532. ((origTarget.mType->IsRef()) || (origTarget.mType->IsPointer())))
  12533. {
  12534. captureThisByValue = false;
  12535. }
  12536. if (methodRefTarget)
  12537. BF_ASSERT(methodRefTarget.mType->IsMethodRef());
  12538. if (target.IsSplat())
  12539. target = mModule->AggregateSplat(target, &bindResult.mIRArgs[0]);
  12540. bool hasCaptures = false;
  12541. // Do we need a special delegate type for this?
  12542. if (((captureThisByValue) || (needsSplat) || (implicitParamCount > 0) /*|| (hasIncompatibleCallingConventions)*/) &&
  12543. (mModule->HasExecutedOutput()))
  12544. {
  12545. hasCaptures = true;
  12546. auto curProject = mModule->mCurTypeInstance->mTypeDef->mProject;
  12547. if (captureThisByValue)
  12548. target = mModule->LoadValue(target);
  12549. String delegateTypeName = mModule->TypeToString(delegateTypeInstance);
  12550. HashContext hashCtx;
  12551. hashCtx.MixinStr(delegateTypeName);
  12552. // We mix in the project for reasons described in the lambda binding handler
  12553. hashCtx.MixinStr(curProject->mName);
  12554. String structTargetTypeName;
  12555. String structTargetName;
  12556. // Implicit param separator
  12557. for (int implicitParamIdx = bindMethodInstance->HasThis() ? - 1 : 0; implicitParamIdx < implicitParamCount; implicitParamIdx++)
  12558. {
  12559. auto paramType = bindResult.mMethodInstance->GetParamType(implicitParamIdx);
  12560. if ((implicitParamIdx == -1) && (captureThisByValue))
  12561. {
  12562. if (paramType->IsPointer())
  12563. paramType = paramType->GetUnderlyingType();
  12564. }
  12565. structTargetTypeName = mModule->TypeToString(paramType);
  12566. structTargetName = bindResult.mMethodInstance->GetParamName(implicitParamIdx);
  12567. hashCtx.MixinStr(structTargetTypeName);
  12568. hashCtx.MixinStr(structTargetName);
  12569. }
  12570. Val128 hash128 = hashCtx.Finish128();
  12571. BfClosureType* checkClosureType = new BfClosureType(delegateTypeInstance, hash128);
  12572. checkClosureType->mContext = mModule->mContext;
  12573. checkClosureType->mBaseType = delegateTypeInstance;
  12574. BfType* resolvedClosureType = mModule->ResolveType(checkClosureType, BfPopulateType_TypeDef);
  12575. closureTypeInst = (BfClosureType*)resolvedClosureType;
  12576. if (checkClosureType == resolvedClosureType)
  12577. {
  12578. // This is a new closure type
  12579. closureTypeInst->Init(curProject);
  12580. for (int implicitParamIdx = bindMethodInstance->HasThis() ? -1 : 0; implicitParamIdx < implicitParamCount; implicitParamIdx++)
  12581. {
  12582. String fieldName = bindResult.mMethodInstance->GetParamName(implicitParamIdx);
  12583. BfType* paramType = bindResult.mMethodInstance->GetParamType(implicitParamIdx);
  12584. if ((implicitParamIdx == -1) && (captureThisByValue))
  12585. {
  12586. if (paramType->IsPointer())
  12587. paramType = paramType->GetUnderlyingType();
  12588. }
  12589. if (fieldName == "this")
  12590. fieldName = "__this";
  12591. closureTypeInst->AddField(paramType, fieldName);
  12592. }
  12593. closureTypeInst->Finish();
  12594. mModule->PopulateType(resolvedClosureType, BfPopulateType_Declaration);
  12595. }
  12596. else
  12597. {
  12598. // Already had this entry
  12599. delete checkClosureType;
  12600. }
  12601. useTypeInstance = closureTypeInst;
  12602. }
  12603. mModule->PopulateType(useTypeInstance);
  12604. if (delegateBindExpr->mTarget == NULL)
  12605. {
  12606. mModule->AssertErrorState();
  12607. return;
  12608. }
  12609. mResult = BfTypedValue(mModule->AllocFromType(useTypeInstance, allocTarget, BfIRValue(), BfIRValue(), 0, BfAllocFlags_None), useTypeInstance);
  12610. // Do we need specialized calling code for this?
  12611. BfIRValue funcValue;
  12612. if (((needsSplat) || (implicitParamCount > 0) || (hasIncompatibleCallingConventions)) &&
  12613. (mModule->HasExecutedOutput()))
  12614. {
  12615. int fieldIdx = 0;
  12616. for (int implicitParamIdx = bindMethodInstance->HasThis() ? -1 : 0; implicitParamIdx < implicitParamCount; implicitParamIdx++)
  12617. {
  12618. auto fieldInst = &useTypeInstance->mFieldInstances[fieldIdx];
  12619. int gepIdx = fieldInst->mDataIdx;
  12620. auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(mResult.mValue, 0, gepIdx);
  12621. auto fieldType = bindMethodInstance->GetParamType(implicitParamIdx);
  12622. if ((implicitParamIdx == -1) && (captureThisByValue))
  12623. {
  12624. if (fieldType->IsPointer())
  12625. fieldType = fieldType->GetUnderlyingType();
  12626. }
  12627. bool failed = false;
  12628. BfTypedValue lookupVal;
  12629. if (implicitParamIdx == -1)
  12630. lookupVal = target;
  12631. else
  12632. lookupVal = DoImplicitArgCapture(delegateBindExpr->mTarget, bindResult.mMethodInstance, implicitParamIdx, failed, BfImplicitParamKind_General, methodRefTarget);
  12633. if (!lookupVal)
  12634. continue;
  12635. if ((fieldType->IsPointer()) && (lookupVal.mType != fieldType))
  12636. {
  12637. BF_ASSERT(fieldType->GetUnderlyingType() == lookupVal.mType);
  12638. BF_ASSERT(lookupVal.IsAddr());
  12639. }
  12640. else if (!fieldType->IsRef())
  12641. lookupVal = mModule->LoadOrAggregateValue(lookupVal);
  12642. if (lookupVal)
  12643. mModule->mBfIRBuilder->CreateStore(lookupVal.mValue, fieldPtr);
  12644. fieldIdx++;
  12645. }
  12646. String methodName = _GetInvokeMethodName();
  12647. SizedArray<BfIRType, 8> irParamTypes;
  12648. BfIRType irReturnType;
  12649. bool hasThis = false;
  12650. if (hasCaptures)
  12651. {
  12652. hasThis = true;
  12653. methodInstance->GetIRFunctionInfo(mModule, irReturnType, irParamTypes);
  12654. int thisIdx = 0;
  12655. if (GetStructRetIdx(methodInstance) == 0)
  12656. thisIdx = 1;
  12657. irParamTypes[thisIdx] = mModule->mBfIRBuilder->MapType(useTypeInstance);
  12658. }
  12659. else
  12660. {
  12661. BF_ASSERT(hasIncompatibleCallingConventions);
  12662. bindMethodInstance->GetIRFunctionInfo(mModule, irReturnType, irParamTypes);
  12663. hasThis = bindMethodInstance->HasThis();
  12664. }
  12665. auto prevActiveFunction = mModule->mBfIRBuilder->GetActiveFunction();
  12666. auto prevInsertBlock = mModule->mBfIRBuilder->GetInsertBlock();
  12667. mModule->mBfIRBuilder->SaveDebugLocation();
  12668. auto funcType = mModule->mBfIRBuilder->CreateFunctionType(irReturnType, irParamTypes);
  12669. funcValue = mModule->mBfIRBuilder->CreateFunction(funcType, BfIRLinkageType_External, methodName);
  12670. if (GetStructRetIdx(methodInstance) != -1)
  12671. {
  12672. mModule->mBfIRBuilder->Func_AddAttribute(funcValue, GetStructRetIdx(methodInstance) + 1, BfIRAttribute_NoAlias);
  12673. mModule->mBfIRBuilder->Func_AddAttribute(funcValue, GetStructRetIdx(methodInstance) + 1, BfIRAttribute_StructRet);
  12674. }
  12675. auto srcCallingConv = mModule->GetIRCallingConvention(methodInstance);
  12676. if ((!hasThis) && (methodInstance->mCallingConvention == BfCallingConvention_Stdcall))
  12677. srcCallingConv = BfIRCallingConv_StdCall;
  12678. else if (methodInstance->mCallingConvention == BfCallingConvention_Fastcall)
  12679. srcCallingConv = BfIRCallingConv_FastCall;
  12680. mModule->mBfIRBuilder->SetFuncCallingConv(funcValue, srcCallingConv);
  12681. mModule->mBfIRBuilder->SetActiveFunction(funcValue);
  12682. auto entryBlock = mModule->mBfIRBuilder->CreateBlock("entry", true);
  12683. mModule->mBfIRBuilder->SetInsertPoint(entryBlock);
  12684. fieldIdx = 0;
  12685. SizedArray<BfIRValue, 8> irArgs;
  12686. int argIdx = 0;
  12687. if (GetStructRetIdx(bindMethodInstance) == 0)
  12688. {
  12689. irArgs.push_back(mModule->mBfIRBuilder->GetArgument(GetStructRetIdx(methodInstance)));
  12690. argIdx++;
  12691. }
  12692. for (int implicitParamIdx = bindMethodInstance->HasThis() ? -1 : 0; implicitParamIdx < implicitParamCount; implicitParamIdx++)
  12693. {
  12694. auto fieldInst = &useTypeInstance->mFieldInstances[fieldIdx];
  12695. int gepIdx = fieldInst->mDataIdx;
  12696. auto fieldType = bindMethodInstance->GetParamType(implicitParamIdx);
  12697. bool disableSplat = false;
  12698. if ((implicitParamIdx == -1) && (captureThisByValue))
  12699. {
  12700. if (fieldType->IsPointer())
  12701. {
  12702. fieldType = fieldType->GetUnderlyingType();
  12703. disableSplat = true;
  12704. }
  12705. }
  12706. int thisIdx = 0;
  12707. if (GetStructRetIdx(methodInstance) == 0)
  12708. thisIdx = 1;
  12709. auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(mModule->mBfIRBuilder->GetArgument(thisIdx), 0, gepIdx);
  12710. BfTypedValue typedVal(fieldPtr, fieldType, true);
  12711. PushArg(typedVal, irArgs, disableSplat);
  12712. fieldIdx++;
  12713. }
  12714. if (hasThis)
  12715. argIdx++;
  12716. if (GetStructRetIdx(bindMethodInstance) == 1)
  12717. {
  12718. irArgs.push_back(mModule->mBfIRBuilder->GetArgument(GetStructRetIdx(methodInstance)));
  12719. argIdx++;
  12720. }
  12721. for (int paramIdx = 0; paramIdx < methodInstance->GetParamCount(); paramIdx++)
  12722. {
  12723. auto paramType = methodInstance->GetParamType(paramIdx);
  12724. if ((paramType->IsSplattable()) && (!IsComptime()))
  12725. {
  12726. BfTypeUtils::SplatIterate([&](BfType* checkType) { irArgs.push_back(mModule->mBfIRBuilder->GetArgument(argIdx++)); }, paramType);
  12727. }
  12728. else if (!paramType->IsValuelessType())
  12729. {
  12730. irArgs.push_back(mModule->mBfIRBuilder->GetArgument(argIdx++));
  12731. }
  12732. }
  12733. auto bindFuncVal = bindResult.mFunc;
  12734. if ((mModule->mCompiler->mOptions.mAllowHotSwapping) && (!mModule->mIsComptimeModule))
  12735. bindFuncVal = mModule->mBfIRBuilder->RemapBindFunction(bindFuncVal);
  12736. auto callInst = mModule->mBfIRBuilder->CreateCall(bindFuncVal, irArgs);
  12737. if (GetStructRetIdx(bindMethodInstance) != -1)
  12738. mModule->mBfIRBuilder->Call_AddAttribute(callInst, GetStructRetIdx(bindMethodInstance) + 1, BfIRAttribute_StructRet);
  12739. auto destCallingConv = mModule->GetIRCallingConvention(bindMethodInstance);
  12740. if (destCallingConv != BfIRCallingConv_CDecl)
  12741. mModule->mBfIRBuilder->SetCallCallingConv(callInst, destCallingConv);
  12742. if ((methodInstance->mReturnType->IsValuelessType()) || (GetStructRetIdx(methodInstance) != -1))
  12743. {
  12744. mModule->mBfIRBuilder->CreateRetVoid();
  12745. }
  12746. else
  12747. {
  12748. mModule->mBfIRBuilder->CreateRet(callInst);
  12749. }
  12750. mModule->mBfIRBuilder->SetActiveFunction(prevActiveFunction);
  12751. mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock);
  12752. mModule->mBfIRBuilder->RestoreDebugLocation();
  12753. }
  12754. else if ((closureTypeInst != NULL) && (captureThisByValue))
  12755. {
  12756. // When we need to aggregrate a splat for a target, we just point out delegate's mTarget to inside ourselves where we aggregated the value
  12757. int dataIdx = 1;
  12758. if (!closureTypeInst->mFieldInstances.IsEmpty())
  12759. {
  12760. auto& fieldInst = closureTypeInst->mFieldInstances[0];
  12761. BF_ASSERT(fieldInst.GetFieldDef()->mName == "__this");
  12762. dataIdx = fieldInst.mDataIdx;
  12763. }
  12764. auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(mResult.mValue, 0, dataIdx);
  12765. target = mModule->LoadValue(target);
  12766. mModule->mBfIRBuilder->CreateStore(target.mValue, fieldPtr);
  12767. target = BfTypedValue(fieldPtr, target.mType, true);
  12768. }
  12769. BfResolvedArgs resolvedArgs;
  12770. MatchConstructor(delegateBindExpr, delegateBindExpr, mResult, useTypeInstance, resolvedArgs, false, BfMethodGenericArguments(), BfAllowAppendKind_No);
  12771. auto baseDelegateType = VerifyBaseDelegateType(delegateTypeInstance->mBaseType);
  12772. auto baseDelegate = mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->MapType(baseDelegateType, BfIRPopulateType_Full));
  12773. // >> delegate.mTarget = bindResult.mTarget
  12774. BfIRValue valPtr;
  12775. if (mModule->HasExecutedOutput())
  12776. {
  12777. if ((implicitParamCount > 0) || (needsSplat)) // Point back to self, it contains capture data
  12778. valPtr = mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->GetPrimitiveType(BfTypeCode_NullPtr));
  12779. else if (bindResult.mTarget)
  12780. {
  12781. if ((target.mType->IsObjectOrInterface()) &&
  12782. (mModule->mCompiler->mOptions.mObjectHasDebugFlags) && (!mModule->mIsComptimeModule) &&
  12783. (mModule->mCompiler->mSystem->mPtrSize == 8))
  12784. {
  12785. auto numVal = mModule->mBfIRBuilder->CreatePtrToInt(target.mValue, BfTypeCode_UInt64);
  12786. auto orVal = mModule->mBfIRBuilder->CreateOr(numVal, mModule->mBfIRBuilder->CreateConst(BfTypeCode_UInt64, (uint64)0x8000000000000000ULL));
  12787. valPtr = mModule->mBfIRBuilder->CreateIntToPtr(orVal, mModule->mBfIRBuilder->GetPrimitiveType(BfTypeCode_NullPtr));
  12788. }
  12789. else
  12790. valPtr = mModule->mBfIRBuilder->CreateBitCast(target.mValue, mModule->mBfIRBuilder->GetPrimitiveType(BfTypeCode_NullPtr));
  12791. }
  12792. else
  12793. valPtr = mModule->GetDefaultValue(mModule->GetPrimitiveType(BfTypeCode_NullPtr));
  12794. auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(baseDelegate, 0, 2);
  12795. mModule->mBfIRBuilder->CreateStore(valPtr, fieldPtr);
  12796. }
  12797. if (!funcValue)
  12798. {
  12799. funcValue = bindResult.mFunc;
  12800. if (!funcValue)
  12801. {
  12802. if ((mModule->HasExecutedOutput()) && (!mModule->mBfIRBuilder->mIgnoreWrites))
  12803. mModule->AssertErrorState();
  12804. return;
  12805. }
  12806. if ((mModule->mCompiler->mOptions.mAllowHotSwapping) && (!bindResult.mMethodInstance->mMethodDef->mIsVirtual) && (!mModule->mIsComptimeModule))
  12807. {
  12808. funcValue = mModule->mBfIRBuilder->RemapBindFunction(funcValue);
  12809. }
  12810. }
  12811. // >> delegate.mFuncPtr = bindResult.mFunc
  12812. auto nullPtrType = mModule->GetPrimitiveType(BfTypeCode_NullPtr);
  12813. valPtr = mModule->mBfIRBuilder->CreateBitCast(funcValue, mModule->mBfIRBuilder->MapType(nullPtrType));
  12814. auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(baseDelegate, 0, 1);
  12815. mModule->mBfIRBuilder->CreateStore(valPtr, fieldPtr);
  12816. }
  12817. void BfExprEvaluator::VisitLambdaBodies(BfAstNode* body, BfFieldDtorDeclaration* fieldDtor)
  12818. {
  12819. if (auto blockBody = BfNodeDynCast<BfBlock>(body))
  12820. mModule->VisitChild(blockBody);
  12821. else if (auto bodyExpr = BfNodeDynCast<BfExpression>(body))
  12822. {
  12823. auto result = mModule->CreateValueFromExpression(bodyExpr);
  12824. if ((result) && (mModule->mCurMethodState->mClosureState != NULL) &&
  12825. (mModule->mCurMethodState->mClosureState->mReturnTypeInferState == BfReturnTypeInferState_Inferring))
  12826. mModule->mCurMethodState->mClosureState->mReturnType = result.mType;
  12827. }
  12828. while (fieldDtor != NULL)
  12829. {
  12830. mModule->mCurMethodState->mLeftBlockUncond = false;
  12831. mModule->VisitChild(fieldDtor->mBody);
  12832. fieldDtor = fieldDtor->mNextFieldDtor;
  12833. }
  12834. }
  12835. BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lambdaBindExpr, BfAllocTarget& allocTarget)
  12836. {
  12837. if (mModule->mCurMethodState == NULL)
  12838. return NULL;
  12839. auto rootMethodState = mModule->mCurMethodState->GetRootMethodState();
  12840. BfAstNodeList cacheNodeList;
  12841. cacheNodeList.mList.Add(lambdaBindExpr);
  12842. ///
  12843. {
  12844. auto checkMethodState = mModule->mCurMethodState;
  12845. while (checkMethodState != NULL)
  12846. {
  12847. if (checkMethodState->mMixinState != NULL)
  12848. cacheNodeList.mList.Add(checkMethodState->mMixinState->mSource);
  12849. checkMethodState = checkMethodState->mPrevMethodState;
  12850. }
  12851. }
  12852. bool isInferReturnType = (mBfEvalExprFlags & BfEvalExprFlags_InferReturnType) != 0;
  12853. BfLambdaInstance* lambdaInstance = NULL;
  12854. if ((!isInferReturnType) && (rootMethodState->mLambdaCache.TryGetValue(cacheNodeList, &lambdaInstance)))
  12855. return lambdaInstance;
  12856. static int sBindCount = 0;
  12857. sBindCount++;
  12858. bool isFunctionBind = false;
  12859. BfTypeInstance* delegateTypeInstance = NULL;
  12860. BfMethodInstance* invokeMethodInstance = NULL;
  12861. if (mExpectingType == NULL)
  12862. {
  12863. mModule->Fail("Cannot infer delegate type", lambdaBindExpr);
  12864. delegateTypeInstance = mModule->ResolveTypeDef(mModule->mCompiler->mActionTypeDef)->ToTypeInstance();
  12865. }
  12866. else
  12867. {
  12868. delegateTypeInstance = mExpectingType->ToTypeInstance();
  12869. if ((delegateTypeInstance == NULL) ||
  12870. ((!delegateTypeInstance->mTypeDef->mIsDelegate) && (!delegateTypeInstance->mTypeDef->mIsFunction)))
  12871. {
  12872. if (lambdaBindExpr->mFatArrowToken != NULL)
  12873. mModule->Fail("Can only bind lambdas to delegate types", lambdaBindExpr->mFatArrowToken);
  12874. delegateTypeInstance = mModule->ResolveTypeDef(mModule->mCompiler->mActionTypeDef)->ToTypeInstance();
  12875. }
  12876. else
  12877. {
  12878. invokeMethodInstance = mModule->GetRawMethodInstanceAtIdx(delegateTypeInstance, 0, "Invoke");
  12879. }
  12880. isFunctionBind = delegateTypeInstance->mTypeDef->mIsFunction;
  12881. }
  12882. if (auto tokenNode = BfNodeDynCast<BfTokenNode>(lambdaBindExpr->mNewToken))
  12883. {
  12884. if (isFunctionBind)
  12885. {
  12886. mModule->Fail("Function lambda binding does not require allocation", lambdaBindExpr->mNewToken);
  12887. }
  12888. else if (tokenNode->GetToken() == BfToken_Append)
  12889. {
  12890. mModule->Fail("Append allocation on delegate bind not supported", lambdaBindExpr->mNewToken);
  12891. }
  12892. }
  12893. if (invokeMethodInstance != NULL)
  12894. {
  12895. if ((int)lambdaBindExpr->mParams.size() < invokeMethodInstance->GetParamCount())
  12896. {
  12897. BfAstNode* refNode = lambdaBindExpr->mCloseParen;
  12898. if (refNode == NULL)
  12899. refNode = lambdaBindExpr;
  12900. mModule->Fail(StrFormat("Not enough parameters for delegate type '%s'. Expected %d more.",
  12901. mModule->TypeToString(delegateTypeInstance).c_str(), invokeMethodInstance->GetParamCount() - lambdaBindExpr->mParams.size()), refNode);
  12902. }
  12903. else if ((int)lambdaBindExpr->mParams.size() > invokeMethodInstance->GetParamCount())
  12904. {
  12905. BfAstNode* refNode = lambdaBindExpr->mParams[invokeMethodInstance->GetParamCount()];
  12906. mModule->Fail(StrFormat("Too many parameters for delegate type '%s'. Expected %d fewer.",
  12907. mModule->TypeToString(delegateTypeInstance).c_str(), lambdaBindExpr->mParams.size() - invokeMethodInstance->GetParamCount()), refNode);
  12908. }
  12909. }
  12910. auto autoComplete = GetAutoComplete();
  12911. bool wasCapturingMethodInfo = false;
  12912. if ((autoComplete != NULL) && (invokeMethodInstance != NULL))
  12913. {
  12914. wasCapturingMethodInfo = autoComplete->mIsCapturingMethodMatchInfo;
  12915. bool isAutocompleteNode = false;
  12916. if (lambdaBindExpr->mFatArrowToken != NULL)
  12917. {
  12918. if (autoComplete->IsAutocompleteNode(lambdaBindExpr, lambdaBindExpr->mFatArrowToken))
  12919. isAutocompleteNode = true;
  12920. }
  12921. else if (autoComplete->IsAutocompleteNode(lambdaBindExpr))
  12922. isAutocompleteNode = true;
  12923. if (isAutocompleteNode)
  12924. autoComplete->CheckInvocation(lambdaBindExpr, lambdaBindExpr->mOpenParen, lambdaBindExpr->mCloseParen, lambdaBindExpr->mCommas);
  12925. if (autoComplete->mIsCapturingMethodMatchInfo)
  12926. {
  12927. autoComplete->mMethodMatchInfo->mInstanceList.Clear();
  12928. auto methodMatchInfo = autoComplete->mMethodMatchInfo;
  12929. BfAutoComplete::MethodMatchEntry methodMatchEntry;
  12930. methodMatchEntry.mTypeInstance = invokeMethodInstance->GetOwner();
  12931. methodMatchEntry.mCurMethodInstance = mModule->mCurMethodInstance;
  12932. methodMatchEntry.mMethodDef = invokeMethodInstance->mMethodDef;
  12933. autoComplete->mMethodMatchInfo->mInstanceList.push_back(methodMatchEntry);
  12934. methodMatchInfo->mBestIdx = 0;
  12935. methodMatchInfo->mMostParamsMatched = 0;
  12936. int cursorIdx = lambdaBindExpr->GetParser()->mCursorIdx;
  12937. if ((lambdaBindExpr->mCloseParen == NULL) || (cursorIdx <= lambdaBindExpr->mCloseParen->GetSrcStart()))
  12938. {
  12939. int paramIdx = 0;
  12940. for (int commaIdx = 0; commaIdx < (int)lambdaBindExpr->mCommas.size(); commaIdx++)
  12941. {
  12942. auto commaNode = lambdaBindExpr->mCommas[commaIdx];
  12943. if ((commaNode != NULL) && (cursorIdx >= commaNode->GetSrcStart()))
  12944. paramIdx = commaIdx + 1;
  12945. }
  12946. bool isEmpty = true;
  12947. if (paramIdx < (int)lambdaBindExpr->mParams.size())
  12948. {
  12949. auto paramNode = lambdaBindExpr->mParams[paramIdx];
  12950. if (paramNode != NULL)
  12951. isEmpty = false;
  12952. }
  12953. if (isEmpty)
  12954. {
  12955. if (paramIdx < (int)invokeMethodInstance->GetParamCount())
  12956. {
  12957. String paramName = invokeMethodInstance->GetParamName(paramIdx);
  12958. autoComplete->mEntriesSet.Clear();
  12959. if (paramName.IsEmpty())
  12960. paramName += StrFormat("val%d", paramIdx + 1);
  12961. autoComplete->AddEntry(AutoCompleteEntry("paramName", paramName));
  12962. autoComplete->mInsertStartIdx = cursorIdx;
  12963. autoComplete->mInsertEndIdx = cursorIdx;
  12964. if ((paramIdx == 0) && (lambdaBindExpr->mParams.IsEmpty()))
  12965. {
  12966. String totalNames;
  12967. for (int checkIdx = 0; checkIdx < (int)invokeMethodInstance->GetParamCount(); checkIdx++)
  12968. {
  12969. if (!totalNames.IsEmpty())
  12970. totalNames += ", ";
  12971. String paramName = invokeMethodInstance->GetParamName(checkIdx);
  12972. if (paramName.IsEmpty())
  12973. paramName += StrFormat("val%d", checkIdx + 1);
  12974. totalNames += paramName;
  12975. }
  12976. autoComplete->AddEntry(AutoCompleteEntry("paramNames", totalNames));
  12977. }
  12978. }
  12979. }
  12980. }
  12981. }
  12982. }
  12983. defer
  12984. (
  12985. {
  12986. if (autoComplete != NULL)
  12987. autoComplete->mIsCapturingMethodMatchInfo = (wasCapturingMethodInfo) && (!autoComplete->mIsCapturingMethodMatchInfo) && (autoComplete->mMethodMatchInfo != NULL);
  12988. }
  12989. );
  12990. if (lambdaBindExpr->mBody == NULL)
  12991. {
  12992. mModule->AssertErrorState();
  12993. return NULL;
  12994. }
  12995. if ((lambdaBindExpr->mNewToken == NULL) && (isInferReturnType))
  12996. {
  12997. // Method ref, but let this follow infer route
  12998. }
  12999. else if ((lambdaBindExpr->mNewToken == NULL) || (isFunctionBind))
  13000. {
  13001. if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mCapturing))
  13002. {
  13003. SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
  13004. VisitLambdaBodies(lambdaBindExpr->mBody, lambdaBindExpr->mDtor);
  13005. }
  13006. if ((lambdaBindExpr->mNewToken != NULL) && (isFunctionBind))
  13007. mModule->Fail("Binds to functions should do not require allocations.", lambdaBindExpr->mNewToken);
  13008. if (lambdaBindExpr->mDtor != NULL)
  13009. {
  13010. mModule->Fail("Valueless method reference cannot contain destructor. Consider either removing destructor or using an allocated lambda.", lambdaBindExpr->mDtor->mTildeToken);
  13011. // Eat it
  13012. auto fieldDtor = lambdaBindExpr->mDtor;
  13013. while (fieldDtor != NULL)
  13014. {
  13015. mModule->VisitEmbeddedStatement(fieldDtor->mBody);
  13016. fieldDtor = fieldDtor->mNextFieldDtor;
  13017. }
  13018. }
  13019. if (invokeMethodInstance != NULL)
  13020. {
  13021. BfLocalMethod* localMethod = new BfLocalMethod();
  13022. localMethod->mMethodName = "anon";
  13023. localMethod->mSystem = mModule->mSystem;
  13024. localMethod->mModule = mModule;
  13025. localMethod->mExpectedFullName = mModule->GetLocalMethodName(localMethod->mMethodName, lambdaBindExpr->mFatArrowToken, mModule->mCurMethodState, mModule->mCurMethodState->mMixinState);
  13026. localMethod->mLambdaInvokeMethodInstance = invokeMethodInstance;
  13027. localMethod->mLambdaBindExpr = lambdaBindExpr;
  13028. localMethod->mDeclMethodState = mModule->mCurMethodState;
  13029. mModule->mContext->mLocalMethodGraveyard.push_back(localMethod);
  13030. auto moduleMethodInstance = mModule->GetLocalMethodInstance(localMethod, BfTypeVector());
  13031. if (moduleMethodInstance.mMethodInstance->mDisallowCalling)
  13032. {
  13033. mResult = mModule->GetDefaultTypedValue(mExpectingType, false, BfDefaultValueKind_Addr);
  13034. return NULL;
  13035. }
  13036. auto methodRefType = mModule->CreateMethodRefType(moduleMethodInstance.mMethodInstance);
  13037. mModule->AddDependency(methodRefType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_Calls);
  13038. mModule->AddCallDependency(moduleMethodInstance.mMethodInstance);
  13039. mResult = BfTypedValue(BfIRValue(BfIRValueFlags_Value, BfIRValue::ID_IMPLICIT), methodRefType);
  13040. return NULL;
  13041. }
  13042. }
  13043. //SetAndRestoreValue<bool> prevIgnoreIRWrites(mModule->mBfIRBuilder->mIgnoreWrites, mModule->mWantsIRIgnoreWrites);
  13044. SetAndRestoreValue<bool> prevIgnoreIRWrites(mModule->mBfIRBuilder->mIgnoreWrites, mModule->mWantsIRIgnoreWrites || mModule->mCurMethodInstance->mIsUnspecialized);
  13045. BfTypeInstance* outerClosure = NULL;
  13046. if ((mModule->mCurMethodState->mClosureState != NULL) && (!mModule->mCurMethodState->mClosureState->mCapturing))
  13047. outerClosure = mModule->mCurMethodState->mClosureState->mClosureType;
  13048. Val128 val128(delegateTypeInstance->mTypeId);
  13049. bool isConstEval = ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0);
  13050. BfMethodState methodState;
  13051. methodState.mPrevMethodState = mModule->mCurMethodState;
  13052. BfIRFunctionType funcType;
  13053. auto voidType = mModule->GetPrimitiveType(BfTypeCode_None);
  13054. SizedArray<BfIRType, 0> paramTypes;
  13055. funcType = mModule->mBfIRBuilder->CreateFunctionType(mModule->mBfIRBuilder->MapType(voidType), paramTypes, false);
  13056. auto prevInsertBlock = mModule->mBfIRBuilder->GetInsertBlock();
  13057. BF_ASSERT(prevInsertBlock || isConstEval);
  13058. auto prevActiveFunction = mModule->mBfIRBuilder->GetActiveFunction();
  13059. mModule->mBfIRBuilder->SaveDebugLocation();
  13060. SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
  13061. BfDeferredLocalAssignData deferredLocalAssignData;
  13062. if (mModule->mCurMethodState->mDeferredLocalAssignData != NULL)
  13063. deferredLocalAssignData.ExtendFrom(mModule->mCurMethodState->mDeferredLocalAssignData);
  13064. SetAndRestoreValue<BfMethodState*> prevMethodState(mModule->mCurMethodState, &methodState);
  13065. methodState.mIRHeadBlock = mModule->mBfIRBuilder->CreateBlock("head", true);
  13066. methodState.mIRInitBlock = mModule->mBfIRBuilder->CreateBlock("init", true);
  13067. methodState.mIREntryBlock = mModule->mBfIRBuilder->CreateBlock("entry", true);
  13068. methodState.mCurScope->mDIScope = prevMethodState.mPrevVal->mCurScope->mDIScope;//invokeMethodInstance->mDIFunction;
  13069. methodState.mCurLocalVarId = -1;
  13070. methodState.mIRFunction = prevMethodState.mPrevVal->mIRFunction;
  13071. methodState.mDeferredLocalAssignData = &deferredLocalAssignData;
  13072. mModule->mBfIRBuilder->SetInsertPoint(methodState.mIREntryBlock);
  13073. BfClosureState closureState;
  13074. if (delegateTypeInstance->IsDelegate())
  13075. closureState.mReturnType = mModule->GetDelegateReturnType(delegateTypeInstance);
  13076. else
  13077. closureState.mReturnType = mModule->mContext->mBfObjectType;
  13078. closureState.mCapturing = true;
  13079. if (delegateTypeInstance->IsDelegate())
  13080. closureState.mDelegateType = delegateTypeInstance;
  13081. closureState.mDeclaringMethodIsMutating = mModule->mCurMethodInstance->mMethodDef->mIsMutating;
  13082. methodState.mClosureState = &closureState;
  13083. closureState.mClosureType = outerClosure;
  13084. BF_ASSERT(methodState.mCurLocalVarId == -1);
  13085. int outerLocalsCount = (int)methodState.mLocals.size();
  13086. // static int sItrCount = 0;
  13087. // ++sItrCount;
  13088. // int itrCount = sItrCount;
  13089. // if ((itrCount == 8) || (itrCount == 10))
  13090. // {
  13091. // NOP;
  13092. // }
  13093. String delegateTypeName = mModule->TypeToString(delegateTypeInstance);
  13094. HashContext hashCtx;
  13095. hashCtx.MixinStr(delegateTypeName);
  13096. BfSource* bfSource = delegateTypeInstance->mTypeDef->mSource;
  13097. BfMethodDef* methodDef = new BfMethodDef();
  13098. methodDef->mDeclaringType = mModule->mCurMethodInstance->mMethodDef->mDeclaringType;
  13099. Val128 closureMethodHash;
  13100. OwnedVector<BfParameterDeclaration> tempParamDecls;
  13101. if ((autoComplete != NULL) && (autoComplete->mMethodMatchInfo != NULL) && (autoComplete->IsAutocompleteNode(lambdaBindExpr->mBody)))
  13102. {
  13103. // Don't show outer method match info when our cursor is inside a lambda expression (being passed as a parameter)
  13104. autoComplete->RemoveMethodMatchInfo();
  13105. }
  13106. if (invokeMethodInstance != NULL)
  13107. {
  13108. for (int paramIdx = 0; paramIdx < (int)invokeMethodInstance->GetParamCount(); paramIdx++)
  13109. {
  13110. BfLocalVariable* localVar = new BfLocalVariable();
  13111. if (paramIdx < (int)lambdaBindExpr->mParams.size())
  13112. {
  13113. localVar->mName = lambdaBindExpr->mParams[paramIdx]->ToString();
  13114. localVar->mNameNode = lambdaBindExpr->mParams[paramIdx];
  13115. }
  13116. else
  13117. {
  13118. mModule->AssertErrorState();
  13119. localVar->mName = invokeMethodInstance->GetParamName(paramIdx);
  13120. }
  13121. localVar->mResolvedType = invokeMethodInstance->GetParamType(paramIdx);
  13122. mModule->PopulateType(localVar->mResolvedType);
  13123. localVar->mAssignedKind = BfLocalVarAssignKind_Unconditional;
  13124. localVar->mReadFromId = 0;
  13125. auto rootMethodState = methodState.GetRootMethodState();
  13126. localVar->mLocalVarId = rootMethodState->mCurLocalVarId++;
  13127. mModule->DoAddLocalVariable(localVar);
  13128. auto resolvePassData = mModule->mCompiler->mResolvePassData;
  13129. if ((resolvePassData != NULL) && (localVar->mNameNode != NULL))
  13130. resolvePassData->HandleLocalReference(BfNodeDynCast<BfIdentifierNode>(localVar->mNameNode), mModule->mCurTypeInstance->mTypeDef,
  13131. mModule->mCurMethodInstance->mMethodDef, localVar->mLocalVarId);
  13132. }
  13133. for (int paramIdx = 0; paramIdx < (int)invokeMethodInstance->mMethodDef->mParams.size(); paramIdx++)
  13134. {
  13135. auto invokeParamDef = invokeMethodInstance->mMethodDef->mParams[paramIdx];
  13136. BfParameterDef* paramDef = new BfParameterDef();
  13137. paramDef->mParamDeclaration = tempParamDecls.Alloc();
  13138. BfAstNode::Zero(paramDef->mParamDeclaration);
  13139. paramDef->mTypeRef = invokeParamDef->mTypeRef;
  13140. paramDef->mParamKind = invokeParamDef->mParamKind;
  13141. if ((paramIdx < (int)lambdaBindExpr->mParams.size()) && (invokeMethodInstance->GetParamKind(paramIdx) != BfParamKind_DelegateParam))
  13142. {
  13143. //TODO: Not always correct if we have a 'params'
  13144. paramDef->mParamDeclaration->mNameNode = lambdaBindExpr->mParams[paramIdx];
  13145. paramDef->mName = paramDef->mParamDeclaration->mNameNode->ToString();
  13146. }
  13147. else
  13148. {
  13149. paramDef->mParamDeclaration->mNameNode = NULL;
  13150. paramDef->mName = invokeParamDef->mName;
  13151. }
  13152. methodDef->mParams.push_back(paramDef);
  13153. if (autoComplete != NULL)
  13154. autoComplete->CheckLocalDef(BfNodeDynCast<BfIdentifierNode>(paramDef->mParamDeclaration->mNameNode), methodState.mLocals.back());
  13155. }
  13156. }
  13157. bool isAutocomplete = mModule->mCompiler->IsAutocomplete();
  13158. methodDef->mIdx = mModule->mCurMethodInstance->mMethodDef->mIdx;
  13159. methodDef->mBody = lambdaBindExpr->mBody;
  13160. ///
  13161. auto varMethodState = methodState.mPrevMethodState;
  13162. bool hasExplicitCaptureNames = false;
  13163. for (auto& captureEntry : allocTarget.mCaptureInfo->mCaptures)
  13164. {
  13165. if (captureEntry.mNameNode == NULL)
  13166. {
  13167. hasExplicitCaptureNames = false;
  13168. break;
  13169. }
  13170. hasExplicitCaptureNames = true;
  13171. }
  13172. auto _SetNotCapturedFlag = [&](bool notCaptured)
  13173. {
  13174. auto varMethodState = methodState.mPrevMethodState;
  13175. while (varMethodState != NULL)
  13176. {
  13177. for (int localIdx = 0; localIdx < varMethodState->mLocals.size(); localIdx++)
  13178. {
  13179. auto localVar = varMethodState->mLocals[localIdx];
  13180. localVar->mNotCaptured = notCaptured;
  13181. }
  13182. varMethodState = varMethodState->mPrevMethodState;
  13183. if (varMethodState == NULL)
  13184. break;
  13185. if (varMethodState->mMixinState != NULL)
  13186. break;
  13187. if (varMethodState->mClosureState != NULL)
  13188. {
  13189. if (!varMethodState->mClosureState->mCapturing)
  13190. break;
  13191. }
  13192. }
  13193. };
  13194. if (hasExplicitCaptureNames)
  13195. {
  13196. _SetNotCapturedFlag(true);
  13197. auto varMethodState = methodState.mPrevMethodState;
  13198. while (varMethodState != NULL)
  13199. {
  13200. for (auto& captureEntry : allocTarget.mCaptureInfo->mCaptures)
  13201. {
  13202. if (captureEntry.mNameNode != NULL)
  13203. {
  13204. StringT<64> captureName;
  13205. captureEntry.mNameNode->ToString(captureName);
  13206. BfLocalVarEntry* entry;
  13207. if (varMethodState->mLocalVarSet.TryGetWith<StringImpl&>(captureName, &entry))
  13208. {
  13209. auto localVar = entry->mLocalVar;
  13210. while (localVar != NULL)
  13211. {
  13212. if (autoComplete != NULL)
  13213. autoComplete->CheckLocalRef(captureEntry.mNameNode, localVar);
  13214. if (((mModule->mCurMethodState->mClosureState == NULL) || (mModule->mCurMethodState->mClosureState->mCapturing)) &&
  13215. (mModule->mCompiler->mResolvePassData != NULL) && (mModule->mCurMethodInstance != NULL))
  13216. {
  13217. if (auto captureIdentifierNode = BfNodeDynCast<BfIdentifierNode>(captureEntry.mNameNode))
  13218. mModule->mCompiler->mResolvePassData->HandleLocalReference(captureIdentifierNode, localVar->mNameNode, mModule->mCurTypeInstance->mTypeDef, rootMethodState->mMethodInstance->mMethodDef, localVar->mLocalVarId);
  13219. }
  13220. localVar->mNotCaptured = false;
  13221. localVar = localVar->mShadowedLocal;
  13222. }
  13223. }
  13224. }
  13225. }
  13226. varMethodState = varMethodState->mPrevMethodState;
  13227. if (varMethodState == NULL)
  13228. break;
  13229. if (varMethodState->mMixinState != NULL)
  13230. break;
  13231. if (varMethodState->mClosureState != NULL)
  13232. {
  13233. if (!varMethodState->mClosureState->mCapturing)
  13234. break;
  13235. }
  13236. }
  13237. }
  13238. BfClosureInstanceInfo* closureInstanceInfo = new BfClosureInstanceInfo();
  13239. auto checkInsertBlock = mModule->mBfIRBuilder->GetInsertBlock();
  13240. closureState.mCaptureStartAccessId = methodState.mPrevMethodState->GetRootMethodState()->mCurAccessId;
  13241. closureState.mCaptureVisitingBody = true;
  13242. closureState.mClosureInstanceInfo = closureInstanceInfo;
  13243. if ((mBfEvalExprFlags & BfEvalExprFlags_InferReturnType) != 0)
  13244. {
  13245. closureState.mReturnType = NULL;
  13246. closureState.mReturnTypeInferState = BfReturnTypeInferState_Inferring;
  13247. }
  13248. VisitLambdaBodies(lambdaBindExpr->mBody, lambdaBindExpr->mDtor);
  13249. if (hasExplicitCaptureNames)
  13250. _SetNotCapturedFlag(false);
  13251. // If we ended up being called by a method with a lower captureStartAccessId, propagate that to whoever is calling us, too...
  13252. if ((methodState.mPrevMethodState->mClosureState != NULL) && (methodState.mPrevMethodState->mClosureState->mCapturing))
  13253. {
  13254. auto prevClosureState = methodState.mPrevMethodState->mClosureState;
  13255. if (closureState.mCaptureStartAccessId < prevClosureState->mCaptureStartAccessId)
  13256. prevClosureState->mCaptureStartAccessId = closureState.mCaptureStartAccessId;
  13257. }
  13258. bool earlyExit = false;
  13259. if (isInferReturnType)
  13260. {
  13261. if ((closureState.mReturnTypeInferState == BfReturnTypeInferState_Fail) ||
  13262. (closureState.mReturnType == NULL))
  13263. {
  13264. mResult = BfTypedValue();
  13265. }
  13266. else
  13267. {
  13268. mResult = BfTypedValue(closureState.mReturnType);
  13269. }
  13270. earlyExit = true;
  13271. }
  13272. else if (mModule->mCurMethodInstance->mIsUnspecialized)
  13273. {
  13274. earlyExit = true;
  13275. mResult = mModule->GetDefaultTypedValue(delegateTypeInstance);
  13276. }
  13277. if (earlyExit)
  13278. {
  13279. prevIgnoreWrites.Restore();
  13280. mModule->mBfIRBuilder->RestoreDebugLocation();
  13281. mModule->mBfIRBuilder->SetActiveFunction(prevActiveFunction);
  13282. if (!prevInsertBlock.IsFake())
  13283. mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock);
  13284. delete methodDef;
  13285. delete closureInstanceInfo;
  13286. return NULL;
  13287. }
  13288. closureState.mCaptureVisitingBody = false;
  13289. prevIgnoreWrites.Restore();
  13290. mModule->mBfIRBuilder->RestoreDebugLocation();
  13291. auto _GetCaptureType = [&](const StringImpl& str, BfCaptureInfo::Entry** captureInfo = NULL)
  13292. {
  13293. if (allocTarget.mCaptureInfo->mCaptures.IsEmpty())
  13294. return BfCaptureType_Copy;
  13295. for (auto& captureEntry : allocTarget.mCaptureInfo->mCaptures)
  13296. {
  13297. if ((captureEntry.mNameNode == NULL) || (captureEntry.mNameNode->Equals(str)))
  13298. {
  13299. if (captureInfo != NULL)
  13300. *captureInfo = &captureEntry;
  13301. captureEntry.mUsed = true;
  13302. return captureEntry.mCaptureType;
  13303. }
  13304. }
  13305. return BfCaptureType_None;
  13306. };
  13307. Array<BfClosureCapturedEntry> capturedEntries;
  13308. bool copyOuterCaptures = false;
  13309. //
  13310. {
  13311. auto varMethodState = methodState.mPrevMethodState;
  13312. while (varMethodState != NULL)
  13313. {
  13314. for (int localIdx = 0; localIdx < varMethodState->mLocals.size(); localIdx++)
  13315. {
  13316. auto localVar = varMethodState->mLocals[localIdx];
  13317. if ((localVar->mReadFromId >= closureState.mCaptureStartAccessId) || (localVar->mWrittenToId >= closureState.mCaptureStartAccessId))
  13318. {
  13319. if ((localVar->mIsThis) && (outerClosure != NULL))
  13320. {
  13321. continue;
  13322. }
  13323. auto outerLocal = localVar;
  13324. if ((localVar->mConstValue) || (localVar->mResolvedType->IsValuelessType()))
  13325. {
  13326. closureState.mConstLocals.push_back(*outerLocal);
  13327. continue;
  13328. }
  13329. BfClosureCapturedEntry capturedEntry;
  13330. auto capturedType = outerLocal->mResolvedType;
  13331. bool captureByRef = false;
  13332. BfCaptureInfo::Entry* captureInfoEntry = NULL;
  13333. auto captureType = _GetCaptureType(localVar->mName, &captureInfoEntry);
  13334. if (captureType == BfCaptureType_None)
  13335. {
  13336. continue;
  13337. }
  13338. if (!capturedType->IsRef())
  13339. {
  13340. if (captureType == BfCaptureType_Reference)
  13341. {
  13342. if ((localVar->mIsThis) && (!localVar->mResolvedType->IsValueType()))
  13343. {
  13344. // Just ignore attempting to capture referencetype 'this' by reference
  13345. }
  13346. else
  13347. captureByRef = true;
  13348. }
  13349. else if (captureType == BfCaptureType_Auto)
  13350. {
  13351. if (localVar->mWrittenToId >= closureState.mCaptureStartAccessId)
  13352. captureByRef = true;
  13353. else if ((outerLocal->mResolvedType->mSize > 8) ||
  13354. ((localVar->mIsThis) && (outerLocal->mResolvedType->IsValueType())))
  13355. {
  13356. // Capture "large" values by reference
  13357. captureByRef = true;
  13358. }
  13359. }
  13360. }
  13361. else
  13362. {
  13363. bool allowRef = false;
  13364. if (captureType == BfCaptureType_Reference)
  13365. allowRef = true;
  13366. else if (captureType == BfCaptureType_Auto)
  13367. allowRef = localVar->mWrittenToId < closureState.mCaptureStartAccessId;
  13368. if (!allowRef)
  13369. {
  13370. capturedType = ((BfRefType*)capturedType)->mElementType;
  13371. }
  13372. }
  13373. if (captureByRef)
  13374. {
  13375. capturedType = mModule->CreateRefType(capturedType);
  13376. }
  13377. if (captureType != BfCaptureType_Copy)
  13378. capturedEntry.mExplicitlyByReference = true;
  13379. capturedEntry.mType = capturedType;
  13380. capturedEntry.mNameNode = outerLocal->mNameNode;
  13381. if (outerLocal->mName == "this")
  13382. capturedEntry.mName = "__this";
  13383. else
  13384. {
  13385. capturedEntry.mName = outerLocal->mName;
  13386. BfLocalVarEntry* entry = NULL;
  13387. if (varMethodState->mLocalVarSet.TryGetWith<StringImpl&>(capturedEntry.mName, &entry))
  13388. {
  13389. auto startCheckVar = entry->mLocalVar;
  13390. int shadowIdx = 0;
  13391. auto checkVar = startCheckVar;
  13392. while (checkVar != NULL)
  13393. {
  13394. if (checkVar == outerLocal)
  13395. {
  13396. // We only use mShadowIdx when we have duplicate name nodes (ie: in the case of for looks with iterator vs value)
  13397. auto shadowCheckVar = startCheckVar;
  13398. while (shadowCheckVar != checkVar)
  13399. {
  13400. if (shadowCheckVar->mNameNode == checkVar->mNameNode)
  13401. capturedEntry.mShadowIdx++;
  13402. shadowCheckVar = shadowCheckVar->mShadowedLocal;
  13403. }
  13404. for (int i = 0; i < shadowIdx; i++)
  13405. capturedEntry.mName.Insert(0, '@');
  13406. break;
  13407. }
  13408. shadowIdx++;
  13409. checkVar = checkVar->mShadowedLocal;
  13410. }
  13411. }
  13412. }
  13413. capturedEntries.Add(capturedEntry);
  13414. }
  13415. }
  13416. varMethodState = varMethodState->mPrevMethodState;
  13417. if (varMethodState == NULL)
  13418. break;
  13419. if (varMethodState->mMixinState != NULL)
  13420. break;
  13421. if (varMethodState->mClosureState != NULL)
  13422. {
  13423. if (!varMethodState->mClosureState->mCapturing)
  13424. break;
  13425. }
  13426. }
  13427. }
  13428. for (auto& captureEntry : allocTarget.mCaptureInfo->mCaptures)
  13429. {
  13430. if ((!captureEntry.mUsed) && (captureEntry.mNameNode != NULL))
  13431. mModule->Warn(0, "Capture specifier not used", captureEntry.mNameNode);
  13432. }
  13433. for (auto copyField : closureState.mReferencedOuterClosureMembers)
  13434. {
  13435. auto fieldDef = copyField->GetFieldDef();
  13436. auto captureType = _GetCaptureType(fieldDef->mName);
  13437. BfClosureCapturedEntry capturedEntry;
  13438. capturedEntry.mName = fieldDef->mName;
  13439. capturedEntry.mType = copyField->mResolvedType;
  13440. if ((captureType != BfCaptureType_Copy) && (capturedEntry.mType->IsRef()))
  13441. {
  13442. capturedEntry.mExplicitlyByReference = true;
  13443. }
  13444. else if ((captureType == BfCaptureType_Copy) && (capturedEntry.mType->IsRef()))
  13445. {
  13446. auto refType = (BfRefType*)capturedEntry.mType;
  13447. capturedEntry.mType = refType->mElementType;
  13448. }
  13449. else if ((captureType != BfCaptureType_Copy) && (!capturedEntry.mType->IsRef()) && (!fieldDef->mIsReadOnly))
  13450. {
  13451. capturedEntry.mType = mModule->CreateRefType(capturedEntry.mType);
  13452. }
  13453. }
  13454. std::sort(capturedEntries.begin(), capturedEntries.end());
  13455. bool hasCapture = false;
  13456. BfMethodInstanceGroup methodInstanceGroup;
  13457. methodInstanceGroup.mOwner = mModule->mCurTypeInstance;
  13458. methodInstanceGroup.mOnDemandKind = BfMethodOnDemandKind_AlwaysInclude;
  13459. BfMethodInstance* methodInstance = new BfMethodInstance();
  13460. methodInstance->mMethodInstanceGroup = &methodInstanceGroup;
  13461. methodInstance->GetMethodInfoEx()->mClosureInstanceInfo = closureInstanceInfo;
  13462. if (invokeMethodInstance != NULL)
  13463. methodInstance->mParams = invokeMethodInstance->mParams;
  13464. methodInstance->mIsClosure = true;
  13465. // We want the closure ID to match between hot reloads -- otherwise we wouldn't be able to modify them,
  13466. // so we use the charId from the 'fat arrow' token
  13467. int closureId = 0;
  13468. if (lambdaBindExpr->mFatArrowToken != NULL)
  13469. closureId = lambdaBindExpr->mFatArrowToken->GetStartCharId();
  13470. auto curProject = mModule->mCurTypeInstance->mTypeDef->mProject;
  13471. BF_ASSERT(curProject != NULL);
  13472. // We need to make these per-project even though you'd think we might not because we
  13473. // insert generic type specializations in the generic definition's project,
  13474. // BECAUSE: we would need to scan the captured fields the same way we scan the
  13475. // generic arguments to determine if each project can see it or not in the vdata
  13476. BfTypeInstance* useTypeInstance = delegateTypeInstance;
  13477. BfClosureType* closureTypeInst = NULL;
  13478. // If we are allowing hot swapping we may add a capture later. We also need an equal method that ignores 'target' even when we're capturing ourself
  13479. if ((capturedEntries.size() != 0) || (lambdaBindExpr->mDtor != NULL) || (copyOuterCaptures) || (mModule->mCompiler->mOptions.mAllowHotSwapping) || (closureState.mCapturedDelegateSelf))
  13480. {
  13481. hashCtx.MixinStr(curProject->mName);
  13482. if (copyOuterCaptures)
  13483. {
  13484. hashCtx.Mixin(outerClosure->mTypeId);
  13485. }
  13486. for (auto& capturedEntry : capturedEntries)
  13487. {
  13488. hashCtx.Mixin(capturedEntry.mType->mTypeId);
  13489. hashCtx.MixinStr(capturedEntry.mName);
  13490. hashCtx.Mixin(capturedEntry.mExplicitlyByReference);
  13491. }
  13492. if (lambdaBindExpr->mDtor != NULL)
  13493. {
  13494. // Has DTOR thunk
  13495. bool hasDtorThunk = true;
  13496. hashCtx.Mixin(hasDtorThunk);
  13497. }
  13498. Val128 hash128 = hashCtx.Finish128();
  13499. BfClosureType* checkClosureType = new BfClosureType(delegateTypeInstance, hash128);
  13500. checkClosureType->mContext = mModule->mContext;
  13501. checkClosureType->mBaseType = delegateTypeInstance;
  13502. BfType* resolvedClosureType = mModule->ResolveType(checkClosureType, BfPopulateType_TypeDef);
  13503. closureTypeInst = (BfClosureType*)resolvedClosureType;
  13504. if (checkClosureType == resolvedClosureType)
  13505. {
  13506. // This is a new closure type
  13507. closureTypeInst->Init(curProject);
  13508. closureTypeInst->mTypeDef->mProject = curProject;
  13509. auto delegateDirectTypeRef = BfAstNode::ZeroedAlloc<BfDirectTypeDefReference>();
  13510. delegateDirectTypeRef->Init(mModule->mCompiler->mDelegateTypeDef);
  13511. closureTypeInst->mDirectAllocNodes.push_back(delegateDirectTypeRef);
  13512. BfMethodDef* methodDef = BfDefBuilder::AddMethod(closureTypeInst->mTypeDef, BfMethodType_Normal, BfProtection_Public, false, "Equals");
  13513. methodDef->mReturnTypeRef = mModule->mSystem->mDirectBoolTypeRef;
  13514. BfDefBuilder::AddParam(methodDef, delegateDirectTypeRef, "val");
  13515. methodDef->mIsVirtual = true;
  13516. methodDef->mIsOverride = true;
  13517. if (copyOuterCaptures)
  13518. {
  13519. for (auto& fieldInstance : outerClosure->mFieldInstances)
  13520. {
  13521. BfFieldDef* origFieldDef = fieldInstance.GetFieldDef();
  13522. BfFieldDef* fieldDef = closureTypeInst->AddField(fieldInstance.mResolvedType, origFieldDef->mName);
  13523. fieldDef->mIsReadOnly = origFieldDef->mIsReadOnly;
  13524. }
  13525. }
  13526. for (auto& capturedEntry : capturedEntries)
  13527. {
  13528. BfFieldDef* fieldDef = closureTypeInst->AddField(capturedEntry.mType, capturedEntry.mName);
  13529. if (!capturedEntry.mExplicitlyByReference)
  13530. fieldDef->mIsReadOnly = true;
  13531. }
  13532. if (lambdaBindExpr->mDtor != NULL)
  13533. {
  13534. auto dtorDef = closureTypeInst->AddDtor();
  13535. auto voidType = mModule->GetPrimitiveType(BfTypeCode_None);
  13536. auto voidPtrType = mModule->CreatePointerType(voidType);
  13537. closureTypeInst->AddField(voidPtrType, "__dtorThunk");
  13538. }
  13539. closureTypeInst->Finish();
  13540. }
  13541. else
  13542. {
  13543. // Already had this entry
  13544. delete checkClosureType;
  13545. }
  13546. useTypeInstance = closureTypeInst;
  13547. }
  13548. mModule->mBfIRBuilder->PopulateType(useTypeInstance);
  13549. mModule->PopulateType(useTypeInstance);
  13550. methodDef->mIsStatic = closureTypeInst == NULL;
  13551. SizedArray<BfIRType, 8> origParamTypes;
  13552. BfIRType origReturnType;
  13553. bool forceStatic = false;
  13554. if (invokeMethodInstance != NULL)
  13555. {
  13556. forceStatic = methodDef->mIsStatic;
  13557. auto invokeFunctionType = mModule->mBfIRBuilder->MapMethod(invokeMethodInstance);
  13558. invokeMethodInstance->GetIRFunctionInfo(mModule, origReturnType, origParamTypes, forceStatic);
  13559. }
  13560. else
  13561. {
  13562. origReturnType = mModule->mBfIRBuilder->MapType(mModule->GetPrimitiveType(BfTypeCode_None));
  13563. }
  13564. SizedArray<BfIRType, 3> newTypes;
  13565. if ((invokeMethodInstance != NULL) && (GetStructRetIdx(invokeMethodInstance, forceStatic) == 0))
  13566. newTypes.push_back(origParamTypes[0]);
  13567. if (!methodDef->mIsStatic)
  13568. newTypes.push_back(mModule->mBfIRBuilder->MapType(useTypeInstance));
  13569. if ((invokeMethodInstance != NULL) && (GetStructRetIdx(invokeMethodInstance, forceStatic) == 1))
  13570. newTypes.push_back(origParamTypes[1]);
  13571. int paramStartIdx = 0;
  13572. if ((invokeMethodInstance != NULL) && (GetStructRetIdx(invokeMethodInstance, forceStatic) != -1))
  13573. paramStartIdx++;
  13574. if (!methodDef->mIsStatic)
  13575. paramStartIdx++;
  13576. for (int i = paramStartIdx; i < (int)origParamTypes.size(); i++)
  13577. newTypes.push_back(origParamTypes[i]);
  13578. auto closureFuncType = mModule->mBfIRBuilder->CreateFunctionType(origReturnType, newTypes, false);
  13579. prevMethodState.Restore();
  13580. mModule->mBfIRBuilder->SetActiveFunction(prevActiveFunction);
  13581. if ((prevInsertBlock) && (!prevInsertBlock.IsFake()))
  13582. mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock);
  13583. // Just a check
  13584. mModule->mBfIRBuilder->GetInsertBlock();
  13585. //auto rootMethodState = mModule->mCurMethodState;
  13586. HashContext closureHashCtx;
  13587. closureHashCtx.Mixin(closureId);
  13588. // When we're a nested lambda, strip off the outer hash and closureTypeInst markers
  13589. methodDef->mName = mModule->mCurMethodInstance->mMethodDef->mName;
  13590. int prevSepPos = (int)methodDef->mName.LastIndexOf('$');
  13591. if (prevSepPos != -1)
  13592. {
  13593. closureHashCtx.Mixin(methodDef->mName.c_str() + prevSepPos, (int)methodDef->mName.length() - prevSepPos);
  13594. methodDef->mName.RemoveToEnd(prevSepPos);
  13595. }
  13596. // Mix in this because this can be emitted multiple times when there's multiple ctors and field initializers with lambdas
  13597. if (mModule->mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_Ctor)
  13598. {
  13599. if (auto ctorDecl = BfNodeDynCast<BfConstructorDeclaration>(mModule->mCurMethodInstance->mMethodDef->mMethodDeclaration))
  13600. {
  13601. if (ctorDecl->mThisToken != NULL)
  13602. closureHashCtx.Mixin(ctorDecl->mThisToken->GetStartCharId());
  13603. }
  13604. }
  13605. auto checkMethodState = mModule->mCurMethodState;
  13606. while (checkMethodState != NULL)
  13607. {
  13608. if (checkMethodState->mMethodInstance != NULL)
  13609. {
  13610. if (checkMethodState->mMethodInstance->mMethodInfoEx != NULL)
  13611. {
  13612. for (auto methodGenericArg : checkMethodState->mMethodInstance->mMethodInfoEx->mMethodGenericArguments)
  13613. {
  13614. StringT<128> genericTypeName;
  13615. BfMangler::Mangle(genericTypeName, mModule->mCompiler->GetMangleKind(), methodGenericArg);
  13616. closureHashCtx.MixinStr(genericTypeName);
  13617. }
  13618. }
  13619. }
  13620. checkMethodState = checkMethodState->mPrevMethodState;
  13621. }
  13622. uint64 closureHash = closureHashCtx.Finish64();
  13623. methodDef->mName += "$";
  13624. methodDef->mName += BfTypeUtils::HashEncode64(closureHash);
  13625. methodInstance->mMethodDef = methodDef;
  13626. if (invokeMethodInstance != NULL)
  13627. {
  13628. methodInstance->mParams = invokeMethodInstance->mParams;
  13629. methodInstance->mReturnType = invokeMethodInstance->mReturnType;
  13630. }
  13631. else
  13632. methodInstance->mReturnType = mModule->GetPrimitiveType(BfTypeCode_None);
  13633. StringT<128> closureFuncName;
  13634. BfMangler::Mangle(closureFuncName, mModule->mCompiler->GetMangleKind(), methodInstance);
  13635. auto closureFunc = mModule->mBfIRBuilder->CreateFunction(closureFuncType, BfIRLinkageType_External, closureFuncName);
  13636. methodInstance->mIRFunction = closureFunc;
  13637. if (methodInstance->mIsReified)
  13638. mModule->CheckHotMethod(methodInstance, closureFuncName);
  13639. if ((methodInstance->mHotMethod != NULL) && (mModule->mCurMethodState->mHotDataReferenceBuilder))
  13640. mModule->mCurMethodState->mHotDataReferenceBuilder->mInnerMethods.Add(methodInstance->mHotMethod);
  13641. methodState.Reset();
  13642. lambdaInstance = new BfLambdaInstance();
  13643. rootMethodState->mLambdaCache[cacheNodeList] = lambdaInstance;
  13644. lambdaInstance->mDelegateTypeInstance = delegateTypeInstance;
  13645. lambdaInstance->mUseTypeInstance = useTypeInstance;
  13646. lambdaInstance->mClosureTypeInstance = closureTypeInst;
  13647. lambdaInstance->mOuterClosure = outerClosure;
  13648. lambdaInstance->mCopyOuterCaptures = copyOuterCaptures;
  13649. lambdaInstance->mDeclaringMethodIsMutating = mModule->mCurMethodInstance->mMethodDef->mIsMutating;
  13650. lambdaInstance->mIsStatic = methodDef->mIsStatic;
  13651. lambdaInstance->mClosureFunc = closureFunc;
  13652. lambdaInstance->mMethodInstance = methodInstance;
  13653. lambdaInstance->mConstLocals = closureState.mConstLocals;
  13654. lambdaInstance->mParamDecls = tempParamDecls;
  13655. lambdaInstance->mDeclMixinState = mModule->mCurMethodState->mMixinState;
  13656. if (lambdaInstance->mDeclMixinState != NULL)
  13657. lambdaInstance->mDeclMixinState->mHasDeferredUsage = true;
  13658. tempParamDecls.ClearWithoutDeleting();
  13659. closureState.mCapturing = false;
  13660. closureState.mClosureType = useTypeInstance;
  13661. closureInstanceInfo->mThisOverride = useTypeInstance;
  13662. mModule->mIncompleteMethodCount++;
  13663. SetAndRestoreValue<BfClosureState*> prevClosureState(mModule->mCurMethodState->mClosureState, &closureState);
  13664. if (mModule->HasExecutedOutput())
  13665. mModule->SetupIRMethod(methodInstance, methodInstance->mIRFunction, methodInstance->mAlwaysInline);
  13666. // This keeps us from giving errors twice. ProcessMethod can give errors when we capture by value but needed to
  13667. // capture by reference, so we still need to do it for resolve-only
  13668. bool processMethods = (mModule->mCompiler->GetAutoComplete() == NULL) && !mModule->mHadBuildError;
  13669. mModule->mBfIRBuilder->SaveDebugLocation();
  13670. //
  13671. {
  13672. BfGetSymbolReferenceKind prevSymbolRefKind = BfGetSymbolReferenceKind_None;
  13673. if (mModule->mCompiler->mResolvePassData != NULL)
  13674. {
  13675. prevSymbolRefKind = mModule->mCompiler->mResolvePassData->mGetSymbolReferenceKind;
  13676. mModule->mCompiler->mResolvePassData->mGetSymbolReferenceKind = BfGetSymbolReferenceKind_None;
  13677. }
  13678. if (processMethods)
  13679. {
  13680. // If we are in an always-ignored block, we will have mIgnoreWrites set
  13681. // SetAndRestoreValue<bool> prevWantsIgnoreWrite(mModule->mWantsIRIgnoreWrites, mModule->mBfIRBuilder->mIgnoreWrites);
  13682. // mModule->ProcessMethod(methodInstance);
  13683. }
  13684. if (mModule->mCompiler->mResolvePassData != NULL)
  13685. mModule->mCompiler->mResolvePassData->mGetSymbolReferenceKind = prevSymbolRefKind;
  13686. }
  13687. mModule->mBfIRBuilder->RestoreDebugLocation();
  13688. if (mModule->IsSkippingExtraResolveChecks())
  13689. closureFunc = BfIRFunction();
  13690. BfIRFunction dtorFunc;
  13691. if (lambdaBindExpr->mDtor != NULL)
  13692. {
  13693. SizedArray<BfIRType, 1> newTypes;
  13694. newTypes.push_back(mModule->mBfIRBuilder->MapType(useTypeInstance));
  13695. auto voidType = mModule->GetPrimitiveType(BfTypeCode_None);
  13696. auto dtorFuncType = mModule->mBfIRBuilder->CreateFunctionType(mModule->mBfIRBuilder->MapType(voidType), newTypes, false);
  13697. BfMethodDef* dtorMethodDef = new BfMethodDef();
  13698. dtorMethodDef->mDeclaringType = mModule->mCurMethodInstance->mMethodDef->mDeclaringType;
  13699. dtorMethodDef->mName = "~this$";
  13700. dtorMethodDef->mName += methodDef->mName;
  13701. dtorMethodDef->mMethodType = BfMethodType_Normal;
  13702. dtorMethodDef->mBody = lambdaBindExpr->mDtor;
  13703. dtorMethodDef->mIdx = mModule->mCurMethodInstance->mMethodDef->mIdx;
  13704. BfMethodInstance* dtorMethodInstance = new BfMethodInstance();
  13705. dtorMethodInstance->mMethodDef = dtorMethodDef;
  13706. dtorMethodInstance->mReturnType = mModule->GetPrimitiveType(BfTypeCode_None);
  13707. dtorMethodInstance->mMethodInstanceGroup = &methodInstanceGroup;
  13708. StringT<128> dtorMangledName;
  13709. BfMangler::Mangle(dtorMangledName, mModule->mCompiler->GetMangleKind(), dtorMethodInstance);
  13710. dtorFunc = mModule->mBfIRBuilder->CreateFunction(dtorFuncType, BfIRLinkageType_External, dtorMangledName);
  13711. mModule->SetupIRMethod(NULL, dtorFunc, false);
  13712. dtorMethodInstance->mIRFunction = dtorFunc;
  13713. mModule->mIncompleteMethodCount++;
  13714. mModule->mBfIRBuilder->SaveDebugLocation();
  13715. //
  13716. if (processMethods)
  13717. {
  13718. // If we are in an always-ignored block, we will have mIgnoreWrites set
  13719. // SetAndRestoreValue<bool> prevWantsIgnoreWrite(mModule->mWantsIRIgnoreWrites, mModule->mBfIRBuilder->mIgnoreWrites);
  13720. // mModule->ProcessMethod(dtorMethodInstance);
  13721. }
  13722. mModule->mBfIRBuilder->RestoreDebugLocation();
  13723. if (mModule->IsSkippingExtraResolveChecks())
  13724. dtorFunc = BfIRFunction();
  13725. if (dtorMethodInstance->mIsReified)
  13726. mModule->CheckHotMethod(dtorMethodInstance, dtorMangledName);
  13727. if ((dtorMethodInstance->mHotMethod != NULL) && (mModule->mCurMethodState->mHotDataReferenceBuilder))
  13728. mModule->mCurMethodState->mHotDataReferenceBuilder->mInnerMethods.Add(dtorMethodInstance->mHotMethod);
  13729. lambdaInstance->mDtorMethodInstance = dtorMethodInstance;
  13730. lambdaInstance->mDtorFunc = dtorFunc;
  13731. dtorMethodInstance->mMethodInstanceGroup = NULL;
  13732. }
  13733. prevClosureState.Restore();
  13734. if ((prevInsertBlock) && (!prevInsertBlock.IsFake()))
  13735. mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock);
  13736. for (auto& capturedEntry : capturedEntries)
  13737. {
  13738. BfLambdaCaptureInfo lambdaCapture;
  13739. if (capturedEntry.mName == "__this")
  13740. lambdaCapture.mName = "this";
  13741. else
  13742. lambdaCapture.mName = capturedEntry.mName;
  13743. lambdaInstance->mCaptures.Add(lambdaCapture);
  13744. closureInstanceInfo->mCaptureEntries.Add(capturedEntry);
  13745. }
  13746. if (processMethods)
  13747. rootMethodState->mDeferredLambdaInstances.Add(lambdaInstance);
  13748. methodInstance->mMethodInstanceGroup = NULL;
  13749. return lambdaInstance;
  13750. }
  13751. void BfExprEvaluator::Visit(BfLambdaBindExpression* lambdaBindExpr)
  13752. {
  13753. BfTokenNode* newToken = NULL;
  13754. BfCaptureInfo captureInfo;
  13755. BfAllocTarget allocTarget;
  13756. allocTarget.mCaptureInfo = &captureInfo;
  13757. ResolveAllocTarget(allocTarget, lambdaBindExpr->mNewToken, newToken);
  13758. if (mModule->mCurMethodInstance == NULL)
  13759. mModule->Fail("Invalid use of lambda bind expression", lambdaBindExpr);
  13760. if (((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mBlindCapturing)) ||
  13761. (mModule->mCurMethodInstance == NULL))
  13762. {
  13763. // We're just capturing. We just need to visit the bodies here. This helps infinite recursion with local methods containing lambdas calling each other
  13764. if (lambdaBindExpr->mBody != NULL)
  13765. mModule->VisitChild(lambdaBindExpr->mBody);
  13766. if ((lambdaBindExpr->mDtor != NULL) && (lambdaBindExpr->mDtor->mBody != NULL))
  13767. mModule->VisitChild(lambdaBindExpr->mDtor->mBody);
  13768. return;
  13769. }
  13770. BfLambdaInstance* lambdaInstance = GetLambdaInstance(lambdaBindExpr, allocTarget);
  13771. if (lambdaInstance == NULL)
  13772. return;
  13773. BfTypeInstance* delegateTypeInstance = lambdaInstance->mDelegateTypeInstance;
  13774. BfTypeInstance* useTypeInstance = lambdaInstance->mUseTypeInstance;
  13775. BfTypeInstance* closureTypeInst = lambdaInstance->mClosureTypeInstance;
  13776. mResult = BfTypedValue(mModule->AllocFromType(useTypeInstance, allocTarget, BfIRValue(), BfIRValue(), 0, BfAllocFlags_None), useTypeInstance);
  13777. if (!delegateTypeInstance->IsDelegate())
  13778. {
  13779. mModule->AssertErrorState();
  13780. return;
  13781. }
  13782. auto baseDelegateType = VerifyBaseDelegateType(delegateTypeInstance->mBaseType);
  13783. if (baseDelegateType == NULL)
  13784. {
  13785. mModule->Fail("Invalid delegate type", lambdaBindExpr);
  13786. return;
  13787. }
  13788. mModule->PopulateType(baseDelegateType);
  13789. auto& funcPtrField = baseDelegateType->mFieldInstances[0];
  13790. auto& targetField = baseDelegateType->mFieldInstances[1];
  13791. auto baseDelegate = mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->MapType(baseDelegateType));
  13792. // >> delegate.mTarget = bindResult.mTarget
  13793. auto nullPtrType = mModule->GetPrimitiveType(BfTypeCode_NullPtr);
  13794. BfIRValue valPtr;
  13795. if (!lambdaInstance->mIsStatic)
  13796. valPtr = mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->MapType(nullPtrType));
  13797. else
  13798. valPtr = mModule->GetDefaultValue(nullPtrType);
  13799. auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(baseDelegate, 0, targetField.mDataIdx);
  13800. mModule->mBfIRBuilder->CreateAlignedStore(valPtr, fieldPtr, targetField.mResolvedType->mAlign);
  13801. // >> delegate.mFuncPtr = bindResult.mFunc
  13802. if (lambdaInstance->mClosureFunc)
  13803. {
  13804. auto nullPtrType = mModule->GetPrimitiveType(BfTypeCode_NullPtr);
  13805. auto valPtr = mModule->mBfIRBuilder->CreateBitCast(lambdaInstance->mClosureFunc, mModule->mBfIRBuilder->MapType(nullPtrType));
  13806. auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(baseDelegate, 0, funcPtrField.mDataIdx);
  13807. mModule->mBfIRBuilder->CreateAlignedStore(valPtr, fieldPtr, funcPtrField.mResolvedType->mAlign);
  13808. }
  13809. mModule->AddDependency(useTypeInstance, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_Calls);
  13810. // Copy captures into the delegate
  13811. if (lambdaInstance->mClosureTypeInstance != NULL)
  13812. {
  13813. int fieldIdx = 0;
  13814. if (lambdaInstance->mCopyOuterCaptures)
  13815. {
  13816. for (auto& fieldInstance : lambdaInstance->mOuterClosure->mFieldInstances)
  13817. {
  13818. if (!fieldInstance.mResolvedType->IsValuelessType())
  13819. {
  13820. BF_ASSERT(fieldInstance.mDataIdx == fieldIdx + 1);
  13821. auto localVar = mModule->mCurMethodState->mLocals[0];
  13822. auto capturedValue = mModule->mBfIRBuilder->CreateInBoundsGEP(localVar->mValue, 0, fieldInstance.mDataIdx);
  13823. capturedValue = mModule->mBfIRBuilder->CreateAlignedLoad(capturedValue, fieldInstance.mResolvedType->mAlign);
  13824. auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(mResult.mValue, 0, fieldInstance.mDataIdx);
  13825. mModule->mBfIRBuilder->CreateStore(capturedValue, fieldPtr);
  13826. fieldIdx++;
  13827. }
  13828. }
  13829. }
  13830. int captureIdx = 0;
  13831. for (int captureIdx = 0; captureIdx < (int)lambdaInstance->mCaptures.size(); captureIdx++)
  13832. {
  13833. auto& capturedEntry = lambdaInstance->mCaptures[captureIdx];
  13834. auto& closureCaptureEntry = lambdaInstance->mMethodInstance->mMethodInfoEx->mClosureInstanceInfo->mCaptureEntries[captureIdx];
  13835. BfIdentifierNode* identifierNode = closureCaptureEntry.mNameNode;
  13836. BfIRValue capturedValue;
  13837. auto fieldInstance = &closureTypeInst->mFieldInstances[fieldIdx];
  13838. BfTypedValue capturedTypedVal;
  13839. if (identifierNode != NULL)
  13840. capturedTypedVal = DoImplicitArgCapture(NULL, identifierNode, closureCaptureEntry.mShadowIdx);
  13841. else
  13842. capturedTypedVal = LookupIdentifier(NULL, capturedEntry.mName);
  13843. if (!fieldInstance->mResolvedType->IsRef())
  13844. capturedTypedVal = mModule->LoadOrAggregateValue(capturedTypedVal);
  13845. else if (!capturedTypedVal.IsAddr())
  13846. capturedTypedVal = mModule->MakeAddressable(capturedTypedVal, false, true);
  13847. capturedValue = capturedTypedVal.mValue;
  13848. if (capturedValue)
  13849. {
  13850. if (!IsVar(capturedTypedVal.mType))
  13851. {
  13852. auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(mResult.mValue, 0, fieldInstance->mDataIdx);
  13853. mModule->mBfIRBuilder->CreateAlignedStore(capturedValue, fieldPtr, fieldInstance->mResolvedType->mAlign);
  13854. }
  13855. }
  13856. else
  13857. {
  13858. mModule->Fail(StrFormat("Unable to capture '%s'", capturedEntry.mName.c_str()), lambdaBindExpr);
  13859. mModule->AssertErrorState();
  13860. }
  13861. fieldIdx++;
  13862. }
  13863. if (lambdaInstance->mDtorFunc)
  13864. {
  13865. auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(mResult.mValue, 0, closureTypeInst->mFieldInstances[fieldIdx].mDataIdx);
  13866. auto voidType = mModule->GetPrimitiveType(BfTypeCode_None);
  13867. auto voidPtrType = mModule->CreatePointerType(voidType);
  13868. auto dtorThunk = mModule->mBfIRBuilder->CreateBitCast(lambdaInstance->mDtorFunc, mModule->mBfIRBuilder->MapType(voidPtrType));
  13869. mModule->mBfIRBuilder->CreateAlignedStore(dtorThunk, fieldPtr, mModule->mSystem->mPtrSize);
  13870. fieldIdx++;
  13871. }
  13872. }
  13873. }
  13874. void BfExprEvaluator::ProcessArrayInitializer(BfTokenNode* openToken, const BfSizedArray<BfExpression*>& valueExprs, const BfSizedArray<BfTokenNode*>& commas, BfTokenNode* closeToken, int dimensions, SizedArrayImpl<int64>& dimLengths, int dim, bool& hasFailed)
  13875. {
  13876. bool setSize = false;
  13877. if (dim == dimLengths.size())
  13878. {
  13879. dimLengths.push_back((int)valueExprs.size());
  13880. setSize = true;
  13881. }
  13882. else if (dimLengths[dim] == -1)
  13883. {
  13884. dimLengths[dim] = (int)valueExprs.size();
  13885. setSize = true;
  13886. }
  13887. int64 initCountDiff = (int)valueExprs.size() - dimLengths[dim];
  13888. if ((dimLengths[dim] != -1) && (initCountDiff != 0) && (!hasFailed))
  13889. {
  13890. if (initCountDiff > 0)
  13891. {
  13892. mModule->Fail(StrFormat("Too many initializers, expected %d fewer", initCountDiff), valueExprs[(int)dimLengths[dim]]);
  13893. hasFailed = true;
  13894. }
  13895. else
  13896. {
  13897. // If it ends with ", ?) or ",)" then allow unsized
  13898. if (((valueExprs.size() == 0) || (BfNodeDynCast<BfUninitializedExpression>(valueExprs.back()) == NULL)) &&
  13899. (commas.size() < valueExprs.size()))
  13900. {
  13901. BfAstNode* refNode = closeToken;
  13902. if ((refNode == NULL) && (mModule->mParentNodeEntry != NULL))
  13903. refNode = mModule->mParentNodeEntry->mNode;
  13904. mModule->Fail(StrFormat("Too few initializer, expected %d more", -initCountDiff), refNode);
  13905. hasFailed = true;
  13906. }
  13907. }
  13908. }
  13909. for (int i = 0; i < (int)valueExprs.size(); i++)
  13910. {
  13911. BfExpression* expr = valueExprs[i];
  13912. if (auto uninitExpr = BfNodeDynCast<BfUninitializedExpression>(expr))
  13913. {
  13914. continue;
  13915. }
  13916. auto innerInitExpr = BfNodeDynCast<BfCollectionInitializerExpression>(expr);
  13917. if (dim < dimensions - 1)
  13918. {
  13919. if (innerInitExpr == NULL)
  13920. {
  13921. if (auto innerTupleExpr = BfNodeDynCast<BfTupleExpression>(expr))
  13922. {
  13923. ProcessArrayInitializer(innerTupleExpr->mOpenParen, innerTupleExpr->mValues, innerTupleExpr->mCommas, innerTupleExpr->mCloseParen, dimensions, dimLengths, dim + 1, hasFailed);
  13924. }
  13925. else if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(expr))
  13926. {
  13927. SizedArray<BfExpression*, 1> values;
  13928. values.Add(parenExpr->mExpression);
  13929. SizedArray<BfTokenNode*, 1> commas;
  13930. ProcessArrayInitializer(parenExpr->mOpenParen, values, commas, parenExpr->mCloseParen, dimensions, dimLengths, dim + 1, hasFailed);
  13931. }
  13932. else
  13933. {
  13934. hasFailed = true;
  13935. mModule->Fail("A nested array initializer is expected", expr);
  13936. continue;
  13937. }
  13938. }
  13939. else
  13940. ProcessArrayInitializer(innerInitExpr->mOpenBrace, innerInitExpr->mValues, innerInitExpr->mCommas, innerInitExpr->mCloseBrace, dimensions, dimLengths, dim + 1, hasFailed);
  13941. }
  13942. else if (innerInitExpr != NULL)
  13943. {
  13944. hasFailed = true;
  13945. mModule->Fail("Unexpected nested initializer", expr);
  13946. ProcessArrayInitializer(innerInitExpr->mOpenBrace, innerInitExpr->mValues, innerInitExpr->mCommas, innerInitExpr->mCloseBrace, dimensions, dimLengths, dim + 1, hasFailed);
  13947. }
  13948. else
  13949. {
  13950. //mModule->Fail("Expected initializer", )
  13951. }
  13952. }
  13953. }
  13954. void BfExprEvaluator::CheckObjectCreateTypeRef(BfType* expectingType, BfAstNode* afterNode)
  13955. {
  13956. auto autoComplete = GetAutoComplete();
  13957. if ((autoComplete != NULL) && (afterNode != NULL) && (autoComplete->mIsAutoComplete) &&
  13958. (afterNode->IsFromParser(mModule->mCompiler->mResolvePassData->mParsers[0])) &&
  13959. (afterNode->GetParser()->mCursorIdx == afterNode->GetSrcEnd() + 1))
  13960. {
  13961. BfType* expectingType = mExpectingType;
  13962. BfTypeInstance* expectingTypeInst = NULL;
  13963. if (mExpectingType != NULL)
  13964. {
  13965. expectingTypeInst = mExpectingType->ToTypeInstance();
  13966. }
  13967. if ((mExpectingType != NULL) && (((expectingTypeInst == NULL) || (!expectingTypeInst->mTypeDef->mIsDelegate))))
  13968. {
  13969. // Why were we doing this? It floods the autocomplete with every possible type
  13970. //autoComplete->AddTopLevelTypes(NULL);
  13971. autoComplete->mInsertStartIdx = afterNode->GetSourceData()->ToParser()->mCursorIdx;
  13972. BF_ASSERT(autoComplete->mInsertStartIdx != -1);
  13973. auto expectingType = mExpectingType;
  13974. while (expectingType->IsArray())
  13975. {
  13976. auto arrayType = (BfArrayType*)expectingType;
  13977. expectingType = arrayType->mGenericTypeInfo->mTypeGenericArguments[0];
  13978. }
  13979. auto expectingTypeInst = expectingType->ToTypeInstance();
  13980. if (expectingTypeInst != NULL)
  13981. {
  13982. if (!expectingTypeInst->IsAnonymous())
  13983. autoComplete->AddTypeInstanceEntry(expectingTypeInst);
  13984. }
  13985. else
  13986. autoComplete->mDefaultSelection = mModule->TypeToString(expectingType);
  13987. }
  13988. }
  13989. }
  13990. void BfExprEvaluator::Visit(BfObjectCreateExpression* objCreateExpr)
  13991. {
  13992. CreateObject(objCreateExpr, objCreateExpr->mNewNode, NULL, NULL);
  13993. }
  13994. void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAstNode* allocNode, BfType* wantAllocType, BfInlineTypeReference* inlineTypeRef)
  13995. {
  13996. auto autoComplete = GetAutoComplete();
  13997. if ((autoComplete != NULL) && (objCreateExpr != NULL) && (objCreateExpr->mTypeRef != NULL))
  13998. {
  13999. autoComplete->CheckTypeRef(objCreateExpr->mTypeRef, false, true);
  14000. }
  14001. if ((autoComplete != NULL) && (objCreateExpr != NULL) && (objCreateExpr->mOpenToken != NULL) && (objCreateExpr->mCloseToken != NULL) &&
  14002. (objCreateExpr->mOpenToken->mToken == BfToken_LBrace) && (autoComplete->CheckFixit(objCreateExpr->mOpenToken)))
  14003. {
  14004. auto refNode = objCreateExpr->mOpenToken;
  14005. BfParserData* parser = refNode->GetSourceData()->ToParserData();
  14006. if (parser != NULL)
  14007. {
  14008. autoComplete->AddEntry(AutoCompleteEntry("fixit", StrFormat("Change initializer braces to parentheses\treformat|%s|%d-1|(\x01|%s|%d-1|)",
  14009. parser->mFileName.c_str(), refNode->mSrcStart,
  14010. parser->mFileName.c_str(), objCreateExpr->mCloseToken->mSrcStart).c_str()));
  14011. }
  14012. }
  14013. BfMethodGenericArguments methodGenericArguments;
  14014. if ((objCreateExpr != NULL) && (objCreateExpr->mCtorExplicit != NULL) && (objCreateExpr->mCtorExplicit->mGenericArgs != NULL))
  14015. methodGenericArguments.mArguments = &objCreateExpr->mCtorExplicit->mGenericArgs->mGenericArgs;
  14016. CheckObjectCreateTypeRef(mExpectingType, allocNode);
  14017. BfAttributeState attributeState;
  14018. attributeState.mTarget = BfAttributeTargets_Alloc;
  14019. SetAndRestoreValue<BfAttributeState*> prevAttributeState(mModule->mAttributeState, &attributeState);
  14020. BfTokenNode* newToken = NULL;
  14021. BfAllocTarget allocTarget;
  14022. ResolveAllocTarget(allocTarget, allocNode, newToken, &attributeState.mCustomAttributes);
  14023. bool isStructAlloc = newToken == NULL;
  14024. bool isScopeAlloc = (newToken != NULL) && (newToken->GetToken() == BfToken_Scope);
  14025. bool isAppendAlloc = (newToken != NULL) && (newToken->GetToken() == BfToken_Append);
  14026. bool isStackAlloc = (isScopeAlloc) || (isStructAlloc);
  14027. bool isArrayAlloc = false;// (objCreateExpr->mArraySizeSpecifier != NULL);
  14028. bool isRawArrayAlloc = (objCreateExpr != NULL) && (objCreateExpr->mStarToken != NULL);
  14029. if ((objCreateExpr != NULL) && (objCreateExpr->mCtorExplicit != NULL) && (objCreateExpr->mCtorExplicit->mThisToken != NULL))
  14030. {
  14031. mModule->SetElementType(objCreateExpr->mCtorExplicit->mThisToken, BfSourceElementType_Method);
  14032. }
  14033. if (isScopeAlloc)
  14034. {
  14035. if ((mBfEvalExprFlags & BfEvalExprFlags_FieldInitializer) != 0)
  14036. {
  14037. mModule->Warn(0, "This allocation will only be in scope during the constructor. Consider using a longer-term allocation such as 'new'", allocNode);
  14038. }
  14039. if (allocNode == newToken) // Scope, no target specified
  14040. {
  14041. if (mModule->mParentNodeEntry != NULL)
  14042. {
  14043. if (auto assignExpr = BfNodeDynCastExact<BfAssignmentExpression>(mModule->mParentNodeEntry->mNode))
  14044. {
  14045. if (mModule->mCurMethodState->mCurScope->mCloseNode == NULL)
  14046. {
  14047. // If we are assigning this to a property then it's possible the property setter can actually deal with a temporary allocation so no warning in that case
  14048. if ((mBfEvalExprFlags & BfEvalExprFlags_PendingPropSet) == 0)
  14049. mModule->Warn(0, "This allocation will immediately go out of scope. Consider specifying a wider scope target such as 'scope::'", allocNode);
  14050. }
  14051. }
  14052. }
  14053. }
  14054. }
  14055. BfAutoParentNodeEntry autoParentNodeEntry(mModule, objCreateExpr);
  14056. SizedArray<BfAstNode*, 2> dimLengthRefs;
  14057. SizedArray<BfIRValue, 2> dimLengthVals;
  14058. BfArrayType* arrayType = NULL;
  14059. BfType* unresolvedTypeRef = NULL;
  14060. BfType* resolvedTypeRef = NULL;
  14061. if (wantAllocType != NULL)
  14062. {
  14063. unresolvedTypeRef = wantAllocType;
  14064. resolvedTypeRef = wantAllocType;
  14065. }
  14066. else if (objCreateExpr->mTypeRef == NULL)
  14067. {
  14068. if ((!mExpectingType) || (!mExpectingType->IsArray()))
  14069. {
  14070. mModule->Fail("Cannot imply array type. Explicitly state array type or use array in an assignment to an array type.", objCreateExpr);
  14071. resolvedTypeRef = mModule->mContext->mBfObjectType;
  14072. unresolvedTypeRef = resolvedTypeRef;
  14073. }
  14074. else
  14075. {
  14076. auto arrayType = (BfArrayType*)mExpectingType;
  14077. unresolvedTypeRef = arrayType->GetUnderlyingType();
  14078. resolvedTypeRef = unresolvedTypeRef;
  14079. }
  14080. }
  14081. else
  14082. {
  14083. if ((objCreateExpr->mTypeRef->IsExact<BfDotTypeReference>()) && (mExpectingType != NULL))
  14084. {
  14085. //mModule->SetElementType(objCreateExpr->mTypeRef, BfSourceElementType_TypeRef);
  14086. if ((mExpectingType->IsObject()) || (mExpectingType->IsGenericParam()))
  14087. {
  14088. unresolvedTypeRef = mExpectingType;
  14089. if (unresolvedTypeRef->IsArray())
  14090. {
  14091. arrayType = (BfArrayType*)unresolvedTypeRef;
  14092. unresolvedTypeRef = unresolvedTypeRef->GetUnderlyingType();
  14093. isArrayAlloc = true;
  14094. }
  14095. }
  14096. else if (mExpectingType->IsPointer())
  14097. {
  14098. unresolvedTypeRef = mExpectingType->GetUnderlyingType();
  14099. }
  14100. else if (mExpectingType->IsStruct())
  14101. {
  14102. unresolvedTypeRef = mExpectingType;
  14103. }
  14104. else if (mExpectingType->IsVar())
  14105. unresolvedTypeRef = mExpectingType;
  14106. }
  14107. if (unresolvedTypeRef == NULL)
  14108. {
  14109. if (auto arrayTypeRef = BfNodeDynCast<BfArrayTypeRef>(objCreateExpr->mTypeRef))
  14110. {
  14111. isArrayAlloc = true;
  14112. if (auto dotTypeRef = BfNodeDynCast<BfDotTypeReference>(arrayTypeRef->mElementType))
  14113. {
  14114. if ((mExpectingType != NULL) &&
  14115. ((mExpectingType->IsArray()) || (mExpectingType->IsPointer()) || (mExpectingType->IsSizedArray())))
  14116. unresolvedTypeRef = mExpectingType->GetUnderlyingType();
  14117. }
  14118. if (unresolvedTypeRef == NULL)
  14119. unresolvedTypeRef = mModule->ResolveTypeRef(arrayTypeRef->mElementType);
  14120. if (unresolvedTypeRef == NULL)
  14121. unresolvedTypeRef = mModule->GetPrimitiveType(BfTypeCode_Var);
  14122. int dimensions = 1;
  14123. bool commaExpected = false;
  14124. if (arrayTypeRef->mParams.size() != 0)
  14125. {
  14126. auto intType = mModule->ResolveTypeDef(mModule->mSystem->mTypeIntPtr);
  14127. for (auto arg : arrayTypeRef->mParams)
  14128. {
  14129. if (auto tokenNode = BfNodeDynCastExact<BfTokenNode>(arg))
  14130. {
  14131. if (tokenNode->GetToken() == BfToken_Comma)
  14132. {
  14133. if (isRawArrayAlloc)
  14134. {
  14135. mModule->Fail("Sized arrays cannot be multidimensional.", tokenNode);
  14136. continue;
  14137. }
  14138. dimensions++;
  14139. if (dimensions == 5)
  14140. {
  14141. mModule->Fail("Too many array dimensions, consider using a jagged array.", tokenNode);
  14142. }
  14143. commaExpected = false;
  14144. continue;
  14145. }
  14146. }
  14147. auto expr = BfNodeDynCast<BfExpression>(arg);
  14148. if ((isRawArrayAlloc) && (!dimLengthVals.IsEmpty()))
  14149. {
  14150. mModule->CreateValueFromExpression(expr, intType);
  14151. continue;
  14152. }
  14153. dimLengthRefs.Add(expr);
  14154. BfTypedValue dimLength;
  14155. if (expr == NULL)
  14156. {
  14157. // Not specified
  14158. dimLengthVals.push_back(BfIRValue());
  14159. continue;
  14160. }
  14161. if (arg != NULL)
  14162. {
  14163. dimLength = mModule->CreateValueFromExpression(expr, intType, BfEvalExprFlags_NoCast);
  14164. BfCastFlags castFlags = BfCastFlags_None;
  14165. if ((dimLength) && (dimLength.mType->IsInteger()))
  14166. {
  14167. // Allow uint for size - just force to int
  14168. if (!((BfPrimitiveType*)dimLength.mType)->IsSigned())
  14169. castFlags = BfCastFlags_Explicit;
  14170. }
  14171. if (dimLength)
  14172. dimLength = mModule->Cast(expr, dimLength, intType, castFlags);
  14173. }
  14174. if (commaExpected)
  14175. {
  14176. mModule->AssertErrorState();
  14177. continue;
  14178. }
  14179. if (!dimLength)
  14180. {
  14181. dimLength = mModule->GetDefaultTypedValue(intType);
  14182. }
  14183. dimLengthVals.push_back(dimLength.mValue);
  14184. commaExpected = true;
  14185. }
  14186. }
  14187. if ((arrayTypeRef->mParams.size() == 0) && (objCreateExpr->mOpenToken == NULL))
  14188. mModule->Fail("Array size or array initializer expected", arrayTypeRef->mOpenBracket);
  14189. if (dimensions > 4)
  14190. dimensions = 4;
  14191. if ((!isRawArrayAlloc) && (!unresolvedTypeRef->IsVar()))
  14192. arrayType = mModule->CreateArrayType(unresolvedTypeRef, dimensions);
  14193. }
  14194. if (unresolvedTypeRef == NULL)
  14195. {
  14196. unresolvedTypeRef = ResolveTypeRef(objCreateExpr->mTypeRef, BfPopulateType_Declaration, BfResolveTypeRefFlag_NoResolveGenericParam);
  14197. }
  14198. }
  14199. resolvedTypeRef = unresolvedTypeRef;
  14200. if ((resolvedTypeRef != NULL) && (IsVar(resolvedTypeRef)))
  14201. resolvedTypeRef = unresolvedTypeRef;
  14202. }
  14203. if (inlineTypeRef != NULL)
  14204. {
  14205. auto inlineType = mModule->ResolveTypeRef(inlineTypeRef);
  14206. if (inlineType != NULL)
  14207. {
  14208. unresolvedTypeRef = inlineType;
  14209. resolvedTypeRef = inlineType;
  14210. }
  14211. }
  14212. if (resolvedTypeRef == NULL)
  14213. {
  14214. unresolvedTypeRef = mModule->GetPrimitiveType(BfTypeCode_Var);
  14215. resolvedTypeRef = unresolvedTypeRef;
  14216. }
  14217. auto resultType = resolvedTypeRef;
  14218. if ((resolvedTypeRef->IsInterface()) && (!isArrayAlloc))
  14219. {
  14220. mModule->Fail("Cannot create an instance of an interface", objCreateExpr->mTypeRef);
  14221. resolvedTypeRef = mModule->mContext->mBfObjectType;
  14222. }
  14223. BfTypeInstance* typeInstance = resolvedTypeRef->ToTypeInstance();
  14224. int elementSize = resolvedTypeRef->mSize;
  14225. int elementAlign = resolvedTypeRef->mAlign;
  14226. BfIRType allocType = mModule->mBfIRBuilder->MapType(resolvedTypeRef);
  14227. if (typeInstance != NULL)
  14228. {
  14229. if (!mModule->mCurTypeInstance->mResolvingVarField)
  14230. mModule->PopulateType(typeInstance);
  14231. if ((typeInstance->mTypeDef->mIsDelegate) && (!isArrayAlloc))
  14232. mModule->Fail("Delegates must be constructed through delegate binding", objCreateExpr->mTypeRef);
  14233. elementSize = BF_MAX(0, typeInstance->mInstSize);
  14234. elementAlign = typeInstance->mInstAlign;
  14235. allocType = mModule->mBfIRBuilder->MapTypeInst(typeInstance);
  14236. }
  14237. if (isAppendAlloc)
  14238. {
  14239. if (!mModule->mCurTypeInstance->IsObject())
  14240. {
  14241. mModule->Fail("Append allocations are only allowed in classes", allocNode);
  14242. isAppendAlloc = false;
  14243. }
  14244. else if ((mBfEvalExprFlags & BfEvalExprFlags_VariableDeclaration) == 0)
  14245. {
  14246. mModule->Fail("Append allocations are only allowed as local variable initializers in constructor body", allocNode);
  14247. isAppendAlloc = false;
  14248. }
  14249. else
  14250. {
  14251. auto methodDef = mModule->mCurMethodInstance->mMethodDef;
  14252. if (methodDef->mMethodType == BfMethodType_CtorCalcAppend)
  14253. {
  14254. mModule->Fail("Append allocations are only allowed as local variable declarations in the main method body", allocNode);
  14255. isAppendAlloc = false;
  14256. }
  14257. else if (!methodDef->HasAppend())
  14258. {
  14259. mModule->Fail("Append allocations can only be used on constructors with [AllowAppend] specified", allocNode);
  14260. isAppendAlloc = false;
  14261. }
  14262. else if (methodDef->mMethodType != BfMethodType_Ctor)
  14263. {
  14264. mModule->Fail("Append allocations are only allowed in constructors", allocNode);
  14265. isAppendAlloc = false;
  14266. }
  14267. else if (methodDef->mIsStatic)
  14268. {
  14269. mModule->Fail("Append allocations are only allowed in non-static constructors", allocNode);
  14270. isAppendAlloc = false;
  14271. }
  14272. }
  14273. }
  14274. if (isArrayAlloc)
  14275. {
  14276. const int MAX_DIMENSIONS = 2;
  14277. int dimensions = 1;
  14278. if (arrayType != NULL)
  14279. {
  14280. dimensions = arrayType->mDimensions;
  14281. mModule->AddDependency(arrayType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_Calls);
  14282. }
  14283. bool zeroMemory = true;
  14284. if (objCreateExpr->mOpenToken != NULL)
  14285. {
  14286. if ((objCreateExpr->mArguments.size() == 1) &&
  14287. (BfNodeDynCastExact<BfUninitializedExpression>(objCreateExpr->mArguments[0]) != NULL))
  14288. {
  14289. // Special case for a single "{ ? }"
  14290. zeroMemory = false;
  14291. }
  14292. else
  14293. {
  14294. SizedArray<int64, 2> dimLengths;
  14295. if (dimLengthVals.size() != 0)
  14296. {
  14297. for (int dim = 0; dim < dimensions; dim++)
  14298. {
  14299. BfIRValue dimLengthVal;
  14300. if (dim < (int)dimLengthVals.size())
  14301. dimLengthVal = dimLengthVals[dim];
  14302. if (!dimLengthVal)
  14303. {
  14304. dimLengths.push_back(-1);
  14305. continue;
  14306. }
  14307. auto constant = mModule->mBfIRBuilder->GetConstant(dimLengthVal);
  14308. if ((constant != NULL) && (mModule->mBfIRBuilder->IsInt(constant->mTypeCode)))
  14309. {
  14310. int64 dimLength = constant->mInt64;
  14311. if (dimLength < 0)
  14312. {
  14313. mModule->Fail(StrFormat("Invalid array dimension '%lld'", dimLength), dimLengthRefs[dim]);
  14314. dimLength = -1;
  14315. }
  14316. dimLengths.push_back(dimLength);
  14317. }
  14318. else if ((constant != NULL) && (constant->mConstType == BfConstType_Undef))
  14319. {
  14320. dimLengths.push_back(-1);
  14321. }
  14322. else
  14323. {
  14324. mModule->Fail("A constant length is required when using an initializer", dimLengthRefs[dim]);
  14325. dimLengths.push_back(-1);
  14326. }
  14327. }
  14328. }
  14329. // Ending in an ", )" means we need to zero-fill ending
  14330. zeroMemory = objCreateExpr->mCommas.size() >= objCreateExpr->mArguments.size();
  14331. bool hasFailed = false;
  14332. ProcessArrayInitializer(objCreateExpr->mOpenToken, objCreateExpr->mArguments, objCreateExpr->mCommas, objCreateExpr->mCloseToken, dimensions, dimLengths, 0, hasFailed);
  14333. dimLengthVals.resize(dimLengths.size());
  14334. for (int i = 0; i < (int)dimLengthVals.size(); i++)
  14335. {
  14336. if (!dimLengthVals[i])
  14337. {
  14338. auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  14339. dimLengthVals[i] = mModule->GetConstValue(dimLengths[i], intType);
  14340. }
  14341. }
  14342. }
  14343. }
  14344. while ((int)dimLengthVals.size() < dimensions)
  14345. dimLengthVals.push_back(mModule->GetConstValue(0));
  14346. BfTypedValue arrayValue;
  14347. BfIRValue arraySize;
  14348. for (BfIRValue dimSize : dimLengthVals)
  14349. {
  14350. if (!arraySize)
  14351. arraySize = dimSize;
  14352. else
  14353. arraySize = mModule->mBfIRBuilder->CreateMul(arraySize, dimSize);
  14354. }
  14355. BfAllocFlags allocFlags = BfAllocFlags_None;
  14356. if (isRawArrayAlloc)
  14357. allocFlags = (BfAllocFlags)(allocFlags | BfAllocFlags_RawArray);
  14358. int writeIdx = 0;
  14359. struct BfInitContext
  14360. {
  14361. public:
  14362. BfModule* mModule;
  14363. BfType* resultType;
  14364. int dimensions;
  14365. SizedArray<BfIRValue, 2>& dimLengthVals;
  14366. BfIRValue arraySize;
  14367. int& writeIdx;
  14368. BfInitContext(BfModule* module, BfType* resultType, int dimensions, SizedArray<BfIRValue, 2>& dimLengthVals, BfIRValue arraySize, int& writeIdx) :
  14369. mModule(module), resultType(resultType), dimensions(dimensions), dimLengthVals(dimLengthVals), arraySize(arraySize), writeIdx(writeIdx)
  14370. {
  14371. }
  14372. void Handle(BfIRValue addr, int curDim, const BfSizedArray<BfExpression*>& valueExprs)
  14373. {
  14374. int exprIdx = 0;
  14375. int dimWriteIdx = 0;
  14376. bool isUninit = false;
  14377. int dimLength = -1;
  14378. if (dimLengthVals[curDim].IsConst())
  14379. {
  14380. auto constant = mModule->mBfIRBuilder->GetConstant(dimLengthVals[curDim]);
  14381. dimLength = constant->mInt32;
  14382. }
  14383. while (exprIdx < (int)valueExprs.size())
  14384. {
  14385. auto initExpr = valueExprs[exprIdx];
  14386. exprIdx++;
  14387. if (!initExpr)
  14388. break;
  14389. if (auto unintExpr = BfNodeDynCastExact<BfUninitializedExpression>(initExpr))
  14390. {
  14391. isUninit = true;
  14392. break;
  14393. }
  14394. if (exprIdx > dimLength)
  14395. break;
  14396. if (curDim < dimensions - 1)
  14397. {
  14398. if (auto innerTupleExpr = BfNodeDynCast<BfTupleExpression>(initExpr))
  14399. {
  14400. Handle(addr, curDim + 1, innerTupleExpr->mValues);
  14401. }
  14402. else if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(initExpr))
  14403. {
  14404. SizedArray<BfExpression*, 1> values;
  14405. values.Add(parenExpr->mExpression);
  14406. Handle(addr, curDim + 1, values);
  14407. }
  14408. else if (auto innerInitExpr = BfNodeDynCast<BfCollectionInitializerExpression>(initExpr))
  14409. {
  14410. Handle(addr, curDim + 1, innerInitExpr->mValues);
  14411. }
  14412. dimWriteIdx++;
  14413. continue;
  14414. }
  14415. BfIRValue elemAddr;
  14416. if (!resultType->IsValuelessType())
  14417. elemAddr = mModule->CreateIndexedValue(resultType, addr, writeIdx);
  14418. else
  14419. elemAddr = mModule->mBfIRBuilder->GetFakeVal();
  14420. writeIdx++;
  14421. dimWriteIdx++;
  14422. BfTypedValue elemPtrTypedVal = BfTypedValue(elemAddr, resultType, BfTypedValueKind_Addr);
  14423. BfExprEvaluator exprEvaluator(mModule);
  14424. exprEvaluator.mExpectingType = resultType;
  14425. exprEvaluator.mReceivingValue = &elemPtrTypedVal;
  14426. exprEvaluator.Evaluate(initExpr);
  14427. exprEvaluator.GetResult();
  14428. if (exprEvaluator.mReceivingValue == NULL)
  14429. {
  14430. // We wrote directly to the array in-place, we're done with this element
  14431. continue;
  14432. }
  14433. auto storeValue = exprEvaluator.mResult;
  14434. if (!storeValue)
  14435. continue;
  14436. storeValue = mModule->Cast(initExpr, storeValue, resultType);
  14437. if (!storeValue)
  14438. continue;
  14439. if (!resultType->IsValuelessType())
  14440. {
  14441. storeValue = mModule->LoadOrAggregateValue(storeValue);
  14442. mModule->mBfIRBuilder->CreateStore(storeValue.mValue, elemAddr);
  14443. }
  14444. }
  14445. int clearFromIdx = writeIdx;
  14446. int sectionElemCount = 1;
  14447. BfIRValue numElemsLeft = arraySize;
  14448. if (dimLength != -1)
  14449. {
  14450. int clearCount = dimLength - dimWriteIdx;
  14451. if (clearCount > 0)
  14452. {
  14453. for (int checkDim = curDim + 1; checkDim < (int)dimLengthVals.size(); checkDim++)
  14454. {
  14455. if (dimLengthVals[checkDim].IsConst())
  14456. {
  14457. auto constant = mModule->mBfIRBuilder->GetConstant(dimLengthVals[checkDim]);
  14458. clearCount *= constant->mInt32;
  14459. sectionElemCount *= constant->mInt32;
  14460. }
  14461. }
  14462. }
  14463. writeIdx += clearCount;
  14464. numElemsLeft = mModule->GetConstValue(clearCount);
  14465. }
  14466. // Actually leave it alone?
  14467. if ((isUninit) &&
  14468. ((mModule->IsOptimized()) || (mModule->mIsComptimeModule) || (mModule->mBfIRBuilder->mIgnoreWrites)))
  14469. return;
  14470. bool doClear = true;
  14471. if (numElemsLeft.IsConst())
  14472. {
  14473. auto constant = mModule->mBfIRBuilder->GetConstant(numElemsLeft);
  14474. doClear = constant->mInt64 > 0;
  14475. }
  14476. if (doClear)
  14477. {
  14478. // We multiply by GetStride. This relies on the fact that we over-allocate on the array allocation -- the last
  14479. // element doesn't need to be padded out to the element alignment, but we do anyway. Otherwise this would be
  14480. // a more complicated computation
  14481. auto clearBytes = mModule->mBfIRBuilder->CreateMul(numElemsLeft, mModule->GetConstValue(resultType->GetStride()));
  14482. if (isUninit)
  14483. {
  14484. // Limit to a reasonable number of bytes to stomp with 0xCC
  14485. int maxStompBytes = BF_MIN(128, resultType->GetStride() * sectionElemCount);
  14486. if (clearBytes.IsConst())
  14487. {
  14488. auto constant = mModule->mBfIRBuilder->GetConstant(clearBytes);
  14489. if (constant->mInt64 > maxStompBytes)
  14490. clearBytes = mModule->GetConstValue(maxStompBytes);
  14491. }
  14492. else
  14493. {
  14494. auto insertBlock = mModule->mBfIRBuilder->GetInsertBlock();
  14495. auto gtBlock = mModule->mBfIRBuilder->CreateBlock("unint.gt");
  14496. auto contBlock = mModule->mBfIRBuilder->CreateBlock("unint.cont");
  14497. auto cmp = mModule->mBfIRBuilder->CreateCmpLTE(clearBytes, mModule->GetConstValue(maxStompBytes), true);
  14498. mModule->mBfIRBuilder->CreateCondBr(cmp, contBlock, gtBlock);
  14499. mModule->mBfIRBuilder->AddBlock(gtBlock);
  14500. mModule->mBfIRBuilder->SetInsertPoint(gtBlock);
  14501. mModule->mBfIRBuilder->CreateBr(contBlock);
  14502. mModule->mBfIRBuilder->AddBlock(contBlock);
  14503. mModule->mBfIRBuilder->SetInsertPoint(contBlock);
  14504. auto phi = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(mModule->GetPrimitiveType(BfTypeCode_IntPtr)), 2);
  14505. mModule->mBfIRBuilder->AddPhiIncoming(phi, clearBytes, insertBlock);
  14506. mModule->mBfIRBuilder->AddPhiIncoming(phi, mModule->GetConstValue(maxStompBytes), gtBlock);
  14507. clearBytes = phi;
  14508. }
  14509. }
  14510. mModule->mBfIRBuilder->PopulateType(resultType);
  14511. if ((!resultType->IsValuelessType()) && (!addr.IsConst()))
  14512. {
  14513. mModule->mBfIRBuilder->CreateMemSet(mModule->CreateIndexedValue(resultType, addr, clearFromIdx),
  14514. mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int8, isUninit ? 0xCC : 0), clearBytes, resultType->mAlign);
  14515. }
  14516. }
  14517. }
  14518. };
  14519. BfInitContext initContext(mModule, resultType, dimensions, dimLengthVals, arraySize, writeIdx);
  14520. if (IsVar(resultType))
  14521. {
  14522. SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
  14523. mResult = BfTypedValue(BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), mModule->GetPrimitiveType(BfTypeCode_Var)));
  14524. initContext.Handle(mResult.mValue, 0, objCreateExpr->mArguments);
  14525. return;
  14526. }
  14527. if (isRawArrayAlloc)
  14528. {
  14529. // If we have a constant-sized alloc then make the type a pointer to the sized array, otherwise just a pointer to the raw type
  14530. BfType* ptrType = mModule->CreatePointerType(resultType);
  14531. if (isAppendAlloc)
  14532. arrayValue = BfTypedValue(mModule->AppendAllocFromType(resultType, BfIRValue(), 0, arraySize, (int)dimLengthVals.size(), isRawArrayAlloc, false), ptrType);
  14533. else
  14534. {
  14535. arrayValue = BfTypedValue(mModule->AllocFromType(resultType, allocTarget, BfIRValue(), arraySize, (int)dimLengthVals.size(), allocFlags, allocTarget.mAlignOverride), ptrType);
  14536. }
  14537. initContext.Handle(arrayValue.mValue, 0, objCreateExpr->mArguments);
  14538. mResult = arrayValue;
  14539. return;
  14540. }
  14541. if (dimLengthVals.size() > 4)
  14542. {
  14543. dimLengthVals.RemoveRange(4, dimLengthVals.size() - 4);
  14544. mModule->Fail("Too many array dimensions, consider using a jagged array.", objCreateExpr);
  14545. }
  14546. if (arrayType == NULL)
  14547. return;
  14548. if (isAppendAlloc)
  14549. arrayValue = BfTypedValue(mModule->AppendAllocFromType(resultType, BfIRValue(), 0, arraySize, (int)dimLengthVals.size(), isRawArrayAlloc, zeroMemory), arrayType);
  14550. else
  14551. {
  14552. arrayValue = BfTypedValue(mModule->AllocFromType(resultType, allocTarget, BfIRValue(), arraySize, (int)dimLengthVals.size(), allocFlags, allocTarget.mAlignOverride), arrayType);
  14553. if (isScopeAlloc)
  14554. {
  14555. // See notes below on "general" SkipObjectAccessCheck usage on why we can do this
  14556. mModule->SkipObjectAccessCheck(arrayValue);
  14557. }
  14558. }
  14559. //mModule->InitTypeInst(arrayValue, scopeData);
  14560. BfAstNode* refNode = objCreateExpr->mTypeRef;
  14561. while (true)
  14562. {
  14563. if (auto arrayRef = BfNodeDynCast<BfElementedTypeRef>(refNode))
  14564. {
  14565. refNode = arrayRef->mElementType;
  14566. continue;
  14567. }
  14568. break;
  14569. }
  14570. BfResolvedArgs resolvedArgs;
  14571. auto rawAutoComplete = mModule->mCompiler->GetAutoComplete();
  14572. if (rawAutoComplete != NULL)
  14573. {
  14574. SetAndRestoreValue<bool> prevCapturing(rawAutoComplete->mIsCapturingMethodMatchInfo, false);
  14575. MatchConstructor(refNode, objCreateExpr, arrayValue, arrayType, resolvedArgs, false, methodGenericArguments, BfAllowAppendKind_No);
  14576. }
  14577. else
  14578. {
  14579. MatchConstructor(refNode, objCreateExpr, arrayValue, arrayType, resolvedArgs, false, methodGenericArguments, BfAllowAppendKind_No);
  14580. }
  14581. //TODO: Assert 'length' var is at slot 1
  14582. mModule->PopulateType(arrayType->mBaseType, BfPopulateType_DataAndMethods);
  14583. mModule->mBfIRBuilder->PopulateType(arrayType);
  14584. auto arrayBits = mModule->mBfIRBuilder->CreateBitCast(arrayValue.mValue, mModule->mBfIRBuilder->MapTypeInstPtr(arrayType->mBaseType));
  14585. int arrayLengthBitCount = arrayType->GetLengthBitCount();
  14586. if (arrayLengthBitCount == 0)
  14587. {
  14588. mModule->Fail("INTERNAL ERROR: Unable to find array 'length' field", objCreateExpr);
  14589. return;
  14590. }
  14591. mResult = arrayValue;
  14592. auto lengthFieldInstance = mModule->GetFieldByName(arrayType->mBaseType->ToTypeInstance(), "mLength");
  14593. if (lengthFieldInstance == NULL)
  14594. return;
  14595. auto firstElementFieldInstance = mModule->GetFieldByName(arrayType->ToTypeInstance(), "mFirstElement");
  14596. if (firstElementFieldInstance == NULL)
  14597. return;
  14598. auto addr = mModule->mBfIRBuilder->CreateInBoundsGEP(arrayBits, 0, lengthFieldInstance->mDataIdx);
  14599. if (arrayLengthBitCount == 64)
  14600. mModule->mBfIRBuilder->CreateAlignedStore(arraySize, addr, 8);
  14601. else
  14602. {
  14603. auto arraySize32 = mModule->mBfIRBuilder->CreateNumericCast(arraySize, true, BfTypeCode_Int32);
  14604. mModule->mBfIRBuilder->CreateAlignedStore(arraySize32, addr, 4);
  14605. }
  14606. for (int lowerDim = 1; lowerDim < (int)dimLengthVals.size(); lowerDim++)
  14607. {
  14608. auto length1FieldInstance = mModule->GetFieldByName(arrayType->ToTypeInstance(), "mLength1");
  14609. if (length1FieldInstance == NULL)
  14610. return;
  14611. addr = mModule->mBfIRBuilder->CreateInBoundsGEP(arrayValue.mValue, 0, length1FieldInstance->mDataIdx + lowerDim - 1);
  14612. auto lowerDimVal = mModule->mBfIRBuilder->CreateNumericCast(dimLengthVals[lowerDim], true, (arrayLengthBitCount == 64) ? BfTypeCode_Int64 : BfTypeCode_Int32);
  14613. mModule->mBfIRBuilder->CreateStore(lowerDimVal, addr);
  14614. }
  14615. if (resultType->IsValuelessType())
  14616. addr = mModule->mBfIRBuilder->GetFakeVal();
  14617. else
  14618. addr = mModule->mBfIRBuilder->CreateInBoundsGEP(arrayValue.mValue, 0, firstElementFieldInstance->mDataIdx);
  14619. initContext.Handle(addr, 0, objCreateExpr->mArguments);
  14620. return;
  14621. }
  14622. else
  14623. {
  14624. if (resolvedTypeRef->IsVar())
  14625. {
  14626. // Leave as a var
  14627. }
  14628. else if ((!resolvedTypeRef->IsObjectOrInterface()) && (!resolvedTypeRef->IsGenericParam()))
  14629. {
  14630. resultType = mModule->CreatePointerType(resolvedTypeRef);
  14631. }
  14632. }
  14633. if ((isStackAlloc) && (mModule->mCurMethodState == NULL))
  14634. {
  14635. mModule->Fail("Cannot use 'stack' here", allocNode);
  14636. isStackAlloc = false;
  14637. isScopeAlloc = false;
  14638. }
  14639. bool isGenericParam = unresolvedTypeRef->IsGenericParam();
  14640. if (resolvedTypeRef->IsGenericParam())
  14641. {
  14642. BfGenericParamFlags genericParamFlags = BfGenericParamFlag_None;
  14643. BfType* typeConstraint = NULL;
  14644. auto genericParam = mModule->GetMergedGenericParamData((BfGenericParamType*)resolvedTypeRef, genericParamFlags, typeConstraint);
  14645. if (typeConstraint == NULL)
  14646. {
  14647. if ((genericParamFlags & BfGenericParamFlag_Var) != 0)
  14648. {
  14649. // Allow it
  14650. }
  14651. else
  14652. {
  14653. if ((genericParamFlags & BfGenericParamFlag_New) == 0)
  14654. {
  14655. mModule->Fail(StrFormat("Must add 'where %s : new' constraint to generic parameter to instantiate type", genericParam->GetName().c_str()), objCreateExpr->mTypeRef);
  14656. }
  14657. if (objCreateExpr->mArguments.size() != 0)
  14658. {
  14659. mModule->Fail(StrFormat("Only default parameterless constructors can be called on generic argument '%s'", genericParam->GetName().c_str()), objCreateExpr->mTypeRef);
  14660. }
  14661. }
  14662. }
  14663. if (((typeConstraint != NULL) && (typeConstraint->IsValueType())) ||
  14664. ((genericParamFlags & (BfGenericParamFlag_Struct | BfGenericParamFlag_StructPtr)) != 0))
  14665. {
  14666. resultType = mModule->CreatePointerType(resolvedTypeRef);
  14667. }
  14668. else if (((typeConstraint != NULL) && (!typeConstraint->IsValueType())) ||
  14669. ((genericParamFlags & (BfGenericParamFlag_Class)) != 0))
  14670. {
  14671. // Leave as 'T'
  14672. resultType = resolvedTypeRef;
  14673. }
  14674. else
  14675. resultType = mModule->CreateModifiedTypeType(resolvedTypeRef, BfToken_AllocType);
  14676. mResult.mType = resultType;
  14677. if (typeInstance == NULL)
  14678. {
  14679. mResult = mModule->GetDefaultTypedValue(resultType);
  14680. return;
  14681. }
  14682. }
  14683. else if (resolvedTypeRef->IsSizedArray())
  14684. {
  14685. // Handle the case of "int[3]* val = new .(1, 2, 3)"
  14686. if (auto dotTypeRef = BfNodeDynCastExact<BfDotTypeReference>(objCreateExpr->mTypeRef))
  14687. {
  14688. BfIRValue allocValue;
  14689. if (isAppendAlloc)
  14690. allocValue = mModule->AppendAllocFromType(resolvedTypeRef, BfIRValue(), 0, BfIRValue(), 0, false, false);
  14691. else
  14692. allocValue = mModule->AllocFromType(resolvedTypeRef, allocTarget, BfIRValue(), BfIRValue(), 0, BfAllocFlags_None);
  14693. auto result = BfTypedValue(allocValue, resolvedTypeRef, BfTypedValueKind_Addr);
  14694. InitializedSizedArray((BfSizedArrayType*)resolvedTypeRef, objCreateExpr->mOpenToken, objCreateExpr->mArguments, objCreateExpr->mCommas, objCreateExpr->mCloseToken, &result);
  14695. // Turn from an addr of a sized array to pointer of sized array
  14696. mResult = BfTypedValue(mResult.mValue, resultType);
  14697. return;
  14698. }
  14699. }
  14700. SetAndRestoreValue<bool> prevNoBind(mNoBind, mNoBind || isGenericParam);
  14701. if ((typeInstance != NULL) && (typeInstance->mTypeDef->mIsAbstract))
  14702. {
  14703. mModule->Fail("Cannot create an instance of an abstract class", objCreateExpr->mTypeRef);
  14704. return;
  14705. }
  14706. BfFunctionBindResult bindResult;
  14707. bindResult.mSkipThis = true;
  14708. bindResult.mWantsArgs = true;
  14709. SetAndRestoreValue<BfFunctionBindResult*> prevBindResult(mFunctionBindResult, &bindResult);
  14710. BfIRValue appendSizeValue;
  14711. BfTypedValue emtpyThis(mModule->mBfIRBuilder->GetFakeVal(), resolvedTypeRef, resolvedTypeRef->IsStruct());
  14712. BfResolvedArgs argValues;
  14713. if (objCreateExpr != NULL)
  14714. {
  14715. argValues.Init(objCreateExpr->mOpenToken, &objCreateExpr->mArguments, &objCreateExpr->mCommas, objCreateExpr->mCloseToken);
  14716. ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval); ////
  14717. }
  14718. if (typeInstance == NULL)
  14719. {
  14720. // No CTOR needed
  14721. if (objCreateExpr->mArguments.size() != 0)
  14722. {
  14723. mModule->Fail(StrFormat("Only default parameterless constructors can be called on primitive type '%s'", mModule->TypeToString(resolvedTypeRef).c_str()), objCreateExpr->mTypeRef);
  14724. }
  14725. }
  14726. else if ((autoComplete != NULL) && (objCreateExpr != NULL) && (objCreateExpr->mOpenToken != NULL))
  14727. {
  14728. auto wasCapturingMethodInfo = autoComplete->mIsCapturingMethodMatchInfo;
  14729. autoComplete->CheckInvocation(objCreateExpr, objCreateExpr->mOpenToken, objCreateExpr->mCloseToken, objCreateExpr->mCommas);
  14730. BfAstNode* refNode = objCreateExpr->mTypeRef;
  14731. if ((objCreateExpr->mCtorExplicit != NULL) && (objCreateExpr->mCtorExplicit->mThisToken != NULL))
  14732. refNode = objCreateExpr->mCtorExplicit->mThisToken;
  14733. auto checkTypeInst = typeInstance;
  14734. if (checkTypeInst->IsAnonymousInitializerType())
  14735. checkTypeInst = checkTypeInst->mBaseType;
  14736. MatchConstructor(refNode, objCreateExpr, emtpyThis, checkTypeInst, argValues, false, methodGenericArguments, BfAllowAppendKind_Infer);
  14737. if ((wasCapturingMethodInfo) && (!autoComplete->mIsCapturingMethodMatchInfo))
  14738. {
  14739. if (autoComplete->mMethodMatchInfo != NULL)
  14740. autoComplete->mIsCapturingMethodMatchInfo = true;
  14741. }
  14742. else
  14743. autoComplete->mIsCapturingMethodMatchInfo = false;
  14744. }
  14745. else if (!resolvedTypeRef->IsFunction())
  14746. {
  14747. auto refNode = allocNode;
  14748. if (objCreateExpr != NULL)
  14749. refNode = objCreateExpr->mTypeRef;
  14750. auto checkTypeInst = typeInstance;
  14751. if (checkTypeInst->IsAnonymousInitializerType())
  14752. checkTypeInst = checkTypeInst->mBaseType;
  14753. MatchConstructor(refNode, objCreateExpr, emtpyThis, checkTypeInst, argValues, false, methodGenericArguments, BfAllowAppendKind_Infer);
  14754. }
  14755. if (objCreateExpr != NULL)
  14756. mModule->ValidateAllocation(typeInstance, objCreateExpr->mTypeRef);
  14757. prevBindResult.Restore();
  14758. int allocAlign = resolvedTypeRef->mAlign;
  14759. if (typeInstance != NULL)
  14760. allocAlign = typeInstance->mInstAlign;
  14761. int appendAllocAlign = 0;
  14762. BfAllocFlags allocFlags = BfAllocFlags_None;
  14763. if ((bindResult.mMethodInstance != NULL) && (bindResult.mMethodInstance->mMethodDef->HasAppend()))
  14764. {
  14765. if (!bindResult.mFunc)
  14766. {
  14767. BF_ASSERT((!mModule->HasExecutedOutput()) || (mModule->mBfIRBuilder->mIgnoreWrites));
  14768. appendSizeValue = mModule->GetConstValue(0);
  14769. }
  14770. else
  14771. {
  14772. //auto calcAppendMethodModule = mModule->GetMethodInstanceAtIdx(bindResult.mMethodInstance->GetOwner(), bindResult.mMethodInstance->mMethodDef->mIdx + 1, BF_METHODNAME_CALCAPPEND);
  14773. BfTypeVector methodGenericArguments;
  14774. if (bindResult.mMethodInstance->mMethodInfoEx != NULL)
  14775. methodGenericArguments = bindResult.mMethodInstance->mMethodInfoEx->mMethodGenericArguments;
  14776. auto methodOwner = bindResult.mMethodInstance->GetOwner();
  14777. auto calcAppendMethodDef = methodOwner->mTypeDef->mMethods[bindResult.mMethodInstance->mMethodDef->mIdx + 1];
  14778. BF_ASSERT(calcAppendMethodDef->mName == BF_METHODNAME_CALCAPPEND);
  14779. auto calcAppendMethodModule = mModule->GetMethodInstance(methodOwner, calcAppendMethodDef, methodGenericArguments);
  14780. SizedArray<BfIRValue, 2> irArgs;
  14781. if (bindResult.mIRArgs.size() > 1)
  14782. irArgs.Insert(0, &bindResult.mIRArgs[1], bindResult.mIRArgs.size() - 1);
  14783. BfTypedValue appendSizeTypedValue = mModule->TryConstCalcAppend(calcAppendMethodModule.mMethodInstance, irArgs);
  14784. if (!appendSizeTypedValue)
  14785. {
  14786. BF_ASSERT(calcAppendMethodModule.mFunc);
  14787. appendSizeTypedValue = CreateCall(objCreateExpr, calcAppendMethodModule.mMethodInstance, calcAppendMethodModule.mFunc, false, irArgs);
  14788. BF_ASSERT(appendSizeTypedValue.mType == mModule->GetPrimitiveType(BfTypeCode_IntPtr));
  14789. }
  14790. appendSizeValue = appendSizeTypedValue.mValue;
  14791. allocAlign = BF_MAX(allocAlign, calcAppendMethodModule.mMethodInstance->mAppendAllocAlign);
  14792. appendAllocAlign = calcAppendMethodModule.mMethodInstance->mAppendAllocAlign;
  14793. if (calcAppendMethodModule.mMethodInstance->mHasAppendWantMark)
  14794. allocFlags = (BfAllocFlags)(allocFlags | BfAllocFlags_HasAppendWantMark);
  14795. }
  14796. if (appendAllocAlign != 0)
  14797. {
  14798. int endingAlign = typeInstance->GetEndingInstanceAlignment();
  14799. if (endingAlign % appendAllocAlign != 0)
  14800. {
  14801. int extraSize = appendAllocAlign - (endingAlign % appendAllocAlign);
  14802. appendSizeValue = mModule->mBfIRBuilder->CreateAdd(appendSizeValue, mModule->GetConstValue(extraSize));
  14803. }
  14804. }
  14805. if ((allocFlags & BfAllocFlags_HasAppendWantMark) != 0)
  14806. {
  14807. int markInfoSize = sizeof(intptr) + sizeof(intptr) * 4; // Stack trace, MarkAppendEntry
  14808. appendSizeValue = mModule->mBfIRBuilder->CreateAdd(appendSizeValue, mModule->GetConstValue(markInfoSize));
  14809. }
  14810. }
  14811. // WTF? I'm not even sure this is correct - add more tests
  14812. appendAllocAlign = BF_MAX(appendAllocAlign, allocAlign);
  14813. BfIRValue allocValue;
  14814. if (IsVar(resolvedTypeRef))
  14815. {
  14816. mResult = mModule->GetDefaultTypedValue(resultType);
  14817. return;
  14818. }
  14819. else
  14820. {
  14821. if (isAppendAlloc)
  14822. {
  14823. allocValue = mModule->AppendAllocFromType(resolvedTypeRef, appendSizeValue, appendAllocAlign);
  14824. }
  14825. else
  14826. {
  14827. allocValue = mModule->AllocFromType(resolvedTypeRef, allocTarget, appendSizeValue, BfIRValue(), 0, allocFlags, allocAlign);
  14828. }
  14829. if (((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) && (mModule->mCompiler->mCeMachine != NULL))
  14830. {
  14831. mModule->mCompiler->mCeMachine->SetAppendAllocInfo(mModule, allocValue, appendSizeValue);
  14832. }
  14833. mResult = BfTypedValue(allocValue, resultType);
  14834. }
  14835. if (isScopeAlloc)
  14836. {
  14837. // This allows readonly (ie: 'let') local usage to not require an access check. No matter what scope the alloc is tied to, the
  14838. // lifetime of the local variable will be no longer than that of the allocated value
  14839. mModule->SkipObjectAccessCheck(mResult);
  14840. }
  14841. /*if (typeInstance != NULL)
  14842. {
  14843. mModule->InitTypeInst(mResult, scopeData, true);
  14844. }
  14845. if (isStackAlloc)
  14846. {
  14847. mModule->AddStackAlloc(mResult, objCreateExpr, scopeData);
  14848. }*/
  14849. if (mResult)
  14850. {
  14851. if (bindResult.mMethodInstance == NULL)
  14852. {
  14853. // Why did we have this? It was already zeroed right?
  14854. // Zero
  14855. //mModule->mBfIRBuilder->CreateMemSet(mResult.mValue, mModule->GetConstValue8(0), mModule->GetConstValue(resolvedTypeRef->mSize), resolvedTypeRef->mAlign);
  14856. }
  14857. else if (bindResult.mFunc)
  14858. {
  14859. bool hasRealtimeLeakCheck = (mModule->mCompiler->mOptions.mEnableRealtimeLeakCheck) && (!IsComptime());
  14860. if ((typeInstance->IsObject()) || (typeInstance->IsAnonymousInitializerType()))
  14861. {
  14862. bool wantsCtorClear = true;
  14863. if (hasRealtimeLeakCheck)
  14864. {
  14865. // Dbg_ObjectAlloc clears internally so we don't need to call CtorClear for those
  14866. if ((!isStackAlloc) && (!isAppendAlloc) && (!allocTarget.mCustomAllocator) && (allocTarget.mScopedInvocationTarget == NULL))
  14867. wantsCtorClear = false;
  14868. }
  14869. if (wantsCtorClear)
  14870. {
  14871. auto ctorClear = mModule->GetMethodByName(typeInstance, "__BfCtorClear");
  14872. if (!ctorClear)
  14873. {
  14874. mModule->AssertErrorState();
  14875. }
  14876. else if ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) == 0)
  14877. {
  14878. SizedArray<BfIRValue, 1> irArgs;
  14879. irArgs.push_back(mResult.mValue);
  14880. CreateCall(objCreateExpr, ctorClear.mMethodInstance, ctorClear.mFunc, false, irArgs);
  14881. }
  14882. }
  14883. }
  14884. if (typeInstance->IsObject())
  14885. {
  14886. if ((!mModule->mIsComptimeModule) && (isStackAlloc) && (hasRealtimeLeakCheck))
  14887. {
  14888. BfMethodInstance* markMethod = mModule->GetRawMethodByName(mModule->mContext->mBfObjectType, "GCMarkMembers");
  14889. BF_ASSERT(markMethod != NULL);
  14890. if (markMethod != NULL)
  14891. {
  14892. auto& vtableEntry = typeInstance->mVirtualMethodTable[markMethod->mVirtualTableIdx];
  14893. if (vtableEntry.mImplementingMethod.mTypeInstance != mModule->mContext->mBfObjectType)
  14894. {
  14895. auto impMethodInstance = (BfMethodInstance*)vtableEntry.mImplementingMethod;
  14896. bool needsCall = false;
  14897. if (allocFlags & BfAllocFlags_HasAppendWantMark)
  14898. needsCall = true;
  14899. if (!needsCall)
  14900. {
  14901. if (impMethodInstance != NULL)
  14902. {
  14903. needsCall = impMethodInstance->mMethodDef->mBody != NULL;
  14904. }
  14905. else
  14906. {
  14907. needsCall = true;
  14908. BF_ASSERT(vtableEntry.mImplementingMethod.mKind == BfMethodRefKind_AmbiguousRef);
  14909. }
  14910. }
  14911. if (!needsCall)
  14912. {
  14913. if (typeInstance->HasAppendedField(true))
  14914. needsCall = true;
  14915. }
  14916. if (needsCall)
  14917. {
  14918. SizedArray<BfIRValue, 1> irArgs;
  14919. irArgs.push_back(mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->MapType(mModule->mContext->mBfObjectType)));
  14920. auto gcType = mModule->ResolveTypeDef(mModule->mCompiler->mGCTypeDef);
  14921. BF_ASSERT(gcType != NULL);
  14922. if (gcType != NULL)
  14923. {
  14924. auto addStackObjMethod = mModule->GetMethodByName(gcType->ToTypeInstance(), "AddStackMarkableObject", 1);
  14925. BF_ASSERT(addStackObjMethod);
  14926. if (addStackObjMethod)
  14927. {
  14928. mModule->mBfIRBuilder->CreateCall(addStackObjMethod.mFunc, irArgs);
  14929. }
  14930. auto removeStackObjMethod = mModule->GetMethodByName(gcType->ToTypeInstance(), "RemoveStackMarkableObject", 1);
  14931. BF_ASSERT(removeStackObjMethod);
  14932. if (removeStackObjMethod)
  14933. {
  14934. mModule->AddDeferredCall(removeStackObjMethod, irArgs, allocTarget.mScopeData, allocNode);
  14935. }
  14936. }
  14937. }
  14938. }
  14939. }
  14940. }
  14941. }
  14942. auto origThisTypedValue = mResult;
  14943. auto thisTypedValue = mResult;
  14944. if (inlineTypeRef != NULL)
  14945. {
  14946. BfType* wantType = bindResult.mMethodInstance->GetOwner();
  14947. if (thisTypedValue.mType->IsPointer())
  14948. wantType = mModule->CreatePointerType(wantType);
  14949. thisTypedValue = mModule->Cast(allocNode, thisTypedValue, wantType);
  14950. }
  14951. if ((bindResult.mMethodInstance->mMethodDef->HasAppend()) && (mResult.mType->IsObject()))
  14952. {
  14953. BF_ASSERT(bindResult.mIRArgs[0].IsFake());
  14954. auto typeInst = mResult.mType->ToTypeInstance();
  14955. auto intPtrType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  14956. BfIRValue intPtrVal = mModule->CreateAlloca(intPtrType);
  14957. auto intPtrThisVal = mModule->mBfIRBuilder->CreatePtrToInt(thisTypedValue.mValue, (intPtrType->mSize == 4) ? BfTypeCode_Int32 : BfTypeCode_Int64);
  14958. auto curValPtr = mModule->mBfIRBuilder->CreateAdd(intPtrThisVal, mModule->GetConstValue(typeInst->mInstSize, intPtrType));
  14959. mModule->mBfIRBuilder->CreateStore(curValPtr, intPtrVal);
  14960. bindResult.mIRArgs[0] = intPtrVal;
  14961. }
  14962. if (!typeInstance->IsValuelessType())
  14963. bindResult.mIRArgs.Insert(0, thisTypedValue.mValue);
  14964. auto result = CreateCall(objCreateExpr, bindResult.mMethodInstance, bindResult.mFunc, false, bindResult.mIRArgs);
  14965. if ((result) && (!result.mType->IsVoid()))
  14966. mResult = result;
  14967. if (origThisTypedValue.mType != thisTypedValue.mType)
  14968. {
  14969. auto origThisType = origThisTypedValue.mType;
  14970. if (origThisType->IsPointer())
  14971. origThisType = origThisType->GetUnderlyingType();
  14972. auto origThisTypeInst = origThisType->ToTypeInstance();
  14973. if (origThisTypeInst != NULL)
  14974. {
  14975. BF_ASSERT(origThisTypeInst->IsAnonymousInitializerType());
  14976. auto ctorMethod = mModule->GetMethodByName(origThisTypeInst, "__BfCtor", 0);
  14977. if (!ctorMethod)
  14978. {
  14979. mModule->AssertErrorState();
  14980. }
  14981. else if ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) == 0)
  14982. {
  14983. SizedArray<BfIRValue, 1> irArgs;
  14984. irArgs.push_back(origThisTypedValue.mValue);
  14985. CreateCall(objCreateExpr, ctorMethod.mMethodInstance, ctorMethod.mFunc, false, irArgs);
  14986. }
  14987. }
  14988. }
  14989. }
  14990. }
  14991. if (((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) && (mModule->mCompiler->mCeMachine != NULL))
  14992. {
  14993. mModule->mCompiler->mCeMachine->ClearAppendAllocInfo();
  14994. }
  14995. if ((mResult) && (isStructAlloc))
  14996. {
  14997. if (mResult.mType->IsPointer())
  14998. {
  14999. mResult = mModule->LoadValue(mResult);
  15000. mResult = BfTypedValue(mResult.mValue, mResult.mType->GetUnderlyingType(), true);
  15001. }
  15002. else
  15003. mModule->Fail(StrFormat("Allocation specifier such as 'new' is required for reference type '%s'", mModule->TypeToString(mResult.mType).c_str()), objCreateExpr);
  15004. }
  15005. }
  15006. void BfExprEvaluator::Visit(BfBoxExpression* boxExpr)
  15007. {
  15008. /*if ((boxExpr->mAllocNode == NULL) || (boxExpr->mExpression == NULL))
  15009. {
  15010. mModule->AssertErrorState();
  15011. return;
  15012. }*/
  15013. BfTokenNode* newToken = NULL;
  15014. BfAllocTarget allocTarget;
  15015. ResolveAllocTarget(allocTarget, boxExpr->mAllocNode, newToken);
  15016. if ((boxExpr->mAllocNode != NULL) && (boxExpr->mAllocNode->mToken == BfToken_Scope))
  15017. {
  15018. if ((mBfEvalExprFlags & BfEvalExprFlags_FieldInitializer) != 0)
  15019. {
  15020. mModule->Warn(0, "This allocation will only be in scope during the constructor. Consider using a longer-term allocation such as 'new'", boxExpr->mAllocNode);
  15021. }
  15022. }
  15023. if (boxExpr->mExpression == NULL)
  15024. {
  15025. mModule->AssertErrorState();
  15026. return;
  15027. }
  15028. auto exprValue = mModule->CreateValueFromExpression(boxExpr->mExpression);
  15029. if (exprValue)
  15030. {
  15031. bool doFail = false;
  15032. bool doWarn = false;
  15033. BfType* boxedType = NULL;
  15034. if (exprValue.mType->IsGenericParam())
  15035. {
  15036. BF_ASSERT(mModule->mCurMethodInstance->mIsUnspecialized);
  15037. auto genericParamTarget = (BfGenericParamType*)exprValue.mType;
  15038. auto genericParamInstance = mModule->GetGenericParamInstance(genericParamTarget);
  15039. if ((genericParamInstance->mGenericParamFlags & (BfGenericParamFlag_Struct | BfGenericParamFlag_StructPtr | BfGenericParamFlag_Class)) == BfGenericParamFlag_Class)
  15040. doWarn = true;
  15041. if ((genericParamInstance->mTypeConstraint != NULL) && (genericParamInstance->mTypeConstraint->IsObjectOrInterface()))
  15042. doWarn = true;
  15043. boxedType = mModule->mContext->mBfObjectType;
  15044. }
  15045. else
  15046. {
  15047. doFail = !exprValue.mType->IsValueTypeOrValueTypePtr();
  15048. doWarn = exprValue.mType->IsObjectOrInterface();
  15049. }
  15050. if (doWarn)
  15051. {
  15052. mModule->Warn(0, StrFormat("Boxing is unnecessary since type '%s' is already a reference type.", mModule->TypeToString(exprValue.mType).c_str()), boxExpr->mExpression);
  15053. mResult = exprValue;
  15054. return;
  15055. }
  15056. if (doFail)
  15057. {
  15058. mModule->Fail(StrFormat("Box target '%s' must be a value type or pointer to a value type", mModule->TypeToString(exprValue.mType).c_str()), boxExpr->mExpression);
  15059. return;
  15060. }
  15061. if (boxedType == NULL)
  15062. boxedType = mModule->CreateBoxedType(exprValue.mType);
  15063. if (boxedType == NULL)
  15064. boxedType = mModule->mContext->mBfObjectType;
  15065. mResult = mModule->BoxValue(boxExpr->mExpression, exprValue, boxedType, allocTarget);
  15066. if (!mResult)
  15067. {
  15068. mModule->Fail(StrFormat("Type '%s' is not boxable", mModule->TypeToString(exprValue.mType).c_str()), boxExpr->mExpression);
  15069. return;
  15070. }
  15071. }
  15072. }
  15073. void BfExprEvaluator::ResolveAllocTarget(BfAllocTarget& allocTarget, BfAstNode* allocNode, BfTokenNode*& newToken, BfCustomAttributes** outCustomAttributes)
  15074. {
  15075. auto autoComplete = GetAutoComplete();
  15076. BfAttributeDirective* attributeDirective = NULL;
  15077. allocTarget.mRefNode = allocNode;
  15078. newToken = BfNodeDynCast<BfTokenNode>(allocNode);
  15079. if (allocNode == NULL)
  15080. {
  15081. // Scope
  15082. if (mModule->mCurMethodState != NULL)
  15083. allocTarget.mScopeData = mModule->mCurMethodState->mCurScope->GetTargetable();
  15084. }
  15085. else if (newToken == NULL)
  15086. {
  15087. if (auto scopeNode = BfNodeDynCast<BfScopeNode>(allocNode))
  15088. {
  15089. newToken = scopeNode->mScopeToken;
  15090. allocTarget.mScopeData = mModule->FindScope(scopeNode->GetTargetNode(), true);
  15091. if (autoComplete != NULL)
  15092. {
  15093. auto targetIdentifier = BfNodeDynCast<BfIdentifierNode>(scopeNode->mTargetNode);
  15094. if ((scopeNode->mTargetNode == NULL) || (targetIdentifier != NULL))
  15095. autoComplete->CheckLabel(targetIdentifier, scopeNode->mColonToken, allocTarget.mScopeData);
  15096. }
  15097. attributeDirective = scopeNode->mAttributes;
  15098. }
  15099. if (auto newNode = BfNodeDynCast<BfNewNode>(allocNode))
  15100. {
  15101. newToken = newNode->mNewToken;
  15102. if (auto allocExpr = BfNodeDynCast<BfExpression>(newNode->mAllocNode))
  15103. {
  15104. allocTarget.mCustomAllocator = mModule->CreateValueFromExpression(allocExpr);
  15105. allocTarget.mRefNode = allocExpr;
  15106. }
  15107. else if (auto scopedInvocationTarget = BfNodeDynCast<BfScopedInvocationTarget>(newNode->mAllocNode))
  15108. {
  15109. allocTarget.mScopedInvocationTarget = scopedInvocationTarget;
  15110. }
  15111. attributeDirective = newNode->mAttributes;
  15112. }
  15113. }
  15114. else if (newToken->GetToken() == BfToken_Scope)
  15115. {
  15116. if (mModule->mCurMethodState != NULL)
  15117. allocTarget.mScopeData = mModule->mCurMethodState->mCurScope->GetTargetable();
  15118. }
  15119. if (attributeDirective != NULL)
  15120. {
  15121. auto customAttrs = mModule->GetCustomAttributes(attributeDirective, BfAttributeTargets_Alloc, BfGetCustomAttributesFlags_AllowNonConstArgs, allocTarget.mCaptureInfo);
  15122. if (customAttrs != NULL)
  15123. {
  15124. for (auto& attrib : customAttrs->mAttributes)
  15125. {
  15126. if (attrib.mType->IsInstanceOf(mModule->mCompiler->mAlignAttributeTypeDef))
  15127. {
  15128. allocTarget.mAlignOverride = 16; // System conservative default
  15129. if (!attrib.mCtorArgs.IsEmpty())
  15130. {
  15131. BfIRConstHolder* constHolder = mModule->mCurTypeInstance->mConstHolder;
  15132. auto constant = constHolder->GetConstant(attrib.mCtorArgs[0]);
  15133. if (constant != NULL)
  15134. {
  15135. int alignOverride = (int)BF_MAX(1, constant->mInt64);
  15136. if ((alignOverride & (alignOverride - 1)) == 0)
  15137. allocTarget.mAlignOverride = alignOverride;
  15138. else
  15139. mModule->Fail("Alignment must be a power of 2", attrib.GetRefNode());
  15140. }
  15141. }
  15142. }
  15143. else if (attrib.mType->IsInstanceOf(mModule->mCompiler->mFriendAttributeTypeDef))
  15144. allocTarget.mIsFriend = true;
  15145. }
  15146. if (outCustomAttributes != NULL)
  15147. *outCustomAttributes = customAttrs;
  15148. else
  15149. delete customAttrs;
  15150. }
  15151. }
  15152. }
  15153. BfTypedValue BfExprEvaluator::MakeCallableTarget(BfAstNode* targetSrc, BfTypedValue target)
  15154. {
  15155. if ((target.mType->IsRef()) || (target.mType->IsPointer()))
  15156. {
  15157. auto underlying = target.mType->GetUnderlyingType();
  15158. bool underlyingIsStruct = underlying->IsStruct();
  15159. if (underlyingIsStruct)
  15160. {
  15161. target = mModule->LoadValue(target);
  15162. target.mType = underlying;
  15163. target.mKind = BfTypedValueKind_Addr;
  15164. }
  15165. }
  15166. if ((target.mType->IsStruct()) && (!target.IsAddr()))
  15167. {
  15168. if (IsConstEval())
  15169. return target;
  15170. target = mModule->MakeAddressable(target);
  15171. }
  15172. if (IsVar(target.mType))
  15173. {
  15174. target.mType = mModule->mContext->mBfObjectType;
  15175. return target;
  15176. }
  15177. if (target.mType->IsWrappableType())
  15178. {
  15179. auto primStructType = mModule->GetWrappedStructType(target.mType);
  15180. if (primStructType != NULL)
  15181. {
  15182. mModule->PopulateType(primStructType);
  15183. if (primStructType->IsTypedPrimitive())
  15184. {
  15185. // Type is already the same
  15186. target.mType = primStructType;
  15187. }
  15188. else if (target.IsAddr())
  15189. {
  15190. auto ptrType = mModule->CreatePointerType(primStructType);
  15191. if (primStructType->IsValuelessType())
  15192. target = BfTypedValue(target.mValue, primStructType, true);
  15193. else
  15194. target = BfTypedValue(mModule->mBfIRBuilder->CreateBitCast(target.mValue, mModule->mBfIRBuilder->MapType(ptrType)), primStructType, true);
  15195. }
  15196. else if ((primStructType->IsSplattable()) && (target.IsSplat()) && (!IsComptime()))
  15197. {
  15198. target.mType = primStructType;
  15199. target.mKind = BfTypedValueKind_SplatHead;
  15200. }
  15201. else
  15202. {
  15203. auto allocPtr = mModule->CreateAlloca(primStructType);
  15204. auto srcPtrType = mModule->mBfIRBuilder->CreateBitCast(allocPtr, mModule->mBfIRBuilder->GetPointerTo(mModule->mBfIRBuilder->MapType(target.mType)));
  15205. mModule->mBfIRBuilder->CreateStore(target.mValue, srcPtrType);
  15206. target = BfTypedValue(allocPtr, primStructType, true);
  15207. }
  15208. }
  15209. return target;
  15210. }
  15211. if (target.mType->IsGenericParam())
  15212. {
  15213. target.mType = mModule->mContext->mBfObjectType;
  15214. return target;
  15215. }
  15216. if ((!target.mType->IsTypeInstance()) && (!target.mType->IsConcreteInterfaceType()))
  15217. {
  15218. mModule->Fail(StrFormat("Methods cannot be called on type '%s'", mModule->TypeToString(target.mType).c_str()), targetSrc);
  15219. return BfTypedValue();
  15220. }
  15221. return target;
  15222. }
  15223. int BfExprEvaluator::GetMixinVariable()
  15224. {
  15225. auto curMethodState = mModule->mCurMethodState;
  15226. for (int localIdx = (int)curMethodState->mLocals.size() - 1; localIdx >= 0; localIdx--)
  15227. {
  15228. auto varDecl = curMethodState->mLocals[localIdx];
  15229. if (varDecl->mName == "mixin")
  15230. return localIdx;
  15231. }
  15232. return -1;
  15233. }
  15234. BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc, BfTypeInstance* curTypeInst, BfMethodDef* methodDef, BfMethodMatcher& methodMatcher, BfType** overrideReturnType)
  15235. {
  15236. bool failed = false;
  15237. BfTypeVector resolvedGenericArguments;
  15238. BfMethodState* rootMethodState = NULL;
  15239. if (mModule->mCurMethodState != NULL)
  15240. rootMethodState = mModule->mCurMethodState->GetRootMethodState();
  15241. int localInferrableGenericArgCount = -1;
  15242. if ((methodMatcher.mBestMethodGenericArguments.size() == 0) && (!methodMatcher.mExplicitMethodGenericArguments.IsEmpty()))
  15243. {
  15244. int uniqueGenericStartIdx = mModule->GetLocalInferrableGenericArgCount(methodDef);
  15245. int64 genericArgCountDiff = (int)methodMatcher.mExplicitMethodGenericArguments.size() + uniqueGenericStartIdx - (int)methodDef->mGenericParams.size();
  15246. BfInvocationExpression* invocationExpr = NULL;
  15247. if (mModule->mParentNodeEntry != NULL)
  15248. {
  15249. invocationExpr = BfNodeDynCast<BfInvocationExpression>(mModule->mParentNodeEntry->mNode);
  15250. }
  15251. if (genericArgCountDiff > 0)
  15252. {
  15253. BfAstNode* errorNode = targetSrc;
  15254. if ((invocationExpr != NULL) && (invocationExpr->mGenericArgs != NULL))
  15255. {
  15256. errorNode = invocationExpr->mGenericArgs->mGenericArgs[(int)methodDef->mGenericParams.size()];
  15257. if (errorNode == NULL)
  15258. invocationExpr->mGenericArgs->mCommas.GetSafe((int)methodDef->mGenericParams.size() - 1, errorNode);
  15259. if (errorNode == NULL)
  15260. errorNode = targetSrc;
  15261. }
  15262. mModule->Fail(StrFormat("Too many generic arguments, expected %d fewer", genericArgCountDiff), errorNode);
  15263. }
  15264. else if ((genericArgCountDiff < 0) && (!methodMatcher.mHadOpenGenericArguments))
  15265. {
  15266. BfAstNode* errorNode = targetSrc;
  15267. if ((invocationExpr != NULL) && (invocationExpr->mGenericArgs != NULL) && (invocationExpr->mGenericArgs->mCloseChevron != NULL))
  15268. errorNode = invocationExpr->mGenericArgs->mCloseChevron;
  15269. mModule->Fail(StrFormat("Too few generic arguments, expected %d more", -genericArgCountDiff), errorNode);
  15270. }
  15271. methodMatcher.mBestMethodGenericArguments.resize(methodDef->mGenericParams.size());
  15272. for (int i = 0; i < std::min(methodDef->mGenericParams.size() - uniqueGenericStartIdx, methodMatcher.mExplicitMethodGenericArguments.size()); i++)
  15273. {
  15274. methodMatcher.mBestMethodGenericArguments[i + uniqueGenericStartIdx] = methodMatcher.mExplicitMethodGenericArguments[i];
  15275. }
  15276. }
  15277. BfMethodInstance* unspecializedMethod = NULL;
  15278. bool hasVarGenerics = false;
  15279. for (int checkGenericIdx = 0; checkGenericIdx < (int)methodMatcher.mBestMethodGenericArguments.size(); checkGenericIdx++)
  15280. {
  15281. BfMethodInstance* outerMethodInstance = NULL;
  15282. auto& genericArg = methodMatcher.mBestMethodGenericArguments[checkGenericIdx];
  15283. if (genericArg == NULL)
  15284. {
  15285. if ((methodDef->mIsLocalMethod) && (checkGenericIdx < mModule->mCurMethodInstance->GetNumGenericArguments()))
  15286. {
  15287. // If the root method is generic and we need that param then use that...
  15288. auto rootMethodInstance = rootMethodState->mMethodInstance;
  15289. if ((rootMethodInstance->mMethodInfoEx != NULL) && (checkGenericIdx < rootMethodInstance->mMethodInfoEx->mMethodGenericArguments.size()))
  15290. {
  15291. genericArg = rootMethodInstance->mMethodInfoEx->mMethodGenericArguments[checkGenericIdx];
  15292. }
  15293. else
  15294. {
  15295. if (localInferrableGenericArgCount == -1)
  15296. localInferrableGenericArgCount = mModule->GetLocalInferrableGenericArgCount(methodDef);
  15297. // Otherwise we can only infer generics at the level that the called method was contained
  15298. if (checkGenericIdx < localInferrableGenericArgCount)
  15299. genericArg = mModule->mCurMethodInstance->mMethodInfoEx->mMethodGenericArguments[checkGenericIdx];
  15300. }
  15301. }
  15302. }
  15303. if (genericArg == NULL)
  15304. {
  15305. if (unspecializedMethod == NULL)
  15306. unspecializedMethod = mModule->GetRawMethodInstance(curTypeInst, methodDef);
  15307. auto genericParam = unspecializedMethod->mMethodInfoEx->mGenericParams[checkGenericIdx];
  15308. if ((genericParam->mTypeConstraint != NULL) && (genericParam->mTypeConstraint->IsDelegate()))
  15309. {
  15310. // The only other option was to bind to a MethodRef
  15311. genericArg = mModule->ResolveGenericType(genericParam->mTypeConstraint, NULL, &methodMatcher.mBestMethodGenericArguments, mModule->mCurTypeInstance);
  15312. }
  15313. else
  15314. {
  15315. if (((genericParam->mGenericParamFlags & BfGenericParamFlag_Const) != 0) && (genericParam->mTypeConstraint != NULL))
  15316. {
  15317. for (int paramIdx = 0; paramIdx < (int)unspecializedMethod->mDefaultValues.size(); paramIdx++)
  15318. {
  15319. auto defaultVal = unspecializedMethod->mDefaultValues[paramIdx];
  15320. if (!defaultVal)
  15321. continue;
  15322. auto& param = unspecializedMethod->mParams[paramIdx];
  15323. if (param.mResolvedType->IsGenericParam())
  15324. {
  15325. auto genericParamType = (BfGenericParamType*)param.mResolvedType;
  15326. if ((genericParamType->mGenericParamKind == BfGenericParamKind_Method) && (genericParamType->mGenericParamIdx == checkGenericIdx))
  15327. {
  15328. BfTypedValue constExprVal;
  15329. constExprVal.mType = genericParam->mTypeConstraint;
  15330. auto constant = curTypeInst->mConstHolder->GetConstant(defaultVal.mValue);
  15331. constExprVal.mValue = mModule->ConstantToCurrent(constant, curTypeInst->mConstHolder, genericParam->mTypeConstraint);
  15332. genericArg = mModule->CreateConstExprValueType(constExprVal);
  15333. }
  15334. }
  15335. }
  15336. }
  15337. }
  15338. if (genericArg == NULL)
  15339. {
  15340. BfGenericInferContext genericInferContext;
  15341. genericInferContext.mModule = mModule;
  15342. genericInferContext.mCheckMethodGenericArguments = &methodMatcher.mBestMethodGenericArguments;
  15343. genericInferContext.InferGenericArguments(unspecializedMethod);
  15344. }
  15345. if (genericArg == NULL)
  15346. {
  15347. failed = true;
  15348. BfError* error = mModule->Fail(StrFormat("Unable to determine generic argument '%s'", methodDef->mGenericParams[checkGenericIdx]->mName.c_str()).c_str(), targetSrc);
  15349. if ((genericParam->mTypeConstraint != NULL) && (!genericParam->mTypeConstraint->IsUnspecializedType()))
  15350. genericArg = genericParam->mTypeConstraint;
  15351. else
  15352. genericArg = mModule->mContext->mBfObjectType;
  15353. if (error != NULL)
  15354. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), unspecializedMethod->mMethodDef->GetRefNode());
  15355. }
  15356. }
  15357. if (genericArg->IsVar())
  15358. {
  15359. //BF_ASSERT(methodMatcher.mHasVarArguments);
  15360. hasVarGenerics = true;
  15361. }
  15362. if (genericArg->IsIntUnknown())
  15363. genericArg = mModule->FixIntUnknown(genericArg);
  15364. auto resolvedGenericArg = genericArg;
  15365. resolvedGenericArguments.push_back(genericArg);
  15366. }
  15367. BfTypeInstance* foreignType = NULL;
  15368. BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None;
  15369. if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) && (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mInlineAttributeTypeDef)))
  15370. {
  15371. flags = (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_ForceInline);
  15372. mModule->mAttributeState->mUsed = true;
  15373. }
  15374. if ((!mModule->mCurTypeInstance->IsInterface()) && (methodDef->mBody != NULL))
  15375. {
  15376. if ((methodMatcher.mBypassVirtual) && (methodMatcher.mBestMethodTypeInstance->IsInterface()))
  15377. {
  15378. // This is an explicit 'base' call to a default interface method. We pull the methodDef into our own concrete type.
  15379. foreignType = curTypeInst;
  15380. curTypeInst = mModule->mCurTypeInstance;
  15381. flags = (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_ForeignMethodDef);
  15382. }
  15383. else if ((methodDef->mIsStatic) && (curTypeInst->IsInterface()))
  15384. {
  15385. if (mModule->TypeIsSubTypeOf(mModule->mCurTypeInstance, curTypeInst))
  15386. {
  15387. // This is an explicit call to a default static interface method. We pull the methodDef into our own concrete type.
  15388. foreignType = curTypeInst;
  15389. curTypeInst = mModule->mCurTypeInstance;
  15390. flags = (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_ForeignMethodDef);
  15391. }
  15392. }
  15393. }
  15394. if (hasVarGenerics)
  15395. return BfModuleMethodInstance();
  15396. BfModuleMethodInstance moduleMethodInstance;
  15397. if (methodMatcher.mBestMethodInstance)
  15398. {
  15399. moduleMethodInstance = methodMatcher.mBestMethodInstance;
  15400. }
  15401. else
  15402. {
  15403. moduleMethodInstance = mModule->GetMethodInstance(curTypeInst, methodDef, resolvedGenericArguments, flags, foreignType);
  15404. }
  15405. if (mModule->IsSkippingExtraResolveChecks())
  15406. {
  15407. //BF_ASSERT(methodInstance.mFunc == NULL);
  15408. }
  15409. if (moduleMethodInstance.mMethodInstance == NULL)
  15410. return NULL;
  15411. if (methodDef->IsEmptyPartial())
  15412. return moduleMethodInstance;
  15413. if (moduleMethodInstance.mMethodInstance->mMethodInfoEx != NULL)
  15414. {
  15415. for (int checkGenericIdx = 0; checkGenericIdx < (int)moduleMethodInstance.mMethodInstance->mMethodInfoEx->mGenericParams.size(); checkGenericIdx++)
  15416. {
  15417. auto genericParams = moduleMethodInstance.mMethodInstance->mMethodInfoEx->mGenericParams[checkGenericIdx];
  15418. BfTypeVector* checkMethodGenericArgs = NULL;
  15419. BfType* genericArg = NULL;
  15420. if (checkGenericIdx < (int)methodMatcher.mBestMethodGenericArguments.size())
  15421. {
  15422. genericArg = methodMatcher.mBestMethodGenericArguments[checkGenericIdx];
  15423. }
  15424. else
  15425. {
  15426. checkMethodGenericArgs = &methodMatcher.mBestMethodGenericArguments;
  15427. genericArg = genericParams->mExternType;
  15428. auto owner = moduleMethodInstance.mMethodInstance->GetOwner();
  15429. BfTypeVector* typeGenericArguments = NULL;
  15430. if (owner->mGenericTypeInfo != NULL)
  15431. typeGenericArguments = &owner->mGenericTypeInfo->mTypeGenericArguments;
  15432. //genericArg = mModule->ResolveGenericType(genericArg, typeGenericArguments, checkMethodGenericArgs);
  15433. }
  15434. if (genericArg->IsVar())
  15435. continue;
  15436. BfAstNode* paramSrc;
  15437. if (checkGenericIdx >= methodMatcher.mBestMethodGenericArgumentSrcs.size())
  15438. {
  15439. paramSrc = targetSrc;
  15440. }
  15441. else
  15442. paramSrc = methodMatcher.mArguments[methodMatcher.mBestMethodGenericArgumentSrcs[checkGenericIdx]].mExpression;
  15443. // Note: don't pass methodMatcher.mBestMethodGenericArguments into here, this method is already specialized
  15444. BfError* error = NULL;
  15445. if (!mModule->CheckGenericConstraints(BfGenericParamSource(moduleMethodInstance.mMethodInstance), genericArg, paramSrc, genericParams, NULL,
  15446. failed ? NULL : &error))
  15447. {
  15448. if (moduleMethodInstance.mMethodInstance->IsSpecializedGenericMethod())
  15449. {
  15450. // We mark this as failed to make sure we don't try to process a method that doesn't even follow the constraints
  15451. moduleMethodInstance.mMethodInstance->mFailedConstraints = true;
  15452. }
  15453. if (moduleMethodInstance.mMethodInstance->mMethodDef->mMethodDeclaration != NULL)
  15454. {
  15455. if (error != NULL)
  15456. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), moduleMethodInstance.mMethodInstance->mMethodDef->GetRefNode());
  15457. }
  15458. }
  15459. }
  15460. }
  15461. else
  15462. BF_ASSERT(methodMatcher.mBestMethodGenericArguments.IsEmpty());
  15463. if ((overrideReturnType != NULL) && (moduleMethodInstance.mMethodInstance->mIsUnspecializedVariation) &&
  15464. ((moduleMethodInstance.mMethodInstance->mReturnType->IsUnspecializedTypeVariation()) || (moduleMethodInstance.mMethodInstance->mReturnType->IsVar())))
  15465. {
  15466. if (unspecializedMethod == NULL)
  15467. unspecializedMethod = mModule->GetRawMethodInstance(curTypeInst, methodDef);
  15468. BfTypeVector* typeGenericArgs = NULL;
  15469. auto typeUnspecMethodInstance = unspecializedMethod;
  15470. if (curTypeInst->IsUnspecializedTypeVariation())
  15471. {
  15472. typeUnspecMethodInstance = mModule->GetUnspecializedMethodInstance(typeUnspecMethodInstance, true);
  15473. typeGenericArgs = &curTypeInst->mGenericTypeInfo->mTypeGenericArguments;
  15474. }
  15475. BfType* specializedReturnType = mModule->ResolveGenericType(typeUnspecMethodInstance->mReturnType, typeGenericArgs, &methodMatcher.mBestMethodGenericArguments,
  15476. mModule->mCurTypeInstance);
  15477. if (specializedReturnType != NULL)
  15478. *overrideReturnType = specializedReturnType;
  15479. }
  15480. return moduleMethodInstance;
  15481. }
  15482. BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfMethodMatcher& methodMatcher)
  15483. {
  15484. if (!methodMatcher.mBestMethodInstance)
  15485. methodMatcher.mBestMethodInstance = GetSelectedMethod(methodMatcher.mTargetSrc, methodMatcher.mBestMethodTypeInstance, methodMatcher.mBestMethodDef, methodMatcher);
  15486. return methodMatcher.mBestMethodInstance;
  15487. }
  15488. void BfExprEvaluator::CheckLocalMethods(BfAstNode* targetSrc, BfTypeInstance* typeInstance, const StringImpl& methodName, BfMethodMatcher& methodMatcher, BfMethodType methodType)
  15489. {
  15490. auto _GetNodeId = [&]()
  15491. {
  15492. auto parser = targetSrc->GetSourceData()->ToParserData();
  15493. return ((int64)parser->mDataId << 32) + targetSrc->GetSrcStart();
  15494. };
  15495. BfMethodState* ctxMethodState = NULL;
  15496. BfClosureInstanceInfo* ctxClosureInstanceInfo = NULL;
  15497. if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL))
  15498. {
  15499. ctxClosureInstanceInfo = mModule->mCurMethodState->mClosureState->mClosureInstanceInfo;
  15500. ctxMethodState = mModule->mCurMethodState;
  15501. }
  15502. bool atCtxMethodState = false;
  15503. auto checkMethodState = mModule->mCurMethodState;
  15504. auto rootMethodState = checkMethodState;
  15505. while (checkMethodState != NULL)
  15506. {
  15507. rootMethodState = checkMethodState;
  15508. if (checkMethodState == ctxMethodState)
  15509. atCtxMethodState = true;
  15510. if ((ctxClosureInstanceInfo != NULL) && (!ctxMethodState->mClosureState->mCapturing))
  15511. {
  15512. BfMethodDef* localMethodDef = NULL;
  15513. if (ctxClosureInstanceInfo->mLocalMethodBindings.TryGetValue(_GetNodeId(), &localMethodDef))
  15514. {
  15515. methodMatcher.CheckMethod(mModule->mCurTypeInstance, mModule->mCurTypeInstance, localMethodDef, true);
  15516. BF_ASSERT(methodMatcher.mBestMethodDef != NULL);
  15517. return;
  15518. }
  15519. }
  15520. else
  15521. {
  15522. BfLocalMethod* matchedLocalMethod = NULL;
  15523. BfLocalMethod* localMethod = NULL;
  15524. if (checkMethodState->mLocalMethodMap.TryGetValue(methodName, &localMethod))
  15525. {
  15526. auto typeInst = mModule->mCurTypeInstance;
  15527. if (checkMethodState->mMixinState != NULL)
  15528. typeInst = checkMethodState->mMixinState->mMixinMethodInstance->GetOwner();
  15529. while (localMethod != NULL)
  15530. {
  15531. auto methodDef = mModule->GetLocalMethodDef(localMethod);
  15532. if (methodDef->mMethodType == methodType)
  15533. {
  15534. methodMatcher.CheckMethod(mModule->mCurTypeInstance, typeInst, methodDef, true);
  15535. if (methodMatcher.mBestMethodDef == methodDef)
  15536. matchedLocalMethod = localMethod;
  15537. }
  15538. localMethod = localMethod->mNextWithSameName;
  15539. }
  15540. }
  15541. if (matchedLocalMethod != NULL)
  15542. {
  15543. if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mCapturing))
  15544. {
  15545. BfModuleMethodInstance moduleMethodInstance = GetSelectedMethod(targetSrc, typeInstance, matchedLocalMethod->mMethodDef, methodMatcher);
  15546. if (moduleMethodInstance)
  15547. {
  15548. auto methodInstance = moduleMethodInstance.mMethodInstance;
  15549. if ((methodInstance->mMethodInfoEx != NULL) && (methodInstance->mMethodInfoEx->mClosureInstanceInfo->mCaptureClosureState != NULL))
  15550. {
  15551. // The called method is calling us from its mLocalMethodRefs set. Stretch our mCaptureStartAccessId back to incorporate its
  15552. // captures as well
  15553. if (methodInstance->mMethodInfoEx->mClosureInstanceInfo->mCaptureClosureState->mCaptureStartAccessId < mModule->mCurMethodState->mClosureState->mCaptureStartAccessId)
  15554. mModule->mCurMethodState->mClosureState->mCaptureStartAccessId = methodInstance->mMethodInfoEx->mClosureInstanceInfo->mCaptureClosureState->mCaptureStartAccessId;
  15555. }
  15556. else
  15557. {
  15558. if (methodInstance->mDisallowCalling) // We need to process the captures from this guy
  15559. {
  15560. if (mModule->mCurMethodState->mClosureState->mLocalMethodRefSet.Add(methodInstance))
  15561. mModule->mCurMethodState->mClosureState->mLocalMethodRefs.Add(methodInstance);
  15562. }
  15563. }
  15564. }
  15565. }
  15566. if (ctxClosureInstanceInfo != NULL)
  15567. {
  15568. BF_ASSERT(mModule->mCurMethodState->mClosureState->mCapturing);
  15569. ctxClosureInstanceInfo->mLocalMethodBindings[_GetNodeId()] = methodMatcher.mBestMethodDef;
  15570. }
  15571. break;
  15572. }
  15573. }
  15574. checkMethodState = checkMethodState->mPrevMethodState;
  15575. }
  15576. }
  15577. void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, bool allowImplicitThis, const StringImpl& name, const BfSizedArray<BfExpression*>& arguments, const BfMethodGenericArguments& methodGenericArgs)
  15578. {
  15579. if (mModule->mCurMethodState == NULL)
  15580. return;
  15581. if (mDeferCallData != NULL)
  15582. {
  15583. mModule->Fail("Mixins cannot be directly deferred. Consider wrapping in a block.", targetSrc);
  15584. }
  15585. BfAstNode* origTargetSrc = targetSrc;
  15586. BfScopedInvocationTarget* scopedInvocationTarget = NULL;
  15587. if (mModule->mParentNodeEntry != NULL)
  15588. {
  15589. if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(mModule->mParentNodeEntry->mNode))
  15590. {
  15591. scopedInvocationTarget = BfNodeDynCast<BfScopedInvocationTarget>(invocationExpr->mTarget);
  15592. }
  15593. }
  15594. auto targetNameNode = targetSrc;
  15595. if (scopedInvocationTarget != NULL)
  15596. {
  15597. targetNameNode = scopedInvocationTarget->GetScopeNameNode();
  15598. }
  15599. while (true)
  15600. {
  15601. if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(targetNameNode))
  15602. {
  15603. targetNameNode = qualifiedNameNode->mRight;
  15604. continue;
  15605. }
  15606. if (auto memberRefExpr = BfNodeDynCast<BfMemberReferenceExpression>(targetNameNode))
  15607. {
  15608. targetNameNode = memberRefExpr->mMemberName;
  15609. continue;
  15610. }
  15611. break;
  15612. }
  15613. BfTypeInstance* mixinClass = NULL;
  15614. if (target.mType != NULL)
  15615. mixinClass = target.mType->ToTypeInstance();
  15616. int inLine = mModule->mCurFilePosition.mCurLine;
  15617. SizedArray<BfResolvedArg, 4> args;
  15618. SizedArray<BfExprEvaluator*, 8> argExprEvaluators;
  15619. defer
  15620. (
  15621. {
  15622. for (auto exprEvaluator : argExprEvaluators)
  15623. delete exprEvaluator;
  15624. }
  15625. );
  15626. auto _AddArg = [&](BfExpression* argExpr)
  15627. {
  15628. BfResolvedArg resolvedArg;
  15629. argExprEvaluators.push_back(new BfExprEvaluator(mModule));
  15630. BfExprEvaluator* exprEvaluator = argExprEvaluators.back();
  15631. exprEvaluator->mResolveGenericParam = false;
  15632. exprEvaluator->mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator->mBfEvalExprFlags | BfEvalExprFlags_NoCast | BfEvalExprFlags_AllowRefExpr | BfEvalExprFlags_AllowOutExpr);
  15633. bool deferExpr = false;
  15634. if (auto variableDecl = BfNodeDynCast<BfVariableDeclaration>(argExpr))
  15635. {
  15636. deferExpr = true;
  15637. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_VariableDeclaration);
  15638. }
  15639. if (deferExpr)
  15640. {
  15641. //
  15642. }
  15643. else if (argExpr != NULL)
  15644. exprEvaluator->Evaluate(argExpr, false, false, true);
  15645. else
  15646. mModule->Fail("Missing argument", targetSrc);
  15647. auto argValue = exprEvaluator->mResult;
  15648. mModule->FixIntUnknown(argValue);
  15649. if (argValue)
  15650. {
  15651. if (argValue.mType->IsRef())
  15652. {
  15653. exprEvaluator->FinishExpressionResult();
  15654. }
  15655. }
  15656. resolvedArg.mTypedValue = argValue;
  15657. resolvedArg.mExpression = argExpr;
  15658. args.push_back(resolvedArg);
  15659. };
  15660. for (BfExpression* argExpr : arguments)
  15661. {
  15662. _AddArg(argExpr);
  15663. }
  15664. auto autoComplete = GetAutoComplete();
  15665. if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo) && (autoComplete->mMethodMatchInfo != NULL) && (autoComplete->mMethodMatchInfo->mInstanceList.size() != 0))
  15666. autoComplete->mIsCapturingMethodMatchInfo = false;
  15667. BfMethodMatcher methodMatcher(targetSrc, mModule, name, args, methodGenericArgs);
  15668. methodMatcher.mMethodType = BfMethodType_Mixin;
  15669. methodMatcher.mSkipImplicitParams = true;
  15670. auto curTypeInst = mModule->mCurTypeInstance;
  15671. if (mixinClass != NULL)
  15672. curTypeInst = mixinClass;
  15673. if (target.mType == NULL)
  15674. {
  15675. CheckLocalMethods(targetSrc, curTypeInst, name, methodMatcher, BfMethodType_Mixin);
  15676. }
  15677. if (methodMatcher.mBestMethodDef == NULL)
  15678. methodMatcher.mBestMethodDef = methodMatcher.mBackupMethodDef;
  15679. if (methodMatcher.mBestMethodDef == NULL)
  15680. {
  15681. if (mixinClass != NULL)
  15682. methodMatcher.CheckType(mixinClass, BfTypedValue(), false);
  15683. else
  15684. methodMatcher.CheckType(mModule->mCurTypeInstance, BfTypedValue(), false);
  15685. }
  15686. if ((methodMatcher.mBestMethodDef == NULL) && (target.mType == NULL) && (mModule->mContext->mCurTypeState != NULL))
  15687. {
  15688. BF_ASSERT(mModule->mCurTypeInstance == mModule->mContext->mCurTypeState->mType);
  15689. BfGlobalLookup globalLookup;
  15690. globalLookup.mKind = BfGlobalLookup::Kind_Method;
  15691. globalLookup.mName = name;
  15692. mModule->PopulateGlobalContainersList(globalLookup);
  15693. for (auto& globalContainer : mModule->mContext->mCurTypeState->mGlobalContainers)
  15694. {
  15695. if (globalContainer.mTypeInst == NULL)
  15696. continue;
  15697. methodMatcher.CheckType(globalContainer.mTypeInst, BfTypedValue(), false);
  15698. if (methodMatcher.mBestMethodDef != NULL)
  15699. break;
  15700. }
  15701. }
  15702. if (methodMatcher.mBestMethodDef == NULL)
  15703. {
  15704. BfStaticSearch* staticSearch = mModule->GetStaticSearch();
  15705. if (staticSearch != NULL)
  15706. {
  15707. for (auto typeInst : staticSearch->mStaticTypes)
  15708. {
  15709. if (methodMatcher.CheckType(typeInst, BfTypedValue(), false))
  15710. {
  15711. if (methodMatcher.mBestMethodDef != NULL)
  15712. break;
  15713. }
  15714. }
  15715. }
  15716. }
  15717. if (methodMatcher.mBestMethodDef == NULL)
  15718. {
  15719. mModule->Fail("Cannot find mixin", targetSrc);
  15720. return;
  15721. }
  15722. auto resolvePassData = mModule->mCompiler->mResolvePassData;
  15723. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(targetNameNode)) && (autoComplete->mDefType == NULL))
  15724. {
  15725. autoComplete->mInsertStartIdx = targetNameNode->GetSrcStart();
  15726. autoComplete->mInsertEndIdx = targetNameNode->GetSrcEnd();
  15727. autoComplete->mDefType = methodMatcher.mBestMethodTypeInstance->mTypeDef;
  15728. autoComplete->mDefMethod = methodMatcher.mBestMethodDef;
  15729. autoComplete->SetDefinitionLocation(methodMatcher.mBestMethodDef->GetMethodDeclaration()->mNameNode);
  15730. }
  15731. if ((mModule->mCompiler->mResolvePassData != NULL) && (mModule->mCompiler->mResolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Method))
  15732. {
  15733. targetNameNode->SetSrcEnd(targetNameNode->GetSrcEnd() - 1);
  15734. mModule->mCompiler->mResolvePassData->HandleMethodReference(targetNameNode, methodMatcher.mBestMethodTypeInstance->mTypeDef, methodMatcher.mBestMethodDef);
  15735. targetNameNode->SetSrcEnd(targetNameNode->GetSrcEnd() + 1);
  15736. }
  15737. auto curMethodState = mModule->mCurMethodState;
  15738. auto moduleMethodInstance = GetSelectedMethod(targetSrc, methodMatcher.mBestMethodTypeInstance, methodMatcher.mBestMethodDef, methodMatcher);
  15739. if (!moduleMethodInstance)
  15740. {
  15741. if (methodMatcher.mHasVarArguments)
  15742. {
  15743. mResult = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Var));
  15744. return;
  15745. }
  15746. mModule->Fail("Failed to get selected mixin", targetSrc);
  15747. return;
  15748. }
  15749. if (!mModule->CheckUseMethodInstance(moduleMethodInstance.mMethodInstance, targetSrc))
  15750. return;
  15751. auto methodInstance = moduleMethodInstance.mMethodInstance;
  15752. PerformCallChecks(methodInstance, targetSrc);
  15753. for (int checkGenericIdx = 0; checkGenericIdx < (int)methodMatcher.mBestMethodGenericArguments.size(); checkGenericIdx++)
  15754. {
  15755. auto& genericParams = methodInstance->mMethodInfoEx->mGenericParams;
  15756. auto genericArg = methodMatcher.mBestMethodGenericArguments[checkGenericIdx];
  15757. if (genericArg->IsVar())
  15758. continue;
  15759. BfAstNode* paramSrc;
  15760. if (methodMatcher.mBestMethodGenericArgumentSrcs.size() == 0)
  15761. paramSrc = targetSrc;
  15762. else
  15763. paramSrc = methodMatcher.mArguments[methodMatcher.mBestMethodGenericArgumentSrcs[checkGenericIdx]].mExpression;
  15764. // Note: don't pass methodMatcher.mBestMethodGenericArguments into here, this method is already specialized
  15765. BfError* error = NULL;
  15766. if (!mModule->CheckGenericConstraints(BfGenericParamSource(methodInstance), genericArg, paramSrc, genericParams[checkGenericIdx], NULL, &error))
  15767. {
  15768. if (methodInstance->mMethodDef->mMethodDeclaration != NULL)
  15769. {
  15770. if (error != NULL)
  15771. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
  15772. }
  15773. }
  15774. }
  15775. if (curMethodState->mCurScope->mMixinDepth >= 128)
  15776. {
  15777. mModule->Fail("Maximum nested mixin depth exceeded", targetSrc);
  15778. return;
  15779. }
  15780. // Check circular ref based on methodInstance. We must check the arg types since we could be making progress in mixin evaluation
  15781. // based on method selection within the mixin dependent on args
  15782. {
  15783. bool hasCircularRef = false;
  15784. BfMixinState* checkMixinState = NULL;
  15785. auto checkMethodState = curMethodState;
  15786. while (checkMethodState != NULL)
  15787. {
  15788. auto curMixinState = checkMethodState->mMixinState;
  15789. while (curMixinState != NULL)
  15790. {
  15791. if ((curMixinState->mDoCircularVarResult) && (curMixinState->mMixinMethodInstance == methodInstance))
  15792. {
  15793. mResult = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Var));
  15794. return;
  15795. }
  15796. if ((!curMixinState->mCheckedCircularRef) && (curMixinState->mMixinMethodInstance == methodInstance))
  15797. {
  15798. checkMixinState = curMixinState;
  15799. checkMixinState->mCheckedCircularRef = true;
  15800. }
  15801. else if (checkMixinState != NULL)
  15802. {
  15803. if ((curMixinState->mMixinMethodInstance == checkMixinState->mMixinMethodInstance) &&
  15804. (curMixinState->mArgTypes == checkMixinState->mArgTypes) &&
  15805. (curMixinState->mArgConsts.mSize == checkMixinState->mArgConsts.mSize))
  15806. {
  15807. bool constsMatch = true;
  15808. for (int i = 0; i < curMixinState->mArgConsts.mSize; i++)
  15809. {
  15810. if (!mModule->mBfIRBuilder->CheckConstEquality(curMixinState->mArgConsts[i], checkMixinState->mArgConsts[i]))
  15811. {
  15812. constsMatch = false;
  15813. break;
  15814. }
  15815. }
  15816. if (constsMatch)
  15817. hasCircularRef = true;
  15818. }
  15819. }
  15820. curMixinState = curMixinState->mPrevMixinState;
  15821. }
  15822. checkMethodState = checkMethodState->mPrevMethodState;
  15823. }
  15824. if (hasCircularRef)
  15825. {
  15826. for (auto argType : checkMixinState->mArgTypes)
  15827. {
  15828. if (argType->IsVar())
  15829. checkMixinState->mDoCircularVarResult = true;
  15830. }
  15831. if (checkMixinState->mDoCircularVarResult)
  15832. {
  15833. mResult = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Var));
  15834. return;
  15835. }
  15836. mModule->Fail("Circular reference detected between mixins", targetSrc);
  15837. return;
  15838. }
  15839. }
  15840. AddCallDependencies(methodInstance);
  15841. if (!methodMatcher.mBestMethodDef->mIsStatic)
  15842. {
  15843. if ((!target) && (allowImplicitThis))
  15844. target = mModule->GetThis();
  15845. if (!target)
  15846. {
  15847. BfError* error = mModule->Fail(StrFormat("An instance reference is required to invoke the non-static mixin '%s'",
  15848. mModule->MethodToString(methodInstance).c_str()), targetSrc);
  15849. if ((error != NULL) && (methodInstance->mMethodDef->GetRefNode() != NULL))
  15850. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
  15851. }
  15852. }
  15853. else
  15854. {
  15855. if (target)
  15856. {
  15857. BfError* error = mModule->Fail(StrFormat("Mixin '%s' cannot be accessed with an instance reference; qualify it with a type name instead",
  15858. mModule->MethodToString(methodInstance).c_str()), targetSrc);
  15859. if ((error != NULL) && (methodInstance->mMethodDef->GetRefNode() != NULL))
  15860. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
  15861. }
  15862. }
  15863. int methodParamCount = (int)methodInstance->GetParamCount();
  15864. // Implicit params are ignored for calling- they should be resolved at the injection site
  15865. int implicitParamCount = methodInstance->GetImplicitParamCount();
  15866. int explicitParamCount = methodParamCount - implicitParamCount;
  15867. while ((int)args.size() < explicitParamCount)
  15868. {
  15869. int argIdx = (int)args.size();
  15870. BfExpression* expr = methodInstance->GetParamInitializer(argIdx);
  15871. if (expr == NULL)
  15872. break;
  15873. _AddArg(expr);
  15874. }
  15875. if ((int)args.size() < explicitParamCount)
  15876. {
  15877. BfError* error = mModule->Fail(StrFormat("Not enough arguments specified, expected %d more.", explicitParamCount - (int)arguments.size()), targetSrc);
  15878. if ((error != NULL) && (methodInstance->mMethodDef->GetRefNode() != NULL))
  15879. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
  15880. return;
  15881. }
  15882. else if ((int)args.size() > explicitParamCount)
  15883. {
  15884. BfError* error = mModule->Fail(StrFormat("Too many arguments specified, expected %d fewer.", (int)arguments.size() - explicitParamCount), targetSrc);
  15885. if ((error != NULL) && (methodInstance->mMethodDef->GetRefNode() != NULL))
  15886. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
  15887. return;
  15888. }
  15889. int paramIdx = implicitParamCount;
  15890. auto argExprEvaluatorItr = argExprEvaluators.begin();
  15891. for (int argIdx = 0; argIdx < (int)args.size(); argIdx++)
  15892. {
  15893. auto exprEvaluator = *argExprEvaluatorItr;
  15894. //auto paramType = methodInstance->GetParamKind(paramIdx);
  15895. BfType* wantType = methodInstance->mParams[paramIdx].mResolvedType;
  15896. auto& arg = args[argIdx];
  15897. if ((arg.mArgFlags & BfArgFlag_VariableDeclaration) != 0)
  15898. {
  15899. arg.mTypedValue = ResolveArgValue(arg, wantType);
  15900. }
  15901. if (wantType->IsGenericParam())
  15902. {
  15903. //
  15904. }
  15905. else if (!wantType->IsVar())
  15906. {
  15907. if (arg.mTypedValue.mType == NULL)
  15908. {
  15909. mModule->AssertErrorState();
  15910. return;
  15911. }
  15912. if (arg.mTypedValue.mType != wantType)
  15913. {
  15914. exprEvaluator->FinishExpressionResult();
  15915. arg.mTypedValue = mModule->LoadValue(arg.mTypedValue);
  15916. arg.mTypedValue = mModule->Cast(arg.mExpression, arg.mTypedValue, wantType);
  15917. /*// Do this to generate default implicit cast error
  15918. mModule->Fail(StrFormat("Mixin argument type '%s' must match parameter type '%s'.",
  15919. mModule->TypeToString(arg.mTypedValue.mType).c_str(),
  15920. mModule->TypeToString(wantType).c_str()), arg.mExpression);
  15921. return;*/
  15922. }
  15923. }
  15924. paramIdx++;
  15925. argExprEvaluatorItr++;
  15926. }
  15927. mModule->AddDependency(methodInstance->GetOwner(), mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_InlinedCall);
  15928. auto startBlock = mModule->mBfIRBuilder->CreateBlock("mixinStart");
  15929. mModule->mBfIRBuilder->CreateBr(startBlock);
  15930. mModule->mBfIRBuilder->AddBlock(startBlock);
  15931. mModule->mBfIRBuilder->SetInsertPoint(startBlock);
  15932. //auto prevDebugLoc = mModule->mBfIRBuilder->getCurrentDebugLocation();
  15933. // This is so when we debug we can hit a steppoint on the inlined "call line"
  15934. mModule->EmitEnsureInstructionAt();
  15935. auto rootMethodState = mModule->mCurMethodState->GetRootMethodState();
  15936. BfMixinState* mixinState = rootMethodState->mMixinStates.Alloc();
  15937. mixinState->mInjectFilePosition = mModule->mCurFilePosition;
  15938. mixinState->mPrevMixinState = curMethodState->mMixinState;
  15939. mixinState->mLocalsStartIdx = (int)mModule->mCurMethodState->mLocals.size();
  15940. mixinState->mMixinMethodInstance = methodInstance;
  15941. mixinState->mSource = origTargetSrc;
  15942. mixinState->mCallerScope = mModule->mCurMethodState->mCurScope;
  15943. mixinState->mTargetScope = mixinState->mCallerScope;
  15944. mixinState->mResultExpr = NULL;
  15945. mixinState->mHasDeferredUsage = false;
  15946. mixinState->mUsedInvocationScope = false;
  15947. mixinState->mTarget = target;
  15948. auto checkNode = origTargetSrc;
  15949. if (scopedInvocationTarget != NULL)
  15950. {
  15951. auto targetScope = mModule->FindScope(scopedInvocationTarget->GetScopeNameNode(), curMethodState->mMixinState);
  15952. if (targetScope != NULL)
  15953. {
  15954. mixinState->mTargetScope = targetScope;
  15955. if (autoComplete != NULL)
  15956. {
  15957. if (auto identifer = BfNodeDynCast<BfIdentifierNode>(scopedInvocationTarget->mScopeName))
  15958. autoComplete->CheckLabel(identifer, NULL, targetScope);
  15959. }
  15960. }
  15961. }
  15962. mModule->mBfIRBuilder->SaveDebugLocation();
  15963. SetAndRestoreValue<BfMixinState*> prevMixinState(curMethodState->mMixinState, mixinState);
  15964. SetAndRestoreValue<BfExprEvaluator*> prevExprEvaluator(curMethodState->mCurScope->mExprEvaluator, NULL);
  15965. SetAndRestoreValue<BfPendingNullConditional*> prevNullConditional(curMethodState->mPendingNullConditional, NULL);
  15966. BfGetSymbolReferenceKind prevSymbolRefKind = BfGetSymbolReferenceKind_None;
  15967. if (mModule->mCompiler->mResolvePassData != NULL)
  15968. {
  15969. prevSymbolRefKind = mModule->mCompiler->mResolvePassData->mGetSymbolReferenceKind;
  15970. mModule->mCompiler->mResolvePassData->mGetSymbolReferenceKind = BfGetSymbolReferenceKind_None;
  15971. }
  15972. defer
  15973. (
  15974. {
  15975. if (mModule->mCompiler->mResolvePassData != NULL)
  15976. mModule->mCompiler->mResolvePassData->mGetSymbolReferenceKind = prevSymbolRefKind;
  15977. }
  15978. );
  15979. auto methodDef = methodInstance->mMethodDef;
  15980. auto methodDeclaration = methodDef->GetMethodDeclaration();
  15981. BfScopeData scopeData;
  15982. scopeData.mCloseNode = methodDeclaration->mBody;
  15983. if (auto block = BfNodeDynCast<BfBlock>(methodDeclaration->mBody))
  15984. {
  15985. if (block->mCloseBrace != NULL)
  15986. scopeData.mCloseNode = block->mCloseBrace;
  15987. }
  15988. curMethodState->AddScope(&scopeData);
  15989. curMethodState->mCurScope->mMixinDepth++;
  15990. // We can't flush scope state because we extend params in as arbitrary values
  15991. mModule->NewScopeState(true, false);
  15992. bool wantsDIData = (mModule->mBfIRBuilder->DbgHasInfo()) && (mModule->mHasFullDebugInfo);
  15993. DISubprogram* diFunction = NULL;
  15994. int startLocalIdx = (int)mModule->mCurMethodState->mLocals.size();
  15995. int endLocalIdx = startLocalIdx;
  15996. if ((wantsDIData) || (mModule->mIsComptimeModule))
  15997. {
  15998. BfIRMDNode diFuncType = mModule->mBfIRBuilder->DbgCreateSubroutineType(methodInstance);
  15999. //int defLine = mModule->mCurFilePosition.mCurLine;
  16000. int flags = 0;
  16001. curMethodState->mCurScope->mDIInlinedAt = mModule->mBfIRBuilder->DbgGetCurrentLocation();
  16002. // 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
  16003. // definitions, so we need to be consistent and use the actual line
  16004. mModule->UpdateSrcPos(methodDeclaration->mNameNode, BfSrcPosFlag_NoSetDebugLoc);
  16005. int defLine = mModule->mCurFilePosition.mCurLine;
  16006. auto diParentType = mModule->mBfIRBuilder->DbgGetTypeInst(methodInstance->GetOwner());
  16007. if (!mModule->mBfIRBuilder->mIgnoreWrites)
  16008. {
  16009. String methodName = methodDef->mName;
  16010. methodName += "!";
  16011. BfMangler::Mangle(methodName, mModule->mCompiler->GetMangleKind(), methodInstance);
  16012. String linkageName;
  16013. if ((mModule->mIsComptimeModule) && (mModule->mCompiler->mCeMachine->mCurBuilder != NULL))
  16014. linkageName = StrFormat("%d", mModule->mCompiler->mCeMachine->mCurBuilder->DbgCreateMethodRef(methodInstance, ""));
  16015. curMethodState->mCurScope->mDIScope = mModule->mBfIRBuilder->DbgCreateFunction(diParentType, methodName, linkageName, mModule->mCurFilePosition.mFileInstance->mDIFile,
  16016. defLine + 1, diFuncType, false, true, mModule->mCurFilePosition.mCurLine + 1, flags, false, BfIRValue());
  16017. scopeData.mAltDIFile = mModule->mCurFilePosition.mFileInstance->mDIFile;
  16018. }
  16019. }
  16020. if (methodDef->mBody != NULL)
  16021. mModule->UpdateSrcPos(methodDef->mBody);
  16022. mModule->SetIllegalSrcPos();
  16023. auto _AddLocalVariable = [&](BfLocalVariable* newLocalVar, BfExprEvaluator* exprEvaluator)
  16024. {
  16025. mModule->SetIllegalSrcPos();
  16026. bool hasConstValue = newLocalVar->mConstValue;
  16027. if (hasConstValue)
  16028. {
  16029. auto constant = mModule->mBfIRBuilder->GetConstant(newLocalVar->mConstValue);
  16030. hasConstValue = constant->mConstType < BfConstType_GlobalVar;
  16031. }
  16032. if ((exprEvaluator != NULL) && (exprEvaluator->mResultLocalVar != NULL) && (exprEvaluator->mResultLocalVarField == 0))
  16033. {
  16034. mModule->UpdateSrcPos(methodDeclaration->mNameNode);
  16035. mModule->AddLocalVariableDef(newLocalVar, hasConstValue);
  16036. auto inLocalVar = exprEvaluator->mResultLocalVar;
  16037. newLocalVar->mAssignedKind = inLocalVar->mAssignedKind;
  16038. newLocalVar->mUnassignedFieldFlags = inLocalVar->mUnassignedFieldFlags;
  16039. newLocalVar->mReadFromId = inLocalVar->mReadFromId;
  16040. newLocalVar->mIsReadOnly = inLocalVar->mIsReadOnly;
  16041. if ((newLocalVar->mAssignedKind == BfLocalVarAssignKind_None) && (mModule->mCurMethodState->mDeferredLocalAssignData != NULL))
  16042. {
  16043. for (auto deferredAssign : mModule->mCurMethodState->mDeferredLocalAssignData->mAssignedLocals)
  16044. {
  16045. if (deferredAssign.mLocalVar == inLocalVar)
  16046. newLocalVar->mAssignedKind = BfLocalVarAssignKind_Unconditional;
  16047. }
  16048. }
  16049. }
  16050. else
  16051. {
  16052. mModule->AddLocalVariableDef(newLocalVar, hasConstValue);
  16053. }
  16054. if ((wantsDIData) && (!mModule->mBfIRBuilder->mIgnoreWrites))
  16055. {
  16056. bool handled = false;
  16057. mModule->UpdateSrcPos(methodDeclaration->mNameNode);
  16058. if (hasConstValue)
  16059. {
  16060. // Already handled
  16061. handled = true;
  16062. }
  16063. else if (newLocalVar->mIsSplat)
  16064. {
  16065. bool found = false;
  16066. auto checkMethodState = mModule->mCurMethodState;
  16067. while ((checkMethodState != NULL) && (!found))
  16068. {
  16069. for (auto localVar : checkMethodState->mLocals)
  16070. {
  16071. if (localVar == newLocalVar)
  16072. continue;
  16073. if (!localVar->mIsSplat)
  16074. continue;
  16075. if (newLocalVar->mValue != localVar->mAddr)
  16076. continue;
  16077. bool isDupName = false;
  16078. for (auto param : methodDef->mParams)
  16079. {
  16080. if (param->mName == localVar->mName)
  16081. {
  16082. isDupName = true;
  16083. break;
  16084. }
  16085. }
  16086. if (isDupName)
  16087. {
  16088. auto splatAgg = mModule->AggregateSplat(BfTypedValue(newLocalVar->mValue, newLocalVar->mResolvedType, BfTypedValueKind_SplatHead));
  16089. // Don't allow alias if one of our args has the same name
  16090. newLocalVar->mIsSplat = false;
  16091. newLocalVar->mValue = BfIRValue();
  16092. if (splatAgg.IsAddr())
  16093. newLocalVar->mAddr = splatAgg.mValue;
  16094. else
  16095. newLocalVar->mValue = splatAgg.mValue;
  16096. found = true;
  16097. break;
  16098. }
  16099. String name = "$";
  16100. name += newLocalVar->mName;
  16101. name += "$alias$";
  16102. name += localVar->mName;
  16103. // auto fakeValue = mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, 0);
  16104. // auto diType = mModule->mBfIRBuilder->DbgGetType(mModule->GetPrimitiveType(BfTypeCode_Int32));
  16105. // auto diVariable = mModule->mBfIRBuilder->DbgCreateAutoVariable(mModule->mCurMethodState->mCurScope->mDIScope,
  16106. // name, mModule->mCurFilePosition.mFileInstance->mDIFile, mModule->mCurFilePosition.mCurLine, diType);
  16107. // mModule->mBfIRBuilder->DbgInsertValueIntrinsic(fakeValue, diVariable);
  16108. auto diType = mModule->mBfIRBuilder->DbgGetType(mModule->GetPrimitiveType(BfTypeCode_NullPtr));
  16109. auto diVariable = mModule->mBfIRBuilder->DbgCreateAutoVariable(mModule->mCurMethodState->mCurScope->mDIScope,
  16110. name, mModule->mCurFilePosition.mFileInstance->mDIFile, mModule->mCurFilePosition.mCurLine, diType);
  16111. mModule->mBfIRBuilder->DbgInsertValueIntrinsic(mModule->mBfIRBuilder->CreateConstNull(), diVariable);
  16112. handled = true;
  16113. found = true;
  16114. break;
  16115. }
  16116. checkMethodState = checkMethodState->mPrevMethodState;
  16117. }
  16118. }
  16119. if (handled)
  16120. {
  16121. //
  16122. }
  16123. else if ((mModule->IsTargetingBeefBackend()) && (!mModule->mIsComptimeModule))
  16124. {
  16125. mModule->UpdateSrcPos(methodDeclaration->mNameNode);
  16126. mModule->SetIllegalSrcPos();
  16127. // With the Beef backend we can assign two variables to the same value, but LLVM does not allow this
  16128. // so we have to create a ref to that variable
  16129. auto diType = mModule->mBfIRBuilder->DbgGetType(newLocalVar->mResolvedType);
  16130. auto diVariable = mModule->mBfIRBuilder->DbgCreateAutoVariable(mModule->mCurMethodState->mCurScope->mDIScope,
  16131. newLocalVar->mName, mModule->mCurFilePosition.mFileInstance->mDIFile, mModule->mCurFilePosition.mCurLine, diType);
  16132. if (newLocalVar->mIsSplat)
  16133. {
  16134. //TODO: Implement
  16135. }
  16136. else if (newLocalVar->mResolvedType->IsValuelessType())
  16137. {
  16138. // Do nothing
  16139. }
  16140. else
  16141. {
  16142. BfIRValue value = newLocalVar->mValue;
  16143. if (newLocalVar->mAddr)
  16144. value = newLocalVar->mAddr;
  16145. else if (newLocalVar->mConstValue)
  16146. value = newLocalVar->mConstValue;
  16147. auto aliasValue = mModule->mBfIRBuilder->CreateAliasValue(value);
  16148. if (mModule->WantsLifetimes())
  16149. scopeData.mDeferredLifetimeEnds.Add(aliasValue);
  16150. if (newLocalVar->mAddr)
  16151. mModule->mBfIRBuilder->DbgInsertDeclare(aliasValue, diVariable);
  16152. else
  16153. {
  16154. if (newLocalVar->mResolvedType->IsBoolean())
  16155. {
  16156. // Fix case of remote condbr referencing
  16157. newLocalVar->mAddr = mModule->CreateAlloca(newLocalVar->mResolvedType);
  16158. mModule->mBfIRBuilder->CreateStore(newLocalVar->mValue, newLocalVar->mAddr);
  16159. }
  16160. mModule->mBfIRBuilder->DbgInsertValueIntrinsic(aliasValue, diVariable);
  16161. }
  16162. }
  16163. }
  16164. else if (newLocalVar->mAddr)
  16165. {
  16166. mModule->UpdateSrcPos(methodDeclaration->mNameNode);
  16167. mModule->SetIllegalSrcPos();
  16168. auto refType = mModule->CreateRefType(newLocalVar->mResolvedType);
  16169. auto allocaVal = mModule->CreateAlloca(refType);
  16170. mModule->mBfIRBuilder->CreateStore(newLocalVar->mAddr, allocaVal);
  16171. if (!mModule->mBfIRBuilder->mIgnoreWrites)
  16172. {
  16173. auto diType = mModule->mBfIRBuilder->DbgGetType(refType);
  16174. auto diVariable = mModule->mBfIRBuilder->DbgCreateAutoVariable(mModule->mCurMethodState->mCurScope->mDIScope,
  16175. newLocalVar->mName, mModule->mCurFilePosition.mFileInstance->mDIFile, mModule->mCurFilePosition.mCurLine, diType);
  16176. mModule->mBfIRBuilder->DbgInsertDeclare(allocaVal, diVariable);
  16177. }
  16178. }
  16179. else if (newLocalVar->mValue)
  16180. {
  16181. mModule->UpdateSrcPos(methodDeclaration->mNameNode);
  16182. mModule->SetIllegalSrcPos();
  16183. auto localVal = LoadLocal(newLocalVar);
  16184. localVal = mModule->LoadValue(localVal);
  16185. localVal = mModule->AggregateSplat(localVal);
  16186. BfType* allocType = localVal.mType;
  16187. if (!allocType->IsValuelessType())
  16188. {
  16189. auto allocaVal = mModule->CreateAlloca(allocType);
  16190. mModule->mBfIRBuilder->CreateStore(localVal.mValue, allocaVal);
  16191. if (!mModule->mBfIRBuilder->mIgnoreWrites)
  16192. {
  16193. if (newLocalVar->mIsSplat)
  16194. {
  16195. //TODO: Implement
  16196. }
  16197. else
  16198. {
  16199. auto diType = mModule->mBfIRBuilder->DbgGetType(allocType);
  16200. auto diVariable = mModule->mBfIRBuilder->DbgCreateAutoVariable(mModule->mCurMethodState->mCurScope->mDIScope,
  16201. newLocalVar->mName, mModule->mCurFilePosition.mFileInstance->mDIFile, mModule->mCurFilePosition.mCurLine, diType);
  16202. mModule->mBfIRBuilder->DbgInsertDeclare(allocaVal, diVariable);
  16203. }
  16204. }
  16205. }
  16206. }
  16207. }
  16208. newLocalVar->mParamIdx = -3;
  16209. mixinState->mArgTypes.Add(newLocalVar->mResolvedType);
  16210. if (mModule->mBfIRBuilder->IsConstValue(newLocalVar->mConstValue))
  16211. mixinState->mArgConsts.Add(newLocalVar->mConstValue);
  16212. };
  16213. argExprEvaluatorItr = argExprEvaluators.begin();
  16214. for (int argIdx = methodDef->mIsStatic ? 0 : -1; argIdx < (int)explicitParamCount; argIdx++)
  16215. {
  16216. int paramIdx = argIdx;
  16217. auto exprEvaluator = *argExprEvaluatorItr;
  16218. BfTypedValue argValue;
  16219. BfLocalVariable* localVar = new BfLocalVariable();
  16220. if (argIdx == -1)
  16221. {
  16222. argValue = target;
  16223. localVar->mName = "this";
  16224. localVar->mIsThis = true;
  16225. localVar->mAssignedKind = BfLocalVarAssignKind_Unconditional;
  16226. }
  16227. else
  16228. {
  16229. auto arg = &args[argIdx];
  16230. auto paramDef = methodDef->mParams[paramIdx];
  16231. localVar->mName = paramDef->mName;
  16232. if (!arg->mTypedValue)
  16233. {
  16234. auto wantType = methodInstance->GetParamType(paramIdx);
  16235. if (wantType->IsVar())
  16236. wantType = mModule->mContext->mBfObjectType;
  16237. arg->mTypedValue = mModule->GetDefaultTypedValue(wantType);
  16238. }
  16239. argValue = arg->mTypedValue;
  16240. }
  16241. if (!argValue)
  16242. continue;
  16243. localVar->mResolvedType = argValue.mType;
  16244. if (argValue.mType->IsRef())
  16245. {
  16246. auto refType = (BfRefType*)localVar->mResolvedType;
  16247. localVar->mAddr = mModule->LoadValue(argValue).mValue;
  16248. localVar->mResolvedType = argValue.mType->GetUnderlyingType();
  16249. localVar->mAssignedKind = (refType->mRefKind != BfRefType::RefKind_Out) ? BfLocalVarAssignKind_Unconditional : BfLocalVarAssignKind_None;
  16250. }
  16251. else if (argValue.IsAddr())
  16252. localVar->mAddr = argValue.mValue;
  16253. else
  16254. {
  16255. if (!argValue.mValue)
  16256. {
  16257. // Untyped value
  16258. }
  16259. else if (argValue.mValue.IsConst())
  16260. {
  16261. localVar->mConstValue = argValue.mValue;
  16262. }
  16263. else if (argValue.IsSplat())
  16264. {
  16265. localVar->mValue = argValue.mValue;
  16266. localVar->mIsSplat = true;
  16267. }
  16268. else
  16269. {
  16270. if (argValue.IsAddr())
  16271. localVar->mAddr = argValue.mValue;
  16272. else
  16273. localVar->mValue = argValue.mValue;
  16274. }
  16275. localVar->mIsReadOnly = argValue.IsReadOnly();
  16276. }
  16277. if (argValue.IsReadOnly())
  16278. localVar->mIsReadOnly = true;
  16279. if (argIdx == -1)
  16280. {
  16281. _AddLocalVariable(localVar, NULL);
  16282. }
  16283. else
  16284. {
  16285. _AddLocalVariable(localVar, exprEvaluator);
  16286. endLocalIdx++;
  16287. ++argExprEvaluatorItr;
  16288. }
  16289. }
  16290. if (auto blockBody = BfNodeDynCast<BfBlock>(methodDef->mBody))
  16291. {
  16292. mModule->VisitCodeBlock(blockBody);
  16293. if (mixinState->mResultExpr != NULL)
  16294. {
  16295. if (auto exprNode = BfNodeDynCast<BfExpression>(mixinState->mResultExpr))
  16296. {
  16297. if (!exprNode->IsA<BfBlock>())
  16298. {
  16299. // Mixin expression result
  16300. SetAndRestoreValue<BfEvalExprFlags> prevFlags(mBfEvalExprFlags, (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_AllowRefExpr));
  16301. mModule->UpdateSrcPos(exprNode);
  16302. VisitChild(exprNode);
  16303. FinishExpressionResult();
  16304. ResolveGenericType();
  16305. }
  16306. }
  16307. }
  16308. GetResult();
  16309. }
  16310. else if (auto expr = BfNodeDynCast<BfExpression>(methodDef->mBody))
  16311. {
  16312. mModule->UpdateSrcPos(expr);
  16313. mResult = mModule->CreateValueFromExpression(expr);
  16314. }
  16315. if (!mResult)
  16316. {
  16317. // If we didn't have an expression body then just make the result "void"
  16318. mResult = BfTypedValue(BfIRValue(), mModule->GetPrimitiveType(BfTypeCode_None));
  16319. }
  16320. mResult = mModule->RemoveRef(mResult);
  16321. if (mResult.IsAddr())
  16322. {
  16323. if (mModule->mCurMethodState->mCurScope->ExtendLifetime(mResult.mValue))
  16324. mModule->mBfIRBuilder->CreateLifetimeSoftEnd(mResult.mValue);
  16325. }
  16326. int localIdx = startLocalIdx;
  16327. argExprEvaluatorItr = argExprEvaluators.begin();
  16328. for (; localIdx < endLocalIdx; localIdx++)
  16329. {
  16330. auto exprEvaluator = *argExprEvaluatorItr;
  16331. BfLocalVariable* localVar = curMethodState->mLocals[localIdx];
  16332. //TODO: Merge unassigned flags together
  16333. if ((exprEvaluator != NULL) && (exprEvaluator->mResultLocalVar != NULL))
  16334. {
  16335. auto inLocalVar = exprEvaluator->mResultLocalVar;
  16336. if (localVar->mAssignedKind != BfLocalVarAssignKind_None)
  16337. inLocalVar->mAssignedKind = BfLocalVarAssignKind_Unconditional;
  16338. if (localVar->mReadFromId != -1)
  16339. inLocalVar->mReadFromId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++;
  16340. }
  16341. ++argExprEvaluatorItr;
  16342. }
  16343. if (auto blockBody = BfNodeDynCast<BfBlock>(methodDef->mBody))
  16344. {
  16345. if (blockBody->mCloseBrace != NULL)
  16346. mModule->UpdateSrcPos(blockBody->mCloseBrace);
  16347. }
  16348. else if (auto methodDeclaration = BfNodeDynCast<BfMethodDeclaration>(methodDef->mMethodDeclaration))
  16349. {
  16350. if (methodDeclaration->mFatArrowToken != NULL)
  16351. mModule->UpdateSrcPos(methodDeclaration->mFatArrowToken);
  16352. }
  16353. mModule->RestoreScopeState();
  16354. prevMixinState.Restore();
  16355. if ((scopedInvocationTarget != NULL) && (scopedInvocationTarget->mScopeName != NULL) && (!mixinState->mUsedInvocationScope))
  16356. {
  16357. mModule->Warn(0, "Scope specifier was not referenced in mixin", scopedInvocationTarget->mScopeName);
  16358. }
  16359. if (mixinState->mHasDeferredUsage)
  16360. {
  16361. mixinState->mTarget = BfTypedValue();
  16362. // Put deferred mixin states at the front
  16363. BF_ASSERT(rootMethodState->mMixinStates.back() == mixinState);
  16364. rootMethodState->mMixinStates.pop_back();
  16365. rootMethodState->mMixinStates.Insert(0, mixinState);
  16366. }
  16367. else
  16368. {
  16369. BF_ASSERT(rootMethodState->mMixinStates.back() == mixinState);
  16370. rootMethodState->mMixinStates.pop_back();
  16371. delete mixinState;
  16372. }
  16373. mModule->mBfIRBuilder->RestoreDebugLocation();
  16374. mModule->mBfIRBuilder->DupDebugLocation();
  16375. }
  16376. void BfExprEvaluator::SetMethodElementType(BfAstNode* target)
  16377. {
  16378. if (auto delegateBindExpr = BfNodeDynCast<BfDelegateBindExpression>(target))
  16379. {
  16380. SetMethodElementType(delegateBindExpr->mTarget);
  16381. return;
  16382. }
  16383. if (auto lambdaBindExpr = BfNodeDynCast<BfLambdaBindExpression>(target))
  16384. {
  16385. return;
  16386. }
  16387. if (auto attributedIdentifierNode = BfNodeDynCast<BfAttributedIdentifierNode>(target))
  16388. {
  16389. if (attributedIdentifierNode->mIdentifier != NULL)
  16390. mModule->SetElementType(attributedIdentifierNode->mIdentifier, BfSourceElementType_Method);
  16391. }
  16392. else if (auto memberReferenceExpr = BfNodeDynCast<BfMemberReferenceExpression>(target))
  16393. {
  16394. if (memberReferenceExpr->mMemberName != NULL)
  16395. SetMethodElementType(memberReferenceExpr->mMemberName);
  16396. }
  16397. else if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(target))
  16398. SetMethodElementType(qualifiedNameNode->mRight);
  16399. else
  16400. mModule->SetElementType(target, BfSourceElementType_Method);
  16401. }
  16402. void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* methodBoundExpr, const BfSizedArray<BfExpression*>& args, const BfMethodGenericArguments& methodGenericArgs, BfTypedValue* outCascadeValue)
  16403. {
  16404. auto methodGenericArguments = methodGenericArgs.mArguments;
  16405. // Just a check
  16406. mModule->mBfIRBuilder->GetInsertBlock();
  16407. bool wasCapturingMethodInfo = false;
  16408. auto autoComplete = GetAutoComplete();
  16409. if ((autoComplete != NULL) && (methodGenericArguments != NULL))
  16410. {
  16411. for (BfAstNode* methodGenericArg : *methodGenericArguments)
  16412. {
  16413. autoComplete->CheckNode(methodGenericArg, false, true);
  16414. }
  16415. }
  16416. if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo))
  16417. {
  16418. // We don't want to capture a call within the target node
  16419. wasCapturingMethodInfo = true;
  16420. autoComplete->mIsCapturingMethodMatchInfo = false;
  16421. }
  16422. bool allowImplicitThis = false;
  16423. BfAstNode* methodNodeSrc = target;
  16424. BfAttributeState attributeState;
  16425. attributeState.mTarget = (BfAttributeTargets)(BfAttributeTargets_Invocation | BfAttributeTargets_MemberAccess);
  16426. if (auto scopedTarget = BfNodeDynCast<BfScopedInvocationTarget>(target))
  16427. {
  16428. target = scopedTarget->mTarget;
  16429. if (autoComplete != NULL)
  16430. {
  16431. if (auto identifier = BfNodeDynCast<BfIdentifierNode>(scopedTarget->mScopeName))
  16432. autoComplete->CheckLabel(identifier, scopedTarget->mColonToken, NULL);
  16433. }
  16434. //mModule->FindScope(scopedTarget->mScopeName);
  16435. }
  16436. bool isCascade = false;
  16437. BfAstNode* cascadeOperatorToken = NULL;
  16438. bool bypassVirtual = false;
  16439. bool gaveUnqualifiedDotError = false;
  16440. String targetFunctionName;
  16441. BfTypedValue thisValue;
  16442. //TODO: This may just be a fully qualified static method name, so let's check that also
  16443. if (auto memberRefExpression = BfNodeDynCast<BfMemberReferenceExpression>(target))
  16444. {
  16445. if (autoComplete != NULL)
  16446. {
  16447. if (memberRefExpression->mTarget != NULL)
  16448. autoComplete->CheckMemberReference(memberRefExpression->mTarget, memberRefExpression->mDotToken, memberRefExpression->mMemberName, false, mExpectingType);
  16449. else if (mExpectingType != NULL)
  16450. {
  16451. String filter;
  16452. if ((autoComplete != NULL) && (autoComplete->InitAutocomplete(memberRefExpression->mDotToken, memberRefExpression->mMemberName, filter)))
  16453. {
  16454. auto typeInst = mExpectingType->ToTypeInstance();
  16455. if (typeInst != NULL)
  16456. {
  16457. String filter;
  16458. if ((memberRefExpression->mMemberName != NULL) && (autoComplete->IsAutocompleteNode(memberRefExpression->mMemberName)))
  16459. filter = autoComplete->GetFilter(memberRefExpression->mMemberName);
  16460. bool allowPrivate = typeInst == mModule->mCurTypeInstance;
  16461. autoComplete->AddEnumTypeMembers(typeInst, filter, false, allowPrivate);
  16462. autoComplete->AddSelfResultTypeMembers(typeInst, typeInst, filter, allowPrivate);
  16463. }
  16464. }
  16465. }
  16466. }
  16467. if ((memberRefExpression->mTarget == NULL) && (memberRefExpression->mMemberName == NULL))
  16468. {
  16469. auto expectingType = mExpectingType;
  16470. if ((expectingType != NULL) && (expectingType->IsNullable()))
  16471. {
  16472. auto underlyingType = expectingType->GetUnderlyingType();
  16473. expectingType = underlyingType;
  16474. }
  16475. BfType* inRefType = NULL;
  16476. if ((expectingType != NULL) && (expectingType->IsRef()))
  16477. {
  16478. auto refType = (BfRefType*)expectingType;
  16479. if (refType->mRefKind == BfRefType::RefKind_In)
  16480. {
  16481. inRefType = expectingType;
  16482. auto underlyingType = expectingType->GetUnderlyingType();
  16483. expectingType = underlyingType;
  16484. }
  16485. }
  16486. if (expectingType != NULL)
  16487. {
  16488. if (expectingType->IsSizedArray())
  16489. {
  16490. if (mModule->mParentNodeEntry != NULL)
  16491. {
  16492. if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(mModule->mParentNodeEntry->mNode))
  16493. {
  16494. InitializedSizedArray((BfSizedArrayType*)expectingType, invocationExpr->mOpenParen, invocationExpr->mArguments, invocationExpr->mCommas, invocationExpr->mCloseParen);
  16495. return;
  16496. }
  16497. }
  16498. }
  16499. else if ((expectingType->IsStruct()) || (expectingType->IsTypedPrimitive()))
  16500. {
  16501. if ((wasCapturingMethodInfo) && (autoComplete->mMethodMatchInfo != NULL))
  16502. {
  16503. autoComplete->mIsCapturingMethodMatchInfo = true;
  16504. BF_ASSERT(autoComplete->mMethodMatchInfo != NULL);
  16505. }
  16506. if (mModule->mParentNodeEntry != NULL)
  16507. {
  16508. if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(mModule->mParentNodeEntry->mNode))
  16509. {
  16510. BfResolvedArgs argValues(invocationExpr->mOpenParen, &invocationExpr->mArguments, &invocationExpr->mCommas, invocationExpr->mCloseParen);
  16511. BfResolveArgsFlags resolveArgsFlags = BfResolveArgsFlag_DeferParamEval;
  16512. ResolveArgValues(argValues, resolveArgsFlags);
  16513. if ((mReceivingValue != NULL) && (mReceivingValue->mType == expectingType) && (mReceivingValue->IsAddr()))
  16514. {
  16515. mResult = *mReceivingValue;
  16516. mReceivingValue = NULL;
  16517. }
  16518. else
  16519. mResult = BfTypedValue(mModule->CreateAlloca(expectingType), expectingType, BfTypedValueKind_TempAddr);
  16520. auto ctorResult = MatchConstructor(target, methodBoundExpr, mResult, expectingType->ToTypeInstance(), argValues, false, BfMethodGenericArguments(), BfAllowAppendKind_No);
  16521. if ((ctorResult) && (!ctorResult.mType->IsVoid()))
  16522. mResult = ctorResult;
  16523. mModule->ValidateAllocation(expectingType, invocationExpr->mTarget);
  16524. if ((inRefType != NULL) && (mResult.mType == expectingType) && (mResult.IsAddr()))
  16525. {
  16526. // Put back the 'in'
  16527. mResult = BfTypedValue(mResult.mValue, inRefType);
  16528. }
  16529. return;
  16530. }
  16531. }
  16532. }
  16533. else if (expectingType->IsGenericParam())
  16534. {
  16535. if (mModule->mParentNodeEntry != NULL)
  16536. {
  16537. if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(mModule->mParentNodeEntry->mNode))
  16538. {
  16539. BfResolvedArgs argValues(invocationExpr->mOpenParen, &invocationExpr->mArguments, &invocationExpr->mCommas, invocationExpr->mCloseParen);
  16540. BfResolveArgsFlags resolveArgsFlags = BfResolveArgsFlag_None;
  16541. ResolveArgValues(argValues, resolveArgsFlags);
  16542. if (!mModule->mCurMethodInstance->mIsUnspecializedVariation)
  16543. CheckGenericCtor((BfGenericParamType*)expectingType, argValues, invocationExpr->mTarget);
  16544. mResult = mModule->GetDefaultTypedValue(expectingType);
  16545. return;
  16546. }
  16547. }
  16548. }
  16549. else if (expectingType->IsVar())
  16550. {
  16551. // Silently allow
  16552. gaveUnqualifiedDotError = true;
  16553. }
  16554. else if (expectingType->IsPrimitiveType())
  16555. {
  16556. // Allow
  16557. }
  16558. else if ((mBfEvalExprFlags & BfEvalExprFlags_AppendFieldInitializer) == 0)
  16559. {
  16560. gaveUnqualifiedDotError = true;
  16561. if (mModule->PreFail())
  16562. mModule->Fail(StrFormat("Cannot use inferred constructor on type '%s'", mModule->TypeToString(expectingType).c_str()), memberRefExpression->mDotToken);
  16563. }
  16564. }
  16565. }
  16566. if (memberRefExpression->IsA<BfBaseExpression>())
  16567. bypassVirtual = true;
  16568. if (memberRefExpression->mMemberName != NULL)
  16569. methodNodeSrc = memberRefExpression->mMemberName;
  16570. if (auto attrIdentifier = BfNodeDynCast<BfAttributedIdentifierNode>(memberRefExpression->mMemberName))
  16571. {
  16572. if (attrIdentifier->mIdentifier != NULL)
  16573. methodNodeSrc = attrIdentifier->mIdentifier;
  16574. attributeState.mSrc = attrIdentifier->mAttributes;
  16575. attributeState.mCustomAttributes = mModule->GetCustomAttributes(attrIdentifier->mAttributes, attributeState.mTarget);
  16576. if (attrIdentifier->mIdentifier != NULL)
  16577. targetFunctionName = attrIdentifier->mIdentifier->ToString();
  16578. }
  16579. else if (memberRefExpression->mMemberName != NULL)
  16580. targetFunctionName = memberRefExpression->mMemberName->ToString();
  16581. if (memberRefExpression->mTarget == NULL)
  16582. {
  16583. if (mExpectingType)
  16584. {
  16585. if (mExpectingType->IsVar())
  16586. {
  16587. }
  16588. mResult = BfTypedValue(mExpectingType);
  16589. }
  16590. else if (!gaveUnqualifiedDotError)
  16591. mModule->Fail("Unqualified dot syntax can only be used when the result type can be inferred", memberRefExpression->mDotToken);
  16592. }
  16593. else if (auto typeRef = BfNodeDynCast<BfTypeReference>(memberRefExpression->mTarget))
  16594. {
  16595. // Static method
  16596. mResult = BfTypedValue(ResolveTypeRef(typeRef));
  16597. }
  16598. if (auto leftIdentifier = BfNodeDynCast<BfIdentifierNode>(memberRefExpression->mTarget))
  16599. {
  16600. bool hadError = false;
  16601. thisValue = LookupIdentifier(leftIdentifier, true, &hadError);
  16602. CheckResultForReading(thisValue);
  16603. if (mPropDef != NULL)
  16604. thisValue = GetResult(true);
  16605. if (hadError)
  16606. {
  16607. mModule->AssertErrorState();
  16608. thisValue = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  16609. }
  16610. if ((!thisValue) && (mPropDef == NULL))
  16611. {
  16612. // Identifier not found. Static method? Just check speculatively don't throw error
  16613. BfType* type;
  16614. {
  16615. SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
  16616. type = mModule->ResolveTypeRef(leftIdentifier, NULL, BfPopulateType_DataAndMethods, BfResolveTypeRefFlag_NoResolveGenericParam);
  16617. }
  16618. if (type != NULL)
  16619. thisValue = BfTypedValue(type);
  16620. else if (auto qualifiedLeft = BfNodeDynCast<BfQualifiedNameNode>(leftIdentifier))
  16621. {
  16622. LookupQualifiedStaticField(qualifiedLeft, true);
  16623. thisValue = mResult;
  16624. mResult = BfTypedValue();
  16625. }
  16626. }
  16627. if (mPropDef != NULL)
  16628. thisValue = GetResult(true);
  16629. if (!thisValue.mType)
  16630. {
  16631. mModule->Fail("Identifier not found", leftIdentifier);
  16632. mModule->CheckTypeRefFixit(leftIdentifier);
  16633. thisValue = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  16634. }
  16635. if (mResult)
  16636. CheckResultForReading(mResult);
  16637. mResult = thisValue;
  16638. }
  16639. else if (auto expr = BfNodeDynCast<BfExpression>(memberRefExpression->mTarget))
  16640. {
  16641. BfType* expectingTargetType = NULL;
  16642. if (memberRefExpression->mDotToken->mToken == BfToken_DotDot)
  16643. expectingTargetType = mExpectingType;
  16644. bool handled = false;
  16645. if (auto subMemberRefExpr = BfNodeDynCast<BfMemberReferenceExpression>(expr))
  16646. {
  16647. String findName;
  16648. if (subMemberRefExpr->mMemberName != NULL)
  16649. findName = subMemberRefExpr->mMemberName->ToString();
  16650. if (findName == "base") // Generic IFace<T>.base
  16651. {
  16652. thisValue = mModule->GetThis();
  16653. if (thisValue)
  16654. {
  16655. VisitChild(subMemberRefExpr->mTarget);
  16656. if (mResult.HasType())
  16657. {
  16658. if (mResult.mValue)
  16659. {
  16660. mModule->Fail("Type name expected", subMemberRefExpr->mTarget);
  16661. }
  16662. else
  16663. {
  16664. auto type = mResult.mType;
  16665. if (type != NULL)
  16666. {
  16667. if ((thisValue.mType == type) || (!mModule->TypeIsSubTypeOf(thisValue.mType->ToTypeInstance(), type->ToTypeInstance())))
  16668. {
  16669. mModule->Fail(StrFormat("Type '%s' is not a base type of '%s'",
  16670. mModule->TypeToString(type).c_str(),
  16671. mModule->TypeToString(thisValue.mType).c_str()), subMemberRefExpr->mTarget);
  16672. }
  16673. else
  16674. {
  16675. if (type->IsInterface())
  16676. {
  16677. thisValue.mType = type;
  16678. }
  16679. else
  16680. {
  16681. auto castedThis = mModule->Cast(subMemberRefExpr->mMemberName, thisValue, type, BfCastFlags_Explicit);
  16682. if (castedThis)
  16683. thisValue = castedThis;
  16684. //mModule->Fail("Explicit base types can only be used for specifying default interface members", qualifiedLeft->mLeft);
  16685. }
  16686. }
  16687. handled = true;
  16688. }
  16689. bypassVirtual = true;
  16690. }
  16691. }
  16692. }
  16693. }
  16694. }
  16695. if (!handled)
  16696. {
  16697. SetAndRestoreValue<BfAttributeState*> prevAttributeState(mModule->mAttributeState, &attributeState);
  16698. auto flags = (BfEvalExprFlags)(BfEvalExprFlags_PropogateNullConditional | BfEvalExprFlags_NoCast);
  16699. if (mFunctionBindResult != NULL)
  16700. {
  16701. if (auto paranExpr = BfNodeDynCast<BfParenthesizedExpression>(expr))
  16702. {
  16703. // Allow 'ref' on binding, to indicate we want to capture 'this' by reference
  16704. flags = (BfEvalExprFlags)(flags | BfEvalExprFlags_AllowRefExpr);
  16705. expr = paranExpr->mExpression;
  16706. }
  16707. }
  16708. if (expr != NULL)
  16709. mResult = mModule->CreateValueFromExpression(expr, expectingTargetType, flags);
  16710. }
  16711. }
  16712. isCascade = (memberRefExpression->mDotToken != NULL) && (memberRefExpression->mDotToken->GetToken() == BfToken_DotDot);
  16713. if (isCascade)
  16714. cascadeOperatorToken = memberRefExpression->mDotToken;
  16715. bool isNullCondLookup = (memberRefExpression->mDotToken != NULL) && (memberRefExpression->mDotToken->GetToken() == BfToken_QuestionDot);
  16716. if (isNullCondLookup)
  16717. mResult = SetupNullConditional(mResult, memberRefExpression->mDotToken);
  16718. if ((mResult.mType == NULL) && (memberRefExpression->mTarget != NULL))
  16719. {
  16720. mModule->AssertErrorState();
  16721. mResult = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  16722. }
  16723. thisValue = mResult;
  16724. mResult = BfTypedValue();
  16725. if ((thisValue) && (memberRefExpression->mDotToken != NULL) && (memberRefExpression->mDotToken->mToken == BfToken_Arrow))
  16726. thisValue = TryArrowLookup(thisValue, memberRefExpression->mDotToken);
  16727. }
  16728. else if (auto qualifiedName = BfNodeDynCast<BfQualifiedNameNode>(target))
  16729. {
  16730. if (GetAutoComplete() != NULL)
  16731. GetAutoComplete()->CheckMemberReference(qualifiedName->mLeft, qualifiedName->mDot, qualifiedName->mRight);
  16732. bool isGlobalLookup = false;
  16733. if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(target))
  16734. {
  16735. if (qualifiedNameNode->IsGlobalLookup())
  16736. {
  16737. if (auto subQualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(qualifiedNameNode->mRight))
  16738. {
  16739. qualifiedName = subQualifiedNameNode;
  16740. isGlobalLookup = true;
  16741. }
  16742. }
  16743. }
  16744. if ((!isGlobalLookup) && (qualifiedName->mLeft->GetSrcLength() == 4))
  16745. {
  16746. if (CheckIsBase(qualifiedName->mLeft))
  16747. bypassVirtual = true;
  16748. }
  16749. if (qualifiedName->mRight != NULL)
  16750. methodNodeSrc = qualifiedName->mRight;
  16751. if (auto attrIdentifier = BfNodeDynCast<BfAttributedIdentifierNode>(qualifiedName->mRight))
  16752. {
  16753. if (attrIdentifier->mIdentifier != NULL)
  16754. methodNodeSrc = attrIdentifier->mIdentifier;
  16755. attributeState.mSrc = attrIdentifier->mAttributes;
  16756. attributeState.mCustomAttributes = mModule->GetCustomAttributes(attrIdentifier->mAttributes, attributeState.mTarget);
  16757. targetFunctionName = attrIdentifier->mIdentifier->ToString();
  16758. }
  16759. else
  16760. targetFunctionName = qualifiedName->mRight->ToString();
  16761. bool hadError = false;
  16762. if (!isGlobalLookup)
  16763. thisValue = LookupIdentifier(qualifiedName->mLeft, true, &hadError);
  16764. CheckResultForReading(thisValue);
  16765. if (mPropDef != NULL)
  16766. thisValue = GetResult(true);
  16767. if (hadError)
  16768. {
  16769. mModule->AssertErrorState();
  16770. thisValue = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  16771. }
  16772. if ((!thisValue) && (mPropDef == NULL))
  16773. {
  16774. auto typeLookupFlags = (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoResolveGenericParam | BfResolveTypeRefFlag_AllowGlobalContainer | BfResolveTypeRefFlag_IgnoreLookupError);
  16775. if (isGlobalLookup)
  16776. typeLookupFlags = (BfResolveTypeRefFlags)(typeLookupFlags | BfResolveTypeRefFlag_GlobalLookup);
  16777. // Identifier not found. Static method? Just check speculatively don't throw error
  16778. BfType* type;
  16779. {
  16780. //SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
  16781. type = mModule->ResolveTypeRef(qualifiedName->mLeft, NULL, BfPopulateType_DataAndMethods, typeLookupFlags);
  16782. }
  16783. if (type == NULL)
  16784. {
  16785. //SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
  16786. type = mModule->ResolveTypeRef(qualifiedName, methodGenericArguments, BfPopulateType_DataAndMethods, typeLookupFlags);
  16787. if (type != NULL)
  16788. {
  16789. // This is a CTOR call, treat it as such
  16790. targetFunctionName.clear();
  16791. }
  16792. }
  16793. if (type != NULL)
  16794. thisValue = BfTypedValue(type);
  16795. else if (auto qualifiedLeft = BfNodeDynCast<BfQualifiedNameNode>(qualifiedName->mLeft))
  16796. {
  16797. String findName = qualifiedLeft->mRight->ToString();
  16798. bool handled = false;
  16799. if (findName == "base")
  16800. {
  16801. auto type = mModule->ResolveTypeRef(qualifiedLeft->mLeft, NULL, BfPopulateType_Data, BfResolveTypeRefFlag_AllowRef);
  16802. mModule->CheckTypeRefFixit(qualifiedLeft->mLeft);
  16803. thisValue = mModule->GetThis();
  16804. if (type != NULL)
  16805. {
  16806. if ((thisValue.mType == type) || (!mModule->TypeIsSubTypeOf(thisValue.mType->ToTypeInstance(), type->ToTypeInstance())))
  16807. {
  16808. mModule->Fail(StrFormat("Type '%s' is not a base type of '%s'",
  16809. mModule->TypeToString(type).c_str(),
  16810. mModule->TypeToString(thisValue.mType).c_str()), qualifiedLeft->mLeft);
  16811. }
  16812. else
  16813. {
  16814. if (type->IsInterface())
  16815. {
  16816. thisValue.mType = type;
  16817. }
  16818. else
  16819. {
  16820. auto castedThis = mModule->Cast(qualifiedLeft->mRight, thisValue, type, BfCastFlags_Explicit);
  16821. if (castedThis)
  16822. thisValue = castedThis;
  16823. //mModule->Fail("Explicit base types can only be used for specifying default interface members", qualifiedLeft->mLeft);
  16824. }
  16825. }
  16826. handled = true;
  16827. }
  16828. bypassVirtual = true;
  16829. }
  16830. if (!handled)
  16831. {
  16832. LookupQualifiedStaticField(qualifiedLeft, true);
  16833. thisValue = mResult;
  16834. mResult = BfTypedValue();
  16835. }
  16836. }
  16837. }
  16838. if (mPropDef != NULL)
  16839. thisValue = GetResult(true);
  16840. if (!thisValue.mType)
  16841. {
  16842. mModule->Fail("Identifier not found", qualifiedName->mLeft);
  16843. mModule->CheckTypeRefFixit(qualifiedName->mLeft);
  16844. mModule->CheckIdentifierFixit(qualifiedName->mLeft);
  16845. thisValue = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Var));
  16846. }
  16847. if (mResult)
  16848. CheckResultForReading(mResult);
  16849. mResult = BfTypedValue();
  16850. }
  16851. else if (auto identiferExpr = BfNodeDynCast<BfIdentifierNode>(target))
  16852. {
  16853. if (auto attrIdentifier = BfNodeDynCast<BfAttributedIdentifierNode>(target))
  16854. {
  16855. if (attrIdentifier->mIdentifier != NULL)
  16856. methodNodeSrc = attrIdentifier->mIdentifier;
  16857. attributeState.mSrc = attrIdentifier->mAttributes;
  16858. attributeState.mCustomAttributes = mModule->GetCustomAttributes(attrIdentifier->mAttributes, attributeState.mTarget);
  16859. }
  16860. allowImplicitThis = true;
  16861. if (autoComplete != NULL)
  16862. autoComplete->CheckIdentifier(identiferExpr);
  16863. targetFunctionName = target->ToString();
  16864. if (targetFunctionName == "PrintF") // Just directly call that one
  16865. {
  16866. BfType* charType = mModule->GetPrimitiveType(BfTypeCode_Char8);
  16867. BfType* charPtrType = mModule->CreatePointerType(charType);
  16868. auto func = mModule->GetBuiltInFunc(BfBuiltInFuncType_PrintF);
  16869. SizedArray<BfIRValue, 4> irArgs;
  16870. for (BfExpression* arg : args)
  16871. {
  16872. BfTypedValue value;
  16873. if (arg != NULL)
  16874. value = mModule->CreateValueFromExpression(arg);
  16875. if (!value)
  16876. return;
  16877. auto typeInst = value.mType->ToTypeInstance();
  16878. if ((typeInst != NULL) && (typeInst->IsInstanceOf(mModule->mCompiler->mStringTypeDef)))
  16879. value = mModule->Cast(arg, value, charPtrType);
  16880. if ((value.mType->IsFloat()) && (value.mType->mSize != 8)) // Always cast float to double
  16881. value = mModule->Cast(arg, value, mModule->GetPrimitiveType(BfTypeCode_Double));
  16882. irArgs.push_back(value.mValue);
  16883. }
  16884. if ((targetFunctionName != "PrintF") || (irArgs.size() > 0))
  16885. {
  16886. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCall(func, irArgs/*, targetFunctionName*/),
  16887. mModule->ResolveTypeDef(mModule->mSystem->mTypeInt32));
  16888. }
  16889. return;
  16890. }
  16891. if (auto ceDbgState = mModule->GetCeDbgState())
  16892. {
  16893. if (targetFunctionName.StartsWith("__"))
  16894. {
  16895. auto ceDebugger = mModule->mCompiler->mCeMachine->mDebugger;
  16896. auto _ResolveArg = [&](int argIdx, BfType* type = NULL)
  16897. {
  16898. if ((argIdx < 0) || (argIdx >= args.mSize))
  16899. return BfTypedValue();
  16900. return mModule->CreateValueFromExpression(args[argIdx], type);
  16901. };
  16902. if (targetFunctionName == "__getHighBits")
  16903. {
  16904. auto typedVal = _ResolveArg(0);
  16905. if ((typedVal) && (typedVal.mType->IsPrimitiveType()))
  16906. {
  16907. auto primType = (BfPrimitiveType*)typedVal.mType;
  16908. int64 val = ceDebugger->ValueToInt(typedVal);
  16909. int64 bitCount = ceDebugger->ValueToInt(_ResolveArg(1));
  16910. int64 resultVal = val >> (typedVal.mType->mSize * 8 - bitCount);
  16911. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, (uint64)resultVal), typedVal.mType);
  16912. return;
  16913. }
  16914. }
  16915. else if (targetFunctionName == "__clearHighBits")
  16916. {
  16917. auto typedVal = _ResolveArg(0);
  16918. if ((typedVal) && (typedVal.mType->IsPrimitiveType()))
  16919. {
  16920. auto primType = (BfPrimitiveType*)typedVal.mType;
  16921. int64 val = ceDebugger->ValueToInt(typedVal);
  16922. int64 bitCount = ceDebugger->ValueToInt(_ResolveArg(1));
  16923. int64 andBits = (0x8000000000000000LL) >> ((typedVal.mType->mSize - 8) * 8 + bitCount - 1);
  16924. int64 resultVal = val & ~andBits;
  16925. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, (uint64)resultVal), typedVal.mType);
  16926. return;
  16927. }
  16928. }
  16929. else if ((targetFunctionName == "__cast") || (targetFunctionName == "__bitcast"))
  16930. {
  16931. BfType* type = NULL;
  16932. String typeName;
  16933. for (int argIdx = 0; argIdx < args.mSize - 1; argIdx++)
  16934. {
  16935. auto arg = _ResolveArg(argIdx);
  16936. if (!arg)
  16937. continue;
  16938. if (arg.mType->IsInstanceOf(mModule->mCompiler->mStringTypeDef))
  16939. {
  16940. auto strPtr = mModule->GetStringPoolString(arg.mValue, mModule->mBfIRBuilder);
  16941. if (strPtr != NULL)
  16942. {
  16943. if ((type != NULL) && (*strPtr == "*"))
  16944. {
  16945. type = mModule->CreatePointerType(type);
  16946. }
  16947. else
  16948. typeName += *strPtr;
  16949. }
  16950. }
  16951. if (arg.mType->IsInteger())
  16952. {
  16953. int64 intVal = ceDebugger->ValueToInt(arg);
  16954. if (typeName.IsEmpty())
  16955. {
  16956. auto typeType = mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef)->ToTypeInstance();
  16957. auto fieldDef = typeType->mTypeDef->GetFieldByName("mTypeId");
  16958. if (fieldDef != NULL)
  16959. {
  16960. int typeId = ceDebugger->ReadMemory<int>((intptr)intVal + typeType->mFieldInstances[fieldDef->mIdx].mDataOffset);
  16961. type = mModule->mContext->FindTypeById(typeId);
  16962. }
  16963. }
  16964. else
  16965. typeName += StrFormat("%lld", intVal);
  16966. }
  16967. }
  16968. auto fromTypedVal = _ResolveArg(args.mSize - 1);
  16969. if (!typeName.IsEmpty())
  16970. type = ceDebugger->FindType(typeName);
  16971. if (type != NULL)
  16972. {
  16973. if (targetFunctionName == "__bitcast")
  16974. {
  16975. if ((type->IsObjectOrInterface()) || (type->IsPointer()))
  16976. {
  16977. auto ceAddrVal = ceDebugger->GetAddr(fromTypedVal);
  16978. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateIntToPtr(ceAddrVal.mAddr, mModule->mBfIRBuilder->MapType(type)), type);
  16979. }
  16980. else
  16981. {
  16982. Array<uint8> memArr;
  16983. memArr.Resize(BF_MAX(type->mSize, fromTypedVal.mType->mSize));
  16984. mModule->mBfIRBuilder->WriteConstant(fromTypedVal.mValue, memArr.mVals, fromTypedVal.mType);
  16985. auto newVal = mModule->mBfIRBuilder->ReadConstant(memArr.mVals, type);
  16986. mResult = BfTypedValue(newVal, type);
  16987. }
  16988. }
  16989. else
  16990. mResult = mModule->Cast(target, fromTypedVal, type, (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_SilentFail));
  16991. }
  16992. return;
  16993. }
  16994. else if (targetFunctionName == "__stringView")
  16995. {
  16996. auto ptrVal = _ResolveArg(0);
  16997. auto sizeVal = _ResolveArg(1);
  16998. if (ceDbgState->mFormatInfo != NULL)
  16999. ceDbgState->mFormatInfo->mOverrideCount = (int)ceDebugger->ValueToInt(sizeVal);
  17000. mResult = ptrVal;
  17001. return;
  17002. }
  17003. else if ((targetFunctionName == "__funcName") || (targetFunctionName == "__funcTarget"))
  17004. {
  17005. auto addrVal = _ResolveArg(0);
  17006. auto ceAddrVal = ceDebugger->GetAddr(addrVal);
  17007. CeFunction* ceFunction = NULL;
  17008. int functionId = 0;
  17009. if (mModule->mSystem->mPtrSize == 4)
  17010. {
  17011. functionId = (int)addrVal;
  17012. }
  17013. else
  17014. {
  17015. CeFunction* checkCeFunction = (CeFunction*)ceAddrVal.mAddr;
  17016. functionId = checkCeFunction->SafeGetId();
  17017. }
  17018. if (mModule->mCompiler->mCeMachine->mFunctionIdMap.TryGetValue(functionId, &ceFunction))
  17019. {
  17020. BfMethodInstance* methodInstance = ceFunction->mMethodInstance;
  17021. if (methodInstance != NULL)
  17022. {
  17023. if (targetFunctionName == "__funcTarget")
  17024. {
  17025. BfType* targetType = methodInstance->GetOwner();
  17026. if (targetType->IsValueType())
  17027. targetType = mModule->CreatePointerType(targetType);
  17028. auto targetVal = _ResolveArg(1);
  17029. auto ceTargetVal = ceDebugger->GetAddr(targetVal);
  17030. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateIntToPtr(ceTargetVal.mAddr, mModule->mBfIRBuilder->MapType(targetType)), targetType);
  17031. return;
  17032. }
  17033. else
  17034. {
  17035. mResult = BfTypedValue(mModule->GetStringObjectValue(mModule->MethodToString(methodInstance)),
  17036. mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
  17037. return;
  17038. }
  17039. }
  17040. else if ((ceFunction->mCeInnerFunctionInfo != NULL) && (targetFunctionName == "__funcName"))
  17041. {
  17042. mResult = BfTypedValue(mModule->GetStringObjectValue(BfDemangler::Demangle(ceFunction->mCeInnerFunctionInfo->mName, DbgLanguage_Beef)),
  17043. mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
  17044. return;
  17045. }
  17046. }
  17047. if (targetFunctionName == "__funcTarget")
  17048. mResult = _ResolveArg(1);
  17049. else
  17050. mResult = addrVal;
  17051. return;
  17052. }
  17053. }
  17054. }
  17055. }
  17056. else if (auto expr = BfNodeDynCast<BfExpression>(target))
  17057. {
  17058. auto innerInvocationResult = mModule->CreateValueFromExpression(expr);
  17059. if (!innerInvocationResult)
  17060. {
  17061. mModule->AssertErrorState();
  17062. innerInvocationResult = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  17063. }
  17064. if (innerInvocationResult.mType->IsVar())
  17065. {
  17066. mResult = innerInvocationResult;
  17067. return;
  17068. }
  17069. targetFunctionName = "Invoke";
  17070. if (innerInvocationResult.mType->IsTypeInstance())
  17071. {
  17072. auto invocationTypeInst = innerInvocationResult.mType->ToTypeInstance();
  17073. if ((invocationTypeInst->mTypeDef->mIsDelegate) || (invocationTypeInst->mTypeDef->mIsFunction))
  17074. {
  17075. thisValue = innerInvocationResult;
  17076. }
  17077. }
  17078. if (!thisValue)
  17079. {
  17080. mModule->Fail(StrFormat("Cannot perform invocation on type '%s'", mModule->TypeToString(innerInvocationResult.mType).c_str()), expr);
  17081. thisValue = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  17082. }
  17083. }
  17084. else
  17085. {
  17086. mModule->Fail("Invalid invocation target", target);
  17087. thisValue = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  17088. }
  17089. if ((wasCapturingMethodInfo) && (autoComplete->mMethodMatchInfo != NULL))
  17090. {
  17091. autoComplete->mIsCapturingMethodMatchInfo = true;
  17092. BF_ASSERT(autoComplete->mMethodMatchInfo != NULL);
  17093. }
  17094. SetAndRestoreValue<BfAttributeState*> prevAttributeState;
  17095. if (attributeState.mCustomAttributes != NULL)
  17096. prevAttributeState.Init(mModule->mAttributeState, &attributeState);
  17097. if ((targetFunctionName != "") && (targetFunctionName[targetFunctionName.length() - 1] == '!'))
  17098. {
  17099. targetFunctionName = targetFunctionName.Substring(0, targetFunctionName.length() - 1);
  17100. InjectMixin(methodNodeSrc, thisValue, allowImplicitThis, targetFunctionName, args, methodGenericArgs);
  17101. return;
  17102. }
  17103. if (targetFunctionName.StartsWith('@'))
  17104. targetFunctionName.Remove(0, 1);
  17105. //TODO: We removed this... Messed up with PrimStruct 'this' non-mut errors
  17106. // We moved this until later in MatchMethod, we want the raw target for the GetType optimization, plus we shouldn't do this until we know we won't do a SkipCall
  17107. /*if (thisValue)
  17108. {
  17109. if ((!thisValue.mType->IsGenericParam()) && (!thisValue.IsSplat()) && (!thisValue.mType->IsVar()))
  17110. thisValue = MakeCallableTarget(target, thisValue);
  17111. }*/
  17112. int methodCount = 0;
  17113. bool mayBeSkipCall = false;
  17114. bool mayBeComptimeCall = false;
  17115. BfTypeInstance* checkTypeInst = NULL;
  17116. if (thisValue.mType != NULL)
  17117. {
  17118. if (thisValue.mType->IsAllocType())
  17119. thisValue.mType = thisValue.mType->GetUnderlyingType();
  17120. checkTypeInst = thisValue.mType->ToTypeInstance();
  17121. }
  17122. else if (allowImplicitThis)
  17123. {
  17124. checkTypeInst = mModule->mCurTypeInstance;
  17125. }
  17126. while (checkTypeInst != NULL)
  17127. {
  17128. checkTypeInst->mTypeDef->PopulateMemberSets();
  17129. BfMemberSetEntry* memberSetEntry;
  17130. if (checkTypeInst->mTypeDef->mMethodSet.TryGetWith(targetFunctionName, &memberSetEntry))
  17131. {
  17132. BfMethodDef* methodDef = (BfMethodDef*)memberSetEntry->mMemberDef;
  17133. while (methodDef != NULL)
  17134. {
  17135. if (methodDef->mIsSkipCall)
  17136. mayBeSkipCall = true;
  17137. if (methodDef->mHasComptime)
  17138. mayBeComptimeCall = true;
  17139. methodDef = methodDef->mNextWithSameName;
  17140. }
  17141. }
  17142. checkTypeInst = checkTypeInst->mBaseType;
  17143. }
  17144. SizedArray<BfExpression*, 8> copiedArgs;
  17145. for (BfExpression* arg : args)
  17146. copiedArgs.push_back(arg);
  17147. BfSizedArray<BfExpression*> sizedCopiedArgs(copiedArgs);
  17148. BfResolvedArgs argValues(&sizedCopiedArgs);
  17149. if (mModule->mParentNodeEntry != NULL)
  17150. {
  17151. if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(mModule->mParentNodeEntry->mNode))
  17152. {
  17153. argValues.mOpenToken = invocationExpr->mOpenParen;
  17154. argValues.mCommas = &invocationExpr->mCommas;
  17155. argValues.mCloseToken = invocationExpr->mCloseParen;
  17156. }
  17157. }
  17158. BfResolveArgsFlags resolveArgsFlags = (BfResolveArgsFlags)(BfResolveArgsFlag_DeferFixits | BfResolveArgsFlag_AllowUnresolvedTypes);
  17159. resolveArgsFlags = (BfResolveArgsFlags)(resolveArgsFlags | BfResolveArgsFlag_DeferParamEval);
  17160. if ((mayBeSkipCall) || (mayBeComptimeCall))
  17161. resolveArgsFlags = (BfResolveArgsFlags)(resolveArgsFlags | BfResolveArgsFlag_DeferParamValues);
  17162. static int sCallIdx = 0;
  17163. sCallIdx++;
  17164. int callIdx = sCallIdx;
  17165. if (callIdx == 1557)
  17166. {
  17167. NOP;
  17168. }
  17169. BfCheckedKind checkedKind = BfCheckedKind_NotSet;
  17170. if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL))
  17171. {
  17172. if (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mCheckedAttributeTypeDef))
  17173. {
  17174. checkedKind = BfCheckedKind_Checked;
  17175. mModule->mAttributeState->mUsed = true;
  17176. }
  17177. if (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mUncheckedAttributeTypeDef))
  17178. {
  17179. checkedKind = BfCheckedKind_Unchecked;
  17180. mModule->mAttributeState->mUsed = true;
  17181. }
  17182. if (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mNoStaticCtorAttributeTypeDef))
  17183. {
  17184. mModule->mAttributeState->mUsed = true;
  17185. }
  17186. }
  17187. if ((isCascade) && (cascadeOperatorToken != NULL) && ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0))
  17188. mModule->Fail("Cascade operator cannot be used in const evaluation", cascadeOperatorToken);
  17189. SetAndRestoreValue<bool> prevUsedAsStatement(mUsedAsStatement, mUsedAsStatement || isCascade);
  17190. SetAndRestoreValue<BfEvalExprFlags> prevEvalExprFlags(mBfEvalExprFlags);
  17191. if (isCascade)
  17192. {
  17193. mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_InCascade);
  17194. thisValue = mModule->MakeAddressable(thisValue);
  17195. }
  17196. if (((mayBeComptimeCall) && (!mModule->mIsComptimeModule) && (!mModule->mBfIRBuilder->mIgnoreWrites)) ||
  17197. ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) && (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mConstEvalAttributeTypeDef))))
  17198. {
  17199. resolveArgsFlags = (BfResolveArgsFlags)(resolveArgsFlags | BfResolveArgsFlag_DeferParamEval | BfResolveArgsFlag_DeferStrings);
  17200. }
  17201. ResolveArgValues(argValues, resolveArgsFlags);
  17202. //
  17203. {
  17204. // We also apply this right before the actual call, but we need to set the comptime flag earlier
  17205. SetAndRestoreValue<BfEvalExprFlags> prevEvalExprFlag(mBfEvalExprFlags);
  17206. if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) && (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mConstEvalAttributeTypeDef)))
  17207. {
  17208. mModule->mAttributeState->mUsed = true;
  17209. mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_Comptime);
  17210. }
  17211. mResult = MatchMethod(methodNodeSrc, methodBoundExpr, thisValue, allowImplicitThis, bypassVirtual, targetFunctionName, argValues, methodGenericArgs, checkedKind);
  17212. }
  17213. argValues.HandleFixits(mModule);
  17214. if (mModule->mAttributeState == &attributeState)
  17215. mModule->FinishAttributeState(&attributeState);
  17216. if (isCascade)
  17217. {
  17218. if ((outCascadeValue != NULL) && (thisValue.mValue))
  17219. {
  17220. *outCascadeValue = thisValue;
  17221. }
  17222. else
  17223. {
  17224. mModule->Fail("Invalid use of cascade operator", cascadeOperatorToken);
  17225. }
  17226. }
  17227. }
  17228. void BfExprEvaluator::Visit(BfInvocationExpression* invocationExpr)
  17229. {
  17230. DoInvocation(invocationExpr);
  17231. }
  17232. void BfExprEvaluator::DoInvocation(BfInvocationExpression* invocationExpr)
  17233. {
  17234. BfAutoParentNodeEntry autoParentNodeEntry(mModule, invocationExpr);
  17235. // We need to check for sized array constructor like "uint8[2](1, 2)"
  17236. if (BfNodeDynCastExact<BfIndexerExpression>(invocationExpr->mTarget) != NULL)
  17237. {
  17238. auto checkTarget = invocationExpr->mTarget;
  17239. while (auto indexerExpr = BfNodeDynCastExact<BfIndexerExpression>(checkTarget))
  17240. {
  17241. checkTarget = indexerExpr->mTarget;
  17242. }
  17243. auto resolvedType = mModule->ResolveTypeRef(checkTarget, NULL, BfPopulateType_Identity, BfResolveTypeRefFlag_IgnoreLookupError);
  17244. if (resolvedType != NULL)
  17245. {
  17246. BfType* curType = resolvedType;
  17247. auto checkTarget = invocationExpr->mTarget;
  17248. while (auto indexerExpr = BfNodeDynCastExact<BfIndexerExpression>(checkTarget))
  17249. {
  17250. checkTarget = indexerExpr->mTarget;
  17251. if (indexerExpr->mCommas.size() != 0)
  17252. mModule->Fail("Only one value expected. Consider adding an allocation specifier such as 'new' if construction of a dynamic multidimensional was intended.", indexerExpr->mCommas[0]);
  17253. int arrSize = 0;
  17254. BfTypeState typeState;
  17255. typeState.mArrayInitializerSize = (int)invocationExpr->mArguments.size();
  17256. SetAndRestoreValue<BfTypeState*> prevTypeState(mModule->mContext->mCurTypeState, &typeState);
  17257. BfType* undefSizeParam = NULL;
  17258. if (indexerExpr->mArguments.size() != 0)
  17259. {
  17260. BfConstResolver constResolver(mModule);
  17261. auto arg = indexerExpr->mArguments[0];
  17262. constResolver.mExpectingType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  17263. constResolver.mBfEvalExprFlags = (BfEvalExprFlags)(constResolver.mBfEvalExprFlags | BfEvalExprFlags_AllowGenericConstValue);
  17264. if (arg != NULL)
  17265. constResolver.Resolve(arg, NULL, BfConstResolveFlag_ArrayInitSize);
  17266. if (constResolver.mResult.mKind == BfTypedValueKind_GenericConstValue)
  17267. {
  17268. undefSizeParam = constResolver.mResult.mType;
  17269. }
  17270. else if (constResolver.mResult.mValue.IsConst())
  17271. {
  17272. auto constant = mModule->mBfIRBuilder->GetConstant(constResolver.mResult.mValue);
  17273. if ((mModule->mBfIRBuilder->IsInt(constant->mTypeCode)) && (constant->mInt64 >= 0))
  17274. {
  17275. arrSize = constant->mInt32;
  17276. }
  17277. else if (constant->mConstType != BfConstType_Undef)
  17278. mModule->Fail("Non-negative integer expected", indexerExpr->mArguments[0]);
  17279. }
  17280. }
  17281. else
  17282. arrSize = invocationExpr->mArguments.size();
  17283. if (undefSizeParam != NULL)
  17284. curType = mModule->CreateUnknownSizedArrayType(curType, undefSizeParam);
  17285. else
  17286. curType = mModule->CreateSizedArrayType(curType, arrSize);
  17287. }
  17288. InitializedSizedArray((BfSizedArrayType*)curType, invocationExpr->mOpenParen, invocationExpr->mArguments, invocationExpr->mCommas, invocationExpr->mCloseParen, NULL);
  17289. return;
  17290. }
  17291. }
  17292. auto autoComplete = GetAutoComplete();
  17293. auto wasCapturingMethodInfo = (autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo);
  17294. if (autoComplete != NULL)
  17295. autoComplete->CheckInvocation(invocationExpr, invocationExpr->mOpenParen, invocationExpr->mCloseParen, invocationExpr->mCommas);
  17296. mModule->UpdateExprSrcPos(invocationExpr);
  17297. BfMethodGenericArguments methodGenericArgs;
  17298. if (invocationExpr->mGenericArgs != NULL)
  17299. {
  17300. methodGenericArgs.mArguments = &invocationExpr->mGenericArgs->mGenericArgs;
  17301. if ((!invocationExpr->mGenericArgs->mCommas.IsEmpty()) && (invocationExpr->mGenericArgs->mCommas.back()->mToken == BfToken_DotDotDot))
  17302. {
  17303. methodGenericArgs.mIsOpen = true;
  17304. methodGenericArgs.mIsPartial = true;
  17305. }
  17306. for (int i = 0; i < (int)methodGenericArgs.mArguments->mSize; i++)
  17307. if (BfNodeIsA<BfUninitializedExpression>((*methodGenericArgs.mArguments)[i]))
  17308. methodGenericArgs.mIsPartial = true;
  17309. }
  17310. SizedArray<BfExpression*, 8> copiedArgs;
  17311. for (BfExpression* arg : invocationExpr->mArguments)
  17312. copiedArgs.push_back(arg);
  17313. BfTypedValue cascadeValue;
  17314. DoInvocation(invocationExpr->mTarget, invocationExpr, copiedArgs, methodGenericArgs, &cascadeValue);
  17315. if (autoComplete != NULL)
  17316. {
  17317. if ((wasCapturingMethodInfo) && (!autoComplete->mIsCapturingMethodMatchInfo))
  17318. {
  17319. if (autoComplete->mMethodMatchInfo != NULL)
  17320. autoComplete->mIsCapturingMethodMatchInfo = true;
  17321. else
  17322. autoComplete->mIsCapturingMethodMatchInfo = false;
  17323. //BF_ASSERT(autoComplete->mMethodMatchInfo != NULL);
  17324. }
  17325. else
  17326. autoComplete->mIsCapturingMethodMatchInfo = false;
  17327. }
  17328. /// Previous check for discard
  17329. if (cascadeValue)
  17330. mResult = cascadeValue;
  17331. }
  17332. BfMethodDef* BfExprEvaluator::GetPropertyMethodDef(BfPropertyDef* propDef, BfMethodType methodType, BfCheckedKind checkedKind, BfTypedValue propTarget)
  17333. {
  17334. bool allowMut = true;
  17335. if ((propTarget) && (propTarget.mType->IsValueType()))
  17336. {
  17337. if (propTarget.IsReadOnly())
  17338. {
  17339. allowMut = false;
  17340. }
  17341. else if (!propTarget.IsAddr())
  17342. {
  17343. mModule->PopulateType(propTarget.mType);
  17344. if (!propTarget.IsValuelessType())
  17345. allowMut = false;
  17346. }
  17347. }
  17348. int bestPri = -1000;
  17349. BfMethodDef* matchedMethod = NULL;
  17350. for (auto methodDef : propDef->mMethods)
  17351. {
  17352. if (methodDef->mMethodType != methodType)
  17353. continue;
  17354. int curPri = 0;
  17355. if (methodDef->mCheckedKind == checkedKind)
  17356. {
  17357. curPri = 5;
  17358. }
  17359. else if ((checkedKind == BfCheckedKind_NotSet) && (methodDef->mCheckedKind == mModule->GetDefaultCheckedKind()))
  17360. curPri = 3;
  17361. else
  17362. curPri = 1;
  17363. if (methodDef->mIsMutating)
  17364. {
  17365. if (allowMut)
  17366. curPri++;
  17367. else
  17368. curPri -= 10;
  17369. }
  17370. if (curPri > bestPri)
  17371. {
  17372. bestPri = curPri;
  17373. matchedMethod = methodDef;
  17374. }
  17375. }
  17376. return matchedMethod;
  17377. /*BfMethodDef* matchedMethod = NULL;
  17378. BfMethodDef* backupMethod = NULL;
  17379. for (auto methodDef : propDef->mMethods)
  17380. {
  17381. if (methodDef->mMethodType != methodType)
  17382. continue;
  17383. if (methodDef->mCheckedKind == checkedKind)
  17384. {
  17385. matchedMethod = methodDef;
  17386. break;
  17387. }
  17388. if ((checkedKind == BfCheckedKind_NotSet) && (methodDef->mCheckedKind == mModule->GetDefaultCheckedKind()))
  17389. matchedMethod = methodDef;
  17390. else
  17391. backupMethod = methodDef;
  17392. }
  17393. if (matchedMethod == NULL)
  17394. matchedMethod = backupMethod;
  17395. return matchedMethod;*/
  17396. }
  17397. BfModuleMethodInstance BfExprEvaluator::GetPropertyMethodInstance(BfMethodDef* methodDef)
  17398. {
  17399. if (mPropDefBypassVirtual)
  17400. {
  17401. if (mPropTarget.mType->IsInterface())
  17402. {
  17403. auto curTypeInst = mPropTarget.mType->ToTypeInstance();
  17404. if (mModule->TypeIsSubTypeOf(mModule->mCurTypeInstance, curTypeInst))
  17405. {
  17406. if (methodDef->mBody != NULL)
  17407. {
  17408. // This is an explicit call to a default static interface method. We pull the methodDef into our own concrete type.
  17409. mPropTarget = mModule->GetThis();
  17410. return mModule->GetMethodInstance(mModule->mCurTypeInstance, methodDef, BfTypeVector(), BfGetMethodInstanceFlag_ForeignMethodDef, curTypeInst);
  17411. }
  17412. }
  17413. else
  17414. {
  17415. mModule->Fail("Property is not implemented by this type", mPropSrc);
  17416. return BfModuleMethodInstance();
  17417. }
  17418. }
  17419. else
  17420. {
  17421. auto propTypeInst = mPropTarget.mType->ToTypeInstance();
  17422. mModule->PopulateType(propTypeInst, BfPopulateType_DataAndMethods);
  17423. auto rawMethodInstance = mModule->GetRawMethodInstance(propTypeInst, methodDef);
  17424. if (rawMethodInstance->mVirtualTableIdx == -1)
  17425. {
  17426. if (!mModule->mCompiler->mIsResolveOnly)
  17427. {
  17428. // ResolveOnly does not force methods to slot
  17429. BF_ASSERT(rawMethodInstance->mVirtualTableIdx != -1);
  17430. mModule->Fail(StrFormat("Failed to devirtualize %s", mModule->MethodToString(rawMethodInstance).c_str()));
  17431. }
  17432. }
  17433. else
  17434. {
  17435. auto useTypeInst = mOrigPropTarget.mType->ToTypeInstance();
  17436. auto virtualMethod = (BfMethodInstance*)useTypeInst->mVirtualMethodTable[rawMethodInstance->mVirtualTableIdx].mImplementingMethod;
  17437. return mModule->ReferenceExternalMethodInstance(virtualMethod);
  17438. }
  17439. }
  17440. }
  17441. if ((mOrigPropTarget) && (mOrigPropTarget.mType != mPropTarget.mType) &&
  17442. ((!mOrigPropTarget.mType->IsGenericParam()) && (mPropTarget.mType->IsInterface())))
  17443. {
  17444. auto checkType = mOrigPropTarget.mType;
  17445. if ((checkType->IsNullable()) && (!mPropTarget.mType->IsNullable()))
  17446. checkType = checkType->GetUnderlyingType();
  17447. if (checkType->IsPointer())
  17448. checkType = ((BfPointerType*)checkType)->mElementType;
  17449. if (checkType->IsWrappableType())
  17450. checkType = mModule->GetWrappedStructType(checkType);
  17451. if ((checkType != NULL) && (checkType->IsTypeInstance()))
  17452. {
  17453. auto activeTypeDef = mModule->GetActiveTypeDef(NULL, false, true);
  17454. BfTypeInterfaceEntry* bestIFaceEntry = NULL;
  17455. bool checkedUnderlying = false;
  17456. auto checkTypeInst = checkType->ToTypeInstance();
  17457. while (checkTypeInst != NULL)
  17458. {
  17459. mModule->PopulateType(checkTypeInst, BfPopulateType_DataAndMethods);
  17460. BF_ASSERT((checkTypeInst->mDefineState >= BfTypeDefineState_DefinedAndMethodsSlotted) || (mModule->mCompiler->IsAutocomplete()));
  17461. if (checkTypeInst->mDefineState != BfTypeDefineState_DefinedAndMethodsSlotted)
  17462. break;
  17463. for (auto& iface : checkTypeInst->mInterfaces)
  17464. {
  17465. if (!mModule->IsInSpecializedSection())
  17466. {
  17467. if (!checkTypeInst->IsTypeMemberAccessible(iface.mDeclaringType, activeTypeDef))
  17468. continue;
  17469. }
  17470. if (iface.mInterfaceType == mPropTarget.mType)
  17471. {
  17472. if (bestIFaceEntry == NULL)
  17473. {
  17474. bestIFaceEntry = &iface;
  17475. continue;
  17476. }
  17477. bool isBetter;
  17478. bool isWorse;
  17479. mModule->CompareDeclTypes(NULL, iface.mDeclaringType, bestIFaceEntry->mDeclaringType, isBetter, isWorse);
  17480. if (isBetter == isWorse)
  17481. {
  17482. // Failed
  17483. }
  17484. else
  17485. {
  17486. if (isBetter)
  17487. bestIFaceEntry = &iface;
  17488. }
  17489. }
  17490. }
  17491. if (bestIFaceEntry != NULL)
  17492. break;
  17493. checkTypeInst = checkTypeInst->mBaseType;
  17494. if (checkTypeInst == NULL)
  17495. {
  17496. if (!checkedUnderlying)
  17497. {
  17498. checkedUnderlying = true;
  17499. if (checkType->HasWrappedRepresentation())
  17500. {
  17501. auto underlyingType = checkType->GetUnderlyingType();
  17502. if (underlyingType != NULL)
  17503. checkTypeInst = mModule->GetWrappedStructType(underlyingType);
  17504. }
  17505. }
  17506. }
  17507. }
  17508. if (bestIFaceEntry != NULL)
  17509. {
  17510. if ((checkTypeInst->IsInterface()))
  17511. {
  17512. auto propTypeInst = bestIFaceEntry->mInterfaceType->ToTypeInstance();
  17513. if (propTypeInst == NULL)
  17514. {
  17515. mModule->Fail("INTERNAL ERROR: Invalid property target", mPropSrc);
  17516. return BfModuleMethodInstance();
  17517. }
  17518. BF_ASSERT(propTypeInst->mTypeDef->mFullNameEx == methodDef->mDeclaringType->mFullNameEx);
  17519. return mModule->GetMethodInstance(propTypeInst, methodDef, BfTypeVector(), mPropGetMethodFlags);
  17520. }
  17521. auto ifaceMethodEntry = checkTypeInst->mInterfaceMethodTable[bestIFaceEntry->mStartInterfaceTableIdx + methodDef->mIdx];
  17522. BfMethodInstance* bestMethodInstance = ifaceMethodEntry.mMethodRef;
  17523. if (bestMethodInstance != NULL)
  17524. {
  17525. mPropTarget = mOrigPropTarget;
  17526. //mPropTarget.mType = checkTypeInst;
  17527. //mPropTarget = mModule->Cast( mOrigPropTarget, checkTypeInst);
  17528. return mModule->GetMethodInstanceAtIdx(ifaceMethodEntry.mMethodRef.mTypeInstance, ifaceMethodEntry.mMethodRef.mMethodNum);
  17529. }
  17530. }
  17531. }
  17532. mModule->AssertErrorState();
  17533. return BfModuleMethodInstance();
  17534. }
  17535. auto propTypeInst = mPropTarget.mType->ToTypeInstance();
  17536. if (propTypeInst == NULL)
  17537. {
  17538. propTypeInst = mModule->GetWrappedStructType(mPropTarget.mType);
  17539. }
  17540. if (propTypeInst == NULL)
  17541. {
  17542. mModule->Fail("INTERNAL ERROR: Invalid property target", mPropSrc);
  17543. return BfModuleMethodInstance();
  17544. }
  17545. BF_ASSERT(propTypeInst->mTypeDef->mFullNameEx == methodDef->mDeclaringType->mFullNameEx);
  17546. return mModule->GetMethodInstance(propTypeInst, methodDef, BfTypeVector(), mPropGetMethodFlags);
  17547. }
  17548. void BfExprEvaluator::CheckPropFail(BfMethodDef* propMethodDef, BfMethodInstance* methodInstance, bool checkProt)
  17549. {
  17550. auto propTypeInst = mPropTarget.mType->ToTypeInstance();
  17551. // If mExplicitInterface is null then we are implicitly calling through an interface
  17552. if ((checkProt) && (propTypeInst != NULL) && (methodInstance->GetExplicitInterface() == NULL) &&
  17553. (!mModule->CheckAccessMemberProtection(propMethodDef->mProtection, propTypeInst)))
  17554. mModule->Fail(StrFormat("'%s' is inaccessible due to its protection level", mModule->MethodToString(methodInstance).c_str()), mPropSrc);
  17555. else if (mPropCheckedKind != methodInstance->mMethodDef->mCheckedKind)
  17556. {
  17557. bool passes = true;
  17558. if (mPropCheckedKind != BfCheckedKind_NotSet)
  17559. {
  17560. passes = false;
  17561. }
  17562. else
  17563. {
  17564. auto defaultCheckedKind = mModule->GetDefaultCheckedKind();
  17565. if (defaultCheckedKind != methodInstance->mMethodDef->mCheckedKind)
  17566. passes = false;
  17567. }
  17568. if (!passes)
  17569. {
  17570. auto error = mModule->Fail(StrFormat("'%s' cannot be used because its 'checked' specifier does not match the requested specifier", mModule->MethodToString(methodInstance).c_str()), mPropSrc);
  17571. if (error != NULL)
  17572. {
  17573. if ((error != NULL) && (methodInstance->mMethodDef->mMethodDeclaration != NULL))
  17574. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
  17575. }
  17576. }
  17577. }
  17578. }
  17579. bool BfExprEvaluator::HasResult()
  17580. {
  17581. return (mResult) || (mPropDef != NULL);
  17582. }
  17583. BfTypedValue BfExprEvaluator::GetResult(bool clearResult, bool resolveGenericType)
  17584. {
  17585. if ((!mResult) && (mPropDef != NULL))
  17586. {
  17587. bool handled = false;
  17588. if (mPropTarget.mType->IsGenericTypeInstance())
  17589. {
  17590. auto genericTypeInst = (BfTypeInstance*)mPropTarget.mType;
  17591. if (genericTypeInst->IsInstanceOf(mModule->mCompiler->mSizedArrayTypeDef))
  17592. {
  17593. if (mPropDef->mName == "Count")
  17594. {
  17595. auto sizedType = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[1];
  17596. if (sizedType->IsConstExprValue())
  17597. {
  17598. auto constExprType = (BfConstExprValueType*)sizedType;
  17599. mResult = BfTypedValue(mModule->GetConstValue(constExprType->mValue.mInt64), mModule->GetPrimitiveType(BfTypeCode_IntPtr));
  17600. handled = true;
  17601. }
  17602. else
  17603. {
  17604. BF_ASSERT(mModule->mCurMethodInstance->mIsUnspecialized);
  17605. mResult = BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->GetPrimitiveType(BfTypeCode_IntPtr)), mModule->GetPrimitiveType(BfTypeCode_IntPtr));
  17606. handled = true;
  17607. }
  17608. }
  17609. }
  17610. }
  17611. if (!handled)
  17612. {
  17613. SetAndRestoreValue<BfFunctionBindResult*> prevFunctionBindResult(mFunctionBindResult, NULL);
  17614. SetAndRestoreValue<BfDeferCallData*> prevDeferCallRef(mDeferCallData, NULL);
  17615. BfMethodDef* matchedMethod = GetPropertyMethodDef(mPropDef, BfMethodType_PropertyGetter, mPropCheckedKind, mPropTarget);
  17616. if (matchedMethod == NULL)
  17617. {
  17618. mModule->Fail("Property has no getter", mPropSrc);
  17619. return mResult;
  17620. }
  17621. auto methodInstance = GetPropertyMethodInstance(matchedMethod);
  17622. if (methodInstance.mMethodInstance == NULL)
  17623. return mResult;
  17624. BF_ASSERT(methodInstance.mMethodInstance->mMethodDef->mName == matchedMethod->mName);
  17625. if (!mModule->mBfIRBuilder->mIgnoreWrites)
  17626. {
  17627. BF_ASSERT(!methodInstance.mFunc.IsFake());
  17628. }
  17629. if (mPropSrc != NULL)
  17630. mModule->UpdateExprSrcPos(mPropSrc);
  17631. auto autoComplete = GetAutoComplete();
  17632. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(mPropSrc)) && (autoComplete->mResolveType == BfResolveType_GetResultString))
  17633. {
  17634. autoComplete->mResultString = ":";
  17635. autoComplete->mResultString += mModule->TypeToString(methodInstance.mMethodInstance->mReturnType);
  17636. autoComplete->mResultString += " ";
  17637. autoComplete->mResultString += mModule->TypeToString(methodInstance.mMethodInstance->GetOwner());
  17638. autoComplete->mResultString += ".";
  17639. autoComplete->mResultString += mPropDef->mName;
  17640. }
  17641. CheckPropFail(matchedMethod, methodInstance.mMethodInstance, (mPropGetMethodFlags & BfGetMethodInstanceFlag_Friend) == 0);
  17642. PerformCallChecks(methodInstance.mMethodInstance, mPropSrc);
  17643. if (methodInstance.mMethodInstance->IsSkipCall())
  17644. {
  17645. mResult = mModule->GetDefaultTypedValue(methodInstance.mMethodInstance->mReturnType);
  17646. }
  17647. else
  17648. {
  17649. SizedArray<BfIRValue, 4> args;
  17650. if (!matchedMethod->mIsStatic)
  17651. {
  17652. auto owner = methodInstance.mMethodInstance->GetOwner();
  17653. bool isTypeMatch = mPropTarget.mType == owner;
  17654. if (owner->IsTypedPrimitive())
  17655. isTypeMatch |= mPropTarget.mType == owner->GetUnderlyingType();
  17656. if ((!isTypeMatch) ||
  17657. ((mPropTarget.mValue.IsFake()) && (!mOrigPropTarget.mValue.IsFake())))
  17658. {
  17659. auto prevPropTarget = mPropTarget;
  17660. mPropTarget = mModule->Cast(mPropSrc, mOrigPropTarget, owner);
  17661. if (!mPropTarget)
  17662. {
  17663. mModule->Fail("Internal property error", mPropSrc);
  17664. return BfTypedValue();
  17665. }
  17666. }
  17667. if ((mPropGetMethodFlags & BfGetMethodInstanceFlag_DisableObjectAccessChecks) == 0)
  17668. mModule->EmitObjectAccessCheck(mPropTarget);
  17669. }
  17670. SetAndRestoreValue<BfEvalExprFlags> prevExprFlags(mBfEvalExprFlags);
  17671. auto callFlags = mPropDefBypassVirtual ? BfCreateCallFlags_BypassVirtual : BfCreateCallFlags_None;
  17672. auto methodDef = methodInstance.mMethodInstance->mMethodDef;
  17673. if ((methodDef->mMethodDeclaration == NULL) && (mModule->mBfIRBuilder->IsConstValue(mPropTarget.mValue)) &&
  17674. (methodDef->mName == "get__Underlying"))
  17675. {
  17676. mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_Comptime);
  17677. }
  17678. mResult = CreateCall(mPropSrc, mPropTarget, mOrigPropTarget, matchedMethod, methodInstance, callFlags, mIndexerValues, NULL);
  17679. }
  17680. }
  17681. mPropDef = NULL;
  17682. mPropDefBypassVirtual = false;
  17683. mIndexerValues.clear();
  17684. mResultLocalVar = NULL;
  17685. mResultFieldInstance = NULL;
  17686. }
  17687. if (resolveGenericType)
  17688. ResolveGenericType();
  17689. BfTypedValue result = mResult;
  17690. if (clearResult)
  17691. mResult = BfTypedValue();
  17692. return result;
  17693. }
  17694. void BfExprEvaluator::CheckResultForReading(BfTypedValue& typedValue)
  17695. {
  17696. if (mModule->mCurMethodState == NULL)
  17697. return;
  17698. if ((mModule->mCurMethodState->mTempKind != BfMethodState::TempKind_None) || (mModule->mCurMethodState->mAllowUinitReads))
  17699. return;
  17700. if ((mModule->mCurTypeInstance->mResolvingVarField) || (mModule->mCurTypeInstance->mResolvingConstField))
  17701. return;
  17702. if ((typedValue) && (typedValue.IsAddr()))
  17703. {
  17704. if ((mResultLocalVar != NULL) && (mResultLocalVarRefNode != NULL))
  17705. {
  17706. SetAndRestoreValue<bool> prevIgnoreError(mModule->mIgnoreErrors);
  17707. if ((mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mCapturing))
  17708. {
  17709. // These errors can only be detected during capture time, so we don't ignore them on this pass
  17710. mModule->mIgnoreErrors = false;
  17711. }
  17712. int fieldIdx = mResultLocalVarField - 1;
  17713. auto localVar = mResultLocalVar;
  17714. /*if (localVar->mCompositeCount > 0)
  17715. {
  17716. mModule->Fail(StrFormat("Cannot read from composite '%s', it can only be used in an argument list", localVar->mName.c_str()), mResultLocalVarRefNode);
  17717. typedValue = BfTypedValue();
  17718. return;
  17719. }*/
  17720. if (localVar->mAssignedKind == BfLocalVarAssignKind_None)
  17721. {
  17722. mModule->TryLocalVariableInit(localVar);
  17723. }
  17724. if (localVar->mAssignedKind == BfLocalVarAssignKind_None)
  17725. {
  17726. auto methodStateForLocal = mModule->mCurMethodState->GetMethodStateForLocal(localVar);
  17727. bool isAssigned = false;
  17728. int64 undefinedFieldFlags = localVar->mUnassignedFieldFlags;
  17729. auto deferredLocalAssignData = methodStateForLocal->mDeferredLocalAssignData;
  17730. while ((deferredLocalAssignData != NULL) && (deferredLocalAssignData->mIsChained))
  17731. deferredLocalAssignData = deferredLocalAssignData->mChainedAssignData;
  17732. if (deferredLocalAssignData != NULL)
  17733. {
  17734. for (auto& assignedVar : deferredLocalAssignData->mAssignedLocals)
  17735. {
  17736. auto assignedLocal = assignedVar.mLocalVar;
  17737. if (assignedLocal == localVar)
  17738. {
  17739. int assignedFieldIdx = assignedVar.mLocalVarField;
  17740. if (assignedFieldIdx >= 0)
  17741. undefinedFieldFlags &= ~((int64)1 << assignedFieldIdx);
  17742. else
  17743. undefinedFieldFlags = 0;
  17744. }
  17745. }
  17746. if (deferredLocalAssignData->mLeftBlockUncond)
  17747. isAssigned = true;
  17748. }
  17749. if (fieldIdx == -1)
  17750. {
  17751. if (undefinedFieldFlags == 0)
  17752. isAssigned = true;
  17753. }
  17754. else
  17755. {
  17756. isAssigned = true;
  17757. for (int i = 0; i < mResultLocalVarFieldCount; i++)
  17758. if ((undefinedFieldFlags & (1LL << (fieldIdx + i))) != 0)
  17759. isAssigned = false;
  17760. }
  17761. if (!isAssigned)
  17762. {
  17763. if ((localVar->mIsThis) && (fieldIdx != -1))
  17764. {
  17765. // When we have initializers for fields, they won't all be processed in the autocomplte case
  17766. if (!mModule->mCompiler->IsAutocomplete())
  17767. {
  17768. auto bfError = mModule->Fail(StrFormat("Use of possibly unassigned field '%s'", mResultLocalVarRefNode->ToString().c_str()), mResultLocalVarRefNode, true);
  17769. }
  17770. }
  17771. else
  17772. {
  17773. mModule->Fail(StrFormat("Use of unassigned local variable '%s'", localVar->mName.c_str()), mResultLocalVarRefNode);
  17774. }
  17775. }
  17776. }
  17777. localVar->mReadFromId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++;
  17778. }
  17779. }
  17780. }
  17781. void BfExprEvaluator::FinishExpressionResult()
  17782. {
  17783. CheckResultForReading(mResult);
  17784. mResultLocalVar = NULL;
  17785. mResultFieldInstance = NULL;
  17786. }
  17787. bool BfExprEvaluator::CheckAllowValue(const BfTypedValue& typedValue, BfAstNode* refNode)
  17788. {
  17789. return true;
  17790. }
  17791. void BfExprEvaluator::MarkResultUsed()
  17792. {
  17793. if (mResultLocalVar != NULL)
  17794. {
  17795. mResultLocalVar->mReadFromId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++;
  17796. }
  17797. }
  17798. void BfExprEvaluator::MarkResultAssigned()
  17799. {
  17800. if (mResultLocalVar != NULL)
  17801. {
  17802. //int localIdx = mResultLocalVarIdx;
  17803. //if (localIdx == 0x7FFF)
  17804. //return;
  17805. auto localVar = mResultLocalVar;
  17806. int fieldIdx = mResultLocalVarField - 1;
  17807. int count = mResultLocalVarFieldCount;
  17808. if (fieldIdx == -1)
  17809. count = 1;
  17810. for (int i = 0; i < count; i++)
  17811. mModule->mCurMethodState->GetMethodStateForLocal(localVar)->LocalDefined(localVar, fieldIdx + i);
  17812. //if (localIdx != 0x7FFF)
  17813. {
  17814. if (localVar->mCompositeCount > 0)
  17815. {
  17816. mModule->Fail(StrFormat("Cannot write to composite '%s', it can only be used in an argument list", localVar->mName.c_str()), mResultLocalVarRefNode);
  17817. }
  17818. }
  17819. }
  17820. }
  17821. void BfExprEvaluator::MakeResultAsValue()
  17822. {
  17823. // Expressions like parens will turn a variable reference into a simple value
  17824. mResultLocalVar = NULL;
  17825. mResultFieldInstance = NULL;
  17826. }
  17827. bool BfExprEvaluator::CheckIsBase(BfAstNode* checkNode)
  17828. {
  17829. if (checkNode == NULL)
  17830. return false;
  17831. if (!checkNode->Equals("base"))
  17832. return false;
  17833. auto autoComplete = GetAutoComplete();
  17834. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(checkNode)))
  17835. {
  17836. if ((mModule->mCurTypeInstance != NULL) && (mModule->mCurTypeInstance->mBaseType != NULL))
  17837. autoComplete->SetDefinitionLocation(mModule->mCurTypeInstance->mBaseType->mTypeDef->GetRefNode());
  17838. }
  17839. return true;
  17840. }
  17841. bool BfExprEvaluator::CheckModifyResult(BfTypedValue& typedVal, BfAstNode* refNode, const char* modifyType, bool onlyNeedsMut, bool emitWarning, bool skipCopyOnMutate)
  17842. {
  17843. if (typedVal.mType->IsVar())
  17844. {
  17845. // Allow without error
  17846. return true;
  17847. }
  17848. BfLocalVariable* localVar = NULL;
  17849. bool isCapturedLocal = false;
  17850. if (mResultLocalVar != NULL)
  17851. {
  17852. localVar = mResultLocalVar;
  17853. localVar->mWrittenToId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++;
  17854. }
  17855. else if (typedVal.IsThis())
  17856. {
  17857. localVar = mModule->GetThisVariable();
  17858. }
  17859. else if (typedVal.IsSplat())
  17860. {
  17861. for (auto checkLocal : mModule->mCurMethodState->mLocals)
  17862. {
  17863. if (checkLocal->mAddr == typedVal.mValue)
  17864. {
  17865. localVar = checkLocal;
  17866. break;
  17867. }
  17868. }
  17869. }
  17870. else if (typedVal.mValue.IsArg())
  17871. {
  17872. auto methodState = mModule->mCurMethodState->GetNonCaptureState();
  17873. if (typedVal.mValue.mId < methodState->mLocals.mSize)
  17874. localVar = methodState->mLocals[typedVal.mValue.mId];
  17875. }
  17876. if ((typedVal.mKind == BfTypedValueKind_MutableValue) && (onlyNeedsMut))
  17877. {
  17878. return true;
  17879. }
  17880. bool canModify = typedVal.CanModify();
  17881. if (((typedVal.mKind == BfTypedValueKind_TempAddr) || (typedVal.mKind == BfTypedValueKind_CopyOnMutateAddr_Derived)) &&
  17882. (strcmp(modifyType, "assign to") == 0))
  17883. mModule->Warn(0, "Assigning to temporary copy of a value. Consider using 'ref' in value source declaration.", refNode);
  17884. auto _Fail = [&](const StringImpl& error, BfAstNode* refNode)
  17885. {
  17886. if (emitWarning)
  17887. return mModule->Warn(BfWarning_BF4204_AddressOfReadOnly, error, refNode);
  17888. else
  17889. return mModule->Fail(error, refNode);
  17890. };
  17891. if (localVar != NULL)
  17892. {
  17893. if (!canModify)
  17894. {
  17895. BfError* error = NULL;
  17896. if (localVar->mIsThis)
  17897. {
  17898. bool isClosure = false;
  17899. BfTypeInstance* checkTypeInst = localVar->mResolvedType->ToTypeInstance();
  17900. int fieldIdx = mResultLocalVarField - 1;
  17901. if ((!isCapturedLocal) && (mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mClosureType != NULL))
  17902. {
  17903. isClosure = true;
  17904. auto closureThis = mModule->mCurMethodState->mClosureState->mClosureType;
  17905. closureThis = checkTypeInst->mFieldInstances[0].mResolvedType->ToTypeInstance();
  17906. if (fieldIdx >= -1)
  17907. {
  17908. checkTypeInst = closureThis;
  17909. }
  17910. else
  17911. {
  17912. fieldIdx = -fieldIdx - 2;
  17913. isCapturedLocal = true;
  17914. }
  17915. }
  17916. if (fieldIdx < 0)
  17917. {
  17918. if (isClosure)
  17919. {
  17920. if (!mModule->mCurMethodState->mClosureState->mDeclaringMethodIsMutating)
  17921. error = _Fail(StrFormat("Cannot %s 'this' within struct lambda. Consider adding 'mut' specifier to this method.", modifyType), refNode);
  17922. else
  17923. error = _Fail(StrFormat("Cannot %s 'this' within struct lambda. Consider adding by-reference capture specifier [&] to lambda.", modifyType), refNode);
  17924. }
  17925. else if (localVar->mResolvedType->IsValueType())
  17926. {
  17927. error = _Fail(StrFormat("Cannot %s 'this' within struct method '%s'. Consider adding 'mut' specifier to this method.", modifyType,
  17928. mModule->MethodToString(mModule->mCurMethodInstance).c_str()), refNode);
  17929. }
  17930. else
  17931. {
  17932. error = _Fail(StrFormat("Cannot %s 'this' because '%s' is a reference type.", modifyType,
  17933. mModule->TypeToString(localVar->mResolvedType).c_str()), refNode);
  17934. }
  17935. return false;
  17936. }
  17937. else if (mResultFieldInstance != NULL)
  17938. {
  17939. if (isCapturedLocal)
  17940. {
  17941. error = _Fail(StrFormat("Cannot %s read-only captured local variable '%s'. Consider adding by-reference capture specifier [&] to lambda and ensuring that captured value is not read-only.", modifyType,
  17942. mResultFieldInstance->GetFieldDef()->mName.c_str()), refNode);
  17943. }
  17944. else if (isClosure)
  17945. {
  17946. if (!mModule->mCurMethodState->mClosureState->mDeclaringMethodIsMutating)
  17947. error = _Fail(StrFormat("Cannot %s field '%s.%s' within struct lambda. Consider adding 'mut' specifier to this method.", modifyType,
  17948. mModule->TypeToString(mResultFieldInstance->mOwner).c_str(), mResultFieldInstance->GetFieldDef()->mName.c_str()), refNode);
  17949. else
  17950. error = _Fail(StrFormat("Cannot %s field '%s.%s' within struct lambda. Consider adding by-reference capture specifier [&] to lambda.", modifyType,
  17951. mModule->TypeToString(mResultFieldInstance->mOwner).c_str(), mResultFieldInstance->GetFieldDef()->mName.c_str()), refNode);
  17952. }
  17953. else if (mResultFieldInstance->GetFieldDef()->mIsReadOnly)
  17954. {
  17955. error = _Fail(StrFormat("Cannot %s readonly field '%s.%s' within method '%s'", modifyType,
  17956. mModule->TypeToString(mResultFieldInstance->mOwner).c_str(), mResultFieldInstance->GetFieldDef()->mName.c_str(),
  17957. mModule->MethodToString(mModule->mCurMethodInstance).c_str()), refNode);
  17958. }
  17959. else if (mResultFieldInstance->GetFieldDef()->mIsAppend)
  17960. {
  17961. error = _Fail(StrFormat("Cannot %s append field '%s.%s' within method '%s'", modifyType,
  17962. mModule->TypeToString(mResultFieldInstance->mOwner).c_str(), mResultFieldInstance->GetFieldDef()->mName.c_str(),
  17963. mModule->MethodToString(mModule->mCurMethodInstance).c_str()), refNode);
  17964. }
  17965. else if (auto propertyDeclaration = BfNodeDynCast<BfPropertyDeclaration>(mResultFieldInstance->GetFieldDef()->mFieldDeclaration))
  17966. {
  17967. String propNam;
  17968. if (propertyDeclaration->mNameNode != NULL)
  17969. propertyDeclaration->mNameNode->ToString(propNam);
  17970. error = _Fail(StrFormat("Cannot %s auto-implemented property '%s.%s' without set accessor", modifyType,
  17971. mModule->TypeToString(mResultFieldInstance->mOwner).c_str(), propNam.c_str()), refNode);
  17972. }
  17973. else
  17974. {
  17975. error = _Fail(StrFormat("Cannot %s field '%s.%s' within struct method '%s'. Consider adding 'mut' specifier to this method.", modifyType,
  17976. mModule->TypeToString(mResultFieldInstance->mOwner).c_str(), mResultFieldInstance->GetFieldDef()->mName.c_str(),
  17977. mModule->MethodToString(mModule->mCurMethodInstance).c_str()), refNode);
  17978. }
  17979. return false;
  17980. }
  17981. }
  17982. else if (localVar->IsParam())
  17983. {
  17984. if (!mModule->mCurMethodInstance->IsMixin())
  17985. {
  17986. if (mModule->mCurMethodState->mMixinState != NULL)
  17987. {
  17988. error = _Fail(StrFormat("Cannot %s mixin parameter '%s'", modifyType,
  17989. localVar->mName.c_str()), refNode);
  17990. }
  17991. else if ((onlyNeedsMut) && (localVar->mResolvedType != NULL) && (localVar->mResolvedType->IsGenericParam()))
  17992. {
  17993. if (emitWarning)
  17994. error = _Fail(StrFormat("The address of '%s' may be temporary or immutable. Consider adding 'mut' or 'ref' specifier to parameter or declaring 'var %s;' to create a mutable copy.",
  17995. localVar->mName.c_str(), localVar->mName.c_str()), refNode);
  17996. else
  17997. error = _Fail(StrFormat("Cannot %s parameter '%s'. Consider adding 'mut' or 'ref' specifier to parameter or declaring 'var %s;' to create a mutable copy.", modifyType,
  17998. localVar->mName.c_str(), localVar->mName.c_str()), refNode);
  17999. }
  18000. else
  18001. {
  18002. if (emitWarning)
  18003. error = _Fail(StrFormat("The address of '%s' may be temporary or immutable. Consider adding 'ref' specifier to parameter or declaring 'var %s;' to create a mutable copy.",
  18004. localVar->mName.c_str(), localVar->mName.c_str()), refNode);
  18005. else
  18006. error = _Fail(StrFormat("Cannot %s parameter '%s'. Consider adding 'ref' specifier to parameter or declaring 'var %s;' to create a mutable copy.", modifyType,
  18007. localVar->mName.c_str(), localVar->mName.c_str()), refNode);
  18008. }
  18009. return false;
  18010. }
  18011. }
  18012. else
  18013. {
  18014. if ((mResultLocalVarField != 0) && (!localVar->mIsReadOnly))
  18015. {
  18016. auto typeInst = localVar->mResolvedType->ToTypeInstance();
  18017. int dataIdx = mResultLocalVarField - 1;
  18018. if (typeInst != NULL)
  18019. {
  18020. for (auto& field : typeInst->mFieldInstances)
  18021. {
  18022. if (field.mDataIdx == dataIdx)
  18023. {
  18024. error = _Fail(StrFormat("Cannot %s readonly field '%s.%s'.", modifyType,
  18025. mModule->TypeToString(typeInst).c_str(),
  18026. field.GetFieldDef()->mName.c_str()), refNode);
  18027. break;
  18028. }
  18029. }
  18030. }
  18031. }
  18032. if (error == NULL)
  18033. {
  18034. error = _Fail(StrFormat("Cannot %s read-only local variable '%s'.", modifyType,
  18035. localVar->mName.c_str()), refNode);
  18036. }
  18037. return false;
  18038. }
  18039. }
  18040. else
  18041. {
  18042. // When we are capturing, we need to note that we require capturing by reference here
  18043. localVar->mWrittenToId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++;
  18044. }
  18045. }
  18046. if ((mResultFieldInstance != NULL) && (mResultFieldInstance->GetFieldDef()->mIsReadOnly) && (!canModify))
  18047. {
  18048. if (mModule->mCurMethodInstance != NULL)
  18049. {
  18050. auto error = _Fail(StrFormat("Cannot %s static readonly field '%s.%s' within method '%s'", modifyType,
  18051. mModule->TypeToString(mResultFieldInstance->mOwner).c_str(), mResultFieldInstance->GetFieldDef()->mName.c_str(),
  18052. mModule->MethodToString(mModule->mCurMethodInstance).c_str()), refNode);
  18053. }
  18054. return false;
  18055. }
  18056. if ((!skipCopyOnMutate) && (typedVal.IsCopyOnMutate()))
  18057. typedVal = mModule->CopyValue(typedVal);
  18058. if ((emitWarning) && (typedVal.IsReadOnly()))
  18059. {
  18060. mModule->Warn(0, StrFormat("Cannot %s read-only variable", modifyType), refNode);
  18061. return true;
  18062. }
  18063. return mModule->CheckModifyValue(typedVal, refNode, modifyType);
  18064. }
  18065. void BfExprEvaluator::Visit(BfConditionalExpression* condExpr)
  18066. {
  18067. static int sCallCount = 0;
  18068. sCallCount++;
  18069. auto condResult = mModule->CreateValueFromExpression(condExpr->mConditionExpression, mModule->GetPrimitiveType(BfTypeCode_Boolean), (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags));
  18070. if (!condResult)
  18071. return;
  18072. if (condExpr->mTrueExpression == NULL)
  18073. {
  18074. mModule->AssertErrorState();
  18075. return;
  18076. }
  18077. if (condExpr->mFalseExpression == NULL)
  18078. {
  18079. mModule->CreateValueFromExpression(condExpr->mTrueExpression, mExpectingType, BfEvalExprFlags_NoCast);
  18080. mModule->AssertErrorState();
  18081. return;
  18082. }
  18083. bool isConstBranch = false;
  18084. bool constResult = false;
  18085. bool constResultUndef = false;
  18086. if (condResult.mValue.IsConst())
  18087. {
  18088. auto constValue = mModule->mBfIRBuilder->GetConstant(condResult.mValue);
  18089. if (constValue->mTypeCode == BfTypeCode_Boolean)
  18090. {
  18091. isConstBranch = true;
  18092. constResult = constValue->mBool;
  18093. }
  18094. else if (constValue->mConstType == BfConstType_Undef)
  18095. {
  18096. isConstBranch = true;
  18097. constResultUndef = true;
  18098. }
  18099. }
  18100. if (isConstBranch)
  18101. {
  18102. BfExpression* actualExpr = (constResult) ? condExpr->mTrueExpression : condExpr->mFalseExpression;
  18103. BfExpression* ignoredExpr = (constResult) ? condExpr->mFalseExpression : condExpr->mTrueExpression;
  18104. BfTypedValue actualValue = mModule->CreateValueFromExpression(actualExpr, mExpectingType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast));
  18105. BfTypedValue ignoredValue;
  18106. //
  18107. {
  18108. auto curBlock = mModule->mBfIRBuilder->GetInsertBlock();
  18109. SetAndRestoreValue<bool> ignoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
  18110. SetAndRestoreValue<bool> prevInConstIgnore(mModule->mCurMethodState->mCurScope->mInConstIgnore, true);
  18111. ignoredValue = mModule->CreateValueFromExpression(ignoredExpr, mExpectingType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast));
  18112. mModule->mBfIRBuilder->SetInsertPoint(curBlock);
  18113. }
  18114. if (!actualValue)
  18115. return;
  18116. if ((ignoredValue) && (ignoredValue.mType != actualValue.mType) && (!ignoredValue.mType->IsVar()))
  18117. {
  18118. // Cast to more specific 'ignored' type if applicable
  18119. if (mModule->CanCast(actualValue, ignoredValue.mType))
  18120. {
  18121. actualValue = mModule->Cast(actualExpr, actualValue, ignoredValue.mType);
  18122. }
  18123. else if (!mModule->CanCast(ignoredValue, actualValue.mType))
  18124. {
  18125. mModule->Fail(StrFormat("Type of conditional expression cannot be determined because there is no implicit conversion between '%s' and '%s'",
  18126. mModule->TypeToString(actualValue.mType).c_str(), mModule->TypeToString(ignoredValue.mType).c_str()), condExpr);
  18127. }
  18128. }
  18129. mResult = actualValue;
  18130. if (constResultUndef)
  18131. mResult = mModule->GetDefaultTypedValue(mResult.mType, false, BfDefaultValueKind_Undef);
  18132. return;
  18133. }
  18134. auto trueBB = mModule->mBfIRBuilder->CreateBlock("cond.then");
  18135. auto falseBB = mModule->mBfIRBuilder->CreateBlock("cond.else");
  18136. auto endBB = mModule->mBfIRBuilder->CreateBlock("cond.end");
  18137. auto contBB = mModule->mBfIRBuilder->CreateBlock("cond.cont");
  18138. mModule->mBfIRBuilder->CreateCondBr(condResult.mValue, trueBB, falseBB);
  18139. SetAndRestoreValue<bool> prevInCondBlock(mModule->mCurMethodState->mCurScope->mInnerIsConditional, true);
  18140. bool wantExpectingCast = (mExpectingType != NULL) && ((mBfEvalExprFlags & BfEvalExprFlags_NoCast) == 0);
  18141. mModule->AddBasicBlock(trueBB);
  18142. auto trueValue = mModule->CreateValueFromExpression(condExpr->mTrueExpression, mExpectingType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_CreateConditionalScope));
  18143. if ((wantExpectingCast) && (trueValue) && (trueValue.mType != mExpectingType))
  18144. {
  18145. // In some cases like typed primitives - we CAN individually cast each value which it's a constant still, but not after the merging
  18146. // IE: Color c = isOver ? 0xFF000000 : 0xFFFFFFFF;
  18147. // Otherwise the resulting value would just be 'int' which cannot implicitly convert to Color, but each of those ints can be
  18148. // a uint32 if converted separately
  18149. auto checkTrueValue = mModule->Cast(condExpr->mTrueExpression, trueValue, mExpectingType, BfCastFlags_SilentFail);
  18150. if (checkTrueValue)
  18151. trueValue = checkTrueValue;
  18152. mModule->FixIntUnknown(trueValue);
  18153. }
  18154. auto trueBlockPos = mModule->mBfIRBuilder->GetInsertBlock();
  18155. mModule->AddBasicBlock(falseBB);
  18156. auto falseValue = mModule->CreateValueFromExpression(condExpr->mFalseExpression, mExpectingType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_CreateConditionalScope));
  18157. auto falseBlockPos = mModule->mBfIRBuilder->GetInsertBlock();
  18158. if ((wantExpectingCast) && (falseValue) && (falseValue.mType != mExpectingType))
  18159. {
  18160. auto checkFalseValue = mModule->Cast(condExpr->mFalseExpression, falseValue, mExpectingType, BfCastFlags_SilentFail);
  18161. if (checkFalseValue)
  18162. falseValue = checkFalseValue;
  18163. mModule->FixIntUnknown(falseValue);
  18164. }
  18165. bool isValid = trueValue && falseValue;
  18166. if (isValid)
  18167. {
  18168. BfTypedValue falseToTrue;
  18169. {
  18170. SetAndRestoreValue<bool> prevIgnoreError(mModule->mIgnoreErrors, true);
  18171. mModule->mBfIRBuilder->SetInsertPoint(falseBlockPos);
  18172. falseToTrue = mModule->Cast(condExpr->mFalseExpression, falseValue, trueValue.mType);
  18173. }
  18174. if (falseToTrue)
  18175. {
  18176. falseValue = falseToTrue;
  18177. }
  18178. else
  18179. {
  18180. BfTypedValue trueToFalse;
  18181. {
  18182. SetAndRestoreValue<bool> prevIgnoreError(mModule->mIgnoreErrors, true);
  18183. mModule->mBfIRBuilder->SetInsertPoint(trueBlockPos);
  18184. trueToFalse = mModule->Cast(condExpr->mTrueExpression, trueValue, falseValue.mType);
  18185. }
  18186. if (!trueToFalse)
  18187. {
  18188. mModule->Fail(StrFormat("Type of conditional expression cannot be determined because there is no implicit conversion between '%s' and '%s'",
  18189. mModule->TypeToString(trueValue.mType).c_str(), mModule->TypeToString(falseValue.mType).c_str()), condExpr);
  18190. //return;
  18191. isValid = false;
  18192. }
  18193. else
  18194. trueValue = trueToFalse;
  18195. }
  18196. }
  18197. prevInCondBlock.Restore();
  18198. mModule->mBfIRBuilder->SetInsertPoint(trueBlockPos);
  18199. if (isValid)
  18200. trueValue = mModule->LoadValue(trueValue);
  18201. mModule->mBfIRBuilder->CreateBr(endBB);
  18202. mModule->mBfIRBuilder->SetInsertPoint(falseBlockPos);
  18203. if (isValid)
  18204. falseValue = mModule->LoadValue(falseValue);
  18205. mModule->mBfIRBuilder->CreateBr(endBB);
  18206. mModule->AddBasicBlock(endBB, false);
  18207. if (!isValid)
  18208. return;
  18209. mModule->mBfIRBuilder->SetInsertPoint(endBB);
  18210. BfIRValue phi;
  18211. if (!trueValue.mType->IsValuelessType())
  18212. {
  18213. if (trueValue.mType->IsVar())
  18214. {
  18215. phi = mModule->mBfIRBuilder->GetFakeVal();
  18216. }
  18217. else
  18218. {
  18219. mModule->mBfIRBuilder->PopulateType(trueValue.mType);
  18220. phi = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(trueValue.mType), 2);
  18221. mModule->mBfIRBuilder->AddPhiIncoming(phi, trueValue.mValue, trueBlockPos);
  18222. mModule->mBfIRBuilder->AddPhiIncoming(phi, falseValue.mValue, falseBlockPos);
  18223. }
  18224. }
  18225. mModule->mBfIRBuilder->CreateBr(contBB);
  18226. mModule->AddBasicBlock(contBB);
  18227. mResult = BfTypedValue(phi, trueValue.mType);
  18228. }
  18229. void BfExprEvaluator::PopulateDeferrredTupleAssignData(BfTupleExpression* tupleExpr, DeferredTupleAssignData& deferredTupleAssignData)
  18230. {
  18231. BfTypeVector fieldTypes;
  18232. Array<String> fieldNames;
  18233. // We need to evaluate each LHS tuple component in a separate BfExprEvaluator because each one
  18234. // could be a property and the 'mPropDef' target info is tied to a single evaluator
  18235. for (int valueIdx = 0; valueIdx < (int)tupleExpr->mValues.size(); valueIdx++)
  18236. {
  18237. DeferredTupleAssignData::Entry entry;
  18238. entry.mExprEvaluator = NULL;
  18239. entry.mInnerTuple = NULL;
  18240. entry.mVarType = NULL;
  18241. entry.mVarNameNode = NULL;
  18242. BfExpression* valueExpr = tupleExpr->mValues[valueIdx];
  18243. entry.mExpr = valueExpr;
  18244. BfType* fieldType = NULL;
  18245. BfType* resultType = NULL;
  18246. if (auto innerTupleExpr = BfNodeDynCast<BfTupleExpression>(valueExpr))
  18247. {
  18248. entry.mInnerTuple = new DeferredTupleAssignData();
  18249. PopulateDeferrredTupleAssignData(innerTupleExpr, *entry.mInnerTuple);
  18250. resultType = entry.mInnerTuple->mTupleType;
  18251. }
  18252. else
  18253. {
  18254. BfExprEvaluator* exprEvaluator = new BfExprEvaluator(mModule);
  18255. entry.mExprEvaluator = exprEvaluator;
  18256. if (valueExpr->IsA<BfUninitializedExpression>())
  18257. {
  18258. resultType = mModule->GetPrimitiveType(BfTypeCode_None);
  18259. }
  18260. if (auto varDecl = BfNodeDynCast<BfVariableDeclaration>(valueExpr))
  18261. {
  18262. if ((varDecl->mTypeRef->IsA<BfLetTypeReference>()) || (varDecl->mTypeRef->IsA<BfVarTypeReference>()))
  18263. {
  18264. resultType = mModule->GetPrimitiveType(BfTypeCode_Var);
  18265. }
  18266. else
  18267. {
  18268. resultType = ResolveTypeRef(varDecl->mTypeRef);
  18269. if (resultType == NULL)
  18270. resultType = mModule->GetPrimitiveType(BfTypeCode_Var);
  18271. }
  18272. entry.mVarType = resultType;
  18273. }
  18274. if (auto binOpExpr = BfNodeDynCast<BfBinaryOperatorExpression>(valueExpr))
  18275. {
  18276. if (binOpExpr->mOp == BfBinaryOp_Multiply)
  18277. {
  18278. SetAndRestoreValue<bool> prevIgnoreError(mModule->mIgnoreErrors, true);
  18279. auto resolvedType = mModule->ResolveTypeRef(binOpExpr->mLeft, NULL);
  18280. prevIgnoreError.Restore();
  18281. if (resolvedType != NULL)
  18282. {
  18283. resultType = mModule->CreatePointerType(resolvedType);
  18284. entry.mVarType = resultType;
  18285. entry.mVarNameNode = binOpExpr->mRight;
  18286. }
  18287. }
  18288. }
  18289. if (resultType == NULL)
  18290. {
  18291. exprEvaluator->VisitChild(valueExpr);
  18292. if ((!exprEvaluator->mResult) && (exprEvaluator->mPropDef == NULL))
  18293. exprEvaluator->mResult = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_None));
  18294. resultType = exprEvaluator->mResult.mType;
  18295. }
  18296. if ((resultType == NULL) && (exprEvaluator->mPropDef != NULL) && (exprEvaluator->mPropTarget.mType != NULL))
  18297. {
  18298. auto propTypeInst = exprEvaluator->mPropTarget.mType->ToTypeInstance();
  18299. if ((propTypeInst == NULL) && (exprEvaluator->mPropTarget.mType->IsPointer()))
  18300. {
  18301. BfPointerType* pointerType = (BfPointerType*)exprEvaluator->mPropTarget.mType;
  18302. propTypeInst = pointerType->mElementType->ToTypeInstance();
  18303. }
  18304. auto setMethod = GetPropertyMethodDef(exprEvaluator->mPropDef, BfMethodType_PropertySetter, mPropCheckedKind, mPropTarget);
  18305. if (setMethod != NULL)
  18306. {
  18307. auto methodInstance = mModule->GetMethodInstance(propTypeInst, setMethod, BfTypeVector());
  18308. resultType = methodInstance.mMethodInstance->GetParamType(0);
  18309. }
  18310. else
  18311. {
  18312. auto getMethod = GetPropertyMethodDef(exprEvaluator->mPropDef, BfMethodType_PropertyGetter, mPropCheckedKind, mPropTarget);
  18313. if (getMethod != NULL)
  18314. {
  18315. auto methodInstance = mModule->GetMethodInstance(propTypeInst, getMethod, BfTypeVector());
  18316. auto retType = methodInstance.mMethodInstance->mReturnType;
  18317. if (retType->IsRef())
  18318. resultType = retType->GetUnderlyingType();
  18319. }
  18320. }
  18321. }
  18322. }
  18323. if (resultType == NULL)
  18324. resultType = mModule->GetPrimitiveType(BfTypeCode_None);
  18325. deferredTupleAssignData.mChildren.push_back(entry);
  18326. fieldTypes.push_back(resultType);
  18327. }
  18328. for (BfTupleNameNode* requestedName : tupleExpr->mNames)
  18329. {
  18330. if (requestedName == NULL)
  18331. fieldNames.push_back("");
  18332. else
  18333. fieldNames.push_back(requestedName->mNameNode->ToString());
  18334. }
  18335. BfTypeInstance* tupleType = mModule->CreateTupleType(fieldTypes, fieldNames, true);
  18336. deferredTupleAssignData.mTupleType = tupleType;
  18337. }
  18338. void BfExprEvaluator::AssignDeferrredTupleAssignData(BfAssignmentExpression* assignExpr, DeferredTupleAssignData& deferredTupleAssignData, BfTypedValue rightValue)
  18339. {
  18340. BF_ASSERT(rightValue.mType->IsTuple());
  18341. auto tupleType = (BfTypeInstance*)rightValue.mType;
  18342. for (int valueIdx = 0; valueIdx < (int)deferredTupleAssignData.mChildren.size(); valueIdx++)
  18343. {
  18344. auto& child = deferredTupleAssignData.mChildren[valueIdx];
  18345. BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[valueIdx];
  18346. BfTypedValue elementValue;
  18347. if (fieldInstance->mDataIdx >= 0)
  18348. {
  18349. rightValue = mModule->LoadOrAggregateValue(rightValue);
  18350. mModule->mBfIRBuilder->PopulateType(rightValue.mType);
  18351. auto extractedValue = mModule->mBfIRBuilder->CreateExtractValue(rightValue.mValue, fieldInstance->mDataIdx);
  18352. elementValue = BfTypedValue(extractedValue, fieldInstance->GetResolvedType());
  18353. if (child.mInnerTuple != NULL)
  18354. {
  18355. AssignDeferrredTupleAssignData(assignExpr, *child.mInnerTuple, elementValue);
  18356. delete child.mInnerTuple;
  18357. child.mInnerTuple = NULL;
  18358. }
  18359. else
  18360. {
  18361. if (child.mExprEvaluator->HasResult())
  18362. {
  18363. child.mExprEvaluator->mBfEvalExprFlags = (BfEvalExprFlags)(child.mExprEvaluator->mBfEvalExprFlags | BfEvalExprFlags_NoAutoComplete);
  18364. child.mExprEvaluator->PerformAssignment(assignExpr, true, elementValue);
  18365. }
  18366. }
  18367. }
  18368. if (child.mVarType != NULL)
  18369. {
  18370. if (auto varDecl = BfNodeDynCast<BfVariableDeclaration>(child.mExpr))
  18371. {
  18372. if (!elementValue)
  18373. elementValue = mModule->GetDefaultTypedValue(fieldInstance->GetResolvedType());
  18374. mModule->HandleVariableDeclaration(varDecl, elementValue);
  18375. }
  18376. else
  18377. {
  18378. // This handles the 'a*b' disambiguated variable decl case
  18379. mModule->HandleVariableDeclaration(child.mVarType, child.mVarNameNode, elementValue);
  18380. }
  18381. }
  18382. }
  18383. }
  18384. void BfExprEvaluator::DoTupleAssignment(BfAssignmentExpression* assignExpr)
  18385. {
  18386. auto tupleExpr = BfNodeDynCast<BfTupleExpression>(assignExpr->mLeft);
  18387. DeferredTupleAssignData deferredTupleAssignData;
  18388. PopulateDeferrredTupleAssignData(tupleExpr, deferredTupleAssignData);
  18389. BfTypeInstance* tupleType = deferredTupleAssignData.mTupleType;
  18390. BfTypedValue rightValue;
  18391. if (assignExpr->mRight != NULL)
  18392. {
  18393. rightValue = mModule->CreateValueFromExpression(assignExpr->mRight, tupleType);
  18394. }
  18395. if (!rightValue)
  18396. {
  18397. tupleType = mModule->SantizeTupleType(tupleType);
  18398. rightValue = mModule->GetDefaultTypedValue(tupleType);
  18399. }
  18400. rightValue = mModule->LoadValue(rightValue);
  18401. AssignDeferrredTupleAssignData(assignExpr, deferredTupleAssignData, rightValue);
  18402. mResult = rightValue;
  18403. }
  18404. BfTypedValue BfExprEvaluator::PerformAssignment_CheckOp(BfAssignmentExpression* assignExpr, bool deferBinop, BfTypedValue& leftValue, BfTypedValue& rightValue, bool& evaluatedRight)
  18405. {
  18406. BfResolvedArgs argValues;
  18407. auto checkTypeInst = leftValue.mType->ToTypeInstance();
  18408. while (checkTypeInst != NULL)
  18409. {
  18410. for (auto operatorDef : checkTypeInst->mTypeDef->mOperators)
  18411. {
  18412. if (operatorDef->mOperatorDeclaration->mAssignOp != assignExpr->mOp)
  18413. continue;
  18414. auto methodInst = mModule->GetRawMethodInstanceAtIdx(checkTypeInst, operatorDef->mIdx);
  18415. if (methodInst == NULL)
  18416. continue;
  18417. if (methodInst->GetParamCount() != 1)
  18418. continue;
  18419. auto paramType = methodInst->GetParamType(0);
  18420. BfModuleMethodInstance moduleMethodInstance;
  18421. if (methodInst->mIsUnspecialized)
  18422. {
  18423. BfTypeVector checkMethodGenericArguments;
  18424. checkMethodGenericArguments.resize(methodInst->GetNumGenericArguments());
  18425. BfGenericInferContext genericInferContext;
  18426. genericInferContext.mModule = mModule;
  18427. genericInferContext.mCheckMethodGenericArguments = &checkMethodGenericArguments;
  18428. if (!genericInferContext.InferGenericArgument(methodInst, rightValue.mType, paramType, rightValue.mValue))
  18429. continue;
  18430. bool genericsInferred = true;
  18431. for (int i = 0; i < checkMethodGenericArguments.mSize; i++)
  18432. if ((checkMethodGenericArguments[i] == NULL) || (checkMethodGenericArguments[i]->IsVar()))
  18433. genericsInferred = false;
  18434. if (!genericsInferred)
  18435. continue;
  18436. moduleMethodInstance = mModule->GetMethodInstance(checkTypeInst, operatorDef, checkMethodGenericArguments);
  18437. paramType = moduleMethodInstance.mMethodInstance->GetParamType(0);
  18438. }
  18439. if (deferBinop)
  18440. {
  18441. if (argValues.mArguments == NULL)
  18442. {
  18443. SizedArray<BfExpression*, 2> argExprs;
  18444. argExprs.push_back(assignExpr->mRight);
  18445. BfSizedArray<BfExpression*> sizedArgExprs(argExprs);
  18446. argValues.Init(&sizedArgExprs);
  18447. ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval);
  18448. }
  18449. evaluatedRight = true;
  18450. rightValue = ResolveArgValue(argValues.mResolvedArgs[0], paramType);
  18451. if (!rightValue)
  18452. continue;
  18453. }
  18454. else
  18455. {
  18456. if (!mModule->CanCast(rightValue, paramType))
  18457. continue;
  18458. rightValue = mModule->Cast(assignExpr->mLeft, rightValue, paramType);
  18459. BF_ASSERT(rightValue);
  18460. }
  18461. mModule->SetElementType(assignExpr->mOpToken, BfSourceElementType_Method);
  18462. auto autoComplete = GetAutoComplete();
  18463. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(assignExpr->mOpToken)))
  18464. {
  18465. if (operatorDef->mOperatorDeclaration != NULL)
  18466. autoComplete->SetDefinitionLocation(operatorDef->mOperatorDeclaration->mOpTypeToken);
  18467. }
  18468. if (!moduleMethodInstance)
  18469. moduleMethodInstance = mModule->GetMethodInstance(checkTypeInst, operatorDef, BfTypeVector());
  18470. BfExprEvaluator exprEvaluator(mModule);
  18471. SizedArray<BfIRValue, 1> args;
  18472. exprEvaluator.PushThis(assignExpr->mLeft, leftValue, moduleMethodInstance.mMethodInstance, args);
  18473. exprEvaluator.PushArg(rightValue, args);
  18474. exprEvaluator.CreateCall(assignExpr, moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, false, args);
  18475. return leftValue;
  18476. }
  18477. checkTypeInst = mModule->GetBaseType(checkTypeInst);
  18478. }
  18479. return BfTypedValue();
  18480. }
  18481. void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool evaluatedLeft, BfTypedValue rightValue, BfTypedValue* outCascadeValue)
  18482. {
  18483. auto binaryOp = BfAssignOpToBinaryOp(assignExpr->mOp);
  18484. BfExpression* targetNode = assignExpr->mLeft;
  18485. if ((BfNodeIsA<BfMixinExpression>(targetNode)) && (!mModule->mCurMethodInstance->mIsUnspecialized))
  18486. {
  18487. // If we have a "mixin = <X>" but there's no mixin target then ignore the assignment
  18488. int mixinVar = GetMixinVariable();
  18489. if (mixinVar == -1)
  18490. {
  18491. mResult = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_None));
  18492. return;
  18493. }
  18494. }
  18495. BfAutoComplete* autoComplete = GetAutoComplete();
  18496. bool deferredFixits = false;
  18497. //TODO: Why was this needed? This breaks fixits on target nodes (ie: 'using' field fixit for 'fully quality')
  18498. /*if ((autoComplete != NULL) && (autoComplete->mResolveType == BfResolveType_GetFixits))
  18499. {
  18500. SetAndRestoreValue<bool> ignoreFixits(autoComplete->mIgnoreFixits, true);
  18501. VisitChild(targetNode);
  18502. deferredFixits = true;
  18503. }
  18504. else*/
  18505. if (!evaluatedLeft)
  18506. {
  18507. if (auto memberReferenceExpr = BfNodeDynCast<BfMemberReferenceExpression>(targetNode))
  18508. {
  18509. DoMemberReference(memberReferenceExpr, outCascadeValue);
  18510. }
  18511. else
  18512. VisitChild(targetNode);
  18513. }
  18514. if ((!mResult) && (mPropDef == NULL))
  18515. {
  18516. if (assignExpr->mRight != NULL)
  18517. {
  18518. auto result = mModule->CreateValueFromExpression(assignExpr->mRight);
  18519. if (deferredFixits)
  18520. {
  18521. SetAndRestoreValue<bool> ignoreErrors(mModule->mIgnoreErrors, true);
  18522. mExpectingType = result.mType;
  18523. VisitChild(targetNode);
  18524. mResult = BfTypedValue();
  18525. }
  18526. }
  18527. return;
  18528. }
  18529. ResolveGenericType();
  18530. auto ptr = mModule->RemoveRef(mResult);
  18531. mResult = BfTypedValue();
  18532. if (mPropDef != NULL)
  18533. {
  18534. bool hasLeftVal = false;
  18535. auto propDef = mPropDef;
  18536. auto propTarget = mPropTarget;
  18537. auto setMethod = GetPropertyMethodDef(mPropDef, BfMethodType_PropertySetter, mPropCheckedKind, mPropTarget);
  18538. if (setMethod == NULL)
  18539. {
  18540. // Allow for a ref return on the getter to be used if a setter is not available
  18541. GetResult();
  18542. if ((mResult) && (mResult.mKind == BfTypedValueKind_Addr))
  18543. {
  18544. ptr = mResult;
  18545. mResult = BfTypedValue();
  18546. hasLeftVal = true;
  18547. }
  18548. else
  18549. {
  18550. mModule->Fail("Property has no setter", mPropSrc);
  18551. if (assignExpr->mRight != NULL)
  18552. mModule->CreateValueFromExpression(assignExpr->mRight, ptr.mType, BfEvalExprFlags_NoCast);
  18553. return;
  18554. }
  18555. }
  18556. if (!hasLeftVal)
  18557. {
  18558. auto methodInstance = GetPropertyMethodInstance(setMethod);
  18559. if (methodInstance.mMethodInstance == NULL)
  18560. return;
  18561. //BF_ASSERT(methodInstance.mMethodInstance->mMethodDef == setMethod);
  18562. CheckPropFail(setMethod, methodInstance.mMethodInstance, (mPropGetMethodFlags & BfGetMethodInstanceFlag_Friend) == 0);
  18563. auto autoComplete = GetAutoComplete();
  18564. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(mPropSrc)) && (autoComplete->mResolveType == BfResolveType_GetResultString))
  18565. {
  18566. autoComplete->mResultString = ":";
  18567. autoComplete->mResultString += mModule->TypeToString(methodInstance.mMethodInstance->GetParamType(0));
  18568. autoComplete->mResultString += " ";
  18569. autoComplete->mResultString += mModule->TypeToString(methodInstance.mMethodInstance->GetOwner());
  18570. autoComplete->mResultString += ".";
  18571. autoComplete->mResultString += mPropDef->mName;
  18572. }
  18573. bool handled = false;
  18574. BfTypedValue convVal;
  18575. if (binaryOp != BfBinaryOp_None)
  18576. {
  18577. BfTypedValue leftValue = mModule->CreateValueFromExpression(assignExpr->mLeft, mExpectingType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_AllowIntUnknown));
  18578. if (!leftValue)
  18579. return;
  18580. bool evaluatedRight = false;
  18581. auto opResult = PerformAssignment_CheckOp(assignExpr, true, leftValue, rightValue, evaluatedRight);
  18582. if (opResult)
  18583. {
  18584. mResult = opResult;
  18585. return;
  18586. }
  18587. else
  18588. {
  18589. if (evaluatedRight)
  18590. {
  18591. if (!rightValue)
  18592. return;
  18593. PerformBinaryOperation(assignExpr->mLeft, assignExpr->mRight, binaryOp, assignExpr->mOpToken, BfBinOpFlag_ForceLeftType, leftValue, rightValue);
  18594. }
  18595. else
  18596. PerformBinaryOperation(assignExpr->mLeft, assignExpr->mRight, binaryOp, assignExpr->mOpToken, BfBinOpFlag_ForceLeftType, leftValue);
  18597. if (!mResult)
  18598. return;
  18599. convVal = mResult;
  18600. mResult = BfTypedValue();
  18601. if (!convVal)
  18602. return;
  18603. }
  18604. }
  18605. else
  18606. {
  18607. auto wantType = methodInstance.mMethodInstance->GetParamType(0);
  18608. if (rightValue)
  18609. {
  18610. convVal = mModule->Cast(assignExpr->mRight, rightValue, wantType);
  18611. }
  18612. else
  18613. {
  18614. if (assignExpr->mRight == NULL)
  18615. {
  18616. mModule->AssertErrorState();
  18617. return;
  18618. }
  18619. BfEvalExprFlags exprFlags = (BfEvalExprFlags)(BfEvalExprFlags_AllowSplat | BfEvalExprFlags_PendingPropSet);
  18620. if (wantType->IsRef())
  18621. exprFlags = (BfEvalExprFlags)(exprFlags | BfEvalExprFlags_AllowRefExpr);
  18622. convVal = mModule->CreateValueFromExpression(assignExpr->mRight, wantType, exprFlags);
  18623. }
  18624. if (!convVal)
  18625. {
  18626. mPropDef = NULL;
  18627. return;
  18628. }
  18629. }
  18630. if (!handled)
  18631. {
  18632. if (mPropSrc != NULL)
  18633. mModule->UpdateExprSrcPos(mPropSrc);
  18634. BfResolvedArg valueArg;
  18635. valueArg.mTypedValue = convVal;
  18636. mIndexerValues.Insert(0, valueArg);
  18637. if (!setMethod->mIsStatic)
  18638. {
  18639. auto owner = methodInstance.mMethodInstance->GetOwner();
  18640. if ((mPropTarget.mType != owner) ||
  18641. ((mPropTarget.mValue.IsFake()) && (!mOrigPropTarget.mValue.IsFake())))
  18642. {
  18643. if ((mPropDefBypassVirtual) || (!mPropTarget.mType->IsInterface()))
  18644. {
  18645. mPropTarget = mModule->Cast(mPropSrc, mOrigPropTarget, owner);
  18646. if (!mPropTarget)
  18647. {
  18648. mModule->Fail("Internal property error", mPropSrc);
  18649. return;
  18650. }
  18651. }
  18652. }
  18653. }
  18654. auto callFlags = mPropDefBypassVirtual ? BfCreateCallFlags_BypassVirtual : BfCreateCallFlags_None;
  18655. mResult = CreateCall(mPropSrc, mPropTarget, mOrigPropTarget, setMethod, methodInstance, callFlags, mIndexerValues, NULL);
  18656. mPropDef = NULL;
  18657. mResult = convVal;
  18658. mIndexerValues.Clear();
  18659. return;
  18660. }
  18661. }
  18662. }
  18663. auto toType = ptr.mType;
  18664. if (toType->IsRef())
  18665. {
  18666. auto refType = (BfRefType*)toType;
  18667. toType = refType->mElementType;
  18668. }
  18669. if (toType->IsIntUnknown())
  18670. toType = mModule->FixIntUnknown(toType);
  18671. if ((autoComplete != NULL) && (assignExpr->mOpToken != NULL) && (toType != NULL))
  18672. autoComplete->CheckEmptyStart(assignExpr->mOpToken, toType);
  18673. BfExpression* rightExpr = assignExpr->mRight;
  18674. if (rightExpr == NULL)
  18675. {
  18676. mModule->AssertErrorState();
  18677. return;
  18678. }
  18679. bool alreadyWritten = false;
  18680. BfTypedValue convVal;
  18681. if (binaryOp != BfBinaryOp_None)
  18682. {
  18683. CheckResultForReading(ptr);
  18684. BfTypedValue leftValue = ptr;
  18685. bool deferBinop = false;
  18686. BfDeferEvalChecker deferEvalChecker;
  18687. deferEvalChecker.mDeferLiterals = false;
  18688. assignExpr->mRight->Accept(&deferEvalChecker);
  18689. if (deferEvalChecker.mNeedsDeferEval)
  18690. deferBinop = true;
  18691. if (binaryOp == BfBinaryOp_NullCoalesce)
  18692. {
  18693. deferBinop = true;
  18694. }
  18695. if (!deferBinop)
  18696. {
  18697. auto expectedType = ptr.mType;
  18698. if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift))
  18699. expectedType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  18700. if ((!rightValue) && (assignExpr->mRight != NULL))
  18701. {
  18702. rightValue = mModule->CreateValueFromExpression(assignExpr->mRight, expectedType, (BfEvalExprFlags)(BfEvalExprFlags_AllowSplat | BfEvalExprFlags_NoCast));
  18703. }
  18704. }
  18705. BfResolvedArgs argValues;
  18706. if ((rightValue) || (deferBinop))
  18707. {
  18708. bool evaluatedRight = false;
  18709. auto opResult = PerformAssignment_CheckOp(assignExpr, deferBinop, leftValue, rightValue, evaluatedRight);
  18710. if (opResult)
  18711. {
  18712. mResult = opResult;
  18713. return;
  18714. }
  18715. else
  18716. {
  18717. auto flags = BfBinOpFlag_ForceLeftType;
  18718. if (deferBinop)
  18719. flags = (BfBinOpFlags)(flags | BfBinOpFlag_DeferRight);
  18720. leftValue = mModule->LoadValue(leftValue);
  18721. if (binaryOp == BfBinaryOp_NullCoalesce)
  18722. {
  18723. if (!CheckModifyResult(ptr, assignExpr->mOpToken, "assign to", false, false, true))
  18724. {
  18725. mModule->CreateValueFromExpression(assignExpr->mRight, ptr.mType, (BfEvalExprFlags)(BfEvalExprFlags_AllowSplat | BfEvalExprFlags_NoCast));
  18726. mResult = leftValue;
  18727. return;
  18728. }
  18729. if (PerformBinaryOperation_NullCoalesce(assignExpr->mOpToken, assignExpr->mLeft, assignExpr->mRight, leftValue, leftValue.mType, &ptr))
  18730. return;
  18731. }
  18732. PerformBinaryOperation(assignExpr->mLeft, assignExpr->mRight, binaryOp, assignExpr->mOpToken, flags, leftValue, rightValue);
  18733. }
  18734. }
  18735. convVal = mResult;
  18736. mResult = BfTypedValue();
  18737. if (!convVal)
  18738. return;
  18739. }
  18740. else
  18741. {
  18742. convVal = rightValue;
  18743. if (!convVal)
  18744. {
  18745. if (auto uninitExpr = BfNodeDynCast<BfUninitializedExpression>(rightExpr))
  18746. {
  18747. if (mResultLocalVar != NULL)
  18748. {
  18749. MarkResultAssigned();
  18750. return;
  18751. }
  18752. }
  18753. // In the cases like "structVal = GetVal()", the allowDirectStructRetWrite optimization allows us to pass the
  18754. // address of structVal into the sret. We only allow that if structVal is a local, because if it's globally
  18755. // visible then we could see the results of a partially-modified structVal
  18756. //bool allowDirectStructRetWrite = mResultLocalVarIdx != -1;
  18757. // ALTHOUGH- we can only allow this optimization if we can be sure the local value is not aliased- we could
  18758. // have the backend ensure that this local value never gets its address taken.
  18759. bool allowDirectStructWrite = false;
  18760. BfExprEvaluator exprEvaluator(mModule);
  18761. exprEvaluator.mExpectingType = toType;
  18762. if (allowDirectStructWrite)
  18763. exprEvaluator.mReceivingValue = &ptr;
  18764. exprEvaluator.Evaluate(rightExpr, false, false, true);
  18765. exprEvaluator.CheckResultForReading(exprEvaluator.mResult);
  18766. convVal = exprEvaluator.GetResult();
  18767. mModule->FixIntUnknown(convVal);
  18768. alreadyWritten = (allowDirectStructWrite) && (exprEvaluator.mReceivingValue == NULL);
  18769. if (!convVal)
  18770. convVal = mModule->GetDefaultTypedValue(toType);
  18771. // Did we use mReceivingValue as a mixin result?
  18772. if ((convVal.mValue) && (convVal.mValue == ptr.mValue))
  18773. {
  18774. mResult = convVal;
  18775. return;
  18776. }
  18777. }
  18778. }
  18779. if (!CheckModifyResult(ptr, assignExpr->mOpToken, "assign to", false, false, true))
  18780. {
  18781. mResult = convVal;
  18782. return;
  18783. }
  18784. if (ptr.mKind == BfTypedValueKind_CopyOnMutateAddr)
  18785. ptr.mKind = BfTypedValueKind_Addr;
  18786. else if (ptr.IsCopyOnMutate())
  18787. ptr = mModule->CopyValue(ptr);
  18788. BF_ASSERT(convVal);
  18789. if ((convVal) && (convVal.mType->IsNull()) && (ptr.mType->IsNullable()))
  18790. {
  18791. // Allow this to pass through so we can catch it in the memset later in this function
  18792. }
  18793. else
  18794. {
  18795. if (!convVal.mType->IsComposite())
  18796. convVal = mModule->LoadValue(convVal);
  18797. convVal = mModule->Cast(rightExpr, convVal, toType);
  18798. if (!convVal)
  18799. return;
  18800. convVal = mModule->LoadValue(convVal);
  18801. }
  18802. if (ptr.mType->IsVar())
  18803. {
  18804. mResult = ptr;
  18805. MarkResultAssigned();
  18806. return;
  18807. }
  18808. if (convVal.mValue)
  18809. {
  18810. if ((ptr.mType->IsStruct()) && (!ptr.mType->IsValuelessType()) && (convVal.mValue.IsConst()))
  18811. {
  18812. auto constant = mModule->mBfIRBuilder->GetConstant(convVal.mValue);
  18813. if ((constant->mTypeCode == BfTypeCode_NullPtr) || (constant->mConstType == BfConstType_AggZero))
  18814. {
  18815. auto type = ptr.mType;
  18816. mModule->mBfIRBuilder->CreateMemSet(ptr.mValue, mModule->GetConstValue(0, mModule->GetPrimitiveType(BfTypeCode_Int8)),
  18817. mModule->GetConstValue(type->mSize), type->mAlign);
  18818. mResult = ptr;
  18819. MarkResultAssigned();
  18820. return;
  18821. }
  18822. }
  18823. // if (ptr.mType->IsMethodRef())
  18824. // {
  18825. // auto methodRefType = (BfMethodRefType*)ptr.mType;
  18826. // auto methodInstance = methodRefType->mMethodInstance;
  18827. // int implicitParamCount = methodInstance->GetImplicitParamCount();
  18828. // for (int implicitParamIdx = methodInstance->HasThis() ? - 1 : 0; implicitParamIdx < implicitParamCount; implicitParamIdx++)
  18829. // {
  18830. // bool failed = false;
  18831. // auto destPtr = DoImplicitArgCapture(assignExpr, methodRefType->mMethodInstance, implicitParamIdx, failed, BfImplicitParamKind_GenericTypeMember_Addr);
  18832. // auto srcVal = DoImplicitArgCapture(assignExpr, methodRefType->mMethodInstance, implicitParamIdx, failed, BfImplicitParamKind_GenericMethodMember);
  18833. // if ((destPtr) && (srcVal))
  18834. // {
  18835. // srcVal = mModule->AggregateSplat(srcVal);
  18836. // mModule->mBfIRBuilder->CreateStore(srcVal.mValue, destPtr.mValue);
  18837. // }
  18838. // }
  18839. // }
  18840. // else
  18841. {
  18842. mModule->mBfIRBuilder->PopulateType(ptr.mType);
  18843. if (convVal.IsSplat())
  18844. {
  18845. //convVal = mModule->AggregateSplat(convVal);
  18846. mModule->AggregateSplatIntoAddr(convVal, ptr.mValue);
  18847. }
  18848. else
  18849. {
  18850. if (ptr.mType->IsOpaque())
  18851. {
  18852. mModule->Fail(StrFormat("Unable to assign to opaque type '%s'", mModule->TypeToString(ptr.mType).c_str()), assignExpr);
  18853. }
  18854. else if (ptr.mType->IsValuelessType())
  18855. {
  18856. mModule->EmitEnsureInstructionAt();
  18857. }
  18858. else if (!alreadyWritten)
  18859. {
  18860. if ((mModule->mIsComptimeModule) && (mModule->mCompiler->mCeMachine->mDebugger != NULL) && (mModule->mCompiler->mCeMachine->mDebugger->mCurDbgState != NULL))
  18861. {
  18862. auto ceDbgState = mModule->mCompiler->mCeMachine->mDebugger->mCurDbgState;
  18863. bool success = false;
  18864. if ((convVal.mValue.IsConst()) && (ptr.mValue.IsConst()))
  18865. {
  18866. auto constant = mModule->mBfIRBuilder->GetConstant(ptr.mValue);
  18867. auto valConstant = mModule->mBfIRBuilder->GetConstant(convVal.mValue);
  18868. auto ceTypedVal = mModule->mCompiler->mCeMachine->mDebugger->GetAddr(constant);
  18869. if (!ceTypedVal)
  18870. {
  18871. mModule->Fail("Invalid assignment address", assignExpr);
  18872. return;
  18873. }
  18874. auto ceContext = mModule->mCompiler->mCeMachine->mCurContext;
  18875. if (ceContext->CheckMemory((addr_ce)ceTypedVal.mAddr, convVal.mType->mSize))
  18876. {
  18877. if ((ceDbgState->mDbgExpressionFlags & DwEvalExpressionFlag_AllowSideEffects) != 0)
  18878. {
  18879. ceDbgState->mHadSideEffects = true;
  18880. if (ceContext->WriteConstant(mModule, (addr_ce)ceTypedVal.mAddr, valConstant, convVal.mType))
  18881. success = true;
  18882. }
  18883. else
  18884. {
  18885. ceDbgState->mBlockedSideEffects = true;
  18886. success = true;
  18887. }
  18888. }
  18889. }
  18890. if (!success)
  18891. {
  18892. mModule->Fail("Assignment failed", assignExpr);
  18893. return;
  18894. }
  18895. }
  18896. if (!alreadyWritten)
  18897. {
  18898. //ptr = mModule->LoadValue(ptr);
  18899. BF_ASSERT(ptr.IsAddr());
  18900. convVal = mModule->LoadValue(convVal);
  18901. auto storeInst = mModule->mBfIRBuilder->CreateAlignedStore(convVal.mValue, ptr.mValue, ptr.mType->mAlign, mIsVolatileReference);
  18902. }
  18903. }
  18904. }
  18905. }
  18906. }
  18907. else
  18908. {
  18909. BF_ASSERT(convVal.mType->IsValuelessType());
  18910. }
  18911. mResult = convVal;
  18912. MarkResultAssigned();
  18913. }
  18914. void BfExprEvaluator::Visit(BfAssignmentExpression* assignExpr)
  18915. {
  18916. if (assignExpr->mLeft->IsA<BfTupleExpression>())
  18917. {
  18918. DoTupleAssignment(assignExpr);
  18919. return;
  18920. }
  18921. BfAutoParentNodeEntry autoParentNodeEntry(mModule, assignExpr);
  18922. BfTypedValue cascadeValue;
  18923. PerformAssignment(assignExpr, false, BfTypedValue(), &cascadeValue);
  18924. if (cascadeValue)
  18925. mResult = cascadeValue;
  18926. }
  18927. void BfExprEvaluator::Visit(BfParenthesizedExpression* parenExpr)
  18928. {
  18929. VisitChild(parenExpr->mExpression);
  18930. MakeResultAsValue();
  18931. }
  18932. void BfExprEvaluator::InitializedSizedArray(BfSizedArrayType* arrayType, BfTokenNode* openToken, const BfSizedArray<BfExpression*>& valueExprs, const BfSizedArray<BfTokenNode*>& commas, BfTokenNode* closeToken, BfTypedValue* receivingValue)
  18933. {
  18934. struct InitValue
  18935. {
  18936. BfTypedValue mValue;
  18937. bool mIsUninitialized;
  18938. bool mIsDefaultInitializer;
  18939. bool mIsDeferred;
  18940. InitValue()
  18941. {
  18942. mIsUninitialized = false;
  18943. mIsDefaultInitializer = false;
  18944. mIsDeferred = false;
  18945. }
  18946. };
  18947. SizedArray<InitValue, 8> values;
  18948. {
  18949. //bool hasFailed = false;
  18950. HashSet<int> failedAt;
  18951. bool isAllConst = true;
  18952. //bool endUninitialzied = false;
  18953. int depth = 0;
  18954. std::function<void(BfSizedArrayType*, BfTokenNode* openToken, const BfSizedArray<BfExpression*>&, const BfSizedArray<BfTokenNode*>&, BfTokenNode*, bool)>
  18955. _GetValues = [&](BfSizedArrayType* checkArrayType, BfTokenNode* openToken, const BfSizedArray<BfExpression*>& valueExprs, const BfSizedArray<BfTokenNode*>& commas, BfTokenNode* closeToken, bool ignore)
  18956. {
  18957. int64 initCountDiff = (int)valueExprs.size() - checkArrayType->mElementCount;
  18958. if ((initCountDiff != 0) && (!valueExprs.IsEmpty()) && (!failedAt.Contains(depth)))
  18959. {
  18960. if (checkArrayType->mElementCount == -1)
  18961. {
  18962. // mModule->Fail("Initializers not supported for unknown-sized arrays", valueExprs[0]);
  18963. // failedAt.Add(depth);
  18964. }
  18965. else if (initCountDiff > 0)
  18966. {
  18967. mModule->Fail(StrFormat("Too many initializers, expected %d fewer", initCountDiff), valueExprs[BF_MAX((int)checkArrayType->mElementCount, 0)]);
  18968. failedAt.Add(depth);
  18969. }
  18970. else
  18971. {
  18972. // If it ends with ", ?) or ",)" then allow unsized
  18973. if (((valueExprs.size() == 0) || (BfNodeDynCast<BfUninitializedExpression>(valueExprs.back()) == NULL)) &&
  18974. ((commas.size() < valueExprs.size()) || (valueExprs.size() == 0)))
  18975. {
  18976. BfAstNode* refNode = closeToken;
  18977. if ((refNode == NULL) && (mModule->mParentNodeEntry != NULL))
  18978. refNode = mModule->mParentNodeEntry->mNode;
  18979. BF_ASSERT(refNode != NULL);
  18980. mModule->Fail(StrFormat("Too few initializer, expected %d more", -initCountDiff), refNode);
  18981. failedAt.Add(depth);
  18982. }
  18983. }
  18984. }
  18985. for (int idx = 0; idx < BF_MAX(checkArrayType->mElementCount, valueExprs.size()); idx++)
  18986. {
  18987. BfTypedValue elementValue;
  18988. bool deferredValue = false;
  18989. BfExpression* expr = NULL;
  18990. if (idx < (int)valueExprs.size())
  18991. {
  18992. expr = valueExprs[idx];
  18993. if (expr == NULL)
  18994. {
  18995. if (idx == 0)
  18996. mModule->FailAfter("Expression expected", openToken);
  18997. else
  18998. mModule->FailAfter("Expression expected", commas[idx - 1]);
  18999. }
  19000. if ((BfNodeDynCastExact<BfUninitializedExpression>(expr) != NULL) && (idx == (int)commas.size()))
  19001. {
  19002. isAllConst = false;
  19003. break;
  19004. }
  19005. if (checkArrayType->mElementType->IsSizedArray())
  19006. {
  19007. if (auto arrayInitExpr = BfNodeDynCast<BfTupleExpression>(expr))
  19008. {
  19009. depth++;
  19010. _GetValues((BfSizedArrayType*)checkArrayType->mElementType, arrayInitExpr->mOpenParen, arrayInitExpr->mValues, arrayInitExpr->mCommas, arrayInitExpr->mCloseParen, ignore);
  19011. depth--;
  19012. continue;
  19013. }
  19014. else if (auto arrayInitExpr = BfNodeDynCast<BfCollectionInitializerExpression>(expr))
  19015. {
  19016. depth++;
  19017. _GetValues((BfSizedArrayType*)checkArrayType->mElementType, arrayInitExpr->mOpenBrace, arrayInitExpr->mValues, arrayInitExpr->mCommas, arrayInitExpr->mCloseBrace, ignore);
  19018. depth--;
  19019. continue;
  19020. }
  19021. else if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(expr))
  19022. {
  19023. depth++;
  19024. SizedArray<BfExpression*, 1> values;
  19025. values.Add(parenExpr->mExpression);
  19026. SizedArray<BfTokenNode*, 1> commas;
  19027. _GetValues((BfSizedArrayType*)checkArrayType->mElementType, parenExpr->mOpenParen, values, commas, parenExpr->mCloseParen, ignore);
  19028. depth--;
  19029. continue;
  19030. }
  19031. }
  19032. if (expr != NULL)
  19033. {
  19034. auto evalFlags = (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags);
  19035. bool tryDefer = false;
  19036. if ((checkArrayType->IsComposite()) &&
  19037. ((expr->IsA<BfInvocationExpression>()) || (expr->IsExact<BfTupleExpression>())))
  19038. {
  19039. // We evaluate with a new scope because this expression may create variables that we don't want to be visible to other
  19040. // non-deferred evaluations (since the value may actually be a FakeVal)
  19041. SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
  19042. elementValue = mModule->CreateValueFromExpression(expr, checkArrayType->mElementType, (BfEvalExprFlags)(evalFlags | BfEvalExprFlags_CreateConditionalScope));
  19043. deferredValue = !prevIgnoreWrites.mPrevVal && elementValue.mValue.IsFake();
  19044. }
  19045. else
  19046. {
  19047. elementValue = mModule->CreateValueFromExpression(expr, checkArrayType->mElementType, evalFlags);
  19048. }
  19049. if (!elementValue)
  19050. elementValue = mModule->GetDefaultTypedValue(checkArrayType->mElementType);
  19051. if ((!elementValue) || (!CheckAllowValue(elementValue, expr)))
  19052. elementValue = mModule->GetDefaultTypedValue(checkArrayType->mElementType);
  19053. // For now, we can't properly create const-valued non-size-aligned composites
  19054. if (!elementValue.mValue.IsConst())
  19055. isAllConst = false;
  19056. if (elementValue.IsAddr())
  19057. isAllConst = false;
  19058. InitValue initValue;
  19059. initValue.mValue = elementValue;
  19060. initValue.mIsDeferred = deferredValue;
  19061. values.push_back(initValue);
  19062. }
  19063. }
  19064. }
  19065. };
  19066. int valueIdx = 0;
  19067. std::function<void(BfTypedValue, BfTokenNode* openToken, const BfSizedArray<BfExpression*>&, const BfSizedArray<BfTokenNode*>&, BfTokenNode*)>
  19068. _CreateMemArray = [&](BfTypedValue arrayValue, BfTokenNode* openToken, const BfSizedArray<BfExpression*>& valueExprs, const BfSizedArray<BfTokenNode*>& commas, BfTokenNode* closeToken)
  19069. {
  19070. BF_ASSERT(arrayValue.mType->IsSizedArray());
  19071. auto checkArrayType = (BfSizedArrayType*)arrayValue.mType;
  19072. int valIdx = 0;
  19073. bool hasUninit = false;
  19074. for (int idx = 0; idx < checkArrayType->mElementCount; idx++)
  19075. {
  19076. BfExpression* expr = NULL;
  19077. BfTypedValue elementValue;
  19078. if (idx >= (int)valueExprs.size())
  19079. break;
  19080. expr = valueExprs[idx];
  19081. if ((BfNodeDynCastExact<BfUninitializedExpression>(expr) != NULL) && (idx == (int)commas.size()))
  19082. {
  19083. hasUninit = true;
  19084. break;
  19085. }
  19086. BfIRValue elemPtrValue = mModule->CreateIndexedValue(checkArrayType->mElementType, arrayValue.mValue, valIdx, true);
  19087. valIdx++;
  19088. if (checkArrayType->mElementType->IsSizedArray())
  19089. {
  19090. if (auto arrayInitExpr = BfNodeDynCast<BfTupleExpression>(expr))
  19091. {
  19092. _CreateMemArray(BfTypedValue(elemPtrValue, checkArrayType->mElementType, true), arrayInitExpr->mOpenParen, arrayInitExpr->mValues, arrayInitExpr->mCommas, arrayInitExpr->mCloseParen);
  19093. continue;
  19094. }
  19095. else if (auto arrayInitExpr = BfNodeDynCast<BfCollectionInitializerExpression>(expr))
  19096. {
  19097. _CreateMemArray(BfTypedValue(elemPtrValue, checkArrayType->mElementType, true), arrayInitExpr->mOpenBrace, arrayInitExpr->mValues, arrayInitExpr->mCommas, arrayInitExpr->mCloseBrace);
  19098. continue;
  19099. }
  19100. else if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(expr))
  19101. {
  19102. depth++;
  19103. SizedArray<BfExpression*, 1> values;
  19104. values.Add(parenExpr->mExpression);
  19105. SizedArray<BfTokenNode*, 1> commas;
  19106. _CreateMemArray(BfTypedValue(elemPtrValue, checkArrayType->mElementType, true), parenExpr->mOpenParen, values, commas, parenExpr->mCloseParen);
  19107. depth--;
  19108. continue;
  19109. }
  19110. }
  19111. if (expr != NULL)
  19112. {
  19113. InitValue initValue = values[valueIdx++];
  19114. elementValue = initValue.mValue;
  19115. if (initValue.mIsDeferred)
  19116. {
  19117. BfTypedValue elemePtrTypedVal = BfTypedValue(elemPtrValue, checkArrayType->mElementType, BfTypedValueKind_Addr);
  19118. BfExprEvaluator exprEvaluator(mModule);
  19119. exprEvaluator.mExpectingType = checkArrayType->mElementType;
  19120. exprEvaluator.mReceivingValue = &elemePtrTypedVal;
  19121. exprEvaluator.Evaluate(expr);
  19122. exprEvaluator.GetResult();
  19123. if (exprEvaluator.mReceivingValue == NULL)
  19124. {
  19125. // We wrote directly to the array in-place, we're done with this element
  19126. continue;
  19127. }
  19128. elementValue = exprEvaluator.mResult;
  19129. elementValue = mModule->Cast(expr, elementValue, checkArrayType->mElementType);
  19130. if (!elementValue)
  19131. {
  19132. mModule->AssertErrorState();
  19133. continue;
  19134. }
  19135. }
  19136. elementValue = mModule->LoadOrAggregateValue(elementValue);
  19137. // Note that elemPtrValue can be a const GEP on a global variable
  19138. mModule->mBfIRBuilder->CreateAlignedStore(elementValue.mValue, elemPtrValue, checkArrayType->mElementType->mAlign);
  19139. }
  19140. }
  19141. int fillCount = (int)(checkArrayType->mElementCount - valIdx);
  19142. if (fillCount > 0)
  19143. {
  19144. BfIRValue elemPtrValue = mModule->CreateIndexedValue(checkArrayType->mElementType, arrayValue.mValue, valIdx, true);
  19145. if (hasUninit)
  19146. {
  19147. if (!mModule->IsOptimized())
  19148. {
  19149. int setSize = std::min(checkArrayType->mElementType->mSize, 128); // Keep it to a reasonable number of bytes to trash
  19150. mModule->mBfIRBuilder->CreateMemSet(elemPtrValue, mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int8, 0xCC),
  19151. mModule->GetConstValue(setSize), checkArrayType->mElementType->mAlign);
  19152. }
  19153. }
  19154. else
  19155. {
  19156. int setSize = (int)((checkArrayType->mElementType->GetStride() * (fillCount - 1)) + checkArrayType->mElementType->mSize);
  19157. if (setSize >= 0)
  19158. {
  19159. mModule->mBfIRBuilder->CreateMemSet(elemPtrValue, mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int8, 0),
  19160. mModule->GetConstValue(setSize), checkArrayType->mElementType->mAlign);
  19161. }
  19162. }
  19163. }
  19164. };
  19165. std::function<BfIRValue(BfTypedValue, BfTokenNode*, const BfSizedArray<BfExpression*>&, const BfSizedArray<BfTokenNode*>&, BfTokenNode*)>
  19166. _CreateConstArray = [&](BfTypedValue arrayValue, BfTokenNode* openToken, const BfSizedArray<BfExpression*>& valueExprs, const BfSizedArray<BfTokenNode*>& commas, BfTokenNode* closeToken)
  19167. {
  19168. SizedArray<BfIRValue, 8> members;
  19169. BF_ASSERT(arrayValue.mType->IsSizedArray());
  19170. auto checkArrayType = (BfSizedArrayType*)arrayValue.mType;
  19171. int valIdx = 0;
  19172. for (int idx = 0; idx < checkArrayType->mElementCount; idx++)
  19173. {
  19174. BfTypedValue elementValue;
  19175. if (idx >= (int)valueExprs.size())
  19176. break;
  19177. auto expr = valueExprs[idx];
  19178. if (expr == NULL)
  19179. continue;
  19180. valIdx++;
  19181. if (checkArrayType->mElementType->IsSizedArray())
  19182. {
  19183. if (auto arrayInitExpr = BfNodeDynCast<BfTupleExpression>(expr))
  19184. {
  19185. members.push_back(_CreateConstArray(checkArrayType->mElementType, arrayInitExpr->mOpenParen, arrayInitExpr->mValues, arrayInitExpr->mCommas, arrayInitExpr->mCloseParen));
  19186. continue;
  19187. }
  19188. else if (auto arrayInitExpr = BfNodeDynCast<BfCollectionInitializerExpression>(expr))
  19189. {
  19190. members.push_back(_CreateConstArray(checkArrayType->mElementType, arrayInitExpr->mOpenBrace, arrayInitExpr->mValues, arrayInitExpr->mCommas, arrayInitExpr->mCloseBrace));
  19191. continue;
  19192. }
  19193. else if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(expr))
  19194. {
  19195. depth++;
  19196. SizedArray<BfExpression*, 1> values;
  19197. values.Add(parenExpr->mExpression);
  19198. SizedArray<BfTokenNode*, 1> commas;
  19199. members.push_back(_CreateConstArray(checkArrayType->mElementType, parenExpr->mOpenParen, values, commas, parenExpr->mCloseParen));
  19200. depth--;
  19201. continue;
  19202. }
  19203. }
  19204. InitValue initValue = values[valueIdx++];
  19205. BF_ASSERT(!initValue.mIsUninitialized);
  19206. elementValue = initValue.mValue;
  19207. members.push_back(elementValue.mValue);
  19208. }
  19209. int fillCount = (int)(checkArrayType->mElementCount - valIdx);
  19210. if (fillCount > 0)
  19211. {
  19212. // We just need to insert one default value, it will be duplicated as needed into the backend
  19213. auto defaultVal = mModule->GetDefaultTypedValue(checkArrayType->GetUnderlyingType());
  19214. BF_ASSERT(defaultVal.mValue.IsConst());
  19215. members.push_back(defaultVal.mValue);
  19216. }
  19217. auto allocArrayType = checkArrayType;
  19218. if (checkArrayType->IsUndefSizedArray())
  19219. allocArrayType = mModule->CreateSizedArrayType(checkArrayType->GetUnderlyingType(), (int)members.size());
  19220. return mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(checkArrayType), members);
  19221. };
  19222. _GetValues(arrayType, openToken, valueExprs, commas, closeToken, false);
  19223. if (!failedAt.IsEmpty())
  19224. {
  19225. mResult = mModule->GetDefaultTypedValue(arrayType, false, BfDefaultValueKind_Addr);
  19226. return;
  19227. }
  19228. if (receivingValue != NULL)
  19229. {
  19230. BF_ASSERT(receivingValue->mType == arrayType);
  19231. BF_ASSERT(receivingValue->IsAddr());
  19232. mResult = *receivingValue;
  19233. _CreateMemArray(mResult, openToken, valueExprs, commas, closeToken);
  19234. }
  19235. else if (isAllConst)
  19236. {
  19237. mResult = BfTypedValue(_CreateConstArray(arrayType, openToken, valueExprs, commas, closeToken), arrayType, BfTypedValueKind_Value);
  19238. }
  19239. else
  19240. {
  19241. if ((mReceivingValue != NULL) && (mReceivingValue->mType == arrayType) && (mReceivingValue->IsAddr()))
  19242. {
  19243. mResult = *mReceivingValue;
  19244. mReceivingValue = NULL;
  19245. }
  19246. else
  19247. {
  19248. auto arrayValue = mModule->CreateAlloca(arrayType);
  19249. mResult = BfTypedValue(arrayValue, arrayType, BfTypedValueKind_TempAddr);
  19250. }
  19251. if (!arrayType->IsValuelessType())
  19252. _CreateMemArray(mResult, openToken, valueExprs, commas, closeToken);
  19253. }
  19254. }
  19255. }
  19256. void BfExprEvaluator::Visit(BfTupleExpression* tupleExpr)
  19257. {
  19258. BfTypeInstance* tupleType = NULL;
  19259. bool hadFullMatch = false;
  19260. if ((mExpectingType != NULL) && (mExpectingType->IsTuple()))
  19261. {
  19262. tupleType = (BfTypeInstance*)mExpectingType;
  19263. hadFullMatch = tupleType->mFieldInstances.size() == tupleExpr->mValues.size();
  19264. }
  19265. struct InitValue
  19266. {
  19267. BfTypedValue mValue;
  19268. bool mIsUninitialized;
  19269. bool mIsDefaultInitializer;
  19270. bool mIsDeferred;
  19271. InitValue()
  19272. {
  19273. mIsUninitialized = false;
  19274. mIsDefaultInitializer = false;
  19275. mIsDeferred = false;
  19276. }
  19277. };
  19278. SizedArray<BfTypedValue, 2> typedValues;
  19279. if ((tupleExpr->mCommas.size() != 0) && (tupleExpr->mCommas.size() >= tupleExpr->mValues.size()))
  19280. {
  19281. // We would normally give this error during syntax parsing, but a TupleExpression can be an array initializer
  19282. mModule->FailAfter("Expression expected", tupleExpr->mCommas.back());
  19283. }
  19284. for (int valueIdx = 0; valueIdx < (int)tupleExpr->mValues.size(); valueIdx++)
  19285. {
  19286. BfExpression* valueExpr = tupleExpr->mValues[valueIdx];
  19287. BfType* fieldType = NULL;
  19288. BfFieldInstance* fieldInstance = NULL;
  19289. if (tupleType != NULL)
  19290. {
  19291. if (valueIdx < (int)tupleType->mFieldInstances.size())
  19292. {
  19293. fieldInstance = (BfFieldInstance*)&tupleType->mFieldInstances[valueIdx];
  19294. fieldType = fieldInstance->GetResolvedType();
  19295. if (fieldType->IsVoid())
  19296. {
  19297. typedValues.push_back(BfTypedValue());
  19298. continue;
  19299. }
  19300. if (fieldType->IsVar())
  19301. {
  19302. hadFullMatch = false;
  19303. fieldType = NULL;
  19304. }
  19305. }
  19306. }
  19307. bool tryDefer = false;
  19308. if (((fieldType == NULL) || (fieldType->IsComposite())) &&
  19309. ((valueExpr->IsA<BfInvocationExpression>()) || (valueExpr->IsExact<BfTupleExpression>())))
  19310. {
  19311. tryDefer = true;
  19312. }
  19313. SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, mModule->mBfIRBuilder->mIgnoreWrites || tryDefer);
  19314. BfTypedValue value = mModule->CreateValueFromExpression(valueExpr, fieldType);
  19315. if (!value)
  19316. {
  19317. if (fieldType != NULL)
  19318. value = mModule->GetDefaultTypedValue(fieldType);
  19319. else
  19320. value = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  19321. }
  19322. if ((fieldInstance != NULL) && (!fieldInstance->GetFieldDef()->IsUnnamedTupleField()) && (valueIdx < (int)tupleExpr->mNames.size()))
  19323. {
  19324. auto checkName = tupleExpr->mNames[valueIdx];
  19325. if (checkName != NULL)
  19326. {
  19327. if (checkName->ToString() != fieldInstance->GetFieldDef()->mName)
  19328. hadFullMatch = false;
  19329. }
  19330. }
  19331. value = mModule->LoadValue(value);
  19332. typedValues.push_back(value);
  19333. }
  19334. if (!hadFullMatch)
  19335. {
  19336. BfTypeVector fieldTypes;
  19337. Array<String> fieldNames;
  19338. HashSet<String> fieldNameSet;
  19339. for (auto typedVal : typedValues)
  19340. {
  19341. auto type = typedVal.mType;
  19342. if (type != NULL)
  19343. fieldTypes.push_back(type);
  19344. else
  19345. fieldTypes.push_back(mModule->mContext->mBfObjectType);
  19346. }
  19347. for (BfTupleNameNode* requestedName : tupleExpr->mNames)
  19348. {
  19349. if (requestedName == NULL)
  19350. fieldNames.push_back("");
  19351. else
  19352. {
  19353. auto fieldName = requestedName->mNameNode->ToString();
  19354. if (!fieldNameSet.TryAdd(fieldName, NULL))
  19355. {
  19356. mModule->Fail(StrFormat("A field named '%s' has already been declared", fieldName.c_str()), requestedName->mNameNode);
  19357. }
  19358. fieldNames.push_back(fieldName);
  19359. }
  19360. }
  19361. tupleType = mModule->CreateTupleType(fieldTypes, fieldNames);
  19362. }
  19363. mModule->mBfIRBuilder->PopulateType(tupleType);
  19364. BfIRValue curTupleValue;
  19365. if ((mReceivingValue != NULL) && (mReceivingValue->mType == tupleType) && (mReceivingValue->IsAddr()))
  19366. {
  19367. mResult = *mReceivingValue;
  19368. mReceivingValue = NULL;
  19369. curTupleValue = mResult.mValue;
  19370. }
  19371. else
  19372. {
  19373. int valueIdx = -1;
  19374. bool isExactConst = true;
  19375. for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
  19376. {
  19377. BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx];
  19378. if (fieldInstance->mDataIdx < 0)
  19379. continue;
  19380. ++valueIdx;
  19381. auto typedValue = typedValues[valueIdx];
  19382. if (typedValue.mType != fieldInstance->mResolvedType)
  19383. {
  19384. isExactConst = false;
  19385. break;
  19386. }
  19387. if (!typedValue.mValue.IsConst())
  19388. {
  19389. isExactConst = false;
  19390. break;
  19391. }
  19392. }
  19393. if (isExactConst)
  19394. {
  19395. mModule->PopulateType(tupleType);
  19396. if (tupleType->IsDataIncomplete())
  19397. return;
  19398. Array<BfIRValue> irValues;
  19399. irValues.Resize(typedValues.mSize + 1);
  19400. irValues[0] = mModule->mBfIRBuilder->CreateConstAggZero(mModule->mBfIRBuilder->MapType(tupleType->mBaseType));
  19401. for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
  19402. {
  19403. BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx];
  19404. if (fieldInstance->mDataIdx < 0)
  19405. continue;
  19406. while (fieldInstance->mDataIdx >= irValues.size())
  19407. irValues.Add(BfIRValue());
  19408. irValues[fieldInstance->mDataIdx] = typedValues[fieldIdx].mValue;
  19409. }
  19410. for (auto& val : irValues)
  19411. {
  19412. if (!val)
  19413. val = mModule->mBfIRBuilder->CreateConstArrayZero(0);
  19414. }
  19415. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(tupleType), irValues), tupleType);
  19416. return;
  19417. }
  19418. curTupleValue = mModule->CreateAlloca(tupleType);
  19419. mResultIsTempComposite = true;
  19420. mResult = BfTypedValue(curTupleValue, tupleType, BfTypedValueKind_TempAddr);
  19421. }
  19422. int valueIdx = -1;
  19423. for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
  19424. {
  19425. BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx];
  19426. ++valueIdx;
  19427. if (fieldInstance->mResolvedType->IsValuelessType())
  19428. continue;
  19429. auto typedVal = typedValues[valueIdx];
  19430. if (!typedVal)
  19431. {
  19432. mModule->AssertErrorState();
  19433. continue;
  19434. }
  19435. if (fieldInstance->mDataIdx >= 0)
  19436. {
  19437. auto memberVal = mModule->mBfIRBuilder->CreateInBoundsGEP(curTupleValue, 0, fieldInstance->mDataIdx);
  19438. if ((!mModule->mBfIRBuilder->mIgnoreWrites) && (typedVal.mValue.IsFake()))
  19439. {
  19440. // Value was deferred. Allow us to try to init in place
  19441. BfExpression* valueExpr = tupleExpr->mValues[valueIdx];
  19442. BfTypedValue memberPtrTypedVal = BfTypedValue(memberVal, fieldInstance->mResolvedType, BfTypedValueKind_Addr);
  19443. BfExprEvaluator exprEvaluator(mModule);
  19444. exprEvaluator.mExpectingType = fieldInstance->mResolvedType;
  19445. exprEvaluator.mReceivingValue = &memberPtrTypedVal;
  19446. exprEvaluator.Evaluate(valueExpr);
  19447. exprEvaluator.GetResult();
  19448. if (exprEvaluator.mReceivingValue == NULL)
  19449. {
  19450. // We wrote directly to the array in-place, we're done with this element
  19451. continue;
  19452. }
  19453. typedVal = exprEvaluator.mResult;
  19454. typedVal = mModule->Cast(valueExpr, typedVal, fieldInstance->mResolvedType);
  19455. if (!typedVal)
  19456. {
  19457. mModule->AssertErrorState();
  19458. continue;
  19459. }
  19460. typedVal = mModule->LoadValue(typedVal);
  19461. }
  19462. if (typedVal.mType->IsVar())
  19463. {
  19464. // Do nothing
  19465. }
  19466. else if (typedVal.IsSplat())
  19467. mModule->AggregateSplatIntoAddr(typedVal, memberVal);
  19468. else
  19469. mModule->mBfIRBuilder->CreateAlignedStore(typedVal.mValue, memberVal, typedVal.mType->mAlign);
  19470. }
  19471. }
  19472. }
  19473. BfTypedValue BfExprEvaluator::SetupNullConditional(BfTypedValue thisValue, BfTokenNode* dotToken)
  19474. {
  19475. bool isStaticLookup = (!thisValue) ||
  19476. ((!thisValue.mType->IsValuelessType()) && (!thisValue.mValue));
  19477. if (isStaticLookup)
  19478. {
  19479. mModule->Fail("Null conditional reference not valid for static field references", dotToken);
  19480. return thisValue;
  19481. }
  19482. auto opResult = PerformUnaryOperation_TryOperator(thisValue, NULL, BfUnaryOp_NullConditional, dotToken, BfUnaryOpFlag_None);
  19483. if (opResult)
  19484. thisValue = opResult;
  19485. if (thisValue.mType->IsGenericParam())
  19486. {
  19487. bool isValid = false;
  19488. auto genericParams = mModule->GetGenericParamInstance((BfGenericParamType*)thisValue.mType);
  19489. if (genericParams->mTypeConstraint != NULL)
  19490. {
  19491. if ((genericParams->mTypeConstraint->IsNullable()) ||
  19492. (genericParams->mTypeConstraint->IsPointer()) ||
  19493. (genericParams->mTypeConstraint->IsObjectOrInterface()))
  19494. isValid = true;
  19495. }
  19496. if ((genericParams->mGenericParamFlags & (BfGenericParamFlag_Var | BfGenericParamFlag_StructPtr | BfGenericParamFlag_Class)) != 0)
  19497. isValid = true;
  19498. if (isValid)
  19499. return thisValue;
  19500. }
  19501. if ((thisValue.mType->IsNullable()) || (thisValue.mType->IsVar()))
  19502. {
  19503. // Success
  19504. }
  19505. else if ((thisValue.mType->IsPointer()) || (thisValue.mType->IsObjectOrInterface()) || (thisValue.mType->IsFunction()))
  19506. {
  19507. // Also good
  19508. }
  19509. else
  19510. {
  19511. bool canBeNull = false;
  19512. if (thisValue.mType->IsGenericParam())
  19513. canBeNull = true;
  19514. if (!canBeNull)
  19515. mModule->Warn(0, StrFormat("Null conditional reference is unnecessary since value type '%s' can never be null", mModule->TypeToString(thisValue.mType).c_str()), dotToken);
  19516. return thisValue;
  19517. }
  19518. thisValue = mModule->LoadValue(thisValue);
  19519. if (thisValue.mType->IsVar())
  19520. return thisValue;
  19521. BfPendingNullConditional* pendingNullCond = mModule->mCurMethodState->mPendingNullConditional;
  19522. if (pendingNullCond == NULL)
  19523. {
  19524. pendingNullCond = new BfPendingNullConditional();
  19525. mModule->mCurMethodState->mPendingNullConditional = pendingNullCond;
  19526. }
  19527. if (!pendingNullCond->mPrevBB)
  19528. pendingNullCond->mPrevBB = mModule->mBfIRBuilder->GetInsertBlock();
  19529. if (!pendingNullCond->mDoneBB)
  19530. pendingNullCond->mDoneBB = mModule->mBfIRBuilder->CreateBlock("nullCond.done");
  19531. // We will in the br to checkBB later
  19532. if (!pendingNullCond->mCheckBB)
  19533. {
  19534. pendingNullCond->mCheckBB = mModule->mBfIRBuilder->CreateBlock("nullCond.check");
  19535. mModule->AddBasicBlock(pendingNullCond->mCheckBB);
  19536. }
  19537. BfIRValue isNotNull;
  19538. if (thisValue.mType->IsNullable())
  19539. {
  19540. BfTypeInstance* nullableType = (BfTypeInstance*)thisValue.mType->ToTypeInstance();
  19541. auto elementType = nullableType->GetUnderlyingType();
  19542. if (elementType->IsValuelessType())
  19543. {
  19544. thisValue = mModule->MakeAddressable(thisValue);
  19545. BfIRValue hasValuePtr = mModule->mBfIRBuilder->CreateInBoundsGEP(thisValue.mValue, 0, 1); // mHasValue
  19546. isNotNull = mModule->mBfIRBuilder->CreateAlignedLoad(hasValuePtr, 1);
  19547. thisValue = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), elementType, true);
  19548. }
  19549. else
  19550. {
  19551. thisValue = mModule->MakeAddressable(thisValue);
  19552. BfIRValue hasValuePtr = mModule->mBfIRBuilder->CreateInBoundsGEP(thisValue.mValue, 0, 2); // mHasValue
  19553. isNotNull = mModule->mBfIRBuilder->CreateAlignedLoad(hasValuePtr, 1);
  19554. BfIRValue valuePtr = mModule->mBfIRBuilder->CreateInBoundsGEP(thisValue.mValue, 0, 1); // mValue
  19555. thisValue = BfTypedValue(valuePtr, elementType, true);
  19556. }
  19557. }
  19558. else if (thisValue.mType->IsFunction())
  19559. {
  19560. isNotNull = mModule->mBfIRBuilder->CreateCmpNE(thisValue.mValue, mModule->GetDefaultValue(thisValue.mType));
  19561. }
  19562. else
  19563. isNotNull = mModule->mBfIRBuilder->CreateIsNotNull(thisValue.mValue);
  19564. BfIRBlock notNullBB = mModule->mBfIRBuilder->CreateBlock("nullCond.notNull");
  19565. pendingNullCond->mNotNullBBs.Add(notNullBB);
  19566. mModule->mBfIRBuilder->CreateCondBr(isNotNull, notNullBB, pendingNullCond->mDoneBB);
  19567. mModule->AddBasicBlock(notNullBB);
  19568. return thisValue;
  19569. }
  19570. void BfExprEvaluator::CheckDotToken(BfTokenNode* tokenNode)
  19571. {
  19572. if ((tokenNode != NULL) && (tokenNode->mToken == BfToken_DotDot))
  19573. mModule->Fail("Unexpected cascade operation. Chaining can only be used for method invocations", tokenNode);
  19574. }
  19575. void BfExprEvaluator::DoMemberReference(BfMemberReferenceExpression* memberRefExpr, BfTypedValue* outCascadeValue)
  19576. {
  19577. CheckDotToken(memberRefExpr->mDotToken);
  19578. BfAttributeState attributeState;
  19579. attributeState.mTarget = (BfAttributeTargets)(BfAttributeTargets_MemberAccess);
  19580. String findName;
  19581. BfAstNode* nameRefNode = memberRefExpr->mMemberName;
  19582. if (auto attrIdentifierExpr = BfNodeDynCast<BfAttributedIdentifierNode>(memberRefExpr->mMemberName))
  19583. {
  19584. nameRefNode = attrIdentifierExpr->mIdentifier;
  19585. // Don't validate
  19586. attributeState.mCustomAttributes = mModule->GetCustomAttributes(attrIdentifierExpr->mAttributes, BfAttributeTargets_SkipValidate);
  19587. if (nameRefNode != NULL)
  19588. findName = attrIdentifierExpr->mIdentifier->ToString();
  19589. }
  19590. else if (memberRefExpr->mMemberName != NULL)
  19591. findName = memberRefExpr->mMemberName->ToString();
  19592. else if (memberRefExpr->mDotToken != NULL)
  19593. mModule->FailAfter("Member name expected", memberRefExpr->mDotToken);
  19594. defer
  19595. (
  19596. if (attributeState.mCustomAttributes != NULL)
  19597. {
  19598. if (mPropDef != NULL)
  19599. attributeState.mTarget = (BfAttributeTargets)(attributeState.mTarget | BfAttributeTargets_Invocation);
  19600. mModule->ValidateCustomAttributes(attributeState.mCustomAttributes, attributeState.mTarget);
  19601. }
  19602. );
  19603. SetAndRestoreValue<BfAttributeState*> prevAttributeState(mModule->mAttributeState, &attributeState);
  19604. BfTypeInstance* expectingTypeInst = NULL;
  19605. if (mExpectingType != NULL)
  19606. {
  19607. expectingTypeInst = mExpectingType->ToTypeInstance();
  19608. if (mExpectingType->IsPointer())
  19609. expectingTypeInst = mExpectingType->GetUnderlyingType()->ToTypeInstance();
  19610. else if (mExpectingType->IsNullable())
  19611. expectingTypeInst = mExpectingType->GetUnderlyingType()->ToTypeInstance();
  19612. else if (mExpectingType->IsConstExprValue())
  19613. expectingTypeInst = mExpectingType->GetUnderlyingType()->ToTypeInstance();
  19614. else if (mExpectingType->IsGenericParam())
  19615. {
  19616. auto genericParam = mModule->GetGenericParamInstance((BfGenericParamType*)mExpectingType);
  19617. if (genericParam->mTypeConstraint != NULL)
  19618. expectingTypeInst = genericParam->mTypeConstraint->ToTypeInstance();
  19619. }
  19620. }
  19621. BfAutoComplete* autoComplete = GetAutoComplete();
  19622. if (autoComplete != NULL)
  19623. {
  19624. SetAndRestoreValue<bool> prevFriendSet(autoComplete->mHasFriendSet, (attributeState.mCustomAttributes != NULL) && (attributeState.mCustomAttributes->Contains(mModule->mCompiler->mFriendAttributeTypeDef)));
  19625. if (memberRefExpr->mTarget == NULL)
  19626. {
  19627. String filter;
  19628. if ((mExpectingType != NULL) &&
  19629. (autoComplete->InitAutocomplete(memberRefExpr->mDotToken, memberRefExpr->mMemberName, filter)))
  19630. {
  19631. if (expectingTypeInst != NULL)
  19632. {
  19633. bool allowPrivate = expectingTypeInst == mModule->mCurTypeInstance;
  19634. if (expectingTypeInst->IsEnum())
  19635. autoComplete->AddEnumTypeMembers(expectingTypeInst, filter, false, allowPrivate);
  19636. autoComplete->AddSelfResultTypeMembers(expectingTypeInst, expectingTypeInst, filter, allowPrivate);
  19637. }
  19638. }
  19639. else if ((expectingTypeInst != NULL) && (autoComplete->IsAutocompleteNode(memberRefExpr->mDotToken)) && (autoComplete->mIsGetDefinition))
  19640. {
  19641. if ((autoComplete->mDefType == NULL) &&
  19642. (autoComplete->mDefMethod == NULL) && (autoComplete->mDefField == NULL) &&
  19643. (autoComplete->mDefProp == NULL) && (expectingTypeInst->mTypeDef->mTypeDeclaration != NULL))
  19644. {
  19645. autoComplete->mDefType = expectingTypeInst->mTypeDef;
  19646. autoComplete->SetDefinitionLocation(expectingTypeInst->mTypeDef->mTypeDeclaration->mNameNode);
  19647. }
  19648. }
  19649. }
  19650. else
  19651. {
  19652. autoComplete->CheckMemberReference(memberRefExpr->mTarget, memberRefExpr->mDotToken, memberRefExpr->mMemberName, false, mExpectingType);
  19653. if (auto objCreateExpr = BfNodeDynCast<BfObjectCreateExpression>(memberRefExpr->mTarget))
  19654. {
  19655. // This handles a weird case where we have "obj a = new\nWhatever().Thing = 123;".
  19656. // That gets parsed as "Whatever()" being the type we want to create, and then referencing
  19657. // the "Thing" member of that new object.
  19658. //if (objCreateExpr->mArraySizeSpecifier == NULL)
  19659. CheckObjectCreateTypeRef(mExpectingType, objCreateExpr->mNewNode);
  19660. }
  19661. }
  19662. }
  19663. if (memberRefExpr->mTarget == NULL)
  19664. {
  19665. if (mExpectingType == NULL)
  19666. {
  19667. if (mModule->PreFail())
  19668. mModule->Fail("Unqualified dot syntax can only be used when the result type can be inferred", nameRefNode);
  19669. return;
  19670. }
  19671. if (mExpectingType->IsVar())
  19672. {
  19673. mResult = mModule->GetDefaultTypedValue(mExpectingType);
  19674. return;
  19675. }
  19676. if (mExpectingType->IsSizedArray())
  19677. {
  19678. expectingTypeInst = mModule->GetWrappedStructType(mExpectingType);
  19679. }
  19680. if (expectingTypeInst == NULL)
  19681. {
  19682. if (mModule->PreFail())
  19683. mModule->Fail(StrFormat("Unqualified dot syntax cannot be used with type '%s'", mModule->TypeToString(mExpectingType).c_str()), nameRefNode);
  19684. return;
  19685. }
  19686. BfTypedValue expectingVal(expectingTypeInst);
  19687. mResult = LookupField(memberRefExpr->mMemberName, expectingVal, findName);
  19688. if ((mResult) || (mPropDef != NULL))
  19689. return;
  19690. }
  19691. bool isNullCondLookup = (memberRefExpr->mDotToken != NULL) && (memberRefExpr->mDotToken->GetToken() == BfToken_QuestionDot);
  19692. bool isCascade = ((memberRefExpr->mDotToken != NULL) && (memberRefExpr->mDotToken->GetToken() == BfToken_DotDot));
  19693. bool isArrowLookup = ((memberRefExpr->mDotToken != NULL) && (memberRefExpr->mDotToken->GetToken() == BfToken_Arrow));
  19694. BfIdentifierNode* nameLeft = BfNodeDynCast<BfIdentifierNode>(memberRefExpr->mTarget);
  19695. BfIdentifierNode* nameRight = BfIdentifierCast(memberRefExpr->mMemberName);
  19696. if ((nameLeft != NULL) && (nameRight != NULL) && (!isNullCondLookup) && (!isCascade) && (!isArrowLookup))
  19697. {
  19698. bool hadError = false;
  19699. LookupQualifiedName(memberRefExpr, nameLeft, nameRight, true, &hadError);
  19700. if ((mResult) || (mPropDef != NULL))
  19701. return;
  19702. if (hadError)
  19703. return;
  19704. LookupQualifiedStaticField(memberRefExpr, nameLeft, nameRight, false);
  19705. return;
  19706. }
  19707. BfTypedValue thisValue;
  19708. if (auto exprTarget = BfNodeDynCast<BfExpression>(memberRefExpr->mTarget))
  19709. {
  19710. if (auto typeOfExpr = BfNodeDynCast<BfTypeOfExpression>(memberRefExpr->mTarget))
  19711. {
  19712. if (auto nameIdentifer = BfNodeDynCast<BfIdentifierNode>(memberRefExpr->mMemberName))
  19713. {
  19714. if (LookupTypeProp(typeOfExpr, nameIdentifer))
  19715. return;
  19716. }
  19717. }
  19718. //Hm, not using VisitChild broke our ability to write to a field for a not-initialized local struct
  19719. VisitChild(memberRefExpr->mTarget);
  19720. GetResult();
  19721. thisValue = mResult;
  19722. if (!thisValue)
  19723. {
  19724. if (auto targetIdentifier = BfNodeDynCast<BfIdentifierNode>(exprTarget))
  19725. {
  19726. thisValue = BfTypedValue(mModule->ResolveTypeRef(targetIdentifier, NULL, BfPopulateType_Declaration));
  19727. }
  19728. }
  19729. if (!thisValue.HasType())
  19730. return;
  19731. //thisValue = mResult;
  19732. }
  19733. else if (auto typeRef = BfNodeDynCast<BfTypeReference>(memberRefExpr->mTarget))
  19734. {
  19735. // Look up static field
  19736. thisValue = BfTypedValue(ResolveTypeRef(typeRef));
  19737. }
  19738. if (nameRefNode == NULL)
  19739. {
  19740. mModule->AssertErrorState();
  19741. return;
  19742. }
  19743. if (isNullCondLookup)
  19744. thisValue = SetupNullConditional(thisValue, memberRefExpr->mDotToken);
  19745. if ((isArrowLookup) && (thisValue))
  19746. thisValue = TryArrowLookup(thisValue, memberRefExpr->mDotToken);
  19747. auto nameNode = memberRefExpr->mMemberName;
  19748. if ((thisValue.mType != NULL) && (!thisValue.mType->IsTypeInstance()) && (!thisValue.mType->IsGenericParam()))
  19749. {
  19750. if (thisValue.mType->IsSizedArray())
  19751. {
  19752. if (thisValue.mType->IsValuelessType())
  19753. {
  19754. thisValue.mType = mModule->GetWrappedStructType(thisValue.mType);
  19755. thisValue.mValue = mModule->mBfIRBuilder->GetFakeVal();
  19756. }
  19757. else
  19758. {
  19759. thisValue = mModule->MakeAddressable(thisValue);
  19760. thisValue.mType = mModule->GetWrappedStructType(thisValue.mType);
  19761. thisValue.mValue = mModule->mBfIRBuilder->CreateBitCast(thisValue.mValue, mModule->mBfIRBuilder->MapTypeInstPtr(thisValue.mType->ToTypeInstance()));
  19762. }
  19763. }
  19764. else if (thisValue.mType->IsPointer())
  19765. {
  19766. // Leave alone
  19767. }
  19768. else if (thisValue.mType->IsWrappableType())
  19769. {
  19770. thisValue.mType = mModule->GetWrappedStructType(thisValue.mType);
  19771. }
  19772. }
  19773. BfTypedValue lookupVal = thisValue;
  19774. if (thisValue.mType != NULL)
  19775. {
  19776. auto lookupType = BindGenericType(nameNode, thisValue.mType);
  19777. if ((lookupType->IsGenericParam()) && (!thisValue.mType->IsGenericParam()))
  19778. {
  19779. bool prevUseMixinGenerics = false;
  19780. if (mModule->mCurMethodState->mMixinState != NULL)
  19781. {
  19782. prevUseMixinGenerics = mModule->mCurMethodState->mMixinState->mUseMixinGenerics;
  19783. mModule->mCurMethodState->mMixinState->mUseMixinGenerics = true;
  19784. }
  19785. // Try to lookup from generic binding
  19786. mResult = LookupField(nameRight, BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), lookupType), findName, BfLookupFieldFlag_BindOnly);
  19787. if (mModule->mCurMethodState->mMixinState != NULL)
  19788. mModule->mCurMethodState->mMixinState->mUseMixinGenerics = prevUseMixinGenerics;
  19789. if (mPropDef != NULL)
  19790. {
  19791. mOrigPropTarget = lookupVal;
  19792. return;
  19793. }
  19794. }
  19795. }
  19796. mResult = LookupField(nameRefNode, lookupVal, findName);
  19797. if ((!mResult) && (mPropDef == NULL))
  19798. {
  19799. if (thisValue.mType != NULL)
  19800. {
  19801. BfTypeInstance* typeInst = thisValue.mType->ToTypeInstance();
  19802. auto compiler = mModule->mCompiler;
  19803. if ((typeInst != NULL) && (compiler->IsAutocomplete()) && (compiler->mResolvePassData->mAutoComplete->CheckFixit(memberRefExpr->mMemberName)))
  19804. {
  19805. FixitAddMember(typeInst, mExpectingType, findName, !thisValue.mValue);
  19806. }
  19807. }
  19808. if ((!thisValue.mValue) && (thisValue.mType != NULL))
  19809. {
  19810. if (auto targetIdentifier = BfNodeDynCast<BfIdentifierNode>(memberRefExpr->mMemberName))
  19811. {
  19812. if ((mBfEvalExprFlags & BfEvalExprFlags_NameOf) != 0)
  19813. {
  19814. auto typeInst = thisValue.mType->ToTypeInstance();
  19815. if ((typeInst != NULL) && (CheckForMethodName(nameRight, typeInst, findName)))
  19816. return;
  19817. }
  19818. mResult.mType = mModule->ResolveInnerType(thisValue.mType, targetIdentifier, BfPopulateType_Declaration);
  19819. }
  19820. }
  19821. if ((memberRefExpr->mTarget == NULL) && (expectingTypeInst != NULL) && (autoComplete != NULL))
  19822. {
  19823. if (autoComplete->CheckFixit(memberRefExpr->mMemberName))
  19824. {
  19825. autoComplete->FixitAddCase(expectingTypeInst, memberRefExpr->mMemberName->ToString(), BfTypeVector());
  19826. }
  19827. }
  19828. if (mResult.mType == NULL)
  19829. {
  19830. if (mModule->PreFail())
  19831. {
  19832. if ((thisValue) && (thisValue.mType->IsPointer()) && (thisValue.mType->GetUnderlyingType()->IsObjectOrInterface()))
  19833. mModule->Fail(StrFormat("Members cannot be referenced on type '%s' because the type is a pointer to a reference type (ie: a double-reference).",
  19834. mModule->TypeToString(thisValue.mType).c_str()), nameRefNode);
  19835. else if (thisValue)
  19836. mModule->Fail(StrFormat("Unable to find member '%s' in '%s'", findName.c_str(), mModule->TypeToString(thisValue.mType).c_str()), nameRefNode);
  19837. else
  19838. mModule->Fail("Unable to find member", nameRefNode);
  19839. }
  19840. }
  19841. }
  19842. if ((isNullCondLookup) && (mPropDef == NULL))
  19843. mResult = GetResult();
  19844. if (isCascade)
  19845. {
  19846. if (outCascadeValue != NULL)
  19847. *outCascadeValue = thisValue;
  19848. else if (mModule->PreFail())
  19849. mModule->Fail("Unexpected cascade operation. Chaining can only be used for method invocations", memberRefExpr->mDotToken);
  19850. }
  19851. }
  19852. void BfExprEvaluator::Visit(BfMemberReferenceExpression* memberRefExpr)
  19853. {
  19854. DoMemberReference(memberRefExpr, NULL);
  19855. }
  19856. void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr)
  19857. {
  19858. HandleIndexerExpression(indexerExpr, BfTypedValue());
  19859. }
  19860. void BfExprEvaluator::HandleIndexerExpression(BfIndexerExpression* indexerExpr, BfTypedValue target)
  19861. {
  19862. BfAstNode* refNode = indexerExpr->mOpenBracket;
  19863. if (refNode == NULL)
  19864. refNode = indexerExpr->mTarget;
  19865. bool wantStatic = false;
  19866. // Try first as a non-static indexer, then as a static indexer
  19867. if (!target)
  19868. {
  19869. for (int pass = 0; pass < 2; pass++)
  19870. {
  19871. ///
  19872. {
  19873. SetAndRestoreValue<BfEvalExprFlags> prevFlags(mBfEvalExprFlags, (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_NoLookupError | BfEvalExprFlags_AllowBase), pass == 0);
  19874. VisitChild(indexerExpr->mTarget);
  19875. }
  19876. ResolveGenericType();
  19877. target = GetResult(true);
  19878. if (target)
  19879. break;
  19880. if (pass == 0)
  19881. {
  19882. SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, (mModule->mIgnoreErrors) || (pass == 0));
  19883. auto staticType = mModule->ResolveTypeRef(indexerExpr->mTarget, {});
  19884. if (staticType != NULL)
  19885. {
  19886. wantStatic = true;
  19887. target.mType = staticType;
  19888. break;
  19889. }
  19890. }
  19891. }
  19892. }
  19893. if (!target.HasType())
  19894. return;
  19895. if (target.mType->IsGenericParam())
  19896. {
  19897. auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)target.mType);
  19898. if (genericParamInstance->mTypeConstraint != NULL)
  19899. target.mType = genericParamInstance->mTypeConstraint;
  19900. }
  19901. BfCheckedKind checkedKind = BfCheckedKind_NotSet;
  19902. bool isInlined = false;
  19903. if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL))
  19904. {
  19905. if (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mInlineAttributeTypeDef))
  19906. {
  19907. isInlined = true;
  19908. mModule->mAttributeState->mUsed = true;
  19909. }
  19910. if (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mCheckedAttributeTypeDef))
  19911. {
  19912. checkedKind = BfCheckedKind_Checked;
  19913. mModule->mAttributeState->mUsed = true;
  19914. }
  19915. if (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mUncheckedAttributeTypeDef))
  19916. {
  19917. checkedKind = BfCheckedKind_Unchecked;
  19918. mModule->mAttributeState->mUsed = true;
  19919. }
  19920. }
  19921. // Avoid attempting to apply the current attributes to the indexer arguments
  19922. SetAndRestoreValue<BfAttributeState*> prevAttributeState(mModule->mAttributeState, NULL);
  19923. bool isNullCondLookup = (indexerExpr->mOpenBracket != NULL) && (indexerExpr->mOpenBracket->GetToken() == BfToken_QuestionLBracket);
  19924. if (isNullCondLookup)
  19925. target = SetupNullConditional(target, indexerExpr->mOpenBracket);
  19926. if (target.mType->IsVar())
  19927. {
  19928. mResult = BfTypedValue(mModule->GetDefaultValue(target.mType), target.mType, true);
  19929. return;
  19930. }
  19931. if ((target.mType->IsTypeInstance()) || (target.mType->IsGenericParam()))
  19932. {
  19933. BfGenericParamInstance* genericParamInstance = NULL;
  19934. if (target.mType->IsGenericParam())
  19935. genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)target.mType);
  19936. mIndexerValues.clear();
  19937. SizedArray<BfExpression*, 2> argExprs;
  19938. BfSizedArray<BfExpression*> sizedArgExprs(indexerExpr->mArguments);
  19939. BfResolvedArgs argValues(&sizedArgExprs);
  19940. ResolveArgValues(argValues, (BfResolveArgsFlags)(BfResolveArgsFlag_DeferParamEval | BfResolveArgsFlag_FromIndexer));
  19941. mIndexerValues = argValues.mResolvedArgs;
  19942. BfMethodMatcher methodMatcher(indexerExpr->mTarget, mModule, "[]", mIndexerValues, BfMethodGenericArguments());
  19943. methodMatcher.mCheckedKind = checkedKind;
  19944. BfMethodDef* methodDef = NULL;
  19945. auto startCheckTypeInst = target.mType->ToTypeInstance();
  19946. auto lookupType = target.mType;
  19947. if (lookupType != NULL)
  19948. {
  19949. lookupType = BindGenericType(refNode, lookupType);
  19950. if (lookupType->IsGenericParam())
  19951. startCheckTypeInst = NULL;
  19952. }
  19953. for (int pass = 0; pass < 2; pass++)
  19954. {
  19955. bool isFailurePass = pass == 1;
  19956. BfPropertyDef* foundProp = NULL;
  19957. BfTypeInstance* foundPropTypeInst = NULL;
  19958. BfBaseClassWalker baseClassWalker(lookupType, NULL, mModule, true);
  19959. while (true)
  19960. {
  19961. auto checkEntry = baseClassWalker.Next();
  19962. auto curCheckType = checkEntry.mTypeInstance;
  19963. if (curCheckType == NULL)
  19964. break;
  19965. BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None;
  19966. curCheckType->mTypeDef->PopulateMemberSets();
  19967. BfMemberSetEntry* entry;
  19968. BfPropertyDef* matchedProp = NULL;
  19969. BfPropertyDef* nextProp = NULL;
  19970. if (curCheckType->mTypeDef->mPropertySet.TryGetWith(String("[]"), &entry))
  19971. nextProp = (BfPropertyDef*)entry->mMemberDef;
  19972. while (nextProp != NULL)
  19973. {
  19974. auto prop = nextProp;
  19975. nextProp = nextProp->mNextWithSameName;
  19976. //TODO: Match against setMethod (minus last param) if we have no 'get' method
  19977. for (auto checkMethod : prop->mMethods)
  19978. {
  19979. if (checkMethod->mMethodType != BfMethodType_PropertyGetter)
  19980. continue;
  19981. if (checkMethod->mIsStatic != wantStatic)
  19982. continue;
  19983. if (checkMethod->mExplicitInterface != NULL)
  19984. continue;
  19985. auto autoComplete = GetAutoComplete();
  19986. bool wasCapturingMethodMatchInfo = false;
  19987. if (autoComplete != NULL)
  19988. {
  19989. // Set to false to make sure we don't capture method match info from 'params' array creation
  19990. wasCapturingMethodMatchInfo = autoComplete->mIsCapturingMethodMatchInfo;
  19991. autoComplete->mIsCapturingMethodMatchInfo = false;
  19992. }
  19993. defer
  19994. (
  19995. if (autoComplete != NULL)
  19996. autoComplete->mIsCapturingMethodMatchInfo = wasCapturingMethodMatchInfo;
  19997. );
  19998. if ((!isFailurePass) && (!methodMatcher.WantsCheckMethod(protectionCheckFlags, startCheckTypeInst, curCheckType, checkMethod)))
  19999. continue;
  20000. if (!methodMatcher.IsMemberAccessible(curCheckType, checkMethod->mDeclaringType))
  20001. continue;
  20002. methodMatcher.mCheckedKind = checkedKind;
  20003. methodMatcher.mTarget = target;
  20004. bool hadMatch = methodMatcher.CheckMethod(startCheckTypeInst, curCheckType, checkMethod, false);
  20005. if ((hadMatch) || (methodMatcher.mBackupMethodDef == checkMethod))
  20006. {
  20007. foundPropTypeInst = curCheckType;
  20008. foundProp = prop;
  20009. }
  20010. }
  20011. }
  20012. curCheckType = curCheckType->mBaseType;
  20013. }
  20014. if (foundProp != NULL)
  20015. {
  20016. mPropSrc = indexerExpr->mOpenBracket;
  20017. mPropDef = foundProp;
  20018. if (foundProp->mIsStatic)
  20019. {
  20020. mPropTarget = BfTypedValue(foundPropTypeInst);
  20021. }
  20022. else
  20023. {
  20024. if (target.mType != foundPropTypeInst)
  20025. mPropTarget = mModule->Cast(indexerExpr->mTarget, target, foundPropTypeInst);
  20026. else
  20027. mPropTarget = target;
  20028. }
  20029. mOrigPropTarget = mPropTarget;
  20030. if (isInlined)
  20031. mPropGetMethodFlags = (BfGetMethodInstanceFlags)(mPropGetMethodFlags | BfGetMethodInstanceFlag_ForceInline);
  20032. mPropCheckedKind = checkedKind;
  20033. if ((target.IsBase()) && (mPropDef->IsVirtual()))
  20034. mPropDefBypassVirtual = true;
  20035. return;
  20036. }
  20037. }
  20038. mModule->Fail("Unable to find indexer property", indexerExpr->mTarget);
  20039. return;
  20040. }
  20041. bool wantsChecks = checkedKind == BfCheckedKind_Checked;
  20042. if (checkedKind == BfCheckedKind_NotSet)
  20043. wantsChecks = mModule->GetDefaultCheckedKind() == BfCheckedKind_Checked;
  20044. if (target.mType->IsVar())
  20045. {
  20046. mResult = target;
  20047. return;
  20048. }
  20049. if ((!target.mType->IsPointer()) && (!target.mType->IsSizedArray()))
  20050. {
  20051. mModule->Fail("Expected pointer or array type", indexerExpr->mTarget);
  20052. return;
  20053. }
  20054. auto _GetDefaultResult = [&]()
  20055. {
  20056. return mModule->GetDefaultTypedValue(target.mType->GetUnderlyingType(), false, BfDefaultValueKind_Addr);
  20057. };
  20058. if (indexerExpr->mArguments.size() != 1)
  20059. {
  20060. mModule->Fail("Expected single index", indexerExpr->mOpenBracket);
  20061. mResult = _GetDefaultResult();
  20062. return;
  20063. }
  20064. if (indexerExpr->mArguments[0] == NULL)
  20065. {
  20066. mModule->AssertErrorState();
  20067. mResult = _GetDefaultResult();
  20068. return;
  20069. }
  20070. bool isUndefIndex = false;
  20071. auto indexArgument = mModule->CreateValueFromExpression(indexerExpr->mArguments[0], mModule->GetPrimitiveType(BfTypeCode_IntPtr), BfEvalExprFlags_NoCast);
  20072. if (!indexArgument)
  20073. return;
  20074. if (!indexArgument.mType->IsIntegral())
  20075. {
  20076. if (indexArgument.mType->IsVar())
  20077. {
  20078. isUndefIndex = true;
  20079. indexArgument = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_IntPtr), false, BfDefaultValueKind_Undef);
  20080. }
  20081. else
  20082. {
  20083. indexArgument = mModule->Cast(indexerExpr->mArguments[0], indexArgument, mModule->GetPrimitiveType(BfTypeCode_IntPtr));
  20084. if (!indexArgument)
  20085. indexArgument = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_IntPtr));
  20086. }
  20087. }
  20088. if (indexArgument.mType->IsPrimitiveType())
  20089. {
  20090. auto primType = (BfPrimitiveType*)indexArgument.mType;
  20091. if ((!primType->IsSigned()) && (primType->mSize < 8))
  20092. {
  20093. // GEP will always do a signed upcast so we need to cast manually if we are unsigned
  20094. indexArgument = BfTypedValue(mModule->mBfIRBuilder->CreateNumericCast(indexArgument.mValue, false, BfTypeCode_IntPtr), mModule->GetPrimitiveType(BfTypeCode_IntPtr));
  20095. }
  20096. }
  20097. mModule->PopulateType(target.mType);
  20098. if (target.mType->IsSizedArray())
  20099. {
  20100. BfSizedArrayType* sizedArrayType = (BfSizedArrayType*)target.mType;
  20101. auto underlyingType = sizedArrayType->mElementType;
  20102. if (indexArgument.mValue.IsConst())
  20103. {
  20104. auto indexConst = mModule->mBfIRBuilder->GetConstant(indexArgument.mValue);
  20105. if ((BfIRBuilder::IsIntable(indexConst->mTypeCode)) && (indexConst->mUInt64 >= (uint64)sizedArrayType->mElementCount))
  20106. {
  20107. if ((!mModule->IsInSpecializedSection()) && (checkedKind != BfCheckedKind_Unchecked))
  20108. {
  20109. mModule->Fail(StrFormat("Index '%d' is out of bounds for type '%s'", indexConst->mInt32, mModule->TypeToString(target.mType).c_str()), indexerExpr->mArguments[0]);
  20110. mResult = _GetDefaultResult();
  20111. return;
  20112. }
  20113. else
  20114. {
  20115. // Is this any good?
  20116. mModule->mBfIRBuilder->CreateUnreachable();
  20117. }
  20118. }
  20119. }
  20120. else if (((mModule->HasExecutedOutput()) || (mModule->mIsComptimeModule)) &&
  20121. (wantsChecks))
  20122. {
  20123. if (checkedKind == BfCheckedKind_NotSet)
  20124. checkedKind = mModule->GetDefaultCheckedKind();
  20125. if (checkedKind == BfCheckedKind_Checked)
  20126. {
  20127. auto oobBlock = mModule->mBfIRBuilder->CreateBlock("oob", true);
  20128. auto contBlock = mModule->mBfIRBuilder->CreateBlock("cont", true);
  20129. auto indexType = (BfPrimitiveType*)indexArgument.mType;
  20130. if (!mModule->mSystem->DoesLiteralFit(indexType->mTypeDef->mTypeCode, (int64)sizedArrayType->mElementCount))
  20131. {
  20132. // We need to upsize the index so we can compare it against the larger elementCount
  20133. indexType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  20134. indexArgument = mModule->Cast(indexerExpr->mArguments[0], indexArgument, indexType);
  20135. }
  20136. auto cmpRes = mModule->mBfIRBuilder->CreateCmpGTE(indexArgument.mValue, mModule->mBfIRBuilder->CreateConst(indexType->mTypeDef->mTypeCode, (uint64)sizedArrayType->mElementCount), false);
  20137. mModule->mBfIRBuilder->CreateCondBr(cmpRes, oobBlock, contBlock);
  20138. mModule->mBfIRBuilder->SetInsertPoint(oobBlock);
  20139. auto internalType = mModule->ResolveTypeDef(mModule->mCompiler->mInternalTypeDef);
  20140. auto oobFunc = mModule->GetMethodByName(internalType->ToTypeInstance(), "ThrowIndexOutOfRange");
  20141. if (oobFunc.mFunc)
  20142. {
  20143. if (mModule->mIsComptimeModule)
  20144. mModule->mCompiler->mCeMachine->QueueMethod(oobFunc.mMethodInstance, oobFunc.mFunc);
  20145. SizedArray<BfIRValue, 1> args;
  20146. args.push_back(mModule->GetConstValue(0));
  20147. mModule->mBfIRBuilder->CreateCall(oobFunc.mFunc, args);
  20148. mModule->mBfIRBuilder->CreateUnreachable();
  20149. }
  20150. else
  20151. {
  20152. mModule->Fail("System.Internal class must contain method 'ThrowIndexOutOfRange'");
  20153. }
  20154. mModule->mBfIRBuilder->SetInsertPoint(contBlock);
  20155. }
  20156. }
  20157. // If this is a 'bag of bytes', we should try hard not to have to make this addressable
  20158. if ((!target.IsAddr()) && (!target.mType->IsSizeAligned()))
  20159. mModule->MakeAddressable(target);
  20160. mResult = BfTypedValue();
  20161. mModule->PopulateType(underlyingType);
  20162. if ((sizedArrayType->IsUndefSizedArray()) || (isUndefIndex))
  20163. {
  20164. mResult = mModule->GetDefaultTypedValue(underlyingType, false, BfDefaultValueKind_Addr);
  20165. if ((!target.CanModify()) && (mResult.IsAddr()))
  20166. mResult.mKind = BfTypedValueKind_ReadOnlyAddr;
  20167. }
  20168. else if (sizedArrayType->IsValuelessType())
  20169. {
  20170. if (underlyingType->IsValuelessType())
  20171. mResult = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), underlyingType, true);
  20172. else
  20173. {
  20174. mResult = mModule->GetDefaultTypedValue(underlyingType, false, BfDefaultValueKind_Addr);
  20175. }
  20176. if ((!target.CanModify()) && (mResult.IsAddr()))
  20177. mResult.mKind = BfTypedValueKind_ReadOnlyAddr;
  20178. }
  20179. else if (target.IsAddr())
  20180. {
  20181. // Handle below
  20182. }
  20183. else
  20184. {
  20185. if ((!target.mValue.IsConst()) && (!indexArgument.mValue.IsConst()))
  20186. {
  20187. target = mModule->MakeAddressable(target);
  20188. }
  20189. else
  20190. {
  20191. mModule->mBfIRBuilder->PopulateType(target.mType);
  20192. auto gepResult = mModule->mBfIRBuilder->CreateExtractValue(target.mValue, indexArgument.mValue);
  20193. if ((underlyingType->IsString()) || (underlyingType->IsPointer()))
  20194. {
  20195. auto resultConst = mModule->mBfIRBuilder->GetConstant(gepResult);
  20196. if ((resultConst != NULL) && (resultConst->mTypeCode == BfTypeCode_Int32))
  20197. {
  20198. int strId = resultConst->mInt32;
  20199. const StringImpl& str = mModule->mContext->mStringObjectIdMap[strId].mString;
  20200. if (underlyingType->IsString())
  20201. gepResult = mModule->GetStringObjectValue(str, false);
  20202. else
  20203. gepResult = mModule->GetStringCharPtr(strId);
  20204. }
  20205. }
  20206. mResult = BfTypedValue(gepResult, underlyingType, BfTypedValueKind_Value);
  20207. }
  20208. }
  20209. if ((!mResult) && (target.IsAddr()))
  20210. {
  20211. if (target.mType->IsSizeAligned())
  20212. {
  20213. auto gepResult = mModule->mBfIRBuilder->CreateInBoundsGEP(target.mValue, mModule->GetConstValue(0), indexArgument.mValue);
  20214. mResult = BfTypedValue(gepResult, underlyingType, target.IsReadOnly() ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
  20215. }
  20216. else
  20217. {
  20218. auto indexResult = mModule->CreateIndexedValue(underlyingType, target.mValue, indexArgument.mValue);
  20219. mResult = BfTypedValue(indexResult, underlyingType, target.IsReadOnly() ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
  20220. }
  20221. }
  20222. if (!mResult)
  20223. {
  20224. mModule->Fail("Unable to index value", indexerExpr->mTarget);
  20225. return;
  20226. }
  20227. }
  20228. else
  20229. {
  20230. // We are no longer accessing data within this type
  20231. mResultLocalVar = NULL;
  20232. target = mModule->LoadValue(target);
  20233. BfPointerType* pointerType = (BfPointerType*)target.mType;
  20234. auto underlyingType = pointerType->mElementType;
  20235. mModule->mBfIRBuilder->PopulateType(underlyingType);
  20236. if (underlyingType->IsOpaque())
  20237. {
  20238. mModule->Fail(StrFormat("Unable to index opaque pointer type '%s'", mModule->TypeToString(pointerType).c_str()), indexerExpr);
  20239. }
  20240. else if (isUndefIndex)
  20241. {
  20242. mResult = mModule->GetDefaultTypedValue(underlyingType, false, BfDefaultValueKind_Addr);
  20243. }
  20244. else
  20245. {
  20246. BfIRValue result = mModule->CreateIndexedValue(underlyingType, target.mValue, indexArgument.mValue);
  20247. mResult = BfTypedValue(result, underlyingType, true);
  20248. }
  20249. }
  20250. }
  20251. void BfExprEvaluator::Visit(BfUnaryOperatorExpression* unaryOpExpr)
  20252. {
  20253. BfAutoParentNodeEntry autoParentNodeEntry(mModule, unaryOpExpr);
  20254. PerformUnaryOperation(unaryOpExpr->mExpression, unaryOpExpr->mOp, unaryOpExpr->mOpToken, BfUnaryOpFlag_None);
  20255. }
  20256. void BfExprEvaluator::PerformUnaryOperation(BfExpression* unaryOpExpr, BfUnaryOp unaryOp, BfTokenNode* opToken, BfUnaryOpFlags opFlags)
  20257. {
  20258. if ((unaryOpExpr == NULL) && (unaryOp == BfUnaryOp_PartialRangeThrough))
  20259. {
  20260. PerformBinaryOperation(NULL, NULL, BfBinaryOp_ClosedRange, opToken, BfBinOpFlag_None);
  20261. return;
  20262. }
  20263. ///
  20264. {
  20265. SetAndRestoreValue<BfEvalExprFlags> prevFlags(mBfEvalExprFlags);
  20266. BfType* prevExpedcting = mExpectingType;
  20267. switch (unaryOp)
  20268. {
  20269. case BfUnaryOp_Ref:
  20270. // Allow
  20271. break;
  20272. case BfUnaryOp_Dereference:
  20273. if (mExpectingType != NULL)
  20274. {
  20275. if (mExpectingType->IsRef())
  20276. mExpectingType = mExpectingType->GetUnderlyingType();
  20277. if (!mExpectingType->IsVar())
  20278. mExpectingType = mModule->CreatePointerType(mExpectingType);
  20279. }
  20280. break;
  20281. case BfUnaryOp_Negate:
  20282. case BfUnaryOp_Positive:
  20283. case BfUnaryOp_InvertBits:
  20284. // If we're expecting an int64 or uint64 then just leave the type as unknown
  20285. if ((mExpectingType != NULL) && (mExpectingType->IsInteger()) && (mExpectingType->mSize == 8))
  20286. mExpectingType = NULL;
  20287. // Otherwise keep expecting type
  20288. break;
  20289. case BfUnaryOp_Params:
  20290. mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_InParamsExpr);
  20291. break;
  20292. default:
  20293. mExpectingType = NULL;
  20294. }
  20295. VisitChild(unaryOpExpr);
  20296. mExpectingType = prevExpedcting;
  20297. }
  20298. BfExprEvaluator::PerformUnaryOperation_OnResult(unaryOpExpr, unaryOp, opToken, opFlags);
  20299. }
  20300. BfTypedValue BfExprEvaluator::PerformUnaryOperation_TryOperator(const BfTypedValue& inValue, BfExpression* unaryOpExpr, BfUnaryOp unaryOp, BfTokenNode* opToken, BfUnaryOpFlags opFlags)
  20301. {
  20302. if ((!inValue.mType->IsTypeInstance()) && (!inValue.mType->IsGenericParam()))
  20303. return BfTypedValue();
  20304. SizedArray<BfResolvedArg, 1> args;
  20305. BfResolvedArg resolvedArg;
  20306. resolvedArg.mTypedValue = inValue;
  20307. args.push_back(resolvedArg);
  20308. BfMethodMatcher methodMatcher(opToken, mModule, "", args, BfMethodGenericArguments());
  20309. methodMatcher.mBfEvalExprFlags = BfEvalExprFlags_NoAutoComplete;
  20310. methodMatcher.mAllowImplicitRef = true;
  20311. BfBaseClassWalker baseClassWalker(inValue.mType, NULL, mModule);
  20312. BfUnaryOp findOp = unaryOp;
  20313. bool isPostOp = false;
  20314. if (findOp == BfUnaryOp_PostIncrement)
  20315. {
  20316. findOp = BfUnaryOp_Increment;
  20317. isPostOp = true;
  20318. }
  20319. if (findOp == BfUnaryOp_PostDecrement)
  20320. {
  20321. findOp = BfUnaryOp_Decrement;
  20322. isPostOp = true;
  20323. }
  20324. bool isConstraintCheck = ((opFlags & BfUnaryOpFlag_IsConstraintCheck) != 0);
  20325. BfType* operatorConstraintReturnType = NULL;
  20326. BfType* bestSelfType = NULL;
  20327. while (true)
  20328. {
  20329. auto entry = baseClassWalker.Next();
  20330. auto checkType = entry.mTypeInstance;
  20331. if (checkType == NULL)
  20332. break;
  20333. for (auto operatorDef : checkType->mTypeDef->mOperators)
  20334. {
  20335. if (operatorDef->mOperatorDeclaration->mUnaryOp == findOp)
  20336. {
  20337. if (!methodMatcher.IsMemberAccessible(checkType, operatorDef->mDeclaringType))
  20338. continue;
  20339. int prevArgSize = (int)args.mSize;
  20340. if (!operatorDef->mIsStatic)
  20341. {
  20342. // Try without arg
  20343. args.mSize = 0;
  20344. }
  20345. if (isConstraintCheck)
  20346. {
  20347. auto returnType = mModule->CheckOperator(checkType, operatorDef, inValue, BfTypedValue());
  20348. if (returnType != NULL)
  20349. {
  20350. operatorConstraintReturnType = returnType;
  20351. methodMatcher.mBestMethodDef = operatorDef;
  20352. }
  20353. }
  20354. else
  20355. {
  20356. if (methodMatcher.CheckMethod(NULL, checkType, operatorDef, false))
  20357. methodMatcher.mSelfType = entry.mSrcType;
  20358. }
  20359. args.mSize = prevArgSize;
  20360. }
  20361. }
  20362. }
  20363. methodMatcher.FlushAmbiguityError();
  20364. if (methodMatcher.mBestMethodDef == NULL)
  20365. {
  20366. // Check method generic constraints
  20367. if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsUnspecialized) && (mModule->mCurMethodInstance->mMethodInfoEx != NULL))
  20368. {
  20369. for (int genericParamIdx = 0; genericParamIdx < mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams.size(); genericParamIdx++)
  20370. {
  20371. auto genericParam = mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
  20372. for (auto& opConstraint : genericParam->mOperatorConstraints)
  20373. {
  20374. if (opConstraint.mUnaryOp == findOp)
  20375. {
  20376. if (mModule->CanCast(args[0].mTypedValue, opConstraint.mRightType, isConstraintCheck ? BfCastFlags_IsConstraintCheck : BfCastFlags_None))
  20377. {
  20378. return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), genericParam->mExternType);
  20379. }
  20380. }
  20381. }
  20382. }
  20383. }
  20384. // Check type generic constraints
  20385. if ((mModule->mCurTypeInstance->IsGenericTypeInstance()) && (mModule->mCurTypeInstance->IsUnspecializedType()))
  20386. {
  20387. auto genericTypeInst = (BfTypeInstance*)mModule->mCurTypeInstance;
  20388. for (int genericParamIdx = 0; genericParamIdx < genericTypeInst->mGenericTypeInfo->mGenericParams.size(); genericParamIdx++)
  20389. {
  20390. auto genericParam = mModule->GetGenericTypeParamInstance(genericParamIdx);
  20391. for (auto& opConstraint : genericParam->mOperatorConstraints)
  20392. {
  20393. if (opConstraint.mUnaryOp == findOp)
  20394. {
  20395. if (mModule->CanCast(args[0].mTypedValue, opConstraint.mRightType, isConstraintCheck ? BfCastFlags_IsConstraintCheck : BfCastFlags_None))
  20396. {
  20397. return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), genericParam->mExternType);
  20398. }
  20399. }
  20400. }
  20401. }
  20402. }
  20403. return BfTypedValue();
  20404. }
  20405. if ((!baseClassWalker.mMayBeFromInterface) && (opToken != NULL))
  20406. mModule->SetElementType(opToken, BfSourceElementType_Method);
  20407. auto methodDef = methodMatcher.mBestMethodDef;
  20408. auto autoComplete = GetAutoComplete();
  20409. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(opToken)))
  20410. {
  20411. auto operatorDecl = BfNodeDynCast<BfOperatorDeclaration>(methodDef->mMethodDeclaration);
  20412. if ((operatorDecl != NULL) && (operatorDecl->mOpTypeToken != NULL))
  20413. autoComplete->SetDefinitionLocation(operatorDecl->mOpTypeToken);
  20414. }
  20415. SizedArray<BfExpression*, 2> argSrcs;
  20416. argSrcs.push_back(unaryOpExpr);
  20417. BfTypedValue targetVal = args[0].mTypedValue;
  20418. BfTypedValue postOpVal;
  20419. if (isPostOp)
  20420. postOpVal = mModule->LoadValue(targetVal);
  20421. BfTypedValue callTarget;
  20422. if (!methodMatcher.mBestMethodDef->mIsStatic)
  20423. {
  20424. callTarget = targetVal;
  20425. args.Clear();
  20426. }
  20427. BfTypedValue result;
  20428. if (isConstraintCheck)
  20429. {
  20430. result = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), operatorConstraintReturnType);
  20431. }
  20432. else
  20433. {
  20434. SetAndRestoreValue<BfEvalExprFlags> prevFlags(mBfEvalExprFlags, (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_NoAutoComplete));
  20435. SetAndRestoreValue<BfDeferCallData*> prevDeferCallRef(mDeferCallData, NULL);
  20436. result = CreateCall(&methodMatcher, callTarget);
  20437. }
  20438. if (!methodMatcher.mBestMethodDef->mIsStatic)
  20439. {
  20440. if (!isPostOp)
  20441. result = mModule->LoadValue(targetVal);
  20442. }
  20443. else if ((result.mType != NULL) && (methodMatcher.mSelfType != NULL) && (result.mType->IsSelf()))
  20444. {
  20445. BF_ASSERT(mModule->IsInGeneric());
  20446. result = mModule->GetDefaultTypedValue(methodMatcher.mSelfType);
  20447. }
  20448. if ((methodMatcher.mBestMethodInstance) &&
  20449. ((findOp == BfUnaryOp_Increment) || (findOp == BfUnaryOp_Decrement)))
  20450. {
  20451. if (methodMatcher.mBestMethodInstance.mMethodInstance->mIsIntrinsic)
  20452. {
  20453. if (args[0].mTypedValue.IsAddr())
  20454. mModule->mBfIRBuilder->CreateStore(result.mValue, args[0].mTypedValue.mValue);
  20455. else
  20456. {
  20457. mModule->AssertErrorState();
  20458. }
  20459. }
  20460. else
  20461. {
  20462. if (!result.mType->IsValuelessType())
  20463. {
  20464. if (targetVal.IsAddr())
  20465. {
  20466. result = mModule->LoadValue(result);
  20467. mModule->mBfIRBuilder->CreateStore(result.mValue, targetVal.mValue);
  20468. }
  20469. }
  20470. }
  20471. }
  20472. if (postOpVal)
  20473. result = postOpVal;
  20474. return result;
  20475. }
  20476. void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr, BfUnaryOp unaryOp, BfTokenNode* opToken, BfUnaryOpFlags opFlags)
  20477. {
  20478. BfAstNode* propSrc = mPropSrc;
  20479. BfTypedValue origPropTarget = mOrigPropTarget;
  20480. BfTypedValue propTarget = mPropTarget;
  20481. BfPropertyDef* propDef = mPropDef;
  20482. SizedArray<BfResolvedArg, 2> indexerVals = mIndexerValues;
  20483. BfTypedValue writeToProp;
  20484. GetResult();
  20485. if (!mResult)
  20486. return;
  20487. mResult = mModule->RemoveRef(mResult);
  20488. if (mResult.mType->IsVar())
  20489. {
  20490. mResult = BfTypedValue(mModule->GetDefaultValue(mResult.mType), mResult.mType);
  20491. return;
  20492. }
  20493. if (BfCanOverloadOperator(unaryOp))
  20494. {
  20495. auto opResult = PerformUnaryOperation_TryOperator(mResult, unaryOpExpr, unaryOp, opToken, opFlags);
  20496. if (opResult)
  20497. {
  20498. mResult = opResult;
  20499. return;
  20500. }
  20501. auto typeConstraint = mModule->GetGenericParamInstanceTypeConstraint(mResult.mType);
  20502. if ((typeConstraint != NULL) && (!typeConstraint->IsGenericParam()))
  20503. {
  20504. // Handle cases such as 'where T : float'
  20505. mResult.mType = typeConstraint;
  20506. PerformUnaryOperation_OnResult(unaryOpExpr, unaryOp, opToken, opFlags);
  20507. return;
  20508. }
  20509. }
  20510. switch (unaryOp)
  20511. {
  20512. case BfUnaryOp_PostIncrement:
  20513. case BfUnaryOp_Increment:
  20514. case BfUnaryOp_PostDecrement:
  20515. case BfUnaryOp_Decrement:
  20516. {
  20517. if (mResult.mKind == BfTypedValueKind_CopyOnMutateAddr)
  20518. {
  20519. // Support this ops on direct auto-property access without a copy
  20520. mResult.mKind = BfTypedValueKind_Addr;
  20521. }
  20522. }
  20523. break;
  20524. }
  20525. bool numericFail = false;
  20526. switch (unaryOp)
  20527. {
  20528. case BfUnaryOp_Not:
  20529. {
  20530. CheckResultForReading(mResult);
  20531. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  20532. auto value = mModule->LoadValue(mResult);
  20533. value = mModule->Cast(unaryOpExpr, value, boolType);
  20534. if (!value)
  20535. {
  20536. mResult = BfTypedValue();
  20537. return;
  20538. }
  20539. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateNot(value.mValue), boolType);
  20540. }
  20541. break;
  20542. case BfUnaryOp_Positive:
  20543. return;
  20544. case BfUnaryOp_Negate:
  20545. {
  20546. CheckResultForReading(mResult);
  20547. auto value = mModule->LoadValue(mResult);
  20548. if (!value)
  20549. {
  20550. mResult = BfTypedValue();
  20551. return;
  20552. }
  20553. BfType* origType = value.mType;
  20554. if (value.mType->IsTypedPrimitive())
  20555. value.mType = value.mType->GetUnderlyingType();
  20556. if (value.mType->IsIntegral())
  20557. {
  20558. auto primType = (BfPrimitiveType*)value.mType;
  20559. auto wantType = primType;
  20560. auto constant = mModule->mBfIRBuilder->GetConstant(value.mValue);
  20561. if ((constant != NULL) && (mModule->mBfIRBuilder->IsInt(constant->mTypeCode)))
  20562. {
  20563. if ((primType->mTypeDef->mTypeCode == BfTypeCode_UInt32) && (constant->mInt64 == 0x80000000LL))
  20564. {
  20565. mResult = BfTypedValue(mModule->GetConstValue32(-0x80000000LL), mModule->GetPrimitiveType(BfTypeCode_Int32));
  20566. return;
  20567. }
  20568. else if ((primType->mTypeDef->mTypeCode == BfTypeCode_UInt64) && (constant->mInt64 == 0x8000000000000000LL))
  20569. {
  20570. mResult = BfTypedValue(mModule->GetConstValue64(-0x8000000000000000LL), mModule->GetPrimitiveType(BfTypeCode_Int64));
  20571. return;
  20572. }
  20573. }
  20574. /*if (auto constantInt = dyn_cast<ConstantInt>((Value*)value.mValue))
  20575. {
  20576. int64 i64Val = constantInt->getSExtValue();
  20577. // This is a special case where the user entered -0x80000000 (maxint) but we thought "0x80000000" was a uint in the parser
  20578. // which would get upcasted to an int64 for this negate. Properly bring back down to an int32
  20579. if ((primType->mTypeDef->mTypeCode == BfTypeCode_UInt32) && (i64Val == -0x80000000LL))
  20580. {
  20581. mResult = BfTypedValue(mModule->GetConstValue((int)i64Val), mModule->GetPrimitiveType(BfTypeCode_Int32));
  20582. return;
  20583. }
  20584. }*/
  20585. if (!primType->IsSigned())
  20586. {
  20587. if (primType->mSize == 1)
  20588. wantType = mModule->GetPrimitiveType(BfTypeCode_Int16);
  20589. else if (primType->mSize == 2)
  20590. wantType = mModule->GetPrimitiveType(BfTypeCode_Int32);
  20591. else if (primType->mSize == 4)
  20592. wantType = mModule->GetPrimitiveType(BfTypeCode_Int64);
  20593. else
  20594. mModule->Fail("Operator '-' cannot be applied to uint64", opToken);
  20595. }
  20596. if (primType != wantType)
  20597. {
  20598. value = mModule->Cast(unaryOpExpr, value, wantType, BfCastFlags_Explicit);
  20599. if (!value)
  20600. {
  20601. mResult = BfTypedValue();
  20602. return;
  20603. }
  20604. }
  20605. if (origType->mSize == wantType->mSize) // Allow negative of primitive typed but not if we had to upsize
  20606. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateNeg(value.mValue), origType);
  20607. else
  20608. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateNeg(value.mValue), wantType);
  20609. }
  20610. else if (value.mType->IsFloat())
  20611. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateNeg(value.mValue), origType);
  20612. else
  20613. {
  20614. ResolveGenericType();
  20615. if (mResult.mType->IsVar())
  20616. break;
  20617. numericFail = true;
  20618. }
  20619. }
  20620. break;
  20621. case BfUnaryOp_InvertBits:
  20622. {
  20623. CheckResultForReading(mResult);
  20624. auto value = mModule->LoadValue(mResult);
  20625. if (!value)
  20626. return;
  20627. bool isInteger = value.mType->IsIntegral();
  20628. if (value.mType->IsTypedPrimitive())
  20629. isInteger = value.mType->GetUnderlyingType()->IsIntegral();
  20630. if (!isInteger)
  20631. {
  20632. mResult = BfTypedValue();
  20633. mModule->Fail("Operator can only be used on integer types", opToken);
  20634. return;
  20635. }
  20636. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateNot(value.mValue), value.mType);
  20637. }
  20638. break;
  20639. case BfUnaryOp_AddressOf:
  20640. {
  20641. MarkResultUsed();
  20642. mModule->FixIntUnknown(mResult);
  20643. mModule->PopulateType(mResult.mType);
  20644. auto ptrType = mModule->CreatePointerType(mResult.mType);
  20645. if ((mResult.mType->IsValuelessType()) && (!mResult.mType->IsOpaque()))
  20646. {
  20647. if (!mModule->IsInSpecializedSection())
  20648. {
  20649. mModule->Warn(0, StrFormat("Operator '&' results in a sentinel address for zero-sized type '%s'",
  20650. mModule->TypeToString(mResult.mType).c_str()), opToken);
  20651. }
  20652. // Sentinel value
  20653. auto val = mModule->mBfIRBuilder->CreateIntToPtr(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 1), mModule->mBfIRBuilder->MapType(ptrType));
  20654. mResult = BfTypedValue(val, ptrType);
  20655. }
  20656. else if (!CheckModifyResult(mResult, unaryOpExpr, "take address of", false, true))
  20657. {
  20658. if (!mResult.IsAddr())
  20659. mResult = mModule->MakeAddressable(mResult, false, true);
  20660. mResult = BfTypedValue(mResult.mValue, ptrType, false);
  20661. }
  20662. else
  20663. mResult = BfTypedValue(mResult.mValue, ptrType, false);
  20664. }
  20665. break;
  20666. case BfUnaryOp_Dereference:
  20667. {
  20668. CheckResultForReading(mResult);
  20669. if (mResult.mType->IsGenericParam())
  20670. {
  20671. auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)mResult.mType);
  20672. if ((genericParamInstance->mTypeConstraint != NULL) && (genericParamInstance->mTypeConstraint->IsPointer()))
  20673. {
  20674. mResult = mModule->GetDefaultTypedValue(genericParamInstance->mTypeConstraint->GetUnderlyingType(), false, BfDefaultValueKind_Addr);
  20675. break;
  20676. }
  20677. }
  20678. if (!mResult.mType->IsPointer())
  20679. {
  20680. mResult = BfTypedValue();
  20681. mModule->Fail("Cannot dereference non-pointer type", unaryOpExpr);
  20682. return;
  20683. }
  20684. if (mResult.mValue.IsConst())
  20685. {
  20686. auto constant = mModule->mBfIRBuilder->GetConstant(mResult.mValue);
  20687. bool isNull = constant->mTypeCode == BfTypeCode_NullPtr;
  20688. if (constant->mConstType == BfConstType_ExtractValue)
  20689. {
  20690. auto constExtract = (BfConstantExtractValue*)constant;
  20691. auto targetConst = mModule->mBfIRBuilder->GetConstantById(constExtract->mTarget);
  20692. if (targetConst->mConstType == BfConstType_AggZero)
  20693. isNull = true;
  20694. }
  20695. if (isNull)
  20696. {
  20697. mModule->Warn(0, "Cannot dereference a null pointer", unaryOpExpr);
  20698. mResult = mModule->GetDefaultTypedValue(mResult.mType, false, BfDefaultValueKind_Addr);
  20699. mResult = mModule->LoadValue(mResult);
  20700. }
  20701. }
  20702. auto derefTarget = mModule->LoadValue(mResult);
  20703. BfPointerType* pointerType = (BfPointerType*)derefTarget.mType;
  20704. auto resolvedType = pointerType->mElementType;
  20705. mModule->PopulateType(resolvedType);
  20706. if (resolvedType->IsValuelessNonOpaqueType())
  20707. mResult = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), resolvedType, true);
  20708. else
  20709. mResult = BfTypedValue(derefTarget.mValue, resolvedType, true);
  20710. }
  20711. break;
  20712. case BfUnaryOp_PostIncrement:
  20713. case BfUnaryOp_Increment:
  20714. {
  20715. CheckResultForReading(mResult);
  20716. auto ptr = mResult;
  20717. //if ((propDef == NULL) && (!mModule->CheckModifyValue(ptr, opToken)))
  20718. if ((propDef == NULL) && (!CheckModifyResult(ptr, opToken, "increment")))
  20719. return;
  20720. BfTypedValue origTypedVal = mModule->LoadValue(ptr, NULL, mIsVolatileReference);
  20721. BfIRValue origVal = origTypedVal.mValue;
  20722. BfIRValue constValue = mModule->GetConstValue(1, ptr.mType);
  20723. BfIRValue resultValue;
  20724. if (ptr.mType->IsPointer())
  20725. {
  20726. BfPointerType* ptrType = (BfPointerType*)ptr.mType;
  20727. BfType* intPtrType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  20728. constValue = mModule->GetConstValue(ptrType->mElementType->GetStride(), intPtrType);
  20729. auto i8PtrType = mModule->mBfIRBuilder->GetPointerTo(mModule->mBfIRBuilder->GetPrimitiveType(BfTypeCode_Int8));
  20730. BfIRValue origPtrValue = mModule->mBfIRBuilder->CreateBitCast(origVal, i8PtrType);
  20731. BfIRValue newPtrValue = mModule->mBfIRBuilder->CreateInBoundsGEP(origPtrValue, constValue);
  20732. resultValue = mModule->mBfIRBuilder->CreateBitCast(newPtrValue, mModule->mBfIRBuilder->MapType(ptr.mType));
  20733. }
  20734. else
  20735. {
  20736. constValue = mModule->GetConstValue(1, ptr.mType);
  20737. if (!constValue)
  20738. {
  20739. numericFail = true;
  20740. break;
  20741. }
  20742. if ((ptr.mType->IsIntegral()) || (ptr.mType->IsEnum()) || (ptr.mType->IsFloat()))
  20743. {
  20744. resultValue = mModule->mBfIRBuilder->CreateAdd(origVal, constValue/*, "inc"*/);
  20745. }
  20746. else
  20747. {
  20748. numericFail = true;
  20749. break;
  20750. }
  20751. }
  20752. if ((propDef != NULL) && (!ptr.IsAddr()))
  20753. writeToProp = BfTypedValue(resultValue, ptr.mType);
  20754. else
  20755. mModule->mBfIRBuilder->CreateAlignedStore(resultValue, ptr.mValue, ptr.mType->mAlign, mIsVolatileReference);
  20756. if (unaryOp == BfUnaryOp_PostIncrement)
  20757. mResult = BfTypedValue(origVal, ptr.mType, false);
  20758. else
  20759. mResult = BfTypedValue(resultValue, ptr.mType, false);
  20760. }
  20761. break;
  20762. case BfUnaryOp_PostDecrement:
  20763. case BfUnaryOp_Decrement:
  20764. {
  20765. CheckResultForReading(mResult);
  20766. auto ptr = mResult;
  20767. //if ((propDef == NULL) && (!mModule->CheckModifyValue(ptr, opToken)))
  20768. //return;
  20769. if ((propDef == NULL) && (!CheckModifyResult(ptr, opToken, "decrement")))
  20770. return;
  20771. BfTypedValue origTypedVal = mModule->LoadValue(ptr, NULL, mIsVolatileReference);
  20772. BfIRValue origVal = origTypedVal.mValue;
  20773. BfIRValue constValue = mModule->GetConstValue(1, ptr.mType);
  20774. BfIRValue resultValue;
  20775. if (ptr.mType->IsPointer())
  20776. {
  20777. BfPointerType* ptrType = (BfPointerType*)ptr.mType;
  20778. BfType* intPtrType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  20779. constValue = mModule->GetConstValue(-ptrType->mElementType->GetStride(), intPtrType);
  20780. auto i8PtrType = mModule->mBfIRBuilder->GetPointerTo(mModule->mBfIRBuilder->GetPrimitiveType(BfTypeCode_Int8));
  20781. BfIRValue origPtrValue = mModule->mBfIRBuilder->CreateBitCast(origVal, i8PtrType);
  20782. BfIRValue newPtrValue = mModule->mBfIRBuilder->CreateInBoundsGEP(origPtrValue, constValue);
  20783. resultValue = mModule->mBfIRBuilder->CreateBitCast(newPtrValue, mModule->mBfIRBuilder->MapType(ptr.mType));
  20784. }
  20785. else
  20786. {
  20787. BfIRValue constValue = mModule->GetConstValue(1, ptr.mType);
  20788. if (!constValue)
  20789. {
  20790. numericFail = true;
  20791. break;
  20792. }
  20793. if ((ptr.mType->IsIntegral()) || (ptr.mType->IsEnum()))
  20794. {
  20795. resultValue = mModule->mBfIRBuilder->CreateSub(origVal, constValue);
  20796. }
  20797. else if (ptr.mType->IsFloat())
  20798. {
  20799. resultValue = mModule->mBfIRBuilder->CreateSub(origVal, constValue);
  20800. }
  20801. else
  20802. {
  20803. numericFail = true;
  20804. break;
  20805. }
  20806. }
  20807. if ((propDef != NULL) && (!ptr.IsAddr()))
  20808. writeToProp = BfTypedValue(resultValue, ptr.mType);
  20809. else
  20810. mModule->mBfIRBuilder->CreateAlignedStore(resultValue, ptr.mValue, ptr.mType->mAlign, mIsVolatileReference);
  20811. if (unaryOp == BfUnaryOp_PostDecrement)
  20812. mResult = BfTypedValue(origVal, ptr.mType, false);
  20813. else
  20814. mResult = BfTypedValue(resultValue, ptr.mType, false);
  20815. }
  20816. break;
  20817. case BfUnaryOp_Ref:
  20818. case BfUnaryOp_Mut:
  20819. {
  20820. if (mAllowReadOnlyReference)
  20821. {
  20822. if (mResult.mKind == BfTypedValueKind_ReadOnlyAddr)
  20823. mResult.mKind = BfTypedValueKind_Addr;
  20824. }
  20825. CheckResultForReading(mResult);
  20826. if ((unaryOp == BfUnaryOp_Mut) && (!mResult.mType->IsValueType()) && (!mResult.mType->IsGenericParam()))
  20827. {
  20828. // Non-valuetypes types are already mutable, leave them alone...
  20829. break;
  20830. }
  20831. if ((unaryOp != BfUnaryOp_Mut) || (mResult.mKind != BfTypedValueKind_MutableValue))
  20832. {
  20833. if (!CheckModifyResult(mResult, unaryOpExpr, StrFormat("use '%s' on", BfGetOpName(unaryOp)).c_str()))
  20834. {
  20835. // Just leave the non-ref version in mResult
  20836. return;
  20837. }
  20838. }
  20839. if ((mBfEvalExprFlags & BfEvalExprFlags_AllowRefExpr) == 0)
  20840. {
  20841. mResult = BfTypedValue();
  20842. mModule->Fail(StrFormat("Invalid usage of '%s' expression", BfGetOpName(unaryOp)), opToken);
  20843. return;
  20844. }
  20845. ResolveGenericType();
  20846. if (mResult.mType->IsVar())
  20847. break;
  20848. mResult = BfTypedValue(mResult.mValue, mModule->CreateRefType(mResult.mType, (unaryOp == BfUnaryOp_Ref) ? BfRefType::RefKind_Ref : BfRefType::RefKind_Mut));
  20849. }
  20850. break;
  20851. case BfUnaryOp_Out:
  20852. {
  20853. if (!CheckModifyResult(mResult, unaryOpExpr, "use 'out' on"))
  20854. {
  20855. // Just leave the non-ref version in mResult
  20856. return;
  20857. }
  20858. if ((mBfEvalExprFlags & BfEvalExprFlags_AllowOutExpr) == 0)
  20859. {
  20860. mModule->Fail("Invalid usage of 'out' expression", opToken);
  20861. return;
  20862. }
  20863. if (mInsidePendingNullable)
  20864. {
  20865. // 'out' inside null conditionals never actually causes a definite assignment...
  20866. }
  20867. else
  20868. MarkResultAssigned();
  20869. MarkResultUsed();
  20870. ResolveGenericType();
  20871. if (mResult.mType->IsVar())
  20872. break;
  20873. mResult = BfTypedValue(mResult.mValue, mModule->CreateRefType(mResult.mType, BfRefType::RefKind_Out));
  20874. }
  20875. break;
  20876. case BfUnaryOp_Params:
  20877. {
  20878. bool allowParams = (mBfEvalExprFlags & BfEvalExprFlags_AllowParamsExpr) != 0;
  20879. if (allowParams)
  20880. {
  20881. if ((mResultLocalVar != NULL) && (mResultLocalVar->mCompositeCount >= 0)) // Delegate params
  20882. {
  20883. allowParams = true;
  20884. }
  20885. else
  20886. {
  20887. auto origValue = mResult;
  20888. auto isValid = false;
  20889. for (int pass = 0; pass < 2; pass++)
  20890. {
  20891. auto typeInst = mResult.mType->ToTypeInstance();
  20892. auto genericTypeInst = mResult.mType->ToGenericTypeInstance();
  20893. if ((genericTypeInst != NULL) && (genericTypeInst->IsInstanceOf(mModule->mCompiler->mSpanTypeDef)))
  20894. isValid = true;
  20895. else if ((mResult.mType->IsArray()) || (mResult.mType->IsSizedArray()))
  20896. isValid = true;
  20897. else if ((typeInst != NULL) && (pass == 0))
  20898. {
  20899. BfBaseClassWalker baseClassWalker(typeInst, NULL, mModule);
  20900. BfType* bestCastType = NULL;
  20901. while (true)
  20902. {
  20903. auto entry = baseClassWalker.Next();
  20904. auto checkType = entry.mTypeInstance;
  20905. if (checkType == NULL)
  20906. break;
  20907. for (auto operatorDef : checkType->mTypeDef->mOperators)
  20908. {
  20909. if (operatorDef->mOperatorDeclaration->mIsConvOperator)
  20910. {
  20911. if (operatorDef->IsExplicit())
  20912. continue;
  20913. auto methodInstance = mModule->GetRawMethodInstanceAtIdx(typeInst, operatorDef->mIdx);
  20914. auto checkType = methodInstance->mReturnType;
  20915. if (checkType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef))
  20916. bestCastType = checkType;
  20917. else if ((checkType->IsArray()) || (checkType->IsSizedArray()))
  20918. bestCastType = checkType;
  20919. }
  20920. }
  20921. }
  20922. if (bestCastType == NULL)
  20923. break;
  20924. auto castTypedValue = mModule->Cast(opToken, mResult, bestCastType, BfCastFlags_SilentFail);
  20925. if (!castTypedValue)
  20926. break;
  20927. mResult = castTypedValue;
  20928. }
  20929. else
  20930. break;
  20931. }
  20932. if (!isValid)
  20933. {
  20934. mModule->Fail(StrFormat("A 'params' expression cannot be used on type '%s'", mModule->TypeToString(origValue.mType).c_str()), opToken);
  20935. }
  20936. }
  20937. }
  20938. if (allowParams)
  20939. {
  20940. mResult = mModule->LoadValue(mResult);
  20941. if ((mResult.mType != NULL) && (mResult.mType->IsParamsType()))
  20942. mResult.mType = mResult.mType->GetUnderlyingType();
  20943. if (mResult.IsSplat())
  20944. mResult.mKind = BfTypedValueKind_ParamsSplat;
  20945. else
  20946. mResult.mKind = BfTypedValueKind_Params;
  20947. }
  20948. else
  20949. {
  20950. mModule->Fail("Illegal use of 'params' expression", opToken);
  20951. }
  20952. }
  20953. break;
  20954. case BfUnaryOp_Cascade:
  20955. {
  20956. mModule->Fail("Illegal use of argument cascade expression", opToken);
  20957. }
  20958. break;
  20959. case BfUnaryOp_FromEnd:
  20960. {
  20961. CheckResultForReading(mResult);
  20962. auto value = mModule->Cast(unaryOpExpr, mResult, mModule->GetPrimitiveType(BfTypeCode_IntPtr));
  20963. value = mModule->LoadValue(value);
  20964. if (value)
  20965. {
  20966. auto indexType = mModule->ResolveTypeDef(mModule->mCompiler->mIndexTypeDef);
  20967. auto alloca = mModule->CreateAlloca(indexType);
  20968. mModule->mBfIRBuilder->CreateStore(value.mValue, mModule->mBfIRBuilder->CreateInBoundsGEP(mModule->mBfIRBuilder->CreateInBoundsGEP(alloca, 0, 1), 0, 1));
  20969. mModule->mBfIRBuilder->CreateStore(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int8, 1), mModule->mBfIRBuilder->CreateInBoundsGEP(alloca, 0, 2));
  20970. mResult = BfTypedValue(alloca, indexType, BfTypedValueKind_Addr);
  20971. }
  20972. }
  20973. break;
  20974. case BfUnaryOp_PartialRangeUpTo:
  20975. PerformBinaryOperation(NULL, unaryOpExpr, BfBinaryOp_Range, opToken, BfBinOpFlag_None);
  20976. break;
  20977. case BfUnaryOp_PartialRangeThrough:
  20978. PerformBinaryOperation(NULL, unaryOpExpr, BfBinaryOp_ClosedRange, opToken, BfBinOpFlag_None);
  20979. break;
  20980. case BfUnaryOp_PartialRangeFrom:
  20981. PerformBinaryOperation(unaryOpExpr, NULL, BfBinaryOp_ClosedRange, opToken, BfBinOpFlag_None);
  20982. break;
  20983. default:
  20984. mModule->Fail(StrFormat("Illegal use of '%s' unary operator", BfGetOpName(unaryOp)), unaryOpExpr);
  20985. break;
  20986. }
  20987. if (numericFail)
  20988. {
  20989. if (opToken == NULL)
  20990. {
  20991. BF_ASSERT(mModule->mBfIRBuilder->mIgnoreWrites);
  20992. }
  20993. else if ((mResult.mType != NULL) && (mResult.mType->IsInterface()))
  20994. {
  20995. mModule->Fail(
  20996. StrFormat("Operator '%s' cannot be used on interface '%s'. Consider rewriting using generics and use this interface as a generic constraint.",
  20997. BfTokenToString(opToken->mToken), mModule->TypeToString(mResult.mType).c_str()), opToken);
  20998. }
  20999. else
  21000. {
  21001. mModule->Fail(
  21002. StrFormat("Operator '%s' cannot be used because type '%s' is neither a numeric type nor does it define an applicable operator overload",
  21003. BfTokenToString(opToken->mToken), mModule->TypeToString(mResult.mType).c_str()), opToken);
  21004. }
  21005. mResult = BfTypedValue();
  21006. }
  21007. if (writeToProp)
  21008. {
  21009. auto setMethod = GetPropertyMethodDef(propDef, BfMethodType_PropertySetter, mPropCheckedKind, mPropTarget);
  21010. if (setMethod == NULL)
  21011. {
  21012. mModule->Fail("Property has no setter", propSrc);
  21013. return;
  21014. }
  21015. auto methodInstance = GetPropertyMethodInstance(setMethod);
  21016. if (!methodInstance.mFunc)
  21017. return;
  21018. if (propSrc != NULL)
  21019. mModule->UpdateExprSrcPos(propSrc);
  21020. SizedArray<BfIRValue, 4> args;
  21021. if (!setMethod->mIsStatic)
  21022. {
  21023. auto usePropTarget = propTarget;
  21024. if (origPropTarget.mType == methodInstance.mMethodInstance->GetOwner())
  21025. usePropTarget = origPropTarget;
  21026. else
  21027. BF_ASSERT(propTarget.mType == methodInstance.mMethodInstance->GetOwner());
  21028. PushThis(propSrc, usePropTarget, methodInstance.mMethodInstance, args);
  21029. }
  21030. for (int paramIdx = 0; paramIdx < (int)indexerVals.size(); paramIdx++)
  21031. {
  21032. auto val = mModule->Cast(propSrc, indexerVals[paramIdx].mTypedValue, methodInstance.mMethodInstance->GetParamType(paramIdx));
  21033. if (!val)
  21034. return;
  21035. PushArg(val, args);
  21036. }
  21037. PushArg(writeToProp, args);
  21038. CreateCall(opToken, methodInstance.mMethodInstance, methodInstance.mFunc, false, args);
  21039. }
  21040. }
  21041. void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExpression* rightExpression, BfBinaryOp binaryOp, BfTokenNode* opToken, BfBinOpFlags flags, BfTypedValue leftValue)
  21042. {
  21043. BfTypedValue rightValue;
  21044. if (rightExpression == NULL)
  21045. {
  21046. mModule->AssertErrorState();
  21047. return;
  21048. }
  21049. if (!leftValue)
  21050. {
  21051. if (!rightValue)
  21052. mModule->CreateValueFromExpression(rightExpression, mExpectingType, (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags));
  21053. return;
  21054. }
  21055. if (leftValue.mType->IsRef())
  21056. leftValue.mType = leftValue.mType->GetUnderlyingType();
  21057. if ((binaryOp == BfBinaryOp_ConditionalAnd) || (binaryOp == BfBinaryOp_ConditionalOr))
  21058. {
  21059. if (mModule->mCurMethodState->mDeferredLocalAssignData != NULL)
  21060. mModule->mCurMethodState->mDeferredLocalAssignData->BreakExtendChain();
  21061. if (mModule->mCurMethodState->mCurScope->mScopeKind == BfScopeKind_StatementTarget)
  21062. mModule->mCurMethodState->mCurScope->mScopeKind = BfScopeKind_StatementTarget_Conditional;
  21063. bool isAnd = binaryOp == BfBinaryOp_ConditionalAnd;
  21064. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  21065. leftValue = mModule->Cast(leftExpression, leftValue, boolType);
  21066. if (!leftValue)
  21067. {
  21068. mModule->CreateValueFromExpression(rightExpression);
  21069. mResult = mModule->GetDefaultTypedValue(boolType, false, BfDefaultValueKind_Undef);
  21070. return;
  21071. }
  21072. auto prevBB = mModule->mBfIRBuilder->GetInsertBlock();
  21073. SetAndRestoreValue<bool> prevInCondBlock(mModule->mCurMethodState->mInConditionalBlock, true);
  21074. // The RHS is not guaranteed to be executed
  21075. if ((mModule->mCurMethodState->mDeferredLocalAssignData != NULL) &&
  21076. (mModule->mCurMethodState->mDeferredLocalAssignData->mIsIfCondition))
  21077. mModule->mCurMethodState->mDeferredLocalAssignData->mIfMayBeSkipped = true;
  21078. if (isAnd)
  21079. {
  21080. bool isConstBranch = false;
  21081. bool constResult = false;
  21082. if (leftValue.mValue.IsConst())
  21083. {
  21084. auto constValue = mModule->mBfIRBuilder->GetConstant(leftValue.mValue);
  21085. if (constValue->mTypeCode == BfTypeCode_Boolean)
  21086. {
  21087. isConstBranch = true;
  21088. constResult = constValue->mBool;
  21089. }
  21090. }
  21091. if (isConstBranch)
  21092. {
  21093. if ((constResult) || (HasVariableDeclaration(rightExpression)))
  21094. {
  21095. // Only right side
  21096. rightValue = mModule->CreateValueFromExpression(rightExpression, boolType, (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags));
  21097. mResult = rightValue;
  21098. }
  21099. else
  21100. {
  21101. // Always false
  21102. SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
  21103. SetAndRestoreValue<bool> prevInConstIgnore(mModule->mCurMethodState->mCurScope->mInConstIgnore, true);
  21104. rightValue = mModule->CreateValueFromExpression(rightExpression, boolType, (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags));
  21105. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 0), boolType);
  21106. }
  21107. }
  21108. else
  21109. {
  21110. auto rhsBB = mModule->mBfIRBuilder->CreateBlock("land.rhs");
  21111. auto endBB = mModule->mBfIRBuilder->CreateBlock("land.end");
  21112. mModule->mBfIRBuilder->CreateCondBr(leftValue.mValue, rhsBB, endBB);
  21113. mModule->AddBasicBlock(rhsBB);
  21114. rightValue = mModule->CreateValueFromExpression(rightExpression, boolType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_CreateConditionalScope));
  21115. mModule->mBfIRBuilder->CreateBr(endBB);
  21116. auto endRhsBB = mModule->mBfIRBuilder->GetInsertBlock();
  21117. mModule->AddBasicBlock(endBB);
  21118. auto phi = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(boolType), 2);
  21119. mModule->mBfIRBuilder->AddPhiIncoming(phi, mModule->GetConstValue(0, boolType), prevBB);
  21120. if (rightValue)
  21121. mModule->mBfIRBuilder->AddPhiIncoming(phi, rightValue.mValue, endRhsBB);
  21122. mResult = BfTypedValue(phi, boolType);
  21123. }
  21124. }
  21125. else
  21126. {
  21127. // Put variables in here into a 'possibly assigned' but never commit it.
  21128. // Because if we had "if ((Get(out a)) || (GetOther(out a))" then the LHS would already set it as defined, so
  21129. // the RHS is inconsequential
  21130. BfDeferredLocalAssignData deferredLocalAssignData;
  21131. deferredLocalAssignData.ExtendFrom(mModule->mCurMethodState->mDeferredLocalAssignData, false);
  21132. deferredLocalAssignData.mVarIdBarrier = mModule->mCurMethodState->GetRootMethodState()->mCurLocalVarId;
  21133. SetAndRestoreValue<BfDeferredLocalAssignData*> prevDLA(mModule->mCurMethodState->mDeferredLocalAssignData, &deferredLocalAssignData);
  21134. bool isConstBranch = false;
  21135. bool constResult = false;
  21136. if (leftValue.mValue.IsConst())
  21137. {
  21138. auto constValue = mModule->mBfIRBuilder->GetConstant(leftValue.mValue);
  21139. if (constValue->mTypeCode == BfTypeCode_Boolean)
  21140. {
  21141. isConstBranch = true;
  21142. constResult = constValue->mBool;
  21143. }
  21144. }
  21145. if (isConstBranch)
  21146. {
  21147. if ((constResult) && (!HasVariableDeclaration(rightExpression)))
  21148. {
  21149. // Always true
  21150. SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
  21151. SetAndRestoreValue<bool> prevInConstIgnore(mModule->mCurMethodState->mCurScope->mInConstIgnore, true);
  21152. rightValue = mModule->CreateValueFromExpression(rightExpression, boolType, (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags));
  21153. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 1), boolType);
  21154. }
  21155. else
  21156. {
  21157. // Only right side
  21158. rightValue = mModule->CreateValueFromExpression(rightExpression, boolType, (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags));
  21159. mResult = rightValue;
  21160. }
  21161. }
  21162. else
  21163. {
  21164. auto rhsBB = mModule->mBfIRBuilder->CreateBlock("lor.rhs");
  21165. auto endBB = mModule->mBfIRBuilder->CreateBlock("lor.end");
  21166. // This makes any 'scope' allocs be dyn since we aren't sure if this will be short-circuited
  21167. SetAndRestoreValue<bool> prevIsConditional(mModule->mCurMethodState->mCurScope->mIsConditional, true);
  21168. mModule->mBfIRBuilder->CreateCondBr(leftValue.mValue, endBB, rhsBB);
  21169. mModule->AddBasicBlock(rhsBB);
  21170. rightValue = mModule->CreateValueFromExpression(rightExpression, boolType, (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags));
  21171. mModule->mBfIRBuilder->CreateBr(endBB);
  21172. auto endRhsBB = mModule->mBfIRBuilder->GetInsertBlock();
  21173. mModule->AddBasicBlock(endBB);
  21174. auto phi = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(boolType), 2);
  21175. mModule->mBfIRBuilder->AddPhiIncoming(phi, mModule->GetConstValue(1, boolType), prevBB);
  21176. if (rightValue)
  21177. mModule->mBfIRBuilder->AddPhiIncoming(phi, rightValue.mValue, endRhsBB);
  21178. mResult = BfTypedValue(phi, boolType);
  21179. }
  21180. }
  21181. return;
  21182. }
  21183. BfType* wantType = leftValue.mType;
  21184. BfType* origWantType = wantType;
  21185. if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift))
  21186. wantType = NULL; // Don't presume
  21187. wantType = mModule->FixIntUnknown(wantType);
  21188. if ((binaryOp == BfBinaryOp_NullCoalesce) && (PerformBinaryOperation_NullCoalesce(opToken, leftExpression, rightExpression, leftValue, wantType, NULL)))
  21189. return;
  21190. BfType* rightWantType = wantType;
  21191. if (origWantType->IsIntUnknown())
  21192. rightWantType = NULL;
  21193. else if ((mExpectingType != NULL) && (wantType != NULL) && (mExpectingType->IsIntegral()) && (wantType->IsIntegral()) && (mExpectingType->mSize > wantType->mSize) &&
  21194. ((binaryOp == BfBinaryOp_Add) || (binaryOp == BfBinaryOp_Subtract) || (binaryOp == BfBinaryOp_Multiply)))
  21195. rightWantType = mExpectingType;
  21196. rightValue = mModule->CreateValueFromExpression(rightExpression, rightWantType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_AllowIntUnknown));
  21197. if ((rightWantType != wantType) && (rightValue.mType == rightWantType))
  21198. wantType = rightWantType;
  21199. if ((!leftValue) || (!rightValue))
  21200. return;
  21201. PerformBinaryOperation(leftExpression, rightExpression, binaryOp, opToken, flags, leftValue, rightValue);
  21202. }
  21203. bool BfExprEvaluator::PerformBinaryOperation_NullCoalesce(BfTokenNode* opToken, BfExpression* leftExpression, BfExpression* rightExpression, BfTypedValue leftValue, BfType* wantType, BfTypedValue* assignTo)
  21204. {
  21205. if ((leftValue) && ((leftValue.mType->IsPointer()) || (leftValue.mType->IsFunction()) || (leftValue.mType->IsObject())) || (leftValue.mType->IsNullable()))
  21206. {
  21207. leftValue = mModule->LoadOrAggregateValue(leftValue);
  21208. mModule->mBfIRBuilder->PopulateType(leftValue.mType);
  21209. BfType* nullableElementType = NULL;
  21210. BfIRValue nullableHasValue;
  21211. BfTypedValue nullableExtractedLeftValue;
  21212. if (leftValue.mType->IsNullable())
  21213. {
  21214. nullableElementType = leftValue.mType->GetUnderlyingType();
  21215. nullableHasValue = mModule->mBfIRBuilder->CreateExtractValue(leftValue.mValue, nullableElementType->IsValuelessType() ? 1 : 2); // has_value
  21216. if (!nullableElementType->IsValuelessType())
  21217. nullableExtractedLeftValue = BfTypedValue(mModule->mBfIRBuilder->CreateExtractValue(leftValue.mValue, 1), nullableElementType); // value
  21218. else
  21219. nullableExtractedLeftValue = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), nullableElementType);
  21220. }
  21221. if (leftValue.mValue.IsConst())
  21222. {
  21223. auto constant = mModule->mBfIRBuilder->GetConstant(leftValue.mValue);
  21224. if (constant->IsNull())
  21225. {
  21226. mResult = mModule->CreateValueFromExpression(rightExpression, wantType, (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags));
  21227. return true;
  21228. }
  21229. // Already have a value, we don't need the right side
  21230. SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
  21231. SetAndRestoreValue<bool> prevInConstIgnore(mModule->mCurMethodState->mCurScope->mInConstIgnore, true);
  21232. mModule->CreateValueFromExpression(rightExpression, wantType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_CreateConditionalScope));
  21233. mResult = leftValue;
  21234. return true;
  21235. }
  21236. auto prevBB = mModule->mBfIRBuilder->GetInsertBlock();
  21237. auto rhsBB = mModule->mBfIRBuilder->CreateBlock("nullc.rhs");
  21238. auto endBB = mModule->mBfIRBuilder->CreateBlock("nullc.end");
  21239. auto lhsBB = endBB;
  21240. auto endLhsBB = prevBB;
  21241. BfIRValue isNull;
  21242. if (nullableHasValue)
  21243. isNull = mModule->mBfIRBuilder->CreateCmpEQ(nullableHasValue, mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 0));
  21244. else if (leftValue.mType->IsFunction())
  21245. isNull = mModule->mBfIRBuilder->CreateIsNull(
  21246. mModule->mBfIRBuilder->CreateIntToPtr(leftValue.mValue, mModule->mBfIRBuilder->MapType(mModule->GetPrimitiveType(BfTypeCode_NullPtr))));
  21247. else
  21248. isNull = mModule->mBfIRBuilder->CreateIsNull(leftValue.mValue);
  21249. mModule->AddBasicBlock(rhsBB);
  21250. BfTypedValue rightValue;
  21251. if (assignTo != NULL)
  21252. rightValue = mModule->CreateValueFromExpression(rightExpression, wantType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_CreateConditionalScope));
  21253. else
  21254. rightValue = mModule->CreateValueFromExpression(rightExpression, wantType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_CreateConditionalScope));
  21255. if (!rightValue)
  21256. {
  21257. mModule->AssertErrorState();
  21258. return true;
  21259. }
  21260. if ((assignTo == NULL) && (leftValue.mType->IsNullable()) && (!rightValue.mType->IsNullable()))
  21261. {
  21262. if (wantType == leftValue.mType)
  21263. wantType = nullableElementType;
  21264. leftValue = nullableExtractedLeftValue;
  21265. }
  21266. rightValue = mModule->LoadValue(rightValue);
  21267. if (assignTo == NULL)
  21268. {
  21269. auto rightToLeftValue = mModule->CastToValue(rightExpression, rightValue, leftValue.mType, BfCastFlags_SilentFail);
  21270. if (rightToLeftValue)
  21271. {
  21272. rightValue = BfTypedValue(rightToLeftValue, leftValue.mType);
  21273. }
  21274. else
  21275. {
  21276. lhsBB = mModule->mBfIRBuilder->CreateBlock("nullc.lhs", true);
  21277. mModule->mBfIRBuilder->SetInsertPoint(lhsBB);
  21278. auto leftToRightValue = mModule->CastToValue(leftExpression, leftValue, rightValue.mType, BfCastFlags_SilentFail);
  21279. if (leftToRightValue)
  21280. {
  21281. leftValue = BfTypedValue(leftToRightValue, rightValue.mType);
  21282. }
  21283. else
  21284. {
  21285. // Note: Annoying trigraph split for '??'
  21286. mModule->Fail(StrFormat("Operator '?" "?' cannot be applied to operands of type '%s' and '%s'",
  21287. mModule->TypeToString(leftValue.mType).c_str(), mModule->TypeToString(rightValue.mType).c_str()), opToken);
  21288. leftValue = mModule->GetDefaultTypedValue(rightValue.mType);
  21289. }
  21290. mModule->mBfIRBuilder->CreateBr(endBB);
  21291. endLhsBB = mModule->mBfIRBuilder->GetInsertBlock();
  21292. mModule->mBfIRBuilder->SetInsertPoint(rhsBB);
  21293. }
  21294. }
  21295. if (assignTo != NULL)
  21296. mModule->mBfIRBuilder->CreateStore(rightValue.mValue, assignTo->mValue);
  21297. mModule->mBfIRBuilder->CreateBr(endBB);
  21298. auto endRhsBB = mModule->mBfIRBuilder->GetInsertBlock();
  21299. // Actually add CondBr at start
  21300. mModule->mBfIRBuilder->SetInsertPoint(prevBB);
  21301. mModule->mBfIRBuilder->CreateCondBr(isNull, rhsBB, lhsBB);
  21302. mModule->AddBasicBlock(endBB);
  21303. if (assignTo != NULL)
  21304. {
  21305. mResult = *assignTo;
  21306. }
  21307. else
  21308. {
  21309. auto phi = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(leftValue.mType), 2);
  21310. if (!leftValue.mType->IsValuelessType())
  21311. mModule->mBfIRBuilder->AddPhiIncoming(phi, leftValue.mValue, endLhsBB);
  21312. if (!rightValue.mType->IsValuelessType())
  21313. mModule->mBfIRBuilder->AddPhiIncoming(phi, rightValue.mValue, endRhsBB);
  21314. mResult = BfTypedValue(phi, leftValue.mType);
  21315. }
  21316. return true;
  21317. }
  21318. return false;
  21319. }
  21320. bool BfExprEvaluator::PerformBinaryOperation_Numeric(BfAstNode* leftExpression, BfAstNode* rightExpression, BfBinaryOp binaryOp, BfAstNode* opToken, BfBinOpFlags flags, BfTypedValue leftValue, BfTypedValue rightValue)
  21321. {
  21322. switch (binaryOp)
  21323. {
  21324. case BfBinaryOp_Add:
  21325. case BfBinaryOp_Subtract:
  21326. case BfBinaryOp_Multiply:
  21327. case BfBinaryOp_Divide:
  21328. case BfBinaryOp_Modulus:
  21329. break;
  21330. default:
  21331. return false;
  21332. }
  21333. auto wantType = mExpectingType;
  21334. if ((wantType == NULL) ||
  21335. ((!wantType->IsFloat()) && (!wantType->IsIntegral())))
  21336. wantType = NULL;
  21337. auto leftType = mModule->GetClosestNumericCastType(leftValue, mExpectingType);
  21338. auto rightType = mModule->GetClosestNumericCastType(rightValue, mExpectingType);
  21339. if (leftType != NULL)
  21340. {
  21341. if ((rightType == NULL) || (mModule->CanCast(mModule->GetFakeTypedValue(rightType), leftType)))
  21342. wantType = leftType;
  21343. else if ((rightType != NULL) && (mModule->CanCast(mModule->GetFakeTypedValue(leftType), rightType)))
  21344. wantType = rightType;
  21345. }
  21346. else if (rightType != NULL)
  21347. wantType = rightType;
  21348. if (wantType == NULL)
  21349. wantType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  21350. auto convLeftValue = mModule->Cast(opToken, leftValue, wantType, BfCastFlags_SilentFail);
  21351. if (!convLeftValue)
  21352. return false;
  21353. auto convRightValue = mModule->Cast(opToken, rightValue, wantType, BfCastFlags_SilentFail);
  21354. if (!convRightValue)
  21355. return false;
  21356. mResult = BfTypedValue();
  21357. // Let the error come from here, if any - so we always return 'true' to avoid a second error
  21358. PerformBinaryOperation(leftExpression, rightExpression, binaryOp, opToken, flags, convLeftValue, convRightValue);
  21359. return true;
  21360. }
  21361. void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExpression* rightExpression, BfBinaryOp binaryOp, BfTokenNode* opToken, BfBinOpFlags flags)
  21362. {
  21363. if ((binaryOp == BfBinaryOp_Range) || (binaryOp == BfBinaryOp_ClosedRange))
  21364. {
  21365. auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  21366. bool isIndexExpr = false;
  21367. BfTypeDef* typeDef = NULL;
  21368. if (auto unaryOpExpr = BfNodeDynCast<BfUnaryOperatorExpression>(leftExpression))
  21369. if (unaryOpExpr->mOp == BfUnaryOp_FromEnd)
  21370. isIndexExpr = true;
  21371. if (rightExpression == NULL)
  21372. isIndexExpr = true;
  21373. if (auto unaryOpExpr = BfNodeDynCast<BfUnaryOperatorExpression>(rightExpression))
  21374. if (unaryOpExpr->mOp == BfUnaryOp_FromEnd)
  21375. isIndexExpr = true;
  21376. if (isIndexExpr)
  21377. typeDef = mModule->mCompiler->mIndexRangeTypeDef;
  21378. else
  21379. typeDef = (binaryOp == BfBinaryOp_Range) ? mModule->mCompiler->mRangeTypeDef : mModule->mCompiler->mClosedRangeTypeDef;
  21380. auto allocType = mModule->ResolveTypeDef(typeDef)->ToTypeInstance();
  21381. auto alloca = mModule->CreateAlloca(allocType);
  21382. BfTypedValueExpression leftTypedValueExpr;
  21383. BfTypedValueExpression rightTypedValueExpr;
  21384. BfTypedValueExpression isClosedTypedValueExpr;
  21385. SizedArray<BfExpression*, 2> argExprs;
  21386. if (leftExpression != NULL)
  21387. {
  21388. argExprs.Add(leftExpression);
  21389. }
  21390. else
  21391. {
  21392. leftTypedValueExpr.mRefNode = opToken;
  21393. leftTypedValueExpr.mTypedValue = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0), mModule->GetPrimitiveType(BfTypeCode_IntPtr));
  21394. argExprs.Add(&leftTypedValueExpr);
  21395. }
  21396. if (rightExpression != NULL)
  21397. {
  21398. argExprs.Add(rightExpression);
  21399. }
  21400. else
  21401. {
  21402. // Add as a `^1`
  21403. auto indexType = mModule->ResolveTypeDef(mModule->mCompiler->mIndexTypeDef)->ToTypeInstance();
  21404. mModule->PopulateType(indexType->mBaseType);
  21405. BF_ASSERT_REL(indexType->mBaseType->mBaseType != NULL);
  21406. rightTypedValueExpr.mRefNode = opToken;
  21407. auto valueTypeEmpty = mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(indexType->mBaseType->mBaseType), {});
  21408. SizedArray<BfIRValue, 8> tupleEmptyMembers;
  21409. tupleEmptyMembers.Add(valueTypeEmpty);
  21410. auto tupleTypeEmpty = mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(mModule->ResolveTypeDef(mModule->mCompiler->mTupleTypeDef)), tupleEmptyMembers);
  21411. SizedArray<BfIRValue, 8> enumMembers;
  21412. enumMembers.Add(valueTypeEmpty);
  21413. auto enumValue = mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(indexType->mBaseType), enumMembers);
  21414. SizedArray<BfIRValue, 8> tupleMembers;
  21415. tupleMembers.Add(tupleTypeEmpty);
  21416. tupleMembers.Add(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 1));
  21417. auto tupleValue = mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(indexType->mFieldInstances[0].mResolvedType), tupleMembers);
  21418. SizedArray<BfIRValue, 8> indexMembers;
  21419. indexMembers.Add(enumValue);
  21420. indexMembers.Add(tupleValue);
  21421. indexMembers.Add(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int8, 1));
  21422. auto indexValue = mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(indexType), indexMembers);
  21423. rightTypedValueExpr.mTypedValue = BfTypedValue(indexValue, indexType);
  21424. argExprs.Add(&rightTypedValueExpr);
  21425. }
  21426. if (isIndexExpr)
  21427. {
  21428. isClosedTypedValueExpr.mRefNode = opToken;
  21429. isClosedTypedValueExpr.mTypedValue = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, (binaryOp == BfBinaryOp_ClosedRange) ? 1 : 0), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  21430. argExprs.Add(&isClosedTypedValueExpr);
  21431. }
  21432. BfSizedArray<BfExpression*> args = argExprs;
  21433. BfResolvedArgs argValues;
  21434. argValues.Init(&args);
  21435. ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval);
  21436. mResult = BfTypedValue(alloca, allocType, true);
  21437. auto result = MatchConstructor(opToken, NULL, mResult, allocType, argValues, true, BfMethodGenericArguments(), BfAllowAppendKind_No);
  21438. if ((result) && (!result.mType->IsVoid()))
  21439. mResult = result;
  21440. return;
  21441. }
  21442. BfTypedValue leftValue;
  21443. if (leftExpression != NULL)
  21444. {
  21445. leftValue = mModule->CreateValueFromExpression(leftExpression, mExpectingType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_AllowIntUnknown));
  21446. }
  21447. PerformBinaryOperation(leftExpression, rightExpression, binaryOp, opToken, flags, leftValue);
  21448. }
  21449. bool BfExprEvaluator::CheckConstCompare(BfBinaryOp binaryOp, BfAstNode* opToken, const BfTypedValue& leftValue, const BfTypedValue& rightValue, bool invert)
  21450. {
  21451. if ((binaryOp < BfBinaryOp_Equality) || (binaryOp > BfBinaryOp_LessThanOrEqual))
  21452. return false;
  21453. // LHS is expected to be a value and RHS is expected to be a const
  21454. if (!leftValue.mType->IsIntegral())
  21455. return false;
  21456. BF_ASSERT(rightValue.mValue.IsConst());
  21457. auto rightConst = mModule->mBfIRBuilder->GetConstant(rightValue.mValue);
  21458. if (!mModule->mBfIRBuilder->IsInt(rightConst->mTypeCode))
  21459. return false;
  21460. BfType* checkType = leftValue.mType;
  21461. if (checkType->IsTypedPrimitive())
  21462. checkType = checkType->GetUnderlyingType();
  21463. if (!checkType->IsPrimitiveType())
  21464. return false;
  21465. BfTypeCode typeCode = ((BfPrimitiveType*)checkType)->mTypeDef->mTypeCode;
  21466. int64 minValue = 0;
  21467. int64 maxValue = 0;
  21468. switch (typeCode)
  21469. {
  21470. case BfTypeCode_Int8:
  21471. minValue = -0x80;
  21472. maxValue = 0x7F;
  21473. break;
  21474. case BfTypeCode_Int16:
  21475. minValue = -0x8000;
  21476. maxValue = 0x7FFF;
  21477. break;
  21478. case BfTypeCode_Int32:
  21479. minValue = -0x80000000LL;
  21480. maxValue = 0x7FFFFFFF;
  21481. break;
  21482. case BfTypeCode_Int64:
  21483. minValue = -0x8000000000000000LL;
  21484. maxValue = 0x7FFFFFFFFFFFFFFFLL;
  21485. break;
  21486. case BfTypeCode_UInt8:
  21487. maxValue = 0xFF;
  21488. break;
  21489. case BfTypeCode_UInt16:
  21490. maxValue = 0xFFFF;
  21491. break;
  21492. case BfTypeCode_UInt32:
  21493. maxValue = 0xFFFFFFFF;
  21494. break;
  21495. default:
  21496. return false;
  21497. }
  21498. int constResult = -1;
  21499. if (typeCode == BfTypeCode_UInt64)
  21500. {
  21501. switch (binaryOp)
  21502. {
  21503. case BfBinaryOp_Equality:
  21504. case BfBinaryOp_StrictEquality:
  21505. if (rightConst->mInt64 < minValue)
  21506. constResult = 0;
  21507. break;
  21508. case BfBinaryOp_InEquality:
  21509. case BfBinaryOp_StrictInEquality:
  21510. if (rightConst->mInt64 < minValue)
  21511. constResult = 1;
  21512. break;
  21513. case BfBinaryOp_LessThan:
  21514. if (rightConst->mInt64 <= minValue)
  21515. constResult = 0;
  21516. break;
  21517. case BfBinaryOp_LessThanOrEqual:
  21518. if (rightConst->mInt64 < minValue)
  21519. constResult = 0;
  21520. break;
  21521. default: break;
  21522. }
  21523. return false;
  21524. }
  21525. else
  21526. {
  21527. switch (binaryOp)
  21528. {
  21529. case BfBinaryOp_Equality:
  21530. case BfBinaryOp_StrictEquality:
  21531. if (rightConst->mInt64 < minValue)
  21532. constResult = 0;
  21533. else if (rightConst->mInt64 > maxValue)
  21534. constResult = 0;
  21535. break;
  21536. case BfBinaryOp_InEquality:
  21537. case BfBinaryOp_StrictInEquality:
  21538. if (rightConst->mInt64 < minValue)
  21539. constResult = 1;
  21540. else if (rightConst->mInt64 > maxValue)
  21541. constResult = 1;
  21542. break;
  21543. case BfBinaryOp_LessThan:
  21544. if (rightConst->mInt64 <= minValue)
  21545. constResult = 0;
  21546. else if (rightConst->mInt64 > maxValue)
  21547. constResult = 1;
  21548. break;
  21549. case BfBinaryOp_LessThanOrEqual:
  21550. if (rightConst->mInt64 < minValue)
  21551. constResult = 0;
  21552. else if (rightConst->mInt64 >= maxValue)
  21553. constResult = 1;
  21554. break;
  21555. case BfBinaryOp_GreaterThan:
  21556. if (rightConst->mInt64 >= maxValue)
  21557. constResult = 0;
  21558. else if (rightConst->mInt64 < minValue)
  21559. constResult = 1;
  21560. break;
  21561. case BfBinaryOp_GreaterThanOrEqual:
  21562. if (rightConst->mInt64 > maxValue)
  21563. constResult = 0;
  21564. else if (rightConst->mInt64 <= minValue)
  21565. constResult = 1;
  21566. break;
  21567. default: break;
  21568. }
  21569. }
  21570. if ((invert) && (constResult >= 0))
  21571. constResult ^= 1;
  21572. if (constResult == 0)
  21573. {
  21574. mModule->Warn(0, "The result of this operation is always 'false'", opToken);
  21575. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 0), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  21576. return true;
  21577. }
  21578. else if (constResult == 1)
  21579. {
  21580. mModule->Warn(0, "The result of this operation is always 'true'", opToken);
  21581. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 1), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  21582. return true;
  21583. }
  21584. return false;
  21585. }
  21586. void BfExprEvaluator::AddStrings(const BfTypedValue& leftValue, const BfTypedValue& rightValue, BfAstNode* refNode)
  21587. {
  21588. if ((leftValue.mValue.IsConst()) && (rightValue.mValue.IsConst()))
  21589. {
  21590. String* lhsStr = mModule->GetStringPoolString(leftValue.mValue, mModule->mBfIRBuilder);
  21591. String* rhsStr = mModule->GetStringPoolString(rightValue.mValue, mModule->mBfIRBuilder);
  21592. if ((lhsStr != NULL) && (rhsStr != NULL))
  21593. {
  21594. String resultStr = *lhsStr + *rhsStr;
  21595. BfVariant variant;
  21596. variant.mTypeCode = BfTypeCode_CharPtr;
  21597. variant.mString = &resultStr;
  21598. GetLiteral(refNode, variant);
  21599. return;
  21600. }
  21601. }
  21602. mModule->Fail("Strings can only be added when they are constants. Consider allocating a string and using Concat.", refNode);
  21603. return;
  21604. }
  21605. void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNode* rightExpression, BfBinaryOp binaryOp, BfAstNode* opToken, BfBinOpFlags flags, BfTypedValue leftValue, BfTypedValue rightValue)
  21606. {
  21607. bool noClassify = (flags & BfBinOpFlag_NoClassify) != 0;
  21608. bool forceRightType = (flags & BfBinOpFlag_ForceRightType) != 0;
  21609. bool forceLeftType = (flags & BfBinOpFlag_ForceLeftType) != 0;
  21610. bool deferRight = (flags & BfBinOpFlag_DeferRight) != 0;
  21611. if (deferRight)
  21612. {
  21613. rightValue = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Var));
  21614. }
  21615. if ((rightValue.mValue.IsConst()) && (!leftValue.mValue.IsConst()))
  21616. {
  21617. if (CheckConstCompare(binaryOp, opToken, leftValue, rightValue))
  21618. return;
  21619. }
  21620. else if ((leftValue.mValue.IsConst()) && (!rightValue.mValue.IsConst()))
  21621. {
  21622. if (CheckConstCompare(BfGetOppositeBinaryOp(binaryOp), opToken, rightValue, leftValue, true))
  21623. return;
  21624. }
  21625. if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift))
  21626. {
  21627. forceLeftType = true;
  21628. mModule->FixIntUnknown(leftValue);
  21629. }
  21630. if (rightValue.mType->IsRef())
  21631. rightValue.mType = rightValue.mType->GetUnderlyingType();
  21632. BfType* origLeftType = leftValue.mType;
  21633. BfType* origRightType = rightValue.mType;
  21634. mModule->FixIntUnknown(leftValue, rightValue);
  21635. // Prefer floats, prefer chars
  21636. int leftCompareSize = leftValue.mType->mSize;
  21637. if (leftValue.mType->IsFloat())
  21638. leftCompareSize += 0x10;
  21639. if (leftValue.mType->IsChar())
  21640. leftCompareSize += 0x100;
  21641. if (!leftValue.mType->IsPrimitiveType())
  21642. leftCompareSize += 0x1000;
  21643. int rightCompareSize = rightValue.mType->mSize;
  21644. if (rightValue.mType->IsFloat())
  21645. rightCompareSize += 0x10;
  21646. if (rightValue.mType->IsChar())
  21647. rightCompareSize += 0x100;
  21648. if (!rightValue.mType->IsPrimitiveType())
  21649. rightCompareSize += 0x1000;
  21650. if ((leftValue.mType->IsTypeInstance()) && (rightValue.mType->IsTypeInstance()))
  21651. {
  21652. int leftInheritDepth = leftValue.mType->ToTypeInstance()->mInheritDepth;
  21653. int rightInheritDepth = rightValue.mType->ToTypeInstance()->mInheritDepth;
  21654. if (leftInheritDepth < rightInheritDepth)
  21655. {
  21656. // If both are type instances then choose the type with the lowest inherit depth
  21657. // so we will choose the base type when applicable
  21658. forceLeftType = true;
  21659. }
  21660. }
  21661. auto resultType = leftValue.mType;
  21662. if (forceRightType)
  21663. {
  21664. resultType = rightValue.mType;
  21665. }
  21666. else if (!forceLeftType)
  21667. {
  21668. bool handled = false;
  21669. BfType* expectingType = mExpectingType;
  21670. if (leftValue.mType == rightValue.mType)
  21671. {
  21672. // All good
  21673. handled = true;
  21674. }
  21675. else if ((expectingType != NULL) &&
  21676. (mModule->CanCast(leftValue, expectingType, BfCastFlags_NoBox)) &&
  21677. (mModule->CanCast(rightValue, expectingType, BfCastFlags_NoBox)) &&
  21678. (!leftValue.mType->IsVar()) && (!rightValue.mType->IsVar()))
  21679. {
  21680. resultType = expectingType;
  21681. handled = true;
  21682. }
  21683. else
  21684. {
  21685. // If one of these is a constant that can be converted into a smaller type, then do that
  21686. if (rightValue.mValue.IsConst())
  21687. {
  21688. if (mModule->CanCast(rightValue, leftValue.mType, BfCastFlags_NoBox))
  21689. {
  21690. resultType = leftValue.mType;
  21691. handled = true;
  21692. }
  21693. }
  21694. // If left is an IntUnknown, allow the right to inform the type
  21695. if (leftValue.mType->IsIntUnknown())
  21696. {
  21697. if (leftValue.mValue.IsConst())
  21698. {
  21699. if (mModule->CanCast(leftValue, rightValue.mType))
  21700. {
  21701. resultType = rightValue.mType;
  21702. handled = true;
  21703. }
  21704. }
  21705. }
  21706. if ((leftValue.mType->IsPointer()) &&
  21707. (rightValue.mType->IsPointer()))
  21708. {
  21709. BfPointerType* leftPointerType = (BfPointerType*)leftValue.mType;
  21710. BfPointerType* rightPointerType = (BfPointerType*)rightValue.mType;
  21711. // If one is a pointer to a sized array then use the other type
  21712. if (leftPointerType->mElementType->IsSizedArray())
  21713. {
  21714. resultType = rightPointerType;
  21715. handled = true;
  21716. }
  21717. else if (rightPointerType->mElementType->IsSizedArray())
  21718. {
  21719. resultType = leftPointerType;
  21720. handled = true;
  21721. }
  21722. }
  21723. }
  21724. if (!handled)
  21725. {
  21726. if ((resultType->IsNull()) ||
  21727. (rightCompareSize > leftCompareSize) ||
  21728. (((rightCompareSize == leftCompareSize) && (!rightValue.mType->IsSigned()))) ||
  21729. (rightValue.mType->IsTypedPrimitive()))
  21730. {
  21731. // Select the type with the "most information"
  21732. if (!rightValue.mType->IsNull())
  21733. resultType = rightValue.mType;
  21734. }
  21735. if ((!resultType->IsPointer()) && (rightValue.mType->IsPointer()))
  21736. resultType = rightValue.mType;
  21737. }
  21738. }
  21739. bool explicitCast = false;
  21740. BfTypedValue* resultTypedValue;
  21741. BfTypedValue* otherTypedValue;
  21742. BfType* otherType;
  21743. BfAstNode* resultTypeSrc;
  21744. BfAstNode* otherTypeSrc;
  21745. if (resultType == leftValue.mType)
  21746. {
  21747. resultTypedValue = &leftValue;
  21748. resultTypeSrc = leftExpression;
  21749. otherTypedValue = &rightValue;
  21750. otherTypeSrc = rightExpression;
  21751. otherType = otherTypedValue->mType;
  21752. }
  21753. else
  21754. {
  21755. resultTypedValue = &rightValue;
  21756. resultTypeSrc = rightExpression;
  21757. otherTypedValue = &leftValue;
  21758. otherTypeSrc = leftExpression;
  21759. otherType = otherTypedValue->mType;
  21760. }
  21761. auto _OpFail = [&]()
  21762. {
  21763. if ((rightValue.mType != NULL) && (leftValue.mType != NULL))
  21764. {
  21765. if (rightValue.mType != leftValue.mType)
  21766. mModule->Fail(StrFormat("Cannot perform binary operation '%s' between types '%s' and '%s'",
  21767. BfGetOpName(binaryOp), mModule->TypeToString(leftValue.mType).c_str(), mModule->TypeToString(rightValue.mType).c_str()), opToken);
  21768. else
  21769. {
  21770. if (leftValue.mType->IsInterface())
  21771. {
  21772. mModule->Fail(StrFormat("Cannot perform binary operation '%s' between two instances of interface '%s'. Consider rewriting using generics and use this interface as a generic constraint.",
  21773. BfGetOpName(binaryOp), mModule->TypeToString(leftValue.mType).c_str()), opToken);
  21774. }
  21775. else
  21776. {
  21777. mModule->Fail(StrFormat("Cannot perform binary operation '%s' between two instances of type '%s'",
  21778. BfGetOpName(binaryOp), mModule->TypeToString(leftValue.mType).c_str()), opToken);
  21779. }
  21780. }
  21781. }
  21782. else
  21783. mModule->Fail(StrFormat("Cannot perform binary operation '%s'", BfGetOpName(binaryOp)), opToken);
  21784. };
  21785. // This case fixes cases like "c == 0" where "0" is technically an int but can be reduced
  21786. if (BfBinOpEqualityCheck(binaryOp))
  21787. {
  21788. if ((resultType != otherType) && (resultTypedValue->mValue.IsConst()) && (mModule->CanCast(*resultTypedValue, otherType)))
  21789. {
  21790. std::swap(resultTypedValue, otherTypedValue);
  21791. std::swap(resultTypeSrc, otherTypeSrc);
  21792. std::swap(resultType, otherType);
  21793. }
  21794. }
  21795. BfIRValue convLeftValue;
  21796. BfIRValue convRightValue;
  21797. if (((resultType->IsVar()) || (otherType->IsVar())) && (!deferRight))
  21798. {
  21799. bool isComparison = (binaryOp >= BfBinaryOp_Equality) && (binaryOp <= BfBinaryOp_LessThanOrEqual);
  21800. if (isComparison)
  21801. mResult = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Boolean), false, BfDefaultValueKind_Addr);
  21802. else if (mExpectingType != NULL)
  21803. mResult = mModule->GetDefaultTypedValue(mExpectingType, false, BfDefaultValueKind_Addr);
  21804. else
  21805. mResult = mModule->GetDefaultTypedValue(resultType, false, BfDefaultValueKind_Addr);
  21806. return;
  21807. }
  21808. if ((otherType->IsNull()) && (BfBinOpEqualityCheck(binaryOp)))
  21809. {
  21810. bool isEquality = (binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality);
  21811. if ((resultType->IsValueType()) && (!resultType->IsFunction()))
  21812. {
  21813. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  21814. if (resultType->IsNullable())
  21815. {
  21816. auto elementType = resultType->GetUnderlyingType();
  21817. mModule->PopulateType(elementType);
  21818. if (elementType->IsValuelessType())
  21819. {
  21820. mModule->mBfIRBuilder->PopulateType(resultType);
  21821. BfTypedValue nullableTypedVale = mModule->MakeAddressable(*resultTypedValue);
  21822. BfIRValue hasValuePtr = mModule->mBfIRBuilder->CreateInBoundsGEP(nullableTypedVale.mValue, 0, 1);
  21823. BfIRValue hasValueValue = mModule->mBfIRBuilder->CreateAlignedLoad(hasValuePtr, 1);
  21824. if (isEquality)
  21825. hasValueValue = mModule->mBfIRBuilder->CreateNot(hasValueValue);
  21826. mResult = BfTypedValue(hasValueValue, boolType);
  21827. }
  21828. else
  21829. {
  21830. mModule->mBfIRBuilder->PopulateType(resultType);
  21831. BfTypedValue nullableTypedVale = mModule->MakeAddressable(*resultTypedValue);
  21832. BfIRValue hasValuePtr = mModule->mBfIRBuilder->CreateInBoundsGEP(nullableTypedVale.mValue, 0, 2);
  21833. BfIRValue hasValueValue = mModule->mBfIRBuilder->CreateAlignedLoad(hasValuePtr, 1);
  21834. if (isEquality)
  21835. hasValueValue = mModule->mBfIRBuilder->CreateNot(hasValueValue);
  21836. mResult = BfTypedValue(hasValueValue, boolType);
  21837. }
  21838. return;
  21839. }
  21840. if (resultType->IsNull())
  21841. {
  21842. // Null always equals null
  21843. mResult = BfTypedValue(mModule->GetConstValue(isEquality ? 1 : 0, boolType), boolType);
  21844. return;
  21845. }
  21846. if (!mModule->IsInSpecializedSection())
  21847. {
  21848. //CS0472: The result of the expression is always 'true' since a value of type 'int' is never equal to 'null' of type '<null>'
  21849. mModule->Warn(BfWarning_CS0472_ValueTypeNullCompare,
  21850. StrFormat("The result of the expression is always '%s' since a value of type '%s' can never be null",
  21851. isEquality ? "false" : "true", mModule->TypeToString(resultType).c_str()), otherTypeSrc);
  21852. }
  21853. // Valuetypes never equal null
  21854. mResult = BfTypedValue(mModule->GetConstValue(isEquality ? 0 : 1, boolType), boolType);
  21855. return;
  21856. }
  21857. }
  21858. // Check for constant equality checks (mostly for strings)
  21859. if (BfBinOpEqualityCheck(binaryOp))
  21860. {
  21861. auto leftConstant = mModule->mBfIRBuilder->GetConstant(leftValue.mValue);
  21862. auto rightConstant = mModule->mBfIRBuilder->GetConstant(rightValue.mValue);
  21863. if ((leftConstant != NULL) && (rightConstant != NULL))
  21864. {
  21865. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  21866. int leftStringPoolIdx = mModule->GetStringPoolIdx(leftValue.mValue, mModule->mBfIRBuilder);
  21867. if (leftStringPoolIdx != -1)
  21868. {
  21869. int rightStringPoolIdx = mModule->GetStringPoolIdx(rightValue.mValue, mModule->mBfIRBuilder);
  21870. if (rightStringPoolIdx != -1)
  21871. {
  21872. bool isEqual = leftStringPoolIdx == rightStringPoolIdx;
  21873. if ((binaryOp == BfBinaryOp_InEquality) || (binaryOp == BfBinaryOp_StrictInEquality))
  21874. isEqual = !isEqual;
  21875. mResult = BfTypedValue(mModule->GetConstValue(isEqual ? 1 : 0, boolType), boolType);
  21876. return;
  21877. }
  21878. }
  21879. int eqResult = mModule->mBfIRBuilder->CheckConstEquality(leftValue.mValue, rightValue.mValue);
  21880. if (eqResult != -1)
  21881. {
  21882. bool isEqual = eqResult == 1;
  21883. if ((binaryOp == BfBinaryOp_InEquality) || (binaryOp == BfBinaryOp_StrictInEquality))
  21884. isEqual = !isEqual;
  21885. mResult = BfTypedValue(mModule->GetConstValue(isEqual ? 1 : 0, boolType), boolType);
  21886. return;
  21887. }
  21888. }
  21889. }
  21890. if ((leftValue.mType->IsTypeInstance()) || (leftValue.mType->IsGenericParam()) ||
  21891. (rightValue.mType->IsTypeInstance()) || (rightValue.mType->IsGenericParam()))
  21892. {
  21893. // As an optimization, we don't call user operator overloads for null checks
  21894. bool skipOpOverload = false;
  21895. if ((binaryOp == BfBinaryOp_StrictEquality) || (binaryOp == BfBinaryOp_StrictInEquality))
  21896. skipOpOverload = true;
  21897. else if (BfBinOpEqualityCheck(binaryOp))
  21898. {
  21899. if (!leftValue.IsAddr())
  21900. {
  21901. auto leftConstant = mModule->mBfIRBuilder->GetConstant(leftValue.mValue);
  21902. if ((leftConstant != NULL) && (leftConstant->IsNull()))
  21903. skipOpOverload = true;
  21904. }
  21905. if (!rightValue.IsAddr())
  21906. {
  21907. auto rightConstant = mModule->mBfIRBuilder->GetConstant(rightValue.mValue);
  21908. if ((rightConstant != NULL) && (rightConstant->IsNull()))
  21909. skipOpOverload = true;
  21910. }
  21911. }
  21912. if ((binaryOp == BfBinaryOp_Add) && (resultType->IsInstanceOf(mModule->mCompiler->mStringTypeDef)))
  21913. {
  21914. // Allow failover to constant string addition
  21915. if ((leftValue.mValue.IsConst()) && (rightValue.mValue.IsConst()))
  21916. skipOpOverload = true;
  21917. }
  21918. if (!skipOpOverload)
  21919. {
  21920. BfBinaryOp findBinaryOp = binaryOp;
  21921. bool isComparison = (binaryOp >= BfBinaryOp_Equality) && (binaryOp <= BfBinaryOp_LessThanOrEqual);
  21922. for (int pass = 0; pass < 2; pass++)
  21923. {
  21924. BfBinaryOp oppositeBinaryOp = BfGetOppositeBinaryOp(findBinaryOp);
  21925. BfBinaryOp overflowBinaryOp = BfBinaryOp_None;
  21926. if (findBinaryOp == BfBinaryOp_OverflowAdd)
  21927. overflowBinaryOp = BfBinaryOp_Add;
  21928. else if (findBinaryOp == BfBinaryOp_OverflowSubtract)
  21929. overflowBinaryOp = BfBinaryOp_Subtract;
  21930. else if (findBinaryOp == BfBinaryOp_OverflowMultiply)
  21931. overflowBinaryOp = BfBinaryOp_Multiply;
  21932. bool foundOp = false;
  21933. BfResolvedArg leftArg;
  21934. leftArg.mExpression = leftExpression;
  21935. leftArg.mTypedValue = leftValue;
  21936. BfResolvedArg rightArg;
  21937. rightArg.mExpression = rightExpression;
  21938. rightArg.mTypedValue = rightValue;
  21939. if (deferRight)
  21940. {
  21941. BfResolvedArgs argValues;
  21942. SizedArray<BfExpression*, 2> argExprs;
  21943. argExprs.push_back(BfNodeDynCast<BfExpression>(rightExpression));
  21944. BfSizedArray<BfExpression*> sizedArgExprs(argExprs);
  21945. argValues.Init(&sizedArgExprs);
  21946. ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval);
  21947. rightArg = argValues.mResolvedArgs[0];
  21948. }
  21949. SizedArray<BfResolvedArg, 2> args;
  21950. if (pass == 0)
  21951. {
  21952. args.push_back(leftArg);
  21953. args.push_back(rightArg);
  21954. }
  21955. else
  21956. {
  21957. args.push_back(rightArg);
  21958. args.push_back(leftArg);
  21959. }
  21960. auto checkLeftType = leftValue.mType;
  21961. auto checkRightType = rightValue.mType;
  21962. BfMethodMatcher methodMatcher(opToken, mModule, "", args, BfMethodGenericArguments());
  21963. methodMatcher.mAllowImplicitRef = true;
  21964. methodMatcher.mBfEvalExprFlags = BfEvalExprFlags_NoAutoComplete;
  21965. BfBaseClassWalker baseClassWalker(checkLeftType, checkRightType, mModule);
  21966. bool invertResult = false;
  21967. BfType* operatorConstraintReturnType = NULL;
  21968. bool wasTransformedUsage = (pass == 1);
  21969. while (true)
  21970. {
  21971. auto entry = baseClassWalker.Next();
  21972. auto checkType = entry.mTypeInstance;
  21973. if (checkType == NULL)
  21974. break;
  21975. bool foundExactMatch = false;
  21976. SizedArray<BfOperatorDef*, 8> oppositeOperatorDefs;
  21977. for (auto operatorDef : checkType->mTypeDef->mOperators)
  21978. {
  21979. bool allowOp = operatorDef->mOperatorDeclaration->mBinOp == findBinaryOp;
  21980. if ((isComparison) && (operatorDef->mOperatorDeclaration->mBinOp == BfBinaryOp_Compare))
  21981. allowOp = true;
  21982. if (allowOp)
  21983. {
  21984. foundOp = true;
  21985. if (!methodMatcher.IsMemberAccessible(checkType, operatorDef->mDeclaringType))
  21986. continue;
  21987. if ((flags & BfBinOpFlag_IsConstraintCheck) != 0)
  21988. {
  21989. if (operatorDef->mGenericParams.IsEmpty())
  21990. {
  21991. // Fast check
  21992. auto returnType = mModule->CheckOperator(checkType, operatorDef, args[0].mTypedValue, args[1].mTypedValue);
  21993. if (returnType != NULL)
  21994. {
  21995. operatorConstraintReturnType = returnType;
  21996. methodMatcher.mBestMethodDef = operatorDef;
  21997. methodMatcher.mBestMethodTypeInstance = checkType;
  21998. foundExactMatch = true;
  21999. }
  22000. }
  22001. else
  22002. {
  22003. if (methodMatcher.CheckMethod(NULL, checkType, operatorDef, false))
  22004. {
  22005. auto rawMethodInstance = mModule->GetRawMethodInstance(checkType, operatorDef);
  22006. auto returnType = mModule->ResolveGenericType(rawMethodInstance->mReturnType, NULL, &methodMatcher.mBestMethodGenericArguments,
  22007. mModule->mCurTypeInstance);
  22008. if (returnType != NULL)
  22009. {
  22010. operatorConstraintReturnType = returnType;
  22011. foundExactMatch = true;
  22012. }
  22013. }
  22014. }
  22015. }
  22016. else
  22017. {
  22018. if (methodMatcher.CheckMethod(NULL, checkType, operatorDef, false))
  22019. {
  22020. methodMatcher.mSelfType = entry.mSrcType;
  22021. if (operatorDef->mOperatorDeclaration->mBinOp == findBinaryOp)
  22022. foundExactMatch = true;
  22023. }
  22024. }
  22025. }
  22026. else if ((operatorDef->mOperatorDeclaration->mBinOp == oppositeBinaryOp) || (operatorDef->mOperatorDeclaration->mBinOp == overflowBinaryOp))
  22027. oppositeOperatorDefs.Add(operatorDef);
  22028. }
  22029. if ((((methodMatcher.mBestMethodDef == NULL) && (operatorConstraintReturnType == NULL)) || (!foundExactMatch)) && (!oppositeOperatorDefs.IsEmpty()))
  22030. {
  22031. foundOp = true;
  22032. for (auto oppositeOperatorDef : oppositeOperatorDefs)
  22033. {
  22034. if ((flags & BfBinOpFlag_IsConstraintCheck) != 0)
  22035. {
  22036. if (oppositeOperatorDef->mGenericParams.IsEmpty())
  22037. {
  22038. // Fast check
  22039. auto returnType = mModule->CheckOperator(checkType, oppositeOperatorDef, args[0].mTypedValue, args[1].mTypedValue);
  22040. if (returnType != NULL)
  22041. {
  22042. operatorConstraintReturnType = returnType;
  22043. methodMatcher.mBestMethodDef = oppositeOperatorDef;
  22044. methodMatcher.mBestMethodTypeInstance = checkType;
  22045. methodMatcher.mSelfType = entry.mSrcType;
  22046. if (oppositeBinaryOp != BfBinaryOp_None)
  22047. wasTransformedUsage = true;
  22048. }
  22049. }
  22050. else
  22051. {
  22052. if (methodMatcher.CheckMethod(NULL, checkType, oppositeOperatorDef, false))
  22053. {
  22054. auto rawMethodInstance = mModule->GetRawMethodInstance(checkType, oppositeOperatorDef);
  22055. auto returnType = mModule->ResolveGenericType(rawMethodInstance->mReturnType, NULL, &methodMatcher.mBestMethodGenericArguments,
  22056. mModule->mCurTypeInstance);
  22057. if (returnType != NULL)
  22058. {
  22059. operatorConstraintReturnType = returnType;
  22060. methodMatcher.mSelfType = entry.mSrcType;
  22061. if (oppositeBinaryOp != BfBinaryOp_None)
  22062. wasTransformedUsage = true;
  22063. }
  22064. }
  22065. }
  22066. }
  22067. else
  22068. {
  22069. if (methodMatcher.CheckMethod(NULL, checkType, oppositeOperatorDef, false))
  22070. {
  22071. methodMatcher.mSelfType = entry.mSrcType;
  22072. if (oppositeBinaryOp != BfBinaryOp_None)
  22073. wasTransformedUsage = true;
  22074. }
  22075. }
  22076. }
  22077. }
  22078. }
  22079. bool hadMatch = (methodMatcher.mBestMethodDef != NULL);
  22080. if ((methodMatcher.mBestMethodDef != NULL) && ((flags & BfBinOpFlag_IgnoreOperatorWithWrongResult) != 0))
  22081. {
  22082. auto matchedOp = ((BfOperatorDeclaration*)methodMatcher.mBestMethodDef->mMethodDeclaration)->mBinOp;
  22083. methodMatcher.mBestMethodInstance = GetSelectedMethod(methodMatcher.mTargetSrc, methodMatcher.mBestMethodTypeInstance, methodMatcher.mBestMethodDef, methodMatcher);
  22084. if ((methodMatcher.mBestMethodInstance.mMethodInstance->mReturnType != mExpectingType) &&
  22085. ((matchedOp == binaryOp) || (matchedOp == oppositeBinaryOp)))
  22086. {
  22087. if (binaryOp == BfBinaryOp_Equality)
  22088. binaryOp = BfBinaryOp_StrictEquality;
  22089. if (binaryOp == BfBinaryOp_InEquality)
  22090. binaryOp = BfBinaryOp_StrictEquality;
  22091. hadMatch = false;
  22092. break;
  22093. }
  22094. }
  22095. if (hadMatch)
  22096. {
  22097. methodMatcher.FlushAmbiguityError();
  22098. auto matchedOp = ((BfOperatorDeclaration*)methodMatcher.mBestMethodDef->mMethodDeclaration)->mBinOp;
  22099. bool invertResult = matchedOp == oppositeBinaryOp;
  22100. auto methodDef = methodMatcher.mBestMethodDef;
  22101. auto autoComplete = GetAutoComplete();
  22102. bool wasCapturingMethodInfo = false;
  22103. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(opToken)))
  22104. {
  22105. auto operatorDecl = BfNodeDynCast<BfOperatorDeclaration>(methodDef->mMethodDeclaration);
  22106. if ((operatorDecl != NULL) && (operatorDecl->mOpTypeToken != NULL))
  22107. autoComplete->SetDefinitionLocation(operatorDecl->mOpTypeToken);
  22108. }
  22109. if ((wasTransformedUsage) && (methodDef->mCommutableKind != BfCommutableKind_Operator))
  22110. {
  22111. auto error = mModule->Warn(BfWarning_BF4206_OperatorCommutableUsage, "Transformed operator usage requires 'Commutable' attribute to be added to the operator declaration", opToken);
  22112. if ((error != NULL) && (methodDef->GetRefNode() != NULL))
  22113. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See operator declaration"), methodDef->GetRefNode());
  22114. }
  22115. if (opToken != NULL)
  22116. {
  22117. if ((opToken->IsA<BfTokenNode>()) && (!noClassify) && (!baseClassWalker.mMayBeFromInterface))
  22118. mModule->SetElementType(opToken, BfSourceElementType_Method);
  22119. }
  22120. if ((flags & BfBinOpFlag_IsConstraintCheck) != 0)
  22121. {
  22122. mResult = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), operatorConstraintReturnType);
  22123. }
  22124. else
  22125. {
  22126. SetAndRestoreValue<BfEvalExprFlags> prevFlags(mBfEvalExprFlags, (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_NoAutoComplete));
  22127. mResult = CreateCall(&methodMatcher, BfTypedValue());
  22128. }
  22129. if ((mResult.mType != NULL) && (methodMatcher.mSelfType != NULL) && (mResult.mType->IsSelf()))
  22130. {
  22131. BF_ASSERT(mModule->IsInGeneric());
  22132. mResult = mModule->GetDefaultTypedValue(methodMatcher.mSelfType, false, BfDefaultValueKind_Value);
  22133. }
  22134. if ((invertResult) && (mResult.mType == mModule->GetPrimitiveType(BfTypeCode_Boolean)))
  22135. mResult.mValue = mModule->mBfIRBuilder->CreateNot(mResult.mValue);
  22136. if (pass == 1)
  22137. {
  22138. if (findBinaryOp == BfBinaryOp_Compare)
  22139. {
  22140. mResult = mModule->LoadValue(mResult);
  22141. if (mResult.mType->IsIntegral())
  22142. mResult.mValue = mModule->mBfIRBuilder->CreateNeg(mResult.mValue);
  22143. }
  22144. }
  22145. if ((isComparison) && (matchedOp == BfBinaryOp_Compare))
  22146. {
  22147. auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  22148. mResult = mModule->LoadValue(mResult);
  22149. if (mResult.mType != intType)
  22150. mResult = mModule->GetDefaultTypedValue(intType);
  22151. auto zeroVal = mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0);
  22152. auto useBinaryOp = binaryOp;
  22153. if (pass == 1)
  22154. useBinaryOp = BfGetFlippedBinaryOp(useBinaryOp);
  22155. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  22156. switch (useBinaryOp)
  22157. {
  22158. case BfBinaryOp_Equality:
  22159. case BfBinaryOp_StrictEquality:
  22160. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(mResult.mValue, zeroVal), boolType);
  22161. break;
  22162. case BfBinaryOp_InEquality:
  22163. case BfBinaryOp_StrictInEquality:
  22164. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(mResult.mValue, zeroVal), boolType);
  22165. break;
  22166. case BfBinaryOp_GreaterThan:
  22167. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpGT(mResult.mValue, zeroVal, true), boolType);
  22168. break;
  22169. case BfBinaryOp_LessThan:
  22170. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpLT(mResult.mValue, zeroVal, true), boolType);
  22171. break;
  22172. case BfBinaryOp_GreaterThanOrEqual:
  22173. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpGTE(mResult.mValue, zeroVal, true), boolType);
  22174. break;
  22175. case BfBinaryOp_LessThanOrEqual:
  22176. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpLTE(mResult.mValue, zeroVal, true), boolType);
  22177. break;
  22178. default: break;
  22179. }
  22180. }
  22181. return;
  22182. }
  22183. auto _CheckBinaryOp = [&](BfGenericParamInstance* genericParam)
  22184. {
  22185. for (auto& opConstraint : genericParam->mOperatorConstraints)
  22186. {
  22187. BfType* returnType = genericParam->mExternType;
  22188. bool works = false;
  22189. if (opConstraint.mBinaryOp == findBinaryOp)
  22190. {
  22191. if (((args[0].mTypedValue) && (mModule->CanCast(args[0].mTypedValue, opConstraint.mLeftType))) &&
  22192. ((args[1].mTypedValue) && (mModule->CanCast(args[1].mTypedValue, opConstraint.mRightType))))
  22193. {
  22194. works = true;
  22195. }
  22196. }
  22197. if ((isComparison) && (opConstraint.mBinaryOp == BfBinaryOp_Compare))
  22198. {
  22199. if (((args[0].mTypedValue) && (mModule->CanCast(args[0].mTypedValue, opConstraint.mLeftType))) &&
  22200. ((args[1].mTypedValue) && (mModule->CanCast(args[1].mTypedValue, opConstraint.mRightType))))
  22201. {
  22202. works = true;
  22203. }
  22204. else if (((args[0].mTypedValue) && (mModule->CanCast(args[0].mTypedValue, opConstraint.mRightType))) &&
  22205. ((args[1].mTypedValue) && (mModule->CanCast(args[1].mTypedValue, opConstraint.mLeftType))))
  22206. {
  22207. works = true;
  22208. }
  22209. if (works)
  22210. {
  22211. returnType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  22212. }
  22213. }
  22214. if (works)
  22215. {
  22216. BF_ASSERT(genericParam->mExternType != NULL);
  22217. mResult = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), returnType);
  22218. return true;
  22219. }
  22220. }
  22221. return false;
  22222. };
  22223. // Check method generic constraints
  22224. if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsUnspecialized) && (mModule->mCurMethodInstance->mMethodInfoEx != NULL))
  22225. {
  22226. for (int genericParamIdx = 0; genericParamIdx < mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams.size(); genericParamIdx++)
  22227. {
  22228. auto genericParam = mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
  22229. if (_CheckBinaryOp(genericParam))
  22230. return;
  22231. }
  22232. }
  22233. // Check type generic constraints
  22234. if ((mModule->mCurTypeInstance->IsGenericTypeInstance()) && (mModule->mCurTypeInstance->IsUnspecializedType()))
  22235. {
  22236. SizedArray<BfGenericParamInstance*, 4> genericParams;
  22237. mModule->GetActiveTypeGenericParamInstances(genericParams);
  22238. for (auto genericParam : genericParams)
  22239. {
  22240. if (_CheckBinaryOp(genericParam))
  22241. return;
  22242. }
  22243. }
  22244. if (pass == 1)
  22245. break;
  22246. auto flippedBinaryOp = BfGetFlippedBinaryOp(findBinaryOp);
  22247. if (flippedBinaryOp != BfBinaryOp_None)
  22248. findBinaryOp = flippedBinaryOp;
  22249. }
  22250. auto _FixOpCheckGenericParam = [&](BfTypedValue& typedVal)
  22251. {
  22252. if ((typedVal.mType != NULL) && (typedVal.mType->IsGenericParam()))
  22253. {
  22254. auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)typedVal.mType);
  22255. if (genericParamInstance->mTypeConstraint != NULL)
  22256. {
  22257. typedVal.mType = genericParamInstance->mTypeConstraint;
  22258. return true;
  22259. }
  22260. }
  22261. return false;
  22262. };
  22263. auto leftTypeConstraint = mModule->GetGenericParamInstanceTypeConstraint(leftValue.mType);
  22264. auto rightTypeConstraint = mModule->GetGenericParamInstanceTypeConstraint(rightValue.mType);
  22265. if ((leftTypeConstraint != NULL) || (rightTypeConstraint != NULL))
  22266. {
  22267. // Handle cases such as 'where T : float'
  22268. bool needNewCheck = false;
  22269. BfTypedValue newLeftValue = leftValue;
  22270. if ((leftTypeConstraint != NULL) && (!leftTypeConstraint->IsGenericParam()))
  22271. {
  22272. newLeftValue.mType = leftTypeConstraint;
  22273. needNewCheck = true;
  22274. }
  22275. BfTypedValue newRightValue = rightValue;
  22276. if ((rightTypeConstraint != NULL) && (!rightTypeConstraint->IsGenericParam()))
  22277. {
  22278. newRightValue.mType = rightTypeConstraint;
  22279. needNewCheck = true;
  22280. }
  22281. if (needNewCheck)
  22282. {
  22283. PerformBinaryOperation(leftExpression, rightExpression, binaryOp, opToken, flags, newLeftValue, newRightValue);
  22284. EnsureResultNotConstant();
  22285. return;
  22286. }
  22287. }
  22288. bool resultHandled = false;
  22289. if (((origLeftType != NULL) && (origLeftType->IsIntUnknown())) ||
  22290. ((origRightType != NULL) && (origRightType->IsIntUnknown())))
  22291. {
  22292. if (!resultType->IsPrimitiveType())
  22293. {
  22294. BfType* numericCastType = mModule->GetClosestNumericCastType(*resultTypedValue, mExpectingType);
  22295. if (numericCastType != NULL)
  22296. {
  22297. resultHandled = true;
  22298. resultType = numericCastType;
  22299. }
  22300. }
  22301. }
  22302. if (!resultHandled)
  22303. {
  22304. auto prevResultType = resultType;
  22305. if ((leftValue.mType->IsPrimitiveType()) && (!origLeftType->IsIntUnknown()) && (!rightValue.mType->IsTypedPrimitive()))
  22306. resultType = leftValue.mType;
  22307. if ((rightValue.mType->IsPrimitiveType()) && (!origRightType->IsIntUnknown()) && (!leftValue.mType->IsTypedPrimitive()))
  22308. resultType = rightValue.mType;
  22309. }
  22310. }
  22311. }
  22312. if (deferRight)
  22313. {
  22314. auto expectedType = resultType;
  22315. if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift))
  22316. expectedType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  22317. rightValue = mModule->CreateValueFromExpression(BfNodeDynCast<BfExpression>(rightExpression), expectedType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_AllowSplat | BfEvalExprFlags_NoCast));
  22318. if (rightValue)
  22319. PerformBinaryOperation(leftExpression, rightExpression, binaryOp, opToken, (BfBinOpFlags)(flags & ~BfBinOpFlag_DeferRight), leftValue, rightValue);
  22320. return;
  22321. }
  22322. if (mModule->IsUnboundGeneric(resultType))
  22323. {
  22324. mResult = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Var));
  22325. return;
  22326. }
  22327. if (resultType->IsPointer() && otherType->IsPointer())
  22328. {
  22329. if ((binaryOp == BfBinaryOp_Add) && (resultType == otherType) &&
  22330. (resultType->GetUnderlyingType() == mModule->GetPrimitiveType(BfTypeCode_Char8)))
  22331. {
  22332. AddStrings(leftValue, rightValue, opToken);
  22333. return;
  22334. }
  22335. //TODO: Allow all pointer comparisons, but only allow SUBTRACTION between equal pointer types
  22336. if ((binaryOp == BfBinaryOp_Subtract) || (binaryOp == BfBinaryOp_OverflowSubtract))
  22337. {
  22338. if (!mModule->CanCast(*otherTypedValue, resultType))
  22339. {
  22340. mModule->Fail(StrFormat("Operands '%s' and '%s' are not comparable types.",
  22341. mModule->TypeToString(leftValue.mType).c_str(), mModule->TypeToString(rightValue.mType).c_str()),
  22342. opToken);
  22343. return;
  22344. }
  22345. BfPointerType* resultPointerType = (BfPointerType*)resultType;
  22346. BfType* intPtrType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  22347. if (resultPointerType->mElementType->mSize == 0)
  22348. {
  22349. if (!mModule->IsInSpecializedSection())
  22350. mModule->Warn(0, "Subtracting pointers to zero-sized elements will always result in zero", opToken);
  22351. mResult = mModule->GetDefaultTypedValue(intPtrType);
  22352. }
  22353. else
  22354. {
  22355. convLeftValue = mModule->CastToValue(leftExpression, leftValue, intPtrType, (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_FromCompiler));
  22356. convRightValue = mModule->CastToValue(rightExpression, rightValue, intPtrType, (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_FromCompiler));
  22357. BfIRValue diffValue = mModule->mBfIRBuilder->CreateSub(convLeftValue, convRightValue);
  22358. diffValue = mModule->mBfIRBuilder->CreateDiv(diffValue, mModule->GetConstValue(resultPointerType->mElementType->GetStride(), intPtrType), true);
  22359. mResult = BfTypedValue(diffValue, intPtrType);
  22360. }
  22361. return;
  22362. }
  22363. else if ((binaryOp != BfBinaryOp_Equality) && (binaryOp != BfBinaryOp_StrictEquality) &&
  22364. (binaryOp != BfBinaryOp_InEquality) && (binaryOp != BfBinaryOp_StrictInEquality) &&
  22365. (binaryOp != BfBinaryOp_LessThan) && (binaryOp != BfBinaryOp_LessThanOrEqual) &&
  22366. (binaryOp != BfBinaryOp_GreaterThan) && (binaryOp != BfBinaryOp_GreaterThanOrEqual))
  22367. {
  22368. if (mModule->PreFail())
  22369. mModule->Fail("Invalid operation on pointers", opToken);
  22370. return;
  22371. }
  22372. if ((!BfBinOpEqualityCheck(binaryOp)) || (resultType != otherType))
  22373. {
  22374. resultType = mModule->GetPrimitiveType(BfTypeCode_UIntPtr);
  22375. explicitCast = true;
  22376. }
  22377. }
  22378. else if (resultType->IsPointer())
  22379. {
  22380. if (otherType->IsNull())
  22381. {
  22382. if (!BfBinOpEqualityCheck(binaryOp))
  22383. {
  22384. if (mModule->PreFail())
  22385. mModule->Fail(StrFormat("Invalid operation between '%s' and null", mModule->TypeToString(resultType).c_str()), opToken);
  22386. return;
  22387. }
  22388. if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality))
  22389. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateIsNull(resultTypedValue->mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  22390. else
  22391. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateIsNotNull(resultTypedValue->mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  22392. return;
  22393. }
  22394. // One pointer
  22395. if ((!otherType->IsIntegral()) ||
  22396. ((binaryOp != BfBinaryOp_Add) && (binaryOp != BfBinaryOp_Subtract) && (binaryOp != BfBinaryOp_OverflowAdd) && (binaryOp != BfBinaryOp_OverflowSubtract)))
  22397. {
  22398. _OpFail();
  22399. return;
  22400. }
  22401. auto underlyingType = resultType->GetUnderlyingType();
  22402. if ((underlyingType->IsSizedArray()) && (!mModule->IsInSpecializedSection()))
  22403. mModule->Warn(0, "Performing arithmetic on a pointer to a sized array. Consider performing arithmetic on an element pointer if this is not intended.", resultTypeSrc);
  22404. BfIRValue addValue = otherTypedValue->mValue;
  22405. if ((!otherTypedValue->mType->IsSigned()) && (otherTypedValue->mType->mSize < mModule->mSystem->mPtrSize))
  22406. addValue = mModule->mBfIRBuilder->CreateNumericCast(addValue, false, BfTypeCode_UIntPtr);
  22407. if ((binaryOp == BfBinaryOp_Subtract) || (binaryOp == BfBinaryOp_OverflowSubtract))
  22408. {
  22409. if (resultTypeSrc == rightExpression)
  22410. mModule->Fail("Cannot subtract a pointer from an integer", resultTypeSrc);
  22411. addValue = mModule->mBfIRBuilder->CreateNeg(addValue);
  22412. }
  22413. mModule->PopulateType(underlyingType);
  22414. if (underlyingType->IsValuelessType())
  22415. {
  22416. if (!mModule->IsInSpecializedSection())
  22417. mModule->Warn(0, "Adding to a pointer to a zero-sized element has no effect", opToken);
  22418. mResult = *resultTypedValue;
  22419. return;
  22420. }
  22421. mModule->mBfIRBuilder->PopulateType(underlyingType);
  22422. mResult = BfTypedValue(mModule->CreateIndexedValue(underlyingType, resultTypedValue->mValue, addValue), resultType);
  22423. return;
  22424. }
  22425. if ((resultType->IsFunction()) || (resultType->IsPointer()) || (resultType->IsObject()) || (resultType->IsInterface()) || (resultType->IsGenericParam()))
  22426. {
  22427. if ((binaryOp == BfBinaryOp_Add) &&
  22428. (resultType->IsInstanceOf(mModule->mCompiler->mStringTypeDef)) &&
  22429. (otherType->IsInstanceOf(mModule->mCompiler->mStringTypeDef)))
  22430. {
  22431. AddStrings(leftValue, rightValue, opToken);
  22432. return;
  22433. }
  22434. if (!BfGetBinaryOpPrecendence(binaryOp))
  22435. {
  22436. //mModule->Fail("Invalid operation for objects", opToken);
  22437. _OpFail();
  22438. return;
  22439. }
  22440. if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality) || (binaryOp == BfBinaryOp_InEquality) || (binaryOp == BfBinaryOp_StrictInEquality))
  22441. {
  22442. leftValue = mModule->LoadOrAggregateValue(leftValue);
  22443. rightValue = mModule->LoadOrAggregateValue(rightValue);
  22444. if (resultType->IsInterface())
  22445. {
  22446. // Compare as objects instead
  22447. resultType = mModule->mContext->mBfObjectType;
  22448. *resultTypedValue = mModule->Cast(resultTypeSrc, *resultTypedValue, resultType);
  22449. }
  22450. if (otherType->IsNull())
  22451. {
  22452. if (resultType->IsFunction())
  22453. {
  22454. if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality))
  22455. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0), resultTypedValue->mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  22456. else
  22457. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0), resultTypedValue->mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  22458. }
  22459. else
  22460. {
  22461. if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality))
  22462. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateIsNull(resultTypedValue->mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  22463. else
  22464. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateIsNotNull(resultTypedValue->mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  22465. }
  22466. }
  22467. else
  22468. {
  22469. auto convertedValue = mModule->Cast(otherTypeSrc, *otherTypedValue, resultType, BfCastFlags_NoBox);
  22470. if (!convertedValue)
  22471. return;
  22472. convertedValue = mModule->LoadValue(convertedValue);
  22473. if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality))
  22474. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(resultTypedValue->mValue, convertedValue.mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  22475. else
  22476. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(resultTypedValue->mValue, convertedValue.mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  22477. }
  22478. return;
  22479. }
  22480. }
  22481. if (resultType->IsTypedPrimitive())
  22482. {
  22483. bool needsOtherCast = true;
  22484. if (otherType != resultType)
  22485. {
  22486. if ((otherType->IsPrimitiveType()) && (!otherType->IsValuelessType()))
  22487. {
  22488. // Allow zero comparisons to match all typed primitives
  22489. if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_InEquality))
  22490. {
  22491. auto constant = mModule->mBfIRBuilder->GetConstant(otherTypedValue->mValue);
  22492. if ((constant != NULL) && (mModule->mBfIRBuilder->IsInt(constant->mTypeCode)) && (constant->mInt64 == 0))
  22493. needsOtherCast = false;
  22494. }
  22495. // Allow integer offsetting
  22496. if ((binaryOp == BfBinaryOp_Add) || (binaryOp == BfBinaryOp_Subtract) || (binaryOp == BfBinaryOp_OverflowAdd) || (binaryOp == BfBinaryOp_OverflowSubtract))
  22497. {
  22498. if (otherType->IsIntegral())
  22499. needsOtherCast = false;
  22500. }
  22501. }
  22502. if (needsOtherCast)
  22503. {
  22504. BfCastFlags castFlags = (BfCastFlags)((explicitCast ? BfCastFlags_Explicit : BfCastFlags_None) | BfCastFlags_SilentFail);
  22505. BfIRValue otherCastResult = mModule->CastToValue(otherTypeSrc, *otherTypedValue, resultType, castFlags);
  22506. if (!otherCastResult)
  22507. {
  22508. // We picked the wrong type, try the other one...
  22509. if (mModule->CanCast(*resultTypedValue, otherType))
  22510. {
  22511. BfBinOpFlags newFlags = flags;
  22512. if (otherTypedValue == &leftValue)
  22513. newFlags = (BfBinOpFlags)(flags | BfBinOpFlag_ForceLeftType & ~BfBinOpFlag_ForceRightType & ~BfBinOpFlag_DeferRight);
  22514. else
  22515. newFlags = (BfBinOpFlags)(flags | BfBinOpFlag_ForceRightType & ~BfBinOpFlag_ForceLeftType & ~BfBinOpFlag_DeferRight);
  22516. return PerformBinaryOperation(leftExpression, rightExpression, binaryOp, opToken, newFlags, leftValue, rightValue);
  22517. }
  22518. // Do again but with an error
  22519. castFlags = (BfCastFlags)(castFlags & ~BfCastFlags_SilentFail);
  22520. otherCastResult = mModule->CastToValue(otherTypeSrc, *otherTypedValue, resultType, castFlags);
  22521. }
  22522. }
  22523. }
  22524. auto underlyingType = resultType->GetUnderlyingType();
  22525. if ((binaryOp == BfBinaryOp_Subtract) && (otherTypedValue->mType == resultType))
  22526. {
  22527. intptr maxDist = 0;
  22528. auto resultTypeInstance = resultType->ToTypeInstance();
  22529. if ((resultTypeInstance != NULL) && (resultTypeInstance->mTypeInfoEx != NULL))
  22530. maxDist = resultTypeInstance->mTypeInfoEx->mMaxValue - resultTypeInstance->mTypeInfoEx->mMinValue;
  22531. if (maxDist >= 0x80000000UL)
  22532. resultType = mModule->GetPrimitiveType(BfTypeCode_Int64);
  22533. else if (maxDist >= 0x8000)
  22534. resultType = mModule->GetPrimitiveType(BfTypeCode_Int32);
  22535. else if (maxDist >= 0x80)
  22536. resultType = mModule->GetPrimitiveType(BfTypeCode_Int16);
  22537. else
  22538. resultType = mModule->GetPrimitiveType(BfTypeCode_Int8);
  22539. underlyingType = resultType;
  22540. }
  22541. BfIRValue convResultValue;
  22542. if (resultTypedValue->mType == resultType)
  22543. convResultValue = mModule->LoadValue(*resultTypedValue).mValue;
  22544. else
  22545. convResultValue = mModule->CastToValue(resultTypeSrc, *resultTypedValue, underlyingType, BfCastFlags_Explicit);
  22546. BfIRValue convOtherValue;
  22547. if (otherTypedValue->mType == resultType)
  22548. convOtherValue = mModule->LoadValue(*otherTypedValue).mValue;
  22549. else
  22550. convOtherValue = mModule->CastToValue(otherTypeSrc, *otherTypedValue, underlyingType, BfCastFlags_Explicit);
  22551. if ((!underlyingType->IsValuelessType()) && ((!convResultValue) || (!convOtherValue)))
  22552. return;
  22553. if (resultTypedValue == &leftValue)
  22554. PerformBinaryOperation(underlyingType, convResultValue, convOtherValue, binaryOp, opToken);
  22555. else
  22556. PerformBinaryOperation(underlyingType, convOtherValue, convResultValue, binaryOp, opToken);
  22557. if (mResult.mType == underlyingType)
  22558. mResult.mType = resultType;
  22559. return;
  22560. }
  22561. auto _CallValueTypeEquals = [&]()
  22562. {
  22563. BfModuleMethodInstance moduleMethodInstance;
  22564. auto typeInst = leftValue.mType->ToTypeInstance();
  22565. if (typeInst != NULL)
  22566. {
  22567. if ((binaryOp == BfBinaryOp_StrictEquality) || (binaryOp == BfBinaryOp_StrictInEquality))
  22568. moduleMethodInstance = mModule->GetMethodByName(typeInst, BF_METHODNAME_DEFAULT_STRICT_EQUALS);
  22569. else
  22570. moduleMethodInstance = mModule->GetMethodByName(typeInst, BF_METHODNAME_DEFAULT_EQUALS);
  22571. }
  22572. else
  22573. {
  22574. BF_ASSERT(leftValue.mType->IsSizedArray() || leftValue.mType->IsMethodRef());
  22575. auto valueTypeInst = mModule->ResolveTypeDef(mModule->mCompiler->mValueTypeTypeDef)->ToTypeInstance();
  22576. BfMethodDef* equalsMethodDef = mModule->mCompiler->mValueTypeTypeDef->GetMethodByName("Equals");
  22577. BfTypeVector typeVec;
  22578. typeVec.push_back(leftValue.mType);
  22579. moduleMethodInstance = mModule->GetMethodInstance(valueTypeInst, equalsMethodDef, typeVec);
  22580. }
  22581. if (moduleMethodInstance)
  22582. {
  22583. if ((opToken != NULL) && (!noClassify))
  22584. mModule->SetElementType(opToken, BfSourceElementType_Method);
  22585. SizedArray<BfResolvedArg, 4> argValues;
  22586. BfResolvedArg resolvedArg;
  22587. resolvedArg.mTypedValue = leftValue;
  22588. argValues.push_back(resolvedArg);
  22589. resolvedArg.mTypedValue = rightValue;
  22590. argValues.push_back(resolvedArg);
  22591. mResult = CreateCall(opToken, BfTypedValue(), BfTypedValue(), moduleMethodInstance.mMethodInstance->mMethodDef, moduleMethodInstance, BfCreateCallFlags_None, argValues);
  22592. if ((mResult) &&
  22593. ((binaryOp == BfBinaryOp_InEquality) || (binaryOp == BfBinaryOp_StrictInEquality)))
  22594. mResult.mValue = mModule->mBfIRBuilder->CreateNot(mResult.mValue);
  22595. return true;
  22596. }
  22597. return false;
  22598. };
  22599. //if (((leftValue.mType->IsComposite()) || (leftValue.mType->IsObject())))
  22600. if (((resultType->IsComposite()) || (resultType->IsObject())))
  22601. {
  22602. bool areEquivalentTuples = false;
  22603. if ((leftValue.mType->IsTuple()) && (rightValue.mType->IsTuple()))
  22604. {
  22605. auto leftTupleType = (BfTypeInstance*)leftValue.mType;
  22606. auto rightTupleType = (BfTypeInstance*)rightValue.mType;
  22607. // We only do this for tuples, because we would allow an implicit struct
  22608. // truncation if we allow it for all structs, which would result in only
  22609. // the base class's fields being compared
  22610. if (mModule->CanCast(rightValue, leftValue.mType))
  22611. rightValue = mModule->Cast(opToken, rightValue, leftValue.mType, BfCastFlags_Explicit);
  22612. else if (mModule->CanCast(leftValue, rightValue.mType))
  22613. leftValue = mModule->Cast(opToken, leftValue, rightValue.mType, BfCastFlags_Explicit);
  22614. }
  22615. if (leftValue.mType == rightValue.mType)
  22616. {
  22617. if (BfBinOpEqualityCheck(binaryOp))
  22618. {
  22619. auto intCoercibleType = mModule->GetIntCoercibleType(leftValue.mType);
  22620. if (intCoercibleType != NULL)
  22621. {
  22622. auto intLHS = mModule->GetIntCoercible(leftValue);
  22623. auto intRHS = mModule->GetIntCoercible(rightValue);
  22624. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  22625. if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality))
  22626. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(intLHS.mValue, intRHS.mValue), boolType);
  22627. else
  22628. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(intLHS.mValue, intRHS.mValue), boolType);
  22629. return;
  22630. }
  22631. // Valueless types always compare as 'equal' if we can ensure no members could have an equality operator overload
  22632. if (leftValue.mType->IsComposite())
  22633. {
  22634. mModule->PopulateType(leftValue.mType);
  22635. if (leftValue.mType->IsValuelessType())
  22636. {
  22637. bool mayHaveEqualOverload = false;
  22638. auto leftTypeInst = leftValue.mType->ToTypeInstance();
  22639. if (leftTypeInst != NULL)
  22640. {
  22641. std::function<bool(BfType*)> _HasTypeInstance = [&](BfType* type)
  22642. {
  22643. if (type == NULL)
  22644. return false;
  22645. if (type->IsTypeInstance())
  22646. return true;
  22647. if (type->IsSizedArray())
  22648. return _HasTypeInstance(((BfSizedArrayType*)type)->mElementType);
  22649. return false;
  22650. };
  22651. for (auto& fieldInstance : leftTypeInst->mFieldInstances)
  22652. {
  22653. if (_HasTypeInstance(fieldInstance.mResolvedType))
  22654. mayHaveEqualOverload = true;
  22655. }
  22656. }
  22657. if (!mayHaveEqualOverload)
  22658. {
  22659. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  22660. bool isEqual = (binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality);
  22661. mResult = BfTypedValue(mModule->GetConstValue(isEqual ? 1 : 0, boolType), boolType);
  22662. return;
  22663. }
  22664. }
  22665. }
  22666. if (_CallValueTypeEquals())
  22667. return;
  22668. }
  22669. if (PerformBinaryOperation_Numeric(leftExpression, rightExpression, binaryOp, opToken, flags, leftValue, rightValue))
  22670. return;
  22671. if (mModule->PreFail())
  22672. {
  22673. mModule->Fail(StrFormat("Operator '%s' cannot be applied to operands of type '%s'",
  22674. BfGetOpName(binaryOp),
  22675. mModule->TypeToString(leftValue.mType).c_str()), opToken);
  22676. }
  22677. return;
  22678. }
  22679. else
  22680. {
  22681. bool handled = false;
  22682. for (int pass = 0; pass < 2; pass++)
  22683. {
  22684. BfTypedValue& fromValue = (pass == 0) ? leftValue : rightValue;
  22685. BfType* toType = (pass == 0) ? rightValue.mType : leftValue.mType;
  22686. if (mModule->CanCast(fromValue, toType))
  22687. {
  22688. auto result = mModule->Cast(opToken, fromValue, toType);
  22689. if (result)
  22690. {
  22691. resultType = toType;
  22692. fromValue = result;
  22693. handled = true;
  22694. break;
  22695. }
  22696. }
  22697. }
  22698. if (!handled)
  22699. {
  22700. if ((leftValue.mType->IsUndefSizedArray()) || (rightValue.mType->IsUndefSizedArray()))
  22701. {
  22702. if ((leftValue.mType->IsSizedArray()) && (rightValue.mType->IsSizedArray() &&
  22703. (leftValue.mType->GetUnderlyingType() == rightValue.mType->GetUnderlyingType())))
  22704. {
  22705. if (BfBinOpEqualityCheck(binaryOp))
  22706. {
  22707. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  22708. mResult = mModule->GetDefaultTypedValue(boolType, false, BfDefaultValueKind_Undef);
  22709. return;
  22710. }
  22711. }
  22712. }
  22713. if (PerformBinaryOperation_Numeric(leftExpression, rightExpression, binaryOp, opToken, flags, leftValue, rightValue))
  22714. return;
  22715. mModule->Fail(StrFormat("Operator '%s' cannot be applied to operands of type '%s' and '%s'",
  22716. BfGetOpName(binaryOp),
  22717. mModule->TypeToString(leftValue.mType).c_str(),
  22718. mModule->TypeToString(rightValue.mType).c_str()), opToken);
  22719. return;
  22720. }
  22721. }
  22722. }
  22723. if (resultType->IsMethodRef() && otherType->IsMethodRef())
  22724. {
  22725. if (BfBinOpEqualityCheck(binaryOp))
  22726. {
  22727. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  22728. BfMethodRefType* lhsMethodRefType = (BfMethodRefType*)leftValue.mType;
  22729. BfMethodRefType* rhsMethodRefType = (BfMethodRefType*)rightValue.mType;
  22730. if (lhsMethodRefType->mMethodRef != rhsMethodRefType->mMethodRef)
  22731. {
  22732. mResult = BfTypedValue(mModule->GetConstValue(((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality)) ? 0 : 1, boolType), boolType);
  22733. return;
  22734. }
  22735. if (_CallValueTypeEquals())
  22736. return;
  22737. }
  22738. }
  22739. if (resultType->IsIntegral())
  22740. {
  22741. if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift))
  22742. {
  22743. if (rightValue.mValue.IsConst())
  22744. {
  22745. auto constVal = mModule->mBfIRBuilder->GetConstant(rightValue.mValue);
  22746. if ((constVal->mInt64 < 0) || (constVal->mInt64 >= 8 * resultType->mSize))
  22747. {
  22748. mModule->Fail(StrFormat("Shift value '%lld' is out of range for type '%s'", constVal->mInt64, mModule->TypeToString(resultType).c_str()), opToken);
  22749. }
  22750. }
  22751. }
  22752. // We're trying a simplified scheme that doesn't always try to up-convert into an 'int'
  22753. if (leftValue.mType != rightValue.mType)
  22754. {
  22755. bool isBitwiseExpr =
  22756. (binaryOp == BfBinaryOp_BitwiseAnd) ||
  22757. (binaryOp == BfBinaryOp_BitwiseOr) ||
  22758. (binaryOp == BfBinaryOp_ExclusiveOr) ||
  22759. (binaryOp == BfBinaryOp_LeftShift) ||
  22760. (binaryOp == BfBinaryOp_RightShift) ||
  22761. (binaryOp == BfBinaryOp_Equality) ||
  22762. (binaryOp == BfBinaryOp_InEquality) ||
  22763. (binaryOp == BfBinaryOp_StrictEquality) ||
  22764. (binaryOp == BfBinaryOp_StrictInEquality);
  22765. if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift))
  22766. {
  22767. // For shifts we have more lenient rules - shifts are naturally limited so any int type is equally valid
  22768. if (rightValue.mType->IsIntegral())
  22769. explicitCast = true;
  22770. }
  22771. else if (((binaryOp == BfBinaryOp_Add) || (binaryOp == BfBinaryOp_Subtract) || (binaryOp == BfBinaryOp_OverflowAdd) || (binaryOp == BfBinaryOp_OverflowSubtract)) && (resultType->IsChar()) && (otherType->IsInteger()))
  22772. {
  22773. // charVal += intVal;
  22774. explicitCast = true;
  22775. }
  22776. else if ((!resultType->IsSigned()) && (otherType->IsSigned()))
  22777. {
  22778. if (mModule->CanCast(*otherTypedValue, resultType))
  22779. {
  22780. // If we can convert the 'other' value implicitly then it's a convertible literal, leave as uint
  22781. }
  22782. else
  22783. {
  22784. mModule->Fail(StrFormat("Operator cannot be applied to operands of type '%s' and '%s'",
  22785. mModule->TypeToString(leftValue.mType).c_str(),
  22786. mModule->TypeToString(rightValue.mType).c_str()), opToken);
  22787. return;
  22788. }
  22789. }
  22790. else if ((isBitwiseExpr) && (otherType->IsIntegral()) && (resultType->mSize == otherType->mSize))
  22791. {
  22792. // Forget about signed/unsigned mismatches for bitwise operations
  22793. explicitCast = true;
  22794. }
  22795. else
  22796. {
  22797. if (((binaryOp == BfBinaryOp_Subtract) || (binaryOp == BfBinaryOp_OverflowSubtract)) &&
  22798. (resultType->IsChar()) && (otherType->IsChar()))
  22799. {
  22800. // "wchar - char" subtraction will always fit into int32, because of unicode range
  22801. resultType = mModule->GetPrimitiveType(BfTypeCode_Int32);
  22802. explicitCast = true;
  22803. }
  22804. else if ((otherType->IsChar()) &&
  22805. ((binaryOp == BfBinaryOp_Add) || (binaryOp == BfBinaryOp_Subtract) || (binaryOp == BfBinaryOp_OverflowAdd) || (binaryOp == BfBinaryOp_OverflowSubtract)))
  22806. {
  22807. mModule->Fail(StrFormat("Cannot perform operation between types '%s' and '%s'",
  22808. mModule->TypeToString(leftValue.mType).c_str(),
  22809. mModule->TypeToString(rightValue.mType).c_str()), opToken);
  22810. }
  22811. }
  22812. }
  22813. else if ((!resultType->IsSigned()) && (binaryOp == BfBinaryOp_Subtract) && (!forceLeftType))
  22814. {
  22815. if ((mExpectingType == NULL) || (mExpectingType->IsSigned()) || (resultType->IsChar()))
  22816. {
  22817. if ((resultType->IsChar()) && (resultType->mSize == 4))
  22818. {
  22819. // "wchar - wchar" subtraction will always fit into int32, because of unicode range
  22820. resultType = mModule->GetPrimitiveType(BfTypeCode_Int32);
  22821. }
  22822. else
  22823. {
  22824. // The result of uint8 - uint8 is int16 (for example)
  22825. switch (resultType->mSize)
  22826. {
  22827. case 1:
  22828. resultType = mModule->GetPrimitiveType(BfTypeCode_Int16);
  22829. break;
  22830. case 2:
  22831. resultType = mModule->GetPrimitiveType(BfTypeCode_Int32);
  22832. break;
  22833. case 4:
  22834. resultType = mModule->GetPrimitiveType(BfTypeCode_Int64);
  22835. break;
  22836. }
  22837. }
  22838. explicitCast = true;
  22839. }
  22840. }
  22841. else if (resultType->IsChar())
  22842. {
  22843. bool canDoOp =
  22844. (binaryOp == BfBinaryOp_BitwiseAnd) ||
  22845. (binaryOp == BfBinaryOp_BitwiseOr) ||
  22846. ((binaryOp >= BfBinaryOp_Equality) && (binaryOp <= BfBinaryOp_Compare));
  22847. if (!canDoOp)
  22848. {
  22849. mModule->Fail(StrFormat("Cannot perform operation on type '%s'", mModule->TypeToString(resultType).c_str()), opToken);
  22850. return;
  22851. }
  22852. }
  22853. }
  22854. if (!convLeftValue)
  22855. convLeftValue = mModule->CastToValue(leftExpression, leftValue, resultType,
  22856. explicitCast ? (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_FromCompiler) : BfCastFlags_None);
  22857. if (!convRightValue)
  22858. convRightValue = mModule->CastToValue(rightExpression, rightValue, resultType,
  22859. explicitCast ? (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_FromCompiler) : BfCastFlags_None);
  22860. PerformBinaryOperation(resultType, convLeftValue, convRightValue, binaryOp, opToken);
  22861. }
  22862. void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convLeftValue, BfIRValue convRightValue, BfBinaryOp binaryOp, BfAstNode* opToken)
  22863. {
  22864. if (resultType->IsValuelessType())
  22865. {
  22866. switch (binaryOp)
  22867. {
  22868. case BfBinaryOp_Equality:
  22869. case BfBinaryOp_StrictEquality:
  22870. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 1),
  22871. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  22872. return;
  22873. case BfBinaryOp_InEquality:
  22874. case BfBinaryOp_StrictInEquality:
  22875. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 0),
  22876. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  22877. return;
  22878. default:
  22879. break;
  22880. }
  22881. }
  22882. if ((!convLeftValue) || (!convRightValue))
  22883. return;
  22884. if (resultType->IsPrimitiveType())
  22885. {
  22886. auto primType = (BfPrimitiveType*)resultType;
  22887. if (primType->mTypeDef->mTypeCode == BfTypeCode_Boolean)
  22888. {
  22889. bool passThrough = false;
  22890. switch (binaryOp)
  22891. {
  22892. case BfBinaryOp_Equality:
  22893. case BfBinaryOp_StrictEquality:
  22894. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(convLeftValue, convRightValue),
  22895. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  22896. break;
  22897. case BfBinaryOp_InEquality:
  22898. case BfBinaryOp_StrictInEquality:
  22899. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(convLeftValue, convRightValue),
  22900. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  22901. break;
  22902. case BfBinaryOp_BitwiseAnd:
  22903. case BfBinaryOp_ConditionalAnd:
  22904. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateAnd(convLeftValue, convRightValue),
  22905. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  22906. break;
  22907. case BfBinaryOp_BitwiseOr:
  22908. case BfBinaryOp_ConditionalOr:
  22909. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateOr(convLeftValue, convRightValue),
  22910. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  22911. break;
  22912. case BfBinaryOp_ExclusiveOr:
  22913. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateXor(convLeftValue, convRightValue),
  22914. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  22915. break;
  22916. case BfBinaryOp_Compare:
  22917. passThrough = true;
  22918. break;
  22919. default:
  22920. if (mModule->PreFail())
  22921. mModule->Fail("Invalid operation for booleans", opToken);
  22922. break;
  22923. }
  22924. if (!passThrough)
  22925. return;
  22926. }
  22927. }
  22928. if ((!resultType->IsIntegralOrBool()) && (!resultType->IsFloat()))
  22929. {
  22930. if (mModule->PreFail())
  22931. mModule->Fail(StrFormat("Cannot perform operation on type '%s'", mModule->TypeToString(resultType).c_str()), opToken);
  22932. return;
  22933. }
  22934. if (resultType->IsIntegral())
  22935. {
  22936. switch (binaryOp)
  22937. {
  22938. case BfBinaryOp_BitwiseAnd:
  22939. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateAnd(convLeftValue, convRightValue), resultType);
  22940. return;
  22941. case BfBinaryOp_BitwiseOr:
  22942. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateOr(convLeftValue, convRightValue), resultType);
  22943. return;
  22944. case BfBinaryOp_ExclusiveOr:
  22945. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateXor(convLeftValue, convRightValue), resultType);
  22946. return;
  22947. case BfBinaryOp_LeftShift:
  22948. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateShl(convLeftValue, convRightValue), resultType);
  22949. mModule->CheckRangeError(resultType, opToken);
  22950. return;
  22951. case BfBinaryOp_RightShift:
  22952. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateShr(convLeftValue, convRightValue, resultType->IsSigned()), resultType);
  22953. return;
  22954. default: break;
  22955. }
  22956. }
  22957. if ((resultType->IsChar()) &&
  22958. ((binaryOp == BfBinaryOp_Multiply) ||
  22959. (binaryOp == BfBinaryOp_OverflowMultiply) ||
  22960. (binaryOp == BfBinaryOp_Divide) ||
  22961. (binaryOp == BfBinaryOp_Modulus)))
  22962. {
  22963. mModule->Fail(StrFormat("Cannot perform operation on type '%s'", mModule->TypeToString(resultType).c_str()), opToken);
  22964. return;
  22965. }
  22966. auto _GetOverflowKind = [&](bool wantOverflow)
  22967. {
  22968. if (resultType->IsFloat())
  22969. return BfOverflowCheckKind_None;
  22970. if (!wantOverflow)
  22971. return BfOverflowCheckKind_None;
  22972. if (mModule->GetDefaultCheckedKind() != BfCheckedKind_Checked)
  22973. return BfOverflowCheckKind_None;
  22974. bool arithmeticChecks = mModule->mCompiler->mOptions.mArithmeticChecks;
  22975. auto typeOptions = mModule->GetTypeOptions();
  22976. if (typeOptions != NULL)
  22977. arithmeticChecks = typeOptions->Apply(arithmeticChecks, BfOptionFlags_ArithmeticCheck);
  22978. if (!arithmeticChecks)
  22979. return BfOverflowCheckKind_None;
  22980. BfOverflowCheckKind overflowCheckKind = (resultType->IsSigned()) ? BfOverflowCheckKind_Signed : BfOverflowCheckKind_Unsigned;
  22981. if (!mModule->IsOptimized())
  22982. overflowCheckKind = (BfOverflowCheckKind)(overflowCheckKind | BfOverflowCheckKind_Flag_UseAsm);
  22983. return overflowCheckKind;
  22984. };
  22985. switch (binaryOp)
  22986. {
  22987. case BfBinaryOp_Add:
  22988. case BfBinaryOp_OverflowAdd:
  22989. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateAdd(convLeftValue, convRightValue, _GetOverflowKind(binaryOp == BfBinaryOp_Add)), resultType);
  22990. if (binaryOp != BfBinaryOp_OverflowAdd)
  22991. mModule->CheckRangeError(resultType, opToken);
  22992. break;
  22993. case BfBinaryOp_Subtract:
  22994. case BfBinaryOp_OverflowSubtract:
  22995. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateSub(convLeftValue, convRightValue, _GetOverflowKind(binaryOp == BfBinaryOp_Subtract)), resultType);
  22996. if (binaryOp != BfBinaryOp_OverflowSubtract)
  22997. mModule->CheckRangeError(resultType, opToken);
  22998. break;
  22999. case BfBinaryOp_Multiply:
  23000. case BfBinaryOp_OverflowMultiply:
  23001. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateMul(convLeftValue, convRightValue, _GetOverflowKind(binaryOp == BfBinaryOp_Multiply)), resultType);
  23002. if (binaryOp != BfBinaryOp_OverflowMultiply)
  23003. mModule->CheckRangeError(resultType, opToken);
  23004. break;
  23005. case BfBinaryOp_Divide:
  23006. {
  23007. bool isZero = false;
  23008. if (convRightValue.IsConst())
  23009. {
  23010. auto constVal = mModule->mBfIRBuilder->GetConstant(convRightValue);
  23011. if (BfIRBuilder::IsInt(constVal->mTypeCode))
  23012. isZero = constVal->mInt64 == 0;
  23013. }
  23014. if (isZero)
  23015. {
  23016. mModule->Fail("Divide by zero", opToken);
  23017. mResult = mModule->GetDefaultTypedValue(resultType);
  23018. }
  23019. else
  23020. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateDiv(convLeftValue, convRightValue, resultType->IsSigned()), resultType);
  23021. }
  23022. break;
  23023. case BfBinaryOp_Modulus:
  23024. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateRem(convLeftValue, convRightValue, resultType->IsSigned()), resultType);
  23025. break;
  23026. case BfBinaryOp_Equality:
  23027. case BfBinaryOp_StrictEquality:
  23028. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(convLeftValue, convRightValue),
  23029. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  23030. break;
  23031. case BfBinaryOp_InEquality:
  23032. case BfBinaryOp_StrictInEquality:
  23033. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(convLeftValue, convRightValue),
  23034. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  23035. break;
  23036. case BfBinaryOp_LessThan:
  23037. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpLT(convLeftValue, convRightValue, resultType->IsSigned()),
  23038. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  23039. break;
  23040. case BfBinaryOp_LessThanOrEqual:
  23041. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpLTE(convLeftValue, convRightValue, resultType->IsSigned()),
  23042. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  23043. break;
  23044. case BfBinaryOp_GreaterThan:
  23045. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpGT(convLeftValue, convRightValue, resultType->IsSigned()),
  23046. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  23047. break;
  23048. case BfBinaryOp_GreaterThanOrEqual:
  23049. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpGTE(convLeftValue, convRightValue, resultType->IsSigned()),
  23050. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  23051. break;
  23052. case BfBinaryOp_Compare:
  23053. {
  23054. auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  23055. if ((convLeftValue.IsConst()) && (convRightValue.IsConst()))
  23056. {
  23057. auto cmpLtVal = mModule->mBfIRBuilder->CreateCmpLT(convLeftValue, convRightValue, resultType->IsSigned());
  23058. auto ltConstant = mModule->mBfIRBuilder->GetConstant(cmpLtVal);
  23059. if (ltConstant->mBool)
  23060. {
  23061. mResult = BfTypedValue(mModule->GetConstValue(-1, mModule->GetPrimitiveType(BfTypeCode_IntPtr)), intType);
  23062. }
  23063. else
  23064. {
  23065. auto cmpGtVal = mModule->mBfIRBuilder->CreateCmpGT(convLeftValue, convRightValue, resultType->IsSigned());
  23066. auto rtConstant = mModule->mBfIRBuilder->GetConstant(cmpGtVal);
  23067. if (rtConstant->mBool)
  23068. mResult = BfTypedValue(mModule->GetConstValue(1, mModule->GetPrimitiveType(BfTypeCode_IntPtr)), intType);
  23069. else
  23070. mResult = BfTypedValue(mModule->GetConstValue(0, mModule->GetPrimitiveType(BfTypeCode_IntPtr)), intType);
  23071. }
  23072. }
  23073. else if ((resultType->IsIntegralOrBool()) && (resultType->mSize < intType->mSize))
  23074. {
  23075. auto leftIntValue = mModule->mBfIRBuilder->CreateNumericCast(convLeftValue, resultType->IsSigned(), BfTypeCode_IntPtr);
  23076. auto rightIntValue = mModule->mBfIRBuilder->CreateNumericCast(convRightValue, resultType->IsSigned(), BfTypeCode_IntPtr);
  23077. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateSub(leftIntValue, rightIntValue), intType);
  23078. }
  23079. else
  23080. {
  23081. BfIRBlock checkGtBlock = mModule->mBfIRBuilder->CreateBlock("cmpCheckGt");
  23082. BfIRBlock eqBlock = mModule->mBfIRBuilder->CreateBlock("cmpEq");
  23083. BfIRBlock endBlock = mModule->mBfIRBuilder->CreateBlock("cmpEnd");
  23084. auto startBlock = mModule->mBfIRBuilder->GetInsertBlock();
  23085. auto cmpLtVal = mModule->mBfIRBuilder->CreateCmpLT(convLeftValue, convRightValue, resultType->IsSigned());
  23086. mModule->mBfIRBuilder->CreateCondBr(cmpLtVal, endBlock, checkGtBlock);
  23087. mModule->mBfIRBuilder->AddBlock(checkGtBlock);
  23088. mModule->mBfIRBuilder->SetInsertPoint(checkGtBlock);
  23089. auto cmpGtVal = mModule->mBfIRBuilder->CreateCmpGT(convLeftValue, convRightValue, resultType->IsSigned());
  23090. mModule->mBfIRBuilder->CreateCondBr(cmpGtVal, endBlock, eqBlock);
  23091. mModule->mBfIRBuilder->AddBlock(eqBlock);
  23092. mModule->mBfIRBuilder->SetInsertPoint(eqBlock);
  23093. mModule->mBfIRBuilder->CreateBr(endBlock);
  23094. mModule->mBfIRBuilder->AddBlock(endBlock);
  23095. mModule->mBfIRBuilder->SetInsertPoint(endBlock);
  23096. auto phiVal = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(intType), 3);
  23097. mModule->mBfIRBuilder->AddPhiIncoming(phiVal, mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, -1), startBlock);
  23098. mModule->mBfIRBuilder->AddPhiIncoming(phiVal, mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 1), checkGtBlock);
  23099. mModule->mBfIRBuilder->AddPhiIncoming(phiVal, mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0), eqBlock);
  23100. mResult = BfTypedValue(phiVal, intType);
  23101. }
  23102. }
  23103. break;
  23104. default:
  23105. if (mModule->PreFail())
  23106. mModule->Fail("Invalid operation", opToken);
  23107. break;
  23108. }
  23109. }
  23110. void BfExprEvaluator::Visit(BfBinaryOperatorExpression* binOpExpr)
  23111. {
  23112. BfAutoParentNodeEntry autoParentNodeEntry(mModule, binOpExpr);
  23113. // There are a few binary operations that could actually be casts followed by an unary operation
  23114. // We can't determine that until we know whether the identifier in the parens is a typename or not
  23115. // (double)-1.0 (intptr)&val (BaseStruct)*val
  23116. BfUnaryOp unaryOp = BfUnaryOp_None;
  23117. switch (binOpExpr->mOp)
  23118. {
  23119. case BfBinaryOp_Add: unaryOp = BfUnaryOp_Positive; break;
  23120. case BfBinaryOp_Subtract: unaryOp = BfUnaryOp_Negate; break;
  23121. case BfBinaryOp_Multiply: unaryOp = BfUnaryOp_Dereference; break;
  23122. case BfBinaryOp_BitwiseAnd: unaryOp = BfUnaryOp_AddressOf; break;
  23123. default: break;
  23124. }
  23125. if (unaryOp != BfUnaryOp_None)
  23126. {
  23127. if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(binOpExpr->mLeft))
  23128. {
  23129. if (auto castTypeExpr = BfNodeDynCast<BfIdentifierNode>(parenExpr->mExpression))
  23130. {
  23131. SetAndRestoreValue<bool> prevIgnoreError(mModule->mIgnoreErrors, true);
  23132. auto resolvedType = mModule->ResolveTypeRef(castTypeExpr, NULL);
  23133. prevIgnoreError.Restore();
  23134. if (resolvedType != NULL)
  23135. {
  23136. if (auto rightBinOpExpr = BfNodeDynCast<BfBinaryOperatorExpression>(binOpExpr->mRight))
  23137. {
  23138. int leftPrecedence = BfGetBinaryOpPrecendence(binOpExpr->mOp);
  23139. int rightPrecedence = BfGetBinaryOpPrecendence(rightBinOpExpr->mOp);
  23140. // Do we have a precedence order issue due to mis-parsing this?
  23141. // An example is: "(int)-5.5 * 10"
  23142. if (rightPrecedence > leftPrecedence)
  23143. {
  23144. mModule->FailAfter("Cast target must be wrapped in parentheses", binOpExpr->mLeft);
  23145. }
  23146. }
  23147. PerformUnaryOperation(binOpExpr->mRight, unaryOp, binOpExpr->mOpToken, BfUnaryOpFlag_None);
  23148. if (mResult)
  23149. {
  23150. mResult = mModule->LoadValue(mResult);
  23151. mResult = mModule->Cast(binOpExpr, mResult, resolvedType, BfCastFlags_Explicit);
  23152. }
  23153. return;
  23154. }
  23155. }
  23156. }
  23157. }
  23158. if ((binOpExpr->mOp == BfBinaryOp_LeftShift) || (binOpExpr->mOp == BfBinaryOp_RightShift) ||
  23159. (binOpExpr->mOp == BfBinaryOp_BitwiseAnd) || (binOpExpr->mOp == BfBinaryOp_BitwiseOr) ||
  23160. (binOpExpr->mOp == BfBinaryOp_ExclusiveOr))
  23161. {
  23162. for (int side = 0; side < 2; side++)
  23163. {
  23164. if (auto innerBinOpExpr = BfNodeDynCast<BfBinaryOperatorExpression>((side == 0) ? binOpExpr->mLeft : binOpExpr->mRight))
  23165. {
  23166. if ((innerBinOpExpr->mOp == BfBinaryOp_Add) || (innerBinOpExpr->mOp == BfBinaryOp_Subtract))
  23167. {
  23168. mModule->Warn(BfWarning_C4554_PossiblePrecedenceError, "Check operator precedence for possible error. Consider using parentheses to clarify precedence", innerBinOpExpr);
  23169. }
  23170. }
  23171. }
  23172. }
  23173. if (binOpExpr->mRight == NULL)
  23174. {
  23175. // We visit the children for autocompletion only
  23176. if (binOpExpr->mLeft != NULL)
  23177. VisitChild(binOpExpr->mLeft);
  23178. if (mResult)
  23179. {
  23180. auto autoComplete = GetAutoComplete();
  23181. if (autoComplete != NULL)
  23182. autoComplete->CheckEmptyStart(binOpExpr->mOpToken, mResult.mType);
  23183. }
  23184. if (binOpExpr->mRight != NULL)
  23185. VisitChild(binOpExpr->mRight);
  23186. return;
  23187. }
  23188. PerformBinaryOperation(binOpExpr->mLeft, binOpExpr->mRight, binOpExpr->mOp, binOpExpr->mOpToken, BfBinOpFlag_None);
  23189. }