BfExprEvaluator.cpp 899 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743217442174521746217472174821749217502175121752217532175421755217562175721758217592176021761217622176321764217652176621767217682176921770217712177221773217742177521776217772177821779217802178121782217832178421785217862178721788217892179021791217922179321794217952179621797217982179921800218012180221803218042180521806218072180821809218102181121812218132181421815218162181721818218192182021821218222182321824218252182621827218282182921830218312183221833218342183521836218372183821839218402184121842218432184421845218462184721848218492185021851218522185321854218552185621857218582185921860218612186221863218642186521866218672186821869218702187121872218732187421875218762187721878218792188021881218822188321884218852188621887218882188921890218912189221893218942189521896218972189821899219002190121902219032190421905219062190721908219092191021911219122191321914219152191621917219182191921920219212192221923219242192521926219272192821929219302193121932219332193421935219362193721938219392194021941219422194321944219452194621947219482194921950219512195221953219542195521956219572195821959219602196121962219632196421965219662196721968219692197021971219722197321974219752197621977219782197921980219812198221983219842198521986219872198821989219902199121992219932199421995219962199721998219992200022001220022200322004220052200622007220082200922010220112201222013220142201522016220172201822019220202202122022220232202422025220262202722028220292203022031220322203322034220352203622037220382203922040220412204222043220442204522046220472204822049220502205122052220532205422055220562205722058220592206022061220622206322064220652206622067220682206922070220712207222073220742207522076220772207822079220802208122082220832208422085220862208722088220892209022091220922209322094220952209622097220982209922100221012210222103221042210522106221072210822109221102211122112221132211422115221162211722118221192212022121221222212322124221252212622127221282212922130221312213222133221342213522136221372213822139221402214122142221432214422145221462214722148221492215022151221522215322154221552215622157221582215922160221612216222163221642216522166221672216822169221702217122172221732217422175221762217722178221792218022181221822218322184221852218622187221882218922190221912219222193221942219522196221972219822199222002220122202222032220422205222062220722208222092221022211222122221322214222152221622217222182221922220222212222222223222242222522226222272222822229222302223122232222332223422235222362223722238222392224022241222422224322244222452224622247222482224922250222512225222253222542225522256222572225822259222602226122262222632226422265222662226722268222692227022271222722227322274222752227622277222782227922280222812228222283222842228522286222872228822289222902229122292222932229422295222962229722298222992230022301223022230322304223052230622307223082230922310223112231222313223142231522316223172231822319223202232122322223232232422325223262232722328223292233022331223322233322334223352233622337223382233922340223412234222343223442234522346223472234822349223502235122352223532235422355223562235722358223592236022361223622236322364223652236622367223682236922370223712237222373223742237522376223772237822379223802238122382223832238422385223862238722388223892239022391223922239322394223952239622397223982239922400224012240222403224042240522406224072240822409224102241122412224132241422415224162241722418224192242022421224222242322424224252242622427224282242922430224312243222433224342243522436224372243822439224402244122442224432244422445224462244722448224492245022451224522245322454224552245622457224582245922460224612246222463224642246522466224672246822469224702247122472224732247422475224762247722478224792248022481224822248322484224852248622487224882248922490224912249222493224942249522496224972249822499225002250122502225032250422505225062250722508225092251022511225122251322514225152251622517225182251922520225212252222523225242252522526225272252822529225302253122532225332253422535225362253722538225392254022541225422254322544225452254622547225482254922550225512255222553225542255522556225572255822559225602256122562225632256422565225662256722568225692257022571225722257322574225752257622577225782257922580225812258222583225842258522586225872258822589225902259122592225932259422595225962259722598225992260022601226022260322604226052260622607226082260922610226112261222613226142261522616226172261822619226202262122622226232262422625226262262722628226292263022631226322263322634226352263622637226382263922640226412264222643226442264522646226472264822649226502265122652226532265422655226562265722658226592266022661226622266322664226652266622667226682266922670226712267222673226742267522676226772267822679226802268122682226832268422685226862268722688226892269022691226922269322694226952269622697226982269922700227012270222703227042270522706227072270822709227102271122712227132271422715227162271722718227192272022721227222272322724227252272622727227282272922730227312273222733227342273522736227372273822739227402274122742227432274422745227462274722748227492275022751227522275322754227552275622757227582275922760227612276222763227642276522766227672276822769227702277122772227732277422775227762277722778227792278022781227822278322784227852278622787227882278922790227912279222793227942279522796227972279822799228002280122802228032280422805228062280722808228092281022811228122281322814228152281622817228182281922820228212282222823228242282522826228272282822829228302283122832228332283422835228362283722838228392284022841228422284322844228452284622847228482284922850228512285222853228542285522856228572285822859228602286122862228632286422865228662286722868228692287022871228722287322874228752287622877228782287922880228812288222883228842288522886228872288822889228902289122892228932289422895228962289722898228992290022901229022290322904229052290622907229082290922910229112291222913229142291522916229172291822919229202292122922229232292422925229262292722928229292293022931229322293322934229352293622937229382293922940229412294222943229442294522946229472294822949229502295122952229532295422955229562295722958229592296022961229622296322964229652296622967229682296922970229712297222973229742297522976229772297822979229802298122982229832298422985229862298722988229892299022991229922299322994229952299622997229982299923000230012300223003230042300523006230072300823009230102301123012230132301423015230162301723018230192302023021230222302323024230252302623027230282302923030230312303223033230342303523036230372303823039230402304123042230432304423045230462304723048230492305023051230522305323054230552305623057230582305923060230612306223063230642306523066230672306823069230702307123072230732307423075230762307723078230792308023081230822308323084230852308623087230882308923090230912309223093230942309523096230972309823099231002310123102231032310423105231062310723108231092311023111231122311323114231152311623117231182311923120231212312223123231242312523126231272312823129231302313123132231332313423135231362313723138231392314023141231422314323144231452314623147231482314923150231512315223153231542315523156231572315823159231602316123162231632316423165231662316723168231692317023171231722317323174231752317623177231782317923180231812318223183231842318523186231872318823189231902319123192231932319423195231962319723198231992320023201232022320323204232052320623207232082320923210232112321223213232142321523216232172321823219232202322123222232232322423225232262322723228232292323023231232322323323234232352323623237232382323923240232412324223243232442324523246232472324823249232502325123252232532325423255232562325723258232592326023261232622326323264232652326623267232682326923270232712327223273232742327523276232772327823279232802328123282232832328423285232862328723288232892329023291232922329323294232952329623297232982329923300233012330223303233042330523306233072330823309233102331123312233132331423315233162331723318233192332023321233222332323324233252332623327233282332923330233312333223333233342333523336233372333823339233402334123342233432334423345233462334723348233492335023351233522335323354233552335623357233582335923360233612336223363233642336523366233672336823369233702337123372233732337423375233762337723378233792338023381233822338323384233852338623387233882338923390233912339223393233942339523396233972339823399234002340123402234032340423405234062340723408234092341023411234122341323414234152341623417234182341923420234212342223423234242342523426234272342823429234302343123432234332343423435234362343723438234392344023441234422344323444234452344623447234482344923450234512345223453234542345523456234572345823459234602346123462234632346423465234662346723468234692347023471234722347323474234752347623477234782347923480234812348223483234842348523486234872348823489234902349123492234932349423495234962349723498234992350023501235022350323504235052350623507235082350923510235112351223513235142351523516235172351823519235202352123522235232352423525235262352723528235292353023531235322353323534235352353623537235382353923540235412354223543235442354523546235472354823549235502355123552235532355423555235562355723558235592356023561235622356323564235652356623567235682356923570235712357223573235742357523576235772357823579235802358123582235832358423585235862358723588235892359023591235922359323594235952359623597235982359923600236012360223603236042360523606236072360823609236102361123612236132361423615236162361723618236192362023621236222362323624236252362623627236282362923630236312363223633236342363523636236372363823639236402364123642236432364423645236462364723648236492365023651236522365323654236552365623657236582365923660236612366223663236642366523666236672366823669236702367123672236732367423675236762367723678236792368023681236822368323684236852368623687236882368923690236912369223693236942369523696236972369823699237002370123702237032370423705237062370723708237092371023711237122371323714237152371623717237182371923720237212372223723237242372523726237272372823729237302373123732237332373423735237362373723738237392374023741237422374323744237452374623747237482374923750237512375223753237542375523756237572375823759237602376123762237632376423765237662376723768237692377023771237722377323774237752377623777237782377923780237812378223783237842378523786237872378823789237902379123792237932379423795237962379723798237992380023801238022380323804238052380623807238082380923810238112381223813238142381523816238172381823819238202382123822238232382423825238262382723828238292383023831238322383323834238352383623837238382383923840238412384223843238442384523846238472384823849238502385123852238532385423855238562385723858238592386023861238622386323864238652386623867238682386923870238712387223873238742387523876238772387823879238802388123882238832388423885238862388723888238892389023891238922389323894238952389623897238982389923900239012390223903239042390523906239072390823909239102391123912239132391423915239162391723918239192392023921239222392323924239252392623927239282392923930239312393223933239342393523936239372393823939239402394123942239432394423945239462394723948239492395023951239522395323954239552395623957239582395923960239612396223963239642396523966239672396823969239702397123972239732397423975239762397723978239792398023981239822398323984239852398623987239882398923990239912399223993239942399523996239972399823999240002400124002240032400424005240062400724008240092401024011240122401324014240152401624017240182401924020240212402224023240242402524026240272402824029240302403124032240332403424035240362403724038240392404024041240422404324044240452404624047240482404924050240512405224053240542405524056240572405824059240602406124062240632406424065240662406724068240692407024071240722407324074240752407624077240782407924080240812408224083240842408524086240872408824089240902409124092240932409424095240962409724098240992410024101241022410324104241052410624107241082410924110241112411224113241142411524116241172411824119241202412124122241232412424125241262412724128241292413024131241322413324134241352413624137241382413924140241412414224143241442414524146241472414824149241502415124152241532415424155241562415724158241592416024161241622416324164241652416624167241682416924170241712417224173241742417524176241772417824179241802418124182241832418424185241862418724188241892419024191241922419324194241952419624197241982419924200242012420224203242042420524206242072420824209242102421124212242132421424215242162421724218242192422024221242222422324224242252422624227242282422924230242312423224233242342423524236242372423824239242402424124242242432424424245242462424724248242492425024251242522425324254242552425624257242582425924260242612426224263242642426524266242672426824269242702427124272242732427424275242762427724278242792428024281242822428324284242852428624287242882428924290242912429224293242942429524296242972429824299243002430124302243032430424305243062430724308243092431024311243122431324314243152431624317243182431924320243212432224323243242432524326243272432824329243302433124332243332433424335243362433724338243392434024341243422434324344243452434624347243482434924350243512435224353243542435524356243572435824359243602436124362243632436424365243662436724368243692437024371243722437324374243752437624377243782437924380243812438224383243842438524386243872438824389243902439124392243932439424395243962439724398243992440024401244022440324404244052440624407244082440924410244112441224413244142441524416244172441824419244202442124422244232442424425244262442724428244292443024431244322443324434244352443624437244382443924440244412444224443244442444524446244472444824449244502445124452244532445424455244562445724458244592446024461244622446324464244652446624467244682446924470244712447224473244742447524476244772447824479244802448124482244832448424485244862448724488244892449024491244922449324494244952449624497244982449924500245012450224503245042450524506245072450824509245102451124512245132451424515245162451724518245192452024521245222452324524245252452624527245282452924530245312453224533245342453524536245372453824539245402454124542245432454424545245462454724548245492455024551245522455324554245552455624557245582455924560245612456224563245642456524566245672456824569245702457124572245732457424575245762457724578245792458024581245822458324584245852458624587245882458924590245912459224593245942459524596245972459824599246002460124602246032460424605246062460724608246092461024611246122461324614246152461624617246182461924620246212462224623246242462524626246272462824629246302463124632246332463424635246362463724638246392464024641246422464324644246452464624647246482464924650246512465224653246542465524656246572465824659246602466124662246632466424665246662466724668246692467024671246722467324674246752467624677246782467924680246812468224683246842468524686246872468824689246902469124692246932469424695246962469724698246992470024701247022470324704247052470624707247082470924710247112471224713247142471524716247172471824719247202472124722247232472424725247262472724728247292473024731247322473324734247352473624737247382473924740247412474224743247442474524746247472474824749247502475124752247532475424755247562475724758247592476024761247622476324764247652476624767247682476924770247712477224773247742477524776247772477824779247802478124782247832478424785247862478724788247892479024791247922479324794247952479624797247982479924800248012480224803248042480524806248072480824809248102481124812248132481424815248162481724818248192482024821248222482324824248252482624827248282482924830248312483224833248342483524836248372483824839248402484124842248432484424845248462484724848248492485024851248522485324854248552485624857248582485924860248612486224863248642486524866248672486824869248702487124872248732487424875248762487724878248792488024881248822488324884248852488624887248882488924890248912489224893248942489524896248972489824899249002490124902249032490424905249062490724908249092491024911249122491324914249152491624917249182491924920249212492224923249242492524926249272492824929249302493124932249332493424935249362493724938249392494024941249422494324944249452494624947249482494924950249512495224953249542495524956249572495824959249602496124962249632496424965249662496724968249692497024971249722497324974249752497624977249782497924980249812498224983249842498524986249872498824989249902499124992249932499424995249962499724998249992500025001250022500325004250052500625007250082500925010250112501225013250142501525016250172501825019250202502125022250232502425025250262502725028250292503025031250322503325034250352503625037250382503925040250412504225043250442504525046250472504825049250502505125052250532505425055250562505725058250592506025061250622506325064250652506625067250682506925070250712507225073250742507525076250772507825079250802508125082250832508425085250862508725088250892509025091250922509325094250952509625097250982509925100251012510225103251042510525106251072510825109251102511125112251132511425115251162511725118251192512025121251222512325124251252512625127251282512925130251312513225133251342513525136251372513825139251402514125142251432514425145251462514725148251492515025151251522515325154251552515625157251582515925160251612516225163251642516525166251672516825169251702517125172251732517425175251762517725178251792518025181251822518325184251852518625187251882518925190251912519225193251942519525196251972519825199252002520125202252032520425205252062520725208252092521025211252122521325214252152521625217252182521925220252212522225223252242522525226252272522825229252302523125232252332523425235252362523725238252392524025241252422524325244252452524625247252482524925250252512525225253252542525525256252572525825259252602526125262252632526425265252662526725268252692527025271252722527325274252752527625277252782527925280252812528225283252842528525286252872528825289252902529125292252932529425295252962529725298252992530025301253022530325304253052530625307253082530925310253112531225313253142531525316253172531825319253202532125322253232532425325253262532725328253292533025331253322533325334253352533625337253382533925340253412534225343253442534525346253472534825349253502535125352253532535425355253562535725358253592536025361253622536325364253652536625367253682536925370253712537225373253742537525376253772537825379253802538125382253832538425385253862538725388253892539025391253922539325394253952539625397253982539925400254012540225403254042540525406254072540825409254102541125412254132541425415254162541725418254192542025421254222542325424254252542625427254282542925430254312543225433254342543525436254372543825439254402544125442254432544425445254462544725448254492545025451254522545325454254552545625457254582545925460254612546225463254642546525466254672546825469254702547125472254732547425475254762547725478254792548025481254822548325484254852548625487254882548925490254912549225493254942549525496254972549825499255002550125502255032550425505255062550725508255092551025511255122551325514255152551625517255182551925520255212552225523255242552525526255272552825529255302553125532255332553425535255362553725538255392554025541255422554325544255452554625547255482554925550255512555225553255542555525556255572555825559255602556125562255632556425565255662556725568255692557025571255722557325574255752557625577255782557925580255812558225583255842558525586255872558825589255902559125592255932559425595255962559725598255992560025601256022560325604256052560625607256082560925610256112561225613256142561525616256172561825619256202562125622256232562425625256262562725628256292563025631256322563325634256352563625637256382563925640256412564225643256442564525646256472564825649256502565125652256532565425655256562565725658256592566025661256622566325664256652566625667256682566925670256712567225673256742567525676256772567825679256802568125682256832568425685256862568725688256892569025691256922569325694256952569625697256982569925700257012570225703257042570525706257072570825709257102571125712257132571425715257162571725718257192572025721257222572325724257252572625727257282572925730257312573225733257342573525736257372573825739257402574125742257432574425745257462574725748257492575025751257522575325754257552575625757257582575925760257612576225763257642576525766257672576825769257702577125772257732577425775257762577725778257792578025781257822578325784257852578625787257882578925790257912579225793257942579525796257972579825799258002580125802258032580425805258062580725808258092581025811258122581325814258152581625817258182581925820258212582225823258242582525826258272582825829258302583125832258332583425835258362583725838258392584025841258422584325844258452584625847258482584925850258512585225853258542585525856258572585825859258602586125862258632586425865258662586725868258692587025871258722587325874258752587625877258782587925880258812588225883258842588525886258872588825889258902589125892258932589425895258962589725898258992590025901259022590325904259052590625907259082590925910259112591225913259142591525916259172591825919259202592125922259232592425925259262592725928259292593025931259322593325934259352593625937259382593925940259412594225943259442594525946259472594825949259502595125952259532595425955259562595725958259592596025961259622596325964259652596625967259682596925970259712597225973259742597525976259772597825979259802598125982259832598425985259862598725988259892599025991259922599325994259952599625997259982599926000260012600226003260042600526006260072600826009260102601126012260132601426015260162601726018260192602026021260222602326024260252602626027260282602926030260312603226033260342603526036260372603826039260402604126042260432604426045260462604726048260492605026051260522605326054260552605626057260582605926060260612606226063260642606526066260672606826069260702607126072260732607426075260762607726078260792608026081260822608326084260852608626087260882608926090260912609226093260942609526096260972609826099261002610126102261032610426105261062610726108261092611026111261122611326114261152611626117261182611926120261212612226123261242612526126261272612826129261302613126132261332613426135261362613726138261392614026141261422614326144261452614626147261482614926150261512615226153261542615526156261572615826159261602616126162261632616426165261662616726168261692617026171261722617326174261752617626177261782617926180261812618226183261842618526186261872618826189261902619126192261932619426195261962619726198261992620026201262022620326204262052620626207262082620926210262112621226213262142621526216262172621826219262202622126222262232622426225262262622726228262292623026231262322623326234262352623626237262382623926240262412624226243262442624526246262472624826249262502625126252262532625426255262562625726258262592626026261262622626326264262652626626267262682626926270262712627226273262742627526276262772627826279262802628126282262832628426285262862628726288262892629026291262922629326294262952629626297262982629926300263012630226303263042630526306263072630826309263102631126312263132631426315263162631726318263192632026321263222632326324263252632626327263282632926330263312633226333263342633526336263372633826339263402634126342263432634426345263462634726348263492635026351263522635326354263552635626357263582635926360263612636226363263642636526366263672636826369263702637126372263732637426375263762637726378263792638026381263822638326384263852638626387263882638926390263912639226393263942639526396263972639826399264002640126402264032640426405264062640726408264092641026411264122641326414
  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
  830. {
  831. bool canCastFromCurToPrev = mModule->CanCast(mModule->GetFakeTypedValue(paramType), prevParamType, implicitCastFlags);
  832. bool canCastFromPrevToCur = mModule->CanCast(mModule->GetFakeTypedValue(prevParamType), paramType, implicitCastFlags);
  833. if ((canCastFromCurToPrev) && (canCastFromPrevToCur))
  834. paramsEquivalent = true;
  835. if ((canCastFromCurToPrev) && (!canCastFromPrevToCur))
  836. isBetter = true;
  837. else if ((canCastFromPrevToCur) && (!canCastFromCurToPrev))
  838. isWorse = true;
  839. else if ((paramType->IsIntegral()) && (prevParamType->IsIntegral()))
  840. {
  841. if (paramType == arg.mType)
  842. isBetter = true;
  843. else if (prevParamType == arg.mType)
  844. isWorse = true;
  845. else
  846. {
  847. if (paramType->mSize < prevParamType->mSize)
  848. isBetter = true;
  849. else if (paramType->mSize > prevParamType->mSize)
  850. isWorse = true;
  851. else if (paramType->IsSigned())
  852. isBetter = true;
  853. else
  854. isWorse = true;
  855. }
  856. }
  857. else if ((wasArgDeferred) && ((paramType->IsIntegral()) || (prevParamType->IsIntegral())))
  858. {
  859. SET_BETTER_OR_WORSE(paramType->IsIntegral(), prevParamType->IsIntegral());
  860. }
  861. }
  862. }
  863. }
  864. }
  865. if ((!isBetter) && (!isWorse) && (paramsEquivalent))
  866. {
  867. if ((origParamType != origPrevParamType) && (paramWasConstExpr) && (!prevParamWasConstExpr))
  868. betterByConstExprParam = true;
  869. else if ((origParamType != origPrevParamType) && (!paramWasConstExpr) && (prevParamWasConstExpr))
  870. worseByConstExprParam = true;
  871. else if (((paramWasUnspecialized) || (prevParamWasUnspecialized)))
  872. {
  873. int origTypeMoreSpecific = GetMostSpecificType(origParamType, origPrevParamType);
  874. if (origTypeMoreSpecific == 0)
  875. betterByGenericParam = true;
  876. else if (origTypeMoreSpecific == 1)
  877. worseByGenericParam = true;
  878. }
  879. }
  880. if ((!isBetter) && (!isWorse) && (paramType->IsRef()) && (prevParamType->IsRef()))
  881. {
  882. auto refType = (BfRefType*)paramType;
  883. auto prevRefType = (BfRefType*)prevParamType;
  884. // Prefer 'out' to 'ref'
  885. SET_BETTER_OR_WORSE(
  886. (refType->mRefKind == BfRefType::RefKind_Out) && (prevRefType->mRefKind == BfRefType::RefKind_Ref),
  887. (refType->mRefKind == BfRefType::RefKind_Ref) && (prevRefType->mRefKind == BfRefType::RefKind_Out));
  888. }
  889. if ((newArgIdx >= 0) && (newMethodInstance->GetParamKind(newArgIdx) == BfParamKind_Params))
  890. usedExtendedForm = true;
  891. if ((prevArgIdx >= 0) && (prevMethodInstance->GetParamKind(prevArgIdx) == BfParamKind_Params))
  892. prevUsedExtendedForm = true;
  893. if ((usedExtendedForm) || (prevUsedExtendedForm))
  894. break;
  895. someArgWasBetter |= isBetter;
  896. someArgWasWorse |= isWorse;
  897. isBetter = false;
  898. isWorse = false;
  899. }
  900. isBetter |= someArgWasBetter;
  901. isWorse |= someArgWasWorse;
  902. if ((!isBetter) && (!isWorse))
  903. {
  904. // Don't allow ambiguity
  905. if ((betterByGenericParam && !worseByGenericParam) ||
  906. (!betterByGenericParam && worseByGenericParam))
  907. {
  908. isBetter = betterByGenericParam;
  909. isWorse = worseByGenericParam;
  910. }
  911. }
  912. if ((!isBetter) && (!isWorse))
  913. {
  914. // Don't allow ambiguity
  915. if ((betterByConstExprParam && !worseByConstExprParam) ||
  916. (!betterByConstExprParam && worseByConstExprParam))
  917. {
  918. isBetter = betterByConstExprParam;
  919. isWorse = worseByConstExprParam;
  920. }
  921. }
  922. if ((isBetter) || (isWorse))
  923. {
  924. RETURN_RESULTS;
  925. }
  926. }
  927. // Choose by return type for conversion operators
  928. if (((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp) != 0) && (!isBetter) && (!isWorse))
  929. {
  930. auto returnType = newMethodInstance->mReturnType;
  931. auto prevReturnType = prevMethodInstance->mReturnType;
  932. if ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp_Explicit) != 0)
  933. {
  934. // Pick the one that can implicitly cast
  935. SET_BETTER_OR_WORSE(
  936. mModule->CanCast(mModule->GetFakeTypedValue(returnType), mCheckReturnType, implicitCastFlags),
  937. mModule->CanCast(mModule->GetFakeTypedValue(prevReturnType), mCheckReturnType, implicitCastFlags));
  938. }
  939. if ((!isBetter) && (!isWorse))
  940. {
  941. bool canCastFromCurToPrev = mModule->CanCast(mModule->GetFakeTypedValue(returnType), prevReturnType, implicitCastFlags);
  942. bool canCastFromPrevToCur = mModule->CanCast(mModule->GetFakeTypedValue(prevReturnType), returnType, implicitCastFlags);
  943. if ((canCastFromCurToPrev) && (!canCastFromPrevToCur))
  944. isWorse = true;
  945. else if ((canCastFromPrevToCur) && (!canCastFromCurToPrev))
  946. isBetter = true;
  947. }
  948. if ((isBetter) || (isWorse))
  949. {
  950. RETURN_RESULTS;
  951. }
  952. }
  953. // Check for unused extended params as next param - that still counts as using extended form
  954. usedExtendedForm = newMethodInstance->HasParamsArray();
  955. prevUsedExtendedForm = prevMethodInstance->HasParamsArray();
  956. RETURN_BETTER_OR_WORSE(newMethodInstance->GetNumGenericArguments() == 0, prevMethodInstance->GetNumGenericArguments() == 0);
  957. // Not using generic delegate params is better
  958. RETURN_BETTER_OR_WORSE(!newMethodInstance->mHadGenericDelegateParams, !prevMethodInstance->mHadGenericDelegateParams);
  959. // Normal form trumps extended form
  960. RETURN_BETTER_OR_WORSE(!usedExtendedForm, !prevUsedExtendedForm);
  961. // More used params trumps less params
  962. int paramDiff = (int) numUsedParams - (int) prevNumUsedParams;
  963. RETURN_BETTER_OR_WORSE(paramDiff > 0, paramDiff < 0);
  964. // Fewer defaults trumps more defaults
  965. // Since we know the number of used params is the same (previous check), we infer that the rest are defaults
  966. paramDiff = (int) newMethodInstance->GetParamCount() - (int) prevMethodInstance->GetParamCount();
  967. RETURN_BETTER_OR_WORSE(paramDiff < 0, paramDiff > 0);
  968. BfMethodInstance* typeUnspecNewMethodInstance = mModule->GetUnspecializedMethodInstance(newMethodInstance, true);
  969. BfMethodInstance* typeUnspecPrevMethodInstance = mModule->GetUnspecializedMethodInstance(prevMethodInstance, true);
  970. // Check specificity of args
  971. std::function<void(BfType*, BfType*)> _CompareParamTypes = [&](BfType* newType, BfType* prevType)
  972. {
  973. if ((newType->IsGenericParam()) && (prevType->IsGenericParam()))
  974. {
  975. auto newGenericParamType = (BfGenericParamType*)newType;
  976. auto prevGenericParamType = (BfGenericParamType*)prevType;
  977. if ((newGenericParamType->mGenericParamKind == BfGenericParamKind_Method) && (prevGenericParamType->mGenericParamKind == BfGenericParamKind_Method))
  978. {
  979. auto newMethodGenericParam = typeUnspecNewMethodInstance->mMethodInfoEx->mGenericParams[newGenericParamType->mGenericParamIdx];
  980. auto prevMethodGenericParam = typeUnspecPrevMethodInstance->mMethodInfoEx->mGenericParams[prevGenericParamType->mGenericParamIdx];
  981. SET_BETTER_OR_WORSE(mModule->AreConstraintsSubset(prevMethodGenericParam, newMethodGenericParam), mModule->AreConstraintsSubset(newMethodGenericParam, prevMethodGenericParam));
  982. }
  983. }
  984. else if (newType == prevType)
  985. {
  986. if ((newType->IsUnspecializedType()) && (newType->IsGenericTypeInstance()))
  987. {
  988. BfTypeInstance* newGenericType = (BfTypeInstance*)newType;
  989. BfTypeInstance* prevGenericType = (BfTypeInstance*)prevType;
  990. for (int genericArgIdx = 0; genericArgIdx < (int)newGenericType->mGenericTypeInfo->mTypeGenericArguments.size(); genericArgIdx++)
  991. {
  992. _CompareParamTypes(newGenericType->mGenericTypeInfo->mTypeGenericArguments[genericArgIdx], prevGenericType->mGenericTypeInfo->mTypeGenericArguments[genericArgIdx]);
  993. }
  994. }
  995. }
  996. else
  997. {
  998. //TODO: Why did we need this?
  999. //isBetter |= mModule->IsTypeMoreSpecific(newType, prevType);
  1000. //isWorse |= mModule->IsTypeMoreSpecific(prevType, newType);
  1001. }
  1002. };
  1003. int paramCheckCount = (int)BF_MIN(newMethodInstance->GetParamCount() - newImplicitParamCount, prevMethodInstance->GetParamCount() - prevImplicitParamCount);
  1004. for (argIdx = 0; argIdx < (int)paramCheckCount/*mArguments.size()*/; argIdx++)
  1005. {
  1006. int newArgIdx = argIdx + newImplicitParamCount;
  1007. int prevArgIdx = argIdx + prevImplicitParamCount;
  1008. _CompareParamTypes(typeUnspecNewMethodInstance->GetParamType(newArgIdx), typeUnspecPrevMethodInstance->GetParamType(prevArgIdx));
  1009. }
  1010. // Do generic constraint subset test directly to handle cases like "NotDisposed<T>()" vs "NotDisposed<T>() where T : IDisposable"
  1011. if ((newMethodInstance->GetNumGenericArguments() > 0) && (newMethodInstance->GetNumGenericArguments() == prevMethodInstance->GetNumGenericArguments()))
  1012. {
  1013. for (int genericParamIdx = 0; genericParamIdx < (int)newMethodInstance->GetNumGenericArguments(); genericParamIdx++)
  1014. {
  1015. auto newMethodGenericParam = newMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
  1016. auto prevMethodGenericParam = prevMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
  1017. SET_BETTER_OR_WORSE(mModule->AreConstraintsSubset(prevMethodGenericParam, newMethodGenericParam), mModule->AreConstraintsSubset(newMethodGenericParam, prevMethodGenericParam));
  1018. }
  1019. if ((!isBetter) && (!isWorse))
  1020. {
  1021. SET_BETTER_OR_WORSE(newMethodInstance->HasExternConstraints(), prevMethodInstance->HasExternConstraints());
  1022. }
  1023. }
  1024. if ((isBetter) || (isWorse))
  1025. {
  1026. RETURN_RESULTS;
  1027. }
  1028. // For operators, prefer explicit comparison over '<=>' comparison operator
  1029. if ((!isBetter) && (!isWorse))
  1030. {
  1031. if ((prevMethodDef->mIsOperator) && (newMethodDef->mIsOperator))
  1032. {
  1033. bool newIsComparison = ((BfOperatorDeclaration*)newMethodDef->mMethodDeclaration)->mBinOp == BfBinaryOp_Compare;
  1034. bool prevIsComparison = ((BfOperatorDeclaration*)prevMethodDef->mMethodDeclaration)->mBinOp == BfBinaryOp_Compare;
  1035. RETURN_BETTER_OR_WORSE(!newIsComparison, !prevIsComparison);
  1036. }
  1037. }
  1038. if ((newMethodInstance->mMethodDef->mExternalConstraints.size() != 0) || (prevMethodInstance->mMethodDef->mExternalConstraints.size() != 0))
  1039. {
  1040. struct GenericParamPair
  1041. {
  1042. BfGenericMethodParamInstance* mParams[2];
  1043. GenericParamPair()
  1044. {
  1045. mParams[0] = NULL;
  1046. mParams[1] = NULL;
  1047. }
  1048. };
  1049. Dictionary<BfType*, GenericParamPair> externConstraints;
  1050. auto _GetParams = [&](int idx, BfMethodInstance* methodInstance)
  1051. {
  1052. for (int externConstraintIdx = 0; externConstraintIdx < (int)methodInstance->mMethodDef->mExternalConstraints.size(); externConstraintIdx++)
  1053. {
  1054. auto genericParam = methodInstance->mMethodInfoEx->mGenericParams[methodInstance->mMethodDef->mGenericParams.size() + externConstraintIdx];
  1055. BF_ASSERT(genericParam->mExternType != NULL);
  1056. GenericParamPair* pairPtr = NULL;
  1057. externConstraints.TryAdd(genericParam->mExternType, NULL, &pairPtr);
  1058. pairPtr->mParams[idx] = genericParam;
  1059. }
  1060. };
  1061. _GetParams(0, newMethodInstance);
  1062. _GetParams(1, prevMethodInstance);
  1063. for (auto kv : externConstraints)
  1064. {
  1065. SET_BETTER_OR_WORSE(mModule->AreConstraintsSubset(kv.mValue.mParams[1], kv.mValue.mParams[0]), mModule->AreConstraintsSubset(kv.mValue.mParams[0], kv.mValue.mParams[1]));
  1066. }
  1067. if ((isBetter) || (isWorse))
  1068. {
  1069. RETURN_RESULTS;
  1070. }
  1071. }
  1072. // Does one have a body and one doesn't? Obvious!
  1073. isBetter = prevMethodDef->IsEmptyPartial();
  1074. isWorse = newMethodDef->IsEmptyPartial();
  1075. if ((isBetter) && (isWorse))
  1076. {
  1077. // If both are empty partials then just bind to either
  1078. isWorse = true;
  1079. RETURN_RESULTS;
  1080. }
  1081. // For extensions, select the version in the most-specific project (only applicable for ctors)
  1082. if ((!isBetter) && (!isWorse))
  1083. {
  1084. auto newProject = newMethodDef->mDeclaringType->mProject;
  1085. auto prevProject = prevMethodDef->mDeclaringType->mProject;
  1086. if (newProject != prevProject)
  1087. {
  1088. RETURN_BETTER_OR_WORSE(newProject->ContainsReference(prevProject), prevProject->ContainsReference(newProject));
  1089. }
  1090. }
  1091. // If we have conditional type extensions that both define an implementation for a method, use the most-specific conditional extension constraints
  1092. auto owner = newMethodInstance->GetOwner();
  1093. if ((newMethodDef->mDeclaringType != prevMethodDef->mDeclaringType) && (owner->IsGenericTypeInstance()))
  1094. {
  1095. auto genericOwner = (BfTypeInstance*)owner;
  1096. if (genericOwner->mGenericTypeInfo->mGenericExtensionInfo != NULL)
  1097. {
  1098. BfGenericExtensionEntry* newGenericExtesionEntry = NULL;
  1099. BfGenericExtensionEntry* prevGenericExtesionEntry = NULL;
  1100. if ((genericOwner->mGenericTypeInfo->mGenericExtensionInfo->mExtensionMap.TryGetValue(newMethodDef->mDeclaringType, &newGenericExtesionEntry)) &&
  1101. (genericOwner->mGenericTypeInfo->mGenericExtensionInfo->mExtensionMap.TryGetValue(prevMethodDef->mDeclaringType, &prevGenericExtesionEntry)))
  1102. {
  1103. if ((newGenericExtesionEntry->mGenericParams.size() == prevGenericExtesionEntry->mGenericParams.size()))
  1104. {
  1105. for (int genericParamIdx = 0; genericParamIdx < (int)newGenericExtesionEntry->mGenericParams.size(); genericParamIdx++)
  1106. {
  1107. auto newMethodGenericParam = newGenericExtesionEntry->mGenericParams[genericParamIdx];
  1108. auto prevMethodGenericParam = prevGenericExtesionEntry->mGenericParams[genericParamIdx];
  1109. SET_BETTER_OR_WORSE(mModule->AreConstraintsSubset(prevMethodGenericParam, newMethodGenericParam), mModule->AreConstraintsSubset(newMethodGenericParam, prevMethodGenericParam));
  1110. }
  1111. }
  1112. if ((isBetter) || (isWorse))
  1113. {
  1114. RETURN_RESULTS;
  1115. }
  1116. }
  1117. }
  1118. }
  1119. RETURN_BETTER_OR_WORSE(newMethodDef->mCheckedKind == mCheckedKind, prevMethodDef->mCheckedKind == mCheckedKind);
  1120. RETURN_BETTER_OR_WORSE(newMethodDef->mAppendKind == mAllowAppendKind, prevMethodDef->mAppendKind == mAllowAppendKind);
  1121. RETURN_BETTER_OR_WORSE(newMethodDef->mCommutableKind != BfCommutableKind_Reverse, prevMethodDef->mCommutableKind != BfCommutableKind_Reverse);
  1122. // If one of these methods is local to the current extension then choose that one
  1123. auto activeDef = mModule->GetActiveTypeDef();
  1124. RETURN_BETTER_OR_WORSE(newMethodDef->mDeclaringType == activeDef, prevMethodDef->mDeclaringType == activeDef);
  1125. RETURN_BETTER_OR_WORSE(newMethodDef->mDeclaringType->IsExtension(), prevMethodDef->mDeclaringType->IsExtension());
  1126. RETURN_BETTER_OR_WORSE(newMethodDef->mIsMutating, prevMethodDef->mIsMutating);
  1127. if (newMethodDef->mHasComptime != prevMethodDef->mHasComptime)
  1128. {
  1129. bool isComptime = (mModule->mIsComptimeModule) || ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0);
  1130. RETURN_BETTER_OR_WORSE(newMethodDef->mHasComptime == isComptime, prevMethodDef->mHasComptime == isComptime);
  1131. }
  1132. RETURN_RESULTS;
  1133. }
  1134. BfTypedValue BfMethodMatcher::ResolveArgTypedValue(BfResolvedArg& resolvedArg, BfType* checkType, BfTypeVector* genericArgumentsSubstitute, BfType *origCheckType, BfResolveArgFlags flags)
  1135. {
  1136. BfTypedValue argTypedValue = resolvedArg.mTypedValue;
  1137. if ((resolvedArg.mArgFlags & BfArgFlag_DelegateBindAttempt) != 0)
  1138. {
  1139. BfExprEvaluator exprEvaluator(mModule);
  1140. exprEvaluator.mExpectingType = checkType;
  1141. BF_ASSERT(resolvedArg.mExpression->IsA<BfDelegateBindExpression>());
  1142. auto delegateBindExpr = BfNodeDynCast<BfDelegateBindExpression>(resolvedArg.mExpression);
  1143. BfMethodInstance* boundMethodInstance = NULL;
  1144. auto bindType = checkType;
  1145. if ((bindType == NULL) && (origCheckType != NULL) && (!origCheckType->IsUnspecializedTypeVariation()))
  1146. bindType = checkType;
  1147. if (exprEvaluator.CanBindDelegate(delegateBindExpr, &boundMethodInstance, bindType, genericArgumentsSubstitute))
  1148. {
  1149. if (delegateBindExpr->mNewToken == NULL)
  1150. {
  1151. if (boundMethodInstance->GetOwner()->IsFunction())
  1152. {
  1153. return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), boundMethodInstance->GetOwner());
  1154. }
  1155. else if ((boundMethodInstance->mDisallowCalling) || ((flags & BfResolveArgFlag_FromGeneric) == 0))
  1156. {
  1157. argTypedValue = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), checkType);
  1158. }
  1159. else
  1160. {
  1161. resolvedArg.mExpectedType = checkType;
  1162. auto methodRefType = mModule->CreateMethodRefType(boundMethodInstance);
  1163. mModule->AddDependency(methodRefType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_Calls);
  1164. mModule->AddCallDependency(boundMethodInstance);
  1165. argTypedValue = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), methodRefType);
  1166. }
  1167. }
  1168. else
  1169. argTypedValue = BfTypedValue(BfTypedValueKind_UntypedValue);
  1170. }
  1171. }
  1172. else if ((resolvedArg.mArgFlags & BfArgFlag_LambdaBindAttempt) != 0)
  1173. {
  1174. if ((argTypedValue) && (argTypedValue.mType->IsMethodRef()) &&
  1175. ((checkType == NULL) || (!checkType->IsMethodRef())))
  1176. {
  1177. // This may be from a previous checkMethod, clear it out
  1178. argTypedValue = BfTypedValue();
  1179. }
  1180. BfExprEvaluator exprEvaluator(mModule);
  1181. exprEvaluator.mExpectingType = checkType;
  1182. BF_ASSERT(resolvedArg.mExpression->IsA<BfLambdaBindExpression>());
  1183. auto lambdaBindExpr = (BfLambdaBindExpression*)resolvedArg.mExpression;
  1184. if ((checkType != NULL) && (checkType->IsDelegate()))
  1185. {
  1186. BfMethodInstance* methodInstance = mModule->GetRawMethodInstanceAtIdx(checkType->ToTypeInstance(), 0, "Invoke");
  1187. if (methodInstance != NULL)
  1188. {
  1189. if (methodInstance->GetParamCount() == (int)lambdaBindExpr->mParams.size())
  1190. {
  1191. if (lambdaBindExpr->mNewToken == NULL)
  1192. {
  1193. if (!resolvedArg.mTypedValue)
  1194. {
  1195. // Resolve for real
  1196. resolvedArg.mTypedValue = mModule->CreateValueFromExpression(lambdaBindExpr, checkType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_NoAutoComplete));
  1197. }
  1198. argTypedValue = resolvedArg.mTypedValue;
  1199. }
  1200. else
  1201. argTypedValue = BfTypedValue(BfTypedValueKind_UntypedValue);
  1202. //argTypedValue = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), checkType);
  1203. }
  1204. }
  1205. }
  1206. else if ((checkType == NULL) && (origCheckType != NULL) && (origCheckType->IsUnspecializedTypeVariation()) && (genericArgumentsSubstitute != NULL) && (origCheckType->IsDelegateOrFunction()))
  1207. {
  1208. BfMethodInstance* methodInstance = mModule->GetRawMethodInstanceAtIdx(origCheckType->ToTypeInstance(), 0, "Invoke");
  1209. if (methodInstance != NULL)
  1210. {
  1211. if ((methodInstance->mReturnType->IsGenericParam()) && (((BfGenericParamType*)methodInstance->mReturnType)->mGenericParamKind == BfGenericParamKind_Method))
  1212. {
  1213. bool isValid = true;
  1214. int returnMethodGenericArgIdx = ((BfGenericParamType*)methodInstance->mReturnType)->mGenericParamIdx;
  1215. if ((*genericArgumentsSubstitute)[returnMethodGenericArgIdx] != NULL)
  1216. {
  1217. isValid = false;
  1218. }
  1219. if (methodInstance->mParams.size() != (int)lambdaBindExpr->mParams.size())
  1220. isValid = false;
  1221. for (auto& param : methodInstance->mParams)
  1222. {
  1223. if (param.mResolvedType->IsGenericParam())
  1224. {
  1225. auto genericParamType = (BfGenericParamType*)param.mResolvedType;
  1226. if ((genericParamType->mGenericParamKind == BfGenericParamKind_Method) && ((*genericArgumentsSubstitute)[genericParamType->mGenericParamIdx] == NULL))
  1227. {
  1228. isValid = false;
  1229. }
  1230. }
  1231. }
  1232. if (isValid)
  1233. {
  1234. bool success = false;
  1235. (*genericArgumentsSubstitute)[returnMethodGenericArgIdx] = mModule->GetPrimitiveType(BfTypeCode_None);
  1236. auto tryType = mModule->ResolveGenericType(origCheckType, NULL, genericArgumentsSubstitute, mModule->mCurTypeInstance);
  1237. if (tryType != NULL)
  1238. {
  1239. auto inferredReturnType = mModule->CreateValueFromExpression(lambdaBindExpr, tryType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_InferReturnType | BfEvalExprFlags_NoAutoComplete));
  1240. if (inferredReturnType.mType != NULL)
  1241. {
  1242. (*genericArgumentsSubstitute)[returnMethodGenericArgIdx] = inferredReturnType.mType;
  1243. if (((flags & BfResolveArgFlag_FromGenericParam) != 0) && (lambdaBindExpr->mNewToken == NULL))
  1244. {
  1245. auto resolvedType = mModule->ResolveGenericType(origCheckType, NULL, genericArgumentsSubstitute, mModule->mCurTypeInstance);
  1246. if (resolvedType != NULL)
  1247. {
  1248. // Resolve for real
  1249. resolvedArg.mTypedValue = mModule->CreateValueFromExpression(lambdaBindExpr, resolvedType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_NoAutoComplete));
  1250. argTypedValue = resolvedArg.mTypedValue;
  1251. }
  1252. }
  1253. success = true;
  1254. }
  1255. }
  1256. if (!success)
  1257. {
  1258. // Put back
  1259. (*genericArgumentsSubstitute)[returnMethodGenericArgIdx] = NULL;
  1260. }
  1261. }
  1262. }
  1263. }
  1264. }
  1265. }
  1266. else if ((resolvedArg.mArgFlags & BfArgFlag_UnqualifiedDotAttempt) != 0)
  1267. {
  1268. if ((checkType != NULL) && (checkType->IsPayloadEnum()))
  1269. {
  1270. // Should we actually check the member name?
  1271. argTypedValue = BfTypedValue(BfTypedValueKind_UntypedValue);
  1272. }
  1273. }
  1274. else if ((resolvedArg.mArgFlags & BfArgFlag_UntypedDefault) != 0)
  1275. {
  1276. if (checkType != NULL)
  1277. argTypedValue = BfTypedValue(BfTypedValueKind_UntypedValue);
  1278. }
  1279. else if ((resolvedArg.mArgFlags & BfArgFlag_DeferredEval) != 0)
  1280. {
  1281. if (resolvedArg.mExpression != NULL)
  1282. {
  1283. if ((resolvedArg.mExpectedType != checkType) || (resolvedArg.mExpectedType == NULL)) // Did our last check match for this type?
  1284. {
  1285. SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
  1286. SetAndRestoreValue<bool> prevIgnoreError(mModule->mIgnoreErrors, true);
  1287. bool prevNoBind = false;
  1288. if (mModule->mCurMethodState != NULL)
  1289. {
  1290. prevNoBind = mModule->mCurMethodState->mNoBind;
  1291. mModule->mCurMethodState->mNoBind = true;
  1292. }
  1293. auto prevBlock = mModule->mBfIRBuilder->GetInsertBlock();
  1294. BfExprEvaluator exprEvaluator(mModule);
  1295. exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags);
  1296. exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | BfEvalExprFlags_AllowIntUnknown | BfEvalExprFlags_AllowRefExpr | BfEvalExprFlags_NoAutoComplete);
  1297. if ((resolvedArg.mArgFlags & BfArgFlag_ParamsExpr) != 0)
  1298. exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | BfEvalExprFlags_AllowParamsExpr);
  1299. auto expectType = checkType;
  1300. if (expectType != NULL)
  1301. {
  1302. if (expectType->IsRef())
  1303. {
  1304. auto refType = (BfRefType*)expectType;
  1305. expectType = refType->mElementType;
  1306. }
  1307. if ((genericArgumentsSubstitute != NULL) && (expectType->IsUnspecializedType()))
  1308. expectType = mModule->ResolveGenericType(expectType, NULL, genericArgumentsSubstitute, mModule->mCurTypeInstance, true);
  1309. }
  1310. exprEvaluator.mExpectingType = expectType;
  1311. exprEvaluator.Evaluate(resolvedArg.mExpression);
  1312. argTypedValue = exprEvaluator.GetResult();
  1313. if ((argTypedValue) && (argTypedValue.mType->IsVar()))
  1314. argTypedValue = BfTypedValue();
  1315. if (mModule->mCurMethodState != NULL)
  1316. mModule->mCurMethodState->mNoBind = prevNoBind;
  1317. if ((argTypedValue) && (!argTypedValue.mType->IsVar()))
  1318. {
  1319. if (checkType != NULL)
  1320. resolvedArg.mExpectedType = checkType;
  1321. auto storeTypedValue = argTypedValue;
  1322. if ((storeTypedValue.mValue) & (!storeTypedValue.mValue.IsFake()))
  1323. {
  1324. // We actually want to ensure that this cached value is a fake val. There are potential cases where a fake val
  1325. // won't be generated but we should throw an error, so we need to make sure we actually re-evaluate when the call
  1326. // is generated
  1327. //storeTypedValue.mValue = mModule->mBfIRBuilder->GetFakeVal();
  1328. resolvedArg.mWantsRecalc = true;
  1329. }
  1330. resolvedArg.mTypedValue = storeTypedValue;
  1331. //BF_ASSERT(argTypedValue.mValue.mId != -1);
  1332. }
  1333. mModule->mBfIRBuilder->SetInsertPoint(prevBlock);
  1334. }
  1335. }
  1336. }
  1337. else if ((resolvedArg.mArgFlags & BfArgFlag_VariableDeclaration) != 0)
  1338. {
  1339. if ((checkType != NULL) && (checkType->IsRef()))
  1340. argTypedValue = BfTypedValue(BfTypedValueKind_UntypedValue);
  1341. }
  1342. return argTypedValue;
  1343. }
  1344. bool BfMethodMatcher::WantsCheckMethod(BfProtectionCheckFlags& flags, BfTypeInstance* startTypeInstance, BfTypeInstance* checkTypeInstance, BfMethodDef* checkMethod)
  1345. {
  1346. MatchFailKind matchFailKind = MatchFailKind_None;
  1347. if (!mModule->CheckProtection(flags, checkTypeInstance, checkMethod->mDeclaringType->mProject, checkMethod->mProtection, startTypeInstance))
  1348. {
  1349. if ((mBypassVirtual) &&
  1350. ((checkMethod->mProtection == BfProtection_Protected) || (checkMethod->mProtection == BfProtection_ProtectedInternal)) &&
  1351. (mModule->TypeIsSubTypeOf(mModule->mCurTypeInstance, startTypeInstance)))
  1352. {
  1353. // Allow explicit 'base' call
  1354. }
  1355. else
  1356. {
  1357. return false;
  1358. }
  1359. }
  1360. if (mCheckedKind != checkMethod->mCheckedKind)
  1361. {
  1362. bool passes = true;
  1363. if (mCheckedKind != BfCheckedKind_NotSet)
  1364. {
  1365. passes = false;
  1366. }
  1367. else
  1368. {
  1369. auto defaultCheckedKind = mModule->GetDefaultCheckedKind();
  1370. if (defaultCheckedKind != checkMethod->mCheckedKind)
  1371. passes = false;
  1372. }
  1373. if (!passes)
  1374. {
  1375. return false;
  1376. }
  1377. }
  1378. return true;
  1379. }
  1380. bool BfMethodMatcher::InferFromGenericConstraints(BfMethodInstance* methodInstance, BfGenericParamInstance* genericParamInst, BfTypeVector* methodGenericArgs)
  1381. {
  1382. if (!genericParamInst->mExternType->IsGenericParam())
  1383. return false;
  1384. auto genericParamType = (BfGenericParamType*)genericParamInst->mExternType;
  1385. if (genericParamType->mGenericParamKind != BfGenericParamKind_Method)
  1386. return false;
  1387. BfType* checkArgType = NULL;
  1388. for (auto& checkOpConstraint : genericParamInst->mOperatorConstraints)
  1389. {
  1390. auto leftType = checkOpConstraint.mLeftType;
  1391. if ((leftType != NULL) && (leftType->IsUnspecializedType()))
  1392. leftType = mModule->ResolveGenericType(leftType, NULL, methodGenericArgs, mModule->mCurTypeInstance);
  1393. if (leftType != NULL)
  1394. leftType = mModule->FixIntUnknown(leftType);
  1395. auto rightType = checkOpConstraint.mRightType;
  1396. if ((rightType != NULL) && (rightType->IsUnspecializedType()))
  1397. rightType = mModule->ResolveGenericType(rightType, NULL, methodGenericArgs, mModule->mCurTypeInstance);
  1398. if (rightType != NULL)
  1399. rightType = mModule->FixIntUnknown(rightType);
  1400. BfConstraintState constraintSet;
  1401. constraintSet.mPrevState = mModule->mContext->mCurConstraintState;
  1402. constraintSet.mGenericParamInstance = genericParamInst;
  1403. constraintSet.mLeftType = leftType;
  1404. constraintSet.mRightType = rightType;
  1405. SetAndRestoreValue<BfConstraintState*> prevConstraintSet(mModule->mContext->mCurConstraintState, &constraintSet);
  1406. if (!mModule->CheckConstraintState(NULL))
  1407. return false;
  1408. if (checkOpConstraint.mBinaryOp != BfBinaryOp_None)
  1409. {
  1410. if ((leftType == NULL) || (rightType == NULL))
  1411. continue;
  1412. BfExprEvaluator exprEvaluator(mModule);
  1413. BfTypedValue leftValue(mModule->mBfIRBuilder->GetFakeVal(), leftType);
  1414. BfTypedValue rightValue(mModule->mBfIRBuilder->GetFakeVal(), rightType);
  1415. //
  1416. {
  1417. SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
  1418. SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
  1419. exprEvaluator.PerformBinaryOperation(NULL, NULL, checkOpConstraint.mBinaryOp, NULL, BfBinOpFlag_NoClassify, leftValue, rightValue);
  1420. }
  1421. if (exprEvaluator.mResult)
  1422. checkArgType = exprEvaluator.mResult.mType;
  1423. }
  1424. else
  1425. {
  1426. if (rightType == NULL)
  1427. continue;
  1428. BfTypedValue rightValue(mModule->mBfIRBuilder->GetFakeVal(), rightType);
  1429. StringT<128> failedOpName;
  1430. if (checkOpConstraint.mCastToken == BfToken_Implicit)
  1431. {
  1432. }
  1433. else
  1434. {
  1435. SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
  1436. SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
  1437. if (checkOpConstraint.mCastToken == BfToken_Explicit)
  1438. {
  1439. }
  1440. else
  1441. {
  1442. BfExprEvaluator exprEvaluator(mModule);
  1443. exprEvaluator.mResult = rightValue;
  1444. exprEvaluator.PerformUnaryOperation(NULL, checkOpConstraint.mUnaryOp, NULL, BfUnaryOpFlag_IsConstraintCheck);
  1445. if (exprEvaluator.mResult)
  1446. checkArgType = exprEvaluator.mResult.mType;
  1447. }
  1448. }
  1449. }
  1450. }
  1451. if ((checkArgType == NULL) && ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_ComptypeExpr) != 0))
  1452. {
  1453. for (auto comptypeConstraint : genericParamInst->mComptypeConstraint)
  1454. {
  1455. checkArgType = mModule->ResolveGenericMethodTypeRef(comptypeConstraint, methodInstance, genericParamInst, methodGenericArgs);
  1456. if (checkArgType == NULL)
  1457. return false;
  1458. }
  1459. }
  1460. if (checkArgType == NULL)
  1461. return false;
  1462. if (checkArgType->IsVar())
  1463. return false;
  1464. (*methodGenericArgs)[genericParamType->mGenericParamIdx] = checkArgType;
  1465. return true;
  1466. }
  1467. bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInstance* typeInstance, BfMethodDef* checkMethod, bool isFailurePass)
  1468. {
  1469. BP_ZONE("BfMethodMatcher::CheckMethod");
  1470. BackupMatchKind curMatchKind = BackupMatchKind_None;
  1471. bool hadMatch = false;
  1472. // Never consider overrides - they only get found at original method declaration
  1473. // mBypassVirtual gets set when we are doing an explicit "base" call, or when we are a struct --
  1474. // because on structs we know the exact type
  1475. if ((checkMethod->mIsOverride) && (!mBypassVirtual) && (!typeInstance->IsValueType()))
  1476. return false;
  1477. mMethodCheckCount++;
  1478. BfMethodInstance* methodInstance = mModule->GetRawMethodInstance(typeInstance, checkMethod);
  1479. if (methodInstance == NULL)
  1480. return false;
  1481. BfMethodInstance* typeUnspecMethodInstance = mModule->GetUnspecializedMethodInstance(methodInstance, true);
  1482. BfTypeVector* typeGenericArguments = NULL;
  1483. if (typeInstance->mGenericTypeInfo != NULL)
  1484. typeGenericArguments = &typeInstance->mGenericTypeInfo->mTypeGenericArguments;
  1485. if ((mInterfaceMethodInstance != NULL) && (methodInstance->GetExplicitInterface() != NULL))
  1486. {
  1487. BfTypeInstance* wantInterface = mInterfaceMethodInstance->mMethodInstanceGroup->mOwner;
  1488. if (wantInterface != methodInstance->GetExplicitInterface())
  1489. return false;
  1490. }
  1491. if ((checkMethod->mIsVirtual) && (!checkMethod->mIsOverride) && (!mBypassVirtual) &&
  1492. (targetTypeInstance != NULL) && (targetTypeInstance->IsObject()))
  1493. {
  1494. mModule->PopulateType(targetTypeInstance, BfPopulateType_DataAndMethods);
  1495. if ((methodInstance->mVirtualTableIdx < targetTypeInstance->mVirtualMethodTable.mSize) && (methodInstance->mVirtualTableIdx >= 0))
  1496. {
  1497. BfVirtualMethodEntry& vEntry = targetTypeInstance->mVirtualMethodTable[methodInstance->mVirtualTableIdx];
  1498. if ((vEntry.mImplementingMethod.mTypeInstance != NULL) && (vEntry.mImplementingMethod.mTypeInstance->mDefineState < BfTypeDefineState_DefinedAndMethodsSlotted) &&
  1499. (mModule->mCompiler->IsAutocomplete()))
  1500. {
  1501. // Silently ignore
  1502. }
  1503. else
  1504. {
  1505. auto implMethod = (BfMethodInstance*)vEntry.mImplementingMethod;
  1506. if ((implMethod != methodInstance) && (implMethod != NULL))
  1507. {
  1508. SetAndRestoreValue<bool> prevBypassVirtual(mBypassVirtual, true);
  1509. return CheckMethod(targetTypeInstance, implMethod->GetOwner(), implMethod->mMethodDef, isFailurePass);
  1510. }
  1511. }
  1512. }
  1513. else
  1514. {
  1515. // Being in autocomplete mode is the only excuse for not having the virtual method table slotted
  1516. if ((!mModule->mCompiler->IsAutocomplete()) && (!targetTypeInstance->mTypeFailed) && (!targetTypeInstance->IsUnspecializedTypeVariation()))
  1517. {
  1518. mModule->AssertErrorState();
  1519. }
  1520. }
  1521. }
  1522. BfGenericInferContext genericInferContext;
  1523. genericInferContext.mModule = mModule;
  1524. genericInferContext.mCheckMethodGenericArguments = &mCheckMethodGenericArguments;
  1525. HashSet<int> allowEmptyGenericSet;
  1526. BfAutoComplete* autoComplete = NULL;
  1527. if ((mModule->mCompiler->mResolvePassData != NULL) && (!isFailurePass) && ((mBfEvalExprFlags & BfEvalExprFlags_NoAutoComplete) == 0))
  1528. autoComplete = mModule->mCompiler->mResolvePassData->mAutoComplete;
  1529. if (checkMethod->mMethodType != BfMethodType_Extension)
  1530. {
  1531. if (((checkMethod->mIsStatic) && (!mAllowStatic)) ||
  1532. ((!checkMethod->mIsStatic) && (!mAllowNonStatic)))
  1533. {
  1534. if (!typeInstance->IsFunction())
  1535. autoComplete = NULL;
  1536. }
  1537. }
  1538. if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo))
  1539. {
  1540. BfAutoComplete::MethodMatchEntry methodMatchEntry;
  1541. methodMatchEntry.mMethodDef = checkMethod;
  1542. methodMatchEntry.mTypeInstance = typeInstance;
  1543. methodMatchEntry.mCurMethodInstance = mModule->mCurMethodInstance;
  1544. autoComplete->mMethodMatchInfo->mInstanceList.push_back(methodMatchEntry);
  1545. }
  1546. BfTypeVector* genericArgumentsSubstitute = NULL;
  1547. int argIdx = 0;
  1548. int argMatchCount = 0;
  1549. bool needInferGenericParams = (checkMethod->mGenericParams.size() != 0) &&
  1550. ((!mHadExplicitGenericArguments) || (mHadPartialGenericArguments));
  1551. int paramIdx = 0;
  1552. BfType* paramsElementType = NULL;
  1553. if (checkMethod->HasAppend())
  1554. paramIdx++;
  1555. int uniqueGenericStartIdx = mModule->GetLocalInferrableGenericArgCount(checkMethod);
  1556. if (mHadExplicitGenericArguments)
  1557. {
  1558. int genericArgDelta = (int)(checkMethod->mGenericParams.size() - (mExplicitMethodGenericArguments.size() + uniqueGenericStartIdx));
  1559. if (mHadOpenGenericArguments)
  1560. {
  1561. if (genericArgDelta <= 0)
  1562. goto NoMatch;
  1563. }
  1564. else
  1565. {
  1566. if (genericArgDelta != 0)
  1567. goto NoMatch;
  1568. }
  1569. }
  1570. for (auto& checkGenericArgRef : mCheckMethodGenericArguments)
  1571. checkGenericArgRef = NULL;
  1572. mCheckMethodGenericArguments.resize(checkMethod->mGenericParams.size());
  1573. for (auto& genericArgRef : mCheckMethodGenericArguments)
  1574. genericArgRef = NULL;
  1575. if (mHadExplicitGenericArguments)
  1576. {
  1577. if (uniqueGenericStartIdx > 0)
  1578. {
  1579. genericArgumentsSubstitute = &mCheckMethodGenericArguments;
  1580. mCheckMethodGenericArguments.clear();
  1581. mCheckMethodGenericArguments.reserve(mExplicitMethodGenericArguments.size() + uniqueGenericStartIdx);
  1582. for (int i = 0; i < uniqueGenericStartIdx; i++)
  1583. mCheckMethodGenericArguments.Add(NULL);
  1584. for (int i = 0; i < (int)mExplicitMethodGenericArguments.size(); i++)
  1585. mCheckMethodGenericArguments.Add(mExplicitMethodGenericArguments[i]);
  1586. }
  1587. else
  1588. {
  1589. genericArgumentsSubstitute = &mExplicitMethodGenericArguments;
  1590. }
  1591. if ((mHadPartialGenericArguments) && (needInferGenericParams))
  1592. {
  1593. genericArgumentsSubstitute = &mCheckMethodGenericArguments;
  1594. for (int i = 0; i < (int)mExplicitMethodGenericArguments.mSize; i++)
  1595. mCheckMethodGenericArguments[i] = mExplicitMethodGenericArguments[i];
  1596. }
  1597. }
  1598. else if (needInferGenericParams)
  1599. genericArgumentsSubstitute = &mCheckMethodGenericArguments;
  1600. if (mHasArgNames)
  1601. {
  1602. checkMethod->BuildParamNameMap();
  1603. bool prevWasNull = false;
  1604. for (int argIdx = (int)mArguments.mSize - 1; argIdx >= 0; argIdx--)
  1605. {
  1606. auto& arg = mArguments[argIdx];
  1607. if (arg.mNameNode != NULL)
  1608. {
  1609. if (prevWasNull)
  1610. {
  1611. if (argIdx >= checkMethod->mParams.mSize)
  1612. goto NoMatch;
  1613. if (checkMethod->mParams[argIdx]->mName != arg.mNameNode->ToStringView())
  1614. goto NoMatch;
  1615. }
  1616. else
  1617. {
  1618. if (!checkMethod->mParamNameMap->ContainsKey(arg.mNameNode->ToStringView()))
  1619. goto NoMatch;
  1620. }
  1621. prevWasNull = false;
  1622. }
  1623. else
  1624. {
  1625. prevWasNull = true;
  1626. }
  1627. }
  1628. }
  1629. if ((checkMethod->mIsMutating) && (targetTypeInstance != NULL) && (targetTypeInstance->IsValueType()) &&
  1630. ((mTarget.IsReadOnly()) || (!mTarget.IsAddr())) &&
  1631. (!targetTypeInstance->IsValuelessType()))
  1632. {
  1633. goto NoMatch;
  1634. }
  1635. if (mSkipImplicitParams)
  1636. {
  1637. //paramOfs = methodInstance->GetImplicitParamCount();
  1638. //paramIdx += paramOfs;
  1639. }
  1640. if (needInferGenericParams)
  1641. {
  1642. genericInferContext.mPrevArgValues.resize(checkMethod->mGenericParams.size());
  1643. int paramOfs = methodInstance->GetImplicitParamCount();
  1644. int paramCount = methodInstance->GetParamCount();
  1645. SizedArray<int, 8> deferredArgs;
  1646. int argIdx = 0;
  1647. int paramIdx = 0;
  1648. if (checkMethod->HasAppend())
  1649. paramIdx++;
  1650. if (checkMethod->mMethodType == BfMethodType_Extension)
  1651. {
  1652. argIdx--;
  1653. }
  1654. paramIdx += paramOfs;
  1655. bool hadInferFailure = false;
  1656. int inferParamOffset = paramOfs - argIdx;
  1657. int paramsParamIdx = -1;
  1658. enum ResultKind
  1659. {
  1660. ResultKind_Ok,
  1661. ResultKind_Failed,
  1662. ResultKind_Deferred,
  1663. };
  1664. auto _CheckArg = [&](int argIdx)
  1665. {
  1666. paramIdx = argIdx + inferParamOffset;
  1667. if ((paramsParamIdx != -1) && (paramIdx > paramsParamIdx))
  1668. paramIdx = paramsParamIdx;
  1669. auto wantType = methodInstance->GetParamType(paramIdx);
  1670. auto checkType = wantType;
  1671. auto origCheckType = checkType;
  1672. if (checkType->IsGenericParam())
  1673. {
  1674. BfGenericParamInstance* genericParamInstance = NULL;
  1675. auto genericParamType = (BfGenericParamType*)checkType;
  1676. checkType = NULL;
  1677. if (genericParamType->mGenericParamKind == BfGenericParamKind_Method)
  1678. {
  1679. if ((genericArgumentsSubstitute != NULL) && (genericParamType->mGenericParamIdx < (int)genericArgumentsSubstitute->size()))
  1680. checkType = (*genericArgumentsSubstitute)[genericParamType->mGenericParamIdx];
  1681. genericParamInstance = methodInstance->mMethodInfoEx->mGenericParams[genericParamType->mGenericParamIdx];
  1682. }
  1683. else
  1684. genericParamInstance = mModule->GetGenericParamInstance(genericParamType);
  1685. if (checkType == NULL)
  1686. {
  1687. checkType = genericParamInstance->mTypeConstraint;
  1688. origCheckType = checkType; // We can do "ResolveGenericType" on this type
  1689. }
  1690. }
  1691. bool attemptedGenericResolve = false;
  1692. if ((checkType != NULL) && (genericArgumentsSubstitute != NULL) && (checkType->IsUnspecializedType()))
  1693. {
  1694. attemptedGenericResolve = true;
  1695. checkType = mModule->ResolveGenericType(origCheckType, NULL, genericArgumentsSubstitute, mModule->mCurTypeInstance);
  1696. }
  1697. if (wantType->IsUnspecializedType())
  1698. {
  1699. BfTypedValue argTypedValue;
  1700. if (argIdx == -1)
  1701. {
  1702. if (mOrigTarget)
  1703. argTypedValue = mOrigTarget;
  1704. else
  1705. argTypedValue = mTarget;
  1706. }
  1707. else
  1708. {
  1709. BfResolveArgFlags flags = BfResolveArgFlag_FromGeneric;
  1710. if (wantType->IsGenericParam())
  1711. flags = (BfResolveArgFlags)(flags | BfResolveArgFlag_FromGenericParam);
  1712. argTypedValue = ResolveArgTypedValue(mArguments[argIdx], checkType, genericArgumentsSubstitute, origCheckType, flags);
  1713. }
  1714. if (!argTypedValue.IsUntypedValue())
  1715. {
  1716. auto type = argTypedValue.mType;
  1717. if (!argTypedValue)
  1718. {
  1719. if ((checkType == NULL) && (attemptedGenericResolve) && (genericInferContext.GetUnresolvedCount() >= 2))
  1720. {
  1721. deferredArgs.Add(argIdx);
  1722. return ResultKind_Deferred;
  1723. }
  1724. return ResultKind_Failed;
  1725. }
  1726. if (type->IsVar())
  1727. mHasVarArguments = true;
  1728. if (methodInstance->GetParamKind(paramIdx) == BfParamKind_Params)
  1729. {
  1730. if ((mArguments[argIdx].mArgFlags & BfArgFlag_ParamsExpr) != 0)
  1731. {
  1732. // Match to entire thing
  1733. }
  1734. else
  1735. {
  1736. paramsParamIdx = paramIdx;
  1737. if ((wantType->IsArray()) || (wantType->IsSizedArray()) || (wantType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef)))
  1738. wantType = wantType->GetUnderlyingType();
  1739. }
  1740. }
  1741. if (!genericInferContext.InferGenericArgument(methodInstance, type, wantType, argTypedValue.mValue))
  1742. return ResultKind_Failed;
  1743. }
  1744. }
  1745. return ResultKind_Ok;
  1746. };
  1747. for (; argIdx < (int)mArguments.size(); argIdx++)
  1748. {
  1749. paramIdx = argIdx + inferParamOffset;
  1750. if ((paramIdx >= paramCount) && (paramsParamIdx == -1))
  1751. break; // Possible for delegate 'params' type methods
  1752. auto resultKind = _CheckArg(argIdx);
  1753. if (resultKind == ResultKind_Failed)
  1754. goto NoMatch;
  1755. }
  1756. if ((methodInstance->mParams.mSize > 0) && (methodInstance->GetParamKind(methodInstance->mParams.mSize - 1) == BfParamKind_Params))
  1757. {
  1758. // Handle `params int[C]` generic sized array params case
  1759. auto paramsType = methodInstance->GetParamType(methodInstance->mParams.mSize - 1);
  1760. if (paramsType->IsUnknownSizedArrayType())
  1761. {
  1762. auto unknownSizedArray = (BfUnknownSizedArrayType*)paramsType;
  1763. if (unknownSizedArray->mElementCountSource->IsMethodGenericParam())
  1764. {
  1765. auto genericParam = (BfGenericParamType*)unknownSizedArray->mElementCountSource;
  1766. if ((*genericArgumentsSubstitute)[genericParam->mGenericParamIdx] == NULL)
  1767. {
  1768. int paramsCount = (int)mArguments.mSize - inferParamOffset;
  1769. (*genericArgumentsSubstitute)[genericParam->mGenericParamIdx] = mModule->CreateConstExprValueType(
  1770. BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, paramsCount), mModule->GetPrimitiveType(BfTypeCode_IntPtr)));
  1771. }
  1772. }
  1773. }
  1774. else if (paramsType->IsParamsType())
  1775. {
  1776. paramsType = paramsType->GetUnderlyingType();
  1777. if (paramsType->IsGenericParam())
  1778. {
  1779. auto genericParamType = (BfGenericParamType*)paramsType;
  1780. if (genericParamType->mGenericParamKind == BfGenericParamKind_Method)
  1781. {
  1782. auto genericParamInst = methodInstance->mMethodInfoEx->mGenericParams[genericParamType->mGenericParamIdx];
  1783. if ((genericParamInst->mTypeConstraint != NULL) && (genericParamInst->mTypeConstraint->IsInstanceOf(mModule->mCompiler->mTupleTypeDef)))
  1784. {
  1785. bool isValid = true;
  1786. BfTypeVector genericArgs;
  1787. for (int argIdx = methodInstance->mParams.mSize - 1 - inferParamOffset; argIdx < (int)mArguments.size(); argIdx++)
  1788. {
  1789. BfTypedValue argTypedValue = ResolveArgTypedValue(mArguments[argIdx], NULL, genericArgumentsSubstitute);
  1790. if (!argTypedValue)
  1791. {
  1792. isValid = false;
  1793. break;
  1794. }
  1795. genericArgs.Add(mModule->FixIntUnknown(argTypedValue.mType));
  1796. }
  1797. if (isValid)
  1798. {
  1799. (*genericArgumentsSubstitute)[genericParamType->mGenericParamIdx] = mModule->CreateTupleType(genericArgs, SubstituteList());
  1800. }
  1801. }
  1802. }
  1803. }
  1804. }
  1805. }
  1806. if (!deferredArgs.IsEmpty())
  1807. {
  1808. genericInferContext.InferGenericArguments(methodInstance);
  1809. }
  1810. while (!deferredArgs.IsEmpty())
  1811. {
  1812. int prevDeferredSize = (int)deferredArgs.size();
  1813. for (int i = 0; i < prevDeferredSize; i++)
  1814. {
  1815. auto resultKind = _CheckArg(deferredArgs[i]);
  1816. if (resultKind == ResultKind_Failed)
  1817. goto NoMatch;
  1818. }
  1819. deferredArgs.RemoveRange(0, prevDeferredSize);
  1820. if (prevDeferredSize == deferredArgs.size())
  1821. {
  1822. // No progress
  1823. goto NoMatch;
  1824. }
  1825. }
  1826. //
  1827. {
  1828. int paramIdx = (int)mArguments.size() + paramOfs;
  1829. while (paramIdx < checkMethod->mParams.size())
  1830. {
  1831. if ((paramIdx < methodInstance->mDefaultValues.size()) && (methodInstance->mDefaultValues[paramIdx]))
  1832. {
  1833. auto wantType = methodInstance->GetParamType(paramIdx);
  1834. auto checkType = wantType;
  1835. if (checkType->IsGenericParam())
  1836. {
  1837. BfGenericParamInstance* genericParamInstance = NULL;
  1838. auto genericParamType = (BfGenericParamType*)checkType;
  1839. if (genericParamType->mGenericParamKind == BfGenericParamKind_Method)
  1840. {
  1841. if ((genericArgumentsSubstitute != NULL) && (genericParamType->mGenericParamIdx < (int)genericArgumentsSubstitute->size()))
  1842. checkType = (*genericArgumentsSubstitute)[genericParamType->mGenericParamIdx];
  1843. genericParamInstance = methodInstance->mMethodInfoEx->mGenericParams[genericParamType->mGenericParamIdx];
  1844. if ((genericParamInstance->mGenericParamFlags & BfGenericParamFlag_Const) != 0)
  1845. {
  1846. if (mCheckMethodGenericArguments[genericParamType->mGenericParamIdx] == NULL)
  1847. allowEmptyGenericSet.Add(genericParamType->mGenericParamIdx);
  1848. }
  1849. }
  1850. }
  1851. }
  1852. paramIdx++;
  1853. }
  1854. }
  1855. if ((mCheckReturnType != NULL) && (methodInstance->mReturnType->IsUnspecializedType()))
  1856. {
  1857. if (!genericInferContext.InferGenericArgument(methodInstance, mCheckReturnType, methodInstance->mReturnType, BfIRValue()))
  1858. return ResultKind_Failed;
  1859. }
  1860. bool failed = false;
  1861. bool inferredAllGenericArguments = false;
  1862. for (int pass = 0; true; pass++)
  1863. {
  1864. bool madeProgress = false;
  1865. bool hasUninferred = false;
  1866. failed = false;
  1867. for (int genericArgIdx = uniqueGenericStartIdx; genericArgIdx < (int)checkMethod->mGenericParams.size(); genericArgIdx++)
  1868. {
  1869. if (genericArgIdx >= mCheckMethodGenericArguments.mSize)
  1870. {
  1871. failed = true;
  1872. }
  1873. else
  1874. {
  1875. auto& genericArg = mCheckMethodGenericArguments[genericArgIdx];
  1876. if (genericArg == NULL)
  1877. {
  1878. auto genericParam = methodInstance->mMethodInfoEx->mGenericParams[genericArgIdx];
  1879. InferFromGenericConstraints(methodInstance, genericParam, &mCheckMethodGenericArguments);
  1880. if (genericArg != NULL)
  1881. {
  1882. if (inferredAllGenericArguments)
  1883. genericInferContext.InferGenericArguments(methodInstance, genericArgIdx);
  1884. madeProgress = true;
  1885. }
  1886. hasUninferred = true;
  1887. if (!allowEmptyGenericSet.Contains(genericArgIdx))
  1888. failed = true;
  1889. }
  1890. }
  1891. }
  1892. if (!hasUninferred)
  1893. break;
  1894. if (inferredAllGenericArguments)
  1895. {
  1896. if (!madeProgress)
  1897. break;
  1898. }
  1899. genericInferContext.InferGenericArguments(methodInstance);
  1900. inferredAllGenericArguments = true;
  1901. }
  1902. if (failed)
  1903. goto NoMatch;
  1904. }
  1905. if (checkMethod->mMethodType == BfMethodType_Extension)
  1906. argIdx--;
  1907. // Iterate through params
  1908. while (true)
  1909. {
  1910. // Too many arguments
  1911. if (paramIdx >= (int)methodInstance->GetParamCount())
  1912. {
  1913. break;
  1914. }
  1915. bool isDeferredEval = false;
  1916. if ((argIdx >= 0) && (methodInstance->GetParamKind(paramIdx) == BfParamKind_Params) && (paramsElementType == NULL))
  1917. {
  1918. if (argIdx >= (int) mArguments.size())
  1919. break; // No params
  1920. BfTypedValue argTypedValue = ResolveArgTypedValue(mArguments[argIdx], NULL, genericArgumentsSubstitute);
  1921. if (!argTypedValue)
  1922. goto NoMatch;
  1923. if ((!argTypedValue.HasType()) && (!mArguments[argIdx].IsDeferredEval()))
  1924. goto NoMatch;
  1925. auto paramsArrayType = methodInstance->GetParamType(paramIdx);
  1926. paramsArrayType = mModule->ResolveGenericType(paramsArrayType, NULL, genericArgumentsSubstitute, mModule->mCurTypeInstance);
  1927. if (paramsArrayType == NULL)
  1928. goto NoMatch;
  1929. if ((mArguments[argIdx].mArgFlags & BfArgFlag_ParamsExpr) != 0)
  1930. {
  1931. // Direct-pass params
  1932. if ((argTypedValue.IsUntypedValue()) || (mModule->CanCast(argTypedValue, paramsArrayType)))
  1933. {
  1934. argIdx++;
  1935. argMatchCount++;
  1936. paramIdx++;
  1937. break;
  1938. }
  1939. goto NoMatch;
  1940. }
  1941. if ((paramsArrayType->IsArray()) || (paramsArrayType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef)))
  1942. {
  1943. paramsElementType = paramsArrayType->GetUnderlyingType();
  1944. while (argIdx < (int)mArguments.size())
  1945. {
  1946. argTypedValue = ResolveArgTypedValue(mArguments[argIdx], paramsElementType, genericArgumentsSubstitute);
  1947. if (!argTypedValue.HasType())
  1948. goto NoMatch;
  1949. BfCastFlags castFlags = ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp) != 0) ? BfCastFlags_NoConversionOperator : BfCastFlags_None;
  1950. if ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp_Explicit) != 0)
  1951. castFlags = (BfCastFlags)(castFlags | BfCastFlags_Explicit);
  1952. if (!mModule->CanCast(argTypedValue, paramsElementType, castFlags))
  1953. goto NoMatch;
  1954. argIdx++;
  1955. argMatchCount++;
  1956. }
  1957. }
  1958. else
  1959. goto NoMatch;
  1960. break;
  1961. }
  1962. if (methodInstance->IsImplicitCapture(paramIdx))
  1963. {
  1964. paramIdx++;
  1965. continue;
  1966. }
  1967. if (argIdx >= (int) mArguments.size())
  1968. {
  1969. // We have defaults the rest of the way, so that's cool
  1970. if (methodInstance->GetParamInitializer(paramIdx) != NULL)
  1971. break;
  1972. // We have unused params left over
  1973. goto NoMatch;
  1974. }
  1975. auto wantType = methodInstance->GetParamType(paramIdx);
  1976. if ((genericArgumentsSubstitute != NULL) && (wantType->IsUnspecializedType()))
  1977. {
  1978. wantType = typeUnspecMethodInstance->GetParamType(paramIdx);
  1979. auto resolvedType = mModule->ResolveGenericType(wantType, typeGenericArguments, genericArgumentsSubstitute, mModule->mCurTypeInstance, false);
  1980. if (resolvedType == NULL)
  1981. goto NoMatch;
  1982. wantType = resolvedType;
  1983. }
  1984. wantType = mModule->ResolveSelfType(wantType, typeInstance);
  1985. if ((argIdx >= 0) && ((mArguments[argIdx].mArgFlags & BfArgFlag_ParamsExpr) != 0))
  1986. {
  1987. // We had a 'params' expression but this method didn't have a params slot in this parameter
  1988. goto NoMatch;
  1989. }
  1990. BfTypedValue argTypedValue;
  1991. if (argIdx == -1)
  1992. argTypedValue = mTarget;
  1993. else
  1994. argTypedValue = ResolveArgTypedValue(mArguments[argIdx], wantType, genericArgumentsSubstitute);
  1995. if (!argTypedValue.IsUntypedValue())
  1996. {
  1997. if (!argTypedValue.HasType())
  1998. {
  1999. // Check to see if this is the last argument and that it's a potential enum match
  2000. if ((wantType->IsEnum()) && (argIdx == mArguments.size() - 1))
  2001. {
  2002. if (auto memberRefExpr = BfNodeDynCast<BfMemberReferenceExpression>(mArguments[argIdx].mExpression))
  2003. {
  2004. if (memberRefExpr->mTarget == NULL)
  2005. {
  2006. // Is dot expression
  2007. curMatchKind = BackupMatchKind_PartialLastArgMatch;
  2008. }
  2009. }
  2010. }
  2011. bool matches = false;
  2012. if (wantType->IsOut())
  2013. {
  2014. if (auto memberRefExpr = BfNodeDynCast<BfUninitializedExpression>(mArguments[argIdx].mExpression))
  2015. matches = true;
  2016. }
  2017. if (!matches)
  2018. goto NoMatch;
  2019. }
  2020. else
  2021. {
  2022. if ((checkMethod->mMethodType == BfMethodType_Extension) && (argIdx == -1))
  2023. {
  2024. if ((wantType->IsRef()) && (!argTypedValue.mType->IsRef()))
  2025. wantType = wantType->GetUnderlyingType();
  2026. }
  2027. if ((wantType->IsRef()) && (!argTypedValue.mType->IsRef()) &&
  2028. ((mAllowImplicitRef) || (wantType->IsIn())))
  2029. wantType = wantType->GetUnderlyingType();
  2030. BfCastFlags castFlags = ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp) != 0) ? BfCastFlags_NoConversionOperator : BfCastFlags_None;
  2031. if ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp_Explicit) != 0)
  2032. castFlags = (BfCastFlags)(castFlags | BfCastFlags_Explicit);
  2033. if ((mCheckReturnType != NULL) && (wantType->IsVar()))
  2034. {
  2035. // If we allowed this then it would allow too many matches (and allow conversion from any type during CastToValue)
  2036. goto NoMatch;
  2037. }
  2038. if (!mModule->CanCast(argTypedValue, wantType, castFlags))
  2039. {
  2040. if ((argIdx == -1) && (wantType->IsWrappableType()) && (mModule->GetWrappedStructType(wantType) == argTypedValue.mType))
  2041. {
  2042. // Extension target can be wrapped
  2043. }
  2044. else if ((mAllowImplicitWrap) && (argTypedValue.mType->IsWrappableType()) && (mModule->GetWrappedStructType(argTypedValue.mType) == wantType))
  2045. {
  2046. // Is wrapped type
  2047. }
  2048. else
  2049. goto NoMatch;
  2050. }
  2051. }
  2052. }
  2053. paramIdx++;
  2054. argIdx++;
  2055. argMatchCount++;
  2056. if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo))
  2057. {
  2058. auto methodMatchInfo = autoComplete->mMethodMatchInfo;
  2059. if (!methodMatchInfo->mHadExactMatch)
  2060. {
  2061. bool isBetter = false;
  2062. bool isWorse = false;
  2063. int methodIdx = (int)methodMatchInfo->mInstanceList.size() - 1;
  2064. if ((methodMatchInfo->mBestIdx != -1) && (methodMatchInfo->mBestIdx < (int)methodMatchInfo->mInstanceList.size()))
  2065. {
  2066. auto prevMethodMatchEntry = &methodMatchInfo->mInstanceList[methodMatchInfo->mBestIdx];
  2067. if (checkMethod->mParams.size() < mArguments.size())
  2068. {
  2069. isWorse = true;
  2070. }
  2071. else if ((prevMethodMatchEntry->mMethodDef != NULL) && (prevMethodMatchEntry->mMethodDef->mParams.size() < (int) mArguments.size()))
  2072. {
  2073. isBetter = true;
  2074. }
  2075. }
  2076. }
  2077. }
  2078. }
  2079. // Too many arguments (not all incoming arguments processed)
  2080. if (argIdx < (int)mArguments.size())
  2081. {
  2082. if (!methodInstance->IsVarArgs())
  2083. goto NoMatch;
  2084. }
  2085. if (mCheckReturnType != NULL)
  2086. {
  2087. auto returnType = methodInstance->mReturnType;
  2088. if (returnType->IsVar())
  2089. {
  2090. // If we allowed this then it would allow too many matches (and allow conversion to any type during CastToValue)
  2091. goto NoMatch;
  2092. }
  2093. bool doFullTypeResolve = false;
  2094. if (returnType->IsUnspecializedTypeVariation())
  2095. {
  2096. returnType = typeUnspecMethodInstance->mReturnType;
  2097. doFullTypeResolve = true;
  2098. }
  2099. if ((genericArgumentsSubstitute != NULL) && (returnType->IsUnspecializedType()))
  2100. doFullTypeResolve = true;
  2101. if (doFullTypeResolve)
  2102. {
  2103. auto resolvedType = mModule->ResolveGenericType(returnType, typeGenericArguments, genericArgumentsSubstitute, mModule->mCurTypeInstance, false);
  2104. if (resolvedType == NULL)
  2105. goto NoMatch;
  2106. returnType = resolvedType;
  2107. }
  2108. returnType = mModule->ResolveSelfType(returnType, typeInstance);
  2109. BfCastFlags castFlags = ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp) != 0) ? (BfCastFlags)(BfCastFlags_NoConversionOperator | BfCastFlags_NoInterfaceImpl) : BfCastFlags_None;
  2110. if ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp_Explicit) != 0)
  2111. castFlags = (BfCastFlags)(castFlags | BfCastFlags_Explicit);
  2112. if (!mModule->CanCast(mModule->GetFakeTypedValue(returnType), mCheckReturnType, castFlags))
  2113. goto NoMatch;
  2114. }
  2115. if ((genericArgumentsSubstitute != NULL) && (genericArgumentsSubstitute->size() != 0))
  2116. {
  2117. for (int checkGenericIdx = uniqueGenericStartIdx; checkGenericIdx < (int)genericArgumentsSubstitute->size(); checkGenericIdx++)
  2118. {
  2119. auto& genericParams = methodInstance->mMethodInfoEx->mGenericParams;
  2120. auto genericArg = (*genericArgumentsSubstitute)[checkGenericIdx];
  2121. if (genericArg == NULL)
  2122. {
  2123. if (allowEmptyGenericSet.Contains(checkGenericIdx))
  2124. continue;
  2125. goto NoMatch;
  2126. }
  2127. if (genericArg == NULL)
  2128. goto NoMatch;
  2129. if (!mModule->CheckGenericConstraints(BfGenericParamSource(methodInstance), genericArg, NULL, genericParams[checkGenericIdx], genericArgumentsSubstitute, NULL))
  2130. goto NoMatch;
  2131. }
  2132. }
  2133. for (int externConstraintIdx = 0; externConstraintIdx < (int)checkMethod->mExternalConstraints.size(); externConstraintIdx++)
  2134. {
  2135. auto genericParam = methodInstance->mMethodInfoEx->mGenericParams[checkMethod->mGenericParams.size() + externConstraintIdx];
  2136. BF_ASSERT(genericParam->mExternType != NULL);
  2137. auto externType = genericParam->mExternType;
  2138. BfTypeVector* externGenericArgumentsSubstitute = genericArgumentsSubstitute;
  2139. if (externType->IsVar())
  2140. {
  2141. auto& externConstraint = checkMethod->mExternalConstraints[externConstraintIdx];
  2142. if (externConstraint.mTypeRef != NULL)
  2143. {
  2144. externType = mModule->ResolveGenericMethodTypeRef(externConstraint.mTypeRef, methodInstance, genericParam, genericArgumentsSubstitute);
  2145. if (externType == NULL)
  2146. goto NoMatch;
  2147. }
  2148. }
  2149. if (externType->IsGenericParam())
  2150. {
  2151. auto genericParamType = (BfGenericParamType*)externType;
  2152. if (genericParamType->mGenericParamKind == BfGenericParamKind_Method)
  2153. {
  2154. if (genericArgumentsSubstitute != NULL)
  2155. {
  2156. auto genericArg = (*genericArgumentsSubstitute)[genericParamType->mGenericParamIdx];
  2157. if (genericArg == NULL)
  2158. {
  2159. if (allowEmptyGenericSet.Contains(genericParamType->mGenericParamIdx))
  2160. continue;
  2161. goto NoMatch;
  2162. }
  2163. externType = genericArg;
  2164. }
  2165. }
  2166. }
  2167. if (!mModule->CheckGenericConstraints(BfGenericParamSource(methodInstance), externType, NULL, genericParam, externGenericArgumentsSubstitute, NULL))
  2168. goto NoMatch;
  2169. }
  2170. // if (auto methodDecl = BfNodeDynCast<BfMethodDeclaration>(checkMethod->mMethodDeclaration))
  2171. // {
  2172. // if ((methodDecl->mGenericConstraintsDeclaration != NULL) && (methodDecl->mGenericConstraintsDeclaration->mHasExpressions))
  2173. // {
  2174. // for (auto genericConstraint : methodDecl->mGenericConstraintsDeclaration->mGenericConstraints)
  2175. // {
  2176. // if (auto genericConstraintExpr = BfNodeDynCast<BfGenericConstraintExpression>(genericConstraint))
  2177. // {
  2178. // if (genericConstraintExpr->mExpression == NULL)
  2179. // continue;
  2180. // BfConstResolver constResolver(mModule);
  2181. // constResolver.mExpectingType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  2182. // constResolver.Resolve(genericConstraintExpr->mExpression, constResolver.mExpectingType);
  2183. // }
  2184. // }
  2185. // }
  2186. // }
  2187. // Method is applicable, check to see which method is better
  2188. if (mBestMethodDef != NULL)
  2189. {
  2190. bool isBetter = false;
  2191. bool isWorse = false;
  2192. BfMethodInstance* prevMethodInstance = mModule->GetRawMethodInstance(mBestMethodTypeInstance, mBestMethodDef);
  2193. bool allowSpecializeFail = mModule->mCurTypeInstance->IsUnspecializedType();
  2194. if (mModule->mCurMethodInstance != NULL)
  2195. allowSpecializeFail = mModule->mCurMethodInstance->mIsUnspecialized;
  2196. CompareMethods(prevMethodInstance, &mBestMethodGenericArguments, methodInstance, genericArgumentsSubstitute, &isBetter, &isWorse, allowSpecializeFail);
  2197. // If we had both a 'better' and 'worse', that's ambiguous because the methods are each better in different ways (not allowed)
  2198. // And if neither better nor worse then they are equally good, which is not allowed either
  2199. if (((!isBetter) && (!isWorse)) || ((isBetter) && (isWorse)))
  2200. {
  2201. if (!mHasVarArguments)
  2202. {
  2203. // If we are ambiguous based on a subset of an extern 'var' constraint then don't throw an error
  2204. auto _CheckMethodInfo = [&](BfMethodInstance* checkMethodInstance)
  2205. {
  2206. if (checkMethodInstance->mMethodInfoEx == NULL)
  2207. return;
  2208. for (auto genericParam : checkMethodInstance->mMethodInfoEx->mGenericParams)
  2209. {
  2210. if ((genericParam->mExternType == NULL) || (!genericParam->mExternType->IsGenericParam()))
  2211. continue;
  2212. auto genericParamType = (BfGenericParamType*)genericParam->mExternType;
  2213. if (genericParamType->mGenericParamKind != BfGenericParamKind_Type)
  2214. continue;
  2215. auto externGenericParam = mModule->GetGenericParamInstance(genericParamType);
  2216. if ((externGenericParam->mGenericParamFlags & BfGenericParamFlag_Var) != 0)
  2217. mHasVarArguments = true;
  2218. }
  2219. };
  2220. _CheckMethodInfo(methodInstance);
  2221. _CheckMethodInfo(prevMethodInstance);
  2222. }
  2223. if (mHasVarArguments)
  2224. {
  2225. if (methodInstance->mReturnType != prevMethodInstance->mReturnType)
  2226. mHadVarConflictingReturnType = true;
  2227. }
  2228. else
  2229. {
  2230. BfAmbiguousEntry ambiguousEntry;
  2231. ambiguousEntry.mMethodInstance = methodInstance;
  2232. if (genericArgumentsSubstitute != NULL)
  2233. ambiguousEntry.mBestMethodGenericArguments = *genericArgumentsSubstitute;
  2234. if (methodInstance->mMethodDef->mGenericParams.size() != 0)
  2235. {
  2236. BF_ASSERT(!ambiguousEntry.mBestMethodGenericArguments.empty());
  2237. }
  2238. mAmbiguousEntries.push_back(ambiguousEntry);
  2239. goto Done;
  2240. }
  2241. }
  2242. if (!isBetter)
  2243. goto Done;
  2244. }
  2245. if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo))
  2246. {
  2247. auto methodMatchInfo = autoComplete->mMethodMatchInfo;
  2248. // Try to persist with previous partial match, if we have one - this keeps us from locking onto
  2249. // an incorrect method just because it had the current number of params that we've typed so far
  2250. if (methodMatchInfo->mPrevBestIdx == -1)
  2251. {
  2252. methodMatchInfo->mHadExactMatch = true;
  2253. methodMatchInfo->mBestIdx = (int) methodMatchInfo->mInstanceList.size() - 1;
  2254. }
  2255. }
  2256. mAmbiguousEntries.Clear();
  2257. hadMatch = true;
  2258. mBestMethodDef = checkMethod;
  2259. mBestRawMethodInstance = methodInstance;
  2260. for (auto& arg : mArguments)
  2261. arg.mBestBoundType = arg.mTypedValue.mType;
  2262. NoMatch:
  2263. if (!hadMatch)
  2264. {
  2265. if (mBestMethodDef != NULL)
  2266. return false;
  2267. if (checkMethod->mMethodType == BfMethodType_Extension)
  2268. {
  2269. auto thisParam = methodInstance->GetParamType(0);
  2270. auto resolveThisParam = mModule->ResolveGenericType(thisParam, NULL, &mCheckMethodGenericArguments, mModule->mCurTypeInstance);
  2271. if (resolveThisParam == NULL)
  2272. return false;
  2273. if (!mModule->CanCast(mTarget, resolveThisParam,
  2274. ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp) != 0) ? (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_NoConversionOperator) : BfCastFlags_Explicit))
  2275. return false;
  2276. }
  2277. if (mBackupMethodDef != NULL)
  2278. {
  2279. int prevParamDiff = (int)mBackupMethodDef->GetExplicitParamCount() - (int)mArguments.size();
  2280. int paramDiff = (int)checkMethod->GetExplicitParamCount() - (int)mArguments.size();
  2281. if ((prevParamDiff < 0) && (prevParamDiff > paramDiff))
  2282. return false;
  2283. if ((prevParamDiff >= 0) && (paramDiff < 0))
  2284. return false;
  2285. if (argMatchCount < mBackupArgMatchCount)
  2286. return false;
  2287. else if (argMatchCount == mBackupArgMatchCount)
  2288. {
  2289. if (curMatchKind < mBackupMatchKind)
  2290. return false;
  2291. // We search from the most specific type, so don't prefer a less specific type
  2292. if (mBestMethodTypeInstance != typeInstance)
  2293. return false;
  2294. }
  2295. }
  2296. if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo))
  2297. {
  2298. auto methodMatchInfo = autoComplete->mMethodMatchInfo;
  2299. if ((methodMatchInfo->mPrevBestIdx == -1) && (!methodMatchInfo->mHadExactMatch))
  2300. {
  2301. methodMatchInfo->mBestIdx = (int)methodMatchInfo->mInstanceList.size() - 1;
  2302. }
  2303. }
  2304. mBackupMatchKind = curMatchKind;
  2305. mBackupMethodDef = checkMethod;
  2306. mBackupArgMatchCount = argMatchCount;
  2307. // Lie temporarily to store at least one candidate (but mBestMethodDef is still NULL)
  2308. hadMatch = true;
  2309. }
  2310. if (hadMatch)
  2311. {
  2312. mBestMethodTypeInstance = typeInstance;
  2313. if (genericArgumentsSubstitute != &mBestMethodGenericArguments)
  2314. {
  2315. if (genericArgumentsSubstitute != NULL)
  2316. {
  2317. for (auto& genericArg : *genericArgumentsSubstitute)
  2318. genericArg = mModule->FixIntUnknown(genericArg);
  2319. mBestMethodGenericArguments = *genericArgumentsSubstitute;
  2320. // #ifdef _DEBUG
  2321. // for (auto arg : mBestMethodGenericArguments)
  2322. // BF_ASSERT((arg == NULL) || (!arg->IsVar()));
  2323. // #endif
  2324. }
  2325. else
  2326. mBestMethodGenericArguments.clear();
  2327. }
  2328. }
  2329. Done:
  2330. if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo))
  2331. {
  2332. auto methodMatchInfo = autoComplete->mMethodMatchInfo;
  2333. if (!methodMatchInfo->mInstanceList.IsEmpty())
  2334. {
  2335. auto& matchInstance = methodMatchInfo->mInstanceList[methodMatchInfo->mInstanceList.size() - 1];
  2336. matchInstance.mArgMatchCount = argMatchCount;
  2337. matchInstance.mIsMatch = hadMatch;
  2338. if (genericArgumentsSubstitute != NULL)
  2339. matchInstance.mGenericArguments = *genericArgumentsSubstitute;
  2340. }
  2341. }
  2342. return mBestMethodDef == checkMethod;
  2343. }
  2344. void BfMethodMatcher::FlushAmbiguityError(bool useWarning)
  2345. {
  2346. if (!mAmbiguousEntries.empty())
  2347. {
  2348. if (mModule->PreFail())
  2349. {
  2350. BfError* error;
  2351. if (!mMethodName.empty())
  2352. {
  2353. if (useWarning)
  2354. error = mModule->Warn(0, StrFormat("Ambiguous method call for '%s'", mMethodName.c_str()), mTargetSrc);
  2355. else
  2356. error = mModule->Fail(StrFormat("Ambiguous method call for '%s'", mMethodName.c_str()), mTargetSrc);
  2357. }
  2358. else
  2359. {
  2360. if (useWarning)
  2361. error = mModule->Warn(0, "Ambiguous method call", mTargetSrc);
  2362. else
  2363. error = mModule->Fail("Ambiguous method call", mTargetSrc);
  2364. }
  2365. if (error != NULL)
  2366. {
  2367. BfMethodInstance* bestMethodInstance = mModule->GetUnspecializedMethodInstance(mBestRawMethodInstance, true);
  2368. BfTypeVector* typeGenericArguments = NULL;
  2369. if (mBestMethodTypeInstance->mGenericTypeInfo != NULL)
  2370. typeGenericArguments = &mBestMethodTypeInstance->mGenericTypeInfo->mTypeGenericArguments;
  2371. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' is a candidate", mModule->MethodToString(bestMethodInstance, BfMethodNameFlag_ResolveGenericParamNames,
  2372. typeGenericArguments, mBestMethodGenericArguments.empty() ? NULL : &mBestMethodGenericArguments).c_str()),
  2373. bestMethodInstance->mMethodDef->GetRefNode());
  2374. for (auto& ambiguousEntry : mAmbiguousEntries)
  2375. {
  2376. auto typeInstance = ambiguousEntry.mMethodInstance->GetOwner();
  2377. auto unspecTypeMethodInstance = mModule->GetUnspecializedMethodInstance(ambiguousEntry.mMethodInstance, true);
  2378. BfTypeVector* typeGenericArguments = NULL;
  2379. if (typeInstance->mGenericTypeInfo != NULL)
  2380. typeGenericArguments = &typeInstance->mGenericTypeInfo->mTypeGenericArguments;
  2381. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' is a candidate", mModule->MethodToString(unspecTypeMethodInstance, BfMethodNameFlag_ResolveGenericParamNames,
  2382. typeGenericArguments, ambiguousEntry.mBestMethodGenericArguments.empty() ? NULL : &ambiguousEntry.mBestMethodGenericArguments).c_str()),
  2383. ambiguousEntry.mMethodInstance->mMethodDef->GetRefNode());
  2384. }
  2385. }
  2386. }
  2387. mAmbiguousEntries.Clear();
  2388. }
  2389. }
  2390. bool BfMethodMatcher::IsType(BfTypedValue& typedVal, BfType* type)
  2391. {
  2392. if (typedVal.mType == type)
  2393. return true;
  2394. if (!typedVal)
  2395. return false;
  2396. if (!typedVal.mType->IsPrimitiveType())
  2397. return false;
  2398. if (!type->IsPrimitiveType())
  2399. return false;
  2400. auto fromPrimType = typedVal.mType->ToPrimitiveType();
  2401. if ((fromPrimType->mTypeDef->mTypeCode != BfTypeCode_IntUnknown) &&
  2402. (fromPrimType->mTypeDef->mTypeCode != BfTypeCode_UIntUnknown))
  2403. return false;
  2404. auto constant = mModule->mBfIRBuilder->GetConstant(typedVal.mValue);
  2405. if (constant == NULL)
  2406. return false;
  2407. auto toPrimType = type->ToPrimitiveType();
  2408. if (!mModule->mBfIRBuilder->IsInt(toPrimType->mTypeDef->mTypeCode))
  2409. return false;
  2410. if (type->mSize == 8)
  2411. return false;
  2412. int64 minVal = -(1LL << (8 * type->mSize - 1));
  2413. int64 maxVal = (1LL << (8 * type->mSize - 1)) - 1;
  2414. if ((constant->mInt64 >= minVal) && (constant->mInt64 <= maxVal))
  2415. return true;
  2416. return false;
  2417. }
  2418. // This method checks all base classes before checking interfaces. Is that correct?
  2419. bool BfMethodMatcher::CheckType(BfTypeInstance* typeInstance, BfTypedValue target, bool isFailurePass, bool forceOuterCheck)
  2420. {
  2421. BfMethodDef* prevBestMethodDef = mBestMethodDef;
  2422. auto curTypeInst = typeInstance;
  2423. auto curTypeDef = typeInstance->mTypeDef;
  2424. int checkInterfaceIdx = 0;
  2425. bool targetIsBase = target.IsBase();
  2426. bool checkExtensionBase = false;
  2427. if (targetIsBase)
  2428. {
  2429. if ((curTypeInst == mModule->mCurTypeInstance) && (curTypeInst->mTypeDef->mIsCombinedPartial))
  2430. {
  2431. checkExtensionBase = true;
  2432. }
  2433. else
  2434. {
  2435. curTypeInst = curTypeInst->mBaseType;
  2436. }
  2437. }
  2438. BfTypeInstance* targetTypeInstance = NULL;
  2439. if (target.mType != NULL)
  2440. targetTypeInstance = target.mType->ToTypeInstance();
  2441. while (true)
  2442. {
  2443. bool doSearch = true;
  2444. if ((mMethodType == BfMethodType_Extension) && (!curTypeDef->mHasExtensionMethods))
  2445. doSearch = false;
  2446. BfMethodDef* nextMethodDef = NULL;
  2447. if (doSearch)
  2448. {
  2449. curTypeDef->PopulateMemberSets();
  2450. BfMemberSetEntry* entry;
  2451. if (curTypeDef->mMethodSet.TryGetWith(mMethodName, &entry))
  2452. nextMethodDef = (BfMethodDef*)entry->mMemberDef;
  2453. }
  2454. BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None;
  2455. if (target)
  2456. {
  2457. if (mBypassVirtual)
  2458. {
  2459. // Not an "instance lookup"
  2460. }
  2461. else
  2462. {
  2463. protectionCheckFlags = (BfProtectionCheckFlags)(protectionCheckFlags | BfProtectionCheckFlag_InstanceLookup);
  2464. }
  2465. }
  2466. while (nextMethodDef != NULL)
  2467. {
  2468. bool allowExplicitInterface = curTypeInst->IsInterface() && mBypassVirtual;
  2469. auto activeTypeDef = mModule->GetActiveTypeDef();
  2470. auto visibleProjectSet = mModule->GetVisibleProjectSet();
  2471. bool isDelegate = typeInstance->IsDelegate();
  2472. auto checkMethod = nextMethodDef;
  2473. nextMethodDef = nextMethodDef->mNextWithSameName;
  2474. if (mModule->mContext->mResolvingVarField)
  2475. {
  2476. bool isResolvingVarField = false;
  2477. auto checkTypeState = mModule->mContext->mCurTypeState;
  2478. while (checkTypeState != NULL)
  2479. {
  2480. if ((checkTypeState->mResolveKind == BfTypeState::ResolveKind_ResolvingVarType) &&
  2481. (checkTypeState->mType == typeInstance))
  2482. isResolvingVarField = true;
  2483. checkTypeState = checkTypeState->mPrevState;
  2484. }
  2485. if (isResolvingVarField)
  2486. {
  2487. BF_ASSERT(mModule->mBfIRBuilder->mIgnoreWrites);
  2488. // Don't even consider - we can't do method calls on ourselves when we are resolving var fields, because
  2489. // we are not allowed to generate methods when our field types are unknown. We may fix this in the future,
  2490. // but currently it breaks out expected order of operations. One issue is that our call signatures change
  2491. // depending on whether we are valueless or splattable, which depend on underlying type information
  2492. break;
  2493. }
  2494. }
  2495. if ((checkExtensionBase) && (curTypeInst == mModule->mCurTypeInstance))
  2496. {
  2497. // Accept either a method in the same project but that's the root definition, OR a method that's in a dependent project
  2498. bool accept = false;
  2499. if (activeTypeDef->mProject == checkMethod->mDeclaringType->mProject)
  2500. accept = (activeTypeDef->IsExtension()) && (!checkMethod->mDeclaringType->IsExtension());
  2501. else
  2502. accept = activeTypeDef->mProject->ContainsReference(checkMethod->mDeclaringType->mProject);
  2503. if (!accept)
  2504. continue;
  2505. }
  2506. if ((!allowExplicitInterface) && (checkMethod->mExplicitInterface != NULL) && (mInterfaceMethodInstance == NULL))
  2507. {
  2508. continue;
  2509. }
  2510. if (checkMethod->mMethodType != mMethodType)
  2511. continue;
  2512. // if (checkMethod->mName != mMethodName)
  2513. // continue;
  2514. if ((checkMethod->mDeclaringType->IsExtension()) && (mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) &&
  2515. (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mNoExtensionAttributeTypeDef)))
  2516. {
  2517. mModule->mAttributeState->mUsed = true;
  2518. continue;
  2519. }
  2520. if (!isDelegate)
  2521. {
  2522. if ((!curTypeInst->IsTypeMemberIncluded(checkMethod->mDeclaringType, activeTypeDef, mModule)) ||
  2523. (!curTypeInst->IsTypeMemberAccessible(checkMethod->mDeclaringType, visibleProjectSet)))
  2524. continue;
  2525. }
  2526. MatchFailKind matchFailKind = MatchFailKind_None;
  2527. if (!mModule->CheckProtection(protectionCheckFlags, curTypeInst, checkMethod->mDeclaringType->mProject, checkMethod->mProtection, typeInstance))
  2528. {
  2529. if ((mBypassVirtual) &&
  2530. ((checkMethod->mProtection == BfProtection_Protected) || (checkMethod->mProtection == BfProtection_ProtectedInternal)) &&
  2531. (mModule->TypeIsSubTypeOf(mModule->mCurTypeInstance, typeInstance)))
  2532. {
  2533. // Allow explicit 'base' call
  2534. }
  2535. else
  2536. {
  2537. if (!isFailurePass)
  2538. continue;
  2539. matchFailKind = MatchFailKind_Protection;
  2540. }
  2541. }
  2542. if (mCheckedKind != checkMethod->mCheckedKind)
  2543. {
  2544. bool passes = true;
  2545. if (mCheckedKind != BfCheckedKind_NotSet)
  2546. {
  2547. passes = false;
  2548. }
  2549. else
  2550. {
  2551. auto defaultCheckedKind = mModule->GetDefaultCheckedKind();
  2552. if (defaultCheckedKind != checkMethod->mCheckedKind)
  2553. passes = false;
  2554. }
  2555. if (!passes)
  2556. {
  2557. if (!isFailurePass)
  2558. continue;
  2559. matchFailKind = MatchFailKind_CheckedMismatch;
  2560. }
  2561. }
  2562. CheckMethod(targetTypeInstance, curTypeInst, checkMethod, isFailurePass);
  2563. if ((isFailurePass) &&
  2564. ((mBestMethodDef == checkMethod) || (mBackupMethodDef == checkMethod)))
  2565. mMatchFailKind = matchFailKind;
  2566. }
  2567. if ((mBestMethodDef != NULL) && (mMethodType != BfMethodType_Extension))
  2568. {
  2569. if ((mUsingLists != NULL) && (mUsingLists->mSize != 0))
  2570. mUsingLists->Clear();
  2571. if (mAutoFlushAmbiguityErrors)
  2572. FlushAmbiguityError();
  2573. return true;
  2574. }
  2575. if ((mUsingLists != NULL) && (curTypeInst->mTypeDef->mHasUsingFields))
  2576. mModule->PopulateUsingFieldData(curTypeInst);
  2577. if (mUsingLists != NULL)
  2578. {
  2579. auto _CheckUsingData = [&](BfUsingFieldData* usingData)
  2580. {
  2581. BfUsingFieldData::Entry* entry = NULL;
  2582. if (!usingData->mMethods.TryGetValue(mMethodName, &entry))
  2583. return;
  2584. for (int listIdx = 0; listIdx < entry->mLookups.mSize; listIdx++)
  2585. {
  2586. bool passesProtection = true;
  2587. auto& entryList = entry->mLookups[listIdx];
  2588. for (int entryIdx = 0; entryIdx < entryList.mSize; entryIdx++)
  2589. {
  2590. auto& entry = entryList[entryIdx];
  2591. BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None;
  2592. if (!mModule->CheckProtection(protectionCheckFlags, entry.mTypeInstance, entry.GetDeclaringType(mModule)->mProject,
  2593. (entryIdx < entryList.mSize - 1) ? entry.GetUsingProtection() : entry.GetProtection(), curTypeInst))
  2594. {
  2595. passesProtection = false;
  2596. break;
  2597. }
  2598. }
  2599. if (!passesProtection)
  2600. continue;
  2601. auto& entry = entryList.back();
  2602. BF_ASSERT(entry.mKind == BfUsingFieldData::MemberRef::Kind_Method);
  2603. auto methodDef = entry.mTypeInstance->mTypeDef->mMethods[entry.mIdx];
  2604. CheckMethod(curTypeInst, entry.mTypeInstance, methodDef, isFailurePass);
  2605. if ((mBestMethodDef != methodDef) && (mBackupMethodDef != methodDef))
  2606. {
  2607. bool foundAmbiguous = false;
  2608. for (int checkIdx = 0; checkIdx < mAmbiguousEntries.mSize; checkIdx++)
  2609. {
  2610. if (mAmbiguousEntries[checkIdx].mMethodInstance->mMethodDef == methodDef)
  2611. {
  2612. mAmbiguousEntries.RemoveAt(checkIdx);
  2613. foundAmbiguous = true;
  2614. break;
  2615. }
  2616. }
  2617. if (!foundAmbiguous)
  2618. continue;
  2619. }
  2620. if (mUsingLists->mSize == 0)
  2621. {
  2622. mUsingLists->Add(&entryList);
  2623. }
  2624. else
  2625. {
  2626. if (entryList.mSize < (*mUsingLists)[0]->mSize)
  2627. {
  2628. // New is shorter
  2629. mUsingLists->Clear();
  2630. mUsingLists->Add(&entryList);
  2631. }
  2632. else if (entryList.mSize > (*mUsingLists)[0]->mSize)
  2633. {
  2634. // Ignore longer
  2635. }
  2636. else
  2637. {
  2638. mUsingLists->Add(&entryList);
  2639. }
  2640. }
  2641. }
  2642. };
  2643. if ((curTypeInst->mTypeInfoEx != NULL) && (curTypeInst->mTypeInfoEx->mUsingFieldData != NULL))
  2644. _CheckUsingData(curTypeInst->mTypeInfoEx->mUsingFieldData);
  2645. if (mBestMethodDef != NULL)
  2646. break;
  2647. }
  2648. auto baseType = curTypeInst->mBaseType;
  2649. if (baseType == NULL)
  2650. {
  2651. //TODO: Why were we doing the interface checking?
  2652. if ((curTypeInst->IsInterface()) && (curTypeInst == target.mType))
  2653. {
  2654. // When we are directly calling on interfaces rather than indirectly matching through binding
  2655. baseType = mModule->mContext->mBfObjectType;
  2656. }
  2657. else if ((curTypeInst != mModule->mContext->mBfObjectType) && (!curTypeInst->IsInterface()))
  2658. {
  2659. // This can happen for structs
  2660. baseType = mModule->mContext->mBfObjectType;
  2661. }
  2662. else if ((typeInstance->IsInterface()) && (checkInterfaceIdx < (int)typeInstance->mInterfaces.size()))
  2663. {
  2664. baseType = typeInstance->mInterfaces[checkInterfaceIdx].mInterfaceType;
  2665. checkInterfaceIdx++;
  2666. }
  2667. else
  2668. {
  2669. break;
  2670. }
  2671. }
  2672. curTypeDef = baseType->mTypeDef;
  2673. curTypeInst = baseType;
  2674. if ((isFailurePass) && (mBackupMethodDef != NULL))
  2675. break;
  2676. }
  2677. if (mBestMethodDef == NULL)
  2678. {
  2679. // FAILED, but select the first method which will fire an actual error on param type matching
  2680. mBestMethodDef = mBackupMethodDef;
  2681. }
  2682. if (((mBestMethodDef == NULL) && (!target) && (mAllowImplicitThis)) ||
  2683. (forceOuterCheck))
  2684. {
  2685. // No explicit target - maybe this was a static call in the outer type?
  2686. auto outerType = mModule->GetOuterType(typeInstance);
  2687. if (outerType != NULL)
  2688. CheckOuterTypeStaticMethods(outerType, isFailurePass);
  2689. }
  2690. if (mAutoFlushAmbiguityErrors)
  2691. FlushAmbiguityError();
  2692. return mBestMethodDef != prevBestMethodDef;
  2693. }
  2694. void BfMethodMatcher::TryDevirtualizeCall(BfTypedValue target, BfTypedValue* origTarget, BfTypedValue* staticResult)
  2695. {
  2696. if ((mBestMethodDef == NULL) || (target.mType == NULL))
  2697. return;
  2698. if ((mModule->mCompiler->IsAutocomplete()) || (mModule->mContext->mResolvingVarField))
  2699. return;
  2700. if ((mModule->mBfIRBuilder->mIgnoreWrites) && (!mBestMethodDef->mIsConcrete) && (!mBestMethodTypeInstance->IsInterface()))
  2701. return;
  2702. if (mBestMethodTypeInstance->IsInterface())
  2703. {
  2704. mModule->PopulateType(mBestMethodTypeInstance, BfPopulateType_DataAndMethods);
  2705. auto activeTypeDef = mModule->GetActiveTypeDef();
  2706. // Statically map this call
  2707. auto checkType = target.mType;
  2708. if (checkType->IsPointer())
  2709. checkType = ((BfPointerType*)checkType)->mElementType;
  2710. if (checkType->IsWrappableType())
  2711. checkType = mModule->GetWrappedStructType(checkType);
  2712. if ((checkType != NULL) && (checkType->IsTypeInstance()) && (!checkType->IsInterface()))
  2713. {
  2714. BfTypeInterfaceEntry* bestIFaceEntry = NULL;
  2715. auto checkTypeInst = checkType->ToTypeInstance();
  2716. if (mBestMethodTypeInstance->IsInstanceOf(mModule->mCompiler->mIHashableTypeDef))
  2717. {
  2718. if ((origTarget != NULL) && (origTarget->mType->IsPointer()) && (staticResult != NULL))
  2719. {
  2720. BfTypedValue ptrVal = mModule->LoadValue(*origTarget);
  2721. *staticResult = BfTypedValue(mModule->mBfIRBuilder->CreatePtrToInt(ptrVal.mValue, BfTypeCode_IntPtr), mModule->GetPrimitiveType(BfTypeCode_IntPtr));
  2722. return;
  2723. }
  2724. }
  2725. while (checkTypeInst != NULL)
  2726. {
  2727. mModule->PopulateType(checkTypeInst, BfPopulateType_DataAndMethods);
  2728. if (checkTypeInst->mDefineState >= BfTypeDefineState_DefinedAndMethodsSlotted)
  2729. {
  2730. for (auto&& iface : checkTypeInst->mInterfaces)
  2731. {
  2732. //TODO: Why did we have this check? This caused Dictionary to not be able to devirtualize
  2733. // calls to TKey GetHashCode when TKey was from a user's project...
  2734. /*if (!checkTypeInst->IsTypeMemberAccessible(iface.mDeclaringType, activeTypeDef))
  2735. continue;*/
  2736. if (iface.mInterfaceType == mBestMethodTypeInstance)
  2737. {
  2738. if (bestIFaceEntry == NULL)
  2739. {
  2740. bestIFaceEntry = &iface;
  2741. continue;
  2742. }
  2743. bool isBetter;
  2744. bool isWorse;
  2745. mModule->CompareDeclTypes(NULL, iface.mDeclaringType, bestIFaceEntry->mDeclaringType, isBetter, isWorse);
  2746. if (isBetter == isWorse)
  2747. {
  2748. // Failed
  2749. }
  2750. else
  2751. {
  2752. if (isBetter)
  2753. bestIFaceEntry = &iface;
  2754. }
  2755. }
  2756. }
  2757. }
  2758. if (bestIFaceEntry != NULL)
  2759. break;
  2760. checkTypeInst = checkTypeInst->mBaseType;
  2761. if ((checkTypeInst == NULL) && (checkType->HasWrappedRepresentation()))
  2762. {
  2763. auto underlyingType = checkType->GetUnderlyingType();
  2764. if ((underlyingType != NULL) && (underlyingType->IsWrappableType()))
  2765. checkTypeInst = mModule->GetWrappedStructType(underlyingType);
  2766. if (checkTypeInst == checkType)
  2767. break;
  2768. }
  2769. }
  2770. if (bestIFaceEntry != NULL)
  2771. {
  2772. auto ifaceMethodEntry = checkTypeInst->mInterfaceMethodTable[bestIFaceEntry->mStartInterfaceTableIdx + mBestMethodDef->mIdx];
  2773. BfMethodInstance* bestMethodInstance = ifaceMethodEntry.mMethodRef;
  2774. if (bestMethodInstance != NULL)
  2775. {
  2776. bool isMissingArg = false;
  2777. for (auto genericArg : mBestMethodGenericArguments)
  2778. {
  2779. if (genericArg == NULL)
  2780. isMissingArg = true;
  2781. }
  2782. if (!isMissingArg)
  2783. {
  2784. // Assert error state?
  2785. mBestMethodTypeInstance = ifaceMethodEntry.mMethodRef.mTypeInstance;
  2786. mBestMethodDef = bestMethodInstance->mMethodDef;
  2787. mBestMethodInstance = mModule->GetMethodInstance(mBestMethodTypeInstance, bestMethodInstance->mMethodDef, mBestMethodGenericArguments,
  2788. bestMethodInstance->mIsForeignMethodDef ? BfGetMethodInstanceFlag_ForeignMethodDef : BfGetMethodInstanceFlag_None,
  2789. bestMethodInstance->GetForeignType());
  2790. }
  2791. }
  2792. else
  2793. {
  2794. // Failed
  2795. mFakeConcreteTarget = true;
  2796. }
  2797. }
  2798. }
  2799. }
  2800. if ((target.mType->IsValueType()) && (mBestMethodTypeInstance->IsObject()) && (mBestMethodDef->mIsVirtual))
  2801. {
  2802. auto structType = target.mType->ToTypeInstance();
  2803. if (structType == NULL)
  2804. {
  2805. mModule->InternalError("Invalid type in TryDevirtualizeCall");
  2806. return;
  2807. }
  2808. auto virtualMethodInstance = mModule->GetMethodInstance(mBestMethodTypeInstance, mBestMethodDef, BfTypeVector());
  2809. BF_ASSERT(virtualMethodInstance.mMethodInstance->mVirtualTableIdx != -1);
  2810. BfTypeInstance* boxedType;
  2811. if (structType->HasOverrideMethods())
  2812. {
  2813. // We don't actually need this boxed type, so just resolve it unreified
  2814. auto useModule = mModule->mContext->mUnreifiedModule;
  2815. boxedType = useModule->CreateBoxedType(target.mType);
  2816. useModule->PopulateType(boxedType, BfPopulateType_DataAndMethods);
  2817. useModule->AddDependency(boxedType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_WeakReference);
  2818. }
  2819. else
  2820. {
  2821. boxedType = mModule->mContext->mBfObjectType;
  2822. }
  2823. auto methodRef = boxedType->mVirtualMethodTable[virtualMethodInstance.mMethodInstance->mVirtualTableIdx];
  2824. if (methodRef.mImplementingMethod.mTypeInstance->IsBoxed())
  2825. {
  2826. auto useModule = mModule->mContext->mUnreifiedModule;
  2827. auto boxedMethodInstance = useModule->ReferenceExternalMethodInstance(methodRef.mImplementingMethod);
  2828. BfBoxedType* vBoxedType = (BfBoxedType*)methodRef.mImplementingMethod.mTypeInstance;
  2829. mBestMethodTypeInstance = vBoxedType->mElementType->ToTypeInstance();
  2830. mBestMethodInstance = mModule->GetMethodInstance(mBestMethodTypeInstance, boxedMethodInstance.mMethodInstance->mMethodDef, BfTypeVector());
  2831. mBestMethodDef = mBestMethodInstance.mMethodInstance->mMethodDef;
  2832. }
  2833. else
  2834. {
  2835. mBestMethodTypeInstance = methodRef.mImplementingMethod.mTypeInstance;
  2836. mBestMethodInstance = mModule->ReferenceExternalMethodInstance(methodRef.mImplementingMethod);
  2837. mBestMethodDef = mBestMethodInstance.mMethodInstance->mMethodDef;
  2838. }
  2839. mBypassVirtual = true;
  2840. }
  2841. }
  2842. bool BfMethodMatcher::HasVarGenerics()
  2843. {
  2844. for (auto genericArg : mBestMethodGenericArguments)
  2845. if (genericArg->IsVar())
  2846. return true;
  2847. for (auto genericArg : mExplicitMethodGenericArguments)
  2848. if (genericArg->IsVar())
  2849. return true;
  2850. return false;
  2851. }
  2852. void BfMethodMatcher::CheckOuterTypeStaticMethods(BfTypeInstance* typeInstance, bool isFailurePass)
  2853. {
  2854. bool allowPrivate = true;
  2855. bool allowProtected = true;
  2856. auto curTypeInst = typeInstance;
  2857. auto curTypeDef = typeInstance->mTypeDef;
  2858. while (true)
  2859. {
  2860. curTypeDef->PopulateMemberSets();
  2861. BfMethodDef* nextMethodDef = NULL;
  2862. BfMemberSetEntry* entry;
  2863. if (curTypeDef->mMethodSet.TryGetWith(mMethodName, &entry))
  2864. nextMethodDef = (BfMethodDef*)entry->mMemberDef;
  2865. while (nextMethodDef != NULL)
  2866. {
  2867. auto checkMethod = nextMethodDef;
  2868. nextMethodDef = nextMethodDef->mNextWithSameName;
  2869. // These can only be invoked when the target itself is the interface
  2870. if (checkMethod->mExplicitInterface != NULL)
  2871. continue;
  2872. if ((checkMethod->mMethodType != mMethodType) || (!checkMethod->mIsStatic))
  2873. continue;
  2874. if (checkMethod->mName != mMethodName)
  2875. continue;
  2876. if ((!isFailurePass) && (!mModule->CheckProtection(checkMethod->mProtection, NULL, allowProtected, allowPrivate)))
  2877. continue;
  2878. CheckMethod(typeInstance, curTypeInst, checkMethod, isFailurePass);
  2879. }
  2880. if (mBestMethodDef != NULL)
  2881. return;
  2882. auto baseType = curTypeInst->mBaseType;
  2883. if (baseType == NULL)
  2884. break;
  2885. curTypeDef = baseType->mTypeDef;
  2886. curTypeInst = baseType;
  2887. allowPrivate = false;
  2888. if ((isFailurePass) && (mBackupMethodDef != NULL))
  2889. break;
  2890. }
  2891. if (mBestMethodDef == NULL)
  2892. {
  2893. // FAILED, but select the first method which will fire an actual error on param type matching
  2894. mBestMethodDef = mBackupMethodDef;
  2895. }
  2896. if (mBestMethodDef == NULL)
  2897. {
  2898. // No explicit target - maybe this was a static call in the outer type?
  2899. auto outerType = mModule->GetOuterType(typeInstance);
  2900. if (outerType != NULL)
  2901. CheckOuterTypeStaticMethods(outerType, isFailurePass);
  2902. }
  2903. }
  2904. //////////////////////////////////////////////////////////////////////////
  2905. void BfResolvedArgs::HandleFixits(BfModule* module)
  2906. {
  2907. auto compiler = module->mCompiler;
  2908. if ((!compiler->IsAutocomplete()) || (compiler->mResolvePassData->mResolveType != BfResolveType_GetFixits))
  2909. return;
  2910. SetAndRestoreValue<bool> ignoreErrors(module->mIgnoreErrors, true);
  2911. for (int argIdx = 0; argIdx < (int)mResolvedArgs.size(); argIdx++)
  2912. {
  2913. auto& resolvedArg = mResolvedArgs[argIdx];
  2914. auto expr = BfNodeDynCast<BfExpression>(resolvedArg.mExpression);
  2915. if (expr != NULL)
  2916. {
  2917. module->CreateValueFromExpression(expr, resolvedArg.mExpectedType);
  2918. }
  2919. }
  2920. }
  2921. //////////////////////////////////////////////////////////////////////////
  2922. BfExprEvaluator::BfExprEvaluator(BfModule* module)
  2923. {
  2924. mBfEvalExprFlags = BfEvalExprFlags_None;
  2925. mModule = module;
  2926. mPropDef = NULL;
  2927. mPropSrc = NULL;
  2928. mPropGetMethodFlags = BfGetMethodInstanceFlag_None;
  2929. mPropCheckedKind = BfCheckedKind_NotSet;
  2930. mUsedAsStatement = false;
  2931. mPropDefBypassVirtual = false;
  2932. mExpectingType = NULL;
  2933. mFunctionBindResult = NULL;
  2934. mExplicitCast = false;
  2935. mDeferCallData = NULL;
  2936. mPrefixedAttributeState = NULL;
  2937. mResolveGenericParam = true;
  2938. mNoBind = false;
  2939. mResultLocalVar = NULL;
  2940. mResultFieldInstance = NULL;
  2941. mResultLocalVarField = 0;
  2942. mResultLocalVarFieldCount = 0;
  2943. mResultLocalVarRefNode = NULL;
  2944. mIsVolatileReference = false;
  2945. mIsHeapReference = false;
  2946. mResultIsTempComposite = false;
  2947. mAllowReadOnlyReference = false;
  2948. mInsidePendingNullable = false;
  2949. mReceivingValue = NULL;
  2950. }
  2951. BfExprEvaluator::~BfExprEvaluator()
  2952. {
  2953. }
  2954. BfAutoComplete* BfExprEvaluator::GetAutoComplete()
  2955. {
  2956. if (mModule->mCompiler->mResolvePassData == NULL)
  2957. return NULL;
  2958. if ((mBfEvalExprFlags & BfEvalExprFlags_NoAutoComplete) != 0)
  2959. return NULL;
  2960. // For local methods- only process autocomplete on capture phase
  2961. if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) && (!mModule->mCurMethodState->mClosureState->mCapturing))
  2962. return NULL;
  2963. // if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mMethodDef->mIsLocalMethod))
  2964. // return NULL;
  2965. return mModule->mCompiler->mResolvePassData->mAutoComplete;
  2966. }
  2967. bool BfExprEvaluator::IsComptime()
  2968. {
  2969. return (mModule->mIsComptimeModule) || ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0);
  2970. }
  2971. bool BfExprEvaluator::IsConstEval()
  2972. {
  2973. return ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0);
  2974. }
  2975. bool BfExprEvaluator::IsComptimeEntry()
  2976. {
  2977. if (mModule->mIsComptimeModule)
  2978. return false;
  2979. return ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0);
  2980. }
  2981. void BfExprEvaluator::EnsureResultNotConstant()
  2982. {
  2983. if ((mResult.mValue.IsConst()) && (!mResult.mType->IsValuelessType()))
  2984. {
  2985. auto newTypedValue = mModule->GetDefaultTypedValue(mResult.mType, true, Beefy::BfDefaultValueKind_Addr);
  2986. mModule->mBfIRBuilder->CreateStore(mResult.mValue, newTypedValue.mValue);
  2987. mResult = newTypedValue;
  2988. }
  2989. }
  2990. int BfExprEvaluator::GetStructRetIdx(BfMethodInstance* methodInstance, bool forceStatic)
  2991. {
  2992. if (IsComptime())
  2993. return -1;
  2994. return methodInstance->GetStructRetIdx(forceStatic);
  2995. }
  2996. BfType* BfExprEvaluator::BindGenericType(BfAstNode* node, BfType* bindType)
  2997. {
  2998. if ((mModule->mCurMethodState == NULL) || (mModule->mCurMethodInstance == NULL) || (bindType == NULL))
  2999. return bindType;
  3000. if ((mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mCapturing))
  3001. return bindType;
  3002. if ((mBfEvalExprFlags & BfEvalExprFlags_DeclType) != 0)
  3003. return bindType;
  3004. BF_ASSERT((!mModule->mCurMethodInstance->mIsUnspecializedVariation) || (mModule->mIsComptimeModule));
  3005. auto parser = node->GetSourceData()->ToParserData();
  3006. if (parser == NULL)
  3007. return bindType;
  3008. int64 nodeId = ((int64)parser->mDataId << 32) + node->GetSrcStart();
  3009. auto genericTypeBindings = mModule->mCurMethodState->GetRootMethodState()->mGenericTypeBindings;
  3010. auto methodInstance = mModule->mCurMethodInstance;
  3011. bool isMixinBind = false;
  3012. if (mModule->mCurMethodState->mMixinState != NULL)
  3013. {
  3014. auto mixinMethodInstance = mModule->mCurMethodState->mMixinState->mMixinMethodInstance;
  3015. if (!mixinMethodInstance->mMethodDef->mGenericParams.IsEmpty())
  3016. {
  3017. auto unspecMixinMethodInstance = mModule->GetUnspecializedMethodInstance(mixinMethodInstance, false);
  3018. if (!unspecMixinMethodInstance->mHasBeenProcessed)
  3019. {
  3020. // Make sure the unspecialized method is processed so we can take its bindings
  3021. // Clear mCurMethodState so we don't think we're in a local method
  3022. SetAndRestoreValue<BfMethodState*> prevMethodState_Unspec(mModule->mCurMethodState, NULL);
  3023. if (unspecMixinMethodInstance->mMethodProcessRequest == NULL)
  3024. unspecMixinMethodInstance->mDeclModule->mIncompleteMethodCount++;
  3025. mModule->mContext->ProcessMethod(unspecMixinMethodInstance);
  3026. }
  3027. isMixinBind = true;
  3028. methodInstance = mixinMethodInstance;
  3029. genericTypeBindings = &unspecMixinMethodInstance->mMethodInfoEx->mGenericTypeBindings;
  3030. }
  3031. }
  3032. if ((methodInstance->mIsUnspecialized) && (!methodInstance->mIsUnspecializedVariation))
  3033. {
  3034. if (isMixinBind)
  3035. return bindType;
  3036. if (!bindType->IsGenericParam())
  3037. return bindType;
  3038. if (genericTypeBindings == NULL)
  3039. return bindType;
  3040. (*genericTypeBindings)[nodeId] = bindType;
  3041. return bindType;
  3042. }
  3043. else
  3044. {
  3045. if (genericTypeBindings == NULL)
  3046. return bindType;
  3047. BfType** typePtr = NULL;
  3048. if (genericTypeBindings->TryGetValue(nodeId, &typePtr))
  3049. return *typePtr;
  3050. return bindType;
  3051. }
  3052. }
  3053. BfType * BfExprEvaluator::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags)
  3054. {
  3055. if (mExpectingType != NULL)
  3056. {
  3057. if (auto namedTypeRef = BfNodeDynCastExact<BfNamedTypeReference>(typeRef))
  3058. {
  3059. if (namedTypeRef->ToString() == "ExpectedType")
  3060. {
  3061. return mModule->ResolveTypeResult(typeRef, mExpectingType, populateType, resolveFlags);
  3062. }
  3063. }
  3064. }
  3065. return mModule->ResolveTypeRef(typeRef, populateType, resolveFlags);
  3066. }
  3067. void BfExprEvaluator::ResolveGenericType()
  3068. {
  3069. if (mResult)
  3070. {
  3071. if (mModule->IsUnboundGeneric(mResult.mType))
  3072. mResult.mType = mModule->GetPrimitiveType(BfTypeCode_Var);
  3073. //mResult.mType = mModule->ResolveGenericType(mResult.mType, true);
  3074. }
  3075. }
  3076. void BfExprEvaluator::Evaluate(BfAstNode* astNode, bool propogateNullConditional, bool ignoreNullConditional, bool allowSplat)
  3077. {
  3078. BP_ZONE("BfExprEvaluator::Evaluate");
  3079. // ParenthesizedExpression breaks null conditional chain
  3080. if (astNode->IsExact<BfParenthesizedExpression>())
  3081. propogateNullConditional = false;
  3082. bool scopeWasConditional = false;
  3083. BfPendingNullConditional* pendingNullCond = NULL;
  3084. mInsidePendingNullable = false;
  3085. if (mModule->mCurMethodState != NULL)
  3086. {
  3087. scopeWasConditional = mModule->mCurMethodState->mCurScope->mIsConditional;
  3088. pendingNullCond = mModule->mCurMethodState->mPendingNullConditional;
  3089. if (!propogateNullConditional)
  3090. mModule->mCurMethodState->mPendingNullConditional = NULL;
  3091. if (pendingNullCond != NULL)
  3092. {
  3093. mInsidePendingNullable = true;
  3094. mModule->mCurMethodState->mCurScope->mIsConditional = true;
  3095. }
  3096. }
  3097. astNode->Accept(this);
  3098. GetResult();
  3099. if ((mResultIsTempComposite) && (mResult.IsAddr()))
  3100. mResult.mKind = BfTypedValueKind_TempAddr;
  3101. if ((!allowSplat) && (mResult.IsSplat()))
  3102. mResult = mModule->AggregateSplat(mResult);
  3103. if ((mBfEvalExprFlags & BfEvalExprFlags_AllowIntUnknown) == 0)
  3104. mModule->FixIntUnknown(mResult);
  3105. if (!mModule->mBfIRBuilder->mIgnoreWrites)
  3106. {
  3107. if (mResult.mValue.IsConst())
  3108. {
  3109. auto constant = mModule->mBfIRBuilder->GetConstant(mResult.mValue);
  3110. if (constant->mConstType == BfConstType_TypeOf)
  3111. {
  3112. auto typeOfConst = (BfTypeOf_Const*)constant;
  3113. mResult.mValue = mModule->CreateTypeDataRef(typeOfConst->mType);
  3114. }
  3115. }
  3116. }
  3117. if (mModule->mCurMethodState != NULL)
  3118. {
  3119. if (mInsidePendingNullable)
  3120. mModule->mCurMethodState->mCurScope->mIsConditional = scopeWasConditional;
  3121. if (!propogateNullConditional)
  3122. {
  3123. if (mModule->mCurMethodState->mPendingNullConditional != NULL)
  3124. mResult = mModule->FlushNullConditional(mResult, ignoreNullConditional);
  3125. mModule->mCurMethodState->mPendingNullConditional = pendingNullCond;
  3126. }
  3127. }
  3128. }
  3129. void BfExprEvaluator::Visit(BfErrorNode* errorNode)
  3130. {
  3131. mModule->Fail("Invalid token", errorNode);
  3132. auto autoComplete = GetAutoComplete();
  3133. if (autoComplete != NULL)
  3134. {
  3135. if (auto tokenNode = BfNodeDynCast<BfTokenNode>(errorNode->mRefNode))
  3136. return;
  3137. autoComplete->CheckIdentifier(errorNode->mRefNode, true);
  3138. }
  3139. }
  3140. void BfExprEvaluator::Visit(BfTypeReference* typeRef)
  3141. {
  3142. mResult.mType = ResolveTypeRef(typeRef, BfPopulateType_Declaration);
  3143. }
  3144. void BfExprEvaluator::Visit(BfAttributedExpression* attribExpr)
  3145. {
  3146. BfAttributeState attributeState;
  3147. attributeState.mSrc = attribExpr->mAttributes;
  3148. attributeState.mTarget = (BfAttributeTargets)(BfAttributeTargets_Invocation | BfAttributeTargets_MemberAccess);
  3149. if (auto block = BfNodeDynCast<BfBlock>(attribExpr->mExpression))
  3150. attributeState.mTarget = BfAttributeTargets_Block;
  3151. attributeState.mCustomAttributes = mModule->GetCustomAttributes(attribExpr->mAttributes, attributeState.mTarget);
  3152. SetAndRestoreValue<BfAttributeState*> prevAttributeState(mModule->mAttributeState, &attributeState);
  3153. if (auto ignoreErrorsAttrib = attributeState.mCustomAttributes->Get(mModule->mCompiler->mIgnoreErrorsAttributeTypeDef))
  3154. {
  3155. SetAndRestoreValue<bool> ignoreErrors(mModule->mIgnoreErrors, true);
  3156. if (!ignoreErrorsAttrib->mCtorArgs.IsEmpty())
  3157. {
  3158. auto constant = mModule->mCurTypeInstance->mConstHolder->GetConstant(ignoreErrorsAttrib->mCtorArgs[0]);
  3159. if (constant->mBool)
  3160. attributeState.mFlags = BfAttributeState::Flag_StopOnError;
  3161. }
  3162. VisitChild(attribExpr->mExpression);
  3163. attributeState.mUsed = true;
  3164. if ((!mResult) ||
  3165. ((mResult) && (mResult.mType->IsVar())))
  3166. {
  3167. if (!mResult)
  3168. mModule->Fail("Expression did not result in a value", attribExpr->mExpression);
  3169. // Make empty or 'var' resolve as 'false' because var is only valid if we threw errors
  3170. mResult = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Boolean));
  3171. }
  3172. }
  3173. else if (attributeState.mCustomAttributes->Contains(mModule->mCompiler->mConstSkipAttributeTypeDef))
  3174. {
  3175. if ((mModule->mCurMethodState == NULL) || (mModule->mCurMethodState->mCurScope == NULL) || (!mModule->mCurMethodState->mCurScope->mInConstIgnore))
  3176. {
  3177. VisitChild(attribExpr->mExpression);
  3178. }
  3179. else
  3180. {
  3181. BF_ASSERT(mModule->mBfIRBuilder->mIgnoreWrites);
  3182. mResult = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Var));
  3183. }
  3184. attributeState.mUsed = true;
  3185. }
  3186. else
  3187. {
  3188. VisitChild(attribExpr->mExpression);
  3189. }
  3190. mModule->FinishAttributeState(&attributeState);
  3191. }
  3192. void BfExprEvaluator::Visit(BfNamedExpression* namedExpr)
  3193. {
  3194. if (namedExpr->mExpression != NULL)
  3195. VisitChild(namedExpr->mExpression);
  3196. }
  3197. void BfExprEvaluator::Visit(BfBlock* blockExpr)
  3198. {
  3199. if (mModule->mCurMethodState == NULL)
  3200. {
  3201. mModule->Fail("Illegal use of block expression", blockExpr);
  3202. return;
  3203. }
  3204. auto autoComplete = GetAutoComplete();
  3205. if ((autoComplete != NULL) && (autoComplete->mMethodMatchInfo != NULL) && (autoComplete->IsAutocompleteNode(blockExpr)))
  3206. {
  3207. // Don't show outer method match info when our cursor is inside a block (being passed as a parameter)
  3208. autoComplete->RemoveMethodMatchInfo();
  3209. }
  3210. if (blockExpr->mChildArr.IsEmpty())
  3211. {
  3212. mModule->Fail("An empty block cannot be used as an expression", blockExpr);
  3213. return;
  3214. }
  3215. bool lastWasResultExpr = false;
  3216. if (auto lastExpr = BfNodeDynCast<BfExpressionStatement>(blockExpr->mChildArr.GetLast()))
  3217. {
  3218. if (!lastExpr->IsMissingSemicolon())
  3219. mModule->Fail("Expression blocks must end in an expression which is missing its terminating semicolon", lastExpr->mTrailingSemicolon);
  3220. }
  3221. else if (blockExpr->mChildArr.GetLast()->IsExpression())
  3222. {
  3223. // Expression
  3224. }
  3225. else
  3226. {
  3227. mModule->Fail("Expression blocks must end with an expression", blockExpr);
  3228. }
  3229. mModule->VisitEmbeddedStatement(blockExpr, this, BfNodeIsA<BfUnscopedBlock>(blockExpr) ? BfEmbeddedStatementFlags_Unscoped : BfEmbeddedStatementFlags_None);
  3230. }
  3231. bool BfExprEvaluator::CheckVariableDeclaration(BfAstNode* checkNode, bool requireSimpleIfExpr, bool exprMustBeTrue, bool silentFail)
  3232. {
  3233. if (BfNodeIsA<BfUninitializedExpression>(checkNode))
  3234. return true;
  3235. BfAstNode* checkChild = checkNode;
  3236. bool childWasAndRHS = false;
  3237. bool foundIf = false;
  3238. auto parentNodeEntry = mModule->mParentNodeEntry;
  3239. if (parentNodeEntry != NULL)
  3240. {
  3241. if (BfNodeIsA<BfInvocationExpression>(parentNodeEntry->mNode))
  3242. {
  3243. checkChild = parentNodeEntry->mNode;
  3244. parentNodeEntry = parentNodeEntry->mPrev;
  3245. }
  3246. }
  3247. auto _Fail = [&](const StringImpl& errorStr, BfAstNode* node)
  3248. {
  3249. if (!silentFail)
  3250. {
  3251. auto error = mModule->Fail(errorStr, node);
  3252. if ((error != NULL) && (node != checkNode))
  3253. {
  3254. mModule->mCompiler->mPassInstance->MoreInfo("See variable declaration", checkNode);
  3255. }
  3256. }
  3257. return false;
  3258. };
  3259. while (parentNodeEntry != NULL)
  3260. {
  3261. BfAstNode* checkParent = parentNodeEntry->mNode;
  3262. if (auto binOpExpr = BfNodeDynCastExact<BfBinaryOperatorExpression>(checkParent))
  3263. {
  3264. if (binOpExpr->mOp == BfBinaryOp_ConditionalAnd)
  3265. {
  3266. // This is always okay
  3267. childWasAndRHS = (binOpExpr->mRight != NULL) && (binOpExpr->mRight->Contains(checkChild));
  3268. }
  3269. else if ((binOpExpr->mOp == BfBinaryOp_ConditionalOr) && (!exprMustBeTrue))
  3270. {
  3271. if ((binOpExpr->mRight != NULL) && (binOpExpr->mRight->Contains(checkChild)))
  3272. {
  3273. return _Fail("Conditional short-circuiting may skip variable initialization", binOpExpr->mOpToken);
  3274. }
  3275. }
  3276. else
  3277. {
  3278. if (exprMustBeTrue)
  3279. {
  3280. return _Fail("Operator cannot be used with variable initialization", binOpExpr->mOpToken);
  3281. }
  3282. }
  3283. }
  3284. else if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(checkParent))
  3285. {
  3286. // This is okay
  3287. }
  3288. else if (auto unaryOp = BfNodeDynCast<BfUnaryOperatorExpression>(checkParent))
  3289. {
  3290. if (exprMustBeTrue)
  3291. {
  3292. return _Fail("Operator cannot be used with variable initialization", unaryOp->mOpToken);
  3293. return false;
  3294. }
  3295. if (childWasAndRHS)
  3296. {
  3297. return _Fail("Operator may allow conditional short-circuiting to skip variable initialization", unaryOp->mOpToken);
  3298. }
  3299. }
  3300. else if (auto ifStmt = BfNodeDynCast<BfIfStatement>(checkParent))
  3301. {
  3302. // Done
  3303. foundIf = true;
  3304. break;
  3305. }
  3306. else
  3307. {
  3308. if (requireSimpleIfExpr)
  3309. {
  3310. return _Fail("Variable declaration expression can only be contained in simple 'if' expressions", checkNode);
  3311. }
  3312. break;
  3313. }
  3314. checkChild = parentNodeEntry->mNode;
  3315. parentNodeEntry = parentNodeEntry->mPrev;
  3316. }
  3317. return foundIf;
  3318. }
  3319. bool BfExprEvaluator::HasVariableDeclaration(BfAstNode* checkNode)
  3320. {
  3321. BfVarDeclChecker checker;
  3322. checker.VisitChild(checkNode);
  3323. return checker.mHasVarDecl;
  3324. }
  3325. void BfExprEvaluator::Visit(BfVariableDeclaration* varDecl)
  3326. {
  3327. mModule->UpdateExprSrcPos(varDecl);
  3328. if ((mModule->mCurMethodState == NULL) || (!mModule->mCurMethodState->mCurScope->mAllowVariableDeclarations))
  3329. {
  3330. mModule->Fail("Variable declarations are not allowed in this context", varDecl);
  3331. if (varDecl->mInitializer != NULL)
  3332. {
  3333. VisitChild(varDecl->mInitializer);
  3334. }
  3335. return;
  3336. }
  3337. CheckVariableDeclaration(varDecl, true, false, false);
  3338. if (varDecl->mInitializer == NULL)
  3339. {
  3340. mModule->Fail("Variable declarations used as expressions must have an initializer", varDecl);
  3341. }
  3342. BfTupleExpression* tupleVariableDeclaration = BfNodeDynCast<BfTupleExpression>(varDecl->mNameNode);
  3343. if (tupleVariableDeclaration != NULL)
  3344. {
  3345. mModule->Fail("Tuple variable declarations cannot be used as expressions", varDecl);
  3346. mModule->HandleTupleVariableDeclaration(varDecl);
  3347. }
  3348. else
  3349. mModule->HandleVariableDeclaration(varDecl, this);
  3350. }
  3351. void BfExprEvaluator::DoCaseExpression(BfTypedValue caseValAddr, BfCaseExpression* caseExpr)
  3352. {
  3353. if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mDeferredLocalAssignData != NULL))
  3354. mModule->mCurMethodState->mDeferredLocalAssignData->BreakExtendChain();
  3355. if (auto bindExpr = BfNodeDynCast<BfEnumCaseBindExpression>(caseExpr->mCaseExpression))
  3356. {
  3357. if (caseValAddr)
  3358. {
  3359. BfTypedValue enumTagVal;
  3360. if (caseValAddr.mType->IsPayloadEnum())
  3361. {
  3362. int dscrDataIdx;
  3363. auto dscrType = caseValAddr.mType->ToTypeInstance()->GetDiscriminatorType(&dscrDataIdx);
  3364. enumTagVal = BfTypedValue(mModule->ExtractValue(caseValAddr, dscrDataIdx), dscrType);
  3365. }
  3366. else
  3367. enumTagVal = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Int32));
  3368. mResult = mModule->HandleCaseBind(caseValAddr, enumTagVal, bindExpr);
  3369. return;
  3370. }
  3371. }
  3372. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  3373. bool isPayloadEnum = (caseValAddr.mType != NULL) && (caseValAddr.mType->IsPayloadEnum());
  3374. auto tupleExpr = BfNodeDynCast<BfTupleExpression>(caseExpr->mCaseExpression);
  3375. if ((caseValAddr) &&
  3376. ((isPayloadEnum) || (tupleExpr != NULL)))
  3377. {
  3378. bool hasVariable = false;
  3379. bool hasOut = false;
  3380. bool clearOutOnMismatch = false;
  3381. if (auto invocateExpr = BfNodeDynCast<BfInvocationExpression>(caseExpr->mCaseExpression))
  3382. {
  3383. for (auto arg : invocateExpr->mArguments)
  3384. {
  3385. if (auto varDecl = BfNodeDynCast<BfVariableDeclaration>(arg))
  3386. {
  3387. hasVariable = true;
  3388. }
  3389. else if (auto unaryOpExpr = BfNodeDynCast<BfUnaryOperatorExpression>(arg))
  3390. {
  3391. if ((unaryOpExpr->mOpToken != NULL) && (unaryOpExpr->mOpToken->mToken == BfToken_Out))
  3392. {
  3393. hasOut = true;
  3394. }
  3395. }
  3396. }
  3397. }
  3398. if (hasVariable)
  3399. {
  3400. CheckVariableDeclaration(caseExpr, false, false, false);
  3401. }
  3402. // We can avoid clearing on mismatch if we can be sure we ONLY enter the true block on a match.
  3403. // An example of requiring clearing is: if ((result case .Ok(out val)) || (force))
  3404. if (hasOut)
  3405. clearOutOnMismatch = !CheckVariableDeclaration(caseExpr, true, true, true);
  3406. bool hadConditional = false;
  3407. if (isPayloadEnum)
  3408. {
  3409. int dscrDataIdx;
  3410. auto dscrType = caseValAddr.mType->ToTypeInstance()->GetDiscriminatorType(&dscrDataIdx);
  3411. auto enumTagVal = mModule->LoadValue(mModule->ExtractValue(caseValAddr, NULL, 2));
  3412. int uncondTagId = -1;
  3413. mResult = mModule->TryCaseEnumMatch(caseValAddr, enumTagVal, caseExpr->mCaseExpression, NULL, NULL, NULL, uncondTagId, hadConditional, clearOutOnMismatch, false);
  3414. }
  3415. else
  3416. {
  3417. mResult = mModule->TryCaseTupleMatch(caseValAddr, tupleExpr, NULL, NULL, NULL, hadConditional, clearOutOnMismatch, false);
  3418. }
  3419. if (mResult)
  3420. return;
  3421. }
  3422. if ((caseValAddr) && (IsVar(caseValAddr.mType)))
  3423. {
  3424. auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(caseExpr->mCaseExpression);
  3425. if (invocationExpr != NULL)
  3426. {
  3427. for (auto expr : invocationExpr->mArguments)
  3428. {
  3429. if (expr == NULL)
  3430. continue;
  3431. if (auto varDecl = BfNodeDynCast<BfVariableDeclaration>(expr))
  3432. {
  3433. auto localVar = mModule->HandleVariableDeclaration(varDecl, BfTypedValue());
  3434. if (localVar != NULL)
  3435. localVar->mReadFromId = 0;
  3436. }
  3437. }
  3438. }
  3439. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  3440. mResult = mModule->GetDefaultTypedValue(boolType);
  3441. return;
  3442. }
  3443. BfTypedValue caseMatch;
  3444. if (caseExpr->mCaseExpression != NULL)
  3445. caseMatch = mModule->CreateValueFromExpression(caseExpr->mCaseExpression, caseValAddr.mType, BfEvalExprFlags_AllowEnumId);
  3446. if ((!caseMatch) || (!caseValAddr))
  3447. {
  3448. mResult = mModule->GetDefaultTypedValue(boolType);
  3449. return;
  3450. }
  3451. if (caseValAddr.mType == caseMatch.mType)
  3452. {
  3453. if (((caseValAddr.mType->IsEnum()) && (caseValAddr.mType->IsStruct())) &&
  3454. ((caseMatch) && (caseMatch.mType->IsPayloadEnum()) && (caseMatch.mValue.IsConst())))
  3455. {
  3456. BfTypedValue enumTagVal = mModule->LoadValue(mModule->ExtractValue(caseValAddr, NULL, 2));
  3457. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(enumTagVal.mValue, caseMatch.mValue), boolType);
  3458. return;
  3459. }
  3460. }
  3461. else
  3462. {
  3463. // We need to get rid of the int-const for the 'scalar match'. We get a full payload enum value so we can
  3464. // possibly use it in a user-defined comparison operator
  3465. if ((caseMatch.mType->IsStruct()) && (caseMatch.mValue.IsConst()))
  3466. {
  3467. // Is it possible this could throw an error twice? Hope not.
  3468. caseMatch = mModule->CreateValueFromExpression(caseExpr->mCaseExpression, NULL, (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags));
  3469. }
  3470. }
  3471. PerformBinaryOperation(caseExpr->mCaseExpression, caseExpr->mValueExpression, BfBinaryOp_Equality, caseExpr->mEqualsNode, BfBinOpFlag_None, caseValAddr, caseMatch);
  3472. }
  3473. void BfExprEvaluator::Visit(BfCaseExpression* caseExpr)
  3474. {
  3475. if (caseExpr->mEqualsNode != NULL)
  3476. {
  3477. mModule->Warn(0, "Deprecated case syntax", caseExpr->mEqualsNode);
  3478. }
  3479. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  3480. BfTypedValue caseValAddr;
  3481. if (caseExpr->mValueExpression != NULL)
  3482. caseValAddr = mModule->CreateValueFromExpression(caseExpr->mValueExpression, NULL, (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags));
  3483. if ((caseValAddr.mType != NULL) && (caseValAddr.mType->IsPointer()))
  3484. {
  3485. caseValAddr = mModule->LoadValue(caseValAddr);
  3486. caseValAddr = BfTypedValue(caseValAddr.mValue, caseValAddr.mType->GetUnderlyingType(), true);
  3487. }
  3488. BfIRValue hasValueValue;
  3489. if (caseValAddr.mType != NULL)
  3490. mModule->mBfIRBuilder->PopulateType(caseValAddr.mType);
  3491. if ((caseValAddr.mType != NULL) && (caseValAddr.mType->IsNullable()))
  3492. {
  3493. auto nullableElementType = caseValAddr.mType->GetUnderlyingType();
  3494. hasValueValue = mModule->ExtractValue(caseValAddr, nullableElementType->IsValuelessType() ? 1 : 2);
  3495. if (!nullableElementType->IsValuelessType())
  3496. caseValAddr = BfTypedValue(mModule->ExtractValue(caseValAddr, 1), nullableElementType); // value
  3497. else
  3498. caseValAddr = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), nullableElementType);
  3499. }
  3500. BfIRBlock nullBB;
  3501. BfIRBlock endBB;
  3502. if (hasValueValue)
  3503. {
  3504. auto caseBB = mModule->mBfIRBuilder->CreateBlock("caseexpr.case");
  3505. endBB = mModule->mBfIRBuilder->CreateBlock("caseexpr.end");
  3506. mModule->mBfIRBuilder->CreateCondBr(hasValueValue, caseBB, endBB);
  3507. nullBB = mModule->mBfIRBuilder->GetInsertBlock();
  3508. mModule->mBfIRBuilder->AddBlock(caseBB);
  3509. mModule->mBfIRBuilder->SetInsertPoint(caseBB);
  3510. }
  3511. DoCaseExpression(caseValAddr, caseExpr);
  3512. if (!mResult)
  3513. mResult = mModule->GetDefaultTypedValue(boolType);
  3514. else
  3515. {
  3516. BF_ASSERT(mResult.mType == boolType);
  3517. }
  3518. if (hasValueValue)
  3519. {
  3520. auto endCaseBB = mModule->mBfIRBuilder->GetInsertBlock();
  3521. mModule->mBfIRBuilder->CreateBr(endBB);
  3522. mModule->mBfIRBuilder->AddBlock(endBB);
  3523. mModule->mBfIRBuilder->SetInsertPoint(endBB);
  3524. auto phiValue = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(boolType), 2);
  3525. mModule->mBfIRBuilder->AddPhiIncoming(phiValue, mModule->GetDefaultValue(boolType), nullBB);
  3526. mModule->mBfIRBuilder->AddPhiIncoming(phiValue, mResult.mValue, endCaseBB);
  3527. mResult = BfTypedValue(phiValue, boolType);
  3528. }
  3529. if (caseExpr->mNotToken != NULL)
  3530. mResult.mValue = mModule->mBfIRBuilder->CreateNot(mResult.mValue);
  3531. }
  3532. void BfExprEvaluator::Visit(BfTypedValueExpression* typedValueExpr)
  3533. {
  3534. mResult = typedValueExpr->mTypedValue;
  3535. }
  3536. static bool IsCharType(BfTypeCode typeCode)
  3537. {
  3538. switch (typeCode)
  3539. {
  3540. case BfTypeCode_Char8:
  3541. case BfTypeCode_Char16:
  3542. case BfTypeCode_Char32:
  3543. return true;
  3544. default:
  3545. return false;
  3546. }
  3547. }
  3548. bool BfExprEvaluator::CheckForMethodName(BfAstNode* refNode, BfTypeInstance* typeInst, const StringImpl& findName)
  3549. {
  3550. BF_ASSERT((mBfEvalExprFlags & BfEvalExprFlags_NameOf) != 0);
  3551. auto autoComplete = GetAutoComplete();
  3552. while (typeInst != NULL)
  3553. {
  3554. auto typeDef = typeInst->mTypeDef;
  3555. typeDef->PopulateMemberSets();
  3556. BfMemberSetEntry* memberSetEntry;
  3557. if (typeDef->mMethodSet.TryGetWith(findName, &memberSetEntry))
  3558. {
  3559. if (mModule->mCompiler->mResolvePassData != NULL)
  3560. mModule->mCompiler->mResolvePassData->HandleMethodReference(refNode, typeDef, (BfMethodDef*)memberSetEntry->mMemberDef);
  3561. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(refNode)))
  3562. {
  3563. autoComplete->SetDefinitionLocation(((BfMethodDef*)memberSetEntry->mMemberDef)->GetRefNode());
  3564. if ((autoComplete->mResolveType == BfResolveType_GetSymbolInfo) && (autoComplete->mDefType == NULL))
  3565. {
  3566. autoComplete->mDefType = typeDef;
  3567. autoComplete->mDefMethod = (BfMethodDef*)memberSetEntry->mMemberDef;
  3568. }
  3569. }
  3570. if (mModule->mCompiler->mResolvePassData != NULL)
  3571. {
  3572. if (auto sourceClassifier = mModule->mCompiler->mResolvePassData->GetSourceClassifier(refNode))
  3573. sourceClassifier->SetElementType(refNode, BfSourceElementType_Method);
  3574. }
  3575. mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_NameOfSuccess);
  3576. return true;
  3577. }
  3578. typeInst = typeInst->mBaseType;
  3579. }
  3580. return false;
  3581. }
  3582. bool BfExprEvaluator::IsVar(BfType* type, bool forceIgnoreWrites)
  3583. {
  3584. if (type->IsVar())
  3585. return true;
  3586. if ((type->IsGenericParam()) && (!forceIgnoreWrites) && (!mModule->mBfIRBuilder->mIgnoreWrites))
  3587. {
  3588. BF_ASSERT(mModule->mIsComptimeModule);
  3589. return true;
  3590. }
  3591. return false;
  3592. }
  3593. void BfExprEvaluator::GetLiteral(BfAstNode* refNode, const BfVariant& variant, BfType* type)
  3594. {
  3595. switch (variant.mTypeCode)
  3596. {
  3597. case BfTypeCode_NullPtr:
  3598. {
  3599. auto nullType = mModule->ResolveTypeDef(mModule->mSystem->mTypeNullPtr);
  3600. /*mResult = BfTypedValue(ConstantPointerNull::get((PointerType*) nullType->mIRType), nullType);*/
  3601. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConstNull(), nullType);
  3602. }
  3603. break;
  3604. case BfTypeCode_CharPtr:
  3605. {
  3606. if ((mExpectingType != NULL) && (mExpectingType->IsSizedArray()))
  3607. {
  3608. auto sizedArray = (BfSizedArrayType*)mExpectingType;
  3609. if (sizedArray->mElementType == mModule->GetPrimitiveType(BfTypeCode_Char8))
  3610. {
  3611. if (sizedArray->IsUndefSizedArray())
  3612. sizedArray = mModule->CreateSizedArrayType(sizedArray->mElementType, variant.mString->GetLength());
  3613. if (variant.mString->GetLength() > sizedArray->mElementCount)
  3614. {
  3615. mModule->Fail(StrFormat("String literal is too long to fit into '%s'", mModule->TypeToString(sizedArray).c_str()), refNode);
  3616. }
  3617. Array<BfIRValue> charValues;
  3618. for (int i = 0; i < (int)BF_MIN(variant.mString->GetLength(), sizedArray->mElementCount); i++)
  3619. {
  3620. char c = (*variant.mString)[i];
  3621. charValues.Add(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Char8, (int)(uint8)c));
  3622. }
  3623. if (sizedArray->mElementCount > charValues.size())
  3624. charValues.Add(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Char8, 0));
  3625. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(sizedArray), charValues), sizedArray);
  3626. return;
  3627. }
  3628. }
  3629. if ((mExpectingType == NULL) || (!mExpectingType->IsPointer()))
  3630. {
  3631. mResult = BfTypedValue(mModule->GetStringObjectValue(*variant.mString),
  3632. mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
  3633. }
  3634. else
  3635. {
  3636. auto charType = mModule->GetPrimitiveType(BfTypeCode_Char8);
  3637. auto charPtrType = mModule->CreatePointerType(charType);
  3638. mResult = BfTypedValue(mModule->GetStringCharPtr(*variant.mString),
  3639. charPtrType);
  3640. }
  3641. }
  3642. break;
  3643. case BfTypeCode_Boolean:
  3644. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(variant.mTypeCode, variant.mUInt64), mModule->GetPrimitiveType(variant.mTypeCode));
  3645. break;
  3646. case BfTypeCode_Char8:
  3647. case BfTypeCode_Char16:
  3648. case BfTypeCode_Char32:
  3649. case BfTypeCode_Int8:
  3650. case BfTypeCode_UInt8:
  3651. case BfTypeCode_Int16:
  3652. case BfTypeCode_UInt16:
  3653. case BfTypeCode_Int32:
  3654. case BfTypeCode_UInt32:
  3655. case BfTypeCode_Int64:
  3656. case BfTypeCode_UInt64:
  3657. case BfTypeCode_IntPtr:
  3658. case BfTypeCode_UIntPtr:
  3659. case BfTypeCode_IntUnknown:
  3660. case BfTypeCode_UIntUnknown:
  3661. if ((mExpectingType != NULL) && (mExpectingType->IsIntegral()) && (mExpectingType->IsChar() == IsCharType(variant.mTypeCode)))
  3662. {
  3663. auto primType = (BfPrimitiveType*)mExpectingType;
  3664. if (mModule->mSystem->DoesLiteralFit(primType->mTypeDef->mTypeCode, variant.mUInt64))
  3665. {
  3666. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, variant.mUInt64), mExpectingType);
  3667. break;
  3668. }
  3669. }
  3670. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(variant.mTypeCode, variant.mUInt64), mModule->GetPrimitiveType(variant.mTypeCode));
  3671. break;
  3672. case BfTypeCode_Float:
  3673. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(variant.mTypeCode, variant.mSingle), mModule->GetPrimitiveType(variant.mTypeCode));
  3674. break;
  3675. case BfTypeCode_Double:
  3676. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(variant.mTypeCode, variant.mDouble), mModule->GetPrimitiveType(variant.mTypeCode));
  3677. break;
  3678. case BfTypeCode_StringId:
  3679. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(variant.mTypeCode, variant.mUInt64), mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
  3680. break;
  3681. case BfTypeCode_Let:
  3682. if (mExpectingType != NULL)
  3683. {
  3684. mResult = BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->MapType(mExpectingType)), mExpectingType);
  3685. break;
  3686. }
  3687. mModule->Fail("Invalid undef literal", refNode);
  3688. break;
  3689. case BfTypeCode_Struct:
  3690. if (type != NULL)
  3691. {
  3692. BfVariant::StructData* structData = (BfVariant::StructData*)variant.mPtr;
  3693. mResult = BfTypedValue(mModule->mBfIRBuilder->ReadConstant(structData->mData, type), type);
  3694. }
  3695. break;
  3696. default:
  3697. mModule->Fail("Invalid literal", refNode);
  3698. break;
  3699. }
  3700. }
  3701. void BfExprEvaluator::Visit(BfLiteralExpression* literalExpr)
  3702. {
  3703. switch (literalExpr->mValue.mWarnType)
  3704. {
  3705. case BfWarning_BF4201_Only7Hex:
  3706. mModule->Warn(BfWarning_BF4201_Only7Hex, "Only 7 hex digits specified. Add a leading zero to clarify intention.", literalExpr);
  3707. break;
  3708. case BfWarning_BF4202_TooManyHexForInt:
  3709. 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);
  3710. break;
  3711. }
  3712. GetLiteral(literalExpr, literalExpr->mValue);
  3713. }
  3714. void BfExprEvaluator::Visit(BfStringInterpolationExpression* stringInterpolationExpression)
  3715. {
  3716. if ((mBfEvalExprFlags & BfEvalExprFlags_StringInterpolateFormat) != 0)
  3717. {
  3718. BfVariant variant;
  3719. variant.mTypeCode = BfTypeCode_CharPtr;
  3720. variant.mString = stringInterpolationExpression->mString;
  3721. GetLiteral(stringInterpolationExpression, variant);
  3722. return;
  3723. }
  3724. //
  3725. {
  3726. SetAndRestoreValue<BfEvalExprFlags> prevEvalExprFlag(mBfEvalExprFlags);
  3727. if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) && (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mConstEvalAttributeTypeDef)))
  3728. {
  3729. mModule->mAttributeState->mUsed = true;
  3730. mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_Comptime);
  3731. }
  3732. if (IsConstEval())
  3733. {
  3734. auto stringType = mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef);
  3735. if (stringType != NULL)
  3736. {
  3737. SetAndRestoreValue<bool> prevUsedAsStatement(mUsedAsStatement, true);
  3738. SizedArray<BfExpression*, 2> argExprs;
  3739. argExprs.Add(stringInterpolationExpression);
  3740. BfSizedArray<BfExpression*> sizedArgExprs(argExprs);
  3741. BfResolvedArgs argValues(&sizedArgExprs);
  3742. ResolveArgValues(argValues, BfResolveArgsFlag_InsideStringInterpolationAlloc);
  3743. auto result = MatchMethod(stringInterpolationExpression, NULL, BfTypedValue(stringType), false, false, "ConstF", argValues, BfMethodGenericArguments());
  3744. if (result.mType == stringType)
  3745. {
  3746. mResult = result;
  3747. return;
  3748. }
  3749. }
  3750. mModule->Fail("Const evaluation of string interpolation not allowed", stringInterpolationExpression);
  3751. }
  3752. }
  3753. if (stringInterpolationExpression->mAllocNode != NULL)
  3754. {
  3755. auto stringType = mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef)->ToTypeInstance();
  3756. BfTokenNode* newToken = NULL;
  3757. BfAllocTarget allocTarget;
  3758. ResolveAllocTarget(allocTarget, stringInterpolationExpression->mAllocNode, newToken);
  3759. //
  3760. {
  3761. SetAndRestoreValue<BfEvalExprFlags> prevFlags(mBfEvalExprFlags, (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_NoAutoComplete));
  3762. CreateObject(NULL, stringInterpolationExpression->mAllocNode, stringType, NULL);
  3763. }
  3764. BfTypedValue newString = mResult;
  3765. BF_ASSERT(newString);
  3766. SetAndRestoreValue<bool> prevUsedAsStatement(mUsedAsStatement, true);
  3767. SizedArray<BfExpression*, 2> argExprs;
  3768. argExprs.Add(stringInterpolationExpression);
  3769. BfSizedArray<BfExpression*> sizedArgExprs(argExprs);
  3770. BfResolvedArgs argValues(&sizedArgExprs);
  3771. ResolveArgValues(argValues, BfResolveArgsFlag_InsideStringInterpolationAlloc);
  3772. MatchMethod(stringInterpolationExpression, NULL, newString, false, false, "AppendF", argValues, BfMethodGenericArguments());
  3773. mResult = newString;
  3774. return;
  3775. }
  3776. mModule->Fail("Invalid use of string interpolation expression. Consider adding an allocation specifier such as 'scope'.", stringInterpolationExpression);
  3777. for (auto block : stringInterpolationExpression->mExpressions)
  3778. {
  3779. VisitChild(block);
  3780. }
  3781. }
  3782. BfTypedValue BfExprEvaluator::LoadLocal(BfLocalVariable* varDecl, bool allowRef)
  3783. {
  3784. if (!mModule->mIsInsideAutoComplete)
  3785. varDecl->mReadFromId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++;
  3786. // The Beef backend prefers readonly addrs since that reduces register pressure, whereas
  3787. // LLVM prefers values to avoid memory loads. This only applies to primitive types...
  3788. bool preferValue = (varDecl->mResolvedType->IsPrimitiveType()) && (!mModule->IsTargetingBeefBackend());
  3789. BfTypedValue localResult;
  3790. if (varDecl->mIsThis)
  3791. {
  3792. return mModule->GetThis();
  3793. }
  3794. else if (varDecl->mConstValue)
  3795. {
  3796. localResult = BfTypedValue(varDecl->mConstValue, varDecl->mResolvedType, false);
  3797. }
  3798. else if (varDecl->mIsSplat)
  3799. {
  3800. if (!varDecl->mResolvedType->IsValuelessType())
  3801. localResult = BfTypedValue(varDecl->mValue, varDecl->mResolvedType, BfTypedValueKind_SplatHead);
  3802. else if ((varDecl->mResolvedType->IsRef()) && (!allowRef))
  3803. {
  3804. BF_ASSERT(varDecl->mResolvedType->IsValuelessType());
  3805. localResult = BfTypedValue(varDecl->mValue, varDecl->mResolvedType->GetUnderlyingType());
  3806. }
  3807. else
  3808. localResult = BfTypedValue(varDecl->mValue, varDecl->mResolvedType);
  3809. //BF_ASSERT(varDecl->mValue.IsArg());
  3810. }
  3811. else if ((varDecl->mValue) && ((varDecl->mIsReadOnly && preferValue) || (!varDecl->mAddr)))
  3812. {
  3813. if ((varDecl->mResolvedType->IsRef()) && (!allowRef))
  3814. {
  3815. BfRefType* refType = (BfRefType*)varDecl->mResolvedType;
  3816. BfType* innerType = refType->mElementType;
  3817. if (innerType->IsGenericParam())
  3818. {
  3819. if (refType->mRefKind == BfRefType::RefKind_Mut)
  3820. {
  3821. localResult = BfTypedValue(varDecl->mValue, innerType, BfTypedValueKind_MutableValue);
  3822. return localResult;
  3823. }
  3824. else
  3825. {
  3826. localResult = BfTypedValue(varDecl->mValue, innerType, BfTypedValueKind_Addr);
  3827. return localResult;
  3828. }
  3829. }
  3830. localResult = BfTypedValue(varDecl->mValue, innerType, varDecl->mIsReadOnly ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
  3831. }
  3832. else
  3833. {
  3834. BfTypedValueKind kind;
  3835. if ((varDecl->mResolvedType->IsComposite()) && (varDecl->mValue.IsArg()))
  3836. {
  3837. kind = varDecl->mIsReadOnly ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr;
  3838. }
  3839. else
  3840. kind = BfTypedValueKind_Value;
  3841. localResult = BfTypedValue(varDecl->mValue, varDecl->mResolvedType, kind);
  3842. }
  3843. }
  3844. else if (varDecl->mAddr)
  3845. {
  3846. if ((!mModule->mBfIRBuilder->mIgnoreWrites) && (varDecl->mAddr.IsFake()) && (!varDecl->mResolvedType->IsValuelessType()))
  3847. {
  3848. // In an ignore case match we can may need to create a fake "out" when someone tries to read it
  3849. auto defaultTypedValue = mModule->GetDefaultTypedValue(varDecl->mResolvedType, true, BfDefaultValueKind_Addr);
  3850. varDecl->mAddr = defaultTypedValue.mValue;
  3851. }
  3852. if ((varDecl->mResolvedType->IsRef()) && (!allowRef))
  3853. {
  3854. BfRefType* refType = (BfRefType*)varDecl->mResolvedType;
  3855. BfType* innerType = refType->mElementType;
  3856. if (innerType->IsValuelessNonOpaqueType())
  3857. {
  3858. if (refType->mRefKind == BfRefType::RefKind_Mut)
  3859. return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), innerType, BfTypedValueKind_MutableValue);
  3860. return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), innerType, varDecl->mIsReadOnly ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
  3861. }
  3862. if (refType->mRefKind == BfRefType::RefKind_Mut)
  3863. {
  3864. if (innerType->IsGenericParam())
  3865. {
  3866. localResult = BfTypedValue(mModule->mBfIRBuilder->CreateAlignedLoad(varDecl->mAddr, varDecl->mResolvedType->mAlign), innerType, BfTypedValueKind_MutableValue);
  3867. return localResult;
  3868. }
  3869. }
  3870. localResult = BfTypedValue(mModule->mBfIRBuilder->CreateAlignedLoad(varDecl->mAddr, varDecl->mResolvedType->mAlign), innerType, varDecl->mIsReadOnly ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
  3871. }
  3872. else if (varDecl->mHasLocalStructBacking)
  3873. {
  3874. // varDecl->mAddr is a "struct**"
  3875. localResult = BfTypedValue(mModule->mBfIRBuilder->CreateAlignedLoad(varDecl->mAddr, varDecl->mResolvedType->mAlign), varDecl->mResolvedType, varDecl->mIsReadOnly ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
  3876. }
  3877. else
  3878. localResult = BfTypedValue(varDecl->mAddr, varDecl->mResolvedType, varDecl->mIsReadOnly ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
  3879. }
  3880. else if ((varDecl->mResolvedType->IsModifiedTypeType()) && (((BfModifiedTypeType*)varDecl->mResolvedType)->mModifiedKind == BfToken_Params))
  3881. {
  3882. localResult = BfTypedValue(BfIRValue(), varDecl->mResolvedType);
  3883. }
  3884. else if (varDecl->mResolvedType->IsValuelessNonOpaqueType())
  3885. {
  3886. if ((varDecl->mResolvedType->IsRef()) && (!allowRef))
  3887. {
  3888. BfRefType* refType = (BfRefType*)varDecl->mResolvedType;
  3889. BfType* innerType = refType->mElementType;
  3890. localResult = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), innerType, true);
  3891. return localResult;
  3892. }
  3893. localResult = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), varDecl->mResolvedType, true);
  3894. }
  3895. else if (varDecl->mCompositeCount >= 0)
  3896. {
  3897. if ((mBfEvalExprFlags & BfEvalExprFlags_InParamsExpr) != 0)
  3898. {
  3899. localResult = BfTypedValue(BfIRValue(), mModule->GetPrimitiveType(BfTypeCode_None));
  3900. }
  3901. else if (!varDecl->mAddr)
  3902. {
  3903. bool isValid = true;
  3904. Array<BfTypedValue> argVals;
  3905. auto methodState = mModule->mCurMethodState->GetMethodStateForLocal(varDecl);
  3906. for (int compositeIdx = 0; compositeIdx < varDecl->mCompositeCount; compositeIdx++)
  3907. {
  3908. BfResolvedArg compositeResolvedArg;
  3909. auto compositeLocalVar = methodState->mLocals[varDecl->mLocalVarIdx + compositeIdx + 1];
  3910. auto argValue = LoadLocal(compositeLocalVar, true);
  3911. if (argValue)
  3912. {
  3913. if (!argValue.mType->IsStruct())
  3914. argValue = mModule->LoadValue(argValue, NULL, mIsVolatileReference);
  3915. argVals.Add(argValue);
  3916. }
  3917. else
  3918. isValid = false;
  3919. }
  3920. if (isValid)
  3921. {
  3922. BfTypeInstance* tupleType = NULL;
  3923. if (varDecl->mResolvedType->IsTuple())
  3924. tupleType = (BfTupleType*)varDecl->mResolvedType;
  3925. else if ((varDecl->mResolvedType->IsDelegateOrFunction()))
  3926. {
  3927. auto invokeFunction = mModule->GetDelegateInvokeMethod(varDecl->mResolvedType->ToTypeInstance());
  3928. if (invokeFunction != NULL)
  3929. {
  3930. BfTypeVector fieldTypes;
  3931. SubstituteList fieldNames;
  3932. for (int paramIdx = 0; paramIdx < invokeFunction->GetParamCount(); paramIdx++)
  3933. {
  3934. fieldNames.Add(invokeFunction->GetParamName(paramIdx));
  3935. fieldTypes.Add(invokeFunction->GetParamType(paramIdx));
  3936. }
  3937. tupleType = mModule->CreateTupleType(fieldTypes, fieldNames);
  3938. }
  3939. }
  3940. if (tupleType == NULL)
  3941. {
  3942. isValid = false;
  3943. }
  3944. else if (tupleType->IsValuelessType())
  3945. {
  3946. localResult = mModule->GetDefaultTypedValue(tupleType);
  3947. }
  3948. else
  3949. {
  3950. BF_ASSERT(tupleType->mFieldInstances.mSize == argVals.mSize);
  3951. auto instAlloca = mModule->CreateAlloca(tupleType);
  3952. for (int i = 0; i < argVals.mSize; i++)
  3953. {
  3954. auto& fieldInstance = tupleType->mFieldInstances[i];
  3955. if (fieldInstance.mDataIdx >= 0)
  3956. {
  3957. auto val = mModule->Cast(varDecl->mNameNode, argVals[i], fieldInstance.mResolvedType);
  3958. if (val)
  3959. {
  3960. val = mModule->LoadOrAggregateValue(val);
  3961. if (!val.mType->IsValuelessType())
  3962. {
  3963. auto elemPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(instAlloca, 0, fieldInstance.mDataIdx);
  3964. mModule->mBfIRBuilder->CreateStore(val.mValue, elemPtr);
  3965. }
  3966. }
  3967. }
  3968. }
  3969. varDecl->mResolvedType = tupleType;
  3970. varDecl->mAddr = instAlloca;
  3971. varDecl->mIsReadOnly = true;
  3972. localResult = BfTypedValue(varDecl->mAddr, varDecl->mResolvedType, BfTypedValueKind_ReadOnlyAddr);
  3973. }
  3974. }
  3975. if (!isValid)
  3976. {
  3977. localResult = mModule->GetDefaultTypedValue(mModule->ResolveTypeDef(mModule->mCompiler->mTupleTypeDef));
  3978. }
  3979. }
  3980. }
  3981. else
  3982. {
  3983. BF_ASSERT((mModule->mCurMethodState->mClosureState != NULL) || (mModule->mBfIRBuilder->mIgnoreWrites));
  3984. // Just temporary
  3985. auto varType = varDecl->mResolvedType;
  3986. auto allocType = varType;
  3987. if (varType->IsRef())
  3988. {
  3989. BfRefType* refType = (BfRefType*)varType;
  3990. allocType = refType->mElementType;
  3991. }
  3992. auto declType = varDecl->mResolvedType;
  3993. if (declType->IsRef())
  3994. {
  3995. BfRefType* refType = (BfRefType*)declType;
  3996. declType = refType->mElementType;
  3997. }
  3998. mModule->PopulateType(allocType);
  3999. varDecl->mAddr = mModule->mBfIRBuilder->CreateAlloca(mModule->mBfIRBuilder->MapType(allocType));
  4000. localResult = BfTypedValue(varDecl->mAddr, declType, true);
  4001. return localResult;
  4002. }
  4003. if ((varDecl->mIsThis) && (localResult.mKind == BfTypedValueKind_Value))
  4004. localResult.mKind = BfTypedValueKind_ThisValue;
  4005. return localResult;
  4006. }
  4007. BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringImpl& findName, bool ignoreInitialError, bool* hadError)
  4008. {
  4009. int varSkipCount = 0;
  4010. StringT<128> wantName;
  4011. wantName.Reference(findName);
  4012. if (findName.StartsWith('@'))
  4013. {
  4014. wantName = findName;
  4015. while (wantName.StartsWith("@"))
  4016. {
  4017. if (wantName != "@return")
  4018. varSkipCount++;
  4019. wantName.Remove(0);
  4020. }
  4021. }
  4022. if (wantName.IsEmpty())
  4023. {
  4024. mModule->Fail("Shadowed variable name expected after '@'", refNode);
  4025. }
  4026. if ((mModule->mCompiler->mCeMachine != NULL) && (mModule->mCompiler->mCeMachine->mDebugger != NULL) && (mModule->mCompiler->mCeMachine->mDebugger->mCurDbgState != NULL))
  4027. {
  4028. auto ceDebugger = mModule->mCompiler->mCeMachine->mDebugger;
  4029. auto ceContext = ceDebugger->mCurDbgState->mCeContext;
  4030. auto activeFrame = ceDebugger->mCurDbgState->mActiveFrame;
  4031. if (activeFrame->mFunction->mDbgInfo != NULL)
  4032. {
  4033. int varSkipCountLeft = varSkipCount;
  4034. int instIdx = activeFrame->GetInstIdx();
  4035. for (int i = activeFrame->mFunction->mDbgInfo->mVariables.mSize - 1; i >= 0; i--)
  4036. {
  4037. auto& dbgVar = activeFrame->mFunction->mDbgInfo->mVariables[i];
  4038. if (dbgVar.mName == wantName)
  4039. {
  4040. if (varSkipCountLeft > 0)
  4041. {
  4042. varSkipCountLeft--;
  4043. }
  4044. else if ((dbgVar.mValue.mKind == CeOperandKind_AllocaAddr) || (dbgVar.mValue.mKind == CeOperandKind_FrameOfs))
  4045. {
  4046. if ((instIdx >= dbgVar.mStartCodePos) && (instIdx < dbgVar.mEndCodePos))
  4047. {
  4048. return BfTypedValue(mModule->mBfIRBuilder->CreateConstAggCE(mModule->mBfIRBuilder->MapType(dbgVar.mType), activeFrame->mFrameAddr + dbgVar.mValue.mFrameOfs),
  4049. dbgVar.mType, dbgVar.mIsConst ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
  4050. }
  4051. }
  4052. }
  4053. }
  4054. }
  4055. if (findName == "FR")
  4056. {
  4057. auto ptrType = mModule->CreatePointerType(mModule->GetPrimitiveType(BfTypeCode_UInt8));
  4058. auto intVal = mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, activeFrame->mFrameAddr);
  4059. auto ptrVal = mModule->mBfIRBuilder->CreateIntToPtr(intVal, mModule->mBfIRBuilder->MapType(ptrType));
  4060. return BfTypedValue(ptrVal, ptrType);
  4061. }
  4062. }
  4063. auto identifierNode = BfNodeDynCast<BfIdentifierNode>(refNode);
  4064. if (mModule->mCurMethodState != NULL)
  4065. {
  4066. auto rootMethodState = mModule->mCurMethodState->GetRootMethodState();
  4067. auto checkMethodState = mModule->mCurMethodState;
  4068. bool isMixinOuterVariablePass = false;
  4069. while (checkMethodState != NULL)
  4070. {
  4071. BP_ZONE("LookupIdentifier:LocalVar");
  4072. BfTypeInstance* closureTypeInst = NULL;
  4073. if ((checkMethodState->mClosureState != NULL) && (checkMethodState->mClosureState->mClosureType != NULL) && (!checkMethodState->mClosureState->mCapturing))
  4074. {
  4075. closureTypeInst = mModule->mCurMethodState->mClosureState->mClosureType;
  4076. }
  4077. int varSkipCountLeft = varSkipCount;
  4078. BfLocalVarEntry* entry;
  4079. if (checkMethodState->mLocalVarSet.TryGetWith<StringImpl&>(wantName, &entry))
  4080. {
  4081. auto varDecl = entry->mLocalVar;
  4082. if (varDecl != NULL)
  4083. varSkipCountLeft -= varDecl->mNamePrefixCount;
  4084. while ((varSkipCountLeft > 0) && (varDecl != NULL))
  4085. {
  4086. varDecl = varDecl->mShadowedLocal;
  4087. varSkipCountLeft--;
  4088. }
  4089. if ((varDecl != NULL) && (varDecl->mNotCaptured))
  4090. {
  4091. mModule->Fail("Local variable is not captured", refNode);
  4092. }
  4093. if ((varSkipCountLeft == 0) && (varDecl != NULL))
  4094. {
  4095. if ((closureTypeInst != NULL) && (wantName == "this"))
  4096. break;
  4097. if (varDecl->mResolvedType->IsVoid())
  4098. {
  4099. if ((varDecl->mIsReadOnly) && (varDecl->mParamIdx == -2) && (varDecl->mParamFailed))
  4100. {
  4101. BF_ASSERT(mModule->mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_CtorCalcAppend);
  4102. 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);
  4103. }
  4104. }
  4105. if (!varDecl->mIsThis)
  4106. mModule->SetElementType(identifierNode, (varDecl->IsParam()) ? BfSourceElementType_Parameter : BfSourceElementType_Local);
  4107. BfTypedValue localResult = LoadLocal(varDecl);
  4108. if ((localResult) && (localResult.mType->IsParamsType()) && ((mBfEvalExprFlags & BfEvalExprFlags_AllowParamsExpr) == 0))
  4109. {
  4110. localResult = mModule->LoadOrAggregateValue(localResult);
  4111. }
  4112. auto autoComplete = GetAutoComplete();
  4113. if (identifierNode != NULL)
  4114. {
  4115. if (autoComplete != NULL)
  4116. autoComplete->CheckLocalRef(identifierNode, varDecl);
  4117. if (((mModule->mCurMethodState->mClosureState == NULL) || (mModule->mCurMethodState->mClosureState->mCapturing)) &&
  4118. (mModule->mCompiler->mResolvePassData != NULL) && (mModule->mCurMethodInstance != NULL) && (!mModule->mCurMethodState->IsTemporary()))
  4119. mModule->mCompiler->mResolvePassData->HandleLocalReference(identifierNode, varDecl->mNameNode, mModule->mCurTypeInstance->mTypeDef, rootMethodState->mMethodInstance->mMethodDef, varDecl->mLocalVarId);
  4120. }
  4121. if (!isMixinOuterVariablePass)
  4122. {
  4123. mResultLocalVar = varDecl;
  4124. mResultFieldInstance = NULL;
  4125. mResultLocalVarRefNode = identifierNode;
  4126. }
  4127. return localResult;
  4128. }
  4129. }
  4130. // Check for the captured locals. It's important we do it here so we get local-first precedence still
  4131. if (closureTypeInst != NULL)
  4132. {
  4133. int varSkipCountLeft = varSkipCount;
  4134. closureTypeInst->mTypeDef->PopulateMemberSets();
  4135. BfMemberSetEntry* memberSetEntry = NULL;
  4136. if (closureTypeInst->mTypeDef->mFieldSet.TryGetWith((StringImpl&)findName, &memberSetEntry))
  4137. {
  4138. auto fieldDef = (BfFieldDef*)memberSetEntry->mMemberDef;
  4139. auto& field = closureTypeInst->mFieldInstances[fieldDef->mIdx];
  4140. if (!field.mResolvedType->IsValuelessType())
  4141. {
  4142. if (mModule->mCurMethodState->mClosureState->mCapturing)
  4143. {
  4144. mModule->mCurMethodState->mClosureState->mReferencedOuterClosureMembers.Add(&field);
  4145. return mModule->GetDefaultTypedValue(field.mResolvedType);
  4146. }
  4147. auto localVar = mModule->mCurMethodState->mLocals[0];
  4148. auto thisValue = localVar->mValue;
  4149. mModule->mBfIRBuilder->PopulateType(localVar->mResolvedType);
  4150. BfTypedValue result = BfTypedValue(mModule->mBfIRBuilder->CreateInBoundsGEP(thisValue, 0, field.mDataIdx), field.mResolvedType, true);
  4151. if (field.mResolvedType->IsRef())
  4152. {
  4153. auto refType = (BfRefType*)field.mResolvedType;
  4154. auto underlyingType = refType->GetUnderlyingType();
  4155. result = BfTypedValue(mModule->mBfIRBuilder->CreateLoad(result.mValue), underlyingType, true);
  4156. }
  4157. else if (fieldDef->mIsReadOnly)
  4158. result = mModule->LoadValue(result);
  4159. //mModule->SetElementType(identifierNode, (localVar->IsParam()) ? BfSourceElementType_Parameter : BfSourceElementType_Local);
  4160. mResultLocalVar = localVar;
  4161. mResultFieldInstance = &field;
  4162. mResultLocalVarField = -(field.mMergedDataIdx + 1);
  4163. return result;
  4164. }
  4165. }
  4166. }
  4167. if ((checkMethodState->mClosureState != NULL) && (checkMethodState->mClosureState->mCapturing) /*&& (checkMethodState->mClosureState->mIsLocalMethod)*/)
  4168. {
  4169. checkMethodState = checkMethodState->mPrevMethodState;
  4170. continue;
  4171. }
  4172. // Allow local mixin to see outside variables during its processing -- since we don't actually "capture" those into params
  4173. bool isLocalMixinProcessing = false;
  4174. if ((checkMethodState->mClosureState != NULL) && (!checkMethodState->mClosureState->mCapturing) && (closureTypeInst == NULL) &&
  4175. (mModule->mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_Mixin))
  4176. isLocalMixinProcessing = true;
  4177. if (!isLocalMixinProcessing)
  4178. break;
  4179. isMixinOuterVariablePass = true;
  4180. checkMethodState = checkMethodState->mPrevMethodState;
  4181. }
  4182. }
  4183. if ((mModule->mCurMethodInstance == NULL) && (mModule->mCurTypeInstance != NULL) && (mModule->mCurTypeInstance->IsEnum()))
  4184. {
  4185. if (findName == "_")
  4186. {
  4187. BfFieldDef* resolvingFieldDef = NULL;
  4188. auto checkTypeState = mModule->mContext->mCurTypeState;
  4189. while (checkTypeState != NULL)
  4190. {
  4191. if (checkTypeState->mCurFieldDef != NULL)
  4192. {
  4193. if (checkTypeState->mType == mModule->mCurTypeInstance)
  4194. resolvingFieldDef = checkTypeState->mCurFieldDef;
  4195. }
  4196. checkTypeState = checkTypeState->mPrevState;
  4197. }
  4198. if ((resolvingFieldDef != NULL) &&
  4199. (mModule->mCompiler->mResolvePassData != NULL) &&
  4200. (!mModule->mCompiler->mResolvePassData->mParsers.IsEmpty()) &&
  4201. (mModule->mCompiler->mResolvePassData->mParsers[0] == resolvingFieldDef->mFieldDeclaration->GetParser()) &&
  4202. (GetAutoComplete() != NULL))
  4203. {
  4204. return mModule->GetDefaultTypedValue(mModule->mCurTypeInstance);
  4205. }
  4206. else if ((resolvingFieldDef != NULL) && (resolvingFieldDef->mIdx > 0))
  4207. {
  4208. auto enumType = mModule->mCurTypeInstance;
  4209. if (!enumType->mFieldInstances.IsEmpty())
  4210. {
  4211. auto fieldInstance = &mModule->mCurTypeInstance->mFieldInstances[resolvingFieldDef->mIdx - 1];
  4212. if ((fieldInstance->mConstIdx != -1) &&
  4213. (fieldInstance->mResolvedType == mModule->mCurTypeInstance))
  4214. {
  4215. auto foreignConst = enumType->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
  4216. auto retVal = mModule->ConstantToCurrent(foreignConst, enumType->mConstHolder, enumType);
  4217. return BfTypedValue(retVal, enumType);
  4218. }
  4219. }
  4220. }
  4221. }
  4222. }
  4223. BfTypedValue thisValue = mModule->GetThis(false);
  4224. bool forcedIFaceLookup = false;
  4225. if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsForeignMethodDef))
  4226. {
  4227. thisValue.mType = mModule->mCurMethodInstance->GetForeignType();
  4228. forcedIFaceLookup = true;
  4229. }
  4230. if (thisValue)
  4231. {
  4232. if (findName == "this")
  4233. {
  4234. mModule->MarkUsingThis();
  4235. return thisValue;
  4236. }
  4237. if (findName == "base")
  4238. {
  4239. auto baseValue = thisValue;
  4240. if (baseValue.IsThis())
  4241. baseValue.ToBase();
  4242. if (mModule->GetActiveTypeDef()->mTypeCode != BfTypeCode_Extension)
  4243. {
  4244. MakeBaseConcrete(baseValue);
  4245. }
  4246. mModule->MarkUsingThis();
  4247. return baseValue;
  4248. }
  4249. if (!mModule->mCurMethodState->HasNonStaticMixin())
  4250. {
  4251. mResultLocalVar = mModule->GetThisVariable();
  4252. mResultFieldInstance = NULL;
  4253. mResultLocalVarRefNode = identifierNode;
  4254. }
  4255. }
  4256. if (!thisValue.HasType())
  4257. {
  4258. if ((mModule->mContext->mCurTypeState != NULL) && (mModule->mContext->mCurTypeState->mType == mModule->mCurTypeInstance) &&
  4259. (mModule->mContext->mCurTypeState->mResolveKind == BfTypeState::ResolveKind_Attributes))
  4260. {
  4261. // Can't do static lookups yet
  4262. }
  4263. else
  4264. thisValue = BfTypedValue(mModule->mCurTypeInstance);
  4265. }
  4266. BfTypedValue result;
  4267. if (thisValue.HasType())
  4268. {
  4269. result = LookupField(identifierNode, thisValue, findName, BfLookupFieldFlag_IsImplicitThis);
  4270. if (mResultFieldInstance == NULL)
  4271. {
  4272. mResultLocalVar = NULL;
  4273. mResultLocalVarRefNode = NULL;
  4274. }
  4275. }
  4276. if (mPropDef != NULL)
  4277. {
  4278. if (forcedIFaceLookup)
  4279. {
  4280. if (mPropTarget == thisValue)
  4281. {
  4282. mPropDefBypassVirtual = true;
  4283. mOrigPropTarget = mModule->GetThis();
  4284. }
  4285. }
  4286. }
  4287. if ((!result) && (mPropDef == NULL))
  4288. {
  4289. if (mModule->mContext->mCurTypeState != NULL)
  4290. {
  4291. // This is not necessarily true since we changed ConstResolver
  4292. //BF_ASSERT(mModule->mCurTypeInstance == mModule->mContext->mCurTypeState->mTypeInstance);
  4293. BfGlobalLookup globalLookup;
  4294. globalLookup.mKind = BfGlobalLookup::Kind_Field;
  4295. globalLookup.mName = findName;
  4296. mModule->PopulateGlobalContainersList(globalLookup);
  4297. for (auto& globalContainer : mModule->mContext->mCurTypeState->mGlobalContainers)
  4298. {
  4299. if (globalContainer.mTypeInst == NULL)
  4300. continue;
  4301. thisValue = BfTypedValue(globalContainer.mTypeInst);
  4302. result = LookupField(identifierNode, thisValue, findName);
  4303. if ((result) || (mPropDef != NULL))
  4304. {
  4305. mModule->SetHighestElementType(identifierNode, BfSourceElementType_Member);
  4306. return result;
  4307. }
  4308. }
  4309. }
  4310. auto staticSearch = mModule->GetStaticSearch();
  4311. if (staticSearch != NULL)
  4312. {
  4313. for (auto typeInst : staticSearch->mStaticTypes)
  4314. {
  4315. thisValue = BfTypedValue(typeInst);
  4316. result = LookupField(identifierNode, thisValue, findName);
  4317. if ((result) || (mPropDef != NULL))
  4318. {
  4319. mModule->SetHighestElementType(identifierNode, BfSourceElementType_Member);
  4320. return result;
  4321. }
  4322. }
  4323. }
  4324. }
  4325. else
  4326. {
  4327. mModule->SetHighestElementType(identifierNode, BfSourceElementType_Member);
  4328. }
  4329. if ((!result) && (identifierNode != NULL))
  4330. {
  4331. result = mModule->TryLookupGenericConstVaue(identifierNode, mExpectingType);
  4332. if ((mBfEvalExprFlags & (BfEvalExprFlags_Comptime | BfEvalExprFlags_AllowGenericConstValue)) == BfEvalExprFlags_Comptime)
  4333. {
  4334. if (result.mKind == BfTypedValueKind_GenericConstValue)
  4335. {
  4336. auto genericParamDef = mModule->GetGenericParamInstance((BfGenericParamType*)result.mType);
  4337. if ((genericParamDef->mGenericParamFlags & BfGenericParamFlag_Const) != 0)
  4338. {
  4339. auto genericTypeConstraint = genericParamDef->mTypeConstraint;
  4340. if (genericTypeConstraint != NULL)
  4341. {
  4342. auto primType = genericTypeConstraint->ToPrimitiveType();
  4343. if (primType != NULL)
  4344. {
  4345. BfTypedValue result;
  4346. result.mKind = BfTypedValueKind_Value;
  4347. result.mType = genericTypeConstraint;
  4348. result.mValue = mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->GetPrimitiveType(primType->mTypeDef->mTypeCode));
  4349. return result;
  4350. }
  4351. }
  4352. else
  4353. {
  4354. BF_FATAL("Error");
  4355. }
  4356. }
  4357. }
  4358. }
  4359. mModule->FixValueActualization(result);
  4360. }
  4361. if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) && (findName == "@this"))
  4362. {
  4363. if (mModule->mCurMethodState->mClosureState->mCapturing)
  4364. {
  4365. if (mModule->mCurMethodState->mClosureState->mDelegateType != NULL)
  4366. {
  4367. mModule->mCurMethodState->mClosureState->mCapturedDelegateSelf = true;
  4368. return mModule->GetDefaultTypedValue(mModule->mCurMethodState->mClosureState->mDelegateType);
  4369. }
  4370. }
  4371. else
  4372. {
  4373. if (!mModule->mCurMethodState->mLocals.IsEmpty())
  4374. {
  4375. auto thisLocal = mModule->mCurMethodState->mLocals[0];
  4376. if (thisLocal->mIsThis)
  4377. {
  4378. if (thisLocal->mAddr)
  4379. return BfTypedValue(mModule->mBfIRBuilder->CreateLoad(thisLocal->mAddr), thisLocal->mResolvedType);
  4380. else
  4381. return BfTypedValue(thisLocal->mValue, thisLocal->mResolvedType);
  4382. }
  4383. }
  4384. }
  4385. }
  4386. return result;
  4387. }
  4388. BfTypedValue BfExprEvaluator::LookupIdentifier(BfIdentifierNode* identifierNode, bool ignoreInitialError, bool* hadError)
  4389. {
  4390. auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(identifierNode);
  4391. if (qualifiedNameNode != NULL)
  4392. {
  4393. LookupQualifiedName(qualifiedNameNode, ignoreInitialError, hadError);
  4394. auto qualifiedResult = mResult;
  4395. mResult = BfTypedValue();
  4396. return qualifiedResult;
  4397. }
  4398. StringT<128> identifierStr;
  4399. identifierNode->ToString(identifierStr);
  4400. return LookupIdentifier(identifierNode, identifierStr, ignoreInitialError, hadError);
  4401. }
  4402. void BfExprEvaluator::Visit(BfIdentifierNode* identifierNode)
  4403. {
  4404. auto autoComplete = GetAutoComplete();
  4405. if (autoComplete != NULL)
  4406. autoComplete->CheckIdentifier(identifierNode, true);
  4407. mResult = LookupIdentifier(identifierNode);
  4408. if ((!mResult) && (mPropDef == NULL))
  4409. {
  4410. mModule->CheckTypeRefFixit(identifierNode);
  4411. if ((autoComplete != NULL) && (autoComplete->CheckFixit(identifierNode)))
  4412. {
  4413. if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mCapturing))
  4414. {
  4415. // During this phase we don't have lambda and local method params available so they would result in erroneous fixits
  4416. }
  4417. else if (mModule->mCurMethodInstance != NULL)
  4418. {
  4419. BfType* fieldType = mExpectingType;
  4420. if (fieldType == NULL)
  4421. fieldType = mModule->mContext->mBfObjectType;
  4422. autoComplete->FixitAddMember(mModule->mCurTypeInstance, fieldType, identifierNode->ToString(), true, mModule->mCurTypeInstance);
  4423. if (!mModule->mCurMethodInstance->mMethodDef->mIsStatic)
  4424. autoComplete->FixitAddMember(mModule->mCurTypeInstance, fieldType, identifierNode->ToString(), false, mModule->mCurTypeInstance);
  4425. for (auto typeDef : mModule->mSystem->mTypeDefs)
  4426. {
  4427. if (!typeDef->mIsCombinedPartial)
  4428. continue;
  4429. if (!typeDef->IsGlobalsContainer())
  4430. continue;
  4431. typeDef->PopulateMemberSets();
  4432. String findName = identifierNode->ToString();
  4433. BfMemberSetEntry* memberSetEntry;
  4434. if ((typeDef->mMethodSet.TryGetWith(findName, &memberSetEntry)) ||
  4435. (typeDef->mFieldSet.TryGetWith(findName, &memberSetEntry)) ||
  4436. (typeDef->mPropertySet.TryGetWith(findName, &memberSetEntry)))
  4437. {
  4438. if (mModule->GetActiveTypeDef()->mProject->ContainsReference(typeDef->mProject))
  4439. autoComplete->FixitAddNamespace(identifierNode, typeDef->mNamespace.ToString());
  4440. }
  4441. }
  4442. }
  4443. }
  4444. if (((mBfEvalExprFlags & BfEvalExprFlags_NameOf) != 0) && (mModule->mCurTypeInstance != NULL) && (CheckForMethodName(identifierNode, mModule->mCurTypeInstance, identifierNode->ToString())))
  4445. return;
  4446. if ((mBfEvalExprFlags & BfEvalExprFlags_NoLookupError) == 0)
  4447. mModule->Fail("Identifier not found", identifierNode);
  4448. }
  4449. }
  4450. void BfExprEvaluator::Visit(BfAttributedIdentifierNode* attrIdentifierNode)
  4451. {
  4452. if ((mModule->mAttributeState != NULL))
  4453. {
  4454. mModule->mAttributeState->mCustomAttributes = mModule->GetCustomAttributes(attrIdentifierNode->mAttributes, mModule->mAttributeState->mTarget);
  4455. VisitChild(attrIdentifierNode->mIdentifier);
  4456. }
  4457. else
  4458. {
  4459. BfAttributeState attributeState;
  4460. attributeState.mTarget = (BfAttributeTargets)(BfAttributeTargets_MemberAccess);
  4461. SetAndRestoreValue<BfAttributeState*> prevAttributeState(mModule->mAttributeState, &attributeState);
  4462. mModule->mAttributeState->mCustomAttributes = mModule->GetCustomAttributes(attrIdentifierNode->mAttributes, mModule->mAttributeState->mTarget);
  4463. VisitChild(attrIdentifierNode->mIdentifier);
  4464. }
  4465. }
  4466. static int gPropIdx = 0;
  4467. void BfExprEvaluator::FixitAddMember(BfTypeInstance* typeInst, BfType* fieldType, const StringImpl& fieldName, bool isStatic)
  4468. {
  4469. if (fieldType == NULL)
  4470. {
  4471. fieldType = mExpectingType;
  4472. }
  4473. if (fieldType != NULL)
  4474. {
  4475. if (fieldType->IsRef())
  4476. fieldType = fieldType->GetUnderlyingType();
  4477. }
  4478. mModule->mCompiler->mResolvePassData->mAutoComplete->FixitAddMember(typeInst, fieldType, fieldName, isStatic, mModule->mCurTypeInstance);
  4479. }
  4480. BfTypedValue BfExprEvaluator::TryArrowLookup(BfTypedValue typedValue, BfTokenNode* arrowToken)
  4481. {
  4482. auto arrowValue = PerformUnaryOperation_TryOperator(typedValue, NULL, BfUnaryOp_Arrow, arrowToken, BfUnaryOpFlag_None);
  4483. if (arrowValue)
  4484. return arrowValue;
  4485. if (mModule->PreFail())
  4486. mModule->Fail(StrFormat("Type '%s' does not contain a '->' operator", mModule->TypeToString(typedValue.mType).c_str()), arrowToken);
  4487. return typedValue;
  4488. }
  4489. BfTypedValue BfExprEvaluator::LoadProperty(BfAstNode* targetSrc, BfTypedValue target, BfTypeInstance* typeInstance, BfPropertyDef* prop, BfLookupFieldFlags flags, BfCheckedKind checkedKind, bool isInlined)
  4490. {
  4491. BfTypedValue origTarget = target;
  4492. if ((target.mType != NULL) && (target.mType->IsStructPtr()))
  4493. {
  4494. target = mModule->LoadValue(target);
  4495. target = BfTypedValue(target.mValue, target.mType->GetUnderlyingType(), target.IsReadOnly() ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
  4496. }
  4497. if ((flags & BfLookupFieldFlag_IsAnonymous) == 0)
  4498. mModule->SetElementType(targetSrc, BfSourceElementType_Method);
  4499. if ((!prop->mIsStatic) && ((flags & BfLookupFieldFlag_IsImplicitThis) != 0))
  4500. mModule->MarkUsingThis();
  4501. mPropSrc = targetSrc;
  4502. mPropDef = prop;
  4503. mPropCheckedKind = checkedKind;
  4504. if (isInlined)
  4505. mPropGetMethodFlags = (BfGetMethodInstanceFlags)(mPropGetMethodFlags | BfGetMethodInstanceFlag_ForceInline);
  4506. if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL))
  4507. {
  4508. if (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mFriendAttributeTypeDef))
  4509. {
  4510. mPropGetMethodFlags = (BfGetMethodInstanceFlags)(mPropGetMethodFlags | BfGetMethodInstanceFlag_Friend);
  4511. mModule->mAttributeState->mUsed = true;
  4512. }
  4513. if (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mDisableObjectAccessChecksAttributeTypeDef))
  4514. {
  4515. mPropGetMethodFlags = (BfGetMethodInstanceFlags)(mPropGetMethodFlags | BfGetMethodInstanceFlag_DisableObjectAccessChecks);
  4516. mModule->mAttributeState->mUsed = true;
  4517. }
  4518. }
  4519. if (mPropDef->mIsStatic)
  4520. {
  4521. if ((target) && ((flags & BfLookupFieldFlag_IsImplicitThis) == 0) && (!typeInstance->mTypeDef->IsGlobalsContainer()))
  4522. {
  4523. //CS0176: Member 'Program.sVal' cannot be accessed with an instance reference; qualify it with a type name instead
  4524. mModule->Fail(StrFormat("Property '%s.%s' cannot be accessed with an instance reference; qualify it with a type name instead",
  4525. mModule->TypeToString(typeInstance).c_str(), mPropDef->mName.c_str()), targetSrc);
  4526. }
  4527. }
  4528. bool isBaseLookup = (target.mType) && (typeInstance != target.mType);
  4529. if ((isBaseLookup) && (target.mType->IsWrappableType()))
  4530. isBaseLookup = false;
  4531. if (prop->mIsStatic)
  4532. mPropTarget = BfTypedValue(typeInstance);
  4533. else if (isBaseLookup)
  4534. {
  4535. if (target.mValue.IsFake())
  4536. {
  4537. mPropTarget = BfTypedValue(target.mValue, typeInstance, target.mKind);
  4538. }
  4539. else
  4540. {
  4541. mPropTarget = mModule->Cast(targetSrc, target, typeInstance);
  4542. BF_ASSERT(mPropTarget);
  4543. }
  4544. }
  4545. else
  4546. mPropTarget = target;
  4547. mOrigPropTarget = mPropTarget;
  4548. if (prop->mIsStatic)
  4549. mOrigPropTarget = target;
  4550. #ifdef _DEBUG
  4551. if (mPropTarget)
  4552. {
  4553. auto propTargetTypeInst = mPropTarget.mType->ToTypeInstance();
  4554. if (propTargetTypeInst != NULL)
  4555. {
  4556. BF_ASSERT(prop->mDeclaringType->mFullNameEx == propTargetTypeInst->mTypeDef->mFullNameEx);
  4557. }
  4558. }
  4559. #endif
  4560. if ((flags & BfLookupFieldFlag_IsAnonymous) == 0)
  4561. {
  4562. auto autoComplete = GetAutoComplete();
  4563. auto resolvePassData = mModule->mCompiler->mResolvePassData;
  4564. if (((autoComplete != NULL) && (autoComplete->mIsGetDefinition)) ||
  4565. ((resolvePassData != NULL) && (resolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Property)))
  4566. {
  4567. BfPropertyDef* basePropDef = mPropDef;
  4568. BfTypeInstance* baseTypeInst = typeInstance;
  4569. mModule->GetBasePropertyDef(basePropDef, baseTypeInst);
  4570. resolvePassData->HandlePropertyReference(targetSrc, baseTypeInst->mTypeDef, basePropDef);
  4571. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(targetSrc)))
  4572. {
  4573. if (autoComplete->mIsGetDefinition)
  4574. {
  4575. //NOTE: passing 'force=true' in here causes https://github.com/beefytech/Beef/issues/1064
  4576. autoComplete->SetDefinitionLocation(basePropDef->GetRefNode());
  4577. }
  4578. autoComplete->mDefProp = basePropDef;
  4579. autoComplete->mDefType = baseTypeInst->mTypeDef;
  4580. }
  4581. }
  4582. if ((autoComplete != NULL) && (autoComplete->mResolveType == BfResolveType_GetResultString) && (autoComplete->IsAutocompleteNode(targetSrc)))
  4583. {
  4584. BfPropertyDef* basePropDef = mPropDef;
  4585. BfTypeInstance* baseTypeInst = typeInstance;
  4586. mModule->GetBasePropertyDef(basePropDef, baseTypeInst);
  4587. autoComplete->mResultString = ":";
  4588. autoComplete->mResultString += mModule->TypeToString(baseTypeInst);
  4589. autoComplete->mResultString += ".";
  4590. autoComplete->mResultString += basePropDef->mName;
  4591. }
  4592. }
  4593. // Check for direct auto-property access
  4594. if ((target.mType == mModule->mCurTypeInstance) && ((flags & BfLookupFieldFlag_BindOnly) == 0))
  4595. {
  4596. if (auto propertyDeclaration = BfNodeDynCast<BfPropertyDeclaration>(mPropDef->mFieldDeclaration))
  4597. {
  4598. if ((typeInstance->mTypeDef->HasAutoProperty(propertyDeclaration)) && (propertyDeclaration->mVirtualSpecifier == NULL))
  4599. {
  4600. BfMethodDef* getter = GetPropertyMethodDef(mPropDef, BfMethodType_PropertyGetter, BfCheckedKind_NotSet, mPropTarget);
  4601. BfMethodDef* setter = GetPropertyMethodDef(mPropDef, BfMethodType_PropertySetter, BfCheckedKind_NotSet, mPropTarget);
  4602. bool optAllowed = true;
  4603. if ((getter != NULL) && (getter->mBody != NULL))
  4604. optAllowed = false;
  4605. if ((setter != NULL) && (setter->mBody != NULL))
  4606. optAllowed = false;
  4607. if (optAllowed)
  4608. {
  4609. auto autoFieldName = typeInstance->mTypeDef->GetAutoPropertyName(propertyDeclaration);
  4610. auto result = LookupField(targetSrc, target, autoFieldName, (BfLookupFieldFlags)(BfLookupFieldFlag_IgnoreProtection | BfLookupFieldFlag_IsImplicitThis));
  4611. if (result)
  4612. {
  4613. bool needsCopy = true;
  4614. if (BfNodeIsA<BfRefTypeRef>(prop->mTypeRef))
  4615. {
  4616. // Allow full ref
  4617. }
  4618. else
  4619. {
  4620. if (setter == NULL)
  4621. {
  4622. if (((mModule->mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_Ctor)) &&
  4623. (target.mType == mModule->mCurTypeInstance))
  4624. {
  4625. // Allow writing inside ctor
  4626. }
  4627. else
  4628. {
  4629. result.MakeReadOnly();
  4630. needsCopy = false;
  4631. }
  4632. }
  4633. if (result.mKind == BfTypedValueKind_Addr)
  4634. result.mKind = BfTypedValueKind_CopyOnMutateAddr;
  4635. }
  4636. mPropDef = NULL;
  4637. mPropSrc = NULL;
  4638. mOrigPropTarget = BfTypedValue();
  4639. return result;
  4640. }
  4641. }
  4642. }
  4643. }
  4644. }
  4645. if (!mPropDef->mIsStatic)
  4646. {
  4647. SetAndRestoreValue<BfTypedValue> prevResult(mResult, target);
  4648. CheckResultForReading(mResult);
  4649. }
  4650. return BfTypedValue();
  4651. }
  4652. BfTypedValue BfExprEvaluator::LoadField(BfAstNode* targetSrc, BfTypedValue target, BfTypeInstance* typeInstance, BfFieldDef* fieldDef, BfLookupFieldFlags flags)
  4653. {
  4654. if (fieldDef->mIsProperty)
  4655. {
  4656. BfPropertyDef* propDef = (BfPropertyDef*)fieldDef;
  4657. return LoadProperty(targetSrc, target, typeInstance, propDef, flags, BfCheckedKind_NotSet, false);
  4658. }
  4659. bool isFailurePass = (flags & BfLookupFieldFlag_IsFailurePass) != 0;
  4660. auto fieldInstance = &typeInstance->mFieldInstances[fieldDef->mIdx];
  4661. bool isResolvingFields = typeInstance->mResolvingConstField || typeInstance->mResolvingVarField;
  4662. if (typeInstance->mDefineState < BfTypeDefineState_Defined)
  4663. {
  4664. // Check for cases like a member like 'uint8[sizeof(decltype(PrevMember))] NextMember;'
  4665. auto checkTypeState = mModule->mContext->mCurTypeState;
  4666. while (checkTypeState != NULL)
  4667. {
  4668. if ((checkTypeState->mType == typeInstance) && (checkTypeState->mResolveKind == BfTypeState::ResolveKind_FieldType))
  4669. isResolvingFields = true;
  4670. checkTypeState = checkTypeState->mPrevState;
  4671. }
  4672. }
  4673. if (fieldDef->mIsVolatile)
  4674. mIsVolatileReference = true;
  4675. if (fieldInstance->mCustomAttributes != NULL)
  4676. mModule->CheckErrorAttributes(fieldInstance->mOwner, NULL, fieldInstance, fieldInstance->mCustomAttributes, targetSrc);
  4677. if (isFailurePass)
  4678. {
  4679. if (mModule->GetCeDbgState() == NULL)
  4680. mModule->Fail(StrFormat("'%s.%s' is inaccessible due to its protection level", mModule->TypeToString(typeInstance).c_str(), fieldDef->mName.c_str()), targetSrc);
  4681. }
  4682. auto resolvePassData = mModule->mCompiler->mResolvePassData;
  4683. if ((resolvePassData != NULL) && (resolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Field) && ((flags & BfLookupFieldFlag_IsAnonymous) == 0))
  4684. {
  4685. resolvePassData->HandleFieldReference(targetSrc, typeInstance->mTypeDef, fieldDef);
  4686. }
  4687. if ((!typeInstance->mTypeFailed) && (!isResolvingFields) && (typeInstance->IsIncomplete()))
  4688. {
  4689. if ((fieldInstance->mResolvedType == NULL) ||
  4690. (!fieldDef->mIsStatic))
  4691. {
  4692. mModule->PopulateType(typeInstance, BfPopulateType_Data);
  4693. // Update fieldInstance pointer as it may have moved
  4694. fieldInstance = &typeInstance->mFieldInstances[fieldDef->mIdx];
  4695. }
  4696. }
  4697. if (fieldInstance->mResolvedType == NULL)
  4698. {
  4699. if (mModule->mCompiler->EnsureCeUnpaused(typeInstance))
  4700. {
  4701. BF_ASSERT((typeInstance->mTypeFailed) || (isResolvingFields));
  4702. }
  4703. return BfTypedValue();
  4704. }
  4705. if (fieldInstance->mFieldIdx == -1)
  4706. {
  4707. mModule->AssertErrorState();
  4708. return BfTypedValue();
  4709. }
  4710. if ((!fieldDef->mIsStatic) && ((flags & BfLookupFieldFlag_IsImplicitThis) != 0))
  4711. mModule->MarkUsingThis();
  4712. mResultFieldInstance = fieldInstance;
  4713. // Are we accessing a 'var' field that has not yet been resolved?
  4714. if (IsVar(fieldInstance->mResolvedType))
  4715. {
  4716. // This can happen if we have one var field referencing another var field
  4717. fieldInstance->mResolvedType = mModule->ResolveVarFieldType(typeInstance, fieldInstance, fieldDef);
  4718. if (fieldInstance->mResolvedType == NULL)
  4719. return BfTypedValue();
  4720. }
  4721. auto resolvedFieldType = fieldInstance->mResolvedType;
  4722. if (fieldInstance->mIsEnumPayloadCase)
  4723. {
  4724. resolvedFieldType = typeInstance;
  4725. }
  4726. mModule->PopulateType(resolvedFieldType, BfPopulateType_Data);
  4727. mModule->AddDependency(typeInstance, mModule->mCurTypeInstance, fieldDef->mIsConst ? BfDependencyMap::DependencyFlag_ConstValue : BfDependencyMap::DependencyFlag_ReadFields);
  4728. if (fieldInstance->mHadConstEval)
  4729. {
  4730. mModule->AddDependency(typeInstance, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ConstEvalConstField);
  4731. if ((mModule->mContext->mCurTypeState != NULL) && (mModule->mContext->mCurTypeState->mCurFieldDef != NULL))
  4732. {
  4733. // If we're initializing another const field then also set it as having const eval
  4734. auto resolvingFieldInstance = &mModule->mContext->mCurTypeState->mType->ToTypeInstance()->mFieldInstances[mModule->mContext->mCurTypeState->mCurFieldDef->mIdx];
  4735. if (resolvingFieldInstance->GetFieldDef()->mIsConst)
  4736. resolvingFieldInstance->mHadConstEval = true;
  4737. }
  4738. }
  4739. if ((flags & BfLookupFieldFlag_IsAnonymous) == 0)
  4740. {
  4741. auto autoComplete = GetAutoComplete();
  4742. if (autoComplete != NULL)
  4743. {
  4744. autoComplete->CheckFieldRef(BfNodeDynCast<BfIdentifierNode>(targetSrc), fieldInstance);
  4745. if ((autoComplete->mResolveType == BfResolveType_GetResultString) && (autoComplete->IsAutocompleteNode(targetSrc)))
  4746. {
  4747. autoComplete->mResultString = ":";
  4748. autoComplete->mResultString += mModule->TypeToString(fieldInstance->mResolvedType);
  4749. autoComplete->mResultString += " ";
  4750. autoComplete->mResultString += mModule->TypeToString(typeInstance);
  4751. autoComplete->mResultString += ".";
  4752. autoComplete->mResultString += fieldDef->mName;
  4753. if (fieldInstance->mConstIdx != -1)
  4754. {
  4755. String constStr = autoComplete->ConstantToString(typeInstance->mConstHolder, BfTypedValue(BfIRValue(BfIRValueFlags_Const, fieldInstance->mConstIdx), fieldInstance->mResolvedType));
  4756. if (!constStr.IsEmpty())
  4757. {
  4758. autoComplete->mResultString += " = ";
  4759. if (constStr.StartsWith(':'))
  4760. autoComplete->mResultString.Append(StringView(constStr, 1, constStr.mLength - 1));
  4761. else
  4762. autoComplete->mResultString += constStr;
  4763. }
  4764. }
  4765. auto fieldDecl = fieldInstance->GetFieldDef()->GetFieldDeclaration();
  4766. if ((fieldDecl != NULL) && (fieldDecl->mDocumentation != NULL))
  4767. {
  4768. String docString;
  4769. fieldDecl->mDocumentation->GetDocString(docString);
  4770. autoComplete->mResultString += "\x03";
  4771. autoComplete->mResultString += docString;
  4772. }
  4773. }
  4774. }
  4775. }
  4776. if (fieldDef->mIsStatic)
  4777. {
  4778. if (target)
  4779. {
  4780. //BF_ASSERT((flags & BfLookupFieldFlag_HasInstance) != 0);
  4781. flags = (BfLookupFieldFlags)(flags | BfLookupFieldFlag_HasInstance);
  4782. }
  4783. if (((flags & BfLookupFieldFlag_HasInstance) != 0) && ((flags & BfLookupFieldFlag_IsImplicitThis) == 0) && (!typeInstance->mTypeDef->IsGlobalsContainer()))
  4784. {
  4785. //CS0176: Member 'Program.sVal' cannot be accessed with an instance reference; qualify it with a type name instead
  4786. mModule->Fail(StrFormat("Member '%s.%s' cannot be accessed with an instance reference; qualify it with a type name instead",
  4787. mModule->TypeToString(typeInstance).c_str(), fieldDef->mName.c_str()), targetSrc);
  4788. }
  4789. // Target must be an implicit 'this', or an error (accessing a static with a non-static target).
  4790. // Not actually needed in either case since this is a static lookup.
  4791. mResultLocalVar = NULL;
  4792. }
  4793. bool isConst = false;
  4794. if (fieldDef->mIsConst)
  4795. {
  4796. isConst = true;
  4797. auto fieldDef = fieldInstance->GetFieldDef();
  4798. if ((resolvedFieldType->IsPointer()) && (fieldDef->mIsExtern))
  4799. isConst = false;
  4800. }
  4801. if (isConst)
  4802. {
  4803. if (fieldInstance->mIsEnumPayloadCase)
  4804. {
  4805. auto dscrType = typeInstance->GetDiscriminatorType();
  4806. mModule->mBfIRBuilder->PopulateType(typeInstance);
  4807. int tagIdx = -fieldInstance->mDataIdx - 1;
  4808. if ((mBfEvalExprFlags & BfEvalExprFlags_AllowEnumId) != 0)
  4809. {
  4810. return BfTypedValue(mModule->mBfIRBuilder->CreateConst(dscrType->mTypeDef->mTypeCode, tagIdx), fieldInstance->mOwner);
  4811. }
  4812. mModule->PopulateType(fieldInstance->mOwner, BfPopulateType_Data);
  4813. if (auto fieldTypeInstance = fieldInstance->mResolvedType->ToTypeInstance())
  4814. {
  4815. bool hasFields = false;
  4816. for (auto& fieldInstance : fieldTypeInstance->mFieldInstances)
  4817. {
  4818. if (!fieldInstance.mResolvedType->IsVoid())
  4819. hasFields = true;
  4820. }
  4821. if (hasFields)
  4822. mModule->FailAfter("Enum payload arguments expected", targetSrc);
  4823. }
  4824. SizedArray<BfIRValue, 3> values;
  4825. values.Add(mModule->mBfIRBuilder->CreateConstAggZero(mModule->mBfIRBuilder->MapType(typeInstance->mBaseType)));
  4826. values.Add(mModule->GetDefaultValue(typeInstance->GetUnionInnerType()));
  4827. values.Add(mModule->mBfIRBuilder->CreateConst(dscrType->mTypeDef->mTypeCode, tagIdx));
  4828. return BfTypedValue(mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(typeInstance), values), typeInstance);
  4829. }
  4830. if (fieldInstance->mConstIdx == -1)
  4831. {
  4832. if ((mBfEvalExprFlags & BfEvalExprFlags_DeclType) != 0)
  4833. {
  4834. // We don't need a real value
  4835. return BfTypedValue(mModule->GetDefaultValue(resolvedFieldType), resolvedFieldType);
  4836. }
  4837. typeInstance->mModule->ResolveConstField(typeInstance, fieldInstance, fieldDef);
  4838. if (fieldInstance->mConstIdx == -1)
  4839. return BfTypedValue(mModule->GetDefaultValue(resolvedFieldType), resolvedFieldType);
  4840. }
  4841. BF_ASSERT(fieldInstance->mConstIdx != -1);
  4842. auto foreignConst = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
  4843. auto retVal = mModule->ConstantToCurrent(foreignConst, typeInstance->mConstHolder, resolvedFieldType);
  4844. return BfTypedValue(retVal, resolvedFieldType);
  4845. }
  4846. else if (fieldDef->mIsStatic)
  4847. {
  4848. if ((mModule->mAttributeState == NULL) || (mModule->mAttributeState->mCustomAttributes == NULL) ||
  4849. (!mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mNoStaticCtorAttributeTypeDef)))
  4850. {
  4851. mModule->CheckStaticAccess(typeInstance);
  4852. }
  4853. auto retVal = mModule->ReferenceStaticField(fieldInstance);
  4854. bool isStaticCtor = (mModule->mCurMethodInstance != NULL) &&
  4855. (mModule->mCurMethodInstance->mMethodDef->IsCtorOrInit()) &&
  4856. (mModule->mCurMethodInstance->mMethodDef->mIsStatic);
  4857. if ((mModule->mCompiler->mOptions.mRuntimeChecks) && (fieldInstance->IsAppendedObject()) && (!fieldDef->mIsStatic) && (!mModule->mBfIRBuilder->mIgnoreWrites) &&
  4858. (!mModule->IsSkippingExtraResolveChecks()))
  4859. {
  4860. auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  4861. auto intPtrType = mModule->CreatePointerType(intType);
  4862. auto intPtrVal = mModule->mBfIRBuilder->CreateBitCast(retVal.mValue, mModule->mBfIRBuilder->MapType(intPtrType));
  4863. auto intVal = mModule->mBfIRBuilder->CreateLoad(intPtrVal);
  4864. auto oobBlock = mModule->mBfIRBuilder->CreateBlock("oob", true);
  4865. auto contBlock = mModule->mBfIRBuilder->CreateBlock("cont", true);
  4866. auto cmpRes = mModule->mBfIRBuilder->CreateCmpEQ(intVal, mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0));
  4867. mModule->mBfIRBuilder->CreateCondBr(cmpRes, oobBlock, contBlock);
  4868. mModule->mBfIRBuilder->SetInsertPoint(oobBlock);
  4869. auto internalType = mModule->ResolveTypeDef(mModule->mCompiler->mInternalTypeDef);
  4870. auto oobFunc = mModule->GetMethodByName(internalType->ToTypeInstance(), "ThrowObjectNotInitialized");
  4871. if (oobFunc.mFunc)
  4872. {
  4873. if (mModule->mIsComptimeModule)
  4874. mModule->mCompiler->mCeMachine->QueueMethod(oobFunc.mMethodInstance, oobFunc.mFunc);
  4875. SizedArray<BfIRValue, 1> args;
  4876. args.push_back(mModule->GetConstValue(0));
  4877. mModule->mBfIRBuilder->CreateCall(oobFunc.mFunc, args);
  4878. mModule->mBfIRBuilder->CreateUnreachable();
  4879. }
  4880. else
  4881. {
  4882. mModule->Fail("System.Internal class must contain method 'ThrowObjectNotInitialized'", fieldDef->GetRefNode());
  4883. }
  4884. mModule->mBfIRBuilder->SetInsertPoint(contBlock);
  4885. }
  4886. if ((fieldDef->mIsReadOnly) && (!isStaticCtor))
  4887. {
  4888. if (retVal.IsAddr())
  4889. retVal.mKind = BfTypedValueKind_ReadOnlyAddr;
  4890. }
  4891. else
  4892. mIsHeapReference = true;
  4893. return retVal;
  4894. }
  4895. else if (!target)
  4896. {
  4897. if (((mBfEvalExprFlags & (BfEvalExprFlags_NameOf | BfEvalExprFlags_DeclType)) == 0) && (mModule->PreFail()))
  4898. {
  4899. if ((flags & BfLookupFieldFlag_CheckingOuter) != 0)
  4900. 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()),
  4901. targetSrc);
  4902. else if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_CtorCalcAppend))
  4903. {
  4904. if ((mBfEvalExprFlags & BfEvalExprFlags_DeclType) == 0)
  4905. mModule->Fail(StrFormat("Cannot reference field '%s' before append allocations", fieldDef->mName.c_str()), targetSrc);
  4906. }
  4907. else
  4908. mModule->Fail(StrFormat("Cannot reference non-static field '%s' from a static method", fieldDef->mName.c_str()), targetSrc);
  4909. }
  4910. return mModule->GetDefaultTypedValue(resolvedFieldType, false, BfDefaultValueKind_Addr);
  4911. }
  4912. if (resolvedFieldType->IsValuelessType())
  4913. {
  4914. return BfTypedValue(BfIRValue::sValueless, resolvedFieldType, true);
  4915. }
  4916. if ((mResultLocalVar != NULL) && (fieldInstance->mMergedDataIdx != -1))
  4917. {
  4918. if (mResultLocalVarFieldCount != 1)
  4919. {
  4920. fieldInstance->GetDataRange(mResultLocalVarField, mResultLocalVarFieldCount);
  4921. mResultLocalVarRefNode = targetSrc;
  4922. }
  4923. }
  4924. if ((typeInstance->IsIncomplete()) && (!typeInstance->mNeedsMethodProcessing))
  4925. {
  4926. BF_ASSERT(typeInstance->mTypeFailed || (mModule->mCurMethodState == NULL) || (mModule->mCurMethodState->mTempKind != BfMethodState::TempKind_None) || (mModule->mCompiler->IsAutocomplete()));
  4927. return mModule->GetDefaultTypedValue(resolvedFieldType);
  4928. }
  4929. bool isTemporary = target.IsTempAddr();
  4930. bool wantsLoadValue = false;
  4931. bool wantsReadOnly = false;
  4932. if ((fieldDef->mIsReadOnly) && (mModule->mCurMethodInstance != NULL) && ((!mModule->mCurMethodInstance->mMethodDef->IsCtorOrInit()) || (!target.IsThis())))
  4933. wantsReadOnly = true;
  4934. bool isComposite = target.mType->IsComposite();
  4935. if ((isComposite) && (!target.mType->IsTypedPrimitive()) && (!target.IsAddr()))
  4936. isTemporary = true;
  4937. if ((isComposite) && (!target.IsAddr()))
  4938. wantsLoadValue = true;
  4939. if ((target.mType->IsWrappableType()) && (!target.mType->IsPointer()))
  4940. {
  4941. BfTypeInstance* primStructType = mModule->GetWrappedStructType(target.mType);
  4942. BfIRValue allocaInst = mModule->CreateAlloca(primStructType, true, "tmpStruct");
  4943. BfIRValue elementAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, 1);
  4944. mModule->mBfIRBuilder->CreateStore(target.mValue, elementAddr);
  4945. target = BfTypedValue(allocaInst, primStructType, true);
  4946. }
  4947. BfTypedValue targetValue;
  4948. if ((target.mType != typeInstance) && (!target.IsSplat()))
  4949. {
  4950. if ((!isComposite) || (target.IsAddr()))
  4951. targetValue = BfTypedValue(mModule->mBfIRBuilder->CreateBitCast(target.mValue, mModule->mBfIRBuilder->MapTypeInstPtr(typeInstance)), typeInstance);
  4952. else
  4953. {
  4954. BfIRValue curVal = target.mValue;
  4955. auto baseCheckType = target.mType->ToTypeInstance();
  4956. while (baseCheckType != typeInstance)
  4957. {
  4958. curVal = mModule->mBfIRBuilder->CreateExtractValue(curVal, 0);
  4959. baseCheckType = baseCheckType->mBaseType;
  4960. }
  4961. targetValue = BfTypedValue(curVal, typeInstance);
  4962. }
  4963. }
  4964. else
  4965. targetValue = target;
  4966. bool doAccessCheck = true;
  4967. if ((flags & BfLookupFieldFlag_BindOnly) != 0)
  4968. doAccessCheck = false;
  4969. if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) && (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mDisableObjectAccessChecksAttributeTypeDef)))
  4970. doAccessCheck = false;
  4971. if (target.IsThis())
  4972. {
  4973. if (!mModule->mCurMethodState->mMayNeedThisAccessCheck)
  4974. doAccessCheck = false;
  4975. }
  4976. if (doAccessCheck)
  4977. mModule->EmitObjectAccessCheck(target);
  4978. if (fieldInstance->mDataIdx < 0)
  4979. {
  4980. mModule->mCompiler->RequestExtraCompile();
  4981. mModule->InternalError("LoadField field DataIdx<0 where InstSize>0");
  4982. mModule->DeferRebuildType(typeInstance);
  4983. return mModule->GetDefaultTypedValue(resolvedFieldType);
  4984. }
  4985. BfTypedValue retVal;
  4986. if (targetValue.IsSplat())
  4987. {
  4988. retVal = mModule->ExtractValue(targetValue, fieldInstance, fieldInstance->mDataIdx);
  4989. }
  4990. else if ((target.mType->IsStruct()) && (!target.IsAddr()))
  4991. {
  4992. mModule->mBfIRBuilder->PopulateType(targetValue.mType);
  4993. retVal = BfTypedValue(mModule->mBfIRBuilder->CreateExtractValue(targetValue.mValue, fieldInstance->mDataIdx/*, fieldDef->mName*/),
  4994. resolvedFieldType);
  4995. }
  4996. else
  4997. {
  4998. mModule->mBfIRBuilder->PopulateType(typeInstance);
  4999. if ((targetValue.IsAddr()) && (!typeInstance->IsValueType()))
  5000. targetValue = mModule->LoadValue(targetValue);
  5001. if (fieldInstance->IsAppendedObject())
  5002. {
  5003. auto elemPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(targetValue.mValue, 0, fieldInstance->mDataIdx);
  5004. retVal = BfTypedValue(mModule->mBfIRBuilder->CreateBitCast(elemPtr, mModule->mBfIRBuilder->MapType(resolvedFieldType)), resolvedFieldType);
  5005. }
  5006. else
  5007. {
  5008. retVal = BfTypedValue(mModule->mBfIRBuilder->CreateInBoundsGEP(targetValue.mValue, 0, fieldInstance->mDataIdx/*, fieldDef->mName*/),
  5009. resolvedFieldType, target.IsReadOnly() ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
  5010. }
  5011. }
  5012. if (typeInstance->mIsUnion)
  5013. {
  5014. auto unionInnerType = typeInstance->GetUnionInnerType();
  5015. if (unionInnerType != resolvedFieldType)
  5016. {
  5017. BfTypedValue unionTypedValue = retVal;
  5018. unionTypedValue.mType = unionInnerType;
  5019. if (!unionTypedValue.IsAddr())
  5020. unionTypedValue = mModule->MakeAddressable(unionTypedValue);
  5021. BfIRType llvmPtrType = mModule->mBfIRBuilder->GetPointerTo(mModule->mBfIRBuilder->MapType(resolvedFieldType));
  5022. retVal.mValue = mModule->mBfIRBuilder->CreateBitCast(unionTypedValue.mValue, llvmPtrType);
  5023. retVal.mKind = unionTypedValue.mKind;
  5024. }
  5025. }
  5026. if ((fieldDef->mIsVolatile) && (retVal.IsAddr()))
  5027. retVal.mKind = BfTypedValueKind_VolatileAddr;
  5028. if (wantsLoadValue)
  5029. retVal = mModule->LoadValue(retVal, NULL, mIsVolatileReference);
  5030. else
  5031. {
  5032. if ((wantsReadOnly) && (retVal.IsAddr()) && (!retVal.IsReadOnly()))
  5033. retVal.mKind = BfTypedValueKind_ReadOnlyAddr;
  5034. else if ((target.IsCopyOnMutate()) && (retVal.IsAddr()))
  5035. retVal.mKind = BfTypedValueKind_CopyOnMutateAddr_Derived;
  5036. mIsHeapReference = true;
  5037. }
  5038. if (isTemporary)
  5039. {
  5040. if (retVal.IsAddr())
  5041. retVal.mKind = BfTypedValueKind_TempAddr;
  5042. }
  5043. return retVal;
  5044. }
  5045. BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue target, const StringImpl& fieldName, BfLookupFieldFlags flags)
  5046. {
  5047. if (target)
  5048. flags = (BfLookupFieldFlags)(flags | BfLookupFieldFlag_HasInstance);
  5049. if ((target.mType != NULL && (target.mType->IsGenericParam())))
  5050. {
  5051. auto genericParamType = (BfGenericParamType*)target.mType;
  5052. auto genericParamInst = mModule->GetGenericParamInstance(genericParamType);
  5053. if (target.mValue)
  5054. {
  5055. for (auto iface : genericParamInst->mInterfaceConstraints)
  5056. {
  5057. auto result = LookupField(targetSrc, BfTypedValue(target.mValue, iface), fieldName, flags);
  5058. if ((result) || (mPropDef != NULL))
  5059. {
  5060. return result;
  5061. }
  5062. }
  5063. }
  5064. bool isUnspecializedSection = false;
  5065. if (genericParamType->mGenericParamKind == BfGenericParamKind_Method)
  5066. isUnspecializedSection = (mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsUnspecialized);
  5067. else
  5068. isUnspecializedSection = (mModule->mCurTypeInstance != NULL) && (mModule->mCurTypeInstance->IsUnspecializedType());
  5069. if (isUnspecializedSection)
  5070. {
  5071. auto origTarget = target;
  5072. if (genericParamInst->mTypeConstraint != NULL)
  5073. {
  5074. target.mType = genericParamInst->mTypeConstraint;
  5075. }
  5076. else
  5077. target.mType = mModule->mContext->mBfObjectType;
  5078. if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Var) != 0)
  5079. {
  5080. target.mType = mModule->GetPrimitiveType(BfTypeCode_Var);
  5081. }
  5082. if (origTarget.mType->IsTypeGenericParam())
  5083. {
  5084. // Check for extern constraint in method generic params
  5085. if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mMethodInfoEx != NULL))
  5086. {
  5087. for (auto genericParam : mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams)
  5088. {
  5089. if (genericParam->mExternType == origTarget.mType)
  5090. {
  5091. if (genericParam->mTypeConstraint != NULL)
  5092. {
  5093. target.mType = genericParam->mTypeConstraint;
  5094. break;
  5095. }
  5096. }
  5097. }
  5098. }
  5099. }
  5100. if (target.mType->IsWrappableType())
  5101. target.mType = mModule->GetWrappedStructType(target.mType);
  5102. }
  5103. else
  5104. {
  5105. if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Var) != 0)
  5106. {
  5107. //target.mType = mModule->ResolveGenericType(mResult.mType);
  5108. }
  5109. else if (genericParamInst->mTypeConstraint != NULL)
  5110. {
  5111. target = mModule->Cast(targetSrc, target, genericParamInst->mTypeConstraint);
  5112. BF_ASSERT(target);
  5113. }
  5114. else
  5115. {
  5116. // This shouldn't occur - this would infer that we are accessing a member of Object or something...
  5117. //target.mType = mModule->ResolveGenericType(mResult.mType);
  5118. }
  5119. }
  5120. }
  5121. if ((target.mType != NULL) && (IsVar(target.mType, (flags & BfLookupFieldFlag_BindOnly) != 0)))
  5122. return BfTypedValue(mModule->GetDefaultValue(target.mType), target.mType, true);
  5123. BfTypeInstance* startCheckType = mModule->mCurTypeInstance;
  5124. mPropDef = NULL;
  5125. mPropDefBypassVirtual = false;
  5126. if (target)
  5127. {
  5128. if ((!target.mType->IsValueType()) && (target.IsAddr()))
  5129. target = mModule->LoadValue(target);
  5130. if (target.mType->IsPrimitiveType())
  5131. {
  5132. auto primType = (BfPrimitiveType*)target.mType;
  5133. startCheckType = mModule->GetPrimitiveStructType(primType->mTypeDef->mTypeCode);
  5134. }
  5135. else
  5136. {
  5137. startCheckType = target.mType->ToTypeInstance();
  5138. if ((startCheckType == NULL) && (target.mType->IsPointer()))
  5139. {
  5140. startCheckType = ((BfPointerType*)target.mType)->mElementType->ToTypeInstance();
  5141. if ((startCheckType != NULL) && (!startCheckType->IsValueType()))
  5142. return BfTypedValue();
  5143. }
  5144. }
  5145. //BF_ASSERT(startCheckType != NULL);
  5146. }
  5147. else if (target.mType != NULL)
  5148. {
  5149. startCheckType = target.mType->ToTypeInstance();
  5150. }
  5151. if ((startCheckType != NULL) && (startCheckType->mBaseType == NULL))
  5152. {
  5153. if (startCheckType->mDefineState == BfTypeDefineState_ResolvingBaseType)
  5154. {
  5155. // Fixes cases where we have something like 'Base[Value]' as a base typeref
  5156. return BfTypedValue();
  5157. }
  5158. mModule->PopulateType(startCheckType, BfPopulateType_BaseType);
  5159. }
  5160. String findName;
  5161. int varSkipCount = 0;
  5162. if (fieldName.StartsWith('@'))
  5163. {
  5164. findName = fieldName;
  5165. while (findName.StartsWith('@'))
  5166. {
  5167. findName.Remove(0);
  5168. varSkipCount++;
  5169. }
  5170. }
  5171. else
  5172. findName.Reference(fieldName);
  5173. auto activeTypeDef = mModule->GetActiveTypeDef();
  5174. for (int pass = 0; pass < 2; pass++)
  5175. {
  5176. auto curCheckType = startCheckType;
  5177. bool isFailurePass = pass == 1;
  5178. if (isFailurePass)
  5179. flags = (BfLookupFieldFlags)(flags | BfLookupFieldFlag_IsFailurePass);
  5180. bool isBaseLookup = false;
  5181. int checkInterfaceIdx = 0;
  5182. while (curCheckType != NULL)
  5183. {
  5184. if (((flags & BfLookupFieldFlag_CheckingOuter) != 0) && ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0))
  5185. {
  5186. // Don't fully populateType for CheckingOuter - it carries a risk of an inadvertent data cycle
  5187. // Avoiding this could cause issues finding emitted statics/constants
  5188. }
  5189. else
  5190. {
  5191. bool isPopulatingType = false;
  5192. auto checkTypeState = mModule->mContext->mCurTypeState;
  5193. while (checkTypeState != NULL)
  5194. {
  5195. if (curCheckType == checkTypeState->mType)
  5196. {
  5197. isPopulatingType = true;
  5198. if (checkTypeState->mResolveKind == BfTypeState::ResolveKind_Attributes)
  5199. {
  5200. // Don't allow lookups yet
  5201. return BfTypedValue();
  5202. }
  5203. }
  5204. checkTypeState = checkTypeState->mPrevState;
  5205. }
  5206. if ((!isPopulatingType) && (curCheckType->mDefineState < Beefy::BfTypeDefineState_Defined))
  5207. {
  5208. // We MAY have emitted fields so we need to do this
  5209. mModule->mContext->mUnreifiedModule->PopulateType(curCheckType, Beefy::BfPopulateType_Interfaces_All);
  5210. }
  5211. }
  5212. curCheckType->mTypeDef->PopulateMemberSets();
  5213. BfFieldDef* nextField = NULL;
  5214. BfMemberSetEntry* entry;
  5215. if (curCheckType->mTypeDef->mFieldSet.TryGetWith(findName, &entry))
  5216. nextField = (BfFieldDef*)entry->mMemberDef;
  5217. if (nextField != NULL)
  5218. varSkipCount -= nextField->mNamePrefixCount;
  5219. while ((varSkipCount > 0) && (nextField != NULL))
  5220. {
  5221. nextField = nextField->mNextWithSameName;
  5222. varSkipCount--;
  5223. }
  5224. BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None;
  5225. if (target)
  5226. {
  5227. if ((flags & (BfLookupFieldFlag_IsImplicitThis | BfLookupFieldFlag_BaseLookup)) != 0)
  5228. {
  5229. // Not an "instance lookup"
  5230. }
  5231. else
  5232. {
  5233. protectionCheckFlags = (BfProtectionCheckFlags)(protectionCheckFlags | BfProtectionCheckFlag_InstanceLookup);
  5234. }
  5235. }
  5236. BfFieldDef* matchedField = NULL;
  5237. while (nextField != NULL)
  5238. {
  5239. if ((flags & BfLookupFieldFlag_BindOnly) != 0)
  5240. break;
  5241. auto field = nextField;
  5242. nextField = nextField->mNextWithSameName;
  5243. auto checkProtection = field->mProtection;
  5244. if (checkProtection == BfProtection_Hidden)
  5245. {
  5246. // Allow accessing hidden fields
  5247. checkProtection = BfProtection_Private;
  5248. }
  5249. if (((flags & BfLookupFieldFlag_IgnoreProtection) == 0) && (!isFailurePass) &&
  5250. (!mModule->CheckProtection(protectionCheckFlags, curCheckType, field->mDeclaringType->mProject, checkProtection, startCheckType)))
  5251. {
  5252. continue;
  5253. }
  5254. bool isResolvingFields = curCheckType->mResolvingConstField || curCheckType->mResolvingVarField;
  5255. if (curCheckType->mFieldInstances.IsEmpty())
  5256. {
  5257. mModule->PopulateType(curCheckType, BfPopulateType_Data);
  5258. }
  5259. if (field->mIdx >= (int)curCheckType->mFieldInstances.size())
  5260. {
  5261. if (mModule->mCompiler->EnsureCeUnpaused(curCheckType))
  5262. {
  5263. BF_DBG_FATAL("OOB in DoLookupField");
  5264. }
  5265. return mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Var));
  5266. }
  5267. BF_ASSERT(field->mIdx < (int)curCheckType->mFieldInstances.size());
  5268. auto fieldInstance = &curCheckType->mFieldInstances[field->mIdx];
  5269. if (!fieldInstance->mFieldIncluded)
  5270. continue;
  5271. if (curCheckType->IsUnspecializedType())
  5272. {
  5273. // The check for non-unspecialized types is already handled in mFieldIncluded
  5274. if (!curCheckType->IsTypeMemberIncluded(field->mDeclaringType, activeTypeDef, mModule))
  5275. continue;
  5276. }
  5277. if (!mModule->IsInSpecializedSection())
  5278. {
  5279. if (!curCheckType->IsTypeMemberAccessible(field->mDeclaringType, activeTypeDef))
  5280. continue;
  5281. }
  5282. if (matchedField != NULL)
  5283. {
  5284. auto error = mModule->Fail(StrFormat("Ambiguous reference to field '%s.%s'", mModule->TypeToString(curCheckType).c_str(), fieldName.c_str()), targetSrc);
  5285. if (error != NULL)
  5286. {
  5287. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See field declaration in project '%s'", matchedField->mDeclaringType->mProject->mName.c_str()), matchedField->mFieldDeclaration);
  5288. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See field declaration in project '%s'", field->mDeclaringType->mProject->mName.c_str()), field->mFieldDeclaration);
  5289. break;
  5290. }
  5291. }
  5292. matchedField = field;
  5293. }
  5294. if (matchedField != NULL)
  5295. return LoadField(targetSrc, target, curCheckType, matchedField, flags);
  5296. BfPropertyDef* nextProp = NULL;
  5297. if (curCheckType->mTypeDef->mPropertySet.TryGetWith(fieldName, &entry))
  5298. nextProp = (BfPropertyDef*)entry->mMemberDef;
  5299. if (nextProp != NULL)
  5300. {
  5301. BfCheckedKind checkedKind = BfCheckedKind_NotSet;
  5302. bool isInlined = false;
  5303. if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL))
  5304. {
  5305. if (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mInlineAttributeTypeDef))
  5306. {
  5307. isInlined = true;
  5308. mModule->mAttributeState->mUsed = true;
  5309. }
  5310. if (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mCheckedAttributeTypeDef))
  5311. {
  5312. checkedKind = BfCheckedKind_Checked;
  5313. mModule->mAttributeState->mUsed = true;
  5314. }
  5315. if (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mUncheckedAttributeTypeDef))
  5316. {
  5317. checkedKind = BfCheckedKind_Unchecked;
  5318. mModule->mAttributeState->mUsed = true;
  5319. }
  5320. }
  5321. BfPropertyDef* matchedProp = NULL;
  5322. while (nextProp != NULL)
  5323. {
  5324. auto prop = nextProp;
  5325. nextProp = nextProp->mNextWithSameName;
  5326. if ((!isFailurePass) && ((mBfEvalExprFlags & BfEvalExprFlags_NameOf) == 0) && (!mModule->CheckProtection(protectionCheckFlags, curCheckType, prop->mDeclaringType->mProject, prop->mProtection, startCheckType)))
  5327. {
  5328. continue;
  5329. }
  5330. if (!prop->mMethods.IsEmpty())
  5331. {
  5332. BfMethodDef* checkMethod = prop->mMethods[0];
  5333. // Properties with explicit interfaces or marked as overrides can only be called indirectly
  5334. if ((checkMethod->mExplicitInterface != NULL) || (checkMethod->mIsOverride))
  5335. continue;
  5336. }
  5337. if ((!target.IsStatic()) || (prop->mIsStatic) || ((mBfEvalExprFlags & BfEvalExprFlags_NameOf) != 0))
  5338. {
  5339. if (!curCheckType->IsTypeMemberIncluded(prop->mDeclaringType, activeTypeDef, mModule))
  5340. continue;
  5341. if (!mModule->IsInSpecializedSection())
  5342. {
  5343. if (!curCheckType->IsTypeMemberAccessible(prop->mDeclaringType, mModule->GetVisibleProjectSet()))
  5344. continue;
  5345. }
  5346. if (matchedProp != NULL)
  5347. {
  5348. if ((matchedProp->mDeclaringType->IsExtension()) && (!prop->mDeclaringType->IsExtension()))
  5349. {
  5350. // Prefer non-extension
  5351. continue;
  5352. }
  5353. else
  5354. {
  5355. if (mModule->PreFail())
  5356. {
  5357. auto error = mModule->Fail(StrFormat("Ambiguous reference to property '%s.%s'", mModule->TypeToString(curCheckType).c_str(), fieldName.c_str()), targetSrc);
  5358. if (error != NULL)
  5359. {
  5360. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See property declaration in project '%s'", matchedProp->mDeclaringType->mProject->mName.c_str()), matchedProp->mFieldDeclaration);
  5361. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See property declaration in project '%s'", prop->mDeclaringType->mProject->mName.c_str()), prop->mFieldDeclaration);
  5362. break;
  5363. }
  5364. }
  5365. }
  5366. }
  5367. matchedProp = prop;
  5368. }
  5369. }
  5370. if (matchedProp != NULL)
  5371. return LoadProperty(targetSrc, target, curCheckType, matchedProp, flags, checkedKind, isInlined);
  5372. }
  5373. if (curCheckType->mTypeDef->mHasUsingFields)
  5374. mModule->PopulateUsingFieldData(curCheckType);
  5375. ///
  5376. {
  5377. Array<SizedArray<BfUsingFieldData::MemberRef, 1>*> foundLists;
  5378. auto _CheckUsingData = [&](BfUsingFieldData* usingData)
  5379. {
  5380. BfUsingFieldData::Entry* entry = NULL;
  5381. if (!usingData->mEntries.TryGetValue(findName, &entry))
  5382. return;
  5383. for (int listIdx = 0; listIdx < entry->mLookups.mSize; listIdx++)
  5384. {
  5385. bool passesProtection = true;
  5386. auto& entryList = entry->mLookups[listIdx];
  5387. for (int entryIdx = 0; entryIdx < entryList.mSize; entryIdx++)
  5388. {
  5389. auto& entry = entryList[entryIdx];
  5390. BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None;
  5391. if (!mModule->CheckProtection(protectionCheckFlags, entry.mTypeInstance, entry.GetDeclaringType(mModule)->mProject,
  5392. (entryIdx < entryList.mSize - 1) ? entry.GetUsingProtection() : entry.GetProtection(), curCheckType))
  5393. {
  5394. passesProtection = false;
  5395. break;
  5396. }
  5397. }
  5398. if (!passesProtection)
  5399. continue;
  5400. if (foundLists.mSize == 0)
  5401. {
  5402. foundLists.Add(&entryList);
  5403. }
  5404. else
  5405. {
  5406. if (entryList.mSize < foundLists[0]->mSize)
  5407. {
  5408. // New is shorter
  5409. foundLists.Clear();
  5410. foundLists.Add(&entryList);
  5411. }
  5412. else if (entryList.mSize > foundLists[0]->mSize)
  5413. {
  5414. // Ignore longer
  5415. }
  5416. else
  5417. {
  5418. foundLists.Add(&entryList);
  5419. }
  5420. }
  5421. }
  5422. };
  5423. if ((curCheckType->mTypeInfoEx != NULL) && (curCheckType->mTypeInfoEx->mUsingFieldData != NULL))
  5424. _CheckUsingData(curCheckType->mTypeInfoEx->mUsingFieldData);
  5425. if (!foundLists.IsEmpty())
  5426. {
  5427. auto foundList = foundLists[0];
  5428. if (foundLists.mSize > 1)
  5429. {
  5430. BfError* error = mModule->Fail("Ambiguous 'using' field reference", targetSrc);
  5431. if (error != NULL)
  5432. {
  5433. for (auto checkList : foundLists)
  5434. {
  5435. String errorStr = "'";
  5436. for (int entryIdx = 0; entryIdx < checkList->mSize; entryIdx++)
  5437. {
  5438. if (entryIdx == 0)
  5439. errorStr += (*checkList)[entryIdx].GetFullName(mModule);
  5440. else
  5441. {
  5442. errorStr += ".";
  5443. errorStr += (*checkList)[entryIdx].GetName(mModule);
  5444. }
  5445. }
  5446. errorStr += "' is a candidate";
  5447. mModule->mCompiler->mPassInstance->MoreInfo(errorStr, (*checkList)[0].GetRefNode(mModule));
  5448. }
  5449. }
  5450. }
  5451. BfTypedValue curResult = target;
  5452. for (int entryIdx = 0; entryIdx < foundList->mSize; entryIdx++)
  5453. {
  5454. if ((entryIdx == 0) && (foundList->back().IsStatic()))
  5455. entryIdx = (int)foundList->mSize - 1;
  5456. auto& entry = (*foundList)[entryIdx];
  5457. if (mPropDef != NULL)
  5458. {
  5459. SetAndRestoreValue<BfTypedValue> prevResult(mResult, BfTypedValue());
  5460. mPropGetMethodFlags = (BfGetMethodInstanceFlags)(mPropGetMethodFlags | BfGetMethodInstanceFlag_Friend);
  5461. curResult = GetResult();
  5462. if (!curResult)
  5463. return curResult;
  5464. }
  5465. auto useFlags = flags;
  5466. if (entryIdx < foundList->mSize - 1)
  5467. useFlags = (BfLookupFieldFlags)(flags | BfLookupFieldFlag_IsAnonymous);
  5468. if (entry.mKind == BfUsingFieldData::MemberRef::Kind_Field)
  5469. {
  5470. curResult = LoadField(targetSrc, curResult, entry.mTypeInstance, entry.mTypeInstance->mTypeDef->mFields[entry.mIdx], useFlags);
  5471. }
  5472. else if (entry.mKind == BfUsingFieldData::MemberRef::Kind_Property)
  5473. {
  5474. curResult = LoadProperty(targetSrc, curResult, entry.mTypeInstance, entry.mTypeInstance->mTypeDef->mProperties[entry.mIdx], useFlags, BfCheckedKind_NotSet, false);
  5475. }
  5476. else if (entry.mKind == BfUsingFieldData::MemberRef::Kind_Local)
  5477. {
  5478. auto localDef = mModule->mCurMethodState->mLocals[entry.mIdx];
  5479. curResult = LoadLocal(localDef);
  5480. }
  5481. if ((!curResult) && (mPropDef == NULL))
  5482. return curResult;
  5483. if (entryIdx == foundList->mSize - 1)
  5484. {
  5485. auto autoComplete = GetAutoComplete();
  5486. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(targetSrc)))
  5487. autoComplete->SetDefinitionLocation(entry.GetRefNode(mModule));
  5488. if ((autoComplete != NULL) && (autoComplete->CheckFixit(targetSrc)))
  5489. autoComplete->FixitAddFullyQualify(targetSrc, findName, *foundList);
  5490. }
  5491. }
  5492. return curResult;
  5493. }
  5494. }
  5495. if ((!isBaseLookup) && (startCheckType->IsInterface() && (checkInterfaceIdx < (int)startCheckType->mInterfaces.size())))
  5496. {
  5497. curCheckType = startCheckType->mInterfaces[checkInterfaceIdx].mInterfaceType;
  5498. checkInterfaceIdx++;
  5499. }
  5500. else
  5501. {
  5502. isBaseLookup = true;
  5503. curCheckType = curCheckType->mBaseType;
  5504. }
  5505. }
  5506. }
  5507. auto outerTypeDef = mModule->GetOuterType(startCheckType);
  5508. if (outerTypeDef != NULL)
  5509. {
  5510. BfLookupFieldFlags newFlags = BfLookupFieldFlag_CheckingOuter;
  5511. if (((flags & BfLookupFieldFlag_HasInstance) != 0) &&
  5512. ((flags & BfLookupFieldFlag_IsImplicitThis) == 0))
  5513. newFlags = (BfLookupFieldFlags)(newFlags | BfLookupFieldFlag_HasInstance);
  5514. // Check statics in outer type
  5515. return LookupField(targetSrc, BfTypedValue(outerTypeDef), fieldName, newFlags);
  5516. }
  5517. return BfTypedValue();
  5518. }
  5519. void BfExprEvaluator::ResolveArgValues(BfResolvedArgs& resolvedArgs, BfResolveArgsFlags flags)
  5520. {
  5521. static int idx = 0;
  5522. idx++;
  5523. int curIdx = idx;
  5524. if (resolvedArgs.mArguments == NULL)
  5525. return;
  5526. int argCount = (int)resolvedArgs.mArguments->size();
  5527. if ((resolvedArgs.mCommas != NULL) && (resolvedArgs.mCommas->size() != 0) && (resolvedArgs.mCommas->size() >= resolvedArgs.mArguments->size()))
  5528. {
  5529. //mModule->FailAfter("Expression expected", resolvedArgs.mCommas->back());
  5530. argCount++;
  5531. }
  5532. BfAutoComplete* autoComplete = GetAutoComplete();
  5533. bool hadIgnoredFixits = false;
  5534. if (autoComplete != NULL)
  5535. {
  5536. hadIgnoredFixits = autoComplete->mIgnoreFixits;
  5537. if (flags & BfResolveArgsFlag_DeferFixits)
  5538. autoComplete->mIgnoreFixits = true;
  5539. }
  5540. int deferredArgIdx = 0;
  5541. SizedArray<BfExpression*, 8> deferredArgs;
  5542. int argIdx = 0;
  5543. while (true)
  5544. {
  5545. //printf("Args: %p %p %d\n", resolvedArgs.mArguments, resolvedArgs.mArguments->mVals, resolvedArgs.mArguments->mSize);
  5546. BfExpression* argExpr = NULL;
  5547. bool isDeferredArg = false;
  5548. int curArgIdx = -1;
  5549. if (deferredArgIdx < deferredArgs.size())
  5550. {
  5551. argExpr = deferredArgs[deferredArgIdx++];
  5552. isDeferredArg = true;
  5553. }
  5554. else if (argIdx >= argCount)
  5555. {
  5556. break;
  5557. }
  5558. else
  5559. {
  5560. curArgIdx = argIdx++;
  5561. if (curArgIdx < resolvedArgs.mArguments->size())
  5562. argExpr = (*resolvedArgs.mArguments)[curArgIdx];
  5563. }
  5564. if (argExpr == NULL)
  5565. {
  5566. if (curArgIdx == 0)
  5567. {
  5568. if (resolvedArgs.mOpenToken != NULL)
  5569. mModule->FailAfter("Expression expected", resolvedArgs.mOpenToken);
  5570. }
  5571. else if (resolvedArgs.mCommas != NULL)
  5572. mModule->FailAfter("Expression expected", (*resolvedArgs.mCommas)[curArgIdx - 1]);
  5573. }
  5574. if (auto typedValueExpr = BfNodeDynCast<BfTypedValueExpression>(argExpr))
  5575. {
  5576. BfResolvedArg resolvedArg;
  5577. resolvedArg.mTypedValue = typedValueExpr->mTypedValue;
  5578. if (resolvedArg.mTypedValue.IsParams())
  5579. resolvedArg.mArgFlags = BfArgFlag_ParamsExpr;
  5580. resolvedArg.mExpression = typedValueExpr->mRefNode;
  5581. resolvedArgs.mResolvedArgs.push_back(resolvedArg);
  5582. continue;
  5583. }
  5584. BfResolvedArg resolvedArg;
  5585. if (isDeferredArg)
  5586. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_StringInterpolateArg);
  5587. BfExprEvaluator exprEvaluator(mModule);
  5588. exprEvaluator.mResolveGenericParam = (flags & BfResolveArgsFlag_AllowUnresolvedTypes) == 0;
  5589. exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | BfEvalExprFlags_AllowRefExpr | BfEvalExprFlags_AllowOutExpr |
  5590. (mBfEvalExprFlags & (BfEvalExprFlags_Comptime)));
  5591. bool handled = false;
  5592. bool evaluated = false;
  5593. if (auto namedExpression = BfNodeDynCastExact<BfNamedExpression>(argExpr))
  5594. {
  5595. resolvedArg.mNameNode = namedExpression->mNameNode;
  5596. argExpr = namedExpression->mExpression;
  5597. }
  5598. if (auto interpolateExpr = BfNodeDynCastExact<BfStringInterpolationExpression>(argExpr))
  5599. {
  5600. if ((interpolateExpr->mAllocNode == NULL) || ((flags & BfResolveArgsFlag_InsideStringInterpolationAlloc) != 0))
  5601. {
  5602. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_StringInterpolateFormat);
  5603. for (auto innerExpr : interpolateExpr->mExpressions)
  5604. deferredArgs.Add(innerExpr);
  5605. }
  5606. }
  5607. if (auto unaryOpExpr = BfNodeDynCastExact<BfUnaryOperatorExpression>(argExpr))
  5608. {
  5609. if ((unaryOpExpr->mOp == BfUnaryOp_Cascade) && ((flags & BfResolveArgsFlag_FromIndexer) == 0))
  5610. {
  5611. if ((mBfEvalExprFlags & BfEvalExprFlags_InCascade) != 0)
  5612. mModule->Fail("Cascade already specified on call target", unaryOpExpr->mOpToken);
  5613. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_Cascade);
  5614. argExpr = unaryOpExpr->mExpression;
  5615. }
  5616. }
  5617. bool deferParamEval = false;
  5618. if ((flags & BfResolveArgsFlag_DeferParamEval) != 0)
  5619. {
  5620. if (argExpr != NULL)
  5621. {
  5622. BfDeferEvalChecker deferEvalChecker;
  5623. if ((flags & BfResolveArgsFlag_DeferStrings) != 0)
  5624. deferEvalChecker.mDeferStrings = true;
  5625. deferEvalChecker.mDeferDelegateBind = false;
  5626. deferEvalChecker.Check(argExpr);
  5627. deferParamEval = deferEvalChecker.mNeedsDeferEval;
  5628. }
  5629. }
  5630. if (deferParamEval)
  5631. {
  5632. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_DeferredEval);
  5633. handled = true;
  5634. }
  5635. else if (auto delegateBindExpression = BfNodeDynCast<BfDelegateBindExpression>(argExpr))
  5636. {
  5637. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_DelegateBindAttempt);
  5638. handled = true;
  5639. }
  5640. else if (auto lambdaBindExpression = BfNodeDynCast<BfLambdaBindExpression>(argExpr))
  5641. {
  5642. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_LambdaBindAttempt);
  5643. handled = true;
  5644. }
  5645. else if (auto defaultExpr = BfNodeDynCast<BfDefaultExpression>(argExpr))
  5646. {
  5647. if (defaultExpr->mTypeRef == NULL)
  5648. {
  5649. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_UntypedDefault);
  5650. handled = true;
  5651. }
  5652. }
  5653. else if (auto varDeclExpr = BfNodeDynCast<BfVariableDeclaration>(argExpr))
  5654. {
  5655. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_VariableDeclaration);
  5656. handled = true;
  5657. }
  5658. else if (auto unaryExpr = BfNodeDynCast<BfUnaryOperatorExpression>(argExpr))
  5659. {
  5660. if (unaryExpr->mOp == BfUnaryOp_Params)
  5661. {
  5662. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_ParamsExpr);
  5663. }
  5664. }
  5665. else if (auto uninitExpr = BfNodeDynCast<BfUninitializedExpression>(argExpr))
  5666. {
  5667. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_UninitializedExpr);
  5668. handled = true;
  5669. }
  5670. if (!handled)
  5671. {
  5672. BfAstNode* checkArgExpr = argExpr;
  5673. while (checkArgExpr != NULL)
  5674. {
  5675. if (auto memberRef = BfNodeDynCast<BfMemberReferenceExpression>(checkArgExpr))
  5676. {
  5677. if (memberRef->mTarget == NULL)
  5678. {
  5679. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_UnqualifiedDotAttempt);
  5680. handled = true;
  5681. break;
  5682. }
  5683. else
  5684. checkArgExpr = memberRef->mTarget;
  5685. }
  5686. else if (auto invokeExpr = BfNodeDynCast<BfInvocationExpression>(checkArgExpr))
  5687. {
  5688. checkArgExpr = invokeExpr->mTarget;
  5689. }
  5690. else if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(checkArgExpr))
  5691. {
  5692. checkArgExpr = parenExpr->mExpression;
  5693. }
  5694. else
  5695. break;
  5696. }
  5697. }
  5698. if ((argExpr != NULL) && (!handled))
  5699. {
  5700. bool deferParamValues = (flags & BfResolveArgsFlag_DeferParamValues) != 0;
  5701. SetAndRestoreValue<bool> ignoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, mModule->mBfIRBuilder->mIgnoreWrites || deferParamValues);
  5702. auto prevInsertBlock = mModule->mBfIRBuilder->GetInsertBlock();
  5703. if (deferParamValues)
  5704. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_DeferredValue);
  5705. if (!evaluated)
  5706. {
  5707. exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | BfEvalExprFlags_AllowParamsExpr);
  5708. if ((resolvedArg.mArgFlags & BfArgFlag_StringInterpolateFormat) != 0)
  5709. exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | BfEvalExprFlags_StringInterpolateFormat);
  5710. int lastLocalVarIdx = (mModule->mCurMethodState != NULL) ? mModule->mCurMethodState->mLocals.mSize : 0;
  5711. exprEvaluator.Evaluate(argExpr, false, false, true);
  5712. if ((deferParamValues) && (mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mLocals.mSize > lastLocalVarIdx))
  5713. {
  5714. // Remove any ignored locals
  5715. mModule->RestoreScoreState_LocalVariables(lastLocalVarIdx);
  5716. }
  5717. }
  5718. if ((mModule->mCurMethodState != NULL) && (exprEvaluator.mResultLocalVar != NULL) && (exprEvaluator.mResultLocalVarRefNode != NULL))
  5719. {
  5720. auto localVar = exprEvaluator.mResultLocalVar;
  5721. int fieldIdx = mResultLocalVarField - 1;
  5722. auto methodState = mModule->mCurMethodState->GetMethodStateForLocal(localVar);
  5723. if (localVar->mCompositeCount >= 0)
  5724. {
  5725. if ((resolvedArg.mArgFlags & BfArgFlag_ParamsExpr) != 0)
  5726. {
  5727. for (int compositeIdx = 0; compositeIdx < localVar->mCompositeCount; compositeIdx++)
  5728. {
  5729. BfResolvedArg compositeResolvedArg;
  5730. auto compositeLocalVar = methodState->mLocals[localVar->mLocalVarIdx + compositeIdx + 1];
  5731. auto argValue = exprEvaluator.LoadLocal(compositeLocalVar, true);
  5732. if (argValue)
  5733. {
  5734. if (!argValue.mType->IsStruct())
  5735. argValue = mModule->LoadValue(argValue, NULL, exprEvaluator.mIsVolatileReference);
  5736. }
  5737. resolvedArg.mTypedValue = argValue;
  5738. resolvedArg.mExpression = argExpr;
  5739. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_FromParamComposite);
  5740. resolvedArgs.mResolvedArgs.push_back(resolvedArg);
  5741. exprEvaluator.mIsVolatileReference = false;
  5742. }
  5743. if ((localVar->mResolvedType->IsModifiedTypeType()) && (((BfModifiedTypeType*)localVar->mResolvedType)->mModifiedKind == BfToken_Params))
  5744. {
  5745. // Is a 'params'
  5746. }
  5747. else
  5748. continue;
  5749. }
  5750. else
  5751. exprEvaluator.mResult = mModule->LoadOrAggregateValue(exprEvaluator.mResult);
  5752. }
  5753. }
  5754. exprEvaluator.CheckResultForReading(exprEvaluator.mResult);
  5755. auto argValue = exprEvaluator.mResult;
  5756. if (argValue)
  5757. {
  5758. mModule->mBfIRBuilder->PopulateType(argValue.mType);
  5759. resolvedArg.mResolvedType = argValue.mType;
  5760. if (resolvedArg.mResolvedType->IsRef())
  5761. argValue.mKind = BfTypedValueKind_Value;
  5762. if (exprEvaluator.mIsVolatileReference)
  5763. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_Volatile);
  5764. }
  5765. resolvedArg.mUncastedTypedValue = argValue;
  5766. resolvedArg.mTypedValue = argValue;
  5767. if (deferParamValues)
  5768. mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock);
  5769. }
  5770. resolvedArg.mExpression = argExpr;
  5771. resolvedArgs.mResolvedArgs.push_back(resolvedArg);
  5772. }
  5773. if (autoComplete != NULL)
  5774. autoComplete->mIgnoreFixits = hadIgnoredFixits;
  5775. }
  5776. void BfExprEvaluator::PerformCallChecks(BfMethodInstance* methodInstance, BfAstNode* targetSrc)
  5777. {
  5778. BfCustomAttributes* customAttributes = methodInstance->GetCustomAttributes();
  5779. if (customAttributes != NULL)
  5780. mModule->CheckErrorAttributes(methodInstance->GetOwner(), methodInstance, NULL, customAttributes, targetSrc);
  5781. }
  5782. void BfExprEvaluator::CheckSkipCall(BfAstNode* targetSrc, SizedArrayImpl<BfResolvedArg>& argValues)
  5783. {
  5784. for (auto& argValue : argValues)
  5785. {
  5786. if ((!argValue.IsDeferredValue()) && (argValue.mExpression != NULL))
  5787. {
  5788. mModule->Fail("Illegal SkipCall invocation", targetSrc);
  5789. return;
  5790. }
  5791. }
  5792. }
  5793. BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* methodInstance, BfIRValue func, bool bypassVirtual, SizedArrayImpl<BfIRValue>& irArgs, BfTypedValue* sret, BfCreateCallFlags callFlags, BfType* origTargetType)
  5794. {
  5795. // static int sCallIdx = 0;
  5796. // if (!mModule->mCompiler->mIsResolveOnly)
  5797. // sCallIdx++;
  5798. // int callIdx = sCallIdx;
  5799. // if (callIdx == 0x000000E8)
  5800. // {
  5801. // NOP;
  5802. // }
  5803. bool isDelegateThunk = ((callFlags & (BfCreateCallFlags_DelegateThunkNonStatic | BfCreateCallFlags_DelegateThunkStatic)) != 0);
  5804. auto methodDef = methodInstance->mMethodDef;
  5805. BfIRValue funcCallInst = func;
  5806. auto importCallKind = methodInstance->GetImportCallKind();
  5807. if ((funcCallInst) && (importCallKind != BfImportCallKind_None))
  5808. {
  5809. if ((funcCallInst.IsFake()) && (!mModule->mBfIRBuilder->mIgnoreWrites))
  5810. {
  5811. mModule->mFuncReferences.TryGetValue(methodInstance, &funcCallInst);
  5812. }
  5813. if ((importCallKind == BfImportCallKind_GlobalVar) &&
  5814. (methodInstance->mHotMethod == NULL) &&
  5815. (mModule->mCompiler->IsHotCompile()))
  5816. {
  5817. // This may actually be a BfImportCallKind_GlobalVar_Hot, so check it...
  5818. mModule->CheckHotMethod(methodInstance, "");
  5819. importCallKind = methodInstance->GetImportCallKind();
  5820. }
  5821. if (importCallKind == BfImportCallKind_GlobalVar_Hot)
  5822. {
  5823. //TODO: Check against NULL for calling BfLoadSharedLibraries
  5824. auto checkVal = mModule->mBfIRBuilder->CreateLoad(funcCallInst);
  5825. BfIRBlock nullBlock = mModule->mBfIRBuilder->CreateBlock("importNull");
  5826. BfIRBlock doneBlock = mModule->mBfIRBuilder->CreateBlock("importLoad");
  5827. auto condVal = mModule->mBfIRBuilder->CreateIsNull(checkVal);
  5828. mModule->mBfIRBuilder->CreateCondBr(condVal, nullBlock, doneBlock);
  5829. mModule->mBfIRBuilder->AddBlock(nullBlock);
  5830. mModule->mBfIRBuilder->SetInsertPoint(nullBlock);
  5831. auto loadSharedLibsFunc = mModule->GetBuiltInFunc(BfBuiltInFuncType_LoadSharedLibraries);
  5832. mModule->mBfIRBuilder->CreateCall(loadSharedLibsFunc, SizedArray<BfIRValue, 0>());
  5833. mModule->mBfIRBuilder->CreateBr(doneBlock);
  5834. mModule->mBfIRBuilder->AddBlock(doneBlock);
  5835. mModule->mBfIRBuilder->SetInsertPoint(doneBlock);
  5836. funcCallInst = mModule->mBfIRBuilder->CreateLoad(funcCallInst);
  5837. }
  5838. else
  5839. {
  5840. funcCallInst = mModule->mBfIRBuilder->CreateLoad(funcCallInst);
  5841. }
  5842. }
  5843. if ((methodInstance->GetOwner()->IsInstanceOf(mModule->mCompiler->mDeferredCallTypeDef)) &&
  5844. (methodInstance->mMethodDef->mName == "Cancel"))
  5845. {
  5846. if (mModule->mCurMethodState != NULL)
  5847. mModule->mCurMethodState->mCancelledDeferredCall = true;
  5848. }
  5849. if ((methodDef->mIsNoReturn) && ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) == 0))
  5850. {
  5851. mModule->mCurMethodState->SetHadReturn(true);
  5852. mModule->mCurMethodState->mLeftBlockUncond = true;
  5853. mModule->MarkScopeLeft(&mModule->mCurMethodState->mHeadScope, true);
  5854. }
  5855. if (mModule->mCurTypeInstance != NULL)
  5856. {
  5857. bool isVirtual = (methodInstance->mVirtualTableIdx != -1) && (!bypassVirtual);
  5858. mModule->AddDependency(methodInstance->mMethodInstanceGroup->mOwner, mModule->mCurTypeInstance, isVirtual ? BfDependencyMap::DependencyFlag_VirtualCall : BfDependencyMap::DependencyFlag_Calls);
  5859. mModule->AddCallDependency(methodInstance, bypassVirtual);
  5860. }
  5861. if (methodInstance->GetOwner()->IsUnspecializedType())
  5862. {
  5863. BF_ASSERT((!methodInstance->mIRFunction) || (methodInstance == mModule->mCurMethodInstance) || (methodInstance->mMethodDef->mIsLocalMethod));
  5864. }
  5865. if (mFunctionBindResult != NULL)
  5866. {
  5867. BF_ASSERT(mFunctionBindResult->mMethodInstance == NULL);
  5868. mFunctionBindResult->mMethodInstance = methodInstance;
  5869. for (auto arg : irArgs)
  5870. mFunctionBindResult->mIRArgs.push_back(arg);
  5871. }
  5872. BfType* origReturnType = methodInstance->mReturnType;
  5873. /*if (origReturnType->IsSelf())
  5874. {
  5875. origReturnType = methodInstance->GetOwner();
  5876. BF_ASSERT(origReturnType->IsInterface());
  5877. }*/
  5878. BfType* returnType = origReturnType;
  5879. BfTypedValue sretVal;
  5880. auto _GetDefaultReturnValue = [&]()
  5881. {
  5882. if (methodInstance->mVirtualTableIdx == -1)
  5883. {
  5884. if (methodInstance->GetOwner()->IsInterface())
  5885. {
  5886. // We're attempting to directly invoke a non-virtual interface method, if we're return an interface then
  5887. // it is a concrete interface
  5888. if (returnType->IsInterface())
  5889. returnType = mModule->CreateConcreteInterfaceType(returnType->ToTypeInstance());
  5890. }
  5891. }
  5892. if ((returnType->IsVar()) && (mExpectingType != NULL))
  5893. returnType = mExpectingType;
  5894. if (returnType->IsRef())
  5895. {
  5896. auto result = mModule->GetDefaultTypedValue(returnType->GetUnderlyingType(), true, BfDefaultValueKind_Addr);
  5897. if (methodDef->mIsReadOnly)
  5898. result.mKind = BfTypedValueKind_ReadOnlyAddr;
  5899. return result;
  5900. }
  5901. else
  5902. {
  5903. auto val = mModule->GetDefaultTypedValue(returnType, true, (GetStructRetIdx(methodInstance) != -1) ? BfDefaultValueKind_Addr : BfDefaultValueKind_Value);
  5904. if (val.mKind == BfTypedValueKind_Addr)
  5905. val.mKind = BfTypedValueKind_RestrictedTempAddr;
  5906. return val;
  5907. }
  5908. };
  5909. mModule->PopulateType(origReturnType, BfPopulateType_Data);
  5910. if ((GetStructRetIdx(methodInstance) != -1) && (!isDelegateThunk))
  5911. {
  5912. // We need to ensure that mReceivingValue has the correct type, otherwise it's possible that a conversion operator needs to be applied
  5913. // This happens for returning Result<T>'s with a 'T' value
  5914. if ((sret == NULL) && (mReceivingValue != NULL) && (mReceivingValue->mType == returnType))
  5915. {
  5916. sretVal = *mReceivingValue;
  5917. sret = &sretVal;
  5918. auto ptrType = mModule->CreatePointerType(returnType);
  5919. if (returnType != sret->mType)
  5920. {
  5921. sret->mValue = mModule->mBfIRBuilder->CreateBitCast(sret->mValue, mModule->mBfIRBuilder->MapType(ptrType));
  5922. sret->mType = returnType;
  5923. }
  5924. mReceivingValue = NULL;
  5925. }
  5926. if (sret == NULL)
  5927. {
  5928. sretVal = BfTypedValue(mModule->CreateAlloca(returnType), returnType, BfTypedValueKind_RestrictedTempAddr);
  5929. sret = &sretVal;
  5930. }
  5931. }
  5932. else
  5933. {
  5934. BF_ASSERT(sret == NULL);
  5935. }
  5936. if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mCapturing))
  5937. {
  5938. if ((methodInstance->mComptimeFlags & BfComptimeFlag_ConstEval) != 0)
  5939. {
  5940. // We need to perform call such as Compiler.Mixin and String.ConstF
  5941. }
  5942. else
  5943. return _GetDefaultReturnValue();
  5944. }
  5945. BF_ASSERT(!methodInstance->mDisallowCalling);
  5946. if ((mModule->mCompiler->mResolvePassData != NULL) && (mModule->mCompiler->mResolvePassData->mAutoComplete != NULL))
  5947. {
  5948. bool wantQuickEval = true;
  5949. if (IsComptime())
  5950. {
  5951. auto autoComplete = mModule->mCompiler->mResolvePassData->mAutoComplete;
  5952. wantQuickEval =
  5953. ((autoComplete->mResolveType != BfResolveType_Autocomplete) &&
  5954. (autoComplete->mResolveType != BfResolveType_Autocomplete_HighPri) &&
  5955. (autoComplete->mResolveType != BfResolveType_GetResultString));
  5956. for (auto& entry : mModule->mCompiler->mResolvePassData->mEmitEmbedEntries)
  5957. {
  5958. if (entry.mValue.mCursorIdx >= 0)
  5959. {
  5960. // Needed for Go To Definition in Compiler.Mixin
  5961. wantQuickEval = false;
  5962. }
  5963. }
  5964. }
  5965. if (wantQuickEval)
  5966. {
  5967. // In an autocomplete pass we may have stale method references that need to be resolved
  5968. // in the full classify pass, and in the full classify pass while just refreshing internals, we
  5969. // may have NULL funcs temporarily. We simply skip generating the method call here.
  5970. if ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0)
  5971. {
  5972. if (methodInstance->mReturnType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef))
  5973. {
  5974. if ((mExpectingType != NULL) && (mExpectingType->IsSizedArray()))
  5975. {
  5976. return BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->MapType(mExpectingType)), mExpectingType);
  5977. }
  5978. }
  5979. auto returnType = methodInstance->mReturnType;
  5980. if ((returnType->IsVar()) && (mExpectingType != NULL))
  5981. returnType = mExpectingType;
  5982. if (methodInstance->mReturnType->IsValuelessType())
  5983. return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), returnType);
  5984. return BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->MapType(returnType)), returnType);
  5985. }
  5986. BfTypedValue result;
  5987. if (sret != NULL)
  5988. result = *sret;
  5989. else
  5990. result = _GetDefaultReturnValue();
  5991. return result;
  5992. }
  5993. }
  5994. bool forceBind = false;
  5995. if (mModule->mCompiler->mCeMachine != NULL)
  5996. {
  5997. bool doConstReturn = false;
  5998. if ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0)
  5999. {
  6000. if (mFunctionBindResult != NULL)
  6001. {
  6002. forceBind = true;
  6003. }
  6004. else if ((mBfEvalExprFlags & BfEvalExprFlags_InCascade) != 0)
  6005. {
  6006. mModule->Fail("Const evaluation not allowed with cascade operator", targetSrc);
  6007. }
  6008. else if (((methodInstance->mComptimeFlags & BfComptimeFlag_OnlyFromComptime) != 0) && (!mModule->mIsComptimeModule))
  6009. {
  6010. // This either generated an error already or this is just the non-const type check pass for a comptime-only method
  6011. doConstReturn = true;
  6012. }
  6013. else if ((mBfEvalExprFlags & BfEvalExprFlags_DisallowComptime) != 0)
  6014. {
  6015. doConstReturn = true;
  6016. }
  6017. else if (((callFlags & BfCreateCallFlags_GenericParamThis) != 0) && (methodInstance->GetOwner()->IsInterface()))
  6018. {
  6019. mModule->Warn(0, "Concrete method may fail to comptime during specialization", targetSrc);
  6020. doConstReturn = true;
  6021. }
  6022. else if (methodDef->mIsVirtual)
  6023. {
  6024. // This could only really be the case for a Type, since no other 'this' could qualify as const
  6025. }
  6026. else
  6027. {
  6028. CeEvalFlags evalFlags = CeEvalFlags_None;
  6029. if ((mBfEvalExprFlags & BfEvalExprFlags_NoCeRebuildFlags) != 0)
  6030. evalFlags = (CeEvalFlags)(evalFlags | CeEvalFlags_NoRebuild);
  6031. if ((mModule->mIsComptimeModule) && (mModule->mCompiler->mCeMachine->mDebugger != NULL) && (mModule->mCompiler->mCeMachine->mDebugger->mCurDbgState != NULL))
  6032. {
  6033. auto ceDbgState = mModule->mCompiler->mCeMachine->mDebugger->mCurDbgState;
  6034. if ((ceDbgState->mDbgExpressionFlags & DwEvalExpressionFlag_AllowCalls) != 0)
  6035. {
  6036. ceDbgState->mHadSideEffects = true;
  6037. //SetAndRestoreValue<CeDebugger*> prevDebugger(mModule->mCompiler->mCeMachine->mDebugger, NULL);
  6038. evalFlags = (CeEvalFlags)(evalFlags | CeEvalFlags_DbgCall);
  6039. auto result = ceDbgState->mCeContext->Call(targetSrc, mModule, methodInstance, irArgs, evalFlags, mExpectingType);
  6040. if (result)
  6041. return result;
  6042. }
  6043. else
  6044. {
  6045. ceDbgState->mBlockedSideEffects = true;
  6046. }
  6047. }
  6048. else
  6049. {
  6050. CeCallSource ceCallSource(targetSrc);
  6051. ceCallSource.mOrigCalleeType = origTargetType;
  6052. auto constRet = mModule->mCompiler->mCeMachine->Call(ceCallSource, mModule, methodInstance, irArgs, evalFlags, mExpectingType);
  6053. if (constRet)
  6054. {
  6055. auto constant = mModule->mBfIRBuilder->GetConstant(constRet.mValue);
  6056. BF_ASSERT(!constRet.mType->IsVar());
  6057. return constRet;
  6058. }
  6059. if (mModule->mCompiler->mFastFinish)
  6060. {
  6061. if ((mModule->mCurMethodInstance == NULL) || (!mModule->mCurMethodInstance->mIsAutocompleteMethod))
  6062. {
  6063. // We didn't properly resolve this so queue for a rebuild later
  6064. mModule->DeferRebuildType(mModule->mCurTypeInstance);
  6065. }
  6066. }
  6067. doConstReturn = true;
  6068. }
  6069. }
  6070. }
  6071. else if (mModule->mIsComptimeModule)
  6072. {
  6073. //TODO: This meant that unspecialized types were not even allowed to have Init methods that called into themselves
  6074. // if (methodInstance->mIsUnspecialized)
  6075. // {
  6076. // doConstReturn = true;
  6077. // }
  6078. // else
  6079. {
  6080. mModule->mCompiler->mCeMachine->QueueMethod(methodInstance, func);
  6081. }
  6082. }
  6083. if (doConstReturn)
  6084. {
  6085. if ((returnType->IsVar()) && (mExpectingType != NULL))
  6086. returnType = mExpectingType;
  6087. if (returnType->IsRef())
  6088. {
  6089. return _GetDefaultReturnValue();
  6090. }
  6091. else
  6092. {
  6093. if (returnType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef))
  6094. {
  6095. if ((mExpectingType != NULL) && (mExpectingType->IsUndefSizedArray()))
  6096. {
  6097. if (returnType->GetUnderlyingType() == mExpectingType->GetUnderlyingType())
  6098. return mModule->GetDefaultTypedValue(mExpectingType, true, BfDefaultValueKind_Undef);
  6099. }
  6100. }
  6101. if (methodInstance->mReturnType->IsValuelessType())
  6102. return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), returnType);
  6103. return mModule->GetDefaultTypedValue(returnType, true, BfDefaultValueKind_Undef);
  6104. }
  6105. return _GetDefaultReturnValue();
  6106. }
  6107. }
  6108. if (!forceBind)
  6109. {
  6110. if (((!func) && (methodInstance->mIsUnspecialized)) || (mModule->mBfIRBuilder->mIgnoreWrites))
  6111. {
  6112. // We don't actually submit method calls for unspecialized methods
  6113. // - this includes all methods in unspecialized types
  6114. return _GetDefaultReturnValue();
  6115. }
  6116. }
  6117. if (methodInstance->mVirtualTableIdx != -1)
  6118. {
  6119. if ((!bypassVirtual) && (mDeferCallData == NULL))
  6120. {
  6121. if ((methodDef->mIsOverride) && (mModule->mCurMethodInstance->mIsReified))
  6122. {
  6123. // Ensure that declaring method gets referenced
  6124. auto typeInstance = methodInstance->GetOwner();
  6125. auto& vEntry = typeInstance->mVirtualMethodTable[methodInstance->mVirtualTableIdx];
  6126. BfMethodInstance* declaringMethodInstance = vEntry.mDeclaringMethod;
  6127. if ((declaringMethodInstance->mMethodInstanceGroup->mOnDemandKind < BfMethodOnDemandKind_InWorkList) || (!declaringMethodInstance->mIsReified))
  6128. mModule->GetMethodInstance(declaringMethodInstance);
  6129. }
  6130. auto funcType = mModule->mBfIRBuilder->MapMethod(methodInstance);
  6131. auto funcPtrType1 = mModule->mBfIRBuilder->GetPointerTo(funcType);
  6132. auto funcPtrType2 = mModule->mBfIRBuilder->GetPointerTo(funcPtrType1);
  6133. auto funcPtrType3 = mModule->mBfIRBuilder->GetPointerTo(funcPtrType2);
  6134. auto funcPtrType4 = mModule->mBfIRBuilder->GetPointerTo(funcPtrType3);
  6135. if (methodInstance->mMethodInstanceGroup->mOwner->IsInterface())
  6136. {
  6137. if (mModule->mIsComptimeModule)
  6138. {
  6139. funcCallInst = mModule->mBfIRBuilder->Comptime_GetInterfaceFunc(irArgs[0], methodInstance->mMethodInstanceGroup->mOwner->mTypeId, methodInstance->mMethodDef->mIdx, funcPtrType1);
  6140. }
  6141. else
  6142. {
  6143. // IFace dispatch
  6144. auto ifaceTypeInst = methodInstance->mMethodInstanceGroup->mOwner;
  6145. BfIRValue slotOfs = mModule->GetInterfaceSlotNum(methodInstance->mMethodInstanceGroup->mOwner);
  6146. auto vDataPtrPtr = mModule->mBfIRBuilder->CreateBitCast(irArgs[0], funcPtrType4);
  6147. auto vDataPtr = mModule->FixClassVData(mModule->mBfIRBuilder->CreateLoad(vDataPtrPtr/*, "vtable"*/));
  6148. auto ifacePtrPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(vDataPtr, slotOfs/*, "iface"*/);
  6149. auto ifacePtr = mModule->mBfIRBuilder->CreateLoad(ifacePtrPtr);
  6150. auto funcPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(ifacePtr, methodInstance->mVirtualTableIdx/*, "vfn"*/);
  6151. funcCallInst = mModule->mBfIRBuilder->CreateLoad(funcPtr);
  6152. }
  6153. }
  6154. else if (mModule->mIsComptimeModule)
  6155. {
  6156. funcCallInst = mModule->mBfIRBuilder->Comptime_GetVirtualFunc(irArgs[0], methodInstance->mVirtualTableIdx, funcPtrType1);
  6157. }
  6158. else
  6159. {
  6160. mModule->HadSlotCountDependency();
  6161. // Virtual dispatch
  6162. // int vDataIdx = 0;
  6163. // vDataIdx += 1 + methodInstance->GetOwner()->GetDynCastVDataCount() + mModule->mCompiler->mMaxInterfaceSlots;
  6164. BfIRValue vDataPtr;
  6165. BfIRValue vDataIdx;
  6166. if ((mModule->mCompiler->mOptions.mHasVDataExtender) && (mModule->mCompiler->IsHotCompile()))
  6167. {
  6168. auto typeInst = methodInstance->mMethodInstanceGroup->mOwner;
  6169. int extMethodIdx = (methodInstance->mVirtualTableIdx - typeInst->GetImplBaseVTableSize()) - typeInst->GetOrigSelfVTableSize();
  6170. if (extMethodIdx >= 0)
  6171. {
  6172. BF_ASSERT(mModule->mCompiler->IsHotCompile());
  6173. // We have grown outside our original virtual table, Load the new vdataPtr from the mHasVDataExtender
  6174. // vDataPtr = obj.vtable.extension.entry[curVersion]
  6175. BfIRValue vDataPtrPtr = mModule->mBfIRBuilder->CreateBitCast(irArgs[0], funcPtrType4);
  6176. vDataPtr = mModule->FixClassVData(mModule->mBfIRBuilder->CreateLoad(vDataPtrPtr));
  6177. // The offset of the vExt is one past the base vtable. When a base class extends its virtual table, an entry
  6178. // for that new method is inserted in mVirtualMethodTable (thus increasing the index relative to GetBaseVTableSize()),
  6179. // but the actual written vtable position doesn't change, hence offsetting from GetOrigBaseVTableSize()
  6180. #ifdef _DEBUG
  6181. int vExtIdx = typeInst->GetImplBaseVTableSize();
  6182. BF_ASSERT(typeInst->mVirtualMethodTable[vExtIdx].mDeclaringMethod.mMethodNum == -1); // A type entry with a -1 mMethodNum means it's a vtable ext slot
  6183. #endif
  6184. int vExtOfs = typeInst->GetOrigImplBaseVTableSize();
  6185. vDataIdx = mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, mModule->mCompiler->GetVDataPrefixDataCount() + mModule->mCompiler->GetDynCastVDataCount() + mModule->mCompiler->mMaxInterfaceSlots);
  6186. vDataIdx = mModule->mBfIRBuilder->CreateAdd(vDataIdx, mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, vExtOfs));
  6187. BfIRValue extendPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(vDataPtr, vDataIdx);
  6188. vDataPtr = mModule->mBfIRBuilder->CreateLoad(extendPtr);
  6189. vDataIdx = mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, extMethodIdx);
  6190. }
  6191. else
  6192. {
  6193. // Map this new virtual index back to the original index
  6194. // Find the type instance that declared the original method
  6195. auto declTypeInst = typeInst;
  6196. while (declTypeInst->mBaseType != NULL)
  6197. {
  6198. mModule->PopulateType(declTypeInst->mBaseType, BfPopulateType_DataAndMethods);
  6199. if (methodInstance->mVirtualTableIdx >= declTypeInst->mBaseType->mVirtualMethodTableSize)
  6200. break;
  6201. BF_ASSERT(methodInstance->mMethodDef->mIsOverride);
  6202. declTypeInst = declTypeInst->mBaseType;
  6203. }
  6204. vDataIdx = mModule->mBfIRBuilder->GetConfigConst(BfIRConfigConst_VirtualMethodOfs, BfTypeCode_Int32);
  6205. vDataIdx = mModule->mBfIRBuilder->CreateAdd(vDataIdx, mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32,
  6206. (methodInstance->mVirtualTableIdx - declTypeInst->GetImplBaseVTableSize()) + declTypeInst->GetOrigImplBaseVTableSize()));
  6207. }
  6208. }
  6209. else
  6210. {
  6211. vDataIdx = mModule->mBfIRBuilder->GetConfigConst(BfIRConfigConst_VirtualMethodOfs, BfTypeCode_Int32);
  6212. vDataIdx = mModule->mBfIRBuilder->CreateAdd(vDataIdx, mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, methodInstance->mVirtualTableIdx));
  6213. }
  6214. if (!vDataPtr)
  6215. {
  6216. BfIRValue vDataPtrPtr = mModule->mBfIRBuilder->CreateBitCast(irArgs[0], funcPtrType3);
  6217. vDataPtr = mModule->FixClassVData(mModule->mBfIRBuilder->CreateLoad(vDataPtrPtr/*, "vtable"*/));
  6218. }
  6219. auto funcPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(vDataPtr, vDataIdx/*, "vfn"*/);
  6220. funcCallInst = mModule->mBfIRBuilder->CreateLoad(funcPtr);
  6221. }
  6222. }
  6223. }
  6224. else // non-virtual
  6225. {
  6226. if (methodInstance->GetOwner()->IsInterface())
  6227. {
  6228. // We're attempting to directly invoke a non-virtual interface method, this will happen during the unspecialized pass
  6229. // OR if we had an error and didn't find an implementing member in the actual target
  6230. if (((mModule->mCurMethodInstance == NULL) || (!mModule->mCurMethodInstance->mIsUnspecialized)) &&
  6231. (!mModule->mCurTypeInstance->IsInterface()))
  6232. mModule->AssertErrorState();
  6233. if (returnType->IsInterface())
  6234. returnType = mModule->CreateConcreteInterfaceType(returnType->ToTypeInstance());
  6235. return _GetDefaultReturnValue();
  6236. }
  6237. }
  6238. if (mFunctionBindResult != NULL)
  6239. {
  6240. mFunctionBindResult->mFunc = funcCallInst;
  6241. if (irArgs.size() != 0)
  6242. {
  6243. auto targetType = methodInstance->mMethodInstanceGroup->mOwner;
  6244. if ((targetType->IsValueType()) && (targetType->IsSplattable()) && (!methodDef->HasNoThisSplat()) && (!IsComptime()))
  6245. mFunctionBindResult->mTarget = BfTypedValue(irArgs[0], targetType, BfTypedValueKind_SplatHead);
  6246. else
  6247. mFunctionBindResult->mTarget = BfTypedValue(irArgs[0], targetType, targetType->IsComposite() ? BfTypedValueKind_Addr : BfTypedValueKind_Value);
  6248. }
  6249. else
  6250. {
  6251. mFunctionBindResult->mTarget = BfTypedValue();
  6252. }
  6253. return BfTypedValue();
  6254. }
  6255. if (methodInstance->mReturnType == NULL)
  6256. {
  6257. mModule->AssertErrorState();
  6258. return BfTypedValue();
  6259. }
  6260. if (((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsUnspecialized)) && (mModule->mBfIRBuilder->mIgnoreWrites))
  6261. {
  6262. // Don't actually do the call - our target may be a generic param
  6263. return _GetDefaultReturnValue();
  6264. }
  6265. if (mDeferCallData != NULL)
  6266. {
  6267. if ((func) && (mDeferCallData->mFuncAlloca_Orig == func))
  6268. mModule->AddDeferredCall(BfModuleMethodInstance(methodInstance, mDeferCallData->mFuncAlloca), irArgs, mDeferCallData->mScopeAlloc, mDeferCallData->mRefNode, bypassVirtual, false, true);
  6269. else
  6270. mModule->AddDeferredCall(BfModuleMethodInstance(methodInstance, func), irArgs, mDeferCallData->mScopeAlloc, mDeferCallData->mRefNode, bypassVirtual);
  6271. return mModule->GetFakeTypedValue(returnType);
  6272. }
  6273. if (!funcCallInst)
  6274. {
  6275. if ((mModule->HasCompiledOutput()) || (mModule->mCompiler->mOptions.mExtraResolveChecks))
  6276. {
  6277. // This can happen either from an error, or from the resolver while doing Internals_Changed processing
  6278. mModule->AssertErrorState();
  6279. }
  6280. return _GetDefaultReturnValue();
  6281. }
  6282. bool hasResult = !methodInstance->mReturnType->IsValuelessType();
  6283. BfIRValue firstArg;
  6284. if (irArgs.size() != 0)
  6285. firstArg = irArgs[0];
  6286. auto methodInstOwner = methodInstance->GetOwner();
  6287. auto expectCallingConvention = mModule->GetIRCallingConvention(methodInstance);
  6288. if ((methodInstOwner->IsFunction()) && (methodInstance->GetParamCount() > 0) && (methodInstance->GetParamName(0) == "this"))
  6289. {
  6290. auto paramType = methodInstance->GetParamType(0);
  6291. if (!paramType->IsValueType())
  6292. expectCallingConvention = BfIRCallingConv_ThisCall;
  6293. }
  6294. if (((callFlags & BfCreateCallFlags_DelegateThunkStatic) != 0) && (expectCallingConvention == BfIRCallingConv_ThisCall))
  6295. expectCallingConvention = BfIRCallingConv_CDecl;
  6296. if ((methodInstance->mAlwaysInline) && (mModule->mCompiler->mOptions.mEmitLineInfo))
  6297. {
  6298. // Emit a NOP so we always have a "step over" point
  6299. mModule->EmitEnsureInstructionAt();
  6300. }
  6301. if (returnType->IsComposite())
  6302. mModule->mBfIRBuilder->PopulateType(returnType);
  6303. methodInstance->mMethodInstanceGroup->mHasEmittedReference = true;
  6304. BfIRValue callInst;
  6305. int callIRArgCount = (int)irArgs.size();
  6306. if (sret != NULL)
  6307. {
  6308. SizedArray<BfIRValue, 8> sretIRArgs;
  6309. int sretIdx = GetStructRetIdx(methodInstance);
  6310. int inIdx = 0;
  6311. for (int outIdx = 0; outIdx < irArgs.size() + 1; outIdx++)
  6312. {
  6313. if (outIdx == sretIdx)
  6314. {
  6315. sretIRArgs.Add(sret->mValue);
  6316. continue;
  6317. }
  6318. sretIRArgs.Add(irArgs[inIdx++]);
  6319. }
  6320. callInst = mModule->mBfIRBuilder->CreateCall(funcCallInst, sretIRArgs);
  6321. callIRArgCount++;
  6322. }
  6323. else
  6324. {
  6325. callInst = mModule->mBfIRBuilder->CreateCall(funcCallInst, irArgs);
  6326. if ((hasResult) && (!methodDef->mName.IsEmpty()) && (!methodInstance->mIsIntrinsic))
  6327. mModule->mBfIRBuilder->SetName(callInst, methodDef->mName);
  6328. }
  6329. if ((expectCallingConvention != BfIRCallingConv_CDecl) && (!methodInstance->mIsIntrinsic))
  6330. mModule->mBfIRBuilder->SetCallCallingConv(callInst, expectCallingConvention);
  6331. if ((methodDef->mIsNoReturn) && (!methodInstance->mIsIntrinsic))
  6332. mModule->mBfIRBuilder->Call_AddAttribute(callInst, -1, BfIRAttribute_NoReturn);
  6333. bool hadAttrs = false;
  6334. int paramIdx = 0;
  6335. bool doingThis = methodInstance->HasThis();
  6336. int argIdx = 0;
  6337. if ((callFlags & BfCreateCallFlags_DelegateThunkStatic) != 0)
  6338. doingThis = false;
  6339. bool forceThisPtr = ((callFlags & BfCreateCallFlags_DelegateThunkNonStatic) != 0);
  6340. if (methodDef->mHasExplicitThis)
  6341. paramIdx++;
  6342. int paramCount = methodInstance->GetParamCount();
  6343. for ( ; argIdx < callIRArgCount ; )
  6344. {
  6345. if (methodInstance->mIsIntrinsic)
  6346. break;
  6347. if ((sret != NULL) && (argIdx == GetStructRetIdx(methodInstance)))
  6348. {
  6349. mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_StructRet);
  6350. argIdx++;
  6351. continue;
  6352. }
  6353. auto _HandleParamType = [&] (BfType* paramType)
  6354. {
  6355. if (paramType->IsStruct())
  6356. {
  6357. if ((!doingThis) || (!methodDef->mIsMutating && methodInstance->AllowsSplatting(paramIdx)))
  6358. {
  6359. BfTypeCode loweredTypeCode = BfTypeCode_None;
  6360. BfTypeCode loweredTypeCode2 = BfTypeCode_None;
  6361. if (paramType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2))
  6362. {
  6363. argIdx++;
  6364. if (loweredTypeCode2 != BfTypeCode_None)
  6365. argIdx++;
  6366. return; // Lowering never requires attributes
  6367. }
  6368. }
  6369. }
  6370. int addDeref = -1;
  6371. if (paramType->IsRef())
  6372. {
  6373. auto refType = (BfRefType*)paramType;
  6374. auto elementType = refType->mElementType;
  6375. mModule->PopulateType(elementType, BfPopulateType_Data);
  6376. addDeref = elementType->mSize;
  6377. if ((addDeref <= 0) && (!elementType->IsValuelessType()))
  6378. mModule->AssertErrorState();
  6379. }
  6380. if ((paramType->IsComposite()) && (!paramType->IsTypedPrimitive()))
  6381. {
  6382. if (mModule->mCompiler->mOptions.mAllowStructByVal)
  6383. {
  6384. //byval
  6385. }
  6386. else
  6387. {
  6388. mModule->PopulateType(paramType, BfPopulateType_Data);
  6389. auto typeInst = paramType->ToTypeInstance();
  6390. if ((typeInst != NULL) && (typeInst->mIsCRepr) && (typeInst->IsSplattable()) && (!IsComptime()))
  6391. {
  6392. // We're splatting
  6393. }
  6394. else
  6395. {
  6396. if (doingThis)
  6397. {
  6398. mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_NoCapture);
  6399. addDeref = paramType->mSize;
  6400. }
  6401. else if (methodInstance->WantsStructsAttribByVal(paramType))
  6402. {
  6403. mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_ByVal, mModule->mSystem->mPtrSize);
  6404. }
  6405. }
  6406. }
  6407. }
  6408. else if (paramType->IsPrimitiveType())
  6409. {
  6410. auto primType = (BfPrimitiveType*)paramType;
  6411. if ((primType->mTypeDef->mTypeCode == BfTypeCode_Boolean) && (!methodInstance->mIsIntrinsic))
  6412. mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_ZExt);
  6413. }
  6414. if (addDeref >= 0)
  6415. {
  6416. mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_Dereferencable, addDeref);
  6417. }
  6418. argIdx++;
  6419. };
  6420. BfType* paramType = NULL;
  6421. if (doingThis)
  6422. {
  6423. int thisIdx = methodInstance->GetThisIdx();
  6424. paramType = methodInstance->GetThisType();
  6425. if (paramType->IsValuelessType())
  6426. {
  6427. doingThis = false;
  6428. continue;
  6429. }
  6430. bool isSplatted = methodInstance->GetParamIsSplat(thisIdx) && (!IsComptime()); // (resolvedTypeRef->IsSplattable()) && (!methodDef->mIsMutating);
  6431. if (isSplatted)
  6432. {
  6433. BfTypeUtils::SplatIterate(_HandleParamType, paramType);
  6434. doingThis = false;
  6435. continue;
  6436. }
  6437. else
  6438. _HandleParamType(paramType);
  6439. }
  6440. else
  6441. {
  6442. if (paramIdx >= methodInstance->GetParamCount())
  6443. break;
  6444. paramType = methodInstance->GetParamType(paramIdx);
  6445. BfTypeCode loweredTypeCode = BfTypeCode_None;
  6446. BfTypeCode loweredTypeCode2 = BfTypeCode_None;
  6447. if (paramType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2))
  6448. {
  6449. argIdx++;
  6450. paramIdx++;
  6451. if (loweredTypeCode2 != BfTypeCode_None)
  6452. argIdx++;
  6453. continue;
  6454. }
  6455. if ((paramType->IsValuelessType()) && (!paramType->IsMethodRef()))
  6456. {
  6457. paramIdx++;
  6458. continue;
  6459. }
  6460. if ((methodInstance->GetParamIsSplat(paramIdx)) && (!IsComptime()))
  6461. {
  6462. BfTypeUtils::SplatIterate(_HandleParamType, paramType);
  6463. paramIdx++;
  6464. continue;
  6465. }
  6466. else
  6467. _HandleParamType(methodInstance->GetParamType(paramIdx));
  6468. }
  6469. if (doingThis)
  6470. doingThis = false;
  6471. else
  6472. paramIdx++;
  6473. //argIdx++;
  6474. }
  6475. if ((callFlags & BfCreateCallFlags_TailCall) != 0)
  6476. mModule->mBfIRBuilder->SetTailCall(callInst);
  6477. if (methodDef->mIsNoReturn)
  6478. {
  6479. mModule->mBfIRBuilder->CreateUnreachable();
  6480. // For debuggability when looking back at stack trace
  6481. //mModule->ExtendLocalLifetimes(0);
  6482. if (mModule->IsTargetingBeefBackend())
  6483. {
  6484. auto checkScope = mModule->mCurMethodState->mCurScope;
  6485. while (checkScope != NULL)
  6486. {
  6487. mModule->EmitLifetimeEnds(checkScope);
  6488. checkScope = checkScope->mPrevScope;
  6489. }
  6490. // This 'fake' branch extends lifetimes of outer variable scopes
  6491. if (mModule->mCurMethodState->mIRExitBlock)
  6492. mModule->mBfIRBuilder->CreateBr_Fake(mModule->mCurMethodState->mIRExitBlock);
  6493. }
  6494. }
  6495. else
  6496. {
  6497. if (mModule->mCurMethodState != NULL)
  6498. mModule->mCurMethodState->mMayNeedThisAccessCheck = true;
  6499. }
  6500. if (isDelegateThunk)
  6501. return BfTypedValue(callInst, methodInstance->mReturnType);
  6502. BfTypedValue result;
  6503. if (sret != NULL)
  6504. result = *sret;
  6505. else if (hasResult)
  6506. {
  6507. BfTypeCode loweredRetType = BfTypeCode_None;
  6508. BfTypeCode loweredRetType2 = BfTypeCode_None;
  6509. if ((!IsComptime()) && (methodInstance->GetLoweredReturnType(&loweredRetType, &loweredRetType2)) && (loweredRetType != BfTypeCode_None))
  6510. {
  6511. auto retVal = mModule->CreateAlloca(methodInstance->mReturnType);
  6512. BfIRType loweredIRType = mModule->GetIRLoweredType(loweredRetType, loweredRetType2);
  6513. loweredIRType = mModule->mBfIRBuilder->GetPointerTo(loweredIRType);
  6514. auto castedRetVal = mModule->mBfIRBuilder->CreateBitCast(retVal, loweredIRType);
  6515. mModule->mBfIRBuilder->CreateStore(callInst, castedRetVal);
  6516. result = BfTypedValue(retVal, methodInstance->mReturnType, BfTypedValueKind_RestrictedTempAddr);
  6517. }
  6518. else
  6519. result = BfTypedValue(callInst, methodInstance->mReturnType);
  6520. }
  6521. else
  6522. result = mModule->GetFakeTypedValue(methodInstance->mReturnType);
  6523. if (result.mType->IsRef())
  6524. {
  6525. result = mModule->RemoveRef(result);
  6526. if (methodDef->mIsReadOnly)
  6527. {
  6528. if (result.mKind == BfTypedValueKind_Addr)
  6529. result.mKind = BfTypedValueKind_ReadOnlyAddr;
  6530. }
  6531. }
  6532. return result;
  6533. }
  6534. BfTypedValue BfExprEvaluator::CreateCall(BfMethodMatcher* methodMatcher, BfTypedValue target)
  6535. {
  6536. auto moduleMethodInstance = GetSelectedMethod(*methodMatcher);
  6537. if (moduleMethodInstance.mMethodInstance == NULL)
  6538. return BfTypedValue();
  6539. if ((target) && (target.mType != moduleMethodInstance.mMethodInstance->GetOwner()))
  6540. {
  6541. auto castedTarget = mModule->Cast(methodMatcher->mTargetSrc, target, moduleMethodInstance.mMethodInstance->GetOwner());
  6542. BF_ASSERT(castedTarget);
  6543. target = castedTarget;
  6544. }
  6545. PerformCallChecks(moduleMethodInstance.mMethodInstance, methodMatcher->mTargetSrc);
  6546. BfCreateCallFlags callFlags = BfCreateCallFlags_None;
  6547. if (methodMatcher->mAllowImplicitRef)
  6548. callFlags = (BfCreateCallFlags)(callFlags | BfCreateCallFlags_AllowImplicitRef);
  6549. return CreateCall(methodMatcher->mTargetSrc, target, BfTypedValue(), methodMatcher->mBestMethodDef, moduleMethodInstance, callFlags, methodMatcher->mArguments);
  6550. }
  6551. void BfExprEvaluator::MakeBaseConcrete(BfTypedValue& typedValue)
  6552. {
  6553. if (typedValue.IsBase())
  6554. {
  6555. auto baseType = mModule->mCurTypeInstance->mBaseType;
  6556. if (baseType == NULL)
  6557. baseType = mModule->mContext->mBfObjectType;
  6558. mModule->PopulateType(baseType, BfPopulateType_Data);
  6559. typedValue = mModule->Cast(NULL, typedValue, baseType, BfCastFlags_Explicit);
  6560. }
  6561. }
  6562. void BfExprEvaluator::SplatArgs(BfTypedValue value, SizedArrayImpl<BfIRValue>& irArgs)
  6563. {
  6564. if (value.IsSplat())
  6565. {
  6566. int componentIdx = 0;
  6567. BfTypeUtils::SplatIterate([&](BfType* checkType) { irArgs.push_back(mModule->ExtractSplatValue(value, componentIdx++, checkType)); }, value.mType);
  6568. return;
  6569. }
  6570. mModule->mBfIRBuilder->PopulateType(value.mType);
  6571. std::function<void(BfTypedValue)> checkTypeLambda = [&](BfTypedValue curValue)
  6572. {
  6573. BfType* checkType = curValue.mType;
  6574. if (checkType->IsStruct())
  6575. {
  6576. auto checkTypeInstance = checkType->ToTypeInstance();
  6577. if (checkTypeInstance->mBaseType != NULL)
  6578. mModule->PopulateType(checkTypeInstance->mBaseType);
  6579. if ((checkTypeInstance->mBaseType != NULL) && (!checkTypeInstance->mBaseType->IsValuelessType()))
  6580. {
  6581. BfTypedValue baseValue;
  6582. if (curValue.IsAddr())
  6583. baseValue = BfTypedValue((!curValue.mValue) ? BfIRValue() : mModule->mBfIRBuilder->CreateInBoundsGEP(curValue.mValue, 0, 0), checkTypeInstance->mBaseType, true);
  6584. else
  6585. baseValue = BfTypedValue((!curValue.mValue) ? BfIRValue() : mModule->mBfIRBuilder->CreateExtractValue(curValue.mValue, 0), checkTypeInstance->mBaseType);
  6586. checkTypeLambda(baseValue);
  6587. }
  6588. if (checkTypeInstance->mIsUnion)
  6589. {
  6590. auto unionInnerType = checkTypeInstance->GetUnionInnerType();
  6591. if (!unionInnerType->IsValuelessType())
  6592. {
  6593. BfTypedValue unionValue = mModule->ExtractValue(curValue, NULL, 1);
  6594. checkTypeLambda(unionValue);
  6595. }
  6596. if (checkTypeInstance->IsEnum())
  6597. {
  6598. BfTypedValue dscrValue = mModule->ExtractValue(curValue, NULL, 2);
  6599. checkTypeLambda(dscrValue);
  6600. }
  6601. }
  6602. else
  6603. {
  6604. for (int fieldIdx = 0; fieldIdx < (int)checkTypeInstance->mFieldInstances.size(); fieldIdx++)
  6605. {
  6606. auto fieldInstance = (BfFieldInstance*)&checkTypeInstance->mFieldInstances[fieldIdx];
  6607. if (fieldInstance->mDataIdx >= 0)
  6608. {
  6609. BfTypedValue fieldValue = mModule->ExtractValue(curValue, fieldInstance, fieldInstance->mDataIdx);
  6610. checkTypeLambda(fieldValue);
  6611. }
  6612. }
  6613. }
  6614. }
  6615. else if (checkType->IsMethodRef())
  6616. {
  6617. BF_ASSERT(curValue.IsAddr());
  6618. BfMethodRefType* methodRefType = (BfMethodRefType*)checkType;
  6619. for (int dataIdx = 0; dataIdx < methodRefType->GetCaptureDataCount(); dataIdx++)
  6620. {
  6621. auto checkType = methodRefType->GetCaptureType(dataIdx);
  6622. if (methodRefType->WantsDataPassedAsSplat(dataIdx))
  6623. {
  6624. BF_ASSERT(dataIdx == 0);
  6625. auto ptrType = mModule->CreatePointerType(checkType);
  6626. auto elemPtr = mModule->mBfIRBuilder->CreateBitCast(curValue.mValue, mModule->mBfIRBuilder->MapType(ptrType));
  6627. checkTypeLambda(BfTypedValue(elemPtr, checkType, BfTypedValueKind_Addr));
  6628. //BfTypedValue fieldValue = mModule->ExtractValue(curValue, fieldInstance, fieldInstance->mDataIdx);
  6629. //checkTypeLambda(fieldValue);
  6630. }
  6631. else
  6632. {
  6633. auto elemVal = mModule->mBfIRBuilder->CreateInBoundsGEP(curValue.mValue, 0, dataIdx);
  6634. if (!checkType->IsComposite())
  6635. elemVal = mModule->mBfIRBuilder->CreateLoad(elemVal);
  6636. irArgs.Add(elemVal);
  6637. //irArgs.Add(mModule->ExtractValue(curValue, dataIdx));
  6638. }
  6639. }
  6640. }
  6641. else if (!checkType->IsValuelessType())
  6642. {
  6643. auto loadedVal = mModule->LoadValue(curValue);
  6644. loadedVal = mModule->PrepareConst(loadedVal);
  6645. irArgs.push_back(loadedVal.mValue);
  6646. }
  6647. };
  6648. checkTypeLambda(value);
  6649. }
  6650. void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl<BfIRValue>& irArgs, bool disableSplat, bool disableLowering, bool isIntrinsic, bool createCompositeCopy)
  6651. {
  6652. MakeBaseConcrete(argVal);
  6653. if (IsVar(argVal.mType))
  6654. {
  6655. argVal = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  6656. }
  6657. if (argVal.mType->IsIncomplete())
  6658. mModule->PopulateType(argVal.mType);
  6659. if (argVal.mType->IsValuelessNonOpaqueType())
  6660. return;
  6661. bool wantSplat = false;
  6662. if ((argVal.mType->IsSplattable()) && (!disableSplat) && (!IsComptime()))
  6663. {
  6664. disableLowering = true;
  6665. auto argTypeInstance = argVal.mType->ToTypeInstance();
  6666. if (!disableSplat)
  6667. {
  6668. if ((argTypeInstance != NULL) && (argTypeInstance->mIsCRepr))
  6669. wantSplat = true;
  6670. else if ((int)irArgs.size() + argVal.mType->GetSplatCount() <= mModule->mCompiler->mOptions.mMaxSplatRegs)
  6671. wantSplat = true;
  6672. }
  6673. }
  6674. if (wantSplat)
  6675. {
  6676. SplatArgs(argVal, irArgs);
  6677. }
  6678. else
  6679. {
  6680. if (argVal.mType->IsComposite())
  6681. {
  6682. if ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0)
  6683. {
  6684. // Const eval entry - we want any incoming consts as they are
  6685. }
  6686. else if (isIntrinsic)
  6687. {
  6688. // We can handle composites either by value or not
  6689. }
  6690. else
  6691. argVal = mModule->MakeAddressable(argVal);
  6692. if ((!IsComptime()) && (!disableLowering) && (!isIntrinsic))
  6693. {
  6694. BfTypeCode loweredTypeCode = BfTypeCode_None;
  6695. BfTypeCode loweredTypeCode2 = BfTypeCode_None;
  6696. if (argVal.mType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2))
  6697. {
  6698. BfIRValue argPtrVal = argVal.mValue;
  6699. int loweredSize = mModule->mBfIRBuilder->GetSize(loweredTypeCode) + mModule->mBfIRBuilder->GetSize(loweredTypeCode2);
  6700. if (argVal.mType->mSize < loweredSize)
  6701. {
  6702. auto allocaVal = mModule->CreateAlloca(mModule->GetPrimitiveType(BfTypeCode_UInt8), true, NULL, mModule->GetConstValue(loweredSize));
  6703. mModule->mBfIRBuilder->SetAllocaAlignment(allocaVal,
  6704. BF_MAX(argVal.mType->mAlign,
  6705. BF_MAX(mModule->mBfIRBuilder->GetSize(loweredTypeCode), mModule->mBfIRBuilder->GetSize(loweredTypeCode2))));
  6706. auto castedPtr = mModule->mBfIRBuilder->CreateBitCast(allocaVal, mModule->mBfIRBuilder->MapType(mModule->CreatePointerType(argVal.mType)));
  6707. auto argIRVal = mModule->mBfIRBuilder->CreateAlignedLoad(argVal.mValue, argVal.mType->mAlign);
  6708. mModule->mBfIRBuilder->CreateAlignedStore(argIRVal, castedPtr, argVal.mType->mAlign);
  6709. argPtrVal = castedPtr;
  6710. }
  6711. auto primType = mModule->mBfIRBuilder->GetPrimitiveType(loweredTypeCode);
  6712. auto ptrType = mModule->mBfIRBuilder->GetPointerTo(primType);
  6713. BfIRValue primPtrVal = mModule->mBfIRBuilder->CreateBitCast(argPtrVal, ptrType);
  6714. auto primVal = mModule->mBfIRBuilder->CreateLoad(primPtrVal);
  6715. irArgs.push_back(primVal);
  6716. if (loweredTypeCode2 != BfTypeCode_None)
  6717. {
  6718. auto primType2 = mModule->mBfIRBuilder->GetPrimitiveType(loweredTypeCode2);
  6719. auto ptrType2 = mModule->mBfIRBuilder->GetPointerTo(primType2);
  6720. BfIRValue primPtrVal2;
  6721. if (mModule->mBfIRBuilder->GetSize(loweredTypeCode) < mModule->mBfIRBuilder->GetSize(loweredTypeCode2))
  6722. primPtrVal2 = mModule->mBfIRBuilder->CreateInBoundsGEP(mModule->mBfIRBuilder->CreateBitCast(primPtrVal, ptrType2), 1);
  6723. else
  6724. primPtrVal2 = mModule->mBfIRBuilder->CreateBitCast(mModule->mBfIRBuilder->CreateInBoundsGEP(primPtrVal, 1), ptrType2);
  6725. auto primVal2 = mModule->mBfIRBuilder->CreateLoad(primPtrVal2);
  6726. irArgs.Add(primVal2);
  6727. }
  6728. return;
  6729. }
  6730. }
  6731. if ((createCompositeCopy) && (!argVal.IsTempAddr()))
  6732. {
  6733. // Non-Beef calling conventions require copies of composites
  6734. auto copyAddr = mModule->CreateAlloca(argVal.mType);
  6735. mModule->mBfIRBuilder->CreateStore(mModule->LoadValue(argVal).mValue, copyAddr);
  6736. argVal = BfTypedValue(copyAddr, argVal.mType, BfTypedValueKind_TempAddr);
  6737. }
  6738. }
  6739. else
  6740. argVal = mModule->LoadValue(argVal);
  6741. irArgs.Add(argVal.mValue);
  6742. }
  6743. }
  6744. void BfExprEvaluator::PushThis(BfAstNode* targetSrc, BfTypedValue argVal, BfMethodInstance* methodInstance, SizedArrayImpl<BfIRValue>& irArgs, bool skipMutCheck)
  6745. {
  6746. MakeBaseConcrete(argVal);
  6747. auto methodDef = methodInstance->mMethodDef;
  6748. if (methodInstance->IsSkipCall())
  6749. return;
  6750. if (!argVal)
  6751. {
  6752. //BF_ASSERT(mFunctionBindResult != NULL);
  6753. return;
  6754. }
  6755. if (methodDef->mIsMutating)
  6756. {
  6757. bool checkMut = false;
  6758. if (argVal.mType->IsGenericParam())
  6759. {
  6760. // For capturing mutability
  6761. if (mResultLocalVar != NULL)
  6762. mResultLocalVar->mWrittenToId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++;
  6763. }
  6764. if (((argVal.mType->IsComposite()) || (argVal.mType->IsTypedPrimitive())))
  6765. {
  6766. if (argVal.IsCopyOnMutate())
  6767. argVal = mModule->CopyValue(argVal);
  6768. if ((argVal.IsReadOnly()) || (!argVal.IsAddr()))
  6769. {
  6770. if (!skipMutCheck)
  6771. {
  6772. String err = StrFormat("call mutating method '%s' on", mModule->MethodToString(methodInstance).c_str());
  6773. CheckModifyResult(argVal, targetSrc, err.c_str());
  6774. }
  6775. if (argVal.IsSplat())
  6776. {
  6777. argVal = mModule->AggregateSplat(argVal);
  6778. argVal = mModule->MakeAddressable(argVal);
  6779. }
  6780. }
  6781. else
  6782. {
  6783. if (mResultLocalVar != NULL)
  6784. {
  6785. // When we are capturing, we need to note that we require capturing by reference here
  6786. mResultLocalVar->mWrittenToId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++;
  6787. }
  6788. }
  6789. }
  6790. }
  6791. if (argVal.mType->IsValuelessNonOpaqueType())
  6792. return;
  6793. auto owner = methodInstance->GetOwner();
  6794. bool allowThisSplatting;
  6795. if (mModule->mIsComptimeModule)
  6796. allowThisSplatting = owner->IsTypedPrimitive() || owner->IsValuelessNonOpaqueType();
  6797. else
  6798. allowThisSplatting = methodInstance->AllowsSplatting(-1);
  6799. if ((!allowThisSplatting) || (methodDef->mIsMutating) || (methodInstance->ForcingThisPtr()))
  6800. {
  6801. argVal = mModule->MakeAddressable(argVal);
  6802. irArgs.push_back(argVal.mValue);
  6803. return;
  6804. }
  6805. auto thisType = methodInstance->GetThisType();
  6806. PushArg(argVal, irArgs, !methodInstance->AllowsSplatting(-1), thisType->IsPointer());
  6807. }
  6808. void BfExprEvaluator::FinishDeferredEvals(SizedArrayImpl<BfResolvedArg>& argValues)
  6809. {
  6810. for (int argIdx = 0; argIdx < argValues.size(); argIdx++)
  6811. {
  6812. auto& argValue = argValues[argIdx].mTypedValue;
  6813. if ((argValues[argIdx].mArgFlags & (BfArgFlag_DelegateBindAttempt | BfArgFlag_LambdaBindAttempt | BfArgFlag_UnqualifiedDotAttempt | BfArgFlag_DeferredEval)) != 0)
  6814. {
  6815. if (!argValue)
  6816. {
  6817. auto expr = BfNodeDynCast<BfExpression>(argValues[argIdx].mExpression);
  6818. if (expr != NULL)
  6819. argValue = mModule->CreateValueFromExpression(expr, argValues[argIdx].mExpectedType, BfEvalExprFlags_NoCast);
  6820. }
  6821. }
  6822. }
  6823. }
  6824. void BfExprEvaluator::FinishDeferredEvals(BfResolvedArgs& argValues)
  6825. {
  6826. for (int argIdx = 0; argIdx < (int)argValues.mResolvedArgs.size(); argIdx++)
  6827. {
  6828. auto& argValue = argValues.mResolvedArgs[argIdx].mTypedValue;
  6829. if ((argValues.mResolvedArgs[argIdx].mArgFlags & (BfArgFlag_VariableDeclaration)) != 0)
  6830. {
  6831. auto variableDeclaration = BfNodeDynCast<BfVariableDeclaration>((*argValues.mArguments)[argIdx]);
  6832. if ((variableDeclaration != NULL) && (variableDeclaration->mNameNode != NULL))
  6833. {
  6834. if (mModule->mCurMethodState == NULL)
  6835. {
  6836. mModule->Fail("Illegal local variable", variableDeclaration);
  6837. }
  6838. else
  6839. {
  6840. BfLocalVariable* localVar = new BfLocalVariable();
  6841. localVar->mName = variableDeclaration->mNameNode->ToString();
  6842. localVar->mResolvedType = mModule->GetPrimitiveType(BfTypeCode_Var);
  6843. localVar->mAddr = mModule->mBfIRBuilder->GetFakeVal();
  6844. localVar->mReadFromId = 0;
  6845. localVar->mWrittenToId = 0;
  6846. localVar->mAssignedKind = BfLocalVarAssignKind_Unconditional;
  6847. mModule->CheckVariableDef(localVar);
  6848. localVar->Init();
  6849. mModule->AddLocalVariableDef(localVar, true);
  6850. auto curScope = mModule->mCurMethodState->mCurScope;
  6851. if (curScope->mScopeKind == BfScopeKind_StatementTarget)
  6852. mModule->MoveLocalToParentScope(localVar);
  6853. }
  6854. }
  6855. }
  6856. }
  6857. FinishDeferredEvals(argValues.mResolvedArgs);
  6858. }
  6859. void BfExprEvaluator::AddCallDependencies(BfMethodInstance* methodInstance)
  6860. {
  6861. if (methodInstance->mReturnType != NULL)
  6862. mModule->AddDependency(methodInstance->mReturnType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage);
  6863. for (int paramIdx = 0; paramIdx < methodInstance->GetParamCount(); paramIdx++)
  6864. {
  6865. auto paramType = methodInstance->GetParamType(paramIdx);
  6866. mModule->AddDependency(paramType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage);
  6867. }
  6868. if (methodInstance->mMethodInfoEx != NULL)
  6869. {
  6870. for (auto genericArg : methodInstance->mMethodInfoEx->mMethodGenericArguments)
  6871. {
  6872. if (genericArg->IsWrappableType())
  6873. genericArg = mModule->GetWrappedStructType(genericArg);
  6874. if (genericArg != NULL)
  6875. mModule->AddDependency(genericArg, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage);
  6876. }
  6877. }
  6878. }
  6879. BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValue& inTarget, const BfTypedValue& origTarget, BfMethodDef* methodDef, BfModuleMethodInstance moduleMethodInstance, BfCreateCallFlags callFlags, SizedArrayImpl<BfResolvedArg>& argValues, BfTypedValue* argCascade)
  6880. {
  6881. SetAndRestoreValue<BfEvalExprFlags> prevEvalExprFlag(mBfEvalExprFlags);
  6882. if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) && (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mConstEvalAttributeTypeDef)))
  6883. {
  6884. mModule->mAttributeState->mUsed = true;
  6885. mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_Comptime);
  6886. }
  6887. else if ((moduleMethodInstance.mMethodInstance->mComptimeFlags & BfComptimeFlag_ConstEval) != 0)
  6888. {
  6889. mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_Comptime);
  6890. }
  6891. else if (((moduleMethodInstance.mMethodInstance->mComptimeFlags & BfComptimeFlag_Comptime) != 0) && (!mModule->mIsComptimeModule))
  6892. {
  6893. if ((mModule->mCurMethodInstance == NULL) || (mModule->mCurMethodInstance->mComptimeFlags == BfComptimeFlag_None))
  6894. mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_Comptime);
  6895. }
  6896. SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, mModule->mBfIRBuilder->mIgnoreWrites || IsConstEval());
  6897. if (((moduleMethodInstance.mMethodInstance->mComptimeFlags & BfComptimeFlag_OnlyFromComptime) != 0) &&
  6898. ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) &&
  6899. ((mModule->mCurMethodInstance == NULL) || (mModule->mCurMethodInstance->mComptimeFlags == BfComptimeFlag_None)) &&
  6900. (!mModule->mIsComptimeModule))
  6901. {
  6902. 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);
  6903. }
  6904. bool bypassVirtual = (callFlags & BfCreateCallFlags_BypassVirtual) != 0;
  6905. bool skipThis = (callFlags & BfCreateCallFlags_SkipThis) != 0;;
  6906. static int sCallIdx = 0;
  6907. if (!mModule->mCompiler->mIsResolveOnly)
  6908. sCallIdx++;
  6909. int callIdx = sCallIdx;
  6910. if (callIdx == 0x000015CB)
  6911. {
  6912. NOP;
  6913. }
  6914. // Temporarily disable so we don't capture calls in params
  6915. SetAndRestoreValue<BfFunctionBindResult*> prevBindResult(mFunctionBindResult, NULL);
  6916. SetAndRestoreValue<bool> prevAllowVariableDeclarations;
  6917. if (mModule->mCurMethodState != NULL)
  6918. prevAllowVariableDeclarations.Init(mModule->mCurMethodState->mCurScope->mAllowVariableDeclarations, false);
  6919. BfMethodInstance* methodInstance = moduleMethodInstance.mMethodInstance;
  6920. SizedArray<BfIRValue, 4> irArgs;
  6921. if ((methodDef->mIsAbstract) && (bypassVirtual))
  6922. {
  6923. mModule->Fail(StrFormat("Abstract base method '%s' cannot be invoked", mModule->MethodToString(methodInstance).c_str()), targetSrc);
  6924. }
  6925. bool isSkipCall = moduleMethodInstance.mMethodInstance->IsSkipCall(bypassVirtual);
  6926. BfType* returnType = methodInstance->mReturnType;
  6927. /*if (returnType->IsSelf())
  6928. {
  6929. returnType = methodInstance->GetOwner();
  6930. BF_ASSERT(returnType->IsInterface());
  6931. }*/
  6932. Array<BfTypedValue> argCascades;
  6933. BfTypedValue target = inTarget;
  6934. if (!skipThis)
  6935. {
  6936. if ((target) && (target.mType->IsFunction()) && (methodInstance->GetOwner() == target.mType))
  6937. {
  6938. CheckResultForReading(target);
  6939. target = mModule->LoadValue(target);
  6940. auto funcType = mModule->mBfIRBuilder->MapMethod(moduleMethodInstance.mMethodInstance);
  6941. auto funcPtrType = mModule->mBfIRBuilder->GetPointerTo(funcType);
  6942. moduleMethodInstance.mFunc = mModule->mBfIRBuilder->CreateIntToPtr(target.mValue, funcPtrType);
  6943. if (mDeferCallData != NULL)
  6944. {
  6945. mDeferCallData->mFuncAlloca_Orig = moduleMethodInstance.mFunc;
  6946. mDeferCallData->mFuncAlloca = mModule->CreateAlloca(funcPtrType, target.mType->mAlign, false, "FuncAlloca");
  6947. mModule->mBfIRBuilder->CreateStore(mDeferCallData->mFuncAlloca_Orig, mDeferCallData->mFuncAlloca);
  6948. }
  6949. }
  6950. else if (!methodDef->mIsStatic)
  6951. {
  6952. if ((!target) && (prevBindResult.mPrevVal != NULL))
  6953. {
  6954. auto bindResult = prevBindResult.mPrevVal;
  6955. if (bindResult->mBindType != NULL)
  6956. {
  6957. // Allow binding a function to a 'this' type even if no target is specified
  6958. auto delegateInfo = bindResult->mBindType->GetDelegateInfo();
  6959. if (delegateInfo != NULL)
  6960. {
  6961. if (delegateInfo->mHasExplicitThis)
  6962. {
  6963. target = mModule->GetDefaultTypedValue(delegateInfo->mParams[0], false, BfDefaultValueKind_Addr);
  6964. bypassVirtual = true;
  6965. }
  6966. }
  6967. else if (bindResult->mBindType->IsFunction())
  6968. {
  6969. BfMethodInstance* invokeMethodInstance = mModule->GetRawMethodInstanceAtIdx(bindResult->mBindType->ToTypeInstance(), 0, "Invoke");
  6970. if (!invokeMethodInstance->mMethodDef->mIsStatic)
  6971. {
  6972. target = mModule->GetDefaultTypedValue(invokeMethodInstance->GetThisType(), false, BfDefaultValueKind_Addr);
  6973. }
  6974. }
  6975. }
  6976. }
  6977. if (!target)
  6978. {
  6979. FinishDeferredEvals(argValues);
  6980. auto error = mModule->Fail(StrFormat("An instance reference is required to %s the non-static method '%s'",
  6981. (prevBindResult.mPrevVal != NULL) ? "bind" : "invoke",
  6982. mModule->MethodToString(methodInstance).c_str()), targetSrc);
  6983. if ((error != NULL) && (methodInstance->mMethodDef->GetRefNode() != NULL))
  6984. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
  6985. return mModule->GetDefaultTypedValue(returnType);
  6986. }
  6987. auto prevResult = mResult;
  6988. mResult = target;
  6989. CheckResultForReading(mResult);
  6990. mResult = prevResult;
  6991. if (methodDef->mMethodType != BfMethodType_Ctor)
  6992. {
  6993. bool doAccessCheck = true;
  6994. if (target.IsThis())
  6995. {
  6996. if (!mModule->mCurMethodState->mMayNeedThisAccessCheck)
  6997. doAccessCheck = false;
  6998. }
  6999. if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) && (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mDisableObjectAccessChecksAttributeTypeDef)))
  7000. doAccessCheck = false;
  7001. if ((doAccessCheck) && (!isSkipCall) && (prevBindResult.mPrevVal == NULL))
  7002. mModule->EmitObjectAccessCheck(target);
  7003. }
  7004. if (((prevBindResult.mPrevVal == NULL) || (!prevBindResult.mPrevVal->mSkipThis)) &&
  7005. (!isSkipCall))
  7006. {
  7007. bool skipMutCheck = false;
  7008. if ((prevBindResult.mPrevVal != NULL) && (prevBindResult.mPrevVal->mSkipMutCheck))
  7009. {
  7010. // If we are binding a delegate, then we will end up making a copy of the target anyway
  7011. // so we don't need to do a mutability check
  7012. skipMutCheck = true;
  7013. }
  7014. if (methodDef->mMethodType == BfMethodType_Extension)
  7015. PushArg(target, irArgs);
  7016. else
  7017. PushThis(targetSrc, target, moduleMethodInstance.mMethodInstance, irArgs, skipMutCheck);
  7018. }
  7019. }
  7020. else if (methodDef->mMethodType == BfMethodType_Extension)
  7021. {
  7022. // Handled in args
  7023. }
  7024. else
  7025. {
  7026. if (prevBindResult.mPrevVal == NULL)
  7027. {
  7028. if ((mModule->mAttributeState == NULL) || (mModule->mAttributeState->mCustomAttributes == NULL) ||
  7029. (!mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mNoStaticCtorAttributeTypeDef)))
  7030. {
  7031. mModule->CheckStaticAccess(methodInstance->mMethodInstanceGroup->mOwner);
  7032. }
  7033. }
  7034. if (target)
  7035. {
  7036. FinishDeferredEvals(argValues);
  7037. mModule->Fail(StrFormat("Method '%s' cannot be accessed with an instance reference; qualify it with a type name instead",
  7038. mModule->MethodToString(methodInstance).c_str()), targetSrc);
  7039. return mModule->GetDefaultTypedValue(returnType);
  7040. }
  7041. }
  7042. }
  7043. if (isSkipCall)
  7044. {
  7045. CheckSkipCall(targetSrc, argValues);
  7046. FinishDeferredEvals(argValues);
  7047. mModule->EmitEnsureInstructionAt();
  7048. return mModule->GetDefaultTypedValue(returnType);
  7049. }
  7050. bool hasNamedArgs = false;
  7051. for (auto& arg : argValues)
  7052. if (arg.mNameNode != NULL)
  7053. hasNamedArgs = true;
  7054. if (hasNamedArgs)
  7055. {
  7056. methodDef->BuildParamNameMap();
  7057. BfIdentifierNode* outOfPlaceName = NULL;
  7058. int curParamIdx = 0;
  7059. SizedArrayImpl<BfResolvedArg> origArgValues = argValues;
  7060. argValues.Clear();
  7061. for (int argIdx = 0; argIdx < origArgValues.mSize; argIdx++)
  7062. {
  7063. int paramIdx = curParamIdx;
  7064. auto& argValue = origArgValues[argIdx];
  7065. if (argValue.mNameNode != NULL)
  7066. {
  7067. int namedParamIdx = -1;
  7068. if (methodDef->mParamNameMap->TryGetValue(argValue.mNameNode->ToStringView(), &namedParamIdx))
  7069. {
  7070. paramIdx = namedParamIdx;
  7071. }
  7072. else
  7073. {
  7074. if (mModule->PreFail())
  7075. {
  7076. mModule->Fail(StrFormat("The best overload for '%s' does not have a parameter named '%s'", methodInstance->mMethodDef->mName.c_str(),
  7077. argValue.mNameNode->ToString().c_str()), argValue.mNameNode);
  7078. }
  7079. }
  7080. if (paramIdx != curParamIdx)
  7081. outOfPlaceName = argValue.mNameNode;
  7082. }
  7083. else if (outOfPlaceName != NULL)
  7084. {
  7085. if (mModule->PreFail())
  7086. mModule->Fail(StrFormat("Named argument '%s' is used out-of-position but is followed by an unnamed argument", outOfPlaceName->ToString().c_str()), outOfPlaceName);
  7087. outOfPlaceName = NULL;
  7088. }
  7089. if ((paramIdx < methodInstance->GetParamCount()) && (paramIdx != argIdx))
  7090. {
  7091. if (methodInstance->GetParamKind(paramIdx) == BfParamKind_Normal)
  7092. {
  7093. auto wantType = methodInstance->GetParamType(paramIdx);
  7094. auto resolvedValue = ResolveArgValue(argValue, wantType);
  7095. if (resolvedValue)
  7096. {
  7097. argValue.mTypedValue = resolvedValue;
  7098. argValue.mArgFlags = (BfArgFlags)(argValue.mArgFlags | BfArgFlag_Finalized);
  7099. }
  7100. }
  7101. }
  7102. while (paramIdx >= argValues.mSize)
  7103. argValues.Add(BfResolvedArg());
  7104. if (argValues[paramIdx].mExpression != NULL)
  7105. {
  7106. if (argValue.mNameNode != NULL)
  7107. {
  7108. if (mModule->PreFail())
  7109. mModule->Fail(StrFormat("Named argument '%s' cannot be specified multiple times", argValue.mNameNode->ToString().c_str()), argValue.mNameNode);
  7110. }
  7111. }
  7112. argValues[paramIdx] = argValue;
  7113. curParamIdx++;
  7114. }
  7115. }
  7116. int argIdx = 0;
  7117. int paramIdx = 0;
  7118. BfIRValue expandedParamAlloca;
  7119. BfTypedValue expandedParamsArray;
  7120. BfType* expandedParamsElementType = NULL;
  7121. bool hadDelegateParamIdx = false;
  7122. int extendedParamIdx = 0;
  7123. AddCallDependencies(methodInstance);
  7124. bool wasCapturingMatchInfo = false;
  7125. auto autoComplete = GetAutoComplete();
  7126. if (autoComplete != NULL)
  7127. {
  7128. // Set to false to make sure we don't capture method match info from 'params' array creation
  7129. wasCapturingMatchInfo = autoComplete->mIsCapturingMethodMatchInfo;
  7130. autoComplete->mIsCapturingMethodMatchInfo = false;
  7131. }
  7132. defer(
  7133. {
  7134. if (autoComplete != NULL)
  7135. autoComplete->mIsCapturingMethodMatchInfo = wasCapturingMatchInfo;
  7136. });
  7137. BfScopeData* boxScopeData = (mDeferCallData != NULL) ? mDeferCallData->mScopeAlloc : NULL;
  7138. if ((boxScopeData == NULL) && (mModule->mCurMethodState != NULL))
  7139. boxScopeData = mModule->mCurMethodState->mCurScope;
  7140. bool failed = false;
  7141. while (true)
  7142. {
  7143. int argExprIdx = argIdx;
  7144. if (methodDef->mMethodType == BfMethodType_Extension)
  7145. argExprIdx--;
  7146. bool isThis = (paramIdx == -1) || ((methodDef->mHasExplicitThis) && (paramIdx == 0));
  7147. bool isDirectPass = false;
  7148. if (paramIdx >= (int)methodInstance->GetParamCount())
  7149. {
  7150. if (methodInstance->IsVarArgs())
  7151. {
  7152. if (argExprIdx >= (int)argValues.size())
  7153. break;
  7154. BfTypedValue argValue = ResolveArgValue(argValues[argExprIdx], NULL);
  7155. if (argValue)
  7156. {
  7157. auto typeInst = argValue.mType->ToTypeInstance();
  7158. if (argValue.mType == mModule->GetPrimitiveType(BfTypeCode_Float))
  7159. argValue = mModule->Cast(argValues[argExprIdx].mExpression, argValue, mModule->GetPrimitiveType(BfTypeCode_Double));
  7160. if ((typeInst != NULL) && (typeInst->IsInstanceOf(mModule->mCompiler->mStringTypeDef)))
  7161. {
  7162. BfType* charType = mModule->GetPrimitiveType(BfTypeCode_Char8);
  7163. BfType* charPtrType = mModule->CreatePointerType(charType);
  7164. argValue = mModule->Cast(argValues[argExprIdx].mExpression, argValue, charPtrType);
  7165. }
  7166. PushArg(argValue, irArgs, true, false);
  7167. }
  7168. argIdx++;
  7169. continue;
  7170. }
  7171. if (argExprIdx < (int)argValues.size())
  7172. {
  7173. if (mModule->PreFail())
  7174. {
  7175. BfAstNode* errorRef = argValues[argExprIdx].mExpression;
  7176. if (errorRef == NULL)
  7177. errorRef = targetSrc;
  7178. BfError* error;
  7179. if ((argValues[argExprIdx].mArgFlags & BfArgFlag_StringInterpolateArg) != 0)
  7180. {
  7181. int checkIdx = argExprIdx - 1;
  7182. while (checkIdx >= 0)
  7183. {
  7184. if ((argValues[checkIdx].mArgFlags & BfArgFlag_StringInterpolateFormat) != 0)
  7185. {
  7186. errorRef = argValues[checkIdx].mExpression;
  7187. break;
  7188. }
  7189. checkIdx--;
  7190. }
  7191. error = mModule->Fail("Expanded string interpolation generates too many arguments. If string allocation was intended then consider adding a specifier such as 'scope'.", errorRef);
  7192. }
  7193. else if ((prevBindResult.mPrevVal != NULL) && (prevBindResult.mPrevVal->mBindType != NULL))
  7194. 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);
  7195. else
  7196. error = mModule->Fail(StrFormat("Too many arguments, expected %d fewer.", (int)argValues.size() - argExprIdx), errorRef);
  7197. if ((error != NULL) && (methodInstance->mMethodDef->mMethodDeclaration != NULL))
  7198. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
  7199. }
  7200. failed = true;
  7201. break;
  7202. }
  7203. break;
  7204. }
  7205. // Only create actual params if we're not just trying to bind the function
  7206. if ((prevBindResult.mPrevVal != NULL) && (!prevBindResult.mPrevVal->mWantsArgs))
  7207. break;
  7208. BfType* wantType = NULL;
  7209. bool wantsSplat = false;
  7210. if (expandedParamsElementType != NULL)
  7211. {
  7212. wantType = expandedParamsElementType;
  7213. }
  7214. else
  7215. {
  7216. wantsSplat = methodInstance->GetParamIsSplat(paramIdx) && (!IsComptime());
  7217. if (methodInstance->IsImplicitCapture(paramIdx))
  7218. {
  7219. auto paramType = methodInstance->GetParamType(paramIdx);
  7220. if (mModule->mCurMethodInstance->IsMixin())
  7221. {
  7222. // Don't bother, also- can fail on captures
  7223. }
  7224. else
  7225. {
  7226. // static int captureIdx = 0;
  7227. // captureIdx++;
  7228. // int curCaptureIdx = captureIdx;
  7229. //
  7230. // if (curCaptureIdx == 0x91)
  7231. // {
  7232. // NOP;
  7233. // }
  7234. auto lookupVal = DoImplicitArgCapture(targetSrc, methodInstance, paramIdx, failed, BfImplicitParamKind_General, origTarget);
  7235. if (lookupVal)
  7236. {
  7237. if (wantsSplat)
  7238. {
  7239. SplatArgs(lookupVal, irArgs);
  7240. }
  7241. else if (paramType->IsRef())
  7242. {
  7243. irArgs.push_back(lookupVal.mValue);
  7244. }
  7245. else
  7246. PushArg(lookupVal, irArgs, true);
  7247. }
  7248. }
  7249. paramIdx++;
  7250. continue;
  7251. }
  7252. wantType = methodInstance->GetParamType(paramIdx);
  7253. if (!mModule->mCurTypeInstance->IsInterface())
  7254. {
  7255. // Resolve `Self` types
  7256. if (wantType->IsUnspecializedTypeVariation())
  7257. {
  7258. wantType = mModule->ResolveSelfType(wantType, methodInstance->GetOwner());
  7259. }
  7260. }
  7261. if (IsVar(wantType))
  7262. {
  7263. // Case happens when we can't find the argument type
  7264. failed = true;
  7265. }
  7266. BfParamKind paramKind = methodInstance->GetParamKind(paramIdx);
  7267. if (paramKind == BfParamKind_Params)
  7268. {
  7269. //TODO: Check to see if it's a direct array pass
  7270. if (argIdx < (int)argValues.size())
  7271. {
  7272. auto argValue = argValues[argIdx].mTypedValue;
  7273. if ((argValue.IsParams()) /*&& (mModule->CanCast(argValue, wantType))*/)
  7274. isDirectPass = true;
  7275. }
  7276. if (!isDirectPass)
  7277. {
  7278. int numElements = BF_MAX((int)argValues.size() - argIdx, 0);
  7279. if (methodDef->mMethodType == BfMethodType_Extension)
  7280. numElements++;
  7281. if (IsConstEval())
  7282. {
  7283. if ((wantType->IsArray()) || (wantType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef)))
  7284. {
  7285. auto genericTypeInst = wantType->ToGenericTypeInstance();
  7286. expandedParamsElementType = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[0];
  7287. auto irSizedArrayType = mModule->mBfIRBuilder->GetSizedArrayType(mModule->mBfIRBuilder->MapType(expandedParamsElementType), numElements);
  7288. Array<BfIRValue> values;
  7289. for (int i = 0; i < numElements; i++)
  7290. values.Add(mModule->mBfIRBuilder->GetFakeVal());
  7291. expandedParamsArray = BfTypedValue(mModule->mBfIRBuilder->CreateConstAgg(irSizedArrayType, values), wantType);
  7292. PushArg(expandedParamsArray, irArgs);
  7293. continue;
  7294. }
  7295. }
  7296. else if (wantType->IsArray())
  7297. {
  7298. BfArrayType* arrayType = (BfArrayType*)wantType;
  7299. mModule->PopulateType(arrayType, BfPopulateType_DataAndMethods);
  7300. expandedParamsElementType = arrayType->mGenericTypeInfo->mTypeGenericArguments[0];
  7301. int arrayClassSize = arrayType->mInstSize - expandedParamsElementType->mSize;
  7302. expandedParamsArray = BfTypedValue(mModule->AllocFromType(arrayType->GetUnderlyingType(), boxScopeData, BfIRValue(), mModule->GetConstValue(numElements), 1, BfAllocFlags_None),
  7303. arrayType, false);
  7304. BfResolvedArgs resolvedArgs;
  7305. MatchConstructor(targetSrc, NULL, expandedParamsArray, arrayType, resolvedArgs, false, BfMethodGenericArguments(), BfAllowAppendKind_No);
  7306. //TODO: Assert 'length' var is at slot 1
  7307. auto arrayBits = mModule->mBfIRBuilder->CreateBitCast(expandedParamsArray.mValue, mModule->mBfIRBuilder->MapType(arrayType->mBaseType));
  7308. int arrayLengthBitCount = arrayType->GetLengthBitCount();
  7309. if (arrayLengthBitCount == 0)
  7310. {
  7311. mModule->Fail("INTERNAL ERROR: Unable to find array 'length' field", targetSrc);
  7312. return BfTypedValue();
  7313. }
  7314. auto& fieldInstance = arrayType->mBaseType->mFieldInstances[0];
  7315. auto addr = mModule->mBfIRBuilder->CreateInBoundsGEP(arrayBits, 0, fieldInstance.mDataIdx);
  7316. if (arrayLengthBitCount == 64)
  7317. mModule->mBfIRBuilder->CreateAlignedStore(mModule->GetConstValue64(numElements), addr, 8);
  7318. else
  7319. mModule->mBfIRBuilder->CreateAlignedStore(mModule->GetConstValue32(numElements), addr, 4);
  7320. PushArg(expandedParamsArray, irArgs);
  7321. continue;
  7322. }
  7323. else if (wantType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef))
  7324. {
  7325. mModule->PopulateType(wantType);
  7326. mModule->mBfIRBuilder->PopulateType(wantType);
  7327. auto genericTypeInst = wantType->ToGenericTypeInstance();
  7328. expandedParamsElementType = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[0];
  7329. expandedParamsArray = BfTypedValue(mModule->CreateAlloca(wantType), wantType, true);
  7330. expandedParamAlloca = mModule->CreateAlloca(genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[0], true, NULL, mModule->GetConstValue(numElements));
  7331. mModule->mBfIRBuilder->CreateAlignedStore(expandedParamAlloca, mModule->mBfIRBuilder->CreateInBoundsGEP(expandedParamsArray.mValue, 0, 1), mModule->mSystem->mPtrSize);
  7332. mModule->mBfIRBuilder->CreateAlignedStore(mModule->GetConstValue(numElements), mModule->mBfIRBuilder->CreateInBoundsGEP(expandedParamsArray.mValue, 0, 2), mModule->mSystem->mPtrSize);
  7333. PushArg(expandedParamsArray, irArgs, !wantsSplat);
  7334. continue;
  7335. }
  7336. else if (wantType->IsSizedArray())
  7337. {
  7338. mModule->PopulateType(wantType);
  7339. mModule->mBfIRBuilder->PopulateType(wantType);
  7340. BfSizedArrayType* sizedArrayType = (BfSizedArrayType*)wantType;
  7341. expandedParamsElementType = wantType->GetUnderlyingType();
  7342. if (numElements != sizedArrayType->mElementCount)
  7343. {
  7344. BfAstNode* refNode = targetSrc;
  7345. if (argExprIdx < (int)argValues.size())
  7346. refNode = argValues[argExprIdx].mExpression;
  7347. mModule->Fail(StrFormat("Incorrect number of arguments to match params type '%s'", mModule->TypeToString(wantType).c_str()), refNode);
  7348. }
  7349. expandedParamsArray = BfTypedValue(mModule->CreateAlloca(wantType), wantType, true);
  7350. expandedParamAlloca = mModule->mBfIRBuilder->CreateBitCast(expandedParamsArray.mValue, mModule->mBfIRBuilder->GetPointerTo(mModule->mBfIRBuilder->MapType(expandedParamsElementType)));
  7351. PushArg(expandedParamsArray, irArgs, !wantsSplat);
  7352. continue;
  7353. }
  7354. }
  7355. }
  7356. else if (paramKind == BfParamKind_DelegateParam)
  7357. hadDelegateParamIdx = true;
  7358. }
  7359. BfAstNode* arg = NULL;
  7360. bool hadMissingArg = false;
  7361. if (argExprIdx == -1)
  7362. arg = targetSrc;
  7363. if (argExprIdx >= 0)
  7364. {
  7365. if (argExprIdx < (int)argValues.size())
  7366. {
  7367. arg = argValues[argExprIdx].mExpression;
  7368. if (((argValues[argExprIdx].mArgFlags & BfArgFlag_StringInterpolateArg) != 0) && (!expandedParamsArray) && (!hadDelegateParamIdx))
  7369. {
  7370. BfAstNode* errorRef = arg;
  7371. int checkIdx = argExprIdx - 1;
  7372. while (checkIdx >= 0)
  7373. {
  7374. if ((argValues[checkIdx].mArgFlags & BfArgFlag_StringInterpolateFormat) != 0)
  7375. {
  7376. errorRef = argValues[checkIdx].mExpression;
  7377. break;
  7378. }
  7379. checkIdx--;
  7380. }
  7381. 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);
  7382. }
  7383. // if ((arg == NULL) && (argValues[argExprIdx].mExpression != NULL))
  7384. // hadMissingArg = true;
  7385. if ((arg == NULL) && (!argValues[argExprIdx].mTypedValue))
  7386. hadMissingArg = true;
  7387. }
  7388. else
  7389. hadMissingArg = true;
  7390. }
  7391. BfTypedValue argValue;
  7392. if (hadMissingArg)
  7393. {
  7394. if (expandedParamsArray)
  7395. break;
  7396. if ((argIdx >= (int) methodInstance->mDefaultValues.size()) || (!methodInstance->mDefaultValues[argIdx]))
  7397. {
  7398. BfAstNode* refNode = targetSrc;
  7399. if (argValues.size() > 0)
  7400. {
  7401. auto checkExpr = argValues.back().mExpression;
  7402. if (checkExpr != NULL)
  7403. refNode = checkExpr;
  7404. }
  7405. BfAstNode* prevNode = NULL;
  7406. if (targetSrc == NULL)
  7407. {
  7408. // We must be in BfModule::EmitCtorBody
  7409. }
  7410. else if (auto tupleExpr = BfNodeDynCastExact<BfTupleExpression>(targetSrc))
  7411. {
  7412. if (tupleExpr->mCommas.size() > 0)
  7413. prevNode = tupleExpr->mCommas.back();
  7414. else
  7415. prevNode = tupleExpr->mOpenParen;
  7416. if (tupleExpr->mCloseParen != NULL)
  7417. refNode = tupleExpr->mCloseParen;
  7418. }
  7419. else if (mModule->mParentNodeEntry != NULL)
  7420. {
  7421. if (auto objectCreateExpr = BfNodeDynCast<BfObjectCreateExpression>(mModule->mParentNodeEntry->mNode))
  7422. {
  7423. if (objectCreateExpr->mCommas.size() > 0)
  7424. prevNode = objectCreateExpr->mCommas.back();
  7425. else
  7426. prevNode = objectCreateExpr->mOpenToken;
  7427. if (objectCreateExpr->mCloseToken != NULL)
  7428. refNode = objectCreateExpr->mCloseToken;
  7429. if (auto newNode = BfNodeDynCast<BfNewNode>(objectCreateExpr->mNewNode))
  7430. {
  7431. if (newNode->mAllocNode == targetSrc)
  7432. refNode = targetSrc;
  7433. }
  7434. }
  7435. else if (auto invokeExpr = BfNodeDynCast<BfInvocationExpression>(mModule->mParentNodeEntry->mNode))
  7436. {
  7437. if (invokeExpr->mCommas.size() > 0)
  7438. prevNode = invokeExpr->mCommas.back();
  7439. else
  7440. prevNode = invokeExpr->mOpenParen;
  7441. if (invokeExpr->mCloseParen != NULL)
  7442. refNode = invokeExpr->mCloseParen;
  7443. }
  7444. }
  7445. if (refNode == NULL)
  7446. refNode = methodInstance->GetOwner()->mTypeDef->GetRefNode();
  7447. if ((autoComplete != NULL) && (prevNode != NULL))
  7448. autoComplete->CheckEmptyStart(prevNode, wantType);
  7449. BfError* error = NULL;
  7450. if (mModule->mParentNodeEntry != NULL)
  7451. {
  7452. bool showCtorError = false;
  7453. if (auto ctorDeclaration = BfNodeDynCast<BfConstructorDeclaration>(mModule->mParentNodeEntry->mNode))
  7454. {
  7455. if (ctorDeclaration->mInitializer == NULL)
  7456. showCtorError = true;
  7457. }
  7458. if (auto typerDecl = BfNodeDynCast<BfTypeDeclaration>(mModule->mParentNodeEntry->mNode))
  7459. showCtorError = true;
  7460. if (showCtorError)
  7461. {
  7462. if (mModule->PreFail())
  7463. {
  7464. error = mModule->Fail(StrFormat("No parameterless constructor is available for base class. Consider calling base constructor '%s'.",
  7465. mModule->MethodToString(methodInstance).c_str()), refNode);
  7466. }
  7467. auto srcNode = mModule->mCurMethodInstance->mMethodDef->GetRefNode();
  7468. if ((autoComplete != NULL) && (autoComplete->CheckFixit(srcNode)))
  7469. autoComplete->FixitAddConstructor(mModule->mCurTypeInstance);
  7470. }
  7471. }
  7472. if (mModule->PreFail())
  7473. {
  7474. if (error == NULL)
  7475. {
  7476. if (hasNamedArgs)
  7477. error = mModule->Fail(StrFormat("There is no argument given that corresponds to the required formal parameter '%s' of '%s'.",
  7478. methodInstance->GetParamName(paramIdx).c_str(), mModule->MethodToString(methodInstance).c_str()), refNode);
  7479. else
  7480. error = mModule->Fail(StrFormat("Not enough parameters specified, expected %d more.", methodInstance->GetParamCount() - paramIdx), refNode);
  7481. }
  7482. if ((error != NULL) && (methodInstance->mMethodDef->mMethodDeclaration != NULL))
  7483. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
  7484. }
  7485. failed = true;
  7486. break;
  7487. }
  7488. auto foreignDefaultVal = methodInstance->mDefaultValues[argIdx];
  7489. auto foreignConst = methodInstance->GetOwner()->mConstHolder->GetConstant(foreignDefaultVal.mValue);
  7490. if (foreignConst->mConstType == BfConstType_AggZero)
  7491. {
  7492. // Allow this
  7493. }
  7494. else if (foreignConst->mTypeCode == BfTypeCode_NullPtr)
  7495. {
  7496. if (wantType->IsNullable())
  7497. {
  7498. argValue = mModule->GetDefaultTypedValue(wantType, false, BfDefaultValueKind_Addr);
  7499. }
  7500. }
  7501. else if (foreignConst->mConstType == BfConstType_GlobalVar)
  7502. {
  7503. auto globalVar = (BfGlobalVar*)foreignConst;
  7504. if (globalVar->mName[0] == '#')
  7505. {
  7506. if (strcmp(globalVar->mName, "#CallerLineNum") == 0)
  7507. {
  7508. argValue = BfTypedValue(mModule->GetConstValue(mModule->mCurFilePosition.mCurLine + 1), mModule->GetPrimitiveType(BfTypeCode_Int32));
  7509. }
  7510. else if (strcmp(globalVar->mName, "#CallerFilePath") == 0)
  7511. {
  7512. String filePath = "";
  7513. if (mModule->mCurFilePosition.mFileInstance != NULL)
  7514. filePath = mModule->mCurFilePosition.mFileInstance->mParser->mFileName;
  7515. argValue = BfTypedValue(mModule->GetStringObjectValue(filePath),
  7516. mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
  7517. }
  7518. else if (strcmp(globalVar->mName, "#CallerFileName") == 0)
  7519. {
  7520. String filePath = "";
  7521. if (mModule->mCurFilePosition.mFileInstance != NULL)
  7522. filePath = mModule->mCurFilePosition.mFileInstance->mParser->mFileName;
  7523. argValue = BfTypedValue(mModule->GetStringObjectValue(GetFileName(filePath)),
  7524. mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
  7525. }
  7526. else if (strcmp(globalVar->mName, "#CallerFileDir") == 0)
  7527. {
  7528. String filePath = "";
  7529. if (mModule->mCurFilePosition.mFileInstance != NULL)
  7530. filePath = mModule->mCurFilePosition.mFileInstance->mParser->mFileName;
  7531. argValue = BfTypedValue(mModule->GetStringObjectValue(GetFileDir(filePath)),
  7532. mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
  7533. }
  7534. else if (strcmp(globalVar->mName, "#CallerTypeName") == 0)
  7535. {
  7536. String typeName = "";
  7537. if (mModule->mCurTypeInstance != NULL)
  7538. typeName = mModule->TypeToString(mModule->mCurTypeInstance);
  7539. argValue = BfTypedValue(mModule->GetStringObjectValue(typeName),
  7540. mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
  7541. }
  7542. else if (strcmp(globalVar->mName, "#CallerType") == 0)
  7543. {
  7544. auto typeType = mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef);
  7545. BfType* type = mModule->mCurTypeInstance;
  7546. if (type != NULL)
  7547. {
  7548. mModule->AddDependency(type, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
  7549. argValue = BfTypedValue(mModule->CreateTypeDataRef(type), typeType);
  7550. }
  7551. }
  7552. else if (strcmp(globalVar->mName, "#CallerMemberName") == 0)
  7553. {
  7554. String memberName = "";
  7555. if (mModule->mCurMethodInstance != NULL)
  7556. memberName = mModule->MethodToString(mModule->mCurMethodInstance);
  7557. argValue = BfTypedValue(mModule->GetStringObjectValue(memberName),
  7558. mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
  7559. }
  7560. else if (strcmp(globalVar->mName, "#CallerProject") == 0)
  7561. {
  7562. String projectName = "";
  7563. if (mModule->mCurMethodInstance != NULL)
  7564. projectName = mModule->mCurMethodInstance->mMethodDef->mDeclaringType->mProject->mName;
  7565. argValue = BfTypedValue(mModule->GetStringObjectValue(projectName),
  7566. mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
  7567. }
  7568. else if (strcmp(globalVar->mName, "#ProjectName") == 0)
  7569. {
  7570. String projectName = methodInstance->mMethodDef->mDeclaringType->mProject->mName;
  7571. argValue = BfTypedValue(mModule->GetStringObjectValue(projectName),
  7572. mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
  7573. }
  7574. else
  7575. {
  7576. argValue = mModule->GetCompilerFieldValue(globalVar->mName);
  7577. }
  7578. }
  7579. }
  7580. else if (foreignConst->mConstType == BfConstType_GEP32_2)
  7581. {
  7582. auto constGep32_2 = (BfConstantGEP32_2*)foreignConst;
  7583. auto gepTarget = methodInstance->GetOwner()->mConstHolder->GetConstantById(constGep32_2->mTarget);
  7584. if (gepTarget->mConstType == BfConstType_GlobalVar)
  7585. {
  7586. auto globalVar = (BfGlobalVar*)gepTarget;
  7587. if (globalVar->mName[0] == '#')
  7588. {
  7589. if (strcmp(globalVar->mName, "#CallerExpression") == 0)
  7590. {
  7591. int exprIdx = constGep32_2->mIdx1;
  7592. if ((exprIdx >= 0) && (exprIdx < (int)argValues.size()))
  7593. {
  7594. auto expr = argValues[exprIdx].mExpression;
  7595. if (expr != NULL)
  7596. {
  7597. argValue = BfTypedValue(mModule->GetStringObjectValue(expr->ToString()),
  7598. mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
  7599. }
  7600. }
  7601. else
  7602. {
  7603. mModule->Fail("CallerExpression index out of bounds", targetSrc);
  7604. argValue = BfTypedValue(mModule->GetStringObjectValue(""),
  7605. mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
  7606. }
  7607. }
  7608. }
  7609. }
  7610. }
  7611. if (!argValue)
  7612. {
  7613. argValue = mModule->GetTypedValueFromConstant(foreignConst, methodInstance->GetOwner()->mConstHolder, foreignDefaultVal.mType);
  7614. if (!argValue)
  7615. mModule->Fail("Default parameter value failed", targetSrc);
  7616. mModule->mBfIRBuilder->PopulateType(foreignDefaultVal.mType);
  7617. }
  7618. }
  7619. else
  7620. {
  7621. if (argExprIdx == -1)
  7622. argValue = target;
  7623. else
  7624. argValue = argValues[argExprIdx].mTypedValue;
  7625. if ((argValue.IsParams()) && (!isDirectPass))
  7626. {
  7627. BfAstNode* refNode = arg;
  7628. if (auto unaryOperatorExpr = BfNodeDynCast<BfUnaryOperatorExpression>(refNode))
  7629. refNode = unaryOperatorExpr->mOpToken;
  7630. mModule->Warn(0, "Unused 'params' expression", refNode);
  7631. }
  7632. if (wantType->IsMethodRef())
  7633. {
  7634. auto expr = argValues[argExprIdx].mExpression;
  7635. if (expr != NULL)
  7636. SetMethodElementType(expr);
  7637. if (!argValue)
  7638. argValue = mModule->CreateValueFromExpression(BfNodeDynCast<BfExpression>(arg), wantType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast));
  7639. // Add any implicit captures now
  7640. auto methodRefType = (BfMethodRefType*)wantType;
  7641. BfMethodInstance* useMethodInstance = methodRefType->mMethodRef;
  7642. for (int dataIdx = 0; dataIdx < methodRefType->GetCaptureDataCount(); dataIdx++)
  7643. {
  7644. int paramIdx = methodRefType->GetParamIdxFromDataIdx(dataIdx);
  7645. auto lookupVal = DoImplicitArgCapture(arg, useMethodInstance, paramIdx, failed, BfImplicitParamKind_General, argValue);
  7646. if (lookupVal)
  7647. {
  7648. if (methodRefType->WantsDataPassedAsSplat(dataIdx))
  7649. SplatArgs(lookupVal, irArgs);
  7650. else
  7651. {
  7652. if (lookupVal.mType->IsComposite())
  7653. lookupVal = mModule->MakeAddressable(lookupVal, false);
  7654. irArgs.push_back(lookupVal.mValue);
  7655. }
  7656. }
  7657. }
  7658. paramIdx++;
  7659. argIdx++;
  7660. continue;
  7661. }
  7662. else if (argExprIdx >= 0)
  7663. {
  7664. BfParamKind paramKind = BfParamKind_Normal;
  7665. BfIdentifierNode* paramNameNode = NULL;
  7666. if (paramIdx < methodInstance->GetParamCount())
  7667. {
  7668. paramKind = methodInstance->GetParamKind(paramIdx);
  7669. paramNameNode = methodInstance->GetParamNameNode(paramIdx);
  7670. }
  7671. argValues[argExprIdx].mExpectedType = wantType;
  7672. argValue = ResolveArgValue(argValues[argExprIdx], wantType, NULL, paramKind, paramNameNode);
  7673. }
  7674. }
  7675. if (!argValue)
  7676. {
  7677. failed = true;
  7678. }
  7679. if ((arg != NULL) && (autoComplete != NULL) && (autoComplete->mResolveType == BfResolveType_GetResultString) && (autoComplete->IsAutocompleteNode(arg)))
  7680. {
  7681. if (!autoComplete->mResultString.Contains('\r'))
  7682. {
  7683. String str;
  7684. str += methodInstance->GetParamName(paramIdx);
  7685. str += " @ ";
  7686. bool isCtor = methodInstance->mMethodDef->mMethodType == BfMethodType_Ctor;
  7687. if (isCtor)
  7688. str += methodInstance->GetOwner()->mTypeDef->mName->ToString();
  7689. else
  7690. str += methodInstance->mMethodDef->mName;
  7691. str += "(";
  7692. for (int i = isCtor ? 1 : 0; i < methodInstance->GetParamCount(); i++)
  7693. {
  7694. if (i > (isCtor ? 1 : 0))
  7695. str += ",";
  7696. if (i == paramIdx)
  7697. {
  7698. if (methodInstance->GetParamKind(paramIdx) == BfParamKind_Params)
  7699. str += "params ";
  7700. str += mModule->TypeToString(methodInstance->GetParamType(paramIdx));
  7701. }
  7702. }
  7703. str += ")";
  7704. if (!autoComplete->mResultString.StartsWith(":"))
  7705. autoComplete->mResultString.Clear();
  7706. int crPos = (int)autoComplete->mResultString.IndexOf('\n');
  7707. if (crPos == -1)
  7708. crPos = autoComplete->mResultString.mLength;
  7709. int insertPos = BF_MAX(1, crPos);
  7710. if (autoComplete->mResultString.IsEmpty())
  7711. autoComplete->mResultString += ":";
  7712. if (insertPos > 1)
  7713. str.Insert(0, '\r');
  7714. autoComplete->mResultString.Insert(insertPos, str);
  7715. }
  7716. }
  7717. if (argValue)
  7718. {
  7719. if ((isThis) && (argValue.mType->IsRef()))
  7720. {
  7721. // Convert a 'ref this' to a 'this*'
  7722. argValue.mType = mModule->CreatePointerType(argValue.mType->GetUnderlyingType());
  7723. }
  7724. BfAstNode* refNode = arg;
  7725. if (refNode == NULL)
  7726. refNode = targetSrc;
  7727. if ((wantType->IsRef()) && (!argValue.mType->IsRef()) &&
  7728. (((callFlags & BfCreateCallFlags_AllowImplicitRef) != 0) || (wantType->IsIn())))
  7729. {
  7730. auto underlyingType = wantType->GetUnderlyingType();
  7731. if (mModule->mCurMethodState != NULL)
  7732. {
  7733. SetAndRestoreValue<BfScopeData*> prevScopeData(mModule->mCurMethodState->mOverrideScope, boxScopeData);
  7734. argValue = mModule->Cast(refNode, argValue, underlyingType);
  7735. }
  7736. else
  7737. argValue = mModule->Cast(refNode, argValue, underlyingType, ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) ? BfCastFlags_WantsConst : BfCastFlags_None);
  7738. if (argValue)
  7739. argValue = mModule->ToRef(argValue, (BfRefType*)wantType);
  7740. }
  7741. else
  7742. {
  7743. if (mModule->mCurMethodState != NULL)
  7744. {
  7745. SetAndRestoreValue<BfScopeData*> prevScopeData(mModule->mCurMethodState->mOverrideScope, boxScopeData);
  7746. argValue = mModule->Cast(refNode, argValue, wantType, ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) ? BfCastFlags_WantsConst : BfCastFlags_None);
  7747. }
  7748. else
  7749. argValue = mModule->Cast(refNode, argValue, wantType, ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) ? BfCastFlags_WantsConst : BfCastFlags_None);
  7750. }
  7751. if (!argValue)
  7752. {
  7753. if ((argExprIdx < (int)argValues.size()) && ((argValues[argExprIdx].mArgFlags & BfArgFlag_StringInterpolateArg) != 0))
  7754. {
  7755. BfAstNode* errorRef = NULL;
  7756. int checkIdx = argExprIdx - 1;
  7757. while (checkIdx >= 0)
  7758. {
  7759. if ((argValues[checkIdx].mArgFlags & BfArgFlag_StringInterpolateFormat) != 0)
  7760. {
  7761. errorRef = argValues[checkIdx].mExpression;
  7762. break;
  7763. }
  7764. checkIdx--;
  7765. }
  7766. if (errorRef != NULL)
  7767. mModule->Warn(0, "If string allocation was intended then consider adding a specifier such as 'scope'.", errorRef);
  7768. }
  7769. failed = true;
  7770. }
  7771. else if ((wantType->IsComposite()) && (!expandedParamsArray))
  7772. {
  7773. if (methodInstance->mIsIntrinsic)
  7774. {
  7775. // Intrinsics can handle structs either by value or address
  7776. }
  7777. else
  7778. {
  7779. // We need to make a temp and get the addr of that
  7780. if ((!wantsSplat) && (!argValue.IsValuelessType()) && (!argValue.IsAddr()) && (!IsConstEval()))
  7781. {
  7782. argValue = mModule->MakeAddressable(argValue);
  7783. }
  7784. }
  7785. }
  7786. else if (!wantType->IsRef())
  7787. argValue = mModule->LoadValue(argValue);
  7788. }
  7789. if ((argExprIdx != -1) && (argExprIdx < (int)argValues.size()) && ((argValues[argExprIdx].mArgFlags & BfArgFlag_Cascade) != 0))
  7790. {
  7791. mUsedAsStatement = true;
  7792. if (argValues[argExprIdx].mUncastedTypedValue)
  7793. argCascades.Add(argValues[argExprIdx].mUncastedTypedValue);
  7794. else
  7795. argCascades.Add(argValue);
  7796. }
  7797. if (expandedParamsArray)
  7798. {
  7799. if (argValue)
  7800. {
  7801. if (argValue.mValue.IsFake())
  7802. {
  7803. if ((!mModule->IsInUnspecializedGeneric()) && (!mModule->mBfIRBuilder->mIgnoreWrites))
  7804. mModule->InternalError("Invalid expandedParamsArray value");
  7805. }
  7806. else if (IsConstEval())
  7807. {
  7808. auto constant = mModule->mBfIRBuilder->GetConstant(expandedParamsArray.mValue);
  7809. BF_ASSERT(constant->mConstType == BfConstType_Agg);
  7810. auto constAgg = (BfConstantAgg*)constant;
  7811. constAgg->mValues[extendedParamIdx] = argValue.mValue;
  7812. }
  7813. else if (expandedParamAlloca)
  7814. {
  7815. argValue = mModule->LoadOrAggregateValue(argValue);
  7816. auto addr = mModule->mBfIRBuilder->CreateInBoundsGEP(expandedParamAlloca, extendedParamIdx);
  7817. auto storeInst = mModule->mBfIRBuilder->CreateAlignedStore(argValue.mValue, addr, argValue.mType->mAlign);
  7818. }
  7819. else
  7820. {
  7821. auto firstElem = mModule->GetFieldByName(expandedParamsArray.mType->ToTypeInstance(), "mFirstElement");
  7822. if (firstElem != NULL)
  7823. {
  7824. argValue = mModule->LoadValue(argValue);
  7825. auto firstAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(expandedParamsArray.mValue, 0, firstElem->mDataIdx);
  7826. auto indexedAddr = mModule->CreateIndexedValue(argValue.mType, firstAddr, extendedParamIdx);
  7827. if (argValue.IsSplat())
  7828. mModule->AggregateSplatIntoAddr(argValue, indexedAddr);
  7829. else
  7830. mModule->mBfIRBuilder->CreateAlignedStore(argValue.mValue, indexedAddr, argValue.mType->mAlign);
  7831. }
  7832. }
  7833. }
  7834. extendedParamIdx++;
  7835. }
  7836. else
  7837. {
  7838. if ((paramIdx == 0) && (methodInstance->GetParamName(paramIdx) == "this") && (wantType->IsPointer()))
  7839. {
  7840. auto underlyingType = wantType->GetUnderlyingType();
  7841. mModule->PopulateType(underlyingType, BfPopulateType_Data);
  7842. if ((underlyingType->IsValuelessType()) && (!underlyingType->IsVoid()))
  7843. {
  7844. // We don't actually pass a 'this' pointer for mut methods on valueless structs
  7845. argIdx++;
  7846. paramIdx++;
  7847. continue;
  7848. }
  7849. }
  7850. if (argValue)
  7851. {
  7852. if (isThis)
  7853. PushThis(targetSrc, argValue, methodInstance, irArgs);
  7854. else if (wantsSplat)
  7855. SplatArgs(argValue, irArgs);
  7856. else
  7857. PushArg(argValue, irArgs, true, false, methodInstance->mIsIntrinsic, methodInstance->mCallingConvention != BfCallingConvention_Unspecified);
  7858. }
  7859. paramIdx++;
  7860. }
  7861. argIdx++;
  7862. }
  7863. if (failed)
  7864. {
  7865. // Process the other unused arguments
  7866. while (argIdx < argValues.size())
  7867. {
  7868. mModule->AssertErrorState();
  7869. auto argValue = argValues[argIdx].mTypedValue;
  7870. if ((argValues[argIdx].mArgFlags & (BfArgFlag_DelegateBindAttempt | BfArgFlag_LambdaBindAttempt | BfArgFlag_UnqualifiedDotAttempt | BfArgFlag_DeferredEval | BfArgFlag_VariableDeclaration | BfArgFlag_UninitializedExpr)) != 0)
  7871. {
  7872. if (!argValue)
  7873. {
  7874. auto expr = BfNodeDynCast<BfExpression>(argValues[argIdx].mExpression);
  7875. if (expr != NULL)
  7876. argValue = mModule->CreateValueFromExpression(expr);
  7877. }
  7878. }
  7879. argIdx++;
  7880. }
  7881. prevIgnoreWrites.Restore();
  7882. return mModule->GetDefaultTypedValue(returnType, false, BfDefaultValueKind_Addr);
  7883. }
  7884. prevBindResult.Restore();
  7885. if (!methodDef->mIsStatic)
  7886. {
  7887. bool ignoreVirtualError = (mModule->mBfIRBuilder->mIgnoreWrites) && (mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsForeignMethodDef);
  7888. if ((methodInstance->GetOwner()->IsInterface()) && (!target.mType->IsGenericParam()) && (!target.mType->IsConcreteInterfaceType()) &&
  7889. (!mModule->mCurTypeInstance->IsInterface()) && (!ignoreVirtualError))
  7890. {
  7891. if (methodInstance->mVirtualTableIdx == -1)
  7892. {
  7893. mModule->PopulateType(methodInstance->GetOwner(), BfPopulateType_DataAndMethods);
  7894. }
  7895. if (methodInstance->mVirtualTableIdx == -1)
  7896. {
  7897. if (methodInstance->mMethodDef->mIsConcrete)
  7898. {
  7899. 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);
  7900. }
  7901. else if (methodInstance->HasSelf())
  7902. {
  7903. 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);
  7904. }
  7905. else
  7906. {
  7907. if ((bypassVirtual) && (mModule->mCurTypeInstance->IsInterface()))
  7908. {
  7909. // Allow a base call to be defined
  7910. }
  7911. else if ((methodInstance->IsSpecializedGenericMethod()) && (origTarget) && (!origTarget.mType->IsInterface()))
  7912. {
  7913. if (!mModule->mBfIRBuilder->mIgnoreWrites)
  7914. mModule->AssertErrorState();
  7915. }
  7916. else if ((!mModule->mCurMethodInstance->mIsUnspecialized))
  7917. {
  7918. // Compiler error?
  7919. String errorString = "Unable to dynamically dispatch '%s'";
  7920. if (methodInstance->IsSpecializedGenericMethod())
  7921. errorString = "Unable to dynamically dispatch '%s' because generic methods can only be directly dispatched";
  7922. if (methodInstance->mReturnType->IsConcreteInterfaceType())
  7923. errorString = "Unable to dynamically dispatch '%s' because the concrete return type is unknown";
  7924. mModule->Fail(StrFormat(errorString.c_str(), mModule->MethodToString(methodInstance).c_str()), targetSrc);
  7925. }
  7926. //BF_ASSERT(mModule->mCurMethodInstance->mIsUnspecialized);
  7927. }
  7928. if (mFunctionBindResult != NULL)
  7929. {
  7930. mFunctionBindResult->mMethodInstance = methodInstance;
  7931. mFunctionBindResult->mTarget = target;
  7932. mFunctionBindResult->mFunc = moduleMethodInstance.mFunc;
  7933. for (auto arg : irArgs)
  7934. mFunctionBindResult->mIRArgs.push_back(arg);
  7935. }
  7936. prevIgnoreWrites.Restore();
  7937. return mModule->GetDefaultTypedValue(returnType);
  7938. }
  7939. }
  7940. }
  7941. else
  7942. {
  7943. //BF_ASSERT(!methodInstance->GetOwner()->IsInterface());
  7944. }
  7945. prevIgnoreWrites.Restore();
  7946. if (target.mType != NULL)
  7947. {
  7948. // When we call a method from a static ctor, that method could access static fields so we need to make sure
  7949. // the type has been initialized
  7950. auto targetTypeInst = target.mType->ToTypeInstance();
  7951. if (targetTypeInst != NULL)
  7952. {
  7953. if (prevBindResult.mPrevVal == NULL)
  7954. {
  7955. if ((mModule->mAttributeState == NULL) || (mModule->mAttributeState->mCustomAttributes == NULL) ||
  7956. (!mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mNoStaticCtorAttributeTypeDef)))
  7957. {
  7958. mModule->CheckStaticAccess(targetTypeInst);
  7959. }
  7960. }
  7961. }
  7962. }
  7963. if (methodInstance->mReturnType == NULL)
  7964. {
  7965. mModule->AssertErrorState();
  7966. mModule->Fail("Circular reference in method instance", targetSrc);
  7967. return BfTypedValue();
  7968. }
  7969. BfCreateCallFlags physCallFlags = BfCreateCallFlags_None;
  7970. if ((origTarget.mType != NULL) && (origTarget.mType->IsGenericParam()))
  7971. physCallFlags = (BfCreateCallFlags)(physCallFlags | BfCreateCallFlags_GenericParamThis);
  7972. auto func = moduleMethodInstance.mFunc;
  7973. BfTypedValue callResult = CreateCall(targetSrc, methodInstance, func, bypassVirtual, irArgs, NULL, physCallFlags, origTarget.mType);
  7974. prevIgnoreWrites.Restore();
  7975. if ((methodInstance->mMethodDef->mIsNoReturn) && ((mBfEvalExprFlags & BfEvalExprFlags_IsExpressionBody) != 0) &&
  7976. (mExpectingType != NULL) && (callResult.mType != mExpectingType))
  7977. {
  7978. callResult = mModule->GetDefaultTypedValue(mExpectingType);
  7979. }
  7980. // This gets triggered for non-sret (ie: comptime) composite returns so they aren't considered readonly
  7981. if ((callResult.mKind == BfTypedValueKind_Value) && (!callResult.mValue.IsConst()) &&
  7982. (!callResult.mType->IsValuelessType()) && (callResult.mType->IsComposite()) && (!methodInstance->GetLoweredReturnType()))
  7983. {
  7984. bool makeAddressable = true;
  7985. auto typeInstance = callResult.mType->ToTypeInstance();
  7986. if ((typeInstance != NULL) && (typeInstance->mHasUnderlyingArray))
  7987. makeAddressable = false;
  7988. if (makeAddressable)
  7989. {
  7990. callResult = mModule->MakeAddressable(callResult, true);
  7991. }
  7992. }
  7993. if (argCascades.mSize == 1)
  7994. {
  7995. if (argCascade == NULL)
  7996. return argCascades[0];
  7997. *argCascade = argCascades[0];
  7998. }
  7999. if (argCascades.mSize > 1)
  8000. {
  8001. if (argCascade == NULL)
  8002. return mModule->CreateTuple(argCascades, {});
  8003. *argCascade = mModule->CreateTuple(argCascades, {});
  8004. }
  8005. return callResult;
  8006. }
  8007. BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBoundExpression* methodBoundExpr, BfTypedValue target, BfTypeInstance* targetType, BfResolvedArgs& argValues, bool callCtorBodyOnly,
  8008. const BfMethodGenericArguments& methodGenericArguments, BfAllowAppendKind allowAppendKind, BfTypedValue* appendIndexValue)
  8009. {
  8010. // Temporarily disable so we don't capture calls in params
  8011. SetAndRestoreValue<BfFunctionBindResult*> prevBindResult(mFunctionBindResult, NULL);
  8012. auto origAllowAppendKind = allowAppendKind;
  8013. if (allowAppendKind == BfAllowAppendKind_Infer)
  8014. {
  8015. mModule->PopulateType(targetType);
  8016. allowAppendKind = targetType->IsZeroGap() ? BfAllowAppendKind_ZeroGap : BfAllowAppendKind_Yes;
  8017. }
  8018. static int sCtorCount = 0;
  8019. sCtorCount++;
  8020. BfMethodMatcher methodMatcher(targetSrc, mModule, "", argValues.mResolvedArgs, methodGenericArguments);
  8021. methodMatcher.mAllowAppendKind = allowAppendKind;
  8022. methodMatcher.mBfEvalExprFlags = mBfEvalExprFlags;
  8023. BfTypeVector typeGenericArguments;
  8024. auto curTypeInst = targetType;
  8025. auto curTypeDef = targetType->mTypeDef;
  8026. BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None;
  8027. auto activeTypeDef = mModule->GetActiveTypeDef();
  8028. auto visibleProjectSet = mModule->GetVisibleProjectSet();
  8029. bool isFailurePass = false;
  8030. for (int pass = 0; pass < 2; pass++)
  8031. {
  8032. isFailurePass = pass == 1;
  8033. curTypeDef->PopulateMemberSets();
  8034. BfMethodDef* nextMethodDef = NULL;
  8035. BfMemberSetEntry* entry;
  8036. if (curTypeDef->mMethodSet.TryGetWith(String("__BfCtor"), &entry))
  8037. nextMethodDef = (BfMethodDef*)entry->mMemberDef;
  8038. while (nextMethodDef != NULL)
  8039. {
  8040. auto checkMethod = nextMethodDef;
  8041. nextMethodDef = nextMethodDef->mNextWithSameName;
  8042. if ((isFailurePass) && (checkMethod->mMethodDeclaration == NULL))
  8043. continue; // Don't match private default ctor if there's a user-defined one
  8044. if (checkMethod->mIsStatic)
  8045. continue;
  8046. if ((checkMethod->mDeclaringType->IsExtension()) && (mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) &&
  8047. (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mNoExtensionAttributeTypeDef)))
  8048. {
  8049. mModule->mAttributeState->mUsed = true;
  8050. continue;
  8051. }
  8052. if (!mModule->IsInSpecializedSection())
  8053. {
  8054. if ((!curTypeInst->IsTypeMemberIncluded(checkMethod->mDeclaringType, activeTypeDef, mModule)) ||
  8055. (!curTypeInst->IsTypeMemberAccessible(checkMethod->mDeclaringType, visibleProjectSet)))
  8056. continue;
  8057. }
  8058. auto checkProt = checkMethod->mProtection;
  8059. if (!isFailurePass)
  8060. {
  8061. if (callCtorBodyOnly)
  8062. {
  8063. if (curTypeDef != mModule->mCurTypeInstance->mTypeDef)
  8064. {
  8065. // We're calling the base class's ctor from a derived class
  8066. if (checkProt <= BfProtection_Private)
  8067. continue;
  8068. }
  8069. }
  8070. else
  8071. {
  8072. if ((checkProt == BfProtection_Protected) || (checkProt == BfProtection_ProtectedInternal)) // Treat protected constructors as private
  8073. checkProt = BfProtection_Private;
  8074. if (!mModule->CheckProtection(protectionCheckFlags, curTypeInst, checkMethod->mDeclaringType->mProject, checkProt, curTypeInst))
  8075. continue;
  8076. }
  8077. }
  8078. methodMatcher.CheckMethod(NULL, curTypeInst, checkMethod, isFailurePass);
  8079. }
  8080. if ((methodMatcher.mBestMethodDef != NULL) || (methodMatcher.mBackupMethodDef != NULL))
  8081. break;
  8082. }
  8083. if (methodMatcher.mBestMethodDef == NULL)
  8084. methodMatcher.mBestMethodDef = methodMatcher.mBackupMethodDef;
  8085. if (methodMatcher.mBestMethodDef == NULL)
  8086. {
  8087. mModule->Fail("No constructor available", targetSrc);
  8088. return BfTypedValue();
  8089. }
  8090. auto methodDef = methodMatcher.mBestMethodDef;
  8091. if (mModule->mCompiler->mResolvePassData != NULL)
  8092. mModule->mCompiler->mResolvePassData->HandleMethodReference(targetSrc, curTypeInst->mTypeDef->GetDefinition(), methodDef);
  8093. // There should always be a constructor
  8094. BF_ASSERT(methodMatcher.mBestMethodDef != NULL);
  8095. //auto moduleMethodInstance = mModule->GetMethodInstance(methodMatcher.mBestMethodTypeInstance, methodMatcher.mBestMethodDef, methodMatcher.mBestMethodGenericArguments);
  8096. auto moduleMethodInstance = GetSelectedMethod(methodMatcher);
  8097. if (!moduleMethodInstance)
  8098. return BfTypedValue();
  8099. if (!mModule->CheckUseMethodInstance(moduleMethodInstance.mMethodInstance, targetSrc))
  8100. return BfTypedValue();
  8101. BfAutoComplete* autoComplete = GetAutoComplete();
  8102. if (autoComplete != NULL)
  8103. {
  8104. BfTypeInstance* resolvedTypeInstance = target.mType->ToTypeInstance();
  8105. auto ctorDecl = BfNodeDynCast<BfConstructorDeclaration>(methodDef->mMethodDeclaration);
  8106. if ((autoComplete->mIsGetDefinition) && (autoComplete->IsAutocompleteNode(targetSrc)) && (!BfNodeIsA<BfDelegateBindExpression>(targetSrc)))
  8107. {
  8108. if ((autoComplete->mDefMethod == NULL) && (autoComplete->mDefField == NULL) &&
  8109. (autoComplete->mDefProp == NULL)
  8110. && ((autoComplete->mDefType == NULL) || (autoComplete->mDefType == resolvedTypeInstance->mTypeDef)))
  8111. {
  8112. // Do we need to do this mDefType setting? If we do, then make sure we only get the element type of generics and such
  8113. //autoComplete->mDefType = resolvedTypeInstance->mTypeDef;
  8114. if (ctorDecl != NULL)
  8115. autoComplete->SetDefinitionLocation(ctorDecl->mThisToken, true);
  8116. else if (resolvedTypeInstance->mTypeDef->mTypeDeclaration != NULL)
  8117. autoComplete->SetDefinitionLocation(resolvedTypeInstance->mTypeDef->mTypeDeclaration->mNameNode, true);
  8118. }
  8119. }
  8120. else if ((autoComplete->mResolveType == BfResolveType_GetResultString) && (autoComplete->IsAutocompleteNode(targetSrc)) &&
  8121. (moduleMethodInstance.mMethodInstance != NULL))
  8122. {
  8123. autoComplete->mResultString = ":";
  8124. autoComplete->mResultString += mModule->MethodToString(moduleMethodInstance.mMethodInstance);
  8125. }
  8126. }
  8127. BfConstructorDeclaration* ctorDecl = (BfConstructorDeclaration*)methodMatcher.mBestMethodDef->mMethodDeclaration;
  8128. if ((methodMatcher.mBestMethodDef->HasAppend()) && (targetType->IsObject()))
  8129. {
  8130. if (allowAppendKind == BfAllowAppendKind_No)
  8131. {
  8132. if (mModule->mCurMethodInstance->mMethodDef->mMethodDeclaration == NULL)
  8133. mModule->Fail("Constructors with append allocations cannot be called from a default constructor. Considering adding an explicit default constructor with the [AllowAppend] specifier.", targetSrc);
  8134. else
  8135. mModule->Fail("Constructors with append allocations cannot be called from a constructor without [AllowAppend] specified.", targetSrc);
  8136. }
  8137. else
  8138. {
  8139. if ((allowAppendKind == BfAllowAppendKind_Yes) && (methodMatcher.mBestMethodDef->mAppendKind == BfAllowAppendKind_ZeroGap))
  8140. {
  8141. BfError* error;
  8142. if (origAllowAppendKind == BfAllowAppendKind_Infer)
  8143. error = mModule->Fail(StrFormat("Cannot call ZeroGap constructor for type '%s' because of fields added from type extensions", mModule->TypeToString(targetType).c_str()), targetSrc);
  8144. else
  8145. error = mModule->Fail(StrFormat("Cannot call ZeroGap constructor for type '%s' from here", mModule->TypeToString(targetType).c_str()), targetSrc);
  8146. if ((error != NULL) && (methodMatcher.mBestMethodDef->mMethodDeclaration != NULL))
  8147. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodMatcher.mBestMethodDef->GetRefNode());
  8148. }
  8149. BfResolvedArg resolvedArg;
  8150. if (appendIndexValue != NULL)
  8151. {
  8152. resolvedArg.mTypedValue = *appendIndexValue;
  8153. }
  8154. else
  8155. {
  8156. auto intPtrType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  8157. auto intPtrRefType = mModule->CreateRefType(intPtrType);
  8158. if (target.mValue.IsFake())
  8159. {
  8160. resolvedArg.mTypedValue = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), intPtrRefType);
  8161. }
  8162. else
  8163. {
  8164. BFMODULE_FATAL(mModule, "Bad");
  8165. }
  8166. }
  8167. methodMatcher.mArguments.Insert(0, resolvedArg);
  8168. }
  8169. }
  8170. if (methodMatcher.mAutoFlushAmbiguityErrors)
  8171. methodMatcher.FlushAmbiguityError(true);
  8172. if (isFailurePass)
  8173. mModule->Fail(StrFormat("'%s' is inaccessible due to its protection level", mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str()), targetSrc);
  8174. prevBindResult.Restore();
  8175. return CreateCall(methodMatcher.mTargetSrc, target, BfTypedValue(), methodMatcher.mBestMethodDef, moduleMethodInstance, BfCreateCallFlags_None, methodMatcher.mArguments);
  8176. }
  8177. static int sInvocationIdx = 0;
  8178. BfTypedValue BfExprEvaluator::ResolveArgValue(BfResolvedArg& resolvedArg, BfType* wantType, BfTypedValue* receivingValue, BfParamKind paramKind, BfIdentifierNode* paramNameNode)
  8179. {
  8180. BfTypedValue argValue = resolvedArg.mTypedValue;
  8181. if ((resolvedArg.mArgFlags & BfArgFlag_Finalized) != 0)
  8182. return argValue;
  8183. if ((resolvedArg.mArgFlags & (BfArgFlag_DelegateBindAttempt | BfArgFlag_LambdaBindAttempt | BfArgFlag_UnqualifiedDotAttempt | BfArgFlag_DeferredEval)) != 0)
  8184. {
  8185. if ((!argValue) || (argValue.mValue.IsFake()) || (resolvedArg.mWantsRecalc))
  8186. {
  8187. resolvedArg.mWantsRecalc = false;
  8188. auto expr = BfNodeDynCast<BfExpression>(resolvedArg.mExpression);
  8189. if (expr != NULL)
  8190. {
  8191. BfExprEvaluator exprEvaluator(mModule);
  8192. exprEvaluator.mReceivingValue = receivingValue;
  8193. BfEvalExprFlags flags = (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_AllowRefExpr);
  8194. if ((paramKind == BfParamKind_Params) || (paramKind == BfParamKind_DelegateParam))
  8195. flags = (BfEvalExprFlags)(flags | BfEvalExprFlags_AllowParamsExpr);
  8196. argValue = mModule->CreateValueFromExpression(exprEvaluator, expr, wantType, flags);
  8197. if ((argValue) && (argValue.mType != wantType) && (wantType != NULL))
  8198. {
  8199. if ((mDeferCallData != NULL) && (wantType == mModule->mContext->mBfObjectType))
  8200. {
  8201. BfAllocTarget allocTarget(mDeferCallData->mScopeAlloc);
  8202. argValue = mModule->BoxValue(expr, argValue, wantType, allocTarget, ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) ? BfCastFlags_WantsConst : BfCastFlags_None);
  8203. }
  8204. else
  8205. argValue = mModule->Cast(expr, argValue, wantType, ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) ? BfCastFlags_WantsConst : BfCastFlags_None);
  8206. }
  8207. }
  8208. }
  8209. }
  8210. else if ((resolvedArg.mArgFlags & (BfArgFlag_DeferredValue)) != 0)
  8211. {
  8212. // We should have already had an error on the first call
  8213. SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, mModule->mHadBuildError);
  8214. auto expr = BfNodeDynCast<BfExpression>(resolvedArg.mExpression);
  8215. BF_ASSERT(expr != NULL);
  8216. argValue = mModule->CreateValueFromExpression(expr, wantType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_AllowRefExpr | BfEvalExprFlags_AllowOutExpr));
  8217. resolvedArg.mUncastedTypedValue = argValue;
  8218. if ((argValue) && (wantType != NULL))
  8219. argValue = mModule->Cast(expr, argValue, wantType);
  8220. }
  8221. else if ((resolvedArg.mArgFlags & (BfArgFlag_UntypedDefault)) != 0)
  8222. {
  8223. argValue = mModule->GetDefaultTypedValue(wantType);
  8224. }
  8225. else if ((resolvedArg.mArgFlags & (BfArgFlag_VariableDeclaration | BfArgFlag_UninitializedExpr)) != 0)
  8226. {
  8227. auto variableDeclaration = BfNodeDynCast<BfVariableDeclaration>(resolvedArg.mExpression);
  8228. auto variableType = wantType;
  8229. bool isLet = (variableDeclaration != NULL) && (variableDeclaration->mTypeRef->IsExact<BfLetTypeReference>());
  8230. bool isVar = (variableDeclaration == NULL) || (variableDeclaration->mTypeRef->IsExact<BfVarTypeReference>());
  8231. if (mModule->mCurMethodState->mPendingNullConditional != NULL)
  8232. {
  8233. mModule->Fail("Variables cannot be declared in method arguments inside null conditional expressions", variableDeclaration);
  8234. }
  8235. if ((!isLet) && (!isVar))
  8236. {
  8237. if (variableType->IsVar())
  8238. {
  8239. auto resolvedType = mModule->ResolveTypeRef(variableDeclaration->mTypeRef);
  8240. if (resolvedType != NULL)
  8241. variableType = resolvedType;
  8242. }
  8243. else
  8244. {
  8245. mModule->Fail("Only 'ref' or 'var' variables can be declared in method arguments", variableDeclaration);
  8246. auto autoComplete = GetAutoComplete();
  8247. if (autoComplete != NULL)
  8248. autoComplete->CheckTypeRef(variableDeclaration->mTypeRef, true, true);
  8249. }
  8250. }
  8251. else
  8252. {
  8253. if (variableType->IsVar())
  8254. {
  8255. mModule->Fail("Variable type required for 'var' parameter types", variableDeclaration);
  8256. }
  8257. }
  8258. if (wantType->IsRef())
  8259. {
  8260. auto refType = (BfRefType*)wantType;
  8261. variableType = refType->mElementType;
  8262. }
  8263. if ((variableDeclaration != NULL) && (variableDeclaration->mInitializer != NULL))
  8264. {
  8265. mModule->Fail("Initializers cannot be used when declaring variables for 'out' parameters", variableDeclaration->mEqualsNode);
  8266. mModule->CreateValueFromExpression(variableDeclaration->mInitializer, variableType, BfEvalExprFlags_NoCast);
  8267. }
  8268. argValue = mModule->CreateOutVariable(resolvedArg.mExpression, variableDeclaration, paramNameNode, variableType, BfTypedValue());
  8269. }
  8270. return argValue;
  8271. }
  8272. BfTypedValue BfExprEvaluator::CheckEnumCreation(BfAstNode* targetSrc, BfTypeInstance* enumType, const StringImpl& caseName, BfResolvedArgs& argValues)
  8273. {
  8274. auto activeTypeDef = mModule->GetActiveTypeDef();
  8275. mModule->PopulateType(enumType);
  8276. mModule->mBfIRBuilder->PopulateType(enumType);
  8277. auto resolvePassData = mModule->mCompiler->mResolvePassData;
  8278. // if (resolvePassData != NULL)
  8279. // {
  8280. // if (mModule->mParentNodeEntry != NULL)
  8281. // {
  8282. // if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(mModule->mParentNodeEntry->mNode))
  8283. // {
  8284. // if (auto memberRefExpr = BfNodeDynCast<BfMemberReferenceExpression>(invocationExpr->mTarget))
  8285. // {
  8286. // BfAstNode* dotNode = memberRefExpr->mDotToken;
  8287. // BfAstNode* nameNode = targetSrc;
  8288. // String filter;
  8289. // auto autoComplete = resolvePassData->mAutoComplete;
  8290. // if ((autoComplete != NULL) && (autoComplete->InitAutocomplete(dotNode, nameNode, filter)))
  8291. // autoComplete->AddEnumTypeMembers(enumType, caseName, false, enumType == mModule->mCurTypeInstance);
  8292. // }
  8293. // }
  8294. // }
  8295. // }
  8296. for (int fieldIdx = 0; fieldIdx < (int)enumType->mFieldInstances.size(); fieldIdx++)
  8297. {
  8298. auto fieldInstance = &enumType->mFieldInstances[fieldIdx];
  8299. auto fieldDef = fieldInstance->GetFieldDef();
  8300. if (fieldDef == NULL)
  8301. continue;
  8302. if ((fieldInstance->mIsEnumPayloadCase) && (fieldDef->mName == caseName))
  8303. {
  8304. if ((!enumType->IsTypeMemberIncluded(fieldDef->mDeclaringType, activeTypeDef, mModule)) ||
  8305. (!enumType->IsTypeMemberAccessible(fieldDef->mDeclaringType, activeTypeDef)))
  8306. continue;
  8307. auto autoComplete = GetAutoComplete();
  8308. if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo))
  8309. {
  8310. BfAutoComplete::MethodMatchEntry methodMatchEntry;
  8311. methodMatchEntry.mPayloadEnumField = fieldInstance;
  8312. methodMatchEntry.mTypeInstance = enumType;
  8313. methodMatchEntry.mCurMethodInstance = mModule->mCurMethodInstance;
  8314. autoComplete->mMethodMatchInfo->mInstanceList.push_back(methodMatchEntry);
  8315. }
  8316. if (resolvePassData != NULL)
  8317. {
  8318. BfAstNode* nameNode = targetSrc;
  8319. if (resolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Field)
  8320. resolvePassData->HandleFieldReference(nameNode, enumType->mTypeDef, fieldDef);
  8321. }
  8322. BfIRValue enumValue;
  8323. BfTypedValue result;
  8324. bool wantConst = IsConstEval();
  8325. if (wantConst)
  8326. {
  8327. //
  8328. }
  8329. else if ((mReceivingValue != NULL) && (mReceivingValue->mType == enumType) && (mReceivingValue->IsAddr()))
  8330. {
  8331. result = *mReceivingValue;
  8332. mReceivingValue = NULL;
  8333. enumValue = result.mValue;
  8334. }
  8335. else
  8336. {
  8337. mResultIsTempComposite = true;
  8338. enumValue = mModule->CreateAlloca(enumType);
  8339. result = BfTypedValue(enumValue, fieldInstance->mOwner, BfTypedValueKind_TempAddr);
  8340. }
  8341. BF_ASSERT(fieldInstance->mResolvedType->IsTuple());
  8342. auto tupleType = (BfTypeInstance*)fieldInstance->mResolvedType;
  8343. mModule->mBfIRBuilder->PopulateType(tupleType);
  8344. if (tupleType->IsDeleting())
  8345. {
  8346. mModule->FailInternal("Deleted tuple type found in CheckEnumCreation", targetSrc);
  8347. return BfTypedValue();
  8348. }
  8349. bool constFailed = false;
  8350. SizedArray<BfIRValue, 8> constTupleMembers;
  8351. BfIRValue fieldPtr;
  8352. BfIRValue tuplePtr;
  8353. if (wantConst)
  8354. {
  8355. constTupleMembers.Add(mModule->mBfIRBuilder->CreateConstAggZero(mModule->mBfIRBuilder->MapType(tupleType->mBaseType)));
  8356. }
  8357. else if (!tupleType->IsValuelessType())
  8358. {
  8359. fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(enumValue, 0, 1);
  8360. auto tuplePtrType = mModule->CreatePointerType(tupleType);
  8361. auto mappedPtrType = mModule->mBfIRBuilder->MapType(tuplePtrType);
  8362. tuplePtr = mModule->mBfIRBuilder->CreateBitCast(fieldPtr, mappedPtrType);
  8363. }
  8364. for (int tupleFieldIdx = 0; tupleFieldIdx < (int)tupleType->mFieldInstances.size(); tupleFieldIdx++)
  8365. {
  8366. auto tupleFieldInstance = &tupleType->mFieldInstances[tupleFieldIdx];
  8367. auto resolvedFieldType = tupleFieldInstance->GetResolvedType();
  8368. if (tupleFieldIdx >= argValues.mResolvedArgs.size())
  8369. {
  8370. BfAstNode* refNode = targetSrc;
  8371. BfAstNode* prevNode = NULL;
  8372. if (mModule->mParentNodeEntry != NULL)
  8373. {
  8374. if (auto invokeExpr = BfNodeDynCast<BfInvocationExpression>(mModule->mParentNodeEntry->mNode))
  8375. {
  8376. if (invokeExpr->mCloseParen != NULL)
  8377. refNode = invokeExpr->mCloseParen;
  8378. }
  8379. }
  8380. BfError* error = mModule->Fail(StrFormat("Not enough parameters specified, expected %d more.", tupleType->mFieldInstances.size() - (int)argValues.mArguments->size()), refNode);
  8381. if (error != NULL)
  8382. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See enum declaration"), fieldDef->mFieldDeclaration);
  8383. if (wantConst)
  8384. constFailed = true;
  8385. break;
  8386. }
  8387. BfTypedValue receivingValue;
  8388. BfIRValue tupleFieldPtr;
  8389. mModule->PopulateType(tupleFieldInstance->mResolvedType);
  8390. if (tupleFieldInstance->mResolvedType->IsValuelessType())
  8391. {
  8392. receivingValue = mModule->GetDefaultTypedValue(tupleFieldInstance->mResolvedType);
  8393. }
  8394. else if (tuplePtr)
  8395. {
  8396. tupleFieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(tuplePtr, 0, tupleFieldInstance->mDataIdx);
  8397. receivingValue = BfTypedValue(tupleFieldPtr, tupleFieldInstance->mResolvedType, true);
  8398. }
  8399. auto argValue = ResolveArgValue(argValues.mResolvedArgs[tupleFieldIdx], resolvedFieldType, &receivingValue);
  8400. if (!argValue)
  8401. {
  8402. if (wantConst)
  8403. constFailed = true;
  8404. continue;
  8405. }
  8406. if (resolvedFieldType->IsValuelessType())
  8407. continue;
  8408. // Used receiving value?
  8409. if (argValue.mValue == receivingValue.mValue)
  8410. continue;
  8411. argValue = mModule->AggregateSplat(argValue);
  8412. argValues.mResolvedArgs[tupleFieldIdx].mExpectedType = resolvedFieldType;
  8413. if ((argValues.mResolvedArgs[tupleFieldIdx].mArgFlags & (BfArgFlag_DelegateBindAttempt | BfArgFlag_LambdaBindAttempt | BfArgFlag_UnqualifiedDotAttempt)) != 0)
  8414. {
  8415. auto expr = BfNodeDynCast<BfExpression>(argValues.mResolvedArgs[tupleFieldIdx].mExpression);
  8416. BF_ASSERT(expr != NULL);
  8417. argValue = mModule->CreateValueFromExpression(expr, resolvedFieldType, (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags));
  8418. }
  8419. if (argValue)
  8420. {
  8421. if ((argValue.mType->IsRef()) && (argValue.mType->GetUnderlyingType() == resolvedFieldType))
  8422. {
  8423. if (auto unaryOperator = BfNodeDynCast<BfUnaryOperatorExpression>(argValues.mResolvedArgs[tupleFieldIdx].mExpression))
  8424. {
  8425. mModule->Fail(StrFormat("Invalid use of '%s'. Enum payloads can only be retrieved through 'case' expressions.", BfGetOpName(unaryOperator->mOp)), unaryOperator->mOpToken);
  8426. argValue = mModule->GetDefaultTypedValue(resolvedFieldType);
  8427. }
  8428. else if (auto varDecl = BfNodeDynCast<BfVariableDeclaration>(argValues.mResolvedArgs[tupleFieldIdx].mExpression))
  8429. {
  8430. mModule->Fail("Invalid variable declaration. Enum payloads can only be retrieved through 'case' expressions.", varDecl);
  8431. argValue = mModule->GetDefaultTypedValue(resolvedFieldType);
  8432. }
  8433. }
  8434. // argValue can have a value even if tuplePtr does not have a value. This can happen if we are assigning to a (void) tuple,
  8435. // but we have a value that needs to be attempted to be casted to void
  8436. argValue = mModule->Cast(argValues.mResolvedArgs[tupleFieldIdx].mExpression, argValue, resolvedFieldType, wantConst ? BfCastFlags_WantsConst : BfCastFlags_None);
  8437. if (wantConst)
  8438. {
  8439. if (!argValue.mValue.IsConst())
  8440. {
  8441. mModule->Fail("Field not const", argValues.mResolvedArgs[tupleFieldIdx].mExpression);
  8442. constFailed = true;
  8443. }
  8444. constTupleMembers.Add(argValue.mValue);
  8445. }
  8446. else if (tupleFieldPtr)
  8447. {
  8448. argValue = mModule->LoadValue(argValue);
  8449. if (argValue)
  8450. mModule->mBfIRBuilder->CreateAlignedStore(argValue.mValue, tupleFieldPtr, resolvedFieldType->mAlign);
  8451. }
  8452. }
  8453. else if (wantConst)
  8454. constFailed = true;
  8455. }
  8456. if ((intptr)argValues.mResolvedArgs.size() > tupleType->mFieldInstances.size())
  8457. {
  8458. BfAstNode* errorRef = argValues.mResolvedArgs[tupleType->mFieldInstances.size()].mExpression;
  8459. if (errorRef == NULL)
  8460. errorRef = targetSrc;
  8461. BfError* error = mModule->Fail(StrFormat("Too many arguments, expected %d fewer.", argValues.mResolvedArgs.size() - tupleType->mFieldInstances.size()), errorRef);
  8462. if (error != NULL)
  8463. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See enum declaration"), fieldDef->mFieldDeclaration);
  8464. if (wantConst)
  8465. constFailed = true;
  8466. }
  8467. auto dscrType = enumType->GetDiscriminatorType();
  8468. auto dscrField = &enumType->mFieldInstances.back();
  8469. int tagIdx = -fieldInstance->mDataIdx - 1;
  8470. if ((wantConst) && (!constFailed))
  8471. {
  8472. auto unionType = enumType->GetUnionInnerType();
  8473. auto constTuple = mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(tupleType, BfIRPopulateType_Full), constTupleMembers);
  8474. Array<uint8> memArr;
  8475. memArr.Resize(unionType->mSize);
  8476. if (!mModule->mBfIRBuilder->WriteConstant(constTuple, memArr.mVals, tupleType))
  8477. {
  8478. constFailed = true;
  8479. }
  8480. else
  8481. {
  8482. auto unionValue = mModule->mBfIRBuilder->ReadConstant(memArr.mVals, unionType);
  8483. if (!unionValue)
  8484. {
  8485. constFailed = true;
  8486. }
  8487. else
  8488. {
  8489. SizedArray<BfIRValue, 3> constEnumMembers;
  8490. constEnumMembers.Add(mModule->mBfIRBuilder->CreateConstAggZero(mModule->mBfIRBuilder->MapType(enumType->mBaseType, BfIRPopulateType_Full)));
  8491. constEnumMembers.Add(unionValue);
  8492. constEnumMembers.Add(mModule->mBfIRBuilder->CreateConst(dscrType->mTypeDef->mTypeCode, tagIdx));
  8493. return BfTypedValue(mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(enumType, BfIRPopulateType_Full), constEnumMembers), enumType);
  8494. }
  8495. }
  8496. }
  8497. if (constFailed)
  8498. {
  8499. return mModule->GetDefaultTypedValue(enumType, false, BfDefaultValueKind_Addr);
  8500. }
  8501. auto dscFieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(enumValue, 0, dscrField->mDataIdx);
  8502. mModule->mBfIRBuilder->CreateAlignedStore(mModule->mBfIRBuilder->CreateConst(dscrType->mTypeDef->mTypeCode, tagIdx), dscFieldPtr, 4);
  8503. return result;
  8504. }
  8505. }
  8506. return BfTypedValue();
  8507. }
  8508. bool BfExprEvaluator::CheckGenericCtor(BfGenericParamType* genericParamType, BfResolvedArgs& argValues, BfAstNode* targetSrc)
  8509. {
  8510. BfGenericParamFlags genericParamFlags = BfGenericParamFlag_None;
  8511. BfType* typeConstraint = NULL;
  8512. auto genericParam = mModule->GetMergedGenericParamData((BfGenericParamType*)genericParamType, genericParamFlags, typeConstraint);
  8513. bool success = true;
  8514. if ((argValues.mArguments != NULL) && (argValues.mArguments->size() != 0))
  8515. {
  8516. mModule->Fail(StrFormat("Only default parameterless constructors can be called on generic argument '%s'", genericParam->GetGenericParamDef()->mName.c_str()), targetSrc);
  8517. success = false;
  8518. }
  8519. else if ((genericParamFlags & (BfGenericParamFlag_New | BfGenericParamFlag_Struct | BfGenericParamFlag_Var)) == 0)
  8520. {
  8521. mModule->Fail(StrFormat("Must add 'where %s : new, struct' constraint to generic parameter to instantiate type", genericParam->GetGenericParamDef()->mName.c_str()), targetSrc);
  8522. success = false;
  8523. }
  8524. else if ((genericParamFlags & (BfGenericParamFlag_New | BfGenericParamFlag_Var)) == 0)
  8525. {
  8526. mModule->Fail(StrFormat("Must add 'where %s : new' constraint to generic parameter to instantiate type", genericParam->GetGenericParamDef()->mName.c_str()), targetSrc);
  8527. success = false;
  8528. }
  8529. else if ((genericParamFlags & (BfGenericParamFlag_Struct | BfGenericParamFlag_Var)) == 0)
  8530. {
  8531. mModule->Fail(StrFormat("Must add 'where %s : struct' constraint to generic parameter to instantiate type without allocator", genericParam->GetGenericParamDef()->mName.c_str()), targetSrc);
  8532. success = false;
  8533. }
  8534. else if ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0)
  8535. {
  8536. mModule->Fail(StrFormat("Generic parameter '%s' constructor cannot be guaranteed to be const-evaluable", genericParam->GetGenericParamDef()->mName.c_str()), targetSrc);
  8537. }
  8538. return success;
  8539. }
  8540. BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExpression* methodBoundExpr, BfTypedValue target, bool allowImplicitThis, bool bypassVirtual, const StringImpl& methodName,
  8541. BfResolvedArgs& argValues, const BfMethodGenericArguments& methodGenericArgs, BfCheckedKind checkedKind)
  8542. {
  8543. BP_ZONE("MatchMethod");
  8544. auto methodGenericArguments = methodGenericArgs.mArguments;
  8545. if (bypassVirtual)
  8546. {
  8547. // "bypassVirtual" means that we know for sure that the target is EXACTLY the specified target type,
  8548. // not derived from (or implementing) the target type. This cannot apply to interfaces.
  8549. BF_ASSERT(!target.mType->IsInterface());
  8550. }
  8551. auto origTarget = target;
  8552. if (mFunctionBindResult != NULL)
  8553. {
  8554. BF_ASSERT(!mFunctionBindResult->mOrigTarget);
  8555. mFunctionBindResult->mOrigTarget = origTarget;
  8556. }
  8557. if (target)
  8558. {
  8559. if (target.mType->IsConcreteInterfaceType())
  8560. target.mType = target.mType->GetUnderlyingType();
  8561. // Turn T* into a T, if we can
  8562. if ((target.mType->IsPointer()) && (target.mType->GetUnderlyingType()->IsGenericParam()))
  8563. {
  8564. auto underlyingType = target.mType->GetUnderlyingType();
  8565. auto genericParam = mModule->GetGenericParamInstance((BfGenericParamType*)underlyingType);
  8566. if (((genericParam->mTypeConstraint != NULL) && (genericParam->mTypeConstraint->IsValueType())) ||
  8567. ((genericParam->mGenericParamFlags & (BfGenericParamFlag_Struct)) != 0))
  8568. {
  8569. target.mType = underlyingType;
  8570. }
  8571. }
  8572. if ((!target.mType->IsGenericParam()) &&
  8573. ((!target.IsSplat()) || (target.mType->IsWrappableType())) &&
  8574. (!IsVar(target.mType)))
  8575. target = MakeCallableTarget(targetSrc, target);
  8576. }
  8577. // static int sCallIdx = 0;
  8578. // if (!mModule->mCompiler->mIsResolveOnly)
  8579. // sCallIdx++;
  8580. // int callIdx = sCallIdx;
  8581. // if (callIdx == 118)
  8582. // {
  8583. // NOP;
  8584. // }
  8585. bool prevAllowVariableDeclarations = true;
  8586. if (mModule->mCurMethodState != NULL)
  8587. {
  8588. // Don't allow variable declarations in arguments for this method call
  8589. prevAllowVariableDeclarations = mModule->mCurMethodState->mCurScope->mAllowVariableDeclarations;
  8590. mModule->mCurMethodState->mCurScope->mAllowVariableDeclarations = false;
  8591. }
  8592. defer
  8593. (
  8594. if (mModule->mCurMethodState != NULL)
  8595. mModule->mCurMethodState->mCurScope->mAllowVariableDeclarations = prevAllowVariableDeclarations;
  8596. );
  8597. // Temporarily disable so we don't capture calls in params
  8598. SetAndRestoreValue<BfFunctionBindResult*> prevBindResult(mFunctionBindResult, NULL);
  8599. sInvocationIdx++;
  8600. bool wantCtor = methodName.IsEmpty();
  8601. BfAutoComplete::MethodMatchInfo* restoreCapturingMethodMatchInfo = NULL;
  8602. auto autoComplete = GetAutoComplete();
  8603. if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo))
  8604. {
  8605. if ((!targetSrc->IsFromParser(mModule->mCompiler->mResolvePassData->mParsers[0])) ||
  8606. ((autoComplete->mMethodMatchInfo->mInvocationSrcIdx != -1) && (autoComplete->mMethodMatchInfo->mInvocationSrcIdx != targetSrc->GetSrcStart())))
  8607. {
  8608. autoComplete->mIsCapturingMethodMatchInfo = false;
  8609. restoreCapturingMethodMatchInfo = autoComplete->mMethodMatchInfo;
  8610. }
  8611. }
  8612. defer(
  8613. {
  8614. if ((restoreCapturingMethodMatchInfo != NULL) && (autoComplete->mMethodMatchInfo == restoreCapturingMethodMatchInfo))
  8615. autoComplete->mIsCapturingMethodMatchInfo = true;
  8616. });
  8617. /*if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo) && (autoComplete->mMethodMatchInfo->mInstanceList.size() != 0))
  8618. autoComplete->mIsCapturingMethodMatchInfo = false;*/
  8619. bool isUnboundCall = false;
  8620. if (target.mType != NULL)
  8621. {
  8622. if (target.mType->IsGenericParam())
  8623. {
  8624. auto genericParamTarget = (BfGenericParamType*) target.mType;
  8625. auto genericParamInstance = mModule->GetGenericParamInstance(genericParamTarget);
  8626. isUnboundCall = (genericParamInstance->mGenericParamFlags & BfGenericParamFlag_Var) != 0;
  8627. if (isUnboundCall)
  8628. {
  8629. if (mModule->mCurMethodInstance->mIsUnspecialized)
  8630. {
  8631. auto varType = mModule->GetPrimitiveType(BfTypeCode_Var);
  8632. target.mType = varType;
  8633. }
  8634. }
  8635. }
  8636. else if (IsVar(target.mType))
  8637. isUnboundCall = true;
  8638. }
  8639. /*if (mPrefixedAttributeState != NULL)
  8640. {
  8641. auto customAttr = mPrefixedAttributeState->mCustomAttributes->Get(mModule->mCompiler->mUnboundAttributeTypeDef);
  8642. if (customAttr != NULL)
  8643. {
  8644. if (!mModule->IsInGeneric())
  8645. {
  8646. mModule->Fail("'Unbound' can only be used within generics");
  8647. }
  8648. mPrefixedAttributeState->mUsed = true;
  8649. isUnboundCall = true;
  8650. }
  8651. }*/
  8652. if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL))
  8653. {
  8654. auto customAttr = mModule->mAttributeState->mCustomAttributes->Get(mModule->mCompiler->mUnboundAttributeTypeDef);
  8655. if (customAttr != NULL)
  8656. {
  8657. if (!mModule->IsInGeneric())
  8658. {
  8659. mModule->Fail("'Unbound' can only be used within generics");
  8660. }
  8661. mModule->mAttributeState->mUsed = true;
  8662. isUnboundCall = true;
  8663. }
  8664. }
  8665. if (isUnboundCall)
  8666. {
  8667. if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsUnspecialized))
  8668. {
  8669. auto varType = mModule->GetPrimitiveType(BfTypeCode_Var);
  8670. for (int argIdx = 0; argIdx < (int)argValues.mResolvedArgs.size(); argIdx++)
  8671. {
  8672. if ((argValues.mResolvedArgs[argIdx].mArgFlags & BfArgFlag_DeferredEval) != 0)
  8673. {
  8674. mModule->CreateValueFromExpression((*argValues.mArguments)[argIdx], varType);
  8675. }
  8676. }
  8677. return BfTypedValue(mModule->GetDefaultValue(varType), varType);
  8678. }
  8679. }
  8680. SetAndRestoreValue<bool> prevNoBind(mNoBind, mNoBind || isUnboundCall);
  8681. bool wantsExtensionCheck = target;
  8682. auto targetType = target.mType;
  8683. BfTypeDef* curTypeDef = NULL;
  8684. BfType* selfType = NULL;
  8685. BfTypeInstance* targetTypeInst = NULL;
  8686. bool checkNonStatic = true;
  8687. if (target)
  8688. {
  8689. if (IsVar(targetType))
  8690. return mModule->GetDefaultTypedValue(targetType);
  8691. targetTypeInst = targetType->ToTypeInstance();
  8692. if (targetTypeInst != NULL)
  8693. curTypeDef = targetTypeInst->mTypeDef;
  8694. }
  8695. else if (targetType != NULL) // Static targeted
  8696. {
  8697. if (targetType->IsWrappableType())
  8698. {
  8699. if ((targetType->IsPrimitiveType()) && (methodName.IsEmpty()))
  8700. {
  8701. if (argValues.mArguments->IsEmpty())
  8702. {
  8703. return mModule->GetDefaultTypedValue(targetType);
  8704. }
  8705. else if (argValues.mArguments->mSize == 1)
  8706. {
  8707. FinishDeferredEvals(argValues);
  8708. // This is just a primitive cast
  8709. auto& resolvedArg = argValues.mResolvedArgs[0];
  8710. BfTypedValue castedValue;
  8711. BfTypedValue castTarget = resolvedArg.mTypedValue;
  8712. if (resolvedArg.mTypedValue)
  8713. {
  8714. castTarget = mModule->LoadValue(castTarget);
  8715. castedValue = mModule->Cast(targetSrc, castTarget, targetType, BfCastFlags_Explicit);
  8716. }
  8717. if (!castedValue)
  8718. castedValue = mModule->GetDefaultTypedValue(targetType);
  8719. return castedValue;
  8720. }
  8721. }
  8722. targetTypeInst = mModule->GetWrappedStructType(targetType);
  8723. }
  8724. else if (targetType->IsGenericParam())
  8725. {
  8726. auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)targetType);
  8727. if (genericParamInstance->mTypeConstraint != NULL)
  8728. targetTypeInst = genericParamInstance->mTypeConstraint->ToTypeInstance();
  8729. if (genericParamInstance->mGenericParamFlags & BfGenericParamFlag_Var)
  8730. {
  8731. auto varType = mModule->GetPrimitiveType(BfTypeCode_Var);
  8732. return BfTypedValue(mModule->GetDefaultValue(varType), varType);
  8733. }
  8734. }
  8735. else
  8736. targetTypeInst = targetType->ToTypeInstance();
  8737. if (targetTypeInst == NULL)
  8738. {
  8739. //mModule->Fail("No static methods available", targetSrc);
  8740. //return BfTypedValue();
  8741. }
  8742. else
  8743. {
  8744. curTypeDef = targetTypeInst->mTypeDef;
  8745. checkNonStatic = false;
  8746. }
  8747. }
  8748. else // Current scopeData
  8749. {
  8750. if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsForeignMethodDef) && (mModule->mCurMethodInstance->mMethodInfoEx->mForeignType->IsInterface()))
  8751. {
  8752. targetTypeInst = mModule->mCurMethodInstance->mMethodInfoEx->mForeignType;
  8753. curTypeDef = targetTypeInst->mTypeDef;
  8754. checkNonStatic = true;
  8755. target = mModule->GetThis();
  8756. selfType = mModule->mCurTypeInstance;
  8757. //target.mType = targetTypeInst;
  8758. }
  8759. else
  8760. {
  8761. curTypeDef = mModule->mCurTypeInstance->mTypeDef;
  8762. targetTypeInst = mModule->mCurTypeInstance;
  8763. if (mModule->mCurMethodState == NULL)
  8764. {
  8765. checkNonStatic = false;
  8766. }
  8767. else
  8768. {
  8769. if (mModule->mCurMethodState->mMixinState != NULL)
  8770. {
  8771. targetTypeInst = mModule->mCurMethodState->mMixinState->mMixinMethodInstance->GetOwner();
  8772. curTypeDef = targetTypeInst->mTypeDef;
  8773. }
  8774. if (mModule->mCurMethodState->mTempKind != BfMethodState::TempKind_None)
  8775. {
  8776. checkNonStatic = mModule->mCurMethodState->mTempKind == BfMethodState::TempKind_NonStatic;
  8777. }
  8778. else
  8779. checkNonStatic = !mModule->mCurMethodInstance->mMethodDef->mIsStatic;
  8780. }
  8781. }
  8782. }
  8783. bool isIndirectMethodCall = false;
  8784. BfType* lookupType = targetType;
  8785. BfTypeInstance* lookupTypeInst = targetTypeInst;
  8786. if (targetType != NULL)
  8787. {
  8788. lookupType = BindGenericType(targetSrc, targetType);
  8789. if (lookupType->IsGenericParam())
  8790. lookupTypeInst = NULL;
  8791. }
  8792. if ((mModule->mIsReified) && (targetTypeInst != NULL) && (!targetTypeInst->mIsReified) && (!targetTypeInst->mModule->mReifyQueued))
  8793. mModule->PopulateType(targetTypeInst);
  8794. BfMethodDef* methodDef = NULL;
  8795. BfTypeVector checkMethodGenericArguments;
  8796. BfTypeInstance* curTypeInst = targetTypeInst;
  8797. Array<SizedArray<BfUsingFieldData::MemberRef, 1>*> methodUsingLists;
  8798. BfMethodMatcher methodMatcher(targetSrc, mModule, methodName, argValues.mResolvedArgs, methodGenericArgs);
  8799. methodMatcher.mUsingLists = &methodUsingLists;
  8800. methodMatcher.mOrigTarget = origTarget;
  8801. methodMatcher.mTarget = target;
  8802. methodMatcher.mCheckedKind = checkedKind;
  8803. methodMatcher.mAllowImplicitThis = allowImplicitThis;
  8804. methodMatcher.mAllowStatic = !target.mValue;
  8805. methodMatcher.mAllowNonStatic = !methodMatcher.mAllowStatic;
  8806. methodMatcher.mAutoFlushAmbiguityErrors = !wantsExtensionCheck;
  8807. if (allowImplicitThis)
  8808. {
  8809. if (mModule->mCurMethodState == NULL)
  8810. {
  8811. methodMatcher.mAllowStatic = true;
  8812. methodMatcher.mAllowNonStatic = false;
  8813. }
  8814. else if (mModule->mCurMethodState->mTempKind != BfMethodState::TempKind_None)
  8815. {
  8816. methodMatcher.mAllowNonStatic = mModule->mCurMethodState->mTempKind == BfMethodState::TempKind_NonStatic;
  8817. methodMatcher.mAllowStatic = true;
  8818. }
  8819. else
  8820. {
  8821. if (!mModule->mCurMethodInstance->mMethodDef->mIsStatic)
  8822. methodMatcher.mAllowNonStatic = true;
  8823. methodMatcher.mAllowStatic = true;
  8824. if (mModule->mCurMethodInstance->mMethodDef->mIsLocalMethod)
  8825. {
  8826. auto rootMethodState = mModule->mCurMethodState->GetRootMethodState();
  8827. methodMatcher.mAllowNonStatic = !rootMethodState->mMethodInstance->mMethodDef->mIsStatic;
  8828. }
  8829. }
  8830. }
  8831. if (methodName == BF_METHODNAME_CALCAPPEND)
  8832. methodMatcher.mMethodType = BfMethodType_CtorCalcAppend;
  8833. BF_ASSERT(methodMatcher.mBestMethodDef == NULL);
  8834. BfLocalMethod* matchedLocalMethod = NULL;
  8835. if (target.mType == NULL)
  8836. {
  8837. CheckLocalMethods(targetSrc, curTypeInst, methodName, methodMatcher, BfMethodType_Normal);
  8838. if (methodMatcher.mBestMethodDef == NULL)
  8839. methodMatcher.mBestMethodDef = methodMatcher.mBackupMethodDef;
  8840. if (methodMatcher.mBestMethodDef != NULL)
  8841. {
  8842. auto rootMethodState = mModule->mCurMethodState->GetRootMethodState();
  8843. auto methodDef = methodMatcher.mBestMethodDef;
  8844. if (mModule->mCompiler->mResolvePassData != NULL)
  8845. {
  8846. auto identifierNode = BfNodeDynCast<BfIdentifierNode>(targetSrc);
  8847. mModule->mCompiler->mResolvePassData->HandleLocalReference(identifierNode, curTypeInst->mTypeDef, rootMethodState->mMethodInstance->mMethodDef, ~methodDef->mIdx);
  8848. auto autoComplete = GetAutoComplete();
  8849. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(identifierNode)))
  8850. {
  8851. autoComplete->SetDefinitionLocation(methodDef->GetRefNode(), true);
  8852. if (autoComplete->mDefType == NULL)
  8853. {
  8854. autoComplete->mDefMethod = mModule->mCurMethodState->GetRootMethodState()->mMethodInstance->mMethodDef;
  8855. autoComplete->mDefType = curTypeDef;
  8856. autoComplete->mReplaceLocalId = ~methodDef->mIdx;
  8857. }
  8858. }
  8859. if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo))
  8860. {
  8861. BfAutoComplete::MethodMatchEntry methodMatchEntry;
  8862. methodMatchEntry.mMethodDef = methodDef;
  8863. methodMatchEntry.mTypeInstance = mModule->mCurTypeInstance;
  8864. methodMatchEntry.mCurMethodInstance = mModule->mCurMethodInstance;
  8865. autoComplete->mMethodMatchInfo->mInstanceList.push_back(methodMatchEntry);
  8866. }
  8867. }
  8868. if ((mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mCapturing))
  8869. {
  8870. auto methodInstance = mModule->GetRawMethodInstance(methodMatcher.mBestMethodTypeInstance, methodMatcher.mBestMethodDef);
  8871. if (methodInstance->mReturnType == NULL)
  8872. {
  8873. FinishDeferredEvals(argValues);
  8874. // If we are recursive then we won't even have a completed methodInstance yet to look at
  8875. return mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  8876. }
  8877. }
  8878. }
  8879. }
  8880. if (methodMatcher.mBestMethodDef == NULL)
  8881. {
  8882. if (lookupTypeInst == NULL)
  8883. {
  8884. if ((lookupType != NULL) && (lookupType->IsConcreteInterfaceType()))
  8885. {
  8886. auto concreteInterfaceType = (BfConcreteInterfaceType*)lookupType;
  8887. lookupTypeInst = concreteInterfaceType->mInterface;
  8888. }
  8889. else if (isUnboundCall)
  8890. {
  8891. //auto resolvedType = mModule->ResolveGenericType(lookupType);
  8892. }
  8893. else if (lookupType->IsGenericParam())
  8894. {
  8895. auto genericParamTarget = (BfGenericParamType*)lookupType;
  8896. auto _HandleGenericParamInstance = [&](BfGenericParamInstance* genericParamInstance)
  8897. {
  8898. if (genericParamInstance->mTypeConstraint != NULL)
  8899. lookupTypeInst = genericParamInstance->mTypeConstraint->ToTypeInstance();
  8900. else
  8901. lookupTypeInst = mModule->mContext->mBfObjectType;
  8902. for (BfType* ifaceInst : genericParamInstance->mInterfaceConstraints)
  8903. {
  8904. BfTypeInstance* typeInst = ifaceInst->ToTypeInstance();
  8905. BF_ASSERT(typeInst != NULL);
  8906. if (methodMatcher.CheckType(typeInst, target, false))
  8907. methodMatcher.mSelfType = lookupType;
  8908. }
  8909. };
  8910. auto genericParamInstance = mModule->GetGenericParamInstance(genericParamTarget, true);
  8911. _HandleGenericParamInstance(genericParamInstance);
  8912. // Check method generic constraints
  8913. if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsUnspecialized) && (mModule->mCurMethodInstance->mMethodInfoEx != NULL))
  8914. {
  8915. for (int genericParamIdx = (int)mModule->mCurMethodInstance->mMethodInfoEx->mMethodGenericArguments.size();
  8916. genericParamIdx < mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams.size(); genericParamIdx++)
  8917. {
  8918. auto genericParam = mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
  8919. if (genericParam->mExternType == lookupType)
  8920. _HandleGenericParamInstance(genericParam);
  8921. }
  8922. }
  8923. }
  8924. }
  8925. if ((lookupTypeInst != NULL) && (!wantCtor))
  8926. {
  8927. methodMatcher.mBypassVirtual = bypassVirtual;
  8928. methodMatcher.CheckType(lookupTypeInst, target, false);
  8929. }
  8930. if ((lookupType != NULL) && (lookupType->IsGenericParam()))
  8931. {
  8932. //lookupType = mModule->ResolveGenericType(lookupType);
  8933. if (!lookupType->IsGenericParam())
  8934. {
  8935. target = MakeCallableTarget(targetSrc, target);
  8936. if (target)
  8937. {
  8938. lookupTypeInst = lookupType->ToTypeInstance();
  8939. }
  8940. }
  8941. }
  8942. }
  8943. bool isFailurePass = false;
  8944. if (methodMatcher.mBestMethodDef == NULL)
  8945. {
  8946. isFailurePass = true;
  8947. if (lookupTypeInst != NULL)
  8948. methodMatcher.CheckType(lookupTypeInst, target, true);
  8949. }
  8950. BfTypedValue staticResult;
  8951. //
  8952. {
  8953. auto devirtTarget = target;
  8954. if ((devirtTarget.mType == NULL) && (selfType != NULL))
  8955. devirtTarget.mType = selfType;
  8956. methodMatcher.TryDevirtualizeCall(devirtTarget, &origTarget, &staticResult);
  8957. }
  8958. if (staticResult)
  8959. return staticResult;
  8960. bypassVirtual |= methodMatcher.mBypassVirtual;
  8961. if (methodMatcher.mBestMethodDef != NULL)
  8962. {
  8963. curTypeInst = methodMatcher.mBestMethodTypeInstance;
  8964. methodDef = methodMatcher.mBestMethodDef;
  8965. }
  8966. if ((methodDef) && (!methodDef->mIsStatic) && (!target) && (allowImplicitThis))
  8967. {
  8968. target = mModule->GetThis();
  8969. }
  8970. if (!methodUsingLists.IsEmpty())
  8971. {
  8972. auto foundList = methodUsingLists[0];
  8973. if (methodUsingLists.mSize > 1)
  8974. {
  8975. BfError* error = mModule->Fail("Ambiguous 'using' method reference", targetSrc);
  8976. if (error != NULL)
  8977. {
  8978. for (auto checkList : methodUsingLists)
  8979. {
  8980. String errorStr = "'";
  8981. for (int entryIdx = 0; entryIdx < checkList->mSize; entryIdx++)
  8982. {
  8983. if (entryIdx == 0)
  8984. errorStr += (*checkList)[entryIdx].GetFullName(mModule);
  8985. else
  8986. {
  8987. errorStr += ".";
  8988. errorStr += (*checkList)[entryIdx].GetName(mModule);
  8989. }
  8990. }
  8991. errorStr += "' is a candidate";
  8992. mModule->mCompiler->mPassInstance->MoreInfo(errorStr, (*checkList)[0].GetRefNode(mModule));
  8993. }
  8994. }
  8995. }
  8996. BfTypedValue curResult = target;
  8997. for (int entryIdx = 0; entryIdx < foundList->mSize; entryIdx++)
  8998. {
  8999. if ((entryIdx == 0) && (foundList->back().IsStatic()))
  9000. entryIdx = (int)foundList->mSize - 1;
  9001. auto& entry = (*foundList)[entryIdx];
  9002. if (mPropDef != NULL)
  9003. {
  9004. SetAndRestoreValue<BfTypedValue> prevResult(mResult, BfTypedValue());
  9005. mPropGetMethodFlags = (BfGetMethodInstanceFlags)(mPropGetMethodFlags | BfGetMethodInstanceFlag_Friend);
  9006. curResult = GetResult();
  9007. if (!curResult)
  9008. break;
  9009. }
  9010. auto useFlags = BfLookupFieldFlag_None;
  9011. if (entryIdx < foundList->mSize - 1)
  9012. useFlags = (BfLookupFieldFlags)(useFlags | BfLookupFieldFlag_IsAnonymous);
  9013. if (entry.mKind == BfUsingFieldData::MemberRef::Kind_Field)
  9014. {
  9015. curResult = LoadField(targetSrc, curResult, entry.mTypeInstance, entry.mTypeInstance->mTypeDef->mFields[entry.mIdx], useFlags);
  9016. }
  9017. else if (entry.mKind == BfUsingFieldData::MemberRef::Kind_Property)
  9018. {
  9019. curResult = LoadProperty(targetSrc, curResult, entry.mTypeInstance, entry.mTypeInstance->mTypeDef->mProperties[entry.mIdx], useFlags, BfCheckedKind_NotSet, false);
  9020. }
  9021. else if (entry.mKind == BfUsingFieldData::MemberRef::Kind_Local)
  9022. {
  9023. auto localDef = mModule->mCurMethodState->mLocals[entry.mIdx];
  9024. curResult = LoadLocal(localDef);
  9025. }
  9026. else if (entry.mKind == BfUsingFieldData::MemberRef::Kind_Local)
  9027. {
  9028. auto checkMethodDef = entry.mTypeInstance->mTypeDef->mMethods[entry.mIdx];
  9029. BF_ASSERT(methodDef == checkMethodDef);
  9030. break;
  9031. }
  9032. if ((!curResult) && (mPropDef == NULL))
  9033. break;
  9034. if (entryIdx == foundList->mSize - 1)
  9035. {
  9036. auto autoComplete = GetAutoComplete();
  9037. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(targetSrc)))
  9038. autoComplete->SetDefinitionLocation(entry.GetRefNode(mModule));
  9039. if ((autoComplete != NULL) && (autoComplete->CheckFixit(targetSrc)))
  9040. autoComplete->FixitAddFullyQualify(targetSrc, methodName, *foundList);
  9041. }
  9042. }
  9043. if (methodDef->mIsStatic)
  9044. target = BfTypedValue(curTypeInst);
  9045. else if (curResult)
  9046. target = curResult;
  9047. else if ((!methodDef->mIsStatic) && (curTypeInst != NULL))
  9048. target = mModule->GetDefaultTypedValue(curTypeInst);
  9049. }
  9050. // If we call "GetType" on a value type, statically determine the type rather than boxing and then dispatching
  9051. if ((methodDef) && (target) && (curTypeInst == mModule->mContext->mBfObjectType) &&
  9052. (methodDef->mName == "GetType") && (target.mType->IsValueType()) && (argValues.mArguments->IsEmpty()))
  9053. {
  9054. BfType* targetType = target.mType;
  9055. if (origTarget)
  9056. targetType = origTarget.mType;
  9057. auto typeType = mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef);
  9058. mModule->AddDependency(targetType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
  9059. return BfTypedValue(mModule->CreateTypeDataRef(targetType), typeType);
  9060. }
  9061. bool skipThis = false;
  9062. BfTypedValue fieldVal;
  9063. bool hasFieldVal = false;
  9064. // Fail, check for delegate field invocation
  9065. if ((methodDef == NULL) && ((methodGenericArguments == NULL) || (methodGenericArguments->size() == 0)))
  9066. {
  9067. // Check for payload enum initialization first
  9068. BfTypedValue enumResult;
  9069. BfTypeInstance* enumType = NULL;
  9070. if ((!target) && (target.HasType()) && (targetType->IsPayloadEnum()))
  9071. {
  9072. enumType = targetType->ToTypeInstance();
  9073. }
  9074. else if ((!target) && (!target.HasType()) && (mModule->mCurTypeInstance->IsPayloadEnum()))
  9075. {
  9076. enumType = mModule->mCurTypeInstance;
  9077. }
  9078. if (enumType != NULL)
  9079. {
  9080. enumResult = CheckEnumCreation(targetSrc, enumType, methodName, argValues);
  9081. }
  9082. if (enumResult)
  9083. {
  9084. if (mModule->mCompiler->mResolvePassData != NULL)
  9085. {
  9086. if (auto sourceClassifier = mModule->mCompiler->mResolvePassData->GetSourceClassifier(targetSrc))
  9087. {
  9088. sourceClassifier->SetElementType(targetSrc, BfSourceElementType_Normal);
  9089. }
  9090. }
  9091. return enumResult;
  9092. }
  9093. if (allowImplicitThis)
  9094. {
  9095. auto identifierNode = BfNodeDynCast<BfIdentifierNode>(targetSrc);
  9096. if (identifierNode != NULL)
  9097. fieldVal = LookupIdentifier(identifierNode);
  9098. }
  9099. else
  9100. {
  9101. SetAndRestoreValue<BfEvalExprFlags> prevFlags(mBfEvalExprFlags, (BfEvalExprFlags)(mBfEvalExprFlags & ~BfEvalExprFlags_AllowEnumId));
  9102. fieldVal = LookupField(targetSrc, target, methodName);
  9103. }
  9104. if (fieldVal)
  9105. {
  9106. hasFieldVal = true;
  9107. wantsExtensionCheck = !fieldVal.mType->IsDelegate() && !fieldVal.mType->IsFunction();
  9108. }
  9109. else if (mPropDef != NULL)
  9110. {
  9111. hasFieldVal = true;
  9112. BfMethodDef* matchedMethod = GetPropertyMethodDef(mPropDef, BfMethodType_PropertyGetter, mPropCheckedKind, mPropTarget);
  9113. if (matchedMethod != NULL)
  9114. {
  9115. auto getMethodInstance = mModule->GetRawMethodInstance(mPropTarget.mType->ToTypeInstance(), matchedMethod);
  9116. if ((getMethodInstance != NULL) &&
  9117. ((getMethodInstance->mReturnType->IsDelegate()) || (getMethodInstance->mReturnType->IsFunction())))
  9118. wantsExtensionCheck = false;
  9119. }
  9120. }
  9121. }
  9122. if ((!methodDef) && (!target.mValue))
  9123. {
  9124. // Check to see if we're constructing a struct via a call like: "Struct structVal = Struct()"
  9125. int wantNumGenericArgs = 0;
  9126. if ((methodGenericArguments != NULL) && (methodGenericArguments->size() > 0))
  9127. wantNumGenericArgs = (int)methodGenericArguments->size();
  9128. BfTypeInstance* resolvedTypeInstance = NULL;
  9129. BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None;
  9130. if (wantCtor)
  9131. {
  9132. resolvedTypeInstance = targetTypeInst;
  9133. }
  9134. else if (targetType != NULL)
  9135. {
  9136. if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(methodBoundExpr))
  9137. {
  9138. auto resolvedType = mModule->ResolveTypeRef_Ref(invocationExpr->mTarget, methodGenericArguments, BfPopulateType_Data, resolveFlags);
  9139. if (resolvedType != NULL)
  9140. resolvedTypeInstance = resolvedType->ToTypeInstance();
  9141. }
  9142. }
  9143. else
  9144. {
  9145. BfIdentifierNode* identifierNode = BfNodeDynCast<BfIdentifierNode>(targetSrc);
  9146. if (identifierNode != NULL)
  9147. {
  9148. SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
  9149. BfType* refType;
  9150. if (methodGenericArguments != NULL)
  9151. {
  9152. refType = mModule->ResolveTypeRef_Ref(identifierNode, methodGenericArguments, BfPopulateType_Data, resolveFlags);
  9153. }
  9154. else
  9155. refType = mModule->ResolveTypeRef_Ref(identifierNode, NULL, BfPopulateType_Data, resolveFlags);
  9156. prevIgnoreErrors.Restore();
  9157. if ((refType != NULL) && (refType->IsPrimitiveType()))
  9158. {
  9159. for (auto& resolvedArg : argValues.mResolvedArgs)
  9160. resolvedArg.mExpectedType = refType;
  9161. FinishDeferredEvals(argValues);
  9162. if (argValues.mResolvedArgs.IsEmpty())
  9163. return mModule->GetDefaultTypedValue(refType);
  9164. if (argValues.mResolvedArgs.size() != 1)
  9165. {
  9166. mModule->Fail("Cast requires one parameter", targetSrc);
  9167. return BfTypedValue();
  9168. }
  9169. // This is just a primitive cast
  9170. auto& resolvedArg = argValues.mResolvedArgs[0];
  9171. BfTypedValue castedValue;
  9172. BfTypedValue castTarget = resolvedArg.mTypedValue;
  9173. if (resolvedArg.mTypedValue)
  9174. {
  9175. castTarget = mModule->LoadValue(castTarget);
  9176. castedValue = mModule->Cast(targetSrc, castTarget, refType, BfCastFlags_Explicit);
  9177. }
  9178. if (!castedValue)
  9179. castedValue = mModule->GetDefaultTypedValue(refType);
  9180. return castedValue;
  9181. }
  9182. if (refType != NULL)
  9183. {
  9184. resolvedTypeInstance = refType->ToTypeInstance();
  9185. if (refType->IsGenericParam())
  9186. {
  9187. CheckGenericCtor((BfGenericParamType*)refType, argValues, targetSrc);
  9188. return mModule->GetDefaultTypedValue(refType);
  9189. }
  9190. }
  9191. }
  9192. }
  9193. if (resolvedTypeInstance != NULL)
  9194. {
  9195. auto origTypeInstance = resolvedTypeInstance;
  9196. if ((mBfEvalExprFlags & BfEvalExprFlags_AppendFieldInitializer) == 0)
  9197. {
  9198. if ((!resolvedTypeInstance->IsStruct()) && (!resolvedTypeInstance->IsTypedPrimitive()))
  9199. {
  9200. if (mModule->PreFail())
  9201. mModule->Fail("Objects must be allocated through 'new' or 'scope'", targetSrc);
  9202. return BfTypedValue();
  9203. }
  9204. }
  9205. if (auto identifier = BfNodeDynCastExact<BfIdentifierNode>(targetSrc))
  9206. {
  9207. auto elementType = resolvedTypeInstance->IsEnum() ? BfSourceElementType_Type : BfSourceElementType_Struct;
  9208. if (resolvedTypeInstance->IsObject())
  9209. elementType = BfSourceElementType_RefType;
  9210. mModule->SetElementType(identifier, elementType);
  9211. }
  9212. if (mModule->mCompiler->mResolvePassData != NULL)
  9213. {
  9214. if ((!BfNodeIsA<BfMemberReferenceExpression>(targetSrc)) && ((resolveFlags & BfResolveTypeRefFlag_FromIndirectSource) == 0))
  9215. mModule->mCompiler->mResolvePassData->HandleTypeReference(targetSrc, resolvedTypeInstance->mTypeDef);
  9216. }
  9217. BfTypedValue structInst;
  9218. mModule->PopulateType(resolvedTypeInstance);
  9219. if (!resolvedTypeInstance->IsValuelessType())
  9220. {
  9221. if ((mReceivingValue != NULL) && (mReceivingValue->mType == resolvedTypeInstance) && (mReceivingValue->IsAddr()))
  9222. {
  9223. structInst = *mReceivingValue;
  9224. mReceivingValue = NULL;
  9225. }
  9226. else
  9227. {
  9228. auto allocaInst = mModule->CreateAlloca(resolvedTypeInstance);
  9229. structInst = BfTypedValue(allocaInst, resolvedTypeInstance, true);
  9230. }
  9231. mResultIsTempComposite = true;
  9232. }
  9233. else
  9234. {
  9235. structInst = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), resolvedTypeInstance, true);
  9236. }
  9237. bool doBind = false;
  9238. mResultLocalVar = NULL;
  9239. mResultFieldInstance = NULL;
  9240. mResultLocalVarRefNode = NULL;
  9241. BfTypedValue result = MatchConstructor(targetSrc, methodBoundExpr, structInst, resolvedTypeInstance, argValues, false, BfMethodGenericArguments(),
  9242. resolvedTypeInstance->IsObject() ? BfAllowAppendKind_Infer : BfAllowAppendKind_No);
  9243. if ((result) && (!result.mType->IsVoid()))
  9244. return result;
  9245. mModule->ValidateAllocation(resolvedTypeInstance, targetSrc);
  9246. mModule->AddDependency(resolvedTypeInstance, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage);
  9247. if (mUsedAsStatement)
  9248. {
  9249. mModule->Warn(0, "Struct constructor being used as a statement", targetSrc);
  9250. }
  9251. return structInst;
  9252. }
  9253. }
  9254. // For for extensions in current type
  9255. if (wantsExtensionCheck)
  9256. {
  9257. auto checkTypeInst = mModule->mCurTypeInstance;
  9258. methodMatcher.mMethodType = BfMethodType_Extension;
  9259. if (methodMatcher.CheckType(checkTypeInst, BfTypedValue(), false, true))
  9260. {
  9261. isFailurePass = false;
  9262. curTypeInst = methodMatcher.mBestMethodTypeInstance;
  9263. methodDef = methodMatcher.mBestMethodDef;
  9264. }
  9265. }
  9266. // Look in globals. Always check for extension methods.
  9267. if ((((methodDef == NULL) && (!target.HasType())) ||
  9268. (wantsExtensionCheck)))
  9269. {
  9270. if (mModule->mContext->mCurTypeState != NULL)
  9271. {
  9272. BfGlobalLookup globalLookup;
  9273. globalLookup.mKind = BfGlobalLookup::Kind_Method;
  9274. globalLookup.mName = methodName;
  9275. mModule->PopulateGlobalContainersList(globalLookup);
  9276. for (auto& globalContainer : mModule->mContext->mCurTypeState->mGlobalContainers)
  9277. {
  9278. if (globalContainer.mTypeInst == NULL)
  9279. continue;
  9280. methodMatcher.mMethodType = wantsExtensionCheck ? BfMethodType_Extension : BfMethodType_Normal;
  9281. if (methodMatcher.CheckType(globalContainer.mTypeInst, BfTypedValue(), false))
  9282. {
  9283. isFailurePass = false;
  9284. curTypeInst = methodMatcher.mBestMethodTypeInstance;
  9285. methodDef = methodMatcher.mBestMethodDef;
  9286. }
  9287. }
  9288. }
  9289. }
  9290. // Look in static search. Always check for extension methods.
  9291. if ((methodDef == NULL) || (wantsExtensionCheck))
  9292. {
  9293. BfStaticSearch* staticSearch = mModule->GetStaticSearch();
  9294. if (staticSearch != NULL)
  9295. {
  9296. for (auto typeInst : staticSearch->mStaticTypes)
  9297. {
  9298. methodMatcher.mMethodType = wantsExtensionCheck ? BfMethodType_Extension : BfMethodType_Normal;
  9299. if (methodMatcher.CheckType(typeInst, BfTypedValue(), false))
  9300. {
  9301. isFailurePass = false;
  9302. curTypeInst = methodMatcher.mBestMethodTypeInstance;
  9303. methodDef = methodMatcher.mBestMethodDef;
  9304. }
  9305. }
  9306. }
  9307. }
  9308. if ((methodDef == NULL) && (hasFieldVal))
  9309. {
  9310. if (mPropDef != NULL)
  9311. fieldVal = GetResult();
  9312. if (fieldVal)
  9313. {
  9314. if (fieldVal.mType->IsGenericParam())
  9315. {
  9316. bool delegateFailed = true;
  9317. auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)fieldVal.mType);
  9318. BfTypeInstance* typeInstConstraint = NULL;
  9319. if (genericParamInstance->mTypeConstraint != NULL)
  9320. typeInstConstraint = genericParamInstance->mTypeConstraint->ToTypeInstance();
  9321. if ((typeInstConstraint != NULL) &&
  9322. ((typeInstConstraint->IsInstanceOf(mModule->mCompiler->mDelegateTypeDef)) || (typeInstConstraint->IsInstanceOf(mModule->mCompiler->mFunctionTypeDef))))
  9323. {
  9324. MarkResultUsed();
  9325. if (argValues.mArguments->size() == 1)
  9326. {
  9327. BfExprEvaluator exprEvaluator(mModule);
  9328. exprEvaluator.mBfEvalExprFlags = BfEvalExprFlags_AllowParamsExpr;
  9329. auto argExpr = (*argValues.mArguments)[0];
  9330. if (argExpr != NULL)
  9331. exprEvaluator.Evaluate(argExpr);
  9332. if ((mModule->mCurMethodState != NULL) && (exprEvaluator.mResultLocalVar != NULL) && (exprEvaluator.mResultLocalVarRefNode != NULL))
  9333. {
  9334. auto localVar = exprEvaluator.mResultLocalVar;
  9335. auto checkType = localVar->mResolvedType;
  9336. if (checkType->IsParamsType())
  9337. checkType = checkType->GetUnderlyingType();
  9338. if ((localVar->mCompositeCount >= 0) && (checkType == fieldVal.mType))
  9339. {
  9340. delegateFailed = false;
  9341. if (mModule->mCurMethodInstance->mIsUnspecialized)
  9342. {
  9343. auto retTypeType = mModule->CreateModifiedTypeType(fieldVal.mType, BfToken_RetType);
  9344. return mModule->GetFakeTypedValue(retTypeType);
  9345. }
  9346. }
  9347. }
  9348. }
  9349. if (delegateFailed)
  9350. {
  9351. mModule->Fail(StrFormat("Generic delegates can only be invoked with 'params %s' composite parameters", mModule->TypeToString(fieldVal.mType).c_str()), targetSrc);
  9352. return BfTypedValue();
  9353. }
  9354. }
  9355. }
  9356. if (fieldVal.mType->IsTypeInstance())
  9357. {
  9358. prevBindResult.Restore();
  9359. auto fieldTypeInst = fieldVal.mType->ToTypeInstance();
  9360. MarkResultUsed();
  9361. if (mFunctionBindResult != NULL)
  9362. {
  9363. mFunctionBindResult->mOrigTarget = BfTypedValue();
  9364. }
  9365. return MatchMethod(targetSrc, NULL, fieldVal, false, false, "Invoke", argValues, methodGenericArgs, checkedKind);
  9366. }
  9367. if (IsVar(fieldVal.mType))
  9368. {
  9369. FinishDeferredEvals(argValues);
  9370. return BfTypedValue(mModule->GetDefaultValue(fieldVal.mType), fieldVal.mType);
  9371. }
  9372. if (fieldVal.mType->IsGenericParam())
  9373. {
  9374. auto genericParam = mModule->GetGenericParamInstance((BfGenericParamType*)fieldVal.mType);
  9375. BfType* typeConstraint = genericParam->mTypeConstraint;
  9376. if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsUnspecialized) && (mModule->mCurMethodInstance->mMethodInfoEx != NULL))
  9377. {
  9378. for (int genericParamIdx = (int)mModule->mCurMethodInstance->mMethodInfoEx->mMethodGenericArguments.size();
  9379. genericParamIdx < mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams.size(); genericParamIdx++)
  9380. {
  9381. auto genericParam = mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
  9382. if ((genericParam->mExternType == fieldVal.mType) && (genericParam->mTypeConstraint != NULL))
  9383. typeConstraint = genericParam->mTypeConstraint;
  9384. }
  9385. }
  9386. if ((typeConstraint != NULL) &&
  9387. ((typeConstraint->IsDelegate()) || (typeConstraint->IsFunction())))
  9388. {
  9389. BfMethodInstance* invokeMethodInstance = mModule->GetRawMethodInstanceAtIdx(typeConstraint->ToTypeInstance(), 0, "Invoke");
  9390. if (invokeMethodInstance == NULL)
  9391. {
  9392. mModule->InternalError("Get Invoke failed", targetSrc);
  9393. return BfTypedValue();
  9394. }
  9395. methodDef = invokeMethodInstance->mMethodDef;
  9396. methodMatcher.mBestMethodInstance = invokeMethodInstance;
  9397. methodMatcher.mBestMethodTypeInstance = invokeMethodInstance->GetOwner();
  9398. methodMatcher.mBestMethodDef = invokeMethodInstance->mMethodDef;
  9399. target = mModule->GetDefaultTypedValue(methodMatcher.mBestMethodTypeInstance);
  9400. isFailurePass = false;
  9401. isIndirectMethodCall = true;
  9402. }
  9403. }
  9404. else if (fieldVal.mType->IsMethodRef())
  9405. {
  9406. auto functionBindResults = prevBindResult.mPrevVal;
  9407. if (functionBindResults != NULL)
  9408. {
  9409. functionBindResults->mOrigTarget = fieldVal;
  9410. }
  9411. origTarget = fieldVal;
  9412. auto methodRefType = (BfMethodRefType*)fieldVal.mType;
  9413. BfMethodInstance* methodInstance = methodRefType->mMethodRef;
  9414. methodDef = methodInstance->mMethodDef;
  9415. if (methodDef->mIsLocalMethod)
  9416. {
  9417. methodMatcher.mBestMethodInstance = mModule->ReferenceExternalMethodInstance(methodInstance);
  9418. }
  9419. else
  9420. {
  9421. BfTypeVector methodGenericArguments;
  9422. if (methodInstance->mMethodInfoEx != NULL)
  9423. methodGenericArguments = methodInstance->mMethodInfoEx->mMethodGenericArguments;
  9424. methodMatcher.mBestMethodInstance = mModule->GetMethodInstance(methodInstance->GetOwner(), methodInstance->mMethodDef, methodGenericArguments);
  9425. }
  9426. if (methodInstance->mMethodInfoEx != NULL)
  9427. {
  9428. methodMatcher.mBestMethodGenericArguments = methodInstance->mMethodInfoEx->mMethodGenericArguments;
  9429. }
  9430. methodMatcher.mBestMethodTypeInstance = methodInstance->GetOwner();
  9431. if (methodInstance->HasThis())
  9432. {
  9433. bool failed = false;
  9434. target = DoImplicitArgCapture(targetSrc, methodInstance, -1, failed, BfImplicitParamKind_General, origTarget);
  9435. }
  9436. else if (!methodDef->mIsStatic)
  9437. {
  9438. auto thisType = methodInstance->GetParamType(-1);
  9439. BF_ASSERT(thisType->IsValuelessType());
  9440. target = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), methodMatcher.mBestMethodTypeInstance);
  9441. }
  9442. else
  9443. target = BfTypedValue(methodMatcher.mBestMethodTypeInstance);
  9444. methodMatcher.mBypassVirtual = true;
  9445. bypassVirtual = true;
  9446. isFailurePass = false;
  9447. isIndirectMethodCall = true;
  9448. }
  9449. if (methodDef == NULL)
  9450. {
  9451. mModule->Fail(StrFormat("Cannot perform invocation on type '%s'", mModule->TypeToString(fieldVal.mType).c_str()), targetSrc);
  9452. return BfTypedValue();
  9453. }
  9454. }
  9455. }
  9456. if (methodDef == NULL)
  9457. {
  9458. }
  9459. // This will flush out any new ambiguity errors from extension methods
  9460. methodMatcher.FlushAmbiguityError();
  9461. if (methodDef == NULL)
  9462. {
  9463. FinishDeferredEvals(argValues);
  9464. auto compiler = mModule->mCompiler;
  9465. if ((autoComplete != NULL) && (autoComplete->CheckFixit(targetSrc)))
  9466. {
  9467. mModule->CheckTypeRefFixit(targetSrc);
  9468. bool wantStatic = !target.mValue;
  9469. if ((targetType == NULL) && (allowImplicitThis))
  9470. {
  9471. targetType = mModule->mCurTypeInstance;
  9472. if (mModule->mCurMethodInstance != NULL)
  9473. wantStatic = mModule->mCurMethodInstance->mMethodDef->mIsStatic;
  9474. }
  9475. if (targetType != NULL)
  9476. {
  9477. auto typeInst = targetType->ToTypeInstance();
  9478. if ((typeInst != NULL) && (!methodName.IsEmpty()))
  9479. {
  9480. BfTypeVector paramTypes;
  9481. for (int argIdx = 0; argIdx < (int)argValues.mResolvedArgs.size(); argIdx++)
  9482. {
  9483. auto& resolvedArg = argValues.mResolvedArgs[argIdx];
  9484. paramTypes.Add(resolvedArg.mTypedValue.mType);
  9485. }
  9486. autoComplete->FixitAddMethod(typeInst, methodName, mExpectingType, paramTypes, wantStatic);
  9487. }
  9488. }
  9489. }
  9490. if (methodName.IsEmpty())
  9491. {
  9492. // Would have caused a parsing error
  9493. }
  9494. else if ((target.mType != NULL) && (origTarget.mType != NULL))
  9495. {
  9496. if (mModule->PreFail())
  9497. {
  9498. if ((origTarget.mType->IsPointer()) && (origTarget.mType->GetUnderlyingType()->IsObjectOrInterface()))
  9499. {
  9500. mModule->Fail(StrFormat("Methods cannot be called on type '%s' because the type is a pointer to a reference type (ie: a double-reference).",
  9501. mModule->TypeToString(origTarget.mType).c_str()), targetSrc);
  9502. }
  9503. else
  9504. mModule->Fail(StrFormat("Method '%s' does not exist in type '%s'", methodName.c_str(), mModule->TypeToString(target.mType).c_str()), targetSrc);
  9505. }
  9506. }
  9507. else
  9508. {
  9509. if (mModule->PreFail())
  9510. mModule->Fail(StrFormat("Method '%s' does not exist", methodName.c_str()), targetSrc);
  9511. }
  9512. return BfTypedValue();
  9513. }
  9514. if ((prevBindResult.mPrevVal != NULL) && (methodMatcher.mMethodCheckCount > 1))
  9515. prevBindResult.mPrevVal->mCheckedMultipleMethods = true;
  9516. BfType* overrideReturnType = NULL;
  9517. BfModuleMethodInstance moduleMethodInstance = GetSelectedMethod(targetSrc, curTypeInst, methodDef, methodMatcher, &overrideReturnType);
  9518. if ((mModule->mAttributeState != NULL) && ((mModule->mAttributeState->mFlags & (BfAttributeState::Flag_StopOnError | BfAttributeState::Flag_HadError)) ==
  9519. (BfAttributeState::Flag_StopOnError | BfAttributeState::Flag_HadError)))
  9520. {
  9521. FinishDeferredEvals(argValues);
  9522. return BfTypedValue();
  9523. }
  9524. if ((moduleMethodInstance.mMethodInstance != NULL) && (!mModule->CheckUseMethodInstance(moduleMethodInstance.mMethodInstance, targetSrc)))
  9525. {
  9526. FinishDeferredEvals(argValues);
  9527. return BfTypedValue();
  9528. }
  9529. if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsUnspecialized))
  9530. {
  9531. if (methodMatcher.mHasVarArguments)
  9532. {
  9533. BfType* retType = mModule->GetPrimitiveType(BfTypeCode_Var);
  9534. if ((!methodMatcher.mHadVarConflictingReturnType) && (methodMatcher.mBestRawMethodInstance != NULL) && (!methodMatcher.mBestRawMethodInstance->mReturnType->IsUnspecializedTypeVariation()) &&
  9535. (prevBindResult.mPrevVal == NULL))
  9536. {
  9537. if ((!methodMatcher.mBestRawMethodInstance->mReturnType->IsGenericParam()) ||
  9538. (((BfGenericParamType*)methodMatcher.mBestRawMethodInstance->mReturnType)->mGenericParamKind != BfGenericParamKind_Method))
  9539. retType = methodMatcher.mBestRawMethodInstance->mReturnType;
  9540. }
  9541. return mModule->GetDefaultTypedValue(retType, true, BfDefaultValueKind_Addr);
  9542. }
  9543. }
  9544. if ((bypassVirtual) && (!target.mValue) && (target.mType->IsInterface()))
  9545. {
  9546. target = mModule->GetThis();
  9547. }
  9548. if (!moduleMethodInstance)
  9549. {
  9550. FinishDeferredEvals(argValues);
  9551. if (mModule->IsInUnspecializedGeneric())
  9552. return mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Var));
  9553. return BfTypedValue();
  9554. }
  9555. bool isSkipCall = moduleMethodInstance.mMethodInstance->IsSkipCall(bypassVirtual);
  9556. if ((moduleMethodInstance.mMethodInstance->IsOrInUnspecializedVariation()) && (!mModule->mBfIRBuilder->mIgnoreWrites))
  9557. {
  9558. // Invalid methods such as types with a HasVar tuple generic arg will be marked as mIsUnspecializedVariation and shouldn't actually be called
  9559. FinishDeferredEvals(argValues);
  9560. return mModule->GetDefaultTypedValue(moduleMethodInstance.mMethodInstance->mReturnType, true, BfDefaultValueKind_Addr);
  9561. }
  9562. if (methodDef->IsEmptyPartial())
  9563. {
  9564. // Ignore call
  9565. return mModule->GetDefaultTypedValue(moduleMethodInstance.mMethodInstance->mReturnType, true, BfDefaultValueKind_Addr);
  9566. }
  9567. if ((moduleMethodInstance.mMethodInstance->mMethodDef->mIsStatic) && (moduleMethodInstance.mMethodInstance->GetOwner()->IsInterface()))
  9568. {
  9569. bool isConstrained = false;
  9570. if (target.mType != NULL)
  9571. isConstrained = target.mType->IsGenericParam();
  9572. if ((target.mType == NULL) && ((mModule->mCurMethodInstance->mIsForeignMethodDef) || (mModule->mCurTypeInstance->IsInterface())))
  9573. isConstrained = true;
  9574. // If mIgnoreWrites is off then we skip devirtualization, so allow this
  9575. if ((target.mType != NULL) && (!target.mType->IsInterface()) && (mModule->mBfIRBuilder->mIgnoreWrites))
  9576. isConstrained = true;
  9577. if (!isConstrained)
  9578. {
  9579. if (mModule->mCurTypeInstance->IsInterface())
  9580. {
  9581. if (methodDef->mBody == NULL)
  9582. mModule->Fail(StrFormat("Interface method '%s' must provide a body to be explicitly invoked", mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str()), targetSrc);
  9583. }
  9584. else
  9585. 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);
  9586. FinishDeferredEvals(argValues);
  9587. return mModule->GetDefaultTypedValue(moduleMethodInstance.mMethodInstance->mReturnType, true, BfDefaultValueKind_Addr);
  9588. }
  9589. }
  9590. // 'base' could really mean 'this' if we're in an extension
  9591. if ((target.IsBase()) && (targetTypeInst == mModule->mCurTypeInstance))
  9592. target.ToThis();
  9593. else
  9594. MakeBaseConcrete(target);
  9595. BfType* callTargetType = curTypeInst;
  9596. if (methodDef->mMethodType == BfMethodType_Extension)
  9597. {
  9598. callTargetType = moduleMethodInstance.mMethodInstance->GetParamType(0);
  9599. if ((callTargetType->IsRef()) && (target.IsAddr()) && (!target.IsReadOnly()) && (target.mType->IsValueType()))
  9600. {
  9601. auto refType = (BfRefType*)callTargetType;
  9602. target = BfTypedValue(target.mValue, mModule->CreateRefType(target.mType, refType->mRefKind));
  9603. }
  9604. }
  9605. BfTypedValue callTarget;
  9606. if (isSkipCall)
  9607. {
  9608. // Just a fake value so we can continue on without generating any code (boxing, conversion, etc)
  9609. if (target)
  9610. {
  9611. if (((target.mType->IsComposite()) || (target.mType->IsTypedPrimitive())))
  9612. {
  9613. if ((moduleMethodInstance.mMethodInstance->mMethodDef->mIsMutating) &&
  9614. ((target.IsReadOnly()) || (!target.IsAddr())))
  9615. {
  9616. String err = StrFormat("call mutating method '%s' on", mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str());
  9617. CheckModifyResult(target, targetSrc, err.c_str());
  9618. }
  9619. }
  9620. callTarget = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), targetTypeInst);
  9621. }
  9622. }
  9623. else if (targetTypeInst == callTargetType)
  9624. {
  9625. if ((target) && (methodDef->HasNoThisSplat()))
  9626. {
  9627. callTarget = mModule->MakeAddressable(target);
  9628. }
  9629. else
  9630. callTarget = target;
  9631. if ((callTarget) && (moduleMethodInstance.mMethodInstance->GetOwner()->IsInterface()))
  9632. {
  9633. auto wantThis = moduleMethodInstance.mMethodInstance->GetParamType(-1);
  9634. if ((callTarget.mType != wantThis) && (wantThis->IsInterface()))
  9635. callTarget = mModule->Cast(targetSrc, callTarget, wantThis, BfCastFlags_Explicit);
  9636. }
  9637. }
  9638. else if (target)
  9639. {
  9640. if (methodMatcher.mFakeConcreteTarget)
  9641. {
  9642. BF_ASSERT(callTargetType->IsInterface());
  9643. callTarget = mModule->GetDefaultTypedValue(mModule->CreateConcreteInterfaceType(callTargetType->ToTypeInstance()));
  9644. }
  9645. else if (((target.mType->IsGenericParam()) || (target.mType->IsConcreteInterfaceType())) && (callTargetType->IsInterface()))
  9646. {
  9647. // Leave as generic
  9648. callTarget = target;
  9649. }
  9650. else
  9651. {
  9652. bool handled = false;
  9653. if ((target.mType->IsTypedPrimitive()) && (callTargetType->IsTypedPrimitive()))
  9654. {
  9655. handled = true;
  9656. callTarget = target;
  9657. }
  9658. else if ((target.mType->IsStructOrStructPtr()) || (target.mType->IsTypedPrimitive()))
  9659. {
  9660. //BF_ASSERT(target.IsAddr());
  9661. if (callTargetType->IsObjectOrInterface())
  9662. {
  9663. // Box it
  9664. callTarget = mModule->Cast(targetSrc, target, callTargetType, BfCastFlags_Explicit);
  9665. handled = true;
  9666. }
  9667. else
  9668. {
  9669. //BF_ASSERT(target.IsAddr() || target.IsSplat() || target.mType->IsPointer());
  9670. }
  9671. }
  9672. else
  9673. target = mModule->LoadValue(target);
  9674. if (!handled)
  9675. {
  9676. // Could we have just unconditionally done this?
  9677. callTarget = mModule->Cast(targetSrc, target, callTargetType, BfCastFlags_Explicit);
  9678. }
  9679. }
  9680. }
  9681. if (isFailurePass)
  9682. {
  9683. BfError* error;
  9684. if (methodMatcher.mMatchFailKind == BfMethodMatcher::MatchFailKind_CheckedMismatch)
  9685. 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);
  9686. else
  9687. error = mModule->Fail(StrFormat("'%s' is inaccessible due to its protection level", mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str()), targetSrc);
  9688. if (error != NULL)
  9689. {
  9690. if ((error != NULL) && (moduleMethodInstance.mMethodInstance->mMethodDef->mMethodDeclaration != NULL))
  9691. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), moduleMethodInstance.mMethodInstance->mMethodDef->GetRefNode());
  9692. }
  9693. }
  9694. if ((mModule->mCompiler->mResolvePassData != NULL) && (methodDef != NULL))
  9695. {
  9696. auto identifierNode = BfNodeDynCast<BfIdentifierNode>(targetSrc);
  9697. while (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(identifierNode))
  9698. identifierNode = qualifiedNameNode->mRight;
  9699. if ((identifierNode != NULL) && (methodDef->mIdx >= 0) && (!isIndirectMethodCall) &&
  9700. ((targetTypeInst == NULL) || (!targetTypeInst->IsDelegateOrFunction())))
  9701. {
  9702. auto refMethodInstance = moduleMethodInstance.mMethodInstance;
  9703. if (refMethodInstance->mVirtualTableIdx != -1)
  9704. {
  9705. auto& virtualEntry = refMethodInstance->GetOwner()->mVirtualMethodTable[refMethodInstance->mVirtualTableIdx];
  9706. refMethodInstance = virtualEntry.mDeclaringMethod;
  9707. }
  9708. mModule->mCompiler->mResolvePassData->HandleMethodReference(identifierNode, refMethodInstance->GetOwner()->mTypeDef, refMethodInstance->mMethodDef);
  9709. auto autoComplete = GetAutoComplete();
  9710. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(identifierNode)))
  9711. {
  9712. autoComplete->SetDefinitionLocation(methodDef->GetRefNode(), true);
  9713. int virtualIdx = moduleMethodInstance.mMethodInstance->mVirtualTableIdx;
  9714. if ((autoComplete->mResolveType == BfResolveType_GoToDefinition) &&
  9715. (virtualIdx != -1) && (targetTypeInst != NULL) && (!targetTypeInst->IsStruct()) && (!targetTypeInst->IsTypedPrimitive()) && (!targetTypeInst->IsInterface()) &&
  9716. // 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
  9717. (targetTypeInst->mVirtualMethodTable.size() != 0))
  9718. {
  9719. auto methodEntry = targetTypeInst->mVirtualMethodTable[virtualIdx];
  9720. if (methodEntry.mImplementingMethod.mMethodNum != -1)
  9721. {
  9722. BfMethodInstance* callingMethodInstance = methodEntry.mImplementingMethod;
  9723. if (callingMethodInstance != NULL)
  9724. {
  9725. auto callingMethodDef = callingMethodInstance->mMethodDef;
  9726. auto callingMethodDeclaration = callingMethodDef->GetMethodDeclaration();
  9727. if ((callingMethodDeclaration != NULL) && (callingMethodDeclaration->mNameNode != NULL))
  9728. autoComplete->SetDefinitionLocation(callingMethodDeclaration->mNameNode, true);
  9729. }
  9730. }
  9731. }
  9732. if (autoComplete->mDefType == NULL)
  9733. {
  9734. autoComplete->mDefMethod = refMethodInstance->mMethodDef;
  9735. autoComplete->mDefType = refMethodInstance->GetOwner()->mTypeDef;
  9736. }
  9737. if (autoComplete->mResolveType == BfResolveType_GetResultString)
  9738. {
  9739. autoComplete->mResultString = ":";
  9740. autoComplete->mResultString += mModule->MethodToString(moduleMethodInstance.mMethodInstance);
  9741. auto methodDecl = moduleMethodInstance.mMethodInstance->mMethodDef->GetMethodDeclaration();
  9742. if ((methodDecl != NULL) && (methodDecl->mDocumentation != NULL))
  9743. {
  9744. autoComplete->mResultString += "\x03";
  9745. methodDecl->mDocumentation->GetDocString(autoComplete->mResultString);
  9746. }
  9747. }
  9748. }
  9749. }
  9750. }
  9751. // This was causing forward-backward-forward steps when we just used 'targetSrc'. Using closeParen is undesirable because most of the time
  9752. // we DO just want it to just go to the targetSrc... do we even need this?
  9753. /*if (auto invokeExpr = BfNodeDynCast<BfInvocationExpression>(targetSrc->mParent))
  9754. {
  9755. // We set the srcPos to the close paren right before the call so we keep a forward progression of src positions in the case
  9756. // where some of the params are method calls and such
  9757. if (invokeExpr->mCloseParen != NULL)
  9758. mModule->UpdateExprSrcPos(invokeExpr->mCloseParen);
  9759. else
  9760. mModule->UpdateExprSrcPos(targetSrc);
  9761. }
  9762. else
  9763. mModule->UpdateExprSrcPos(targetSrc);*/
  9764. if (!mModule->mBfIRBuilder->mIgnoreWrites)
  9765. {
  9766. //BF_ASSERT(!callTarget.mValue.IsFake());
  9767. }
  9768. prevBindResult.Restore();
  9769. // Check mut
  9770. if ((callTarget.mType != NULL) &&
  9771. (callTarget.mType->IsGenericParam()) &&
  9772. ((!callTarget.IsAddr()) || (callTarget.IsReadOnly())) &&
  9773. (callTarget.mKind != BfTypedValueKind_MutableValue) &&
  9774. (moduleMethodInstance.mMethodInstance->mMethodDef->mIsMutating))
  9775. {
  9776. auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)callTarget.mType);
  9777. bool needsMut = true;
  9778. if ((genericParamInstance->mGenericParamFlags & (BfGenericParamFlag_StructPtr | BfGenericParamFlag_Class | BfGenericParamFlag_Var)) != 0)
  9779. needsMut = false;
  9780. if (genericParamInstance->mTypeConstraint != NULL)
  9781. {
  9782. auto typeConstaintTypeInstance = genericParamInstance->mTypeConstraint->ToTypeInstance();
  9783. if ((typeConstaintTypeInstance != NULL) && (!typeConstaintTypeInstance->IsComposite()))
  9784. needsMut = false;
  9785. }
  9786. if ((mFunctionBindResult != NULL) && (mFunctionBindResult->mSkipMutCheck))
  9787. needsMut = false;
  9788. if (needsMut)
  9789. {
  9790. String err = StrFormat("call mutating method '%s' on", mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str());
  9791. CheckModifyResult(callTarget, targetSrc, err.c_str(), true);
  9792. }
  9793. }
  9794. // Check mut on interface
  9795. if ((callTarget.mType != NULL) &&
  9796. (callTarget.mType->IsInterface()) &&
  9797. (target.IsThis()) &&
  9798. (mModule->mCurTypeInstance) &&
  9799. (!mModule->mCurMethodInstance->mMethodDef->mIsMutating) &&
  9800. (methodDef->mIsMutating))
  9801. {
  9802. mModule->Fail(StrFormat("Cannot call mutating method '%s' within default interface method '%s'. Consider adding 'mut' specifier to this method.",
  9803. mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str(), mModule->MethodToString(mModule->mCurMethodInstance).c_str()), targetSrc);
  9804. }
  9805. BfTypedValue result;
  9806. BfTypedValue argCascade;
  9807. BfCreateCallFlags subCallFlags = BfCreateCallFlags_None;
  9808. if (bypassVirtual)
  9809. subCallFlags = (BfCreateCallFlags)(subCallFlags | BfCreateCallFlags_BypassVirtual);
  9810. if (skipThis)
  9811. subCallFlags = (BfCreateCallFlags)(subCallFlags | BfCreateCallFlags_SkipThis);
  9812. result = CreateCall(targetSrc, callTarget, origTarget, methodDef, moduleMethodInstance, subCallFlags, argValues.mResolvedArgs, &argCascade);
  9813. if (overrideReturnType != NULL)
  9814. {
  9815. BF_ASSERT(moduleMethodInstance.mMethodInstance->mIsUnspecializedVariation);
  9816. result = mModule->GetDefaultTypedValue(overrideReturnType, false, BfDefaultValueKind_Addr);
  9817. }
  9818. if (result)
  9819. {
  9820. if (result.mType->IsRef())
  9821. result = mModule->RemoveRef(result);
  9822. }
  9823. PerformCallChecks(moduleMethodInstance.mMethodInstance, targetSrc);
  9824. if (result)
  9825. {
  9826. bool discardedReturnValue = mUsedAsStatement;
  9827. if (discardedReturnValue)
  9828. {
  9829. auto _ShowDiscardWaring = [&](const String& text, BfCustomAttributes* customAttributes, BfIRConstHolder* constHolder, BfAstNode* refNode)
  9830. {
  9831. if (customAttributes != NULL)
  9832. {
  9833. auto customAttribute = customAttributes->Get(mModule->mCompiler->mNoDiscardAttributeTypeDef);
  9834. if (!customAttribute->mCtorArgs.IsEmpty())
  9835. {
  9836. String* str = mModule->GetStringPoolString(customAttribute->mCtorArgs[0], constHolder);
  9837. if ((str != NULL) && (!str->IsEmpty()))
  9838. {
  9839. mModule->Warn(0, text + ": " + *str, targetSrc);
  9840. return;
  9841. }
  9842. }
  9843. }
  9844. mModule->Warn(0, text, targetSrc);
  9845. };
  9846. bool showedWarning = false;
  9847. if (moduleMethodInstance.mMethodInstance->mMethodDef->mIsNoDiscard)
  9848. {
  9849. _ShowDiscardWaring("Discarding return value of method with [NoDiscard] attribute", moduleMethodInstance.mMethodInstance->GetCustomAttributes(),
  9850. moduleMethodInstance.mMethodInstance->GetOwner()->mConstHolder, targetSrc);
  9851. showedWarning = true;
  9852. }
  9853. auto typeInst = result.mType->ToTypeInstance();
  9854. if (typeInst != NULL)
  9855. {
  9856. if ((typeInst->mTypeDef->mIsNoDiscard) && (!showedWarning))
  9857. {
  9858. _ShowDiscardWaring("Discarding return value whose type has [NoDiscard] attribute", typeInst->mCustomAttributes, typeInst->mConstHolder, targetSrc);
  9859. }
  9860. BfModuleMethodInstance moduleMethodInstance = mModule->GetMethodByName(typeInst, "ReturnValueDiscarded", 0, true);
  9861. if (moduleMethodInstance)
  9862. {
  9863. bool wasCapturingMethodMatchInfo = false;
  9864. if (autoComplete != NULL)
  9865. {
  9866. wasCapturingMethodMatchInfo = autoComplete->mIsCapturingMethodMatchInfo;
  9867. autoComplete->mIsCapturingMethodMatchInfo = false;
  9868. }
  9869. defer
  9870. (
  9871. if (autoComplete != NULL)
  9872. autoComplete->mIsCapturingMethodMatchInfo = wasCapturingMethodMatchInfo;
  9873. );
  9874. auto wasGetDefinition = (autoComplete != NULL) && (autoComplete->mIsGetDefinition);
  9875. if (wasGetDefinition)
  9876. autoComplete->mIsGetDefinition = false;
  9877. result = mModule->MakeAddressable(result);
  9878. BfResolvedArgs resolvedArgs;
  9879. MatchMethod(targetSrc, NULL, result, false, false, "ReturnValueDiscarded", resolvedArgs, BfMethodGenericArguments());
  9880. if (wasGetDefinition)
  9881. autoComplete->mIsGetDefinition = true;
  9882. }
  9883. }
  9884. }
  9885. }
  9886. if (argCascade)
  9887. {
  9888. if (argCascade.mType->IsRef())
  9889. argCascade = mModule->RemoveRef(argCascade);
  9890. result = argCascade;
  9891. }
  9892. if (result)
  9893. {
  9894. if ((result.mType->IsUnspecializedTypeVariation()) && (moduleMethodInstance.mMethodInstance->GetOwner()->IsInterface()))
  9895. {
  9896. BfType* selfType = NULL;
  9897. if (methodMatcher.mSelfType != NULL)
  9898. {
  9899. BF_ASSERT(mModule->IsInGeneric());
  9900. selfType = methodMatcher.mSelfType;
  9901. }
  9902. else
  9903. {
  9904. // Will be an error
  9905. selfType = methodMatcher.mBestMethodTypeInstance;
  9906. }
  9907. if ((selfType != NULL) && (!selfType->IsInterface()))
  9908. {
  9909. auto resolvedType = mModule->ResolveSelfType(result.mType, selfType);
  9910. if ((resolvedType != NULL) && (resolvedType != result.mType))
  9911. result = mModule->GetDefaultTypedValue(resolvedType);
  9912. }
  9913. }
  9914. }
  9915. return result;
  9916. }
  9917. void BfExprEvaluator::LookupQualifiedName(BfQualifiedNameNode* nameNode, bool ignoreInitialError, bool* hadError)
  9918. {
  9919. BfIdentifierNode* nameLeft = nameNode->mLeft;
  9920. BfIdentifierNode* nameRight = nameNode->mRight;
  9921. StringT<64> fieldName;
  9922. if (nameNode->mRight != NULL)
  9923. nameNode->mRight->ToString(fieldName);
  9924. bool wasBaseLookup = false;
  9925. if (auto qualifiedLeftName = BfNodeDynCast<BfQualifiedNameNode>(nameNode->mLeft))
  9926. {
  9927. if (CheckIsBase(qualifiedLeftName->mRight))
  9928. {
  9929. wasBaseLookup = true;
  9930. auto type = mModule->ResolveTypeRef(qualifiedLeftName->mLeft, NULL);
  9931. if (type == NULL)
  9932. return;
  9933. auto fieldName = nameNode->mRight->ToString();
  9934. auto target = mModule->GetThis();
  9935. target.mType = type;
  9936. mResult = LookupField(nameNode->mRight, target, fieldName);
  9937. if ((mPropDef != NULL) && (mPropDef->IsVirtual()))
  9938. mPropDefBypassVirtual = true;
  9939. return;
  9940. }
  9941. }
  9942. if (!wasBaseLookup)
  9943. mResult = LookupIdentifier(nameNode->mLeft, ignoreInitialError, hadError);
  9944. GetResult();
  9945. if (!mResult)
  9946. {
  9947. if (!ignoreInitialError)
  9948. mModule->Fail("Identifier not found", nameNode->mLeft);
  9949. return;
  9950. }
  9951. if (mResult.mType->IsObject())
  9952. {
  9953. mResult = mModule->LoadValue(mResult, 0, mIsVolatileReference);
  9954. }
  9955. else if ((mResult.mType->IsPointer()) && mResult.mType->IsStructOrStructPtr())
  9956. {
  9957. BfPointerType* structPtrType = (BfPointerType*)mResult.mType;
  9958. mResult = mModule->LoadValue(mResult, 0, mIsVolatileReference);
  9959. mResult.mType = structPtrType->mElementType;
  9960. if (mResult.mKind == BfTypedValueKind_ThisValue)
  9961. mResult.mKind = BfTypedValueKind_ThisAddr;
  9962. else
  9963. mResult.mKind = BfTypedValueKind_Addr;
  9964. }
  9965. else if (mResult.mType->IsAllocType())
  9966. {
  9967. BF_ASSERT(mResult.mValue.IsFake());
  9968. mResult.mType = mResult.mType->GetUnderlyingType();
  9969. }
  9970. mIsVolatileReference = false;
  9971. mIsHeapReference = false;
  9972. if (!mResult)
  9973. return;
  9974. auto origResult = mResult;
  9975. auto lookupType = BindGenericType(nameNode, mResult.mType);
  9976. if (IsVar(mResult.mType))
  9977. {
  9978. mResult = BfTypedValue(mModule->GetDefaultValue(mResult.mType), mResult.mType, true);
  9979. return;
  9980. }
  9981. if ((!mResult.mType->IsTypeInstance()) && (!mResult.mType->IsGenericParam()))
  9982. {
  9983. if (hadError != NULL)
  9984. *hadError = true;
  9985. mModule->Fail(StrFormat("Type '%s' has no fields", mModule->TypeToString(mResult.mType).c_str()), nameNode->mLeft);
  9986. mResult = BfTypedValue();
  9987. return;
  9988. }
  9989. BfTypedValue lookupVal = mResult;
  9990. mResult = LookupField(nameNode->mRight, lookupVal, fieldName);
  9991. if ((!mResult) && (mPropDef == NULL) && (lookupType->IsGenericParam()))
  9992. {
  9993. auto genericParamInst = mModule->GetGenericParamInstance((BfGenericParamType*)lookupType, true);
  9994. SizedArray<BfTypeInstance*, 8> searchConstraints;
  9995. for (auto ifaceConstraint : genericParamInst->mInterfaceConstraints)
  9996. {
  9997. if (!searchConstraints.Contains(ifaceConstraint))
  9998. {
  9999. searchConstraints.push_back(ifaceConstraint);
  10000. for (auto& innerIFaceEntry : ifaceConstraint->mInterfaces)
  10001. {
  10002. auto innerIFace = innerIFaceEntry.mInterfaceType;
  10003. if (!searchConstraints.Contains(innerIFace))
  10004. {
  10005. searchConstraints.push_back(innerIFace);
  10006. }
  10007. }
  10008. }
  10009. }
  10010. BfTypedValue prevTarget;
  10011. BfPropertyDef* prevDef = NULL;
  10012. for (auto ifaceConstraint : searchConstraints)
  10013. {
  10014. BfTypedValue lookupVal = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), ifaceConstraint);
  10015. mResult = LookupField(nameNode->mRight, lookupVal, fieldName);
  10016. if (mPropDef != NULL)
  10017. {
  10018. if (prevDef != NULL)
  10019. {
  10020. bool isBetter = mModule->TypeIsSubTypeOf(mPropTarget.mType->ToTypeInstance(), prevTarget.mType->ToTypeInstance());
  10021. bool isWorse = mModule->TypeIsSubTypeOf(prevTarget.mType->ToTypeInstance(), mPropTarget.mType->ToTypeInstance());
  10022. if ((isWorse) && (!isBetter))
  10023. continue;
  10024. if (isBetter == isWorse)
  10025. {
  10026. auto error = mModule->Fail("Ambiguous property reference", nameNode->mRight);
  10027. if (error != NULL)
  10028. {
  10029. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' has a candidate", mModule->TypeToString(prevTarget.mType).c_str()), prevDef->GetRefNode());
  10030. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' has a candidate", mModule->TypeToString(mPropTarget.mType).c_str()), mPropDef->GetRefNode());
  10031. }
  10032. }
  10033. }
  10034. prevDef = mPropDef;
  10035. prevTarget = mPropTarget;
  10036. }
  10037. }
  10038. /*if ((mResult) || (mPropDef != NULL))
  10039. break;*/
  10040. }
  10041. if (mPropDef != NULL)
  10042. {
  10043. mOrigPropTarget = origResult;
  10044. if (((CheckIsBase(nameNode->mLeft)) || (wasBaseLookup)) && (mPropDef->IsVirtual()))
  10045. mPropDefBypassVirtual = true;
  10046. }
  10047. if ((mResult) || (mPropDef != NULL))
  10048. return;
  10049. if (hadError != NULL)
  10050. *hadError = true;
  10051. BfTypeInstance* typeInst = lookupType->ToTypeInstance();
  10052. auto compiler = mModule->mCompiler;
  10053. if ((typeInst != NULL) && (compiler->IsAutocomplete()) && (compiler->mResolvePassData->mAutoComplete->CheckFixit(nameNode->mRight)))
  10054. {
  10055. FixitAddMember(typeInst, mExpectingType, nameNode->mRight->ToString(), false);
  10056. }
  10057. mModule->Fail(StrFormat("Unable to find member '%s' in '%s'", fieldName.c_str(), mModule->TypeToString(lookupType).c_str()), nameNode->mRight);
  10058. }
  10059. void BfExprEvaluator::LookupQualifiedName(BfAstNode* nameNode, BfIdentifierNode* nameLeft, BfIdentifierNode* nameRight, bool ignoreInitialError, bool* hadError)
  10060. {
  10061. String fieldName;
  10062. if (nameRight != NULL)
  10063. fieldName = nameRight->ToString();
  10064. bool wasBaseLookup = false;
  10065. if (auto qualifiedLeftName = BfNodeDynCast<BfQualifiedNameNode>(nameLeft))
  10066. {
  10067. if (CheckIsBase(qualifiedLeftName->mRight))
  10068. {
  10069. wasBaseLookup = true;
  10070. auto type = mModule->ResolveTypeRef(qualifiedLeftName->mLeft, NULL);
  10071. if (type == NULL)
  10072. return;
  10073. auto fieldName = nameRight->ToString();
  10074. auto target = mModule->GetThis();
  10075. target.mType = type;
  10076. mResult = LookupField(nameRight, target, fieldName);
  10077. if ((mPropDef != NULL) && (mPropDef->IsVirtual()))
  10078. mPropDefBypassVirtual = true;
  10079. return;
  10080. }
  10081. }
  10082. if (!wasBaseLookup)
  10083. {
  10084. mResult = LookupIdentifier(nameLeft, ignoreInitialError, hadError);
  10085. if ((mResult) && (!mResult.mType->IsComposite()))
  10086. CheckResultForReading(mResult);
  10087. }
  10088. GetResult();
  10089. if (!mResult)
  10090. {
  10091. if (!ignoreInitialError)
  10092. mModule->Fail("Identifier not found", nameLeft);
  10093. return;
  10094. }
  10095. if (mResult.mType->IsObject())
  10096. {
  10097. mResult = mModule->LoadValue(mResult, 0, mIsVolatileReference);
  10098. }
  10099. else if ((mResult.mType->IsPointer()) && mResult.mType->IsStructOrStructPtr())
  10100. {
  10101. BfPointerType* structPtrType = (BfPointerType*)mResult.mType;
  10102. mResult = mModule->LoadValue(mResult, 0, mIsVolatileReference);
  10103. mResult.mType = structPtrType->mElementType;
  10104. if (mResult.mKind == BfTypedValueKind_ThisValue)
  10105. mResult.mKind = BfTypedValueKind_ThisAddr;
  10106. else
  10107. mResult.mKind = BfTypedValueKind_Addr;
  10108. }
  10109. mIsVolatileReference = false;
  10110. mIsHeapReference = false;
  10111. if (!mResult)
  10112. return;
  10113. if (mResult.mType->IsAllocType())
  10114. mResult.mType = mResult.mType->GetUnderlyingType();
  10115. auto origResult = mResult;
  10116. if (IsVar(mResult.mType))
  10117. {
  10118. auto varType = mModule->GetPrimitiveType(BfTypeCode_Var);
  10119. mResult = BfTypedValue(mModule->GetDefaultValue(varType), varType, true);
  10120. return;
  10121. }
  10122. if ((!mResult.mType->IsTypeInstance()) && (!mResult.mType->IsGenericParam()))
  10123. {
  10124. if (mResult.mType->IsSizedArray())
  10125. {
  10126. if (mResult.mType->IsValuelessType())
  10127. {
  10128. mResult.mType = mModule->GetWrappedStructType(mResult.mType);
  10129. mResult.mValue = mModule->mBfIRBuilder->GetFakeVal();
  10130. }
  10131. else
  10132. {
  10133. mResult = mModule->MakeAddressable(mResult);
  10134. mResult.mType = mModule->GetWrappedStructType(mResult.mType);
  10135. mResult.mValue = mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->MapTypeInstPtr(mResult.mType->ToTypeInstance()));
  10136. }
  10137. }
  10138. else if (mResult.mType->IsWrappableType())
  10139. {
  10140. mResult.mType = mModule->GetWrappedStructType(mResult.mType);
  10141. }
  10142. else
  10143. {
  10144. if (hadError != NULL)
  10145. *hadError = true;
  10146. mModule->Fail(StrFormat("Type '%s' has no fields", mModule->TypeToString(mResult.mType).c_str()), nameLeft);
  10147. mResult = BfTypedValue();
  10148. return;
  10149. }
  10150. }
  10151. BfTypedValue lookupVal = mResult;
  10152. auto lookupType = BindGenericType(nameNode, mResult.mType);
  10153. if ((lookupType->IsGenericParam()) && (!mResult.mType->IsGenericParam()))
  10154. {
  10155. bool prevUseMixinGenerics = false;
  10156. if (mModule->mCurMethodState->mMixinState != NULL)
  10157. {
  10158. prevUseMixinGenerics = mModule->mCurMethodState->mMixinState->mUseMixinGenerics;
  10159. mModule->mCurMethodState->mMixinState->mUseMixinGenerics = true;
  10160. }
  10161. // Try to lookup from generic binding
  10162. mResult = LookupField(nameRight, BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), lookupType), fieldName, BfLookupFieldFlag_BindOnly);
  10163. if (mModule->mCurMethodState->mMixinState != NULL)
  10164. mModule->mCurMethodState->mMixinState->mUseMixinGenerics = prevUseMixinGenerics;
  10165. if (mPropDef != NULL)
  10166. {
  10167. mOrigPropTarget = lookupVal;
  10168. return;
  10169. }
  10170. }
  10171. if (mPropDef == NULL)
  10172. mResult = LookupField(nameRight, lookupVal, fieldName, CheckIsBase(nameLeft) ? BfLookupFieldFlag_BaseLookup : BfLookupFieldFlag_None);
  10173. if ((!mResult) && (mPropDef == NULL) && (lookupType->IsGenericParam()))
  10174. {
  10175. auto genericParamInst = mModule->GetGenericParamInstance((BfGenericParamType*)lookupType, true);
  10176. SizedArray<BfTypeInstance*, 8> searchConstraints;
  10177. for (auto ifaceConstraint : genericParamInst->mInterfaceConstraints)
  10178. {
  10179. if (!searchConstraints.Contains(ifaceConstraint))
  10180. {
  10181. searchConstraints.push_back(ifaceConstraint);
  10182. for (auto& innerIFaceEntry : ifaceConstraint->mInterfaces)
  10183. {
  10184. auto innerIFace = innerIFaceEntry.mInterfaceType;
  10185. if (!searchConstraints.Contains(innerIFace))
  10186. {
  10187. searchConstraints.push_back(innerIFace);
  10188. }
  10189. }
  10190. }
  10191. }
  10192. BfTypedValue prevTarget;
  10193. BfPropertyDef* prevDef = NULL;
  10194. for (auto ifaceConstraint : searchConstraints)
  10195. {
  10196. BfTypedValue lookupVal = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), ifaceConstraint);
  10197. mResult = LookupField(nameRight, lookupVal, fieldName);
  10198. if (mPropDef != NULL)
  10199. {
  10200. if (prevDef != NULL)
  10201. {
  10202. bool isBetter = mModule->TypeIsSubTypeOf(mPropTarget.mType->ToTypeInstance(), prevTarget.mType->ToTypeInstance());
  10203. bool isWorse = mModule->TypeIsSubTypeOf(prevTarget.mType->ToTypeInstance(), mPropTarget.mType->ToTypeInstance());
  10204. if ((isWorse) && (!isBetter))
  10205. continue;
  10206. if (isBetter == isWorse)
  10207. {
  10208. auto error = mModule->Fail("Ambiguous property reference", nameRight);
  10209. if (error != NULL)
  10210. {
  10211. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' has a candidate", mModule->TypeToString(prevTarget.mType).c_str()), prevDef->GetRefNode());
  10212. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' has a candidate", mModule->TypeToString(mPropTarget.mType).c_str()), mPropDef->GetRefNode());
  10213. }
  10214. }
  10215. }
  10216. prevDef = mPropDef;
  10217. prevTarget = mPropTarget;
  10218. }
  10219. }
  10220. if ((mPropDef == NULL) && (genericParamInst->IsEnum()))
  10221. {
  10222. if ((fieldName == "Underlying") || (fieldName == "UnderlyingRef"))
  10223. {
  10224. mResult = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Var));
  10225. return;
  10226. }
  10227. }
  10228. }
  10229. if (mPropDef != NULL)
  10230. {
  10231. mOrigPropTarget = origResult;
  10232. if ((CheckIsBase(nameLeft)) || (wasBaseLookup))
  10233. {
  10234. if (mPropDef->IsVirtual())
  10235. mPropDefBypassVirtual = true;
  10236. }
  10237. }
  10238. if ((mResult) || (mPropDef != NULL))
  10239. return;
  10240. if (hadError != NULL)
  10241. *hadError = true;
  10242. BfTypeInstance* typeInst = lookupType->ToTypeInstance();
  10243. auto compiler = mModule->mCompiler;
  10244. if ((typeInst != NULL) && (compiler->IsAutocomplete()) && (compiler->mResolvePassData->mAutoComplete->CheckFixit(nameRight)))
  10245. {
  10246. FixitAddMember(typeInst, mExpectingType, nameRight->ToString(), false);
  10247. }
  10248. if (((mBfEvalExprFlags & BfEvalExprFlags_NameOf) != 0) && (typeInst != NULL) && (CheckForMethodName(nameRight, typeInst, fieldName)))
  10249. return;
  10250. mModule->Fail(StrFormat("Unable to find member '%s' in '%s'", fieldName.c_str(), mModule->TypeToString(lookupType).c_str()), nameRight);
  10251. }
  10252. void BfExprEvaluator::LookupQualifiedStaticField(BfQualifiedNameNode* nameNode, bool ignoreIdentifierNotFoundError)
  10253. {
  10254. // Lookup left side as a type
  10255. {
  10256. BfType* type = NULL;
  10257. {
  10258. type = mModule->ResolveTypeRef(nameNode->mLeft, NULL, BfPopulateType_Data, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_AllowRef | BfResolveTypeRefFlag_IgnoreLookupError));
  10259. mModule->CheckTypeRefFixit(nameNode->mLeft);
  10260. }
  10261. if (type != NULL)
  10262. {
  10263. BfTypedValue lookupType;
  10264. if (type->IsWrappableType())
  10265. lookupType = BfTypedValue(mModule->GetWrappedStructType(type));
  10266. else
  10267. lookupType = BfTypedValue(type);
  10268. auto findName = nameNode->mRight->ToString();
  10269. /*if (findName == "base")
  10270. {
  10271. mResult = BfTypedValue(lookupType);
  10272. return;
  10273. }*/
  10274. mResult = LookupField(nameNode->mRight, lookupType, findName);
  10275. if ((mResult) || (mPropDef != NULL))
  10276. return;
  10277. if (lookupType.mType != NULL)
  10278. {
  10279. BfTypeInstance* typeInst = lookupType.mType->ToTypeInstance();
  10280. auto compiler = mModule->mCompiler;
  10281. if ((typeInst != NULL) && (compiler->IsAutocomplete()) && (compiler->mResolvePassData->mAutoComplete->CheckFixit(nameNode->mRight)))
  10282. {
  10283. FixitAddMember(typeInst, mExpectingType, nameNode->mRight->ToString(), true);
  10284. }
  10285. }
  10286. if ((mBfEvalExprFlags & BfEvalExprFlags_NoLookupError) == 0)
  10287. mModule->Fail("Field not found", nameNode->mRight);
  10288. return;
  10289. }
  10290. }
  10291. String fieldName = nameNode->mRight->ToString();
  10292. if (auto qualifiedLeftName = BfNodeDynCast<BfQualifiedNameNode>(nameNode->mLeft))
  10293. LookupQualifiedStaticField(qualifiedLeftName, true);
  10294. else if (auto leftName = BfNodeDynCast<BfIdentifierNode>(nameNode->mLeft))
  10295. {
  10296. mResult = LookupIdentifier(leftName);
  10297. }
  10298. GetResult();
  10299. if (!mResult)
  10300. {
  10301. if (!ignoreIdentifierNotFoundError)
  10302. mModule->Fail("Identifier not found", nameNode->mLeft);
  10303. return;
  10304. }
  10305. if (mResult.mType->IsObject())
  10306. {
  10307. mResult = mModule->LoadValue(mResult);
  10308. }
  10309. else if ((mResult.mType->IsPointer()) && mResult.mType->IsStructOrStructPtr())
  10310. {
  10311. BfPointerType* structPtrType = (BfPointerType*) mResult.mType;
  10312. mResult = mModule->LoadValue(mResult);
  10313. mResult.mType = structPtrType->mElementType;
  10314. }
  10315. if (!mResult)
  10316. return;
  10317. if (!mResult.mType->IsTypeInstance())
  10318. {
  10319. mModule->Fail(StrFormat("Type '%s' has no fields", mModule->TypeToString(mResult.mType).c_str()), nameNode->mLeft);
  10320. return;
  10321. }
  10322. auto leftResult = mResult;
  10323. mResult = LookupField(nameNode->mRight, leftResult, fieldName);
  10324. if ((mResult) || (mPropDef != NULL))
  10325. return;
  10326. mModule->Fail(StrFormat("Unable to find member '%s' in '%s'", fieldName.c_str(), mModule->TypeToString(leftResult.mType).c_str()), nameNode->mRight);
  10327. }
  10328. void BfExprEvaluator::LookupQualifiedStaticField(BfAstNode* nameNode, BfIdentifierNode* nameLeft, BfIdentifierNode* nameRight, bool ignoreIdentifierNotFoundError)
  10329. {
  10330. // Lookup left side as a type
  10331. {
  10332. BfType* type = mModule->ResolveTypeRef(nameLeft, NULL, BfPopulateType_Declaration, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_IgnoreLookupError | BfResolveTypeRefFlag_AllowGlobalContainer));
  10333. if ((type != NULL) && (type->IsVar()) && (nameLeft->Equals("var")))
  10334. type = NULL;
  10335. if (type != NULL)
  10336. {
  10337. BfTypedValue lookupType;
  10338. if (type->IsWrappableType())
  10339. lookupType = BfTypedValue(mModule->GetWrappedStructType(type));
  10340. else
  10341. lookupType = BfTypedValue(type);
  10342. auto findName = nameRight->ToString();
  10343. if ((lookupType.mType != NULL) && (lookupType.mType->IsGenericParam()))
  10344. {
  10345. auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)lookupType.mType);
  10346. if (genericParamInstance->mTypeConstraint != NULL)
  10347. {
  10348. mResult = LookupField(nameRight, BfTypedValue(genericParamInstance->mTypeConstraint), findName);
  10349. if ((mResult) || (mPropDef != NULL))
  10350. {
  10351. mOrigPropTarget = lookupType;
  10352. return;
  10353. }
  10354. }
  10355. for (auto constraint : genericParamInstance->mInterfaceConstraints)
  10356. {
  10357. mResult = LookupField(nameRight, BfTypedValue(constraint), findName);
  10358. if ((mResult) || (mPropDef != NULL))
  10359. {
  10360. mOrigPropTarget = lookupType;
  10361. return;
  10362. }
  10363. }
  10364. }
  10365. /*if (findName == "base")
  10366. {
  10367. mResult = BfTypedValue(lookupType);
  10368. return;
  10369. }*/
  10370. mResult = LookupField(nameRight, lookupType, findName);
  10371. if ((mResult) || (mPropDef != NULL))
  10372. return;
  10373. if (lookupType.mType != NULL)
  10374. {
  10375. BfTypeInstance* typeInst = lookupType.mType->ToTypeInstance();
  10376. auto compiler = mModule->mCompiler;
  10377. if ((typeInst != NULL) && (compiler->IsAutocomplete()) && (compiler->mResolvePassData->mAutoComplete->CheckFixit(nameRight)))
  10378. {
  10379. FixitAddMember(typeInst, mExpectingType, nameRight->ToString(), true);
  10380. }
  10381. }
  10382. if ((mBfEvalExprFlags & BfEvalExprFlags_NameOf) != 0)
  10383. {
  10384. auto typeInst = lookupType.mType->ToTypeInstance();
  10385. if ((typeInst != NULL) && (CheckForMethodName(nameRight, typeInst, findName)))
  10386. return;
  10387. }
  10388. if ((mBfEvalExprFlags & BfEvalExprFlags_NoLookupError) == 0)
  10389. mModule->Fail("Field not found", nameRight);
  10390. return;
  10391. }
  10392. }
  10393. String fieldName = nameRight->ToString();
  10394. if (auto qualifiedLeftName = BfNodeDynCast<BfQualifiedNameNode>(nameLeft))
  10395. LookupQualifiedStaticField(qualifiedLeftName, qualifiedLeftName->mLeft, qualifiedLeftName->mRight, true);
  10396. else if (auto leftName = BfNodeDynCast<BfIdentifierNode>(nameLeft))
  10397. {
  10398. mResult = LookupIdentifier(leftName);
  10399. }
  10400. GetResult();
  10401. if (!mResult)
  10402. {
  10403. if (!ignoreIdentifierNotFoundError)
  10404. mModule->Fail("Identifier not found", nameLeft);
  10405. return;
  10406. }
  10407. if (mResult.mType->IsObject())
  10408. {
  10409. mResult = mModule->LoadValue(mResult);
  10410. }
  10411. else if ((mResult.mType->IsPointer()) && mResult.mType->IsStructOrStructPtr())
  10412. {
  10413. BfPointerType* structPtrType = (BfPointerType*)mResult.mType;
  10414. mResult = mModule->LoadValue(mResult);
  10415. mResult = BfTypedValue(mResult.mValue, structPtrType->mElementType, true);
  10416. }
  10417. if (!mResult)
  10418. return;
  10419. if (!mResult.mType->IsTypeInstance())
  10420. {
  10421. if (mResult.mType->IsSizedArray())
  10422. {
  10423. mResult.mType = mModule->GetWrappedStructType(mResult.mType);
  10424. mResult.mValue = mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->MapTypeInstPtr(mResult.mType->ToTypeInstance()));
  10425. }
  10426. else if (mResult.mType->IsWrappableType())
  10427. {
  10428. mResult.mType = mModule->GetWrappedStructType(mResult.mType);
  10429. }
  10430. else
  10431. {
  10432. mModule->Fail(StrFormat("Type '%s' has no fields", mModule->TypeToString(mResult.mType).c_str()), nameLeft);
  10433. return;
  10434. }
  10435. }
  10436. auto leftResult = mResult;
  10437. mResult = LookupField(nameRight, leftResult, fieldName);
  10438. if ((mResult) || (mPropDef != NULL))
  10439. return;
  10440. mModule->CheckTypeRefFixit(nameLeft);
  10441. mModule->Fail(StrFormat("Unable to find member '%s' in '%s'", fieldName.c_str(), mModule->TypeToString(leftResult.mType).c_str()), nameRight);
  10442. }
  10443. void BfExprEvaluator::Visit(BfQualifiedNameNode* nameNode)
  10444. {
  10445. auto autoComplete = GetAutoComplete();
  10446. if (autoComplete != NULL)
  10447. {
  10448. autoComplete->CheckMemberReference(nameNode->mLeft, nameNode->mDot, nameNode->mRight);
  10449. }
  10450. bool hadError = false;
  10451. LookupQualifiedName(nameNode, nameNode->mLeft, nameNode->mRight, true, &hadError);
  10452. if ((mResult) || (mPropDef != NULL))
  10453. return;
  10454. if (hadError)
  10455. return;
  10456. LookupQualifiedStaticField(nameNode, nameNode->mLeft, nameNode->mRight, false);
  10457. }
  10458. void BfExprEvaluator::Visit(BfThisExpression* thisExpr)
  10459. {
  10460. mResult = mModule->GetThis();
  10461. if (!mResult)
  10462. {
  10463. mModule->Fail("Static methods don't have 'this'", thisExpr);
  10464. return;
  10465. }
  10466. auto autoComplete = GetAutoComplete();
  10467. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(thisExpr)))
  10468. autoComplete->SetDefinitionLocation(mModule->mCurTypeInstance->mTypeDef->GetRefNode());
  10469. mResultLocalVar = mModule->GetThisVariable();
  10470. mResultFieldInstance = NULL;
  10471. }
  10472. void BfExprEvaluator::Visit(BfBaseExpression* baseExpr)
  10473. {
  10474. mResult = mModule->GetThis();
  10475. if (!mResult)
  10476. {
  10477. mModule->Fail("Static methods don't have 'base'", baseExpr);
  10478. return;
  10479. }
  10480. if ((mBfEvalExprFlags & BfEvalExprFlags_AllowBase) == 0)
  10481. mModule->Fail("Use of keyword 'base' is not valid in this context", baseExpr);
  10482. auto baseType = mModule->mCurTypeInstance->mBaseType;
  10483. if (baseType == NULL)
  10484. baseType = mModule->mContext->mBfObjectType;
  10485. auto autoComplete = GetAutoComplete();
  10486. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(baseExpr)))
  10487. autoComplete->SetDefinitionLocation(baseType->mTypeDef->GetRefNode());
  10488. mModule->PopulateType(baseType, BfPopulateType_Data);
  10489. mResult = mModule->Cast(baseExpr, mResult, baseType, BfCastFlags_Explicit);
  10490. if (mResult.IsSplat())
  10491. mResult.mKind = BfTypedValueKind_BaseSplatHead;
  10492. else if (mResult.IsAddr())
  10493. mResult.mKind = BfTypedValueKind_BaseAddr;
  10494. else if (mResult)
  10495. mResult.mKind = BfTypedValueKind_BaseValue;
  10496. }
  10497. void BfExprEvaluator::Visit(BfMixinExpression* mixinExpr)
  10498. {
  10499. if (mModule->mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_Mixin)
  10500. {
  10501. auto varType = mModule->GetPrimitiveType(BfTypeCode_Var);
  10502. auto newVar = mModule->AllocFromType(varType, mModule->mCurMethodState->mCurScope);
  10503. mResult = BfTypedValue(newVar, varType, true);
  10504. return;
  10505. }
  10506. auto curMethodState = mModule->mCurMethodState;
  10507. if (curMethodState->mMixinState == NULL)
  10508. {
  10509. mModule->Fail("Mixin references can only be used within mixins", mixinExpr);
  10510. return;
  10511. }
  10512. int localIdx = GetMixinVariable();
  10513. if (localIdx != -1)
  10514. {
  10515. auto varDecl = curMethodState->mLocals[localIdx];
  10516. if (varDecl != NULL)
  10517. {
  10518. BfTypedValue localResult = LoadLocal(varDecl);
  10519. mResult = localResult;
  10520. mResultLocalVar = varDecl;
  10521. mResultFieldInstance = NULL;
  10522. mResultLocalVarRefNode = mixinExpr;
  10523. return;
  10524. }
  10525. }
  10526. if (mModule->mCurMethodInstance->mIsUnspecialized)
  10527. {
  10528. mResult = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Var));
  10529. return;
  10530. }
  10531. mModule->Fail("Mixin value cannot be inferred", mixinExpr);
  10532. }
  10533. void BfExprEvaluator::Visit(BfSizedArrayCreateExpression* createExpr)
  10534. {
  10535. auto type = mModule->ResolveTypeRef(createExpr->mTypeRef, NULL, BfPopulateType_Data, BfResolveTypeRefFlag_AllowInferredSizedArray);
  10536. if (type == NULL)
  10537. return;
  10538. if (type->IsArray())
  10539. {
  10540. // If we have a case like 'int[] (1, 2)' then we infer the sized array size from the initializer
  10541. auto arrayType = (BfArrayType*)type;
  10542. if (arrayType->mDimensions == 1)
  10543. {
  10544. int arraySize = 0;
  10545. if (auto arrayInitExpr = BfNodeDynCast<BfCollectionInitializerExpression>(createExpr->mInitializer))
  10546. {
  10547. arraySize = (int)arrayInitExpr->mValues.size();
  10548. }
  10549. type = mModule->CreateSizedArrayType(arrayType->GetUnderlyingType(), arraySize);
  10550. }
  10551. }
  10552. if (!type->IsSizedArray())
  10553. {
  10554. mModule->Fail("Sized array expected", createExpr->mTypeRef);
  10555. return;
  10556. }
  10557. if (type->IsUndefSizedArray())
  10558. {
  10559. int arraySize = 0;
  10560. if (createExpr->mInitializer != NULL)
  10561. arraySize = (int)createExpr->mInitializer->mValues.size();
  10562. type = mModule->CreateSizedArrayType(type->GetUnderlyingType(), arraySize);
  10563. }
  10564. BfSizedArrayType* arrayType = (BfSizedArrayType*)type;
  10565. if (createExpr->mInitializer == NULL)
  10566. {
  10567. mModule->AssertErrorState();
  10568. mResult = mModule->GetDefaultTypedValue(arrayType);
  10569. return;
  10570. }
  10571. InitializedSizedArray(arrayType, createExpr->mInitializer->mOpenBrace, createExpr->mInitializer->mValues, createExpr->mInitializer->mCommas, createExpr->mInitializer->mCloseBrace);
  10572. }
  10573. void BfExprEvaluator::Visit(BfInitializerExpression* initExpr)
  10574. {
  10575. uint64 unassignedFieldFlags = 0;
  10576. if (auto typeRef = BfNodeDynCast<BfTypeReference>(initExpr->mTarget))
  10577. {
  10578. BfType* type = NULL;
  10579. if (auto typeRef = BfNodeDynCast<BfDotTypeReference>(initExpr->mTarget))
  10580. {
  10581. type = mExpectingType;
  10582. }
  10583. if (type == NULL)
  10584. type = mModule->ResolveTypeRef(typeRef);
  10585. if (type != NULL)
  10586. {
  10587. if (type->IsValueType())
  10588. {
  10589. if ((mReceivingValue != NULL) && (mReceivingValue->mType == type) && (mReceivingValue->IsAddr()))
  10590. {
  10591. mResult = *mReceivingValue;
  10592. mReceivingValue = NULL;
  10593. }
  10594. else
  10595. {
  10596. mResult = BfTypedValue(mModule->CreateAlloca(type), type, true);
  10597. }
  10598. auto typeInstance = type->ToTypeInstance();
  10599. if (typeInstance != NULL)
  10600. unassignedFieldFlags = (1 << typeInstance->mMergedFieldDataCount) - 1;
  10601. }
  10602. else
  10603. {
  10604. mModule->Fail("Initializer expressions can only be used on value types or allocated values", initExpr->mTarget);
  10605. }
  10606. }
  10607. }
  10608. else if (auto objCreateExpr = BfNodeDynCast<BfObjectCreateExpression>(initExpr->mTarget))
  10609. {
  10610. CreateObject(objCreateExpr, objCreateExpr->mNewNode, NULL, initExpr->mInlineTypeRef);
  10611. }
  10612. else
  10613. VisitChild(initExpr->mTarget);
  10614. if (!mResult)
  10615. mResult = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  10616. BfIRBlock initBlock = BfIRBlock();
  10617. if (unassignedFieldFlags != 0)
  10618. {
  10619. initBlock = mModule->mBfIRBuilder->CreateBlock("initStart", true);
  10620. mModule->mBfIRBuilder->CreateBr(initBlock);
  10621. mModule->mBfIRBuilder->SetInsertPoint(initBlock);
  10622. }
  10623. BfTypedValue origInitValue = GetResult(true);
  10624. BfTypedValue initValue = origInitValue;
  10625. if ((initValue) && (initValue.mType->IsRef()))
  10626. initValue = mModule->RemoveRef(initValue, false);
  10627. bool isFirstAdd = true;
  10628. SetAndRestoreValue<BfTypeInstance*> prevPrivateTypeInstance(mModule->mCurMethodState->mPrivateTypeInstance);
  10629. BfScopeData newScope;
  10630. if (initExpr->mInlineTypeRef != NULL)
  10631. mModule->mCurMethodState->mPrivateTypeInstance = initValue.mType->ToTypeInstance();
  10632. newScope.mAllowTargeting = false;
  10633. newScope.mInnerIsConditional = true;
  10634. newScope.mCloseNode = initExpr->mCloseBrace;
  10635. mModule->mCurMethodState->AddScope(&newScope);
  10636. mModule->NewScopeState();
  10637. BfLocalVariable* localDef = new BfLocalVariable();
  10638. localDef->mName = "_";
  10639. localDef->mResolvedType = initValue.mType;
  10640. localDef->mAssignedKind = BfLocalVarAssignKind_Unconditional;
  10641. if (initValue.IsAddr())
  10642. {
  10643. localDef->mAddr = initValue.mValue;
  10644. }
  10645. else
  10646. {
  10647. localDef->mValue = initValue.mValue;
  10648. localDef->mIsSplat = initValue.IsSplat();
  10649. }
  10650. if (!localDef->mResolvedType->IsVar())
  10651. mModule->AddLocalVariableDef(localDef, true, true);
  10652. auto autoComplete = mModule->mCompiler->GetAutoComplete();
  10653. for (auto elementExpr : initExpr->mValues)
  10654. {
  10655. if ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0)
  10656. {
  10657. mModule->Fail("Comptime cannot evaluate initializer expressions", elementExpr);
  10658. break;
  10659. }
  10660. bool wasValidInitKind = false;
  10661. if (auto assignExpr = BfNodeDynCast<BfAssignmentExpression>(elementExpr))
  10662. {
  10663. BfTypedValue fieldResult;
  10664. if (auto identifierNode = BfNodeDynCast<BfIdentifierNode>(assignExpr->mLeft))
  10665. {
  10666. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(identifierNode)))
  10667. {
  10668. auto type = initValue.mType;
  10669. if (type->IsPointer())
  10670. type = type->GetUnderlyingType();
  10671. if (auto typeInst = type->ToTypeInstance())
  10672. {
  10673. autoComplete->mInsertStartIdx = identifierNode->GetSrcStart();
  10674. autoComplete->mInsertEndIdx = identifierNode->GetSrcEnd();
  10675. autoComplete->AddTypeMembers(typeInst, false, true, identifierNode->ToString(), typeInst, false, true, false);
  10676. }
  10677. }
  10678. StringT<128> findName;
  10679. identifierNode->ToString(findName);
  10680. mResultFieldInstance = NULL;
  10681. fieldResult = LookupField(identifierNode, initValue, findName, BfLookupFieldFlag_IsImplicitThis);
  10682. if ((fieldResult.mKind == BfTypedValueKind_TempAddr) || (fieldResult.mKind == BfTypedValueKind_RestrictedTempAddr))
  10683. fieldResult.mKind = BfTypedValueKind_Addr;
  10684. if ((mResultFieldInstance != NULL) && (mResultFieldInstance->mMergedDataIdx != -1))
  10685. {
  10686. int resultLocalVarField = 0;
  10687. int resultLocalVarFieldCount = 0;
  10688. mResultFieldInstance->GetDataRange(resultLocalVarField, resultLocalVarFieldCount);
  10689. for (int i = 0; i < resultLocalVarFieldCount; i++)
  10690. unassignedFieldFlags &= ~((int64)1 << (resultLocalVarField - 1 + i));
  10691. }
  10692. wasValidInitKind = true;
  10693. if ((fieldResult) || (mPropDef != NULL))
  10694. {
  10695. if (mResultFieldInstance != NULL)
  10696. {
  10697. auto autoComplete = GetAutoComplete();
  10698. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(identifierNode)))
  10699. {
  10700. auto fieldDef = mResultFieldInstance->GetFieldDef();
  10701. if (fieldDef != NULL)
  10702. autoComplete->SetDefinitionLocation(fieldDef->GetRefNode());
  10703. }
  10704. }
  10705. mResult = fieldResult;
  10706. PerformAssignment(assignExpr, true, BfTypedValue());
  10707. mResult = BfTypedValue();
  10708. }
  10709. else
  10710. {
  10711. mModule->Fail(StrFormat("'%s' does not contain a definition for '%s'", mModule->TypeToString(initValue.mType).c_str(),
  10712. findName.c_str()), identifierNode);
  10713. }
  10714. }
  10715. else if (auto indexerExpression = BfNodeDynCast<BfIndexerExpression>(assignExpr->mLeft))
  10716. {
  10717. if (indexerExpression->mTarget == NULL)
  10718. {
  10719. if ((initValue.mType->IsValueType()) && (!initValue.IsAddr()))
  10720. {
  10721. initValue = mModule->MakeAddressable(initValue, true, true);
  10722. }
  10723. mResult = BfTypedValue();
  10724. HandleIndexerExpression(indexerExpression, initValue);
  10725. wasValidInitKind = true;
  10726. if ((mPropDef) || (mResult))
  10727. {
  10728. PerformAssignment(assignExpr, true, BfTypedValue());
  10729. mResult = BfTypedValue();
  10730. }
  10731. }
  10732. }
  10733. }
  10734. else
  10735. {
  10736. BfBlock* block = BfNodeDynCast<BfBlock>(elementExpr);
  10737. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(elementExpr)))
  10738. {
  10739. if (auto identiferNode = BfNodeDynCast<BfIdentifierNode>(elementExpr))
  10740. {
  10741. auto type = initValue.mType;
  10742. if (type->IsPointer())
  10743. type = type->GetUnderlyingType();
  10744. if (auto typeInst = type->ToTypeInstance())
  10745. {
  10746. String filter;
  10747. identiferNode->ToString(filter);
  10748. autoComplete->AddTypeMembers(typeInst, false, true, filter, typeInst, false, true, false);
  10749. }
  10750. }
  10751. }
  10752. if ((block != NULL) && (!block->IsExpression()))
  10753. {
  10754. mModule->VisitCodeBlock(block);
  10755. }
  10756. else
  10757. {
  10758. BfExprEvaluator exprEvaluator(mModule);
  10759. SizedArray<BfExpression*, 2> argExprs;
  10760. argExprs.push_back(elementExpr);
  10761. BfSizedArray<BfExpression*> sizedArgExprs(argExprs);
  10762. BfResolvedArgs argValues(&sizedArgExprs);
  10763. exprEvaluator.ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval);
  10764. exprEvaluator.MatchMethod(elementExpr, NULL, initValue, false, false, "Add", argValues, BfMethodGenericArguments());
  10765. }
  10766. wasValidInitKind = true;
  10767. }
  10768. if (!wasValidInitKind)
  10769. {
  10770. mModule->Fail("Invalid initializer member declarator", initExpr);
  10771. }
  10772. }
  10773. mModule->RestoreScopeState();
  10774. if (initExpr->mValues.IsEmpty())
  10775. {
  10776. // When we are first typing out 'override', we
  10777. if (initExpr->mInlineTypeRef != NULL)
  10778. {
  10779. if (auto defineBlock = BfNodeDynCast<BfBlock>(initExpr->mInlineTypeRef->mTypeDeclaration->mDefineNode))
  10780. {
  10781. if (defineBlock->mChildArr.mSize == 1)
  10782. {
  10783. auto lastNode = defineBlock->mChildArr[0];
  10784. if (lastNode->Equals("override"))
  10785. {
  10786. auto autoComplete = mModule->mCompiler->GetAutoComplete();
  10787. if (autoComplete != NULL)
  10788. {
  10789. int cursorIdx = autoComplete->GetCursorIdx(lastNode);
  10790. if ((autoComplete->IsAutocompleteNode(lastNode, 1)) && (cursorIdx == lastNode->GetSrcEnd()))
  10791. {
  10792. auto typeInst = initValue.mType->ToTypeInstance();
  10793. if (typeInst != NULL)
  10794. {
  10795. SetAndRestoreValue<BfTypeInstance*> prevTypeInst(mModule->mCurTypeInstance, typeInst);
  10796. SetAndRestoreValue<BfMethodInstance*> prevMethodInst(mModule->mCurMethodInstance, NULL);
  10797. autoComplete->AddOverrides("", true);
  10798. autoComplete->mInsertStartIdx = lastNode->mSrcStart;
  10799. autoComplete->mInsertEndIdx = lastNode->mSrcEnd;
  10800. }
  10801. }
  10802. }
  10803. }
  10804. }
  10805. }
  10806. }
  10807. }
  10808. else
  10809. {
  10810. auto lastNode = initExpr->mValues.back();
  10811. if (auto lastIdentifier = BfNodeDynCast<BfIdentifierNode>(lastNode))
  10812. {
  10813. auto autoComplete = mModule->mCompiler->GetAutoComplete();
  10814. if (autoComplete != NULL)
  10815. {
  10816. autoComplete->CheckIdentifier(lastIdentifier, false, false);
  10817. }
  10818. }
  10819. }
  10820. if (unassignedFieldFlags != 0)
  10821. {
  10822. auto curBlock = mModule->mBfIRBuilder->GetInsertBlock();
  10823. mModule->mBfIRBuilder->SetInsertPointAtStart(initBlock);
  10824. mModule->mBfIRBuilder->CreateMemSet(initValue.mValue, mModule->GetConstValue(0, mModule->GetPrimitiveType(BfTypeCode_Int8)),
  10825. mModule->GetConstValue(initValue.mType->mSize), initValue.mType->mAlign);
  10826. mModule->mBfIRBuilder->SetInsertPoint(curBlock);
  10827. }
  10828. mResult = origInitValue;
  10829. }
  10830. void BfExprEvaluator::Visit(BfCollectionInitializerExpression* arrayInitExpr)
  10831. {
  10832. mModule->Fail("Collection initializer not usable here", arrayInitExpr);
  10833. }
  10834. void BfExprEvaluator::Visit(BfTypeOfExpression* typeOfExpr)
  10835. {
  10836. auto typeType = mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef);
  10837. auto autoComplete = GetAutoComplete();
  10838. if ((autoComplete != NULL) && (typeOfExpr->mTypeRef != NULL))
  10839. {
  10840. autoComplete->CheckTypeRef(typeOfExpr->mTypeRef, false, true);
  10841. }
  10842. BfType* type;
  10843. if ((typeOfExpr->mTypeRef != NULL) && (typeOfExpr->mTypeRef->IsA<BfVarTypeReference>()))
  10844. {
  10845. type = mModule->GetPrimitiveType(BfTypeCode_Var);
  10846. }
  10847. else
  10848. {
  10849. type = ResolveTypeRef(typeOfExpr->mTypeRef, BfPopulateType_Identity, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_AllowGlobalsSelf | BfResolveTypeRefFlag_AllowUnboundGeneric));
  10850. }
  10851. if (type == NULL)
  10852. {
  10853. mResult = mModule->GetDefaultTypedValue(mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef));
  10854. return;
  10855. }
  10856. mModule->AddDependency(type, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
  10857. mResult = BfTypedValue(mModule->CreateTypeDataRef(type), typeType);
  10858. }
  10859. bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifierNode* propName)
  10860. {
  10861. auto typeType = mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef);
  10862. BfType* type;
  10863. //
  10864. {
  10865. // We ignore errors because we go through the normal Visit(BfTypeOfExpression) if this fails, which will throw the error again
  10866. SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
  10867. if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeOfExpr->mTypeRef))
  10868. {
  10869. SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
  10870. type = mModule->ResolveTypeRefAllowUnboundGenerics(typeOfExpr->mTypeRef, BfPopulateType_Identity);
  10871. }
  10872. else
  10873. {
  10874. type = ResolveTypeRef(typeOfExpr->mTypeRef, BfPopulateType_Identity, BfResolveTypeRefFlag_IgnoreLookupError);
  10875. }
  10876. }
  10877. if (type == NULL)
  10878. {
  10879. mResult = mModule->GetDefaultTypedValue(mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef));
  10880. return false;
  10881. }
  10882. bool success = true;
  10883. defer(
  10884. {
  10885. if (success)
  10886. mModule->AddDependency(type, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_TypeSignature);
  10887. });
  10888. // We want to try to avoid triggering OnTypeInit for basic info
  10889. mModule->PopulateType(type, BfPopulateType_Interfaces_Direct);
  10890. auto typeInstance = type->ToTypeInstance();
  10891. auto _BoolResult = [&](bool val)
  10892. {
  10893. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, val ? 1 : 0), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  10894. };
  10895. auto _Int32Result = [&](int32 val)
  10896. {
  10897. mResult = BfTypedValue(mModule->GetConstValue32(val), mModule->GetPrimitiveType(BfTypeCode_Int32));
  10898. };
  10899. String memberName;
  10900. propName->ToString(memberName);
  10901. bool handled = true;
  10902. if (memberName == "IsTypedPrimitive")
  10903. _BoolResult(type->IsPrimitiveType());
  10904. else if (memberName == "IsObject")
  10905. _BoolResult(type->IsObject());
  10906. else if (memberName == "IsValueType")
  10907. _BoolResult(type->IsValueType());
  10908. else if (memberName == "IsPrimitive")
  10909. _BoolResult(type->IsPrimitiveType());
  10910. else if (memberName == "IsInteger")
  10911. _BoolResult(type->IsInteger());
  10912. else if (memberName == "IsIntegral")
  10913. _BoolResult(type->IsIntegral());
  10914. else if (memberName == "IsSigned")
  10915. _BoolResult(type->IsSigned());
  10916. else if (memberName == "IsFloatingPoint")
  10917. _BoolResult(type->IsFloat());
  10918. else if (memberName == "IsPointer")
  10919. _BoolResult(type->IsPointer());
  10920. else if (memberName == "IsStruct")
  10921. _BoolResult(type->IsStruct());
  10922. else if (memberName == "IsSplattable")
  10923. _BoolResult(type->IsSplattable());
  10924. else if (memberName == "IsUnion")
  10925. _BoolResult(type->IsUnion());
  10926. else if (memberName == "IsBoxed")
  10927. _BoolResult(type->IsBoxed());
  10928. else if (memberName == "IsEnum")
  10929. _BoolResult(type->IsEnum());
  10930. else if (memberName == "IsTuple")
  10931. _BoolResult(type->IsTuple());
  10932. else if (memberName == "IsNullable")
  10933. _BoolResult(type->IsNullable());
  10934. else if (memberName == "IsGenericType")
  10935. _BoolResult(type->IsGenericTypeInstance());
  10936. else if (memberName == "IsGenericParam")
  10937. _BoolResult(type->IsGenericParam());
  10938. else if (memberName == "IsArray")
  10939. _BoolResult(type->IsArray());
  10940. else if (memberName == "IsSizedArray")
  10941. _BoolResult(type->IsSizedArray());
  10942. else if (memberName == "TypeId")
  10943. {
  10944. _Int32Result(type->mTypeId);
  10945. mResult.mType = mModule->ResolveTypeDef(mModule->mCompiler->mReflectTypeIdTypeDef);
  10946. }
  10947. else if (memberName == "GenericParamCount")
  10948. {
  10949. auto genericTypeInst = type->ToGenericTypeInstance();
  10950. _Int32Result((genericTypeInst != NULL) ? (int)genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size() : 0);
  10951. }
  10952. else
  10953. {
  10954. // We need full data
  10955. mModule->PopulateType(type, BfPopulateType_Data);
  10956. if (memberName == "Size")
  10957. _Int32Result(type->mSize);
  10958. else if (memberName == "Align")
  10959. _Int32Result(type->mAlign);
  10960. else if (memberName == "Stride")
  10961. _Int32Result(type->GetStride());
  10962. else if (memberName == "InstanceSize")
  10963. _Int32Result((typeInstance != NULL) ? typeInstance->mInstSize : type->mSize);
  10964. else if (memberName == "InstanceAlign")
  10965. _Int32Result((typeInstance != NULL) ? typeInstance->mInstAlign : type->mSize);
  10966. else if (memberName == "InstanceStride")
  10967. _Int32Result((typeInstance != NULL) ? typeInstance->GetInstStride() : type->GetStride());
  10968. else if (memberName == "UnderlyingType")
  10969. {
  10970. bool handled = false;
  10971. auto typeType = mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef);
  10972. if (type->IsGenericParam())
  10973. {
  10974. auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)type);
  10975. if (genericParamInstance->IsEnum())
  10976. {
  10977. handled = true;
  10978. mResult = BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->MapType(typeType)), typeType);
  10979. }
  10980. }
  10981. else if (type->IsEnum())
  10982. {
  10983. if (type->IsDataIncomplete())
  10984. mModule->PopulateType(type);
  10985. auto underlyingType = type->GetUnderlyingType();
  10986. if (underlyingType != NULL)
  10987. {
  10988. handled = true;
  10989. mModule->AddDependency(underlyingType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
  10990. mResult = BfTypedValue(mModule->CreateTypeDataRef(underlyingType), typeType);
  10991. }
  10992. }
  10993. if (!handled)
  10994. mResult = BfTypedValue(mModule->CreateTypeDataRef(mModule->GetPrimitiveType(BfTypeCode_None)), typeType);
  10995. }
  10996. else if (memberName == "BitSize")
  10997. {
  10998. auto int32Type = mModule->GetPrimitiveType(BfTypeCode_Int32);
  10999. BfType* checkType = type;
  11000. if (checkType->IsTypedPrimitive())
  11001. checkType = checkType->GetUnderlyingType();
  11002. if (checkType->IsGenericParam())
  11003. {
  11004. mResult = mModule->GetDefaultTypedValue(int32Type, false, Beefy::BfDefaultValueKind_Undef);
  11005. return true;
  11006. }
  11007. if ((typeInstance != NULL) && (typeInstance->IsEnum()))
  11008. {
  11009. if (typeInstance->mTypeInfoEx != NULL)
  11010. {
  11011. int64 minValue = typeInstance->mTypeInfoEx->mMinValue;
  11012. if (minValue < 0)
  11013. minValue = ~minValue;
  11014. int64 maxValue = typeInstance->mTypeInfoEx->mMaxValue;
  11015. if (maxValue < 0)
  11016. maxValue = ~maxValue;
  11017. uint64 value = (uint64)minValue | (uint64)maxValue;
  11018. int bitCount = 1;
  11019. if (typeInstance->mTypeInfoEx->mMinValue < 0)
  11020. bitCount++;
  11021. while (value >>= 1)
  11022. bitCount++;
  11023. mModule->AddDependency(typeInstance, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields);
  11024. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, bitCount), int32Type);
  11025. return true;
  11026. }
  11027. }
  11028. int bitSize = checkType->mSize * 8;
  11029. if (checkType->GetTypeCode() == BfTypeCode_Boolean)
  11030. bitSize = 1;
  11031. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, bitSize), int32Type);
  11032. return true;
  11033. }
  11034. else if ((memberName == "MinValue") || (memberName == "MaxValue"))
  11035. {
  11036. bool isMin = memberName == "MinValue";
  11037. bool isBitSize = memberName == "BitSize";
  11038. BfType* checkType = type;
  11039. if (checkType->IsTypedPrimitive())
  11040. checkType = checkType->GetUnderlyingType();
  11041. if (checkType->IsGenericParam())
  11042. {
  11043. bool foundMatch = false;
  11044. auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)checkType);
  11045. if (((genericParamInstance->mGenericParamFlags & BfGenericParamFlag_Enum) != 0) ||
  11046. ((genericParamInstance->mTypeConstraint != NULL) && (genericParamInstance->mTypeConstraint->IsInstanceOf(mModule->mCompiler->mEnumTypeDef))))
  11047. foundMatch = true;
  11048. else
  11049. {
  11050. for (auto constraint : genericParamInstance->mInterfaceConstraints)
  11051. {
  11052. if (constraint->IsInstanceOf(mModule->mCompiler->mIIntegerTypeDef))
  11053. foundMatch = true;
  11054. }
  11055. }
  11056. if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsUnspecialized) && (mModule->mCurMethodInstance->mMethodInfoEx != NULL))
  11057. {
  11058. for (int genericParamIdx = (int)mModule->mCurMethodInstance->mMethodInfoEx->mMethodGenericArguments.size();
  11059. genericParamIdx < mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams.size(); genericParamIdx++)
  11060. {
  11061. genericParamInstance = mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
  11062. if (genericParamInstance->mExternType == type)
  11063. {
  11064. if (((genericParamInstance->mGenericParamFlags & BfGenericParamFlag_Enum) != 0) ||
  11065. ((genericParamInstance->mTypeConstraint != NULL) && (genericParamInstance->mTypeConstraint->IsInstanceOf(mModule->mCompiler->mEnumTypeDef))))
  11066. foundMatch = true;
  11067. }
  11068. }
  11069. }
  11070. if (foundMatch)
  11071. {
  11072. mResult = mModule->GetDefaultTypedValue(type, false, Beefy::BfDefaultValueKind_Undef);
  11073. return true;
  11074. }
  11075. }
  11076. if (checkType->IsPrimitiveType())
  11077. {
  11078. auto primType = (BfPrimitiveType*)checkType;
  11079. if ((typeInstance != NULL) && (typeInstance->IsEnum()))
  11080. {
  11081. if (typeInstance->mTypeInfoEx != NULL)
  11082. {
  11083. mModule->AddDependency(typeInstance, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields);
  11084. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? (uint64)typeInstance->mTypeInfoEx->mMinValue : (uint64)typeInstance->mTypeInfoEx->mMaxValue), typeInstance);
  11085. return true;
  11086. }
  11087. }
  11088. else
  11089. {
  11090. switch (primType->mTypeDef->mTypeCode)
  11091. {
  11092. case BfTypeCode_Int8:
  11093. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? -0x80 : 0x7F), primType);
  11094. return true;
  11095. case BfTypeCode_Int16:
  11096. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? -0x8000 : 0x7FFF), primType);
  11097. return true;
  11098. case BfTypeCode_Int32:
  11099. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? (uint64)-0x80000000LL : 0x7FFFFFFF), primType);
  11100. return true;
  11101. case BfTypeCode_Int64:
  11102. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? (uint64)-0x8000000000000000LL : (uint64)0x7FFFFFFFFFFFFFFFLL), primType);
  11103. return true;
  11104. case BfTypeCode_UInt8:
  11105. case BfTypeCode_Char8:
  11106. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? 0 : 0xFF), primType);
  11107. return true;
  11108. case BfTypeCode_UInt16:
  11109. case BfTypeCode_Char16:
  11110. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? 0 : 0xFFFF), primType);
  11111. return true;
  11112. case BfTypeCode_UInt32:
  11113. case BfTypeCode_Char32:
  11114. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? 0 : (uint64)0xFFFFFFFFLL), primType);
  11115. return true;
  11116. case BfTypeCode_UInt64:
  11117. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? 0 : (uint64)0xFFFFFFFFFFFFFFFFLL), primType);
  11118. return true;
  11119. case BfTypeCode_IntPtr:
  11120. if (mModule->mSystem->mPtrSize == 8)
  11121. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? (uint64)-0x8000000000000000LL : (uint64)0x7FFFFFFFFFFFFFFFLL), primType);
  11122. else
  11123. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? (uint64)-0x80000000LL : 0x7FFFFFFF), primType);
  11124. return true;
  11125. case BfTypeCode_UIntPtr:
  11126. if (mModule->mSystem->mPtrSize == 8)
  11127. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? 0 : (uint64)0xFFFFFFFFFFFFFFFFLL), primType);
  11128. else
  11129. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? 0 : (uint64)0xFFFFFFFFLL), primType);
  11130. return true;
  11131. default: break;
  11132. }
  11133. }
  11134. }
  11135. if (type->IsEnum())
  11136. {
  11137. mModule->Fail(StrFormat("'MinValue' cannot be used on enum with payload '%s'", mModule->TypeToString(type).c_str()), propName);
  11138. }
  11139. else
  11140. {
  11141. mModule->Fail(StrFormat("'%s' cannot be used on type '%s'", memberName.c_str(), mModule->TypeToString(type).c_str()), propName);
  11142. }
  11143. }
  11144. else
  11145. {
  11146. success = false;
  11147. return false;
  11148. }
  11149. }
  11150. if ((type->IsGenericParam()) && (!mModule->mIsComptimeModule))
  11151. {
  11152. if (mResult.mType != NULL)
  11153. mResult = mModule->GetDefaultTypedValue(mResult.mType, false, Beefy::BfDefaultValueKind_Undef);
  11154. }
  11155. auto autoComplete = GetAutoComplete();
  11156. if ((autoComplete != NULL) && (typeOfExpr->mTypeRef != NULL))
  11157. {
  11158. autoComplete->CheckTypeRef(typeOfExpr->mTypeRef, false, true);
  11159. }
  11160. return true;
  11161. }
  11162. void BfExprEvaluator::DoTypeIntAttr(BfTypeReference* typeRef, BfTokenNode* commaToken, BfIdentifierNode* memberName, BfToken token)
  11163. {
  11164. auto autoComplete = GetAutoComplete();
  11165. auto type = mModule->ResolveTypeRef(typeRef, BfPopulateType_Data, BfResolveTypeRefFlag_AutoComplete);
  11166. if (type == NULL)
  11167. return;
  11168. mModule->AddDependency(type, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage); // Local usage ensures it changes when the type data changes
  11169. auto typeInst = type->ToTypeInstance();
  11170. if ((typeInst != NULL) && (typeInst->mTypeDef->mIsOpaque))
  11171. {
  11172. mModule->Fail(StrFormat("Unable to determine attributes for opaque type '%s'", mModule->TypeToString(type).c_str()), typeRef);
  11173. }
  11174. BfType* sizeType = mModule->GetPrimitiveType(BfTypeCode_Int32);
  11175. int attrVal = 0;
  11176. switch (token)
  11177. {
  11178. case BfToken_SizeOf: attrVal = type->mSize; break;
  11179. case BfToken_AlignOf: attrVal = type->mAlign; break;
  11180. case BfToken_StrideOf: attrVal = type->GetStride(); break;
  11181. default: break;
  11182. }
  11183. if (token == BfToken_OffsetOf)
  11184. {
  11185. bool found = false;
  11186. String findName;
  11187. if (memberName != NULL)
  11188. findName = memberName->ToString();
  11189. BfAstNode* refNode = typeRef;
  11190. if (memberName != NULL)
  11191. refNode = memberName;
  11192. auto checkTypeInst = typeInst;
  11193. while (checkTypeInst != NULL)
  11194. {
  11195. checkTypeInst->mTypeDef->PopulateMemberSets();
  11196. String filter;
  11197. if ((autoComplete != NULL) && (autoComplete->InitAutocomplete(commaToken, memberName, filter)))
  11198. {
  11199. auto activeTypeDef = mModule->GetActiveTypeDef();
  11200. mModule->PopulateType(checkTypeInst);
  11201. BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None;
  11202. for (auto fieldDef : checkTypeInst->mTypeDef->mFields)
  11203. {
  11204. if (fieldDef->mIsStatic)
  11205. continue;
  11206. if (!mModule->CheckProtection(protectionCheckFlags, typeInst, fieldDef->mDeclaringType->mProject, fieldDef->mProtection, typeInst))
  11207. continue;
  11208. if ((!typeInst->IsTypeMemberIncluded(fieldDef->mDeclaringType, activeTypeDef, mModule)) ||
  11209. (!typeInst->IsTypeMemberAccessible(fieldDef->mDeclaringType, activeTypeDef)))
  11210. continue;
  11211. auto& fieldInst = checkTypeInst->mFieldInstances[fieldDef->mIdx];
  11212. autoComplete->AddField(checkTypeInst, fieldDef, &fieldInst, filter);
  11213. }
  11214. }
  11215. BfMemberSetEntry* memberSetEntry = NULL;
  11216. if (checkTypeInst->mTypeDef->mFieldSet.TryGetWith(findName, &memberSetEntry))
  11217. {
  11218. auto fieldDef = (BfFieldDef*)memberSetEntry->mMemberDef;
  11219. if (fieldDef != NULL)
  11220. {
  11221. if (fieldDef->mIsStatic)
  11222. mModule->Fail(StrFormat("Cannot generate an offset from static field '%s.%s'", mModule->TypeToString(type).c_str(), fieldDef->mName.c_str()), refNode);
  11223. mModule->PopulateType(checkTypeInst);
  11224. auto& fieldInst = checkTypeInst->mFieldInstances[fieldDef->mIdx];
  11225. attrVal = fieldInst.mDataOffset;
  11226. found = true;
  11227. break;
  11228. }
  11229. }
  11230. checkTypeInst = checkTypeInst->mBaseType;
  11231. }
  11232. if (!found)
  11233. {
  11234. mModule->Fail(StrFormat("Unable to locate field '%s.%s'", mModule->TypeToString(type).c_str(), findName.c_str()), refNode);
  11235. }
  11236. }
  11237. bool isUndefVal = false;
  11238. if (type->IsGenericParam())
  11239. isUndefVal = true;
  11240. if (type->IsSizedArray())
  11241. {
  11242. auto sizedArray = (BfSizedArrayType*)type;
  11243. if (sizedArray->mElementCount == -1)
  11244. isUndefVal = true;
  11245. }
  11246. if (isUndefVal)
  11247. {
  11248. // We do this so we know it's a constant but we can't assume anything about its value
  11249. // We make the value an Int32 which doesn't match the IntPtr type, but it allows us to
  11250. // assume it can be implicitly cased to int32
  11251. mResult = BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->MapType(sizeType)), sizeType);
  11252. }
  11253. else
  11254. mResult = BfTypedValue(mModule->GetConstValue(attrVal, sizeType), sizeType);
  11255. }
  11256. void BfExprEvaluator::Visit(BfSizeOfExpression* sizeOfExpr)
  11257. {
  11258. DoTypeIntAttr(sizeOfExpr->mTypeRef, NULL, NULL, BfToken_SizeOf);
  11259. }
  11260. void BfExprEvaluator::Visit(BfAlignOfExpression* alignOfExpr)
  11261. {
  11262. DoTypeIntAttr(alignOfExpr->mTypeRef, NULL, NULL, BfToken_AlignOf);
  11263. }
  11264. void BfExprEvaluator::Visit(BfStrideOfExpression* strideOfExpr)
  11265. {
  11266. DoTypeIntAttr(strideOfExpr->mTypeRef, NULL, NULL, BfToken_StrideOf);
  11267. }
  11268. void BfExprEvaluator::Visit(BfOffsetOfExpression* offsetOfExpr)
  11269. {
  11270. DoTypeIntAttr(offsetOfExpr->mTypeRef, offsetOfExpr->mCommaToken, offsetOfExpr->mMemberName, BfToken_OffsetOf);
  11271. }
  11272. void BfExprEvaluator::Visit(BfNameOfExpression* nameOfExpr)
  11273. {
  11274. String name;
  11275. if (mModule->IsInSpecializedGeneric())
  11276. {
  11277. if (auto identifierNode = BfNodeDynCastExact<BfIdentifierNode>(nameOfExpr->mTarget))
  11278. {
  11279. // This is necessary so we don't resolve 'T' to the actual generic argument type
  11280. name = identifierNode->ToString();
  11281. }
  11282. }
  11283. if (name.IsEmpty())
  11284. {
  11285. auto type = mModule->ResolveTypeRef(nameOfExpr->mTarget, {}, BfPopulateType_IdentityNoRemapAlias,
  11286. (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_AllowUnboundGeneric | BfResolveTypeRefFlag_IgnoreLookupError | BfResolveTypeRefFlag_IgnoreProtection));
  11287. if (type != NULL)
  11288. {
  11289. auto typeInst = type->ToTypeInstance();
  11290. if (typeInst != NULL)
  11291. name = typeInst->mTypeDef->mName->ToString();
  11292. else
  11293. name = mModule->TypeToString(type);
  11294. mModule->AddDependency(type, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_NameReference);
  11295. // Just do this for autocomplete
  11296. SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
  11297. VisitChild(nameOfExpr->mTarget);
  11298. }
  11299. }
  11300. if (name.IsEmpty())
  11301. {
  11302. if (auto identifer = BfNodeDynCast<BfIdentifierNode>(nameOfExpr->mTarget))
  11303. {
  11304. String targetStr = nameOfExpr->mTarget->ToString();
  11305. BfAtomComposite targetComposite;
  11306. bool isValid = mModule->mSystem->ParseAtomComposite(targetStr, targetComposite);
  11307. bool namespaceExists = false;
  11308. BfProject* bfProject = NULL;
  11309. auto activeTypeDef = mModule->GetActiveTypeDef();
  11310. if (activeTypeDef != NULL)
  11311. bfProject = activeTypeDef->mProject;
  11312. auto _CheckProject = [&](BfProject* project)
  11313. {
  11314. if ((isValid) && (project->mNamespaces.ContainsKey(targetComposite)))
  11315. namespaceExists = true;
  11316. };
  11317. if (bfProject != NULL)
  11318. {
  11319. for (int depIdx = -1; depIdx < (int)bfProject->mDependencies.size(); depIdx++)
  11320. {
  11321. BfProject* depProject = (depIdx == -1) ? bfProject : bfProject->mDependencies[depIdx];
  11322. _CheckProject(depProject);
  11323. }
  11324. }
  11325. else
  11326. {
  11327. for (auto project : mModule->mSystem->mProjects)
  11328. _CheckProject(project);
  11329. }
  11330. if (namespaceExists)
  11331. {
  11332. if (mModule->mCompiler->mResolvePassData != NULL)
  11333. {
  11334. if (auto sourceClassifier = mModule->mCompiler->mResolvePassData->GetSourceClassifier(nameOfExpr->mTarget))
  11335. {
  11336. BfAstNode* checkIdentifier = identifer;
  11337. while (true)
  11338. {
  11339. auto qualifiedIdentifier = BfNodeDynCast<BfQualifiedNameNode>(checkIdentifier);
  11340. if (qualifiedIdentifier == NULL)
  11341. break;
  11342. sourceClassifier->SetElementType(qualifiedIdentifier->mRight, BfSourceElementType_Namespace);
  11343. checkIdentifier = qualifiedIdentifier->mLeft;
  11344. }
  11345. sourceClassifier->SetElementType(checkIdentifier, BfSourceElementType_Namespace);
  11346. }
  11347. }
  11348. name = targetComposite.mParts[targetComposite.mSize - 1]->ToString();
  11349. }
  11350. }
  11351. }
  11352. if (name.IsEmpty())
  11353. {
  11354. SetAndRestoreValue<BfEvalExprFlags> prevFlags(mBfEvalExprFlags, (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_NameOf));
  11355. SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mBfIRBuilder->mIgnoreWrites, true);
  11356. VisitChild(nameOfExpr->mTarget);
  11357. if ((mBfEvalExprFlags & BfEvalExprFlags_NameOfSuccess) != 0)
  11358. {
  11359. BfAstNode* nameNode = nameOfExpr->mTarget;
  11360. if (auto attributedIdentifierNode = BfNodeDynCast<BfAttributedIdentifierNode>(nameNode))
  11361. nameNode = attributedIdentifierNode->mIdentifier;
  11362. if (auto memberReferenceExpr = BfNodeDynCast<BfMemberReferenceExpression>(nameNode))
  11363. nameNode = memberReferenceExpr->mMemberName;
  11364. if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(nameNode))
  11365. nameNode = qualifiedNameNode->mRight;
  11366. name = nameNode->ToString();
  11367. }
  11368. else if (mResultFieldInstance != NULL)
  11369. {
  11370. auto fieldDef = mResultFieldInstance->GetFieldDef();
  11371. if (fieldDef != NULL)
  11372. name = fieldDef->mName;
  11373. }
  11374. else if (mResultLocalVar != NULL)
  11375. {
  11376. name = mResultLocalVar->mName;
  11377. }
  11378. else if (mPropDef != NULL)
  11379. {
  11380. name = mPropDef->mName;
  11381. }
  11382. }
  11383. if ((name.IsEmpty()) && (nameOfExpr->mTarget != NULL))
  11384. mModule->Fail("Expression does not have a name", nameOfExpr->mTarget);
  11385. mResult = BfTypedValue(mModule->GetStringObjectValue(name), mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
  11386. }
  11387. void BfExprEvaluator::Visit(BfIsConstExpression* isConstExpr)
  11388. {
  11389. if (isConstExpr->mExpression == NULL)
  11390. {
  11391. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 0), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  11392. return;
  11393. }
  11394. BfMethodState methodState;
  11395. SetAndRestoreValue<BfMethodState*> prevMethodState(mModule->mCurMethodState, &methodState, false);
  11396. if (mModule->mCurMethodState == NULL)
  11397. prevMethodState.Set();
  11398. methodState.mTempKind = BfMethodState::TempKind_NonStatic;
  11399. SetAndRestoreValue<bool> ignoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
  11400. SetAndRestoreValue<bool> allowUninitReads(mModule->mCurMethodState->mAllowUinitReads, true);
  11401. BfEvalExprFlags exprFlags = BfEvalExprFlags_None;
  11402. auto result = mModule->CreateValueFromExpression(isConstExpr->mExpression, NULL, BfEvalExprFlags_DeclType);
  11403. bool isConst = mModule->mBfIRBuilder->IsConstValue(result.mValue);
  11404. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, isConst ? 1 : 0), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  11405. }
  11406. void BfExprEvaluator::Visit(BfDefaultExpression* defaultExpr)
  11407. {
  11408. auto autoComplete = GetAutoComplete();
  11409. if (autoComplete != NULL)
  11410. autoComplete->CheckTypeRef(defaultExpr->mTypeRef, false, true);
  11411. BfType* type = NULL;
  11412. if (defaultExpr->mOpenParen == NULL)
  11413. {
  11414. if (mExpectingType)
  11415. {
  11416. type = mExpectingType;
  11417. }
  11418. else
  11419. {
  11420. mModule->Fail("Type cannot be inferred, consider adding explicit type name", defaultExpr);
  11421. return;
  11422. }
  11423. }
  11424. else
  11425. type = mModule->ResolveTypeRef(defaultExpr->mTypeRef);
  11426. if (type == NULL)
  11427. return;
  11428. BfDefaultValueKind defaultKind = BfDefaultValueKind_Const;
  11429. if (type->IsRef())
  11430. {
  11431. mModule->Fail(StrFormat("There is no default value for type '%s'", mModule->TypeToString(type).c_str()), defaultExpr);
  11432. defaultKind = BfDefaultValueKind_Addr;
  11433. }
  11434. mModule->ValidateAllocation(type, defaultExpr->mTypeRef);
  11435. mModule->AddDependency(type, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
  11436. mResult = mModule->GetDefaultTypedValue(type, true, defaultKind);
  11437. }
  11438. void BfExprEvaluator::Visit(BfUninitializedExpression* uninitialziedExpr)
  11439. {
  11440. mModule->Fail("Invalid use of the '?' uninitialized specifier", uninitialziedExpr);
  11441. }
  11442. void BfExprEvaluator::Visit(BfCheckTypeExpression* checkTypeExpr)
  11443. {
  11444. auto targetValue = mModule->CreateValueFromExpression(checkTypeExpr->mTarget, NULL, (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags));
  11445. if (!targetValue)
  11446. return;
  11447. if (checkTypeExpr->mTypeRef == NULL)
  11448. {
  11449. mModule->AssertErrorState();
  11450. return;
  11451. }
  11452. auto autoComplete = GetAutoComplete();
  11453. if (autoComplete != NULL)
  11454. autoComplete->CheckTypeRef(checkTypeExpr->mTypeRef, false, true);
  11455. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  11456. if (checkTypeExpr->mTypeRef->IsA<BfVarTypeReference>())
  11457. {
  11458. bool isVar = false;
  11459. if ((targetValue.mType != NULL) && (targetValue.mType->IsVar()))
  11460. {
  11461. auto irb = mModule->mBfIRBuilder;
  11462. BfIRValue boolResult = mModule->CreateAlloca(boolType);
  11463. irb->CreateAlignedStore(irb->CreateConst(BfTypeCode_Boolean, 1), boolResult, 1);
  11464. mResult = BfTypedValue(irb->CreateAlignedLoad(boolResult, 1), boolType);
  11465. }
  11466. else
  11467. mResult = BfTypedValue(mModule->GetConstValue(0, boolType), boolType);
  11468. return;
  11469. }
  11470. auto targetType = mModule->ResolveTypeRef(checkTypeExpr->mTypeRef, BfPopulateType_Declaration);
  11471. if (!targetType)
  11472. {
  11473. mModule->AssertErrorState();
  11474. return;
  11475. }
  11476. mModule->AddDependency(targetType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
  11477. if (targetValue.mType->IsVar())
  11478. {
  11479. mResult = mModule->GetDefaultTypedValue(boolType, false, BfDefaultValueKind_Undef);
  11480. return;
  11481. }
  11482. if (targetValue.mType->IsValueTypeOrValueTypePtr())
  11483. {
  11484. auto typeInstance = targetValue.mType->ToTypeInstance();
  11485. if (targetValue.mType->IsWrappableType())
  11486. typeInstance = mModule->GetWrappedStructType(targetValue.mType);
  11487. bool matches = (targetValue.mType == targetType) || (mModule->mContext->mBfObjectType == targetType);
  11488. if (!matches)
  11489. matches = mModule->TypeIsSubTypeOf(typeInstance, targetType->ToTypeInstance());
  11490. if (!typeInstance->IsGenericParam())
  11491. {
  11492. if (matches)
  11493. mModule->Warn(0, "The result of this operation is always 'true'", checkTypeExpr->mIsToken);
  11494. else
  11495. mModule->Warn(0, "The result of this operation is always 'false'", checkTypeExpr->mIsToken);
  11496. }
  11497. mResult = BfTypedValue(mModule->GetConstValue(matches ? 1 : 0, boolType), boolType);
  11498. return;
  11499. }
  11500. if (targetType->IsValueType())
  11501. {
  11502. if ((targetValue.mType != mModule->mContext->mBfObjectType) && (!targetValue.mType->IsInterface()))
  11503. {
  11504. mResult = BfTypedValue(mModule->GetConstValue(0, boolType), boolType);
  11505. return;
  11506. }
  11507. }
  11508. int wantTypeId = 0;
  11509. if (!targetType->IsGenericParam())
  11510. wantTypeId = targetType->mTypeId;
  11511. auto objectType = mModule->mContext->mBfObjectType;
  11512. mModule->PopulateType(objectType, BfPopulateType_Full);
  11513. targetValue = mModule->LoadValue(targetValue);
  11514. BfTypeInstance* srcTypeInstance = targetValue.mType->ToTypeInstance();
  11515. BfTypeInstance* targetTypeInstance = targetType->ToTypeInstance();
  11516. bool wasGenericParamType = false;
  11517. if ((srcTypeInstance != NULL) && (targetTypeInstance != NULL))
  11518. {
  11519. if (mModule->TypeIsSubTypeOf(srcTypeInstance, targetTypeInstance))
  11520. {
  11521. // We don't give this warning when we have wasGenericParmType set because that indicates we had a generic type constraint,
  11522. // and a type constraint infers that the ACTUAL type used will be equal to or derived from that type and therefore
  11523. // it may be a "necessary cast" indeed
  11524. if ((!wasGenericParamType) && (mModule->mCurMethodState->mMixinState == NULL))
  11525. {
  11526. if (srcTypeInstance == targetType)
  11527. mModule->Warn(BfWarning_BF4203_UnnecessaryDynamicCast, StrFormat("Unnecessary check, the value is already type '%s'",
  11528. mModule->TypeToString(srcTypeInstance).c_str()), checkTypeExpr->mIsToken);
  11529. else
  11530. mModule->Warn(BfWarning_BF4203_UnnecessaryDynamicCast, StrFormat("Unnecessary check, '%s' is a subtype of '%s'",
  11531. mModule->TypeToString(srcTypeInstance).c_str(), mModule->TypeToString(targetType).c_str()), checkTypeExpr->mIsToken);
  11532. }
  11533. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 1), boolType);
  11534. return;
  11535. }
  11536. else if ((!targetType->IsInterface()) && (srcTypeInstance != mModule->mContext->mBfObjectType) && (!mModule->TypeIsSubTypeOf(targetTypeInstance, srcTypeInstance)))
  11537. {
  11538. mModule->Fail(StrFormat("Cannot convert type '%s' to '%s' via any conversion",
  11539. mModule->TypeToString(targetValue.mType).c_str(), mModule->TypeToString(targetTypeInstance).c_str()), checkTypeExpr->mIsToken);
  11540. }
  11541. }
  11542. if (mModule->mCompiler->IsAutocomplete())
  11543. {
  11544. mResult = mModule->GetDefaultTypedValue(boolType, false, BfDefaultValueKind_Addr);
  11545. return;
  11546. }
  11547. auto irb = mModule->mBfIRBuilder;
  11548. auto prevBB = mModule->mBfIRBuilder->GetInsertBlock();
  11549. auto matchBB = mModule->mBfIRBuilder->CreateBlock("is.match");
  11550. auto endBB = mModule->mBfIRBuilder->CreateBlock("is.done");
  11551. BfIRValue boolResult = mModule->CreateAlloca(boolType);
  11552. irb->CreateAlignedStore(irb->CreateConst(BfTypeCode_Boolean, 0), boolResult, 1);
  11553. mModule->EmitDynamicCastCheck(targetValue, targetType, matchBB, endBB);
  11554. mModule->AddBasicBlock(matchBB);
  11555. irb->CreateAlignedStore(irb->CreateConst(BfTypeCode_Boolean, 1), boolResult, 1);
  11556. irb->CreateBr(endBB);
  11557. mModule->AddBasicBlock(endBB);
  11558. mResult = BfTypedValue(irb->CreateAlignedLoad(boolResult, 1), boolType);
  11559. }
  11560. void BfExprEvaluator::Visit(BfDynamicCastExpression* dynCastExpr)
  11561. {
  11562. auto targetValue = mModule->CreateValueFromExpression(dynCastExpr->mTarget);
  11563. auto targetType = mModule->ResolveTypeRefAllowUnboundGenerics(dynCastExpr->mTypeRef, BfPopulateType_Data, BfResolveTypeRefFlag_None, false);
  11564. auto autoComplete = GetAutoComplete();
  11565. if (autoComplete != NULL)
  11566. {
  11567. autoComplete->CheckTypeRef(dynCastExpr->mTypeRef, false, true);
  11568. }
  11569. auto origTargetType = targetType;
  11570. if (!targetValue)
  11571. return;
  11572. if (!targetType)
  11573. {
  11574. mModule->AssertErrorState();
  11575. return;
  11576. }
  11577. bool wasGenericParamType = false;
  11578. if (targetType->IsGenericParam())
  11579. {
  11580. //targetType = mModule->ResolveGenericType(targetType);
  11581. //wasGenericParamType = true;
  11582. }
  11583. if ((targetValue.mType->IsMethodRef()) || (targetType->IsMethodRef()))
  11584. {
  11585. // We can never cast a MethodRef to any class type
  11586. mResult = mModule->GetDefaultTypedValue(targetType);
  11587. return;
  11588. }
  11589. if (mModule->mContext->mResolvingVarField)
  11590. {
  11591. mResult = mModule->GetDefaultTypedValue(targetType);
  11592. return;
  11593. }
  11594. mModule->AddDependency(targetType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
  11595. if (targetType->IsGenericParam())
  11596. {
  11597. wasGenericParamType = true;
  11598. BfGenericParamInstance* origGenericParam = NULL;
  11599. int pass = 0;
  11600. while ((targetType != NULL) && (targetType->IsGenericParam()))
  11601. {
  11602. auto genericParamType = (BfGenericParamType*)targetType;
  11603. auto genericParam = mModule->GetGenericParamInstance(genericParamType);
  11604. if (pass == 0)
  11605. origGenericParam = genericParam;
  11606. auto typeConstraint = genericParam->mTypeConstraint;
  11607. if ((typeConstraint == NULL) && (genericParam->mGenericParamFlags & (BfGenericParamFlag_Class | BfGenericParamFlag_Interface)))
  11608. typeConstraint = mModule->mContext->mBfObjectType;
  11609. targetType = typeConstraint;
  11610. if (++pass >= 100) // Sanity - but we should have caught circular error before
  11611. break;
  11612. }
  11613. if ((targetType == NULL) || (!targetType->IsObjectOrInterface()))
  11614. {
  11615. 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",
  11616. origGenericParam->GetGenericParamDef()->mName.c_str()), dynCastExpr->mTypeRef);
  11617. return;
  11618. }
  11619. }
  11620. if (targetType->IsVar())
  11621. {
  11622. mResult = mModule->GetDefaultTypedValue(targetType);
  11623. return;
  11624. }
  11625. if ((!targetType->IsObjectOrInterface()) && (!targetType->IsNullable()))
  11626. {
  11627. mModule->Fail(StrFormat("The as operator must be used with a reference type or nullable type ('%s' is a non-nullable value type)",
  11628. mModule->TypeToString(origTargetType).c_str()), dynCastExpr->mTypeRef);
  11629. return;
  11630. }
  11631. if (targetValue.mType->IsGenericParam())
  11632. {
  11633. auto genericParamType = (BfGenericParamType*)targetValue.mType;
  11634. auto genericParam = mModule->GetGenericParamInstance(genericParamType);
  11635. auto typeConstraint = genericParam->mTypeConstraint;
  11636. if (typeConstraint == NULL)
  11637. typeConstraint = mModule->mContext->mBfObjectType;
  11638. if ((typeConstraint->IsDelegate()) && (typeConstraint == targetType))
  11639. {
  11640. // Delegate constraints may be matched by valueless method references, so this won't always match (don't warn)
  11641. mResult = mModule->GetDefaultTypedValue(targetType);
  11642. return;
  11643. }
  11644. targetValue = mModule->GetDefaultTypedValue(typeConstraint);
  11645. }
  11646. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  11647. auto _CheckResult = [&]()
  11648. {
  11649. if ((mResult) && (origTargetType->IsGenericParam()))
  11650. mResult = mModule->GetDefaultTypedValue(origTargetType, false, BfDefaultValueKind_Undef);
  11651. };
  11652. if ((targetValue.mType->IsNullable()) && (targetType->IsInterface()))
  11653. {
  11654. mResult = mModule->Cast(dynCastExpr, targetValue, targetType, BfCastFlags_SilentFail);
  11655. if (!mResult)
  11656. {
  11657. mModule->Warn(0, StrFormat("Conversion from '%s' to '%s' will always be null",
  11658. mModule->TypeToString(targetValue.mType).c_str(), mModule->TypeToString(origTargetType).c_str()), dynCastExpr->mAsToken);
  11659. mResult = BfTypedValue(mModule->GetDefaultValue(origTargetType), origTargetType);
  11660. }
  11661. _CheckResult();
  11662. return;
  11663. }
  11664. if (targetValue.mType->IsVar())
  11665. {
  11666. mResult = mModule->GetDefaultTypedValue(targetType, false, BfDefaultValueKind_Undef);
  11667. return;
  11668. }
  11669. if (targetValue.mType->IsValueTypeOrValueTypePtr())
  11670. {
  11671. mModule->Warn(0, StrFormat("Type '%s' is not applicable for dynamic casting",
  11672. mModule->TypeToString(targetValue.mType).c_str()), dynCastExpr->mAsToken);
  11673. auto typeInstance = targetValue.mType->ToTypeInstance();
  11674. if (targetValue.mType->IsWrappableType())
  11675. typeInstance = mModule->GetWrappedStructType(targetValue.mType);
  11676. bool matches = (targetValue.mType == targetType) || (mModule->mContext->mBfObjectType == targetType);
  11677. if (targetType->IsNullable())
  11678. {
  11679. auto elementType = targetType->GetUnderlyingType();
  11680. if (elementType == targetValue.mType)
  11681. {
  11682. mModule->mBfIRBuilder->PopulateType(targetType);
  11683. // We match nullable element
  11684. auto allocaInst = mModule->CreateAlloca(targetType);
  11685. auto hasValueAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, 2); // has_value
  11686. mModule->mBfIRBuilder->CreateStore(mModule->GetConstValue(1, boolType), hasValueAddr);
  11687. hasValueAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, 1); // value
  11688. mModule->mBfIRBuilder->CreateStore(targetValue.mValue, hasValueAddr);
  11689. mResult = BfTypedValue(allocaInst, targetType, true);
  11690. _CheckResult();
  11691. return;
  11692. }
  11693. }
  11694. if (!matches)
  11695. matches = mModule->TypeIsSubTypeOf(typeInstance, targetType->ToTypeInstance());
  11696. if (matches)
  11697. mResult = mModule->Cast(dynCastExpr, targetValue, targetType, BfCastFlags_Explicit);
  11698. else if (targetType->IsNullable())
  11699. {
  11700. auto allocaInst = mModule->CreateAlloca(targetType);
  11701. auto allocaBits = mModule->mBfIRBuilder->CreateBitCast(allocaInst, mModule->mBfIRBuilder->GetPrimitiveType(BfTypeCode_NullPtr));
  11702. mModule->mBfIRBuilder->CreateMemSet(allocaBits, mModule->GetConstValue(0, mModule->GetPrimitiveType(BfTypeCode_Int8)),
  11703. mModule->GetConstValue(targetType->mSize), targetType->mAlign);
  11704. mResult = BfTypedValue(allocaInst, targetType, true);
  11705. }
  11706. else
  11707. mResult = BfTypedValue(mModule->GetDefaultValue(targetType), targetType);
  11708. _CheckResult();
  11709. return;
  11710. }
  11711. if (targetType->IsNullable())
  11712. {
  11713. if (autoComplete != NULL)
  11714. {
  11715. mResult = mModule->GetDefaultTypedValue(targetType);
  11716. return;
  11717. }
  11718. auto elementType = targetType->GetUnderlyingType();
  11719. auto allocaInst = mModule->CreateAlloca(targetType);
  11720. auto hasValueAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, elementType->IsValuelessType() ? 1 : 2); // has_value
  11721. mModule->mBfIRBuilder->CreateStore(mModule->GetConstValue(0, boolType), hasValueAddr);
  11722. auto objectType = mModule->mContext->mBfObjectType;
  11723. auto prevBB = mModule->mBfIRBuilder->GetInsertBlock();
  11724. auto matchBB = mModule->mBfIRBuilder->CreateBlock("as.match");
  11725. auto endBB = mModule->mBfIRBuilder->CreateBlock("as.end");
  11726. mModule->EmitDynamicCastCheck(targetValue, elementType, matchBB, endBB);
  11727. BfBoxedType* boxedType = mModule->CreateBoxedType(elementType);
  11728. mModule->AddBasicBlock(matchBB);
  11729. if (elementType->IsValuelessType())
  11730. {
  11731. auto hasValueAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, 1); // has_value
  11732. mModule->mBfIRBuilder->CreateStore(mModule->GetConstValue(1, boolType), hasValueAddr);
  11733. }
  11734. else
  11735. {
  11736. auto hasValueAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, 2); // has_value
  11737. mModule->mBfIRBuilder->CreateStore(mModule->GetConstValue(1, boolType), hasValueAddr);
  11738. auto nullableValueAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, 1); // value
  11739. auto srcBoxedType = mModule->mBfIRBuilder->CreateBitCast(targetValue.mValue, mModule->mBfIRBuilder->MapType(boxedType, BfIRPopulateType_Full));
  11740. auto boxedValueAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(srcBoxedType, 0, 1); // mValue
  11741. auto boxedValue = mModule->mBfIRBuilder->CreateLoad(boxedValueAddr);
  11742. mModule->mBfIRBuilder->CreateStore(boxedValue, nullableValueAddr);
  11743. }
  11744. mModule->mBfIRBuilder->CreateBr(endBB);
  11745. mModule->AddBasicBlock(endBB);
  11746. mResult = BfTypedValue(allocaInst, targetType, true);
  11747. _CheckResult();
  11748. return;
  11749. }
  11750. targetValue = mModule->LoadValue(targetValue);
  11751. if (targetType->IsValueType())
  11752. {
  11753. mModule->Fail("Invalid dynamic cast type", dynCastExpr->mTypeRef);
  11754. return;
  11755. }
  11756. BfTypeInstance* srcTypeInstance = targetValue.mType->ToTypeInstance();
  11757. BfTypeInstance* targetTypeInstance = targetType->ToTypeInstance();
  11758. if (mModule->TypeIsSubTypeOf(srcTypeInstance, targetTypeInstance))
  11759. {
  11760. // We don't give this warning when we have wasGenericParmType set because that indicates we had a generic type constraint,
  11761. // and a type constraint infers that the ACTUAL type used will be equal to or derived from that type and therefore
  11762. // it may be a "necessary cast" indeed
  11763. if ((!wasGenericParamType) && (mModule->mCurMethodState->mMixinState == NULL))
  11764. {
  11765. if (srcTypeInstance == targetType)
  11766. mModule->Warn(BfWarning_BF4203_UnnecessaryDynamicCast, StrFormat("Unnecessary cast, the value is already type '%s'",
  11767. mModule->TypeToString(srcTypeInstance).c_str()), dynCastExpr->mAsToken);
  11768. else
  11769. mModule->Warn(BfWarning_BF4203_UnnecessaryDynamicCast, StrFormat("Unnecessary cast, '%s' is a subtype of '%s'",
  11770. mModule->TypeToString(srcTypeInstance).c_str(), mModule->TypeToString(targetType).c_str()), dynCastExpr->mAsToken);
  11771. }
  11772. auto castedValue = mModule->mBfIRBuilder->CreateBitCast(targetValue.mValue, mModule->mBfIRBuilder->MapType(targetTypeInstance));
  11773. mResult = BfTypedValue(castedValue, targetTypeInstance);
  11774. _CheckResult();
  11775. return;
  11776. }
  11777. else if ((!targetType->IsInterface()) && (!mModule->TypeIsSubTypeOf(targetTypeInstance, srcTypeInstance)))
  11778. {
  11779. if (!mModule->IsInSpecializedSection())
  11780. {
  11781. mModule->Fail(StrFormat("Cannot convert type '%s' to '%s' via any conversion",
  11782. mModule->TypeToString(targetValue.mType).c_str(), mModule->TypeToString(targetTypeInstance).c_str()), dynCastExpr->mAsToken);
  11783. }
  11784. mResult = mModule->GetDefaultTypedValue(targetType);
  11785. return;
  11786. }
  11787. if (autoComplete != NULL)
  11788. {
  11789. mResult = mModule->GetDefaultTypedValue(targetType, false, BfDefaultValueKind_Addr);
  11790. _CheckResult();
  11791. return;
  11792. }
  11793. auto irb = mModule->mBfIRBuilder;
  11794. auto objectType = mModule->mContext->mBfObjectType;
  11795. mModule->PopulateType(objectType, BfPopulateType_Full);
  11796. auto prevBB = mModule->mBfIRBuilder->GetInsertBlock();
  11797. auto endBB = mModule->mBfIRBuilder->CreateBlock("as.end");
  11798. auto matchBlock = irb->CreateBlock("as.match");
  11799. BfIRValue targetVal = mModule->CreateAlloca(targetType);
  11800. irb->CreateAlignedStore(irb->CreateConstNull(irb->MapType(targetType)), targetVal, targetType->mAlign);
  11801. mModule->EmitDynamicCastCheck(targetValue, targetType, matchBlock, endBB);
  11802. mModule->AddBasicBlock(matchBlock);
  11803. BfIRValue castedCallResult = mModule->mBfIRBuilder->CreateBitCast(targetValue.mValue, mModule->mBfIRBuilder->MapType(targetType));
  11804. irb->CreateAlignedStore(castedCallResult, targetVal, targetValue.mType->mAlign);
  11805. irb->CreateBr(endBB);
  11806. mModule->AddBasicBlock(endBB);
  11807. mResult = BfTypedValue(irb->CreateAlignedLoad(targetVal, targetType->mAlign), targetType);
  11808. _CheckResult();
  11809. }
  11810. void BfExprEvaluator::Visit(BfCastExpression* castExpr)
  11811. {
  11812. auto autoComplete = GetAutoComplete();
  11813. if ((autoComplete != NULL) && (castExpr->mTypeRef != NULL))
  11814. {
  11815. // 'mayBeIdentifier' because this may be a misidentified cast - it could be a parenthesized expression
  11816. autoComplete->CheckTypeRef(castExpr->mTypeRef, true, true);
  11817. }
  11818. BfType* resolvedType = NULL;
  11819. if ((BfNodeDynCastExact<BfDotTypeReference>(castExpr->mTypeRef) != NULL) && (mExpectingType != NULL))
  11820. {
  11821. //mModule->SetElementType(castExpr->mTypeRef, BfSourceElementType_TypeRef);
  11822. resolvedType = mExpectingType;
  11823. }
  11824. else
  11825. resolvedType = ResolveTypeRef(castExpr->mTypeRef);
  11826. if (resolvedType != NULL)
  11827. mModule->AddDependency(resolvedType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage);
  11828. // If resolvedType is NULL then that's okay- we just leave the following expression uncasted
  11829. if (castExpr->mExpression == NULL)
  11830. {
  11831. mModule->AssertErrorState();
  11832. return;
  11833. }
  11834. auto exprFlags = (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_NoAutoComplete) | BfEvalExprFlags_ExplicitCast);
  11835. mResult = mModule->CreateValueFromExpression(castExpr->mExpression, resolvedType, exprFlags);
  11836. }
  11837. bool BfExprEvaluator::IsExactMethodMatch(BfMethodInstance* methodA, BfMethodInstance* methodB, bool ignoreImplicitParams)
  11838. {
  11839. if (methodA->mReturnType != methodB->mReturnType)
  11840. return false;
  11841. int implicitParamCountA = methodA->GetImplicitParamCount();
  11842. if (methodA->HasExplicitThis())
  11843. implicitParamCountA++;
  11844. int implicitParamCountB = methodB->GetImplicitParamCount();
  11845. if (methodB->HasExplicitThis())
  11846. implicitParamCountB++;
  11847. if (methodA->GetParamCount() - implicitParamCountA != methodB->GetParamCount() - implicitParamCountB)
  11848. return false;
  11849. for (int i = 0; i < (int)methodA->GetParamCount() - implicitParamCountA; i++)
  11850. {
  11851. auto paramA = methodA->GetParamType(i + implicitParamCountA);
  11852. auto paramB = methodB->GetParamType(i + implicitParamCountB);
  11853. if (paramA != paramB)
  11854. return false;
  11855. }
  11856. return true;
  11857. }
  11858. void BfExprEvaluator::ConstResolve(BfExpression* expr)
  11859. {
  11860. BfConstResolver constResolver(mModule);
  11861. constResolver.Resolve(expr);
  11862. mResult = constResolver.mResult;
  11863. }
  11864. BfTypeInstance* BfExprEvaluator::VerifyBaseDelegateType(BfTypeInstance* baseDelegateType)
  11865. {
  11866. mModule->PopulateType(baseDelegateType, BfPopulateType_DataAndMethods);
  11867. if (baseDelegateType->mFieldInstances.size() != 2)
  11868. {
  11869. mModule->AssertErrorState();
  11870. return NULL;
  11871. }
  11872. return baseDelegateType;
  11873. }
  11874. bool BfExprEvaluator::CanBindDelegate(BfDelegateBindExpression* delegateBindExpr, BfMethodInstance** boundMethod, BfType* origMethodExpectingType, BfTypeVector* methodGenericArgumentsSubstitute)
  11875. {
  11876. if ((mExpectingType == NULL) && (origMethodExpectingType == NULL))
  11877. {
  11878. return false;
  11879. }
  11880. bool isGenericMatch = mExpectingType == NULL;
  11881. auto expectingType = mExpectingType;
  11882. if (expectingType == NULL)
  11883. expectingType = origMethodExpectingType;
  11884. auto typeInstance = expectingType->ToTypeInstance();
  11885. if ((typeInstance == NULL) ||
  11886. ((!typeInstance->mTypeDef->mIsDelegate) && (!typeInstance->mTypeDef->mIsFunction)))
  11887. return false;
  11888. mModule->PopulateType(typeInstance, BfPopulateType_DataAndMethods);
  11889. auto methodInstance = mModule->GetRawMethodInstanceAtIdx(typeInstance, 0, "Invoke");
  11890. if (methodInstance == NULL)
  11891. {
  11892. BF_DBG_FATAL("Invoke not found");
  11893. return false;
  11894. }
  11895. if (delegateBindExpr->mTarget == NULL)
  11896. return false;
  11897. BfAutoParentNodeEntry autoParentNodeEntry(mModule, delegateBindExpr);
  11898. SizedArray<BfTypedValueExpression, 4> typedValueExprs;
  11899. typedValueExprs.resize(methodInstance->GetParamCount());
  11900. SizedArray<BfExpression*, 4> args;
  11901. args.resize(methodInstance->GetParamCount());
  11902. auto _FixType = [&](BfType* type)
  11903. {
  11904. if (!isGenericMatch)
  11905. return type;
  11906. auto fixedType = mModule->ResolveGenericType(type, NULL, methodGenericArgumentsSubstitute, mModule->mCurTypeInstance);
  11907. if (fixedType != NULL)
  11908. return fixedType;
  11909. return (BfType*)mModule->GetPrimitiveType(BfTypeCode_Var);
  11910. };
  11911. auto _TypeMatches = [&](BfType* lhs, BfType* rhs)
  11912. {
  11913. if (lhs == rhs)
  11914. return true;
  11915. return lhs->IsVar();
  11916. };
  11917. for (int i = 0; i < (int) methodInstance->GetParamCount(); i++)
  11918. {
  11919. auto typedValueExpr = &typedValueExprs[i];
  11920. typedValueExpr->mTypedValue.mValue = BfIRValue(BfIRValueFlags_Value, -1);
  11921. typedValueExpr->mTypedValue.mType = _FixType(methodInstance->GetParamType(i));
  11922. typedValueExpr->mRefNode = NULL;
  11923. args[i] = typedValueExpr;
  11924. }
  11925. BfMethodGenericArguments methodGenericArgs;
  11926. if (delegateBindExpr->mGenericArgs != NULL)
  11927. methodGenericArgs.mArguments = &delegateBindExpr->mGenericArgs->mGenericArgs;
  11928. BfFunctionBindResult bindResult;
  11929. bindResult.mSkipMutCheck = true; // Allow operating on copies
  11930. bindResult.mBindType = expectingType;
  11931. mFunctionBindResult = &bindResult;
  11932. SetAndRestoreValue<bool> ignoreError(mModule->mIgnoreErrors, true);
  11933. DoInvocation(delegateBindExpr->mTarget, delegateBindExpr, args, methodGenericArgs);
  11934. mFunctionBindResult = NULL;
  11935. if (bindResult.mMethodInstance == NULL)
  11936. return false;
  11937. if (boundMethod != NULL)
  11938. *boundMethod = bindResult.mMethodInstance;
  11939. auto matchedMethod = bindResult.mMethodInstance;
  11940. if (!_TypeMatches(_FixType(methodInstance->mReturnType), matchedMethod->mReturnType))
  11941. return false;
  11942. int implicitParamCountA = methodInstance->GetImplicitParamCount();
  11943. int implicitParamCountB = matchedMethod->GetImplicitParamCount();
  11944. if (methodInstance->GetParamCount() - implicitParamCountA != matchedMethod->GetParamCount() - implicitParamCountB)
  11945. return false;
  11946. for (int i = 0; i < (int)methodInstance->GetParamCount() - implicitParamCountA; i++)
  11947. {
  11948. auto paramA = _FixType(methodInstance->GetParamType(i + implicitParamCountA));
  11949. auto paramB = _FixType(matchedMethod->GetParamType(i + implicitParamCountB));
  11950. if (!_TypeMatches(paramA, paramB))
  11951. return false;
  11952. }
  11953. return true;
  11954. }
  11955. BfTypedValue BfExprEvaluator::DoImplicitArgCapture(BfAstNode* refNode, BfIdentifierNode* identifierNode, int shadowIdx)
  11956. {
  11957. String findName = identifierNode->ToString();
  11958. if (mModule->mCurMethodState != NULL)
  11959. {
  11960. auto rootMethodState = mModule->mCurMethodState->GetRootMethodState();
  11961. auto checkMethodState = mModule->mCurMethodState;
  11962. bool isMixinOuterVariablePass = false;
  11963. int shadowSkip = shadowIdx;
  11964. while (checkMethodState != NULL)
  11965. {
  11966. BP_ZONE("LookupIdentifier:DoImplicitArgCapture");
  11967. BfTypeInstance* closureTypeInst = NULL;
  11968. BfClosureInstanceInfo* closureInstanceInfo = NULL;
  11969. if ((checkMethodState->mClosureState != NULL) && (checkMethodState->mClosureState->mClosureType != NULL) && (!checkMethodState->mClosureState->mCapturing))
  11970. {
  11971. closureTypeInst = mModule->mCurMethodState->mClosureState->mClosureType;
  11972. }
  11973. BfLocalVarEntry* entry;
  11974. if (checkMethodState->mLocalVarSet.TryGetWith<StringImpl&>(findName, &entry))
  11975. {
  11976. auto varDecl = entry->mLocalVar;
  11977. while (varDecl != NULL)
  11978. {
  11979. if (varDecl->mNameNode == identifierNode)
  11980. {
  11981. if (shadowSkip > 0)
  11982. {
  11983. shadowSkip--;
  11984. }
  11985. else
  11986. {
  11987. BfTypedValue localResult = LoadLocal(varDecl);
  11988. if (!isMixinOuterVariablePass)
  11989. {
  11990. mResultLocalVar = varDecl;
  11991. mResultFieldInstance = NULL;
  11992. mResultLocalVarRefNode = identifierNode;
  11993. }
  11994. return localResult;
  11995. }
  11996. }
  11997. varDecl = varDecl->mShadowedLocal;
  11998. }
  11999. }
  12000. // Check for the captured locals. It's important we do it here so we get local-first precedence still
  12001. if (closureTypeInst != NULL)
  12002. {
  12003. closureTypeInst->mTypeDef->PopulateMemberSets();
  12004. BfMemberSetEntry* memberSetEntry = NULL;
  12005. if (closureTypeInst->mTypeDef->mFieldSet.TryGetWith(findName, &memberSetEntry))
  12006. {
  12007. auto fieldDef = (BfFieldDef*)memberSetEntry->mMemberDef;
  12008. while (fieldDef != NULL)
  12009. {
  12010. BfIdentifierNode* fieldNameNode = NULL;
  12011. if (fieldDef->mIdx < (int)checkMethodState->mClosureState->mClosureInstanceInfo->mCaptureEntries.size())
  12012. fieldNameNode = checkMethodState->mClosureState->mClosureInstanceInfo->mCaptureEntries[fieldDef->mIdx].mNameNode;
  12013. if (fieldNameNode == identifierNode)
  12014. {
  12015. auto& field = closureTypeInst->mFieldInstances[fieldDef->mIdx];
  12016. if (!field.mResolvedType->IsValuelessType())
  12017. {
  12018. if (mModule->mCurMethodState->mClosureState->mCapturing)
  12019. {
  12020. mModule->mCurMethodState->mClosureState->mReferencedOuterClosureMembers.Add(&field);
  12021. return mModule->GetDefaultTypedValue(field.mResolvedType);
  12022. }
  12023. auto localVar = mModule->mCurMethodState->mLocals[0];
  12024. auto thisValue = localVar->mValue;
  12025. mModule->mBfIRBuilder->PopulateType(localVar->mResolvedType);
  12026. BfTypedValue result = BfTypedValue(mModule->mBfIRBuilder->CreateInBoundsGEP(thisValue, 0, field.mDataIdx), field.mResolvedType, true);
  12027. if (field.mResolvedType->IsRef())
  12028. {
  12029. auto refType = (BfRefType*)field.mResolvedType;
  12030. auto underlyingType = refType->GetUnderlyingType();
  12031. result = BfTypedValue(mModule->mBfIRBuilder->CreateAlignedLoad(result.mValue, underlyingType->mAlign), underlyingType, true);
  12032. }
  12033. else if (fieldDef->mIsReadOnly)
  12034. result = mModule->LoadValue(result);
  12035. mResultLocalVar = localVar;
  12036. mResultFieldInstance = &field;
  12037. mResultLocalVarField = -(field.mMergedDataIdx + 1);
  12038. return result;
  12039. }
  12040. }
  12041. fieldDef = fieldDef->mNextWithSameName;
  12042. }
  12043. }
  12044. }
  12045. if ((checkMethodState->mClosureState != NULL) && (checkMethodState->mClosureState->mCapturing) /*&& (checkMethodState->mClosureState->mIsLocalMethod)*/)
  12046. {
  12047. checkMethodState = checkMethodState->mPrevMethodState;
  12048. continue;
  12049. }
  12050. // Allow local mixin to see outside variables during its processing -- since we don't actually "capture" those into params
  12051. bool isLocalMixinProcessing = false;
  12052. if ((checkMethodState->mClosureState != NULL) && (!checkMethodState->mClosureState->mCapturing) && (closureTypeInst == NULL) &&
  12053. (mModule->mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_Mixin))
  12054. isLocalMixinProcessing = true;
  12055. if (!isLocalMixinProcessing)
  12056. break;
  12057. isMixinOuterVariablePass = true;
  12058. checkMethodState = checkMethodState->mPrevMethodState;
  12059. }
  12060. }
  12061. return BfTypedValue();
  12062. }
  12063. BfTypedValue BfExprEvaluator::DoImplicitArgCapture(BfAstNode* refNode, BfMethodInstance* methodInstance, int paramIdx, bool& failed, BfImplicitParamKind paramKind, const BfTypedValue& methodRefTarget)
  12064. {
  12065. if ((methodRefTarget) && (methodRefTarget.mValue.mId != BfIRValue::ID_IMPLICIT))
  12066. {
  12067. if (methodRefTarget.mType->IsMethodRef())
  12068. {
  12069. BfMethodRefType* methodRefType = (BfMethodRefType*)methodRefTarget.mType;
  12070. BfMethodInstance* methodRefMethodInst = methodRefType->mMethodRef;
  12071. BF_ASSERT(methodRefMethodInst == methodInstance);
  12072. auto paramType = methodInstance->GetParamType(paramIdx);
  12073. int dataIdx = methodRefType->GetDataIdxFromParamIdx(paramIdx);
  12074. if (dataIdx == -1)
  12075. {
  12076. BF_ASSERT(paramType->IsValuelessType());
  12077. return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), paramType);
  12078. }
  12079. if (methodRefTarget.IsSplat())
  12080. {
  12081. if (methodRefType->WantsDataPassedAsSplat(dataIdx))
  12082. {
  12083. BF_ASSERT(paramIdx == -1);
  12084. return BfTypedValue(methodRefTarget.mValue, paramType, BfTypedValueKind_SplatHead);
  12085. }
  12086. else
  12087. {
  12088. int splatIdx = dataIdx;
  12089. if (dataIdx > 0)
  12090. {
  12091. if (methodRefType->WantsDataPassedAsSplat(0))
  12092. splatIdx += methodRefType->GetCaptureType(0)->GetSplatCount() - 1;
  12093. }
  12094. bool isAddr = false;
  12095. BfIRValue value = mModule->ExtractSplatValue(methodRefTarget, splatIdx, paramType, &isAddr);
  12096. // We moved the composite load from ExtractSplatValue to here. Hopefully this is correct.
  12097. // 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)
  12098. // if ((paramType->IsComposite()) && (mModule->IsTargetingBeefBackend()))
  12099. // value = mModule->mBfIRBuilder->CreateLoad(value);
  12100. auto lookupVal = BfTypedValue(value, paramType, isAddr);
  12101. if ((isAddr) && (!lookupVal.mType->IsComposite()))
  12102. lookupVal = mModule->LoadValue(lookupVal);
  12103. return lookupVal;
  12104. }
  12105. }
  12106. if ((paramType->IsComposite()) && (methodRefTarget.IsAddr()))
  12107. return BfTypedValue(mModule->mBfIRBuilder->CreateInBoundsGEP(methodRefTarget.mValue, 0, dataIdx), paramType, true);
  12108. return BfTypedValue(mModule->ExtractValue(methodRefTarget, dataIdx), paramType);
  12109. }
  12110. }
  12111. // 'Default' implicit arg lookup, by identifier. May match field (for lambda), or local variable
  12112. if (paramKind == BfImplicitParamKind_General)
  12113. {
  12114. if (paramIdx == -1)
  12115. {
  12116. if (auto delegateBindExpr = BfNodeDynCast<BfDelegateBindExpression>(refNode))
  12117. {
  12118. BfAstNode* thisNode = NULL;
  12119. BfTypedValue thisValue;
  12120. if (auto memberReferenceExpr = BfNodeDynCast<BfMemberReferenceExpression>(delegateBindExpr->mTarget))
  12121. thisNode = memberReferenceExpr->mTarget;
  12122. else if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(delegateBindExpr->mTarget))
  12123. thisNode = qualifiedNameNode->mLeft;
  12124. else if (auto identifierNode = BfNodeDynCast<BfIdentifierNode>(delegateBindExpr->mTarget))
  12125. {
  12126. // Implicit
  12127. thisValue = mModule->GetThis();
  12128. }
  12129. if (auto thisExpr = BfNodeDynCast<BfExpression>(thisNode))
  12130. {
  12131. thisValue = mModule->CreateValueFromExpression(thisExpr);
  12132. if (!thisValue)
  12133. return BfTypedValue();
  12134. }
  12135. if (thisValue)
  12136. {
  12137. //TODO: handle 'mut', throw error if trying to capture from a non-mut, etc...
  12138. return thisValue;
  12139. }
  12140. }
  12141. }
  12142. String captureName = methodInstance->GetParamName(paramIdx);
  12143. BfIdentifierNode* identifierNode = methodInstance->GetParamNameNode(paramIdx);
  12144. BfTypedValue lookupVal;
  12145. if (identifierNode != NULL)
  12146. {
  12147. lookupVal = DoImplicitArgCapture(refNode, identifierNode, 0);
  12148. }
  12149. else
  12150. {
  12151. lookupVal = LookupIdentifier(NULL, captureName);
  12152. }
  12153. if (lookupVal)
  12154. {
  12155. auto paramType = methodInstance->GetParamType(paramIdx);
  12156. if (paramType->IsRef())
  12157. {
  12158. auto refType = (BfRefType*)paramType;
  12159. if (mResultLocalVar != NULL)
  12160. {
  12161. // When we are capturing, we need to note that we require capturing by reference here
  12162. auto localVar = mResultLocalVar;
  12163. localVar->mWrittenToId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++;
  12164. }
  12165. bool isValid = false;
  12166. if ((refType->mRefKind == BfRefType::RefKind_Mut) && (lookupVal.mKind == BfTypedValueKind_MutableValue))
  12167. isValid = true;
  12168. if ((lookupVal.mType->IsRef()) || (lookupVal.IsAddr()))
  12169. isValid = true;
  12170. if (!isValid)
  12171. {
  12172. // Is there another way this can fail than to be in a lambda?
  12173. auto error = mModule->Fail(StrFormat("Method '%s' requires that '%s' be captured by reference. Consider adding by-reference capture specifier [&] to lambda.",
  12174. mModule->MethodToString(methodInstance).c_str(), captureName.c_str()), refNode, true);
  12175. if ((error != NULL) && (methodInstance->mMethodDef->mMethodDeclaration != NULL))
  12176. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
  12177. failed = true;
  12178. }
  12179. }
  12180. else
  12181. {
  12182. if (lookupVal.mType->IsRef())
  12183. lookupVal = mModule->RemoveRef(lookupVal);
  12184. if (!lookupVal.mType->IsComposite())
  12185. lookupVal = mModule->LoadValue(lookupVal);
  12186. }
  12187. return lookupVal;
  12188. }
  12189. else
  12190. {
  12191. mModule->Fail(StrFormat("Failed to lookup implicit capture '%s'", captureName.c_str()), refNode, true);
  12192. failed = true;
  12193. return BfTypedValue();
  12194. }
  12195. }
  12196. return BfTypedValue();
  12197. }
  12198. void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
  12199. {
  12200. BfAutoParentNodeEntry autoParentNodeEntry(mModule, delegateBindExpr);
  12201. if (mExpectingType == NULL)
  12202. {
  12203. mModule->Fail("Cannot infer delegate type", delegateBindExpr);
  12204. return;
  12205. }
  12206. BfTokenNode* newToken = NULL;
  12207. BfAllocTarget allocTarget;
  12208. ResolveAllocTarget(allocTarget, delegateBindExpr->mNewToken, newToken);
  12209. SizedArray<BfTypedValueExpression, 4> typedValueExprs;
  12210. SizedArray<BfExpression*, 4> args;
  12211. BfTypeInstance* delegateTypeInstance = NULL;
  12212. BfMethodInstance* methodInstance = NULL;
  12213. const char* bindTypeName = NULL;
  12214. bool isMethodRefMatch = false;
  12215. if (mExpectingType->IsMethodRef())
  12216. {
  12217. auto methodRefType = (BfMethodRefType*)mExpectingType;
  12218. BF_ASSERT(delegateBindExpr->mNewToken == NULL);
  12219. methodInstance = methodRefType->mMethodRef;
  12220. isMethodRefMatch = true;
  12221. }
  12222. else
  12223. {
  12224. if (mExpectingType->IsGenericParam())
  12225. {
  12226. auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)mExpectingType);
  12227. if ((genericParamInstance->mTypeConstraint != NULL) && (genericParamInstance->mTypeConstraint->IsDelegate()))
  12228. {
  12229. delegateTypeInstance = genericParamInstance->mTypeConstraint->ToTypeInstance();
  12230. }
  12231. }
  12232. else
  12233. delegateTypeInstance = mExpectingType->ToTypeInstance();
  12234. if ((delegateTypeInstance == NULL) ||
  12235. ((!delegateTypeInstance->IsDelegate()) && (!delegateTypeInstance->IsFunction())))
  12236. {
  12237. mModule->Fail(StrFormat("Type '%s' cannot be used for method binding. Only delegate or function types are allowed.", mModule->TypeToString(mExpectingType).c_str()), delegateBindExpr);
  12238. return;
  12239. }
  12240. bindTypeName = (delegateTypeInstance->IsDelegate()) ? "delegate" : "function";
  12241. mModule->PopulateType(delegateTypeInstance, BfPopulateType_DataAndMethods);
  12242. methodInstance = mModule->GetRawMethodInstanceAtIdx(delegateTypeInstance, 0, "Invoke");
  12243. if (methodInstance == NULL)
  12244. {
  12245. BF_DBG_FATAL("Invoke not found");
  12246. return;
  12247. }
  12248. if (auto tokenNode = BfNodeDynCast<BfTokenNode>(delegateBindExpr->mNewToken))
  12249. {
  12250. if (delegateTypeInstance->IsFunction())
  12251. mModule->Fail("Function bindings are direct assignments, allocation specifier is not applicable", delegateBindExpr->mNewToken);
  12252. else if (tokenNode->GetToken() == BfToken_Append)
  12253. {
  12254. mModule->Fail("Append allocation on delegate bind not supported", delegateBindExpr->mNewToken);
  12255. }
  12256. }
  12257. }
  12258. int paramOffset = methodInstance->HasExplicitThis() ? 1 : 0;
  12259. typedValueExprs.resize(methodInstance->GetParamCount() - paramOffset);
  12260. args.resize(methodInstance->GetParamCount() - paramOffset);
  12261. for (int i = 0; i < (int)methodInstance->GetParamCount() - paramOffset; i++)
  12262. {
  12263. auto typedValueExpr = &typedValueExprs[i];
  12264. typedValueExpr->mTypedValue.mValue = BfIRValue(BfIRValueFlags_Value, -1);
  12265. typedValueExpr->mTypedValue.mType = methodInstance->GetParamType(i + paramOffset);
  12266. if (methodInstance->GetParamKind(i + paramOffset) == BfParamKind_Params)
  12267. typedValueExpr->mTypedValue.mKind = BfTypedValueKind_Params;
  12268. typedValueExpr->mRefNode = NULL;
  12269. args[i] = typedValueExpr;
  12270. }
  12271. BfMethodGenericArguments methodGenericArgs;
  12272. if (delegateBindExpr->mGenericArgs != NULL)
  12273. methodGenericArgs.mArguments = &delegateBindExpr->mGenericArgs->mGenericArgs;
  12274. if (delegateBindExpr->mTarget == NULL)
  12275. {
  12276. mModule->AssertErrorState();
  12277. return;
  12278. }
  12279. auto autoComplete = GetAutoComplete();
  12280. if (autoComplete != NULL)
  12281. {
  12282. SetAndRestoreValue<bool> prevForceAllowNonStatic(autoComplete->mForceAllowNonStatic, methodInstance->mMethodDef->mHasExplicitThis);
  12283. GetAutoComplete()->CheckNode(delegateBindExpr->mTarget, true);
  12284. }
  12285. if ((!delegateBindExpr->mTarget->IsA<BfIdentifierNode>()) &&
  12286. (!delegateBindExpr->mTarget->IsA<BfMemberReferenceExpression>()))
  12287. {
  12288. mModule->Fail(StrFormat("Invalid %s binding target, %s can only bind to method references. Consider wrapping expression in a lambda.", bindTypeName, bindTypeName), delegateBindExpr->mTarget);
  12289. mModule->CreateValueFromExpression(delegateBindExpr->mTarget);
  12290. return;
  12291. }
  12292. BfFunctionBindResult bindResult;
  12293. bindResult.mSkipMutCheck = true; // Allow operating on copies
  12294. bindResult.mBindType = delegateTypeInstance;
  12295. //
  12296. {
  12297. SetAndRestoreValue<BfType*> prevExpectingType(mExpectingType, methodInstance->mReturnType);
  12298. mFunctionBindResult = &bindResult;
  12299. DoInvocation(delegateBindExpr->mTarget, delegateBindExpr, args, methodGenericArgs);
  12300. mFunctionBindResult = NULL;
  12301. }
  12302. SetMethodElementType(delegateBindExpr->mTarget);
  12303. if (bindResult.mMethodInstance == NULL)
  12304. {
  12305. if ((mResult) && (IsVar(mResult.mType)))
  12306. return;
  12307. mResult = BfTypedValue();
  12308. return;
  12309. }
  12310. if (((bindResult.mMethodInstance->mComptimeFlags & BfComptimeFlag_Comptime) != 0) && ((mModule->mCurMethodInstance->mComptimeFlags & BfComptimeFlag_Comptime) == 0))
  12311. {
  12312. 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);
  12313. }
  12314. auto bindMethodInstance = bindResult.mMethodInstance;
  12315. if (isMethodRefMatch)
  12316. {
  12317. // WTF- this was always false, what was it supposed to catch?
  12318. // if (bindMethodInstance != bindResult.mMethodInstance)
  12319. // {
  12320. // mResult = BfTypedValue();
  12321. // return;
  12322. // }
  12323. }
  12324. else
  12325. {
  12326. bool isExactMethodMatch = IsExactMethodMatch(methodInstance, bindMethodInstance, true);
  12327. if ((mExpectingType != NULL) && (mExpectingType->IsFunction()) && (methodInstance->mMethodDef->mIsMutating != bindMethodInstance->mMethodDef->mIsMutating))
  12328. isExactMethodMatch = false;
  12329. if (!isExactMethodMatch)
  12330. {
  12331. if (bindResult.mCheckedMultipleMethods)
  12332. {
  12333. mModule->Fail(StrFormat("No overload for '%s' matches %s '%s'", bindMethodInstance->mMethodDef->mName.c_str(), bindTypeName,
  12334. mModule->TypeToString(delegateTypeInstance).c_str()), delegateBindExpr->mTarget);
  12335. }
  12336. else
  12337. {
  12338. mModule->Fail(StrFormat("Method '%s' does not match %s '%s'", mModule->MethodToString(bindMethodInstance, (BfMethodNameFlags)(BfMethodNameFlag_ResolveGenericParamNames | BfMethodNameFlag_IncludeReturnType | BfMethodNameFlag_IncludeMut)).c_str(), bindTypeName,
  12339. mModule->TypeToString(delegateTypeInstance).c_str()), delegateBindExpr->mTarget);
  12340. }
  12341. mResult = BfTypedValue();
  12342. return;
  12343. }
  12344. }
  12345. bool isDirectFunction = false;
  12346. if ((bindResult.mMethodInstance->GetOwner()->IsFunction()) && (bindResult.mFunc))
  12347. isDirectFunction = true;
  12348. if (bindMethodInstance->mIsIntrinsic)
  12349. {
  12350. 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);
  12351. mResult = BfTypedValue();
  12352. return;
  12353. }
  12354. bool hasIncompatibleCallingConventions = !mModule->mSystem->IsCompatibleCallingConvention(methodInstance->mCallingConvention, bindMethodInstance->mCallingConvention);
  12355. auto _GetInvokeMethodName = [&]()
  12356. {
  12357. StringT<512> methodName = "Invoke$";
  12358. methodName += mModule->mCurMethodInstance->mMethodDef->mName;
  12359. int prevSepPos = (int)methodName.LastIndexOf('$');
  12360. if (prevSepPos > 6)
  12361. {
  12362. methodName.RemoveToEnd(prevSepPos);
  12363. }
  12364. auto rootMethodState = mModule->mCurMethodState->GetRootMethodState();
  12365. HashContext hashCtx;
  12366. if (mModule->mCurMethodInstance->mMethodDef->mDeclaringType->mPartialIdx != -1)
  12367. hashCtx.Mixin(mModule->mCurMethodInstance->mMethodDef->mDeclaringType->mPartialIdx);
  12368. if (delegateBindExpr->mFatArrowToken != NULL)
  12369. {
  12370. hashCtx.Mixin(delegateBindExpr->mFatArrowToken->GetStartCharId());
  12371. }
  12372. if (rootMethodState->mMethodInstance->mMethodInfoEx != NULL)
  12373. {
  12374. for (auto methodGenericArg : rootMethodState->mMethodInstance->mMethodInfoEx->mMethodGenericArguments)
  12375. {
  12376. StringT<128> genericTypeName;
  12377. BfMangler::Mangle(genericTypeName, mModule->mCompiler->GetMangleKind(), methodGenericArg);
  12378. hashCtx.MixinStr(genericTypeName);
  12379. }
  12380. }
  12381. Val128 hashVal = hashCtx.Finish128();
  12382. methodName += '$';
  12383. methodName += BfTypeUtils::HashEncode64(hashVal.mLow);
  12384. StringT<512> mangledName;
  12385. BfMangler::MangleMethodName(mangledName, mModule->mCompiler->GetMangleKind(), mModule->mCurTypeInstance, methodName);
  12386. return mangledName;
  12387. };
  12388. if ((delegateBindExpr->mNewToken == NULL) || (delegateTypeInstance->IsFunction()))
  12389. {
  12390. if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mHotDataReferenceBuilder != NULL))
  12391. {
  12392. BF_ASSERT(bindResult.mMethodInstance->mHotMethod != NULL);
  12393. mModule->mCurMethodState->mHotDataReferenceBuilder->mFunctionPtrs.Add(bindResult.mMethodInstance->mHotMethod);
  12394. }
  12395. if (isDirectFunction)
  12396. {
  12397. //if ((delegateTypeInstance != NULL) && (delegateTypeInstance->IsFunction()))
  12398. if (mExpectingType->IsFunction())
  12399. {
  12400. auto intPtrVal = mModule->mBfIRBuilder->CreatePtrToInt(bindResult.mFunc, BfTypeCode_IntPtr);
  12401. mResult = BfTypedValue(intPtrVal, mExpectingType);
  12402. return;
  12403. }
  12404. }
  12405. if (mExpectingType->IsFunction())
  12406. {
  12407. BfIRValue result;
  12408. if ((hasIncompatibleCallingConventions) && (mModule->HasExecutedOutput()))
  12409. {
  12410. //
  12411. {
  12412. SetAndRestoreValue<bool> prevIgnore(mModule->mBfIRBuilder->mIgnoreWrites, true);
  12413. result = mModule->CastToFunction(delegateBindExpr->mTarget, bindResult.mOrigTarget, bindResult.mMethodInstance, mExpectingType);
  12414. }
  12415. if (result)
  12416. {
  12417. String methodName = _GetInvokeMethodName();
  12418. SizedArray<BfIRType, 8> irParamTypes;
  12419. BfIRType irReturnType;
  12420. methodInstance->GetIRFunctionInfo(mModule, irReturnType, irParamTypes);
  12421. int thisFuncParamIdx = methodInstance->GetThisIdx();
  12422. int thisBindParamIdx = methodInstance->GetThisIdx();
  12423. auto prevActiveFunction = mModule->mBfIRBuilder->GetActiveFunction();
  12424. auto prevInsertBlock = mModule->mBfIRBuilder->GetInsertBlock();
  12425. mModule->mBfIRBuilder->SaveDebugLocation();
  12426. auto funcType = mModule->mBfIRBuilder->CreateFunctionType(irReturnType, irParamTypes);
  12427. auto funcValue = mModule->mBfIRBuilder->CreateFunction(funcType, BfIRLinkageType_External, methodName);
  12428. auto srcCallingConv = mModule->GetIRCallingConvention(methodInstance);
  12429. mModule->mBfIRBuilder->SetFuncCallingConv(funcValue, srcCallingConv);
  12430. mModule->mBfIRBuilder->SetActiveFunction(funcValue);
  12431. auto entryBlock = mModule->mBfIRBuilder->CreateBlock("entry", true);
  12432. mModule->mBfIRBuilder->SetInsertPoint(entryBlock);
  12433. SizedArray<BfIRValue, 8> irArgs;
  12434. for (int paramIdx = 0; paramIdx < irParamTypes.size(); paramIdx++)
  12435. {
  12436. irArgs.push_back(mModule->mBfIRBuilder->GetArgument(paramIdx));
  12437. }
  12438. auto bindFuncVal = bindResult.mFunc;
  12439. if ((mModule->mCompiler->mOptions.mAllowHotSwapping) && (!mModule->mIsComptimeModule))
  12440. bindFuncVal = mModule->mBfIRBuilder->RemapBindFunction(bindFuncVal);
  12441. auto callResult = mModule->mBfIRBuilder->CreateCall(bindFuncVal, irArgs);
  12442. auto destCallingConv = mModule->GetIRCallingConvention(bindMethodInstance);
  12443. if (destCallingConv != BfIRCallingConv_CDecl)
  12444. mModule->mBfIRBuilder->SetCallCallingConv(callResult, destCallingConv);
  12445. if (methodInstance->mReturnType->IsValuelessType())
  12446. mModule->mBfIRBuilder->CreateRetVoid();
  12447. else
  12448. mModule->mBfIRBuilder->CreateRet(callResult);
  12449. mModule->mBfIRBuilder->SetActiveFunction(prevActiveFunction);
  12450. mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock);
  12451. mModule->mBfIRBuilder->RestoreDebugLocation();
  12452. result = mModule->mBfIRBuilder->CreatePtrToInt(funcValue, BfTypeCode_IntPtr);
  12453. }
  12454. }
  12455. else
  12456. {
  12457. if ((bindResult.mOrigTarget) && (bindResult.mOrigTarget.mType->IsGenericParam()) && (bindResult.mMethodInstance->GetOwner()->IsInterface()))
  12458. {
  12459. bool matching = true;
  12460. if (methodInstance->HasExplicitThis())
  12461. {
  12462. auto thisType = methodInstance->GetParamType(0);
  12463. if (thisType->IsPointer())
  12464. thisType = thisType->GetUnderlyingType();
  12465. if (thisType->IsRef())
  12466. thisType = thisType->GetUnderlyingType();
  12467. matching = thisType == bindResult.mOrigTarget.mType;
  12468. }
  12469. if (matching)
  12470. {
  12471. mResult = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), mExpectingType);
  12472. return;
  12473. }
  12474. }
  12475. result = mModule->CastToFunction(delegateBindExpr->mTarget, bindResult.mOrigTarget, bindResult.mMethodInstance, mExpectingType, BfCastFlags_None, bindResult.mFunc);
  12476. }
  12477. if (result)
  12478. mResult = BfTypedValue(result, mExpectingType);
  12479. return;
  12480. }
  12481. if (bindResult.mMethodInstance->mDisallowCalling)
  12482. {
  12483. BF_ASSERT(mModule->mBfIRBuilder->mIgnoreWrites);
  12484. mResult = mModule->GetDefaultTypedValue(mExpectingType, false, BfDefaultValueKind_Addr);
  12485. return;
  12486. }
  12487. auto methodRefType = mModule->CreateMethodRefType(bindResult.mMethodInstance);
  12488. mModule->AddDependency(methodRefType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_Calls);
  12489. mModule->AddCallDependency(bindResult.mMethodInstance);
  12490. if ((bindResult.mOrigTarget) && (bindResult.mOrigTarget.mType->IsMethodRef()))
  12491. {
  12492. mResult = bindResult.mOrigTarget;
  12493. }
  12494. else
  12495. {
  12496. if ((bindResult.mMethodInstance->mMethodDef->mIsLocalMethod) || (!bindResult.mTarget))
  12497. mResult = BfTypedValue(BfIRValue(BfIRValueFlags_Value, BfIRValue::ID_IMPLICIT), methodRefType);
  12498. else
  12499. {
  12500. auto methodRefPtr = mModule->CreateAlloca(methodRefType, "bindResult");
  12501. auto elemPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(methodRefPtr, 0, 0);
  12502. BfTypedValue target;
  12503. if (bindResult.mTarget.IsSplat())
  12504. target = mModule->AggregateSplat(bindResult.mTarget, &bindResult.mIRArgs[0]);
  12505. else
  12506. target = bindResult.mTarget;
  12507. mModule->mBfIRBuilder->CreateStore(target.mValue, elemPtr);
  12508. mResult = BfTypedValue(methodRefPtr, methodRefType, true);
  12509. }
  12510. }
  12511. return;
  12512. }
  12513. int implicitParamCount = bindMethodInstance->GetImplicitParamCount();
  12514. BfTypeInstance* useTypeInstance = delegateTypeInstance;
  12515. BfClosureType* closureTypeInst = NULL;
  12516. auto origTarget = bindResult.mOrigTarget;
  12517. auto target = bindResult.mTarget;
  12518. BfTypedValue methodRefTarget;
  12519. if ((bindResult.mOrigTarget) && (bindResult.mOrigTarget.mType->IsMethodRef()))
  12520. methodRefTarget = bindResult.mOrigTarget;
  12521. bool isStructTarget = (target) && (target.mType->IsStruct());
  12522. bool bindCapturesThis = bindMethodInstance->HasThis() && !isStructTarget;
  12523. bool needsSplat = (isStructTarget) && (!bindMethodInstance->mMethodDef->mIsMutating) && (bindMethodInstance->AllowsSplatting(-1));
  12524. bool captureThisByValue = isStructTarget;
  12525. if (bindMethodInstance->mMethodDef->mIsLocalMethod)
  12526. {
  12527. // Local method captures always capture 'this' by reference
  12528. captureThisByValue = false;
  12529. }
  12530. if ((origTarget.mType != NULL) &&
  12531. ((origTarget.mType->IsRef()) || (origTarget.mType->IsPointer())))
  12532. {
  12533. captureThisByValue = false;
  12534. }
  12535. if (methodRefTarget)
  12536. BF_ASSERT(methodRefTarget.mType->IsMethodRef());
  12537. if (target.IsSplat())
  12538. target = mModule->AggregateSplat(target, &bindResult.mIRArgs[0]);
  12539. bool hasCaptures = false;
  12540. // Do we need a special delegate type for this?
  12541. if (((captureThisByValue) || (needsSplat) || (implicitParamCount > 0) /*|| (hasIncompatibleCallingConventions)*/) &&
  12542. (mModule->HasExecutedOutput()))
  12543. {
  12544. hasCaptures = true;
  12545. auto curProject = mModule->mCurTypeInstance->mTypeDef->mProject;
  12546. if (captureThisByValue)
  12547. target = mModule->LoadValue(target);
  12548. String delegateTypeName = mModule->TypeToString(delegateTypeInstance);
  12549. HashContext hashCtx;
  12550. hashCtx.MixinStr(delegateTypeName);
  12551. // We mix in the project for reasons described in the lambda binding handler
  12552. hashCtx.MixinStr(curProject->mName);
  12553. String structTargetTypeName;
  12554. String structTargetName;
  12555. // Implicit param separator
  12556. for (int implicitParamIdx = bindMethodInstance->HasThis() ? - 1 : 0; implicitParamIdx < implicitParamCount; implicitParamIdx++)
  12557. {
  12558. auto paramType = bindResult.mMethodInstance->GetParamType(implicitParamIdx);
  12559. if ((implicitParamIdx == -1) && (captureThisByValue))
  12560. {
  12561. if (paramType->IsPointer())
  12562. paramType = paramType->GetUnderlyingType();
  12563. }
  12564. structTargetTypeName = mModule->TypeToString(paramType);
  12565. structTargetName = bindResult.mMethodInstance->GetParamName(implicitParamIdx);
  12566. hashCtx.MixinStr(structTargetTypeName);
  12567. hashCtx.MixinStr(structTargetName);
  12568. }
  12569. Val128 hash128 = hashCtx.Finish128();
  12570. BfClosureType* checkClosureType = new BfClosureType(delegateTypeInstance, hash128);
  12571. checkClosureType->mContext = mModule->mContext;
  12572. checkClosureType->mBaseType = delegateTypeInstance;
  12573. BfType* resolvedClosureType = mModule->ResolveType(checkClosureType, BfPopulateType_TypeDef);
  12574. closureTypeInst = (BfClosureType*)resolvedClosureType;
  12575. if (checkClosureType == resolvedClosureType)
  12576. {
  12577. // This is a new closure type
  12578. closureTypeInst->Init(curProject);
  12579. for (int implicitParamIdx = bindMethodInstance->HasThis() ? -1 : 0; implicitParamIdx < implicitParamCount; implicitParamIdx++)
  12580. {
  12581. String fieldName = bindResult.mMethodInstance->GetParamName(implicitParamIdx);
  12582. BfType* paramType = bindResult.mMethodInstance->GetParamType(implicitParamIdx);
  12583. if ((implicitParamIdx == -1) && (captureThisByValue))
  12584. {
  12585. if (paramType->IsPointer())
  12586. paramType = paramType->GetUnderlyingType();
  12587. }
  12588. if (fieldName == "this")
  12589. fieldName = "__this";
  12590. closureTypeInst->AddField(paramType, fieldName);
  12591. }
  12592. closureTypeInst->Finish();
  12593. mModule->PopulateType(resolvedClosureType, BfPopulateType_Declaration);
  12594. }
  12595. else
  12596. {
  12597. // Already had this entry
  12598. delete checkClosureType;
  12599. }
  12600. useTypeInstance = closureTypeInst;
  12601. }
  12602. mModule->PopulateType(useTypeInstance);
  12603. if (delegateBindExpr->mTarget == NULL)
  12604. {
  12605. mModule->AssertErrorState();
  12606. return;
  12607. }
  12608. mResult = BfTypedValue(mModule->AllocFromType(useTypeInstance, allocTarget, BfIRValue(), BfIRValue(), 0, BfAllocFlags_None), useTypeInstance);
  12609. // Do we need specialized calling code for this?
  12610. BfIRValue funcValue;
  12611. if (((needsSplat) || (implicitParamCount > 0) || (hasIncompatibleCallingConventions)) &&
  12612. (mModule->HasExecutedOutput()))
  12613. {
  12614. int fieldIdx = 0;
  12615. for (int implicitParamIdx = bindMethodInstance->HasThis() ? -1 : 0; implicitParamIdx < implicitParamCount; implicitParamIdx++)
  12616. {
  12617. auto fieldInst = &useTypeInstance->mFieldInstances[fieldIdx];
  12618. int gepIdx = fieldInst->mDataIdx;
  12619. auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(mResult.mValue, 0, gepIdx);
  12620. auto fieldType = bindMethodInstance->GetParamType(implicitParamIdx);
  12621. if ((implicitParamIdx == -1) && (captureThisByValue))
  12622. {
  12623. if (fieldType->IsPointer())
  12624. fieldType = fieldType->GetUnderlyingType();
  12625. }
  12626. bool failed = false;
  12627. BfTypedValue lookupVal;
  12628. if (implicitParamIdx == -1)
  12629. lookupVal = target;
  12630. else
  12631. lookupVal = DoImplicitArgCapture(delegateBindExpr->mTarget, bindResult.mMethodInstance, implicitParamIdx, failed, BfImplicitParamKind_General, methodRefTarget);
  12632. if (!lookupVal)
  12633. continue;
  12634. if ((fieldType->IsPointer()) && (lookupVal.mType != fieldType))
  12635. {
  12636. BF_ASSERT(fieldType->GetUnderlyingType() == lookupVal.mType);
  12637. BF_ASSERT(lookupVal.IsAddr());
  12638. }
  12639. else if (!fieldType->IsRef())
  12640. lookupVal = mModule->LoadOrAggregateValue(lookupVal);
  12641. if (lookupVal)
  12642. mModule->mBfIRBuilder->CreateStore(lookupVal.mValue, fieldPtr);
  12643. fieldIdx++;
  12644. }
  12645. String methodName = _GetInvokeMethodName();
  12646. SizedArray<BfIRType, 8> irParamTypes;
  12647. BfIRType irReturnType;
  12648. bool hasThis = false;
  12649. if (hasCaptures)
  12650. {
  12651. hasThis = true;
  12652. methodInstance->GetIRFunctionInfo(mModule, irReturnType, irParamTypes);
  12653. int thisIdx = 0;
  12654. if (GetStructRetIdx(methodInstance) == 0)
  12655. thisIdx = 1;
  12656. irParamTypes[thisIdx] = mModule->mBfIRBuilder->MapType(useTypeInstance);
  12657. }
  12658. else
  12659. {
  12660. BF_ASSERT(hasIncompatibleCallingConventions);
  12661. bindMethodInstance->GetIRFunctionInfo(mModule, irReturnType, irParamTypes);
  12662. hasThis = bindMethodInstance->HasThis();
  12663. }
  12664. auto prevActiveFunction = mModule->mBfIRBuilder->GetActiveFunction();
  12665. auto prevInsertBlock = mModule->mBfIRBuilder->GetInsertBlock();
  12666. mModule->mBfIRBuilder->SaveDebugLocation();
  12667. auto funcType = mModule->mBfIRBuilder->CreateFunctionType(irReturnType, irParamTypes);
  12668. funcValue = mModule->mBfIRBuilder->CreateFunction(funcType, BfIRLinkageType_External, methodName);
  12669. if (GetStructRetIdx(methodInstance) != -1)
  12670. {
  12671. mModule->mBfIRBuilder->Func_AddAttribute(funcValue, GetStructRetIdx(methodInstance) + 1, BfIRAttribute_NoAlias);
  12672. mModule->mBfIRBuilder->Func_AddAttribute(funcValue, GetStructRetIdx(methodInstance) + 1, BfIRAttribute_StructRet);
  12673. }
  12674. auto srcCallingConv = mModule->GetIRCallingConvention(methodInstance);
  12675. if ((!hasThis) && (methodInstance->mCallingConvention == BfCallingConvention_Stdcall))
  12676. srcCallingConv = BfIRCallingConv_StdCall;
  12677. else if (methodInstance->mCallingConvention == BfCallingConvention_Fastcall)
  12678. srcCallingConv = BfIRCallingConv_FastCall;
  12679. mModule->mBfIRBuilder->SetFuncCallingConv(funcValue, srcCallingConv);
  12680. mModule->mBfIRBuilder->SetActiveFunction(funcValue);
  12681. auto entryBlock = mModule->mBfIRBuilder->CreateBlock("entry", true);
  12682. mModule->mBfIRBuilder->SetInsertPoint(entryBlock);
  12683. fieldIdx = 0;
  12684. SizedArray<BfIRValue, 8> irArgs;
  12685. int argIdx = 0;
  12686. if (GetStructRetIdx(bindMethodInstance) == 0)
  12687. {
  12688. irArgs.push_back(mModule->mBfIRBuilder->GetArgument(GetStructRetIdx(methodInstance)));
  12689. argIdx++;
  12690. }
  12691. for (int implicitParamIdx = bindMethodInstance->HasThis() ? -1 : 0; implicitParamIdx < implicitParamCount; implicitParamIdx++)
  12692. {
  12693. auto fieldInst = &useTypeInstance->mFieldInstances[fieldIdx];
  12694. int gepIdx = fieldInst->mDataIdx;
  12695. auto fieldType = bindMethodInstance->GetParamType(implicitParamIdx);
  12696. bool disableSplat = false;
  12697. if ((implicitParamIdx == -1) && (captureThisByValue))
  12698. {
  12699. if (fieldType->IsPointer())
  12700. {
  12701. fieldType = fieldType->GetUnderlyingType();
  12702. disableSplat = true;
  12703. }
  12704. }
  12705. int thisIdx = 0;
  12706. if (GetStructRetIdx(methodInstance) == 0)
  12707. thisIdx = 1;
  12708. auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(mModule->mBfIRBuilder->GetArgument(thisIdx), 0, gepIdx);
  12709. BfTypedValue typedVal(fieldPtr, fieldType, true);
  12710. PushArg(typedVal, irArgs, disableSplat);
  12711. fieldIdx++;
  12712. }
  12713. if (hasThis)
  12714. argIdx++;
  12715. if (GetStructRetIdx(bindMethodInstance) == 1)
  12716. {
  12717. irArgs.push_back(mModule->mBfIRBuilder->GetArgument(GetStructRetIdx(methodInstance)));
  12718. argIdx++;
  12719. }
  12720. for (int paramIdx = 0; paramIdx < methodInstance->GetParamCount(); paramIdx++)
  12721. {
  12722. auto paramType = methodInstance->GetParamType(paramIdx);
  12723. if ((paramType->IsSplattable()) && (!IsComptime()))
  12724. {
  12725. BfTypeUtils::SplatIterate([&](BfType* checkType) { irArgs.push_back(mModule->mBfIRBuilder->GetArgument(argIdx++)); }, paramType);
  12726. }
  12727. else if (!paramType->IsValuelessType())
  12728. {
  12729. irArgs.push_back(mModule->mBfIRBuilder->GetArgument(argIdx++));
  12730. }
  12731. }
  12732. auto bindFuncVal = bindResult.mFunc;
  12733. if ((mModule->mCompiler->mOptions.mAllowHotSwapping) && (!mModule->mIsComptimeModule))
  12734. bindFuncVal = mModule->mBfIRBuilder->RemapBindFunction(bindFuncVal);
  12735. auto callInst = mModule->mBfIRBuilder->CreateCall(bindFuncVal, irArgs);
  12736. if (GetStructRetIdx(bindMethodInstance) != -1)
  12737. mModule->mBfIRBuilder->Call_AddAttribute(callInst, GetStructRetIdx(bindMethodInstance) + 1, BfIRAttribute_StructRet);
  12738. auto destCallingConv = mModule->GetIRCallingConvention(bindMethodInstance);
  12739. if (destCallingConv != BfIRCallingConv_CDecl)
  12740. mModule->mBfIRBuilder->SetCallCallingConv(callInst, destCallingConv);
  12741. if ((methodInstance->mReturnType->IsValuelessType()) || (GetStructRetIdx(methodInstance) != -1))
  12742. {
  12743. mModule->mBfIRBuilder->CreateRetVoid();
  12744. }
  12745. else
  12746. {
  12747. mModule->mBfIRBuilder->CreateRet(callInst);
  12748. }
  12749. mModule->mBfIRBuilder->SetActiveFunction(prevActiveFunction);
  12750. mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock);
  12751. mModule->mBfIRBuilder->RestoreDebugLocation();
  12752. }
  12753. else if ((closureTypeInst != NULL) && (captureThisByValue))
  12754. {
  12755. // 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
  12756. int dataIdx = 1;
  12757. if (!closureTypeInst->mFieldInstances.IsEmpty())
  12758. {
  12759. auto& fieldInst = closureTypeInst->mFieldInstances[0];
  12760. BF_ASSERT(fieldInst.GetFieldDef()->mName == "__this");
  12761. dataIdx = fieldInst.mDataIdx;
  12762. }
  12763. auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(mResult.mValue, 0, dataIdx);
  12764. target = mModule->LoadValue(target);
  12765. mModule->mBfIRBuilder->CreateStore(target.mValue, fieldPtr);
  12766. target = BfTypedValue(fieldPtr, target.mType, true);
  12767. }
  12768. BfResolvedArgs resolvedArgs;
  12769. MatchConstructor(delegateBindExpr, delegateBindExpr, mResult, useTypeInstance, resolvedArgs, false, BfMethodGenericArguments(), BfAllowAppendKind_No);
  12770. auto baseDelegateType = VerifyBaseDelegateType(delegateTypeInstance->mBaseType);
  12771. auto baseDelegate = mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->MapType(baseDelegateType, BfIRPopulateType_Full));
  12772. // >> delegate.mTarget = bindResult.mTarget
  12773. BfIRValue valPtr;
  12774. if (mModule->HasExecutedOutput())
  12775. {
  12776. if ((implicitParamCount > 0) || (needsSplat)) // Point back to self, it contains capture data
  12777. valPtr = mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->GetPrimitiveType(BfTypeCode_NullPtr));
  12778. else if (bindResult.mTarget)
  12779. {
  12780. if ((target.mType->IsObjectOrInterface()) &&
  12781. (mModule->mCompiler->mOptions.mObjectHasDebugFlags) && (!mModule->mIsComptimeModule) &&
  12782. (mModule->mCompiler->mSystem->mPtrSize == 8))
  12783. {
  12784. auto numVal = mModule->mBfIRBuilder->CreatePtrToInt(target.mValue, BfTypeCode_UInt64);
  12785. auto orVal = mModule->mBfIRBuilder->CreateOr(numVal, mModule->mBfIRBuilder->CreateConst(BfTypeCode_UInt64, (uint64)0x8000000000000000ULL));
  12786. valPtr = mModule->mBfIRBuilder->CreateIntToPtr(orVal, mModule->mBfIRBuilder->GetPrimitiveType(BfTypeCode_NullPtr));
  12787. }
  12788. else
  12789. valPtr = mModule->mBfIRBuilder->CreateBitCast(target.mValue, mModule->mBfIRBuilder->GetPrimitiveType(BfTypeCode_NullPtr));
  12790. }
  12791. else
  12792. valPtr = mModule->GetDefaultValue(mModule->GetPrimitiveType(BfTypeCode_NullPtr));
  12793. auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(baseDelegate, 0, 2);
  12794. mModule->mBfIRBuilder->CreateStore(valPtr, fieldPtr);
  12795. }
  12796. if (!funcValue)
  12797. {
  12798. funcValue = bindResult.mFunc;
  12799. if (!funcValue)
  12800. {
  12801. if ((mModule->HasExecutedOutput()) && (!mModule->mBfIRBuilder->mIgnoreWrites))
  12802. mModule->AssertErrorState();
  12803. return;
  12804. }
  12805. if ((mModule->mCompiler->mOptions.mAllowHotSwapping) && (!bindResult.mMethodInstance->mMethodDef->mIsVirtual) && (!mModule->mIsComptimeModule))
  12806. {
  12807. funcValue = mModule->mBfIRBuilder->RemapBindFunction(funcValue);
  12808. }
  12809. }
  12810. // >> delegate.mFuncPtr = bindResult.mFunc
  12811. auto nullPtrType = mModule->GetPrimitiveType(BfTypeCode_NullPtr);
  12812. valPtr = mModule->mBfIRBuilder->CreateBitCast(funcValue, mModule->mBfIRBuilder->MapType(nullPtrType));
  12813. auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(baseDelegate, 0, 1);
  12814. mModule->mBfIRBuilder->CreateStore(valPtr, fieldPtr);
  12815. }
  12816. void BfExprEvaluator::VisitLambdaBodies(BfAstNode* body, BfFieldDtorDeclaration* fieldDtor)
  12817. {
  12818. if (auto blockBody = BfNodeDynCast<BfBlock>(body))
  12819. mModule->VisitChild(blockBody);
  12820. else if (auto bodyExpr = BfNodeDynCast<BfExpression>(body))
  12821. {
  12822. auto result = mModule->CreateValueFromExpression(bodyExpr);
  12823. if ((result) && (mModule->mCurMethodState->mClosureState != NULL) &&
  12824. (mModule->mCurMethodState->mClosureState->mReturnTypeInferState == BfReturnTypeInferState_Inferring))
  12825. mModule->mCurMethodState->mClosureState->mReturnType = result.mType;
  12826. }
  12827. while (fieldDtor != NULL)
  12828. {
  12829. mModule->mCurMethodState->mLeftBlockUncond = false;
  12830. mModule->VisitChild(fieldDtor->mBody);
  12831. fieldDtor = fieldDtor->mNextFieldDtor;
  12832. }
  12833. }
  12834. BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lambdaBindExpr, BfAllocTarget& allocTarget)
  12835. {
  12836. if (mModule->mCurMethodState == NULL)
  12837. return NULL;
  12838. auto rootMethodState = mModule->mCurMethodState->GetRootMethodState();
  12839. BfAstNodeList cacheNodeList;
  12840. cacheNodeList.mList.Add(lambdaBindExpr);
  12841. ///
  12842. {
  12843. auto checkMethodState = mModule->mCurMethodState;
  12844. while (checkMethodState != NULL)
  12845. {
  12846. if (checkMethodState->mMixinState != NULL)
  12847. cacheNodeList.mList.Add(checkMethodState->mMixinState->mSource);
  12848. checkMethodState = checkMethodState->mPrevMethodState;
  12849. }
  12850. }
  12851. bool isInferReturnType = (mBfEvalExprFlags & BfEvalExprFlags_InferReturnType) != 0;
  12852. BfLambdaInstance* lambdaInstance = NULL;
  12853. if ((!isInferReturnType) && (rootMethodState->mLambdaCache.TryGetValue(cacheNodeList, &lambdaInstance)))
  12854. return lambdaInstance;
  12855. static int sBindCount = 0;
  12856. sBindCount++;
  12857. bool isFunctionBind = false;
  12858. BfTypeInstance* delegateTypeInstance = NULL;
  12859. BfMethodInstance* invokeMethodInstance = NULL;
  12860. if (mExpectingType == NULL)
  12861. {
  12862. mModule->Fail("Cannot infer delegate type", lambdaBindExpr);
  12863. delegateTypeInstance = mModule->ResolveTypeDef(mModule->mCompiler->mActionTypeDef)->ToTypeInstance();
  12864. }
  12865. else
  12866. {
  12867. delegateTypeInstance = mExpectingType->ToTypeInstance();
  12868. if ((delegateTypeInstance == NULL) ||
  12869. ((!delegateTypeInstance->mTypeDef->mIsDelegate) && (!delegateTypeInstance->mTypeDef->mIsFunction)))
  12870. {
  12871. if (lambdaBindExpr->mFatArrowToken != NULL)
  12872. mModule->Fail("Can only bind lambdas to delegate types", lambdaBindExpr->mFatArrowToken);
  12873. delegateTypeInstance = mModule->ResolveTypeDef(mModule->mCompiler->mActionTypeDef)->ToTypeInstance();
  12874. }
  12875. else
  12876. {
  12877. invokeMethodInstance = mModule->GetRawMethodInstanceAtIdx(delegateTypeInstance, 0, "Invoke");
  12878. }
  12879. isFunctionBind = delegateTypeInstance->mTypeDef->mIsFunction;
  12880. }
  12881. if (auto tokenNode = BfNodeDynCast<BfTokenNode>(lambdaBindExpr->mNewToken))
  12882. {
  12883. if (isFunctionBind)
  12884. {
  12885. mModule->Fail("Function lambda binding does not require allocation", lambdaBindExpr->mNewToken);
  12886. }
  12887. else if (tokenNode->GetToken() == BfToken_Append)
  12888. {
  12889. mModule->Fail("Append allocation on delegate bind not supported", lambdaBindExpr->mNewToken);
  12890. }
  12891. }
  12892. if (invokeMethodInstance != NULL)
  12893. {
  12894. if ((int)lambdaBindExpr->mParams.size() < invokeMethodInstance->GetParamCount())
  12895. {
  12896. BfAstNode* refNode = lambdaBindExpr->mCloseParen;
  12897. if (refNode == NULL)
  12898. refNode = lambdaBindExpr;
  12899. mModule->Fail(StrFormat("Not enough parameters for delegate type '%s'. Expected %d more.",
  12900. mModule->TypeToString(delegateTypeInstance).c_str(), invokeMethodInstance->GetParamCount() - lambdaBindExpr->mParams.size()), refNode);
  12901. }
  12902. else if ((int)lambdaBindExpr->mParams.size() > invokeMethodInstance->GetParamCount())
  12903. {
  12904. BfAstNode* refNode = lambdaBindExpr->mParams[invokeMethodInstance->GetParamCount()];
  12905. mModule->Fail(StrFormat("Too many parameters for delegate type '%s'. Expected %d fewer.",
  12906. mModule->TypeToString(delegateTypeInstance).c_str(), lambdaBindExpr->mParams.size() - invokeMethodInstance->GetParamCount()), refNode);
  12907. }
  12908. }
  12909. auto autoComplete = GetAutoComplete();
  12910. bool wasCapturingMethodInfo = false;
  12911. if ((autoComplete != NULL) && (invokeMethodInstance != NULL))
  12912. {
  12913. wasCapturingMethodInfo = autoComplete->mIsCapturingMethodMatchInfo;
  12914. bool isAutocompleteNode = false;
  12915. if (lambdaBindExpr->mFatArrowToken != NULL)
  12916. {
  12917. if (autoComplete->IsAutocompleteNode(lambdaBindExpr, lambdaBindExpr->mFatArrowToken))
  12918. isAutocompleteNode = true;
  12919. }
  12920. else if (autoComplete->IsAutocompleteNode(lambdaBindExpr))
  12921. isAutocompleteNode = true;
  12922. if (isAutocompleteNode)
  12923. autoComplete->CheckInvocation(lambdaBindExpr, lambdaBindExpr->mOpenParen, lambdaBindExpr->mCloseParen, lambdaBindExpr->mCommas);
  12924. if (autoComplete->mIsCapturingMethodMatchInfo)
  12925. {
  12926. autoComplete->mMethodMatchInfo->mInstanceList.Clear();
  12927. auto methodMatchInfo = autoComplete->mMethodMatchInfo;
  12928. BfAutoComplete::MethodMatchEntry methodMatchEntry;
  12929. methodMatchEntry.mTypeInstance = invokeMethodInstance->GetOwner();
  12930. methodMatchEntry.mCurMethodInstance = mModule->mCurMethodInstance;
  12931. methodMatchEntry.mMethodDef = invokeMethodInstance->mMethodDef;
  12932. autoComplete->mMethodMatchInfo->mInstanceList.push_back(methodMatchEntry);
  12933. methodMatchInfo->mBestIdx = 0;
  12934. methodMatchInfo->mMostParamsMatched = 0;
  12935. int cursorIdx = lambdaBindExpr->GetParser()->mCursorIdx;
  12936. if ((lambdaBindExpr->mCloseParen == NULL) || (cursorIdx <= lambdaBindExpr->mCloseParen->GetSrcStart()))
  12937. {
  12938. int paramIdx = 0;
  12939. for (int commaIdx = 0; commaIdx < (int)lambdaBindExpr->mCommas.size(); commaIdx++)
  12940. {
  12941. auto commaNode = lambdaBindExpr->mCommas[commaIdx];
  12942. if ((commaNode != NULL) && (cursorIdx >= commaNode->GetSrcStart()))
  12943. paramIdx = commaIdx + 1;
  12944. }
  12945. bool isEmpty = true;
  12946. if (paramIdx < (int)lambdaBindExpr->mParams.size())
  12947. {
  12948. auto paramNode = lambdaBindExpr->mParams[paramIdx];
  12949. if (paramNode != NULL)
  12950. isEmpty = false;
  12951. }
  12952. if (isEmpty)
  12953. {
  12954. if (paramIdx < (int)invokeMethodInstance->GetParamCount())
  12955. {
  12956. String paramName = invokeMethodInstance->GetParamName(paramIdx);
  12957. autoComplete->mEntriesSet.Clear();
  12958. if (paramName.IsEmpty())
  12959. paramName += StrFormat("val%d", paramIdx + 1);
  12960. autoComplete->AddEntry(AutoCompleteEntry("paramName", paramName));
  12961. autoComplete->mInsertStartIdx = cursorIdx;
  12962. autoComplete->mInsertEndIdx = cursorIdx;
  12963. if ((paramIdx == 0) && (lambdaBindExpr->mParams.IsEmpty()))
  12964. {
  12965. String totalNames;
  12966. for (int checkIdx = 0; checkIdx < (int)invokeMethodInstance->GetParamCount(); checkIdx++)
  12967. {
  12968. if (!totalNames.IsEmpty())
  12969. totalNames += ", ";
  12970. String paramName = invokeMethodInstance->GetParamName(checkIdx);
  12971. if (paramName.IsEmpty())
  12972. paramName += StrFormat("val%d", checkIdx + 1);
  12973. totalNames += paramName;
  12974. }
  12975. autoComplete->AddEntry(AutoCompleteEntry("paramNames", totalNames));
  12976. }
  12977. }
  12978. }
  12979. }
  12980. }
  12981. }
  12982. defer
  12983. (
  12984. {
  12985. if (autoComplete != NULL)
  12986. autoComplete->mIsCapturingMethodMatchInfo = (wasCapturingMethodInfo) && (!autoComplete->mIsCapturingMethodMatchInfo) && (autoComplete->mMethodMatchInfo != NULL);
  12987. }
  12988. );
  12989. if (lambdaBindExpr->mBody == NULL)
  12990. {
  12991. mModule->AssertErrorState();
  12992. return NULL;
  12993. }
  12994. if ((lambdaBindExpr->mNewToken == NULL) && (isInferReturnType))
  12995. {
  12996. // Method ref, but let this follow infer route
  12997. }
  12998. else if ((lambdaBindExpr->mNewToken == NULL) || (isFunctionBind))
  12999. {
  13000. if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mCapturing))
  13001. {
  13002. SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
  13003. VisitLambdaBodies(lambdaBindExpr->mBody, lambdaBindExpr->mDtor);
  13004. }
  13005. if ((lambdaBindExpr->mNewToken != NULL) && (isFunctionBind))
  13006. mModule->Fail("Binds to functions should do not require allocations.", lambdaBindExpr->mNewToken);
  13007. if (lambdaBindExpr->mDtor != NULL)
  13008. {
  13009. mModule->Fail("Valueless method reference cannot contain destructor. Consider either removing destructor or using an allocated lambda.", lambdaBindExpr->mDtor->mTildeToken);
  13010. // Eat it
  13011. auto fieldDtor = lambdaBindExpr->mDtor;
  13012. while (fieldDtor != NULL)
  13013. {
  13014. mModule->VisitEmbeddedStatement(fieldDtor->mBody);
  13015. fieldDtor = fieldDtor->mNextFieldDtor;
  13016. }
  13017. }
  13018. if (invokeMethodInstance != NULL)
  13019. {
  13020. BfLocalMethod* localMethod = new BfLocalMethod();
  13021. localMethod->mMethodName = "anon";
  13022. localMethod->mSystem = mModule->mSystem;
  13023. localMethod->mModule = mModule;
  13024. localMethod->mExpectedFullName = mModule->GetLocalMethodName(localMethod->mMethodName, lambdaBindExpr->mFatArrowToken, mModule->mCurMethodState, mModule->mCurMethodState->mMixinState);
  13025. localMethod->mLambdaInvokeMethodInstance = invokeMethodInstance;
  13026. localMethod->mLambdaBindExpr = lambdaBindExpr;
  13027. localMethod->mDeclMethodState = mModule->mCurMethodState;
  13028. mModule->mContext->mLocalMethodGraveyard.push_back(localMethod);
  13029. auto moduleMethodInstance = mModule->GetLocalMethodInstance(localMethod, BfTypeVector());
  13030. if (moduleMethodInstance.mMethodInstance->mDisallowCalling)
  13031. {
  13032. mResult = mModule->GetDefaultTypedValue(mExpectingType, false, BfDefaultValueKind_Addr);
  13033. return NULL;
  13034. }
  13035. auto methodRefType = mModule->CreateMethodRefType(moduleMethodInstance.mMethodInstance);
  13036. mModule->AddDependency(methodRefType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_Calls);
  13037. mModule->AddCallDependency(moduleMethodInstance.mMethodInstance);
  13038. mResult = BfTypedValue(BfIRValue(BfIRValueFlags_Value, BfIRValue::ID_IMPLICIT), methodRefType);
  13039. return NULL;
  13040. }
  13041. }
  13042. //SetAndRestoreValue<bool> prevIgnoreIRWrites(mModule->mBfIRBuilder->mIgnoreWrites, mModule->mWantsIRIgnoreWrites);
  13043. SetAndRestoreValue<bool> prevIgnoreIRWrites(mModule->mBfIRBuilder->mIgnoreWrites, mModule->mWantsIRIgnoreWrites || mModule->mCurMethodInstance->mIsUnspecialized);
  13044. BfTypeInstance* outerClosure = NULL;
  13045. if ((mModule->mCurMethodState->mClosureState != NULL) && (!mModule->mCurMethodState->mClosureState->mCapturing))
  13046. outerClosure = mModule->mCurMethodState->mClosureState->mClosureType;
  13047. Val128 val128(delegateTypeInstance->mTypeId);
  13048. bool isConstEval = ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0);
  13049. BfMethodState methodState;
  13050. methodState.mPrevMethodState = mModule->mCurMethodState;
  13051. BfIRFunctionType funcType;
  13052. auto voidType = mModule->GetPrimitiveType(BfTypeCode_None);
  13053. SizedArray<BfIRType, 0> paramTypes;
  13054. funcType = mModule->mBfIRBuilder->CreateFunctionType(mModule->mBfIRBuilder->MapType(voidType), paramTypes, false);
  13055. auto prevInsertBlock = mModule->mBfIRBuilder->GetInsertBlock();
  13056. BF_ASSERT(prevInsertBlock || isConstEval);
  13057. auto prevActiveFunction = mModule->mBfIRBuilder->GetActiveFunction();
  13058. mModule->mBfIRBuilder->SaveDebugLocation();
  13059. SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
  13060. BfDeferredLocalAssignData deferredLocalAssignData;
  13061. if (mModule->mCurMethodState->mDeferredLocalAssignData != NULL)
  13062. deferredLocalAssignData.ExtendFrom(mModule->mCurMethodState->mDeferredLocalAssignData);
  13063. SetAndRestoreValue<BfMethodState*> prevMethodState(mModule->mCurMethodState, &methodState);
  13064. methodState.mIRHeadBlock = mModule->mBfIRBuilder->CreateBlock("head", true);
  13065. methodState.mIRInitBlock = mModule->mBfIRBuilder->CreateBlock("init", true);
  13066. methodState.mIREntryBlock = mModule->mBfIRBuilder->CreateBlock("entry", true);
  13067. methodState.mCurScope->mDIScope = prevMethodState.mPrevVal->mCurScope->mDIScope;//invokeMethodInstance->mDIFunction;
  13068. methodState.mCurLocalVarId = -1;
  13069. methodState.mIRFunction = prevMethodState.mPrevVal->mIRFunction;
  13070. methodState.mDeferredLocalAssignData = &deferredLocalAssignData;
  13071. mModule->mBfIRBuilder->SetInsertPoint(methodState.mIREntryBlock);
  13072. BfClosureState closureState;
  13073. if (delegateTypeInstance->IsDelegate())
  13074. closureState.mReturnType = mModule->GetDelegateReturnType(delegateTypeInstance);
  13075. else
  13076. closureState.mReturnType = mModule->mContext->mBfObjectType;
  13077. closureState.mCapturing = true;
  13078. if (delegateTypeInstance->IsDelegate())
  13079. closureState.mDelegateType = delegateTypeInstance;
  13080. closureState.mDeclaringMethodIsMutating = mModule->mCurMethodInstance->mMethodDef->mIsMutating;
  13081. methodState.mClosureState = &closureState;
  13082. closureState.mClosureType = outerClosure;
  13083. BF_ASSERT(methodState.mCurLocalVarId == -1);
  13084. int outerLocalsCount = (int)methodState.mLocals.size();
  13085. // static int sItrCount = 0;
  13086. // ++sItrCount;
  13087. // int itrCount = sItrCount;
  13088. // if ((itrCount == 8) || (itrCount == 10))
  13089. // {
  13090. // NOP;
  13091. // }
  13092. String delegateTypeName = mModule->TypeToString(delegateTypeInstance);
  13093. HashContext hashCtx;
  13094. hashCtx.MixinStr(delegateTypeName);
  13095. BfSource* bfSource = delegateTypeInstance->mTypeDef->mSource;
  13096. BfMethodDef* methodDef = new BfMethodDef();
  13097. methodDef->mDeclaringType = mModule->mCurMethodInstance->mMethodDef->mDeclaringType;
  13098. Val128 closureMethodHash;
  13099. OwnedVector<BfParameterDeclaration> tempParamDecls;
  13100. if ((autoComplete != NULL) && (autoComplete->mMethodMatchInfo != NULL) && (autoComplete->IsAutocompleteNode(lambdaBindExpr->mBody)))
  13101. {
  13102. // Don't show outer method match info when our cursor is inside a lambda expression (being passed as a parameter)
  13103. autoComplete->RemoveMethodMatchInfo();
  13104. }
  13105. if (invokeMethodInstance != NULL)
  13106. {
  13107. for (int paramIdx = 0; paramIdx < (int)invokeMethodInstance->GetParamCount(); paramIdx++)
  13108. {
  13109. BfLocalVariable* localVar = new BfLocalVariable();
  13110. if (paramIdx < (int)lambdaBindExpr->mParams.size())
  13111. {
  13112. localVar->mName = lambdaBindExpr->mParams[paramIdx]->ToString();
  13113. localVar->mNameNode = lambdaBindExpr->mParams[paramIdx];
  13114. }
  13115. else
  13116. {
  13117. mModule->AssertErrorState();
  13118. localVar->mName = invokeMethodInstance->GetParamName(paramIdx);
  13119. }
  13120. localVar->mResolvedType = invokeMethodInstance->GetParamType(paramIdx);
  13121. mModule->PopulateType(localVar->mResolvedType);
  13122. localVar->mAssignedKind = BfLocalVarAssignKind_Unconditional;
  13123. localVar->mReadFromId = 0;
  13124. auto rootMethodState = methodState.GetRootMethodState();
  13125. localVar->mLocalVarId = rootMethodState->mCurLocalVarId++;
  13126. mModule->DoAddLocalVariable(localVar);
  13127. auto resolvePassData = mModule->mCompiler->mResolvePassData;
  13128. if ((resolvePassData != NULL) && (localVar->mNameNode != NULL))
  13129. resolvePassData->HandleLocalReference(BfNodeDynCast<BfIdentifierNode>(localVar->mNameNode), mModule->mCurTypeInstance->mTypeDef,
  13130. mModule->mCurMethodInstance->mMethodDef, localVar->mLocalVarId);
  13131. }
  13132. for (int paramIdx = 0; paramIdx < (int)invokeMethodInstance->mMethodDef->mParams.size(); paramIdx++)
  13133. {
  13134. auto invokeParamDef = invokeMethodInstance->mMethodDef->mParams[paramIdx];
  13135. BfParameterDef* paramDef = new BfParameterDef();
  13136. paramDef->mParamDeclaration = tempParamDecls.Alloc();
  13137. BfAstNode::Zero(paramDef->mParamDeclaration);
  13138. paramDef->mTypeRef = invokeParamDef->mTypeRef;
  13139. paramDef->mParamKind = invokeParamDef->mParamKind;
  13140. if ((paramIdx < (int)lambdaBindExpr->mParams.size()) && (invokeMethodInstance->GetParamKind(paramIdx) != BfParamKind_DelegateParam))
  13141. {
  13142. //TODO: Not always correct if we have a 'params'
  13143. paramDef->mParamDeclaration->mNameNode = lambdaBindExpr->mParams[paramIdx];
  13144. paramDef->mName = paramDef->mParamDeclaration->mNameNode->ToString();
  13145. }
  13146. else
  13147. {
  13148. paramDef->mParamDeclaration->mNameNode = NULL;
  13149. paramDef->mName = invokeParamDef->mName;
  13150. }
  13151. methodDef->mParams.push_back(paramDef);
  13152. if (autoComplete != NULL)
  13153. autoComplete->CheckLocalDef(BfNodeDynCast<BfIdentifierNode>(paramDef->mParamDeclaration->mNameNode), methodState.mLocals.back());
  13154. }
  13155. }
  13156. bool isAutocomplete = mModule->mCompiler->IsAutocomplete();
  13157. methodDef->mIdx = mModule->mCurMethodInstance->mMethodDef->mIdx;
  13158. methodDef->mBody = lambdaBindExpr->mBody;
  13159. ///
  13160. auto varMethodState = methodState.mPrevMethodState;
  13161. bool hasExplicitCaptureNames = false;
  13162. for (auto& captureEntry : allocTarget.mCaptureInfo->mCaptures)
  13163. {
  13164. if (captureEntry.mNameNode == NULL)
  13165. {
  13166. hasExplicitCaptureNames = false;
  13167. break;
  13168. }
  13169. hasExplicitCaptureNames = true;
  13170. }
  13171. auto _SetNotCapturedFlag = [&](bool notCaptured)
  13172. {
  13173. auto varMethodState = methodState.mPrevMethodState;
  13174. while (varMethodState != NULL)
  13175. {
  13176. for (int localIdx = 0; localIdx < varMethodState->mLocals.size(); localIdx++)
  13177. {
  13178. auto localVar = varMethodState->mLocals[localIdx];
  13179. localVar->mNotCaptured = notCaptured;
  13180. }
  13181. varMethodState = varMethodState->mPrevMethodState;
  13182. if (varMethodState == NULL)
  13183. break;
  13184. if (varMethodState->mMixinState != NULL)
  13185. break;
  13186. if (varMethodState->mClosureState != NULL)
  13187. {
  13188. if (!varMethodState->mClosureState->mCapturing)
  13189. break;
  13190. }
  13191. }
  13192. };
  13193. if (hasExplicitCaptureNames)
  13194. {
  13195. _SetNotCapturedFlag(true);
  13196. auto varMethodState = methodState.mPrevMethodState;
  13197. while (varMethodState != NULL)
  13198. {
  13199. for (auto& captureEntry : allocTarget.mCaptureInfo->mCaptures)
  13200. {
  13201. if (captureEntry.mNameNode != NULL)
  13202. {
  13203. StringT<64> captureName;
  13204. captureEntry.mNameNode->ToString(captureName);
  13205. BfLocalVarEntry* entry;
  13206. if (varMethodState->mLocalVarSet.TryGetWith<StringImpl&>(captureName, &entry))
  13207. {
  13208. auto localVar = entry->mLocalVar;
  13209. while (localVar != NULL)
  13210. {
  13211. if (autoComplete != NULL)
  13212. autoComplete->CheckLocalRef(captureEntry.mNameNode, localVar);
  13213. if (((mModule->mCurMethodState->mClosureState == NULL) || (mModule->mCurMethodState->mClosureState->mCapturing)) &&
  13214. (mModule->mCompiler->mResolvePassData != NULL) && (mModule->mCurMethodInstance != NULL))
  13215. {
  13216. if (auto captureIdentifierNode = BfNodeDynCast<BfIdentifierNode>(captureEntry.mNameNode))
  13217. mModule->mCompiler->mResolvePassData->HandleLocalReference(captureIdentifierNode, localVar->mNameNode, mModule->mCurTypeInstance->mTypeDef, rootMethodState->mMethodInstance->mMethodDef, localVar->mLocalVarId);
  13218. }
  13219. localVar->mNotCaptured = false;
  13220. localVar = localVar->mShadowedLocal;
  13221. }
  13222. }
  13223. }
  13224. }
  13225. varMethodState = varMethodState->mPrevMethodState;
  13226. if (varMethodState == NULL)
  13227. break;
  13228. if (varMethodState->mMixinState != NULL)
  13229. break;
  13230. if (varMethodState->mClosureState != NULL)
  13231. {
  13232. if (!varMethodState->mClosureState->mCapturing)
  13233. break;
  13234. }
  13235. }
  13236. }
  13237. BfClosureInstanceInfo* closureInstanceInfo = new BfClosureInstanceInfo();
  13238. auto checkInsertBlock = mModule->mBfIRBuilder->GetInsertBlock();
  13239. closureState.mCaptureStartAccessId = methodState.mPrevMethodState->GetRootMethodState()->mCurAccessId;
  13240. closureState.mCaptureVisitingBody = true;
  13241. closureState.mClosureInstanceInfo = closureInstanceInfo;
  13242. if ((mBfEvalExprFlags & BfEvalExprFlags_InferReturnType) != 0)
  13243. {
  13244. closureState.mReturnType = NULL;
  13245. closureState.mReturnTypeInferState = BfReturnTypeInferState_Inferring;
  13246. }
  13247. VisitLambdaBodies(lambdaBindExpr->mBody, lambdaBindExpr->mDtor);
  13248. if (hasExplicitCaptureNames)
  13249. _SetNotCapturedFlag(false);
  13250. // If we ended up being called by a method with a lower captureStartAccessId, propagate that to whoever is calling us, too...
  13251. if ((methodState.mPrevMethodState->mClosureState != NULL) && (methodState.mPrevMethodState->mClosureState->mCapturing))
  13252. {
  13253. auto prevClosureState = methodState.mPrevMethodState->mClosureState;
  13254. if (closureState.mCaptureStartAccessId < prevClosureState->mCaptureStartAccessId)
  13255. prevClosureState->mCaptureStartAccessId = closureState.mCaptureStartAccessId;
  13256. }
  13257. bool earlyExit = false;
  13258. if (isInferReturnType)
  13259. {
  13260. if ((closureState.mReturnTypeInferState == BfReturnTypeInferState_Fail) ||
  13261. (closureState.mReturnType == NULL))
  13262. {
  13263. mResult = BfTypedValue();
  13264. }
  13265. else
  13266. {
  13267. mResult = BfTypedValue(closureState.mReturnType);
  13268. }
  13269. earlyExit = true;
  13270. }
  13271. else if (mModule->mCurMethodInstance->mIsUnspecialized)
  13272. {
  13273. earlyExit = true;
  13274. mResult = mModule->GetDefaultTypedValue(delegateTypeInstance);
  13275. }
  13276. if (earlyExit)
  13277. {
  13278. prevIgnoreWrites.Restore();
  13279. mModule->mBfIRBuilder->RestoreDebugLocation();
  13280. mModule->mBfIRBuilder->SetActiveFunction(prevActiveFunction);
  13281. if (!prevInsertBlock.IsFake())
  13282. mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock);
  13283. delete methodDef;
  13284. delete closureInstanceInfo;
  13285. return NULL;
  13286. }
  13287. closureState.mCaptureVisitingBody = false;
  13288. prevIgnoreWrites.Restore();
  13289. mModule->mBfIRBuilder->RestoreDebugLocation();
  13290. auto _GetCaptureType = [&](const StringImpl& str, BfCaptureInfo::Entry** captureInfo = NULL)
  13291. {
  13292. if (allocTarget.mCaptureInfo->mCaptures.IsEmpty())
  13293. return BfCaptureType_Copy;
  13294. for (auto& captureEntry : allocTarget.mCaptureInfo->mCaptures)
  13295. {
  13296. if ((captureEntry.mNameNode == NULL) || (captureEntry.mNameNode->Equals(str)))
  13297. {
  13298. if (captureInfo != NULL)
  13299. *captureInfo = &captureEntry;
  13300. captureEntry.mUsed = true;
  13301. return captureEntry.mCaptureType;
  13302. }
  13303. }
  13304. return BfCaptureType_None;
  13305. };
  13306. Array<BfClosureCapturedEntry> capturedEntries;
  13307. bool copyOuterCaptures = false;
  13308. //
  13309. {
  13310. auto varMethodState = methodState.mPrevMethodState;
  13311. while (varMethodState != NULL)
  13312. {
  13313. for (int localIdx = 0; localIdx < varMethodState->mLocals.size(); localIdx++)
  13314. {
  13315. auto localVar = varMethodState->mLocals[localIdx];
  13316. if ((localVar->mReadFromId >= closureState.mCaptureStartAccessId) || (localVar->mWrittenToId >= closureState.mCaptureStartAccessId))
  13317. {
  13318. if ((localVar->mIsThis) && (outerClosure != NULL))
  13319. {
  13320. continue;
  13321. }
  13322. auto outerLocal = localVar;
  13323. if ((localVar->mConstValue) || (localVar->mResolvedType->IsValuelessType()))
  13324. {
  13325. closureState.mConstLocals.push_back(*outerLocal);
  13326. continue;
  13327. }
  13328. BfClosureCapturedEntry capturedEntry;
  13329. auto capturedType = outerLocal->mResolvedType;
  13330. bool captureByRef = false;
  13331. BfCaptureInfo::Entry* captureInfoEntry = NULL;
  13332. auto captureType = _GetCaptureType(localVar->mName, &captureInfoEntry);
  13333. if (captureType == BfCaptureType_None)
  13334. {
  13335. continue;
  13336. }
  13337. if (!capturedType->IsRef())
  13338. {
  13339. if (captureType == BfCaptureType_Reference)
  13340. {
  13341. if ((localVar->mIsThis) && (!localVar->mResolvedType->IsValueType()))
  13342. {
  13343. // Just ignore attempting to capture referencetype 'this' by reference
  13344. }
  13345. else
  13346. captureByRef = true;
  13347. }
  13348. else if (captureType == BfCaptureType_Auto)
  13349. {
  13350. if (localVar->mWrittenToId >= closureState.mCaptureStartAccessId)
  13351. captureByRef = true;
  13352. else if ((outerLocal->mResolvedType->mSize > 8) ||
  13353. ((localVar->mIsThis) && (outerLocal->mResolvedType->IsValueType())))
  13354. {
  13355. // Capture "large" values by reference
  13356. captureByRef = true;
  13357. }
  13358. }
  13359. }
  13360. else
  13361. {
  13362. bool allowRef = false;
  13363. if (captureType == BfCaptureType_Reference)
  13364. allowRef = true;
  13365. else if (captureType == BfCaptureType_Auto)
  13366. allowRef = localVar->mWrittenToId < closureState.mCaptureStartAccessId;
  13367. if (!allowRef)
  13368. {
  13369. capturedType = ((BfRefType*)capturedType)->mElementType;
  13370. }
  13371. }
  13372. if (captureByRef)
  13373. {
  13374. capturedType = mModule->CreateRefType(capturedType);
  13375. }
  13376. if (captureType != BfCaptureType_Copy)
  13377. capturedEntry.mExplicitlyByReference = true;
  13378. capturedEntry.mType = capturedType;
  13379. capturedEntry.mNameNode = outerLocal->mNameNode;
  13380. if (outerLocal->mName == "this")
  13381. capturedEntry.mName = "__this";
  13382. else
  13383. {
  13384. capturedEntry.mName = outerLocal->mName;
  13385. BfLocalVarEntry* entry = NULL;
  13386. if (varMethodState->mLocalVarSet.TryGetWith<StringImpl&>(capturedEntry.mName, &entry))
  13387. {
  13388. auto startCheckVar = entry->mLocalVar;
  13389. int shadowIdx = 0;
  13390. auto checkVar = startCheckVar;
  13391. while (checkVar != NULL)
  13392. {
  13393. if (checkVar == outerLocal)
  13394. {
  13395. // We only use mShadowIdx when we have duplicate name nodes (ie: in the case of for looks with iterator vs value)
  13396. auto shadowCheckVar = startCheckVar;
  13397. while (shadowCheckVar != checkVar)
  13398. {
  13399. if (shadowCheckVar->mNameNode == checkVar->mNameNode)
  13400. capturedEntry.mShadowIdx++;
  13401. shadowCheckVar = shadowCheckVar->mShadowedLocal;
  13402. }
  13403. for (int i = 0; i < shadowIdx; i++)
  13404. capturedEntry.mName.Insert(0, '@');
  13405. break;
  13406. }
  13407. shadowIdx++;
  13408. checkVar = checkVar->mShadowedLocal;
  13409. }
  13410. }
  13411. }
  13412. capturedEntries.Add(capturedEntry);
  13413. }
  13414. }
  13415. varMethodState = varMethodState->mPrevMethodState;
  13416. if (varMethodState == NULL)
  13417. break;
  13418. if (varMethodState->mMixinState != NULL)
  13419. break;
  13420. if (varMethodState->mClosureState != NULL)
  13421. {
  13422. if (!varMethodState->mClosureState->mCapturing)
  13423. break;
  13424. }
  13425. }
  13426. }
  13427. for (auto& captureEntry : allocTarget.mCaptureInfo->mCaptures)
  13428. {
  13429. if ((!captureEntry.mUsed) && (captureEntry.mNameNode != NULL))
  13430. mModule->Warn(0, "Capture specifier not used", captureEntry.mNameNode);
  13431. }
  13432. for (auto copyField : closureState.mReferencedOuterClosureMembers)
  13433. {
  13434. auto fieldDef = copyField->GetFieldDef();
  13435. auto captureType = _GetCaptureType(fieldDef->mName);
  13436. BfClosureCapturedEntry capturedEntry;
  13437. capturedEntry.mName = fieldDef->mName;
  13438. capturedEntry.mType = copyField->mResolvedType;
  13439. if ((captureType != BfCaptureType_Copy) && (capturedEntry.mType->IsRef()))
  13440. {
  13441. capturedEntry.mExplicitlyByReference = true;
  13442. }
  13443. else if ((captureType == BfCaptureType_Copy) && (capturedEntry.mType->IsRef()))
  13444. {
  13445. auto refType = (BfRefType*)capturedEntry.mType;
  13446. capturedEntry.mType = refType->mElementType;
  13447. }
  13448. else if ((captureType != BfCaptureType_Copy) && (!capturedEntry.mType->IsRef()) && (!fieldDef->mIsReadOnly))
  13449. {
  13450. capturedEntry.mType = mModule->CreateRefType(capturedEntry.mType);
  13451. }
  13452. }
  13453. std::sort(capturedEntries.begin(), capturedEntries.end());
  13454. bool hasCapture = false;
  13455. BfMethodInstanceGroup methodInstanceGroup;
  13456. methodInstanceGroup.mOwner = mModule->mCurTypeInstance;
  13457. methodInstanceGroup.mOnDemandKind = BfMethodOnDemandKind_AlwaysInclude;
  13458. BfMethodInstance* methodInstance = new BfMethodInstance();
  13459. methodInstance->mMethodInstanceGroup = &methodInstanceGroup;
  13460. methodInstance->GetMethodInfoEx()->mClosureInstanceInfo = closureInstanceInfo;
  13461. if (invokeMethodInstance != NULL)
  13462. methodInstance->mParams = invokeMethodInstance->mParams;
  13463. methodInstance->mIsClosure = true;
  13464. // We want the closure ID to match between hot reloads -- otherwise we wouldn't be able to modify them,
  13465. // so we use the charId from the 'fat arrow' token
  13466. int closureId = 0;
  13467. if (lambdaBindExpr->mFatArrowToken != NULL)
  13468. closureId = lambdaBindExpr->mFatArrowToken->GetStartCharId();
  13469. auto curProject = mModule->mCurTypeInstance->mTypeDef->mProject;
  13470. BF_ASSERT(curProject != NULL);
  13471. // We need to make these per-project even though you'd think we might not because we
  13472. // insert generic type specializations in the generic definition's project,
  13473. // BECAUSE: we would need to scan the captured fields the same way we scan the
  13474. // generic arguments to determine if each project can see it or not in the vdata
  13475. BfTypeInstance* useTypeInstance = delegateTypeInstance;
  13476. BfClosureType* closureTypeInst = NULL;
  13477. // 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
  13478. if ((capturedEntries.size() != 0) || (lambdaBindExpr->mDtor != NULL) || (copyOuterCaptures) || (mModule->mCompiler->mOptions.mAllowHotSwapping) || (closureState.mCapturedDelegateSelf))
  13479. {
  13480. hashCtx.MixinStr(curProject->mName);
  13481. if (copyOuterCaptures)
  13482. {
  13483. hashCtx.Mixin(outerClosure->mTypeId);
  13484. }
  13485. for (auto& capturedEntry : capturedEntries)
  13486. {
  13487. hashCtx.Mixin(capturedEntry.mType->mTypeId);
  13488. hashCtx.MixinStr(capturedEntry.mName);
  13489. hashCtx.Mixin(capturedEntry.mExplicitlyByReference);
  13490. }
  13491. if (lambdaBindExpr->mDtor != NULL)
  13492. {
  13493. // Has DTOR thunk
  13494. bool hasDtorThunk = true;
  13495. hashCtx.Mixin(hasDtorThunk);
  13496. }
  13497. Val128 hash128 = hashCtx.Finish128();
  13498. BfClosureType* checkClosureType = new BfClosureType(delegateTypeInstance, hash128);
  13499. checkClosureType->mContext = mModule->mContext;
  13500. checkClosureType->mBaseType = delegateTypeInstance;
  13501. BfType* resolvedClosureType = mModule->ResolveType(checkClosureType, BfPopulateType_TypeDef);
  13502. closureTypeInst = (BfClosureType*)resolvedClosureType;
  13503. if (checkClosureType == resolvedClosureType)
  13504. {
  13505. // This is a new closure type
  13506. closureTypeInst->Init(curProject);
  13507. closureTypeInst->mTypeDef->mProject = curProject;
  13508. auto delegateDirectTypeRef = BfAstNode::ZeroedAlloc<BfDirectTypeDefReference>();
  13509. delegateDirectTypeRef->Init(mModule->mCompiler->mDelegateTypeDef);
  13510. closureTypeInst->mDirectAllocNodes.push_back(delegateDirectTypeRef);
  13511. BfMethodDef* methodDef = BfDefBuilder::AddMethod(closureTypeInst->mTypeDef, BfMethodType_Normal, BfProtection_Public, false, "Equals");
  13512. methodDef->mReturnTypeRef = mModule->mSystem->mDirectBoolTypeRef;
  13513. BfDefBuilder::AddParam(methodDef, delegateDirectTypeRef, "val");
  13514. methodDef->mIsVirtual = true;
  13515. methodDef->mIsOverride = true;
  13516. if (copyOuterCaptures)
  13517. {
  13518. for (auto& fieldInstance : outerClosure->mFieldInstances)
  13519. {
  13520. BfFieldDef* origFieldDef = fieldInstance.GetFieldDef();
  13521. BfFieldDef* fieldDef = closureTypeInst->AddField(fieldInstance.mResolvedType, origFieldDef->mName);
  13522. fieldDef->mIsReadOnly = origFieldDef->mIsReadOnly;
  13523. }
  13524. }
  13525. for (auto& capturedEntry : capturedEntries)
  13526. {
  13527. BfFieldDef* fieldDef = closureTypeInst->AddField(capturedEntry.mType, capturedEntry.mName);
  13528. if (!capturedEntry.mExplicitlyByReference)
  13529. fieldDef->mIsReadOnly = true;
  13530. }
  13531. if (lambdaBindExpr->mDtor != NULL)
  13532. {
  13533. auto dtorDef = closureTypeInst->AddDtor();
  13534. auto voidType = mModule->GetPrimitiveType(BfTypeCode_None);
  13535. auto voidPtrType = mModule->CreatePointerType(voidType);
  13536. closureTypeInst->AddField(voidPtrType, "__dtorThunk");
  13537. }
  13538. closureTypeInst->Finish();
  13539. }
  13540. else
  13541. {
  13542. // Already had this entry
  13543. delete checkClosureType;
  13544. }
  13545. useTypeInstance = closureTypeInst;
  13546. }
  13547. mModule->mBfIRBuilder->PopulateType(useTypeInstance);
  13548. mModule->PopulateType(useTypeInstance);
  13549. methodDef->mIsStatic = closureTypeInst == NULL;
  13550. SizedArray<BfIRType, 8> origParamTypes;
  13551. BfIRType origReturnType;
  13552. bool forceStatic = false;
  13553. if (invokeMethodInstance != NULL)
  13554. {
  13555. forceStatic = methodDef->mIsStatic;
  13556. auto invokeFunctionType = mModule->mBfIRBuilder->MapMethod(invokeMethodInstance);
  13557. invokeMethodInstance->GetIRFunctionInfo(mModule, origReturnType, origParamTypes, forceStatic);
  13558. }
  13559. else
  13560. {
  13561. origReturnType = mModule->mBfIRBuilder->MapType(mModule->GetPrimitiveType(BfTypeCode_None));
  13562. }
  13563. SizedArray<BfIRType, 3> newTypes;
  13564. if ((invokeMethodInstance != NULL) && (GetStructRetIdx(invokeMethodInstance, forceStatic) == 0))
  13565. newTypes.push_back(origParamTypes[0]);
  13566. if (!methodDef->mIsStatic)
  13567. newTypes.push_back(mModule->mBfIRBuilder->MapType(useTypeInstance));
  13568. if ((invokeMethodInstance != NULL) && (GetStructRetIdx(invokeMethodInstance, forceStatic) == 1))
  13569. newTypes.push_back(origParamTypes[1]);
  13570. int paramStartIdx = 0;
  13571. if ((invokeMethodInstance != NULL) && (GetStructRetIdx(invokeMethodInstance, forceStatic) != -1))
  13572. paramStartIdx++;
  13573. if (!methodDef->mIsStatic)
  13574. paramStartIdx++;
  13575. for (int i = paramStartIdx; i < (int)origParamTypes.size(); i++)
  13576. newTypes.push_back(origParamTypes[i]);
  13577. auto closureFuncType = mModule->mBfIRBuilder->CreateFunctionType(origReturnType, newTypes, false);
  13578. prevMethodState.Restore();
  13579. mModule->mBfIRBuilder->SetActiveFunction(prevActiveFunction);
  13580. if ((prevInsertBlock) && (!prevInsertBlock.IsFake()))
  13581. mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock);
  13582. // Just a check
  13583. mModule->mBfIRBuilder->GetInsertBlock();
  13584. //auto rootMethodState = mModule->mCurMethodState;
  13585. HashContext closureHashCtx;
  13586. closureHashCtx.Mixin(closureId);
  13587. // When we're a nested lambda, strip off the outer hash and closureTypeInst markers
  13588. methodDef->mName = mModule->mCurMethodInstance->mMethodDef->mName;
  13589. int prevSepPos = (int)methodDef->mName.LastIndexOf('$');
  13590. if (prevSepPos != -1)
  13591. {
  13592. closureHashCtx.Mixin(methodDef->mName.c_str() + prevSepPos, (int)methodDef->mName.length() - prevSepPos);
  13593. methodDef->mName.RemoveToEnd(prevSepPos);
  13594. }
  13595. // Mix in this because this can be emitted multiple times when there's multiple ctors and field initializers with lambdas
  13596. if (mModule->mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_Ctor)
  13597. {
  13598. if (auto ctorDecl = BfNodeDynCast<BfConstructorDeclaration>(mModule->mCurMethodInstance->mMethodDef->mMethodDeclaration))
  13599. {
  13600. if (ctorDecl->mThisToken != NULL)
  13601. closureHashCtx.Mixin(ctorDecl->mThisToken->GetStartCharId());
  13602. }
  13603. }
  13604. auto checkMethodState = mModule->mCurMethodState;
  13605. while (checkMethodState != NULL)
  13606. {
  13607. if (checkMethodState->mMethodInstance != NULL)
  13608. {
  13609. if (checkMethodState->mMethodInstance->mMethodInfoEx != NULL)
  13610. {
  13611. for (auto methodGenericArg : checkMethodState->mMethodInstance->mMethodInfoEx->mMethodGenericArguments)
  13612. {
  13613. StringT<128> genericTypeName;
  13614. BfMangler::Mangle(genericTypeName, mModule->mCompiler->GetMangleKind(), methodGenericArg);
  13615. closureHashCtx.MixinStr(genericTypeName);
  13616. }
  13617. }
  13618. }
  13619. checkMethodState = checkMethodState->mPrevMethodState;
  13620. }
  13621. uint64 closureHash = closureHashCtx.Finish64();
  13622. methodDef->mName += "$";
  13623. methodDef->mName += BfTypeUtils::HashEncode64(closureHash);
  13624. methodInstance->mMethodDef = methodDef;
  13625. if (invokeMethodInstance != NULL)
  13626. {
  13627. methodInstance->mParams = invokeMethodInstance->mParams;
  13628. methodInstance->mReturnType = invokeMethodInstance->mReturnType;
  13629. }
  13630. else
  13631. methodInstance->mReturnType = mModule->GetPrimitiveType(BfTypeCode_None);
  13632. StringT<128> closureFuncName;
  13633. BfMangler::Mangle(closureFuncName, mModule->mCompiler->GetMangleKind(), methodInstance);
  13634. auto closureFunc = mModule->mBfIRBuilder->CreateFunction(closureFuncType, BfIRLinkageType_External, closureFuncName);
  13635. methodInstance->mIRFunction = closureFunc;
  13636. if (methodInstance->mIsReified)
  13637. mModule->CheckHotMethod(methodInstance, closureFuncName);
  13638. if ((methodInstance->mHotMethod != NULL) && (mModule->mCurMethodState->mHotDataReferenceBuilder))
  13639. mModule->mCurMethodState->mHotDataReferenceBuilder->mInnerMethods.Add(methodInstance->mHotMethod);
  13640. methodState.Reset();
  13641. lambdaInstance = new BfLambdaInstance();
  13642. rootMethodState->mLambdaCache[cacheNodeList] = lambdaInstance;
  13643. lambdaInstance->mDelegateTypeInstance = delegateTypeInstance;
  13644. lambdaInstance->mUseTypeInstance = useTypeInstance;
  13645. lambdaInstance->mClosureTypeInstance = closureTypeInst;
  13646. lambdaInstance->mOuterClosure = outerClosure;
  13647. lambdaInstance->mCopyOuterCaptures = copyOuterCaptures;
  13648. lambdaInstance->mDeclaringMethodIsMutating = mModule->mCurMethodInstance->mMethodDef->mIsMutating;
  13649. lambdaInstance->mIsStatic = methodDef->mIsStatic;
  13650. lambdaInstance->mClosureFunc = closureFunc;
  13651. lambdaInstance->mMethodInstance = methodInstance;
  13652. lambdaInstance->mConstLocals = closureState.mConstLocals;
  13653. lambdaInstance->mParamDecls = tempParamDecls;
  13654. lambdaInstance->mDeclMixinState = mModule->mCurMethodState->mMixinState;
  13655. if (lambdaInstance->mDeclMixinState != NULL)
  13656. lambdaInstance->mDeclMixinState->mHasDeferredUsage = true;
  13657. tempParamDecls.ClearWithoutDeleting();
  13658. closureState.mCapturing = false;
  13659. closureState.mClosureType = useTypeInstance;
  13660. closureInstanceInfo->mThisOverride = useTypeInstance;
  13661. mModule->mIncompleteMethodCount++;
  13662. SetAndRestoreValue<BfClosureState*> prevClosureState(mModule->mCurMethodState->mClosureState, &closureState);
  13663. if (mModule->HasExecutedOutput())
  13664. mModule->SetupIRMethod(methodInstance, methodInstance->mIRFunction, methodInstance->mAlwaysInline);
  13665. // This keeps us from giving errors twice. ProcessMethod can give errors when we capture by value but needed to
  13666. // capture by reference, so we still need to do it for resolve-only
  13667. bool processMethods = (mModule->mCompiler->GetAutoComplete() == NULL) && !mModule->mHadBuildError;
  13668. mModule->mBfIRBuilder->SaveDebugLocation();
  13669. //
  13670. {
  13671. BfGetSymbolReferenceKind prevSymbolRefKind = BfGetSymbolReferenceKind_None;
  13672. if (mModule->mCompiler->mResolvePassData != NULL)
  13673. {
  13674. prevSymbolRefKind = mModule->mCompiler->mResolvePassData->mGetSymbolReferenceKind;
  13675. mModule->mCompiler->mResolvePassData->mGetSymbolReferenceKind = BfGetSymbolReferenceKind_None;
  13676. }
  13677. if (processMethods)
  13678. {
  13679. // If we are in an always-ignored block, we will have mIgnoreWrites set
  13680. // SetAndRestoreValue<bool> prevWantsIgnoreWrite(mModule->mWantsIRIgnoreWrites, mModule->mBfIRBuilder->mIgnoreWrites);
  13681. // mModule->ProcessMethod(methodInstance);
  13682. }
  13683. if (mModule->mCompiler->mResolvePassData != NULL)
  13684. mModule->mCompiler->mResolvePassData->mGetSymbolReferenceKind = prevSymbolRefKind;
  13685. }
  13686. mModule->mBfIRBuilder->RestoreDebugLocation();
  13687. if (mModule->IsSkippingExtraResolveChecks())
  13688. closureFunc = BfIRFunction();
  13689. BfIRFunction dtorFunc;
  13690. if (lambdaBindExpr->mDtor != NULL)
  13691. {
  13692. SizedArray<BfIRType, 1> newTypes;
  13693. newTypes.push_back(mModule->mBfIRBuilder->MapType(useTypeInstance));
  13694. auto voidType = mModule->GetPrimitiveType(BfTypeCode_None);
  13695. auto dtorFuncType = mModule->mBfIRBuilder->CreateFunctionType(mModule->mBfIRBuilder->MapType(voidType), newTypes, false);
  13696. BfMethodDef* dtorMethodDef = new BfMethodDef();
  13697. dtorMethodDef->mDeclaringType = mModule->mCurMethodInstance->mMethodDef->mDeclaringType;
  13698. dtorMethodDef->mName = "~this$";
  13699. dtorMethodDef->mName += methodDef->mName;
  13700. dtorMethodDef->mMethodType = BfMethodType_Normal;
  13701. dtorMethodDef->mBody = lambdaBindExpr->mDtor;
  13702. dtorMethodDef->mIdx = mModule->mCurMethodInstance->mMethodDef->mIdx;
  13703. BfMethodInstance* dtorMethodInstance = new BfMethodInstance();
  13704. dtorMethodInstance->mMethodDef = dtorMethodDef;
  13705. dtorMethodInstance->mReturnType = mModule->GetPrimitiveType(BfTypeCode_None);
  13706. dtorMethodInstance->mMethodInstanceGroup = &methodInstanceGroup;
  13707. StringT<128> dtorMangledName;
  13708. BfMangler::Mangle(dtorMangledName, mModule->mCompiler->GetMangleKind(), dtorMethodInstance);
  13709. dtorFunc = mModule->mBfIRBuilder->CreateFunction(dtorFuncType, BfIRLinkageType_External, dtorMangledName);
  13710. mModule->SetupIRMethod(NULL, dtorFunc, false);
  13711. dtorMethodInstance->mIRFunction = dtorFunc;
  13712. mModule->mIncompleteMethodCount++;
  13713. mModule->mBfIRBuilder->SaveDebugLocation();
  13714. //
  13715. if (processMethods)
  13716. {
  13717. // If we are in an always-ignored block, we will have mIgnoreWrites set
  13718. // SetAndRestoreValue<bool> prevWantsIgnoreWrite(mModule->mWantsIRIgnoreWrites, mModule->mBfIRBuilder->mIgnoreWrites);
  13719. // mModule->ProcessMethod(dtorMethodInstance);
  13720. }
  13721. mModule->mBfIRBuilder->RestoreDebugLocation();
  13722. if (mModule->IsSkippingExtraResolveChecks())
  13723. dtorFunc = BfIRFunction();
  13724. if (dtorMethodInstance->mIsReified)
  13725. mModule->CheckHotMethod(dtorMethodInstance, dtorMangledName);
  13726. if ((dtorMethodInstance->mHotMethod != NULL) && (mModule->mCurMethodState->mHotDataReferenceBuilder))
  13727. mModule->mCurMethodState->mHotDataReferenceBuilder->mInnerMethods.Add(dtorMethodInstance->mHotMethod);
  13728. lambdaInstance->mDtorMethodInstance = dtorMethodInstance;
  13729. lambdaInstance->mDtorFunc = dtorFunc;
  13730. dtorMethodInstance->mMethodInstanceGroup = NULL;
  13731. }
  13732. prevClosureState.Restore();
  13733. if ((prevInsertBlock) && (!prevInsertBlock.IsFake()))
  13734. mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock);
  13735. for (auto& capturedEntry : capturedEntries)
  13736. {
  13737. BfLambdaCaptureInfo lambdaCapture;
  13738. if (capturedEntry.mName == "__this")
  13739. lambdaCapture.mName = "this";
  13740. else
  13741. lambdaCapture.mName = capturedEntry.mName;
  13742. lambdaInstance->mCaptures.Add(lambdaCapture);
  13743. closureInstanceInfo->mCaptureEntries.Add(capturedEntry);
  13744. }
  13745. if (processMethods)
  13746. rootMethodState->mDeferredLambdaInstances.Add(lambdaInstance);
  13747. methodInstance->mMethodInstanceGroup = NULL;
  13748. return lambdaInstance;
  13749. }
  13750. void BfExprEvaluator::Visit(BfLambdaBindExpression* lambdaBindExpr)
  13751. {
  13752. BfTokenNode* newToken = NULL;
  13753. BfCaptureInfo captureInfo;
  13754. BfAllocTarget allocTarget;
  13755. allocTarget.mCaptureInfo = &captureInfo;
  13756. ResolveAllocTarget(allocTarget, lambdaBindExpr->mNewToken, newToken);
  13757. if (mModule->mCurMethodInstance == NULL)
  13758. mModule->Fail("Invalid use of lambda bind expression", lambdaBindExpr);
  13759. if (((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mBlindCapturing)) ||
  13760. (mModule->mCurMethodInstance == NULL))
  13761. {
  13762. // We're just capturing. We just need to visit the bodies here. This helps infinite recursion with local methods containing lambdas calling each other
  13763. if (lambdaBindExpr->mBody != NULL)
  13764. mModule->VisitChild(lambdaBindExpr->mBody);
  13765. if ((lambdaBindExpr->mDtor != NULL) && (lambdaBindExpr->mDtor->mBody != NULL))
  13766. mModule->VisitChild(lambdaBindExpr->mDtor->mBody);
  13767. return;
  13768. }
  13769. BfLambdaInstance* lambdaInstance = GetLambdaInstance(lambdaBindExpr, allocTarget);
  13770. if (lambdaInstance == NULL)
  13771. return;
  13772. BfTypeInstance* delegateTypeInstance = lambdaInstance->mDelegateTypeInstance;
  13773. BfTypeInstance* useTypeInstance = lambdaInstance->mUseTypeInstance;
  13774. BfTypeInstance* closureTypeInst = lambdaInstance->mClosureTypeInstance;
  13775. mResult = BfTypedValue(mModule->AllocFromType(useTypeInstance, allocTarget, BfIRValue(), BfIRValue(), 0, BfAllocFlags_None), useTypeInstance);
  13776. if (!delegateTypeInstance->IsDelegate())
  13777. {
  13778. mModule->AssertErrorState();
  13779. return;
  13780. }
  13781. auto baseDelegateType = VerifyBaseDelegateType(delegateTypeInstance->mBaseType);
  13782. if (baseDelegateType == NULL)
  13783. {
  13784. mModule->Fail("Invalid delegate type", lambdaBindExpr);
  13785. return;
  13786. }
  13787. mModule->PopulateType(baseDelegateType);
  13788. auto& funcPtrField = baseDelegateType->mFieldInstances[0];
  13789. auto& targetField = baseDelegateType->mFieldInstances[1];
  13790. auto baseDelegate = mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->MapType(baseDelegateType));
  13791. // >> delegate.mTarget = bindResult.mTarget
  13792. auto nullPtrType = mModule->GetPrimitiveType(BfTypeCode_NullPtr);
  13793. BfIRValue valPtr;
  13794. if (!lambdaInstance->mIsStatic)
  13795. valPtr = mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->MapType(nullPtrType));
  13796. else
  13797. valPtr = mModule->GetDefaultValue(nullPtrType);
  13798. auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(baseDelegate, 0, targetField.mDataIdx);
  13799. mModule->mBfIRBuilder->CreateAlignedStore(valPtr, fieldPtr, targetField.mResolvedType->mAlign);
  13800. // >> delegate.mFuncPtr = bindResult.mFunc
  13801. if (lambdaInstance->mClosureFunc)
  13802. {
  13803. auto nullPtrType = mModule->GetPrimitiveType(BfTypeCode_NullPtr);
  13804. auto valPtr = mModule->mBfIRBuilder->CreateBitCast(lambdaInstance->mClosureFunc, mModule->mBfIRBuilder->MapType(nullPtrType));
  13805. auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(baseDelegate, 0, funcPtrField.mDataIdx);
  13806. mModule->mBfIRBuilder->CreateAlignedStore(valPtr, fieldPtr, funcPtrField.mResolvedType->mAlign);
  13807. }
  13808. mModule->AddDependency(useTypeInstance, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_Calls);
  13809. // Copy captures into the delegate
  13810. if (lambdaInstance->mClosureTypeInstance != NULL)
  13811. {
  13812. int fieldIdx = 0;
  13813. if (lambdaInstance->mCopyOuterCaptures)
  13814. {
  13815. for (auto& fieldInstance : lambdaInstance->mOuterClosure->mFieldInstances)
  13816. {
  13817. if (!fieldInstance.mResolvedType->IsValuelessType())
  13818. {
  13819. BF_ASSERT(fieldInstance.mDataIdx == fieldIdx + 1);
  13820. auto localVar = mModule->mCurMethodState->mLocals[0];
  13821. auto capturedValue = mModule->mBfIRBuilder->CreateInBoundsGEP(localVar->mValue, 0, fieldInstance.mDataIdx);
  13822. capturedValue = mModule->mBfIRBuilder->CreateAlignedLoad(capturedValue, fieldInstance.mResolvedType->mAlign);
  13823. auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(mResult.mValue, 0, fieldInstance.mDataIdx);
  13824. mModule->mBfIRBuilder->CreateStore(capturedValue, fieldPtr);
  13825. fieldIdx++;
  13826. }
  13827. }
  13828. }
  13829. int captureIdx = 0;
  13830. for (int captureIdx = 0; captureIdx < (int)lambdaInstance->mCaptures.size(); captureIdx++)
  13831. {
  13832. auto& capturedEntry = lambdaInstance->mCaptures[captureIdx];
  13833. auto& closureCaptureEntry = lambdaInstance->mMethodInstance->mMethodInfoEx->mClosureInstanceInfo->mCaptureEntries[captureIdx];
  13834. BfIdentifierNode* identifierNode = closureCaptureEntry.mNameNode;
  13835. BfIRValue capturedValue;
  13836. auto fieldInstance = &closureTypeInst->mFieldInstances[fieldIdx];
  13837. BfTypedValue capturedTypedVal;
  13838. if (identifierNode != NULL)
  13839. capturedTypedVal = DoImplicitArgCapture(NULL, identifierNode, closureCaptureEntry.mShadowIdx);
  13840. else
  13841. capturedTypedVal = LookupIdentifier(NULL, capturedEntry.mName);
  13842. if (!fieldInstance->mResolvedType->IsRef())
  13843. capturedTypedVal = mModule->LoadOrAggregateValue(capturedTypedVal);
  13844. else if (!capturedTypedVal.IsAddr())
  13845. capturedTypedVal = mModule->MakeAddressable(capturedTypedVal, false, true);
  13846. capturedValue = capturedTypedVal.mValue;
  13847. if (capturedValue)
  13848. {
  13849. if (!IsVar(capturedTypedVal.mType))
  13850. {
  13851. auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(mResult.mValue, 0, fieldInstance->mDataIdx);
  13852. mModule->mBfIRBuilder->CreateAlignedStore(capturedValue, fieldPtr, fieldInstance->mResolvedType->mAlign);
  13853. }
  13854. }
  13855. else
  13856. {
  13857. mModule->Fail(StrFormat("Unable to capture '%s'", capturedEntry.mName.c_str()), lambdaBindExpr);
  13858. mModule->AssertErrorState();
  13859. }
  13860. fieldIdx++;
  13861. }
  13862. if (lambdaInstance->mDtorFunc)
  13863. {
  13864. auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(mResult.mValue, 0, closureTypeInst->mFieldInstances[fieldIdx].mDataIdx);
  13865. auto voidType = mModule->GetPrimitiveType(BfTypeCode_None);
  13866. auto voidPtrType = mModule->CreatePointerType(voidType);
  13867. auto dtorThunk = mModule->mBfIRBuilder->CreateBitCast(lambdaInstance->mDtorFunc, mModule->mBfIRBuilder->MapType(voidPtrType));
  13868. mModule->mBfIRBuilder->CreateAlignedStore(dtorThunk, fieldPtr, mModule->mSystem->mPtrSize);
  13869. fieldIdx++;
  13870. }
  13871. }
  13872. }
  13873. void BfExprEvaluator::ProcessArrayInitializer(BfTokenNode* openToken, const BfSizedArray<BfExpression*>& valueExprs, const BfSizedArray<BfTokenNode*>& commas, BfTokenNode* closeToken, int dimensions, SizedArrayImpl<int64>& dimLengths, int dim, bool& hasFailed)
  13874. {
  13875. bool setSize = false;
  13876. if (dim == dimLengths.size())
  13877. {
  13878. dimLengths.push_back((int)valueExprs.size());
  13879. setSize = true;
  13880. }
  13881. else if (dimLengths[dim] == -1)
  13882. {
  13883. dimLengths[dim] = (int)valueExprs.size();
  13884. setSize = true;
  13885. }
  13886. int64 initCountDiff = (int)valueExprs.size() - dimLengths[dim];
  13887. if ((dimLengths[dim] != -1) && (initCountDiff != 0) && (!hasFailed))
  13888. {
  13889. if (initCountDiff > 0)
  13890. {
  13891. mModule->Fail(StrFormat("Too many initializers, expected %d fewer", initCountDiff), valueExprs[(int)dimLengths[dim]]);
  13892. hasFailed = true;
  13893. }
  13894. else
  13895. {
  13896. // If it ends with ", ?) or ",)" then allow unsized
  13897. if (((valueExprs.size() == 0) || (BfNodeDynCast<BfUninitializedExpression>(valueExprs.back()) == NULL)) &&
  13898. (commas.size() < valueExprs.size()))
  13899. {
  13900. BfAstNode* refNode = closeToken;
  13901. if ((refNode == NULL) && (mModule->mParentNodeEntry != NULL))
  13902. refNode = mModule->mParentNodeEntry->mNode;
  13903. mModule->Fail(StrFormat("Too few initializer, expected %d more", -initCountDiff), refNode);
  13904. hasFailed = true;
  13905. }
  13906. }
  13907. }
  13908. for (int i = 0; i < (int)valueExprs.size(); i++)
  13909. {
  13910. BfExpression* expr = valueExprs[i];
  13911. if (auto uninitExpr = BfNodeDynCast<BfUninitializedExpression>(expr))
  13912. {
  13913. continue;
  13914. }
  13915. auto innerInitExpr = BfNodeDynCast<BfCollectionInitializerExpression>(expr);
  13916. if (dim < dimensions - 1)
  13917. {
  13918. if (innerInitExpr == NULL)
  13919. {
  13920. if (auto innerTupleExpr = BfNodeDynCast<BfTupleExpression>(expr))
  13921. {
  13922. ProcessArrayInitializer(innerTupleExpr->mOpenParen, innerTupleExpr->mValues, innerTupleExpr->mCommas, innerTupleExpr->mCloseParen, dimensions, dimLengths, dim + 1, hasFailed);
  13923. }
  13924. else if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(expr))
  13925. {
  13926. SizedArray<BfExpression*, 1> values;
  13927. values.Add(parenExpr->mExpression);
  13928. SizedArray<BfTokenNode*, 1> commas;
  13929. ProcessArrayInitializer(parenExpr->mOpenParen, values, commas, parenExpr->mCloseParen, dimensions, dimLengths, dim + 1, hasFailed);
  13930. }
  13931. else
  13932. {
  13933. hasFailed = true;
  13934. mModule->Fail("A nested array initializer is expected", expr);
  13935. continue;
  13936. }
  13937. }
  13938. else
  13939. ProcessArrayInitializer(innerInitExpr->mOpenBrace, innerInitExpr->mValues, innerInitExpr->mCommas, innerInitExpr->mCloseBrace, dimensions, dimLengths, dim + 1, hasFailed);
  13940. }
  13941. else if (innerInitExpr != NULL)
  13942. {
  13943. hasFailed = true;
  13944. mModule->Fail("Unexpected nested initializer", expr);
  13945. ProcessArrayInitializer(innerInitExpr->mOpenBrace, innerInitExpr->mValues, innerInitExpr->mCommas, innerInitExpr->mCloseBrace, dimensions, dimLengths, dim + 1, hasFailed);
  13946. }
  13947. else
  13948. {
  13949. //mModule->Fail("Expected initializer", )
  13950. }
  13951. }
  13952. }
  13953. void BfExprEvaluator::CheckObjectCreateTypeRef(BfType* expectingType, BfAstNode* afterNode)
  13954. {
  13955. auto autoComplete = GetAutoComplete();
  13956. if ((autoComplete != NULL) && (afterNode != NULL) && (autoComplete->mIsAutoComplete) &&
  13957. (afterNode->IsFromParser(mModule->mCompiler->mResolvePassData->mParsers[0])) &&
  13958. (afterNode->GetParser()->mCursorIdx == afterNode->GetSrcEnd() + 1))
  13959. {
  13960. BfType* expectingType = mExpectingType;
  13961. BfTypeInstance* expectingTypeInst = NULL;
  13962. if (mExpectingType != NULL)
  13963. {
  13964. expectingTypeInst = mExpectingType->ToTypeInstance();
  13965. }
  13966. if ((mExpectingType != NULL) && (((expectingTypeInst == NULL) || (!expectingTypeInst->mTypeDef->mIsDelegate))))
  13967. {
  13968. // Why were we doing this? It floods the autocomplete with every possible type
  13969. //autoComplete->AddTopLevelTypes(NULL);
  13970. autoComplete->mInsertStartIdx = afterNode->GetSourceData()->ToParser()->mCursorIdx;
  13971. BF_ASSERT(autoComplete->mInsertStartIdx != -1);
  13972. auto expectingType = mExpectingType;
  13973. while (expectingType->IsArray())
  13974. {
  13975. auto arrayType = (BfArrayType*)expectingType;
  13976. expectingType = arrayType->mGenericTypeInfo->mTypeGenericArguments[0];
  13977. }
  13978. auto expectingTypeInst = expectingType->ToTypeInstance();
  13979. if (expectingTypeInst != NULL)
  13980. {
  13981. if (!expectingTypeInst->IsAnonymous())
  13982. autoComplete->AddTypeInstanceEntry(expectingTypeInst);
  13983. }
  13984. else
  13985. autoComplete->mDefaultSelection = mModule->TypeToString(expectingType);
  13986. }
  13987. }
  13988. }
  13989. void BfExprEvaluator::Visit(BfObjectCreateExpression* objCreateExpr)
  13990. {
  13991. CreateObject(objCreateExpr, objCreateExpr->mNewNode, NULL, NULL);
  13992. }
  13993. void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAstNode* allocNode, BfType* wantAllocType, BfInlineTypeReference* inlineTypeRef)
  13994. {
  13995. auto autoComplete = GetAutoComplete();
  13996. if ((autoComplete != NULL) && (objCreateExpr != NULL) && (objCreateExpr->mTypeRef != NULL))
  13997. {
  13998. autoComplete->CheckTypeRef(objCreateExpr->mTypeRef, false, true);
  13999. }
  14000. if ((autoComplete != NULL) && (objCreateExpr != NULL) && (objCreateExpr->mOpenToken != NULL) && (objCreateExpr->mCloseToken != NULL) &&
  14001. (objCreateExpr->mOpenToken->mToken == BfToken_LBrace) && (autoComplete->CheckFixit(objCreateExpr->mOpenToken)))
  14002. {
  14003. auto refNode = objCreateExpr->mOpenToken;
  14004. BfParserData* parser = refNode->GetSourceData()->ToParserData();
  14005. if (parser != NULL)
  14006. {
  14007. autoComplete->AddEntry(AutoCompleteEntry("fixit", StrFormat("Change initializer braces to parentheses\treformat|%s|%d-1|(\x01|%s|%d-1|)",
  14008. parser->mFileName.c_str(), refNode->mSrcStart,
  14009. parser->mFileName.c_str(), objCreateExpr->mCloseToken->mSrcStart).c_str()));
  14010. }
  14011. }
  14012. BfMethodGenericArguments methodGenericArguments;
  14013. if ((objCreateExpr != NULL) && (objCreateExpr->mCtorExplicit != NULL) && (objCreateExpr->mCtorExplicit->mGenericArgs != NULL))
  14014. methodGenericArguments.mArguments = &objCreateExpr->mCtorExplicit->mGenericArgs->mGenericArgs;
  14015. CheckObjectCreateTypeRef(mExpectingType, allocNode);
  14016. BfAttributeState attributeState;
  14017. attributeState.mTarget = BfAttributeTargets_Alloc;
  14018. SetAndRestoreValue<BfAttributeState*> prevAttributeState(mModule->mAttributeState, &attributeState);
  14019. BfTokenNode* newToken = NULL;
  14020. BfAllocTarget allocTarget;
  14021. ResolveAllocTarget(allocTarget, allocNode, newToken, &attributeState.mCustomAttributes);
  14022. bool isStructAlloc = newToken == NULL;
  14023. bool isScopeAlloc = (newToken != NULL) && (newToken->GetToken() == BfToken_Scope);
  14024. bool isAppendAlloc = (newToken != NULL) && (newToken->GetToken() == BfToken_Append);
  14025. bool isStackAlloc = (isScopeAlloc) || (isStructAlloc);
  14026. bool isArrayAlloc = false;// (objCreateExpr->mArraySizeSpecifier != NULL);
  14027. bool isRawArrayAlloc = (objCreateExpr != NULL) && (objCreateExpr->mStarToken != NULL);
  14028. if ((objCreateExpr != NULL) && (objCreateExpr->mCtorExplicit != NULL) && (objCreateExpr->mCtorExplicit->mThisToken != NULL))
  14029. {
  14030. mModule->SetElementType(objCreateExpr->mCtorExplicit->mThisToken, BfSourceElementType_Method);
  14031. }
  14032. if (isScopeAlloc)
  14033. {
  14034. if ((mBfEvalExprFlags & BfEvalExprFlags_FieldInitializer) != 0)
  14035. {
  14036. mModule->Warn(0, "This allocation will only be in scope during the constructor. Consider using a longer-term allocation such as 'new'", allocNode);
  14037. }
  14038. if (allocNode == newToken) // Scope, no target specified
  14039. {
  14040. if (mModule->mParentNodeEntry != NULL)
  14041. {
  14042. if (auto assignExpr = BfNodeDynCastExact<BfAssignmentExpression>(mModule->mParentNodeEntry->mNode))
  14043. {
  14044. if (mModule->mCurMethodState->mCurScope->mCloseNode == NULL)
  14045. {
  14046. // 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
  14047. if ((mBfEvalExprFlags & BfEvalExprFlags_PendingPropSet) == 0)
  14048. mModule->Warn(0, "This allocation will immediately go out of scope. Consider specifying a wider scope target such as 'scope::'", allocNode);
  14049. }
  14050. }
  14051. }
  14052. }
  14053. }
  14054. BfAutoParentNodeEntry autoParentNodeEntry(mModule, objCreateExpr);
  14055. SizedArray<BfAstNode*, 2> dimLengthRefs;
  14056. SizedArray<BfIRValue, 2> dimLengthVals;
  14057. BfArrayType* arrayType = NULL;
  14058. BfType* unresolvedTypeRef = NULL;
  14059. BfType* resolvedTypeRef = NULL;
  14060. if (wantAllocType != NULL)
  14061. {
  14062. unresolvedTypeRef = wantAllocType;
  14063. resolvedTypeRef = wantAllocType;
  14064. }
  14065. else if (objCreateExpr->mTypeRef == NULL)
  14066. {
  14067. if ((!mExpectingType) || (!mExpectingType->IsArray()))
  14068. {
  14069. mModule->Fail("Cannot imply array type. Explicitly state array type or use array in an assignment to an array type.", objCreateExpr);
  14070. resolvedTypeRef = mModule->mContext->mBfObjectType;
  14071. unresolvedTypeRef = resolvedTypeRef;
  14072. }
  14073. else
  14074. {
  14075. auto arrayType = (BfArrayType*)mExpectingType;
  14076. unresolvedTypeRef = arrayType->GetUnderlyingType();
  14077. resolvedTypeRef = unresolvedTypeRef;
  14078. }
  14079. }
  14080. else
  14081. {
  14082. if ((objCreateExpr->mTypeRef->IsExact<BfDotTypeReference>()) && (mExpectingType != NULL))
  14083. {
  14084. //mModule->SetElementType(objCreateExpr->mTypeRef, BfSourceElementType_TypeRef);
  14085. if ((mExpectingType->IsObject()) || (mExpectingType->IsGenericParam()))
  14086. {
  14087. unresolvedTypeRef = mExpectingType;
  14088. if (unresolvedTypeRef->IsArray())
  14089. {
  14090. arrayType = (BfArrayType*)unresolvedTypeRef;
  14091. unresolvedTypeRef = unresolvedTypeRef->GetUnderlyingType();
  14092. isArrayAlloc = true;
  14093. }
  14094. }
  14095. else if (mExpectingType->IsPointer())
  14096. {
  14097. unresolvedTypeRef = mExpectingType->GetUnderlyingType();
  14098. }
  14099. else if (mExpectingType->IsStruct())
  14100. {
  14101. unresolvedTypeRef = mExpectingType;
  14102. }
  14103. else if (mExpectingType->IsVar())
  14104. unresolvedTypeRef = mExpectingType;
  14105. }
  14106. if (unresolvedTypeRef == NULL)
  14107. {
  14108. if (auto arrayTypeRef = BfNodeDynCast<BfArrayTypeRef>(objCreateExpr->mTypeRef))
  14109. {
  14110. isArrayAlloc = true;
  14111. if (auto dotTypeRef = BfNodeDynCast<BfDotTypeReference>(arrayTypeRef->mElementType))
  14112. {
  14113. if ((mExpectingType != NULL) &&
  14114. ((mExpectingType->IsArray()) || (mExpectingType->IsPointer()) || (mExpectingType->IsSizedArray())))
  14115. unresolvedTypeRef = mExpectingType->GetUnderlyingType();
  14116. }
  14117. if (unresolvedTypeRef == NULL)
  14118. unresolvedTypeRef = mModule->ResolveTypeRef(arrayTypeRef->mElementType);
  14119. if (unresolvedTypeRef == NULL)
  14120. unresolvedTypeRef = mModule->GetPrimitiveType(BfTypeCode_Var);
  14121. int dimensions = 1;
  14122. bool commaExpected = false;
  14123. if (arrayTypeRef->mParams.size() != 0)
  14124. {
  14125. auto intType = mModule->ResolveTypeDef(mModule->mSystem->mTypeIntPtr);
  14126. for (auto arg : arrayTypeRef->mParams)
  14127. {
  14128. if (auto tokenNode = BfNodeDynCastExact<BfTokenNode>(arg))
  14129. {
  14130. if (tokenNode->GetToken() == BfToken_Comma)
  14131. {
  14132. if (isRawArrayAlloc)
  14133. {
  14134. mModule->Fail("Sized arrays cannot be multidimensional.", tokenNode);
  14135. continue;
  14136. }
  14137. dimensions++;
  14138. if (dimensions == 5)
  14139. {
  14140. mModule->Fail("Too many array dimensions, consider using a jagged array.", tokenNode);
  14141. }
  14142. commaExpected = false;
  14143. continue;
  14144. }
  14145. }
  14146. auto expr = BfNodeDynCast<BfExpression>(arg);
  14147. if ((isRawArrayAlloc) && (!dimLengthVals.IsEmpty()))
  14148. {
  14149. mModule->CreateValueFromExpression(expr, intType);
  14150. continue;
  14151. }
  14152. dimLengthRefs.Add(expr);
  14153. BfTypedValue dimLength;
  14154. if (expr == NULL)
  14155. {
  14156. // Not specified
  14157. dimLengthVals.push_back(BfIRValue());
  14158. continue;
  14159. }
  14160. if (arg != NULL)
  14161. {
  14162. dimLength = mModule->CreateValueFromExpression(expr, intType, BfEvalExprFlags_NoCast);
  14163. BfCastFlags castFlags = BfCastFlags_None;
  14164. if ((dimLength) && (dimLength.mType->IsInteger()))
  14165. {
  14166. // Allow uint for size - just force to int
  14167. if (!((BfPrimitiveType*)dimLength.mType)->IsSigned())
  14168. castFlags = BfCastFlags_Explicit;
  14169. }
  14170. if (dimLength)
  14171. dimLength = mModule->Cast(expr, dimLength, intType, castFlags);
  14172. }
  14173. if (commaExpected)
  14174. {
  14175. mModule->AssertErrorState();
  14176. continue;
  14177. }
  14178. if (!dimLength)
  14179. {
  14180. dimLength = mModule->GetDefaultTypedValue(intType);
  14181. }
  14182. dimLengthVals.push_back(dimLength.mValue);
  14183. commaExpected = true;
  14184. }
  14185. }
  14186. if ((arrayTypeRef->mParams.size() == 0) && (objCreateExpr->mOpenToken == NULL))
  14187. mModule->Fail("Array size or array initializer expected", arrayTypeRef->mOpenBracket);
  14188. if (dimensions > 4)
  14189. dimensions = 4;
  14190. if ((!isRawArrayAlloc) && (!unresolvedTypeRef->IsVar()))
  14191. arrayType = mModule->CreateArrayType(unresolvedTypeRef, dimensions);
  14192. }
  14193. if (unresolvedTypeRef == NULL)
  14194. {
  14195. unresolvedTypeRef = ResolveTypeRef(objCreateExpr->mTypeRef, BfPopulateType_Declaration, BfResolveTypeRefFlag_NoResolveGenericParam);
  14196. }
  14197. }
  14198. resolvedTypeRef = unresolvedTypeRef;
  14199. if ((resolvedTypeRef != NULL) && (IsVar(resolvedTypeRef)))
  14200. resolvedTypeRef = unresolvedTypeRef;
  14201. }
  14202. if (inlineTypeRef != NULL)
  14203. {
  14204. auto inlineType = mModule->ResolveTypeRef(inlineTypeRef);
  14205. if (inlineType != NULL)
  14206. {
  14207. unresolvedTypeRef = inlineType;
  14208. resolvedTypeRef = inlineType;
  14209. }
  14210. }
  14211. if (resolvedTypeRef == NULL)
  14212. {
  14213. unresolvedTypeRef = mModule->GetPrimitiveType(BfTypeCode_Var);
  14214. resolvedTypeRef = unresolvedTypeRef;
  14215. }
  14216. auto resultType = resolvedTypeRef;
  14217. if ((resolvedTypeRef->IsInterface()) && (!isArrayAlloc))
  14218. {
  14219. mModule->Fail("Cannot create an instance of an interface", objCreateExpr->mTypeRef);
  14220. resolvedTypeRef = mModule->mContext->mBfObjectType;
  14221. }
  14222. BfTypeInstance* typeInstance = resolvedTypeRef->ToTypeInstance();
  14223. int elementSize = resolvedTypeRef->mSize;
  14224. int elementAlign = resolvedTypeRef->mAlign;
  14225. BfIRType allocType = mModule->mBfIRBuilder->MapType(resolvedTypeRef);
  14226. if (typeInstance != NULL)
  14227. {
  14228. if (!mModule->mCurTypeInstance->mResolvingVarField)
  14229. mModule->PopulateType(typeInstance);
  14230. if ((typeInstance->mTypeDef->mIsDelegate) && (!isArrayAlloc))
  14231. mModule->Fail("Delegates must be constructed through delegate binding", objCreateExpr->mTypeRef);
  14232. elementSize = BF_MAX(0, typeInstance->mInstSize);
  14233. elementAlign = typeInstance->mInstAlign;
  14234. allocType = mModule->mBfIRBuilder->MapTypeInst(typeInstance);
  14235. }
  14236. if (isAppendAlloc)
  14237. {
  14238. if (!mModule->mCurTypeInstance->IsObject())
  14239. {
  14240. mModule->Fail("Append allocations are only allowed in classes", allocNode);
  14241. isAppendAlloc = false;
  14242. }
  14243. else if ((mBfEvalExprFlags & BfEvalExprFlags_VariableDeclaration) == 0)
  14244. {
  14245. mModule->Fail("Append allocations are only allowed as local variable initializers in constructor body", allocNode);
  14246. isAppendAlloc = false;
  14247. }
  14248. else
  14249. {
  14250. auto methodDef = mModule->mCurMethodInstance->mMethodDef;
  14251. if (methodDef->mMethodType == BfMethodType_CtorCalcAppend)
  14252. {
  14253. mModule->Fail("Append allocations are only allowed as local variable declarations in the main method body", allocNode);
  14254. isAppendAlloc = false;
  14255. }
  14256. else if (!methodDef->HasAppend())
  14257. {
  14258. mModule->Fail("Append allocations can only be used on constructors with [AllowAppend] specified", allocNode);
  14259. isAppendAlloc = false;
  14260. }
  14261. else if (methodDef->mMethodType != BfMethodType_Ctor)
  14262. {
  14263. mModule->Fail("Append allocations are only allowed in constructors", allocNode);
  14264. isAppendAlloc = false;
  14265. }
  14266. else if (methodDef->mIsStatic)
  14267. {
  14268. mModule->Fail("Append allocations are only allowed in non-static constructors", allocNode);
  14269. isAppendAlloc = false;
  14270. }
  14271. }
  14272. }
  14273. if (isArrayAlloc)
  14274. {
  14275. const int MAX_DIMENSIONS = 2;
  14276. int dimensions = 1;
  14277. if (arrayType != NULL)
  14278. {
  14279. dimensions = arrayType->mDimensions;
  14280. mModule->AddDependency(arrayType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_Calls);
  14281. }
  14282. bool zeroMemory = true;
  14283. if (objCreateExpr->mOpenToken != NULL)
  14284. {
  14285. if ((objCreateExpr->mArguments.size() == 1) &&
  14286. (BfNodeDynCastExact<BfUninitializedExpression>(objCreateExpr->mArguments[0]) != NULL))
  14287. {
  14288. // Special case for a single "{ ? }"
  14289. zeroMemory = false;
  14290. }
  14291. else
  14292. {
  14293. SizedArray<int64, 2> dimLengths;
  14294. if (dimLengthVals.size() != 0)
  14295. {
  14296. for (int dim = 0; dim < dimensions; dim++)
  14297. {
  14298. BfIRValue dimLengthVal;
  14299. if (dim < (int)dimLengthVals.size())
  14300. dimLengthVal = dimLengthVals[dim];
  14301. if (!dimLengthVal)
  14302. {
  14303. dimLengths.push_back(-1);
  14304. continue;
  14305. }
  14306. auto constant = mModule->mBfIRBuilder->GetConstant(dimLengthVal);
  14307. if ((constant != NULL) && (mModule->mBfIRBuilder->IsInt(constant->mTypeCode)))
  14308. {
  14309. int64 dimLength = constant->mInt64;
  14310. if (dimLength < 0)
  14311. {
  14312. mModule->Fail(StrFormat("Invalid array dimension '%lld'", dimLength), dimLengthRefs[dim]);
  14313. dimLength = -1;
  14314. }
  14315. dimLengths.push_back(dimLength);
  14316. }
  14317. else if ((constant != NULL) && (constant->mConstType == BfConstType_Undef))
  14318. {
  14319. dimLengths.push_back(-1);
  14320. }
  14321. else
  14322. {
  14323. mModule->Fail("A constant length is required when using an initializer", dimLengthRefs[dim]);
  14324. dimLengths.push_back(-1);
  14325. }
  14326. }
  14327. }
  14328. // Ending in an ", )" means we need to zero-fill ending
  14329. zeroMemory = objCreateExpr->mCommas.size() >= objCreateExpr->mArguments.size();
  14330. bool hasFailed = false;
  14331. ProcessArrayInitializer(objCreateExpr->mOpenToken, objCreateExpr->mArguments, objCreateExpr->mCommas, objCreateExpr->mCloseToken, dimensions, dimLengths, 0, hasFailed);
  14332. dimLengthVals.resize(dimLengths.size());
  14333. for (int i = 0; i < (int)dimLengthVals.size(); i++)
  14334. {
  14335. if (!dimLengthVals[i])
  14336. {
  14337. auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  14338. dimLengthVals[i] = mModule->GetConstValue(dimLengths[i], intType);
  14339. }
  14340. }
  14341. }
  14342. }
  14343. while ((int)dimLengthVals.size() < dimensions)
  14344. dimLengthVals.push_back(mModule->GetConstValue(0));
  14345. BfTypedValue arrayValue;
  14346. BfIRValue arraySize;
  14347. for (BfIRValue dimSize : dimLengthVals)
  14348. {
  14349. if (!arraySize)
  14350. arraySize = dimSize;
  14351. else
  14352. arraySize = mModule->mBfIRBuilder->CreateMul(arraySize, dimSize);
  14353. }
  14354. BfAllocFlags allocFlags = BfAllocFlags_None;
  14355. if (isRawArrayAlloc)
  14356. allocFlags = (BfAllocFlags)(allocFlags | BfAllocFlags_RawArray);
  14357. int writeIdx = 0;
  14358. struct BfInitContext
  14359. {
  14360. public:
  14361. BfModule* mModule;
  14362. BfType* resultType;
  14363. int dimensions;
  14364. SizedArray<BfIRValue, 2>& dimLengthVals;
  14365. BfIRValue arraySize;
  14366. int& writeIdx;
  14367. BfInitContext(BfModule* module, BfType* resultType, int dimensions, SizedArray<BfIRValue, 2>& dimLengthVals, BfIRValue arraySize, int& writeIdx) :
  14368. mModule(module), resultType(resultType), dimensions(dimensions), dimLengthVals(dimLengthVals), arraySize(arraySize), writeIdx(writeIdx)
  14369. {
  14370. }
  14371. void Handle(BfIRValue addr, int curDim, const BfSizedArray<BfExpression*>& valueExprs)
  14372. {
  14373. int exprIdx = 0;
  14374. int dimWriteIdx = 0;
  14375. bool isUninit = false;
  14376. int dimLength = -1;
  14377. if (dimLengthVals[curDim].IsConst())
  14378. {
  14379. auto constant = mModule->mBfIRBuilder->GetConstant(dimLengthVals[curDim]);
  14380. dimLength = constant->mInt32;
  14381. }
  14382. while (exprIdx < (int)valueExprs.size())
  14383. {
  14384. auto initExpr = valueExprs[exprIdx];
  14385. exprIdx++;
  14386. if (!initExpr)
  14387. break;
  14388. if (auto unintExpr = BfNodeDynCastExact<BfUninitializedExpression>(initExpr))
  14389. {
  14390. isUninit = true;
  14391. break;
  14392. }
  14393. if (exprIdx > dimLength)
  14394. break;
  14395. if (curDim < dimensions - 1)
  14396. {
  14397. if (auto innerTupleExpr = BfNodeDynCast<BfTupleExpression>(initExpr))
  14398. {
  14399. Handle(addr, curDim + 1, innerTupleExpr->mValues);
  14400. }
  14401. else if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(initExpr))
  14402. {
  14403. SizedArray<BfExpression*, 1> values;
  14404. values.Add(parenExpr->mExpression);
  14405. Handle(addr, curDim + 1, values);
  14406. }
  14407. else if (auto innerInitExpr = BfNodeDynCast<BfCollectionInitializerExpression>(initExpr))
  14408. {
  14409. Handle(addr, curDim + 1, innerInitExpr->mValues);
  14410. }
  14411. dimWriteIdx++;
  14412. continue;
  14413. }
  14414. BfIRValue elemAddr;
  14415. if (!resultType->IsValuelessType())
  14416. elemAddr = mModule->CreateIndexedValue(resultType, addr, writeIdx);
  14417. else
  14418. elemAddr = mModule->mBfIRBuilder->GetFakeVal();
  14419. writeIdx++;
  14420. dimWriteIdx++;
  14421. BfTypedValue elemPtrTypedVal = BfTypedValue(elemAddr, resultType, BfTypedValueKind_Addr);
  14422. BfExprEvaluator exprEvaluator(mModule);
  14423. exprEvaluator.mExpectingType = resultType;
  14424. exprEvaluator.mReceivingValue = &elemPtrTypedVal;
  14425. exprEvaluator.Evaluate(initExpr);
  14426. exprEvaluator.GetResult();
  14427. if (exprEvaluator.mReceivingValue == NULL)
  14428. {
  14429. // We wrote directly to the array in-place, we're done with this element
  14430. continue;
  14431. }
  14432. auto storeValue = exprEvaluator.mResult;
  14433. if (!storeValue)
  14434. continue;
  14435. storeValue = mModule->Cast(initExpr, storeValue, resultType);
  14436. if (!storeValue)
  14437. continue;
  14438. if (!resultType->IsValuelessType())
  14439. {
  14440. storeValue = mModule->LoadOrAggregateValue(storeValue);
  14441. mModule->mBfIRBuilder->CreateStore(storeValue.mValue, elemAddr);
  14442. }
  14443. }
  14444. int clearFromIdx = writeIdx;
  14445. int sectionElemCount = 1;
  14446. BfIRValue numElemsLeft = arraySize;
  14447. if (dimLength != -1)
  14448. {
  14449. int clearCount = dimLength - dimWriteIdx;
  14450. if (clearCount > 0)
  14451. {
  14452. for (int checkDim = curDim + 1; checkDim < (int)dimLengthVals.size(); checkDim++)
  14453. {
  14454. if (dimLengthVals[checkDim].IsConst())
  14455. {
  14456. auto constant = mModule->mBfIRBuilder->GetConstant(dimLengthVals[checkDim]);
  14457. clearCount *= constant->mInt32;
  14458. sectionElemCount *= constant->mInt32;
  14459. }
  14460. }
  14461. }
  14462. writeIdx += clearCount;
  14463. numElemsLeft = mModule->GetConstValue(clearCount);
  14464. }
  14465. // Actually leave it alone?
  14466. if ((isUninit) &&
  14467. ((mModule->IsOptimized()) || (mModule->mIsComptimeModule) || (mModule->mBfIRBuilder->mIgnoreWrites)))
  14468. return;
  14469. bool doClear = true;
  14470. if (numElemsLeft.IsConst())
  14471. {
  14472. auto constant = mModule->mBfIRBuilder->GetConstant(numElemsLeft);
  14473. doClear = constant->mInt64 > 0;
  14474. }
  14475. if (doClear)
  14476. {
  14477. // We multiply by GetStride. This relies on the fact that we over-allocate on the array allocation -- the last
  14478. // element doesn't need to be padded out to the element alignment, but we do anyway. Otherwise this would be
  14479. // a more complicated computation
  14480. auto clearBytes = mModule->mBfIRBuilder->CreateMul(numElemsLeft, mModule->GetConstValue(resultType->GetStride()));
  14481. if (isUninit)
  14482. {
  14483. // Limit to a reasonable number of bytes to stomp with 0xCC
  14484. int maxStompBytes = BF_MIN(128, resultType->GetStride() * sectionElemCount);
  14485. if (clearBytes.IsConst())
  14486. {
  14487. auto constant = mModule->mBfIRBuilder->GetConstant(clearBytes);
  14488. if (constant->mInt64 > maxStompBytes)
  14489. clearBytes = mModule->GetConstValue(maxStompBytes);
  14490. }
  14491. else
  14492. {
  14493. auto insertBlock = mModule->mBfIRBuilder->GetInsertBlock();
  14494. auto gtBlock = mModule->mBfIRBuilder->CreateBlock("unint.gt");
  14495. auto contBlock = mModule->mBfIRBuilder->CreateBlock("unint.cont");
  14496. auto cmp = mModule->mBfIRBuilder->CreateCmpLTE(clearBytes, mModule->GetConstValue(maxStompBytes), true);
  14497. mModule->mBfIRBuilder->CreateCondBr(cmp, contBlock, gtBlock);
  14498. mModule->mBfIRBuilder->AddBlock(gtBlock);
  14499. mModule->mBfIRBuilder->SetInsertPoint(gtBlock);
  14500. mModule->mBfIRBuilder->CreateBr(contBlock);
  14501. mModule->mBfIRBuilder->AddBlock(contBlock);
  14502. mModule->mBfIRBuilder->SetInsertPoint(contBlock);
  14503. auto phi = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(mModule->GetPrimitiveType(BfTypeCode_IntPtr)), 2);
  14504. mModule->mBfIRBuilder->AddPhiIncoming(phi, clearBytes, insertBlock);
  14505. mModule->mBfIRBuilder->AddPhiIncoming(phi, mModule->GetConstValue(maxStompBytes), gtBlock);
  14506. clearBytes = phi;
  14507. }
  14508. }
  14509. mModule->mBfIRBuilder->PopulateType(resultType);
  14510. if ((!resultType->IsValuelessType()) && (!addr.IsConst()))
  14511. {
  14512. mModule->mBfIRBuilder->CreateMemSet(mModule->CreateIndexedValue(resultType, addr, clearFromIdx),
  14513. mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int8, isUninit ? 0xCC : 0), clearBytes, resultType->mAlign);
  14514. }
  14515. }
  14516. }
  14517. };
  14518. BfInitContext initContext(mModule, resultType, dimensions, dimLengthVals, arraySize, writeIdx);
  14519. if (IsVar(resultType))
  14520. {
  14521. SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
  14522. mResult = BfTypedValue(BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), mModule->GetPrimitiveType(BfTypeCode_Var)));
  14523. initContext.Handle(mResult.mValue, 0, objCreateExpr->mArguments);
  14524. return;
  14525. }
  14526. if (isRawArrayAlloc)
  14527. {
  14528. // 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
  14529. BfType* ptrType = mModule->CreatePointerType(resultType);
  14530. if (isAppendAlloc)
  14531. arrayValue = BfTypedValue(mModule->AppendAllocFromType(resultType, BfIRValue(), 0, arraySize, (int)dimLengthVals.size(), isRawArrayAlloc, false), ptrType);
  14532. else
  14533. {
  14534. arrayValue = BfTypedValue(mModule->AllocFromType(resultType, allocTarget, BfIRValue(), arraySize, (int)dimLengthVals.size(), allocFlags, allocTarget.mAlignOverride), ptrType);
  14535. }
  14536. initContext.Handle(arrayValue.mValue, 0, objCreateExpr->mArguments);
  14537. mResult = arrayValue;
  14538. return;
  14539. }
  14540. if (dimLengthVals.size() > 4)
  14541. {
  14542. dimLengthVals.RemoveRange(4, dimLengthVals.size() - 4);
  14543. mModule->Fail("Too many array dimensions, consider using a jagged array.", objCreateExpr);
  14544. }
  14545. if (arrayType == NULL)
  14546. return;
  14547. if (isAppendAlloc)
  14548. arrayValue = BfTypedValue(mModule->AppendAllocFromType(resultType, BfIRValue(), 0, arraySize, (int)dimLengthVals.size(), isRawArrayAlloc, zeroMemory), arrayType);
  14549. else
  14550. {
  14551. arrayValue = BfTypedValue(mModule->AllocFromType(resultType, allocTarget, BfIRValue(), arraySize, (int)dimLengthVals.size(), allocFlags, allocTarget.mAlignOverride), arrayType);
  14552. if (isScopeAlloc)
  14553. {
  14554. // See notes below on "general" SkipObjectAccessCheck usage on why we can do this
  14555. mModule->SkipObjectAccessCheck(arrayValue);
  14556. }
  14557. }
  14558. //mModule->InitTypeInst(arrayValue, scopeData);
  14559. BfAstNode* refNode = objCreateExpr->mTypeRef;
  14560. while (true)
  14561. {
  14562. if (auto arrayRef = BfNodeDynCast<BfElementedTypeRef>(refNode))
  14563. {
  14564. refNode = arrayRef->mElementType;
  14565. continue;
  14566. }
  14567. break;
  14568. }
  14569. BfResolvedArgs resolvedArgs;
  14570. auto rawAutoComplete = mModule->mCompiler->GetAutoComplete();
  14571. if (rawAutoComplete != NULL)
  14572. {
  14573. SetAndRestoreValue<bool> prevCapturing(rawAutoComplete->mIsCapturingMethodMatchInfo, false);
  14574. MatchConstructor(refNode, objCreateExpr, arrayValue, arrayType, resolvedArgs, false, methodGenericArguments, BfAllowAppendKind_No);
  14575. }
  14576. else
  14577. {
  14578. MatchConstructor(refNode, objCreateExpr, arrayValue, arrayType, resolvedArgs, false, methodGenericArguments, BfAllowAppendKind_No);
  14579. }
  14580. //TODO: Assert 'length' var is at slot 1
  14581. mModule->PopulateType(arrayType->mBaseType, BfPopulateType_DataAndMethods);
  14582. mModule->mBfIRBuilder->PopulateType(arrayType);
  14583. auto arrayBits = mModule->mBfIRBuilder->CreateBitCast(arrayValue.mValue, mModule->mBfIRBuilder->MapTypeInstPtr(arrayType->mBaseType));
  14584. int arrayLengthBitCount = arrayType->GetLengthBitCount();
  14585. if (arrayLengthBitCount == 0)
  14586. {
  14587. mModule->Fail("INTERNAL ERROR: Unable to find array 'length' field", objCreateExpr);
  14588. return;
  14589. }
  14590. mResult = arrayValue;
  14591. auto lengthFieldInstance = mModule->GetFieldByName(arrayType->mBaseType->ToTypeInstance(), "mLength");
  14592. if (lengthFieldInstance == NULL)
  14593. return;
  14594. auto firstElementFieldInstance = mModule->GetFieldByName(arrayType->ToTypeInstance(), "mFirstElement");
  14595. if (firstElementFieldInstance == NULL)
  14596. return;
  14597. auto addr = mModule->mBfIRBuilder->CreateInBoundsGEP(arrayBits, 0, lengthFieldInstance->mDataIdx);
  14598. if (arrayLengthBitCount == 64)
  14599. mModule->mBfIRBuilder->CreateAlignedStore(arraySize, addr, 8);
  14600. else
  14601. {
  14602. auto arraySize32 = mModule->mBfIRBuilder->CreateNumericCast(arraySize, true, BfTypeCode_Int32);
  14603. mModule->mBfIRBuilder->CreateAlignedStore(arraySize32, addr, 4);
  14604. }
  14605. for (int lowerDim = 1; lowerDim < (int)dimLengthVals.size(); lowerDim++)
  14606. {
  14607. auto length1FieldInstance = mModule->GetFieldByName(arrayType->ToTypeInstance(), "mLength1");
  14608. if (length1FieldInstance == NULL)
  14609. return;
  14610. addr = mModule->mBfIRBuilder->CreateInBoundsGEP(arrayValue.mValue, 0, length1FieldInstance->mDataIdx + lowerDim - 1);
  14611. auto lowerDimVal = mModule->mBfIRBuilder->CreateNumericCast(dimLengthVals[lowerDim], true, (arrayLengthBitCount == 64) ? BfTypeCode_Int64 : BfTypeCode_Int32);
  14612. mModule->mBfIRBuilder->CreateStore(lowerDimVal, addr);
  14613. }
  14614. if (resultType->IsValuelessType())
  14615. addr = mModule->mBfIRBuilder->GetFakeVal();
  14616. else
  14617. addr = mModule->mBfIRBuilder->CreateInBoundsGEP(arrayValue.mValue, 0, firstElementFieldInstance->mDataIdx);
  14618. initContext.Handle(addr, 0, objCreateExpr->mArguments);
  14619. return;
  14620. }
  14621. else
  14622. {
  14623. if (resolvedTypeRef->IsVar())
  14624. {
  14625. // Leave as a var
  14626. }
  14627. else if ((!resolvedTypeRef->IsObjectOrInterface()) && (!resolvedTypeRef->IsGenericParam()))
  14628. {
  14629. resultType = mModule->CreatePointerType(resolvedTypeRef);
  14630. }
  14631. }
  14632. if ((isStackAlloc) && (mModule->mCurMethodState == NULL))
  14633. {
  14634. mModule->Fail("Cannot use 'stack' here", allocNode);
  14635. isStackAlloc = false;
  14636. isScopeAlloc = false;
  14637. }
  14638. bool isGenericParam = unresolvedTypeRef->IsGenericParam();
  14639. if (resolvedTypeRef->IsGenericParam())
  14640. {
  14641. BfGenericParamFlags genericParamFlags = BfGenericParamFlag_None;
  14642. BfType* typeConstraint = NULL;
  14643. auto genericParam = mModule->GetMergedGenericParamData((BfGenericParamType*)resolvedTypeRef, genericParamFlags, typeConstraint);
  14644. if (typeConstraint == NULL)
  14645. {
  14646. if ((genericParamFlags & BfGenericParamFlag_Var) != 0)
  14647. {
  14648. // Allow it
  14649. }
  14650. else
  14651. {
  14652. if ((genericParamFlags & BfGenericParamFlag_New) == 0)
  14653. {
  14654. mModule->Fail(StrFormat("Must add 'where %s : new' constraint to generic parameter to instantiate type", genericParam->GetName().c_str()), objCreateExpr->mTypeRef);
  14655. }
  14656. if (objCreateExpr->mArguments.size() != 0)
  14657. {
  14658. mModule->Fail(StrFormat("Only default parameterless constructors can be called on generic argument '%s'", genericParam->GetName().c_str()), objCreateExpr->mTypeRef);
  14659. }
  14660. }
  14661. }
  14662. if (((typeConstraint != NULL) && (typeConstraint->IsValueType())) ||
  14663. ((genericParamFlags & (BfGenericParamFlag_Struct | BfGenericParamFlag_StructPtr)) != 0))
  14664. {
  14665. resultType = mModule->CreatePointerType(resolvedTypeRef);
  14666. }
  14667. else if (((typeConstraint != NULL) && (!typeConstraint->IsValueType())) ||
  14668. ((genericParamFlags & (BfGenericParamFlag_Class)) != 0))
  14669. {
  14670. // Leave as 'T'
  14671. resultType = resolvedTypeRef;
  14672. }
  14673. else
  14674. resultType = mModule->CreateModifiedTypeType(resolvedTypeRef, BfToken_AllocType);
  14675. mResult.mType = resultType;
  14676. if (typeInstance == NULL)
  14677. {
  14678. mResult = mModule->GetDefaultTypedValue(resultType);
  14679. return;
  14680. }
  14681. }
  14682. else if (resolvedTypeRef->IsSizedArray())
  14683. {
  14684. // Handle the case of "int[3]* val = new .(1, 2, 3)"
  14685. if (auto dotTypeRef = BfNodeDynCastExact<BfDotTypeReference>(objCreateExpr->mTypeRef))
  14686. {
  14687. BfIRValue allocValue;
  14688. if (isAppendAlloc)
  14689. allocValue = mModule->AppendAllocFromType(resolvedTypeRef, BfIRValue(), 0, BfIRValue(), 0, false, false);
  14690. else
  14691. allocValue = mModule->AllocFromType(resolvedTypeRef, allocTarget, BfIRValue(), BfIRValue(), 0, BfAllocFlags_None);
  14692. auto result = BfTypedValue(allocValue, resolvedTypeRef, BfTypedValueKind_Addr);
  14693. InitializedSizedArray((BfSizedArrayType*)resolvedTypeRef, objCreateExpr->mOpenToken, objCreateExpr->mArguments, objCreateExpr->mCommas, objCreateExpr->mCloseToken, &result);
  14694. // Turn from an addr of a sized array to pointer of sized array
  14695. mResult = BfTypedValue(mResult.mValue, resultType);
  14696. return;
  14697. }
  14698. }
  14699. SetAndRestoreValue<bool> prevNoBind(mNoBind, mNoBind || isGenericParam);
  14700. if ((typeInstance != NULL) && (typeInstance->mTypeDef->mIsAbstract))
  14701. {
  14702. mModule->Fail("Cannot create an instance of an abstract class", objCreateExpr->mTypeRef);
  14703. return;
  14704. }
  14705. BfFunctionBindResult bindResult;
  14706. bindResult.mSkipThis = true;
  14707. bindResult.mWantsArgs = true;
  14708. SetAndRestoreValue<BfFunctionBindResult*> prevBindResult(mFunctionBindResult, &bindResult);
  14709. BfIRValue appendSizeValue;
  14710. BfTypedValue emtpyThis(mModule->mBfIRBuilder->GetFakeVal(), resolvedTypeRef, resolvedTypeRef->IsStruct());
  14711. BfResolvedArgs argValues;
  14712. if (objCreateExpr != NULL)
  14713. {
  14714. argValues.Init(objCreateExpr->mOpenToken, &objCreateExpr->mArguments, &objCreateExpr->mCommas, objCreateExpr->mCloseToken);
  14715. ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval); ////
  14716. }
  14717. if (typeInstance == NULL)
  14718. {
  14719. // No CTOR needed
  14720. if (objCreateExpr->mArguments.size() != 0)
  14721. {
  14722. mModule->Fail(StrFormat("Only default parameterless constructors can be called on primitive type '%s'", mModule->TypeToString(resolvedTypeRef).c_str()), objCreateExpr->mTypeRef);
  14723. }
  14724. }
  14725. else if ((autoComplete != NULL) && (objCreateExpr != NULL) && (objCreateExpr->mOpenToken != NULL))
  14726. {
  14727. auto wasCapturingMethodInfo = autoComplete->mIsCapturingMethodMatchInfo;
  14728. autoComplete->CheckInvocation(objCreateExpr, objCreateExpr->mOpenToken, objCreateExpr->mCloseToken, objCreateExpr->mCommas);
  14729. BfAstNode* refNode = objCreateExpr->mTypeRef;
  14730. if ((objCreateExpr->mCtorExplicit != NULL) && (objCreateExpr->mCtorExplicit->mThisToken != NULL))
  14731. refNode = objCreateExpr->mCtorExplicit->mThisToken;
  14732. auto checkTypeInst = typeInstance;
  14733. if (checkTypeInst->IsAnonymousInitializerType())
  14734. checkTypeInst = checkTypeInst->mBaseType;
  14735. MatchConstructor(refNode, objCreateExpr, emtpyThis, checkTypeInst, argValues, false, methodGenericArguments, BfAllowAppendKind_Infer);
  14736. if ((wasCapturingMethodInfo) && (!autoComplete->mIsCapturingMethodMatchInfo))
  14737. {
  14738. if (autoComplete->mMethodMatchInfo != NULL)
  14739. autoComplete->mIsCapturingMethodMatchInfo = true;
  14740. }
  14741. else
  14742. autoComplete->mIsCapturingMethodMatchInfo = false;
  14743. }
  14744. else if (!resolvedTypeRef->IsFunction())
  14745. {
  14746. auto refNode = allocNode;
  14747. if (objCreateExpr != NULL)
  14748. refNode = objCreateExpr->mTypeRef;
  14749. auto checkTypeInst = typeInstance;
  14750. if (checkTypeInst->IsAnonymousInitializerType())
  14751. checkTypeInst = checkTypeInst->mBaseType;
  14752. MatchConstructor(refNode, objCreateExpr, emtpyThis, checkTypeInst, argValues, false, methodGenericArguments, BfAllowAppendKind_Infer);
  14753. }
  14754. if (objCreateExpr != NULL)
  14755. mModule->ValidateAllocation(typeInstance, objCreateExpr->mTypeRef);
  14756. prevBindResult.Restore();
  14757. int allocAlign = resolvedTypeRef->mAlign;
  14758. if (typeInstance != NULL)
  14759. allocAlign = typeInstance->mInstAlign;
  14760. int appendAllocAlign = 0;
  14761. BfAllocFlags allocFlags = BfAllocFlags_None;
  14762. if ((bindResult.mMethodInstance != NULL) && (bindResult.mMethodInstance->mMethodDef->HasAppend()))
  14763. {
  14764. if (!bindResult.mFunc)
  14765. {
  14766. BF_ASSERT((!mModule->HasExecutedOutput()) || (mModule->mBfIRBuilder->mIgnoreWrites));
  14767. appendSizeValue = mModule->GetConstValue(0);
  14768. }
  14769. else
  14770. {
  14771. //auto calcAppendMethodModule = mModule->GetMethodInstanceAtIdx(bindResult.mMethodInstance->GetOwner(), bindResult.mMethodInstance->mMethodDef->mIdx + 1, BF_METHODNAME_CALCAPPEND);
  14772. BfTypeVector methodGenericArguments;
  14773. if (bindResult.mMethodInstance->mMethodInfoEx != NULL)
  14774. methodGenericArguments = bindResult.mMethodInstance->mMethodInfoEx->mMethodGenericArguments;
  14775. auto methodOwner = bindResult.mMethodInstance->GetOwner();
  14776. auto calcAppendMethodDef = methodOwner->mTypeDef->mMethods[bindResult.mMethodInstance->mMethodDef->mIdx + 1];
  14777. BF_ASSERT(calcAppendMethodDef->mName == BF_METHODNAME_CALCAPPEND);
  14778. auto calcAppendMethodModule = mModule->GetMethodInstance(methodOwner, calcAppendMethodDef, methodGenericArguments);
  14779. SizedArray<BfIRValue, 2> irArgs;
  14780. if (bindResult.mIRArgs.size() > 1)
  14781. irArgs.Insert(0, &bindResult.mIRArgs[1], bindResult.mIRArgs.size() - 1);
  14782. BfTypedValue appendSizeTypedValue = mModule->TryConstCalcAppend(calcAppendMethodModule.mMethodInstance, irArgs);
  14783. if (!appendSizeTypedValue)
  14784. {
  14785. BF_ASSERT(calcAppendMethodModule.mFunc);
  14786. appendSizeTypedValue = CreateCall(objCreateExpr, calcAppendMethodModule.mMethodInstance, calcAppendMethodModule.mFunc, false, irArgs);
  14787. BF_ASSERT(appendSizeTypedValue.mType == mModule->GetPrimitiveType(BfTypeCode_IntPtr));
  14788. }
  14789. appendSizeValue = appendSizeTypedValue.mValue;
  14790. allocAlign = BF_MAX(allocAlign, calcAppendMethodModule.mMethodInstance->mAppendAllocAlign);
  14791. appendAllocAlign = calcAppendMethodModule.mMethodInstance->mAppendAllocAlign;
  14792. if (calcAppendMethodModule.mMethodInstance->mHasAppendWantMark)
  14793. allocFlags = (BfAllocFlags)(allocFlags | BfAllocFlags_HasAppendWantMark);
  14794. }
  14795. if (appendAllocAlign != 0)
  14796. {
  14797. int endingAlign = typeInstance->GetEndingInstanceAlignment();
  14798. if (endingAlign % appendAllocAlign != 0)
  14799. {
  14800. int extraSize = appendAllocAlign - (endingAlign % appendAllocAlign);
  14801. appendSizeValue = mModule->mBfIRBuilder->CreateAdd(appendSizeValue, mModule->GetConstValue(extraSize));
  14802. }
  14803. }
  14804. if ((allocFlags & BfAllocFlags_HasAppendWantMark) != 0)
  14805. {
  14806. int markInfoSize = sizeof(intptr) + sizeof(intptr) * 4; // Stack trace, MarkAppendEntry
  14807. appendSizeValue = mModule->mBfIRBuilder->CreateAdd(appendSizeValue, mModule->GetConstValue(markInfoSize));
  14808. }
  14809. }
  14810. // WTF? I'm not even sure this is correct - add more tests
  14811. appendAllocAlign = BF_MAX(appendAllocAlign, allocAlign);
  14812. BfIRValue allocValue;
  14813. if (IsVar(resolvedTypeRef))
  14814. {
  14815. mResult = mModule->GetDefaultTypedValue(resultType);
  14816. return;
  14817. }
  14818. else
  14819. {
  14820. if (isAppendAlloc)
  14821. {
  14822. allocValue = mModule->AppendAllocFromType(resolvedTypeRef, appendSizeValue, appendAllocAlign);
  14823. }
  14824. else
  14825. {
  14826. allocValue = mModule->AllocFromType(resolvedTypeRef, allocTarget, appendSizeValue, BfIRValue(), 0, allocFlags, allocAlign);
  14827. }
  14828. if (((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) && (mModule->mCompiler->mCeMachine != NULL))
  14829. {
  14830. mModule->mCompiler->mCeMachine->SetAppendAllocInfo(mModule, allocValue, appendSizeValue);
  14831. }
  14832. mResult = BfTypedValue(allocValue, resultType);
  14833. }
  14834. if (isScopeAlloc)
  14835. {
  14836. // This allows readonly (ie: 'let') local usage to not require an access check. No matter what scope the alloc is tied to, the
  14837. // lifetime of the local variable will be no longer than that of the allocated value
  14838. mModule->SkipObjectAccessCheck(mResult);
  14839. }
  14840. /*if (typeInstance != NULL)
  14841. {
  14842. mModule->InitTypeInst(mResult, scopeData, true);
  14843. }
  14844. if (isStackAlloc)
  14845. {
  14846. mModule->AddStackAlloc(mResult, objCreateExpr, scopeData);
  14847. }*/
  14848. if (mResult)
  14849. {
  14850. if (bindResult.mMethodInstance == NULL)
  14851. {
  14852. // Why did we have this? It was already zeroed right?
  14853. // Zero
  14854. //mModule->mBfIRBuilder->CreateMemSet(mResult.mValue, mModule->GetConstValue8(0), mModule->GetConstValue(resolvedTypeRef->mSize), resolvedTypeRef->mAlign);
  14855. }
  14856. else if (bindResult.mFunc)
  14857. {
  14858. bool hasRealtimeLeakCheck = (mModule->mCompiler->mOptions.mEnableRealtimeLeakCheck) && (!IsComptime());
  14859. if ((typeInstance->IsObject()) || (typeInstance->IsAnonymousInitializerType()))
  14860. {
  14861. bool wantsCtorClear = true;
  14862. if (hasRealtimeLeakCheck)
  14863. {
  14864. // Dbg_ObjectAlloc clears internally so we don't need to call CtorClear for those
  14865. if ((!isStackAlloc) && (!isAppendAlloc) && (!allocTarget.mCustomAllocator) && (allocTarget.mScopedInvocationTarget == NULL))
  14866. wantsCtorClear = false;
  14867. }
  14868. if (wantsCtorClear)
  14869. {
  14870. auto ctorClear = mModule->GetMethodByName(typeInstance, "__BfCtorClear");
  14871. if (!ctorClear)
  14872. {
  14873. mModule->AssertErrorState();
  14874. }
  14875. else if ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) == 0)
  14876. {
  14877. SizedArray<BfIRValue, 1> irArgs;
  14878. irArgs.push_back(mResult.mValue);
  14879. CreateCall(objCreateExpr, ctorClear.mMethodInstance, ctorClear.mFunc, false, irArgs);
  14880. }
  14881. }
  14882. }
  14883. if (typeInstance->IsObject())
  14884. {
  14885. if ((!mModule->mIsComptimeModule) && (isStackAlloc) && (hasRealtimeLeakCheck))
  14886. {
  14887. BfMethodInstance* markMethod = mModule->GetRawMethodByName(mModule->mContext->mBfObjectType, "GCMarkMembers");
  14888. BF_ASSERT(markMethod != NULL);
  14889. if (markMethod != NULL)
  14890. {
  14891. auto& vtableEntry = typeInstance->mVirtualMethodTable[markMethod->mVirtualTableIdx];
  14892. if (vtableEntry.mImplementingMethod.mTypeInstance != mModule->mContext->mBfObjectType)
  14893. {
  14894. auto impMethodInstance = (BfMethodInstance*)vtableEntry.mImplementingMethod;
  14895. bool needsCall = false;
  14896. if (allocFlags & BfAllocFlags_HasAppendWantMark)
  14897. needsCall = true;
  14898. if (!needsCall)
  14899. {
  14900. if (impMethodInstance != NULL)
  14901. {
  14902. needsCall = impMethodInstance->mMethodDef->mBody != NULL;
  14903. }
  14904. else
  14905. {
  14906. needsCall = true;
  14907. BF_ASSERT(vtableEntry.mImplementingMethod.mKind == BfMethodRefKind_AmbiguousRef);
  14908. }
  14909. }
  14910. if (!needsCall)
  14911. {
  14912. if (typeInstance->HasAppendedField(true))
  14913. needsCall = true;
  14914. }
  14915. if (needsCall)
  14916. {
  14917. SizedArray<BfIRValue, 1> irArgs;
  14918. irArgs.push_back(mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->MapType(mModule->mContext->mBfObjectType)));
  14919. auto gcType = mModule->ResolveTypeDef(mModule->mCompiler->mGCTypeDef);
  14920. BF_ASSERT(gcType != NULL);
  14921. if (gcType != NULL)
  14922. {
  14923. auto addStackObjMethod = mModule->GetMethodByName(gcType->ToTypeInstance(), "AddStackMarkableObject", 1);
  14924. BF_ASSERT(addStackObjMethod);
  14925. if (addStackObjMethod)
  14926. {
  14927. mModule->mBfIRBuilder->CreateCall(addStackObjMethod.mFunc, irArgs);
  14928. }
  14929. auto removeStackObjMethod = mModule->GetMethodByName(gcType->ToTypeInstance(), "RemoveStackMarkableObject", 1);
  14930. BF_ASSERT(removeStackObjMethod);
  14931. if (removeStackObjMethod)
  14932. {
  14933. mModule->AddDeferredCall(removeStackObjMethod, irArgs, allocTarget.mScopeData, allocNode);
  14934. }
  14935. }
  14936. }
  14937. }
  14938. }
  14939. }
  14940. }
  14941. auto origThisTypedValue = mResult;
  14942. auto thisTypedValue = mResult;
  14943. if (inlineTypeRef != NULL)
  14944. {
  14945. BfType* wantType = bindResult.mMethodInstance->GetOwner();
  14946. if (thisTypedValue.mType->IsPointer())
  14947. wantType = mModule->CreatePointerType(wantType);
  14948. thisTypedValue = mModule->Cast(allocNode, thisTypedValue, wantType);
  14949. }
  14950. if ((bindResult.mMethodInstance->mMethodDef->HasAppend()) && (mResult.mType->IsObject()))
  14951. {
  14952. BF_ASSERT(bindResult.mIRArgs[0].IsFake());
  14953. auto typeInst = mResult.mType->ToTypeInstance();
  14954. auto intPtrType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  14955. BfIRValue intPtrVal = mModule->CreateAlloca(intPtrType);
  14956. auto intPtrThisVal = mModule->mBfIRBuilder->CreatePtrToInt(thisTypedValue.mValue, (intPtrType->mSize == 4) ? BfTypeCode_Int32 : BfTypeCode_Int64);
  14957. auto curValPtr = mModule->mBfIRBuilder->CreateAdd(intPtrThisVal, mModule->GetConstValue(typeInst->mInstSize, intPtrType));
  14958. mModule->mBfIRBuilder->CreateStore(curValPtr, intPtrVal);
  14959. bindResult.mIRArgs[0] = intPtrVal;
  14960. }
  14961. if (!typeInstance->IsValuelessType())
  14962. bindResult.mIRArgs.Insert(0, thisTypedValue.mValue);
  14963. auto result = CreateCall(objCreateExpr, bindResult.mMethodInstance, bindResult.mFunc, false, bindResult.mIRArgs);
  14964. if ((result) && (!result.mType->IsVoid()))
  14965. mResult = result;
  14966. if (origThisTypedValue.mType != thisTypedValue.mType)
  14967. {
  14968. auto origThisType = origThisTypedValue.mType;
  14969. if (origThisType->IsPointer())
  14970. origThisType = origThisType->GetUnderlyingType();
  14971. auto origThisTypeInst = origThisType->ToTypeInstance();
  14972. if (origThisTypeInst != NULL)
  14973. {
  14974. BF_ASSERT(origThisTypeInst->IsAnonymousInitializerType());
  14975. auto ctorMethod = mModule->GetMethodByName(origThisTypeInst, "__BfCtor", 0);
  14976. if (!ctorMethod)
  14977. {
  14978. mModule->AssertErrorState();
  14979. }
  14980. else if ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) == 0)
  14981. {
  14982. SizedArray<BfIRValue, 1> irArgs;
  14983. irArgs.push_back(origThisTypedValue.mValue);
  14984. CreateCall(objCreateExpr, ctorMethod.mMethodInstance, ctorMethod.mFunc, false, irArgs);
  14985. }
  14986. }
  14987. }
  14988. }
  14989. }
  14990. if (((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) && (mModule->mCompiler->mCeMachine != NULL))
  14991. {
  14992. mModule->mCompiler->mCeMachine->ClearAppendAllocInfo();
  14993. }
  14994. if ((mResult) && (isStructAlloc))
  14995. {
  14996. if (mResult.mType->IsPointer())
  14997. {
  14998. mResult = mModule->LoadValue(mResult);
  14999. mResult = BfTypedValue(mResult.mValue, mResult.mType->GetUnderlyingType(), true);
  15000. }
  15001. else
  15002. mModule->Fail(StrFormat("Allocation specifier such as 'new' is required for reference type '%s'", mModule->TypeToString(mResult.mType).c_str()), objCreateExpr);
  15003. }
  15004. }
  15005. void BfExprEvaluator::Visit(BfBoxExpression* boxExpr)
  15006. {
  15007. /*if ((boxExpr->mAllocNode == NULL) || (boxExpr->mExpression == NULL))
  15008. {
  15009. mModule->AssertErrorState();
  15010. return;
  15011. }*/
  15012. BfTokenNode* newToken = NULL;
  15013. BfAllocTarget allocTarget;
  15014. ResolveAllocTarget(allocTarget, boxExpr->mAllocNode, newToken);
  15015. if ((boxExpr->mAllocNode != NULL) && (boxExpr->mAllocNode->mToken == BfToken_Scope))
  15016. {
  15017. if ((mBfEvalExprFlags & BfEvalExprFlags_FieldInitializer) != 0)
  15018. {
  15019. mModule->Warn(0, "This allocation will only be in scope during the constructor. Consider using a longer-term allocation such as 'new'", boxExpr->mAllocNode);
  15020. }
  15021. }
  15022. if (boxExpr->mExpression == NULL)
  15023. {
  15024. mModule->AssertErrorState();
  15025. return;
  15026. }
  15027. auto exprValue = mModule->CreateValueFromExpression(boxExpr->mExpression);
  15028. if (exprValue)
  15029. {
  15030. bool doFail = false;
  15031. bool doWarn = false;
  15032. BfType* boxedType = NULL;
  15033. if (exprValue.mType->IsGenericParam())
  15034. {
  15035. BF_ASSERT(mModule->mCurMethodInstance->mIsUnspecialized);
  15036. auto genericParamTarget = (BfGenericParamType*)exprValue.mType;
  15037. auto genericParamInstance = mModule->GetGenericParamInstance(genericParamTarget);
  15038. if ((genericParamInstance->mGenericParamFlags & (BfGenericParamFlag_Struct | BfGenericParamFlag_StructPtr | BfGenericParamFlag_Class)) == BfGenericParamFlag_Class)
  15039. doWarn = true;
  15040. if ((genericParamInstance->mTypeConstraint != NULL) && (genericParamInstance->mTypeConstraint->IsObjectOrInterface()))
  15041. doWarn = true;
  15042. boxedType = mModule->mContext->mBfObjectType;
  15043. }
  15044. else
  15045. {
  15046. doFail = !exprValue.mType->IsValueTypeOrValueTypePtr();
  15047. doWarn = exprValue.mType->IsObjectOrInterface();
  15048. }
  15049. if (doWarn)
  15050. {
  15051. mModule->Warn(0, StrFormat("Boxing is unnecessary since type '%s' is already a reference type.", mModule->TypeToString(exprValue.mType).c_str()), boxExpr->mExpression);
  15052. mResult = exprValue;
  15053. return;
  15054. }
  15055. if (doFail)
  15056. {
  15057. 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);
  15058. return;
  15059. }
  15060. if (boxedType == NULL)
  15061. boxedType = mModule->CreateBoxedType(exprValue.mType);
  15062. if (boxedType == NULL)
  15063. boxedType = mModule->mContext->mBfObjectType;
  15064. mResult = mModule->BoxValue(boxExpr->mExpression, exprValue, boxedType, allocTarget);
  15065. if (!mResult)
  15066. {
  15067. mModule->Fail(StrFormat("Type '%s' is not boxable", mModule->TypeToString(exprValue.mType).c_str()), boxExpr->mExpression);
  15068. return;
  15069. }
  15070. }
  15071. }
  15072. void BfExprEvaluator::ResolveAllocTarget(BfAllocTarget& allocTarget, BfAstNode* allocNode, BfTokenNode*& newToken, BfCustomAttributes** outCustomAttributes)
  15073. {
  15074. auto autoComplete = GetAutoComplete();
  15075. BfAttributeDirective* attributeDirective = NULL;
  15076. allocTarget.mRefNode = allocNode;
  15077. newToken = BfNodeDynCast<BfTokenNode>(allocNode);
  15078. if (allocNode == NULL)
  15079. {
  15080. // Scope
  15081. if (mModule->mCurMethodState != NULL)
  15082. allocTarget.mScopeData = mModule->mCurMethodState->mCurScope->GetTargetable();
  15083. }
  15084. else if (newToken == NULL)
  15085. {
  15086. if (auto scopeNode = BfNodeDynCast<BfScopeNode>(allocNode))
  15087. {
  15088. newToken = scopeNode->mScopeToken;
  15089. allocTarget.mScopeData = mModule->FindScope(scopeNode->GetTargetNode(), true);
  15090. if (autoComplete != NULL)
  15091. {
  15092. auto targetIdentifier = BfNodeDynCast<BfIdentifierNode>(scopeNode->mTargetNode);
  15093. if ((scopeNode->mTargetNode == NULL) || (targetIdentifier != NULL))
  15094. autoComplete->CheckLabel(targetIdentifier, scopeNode->mColonToken, allocTarget.mScopeData);
  15095. }
  15096. attributeDirective = scopeNode->mAttributes;
  15097. }
  15098. if (auto newNode = BfNodeDynCast<BfNewNode>(allocNode))
  15099. {
  15100. newToken = newNode->mNewToken;
  15101. if (auto allocExpr = BfNodeDynCast<BfExpression>(newNode->mAllocNode))
  15102. {
  15103. allocTarget.mCustomAllocator = mModule->CreateValueFromExpression(allocExpr);
  15104. allocTarget.mRefNode = allocExpr;
  15105. }
  15106. else if (auto scopedInvocationTarget = BfNodeDynCast<BfScopedInvocationTarget>(newNode->mAllocNode))
  15107. {
  15108. allocTarget.mScopedInvocationTarget = scopedInvocationTarget;
  15109. }
  15110. attributeDirective = newNode->mAttributes;
  15111. }
  15112. }
  15113. else if (newToken->GetToken() == BfToken_Scope)
  15114. {
  15115. if (mModule->mCurMethodState != NULL)
  15116. allocTarget.mScopeData = mModule->mCurMethodState->mCurScope->GetTargetable();
  15117. }
  15118. if (attributeDirective != NULL)
  15119. {
  15120. auto customAttrs = mModule->GetCustomAttributes(attributeDirective, BfAttributeTargets_Alloc, BfGetCustomAttributesFlags_AllowNonConstArgs, allocTarget.mCaptureInfo);
  15121. if (customAttrs != NULL)
  15122. {
  15123. for (auto& attrib : customAttrs->mAttributes)
  15124. {
  15125. if (attrib.mType->IsInstanceOf(mModule->mCompiler->mAlignAttributeTypeDef))
  15126. {
  15127. allocTarget.mAlignOverride = 16; // System conservative default
  15128. if (!attrib.mCtorArgs.IsEmpty())
  15129. {
  15130. BfIRConstHolder* constHolder = mModule->mCurTypeInstance->mConstHolder;
  15131. auto constant = constHolder->GetConstant(attrib.mCtorArgs[0]);
  15132. if (constant != NULL)
  15133. {
  15134. int alignOverride = (int)BF_MAX(1, constant->mInt64);
  15135. if ((alignOverride & (alignOverride - 1)) == 0)
  15136. allocTarget.mAlignOverride = alignOverride;
  15137. else
  15138. mModule->Fail("Alignment must be a power of 2", attrib.GetRefNode());
  15139. }
  15140. }
  15141. }
  15142. else if (attrib.mType->IsInstanceOf(mModule->mCompiler->mFriendAttributeTypeDef))
  15143. allocTarget.mIsFriend = true;
  15144. }
  15145. if (outCustomAttributes != NULL)
  15146. *outCustomAttributes = customAttrs;
  15147. else
  15148. delete customAttrs;
  15149. }
  15150. }
  15151. }
  15152. BfTypedValue BfExprEvaluator::MakeCallableTarget(BfAstNode* targetSrc, BfTypedValue target)
  15153. {
  15154. if ((target.mType->IsRef()) || (target.mType->IsPointer()))
  15155. {
  15156. auto underlying = target.mType->GetUnderlyingType();
  15157. bool underlyingIsStruct = underlying->IsStruct();
  15158. if (underlyingIsStruct)
  15159. {
  15160. target = mModule->LoadValue(target);
  15161. target.mType = underlying;
  15162. target.mKind = BfTypedValueKind_Addr;
  15163. }
  15164. }
  15165. if ((target.mType->IsStruct()) && (!target.IsAddr()))
  15166. {
  15167. if (IsConstEval())
  15168. return target;
  15169. target = mModule->MakeAddressable(target);
  15170. }
  15171. if (IsVar(target.mType))
  15172. {
  15173. target.mType = mModule->mContext->mBfObjectType;
  15174. return target;
  15175. }
  15176. if (target.mType->IsWrappableType())
  15177. {
  15178. auto primStructType = mModule->GetWrappedStructType(target.mType);
  15179. if (primStructType != NULL)
  15180. {
  15181. mModule->PopulateType(primStructType);
  15182. if (primStructType->IsTypedPrimitive())
  15183. {
  15184. // Type is already the same
  15185. target.mType = primStructType;
  15186. }
  15187. else if (target.IsAddr())
  15188. {
  15189. auto ptrType = mModule->CreatePointerType(primStructType);
  15190. if (primStructType->IsValuelessType())
  15191. target = BfTypedValue(target.mValue, primStructType, true);
  15192. else
  15193. target = BfTypedValue(mModule->mBfIRBuilder->CreateBitCast(target.mValue, mModule->mBfIRBuilder->MapType(ptrType)), primStructType, true);
  15194. }
  15195. else if ((primStructType->IsSplattable()) && (target.IsSplat()) && (!IsComptime()))
  15196. {
  15197. target.mType = primStructType;
  15198. target.mKind = BfTypedValueKind_SplatHead;
  15199. }
  15200. else
  15201. {
  15202. auto allocPtr = mModule->CreateAlloca(primStructType);
  15203. auto srcPtrType = mModule->mBfIRBuilder->CreateBitCast(allocPtr, mModule->mBfIRBuilder->GetPointerTo(mModule->mBfIRBuilder->MapType(target.mType)));
  15204. mModule->mBfIRBuilder->CreateStore(target.mValue, srcPtrType);
  15205. target = BfTypedValue(allocPtr, primStructType, true);
  15206. }
  15207. }
  15208. return target;
  15209. }
  15210. if (target.mType->IsGenericParam())
  15211. {
  15212. target.mType = mModule->mContext->mBfObjectType;
  15213. return target;
  15214. }
  15215. if ((!target.mType->IsTypeInstance()) && (!target.mType->IsConcreteInterfaceType()))
  15216. {
  15217. mModule->Fail(StrFormat("Methods cannot be called on type '%s'", mModule->TypeToString(target.mType).c_str()), targetSrc);
  15218. return BfTypedValue();
  15219. }
  15220. return target;
  15221. }
  15222. int BfExprEvaluator::GetMixinVariable()
  15223. {
  15224. auto curMethodState = mModule->mCurMethodState;
  15225. for (int localIdx = (int)curMethodState->mLocals.size() - 1; localIdx >= 0; localIdx--)
  15226. {
  15227. auto varDecl = curMethodState->mLocals[localIdx];
  15228. if (varDecl->mName == "mixin")
  15229. return localIdx;
  15230. }
  15231. return -1;
  15232. }
  15233. BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc, BfTypeInstance* curTypeInst, BfMethodDef* methodDef, BfMethodMatcher& methodMatcher, BfType** overrideReturnType)
  15234. {
  15235. bool failed = false;
  15236. BfTypeVector resolvedGenericArguments;
  15237. BfMethodState* rootMethodState = NULL;
  15238. if (mModule->mCurMethodState != NULL)
  15239. rootMethodState = mModule->mCurMethodState->GetRootMethodState();
  15240. int localInferrableGenericArgCount = -1;
  15241. if ((methodMatcher.mBestMethodGenericArguments.size() == 0) && (!methodMatcher.mExplicitMethodGenericArguments.IsEmpty()))
  15242. {
  15243. int uniqueGenericStartIdx = mModule->GetLocalInferrableGenericArgCount(methodDef);
  15244. int64 genericArgCountDiff = (int)methodMatcher.mExplicitMethodGenericArguments.size() + uniqueGenericStartIdx - (int)methodDef->mGenericParams.size();
  15245. BfInvocationExpression* invocationExpr = NULL;
  15246. if (mModule->mParentNodeEntry != NULL)
  15247. {
  15248. invocationExpr = BfNodeDynCast<BfInvocationExpression>(mModule->mParentNodeEntry->mNode);
  15249. }
  15250. if (genericArgCountDiff > 0)
  15251. {
  15252. BfAstNode* errorNode = targetSrc;
  15253. if ((invocationExpr != NULL) && (invocationExpr->mGenericArgs != NULL))
  15254. {
  15255. errorNode = invocationExpr->mGenericArgs->mGenericArgs[(int)methodDef->mGenericParams.size()];
  15256. if (errorNode == NULL)
  15257. invocationExpr->mGenericArgs->mCommas.GetSafe((int)methodDef->mGenericParams.size() - 1, errorNode);
  15258. if (errorNode == NULL)
  15259. errorNode = targetSrc;
  15260. }
  15261. mModule->Fail(StrFormat("Too many generic arguments, expected %d fewer", genericArgCountDiff), errorNode);
  15262. }
  15263. else if ((genericArgCountDiff < 0) && (!methodMatcher.mHadOpenGenericArguments))
  15264. {
  15265. BfAstNode* errorNode = targetSrc;
  15266. if ((invocationExpr != NULL) && (invocationExpr->mGenericArgs != NULL) && (invocationExpr->mGenericArgs->mCloseChevron != NULL))
  15267. errorNode = invocationExpr->mGenericArgs->mCloseChevron;
  15268. mModule->Fail(StrFormat("Too few generic arguments, expected %d more", -genericArgCountDiff), errorNode);
  15269. }
  15270. methodMatcher.mBestMethodGenericArguments.resize(methodDef->mGenericParams.size());
  15271. for (int i = 0; i < std::min(methodDef->mGenericParams.size() - uniqueGenericStartIdx, methodMatcher.mExplicitMethodGenericArguments.size()); i++)
  15272. {
  15273. methodMatcher.mBestMethodGenericArguments[i + uniqueGenericStartIdx] = methodMatcher.mExplicitMethodGenericArguments[i];
  15274. }
  15275. }
  15276. BfMethodInstance* unspecializedMethod = NULL;
  15277. bool hasVarGenerics = false;
  15278. for (int checkGenericIdx = 0; checkGenericIdx < (int)methodMatcher.mBestMethodGenericArguments.size(); checkGenericIdx++)
  15279. {
  15280. BfMethodInstance* outerMethodInstance = NULL;
  15281. auto& genericArg = methodMatcher.mBestMethodGenericArguments[checkGenericIdx];
  15282. if (genericArg == NULL)
  15283. {
  15284. if ((methodDef->mIsLocalMethod) && (checkGenericIdx < mModule->mCurMethodInstance->GetNumGenericArguments()))
  15285. {
  15286. // If the root method is generic and we need that param then use that...
  15287. auto rootMethodInstance = rootMethodState->mMethodInstance;
  15288. if ((rootMethodInstance->mMethodInfoEx != NULL) && (checkGenericIdx < rootMethodInstance->mMethodInfoEx->mMethodGenericArguments.size()))
  15289. {
  15290. genericArg = rootMethodInstance->mMethodInfoEx->mMethodGenericArguments[checkGenericIdx];
  15291. }
  15292. else
  15293. {
  15294. if (localInferrableGenericArgCount == -1)
  15295. localInferrableGenericArgCount = mModule->GetLocalInferrableGenericArgCount(methodDef);
  15296. // Otherwise we can only infer generics at the level that the called method was contained
  15297. if (checkGenericIdx < localInferrableGenericArgCount)
  15298. genericArg = mModule->mCurMethodInstance->mMethodInfoEx->mMethodGenericArguments[checkGenericIdx];
  15299. }
  15300. }
  15301. }
  15302. if (genericArg == NULL)
  15303. {
  15304. if (unspecializedMethod == NULL)
  15305. unspecializedMethod = mModule->GetRawMethodInstance(curTypeInst, methodDef);
  15306. auto genericParam = unspecializedMethod->mMethodInfoEx->mGenericParams[checkGenericIdx];
  15307. if ((genericParam->mTypeConstraint != NULL) && (genericParam->mTypeConstraint->IsDelegate()))
  15308. {
  15309. // The only other option was to bind to a MethodRef
  15310. genericArg = mModule->ResolveGenericType(genericParam->mTypeConstraint, NULL, &methodMatcher.mBestMethodGenericArguments, mModule->mCurTypeInstance);
  15311. }
  15312. else
  15313. {
  15314. if (((genericParam->mGenericParamFlags & BfGenericParamFlag_Const) != 0) && (genericParam->mTypeConstraint != NULL))
  15315. {
  15316. for (int paramIdx = 0; paramIdx < (int)unspecializedMethod->mDefaultValues.size(); paramIdx++)
  15317. {
  15318. auto defaultVal = unspecializedMethod->mDefaultValues[paramIdx];
  15319. if (!defaultVal)
  15320. continue;
  15321. auto& param = unspecializedMethod->mParams[paramIdx];
  15322. if (param.mResolvedType->IsGenericParam())
  15323. {
  15324. auto genericParamType = (BfGenericParamType*)param.mResolvedType;
  15325. if ((genericParamType->mGenericParamKind == BfGenericParamKind_Method) && (genericParamType->mGenericParamIdx == checkGenericIdx))
  15326. {
  15327. BfTypedValue constExprVal;
  15328. constExprVal.mType = genericParam->mTypeConstraint;
  15329. auto constant = curTypeInst->mConstHolder->GetConstant(defaultVal.mValue);
  15330. constExprVal.mValue = mModule->ConstantToCurrent(constant, curTypeInst->mConstHolder, genericParam->mTypeConstraint);
  15331. genericArg = mModule->CreateConstExprValueType(constExprVal);
  15332. }
  15333. }
  15334. }
  15335. }
  15336. }
  15337. if (genericArg == NULL)
  15338. {
  15339. BfGenericInferContext genericInferContext;
  15340. genericInferContext.mModule = mModule;
  15341. genericInferContext.mCheckMethodGenericArguments = &methodMatcher.mBestMethodGenericArguments;
  15342. genericInferContext.InferGenericArguments(unspecializedMethod);
  15343. }
  15344. if (genericArg == NULL)
  15345. {
  15346. failed = true;
  15347. BfError* error = mModule->Fail(StrFormat("Unable to determine generic argument '%s'", methodDef->mGenericParams[checkGenericIdx]->mName.c_str()).c_str(), targetSrc);
  15348. if ((genericParam->mTypeConstraint != NULL) && (!genericParam->mTypeConstraint->IsUnspecializedType()))
  15349. genericArg = genericParam->mTypeConstraint;
  15350. else
  15351. genericArg = mModule->mContext->mBfObjectType;
  15352. if (error != NULL)
  15353. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), unspecializedMethod->mMethodDef->GetRefNode());
  15354. }
  15355. }
  15356. if (genericArg->IsVar())
  15357. {
  15358. //BF_ASSERT(methodMatcher.mHasVarArguments);
  15359. hasVarGenerics = true;
  15360. }
  15361. if (genericArg->IsIntUnknown())
  15362. genericArg = mModule->FixIntUnknown(genericArg);
  15363. auto resolvedGenericArg = genericArg;
  15364. resolvedGenericArguments.push_back(genericArg);
  15365. }
  15366. BfTypeInstance* foreignType = NULL;
  15367. BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None;
  15368. if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) && (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mInlineAttributeTypeDef)))
  15369. {
  15370. flags = (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_ForceInline);
  15371. mModule->mAttributeState->mUsed = true;
  15372. }
  15373. if ((!mModule->mCurTypeInstance->IsInterface()) && (methodDef->mBody != NULL))
  15374. {
  15375. if ((methodMatcher.mBypassVirtual) && (methodMatcher.mBestMethodTypeInstance->IsInterface()))
  15376. {
  15377. // This is an explicit 'base' call to a default interface method. We pull the methodDef into our own concrete type.
  15378. foreignType = curTypeInst;
  15379. curTypeInst = mModule->mCurTypeInstance;
  15380. flags = (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_ForeignMethodDef);
  15381. }
  15382. else if ((methodDef->mIsStatic) && (curTypeInst->IsInterface()))
  15383. {
  15384. if (mModule->TypeIsSubTypeOf(mModule->mCurTypeInstance, curTypeInst))
  15385. {
  15386. // This is an explicit call to a default static interface method. We pull the methodDef into our own concrete type.
  15387. foreignType = curTypeInst;
  15388. curTypeInst = mModule->mCurTypeInstance;
  15389. flags = (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_ForeignMethodDef);
  15390. }
  15391. }
  15392. }
  15393. if (hasVarGenerics)
  15394. return BfModuleMethodInstance();
  15395. BfModuleMethodInstance moduleMethodInstance;
  15396. if (methodMatcher.mBestMethodInstance)
  15397. {
  15398. moduleMethodInstance = methodMatcher.mBestMethodInstance;
  15399. }
  15400. else
  15401. {
  15402. moduleMethodInstance = mModule->GetMethodInstance(curTypeInst, methodDef, resolvedGenericArguments, flags, foreignType);
  15403. }
  15404. if (mModule->IsSkippingExtraResolveChecks())
  15405. {
  15406. //BF_ASSERT(methodInstance.mFunc == NULL);
  15407. }
  15408. if (moduleMethodInstance.mMethodInstance == NULL)
  15409. return NULL;
  15410. if (methodDef->IsEmptyPartial())
  15411. return moduleMethodInstance;
  15412. if (moduleMethodInstance.mMethodInstance->mMethodInfoEx != NULL)
  15413. {
  15414. for (int checkGenericIdx = 0; checkGenericIdx < (int)moduleMethodInstance.mMethodInstance->mMethodInfoEx->mGenericParams.size(); checkGenericIdx++)
  15415. {
  15416. auto genericParams = moduleMethodInstance.mMethodInstance->mMethodInfoEx->mGenericParams[checkGenericIdx];
  15417. BfTypeVector* checkMethodGenericArgs = NULL;
  15418. BfType* genericArg = NULL;
  15419. if (checkGenericIdx < (int)methodMatcher.mBestMethodGenericArguments.size())
  15420. {
  15421. genericArg = methodMatcher.mBestMethodGenericArguments[checkGenericIdx];
  15422. }
  15423. else
  15424. {
  15425. checkMethodGenericArgs = &methodMatcher.mBestMethodGenericArguments;
  15426. genericArg = genericParams->mExternType;
  15427. auto owner = moduleMethodInstance.mMethodInstance->GetOwner();
  15428. BfTypeVector* typeGenericArguments = NULL;
  15429. if (owner->mGenericTypeInfo != NULL)
  15430. typeGenericArguments = &owner->mGenericTypeInfo->mTypeGenericArguments;
  15431. //genericArg = mModule->ResolveGenericType(genericArg, typeGenericArguments, checkMethodGenericArgs);
  15432. }
  15433. if (genericArg->IsVar())
  15434. continue;
  15435. BfAstNode* paramSrc;
  15436. if (checkGenericIdx >= methodMatcher.mBestMethodGenericArgumentSrcs.size())
  15437. {
  15438. paramSrc = targetSrc;
  15439. }
  15440. else
  15441. paramSrc = methodMatcher.mArguments[methodMatcher.mBestMethodGenericArgumentSrcs[checkGenericIdx]].mExpression;
  15442. // Note: don't pass methodMatcher.mBestMethodGenericArguments into here, this method is already specialized
  15443. BfError* error = NULL;
  15444. if (!mModule->CheckGenericConstraints(BfGenericParamSource(moduleMethodInstance.mMethodInstance), genericArg, paramSrc, genericParams, NULL,
  15445. failed ? NULL : &error))
  15446. {
  15447. if (moduleMethodInstance.mMethodInstance->IsSpecializedGenericMethod())
  15448. {
  15449. // We mark this as failed to make sure we don't try to process a method that doesn't even follow the constraints
  15450. moduleMethodInstance.mMethodInstance->mFailedConstraints = true;
  15451. }
  15452. if (moduleMethodInstance.mMethodInstance->mMethodDef->mMethodDeclaration != NULL)
  15453. {
  15454. if (error != NULL)
  15455. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), moduleMethodInstance.mMethodInstance->mMethodDef->GetRefNode());
  15456. }
  15457. }
  15458. }
  15459. }
  15460. else
  15461. BF_ASSERT(methodMatcher.mBestMethodGenericArguments.IsEmpty());
  15462. if ((overrideReturnType != NULL) && (moduleMethodInstance.mMethodInstance->mIsUnspecializedVariation) &&
  15463. ((moduleMethodInstance.mMethodInstance->mReturnType->IsUnspecializedTypeVariation()) || (moduleMethodInstance.mMethodInstance->mReturnType->IsVar())))
  15464. {
  15465. if (unspecializedMethod == NULL)
  15466. unspecializedMethod = mModule->GetRawMethodInstance(curTypeInst, methodDef);
  15467. BfTypeVector* typeGenericArgs = NULL;
  15468. auto typeUnspecMethodInstance = unspecializedMethod;
  15469. if (curTypeInst->IsUnspecializedTypeVariation())
  15470. {
  15471. typeUnspecMethodInstance = mModule->GetUnspecializedMethodInstance(typeUnspecMethodInstance, true);
  15472. typeGenericArgs = &curTypeInst->mGenericTypeInfo->mTypeGenericArguments;
  15473. }
  15474. BfType* specializedReturnType = mModule->ResolveGenericType(typeUnspecMethodInstance->mReturnType, typeGenericArgs, &methodMatcher.mBestMethodGenericArguments,
  15475. mModule->mCurTypeInstance);
  15476. if (specializedReturnType != NULL)
  15477. *overrideReturnType = specializedReturnType;
  15478. }
  15479. return moduleMethodInstance;
  15480. }
  15481. BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfMethodMatcher& methodMatcher)
  15482. {
  15483. if (!methodMatcher.mBestMethodInstance)
  15484. methodMatcher.mBestMethodInstance = GetSelectedMethod(methodMatcher.mTargetSrc, methodMatcher.mBestMethodTypeInstance, methodMatcher.mBestMethodDef, methodMatcher);
  15485. return methodMatcher.mBestMethodInstance;
  15486. }
  15487. void BfExprEvaluator::CheckLocalMethods(BfAstNode* targetSrc, BfTypeInstance* typeInstance, const StringImpl& methodName, BfMethodMatcher& methodMatcher, BfMethodType methodType)
  15488. {
  15489. auto _GetNodeId = [&]()
  15490. {
  15491. auto parser = targetSrc->GetSourceData()->ToParserData();
  15492. return ((int64)parser->mDataId << 32) + targetSrc->GetSrcStart();
  15493. };
  15494. BfMethodState* ctxMethodState = NULL;
  15495. BfClosureInstanceInfo* ctxClosureInstanceInfo = NULL;
  15496. if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL))
  15497. {
  15498. ctxClosureInstanceInfo = mModule->mCurMethodState->mClosureState->mClosureInstanceInfo;
  15499. ctxMethodState = mModule->mCurMethodState;
  15500. }
  15501. bool atCtxMethodState = false;
  15502. auto checkMethodState = mModule->mCurMethodState;
  15503. auto rootMethodState = checkMethodState;
  15504. while (checkMethodState != NULL)
  15505. {
  15506. rootMethodState = checkMethodState;
  15507. if (checkMethodState == ctxMethodState)
  15508. atCtxMethodState = true;
  15509. if ((ctxClosureInstanceInfo != NULL) && (!ctxMethodState->mClosureState->mCapturing))
  15510. {
  15511. BfMethodDef* localMethodDef = NULL;
  15512. if (ctxClosureInstanceInfo->mLocalMethodBindings.TryGetValue(_GetNodeId(), &localMethodDef))
  15513. {
  15514. methodMatcher.CheckMethod(mModule->mCurTypeInstance, mModule->mCurTypeInstance, localMethodDef, true);
  15515. BF_ASSERT(methodMatcher.mBestMethodDef != NULL);
  15516. return;
  15517. }
  15518. }
  15519. else
  15520. {
  15521. BfLocalMethod* matchedLocalMethod = NULL;
  15522. BfLocalMethod* localMethod = NULL;
  15523. if (checkMethodState->mLocalMethodMap.TryGetValue(methodName, &localMethod))
  15524. {
  15525. auto typeInst = mModule->mCurTypeInstance;
  15526. if (checkMethodState->mMixinState != NULL)
  15527. typeInst = checkMethodState->mMixinState->mMixinMethodInstance->GetOwner();
  15528. while (localMethod != NULL)
  15529. {
  15530. auto methodDef = mModule->GetLocalMethodDef(localMethod);
  15531. if (methodDef->mMethodType == methodType)
  15532. {
  15533. methodMatcher.CheckMethod(mModule->mCurTypeInstance, typeInst, methodDef, true);
  15534. if (methodMatcher.mBestMethodDef == methodDef)
  15535. matchedLocalMethod = localMethod;
  15536. }
  15537. localMethod = localMethod->mNextWithSameName;
  15538. }
  15539. }
  15540. if (matchedLocalMethod != NULL)
  15541. {
  15542. if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mCapturing))
  15543. {
  15544. BfModuleMethodInstance moduleMethodInstance = GetSelectedMethod(targetSrc, typeInstance, matchedLocalMethod->mMethodDef, methodMatcher);
  15545. if (moduleMethodInstance)
  15546. {
  15547. auto methodInstance = moduleMethodInstance.mMethodInstance;
  15548. if ((methodInstance->mMethodInfoEx != NULL) && (methodInstance->mMethodInfoEx->mClosureInstanceInfo->mCaptureClosureState != NULL))
  15549. {
  15550. // The called method is calling us from its mLocalMethodRefs set. Stretch our mCaptureStartAccessId back to incorporate its
  15551. // captures as well
  15552. if (methodInstance->mMethodInfoEx->mClosureInstanceInfo->mCaptureClosureState->mCaptureStartAccessId < mModule->mCurMethodState->mClosureState->mCaptureStartAccessId)
  15553. mModule->mCurMethodState->mClosureState->mCaptureStartAccessId = methodInstance->mMethodInfoEx->mClosureInstanceInfo->mCaptureClosureState->mCaptureStartAccessId;
  15554. }
  15555. else
  15556. {
  15557. if (methodInstance->mDisallowCalling) // We need to process the captures from this guy
  15558. {
  15559. if (mModule->mCurMethodState->mClosureState->mLocalMethodRefSet.Add(methodInstance))
  15560. mModule->mCurMethodState->mClosureState->mLocalMethodRefs.Add(methodInstance);
  15561. }
  15562. }
  15563. }
  15564. }
  15565. if (ctxClosureInstanceInfo != NULL)
  15566. {
  15567. BF_ASSERT(mModule->mCurMethodState->mClosureState->mCapturing);
  15568. ctxClosureInstanceInfo->mLocalMethodBindings[_GetNodeId()] = methodMatcher.mBestMethodDef;
  15569. }
  15570. break;
  15571. }
  15572. }
  15573. checkMethodState = checkMethodState->mPrevMethodState;
  15574. }
  15575. }
  15576. void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, bool allowImplicitThis, const StringImpl& name, const BfSizedArray<BfExpression*>& arguments, const BfMethodGenericArguments& methodGenericArgs)
  15577. {
  15578. if (mModule->mCurMethodState == NULL)
  15579. return;
  15580. if (mDeferCallData != NULL)
  15581. {
  15582. mModule->Fail("Mixins cannot be directly deferred. Consider wrapping in a block.", targetSrc);
  15583. }
  15584. BfAstNode* origTargetSrc = targetSrc;
  15585. BfScopedInvocationTarget* scopedInvocationTarget = NULL;
  15586. if (mModule->mParentNodeEntry != NULL)
  15587. {
  15588. if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(mModule->mParentNodeEntry->mNode))
  15589. {
  15590. scopedInvocationTarget = BfNodeDynCast<BfScopedInvocationTarget>(invocationExpr->mTarget);
  15591. }
  15592. }
  15593. auto targetNameNode = targetSrc;
  15594. if (scopedInvocationTarget != NULL)
  15595. {
  15596. targetNameNode = scopedInvocationTarget->GetScopeNameNode();
  15597. }
  15598. while (true)
  15599. {
  15600. if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(targetNameNode))
  15601. {
  15602. targetNameNode = qualifiedNameNode->mRight;
  15603. continue;
  15604. }
  15605. if (auto memberRefExpr = BfNodeDynCast<BfMemberReferenceExpression>(targetNameNode))
  15606. {
  15607. targetNameNode = memberRefExpr->mMemberName;
  15608. continue;
  15609. }
  15610. break;
  15611. }
  15612. BfTypeInstance* mixinClass = NULL;
  15613. if (target.mType != NULL)
  15614. mixinClass = target.mType->ToTypeInstance();
  15615. int inLine = mModule->mCurFilePosition.mCurLine;
  15616. SizedArray<BfResolvedArg, 4> args;
  15617. SizedArray<BfExprEvaluator*, 8> argExprEvaluators;
  15618. defer
  15619. (
  15620. {
  15621. for (auto exprEvaluator : argExprEvaluators)
  15622. delete exprEvaluator;
  15623. }
  15624. );
  15625. auto _AddArg = [&](BfExpression* argExpr)
  15626. {
  15627. BfResolvedArg resolvedArg;
  15628. argExprEvaluators.push_back(new BfExprEvaluator(mModule));
  15629. BfExprEvaluator* exprEvaluator = argExprEvaluators.back();
  15630. exprEvaluator->mResolveGenericParam = false;
  15631. exprEvaluator->mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator->mBfEvalExprFlags | BfEvalExprFlags_NoCast | BfEvalExprFlags_AllowRefExpr | BfEvalExprFlags_AllowOutExpr);
  15632. bool deferExpr = false;
  15633. if (auto variableDecl = BfNodeDynCast<BfVariableDeclaration>(argExpr))
  15634. {
  15635. deferExpr = true;
  15636. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_VariableDeclaration);
  15637. }
  15638. if (deferExpr)
  15639. {
  15640. //
  15641. }
  15642. else if (argExpr != NULL)
  15643. exprEvaluator->Evaluate(argExpr, false, false, true);
  15644. else
  15645. mModule->Fail("Missing argument", targetSrc);
  15646. auto argValue = exprEvaluator->mResult;
  15647. mModule->FixIntUnknown(argValue);
  15648. if (argValue)
  15649. {
  15650. if (argValue.mType->IsRef())
  15651. {
  15652. exprEvaluator->FinishExpressionResult();
  15653. }
  15654. }
  15655. resolvedArg.mTypedValue = argValue;
  15656. resolvedArg.mExpression = argExpr;
  15657. args.push_back(resolvedArg);
  15658. };
  15659. for (BfExpression* argExpr : arguments)
  15660. {
  15661. _AddArg(argExpr);
  15662. }
  15663. auto autoComplete = GetAutoComplete();
  15664. if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo) && (autoComplete->mMethodMatchInfo != NULL) && (autoComplete->mMethodMatchInfo->mInstanceList.size() != 0))
  15665. autoComplete->mIsCapturingMethodMatchInfo = false;
  15666. BfMethodMatcher methodMatcher(targetSrc, mModule, name, args, methodGenericArgs);
  15667. methodMatcher.mMethodType = BfMethodType_Mixin;
  15668. methodMatcher.mSkipImplicitParams = true;
  15669. auto curTypeInst = mModule->mCurTypeInstance;
  15670. if (mixinClass != NULL)
  15671. curTypeInst = mixinClass;
  15672. if (target.mType == NULL)
  15673. {
  15674. CheckLocalMethods(targetSrc, curTypeInst, name, methodMatcher, BfMethodType_Mixin);
  15675. }
  15676. if (methodMatcher.mBestMethodDef == NULL)
  15677. methodMatcher.mBestMethodDef = methodMatcher.mBackupMethodDef;
  15678. if (methodMatcher.mBestMethodDef == NULL)
  15679. {
  15680. if (mixinClass != NULL)
  15681. methodMatcher.CheckType(mixinClass, BfTypedValue(), false);
  15682. else
  15683. methodMatcher.CheckType(mModule->mCurTypeInstance, BfTypedValue(), false);
  15684. }
  15685. if ((methodMatcher.mBestMethodDef == NULL) && (target.mType == NULL) && (mModule->mContext->mCurTypeState != NULL))
  15686. {
  15687. BF_ASSERT(mModule->mCurTypeInstance == mModule->mContext->mCurTypeState->mType);
  15688. BfGlobalLookup globalLookup;
  15689. globalLookup.mKind = BfGlobalLookup::Kind_Method;
  15690. globalLookup.mName = name;
  15691. mModule->PopulateGlobalContainersList(globalLookup);
  15692. for (auto& globalContainer : mModule->mContext->mCurTypeState->mGlobalContainers)
  15693. {
  15694. if (globalContainer.mTypeInst == NULL)
  15695. continue;
  15696. methodMatcher.CheckType(globalContainer.mTypeInst, BfTypedValue(), false);
  15697. if (methodMatcher.mBestMethodDef != NULL)
  15698. break;
  15699. }
  15700. }
  15701. if (methodMatcher.mBestMethodDef == NULL)
  15702. {
  15703. BfStaticSearch* staticSearch = mModule->GetStaticSearch();
  15704. if (staticSearch != NULL)
  15705. {
  15706. for (auto typeInst : staticSearch->mStaticTypes)
  15707. {
  15708. if (methodMatcher.CheckType(typeInst, BfTypedValue(), false))
  15709. {
  15710. if (methodMatcher.mBestMethodDef != NULL)
  15711. break;
  15712. }
  15713. }
  15714. }
  15715. }
  15716. if (methodMatcher.mBestMethodDef == NULL)
  15717. {
  15718. mModule->Fail("Cannot find mixin", targetSrc);
  15719. return;
  15720. }
  15721. auto resolvePassData = mModule->mCompiler->mResolvePassData;
  15722. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(targetNameNode)) && (autoComplete->mDefType == NULL))
  15723. {
  15724. autoComplete->mInsertStartIdx = targetNameNode->GetSrcStart();
  15725. autoComplete->mInsertEndIdx = targetNameNode->GetSrcEnd();
  15726. autoComplete->mDefType = methodMatcher.mBestMethodTypeInstance->mTypeDef;
  15727. autoComplete->mDefMethod = methodMatcher.mBestMethodDef;
  15728. autoComplete->SetDefinitionLocation(methodMatcher.mBestMethodDef->GetMethodDeclaration()->mNameNode);
  15729. }
  15730. if ((mModule->mCompiler->mResolvePassData != NULL) && (mModule->mCompiler->mResolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Method))
  15731. {
  15732. targetNameNode->SetSrcEnd(targetNameNode->GetSrcEnd() - 1);
  15733. mModule->mCompiler->mResolvePassData->HandleMethodReference(targetNameNode, methodMatcher.mBestMethodTypeInstance->mTypeDef, methodMatcher.mBestMethodDef);
  15734. targetNameNode->SetSrcEnd(targetNameNode->GetSrcEnd() + 1);
  15735. }
  15736. auto curMethodState = mModule->mCurMethodState;
  15737. auto moduleMethodInstance = GetSelectedMethod(targetSrc, methodMatcher.mBestMethodTypeInstance, methodMatcher.mBestMethodDef, methodMatcher);
  15738. if (!moduleMethodInstance)
  15739. {
  15740. if (methodMatcher.mHasVarArguments)
  15741. {
  15742. mResult = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Var));
  15743. return;
  15744. }
  15745. mModule->Fail("Failed to get selected mixin", targetSrc);
  15746. return;
  15747. }
  15748. if (!mModule->CheckUseMethodInstance(moduleMethodInstance.mMethodInstance, targetSrc))
  15749. return;
  15750. auto methodInstance = moduleMethodInstance.mMethodInstance;
  15751. PerformCallChecks(methodInstance, targetSrc);
  15752. for (int checkGenericIdx = 0; checkGenericIdx < (int)methodMatcher.mBestMethodGenericArguments.size(); checkGenericIdx++)
  15753. {
  15754. auto& genericParams = methodInstance->mMethodInfoEx->mGenericParams;
  15755. auto genericArg = methodMatcher.mBestMethodGenericArguments[checkGenericIdx];
  15756. if (genericArg->IsVar())
  15757. continue;
  15758. BfAstNode* paramSrc;
  15759. if (methodMatcher.mBestMethodGenericArgumentSrcs.size() == 0)
  15760. paramSrc = targetSrc;
  15761. else
  15762. paramSrc = methodMatcher.mArguments[methodMatcher.mBestMethodGenericArgumentSrcs[checkGenericIdx]].mExpression;
  15763. // Note: don't pass methodMatcher.mBestMethodGenericArguments into here, this method is already specialized
  15764. BfError* error = NULL;
  15765. if (!mModule->CheckGenericConstraints(BfGenericParamSource(methodInstance), genericArg, paramSrc, genericParams[checkGenericIdx], NULL, &error))
  15766. {
  15767. if (methodInstance->mMethodDef->mMethodDeclaration != NULL)
  15768. {
  15769. if (error != NULL)
  15770. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
  15771. }
  15772. }
  15773. }
  15774. if (curMethodState->mCurScope->mMixinDepth >= 128)
  15775. {
  15776. mModule->Fail("Maximum nested mixin depth exceeded", targetSrc);
  15777. return;
  15778. }
  15779. // Check circular ref based on methodInstance. We must check the arg types since we could be making progress in mixin evaluation
  15780. // based on method selection within the mixin dependent on args
  15781. {
  15782. bool hasCircularRef = false;
  15783. BfMixinState* checkMixinState = NULL;
  15784. auto checkMethodState = curMethodState;
  15785. while (checkMethodState != NULL)
  15786. {
  15787. auto curMixinState = checkMethodState->mMixinState;
  15788. while (curMixinState != NULL)
  15789. {
  15790. if ((curMixinState->mDoCircularVarResult) && (curMixinState->mMixinMethodInstance == methodInstance))
  15791. {
  15792. mResult = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Var));
  15793. return;
  15794. }
  15795. if ((!curMixinState->mCheckedCircularRef) && (curMixinState->mMixinMethodInstance == methodInstance))
  15796. {
  15797. checkMixinState = curMixinState;
  15798. checkMixinState->mCheckedCircularRef = true;
  15799. }
  15800. else if (checkMixinState != NULL)
  15801. {
  15802. if ((curMixinState->mMixinMethodInstance == checkMixinState->mMixinMethodInstance) &&
  15803. (curMixinState->mArgTypes == checkMixinState->mArgTypes) &&
  15804. (curMixinState->mArgConsts.mSize == checkMixinState->mArgConsts.mSize))
  15805. {
  15806. bool constsMatch = true;
  15807. for (int i = 0; i < curMixinState->mArgConsts.mSize; i++)
  15808. {
  15809. if (!mModule->mBfIRBuilder->CheckConstEquality(curMixinState->mArgConsts[i], checkMixinState->mArgConsts[i]))
  15810. {
  15811. constsMatch = false;
  15812. break;
  15813. }
  15814. }
  15815. if (constsMatch)
  15816. hasCircularRef = true;
  15817. }
  15818. }
  15819. curMixinState = curMixinState->mPrevMixinState;
  15820. }
  15821. checkMethodState = checkMethodState->mPrevMethodState;
  15822. }
  15823. if (hasCircularRef)
  15824. {
  15825. for (auto argType : checkMixinState->mArgTypes)
  15826. {
  15827. if (argType->IsVar())
  15828. checkMixinState->mDoCircularVarResult = true;
  15829. }
  15830. if (checkMixinState->mDoCircularVarResult)
  15831. {
  15832. mResult = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Var));
  15833. return;
  15834. }
  15835. mModule->Fail("Circular reference detected between mixins", targetSrc);
  15836. return;
  15837. }
  15838. }
  15839. AddCallDependencies(methodInstance);
  15840. if (!methodMatcher.mBestMethodDef->mIsStatic)
  15841. {
  15842. if ((!target) && (allowImplicitThis))
  15843. target = mModule->GetThis();
  15844. if (!target)
  15845. {
  15846. BfError* error = mModule->Fail(StrFormat("An instance reference is required to invoke the non-static mixin '%s'",
  15847. mModule->MethodToString(methodInstance).c_str()), targetSrc);
  15848. if ((error != NULL) && (methodInstance->mMethodDef->GetRefNode() != NULL))
  15849. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
  15850. }
  15851. }
  15852. else
  15853. {
  15854. if (target)
  15855. {
  15856. BfError* error = mModule->Fail(StrFormat("Mixin '%s' cannot be accessed with an instance reference; qualify it with a type name instead",
  15857. mModule->MethodToString(methodInstance).c_str()), targetSrc);
  15858. if ((error != NULL) && (methodInstance->mMethodDef->GetRefNode() != NULL))
  15859. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
  15860. }
  15861. }
  15862. int methodParamCount = (int)methodInstance->GetParamCount();
  15863. // Implicit params are ignored for calling- they should be resolved at the injection site
  15864. int implicitParamCount = methodInstance->GetImplicitParamCount();
  15865. int explicitParamCount = methodParamCount - implicitParamCount;
  15866. while ((int)args.size() < explicitParamCount)
  15867. {
  15868. int argIdx = (int)args.size();
  15869. BfExpression* expr = methodInstance->GetParamInitializer(argIdx);
  15870. if (expr == NULL)
  15871. break;
  15872. _AddArg(expr);
  15873. }
  15874. if ((int)args.size() < explicitParamCount)
  15875. {
  15876. BfError* error = mModule->Fail(StrFormat("Not enough arguments specified, expected %d more.", explicitParamCount - (int)arguments.size()), targetSrc);
  15877. if ((error != NULL) && (methodInstance->mMethodDef->GetRefNode() != NULL))
  15878. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
  15879. return;
  15880. }
  15881. else if ((int)args.size() > explicitParamCount)
  15882. {
  15883. BfError* error = mModule->Fail(StrFormat("Too many arguments specified, expected %d fewer.", (int)arguments.size() - explicitParamCount), targetSrc);
  15884. if ((error != NULL) && (methodInstance->mMethodDef->GetRefNode() != NULL))
  15885. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
  15886. return;
  15887. }
  15888. int paramIdx = implicitParamCount;
  15889. auto argExprEvaluatorItr = argExprEvaluators.begin();
  15890. for (int argIdx = 0; argIdx < (int)args.size(); argIdx++)
  15891. {
  15892. auto exprEvaluator = *argExprEvaluatorItr;
  15893. //auto paramType = methodInstance->GetParamKind(paramIdx);
  15894. BfType* wantType = methodInstance->mParams[paramIdx].mResolvedType;
  15895. auto& arg = args[argIdx];
  15896. if ((arg.mArgFlags & BfArgFlag_VariableDeclaration) != 0)
  15897. {
  15898. arg.mTypedValue = ResolveArgValue(arg, wantType);
  15899. }
  15900. if (wantType->IsGenericParam())
  15901. {
  15902. //
  15903. }
  15904. else if (!wantType->IsVar())
  15905. {
  15906. if (arg.mTypedValue.mType == NULL)
  15907. {
  15908. mModule->AssertErrorState();
  15909. return;
  15910. }
  15911. if (arg.mTypedValue.mType != wantType)
  15912. {
  15913. exprEvaluator->FinishExpressionResult();
  15914. arg.mTypedValue = mModule->LoadValue(arg.mTypedValue);
  15915. arg.mTypedValue = mModule->Cast(arg.mExpression, arg.mTypedValue, wantType);
  15916. /*// Do this to generate default implicit cast error
  15917. mModule->Fail(StrFormat("Mixin argument type '%s' must match parameter type '%s'.",
  15918. mModule->TypeToString(arg.mTypedValue.mType).c_str(),
  15919. mModule->TypeToString(wantType).c_str()), arg.mExpression);
  15920. return;*/
  15921. }
  15922. }
  15923. paramIdx++;
  15924. argExprEvaluatorItr++;
  15925. }
  15926. mModule->AddDependency(methodInstance->GetOwner(), mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_InlinedCall);
  15927. auto startBlock = mModule->mBfIRBuilder->CreateBlock("mixinStart");
  15928. mModule->mBfIRBuilder->CreateBr(startBlock);
  15929. mModule->mBfIRBuilder->AddBlock(startBlock);
  15930. mModule->mBfIRBuilder->SetInsertPoint(startBlock);
  15931. //auto prevDebugLoc = mModule->mBfIRBuilder->getCurrentDebugLocation();
  15932. // This is so when we debug we can hit a steppoint on the inlined "call line"
  15933. mModule->EmitEnsureInstructionAt();
  15934. auto rootMethodState = mModule->mCurMethodState->GetRootMethodState();
  15935. BfMixinState* mixinState = rootMethodState->mMixinStates.Alloc();
  15936. mixinState->mInjectFilePosition = mModule->mCurFilePosition;
  15937. mixinState->mPrevMixinState = curMethodState->mMixinState;
  15938. mixinState->mLocalsStartIdx = (int)mModule->mCurMethodState->mLocals.size();
  15939. mixinState->mMixinMethodInstance = methodInstance;
  15940. mixinState->mSource = origTargetSrc;
  15941. mixinState->mCallerScope = mModule->mCurMethodState->mCurScope;
  15942. mixinState->mTargetScope = mixinState->mCallerScope;
  15943. mixinState->mResultExpr = NULL;
  15944. mixinState->mHasDeferredUsage = false;
  15945. mixinState->mUsedInvocationScope = false;
  15946. mixinState->mTarget = target;
  15947. auto checkNode = origTargetSrc;
  15948. if (scopedInvocationTarget != NULL)
  15949. {
  15950. auto targetScope = mModule->FindScope(scopedInvocationTarget->GetScopeNameNode(), curMethodState->mMixinState);
  15951. if (targetScope != NULL)
  15952. {
  15953. mixinState->mTargetScope = targetScope;
  15954. if (autoComplete != NULL)
  15955. {
  15956. if (auto identifer = BfNodeDynCast<BfIdentifierNode>(scopedInvocationTarget->mScopeName))
  15957. autoComplete->CheckLabel(identifer, NULL, targetScope);
  15958. }
  15959. }
  15960. }
  15961. mModule->mBfIRBuilder->SaveDebugLocation();
  15962. SetAndRestoreValue<BfMixinState*> prevMixinState(curMethodState->mMixinState, mixinState);
  15963. SetAndRestoreValue<BfExprEvaluator*> prevExprEvaluator(curMethodState->mCurScope->mExprEvaluator, NULL);
  15964. SetAndRestoreValue<BfPendingNullConditional*> prevNullConditional(curMethodState->mPendingNullConditional, NULL);
  15965. BfGetSymbolReferenceKind prevSymbolRefKind = BfGetSymbolReferenceKind_None;
  15966. if (mModule->mCompiler->mResolvePassData != NULL)
  15967. {
  15968. prevSymbolRefKind = mModule->mCompiler->mResolvePassData->mGetSymbolReferenceKind;
  15969. mModule->mCompiler->mResolvePassData->mGetSymbolReferenceKind = BfGetSymbolReferenceKind_None;
  15970. }
  15971. defer
  15972. (
  15973. {
  15974. if (mModule->mCompiler->mResolvePassData != NULL)
  15975. mModule->mCompiler->mResolvePassData->mGetSymbolReferenceKind = prevSymbolRefKind;
  15976. }
  15977. );
  15978. auto methodDef = methodInstance->mMethodDef;
  15979. auto methodDeclaration = methodDef->GetMethodDeclaration();
  15980. BfScopeData scopeData;
  15981. scopeData.mCloseNode = methodDeclaration->mBody;
  15982. if (auto block = BfNodeDynCast<BfBlock>(methodDeclaration->mBody))
  15983. {
  15984. if (block->mCloseBrace != NULL)
  15985. scopeData.mCloseNode = block->mCloseBrace;
  15986. }
  15987. curMethodState->AddScope(&scopeData);
  15988. curMethodState->mCurScope->mMixinDepth++;
  15989. // We can't flush scope state because we extend params in as arbitrary values
  15990. mModule->NewScopeState(true, false);
  15991. bool wantsDIData = (mModule->mBfIRBuilder->DbgHasInfo()) && (mModule->mHasFullDebugInfo);
  15992. DISubprogram* diFunction = NULL;
  15993. int startLocalIdx = (int)mModule->mCurMethodState->mLocals.size();
  15994. int endLocalIdx = startLocalIdx;
  15995. if ((wantsDIData) || (mModule->mIsComptimeModule))
  15996. {
  15997. BfIRMDNode diFuncType = mModule->mBfIRBuilder->DbgCreateSubroutineType(methodInstance);
  15998. //int defLine = mModule->mCurFilePosition.mCurLine;
  15999. int flags = 0;
  16000. curMethodState->mCurScope->mDIInlinedAt = mModule->mBfIRBuilder->DbgGetCurrentLocation();
  16001. // 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
  16002. // definitions, so we need to be consistent and use the actual line
  16003. mModule->UpdateSrcPos(methodDeclaration->mNameNode, BfSrcPosFlag_NoSetDebugLoc);
  16004. int defLine = mModule->mCurFilePosition.mCurLine;
  16005. auto diParentType = mModule->mBfIRBuilder->DbgGetTypeInst(methodInstance->GetOwner());
  16006. if (!mModule->mBfIRBuilder->mIgnoreWrites)
  16007. {
  16008. String methodName = methodDef->mName;
  16009. methodName += "!";
  16010. BfMangler::Mangle(methodName, mModule->mCompiler->GetMangleKind(), methodInstance);
  16011. String linkageName;
  16012. if ((mModule->mIsComptimeModule) && (mModule->mCompiler->mCeMachine->mCurBuilder != NULL))
  16013. linkageName = StrFormat("%d", mModule->mCompiler->mCeMachine->mCurBuilder->DbgCreateMethodRef(methodInstance, ""));
  16014. curMethodState->mCurScope->mDIScope = mModule->mBfIRBuilder->DbgCreateFunction(diParentType, methodName, linkageName, mModule->mCurFilePosition.mFileInstance->mDIFile,
  16015. defLine + 1, diFuncType, false, true, mModule->mCurFilePosition.mCurLine + 1, flags, false, BfIRValue());
  16016. scopeData.mAltDIFile = mModule->mCurFilePosition.mFileInstance->mDIFile;
  16017. }
  16018. }
  16019. if (methodDef->mBody != NULL)
  16020. mModule->UpdateSrcPos(methodDef->mBody);
  16021. mModule->SetIllegalSrcPos();
  16022. auto _AddLocalVariable = [&](BfLocalVariable* newLocalVar, BfExprEvaluator* exprEvaluator)
  16023. {
  16024. mModule->SetIllegalSrcPos();
  16025. bool hasConstValue = newLocalVar->mConstValue;
  16026. if (hasConstValue)
  16027. {
  16028. auto constant = mModule->mBfIRBuilder->GetConstant(newLocalVar->mConstValue);
  16029. hasConstValue = constant->mConstType < BfConstType_GlobalVar;
  16030. }
  16031. if ((exprEvaluator != NULL) && (exprEvaluator->mResultLocalVar != NULL) && (exprEvaluator->mResultLocalVarField == 0))
  16032. {
  16033. mModule->UpdateSrcPos(methodDeclaration->mNameNode);
  16034. mModule->AddLocalVariableDef(newLocalVar, hasConstValue);
  16035. auto inLocalVar = exprEvaluator->mResultLocalVar;
  16036. newLocalVar->mAssignedKind = inLocalVar->mAssignedKind;
  16037. newLocalVar->mUnassignedFieldFlags = inLocalVar->mUnassignedFieldFlags;
  16038. newLocalVar->mReadFromId = inLocalVar->mReadFromId;
  16039. newLocalVar->mIsReadOnly = inLocalVar->mIsReadOnly;
  16040. if ((newLocalVar->mAssignedKind == BfLocalVarAssignKind_None) && (mModule->mCurMethodState->mDeferredLocalAssignData != NULL))
  16041. {
  16042. for (auto deferredAssign : mModule->mCurMethodState->mDeferredLocalAssignData->mAssignedLocals)
  16043. {
  16044. if (deferredAssign.mLocalVar == inLocalVar)
  16045. newLocalVar->mAssignedKind = BfLocalVarAssignKind_Unconditional;
  16046. }
  16047. }
  16048. }
  16049. else
  16050. {
  16051. mModule->AddLocalVariableDef(newLocalVar, hasConstValue);
  16052. }
  16053. if ((wantsDIData) && (!mModule->mBfIRBuilder->mIgnoreWrites))
  16054. {
  16055. bool handled = false;
  16056. mModule->UpdateSrcPos(methodDeclaration->mNameNode);
  16057. if (hasConstValue)
  16058. {
  16059. // Already handled
  16060. handled = true;
  16061. }
  16062. else if (newLocalVar->mIsSplat)
  16063. {
  16064. bool found = false;
  16065. auto checkMethodState = mModule->mCurMethodState;
  16066. while ((checkMethodState != NULL) && (!found))
  16067. {
  16068. for (auto localVar : checkMethodState->mLocals)
  16069. {
  16070. if (localVar == newLocalVar)
  16071. continue;
  16072. if (!localVar->mIsSplat)
  16073. continue;
  16074. if (newLocalVar->mValue != localVar->mAddr)
  16075. continue;
  16076. bool isDupName = false;
  16077. for (auto param : methodDef->mParams)
  16078. {
  16079. if (param->mName == localVar->mName)
  16080. {
  16081. isDupName = true;
  16082. break;
  16083. }
  16084. }
  16085. if (isDupName)
  16086. {
  16087. auto splatAgg = mModule->AggregateSplat(BfTypedValue(newLocalVar->mValue, newLocalVar->mResolvedType, BfTypedValueKind_SplatHead));
  16088. // Don't allow alias if one of our args has the same name
  16089. newLocalVar->mIsSplat = false;
  16090. newLocalVar->mValue = BfIRValue();
  16091. if (splatAgg.IsAddr())
  16092. newLocalVar->mAddr = splatAgg.mValue;
  16093. else
  16094. newLocalVar->mValue = splatAgg.mValue;
  16095. found = true;
  16096. break;
  16097. }
  16098. String name = "$";
  16099. name += newLocalVar->mName;
  16100. name += "$alias$";
  16101. name += localVar->mName;
  16102. // auto fakeValue = mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, 0);
  16103. // auto diType = mModule->mBfIRBuilder->DbgGetType(mModule->GetPrimitiveType(BfTypeCode_Int32));
  16104. // auto diVariable = mModule->mBfIRBuilder->DbgCreateAutoVariable(mModule->mCurMethodState->mCurScope->mDIScope,
  16105. // name, mModule->mCurFilePosition.mFileInstance->mDIFile, mModule->mCurFilePosition.mCurLine, diType);
  16106. // mModule->mBfIRBuilder->DbgInsertValueIntrinsic(fakeValue, diVariable);
  16107. auto diType = mModule->mBfIRBuilder->DbgGetType(mModule->GetPrimitiveType(BfTypeCode_NullPtr));
  16108. auto diVariable = mModule->mBfIRBuilder->DbgCreateAutoVariable(mModule->mCurMethodState->mCurScope->mDIScope,
  16109. name, mModule->mCurFilePosition.mFileInstance->mDIFile, mModule->mCurFilePosition.mCurLine, diType);
  16110. mModule->mBfIRBuilder->DbgInsertValueIntrinsic(mModule->mBfIRBuilder->CreateConstNull(), diVariable);
  16111. handled = true;
  16112. found = true;
  16113. break;
  16114. }
  16115. checkMethodState = checkMethodState->mPrevMethodState;
  16116. }
  16117. }
  16118. if (handled)
  16119. {
  16120. //
  16121. }
  16122. else if ((mModule->IsTargetingBeefBackend()) && (!mModule->mIsComptimeModule))
  16123. {
  16124. mModule->UpdateSrcPos(methodDeclaration->mNameNode);
  16125. mModule->SetIllegalSrcPos();
  16126. // With the Beef backend we can assign two variables to the same value, but LLVM does not allow this
  16127. // so we have to create a ref to that variable
  16128. auto diType = mModule->mBfIRBuilder->DbgGetType(newLocalVar->mResolvedType);
  16129. auto diVariable = mModule->mBfIRBuilder->DbgCreateAutoVariable(mModule->mCurMethodState->mCurScope->mDIScope,
  16130. newLocalVar->mName, mModule->mCurFilePosition.mFileInstance->mDIFile, mModule->mCurFilePosition.mCurLine, diType);
  16131. if (newLocalVar->mIsSplat)
  16132. {
  16133. //TODO: Implement
  16134. }
  16135. else if (newLocalVar->mResolvedType->IsValuelessType())
  16136. {
  16137. // Do nothing
  16138. }
  16139. else
  16140. {
  16141. BfIRValue value = newLocalVar->mValue;
  16142. if (newLocalVar->mAddr)
  16143. value = newLocalVar->mAddr;
  16144. else if (newLocalVar->mConstValue)
  16145. value = newLocalVar->mConstValue;
  16146. auto aliasValue = mModule->mBfIRBuilder->CreateAliasValue(value);
  16147. if (mModule->WantsLifetimes())
  16148. scopeData.mDeferredLifetimeEnds.Add(aliasValue);
  16149. if (newLocalVar->mAddr)
  16150. mModule->mBfIRBuilder->DbgInsertDeclare(aliasValue, diVariable);
  16151. else
  16152. {
  16153. if (newLocalVar->mResolvedType->IsBoolean())
  16154. {
  16155. // Fix case of remote condbr referencing
  16156. newLocalVar->mAddr = mModule->CreateAlloca(newLocalVar->mResolvedType);
  16157. mModule->mBfIRBuilder->CreateStore(newLocalVar->mValue, newLocalVar->mAddr);
  16158. }
  16159. mModule->mBfIRBuilder->DbgInsertValueIntrinsic(aliasValue, diVariable);
  16160. }
  16161. }
  16162. }
  16163. else if (newLocalVar->mAddr)
  16164. {
  16165. mModule->UpdateSrcPos(methodDeclaration->mNameNode);
  16166. mModule->SetIllegalSrcPos();
  16167. auto refType = mModule->CreateRefType(newLocalVar->mResolvedType);
  16168. auto allocaVal = mModule->CreateAlloca(refType);
  16169. mModule->mBfIRBuilder->CreateStore(newLocalVar->mAddr, allocaVal);
  16170. if (!mModule->mBfIRBuilder->mIgnoreWrites)
  16171. {
  16172. auto diType = mModule->mBfIRBuilder->DbgGetType(refType);
  16173. auto diVariable = mModule->mBfIRBuilder->DbgCreateAutoVariable(mModule->mCurMethodState->mCurScope->mDIScope,
  16174. newLocalVar->mName, mModule->mCurFilePosition.mFileInstance->mDIFile, mModule->mCurFilePosition.mCurLine, diType);
  16175. mModule->mBfIRBuilder->DbgInsertDeclare(allocaVal, diVariable);
  16176. }
  16177. }
  16178. else if (newLocalVar->mValue)
  16179. {
  16180. mModule->UpdateSrcPos(methodDeclaration->mNameNode);
  16181. mModule->SetIllegalSrcPos();
  16182. auto localVal = LoadLocal(newLocalVar);
  16183. localVal = mModule->LoadValue(localVal);
  16184. localVal = mModule->AggregateSplat(localVal);
  16185. BfType* allocType = localVal.mType;
  16186. if (!allocType->IsValuelessType())
  16187. {
  16188. auto allocaVal = mModule->CreateAlloca(allocType);
  16189. mModule->mBfIRBuilder->CreateStore(localVal.mValue, allocaVal);
  16190. if (!mModule->mBfIRBuilder->mIgnoreWrites)
  16191. {
  16192. if (newLocalVar->mIsSplat)
  16193. {
  16194. //TODO: Implement
  16195. }
  16196. else
  16197. {
  16198. auto diType = mModule->mBfIRBuilder->DbgGetType(allocType);
  16199. auto diVariable = mModule->mBfIRBuilder->DbgCreateAutoVariable(mModule->mCurMethodState->mCurScope->mDIScope,
  16200. newLocalVar->mName, mModule->mCurFilePosition.mFileInstance->mDIFile, mModule->mCurFilePosition.mCurLine, diType);
  16201. mModule->mBfIRBuilder->DbgInsertDeclare(allocaVal, diVariable);
  16202. }
  16203. }
  16204. }
  16205. }
  16206. }
  16207. newLocalVar->mParamIdx = -3;
  16208. mixinState->mArgTypes.Add(newLocalVar->mResolvedType);
  16209. if (mModule->mBfIRBuilder->IsConstValue(newLocalVar->mConstValue))
  16210. mixinState->mArgConsts.Add(newLocalVar->mConstValue);
  16211. };
  16212. argExprEvaluatorItr = argExprEvaluators.begin();
  16213. for (int argIdx = methodDef->mIsStatic ? 0 : -1; argIdx < (int)explicitParamCount; argIdx++)
  16214. {
  16215. int paramIdx = argIdx;
  16216. auto exprEvaluator = *argExprEvaluatorItr;
  16217. BfTypedValue argValue;
  16218. BfLocalVariable* localVar = new BfLocalVariable();
  16219. if (argIdx == -1)
  16220. {
  16221. argValue = target;
  16222. localVar->mName = "this";
  16223. localVar->mIsThis = true;
  16224. localVar->mAssignedKind = BfLocalVarAssignKind_Unconditional;
  16225. }
  16226. else
  16227. {
  16228. auto arg = &args[argIdx];
  16229. auto paramDef = methodDef->mParams[paramIdx];
  16230. localVar->mName = paramDef->mName;
  16231. if (!arg->mTypedValue)
  16232. {
  16233. auto wantType = methodInstance->GetParamType(paramIdx);
  16234. if (wantType->IsVar())
  16235. wantType = mModule->mContext->mBfObjectType;
  16236. arg->mTypedValue = mModule->GetDefaultTypedValue(wantType);
  16237. }
  16238. argValue = arg->mTypedValue;
  16239. }
  16240. if (!argValue)
  16241. continue;
  16242. localVar->mResolvedType = argValue.mType;
  16243. if (argValue.mType->IsRef())
  16244. {
  16245. auto refType = (BfRefType*)localVar->mResolvedType;
  16246. localVar->mAddr = mModule->LoadValue(argValue).mValue;
  16247. localVar->mResolvedType = argValue.mType->GetUnderlyingType();
  16248. localVar->mAssignedKind = (refType->mRefKind != BfRefType::RefKind_Out) ? BfLocalVarAssignKind_Unconditional : BfLocalVarAssignKind_None;
  16249. }
  16250. else if (argValue.IsAddr())
  16251. localVar->mAddr = argValue.mValue;
  16252. else
  16253. {
  16254. if (!argValue.mValue)
  16255. {
  16256. // Untyped value
  16257. }
  16258. else if (argValue.mValue.IsConst())
  16259. {
  16260. localVar->mConstValue = argValue.mValue;
  16261. }
  16262. else if (argValue.IsSplat())
  16263. {
  16264. localVar->mValue = argValue.mValue;
  16265. localVar->mIsSplat = true;
  16266. }
  16267. else
  16268. {
  16269. if (argValue.IsAddr())
  16270. localVar->mAddr = argValue.mValue;
  16271. else
  16272. localVar->mValue = argValue.mValue;
  16273. }
  16274. localVar->mIsReadOnly = argValue.IsReadOnly();
  16275. }
  16276. if (argValue.IsReadOnly())
  16277. localVar->mIsReadOnly = true;
  16278. if (argIdx == -1)
  16279. {
  16280. _AddLocalVariable(localVar, NULL);
  16281. }
  16282. else
  16283. {
  16284. _AddLocalVariable(localVar, exprEvaluator);
  16285. endLocalIdx++;
  16286. ++argExprEvaluatorItr;
  16287. }
  16288. }
  16289. if (auto blockBody = BfNodeDynCast<BfBlock>(methodDef->mBody))
  16290. {
  16291. mModule->VisitCodeBlock(blockBody);
  16292. if (mixinState->mResultExpr != NULL)
  16293. {
  16294. if (auto exprNode = BfNodeDynCast<BfExpression>(mixinState->mResultExpr))
  16295. {
  16296. if (!exprNode->IsA<BfBlock>())
  16297. {
  16298. // Mixin expression result
  16299. SetAndRestoreValue<BfEvalExprFlags> prevFlags(mBfEvalExprFlags, (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_AllowRefExpr));
  16300. mModule->UpdateSrcPos(exprNode);
  16301. VisitChild(exprNode);
  16302. FinishExpressionResult();
  16303. ResolveGenericType();
  16304. }
  16305. }
  16306. }
  16307. GetResult();
  16308. }
  16309. else if (auto expr = BfNodeDynCast<BfExpression>(methodDef->mBody))
  16310. {
  16311. mModule->UpdateSrcPos(expr);
  16312. mResult = mModule->CreateValueFromExpression(expr);
  16313. }
  16314. if (!mResult)
  16315. {
  16316. // If we didn't have an expression body then just make the result "void"
  16317. mResult = BfTypedValue(BfIRValue(), mModule->GetPrimitiveType(BfTypeCode_None));
  16318. }
  16319. mResult = mModule->RemoveRef(mResult);
  16320. if (mResult.IsAddr())
  16321. {
  16322. if (mModule->mCurMethodState->mCurScope->ExtendLifetime(mResult.mValue))
  16323. mModule->mBfIRBuilder->CreateLifetimeSoftEnd(mResult.mValue);
  16324. }
  16325. int localIdx = startLocalIdx;
  16326. argExprEvaluatorItr = argExprEvaluators.begin();
  16327. for (; localIdx < endLocalIdx; localIdx++)
  16328. {
  16329. auto exprEvaluator = *argExprEvaluatorItr;
  16330. BfLocalVariable* localVar = curMethodState->mLocals[localIdx];
  16331. //TODO: Merge unassigned flags together
  16332. if ((exprEvaluator != NULL) && (exprEvaluator->mResultLocalVar != NULL))
  16333. {
  16334. auto inLocalVar = exprEvaluator->mResultLocalVar;
  16335. if (localVar->mAssignedKind != BfLocalVarAssignKind_None)
  16336. inLocalVar->mAssignedKind = BfLocalVarAssignKind_Unconditional;
  16337. if (localVar->mReadFromId != -1)
  16338. inLocalVar->mReadFromId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++;
  16339. }
  16340. ++argExprEvaluatorItr;
  16341. }
  16342. if (auto blockBody = BfNodeDynCast<BfBlock>(methodDef->mBody))
  16343. {
  16344. if (blockBody->mCloseBrace != NULL)
  16345. mModule->UpdateSrcPos(blockBody->mCloseBrace);
  16346. }
  16347. else if (auto methodDeclaration = BfNodeDynCast<BfMethodDeclaration>(methodDef->mMethodDeclaration))
  16348. {
  16349. if (methodDeclaration->mFatArrowToken != NULL)
  16350. mModule->UpdateSrcPos(methodDeclaration->mFatArrowToken);
  16351. }
  16352. mModule->RestoreScopeState();
  16353. prevMixinState.Restore();
  16354. if ((scopedInvocationTarget != NULL) && (scopedInvocationTarget->mScopeName != NULL) && (!mixinState->mUsedInvocationScope))
  16355. {
  16356. mModule->Warn(0, "Scope specifier was not referenced in mixin", scopedInvocationTarget->mScopeName);
  16357. }
  16358. if (mixinState->mHasDeferredUsage)
  16359. {
  16360. mixinState->mTarget = BfTypedValue();
  16361. // Put deferred mixin states at the front
  16362. BF_ASSERT(rootMethodState->mMixinStates.back() == mixinState);
  16363. rootMethodState->mMixinStates.pop_back();
  16364. rootMethodState->mMixinStates.Insert(0, mixinState);
  16365. }
  16366. else
  16367. {
  16368. BF_ASSERT(rootMethodState->mMixinStates.back() == mixinState);
  16369. rootMethodState->mMixinStates.pop_back();
  16370. delete mixinState;
  16371. }
  16372. mModule->mBfIRBuilder->RestoreDebugLocation();
  16373. mModule->mBfIRBuilder->DupDebugLocation();
  16374. }
  16375. void BfExprEvaluator::SetMethodElementType(BfAstNode* target)
  16376. {
  16377. if (auto delegateBindExpr = BfNodeDynCast<BfDelegateBindExpression>(target))
  16378. {
  16379. SetMethodElementType(delegateBindExpr->mTarget);
  16380. return;
  16381. }
  16382. if (auto lambdaBindExpr = BfNodeDynCast<BfLambdaBindExpression>(target))
  16383. {
  16384. return;
  16385. }
  16386. if (auto attributedIdentifierNode = BfNodeDynCast<BfAttributedIdentifierNode>(target))
  16387. {
  16388. if (attributedIdentifierNode->mIdentifier != NULL)
  16389. mModule->SetElementType(attributedIdentifierNode->mIdentifier, BfSourceElementType_Method);
  16390. }
  16391. else if (auto memberReferenceExpr = BfNodeDynCast<BfMemberReferenceExpression>(target))
  16392. {
  16393. if (memberReferenceExpr->mMemberName != NULL)
  16394. SetMethodElementType(memberReferenceExpr->mMemberName);
  16395. }
  16396. else if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(target))
  16397. SetMethodElementType(qualifiedNameNode->mRight);
  16398. else
  16399. mModule->SetElementType(target, BfSourceElementType_Method);
  16400. }
  16401. void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* methodBoundExpr, const BfSizedArray<BfExpression*>& args, const BfMethodGenericArguments& methodGenericArgs, BfTypedValue* outCascadeValue)
  16402. {
  16403. auto methodGenericArguments = methodGenericArgs.mArguments;
  16404. // Just a check
  16405. mModule->mBfIRBuilder->GetInsertBlock();
  16406. bool wasCapturingMethodInfo = false;
  16407. auto autoComplete = GetAutoComplete();
  16408. if ((autoComplete != NULL) && (methodGenericArguments != NULL))
  16409. {
  16410. for (BfAstNode* methodGenericArg : *methodGenericArguments)
  16411. {
  16412. autoComplete->CheckNode(methodGenericArg, false, true);
  16413. }
  16414. }
  16415. if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo))
  16416. {
  16417. // We don't want to capture a call within the target node
  16418. wasCapturingMethodInfo = true;
  16419. autoComplete->mIsCapturingMethodMatchInfo = false;
  16420. }
  16421. bool allowImplicitThis = false;
  16422. BfAstNode* methodNodeSrc = target;
  16423. BfAttributeState attributeState;
  16424. attributeState.mTarget = (BfAttributeTargets)(BfAttributeTargets_Invocation | BfAttributeTargets_MemberAccess);
  16425. if (auto scopedTarget = BfNodeDynCast<BfScopedInvocationTarget>(target))
  16426. {
  16427. target = scopedTarget->mTarget;
  16428. if (autoComplete != NULL)
  16429. {
  16430. if (auto identifier = BfNodeDynCast<BfIdentifierNode>(scopedTarget->mScopeName))
  16431. autoComplete->CheckLabel(identifier, scopedTarget->mColonToken, NULL);
  16432. }
  16433. //mModule->FindScope(scopedTarget->mScopeName);
  16434. }
  16435. bool isCascade = false;
  16436. BfAstNode* cascadeOperatorToken = NULL;
  16437. bool bypassVirtual = false;
  16438. bool gaveUnqualifiedDotError = false;
  16439. String targetFunctionName;
  16440. BfTypedValue thisValue;
  16441. //TODO: This may just be a fully qualified static method name, so let's check that also
  16442. if (auto memberRefExpression = BfNodeDynCast<BfMemberReferenceExpression>(target))
  16443. {
  16444. if (autoComplete != NULL)
  16445. {
  16446. if (memberRefExpression->mTarget != NULL)
  16447. autoComplete->CheckMemberReference(memberRefExpression->mTarget, memberRefExpression->mDotToken, memberRefExpression->mMemberName, false, mExpectingType);
  16448. else if (mExpectingType != NULL)
  16449. {
  16450. String filter;
  16451. if ((autoComplete != NULL) && (autoComplete->InitAutocomplete(memberRefExpression->mDotToken, memberRefExpression->mMemberName, filter)))
  16452. {
  16453. auto typeInst = mExpectingType->ToTypeInstance();
  16454. if (typeInst != NULL)
  16455. {
  16456. String filter;
  16457. if ((memberRefExpression->mMemberName != NULL) && (autoComplete->IsAutocompleteNode(memberRefExpression->mMemberName)))
  16458. filter = autoComplete->GetFilter(memberRefExpression->mMemberName);
  16459. bool allowPrivate = typeInst == mModule->mCurTypeInstance;
  16460. autoComplete->AddEnumTypeMembers(typeInst, filter, false, allowPrivate);
  16461. autoComplete->AddSelfResultTypeMembers(typeInst, typeInst, filter, allowPrivate);
  16462. }
  16463. }
  16464. }
  16465. }
  16466. if ((memberRefExpression->mTarget == NULL) && (memberRefExpression->mMemberName == NULL))
  16467. {
  16468. auto expectingType = mExpectingType;
  16469. if ((expectingType != NULL) && (expectingType->IsNullable()))
  16470. {
  16471. auto underlyingType = expectingType->GetUnderlyingType();
  16472. expectingType = underlyingType;
  16473. }
  16474. BfType* inRefType = NULL;
  16475. if ((expectingType != NULL) && (expectingType->IsRef()))
  16476. {
  16477. auto refType = (BfRefType*)expectingType;
  16478. if (refType->mRefKind == BfRefType::RefKind_In)
  16479. {
  16480. inRefType = expectingType;
  16481. auto underlyingType = expectingType->GetUnderlyingType();
  16482. expectingType = underlyingType;
  16483. }
  16484. }
  16485. if (expectingType != NULL)
  16486. {
  16487. if (expectingType->IsSizedArray())
  16488. {
  16489. if (mModule->mParentNodeEntry != NULL)
  16490. {
  16491. if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(mModule->mParentNodeEntry->mNode))
  16492. {
  16493. InitializedSizedArray((BfSizedArrayType*)expectingType, invocationExpr->mOpenParen, invocationExpr->mArguments, invocationExpr->mCommas, invocationExpr->mCloseParen);
  16494. return;
  16495. }
  16496. }
  16497. }
  16498. else if ((expectingType->IsStruct()) || (expectingType->IsTypedPrimitive()))
  16499. {
  16500. if ((wasCapturingMethodInfo) && (autoComplete->mMethodMatchInfo != NULL))
  16501. {
  16502. autoComplete->mIsCapturingMethodMatchInfo = true;
  16503. BF_ASSERT(autoComplete->mMethodMatchInfo != NULL);
  16504. }
  16505. if (mModule->mParentNodeEntry != NULL)
  16506. {
  16507. if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(mModule->mParentNodeEntry->mNode))
  16508. {
  16509. BfResolvedArgs argValues(invocationExpr->mOpenParen, &invocationExpr->mArguments, &invocationExpr->mCommas, invocationExpr->mCloseParen);
  16510. BfResolveArgsFlags resolveArgsFlags = BfResolveArgsFlag_DeferParamEval;
  16511. ResolveArgValues(argValues, resolveArgsFlags);
  16512. if ((mReceivingValue != NULL) && (mReceivingValue->mType == expectingType) && (mReceivingValue->IsAddr()))
  16513. {
  16514. mResult = *mReceivingValue;
  16515. mReceivingValue = NULL;
  16516. }
  16517. else
  16518. mResult = BfTypedValue(mModule->CreateAlloca(expectingType), expectingType, BfTypedValueKind_TempAddr);
  16519. auto ctorResult = MatchConstructor(target, methodBoundExpr, mResult, expectingType->ToTypeInstance(), argValues, false, BfMethodGenericArguments(), BfAllowAppendKind_No);
  16520. if ((ctorResult) && (!ctorResult.mType->IsVoid()))
  16521. mResult = ctorResult;
  16522. mModule->ValidateAllocation(expectingType, invocationExpr->mTarget);
  16523. if ((inRefType != NULL) && (mResult.mType == expectingType) && (mResult.IsAddr()))
  16524. {
  16525. // Put back the 'in'
  16526. mResult = BfTypedValue(mResult.mValue, inRefType);
  16527. }
  16528. return;
  16529. }
  16530. }
  16531. }
  16532. else if (expectingType->IsGenericParam())
  16533. {
  16534. if (mModule->mParentNodeEntry != NULL)
  16535. {
  16536. if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(mModule->mParentNodeEntry->mNode))
  16537. {
  16538. BfResolvedArgs argValues(invocationExpr->mOpenParen, &invocationExpr->mArguments, &invocationExpr->mCommas, invocationExpr->mCloseParen);
  16539. BfResolveArgsFlags resolveArgsFlags = BfResolveArgsFlag_None;
  16540. ResolveArgValues(argValues, resolveArgsFlags);
  16541. if (!mModule->mCurMethodInstance->mIsUnspecializedVariation)
  16542. CheckGenericCtor((BfGenericParamType*)expectingType, argValues, invocationExpr->mTarget);
  16543. mResult = mModule->GetDefaultTypedValue(expectingType);
  16544. return;
  16545. }
  16546. }
  16547. }
  16548. else if (expectingType->IsVar())
  16549. {
  16550. // Silently allow
  16551. gaveUnqualifiedDotError = true;
  16552. }
  16553. else if (expectingType->IsPrimitiveType())
  16554. {
  16555. // Allow
  16556. }
  16557. else if ((mBfEvalExprFlags & BfEvalExprFlags_AppendFieldInitializer) == 0)
  16558. {
  16559. gaveUnqualifiedDotError = true;
  16560. if (mModule->PreFail())
  16561. mModule->Fail(StrFormat("Cannot use inferred constructor on type '%s'", mModule->TypeToString(expectingType).c_str()), memberRefExpression->mDotToken);
  16562. }
  16563. }
  16564. }
  16565. if (memberRefExpression->IsA<BfBaseExpression>())
  16566. bypassVirtual = true;
  16567. if (memberRefExpression->mMemberName != NULL)
  16568. methodNodeSrc = memberRefExpression->mMemberName;
  16569. if (auto attrIdentifier = BfNodeDynCast<BfAttributedIdentifierNode>(memberRefExpression->mMemberName))
  16570. {
  16571. if (attrIdentifier->mIdentifier != NULL)
  16572. methodNodeSrc = attrIdentifier->mIdentifier;
  16573. attributeState.mSrc = attrIdentifier->mAttributes;
  16574. attributeState.mCustomAttributes = mModule->GetCustomAttributes(attrIdentifier->mAttributes, attributeState.mTarget);
  16575. if (attrIdentifier->mIdentifier != NULL)
  16576. targetFunctionName = attrIdentifier->mIdentifier->ToString();
  16577. }
  16578. else if (memberRefExpression->mMemberName != NULL)
  16579. targetFunctionName = memberRefExpression->mMemberName->ToString();
  16580. if (memberRefExpression->mTarget == NULL)
  16581. {
  16582. if (mExpectingType)
  16583. {
  16584. if (mExpectingType->IsVar())
  16585. {
  16586. }
  16587. mResult = BfTypedValue(mExpectingType);
  16588. }
  16589. else if (!gaveUnqualifiedDotError)
  16590. mModule->Fail("Unqualified dot syntax can only be used when the result type can be inferred", memberRefExpression->mDotToken);
  16591. }
  16592. else if (auto typeRef = BfNodeDynCast<BfTypeReference>(memberRefExpression->mTarget))
  16593. {
  16594. // Static method
  16595. mResult = BfTypedValue(ResolveTypeRef(typeRef));
  16596. }
  16597. if (auto leftIdentifier = BfNodeDynCast<BfIdentifierNode>(memberRefExpression->mTarget))
  16598. {
  16599. bool hadError = false;
  16600. thisValue = LookupIdentifier(leftIdentifier, true, &hadError);
  16601. CheckResultForReading(thisValue);
  16602. if (mPropDef != NULL)
  16603. thisValue = GetResult(true);
  16604. if (hadError)
  16605. {
  16606. mModule->AssertErrorState();
  16607. thisValue = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  16608. }
  16609. if ((!thisValue) && (mPropDef == NULL))
  16610. {
  16611. // Identifier not found. Static method? Just check speculatively don't throw error
  16612. BfType* type;
  16613. {
  16614. SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
  16615. type = mModule->ResolveTypeRef(leftIdentifier, NULL, BfPopulateType_DataAndMethods, BfResolveTypeRefFlag_NoResolveGenericParam);
  16616. }
  16617. if (type != NULL)
  16618. thisValue = BfTypedValue(type);
  16619. else if (auto qualifiedLeft = BfNodeDynCast<BfQualifiedNameNode>(leftIdentifier))
  16620. {
  16621. LookupQualifiedStaticField(qualifiedLeft, true);
  16622. thisValue = mResult;
  16623. mResult = BfTypedValue();
  16624. }
  16625. }
  16626. if (mPropDef != NULL)
  16627. thisValue = GetResult(true);
  16628. if (!thisValue.mType)
  16629. {
  16630. mModule->Fail("Identifier not found", leftIdentifier);
  16631. mModule->CheckTypeRefFixit(leftIdentifier);
  16632. thisValue = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  16633. }
  16634. if (mResult)
  16635. CheckResultForReading(mResult);
  16636. mResult = thisValue;
  16637. }
  16638. else if (auto expr = BfNodeDynCast<BfExpression>(memberRefExpression->mTarget))
  16639. {
  16640. BfType* expectingTargetType = NULL;
  16641. if (memberRefExpression->mDotToken->mToken == BfToken_DotDot)
  16642. expectingTargetType = mExpectingType;
  16643. bool handled = false;
  16644. if (auto subMemberRefExpr = BfNodeDynCast<BfMemberReferenceExpression>(expr))
  16645. {
  16646. String findName;
  16647. if (subMemberRefExpr->mMemberName != NULL)
  16648. findName = subMemberRefExpr->mMemberName->ToString();
  16649. if (findName == "base") // Generic IFace<T>.base
  16650. {
  16651. thisValue = mModule->GetThis();
  16652. if (thisValue)
  16653. {
  16654. VisitChild(subMemberRefExpr->mTarget);
  16655. if (mResult.HasType())
  16656. {
  16657. if (mResult.mValue)
  16658. {
  16659. mModule->Fail("Type name expected", subMemberRefExpr->mTarget);
  16660. }
  16661. else
  16662. {
  16663. auto type = mResult.mType;
  16664. if (type != NULL)
  16665. {
  16666. if ((thisValue.mType == type) || (!mModule->TypeIsSubTypeOf(thisValue.mType->ToTypeInstance(), type->ToTypeInstance())))
  16667. {
  16668. mModule->Fail(StrFormat("Type '%s' is not a base type of '%s'",
  16669. mModule->TypeToString(type).c_str(),
  16670. mModule->TypeToString(thisValue.mType).c_str()), subMemberRefExpr->mTarget);
  16671. }
  16672. else
  16673. {
  16674. if (type->IsInterface())
  16675. {
  16676. thisValue.mType = type;
  16677. }
  16678. else
  16679. {
  16680. auto castedThis = mModule->Cast(subMemberRefExpr->mMemberName, thisValue, type, BfCastFlags_Explicit);
  16681. if (castedThis)
  16682. thisValue = castedThis;
  16683. //mModule->Fail("Explicit base types can only be used for specifying default interface members", qualifiedLeft->mLeft);
  16684. }
  16685. }
  16686. handled = true;
  16687. }
  16688. bypassVirtual = true;
  16689. }
  16690. }
  16691. }
  16692. }
  16693. }
  16694. if (!handled)
  16695. {
  16696. SetAndRestoreValue<BfAttributeState*> prevAttributeState(mModule->mAttributeState, &attributeState);
  16697. auto flags = (BfEvalExprFlags)(BfEvalExprFlags_PropogateNullConditional | BfEvalExprFlags_NoCast);
  16698. if (mFunctionBindResult != NULL)
  16699. {
  16700. if (auto paranExpr = BfNodeDynCast<BfParenthesizedExpression>(expr))
  16701. {
  16702. // Allow 'ref' on binding, to indicate we want to capture 'this' by reference
  16703. flags = (BfEvalExprFlags)(flags | BfEvalExprFlags_AllowRefExpr);
  16704. expr = paranExpr->mExpression;
  16705. }
  16706. }
  16707. if (expr != NULL)
  16708. mResult = mModule->CreateValueFromExpression(expr, expectingTargetType, flags);
  16709. }
  16710. }
  16711. isCascade = (memberRefExpression->mDotToken != NULL) && (memberRefExpression->mDotToken->GetToken() == BfToken_DotDot);
  16712. if (isCascade)
  16713. cascadeOperatorToken = memberRefExpression->mDotToken;
  16714. bool isNullCondLookup = (memberRefExpression->mDotToken != NULL) && (memberRefExpression->mDotToken->GetToken() == BfToken_QuestionDot);
  16715. if (isNullCondLookup)
  16716. mResult = SetupNullConditional(mResult, memberRefExpression->mDotToken);
  16717. if ((mResult.mType == NULL) && (memberRefExpression->mTarget != NULL))
  16718. {
  16719. mModule->AssertErrorState();
  16720. mResult = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  16721. }
  16722. thisValue = mResult;
  16723. mResult = BfTypedValue();
  16724. if ((thisValue) && (memberRefExpression->mDotToken != NULL) && (memberRefExpression->mDotToken->mToken == BfToken_Arrow))
  16725. thisValue = TryArrowLookup(thisValue, memberRefExpression->mDotToken);
  16726. }
  16727. else if (auto qualifiedName = BfNodeDynCast<BfQualifiedNameNode>(target))
  16728. {
  16729. if (GetAutoComplete() != NULL)
  16730. GetAutoComplete()->CheckMemberReference(qualifiedName->mLeft, qualifiedName->mDot, qualifiedName->mRight);
  16731. bool isGlobalLookup = false;
  16732. if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(target))
  16733. {
  16734. if (qualifiedNameNode->IsGlobalLookup())
  16735. {
  16736. if (auto subQualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(qualifiedNameNode->mRight))
  16737. {
  16738. qualifiedName = subQualifiedNameNode;
  16739. isGlobalLookup = true;
  16740. }
  16741. }
  16742. }
  16743. if ((!isGlobalLookup) && (qualifiedName->mLeft->GetSrcLength() == 4))
  16744. {
  16745. if (CheckIsBase(qualifiedName->mLeft))
  16746. bypassVirtual = true;
  16747. }
  16748. if (qualifiedName->mRight != NULL)
  16749. methodNodeSrc = qualifiedName->mRight;
  16750. if (auto attrIdentifier = BfNodeDynCast<BfAttributedIdentifierNode>(qualifiedName->mRight))
  16751. {
  16752. if (attrIdentifier->mIdentifier != NULL)
  16753. methodNodeSrc = attrIdentifier->mIdentifier;
  16754. attributeState.mSrc = attrIdentifier->mAttributes;
  16755. attributeState.mCustomAttributes = mModule->GetCustomAttributes(attrIdentifier->mAttributes, attributeState.mTarget);
  16756. targetFunctionName = attrIdentifier->mIdentifier->ToString();
  16757. }
  16758. else
  16759. targetFunctionName = qualifiedName->mRight->ToString();
  16760. bool hadError = false;
  16761. if (!isGlobalLookup)
  16762. thisValue = LookupIdentifier(qualifiedName->mLeft, true, &hadError);
  16763. CheckResultForReading(thisValue);
  16764. if (mPropDef != NULL)
  16765. thisValue = GetResult(true);
  16766. if (hadError)
  16767. {
  16768. mModule->AssertErrorState();
  16769. thisValue = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  16770. }
  16771. if ((!thisValue) && (mPropDef == NULL))
  16772. {
  16773. auto typeLookupFlags = (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoResolveGenericParam | BfResolveTypeRefFlag_AllowGlobalContainer | BfResolveTypeRefFlag_IgnoreLookupError);
  16774. if (isGlobalLookup)
  16775. typeLookupFlags = (BfResolveTypeRefFlags)(typeLookupFlags | BfResolveTypeRefFlag_GlobalLookup);
  16776. // Identifier not found. Static method? Just check speculatively don't throw error
  16777. BfType* type;
  16778. {
  16779. //SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
  16780. type = mModule->ResolveTypeRef(qualifiedName->mLeft, NULL, BfPopulateType_DataAndMethods, typeLookupFlags);
  16781. }
  16782. if (type == NULL)
  16783. {
  16784. //SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
  16785. type = mModule->ResolveTypeRef(qualifiedName, methodGenericArguments, BfPopulateType_DataAndMethods, typeLookupFlags);
  16786. if (type != NULL)
  16787. {
  16788. // This is a CTOR call, treat it as such
  16789. targetFunctionName.clear();
  16790. }
  16791. }
  16792. if (type != NULL)
  16793. thisValue = BfTypedValue(type);
  16794. else if (auto qualifiedLeft = BfNodeDynCast<BfQualifiedNameNode>(qualifiedName->mLeft))
  16795. {
  16796. String findName = qualifiedLeft->mRight->ToString();
  16797. bool handled = false;
  16798. if (findName == "base")
  16799. {
  16800. auto type = mModule->ResolveTypeRef(qualifiedLeft->mLeft, NULL, BfPopulateType_Data, BfResolveTypeRefFlag_AllowRef);
  16801. mModule->CheckTypeRefFixit(qualifiedLeft->mLeft);
  16802. thisValue = mModule->GetThis();
  16803. if (type != NULL)
  16804. {
  16805. if ((thisValue.mType == type) || (!mModule->TypeIsSubTypeOf(thisValue.mType->ToTypeInstance(), type->ToTypeInstance())))
  16806. {
  16807. mModule->Fail(StrFormat("Type '%s' is not a base type of '%s'",
  16808. mModule->TypeToString(type).c_str(),
  16809. mModule->TypeToString(thisValue.mType).c_str()), qualifiedLeft->mLeft);
  16810. }
  16811. else
  16812. {
  16813. if (type->IsInterface())
  16814. {
  16815. thisValue.mType = type;
  16816. }
  16817. else
  16818. {
  16819. auto castedThis = mModule->Cast(qualifiedLeft->mRight, thisValue, type, BfCastFlags_Explicit);
  16820. if (castedThis)
  16821. thisValue = castedThis;
  16822. //mModule->Fail("Explicit base types can only be used for specifying default interface members", qualifiedLeft->mLeft);
  16823. }
  16824. }
  16825. handled = true;
  16826. }
  16827. bypassVirtual = true;
  16828. }
  16829. if (!handled)
  16830. {
  16831. LookupQualifiedStaticField(qualifiedLeft, true);
  16832. thisValue = mResult;
  16833. mResult = BfTypedValue();
  16834. }
  16835. }
  16836. }
  16837. if (mPropDef != NULL)
  16838. thisValue = GetResult(true);
  16839. if (!thisValue.mType)
  16840. {
  16841. mModule->Fail("Identifier not found", qualifiedName->mLeft);
  16842. mModule->CheckTypeRefFixit(qualifiedName->mLeft);
  16843. mModule->CheckIdentifierFixit(qualifiedName->mLeft);
  16844. thisValue = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Var));
  16845. }
  16846. if (mResult)
  16847. CheckResultForReading(mResult);
  16848. mResult = BfTypedValue();
  16849. }
  16850. else if (auto identiferExpr = BfNodeDynCast<BfIdentifierNode>(target))
  16851. {
  16852. if (auto attrIdentifier = BfNodeDynCast<BfAttributedIdentifierNode>(target))
  16853. {
  16854. if (attrIdentifier->mIdentifier != NULL)
  16855. methodNodeSrc = attrIdentifier->mIdentifier;
  16856. attributeState.mSrc = attrIdentifier->mAttributes;
  16857. attributeState.mCustomAttributes = mModule->GetCustomAttributes(attrIdentifier->mAttributes, attributeState.mTarget);
  16858. }
  16859. allowImplicitThis = true;
  16860. if (autoComplete != NULL)
  16861. autoComplete->CheckIdentifier(identiferExpr);
  16862. targetFunctionName = target->ToString();
  16863. if (targetFunctionName == "PrintF") // Just directly call that one
  16864. {
  16865. BfType* charType = mModule->GetPrimitiveType(BfTypeCode_Char8);
  16866. BfType* charPtrType = mModule->CreatePointerType(charType);
  16867. auto func = mModule->GetBuiltInFunc(BfBuiltInFuncType_PrintF);
  16868. SizedArray<BfIRValue, 4> irArgs;
  16869. for (BfExpression* arg : args)
  16870. {
  16871. BfTypedValue value;
  16872. if (arg != NULL)
  16873. value = mModule->CreateValueFromExpression(arg);
  16874. if (!value)
  16875. return;
  16876. auto typeInst = value.mType->ToTypeInstance();
  16877. if ((typeInst != NULL) && (typeInst->IsInstanceOf(mModule->mCompiler->mStringTypeDef)))
  16878. value = mModule->Cast(arg, value, charPtrType);
  16879. if ((value.mType->IsFloat()) && (value.mType->mSize != 8)) // Always cast float to double
  16880. value = mModule->Cast(arg, value, mModule->GetPrimitiveType(BfTypeCode_Double));
  16881. irArgs.push_back(value.mValue);
  16882. }
  16883. if ((targetFunctionName != "PrintF") || (irArgs.size() > 0))
  16884. {
  16885. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCall(func, irArgs/*, targetFunctionName*/),
  16886. mModule->ResolveTypeDef(mModule->mSystem->mTypeInt32));
  16887. }
  16888. return;
  16889. }
  16890. if (auto ceDbgState = mModule->GetCeDbgState())
  16891. {
  16892. if (targetFunctionName.StartsWith("__"))
  16893. {
  16894. auto ceDebugger = mModule->mCompiler->mCeMachine->mDebugger;
  16895. auto _ResolveArg = [&](int argIdx, BfType* type = NULL)
  16896. {
  16897. if ((argIdx < 0) || (argIdx >= args.mSize))
  16898. return BfTypedValue();
  16899. return mModule->CreateValueFromExpression(args[argIdx], type);
  16900. };
  16901. if (targetFunctionName == "__getHighBits")
  16902. {
  16903. auto typedVal = _ResolveArg(0);
  16904. if ((typedVal) && (typedVal.mType->IsPrimitiveType()))
  16905. {
  16906. auto primType = (BfPrimitiveType*)typedVal.mType;
  16907. int64 val = ceDebugger->ValueToInt(typedVal);
  16908. int64 bitCount = ceDebugger->ValueToInt(_ResolveArg(1));
  16909. int64 resultVal = val >> (typedVal.mType->mSize * 8 - bitCount);
  16910. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, (uint64)resultVal), typedVal.mType);
  16911. return;
  16912. }
  16913. }
  16914. else if (targetFunctionName == "__clearHighBits")
  16915. {
  16916. auto typedVal = _ResolveArg(0);
  16917. if ((typedVal) && (typedVal.mType->IsPrimitiveType()))
  16918. {
  16919. auto primType = (BfPrimitiveType*)typedVal.mType;
  16920. int64 val = ceDebugger->ValueToInt(typedVal);
  16921. int64 bitCount = ceDebugger->ValueToInt(_ResolveArg(1));
  16922. int64 andBits = (0x8000000000000000LL) >> ((typedVal.mType->mSize - 8) * 8 + bitCount - 1);
  16923. int64 resultVal = val & ~andBits;
  16924. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, (uint64)resultVal), typedVal.mType);
  16925. return;
  16926. }
  16927. }
  16928. else if ((targetFunctionName == "__cast") || (targetFunctionName == "__bitcast"))
  16929. {
  16930. BfType* type = NULL;
  16931. String typeName;
  16932. for (int argIdx = 0; argIdx < args.mSize - 1; argIdx++)
  16933. {
  16934. auto arg = _ResolveArg(argIdx);
  16935. if (!arg)
  16936. continue;
  16937. if (arg.mType->IsInstanceOf(mModule->mCompiler->mStringTypeDef))
  16938. {
  16939. auto strPtr = mModule->GetStringPoolString(arg.mValue, mModule->mBfIRBuilder);
  16940. if (strPtr != NULL)
  16941. {
  16942. if ((type != NULL) && (*strPtr == "*"))
  16943. {
  16944. type = mModule->CreatePointerType(type);
  16945. }
  16946. else
  16947. typeName += *strPtr;
  16948. }
  16949. }
  16950. if (arg.mType->IsInteger())
  16951. {
  16952. int64 intVal = ceDebugger->ValueToInt(arg);
  16953. if (typeName.IsEmpty())
  16954. {
  16955. auto typeType = mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef)->ToTypeInstance();
  16956. auto fieldDef = typeType->mTypeDef->GetFieldByName("mTypeId");
  16957. if (fieldDef != NULL)
  16958. {
  16959. int typeId = ceDebugger->ReadMemory<int>((intptr)intVal + typeType->mFieldInstances[fieldDef->mIdx].mDataOffset);
  16960. type = mModule->mContext->FindTypeById(typeId);
  16961. }
  16962. }
  16963. else
  16964. typeName += StrFormat("%lld", intVal);
  16965. }
  16966. }
  16967. auto fromTypedVal = _ResolveArg(args.mSize - 1);
  16968. if (!typeName.IsEmpty())
  16969. type = ceDebugger->FindType(typeName);
  16970. if (type != NULL)
  16971. {
  16972. if (targetFunctionName == "__bitcast")
  16973. {
  16974. if ((type->IsObjectOrInterface()) || (type->IsPointer()))
  16975. {
  16976. auto ceAddrVal = ceDebugger->GetAddr(fromTypedVal);
  16977. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateIntToPtr(ceAddrVal.mAddr, mModule->mBfIRBuilder->MapType(type)), type);
  16978. }
  16979. else
  16980. {
  16981. Array<uint8> memArr;
  16982. memArr.Resize(BF_MAX(type->mSize, fromTypedVal.mType->mSize));
  16983. mModule->mBfIRBuilder->WriteConstant(fromTypedVal.mValue, memArr.mVals, fromTypedVal.mType);
  16984. auto newVal = mModule->mBfIRBuilder->ReadConstant(memArr.mVals, type);
  16985. mResult = BfTypedValue(newVal, type);
  16986. }
  16987. }
  16988. else
  16989. mResult = mModule->Cast(target, fromTypedVal, type, (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_SilentFail));
  16990. }
  16991. return;
  16992. }
  16993. else if (targetFunctionName == "__stringView")
  16994. {
  16995. auto ptrVal = _ResolveArg(0);
  16996. auto sizeVal = _ResolveArg(1);
  16997. if (ceDbgState->mFormatInfo != NULL)
  16998. ceDbgState->mFormatInfo->mOverrideCount = (int)ceDebugger->ValueToInt(sizeVal);
  16999. mResult = ptrVal;
  17000. return;
  17001. }
  17002. else if ((targetFunctionName == "__funcName") || (targetFunctionName == "__funcTarget"))
  17003. {
  17004. auto addrVal = _ResolveArg(0);
  17005. auto ceAddrVal = ceDebugger->GetAddr(addrVal);
  17006. CeFunction* ceFunction = NULL;
  17007. int functionId = 0;
  17008. if (mModule->mSystem->mPtrSize == 4)
  17009. {
  17010. functionId = (int)addrVal;
  17011. }
  17012. else
  17013. {
  17014. CeFunction* checkCeFunction = (CeFunction*)ceAddrVal.mAddr;
  17015. functionId = checkCeFunction->SafeGetId();
  17016. }
  17017. if (mModule->mCompiler->mCeMachine->mFunctionIdMap.TryGetValue(functionId, &ceFunction))
  17018. {
  17019. BfMethodInstance* methodInstance = ceFunction->mMethodInstance;
  17020. if (methodInstance != NULL)
  17021. {
  17022. if (targetFunctionName == "__funcTarget")
  17023. {
  17024. BfType* targetType = methodInstance->GetOwner();
  17025. if (targetType->IsValueType())
  17026. targetType = mModule->CreatePointerType(targetType);
  17027. auto targetVal = _ResolveArg(1);
  17028. auto ceTargetVal = ceDebugger->GetAddr(targetVal);
  17029. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateIntToPtr(ceTargetVal.mAddr, mModule->mBfIRBuilder->MapType(targetType)), targetType);
  17030. return;
  17031. }
  17032. else
  17033. {
  17034. mResult = BfTypedValue(mModule->GetStringObjectValue(mModule->MethodToString(methodInstance)),
  17035. mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
  17036. return;
  17037. }
  17038. }
  17039. else if ((ceFunction->mCeInnerFunctionInfo != NULL) && (targetFunctionName == "__funcName"))
  17040. {
  17041. mResult = BfTypedValue(mModule->GetStringObjectValue(BfDemangler::Demangle(ceFunction->mCeInnerFunctionInfo->mName, DbgLanguage_Beef)),
  17042. mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
  17043. return;
  17044. }
  17045. }
  17046. if (targetFunctionName == "__funcTarget")
  17047. mResult = _ResolveArg(1);
  17048. else
  17049. mResult = addrVal;
  17050. return;
  17051. }
  17052. }
  17053. }
  17054. }
  17055. else if (auto expr = BfNodeDynCast<BfExpression>(target))
  17056. {
  17057. auto innerInvocationResult = mModule->CreateValueFromExpression(expr);
  17058. if (!innerInvocationResult)
  17059. {
  17060. mModule->AssertErrorState();
  17061. innerInvocationResult = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  17062. }
  17063. if (innerInvocationResult.mType->IsVar())
  17064. {
  17065. mResult = innerInvocationResult;
  17066. return;
  17067. }
  17068. targetFunctionName = "Invoke";
  17069. if (innerInvocationResult.mType->IsTypeInstance())
  17070. {
  17071. auto invocationTypeInst = innerInvocationResult.mType->ToTypeInstance();
  17072. if ((invocationTypeInst->mTypeDef->mIsDelegate) || (invocationTypeInst->mTypeDef->mIsFunction))
  17073. {
  17074. thisValue = innerInvocationResult;
  17075. }
  17076. }
  17077. if (!thisValue)
  17078. {
  17079. mModule->Fail(StrFormat("Cannot perform invocation on type '%s'", mModule->TypeToString(innerInvocationResult.mType).c_str()), expr);
  17080. thisValue = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  17081. }
  17082. }
  17083. else
  17084. {
  17085. mModule->Fail("Invalid invocation target", target);
  17086. thisValue = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  17087. }
  17088. if ((wasCapturingMethodInfo) && (autoComplete->mMethodMatchInfo != NULL))
  17089. {
  17090. autoComplete->mIsCapturingMethodMatchInfo = true;
  17091. BF_ASSERT(autoComplete->mMethodMatchInfo != NULL);
  17092. }
  17093. SetAndRestoreValue<BfAttributeState*> prevAttributeState;
  17094. if (attributeState.mCustomAttributes != NULL)
  17095. prevAttributeState.Init(mModule->mAttributeState, &attributeState);
  17096. if ((targetFunctionName != "") && (targetFunctionName[targetFunctionName.length() - 1] == '!'))
  17097. {
  17098. targetFunctionName = targetFunctionName.Substring(0, targetFunctionName.length() - 1);
  17099. InjectMixin(methodNodeSrc, thisValue, allowImplicitThis, targetFunctionName, args, methodGenericArgs);
  17100. return;
  17101. }
  17102. if (targetFunctionName.StartsWith('@'))
  17103. targetFunctionName.Remove(0, 1);
  17104. //TODO: We removed this... Messed up with PrimStruct 'this' non-mut errors
  17105. // 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
  17106. /*if (thisValue)
  17107. {
  17108. if ((!thisValue.mType->IsGenericParam()) && (!thisValue.IsSplat()) && (!thisValue.mType->IsVar()))
  17109. thisValue = MakeCallableTarget(target, thisValue);
  17110. }*/
  17111. int methodCount = 0;
  17112. bool mayBeSkipCall = false;
  17113. bool mayBeComptimeCall = false;
  17114. BfTypeInstance* checkTypeInst = NULL;
  17115. if (thisValue.mType != NULL)
  17116. {
  17117. if (thisValue.mType->IsAllocType())
  17118. thisValue.mType = thisValue.mType->GetUnderlyingType();
  17119. checkTypeInst = thisValue.mType->ToTypeInstance();
  17120. }
  17121. else if (allowImplicitThis)
  17122. {
  17123. checkTypeInst = mModule->mCurTypeInstance;
  17124. }
  17125. while (checkTypeInst != NULL)
  17126. {
  17127. checkTypeInst->mTypeDef->PopulateMemberSets();
  17128. BfMemberSetEntry* memberSetEntry;
  17129. if (checkTypeInst->mTypeDef->mMethodSet.TryGetWith(targetFunctionName, &memberSetEntry))
  17130. {
  17131. BfMethodDef* methodDef = (BfMethodDef*)memberSetEntry->mMemberDef;
  17132. while (methodDef != NULL)
  17133. {
  17134. if (methodDef->mIsSkipCall)
  17135. mayBeSkipCall = true;
  17136. if (methodDef->mHasComptime)
  17137. mayBeComptimeCall = true;
  17138. methodDef = methodDef->mNextWithSameName;
  17139. }
  17140. }
  17141. checkTypeInst = checkTypeInst->mBaseType;
  17142. }
  17143. SizedArray<BfExpression*, 8> copiedArgs;
  17144. for (BfExpression* arg : args)
  17145. copiedArgs.push_back(arg);
  17146. BfSizedArray<BfExpression*> sizedCopiedArgs(copiedArgs);
  17147. BfResolvedArgs argValues(&sizedCopiedArgs);
  17148. if (mModule->mParentNodeEntry != NULL)
  17149. {
  17150. if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(mModule->mParentNodeEntry->mNode))
  17151. {
  17152. argValues.mOpenToken = invocationExpr->mOpenParen;
  17153. argValues.mCommas = &invocationExpr->mCommas;
  17154. argValues.mCloseToken = invocationExpr->mCloseParen;
  17155. }
  17156. }
  17157. BfResolveArgsFlags resolveArgsFlags = (BfResolveArgsFlags)(BfResolveArgsFlag_DeferFixits | BfResolveArgsFlag_AllowUnresolvedTypes);
  17158. resolveArgsFlags = (BfResolveArgsFlags)(resolveArgsFlags | BfResolveArgsFlag_DeferParamEval);
  17159. if ((mayBeSkipCall) || (mayBeComptimeCall))
  17160. resolveArgsFlags = (BfResolveArgsFlags)(resolveArgsFlags | BfResolveArgsFlag_DeferParamValues);
  17161. static int sCallIdx = 0;
  17162. sCallIdx++;
  17163. int callIdx = sCallIdx;
  17164. if (callIdx == 1557)
  17165. {
  17166. NOP;
  17167. }
  17168. BfCheckedKind checkedKind = BfCheckedKind_NotSet;
  17169. if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL))
  17170. {
  17171. if (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mCheckedAttributeTypeDef))
  17172. {
  17173. checkedKind = BfCheckedKind_Checked;
  17174. mModule->mAttributeState->mUsed = true;
  17175. }
  17176. if (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mUncheckedAttributeTypeDef))
  17177. {
  17178. checkedKind = BfCheckedKind_Unchecked;
  17179. mModule->mAttributeState->mUsed = true;
  17180. }
  17181. if (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mNoStaticCtorAttributeTypeDef))
  17182. {
  17183. mModule->mAttributeState->mUsed = true;
  17184. }
  17185. }
  17186. if ((isCascade) && (cascadeOperatorToken != NULL) && ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0))
  17187. mModule->Fail("Cascade operator cannot be used in const evaluation", cascadeOperatorToken);
  17188. SetAndRestoreValue<bool> prevUsedAsStatement(mUsedAsStatement, mUsedAsStatement || isCascade);
  17189. SetAndRestoreValue<BfEvalExprFlags> prevEvalExprFlags(mBfEvalExprFlags);
  17190. if (isCascade)
  17191. {
  17192. mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_InCascade);
  17193. thisValue = mModule->MakeAddressable(thisValue);
  17194. }
  17195. if (((mayBeComptimeCall) && (!mModule->mIsComptimeModule) && (!mModule->mBfIRBuilder->mIgnoreWrites)) ||
  17196. ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) && (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mConstEvalAttributeTypeDef))))
  17197. {
  17198. resolveArgsFlags = (BfResolveArgsFlags)(resolveArgsFlags | BfResolveArgsFlag_DeferParamEval | BfResolveArgsFlag_DeferStrings);
  17199. }
  17200. ResolveArgValues(argValues, resolveArgsFlags);
  17201. //
  17202. {
  17203. // We also apply this right before the actual call, but we need to set the comptime flag earlier
  17204. SetAndRestoreValue<BfEvalExprFlags> prevEvalExprFlag(mBfEvalExprFlags);
  17205. if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) && (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mConstEvalAttributeTypeDef)))
  17206. {
  17207. mModule->mAttributeState->mUsed = true;
  17208. mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_Comptime);
  17209. }
  17210. mResult = MatchMethod(methodNodeSrc, methodBoundExpr, thisValue, allowImplicitThis, bypassVirtual, targetFunctionName, argValues, methodGenericArgs, checkedKind);
  17211. }
  17212. argValues.HandleFixits(mModule);
  17213. if (mModule->mAttributeState == &attributeState)
  17214. mModule->FinishAttributeState(&attributeState);
  17215. if (isCascade)
  17216. {
  17217. if ((outCascadeValue != NULL) && (thisValue.mValue))
  17218. {
  17219. *outCascadeValue = thisValue;
  17220. }
  17221. else
  17222. {
  17223. mModule->Fail("Invalid use of cascade operator", cascadeOperatorToken);
  17224. }
  17225. }
  17226. }
  17227. void BfExprEvaluator::Visit(BfInvocationExpression* invocationExpr)
  17228. {
  17229. DoInvocation(invocationExpr);
  17230. }
  17231. void BfExprEvaluator::DoInvocation(BfInvocationExpression* invocationExpr)
  17232. {
  17233. BfAutoParentNodeEntry autoParentNodeEntry(mModule, invocationExpr);
  17234. // We need to check for sized array constructor like "uint8[2](1, 2)"
  17235. if (BfNodeDynCastExact<BfIndexerExpression>(invocationExpr->mTarget) != NULL)
  17236. {
  17237. auto checkTarget = invocationExpr->mTarget;
  17238. while (auto indexerExpr = BfNodeDynCastExact<BfIndexerExpression>(checkTarget))
  17239. {
  17240. checkTarget = indexerExpr->mTarget;
  17241. }
  17242. auto resolvedType = mModule->ResolveTypeRef(checkTarget, NULL, BfPopulateType_Identity, BfResolveTypeRefFlag_IgnoreLookupError);
  17243. if (resolvedType != NULL)
  17244. {
  17245. BfType* curType = resolvedType;
  17246. auto checkTarget = invocationExpr->mTarget;
  17247. while (auto indexerExpr = BfNodeDynCastExact<BfIndexerExpression>(checkTarget))
  17248. {
  17249. checkTarget = indexerExpr->mTarget;
  17250. if (indexerExpr->mCommas.size() != 0)
  17251. 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]);
  17252. int arrSize = 0;
  17253. BfTypeState typeState;
  17254. typeState.mArrayInitializerSize = (int)invocationExpr->mArguments.size();
  17255. SetAndRestoreValue<BfTypeState*> prevTypeState(mModule->mContext->mCurTypeState, &typeState);
  17256. BfType* undefSizeParam = NULL;
  17257. if (indexerExpr->mArguments.size() != 0)
  17258. {
  17259. BfConstResolver constResolver(mModule);
  17260. auto arg = indexerExpr->mArguments[0];
  17261. constResolver.mExpectingType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  17262. constResolver.mBfEvalExprFlags = (BfEvalExprFlags)(constResolver.mBfEvalExprFlags | BfEvalExprFlags_AllowGenericConstValue);
  17263. if (arg != NULL)
  17264. constResolver.Resolve(arg, NULL, BfConstResolveFlag_ArrayInitSize);
  17265. if (constResolver.mResult.mKind == BfTypedValueKind_GenericConstValue)
  17266. {
  17267. undefSizeParam = constResolver.mResult.mType;
  17268. }
  17269. else if (constResolver.mResult.mValue.IsConst())
  17270. {
  17271. auto constant = mModule->mBfIRBuilder->GetConstant(constResolver.mResult.mValue);
  17272. if ((mModule->mBfIRBuilder->IsInt(constant->mTypeCode)) && (constant->mInt64 >= 0))
  17273. {
  17274. arrSize = constant->mInt32;
  17275. }
  17276. else if (constant->mConstType != BfConstType_Undef)
  17277. mModule->Fail("Non-negative integer expected", indexerExpr->mArguments[0]);
  17278. }
  17279. }
  17280. else
  17281. arrSize = invocationExpr->mArguments.size();
  17282. if (undefSizeParam != NULL)
  17283. curType = mModule->CreateUnknownSizedArrayType(curType, undefSizeParam);
  17284. else
  17285. curType = mModule->CreateSizedArrayType(curType, arrSize);
  17286. }
  17287. InitializedSizedArray((BfSizedArrayType*)curType, invocationExpr->mOpenParen, invocationExpr->mArguments, invocationExpr->mCommas, invocationExpr->mCloseParen, NULL);
  17288. return;
  17289. }
  17290. }
  17291. auto autoComplete = GetAutoComplete();
  17292. auto wasCapturingMethodInfo = (autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo);
  17293. if (autoComplete != NULL)
  17294. autoComplete->CheckInvocation(invocationExpr, invocationExpr->mOpenParen, invocationExpr->mCloseParen, invocationExpr->mCommas);
  17295. mModule->UpdateExprSrcPos(invocationExpr);
  17296. BfMethodGenericArguments methodGenericArgs;
  17297. if (invocationExpr->mGenericArgs != NULL)
  17298. {
  17299. methodGenericArgs.mArguments = &invocationExpr->mGenericArgs->mGenericArgs;
  17300. if ((!invocationExpr->mGenericArgs->mCommas.IsEmpty()) && (invocationExpr->mGenericArgs->mCommas.back()->mToken == BfToken_DotDotDot))
  17301. {
  17302. methodGenericArgs.mIsOpen = true;
  17303. methodGenericArgs.mIsPartial = true;
  17304. }
  17305. for (int i = 0; i < (int)methodGenericArgs.mArguments->mSize; i++)
  17306. if (BfNodeIsA<BfUninitializedExpression>((*methodGenericArgs.mArguments)[i]))
  17307. methodGenericArgs.mIsPartial = true;
  17308. }
  17309. SizedArray<BfExpression*, 8> copiedArgs;
  17310. for (BfExpression* arg : invocationExpr->mArguments)
  17311. copiedArgs.push_back(arg);
  17312. BfTypedValue cascadeValue;
  17313. DoInvocation(invocationExpr->mTarget, invocationExpr, copiedArgs, methodGenericArgs, &cascadeValue);
  17314. if (autoComplete != NULL)
  17315. {
  17316. if ((wasCapturingMethodInfo) && (!autoComplete->mIsCapturingMethodMatchInfo))
  17317. {
  17318. if (autoComplete->mMethodMatchInfo != NULL)
  17319. autoComplete->mIsCapturingMethodMatchInfo = true;
  17320. else
  17321. autoComplete->mIsCapturingMethodMatchInfo = false;
  17322. //BF_ASSERT(autoComplete->mMethodMatchInfo != NULL);
  17323. }
  17324. else
  17325. autoComplete->mIsCapturingMethodMatchInfo = false;
  17326. }
  17327. /// Previous check for discard
  17328. if (cascadeValue)
  17329. mResult = cascadeValue;
  17330. }
  17331. BfMethodDef* BfExprEvaluator::GetPropertyMethodDef(BfPropertyDef* propDef, BfMethodType methodType, BfCheckedKind checkedKind, BfTypedValue propTarget)
  17332. {
  17333. bool allowMut = true;
  17334. if ((propTarget) && (propTarget.mType->IsValueType()))
  17335. {
  17336. if (propTarget.IsReadOnly())
  17337. {
  17338. allowMut = false;
  17339. }
  17340. else if (!propTarget.IsAddr())
  17341. {
  17342. mModule->PopulateType(propTarget.mType);
  17343. if (!propTarget.IsValuelessType())
  17344. allowMut = false;
  17345. }
  17346. }
  17347. int bestPri = -1000;
  17348. BfMethodDef* matchedMethod = NULL;
  17349. for (auto methodDef : propDef->mMethods)
  17350. {
  17351. if (methodDef->mMethodType != methodType)
  17352. continue;
  17353. int curPri = 0;
  17354. if (methodDef->mCheckedKind == checkedKind)
  17355. {
  17356. curPri = 5;
  17357. }
  17358. else if ((checkedKind == BfCheckedKind_NotSet) && (methodDef->mCheckedKind == mModule->GetDefaultCheckedKind()))
  17359. curPri = 3;
  17360. else
  17361. curPri = 1;
  17362. if (methodDef->mIsMutating)
  17363. {
  17364. if (allowMut)
  17365. curPri++;
  17366. else
  17367. curPri -= 10;
  17368. }
  17369. if (curPri > bestPri)
  17370. {
  17371. bestPri = curPri;
  17372. matchedMethod = methodDef;
  17373. }
  17374. }
  17375. return matchedMethod;
  17376. /*BfMethodDef* matchedMethod = NULL;
  17377. BfMethodDef* backupMethod = NULL;
  17378. for (auto methodDef : propDef->mMethods)
  17379. {
  17380. if (methodDef->mMethodType != methodType)
  17381. continue;
  17382. if (methodDef->mCheckedKind == checkedKind)
  17383. {
  17384. matchedMethod = methodDef;
  17385. break;
  17386. }
  17387. if ((checkedKind == BfCheckedKind_NotSet) && (methodDef->mCheckedKind == mModule->GetDefaultCheckedKind()))
  17388. matchedMethod = methodDef;
  17389. else
  17390. backupMethod = methodDef;
  17391. }
  17392. if (matchedMethod == NULL)
  17393. matchedMethod = backupMethod;
  17394. return matchedMethod;*/
  17395. }
  17396. BfModuleMethodInstance BfExprEvaluator::GetPropertyMethodInstance(BfMethodDef* methodDef)
  17397. {
  17398. if (mPropDefBypassVirtual)
  17399. {
  17400. if (mPropTarget.mType->IsInterface())
  17401. {
  17402. auto curTypeInst = mPropTarget.mType->ToTypeInstance();
  17403. if (mModule->TypeIsSubTypeOf(mModule->mCurTypeInstance, curTypeInst))
  17404. {
  17405. if (methodDef->mBody != NULL)
  17406. {
  17407. // This is an explicit call to a default static interface method. We pull the methodDef into our own concrete type.
  17408. mPropTarget = mModule->GetThis();
  17409. return mModule->GetMethodInstance(mModule->mCurTypeInstance, methodDef, BfTypeVector(), BfGetMethodInstanceFlag_ForeignMethodDef, curTypeInst);
  17410. }
  17411. }
  17412. else
  17413. {
  17414. mModule->Fail("Property is not implemented by this type", mPropSrc);
  17415. return BfModuleMethodInstance();
  17416. }
  17417. }
  17418. else
  17419. {
  17420. auto propTypeInst = mPropTarget.mType->ToTypeInstance();
  17421. mModule->PopulateType(propTypeInst, BfPopulateType_DataAndMethods);
  17422. auto rawMethodInstance = mModule->GetRawMethodInstance(propTypeInst, methodDef);
  17423. if (rawMethodInstance->mVirtualTableIdx == -1)
  17424. {
  17425. if (!mModule->mCompiler->mIsResolveOnly)
  17426. {
  17427. // ResolveOnly does not force methods to slot
  17428. BF_ASSERT(rawMethodInstance->mVirtualTableIdx != -1);
  17429. mModule->Fail(StrFormat("Failed to devirtualize %s", mModule->MethodToString(rawMethodInstance).c_str()));
  17430. }
  17431. }
  17432. else
  17433. {
  17434. auto useTypeInst = mOrigPropTarget.mType->ToTypeInstance();
  17435. auto virtualMethod = (BfMethodInstance*)useTypeInst->mVirtualMethodTable[rawMethodInstance->mVirtualTableIdx].mImplementingMethod;
  17436. return mModule->ReferenceExternalMethodInstance(virtualMethod);
  17437. }
  17438. }
  17439. }
  17440. if ((mOrigPropTarget) && (mOrigPropTarget.mType != mPropTarget.mType) &&
  17441. ((!mOrigPropTarget.mType->IsGenericParam()) && (mPropTarget.mType->IsInterface())))
  17442. {
  17443. auto checkType = mOrigPropTarget.mType;
  17444. if ((checkType->IsNullable()) && (!mPropTarget.mType->IsNullable()))
  17445. checkType = checkType->GetUnderlyingType();
  17446. if (checkType->IsPointer())
  17447. checkType = ((BfPointerType*)checkType)->mElementType;
  17448. if (checkType->IsWrappableType())
  17449. checkType = mModule->GetWrappedStructType(checkType);
  17450. if ((checkType != NULL) && (checkType->IsTypeInstance()))
  17451. {
  17452. auto activeTypeDef = mModule->GetActiveTypeDef(NULL, false, true);
  17453. BfTypeInterfaceEntry* bestIFaceEntry = NULL;
  17454. bool checkedUnderlying = false;
  17455. auto checkTypeInst = checkType->ToTypeInstance();
  17456. while (checkTypeInst != NULL)
  17457. {
  17458. mModule->PopulateType(checkTypeInst, BfPopulateType_DataAndMethods);
  17459. BF_ASSERT((checkTypeInst->mDefineState >= BfTypeDefineState_DefinedAndMethodsSlotted) || (mModule->mCompiler->IsAutocomplete()));
  17460. if (checkTypeInst->mDefineState != BfTypeDefineState_DefinedAndMethodsSlotted)
  17461. break;
  17462. for (auto& iface : checkTypeInst->mInterfaces)
  17463. {
  17464. if (!mModule->IsInSpecializedSection())
  17465. {
  17466. if (!checkTypeInst->IsTypeMemberAccessible(iface.mDeclaringType, activeTypeDef))
  17467. continue;
  17468. }
  17469. if (iface.mInterfaceType == mPropTarget.mType)
  17470. {
  17471. if (bestIFaceEntry == NULL)
  17472. {
  17473. bestIFaceEntry = &iface;
  17474. continue;
  17475. }
  17476. bool isBetter;
  17477. bool isWorse;
  17478. mModule->CompareDeclTypes(NULL, iface.mDeclaringType, bestIFaceEntry->mDeclaringType, isBetter, isWorse);
  17479. if (isBetter == isWorse)
  17480. {
  17481. // Failed
  17482. }
  17483. else
  17484. {
  17485. if (isBetter)
  17486. bestIFaceEntry = &iface;
  17487. }
  17488. }
  17489. }
  17490. if (bestIFaceEntry != NULL)
  17491. break;
  17492. checkTypeInst = checkTypeInst->mBaseType;
  17493. if (checkTypeInst == NULL)
  17494. {
  17495. if (!checkedUnderlying)
  17496. {
  17497. checkedUnderlying = true;
  17498. if (checkType->HasWrappedRepresentation())
  17499. {
  17500. auto underlyingType = checkType->GetUnderlyingType();
  17501. if (underlyingType != NULL)
  17502. checkTypeInst = mModule->GetWrappedStructType(underlyingType);
  17503. }
  17504. }
  17505. }
  17506. }
  17507. if (bestIFaceEntry != NULL)
  17508. {
  17509. if ((checkTypeInst->IsInterface()))
  17510. {
  17511. auto propTypeInst = bestIFaceEntry->mInterfaceType->ToTypeInstance();
  17512. if (propTypeInst == NULL)
  17513. {
  17514. mModule->Fail("INTERNAL ERROR: Invalid property target", mPropSrc);
  17515. return BfModuleMethodInstance();
  17516. }
  17517. BF_ASSERT(propTypeInst->mTypeDef->mFullNameEx == methodDef->mDeclaringType->mFullNameEx);
  17518. return mModule->GetMethodInstance(propTypeInst, methodDef, BfTypeVector(), mPropGetMethodFlags);
  17519. }
  17520. auto ifaceMethodEntry = checkTypeInst->mInterfaceMethodTable[bestIFaceEntry->mStartInterfaceTableIdx + methodDef->mIdx];
  17521. BfMethodInstance* bestMethodInstance = ifaceMethodEntry.mMethodRef;
  17522. if (bestMethodInstance != NULL)
  17523. {
  17524. mPropTarget = mOrigPropTarget;
  17525. //mPropTarget.mType = checkTypeInst;
  17526. //mPropTarget = mModule->Cast( mOrigPropTarget, checkTypeInst);
  17527. return mModule->GetMethodInstanceAtIdx(ifaceMethodEntry.mMethodRef.mTypeInstance, ifaceMethodEntry.mMethodRef.mMethodNum);
  17528. }
  17529. }
  17530. }
  17531. mModule->AssertErrorState();
  17532. return BfModuleMethodInstance();
  17533. }
  17534. auto propTypeInst = mPropTarget.mType->ToTypeInstance();
  17535. if (propTypeInst == NULL)
  17536. {
  17537. propTypeInst = mModule->GetWrappedStructType(mPropTarget.mType);
  17538. }
  17539. if (propTypeInst == NULL)
  17540. {
  17541. mModule->Fail("INTERNAL ERROR: Invalid property target", mPropSrc);
  17542. return BfModuleMethodInstance();
  17543. }
  17544. BF_ASSERT(propTypeInst->mTypeDef->mFullNameEx == methodDef->mDeclaringType->mFullNameEx);
  17545. return mModule->GetMethodInstance(propTypeInst, methodDef, BfTypeVector(), mPropGetMethodFlags);
  17546. }
  17547. void BfExprEvaluator::CheckPropFail(BfMethodDef* propMethodDef, BfMethodInstance* methodInstance, bool checkProt)
  17548. {
  17549. auto propTypeInst = mPropTarget.mType->ToTypeInstance();
  17550. // If mExplicitInterface is null then we are implicitly calling through an interface
  17551. if ((checkProt) && (propTypeInst != NULL) && (methodInstance->GetExplicitInterface() == NULL) &&
  17552. (!mModule->CheckAccessMemberProtection(propMethodDef->mProtection, propTypeInst)))
  17553. mModule->Fail(StrFormat("'%s' is inaccessible due to its protection level", mModule->MethodToString(methodInstance).c_str()), mPropSrc);
  17554. else if (mPropCheckedKind != methodInstance->mMethodDef->mCheckedKind)
  17555. {
  17556. bool passes = true;
  17557. if (mPropCheckedKind != BfCheckedKind_NotSet)
  17558. {
  17559. passes = false;
  17560. }
  17561. else
  17562. {
  17563. auto defaultCheckedKind = mModule->GetDefaultCheckedKind();
  17564. if (defaultCheckedKind != methodInstance->mMethodDef->mCheckedKind)
  17565. passes = false;
  17566. }
  17567. if (!passes)
  17568. {
  17569. 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);
  17570. if (error != NULL)
  17571. {
  17572. if ((error != NULL) && (methodInstance->mMethodDef->mMethodDeclaration != NULL))
  17573. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
  17574. }
  17575. }
  17576. }
  17577. }
  17578. bool BfExprEvaluator::HasResult()
  17579. {
  17580. return (mResult) || (mPropDef != NULL);
  17581. }
  17582. BfTypedValue BfExprEvaluator::GetResult(bool clearResult, bool resolveGenericType)
  17583. {
  17584. if ((!mResult) && (mPropDef != NULL))
  17585. {
  17586. bool handled = false;
  17587. if (mPropTarget.mType->IsGenericTypeInstance())
  17588. {
  17589. auto genericTypeInst = (BfTypeInstance*)mPropTarget.mType;
  17590. if (genericTypeInst->IsInstanceOf(mModule->mCompiler->mSizedArrayTypeDef))
  17591. {
  17592. if (mPropDef->mName == "Count")
  17593. {
  17594. auto sizedType = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[1];
  17595. if (sizedType->IsConstExprValue())
  17596. {
  17597. auto constExprType = (BfConstExprValueType*)sizedType;
  17598. mResult = BfTypedValue(mModule->GetConstValue(constExprType->mValue.mInt64), mModule->GetPrimitiveType(BfTypeCode_IntPtr));
  17599. handled = true;
  17600. }
  17601. else
  17602. {
  17603. BF_ASSERT(mModule->mCurMethodInstance->mIsUnspecialized);
  17604. mResult = BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->GetPrimitiveType(BfTypeCode_IntPtr)), mModule->GetPrimitiveType(BfTypeCode_IntPtr));
  17605. handled = true;
  17606. }
  17607. }
  17608. }
  17609. }
  17610. if (!handled)
  17611. {
  17612. SetAndRestoreValue<BfFunctionBindResult*> prevFunctionBindResult(mFunctionBindResult, NULL);
  17613. SetAndRestoreValue<BfDeferCallData*> prevDeferCallRef(mDeferCallData, NULL);
  17614. BfMethodDef* matchedMethod = GetPropertyMethodDef(mPropDef, BfMethodType_PropertyGetter, mPropCheckedKind, mPropTarget);
  17615. if (matchedMethod == NULL)
  17616. {
  17617. mModule->Fail("Property has no getter", mPropSrc);
  17618. return mResult;
  17619. }
  17620. auto methodInstance = GetPropertyMethodInstance(matchedMethod);
  17621. if (methodInstance.mMethodInstance == NULL)
  17622. return mResult;
  17623. BF_ASSERT(methodInstance.mMethodInstance->mMethodDef->mName == matchedMethod->mName);
  17624. if (!mModule->mBfIRBuilder->mIgnoreWrites)
  17625. {
  17626. BF_ASSERT(!methodInstance.mFunc.IsFake());
  17627. }
  17628. if (mPropSrc != NULL)
  17629. mModule->UpdateExprSrcPos(mPropSrc);
  17630. auto autoComplete = GetAutoComplete();
  17631. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(mPropSrc)) && (autoComplete->mResolveType == BfResolveType_GetResultString))
  17632. {
  17633. autoComplete->mResultString = ":";
  17634. autoComplete->mResultString += mModule->TypeToString(methodInstance.mMethodInstance->mReturnType);
  17635. autoComplete->mResultString += " ";
  17636. autoComplete->mResultString += mModule->TypeToString(methodInstance.mMethodInstance->GetOwner());
  17637. autoComplete->mResultString += ".";
  17638. autoComplete->mResultString += mPropDef->mName;
  17639. }
  17640. CheckPropFail(matchedMethod, methodInstance.mMethodInstance, (mPropGetMethodFlags & BfGetMethodInstanceFlag_Friend) == 0);
  17641. PerformCallChecks(methodInstance.mMethodInstance, mPropSrc);
  17642. if (methodInstance.mMethodInstance->IsSkipCall())
  17643. {
  17644. mResult = mModule->GetDefaultTypedValue(methodInstance.mMethodInstance->mReturnType);
  17645. }
  17646. else
  17647. {
  17648. SizedArray<BfIRValue, 4> args;
  17649. if (!matchedMethod->mIsStatic)
  17650. {
  17651. auto owner = methodInstance.mMethodInstance->GetOwner();
  17652. bool isTypeMatch = mPropTarget.mType == owner;
  17653. if (owner->IsTypedPrimitive())
  17654. isTypeMatch |= mPropTarget.mType == owner->GetUnderlyingType();
  17655. if ((!isTypeMatch) ||
  17656. ((mPropTarget.mValue.IsFake()) && (!mOrigPropTarget.mValue.IsFake())))
  17657. {
  17658. auto prevPropTarget = mPropTarget;
  17659. mPropTarget = mModule->Cast(mPropSrc, mOrigPropTarget, owner);
  17660. if (!mPropTarget)
  17661. {
  17662. mModule->Fail("Internal property error", mPropSrc);
  17663. return BfTypedValue();
  17664. }
  17665. }
  17666. if ((mPropGetMethodFlags & BfGetMethodInstanceFlag_DisableObjectAccessChecks) == 0)
  17667. mModule->EmitObjectAccessCheck(mPropTarget);
  17668. }
  17669. SetAndRestoreValue<BfEvalExprFlags> prevExprFlags(mBfEvalExprFlags);
  17670. auto callFlags = mPropDefBypassVirtual ? BfCreateCallFlags_BypassVirtual : BfCreateCallFlags_None;
  17671. auto methodDef = methodInstance.mMethodInstance->mMethodDef;
  17672. if ((methodDef->mMethodDeclaration == NULL) && (mModule->mBfIRBuilder->IsConstValue(mPropTarget.mValue)) &&
  17673. (methodDef->mName == "get__Underlying"))
  17674. {
  17675. mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_Comptime);
  17676. }
  17677. mResult = CreateCall(mPropSrc, mPropTarget, mOrigPropTarget, matchedMethod, methodInstance, callFlags, mIndexerValues, NULL);
  17678. }
  17679. }
  17680. mPropDef = NULL;
  17681. mPropDefBypassVirtual = false;
  17682. mIndexerValues.clear();
  17683. mResultLocalVar = NULL;
  17684. mResultFieldInstance = NULL;
  17685. }
  17686. if (resolveGenericType)
  17687. ResolveGenericType();
  17688. BfTypedValue result = mResult;
  17689. if (clearResult)
  17690. mResult = BfTypedValue();
  17691. return result;
  17692. }
  17693. void BfExprEvaluator::CheckResultForReading(BfTypedValue& typedValue)
  17694. {
  17695. if (mModule->mCurMethodState == NULL)
  17696. return;
  17697. if ((mModule->mCurMethodState->mTempKind != BfMethodState::TempKind_None) || (mModule->mCurMethodState->mAllowUinitReads))
  17698. return;
  17699. if ((mModule->mCurTypeInstance->mResolvingVarField) || (mModule->mCurTypeInstance->mResolvingConstField))
  17700. return;
  17701. if ((typedValue) && (typedValue.IsAddr()))
  17702. {
  17703. if ((mResultLocalVar != NULL) && (mResultLocalVarRefNode != NULL))
  17704. {
  17705. SetAndRestoreValue<bool> prevIgnoreError(mModule->mIgnoreErrors);
  17706. if ((mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mCapturing))
  17707. {
  17708. // These errors can only be detected during capture time, so we don't ignore them on this pass
  17709. mModule->mIgnoreErrors = false;
  17710. }
  17711. int fieldIdx = mResultLocalVarField - 1;
  17712. auto localVar = mResultLocalVar;
  17713. /*if (localVar->mCompositeCount > 0)
  17714. {
  17715. mModule->Fail(StrFormat("Cannot read from composite '%s', it can only be used in an argument list", localVar->mName.c_str()), mResultLocalVarRefNode);
  17716. typedValue = BfTypedValue();
  17717. return;
  17718. }*/
  17719. if (localVar->mAssignedKind == BfLocalVarAssignKind_None)
  17720. {
  17721. mModule->TryLocalVariableInit(localVar);
  17722. }
  17723. if (localVar->mAssignedKind == BfLocalVarAssignKind_None)
  17724. {
  17725. auto methodStateForLocal = mModule->mCurMethodState->GetMethodStateForLocal(localVar);
  17726. bool isAssigned = false;
  17727. int64 undefinedFieldFlags = localVar->mUnassignedFieldFlags;
  17728. auto deferredLocalAssignData = methodStateForLocal->mDeferredLocalAssignData;
  17729. while ((deferredLocalAssignData != NULL) && (deferredLocalAssignData->mIsChained))
  17730. deferredLocalAssignData = deferredLocalAssignData->mChainedAssignData;
  17731. if (deferredLocalAssignData != NULL)
  17732. {
  17733. for (auto& assignedVar : deferredLocalAssignData->mAssignedLocals)
  17734. {
  17735. auto assignedLocal = assignedVar.mLocalVar;
  17736. if (assignedLocal == localVar)
  17737. {
  17738. int assignedFieldIdx = assignedVar.mLocalVarField;
  17739. if (assignedFieldIdx >= 0)
  17740. undefinedFieldFlags &= ~((int64)1 << assignedFieldIdx);
  17741. else
  17742. undefinedFieldFlags = 0;
  17743. }
  17744. }
  17745. if (deferredLocalAssignData->mLeftBlockUncond)
  17746. isAssigned = true;
  17747. }
  17748. if (fieldIdx == -1)
  17749. {
  17750. if (undefinedFieldFlags == 0)
  17751. isAssigned = true;
  17752. }
  17753. else
  17754. {
  17755. isAssigned = true;
  17756. for (int i = 0; i < mResultLocalVarFieldCount; i++)
  17757. if ((undefinedFieldFlags & (1LL << (fieldIdx + i))) != 0)
  17758. isAssigned = false;
  17759. }
  17760. if (!isAssigned)
  17761. {
  17762. if ((localVar->mIsThis) && (fieldIdx != -1))
  17763. {
  17764. // When we have initializers for fields, they won't all be processed in the autocomplte case
  17765. if (!mModule->mCompiler->IsAutocomplete())
  17766. {
  17767. auto bfError = mModule->Fail(StrFormat("Use of possibly unassigned field '%s'", mResultLocalVarRefNode->ToString().c_str()), mResultLocalVarRefNode, true);
  17768. }
  17769. }
  17770. else
  17771. {
  17772. mModule->Fail(StrFormat("Use of unassigned local variable '%s'", localVar->mName.c_str()), mResultLocalVarRefNode);
  17773. }
  17774. }
  17775. }
  17776. localVar->mReadFromId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++;
  17777. }
  17778. }
  17779. }
  17780. void BfExprEvaluator::FinishExpressionResult()
  17781. {
  17782. CheckResultForReading(mResult);
  17783. mResultLocalVar = NULL;
  17784. mResultFieldInstance = NULL;
  17785. }
  17786. bool BfExprEvaluator::CheckAllowValue(const BfTypedValue& typedValue, BfAstNode* refNode)
  17787. {
  17788. return true;
  17789. }
  17790. void BfExprEvaluator::MarkResultUsed()
  17791. {
  17792. if (mResultLocalVar != NULL)
  17793. {
  17794. mResultLocalVar->mReadFromId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++;
  17795. }
  17796. }
  17797. void BfExprEvaluator::MarkResultAssigned()
  17798. {
  17799. if (mResultLocalVar != NULL)
  17800. {
  17801. //int localIdx = mResultLocalVarIdx;
  17802. //if (localIdx == 0x7FFF)
  17803. //return;
  17804. auto localVar = mResultLocalVar;
  17805. int fieldIdx = mResultLocalVarField - 1;
  17806. int count = mResultLocalVarFieldCount;
  17807. if (fieldIdx == -1)
  17808. count = 1;
  17809. for (int i = 0; i < count; i++)
  17810. mModule->mCurMethodState->GetMethodStateForLocal(localVar)->LocalDefined(localVar, fieldIdx + i);
  17811. //if (localIdx != 0x7FFF)
  17812. {
  17813. if (localVar->mCompositeCount > 0)
  17814. {
  17815. mModule->Fail(StrFormat("Cannot write to composite '%s', it can only be used in an argument list", localVar->mName.c_str()), mResultLocalVarRefNode);
  17816. }
  17817. }
  17818. }
  17819. }
  17820. void BfExprEvaluator::MakeResultAsValue()
  17821. {
  17822. // Expressions like parens will turn a variable reference into a simple value
  17823. mResultLocalVar = NULL;
  17824. mResultFieldInstance = NULL;
  17825. }
  17826. bool BfExprEvaluator::CheckIsBase(BfAstNode* checkNode)
  17827. {
  17828. if (checkNode == NULL)
  17829. return false;
  17830. if (!checkNode->Equals("base"))
  17831. return false;
  17832. auto autoComplete = GetAutoComplete();
  17833. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(checkNode)))
  17834. {
  17835. if ((mModule->mCurTypeInstance != NULL) && (mModule->mCurTypeInstance->mBaseType != NULL))
  17836. autoComplete->SetDefinitionLocation(mModule->mCurTypeInstance->mBaseType->mTypeDef->GetRefNode());
  17837. }
  17838. return true;
  17839. }
  17840. bool BfExprEvaluator::CheckModifyResult(BfTypedValue& typedVal, BfAstNode* refNode, const char* modifyType, bool onlyNeedsMut, bool emitWarning, bool skipCopyOnMutate)
  17841. {
  17842. if (typedVal.mType->IsVar())
  17843. {
  17844. // Allow without error
  17845. return true;
  17846. }
  17847. BfLocalVariable* localVar = NULL;
  17848. bool isCapturedLocal = false;
  17849. if (mResultLocalVar != NULL)
  17850. {
  17851. localVar = mResultLocalVar;
  17852. localVar->mWrittenToId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++;
  17853. }
  17854. else if (typedVal.IsThis())
  17855. {
  17856. localVar = mModule->GetThisVariable();
  17857. }
  17858. else if (typedVal.IsSplat())
  17859. {
  17860. for (auto checkLocal : mModule->mCurMethodState->mLocals)
  17861. {
  17862. if (checkLocal->mAddr == typedVal.mValue)
  17863. {
  17864. localVar = checkLocal;
  17865. break;
  17866. }
  17867. }
  17868. }
  17869. else if (typedVal.mValue.IsArg())
  17870. {
  17871. auto methodState = mModule->mCurMethodState->GetNonCaptureState();
  17872. if (typedVal.mValue.mId < methodState->mLocals.mSize)
  17873. localVar = methodState->mLocals[typedVal.mValue.mId];
  17874. }
  17875. if ((typedVal.mKind == BfTypedValueKind_MutableValue) && (onlyNeedsMut))
  17876. {
  17877. return true;
  17878. }
  17879. bool canModify = typedVal.CanModify();
  17880. if (((typedVal.mKind == BfTypedValueKind_TempAddr) || (typedVal.mKind == BfTypedValueKind_CopyOnMutateAddr_Derived)) &&
  17881. (strcmp(modifyType, "assign to") == 0))
  17882. mModule->Warn(0, "Assigning to temporary copy of a value. Consider using 'ref' in value source declaration.", refNode);
  17883. auto _Fail = [&](const StringImpl& error, BfAstNode* refNode)
  17884. {
  17885. if (emitWarning)
  17886. return mModule->Warn(BfWarning_BF4204_AddressOfReadOnly, error, refNode);
  17887. else
  17888. return mModule->Fail(error, refNode);
  17889. };
  17890. if (localVar != NULL)
  17891. {
  17892. if (!canModify)
  17893. {
  17894. BfError* error = NULL;
  17895. if (localVar->mIsThis)
  17896. {
  17897. bool isClosure = false;
  17898. BfTypeInstance* checkTypeInst = localVar->mResolvedType->ToTypeInstance();
  17899. int fieldIdx = mResultLocalVarField - 1;
  17900. if ((!isCapturedLocal) && (mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mClosureType != NULL))
  17901. {
  17902. isClosure = true;
  17903. auto closureThis = mModule->mCurMethodState->mClosureState->mClosureType;
  17904. closureThis = checkTypeInst->mFieldInstances[0].mResolvedType->ToTypeInstance();
  17905. if (fieldIdx >= -1)
  17906. {
  17907. checkTypeInst = closureThis;
  17908. }
  17909. else
  17910. {
  17911. fieldIdx = -fieldIdx - 2;
  17912. isCapturedLocal = true;
  17913. }
  17914. }
  17915. if (fieldIdx < 0)
  17916. {
  17917. if (isClosure)
  17918. {
  17919. if (!mModule->mCurMethodState->mClosureState->mDeclaringMethodIsMutating)
  17920. error = _Fail(StrFormat("Cannot %s 'this' within struct lambda. Consider adding 'mut' specifier to this method.", modifyType), refNode);
  17921. else
  17922. error = _Fail(StrFormat("Cannot %s 'this' within struct lambda. Consider adding by-reference capture specifier [&] to lambda.", modifyType), refNode);
  17923. }
  17924. else if (localVar->mResolvedType->IsValueType())
  17925. {
  17926. error = _Fail(StrFormat("Cannot %s 'this' within struct method '%s'. Consider adding 'mut' specifier to this method.", modifyType,
  17927. mModule->MethodToString(mModule->mCurMethodInstance).c_str()), refNode);
  17928. }
  17929. else
  17930. {
  17931. error = _Fail(StrFormat("Cannot %s 'this' because '%s' is a reference type.", modifyType,
  17932. mModule->TypeToString(localVar->mResolvedType).c_str()), refNode);
  17933. }
  17934. return false;
  17935. }
  17936. else if (mResultFieldInstance != NULL)
  17937. {
  17938. if (isCapturedLocal)
  17939. {
  17940. 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,
  17941. mResultFieldInstance->GetFieldDef()->mName.c_str()), refNode);
  17942. }
  17943. else if (isClosure)
  17944. {
  17945. if (!mModule->mCurMethodState->mClosureState->mDeclaringMethodIsMutating)
  17946. error = _Fail(StrFormat("Cannot %s field '%s.%s' within struct lambda. Consider adding 'mut' specifier to this method.", modifyType,
  17947. mModule->TypeToString(mResultFieldInstance->mOwner).c_str(), mResultFieldInstance->GetFieldDef()->mName.c_str()), refNode);
  17948. else
  17949. error = _Fail(StrFormat("Cannot %s field '%s.%s' within struct lambda. Consider adding by-reference capture specifier [&] to lambda.", modifyType,
  17950. mModule->TypeToString(mResultFieldInstance->mOwner).c_str(), mResultFieldInstance->GetFieldDef()->mName.c_str()), refNode);
  17951. }
  17952. else if (mResultFieldInstance->GetFieldDef()->mIsReadOnly)
  17953. {
  17954. error = _Fail(StrFormat("Cannot %s readonly field '%s.%s' within method '%s'", modifyType,
  17955. mModule->TypeToString(mResultFieldInstance->mOwner).c_str(), mResultFieldInstance->GetFieldDef()->mName.c_str(),
  17956. mModule->MethodToString(mModule->mCurMethodInstance).c_str()), refNode);
  17957. }
  17958. else if (mResultFieldInstance->GetFieldDef()->mIsAppend)
  17959. {
  17960. error = _Fail(StrFormat("Cannot %s append field '%s.%s' within method '%s'", modifyType,
  17961. mModule->TypeToString(mResultFieldInstance->mOwner).c_str(), mResultFieldInstance->GetFieldDef()->mName.c_str(),
  17962. mModule->MethodToString(mModule->mCurMethodInstance).c_str()), refNode);
  17963. }
  17964. else if (auto propertyDeclaration = BfNodeDynCast<BfPropertyDeclaration>(mResultFieldInstance->GetFieldDef()->mFieldDeclaration))
  17965. {
  17966. String propNam;
  17967. if (propertyDeclaration->mNameNode != NULL)
  17968. propertyDeclaration->mNameNode->ToString(propNam);
  17969. error = _Fail(StrFormat("Cannot %s auto-implemented property '%s.%s' without set accessor", modifyType,
  17970. mModule->TypeToString(mResultFieldInstance->mOwner).c_str(), propNam.c_str()), refNode);
  17971. }
  17972. else
  17973. {
  17974. error = _Fail(StrFormat("Cannot %s field '%s.%s' within struct method '%s'. Consider adding 'mut' specifier to this method.", modifyType,
  17975. mModule->TypeToString(mResultFieldInstance->mOwner).c_str(), mResultFieldInstance->GetFieldDef()->mName.c_str(),
  17976. mModule->MethodToString(mModule->mCurMethodInstance).c_str()), refNode);
  17977. }
  17978. return false;
  17979. }
  17980. }
  17981. else if (localVar->IsParam())
  17982. {
  17983. if (!mModule->mCurMethodInstance->IsMixin())
  17984. {
  17985. if (mModule->mCurMethodState->mMixinState != NULL)
  17986. {
  17987. error = _Fail(StrFormat("Cannot %s mixin parameter '%s'", modifyType,
  17988. localVar->mName.c_str()), refNode);
  17989. }
  17990. else if ((onlyNeedsMut) && (localVar->mResolvedType != NULL) && (localVar->mResolvedType->IsGenericParam()))
  17991. {
  17992. if (emitWarning)
  17993. 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.",
  17994. localVar->mName.c_str(), localVar->mName.c_str()), refNode);
  17995. else
  17996. 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,
  17997. localVar->mName.c_str(), localVar->mName.c_str()), refNode);
  17998. }
  17999. else
  18000. {
  18001. if (emitWarning)
  18002. 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.",
  18003. localVar->mName.c_str(), localVar->mName.c_str()), refNode);
  18004. else
  18005. error = _Fail(StrFormat("Cannot %s parameter '%s'. Consider adding 'ref' specifier to parameter or declaring 'var %s;' to create a mutable copy.", modifyType,
  18006. localVar->mName.c_str(), localVar->mName.c_str()), refNode);
  18007. }
  18008. return false;
  18009. }
  18010. }
  18011. else
  18012. {
  18013. if ((mResultLocalVarField != 0) && (!localVar->mIsReadOnly))
  18014. {
  18015. auto typeInst = localVar->mResolvedType->ToTypeInstance();
  18016. int dataIdx = mResultLocalVarField - 1;
  18017. if (typeInst != NULL)
  18018. {
  18019. for (auto& field : typeInst->mFieldInstances)
  18020. {
  18021. if (field.mDataIdx == dataIdx)
  18022. {
  18023. error = _Fail(StrFormat("Cannot %s readonly field '%s.%s'.", modifyType,
  18024. mModule->TypeToString(typeInst).c_str(),
  18025. field.GetFieldDef()->mName.c_str()), refNode);
  18026. break;
  18027. }
  18028. }
  18029. }
  18030. }
  18031. if (error == NULL)
  18032. {
  18033. error = _Fail(StrFormat("Cannot %s read-only local variable '%s'.", modifyType,
  18034. localVar->mName.c_str()), refNode);
  18035. }
  18036. return false;
  18037. }
  18038. }
  18039. else
  18040. {
  18041. // When we are capturing, we need to note that we require capturing by reference here
  18042. localVar->mWrittenToId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++;
  18043. }
  18044. }
  18045. if ((mResultFieldInstance != NULL) && (mResultFieldInstance->GetFieldDef()->mIsReadOnly) && (!canModify))
  18046. {
  18047. if (mModule->mCurMethodInstance != NULL)
  18048. {
  18049. auto error = _Fail(StrFormat("Cannot %s static readonly field '%s.%s' within method '%s'", modifyType,
  18050. mModule->TypeToString(mResultFieldInstance->mOwner).c_str(), mResultFieldInstance->GetFieldDef()->mName.c_str(),
  18051. mModule->MethodToString(mModule->mCurMethodInstance).c_str()), refNode);
  18052. }
  18053. return false;
  18054. }
  18055. if ((!skipCopyOnMutate) && (typedVal.IsCopyOnMutate()))
  18056. typedVal = mModule->CopyValue(typedVal);
  18057. if ((emitWarning) && (typedVal.IsReadOnly()))
  18058. {
  18059. mModule->Warn(0, StrFormat("Cannot %s read-only variable", modifyType), refNode);
  18060. return true;
  18061. }
  18062. return mModule->CheckModifyValue(typedVal, refNode, modifyType);
  18063. }
  18064. void BfExprEvaluator::Visit(BfConditionalExpression* condExpr)
  18065. {
  18066. static int sCallCount = 0;
  18067. sCallCount++;
  18068. auto condResult = mModule->CreateValueFromExpression(condExpr->mConditionExpression, mModule->GetPrimitiveType(BfTypeCode_Boolean), (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags));
  18069. if (!condResult)
  18070. return;
  18071. if (condExpr->mTrueExpression == NULL)
  18072. {
  18073. mModule->AssertErrorState();
  18074. return;
  18075. }
  18076. if (condExpr->mFalseExpression == NULL)
  18077. {
  18078. mModule->CreateValueFromExpression(condExpr->mTrueExpression, mExpectingType, BfEvalExprFlags_NoCast);
  18079. mModule->AssertErrorState();
  18080. return;
  18081. }
  18082. bool isConstBranch = false;
  18083. bool constResult = false;
  18084. bool constResultUndef = false;
  18085. if (condResult.mValue.IsConst())
  18086. {
  18087. auto constValue = mModule->mBfIRBuilder->GetConstant(condResult.mValue);
  18088. if (constValue->mTypeCode == BfTypeCode_Boolean)
  18089. {
  18090. isConstBranch = true;
  18091. constResult = constValue->mBool;
  18092. }
  18093. else if (constValue->mConstType == BfConstType_Undef)
  18094. {
  18095. isConstBranch = true;
  18096. constResultUndef = true;
  18097. }
  18098. }
  18099. if (isConstBranch)
  18100. {
  18101. BfExpression* actualExpr = (constResult) ? condExpr->mTrueExpression : condExpr->mFalseExpression;
  18102. BfExpression* ignoredExpr = (constResult) ? condExpr->mFalseExpression : condExpr->mTrueExpression;
  18103. BfTypedValue actualValue = mModule->CreateValueFromExpression(actualExpr, mExpectingType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast));
  18104. BfTypedValue ignoredValue;
  18105. //
  18106. {
  18107. auto curBlock = mModule->mBfIRBuilder->GetInsertBlock();
  18108. SetAndRestoreValue<bool> ignoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
  18109. SetAndRestoreValue<bool> prevInConstIgnore(mModule->mCurMethodState->mCurScope->mInConstIgnore, true);
  18110. ignoredValue = mModule->CreateValueFromExpression(ignoredExpr, mExpectingType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast));
  18111. mModule->mBfIRBuilder->SetInsertPoint(curBlock);
  18112. }
  18113. if (!actualValue)
  18114. return;
  18115. if ((ignoredValue) && (ignoredValue.mType != actualValue.mType) && (!ignoredValue.mType->IsVar()))
  18116. {
  18117. // Cast to more specific 'ignored' type if applicable
  18118. if (mModule->CanCast(actualValue, ignoredValue.mType))
  18119. {
  18120. actualValue = mModule->Cast(actualExpr, actualValue, ignoredValue.mType);
  18121. }
  18122. else if (!mModule->CanCast(ignoredValue, actualValue.mType))
  18123. {
  18124. mModule->Fail(StrFormat("Type of conditional expression cannot be determined because there is no implicit conversion between '%s' and '%s'",
  18125. mModule->TypeToString(actualValue.mType).c_str(), mModule->TypeToString(ignoredValue.mType).c_str()), condExpr);
  18126. }
  18127. }
  18128. mResult = actualValue;
  18129. if (constResultUndef)
  18130. mResult = mModule->GetDefaultTypedValue(mResult.mType, false, BfDefaultValueKind_Undef);
  18131. return;
  18132. }
  18133. auto trueBB = mModule->mBfIRBuilder->CreateBlock("cond.then");
  18134. auto falseBB = mModule->mBfIRBuilder->CreateBlock("cond.else");
  18135. auto endBB = mModule->mBfIRBuilder->CreateBlock("cond.end");
  18136. auto contBB = mModule->mBfIRBuilder->CreateBlock("cond.cont");
  18137. mModule->mBfIRBuilder->CreateCondBr(condResult.mValue, trueBB, falseBB);
  18138. SetAndRestoreValue<bool> prevInCondBlock(mModule->mCurMethodState->mCurScope->mInnerIsConditional, true);
  18139. bool wantExpectingCast = (mExpectingType != NULL) && ((mBfEvalExprFlags & BfEvalExprFlags_NoCast) == 0);
  18140. mModule->AddBasicBlock(trueBB);
  18141. auto trueValue = mModule->CreateValueFromExpression(condExpr->mTrueExpression, mExpectingType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_CreateConditionalScope));
  18142. if ((wantExpectingCast) && (trueValue) && (trueValue.mType != mExpectingType))
  18143. {
  18144. // In some cases like typed primitives - we CAN individually cast each value which it's a constant still, but not after the merging
  18145. // IE: Color c = isOver ? 0xFF000000 : 0xFFFFFFFF;
  18146. // Otherwise the resulting value would just be 'int' which cannot implicitly convert to Color, but each of those ints can be
  18147. // a uint32 if converted separately
  18148. auto checkTrueValue = mModule->Cast(condExpr->mTrueExpression, trueValue, mExpectingType, BfCastFlags_SilentFail);
  18149. if (checkTrueValue)
  18150. trueValue = checkTrueValue;
  18151. mModule->FixIntUnknown(trueValue);
  18152. }
  18153. auto trueBlockPos = mModule->mBfIRBuilder->GetInsertBlock();
  18154. mModule->AddBasicBlock(falseBB);
  18155. auto falseValue = mModule->CreateValueFromExpression(condExpr->mFalseExpression, mExpectingType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_CreateConditionalScope));
  18156. auto falseBlockPos = mModule->mBfIRBuilder->GetInsertBlock();
  18157. if ((wantExpectingCast) && (falseValue) && (falseValue.mType != mExpectingType))
  18158. {
  18159. auto checkFalseValue = mModule->Cast(condExpr->mFalseExpression, falseValue, mExpectingType, BfCastFlags_SilentFail);
  18160. if (checkFalseValue)
  18161. falseValue = checkFalseValue;
  18162. mModule->FixIntUnknown(falseValue);
  18163. }
  18164. bool isValid = trueValue && falseValue;
  18165. if (isValid)
  18166. {
  18167. BfTypedValue falseToTrue;
  18168. {
  18169. SetAndRestoreValue<bool> prevIgnoreError(mModule->mIgnoreErrors, true);
  18170. mModule->mBfIRBuilder->SetInsertPoint(falseBlockPos);
  18171. falseToTrue = mModule->Cast(condExpr->mFalseExpression, falseValue, trueValue.mType);
  18172. }
  18173. if (falseToTrue)
  18174. {
  18175. falseValue = falseToTrue;
  18176. }
  18177. else
  18178. {
  18179. BfTypedValue trueToFalse;
  18180. {
  18181. SetAndRestoreValue<bool> prevIgnoreError(mModule->mIgnoreErrors, true);
  18182. mModule->mBfIRBuilder->SetInsertPoint(trueBlockPos);
  18183. trueToFalse = mModule->Cast(condExpr->mTrueExpression, trueValue, falseValue.mType);
  18184. }
  18185. if (!trueToFalse)
  18186. {
  18187. mModule->Fail(StrFormat("Type of conditional expression cannot be determined because there is no implicit conversion between '%s' and '%s'",
  18188. mModule->TypeToString(trueValue.mType).c_str(), mModule->TypeToString(falseValue.mType).c_str()), condExpr);
  18189. //return;
  18190. isValid = false;
  18191. }
  18192. else
  18193. trueValue = trueToFalse;
  18194. }
  18195. }
  18196. prevInCondBlock.Restore();
  18197. mModule->mBfIRBuilder->SetInsertPoint(trueBlockPos);
  18198. if (isValid)
  18199. trueValue = mModule->LoadValue(trueValue);
  18200. mModule->mBfIRBuilder->CreateBr(endBB);
  18201. mModule->mBfIRBuilder->SetInsertPoint(falseBlockPos);
  18202. if (isValid)
  18203. falseValue = mModule->LoadValue(falseValue);
  18204. mModule->mBfIRBuilder->CreateBr(endBB);
  18205. mModule->AddBasicBlock(endBB, false);
  18206. if (!isValid)
  18207. return;
  18208. mModule->mBfIRBuilder->SetInsertPoint(endBB);
  18209. BfIRValue phi;
  18210. if (!trueValue.mType->IsValuelessType())
  18211. {
  18212. if (trueValue.mType->IsVar())
  18213. {
  18214. phi = mModule->mBfIRBuilder->GetFakeVal();
  18215. }
  18216. else
  18217. {
  18218. mModule->mBfIRBuilder->PopulateType(trueValue.mType);
  18219. phi = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(trueValue.mType), 2);
  18220. mModule->mBfIRBuilder->AddPhiIncoming(phi, trueValue.mValue, trueBlockPos);
  18221. mModule->mBfIRBuilder->AddPhiIncoming(phi, falseValue.mValue, falseBlockPos);
  18222. }
  18223. }
  18224. mModule->mBfIRBuilder->CreateBr(contBB);
  18225. mModule->AddBasicBlock(contBB);
  18226. mResult = BfTypedValue(phi, trueValue.mType);
  18227. }
  18228. void BfExprEvaluator::PopulateDeferrredTupleAssignData(BfTupleExpression* tupleExpr, DeferredTupleAssignData& deferredTupleAssignData)
  18229. {
  18230. BfTypeVector fieldTypes;
  18231. Array<String> fieldNames;
  18232. // We need to evaluate each LHS tuple component in a separate BfExprEvaluator because each one
  18233. // could be a property and the 'mPropDef' target info is tied to a single evaluator
  18234. for (int valueIdx = 0; valueIdx < (int)tupleExpr->mValues.size(); valueIdx++)
  18235. {
  18236. DeferredTupleAssignData::Entry entry;
  18237. entry.mExprEvaluator = NULL;
  18238. entry.mInnerTuple = NULL;
  18239. entry.mVarType = NULL;
  18240. entry.mVarNameNode = NULL;
  18241. BfExpression* valueExpr = tupleExpr->mValues[valueIdx];
  18242. entry.mExpr = valueExpr;
  18243. BfType* fieldType = NULL;
  18244. BfType* resultType = NULL;
  18245. if (auto innerTupleExpr = BfNodeDynCast<BfTupleExpression>(valueExpr))
  18246. {
  18247. entry.mInnerTuple = new DeferredTupleAssignData();
  18248. PopulateDeferrredTupleAssignData(innerTupleExpr, *entry.mInnerTuple);
  18249. resultType = entry.mInnerTuple->mTupleType;
  18250. }
  18251. else
  18252. {
  18253. BfExprEvaluator* exprEvaluator = new BfExprEvaluator(mModule);
  18254. entry.mExprEvaluator = exprEvaluator;
  18255. if (valueExpr->IsA<BfUninitializedExpression>())
  18256. {
  18257. resultType = mModule->GetPrimitiveType(BfTypeCode_None);
  18258. }
  18259. if (auto varDecl = BfNodeDynCast<BfVariableDeclaration>(valueExpr))
  18260. {
  18261. if ((varDecl->mTypeRef->IsA<BfLetTypeReference>()) || (varDecl->mTypeRef->IsA<BfVarTypeReference>()))
  18262. {
  18263. resultType = mModule->GetPrimitiveType(BfTypeCode_Var);
  18264. }
  18265. else
  18266. {
  18267. resultType = ResolveTypeRef(varDecl->mTypeRef);
  18268. if (resultType == NULL)
  18269. resultType = mModule->GetPrimitiveType(BfTypeCode_Var);
  18270. }
  18271. entry.mVarType = resultType;
  18272. }
  18273. if (auto binOpExpr = BfNodeDynCast<BfBinaryOperatorExpression>(valueExpr))
  18274. {
  18275. if (binOpExpr->mOp == BfBinaryOp_Multiply)
  18276. {
  18277. SetAndRestoreValue<bool> prevIgnoreError(mModule->mIgnoreErrors, true);
  18278. auto resolvedType = mModule->ResolveTypeRef(binOpExpr->mLeft, NULL);
  18279. prevIgnoreError.Restore();
  18280. if (resolvedType != NULL)
  18281. {
  18282. resultType = mModule->CreatePointerType(resolvedType);
  18283. entry.mVarType = resultType;
  18284. entry.mVarNameNode = binOpExpr->mRight;
  18285. }
  18286. }
  18287. }
  18288. if (resultType == NULL)
  18289. {
  18290. exprEvaluator->VisitChild(valueExpr);
  18291. if ((!exprEvaluator->mResult) && (exprEvaluator->mPropDef == NULL))
  18292. exprEvaluator->mResult = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_None));
  18293. resultType = exprEvaluator->mResult.mType;
  18294. }
  18295. if ((resultType == NULL) && (exprEvaluator->mPropDef != NULL) && (exprEvaluator->mPropTarget.mType != NULL))
  18296. {
  18297. auto propTypeInst = exprEvaluator->mPropTarget.mType->ToTypeInstance();
  18298. if ((propTypeInst == NULL) && (exprEvaluator->mPropTarget.mType->IsPointer()))
  18299. {
  18300. BfPointerType* pointerType = (BfPointerType*)exprEvaluator->mPropTarget.mType;
  18301. propTypeInst = pointerType->mElementType->ToTypeInstance();
  18302. }
  18303. auto setMethod = GetPropertyMethodDef(exprEvaluator->mPropDef, BfMethodType_PropertySetter, mPropCheckedKind, mPropTarget);
  18304. if (setMethod != NULL)
  18305. {
  18306. auto methodInstance = mModule->GetMethodInstance(propTypeInst, setMethod, BfTypeVector());
  18307. resultType = methodInstance.mMethodInstance->GetParamType(0);
  18308. }
  18309. else
  18310. {
  18311. auto getMethod = GetPropertyMethodDef(exprEvaluator->mPropDef, BfMethodType_PropertyGetter, mPropCheckedKind, mPropTarget);
  18312. if (getMethod != NULL)
  18313. {
  18314. auto methodInstance = mModule->GetMethodInstance(propTypeInst, getMethod, BfTypeVector());
  18315. auto retType = methodInstance.mMethodInstance->mReturnType;
  18316. if (retType->IsRef())
  18317. resultType = retType->GetUnderlyingType();
  18318. }
  18319. }
  18320. }
  18321. }
  18322. if (resultType == NULL)
  18323. resultType = mModule->GetPrimitiveType(BfTypeCode_None);
  18324. deferredTupleAssignData.mChildren.push_back(entry);
  18325. fieldTypes.push_back(resultType);
  18326. }
  18327. for (BfTupleNameNode* requestedName : tupleExpr->mNames)
  18328. {
  18329. if (requestedName == NULL)
  18330. fieldNames.push_back("");
  18331. else
  18332. fieldNames.push_back(requestedName->mNameNode->ToString());
  18333. }
  18334. BfTypeInstance* tupleType = mModule->CreateTupleType(fieldTypes, fieldNames, true);
  18335. deferredTupleAssignData.mTupleType = tupleType;
  18336. }
  18337. void BfExprEvaluator::AssignDeferrredTupleAssignData(BfAssignmentExpression* assignExpr, DeferredTupleAssignData& deferredTupleAssignData, BfTypedValue rightValue)
  18338. {
  18339. BF_ASSERT(rightValue.mType->IsTuple());
  18340. auto tupleType = (BfTypeInstance*)rightValue.mType;
  18341. for (int valueIdx = 0; valueIdx < (int)deferredTupleAssignData.mChildren.size(); valueIdx++)
  18342. {
  18343. auto& child = deferredTupleAssignData.mChildren[valueIdx];
  18344. BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[valueIdx];
  18345. BfTypedValue elementValue;
  18346. if (fieldInstance->mDataIdx >= 0)
  18347. {
  18348. rightValue = mModule->LoadOrAggregateValue(rightValue);
  18349. mModule->mBfIRBuilder->PopulateType(rightValue.mType);
  18350. auto extractedValue = mModule->mBfIRBuilder->CreateExtractValue(rightValue.mValue, fieldInstance->mDataIdx);
  18351. elementValue = BfTypedValue(extractedValue, fieldInstance->GetResolvedType());
  18352. if (child.mInnerTuple != NULL)
  18353. {
  18354. AssignDeferrredTupleAssignData(assignExpr, *child.mInnerTuple, elementValue);
  18355. delete child.mInnerTuple;
  18356. child.mInnerTuple = NULL;
  18357. }
  18358. else
  18359. {
  18360. if (child.mExprEvaluator->HasResult())
  18361. {
  18362. child.mExprEvaluator->mBfEvalExprFlags = (BfEvalExprFlags)(child.mExprEvaluator->mBfEvalExprFlags | BfEvalExprFlags_NoAutoComplete);
  18363. child.mExprEvaluator->PerformAssignment(assignExpr, true, elementValue);
  18364. }
  18365. }
  18366. }
  18367. if (child.mVarType != NULL)
  18368. {
  18369. if (auto varDecl = BfNodeDynCast<BfVariableDeclaration>(child.mExpr))
  18370. {
  18371. if (!elementValue)
  18372. elementValue = mModule->GetDefaultTypedValue(fieldInstance->GetResolvedType());
  18373. mModule->HandleVariableDeclaration(varDecl, elementValue);
  18374. }
  18375. else
  18376. {
  18377. // This handles the 'a*b' disambiguated variable decl case
  18378. mModule->HandleVariableDeclaration(child.mVarType, child.mVarNameNode, elementValue);
  18379. }
  18380. }
  18381. }
  18382. }
  18383. void BfExprEvaluator::DoTupleAssignment(BfAssignmentExpression* assignExpr)
  18384. {
  18385. auto tupleExpr = BfNodeDynCast<BfTupleExpression>(assignExpr->mLeft);
  18386. DeferredTupleAssignData deferredTupleAssignData;
  18387. PopulateDeferrredTupleAssignData(tupleExpr, deferredTupleAssignData);
  18388. BfTypeInstance* tupleType = deferredTupleAssignData.mTupleType;
  18389. BfTypedValue rightValue;
  18390. if (assignExpr->mRight != NULL)
  18391. {
  18392. rightValue = mModule->CreateValueFromExpression(assignExpr->mRight, tupleType);
  18393. }
  18394. if (!rightValue)
  18395. {
  18396. tupleType = mModule->SantizeTupleType(tupleType);
  18397. rightValue = mModule->GetDefaultTypedValue(tupleType);
  18398. }
  18399. rightValue = mModule->LoadValue(rightValue);
  18400. AssignDeferrredTupleAssignData(assignExpr, deferredTupleAssignData, rightValue);
  18401. mResult = rightValue;
  18402. }
  18403. BfTypedValue BfExprEvaluator::PerformAssignment_CheckOp(BfAssignmentExpression* assignExpr, bool deferBinop, BfTypedValue& leftValue, BfTypedValue& rightValue, bool& evaluatedRight)
  18404. {
  18405. BfResolvedArgs argValues;
  18406. auto checkTypeInst = leftValue.mType->ToTypeInstance();
  18407. while (checkTypeInst != NULL)
  18408. {
  18409. for (auto operatorDef : checkTypeInst->mTypeDef->mOperators)
  18410. {
  18411. if (operatorDef->mOperatorDeclaration->mAssignOp != assignExpr->mOp)
  18412. continue;
  18413. auto methodInst = mModule->GetRawMethodInstanceAtIdx(checkTypeInst, operatorDef->mIdx);
  18414. if (methodInst == NULL)
  18415. continue;
  18416. if (methodInst->GetParamCount() != 1)
  18417. continue;
  18418. auto paramType = methodInst->GetParamType(0);
  18419. BfModuleMethodInstance moduleMethodInstance;
  18420. if (methodInst->mIsUnspecialized)
  18421. {
  18422. BfTypeVector checkMethodGenericArguments;
  18423. checkMethodGenericArguments.resize(methodInst->GetNumGenericArguments());
  18424. BfGenericInferContext genericInferContext;
  18425. genericInferContext.mModule = mModule;
  18426. genericInferContext.mCheckMethodGenericArguments = &checkMethodGenericArguments;
  18427. if (!genericInferContext.InferGenericArgument(methodInst, rightValue.mType, paramType, rightValue.mValue))
  18428. continue;
  18429. bool genericsInferred = true;
  18430. for (int i = 0; i < checkMethodGenericArguments.mSize; i++)
  18431. if ((checkMethodGenericArguments[i] == NULL) || (checkMethodGenericArguments[i]->IsVar()))
  18432. genericsInferred = false;
  18433. if (!genericsInferred)
  18434. continue;
  18435. moduleMethodInstance = mModule->GetMethodInstance(checkTypeInst, operatorDef, checkMethodGenericArguments);
  18436. paramType = moduleMethodInstance.mMethodInstance->GetParamType(0);
  18437. }
  18438. if (deferBinop)
  18439. {
  18440. if (argValues.mArguments == NULL)
  18441. {
  18442. SizedArray<BfExpression*, 2> argExprs;
  18443. argExprs.push_back(assignExpr->mRight);
  18444. BfSizedArray<BfExpression*> sizedArgExprs(argExprs);
  18445. argValues.Init(&sizedArgExprs);
  18446. ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval);
  18447. }
  18448. evaluatedRight = true;
  18449. rightValue = ResolveArgValue(argValues.mResolvedArgs[0], paramType);
  18450. if (!rightValue)
  18451. continue;
  18452. }
  18453. else
  18454. {
  18455. if (!mModule->CanCast(rightValue, paramType))
  18456. continue;
  18457. rightValue = mModule->Cast(assignExpr->mLeft, rightValue, paramType);
  18458. BF_ASSERT(rightValue);
  18459. }
  18460. mModule->SetElementType(assignExpr->mOpToken, BfSourceElementType_Method);
  18461. auto autoComplete = GetAutoComplete();
  18462. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(assignExpr->mOpToken)))
  18463. {
  18464. if (operatorDef->mOperatorDeclaration != NULL)
  18465. autoComplete->SetDefinitionLocation(operatorDef->mOperatorDeclaration->mOpTypeToken);
  18466. }
  18467. if (!moduleMethodInstance)
  18468. moduleMethodInstance = mModule->GetMethodInstance(checkTypeInst, operatorDef, BfTypeVector());
  18469. BfExprEvaluator exprEvaluator(mModule);
  18470. SizedArray<BfIRValue, 1> args;
  18471. exprEvaluator.PushThis(assignExpr->mLeft, leftValue, moduleMethodInstance.mMethodInstance, args);
  18472. exprEvaluator.PushArg(rightValue, args);
  18473. exprEvaluator.CreateCall(assignExpr, moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, false, args);
  18474. return leftValue;
  18475. }
  18476. checkTypeInst = mModule->GetBaseType(checkTypeInst);
  18477. }
  18478. return BfTypedValue();
  18479. }
  18480. void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool evaluatedLeft, BfTypedValue rightValue, BfTypedValue* outCascadeValue)
  18481. {
  18482. auto binaryOp = BfAssignOpToBinaryOp(assignExpr->mOp);
  18483. BfExpression* targetNode = assignExpr->mLeft;
  18484. if ((BfNodeIsA<BfMixinExpression>(targetNode)) && (!mModule->mCurMethodInstance->mIsUnspecialized))
  18485. {
  18486. // If we have a "mixin = <X>" but there's no mixin target then ignore the assignment
  18487. int mixinVar = GetMixinVariable();
  18488. if (mixinVar == -1)
  18489. {
  18490. mResult = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_None));
  18491. return;
  18492. }
  18493. }
  18494. BfAutoComplete* autoComplete = GetAutoComplete();
  18495. bool deferredFixits = false;
  18496. //TODO: Why was this needed? This breaks fixits on target nodes (ie: 'using' field fixit for 'fully quality')
  18497. /*if ((autoComplete != NULL) && (autoComplete->mResolveType == BfResolveType_GetFixits))
  18498. {
  18499. SetAndRestoreValue<bool> ignoreFixits(autoComplete->mIgnoreFixits, true);
  18500. VisitChild(targetNode);
  18501. deferredFixits = true;
  18502. }
  18503. else*/
  18504. if (!evaluatedLeft)
  18505. {
  18506. if (auto memberReferenceExpr = BfNodeDynCast<BfMemberReferenceExpression>(targetNode))
  18507. {
  18508. DoMemberReference(memberReferenceExpr, outCascadeValue);
  18509. }
  18510. else
  18511. VisitChild(targetNode);
  18512. }
  18513. if ((!mResult) && (mPropDef == NULL))
  18514. {
  18515. if (assignExpr->mRight != NULL)
  18516. {
  18517. auto result = mModule->CreateValueFromExpression(assignExpr->mRight);
  18518. if (deferredFixits)
  18519. {
  18520. SetAndRestoreValue<bool> ignoreErrors(mModule->mIgnoreErrors, true);
  18521. mExpectingType = result.mType;
  18522. VisitChild(targetNode);
  18523. mResult = BfTypedValue();
  18524. }
  18525. }
  18526. return;
  18527. }
  18528. ResolveGenericType();
  18529. auto ptr = mModule->RemoveRef(mResult);
  18530. mResult = BfTypedValue();
  18531. if (mPropDef != NULL)
  18532. {
  18533. bool hasLeftVal = false;
  18534. auto propDef = mPropDef;
  18535. auto propTarget = mPropTarget;
  18536. auto setMethod = GetPropertyMethodDef(mPropDef, BfMethodType_PropertySetter, mPropCheckedKind, mPropTarget);
  18537. if (setMethod == NULL)
  18538. {
  18539. // Allow for a ref return on the getter to be used if a setter is not available
  18540. GetResult();
  18541. if ((mResult) && (mResult.mKind == BfTypedValueKind_Addr))
  18542. {
  18543. ptr = mResult;
  18544. mResult = BfTypedValue();
  18545. hasLeftVal = true;
  18546. }
  18547. else
  18548. {
  18549. mModule->Fail("Property has no setter", mPropSrc);
  18550. if (assignExpr->mRight != NULL)
  18551. mModule->CreateValueFromExpression(assignExpr->mRight, ptr.mType, BfEvalExprFlags_NoCast);
  18552. return;
  18553. }
  18554. }
  18555. if (!hasLeftVal)
  18556. {
  18557. auto methodInstance = GetPropertyMethodInstance(setMethod);
  18558. if (methodInstance.mMethodInstance == NULL)
  18559. return;
  18560. //BF_ASSERT(methodInstance.mMethodInstance->mMethodDef == setMethod);
  18561. CheckPropFail(setMethod, methodInstance.mMethodInstance, (mPropGetMethodFlags & BfGetMethodInstanceFlag_Friend) == 0);
  18562. auto autoComplete = GetAutoComplete();
  18563. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(mPropSrc)) && (autoComplete->mResolveType == BfResolveType_GetResultString))
  18564. {
  18565. autoComplete->mResultString = ":";
  18566. autoComplete->mResultString += mModule->TypeToString(methodInstance.mMethodInstance->GetParamType(0));
  18567. autoComplete->mResultString += " ";
  18568. autoComplete->mResultString += mModule->TypeToString(methodInstance.mMethodInstance->GetOwner());
  18569. autoComplete->mResultString += ".";
  18570. autoComplete->mResultString += mPropDef->mName;
  18571. }
  18572. bool handled = false;
  18573. BfTypedValue convVal;
  18574. if (binaryOp != BfBinaryOp_None)
  18575. {
  18576. BfTypedValue leftValue = mModule->CreateValueFromExpression(assignExpr->mLeft, mExpectingType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_AllowIntUnknown));
  18577. if (!leftValue)
  18578. return;
  18579. bool evaluatedRight = false;
  18580. auto opResult = PerformAssignment_CheckOp(assignExpr, true, leftValue, rightValue, evaluatedRight);
  18581. if (opResult)
  18582. {
  18583. mResult = opResult;
  18584. return;
  18585. }
  18586. else
  18587. {
  18588. if (evaluatedRight)
  18589. {
  18590. if (!rightValue)
  18591. return;
  18592. PerformBinaryOperation(assignExpr->mLeft, assignExpr->mRight, binaryOp, assignExpr->mOpToken, BfBinOpFlag_ForceLeftType, leftValue, rightValue);
  18593. }
  18594. else
  18595. PerformBinaryOperation(assignExpr->mLeft, assignExpr->mRight, binaryOp, assignExpr->mOpToken, BfBinOpFlag_ForceLeftType, leftValue);
  18596. if (!mResult)
  18597. return;
  18598. convVal = mResult;
  18599. mResult = BfTypedValue();
  18600. if (!convVal)
  18601. return;
  18602. }
  18603. }
  18604. else
  18605. {
  18606. auto wantType = methodInstance.mMethodInstance->GetParamType(0);
  18607. if (rightValue)
  18608. {
  18609. convVal = mModule->Cast(assignExpr->mRight, rightValue, wantType);
  18610. }
  18611. else
  18612. {
  18613. if (assignExpr->mRight == NULL)
  18614. {
  18615. mModule->AssertErrorState();
  18616. return;
  18617. }
  18618. BfEvalExprFlags exprFlags = (BfEvalExprFlags)(BfEvalExprFlags_AllowSplat | BfEvalExprFlags_PendingPropSet);
  18619. if (wantType->IsRef())
  18620. exprFlags = (BfEvalExprFlags)(exprFlags | BfEvalExprFlags_AllowRefExpr);
  18621. convVal = mModule->CreateValueFromExpression(assignExpr->mRight, wantType, exprFlags);
  18622. }
  18623. if (!convVal)
  18624. {
  18625. mPropDef = NULL;
  18626. return;
  18627. }
  18628. }
  18629. if (!handled)
  18630. {
  18631. if (mPropSrc != NULL)
  18632. mModule->UpdateExprSrcPos(mPropSrc);
  18633. BfResolvedArg valueArg;
  18634. valueArg.mTypedValue = convVal;
  18635. mIndexerValues.Insert(0, valueArg);
  18636. if (!setMethod->mIsStatic)
  18637. {
  18638. auto owner = methodInstance.mMethodInstance->GetOwner();
  18639. if ((mPropTarget.mType != owner) ||
  18640. ((mPropTarget.mValue.IsFake()) && (!mOrigPropTarget.mValue.IsFake())))
  18641. {
  18642. if ((mPropDefBypassVirtual) || (!mPropTarget.mType->IsInterface()))
  18643. {
  18644. mPropTarget = mModule->Cast(mPropSrc, mOrigPropTarget, owner);
  18645. if (!mPropTarget)
  18646. {
  18647. mModule->Fail("Internal property error", mPropSrc);
  18648. return;
  18649. }
  18650. }
  18651. }
  18652. }
  18653. auto callFlags = mPropDefBypassVirtual ? BfCreateCallFlags_BypassVirtual : BfCreateCallFlags_None;
  18654. mResult = CreateCall(mPropSrc, mPropTarget, mOrigPropTarget, setMethod, methodInstance, callFlags, mIndexerValues, NULL);
  18655. mPropDef = NULL;
  18656. mResult = convVal;
  18657. mIndexerValues.Clear();
  18658. return;
  18659. }
  18660. }
  18661. }
  18662. auto toType = ptr.mType;
  18663. if (toType->IsRef())
  18664. {
  18665. auto refType = (BfRefType*)toType;
  18666. toType = refType->mElementType;
  18667. }
  18668. if (toType->IsIntUnknown())
  18669. toType = mModule->FixIntUnknown(toType);
  18670. if ((autoComplete != NULL) && (assignExpr->mOpToken != NULL) && (toType != NULL))
  18671. autoComplete->CheckEmptyStart(assignExpr->mOpToken, toType);
  18672. BfExpression* rightExpr = assignExpr->mRight;
  18673. if (rightExpr == NULL)
  18674. {
  18675. mModule->AssertErrorState();
  18676. return;
  18677. }
  18678. bool alreadyWritten = false;
  18679. BfTypedValue convVal;
  18680. if (binaryOp != BfBinaryOp_None)
  18681. {
  18682. CheckResultForReading(ptr);
  18683. BfTypedValue leftValue = ptr;
  18684. bool deferBinop = false;
  18685. BfDeferEvalChecker deferEvalChecker;
  18686. deferEvalChecker.mDeferLiterals = false;
  18687. assignExpr->mRight->Accept(&deferEvalChecker);
  18688. if (deferEvalChecker.mNeedsDeferEval)
  18689. deferBinop = true;
  18690. if (binaryOp == BfBinaryOp_NullCoalesce)
  18691. {
  18692. deferBinop = true;
  18693. }
  18694. if (!deferBinop)
  18695. {
  18696. auto expectedType = ptr.mType;
  18697. if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift))
  18698. expectedType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  18699. if ((!rightValue) && (assignExpr->mRight != NULL))
  18700. {
  18701. rightValue = mModule->CreateValueFromExpression(assignExpr->mRight, expectedType, (BfEvalExprFlags)(BfEvalExprFlags_AllowSplat | BfEvalExprFlags_NoCast));
  18702. }
  18703. }
  18704. BfResolvedArgs argValues;
  18705. if ((rightValue) || (deferBinop))
  18706. {
  18707. bool evaluatedRight = false;
  18708. auto opResult = PerformAssignment_CheckOp(assignExpr, deferBinop, leftValue, rightValue, evaluatedRight);
  18709. if (opResult)
  18710. {
  18711. mResult = opResult;
  18712. return;
  18713. }
  18714. else
  18715. {
  18716. auto flags = BfBinOpFlag_ForceLeftType;
  18717. if (deferBinop)
  18718. flags = (BfBinOpFlags)(flags | BfBinOpFlag_DeferRight);
  18719. leftValue = mModule->LoadValue(leftValue);
  18720. if (binaryOp == BfBinaryOp_NullCoalesce)
  18721. {
  18722. if (!CheckModifyResult(ptr, assignExpr->mOpToken, "assign to", false, false, true))
  18723. {
  18724. mModule->CreateValueFromExpression(assignExpr->mRight, ptr.mType, (BfEvalExprFlags)(BfEvalExprFlags_AllowSplat | BfEvalExprFlags_NoCast));
  18725. mResult = leftValue;
  18726. return;
  18727. }
  18728. if (PerformBinaryOperation_NullCoalesce(assignExpr->mOpToken, assignExpr->mLeft, assignExpr->mRight, leftValue, leftValue.mType, &ptr))
  18729. return;
  18730. }
  18731. PerformBinaryOperation(assignExpr->mLeft, assignExpr->mRight, binaryOp, assignExpr->mOpToken, flags, leftValue, rightValue);
  18732. }
  18733. }
  18734. convVal = mResult;
  18735. mResult = BfTypedValue();
  18736. if (!convVal)
  18737. return;
  18738. }
  18739. else
  18740. {
  18741. convVal = rightValue;
  18742. if (!convVal)
  18743. {
  18744. if (auto uninitExpr = BfNodeDynCast<BfUninitializedExpression>(rightExpr))
  18745. {
  18746. if (mResultLocalVar != NULL)
  18747. {
  18748. MarkResultAssigned();
  18749. return;
  18750. }
  18751. }
  18752. // In the cases like "structVal = GetVal()", the allowDirectStructRetWrite optimization allows us to pass the
  18753. // address of structVal into the sret. We only allow that if structVal is a local, because if it's globally
  18754. // visible then we could see the results of a partially-modified structVal
  18755. //bool allowDirectStructRetWrite = mResultLocalVarIdx != -1;
  18756. // ALTHOUGH- we can only allow this optimization if we can be sure the local value is not aliased- we could
  18757. // have the backend ensure that this local value never gets its address taken.
  18758. bool allowDirectStructWrite = false;
  18759. BfExprEvaluator exprEvaluator(mModule);
  18760. exprEvaluator.mExpectingType = toType;
  18761. if (allowDirectStructWrite)
  18762. exprEvaluator.mReceivingValue = &ptr;
  18763. exprEvaluator.Evaluate(rightExpr, false, false, true);
  18764. exprEvaluator.CheckResultForReading(exprEvaluator.mResult);
  18765. convVal = exprEvaluator.GetResult();
  18766. mModule->FixIntUnknown(convVal);
  18767. alreadyWritten = (allowDirectStructWrite) && (exprEvaluator.mReceivingValue == NULL);
  18768. if (!convVal)
  18769. convVal = mModule->GetDefaultTypedValue(toType);
  18770. // Did we use mReceivingValue as a mixin result?
  18771. if ((convVal.mValue) && (convVal.mValue == ptr.mValue))
  18772. {
  18773. mResult = convVal;
  18774. return;
  18775. }
  18776. }
  18777. }
  18778. if (!CheckModifyResult(ptr, assignExpr->mOpToken, "assign to", false, false, true))
  18779. {
  18780. mResult = convVal;
  18781. return;
  18782. }
  18783. if (ptr.mKind == BfTypedValueKind_CopyOnMutateAddr)
  18784. ptr.mKind = BfTypedValueKind_Addr;
  18785. else if (ptr.IsCopyOnMutate())
  18786. ptr = mModule->CopyValue(ptr);
  18787. BF_ASSERT(convVal);
  18788. if ((convVal) && (convVal.mType->IsNull()) && (ptr.mType->IsNullable()))
  18789. {
  18790. // Allow this to pass through so we can catch it in the memset later in this function
  18791. }
  18792. else
  18793. {
  18794. if (!convVal.mType->IsComposite())
  18795. convVal = mModule->LoadValue(convVal);
  18796. convVal = mModule->Cast(rightExpr, convVal, toType);
  18797. if (!convVal)
  18798. return;
  18799. convVal = mModule->LoadValue(convVal);
  18800. }
  18801. if (ptr.mType->IsVar())
  18802. {
  18803. mResult = ptr;
  18804. MarkResultAssigned();
  18805. return;
  18806. }
  18807. if (convVal.mValue)
  18808. {
  18809. if ((ptr.mType->IsStruct()) && (!ptr.mType->IsValuelessType()) && (convVal.mValue.IsConst()))
  18810. {
  18811. auto constant = mModule->mBfIRBuilder->GetConstant(convVal.mValue);
  18812. if ((constant->mTypeCode == BfTypeCode_NullPtr) || (constant->mConstType == BfConstType_AggZero))
  18813. {
  18814. auto type = ptr.mType;
  18815. mModule->mBfIRBuilder->CreateMemSet(ptr.mValue, mModule->GetConstValue(0, mModule->GetPrimitiveType(BfTypeCode_Int8)),
  18816. mModule->GetConstValue(type->mSize), type->mAlign);
  18817. mResult = ptr;
  18818. MarkResultAssigned();
  18819. return;
  18820. }
  18821. }
  18822. // if (ptr.mType->IsMethodRef())
  18823. // {
  18824. // auto methodRefType = (BfMethodRefType*)ptr.mType;
  18825. // auto methodInstance = methodRefType->mMethodInstance;
  18826. // int implicitParamCount = methodInstance->GetImplicitParamCount();
  18827. // for (int implicitParamIdx = methodInstance->HasThis() ? - 1 : 0; implicitParamIdx < implicitParamCount; implicitParamIdx++)
  18828. // {
  18829. // bool failed = false;
  18830. // auto destPtr = DoImplicitArgCapture(assignExpr, methodRefType->mMethodInstance, implicitParamIdx, failed, BfImplicitParamKind_GenericTypeMember_Addr);
  18831. // auto srcVal = DoImplicitArgCapture(assignExpr, methodRefType->mMethodInstance, implicitParamIdx, failed, BfImplicitParamKind_GenericMethodMember);
  18832. // if ((destPtr) && (srcVal))
  18833. // {
  18834. // srcVal = mModule->AggregateSplat(srcVal);
  18835. // mModule->mBfIRBuilder->CreateStore(srcVal.mValue, destPtr.mValue);
  18836. // }
  18837. // }
  18838. // }
  18839. // else
  18840. {
  18841. mModule->mBfIRBuilder->PopulateType(ptr.mType);
  18842. if (convVal.IsSplat())
  18843. {
  18844. //convVal = mModule->AggregateSplat(convVal);
  18845. mModule->AggregateSplatIntoAddr(convVal, ptr.mValue);
  18846. }
  18847. else
  18848. {
  18849. if (ptr.mType->IsOpaque())
  18850. {
  18851. mModule->Fail(StrFormat("Unable to assign to opaque type '%s'", mModule->TypeToString(ptr.mType).c_str()), assignExpr);
  18852. }
  18853. else if (ptr.mType->IsValuelessType())
  18854. {
  18855. mModule->EmitEnsureInstructionAt();
  18856. }
  18857. else if (!alreadyWritten)
  18858. {
  18859. if ((mModule->mIsComptimeModule) && (mModule->mCompiler->mCeMachine->mDebugger != NULL) && (mModule->mCompiler->mCeMachine->mDebugger->mCurDbgState != NULL))
  18860. {
  18861. auto ceDbgState = mModule->mCompiler->mCeMachine->mDebugger->mCurDbgState;
  18862. bool success = false;
  18863. if ((convVal.mValue.IsConst()) && (ptr.mValue.IsConst()))
  18864. {
  18865. auto constant = mModule->mBfIRBuilder->GetConstant(ptr.mValue);
  18866. auto valConstant = mModule->mBfIRBuilder->GetConstant(convVal.mValue);
  18867. auto ceTypedVal = mModule->mCompiler->mCeMachine->mDebugger->GetAddr(constant);
  18868. if (!ceTypedVal)
  18869. {
  18870. mModule->Fail("Invalid assignment address", assignExpr);
  18871. return;
  18872. }
  18873. auto ceContext = mModule->mCompiler->mCeMachine->mCurContext;
  18874. if (ceContext->CheckMemory((addr_ce)ceTypedVal.mAddr, convVal.mType->mSize))
  18875. {
  18876. if ((ceDbgState->mDbgExpressionFlags & DwEvalExpressionFlag_AllowSideEffects) != 0)
  18877. {
  18878. ceDbgState->mHadSideEffects = true;
  18879. if (ceContext->WriteConstant(mModule, (addr_ce)ceTypedVal.mAddr, valConstant, convVal.mType))
  18880. success = true;
  18881. }
  18882. else
  18883. {
  18884. ceDbgState->mBlockedSideEffects = true;
  18885. success = true;
  18886. }
  18887. }
  18888. }
  18889. if (!success)
  18890. {
  18891. mModule->Fail("Assignment failed", assignExpr);
  18892. return;
  18893. }
  18894. }
  18895. if (!alreadyWritten)
  18896. {
  18897. //ptr = mModule->LoadValue(ptr);
  18898. BF_ASSERT(ptr.IsAddr());
  18899. convVal = mModule->LoadValue(convVal);
  18900. auto storeInst = mModule->mBfIRBuilder->CreateAlignedStore(convVal.mValue, ptr.mValue, ptr.mType->mAlign, mIsVolatileReference);
  18901. }
  18902. }
  18903. }
  18904. }
  18905. }
  18906. else
  18907. {
  18908. BF_ASSERT(convVal.mType->IsValuelessType());
  18909. }
  18910. mResult = convVal;
  18911. MarkResultAssigned();
  18912. }
  18913. void BfExprEvaluator::Visit(BfAssignmentExpression* assignExpr)
  18914. {
  18915. if (assignExpr->mLeft->IsA<BfTupleExpression>())
  18916. {
  18917. DoTupleAssignment(assignExpr);
  18918. return;
  18919. }
  18920. BfAutoParentNodeEntry autoParentNodeEntry(mModule, assignExpr);
  18921. BfTypedValue cascadeValue;
  18922. PerformAssignment(assignExpr, false, BfTypedValue(), &cascadeValue);
  18923. if (cascadeValue)
  18924. mResult = cascadeValue;
  18925. }
  18926. void BfExprEvaluator::Visit(BfParenthesizedExpression* parenExpr)
  18927. {
  18928. VisitChild(parenExpr->mExpression);
  18929. MakeResultAsValue();
  18930. }
  18931. void BfExprEvaluator::InitializedSizedArray(BfSizedArrayType* arrayType, BfTokenNode* openToken, const BfSizedArray<BfExpression*>& valueExprs, const BfSizedArray<BfTokenNode*>& commas, BfTokenNode* closeToken, BfTypedValue* receivingValue)
  18932. {
  18933. struct InitValue
  18934. {
  18935. BfTypedValue mValue;
  18936. bool mIsUninitialized;
  18937. bool mIsDefaultInitializer;
  18938. bool mIsDeferred;
  18939. InitValue()
  18940. {
  18941. mIsUninitialized = false;
  18942. mIsDefaultInitializer = false;
  18943. mIsDeferred = false;
  18944. }
  18945. };
  18946. SizedArray<InitValue, 8> values;
  18947. {
  18948. //bool hasFailed = false;
  18949. HashSet<int> failedAt;
  18950. bool isAllConst = true;
  18951. //bool endUninitialzied = false;
  18952. int depth = 0;
  18953. std::function<void(BfSizedArrayType*, BfTokenNode* openToken, const BfSizedArray<BfExpression*>&, const BfSizedArray<BfTokenNode*>&, BfTokenNode*, bool)>
  18954. _GetValues = [&](BfSizedArrayType* checkArrayType, BfTokenNode* openToken, const BfSizedArray<BfExpression*>& valueExprs, const BfSizedArray<BfTokenNode*>& commas, BfTokenNode* closeToken, bool ignore)
  18955. {
  18956. int64 initCountDiff = (int)valueExprs.size() - checkArrayType->mElementCount;
  18957. if ((initCountDiff != 0) && (!valueExprs.IsEmpty()) && (!failedAt.Contains(depth)))
  18958. {
  18959. if (checkArrayType->mElementCount == -1)
  18960. {
  18961. // mModule->Fail("Initializers not supported for unknown-sized arrays", valueExprs[0]);
  18962. // failedAt.Add(depth);
  18963. }
  18964. else if (initCountDiff > 0)
  18965. {
  18966. mModule->Fail(StrFormat("Too many initializers, expected %d fewer", initCountDiff), valueExprs[BF_MAX((int)checkArrayType->mElementCount, 0)]);
  18967. failedAt.Add(depth);
  18968. }
  18969. else
  18970. {
  18971. // If it ends with ", ?) or ",)" then allow unsized
  18972. if (((valueExprs.size() == 0) || (BfNodeDynCast<BfUninitializedExpression>(valueExprs.back()) == NULL)) &&
  18973. ((commas.size() < valueExprs.size()) || (valueExprs.size() == 0)))
  18974. {
  18975. BfAstNode* refNode = closeToken;
  18976. if ((refNode == NULL) && (mModule->mParentNodeEntry != NULL))
  18977. refNode = mModule->mParentNodeEntry->mNode;
  18978. BF_ASSERT(refNode != NULL);
  18979. mModule->Fail(StrFormat("Too few initializer, expected %d more", -initCountDiff), refNode);
  18980. failedAt.Add(depth);
  18981. }
  18982. }
  18983. }
  18984. for (int idx = 0; idx < BF_MAX(checkArrayType->mElementCount, valueExprs.size()); idx++)
  18985. {
  18986. BfTypedValue elementValue;
  18987. bool deferredValue = false;
  18988. BfExpression* expr = NULL;
  18989. if (idx < (int)valueExprs.size())
  18990. {
  18991. expr = valueExprs[idx];
  18992. if (expr == NULL)
  18993. {
  18994. if (idx == 0)
  18995. mModule->FailAfter("Expression expected", openToken);
  18996. else
  18997. mModule->FailAfter("Expression expected", commas[idx - 1]);
  18998. }
  18999. if ((BfNodeDynCastExact<BfUninitializedExpression>(expr) != NULL) && (idx == (int)commas.size()))
  19000. {
  19001. isAllConst = false;
  19002. break;
  19003. }
  19004. if (checkArrayType->mElementType->IsSizedArray())
  19005. {
  19006. if (auto arrayInitExpr = BfNodeDynCast<BfTupleExpression>(expr))
  19007. {
  19008. depth++;
  19009. _GetValues((BfSizedArrayType*)checkArrayType->mElementType, arrayInitExpr->mOpenParen, arrayInitExpr->mValues, arrayInitExpr->mCommas, arrayInitExpr->mCloseParen, ignore);
  19010. depth--;
  19011. continue;
  19012. }
  19013. else if (auto arrayInitExpr = BfNodeDynCast<BfCollectionInitializerExpression>(expr))
  19014. {
  19015. depth++;
  19016. _GetValues((BfSizedArrayType*)checkArrayType->mElementType, arrayInitExpr->mOpenBrace, arrayInitExpr->mValues, arrayInitExpr->mCommas, arrayInitExpr->mCloseBrace, ignore);
  19017. depth--;
  19018. continue;
  19019. }
  19020. else if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(expr))
  19021. {
  19022. depth++;
  19023. SizedArray<BfExpression*, 1> values;
  19024. values.Add(parenExpr->mExpression);
  19025. SizedArray<BfTokenNode*, 1> commas;
  19026. _GetValues((BfSizedArrayType*)checkArrayType->mElementType, parenExpr->mOpenParen, values, commas, parenExpr->mCloseParen, ignore);
  19027. depth--;
  19028. continue;
  19029. }
  19030. }
  19031. if (expr != NULL)
  19032. {
  19033. auto evalFlags = (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags);
  19034. bool tryDefer = false;
  19035. if ((checkArrayType->IsComposite()) &&
  19036. ((expr->IsA<BfInvocationExpression>()) || (expr->IsExact<BfTupleExpression>())))
  19037. {
  19038. // We evaluate with a new scope because this expression may create variables that we don't want to be visible to other
  19039. // non-deferred evaluations (since the value may actually be a FakeVal)
  19040. SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
  19041. elementValue = mModule->CreateValueFromExpression(expr, checkArrayType->mElementType, (BfEvalExprFlags)(evalFlags | BfEvalExprFlags_CreateConditionalScope));
  19042. deferredValue = !prevIgnoreWrites.mPrevVal && elementValue.mValue.IsFake();
  19043. }
  19044. else
  19045. {
  19046. elementValue = mModule->CreateValueFromExpression(expr, checkArrayType->mElementType, evalFlags);
  19047. }
  19048. if (!elementValue)
  19049. elementValue = mModule->GetDefaultTypedValue(checkArrayType->mElementType);
  19050. if ((!elementValue) || (!CheckAllowValue(elementValue, expr)))
  19051. elementValue = mModule->GetDefaultTypedValue(checkArrayType->mElementType);
  19052. // For now, we can't properly create const-valued non-size-aligned composites
  19053. if (!elementValue.mValue.IsConst())
  19054. isAllConst = false;
  19055. if (elementValue.IsAddr())
  19056. isAllConst = false;
  19057. InitValue initValue;
  19058. initValue.mValue = elementValue;
  19059. initValue.mIsDeferred = deferredValue;
  19060. values.push_back(initValue);
  19061. }
  19062. }
  19063. }
  19064. };
  19065. int valueIdx = 0;
  19066. std::function<void(BfTypedValue, BfTokenNode* openToken, const BfSizedArray<BfExpression*>&, const BfSizedArray<BfTokenNode*>&, BfTokenNode*)>
  19067. _CreateMemArray = [&](BfTypedValue arrayValue, BfTokenNode* openToken, const BfSizedArray<BfExpression*>& valueExprs, const BfSizedArray<BfTokenNode*>& commas, BfTokenNode* closeToken)
  19068. {
  19069. BF_ASSERT(arrayValue.mType->IsSizedArray());
  19070. auto checkArrayType = (BfSizedArrayType*)arrayValue.mType;
  19071. int valIdx = 0;
  19072. bool hasUninit = false;
  19073. for (int idx = 0; idx < checkArrayType->mElementCount; idx++)
  19074. {
  19075. BfExpression* expr = NULL;
  19076. BfTypedValue elementValue;
  19077. if (idx >= (int)valueExprs.size())
  19078. break;
  19079. expr = valueExprs[idx];
  19080. if ((BfNodeDynCastExact<BfUninitializedExpression>(expr) != NULL) && (idx == (int)commas.size()))
  19081. {
  19082. hasUninit = true;
  19083. break;
  19084. }
  19085. BfIRValue elemPtrValue = mModule->CreateIndexedValue(checkArrayType->mElementType, arrayValue.mValue, valIdx, true);
  19086. valIdx++;
  19087. if (checkArrayType->mElementType->IsSizedArray())
  19088. {
  19089. if (auto arrayInitExpr = BfNodeDynCast<BfTupleExpression>(expr))
  19090. {
  19091. _CreateMemArray(BfTypedValue(elemPtrValue, checkArrayType->mElementType, true), arrayInitExpr->mOpenParen, arrayInitExpr->mValues, arrayInitExpr->mCommas, arrayInitExpr->mCloseParen);
  19092. continue;
  19093. }
  19094. else if (auto arrayInitExpr = BfNodeDynCast<BfCollectionInitializerExpression>(expr))
  19095. {
  19096. _CreateMemArray(BfTypedValue(elemPtrValue, checkArrayType->mElementType, true), arrayInitExpr->mOpenBrace, arrayInitExpr->mValues, arrayInitExpr->mCommas, arrayInitExpr->mCloseBrace);
  19097. continue;
  19098. }
  19099. else if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(expr))
  19100. {
  19101. depth++;
  19102. SizedArray<BfExpression*, 1> values;
  19103. values.Add(parenExpr->mExpression);
  19104. SizedArray<BfTokenNode*, 1> commas;
  19105. _CreateMemArray(BfTypedValue(elemPtrValue, checkArrayType->mElementType, true), parenExpr->mOpenParen, values, commas, parenExpr->mCloseParen);
  19106. depth--;
  19107. continue;
  19108. }
  19109. }
  19110. if (expr != NULL)
  19111. {
  19112. InitValue initValue = values[valueIdx++];
  19113. elementValue = initValue.mValue;
  19114. if (initValue.mIsDeferred)
  19115. {
  19116. BfTypedValue elemePtrTypedVal = BfTypedValue(elemPtrValue, checkArrayType->mElementType, BfTypedValueKind_Addr);
  19117. BfExprEvaluator exprEvaluator(mModule);
  19118. exprEvaluator.mExpectingType = checkArrayType->mElementType;
  19119. exprEvaluator.mReceivingValue = &elemePtrTypedVal;
  19120. exprEvaluator.Evaluate(expr);
  19121. exprEvaluator.GetResult();
  19122. if (exprEvaluator.mReceivingValue == NULL)
  19123. {
  19124. // We wrote directly to the array in-place, we're done with this element
  19125. continue;
  19126. }
  19127. elementValue = exprEvaluator.mResult;
  19128. elementValue = mModule->Cast(expr, elementValue, checkArrayType->mElementType);
  19129. if (!elementValue)
  19130. {
  19131. mModule->AssertErrorState();
  19132. continue;
  19133. }
  19134. }
  19135. elementValue = mModule->LoadOrAggregateValue(elementValue);
  19136. // Note that elemPtrValue can be a const GEP on a global variable
  19137. mModule->mBfIRBuilder->CreateAlignedStore(elementValue.mValue, elemPtrValue, checkArrayType->mElementType->mAlign);
  19138. }
  19139. }
  19140. int fillCount = (int)(checkArrayType->mElementCount - valIdx);
  19141. if (fillCount > 0)
  19142. {
  19143. BfIRValue elemPtrValue = mModule->CreateIndexedValue(checkArrayType->mElementType, arrayValue.mValue, valIdx, true);
  19144. if (hasUninit)
  19145. {
  19146. if (!mModule->IsOptimized())
  19147. {
  19148. int setSize = std::min(checkArrayType->mElementType->mSize, 128); // Keep it to a reasonable number of bytes to trash
  19149. mModule->mBfIRBuilder->CreateMemSet(elemPtrValue, mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int8, 0xCC),
  19150. mModule->GetConstValue(setSize), checkArrayType->mElementType->mAlign);
  19151. }
  19152. }
  19153. else
  19154. {
  19155. int setSize = (int)((checkArrayType->mElementType->GetStride() * (fillCount - 1)) + checkArrayType->mElementType->mSize);
  19156. if (setSize >= 0)
  19157. {
  19158. mModule->mBfIRBuilder->CreateMemSet(elemPtrValue, mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int8, 0),
  19159. mModule->GetConstValue(setSize), checkArrayType->mElementType->mAlign);
  19160. }
  19161. }
  19162. }
  19163. };
  19164. std::function<BfIRValue(BfTypedValue, BfTokenNode*, const BfSizedArray<BfExpression*>&, const BfSizedArray<BfTokenNode*>&, BfTokenNode*)>
  19165. _CreateConstArray = [&](BfTypedValue arrayValue, BfTokenNode* openToken, const BfSizedArray<BfExpression*>& valueExprs, const BfSizedArray<BfTokenNode*>& commas, BfTokenNode* closeToken)
  19166. {
  19167. SizedArray<BfIRValue, 8> members;
  19168. BF_ASSERT(arrayValue.mType->IsSizedArray());
  19169. auto checkArrayType = (BfSizedArrayType*)arrayValue.mType;
  19170. int valIdx = 0;
  19171. for (int idx = 0; idx < checkArrayType->mElementCount; idx++)
  19172. {
  19173. BfTypedValue elementValue;
  19174. if (idx >= (int)valueExprs.size())
  19175. break;
  19176. auto expr = valueExprs[idx];
  19177. if (expr == NULL)
  19178. continue;
  19179. valIdx++;
  19180. if (checkArrayType->mElementType->IsSizedArray())
  19181. {
  19182. if (auto arrayInitExpr = BfNodeDynCast<BfTupleExpression>(expr))
  19183. {
  19184. members.push_back(_CreateConstArray(checkArrayType->mElementType, arrayInitExpr->mOpenParen, arrayInitExpr->mValues, arrayInitExpr->mCommas, arrayInitExpr->mCloseParen));
  19185. continue;
  19186. }
  19187. else if (auto arrayInitExpr = BfNodeDynCast<BfCollectionInitializerExpression>(expr))
  19188. {
  19189. members.push_back(_CreateConstArray(checkArrayType->mElementType, arrayInitExpr->mOpenBrace, arrayInitExpr->mValues, arrayInitExpr->mCommas, arrayInitExpr->mCloseBrace));
  19190. continue;
  19191. }
  19192. else if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(expr))
  19193. {
  19194. depth++;
  19195. SizedArray<BfExpression*, 1> values;
  19196. values.Add(parenExpr->mExpression);
  19197. SizedArray<BfTokenNode*, 1> commas;
  19198. members.push_back(_CreateConstArray(checkArrayType->mElementType, parenExpr->mOpenParen, values, commas, parenExpr->mCloseParen));
  19199. depth--;
  19200. continue;
  19201. }
  19202. }
  19203. InitValue initValue = values[valueIdx++];
  19204. BF_ASSERT(!initValue.mIsUninitialized);
  19205. elementValue = initValue.mValue;
  19206. members.push_back(elementValue.mValue);
  19207. }
  19208. int fillCount = (int)(checkArrayType->mElementCount - valIdx);
  19209. if (fillCount > 0)
  19210. {
  19211. // We just need to insert one default value, it will be duplicated as needed into the backend
  19212. auto defaultVal = mModule->GetDefaultTypedValue(checkArrayType->GetUnderlyingType());
  19213. BF_ASSERT(defaultVal.mValue.IsConst());
  19214. members.push_back(defaultVal.mValue);
  19215. }
  19216. auto allocArrayType = checkArrayType;
  19217. if (checkArrayType->IsUndefSizedArray())
  19218. allocArrayType = mModule->CreateSizedArrayType(checkArrayType->GetUnderlyingType(), (int)members.size());
  19219. return mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(checkArrayType), members);
  19220. };
  19221. _GetValues(arrayType, openToken, valueExprs, commas, closeToken, false);
  19222. if (!failedAt.IsEmpty())
  19223. {
  19224. mResult = mModule->GetDefaultTypedValue(arrayType, false, BfDefaultValueKind_Addr);
  19225. return;
  19226. }
  19227. if (receivingValue != NULL)
  19228. {
  19229. BF_ASSERT(receivingValue->mType == arrayType);
  19230. BF_ASSERT(receivingValue->IsAddr());
  19231. mResult = *receivingValue;
  19232. _CreateMemArray(mResult, openToken, valueExprs, commas, closeToken);
  19233. }
  19234. else if (isAllConst)
  19235. {
  19236. mResult = BfTypedValue(_CreateConstArray(arrayType, openToken, valueExprs, commas, closeToken), arrayType, BfTypedValueKind_Value);
  19237. }
  19238. else
  19239. {
  19240. if ((mReceivingValue != NULL) && (mReceivingValue->mType == arrayType) && (mReceivingValue->IsAddr()))
  19241. {
  19242. mResult = *mReceivingValue;
  19243. mReceivingValue = NULL;
  19244. }
  19245. else
  19246. {
  19247. auto arrayValue = mModule->CreateAlloca(arrayType);
  19248. mResult = BfTypedValue(arrayValue, arrayType, BfTypedValueKind_TempAddr);
  19249. }
  19250. if (!arrayType->IsValuelessType())
  19251. _CreateMemArray(mResult, openToken, valueExprs, commas, closeToken);
  19252. }
  19253. }
  19254. }
  19255. void BfExprEvaluator::Visit(BfTupleExpression* tupleExpr)
  19256. {
  19257. BfTypeInstance* tupleType = NULL;
  19258. bool hadFullMatch = false;
  19259. if ((mExpectingType != NULL) && (mExpectingType->IsTuple()))
  19260. {
  19261. tupleType = (BfTypeInstance*)mExpectingType;
  19262. hadFullMatch = tupleType->mFieldInstances.size() == tupleExpr->mValues.size();
  19263. }
  19264. struct InitValue
  19265. {
  19266. BfTypedValue mValue;
  19267. bool mIsUninitialized;
  19268. bool mIsDefaultInitializer;
  19269. bool mIsDeferred;
  19270. InitValue()
  19271. {
  19272. mIsUninitialized = false;
  19273. mIsDefaultInitializer = false;
  19274. mIsDeferred = false;
  19275. }
  19276. };
  19277. SizedArray<BfTypedValue, 2> typedValues;
  19278. if ((tupleExpr->mCommas.size() != 0) && (tupleExpr->mCommas.size() >= tupleExpr->mValues.size()))
  19279. {
  19280. // We would normally give this error during syntax parsing, but a TupleExpression can be an array initializer
  19281. mModule->FailAfter("Expression expected", tupleExpr->mCommas.back());
  19282. }
  19283. for (int valueIdx = 0; valueIdx < (int)tupleExpr->mValues.size(); valueIdx++)
  19284. {
  19285. BfExpression* valueExpr = tupleExpr->mValues[valueIdx];
  19286. BfType* fieldType = NULL;
  19287. BfFieldInstance* fieldInstance = NULL;
  19288. if (tupleType != NULL)
  19289. {
  19290. if (valueIdx < (int)tupleType->mFieldInstances.size())
  19291. {
  19292. fieldInstance = (BfFieldInstance*)&tupleType->mFieldInstances[valueIdx];
  19293. fieldType = fieldInstance->GetResolvedType();
  19294. if (fieldType->IsVoid())
  19295. {
  19296. typedValues.push_back(BfTypedValue());
  19297. continue;
  19298. }
  19299. if (fieldType->IsVar())
  19300. {
  19301. hadFullMatch = false;
  19302. fieldType = NULL;
  19303. }
  19304. }
  19305. }
  19306. bool tryDefer = false;
  19307. if (((fieldType == NULL) || (fieldType->IsComposite())) &&
  19308. ((valueExpr->IsA<BfInvocationExpression>()) || (valueExpr->IsExact<BfTupleExpression>())))
  19309. {
  19310. tryDefer = true;
  19311. }
  19312. SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, mModule->mBfIRBuilder->mIgnoreWrites || tryDefer);
  19313. BfTypedValue value = mModule->CreateValueFromExpression(valueExpr, fieldType);
  19314. if (!value)
  19315. {
  19316. if (fieldType != NULL)
  19317. value = mModule->GetDefaultTypedValue(fieldType);
  19318. else
  19319. value = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  19320. }
  19321. if ((fieldInstance != NULL) && (!fieldInstance->GetFieldDef()->IsUnnamedTupleField()) && (valueIdx < (int)tupleExpr->mNames.size()))
  19322. {
  19323. auto checkName = tupleExpr->mNames[valueIdx];
  19324. if (checkName != NULL)
  19325. {
  19326. if (checkName->ToString() != fieldInstance->GetFieldDef()->mName)
  19327. hadFullMatch = false;
  19328. }
  19329. }
  19330. value = mModule->LoadValue(value);
  19331. typedValues.push_back(value);
  19332. }
  19333. if (!hadFullMatch)
  19334. {
  19335. BfTypeVector fieldTypes;
  19336. Array<String> fieldNames;
  19337. HashSet<String> fieldNameSet;
  19338. for (auto typedVal : typedValues)
  19339. {
  19340. auto type = typedVal.mType;
  19341. if (type != NULL)
  19342. fieldTypes.push_back(type);
  19343. else
  19344. fieldTypes.push_back(mModule->mContext->mBfObjectType);
  19345. }
  19346. for (BfTupleNameNode* requestedName : tupleExpr->mNames)
  19347. {
  19348. if (requestedName == NULL)
  19349. fieldNames.push_back("");
  19350. else
  19351. {
  19352. auto fieldName = requestedName->mNameNode->ToString();
  19353. if (!fieldNameSet.TryAdd(fieldName, NULL))
  19354. {
  19355. mModule->Fail(StrFormat("A field named '%s' has already been declared", fieldName.c_str()), requestedName->mNameNode);
  19356. }
  19357. fieldNames.push_back(fieldName);
  19358. }
  19359. }
  19360. tupleType = mModule->CreateTupleType(fieldTypes, fieldNames);
  19361. }
  19362. mModule->mBfIRBuilder->PopulateType(tupleType);
  19363. BfIRValue curTupleValue;
  19364. if ((mReceivingValue != NULL) && (mReceivingValue->mType == tupleType) && (mReceivingValue->IsAddr()))
  19365. {
  19366. mResult = *mReceivingValue;
  19367. mReceivingValue = NULL;
  19368. curTupleValue = mResult.mValue;
  19369. }
  19370. else
  19371. {
  19372. int valueIdx = -1;
  19373. bool isExactConst = true;
  19374. for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
  19375. {
  19376. BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx];
  19377. if (fieldInstance->mDataIdx < 0)
  19378. continue;
  19379. ++valueIdx;
  19380. auto typedValue = typedValues[valueIdx];
  19381. if (typedValue.mType != fieldInstance->mResolvedType)
  19382. {
  19383. isExactConst = false;
  19384. break;
  19385. }
  19386. if (!typedValue.mValue.IsConst())
  19387. {
  19388. isExactConst = false;
  19389. break;
  19390. }
  19391. }
  19392. if (isExactConst)
  19393. {
  19394. mModule->PopulateType(tupleType);
  19395. if (tupleType->IsDataIncomplete())
  19396. return;
  19397. Array<BfIRValue> irValues;
  19398. irValues.Resize(typedValues.mSize + 1);
  19399. irValues[0] = mModule->mBfIRBuilder->CreateConstAggZero(mModule->mBfIRBuilder->MapType(tupleType->mBaseType));
  19400. for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
  19401. {
  19402. BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx];
  19403. if (fieldInstance->mDataIdx < 0)
  19404. continue;
  19405. while (fieldInstance->mDataIdx >= irValues.size())
  19406. irValues.Add(BfIRValue());
  19407. irValues[fieldInstance->mDataIdx] = typedValues[fieldIdx].mValue;
  19408. }
  19409. for (auto& val : irValues)
  19410. {
  19411. if (!val)
  19412. val = mModule->mBfIRBuilder->CreateConstArrayZero(0);
  19413. }
  19414. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(tupleType), irValues), tupleType);
  19415. return;
  19416. }
  19417. curTupleValue = mModule->CreateAlloca(tupleType);
  19418. mResultIsTempComposite = true;
  19419. mResult = BfTypedValue(curTupleValue, tupleType, BfTypedValueKind_TempAddr);
  19420. }
  19421. int valueIdx = -1;
  19422. for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
  19423. {
  19424. BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx];
  19425. ++valueIdx;
  19426. if (fieldInstance->mResolvedType->IsValuelessType())
  19427. continue;
  19428. auto typedVal = typedValues[valueIdx];
  19429. if (!typedVal)
  19430. {
  19431. mModule->AssertErrorState();
  19432. continue;
  19433. }
  19434. if (fieldInstance->mDataIdx >= 0)
  19435. {
  19436. auto memberVal = mModule->mBfIRBuilder->CreateInBoundsGEP(curTupleValue, 0, fieldInstance->mDataIdx);
  19437. if ((!mModule->mBfIRBuilder->mIgnoreWrites) && (typedVal.mValue.IsFake()))
  19438. {
  19439. // Value was deferred. Allow us to try to init in place
  19440. BfExpression* valueExpr = tupleExpr->mValues[valueIdx];
  19441. BfTypedValue memberPtrTypedVal = BfTypedValue(memberVal, fieldInstance->mResolvedType, BfTypedValueKind_Addr);
  19442. BfExprEvaluator exprEvaluator(mModule);
  19443. exprEvaluator.mExpectingType = fieldInstance->mResolvedType;
  19444. exprEvaluator.mReceivingValue = &memberPtrTypedVal;
  19445. exprEvaluator.Evaluate(valueExpr);
  19446. exprEvaluator.GetResult();
  19447. if (exprEvaluator.mReceivingValue == NULL)
  19448. {
  19449. // We wrote directly to the array in-place, we're done with this element
  19450. continue;
  19451. }
  19452. typedVal = exprEvaluator.mResult;
  19453. typedVal = mModule->Cast(valueExpr, typedVal, fieldInstance->mResolvedType);
  19454. if (!typedVal)
  19455. {
  19456. mModule->AssertErrorState();
  19457. continue;
  19458. }
  19459. typedVal = mModule->LoadValue(typedVal);
  19460. }
  19461. if (typedVal.mType->IsVar())
  19462. {
  19463. // Do nothing
  19464. }
  19465. else if (typedVal.IsSplat())
  19466. mModule->AggregateSplatIntoAddr(typedVal, memberVal);
  19467. else
  19468. mModule->mBfIRBuilder->CreateAlignedStore(typedVal.mValue, memberVal, typedVal.mType->mAlign);
  19469. }
  19470. }
  19471. }
  19472. BfTypedValue BfExprEvaluator::SetupNullConditional(BfTypedValue thisValue, BfTokenNode* dotToken)
  19473. {
  19474. bool isStaticLookup = (!thisValue) ||
  19475. ((!thisValue.mType->IsValuelessType()) && (!thisValue.mValue));
  19476. if (isStaticLookup)
  19477. {
  19478. mModule->Fail("Null conditional reference not valid for static field references", dotToken);
  19479. return thisValue;
  19480. }
  19481. auto opResult = PerformUnaryOperation_TryOperator(thisValue, NULL, BfUnaryOp_NullConditional, dotToken, BfUnaryOpFlag_None);
  19482. if (opResult)
  19483. thisValue = opResult;
  19484. if (thisValue.mType->IsGenericParam())
  19485. {
  19486. bool isValid = false;
  19487. auto genericParams = mModule->GetGenericParamInstance((BfGenericParamType*)thisValue.mType);
  19488. if (genericParams->mTypeConstraint != NULL)
  19489. {
  19490. if ((genericParams->mTypeConstraint->IsNullable()) ||
  19491. (genericParams->mTypeConstraint->IsPointer()) ||
  19492. (genericParams->mTypeConstraint->IsObjectOrInterface()))
  19493. isValid = true;
  19494. }
  19495. if ((genericParams->mGenericParamFlags & (BfGenericParamFlag_Var | BfGenericParamFlag_StructPtr | BfGenericParamFlag_Class)) != 0)
  19496. isValid = true;
  19497. if (isValid)
  19498. return thisValue;
  19499. }
  19500. if ((thisValue.mType->IsNullable()) || (thisValue.mType->IsVar()))
  19501. {
  19502. // Success
  19503. }
  19504. else if ((thisValue.mType->IsPointer()) || (thisValue.mType->IsObjectOrInterface()) || (thisValue.mType->IsFunction()))
  19505. {
  19506. // Also good
  19507. }
  19508. else
  19509. {
  19510. bool canBeNull = false;
  19511. if (thisValue.mType->IsGenericParam())
  19512. canBeNull = true;
  19513. if (!canBeNull)
  19514. mModule->Warn(0, StrFormat("Null conditional reference is unnecessary since value type '%s' can never be null", mModule->TypeToString(thisValue.mType).c_str()), dotToken);
  19515. return thisValue;
  19516. }
  19517. thisValue = mModule->LoadValue(thisValue);
  19518. if (thisValue.mType->IsVar())
  19519. return thisValue;
  19520. BfPendingNullConditional* pendingNullCond = mModule->mCurMethodState->mPendingNullConditional;
  19521. if (pendingNullCond == NULL)
  19522. {
  19523. pendingNullCond = new BfPendingNullConditional();
  19524. mModule->mCurMethodState->mPendingNullConditional = pendingNullCond;
  19525. }
  19526. if (!pendingNullCond->mPrevBB)
  19527. pendingNullCond->mPrevBB = mModule->mBfIRBuilder->GetInsertBlock();
  19528. if (!pendingNullCond->mDoneBB)
  19529. pendingNullCond->mDoneBB = mModule->mBfIRBuilder->CreateBlock("nullCond.done");
  19530. // We will in the br to checkBB later
  19531. if (!pendingNullCond->mCheckBB)
  19532. {
  19533. pendingNullCond->mCheckBB = mModule->mBfIRBuilder->CreateBlock("nullCond.check");
  19534. mModule->AddBasicBlock(pendingNullCond->mCheckBB);
  19535. }
  19536. BfIRValue isNotNull;
  19537. if (thisValue.mType->IsNullable())
  19538. {
  19539. BfTypeInstance* nullableType = (BfTypeInstance*)thisValue.mType->ToTypeInstance();
  19540. auto elementType = nullableType->GetUnderlyingType();
  19541. if (elementType->IsValuelessType())
  19542. {
  19543. thisValue = mModule->MakeAddressable(thisValue);
  19544. BfIRValue hasValuePtr = mModule->mBfIRBuilder->CreateInBoundsGEP(thisValue.mValue, 0, 1); // mHasValue
  19545. isNotNull = mModule->mBfIRBuilder->CreateAlignedLoad(hasValuePtr, 1);
  19546. thisValue = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), elementType, true);
  19547. }
  19548. else
  19549. {
  19550. thisValue = mModule->MakeAddressable(thisValue);
  19551. BfIRValue hasValuePtr = mModule->mBfIRBuilder->CreateInBoundsGEP(thisValue.mValue, 0, 2); // mHasValue
  19552. isNotNull = mModule->mBfIRBuilder->CreateAlignedLoad(hasValuePtr, 1);
  19553. BfIRValue valuePtr = mModule->mBfIRBuilder->CreateInBoundsGEP(thisValue.mValue, 0, 1); // mValue
  19554. thisValue = BfTypedValue(valuePtr, elementType, true);
  19555. }
  19556. }
  19557. else if (thisValue.mType->IsFunction())
  19558. {
  19559. isNotNull = mModule->mBfIRBuilder->CreateCmpNE(thisValue.mValue, mModule->GetDefaultValue(thisValue.mType));
  19560. }
  19561. else
  19562. isNotNull = mModule->mBfIRBuilder->CreateIsNotNull(thisValue.mValue);
  19563. BfIRBlock notNullBB = mModule->mBfIRBuilder->CreateBlock("nullCond.notNull");
  19564. pendingNullCond->mNotNullBBs.Add(notNullBB);
  19565. mModule->mBfIRBuilder->CreateCondBr(isNotNull, notNullBB, pendingNullCond->mDoneBB);
  19566. mModule->AddBasicBlock(notNullBB);
  19567. return thisValue;
  19568. }
  19569. void BfExprEvaluator::CheckDotToken(BfTokenNode* tokenNode)
  19570. {
  19571. if ((tokenNode != NULL) && (tokenNode->mToken == BfToken_DotDot))
  19572. mModule->Fail("Unexpected cascade operation. Chaining can only be used for method invocations", tokenNode);
  19573. }
  19574. void BfExprEvaluator::DoMemberReference(BfMemberReferenceExpression* memberRefExpr, BfTypedValue* outCascadeValue)
  19575. {
  19576. CheckDotToken(memberRefExpr->mDotToken);
  19577. BfAttributeState attributeState;
  19578. attributeState.mTarget = (BfAttributeTargets)(BfAttributeTargets_MemberAccess);
  19579. String findName;
  19580. BfAstNode* nameRefNode = memberRefExpr->mMemberName;
  19581. if (auto attrIdentifierExpr = BfNodeDynCast<BfAttributedIdentifierNode>(memberRefExpr->mMemberName))
  19582. {
  19583. nameRefNode = attrIdentifierExpr->mIdentifier;
  19584. // Don't validate
  19585. attributeState.mCustomAttributes = mModule->GetCustomAttributes(attrIdentifierExpr->mAttributes, BfAttributeTargets_SkipValidate);
  19586. if (nameRefNode != NULL)
  19587. findName = attrIdentifierExpr->mIdentifier->ToString();
  19588. }
  19589. else if (memberRefExpr->mMemberName != NULL)
  19590. findName = memberRefExpr->mMemberName->ToString();
  19591. else if (memberRefExpr->mDotToken != NULL)
  19592. mModule->FailAfter("Member name expected", memberRefExpr->mDotToken);
  19593. defer
  19594. (
  19595. if (attributeState.mCustomAttributes != NULL)
  19596. {
  19597. if (mPropDef != NULL)
  19598. attributeState.mTarget = (BfAttributeTargets)(attributeState.mTarget | BfAttributeTargets_Invocation);
  19599. mModule->ValidateCustomAttributes(attributeState.mCustomAttributes, attributeState.mTarget);
  19600. }
  19601. );
  19602. SetAndRestoreValue<BfAttributeState*> prevAttributeState(mModule->mAttributeState, &attributeState);
  19603. BfTypeInstance* expectingTypeInst = NULL;
  19604. if (mExpectingType != NULL)
  19605. {
  19606. expectingTypeInst = mExpectingType->ToTypeInstance();
  19607. if (mExpectingType->IsPointer())
  19608. expectingTypeInst = mExpectingType->GetUnderlyingType()->ToTypeInstance();
  19609. else if (mExpectingType->IsNullable())
  19610. expectingTypeInst = mExpectingType->GetUnderlyingType()->ToTypeInstance();
  19611. else if (mExpectingType->IsConstExprValue())
  19612. expectingTypeInst = mExpectingType->GetUnderlyingType()->ToTypeInstance();
  19613. else if (mExpectingType->IsGenericParam())
  19614. {
  19615. auto genericParam = mModule->GetGenericParamInstance((BfGenericParamType*)mExpectingType);
  19616. if (genericParam->mTypeConstraint != NULL)
  19617. expectingTypeInst = genericParam->mTypeConstraint->ToTypeInstance();
  19618. }
  19619. }
  19620. BfAutoComplete* autoComplete = GetAutoComplete();
  19621. if (autoComplete != NULL)
  19622. {
  19623. SetAndRestoreValue<bool> prevFriendSet(autoComplete->mHasFriendSet, (attributeState.mCustomAttributes != NULL) && (attributeState.mCustomAttributes->Contains(mModule->mCompiler->mFriendAttributeTypeDef)));
  19624. if (memberRefExpr->mTarget == NULL)
  19625. {
  19626. String filter;
  19627. if ((mExpectingType != NULL) &&
  19628. (autoComplete->InitAutocomplete(memberRefExpr->mDotToken, memberRefExpr->mMemberName, filter)))
  19629. {
  19630. if (expectingTypeInst != NULL)
  19631. {
  19632. bool allowPrivate = expectingTypeInst == mModule->mCurTypeInstance;
  19633. if (expectingTypeInst->IsEnum())
  19634. autoComplete->AddEnumTypeMembers(expectingTypeInst, filter, false, allowPrivate);
  19635. autoComplete->AddSelfResultTypeMembers(expectingTypeInst, expectingTypeInst, filter, allowPrivate);
  19636. }
  19637. }
  19638. else if ((expectingTypeInst != NULL) && (autoComplete->IsAutocompleteNode(memberRefExpr->mDotToken)) && (autoComplete->mIsGetDefinition))
  19639. {
  19640. if ((autoComplete->mDefType == NULL) &&
  19641. (autoComplete->mDefMethod == NULL) && (autoComplete->mDefField == NULL) &&
  19642. (autoComplete->mDefProp == NULL) && (expectingTypeInst->mTypeDef->mTypeDeclaration != NULL))
  19643. {
  19644. autoComplete->mDefType = expectingTypeInst->mTypeDef;
  19645. autoComplete->SetDefinitionLocation(expectingTypeInst->mTypeDef->mTypeDeclaration->mNameNode);
  19646. }
  19647. }
  19648. }
  19649. else
  19650. {
  19651. autoComplete->CheckMemberReference(memberRefExpr->mTarget, memberRefExpr->mDotToken, memberRefExpr->mMemberName, false, mExpectingType);
  19652. if (auto objCreateExpr = BfNodeDynCast<BfObjectCreateExpression>(memberRefExpr->mTarget))
  19653. {
  19654. // This handles a weird case where we have "obj a = new\nWhatever().Thing = 123;".
  19655. // That gets parsed as "Whatever()" being the type we want to create, and then referencing
  19656. // the "Thing" member of that new object.
  19657. //if (objCreateExpr->mArraySizeSpecifier == NULL)
  19658. CheckObjectCreateTypeRef(mExpectingType, objCreateExpr->mNewNode);
  19659. }
  19660. }
  19661. }
  19662. if (memberRefExpr->mTarget == NULL)
  19663. {
  19664. if (mExpectingType == NULL)
  19665. {
  19666. if (mModule->PreFail())
  19667. mModule->Fail("Unqualified dot syntax can only be used when the result type can be inferred", nameRefNode);
  19668. return;
  19669. }
  19670. if (mExpectingType->IsVar())
  19671. {
  19672. mResult = mModule->GetDefaultTypedValue(mExpectingType);
  19673. return;
  19674. }
  19675. if (mExpectingType->IsSizedArray())
  19676. {
  19677. expectingTypeInst = mModule->GetWrappedStructType(mExpectingType);
  19678. }
  19679. if (expectingTypeInst == NULL)
  19680. {
  19681. if (mModule->PreFail())
  19682. mModule->Fail(StrFormat("Unqualified dot syntax cannot be used with type '%s'", mModule->TypeToString(mExpectingType).c_str()), nameRefNode);
  19683. return;
  19684. }
  19685. BfTypedValue expectingVal(expectingTypeInst);
  19686. mResult = LookupField(memberRefExpr->mMemberName, expectingVal, findName);
  19687. if ((mResult) || (mPropDef != NULL))
  19688. return;
  19689. }
  19690. bool isNullCondLookup = (memberRefExpr->mDotToken != NULL) && (memberRefExpr->mDotToken->GetToken() == BfToken_QuestionDot);
  19691. bool isCascade = ((memberRefExpr->mDotToken != NULL) && (memberRefExpr->mDotToken->GetToken() == BfToken_DotDot));
  19692. bool isArrowLookup = ((memberRefExpr->mDotToken != NULL) && (memberRefExpr->mDotToken->GetToken() == BfToken_Arrow));
  19693. BfIdentifierNode* nameLeft = BfNodeDynCast<BfIdentifierNode>(memberRefExpr->mTarget);
  19694. BfIdentifierNode* nameRight = BfIdentifierCast(memberRefExpr->mMemberName);
  19695. if ((nameLeft != NULL) && (nameRight != NULL) && (!isNullCondLookup) && (!isCascade) && (!isArrowLookup))
  19696. {
  19697. bool hadError = false;
  19698. LookupQualifiedName(memberRefExpr, nameLeft, nameRight, true, &hadError);
  19699. if ((mResult) || (mPropDef != NULL))
  19700. return;
  19701. if (hadError)
  19702. return;
  19703. LookupQualifiedStaticField(memberRefExpr, nameLeft, nameRight, false);
  19704. return;
  19705. }
  19706. BfTypedValue thisValue;
  19707. if (auto exprTarget = BfNodeDynCast<BfExpression>(memberRefExpr->mTarget))
  19708. {
  19709. if (auto typeOfExpr = BfNodeDynCast<BfTypeOfExpression>(memberRefExpr->mTarget))
  19710. {
  19711. if (auto nameIdentifer = BfNodeDynCast<BfIdentifierNode>(memberRefExpr->mMemberName))
  19712. {
  19713. if (LookupTypeProp(typeOfExpr, nameIdentifer))
  19714. return;
  19715. }
  19716. }
  19717. //Hm, not using VisitChild broke our ability to write to a field for a not-initialized local struct
  19718. VisitChild(memberRefExpr->mTarget);
  19719. GetResult();
  19720. thisValue = mResult;
  19721. if (!thisValue)
  19722. {
  19723. if (auto targetIdentifier = BfNodeDynCast<BfIdentifierNode>(exprTarget))
  19724. {
  19725. thisValue = BfTypedValue(mModule->ResolveTypeRef(targetIdentifier, NULL, BfPopulateType_Declaration));
  19726. }
  19727. }
  19728. if (!thisValue.HasType())
  19729. return;
  19730. //thisValue = mResult;
  19731. }
  19732. else if (auto typeRef = BfNodeDynCast<BfTypeReference>(memberRefExpr->mTarget))
  19733. {
  19734. // Look up static field
  19735. thisValue = BfTypedValue(ResolveTypeRef(typeRef));
  19736. }
  19737. if (nameRefNode == NULL)
  19738. {
  19739. mModule->AssertErrorState();
  19740. return;
  19741. }
  19742. if (isNullCondLookup)
  19743. thisValue = SetupNullConditional(thisValue, memberRefExpr->mDotToken);
  19744. if ((isArrowLookup) && (thisValue))
  19745. thisValue = TryArrowLookup(thisValue, memberRefExpr->mDotToken);
  19746. auto nameNode = memberRefExpr->mMemberName;
  19747. if ((thisValue.mType != NULL) && (!thisValue.mType->IsTypeInstance()) && (!thisValue.mType->IsGenericParam()))
  19748. {
  19749. if (thisValue.mType->IsSizedArray())
  19750. {
  19751. if (thisValue.mType->IsValuelessType())
  19752. {
  19753. thisValue.mType = mModule->GetWrappedStructType(thisValue.mType);
  19754. thisValue.mValue = mModule->mBfIRBuilder->GetFakeVal();
  19755. }
  19756. else
  19757. {
  19758. thisValue = mModule->MakeAddressable(thisValue);
  19759. thisValue.mType = mModule->GetWrappedStructType(thisValue.mType);
  19760. thisValue.mValue = mModule->mBfIRBuilder->CreateBitCast(thisValue.mValue, mModule->mBfIRBuilder->MapTypeInstPtr(thisValue.mType->ToTypeInstance()));
  19761. }
  19762. }
  19763. else if (thisValue.mType->IsPointer())
  19764. {
  19765. // Leave alone
  19766. }
  19767. else if (thisValue.mType->IsWrappableType())
  19768. {
  19769. thisValue.mType = mModule->GetWrappedStructType(thisValue.mType);
  19770. }
  19771. }
  19772. BfTypedValue lookupVal = thisValue;
  19773. if (thisValue.mType != NULL)
  19774. {
  19775. auto lookupType = BindGenericType(nameNode, thisValue.mType);
  19776. if ((lookupType->IsGenericParam()) && (!thisValue.mType->IsGenericParam()))
  19777. {
  19778. bool prevUseMixinGenerics = false;
  19779. if (mModule->mCurMethodState->mMixinState != NULL)
  19780. {
  19781. prevUseMixinGenerics = mModule->mCurMethodState->mMixinState->mUseMixinGenerics;
  19782. mModule->mCurMethodState->mMixinState->mUseMixinGenerics = true;
  19783. }
  19784. // Try to lookup from generic binding
  19785. mResult = LookupField(nameRight, BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), lookupType), findName, BfLookupFieldFlag_BindOnly);
  19786. if (mModule->mCurMethodState->mMixinState != NULL)
  19787. mModule->mCurMethodState->mMixinState->mUseMixinGenerics = prevUseMixinGenerics;
  19788. if (mPropDef != NULL)
  19789. {
  19790. mOrigPropTarget = lookupVal;
  19791. return;
  19792. }
  19793. }
  19794. }
  19795. mResult = LookupField(nameRefNode, lookupVal, findName);
  19796. if ((!mResult) && (mPropDef == NULL))
  19797. {
  19798. if (thisValue.mType != NULL)
  19799. {
  19800. BfTypeInstance* typeInst = thisValue.mType->ToTypeInstance();
  19801. auto compiler = mModule->mCompiler;
  19802. if ((typeInst != NULL) && (compiler->IsAutocomplete()) && (compiler->mResolvePassData->mAutoComplete->CheckFixit(memberRefExpr->mMemberName)))
  19803. {
  19804. FixitAddMember(typeInst, mExpectingType, findName, !thisValue.mValue);
  19805. }
  19806. }
  19807. if ((!thisValue.mValue) && (thisValue.mType != NULL))
  19808. {
  19809. if (auto targetIdentifier = BfNodeDynCast<BfIdentifierNode>(memberRefExpr->mMemberName))
  19810. {
  19811. if ((mBfEvalExprFlags & BfEvalExprFlags_NameOf) != 0)
  19812. {
  19813. auto typeInst = thisValue.mType->ToTypeInstance();
  19814. if ((typeInst != NULL) && (CheckForMethodName(nameRight, typeInst, findName)))
  19815. return;
  19816. }
  19817. mResult.mType = mModule->ResolveInnerType(thisValue.mType, targetIdentifier, BfPopulateType_Declaration);
  19818. }
  19819. }
  19820. if ((memberRefExpr->mTarget == NULL) && (expectingTypeInst != NULL) && (autoComplete != NULL))
  19821. {
  19822. if (autoComplete->CheckFixit(memberRefExpr->mMemberName))
  19823. {
  19824. autoComplete->FixitAddCase(expectingTypeInst, memberRefExpr->mMemberName->ToString(), BfTypeVector());
  19825. }
  19826. }
  19827. if (mResult.mType == NULL)
  19828. {
  19829. if (mModule->PreFail())
  19830. {
  19831. if ((thisValue) && (thisValue.mType->IsPointer()) && (thisValue.mType->GetUnderlyingType()->IsObjectOrInterface()))
  19832. mModule->Fail(StrFormat("Members cannot be referenced on type '%s' because the type is a pointer to a reference type (ie: a double-reference).",
  19833. mModule->TypeToString(thisValue.mType).c_str()), nameRefNode);
  19834. else if (thisValue)
  19835. mModule->Fail(StrFormat("Unable to find member '%s' in '%s'", findName.c_str(), mModule->TypeToString(thisValue.mType).c_str()), nameRefNode);
  19836. else
  19837. mModule->Fail("Unable to find member", nameRefNode);
  19838. }
  19839. }
  19840. }
  19841. if ((isNullCondLookup) && (mPropDef == NULL))
  19842. mResult = GetResult();
  19843. if (isCascade)
  19844. {
  19845. if (outCascadeValue != NULL)
  19846. *outCascadeValue = thisValue;
  19847. else if (mModule->PreFail())
  19848. mModule->Fail("Unexpected cascade operation. Chaining can only be used for method invocations", memberRefExpr->mDotToken);
  19849. }
  19850. }
  19851. void BfExprEvaluator::Visit(BfMemberReferenceExpression* memberRefExpr)
  19852. {
  19853. DoMemberReference(memberRefExpr, NULL);
  19854. }
  19855. void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr)
  19856. {
  19857. HandleIndexerExpression(indexerExpr, BfTypedValue());
  19858. }
  19859. void BfExprEvaluator::HandleIndexerExpression(BfIndexerExpression* indexerExpr, BfTypedValue target)
  19860. {
  19861. BfAstNode* refNode = indexerExpr->mOpenBracket;
  19862. if (refNode == NULL)
  19863. refNode = indexerExpr->mTarget;
  19864. bool wantStatic = false;
  19865. // Try first as a non-static indexer, then as a static indexer
  19866. if (!target)
  19867. {
  19868. for (int pass = 0; pass < 2; pass++)
  19869. {
  19870. ///
  19871. {
  19872. SetAndRestoreValue<BfEvalExprFlags> prevFlags(mBfEvalExprFlags, (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_NoLookupError | BfEvalExprFlags_AllowBase), pass == 0);
  19873. VisitChild(indexerExpr->mTarget);
  19874. }
  19875. ResolveGenericType();
  19876. target = GetResult(true);
  19877. if (target)
  19878. break;
  19879. if (pass == 0)
  19880. {
  19881. SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, (mModule->mIgnoreErrors) || (pass == 0));
  19882. auto staticType = mModule->ResolveTypeRef(indexerExpr->mTarget, {});
  19883. if (staticType != NULL)
  19884. {
  19885. wantStatic = true;
  19886. target.mType = staticType;
  19887. break;
  19888. }
  19889. }
  19890. }
  19891. }
  19892. if (!target.HasType())
  19893. return;
  19894. if (target.mType->IsGenericParam())
  19895. {
  19896. auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)target.mType);
  19897. if (genericParamInstance->mTypeConstraint != NULL)
  19898. target.mType = genericParamInstance->mTypeConstraint;
  19899. }
  19900. BfCheckedKind checkedKind = BfCheckedKind_NotSet;
  19901. bool isInlined = false;
  19902. if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL))
  19903. {
  19904. if (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mInlineAttributeTypeDef))
  19905. {
  19906. isInlined = true;
  19907. mModule->mAttributeState->mUsed = true;
  19908. }
  19909. if (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mCheckedAttributeTypeDef))
  19910. {
  19911. checkedKind = BfCheckedKind_Checked;
  19912. mModule->mAttributeState->mUsed = true;
  19913. }
  19914. if (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mUncheckedAttributeTypeDef))
  19915. {
  19916. checkedKind = BfCheckedKind_Unchecked;
  19917. mModule->mAttributeState->mUsed = true;
  19918. }
  19919. }
  19920. // Avoid attempting to apply the current attributes to the indexer arguments
  19921. SetAndRestoreValue<BfAttributeState*> prevAttributeState(mModule->mAttributeState, NULL);
  19922. bool isNullCondLookup = (indexerExpr->mOpenBracket != NULL) && (indexerExpr->mOpenBracket->GetToken() == BfToken_QuestionLBracket);
  19923. if (isNullCondLookup)
  19924. target = SetupNullConditional(target, indexerExpr->mOpenBracket);
  19925. if (target.mType->IsVar())
  19926. {
  19927. mResult = BfTypedValue(mModule->GetDefaultValue(target.mType), target.mType, true);
  19928. return;
  19929. }
  19930. if ((target.mType->IsTypeInstance()) || (target.mType->IsGenericParam()))
  19931. {
  19932. BfGenericParamInstance* genericParamInstance = NULL;
  19933. if (target.mType->IsGenericParam())
  19934. genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)target.mType);
  19935. mIndexerValues.clear();
  19936. SizedArray<BfExpression*, 2> argExprs;
  19937. BfSizedArray<BfExpression*> sizedArgExprs(indexerExpr->mArguments);
  19938. BfResolvedArgs argValues(&sizedArgExprs);
  19939. ResolveArgValues(argValues, (BfResolveArgsFlags)(BfResolveArgsFlag_DeferParamEval | BfResolveArgsFlag_FromIndexer));
  19940. mIndexerValues = argValues.mResolvedArgs;
  19941. BfMethodMatcher methodMatcher(indexerExpr->mTarget, mModule, "[]", mIndexerValues, BfMethodGenericArguments());
  19942. methodMatcher.mCheckedKind = checkedKind;
  19943. BfMethodDef* methodDef = NULL;
  19944. auto startCheckTypeInst = target.mType->ToTypeInstance();
  19945. auto lookupType = target.mType;
  19946. if (lookupType != NULL)
  19947. {
  19948. lookupType = BindGenericType(refNode, lookupType);
  19949. if (lookupType->IsGenericParam())
  19950. startCheckTypeInst = NULL;
  19951. }
  19952. for (int pass = 0; pass < 2; pass++)
  19953. {
  19954. bool isFailurePass = pass == 1;
  19955. BfPropertyDef* foundProp = NULL;
  19956. BfTypeInstance* foundPropTypeInst = NULL;
  19957. BfBaseClassWalker baseClassWalker(lookupType, NULL, mModule, true);
  19958. while (true)
  19959. {
  19960. auto checkEntry = baseClassWalker.Next();
  19961. auto curCheckType = checkEntry.mTypeInstance;
  19962. if (curCheckType == NULL)
  19963. break;
  19964. BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None;
  19965. curCheckType->mTypeDef->PopulateMemberSets();
  19966. BfMemberSetEntry* entry;
  19967. BfPropertyDef* matchedProp = NULL;
  19968. BfPropertyDef* nextProp = NULL;
  19969. if (curCheckType->mTypeDef->mPropertySet.TryGetWith(String("[]"), &entry))
  19970. nextProp = (BfPropertyDef*)entry->mMemberDef;
  19971. while (nextProp != NULL)
  19972. {
  19973. auto prop = nextProp;
  19974. nextProp = nextProp->mNextWithSameName;
  19975. //TODO: Match against setMethod (minus last param) if we have no 'get' method
  19976. for (auto checkMethod : prop->mMethods)
  19977. {
  19978. if (checkMethod->mMethodType != BfMethodType_PropertyGetter)
  19979. continue;
  19980. if (checkMethod->mIsStatic != wantStatic)
  19981. continue;
  19982. if (checkMethod->mExplicitInterface != NULL)
  19983. continue;
  19984. auto autoComplete = GetAutoComplete();
  19985. bool wasCapturingMethodMatchInfo = false;
  19986. if (autoComplete != NULL)
  19987. {
  19988. // Set to false to make sure we don't capture method match info from 'params' array creation
  19989. wasCapturingMethodMatchInfo = autoComplete->mIsCapturingMethodMatchInfo;
  19990. autoComplete->mIsCapturingMethodMatchInfo = false;
  19991. }
  19992. defer
  19993. (
  19994. if (autoComplete != NULL)
  19995. autoComplete->mIsCapturingMethodMatchInfo = wasCapturingMethodMatchInfo;
  19996. );
  19997. if ((!isFailurePass) && (!methodMatcher.WantsCheckMethod(protectionCheckFlags, startCheckTypeInst, curCheckType, checkMethod)))
  19998. continue;
  19999. if (!methodMatcher.IsMemberAccessible(curCheckType, checkMethod->mDeclaringType))
  20000. continue;
  20001. methodMatcher.mCheckedKind = checkedKind;
  20002. methodMatcher.mTarget = target;
  20003. bool hadMatch = methodMatcher.CheckMethod(startCheckTypeInst, curCheckType, checkMethod, false);
  20004. if ((hadMatch) || (methodMatcher.mBackupMethodDef == checkMethod))
  20005. {
  20006. foundPropTypeInst = curCheckType;
  20007. foundProp = prop;
  20008. }
  20009. }
  20010. }
  20011. curCheckType = curCheckType->mBaseType;
  20012. }
  20013. if (foundProp != NULL)
  20014. {
  20015. mPropSrc = indexerExpr->mOpenBracket;
  20016. mPropDef = foundProp;
  20017. if (foundProp->mIsStatic)
  20018. {
  20019. mPropTarget = BfTypedValue(foundPropTypeInst);
  20020. }
  20021. else
  20022. {
  20023. if (target.mType != foundPropTypeInst)
  20024. mPropTarget = mModule->Cast(indexerExpr->mTarget, target, foundPropTypeInst);
  20025. else
  20026. mPropTarget = target;
  20027. }
  20028. mOrigPropTarget = mPropTarget;
  20029. if (isInlined)
  20030. mPropGetMethodFlags = (BfGetMethodInstanceFlags)(mPropGetMethodFlags | BfGetMethodInstanceFlag_ForceInline);
  20031. mPropCheckedKind = checkedKind;
  20032. if ((target.IsBase()) && (mPropDef->IsVirtual()))
  20033. mPropDefBypassVirtual = true;
  20034. return;
  20035. }
  20036. }
  20037. mModule->Fail("Unable to find indexer property", indexerExpr->mTarget);
  20038. return;
  20039. }
  20040. bool wantsChecks = checkedKind == BfCheckedKind_Checked;
  20041. if (checkedKind == BfCheckedKind_NotSet)
  20042. wantsChecks = mModule->GetDefaultCheckedKind() == BfCheckedKind_Checked;
  20043. if (target.mType->IsVar())
  20044. {
  20045. mResult = target;
  20046. return;
  20047. }
  20048. if ((!target.mType->IsPointer()) && (!target.mType->IsSizedArray()))
  20049. {
  20050. mModule->Fail("Expected pointer or array type", indexerExpr->mTarget);
  20051. return;
  20052. }
  20053. auto _GetDefaultResult = [&]()
  20054. {
  20055. return mModule->GetDefaultTypedValue(target.mType->GetUnderlyingType(), false, BfDefaultValueKind_Addr);
  20056. };
  20057. if (indexerExpr->mArguments.size() != 1)
  20058. {
  20059. mModule->Fail("Expected single index", indexerExpr->mOpenBracket);
  20060. mResult = _GetDefaultResult();
  20061. return;
  20062. }
  20063. if (indexerExpr->mArguments[0] == NULL)
  20064. {
  20065. mModule->AssertErrorState();
  20066. mResult = _GetDefaultResult();
  20067. return;
  20068. }
  20069. bool isUndefIndex = false;
  20070. auto indexArgument = mModule->CreateValueFromExpression(indexerExpr->mArguments[0], mModule->GetPrimitiveType(BfTypeCode_IntPtr), BfEvalExprFlags_NoCast);
  20071. if (!indexArgument)
  20072. return;
  20073. if (!indexArgument.mType->IsIntegral())
  20074. {
  20075. if (indexArgument.mType->IsVar())
  20076. {
  20077. isUndefIndex = true;
  20078. indexArgument = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_IntPtr), false, BfDefaultValueKind_Undef);
  20079. }
  20080. else
  20081. {
  20082. indexArgument = mModule->Cast(indexerExpr->mArguments[0], indexArgument, mModule->GetPrimitiveType(BfTypeCode_IntPtr));
  20083. if (!indexArgument)
  20084. indexArgument = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_IntPtr));
  20085. }
  20086. }
  20087. if (indexArgument.mType->IsPrimitiveType())
  20088. {
  20089. auto primType = (BfPrimitiveType*)indexArgument.mType;
  20090. if ((!primType->IsSigned()) && (primType->mSize < 8))
  20091. {
  20092. // GEP will always do a signed upcast so we need to cast manually if we are unsigned
  20093. indexArgument = BfTypedValue(mModule->mBfIRBuilder->CreateNumericCast(indexArgument.mValue, false, BfTypeCode_IntPtr), mModule->GetPrimitiveType(BfTypeCode_IntPtr));
  20094. }
  20095. }
  20096. mModule->PopulateType(target.mType);
  20097. if (target.mType->IsSizedArray())
  20098. {
  20099. BfSizedArrayType* sizedArrayType = (BfSizedArrayType*)target.mType;
  20100. auto underlyingType = sizedArrayType->mElementType;
  20101. if (indexArgument.mValue.IsConst())
  20102. {
  20103. auto indexConst = mModule->mBfIRBuilder->GetConstant(indexArgument.mValue);
  20104. if ((BfIRBuilder::IsIntable(indexConst->mTypeCode)) && (indexConst->mUInt64 >= (uint64)sizedArrayType->mElementCount))
  20105. {
  20106. if ((!mModule->IsInSpecializedSection()) && (checkedKind != BfCheckedKind_Unchecked))
  20107. {
  20108. mModule->Fail(StrFormat("Index '%d' is out of bounds for type '%s'", indexConst->mInt32, mModule->TypeToString(target.mType).c_str()), indexerExpr->mArguments[0]);
  20109. mResult = _GetDefaultResult();
  20110. return;
  20111. }
  20112. else
  20113. {
  20114. // Is this any good?
  20115. mModule->mBfIRBuilder->CreateUnreachable();
  20116. }
  20117. }
  20118. }
  20119. else if (((mModule->HasExecutedOutput()) || (mModule->mIsComptimeModule)) &&
  20120. (wantsChecks))
  20121. {
  20122. if (checkedKind == BfCheckedKind_NotSet)
  20123. checkedKind = mModule->GetDefaultCheckedKind();
  20124. if (checkedKind == BfCheckedKind_Checked)
  20125. {
  20126. auto oobBlock = mModule->mBfIRBuilder->CreateBlock("oob", true);
  20127. auto contBlock = mModule->mBfIRBuilder->CreateBlock("cont", true);
  20128. auto indexType = (BfPrimitiveType*)indexArgument.mType;
  20129. if (!mModule->mSystem->DoesLiteralFit(indexType->mTypeDef->mTypeCode, (int64)sizedArrayType->mElementCount))
  20130. {
  20131. // We need to upsize the index so we can compare it against the larger elementCount
  20132. indexType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  20133. indexArgument = mModule->Cast(indexerExpr->mArguments[0], indexArgument, indexType);
  20134. }
  20135. auto cmpRes = mModule->mBfIRBuilder->CreateCmpGTE(indexArgument.mValue, mModule->mBfIRBuilder->CreateConst(indexType->mTypeDef->mTypeCode, (uint64)sizedArrayType->mElementCount), false);
  20136. mModule->mBfIRBuilder->CreateCondBr(cmpRes, oobBlock, contBlock);
  20137. mModule->mBfIRBuilder->SetInsertPoint(oobBlock);
  20138. auto internalType = mModule->ResolveTypeDef(mModule->mCompiler->mInternalTypeDef);
  20139. auto oobFunc = mModule->GetMethodByName(internalType->ToTypeInstance(), "ThrowIndexOutOfRange");
  20140. if (oobFunc.mFunc)
  20141. {
  20142. if (mModule->mIsComptimeModule)
  20143. mModule->mCompiler->mCeMachine->QueueMethod(oobFunc.mMethodInstance, oobFunc.mFunc);
  20144. SizedArray<BfIRValue, 1> args;
  20145. args.push_back(mModule->GetConstValue(0));
  20146. mModule->mBfIRBuilder->CreateCall(oobFunc.mFunc, args);
  20147. mModule->mBfIRBuilder->CreateUnreachable();
  20148. }
  20149. else
  20150. {
  20151. mModule->Fail("System.Internal class must contain method 'ThrowIndexOutOfRange'");
  20152. }
  20153. mModule->mBfIRBuilder->SetInsertPoint(contBlock);
  20154. }
  20155. }
  20156. // If this is a 'bag of bytes', we should try hard not to have to make this addressable
  20157. if ((!target.IsAddr()) && (!target.mType->IsSizeAligned()))
  20158. mModule->MakeAddressable(target);
  20159. mResult = BfTypedValue();
  20160. mModule->PopulateType(underlyingType);
  20161. if ((sizedArrayType->IsUndefSizedArray()) || (isUndefIndex))
  20162. {
  20163. mResult = mModule->GetDefaultTypedValue(underlyingType, false, BfDefaultValueKind_Addr);
  20164. }
  20165. else if (sizedArrayType->IsValuelessType())
  20166. {
  20167. if (underlyingType->IsValuelessType())
  20168. mResult = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), underlyingType, true);
  20169. else
  20170. {
  20171. mResult = mModule->GetDefaultTypedValue(underlyingType, false, BfDefaultValueKind_Addr);
  20172. }
  20173. }
  20174. else if (target.IsAddr())
  20175. {
  20176. // Handle below
  20177. }
  20178. else
  20179. {
  20180. if ((!target.mValue.IsConst()) && (!indexArgument.mValue.IsConst()))
  20181. {
  20182. target = mModule->MakeAddressable(target);
  20183. }
  20184. else
  20185. {
  20186. mModule->mBfIRBuilder->PopulateType(target.mType);
  20187. auto gepResult = mModule->mBfIRBuilder->CreateExtractValue(target.mValue, indexArgument.mValue);
  20188. if ((underlyingType->IsString()) || (underlyingType->IsPointer()))
  20189. {
  20190. auto resultConst = mModule->mBfIRBuilder->GetConstant(gepResult);
  20191. if ((resultConst != NULL) && (resultConst->mTypeCode == BfTypeCode_Int32))
  20192. {
  20193. int strId = resultConst->mInt32;
  20194. const StringImpl& str = mModule->mContext->mStringObjectIdMap[strId].mString;
  20195. if (underlyingType->IsString())
  20196. gepResult = mModule->GetStringObjectValue(str, false);
  20197. else
  20198. gepResult = mModule->GetStringCharPtr(strId);
  20199. }
  20200. }
  20201. mResult = BfTypedValue(gepResult, underlyingType, BfTypedValueKind_Value);
  20202. }
  20203. }
  20204. if ((!mResult) && (target.IsAddr()))
  20205. {
  20206. if (target.mType->IsSizeAligned())
  20207. {
  20208. auto gepResult = mModule->mBfIRBuilder->CreateInBoundsGEP(target.mValue, mModule->GetConstValue(0), indexArgument.mValue);
  20209. mResult = BfTypedValue(gepResult, underlyingType, target.IsReadOnly() ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
  20210. }
  20211. else
  20212. {
  20213. auto indexResult = mModule->CreateIndexedValue(underlyingType, target.mValue, indexArgument.mValue);
  20214. mResult = BfTypedValue(indexResult, underlyingType, target.IsReadOnly() ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
  20215. }
  20216. }
  20217. if (!mResult)
  20218. {
  20219. mModule->Fail("Unable to index value", indexerExpr->mTarget);
  20220. return;
  20221. }
  20222. }
  20223. else
  20224. {
  20225. // We are no longer accessing data within this type
  20226. mResultLocalVar = NULL;
  20227. target = mModule->LoadValue(target);
  20228. BfPointerType* pointerType = (BfPointerType*)target.mType;
  20229. auto underlyingType = pointerType->mElementType;
  20230. mModule->mBfIRBuilder->PopulateType(underlyingType);
  20231. if (underlyingType->IsOpaque())
  20232. {
  20233. mModule->Fail(StrFormat("Unable to index opaque pointer type '%s'", mModule->TypeToString(pointerType).c_str()), indexerExpr);
  20234. }
  20235. else if (isUndefIndex)
  20236. {
  20237. mResult = mModule->GetDefaultTypedValue(underlyingType, false, BfDefaultValueKind_Addr);
  20238. }
  20239. else
  20240. {
  20241. BfIRValue result = mModule->CreateIndexedValue(underlyingType, target.mValue, indexArgument.mValue);
  20242. mResult = BfTypedValue(result, underlyingType, true);
  20243. }
  20244. }
  20245. }
  20246. void BfExprEvaluator::Visit(BfUnaryOperatorExpression* unaryOpExpr)
  20247. {
  20248. BfAutoParentNodeEntry autoParentNodeEntry(mModule, unaryOpExpr);
  20249. PerformUnaryOperation(unaryOpExpr->mExpression, unaryOpExpr->mOp, unaryOpExpr->mOpToken, BfUnaryOpFlag_None);
  20250. }
  20251. void BfExprEvaluator::PerformUnaryOperation(BfExpression* unaryOpExpr, BfUnaryOp unaryOp, BfTokenNode* opToken, BfUnaryOpFlags opFlags)
  20252. {
  20253. if ((unaryOpExpr == NULL) && (unaryOp == BfUnaryOp_PartialRangeThrough))
  20254. {
  20255. PerformBinaryOperation(NULL, NULL, BfBinaryOp_ClosedRange, opToken, BfBinOpFlag_None);
  20256. return;
  20257. }
  20258. ///
  20259. {
  20260. SetAndRestoreValue<BfEvalExprFlags> prevFlags(mBfEvalExprFlags);
  20261. BfType* prevExpedcting = mExpectingType;
  20262. switch (unaryOp)
  20263. {
  20264. case BfUnaryOp_Ref:
  20265. // Allow
  20266. break;
  20267. case BfUnaryOp_Dereference:
  20268. if (mExpectingType != NULL)
  20269. {
  20270. if (mExpectingType->IsRef())
  20271. mExpectingType = mExpectingType->GetUnderlyingType();
  20272. if (!mExpectingType->IsVar())
  20273. mExpectingType = mModule->CreatePointerType(mExpectingType);
  20274. }
  20275. break;
  20276. case BfUnaryOp_Negate:
  20277. case BfUnaryOp_Positive:
  20278. case BfUnaryOp_InvertBits:
  20279. // If we're expecting an int64 or uint64 then just leave the type as unknown
  20280. if ((mExpectingType != NULL) && (mExpectingType->IsInteger()) && (mExpectingType->mSize == 8))
  20281. mExpectingType = NULL;
  20282. // Otherwise keep expecting type
  20283. break;
  20284. case BfUnaryOp_Params:
  20285. mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_InParamsExpr);
  20286. break;
  20287. default:
  20288. mExpectingType = NULL;
  20289. }
  20290. VisitChild(unaryOpExpr);
  20291. mExpectingType = prevExpedcting;
  20292. }
  20293. BfExprEvaluator::PerformUnaryOperation_OnResult(unaryOpExpr, unaryOp, opToken, opFlags);
  20294. }
  20295. BfTypedValue BfExprEvaluator::PerformUnaryOperation_TryOperator(const BfTypedValue& inValue, BfExpression* unaryOpExpr, BfUnaryOp unaryOp, BfTokenNode* opToken, BfUnaryOpFlags opFlags)
  20296. {
  20297. if ((!inValue.mType->IsTypeInstance()) && (!inValue.mType->IsGenericParam()))
  20298. return BfTypedValue();
  20299. SizedArray<BfResolvedArg, 1> args;
  20300. BfResolvedArg resolvedArg;
  20301. resolvedArg.mTypedValue = inValue;
  20302. args.push_back(resolvedArg);
  20303. BfMethodMatcher methodMatcher(opToken, mModule, "", args, BfMethodGenericArguments());
  20304. methodMatcher.mBfEvalExprFlags = BfEvalExprFlags_NoAutoComplete;
  20305. methodMatcher.mAllowImplicitRef = true;
  20306. BfBaseClassWalker baseClassWalker(inValue.mType, NULL, mModule);
  20307. BfUnaryOp findOp = unaryOp;
  20308. bool isPostOp = false;
  20309. if (findOp == BfUnaryOp_PostIncrement)
  20310. {
  20311. findOp = BfUnaryOp_Increment;
  20312. isPostOp = true;
  20313. }
  20314. if (findOp == BfUnaryOp_PostDecrement)
  20315. {
  20316. findOp = BfUnaryOp_Decrement;
  20317. isPostOp = true;
  20318. }
  20319. bool isConstraintCheck = ((opFlags & BfUnaryOpFlag_IsConstraintCheck) != 0);
  20320. BfType* operatorConstraintReturnType = NULL;
  20321. BfType* bestSelfType = NULL;
  20322. while (true)
  20323. {
  20324. auto entry = baseClassWalker.Next();
  20325. auto checkType = entry.mTypeInstance;
  20326. if (checkType == NULL)
  20327. break;
  20328. for (auto operatorDef : checkType->mTypeDef->mOperators)
  20329. {
  20330. if (operatorDef->mOperatorDeclaration->mUnaryOp == findOp)
  20331. {
  20332. if (!methodMatcher.IsMemberAccessible(checkType, operatorDef->mDeclaringType))
  20333. continue;
  20334. int prevArgSize = (int)args.mSize;
  20335. if (!operatorDef->mIsStatic)
  20336. {
  20337. // Try without arg
  20338. args.mSize = 0;
  20339. }
  20340. if (isConstraintCheck)
  20341. {
  20342. auto returnType = mModule->CheckOperator(checkType, operatorDef, inValue, BfTypedValue());
  20343. if (returnType != NULL)
  20344. {
  20345. operatorConstraintReturnType = returnType;
  20346. methodMatcher.mBestMethodDef = operatorDef;
  20347. }
  20348. }
  20349. else
  20350. {
  20351. if (methodMatcher.CheckMethod(NULL, checkType, operatorDef, false))
  20352. methodMatcher.mSelfType = entry.mSrcType;
  20353. }
  20354. args.mSize = prevArgSize;
  20355. }
  20356. }
  20357. }
  20358. methodMatcher.FlushAmbiguityError();
  20359. if (methodMatcher.mBestMethodDef == NULL)
  20360. {
  20361. // Check method generic constraints
  20362. if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsUnspecialized) && (mModule->mCurMethodInstance->mMethodInfoEx != NULL))
  20363. {
  20364. for (int genericParamIdx = 0; genericParamIdx < mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams.size(); genericParamIdx++)
  20365. {
  20366. auto genericParam = mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
  20367. for (auto& opConstraint : genericParam->mOperatorConstraints)
  20368. {
  20369. if (opConstraint.mUnaryOp == findOp)
  20370. {
  20371. if (mModule->CanCast(args[0].mTypedValue, opConstraint.mRightType, isConstraintCheck ? BfCastFlags_IsConstraintCheck : BfCastFlags_None))
  20372. {
  20373. return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), genericParam->mExternType);
  20374. }
  20375. }
  20376. }
  20377. }
  20378. }
  20379. // Check type generic constraints
  20380. if ((mModule->mCurTypeInstance->IsGenericTypeInstance()) && (mModule->mCurTypeInstance->IsUnspecializedType()))
  20381. {
  20382. auto genericTypeInst = (BfTypeInstance*)mModule->mCurTypeInstance;
  20383. for (int genericParamIdx = 0; genericParamIdx < genericTypeInst->mGenericTypeInfo->mGenericParams.size(); genericParamIdx++)
  20384. {
  20385. auto genericParam = mModule->GetGenericTypeParamInstance(genericParamIdx);
  20386. for (auto& opConstraint : genericParam->mOperatorConstraints)
  20387. {
  20388. if (opConstraint.mUnaryOp == findOp)
  20389. {
  20390. if (mModule->CanCast(args[0].mTypedValue, opConstraint.mRightType, isConstraintCheck ? BfCastFlags_IsConstraintCheck : BfCastFlags_None))
  20391. {
  20392. return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), genericParam->mExternType);
  20393. }
  20394. }
  20395. }
  20396. }
  20397. }
  20398. return BfTypedValue();
  20399. }
  20400. if ((!baseClassWalker.mMayBeFromInterface) && (opToken != NULL))
  20401. mModule->SetElementType(opToken, BfSourceElementType_Method);
  20402. auto methodDef = methodMatcher.mBestMethodDef;
  20403. auto autoComplete = GetAutoComplete();
  20404. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(opToken)))
  20405. {
  20406. auto operatorDecl = BfNodeDynCast<BfOperatorDeclaration>(methodDef->mMethodDeclaration);
  20407. if ((operatorDecl != NULL) && (operatorDecl->mOpTypeToken != NULL))
  20408. autoComplete->SetDefinitionLocation(operatorDecl->mOpTypeToken);
  20409. }
  20410. SizedArray<BfExpression*, 2> argSrcs;
  20411. argSrcs.push_back(unaryOpExpr);
  20412. BfTypedValue targetVal = args[0].mTypedValue;
  20413. BfTypedValue postOpVal;
  20414. if (isPostOp)
  20415. postOpVal = mModule->LoadValue(targetVal);
  20416. BfTypedValue callTarget;
  20417. if (!methodMatcher.mBestMethodDef->mIsStatic)
  20418. {
  20419. callTarget = targetVal;
  20420. args.Clear();
  20421. }
  20422. BfTypedValue result;
  20423. if (isConstraintCheck)
  20424. {
  20425. result = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), operatorConstraintReturnType);
  20426. }
  20427. else
  20428. {
  20429. SetAndRestoreValue<BfEvalExprFlags> prevFlags(mBfEvalExprFlags, (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_NoAutoComplete));
  20430. SetAndRestoreValue<BfDeferCallData*> prevDeferCallRef(mDeferCallData, NULL);
  20431. result = CreateCall(&methodMatcher, callTarget);
  20432. }
  20433. if (!methodMatcher.mBestMethodDef->mIsStatic)
  20434. {
  20435. if (!isPostOp)
  20436. result = mModule->LoadValue(targetVal);
  20437. }
  20438. else if ((result.mType != NULL) && (methodMatcher.mSelfType != NULL) && (result.mType->IsSelf()))
  20439. {
  20440. BF_ASSERT(mModule->IsInGeneric());
  20441. result = mModule->GetDefaultTypedValue(methodMatcher.mSelfType);
  20442. }
  20443. if ((methodMatcher.mBestMethodInstance) &&
  20444. ((findOp == BfUnaryOp_Increment) || (findOp == BfUnaryOp_Decrement)))
  20445. {
  20446. if (methodMatcher.mBestMethodInstance.mMethodInstance->mIsIntrinsic)
  20447. {
  20448. if (args[0].mTypedValue.IsAddr())
  20449. mModule->mBfIRBuilder->CreateStore(result.mValue, args[0].mTypedValue.mValue);
  20450. else
  20451. {
  20452. mModule->AssertErrorState();
  20453. }
  20454. }
  20455. else
  20456. {
  20457. if (!result.mType->IsValuelessType())
  20458. {
  20459. if (targetVal.IsAddr())
  20460. {
  20461. result = mModule->LoadValue(result);
  20462. mModule->mBfIRBuilder->CreateStore(result.mValue, targetVal.mValue);
  20463. }
  20464. }
  20465. }
  20466. }
  20467. if (postOpVal)
  20468. result = postOpVal;
  20469. return result;
  20470. }
  20471. void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr, BfUnaryOp unaryOp, BfTokenNode* opToken, BfUnaryOpFlags opFlags)
  20472. {
  20473. BfAstNode* propSrc = mPropSrc;
  20474. BfTypedValue origPropTarget = mOrigPropTarget;
  20475. BfTypedValue propTarget = mPropTarget;
  20476. BfPropertyDef* propDef = mPropDef;
  20477. SizedArray<BfResolvedArg, 2> indexerVals = mIndexerValues;
  20478. BfTypedValue writeToProp;
  20479. GetResult();
  20480. if (!mResult)
  20481. return;
  20482. mResult = mModule->RemoveRef(mResult);
  20483. if (mResult.mType->IsVar())
  20484. {
  20485. mResult = BfTypedValue(mModule->GetDefaultValue(mResult.mType), mResult.mType);
  20486. return;
  20487. }
  20488. if (BfCanOverloadOperator(unaryOp))
  20489. {
  20490. auto opResult = PerformUnaryOperation_TryOperator(mResult, unaryOpExpr, unaryOp, opToken, opFlags);
  20491. if (opResult)
  20492. {
  20493. mResult = opResult;
  20494. return;
  20495. }
  20496. auto typeConstraint = mModule->GetGenericParamInstanceTypeConstraint(mResult.mType);
  20497. if ((typeConstraint != NULL) && (!typeConstraint->IsGenericParam()))
  20498. {
  20499. // Handle cases such as 'where T : float'
  20500. mResult.mType = typeConstraint;
  20501. PerformUnaryOperation_OnResult(unaryOpExpr, unaryOp, opToken, opFlags);
  20502. return;
  20503. }
  20504. }
  20505. switch (unaryOp)
  20506. {
  20507. case BfUnaryOp_PostIncrement:
  20508. case BfUnaryOp_Increment:
  20509. case BfUnaryOp_PostDecrement:
  20510. case BfUnaryOp_Decrement:
  20511. {
  20512. if (mResult.mKind == BfTypedValueKind_CopyOnMutateAddr)
  20513. {
  20514. // Support this ops on direct auto-property access without a copy
  20515. mResult.mKind = BfTypedValueKind_Addr;
  20516. }
  20517. }
  20518. break;
  20519. }
  20520. bool numericFail = false;
  20521. switch (unaryOp)
  20522. {
  20523. case BfUnaryOp_Not:
  20524. {
  20525. CheckResultForReading(mResult);
  20526. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  20527. auto value = mModule->LoadValue(mResult);
  20528. value = mModule->Cast(unaryOpExpr, value, boolType);
  20529. if (!value)
  20530. {
  20531. mResult = BfTypedValue();
  20532. return;
  20533. }
  20534. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateNot(value.mValue), boolType);
  20535. }
  20536. break;
  20537. case BfUnaryOp_Positive:
  20538. return;
  20539. case BfUnaryOp_Negate:
  20540. {
  20541. CheckResultForReading(mResult);
  20542. auto value = mModule->LoadValue(mResult);
  20543. if (!value)
  20544. {
  20545. mResult = BfTypedValue();
  20546. return;
  20547. }
  20548. BfType* origType = value.mType;
  20549. if (value.mType->IsTypedPrimitive())
  20550. value.mType = value.mType->GetUnderlyingType();
  20551. if (value.mType->IsIntegral())
  20552. {
  20553. auto primType = (BfPrimitiveType*)value.mType;
  20554. auto wantType = primType;
  20555. auto constant = mModule->mBfIRBuilder->GetConstant(value.mValue);
  20556. if ((constant != NULL) && (mModule->mBfIRBuilder->IsInt(constant->mTypeCode)))
  20557. {
  20558. if ((primType->mTypeDef->mTypeCode == BfTypeCode_UInt32) && (constant->mInt64 == 0x80000000LL))
  20559. {
  20560. mResult = BfTypedValue(mModule->GetConstValue32(-0x80000000LL), mModule->GetPrimitiveType(BfTypeCode_Int32));
  20561. return;
  20562. }
  20563. else if ((primType->mTypeDef->mTypeCode == BfTypeCode_UInt64) && (constant->mInt64 == 0x8000000000000000LL))
  20564. {
  20565. mResult = BfTypedValue(mModule->GetConstValue64(-0x8000000000000000LL), mModule->GetPrimitiveType(BfTypeCode_Int64));
  20566. return;
  20567. }
  20568. }
  20569. /*if (auto constantInt = dyn_cast<ConstantInt>((Value*)value.mValue))
  20570. {
  20571. int64 i64Val = constantInt->getSExtValue();
  20572. // This is a special case where the user entered -0x80000000 (maxint) but we thought "0x80000000" was a uint in the parser
  20573. // which would get upcasted to an int64 for this negate. Properly bring back down to an int32
  20574. if ((primType->mTypeDef->mTypeCode == BfTypeCode_UInt32) && (i64Val == -0x80000000LL))
  20575. {
  20576. mResult = BfTypedValue(mModule->GetConstValue((int)i64Val), mModule->GetPrimitiveType(BfTypeCode_Int32));
  20577. return;
  20578. }
  20579. }*/
  20580. if (!primType->IsSigned())
  20581. {
  20582. if (primType->mSize == 1)
  20583. wantType = mModule->GetPrimitiveType(BfTypeCode_Int16);
  20584. else if (primType->mSize == 2)
  20585. wantType = mModule->GetPrimitiveType(BfTypeCode_Int32);
  20586. else if (primType->mSize == 4)
  20587. wantType = mModule->GetPrimitiveType(BfTypeCode_Int64);
  20588. else
  20589. mModule->Fail("Operator '-' cannot be applied to uint64", opToken);
  20590. }
  20591. if (primType != wantType)
  20592. {
  20593. value = mModule->Cast(unaryOpExpr, value, wantType, BfCastFlags_Explicit);
  20594. if (!value)
  20595. {
  20596. mResult = BfTypedValue();
  20597. return;
  20598. }
  20599. }
  20600. if (origType->mSize == wantType->mSize) // Allow negative of primitive typed but not if we had to upsize
  20601. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateNeg(value.mValue), origType);
  20602. else
  20603. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateNeg(value.mValue), wantType);
  20604. }
  20605. else if (value.mType->IsFloat())
  20606. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateNeg(value.mValue), origType);
  20607. else
  20608. {
  20609. ResolveGenericType();
  20610. if (mResult.mType->IsVar())
  20611. break;
  20612. numericFail = true;
  20613. }
  20614. }
  20615. break;
  20616. case BfUnaryOp_InvertBits:
  20617. {
  20618. CheckResultForReading(mResult);
  20619. auto value = mModule->LoadValue(mResult);
  20620. if (!value)
  20621. return;
  20622. bool isInteger = value.mType->IsIntegral();
  20623. if (value.mType->IsTypedPrimitive())
  20624. isInteger = value.mType->GetUnderlyingType()->IsIntegral();
  20625. if (!isInteger)
  20626. {
  20627. mResult = BfTypedValue();
  20628. mModule->Fail("Operator can only be used on integer types", opToken);
  20629. return;
  20630. }
  20631. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateNot(value.mValue), value.mType);
  20632. }
  20633. break;
  20634. case BfUnaryOp_AddressOf:
  20635. {
  20636. MarkResultUsed();
  20637. mModule->FixIntUnknown(mResult);
  20638. mModule->PopulateType(mResult.mType);
  20639. auto ptrType = mModule->CreatePointerType(mResult.mType);
  20640. if ((mResult.mType->IsValuelessType()) && (!mResult.mType->IsOpaque()))
  20641. {
  20642. if (!mModule->IsInSpecializedSection())
  20643. {
  20644. mModule->Warn(0, StrFormat("Operator '&' results in a sentinel address for zero-sized type '%s'",
  20645. mModule->TypeToString(mResult.mType).c_str()), opToken);
  20646. }
  20647. // Sentinel value
  20648. auto val = mModule->mBfIRBuilder->CreateIntToPtr(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 1), mModule->mBfIRBuilder->MapType(ptrType));
  20649. mResult = BfTypedValue(val, ptrType);
  20650. }
  20651. else if (!CheckModifyResult(mResult, unaryOpExpr, "take address of", false, true))
  20652. {
  20653. if (!mResult.IsAddr())
  20654. mResult = mModule->MakeAddressable(mResult, false, true);
  20655. mResult = BfTypedValue(mResult.mValue, ptrType, false);
  20656. }
  20657. else
  20658. mResult = BfTypedValue(mResult.mValue, ptrType, false);
  20659. }
  20660. break;
  20661. case BfUnaryOp_Dereference:
  20662. {
  20663. CheckResultForReading(mResult);
  20664. if (mResult.mType->IsGenericParam())
  20665. {
  20666. auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)mResult.mType);
  20667. if ((genericParamInstance->mTypeConstraint != NULL) && (genericParamInstance->mTypeConstraint->IsPointer()))
  20668. {
  20669. mResult = mModule->GetDefaultTypedValue(genericParamInstance->mTypeConstraint->GetUnderlyingType(), false, BfDefaultValueKind_Addr);
  20670. break;
  20671. }
  20672. }
  20673. if (!mResult.mType->IsPointer())
  20674. {
  20675. mResult = BfTypedValue();
  20676. mModule->Fail("Cannot dereference non-pointer type", unaryOpExpr);
  20677. return;
  20678. }
  20679. if (mResult.mValue.IsConst())
  20680. {
  20681. auto constant = mModule->mBfIRBuilder->GetConstant(mResult.mValue);
  20682. bool isNull = constant->mTypeCode == BfTypeCode_NullPtr;
  20683. if (constant->mConstType == BfConstType_ExtractValue)
  20684. {
  20685. auto constExtract = (BfConstantExtractValue*)constant;
  20686. auto targetConst = mModule->mBfIRBuilder->GetConstantById(constExtract->mTarget);
  20687. if (targetConst->mConstType == BfConstType_AggZero)
  20688. isNull = true;
  20689. }
  20690. if (isNull)
  20691. {
  20692. mModule->Warn(0, "Cannot dereference a null pointer", unaryOpExpr);
  20693. mResult = mModule->GetDefaultTypedValue(mResult.mType, false, BfDefaultValueKind_Addr);
  20694. mResult = mModule->LoadValue(mResult);
  20695. }
  20696. }
  20697. auto derefTarget = mModule->LoadValue(mResult);
  20698. BfPointerType* pointerType = (BfPointerType*)derefTarget.mType;
  20699. auto resolvedType = pointerType->mElementType;
  20700. mModule->PopulateType(resolvedType);
  20701. if (resolvedType->IsValuelessNonOpaqueType())
  20702. mResult = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), resolvedType, true);
  20703. else
  20704. mResult = BfTypedValue(derefTarget.mValue, resolvedType, true);
  20705. }
  20706. break;
  20707. case BfUnaryOp_PostIncrement:
  20708. case BfUnaryOp_Increment:
  20709. {
  20710. CheckResultForReading(mResult);
  20711. auto ptr = mResult;
  20712. //if ((propDef == NULL) && (!mModule->CheckModifyValue(ptr, opToken)))
  20713. if ((propDef == NULL) && (!CheckModifyResult(ptr, opToken, "increment")))
  20714. return;
  20715. BfTypedValue origTypedVal = mModule->LoadValue(ptr, NULL, mIsVolatileReference);
  20716. BfIRValue origVal = origTypedVal.mValue;
  20717. BfIRValue constValue = mModule->GetConstValue(1, ptr.mType);
  20718. BfIRValue resultValue;
  20719. if (ptr.mType->IsPointer())
  20720. {
  20721. BfPointerType* ptrType = (BfPointerType*)ptr.mType;
  20722. BfType* intPtrType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  20723. constValue = mModule->GetConstValue(ptrType->mElementType->GetStride(), intPtrType);
  20724. auto i8PtrType = mModule->mBfIRBuilder->GetPointerTo(mModule->mBfIRBuilder->GetPrimitiveType(BfTypeCode_Int8));
  20725. BfIRValue origPtrValue = mModule->mBfIRBuilder->CreateBitCast(origVal, i8PtrType);
  20726. BfIRValue newPtrValue = mModule->mBfIRBuilder->CreateInBoundsGEP(origPtrValue, constValue);
  20727. resultValue = mModule->mBfIRBuilder->CreateBitCast(newPtrValue, mModule->mBfIRBuilder->MapType(ptr.mType));
  20728. }
  20729. else
  20730. {
  20731. constValue = mModule->GetConstValue(1, ptr.mType);
  20732. if (!constValue)
  20733. {
  20734. numericFail = true;
  20735. break;
  20736. }
  20737. if ((ptr.mType->IsIntegral()) || (ptr.mType->IsEnum()) || (ptr.mType->IsFloat()))
  20738. {
  20739. resultValue = mModule->mBfIRBuilder->CreateAdd(origVal, constValue/*, "inc"*/);
  20740. }
  20741. else
  20742. {
  20743. numericFail = true;
  20744. break;
  20745. }
  20746. }
  20747. if ((propDef != NULL) && (!ptr.IsAddr()))
  20748. writeToProp = BfTypedValue(resultValue, ptr.mType);
  20749. else
  20750. mModule->mBfIRBuilder->CreateAlignedStore(resultValue, ptr.mValue, ptr.mType->mAlign, mIsVolatileReference);
  20751. if (unaryOp == BfUnaryOp_PostIncrement)
  20752. mResult = BfTypedValue(origVal, ptr.mType, false);
  20753. else
  20754. mResult = BfTypedValue(resultValue, ptr.mType, false);
  20755. }
  20756. break;
  20757. case BfUnaryOp_PostDecrement:
  20758. case BfUnaryOp_Decrement:
  20759. {
  20760. CheckResultForReading(mResult);
  20761. auto ptr = mResult;
  20762. //if ((propDef == NULL) && (!mModule->CheckModifyValue(ptr, opToken)))
  20763. //return;
  20764. if ((propDef == NULL) && (!CheckModifyResult(ptr, opToken, "decrement")))
  20765. return;
  20766. BfTypedValue origTypedVal = mModule->LoadValue(ptr, NULL, mIsVolatileReference);
  20767. BfIRValue origVal = origTypedVal.mValue;
  20768. BfIRValue constValue = mModule->GetConstValue(1, ptr.mType);
  20769. BfIRValue resultValue;
  20770. if (ptr.mType->IsPointer())
  20771. {
  20772. BfPointerType* ptrType = (BfPointerType*)ptr.mType;
  20773. BfType* intPtrType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  20774. constValue = mModule->GetConstValue(-ptrType->mElementType->GetStride(), intPtrType);
  20775. auto i8PtrType = mModule->mBfIRBuilder->GetPointerTo(mModule->mBfIRBuilder->GetPrimitiveType(BfTypeCode_Int8));
  20776. BfIRValue origPtrValue = mModule->mBfIRBuilder->CreateBitCast(origVal, i8PtrType);
  20777. BfIRValue newPtrValue = mModule->mBfIRBuilder->CreateInBoundsGEP(origPtrValue, constValue);
  20778. resultValue = mModule->mBfIRBuilder->CreateBitCast(newPtrValue, mModule->mBfIRBuilder->MapType(ptr.mType));
  20779. }
  20780. else
  20781. {
  20782. BfIRValue constValue = mModule->GetConstValue(1, ptr.mType);
  20783. if (!constValue)
  20784. {
  20785. numericFail = true;
  20786. break;
  20787. }
  20788. if ((ptr.mType->IsIntegral()) || (ptr.mType->IsEnum()))
  20789. {
  20790. resultValue = mModule->mBfIRBuilder->CreateSub(origVal, constValue);
  20791. }
  20792. else if (ptr.mType->IsFloat())
  20793. {
  20794. resultValue = mModule->mBfIRBuilder->CreateSub(origVal, constValue);
  20795. }
  20796. else
  20797. {
  20798. numericFail = true;
  20799. break;
  20800. }
  20801. }
  20802. if ((propDef != NULL) && (!ptr.IsAddr()))
  20803. writeToProp = BfTypedValue(resultValue, ptr.mType);
  20804. else
  20805. mModule->mBfIRBuilder->CreateAlignedStore(resultValue, ptr.mValue, ptr.mType->mAlign, mIsVolatileReference);
  20806. if (unaryOp == BfUnaryOp_PostDecrement)
  20807. mResult = BfTypedValue(origVal, ptr.mType, false);
  20808. else
  20809. mResult = BfTypedValue(resultValue, ptr.mType, false);
  20810. }
  20811. break;
  20812. case BfUnaryOp_Ref:
  20813. case BfUnaryOp_Mut:
  20814. {
  20815. if (mAllowReadOnlyReference)
  20816. {
  20817. if (mResult.mKind == BfTypedValueKind_ReadOnlyAddr)
  20818. mResult.mKind = BfTypedValueKind_Addr;
  20819. }
  20820. CheckResultForReading(mResult);
  20821. if ((unaryOp == BfUnaryOp_Mut) && (!mResult.mType->IsValueType()) && (!mResult.mType->IsGenericParam()))
  20822. {
  20823. // Non-valuetypes types are already mutable, leave them alone...
  20824. break;
  20825. }
  20826. if ((unaryOp != BfUnaryOp_Mut) || (mResult.mKind != BfTypedValueKind_MutableValue))
  20827. {
  20828. if (!CheckModifyResult(mResult, unaryOpExpr, StrFormat("use '%s' on", BfGetOpName(unaryOp)).c_str()))
  20829. {
  20830. // Just leave the non-ref version in mResult
  20831. return;
  20832. }
  20833. }
  20834. if ((mBfEvalExprFlags & BfEvalExprFlags_AllowRefExpr) == 0)
  20835. {
  20836. mResult = BfTypedValue();
  20837. mModule->Fail(StrFormat("Invalid usage of '%s' expression", BfGetOpName(unaryOp)), opToken);
  20838. return;
  20839. }
  20840. ResolveGenericType();
  20841. if (mResult.mType->IsVar())
  20842. break;
  20843. mResult = BfTypedValue(mResult.mValue, mModule->CreateRefType(mResult.mType, (unaryOp == BfUnaryOp_Ref) ? BfRefType::RefKind_Ref : BfRefType::RefKind_Mut));
  20844. }
  20845. break;
  20846. case BfUnaryOp_Out:
  20847. {
  20848. if (!CheckModifyResult(mResult, unaryOpExpr, "use 'out' on"))
  20849. {
  20850. // Just leave the non-ref version in mResult
  20851. return;
  20852. }
  20853. if ((mBfEvalExprFlags & BfEvalExprFlags_AllowOutExpr) == 0)
  20854. {
  20855. mModule->Fail("Invalid usage of 'out' expression", opToken);
  20856. return;
  20857. }
  20858. if (mInsidePendingNullable)
  20859. {
  20860. // 'out' inside null conditionals never actually causes a definite assignment...
  20861. }
  20862. else
  20863. MarkResultAssigned();
  20864. MarkResultUsed();
  20865. ResolveGenericType();
  20866. if (mResult.mType->IsVar())
  20867. break;
  20868. mResult = BfTypedValue(mResult.mValue, mModule->CreateRefType(mResult.mType, BfRefType::RefKind_Out));
  20869. }
  20870. break;
  20871. case BfUnaryOp_Params:
  20872. {
  20873. bool allowParams = (mBfEvalExprFlags & BfEvalExprFlags_AllowParamsExpr) != 0;
  20874. if (allowParams)
  20875. {
  20876. if ((mResultLocalVar != NULL) && (mResultLocalVar->mCompositeCount >= 0)) // Delegate params
  20877. {
  20878. allowParams = true;
  20879. }
  20880. else
  20881. {
  20882. auto origValue = mResult;
  20883. auto isValid = false;
  20884. for (int pass = 0; pass < 2; pass++)
  20885. {
  20886. auto typeInst = mResult.mType->ToTypeInstance();
  20887. auto genericTypeInst = mResult.mType->ToGenericTypeInstance();
  20888. if ((genericTypeInst != NULL) && (genericTypeInst->IsInstanceOf(mModule->mCompiler->mSpanTypeDef)))
  20889. isValid = true;
  20890. else if ((mResult.mType->IsArray()) || (mResult.mType->IsSizedArray()))
  20891. isValid = true;
  20892. else if ((typeInst != NULL) && (pass == 0))
  20893. {
  20894. BfBaseClassWalker baseClassWalker(typeInst, NULL, mModule);
  20895. BfType* bestCastType = NULL;
  20896. while (true)
  20897. {
  20898. auto entry = baseClassWalker.Next();
  20899. auto checkType = entry.mTypeInstance;
  20900. if (checkType == NULL)
  20901. break;
  20902. for (auto operatorDef : checkType->mTypeDef->mOperators)
  20903. {
  20904. if (operatorDef->mOperatorDeclaration->mIsConvOperator)
  20905. {
  20906. if (operatorDef->IsExplicit())
  20907. continue;
  20908. auto methodInstance = mModule->GetRawMethodInstanceAtIdx(typeInst, operatorDef->mIdx);
  20909. auto checkType = methodInstance->mReturnType;
  20910. if (checkType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef))
  20911. bestCastType = checkType;
  20912. else if ((checkType->IsArray()) || (checkType->IsSizedArray()))
  20913. bestCastType = checkType;
  20914. }
  20915. }
  20916. }
  20917. if (bestCastType == NULL)
  20918. break;
  20919. auto castTypedValue = mModule->Cast(opToken, mResult, bestCastType, BfCastFlags_SilentFail);
  20920. if (!castTypedValue)
  20921. break;
  20922. mResult = castTypedValue;
  20923. }
  20924. else
  20925. break;
  20926. }
  20927. if (!isValid)
  20928. {
  20929. mModule->Fail(StrFormat("A 'params' expression cannot be used on type '%s'", mModule->TypeToString(origValue.mType).c_str()), opToken);
  20930. }
  20931. }
  20932. }
  20933. if (allowParams)
  20934. {
  20935. mResult = mModule->LoadValue(mResult);
  20936. if ((mResult.mType != NULL) && (mResult.mType->IsParamsType()))
  20937. mResult.mType = mResult.mType->GetUnderlyingType();
  20938. if (mResult.IsSplat())
  20939. mResult.mKind = BfTypedValueKind_ParamsSplat;
  20940. else
  20941. mResult.mKind = BfTypedValueKind_Params;
  20942. }
  20943. else
  20944. {
  20945. mModule->Fail("Illegal use of 'params' expression", opToken);
  20946. }
  20947. }
  20948. break;
  20949. case BfUnaryOp_Cascade:
  20950. {
  20951. mModule->Fail("Illegal use of argument cascade expression", opToken);
  20952. }
  20953. break;
  20954. case BfUnaryOp_FromEnd:
  20955. {
  20956. CheckResultForReading(mResult);
  20957. auto value = mModule->Cast(unaryOpExpr, mResult, mModule->GetPrimitiveType(BfTypeCode_IntPtr));
  20958. value = mModule->LoadValue(value);
  20959. if (value)
  20960. {
  20961. auto indexType = mModule->ResolveTypeDef(mModule->mCompiler->mIndexTypeDef);
  20962. auto alloca = mModule->CreateAlloca(indexType);
  20963. mModule->mBfIRBuilder->CreateStore(value.mValue, mModule->mBfIRBuilder->CreateInBoundsGEP(mModule->mBfIRBuilder->CreateInBoundsGEP(alloca, 0, 1), 0, 1));
  20964. mModule->mBfIRBuilder->CreateStore(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int8, 1), mModule->mBfIRBuilder->CreateInBoundsGEP(alloca, 0, 2));
  20965. mResult = BfTypedValue(alloca, indexType, BfTypedValueKind_Addr);
  20966. }
  20967. }
  20968. break;
  20969. case BfUnaryOp_PartialRangeUpTo:
  20970. PerformBinaryOperation(NULL, unaryOpExpr, BfBinaryOp_Range, opToken, BfBinOpFlag_None);
  20971. break;
  20972. case BfUnaryOp_PartialRangeThrough:
  20973. PerformBinaryOperation(NULL, unaryOpExpr, BfBinaryOp_ClosedRange, opToken, BfBinOpFlag_None);
  20974. break;
  20975. case BfUnaryOp_PartialRangeFrom:
  20976. PerformBinaryOperation(unaryOpExpr, NULL, BfBinaryOp_ClosedRange, opToken, BfBinOpFlag_None);
  20977. break;
  20978. default:
  20979. mModule->Fail(StrFormat("Illegal use of '%s' unary operator", BfGetOpName(unaryOp)), unaryOpExpr);
  20980. break;
  20981. }
  20982. if (numericFail)
  20983. {
  20984. if (opToken == NULL)
  20985. {
  20986. BF_ASSERT(mModule->mBfIRBuilder->mIgnoreWrites);
  20987. }
  20988. else if ((mResult.mType != NULL) && (mResult.mType->IsInterface()))
  20989. {
  20990. mModule->Fail(
  20991. StrFormat("Operator '%s' cannot be used on interface '%s'. Consider rewriting using generics and use this interface as a generic constraint.",
  20992. BfTokenToString(opToken->mToken), mModule->TypeToString(mResult.mType).c_str()), opToken);
  20993. }
  20994. else
  20995. {
  20996. mModule->Fail(
  20997. StrFormat("Operator '%s' cannot be used because type '%s' is neither a numeric type nor does it define an applicable operator overload",
  20998. BfTokenToString(opToken->mToken), mModule->TypeToString(mResult.mType).c_str()), opToken);
  20999. }
  21000. mResult = BfTypedValue();
  21001. }
  21002. if (writeToProp)
  21003. {
  21004. auto setMethod = GetPropertyMethodDef(propDef, BfMethodType_PropertySetter, mPropCheckedKind, mPropTarget);
  21005. if (setMethod == NULL)
  21006. {
  21007. mModule->Fail("Property has no setter", propSrc);
  21008. return;
  21009. }
  21010. auto methodInstance = GetPropertyMethodInstance(setMethod);
  21011. if (!methodInstance.mFunc)
  21012. return;
  21013. if (propSrc != NULL)
  21014. mModule->UpdateExprSrcPos(propSrc);
  21015. SizedArray<BfIRValue, 4> args;
  21016. if (!setMethod->mIsStatic)
  21017. {
  21018. auto usePropTarget = propTarget;
  21019. if (origPropTarget.mType == methodInstance.mMethodInstance->GetOwner())
  21020. usePropTarget = origPropTarget;
  21021. else
  21022. BF_ASSERT(propTarget.mType == methodInstance.mMethodInstance->GetOwner());
  21023. PushThis(propSrc, usePropTarget, methodInstance.mMethodInstance, args);
  21024. }
  21025. for (int paramIdx = 0; paramIdx < (int)indexerVals.size(); paramIdx++)
  21026. {
  21027. auto val = mModule->Cast(propSrc, indexerVals[paramIdx].mTypedValue, methodInstance.mMethodInstance->GetParamType(paramIdx));
  21028. if (!val)
  21029. return;
  21030. PushArg(val, args);
  21031. }
  21032. PushArg(writeToProp, args);
  21033. CreateCall(opToken, methodInstance.mMethodInstance, methodInstance.mFunc, false, args);
  21034. }
  21035. }
  21036. void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExpression* rightExpression, BfBinaryOp binaryOp, BfTokenNode* opToken, BfBinOpFlags flags, BfTypedValue leftValue)
  21037. {
  21038. BfTypedValue rightValue;
  21039. if (rightExpression == NULL)
  21040. {
  21041. mModule->AssertErrorState();
  21042. return;
  21043. }
  21044. if (!leftValue)
  21045. {
  21046. if (!rightValue)
  21047. mModule->CreateValueFromExpression(rightExpression, mExpectingType, (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags));
  21048. return;
  21049. }
  21050. if (leftValue.mType->IsRef())
  21051. leftValue.mType = leftValue.mType->GetUnderlyingType();
  21052. if ((binaryOp == BfBinaryOp_ConditionalAnd) || (binaryOp == BfBinaryOp_ConditionalOr))
  21053. {
  21054. if (mModule->mCurMethodState->mDeferredLocalAssignData != NULL)
  21055. mModule->mCurMethodState->mDeferredLocalAssignData->BreakExtendChain();
  21056. if (mModule->mCurMethodState->mCurScope->mScopeKind == BfScopeKind_StatementTarget)
  21057. mModule->mCurMethodState->mCurScope->mScopeKind = BfScopeKind_StatementTarget_Conditional;
  21058. bool isAnd = binaryOp == BfBinaryOp_ConditionalAnd;
  21059. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  21060. leftValue = mModule->Cast(leftExpression, leftValue, boolType);
  21061. if (!leftValue)
  21062. {
  21063. mModule->CreateValueFromExpression(rightExpression);
  21064. mResult = mModule->GetDefaultTypedValue(boolType, false, BfDefaultValueKind_Undef);
  21065. return;
  21066. }
  21067. auto prevBB = mModule->mBfIRBuilder->GetInsertBlock();
  21068. SetAndRestoreValue<bool> prevInCondBlock(mModule->mCurMethodState->mInConditionalBlock, true);
  21069. // The RHS is not guaranteed to be executed
  21070. if ((mModule->mCurMethodState->mDeferredLocalAssignData != NULL) &&
  21071. (mModule->mCurMethodState->mDeferredLocalAssignData->mIsIfCondition))
  21072. mModule->mCurMethodState->mDeferredLocalAssignData->mIfMayBeSkipped = true;
  21073. if (isAnd)
  21074. {
  21075. bool isConstBranch = false;
  21076. bool constResult = false;
  21077. if (leftValue.mValue.IsConst())
  21078. {
  21079. auto constValue = mModule->mBfIRBuilder->GetConstant(leftValue.mValue);
  21080. if (constValue->mTypeCode == BfTypeCode_Boolean)
  21081. {
  21082. isConstBranch = true;
  21083. constResult = constValue->mBool;
  21084. }
  21085. }
  21086. if (isConstBranch)
  21087. {
  21088. if ((constResult) || (HasVariableDeclaration(rightExpression)))
  21089. {
  21090. // Only right side
  21091. rightValue = mModule->CreateValueFromExpression(rightExpression, boolType, (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags));
  21092. mResult = rightValue;
  21093. }
  21094. else
  21095. {
  21096. // Always false
  21097. SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
  21098. SetAndRestoreValue<bool> prevInConstIgnore(mModule->mCurMethodState->mCurScope->mInConstIgnore, true);
  21099. rightValue = mModule->CreateValueFromExpression(rightExpression, boolType, (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags));
  21100. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 0), boolType);
  21101. }
  21102. }
  21103. else
  21104. {
  21105. auto rhsBB = mModule->mBfIRBuilder->CreateBlock("land.rhs");
  21106. auto endBB = mModule->mBfIRBuilder->CreateBlock("land.end");
  21107. mModule->mBfIRBuilder->CreateCondBr(leftValue.mValue, rhsBB, endBB);
  21108. mModule->AddBasicBlock(rhsBB);
  21109. rightValue = mModule->CreateValueFromExpression(rightExpression, boolType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_CreateConditionalScope));
  21110. mModule->mBfIRBuilder->CreateBr(endBB);
  21111. auto endRhsBB = mModule->mBfIRBuilder->GetInsertBlock();
  21112. mModule->AddBasicBlock(endBB);
  21113. auto phi = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(boolType), 2);
  21114. mModule->mBfIRBuilder->AddPhiIncoming(phi, mModule->GetConstValue(0, boolType), prevBB);
  21115. if (rightValue)
  21116. mModule->mBfIRBuilder->AddPhiIncoming(phi, rightValue.mValue, endRhsBB);
  21117. mResult = BfTypedValue(phi, boolType);
  21118. }
  21119. }
  21120. else
  21121. {
  21122. // Put variables in here into a 'possibly assigned' but never commit it.
  21123. // Because if we had "if ((Get(out a)) || (GetOther(out a))" then the LHS would already set it as defined, so
  21124. // the RHS is inconsequential
  21125. BfDeferredLocalAssignData deferredLocalAssignData;
  21126. deferredLocalAssignData.ExtendFrom(mModule->mCurMethodState->mDeferredLocalAssignData, false);
  21127. deferredLocalAssignData.mVarIdBarrier = mModule->mCurMethodState->GetRootMethodState()->mCurLocalVarId;
  21128. SetAndRestoreValue<BfDeferredLocalAssignData*> prevDLA(mModule->mCurMethodState->mDeferredLocalAssignData, &deferredLocalAssignData);
  21129. bool isConstBranch = false;
  21130. bool constResult = false;
  21131. if (leftValue.mValue.IsConst())
  21132. {
  21133. auto constValue = mModule->mBfIRBuilder->GetConstant(leftValue.mValue);
  21134. if (constValue->mTypeCode == BfTypeCode_Boolean)
  21135. {
  21136. isConstBranch = true;
  21137. constResult = constValue->mBool;
  21138. }
  21139. }
  21140. if (isConstBranch)
  21141. {
  21142. if ((constResult) && (!HasVariableDeclaration(rightExpression)))
  21143. {
  21144. // Always true
  21145. SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
  21146. SetAndRestoreValue<bool> prevInConstIgnore(mModule->mCurMethodState->mCurScope->mInConstIgnore, true);
  21147. rightValue = mModule->CreateValueFromExpression(rightExpression, boolType, (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags));
  21148. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 1), boolType);
  21149. }
  21150. else
  21151. {
  21152. // Only right side
  21153. rightValue = mModule->CreateValueFromExpression(rightExpression, boolType, (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags));
  21154. mResult = rightValue;
  21155. }
  21156. }
  21157. else
  21158. {
  21159. auto rhsBB = mModule->mBfIRBuilder->CreateBlock("lor.rhs");
  21160. auto endBB = mModule->mBfIRBuilder->CreateBlock("lor.end");
  21161. // This makes any 'scope' allocs be dyn since we aren't sure if this will be short-circuited
  21162. SetAndRestoreValue<bool> prevIsConditional(mModule->mCurMethodState->mCurScope->mIsConditional, true);
  21163. mModule->mBfIRBuilder->CreateCondBr(leftValue.mValue, endBB, rhsBB);
  21164. mModule->AddBasicBlock(rhsBB);
  21165. rightValue = mModule->CreateValueFromExpression(rightExpression, boolType, (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags));
  21166. mModule->mBfIRBuilder->CreateBr(endBB);
  21167. auto endRhsBB = mModule->mBfIRBuilder->GetInsertBlock();
  21168. mModule->AddBasicBlock(endBB);
  21169. auto phi = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(boolType), 2);
  21170. mModule->mBfIRBuilder->AddPhiIncoming(phi, mModule->GetConstValue(1, boolType), prevBB);
  21171. if (rightValue)
  21172. mModule->mBfIRBuilder->AddPhiIncoming(phi, rightValue.mValue, endRhsBB);
  21173. mResult = BfTypedValue(phi, boolType);
  21174. }
  21175. }
  21176. return;
  21177. }
  21178. BfType* wantType = leftValue.mType;
  21179. BfType* origWantType = wantType;
  21180. if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift))
  21181. wantType = NULL; // Don't presume
  21182. wantType = mModule->FixIntUnknown(wantType);
  21183. if ((binaryOp == BfBinaryOp_NullCoalesce) && (PerformBinaryOperation_NullCoalesce(opToken, leftExpression, rightExpression, leftValue, wantType, NULL)))
  21184. return;
  21185. BfType* rightWantType = wantType;
  21186. if (origWantType->IsIntUnknown())
  21187. rightWantType = NULL;
  21188. else if ((mExpectingType != NULL) && (wantType != NULL) && (mExpectingType->IsIntegral()) && (wantType->IsIntegral()) && (mExpectingType->mSize > wantType->mSize) &&
  21189. ((binaryOp == BfBinaryOp_Add) || (binaryOp == BfBinaryOp_Subtract) || (binaryOp == BfBinaryOp_Multiply)))
  21190. rightWantType = mExpectingType;
  21191. rightValue = mModule->CreateValueFromExpression(rightExpression, rightWantType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_AllowIntUnknown));
  21192. if ((rightWantType != wantType) && (rightValue.mType == rightWantType))
  21193. wantType = rightWantType;
  21194. if ((!leftValue) || (!rightValue))
  21195. return;
  21196. PerformBinaryOperation(leftExpression, rightExpression, binaryOp, opToken, flags, leftValue, rightValue);
  21197. }
  21198. bool BfExprEvaluator::PerformBinaryOperation_NullCoalesce(BfTokenNode* opToken, BfExpression* leftExpression, BfExpression* rightExpression, BfTypedValue leftValue, BfType* wantType, BfTypedValue* assignTo)
  21199. {
  21200. if ((leftValue) && ((leftValue.mType->IsPointer()) || (leftValue.mType->IsFunction()) || (leftValue.mType->IsObject())) || (leftValue.mType->IsNullable()))
  21201. {
  21202. leftValue = mModule->LoadOrAggregateValue(leftValue);
  21203. mModule->mBfIRBuilder->PopulateType(leftValue.mType);
  21204. BfType* nullableElementType = NULL;
  21205. BfIRValue nullableHasValue;
  21206. BfTypedValue nullableExtractedLeftValue;
  21207. if (leftValue.mType->IsNullable())
  21208. {
  21209. nullableElementType = leftValue.mType->GetUnderlyingType();
  21210. nullableHasValue = mModule->mBfIRBuilder->CreateExtractValue(leftValue.mValue, nullableElementType->IsValuelessType() ? 1 : 2); // has_value
  21211. if (!nullableElementType->IsValuelessType())
  21212. nullableExtractedLeftValue = BfTypedValue(mModule->mBfIRBuilder->CreateExtractValue(leftValue.mValue, 1), nullableElementType); // value
  21213. else
  21214. nullableExtractedLeftValue = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), nullableElementType);
  21215. }
  21216. if (leftValue.mValue.IsConst())
  21217. {
  21218. auto constant = mModule->mBfIRBuilder->GetConstant(leftValue.mValue);
  21219. if (constant->IsNull())
  21220. {
  21221. mResult = mModule->CreateValueFromExpression(rightExpression, wantType, (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags));
  21222. return true;
  21223. }
  21224. // Already have a value, we don't need the right side
  21225. SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
  21226. SetAndRestoreValue<bool> prevInConstIgnore(mModule->mCurMethodState->mCurScope->mInConstIgnore, true);
  21227. mModule->CreateValueFromExpression(rightExpression, wantType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_CreateConditionalScope));
  21228. mResult = leftValue;
  21229. return true;
  21230. }
  21231. auto prevBB = mModule->mBfIRBuilder->GetInsertBlock();
  21232. auto rhsBB = mModule->mBfIRBuilder->CreateBlock("nullc.rhs");
  21233. auto endBB = mModule->mBfIRBuilder->CreateBlock("nullc.end");
  21234. auto lhsBB = endBB;
  21235. auto endLhsBB = prevBB;
  21236. BfIRValue isNull;
  21237. if (nullableHasValue)
  21238. isNull = mModule->mBfIRBuilder->CreateCmpEQ(nullableHasValue, mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 0));
  21239. else if (leftValue.mType->IsFunction())
  21240. isNull = mModule->mBfIRBuilder->CreateIsNull(
  21241. mModule->mBfIRBuilder->CreateIntToPtr(leftValue.mValue, mModule->mBfIRBuilder->MapType(mModule->GetPrimitiveType(BfTypeCode_NullPtr))));
  21242. else
  21243. isNull = mModule->mBfIRBuilder->CreateIsNull(leftValue.mValue);
  21244. mModule->AddBasicBlock(rhsBB);
  21245. BfTypedValue rightValue;
  21246. if (assignTo != NULL)
  21247. rightValue = mModule->CreateValueFromExpression(rightExpression, wantType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_CreateConditionalScope));
  21248. else
  21249. rightValue = mModule->CreateValueFromExpression(rightExpression, wantType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_CreateConditionalScope));
  21250. if (!rightValue)
  21251. {
  21252. mModule->AssertErrorState();
  21253. return true;
  21254. }
  21255. if ((assignTo == NULL) && (leftValue.mType->IsNullable()) && (!rightValue.mType->IsNullable()))
  21256. {
  21257. if (wantType == leftValue.mType)
  21258. wantType = nullableElementType;
  21259. leftValue = nullableExtractedLeftValue;
  21260. }
  21261. rightValue = mModule->LoadValue(rightValue);
  21262. if (assignTo == NULL)
  21263. {
  21264. auto rightToLeftValue = mModule->CastToValue(rightExpression, rightValue, leftValue.mType, BfCastFlags_SilentFail);
  21265. if (rightToLeftValue)
  21266. {
  21267. rightValue = BfTypedValue(rightToLeftValue, leftValue.mType);
  21268. }
  21269. else
  21270. {
  21271. lhsBB = mModule->mBfIRBuilder->CreateBlock("nullc.lhs", true);
  21272. mModule->mBfIRBuilder->SetInsertPoint(lhsBB);
  21273. auto leftToRightValue = mModule->CastToValue(leftExpression, leftValue, rightValue.mType, BfCastFlags_SilentFail);
  21274. if (leftToRightValue)
  21275. {
  21276. leftValue = BfTypedValue(leftToRightValue, rightValue.mType);
  21277. }
  21278. else
  21279. {
  21280. // Note: Annoying trigraph split for '??'
  21281. mModule->Fail(StrFormat("Operator '?" "?' cannot be applied to operands of type '%s' and '%s'",
  21282. mModule->TypeToString(leftValue.mType).c_str(), mModule->TypeToString(rightValue.mType).c_str()), opToken);
  21283. leftValue = mModule->GetDefaultTypedValue(rightValue.mType);
  21284. }
  21285. mModule->mBfIRBuilder->CreateBr(endBB);
  21286. endLhsBB = mModule->mBfIRBuilder->GetInsertBlock();
  21287. mModule->mBfIRBuilder->SetInsertPoint(rhsBB);
  21288. }
  21289. }
  21290. if (assignTo != NULL)
  21291. mModule->mBfIRBuilder->CreateStore(rightValue.mValue, assignTo->mValue);
  21292. mModule->mBfIRBuilder->CreateBr(endBB);
  21293. auto endRhsBB = mModule->mBfIRBuilder->GetInsertBlock();
  21294. // Actually add CondBr at start
  21295. mModule->mBfIRBuilder->SetInsertPoint(prevBB);
  21296. mModule->mBfIRBuilder->CreateCondBr(isNull, rhsBB, lhsBB);
  21297. mModule->AddBasicBlock(endBB);
  21298. if (assignTo != NULL)
  21299. {
  21300. mResult = *assignTo;
  21301. }
  21302. else
  21303. {
  21304. auto phi = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(leftValue.mType), 2);
  21305. if (!leftValue.mType->IsValuelessType())
  21306. mModule->mBfIRBuilder->AddPhiIncoming(phi, leftValue.mValue, endLhsBB);
  21307. if (!rightValue.mType->IsValuelessType())
  21308. mModule->mBfIRBuilder->AddPhiIncoming(phi, rightValue.mValue, endRhsBB);
  21309. mResult = BfTypedValue(phi, leftValue.mType);
  21310. }
  21311. return true;
  21312. }
  21313. return false;
  21314. }
  21315. bool BfExprEvaluator::PerformBinaryOperation_Numeric(BfAstNode* leftExpression, BfAstNode* rightExpression, BfBinaryOp binaryOp, BfAstNode* opToken, BfBinOpFlags flags, BfTypedValue leftValue, BfTypedValue rightValue)
  21316. {
  21317. switch (binaryOp)
  21318. {
  21319. case BfBinaryOp_Add:
  21320. case BfBinaryOp_Subtract:
  21321. case BfBinaryOp_Multiply:
  21322. case BfBinaryOp_Divide:
  21323. case BfBinaryOp_Modulus:
  21324. break;
  21325. default:
  21326. return false;
  21327. }
  21328. auto wantType = mExpectingType;
  21329. if ((wantType == NULL) ||
  21330. ((!wantType->IsFloat()) && (!wantType->IsIntegral())))
  21331. wantType = NULL;
  21332. auto leftType = mModule->GetClosestNumericCastType(leftValue, mExpectingType);
  21333. auto rightType = mModule->GetClosestNumericCastType(rightValue, mExpectingType);
  21334. if (leftType != NULL)
  21335. {
  21336. if ((rightType == NULL) || (mModule->CanCast(mModule->GetFakeTypedValue(rightType), leftType)))
  21337. wantType = leftType;
  21338. else if ((rightType != NULL) && (mModule->CanCast(mModule->GetFakeTypedValue(leftType), rightType)))
  21339. wantType = rightType;
  21340. }
  21341. else if (rightType != NULL)
  21342. wantType = rightType;
  21343. if (wantType == NULL)
  21344. wantType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  21345. auto convLeftValue = mModule->Cast(opToken, leftValue, wantType, BfCastFlags_SilentFail);
  21346. if (!convLeftValue)
  21347. return false;
  21348. auto convRightValue = mModule->Cast(opToken, rightValue, wantType, BfCastFlags_SilentFail);
  21349. if (!convRightValue)
  21350. return false;
  21351. mResult = BfTypedValue();
  21352. // Let the error come from here, if any - so we always return 'true' to avoid a second error
  21353. PerformBinaryOperation(leftExpression, rightExpression, binaryOp, opToken, flags, convLeftValue, convRightValue);
  21354. return true;
  21355. }
  21356. void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExpression* rightExpression, BfBinaryOp binaryOp, BfTokenNode* opToken, BfBinOpFlags flags)
  21357. {
  21358. if ((binaryOp == BfBinaryOp_Range) || (binaryOp == BfBinaryOp_ClosedRange))
  21359. {
  21360. auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  21361. bool isIndexExpr = false;
  21362. BfTypeDef* typeDef = NULL;
  21363. if (auto unaryOpExpr = BfNodeDynCast<BfUnaryOperatorExpression>(leftExpression))
  21364. if (unaryOpExpr->mOp == BfUnaryOp_FromEnd)
  21365. isIndexExpr = true;
  21366. if (rightExpression == NULL)
  21367. isIndexExpr = true;
  21368. if (auto unaryOpExpr = BfNodeDynCast<BfUnaryOperatorExpression>(rightExpression))
  21369. if (unaryOpExpr->mOp == BfUnaryOp_FromEnd)
  21370. isIndexExpr = true;
  21371. if (isIndexExpr)
  21372. typeDef = mModule->mCompiler->mIndexRangeTypeDef;
  21373. else
  21374. typeDef = (binaryOp == BfBinaryOp_Range) ? mModule->mCompiler->mRangeTypeDef : mModule->mCompiler->mClosedRangeTypeDef;
  21375. auto allocType = mModule->ResolveTypeDef(typeDef)->ToTypeInstance();
  21376. auto alloca = mModule->CreateAlloca(allocType);
  21377. BfTypedValueExpression leftTypedValueExpr;
  21378. BfTypedValueExpression rightTypedValueExpr;
  21379. BfTypedValueExpression isClosedTypedValueExpr;
  21380. SizedArray<BfExpression*, 2> argExprs;
  21381. if (leftExpression != NULL)
  21382. {
  21383. argExprs.Add(leftExpression);
  21384. }
  21385. else
  21386. {
  21387. leftTypedValueExpr.mRefNode = opToken;
  21388. leftTypedValueExpr.mTypedValue = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0), mModule->GetPrimitiveType(BfTypeCode_IntPtr));
  21389. argExprs.Add(&leftTypedValueExpr);
  21390. }
  21391. if (rightExpression != NULL)
  21392. {
  21393. argExprs.Add(rightExpression);
  21394. }
  21395. else
  21396. {
  21397. // Add as a `^1`
  21398. auto indexType = mModule->ResolveTypeDef(mModule->mCompiler->mIndexTypeDef)->ToTypeInstance();
  21399. mModule->PopulateType(indexType->mBaseType);
  21400. BF_ASSERT_REL(indexType->mBaseType->mBaseType != NULL);
  21401. rightTypedValueExpr.mRefNode = opToken;
  21402. auto valueTypeEmpty = mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(indexType->mBaseType->mBaseType), {});
  21403. SizedArray<BfIRValue, 8> tupleEmptyMembers;
  21404. tupleEmptyMembers.Add(valueTypeEmpty);
  21405. auto tupleTypeEmpty = mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(mModule->ResolveTypeDef(mModule->mCompiler->mTupleTypeDef)), tupleEmptyMembers);
  21406. SizedArray<BfIRValue, 8> enumMembers;
  21407. enumMembers.Add(valueTypeEmpty);
  21408. auto enumValue = mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(indexType->mBaseType), enumMembers);
  21409. SizedArray<BfIRValue, 8> tupleMembers;
  21410. tupleMembers.Add(tupleTypeEmpty);
  21411. tupleMembers.Add(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 1));
  21412. auto tupleValue = mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(indexType->mFieldInstances[0].mResolvedType), tupleMembers);
  21413. SizedArray<BfIRValue, 8> indexMembers;
  21414. indexMembers.Add(enumValue);
  21415. indexMembers.Add(tupleValue);
  21416. indexMembers.Add(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int8, 1));
  21417. auto indexValue = mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(indexType), indexMembers);
  21418. rightTypedValueExpr.mTypedValue = BfTypedValue(indexValue, indexType);
  21419. argExprs.Add(&rightTypedValueExpr);
  21420. }
  21421. if (isIndexExpr)
  21422. {
  21423. isClosedTypedValueExpr.mRefNode = opToken;
  21424. isClosedTypedValueExpr.mTypedValue = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, (binaryOp == BfBinaryOp_ClosedRange) ? 1 : 0), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  21425. argExprs.Add(&isClosedTypedValueExpr);
  21426. }
  21427. BfSizedArray<BfExpression*> args = argExprs;
  21428. BfResolvedArgs argValues;
  21429. argValues.Init(&args);
  21430. ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval);
  21431. mResult = BfTypedValue(alloca, allocType, true);
  21432. auto result = MatchConstructor(opToken, NULL, mResult, allocType, argValues, true, BfMethodGenericArguments(), BfAllowAppendKind_No);
  21433. if ((result) && (!result.mType->IsVoid()))
  21434. mResult = result;
  21435. return;
  21436. }
  21437. BfTypedValue leftValue;
  21438. if (leftExpression != NULL)
  21439. {
  21440. leftValue = mModule->CreateValueFromExpression(leftExpression, mExpectingType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_AllowIntUnknown));
  21441. }
  21442. PerformBinaryOperation(leftExpression, rightExpression, binaryOp, opToken, flags, leftValue);
  21443. }
  21444. bool BfExprEvaluator::CheckConstCompare(BfBinaryOp binaryOp, BfAstNode* opToken, const BfTypedValue& leftValue, const BfTypedValue& rightValue, bool invert)
  21445. {
  21446. if ((binaryOp < BfBinaryOp_Equality) || (binaryOp > BfBinaryOp_LessThanOrEqual))
  21447. return false;
  21448. // LHS is expected to be a value and RHS is expected to be a const
  21449. if (!leftValue.mType->IsIntegral())
  21450. return false;
  21451. BF_ASSERT(rightValue.mValue.IsConst());
  21452. auto rightConst = mModule->mBfIRBuilder->GetConstant(rightValue.mValue);
  21453. if (!mModule->mBfIRBuilder->IsInt(rightConst->mTypeCode))
  21454. return false;
  21455. BfType* checkType = leftValue.mType;
  21456. if (checkType->IsTypedPrimitive())
  21457. checkType = checkType->GetUnderlyingType();
  21458. if (!checkType->IsPrimitiveType())
  21459. return false;
  21460. BfTypeCode typeCode = ((BfPrimitiveType*)checkType)->mTypeDef->mTypeCode;
  21461. int64 minValue = 0;
  21462. int64 maxValue = 0;
  21463. switch (typeCode)
  21464. {
  21465. case BfTypeCode_Int8:
  21466. minValue = -0x80;
  21467. maxValue = 0x7F;
  21468. break;
  21469. case BfTypeCode_Int16:
  21470. minValue = -0x8000;
  21471. maxValue = 0x7FFF;
  21472. break;
  21473. case BfTypeCode_Int32:
  21474. minValue = -0x80000000LL;
  21475. maxValue = 0x7FFFFFFF;
  21476. break;
  21477. case BfTypeCode_Int64:
  21478. minValue = -0x8000000000000000LL;
  21479. maxValue = 0x7FFFFFFFFFFFFFFFLL;
  21480. break;
  21481. case BfTypeCode_UInt8:
  21482. maxValue = 0xFF;
  21483. break;
  21484. case BfTypeCode_UInt16:
  21485. maxValue = 0xFFFF;
  21486. break;
  21487. case BfTypeCode_UInt32:
  21488. maxValue = 0xFFFFFFFF;
  21489. break;
  21490. default:
  21491. return false;
  21492. }
  21493. int constResult = -1;
  21494. if (typeCode == BfTypeCode_UInt64)
  21495. {
  21496. switch (binaryOp)
  21497. {
  21498. case BfBinaryOp_Equality:
  21499. case BfBinaryOp_StrictEquality:
  21500. if (rightConst->mInt64 < minValue)
  21501. constResult = 0;
  21502. break;
  21503. case BfBinaryOp_InEquality:
  21504. case BfBinaryOp_StrictInEquality:
  21505. if (rightConst->mInt64 < minValue)
  21506. constResult = 1;
  21507. break;
  21508. case BfBinaryOp_LessThan:
  21509. if (rightConst->mInt64 <= minValue)
  21510. constResult = 0;
  21511. break;
  21512. case BfBinaryOp_LessThanOrEqual:
  21513. if (rightConst->mInt64 < minValue)
  21514. constResult = 0;
  21515. break;
  21516. default: break;
  21517. }
  21518. return false;
  21519. }
  21520. else
  21521. {
  21522. switch (binaryOp)
  21523. {
  21524. case BfBinaryOp_Equality:
  21525. case BfBinaryOp_StrictEquality:
  21526. if (rightConst->mInt64 < minValue)
  21527. constResult = 0;
  21528. else if (rightConst->mInt64 > maxValue)
  21529. constResult = 0;
  21530. break;
  21531. case BfBinaryOp_InEquality:
  21532. case BfBinaryOp_StrictInEquality:
  21533. if (rightConst->mInt64 < minValue)
  21534. constResult = 1;
  21535. else if (rightConst->mInt64 > maxValue)
  21536. constResult = 1;
  21537. break;
  21538. case BfBinaryOp_LessThan:
  21539. if (rightConst->mInt64 <= minValue)
  21540. constResult = 0;
  21541. else if (rightConst->mInt64 > maxValue)
  21542. constResult = 1;
  21543. break;
  21544. case BfBinaryOp_LessThanOrEqual:
  21545. if (rightConst->mInt64 < minValue)
  21546. constResult = 0;
  21547. else if (rightConst->mInt64 >= maxValue)
  21548. constResult = 1;
  21549. break;
  21550. case BfBinaryOp_GreaterThan:
  21551. if (rightConst->mInt64 >= maxValue)
  21552. constResult = 0;
  21553. else if (rightConst->mInt64 < minValue)
  21554. constResult = 1;
  21555. break;
  21556. case BfBinaryOp_GreaterThanOrEqual:
  21557. if (rightConst->mInt64 > maxValue)
  21558. constResult = 0;
  21559. else if (rightConst->mInt64 <= minValue)
  21560. constResult = 1;
  21561. break;
  21562. default: break;
  21563. }
  21564. }
  21565. if ((invert) && (constResult >= 0))
  21566. constResult ^= 1;
  21567. if (constResult == 0)
  21568. {
  21569. mModule->Warn(0, "The result of this operation is always 'false'", opToken);
  21570. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 0), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  21571. return true;
  21572. }
  21573. else if (constResult == 1)
  21574. {
  21575. mModule->Warn(0, "The result of this operation is always 'true'", opToken);
  21576. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 1), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  21577. return true;
  21578. }
  21579. return false;
  21580. }
  21581. void BfExprEvaluator::AddStrings(const BfTypedValue& leftValue, const BfTypedValue& rightValue, BfAstNode* refNode)
  21582. {
  21583. if ((leftValue.mValue.IsConst()) && (rightValue.mValue.IsConst()))
  21584. {
  21585. String* lhsStr = mModule->GetStringPoolString(leftValue.mValue, mModule->mBfIRBuilder);
  21586. String* rhsStr = mModule->GetStringPoolString(rightValue.mValue, mModule->mBfIRBuilder);
  21587. if ((lhsStr != NULL) && (rhsStr != NULL))
  21588. {
  21589. String resultStr = *lhsStr + *rhsStr;
  21590. BfVariant variant;
  21591. variant.mTypeCode = BfTypeCode_CharPtr;
  21592. variant.mString = &resultStr;
  21593. GetLiteral(refNode, variant);
  21594. return;
  21595. }
  21596. }
  21597. mModule->Fail("Strings can only be added when they are constants. Consider allocating a string and using Concat.", refNode);
  21598. return;
  21599. }
  21600. void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNode* rightExpression, BfBinaryOp binaryOp, BfAstNode* opToken, BfBinOpFlags flags, BfTypedValue leftValue, BfTypedValue rightValue)
  21601. {
  21602. bool noClassify = (flags & BfBinOpFlag_NoClassify) != 0;
  21603. bool forceRightType = (flags & BfBinOpFlag_ForceRightType) != 0;
  21604. bool forceLeftType = (flags & BfBinOpFlag_ForceLeftType) != 0;
  21605. bool deferRight = (flags & BfBinOpFlag_DeferRight) != 0;
  21606. if (deferRight)
  21607. {
  21608. rightValue = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Var));
  21609. }
  21610. if ((rightValue.mValue.IsConst()) && (!leftValue.mValue.IsConst()))
  21611. {
  21612. if (CheckConstCompare(binaryOp, opToken, leftValue, rightValue))
  21613. return;
  21614. }
  21615. else if ((leftValue.mValue.IsConst()) && (!rightValue.mValue.IsConst()))
  21616. {
  21617. if (CheckConstCompare(BfGetOppositeBinaryOp(binaryOp), opToken, rightValue, leftValue, true))
  21618. return;
  21619. }
  21620. if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift))
  21621. {
  21622. forceLeftType = true;
  21623. mModule->FixIntUnknown(leftValue);
  21624. }
  21625. if (rightValue.mType->IsRef())
  21626. rightValue.mType = rightValue.mType->GetUnderlyingType();
  21627. BfType* origLeftType = leftValue.mType;
  21628. BfType* origRightType = rightValue.mType;
  21629. mModule->FixIntUnknown(leftValue, rightValue);
  21630. // Prefer floats, prefer chars
  21631. int leftCompareSize = leftValue.mType->mSize;
  21632. if (leftValue.mType->IsFloat())
  21633. leftCompareSize += 0x10;
  21634. if (leftValue.mType->IsChar())
  21635. leftCompareSize += 0x100;
  21636. if (!leftValue.mType->IsPrimitiveType())
  21637. leftCompareSize += 0x1000;
  21638. int rightCompareSize = rightValue.mType->mSize;
  21639. if (rightValue.mType->IsFloat())
  21640. rightCompareSize += 0x10;
  21641. if (rightValue.mType->IsChar())
  21642. rightCompareSize += 0x100;
  21643. if (!rightValue.mType->IsPrimitiveType())
  21644. rightCompareSize += 0x1000;
  21645. if ((leftValue.mType->IsTypeInstance()) && (rightValue.mType->IsTypeInstance()))
  21646. {
  21647. int leftInheritDepth = leftValue.mType->ToTypeInstance()->mInheritDepth;
  21648. int rightInheritDepth = rightValue.mType->ToTypeInstance()->mInheritDepth;
  21649. if (leftInheritDepth < rightInheritDepth)
  21650. {
  21651. // If both are type instances then choose the type with the lowest inherit depth
  21652. // so we will choose the base type when applicable
  21653. forceLeftType = true;
  21654. }
  21655. }
  21656. auto resultType = leftValue.mType;
  21657. if (forceRightType)
  21658. {
  21659. resultType = rightValue.mType;
  21660. }
  21661. else if (!forceLeftType)
  21662. {
  21663. bool handled = false;
  21664. BfType* expectingType = mExpectingType;
  21665. if (leftValue.mType == rightValue.mType)
  21666. {
  21667. // All good
  21668. handled = true;
  21669. }
  21670. else if ((expectingType != NULL) &&
  21671. (mModule->CanCast(leftValue, expectingType, BfCastFlags_NoBox)) &&
  21672. (mModule->CanCast(rightValue, expectingType, BfCastFlags_NoBox)) &&
  21673. (!leftValue.mType->IsVar()) && (!rightValue.mType->IsVar()))
  21674. {
  21675. resultType = expectingType;
  21676. handled = true;
  21677. }
  21678. else
  21679. {
  21680. // If one of these is a constant that can be converted into a smaller type, then do that
  21681. if (rightValue.mValue.IsConst())
  21682. {
  21683. if (mModule->CanCast(rightValue, leftValue.mType, BfCastFlags_NoBox))
  21684. {
  21685. resultType = leftValue.mType;
  21686. handled = true;
  21687. }
  21688. }
  21689. // If left is an IntUnknown, allow the right to inform the type
  21690. if (leftValue.mType->IsIntUnknown())
  21691. {
  21692. if (leftValue.mValue.IsConst())
  21693. {
  21694. if (mModule->CanCast(leftValue, rightValue.mType))
  21695. {
  21696. resultType = rightValue.mType;
  21697. handled = true;
  21698. }
  21699. }
  21700. }
  21701. if ((leftValue.mType->IsPointer()) &&
  21702. (rightValue.mType->IsPointer()))
  21703. {
  21704. BfPointerType* leftPointerType = (BfPointerType*)leftValue.mType;
  21705. BfPointerType* rightPointerType = (BfPointerType*)rightValue.mType;
  21706. // If one is a pointer to a sized array then use the other type
  21707. if (leftPointerType->mElementType->IsSizedArray())
  21708. {
  21709. resultType = rightPointerType;
  21710. handled = true;
  21711. }
  21712. else if (rightPointerType->mElementType->IsSizedArray())
  21713. {
  21714. resultType = leftPointerType;
  21715. handled = true;
  21716. }
  21717. }
  21718. }
  21719. if (!handled)
  21720. {
  21721. if ((resultType->IsNull()) ||
  21722. (rightCompareSize > leftCompareSize) ||
  21723. (((rightCompareSize == leftCompareSize) && (!rightValue.mType->IsSigned()))) ||
  21724. (rightValue.mType->IsTypedPrimitive()))
  21725. {
  21726. // Select the type with the "most information"
  21727. if (!rightValue.mType->IsNull())
  21728. resultType = rightValue.mType;
  21729. }
  21730. if ((!resultType->IsPointer()) && (rightValue.mType->IsPointer()))
  21731. resultType = rightValue.mType;
  21732. }
  21733. }
  21734. bool explicitCast = false;
  21735. BfTypedValue* resultTypedValue;
  21736. BfTypedValue* otherTypedValue;
  21737. BfType* otherType;
  21738. BfAstNode* resultTypeSrc;
  21739. BfAstNode* otherTypeSrc;
  21740. if (resultType == leftValue.mType)
  21741. {
  21742. resultTypedValue = &leftValue;
  21743. resultTypeSrc = leftExpression;
  21744. otherTypedValue = &rightValue;
  21745. otherTypeSrc = rightExpression;
  21746. otherType = otherTypedValue->mType;
  21747. }
  21748. else
  21749. {
  21750. resultTypedValue = &rightValue;
  21751. resultTypeSrc = rightExpression;
  21752. otherTypedValue = &leftValue;
  21753. otherTypeSrc = leftExpression;
  21754. otherType = otherTypedValue->mType;
  21755. }
  21756. auto _OpFail = [&]()
  21757. {
  21758. if ((rightValue.mType != NULL) && (leftValue.mType != NULL))
  21759. {
  21760. if (rightValue.mType != leftValue.mType)
  21761. mModule->Fail(StrFormat("Cannot perform binary operation '%s' between types '%s' and '%s'",
  21762. BfGetOpName(binaryOp), mModule->TypeToString(leftValue.mType).c_str(), mModule->TypeToString(rightValue.mType).c_str()), opToken);
  21763. else
  21764. {
  21765. if (leftValue.mType->IsInterface())
  21766. {
  21767. 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.",
  21768. BfGetOpName(binaryOp), mModule->TypeToString(leftValue.mType).c_str()), opToken);
  21769. }
  21770. else
  21771. {
  21772. mModule->Fail(StrFormat("Cannot perform binary operation '%s' between two instances of type '%s'",
  21773. BfGetOpName(binaryOp), mModule->TypeToString(leftValue.mType).c_str()), opToken);
  21774. }
  21775. }
  21776. }
  21777. else
  21778. mModule->Fail(StrFormat("Cannot perform binary operation '%s'", BfGetOpName(binaryOp)), opToken);
  21779. };
  21780. // This case fixes cases like "c == 0" where "0" is technically an int but can be reduced
  21781. if (BfBinOpEqualityCheck(binaryOp))
  21782. {
  21783. if ((resultType != otherType) && (resultTypedValue->mValue.IsConst()) && (mModule->CanCast(*resultTypedValue, otherType)))
  21784. {
  21785. std::swap(resultTypedValue, otherTypedValue);
  21786. std::swap(resultTypeSrc, otherTypeSrc);
  21787. std::swap(resultType, otherType);
  21788. }
  21789. }
  21790. BfIRValue convLeftValue;
  21791. BfIRValue convRightValue;
  21792. if (((resultType->IsVar()) || (otherType->IsVar())) && (!deferRight))
  21793. {
  21794. bool isComparison = (binaryOp >= BfBinaryOp_Equality) && (binaryOp <= BfBinaryOp_LessThanOrEqual);
  21795. if (isComparison)
  21796. mResult = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Boolean), false, BfDefaultValueKind_Addr);
  21797. else if (mExpectingType != NULL)
  21798. mResult = mModule->GetDefaultTypedValue(mExpectingType, false, BfDefaultValueKind_Addr);
  21799. else
  21800. mResult = mModule->GetDefaultTypedValue(resultType, false, BfDefaultValueKind_Addr);
  21801. return;
  21802. }
  21803. if ((otherType->IsNull()) && (BfBinOpEqualityCheck(binaryOp)))
  21804. {
  21805. bool isEquality = (binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality);
  21806. if ((resultType->IsValueType()) && (!resultType->IsFunction()))
  21807. {
  21808. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  21809. if (resultType->IsNullable())
  21810. {
  21811. auto elementType = resultType->GetUnderlyingType();
  21812. mModule->PopulateType(elementType);
  21813. if (elementType->IsValuelessType())
  21814. {
  21815. mModule->mBfIRBuilder->PopulateType(resultType);
  21816. BfTypedValue nullableTypedVale = mModule->MakeAddressable(*resultTypedValue);
  21817. BfIRValue hasValuePtr = mModule->mBfIRBuilder->CreateInBoundsGEP(nullableTypedVale.mValue, 0, 1);
  21818. BfIRValue hasValueValue = mModule->mBfIRBuilder->CreateAlignedLoad(hasValuePtr, 1);
  21819. if (isEquality)
  21820. hasValueValue = mModule->mBfIRBuilder->CreateNot(hasValueValue);
  21821. mResult = BfTypedValue(hasValueValue, boolType);
  21822. }
  21823. else
  21824. {
  21825. mModule->mBfIRBuilder->PopulateType(resultType);
  21826. BfTypedValue nullableTypedVale = mModule->MakeAddressable(*resultTypedValue);
  21827. BfIRValue hasValuePtr = mModule->mBfIRBuilder->CreateInBoundsGEP(nullableTypedVale.mValue, 0, 2);
  21828. BfIRValue hasValueValue = mModule->mBfIRBuilder->CreateAlignedLoad(hasValuePtr, 1);
  21829. if (isEquality)
  21830. hasValueValue = mModule->mBfIRBuilder->CreateNot(hasValueValue);
  21831. mResult = BfTypedValue(hasValueValue, boolType);
  21832. }
  21833. return;
  21834. }
  21835. if (resultType->IsNull())
  21836. {
  21837. // Null always equals null
  21838. mResult = BfTypedValue(mModule->GetConstValue(isEquality ? 1 : 0, boolType), boolType);
  21839. return;
  21840. }
  21841. if (!mModule->IsInSpecializedSection())
  21842. {
  21843. //CS0472: The result of the expression is always 'true' since a value of type 'int' is never equal to 'null' of type '<null>'
  21844. mModule->Warn(BfWarning_CS0472_ValueTypeNullCompare,
  21845. StrFormat("The result of the expression is always '%s' since a value of type '%s' can never be null",
  21846. isEquality ? "false" : "true", mModule->TypeToString(resultType).c_str()), otherTypeSrc);
  21847. }
  21848. // Valuetypes never equal null
  21849. mResult = BfTypedValue(mModule->GetConstValue(isEquality ? 0 : 1, boolType), boolType);
  21850. return;
  21851. }
  21852. }
  21853. // Check for constant equality checks (mostly for strings)
  21854. if (BfBinOpEqualityCheck(binaryOp))
  21855. {
  21856. auto leftConstant = mModule->mBfIRBuilder->GetConstant(leftValue.mValue);
  21857. auto rightConstant = mModule->mBfIRBuilder->GetConstant(rightValue.mValue);
  21858. if ((leftConstant != NULL) && (rightConstant != NULL))
  21859. {
  21860. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  21861. int leftStringPoolIdx = mModule->GetStringPoolIdx(leftValue.mValue, mModule->mBfIRBuilder);
  21862. if (leftStringPoolIdx != -1)
  21863. {
  21864. int rightStringPoolIdx = mModule->GetStringPoolIdx(rightValue.mValue, mModule->mBfIRBuilder);
  21865. if (rightStringPoolIdx != -1)
  21866. {
  21867. bool isEqual = leftStringPoolIdx == rightStringPoolIdx;
  21868. if ((binaryOp == BfBinaryOp_InEquality) || (binaryOp == BfBinaryOp_StrictInEquality))
  21869. isEqual = !isEqual;
  21870. mResult = BfTypedValue(mModule->GetConstValue(isEqual ? 1 : 0, boolType), boolType);
  21871. return;
  21872. }
  21873. }
  21874. int eqResult = mModule->mBfIRBuilder->CheckConstEquality(leftValue.mValue, rightValue.mValue);
  21875. if (eqResult != -1)
  21876. {
  21877. bool isEqual = eqResult == 1;
  21878. if ((binaryOp == BfBinaryOp_InEquality) || (binaryOp == BfBinaryOp_StrictInEquality))
  21879. isEqual = !isEqual;
  21880. mResult = BfTypedValue(mModule->GetConstValue(isEqual ? 1 : 0, boolType), boolType);
  21881. return;
  21882. }
  21883. }
  21884. }
  21885. if ((leftValue.mType->IsTypeInstance()) || (leftValue.mType->IsGenericParam()) ||
  21886. (rightValue.mType->IsTypeInstance()) || (rightValue.mType->IsGenericParam()))
  21887. {
  21888. // As an optimization, we don't call user operator overloads for null checks
  21889. bool skipOpOverload = false;
  21890. if ((binaryOp == BfBinaryOp_StrictEquality) || (binaryOp == BfBinaryOp_StrictInEquality))
  21891. skipOpOverload = true;
  21892. else if (BfBinOpEqualityCheck(binaryOp))
  21893. {
  21894. if (!leftValue.IsAddr())
  21895. {
  21896. auto leftConstant = mModule->mBfIRBuilder->GetConstant(leftValue.mValue);
  21897. if ((leftConstant != NULL) && (leftConstant->IsNull()))
  21898. skipOpOverload = true;
  21899. }
  21900. if (!rightValue.IsAddr())
  21901. {
  21902. auto rightConstant = mModule->mBfIRBuilder->GetConstant(rightValue.mValue);
  21903. if ((rightConstant != NULL) && (rightConstant->IsNull()))
  21904. skipOpOverload = true;
  21905. }
  21906. }
  21907. if ((binaryOp == BfBinaryOp_Add) && (resultType->IsInstanceOf(mModule->mCompiler->mStringTypeDef)))
  21908. {
  21909. // Allow failover to constant string addition
  21910. if ((leftValue.mValue.IsConst()) && (rightValue.mValue.IsConst()))
  21911. skipOpOverload = true;
  21912. }
  21913. if (!skipOpOverload)
  21914. {
  21915. BfBinaryOp findBinaryOp = binaryOp;
  21916. bool isComparison = (binaryOp >= BfBinaryOp_Equality) && (binaryOp <= BfBinaryOp_LessThanOrEqual);
  21917. for (int pass = 0; pass < 2; pass++)
  21918. {
  21919. BfBinaryOp oppositeBinaryOp = BfGetOppositeBinaryOp(findBinaryOp);
  21920. BfBinaryOp overflowBinaryOp = BfBinaryOp_None;
  21921. if (findBinaryOp == BfBinaryOp_OverflowAdd)
  21922. overflowBinaryOp = BfBinaryOp_Add;
  21923. else if (findBinaryOp == BfBinaryOp_OverflowSubtract)
  21924. overflowBinaryOp = BfBinaryOp_Subtract;
  21925. else if (findBinaryOp == BfBinaryOp_OverflowMultiply)
  21926. overflowBinaryOp = BfBinaryOp_Multiply;
  21927. bool foundOp = false;
  21928. BfResolvedArg leftArg;
  21929. leftArg.mExpression = leftExpression;
  21930. leftArg.mTypedValue = leftValue;
  21931. BfResolvedArg rightArg;
  21932. rightArg.mExpression = rightExpression;
  21933. rightArg.mTypedValue = rightValue;
  21934. if (deferRight)
  21935. {
  21936. BfResolvedArgs argValues;
  21937. SizedArray<BfExpression*, 2> argExprs;
  21938. argExprs.push_back(BfNodeDynCast<BfExpression>(rightExpression));
  21939. BfSizedArray<BfExpression*> sizedArgExprs(argExprs);
  21940. argValues.Init(&sizedArgExprs);
  21941. ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval);
  21942. rightArg = argValues.mResolvedArgs[0];
  21943. }
  21944. SizedArray<BfResolvedArg, 2> args;
  21945. if (pass == 0)
  21946. {
  21947. args.push_back(leftArg);
  21948. args.push_back(rightArg);
  21949. }
  21950. else
  21951. {
  21952. args.push_back(rightArg);
  21953. args.push_back(leftArg);
  21954. }
  21955. auto checkLeftType = leftValue.mType;
  21956. auto checkRightType = rightValue.mType;
  21957. BfMethodMatcher methodMatcher(opToken, mModule, "", args, BfMethodGenericArguments());
  21958. methodMatcher.mAllowImplicitRef = true;
  21959. methodMatcher.mBfEvalExprFlags = BfEvalExprFlags_NoAutoComplete;
  21960. BfBaseClassWalker baseClassWalker(checkLeftType, checkRightType, mModule);
  21961. bool invertResult = false;
  21962. BfType* operatorConstraintReturnType = NULL;
  21963. bool wasTransformedUsage = (pass == 1);
  21964. while (true)
  21965. {
  21966. auto entry = baseClassWalker.Next();
  21967. auto checkType = entry.mTypeInstance;
  21968. if (checkType == NULL)
  21969. break;
  21970. bool foundExactMatch = false;
  21971. SizedArray<BfOperatorDef*, 8> oppositeOperatorDefs;
  21972. for (auto operatorDef : checkType->mTypeDef->mOperators)
  21973. {
  21974. bool allowOp = operatorDef->mOperatorDeclaration->mBinOp == findBinaryOp;
  21975. if ((isComparison) && (operatorDef->mOperatorDeclaration->mBinOp == BfBinaryOp_Compare))
  21976. allowOp = true;
  21977. if (allowOp)
  21978. {
  21979. foundOp = true;
  21980. if (!methodMatcher.IsMemberAccessible(checkType, operatorDef->mDeclaringType))
  21981. continue;
  21982. if ((flags & BfBinOpFlag_IsConstraintCheck) != 0)
  21983. {
  21984. if (operatorDef->mGenericParams.IsEmpty())
  21985. {
  21986. // Fast check
  21987. auto returnType = mModule->CheckOperator(checkType, operatorDef, args[0].mTypedValue, args[1].mTypedValue);
  21988. if (returnType != NULL)
  21989. {
  21990. operatorConstraintReturnType = returnType;
  21991. methodMatcher.mBestMethodDef = operatorDef;
  21992. methodMatcher.mBestMethodTypeInstance = checkType;
  21993. foundExactMatch = true;
  21994. }
  21995. }
  21996. else
  21997. {
  21998. if (methodMatcher.CheckMethod(NULL, checkType, operatorDef, false))
  21999. {
  22000. auto rawMethodInstance = mModule->GetRawMethodInstance(checkType, operatorDef);
  22001. auto returnType = mModule->ResolveGenericType(rawMethodInstance->mReturnType, NULL, &methodMatcher.mBestMethodGenericArguments,
  22002. mModule->mCurTypeInstance);
  22003. if (returnType != NULL)
  22004. {
  22005. operatorConstraintReturnType = returnType;
  22006. foundExactMatch = true;
  22007. }
  22008. }
  22009. }
  22010. }
  22011. else
  22012. {
  22013. if (methodMatcher.CheckMethod(NULL, checkType, operatorDef, false))
  22014. {
  22015. methodMatcher.mSelfType = entry.mSrcType;
  22016. if (operatorDef->mOperatorDeclaration->mBinOp == findBinaryOp)
  22017. foundExactMatch = true;
  22018. }
  22019. }
  22020. }
  22021. else if ((operatorDef->mOperatorDeclaration->mBinOp == oppositeBinaryOp) || (operatorDef->mOperatorDeclaration->mBinOp == overflowBinaryOp))
  22022. oppositeOperatorDefs.Add(operatorDef);
  22023. }
  22024. if ((((methodMatcher.mBestMethodDef == NULL) && (operatorConstraintReturnType == NULL)) || (!foundExactMatch)) && (!oppositeOperatorDefs.IsEmpty()))
  22025. {
  22026. foundOp = true;
  22027. for (auto oppositeOperatorDef : oppositeOperatorDefs)
  22028. {
  22029. if ((flags & BfBinOpFlag_IsConstraintCheck) != 0)
  22030. {
  22031. if (oppositeOperatorDef->mGenericParams.IsEmpty())
  22032. {
  22033. // Fast check
  22034. auto returnType = mModule->CheckOperator(checkType, oppositeOperatorDef, args[0].mTypedValue, args[1].mTypedValue);
  22035. if (returnType != NULL)
  22036. {
  22037. operatorConstraintReturnType = returnType;
  22038. methodMatcher.mBestMethodDef = oppositeOperatorDef;
  22039. methodMatcher.mBestMethodTypeInstance = checkType;
  22040. methodMatcher.mSelfType = entry.mSrcType;
  22041. if (oppositeBinaryOp != BfBinaryOp_None)
  22042. wasTransformedUsage = true;
  22043. }
  22044. }
  22045. else
  22046. {
  22047. if (methodMatcher.CheckMethod(NULL, checkType, oppositeOperatorDef, false))
  22048. {
  22049. auto rawMethodInstance = mModule->GetRawMethodInstance(checkType, oppositeOperatorDef);
  22050. auto returnType = mModule->ResolveGenericType(rawMethodInstance->mReturnType, NULL, &methodMatcher.mBestMethodGenericArguments,
  22051. mModule->mCurTypeInstance);
  22052. if (returnType != NULL)
  22053. {
  22054. operatorConstraintReturnType = returnType;
  22055. methodMatcher.mSelfType = entry.mSrcType;
  22056. if (oppositeBinaryOp != BfBinaryOp_None)
  22057. wasTransformedUsage = true;
  22058. }
  22059. }
  22060. }
  22061. }
  22062. else
  22063. {
  22064. if (methodMatcher.CheckMethod(NULL, checkType, oppositeOperatorDef, false))
  22065. {
  22066. methodMatcher.mSelfType = entry.mSrcType;
  22067. if (oppositeBinaryOp != BfBinaryOp_None)
  22068. wasTransformedUsage = true;
  22069. }
  22070. }
  22071. }
  22072. }
  22073. }
  22074. bool hadMatch = (methodMatcher.mBestMethodDef != NULL);
  22075. if ((methodMatcher.mBestMethodDef != NULL) && ((flags & BfBinOpFlag_IgnoreOperatorWithWrongResult) != 0))
  22076. {
  22077. auto matchedOp = ((BfOperatorDeclaration*)methodMatcher.mBestMethodDef->mMethodDeclaration)->mBinOp;
  22078. methodMatcher.mBestMethodInstance = GetSelectedMethod(methodMatcher.mTargetSrc, methodMatcher.mBestMethodTypeInstance, methodMatcher.mBestMethodDef, methodMatcher);
  22079. if ((methodMatcher.mBestMethodInstance.mMethodInstance->mReturnType != mExpectingType) &&
  22080. ((matchedOp == binaryOp) || (matchedOp == oppositeBinaryOp)))
  22081. {
  22082. if (binaryOp == BfBinaryOp_Equality)
  22083. binaryOp = BfBinaryOp_StrictEquality;
  22084. if (binaryOp == BfBinaryOp_InEquality)
  22085. binaryOp = BfBinaryOp_StrictEquality;
  22086. hadMatch = false;
  22087. break;
  22088. }
  22089. }
  22090. if (hadMatch)
  22091. {
  22092. methodMatcher.FlushAmbiguityError();
  22093. auto matchedOp = ((BfOperatorDeclaration*)methodMatcher.mBestMethodDef->mMethodDeclaration)->mBinOp;
  22094. bool invertResult = matchedOp == oppositeBinaryOp;
  22095. auto methodDef = methodMatcher.mBestMethodDef;
  22096. auto autoComplete = GetAutoComplete();
  22097. bool wasCapturingMethodInfo = false;
  22098. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(opToken)))
  22099. {
  22100. auto operatorDecl = BfNodeDynCast<BfOperatorDeclaration>(methodDef->mMethodDeclaration);
  22101. if ((operatorDecl != NULL) && (operatorDecl->mOpTypeToken != NULL))
  22102. autoComplete->SetDefinitionLocation(operatorDecl->mOpTypeToken);
  22103. }
  22104. if ((wasTransformedUsage) && (methodDef->mCommutableKind != BfCommutableKind_Operator))
  22105. {
  22106. auto error = mModule->Warn(BfWarning_BF4206_OperatorCommutableUsage, "Transformed operator usage requires 'Commutable' attribute to be added to the operator declaration", opToken);
  22107. if ((error != NULL) && (methodDef->GetRefNode() != NULL))
  22108. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See operator declaration"), methodDef->GetRefNode());
  22109. }
  22110. if (opToken != NULL)
  22111. {
  22112. if ((opToken->IsA<BfTokenNode>()) && (!noClassify) && (!baseClassWalker.mMayBeFromInterface))
  22113. mModule->SetElementType(opToken, BfSourceElementType_Method);
  22114. }
  22115. if ((flags & BfBinOpFlag_IsConstraintCheck) != 0)
  22116. {
  22117. mResult = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), operatorConstraintReturnType);
  22118. }
  22119. else
  22120. {
  22121. SetAndRestoreValue<BfEvalExprFlags> prevFlags(mBfEvalExprFlags, (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_NoAutoComplete));
  22122. mResult = CreateCall(&methodMatcher, BfTypedValue());
  22123. }
  22124. if ((mResult.mType != NULL) && (methodMatcher.mSelfType != NULL) && (mResult.mType->IsSelf()))
  22125. {
  22126. BF_ASSERT(mModule->IsInGeneric());
  22127. mResult = mModule->GetDefaultTypedValue(methodMatcher.mSelfType, false, BfDefaultValueKind_Value);
  22128. }
  22129. if ((invertResult) && (mResult.mType == mModule->GetPrimitiveType(BfTypeCode_Boolean)))
  22130. mResult.mValue = mModule->mBfIRBuilder->CreateNot(mResult.mValue);
  22131. if (pass == 1)
  22132. {
  22133. if (findBinaryOp == BfBinaryOp_Compare)
  22134. {
  22135. mResult = mModule->LoadValue(mResult);
  22136. if (mResult.mType->IsIntegral())
  22137. mResult.mValue = mModule->mBfIRBuilder->CreateNeg(mResult.mValue);
  22138. }
  22139. }
  22140. if ((isComparison) && (matchedOp == BfBinaryOp_Compare))
  22141. {
  22142. auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  22143. mResult = mModule->LoadValue(mResult);
  22144. if (mResult.mType != intType)
  22145. mResult = mModule->GetDefaultTypedValue(intType);
  22146. auto zeroVal = mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0);
  22147. auto useBinaryOp = binaryOp;
  22148. if (pass == 1)
  22149. useBinaryOp = BfGetFlippedBinaryOp(useBinaryOp);
  22150. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  22151. switch (useBinaryOp)
  22152. {
  22153. case BfBinaryOp_Equality:
  22154. case BfBinaryOp_StrictEquality:
  22155. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(mResult.mValue, zeroVal), boolType);
  22156. break;
  22157. case BfBinaryOp_InEquality:
  22158. case BfBinaryOp_StrictInEquality:
  22159. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(mResult.mValue, zeroVal), boolType);
  22160. break;
  22161. case BfBinaryOp_GreaterThan:
  22162. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpGT(mResult.mValue, zeroVal, true), boolType);
  22163. break;
  22164. case BfBinaryOp_LessThan:
  22165. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpLT(mResult.mValue, zeroVal, true), boolType);
  22166. break;
  22167. case BfBinaryOp_GreaterThanOrEqual:
  22168. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpGTE(mResult.mValue, zeroVal, true), boolType);
  22169. break;
  22170. case BfBinaryOp_LessThanOrEqual:
  22171. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpLTE(mResult.mValue, zeroVal, true), boolType);
  22172. break;
  22173. default: break;
  22174. }
  22175. }
  22176. return;
  22177. }
  22178. auto _CheckBinaryOp = [&](BfGenericParamInstance* genericParam)
  22179. {
  22180. for (auto& opConstraint : genericParam->mOperatorConstraints)
  22181. {
  22182. BfType* returnType = genericParam->mExternType;
  22183. bool works = false;
  22184. if (opConstraint.mBinaryOp == findBinaryOp)
  22185. {
  22186. if (((args[0].mTypedValue) && (mModule->CanCast(args[0].mTypedValue, opConstraint.mLeftType))) &&
  22187. ((args[1].mTypedValue) && (mModule->CanCast(args[1].mTypedValue, opConstraint.mRightType))))
  22188. {
  22189. works = true;
  22190. }
  22191. }
  22192. if ((isComparison) && (opConstraint.mBinaryOp == BfBinaryOp_Compare))
  22193. {
  22194. if (((args[0].mTypedValue) && (mModule->CanCast(args[0].mTypedValue, opConstraint.mLeftType))) &&
  22195. ((args[1].mTypedValue) && (mModule->CanCast(args[1].mTypedValue, opConstraint.mRightType))))
  22196. {
  22197. works = true;
  22198. }
  22199. else if (((args[0].mTypedValue) && (mModule->CanCast(args[0].mTypedValue, opConstraint.mRightType))) &&
  22200. ((args[1].mTypedValue) && (mModule->CanCast(args[1].mTypedValue, opConstraint.mLeftType))))
  22201. {
  22202. works = true;
  22203. }
  22204. if (works)
  22205. {
  22206. returnType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  22207. }
  22208. }
  22209. if (works)
  22210. {
  22211. BF_ASSERT(genericParam->mExternType != NULL);
  22212. mResult = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), returnType);
  22213. return true;
  22214. }
  22215. }
  22216. return false;
  22217. };
  22218. // Check method generic constraints
  22219. if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsUnspecialized) && (mModule->mCurMethodInstance->mMethodInfoEx != NULL))
  22220. {
  22221. for (int genericParamIdx = 0; genericParamIdx < mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams.size(); genericParamIdx++)
  22222. {
  22223. auto genericParam = mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
  22224. if (_CheckBinaryOp(genericParam))
  22225. return;
  22226. }
  22227. }
  22228. // Check type generic constraints
  22229. if ((mModule->mCurTypeInstance->IsGenericTypeInstance()) && (mModule->mCurTypeInstance->IsUnspecializedType()))
  22230. {
  22231. SizedArray<BfGenericParamInstance*, 4> genericParams;
  22232. mModule->GetActiveTypeGenericParamInstances(genericParams);
  22233. for (auto genericParam : genericParams)
  22234. {
  22235. if (_CheckBinaryOp(genericParam))
  22236. return;
  22237. }
  22238. }
  22239. if (pass == 1)
  22240. break;
  22241. auto flippedBinaryOp = BfGetFlippedBinaryOp(findBinaryOp);
  22242. if (flippedBinaryOp != BfBinaryOp_None)
  22243. findBinaryOp = flippedBinaryOp;
  22244. }
  22245. auto _FixOpCheckGenericParam = [&](BfTypedValue& typedVal)
  22246. {
  22247. if ((typedVal.mType != NULL) && (typedVal.mType->IsGenericParam()))
  22248. {
  22249. auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)typedVal.mType);
  22250. if (genericParamInstance->mTypeConstraint != NULL)
  22251. {
  22252. typedVal.mType = genericParamInstance->mTypeConstraint;
  22253. return true;
  22254. }
  22255. }
  22256. return false;
  22257. };
  22258. auto leftTypeConstraint = mModule->GetGenericParamInstanceTypeConstraint(leftValue.mType);
  22259. auto rightTypeConstraint = mModule->GetGenericParamInstanceTypeConstraint(rightValue.mType);
  22260. if ((leftTypeConstraint != NULL) || (rightTypeConstraint != NULL))
  22261. {
  22262. // Handle cases such as 'where T : float'
  22263. bool needNewCheck = false;
  22264. BfTypedValue newLeftValue = leftValue;
  22265. if ((leftTypeConstraint != NULL) && (!leftTypeConstraint->IsGenericParam()))
  22266. {
  22267. newLeftValue.mType = leftTypeConstraint;
  22268. needNewCheck = true;
  22269. }
  22270. BfTypedValue newRightValue = rightValue;
  22271. if ((rightTypeConstraint != NULL) && (!rightTypeConstraint->IsGenericParam()))
  22272. {
  22273. newRightValue.mType = rightTypeConstraint;
  22274. needNewCheck = true;
  22275. }
  22276. if (needNewCheck)
  22277. {
  22278. PerformBinaryOperation(leftExpression, rightExpression, binaryOp, opToken, flags, newLeftValue, newRightValue);
  22279. EnsureResultNotConstant();
  22280. return;
  22281. }
  22282. }
  22283. bool resultHandled = false;
  22284. if (((origLeftType != NULL) && (origLeftType->IsIntUnknown())) ||
  22285. ((origRightType != NULL) && (origRightType->IsIntUnknown())))
  22286. {
  22287. if (!resultType->IsPrimitiveType())
  22288. {
  22289. BfType* numericCastType = mModule->GetClosestNumericCastType(*resultTypedValue, mExpectingType);
  22290. if (numericCastType != NULL)
  22291. {
  22292. resultHandled = true;
  22293. resultType = numericCastType;
  22294. }
  22295. }
  22296. }
  22297. if (!resultHandled)
  22298. {
  22299. auto prevResultType = resultType;
  22300. if ((leftValue.mType->IsPrimitiveType()) && (!origLeftType->IsIntUnknown()) && (!rightValue.mType->IsTypedPrimitive()))
  22301. resultType = leftValue.mType;
  22302. if ((rightValue.mType->IsPrimitiveType()) && (!origRightType->IsIntUnknown()) && (!leftValue.mType->IsTypedPrimitive()))
  22303. resultType = rightValue.mType;
  22304. }
  22305. }
  22306. }
  22307. if (deferRight)
  22308. {
  22309. auto expectedType = resultType;
  22310. if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift))
  22311. expectedType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  22312. rightValue = mModule->CreateValueFromExpression(BfNodeDynCast<BfExpression>(rightExpression), expectedType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_AllowSplat | BfEvalExprFlags_NoCast));
  22313. if (rightValue)
  22314. PerformBinaryOperation(leftExpression, rightExpression, binaryOp, opToken, (BfBinOpFlags)(flags & ~BfBinOpFlag_DeferRight), leftValue, rightValue);
  22315. return;
  22316. }
  22317. if (mModule->IsUnboundGeneric(resultType))
  22318. {
  22319. mResult = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Var));
  22320. return;
  22321. }
  22322. if (resultType->IsPointer() && otherType->IsPointer())
  22323. {
  22324. if ((binaryOp == BfBinaryOp_Add) && (resultType == otherType) &&
  22325. (resultType->GetUnderlyingType() == mModule->GetPrimitiveType(BfTypeCode_Char8)))
  22326. {
  22327. AddStrings(leftValue, rightValue, opToken);
  22328. return;
  22329. }
  22330. //TODO: Allow all pointer comparisons, but only allow SUBTRACTION between equal pointer types
  22331. if ((binaryOp == BfBinaryOp_Subtract) || (binaryOp == BfBinaryOp_OverflowSubtract))
  22332. {
  22333. if (!mModule->CanCast(*otherTypedValue, resultType))
  22334. {
  22335. mModule->Fail(StrFormat("Operands '%s' and '%s' are not comparable types.",
  22336. mModule->TypeToString(leftValue.mType).c_str(), mModule->TypeToString(rightValue.mType).c_str()),
  22337. opToken);
  22338. return;
  22339. }
  22340. BfPointerType* resultPointerType = (BfPointerType*)resultType;
  22341. BfType* intPtrType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  22342. if (resultPointerType->mElementType->mSize == 0)
  22343. {
  22344. if (!mModule->IsInSpecializedSection())
  22345. mModule->Warn(0, "Subtracting pointers to zero-sized elements will always result in zero", opToken);
  22346. mResult = mModule->GetDefaultTypedValue(intPtrType);
  22347. }
  22348. else
  22349. {
  22350. convLeftValue = mModule->CastToValue(leftExpression, leftValue, intPtrType, (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_FromCompiler));
  22351. convRightValue = mModule->CastToValue(rightExpression, rightValue, intPtrType, (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_FromCompiler));
  22352. BfIRValue diffValue = mModule->mBfIRBuilder->CreateSub(convLeftValue, convRightValue);
  22353. diffValue = mModule->mBfIRBuilder->CreateDiv(diffValue, mModule->GetConstValue(resultPointerType->mElementType->GetStride(), intPtrType), true);
  22354. mResult = BfTypedValue(diffValue, intPtrType);
  22355. }
  22356. return;
  22357. }
  22358. else if ((binaryOp != BfBinaryOp_Equality) && (binaryOp != BfBinaryOp_StrictEquality) &&
  22359. (binaryOp != BfBinaryOp_InEquality) && (binaryOp != BfBinaryOp_StrictInEquality) &&
  22360. (binaryOp != BfBinaryOp_LessThan) && (binaryOp != BfBinaryOp_LessThanOrEqual) &&
  22361. (binaryOp != BfBinaryOp_GreaterThan) && (binaryOp != BfBinaryOp_GreaterThanOrEqual))
  22362. {
  22363. if (mModule->PreFail())
  22364. mModule->Fail("Invalid operation on pointers", opToken);
  22365. return;
  22366. }
  22367. if ((!BfBinOpEqualityCheck(binaryOp)) || (resultType != otherType))
  22368. {
  22369. resultType = mModule->GetPrimitiveType(BfTypeCode_UIntPtr);
  22370. explicitCast = true;
  22371. }
  22372. }
  22373. else if (resultType->IsPointer())
  22374. {
  22375. if (otherType->IsNull())
  22376. {
  22377. if (!BfBinOpEqualityCheck(binaryOp))
  22378. {
  22379. if (mModule->PreFail())
  22380. mModule->Fail(StrFormat("Invalid operation between '%s' and null", mModule->TypeToString(resultType).c_str()), opToken);
  22381. return;
  22382. }
  22383. if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality))
  22384. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateIsNull(resultTypedValue->mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  22385. else
  22386. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateIsNotNull(resultTypedValue->mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  22387. return;
  22388. }
  22389. // One pointer
  22390. if ((!otherType->IsIntegral()) ||
  22391. ((binaryOp != BfBinaryOp_Add) && (binaryOp != BfBinaryOp_Subtract) && (binaryOp != BfBinaryOp_OverflowAdd) && (binaryOp != BfBinaryOp_OverflowSubtract)))
  22392. {
  22393. _OpFail();
  22394. return;
  22395. }
  22396. auto underlyingType = resultType->GetUnderlyingType();
  22397. if ((underlyingType->IsSizedArray()) && (!mModule->IsInSpecializedSection()))
  22398. 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);
  22399. BfIRValue addValue = otherTypedValue->mValue;
  22400. if ((!otherTypedValue->mType->IsSigned()) && (otherTypedValue->mType->mSize < mModule->mSystem->mPtrSize))
  22401. addValue = mModule->mBfIRBuilder->CreateNumericCast(addValue, false, BfTypeCode_UIntPtr);
  22402. if ((binaryOp == BfBinaryOp_Subtract) || (binaryOp == BfBinaryOp_OverflowSubtract))
  22403. {
  22404. if (resultTypeSrc == rightExpression)
  22405. mModule->Fail("Cannot subtract a pointer from an integer", resultTypeSrc);
  22406. addValue = mModule->mBfIRBuilder->CreateNeg(addValue);
  22407. }
  22408. mModule->PopulateType(underlyingType);
  22409. if (underlyingType->IsValuelessType())
  22410. {
  22411. if (!mModule->IsInSpecializedSection())
  22412. mModule->Warn(0, "Adding to a pointer to a zero-sized element has no effect", opToken);
  22413. mResult = *resultTypedValue;
  22414. return;
  22415. }
  22416. mModule->mBfIRBuilder->PopulateType(underlyingType);
  22417. mResult = BfTypedValue(mModule->CreateIndexedValue(underlyingType, resultTypedValue->mValue, addValue), resultType);
  22418. return;
  22419. }
  22420. if ((resultType->IsFunction()) || (resultType->IsPointer()) || (resultType->IsObject()) || (resultType->IsInterface()) || (resultType->IsGenericParam()))
  22421. {
  22422. if ((binaryOp == BfBinaryOp_Add) &&
  22423. (resultType->IsInstanceOf(mModule->mCompiler->mStringTypeDef)) &&
  22424. (otherType->IsInstanceOf(mModule->mCompiler->mStringTypeDef)))
  22425. {
  22426. AddStrings(leftValue, rightValue, opToken);
  22427. return;
  22428. }
  22429. if (!BfGetBinaryOpPrecendence(binaryOp))
  22430. {
  22431. //mModule->Fail("Invalid operation for objects", opToken);
  22432. _OpFail();
  22433. return;
  22434. }
  22435. if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality) || (binaryOp == BfBinaryOp_InEquality) || (binaryOp == BfBinaryOp_StrictInEquality))
  22436. {
  22437. leftValue = mModule->LoadOrAggregateValue(leftValue);
  22438. rightValue = mModule->LoadOrAggregateValue(rightValue);
  22439. if (resultType->IsInterface())
  22440. {
  22441. // Compare as objects instead
  22442. resultType = mModule->mContext->mBfObjectType;
  22443. *resultTypedValue = mModule->Cast(resultTypeSrc, *resultTypedValue, resultType);
  22444. }
  22445. if (otherType->IsNull())
  22446. {
  22447. if (resultType->IsFunction())
  22448. {
  22449. if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality))
  22450. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0), resultTypedValue->mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  22451. else
  22452. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0), resultTypedValue->mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  22453. }
  22454. else
  22455. {
  22456. if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality))
  22457. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateIsNull(resultTypedValue->mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  22458. else
  22459. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateIsNotNull(resultTypedValue->mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  22460. }
  22461. }
  22462. else
  22463. {
  22464. auto convertedValue = mModule->Cast(otherTypeSrc, *otherTypedValue, resultType, BfCastFlags_NoBox);
  22465. if (!convertedValue)
  22466. return;
  22467. convertedValue = mModule->LoadValue(convertedValue);
  22468. if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality))
  22469. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(resultTypedValue->mValue, convertedValue.mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  22470. else
  22471. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(resultTypedValue->mValue, convertedValue.mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  22472. }
  22473. return;
  22474. }
  22475. }
  22476. if (resultType->IsTypedPrimitive())
  22477. {
  22478. bool needsOtherCast = true;
  22479. if (otherType != resultType)
  22480. {
  22481. if ((otherType->IsPrimitiveType()) && (!otherType->IsValuelessType()))
  22482. {
  22483. // Allow zero comparisons to match all typed primitives
  22484. if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_InEquality))
  22485. {
  22486. auto constant = mModule->mBfIRBuilder->GetConstant(otherTypedValue->mValue);
  22487. if ((constant != NULL) && (mModule->mBfIRBuilder->IsInt(constant->mTypeCode)) && (constant->mInt64 == 0))
  22488. needsOtherCast = false;
  22489. }
  22490. // Allow integer offsetting
  22491. if ((binaryOp == BfBinaryOp_Add) || (binaryOp == BfBinaryOp_Subtract) || (binaryOp == BfBinaryOp_OverflowAdd) || (binaryOp == BfBinaryOp_OverflowSubtract))
  22492. {
  22493. if (otherType->IsIntegral())
  22494. needsOtherCast = false;
  22495. }
  22496. }
  22497. if (needsOtherCast)
  22498. {
  22499. BfCastFlags castFlags = (BfCastFlags)((explicitCast ? BfCastFlags_Explicit : BfCastFlags_None) | BfCastFlags_SilentFail);
  22500. BfIRValue otherCastResult = mModule->CastToValue(otherTypeSrc, *otherTypedValue, resultType, castFlags);
  22501. if (!otherCastResult)
  22502. {
  22503. // We picked the wrong type, try the other one...
  22504. if (mModule->CanCast(*resultTypedValue, otherType))
  22505. {
  22506. BfBinOpFlags newFlags = flags;
  22507. if (otherTypedValue == &leftValue)
  22508. newFlags = (BfBinOpFlags)(flags | BfBinOpFlag_ForceLeftType & ~BfBinOpFlag_ForceRightType & ~BfBinOpFlag_DeferRight);
  22509. else
  22510. newFlags = (BfBinOpFlags)(flags | BfBinOpFlag_ForceRightType & ~BfBinOpFlag_ForceLeftType & ~BfBinOpFlag_DeferRight);
  22511. return PerformBinaryOperation(leftExpression, rightExpression, binaryOp, opToken, newFlags, leftValue, rightValue);
  22512. }
  22513. // Do again but with an error
  22514. castFlags = (BfCastFlags)(castFlags & ~BfCastFlags_SilentFail);
  22515. otherCastResult = mModule->CastToValue(otherTypeSrc, *otherTypedValue, resultType, castFlags);
  22516. }
  22517. }
  22518. }
  22519. auto underlyingType = resultType->GetUnderlyingType();
  22520. if ((binaryOp == BfBinaryOp_Subtract) && (otherTypedValue->mType == resultType))
  22521. {
  22522. intptr maxDist = 0;
  22523. auto resultTypeInstance = resultType->ToTypeInstance();
  22524. if ((resultTypeInstance != NULL) && (resultTypeInstance->mTypeInfoEx != NULL))
  22525. maxDist = resultTypeInstance->mTypeInfoEx->mMaxValue - resultTypeInstance->mTypeInfoEx->mMinValue;
  22526. if (maxDist >= 0x80000000UL)
  22527. resultType = mModule->GetPrimitiveType(BfTypeCode_Int64);
  22528. else if (maxDist >= 0x8000)
  22529. resultType = mModule->GetPrimitiveType(BfTypeCode_Int32);
  22530. else if (maxDist >= 0x80)
  22531. resultType = mModule->GetPrimitiveType(BfTypeCode_Int16);
  22532. else
  22533. resultType = mModule->GetPrimitiveType(BfTypeCode_Int8);
  22534. underlyingType = resultType;
  22535. }
  22536. BfIRValue convResultValue;
  22537. if (resultTypedValue->mType == resultType)
  22538. convResultValue = mModule->LoadValue(*resultTypedValue).mValue;
  22539. else
  22540. convResultValue = mModule->CastToValue(resultTypeSrc, *resultTypedValue, underlyingType, BfCastFlags_Explicit);
  22541. BfIRValue convOtherValue;
  22542. if (otherTypedValue->mType == resultType)
  22543. convOtherValue = mModule->LoadValue(*otherTypedValue).mValue;
  22544. else
  22545. convOtherValue = mModule->CastToValue(otherTypeSrc, *otherTypedValue, underlyingType, BfCastFlags_Explicit);
  22546. if ((!underlyingType->IsValuelessType()) && ((!convResultValue) || (!convOtherValue)))
  22547. return;
  22548. if (resultTypedValue == &leftValue)
  22549. PerformBinaryOperation(underlyingType, convResultValue, convOtherValue, binaryOp, opToken);
  22550. else
  22551. PerformBinaryOperation(underlyingType, convOtherValue, convResultValue, binaryOp, opToken);
  22552. if (mResult.mType == underlyingType)
  22553. mResult.mType = resultType;
  22554. return;
  22555. }
  22556. auto _CallValueTypeEquals = [&]()
  22557. {
  22558. BfModuleMethodInstance moduleMethodInstance;
  22559. auto typeInst = leftValue.mType->ToTypeInstance();
  22560. if (typeInst != NULL)
  22561. {
  22562. if ((binaryOp == BfBinaryOp_StrictEquality) || (binaryOp == BfBinaryOp_StrictInEquality))
  22563. moduleMethodInstance = mModule->GetMethodByName(typeInst, BF_METHODNAME_DEFAULT_STRICT_EQUALS);
  22564. else
  22565. moduleMethodInstance = mModule->GetMethodByName(typeInst, BF_METHODNAME_DEFAULT_EQUALS);
  22566. }
  22567. else
  22568. {
  22569. BF_ASSERT(leftValue.mType->IsSizedArray() || leftValue.mType->IsMethodRef());
  22570. auto valueTypeInst = mModule->ResolveTypeDef(mModule->mCompiler->mValueTypeTypeDef)->ToTypeInstance();
  22571. BfMethodDef* equalsMethodDef = mModule->mCompiler->mValueTypeTypeDef->GetMethodByName("Equals");
  22572. BfTypeVector typeVec;
  22573. typeVec.push_back(leftValue.mType);
  22574. moduleMethodInstance = mModule->GetMethodInstance(valueTypeInst, equalsMethodDef, typeVec);
  22575. }
  22576. if (moduleMethodInstance)
  22577. {
  22578. if ((opToken != NULL) && (!noClassify))
  22579. mModule->SetElementType(opToken, BfSourceElementType_Method);
  22580. SizedArray<BfResolvedArg, 4> argValues;
  22581. BfResolvedArg resolvedArg;
  22582. resolvedArg.mTypedValue = leftValue;
  22583. argValues.push_back(resolvedArg);
  22584. resolvedArg.mTypedValue = rightValue;
  22585. argValues.push_back(resolvedArg);
  22586. mResult = CreateCall(opToken, BfTypedValue(), BfTypedValue(), moduleMethodInstance.mMethodInstance->mMethodDef, moduleMethodInstance, BfCreateCallFlags_None, argValues);
  22587. if ((mResult) &&
  22588. ((binaryOp == BfBinaryOp_InEquality) || (binaryOp == BfBinaryOp_StrictInEquality)))
  22589. mResult.mValue = mModule->mBfIRBuilder->CreateNot(mResult.mValue);
  22590. return true;
  22591. }
  22592. return false;
  22593. };
  22594. //if (((leftValue.mType->IsComposite()) || (leftValue.mType->IsObject())))
  22595. if (((resultType->IsComposite()) || (resultType->IsObject())))
  22596. {
  22597. bool areEquivalentTuples = false;
  22598. if ((leftValue.mType->IsTuple()) && (rightValue.mType->IsTuple()))
  22599. {
  22600. auto leftTupleType = (BfTypeInstance*)leftValue.mType;
  22601. auto rightTupleType = (BfTypeInstance*)rightValue.mType;
  22602. // We only do this for tuples, because we would allow an implicit struct
  22603. // truncation if we allow it for all structs, which would result in only
  22604. // the base class's fields being compared
  22605. if (mModule->CanCast(rightValue, leftValue.mType))
  22606. rightValue = mModule->Cast(opToken, rightValue, leftValue.mType, BfCastFlags_Explicit);
  22607. else if (mModule->CanCast(leftValue, rightValue.mType))
  22608. leftValue = mModule->Cast(opToken, leftValue, rightValue.mType, BfCastFlags_Explicit);
  22609. }
  22610. if (leftValue.mType == rightValue.mType)
  22611. {
  22612. if (BfBinOpEqualityCheck(binaryOp))
  22613. {
  22614. auto intCoercibleType = mModule->GetIntCoercibleType(leftValue.mType);
  22615. if (intCoercibleType != NULL)
  22616. {
  22617. auto intLHS = mModule->GetIntCoercible(leftValue);
  22618. auto intRHS = mModule->GetIntCoercible(rightValue);
  22619. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  22620. if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality))
  22621. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(intLHS.mValue, intRHS.mValue), boolType);
  22622. else
  22623. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(intLHS.mValue, intRHS.mValue), boolType);
  22624. return;
  22625. }
  22626. // Valueless types always compare as 'equal' if we can ensure no members could have an equality operator overload
  22627. if (leftValue.mType->IsComposite())
  22628. {
  22629. mModule->PopulateType(leftValue.mType);
  22630. if (leftValue.mType->IsValuelessType())
  22631. {
  22632. bool mayHaveEqualOverload = false;
  22633. auto leftTypeInst = leftValue.mType->ToTypeInstance();
  22634. if (leftTypeInst != NULL)
  22635. {
  22636. std::function<bool(BfType*)> _HasTypeInstance = [&](BfType* type)
  22637. {
  22638. if (type == NULL)
  22639. return false;
  22640. if (type->IsTypeInstance())
  22641. return true;
  22642. if (type->IsSizedArray())
  22643. return _HasTypeInstance(((BfSizedArrayType*)type)->mElementType);
  22644. return false;
  22645. };
  22646. for (auto& fieldInstance : leftTypeInst->mFieldInstances)
  22647. {
  22648. if (_HasTypeInstance(fieldInstance.mResolvedType))
  22649. mayHaveEqualOverload = true;
  22650. }
  22651. }
  22652. if (!mayHaveEqualOverload)
  22653. {
  22654. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  22655. bool isEqual = (binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality);
  22656. mResult = BfTypedValue(mModule->GetConstValue(isEqual ? 1 : 0, boolType), boolType);
  22657. return;
  22658. }
  22659. }
  22660. }
  22661. if (_CallValueTypeEquals())
  22662. return;
  22663. }
  22664. if (PerformBinaryOperation_Numeric(leftExpression, rightExpression, binaryOp, opToken, flags, leftValue, rightValue))
  22665. return;
  22666. if (mModule->PreFail())
  22667. {
  22668. mModule->Fail(StrFormat("Operator '%s' cannot be applied to operands of type '%s'",
  22669. BfGetOpName(binaryOp),
  22670. mModule->TypeToString(leftValue.mType).c_str()), opToken);
  22671. }
  22672. return;
  22673. }
  22674. else
  22675. {
  22676. bool handled = false;
  22677. for (int pass = 0; pass < 2; pass++)
  22678. {
  22679. BfTypedValue& fromValue = (pass == 0) ? leftValue : rightValue;
  22680. BfType* toType = (pass == 0) ? rightValue.mType : leftValue.mType;
  22681. if (mModule->CanCast(fromValue, toType))
  22682. {
  22683. auto result = mModule->Cast(opToken, fromValue, toType);
  22684. if (result)
  22685. {
  22686. resultType = toType;
  22687. fromValue = result;
  22688. handled = true;
  22689. break;
  22690. }
  22691. }
  22692. }
  22693. if (!handled)
  22694. {
  22695. if ((leftValue.mType->IsUndefSizedArray()) || (rightValue.mType->IsUndefSizedArray()))
  22696. {
  22697. if ((leftValue.mType->IsSizedArray()) && (rightValue.mType->IsSizedArray() &&
  22698. (leftValue.mType->GetUnderlyingType() == rightValue.mType->GetUnderlyingType())))
  22699. {
  22700. if (BfBinOpEqualityCheck(binaryOp))
  22701. {
  22702. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  22703. mResult = mModule->GetDefaultTypedValue(boolType, false, BfDefaultValueKind_Undef);
  22704. return;
  22705. }
  22706. }
  22707. }
  22708. if (PerformBinaryOperation_Numeric(leftExpression, rightExpression, binaryOp, opToken, flags, leftValue, rightValue))
  22709. return;
  22710. mModule->Fail(StrFormat("Operator '%s' cannot be applied to operands of type '%s' and '%s'",
  22711. BfGetOpName(binaryOp),
  22712. mModule->TypeToString(leftValue.mType).c_str(),
  22713. mModule->TypeToString(rightValue.mType).c_str()), opToken);
  22714. return;
  22715. }
  22716. }
  22717. }
  22718. if (resultType->IsMethodRef() && otherType->IsMethodRef())
  22719. {
  22720. if (BfBinOpEqualityCheck(binaryOp))
  22721. {
  22722. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  22723. BfMethodRefType* lhsMethodRefType = (BfMethodRefType*)leftValue.mType;
  22724. BfMethodRefType* rhsMethodRefType = (BfMethodRefType*)rightValue.mType;
  22725. if (lhsMethodRefType->mMethodRef != rhsMethodRefType->mMethodRef)
  22726. {
  22727. mResult = BfTypedValue(mModule->GetConstValue(((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality)) ? 0 : 1, boolType), boolType);
  22728. return;
  22729. }
  22730. if (_CallValueTypeEquals())
  22731. return;
  22732. }
  22733. }
  22734. if (resultType->IsIntegral())
  22735. {
  22736. if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift))
  22737. {
  22738. if (rightValue.mValue.IsConst())
  22739. {
  22740. auto constVal = mModule->mBfIRBuilder->GetConstant(rightValue.mValue);
  22741. if ((constVal->mInt64 < 0) || (constVal->mInt64 >= 8 * resultType->mSize))
  22742. {
  22743. mModule->Fail(StrFormat("Shift value '%lld' is out of range for type '%s'", constVal->mInt64, mModule->TypeToString(resultType).c_str()), opToken);
  22744. }
  22745. }
  22746. }
  22747. // We're trying a simplified scheme that doesn't always try to up-convert into an 'int'
  22748. if (leftValue.mType != rightValue.mType)
  22749. {
  22750. bool isBitwiseExpr =
  22751. (binaryOp == BfBinaryOp_BitwiseAnd) ||
  22752. (binaryOp == BfBinaryOp_BitwiseOr) ||
  22753. (binaryOp == BfBinaryOp_ExclusiveOr) ||
  22754. (binaryOp == BfBinaryOp_LeftShift) ||
  22755. (binaryOp == BfBinaryOp_RightShift) ||
  22756. (binaryOp == BfBinaryOp_Equality) ||
  22757. (binaryOp == BfBinaryOp_InEquality) ||
  22758. (binaryOp == BfBinaryOp_StrictEquality) ||
  22759. (binaryOp == BfBinaryOp_StrictInEquality);
  22760. if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift))
  22761. {
  22762. // For shifts we have more lenient rules - shifts are naturally limited so any int type is equally valid
  22763. if (rightValue.mType->IsIntegral())
  22764. explicitCast = true;
  22765. }
  22766. else if (((binaryOp == BfBinaryOp_Add) || (binaryOp == BfBinaryOp_Subtract) || (binaryOp == BfBinaryOp_OverflowAdd) || (binaryOp == BfBinaryOp_OverflowSubtract)) && (resultType->IsChar()) && (otherType->IsInteger()))
  22767. {
  22768. // charVal += intVal;
  22769. explicitCast = true;
  22770. }
  22771. else if ((!resultType->IsSigned()) && (otherType->IsSigned()))
  22772. {
  22773. if (mModule->CanCast(*otherTypedValue, resultType))
  22774. {
  22775. // If we can convert the 'other' value implicitly then it's a convertible literal, leave as uint
  22776. }
  22777. else
  22778. {
  22779. mModule->Fail(StrFormat("Operator cannot be applied to operands of type '%s' and '%s'",
  22780. mModule->TypeToString(leftValue.mType).c_str(),
  22781. mModule->TypeToString(rightValue.mType).c_str()), opToken);
  22782. return;
  22783. }
  22784. }
  22785. else if ((isBitwiseExpr) && (otherType->IsIntegral()) && (resultType->mSize == otherType->mSize))
  22786. {
  22787. // Forget about signed/unsigned mismatches for bitwise operations
  22788. explicitCast = true;
  22789. }
  22790. else
  22791. {
  22792. if (((binaryOp == BfBinaryOp_Subtract) || (binaryOp == BfBinaryOp_OverflowSubtract)) &&
  22793. (resultType->IsChar()) && (otherType->IsChar()))
  22794. {
  22795. // "wchar - char" subtraction will always fit into int32, because of unicode range
  22796. resultType = mModule->GetPrimitiveType(BfTypeCode_Int32);
  22797. explicitCast = true;
  22798. }
  22799. else if ((otherType->IsChar()) &&
  22800. ((binaryOp == BfBinaryOp_Add) || (binaryOp == BfBinaryOp_Subtract) || (binaryOp == BfBinaryOp_OverflowAdd) || (binaryOp == BfBinaryOp_OverflowSubtract)))
  22801. {
  22802. mModule->Fail(StrFormat("Cannot perform operation between types '%s' and '%s'",
  22803. mModule->TypeToString(leftValue.mType).c_str(),
  22804. mModule->TypeToString(rightValue.mType).c_str()), opToken);
  22805. }
  22806. }
  22807. }
  22808. else if ((!resultType->IsSigned()) && (binaryOp == BfBinaryOp_Subtract) && (!forceLeftType))
  22809. {
  22810. if ((mExpectingType == NULL) || (mExpectingType->IsSigned()) || (resultType->IsChar()))
  22811. {
  22812. if ((resultType->IsChar()) && (resultType->mSize == 4))
  22813. {
  22814. // "wchar - wchar" subtraction will always fit into int32, because of unicode range
  22815. resultType = mModule->GetPrimitiveType(BfTypeCode_Int32);
  22816. }
  22817. else
  22818. {
  22819. // The result of uint8 - uint8 is int16 (for example)
  22820. switch (resultType->mSize)
  22821. {
  22822. case 1:
  22823. resultType = mModule->GetPrimitiveType(BfTypeCode_Int16);
  22824. break;
  22825. case 2:
  22826. resultType = mModule->GetPrimitiveType(BfTypeCode_Int32);
  22827. break;
  22828. case 4:
  22829. resultType = mModule->GetPrimitiveType(BfTypeCode_Int64);
  22830. break;
  22831. }
  22832. }
  22833. explicitCast = true;
  22834. }
  22835. }
  22836. else if (resultType->IsChar())
  22837. {
  22838. bool canDoOp =
  22839. (binaryOp == BfBinaryOp_BitwiseAnd) ||
  22840. (binaryOp == BfBinaryOp_BitwiseOr) ||
  22841. ((binaryOp >= BfBinaryOp_Equality) && (binaryOp <= BfBinaryOp_Compare));
  22842. if (!canDoOp)
  22843. {
  22844. mModule->Fail(StrFormat("Cannot perform operation on type '%s'", mModule->TypeToString(resultType).c_str()), opToken);
  22845. return;
  22846. }
  22847. }
  22848. }
  22849. if (!convLeftValue)
  22850. convLeftValue = mModule->CastToValue(leftExpression, leftValue, resultType,
  22851. explicitCast ? (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_FromCompiler) : BfCastFlags_None);
  22852. if (!convRightValue)
  22853. convRightValue = mModule->CastToValue(rightExpression, rightValue, resultType,
  22854. explicitCast ? (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_FromCompiler) : BfCastFlags_None);
  22855. PerformBinaryOperation(resultType, convLeftValue, convRightValue, binaryOp, opToken);
  22856. }
  22857. void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convLeftValue, BfIRValue convRightValue, BfBinaryOp binaryOp, BfAstNode* opToken)
  22858. {
  22859. if (resultType->IsValuelessType())
  22860. {
  22861. switch (binaryOp)
  22862. {
  22863. case BfBinaryOp_Equality:
  22864. case BfBinaryOp_StrictEquality:
  22865. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 1),
  22866. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  22867. return;
  22868. case BfBinaryOp_InEquality:
  22869. case BfBinaryOp_StrictInEquality:
  22870. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 0),
  22871. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  22872. return;
  22873. default:
  22874. break;
  22875. }
  22876. }
  22877. if ((!convLeftValue) || (!convRightValue))
  22878. return;
  22879. if (resultType->IsPrimitiveType())
  22880. {
  22881. auto primType = (BfPrimitiveType*)resultType;
  22882. if (primType->mTypeDef->mTypeCode == BfTypeCode_Boolean)
  22883. {
  22884. bool passThrough = false;
  22885. switch (binaryOp)
  22886. {
  22887. case BfBinaryOp_Equality:
  22888. case BfBinaryOp_StrictEquality:
  22889. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(convLeftValue, convRightValue),
  22890. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  22891. break;
  22892. case BfBinaryOp_InEquality:
  22893. case BfBinaryOp_StrictInEquality:
  22894. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(convLeftValue, convRightValue),
  22895. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  22896. break;
  22897. case BfBinaryOp_BitwiseAnd:
  22898. case BfBinaryOp_ConditionalAnd:
  22899. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateAnd(convLeftValue, convRightValue),
  22900. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  22901. break;
  22902. case BfBinaryOp_BitwiseOr:
  22903. case BfBinaryOp_ConditionalOr:
  22904. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateOr(convLeftValue, convRightValue),
  22905. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  22906. break;
  22907. case BfBinaryOp_ExclusiveOr:
  22908. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateXor(convLeftValue, convRightValue),
  22909. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  22910. break;
  22911. case BfBinaryOp_Compare:
  22912. passThrough = true;
  22913. break;
  22914. default:
  22915. if (mModule->PreFail())
  22916. mModule->Fail("Invalid operation for booleans", opToken);
  22917. break;
  22918. }
  22919. if (!passThrough)
  22920. return;
  22921. }
  22922. }
  22923. if ((!resultType->IsIntegralOrBool()) && (!resultType->IsFloat()))
  22924. {
  22925. if (mModule->PreFail())
  22926. mModule->Fail(StrFormat("Cannot perform operation on type '%s'", mModule->TypeToString(resultType).c_str()), opToken);
  22927. return;
  22928. }
  22929. if (resultType->IsIntegral())
  22930. {
  22931. switch (binaryOp)
  22932. {
  22933. case BfBinaryOp_BitwiseAnd:
  22934. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateAnd(convLeftValue, convRightValue), resultType);
  22935. return;
  22936. case BfBinaryOp_BitwiseOr:
  22937. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateOr(convLeftValue, convRightValue), resultType);
  22938. return;
  22939. case BfBinaryOp_ExclusiveOr:
  22940. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateXor(convLeftValue, convRightValue), resultType);
  22941. return;
  22942. case BfBinaryOp_LeftShift:
  22943. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateShl(convLeftValue, convRightValue), resultType);
  22944. mModule->CheckRangeError(resultType, opToken);
  22945. return;
  22946. case BfBinaryOp_RightShift:
  22947. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateShr(convLeftValue, convRightValue, resultType->IsSigned()), resultType);
  22948. return;
  22949. default: break;
  22950. }
  22951. }
  22952. if ((resultType->IsChar()) &&
  22953. ((binaryOp == BfBinaryOp_Multiply) ||
  22954. (binaryOp == BfBinaryOp_OverflowMultiply) ||
  22955. (binaryOp == BfBinaryOp_Divide) ||
  22956. (binaryOp == BfBinaryOp_Modulus)))
  22957. {
  22958. mModule->Fail(StrFormat("Cannot perform operation on type '%s'", mModule->TypeToString(resultType).c_str()), opToken);
  22959. return;
  22960. }
  22961. auto _GetOverflowKind = [&](bool wantOverflow)
  22962. {
  22963. if (resultType->IsFloat())
  22964. return BfOverflowCheckKind_None;
  22965. if (!wantOverflow)
  22966. return BfOverflowCheckKind_None;
  22967. if (mModule->GetDefaultCheckedKind() != BfCheckedKind_Checked)
  22968. return BfOverflowCheckKind_None;
  22969. bool arithmeticChecks = mModule->mCompiler->mOptions.mArithmeticChecks;
  22970. auto typeOptions = mModule->GetTypeOptions();
  22971. if (typeOptions != NULL)
  22972. arithmeticChecks = typeOptions->Apply(arithmeticChecks, BfOptionFlags_ArithmeticCheck);
  22973. if (!arithmeticChecks)
  22974. return BfOverflowCheckKind_None;
  22975. BfOverflowCheckKind overflowCheckKind = (resultType->IsSigned()) ? BfOverflowCheckKind_Signed : BfOverflowCheckKind_Unsigned;
  22976. if (!mModule->IsOptimized())
  22977. overflowCheckKind = (BfOverflowCheckKind)(overflowCheckKind | BfOverflowCheckKind_Flag_UseAsm);
  22978. return overflowCheckKind;
  22979. };
  22980. switch (binaryOp)
  22981. {
  22982. case BfBinaryOp_Add:
  22983. case BfBinaryOp_OverflowAdd:
  22984. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateAdd(convLeftValue, convRightValue, _GetOverflowKind(binaryOp == BfBinaryOp_Add)), resultType);
  22985. if (binaryOp != BfBinaryOp_OverflowAdd)
  22986. mModule->CheckRangeError(resultType, opToken);
  22987. break;
  22988. case BfBinaryOp_Subtract:
  22989. case BfBinaryOp_OverflowSubtract:
  22990. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateSub(convLeftValue, convRightValue, _GetOverflowKind(binaryOp == BfBinaryOp_Subtract)), resultType);
  22991. if (binaryOp != BfBinaryOp_OverflowSubtract)
  22992. mModule->CheckRangeError(resultType, opToken);
  22993. break;
  22994. case BfBinaryOp_Multiply:
  22995. case BfBinaryOp_OverflowMultiply:
  22996. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateMul(convLeftValue, convRightValue, _GetOverflowKind(binaryOp == BfBinaryOp_Multiply)), resultType);
  22997. if (binaryOp != BfBinaryOp_OverflowMultiply)
  22998. mModule->CheckRangeError(resultType, opToken);
  22999. break;
  23000. case BfBinaryOp_Divide:
  23001. {
  23002. bool isZero = false;
  23003. if (convRightValue.IsConst())
  23004. {
  23005. auto constVal = mModule->mBfIRBuilder->GetConstant(convRightValue);
  23006. if (BfIRBuilder::IsInt(constVal->mTypeCode))
  23007. isZero = constVal->mInt64 == 0;
  23008. }
  23009. if (isZero)
  23010. {
  23011. mModule->Fail("Divide by zero", opToken);
  23012. mResult = mModule->GetDefaultTypedValue(resultType);
  23013. }
  23014. else
  23015. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateDiv(convLeftValue, convRightValue, resultType->IsSigned()), resultType);
  23016. }
  23017. break;
  23018. case BfBinaryOp_Modulus:
  23019. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateRem(convLeftValue, convRightValue, resultType->IsSigned()), resultType);
  23020. break;
  23021. case BfBinaryOp_Equality:
  23022. case BfBinaryOp_StrictEquality:
  23023. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(convLeftValue, convRightValue),
  23024. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  23025. break;
  23026. case BfBinaryOp_InEquality:
  23027. case BfBinaryOp_StrictInEquality:
  23028. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(convLeftValue, convRightValue),
  23029. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  23030. break;
  23031. case BfBinaryOp_LessThan:
  23032. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpLT(convLeftValue, convRightValue, resultType->IsSigned()),
  23033. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  23034. break;
  23035. case BfBinaryOp_LessThanOrEqual:
  23036. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpLTE(convLeftValue, convRightValue, resultType->IsSigned()),
  23037. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  23038. break;
  23039. case BfBinaryOp_GreaterThan:
  23040. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpGT(convLeftValue, convRightValue, resultType->IsSigned()),
  23041. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  23042. break;
  23043. case BfBinaryOp_GreaterThanOrEqual:
  23044. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpGTE(convLeftValue, convRightValue, resultType->IsSigned()),
  23045. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  23046. break;
  23047. case BfBinaryOp_Compare:
  23048. {
  23049. auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  23050. if ((convLeftValue.IsConst()) && (convRightValue.IsConst()))
  23051. {
  23052. auto cmpLtVal = mModule->mBfIRBuilder->CreateCmpLT(convLeftValue, convRightValue, resultType->IsSigned());
  23053. auto ltConstant = mModule->mBfIRBuilder->GetConstant(cmpLtVal);
  23054. if (ltConstant->mBool)
  23055. {
  23056. mResult = BfTypedValue(mModule->GetConstValue(-1, mModule->GetPrimitiveType(BfTypeCode_IntPtr)), intType);
  23057. }
  23058. else
  23059. {
  23060. auto cmpGtVal = mModule->mBfIRBuilder->CreateCmpGT(convLeftValue, convRightValue, resultType->IsSigned());
  23061. auto rtConstant = mModule->mBfIRBuilder->GetConstant(cmpGtVal);
  23062. if (rtConstant->mBool)
  23063. mResult = BfTypedValue(mModule->GetConstValue(1, mModule->GetPrimitiveType(BfTypeCode_IntPtr)), intType);
  23064. else
  23065. mResult = BfTypedValue(mModule->GetConstValue(0, mModule->GetPrimitiveType(BfTypeCode_IntPtr)), intType);
  23066. }
  23067. }
  23068. else if ((resultType->IsIntegralOrBool()) && (resultType->mSize < intType->mSize))
  23069. {
  23070. auto leftIntValue = mModule->mBfIRBuilder->CreateNumericCast(convLeftValue, resultType->IsSigned(), BfTypeCode_IntPtr);
  23071. auto rightIntValue = mModule->mBfIRBuilder->CreateNumericCast(convRightValue, resultType->IsSigned(), BfTypeCode_IntPtr);
  23072. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateSub(leftIntValue, rightIntValue), intType);
  23073. }
  23074. else
  23075. {
  23076. BfIRBlock checkGtBlock = mModule->mBfIRBuilder->CreateBlock("cmpCheckGt");
  23077. BfIRBlock eqBlock = mModule->mBfIRBuilder->CreateBlock("cmpEq");
  23078. BfIRBlock endBlock = mModule->mBfIRBuilder->CreateBlock("cmpEnd");
  23079. auto startBlock = mModule->mBfIRBuilder->GetInsertBlock();
  23080. auto cmpLtVal = mModule->mBfIRBuilder->CreateCmpLT(convLeftValue, convRightValue, resultType->IsSigned());
  23081. mModule->mBfIRBuilder->CreateCondBr(cmpLtVal, endBlock, checkGtBlock);
  23082. mModule->mBfIRBuilder->AddBlock(checkGtBlock);
  23083. mModule->mBfIRBuilder->SetInsertPoint(checkGtBlock);
  23084. auto cmpGtVal = mModule->mBfIRBuilder->CreateCmpGT(convLeftValue, convRightValue, resultType->IsSigned());
  23085. mModule->mBfIRBuilder->CreateCondBr(cmpGtVal, endBlock, eqBlock);
  23086. mModule->mBfIRBuilder->AddBlock(eqBlock);
  23087. mModule->mBfIRBuilder->SetInsertPoint(eqBlock);
  23088. mModule->mBfIRBuilder->CreateBr(endBlock);
  23089. mModule->mBfIRBuilder->AddBlock(endBlock);
  23090. mModule->mBfIRBuilder->SetInsertPoint(endBlock);
  23091. auto phiVal = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(intType), 3);
  23092. mModule->mBfIRBuilder->AddPhiIncoming(phiVal, mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, -1), startBlock);
  23093. mModule->mBfIRBuilder->AddPhiIncoming(phiVal, mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 1), checkGtBlock);
  23094. mModule->mBfIRBuilder->AddPhiIncoming(phiVal, mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0), eqBlock);
  23095. mResult = BfTypedValue(phiVal, intType);
  23096. }
  23097. }
  23098. break;
  23099. default:
  23100. if (mModule->PreFail())
  23101. mModule->Fail("Invalid operation", opToken);
  23102. break;
  23103. }
  23104. }
  23105. void BfExprEvaluator::Visit(BfBinaryOperatorExpression* binOpExpr)
  23106. {
  23107. BfAutoParentNodeEntry autoParentNodeEntry(mModule, binOpExpr);
  23108. // There are a few binary operations that could actually be casts followed by an unary operation
  23109. // We can't determine that until we know whether the identifier in the parens is a typename or not
  23110. // (double)-1.0 (intptr)&val (BaseStruct)*val
  23111. BfUnaryOp unaryOp = BfUnaryOp_None;
  23112. switch (binOpExpr->mOp)
  23113. {
  23114. case BfBinaryOp_Add: unaryOp = BfUnaryOp_Positive; break;
  23115. case BfBinaryOp_Subtract: unaryOp = BfUnaryOp_Negate; break;
  23116. case BfBinaryOp_Multiply: unaryOp = BfUnaryOp_Dereference; break;
  23117. case BfBinaryOp_BitwiseAnd: unaryOp = BfUnaryOp_AddressOf; break;
  23118. default: break;
  23119. }
  23120. if (unaryOp != BfUnaryOp_None)
  23121. {
  23122. if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(binOpExpr->mLeft))
  23123. {
  23124. if (auto castTypeExpr = BfNodeDynCast<BfIdentifierNode>(parenExpr->mExpression))
  23125. {
  23126. SetAndRestoreValue<bool> prevIgnoreError(mModule->mIgnoreErrors, true);
  23127. auto resolvedType = mModule->ResolveTypeRef(castTypeExpr, NULL);
  23128. prevIgnoreError.Restore();
  23129. if (resolvedType != NULL)
  23130. {
  23131. if (auto rightBinOpExpr = BfNodeDynCast<BfBinaryOperatorExpression>(binOpExpr->mRight))
  23132. {
  23133. int leftPrecedence = BfGetBinaryOpPrecendence(binOpExpr->mOp);
  23134. int rightPrecedence = BfGetBinaryOpPrecendence(rightBinOpExpr->mOp);
  23135. // Do we have a precedence order issue due to mis-parsing this?
  23136. // An example is: "(int)-5.5 * 10"
  23137. if (rightPrecedence > leftPrecedence)
  23138. {
  23139. mModule->FailAfter("Cast target must be wrapped in parentheses", binOpExpr->mLeft);
  23140. }
  23141. }
  23142. PerformUnaryOperation(binOpExpr->mRight, unaryOp, binOpExpr->mOpToken, BfUnaryOpFlag_None);
  23143. if (mResult)
  23144. {
  23145. mResult = mModule->LoadValue(mResult);
  23146. mResult = mModule->Cast(binOpExpr, mResult, resolvedType, BfCastFlags_Explicit);
  23147. }
  23148. return;
  23149. }
  23150. }
  23151. }
  23152. }
  23153. if ((binOpExpr->mOp == BfBinaryOp_LeftShift) || (binOpExpr->mOp == BfBinaryOp_RightShift) ||
  23154. (binOpExpr->mOp == BfBinaryOp_BitwiseAnd) || (binOpExpr->mOp == BfBinaryOp_BitwiseOr) ||
  23155. (binOpExpr->mOp == BfBinaryOp_ExclusiveOr))
  23156. {
  23157. for (int side = 0; side < 2; side++)
  23158. {
  23159. if (auto innerBinOpExpr = BfNodeDynCast<BfBinaryOperatorExpression>((side == 0) ? binOpExpr->mLeft : binOpExpr->mRight))
  23160. {
  23161. if ((innerBinOpExpr->mOp == BfBinaryOp_Add) || (innerBinOpExpr->mOp == BfBinaryOp_Subtract))
  23162. {
  23163. mModule->Warn(BfWarning_C4554_PossiblePrecedenceError, "Check operator precedence for possible error. Consider using parentheses to clarify precedence", innerBinOpExpr);
  23164. }
  23165. }
  23166. }
  23167. }
  23168. if (binOpExpr->mRight == NULL)
  23169. {
  23170. // We visit the children for autocompletion only
  23171. if (binOpExpr->mLeft != NULL)
  23172. VisitChild(binOpExpr->mLeft);
  23173. if (mResult)
  23174. {
  23175. auto autoComplete = GetAutoComplete();
  23176. if (autoComplete != NULL)
  23177. autoComplete->CheckEmptyStart(binOpExpr->mOpToken, mResult.mType);
  23178. }
  23179. if (binOpExpr->mRight != NULL)
  23180. VisitChild(binOpExpr->mRight);
  23181. return;
  23182. }
  23183. PerformBinaryOperation(binOpExpr->mLeft, binOpExpr->mRight, binOpExpr->mOp, binOpExpr->mOpToken, BfBinOpFlag_None);
  23184. }