BfExprEvaluator.cpp 598 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727
  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 "BfResolvePass.h"
  17. #include "BfUtil.h"
  18. #include "BfDeferEvalChecker.h"
  19. #include "BfVarDeclChecker.h"
  20. #pragma warning(pop)
  21. #include "BeefySysLib/util/AllocDebug.h"
  22. USING_NS_BF;
  23. using namespace llvm;
  24. static BfBinaryOp GetOppositeBinaryOp(BfBinaryOp origOp)
  25. {
  26. switch (origOp)
  27. {
  28. case BfBinaryOp_Equality:
  29. return BfBinaryOp_InEquality;
  30. case BfBinaryOp_InEquality:
  31. return BfBinaryOp_Equality;
  32. case BfBinaryOp_LessThan:
  33. return BfBinaryOp_GreaterThanOrEqual;
  34. case BfBinaryOp_LessThanOrEqual:
  35. return BfBinaryOp_GreaterThan;
  36. case BfBinaryOp_GreaterThan:
  37. return BfBinaryOp_LessThanOrEqual;
  38. case BfBinaryOp_GreaterThanOrEqual:
  39. return BfBinaryOp_LessThan;
  40. default: break;
  41. }
  42. return BfBinaryOp_None;
  43. }
  44. static BfBinaryOp GetFlippedBinaryOp(BfBinaryOp origOp)
  45. {
  46. switch (origOp)
  47. {
  48. case BfBinaryOp_Equality:
  49. return BfBinaryOp_Equality;
  50. case BfBinaryOp_InEquality:
  51. return BfBinaryOp_InEquality;
  52. case BfBinaryOp_LessThan:
  53. return BfBinaryOp_GreaterThan;
  54. case BfBinaryOp_LessThanOrEqual:
  55. return BfBinaryOp_GreaterThanOrEqual;
  56. case BfBinaryOp_GreaterThan:
  57. return BfBinaryOp_LessThan;
  58. case BfBinaryOp_GreaterThanOrEqual:
  59. return BfBinaryOp_LessThanOrEqual;
  60. default: break;
  61. }
  62. return BfBinaryOp_None;
  63. }
  64. //////////////////////////////////////////////////////////////////////////
  65. DeferredTupleAssignData::~DeferredTupleAssignData()
  66. {
  67. for (auto entry : mChildren)
  68. {
  69. delete entry.mExprEvaluator;
  70. delete entry.mInnerTuple;
  71. }
  72. }
  73. //////////////////////////////////////////////////////////////////////////
  74. BfBaseClassWalker::BfBaseClassWalker(BfType* typeA, BfType* typeB, BfModule* module)
  75. {
  76. mMayBeFromInterface = false;
  77. if ((typeA != NULL) && (!typeA->IsInterface()))
  78. mTypes[0] = typeA->ToTypeInstance();
  79. else
  80. mTypes[0] = NULL;
  81. if ((typeB != NULL) && (!typeB->IsInterface()))
  82. mTypes[1] = typeB->ToTypeInstance();
  83. else
  84. mTypes[1] = NULL;
  85. if ((typeA != NULL) && (typeA->IsGenericParam()))
  86. {
  87. mMayBeFromInterface = true;
  88. AddConstraints(typeA, module->GetGenericParamInstance((BfGenericParamType*)typeA));
  89. }
  90. if ((typeB != NULL) && (typeB->IsGenericParam()))
  91. {
  92. mMayBeFromInterface = true;
  93. AddConstraints(typeB, module->GetGenericParamInstance((BfGenericParamType*)typeB));
  94. }
  95. }
  96. /*BfBaseClassWalker::BfBaseClassWalker(BfTypeInstance* typeA, BfTypeInstance* typeB)
  97. {
  98. mTypes[0] = typeA;
  99. mTypes[1] = typeB;
  100. }*/
  101. BfBaseClassWalker::BfBaseClassWalker()
  102. {
  103. mMayBeFromInterface = false;
  104. mTypes[0] = NULL;
  105. mTypes[1] = NULL;
  106. }
  107. void BfBaseClassWalker::AddConstraints(BfType* srcType, BfGenericParamInstance* genericParam)
  108. {
  109. if (genericParam->mTypeConstraint != NULL)
  110. {
  111. auto typeInst = genericParam->mTypeConstraint->ToTypeInstance();
  112. {
  113. Entry entry(srcType, typeInst);
  114. if ((typeInst != NULL) && (!mManualList.Contains(entry)))
  115. mManualList.Add(entry);
  116. }
  117. }
  118. for (auto typeInst : genericParam->mInterfaceConstraints)
  119. {
  120. Entry entry(srcType, typeInst);
  121. if ((typeInst != NULL) && (!mManualList.Contains(entry)))
  122. mManualList.Add(entry);
  123. }
  124. }
  125. BfBaseClassWalker::Entry BfBaseClassWalker::Next()
  126. {
  127. if (!mManualList.IsEmpty())
  128. {
  129. auto entry = mManualList.back();
  130. mManualList.pop_back();
  131. return entry;
  132. }
  133. // Check the most specific type instance first (highest inheritance level)
  134. auto checkInstance = mTypes[0];
  135. if (mTypes[0] == NULL)
  136. checkInstance = mTypes[1];
  137. else if ((mTypes[1] != NULL) && (mTypes[1]->mInheritDepth > mTypes[0]->mInheritDepth))
  138. checkInstance = mTypes[1];
  139. if (checkInstance == NULL)
  140. return Entry();
  141. // Do it this was so if we reach the same base class for both types that we only handle each base type once
  142. if (checkInstance == mTypes[0])
  143. mTypes[0] = checkInstance->mBaseType;
  144. if (checkInstance == mTypes[1])
  145. mTypes[1] = checkInstance->mBaseType;
  146. Entry entry;
  147. entry.mSrcType = checkInstance;
  148. entry.mTypeInstance = checkInstance;
  149. return entry;
  150. }
  151. //////////////////////////////////////////////////////////////////////////
  152. BfMethodMatcher::BfMethodMatcher(BfAstNode* targetSrc, BfModule* module, const StringImpl& methodName, SizedArrayImpl<BfResolvedArg>& arguments, BfSizedArray<ASTREF(BfTypeReference*)>* methodGenericArguments) :
  153. mArguments(arguments)
  154. {
  155. mTargetSrc = targetSrc;
  156. mModule = module;
  157. mMethodName = methodName;
  158. Init(/*arguments, */methodGenericArguments);
  159. }
  160. BfMethodMatcher::BfMethodMatcher(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* interfaceMethodInstance, SizedArrayImpl<BfResolvedArg>& arguments, BfSizedArray<ASTREF(BfTypeReference*)>* methodGenericArguments) :
  161. mArguments(arguments)
  162. {
  163. mTargetSrc = targetSrc;
  164. mModule = module;
  165. Init(/*arguments, */methodGenericArguments);
  166. mInterfaceMethodInstance = interfaceMethodInstance;
  167. mMethodName = mInterfaceMethodInstance->mMethodDef->mName;
  168. }
  169. void BfMethodMatcher::Init(/*SizedArrayImpl<BfResolvedArg>& arguments, */BfSizedArray<ASTREF(BfTypeReference*)>* methodGenericArguments)
  170. {
  171. //mArguments = arguments;
  172. mBestMethodDef = NULL;
  173. mBackupMethodDef = NULL;
  174. mBestMethodTypeInstance = NULL;
  175. mExplicitInterfaceCheck = NULL;
  176. mSelfType = NULL;
  177. mMethodType = BfMethodType_Normal;
  178. mHadExplicitGenericArguments = false;
  179. mHasVarArguments = false;
  180. mInterfaceMethodInstance = NULL;
  181. mFakeConcreteTarget = false;
  182. mBypassVirtual = false;
  183. mAllowStatic = true;
  184. mAllowNonStatic = true;
  185. mSkipImplicitParams = false;
  186. mAllowImplicitThis = false;
  187. mMethodCheckCount = 0;
  188. mInferGenericProgressIdx = 0;
  189. mCheckedKind = BfCheckedKind_NotSet;
  190. mMatchFailKind = MatchFailKind_None;
  191. for (auto& arg : mArguments)
  192. {
  193. auto bfType = arg.mTypedValue.mType;
  194. if (bfType != NULL)
  195. mHasVarArguments |= bfType->IsVar();
  196. }
  197. if (methodGenericArguments != NULL)
  198. {
  199. for (BfTypeReference* genericArg : *methodGenericArguments)
  200. {
  201. auto genericArgType = mModule->ResolveTypeRef(genericArg);
  202. // if (genericArgType == NULL)
  203. // return;
  204. mExplicitMethodGenericArguments.push_back(genericArgType);
  205. }
  206. mHadExplicitGenericArguments = true;
  207. }
  208. }
  209. bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfType* argType, BfType* wantType, BfIRValue argValue)
  210. {
  211. if (argType == NULL)
  212. return false;
  213. if (argType->IsVar())
  214. return false;
  215. if (wantType->IsGenericParam())
  216. {
  217. auto wantGenericParam = (BfGenericParamType*)wantType;
  218. BfType* methodGenericTypeConstraint = NULL;
  219. auto _SetGeneric = [&]()
  220. {
  221. if (mCheckMethodGenericArguments[wantGenericParam->mGenericParamIdx] != argType)
  222. {
  223. if (methodGenericTypeConstraint != NULL)
  224. {
  225. if (methodGenericTypeConstraint->IsGenericTypeInstance())
  226. {
  227. auto wantGenericType = (BfGenericTypeInstance*)methodGenericTypeConstraint;
  228. auto checkArgType = argType;
  229. while (checkArgType != NULL)
  230. {
  231. if (checkArgType->IsGenericTypeInstance())
  232. {
  233. auto argGenericType = (BfGenericTypeInstance*)checkArgType;
  234. if (argGenericType->mTypeDef == wantGenericType->mTypeDef)
  235. {
  236. for (int genericArgIdx = 0; genericArgIdx < (int)argGenericType->mTypeGenericArguments.size(); genericArgIdx++)
  237. InferGenericArgument(methodInstance, argGenericType->mTypeGenericArguments[genericArgIdx], wantGenericType->mTypeGenericArguments[genericArgIdx], BfIRValue());
  238. }
  239. }
  240. else if (checkArgType->IsSizedArray())
  241. {
  242. auto sizedArrayType = (BfSizedArrayType*)checkArgType;
  243. if (wantGenericType->mTypeDef == mModule->mCompiler->mSizedArrayTypeDef)
  244. {
  245. InferGenericArgument(methodInstance, sizedArrayType->mElementType, wantGenericType->mTypeGenericArguments[0], BfIRValue());
  246. auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  247. BfTypedValue arraySize = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, (uint64)sizedArrayType->mElementCount), intType);
  248. InferGenericArgument(methodInstance, mModule->CreateConstExprValueType(arraySize), wantGenericType->mTypeGenericArguments[1], BfIRValue());
  249. }
  250. }
  251. else if (checkArgType->IsPointer())
  252. {
  253. auto pointerType = (BfPointerType*)checkArgType;
  254. if (wantGenericType->mTypeDef == mModule->mCompiler->mPointerTTypeDef)
  255. {
  256. InferGenericArgument(methodInstance, pointerType->mElementType, wantGenericType->mTypeGenericArguments[0], BfIRValue());
  257. }
  258. }
  259. auto checkTypeInst = checkArgType->ToTypeInstance();
  260. if ((checkTypeInst == NULL) || (!checkTypeInst->mHasParameterizedBase))
  261. break;
  262. checkArgType = checkTypeInst->mBaseType;
  263. }
  264. }
  265. }
  266. mInferGenericProgressIdx++;
  267. mCheckMethodGenericArguments[wantGenericParam->mGenericParamIdx] = argType;
  268. }
  269. mCheckMethodGenericArguments[wantGenericParam->mGenericParamIdx] = argType;
  270. mPrevArgValues[wantGenericParam->mGenericParamIdx] = argValue;
  271. };
  272. if (wantGenericParam->mGenericParamKind == BfGenericParamKind_Method)
  273. {
  274. auto genericParamInst = methodInstance->mMethodInfoEx->mGenericParams[wantGenericParam->mGenericParamIdx];
  275. methodGenericTypeConstraint = genericParamInst->mTypeConstraint;
  276. if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Const) != 0)
  277. {
  278. if (argValue.IsConst())
  279. {
  280. argType = mModule->CreateConstExprValueType(BfTypedValue(argValue, argType));
  281. }
  282. else if (!argType->IsConstExprValue())
  283. {
  284. return false;
  285. }
  286. }
  287. if (argType == mModule->mContext->mBfObjectType)
  288. {
  289. if ((genericParamInst->mTypeConstraint != NULL) && (genericParamInst->mTypeConstraint->IsDelegate()))
  290. {
  291. argType = genericParamInst->mTypeConstraint;
  292. }
  293. }
  294. auto prevGenericMethodArg = mCheckMethodGenericArguments[wantGenericParam->mGenericParamIdx];
  295. auto prevArgValue = mPrevArgValues[wantGenericParam->mGenericParamIdx];
  296. if (prevGenericMethodArg == NULL)
  297. {
  298. _SetGeneric();
  299. return true;
  300. }
  301. if ((prevGenericMethodArg->IsIntUnknown()) && (!argType->IsIntUnknown()))
  302. {
  303. // Old int fits into new argType, that's good
  304. if (mModule->CanImplicitlyCast(BfTypedValue(prevArgValue, prevGenericMethodArg), argType))
  305. {
  306. _SetGeneric();
  307. return true;
  308. }
  309. // Doesn't fit, upgrade type to 'int'
  310. argType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  311. if (mModule->CanImplicitlyCast(BfTypedValue(prevArgValue, prevGenericMethodArg), argType))
  312. {
  313. _SetGeneric();
  314. return true;
  315. }
  316. }
  317. if (argType->IsIntUnknown())
  318. {
  319. // New int fits into previous arg type, that's good
  320. if (mModule->CanImplicitlyCast(BfTypedValue(argValue, argType), prevGenericMethodArg))
  321. return true;
  322. // Doesn't fit, upgrade type to 'int'
  323. argType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  324. }
  325. else
  326. {
  327. // Prev is already best
  328. if (mModule->CanImplicitlyCast(mModule->GetFakeTypedValue(argType), prevGenericMethodArg))
  329. return true;
  330. }
  331. // New best?
  332. if (mModule->CanImplicitlyCast(mModule->GetFakeTypedValue(prevGenericMethodArg), argType))
  333. {
  334. _SetGeneric();
  335. return true;
  336. }
  337. // No implicit conversion, FAIL!
  338. mCheckMethodGenericArguments[wantGenericParam->mGenericParamIdx] = NULL;
  339. return false;
  340. }
  341. return true;
  342. }
  343. if (wantType->IsGenericTypeInstance())
  344. {
  345. auto wantGenericType = (BfGenericTypeInstance*)wantType;
  346. if (!argType->IsGenericTypeInstance())
  347. return true;
  348. auto argGenericType = (BfGenericTypeInstance*)argType;
  349. if (argGenericType->mTypeDef != wantGenericType->mTypeDef)
  350. return true;
  351. for (int genericArgIdx = 0; genericArgIdx < (int)argGenericType->mTypeGenericArguments.size(); genericArgIdx++)
  352. InferGenericArgument(methodInstance, argGenericType->mTypeGenericArguments[genericArgIdx], wantGenericType->mTypeGenericArguments[genericArgIdx], BfIRValue());
  353. return true;
  354. }
  355. if (wantType->IsRef())
  356. {
  357. auto wantRefType = (BfRefType*)wantType;
  358. if (!argType->IsRef())
  359. {
  360. // Match to non-ref
  361. InferGenericArgument(methodInstance, argType, wantRefType->mElementType, BfIRValue());
  362. return true;
  363. }
  364. auto argRefType = (BfRefType*)argType;
  365. //TODO: We removed this check so we still infer even if we have the wrong ref kind
  366. //if (wantRefType->mRefKind != argRefType->mRefKind)
  367. //return true;
  368. InferGenericArgument(methodInstance, argRefType->mElementType, wantRefType->mElementType, BfIRValue());
  369. return true;
  370. }
  371. if (wantType->IsPointer())
  372. {
  373. if (!argType->IsPointer())
  374. return true;
  375. auto wantPointerType = (BfPointerType*) wantType;
  376. auto argPointerType = (BfPointerType*) argType;
  377. InferGenericArgument(methodInstance, argPointerType->mElementType, wantPointerType->mElementType, BfIRValue());
  378. return true;
  379. }
  380. if (wantType->IsUnknownSizedArray())
  381. {
  382. auto wantArrayType = (BfUnknownSizedArrayType*)wantType;
  383. if (argType->IsUnknownSizedArray())
  384. {
  385. auto argArrayType = (BfUnknownSizedArrayType*)argType;
  386. InferGenericArgument(methodInstance, argArrayType->mElementCountSource, wantArrayType->mElementCountSource, BfIRValue());
  387. }
  388. else if (argType->IsSizedArray())
  389. {
  390. auto argArrayType = (BfSizedArrayType*)argType;
  391. BfTypedValue sizeValue(mModule->GetConstValue(argArrayType->mElementCount), mModule->GetPrimitiveType(BfTypeCode_IntPtr));
  392. auto sizedType = mModule->CreateConstExprValueType(sizeValue);
  393. InferGenericArgument(methodInstance, sizedType, wantArrayType->mElementCountSource, BfIRValue());
  394. }
  395. }
  396. if (wantType->IsSizedArray())
  397. {
  398. if (argType->IsSizedArray())
  399. {
  400. auto wantArrayType = (BfSizedArrayType*)wantType;
  401. auto argArrayType = (BfSizedArrayType*)argType;
  402. InferGenericArgument(methodInstance, argArrayType->mElementType, wantArrayType->mElementType, BfIRValue());
  403. }
  404. }
  405. return true;
  406. }
  407. void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTypeVector* prevGenericArgumentsSubstitute,
  408. BfMethodInstance* newMethodInstance, BfTypeVector* genericArgumentsSubstitute,
  409. bool* outNewIsBetter, bool* outNewIsWorse, bool allowSpecializeFail)
  410. {
  411. #define SET_BETTER_OR_WORSE(lhs, rhs) \
  412. if ((!isBetter) && (lhs) && !(rhs)) isBetter = true; \
  413. if ((!isWorse) && !(lhs) && (rhs)) isWorse = true;
  414. #define RETURN_BETTER_OR_WORSE(lhs, rhs) \
  415. if ((!isBetter) && (lhs) && !(rhs)) { *outNewIsBetter = true; *outNewIsWorse = false; return; } \
  416. if ((!isWorse) && !(lhs) && (rhs)) { *outNewIsBetter = false; *outNewIsWorse = true; return; };
  417. #define RETURN_RESULTS \
  418. *outNewIsBetter = isBetter; \
  419. *outNewIsWorse = isWorse; \
  420. return;
  421. int numUsedParams = 0;
  422. int prevNumUsedParams = 0;
  423. bool usedExtendedForm = false;
  424. bool prevUsedExtendedForm = false;
  425. bool isBetter = false;
  426. bool isWorse = false;
  427. int argIdx;
  428. BfMethodDef* prevMethodDef = prevMethodInstance->mMethodDef;
  429. BfMethodDef* newMethodDef = newMethodInstance->mMethodDef;
  430. if (newMethodDef->mExplicitInterface != prevMethodDef->mExplicitInterface)
  431. {
  432. if (mModule->CompareMethodSignatures(newMethodInstance, prevMethodInstance))
  433. {
  434. SET_BETTER_OR_WORSE(newMethodDef->mExplicitInterface != NULL, prevMethodDef->mExplicitInterface != NULL);
  435. *outNewIsBetter = isBetter;
  436. *outNewIsWorse = isWorse;
  437. return;
  438. }
  439. }
  440. int newImplicitParamCount = newMethodInstance->GetImplicitParamCount();
  441. if (newMethodInstance->mMethodDef->mHasAppend)
  442. newImplicitParamCount++;
  443. int prevImplicitParamCount = prevMethodInstance->GetImplicitParamCount();
  444. if (prevMethodInstance->mMethodDef->mHasAppend)
  445. prevImplicitParamCount++;
  446. bool hadEnoughArgs = newMethodInstance->GetParamCount() - newImplicitParamCount < (int)mArguments.size();
  447. bool prevHadEnoughArgs = prevMethodInstance->GetParamCount() - prevImplicitParamCount < (int)mArguments.size();
  448. RETURN_BETTER_OR_WORSE(hadEnoughArgs, prevHadEnoughArgs);
  449. bool chainSkip = (newMethodInstance->mChainType == BfMethodChainType_ChainMember) || (newMethodInstance->mChainType == BfMethodChainType_ChainSkip);
  450. bool prevChainSkip = (prevMethodInstance->mChainType == BfMethodChainType_ChainMember) || (prevMethodInstance->mChainType == BfMethodChainType_ChainSkip);
  451. RETURN_BETTER_OR_WORSE(!chainSkip, !prevChainSkip);
  452. // If one of these methods is local to the current extension then choose that one
  453. auto activeDef = mModule->GetActiveTypeDef();
  454. RETURN_BETTER_OR_WORSE(newMethodDef->mDeclaringType == activeDef, prevMethodDef->mDeclaringType == activeDef);
  455. RETURN_BETTER_OR_WORSE(newMethodDef->mDeclaringType->IsExtension(), prevMethodDef->mDeclaringType->IsExtension());
  456. if ((!isBetter) && (!isWorse))
  457. {
  458. bool betterByGenericParam = false;
  459. bool worseByGenericParam = false;
  460. for (argIdx = 0; argIdx < (int)mArguments.size(); argIdx++)
  461. {
  462. BfResolvedArg resolvedArg = mArguments[argIdx];;
  463. BfTypedValue arg = resolvedArg.mTypedValue;
  464. int newArgIdx = argIdx + newImplicitParamCount;
  465. int prevArgIdx = argIdx + prevImplicitParamCount;
  466. bool wasGenericParam = newMethodInstance->WasGenericParam(newArgIdx);
  467. bool prevWasGenericParam = prevMethodInstance->WasGenericParam(prevArgIdx);
  468. BfType* paramType = newMethodInstance->GetParamType(newArgIdx);
  469. BfType* prevParamType = prevMethodInstance->GetParamType(prevArgIdx);
  470. numUsedParams++;
  471. prevNumUsedParams++;
  472. BfType* origParamType = paramType;
  473. BfType* origPrevParamType = prevParamType;
  474. if ((genericArgumentsSubstitute != NULL) && (paramType->IsUnspecializedType()))
  475. paramType = mModule->ResolveGenericType(paramType, *genericArgumentsSubstitute, allowSpecializeFail);
  476. if ((prevGenericArgumentsSubstitute != NULL) && (prevParamType->IsUnspecializedType()))
  477. prevParamType = mModule->ResolveGenericType(prevParamType, *prevGenericArgumentsSubstitute, allowSpecializeFail);
  478. if ((wasGenericParam) || (prevWasGenericParam))
  479. {
  480. if ((wasGenericParam) && (!prevWasGenericParam))
  481. worseByGenericParam = true;
  482. else if ((!wasGenericParam) && (prevWasGenericParam))
  483. betterByGenericParam = true;
  484. }
  485. if ((prevParamType == NULL) || (paramType == NULL))
  486. {
  487. SET_BETTER_OR_WORSE(paramType != NULL, prevParamType != NULL);
  488. }
  489. else if (paramType != prevParamType)
  490. {
  491. bool isUnspecializedParam = paramType->IsUnspecializedType();
  492. bool isPrevUnspecializedParam = prevParamType->IsUnspecializedType();
  493. SET_BETTER_OR_WORSE((!isUnspecializedParam) && (!paramType->IsVar()),
  494. (!isPrevUnspecializedParam) && (!prevParamType->IsVar()));
  495. if ((!isBetter) && (!isWorse))
  496. SET_BETTER_OR_WORSE(paramType->IsConstExprValue(), prevParamType->IsConstExprValue());
  497. if ((!isBetter) && (!isWorse) && (!isUnspecializedParam) && (!isPrevUnspecializedParam))
  498. {
  499. SET_BETTER_OR_WORSE((paramType != NULL) && (!paramType->IsUnspecializedType()),
  500. (prevParamType != NULL) && (!prevParamType->IsUnspecializedType()));
  501. if ((!isBetter) && (!isWorse))
  502. {
  503. // The resolved argument type may actually match for both considered functions. IE:
  504. // Method(int8 val) and Method(int16 val) called with Method(0) will create arguments that match their param types
  505. if ((paramType == arg.mType) && (prevParamType != resolvedArg.mBestBoundType))
  506. isBetter = true;
  507. else if ((prevParamType == arg.mType) && (paramType != arg.mType))
  508. isWorse = true;
  509. else
  510. {
  511. bool canCastFromCurToPrev = mModule->CanImplicitlyCast(mModule->GetFakeTypedValue(paramType), prevParamType);
  512. bool canCastFromPrevToCur = mModule->CanImplicitlyCast(mModule->GetFakeTypedValue(prevParamType), paramType);
  513. if ((canCastFromCurToPrev) && (!canCastFromPrevToCur))
  514. isBetter = true;
  515. else if ((canCastFromPrevToCur) && (!canCastFromCurToPrev))
  516. isWorse = true;
  517. else if ((paramType->IsIntegral()) && (prevParamType->IsIntegral()))
  518. {
  519. if (paramType == arg.mType)
  520. isBetter = true;
  521. else if (prevParamType == arg.mType)
  522. isWorse = true;
  523. else
  524. {
  525. if (paramType->mSize < prevParamType->mSize)
  526. isBetter = true;
  527. else if (paramType->mSize > prevParamType->mSize)
  528. isWorse = true;
  529. else if (paramType->IsSigned())
  530. isBetter = true;
  531. else
  532. isWorse = true;
  533. }
  534. }
  535. }
  536. /*if ((paramType->IsIntegral()) && (prevParamType->IsIntegral()))
  537. {
  538. if (paramType == arg.mType)
  539. isBetter = true;
  540. else if (prevParamType == arg.mType)
  541. isWorse = true;
  542. else
  543. {
  544. if (paramType->mSize < prevParamType->mSize)
  545. isBetter = true;
  546. else if (paramType->mSize > prevParamType->mSize)
  547. isWorse = true;
  548. else if (paramType->IsSigned())
  549. isBetter = true;
  550. else
  551. isWorse = true;
  552. }
  553. }
  554. else
  555. {
  556. if (mModule->CanImplicitlyCast(mModule->GetFakeTypedValue(paramType), prevParamType))
  557. isBetter = true;
  558. if (mModule->CanImplicitlyCast(mModule->GetFakeTypedValue(prevParamType), paramType))
  559. isWorse = true;
  560. }*/
  561. }
  562. }
  563. }
  564. else if ((wasGenericParam) || (prevWasGenericParam))
  565. {
  566. if (!wasGenericParam)
  567. isBetter = true;
  568. else if (!prevWasGenericParam)
  569. isWorse = true;
  570. }
  571. if (newMethodInstance->GetParamKind(newArgIdx) == BfParamKind_Params)
  572. usedExtendedForm = true;
  573. if (prevMethodInstance->GetParamKind(prevArgIdx) == BfParamKind_Params)
  574. prevUsedExtendedForm = true;
  575. if ((usedExtendedForm) || (prevUsedExtendedForm))
  576. break;
  577. }
  578. if ((!isBetter) && (!isWorse))
  579. {
  580. isBetter = betterByGenericParam;
  581. isWorse = worseByGenericParam;
  582. }
  583. if ((isBetter) || (isWorse))
  584. {
  585. RETURN_RESULTS;
  586. }
  587. }
  588. // Check for unused extended params as next param - that still counts as using extended form
  589. usedExtendedForm = newMethodInstance->HasParamsArray();
  590. prevUsedExtendedForm = prevMethodInstance->HasParamsArray();
  591. // Non-generic is better than generic.
  592. // The only instance where we can disambiguate is when we have the same number of generic arguments, and the
  593. // constraints for one method's generic argument is a superset of another's. More specific is better.
  594. //TODO: WE changed this to compare the constraints of the ARGUMENTS
  595. // if (newMethodInstance->GetNumGenericArguments() == prevMethodInstance->GetNumGenericArguments())
  596. // {
  597. // if (newMethodInstance->GetNumGenericArguments() != 0)
  598. // {
  599. // for (int genericIdx = 0; genericIdx < (int)newMethodInstance->mMethodInfoEx->mMethodGenericArguments.size(); genericIdx++)
  600. // {
  601. // auto newMethodGenericParam = newMethodInstance->mMethodInfoEx->mGenericParams[genericIdx];
  602. // auto prevMethodGenericParam = prevMethodInstance->mMethodInfoEx->mGenericParams[genericIdx];
  603. // RETURN_BETTER_OR_WORSE(mModule->AreConstraintsSubset(prevMethodGenericParam, newMethodGenericParam), mModule->AreConstraintsSubset(newMethodGenericParam, prevMethodGenericParam));
  604. // }
  605. // }
  606. // }
  607. // else
  608. RETURN_BETTER_OR_WORSE(newMethodInstance->GetNumGenericArguments() == 0, prevMethodInstance->GetNumGenericArguments() == 0);
  609. // Not using generic delegate params is better
  610. RETURN_BETTER_OR_WORSE(!newMethodInstance->mHadGenericDelegateParams, !prevMethodInstance->mHadGenericDelegateParams);
  611. // Normal form trumps extended form
  612. RETURN_BETTER_OR_WORSE(!usedExtendedForm, !prevUsedExtendedForm);
  613. // More used params trumps less params
  614. int paramDiff = (int) numUsedParams - (int) prevNumUsedParams;
  615. RETURN_BETTER_OR_WORSE(paramDiff > 0, paramDiff < 0);
  616. // Fewer defaults trumps more defaults
  617. // Since we know the number of used params is the same (previous check), we infer that the rest are defaults
  618. paramDiff = (int) newMethodInstance->GetParamCount() - (int) prevMethodInstance->GetParamCount();
  619. RETURN_BETTER_OR_WORSE(paramDiff < 0, paramDiff > 0);
  620. // Check specificity of args
  621. std::function<void(BfType*, BfType*)> _CompareParamTypes = [&](BfType* newType, BfType* prevType)
  622. {
  623. if ((newType->IsGenericParam()) && (prevType->IsGenericParam()))
  624. {
  625. auto newGenericParamType = (BfGenericParamType*)newType;
  626. auto prevGenericParamType = (BfGenericParamType*)prevType;
  627. if ((newGenericParamType->mGenericParamKind == BfGenericParamKind_Method) && (prevGenericParamType->mGenericParamKind == BfGenericParamKind_Method))
  628. {
  629. auto newMethodGenericParam = newMethodInstance->mMethodInfoEx->mGenericParams[newGenericParamType->mGenericParamIdx];
  630. auto prevMethodGenericParam = prevMethodInstance->mMethodInfoEx->mGenericParams[prevGenericParamType->mGenericParamIdx];
  631. SET_BETTER_OR_WORSE(mModule->AreConstraintsSubset(prevMethodGenericParam, newMethodGenericParam), mModule->AreConstraintsSubset(newMethodGenericParam, prevMethodGenericParam));
  632. }
  633. }
  634. else if (newType == prevType)
  635. {
  636. if ((newType->IsUnspecializedType()) && (newType->IsGenericTypeInstance()))
  637. {
  638. BfGenericTypeInstance* newGenericType = (BfGenericTypeInstance*)newType;
  639. BfGenericTypeInstance* prevGenericType = (BfGenericTypeInstance*)prevType;
  640. for (int genericArgIdx = 0; genericArgIdx < (int)newGenericType->mTypeGenericArguments.size(); genericArgIdx++)
  641. {
  642. _CompareParamTypes(newGenericType->mTypeGenericArguments[genericArgIdx], prevGenericType->mTypeGenericArguments[genericArgIdx]);
  643. }
  644. }
  645. }
  646. else
  647. {
  648. //TODO: Why did we need this?
  649. //isBetter |= mModule->IsTypeMoreSpecific(newType, prevType);
  650. //isWorse |= mModule->IsTypeMoreSpecific(prevType, newType);
  651. }
  652. };
  653. int paramCheckCount = (int)BF_MIN(newMethodInstance->GetParamCount() - newImplicitParamCount, prevMethodInstance->GetParamCount() - prevImplicitParamCount);
  654. for (argIdx = 0; argIdx < (int)paramCheckCount/*mArguments.size()*/; argIdx++)
  655. {
  656. int newArgIdx = argIdx + newImplicitParamCount;
  657. int prevArgIdx = argIdx + prevImplicitParamCount;
  658. _CompareParamTypes(newMethodInstance->GetParamType(newArgIdx), prevMethodInstance->GetParamType(prevArgIdx));
  659. }
  660. // Do generic constraint subset test directly to handle cases like "NotDisposed<T>()" vs "NOtDisposed<T>() where T : IDisposable"
  661. if ((newMethodInstance->GetNumGenericArguments() > 0) && (newMethodInstance->GetNumGenericArguments() == prevMethodInstance->GetNumGenericArguments()))
  662. {
  663. for (int genericParamIdx = 0; genericParamIdx < (int)newMethodInstance->GetNumGenericArguments(); genericParamIdx++)
  664. {
  665. auto newMethodGenericParam = newMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
  666. auto prevMethodGenericParam = prevMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
  667. SET_BETTER_OR_WORSE(mModule->AreConstraintsSubset(prevMethodGenericParam, newMethodGenericParam), mModule->AreConstraintsSubset(newMethodGenericParam, prevMethodGenericParam));
  668. }
  669. }
  670. if ((isBetter) || (isWorse))
  671. {
  672. RETURN_RESULTS;
  673. }
  674. // Does one have a body and one doesn't? Obvious!
  675. isBetter = prevMethodDef->IsEmptyPartial();
  676. isWorse = newMethodDef->IsEmptyPartial();
  677. if ((isBetter) && (isWorse))
  678. {
  679. // If both are empty partials then just bind to either
  680. isWorse = true;
  681. RETURN_RESULTS;
  682. }
  683. // For operators, prefer explicit comparison over '<=>' comparison operator
  684. if ((!isBetter) && (!isWorse))
  685. {
  686. if ((prevMethodDef->mIsOperator) && (newMethodDef->mIsOperator))
  687. {
  688. bool newIsComparison = ((BfOperatorDeclaration*)newMethodDef->mMethodDeclaration)->mBinOp == BfBinaryOp_Compare;
  689. bool prevIsComparison = ((BfOperatorDeclaration*)prevMethodDef->mMethodDeclaration)->mBinOp == BfBinaryOp_Compare;
  690. RETURN_BETTER_OR_WORSE(!newIsComparison, !prevIsComparison);
  691. }
  692. }
  693. // For extensions, select the version in the most-specific project (only applicable for ctors)
  694. if ((!isBetter) && (!isWorse))
  695. {
  696. auto newProject = newMethodDef->mDeclaringType->mProject;
  697. auto prevProject = prevMethodDef->mDeclaringType->mProject;
  698. if (newProject != prevProject)
  699. {
  700. RETURN_BETTER_OR_WORSE(newProject->ContainsReference(prevProject), prevProject->ContainsReference(newProject));
  701. }
  702. }
  703. // If we have conditional type extensions that both define an implementation for a method, use the most-specific conditional extension constraints
  704. auto owner = newMethodInstance->GetOwner();
  705. if ((newMethodDef->mDeclaringType != prevMethodDef->mDeclaringType) && (owner->IsGenericTypeInstance()))
  706. {
  707. auto genericOwner = (BfGenericTypeInstance*)owner;
  708. if (genericOwner->mGenericExtensionInfo != NULL)
  709. {
  710. BfGenericExtensionEntry* newGenericExtesionEntry = NULL;
  711. BfGenericExtensionEntry* prevGenericExtesionEntry = NULL;
  712. if ((genericOwner->mGenericExtensionInfo->mExtensionMap.TryGetValue(newMethodDef->mDeclaringType, &newGenericExtesionEntry)) &&
  713. (genericOwner->mGenericExtensionInfo->mExtensionMap.TryGetValue(prevMethodDef->mDeclaringType, &prevGenericExtesionEntry)))
  714. {
  715. if ((newGenericExtesionEntry->mGenericParams.size() == prevGenericExtesionEntry->mGenericParams.size()))
  716. {
  717. for (int genericParamIdx = 0; genericParamIdx < (int)newGenericExtesionEntry->mGenericParams.size(); genericParamIdx++)
  718. {
  719. auto newMethodGenericParam = newGenericExtesionEntry->mGenericParams[genericParamIdx];
  720. auto prevMethodGenericParam = prevGenericExtesionEntry->mGenericParams[genericParamIdx];
  721. SET_BETTER_OR_WORSE(mModule->AreConstraintsSubset(prevMethodGenericParam, newMethodGenericParam), mModule->AreConstraintsSubset(newMethodGenericParam, prevMethodGenericParam));
  722. }
  723. }
  724. if ((isBetter) || (isWorse))
  725. {
  726. RETURN_RESULTS;
  727. }
  728. }
  729. }
  730. }
  731. RETURN_BETTER_OR_WORSE(newMethodDef->mCheckedKind == mCheckedKind, prevMethodDef->mCheckedKind == mCheckedKind);
  732. RETURN_RESULTS;
  733. }
  734. BfTypedValue BfMethodMatcher::ResolveArgTypedValue(BfResolvedArg& resolvedArg, BfType* checkType)
  735. {
  736. BfTypedValue argTypedValue = resolvedArg.mTypedValue;
  737. if ((resolvedArg.mArgFlags & BfArgFlag_DelegateBindAttempt) != 0)
  738. {
  739. //TODO: See if we can bind it to a delegate type
  740. BfExprEvaluator exprEvaluator(mModule);
  741. exprEvaluator.mExpectingType = checkType;
  742. BF_ASSERT(resolvedArg.mExpression->IsA<BfDelegateBindExpression>());
  743. auto delegateBindExpr = BfNodeDynCast<BfDelegateBindExpression>(resolvedArg.mExpression);
  744. BfMethodInstance* boundMethodInstance = NULL;
  745. if (exprEvaluator.CanBindDelegate(delegateBindExpr, &boundMethodInstance))
  746. {
  747. if (delegateBindExpr->mNewToken == NULL)
  748. {
  749. resolvedArg.mExpectedType = checkType;
  750. auto methodRefType = mModule->CreateMethodRefType(boundMethodInstance);
  751. mModule->AddDependency(methodRefType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_Calls);
  752. mModule->AddCallDependency(boundMethodInstance);
  753. argTypedValue = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), methodRefType);
  754. }
  755. else
  756. argTypedValue = BfTypedValue(BfTypedValueKind_UntypedValue);
  757. //argTypedValue = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), checkType);
  758. }
  759. }
  760. else if ((resolvedArg.mArgFlags & BfArgFlag_LambdaBindAttempt) != 0)
  761. {
  762. BfExprEvaluator exprEvaluator(mModule);
  763. exprEvaluator.mExpectingType = checkType;
  764. BF_ASSERT(resolvedArg.mExpression->IsA<BfLambdaBindExpression>());
  765. auto lambdaBindExpr = (BfLambdaBindExpression*)resolvedArg.mExpression;
  766. if ((checkType != NULL) && (checkType->IsDelegate()))
  767. {
  768. BfMethodInstance* methodInstance = mModule->GetRawMethodInstanceAtIdx(checkType->ToTypeInstance(), 0, "Invoke");
  769. if (methodInstance != NULL)
  770. {
  771. if (methodInstance->GetParamCount() == (int)lambdaBindExpr->mParams.size())
  772. {
  773. if (lambdaBindExpr->mNewToken == NULL)
  774. {
  775. if (!resolvedArg.mTypedValue)
  776. {
  777. // Resolve for real
  778. resolvedArg.mTypedValue = mModule->CreateValueFromExpression(lambdaBindExpr, checkType, BfEvalExprFlags_NoCast);
  779. }
  780. argTypedValue = resolvedArg.mTypedValue;
  781. }
  782. else
  783. argTypedValue = BfTypedValue(BfTypedValueKind_UntypedValue);
  784. //argTypedValue = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), checkType);
  785. }
  786. }
  787. }
  788. }
  789. else if ((resolvedArg.mArgFlags & BfArgFlag_UnqualifiedDotAttempt) != 0)
  790. {
  791. if ((checkType != NULL) && (checkType->IsPayloadEnum()))
  792. {
  793. // Should we actually check the member name?
  794. argTypedValue = BfTypedValue(BfTypedValueKind_UntypedValue);
  795. }
  796. }
  797. else if ((resolvedArg.mArgFlags & BfArgFlag_UntypedDefault) != 0)
  798. {
  799. if (checkType != NULL)
  800. argTypedValue = BfTypedValue(BfTypedValueKind_UntypedValue);
  801. }
  802. else if ((resolvedArg.mArgFlags & BfArgFlag_DeferredEval) != 0)
  803. {
  804. if (resolvedArg.mExpression != NULL)
  805. {
  806. if ((resolvedArg.mExpectedType != checkType) || (resolvedArg.mExpectedType == NULL)) // Did our last check match for this type?
  807. {
  808. SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
  809. SetAndRestoreValue<bool> prevIgnoreError(mModule->mIgnoreErrors, true);
  810. //SetAndRestoreValue<bool> prevNoBind(mModule->mCurMethodState->mNoBind, true);
  811. bool prevNoBind = false;
  812. if (mModule->mCurMethodState != NULL)
  813. {
  814. prevNoBind = mModule->mCurMethodState->mNoBind;
  815. mModule->mCurMethodState->mNoBind = true;
  816. }
  817. auto prevBlock = mModule->mBfIRBuilder->GetInsertBlock();
  818. BfExprEvaluator exprEvaluator(mModule);
  819. exprEvaluator.mExpectingType = checkType;
  820. exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | BfEvalExprFlags_AllowIntUnknown);
  821. if ((resolvedArg.mArgFlags & BfArgFlag_ParamsExpr) != 0)
  822. exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | BfEvalExprFlags_AllowParamsExpr);
  823. exprEvaluator.Evaluate(resolvedArg.mExpression);
  824. argTypedValue = exprEvaluator.GetResult();
  825. if (mModule->mCurMethodState != NULL)
  826. mModule->mCurMethodState->mNoBind = prevNoBind;
  827. if (argTypedValue)
  828. {
  829. if (checkType != NULL)
  830. resolvedArg.mExpectedType = checkType;
  831. auto storeTypedValue = argTypedValue;
  832. if ((storeTypedValue.mValue) & (!storeTypedValue.mValue.IsFake()))
  833. {
  834. // We actually want to ensure that this cached value is a fake val. There are potential cases where a fake val
  835. // won't be generated but we should throw an error, so we need to make sure we actually re-evaluate when the call
  836. // is generated
  837. //storeTypedValue.mValue = mModule->mBfIRBuilder->GetFakeVal();
  838. resolvedArg.mWantsRecalc = true;
  839. }
  840. resolvedArg.mTypedValue = storeTypedValue;
  841. //BF_ASSERT(argTypedValue.mValue.mId != -1);
  842. }
  843. mModule->mBfIRBuilder->SetInsertPoint(prevBlock);
  844. }
  845. }
  846. }
  847. else if ((resolvedArg.mArgFlags & BfArgFlag_VariableDeclaration) != 0)
  848. {
  849. if ((checkType != NULL) && (checkType->IsRef()))
  850. argTypedValue = BfTypedValue(BfTypedValueKind_UntypedValue);
  851. }
  852. return argTypedValue;
  853. }
  854. bool BfMethodMatcher::WantsCheckMethod(BfProtectionCheckFlags& flags, BfTypeInstance* startTypeInstance, BfTypeInstance* checkTypeInstance, BfMethodDef* checkMethod)
  855. {
  856. MatchFailKind matchFailKind = MatchFailKind_None;
  857. if (!mModule->CheckProtection(flags, checkTypeInstance, checkMethod->mProtection, startTypeInstance))
  858. {
  859. if ((mBypassVirtual) && (checkMethod->mProtection == BfProtection_Protected) && (mModule->TypeIsSubTypeOf(mModule->mCurTypeInstance, startTypeInstance)))
  860. {
  861. // Allow explicit 'base' call
  862. }
  863. else
  864. {
  865. return false;
  866. }
  867. }
  868. if (mCheckedKind != checkMethod->mCheckedKind)
  869. {
  870. bool passes = true;
  871. if (mCheckedKind != BfCheckedKind_NotSet)
  872. {
  873. passes = false;
  874. }
  875. else
  876. {
  877. auto defaultCheckedKind = mModule->GetDefaultCheckedKind();
  878. if (defaultCheckedKind != checkMethod->mCheckedKind)
  879. passes = false;
  880. }
  881. if (!passes)
  882. {
  883. return false;
  884. }
  885. }
  886. return true;
  887. }
  888. bool BfMethodMatcher::CheckMethod(BfTypeInstance* typeInstance, BfMethodDef* checkMethod, bool isFailurePass)
  889. {
  890. bool hadMatch = false;
  891. // Never consider overrides - they only get found at original method declaration
  892. // mBypassVirtual gets set when we are doing an explicit "base" call, or when we are a struct --
  893. // because on structs we know the exact type
  894. if ((checkMethod->mIsOverride) && (!mBypassVirtual) && (!typeInstance->IsValueType()))
  895. return false;
  896. mMethodCheckCount++;
  897. BfMethodInstance* methodInstance = mModule->GetRawMethodInstance(typeInstance, checkMethod);
  898. if ((mInterfaceMethodInstance != NULL) && (methodInstance->GetExplicitInterface() != NULL))
  899. {
  900. BfTypeInstance* wantInterface = mInterfaceMethodInstance->mMethodInstanceGroup->mOwner;
  901. if (wantInterface != methodInstance->GetExplicitInterface())
  902. return false;
  903. }
  904. HashSet<int> allowEmptyGenericSet;
  905. BfAutoComplete* autoComplete = NULL;
  906. if ((mModule->mCompiler->mResolvePassData != NULL) && (!isFailurePass))
  907. autoComplete = mModule->mCompiler->mResolvePassData->mAutoComplete;
  908. if (((checkMethod->mIsStatic) && (!mAllowStatic)) ||
  909. ((!checkMethod->mIsStatic) && (!mAllowNonStatic)))
  910. {
  911. if (!typeInstance->IsFunction())
  912. autoComplete = NULL;
  913. }
  914. if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo))
  915. {
  916. BfAutoComplete::MethodMatchEntry methodMatchEntry;
  917. methodMatchEntry.mMethodDef = checkMethod;
  918. methodMatchEntry.mTypeInstance = typeInstance;
  919. methodMatchEntry.mCurMethodInstance = mModule->mCurMethodInstance;
  920. autoComplete->mMethodMatchInfo->mInstanceList.push_back(methodMatchEntry);
  921. }
  922. BfTypeVector* genericArgumentsSubstitute = NULL;
  923. int argIdx = 0;
  924. bool needInferGenericParams = (checkMethod->mGenericParams.size() != 0) && (!mHadExplicitGenericArguments);
  925. int paramIdx = 0;
  926. BfType* paramsElementType = NULL;
  927. if (checkMethod->mHasAppend)
  928. paramIdx++;
  929. // int outmostGenericCount = 0;
  930. // if (checkMethod->mIsLocalMethod)
  931. // outmostGenericCount = (int)mModule->mCurMethodState->GetRootMethodState()->mMethodInstance->mGenericParams.size();
  932. int uniqueGenericStartIdx = mModule->GetLocalInferrableGenericArgCount(checkMethod);
  933. if ((mHadExplicitGenericArguments) && (checkMethod->mGenericParams.size() != mExplicitMethodGenericArguments.size() + uniqueGenericStartIdx))
  934. goto NoMatch;
  935. for (auto& checkGenericArgRef : mCheckMethodGenericArguments)
  936. checkGenericArgRef = NULL;
  937. mCheckMethodGenericArguments.resize(checkMethod->mGenericParams.size());
  938. mPrevArgValues.resize(checkMethod->mGenericParams.size());
  939. for (auto& genericArgRef : mCheckMethodGenericArguments)
  940. genericArgRef = NULL;
  941. if (mHadExplicitGenericArguments)
  942. {
  943. if (uniqueGenericStartIdx > 0)
  944. {
  945. genericArgumentsSubstitute = &mCheckMethodGenericArguments;
  946. mCheckMethodGenericArguments.clear();
  947. mCheckMethodGenericArguments.reserve(mExplicitMethodGenericArguments.size() + uniqueGenericStartIdx);
  948. for (int i = 0; i < uniqueGenericStartIdx; i++)
  949. mCheckMethodGenericArguments.Add(NULL);
  950. for (int i = 0; i < (int)mExplicitMethodGenericArguments.size(); i++)
  951. mCheckMethodGenericArguments.Add(mExplicitMethodGenericArguments[i]);
  952. }
  953. else
  954. {
  955. genericArgumentsSubstitute = &mExplicitMethodGenericArguments;
  956. }
  957. }
  958. else if (needInferGenericParams)
  959. genericArgumentsSubstitute = &mCheckMethodGenericArguments;
  960. if (mSkipImplicitParams)
  961. {
  962. //paramOfs = methodInstance->GetImplicitParamCount();
  963. //paramIdx += paramOfs;
  964. }
  965. if (needInferGenericParams)
  966. {
  967. int paramOfs = methodInstance->GetImplicitParamCount();
  968. int paramCount = methodInstance->GetParamCount();
  969. if (checkMethod->mHasAppend)
  970. paramOfs++;
  971. for (int argIdx = 0; argIdx < (int)mArguments.size(); argIdx++)
  972. {
  973. if (argIdx >= (int)checkMethod->mParams.size())
  974. break;
  975. int paramIdx = argIdx + paramOfs;
  976. if (paramIdx >= paramCount)
  977. break; // Possible for delegate 'params' type methods
  978. auto wantType = methodInstance->GetParamType(argIdx + paramOfs);
  979. auto checkType = wantType;
  980. auto origCheckType = checkType;
  981. if (checkType->IsGenericParam())
  982. {
  983. BfGenericParamInstance* genericParamInstance = NULL;
  984. auto genericParamType = (BfGenericParamType*)checkType;
  985. checkType = NULL;
  986. if (genericParamType->mGenericParamKind == BfGenericParamKind_Method)
  987. {
  988. if ((genericArgumentsSubstitute != NULL) && (genericParamType->mGenericParamIdx < (int)genericArgumentsSubstitute->size()))
  989. checkType = (*genericArgumentsSubstitute)[genericParamType->mGenericParamIdx];
  990. genericParamInstance = methodInstance->mMethodInfoEx->mGenericParams[genericParamType->mGenericParamIdx];
  991. }
  992. else
  993. genericParamInstance = mModule->GetGenericParamInstance(genericParamType);
  994. if (checkType == NULL)
  995. checkType = genericParamInstance->mTypeConstraint;
  996. }
  997. if ((checkType != NULL) && (genericArgumentsSubstitute != NULL) && (checkType->IsUnspecializedTypeVariation()))
  998. {
  999. checkType = mModule->ResolveGenericType(origCheckType, *genericArgumentsSubstitute);
  1000. }
  1001. if (wantType->IsUnspecializedType())
  1002. {
  1003. BfTypedValue argTypedValue = ResolveArgTypedValue(mArguments[argIdx], checkType);
  1004. if (!argTypedValue.IsUntypedValue())
  1005. {
  1006. auto type = argTypedValue.mType;
  1007. if ((!argTypedValue) || (!InferGenericArgument(methodInstance, type, wantType, argTypedValue.mValue)))
  1008. goto NoMatch;
  1009. }
  1010. }
  1011. }
  1012. //
  1013. {
  1014. int paramIdx = (int)mArguments.size() + paramOfs;
  1015. while (paramIdx < checkMethod->mParams.size())
  1016. {
  1017. if ((paramIdx < methodInstance->mDefaultValues.size()) && (methodInstance->mDefaultValues[paramIdx]))
  1018. {
  1019. auto wantType = methodInstance->GetParamType(paramIdx);
  1020. auto checkType = wantType;
  1021. if (checkType->IsGenericParam())
  1022. {
  1023. BfGenericParamInstance* genericParamInstance = NULL;
  1024. auto genericParamType = (BfGenericParamType*)checkType;
  1025. if (genericParamType->mGenericParamKind == BfGenericParamKind_Method)
  1026. {
  1027. if ((genericArgumentsSubstitute != NULL) && (genericParamType->mGenericParamIdx < (int)genericArgumentsSubstitute->size()))
  1028. checkType = (*genericArgumentsSubstitute)[genericParamType->mGenericParamIdx];
  1029. genericParamInstance = methodInstance->mMethodInfoEx->mGenericParams[genericParamType->mGenericParamIdx];
  1030. if ((genericParamInstance->mGenericParamFlags & BfGenericParamFlag_Const) != 0)
  1031. {
  1032. if (mCheckMethodGenericArguments[genericParamType->mGenericParamIdx] == NULL)
  1033. allowEmptyGenericSet.Add(genericParamType->mGenericParamIdx);
  1034. }
  1035. }
  1036. }
  1037. }
  1038. paramIdx++;
  1039. }
  1040. }
  1041. //
  1042. for (int genericArgIdx = uniqueGenericStartIdx; genericArgIdx < (int)checkMethod->mGenericParams.size(); genericArgIdx++)
  1043. {
  1044. auto& genericArg = mCheckMethodGenericArguments[genericArgIdx];
  1045. if (genericArg == NULL)
  1046. {
  1047. if (!allowEmptyGenericSet.Contains(genericArgIdx))
  1048. goto NoMatch;
  1049. }
  1050. }
  1051. }
  1052. // Iterate through params
  1053. while (true)
  1054. {
  1055. // Too many arguments
  1056. if (paramIdx >= (int)methodInstance->GetParamCount())
  1057. {
  1058. break;
  1059. }
  1060. bool isDeferredEval = false;
  1061. if ((methodInstance->GetParamKind(paramIdx) == BfParamKind_Params) && (paramsElementType == NULL))
  1062. {
  1063. if (paramIdx >= (int) mArguments.size())
  1064. break; // No params
  1065. BfTypedValue argTypedValue = ResolveArgTypedValue(mArguments[argIdx], NULL);
  1066. if (!argTypedValue)
  1067. goto NoMatch;
  1068. if ((!argTypedValue.HasType()) && (!mArguments[argIdx].IsDeferredEval()))
  1069. goto NoMatch;
  1070. auto paramsArrayType = methodInstance->GetParamType(paramIdx);
  1071. if ((mArguments[argIdx].mArgFlags & BfArgFlag_ParamsExpr) != 0)
  1072. {
  1073. // Direct-pass params
  1074. if ((argTypedValue.IsUntypedValue()) || (mModule->CanImplicitlyCast(argTypedValue, paramsArrayType)))
  1075. {
  1076. argIdx++;
  1077. paramIdx++;
  1078. break;
  1079. }
  1080. goto NoMatch;
  1081. }
  1082. if (paramsArrayType->IsArray())
  1083. {
  1084. auto arrayType = (BfArrayType*)paramsArrayType;
  1085. paramsElementType = arrayType->mTypeGenericArguments[0];
  1086. while (argIdx < (int)mArguments.size())
  1087. {
  1088. argTypedValue = ResolveArgTypedValue(mArguments[argIdx], paramsElementType);
  1089. if (!argTypedValue.HasType())
  1090. goto NoMatch;
  1091. if (!mModule->CanImplicitlyCast(argTypedValue, paramsElementType))
  1092. goto NoMatch;
  1093. argIdx++;
  1094. }
  1095. }
  1096. else
  1097. goto NoMatch;
  1098. break;
  1099. }
  1100. if (methodInstance->IsImplicitCapture(paramIdx))
  1101. {
  1102. paramIdx++;
  1103. continue;
  1104. }
  1105. if (argIdx >= (int) mArguments.size())
  1106. {
  1107. // We have defaults the rest of the way, so that's cool
  1108. if (methodInstance->GetParamInitializer(paramIdx) != NULL)
  1109. break;
  1110. // We have unused params left over
  1111. goto NoMatch;
  1112. }
  1113. auto wantType = methodInstance->GetParamType(paramIdx);
  1114. if ((genericArgumentsSubstitute != NULL) && (wantType->IsUnspecializedType()))
  1115. {
  1116. auto resolvedType = mModule->ResolveGenericType(wantType, *genericArgumentsSubstitute);
  1117. if (resolvedType == NULL)
  1118. goto NoMatch;
  1119. wantType = resolvedType;
  1120. }
  1121. if (wantType->IsSelf())
  1122. wantType = typeInstance;
  1123. if ((mArguments[argIdx].mArgFlags & BfArgFlag_ParamsExpr) != 0)
  1124. {
  1125. // We had a 'params' expression but this method didn't have a params slot in this parameter
  1126. goto NoMatch;
  1127. }
  1128. BfTypedValue argTypedValue = ResolveArgTypedValue(mArguments[argIdx], wantType);
  1129. if (!argTypedValue.IsUntypedValue())
  1130. {
  1131. if (!argTypedValue.HasType())
  1132. {
  1133. goto NoMatch;
  1134. }
  1135. else if (!mModule->CanImplicitlyCast(argTypedValue, wantType))
  1136. goto NoMatch;
  1137. }
  1138. paramIdx++;
  1139. argIdx++;
  1140. if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo))
  1141. {
  1142. auto methodMatchInfo = autoComplete->mMethodMatchInfo;
  1143. if (!methodMatchInfo->mHadExactMatch)
  1144. {
  1145. bool isBetter = false;
  1146. bool isWorse = false;
  1147. int methodIdx = (int)methodMatchInfo->mInstanceList.size() - 1;
  1148. if ((methodMatchInfo->mBestIdx != -1) && (methodMatchInfo->mBestIdx < (int)methodMatchInfo->mInstanceList.size()))
  1149. {
  1150. auto prevMethodMatchEntry = &methodMatchInfo->mInstanceList[methodMatchInfo->mBestIdx];
  1151. if (checkMethod->mParams.size() < mArguments.size())
  1152. {
  1153. isWorse = true;
  1154. }
  1155. else if ((prevMethodMatchEntry->mMethodDef != NULL) && (prevMethodMatchEntry->mMethodDef->mParams.size() < (int) mArguments.size()))
  1156. {
  1157. isBetter = true;
  1158. }
  1159. }
  1160. }
  1161. }
  1162. }
  1163. //TODO: Does this ever get hit?
  1164. // Not enough arguments?
  1165. if (argIdx < (int)mArguments.size())
  1166. {
  1167. goto NoMatch;
  1168. }
  1169. if ((genericArgumentsSubstitute != NULL) && (genericArgumentsSubstitute->size() != 0))
  1170. {
  1171. for (int checkGenericIdx = uniqueGenericStartIdx; checkGenericIdx < (int)genericArgumentsSubstitute->size(); checkGenericIdx++)
  1172. {
  1173. auto& genericParams = methodInstance->mMethodInfoEx->mGenericParams;
  1174. auto genericArg = (*genericArgumentsSubstitute)[checkGenericIdx];
  1175. if (genericArg == NULL)
  1176. {
  1177. if (allowEmptyGenericSet.Contains(checkGenericIdx))
  1178. continue;
  1179. goto NoMatch;
  1180. }
  1181. if (genericArg->IsPrimitiveType())
  1182. {
  1183. auto primType = (BfPrimitiveType*) genericArg;
  1184. genericArg = mModule->GetPrimitiveStructType(primType->mTypeDef->mTypeCode);
  1185. }
  1186. if (genericArg == NULL)
  1187. goto NoMatch;
  1188. //SetAndRestoreValue<bool> ignoreError(mModule->mIgnoreErrors, true);
  1189. if (!mModule->CheckGenericConstraints(BfGenericParamSource(methodInstance), genericArg, NULL, genericParams[checkGenericIdx], genericArgumentsSubstitute, NULL))
  1190. {
  1191. goto NoMatch;
  1192. }
  1193. }
  1194. }
  1195. // Method is applicable, check to see which method is better
  1196. if (mBestMethodDef != NULL)
  1197. {
  1198. bool isBetter = false;
  1199. bool isWorse = false;
  1200. BfMethodInstance* prevMethodInstance = mModule->GetRawMethodInstance(mBestMethodTypeInstance, mBestMethodDef);
  1201. bool allowSpecializeFail = mModule->mCurTypeInstance->IsUnspecializedType();
  1202. if (mModule->mCurMethodInstance != NULL)
  1203. allowSpecializeFail = mModule->mCurMethodInstance->mIsUnspecialized;
  1204. CompareMethods(prevMethodInstance, &mBestMethodGenericArguments, methodInstance, genericArgumentsSubstitute, &isBetter, &isWorse, allowSpecializeFail);
  1205. // If we had both a 'better' and 'worse', that's ambiguous because the methods are each better in different ways (not allowed)
  1206. // And if neither better nor worse then they are equally good, which is not allowed either
  1207. if (((!isBetter) && (!isWorse)) || ((isBetter) && (isWorse)))
  1208. {
  1209. if (!mHasVarArguments)
  1210. {
  1211. BfAmbiguousEntry ambiguousEntry;
  1212. ambiguousEntry.mMethodInstance = methodInstance;
  1213. if (genericArgumentsSubstitute != NULL)
  1214. ambiguousEntry.mBestMethodGenericArguments = *genericArgumentsSubstitute;
  1215. if (methodInstance->GetNumGenericParams() != 0)
  1216. {
  1217. BF_ASSERT(!ambiguousEntry.mBestMethodGenericArguments.empty());
  1218. }
  1219. mAmbiguousEntries.push_back(ambiguousEntry);
  1220. }
  1221. }
  1222. if (!isBetter)
  1223. goto Done;
  1224. }
  1225. if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo))
  1226. {
  1227. auto methodMatchInfo = autoComplete->mMethodMatchInfo;
  1228. // Try to persist with previous partial match, if we have one - this keeps us from locking onto
  1229. // an incorrect method just because it had the current number of params that we've typed so far
  1230. if (methodMatchInfo->mPrevBestIdx == -1)
  1231. {
  1232. methodMatchInfo->mHadExactMatch = true;
  1233. methodMatchInfo->mBestIdx = (int) methodMatchInfo->mInstanceList.size() - 1;
  1234. }
  1235. }
  1236. mAmbiguousEntries.Clear();
  1237. hadMatch = true;
  1238. mBestMethodDef = checkMethod;
  1239. for (auto& arg : mArguments)
  1240. arg.mBestBoundType = arg.mTypedValue.mType;
  1241. NoMatch:
  1242. if (!hadMatch)
  1243. {
  1244. if (mBestMethodDef != NULL)
  1245. return false;
  1246. /*if ((mHadExplicitGenericArguments) && (mBestMethodGenericArguments.size() != checkMethod->mGenericParams.size()))
  1247. return false;*/
  1248. if (mBackupMethodDef != NULL)
  1249. {
  1250. int prevParamDiff = (int)mBackupMethodDef->mParams.size() - (int)mArguments.size();
  1251. int paramDiff = (int)checkMethod->mParams.size() - (int)mArguments.size();
  1252. if ((prevParamDiff < 0) && (prevParamDiff > paramDiff))
  1253. return false;
  1254. if ((prevParamDiff >= 0) && ((paramDiff < 0) || (prevParamDiff < paramDiff)))
  1255. return false;
  1256. // We search from the most specific type, so don't prefer a less specific type
  1257. if ((paramDiff == prevParamDiff) && (mBestMethodTypeInstance != typeInstance))
  1258. return false;
  1259. }
  1260. if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo))
  1261. {
  1262. auto methodMatchInfo = autoComplete->mMethodMatchInfo;
  1263. if ((methodMatchInfo->mPrevBestIdx == -1) && (!methodMatchInfo->mHadExactMatch))
  1264. {
  1265. methodMatchInfo->mBestIdx = (int)methodMatchInfo->mInstanceList.size() - 1;
  1266. }
  1267. }
  1268. mBackupMethodDef = checkMethod;
  1269. // Lie temporarily to store at least one candidate (but mBestMethodDef is still NULL)
  1270. hadMatch = true;
  1271. }
  1272. if (hadMatch)
  1273. {
  1274. mBestMethodTypeInstance = typeInstance;
  1275. if (genericArgumentsSubstitute != &mBestMethodGenericArguments)
  1276. {
  1277. if (genericArgumentsSubstitute != NULL)
  1278. mBestMethodGenericArguments = *genericArgumentsSubstitute;
  1279. else
  1280. mBestMethodGenericArguments.clear();
  1281. }
  1282. }
  1283. Done:
  1284. if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo) && (genericArgumentsSubstitute != NULL))
  1285. {
  1286. auto methodMatchInfo = autoComplete->mMethodMatchInfo;
  1287. if (!methodMatchInfo->mInstanceList.IsEmpty())
  1288. {
  1289. methodMatchInfo->mInstanceList[methodMatchInfo->mInstanceList.size() - 1].mGenericArguments = *genericArgumentsSubstitute;
  1290. }
  1291. }
  1292. return mBestMethodDef == checkMethod;
  1293. }
  1294. void BfMethodMatcher::FlushAmbiguityError()
  1295. {
  1296. if (!mAmbiguousEntries.empty())
  1297. {
  1298. BfError* error;
  1299. if (!mMethodName.empty())
  1300. error = mModule->Fail(StrFormat("Ambiguous method call for '%s'", mMethodName.c_str()), mTargetSrc);
  1301. else
  1302. error = mModule->Fail("Ambiguous method call", mTargetSrc);
  1303. if (error != NULL)
  1304. {
  1305. BfMethodInstance* bestMethodInstance = mModule->GetRawMethodInstance(mBestMethodTypeInstance, mBestMethodDef);
  1306. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' is a candidate", mModule->MethodToString(bestMethodInstance, BfMethodNameFlag_ResolveGenericParamNames,
  1307. mBestMethodGenericArguments.empty() ? NULL : &mBestMethodGenericArguments).c_str()),
  1308. bestMethodInstance->mMethodDef->GetRefNode());
  1309. for (auto& ambiguousEntry : mAmbiguousEntries)
  1310. {
  1311. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' is a candidate", mModule->MethodToString(ambiguousEntry.mMethodInstance, BfMethodNameFlag_ResolveGenericParamNames,
  1312. ambiguousEntry.mBestMethodGenericArguments.empty() ? NULL : &ambiguousEntry.mBestMethodGenericArguments).c_str()),
  1313. ambiguousEntry.mMethodInstance->mMethodDef->GetRefNode());
  1314. }
  1315. }
  1316. mAmbiguousEntries.Clear();
  1317. }
  1318. }
  1319. // This method checks all base classes before checking interfaces. Is that correct?
  1320. bool BfMethodMatcher::CheckType(BfTypeInstance* typeInstance, BfTypedValue target, bool isFailurePass)
  1321. {
  1322. auto curTypeInst = typeInstance;
  1323. auto curTypeDef = typeInstance->mTypeDef;
  1324. int checkInterfaceIdx = 0;
  1325. bool allowExplicitInterface = curTypeInst->IsInterface() && mBypassVirtual;
  1326. auto activeTypeDef = mModule->GetActiveTypeDef();
  1327. bool isDelegate = typeInstance->IsDelegate();
  1328. bool targetIsBase = target.IsBase();
  1329. bool checkExtensionBase = false;
  1330. if (targetIsBase)
  1331. {
  1332. if ((curTypeInst == mModule->mCurTypeInstance) && (curTypeInst->mTypeDef->mIsCombinedPartial))
  1333. {
  1334. checkExtensionBase = true;
  1335. }
  1336. else
  1337. {
  1338. curTypeInst = curTypeInst->mBaseType;
  1339. }
  1340. }
  1341. while (true)
  1342. {
  1343. curTypeDef->PopulateMemberSets();
  1344. BfMethodDef* nextMethodDef = NULL;
  1345. BfMemberSetEntry* entry;
  1346. if (curTypeDef->mMethodSet.TryGetWith(mMethodName, &entry))
  1347. nextMethodDef = (BfMethodDef*)entry->mMemberDef;
  1348. BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None;
  1349. while (nextMethodDef != NULL)
  1350. {
  1351. auto checkMethod = nextMethodDef;
  1352. nextMethodDef = nextMethodDef->mNextWithSameName;
  1353. if ((checkExtensionBase) && (curTypeInst == mModule->mCurTypeInstance))
  1354. {
  1355. // Accept either a method in the same project but that's the root definition, OR a method that's in a dependent project
  1356. bool accept = false;
  1357. if (activeTypeDef->mProject == checkMethod->mDeclaringType->mProject)
  1358. accept = (activeTypeDef->IsExtension()) && (!checkMethod->mDeclaringType->IsExtension());
  1359. else
  1360. accept = activeTypeDef->mProject->ContainsReference(checkMethod->mDeclaringType->mProject);
  1361. if (!accept)
  1362. continue;
  1363. }
  1364. if ((!allowExplicitInterface) && (checkMethod->mExplicitInterface != NULL) && (mInterfaceMethodInstance == NULL))
  1365. {
  1366. continue;
  1367. }
  1368. if (checkMethod->mMethodType != mMethodType)
  1369. continue;
  1370. // if (checkMethod->mName != mMethodName)
  1371. // continue;
  1372. if (!isDelegate)
  1373. {
  1374. if ((!curTypeInst->IsTypeMemberIncluded(checkMethod->mDeclaringType, activeTypeDef, mModule)) ||
  1375. (!curTypeInst->IsTypeMemberAccessible(checkMethod->mDeclaringType, activeTypeDef)))
  1376. continue;
  1377. }
  1378. MatchFailKind matchFailKind = MatchFailKind_None;
  1379. if (!mModule->CheckProtection(protectionCheckFlags, curTypeInst, checkMethod->mProtection, typeInstance))
  1380. {
  1381. if ((mBypassVirtual) && (checkMethod->mProtection == BfProtection_Protected) && (mModule->TypeIsSubTypeOf(mModule->mCurTypeInstance, typeInstance)))
  1382. {
  1383. // Allow explicit 'base' call
  1384. }
  1385. else
  1386. {
  1387. if (!isFailurePass)
  1388. continue;
  1389. matchFailKind = MatchFailKind_Protection;
  1390. }
  1391. }
  1392. if (mCheckedKind != checkMethod->mCheckedKind)
  1393. {
  1394. bool passes = true;
  1395. if (mCheckedKind != BfCheckedKind_NotSet)
  1396. {
  1397. passes = false;
  1398. }
  1399. else
  1400. {
  1401. auto defaultCheckedKind = mModule->GetDefaultCheckedKind();
  1402. if (defaultCheckedKind != checkMethod->mCheckedKind)
  1403. passes = false;
  1404. }
  1405. if (!passes)
  1406. {
  1407. if (!isFailurePass)
  1408. continue;
  1409. matchFailKind = MatchFailKind_CheckedMismatch;
  1410. }
  1411. }
  1412. CheckMethod(curTypeInst, checkMethod, isFailurePass);
  1413. if ((isFailurePass) &&
  1414. ((mBestMethodDef == checkMethod) || (mBackupMethodDef == checkMethod)))
  1415. mMatchFailKind = matchFailKind;
  1416. }
  1417. if (mBestMethodDef != NULL)
  1418. {
  1419. FlushAmbiguityError();
  1420. return true;
  1421. }
  1422. auto baseType = curTypeInst->mBaseType;
  1423. if (baseType == NULL)
  1424. {
  1425. //TODO: Why were we doing the interface checking?
  1426. if ((curTypeInst != mModule->mContext->mBfObjectType) && (!curTypeInst->IsInterface()))
  1427. {
  1428. // This can happen for structs
  1429. baseType = mModule->mContext->mBfObjectType;
  1430. }
  1431. else if ((typeInstance->IsInterface()) && (checkInterfaceIdx < (int)typeInstance->mInterfaces.size()))
  1432. {
  1433. baseType = typeInstance->mInterfaces[checkInterfaceIdx].mInterfaceType;
  1434. checkInterfaceIdx++;
  1435. }
  1436. else
  1437. {
  1438. break;
  1439. }
  1440. }
  1441. curTypeDef = baseType->mTypeDef;
  1442. curTypeInst = baseType;
  1443. if ((isFailurePass) && (mBackupMethodDef != NULL))
  1444. break;
  1445. }
  1446. if (mBestMethodDef == NULL)
  1447. {
  1448. // FAILED, but select the first method which will fire an actual error on param type matching
  1449. mBestMethodDef = mBackupMethodDef;
  1450. }
  1451. if ((mBestMethodDef == NULL) && (!target) && (mAllowImplicitThis))
  1452. {
  1453. // No explicit target - maybe this was a static call in the outer type?
  1454. auto outerType = mModule->GetOuterType(typeInstance);
  1455. if (outerType != NULL)
  1456. CheckOuterTypeStaticMethods(outerType, isFailurePass);
  1457. }
  1458. FlushAmbiguityError();
  1459. return mBestMethodDef != NULL;
  1460. }
  1461. void BfMethodMatcher::TryDevirtualizeCall(BfTypedValue target, BfTypedValue* origTarget, BfTypedValue* staticResult)
  1462. {
  1463. if ((mBestMethodDef == NULL) || (target.mType == NULL))
  1464. return;
  1465. if ((mModule->mCompiler->IsAutocomplete()) || (mModule->mContext->mResolvingVarField))
  1466. return;
  1467. if (mModule->mBfIRBuilder->mIgnoreWrites)
  1468. return;
  1469. if (mBestMethodTypeInstance->IsInterface())
  1470. {
  1471. mModule->PopulateType(mBestMethodTypeInstance, BfPopulateType_DataAndMethods);
  1472. auto activeTypeDef = mModule->GetActiveTypeDef();
  1473. // Statically map this call
  1474. auto checkType = target.mType;
  1475. if (checkType->IsPointer())
  1476. checkType = ((BfPointerType*)checkType)->mElementType;
  1477. if (checkType->IsWrappableType())
  1478. checkType = mModule->GetWrappedStructType(checkType);
  1479. if ((checkType != NULL) && (checkType->IsTypeInstance()) && (!checkType->IsInterface()))
  1480. {
  1481. BfTypeInterfaceEntry* bestIFaceEntry = NULL;
  1482. auto checkTypeInst = checkType->ToTypeInstance();
  1483. if (mBestMethodTypeInstance->mTypeDef == mModule->mCompiler->mIHashableTypeDef)
  1484. {
  1485. if ((origTarget != NULL) && (origTarget->mType->IsPointer()) && (staticResult != NULL))
  1486. {
  1487. BfTypedValue ptrVal = mModule->LoadValue(*origTarget);
  1488. *staticResult = BfTypedValue(mModule->mBfIRBuilder->CreatePtrToInt(ptrVal.mValue, BfTypeCode_IntPtr), mModule->GetPrimitiveType(BfTypeCode_IntPtr));
  1489. return;
  1490. }
  1491. }
  1492. while (checkTypeInst != NULL)
  1493. {
  1494. mModule->PopulateType(checkTypeInst, BfPopulateType_DataAndMethods);
  1495. for (auto&& iface : checkTypeInst->mInterfaces)
  1496. {
  1497. //TODO: Why did we have this check? This caused Dictionary to not be able to devirtualize
  1498. // calls to TKey GetHashCode when TKey was from a user's project...
  1499. /*if (!checkTypeInst->IsTypeMemberAccessible(iface.mDeclaringType, activeTypeDef))
  1500. continue;*/
  1501. if (iface.mInterfaceType == mBestMethodTypeInstance)
  1502. {
  1503. if (bestIFaceEntry == NULL)
  1504. {
  1505. bestIFaceEntry = &iface;
  1506. continue;
  1507. }
  1508. bool isBetter;
  1509. bool isWorse;
  1510. mModule->CompareDeclTypes(iface.mDeclaringType, bestIFaceEntry->mDeclaringType, isBetter, isWorse);
  1511. if (isBetter == isWorse)
  1512. {
  1513. // Failed
  1514. }
  1515. else
  1516. {
  1517. if (isBetter)
  1518. bestIFaceEntry = &iface;
  1519. }
  1520. }
  1521. }
  1522. if (bestIFaceEntry != NULL)
  1523. break;
  1524. checkTypeInst = checkTypeInst->mBaseType;
  1525. if ((checkTypeInst == NULL) && (checkType->HasWrappedRepresentation()))
  1526. {
  1527. auto underlyingType = checkType->GetUnderlyingType();
  1528. if ((underlyingType != NULL) && (underlyingType->IsWrappableType()))
  1529. checkTypeInst = mModule->GetWrappedStructType(underlyingType);
  1530. }
  1531. }
  1532. if (bestIFaceEntry != NULL)
  1533. {
  1534. auto ifaceMethodEntry = checkTypeInst->mInterfaceMethodTable[bestIFaceEntry->mStartInterfaceTableIdx + mBestMethodDef->mIdx];
  1535. BfMethodInstance* bestMethodInstance = ifaceMethodEntry.mMethodRef;
  1536. if (bestMethodInstance != NULL)
  1537. {
  1538. bool isMissingArg = false;
  1539. for (auto genericArg : mBestMethodGenericArguments)
  1540. {
  1541. if (genericArg == NULL)
  1542. isMissingArg = true;
  1543. }
  1544. if (!isMissingArg)
  1545. {
  1546. // Assert error state?
  1547. mBestMethodTypeInstance = ifaceMethodEntry.mMethodRef.mTypeInstance;
  1548. mBestMethodDef = bestMethodInstance->mMethodDef;
  1549. mBestMethodInstance = mModule->GetMethodInstance(mBestMethodTypeInstance, bestMethodInstance->mMethodDef, mBestMethodGenericArguments,
  1550. bestMethodInstance->mIsForeignMethodDef ? BfGetMethodInstanceFlag_ForeignMethodDef : BfGetMethodInstanceFlag_None,
  1551. bestMethodInstance->GetForeignType());
  1552. }
  1553. }
  1554. else
  1555. {
  1556. // Failed
  1557. mFakeConcreteTarget = true;
  1558. }
  1559. }
  1560. }
  1561. }
  1562. if ((target.mType->IsValueType()) && (mBestMethodTypeInstance->IsObject()) && (mBestMethodDef->mIsVirtual))
  1563. {
  1564. auto structType = target.mType->ToTypeInstance();
  1565. auto virtualMethodInstance = mModule->GetMethodInstance(mBestMethodTypeInstance, mBestMethodDef, BfTypeVector());
  1566. BF_ASSERT(virtualMethodInstance.mMethodInstance->mVirtualTableIdx != -1);
  1567. BfTypeInstance* boxedType;
  1568. if (structType->HasOverrideMethods())
  1569. {
  1570. // We don't actually need this boxed type, so just resolve it unreified
  1571. auto useModule = mModule->mContext->mUnreifiedModule;
  1572. boxedType = useModule->CreateBoxedType(target.mType);
  1573. useModule->PopulateType(boxedType, BfPopulateType_DataAndMethods);
  1574. useModule->AddDependency(boxedType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_Calls);
  1575. }
  1576. else
  1577. {
  1578. boxedType = mModule->mContext->mBfObjectType;
  1579. }
  1580. auto methodRef = boxedType->mVirtualMethodTable[virtualMethodInstance.mMethodInstance->mVirtualTableIdx];
  1581. if (methodRef.mImplementingMethod.mTypeInstance->IsBoxed())
  1582. {
  1583. auto useModule = mModule->mContext->mUnreifiedModule;
  1584. auto boxedMethodInstance = useModule->ReferenceExternalMethodInstance(methodRef.mImplementingMethod);
  1585. BfBoxedType* vBoxedType = (BfBoxedType*)methodRef.mImplementingMethod.mTypeInstance;
  1586. mBestMethodTypeInstance = vBoxedType->mElementType;
  1587. mBestMethodInstance = mModule->GetMethodInstance(mBestMethodTypeInstance, boxedMethodInstance.mMethodInstance->mMethodDef, BfTypeVector());
  1588. mBestMethodDef = mBestMethodInstance.mMethodInstance->mMethodDef;
  1589. }
  1590. else
  1591. {
  1592. mBestMethodTypeInstance = methodRef.mImplementingMethod.mTypeInstance;
  1593. mBestMethodInstance = mModule->ReferenceExternalMethodInstance(methodRef.mImplementingMethod);
  1594. mBestMethodDef = mBestMethodInstance.mMethodInstance->mMethodDef;
  1595. }
  1596. mBypassVirtual = true;
  1597. }
  1598. }
  1599. void BfMethodMatcher::CheckOuterTypeStaticMethods(BfTypeInstance* typeInstance, bool isFailurePass)
  1600. {
  1601. bool allowPrivate = true;
  1602. bool allowProtected = true;
  1603. auto curTypeInst = typeInstance;
  1604. auto curTypeDef = typeInstance->mTypeDef;
  1605. while (true)
  1606. {
  1607. curTypeDef->PopulateMemberSets();
  1608. BfMethodDef* nextMethodDef = NULL;
  1609. BfMemberSetEntry* entry;
  1610. if (curTypeDef->mMethodSet.TryGetWith(mMethodName, &entry))
  1611. nextMethodDef = (BfMethodDef*)entry->mMemberDef;
  1612. while (nextMethodDef != NULL)
  1613. {
  1614. auto checkMethod = nextMethodDef;
  1615. nextMethodDef = nextMethodDef->mNextWithSameName;
  1616. // These can only be invoked when the target itself is the interface
  1617. if (checkMethod->mExplicitInterface != NULL)
  1618. continue;
  1619. if ((checkMethod->mMethodType != BfMethodType_Normal) || (!checkMethod->mIsStatic))
  1620. continue;
  1621. if (checkMethod->mName != mMethodName)
  1622. continue;
  1623. if ((!isFailurePass) && (!mModule->CheckProtection(checkMethod->mProtection, allowProtected, allowPrivate)))
  1624. continue;
  1625. CheckMethod(curTypeInst, checkMethod, isFailurePass);
  1626. }
  1627. if (mBestMethodDef != NULL)
  1628. return;
  1629. auto baseType = curTypeInst->mBaseType;
  1630. if (baseType == NULL)
  1631. break;
  1632. curTypeDef = baseType->mTypeDef;
  1633. curTypeInst = baseType;
  1634. allowPrivate = false;
  1635. if ((isFailurePass) && (mBackupMethodDef != NULL))
  1636. break;
  1637. }
  1638. if (mBestMethodDef == NULL)
  1639. {
  1640. // FAILED, but select the first method which will fire an actual error on param type matching
  1641. mBestMethodDef = mBackupMethodDef;
  1642. }
  1643. if (mBestMethodDef == NULL)
  1644. {
  1645. // No explicit target - maybe this was a static call in the outer type?
  1646. auto outerType = mModule->GetOuterType(typeInstance);
  1647. if (outerType != NULL)
  1648. CheckOuterTypeStaticMethods(outerType, isFailurePass);
  1649. }
  1650. }
  1651. //////////////////////////////////////////////////////////////////////////
  1652. void BfResolvedArgs::HandleFixits(BfModule* module)
  1653. {
  1654. auto compiler = module->mCompiler;
  1655. if ((!compiler->IsAutocomplete()) || (compiler->mResolvePassData->mResolveType != BfResolveType_GetFixits))
  1656. return;
  1657. SetAndRestoreValue<bool> ignoreErrors(module->mIgnoreErrors, true);
  1658. for (int argIdx = 0; argIdx < (int)mResolvedArgs.size(); argIdx++)
  1659. {
  1660. auto& resolvedArg = mResolvedArgs[argIdx];
  1661. auto expr = BfNodeDynCast<BfExpression>(resolvedArg.mExpression);
  1662. if (expr != NULL)
  1663. {
  1664. module->CreateValueFromExpression(expr, resolvedArg.mExpectedType);
  1665. }
  1666. }
  1667. }
  1668. //////////////////////////////////////////////////////////////////////////
  1669. BfExprEvaluator::BfExprEvaluator(BfModule* module)
  1670. {
  1671. mBfEvalExprFlags = BfEvalExprFlags_None;
  1672. mModule = module;
  1673. mPropDef = NULL;
  1674. mPropSrc = NULL;
  1675. mPropGetMethodFlags = BfGetMethodInstanceFlag_None;
  1676. mPropCheckedKind = BfCheckedKind_NotSet;
  1677. mUsedAsStatement = false;
  1678. mPropDefBypassVirtual = false;
  1679. mExpectingType = NULL;
  1680. mFunctionBindResult = NULL;
  1681. mExplicitCast = false;
  1682. mDeferCallRef = NULL;
  1683. mDeferScopeAlloc = NULL;
  1684. mPrefixedAttributeState = NULL;
  1685. mResolveGenericParam = true;
  1686. mNoBind = false;
  1687. mResultLocalVar = NULL;
  1688. mResultLocalVarField = 0;
  1689. mResultLocalVarFieldCount = 0;
  1690. mResultLocalVarRefNode = NULL;
  1691. mIsVolatileReference = false;
  1692. mIsHeapReference = false;
  1693. mResultIsTempComposite = false;
  1694. mAllowReadOnlyReference = false;
  1695. mReceivingValue = NULL;
  1696. }
  1697. BfExprEvaluator::~BfExprEvaluator()
  1698. {
  1699. }
  1700. BfAutoComplete* BfExprEvaluator::GetAutoComplete()
  1701. {
  1702. if (mModule->mCompiler->mResolvePassData == NULL)
  1703. return NULL;
  1704. // For local methods- only process autocomplete on capture phase
  1705. if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) && (!mModule->mCurMethodState->mClosureState->mCapturing))
  1706. return NULL;
  1707. // if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mMethodDef->mIsLocalMethod))
  1708. // return NULL;
  1709. return mModule->mCompiler->mResolvePassData->mAutoComplete;
  1710. }
  1711. BfType* BfExprEvaluator::BindGenericType(BfAstNode* node, BfType* bindType)
  1712. {
  1713. if ((mModule->mCurMethodState == NULL) || (mModule->mCurMethodInstance == NULL) || (bindType == NULL))
  1714. return bindType;
  1715. BF_ASSERT(!mModule->mCurMethodInstance->mIsUnspecializedVariation);
  1716. auto parser = node->GetSourceData()->ToParserData();
  1717. if (parser == NULL)
  1718. return bindType;
  1719. int64 nodeId = ((int64)parser->mDataId << 32) + node->GetSrcStart();
  1720. if (mModule->mCurMethodInstance->mIsUnspecialized)
  1721. {
  1722. if (!bindType->IsGenericParam())
  1723. return bindType;
  1724. (*mModule->mCurMethodState->mGenericTypeBindings)[nodeId] = bindType;
  1725. return bindType;
  1726. }
  1727. else
  1728. {
  1729. if (mModule->mCurMethodState->mGenericTypeBindings == NULL)
  1730. return bindType;
  1731. /*auto itr = mModule->mCurMethodState->mGenericTypeBindings->find(nodeId);
  1732. if (itr != mModule->mCurMethodState->mGenericTypeBindings->end())
  1733. return itr->second;*/
  1734. BfType** typePtr = NULL;
  1735. if (mModule->mCurMethodState->mGenericTypeBindings->TryGetValue(nodeId, &typePtr))
  1736. return *typePtr;
  1737. return bindType;
  1738. }
  1739. }
  1740. BfType * BfExprEvaluator::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags)
  1741. {
  1742. if (mExpectingType != NULL)
  1743. {
  1744. if (auto namedTypeRef = BfNodeDynCastExact<BfNamedTypeReference>(typeRef))
  1745. {
  1746. if (namedTypeRef->ToString() == "ExpectedType")
  1747. {
  1748. return mModule->ResolveTypeResult(typeRef, mExpectingType, populateType, resolveFlags);
  1749. }
  1750. }
  1751. }
  1752. return mModule->ResolveTypeRef(typeRef, populateType, resolveFlags);
  1753. }
  1754. void BfExprEvaluator::ResolveGenericType()
  1755. {
  1756. if (mResult)
  1757. {
  1758. if (mModule->IsUnboundGeneric(mResult.mType))
  1759. mResult.mType = mModule->GetPrimitiveType(BfTypeCode_Var);
  1760. //mResult.mType = mModule->ResolveGenericType(mResult.mType, true);
  1761. }
  1762. }
  1763. void BfExprEvaluator::Evaluate(BfAstNode* astNode, bool propogateNullConditional, bool ignoreNullConditional, bool allowSplat)
  1764. {
  1765. BP_ZONE("BfExprEvaluator::Evaluate");
  1766. // ParenthesizedExpression breaks null conditional chain
  1767. if (astNode->IsExact<BfParenthesizedExpression>())
  1768. propogateNullConditional = false;
  1769. BfPendingNullConditional* pendingNullCond = NULL;
  1770. if (mModule->mCurMethodState != NULL)
  1771. {
  1772. pendingNullCond = mModule->mCurMethodState->mPendingNullConditional;
  1773. if (!propogateNullConditional)
  1774. mModule->mCurMethodState->mPendingNullConditional = NULL;
  1775. }
  1776. astNode->Accept(this);
  1777. GetResult();
  1778. if ((mResultIsTempComposite) && (mResult.IsAddr()))
  1779. mResult.mKind = BfTypedValueKind_TempAddr;
  1780. if ((!allowSplat) && (mResult.IsSplat()))
  1781. mResult = mModule->AggregateSplat(mResult);
  1782. if ((mBfEvalExprFlags & BfEvalExprFlags_AllowIntUnknown) == 0)
  1783. mModule->FixIntUnknown(mResult);
  1784. if ((!propogateNullConditional) && (mModule->mCurMethodState != NULL))
  1785. {
  1786. if (mModule->mCurMethodState->mPendingNullConditional != NULL)
  1787. mResult = mModule->FlushNullConditional(mResult, ignoreNullConditional);
  1788. mModule->mCurMethodState->mPendingNullConditional = pendingNullCond;
  1789. }
  1790. }
  1791. void BfExprEvaluator::Visit(BfTypeReference* typeRef)
  1792. {
  1793. mResult.mType = ResolveTypeRef(typeRef, BfPopulateType_Declaration);
  1794. }
  1795. void BfExprEvaluator::Visit(BfAttributedExpression* attribExpr)
  1796. {
  1797. BfAttributeState attributeState;
  1798. attributeState.mTarget = (BfAttributeTargets)(BfAttributeTargets_Invocation | BfAttributeTargets_MemberAccess);
  1799. attributeState.mCustomAttributes = mModule->GetCustomAttributes(attribExpr->mAttributes, attributeState.mTarget);
  1800. SetAndRestoreValue<BfAttributeState*> prevAttributeState(mModule->mAttributeState, &attributeState);
  1801. VisitChild(attribExpr->mExpression);
  1802. if (!attributeState.mUsed)
  1803. {
  1804. mModule->Fail("Unused attributes", attribExpr->mAttributes);
  1805. }
  1806. }
  1807. void BfExprEvaluator::Visit(BfBlock* blockExpr)
  1808. {
  1809. if (mModule->mCurMethodState == NULL)
  1810. {
  1811. mModule->Fail("Illegal use of block expression", blockExpr);
  1812. return;
  1813. }
  1814. auto autoComplete = GetAutoComplete();
  1815. if ((autoComplete != NULL) && (autoComplete->mMethodMatchInfo != NULL) && (autoComplete->IsAutocompleteNode(blockExpr)))
  1816. {
  1817. // Don't show outer method match info when our cursor is inside a block (being passed as a parameter)
  1818. autoComplete->RemoveMethodMatchInfo();
  1819. }
  1820. if (blockExpr->mChildArr.IsEmpty())
  1821. {
  1822. mModule->Fail("An empty block cannot be used as an expression", blockExpr);
  1823. return;
  1824. }
  1825. bool lastWasResultExpr = false;
  1826. if (auto lastExpr = BfNodeDynCast<BfExpressionStatement>(blockExpr->mChildArr.GetLast()))
  1827. {
  1828. if (!lastExpr->IsMissingSemicolon())
  1829. mModule->Fail("Expression blocks must end in an expression which is missing its terminating semicolon", lastExpr->mTrailingSemicolon);
  1830. }
  1831. else if (auto lastExpr = BfNodeDynCast<BfExpression>(blockExpr->mChildArr.GetLast()))
  1832. {
  1833. // Expression
  1834. }
  1835. else
  1836. {
  1837. mModule->Fail("Expression blocks must end with an expression", blockExpr);
  1838. }
  1839. mModule->VisitEmbeddedStatement(blockExpr, this);
  1840. }
  1841. bool BfExprEvaluator::CheckVariableDeclaration(BfAstNode* checkNode, bool requireSimpleIfExpr, bool exprMustBeTrue, bool silentFail)
  1842. {
  1843. BfAstNode* checkChild = checkNode;
  1844. bool foundIf = false;
  1845. auto parentNodeEntry = mModule->mParentNodeEntry;
  1846. if (parentNodeEntry != NULL)
  1847. {
  1848. if (BfNodeIsA<BfInvocationExpression>(parentNodeEntry->mNode))
  1849. {
  1850. checkChild = parentNodeEntry->mNode;
  1851. parentNodeEntry = parentNodeEntry->mPrev;
  1852. }
  1853. }
  1854. while (parentNodeEntry != NULL)
  1855. {
  1856. BfAstNode* checkParent = parentNodeEntry->mNode;
  1857. if (auto binOpExpr = BfNodeDynCastExact<BfBinaryOperatorExpression>(checkParent))
  1858. {
  1859. if (binOpExpr->mOp == BfBinaryOp_ConditionalAnd)
  1860. {
  1861. // This is always okay
  1862. }
  1863. else if ((binOpExpr->mOp == BfBinaryOp_ConditionalOr) && (!exprMustBeTrue))
  1864. {
  1865. bool matches = false;
  1866. auto checkRight = binOpExpr->mRight;
  1867. while (checkRight != NULL)
  1868. {
  1869. if (checkRight == checkChild)
  1870. {
  1871. matches = true;
  1872. break;
  1873. }
  1874. if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(checkRight))
  1875. checkRight = parenExpr->mExpression;
  1876. else
  1877. {
  1878. break;
  1879. }
  1880. }
  1881. if (matches)
  1882. {
  1883. if (!silentFail)
  1884. mModule->Fail("Conditional short-circuiting may skip variable initialization", binOpExpr->mOpToken);
  1885. return false;
  1886. }
  1887. }
  1888. else
  1889. {
  1890. if (exprMustBeTrue)
  1891. {
  1892. if (!silentFail)
  1893. mModule->Fail("Operator cannot be used with variable initialization", binOpExpr->mOpToken);
  1894. return false;
  1895. }
  1896. }
  1897. }
  1898. else if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(checkParent))
  1899. {
  1900. // This is okay
  1901. }
  1902. else if (auto unaryOp = BfNodeDynCast<BfUnaryOperatorExpression>(checkParent))
  1903. {
  1904. if (exprMustBeTrue)
  1905. {
  1906. if (!silentFail)
  1907. mModule->Fail("Operator cannot be used with variable initialization", unaryOp->mOpToken);
  1908. return false;
  1909. }
  1910. }
  1911. else if (auto ifStmt = BfNodeDynCast<BfIfStatement>(checkParent))
  1912. {
  1913. // Done
  1914. foundIf = true;
  1915. break;
  1916. }
  1917. else
  1918. {
  1919. if (requireSimpleIfExpr)
  1920. {
  1921. if (!silentFail)
  1922. mModule->Fail("Variable declaration expression can only be contained in simple 'if' expressions", checkNode);
  1923. return false;
  1924. }
  1925. break;
  1926. }
  1927. checkChild = parentNodeEntry->mNode;
  1928. parentNodeEntry = parentNodeEntry->mPrev;
  1929. }
  1930. return foundIf;
  1931. }
  1932. bool BfExprEvaluator::HasVariableDeclaration(BfAstNode* checkNode)
  1933. {
  1934. BfVarDeclChecker checker;
  1935. checker.VisitChild(checkNode);
  1936. return checker.mHasVarDecl;
  1937. }
  1938. void BfExprEvaluator::Visit(BfVariableDeclaration* varDecl)
  1939. {
  1940. mModule->UpdateExprSrcPos(varDecl);
  1941. CheckVariableDeclaration(varDecl, true, false, false);
  1942. if (varDecl->mInitializer == NULL)
  1943. {
  1944. mModule->Fail("Variable declarations used as expressions must have an initializer", varDecl);
  1945. }
  1946. BfTupleExpression* tupleVariableDeclaration = BfNodeDynCast<BfTupleExpression>(varDecl->mNameNode);
  1947. if (tupleVariableDeclaration != NULL)
  1948. {
  1949. mModule->Fail("Tuple variable declarations cannot be used as expressions", varDecl);
  1950. mModule->HandleTupleVariableDeclaration(varDecl);
  1951. }
  1952. else
  1953. mModule->HandleVariableDeclaration(varDecl, this);
  1954. }
  1955. void BfExprEvaluator::Visit(BfCaseExpression* caseExpr)
  1956. {
  1957. if (caseExpr->mEqualsNode != NULL)
  1958. {
  1959. mModule->Warn(0, "Deprecated case syntax", caseExpr->mEqualsNode);
  1960. }
  1961. BfTypedValue caseValAddr;
  1962. if (caseExpr->mValueExpression != NULL)
  1963. caseValAddr = mModule->CreateValueFromExpression(caseExpr->mValueExpression);
  1964. if (caseValAddr.mType != NULL)
  1965. mModule->mBfIRBuilder->PopulateType(caseValAddr.mType);
  1966. if (mModule->mCurMethodState->mDeferredLocalAssignData != NULL)
  1967. mModule->mCurMethodState->mDeferredLocalAssignData->BreakExtendChain();
  1968. if (auto bindExpr = BfNodeDynCast<BfEnumCaseBindExpression>(caseExpr->mCaseExpression))
  1969. {
  1970. if (caseValAddr)
  1971. {
  1972. BfTypedValue enumTagVal;
  1973. if (caseValAddr.mType->IsPayloadEnum())
  1974. {
  1975. int dscrDataIdx;
  1976. auto dscrType = caseValAddr.mType->ToTypeInstance()->GetDiscriminatorType(&dscrDataIdx);
  1977. enumTagVal = BfTypedValue(mModule->ExtractValue(caseValAddr, dscrDataIdx), dscrType);
  1978. }
  1979. else
  1980. enumTagVal = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Int32));
  1981. mResult = mModule->HandleCaseBind(caseValAddr, enumTagVal, bindExpr);
  1982. return;
  1983. }
  1984. }
  1985. if ((caseValAddr) && (caseValAddr.mType->IsPayloadEnum()))
  1986. {
  1987. bool hasVariable = false;
  1988. bool hasOut = false;
  1989. bool clearOutOnMismatch = false;
  1990. if (auto invocateExpr = BfNodeDynCast<BfInvocationExpression>(caseExpr->mCaseExpression))
  1991. {
  1992. for (auto arg : invocateExpr->mArguments)
  1993. {
  1994. if (auto varDecl = BfNodeDynCast<BfVariableDeclaration>(arg))
  1995. {
  1996. hasVariable = true;
  1997. }
  1998. else if (auto unaryOpExpr = BfNodeDynCast<BfUnaryOperatorExpression>(arg))
  1999. {
  2000. if (unaryOpExpr->mOpToken->mToken == BfToken_Out)
  2001. {
  2002. hasOut = true;
  2003. }
  2004. }
  2005. }
  2006. }
  2007. if (hasVariable)
  2008. {
  2009. CheckVariableDeclaration(caseExpr, false, true, false);
  2010. }
  2011. // We can avoid clearing on mismatch if we can be sure we ONLY enter the true block on a match.
  2012. // An example of requiring clearing is: if ((result case .Ok(out val)) || (force))
  2013. if (hasOut)
  2014. clearOutOnMismatch = !CheckVariableDeclaration(caseExpr, true, true, true);
  2015. int dscrDataIdx;
  2016. auto dscrType = caseValAddr.mType->ToTypeInstance()->GetDiscriminatorType(&dscrDataIdx);
  2017. auto enumTagVal = mModule->LoadValue(mModule->ExtractValue(caseValAddr, NULL, 2));
  2018. int uncondTagId = -1;
  2019. bool hadConditional = false;
  2020. mResult = mModule->TryCaseEnumMatch(caseValAddr, enumTagVal, caseExpr->mCaseExpression, NULL, NULL, NULL, uncondTagId, hadConditional, clearOutOnMismatch);
  2021. if (mResult)
  2022. return;
  2023. }
  2024. if ((caseValAddr) && (caseValAddr.mType->IsVar()))
  2025. {
  2026. auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(caseExpr->mCaseExpression);
  2027. if (invocationExpr != NULL)
  2028. {
  2029. for (auto expr : invocationExpr->mArguments)
  2030. {
  2031. if (expr == NULL)
  2032. continue;
  2033. if (auto varDecl = BfNodeDynCast<BfVariableDeclaration>(expr))
  2034. {
  2035. auto localVar = mModule->HandleVariableDeclaration(varDecl, BfTypedValue());
  2036. if (localVar != NULL)
  2037. localVar->mReadFromId = 0;
  2038. }
  2039. }
  2040. }
  2041. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  2042. mResult = mModule->GetDefaultTypedValue(boolType);
  2043. return;
  2044. }
  2045. if ((caseValAddr.mType != NULL) && (caseValAddr.mType->IsPointer()))
  2046. {
  2047. caseValAddr = mModule->LoadValue(caseValAddr);
  2048. caseValAddr = BfTypedValue(caseValAddr.mValue, caseValAddr.mType->GetUnderlyingType(), true);
  2049. }
  2050. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  2051. BfTypedValue caseMatch;
  2052. if (caseExpr->mCaseExpression != NULL)
  2053. caseMatch = mModule->CreateValueFromExpression(caseExpr->mCaseExpression, caseValAddr.mType, BfEvalExprFlags_AllowEnumId);
  2054. if ((!caseMatch) || (!caseValAddr))
  2055. {
  2056. mResult = mModule->GetDefaultTypedValue(boolType);
  2057. return;
  2058. }
  2059. if (caseValAddr.mType == caseMatch.mType)
  2060. {
  2061. if (((caseValAddr.mType->IsEnum()) && (caseValAddr.mType->IsStruct())) &&
  2062. ((caseMatch) && (caseMatch.mType->IsPayloadEnum()) && (caseMatch.mValue.IsConst())))
  2063. {
  2064. BfTypedValue enumTagVal = mModule->LoadValue(mModule->ExtractValue(caseValAddr, NULL, 2));
  2065. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(enumTagVal.mValue, caseMatch.mValue), boolType);
  2066. return;
  2067. }
  2068. }
  2069. else
  2070. {
  2071. // We need to get rid of the int-const for the 'scalar match'. We get a full payload enum value so we can
  2072. // possibly use it in a user-defined comparison operator
  2073. if ((caseMatch.mType->IsStruct()) && (caseMatch.mValue.IsConst()))
  2074. {
  2075. // Is it possible this could throw an error twice? Hope not.
  2076. caseMatch = mModule->CreateValueFromExpression(caseExpr->mCaseExpression, NULL);
  2077. }
  2078. }
  2079. PerformBinaryOperation(caseExpr->mCaseExpression, caseExpr->mValueExpression, BfBinaryOp_Equality, caseExpr->mEqualsNode, BfBinOpFlag_None, caseValAddr, caseMatch);
  2080. }
  2081. void BfExprEvaluator::Visit(BfTypedValueExpression* typedValueExpr)
  2082. {
  2083. mResult = typedValueExpr->mTypedValue;
  2084. }
  2085. static bool IsCharType(BfTypeCode typeCode)
  2086. {
  2087. switch (typeCode)
  2088. {
  2089. case BfTypeCode_Char8:
  2090. case BfTypeCode_Char16:
  2091. case BfTypeCode_Char32:
  2092. return true;
  2093. default:
  2094. return false;
  2095. }
  2096. }
  2097. void BfExprEvaluator::GetLiteral(BfAstNode* refNode, const BfVariant& variant)
  2098. {
  2099. switch (variant.mTypeCode)
  2100. {
  2101. case BfTypeCode_NullPtr:
  2102. {
  2103. auto nullType = mModule->ResolveTypeDef(mModule->mSystem->mTypeNullPtr);
  2104. /*mResult = BfTypedValue(ConstantPointerNull::get((PointerType*) nullType->mIRType), nullType);*/
  2105. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConstNull(), nullType);
  2106. }
  2107. break;
  2108. case BfTypeCode_CharPtr:
  2109. {
  2110. if ((mExpectingType != NULL) && (mExpectingType->IsSizedArray()))
  2111. {
  2112. auto sizedArray = (BfSizedArrayType*)mExpectingType;
  2113. if (sizedArray->mElementType == mModule->GetPrimitiveType(BfTypeCode_Char8))
  2114. {
  2115. if (variant.mString->GetLength() > sizedArray->mElementCount)
  2116. {
  2117. mModule->Fail(StrFormat("String literal is too long to fit into '%s'", mModule->TypeToString(sizedArray).c_str()), refNode);
  2118. }
  2119. Array<BfIRValue> charValues;
  2120. for (int i = 0; i < (int)BF_MIN(variant.mString->GetLength(), sizedArray->mElementCount); i++)
  2121. {
  2122. char c = (*variant.mString)[i];
  2123. charValues.Add(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Char8, (int)(uint8)c));
  2124. }
  2125. if (sizedArray->mElementCount > charValues.size())
  2126. charValues.Add(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Char8, 0));
  2127. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConstArray(mModule->mBfIRBuilder->MapType(sizedArray), charValues), sizedArray);
  2128. return;
  2129. }
  2130. }
  2131. if ((mExpectingType == NULL) || (!mExpectingType->IsPointer()))
  2132. {
  2133. mResult = BfTypedValue(mModule->GetStringObjectValue(*variant.mString),
  2134. mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
  2135. }
  2136. else
  2137. {
  2138. auto charType = mModule->GetPrimitiveType(BfTypeCode_Char8);
  2139. auto charPtrType = mModule->CreatePointerType(charType);
  2140. mResult = BfTypedValue(mModule->GetStringCharPtr(*variant.mString),
  2141. charPtrType);
  2142. }
  2143. }
  2144. break;
  2145. case BfTypeCode_Boolean:
  2146. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(variant.mTypeCode, variant.mUInt64), mModule->GetPrimitiveType(variant.mTypeCode));
  2147. break;
  2148. case BfTypeCode_Char8:
  2149. case BfTypeCode_Char16:
  2150. case BfTypeCode_Char32:
  2151. case BfTypeCode_Int8:
  2152. case BfTypeCode_UInt8:
  2153. case BfTypeCode_Int16:
  2154. case BfTypeCode_UInt16:
  2155. case BfTypeCode_Int32:
  2156. case BfTypeCode_UInt32:
  2157. case BfTypeCode_Int64:
  2158. case BfTypeCode_UInt64:
  2159. case BfTypeCode_IntPtr:
  2160. case BfTypeCode_UIntPtr:
  2161. case BfTypeCode_IntUnknown:
  2162. case BfTypeCode_UIntUnknown:
  2163. if ((mExpectingType != NULL) && (mExpectingType->IsIntegral()) && (mExpectingType->IsChar() == IsCharType(variant.mTypeCode)))
  2164. {
  2165. auto primType = (BfPrimitiveType*)mExpectingType;
  2166. if (mModule->mSystem->DoesLiteralFit(primType->mTypeDef->mTypeCode, variant.mInt64))
  2167. {
  2168. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, variant.mUInt64), mExpectingType);
  2169. break;
  2170. }
  2171. }
  2172. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(variant.mTypeCode, variant.mUInt64), mModule->GetPrimitiveType(variant.mTypeCode));
  2173. break;
  2174. case BfTypeCode_Single:
  2175. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(variant.mTypeCode, variant.mSingle), mModule->GetPrimitiveType(variant.mTypeCode));
  2176. break;
  2177. case BfTypeCode_Double:
  2178. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(variant.mTypeCode, variant.mDouble), mModule->GetPrimitiveType(variant.mTypeCode));
  2179. break;
  2180. default:
  2181. mModule->Fail("Invalid literal", refNode);
  2182. break;
  2183. }
  2184. }
  2185. void BfExprEvaluator::Visit(BfLiteralExpression* literalExpr)
  2186. {
  2187. switch (literalExpr->mValue.mWarnType)
  2188. {
  2189. case BfWarning_BF4201_Only7Hex:
  2190. mModule->Warn(BfWarning_BF4201_Only7Hex, "Only 7 hex digits specified. Add a leading zero to clarify intention.", literalExpr);
  2191. break;
  2192. case BfWarning_BF4202_TooManyHexForInt:
  2193. mModule->Warn(BfWarning_BF4202_TooManyHexForInt, "Too many hex digits for an int, but too few for a long. Use 'L' suffix if a long was intended.", literalExpr);
  2194. break;
  2195. }
  2196. GetLiteral(literalExpr, literalExpr->mValue);
  2197. }
  2198. BfTypedValue BfExprEvaluator::LoadLocal(BfLocalVariable* varDecl, bool allowRef)
  2199. {
  2200. if (!mModule->mIsInsideAutoComplete)
  2201. varDecl->mReadFromId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++;
  2202. // The Beef backend prefers readonly addrs since that reduces register pressure, whereas
  2203. // LLVM prefers values to avoid memory loads. This only applies to primitive types...
  2204. bool preferValue = (varDecl->mResolvedType->IsPrimitiveType()) && (!mModule->IsTargetingBeefBackend());
  2205. BfTypedValue localResult;
  2206. if (varDecl->mIsThis)
  2207. {
  2208. return mModule->GetThis();
  2209. }
  2210. else if (varDecl->mConstValue)
  2211. {
  2212. localResult = BfTypedValue(varDecl->mConstValue, varDecl->mResolvedType, false);
  2213. }
  2214. else if (varDecl->mIsSplat)
  2215. {
  2216. if ((!preferValue) && (varDecl->mAddr))
  2217. localResult = BfTypedValue(varDecl->mAddr, varDecl->mResolvedType, BfTypedValueKind_SplatHead);
  2218. else if (!varDecl->mResolvedType->IsValuelessType())
  2219. localResult = BfTypedValue(varDecl->mValue, varDecl->mResolvedType, BfTypedValueKind_SplatHead);
  2220. else
  2221. localResult = BfTypedValue(varDecl->mValue, varDecl->mResolvedType);
  2222. //BF_ASSERT(varDecl->mValue.IsArg());
  2223. }
  2224. else if ((varDecl->mValue) && ((varDecl->mIsReadOnly && preferValue) || (!varDecl->mAddr)))
  2225. {
  2226. if ((varDecl->mResolvedType->IsRef()) && (!allowRef))
  2227. {
  2228. BfRefType* refType = (BfRefType*)varDecl->mResolvedType;
  2229. BfType* innerType = refType->mElementType;
  2230. if (innerType->IsGenericParam())
  2231. {
  2232. if (refType->mRefKind == BfRefType::RefKind_Mut)
  2233. {
  2234. localResult = BfTypedValue(varDecl->mValue, innerType, BfTypedValueKind_MutableValue);
  2235. return localResult;
  2236. }
  2237. else
  2238. {
  2239. localResult = BfTypedValue(varDecl->mValue, innerType, BfTypedValueKind_Addr);
  2240. return localResult;
  2241. }
  2242. }
  2243. localResult = BfTypedValue(varDecl->mValue, innerType, BfTypedValueKind_Addr);
  2244. }
  2245. else
  2246. {
  2247. BfTypedValueKind kind;
  2248. if ((varDecl->mResolvedType->IsComposite()) && (varDecl->IsParam()) && (mModule->mCurMethodState->mMixinState == NULL))
  2249. kind = varDecl->mIsReadOnly ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr;
  2250. else
  2251. kind = BfTypedValueKind_Value;
  2252. localResult = BfTypedValue(varDecl->mValue, varDecl->mResolvedType, kind);
  2253. }
  2254. }
  2255. else if (varDecl->mAddr)
  2256. {
  2257. if ((varDecl->mResolvedType->IsRef()) && (!allowRef))
  2258. {
  2259. BfRefType* refType = (BfRefType*)varDecl->mResolvedType;
  2260. BfType* innerType = refType->mElementType;
  2261. if (innerType->IsValuelessType())
  2262. {
  2263. if (refType->mRefKind == BfRefType::RefKind_Mut)
  2264. return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), innerType, BfTypedValueKind_MutableValue);
  2265. return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), innerType, varDecl->mIsReadOnly ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
  2266. }
  2267. if (refType->mRefKind == BfRefType::RefKind_Mut)
  2268. {
  2269. if (innerType->IsGenericParam())
  2270. {
  2271. localResult = BfTypedValue(mModule->mBfIRBuilder->CreateAlignedLoad(varDecl->mAddr, varDecl->mResolvedType->mAlign), innerType, BfTypedValueKind_MutableValue);
  2272. return localResult;
  2273. }
  2274. }
  2275. localResult = BfTypedValue(mModule->mBfIRBuilder->CreateAlignedLoad(varDecl->mAddr, varDecl->mResolvedType->mAlign), innerType, varDecl->mIsReadOnly ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
  2276. }
  2277. else if (varDecl->mHasLocalStructBacking)
  2278. {
  2279. // varDecl->mAddr is a "struct**"
  2280. localResult = BfTypedValue(mModule->mBfIRBuilder->CreateAlignedLoad(varDecl->mAddr, varDecl->mResolvedType->mAlign), varDecl->mResolvedType, true);
  2281. }
  2282. else
  2283. localResult = BfTypedValue(varDecl->mAddr, varDecl->mResolvedType, varDecl->mIsReadOnly ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
  2284. }
  2285. else if (varDecl->mResolvedType->IsValuelessType())
  2286. {
  2287. if ((varDecl->mResolvedType->IsRef()) && (!allowRef))
  2288. {
  2289. BfRefType* refType = (BfRefType*)varDecl->mResolvedType;
  2290. BfType* innerType = refType->mElementType;
  2291. localResult = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), innerType, true);
  2292. return localResult;
  2293. }
  2294. localResult = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), varDecl->mResolvedType, true);
  2295. }
  2296. else if (varDecl->mCompositeCount >= 0)
  2297. {
  2298. localResult = BfTypedValue(BfIRValue(), mModule->GetPrimitiveType(BfTypeCode_None));
  2299. }
  2300. else
  2301. {
  2302. BF_ASSERT((mModule->mCurMethodState->mClosureState != NULL) || (mModule->mBfIRBuilder->mIgnoreWrites));
  2303. // Just temporary
  2304. auto varType = varDecl->mResolvedType;
  2305. auto allocType = varType;
  2306. if (varType->IsRef())
  2307. {
  2308. BfRefType* refType = (BfRefType*)varType;
  2309. allocType = refType->mElementType;
  2310. }
  2311. auto declType = varDecl->mResolvedType;
  2312. if (declType->IsRef())
  2313. {
  2314. BfRefType* refType = (BfRefType*)declType;
  2315. declType = refType->mElementType;
  2316. }
  2317. mModule->PopulateType(allocType);
  2318. varDecl->mAddr = mModule->mBfIRBuilder->CreateAlloca(mModule->mBfIRBuilder->MapType(allocType));
  2319. localResult = BfTypedValue(varDecl->mAddr, declType, true);
  2320. return localResult;
  2321. }
  2322. if ((varDecl->mIsThis) && (localResult.mKind == BfTypedValueKind_Value))
  2323. localResult.mKind = BfTypedValueKind_ThisValue;
  2324. return localResult;
  2325. }
  2326. BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringImpl& findName, bool ignoreInitialError, bool* hadError)
  2327. {
  2328. auto identifierNode = BfNodeDynCast<BfIdentifierNode>(refNode);
  2329. if (mModule->mCurMethodState != NULL)
  2330. {
  2331. auto rootMethodState = mModule->mCurMethodState->GetRootMethodState();
  2332. auto checkMethodState = mModule->mCurMethodState;
  2333. bool isMixinOuterVariablePass = false;
  2334. while (checkMethodState != NULL)
  2335. {
  2336. BP_ZONE("LookupIdentifier:LocalVar");
  2337. BfTypeInstance* closureTypeInst = NULL;
  2338. if ((checkMethodState->mClosureState != NULL) && (checkMethodState->mClosureState->mClosureType != NULL) && (!checkMethodState->mClosureState->mCapturing))
  2339. {
  2340. closureTypeInst = mModule->mCurMethodState->mClosureState->mClosureType;
  2341. }
  2342. int varSkipCount = 0;
  2343. StringT<128> wantName = findName;
  2344. while (wantName.StartsWith("@"))
  2345. {
  2346. varSkipCount++;
  2347. wantName.Remove(0);
  2348. }
  2349. if (wantName.IsEmpty())
  2350. {
  2351. mModule->Fail("Shadowed variable name expected after '@'", refNode);
  2352. }
  2353. BfLocalVarEntry* entry;
  2354. if (checkMethodState->mLocalVarSet.TryGetWith<StringImpl&>(wantName, &entry))
  2355. {
  2356. auto varDecl = entry->mLocalVar;
  2357. while ((varSkipCount > 0) && (varDecl != NULL))
  2358. {
  2359. varDecl = varDecl->mShadowedLocal;
  2360. varSkipCount--;
  2361. }
  2362. if ((varSkipCount == 0) && (varDecl != NULL))
  2363. {
  2364. if ((closureTypeInst != NULL) && (wantName == "this"))
  2365. break;
  2366. if ((varDecl->mCompositeCount >= 0) && ((mBfEvalExprFlags & BfEvalExprFlags_AllowParamsExpr) == 0))
  2367. {
  2368. mModule->Fail("Invalid use of 'params' parameter", refNode);
  2369. }
  2370. if (varDecl->mResolvedType->IsVoid())
  2371. {
  2372. if ((varDecl->mIsReadOnly) && (varDecl->mParamIdx == -2) && (varDecl->mParamFailed))
  2373. {
  2374. BF_ASSERT(mModule->mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_CtorCalcAppend);
  2375. 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);
  2376. }
  2377. }
  2378. BfTypedValue localResult = LoadLocal(varDecl);
  2379. auto autoComplete = GetAutoComplete();
  2380. if (identifierNode != NULL)
  2381. {
  2382. if (autoComplete != NULL)
  2383. autoComplete->CheckLocalRef(identifierNode, varDecl);
  2384. if (((mModule->mCurMethodState->mClosureState == NULL) || (mModule->mCurMethodState->mClosureState->mCapturing)) &&
  2385. (mModule->mCompiler->mResolvePassData != NULL) && (mModule->mCurMethodInstance != NULL))
  2386. mModule->mCompiler->mResolvePassData->HandleLocalReference(identifierNode, varDecl->mNameNode, mModule->mCurTypeInstance->mTypeDef, rootMethodState->mMethodInstance->mMethodDef, varDecl->mLocalVarId);
  2387. }
  2388. if (!isMixinOuterVariablePass)
  2389. {
  2390. mResultLocalVar = varDecl;
  2391. mResultLocalVarRefNode = identifierNode;
  2392. }
  2393. return localResult;
  2394. }
  2395. }
  2396. // Check for the captured locals. It's important we do it here so we get local-first precedence still
  2397. if (closureTypeInst != NULL)
  2398. {
  2399. closureTypeInst->mTypeDef->PopulateMemberSets();
  2400. BfMemberSetEntry* memberSetEntry = NULL;
  2401. if (closureTypeInst->mTypeDef->mFieldSet.TryGetWith(findName, &memberSetEntry))
  2402. {
  2403. auto fieldDef = (BfFieldDef*)memberSetEntry->mMemberDef;
  2404. auto& field = closureTypeInst->mFieldInstances[fieldDef->mIdx];
  2405. if (!field.mResolvedType->IsValuelessType())
  2406. {
  2407. if (mModule->mCurMethodState->mClosureState->mCapturing)
  2408. {
  2409. mModule->mCurMethodState->mClosureState->mReferencedOuterClosureMembers.Add(&field);
  2410. return mModule->GetDefaultTypedValue(field.mResolvedType);
  2411. }
  2412. auto localVar = mModule->mCurMethodState->mLocals[0];
  2413. auto thisValue = localVar->mValue;
  2414. mModule->mBfIRBuilder->PopulateType(localVar->mResolvedType);
  2415. BfTypedValue result = BfTypedValue(mModule->mBfIRBuilder->CreateInBoundsGEP(thisValue, 0, field.mDataIdx), field.mResolvedType, true);
  2416. if (field.mResolvedType->IsRef())
  2417. {
  2418. auto refType = (BfRefType*)field.mResolvedType;
  2419. auto underlyingType = refType->GetUnderlyingType();
  2420. result = BfTypedValue(mModule->mBfIRBuilder->CreateLoad(result.mValue), underlyingType, true);
  2421. }
  2422. else if (fieldDef->mIsReadOnly)
  2423. result = mModule->LoadValue(result);
  2424. mResultLocalVar = localVar;
  2425. mResultLocalVarField = -(field.mMergedDataIdx + 1);
  2426. return result;
  2427. }
  2428. }
  2429. }
  2430. if ((checkMethodState->mClosureState != NULL) && (checkMethodState->mClosureState->mCapturing) /*&& (checkMethodState->mClosureState->mIsLocalMethod)*/)
  2431. {
  2432. checkMethodState = checkMethodState->mPrevMethodState;
  2433. continue;
  2434. }
  2435. // Allow local mixin to see outside variables during its processing -- since we don't actually "capture" those into params
  2436. bool isLocalMixinProcessing = false;
  2437. if ((checkMethodState->mClosureState != NULL) && (!checkMethodState->mClosureState->mCapturing) && (closureTypeInst == NULL) &&
  2438. (mModule->mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_Mixin))
  2439. isLocalMixinProcessing = true;
  2440. if (!isLocalMixinProcessing)
  2441. break;
  2442. isMixinOuterVariablePass = true;
  2443. checkMethodState = checkMethodState->mPrevMethodState;
  2444. }
  2445. }
  2446. BfTypedValue thisValue = mModule->GetThis();
  2447. bool forcedIFaceLookup = false;
  2448. if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsForeignMethodDef))
  2449. {
  2450. thisValue.mType = mModule->mCurMethodInstance->GetForeignType();
  2451. forcedIFaceLookup = true;
  2452. }
  2453. if (thisValue)
  2454. {
  2455. if (findName == "this")
  2456. return thisValue;
  2457. if (findName == "base")
  2458. {
  2459. auto baseValue = thisValue;
  2460. if (baseValue.IsThis())
  2461. baseValue.ToBase();
  2462. if (mModule->GetActiveTypeDef()->mTypeCode != BfTypeCode_Extension)
  2463. {
  2464. MakeBaseConcrete(baseValue);
  2465. }
  2466. return baseValue;
  2467. }
  2468. if (!mModule->mCurMethodState->HasNonStaticMixin())
  2469. {
  2470. mResultLocalVar = mModule->GetThisVariable();
  2471. mResultLocalVarRefNode = identifierNode;
  2472. }
  2473. }
  2474. if (!thisValue)
  2475. thisValue = BfTypedValue(mModule->mCurTypeInstance);
  2476. BfTypedValue result = LookupField(identifierNode, thisValue, findName, BfLookupFieldFlag_IsImplicitThis);
  2477. if (mPropDef != NULL)
  2478. {
  2479. if (forcedIFaceLookup)
  2480. {
  2481. }
  2482. }
  2483. if ((!result) && (mPropDef == NULL))
  2484. {
  2485. if (mModule->mContext->mCurTypeState != NULL)
  2486. {
  2487. // This is not necessarily true since we changed ConstResolver
  2488. //BF_ASSERT(mModule->mCurTypeInstance == mModule->mContext->mCurTypeState->mTypeInstance);
  2489. BfGlobalLookup globalLookup;
  2490. globalLookup.mKind = BfGlobalLookup::Kind_Field;
  2491. globalLookup.mName = findName;
  2492. mModule->PopulateGlobalContainersList(globalLookup);
  2493. for (auto& globalContainer : mModule->mContext->mCurTypeState->mGlobalContainers)
  2494. {
  2495. if (globalContainer.mTypeInst == NULL)
  2496. continue;
  2497. thisValue = BfTypedValue(globalContainer.mTypeInst);
  2498. result = LookupField(identifierNode, thisValue, findName);
  2499. if ((result) || (mPropDef != NULL))
  2500. return result;
  2501. }
  2502. }
  2503. }
  2504. if ((!result) && (identifierNode != NULL))
  2505. result = mModule->TryLookupGenericConstVaue(identifierNode, mExpectingType);
  2506. return result;
  2507. }
  2508. BfTypedValue BfExprEvaluator::LookupIdentifier(BfIdentifierNode* identifierNode, bool ignoreInitialError, bool* hadError)
  2509. {
  2510. auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(identifierNode);
  2511. if (qualifiedNameNode != NULL)
  2512. {
  2513. LookupQualifiedName(qualifiedNameNode, ignoreInitialError, hadError);
  2514. auto qualifiedResult = mResult;
  2515. mResult = BfTypedValue();
  2516. return qualifiedResult;
  2517. }
  2518. return LookupIdentifier(identifierNode, identifierNode->ToString(), ignoreInitialError, hadError);
  2519. }
  2520. void BfExprEvaluator::Visit(BfIdentifierNode* identifierNode)
  2521. {
  2522. if (GetAutoComplete() != NULL)
  2523. GetAutoComplete()->CheckIdentifier(identifierNode, true);
  2524. mResult = LookupIdentifier(identifierNode);
  2525. if ((!mResult) && (mPropDef == NULL))
  2526. mModule->Fail("Identifier not found", identifierNode);
  2527. }
  2528. void BfExprEvaluator::Visit(BfAttributedIdentifierNode* attrIdentifierNode)
  2529. {
  2530. if ((mModule->mAttributeState != NULL))
  2531. {
  2532. mModule->mAttributeState->mCustomAttributes = mModule->GetCustomAttributes(attrIdentifierNode->mAttributes, mModule->mAttributeState->mTarget);
  2533. VisitChild(attrIdentifierNode->mIdentifier);
  2534. }
  2535. else
  2536. {
  2537. BfAttributeState attributeState;
  2538. attributeState.mTarget = (BfAttributeTargets)(BfAttributeTargets_MemberAccess);
  2539. SetAndRestoreValue<BfAttributeState*> prevAttributeState(mModule->mAttributeState, &attributeState);
  2540. mModule->mAttributeState->mCustomAttributes = mModule->GetCustomAttributes(attrIdentifierNode->mAttributes, mModule->mAttributeState->mTarget);
  2541. VisitChild(attrIdentifierNode->mIdentifier);
  2542. }
  2543. }
  2544. static int gPropIdx = 0;
  2545. void BfExprEvaluator::FixitAddMember(BfTypeInstance* typeInst, BfType* fieldType, const StringImpl& fieldName, bool isStatic)
  2546. {
  2547. if (fieldType == NULL)
  2548. {
  2549. fieldType = mExpectingType;
  2550. }
  2551. if (fieldType != NULL)
  2552. {
  2553. if (fieldType->IsRef())
  2554. fieldType = fieldType->GetUnderlyingType();
  2555. }
  2556. mModule->mCompiler->mResolvePassData->mAutoComplete->FixitAddMember(typeInst, fieldType, fieldName, isStatic, mModule->mCurTypeInstance);
  2557. }
  2558. BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue target, const StringImpl& fieldName, BfLookupFieldFlags flags)
  2559. {
  2560. BfTypeInstance* startCheckType = mModule->mCurTypeInstance;
  2561. mPropDef = NULL;
  2562. mPropDefBypassVirtual = false;
  2563. if ((target.mType != NULL) && (mModule->mCurMethodState != NULL))
  2564. {
  2565. mModule->PopulateType(target.mType, BfPopulateType_BaseType);
  2566. }
  2567. if (target)
  2568. {
  2569. if ((!target.mType->IsValueType()) && (target.IsAddr()))
  2570. target = mModule->LoadValue(target);
  2571. if (target.mType->IsPrimitiveType())
  2572. {
  2573. auto primType = (BfPrimitiveType*)target.mType;
  2574. startCheckType = mModule->GetPrimitiveStructType(primType->mTypeDef->mTypeCode);
  2575. }
  2576. else
  2577. {
  2578. startCheckType = target.mType->ToTypeInstance();
  2579. if ((startCheckType == NULL) && (target.mType->IsPointer()))
  2580. startCheckType = ((BfPointerType*) target.mType)->mElementType->ToTypeInstance();
  2581. }
  2582. //BF_ASSERT(startCheckType != NULL);
  2583. }
  2584. else if (target.mType != NULL)
  2585. {
  2586. startCheckType = target.mType->ToTypeInstance();
  2587. }
  2588. auto activeTypeDef = mModule->GetActiveTypeDef();
  2589. for (int pass = 0; pass < 2; pass++)
  2590. {
  2591. auto curCheckType = startCheckType;
  2592. bool isFailurePass = pass == 1;
  2593. bool isBaseLookup = false;
  2594. while (curCheckType != NULL)
  2595. {
  2596. curCheckType->mTypeDef->PopulateMemberSets();
  2597. BfFieldDef* nextField = NULL;
  2598. BfMemberSetEntry* entry;
  2599. if (curCheckType->mTypeDef->mFieldSet.TryGetWith(fieldName, &entry))
  2600. nextField = (BfFieldDef*)entry->mMemberDef;
  2601. BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None;
  2602. BfFieldDef* matchedField = NULL;
  2603. while (nextField != NULL)
  2604. {
  2605. auto field = nextField;
  2606. nextField = nextField->mNextWithSameName;
  2607. if ((!isFailurePass) && (!mModule->CheckProtection(protectionCheckFlags, curCheckType, field->mProtection, startCheckType)))
  2608. {
  2609. continue;
  2610. }
  2611. //OLD:
  2612. bool isResolvingFields = curCheckType->mResolvingConstField || curCheckType->mResolvingVarField;
  2613. // mCurMethodState is NULL when we're pre-evaluating var field expressions
  2614. // to determine their type in PopulateFields
  2615. /*if (!isResolvingFields)
  2616. {
  2617. mModule->PopulateType(curCheckType, BfPopulateType_Data);
  2618. }*/
  2619. if (curCheckType->mFieldInstances.IsEmpty())
  2620. {
  2621. mModule->PopulateType(curCheckType, BfPopulateType_Data);
  2622. }
  2623. BF_ASSERT(field->mIdx < (int)curCheckType->mFieldInstances.size());
  2624. auto fieldInstance = &curCheckType->mFieldInstances[field->mIdx];
  2625. if (!fieldInstance->mFieldIncluded)
  2626. continue;
  2627. if (curCheckType->IsUnspecializedType())
  2628. {
  2629. // The check for non-unspecialized types is already handled in mFieldIncluded
  2630. if (!curCheckType->IsTypeMemberIncluded(field->mDeclaringType, activeTypeDef, mModule))
  2631. continue;
  2632. }
  2633. if (!curCheckType->IsTypeMemberAccessible(field->mDeclaringType, activeTypeDef))
  2634. continue;
  2635. if (matchedField != NULL)
  2636. {
  2637. auto error = mModule->Fail(StrFormat("Ambiguous reference to field '%s.%s'", mModule->TypeToString(curCheckType).c_str(), fieldName.c_str()), targetSrc);
  2638. if (error != NULL)
  2639. {
  2640. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See field declaration in project '%s'", matchedField->mDeclaringType->mProject->mName.c_str()), matchedField->mFieldDeclaration);
  2641. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See field declaration in project '%s'", field->mDeclaringType->mProject->mName.c_str()), field->mFieldDeclaration);
  2642. break;
  2643. }
  2644. }
  2645. matchedField = field;
  2646. }
  2647. if (matchedField != NULL)
  2648. {
  2649. auto field = matchedField;
  2650. auto fieldInstance = &curCheckType->mFieldInstances[field->mIdx];
  2651. bool isResolvingFields = curCheckType->mResolvingConstField || curCheckType->mResolvingVarField;
  2652. if (field->mIsVolatile)
  2653. mIsVolatileReference = true;
  2654. if (isFailurePass)
  2655. {
  2656. mModule->Fail(StrFormat("'%s.%s' is inaccessible due to its protection level", mModule->TypeToString(curCheckType).c_str(), field->mName.c_str()), targetSrc);
  2657. }
  2658. auto resolvePassData = mModule->mCompiler->mResolvePassData;
  2659. if ((resolvePassData != NULL) && (resolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Field))
  2660. {
  2661. resolvePassData->HandleFieldReference(targetSrc, curCheckType->mTypeDef, field);
  2662. }
  2663. if ((!curCheckType->mTypeFailed) && (!isResolvingFields) && (curCheckType->IsIncomplete()))
  2664. {
  2665. if ((fieldInstance->mResolvedType == NULL) ||
  2666. (!field->mIsStatic))
  2667. mModule->PopulateType(curCheckType, BfPopulateType_Data);
  2668. }
  2669. if (fieldInstance->mResolvedType == NULL)
  2670. {
  2671. BF_ASSERT((curCheckType->mTypeFailed) || (isResolvingFields));
  2672. return BfTypedValue();
  2673. }
  2674. if (fieldInstance->mFieldIdx == -1)
  2675. {
  2676. mModule->AssertErrorState();
  2677. return BfTypedValue();
  2678. }
  2679. // Are we accessing a 'var' field that has not yet been resolved?
  2680. if (fieldInstance->mResolvedType->IsVar())
  2681. {
  2682. // This can happen if we have one var field referencing another var field
  2683. fieldInstance->mResolvedType = mModule->ResolveVarFieldType(curCheckType, fieldInstance, field);
  2684. if (fieldInstance->mResolvedType == NULL)
  2685. return BfTypedValue();
  2686. if ((fieldInstance->mResolvedType->IsVar()) && (mModule->mCompiler->mIsResolveOnly))
  2687. mModule->Fail("Field type reference failed to resolve", targetSrc);
  2688. }
  2689. auto resolvedFieldType = fieldInstance->mResolvedType;
  2690. if (fieldInstance->mIsEnumPayloadCase)
  2691. {
  2692. resolvedFieldType = curCheckType;
  2693. }
  2694. mModule->PopulateType(resolvedFieldType, BfPopulateType_Data);
  2695. mModule->AddDependency(curCheckType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields);
  2696. auto autoComplete = GetAutoComplete();
  2697. if (autoComplete != NULL)
  2698. autoComplete->CheckFieldRef(BfNodeDynCast<BfIdentifierNode>(targetSrc), fieldInstance);
  2699. if (field->mIsStatic)
  2700. {
  2701. if ((target) && ((flags & BfLookupFieldFlag_IsImplicitThis) == 0) && (!curCheckType->mTypeDef->IsGlobalsContainer()))
  2702. {
  2703. //CS0176: Member 'Program.sVal' cannot be accessed with an instance reference; qualify it with a type name instead
  2704. mModule->Fail(StrFormat("Member '%s.%s' cannot be accessed with an instance reference; qualify it with a type name instead",
  2705. mModule->TypeToString(curCheckType).c_str(), field->mName.c_str()), targetSrc);
  2706. }
  2707. // Target must be an implicit 'this', or an error (accessing a static with a non-static target).
  2708. // Not actually needed in either case since this is a static lookup.
  2709. mResultLocalVar = NULL;
  2710. }
  2711. bool isConst = false;
  2712. if (field->mIsConst)
  2713. {
  2714. isConst = true;
  2715. auto fieldDef = fieldInstance->GetFieldDef();
  2716. if ((resolvedFieldType->IsPointer()) && (fieldDef->mIsExtern))
  2717. isConst = false;
  2718. }
  2719. if (resolvedFieldType->IsValuelessType())
  2720. {
  2721. return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), resolvedFieldType, true);
  2722. }
  2723. if (isConst)
  2724. {
  2725. if (fieldInstance->mIsEnumPayloadCase)
  2726. {
  2727. auto dscrType = curCheckType->GetDiscriminatorType();
  2728. mModule->mBfIRBuilder->PopulateType(curCheckType);
  2729. int tagIdx = -fieldInstance->mDataIdx - 1;
  2730. if ((mBfEvalExprFlags & BfEvalExprFlags_AllowEnumId) != 0)
  2731. {
  2732. return BfTypedValue(mModule->mBfIRBuilder->CreateConst(dscrType->mTypeDef->mTypeCode, tagIdx), fieldInstance->mOwner);
  2733. }
  2734. mModule->PopulateType(fieldInstance->mOwner, BfPopulateType_Data);
  2735. // auto agg = mModule->mBfIRBuilder->CreateUndefValue(mModule->mBfIRBuilder->MapType(fieldInstance->mOwner));
  2736. // agg = mModule->mBfIRBuilder->CreateInsertValue(agg, mModule->mBfIRBuilder->CreateConst(dscrType->mTypeDef->mTypeCode, tagIdx), 2);
  2737. //
  2738. // if (fieldInstance->mResolvedType->mSize != 0)
  2739. // {
  2740. // mModule->FailAfter("Enum case parameters expected", targetSrc);
  2741. // }
  2742. //
  2743. // return BfTypedValue(agg, fieldInstance->mOwner);
  2744. auto agg = mModule->CreateAlloca(fieldInstance->mOwner);
  2745. auto gep = mModule->mBfIRBuilder->CreateInBoundsGEP(agg, 0, 2);
  2746. mModule->mBfIRBuilder->CreateStore(mModule->mBfIRBuilder->CreateConst(dscrType->mTypeDef->mTypeCode, tagIdx), gep);
  2747. if (fieldInstance->mResolvedType->mSize != 0)
  2748. {
  2749. mModule->FailAfter("Enum case parameters expected", targetSrc);
  2750. }
  2751. return BfTypedValue(agg, fieldInstance->mOwner, true);
  2752. }
  2753. if (fieldInstance->mConstIdx == -1)
  2754. {
  2755. curCheckType->mModule->ResolveConstField(curCheckType, fieldInstance, field);
  2756. if (fieldInstance->mConstIdx == -1)
  2757. return BfTypedValue(mModule->GetDefaultValue(resolvedFieldType), resolvedFieldType);
  2758. }
  2759. BF_ASSERT(fieldInstance->mConstIdx != -1);
  2760. auto foreignConst = curCheckType->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
  2761. auto retVal = mModule->ConstantToCurrent(foreignConst, curCheckType->mConstHolder, resolvedFieldType);
  2762. return BfTypedValue(retVal, resolvedFieldType);
  2763. }
  2764. else if (field->mIsStatic)
  2765. {
  2766. mModule->CheckStaticAccess(curCheckType);
  2767. auto retVal = mModule->ReferenceStaticField(fieldInstance);
  2768. if (field->mIsReadOnly)
  2769. retVal = mModule->LoadValue(retVal, NULL, mIsVolatileReference);
  2770. else
  2771. mIsHeapReference = true;
  2772. return retVal;
  2773. }
  2774. else if (!target)
  2775. {
  2776. if ((flags & BfLookupFieldFlag_CheckingOuter) != 0)
  2777. mModule->Fail(StrFormat("An instance reference is required to reference non-static outer field '%s.%s'", mModule->TypeToString(curCheckType).c_str(), field->mName.c_str()),
  2778. targetSrc);
  2779. else if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_CtorCalcAppend))
  2780. mModule->Fail(StrFormat("Cannot reference field '%s' before append allocations", field->mName.c_str()), targetSrc);
  2781. else
  2782. mModule->Fail(StrFormat("Cannot reference non-static field '%s' from a static method", field->mName.c_str()), targetSrc);
  2783. return mModule->GetDefaultTypedValue(resolvedFieldType, false, BfDefaultValueKind_Addr);
  2784. }
  2785. if ((mResultLocalVar != NULL) && (fieldInstance->mMergedDataIdx != -1))
  2786. {
  2787. int minMergedDataIdx = fieldInstance->mMergedDataIdx;
  2788. int maxMergedDataIdx = minMergedDataIdx + 1;
  2789. if (resolvedFieldType->IsStruct())
  2790. maxMergedDataIdx = minMergedDataIdx + resolvedFieldType->ToTypeInstance()->mMergedFieldDataCount;
  2791. if (curCheckType->mIsUnion)
  2792. {
  2793. for (auto& checkFieldInstance : curCheckType->mFieldInstances)
  2794. {
  2795. if (&checkFieldInstance == fieldInstance)
  2796. continue;
  2797. if (checkFieldInstance.mDataIdx == fieldInstance->mDataIdx)
  2798. {
  2799. int checkMinMergedDataIdx = checkFieldInstance.mMergedDataIdx;
  2800. int checkMaxMergedDataIdx = checkMinMergedDataIdx + 1;
  2801. if (checkFieldInstance.GetResolvedType()->IsStruct())
  2802. checkMaxMergedDataIdx = checkMinMergedDataIdx + checkFieldInstance.mResolvedType->ToTypeInstance()->mMergedFieldDataCount;
  2803. minMergedDataIdx = BF_MIN(minMergedDataIdx, checkMinMergedDataIdx);
  2804. maxMergedDataIdx = BF_MAX(maxMergedDataIdx, checkMaxMergedDataIdx);
  2805. }
  2806. }
  2807. }
  2808. int fieldIdx = -1;
  2809. if (fieldIdx == -1)
  2810. {
  2811. mResultLocalVarField = minMergedDataIdx + 1;
  2812. }
  2813. else
  2814. {
  2815. fieldIdx += minMergedDataIdx;
  2816. mResultLocalVarField = fieldIdx + 1;
  2817. }
  2818. mResultLocalVarFieldCount = maxMergedDataIdx - minMergedDataIdx;
  2819. mResultLocalVarRefNode = targetSrc;
  2820. /*int fieldIdx = (mResultLocalVarIdx >> 16) - 1;
  2821. if (fieldIdx == -1)
  2822. {
  2823. mResultLocalVarField = fieldInstance->mMergedDataIdx + 1;
  2824. }
  2825. else
  2826. {
  2827. fieldIdx += fieldInstance->mMergedDataIdx;
  2828. mResultLocalVarField = fieldIdx + 1;
  2829. }
  2830. mResultLocalVarFieldCount = 1;
  2831. if (fieldInstance->mType->IsStruct())
  2832. {
  2833. auto fieldTypeInstance = fieldInstance->mType->ToTypeInstance();
  2834. mResultLocalVarFieldCount = fieldTypeInstance->mMergedFieldDataCount;
  2835. }
  2836. mResultLocalVarRefNode = targetSrc;*/
  2837. }
  2838. if ((curCheckType->IsIncomplete()) && (!curCheckType->mNeedsMethodProcessing))
  2839. {
  2840. BF_ASSERT(curCheckType->mTypeFailed || (mModule->mCurMethodState == NULL) || (mModule->mCurMethodState->mTempKind != BfMethodState::TempKind_None) || (mModule->mCompiler->IsAutocomplete()));
  2841. return mModule->GetDefaultTypedValue(resolvedFieldType);
  2842. }
  2843. bool isTemporary = false;
  2844. bool wantsLoadValue = false;
  2845. if ((field->mIsReadOnly) && ((mModule->mCurMethodInstance->mMethodDef->mMethodType != BfMethodType_Ctor) || (!target.IsThis())))
  2846. wantsLoadValue = true;
  2847. bool isComposite = target.mType->IsComposite();
  2848. if ((isComposite) && (!target.mType->IsTypedPrimitive()) && (!target.IsAddr()))
  2849. isTemporary = true;
  2850. if ((isComposite) && (!target.IsAddr()))
  2851. wantsLoadValue = true;
  2852. if ((target.mType->IsWrappableType()) && (!target.mType->IsPointer()))
  2853. {
  2854. BfTypeInstance* primStructType = mModule->GetWrappedStructType(target.mType);
  2855. BfIRValue allocaInst = mModule->CreateAlloca(primStructType, true, "tmpStruct");
  2856. BfIRValue elementAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, 1);
  2857. mModule->mBfIRBuilder->CreateStore(target.mValue, elementAddr);
  2858. target = BfTypedValue(allocaInst, primStructType, true);
  2859. }
  2860. BfTypedValue targetValue;
  2861. if ((isBaseLookup) && (!target.IsSplat()))
  2862. {
  2863. if ((!isComposite) || (target.IsAddr()))
  2864. targetValue = BfTypedValue(mModule->mBfIRBuilder->CreateBitCast(target.mValue, mModule->mBfIRBuilder->MapTypeInstPtr(curCheckType)), curCheckType);
  2865. else
  2866. {
  2867. BfIRValue curVal = target.mValue;
  2868. auto baseCheckType = target.mType->ToTypeInstance();
  2869. while (baseCheckType != curCheckType)
  2870. {
  2871. curVal = mModule->mBfIRBuilder->CreateExtractValue(curVal, 0);
  2872. baseCheckType = baseCheckType->mBaseType;
  2873. }
  2874. targetValue = BfTypedValue(curVal, curCheckType);
  2875. }
  2876. }
  2877. else
  2878. targetValue = target;
  2879. bool doAccessCheck = true;
  2880. if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) && (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mSkipAccessCheckAttributeTypeDef)))
  2881. doAccessCheck = false;
  2882. if (target.IsThis())
  2883. {
  2884. if (!mModule->mCurMethodState->mMayNeedThisAccessCheck)
  2885. doAccessCheck = false;
  2886. }
  2887. if (doAccessCheck)
  2888. mModule->EmitObjectAccessCheck(target);
  2889. if (fieldInstance->mDataIdx < 0)
  2890. {
  2891. BF_ASSERT(curCheckType->mTypeFailed);
  2892. return mModule->GetDefaultTypedValue(resolvedFieldType);
  2893. }
  2894. BfTypedValue retVal;
  2895. if (target.IsSplat())
  2896. {
  2897. retVal = mModule->ExtractValue(targetValue, fieldInstance, fieldInstance->mDataIdx);
  2898. }
  2899. else if ((target.mType->IsStruct()) && (!target.IsAddr()))
  2900. {
  2901. retVal = BfTypedValue(mModule->mBfIRBuilder->CreateExtractValue(targetValue.mValue, fieldInstance->mDataIdx/*, field->mName*/),
  2902. resolvedFieldType);
  2903. }
  2904. else
  2905. {
  2906. mModule->mBfIRBuilder->PopulateType(curCheckType);
  2907. if ((targetValue.IsAddr()) && (!curCheckType->IsValueType()))
  2908. targetValue = mModule->LoadValue(targetValue);
  2909. retVal = BfTypedValue(mModule->mBfIRBuilder->CreateInBoundsGEP(targetValue.mValue, 0, fieldInstance->mDataIdx/*, field->mName*/),
  2910. resolvedFieldType, target.IsReadOnly() ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
  2911. }
  2912. if (!retVal.IsSplat())
  2913. {
  2914. if (curCheckType->mIsUnion)
  2915. {
  2916. BfIRType llvmPtrType = mModule->mBfIRBuilder->GetPointerTo(mModule->mBfIRBuilder->MapType(resolvedFieldType));
  2917. retVal.mValue = mModule->mBfIRBuilder->CreateBitCast(retVal.mValue, llvmPtrType);
  2918. }
  2919. }
  2920. if (wantsLoadValue)
  2921. retVal = mModule->LoadValue(retVal, NULL, mIsVolatileReference);
  2922. else
  2923. mIsHeapReference = true;
  2924. if (isTemporary)
  2925. {
  2926. if (retVal.IsAddr())
  2927. retVal.mKind = BfTypedValueKind_TempAddr;
  2928. }
  2929. return retVal;
  2930. }
  2931. BfPropertyDef* nextProp = NULL;
  2932. if (curCheckType->mTypeDef->mPropertySet.TryGetWith(fieldName, &entry))
  2933. nextProp = (BfPropertyDef*)entry->mMemberDef;
  2934. if (nextProp != NULL)
  2935. {
  2936. BfCheckedKind checkedKind = BfCheckedKind_NotSet;
  2937. bool isInlined = false;
  2938. if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL))
  2939. {
  2940. if (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mInlineAttributeTypeDef))
  2941. {
  2942. isInlined = true;
  2943. mModule->mAttributeState->mUsed = true;
  2944. }
  2945. if (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mCheckedAttributeTypeDef))
  2946. {
  2947. checkedKind = BfCheckedKind_Checked;
  2948. mModule->mAttributeState->mUsed = true;
  2949. }
  2950. if (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mUncheckedAttributeTypeDef))
  2951. {
  2952. checkedKind = BfCheckedKind_Unchecked;
  2953. mModule->mAttributeState->mUsed = true;
  2954. }
  2955. }
  2956. BfPropertyDef* matchedProp = NULL;
  2957. while (nextProp != NULL)
  2958. {
  2959. auto prop = nextProp;
  2960. nextProp = nextProp->mNextWithSameName;
  2961. if ((!isFailurePass) && (!mModule->CheckProtection(protectionCheckFlags, curCheckType, prop->mProtection, startCheckType)))
  2962. {
  2963. continue;
  2964. }
  2965. if (!prop->mMethods.IsEmpty())
  2966. {
  2967. BfMethodDef* checkMethod = prop->mMethods[0];;
  2968. // Properties with explicit interfaces or marked as overrides can only be called indirectly
  2969. if ((checkMethod->mExplicitInterface != NULL) || (checkMethod->mIsOverride))
  2970. continue;
  2971. }
  2972. if ((!target.IsStatic()) || (prop->mIsStatic))
  2973. {
  2974. if ((!curCheckType->IsTypeMemberIncluded(prop->mDeclaringType, activeTypeDef, mModule)) ||
  2975. (!curCheckType->IsTypeMemberAccessible(prop->mDeclaringType, activeTypeDef)))
  2976. continue;
  2977. if (matchedProp != NULL)
  2978. {
  2979. auto error = mModule->Fail(StrFormat("Ambiguous reference to property '%s.%s'", mModule->TypeToString(curCheckType).c_str(), fieldName.c_str()), targetSrc);
  2980. if (error != NULL)
  2981. {
  2982. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See property declaration in project '%s'", matchedProp->mDeclaringType->mProject->mName.c_str()), matchedProp->mFieldDeclaration);
  2983. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See property declaration in project '%s'", prop->mDeclaringType->mProject->mName.c_str()), prop->mFieldDeclaration);
  2984. break;
  2985. }
  2986. }
  2987. matchedProp = prop;
  2988. }
  2989. }
  2990. if (matchedProp != NULL)
  2991. {
  2992. auto prop = matchedProp;
  2993. gPropIdx++;
  2994. mModule->SetElementType(targetSrc, BfSourceElementType_Method);
  2995. mPropSrc = targetSrc;
  2996. mPropDef = prop;
  2997. mPropCheckedKind = checkedKind;
  2998. if (isInlined)
  2999. mPropGetMethodFlags = (BfGetMethodInstanceFlags)(mPropGetMethodFlags | BfGetMethodInstanceFlag_ForceInline);
  3000. if (mPropDef->mIsStatic)
  3001. {
  3002. if ((target) && ((flags & BfLookupFieldFlag_IsImplicitThis) == 0) && (!curCheckType->mTypeDef->IsGlobalsContainer()))
  3003. {
  3004. //CS0176: Member 'Program.sVal' cannot be accessed with an instance reference; qualify it with a type name instead
  3005. mModule->Fail(StrFormat("Property '%s.%s' cannot be accessed with an instance reference; qualify it with a type name instead",
  3006. mModule->TypeToString(curCheckType).c_str(), mPropDef->mName.c_str()), targetSrc);
  3007. }
  3008. }
  3009. if (prop->mIsStatic)
  3010. mPropTarget = BfTypedValue(curCheckType);
  3011. else if (isBaseLookup)
  3012. {
  3013. mPropTarget = mModule->Cast(targetSrc, target, curCheckType);
  3014. BF_ASSERT(mPropTarget);
  3015. }
  3016. else
  3017. mPropTarget = target;
  3018. mOrigPropTarget = mPropTarget;
  3019. auto autoComplete = GetAutoComplete();
  3020. auto resolvePassData = mModule->mCompiler->mResolvePassData;
  3021. if (((autoComplete != NULL) && (autoComplete->mIsGetDefinition)) ||
  3022. ((resolvePassData != NULL) && (resolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Property)))
  3023. {
  3024. BfPropertyDef* basePropDef = mPropDef;
  3025. BfTypeInstance* baseTypeInst = curCheckType;
  3026. mModule->GetBasePropertyDef(basePropDef, baseTypeInst);
  3027. resolvePassData->HandlePropertyReference(targetSrc, baseTypeInst->mTypeDef, basePropDef);
  3028. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(targetSrc)))
  3029. {
  3030. autoComplete->mDefProp = basePropDef;
  3031. autoComplete->mDefType = baseTypeInst->mTypeDef;
  3032. }
  3033. }
  3034. SetAndRestoreValue<BfTypedValue> prevResult(mResult, target);
  3035. CheckResultForReading(mResult);
  3036. return BfTypedValue();
  3037. }
  3038. }
  3039. isBaseLookup = true;
  3040. curCheckType = curCheckType->mBaseType;
  3041. }
  3042. }
  3043. auto outerTypeDef = mModule->GetOuterType(startCheckType);
  3044. if (outerTypeDef != NULL)
  3045. {
  3046. // Check statics in outer type
  3047. return LookupField(targetSrc, BfTypedValue(outerTypeDef), fieldName, BfLookupFieldFlag_CheckingOuter);
  3048. }
  3049. return BfTypedValue();
  3050. }
  3051. void BfExprEvaluator::ResolveArgValues(BfResolvedArgs& resolvedArgs, BfResolveArgFlags flags)
  3052. {
  3053. static int idx = 0;
  3054. idx++;
  3055. int curIdx = idx;
  3056. if (resolvedArgs.mArguments == NULL)
  3057. return;
  3058. int argCount = (int)resolvedArgs.mArguments->size();
  3059. if ((resolvedArgs.mCommas != NULL) && (resolvedArgs.mCommas->size() != 0) && (resolvedArgs.mCommas->size() >= resolvedArgs.mArguments->size()))
  3060. {
  3061. //mModule->FailAfter("Expression expected", resolvedArgs.mCommas->back());
  3062. argCount++;
  3063. }
  3064. BfAutoComplete* autoComplete = GetAutoComplete();
  3065. bool hadIgnoredFixits = false;
  3066. if (autoComplete != NULL)
  3067. {
  3068. hadIgnoredFixits = autoComplete->mIgnoreFixits;
  3069. if (flags & BfResolveArgFlag_DeferFixits)
  3070. autoComplete->mIgnoreFixits = true;
  3071. }
  3072. for (int argIdx = 0; argIdx < argCount ; argIdx++)
  3073. {
  3074. //printf("Args: %p %p %d\n", resolvedArgs.mArguments, resolvedArgs.mArguments->mVals, resolvedArgs.mArguments->mSize);
  3075. BfExpression* argExpr = NULL;
  3076. if (argIdx < resolvedArgs.mArguments->size())
  3077. argExpr = (*resolvedArgs.mArguments)[argIdx];
  3078. if (argExpr == NULL)
  3079. {
  3080. if (argIdx == 0)
  3081. {
  3082. if (resolvedArgs.mOpenToken != NULL)
  3083. mModule->FailAfter("Expression expected", resolvedArgs.mOpenToken);
  3084. }
  3085. else if (resolvedArgs.mCommas != NULL)
  3086. mModule->FailAfter("Expression expected", (*resolvedArgs.mCommas)[argIdx - 1]);
  3087. }
  3088. if (auto typedValueExpr = BfNodeDynCast<BfTypedValueExpression>(argExpr))
  3089. {
  3090. BfResolvedArg resolvedArg;
  3091. resolvedArg.mTypedValue = typedValueExpr->mTypedValue;
  3092. resolvedArg.mExpression = typedValueExpr->mRefNode;
  3093. resolvedArgs.mResolvedArgs.push_back(resolvedArg);
  3094. continue;
  3095. }
  3096. BfResolvedArg resolvedArg;
  3097. BfExprEvaluator exprEvaluator(mModule);
  3098. exprEvaluator.mResolveGenericParam = (flags & BfResolveArgFlag_AllowUnresolvedTypes) == 0;
  3099. exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | BfEvalExprFlags_AllowRefExpr | BfEvalExprFlags_AllowOutExpr);
  3100. bool handled = false;
  3101. bool evaluated = false;
  3102. bool deferParamEval = false;
  3103. if ((flags & BfResolveArgFlag_DeferParamEval) != 0)
  3104. {
  3105. if (argExpr != NULL)
  3106. {
  3107. BfDeferEvalChecker deferEvalChecker;
  3108. argExpr->Accept(&deferEvalChecker);
  3109. deferParamEval = deferEvalChecker.mNeedsDeferEval;
  3110. }
  3111. }
  3112. if (deferParamEval)
  3113. {
  3114. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_DeferredEval);
  3115. handled = true;
  3116. }
  3117. else if (auto delegateBindExpression = BfNodeDynCast<BfDelegateBindExpression>(argExpr))
  3118. {
  3119. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_DelegateBindAttempt);
  3120. handled = true;
  3121. }
  3122. else if (auto lambdaBindExpression = BfNodeDynCast<BfLambdaBindExpression>(argExpr))
  3123. {
  3124. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_LambdaBindAttempt);
  3125. handled = true;
  3126. }
  3127. else if (auto memberRef = BfNodeDynCast<BfMemberReferenceExpression>(argExpr))
  3128. {
  3129. if (memberRef->mTarget == NULL)
  3130. {
  3131. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_UnqualifiedDotAttempt);
  3132. handled = true;
  3133. }
  3134. }
  3135. else if (auto invokeExpr = BfNodeDynCast<BfInvocationExpression>(argExpr))
  3136. {
  3137. if (auto memberRef = BfNodeDynCast<BfMemberReferenceExpression>(invokeExpr->mTarget))
  3138. {
  3139. if (memberRef->mTarget == NULL)
  3140. {
  3141. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_UnqualifiedDotAttempt);
  3142. handled = true;
  3143. }
  3144. }
  3145. }
  3146. else if (auto defaultExpr = BfNodeDynCast<BfDefaultExpression>(argExpr))
  3147. {
  3148. if (defaultExpr->mTypeRef == NULL)
  3149. {
  3150. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_UntypedDefault);
  3151. handled = true;
  3152. }
  3153. }
  3154. else if (auto varDeclExpr = BfNodeDynCast<BfVariableDeclaration>(argExpr))
  3155. {
  3156. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_VariableDeclaration);
  3157. handled = true;
  3158. }
  3159. else if (auto unaryExpr = BfNodeDynCast<BfUnaryOperatorExpression>(argExpr))
  3160. {
  3161. if (unaryExpr->mOp == BfUnaryOp_Params)
  3162. {
  3163. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_ParamsExpr);
  3164. }
  3165. }
  3166. /*else if (auto castExpr = BfNodeDynCast<BfCastExpression>(argExpr))
  3167. {
  3168. if (auto namedTypeRef = BfNodeDynCastExact<BfNamedTypeReference>(castExpr->mTypeRef))
  3169. {
  3170. if (namedTypeRef->ToString() == "ExpectedType")
  3171. {
  3172. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_ExpectedTypeCast);
  3173. handled = true;
  3174. }
  3175. }
  3176. }*/
  3177. if ((argExpr != NULL) && (!handled))
  3178. {
  3179. bool deferParamValues = (flags & BfResolveArgFlag_DeferParamValues) != 0;
  3180. SetAndRestoreValue<bool> ignoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, mModule->mBfIRBuilder->mIgnoreWrites || deferParamValues);
  3181. auto prevInsertBlock = mModule->mBfIRBuilder->GetInsertBlock();
  3182. if (deferParamValues)
  3183. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_DeferredValue);
  3184. if (!evaluated)
  3185. {
  3186. exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | BfEvalExprFlags_AllowParamsExpr);
  3187. exprEvaluator.Evaluate(argExpr, false, false, true);
  3188. }
  3189. if ((mModule->mCurMethodState != NULL) && (exprEvaluator.mResultLocalVar != NULL) && (exprEvaluator.mResultLocalVarRefNode != NULL))
  3190. {
  3191. auto localVar = exprEvaluator.mResultLocalVar;
  3192. int fieldIdx = mResultLocalVarField - 1;
  3193. auto methodState = mModule->mCurMethodState->GetMethodStateForLocal(localVar);
  3194. if (localVar->mCompositeCount >= 0)
  3195. {
  3196. if ((resolvedArg.mArgFlags & BfArgFlag_ParamsExpr) == 0)
  3197. mModule->Warn(0, "'params' token expected", argExpr);
  3198. for (int compositeIdx = 0; compositeIdx < localVar->mCompositeCount; compositeIdx++)
  3199. {
  3200. BfResolvedArg compositeResolvedArg;
  3201. auto compositeLocalVar = methodState->mLocals[localVar->mLocalVarIdx + compositeIdx + 1];
  3202. auto argValue = exprEvaluator.LoadLocal(compositeLocalVar);
  3203. if (argValue)
  3204. {
  3205. if (argValue.mType->IsRef())
  3206. argValue.mKind = BfTypedValueKind_Value;
  3207. else if (!argValue.mType->IsStruct())
  3208. argValue = mModule->LoadValue(argValue, NULL, exprEvaluator.mIsVolatileReference);
  3209. }
  3210. resolvedArg.mTypedValue = argValue;
  3211. resolvedArg.mExpression = argExpr;
  3212. resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_FromParamComposite);
  3213. resolvedArgs.mResolvedArgs.push_back(resolvedArg);
  3214. }
  3215. continue;
  3216. }
  3217. }
  3218. exprEvaluator.CheckResultForReading(exprEvaluator.mResult);
  3219. auto argValue = exprEvaluator.mResult;
  3220. if (argValue)
  3221. {
  3222. //resolvedArg.mResolvedType = mModule->ResolveGenericType(argValue.mType);
  3223. resolvedArg.mResolvedType = argValue.mType;
  3224. if (resolvedArg.mResolvedType->IsRef())
  3225. argValue.mKind = BfTypedValueKind_Value;
  3226. else if ((!resolvedArg.mResolvedType->IsStruct()) && (!resolvedArg.mResolvedType->IsSizedArray()) && (!resolvedArg.mResolvedType->IsValuelessType()))
  3227. argValue = mModule->LoadValue(argValue, NULL, exprEvaluator.mIsVolatileReference);
  3228. }
  3229. resolvedArg.mTypedValue = argValue;
  3230. if (deferParamValues)
  3231. mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock);
  3232. }
  3233. resolvedArg.mExpression = argExpr;
  3234. resolvedArgs.mResolvedArgs.push_back(resolvedArg);
  3235. }
  3236. if (autoComplete != NULL)
  3237. autoComplete->mIgnoreFixits = hadIgnoredFixits;
  3238. }
  3239. void BfExprEvaluator::PerformCallChecks(BfMethodInstance* methodInstance, BfAstNode* targetSrc)
  3240. {
  3241. BfCustomAttributes* customAttributes = methodInstance->GetCustomAttributes();
  3242. if (customAttributes != NULL)
  3243. {
  3244. auto _AddMethodDeclarationMoreInfo = [&]()
  3245. {
  3246. if (methodInstance->mMethodDef->mMethodDeclaration != NULL)
  3247. mModule->mCompiler->mPassInstance->MoreInfo(
  3248. StrFormat("See method declaration '%s'", mModule->MethodToString(methodInstance).c_str()),
  3249. methodInstance->mMethodDef->GetRefNode());
  3250. };
  3251. BfIRConstHolder* constHolder = methodInstance->GetOwner()->mConstHolder;
  3252. auto customAttribute = customAttributes->Get(mModule->mCompiler->mObsoleteAttributeTypeDef);
  3253. if ((customAttribute != NULL) && (!customAttribute->mCtorArgs.IsEmpty()))
  3254. {
  3255. String err;
  3256. err = StrFormat("'%s' is obsolete", mModule->MethodToString(methodInstance).c_str());
  3257. bool isError = false;
  3258. auto constant = constHolder->GetConstant(customAttribute->mCtorArgs[0]);
  3259. if (constant->mTypeCode == BfTypeCode_Boolean)
  3260. {
  3261. isError = constant->mBool;
  3262. }
  3263. else if (customAttribute->mCtorArgs.size() >= 2)
  3264. {
  3265. String* str = mModule->GetStringPoolString(customAttribute->mCtorArgs[0], constHolder);
  3266. if (str != NULL)
  3267. {
  3268. err += ":\n '";
  3269. err += *str;
  3270. err += "'";
  3271. }
  3272. constant = constHolder->GetConstant(customAttribute->mCtorArgs[1]);
  3273. isError = constant->mBool;
  3274. }
  3275. BfError* error = NULL;
  3276. if (isError)
  3277. error = mModule->Fail(err, targetSrc);
  3278. else
  3279. error = mModule->Warn(0, err, targetSrc);
  3280. if (error != NULL)
  3281. _AddMethodDeclarationMoreInfo();
  3282. }
  3283. customAttribute = customAttributes->Get(mModule->mCompiler->mErrorAttributeTypeDef);
  3284. if ((customAttribute != NULL) && (!customAttribute->mCtorArgs.IsEmpty()))
  3285. {
  3286. String err = StrFormat("Method error: '", mModule->MethodToString(methodInstance).c_str());
  3287. String* str = mModule->GetStringPoolString(customAttribute->mCtorArgs[0], constHolder);
  3288. if (str != NULL)
  3289. err += *str;
  3290. err += "'";
  3291. if (mModule->Fail(err, targetSrc) != NULL)
  3292. _AddMethodDeclarationMoreInfo();
  3293. }
  3294. customAttribute = customAttributes->Get(mModule->mCompiler->mWarnAttributeTypeDef);
  3295. if ((customAttribute != NULL) && (!customAttribute->mCtorArgs.IsEmpty()))
  3296. {
  3297. String err = StrFormat("Method warning: '", mModule->MethodToString(methodInstance).c_str());
  3298. String* str = mModule->GetStringPoolString(customAttribute->mCtorArgs[0], constHolder);
  3299. if (str != NULL)
  3300. err += *str;
  3301. err += "'";
  3302. if (mModule->Warn(0, err, targetSrc) != NULL)
  3303. _AddMethodDeclarationMoreInfo();
  3304. }
  3305. }
  3306. }
  3307. BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRValue func, bool bypassVirtual, SizedArrayImpl<BfIRValue>& irArgs, BfTypedValue* sret, bool isTailCall)
  3308. {
  3309. // static int sCallIdx = 0;
  3310. // if (!mModule->mCompiler->mIsResolveOnly)
  3311. // sCallIdx++;
  3312. // int callIdx = sCallIdx;
  3313. // if (callIdx == 0x000000E8)
  3314. // {
  3315. // NOP;
  3316. // }
  3317. auto methodDef = methodInstance->mMethodDef;
  3318. BfIRValue funcCallInst = func;
  3319. auto importCallKind = methodInstance->GetImportCallKind();
  3320. if ((funcCallInst) && (importCallKind != BfImportCallKind_None))
  3321. {
  3322. if ((funcCallInst.IsFake()) && (!mModule->mBfIRBuilder->mIgnoreWrites))
  3323. {
  3324. mModule->mFuncReferences.TryGetValue(methodInstance, &funcCallInst);
  3325. }
  3326. if (importCallKind == BfImportCallKind_GlobalVar_Hot)
  3327. {
  3328. //TODO: Check against NULL for calling BfLoadSharedLibraries
  3329. auto checkVal = mModule->mBfIRBuilder->CreateLoad(funcCallInst);
  3330. BfIRBlock nullBlock = mModule->mBfIRBuilder->CreateBlock("importNull");
  3331. BfIRBlock doneBlock = mModule->mBfIRBuilder->CreateBlock("importLoad");
  3332. auto condVal = mModule->mBfIRBuilder->CreateIsNull(checkVal);
  3333. mModule->mBfIRBuilder->CreateCondBr(condVal, nullBlock, doneBlock);
  3334. mModule->mBfIRBuilder->AddBlock(nullBlock);
  3335. mModule->mBfIRBuilder->SetInsertPoint(nullBlock);
  3336. auto loadSharedLibsFunc = mModule->GetBuiltInFunc(BfBuiltInFuncType_LoadSharedLibraries);
  3337. mModule->mBfIRBuilder->CreateCall(loadSharedLibsFunc, SizedArray<BfIRValue, 0>());
  3338. mModule->mBfIRBuilder->CreateBr(doneBlock);
  3339. mModule->mBfIRBuilder->AddBlock(doneBlock);
  3340. mModule->mBfIRBuilder->SetInsertPoint(doneBlock);
  3341. funcCallInst = mModule->mBfIRBuilder->CreateLoad(funcCallInst);
  3342. }
  3343. else
  3344. {
  3345. funcCallInst = mModule->mBfIRBuilder->CreateLoad(funcCallInst);
  3346. }
  3347. }
  3348. if ((methodInstance->GetOwner()->mTypeDef == mModule->mCompiler->mDeferredCallTypeDef) &&
  3349. (methodInstance->mMethodDef->mName == "Cancel"))
  3350. {
  3351. if (mModule->mCurMethodState != NULL)
  3352. mModule->mCurMethodState->mCancelledDeferredCall = true;
  3353. }
  3354. if (methodDef->mNoReturn)
  3355. {
  3356. mModule->mCurMethodState->SetHadReturn(true);
  3357. mModule->mCurMethodState->mLeftBlockUncond = true;
  3358. }
  3359. if (mModule->mCurTypeInstance != NULL)
  3360. {
  3361. bool isVirtual = (methodInstance->mVirtualTableIdx != -1) && (!bypassVirtual);
  3362. mModule->AddDependency(methodInstance->mMethodInstanceGroup->mOwner, mModule->mCurTypeInstance, isVirtual ? BfDependencyMap::DependencyFlag_VirtualCall : BfDependencyMap::DependencyFlag_Calls);
  3363. mModule->AddCallDependency(methodInstance, bypassVirtual);
  3364. }
  3365. if (methodInstance->GetOwner()->IsUnspecializedType())
  3366. {
  3367. BF_ASSERT((!methodInstance->mIRFunction) || (methodInstance == mModule->mCurMethodInstance));
  3368. }
  3369. if (mFunctionBindResult != NULL)
  3370. {
  3371. BF_ASSERT(mFunctionBindResult->mMethodInstance == NULL);
  3372. mFunctionBindResult->mMethodInstance = methodInstance;
  3373. for (auto arg : irArgs)
  3374. mFunctionBindResult->mIRArgs.push_back(arg);
  3375. }
  3376. BfType* origReturnType = methodInstance->mReturnType;
  3377. /*if (origReturnType->IsSelf())
  3378. {
  3379. origReturnType = methodInstance->GetOwner();
  3380. BF_ASSERT(origReturnType->IsInterface());
  3381. }*/
  3382. BfType* returnType = origReturnType;
  3383. BfTypedValue sretVal;
  3384. auto _GetDefaultReturnValue = [&]()
  3385. {
  3386. if (returnType->IsRef())
  3387. {
  3388. auto result = mModule->GetDefaultTypedValue(returnType->GetUnderlyingType(), true, BfDefaultValueKind_Addr);
  3389. if (methodDef->mIsReadOnly)
  3390. result.mKind = BfTypedValueKind_ReadOnlyAddr;
  3391. return result;
  3392. }
  3393. else
  3394. {
  3395. return mModule->GetDefaultTypedValue(returnType, true, returnType->IsComposite() ? BfDefaultValueKind_Addr : BfDefaultValueKind_Value);
  3396. }
  3397. };
  3398. mModule->PopulateType(origReturnType, BfPopulateType_Data);
  3399. if (methodInstance->HasStructRet())
  3400. {
  3401. // We need to ensure that mReceivingValue has the correct type, otherwise it's possible that a conversion operator needs to be applied
  3402. // This happens for returning Result<T>'s with a 'T' value
  3403. if ((sret == NULL) && (mReceivingValue != NULL) && (mReceivingValue->mType == returnType))
  3404. {
  3405. sretVal = *mReceivingValue;
  3406. sret = &sretVal;
  3407. auto ptrType = mModule->CreatePointerType(returnType);
  3408. if (returnType != sret->mType)
  3409. {
  3410. sret->mValue = mModule->mBfIRBuilder->CreateBitCast(sret->mValue, mModule->mBfIRBuilder->MapType(ptrType));
  3411. sret->mType = returnType;
  3412. }
  3413. mReceivingValue = NULL;
  3414. }
  3415. if (sret == NULL)
  3416. {
  3417. sretVal = BfTypedValue(mModule->CreateAlloca(returnType), returnType, BfTypedValueKind_TempAddr);
  3418. sret = &sretVal;
  3419. }
  3420. }
  3421. else
  3422. {
  3423. BF_ASSERT(sret == NULL);
  3424. }
  3425. if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mCapturing))
  3426. {
  3427. return _GetDefaultReturnValue();
  3428. }
  3429. BF_ASSERT(!methodInstance->mDisallowCalling);
  3430. if ((mModule->mCompiler->mResolvePassData != NULL) && (mModule->mCompiler->mResolvePassData->mAutoComplete != NULL))
  3431. {
  3432. // In an autocomplete pass we may have stale method references that need to be resolved
  3433. // in the full classify pass, and in the full classify pass while just refreshing internals, we
  3434. // may have NULL funcs temporarily. We simply skip generating the method call here.
  3435. if (methodInstance->mVirtualTableIdx == -1)
  3436. {
  3437. if (methodInstance->GetOwner()->IsInterface())
  3438. {
  3439. // We're attempting to directly invoke a non-virtual interface method, if we're return an interface then
  3440. // it is a concrete interface
  3441. if (returnType->IsInterface())
  3442. returnType = mModule->CreateConcreteInterfaceType(returnType->ToTypeInstance());
  3443. }
  3444. }
  3445. BfTypedValue result;
  3446. if (sret != NULL)
  3447. result = *sret;
  3448. else
  3449. result = _GetDefaultReturnValue();
  3450. return result;
  3451. }
  3452. if (((!func) && (methodInstance->mIsUnspecialized)) || (mModule->mBfIRBuilder->mIgnoreWrites))
  3453. {
  3454. // We don't actually submit method calls for unspecialized methods
  3455. // - this includes all methods in unspecialized types
  3456. return _GetDefaultReturnValue();
  3457. }
  3458. if (methodInstance->mVirtualTableIdx != -1)
  3459. {
  3460. if ((!bypassVirtual) && (mDeferCallRef == NULL))
  3461. {
  3462. auto funcType = mModule->mBfIRBuilder->MapMethod(methodInstance);
  3463. auto funcPtrType1 = mModule->mBfIRBuilder->GetPointerTo(funcType);
  3464. auto funcPtrType2 = mModule->mBfIRBuilder->GetPointerTo(funcPtrType1);
  3465. auto funcPtrType3 = mModule->mBfIRBuilder->GetPointerTo(funcPtrType2);
  3466. auto funcPtrType4 = mModule->mBfIRBuilder->GetPointerTo(funcPtrType3);
  3467. if (methodInstance->mMethodInstanceGroup->mOwner->IsInterface())
  3468. {
  3469. // IFace dispatch
  3470. auto ifaceTypeInst = methodInstance->mMethodInstanceGroup->mOwner;
  3471. BfIRValue slotOfs = mModule->GetInterfaceSlotNum(methodInstance->mMethodInstanceGroup->mOwner);
  3472. auto vDataPtrPtr = mModule->mBfIRBuilder->CreateBitCast(irArgs[0], funcPtrType4);
  3473. auto vDataPtr = mModule->FixClassVData(mModule->mBfIRBuilder->CreateLoad(vDataPtrPtr/*, "vtable"*/));
  3474. auto ifacePtrPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(vDataPtr, slotOfs/*, "iface"*/);
  3475. auto ifacePtr = mModule->mBfIRBuilder->CreateLoad(ifacePtrPtr);
  3476. auto funcPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(ifacePtr, methodInstance->mVirtualTableIdx/*, "vfn"*/);
  3477. funcCallInst = mModule->mBfIRBuilder->CreateLoad(funcPtr);
  3478. }
  3479. else
  3480. {
  3481. mModule->HadSlotCountDependency();
  3482. // Virtual dispatch
  3483. // int vDataIdx = 0;
  3484. // vDataIdx += 1 + methodInstance->GetOwner()->GetDynCastVDataCount() + mModule->mCompiler->mMaxInterfaceSlots;
  3485. BfIRValue vDataPtr;
  3486. BfIRValue vDataIdx;
  3487. if ((mModule->mCompiler->mOptions.mHasVDataExtender) && (mModule->mCompiler->IsHotCompile()))
  3488. {
  3489. auto typeInst = methodInstance->mMethodInstanceGroup->mOwner;
  3490. int extMethodIdx = (methodInstance->mVirtualTableIdx - typeInst->GetBaseVTableSize()) - typeInst->GetOrigSelfVTableSize();
  3491. if (extMethodIdx >= 0)
  3492. {
  3493. BF_ASSERT(mModule->mCompiler->IsHotCompile());
  3494. // We have grown outside our original virtual table, Load the new vdataPtr from the mHasVDataExtender
  3495. // vDataPtr = obj.vtable.extension.entry[curVersion]
  3496. BfIRValue vDataPtrPtr = mModule->mBfIRBuilder->CreateBitCast(irArgs[0], funcPtrType4);
  3497. vDataPtr = mModule->FixClassVData(mModule->mBfIRBuilder->CreateLoad(vDataPtrPtr));
  3498. // The offset of the vExt is one past the base vtable. When a base class extends its virtual table, an entry
  3499. // for that new method is inserted in mVirtualMethodTable (thus increasing the index relative to GetBaseVTableSize()),
  3500. // but the actual written vtable position doesn't change, hence offsetting from GetOrigBaseVTableSize()
  3501. #ifdef _DEBUG
  3502. int vExtIdx = typeInst->GetBaseVTableSize();
  3503. BF_ASSERT(typeInst->mVirtualMethodTable[vExtIdx].mDeclaringMethod.mMethodNum == -1); // A type entry with a -1 mMethodNum means it's a vtable ext slot
  3504. #endif
  3505. int vExtOfs = typeInst->GetOrigBaseVTableSize();
  3506. vDataIdx = mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, 1 + mModule->mCompiler->GetDynCastVDataCount() + mModule->mCompiler->mMaxInterfaceSlots);
  3507. vDataIdx = mModule->mBfIRBuilder->CreateAdd(vDataIdx, mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, vExtOfs));
  3508. BfIRValue extendPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(vDataPtr, vDataIdx);
  3509. vDataPtr = mModule->mBfIRBuilder->CreateLoad(extendPtr);
  3510. vDataIdx = mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, extMethodIdx);
  3511. }
  3512. else
  3513. {
  3514. // Map this new virtual index back to the original index
  3515. //vDataIdx += (methodInstance->mVirtualTableIdx - typeInst->GetBaseVTableSize()) + typeInst->GetOrigBaseVTableSize();
  3516. //vDataIdx = mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, 1 + methodInstance->GetOwner()->GetDynCastVDataCount() + mModule->mCompiler->mMaxInterfaceSlots);
  3517. vDataIdx = mModule->mBfIRBuilder->GetConfigConst(BfIRConfigConst_VirtualMethodOfs, BfTypeCode_Int32);
  3518. vDataIdx = mModule->mBfIRBuilder->CreateAdd(vDataIdx, mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32,
  3519. (methodInstance->mVirtualTableIdx - typeInst->GetBaseVTableSize()) + typeInst->GetOrigBaseVTableSize()));
  3520. }
  3521. }
  3522. else
  3523. {
  3524. //vDataIdx += methodInstance->mVirtualTableIdx;
  3525. //vDataIdx = mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, 1 + methodInstance->GetOwner()->GetDynCastVDataCount() + mModule->mCompiler->mMaxInterfaceSlots);
  3526. vDataIdx = mModule->mBfIRBuilder->GetConfigConst(BfIRConfigConst_VirtualMethodOfs, BfTypeCode_Int32);
  3527. vDataIdx = mModule->mBfIRBuilder->CreateAdd(vDataIdx, mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, methodInstance->mVirtualTableIdx));
  3528. }
  3529. if (!vDataPtr)
  3530. {
  3531. BfIRValue vDataPtrPtr = mModule->mBfIRBuilder->CreateBitCast(irArgs[0], funcPtrType3);
  3532. vDataPtr = mModule->FixClassVData(mModule->mBfIRBuilder->CreateLoad(vDataPtrPtr/*, "vtable"*/));
  3533. }
  3534. auto funcPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(vDataPtr, vDataIdx/*, "vfn"*/);
  3535. funcCallInst = mModule->mBfIRBuilder->CreateLoad(funcPtr);
  3536. }
  3537. }
  3538. }
  3539. else // non-virtual
  3540. {
  3541. if (methodInstance->GetOwner()->IsInterface())
  3542. {
  3543. // We're attempting to directly invoke a non-virtual interface method, this will happen during the unspecialized pass
  3544. // OR if we had an error and didn't find an implementing member in the actual target
  3545. if (!mModule->mCurMethodInstance->mIsUnspecialized)
  3546. mModule->AssertErrorState();
  3547. if (returnType->IsInterface())
  3548. returnType = mModule->CreateConcreteInterfaceType(returnType->ToTypeInstance());
  3549. return _GetDefaultReturnValue();
  3550. }
  3551. }
  3552. if (mFunctionBindResult != NULL)
  3553. {
  3554. mFunctionBindResult->mFunc = funcCallInst;
  3555. if (irArgs.size() != 0)
  3556. {
  3557. auto targetType = methodInstance->mMethodInstanceGroup->mOwner;
  3558. if ((targetType->IsValueType()) && (targetType->IsSplattable()) && (!methodDef->HasNoThisSplat()))
  3559. mFunctionBindResult->mTarget = BfTypedValue(irArgs[0], targetType, BfTypedValueKind_SplatHead);
  3560. else
  3561. mFunctionBindResult->mTarget = BfTypedValue(irArgs[0], targetType, targetType->IsComposite() ? BfTypedValueKind_Addr : BfTypedValueKind_Value);
  3562. }
  3563. else
  3564. {
  3565. mFunctionBindResult->mTarget = BfTypedValue();
  3566. }
  3567. return BfTypedValue();
  3568. }
  3569. if (methodInstance->mReturnType == NULL)
  3570. {
  3571. mModule->AssertErrorState();
  3572. return BfTypedValue();
  3573. }
  3574. if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsUnspecialized))
  3575. {
  3576. // Don't actually do the call - our target may be a generic param
  3577. return _GetDefaultReturnValue();
  3578. }
  3579. if (mDeferCallRef != NULL)
  3580. {
  3581. mModule->AddDeferredCall(BfModuleMethodInstance(methodInstance, func), irArgs, mDeferScopeAlloc, mDeferCallRef);
  3582. //return _GetDefaultReturnValue();
  3583. return mModule->GetFakeTypedValue(returnType);
  3584. }
  3585. if (!funcCallInst)
  3586. {
  3587. if ((mModule->HasCompiledOutput()) || (mModule->mCompiler->mOptions.mExtraResolveChecks))
  3588. {
  3589. // This can happen either from an error, or from the resolver while doing Internals_Changed processing
  3590. mModule->AssertErrorState();
  3591. }
  3592. //return mModule->GetDefaultTypedValue(returnType,/*, true*/false, returnType->IsComposite());
  3593. return _GetDefaultReturnValue();
  3594. }
  3595. bool hasResult = !methodInstance->mReturnType->IsValuelessType();
  3596. BfIRValue firstArg;
  3597. if (irArgs.size() != 0)
  3598. firstArg = irArgs[0];
  3599. auto methodInstOwner = methodInstance->GetOwner();
  3600. auto expectCallingConvention = mModule->GetCallingConvention(methodInstOwner, methodDef);
  3601. if ((methodInstOwner->IsFunction()) && (methodInstance->GetParamCount() > 0) && (methodInstance->GetParamName(0) == "this"))
  3602. {
  3603. auto paramType = methodInstance->GetParamType(0);
  3604. if (!paramType->IsValueType())
  3605. expectCallingConvention = BfIRCallingConv_ThisCall;
  3606. }
  3607. if ((methodInstance->mAlwaysInline) && (mModule->mCompiler->mOptions.mEmitLineInfo))
  3608. {
  3609. // Emit a NOP so we always have a "step over" point
  3610. mModule->EmitEnsureInstructionAt();
  3611. }
  3612. if (returnType->IsComposite())
  3613. mModule->mBfIRBuilder->PopulateType(returnType);
  3614. BfIRValue callInst;
  3615. if (sret != NULL)
  3616. {
  3617. SizedArray<BfIRValue, 8> sretIRArgs;
  3618. sretIRArgs.push_back(sret->mValue);
  3619. if (!irArgs.IsEmpty())
  3620. sretIRArgs.Insert(sretIRArgs.size(), &irArgs[0], irArgs.size());
  3621. callInst = mModule->mBfIRBuilder->CreateCall(funcCallInst, sretIRArgs);
  3622. }
  3623. else
  3624. {
  3625. callInst = mModule->mBfIRBuilder->CreateCall(funcCallInst, irArgs);
  3626. if (hasResult)
  3627. mModule->mBfIRBuilder->SetName(callInst, methodDef->mName);
  3628. }
  3629. if (expectCallingConvention != BfIRCallingConv_CDecl)
  3630. mModule->mBfIRBuilder->SetCallCallingConv(callInst, expectCallingConvention);
  3631. if (methodDef->mNoReturn)
  3632. mModule->mBfIRBuilder->Call_AddAttribute(callInst, -1, BfIRAttribute_NoReturn);
  3633. bool hadAttrs = false;
  3634. int paramIdx = 0;
  3635. bool doingThis = !methodDef->mIsStatic;
  3636. int argIdx = 0;
  3637. if (sret != NULL)
  3638. {
  3639. mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_StructRet);
  3640. argIdx++;
  3641. }
  3642. for ( ; argIdx < (int)irArgs.size(); /*argIdx++*/)
  3643. {
  3644. auto _HandleParamType = [&] (BfType* paramType)
  3645. {
  3646. if (paramType->IsStruct())
  3647. {
  3648. if ((!doingThis) || (!methodDef->mIsMutating && !methodDef->mNoSplat))
  3649. {
  3650. auto loweredTypeCode = paramType->GetLoweredType();
  3651. if (loweredTypeCode != BfTypeCode_None)
  3652. {
  3653. argIdx++;
  3654. return; // Lowering never requires attributes
  3655. }
  3656. }
  3657. }
  3658. int addDeref = -1;
  3659. if (paramType->IsRef())
  3660. {
  3661. auto refType = (BfRefType*)paramType;
  3662. auto elementType = refType->mElementType;
  3663. mModule->PopulateType(elementType, BfPopulateType_Data);
  3664. addDeref = elementType->mSize;
  3665. if ((addDeref <= 0) && (!elementType->IsValuelessType()))
  3666. mModule->AssertErrorState();
  3667. }
  3668. if ((paramType->IsComposite()) && (!paramType->IsTypedPrimitive()))
  3669. {
  3670. if (mModule->mCompiler->mOptions.mAllowStructByVal)
  3671. {
  3672. //byval
  3673. }
  3674. else
  3675. {
  3676. mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_NoCapture);
  3677. mModule->PopulateType(paramType, BfPopulateType_Data);
  3678. addDeref = paramType->mSize;
  3679. }
  3680. }
  3681. else if (paramType->IsPrimitiveType())
  3682. {
  3683. auto primType = (BfPrimitiveType*)paramType;
  3684. if ((primType->mTypeDef->mTypeCode == BfTypeCode_Boolean) && (!methodInstance->mIsIntrinsic))
  3685. mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_ZExt);
  3686. }
  3687. if (addDeref >= 0)
  3688. {
  3689. mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_Dereferencable, addDeref);
  3690. }
  3691. argIdx++;
  3692. };
  3693. BfType* paramType = NULL;
  3694. if (doingThis)
  3695. {
  3696. paramType = methodInstance->GetOwner();
  3697. if (paramType->IsValuelessType())
  3698. {
  3699. doingThis = false;
  3700. continue;
  3701. }
  3702. bool isSplatted = methodInstance->GetParamIsSplat(-1); // (resolvedTypeRef->IsSplattable()) && (!methodDef->mIsMutating);
  3703. if (isSplatted)
  3704. {
  3705. BfTypeUtils::SplatIterate(_HandleParamType, paramType);
  3706. doingThis = false;
  3707. continue;
  3708. }
  3709. else
  3710. _HandleParamType(paramType);
  3711. }
  3712. else
  3713. {
  3714. paramType = methodInstance->GetParamType(paramIdx);
  3715. if ((paramType->IsValuelessType()) && (!paramType->IsMethodRef()))
  3716. {
  3717. paramIdx++;
  3718. continue;
  3719. }
  3720. //if (resolvedTypeRef->IsSplattable())
  3721. if (methodInstance->GetParamIsSplat(paramIdx))
  3722. {
  3723. BfTypeUtils::SplatIterate(_HandleParamType, paramType);
  3724. paramIdx++;
  3725. continue;
  3726. }
  3727. else
  3728. _HandleParamType(methodInstance->GetParamType(paramIdx));
  3729. }
  3730. if (doingThis)
  3731. doingThis = false;
  3732. else
  3733. paramIdx++;
  3734. //argIdx++;
  3735. }
  3736. if (isTailCall)
  3737. mModule->mBfIRBuilder->SetTailCall(callInst);
  3738. if (methodDef->mNoReturn)
  3739. {
  3740. mModule->mBfIRBuilder->CreateUnreachable();
  3741. // For debuggability when looking back at stack trace
  3742. //mModule->ExtendLocalLifetimes(0);
  3743. if (mModule->IsTargetingBeefBackend())
  3744. {
  3745. auto checkScope = mModule->mCurMethodState->mCurScope;
  3746. while (checkScope != NULL)
  3747. {
  3748. mModule->EmitLifetimeEnds(checkScope);
  3749. checkScope = checkScope->mPrevScope;
  3750. }
  3751. // This 'fake' branch extends lifetimes of outer variable scopes
  3752. if (mModule->mCurMethodState->mIRExitBlock)
  3753. mModule->mBfIRBuilder->CreateBr_Fake(mModule->mCurMethodState->mIRExitBlock);
  3754. }
  3755. }
  3756. else
  3757. {
  3758. if (mModule->mCurMethodState != NULL)
  3759. mModule->mCurMethodState->mMayNeedThisAccessCheck = true;
  3760. }
  3761. BfTypedValue result;
  3762. if (sret != NULL)
  3763. result = *sret;
  3764. else if (hasResult)
  3765. result = BfTypedValue(callInst, methodInstance->mReturnType);
  3766. else
  3767. result = mModule->GetFakeTypedValue(methodInstance->mReturnType);
  3768. if (result.mType->IsRef())
  3769. {
  3770. result = mModule->RemoveRef(result);
  3771. if (methodDef->mIsReadOnly)
  3772. {
  3773. if (result.mKind == BfTypedValueKind_Addr)
  3774. result.mKind = BfTypedValueKind_ReadOnlyAddr;
  3775. }
  3776. }
  3777. return result;
  3778. }
  3779. BfTypedValue BfExprEvaluator::CreateCall(BfMethodMatcher* methodMatcher, BfTypedValue target)
  3780. {
  3781. auto moduleMethodInstance = mModule->GetMethodInstance(methodMatcher->mBestMethodTypeInstance, methodMatcher->mBestMethodDef, methodMatcher->mBestMethodGenericArguments);
  3782. if (moduleMethodInstance.mMethodInstance == NULL)
  3783. return BfTypedValue();
  3784. if ((target) && (target.mType != moduleMethodInstance.mMethodInstance->GetOwner()))
  3785. {
  3786. auto castedTarget = mModule->Cast(methodMatcher->mTargetSrc, target, moduleMethodInstance.mMethodInstance->GetOwner());
  3787. BF_ASSERT(castedTarget);
  3788. target = castedTarget;
  3789. }
  3790. return CreateCall(methodMatcher->mTargetSrc, target, BfTypedValue(), methodMatcher->mBestMethodDef, moduleMethodInstance, false, methodMatcher->mArguments);
  3791. }
  3792. void BfExprEvaluator::MakeBaseConcrete(BfTypedValue& typedValue)
  3793. {
  3794. if (typedValue.IsBase())
  3795. {
  3796. auto baseType = mModule->mCurTypeInstance->mBaseType;
  3797. if (baseType == NULL)
  3798. baseType = mModule->mContext->mBfObjectType;
  3799. mModule->PopulateType(baseType, BfPopulateType_Data);
  3800. typedValue = mModule->Cast(NULL, typedValue, baseType, BfCastFlags_Explicit);
  3801. }
  3802. }
  3803. void BfExprEvaluator::SplatArgs(BfTypedValue value, SizedArrayImpl<BfIRValue>& irArgs)
  3804. {
  3805. if (value.IsSplat())
  3806. {
  3807. int componentIdx = 0;
  3808. BfTypeUtils::SplatIterate([&](BfType* checkType) { irArgs.push_back(mModule->ExtractSplatValue(value, componentIdx++, checkType)); }, value.mType);
  3809. return;
  3810. }
  3811. mModule->mBfIRBuilder->PopulateType(value.mType);
  3812. std::function<void(BfTypedValue)> checkTypeLambda = [&](BfTypedValue curValue)
  3813. {
  3814. BfType* checkType = curValue.mType;
  3815. if (checkType->IsStruct())
  3816. {
  3817. auto checkTypeInstance = checkType->ToTypeInstance();
  3818. if ((checkTypeInstance->mBaseType != NULL) && (!checkTypeInstance->mBaseType->IsValuelessType()))
  3819. {
  3820. BfTypedValue baseValue;
  3821. if (curValue.IsAddr())
  3822. baseValue = BfTypedValue((!curValue.mValue) ? BfIRValue() : mModule->mBfIRBuilder->CreateInBoundsGEP(curValue.mValue, 0, 0), checkTypeInstance->mBaseType, true);
  3823. else
  3824. baseValue = BfTypedValue((!curValue.mValue) ? BfIRValue() : mModule->mBfIRBuilder->CreateExtractValue(curValue.mValue, 0), checkTypeInstance->mBaseType);
  3825. checkTypeLambda(baseValue);
  3826. }
  3827. if (checkTypeInstance->mIsUnion)
  3828. {
  3829. auto unionInnerType = checkTypeInstance->GetUnionInnerType();
  3830. if (!unionInnerType->IsValuelessType())
  3831. {
  3832. BfTypedValue unionValue = mModule->ExtractValue(curValue, NULL, 1);
  3833. checkTypeLambda(unionValue);
  3834. }
  3835. if (checkTypeInstance->IsEnum())
  3836. {
  3837. BfTypedValue dscrValue = mModule->ExtractValue(curValue, NULL, 2);
  3838. checkTypeLambda(dscrValue);
  3839. }
  3840. }
  3841. else
  3842. {
  3843. for (int fieldIdx = 0; fieldIdx < (int)checkTypeInstance->mFieldInstances.size(); fieldIdx++)
  3844. {
  3845. auto fieldInstance = (BfFieldInstance*)&checkTypeInstance->mFieldInstances[fieldIdx];
  3846. if (fieldInstance->mDataIdx >= 0)
  3847. {
  3848. BfTypedValue fieldValue = mModule->ExtractValue(curValue, fieldInstance, fieldInstance->mDataIdx);
  3849. checkTypeLambda(fieldValue);
  3850. }
  3851. }
  3852. }
  3853. }
  3854. else if (checkType->IsMethodRef())
  3855. {
  3856. BF_ASSERT(curValue.IsAddr());
  3857. BfMethodRefType* methodRefType = (BfMethodRefType*)checkType;
  3858. for (int dataIdx = 0; dataIdx < methodRefType->GetCaptureDataCount(); dataIdx++)
  3859. {
  3860. auto checkType = methodRefType->GetCaptureType(dataIdx);
  3861. if (methodRefType->WantsDataPassedAsSplat(dataIdx))
  3862. {
  3863. BF_ASSERT(dataIdx == 0);
  3864. auto ptrType = mModule->CreatePointerType(checkType);
  3865. auto elemPtr = mModule->mBfIRBuilder->CreateBitCast(curValue.mValue, mModule->mBfIRBuilder->MapType(ptrType));
  3866. checkTypeLambda(BfTypedValue(elemPtr, checkType, BfTypedValueKind_Addr));
  3867. //BfTypedValue fieldValue = mModule->ExtractValue(curValue, fieldInstance, fieldInstance->mDataIdx);
  3868. //checkTypeLambda(fieldValue);
  3869. }
  3870. else
  3871. {
  3872. auto elemVal = mModule->mBfIRBuilder->CreateInBoundsGEP(curValue.mValue, 0, dataIdx);
  3873. if (!checkType->IsComposite())
  3874. elemVal = mModule->mBfIRBuilder->CreateLoad(elemVal);
  3875. irArgs.Add(elemVal);
  3876. //irArgs.Add(mModule->ExtractValue(curValue, dataIdx));
  3877. }
  3878. }
  3879. }
  3880. else if (!checkType->IsValuelessType())
  3881. {
  3882. auto loadedVal = mModule->LoadValue(curValue);
  3883. irArgs.push_back(loadedVal.mValue);
  3884. }
  3885. };
  3886. checkTypeLambda(value);
  3887. }
  3888. void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl<BfIRValue>& irArgs, bool disableSplat, bool disableLowering)
  3889. {
  3890. MakeBaseConcrete(argVal);
  3891. if (argVal.mType->IsValuelessType())
  3892. return;
  3893. bool wantSplat = false;
  3894. if ((argVal.mType->IsSplattable()) && (!disableSplat))
  3895. {
  3896. if ((int)irArgs.size() + argVal.mType->GetSplatCount() <= mModule->mCompiler->mOptions.mMaxSplatRegs)
  3897. wantSplat = true;
  3898. }
  3899. if (wantSplat)
  3900. {
  3901. SplatArgs(argVal, irArgs);
  3902. }
  3903. else
  3904. {
  3905. if (argVal.mType->IsComposite())
  3906. {
  3907. argVal = mModule->MakeAddressable(argVal);
  3908. if (!disableLowering)
  3909. {
  3910. auto loweredTypeCode = argVal.mType->GetLoweredType();
  3911. if (loweredTypeCode != BfTypeCode_None)
  3912. {
  3913. auto primType = mModule->GetPrimitiveType(loweredTypeCode);
  3914. auto ptrType = mModule->CreatePointerType(primType);
  3915. BfIRValue primPtrVal = mModule->mBfIRBuilder->CreateBitCast(argVal.mValue, mModule->mBfIRBuilder->MapType(ptrType));
  3916. auto primVal = mModule->mBfIRBuilder->CreateLoad(primPtrVal);
  3917. irArgs.push_back(primVal);
  3918. return;
  3919. }
  3920. }
  3921. }
  3922. else
  3923. argVal = mModule->LoadValue(argVal);
  3924. irArgs.push_back(argVal.mValue);
  3925. }
  3926. }
  3927. void BfExprEvaluator::PushThis(BfAstNode* targetSrc, BfTypedValue argVal, BfMethodInstance* methodInstance, SizedArrayImpl<BfIRValue>& irArgs, bool skipMutCheck)
  3928. {
  3929. MakeBaseConcrete(argVal);
  3930. auto methodDef = methodInstance->mMethodDef;
  3931. if (methodInstance->IsSkipCall())
  3932. return;
  3933. if (!argVal)
  3934. {
  3935. //BF_ASSERT(mFunctionBindResult != NULL);
  3936. return;
  3937. }
  3938. if (methodDef->mIsMutating)
  3939. {
  3940. bool checkMut = false;
  3941. if (argVal.mType->IsGenericParam())
  3942. {
  3943. // For capturing mutability
  3944. if (mResultLocalVar != NULL)
  3945. mResultLocalVar->mWrittenToId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++;
  3946. }
  3947. if (((argVal.mType->IsComposite()) || (argVal.mType->IsTypedPrimitive())))
  3948. {
  3949. if ((argVal.IsReadOnly()) || (!argVal.IsAddr()))
  3950. {
  3951. if (!skipMutCheck)
  3952. {
  3953. String err = StrFormat("call mutating method '%s' on", mModule->MethodToString(methodInstance).c_str());
  3954. CheckModifyResult(argVal, targetSrc, err.c_str());
  3955. }
  3956. if (argVal.IsSplat())
  3957. {
  3958. argVal = mModule->AggregateSplat(argVal);
  3959. argVal = mModule->MakeAddressable(argVal);
  3960. }
  3961. }
  3962. else
  3963. {
  3964. if (mResultLocalVar != NULL)
  3965. {
  3966. // When we are capturing, we need to note that we require capturing by reference here
  3967. mResultLocalVar->mWrittenToId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++;
  3968. }
  3969. }
  3970. }
  3971. }
  3972. if (argVal.mType->IsValuelessType())
  3973. return;
  3974. if ((argVal.mType->IsTypedPrimitive()) && (methodDef->HasNoThisSplat()))
  3975. {
  3976. argVal = mModule->MakeAddressable(argVal);
  3977. irArgs.push_back(argVal.mValue);
  3978. return;
  3979. }
  3980. auto thisType = methodInstance->GetParamType(-1);
  3981. PushArg(argVal, irArgs, methodDef->HasNoThisSplat(), thisType->IsPointer());
  3982. }
  3983. void BfExprEvaluator::FinishDeferredEvals(SizedArrayImpl<BfResolvedArg>& argValues)
  3984. {
  3985. for (int argIdx = 0; argIdx < argValues.size(); argIdx++)
  3986. {
  3987. auto argValue = argValues[argIdx].mTypedValue;
  3988. if ((argValues[argIdx].mArgFlags & (BfArgFlag_DelegateBindAttempt | BfArgFlag_LambdaBindAttempt | BfArgFlag_UnqualifiedDotAttempt | BfArgFlag_DeferredEval)) != 0)
  3989. {
  3990. if (!argValue)
  3991. {
  3992. auto expr = BfNodeDynCast<BfExpression>(argValues[argIdx].mExpression);
  3993. if (expr != NULL)
  3994. argValue = mModule->CreateValueFromExpression(expr);
  3995. }
  3996. }
  3997. }
  3998. }
  3999. void BfExprEvaluator::AddCallDependencies(BfMethodInstance* methodInstance)
  4000. {
  4001. if (methodInstance->mReturnType != NULL)
  4002. mModule->AddDependency(methodInstance->mReturnType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage);
  4003. for (int paramIdx = 0; paramIdx < methodInstance->GetParamCount(); paramIdx++)
  4004. {
  4005. auto paramType = methodInstance->GetParamType(paramIdx);
  4006. mModule->AddDependency(paramType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage);
  4007. }
  4008. if (methodInstance->mMethodInfoEx != NULL)
  4009. {
  4010. for (auto genericArg : methodInstance->mMethodInfoEx->mMethodGenericArguments)
  4011. {
  4012. if (genericArg->IsWrappableType())
  4013. genericArg = mModule->GetWrappedStructType(genericArg);
  4014. mModule->AddDependency(genericArg, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage);
  4015. }
  4016. }
  4017. }
  4018. //TODO: delete argumentsZ
  4019. BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValue& inTarget, const BfTypedValue& origTarget, BfMethodDef* methodDef, BfModuleMethodInstance moduleMethodInstance, bool bypassVirtual, SizedArrayImpl<BfResolvedArg>& argValues, bool skipThis)
  4020. {
  4021. static int sCallIdx = 0;
  4022. if (!mModule->mCompiler->mIsResolveOnly)
  4023. sCallIdx++;
  4024. int callIdx = sCallIdx;
  4025. if (callIdx == 0x0000042B)
  4026. {
  4027. NOP;
  4028. }
  4029. // Temporarily disable so we don't capture calls in params
  4030. SetAndRestoreValue<BfFunctionBindResult*> prevBindResult(mFunctionBindResult, NULL);
  4031. BfMethodInstance* methodInstance = moduleMethodInstance.mMethodInstance;
  4032. SizedArray<BfIRValue, 4> irArgs;
  4033. if ((methodDef->mIsAbstract) && (bypassVirtual))
  4034. {
  4035. mModule->Fail(StrFormat("Abstract base method '%s' cannot be invoked", mModule->MethodToString(methodInstance).c_str()), targetSrc);
  4036. }
  4037. bool isSkipCall = moduleMethodInstance.mMethodInstance->IsSkipCall(bypassVirtual);
  4038. BfType* returnType = methodInstance->mReturnType;
  4039. /*if (returnType->IsSelf())
  4040. {
  4041. returnType = methodInstance->GetOwner();
  4042. BF_ASSERT(returnType->IsInterface());
  4043. }*/
  4044. BfTypedValue target = inTarget;
  4045. if (!skipThis)
  4046. {
  4047. if (!methodDef->mIsStatic)
  4048. {
  4049. if (!target)
  4050. {
  4051. FinishDeferredEvals(argValues);
  4052. mModule->Fail(StrFormat("An instance reference is required to %s the non-static method '%s'",
  4053. (prevBindResult.mPrevVal != NULL) ? "bind" : "invoke",
  4054. mModule->MethodToString(methodInstance).c_str()), targetSrc);
  4055. return mModule->GetDefaultTypedValue(returnType);
  4056. }
  4057. auto prevResult = mResult;
  4058. mResult = target;
  4059. CheckResultForReading(mResult);
  4060. mResult = prevResult;
  4061. if (methodDef->mMethodType != BfMethodType_Ctor)
  4062. {
  4063. bool doAccessCheck = true;
  4064. if (target.IsThis())
  4065. {
  4066. if (!mModule->mCurMethodState->mMayNeedThisAccessCheck)
  4067. doAccessCheck = false;
  4068. }
  4069. if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) && (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mSkipAccessCheckAttributeTypeDef)))
  4070. doAccessCheck = false;
  4071. if ((doAccessCheck) && (!isSkipCall))
  4072. mModule->EmitObjectAccessCheck(target);
  4073. }
  4074. if (((prevBindResult.mPrevVal == NULL) || (!prevBindResult.mPrevVal->mSkipThis)) &&
  4075. (!isSkipCall))
  4076. {
  4077. bool skipMutCheck = false;
  4078. if ((prevBindResult.mPrevVal != NULL) && (prevBindResult.mPrevVal->mSkipMutCheck))
  4079. {
  4080. // If we are binding a delegate, then we will end up making a copy of the target anyway
  4081. // so we don't need to do a mutability check
  4082. skipMutCheck = true;
  4083. }
  4084. PushThis(targetSrc, target, moduleMethodInstance.mMethodInstance, irArgs, skipMutCheck);
  4085. }
  4086. }
  4087. else if ((target) && (target.mType->IsFunction()))
  4088. {
  4089. CheckResultForReading(target);
  4090. target = mModule->LoadValue(target);
  4091. auto funcType = mModule->mBfIRBuilder->MapMethod(moduleMethodInstance.mMethodInstance);
  4092. auto funcPtrType = mModule->mBfIRBuilder->GetPointerTo(funcType);
  4093. moduleMethodInstance.mFunc = mModule->mBfIRBuilder->CreateIntToPtr(target.mValue, funcPtrType);
  4094. }
  4095. else
  4096. {
  4097. mModule->CheckStaticAccess(methodInstance->mMethodInstanceGroup->mOwner);
  4098. if (target)
  4099. {
  4100. FinishDeferredEvals(argValues);
  4101. mModule->Fail(StrFormat("Method '%s' cannot be accessed with an instance reference; qualify it with a type name instead",
  4102. mModule->MethodToString(methodInstance).c_str()), targetSrc);
  4103. return mModule->GetDefaultTypedValue(returnType);
  4104. }
  4105. }
  4106. }
  4107. if (isSkipCall)
  4108. {
  4109. FinishDeferredEvals(argValues);
  4110. mModule->EmitEnsureInstructionAt();
  4111. return mModule->GetDefaultTypedValue(returnType);
  4112. }
  4113. int argIdx = 0;
  4114. int paramIdx = 0;
  4115. BfIRValue expandedParamAlloca;
  4116. BfTypedValue expandedParamsArray;
  4117. BfType* expandedParamsElementType = NULL;
  4118. int extendedParamIdx = 0;
  4119. AddCallDependencies(methodInstance);
  4120. auto autoComplete = GetAutoComplete();
  4121. if (autoComplete != NULL)
  4122. {
  4123. // Set to false to make sure we don't capture method match info from 'params' array creation
  4124. autoComplete->mIsCapturingMethodMatchInfo = false;
  4125. }
  4126. BfScopeData* boxScopeData = mDeferScopeAlloc;
  4127. if ((boxScopeData == NULL) && (mModule->mCurMethodState != NULL))
  4128. boxScopeData = mModule->mCurMethodState->mCurScope;
  4129. bool failed = false;
  4130. while (true)
  4131. {
  4132. bool isDirectPass = false;
  4133. if (paramIdx >= (int)methodInstance->GetParamCount())
  4134. {
  4135. if (argIdx < (int)argValues.size())
  4136. {
  4137. BfAstNode* errorRef = argValues[argIdx].mExpression;
  4138. if (errorRef == NULL)
  4139. errorRef = targetSrc;
  4140. BfError* error = mModule->Fail(StrFormat("Too many arguments, expected %d fewer.", (int)argValues.size() - argIdx), errorRef);
  4141. if ((error != NULL) && (methodInstance->mMethodDef->mMethodDeclaration != NULL))
  4142. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
  4143. failed = true;
  4144. break;
  4145. }
  4146. break;
  4147. }
  4148. // Only create actual params if we're not just trying to bind the function
  4149. if ((prevBindResult.mPrevVal != NULL) && (!prevBindResult.mPrevVal->mWantsArgs))
  4150. break;
  4151. BfType* wantType = NULL;
  4152. bool wantsSplat = false;
  4153. if (expandedParamsElementType != NULL)
  4154. {
  4155. wantType = expandedParamsElementType;
  4156. }
  4157. else
  4158. {
  4159. wantsSplat = methodInstance->GetParamIsSplat(paramIdx);
  4160. if (methodInstance->IsImplicitCapture(paramIdx))
  4161. {
  4162. if (mModule->mCurMethodInstance->IsMixin())
  4163. {
  4164. // Don't bother, also- can fail on captures
  4165. }
  4166. else
  4167. {
  4168. // static int captureIdx = 0;
  4169. // captureIdx++;
  4170. // int curCaptureIdx = captureIdx;
  4171. //
  4172. // if (curCaptureIdx == 0x91)
  4173. // {
  4174. // NOP;
  4175. // }
  4176. auto lookupVal = DoImplicitArgCapture(targetSrc, methodInstance, paramIdx, failed, BfImplicitParamKind_General, origTarget);
  4177. if (lookupVal)
  4178. {
  4179. if (wantsSplat)
  4180. {
  4181. SplatArgs(lookupVal, irArgs);
  4182. }
  4183. else
  4184. {
  4185. irArgs.push_back(lookupVal.mValue);
  4186. }
  4187. }
  4188. }
  4189. paramIdx++;
  4190. continue;
  4191. }
  4192. wantType = methodInstance->GetParamType(paramIdx);
  4193. if (wantType->IsSelf())
  4194. wantType = methodInstance->GetOwner();
  4195. BfParamKind paramKind = methodInstance->GetParamKind(paramIdx);
  4196. if (paramKind == BfParamKind_Params)
  4197. {
  4198. //TODO: Check to see if it's a direct array pass
  4199. if (argIdx < (int)argValues.size())
  4200. {
  4201. auto argValue = argValues[argIdx].mTypedValue;
  4202. if ((argValue.IsParams()) /*&& (mModule->CanImplicitlyCast(argValue, wantType))*/)
  4203. isDirectPass = true;
  4204. }
  4205. if (!isDirectPass)
  4206. {
  4207. if (wantType->IsArray())
  4208. {
  4209. BfArrayType* arrayType = (BfArrayType*)wantType;
  4210. mModule->PopulateType(arrayType, BfPopulateType_DataAndMethods);
  4211. expandedParamsElementType = arrayType->mTypeGenericArguments[0];
  4212. int arrayClassSize = arrayType->mInstSize - expandedParamsElementType->mSize;
  4213. int numElements = (int)argValues.size() - argIdx;
  4214. expandedParamsArray = BfTypedValue(mModule->AllocFromType(arrayType->GetUnderlyingType(), boxScopeData, BfIRValue(), mModule->GetConstValue(numElements), 1, BfAllocFlags_None),
  4215. arrayType, false);
  4216. BfResolvedArgs resolvedArgs;
  4217. MatchConstructor(targetSrc, NULL, expandedParamsArray, arrayType, resolvedArgs, false, false);
  4218. //TODO: Assert 'length' var is at slot 1
  4219. auto arrayBits = mModule->mBfIRBuilder->CreateBitCast(expandedParamsArray.mValue, mModule->mBfIRBuilder->MapType(arrayType->mBaseType));
  4220. int arrayLengthBitCount = arrayType->GetLengthBitCount();
  4221. if (arrayLengthBitCount == 0)
  4222. {
  4223. mModule->Fail("INTERNAL ERROR: Unable to find array 'length' field", targetSrc);
  4224. return BfTypedValue();
  4225. }
  4226. auto addr = mModule->mBfIRBuilder->CreateInBoundsGEP(arrayBits, 0, 1);
  4227. if (arrayLengthBitCount == 64)
  4228. mModule->mBfIRBuilder->CreateAlignedStore(mModule->GetConstValue64(numElements), addr, 8);
  4229. else
  4230. mModule->mBfIRBuilder->CreateAlignedStore(mModule->GetConstValue32(numElements), addr, 4);
  4231. PushArg(expandedParamsArray, irArgs);
  4232. }
  4233. else
  4234. {
  4235. int numElements = (int)argValues.size() - argIdx;
  4236. auto genericTypeInst = wantType->ToGenericTypeInstance();
  4237. expandedParamsElementType = genericTypeInst->mTypeGenericArguments[0];
  4238. expandedParamsArray = BfTypedValue(mModule->CreateAlloca(wantType), wantType, true);
  4239. expandedParamAlloca = mModule->CreateAlloca(genericTypeInst->mTypeGenericArguments[0], true, NULL, mModule->GetConstValue(numElements));
  4240. mModule->mBfIRBuilder->CreateStore(expandedParamAlloca, mModule->mBfIRBuilder->CreateInBoundsGEP(expandedParamsArray.mValue, 0, 1));
  4241. mModule->mBfIRBuilder->CreateStore(mModule->GetConstValue(numElements), mModule->mBfIRBuilder->CreateInBoundsGEP(expandedParamsArray.mValue, 0, 2));
  4242. PushArg(expandedParamsArray, irArgs);
  4243. }
  4244. continue;
  4245. }
  4246. }
  4247. }
  4248. BfAstNode* arg = NULL;
  4249. bool hadMissingArg = false;
  4250. if (argIdx < (int)argValues.size())
  4251. {
  4252. arg = argValues[argIdx].mExpression;
  4253. if ((arg == NULL) && (argValues[0].mExpression != NULL))
  4254. hadMissingArg = true;
  4255. }
  4256. else
  4257. hadMissingArg = true;
  4258. BfTypedValue argValue;
  4259. if (hadMissingArg)
  4260. {
  4261. if (expandedParamsArray)
  4262. break;
  4263. if ((argIdx >= (int) methodInstance->mDefaultValues.size()) || (!methodInstance->mDefaultValues[argIdx]))
  4264. {
  4265. BfAstNode* refNode = targetSrc;
  4266. if (argValues.size() > 0)
  4267. {
  4268. auto checkExpr = argValues.back().mExpression;
  4269. if (checkExpr != NULL)
  4270. refNode = checkExpr;
  4271. }
  4272. BfAstNode* prevNode = NULL;
  4273. if (targetSrc == NULL)
  4274. {
  4275. // We must be in BfModule::EmitCtorBody
  4276. }
  4277. else if (auto tupleExpr = BfNodeDynCastExact<BfTupleExpression>(targetSrc))
  4278. {
  4279. if (tupleExpr->mCommas.size() > 0)
  4280. prevNode = tupleExpr->mCommas.back();
  4281. else
  4282. prevNode = tupleExpr->mOpenParen;
  4283. if (tupleExpr->mCloseParen != NULL)
  4284. refNode = tupleExpr->mCloseParen;
  4285. }
  4286. else if (mModule->mParentNodeEntry != NULL)
  4287. {
  4288. if (auto objectCreateExpr = BfNodeDynCast<BfObjectCreateExpression>(mModule->mParentNodeEntry->mNode))
  4289. {
  4290. if (objectCreateExpr->mCommas.size() > 0)
  4291. prevNode = objectCreateExpr->mCommas.back();
  4292. else
  4293. prevNode = objectCreateExpr->mOpenToken;
  4294. if (objectCreateExpr->mCloseToken != NULL)
  4295. refNode = objectCreateExpr->mCloseToken;
  4296. if (auto newNode = BfNodeDynCast<BfNewNode>(objectCreateExpr->mNewNode))
  4297. {
  4298. if (newNode->mAllocNode == targetSrc)
  4299. refNode = targetSrc;
  4300. }
  4301. }
  4302. else if (auto invokeExpr = BfNodeDynCast<BfInvocationExpression>(mModule->mParentNodeEntry->mNode))
  4303. {
  4304. if (invokeExpr->mCommas.size() > 0)
  4305. prevNode = invokeExpr->mCommas.back();
  4306. else
  4307. prevNode = invokeExpr->mOpenParen;
  4308. if (invokeExpr->mCloseParen != NULL)
  4309. refNode = invokeExpr->mCloseParen;
  4310. }
  4311. }
  4312. if ((autoComplete != NULL) && (prevNode != NULL))
  4313. autoComplete->CheckEmptyStart(prevNode, wantType);
  4314. BfError* error = mModule->Fail(StrFormat("Not enough parameters specified, expected %d more.", methodInstance->GetParamCount() - paramIdx), refNode);
  4315. if ((error != NULL) && (methodInstance->mMethodDef->mMethodDeclaration != NULL))
  4316. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
  4317. failed = true;
  4318. break;
  4319. }
  4320. auto foreignDefaultVal = methodInstance->mDefaultValues[argIdx];
  4321. auto foreignConst = methodInstance->GetOwner()->mConstHolder->GetConstant(methodInstance->mDefaultValues[argIdx]);
  4322. if (foreignConst->mConstType == BfConstType_AggZero)
  4323. {
  4324. // Allow this
  4325. }
  4326. else if (foreignConst->mTypeCode == BfTypeCode_NullPtr)
  4327. {
  4328. if (wantType->IsNullable())
  4329. {
  4330. argValue = mModule->GetDefaultTypedValue(wantType, false, BfDefaultValueKind_Addr);
  4331. }
  4332. }
  4333. if (!argValue)
  4334. {
  4335. argValue = mModule->GetTypedValueFromConstant(foreignConst, methodInstance->GetOwner()->mConstHolder, wantType);
  4336. }
  4337. }
  4338. else
  4339. {
  4340. argValue = argValues[argIdx].mTypedValue;
  4341. if ((argValue.IsParams()) && (!isDirectPass))
  4342. {
  4343. BfAstNode* refNode = argValues[argIdx].mExpression;
  4344. if (auto unaryOperatorExpr = BfNodeDynCast<BfUnaryOperatorExpression>(refNode))
  4345. refNode = unaryOperatorExpr->mOpToken;
  4346. mModule->Warn(0, "Unused 'params' expression", refNode);
  4347. }
  4348. if (wantType->IsMethodRef())
  4349. {
  4350. auto expr = argValues[argIdx].mExpression;
  4351. if (expr != NULL)
  4352. SetMethodElementType(expr);
  4353. if (!argValue)
  4354. argValue = mModule->CreateValueFromExpression(BfNodeDynCast<BfExpression>(argValues[argIdx].mExpression), wantType, BfEvalExprFlags_NoCast);
  4355. // Add any implicit captures now
  4356. auto methodRefType = (BfMethodRefType*)wantType;
  4357. BfMethodInstance* useMethodInstance = methodRefType->mMethodRef;
  4358. for (int dataIdx = 0; dataIdx < methodRefType->GetCaptureDataCount(); dataIdx++)
  4359. {
  4360. int paramIdx = methodRefType->GetParamIdxFromDataIdx(dataIdx);
  4361. auto lookupVal = DoImplicitArgCapture(argValues[argIdx].mExpression, useMethodInstance, paramIdx, failed, BfImplicitParamKind_General, argValue);
  4362. if (lookupVal)
  4363. {
  4364. if (methodRefType->WantsDataPassedAsSplat(dataIdx))
  4365. SplatArgs(lookupVal, irArgs);
  4366. else if (lookupVal.mType->IsComposite())
  4367. {
  4368. irArgs.push_back(lookupVal.mValue);
  4369. }
  4370. else
  4371. irArgs.push_back(lookupVal.mValue);
  4372. }
  4373. }
  4374. paramIdx++;
  4375. argIdx++;
  4376. continue;
  4377. }
  4378. else
  4379. {
  4380. BfParamKind paramKind = BfParamKind_Normal;
  4381. if (paramIdx < methodInstance->GetParamCount())
  4382. paramKind = methodInstance->GetParamKind(paramIdx);
  4383. argValues[argIdx].mExpectedType = wantType;
  4384. argValue = ResolveArgValue(argValues[argIdx], wantType, NULL, paramKind);
  4385. }
  4386. }
  4387. if (!argValue)
  4388. {
  4389. failed = true;
  4390. }
  4391. if ((argValue) && (arg != NULL))
  4392. {
  4393. argValue = mModule->Cast(arg, argValue, wantType);
  4394. if (!argValue)
  4395. {
  4396. failed = true;
  4397. }
  4398. else if ((wantType->IsComposite()) && (!expandedParamsArray))
  4399. {
  4400. // We need to make a temp and get the addr of that
  4401. if ((!wantsSplat) && (!argValue.IsValuelessType()) && (!argValue.IsAddr()))
  4402. {
  4403. argValue = mModule->MakeAddressable(argValue);
  4404. }
  4405. }
  4406. else if (!wantType->IsRef())
  4407. argValue = mModule->LoadValue(argValue);
  4408. }
  4409. if (expandedParamsArray)
  4410. {
  4411. if (argValue)
  4412. {
  4413. if (expandedParamAlloca)
  4414. {
  4415. argValue = mModule->LoadValue(argValue);
  4416. auto addr = mModule->mBfIRBuilder->CreateInBoundsGEP(expandedParamAlloca, extendedParamIdx);
  4417. auto storeInst = mModule->mBfIRBuilder->CreateAlignedStore(argValue.mValue, addr, argValue.mType->mAlign);
  4418. }
  4419. else
  4420. {
  4421. argValue = mModule->LoadValue(argValue);
  4422. auto firstAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(expandedParamsArray.mValue, 0, 1);
  4423. auto indexedAddr = mModule->CreateIndexedValue(argValue.mType, firstAddr, extendedParamIdx);
  4424. auto storeInst = mModule->mBfIRBuilder->CreateAlignedStore(argValue.mValue, indexedAddr, argValue.mType->mAlign);
  4425. }
  4426. }
  4427. extendedParamIdx++;
  4428. }
  4429. else
  4430. {
  4431. if ((paramIdx == 0) && (methodInstance->GetParamName(paramIdx) == "this") && (wantType->IsPointer()))
  4432. {
  4433. auto underlyingType = wantType->GetUnderlyingType();
  4434. mModule->PopulateType(underlyingType, BfPopulateType_Data);
  4435. if (underlyingType->IsValuelessType())
  4436. {
  4437. // We don't actually pass a 'this' pointer for mut methods on valueless structs
  4438. argIdx++;
  4439. paramIdx++;
  4440. continue;
  4441. }
  4442. }
  4443. if (argValue)
  4444. {
  4445. if (wantsSplat)
  4446. SplatArgs(argValue, irArgs);
  4447. else
  4448. PushArg(argValue, irArgs, true, false);
  4449. }
  4450. paramIdx++;
  4451. }
  4452. argIdx++;
  4453. }
  4454. if (failed)
  4455. {
  4456. // Process the other unused arguments
  4457. while (argIdx < argValues.size())
  4458. {
  4459. mModule->AssertErrorState();
  4460. auto argValue = argValues[argIdx].mTypedValue;
  4461. if ((argValues[argIdx].mArgFlags & (BfArgFlag_DelegateBindAttempt | BfArgFlag_LambdaBindAttempt | BfArgFlag_UnqualifiedDotAttempt | BfArgFlag_DeferredEval | BfArgFlag_VariableDeclaration)) != 0)
  4462. {
  4463. if (!argValue)
  4464. {
  4465. auto expr = BfNodeDynCast<BfExpression>(argValues[argIdx].mExpression);
  4466. if (expr != NULL)
  4467. argValue = mModule->CreateValueFromExpression(expr);
  4468. }
  4469. }
  4470. argIdx++;
  4471. }
  4472. mModule->AssertErrorState();
  4473. return mModule->GetDefaultTypedValue(returnType, false, BfDefaultValueKind_Addr);
  4474. }
  4475. prevBindResult.Restore();
  4476. if (!methodDef->mIsStatic)
  4477. {
  4478. if ((methodInstance->GetOwner()->IsInterface()) && (!target.mType->IsGenericParam()) && (!target.mType->IsConcreteInterfaceType()))
  4479. {
  4480. if (methodInstance->mVirtualTableIdx == -1)
  4481. {
  4482. mModule->PopulateType(methodInstance->GetOwner(), BfPopulateType_DataAndMethods);
  4483. }
  4484. if (methodInstance->mVirtualTableIdx == -1)
  4485. {
  4486. if (methodInstance->mMethodDef->mIsConcrete)
  4487. {
  4488. 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);
  4489. }
  4490. else if (methodInstance->HasSelf())
  4491. {
  4492. 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);
  4493. }
  4494. else
  4495. {
  4496. if ((bypassVirtual) && (mModule->mCurTypeInstance->IsInterface()))
  4497. {
  4498. // Allow a base call to be defined
  4499. }
  4500. else if ((!mModule->mCurMethodInstance->mIsUnspecialized))
  4501. {
  4502. // Compiler error?
  4503. mModule->Fail(StrFormat("Unable to dynamically dispatch '%s'", mModule->MethodToString(methodInstance).c_str()), targetSrc);
  4504. }
  4505. //BF_ASSERT(mModule->mCurMethodInstance->mIsUnspecialized);
  4506. }
  4507. if (mFunctionBindResult != NULL)
  4508. {
  4509. mFunctionBindResult->mMethodInstance = methodInstance;
  4510. mFunctionBindResult->mTarget = target;
  4511. mFunctionBindResult->mFunc = moduleMethodInstance.mFunc;
  4512. for (auto arg : irArgs)
  4513. mFunctionBindResult->mIRArgs.push_back(arg);
  4514. }
  4515. return mModule->GetDefaultTypedValue(returnType);
  4516. }
  4517. }
  4518. }
  4519. else
  4520. {
  4521. //BF_ASSERT(!methodInstance->GetOwner()->IsInterface());
  4522. }
  4523. if (target.mType != NULL)
  4524. {
  4525. // When we call a method from a static ctor, that method could access static fields so we need to make sure
  4526. // the type has been initialized
  4527. auto targetTypeInst = target.mType->ToTypeInstance();
  4528. if (targetTypeInst != NULL)
  4529. mModule->CheckStaticAccess(targetTypeInst);
  4530. }
  4531. auto func = moduleMethodInstance.mFunc;
  4532. BfTypedValue result = CreateCall(methodInstance, func, bypassVirtual, irArgs);
  4533. if ((result.mType != NULL) && (result.mType->IsVar()) && (mModule->mCompiler->mIsResolveOnly))
  4534. mModule->Fail("Method return type reference failed to resolve", targetSrc);
  4535. return result;
  4536. }
  4537. BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBoundExpression* methodBoundExpr, BfTypedValue target, BfTypeInstance* targetType, BfResolvedArgs& argValues, bool callCtorBodyOnly, bool allowAppendAlloc, BfTypedValue* appendIndexValue)
  4538. {
  4539. // Temporarily disable so we don't capture calls in params
  4540. SetAndRestoreValue<BfFunctionBindResult*> prevBindResult(mFunctionBindResult, NULL);
  4541. static int sCtorCount = 0;
  4542. sCtorCount++;
  4543. BfMethodMatcher methodMatcher(targetSrc, mModule, "", argValues.mResolvedArgs, NULL);
  4544. BfTypeVector typeGenericArguments;
  4545. auto curTypeInst = targetType;
  4546. auto curTypeDef = targetType->mTypeDef;
  4547. BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None;
  4548. auto activeTypeDef = mModule->GetActiveTypeDef();
  4549. bool isFailurePass = false;
  4550. for (int pass = 0; pass < 2; pass++)
  4551. {
  4552. isFailurePass = pass == 1;
  4553. curTypeDef->PopulateMemberSets();
  4554. BfMethodDef* nextMethodDef = NULL;
  4555. BfMemberSetEntry* entry;
  4556. if (curTypeDef->mMethodSet.TryGetWith(String("__BfCtor"), &entry))
  4557. nextMethodDef = (BfMethodDef*)entry->mMemberDef;
  4558. while (nextMethodDef != NULL)
  4559. {
  4560. auto checkMethod = nextMethodDef;
  4561. nextMethodDef = nextMethodDef->mNextWithSameName;
  4562. if ((isFailurePass) && (checkMethod->mMethodDeclaration == NULL))
  4563. continue; // Don't match private default ctor if there's a user-defined one
  4564. if (checkMethod->mIsStatic)
  4565. continue;
  4566. if ((!curTypeInst->IsTypeMemberIncluded(checkMethod->mDeclaringType, activeTypeDef, mModule)) ||
  4567. (!curTypeInst->IsTypeMemberAccessible(checkMethod->mDeclaringType, activeTypeDef)))
  4568. continue;
  4569. auto checkProt = checkMethod->mProtection;
  4570. if (!isFailurePass)
  4571. {
  4572. if (callCtorBodyOnly)
  4573. {
  4574. // We're calling the base class's ctor from a derived class
  4575. if (checkProt == BfProtection_Private)
  4576. continue;
  4577. }
  4578. else
  4579. {
  4580. if (checkProt == BfProtection_Protected) // Treat protected constructors as private
  4581. checkProt = BfProtection_Private;
  4582. if (!mModule->CheckProtection(protectionCheckFlags, curTypeInst, checkProt, curTypeInst))
  4583. continue;
  4584. }
  4585. }
  4586. methodMatcher.CheckMethod(curTypeInst, checkMethod, isFailurePass);
  4587. }
  4588. if ((methodMatcher.mBestMethodDef != NULL) || (methodMatcher.mBackupMethodDef != NULL))
  4589. break;
  4590. }
  4591. if (methodMatcher.mBestMethodDef == NULL)
  4592. methodMatcher.mBestMethodDef = methodMatcher.mBackupMethodDef;
  4593. if (methodMatcher.mBestMethodDef == NULL)
  4594. {
  4595. mModule->Fail("No constructor available", targetSrc);
  4596. return BfTypedValue();
  4597. }
  4598. auto methodDef = methodMatcher.mBestMethodDef;
  4599. if (mModule->mCompiler->mResolvePassData != NULL)
  4600. mModule->mCompiler->mResolvePassData->HandleMethodReference(targetSrc, curTypeInst->mTypeDef, methodDef);
  4601. BfAutoComplete* autoComplete = GetAutoComplete();
  4602. if (autoComplete != NULL)
  4603. {
  4604. BfTypeInstance* resolvedTypeInstance = target.mType->ToTypeInstance();
  4605. auto ctorDecl = BfNodeDynCast<BfConstructorDeclaration>(methodDef->mMethodDeclaration);
  4606. if ((autoComplete->mIsGetDefinition) && (autoComplete->IsAutocompleteNode(targetSrc)) && (!BfNodeIsA<BfDelegateBindExpression>(targetSrc)))
  4607. {
  4608. if ((autoComplete->mDefMethod == NULL) && (autoComplete->mDefField == NULL) &&
  4609. (autoComplete->mDefProp == NULL)
  4610. && ((autoComplete->mDefType == NULL) || (autoComplete->mDefType == resolvedTypeInstance->mTypeDef)))
  4611. {
  4612. // Do we need to do this mDefType setting? If we do, then make sure we only get the element type of generics and such
  4613. //autoComplete->mDefType = resolvedTypeInstance->mTypeDef;
  4614. if (ctorDecl != NULL)
  4615. autoComplete->SetDefinitionLocation(ctorDecl->mThisToken, true);
  4616. else if (resolvedTypeInstance->mTypeDef->mTypeDeclaration != NULL)
  4617. autoComplete->SetDefinitionLocation(resolvedTypeInstance->mTypeDef->mTypeDeclaration->mNameNode, true);
  4618. }
  4619. }
  4620. }
  4621. // There should always be a constructor
  4622. BF_ASSERT(methodMatcher.mBestMethodDef != NULL);
  4623. auto moduleMethodInstance = mModule->GetMethodInstance(methodMatcher.mBestMethodTypeInstance, methodMatcher.mBestMethodDef, methodMatcher.mBestMethodGenericArguments);
  4624. BfConstructorDeclaration* ctorDecl = (BfConstructorDeclaration*)methodMatcher.mBestMethodDef->mMethodDeclaration;
  4625. if ((methodMatcher.mBestMethodDef->mHasAppend) && (targetType->IsObject()))
  4626. {
  4627. if (!allowAppendAlloc)
  4628. {
  4629. if (mModule->mCurMethodInstance->mMethodDef->mMethodDeclaration == NULL)
  4630. mModule->Fail("Constructors with append allocations cannot be called from a default constructor. Considering adding an explicit default constructor with the [AllowAppend] specifier.", targetSrc);
  4631. else
  4632. mModule->Fail("Constructors with append allocations cannot be called from a constructor without [AllowAppend] specified.", targetSrc);
  4633. }
  4634. else
  4635. {
  4636. BfResolvedArg resolvedArg;
  4637. if (appendIndexValue != NULL)
  4638. {
  4639. resolvedArg.mTypedValue = *appendIndexValue;
  4640. }
  4641. else
  4642. {
  4643. auto intPtrType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  4644. auto intPtrRefType = mModule->CreateRefType(intPtrType);
  4645. if (target.mValue.IsFake())
  4646. {
  4647. resolvedArg.mTypedValue = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), intPtrType);
  4648. }
  4649. else
  4650. {
  4651. // auto thisVal = target;
  4652. // BfIRValue intPtrVal = mModule->CreateAlloca(intPtrType);
  4653. // auto intPtrThisVal = mModule->mBfIRBuilder->CreatePtrToInt(thisVal.mValue, (intPtrType->mSize == 4) ? BfTypeCode_Int32 : BfTypeCode_Int64);
  4654. // auto curValPtr = mModule->mBfIRBuilder->CreateAdd(intPtrThisVal, mModule->GetConstValue(targetType->mInstSize, intPtrType));
  4655. // mModule->mBfIRBuilder->CreateStore(curValPtr, intPtrVal);
  4656. // resolvedArg.mTypedValue = BfTypedValue(intPtrVal, intPtrRefType);
  4657. BF_FATAL("Bad");
  4658. }
  4659. }
  4660. methodMatcher.mArguments.Insert(0, resolvedArg);
  4661. }
  4662. }
  4663. if (isFailurePass)
  4664. mModule->Fail(StrFormat("'%s' is inaccessible due to its protection level", mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str()), targetSrc);
  4665. prevBindResult.Restore();
  4666. return CreateCall(methodMatcher.mTargetSrc, target, BfTypedValue(), methodMatcher.mBestMethodDef, moduleMethodInstance, false, methodMatcher.mArguments);
  4667. }
  4668. static int sInvocationIdx = 0;
  4669. BfTypedValue BfExprEvaluator::ResolveArgValue(BfResolvedArg& resolvedArg, BfType* wantType, BfTypedValue* receivingValue, BfParamKind paramKind)
  4670. {
  4671. BfTypedValue argValue = resolvedArg.mTypedValue;
  4672. if ((resolvedArg.mArgFlags & (BfArgFlag_DelegateBindAttempt | BfArgFlag_LambdaBindAttempt | BfArgFlag_UnqualifiedDotAttempt | BfArgFlag_DeferredEval)) != 0)
  4673. {
  4674. if ((!argValue) || (argValue.mValue.IsFake()) || (resolvedArg.mWantsRecalc))
  4675. {
  4676. resolvedArg.mWantsRecalc = false;
  4677. auto expr = BfNodeDynCast<BfExpression>(resolvedArg.mExpression);
  4678. if (expr != NULL)
  4679. {
  4680. BfExprEvaluator exprEvaluator(mModule);
  4681. exprEvaluator.mReceivingValue = receivingValue;
  4682. BfEvalExprFlags flags = BfEvalExprFlags_NoCast;
  4683. if ((paramKind == BfParamKind_Params) || (paramKind == BfParamKind_DelegateParam))
  4684. flags = (BfEvalExprFlags)(flags | BfEvalExprFlags_AllowParamsExpr);
  4685. // if ((mModule->mCurMethodInstance->mHadGenericDelegateParams) && (!mModule->mCurMethodInstance->mIsUnspecialized))
  4686. // flags = (BfEvalExprFlags)(flags | BfEvalExprFlags_AllowParamsExpr);
  4687. argValue = mModule->CreateValueFromExpression(exprEvaluator, expr, wantType, flags);
  4688. // if ((resolvedArg.mArgFlags & BfArgFlag_ParamsExpr) != 0)
  4689. // {
  4690. // if ((mModule->mCurMethodState != NULL) && (exprEvaluator.mResultLocalVar != NULL) && (exprEvaluator.mResultLocalVarRefNode != NULL))
  4691. // {
  4692. // auto localVar = exprEvaluator.mResultLocalVar;
  4693. // int fieldIdx = mResultLocalVarField - 1;
  4694. // auto methodState = mModule->mCurMethodState->GetMethodStateForLocal(localVar);
  4695. // if (localVar->mCompositeCount >= 0)
  4696. // {
  4697. // for (int compositeIdx = 0; compositeIdx < localVar->mCompositeCount; compositeIdx++)
  4698. // {
  4699. // BfResolvedArg compositeResolvedArg;
  4700. // auto compositeLocalVar = methodState->mLocals[localVar->mLocalVarIdx + compositeIdx + 1];
  4701. // auto argValue = exprEvaluator.LoadLocal(compositeLocalVar);
  4702. // if (argValue)
  4703. // {
  4704. // if (argValue.mType->IsRef())
  4705. // argValue.mKind = BfTypedValueKind_Value;
  4706. // else if (!argValue.mType->IsStruct())
  4707. // argValue = mModule->LoadValue(argValue, NULL, exprEvaluator.mIsVolatileReference);
  4708. // }
  4709. // resolvedArg.mTypedValue = argValue;
  4710. // resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_FromParamComposite);
  4711. // return resolvedArg.mTypedValue;
  4712. // }
  4713. // }
  4714. // }
  4715. // }
  4716. if ((argValue) && (argValue.mType != wantType))
  4717. {
  4718. if ((mDeferScopeAlloc != NULL) && (wantType == mModule->mContext->mBfObjectType))
  4719. {
  4720. BfAllocTarget allocTarget(mDeferScopeAlloc);
  4721. argValue = mModule->BoxValue(expr, argValue, wantType, allocTarget);
  4722. }
  4723. else
  4724. argValue = mModule->Cast(expr, argValue, wantType);
  4725. }
  4726. }
  4727. }
  4728. }
  4729. else if ((resolvedArg.mArgFlags & (BfArgFlag_DeferredValue)) != 0)
  4730. {
  4731. // We should have already had an error on the first call
  4732. SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, mModule->mHadBuildError);
  4733. auto expr = BfNodeDynCast<BfExpression>(resolvedArg.mExpression);
  4734. BF_ASSERT(expr != NULL);
  4735. argValue = mModule->CreateValueFromExpression(expr, wantType, (BfEvalExprFlags)(BfEvalExprFlags_NoCast | BfEvalExprFlags_AllowRefExpr | BfEvalExprFlags_AllowOutExpr));
  4736. if (argValue)
  4737. argValue = mModule->Cast(expr, argValue, wantType);
  4738. }
  4739. else if ((resolvedArg.mArgFlags & (BfArgFlag_UntypedDefault)) != 0)
  4740. {
  4741. argValue = mModule->GetDefaultTypedValue(wantType);
  4742. }
  4743. else if ((resolvedArg.mArgFlags & (BfArgFlag_VariableDeclaration)) != 0)
  4744. {
  4745. auto variableDeclaration = BfNodeDynCast<BfVariableDeclaration>(resolvedArg.mExpression);
  4746. auto variableType = wantType;
  4747. bool isLet = variableDeclaration->mTypeRef->IsExact<BfLetTypeReference>();
  4748. bool isVar = variableDeclaration->mTypeRef->IsExact<BfVarTypeReference>();
  4749. if ((!isLet) && (!isVar))
  4750. {
  4751. mModule->Fail("Only 'ref' or 'var' variables can be declared in method arguments", variableDeclaration);
  4752. auto autoComplete = GetAutoComplete();
  4753. if (autoComplete != NULL)
  4754. autoComplete->CheckTypeRef(variableDeclaration->mTypeRef, true, true);
  4755. }
  4756. if (wantType->IsRef())
  4757. {
  4758. auto refType = (BfRefType*)wantType;
  4759. variableType = refType->mElementType;
  4760. }
  4761. if (variableDeclaration->mInitializer != NULL)
  4762. {
  4763. mModule->Fail("Initializers cannot be used when declaring variables for 'out' parameters", variableDeclaration->mEqualsNode);
  4764. mModule->CreateValueFromExpression(variableDeclaration->mInitializer, variableType, BfEvalExprFlags_NoCast);
  4765. }
  4766. if (variableDeclaration->mNameNode == NULL)
  4767. return argValue;
  4768. BfLocalVariable* localVar = new BfLocalVariable();
  4769. localVar->mName = variableDeclaration->mNameNode->ToString();
  4770. localVar->mNameNode = BfNodeDynCast<BfIdentifierNode>(variableDeclaration->mNameNode);
  4771. localVar->mResolvedType = variableType;
  4772. if (!variableType->IsValuelessType())
  4773. localVar->mAddr = mModule->CreateAlloca(variableType);
  4774. localVar->mIsReadOnly = isLet;
  4775. localVar->mReadFromId = 0;
  4776. localVar->mWrittenToId = 0;
  4777. localVar->mIsAssigned = true;
  4778. mModule->CheckVariableDef(localVar);
  4779. localVar->Init();
  4780. mModule->AddLocalVariableDef(localVar, true);
  4781. CheckVariableDeclaration(resolvedArg.mExpression, false, false, false);
  4782. argValue = BfTypedValue(localVar->mAddr, mModule->CreateRefType(variableType, BfRefType::RefKind_Out));
  4783. //argValue = mModule->GetDefaultTypedValue(wantType);
  4784. }
  4785. return argValue;
  4786. }
  4787. BfTypedValue BfExprEvaluator::CheckEnumCreation(BfAstNode* targetSrc, BfTypeInstance* enumType, const StringImpl& caseName, BfResolvedArgs& argValues)
  4788. {
  4789. auto activeTypeDef = mModule->GetActiveTypeDef();
  4790. mModule->mBfIRBuilder->PopulateType(enumType);
  4791. auto resolvePassData = mModule->mCompiler->mResolvePassData;
  4792. // if (resolvePassData != NULL)
  4793. // {
  4794. // if (mModule->mParentNodeEntry != NULL)
  4795. // {
  4796. // if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(mModule->mParentNodeEntry->mNode))
  4797. // {
  4798. // if (auto memberRefExpr = BfNodeDynCast<BfMemberReferenceExpression>(invocationExpr->mTarget))
  4799. // {
  4800. // BfAstNode* dotNode = memberRefExpr->mDotToken;
  4801. // BfAstNode* nameNode = targetSrc;
  4802. // String filter;
  4803. // auto autoComplete = resolvePassData->mAutoComplete;
  4804. // if ((autoComplete != NULL) && (autoComplete->InitAutocomplete(dotNode, nameNode, filter)))
  4805. // autoComplete->AddEnumTypeMembers(enumType, caseName, false, enumType == mModule->mCurTypeInstance);
  4806. // }
  4807. // }
  4808. // }
  4809. // }
  4810. for (int fieldIdx = 0; fieldIdx < (int)enumType->mFieldInstances.size(); fieldIdx++)
  4811. {
  4812. auto fieldInstance = &enumType->mFieldInstances[fieldIdx];
  4813. auto fieldDef = fieldInstance->GetFieldDef();
  4814. if (fieldDef == NULL)
  4815. continue;
  4816. if ((fieldInstance->mIsEnumPayloadCase) && (fieldDef->mName == caseName))
  4817. {
  4818. if ((!enumType->IsTypeMemberIncluded(fieldDef->mDeclaringType, activeTypeDef, mModule)) ||
  4819. (!enumType->IsTypeMemberAccessible(fieldDef->mDeclaringType, activeTypeDef)))
  4820. continue;
  4821. auto autoComplete = GetAutoComplete();
  4822. if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo))
  4823. {
  4824. BfAutoComplete::MethodMatchEntry methodMatchEntry;
  4825. methodMatchEntry.mPayloadEnumField = fieldInstance;
  4826. methodMatchEntry.mTypeInstance = enumType;
  4827. methodMatchEntry.mCurMethodInstance = mModule->mCurMethodInstance;
  4828. autoComplete->mMethodMatchInfo->mInstanceList.push_back(methodMatchEntry);
  4829. }
  4830. if (resolvePassData != NULL)
  4831. {
  4832. BfAstNode* nameNode = targetSrc;
  4833. if (resolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Field)
  4834. resolvePassData->HandleFieldReference(nameNode, enumType->mTypeDef, fieldDef);
  4835. }
  4836. BfIRValue enumValue;
  4837. BfTypedValue result;
  4838. if ((mReceivingValue != NULL) && (mReceivingValue->mType == enumType) && (mReceivingValue->IsAddr()))
  4839. {
  4840. result = *mReceivingValue;
  4841. mReceivingValue = NULL;
  4842. enumValue = result.mValue;
  4843. }
  4844. else
  4845. {
  4846. mResultIsTempComposite = true;
  4847. enumValue = mModule->CreateAlloca(enumType);
  4848. result = BfTypedValue(enumValue, fieldInstance->mOwner, BfTypedValueKind_TempAddr);
  4849. }
  4850. BF_ASSERT(fieldInstance->mResolvedType->IsTuple());
  4851. auto tupleType = (BfTupleType*)fieldInstance->mResolvedType;
  4852. mModule->mBfIRBuilder->PopulateType(tupleType);
  4853. BfIRValue fieldPtr;
  4854. BfIRValue tuplePtr;
  4855. if (!tupleType->IsValuelessType())
  4856. {
  4857. fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(enumValue, 0, 1);
  4858. auto tuplePtrType = mModule->CreatePointerType(tupleType);
  4859. auto mappedPtrType = mModule->mBfIRBuilder->MapType(tuplePtrType);
  4860. tuplePtr = mModule->mBfIRBuilder->CreateBitCast(fieldPtr, mappedPtrType);
  4861. }
  4862. for (int tupleFieldIdx = 0; tupleFieldIdx < (int)tupleType->mFieldInstances.size(); tupleFieldIdx++)
  4863. {
  4864. auto tupleFieldInstance = &tupleType->mFieldInstances[tupleFieldIdx];
  4865. auto resolvedFieldType = tupleFieldInstance->GetResolvedType();
  4866. if (tupleFieldIdx >= argValues.mResolvedArgs.size())
  4867. {
  4868. BfAstNode* refNode = targetSrc;
  4869. BfAstNode* prevNode = NULL;
  4870. if (mModule->mParentNodeEntry != NULL)
  4871. {
  4872. if (auto invokeExpr = BfNodeDynCast<BfInvocationExpression>(mModule->mParentNodeEntry->mNode))
  4873. {
  4874. if (invokeExpr->mCloseParen != NULL)
  4875. refNode = invokeExpr->mCloseParen;
  4876. }
  4877. }
  4878. BfError* error = mModule->Fail(StrFormat("Not enough parameters specified, expected %d more.", tupleType->mFieldInstances.size() - (int)argValues.mArguments->size()), refNode);
  4879. if (error != NULL)
  4880. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See enum declaration"), fieldDef->mFieldDeclaration);
  4881. break;
  4882. }
  4883. BfTypedValue receivingValue;
  4884. BfIRValue tupleFieldPtr;
  4885. if (tuplePtr)
  4886. {
  4887. tupleFieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(tuplePtr, 0, tupleFieldInstance->mDataIdx);
  4888. receivingValue = BfTypedValue(tupleFieldPtr, tupleFieldInstance->mResolvedType, true);
  4889. }
  4890. auto argValue = ResolveArgValue(argValues.mResolvedArgs[tupleFieldIdx], resolvedFieldType, &receivingValue);
  4891. // Used receiving value?
  4892. if (argValue.mValue == receivingValue.mValue)
  4893. continue;
  4894. if ((!argValue) || (argValue.IsValuelessType()))
  4895. continue;
  4896. argValue = mModule->AggregateSplat(argValue);
  4897. argValues.mResolvedArgs[tupleFieldIdx].mExpectedType = resolvedFieldType;
  4898. if ((argValues.mResolvedArgs[tupleFieldIdx].mArgFlags & (BfArgFlag_DelegateBindAttempt | BfArgFlag_LambdaBindAttempt | BfArgFlag_UnqualifiedDotAttempt)) != 0)
  4899. {
  4900. auto expr = BfNodeDynCast<BfExpression>(argValues.mResolvedArgs[tupleFieldIdx].mExpression);
  4901. BF_ASSERT(expr != NULL);
  4902. argValue = mModule->CreateValueFromExpression(expr, resolvedFieldType);
  4903. }
  4904. if (argValue)
  4905. {
  4906. // argValue can have a value even if tuplePtr does not have a value. This can happen if we are assigning to a (void) tuple,
  4907. // but we have a value that needs to be attempted to be casted to void
  4908. argValue = mModule->Cast(argValues.mResolvedArgs[tupleFieldIdx].mExpression, argValue, resolvedFieldType);
  4909. if (tupleFieldPtr)
  4910. {
  4911. argValue = mModule->LoadValue(argValue);
  4912. if (argValue)
  4913. mModule->mBfIRBuilder->CreateAlignedStore(argValue.mValue, tupleFieldPtr, resolvedFieldType->mAlign);
  4914. }
  4915. }
  4916. }
  4917. if ((intptr)argValues.mResolvedArgs.size() > tupleType->mFieldInstances.size())
  4918. {
  4919. BfAstNode* errorRef = argValues.mResolvedArgs[tupleType->mFieldInstances.size()].mExpression;
  4920. if (errorRef == NULL)
  4921. errorRef = targetSrc;
  4922. BfError* error = mModule->Fail(StrFormat("Too many arguments, expected %d fewer.", argValues.mResolvedArgs.size() - tupleType->mFieldInstances.size()), errorRef);
  4923. if (error != NULL)
  4924. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See enum declaration"), fieldDef->mFieldDeclaration);
  4925. }
  4926. //auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(enumValue, 0, 2);
  4927. auto dscrType = enumType->GetDiscriminatorType();
  4928. auto dscrField = &enumType->mFieldInstances.back();
  4929. int tagIdx = -fieldInstance->mDataIdx - 1;
  4930. auto dscFieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(enumValue, 0, dscrField->mDataIdx);
  4931. mModule->mBfIRBuilder->CreateAlignedStore(mModule->mBfIRBuilder->CreateConst(dscrType->mTypeDef->mTypeCode, tagIdx), dscFieldPtr, 4);
  4932. return result;
  4933. }
  4934. }
  4935. return BfTypedValue();
  4936. }
  4937. BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExpression* methodBoundExpr, BfTypedValue target, bool allowImplicitThis, bool bypassVirtual, const StringImpl& methodName,
  4938. BfResolvedArgs& argValues, BfSizedArray<ASTREF(BfTypeReference*)>* methodGenericArguments, BfCheckedKind checkedKind)
  4939. {
  4940. BP_ZONE("MatchMethod");
  4941. if (bypassVirtual)
  4942. {
  4943. // "bypassVirtual" means that we know for sure that the target is EXACTLY the specified target type,
  4944. // not derived from (or implementing) the target type. This cannot apply to interfaces.
  4945. BF_ASSERT(!target.mType->IsInterface());
  4946. }
  4947. auto origTarget = target;
  4948. if (mFunctionBindResult != NULL)
  4949. {
  4950. BF_ASSERT(!mFunctionBindResult->mOrigTarget);
  4951. mFunctionBindResult->mOrigTarget = origTarget;
  4952. }
  4953. if (target)
  4954. {
  4955. if ((!target.mType->IsGenericParam()) && (!target.IsSplat()) && (!target.mType->IsVar()))
  4956. target = MakeCallableTarget(targetSrc, target);
  4957. }
  4958. // static int sCallIdx = 0;
  4959. // if (!mModule->mCompiler->mIsResolveOnly)
  4960. // sCallIdx++;
  4961. // int callIdx = sCallIdx;
  4962. // if (callIdx == 118)
  4963. // {
  4964. // NOP;
  4965. // }
  4966. // Temporarily disable so we don't capture calls in params
  4967. SetAndRestoreValue<BfFunctionBindResult*> prevBindResult(mFunctionBindResult, NULL);
  4968. sInvocationIdx++;
  4969. bool wantCtor = methodName.IsEmpty();
  4970. BfAutoComplete::MethodMatchInfo* restoreCapturingMethodMatchInfo = NULL;
  4971. auto autoComplete = GetAutoComplete();
  4972. if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo))
  4973. {
  4974. if ((!targetSrc->IsFromParser(mModule->mCompiler->mResolvePassData->mParser)) ||
  4975. ((autoComplete->mMethodMatchInfo->mInvocationSrcIdx != -1) && (autoComplete->mMethodMatchInfo->mInvocationSrcIdx != targetSrc->GetSrcStart())))
  4976. {
  4977. autoComplete->mIsCapturingMethodMatchInfo = false;
  4978. restoreCapturingMethodMatchInfo = autoComplete->mMethodMatchInfo;
  4979. }
  4980. }
  4981. OnScopeExit doRestoreAutocomplete([&]()
  4982. {
  4983. if ((restoreCapturingMethodMatchInfo != NULL) && (autoComplete->mMethodMatchInfo == restoreCapturingMethodMatchInfo))
  4984. autoComplete->mIsCapturingMethodMatchInfo = true;
  4985. });
  4986. /*if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo) && (autoComplete->mMethodMatchInfo->mInstanceList.size() != 0))
  4987. autoComplete->mIsCapturingMethodMatchInfo = false;*/
  4988. bool isUnboundCall = false;
  4989. if (target.mType != NULL)
  4990. {
  4991. if (target.mType->IsGenericParam())
  4992. {
  4993. auto genericParamTarget = (BfGenericParamType*) target.mType;
  4994. auto genericParamInstance = mModule->GetGenericParamInstance(genericParamTarget);
  4995. isUnboundCall = (genericParamInstance->mGenericParamFlags & BfGenericParamFlag_Var) != 0;
  4996. if (isUnboundCall)
  4997. {
  4998. if (mModule->mCurMethodInstance->mIsUnspecialized)
  4999. {
  5000. auto varType = mModule->GetPrimitiveType(BfTypeCode_Var);
  5001. target.mType = varType;
  5002. }
  5003. }
  5004. }
  5005. else if (target.mType->IsVar())
  5006. isUnboundCall = true;
  5007. }
  5008. /*if (mPrefixedAttributeState != NULL)
  5009. {
  5010. auto customAttr = mPrefixedAttributeState->mCustomAttributes->Get(mModule->mCompiler->mUnboundAttributeTypeDef);
  5011. if (customAttr != NULL)
  5012. {
  5013. if (!mModule->IsInGeneric())
  5014. {
  5015. mModule->Fail("'Unbound' can only be used within generics");
  5016. }
  5017. mPrefixedAttributeState->mUsed = true;
  5018. isUnboundCall = true;
  5019. }
  5020. }*/
  5021. if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL))
  5022. {
  5023. auto customAttr = mModule->mAttributeState->mCustomAttributes->Get(mModule->mCompiler->mUnboundAttributeTypeDef);
  5024. if (customAttr != NULL)
  5025. {
  5026. if (!mModule->IsInGeneric())
  5027. {
  5028. mModule->Fail("'Unbound' can only be used within generics");
  5029. }
  5030. mModule->mAttributeState->mUsed = true;
  5031. isUnboundCall = true;
  5032. }
  5033. }
  5034. if (isUnboundCall)
  5035. {
  5036. if (mModule->mCurMethodInstance->mIsUnspecialized)
  5037. {
  5038. auto varType = mModule->GetPrimitiveType(BfTypeCode_Var);
  5039. for (int argIdx = 0; argIdx < (int)argValues.mResolvedArgs.size(); argIdx++)
  5040. {
  5041. if ((argValues.mResolvedArgs[argIdx].mArgFlags & BfArgFlag_DeferredEval) != 0)
  5042. {
  5043. mModule->CreateValueFromExpression((*argValues.mArguments)[argIdx], varType);
  5044. }
  5045. }
  5046. return BfTypedValue(mModule->GetDefaultValue(varType), varType);
  5047. }
  5048. }
  5049. SetAndRestoreValue<bool> prevNoBind(mNoBind, mNoBind || isUnboundCall);
  5050. auto targetType = target.mType;
  5051. BfTypeDef* curTypeDef = NULL;
  5052. BfTypeInstance* targetTypeInst = NULL;
  5053. bool checkNonStatic = true;
  5054. if (target)
  5055. {
  5056. if (targetType->IsVar())
  5057. return mModule->GetDefaultTypedValue(targetType);
  5058. targetTypeInst = targetType->ToTypeInstance();
  5059. if (targetTypeInst != NULL)
  5060. curTypeDef = targetTypeInst->mTypeDef;
  5061. }
  5062. else if (targetType != NULL) // Static targeted
  5063. {
  5064. if (targetType->IsWrappableType())
  5065. {
  5066. targetTypeInst = mModule->GetWrappedStructType(targetType);
  5067. }
  5068. else if (targetType->IsGenericParam())
  5069. {
  5070. auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)targetType);
  5071. if (genericParamInstance->mTypeConstraint != NULL)
  5072. targetTypeInst = genericParamInstance->mTypeConstraint->ToTypeInstance();
  5073. if (genericParamInstance->mGenericParamFlags & BfGenericParamFlag_Var)
  5074. {
  5075. auto varType = mModule->GetPrimitiveType(BfTypeCode_Var);
  5076. return BfTypedValue(mModule->GetDefaultValue(varType), varType);
  5077. }
  5078. }
  5079. else
  5080. targetTypeInst = targetType->ToTypeInstance();
  5081. if (targetTypeInst == NULL)
  5082. {
  5083. //mModule->Fail("No static methods available", targetSrc);
  5084. //return BfTypedValue();
  5085. }
  5086. else
  5087. {
  5088. curTypeDef = targetTypeInst->mTypeDef;
  5089. checkNonStatic = false;
  5090. }
  5091. }
  5092. else // Current scopeData
  5093. {
  5094. if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsForeignMethodDef) && (mModule->mCurMethodInstance->mMethodInfoEx->mForeignType->IsInterface()))
  5095. {
  5096. targetTypeInst = mModule->mCurMethodInstance->mMethodInfoEx->mForeignType;
  5097. curTypeDef = targetTypeInst->mTypeDef;
  5098. checkNonStatic = true;
  5099. target = mModule->GetThis();
  5100. //target.mType = targetTypeInst;
  5101. }
  5102. else
  5103. {
  5104. curTypeDef = mModule->mCurTypeInstance->mTypeDef;
  5105. targetTypeInst = mModule->mCurTypeInstance;
  5106. if (mModule->mCurMethodState == NULL)
  5107. {
  5108. checkNonStatic = false;
  5109. }
  5110. else if (mModule->mCurMethodState->mTempKind != BfMethodState::TempKind_None)
  5111. {
  5112. checkNonStatic = mModule->mCurMethodState->mTempKind == BfMethodState::TempKind_NonStatic;
  5113. }
  5114. else
  5115. checkNonStatic = !mModule->mCurMethodInstance->mMethodDef->mIsStatic;
  5116. }
  5117. }
  5118. bool isIndirectMethodCall = false;
  5119. BfType* lookupType = targetType;
  5120. BfTypeInstance* lookupTypeInst = targetTypeInst;
  5121. if (targetType != NULL)
  5122. {
  5123. lookupType = BindGenericType(targetSrc, targetType);
  5124. if (lookupType->IsGenericParam())
  5125. lookupTypeInst = NULL;
  5126. }
  5127. BfMethodDef* methodDef = NULL;
  5128. BfTypeVector checkMethodGenericArguments;
  5129. BfTypeInstance* curTypeInst = targetTypeInst;
  5130. BfMethodMatcher methodMatcher(targetSrc, mModule, methodName, argValues.mResolvedArgs, methodGenericArguments);
  5131. methodMatcher.mCheckedKind = checkedKind;
  5132. methodMatcher.mAllowImplicitThis = allowImplicitThis;
  5133. methodMatcher.mAllowStatic = !target.mValue;
  5134. methodMatcher.mAllowNonStatic = !methodMatcher.mAllowStatic;
  5135. if (allowImplicitThis)
  5136. {
  5137. if (mModule->mCurMethodState == NULL)
  5138. {
  5139. methodMatcher.mAllowStatic = true;
  5140. methodMatcher.mAllowNonStatic = false;
  5141. }
  5142. else if (mModule->mCurMethodState->mTempKind != BfMethodState::TempKind_None)
  5143. {
  5144. methodMatcher.mAllowNonStatic = mModule->mCurMethodState->mTempKind == BfMethodState::TempKind_NonStatic;
  5145. methodMatcher.mAllowStatic = true;
  5146. }
  5147. else
  5148. {
  5149. if (!mModule->mCurMethodInstance->mMethodDef->mIsStatic)
  5150. methodMatcher.mAllowNonStatic = true;
  5151. methodMatcher.mAllowStatic = true;
  5152. if (mModule->mCurMethodInstance->mMethodDef->mIsLocalMethod)
  5153. {
  5154. auto rootMethodState = mModule->mCurMethodState->GetRootMethodState();
  5155. methodMatcher.mAllowNonStatic = !rootMethodState->mMethodInstance->mMethodDef->mIsStatic;
  5156. }
  5157. }
  5158. }
  5159. if (methodName == BF_METHODNAME_CALCAPPEND)
  5160. methodMatcher.mMethodType = BfMethodType_CtorCalcAppend;
  5161. BF_ASSERT(methodMatcher.mBestMethodDef == NULL);
  5162. BfLocalMethod* matchedLocalMethod = NULL;
  5163. if (target.mType == NULL)
  5164. {
  5165. CheckLocalMethods(targetSrc, curTypeInst, methodName, methodMatcher, BfMethodType_Normal);
  5166. if (methodMatcher.mBestMethodDef == NULL)
  5167. methodMatcher.mBestMethodDef = methodMatcher.mBackupMethodDef;
  5168. if (methodMatcher.mBestMethodDef != NULL)
  5169. {
  5170. auto rootMethodState = mModule->mCurMethodState->GetRootMethodState();
  5171. auto methodDef = methodMatcher.mBestMethodDef;
  5172. if (mModule->mCompiler->mResolvePassData != NULL)
  5173. {
  5174. auto identifierNode = BfNodeDynCast<BfIdentifierNode>(targetSrc);
  5175. mModule->mCompiler->mResolvePassData->HandleLocalReference(identifierNode, curTypeInst->mTypeDef, rootMethodState->mMethodInstance->mMethodDef, ~methodDef->mIdx);
  5176. auto autoComplete = GetAutoComplete();
  5177. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(identifierNode)))
  5178. {
  5179. autoComplete->SetDefinitionLocation(methodDef->GetRefNode());
  5180. if (autoComplete->mDefType == NULL)
  5181. {
  5182. autoComplete->mDefMethod = mModule->mCurMethodState->GetRootMethodState()->mMethodInstance->mMethodDef;
  5183. autoComplete->mDefType = curTypeDef;
  5184. autoComplete->mReplaceLocalId = ~methodDef->mIdx;
  5185. }
  5186. }
  5187. if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo))
  5188. {
  5189. BfAutoComplete::MethodMatchEntry methodMatchEntry;
  5190. methodMatchEntry.mMethodDef = methodDef;
  5191. methodMatchEntry.mTypeInstance = mModule->mCurTypeInstance;
  5192. methodMatchEntry.mCurMethodInstance = mModule->mCurMethodInstance;
  5193. autoComplete->mMethodMatchInfo->mInstanceList.push_back(methodMatchEntry);
  5194. }
  5195. }
  5196. if ((mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mCapturing))
  5197. {
  5198. auto methodInstance = mModule->GetRawMethodInstance(methodMatcher.mBestMethodTypeInstance, methodMatcher.mBestMethodDef);
  5199. if (methodInstance->mReturnType == NULL)
  5200. {
  5201. FinishDeferredEvals(argValues.mResolvedArgs);
  5202. // If we are recursive then we won't even have a completed methodInstance yet to look at
  5203. return mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  5204. }
  5205. }
  5206. }
  5207. }
  5208. if (methodMatcher.mBestMethodDef == NULL)
  5209. {
  5210. if (lookupTypeInst == NULL)
  5211. {
  5212. if ((lookupType != NULL) && (lookupType->IsConcreteInterfaceType()))
  5213. {
  5214. auto concreteInterfaceType = (BfConcreteInterfaceType*)lookupType;
  5215. lookupTypeInst = concreteInterfaceType->mInterface;
  5216. }
  5217. else if (isUnboundCall)
  5218. {
  5219. //auto resolvedType = mModule->ResolveGenericType(lookupType);
  5220. }
  5221. else if (lookupType->IsGenericParam())
  5222. {
  5223. auto genericParamTarget = (BfGenericParamType*)lookupType;
  5224. auto genericParamInstance = mModule->GetGenericParamInstance(genericParamTarget);
  5225. if (genericParamInstance->mTypeConstraint != NULL)
  5226. lookupTypeInst = genericParamInstance->mTypeConstraint->ToTypeInstance();
  5227. else
  5228. lookupTypeInst = mModule->mContext->mBfObjectType;
  5229. for (BfType* ifaceInst : genericParamInstance->mInterfaceConstraints)
  5230. {
  5231. if (ifaceInst->IsUnspecializedType())
  5232. ifaceInst = mModule->ResolveType(ifaceInst);
  5233. BfTypeInstance* typeInst = ifaceInst->ToTypeInstance();
  5234. BF_ASSERT(typeInst != NULL);
  5235. if (methodMatcher.CheckType(typeInst, target, false))
  5236. methodMatcher.mSelfType = lookupType;
  5237. }
  5238. }
  5239. }
  5240. if ((lookupTypeInst != NULL) && (!wantCtor))
  5241. {
  5242. methodMatcher.mBypassVirtual = bypassVirtual;
  5243. methodMatcher.CheckType(lookupTypeInst, target, false);
  5244. }
  5245. if ((lookupType != NULL) && (lookupType->IsGenericParam()))
  5246. {
  5247. //lookupType = mModule->ResolveGenericType(lookupType);
  5248. if (!lookupType->IsGenericParam())
  5249. {
  5250. target = MakeCallableTarget(targetSrc, target);
  5251. if (target)
  5252. {
  5253. lookupTypeInst = lookupType->ToTypeInstance();
  5254. }
  5255. }
  5256. }
  5257. }
  5258. bool isFailurePass = false;
  5259. if (methodMatcher.mBestMethodDef == NULL)
  5260. {
  5261. isFailurePass = true;
  5262. if (lookupTypeInst != NULL)
  5263. methodMatcher.CheckType(lookupTypeInst, target, true);
  5264. }
  5265. BfTypedValue staticResult;
  5266. methodMatcher.TryDevirtualizeCall(target, &origTarget, &staticResult);
  5267. if (staticResult)
  5268. return staticResult;
  5269. bypassVirtual |= methodMatcher.mBypassVirtual;
  5270. if (methodMatcher.mBestMethodDef != NULL)
  5271. {
  5272. curTypeInst = methodMatcher.mBestMethodTypeInstance;
  5273. methodDef = methodMatcher.mBestMethodDef;
  5274. }
  5275. if ((methodDef) && (!methodDef->mIsStatic) && (!target) && (allowImplicitThis))
  5276. {
  5277. target = mModule->GetThis();
  5278. }
  5279. // If we call "GetType" on a value type, statically determine the type rather than boxing and then dispatching
  5280. if ((methodDef) && (target) && (curTypeInst == mModule->mContext->mBfObjectType) &&
  5281. (methodDef->mName == "GetType") && (target.mType->IsValueType()))
  5282. {
  5283. BfType* targetType = target.mType;
  5284. if (origTarget)
  5285. targetType = origTarget.mType;
  5286. auto typeType = mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef);
  5287. mModule->AddDependency(targetType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
  5288. return BfTypedValue(mModule->CreateTypeDataRef(targetType), typeType);
  5289. }
  5290. bool skipThis = false;
  5291. // Fail, check for delegate field invocation
  5292. if ((methodDef == NULL) && ((methodGenericArguments == NULL) || (methodGenericArguments->size() == 0)))
  5293. {
  5294. // Check for payload enum initialization first
  5295. BfTypedValue enumResult;
  5296. BfTypeInstance* enumType = NULL;
  5297. if ((!target) && (mModule->mCurTypeInstance->IsPayloadEnum()))
  5298. {
  5299. enumType = mModule->mCurTypeInstance;
  5300. //enumResult = CheckEnumCreation(targetSrc, mModule->mCurTypeInstance, methodName, argValues);
  5301. }
  5302. else if ((!target) && (target.HasType()) && (targetType->IsPayloadEnum()))
  5303. {
  5304. enumType = targetType->ToTypeInstance();
  5305. //enumResult = CheckEnumCreation(targetSrc, enumType, methodName, argValues);
  5306. }
  5307. if (enumType != NULL)
  5308. {
  5309. enumResult = CheckEnumCreation(targetSrc, enumType, methodName, argValues);
  5310. }
  5311. if (enumResult)
  5312. {
  5313. if ((mModule->mCompiler->mResolvePassData != NULL) &&
  5314. (targetSrc->IsFromParser(mModule->mCompiler->mResolvePassData->mParser)) &&
  5315. (mModule->mCompiler->mResolvePassData->mSourceClassifier != NULL))
  5316. {
  5317. mModule->mCompiler->mResolvePassData->mSourceClassifier->SetElementType(targetSrc, BfSourceElementType_Normal);
  5318. }
  5319. return enumResult;
  5320. }
  5321. BfTypedValue fieldVal;
  5322. if (allowImplicitThis)
  5323. {
  5324. auto identifierNode = BfNodeDynCast<BfIdentifierNode>(targetSrc);
  5325. if (identifierNode != NULL)
  5326. fieldVal = LookupIdentifier(identifierNode);
  5327. }
  5328. else
  5329. {
  5330. fieldVal = LookupField(targetSrc, target, methodName);
  5331. }
  5332. if (mPropDef != NULL)
  5333. fieldVal = GetResult();
  5334. if (fieldVal)
  5335. {
  5336. if (fieldVal.mType->IsGenericParam())
  5337. {
  5338. bool delegateFailed = true;
  5339. auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)fieldVal.mType);
  5340. BfTypeInstance* typeInstConstraint = NULL;
  5341. if (genericParamInstance->mTypeConstraint != NULL)
  5342. typeInstConstraint = genericParamInstance->mTypeConstraint->ToTypeInstance();
  5343. if ((typeInstConstraint != NULL) &&
  5344. ((typeInstConstraint->mTypeDef == mModule->mCompiler->mDelegateTypeDef) || (typeInstConstraint->mTypeDef == mModule->mCompiler->mFunctionTypeDef)))
  5345. {
  5346. MarkResultUsed();
  5347. // if (argValues.mResolvedArgs.size() > 0)
  5348. // {
  5349. // if ((argValues.mResolvedArgs[0].mArgFlags & BfArgFlag_FromParamComposite) != 0)
  5350. // delegateFailed = false;
  5351. // }
  5352. // else
  5353. if (argValues.mArguments->size() == 1)
  5354. {
  5355. BfExprEvaluator exprEvaluator(mModule);
  5356. exprEvaluator.mBfEvalExprFlags = BfEvalExprFlags_AllowParamsExpr;
  5357. exprEvaluator.Evaluate((*argValues.mArguments)[0]);
  5358. if ((mModule->mCurMethodState != NULL) && (exprEvaluator.mResultLocalVar != NULL) && (exprEvaluator.mResultLocalVarRefNode != NULL))
  5359. {
  5360. /*if (exprEvaluator.mResult.mKind != BfTypedValueKind_Params)
  5361. mModule->Warn(0, "'params' token expected", (*argValues.mArguments)[0]);*/
  5362. auto localVar = exprEvaluator.mResultLocalVar;
  5363. if ((localVar->mCompositeCount >= 0) && (localVar->mResolvedType == fieldVal.mType))
  5364. {
  5365. delegateFailed = false;
  5366. if (mModule->mCurMethodInstance->mIsUnspecialized)
  5367. {
  5368. auto retTypeType = mModule->CreateRetTypeType(fieldVal.mType);
  5369. return mModule->GetFakeTypedValue(retTypeType);
  5370. }
  5371. }
  5372. }
  5373. }
  5374. if (delegateFailed)
  5375. {
  5376. mModule->Fail(StrFormat("Generic delegates can only be invoked with 'params %s' composite parameters", mModule->TypeToString(fieldVal.mType).c_str()), targetSrc);
  5377. return BfTypedValue();
  5378. }
  5379. }
  5380. }
  5381. if (fieldVal.mType->IsTypeInstance())
  5382. {
  5383. prevBindResult.Restore();
  5384. auto fieldTypeInst = fieldVal.mType->ToTypeInstance();
  5385. MarkResultUsed();
  5386. return MatchMethod(targetSrc, NULL, fieldVal, false, false, "Invoke", argValues, methodGenericArguments, checkedKind);
  5387. }
  5388. if (fieldVal.mType->IsVar())
  5389. return BfTypedValue(mModule->GetDefaultValue(fieldVal.mType), fieldVal.mType);
  5390. if (fieldVal.mType->IsGenericParam())
  5391. {
  5392. auto genericParam = mModule->GetGenericParamInstance((BfGenericParamType*)fieldVal.mType);
  5393. if ((genericParam->mTypeConstraint != NULL) &&
  5394. ((genericParam->mTypeConstraint->IsDelegate()) || (genericParam->mTypeConstraint->IsFunction())))
  5395. {
  5396. BfMethodInstance* invokeMethodInstance = mModule->GetRawMethodInstanceAtIdx(genericParam->mTypeConstraint->ToTypeInstance(), 0, "Invoke");
  5397. methodDef = invokeMethodInstance->mMethodDef;
  5398. methodMatcher.mBestMethodInstance = invokeMethodInstance;
  5399. methodMatcher.mBestMethodTypeInstance = invokeMethodInstance->GetOwner();
  5400. methodMatcher.mBestMethodDef = invokeMethodInstance->mMethodDef;
  5401. target = mModule->GetDefaultTypedValue(methodMatcher.mBestMethodTypeInstance);
  5402. isFailurePass = false;
  5403. isIndirectMethodCall = true;
  5404. }
  5405. }
  5406. else if (fieldVal.mType->IsMethodRef())
  5407. {
  5408. auto functionBindResults = prevBindResult.mPrevVal;
  5409. if (functionBindResults != NULL)
  5410. {
  5411. functionBindResults->mOrigTarget = fieldVal;
  5412. }
  5413. origTarget = fieldVal;
  5414. auto methodRefType = (BfMethodRefType*)fieldVal.mType;
  5415. BfMethodInstance* methodInstance = methodRefType->mMethodRef;
  5416. methodDef = methodInstance->mMethodDef;
  5417. if (methodDef->mIsLocalMethod)
  5418. {
  5419. methodMatcher.mBestMethodInstance = mModule->ReferenceExternalMethodInstance(methodInstance);
  5420. }
  5421. else
  5422. {
  5423. BfTypeVector methodGenericArguments;
  5424. if (methodInstance->mMethodInfoEx != NULL)
  5425. methodGenericArguments = methodInstance->mMethodInfoEx->mMethodGenericArguments;
  5426. methodMatcher.mBestMethodInstance = mModule->GetMethodInstance(methodInstance->GetOwner(), methodInstance->mMethodDef, methodGenericArguments);
  5427. }
  5428. methodMatcher.mBestMethodTypeInstance = methodInstance->GetOwner();
  5429. if (methodInstance->HasThis())
  5430. {
  5431. bool failed = false;
  5432. target = DoImplicitArgCapture(targetSrc, methodInstance, -1, failed, BfImplicitParamKind_General, origTarget);
  5433. }
  5434. else if (!methodDef->mIsStatic)
  5435. {
  5436. auto thisType = methodInstance->GetParamType(-1);
  5437. BF_ASSERT(thisType->IsValuelessType());
  5438. target = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), methodMatcher.mBestMethodTypeInstance);
  5439. }
  5440. else
  5441. target = BfTypedValue(methodMatcher.mBestMethodTypeInstance);
  5442. methodMatcher.mBypassVirtual = true;
  5443. bypassVirtual = true;
  5444. isFailurePass = false;
  5445. isIndirectMethodCall = true;
  5446. }
  5447. if (methodDef == NULL)
  5448. {
  5449. mModule->Fail(StrFormat("Cannot perform invocation on type '%s'", mModule->TypeToString(fieldVal.mType).c_str()), targetSrc);
  5450. return BfTypedValue();
  5451. }
  5452. }
  5453. }
  5454. if ((!methodDef) && (!target.mValue))
  5455. {
  5456. // Check to see if we're constructing a struct via a call like: "Struct structVal = Struct()"
  5457. int wantNumGenericArgs = 0;
  5458. if ((methodGenericArguments != NULL) && (methodGenericArguments->size() > 0))
  5459. wantNumGenericArgs = (int)methodGenericArguments->size();
  5460. BfTypeInstance* resolvedTypeInstance = NULL;
  5461. if (wantCtor)
  5462. {
  5463. resolvedTypeInstance = targetTypeInst;
  5464. }
  5465. else if (targetType != NULL)
  5466. {
  5467. if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(methodBoundExpr))
  5468. {
  5469. auto resolvedType = mModule->ResolveTypeRef(invocationExpr->mTarget, methodGenericArguments);
  5470. if (resolvedType != NULL)
  5471. resolvedTypeInstance = resolvedType->ToTypeInstance();
  5472. }
  5473. }
  5474. else
  5475. {
  5476. BfIdentifierNode* identifierNode = BfNodeDynCast<BfIdentifierNode>(targetSrc);
  5477. if (identifierNode != NULL)
  5478. {
  5479. SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
  5480. BfType* refType;
  5481. if (methodGenericArguments != NULL)
  5482. {
  5483. refType = mModule->ResolveTypeRef(identifierNode, methodGenericArguments);
  5484. }
  5485. else
  5486. refType = mModule->ResolveTypeRef(identifierNode, NULL);
  5487. prevIgnoreErrors.Restore();
  5488. if ((refType != NULL) && (refType->IsPrimitiveType()))
  5489. {
  5490. if (argValues.mResolvedArgs.size() != 1)
  5491. {
  5492. mModule->Fail("Cast requires one parameter", targetSrc);
  5493. return BfTypedValue();
  5494. }
  5495. // This is just a primitive cast
  5496. auto& resolvedArg = argValues.mResolvedArgs[0];
  5497. BfTypedValue castedValue;
  5498. BfTypedValue castTarget = resolvedArg.mTypedValue;
  5499. if (resolvedArg.mTypedValue)
  5500. {
  5501. castTarget = mModule->LoadValue(castTarget);
  5502. castedValue = mModule->Cast(targetSrc, castTarget, refType, BfCastFlags_Explicit);
  5503. }
  5504. if (!castedValue)
  5505. castedValue = mModule->GetDefaultTypedValue(refType);
  5506. return castedValue;
  5507. }
  5508. if (refType != NULL)
  5509. resolvedTypeInstance = refType->ToTypeInstance();
  5510. }
  5511. }
  5512. if (resolvedTypeInstance != NULL)
  5513. {
  5514. if ((!resolvedTypeInstance->IsStruct()) && (!resolvedTypeInstance->IsTypedPrimitive()))
  5515. {
  5516. mModule->Fail("Objects must be allocated through 'new' or 'stack'", targetSrc);
  5517. return BfTypedValue();
  5518. }
  5519. if (auto identifier = BfNodeDynCastExact<BfIdentifierNode>(targetSrc))
  5520. mModule->SetElementType(identifier, BfSourceElementType_TypeRef);
  5521. if (mModule->mCompiler->mResolvePassData != NULL)
  5522. mModule->mCompiler->mResolvePassData->HandleTypeReference(targetSrc, resolvedTypeInstance->mTypeDef);
  5523. BfTypedValue structInst;
  5524. if (!resolvedTypeInstance->IsValuelessType())
  5525. {
  5526. if ((mReceivingValue != NULL) && (mReceivingValue->mType == resolvedTypeInstance) && (mReceivingValue->IsAddr()))
  5527. {
  5528. structInst = *mReceivingValue;
  5529. mReceivingValue = NULL;
  5530. }
  5531. else
  5532. {
  5533. auto allocaInst = mModule->CreateAlloca(resolvedTypeInstance);
  5534. structInst = BfTypedValue(allocaInst, resolvedTypeInstance, true);
  5535. }
  5536. mResultIsTempComposite = true;
  5537. }
  5538. else
  5539. {
  5540. structInst = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), resolvedTypeInstance, true);
  5541. }
  5542. mResultLocalVar = NULL;
  5543. mResultLocalVarRefNode = NULL;
  5544. MatchConstructor(targetSrc, methodBoundExpr, structInst, resolvedTypeInstance, argValues, false, false);
  5545. mModule->ValidateAllocation(resolvedTypeInstance, targetSrc);
  5546. mModule->AddDependency(resolvedTypeInstance, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage);
  5547. if (mUsedAsStatement)
  5548. {
  5549. mModule->Warn(0, "Struct constructor being used as a statement", targetSrc);
  5550. }
  5551. return structInst;
  5552. }
  5553. }
  5554. if ((methodDef == NULL) && (!target) && (mModule->mContext->mCurTypeState != NULL))
  5555. {
  5556. //BF_ASSERT(mModule->mCurTypeInstance == mModule->mContext->mCurTypeState->mTypeInstance);
  5557. BfGlobalLookup globalLookup;
  5558. globalLookup.mKind = BfGlobalLookup::Kind_Method;
  5559. globalLookup.mName = methodName;
  5560. mModule->PopulateGlobalContainersList(globalLookup);
  5561. for (auto& globalContainer : mModule->mContext->mCurTypeState->mGlobalContainers)
  5562. {
  5563. if (globalContainer.mTypeInst == NULL)
  5564. continue;
  5565. methodMatcher.CheckType(globalContainer.mTypeInst, BfTypedValue(), false);
  5566. if (methodMatcher.mBestMethodDef != NULL)
  5567. {
  5568. isFailurePass = false;
  5569. curTypeInst = methodMatcher.mBestMethodTypeInstance;
  5570. methodDef = methodMatcher.mBestMethodDef;
  5571. break;
  5572. }
  5573. }
  5574. }
  5575. if (methodDef == NULL)
  5576. {
  5577. auto compiler = mModule->mCompiler;
  5578. if ((compiler->IsAutocomplete()) && (compiler->mResolvePassData->mAutoComplete->CheckFixit(targetSrc)))
  5579. {
  5580. mModule->CheckTypeRefFixit(targetSrc);
  5581. bool wantStatic = !target.mValue;
  5582. if ((targetType == NULL) && (allowImplicitThis))
  5583. {
  5584. targetType = mModule->mCurTypeInstance;
  5585. if (mModule->mCurMethodInstance != NULL)
  5586. wantStatic = mModule->mCurMethodInstance->mMethodDef->mIsStatic;
  5587. }
  5588. if (targetType != NULL)
  5589. {
  5590. auto typeInst = targetType->ToTypeInstance();
  5591. if ((typeInst->mTypeDef->mSource != NULL) && (typeInst != mModule->mContext->mBfObjectType))
  5592. {
  5593. auto parser = typeInst->mTypeDef->mSource->ToParser();
  5594. if (parser != NULL)
  5595. {
  5596. String fullName = typeInst->mTypeDef->mFullName.ToString();
  5597. String methodStr;
  5598. if (typeInst == mModule->mCurTypeInstance)
  5599. {
  5600. // Implicitly private
  5601. }
  5602. else if (mModule->TypeIsSubTypeOf(mModule->mCurTypeInstance, typeInst))
  5603. {
  5604. methodStr += "protected ";
  5605. }
  5606. else
  5607. {
  5608. methodStr += "public ";
  5609. }
  5610. if (wantStatic)
  5611. methodStr += "static ";
  5612. if (mExpectingType != NULL)
  5613. methodStr += mModule->TypeToString(mExpectingType, BfTypeNameFlag_ReduceName);
  5614. else
  5615. methodStr += "void";
  5616. methodStr += " " + methodName + "(";
  5617. std::set<String> usedNames;
  5618. for (int argIdx = 0; argIdx < (int)argValues.mResolvedArgs.size(); argIdx++)
  5619. {
  5620. if (argIdx > 0)
  5621. methodStr += ", ";
  5622. auto& resolvedArg = argValues.mResolvedArgs[argIdx];
  5623. String checkName = "param";
  5624. if (resolvedArg.mTypedValue.mType != NULL)
  5625. {
  5626. bool isOut = false;
  5627. bool isArr = false;
  5628. BfType* checkType = resolvedArg.mTypedValue.mType;
  5629. while (true)
  5630. {
  5631. if ((checkType->IsArray()) || (checkType->IsSizedArray()))
  5632. {
  5633. isArr = true;
  5634. checkType = checkType->GetUnderlyingType();
  5635. }
  5636. else if (checkType->IsRef())
  5637. {
  5638. BfRefType* refType = (BfRefType*)checkType;
  5639. if (refType->mRefKind == BfRefType::RefKind_Out)
  5640. isOut = true;
  5641. checkType = refType->GetUnderlyingType();
  5642. }
  5643. else if (checkType->IsTypeInstance())
  5644. {
  5645. BfTypeInstance* typeInst = (BfTypeInstance*)checkType;
  5646. checkName = typeInst->mTypeDef->mName->ToString();
  5647. if (checkName == "String")
  5648. checkName = "Str";
  5649. if (checkName == "Object")
  5650. checkName = "Obj";
  5651. if (isOut)
  5652. checkName = "out" + checkName;
  5653. else if (isupper(checkName[0]))
  5654. checkName[0] = tolower(checkName[0]);
  5655. if (isArr)
  5656. checkName += "Arr";
  5657. break;
  5658. }
  5659. else
  5660. break;
  5661. }
  5662. methodStr += mModule->TypeToString(resolvedArg.mTypedValue.mType, BfTypeNameFlag_ReduceName);
  5663. }
  5664. else
  5665. {
  5666. checkName = "param";
  5667. methodStr += "Object";
  5668. }
  5669. for (int i = 1; i < 10; i++)
  5670. {
  5671. String lookupName = checkName;
  5672. if (i > 1)
  5673. lookupName += StrFormat("%d", i);
  5674. if (usedNames.insert(lookupName).second)
  5675. {
  5676. methodStr += " " + lookupName;
  5677. break;
  5678. }
  5679. }
  5680. }
  5681. int fileLoc = typeInst->mTypeDef->mTypeDeclaration->GetSrcEnd();
  5682. if (auto defineBlock = BfNodeDynCast<BfBlock>(typeInst->mTypeDef->mTypeDeclaration->mDefineNode))
  5683. fileLoc = defineBlock->mCloseBrace->GetSrcStart();
  5684. methodStr += ")";
  5685. compiler->mResolvePassData->mAutoComplete->AddEntry(AutoCompleteEntry("fixit", StrFormat("Create method '%s' in '%s'\taddMethod|%s|%d|||%s|{||}", methodName.c_str(), fullName.c_str(), parser->mFileName.c_str(), fileLoc, methodStr.c_str()).c_str()));
  5686. }
  5687. }
  5688. }
  5689. }
  5690. if (methodName.IsEmpty())
  5691. {
  5692. // Would have caused a parsing error
  5693. }
  5694. else if (target.mType != NULL)
  5695. mModule->Fail(StrFormat("Method '%s' does not exist in type '%s'", methodName.c_str(), mModule->TypeToString(target.mType).c_str()), targetSrc);
  5696. else
  5697. mModule->Fail(StrFormat("Method '%s' does not exist", methodName.c_str()), targetSrc);
  5698. FinishDeferredEvals(argValues.mResolvedArgs);
  5699. return BfTypedValue();
  5700. }
  5701. if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsUnspecialized))
  5702. {
  5703. for (auto& arg : methodMatcher.mBestMethodGenericArguments)
  5704. {
  5705. if ((arg != NULL) && (arg->IsVar()))
  5706. return mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Var));
  5707. }
  5708. }
  5709. if ((prevBindResult.mPrevVal != NULL) && (methodMatcher.mMethodCheckCount > 1))
  5710. prevBindResult.mPrevVal->mCheckedMultipleMethods = true;
  5711. BfModuleMethodInstance moduleMethodInstance = GetSelectedMethod(targetSrc, curTypeInst, methodDef, methodMatcher);
  5712. if ((bypassVirtual) && (!target.mValue) && (target.mType->IsInterface()))
  5713. {
  5714. target = mModule->GetThis();
  5715. }
  5716. if (!moduleMethodInstance)
  5717. return BfTypedValue();
  5718. bool isSkipCall = moduleMethodInstance.mMethodInstance->IsSkipCall(bypassVirtual);
  5719. if (methodDef->IsEmptyPartial())
  5720. {
  5721. // Ignore call
  5722. return mModule->GetDefaultTypedValue(moduleMethodInstance.mMethodInstance->mReturnType);
  5723. }
  5724. if ((moduleMethodInstance.mMethodInstance->mMethodDef->mIsStatic) && (moduleMethodInstance.mMethodInstance->GetOwner()->IsInterface()))
  5725. {
  5726. bool isConstrained = false;
  5727. if (target.mType != NULL)
  5728. isConstrained = target.mType->IsGenericParam();
  5729. if ((target.mType == NULL) && ((mModule->mCurMethodInstance->mIsForeignMethodDef) || (mModule->mCurTypeInstance->IsInterface())))
  5730. isConstrained = true;
  5731. if (!isConstrained)
  5732. {
  5733. if (mModule->mCurTypeInstance->IsInterface())
  5734. {
  5735. if (methodDef->mBody == NULL)
  5736. mModule->Fail(StrFormat("Interface method '%s' must provide a body to be explicitly invoked", mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str()), targetSrc);
  5737. }
  5738. else
  5739. 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);
  5740. FinishDeferredEvals(argValues.mResolvedArgs);
  5741. return mModule->GetDefaultTypedValue(moduleMethodInstance.mMethodInstance->mReturnType);
  5742. }
  5743. }
  5744. // 'base' could really mean 'this' if we're in an extension
  5745. if ((target.IsBase()) && (targetTypeInst == mModule->mCurTypeInstance))
  5746. target.ToThis();
  5747. else
  5748. MakeBaseConcrete(target);
  5749. BfTypedValue callTarget;
  5750. if (isSkipCall)
  5751. {
  5752. // Just a fake value so we can continue on without generating any code (boxing, conversion, etc)
  5753. if (target)
  5754. callTarget = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), targetTypeInst);
  5755. }
  5756. else if (targetTypeInst == curTypeInst)
  5757. {
  5758. if ((target) && (methodDef->HasNoThisSplat()))
  5759. {
  5760. callTarget = mModule->MakeAddressable(target);
  5761. }
  5762. else
  5763. callTarget = target;
  5764. }
  5765. else if (target)
  5766. {
  5767. if (methodMatcher.mFakeConcreteTarget)
  5768. {
  5769. BF_ASSERT(curTypeInst->IsInterface());
  5770. callTarget = mModule->GetDefaultTypedValue(mModule->CreateConcreteInterfaceType(curTypeInst));
  5771. }
  5772. else if (((target.mType->IsGenericParam()) || (target.mType->IsConcreteInterfaceType())) && (curTypeInst->IsInterface()))
  5773. {
  5774. // Leave as generic
  5775. callTarget = target;
  5776. }
  5777. else
  5778. {
  5779. bool handled = false;
  5780. if ((target.mType->IsTypedPrimitive()) && (curTypeInst->IsTypedPrimitive()))
  5781. {
  5782. handled = true;
  5783. callTarget = target;
  5784. }
  5785. else if ((target.mType->IsStructOrStructPtr()) || (target.mType->IsTypedPrimitive()))
  5786. {
  5787. //BF_ASSERT(target.IsAddr());
  5788. if (curTypeInst->IsObjectOrInterface())
  5789. {
  5790. // Box it
  5791. callTarget = mModule->Cast(targetSrc, target, curTypeInst, BfCastFlags_Explicit);
  5792. handled = true;
  5793. }
  5794. else
  5795. {
  5796. //BF_ASSERT(target.IsAddr() || target.IsSplat() || target.mType->IsPointer());
  5797. }
  5798. }
  5799. else
  5800. target = mModule->LoadValue(target);
  5801. if (!handled)
  5802. {
  5803. // Could we have just unconditionally done this?
  5804. callTarget = mModule->Cast(targetSrc, target, curTypeInst, BfCastFlags_Explicit);
  5805. }
  5806. }
  5807. }
  5808. if (isFailurePass)
  5809. {
  5810. BfError* error;
  5811. if (methodMatcher.mMatchFailKind == BfMethodMatcher::MatchFailKind_CheckedMismatch)
  5812. 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);
  5813. else
  5814. error = mModule->Fail(StrFormat("'%s' is inaccessible due to its protection level", mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str()), targetSrc);
  5815. if (error != NULL)
  5816. {
  5817. if ((error != NULL) && (moduleMethodInstance.mMethodInstance->mMethodDef->mMethodDeclaration != NULL))
  5818. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), moduleMethodInstance.mMethodInstance->mMethodDef->GetRefNode());
  5819. }
  5820. }
  5821. if ((mModule->mCompiler->mResolvePassData != NULL) && (methodDef != NULL))
  5822. {
  5823. auto identifierNode = BfNodeDynCast<BfIdentifierNode>(targetSrc);
  5824. while (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(identifierNode))
  5825. identifierNode = qualifiedNameNode->mRight;
  5826. if ((identifierNode != NULL) && (methodDef->mIdx >= 0) && (!isIndirectMethodCall))
  5827. {
  5828. mModule->mCompiler->mResolvePassData->HandleMethodReference(identifierNode, curTypeInst->mTypeDef, methodDef);
  5829. auto autoComplete = GetAutoComplete();
  5830. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(identifierNode)))
  5831. {
  5832. autoComplete->SetDefinitionLocation(methodDef->GetRefNode());
  5833. int virtualIdx = moduleMethodInstance.mMethodInstance->mVirtualTableIdx;
  5834. if ((autoComplete->mResolveType == BfResolveType_GoToDefinition) &&
  5835. (virtualIdx != -1) && (targetTypeInst != NULL) && (!targetTypeInst->IsStruct()) && (!targetTypeInst->IsTypedPrimitive()) && (!targetTypeInst->IsInterface()) &&
  5836. // 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
  5837. (targetTypeInst->mVirtualMethodTable.size() != 0))
  5838. {
  5839. auto methodEntry = targetTypeInst->mVirtualMethodTable[virtualIdx];
  5840. if (methodEntry.mImplementingMethod.mMethodNum != -1)
  5841. {
  5842. BfMethodInstance* callingMethodInstance = methodEntry.mImplementingMethod;
  5843. if (callingMethodInstance != NULL)
  5844. {
  5845. auto callingMethodDef = callingMethodInstance->mMethodDef;
  5846. auto callingMethodDeclaration = callingMethodDef->GetMethodDeclaration();
  5847. if ((callingMethodDeclaration != NULL) && (callingMethodDeclaration->mNameNode != NULL))
  5848. autoComplete->SetDefinitionLocation(callingMethodDeclaration->mNameNode, true);
  5849. }
  5850. }
  5851. }
  5852. if (autoComplete->mDefType == NULL)
  5853. {
  5854. autoComplete->mDefMethod = methodDef;
  5855. autoComplete->mDefType = curTypeInst->mTypeDef;
  5856. }
  5857. }
  5858. }
  5859. }
  5860. // This was causing forward-backward-forward steps when we just used 'targetSrc'. Using closeParen is undesirable because most of the time
  5861. // we DO just want it to just go to the targetSrc... do we even need this?
  5862. /*if (auto invokeExpr = BfNodeDynCast<BfInvocationExpression>(targetSrc->mParent))
  5863. {
  5864. // We set the srcPos to the close paren right before the call so we keep a forward progression of src positions in the case
  5865. // where some of the params are method calls and such
  5866. if (invokeExpr->mCloseParen != NULL)
  5867. mModule->UpdateExprSrcPos(invokeExpr->mCloseParen);
  5868. else
  5869. mModule->UpdateExprSrcPos(targetSrc);
  5870. }
  5871. else
  5872. mModule->UpdateExprSrcPos(targetSrc);*/
  5873. if (!mModule->mBfIRBuilder->mIgnoreWrites)
  5874. {
  5875. //BF_ASSERT(!callTarget.mValue.IsFake());
  5876. }
  5877. prevBindResult.Restore();
  5878. if ((callTarget.mType != NULL) &&
  5879. (callTarget.mType->IsGenericParam()) &&
  5880. ((!callTarget.IsAddr()) || (callTarget.IsReadOnly())) &&
  5881. (callTarget.mKind != BfTypedValueKind_MutableValue) &&
  5882. (moduleMethodInstance.mMethodInstance->mMethodDef->mIsMutating))
  5883. {
  5884. auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)callTarget.mType);
  5885. bool needsMut = true;
  5886. if ((genericParamInstance->mGenericParamFlags & (BfGenericParamFlag_StructPtr | BfGenericParamFlag_Class | BfGenericParamFlag_Var)) != 0)
  5887. needsMut = false;
  5888. if (genericParamInstance->mTypeConstraint != NULL)
  5889. {
  5890. auto typeConstaintTypeInstance = genericParamInstance->mTypeConstraint->ToTypeInstance();
  5891. if ((typeConstaintTypeInstance != NULL) && (!typeConstaintTypeInstance->IsComposite()))
  5892. needsMut = false;
  5893. }
  5894. if (needsMut)
  5895. {
  5896. String err = StrFormat("call mutating method '%s' on", mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str());
  5897. CheckModifyResult(callTarget, targetSrc, err.c_str(), true);
  5898. }
  5899. }
  5900. if ((callTarget.mType != NULL) &&
  5901. (callTarget.mType->IsInterface()) &&
  5902. (target.IsThis()) &&
  5903. (mModule->mCurTypeInstance) &&
  5904. (!mModule->mCurMethodInstance->mMethodDef->mIsMutating) &&
  5905. (methodDef->mIsMutating))
  5906. {
  5907. mModule->Fail(StrFormat("Cannot call mutating method '%s' within default interface method '%s'. Consider adding 'mut' specifier to this method.",
  5908. mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str(), mModule->MethodToString(mModule->mCurMethodInstance).c_str()), targetSrc);
  5909. }
  5910. auto result = CreateCall(targetSrc, callTarget, origTarget, methodDef, moduleMethodInstance, bypassVirtual, argValues.mResolvedArgs, skipThis);
  5911. if (result)
  5912. {
  5913. if (result.mType->IsRef())
  5914. result = mModule->RemoveRef(result);
  5915. if (result.mType->IsSelf())
  5916. {
  5917. if (methodMatcher.mSelfType != NULL)
  5918. {
  5919. BF_ASSERT(mModule->IsInGeneric());
  5920. result = mModule->GetDefaultTypedValue(methodMatcher.mSelfType);
  5921. }
  5922. else
  5923. {
  5924. // Will be an error
  5925. result = mModule->GetDefaultTypedValue(methodMatcher.mBestMethodTypeInstance);
  5926. }
  5927. }
  5928. }
  5929. PerformCallChecks(moduleMethodInstance.mMethodInstance, targetSrc);
  5930. if (result)
  5931. {
  5932. bool discardedReturnValue = mUsedAsStatement;
  5933. if (discardedReturnValue)
  5934. {
  5935. auto _ShowDiscardWaring = [&](const String& text, BfCustomAttributes* customAttributes, BfIRConstHolder* constHolder, BfAstNode* refNode)
  5936. {
  5937. if (customAttributes != NULL)
  5938. {
  5939. auto customAttribute = customAttributes->Get(mModule->mCompiler->mNoDiscardAttributeTypeDef);
  5940. if (!customAttribute->mCtorArgs.IsEmpty())
  5941. {
  5942. String* str = mModule->GetStringPoolString(customAttribute->mCtorArgs[0], constHolder);
  5943. if ((str != NULL) && (!str->IsEmpty()))
  5944. {
  5945. mModule->Warn(0, text + ": " + *str, targetSrc);
  5946. return;
  5947. }
  5948. }
  5949. }
  5950. mModule->Warn(0, text, targetSrc);
  5951. };
  5952. bool showedWarning = false;
  5953. if (moduleMethodInstance.mMethodInstance->mMethodDef->mIsNoDiscard)
  5954. {
  5955. _ShowDiscardWaring("Discarding return value of method with [NoDiscard] attribute", moduleMethodInstance.mMethodInstance->GetCustomAttributes(),
  5956. moduleMethodInstance.mMethodInstance->GetOwner()->mConstHolder, targetSrc);
  5957. showedWarning = true;
  5958. }
  5959. auto typeInst = result.mType->ToTypeInstance();
  5960. if (typeInst != NULL)
  5961. {
  5962. if ((typeInst->mTypeDef->mIsNoDiscard) && (!showedWarning))
  5963. {
  5964. _ShowDiscardWaring("Discarding return value whose type has [NoDiscard] attribute", typeInst->mCustomAttributes, typeInst->mConstHolder, targetSrc);
  5965. }
  5966. BfModuleMethodInstance moduleMethodInstance = mModule->GetMethodByName(typeInst, "ReturnValueDiscarded", 0, true);
  5967. if (moduleMethodInstance)
  5968. {
  5969. auto wasGetDefinition = (autoComplete != NULL) && (autoComplete->mIsGetDefinition);
  5970. if (wasGetDefinition)
  5971. autoComplete->mIsGetDefinition = false;
  5972. result = mModule->MakeAddressable(result);
  5973. BfResolvedArgs resolvedArgs;
  5974. MatchMethod(targetSrc, NULL, result, false, false, "ReturnValueDiscarded", resolvedArgs, NULL);
  5975. if (wasGetDefinition)
  5976. autoComplete->mIsGetDefinition = true;
  5977. }
  5978. }
  5979. }
  5980. }
  5981. return result;
  5982. }
  5983. void BfExprEvaluator::LookupQualifiedName(BfQualifiedNameNode* nameNode, bool ignoreInitialError, bool* hadError)
  5984. {
  5985. BfIdentifierNode* nameLeft = nameNode->mLeft;
  5986. BfIdentifierNode* nameRight = nameNode->mRight;
  5987. StringT<64> fieldName;
  5988. if (nameNode->mRight != NULL)
  5989. nameNode->mRight->ToString(fieldName);
  5990. bool wasBaseLookup = false;
  5991. if (auto qualifiedLeftName = BfNodeDynCast<BfQualifiedNameNode>(nameNode->mLeft))
  5992. {
  5993. if ((qualifiedLeftName->mRight->GetSrcLength() == 4) && (qualifiedLeftName->mRight->ToStringView() == "base"))
  5994. {
  5995. wasBaseLookup = true;
  5996. auto type = mModule->ResolveTypeRef(qualifiedLeftName->mLeft, NULL);
  5997. if (type == NULL)
  5998. return;
  5999. auto fieldName = nameNode->mRight->ToString();
  6000. auto target = mModule->GetThis();
  6001. target.mType = type;
  6002. mResult = LookupField(nameNode->mRight, target, fieldName);
  6003. if (mPropDef != NULL)
  6004. {
  6005. mPropDefBypassVirtual = true;
  6006. }
  6007. return;
  6008. }
  6009. }
  6010. if (!wasBaseLookup)
  6011. mResult = LookupIdentifier(nameNode->mLeft, ignoreInitialError, hadError);
  6012. GetResult();
  6013. if (!mResult)
  6014. {
  6015. if (!ignoreInitialError)
  6016. mModule->Fail("Identifier not found", nameNode->mLeft);
  6017. return;
  6018. }
  6019. if (mResult.mType->IsObject())
  6020. {
  6021. mResult = mModule->LoadValue(mResult, 0, mIsVolatileReference);
  6022. }
  6023. else if ((mResult.mType->IsPointer()) && mResult.mType->IsStructOrStructPtr())
  6024. {
  6025. BfPointerType* structPtrType = (BfPointerType*)mResult.mType;
  6026. mResult = mModule->LoadValue(mResult, 0, mIsVolatileReference);
  6027. mResult.mType = structPtrType->mElementType;
  6028. if (mResult.mKind == BfTypedValueKind_ThisValue)
  6029. mResult.mKind = BfTypedValueKind_ThisAddr;
  6030. else
  6031. mResult.mKind = BfTypedValueKind_Addr;
  6032. }
  6033. mIsVolatileReference = false;
  6034. mIsHeapReference = false;
  6035. if (!mResult)
  6036. return;
  6037. //if (mResult.mType->IsVar())
  6038. //ResolveGenericType();
  6039. auto origResult = mResult;
  6040. auto lookupType = BindGenericType(nameNode, mResult.mType);
  6041. if (mResult.mType->IsGenericParam())
  6042. {
  6043. auto genericParamInst = mModule->GetGenericParamInstance((BfGenericParamType*)mResult.mType);
  6044. if (mModule->mCurMethodInstance->mIsUnspecialized)
  6045. {
  6046. if (genericParamInst->mTypeConstraint != NULL)
  6047. mResult.mType = genericParamInst->mTypeConstraint;
  6048. else
  6049. mResult.mType = mModule->mContext->mBfObjectType;
  6050. if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Var) != 0)
  6051. {
  6052. mResult.mType = mModule->GetPrimitiveType(BfTypeCode_Var);
  6053. }
  6054. }
  6055. else
  6056. {
  6057. if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Var) != 0)
  6058. {
  6059. //mResult.mType = mModule->ResolveGenericType(mResult.mType);
  6060. }
  6061. else if (genericParamInst->mTypeConstraint != NULL)
  6062. {
  6063. mResult = mModule->Cast(nameNode, mResult, genericParamInst->mTypeConstraint);
  6064. BF_ASSERT(mResult);
  6065. }
  6066. else
  6067. {
  6068. // This shouldn't occur - this would infer that we are accessing a member of Object or something...
  6069. //mResult.mType = mModule->ResolveGenericType(mResult.mType);
  6070. }
  6071. }
  6072. }
  6073. if (mResult.mType->IsVar())
  6074. {
  6075. mResult = BfTypedValue(mModule->GetDefaultValue(mResult.mType), mResult.mType, true);
  6076. return;
  6077. }
  6078. if (!mResult.mType->IsTypeInstance())
  6079. {
  6080. if (hadError != NULL)
  6081. *hadError = true;
  6082. mModule->Fail(StrFormat("Type '%s' has no fields", mModule->TypeToString(mResult.mType).c_str()), nameNode->mLeft);
  6083. mResult = BfTypedValue();
  6084. return;
  6085. }
  6086. BfTypedValue lookupVal = mResult;
  6087. mResult = LookupField(nameNode->mRight, lookupVal, fieldName);
  6088. if ((!mResult) && (mPropDef == NULL) && (lookupType->IsGenericParam()))
  6089. {
  6090. auto genericParamInst = mModule->GetGenericParamInstance((BfGenericParamType*)lookupType);
  6091. SizedArray<BfTypeInstance*, 8> searchConstraints;
  6092. for (auto ifaceConstraint : genericParamInst->mInterfaceConstraints)
  6093. {
  6094. //if (std::find(searchConstraints.begin(), searchConstraints.end(), ifaceConstraint) == searchConstraints.end())
  6095. if (!searchConstraints.Contains(ifaceConstraint))
  6096. {
  6097. searchConstraints.push_back(ifaceConstraint);
  6098. for (auto& innerIFaceEntry : ifaceConstraint->mInterfaces)
  6099. {
  6100. auto innerIFace = innerIFaceEntry.mInterfaceType;
  6101. //if (std::find(searchConstraints.begin(), searchConstraints.end(), innerIFace) == searchConstraints.end())
  6102. if (!searchConstraints.Contains(innerIFace))
  6103. {
  6104. searchConstraints.push_back(innerIFace);
  6105. }
  6106. }
  6107. }
  6108. }
  6109. BfTypedValue prevTarget;
  6110. BfPropertyDef* prevDef = NULL;
  6111. for (auto ifaceConstraint : searchConstraints)
  6112. {
  6113. //auto lookupVal = mModule->GetDefaultTypedValue(ifaceConstraint, origResult.IsAddr());
  6114. BfTypedValue lookupVal = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), ifaceConstraint);
  6115. mResult = LookupField(nameNode->mRight, lookupVal, fieldName);
  6116. if (mPropDef != NULL)
  6117. {
  6118. if (prevDef != NULL)
  6119. {
  6120. bool isBetter = mModule->TypeIsSubTypeOf(mPropTarget.mType->ToTypeInstance(), prevTarget.mType->ToTypeInstance());
  6121. bool isWorse = mModule->TypeIsSubTypeOf(prevTarget.mType->ToTypeInstance(), mPropTarget.mType->ToTypeInstance());
  6122. if ((isWorse) && (!isBetter))
  6123. continue;
  6124. if (isBetter == isWorse)
  6125. {
  6126. auto error = mModule->Fail("Ambiguous property reference", nameNode->mRight);
  6127. if (error != NULL)
  6128. {
  6129. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' has a candidate", mModule->TypeToString(prevTarget.mType).c_str()), prevDef->GetRefNode());
  6130. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' has a candidate", mModule->TypeToString(mPropTarget.mType).c_str()), mPropDef->GetRefNode());
  6131. }
  6132. }
  6133. }
  6134. prevDef = mPropDef;
  6135. prevTarget = mPropTarget;
  6136. }
  6137. }
  6138. /*if ((mResult) || (mPropDef != NULL))
  6139. break;*/
  6140. }
  6141. if (mPropDef != NULL)
  6142. {
  6143. mOrigPropTarget = origResult;
  6144. if ((nameNode->mLeft->ToString() == "base") || (wasBaseLookup))
  6145. {
  6146. mPropDefBypassVirtual = true;
  6147. }
  6148. }
  6149. if ((mResult) || (mPropDef != NULL))
  6150. return;
  6151. if (hadError != NULL)
  6152. *hadError = true;
  6153. BfTypeInstance* typeInst = lookupType->ToTypeInstance();
  6154. auto compiler = mModule->mCompiler;
  6155. if ((typeInst != NULL) && (compiler->IsAutocomplete()) && (compiler->mResolvePassData->mAutoComplete->CheckFixit(nameNode->mRight)))
  6156. {
  6157. FixitAddMember(typeInst, mExpectingType, nameNode->mRight->ToString(), false);
  6158. }
  6159. mModule->Fail("Unable to find member", nameNode->mRight);
  6160. }
  6161. void BfExprEvaluator::LookupQualifiedName(BfAstNode* nameNode, BfIdentifierNode* nameLeft, BfIdentifierNode* nameRight, bool ignoreInitialError, bool* hadError)
  6162. {
  6163. String fieldName;
  6164. if (nameRight != NULL)
  6165. fieldName = nameRight->ToString();
  6166. bool wasBaseLookup = false;
  6167. if (auto qualifiedLeftName = BfNodeDynCast<BfQualifiedNameNode>(nameLeft))
  6168. {
  6169. if (qualifiedLeftName->mRight->ToString() == "base")
  6170. {
  6171. wasBaseLookup = true;
  6172. auto type = mModule->ResolveTypeRef(qualifiedLeftName->mLeft, NULL);
  6173. if (type == NULL)
  6174. return;
  6175. auto fieldName = nameRight->ToString();
  6176. auto target = mModule->GetThis();
  6177. target.mType = type;
  6178. mResult = LookupField(nameRight, target, fieldName);
  6179. if (mPropDef != NULL)
  6180. {
  6181. mPropDefBypassVirtual = true;
  6182. }
  6183. return;
  6184. }
  6185. }
  6186. if (!wasBaseLookup)
  6187. {
  6188. mResult = LookupIdentifier(nameLeft, ignoreInitialError, hadError);
  6189. if ((mResult) && (!mResult.mType->IsComposite()))
  6190. CheckResultForReading(mResult);
  6191. }
  6192. GetResult();
  6193. if (!mResult)
  6194. {
  6195. if (!ignoreInitialError)
  6196. mModule->Fail("Identifier not found", nameLeft);
  6197. return;
  6198. }
  6199. if (mResult.mType->IsObject())
  6200. {
  6201. mResult = mModule->LoadValue(mResult, 0, mIsVolatileReference);
  6202. }
  6203. else if ((mResult.mType->IsPointer()) && mResult.mType->IsStructOrStructPtr())
  6204. {
  6205. BfPointerType* structPtrType = (BfPointerType*)mResult.mType;
  6206. mResult = mModule->LoadValue(mResult, 0, mIsVolatileReference);
  6207. mResult.mType = structPtrType->mElementType;
  6208. if (mResult.mKind == BfTypedValueKind_ThisValue)
  6209. mResult.mKind = BfTypedValueKind_ThisAddr;
  6210. else
  6211. mResult.mKind = BfTypedValueKind_Addr;
  6212. }
  6213. mIsVolatileReference = false;
  6214. mIsHeapReference = false;
  6215. if (!mResult)
  6216. return;
  6217. //if (mResult.mType->IsVar())
  6218. //ResolveGenericType();
  6219. auto origResult = mResult;
  6220. auto lookupType = BindGenericType(nameNode, mResult.mType);
  6221. if (mResult.mType->IsGenericParam())
  6222. {
  6223. auto genericParamInst = mModule->GetGenericParamInstance((BfGenericParamType*)mResult.mType);
  6224. if (mModule->mCurMethodInstance->mIsUnspecialized)
  6225. {
  6226. if (genericParamInst->mTypeConstraint != NULL)
  6227. mResult.mType = genericParamInst->mTypeConstraint;
  6228. else
  6229. mResult.mType = mModule->mContext->mBfObjectType;
  6230. if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Var) != 0)
  6231. {
  6232. mResult.mType = mModule->GetPrimitiveType(BfTypeCode_Var);
  6233. }
  6234. }
  6235. else
  6236. {
  6237. if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Var) != 0)
  6238. {
  6239. //mResult.mType = mModule->ResolveGenericType(mResult.mType);
  6240. }
  6241. else if (genericParamInst->mTypeConstraint != NULL)
  6242. {
  6243. mResult = mModule->Cast(nameNode, mResult, genericParamInst->mTypeConstraint);
  6244. BF_ASSERT(mResult);
  6245. }
  6246. else
  6247. {
  6248. // This shouldn't occur - this would infer that we are accessing a member of Object or something...
  6249. //mResult.mType = mModule->ResolveGenericType(mResult.mType);
  6250. }
  6251. }
  6252. }
  6253. if (mResult.mType->IsVar())
  6254. {
  6255. mResult = BfTypedValue(mModule->GetDefaultValue(mResult.mType), mResult.mType, true);
  6256. return;
  6257. }
  6258. if (!mResult.mType->IsTypeInstance())
  6259. {
  6260. if (mResult.mType->IsSizedArray())
  6261. {
  6262. mResult.mType = mModule->GetWrappedStructType(mResult.mType);
  6263. mResult.mValue = mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->MapTypeInstPtr(mResult.mType->ToTypeInstance()));
  6264. }
  6265. else if (mResult.mType->IsWrappableType())
  6266. {
  6267. mResult.mType = mModule->GetWrappedStructType(mResult.mType);
  6268. }
  6269. else
  6270. {
  6271. if (hadError != NULL)
  6272. *hadError = true;
  6273. mModule->Fail(StrFormat("Type '%s' has no fields", mModule->TypeToString(mResult.mType).c_str()), nameLeft);
  6274. mResult = BfTypedValue();
  6275. return;
  6276. }
  6277. }
  6278. BfTypedValue lookupVal = mResult;
  6279. mResult = LookupField(nameRight, lookupVal, fieldName);
  6280. if ((!mResult) && (mPropDef == NULL) && (lookupType->IsGenericParam()))
  6281. {
  6282. auto genericParamInst = mModule->GetGenericParamInstance((BfGenericParamType*)lookupType);
  6283. SizedArray<BfTypeInstance*, 8> searchConstraints;
  6284. for (auto ifaceConstraint : genericParamInst->mInterfaceConstraints)
  6285. {
  6286. //if (std::find(searchConstraints.begin(), searchConstraints.end(), ifaceConstraint) == searchConstraints.end())
  6287. if (!searchConstraints.Contains(ifaceConstraint))
  6288. {
  6289. searchConstraints.push_back(ifaceConstraint);
  6290. for (auto& innerIFaceEntry : ifaceConstraint->mInterfaces)
  6291. {
  6292. auto innerIFace = innerIFaceEntry.mInterfaceType;
  6293. //if (std::find(searchConstraints.begin(), searchConstraints.end(), innerIFace) == searchConstraints.end())
  6294. if (!searchConstraints.Contains(innerIFace))
  6295. {
  6296. searchConstraints.push_back(innerIFace);
  6297. }
  6298. }
  6299. }
  6300. }
  6301. BfTypedValue prevTarget;
  6302. BfPropertyDef* prevDef = NULL;
  6303. for (auto ifaceConstraint : searchConstraints)
  6304. {
  6305. //auto lookupVal = mModule->GetDefaultTypedValue(ifaceConstraint, origResult.IsAddr());
  6306. BfTypedValue lookupVal = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), ifaceConstraint);
  6307. mResult = LookupField(nameRight, lookupVal, fieldName);
  6308. if (mPropDef != NULL)
  6309. {
  6310. if (prevDef != NULL)
  6311. {
  6312. bool isBetter = mModule->TypeIsSubTypeOf(mPropTarget.mType->ToTypeInstance(), prevTarget.mType->ToTypeInstance());
  6313. bool isWorse = mModule->TypeIsSubTypeOf(prevTarget.mType->ToTypeInstance(), mPropTarget.mType->ToTypeInstance());
  6314. if ((isWorse) && (!isBetter))
  6315. continue;
  6316. if (isBetter == isWorse)
  6317. {
  6318. auto error = mModule->Fail("Ambiguous property reference", nameRight);
  6319. if (error != NULL)
  6320. {
  6321. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' has a candidate", mModule->TypeToString(prevTarget.mType).c_str()), prevDef->GetRefNode());
  6322. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' has a candidate", mModule->TypeToString(mPropTarget.mType).c_str()), mPropDef->GetRefNode());
  6323. }
  6324. }
  6325. }
  6326. prevDef = mPropDef;
  6327. prevTarget = mPropTarget;
  6328. }
  6329. }
  6330. /*if ((mResult) || (mPropDef != NULL))
  6331. break;*/
  6332. }
  6333. if (mPropDef != NULL)
  6334. {
  6335. mOrigPropTarget = origResult;
  6336. if ((nameLeft->ToString() == "base") || (wasBaseLookup))
  6337. {
  6338. mPropDefBypassVirtual = true;
  6339. }
  6340. }
  6341. if ((mResult) || (mPropDef != NULL))
  6342. return;
  6343. if (hadError != NULL)
  6344. *hadError = true;
  6345. BfTypeInstance* typeInst = lookupType->ToTypeInstance();
  6346. auto compiler = mModule->mCompiler;
  6347. if ((typeInst != NULL) && (compiler->IsAutocomplete()) && (compiler->mResolvePassData->mAutoComplete->CheckFixit(nameRight)))
  6348. {
  6349. FixitAddMember(typeInst, mExpectingType, nameRight->ToString(), false);
  6350. }
  6351. mModule->Fail("Unable to find member", nameRight);
  6352. }
  6353. void BfExprEvaluator::LookupQualifiedStaticField(BfQualifiedNameNode* nameNode, bool ignoreIdentifierNotFoundError)
  6354. {
  6355. // Lookup left side as a type
  6356. {
  6357. SetAndRestoreValue<bool> prevHadIgnoreError(mModule->mHadIgnoredError, false);
  6358. BfType* type = NULL;
  6359. {
  6360. type = mModule->ResolveTypeRef(nameNode->mLeft, NULL, BfPopulateType_Data, BfResolveTypeRefFlag_AllowRef);
  6361. mModule->CheckTypeRefFixit(nameNode->mLeft);
  6362. }
  6363. if (type != NULL)
  6364. {
  6365. BfTypedValue lookupType;
  6366. if (type->IsWrappableType())
  6367. lookupType = BfTypedValue(mModule->GetWrappedStructType(type));
  6368. else
  6369. lookupType = BfTypedValue(type);
  6370. auto findName = nameNode->mRight->ToString();
  6371. /*if (findName == "base")
  6372. {
  6373. mResult = BfTypedValue(lookupType);
  6374. return;
  6375. }*/
  6376. mResult = LookupField(nameNode->mRight, lookupType, findName);
  6377. if ((mResult) || (mPropDef != NULL))
  6378. return;
  6379. if (lookupType.mType != NULL)
  6380. {
  6381. BfTypeInstance* typeInst = lookupType.mType->ToTypeInstance();
  6382. auto compiler = mModule->mCompiler;
  6383. if ((typeInst != NULL) && (compiler->IsAutocomplete()) && (compiler->mResolvePassData->mAutoComplete->CheckFixit(nameNode->mRight)))
  6384. {
  6385. FixitAddMember(typeInst, mExpectingType, nameNode->mRight->ToString(), true);
  6386. }
  6387. }
  6388. mModule->Fail("Field not found", nameNode->mRight);
  6389. return;
  6390. }
  6391. }
  6392. String fieldName = nameNode->mRight->ToString();
  6393. if (auto qualifiedLeftName = BfNodeDynCast<BfQualifiedNameNode>(nameNode->mLeft))
  6394. LookupQualifiedStaticField(qualifiedLeftName, true);
  6395. else if (auto leftName = BfNodeDynCast<BfIdentifierNode>(nameNode->mLeft))
  6396. {
  6397. mResult = LookupIdentifier(leftName);
  6398. }
  6399. GetResult();
  6400. if (!mResult)
  6401. {
  6402. if (!ignoreIdentifierNotFoundError)
  6403. mModule->Fail("Identifier not found", nameNode->mLeft);
  6404. return;
  6405. }
  6406. if (mResult.mType->IsObject())
  6407. {
  6408. mResult = mModule->LoadValue(mResult);
  6409. }
  6410. else if ((mResult.mType->IsPointer()) && mResult.mType->IsStructOrStructPtr())
  6411. {
  6412. BfPointerType* structPtrType = (BfPointerType*) mResult.mType;
  6413. mResult = mModule->LoadValue(mResult);
  6414. mResult.mType = structPtrType->mElementType;
  6415. }
  6416. if (!mResult)
  6417. return;
  6418. if (!mResult.mType->IsTypeInstance())
  6419. {
  6420. mModule->Fail(StrFormat("Type '%s' has no fields", mModule->TypeToString(mResult.mType).c_str()), nameNode->mLeft);
  6421. return;
  6422. }
  6423. mResult = LookupField(nameNode->mRight, mResult, fieldName);
  6424. if ((mResult) || (mPropDef != NULL))
  6425. return;
  6426. mModule->Fail("Unable to find member", nameNode->mRight);
  6427. }
  6428. void BfExprEvaluator::LookupQualifiedStaticField(BfAstNode* nameNode, BfIdentifierNode* nameLeft, BfIdentifierNode* nameRight, bool ignoreIdentifierNotFoundError)
  6429. {
  6430. // Lookup left side as a type
  6431. {
  6432. SetAndRestoreValue<bool> prevHadIgnoreError(mModule->mHadIgnoredError, false);
  6433. BfType* type = NULL;
  6434. {
  6435. SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
  6436. type = mModule->ResolveTypeRef(nameLeft, NULL, BfPopulateType_Data, BfResolveTypeRefFlag_AllowRef);
  6437. }
  6438. if (type != NULL)
  6439. {
  6440. BfTypedValue lookupType;
  6441. if (type->IsWrappableType())
  6442. lookupType = BfTypedValue(mModule->GetWrappedStructType(type));
  6443. else
  6444. lookupType = BfTypedValue(type);
  6445. auto findName = nameRight->ToString();
  6446. /*if (findName == "base")
  6447. {
  6448. mResult = BfTypedValue(lookupType);
  6449. return;
  6450. }*/
  6451. mResult = LookupField(nameRight, lookupType, findName);
  6452. if ((mResult) || (mPropDef != NULL))
  6453. return;
  6454. if (lookupType.mType != NULL)
  6455. {
  6456. BfTypeInstance* typeInst = lookupType.mType->ToTypeInstance();
  6457. auto compiler = mModule->mCompiler;
  6458. if ((typeInst != NULL) && (compiler->IsAutocomplete()) && (compiler->mResolvePassData->mAutoComplete->CheckFixit(nameRight)))
  6459. {
  6460. FixitAddMember(typeInst, mExpectingType, nameRight->ToString(), true);
  6461. }
  6462. }
  6463. mModule->Fail("Field not found", nameRight);
  6464. return;
  6465. }
  6466. }
  6467. String fieldName = nameRight->ToString();
  6468. if (auto qualifiedLeftName = BfNodeDynCast<BfQualifiedNameNode>(nameLeft))
  6469. LookupQualifiedStaticField(qualifiedLeftName, qualifiedLeftName->mLeft, qualifiedLeftName->mRight, true);
  6470. else if (auto leftName = BfNodeDynCast<BfIdentifierNode>(nameLeft))
  6471. {
  6472. mResult = LookupIdentifier(leftName);
  6473. }
  6474. GetResult();
  6475. if (!mResult)
  6476. {
  6477. if (!ignoreIdentifierNotFoundError)
  6478. mModule->Fail("Identifier not found", nameLeft);
  6479. return;
  6480. }
  6481. if (mResult.mType->IsObject())
  6482. {
  6483. mResult = mModule->LoadValue(mResult);
  6484. }
  6485. else if ((mResult.mType->IsPointer()) && mResult.mType->IsStructOrStructPtr())
  6486. {
  6487. BfPointerType* structPtrType = (BfPointerType*)mResult.mType;
  6488. mResult = mModule->LoadValue(mResult);
  6489. mResult.mType = structPtrType->mElementType;
  6490. }
  6491. if (!mResult)
  6492. return;
  6493. if (!mResult.mType->IsTypeInstance())
  6494. {
  6495. mModule->Fail(StrFormat("Type '%s' has no fields", mModule->TypeToString(mResult.mType).c_str()), nameLeft);
  6496. return;
  6497. }
  6498. mResult = LookupField(nameRight, mResult, fieldName);
  6499. if ((mResult) || (mPropDef != NULL))
  6500. return;
  6501. mModule->CheckTypeRefFixit(nameLeft);
  6502. mModule->Fail("Unable to find member", nameRight);
  6503. }
  6504. void BfExprEvaluator::Visit(BfQualifiedNameNode* nameNode)
  6505. {
  6506. auto autoComplete = GetAutoComplete();
  6507. if (autoComplete != NULL)
  6508. {
  6509. autoComplete->CheckMemberReference(nameNode->mLeft, nameNode->mDot, nameNode->mRight);
  6510. }
  6511. bool hadError = false;
  6512. LookupQualifiedName(nameNode, nameNode->mLeft, nameNode->mRight, true, &hadError);
  6513. if ((mResult) || (mPropDef != NULL))
  6514. return;
  6515. if (hadError)
  6516. return;
  6517. LookupQualifiedStaticField(nameNode, nameNode->mLeft, nameNode->mRight, false);
  6518. }
  6519. void BfExprEvaluator::Visit(BfThisExpression* thisExpr)
  6520. {
  6521. mResult = mModule->GetThis();
  6522. if (!mResult)
  6523. {
  6524. mModule->Fail("Static methods don't have 'this'", thisExpr);
  6525. return;
  6526. }
  6527. //if (mResult.mType->IsTypedPrimitive())
  6528. {
  6529. mResultLocalVar = mModule->GetThisVariable();
  6530. }
  6531. }
  6532. void BfExprEvaluator::Visit(BfBaseExpression* baseExpr)
  6533. {
  6534. mResult = mModule->GetThis();
  6535. if (!mResult)
  6536. {
  6537. mModule->Fail("Static methods don't have 'base'", baseExpr);
  6538. return;
  6539. }
  6540. auto baseType = mModule->mCurTypeInstance->mBaseType;
  6541. if (baseType == NULL)
  6542. baseType = mModule->mContext->mBfObjectType;
  6543. mModule->PopulateType(baseType, BfPopulateType_Data);
  6544. mResult = mModule->Cast(baseExpr, mResult, baseType, BfCastFlags_Explicit);
  6545. }
  6546. void BfExprEvaluator::Visit(BfMixinExpression* mixinExpr)
  6547. {
  6548. if (mModule->mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_Mixin)
  6549. {
  6550. auto varType = mModule->GetPrimitiveType(BfTypeCode_Var);
  6551. auto newVar = mModule->AllocFromType(varType, mModule->mCurMethodState->mCurScope);
  6552. mResult = BfTypedValue(newVar, varType, true);
  6553. return;
  6554. }
  6555. auto curMethodState = mModule->mCurMethodState;
  6556. if (curMethodState->mMixinState == NULL)
  6557. {
  6558. mModule->Fail("Mixin references can only be used within mixins", mixinExpr);
  6559. return;
  6560. }
  6561. int localIdx = GetMixinVariable();
  6562. if (localIdx != -1)
  6563. {
  6564. auto varDecl = curMethodState->mLocals[localIdx];
  6565. if (varDecl != NULL)
  6566. {
  6567. BfTypedValue localResult = LoadLocal(varDecl);
  6568. mResult = localResult;
  6569. mResultLocalVar = varDecl;
  6570. mResultLocalVarRefNode = mixinExpr;
  6571. return;
  6572. }
  6573. }
  6574. if (mModule->mCurMethodInstance->mIsUnspecialized)
  6575. {
  6576. mResult = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Var));
  6577. return;
  6578. }
  6579. mModule->Fail("Mixin value cannot be inferred", mixinExpr);
  6580. }
  6581. void BfExprEvaluator::Visit(BfSizedArrayCreateExpression* createExpr)
  6582. {
  6583. auto type = mModule->ResolveTypeRef(createExpr->mTypeRef);
  6584. if (type == NULL)
  6585. return;
  6586. if (type->IsArray())
  6587. {
  6588. // If we have a case like 'int[] (1, 2)' then we infer the sized array size from the initializer
  6589. auto arrayType = (BfArrayType*)type;
  6590. if (arrayType->mDimensions == 1)
  6591. {
  6592. int arraySize = 0;
  6593. if (auto arrayInitExpr = BfNodeDynCast<BfCollectionInitializerExpression>(createExpr->mInitializer))
  6594. {
  6595. arraySize = (int)arrayInitExpr->mValues.size();
  6596. }
  6597. type = mModule->CreateSizedArrayType(arrayType->GetUnderlyingType(), arraySize);
  6598. }
  6599. }
  6600. if (!type->IsSizedArray())
  6601. {
  6602. mModule->Fail("Sized array expected", createExpr->mTypeRef);
  6603. return;
  6604. }
  6605. BfSizedArrayType* arrayType = (BfSizedArrayType*)type;
  6606. if (createExpr->mInitializer == NULL)
  6607. {
  6608. mModule->AssertErrorState();
  6609. mResult = mModule->GetDefaultTypedValue(arrayType);
  6610. return;
  6611. }
  6612. InitializedSizedArray(arrayType, createExpr->mInitializer->mOpenBrace, createExpr->mInitializer->mValues, createExpr->mInitializer->mCommas, createExpr->mInitializer->mCloseBrace);
  6613. }
  6614. void BfExprEvaluator::Visit(BfCollectionInitializerExpression* arrayInitExpr)
  6615. {
  6616. mModule->Fail("Collection initializer not usable here", arrayInitExpr);
  6617. }
  6618. void BfExprEvaluator::Visit(BfParamsExpression* paramsExpr)
  6619. {
  6620. mModule->Fail("Params expression is only usable as a call parameter", paramsExpr);
  6621. }
  6622. void BfExprEvaluator::Visit(BfTypeOfExpression* typeOfExpr)
  6623. {
  6624. auto typeType = mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef);
  6625. auto autoComplete = GetAutoComplete();
  6626. if ((autoComplete != NULL) && (typeOfExpr->mTypeRef != NULL))
  6627. {
  6628. autoComplete->CheckTypeRef(typeOfExpr->mTypeRef, false, true);
  6629. }
  6630. BfType* type;
  6631. if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeOfExpr->mTypeRef))
  6632. {
  6633. type = mModule->ResolveTypeRefAllowUnboundGenerics(typeOfExpr->mTypeRef, BfPopulateType_Identity);
  6634. }
  6635. else
  6636. {
  6637. type = ResolveTypeRef(typeOfExpr->mTypeRef, BfPopulateType_Identity);
  6638. }
  6639. if (type == NULL)
  6640. {
  6641. mResult = mModule->GetDefaultTypedValue(mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef));
  6642. return;
  6643. }
  6644. mModule->AddDependency(type, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
  6645. mResult = BfTypedValue(mModule->CreateTypeDataRef(type), typeType);
  6646. }
  6647. bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifierNode* propName)
  6648. {
  6649. // We ignore errors because we go through the normal Visit(BfTypeOfExpression) if this fails, which will throw the error again
  6650. SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
  6651. auto typeType = mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef);
  6652. BfType* type;
  6653. if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeOfExpr->mTypeRef))
  6654. {
  6655. type = mModule->ResolveTypeRefAllowUnboundGenerics(typeOfExpr->mTypeRef, BfPopulateType_Identity);
  6656. }
  6657. else
  6658. {
  6659. type = ResolveTypeRef(typeOfExpr->mTypeRef, BfPopulateType_Identity);
  6660. }
  6661. if (type == NULL)
  6662. {
  6663. mResult = mModule->GetDefaultTypedValue(mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef));
  6664. return false;
  6665. }
  6666. mModule->AddDependency(type, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
  6667. mModule->PopulateType(type);
  6668. auto typeInstance = type->ToTypeInstance();
  6669. auto _BoolResult = [&](bool val)
  6670. {
  6671. mResult = BfTypedValue(mModule->GetConstValue8(val ? 1 : 0), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  6672. };
  6673. auto _Int32Result = [&](int32 val)
  6674. {
  6675. mResult = BfTypedValue(mModule->GetConstValue32(val), mModule->GetPrimitiveType(BfTypeCode_Int32));
  6676. };
  6677. String memberName;
  6678. propName->ToString(memberName);
  6679. bool handled = true;
  6680. if (memberName == "IsTypedPrimitive")
  6681. _BoolResult(type->IsPrimitiveType());
  6682. else if (memberName == "IsObject")
  6683. _BoolResult(type->IsObject());
  6684. else if (memberName == "IsValueType")
  6685. _BoolResult(type->IsValueType());
  6686. else if (memberName == "IsStruct")
  6687. _BoolResult(type->IsStruct());
  6688. else if (memberName == "IsSplattable")
  6689. _BoolResult(type->IsSplattable());
  6690. else if (memberName == "IsUnion")
  6691. _BoolResult(type->IsUnion());
  6692. else if (memberName == "IsBoxed")
  6693. _BoolResult(type->IsBoxed());
  6694. else if (memberName == "IsEnum")
  6695. _BoolResult(type->IsEnum());
  6696. else if (memberName == "IsTuple")
  6697. _BoolResult(type->IsTuple());
  6698. else if (memberName == "IsNullable")
  6699. _BoolResult(type->IsNullable());
  6700. else if (memberName == "IsGenericType")
  6701. _BoolResult(type->IsGenericTypeInstance());
  6702. else if (memberName == "TypeId")
  6703. _Int32Result(type->mTypeId);
  6704. else if (memberName == "GenericParamCount")
  6705. {
  6706. auto genericTypeInst = type->ToGenericTypeInstance();
  6707. _Int32Result((genericTypeInst != NULL) ? (int)genericTypeInst->mTypeGenericArguments.size() : 0);
  6708. }
  6709. else if (memberName == "Size")
  6710. _Int32Result(type->mSize);
  6711. else if (memberName == "Align")
  6712. _Int32Result(type->mAlign);
  6713. else if (memberName == "Stride")
  6714. _Int32Result(type->GetStride());
  6715. else if (memberName == "InstanceSize")
  6716. _Int32Result((typeInstance != NULL) ? typeInstance->mInstSize : type->mSize);
  6717. else if (memberName == "InstanceAlign")
  6718. _Int32Result((typeInstance != NULL) ? typeInstance->mInstAlign : type->mSize);
  6719. else if (memberName == "InstanceStride")
  6720. _Int32Result((typeInstance != NULL) ? typeInstance->GetInstStride() : type->GetStride());
  6721. else if ((memberName == "MinValue") || (memberName == "MaxValue"))
  6722. {
  6723. bool isMin = memberName == "MinValue";
  6724. BfType* checkType = typeInstance;
  6725. if (checkType->IsTypedPrimitive())
  6726. checkType = checkType->GetUnderlyingType();
  6727. if (checkType->IsPrimitiveType())
  6728. {
  6729. auto primType = (BfPrimitiveType*)checkType;
  6730. if (typeInstance->IsEnum())
  6731. {
  6732. if (typeInstance->mTypeInfoEx != NULL)
  6733. {
  6734. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? (uint64)typeInstance->mTypeInfoEx->mMinValue : (uint64)typeInstance->mTypeInfoEx->mMaxValue), typeInstance);
  6735. return true;
  6736. }
  6737. }
  6738. else
  6739. {
  6740. switch (primType->mTypeDef->mTypeCode)
  6741. {
  6742. case BfTypeCode_Int8:
  6743. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? -0x80 : 0x7F), typeInstance);
  6744. return true;
  6745. case BfTypeCode_Int16:
  6746. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? -0x8000 : 0x7FFF), typeInstance);
  6747. return true;
  6748. case BfTypeCode_Int32:
  6749. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? (uint64)-0x80000000LL : 0x7FFFFFFF), typeInstance);
  6750. return true;
  6751. case BfTypeCode_Int64:
  6752. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? (uint64)-0x8000000000000000LL : (uint64)0x7FFFFFFFFFFFFFFFLL), typeInstance);
  6753. return true;
  6754. case BfTypeCode_UInt8:
  6755. case BfTypeCode_Char8:
  6756. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? 0 : 0xFF), typeInstance);
  6757. return true;
  6758. case BfTypeCode_UInt16:
  6759. case BfTypeCode_Char16:
  6760. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? 0 : 0xFFFF), typeInstance);
  6761. return true;
  6762. case BfTypeCode_UInt32:
  6763. case BfTypeCode_Char32:
  6764. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? 0 : (uint64)0xFFFFFFFFLL), typeInstance);
  6765. return true;
  6766. case BfTypeCode_UInt64:
  6767. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? 0 : (uint64)0xFFFFFFFFFFFFFFFFLL), typeInstance);
  6768. return true;
  6769. default: break;
  6770. }
  6771. }
  6772. }
  6773. if (typeInstance->IsEnum())
  6774. {
  6775. mModule->Fail("'MinValue' cannot be used on enums with payloads", propName);
  6776. }
  6777. else
  6778. {
  6779. mModule->Fail(StrFormat("'%s' cannot be used on type '%s'", memberName.c_str(), mModule->TypeToString(typeInstance).c_str()), propName);
  6780. }
  6781. }
  6782. else
  6783. return false;
  6784. auto autoComplete = GetAutoComplete();
  6785. if ((autoComplete != NULL) && (typeOfExpr->mTypeRef != NULL))
  6786. {
  6787. autoComplete->CheckTypeRef(typeOfExpr->mTypeRef, false, true);
  6788. }
  6789. return true;
  6790. }
  6791. void BfExprEvaluator::DoTypeIntAttr(BfTypeReference* typeRef, BfToken token)
  6792. {
  6793. auto type = mModule->ResolveTypeRef(typeRef, BfPopulateType_Data, BfResolveTypeRefFlag_AutoComplete);
  6794. if (type == NULL)
  6795. return;
  6796. mModule->AddDependency(type, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage); // Local usage ensures it changes when the type data changes
  6797. auto typeInst = type->ToTypeInstance();
  6798. if ((typeInst != NULL) && (typeInst->mTypeDef->mIsOpaque))
  6799. {
  6800. mModule->Fail(StrFormat("Unable to determine attributes for opaque type '%s'", mModule->TypeToString(type).c_str()), typeRef);
  6801. }
  6802. BfType* sizeType = mModule->GetPrimitiveType(BfTypeCode_Int32);
  6803. int attrVal = 0;
  6804. switch (token)
  6805. {
  6806. case BfToken_SizeOf: attrVal = type->mSize; break;
  6807. case BfToken_AlignOf: attrVal = type->mAlign; break;
  6808. case BfToken_StrideOf: attrVal = type->GetStride(); break;
  6809. default: break;
  6810. }
  6811. bool isUndefVal = false;
  6812. if (type->IsGenericParam())
  6813. isUndefVal = true;
  6814. if (type->IsSizedArray())
  6815. {
  6816. auto sizedArray = (BfSizedArrayType*)type;
  6817. if (sizedArray->mElementCount == -1)
  6818. isUndefVal = true;
  6819. }
  6820. if (isUndefVal)
  6821. {
  6822. // We do this so we know it's a constant but we can't assume anything about its value
  6823. // We make the value an Int32 which doesn't match the IntPtr type, but it allows us to
  6824. // assume it can be implicitly cased to int32
  6825. mResult = BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(BfTypeCode_Int32), sizeType);
  6826. }
  6827. else
  6828. mResult = BfTypedValue(mModule->GetConstValue(attrVal, sizeType), sizeType);
  6829. }
  6830. void BfExprEvaluator::Visit(BfSizeOfExpression* sizeOfExpr)
  6831. {
  6832. DoTypeIntAttr(sizeOfExpr->mTypeRef, BfToken_SizeOf);
  6833. }
  6834. void BfExprEvaluator::Visit(BfAlignOfExpression* alignOfExpr)
  6835. {
  6836. DoTypeIntAttr(alignOfExpr->mTypeRef, BfToken_AlignOf);
  6837. }
  6838. void BfExprEvaluator::Visit(BfStrideOfExpression* strideOfExpr)
  6839. {
  6840. DoTypeIntAttr(strideOfExpr->mTypeRef, BfToken_StrideOf);
  6841. }
  6842. void BfExprEvaluator::Visit(BfDefaultExpression* defaultExpr)
  6843. {
  6844. auto autoComplete = GetAutoComplete();
  6845. if (autoComplete != NULL)
  6846. autoComplete->CheckTypeRef(defaultExpr->mTypeRef, false, true);
  6847. BfType* type = NULL;
  6848. if (defaultExpr->mOpenParen == NULL)
  6849. {
  6850. if (mExpectingType)
  6851. {
  6852. type = mExpectingType;
  6853. }
  6854. else
  6855. {
  6856. mModule->Fail("Type cannot be inferred, consider adding explicit type name", defaultExpr);
  6857. return;
  6858. }
  6859. }
  6860. else
  6861. type = mModule->ResolveTypeRef(defaultExpr->mTypeRef);
  6862. if (type == NULL)
  6863. return;
  6864. mModule->ValidateAllocation(type, defaultExpr->mTypeRef);
  6865. mModule->AddDependency(type, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
  6866. mResult = mModule->GetDefaultTypedValue(type);
  6867. }
  6868. void BfExprEvaluator::Visit(BfUninitializedExpression* uninitialziedExpr)
  6869. {
  6870. mModule->Fail("Invalid use of the '?' uninitialized specifier", uninitialziedExpr);
  6871. }
  6872. void BfExprEvaluator::Visit(BfCheckTypeExpression* checkTypeExpr)
  6873. {
  6874. auto targetValue = mModule->CreateValueFromExpression(checkTypeExpr->mTarget);
  6875. if (!targetValue)
  6876. return;
  6877. if (checkTypeExpr->mTypeRef == NULL)
  6878. {
  6879. mModule->AssertErrorState();
  6880. return;
  6881. }
  6882. auto autoComplete = GetAutoComplete();
  6883. if (autoComplete != NULL)
  6884. autoComplete->CheckTypeRef(checkTypeExpr->mTypeRef, false, true);
  6885. auto targetType = mModule->ResolveTypeRefAllowUnboundGenerics(checkTypeExpr->mTypeRef);
  6886. if (!targetType)
  6887. {
  6888. mModule->AssertErrorState();
  6889. return;
  6890. }
  6891. mModule->AddDependency(targetType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
  6892. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  6893. if (targetValue.mType->IsValueTypeOrValueTypePtr())
  6894. {
  6895. auto typeInstance = targetValue.mType->ToTypeInstance();
  6896. if (targetValue.mType->IsWrappableType())
  6897. typeInstance = mModule->GetWrappedStructType(targetValue.mType);
  6898. bool matches = (targetValue.mType == targetType) || (mModule->mContext->mBfObjectType == targetType);
  6899. if (!matches)
  6900. matches = mModule->TypeIsSubTypeOf(typeInstance, targetType->ToTypeInstance());
  6901. mResult = BfTypedValue(mModule->GetConstValue(matches ? 1 : 0, boolType), boolType);
  6902. return;
  6903. }
  6904. if (targetType->IsValueType())
  6905. {
  6906. if ((targetValue.mType != mModule->mContext->mBfObjectType) && (!targetValue.mType->IsInterface()))
  6907. {
  6908. mResult = BfTypedValue(mModule->GetConstValue(0, boolType), boolType);
  6909. return;
  6910. }
  6911. }
  6912. int wantTypeId = 0;
  6913. if (!targetType->IsGenericParam())
  6914. wantTypeId = targetType->mTypeId;
  6915. auto objectType = mModule->mContext->mBfObjectType;
  6916. mModule->PopulateType(objectType, BfPopulateType_Full);
  6917. targetValue = mModule->LoadValue(targetValue);
  6918. BfTypeInstance* srcTypeInstance = targetValue.mType->ToTypeInstance();
  6919. BfTypeInstance* targetTypeInstance = targetType->ToTypeInstance();
  6920. bool wasGenericParamType = false;
  6921. if ((srcTypeInstance != NULL) && (targetTypeInstance != NULL))
  6922. {
  6923. if (mModule->TypeIsSubTypeOf(srcTypeInstance, targetTypeInstance))
  6924. {
  6925. // We don't give this warning when we have wasGenericParmType set because that indicates we had a generic type constraint,
  6926. // and a type constraint infers that the ACTUAL type used will be equal to or derived from that type and therefore
  6927. // it may be a "necessary cast" indeed
  6928. if ((!wasGenericParamType) && (mModule->mCurMethodState->mMixinState == NULL))
  6929. {
  6930. if (srcTypeInstance == targetType)
  6931. mModule->Warn(BfWarning_BF4203_UnnecessaryDynamicCast, StrFormat("Unnecessary cast, the value is already type '%s'",
  6932. mModule->TypeToString(srcTypeInstance).c_str()), checkTypeExpr->mIsToken);
  6933. else
  6934. mModule->Warn(BfWarning_BF4203_UnnecessaryDynamicCast, StrFormat("Unnecessary cast, '%s' is a subtype of '%s'",
  6935. mModule->TypeToString(srcTypeInstance).c_str(), mModule->TypeToString(targetType).c_str()), checkTypeExpr->mIsToken);
  6936. }
  6937. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 1), boolType);
  6938. return;
  6939. }
  6940. else if ((!targetType->IsInterface()) && (srcTypeInstance != mModule->mContext->mBfObjectType) && (!mModule->TypeIsSubTypeOf(targetTypeInstance, srcTypeInstance)))
  6941. {
  6942. mModule->Fail(StrFormat("Cannot convert type '%s' to '%s' via any conversion",
  6943. mModule->TypeToString(targetValue.mType).c_str(), mModule->TypeToString(targetTypeInstance).c_str()), checkTypeExpr->mIsToken);
  6944. }
  6945. }
  6946. if (mModule->mCompiler->IsAutocomplete())
  6947. {
  6948. mResult = mModule->GetDefaultTypedValue(boolType, false, BfDefaultValueKind_Addr);
  6949. return;
  6950. }
  6951. auto irb = mModule->mBfIRBuilder;
  6952. auto prevBB = mModule->mBfIRBuilder->GetInsertBlock();
  6953. auto matchBB = mModule->mBfIRBuilder->CreateBlock("is.match");
  6954. auto endBB = mModule->mBfIRBuilder->CreateBlock("is.done");
  6955. BfIRValue boolResult = mModule->CreateAlloca(boolType);
  6956. irb->CreateStore(irb->CreateConst(BfTypeCode_Boolean, 0), boolResult);
  6957. mModule->EmitDynamicCastCheck(targetValue, targetType, matchBB, endBB);
  6958. mModule->AddBasicBlock(matchBB);
  6959. irb->CreateStore(irb->CreateConst(BfTypeCode_Boolean, 1), boolResult);
  6960. irb->CreateBr(endBB);
  6961. mModule->AddBasicBlock(endBB);
  6962. mResult = BfTypedValue(irb->CreateLoad(boolResult), boolType);
  6963. }
  6964. void BfExprEvaluator::Visit(BfDynamicCastExpression* dynCastExpr)
  6965. {
  6966. auto targetValue = mModule->CreateValueFromExpression(dynCastExpr->mTarget);
  6967. auto targetType = mModule->ResolveTypeRefAllowUnboundGenerics(dynCastExpr->mTypeRef, BfPopulateType_Data, false);
  6968. auto autoComplete = GetAutoComplete();
  6969. if (autoComplete != NULL)
  6970. {
  6971. autoComplete->CheckTypeRef(dynCastExpr->mTypeRef, false, true);
  6972. }
  6973. if (!targetValue)
  6974. return;
  6975. if (!targetType)
  6976. {
  6977. mModule->AssertErrorState();
  6978. return;
  6979. }
  6980. bool wasGenericParamType = false;
  6981. if (targetType->IsGenericParam())
  6982. {
  6983. //targetType = mModule->ResolveGenericType(targetType);
  6984. //wasGenericParamType = true;
  6985. }
  6986. if ((targetValue.mType->IsMethodRef()) || (targetType->IsMethodRef()))
  6987. {
  6988. // We can never cast a MethodRef to any class type
  6989. mResult = mModule->GetDefaultTypedValue(targetType);
  6990. return;
  6991. }
  6992. if (mModule->mContext->mResolvingVarField)
  6993. {
  6994. mResult = mModule->GetDefaultTypedValue(targetType);
  6995. return;
  6996. }
  6997. mModule->AddDependency(targetType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
  6998. if (targetType->IsGenericParam())
  6999. {
  7000. wasGenericParamType = true;
  7001. //wasGenericParamType = false; // "was", not "is"
  7002. auto genericParamType = (BfGenericParamType*) targetType;
  7003. auto genericParam = mModule->GetGenericParamInstance(genericParamType);
  7004. auto typeConstraint = genericParam->mTypeConstraint;
  7005. if ((typeConstraint == NULL) && (genericParam->mGenericParamFlags & BfGenericParamFlag_Class))
  7006. typeConstraint = mModule->mContext->mBfObjectType;
  7007. if ((typeConstraint == NULL) || (!typeConstraint->IsObject()))
  7008. {
  7009. 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' constraint",
  7010. genericParam->GetGenericParamDef()->mName.c_str()), dynCastExpr->mTypeRef);
  7011. return;
  7012. }
  7013. targetType = typeConstraint;
  7014. targetValue = mModule->GetDefaultTypedValue(targetType);
  7015. }
  7016. if ((!targetType->IsObjectOrInterface()) && (!targetType->IsNullable()))
  7017. {
  7018. mModule->Fail(StrFormat("The as operator must be used with a reference type or nullable type ('%s' is a non-nullable value type)",
  7019. mModule->TypeToString(targetType).c_str()), dynCastExpr->mTypeRef);
  7020. return;
  7021. }
  7022. if (targetValue.mType->IsGenericParam())
  7023. {
  7024. auto genericParamType = (BfGenericParamType*)targetValue.mType;
  7025. auto genericParam = mModule->GetGenericParamInstance(genericParamType);
  7026. auto typeConstraint = genericParam->mTypeConstraint;
  7027. if (typeConstraint == NULL)
  7028. typeConstraint = mModule->mContext->mBfObjectType;
  7029. if ((typeConstraint->IsDelegate()) && (typeConstraint == targetType))
  7030. {
  7031. // Delegate constraints may be matched by valueless method references, so this won't always match (don't warn)
  7032. mResult = mModule->GetDefaultTypedValue(targetType);
  7033. return;
  7034. }
  7035. //targetType = typeConstraint;
  7036. targetValue = mModule->GetDefaultTypedValue(typeConstraint);
  7037. }
  7038. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  7039. if (targetValue.mType->IsValueTypeOrValueTypePtr())
  7040. {
  7041. mModule->Warn(0, StrFormat("Type '%s' is not applicable for dynamic casting",
  7042. mModule->TypeToString(targetValue.mType).c_str()), dynCastExpr->mAsToken);
  7043. auto typeInstance = targetValue.mType->ToTypeInstance();
  7044. if (targetValue.mType->IsWrappableType())
  7045. typeInstance = mModule->GetWrappedStructType(targetValue.mType);
  7046. bool matches = (targetValue.mType == targetType) || (mModule->mContext->mBfObjectType == targetType);
  7047. if (targetType->IsNullable())
  7048. {
  7049. auto elementType = targetType->GetUnderlyingType();
  7050. if (elementType == targetValue.mType)
  7051. {
  7052. // We match nullable element
  7053. auto allocaInst = mModule->CreateAlloca(targetType);
  7054. auto hasValueAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, 1); // has_value
  7055. mModule->mBfIRBuilder->CreateStore(mModule->GetConstValue(1, boolType), hasValueAddr);
  7056. hasValueAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, 0); // value
  7057. mModule->mBfIRBuilder->CreateStore(targetValue.mValue, hasValueAddr);
  7058. mResult = BfTypedValue(allocaInst, targetType, true);
  7059. return;
  7060. }
  7061. }
  7062. if (!matches)
  7063. matches = mModule->TypeIsSubTypeOf(typeInstance, targetType->ToTypeInstance());
  7064. if (matches)
  7065. mResult = mModule->Cast(dynCastExpr, targetValue, targetType, BfCastFlags_Explicit);
  7066. else if (targetType->IsNullable())
  7067. {
  7068. auto allocaInst = mModule->CreateAlloca(targetType);
  7069. auto allocaBits = mModule->mBfIRBuilder->CreateBitCast(allocaInst, mModule->mBfIRBuilder->GetPrimitiveType(BfTypeCode_NullPtr));
  7070. mModule->mBfIRBuilder->CreateMemSet(allocaBits, mModule->GetConstValue(0, mModule->GetPrimitiveType(BfTypeCode_Int8)),
  7071. mModule->GetConstValue(targetType->mSize), targetType->mAlign);
  7072. mResult = BfTypedValue(allocaInst, targetType, true);
  7073. }
  7074. else
  7075. mResult = BfTypedValue(mModule->GetDefaultValue(targetType), targetType);
  7076. return;
  7077. }
  7078. if (targetType->IsNullable())
  7079. {
  7080. if (autoComplete != NULL)
  7081. {
  7082. mResult = mModule->GetDefaultTypedValue(targetType);
  7083. return;
  7084. }
  7085. auto elementType = targetType->GetUnderlyingType();
  7086. auto allocaInst = mModule->CreateAlloca(targetType);
  7087. auto hasValueAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, elementType->IsValuelessType() ? 1 : 2); // has_value
  7088. mModule->mBfIRBuilder->CreateStore(mModule->GetConstValue(0, boolType), hasValueAddr);
  7089. auto objectType = mModule->mContext->mBfObjectType;
  7090. auto prevBB = mModule->mBfIRBuilder->GetInsertBlock();
  7091. auto matchBB = mModule->mBfIRBuilder->CreateBlock("as.match");
  7092. auto endBB = mModule->mBfIRBuilder->CreateBlock("as.end");
  7093. mModule->EmitDynamicCastCheck(targetValue, elementType, matchBB, endBB);
  7094. BfBoxedType* boxedType = mModule->CreateBoxedType(elementType);
  7095. mModule->AddBasicBlock(matchBB);
  7096. if (elementType->IsValuelessType())
  7097. {
  7098. auto hasValueAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, 1); // has_value
  7099. mModule->mBfIRBuilder->CreateStore(mModule->GetConstValue(1, boolType), hasValueAddr);
  7100. }
  7101. else
  7102. {
  7103. auto hasValueAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, 2); // has_value
  7104. mModule->mBfIRBuilder->CreateStore(mModule->GetConstValue(1, boolType), hasValueAddr);
  7105. auto nullableValueAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, 1); // value
  7106. auto srcBoxedType = mModule->mBfIRBuilder->CreateBitCast(targetValue.mValue, mModule->mBfIRBuilder->MapType(boxedType, BfIRPopulateType_Full));
  7107. auto boxedValueAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(srcBoxedType, 0, 1); // mValue
  7108. auto boxedValue = mModule->mBfIRBuilder->CreateLoad(boxedValueAddr);
  7109. mModule->mBfIRBuilder->CreateStore(boxedValue, nullableValueAddr);
  7110. }
  7111. mModule->mBfIRBuilder->CreateBr(endBB);
  7112. mModule->AddBasicBlock(endBB);
  7113. mResult = BfTypedValue(allocaInst, targetType, true);
  7114. return;
  7115. }
  7116. targetValue = mModule->LoadValue(targetValue);
  7117. if (targetType->IsValueType())
  7118. {
  7119. mModule->Fail("Invalid dynamic cast type", dynCastExpr->mTypeRef);
  7120. return;
  7121. }
  7122. BfTypeInstance* srcTypeInstance = targetValue.mType->ToTypeInstance();
  7123. BfTypeInstance* targetTypeInstance = targetType->ToTypeInstance();
  7124. if (mModule->TypeIsSubTypeOf(srcTypeInstance, targetTypeInstance))
  7125. {
  7126. // We don't give this warning when we have wasGenericParmType set because that indicates we had a generic type constraint,
  7127. // and a type constraint infers that the ACTUAL type used will be equal to or derived from that type and therefore
  7128. // it may be a "necessary cast" indeed
  7129. if ((!wasGenericParamType) && (mModule->mCurMethodState->mMixinState == NULL))
  7130. {
  7131. if (srcTypeInstance == targetType)
  7132. mModule->Warn(BfWarning_BF4203_UnnecessaryDynamicCast, StrFormat("Unnecessary cast, the value is already type '%s'",
  7133. mModule->TypeToString(srcTypeInstance).c_str()), dynCastExpr->mAsToken);
  7134. else
  7135. mModule->Warn(BfWarning_BF4203_UnnecessaryDynamicCast, StrFormat("Unnecessary cast, '%s' is a subtype of '%s'",
  7136. mModule->TypeToString(srcTypeInstance).c_str(), mModule->TypeToString(targetType).c_str()), dynCastExpr->mAsToken);
  7137. }
  7138. auto castedValue = mModule->mBfIRBuilder->CreateBitCast(targetValue.mValue, mModule->mBfIRBuilder->MapType(targetTypeInstance));
  7139. mResult = BfTypedValue(castedValue, targetTypeInstance);
  7140. return;
  7141. }
  7142. else if ((!targetType->IsInterface()) && (!mModule->TypeIsSubTypeOf(targetTypeInstance, srcTypeInstance)))
  7143. {
  7144. mModule->Fail(StrFormat("Cannot convert type '%s' to '%s' via any conversion",
  7145. mModule->TypeToString(targetValue.mType).c_str(), mModule->TypeToString(targetTypeInstance).c_str()), dynCastExpr->mAsToken);
  7146. }
  7147. if (autoComplete != NULL)
  7148. {
  7149. mResult = mModule->GetDefaultTypedValue(targetType);
  7150. return;
  7151. }
  7152. auto irb = mModule->mBfIRBuilder;
  7153. auto objectType = mModule->mContext->mBfObjectType;
  7154. mModule->PopulateType(objectType, BfPopulateType_Full);
  7155. auto prevBB = mModule->mBfIRBuilder->GetInsertBlock();
  7156. auto endBB = mModule->mBfIRBuilder->CreateBlock("as.end");
  7157. auto matchBlock = irb->CreateBlock("as.match");
  7158. BfIRValue targetVal = mModule->CreateAlloca(targetType);
  7159. irb->CreateStore(irb->CreateConstNull(irb->MapType(targetType)), targetVal);
  7160. mModule->EmitDynamicCastCheck(targetValue, targetType, matchBlock, endBB);
  7161. mModule->AddBasicBlock(matchBlock);
  7162. BfIRValue castedCallResult = mModule->mBfIRBuilder->CreateBitCast(targetValue.mValue, mModule->mBfIRBuilder->MapType(targetType));
  7163. irb->CreateStore(castedCallResult, targetVal);
  7164. irb->CreateBr(endBB);
  7165. mModule->AddBasicBlock(endBB);
  7166. mResult = BfTypedValue(irb->CreateLoad(targetVal), targetType);
  7167. }
  7168. void BfExprEvaluator::Visit(BfCastExpression* castExpr)
  7169. {
  7170. auto autoComplete = GetAutoComplete();
  7171. if ((autoComplete != NULL) && (castExpr->mTypeRef != NULL))
  7172. {
  7173. // 'mayBeIdentifier' because this may be a misidentified cast - it could be a parenthesized expression
  7174. autoComplete->CheckTypeRef(castExpr->mTypeRef, true, true);
  7175. }
  7176. BfType* resolvedType = NULL;
  7177. if ((BfNodeDynCastExact<BfDotTypeReference>(castExpr->mTypeRef) != NULL) && (mExpectingType != NULL))
  7178. {
  7179. //mModule->SetElementType(castExpr->mTypeRef, BfSourceElementType_TypeRef);
  7180. resolvedType = mExpectingType;
  7181. }
  7182. else
  7183. resolvedType = ResolveTypeRef(castExpr->mTypeRef);
  7184. if (resolvedType != NULL)
  7185. mModule->AddDependency(resolvedType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage);
  7186. // If resolvedType is NULL then that's okay- we just leave the following expression uncasted
  7187. if (castExpr->mExpression == NULL)
  7188. {
  7189. mModule->AssertErrorState();
  7190. return;
  7191. }
  7192. mResult = mModule->CreateValueFromExpression(castExpr->mExpression, resolvedType, (BfEvalExprFlags)(BfEvalExprFlags_ExplicitCast));
  7193. }
  7194. bool BfExprEvaluator::IsExactMethodMatch(BfMethodInstance* methodA, BfMethodInstance* methodB, bool ignoreImplicitParams)
  7195. {
  7196. if (methodA->mReturnType != methodB->mReturnType)
  7197. return false;
  7198. int implicitParamCountA = methodA->GetImplicitParamCount();
  7199. int implicitParamCountB = methodB->GetImplicitParamCount();
  7200. if (methodA->GetParamCount() - implicitParamCountA != methodB->GetParamCount() - implicitParamCountB)
  7201. return false;
  7202. for (int i = 0; i < (int)methodA->GetParamCount() - implicitParamCountA; i++)
  7203. {
  7204. auto paramA = methodA->GetParamType(i + implicitParamCountA);
  7205. auto paramB = methodB->GetParamType(i + implicitParamCountB);
  7206. if (paramA != paramB)
  7207. return false;
  7208. }
  7209. return true;
  7210. }
  7211. void BfExprEvaluator::ConstResolve(BfExpression* expr)
  7212. {
  7213. BfConstResolver constResolver(mModule);
  7214. constResolver.Resolve(expr);
  7215. mResult = constResolver.mResult;
  7216. }
  7217. BfTypeInstance* BfExprEvaluator::VerifyBaseDelegateType(BfTypeInstance* baseDelegateType)
  7218. {
  7219. mModule->PopulateType(baseDelegateType, BfPopulateType_DataAndMethods);
  7220. if (baseDelegateType->mFieldInstances.size() != 2)
  7221. {
  7222. mModule->AssertErrorState();
  7223. return NULL;
  7224. }
  7225. return baseDelegateType;
  7226. }
  7227. bool BfExprEvaluator::CanBindDelegate(BfDelegateBindExpression* delegateBindExpr, BfMethodInstance** boundMethod)
  7228. {
  7229. if (mExpectingType == NULL)
  7230. {
  7231. return false;
  7232. }
  7233. auto typeInstance = mExpectingType->ToTypeInstance();
  7234. if ((typeInstance == NULL) || (!typeInstance->mTypeDef->mIsDelegate))
  7235. return false;
  7236. mModule->PopulateType(typeInstance, BfPopulateType_DataAndMethods);
  7237. auto methodInstance = mModule->GetRawMethodInstanceAtIdx(typeInstance, 0, "Invoke");
  7238. if (methodInstance == NULL)
  7239. {
  7240. BF_DBG_FATAL("Invoke not found");
  7241. return false;
  7242. }
  7243. if (delegateBindExpr->mTarget == NULL)
  7244. return false;
  7245. BfAutoParentNodeEntry autoParentNodeEntry(mModule, delegateBindExpr);
  7246. SizedArray<BfTypedValueExpression, 4> typedValueExprs;
  7247. typedValueExprs.resize(methodInstance->GetParamCount());
  7248. SizedArray<BfExpression*, 4> args;
  7249. args.resize(methodInstance->GetParamCount());
  7250. for (int i = 0; i < (int) methodInstance->GetParamCount(); i++)
  7251. {
  7252. auto typedValueExpr = &typedValueExprs[i];
  7253. typedValueExpr->mTypedValue.mType = methodInstance->GetParamType(i);
  7254. typedValueExpr->mRefNode = NULL;
  7255. args[i] = typedValueExpr;
  7256. }
  7257. BfSizedArray<ASTREF(BfTypeReference*)>* methodGenericArguments = NULL;
  7258. if (delegateBindExpr->mGenericArgs != NULL)
  7259. methodGenericArguments = &delegateBindExpr->mGenericArgs->mGenericArgs;
  7260. BfFunctionBindResult bindResult;
  7261. bindResult.mSkipMutCheck = true; // Allow operating on copies
  7262. mFunctionBindResult = &bindResult;
  7263. SetAndRestoreValue<bool> ignoreError(mModule->mIgnoreErrors, true);
  7264. DoInvocation(delegateBindExpr->mTarget, delegateBindExpr, args, methodGenericArguments);
  7265. mFunctionBindResult = NULL;
  7266. if (bindResult.mMethodInstance == NULL)
  7267. return false;
  7268. if (boundMethod != NULL)
  7269. *boundMethod = bindResult.mMethodInstance;
  7270. return IsExactMethodMatch(methodInstance, bindResult.mMethodInstance, true);
  7271. }
  7272. BfTypedValue BfExprEvaluator::DoImplicitArgCapture(BfAstNode* refNode, BfIdentifierNode* identifierNode)
  7273. {
  7274. String findName = identifierNode->ToString();
  7275. if (mModule->mCurMethodState != NULL)
  7276. {
  7277. auto rootMethodState = mModule->mCurMethodState->GetRootMethodState();
  7278. auto checkMethodState = mModule->mCurMethodState;
  7279. bool isMixinOuterVariablePass = false;
  7280. while (checkMethodState != NULL)
  7281. {
  7282. BP_ZONE("LookupIdentifier:DoImplicitArgCapture");
  7283. BfTypeInstance* closureTypeInst = NULL;
  7284. BfClosureInstanceInfo* closureInstanceInfo = NULL;
  7285. if ((checkMethodState->mClosureState != NULL) && (checkMethodState->mClosureState->mClosureType != NULL) && (!checkMethodState->mClosureState->mCapturing))
  7286. {
  7287. closureTypeInst = mModule->mCurMethodState->mClosureState->mClosureType;
  7288. }
  7289. BfLocalVarEntry* entry;
  7290. if (checkMethodState->mLocalVarSet.TryGetWith<StringImpl&>(findName, &entry))
  7291. {
  7292. auto varDecl = entry->mLocalVar;
  7293. while (varDecl != NULL)
  7294. {
  7295. // if ((closureTypeInst != NULL) && (wantName == "this"))
  7296. // break;
  7297. if (varDecl->mNameNode == identifierNode)
  7298. {
  7299. BfTypedValue localResult = LoadLocal(varDecl);
  7300. // auto autoComplete = GetAutoComplete();
  7301. // if (identifierNode != NULL)
  7302. // {
  7303. // if (autoComplete != NULL)
  7304. // autoComplete->CheckLocalRef(identifierNode, varDecl);
  7305. // if (((mModule->mCurMethodState->mClosureState == NULL) || (mModule->mCurMethodState->mClosureState->mCapturing)) &&
  7306. // (mModule->mCompiler->mResolvePassData != NULL) && (mModule->mCurMethodInstance != NULL))
  7307. // mModule->mCompiler->mResolvePassData->HandleLocalReference(identifierNode, varDecl->mNameNode, mModule->mCurTypeInstance->mTypeDef, rootMethodState->mMethodInstance->mMethodDef, varDecl->mLocalVarId);
  7308. // }
  7309. //
  7310. if (!isMixinOuterVariablePass)
  7311. {
  7312. mResultLocalVar = varDecl;
  7313. mResultLocalVarRefNode = identifierNode;
  7314. }
  7315. return localResult;
  7316. }
  7317. varDecl = varDecl->mShadowedLocal;
  7318. }
  7319. }
  7320. // Check for the captured locals. It's important we do it here so we get local-first precedence still
  7321. if (closureTypeInst != NULL)
  7322. {
  7323. closureTypeInst->mTypeDef->PopulateMemberSets();
  7324. BfMemberSetEntry* memberSetEntry = NULL;
  7325. if (closureTypeInst->mTypeDef->mFieldSet.TryGetWith(findName, &memberSetEntry))
  7326. {
  7327. auto fieldDef = (BfFieldDef*)memberSetEntry->mMemberDef;
  7328. while (fieldDef != NULL)
  7329. {
  7330. BfIdentifierNode* fieldNameNode = NULL;
  7331. if (fieldDef->mIdx < (int)checkMethodState->mClosureState->mClosureInstanceInfo->mCaptureEntries.size())
  7332. fieldNameNode = checkMethodState->mClosureState->mClosureInstanceInfo->mCaptureEntries[fieldDef->mIdx].mNameNode;
  7333. if (fieldNameNode == identifierNode)
  7334. {
  7335. auto& field = closureTypeInst->mFieldInstances[fieldDef->mIdx];
  7336. if (!field.mResolvedType->IsValuelessType())
  7337. {
  7338. if (mModule->mCurMethodState->mClosureState->mCapturing)
  7339. {
  7340. mModule->mCurMethodState->mClosureState->mReferencedOuterClosureMembers.Add(&field);
  7341. return mModule->GetDefaultTypedValue(field.mResolvedType);
  7342. }
  7343. auto localVar = mModule->mCurMethodState->mLocals[0];
  7344. auto thisValue = localVar->mValue;
  7345. mModule->mBfIRBuilder->PopulateType(localVar->mResolvedType);
  7346. BfTypedValue result = BfTypedValue(mModule->mBfIRBuilder->CreateInBoundsGEP(thisValue, 0, field.mDataIdx), field.mResolvedType, true);
  7347. if (field.mResolvedType->IsRef())
  7348. {
  7349. auto refType = (BfRefType*)field.mResolvedType;
  7350. auto underlyingType = refType->GetUnderlyingType();
  7351. result = BfTypedValue(mModule->mBfIRBuilder->CreateLoad(result.mValue), underlyingType, true);
  7352. }
  7353. else if (fieldDef->mIsReadOnly)
  7354. result = mModule->LoadValue(result);
  7355. mResultLocalVar = localVar;
  7356. mResultLocalVarField = -(field.mMergedDataIdx + 1);
  7357. return result;
  7358. }
  7359. }
  7360. fieldDef = fieldDef->mNextWithSameName;
  7361. }
  7362. }
  7363. }
  7364. if ((checkMethodState->mClosureState != NULL) && (checkMethodState->mClosureState->mCapturing) /*&& (checkMethodState->mClosureState->mIsLocalMethod)*/)
  7365. {
  7366. checkMethodState = checkMethodState->mPrevMethodState;
  7367. continue;
  7368. }
  7369. // Allow local mixin to see outside variables during its processing -- since we don't actually "capture" those into params
  7370. bool isLocalMixinProcessing = false;
  7371. if ((checkMethodState->mClosureState != NULL) && (!checkMethodState->mClosureState->mCapturing) && (closureTypeInst == NULL) &&
  7372. (mModule->mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_Mixin))
  7373. isLocalMixinProcessing = true;
  7374. if (!isLocalMixinProcessing)
  7375. break;
  7376. isMixinOuterVariablePass = true;
  7377. checkMethodState = checkMethodState->mPrevMethodState;
  7378. }
  7379. }
  7380. return BfTypedValue();
  7381. }
  7382. BfTypedValue BfExprEvaluator::DoImplicitArgCapture(BfAstNode* refNode, BfMethodInstance* methodInstance, int paramIdx, bool& failed, BfImplicitParamKind paramKind, const BfTypedValue& methodRefTarget)
  7383. {
  7384. if ((methodRefTarget) && (methodRefTarget.mValue.mId != BfIRValue::ID_IMPLICIT))
  7385. {
  7386. if (methodRefTarget.mType->IsMethodRef())
  7387. {
  7388. BfMethodRefType* methodRefType = (BfMethodRefType*)methodRefTarget.mType;
  7389. BfMethodInstance* methodRefMethodInst = methodRefType->mMethodRef;
  7390. BF_ASSERT(methodRefMethodInst == methodInstance);
  7391. auto paramType = methodInstance->GetParamType(paramIdx);
  7392. int dataIdx = methodRefType->GetDataIdxFromParamIdx(paramIdx);
  7393. if (dataIdx == -1)
  7394. {
  7395. BF_ASSERT(paramType->IsValuelessType());
  7396. return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), paramType);
  7397. }
  7398. if (methodRefTarget.IsSplat())
  7399. {
  7400. if (methodRefType->WantsDataPassedAsSplat(dataIdx))
  7401. {
  7402. BF_ASSERT(paramIdx == -1);
  7403. return BfTypedValue(methodRefTarget.mValue, paramType, BfTypedValueKind_SplatHead);
  7404. }
  7405. else
  7406. {
  7407. int splatIdx = dataIdx;
  7408. if (dataIdx > 0)
  7409. {
  7410. if (methodRefType->WantsDataPassedAsSplat(0))
  7411. splatIdx += methodRefType->GetCaptureType(0)->GetSplatCount() - 1;
  7412. }
  7413. bool isAddr = false;
  7414. BfIRValue value = mModule->ExtractSplatValue(methodRefTarget, splatIdx, paramType, &isAddr);
  7415. // We moved the composite load from ExtractSplatValue to here. Hopefully this is correct.
  7416. // 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)
  7417. // if ((paramType->IsComposite()) && (mModule->IsTargetingBeefBackend()))
  7418. // value = mModule->mBfIRBuilder->CreateLoad(value);
  7419. auto lookupVal = BfTypedValue(value, paramType, isAddr);
  7420. if ((isAddr) && (!lookupVal.mType->IsComposite()))
  7421. lookupVal = mModule->LoadValue(lookupVal);
  7422. return lookupVal;
  7423. }
  7424. }
  7425. BF_ASSERT(methodRefTarget.IsAddr());
  7426. if (paramType->IsComposite())
  7427. return BfTypedValue(mModule->mBfIRBuilder->CreateInBoundsGEP(methodRefTarget.mValue, 0, dataIdx), paramType, true);
  7428. return BfTypedValue(mModule->ExtractValue(methodRefTarget, dataIdx), paramType);
  7429. }
  7430. }
  7431. // 'Default' implicit arg lookup, by identifier. May match field (for lambda), or local variable
  7432. if (paramKind == BfImplicitParamKind_General)
  7433. {
  7434. if (paramIdx == -1)
  7435. {
  7436. if (auto delegateBindExpr = BfNodeDynCast<BfDelegateBindExpression>(refNode))
  7437. {
  7438. BfAstNode* thisNode = NULL;
  7439. BfTypedValue thisValue;
  7440. if (auto memberReferenceExpr = BfNodeDynCast<BfMemberReferenceExpression>(delegateBindExpr->mTarget))
  7441. thisNode = memberReferenceExpr->mTarget;
  7442. else if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(delegateBindExpr->mTarget))
  7443. thisNode = qualifiedNameNode->mLeft;
  7444. else if (auto identifierNode = BfNodeDynCast<BfIdentifierNode>(delegateBindExpr->mTarget))
  7445. {
  7446. // Implicit
  7447. thisValue = mModule->GetThis();
  7448. }
  7449. if (auto thisExpr = BfNodeDynCast<BfExpression>(thisNode))
  7450. {
  7451. thisValue = mModule->CreateValueFromExpression(thisExpr);
  7452. if (!thisValue)
  7453. return BfTypedValue();
  7454. }
  7455. if (thisValue)
  7456. {
  7457. //TODO: handle 'mut', throw error if trying to capture from a non-mut, etc...
  7458. return thisValue;
  7459. }
  7460. }
  7461. }
  7462. String captureName = methodInstance->GetParamName(paramIdx);
  7463. BfIdentifierNode* identifierNode = methodInstance->GetParamNameNode(paramIdx);
  7464. BfTypedValue lookupVal;
  7465. if (identifierNode != NULL)
  7466. {
  7467. lookupVal = DoImplicitArgCapture(refNode, identifierNode);
  7468. }
  7469. else
  7470. {
  7471. lookupVal = LookupIdentifier(NULL, captureName);
  7472. }
  7473. if (lookupVal)
  7474. {
  7475. auto paramType = methodInstance->GetParamType(paramIdx);
  7476. if (paramType->IsRef())
  7477. {
  7478. auto refType = (BfRefType*)paramType;
  7479. if (mResultLocalVar != NULL)
  7480. {
  7481. // When we are capturing, we need to note that we require capturing by reference here
  7482. auto localVar = mResultLocalVar;
  7483. localVar->mWrittenToId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++;
  7484. }
  7485. bool isValid = false;
  7486. if ((refType->mRefKind == BfRefType::RefKind_Mut) && (lookupVal.mKind == BfTypedValueKind_MutableValue))
  7487. isValid = true;
  7488. if ((lookupVal.mType->IsRef()) || (lookupVal.IsAddr()))
  7489. isValid = true;
  7490. if (!isValid)
  7491. {
  7492. // Is there another way this can fail than to be in a lambda?
  7493. auto error = mModule->Fail(StrFormat("Method '%s' requires that '%s' be captured by reference. Consider adding by-reference capture specifier [&] to lambda.",
  7494. mModule->MethodToString(methodInstance).c_str(), captureName.c_str()), refNode, true);
  7495. if ((error != NULL) && (methodInstance->mMethodDef->mMethodDeclaration != NULL))
  7496. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
  7497. failed = true;
  7498. }
  7499. }
  7500. else
  7501. {
  7502. if (lookupVal.mType->IsRef())
  7503. lookupVal = mModule->RemoveRef(lookupVal);
  7504. if (!lookupVal.mType->IsComposite())
  7505. lookupVal = mModule->LoadValue(lookupVal);
  7506. }
  7507. return lookupVal;
  7508. }
  7509. else
  7510. {
  7511. mModule->Fail(StrFormat("Failed to lookup implicit capture '%s'", captureName.c_str()), refNode, true);
  7512. failed = true;
  7513. return BfTypedValue();
  7514. }
  7515. }
  7516. return BfTypedValue();
  7517. }
  7518. void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
  7519. {
  7520. BfAutoParentNodeEntry autoParentNodeEntry(mModule, delegateBindExpr);
  7521. if (mExpectingType == NULL)
  7522. {
  7523. mModule->Fail("Cannot infer delegate type", delegateBindExpr);
  7524. return;
  7525. }
  7526. BfTokenNode* newToken = NULL;
  7527. BfAllocTarget allocTarget = ResolveAllocTarget(delegateBindExpr->mNewToken, newToken);
  7528. SizedArray<BfTypedValueExpression, 4> typedValueExprs;
  7529. SizedArray<BfExpression*, 4> args;
  7530. BfTypeInstance* delegateTypeInstance = NULL;
  7531. BfMethodInstance* methodInstance = NULL;
  7532. const char* bindTypeName = NULL;
  7533. bool isMethodRefMatch = false;
  7534. if (mExpectingType->IsMethodRef())
  7535. {
  7536. auto methodRefType = (BfMethodRefType*)mExpectingType;
  7537. BF_ASSERT(delegateBindExpr->mNewToken == NULL);
  7538. methodInstance = methodRefType->mMethodRef;
  7539. isMethodRefMatch = true;
  7540. }
  7541. else
  7542. {
  7543. if (mExpectingType->IsGenericParam())
  7544. {
  7545. auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)mExpectingType);
  7546. if ((genericParamInstance->mTypeConstraint != NULL) && (genericParamInstance->mTypeConstraint->IsDelegate()))
  7547. {
  7548. delegateTypeInstance = genericParamInstance->mTypeConstraint->ToTypeInstance();
  7549. }
  7550. }
  7551. else
  7552. delegateTypeInstance = mExpectingType->ToTypeInstance();
  7553. if ((delegateTypeInstance == NULL) ||
  7554. ((!delegateTypeInstance->IsDelegate()) && (!delegateTypeInstance->IsFunction())))
  7555. {
  7556. mModule->Fail(StrFormat("Type '%s' cannot be used for method binding. Only delegate or function types are allowed.", mModule->TypeToString(mExpectingType).c_str()), delegateBindExpr);
  7557. return;
  7558. }
  7559. bindTypeName = (delegateTypeInstance->IsDelegate()) ? "delegate" : "function";
  7560. mModule->PopulateType(delegateTypeInstance, BfPopulateType_DataAndMethods);
  7561. methodInstance = mModule->GetRawMethodInstanceAtIdx(delegateTypeInstance, 0, "Invoke");
  7562. if (methodInstance == NULL)
  7563. {
  7564. BF_DBG_FATAL("Invoke not found");
  7565. return;
  7566. }
  7567. if (auto tokenNode = BfNodeDynCast<BfTokenNode>(delegateBindExpr->mNewToken))
  7568. {
  7569. if (delegateTypeInstance->IsFunction())
  7570. mModule->Fail("Function bindings are direct assignments, allocation specifier is not applicable", delegateBindExpr->mNewToken);
  7571. else if (tokenNode->GetToken() == BfToken_Append)
  7572. {
  7573. mModule->Fail("Append allocation on delegate bind not supported", delegateBindExpr->mNewToken);
  7574. }
  7575. }
  7576. }
  7577. typedValueExprs.resize(methodInstance->GetParamCount());
  7578. args.resize(methodInstance->GetParamCount());
  7579. for (int i = 0; i < (int)methodInstance->GetParamCount(); i++)
  7580. {
  7581. auto typedValueExpr = &typedValueExprs[i];
  7582. typedValueExpr->mTypedValue.mType = methodInstance->GetParamType(i);
  7583. typedValueExpr->mRefNode = NULL;
  7584. args[i] = typedValueExpr;
  7585. }
  7586. BfSizedArray<ASTREF(BfTypeReference*)>* methodGenericArguments = NULL;
  7587. if (delegateBindExpr->mGenericArgs != NULL)
  7588. methodGenericArguments = &delegateBindExpr->mGenericArgs->mGenericArgs;
  7589. if (delegateBindExpr->mTarget == NULL)
  7590. {
  7591. mModule->AssertErrorState();
  7592. return;
  7593. }
  7594. if (GetAutoComplete() != NULL)
  7595. GetAutoComplete()->CheckNode(delegateBindExpr->mTarget);
  7596. if ((!delegateBindExpr->mTarget->IsA<BfIdentifierNode>()) &&
  7597. (!delegateBindExpr->mTarget->IsA<BfMemberReferenceExpression>()))
  7598. {
  7599. mModule->Fail(StrFormat("Invalid %s binding target, %s can only bind to method references. Consider wrapping expression in a lambda.", bindTypeName, bindTypeName), delegateBindExpr->mTarget);
  7600. mModule->CreateValueFromExpression(delegateBindExpr->mTarget);
  7601. return;
  7602. }
  7603. BfFunctionBindResult bindResult;
  7604. bindResult.mSkipMutCheck = true; // Allow operating on copies
  7605. mFunctionBindResult = &bindResult;
  7606. DoInvocation(delegateBindExpr->mTarget, delegateBindExpr, args, methodGenericArguments);
  7607. mFunctionBindResult = NULL;
  7608. SetMethodElementType(delegateBindExpr->mTarget);
  7609. if (bindResult.mMethodInstance == NULL)
  7610. {
  7611. mResult = BfTypedValue();
  7612. return;
  7613. }
  7614. auto bindMethodInstance = bindResult.mMethodInstance;
  7615. if (isMethodRefMatch)
  7616. {
  7617. // WTF- this was always false, what was it supposed to catch?
  7618. // if (bindMethodInstance != bindResult.mMethodInstance)
  7619. // {
  7620. // mResult = BfTypedValue();
  7621. // return;
  7622. // }
  7623. }
  7624. else
  7625. {
  7626. if (!IsExactMethodMatch(methodInstance, bindMethodInstance, true))
  7627. {
  7628. if (bindResult.mCheckedMultipleMethods)
  7629. {
  7630. mModule->Fail(StrFormat("No overload for '%s' matches %s '%s'", bindMethodInstance->mMethodDef->mName.c_str(), bindTypeName,
  7631. mModule->TypeToString(delegateTypeInstance).c_str()), delegateBindExpr->mTarget);
  7632. }
  7633. else
  7634. {
  7635. mModule->Fail(StrFormat("Method '%s' does not match %s '%s'", mModule->MethodToString(bindMethodInstance).c_str(), bindTypeName,
  7636. mModule->TypeToString(delegateTypeInstance).c_str()), delegateBindExpr->mTarget);
  7637. }
  7638. mResult = BfTypedValue();
  7639. return;
  7640. }
  7641. }
  7642. bool isDirectFunction = false;
  7643. if ((bindResult.mMethodInstance->GetOwner()->IsFunction()) && (bindResult.mFunc))
  7644. isDirectFunction = true;
  7645. if (bindMethodInstance->mIsIntrinsic)
  7646. {
  7647. 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);
  7648. mResult = BfTypedValue();
  7649. return;
  7650. }
  7651. bool hasIncompatibleCallingConventions = !mModule->mSystem->IsCompatibleCallingConvention(methodInstance->mMethodDef->mCallingConvention, bindMethodInstance->mMethodDef->mCallingConvention);
  7652. auto _GetInvokeMethodName = [&]()
  7653. {
  7654. String methodName = "Invoke@";
  7655. methodName += mModule->mCurMethodInstance->mMethodDef->mName;
  7656. int prevSepPos = (int)methodName.LastIndexOf('$');
  7657. if (prevSepPos != -1)
  7658. {
  7659. methodName.RemoveToEnd(prevSepPos);
  7660. }
  7661. auto rootMethodState = mModule->mCurMethodState->GetRootMethodState();
  7662. HashContext hashCtx;
  7663. if (delegateBindExpr->mFatArrowToken != NULL)
  7664. {
  7665. hashCtx.Mixin(delegateBindExpr->mFatArrowToken->GetStartCharId());
  7666. }
  7667. if (rootMethodState->mMethodInstance->mMethodInfoEx != NULL)
  7668. {
  7669. for (auto methodGenericArg : rootMethodState->mMethodInstance->mMethodInfoEx->mMethodGenericArguments)
  7670. {
  7671. StringT<128> genericTypeName;
  7672. BfMangler::Mangle(genericTypeName, mModule->mCompiler->GetMangleKind(), methodGenericArg);
  7673. hashCtx.MixinStr(genericTypeName);
  7674. }
  7675. }
  7676. Val128 hashVal = hashCtx.Finish128();
  7677. methodName += '$';
  7678. methodName += BfTypeUtils::HashEncode64(hashVal.mLow);
  7679. return methodName;
  7680. };
  7681. if ((delegateBindExpr->mNewToken == NULL) || (delegateTypeInstance->IsFunction()))
  7682. {
  7683. if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mHotDataReferenceBuilder != NULL))
  7684. {
  7685. BF_ASSERT(bindResult.mMethodInstance->mHotMethod != NULL);
  7686. mModule->mCurMethodState->mHotDataReferenceBuilder->mFunctionPtrs.Add(bindResult.mMethodInstance->mHotMethod);
  7687. }
  7688. if (isDirectFunction)
  7689. {
  7690. if (delegateTypeInstance->IsFunction())
  7691. {
  7692. auto intPtrVal = mModule->mBfIRBuilder->CreatePtrToInt(bindResult.mFunc, BfTypeCode_IntPtr);
  7693. mResult = BfTypedValue(intPtrVal, mExpectingType);
  7694. return;
  7695. }
  7696. }
  7697. if (mExpectingType->IsFunction())
  7698. {
  7699. BfIRValue result;
  7700. if ((hasIncompatibleCallingConventions) && (mModule->HasCompiledOutput()))
  7701. {
  7702. //
  7703. {
  7704. SetAndRestoreValue<bool> prevIgnore(mModule->mBfIRBuilder->mIgnoreWrites, true);
  7705. result = mModule->CastToFunction(delegateBindExpr->mTarget, bindResult.mMethodInstance, mExpectingType);
  7706. }
  7707. if (result)
  7708. {
  7709. String methodName = _GetInvokeMethodName();
  7710. SizedArray<BfIRType, 8> irParamTypes;
  7711. BfIRType irReturnType;
  7712. bindMethodInstance->GetIRFunctionInfo(mModule, irReturnType, irParamTypes);
  7713. auto prevActiveFunction = mModule->mBfIRBuilder->GetActiveFunction();
  7714. auto prevInsertBlock = mModule->mBfIRBuilder->GetInsertBlock();
  7715. mModule->mBfIRBuilder->SaveDebugLocation();
  7716. auto funcType = mModule->mBfIRBuilder->CreateFunctionType(irReturnType, irParamTypes);
  7717. auto funcValue = mModule->mBfIRBuilder->CreateFunction(funcType, BfIRLinkageType_External, methodName);
  7718. auto srcCallingConv = mModule->GetCallingConvention(methodInstance->GetOwner(), methodInstance->mMethodDef);
  7719. mModule->mBfIRBuilder->SetFuncCallingConv(funcValue, srcCallingConv);
  7720. mModule->mBfIRBuilder->SetActiveFunction(funcValue);
  7721. auto entryBlock = mModule->mBfIRBuilder->CreateBlock("entry", true);
  7722. mModule->mBfIRBuilder->SetInsertPoint(entryBlock);
  7723. SizedArray<BfIRValue, 8> irArgs;
  7724. for (int paramIdx = 0; paramIdx < irParamTypes.size(); paramIdx++)
  7725. {
  7726. irArgs.push_back(mModule->mBfIRBuilder->GetArgument(paramIdx));
  7727. }
  7728. auto bindFuncVal = bindResult.mFunc;
  7729. if (mModule->mCompiler->mOptions.mAllowHotSwapping)
  7730. bindFuncVal = mModule->mBfIRBuilder->RemapBindFunction(bindFuncVal);
  7731. auto callResult = mModule->mBfIRBuilder->CreateCall(bindFuncVal, irArgs);
  7732. auto destCallingConv = mModule->GetCallingConvention(bindMethodInstance->GetOwner(), bindMethodInstance->mMethodDef);
  7733. if (destCallingConv != BfIRCallingConv_CDecl)
  7734. mModule->mBfIRBuilder->SetCallCallingConv(callResult, destCallingConv);
  7735. if (methodInstance->mReturnType->IsValuelessType())
  7736. mModule->mBfIRBuilder->CreateRetVoid();
  7737. else
  7738. mModule->mBfIRBuilder->CreateRet(callResult);
  7739. mModule->mBfIRBuilder->SetActiveFunction(prevActiveFunction);
  7740. mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock);
  7741. mModule->mBfIRBuilder->RestoreDebugLocation();
  7742. result = mModule->mBfIRBuilder->CreatePtrToInt(funcValue, BfTypeCode_IntPtr);
  7743. }
  7744. }
  7745. else
  7746. {
  7747. result = mModule->CastToFunction(delegateBindExpr->mTarget, bindResult.mMethodInstance, mExpectingType);
  7748. }
  7749. if (result)
  7750. mResult = BfTypedValue(result, mExpectingType);
  7751. return;
  7752. }
  7753. auto methodRefType = mModule->CreateMethodRefType(bindResult.mMethodInstance);
  7754. mModule->AddDependency(methodRefType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_Calls);
  7755. mModule->AddCallDependency(bindResult.mMethodInstance);
  7756. if ((bindResult.mOrigTarget) && (bindResult.mOrigTarget.mType->IsMethodRef()))
  7757. {
  7758. mResult = bindResult.mOrigTarget;
  7759. }
  7760. else
  7761. {
  7762. if ((bindResult.mMethodInstance->mMethodDef->mIsLocalMethod) || (!bindResult.mTarget))
  7763. mResult = BfTypedValue(BfIRValue(BfIRValueFlags_Value, BfIRValue::ID_IMPLICIT), methodRefType);
  7764. else
  7765. {
  7766. auto methodRefPtr = mModule->CreateAlloca(methodRefType, "bindResult");
  7767. auto elemPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(methodRefPtr, 0, 0);
  7768. BfTypedValue target;
  7769. if (bindResult.mTarget.IsSplat())
  7770. target = mModule->AggregateSplat(bindResult.mTarget, &bindResult.mIRArgs[0]);
  7771. else
  7772. target = mModule->LoadValue(bindResult.mTarget);
  7773. mModule->mBfIRBuilder->CreateStore(target.mValue, elemPtr);
  7774. mResult = BfTypedValue(methodRefPtr, methodRefType, true);
  7775. }
  7776. }
  7777. return;
  7778. }
  7779. int implicitParamCount = bindMethodInstance->GetImplicitParamCount();
  7780. BfTypeInstance* useTypeInstance = delegateTypeInstance;
  7781. BfClosureType* closureTypeInst = NULL;
  7782. auto origTarget = bindResult.mOrigTarget;
  7783. auto target = bindResult.mTarget;
  7784. BfTypedValue methodRefTarget;
  7785. if ((bindResult.mOrigTarget) && (bindResult.mOrigTarget.mType->IsMethodRef()))
  7786. methodRefTarget = bindResult.mOrigTarget;
  7787. bool isStructTarget = (target) && (target.mType->IsStruct());
  7788. bool bindCapturesThis = bindMethodInstance->HasThis() && !isStructTarget;
  7789. bool needsSplat = (isStructTarget) && (!bindMethodInstance->mMethodDef->mIsMutating) && (!bindMethodInstance->mMethodDef->mNoSplat);
  7790. bool captureThisByValue = isStructTarget;
  7791. if (bindMethodInstance->mMethodDef->mIsLocalMethod)
  7792. {
  7793. // Local method captures always capture 'this' by reference
  7794. captureThisByValue = false;
  7795. }
  7796. if ((origTarget.mType != NULL) &&
  7797. ((origTarget.mType->IsRef()) || (origTarget.mType->IsPointer())))
  7798. {
  7799. captureThisByValue = false;
  7800. }
  7801. if (methodRefTarget)
  7802. BF_ASSERT(methodRefTarget.mType->IsMethodRef());
  7803. if (target.IsSplat())
  7804. target = mModule->AggregateSplat(target, &bindResult.mIRArgs[0]);
  7805. bool hasCaptures = false;
  7806. // Do we need a special delegate type for this?
  7807. if (((captureThisByValue) || (needsSplat) || (implicitParamCount > 0) /*|| (hasIncompatibleCallingConventions)*/) &&
  7808. (mModule->HasCompiledOutput()))
  7809. {
  7810. hasCaptures = true;
  7811. auto curProject = mModule->mCurTypeInstance->mTypeDef->mProject;
  7812. if (captureThisByValue)
  7813. target = mModule->LoadValue(target);
  7814. String delegateTypeName = mModule->TypeToString(delegateTypeInstance);
  7815. HashContext hashCtx;
  7816. hashCtx.MixinStr(delegateTypeName);
  7817. // We mix in the project for reasons described in the lambda binding handler
  7818. hashCtx.MixinStr(curProject->mName);
  7819. String structTargetTypeName;
  7820. String structTargetName;
  7821. // Implicit param separator
  7822. for (int implicitParamIdx = bindMethodInstance->HasThis() ? - 1 : 0; implicitParamIdx < implicitParamCount; implicitParamIdx++)
  7823. {
  7824. auto paramType = bindResult.mMethodInstance->GetParamType(implicitParamIdx);
  7825. if ((implicitParamIdx == -1) && (captureThisByValue))
  7826. {
  7827. if (paramType->IsPointer())
  7828. paramType = paramType->GetUnderlyingType();
  7829. }
  7830. structTargetTypeName = mModule->TypeToString(paramType);
  7831. structTargetName = bindResult.mMethodInstance->GetParamName(implicitParamIdx);
  7832. hashCtx.MixinStr(structTargetTypeName);
  7833. hashCtx.MixinStr(structTargetName);
  7834. }
  7835. Val128 hash128 = hashCtx.Finish128();
  7836. BfClosureType* checkClosureType = new BfClosureType(delegateTypeInstance, hash128);
  7837. checkClosureType->mContext = mModule->mContext;
  7838. checkClosureType->mBaseType = delegateTypeInstance;
  7839. BfType* resolvedClosureType = mModule->ResolveType(checkClosureType, BfPopulateType_Identity);
  7840. closureTypeInst = (BfClosureType*)resolvedClosureType;
  7841. if (checkClosureType == resolvedClosureType)
  7842. {
  7843. // This is a new closure type
  7844. closureTypeInst->Init(curProject);
  7845. for (int implicitParamIdx = bindMethodInstance->HasThis() ? -1 : 0; implicitParamIdx < implicitParamCount; implicitParamIdx++)
  7846. {
  7847. String fieldName = bindResult.mMethodInstance->GetParamName(implicitParamIdx);
  7848. BfType* paramType = bindResult.mMethodInstance->GetParamType(implicitParamIdx);
  7849. if ((implicitParamIdx == -1) && (captureThisByValue))
  7850. {
  7851. if (paramType->IsPointer())
  7852. paramType = paramType->GetUnderlyingType();
  7853. }
  7854. if (fieldName == "this")
  7855. fieldName = "__this";
  7856. closureTypeInst->AddField(paramType, fieldName);
  7857. }
  7858. closureTypeInst->Finish();
  7859. mModule->PopulateType(resolvedClosureType, BfPopulateType_Declaration);
  7860. }
  7861. else
  7862. {
  7863. // Already had this entry
  7864. delete checkClosureType;
  7865. }
  7866. useTypeInstance = closureTypeInst;
  7867. }
  7868. mModule->PopulateType(useTypeInstance);
  7869. if (delegateBindExpr->mTarget == NULL)
  7870. {
  7871. mModule->AssertErrorState();
  7872. return;
  7873. }
  7874. mResult = BfTypedValue(mModule->AllocFromType(useTypeInstance, allocTarget, BfIRValue(), BfIRValue(), 0, BfAllocFlags_None), useTypeInstance);
  7875. // Do we need specialized calling code for this?
  7876. BfIRValue funcValue;
  7877. if (((needsSplat) || (implicitParamCount > 0) || (hasIncompatibleCallingConventions)) &&
  7878. (mModule->HasCompiledOutput()))
  7879. {
  7880. int fieldIdx = 0;
  7881. for (int implicitParamIdx = bindMethodInstance->HasThis() ? -1 : 0; implicitParamIdx < implicitParamCount; implicitParamIdx++)
  7882. {
  7883. auto fieldInst = &useTypeInstance->mFieldInstances[fieldIdx];
  7884. int gepIdx = fieldInst->mDataIdx;
  7885. auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(mResult.mValue, 0, gepIdx);
  7886. auto fieldType = bindMethodInstance->GetParamType(implicitParamIdx);
  7887. if ((implicitParamIdx == -1) && (captureThisByValue))
  7888. {
  7889. if (fieldType->IsPointer())
  7890. fieldType = fieldType->GetUnderlyingType();
  7891. }
  7892. bool failed = false;
  7893. BfTypedValue lookupVal;
  7894. if (implicitParamIdx == -1)
  7895. lookupVal = target;
  7896. else
  7897. lookupVal = DoImplicitArgCapture(delegateBindExpr->mTarget, bindResult.mMethodInstance, implicitParamIdx, failed, BfImplicitParamKind_General, methodRefTarget);
  7898. if (!lookupVal)
  7899. continue;
  7900. if ((fieldType->IsPointer()) && (lookupVal.mType != fieldType))
  7901. {
  7902. BF_ASSERT(fieldType->GetUnderlyingType() == lookupVal.mType);
  7903. BF_ASSERT(lookupVal.IsAddr());
  7904. }
  7905. else if (!fieldType->IsRef())
  7906. lookupVal = mModule->LoadOrAggregateValue(lookupVal);
  7907. if (lookupVal)
  7908. mModule->mBfIRBuilder->CreateStore(lookupVal.mValue, fieldPtr);
  7909. fieldIdx++;
  7910. }
  7911. String methodName = _GetInvokeMethodName();
  7912. SizedArray<BfIRType, 8> irParamTypes;
  7913. BfIRType irReturnType;
  7914. bool hasThis = false;
  7915. if (hasCaptures)
  7916. {
  7917. hasThis = true;
  7918. methodInstance->GetIRFunctionInfo(mModule, irReturnType, irParamTypes);
  7919. irParamTypes[0] = mModule->mBfIRBuilder->MapType(useTypeInstance);
  7920. }
  7921. else
  7922. {
  7923. BF_ASSERT(hasIncompatibleCallingConventions);
  7924. bindMethodInstance->GetIRFunctionInfo(mModule, irReturnType, irParamTypes);
  7925. hasThis = bindMethodInstance->HasThis();
  7926. }
  7927. auto prevActiveFunction = mModule->mBfIRBuilder->GetActiveFunction();
  7928. auto prevInsertBlock = mModule->mBfIRBuilder->GetInsertBlock();
  7929. mModule->mBfIRBuilder->SaveDebugLocation();
  7930. auto funcType = mModule->mBfIRBuilder->CreateFunctionType(irReturnType, irParamTypes);
  7931. funcValue = mModule->mBfIRBuilder->CreateFunction(funcType, BfIRLinkageType_External, methodName);
  7932. auto srcCallingConv = mModule->GetCallingConvention(methodInstance->GetOwner(), methodInstance->mMethodDef);
  7933. if ((!hasThis) && (methodInstance->mMethodDef->mCallingConvention == BfCallingConvention_Stdcall))
  7934. srcCallingConv = BfIRCallingConv_StdCall;
  7935. mModule->mBfIRBuilder->SetFuncCallingConv(funcValue, srcCallingConv);
  7936. mModule->mBfIRBuilder->SetActiveFunction(funcValue);
  7937. auto entryBlock = mModule->mBfIRBuilder->CreateBlock("entry", true);
  7938. mModule->mBfIRBuilder->SetInsertPoint(entryBlock);
  7939. fieldIdx = 0;
  7940. SizedArray<BfIRValue, 8> irArgs;
  7941. for (int implicitParamIdx = bindMethodInstance->HasThis() ? -1 : 0; implicitParamIdx < implicitParamCount; implicitParamIdx++)
  7942. {
  7943. auto fieldInst = &useTypeInstance->mFieldInstances[fieldIdx];
  7944. int gepIdx = fieldInst->mDataIdx;
  7945. auto fieldType = bindMethodInstance->GetParamType(implicitParamIdx);
  7946. bool disableSplat = false;
  7947. if ((implicitParamIdx == -1) && (captureThisByValue))
  7948. {
  7949. if (fieldType->IsPointer())
  7950. {
  7951. fieldType = fieldType->GetUnderlyingType();
  7952. disableSplat = true;
  7953. }
  7954. }
  7955. auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(mModule->mBfIRBuilder->GetArgument(0), 0, gepIdx);
  7956. BfTypedValue typedVal(fieldPtr, fieldType, true);
  7957. PushArg(typedVal, irArgs, disableSplat);
  7958. fieldIdx++;
  7959. }
  7960. int argIdx = hasThis ? 1 : 0;
  7961. for (int paramIdx = 0; paramIdx < methodInstance->GetParamCount(); paramIdx++)
  7962. {
  7963. auto paramType = methodInstance->GetParamType(paramIdx);
  7964. if (paramType->IsSplattable())
  7965. {
  7966. BfTypeUtils::SplatIterate([&](BfType* checkType) { irArgs.push_back(mModule->mBfIRBuilder->GetArgument(argIdx++)); }, paramType);
  7967. }
  7968. else if (!paramType->IsValuelessType())
  7969. {
  7970. irArgs.push_back(mModule->mBfIRBuilder->GetArgument(argIdx++));
  7971. }
  7972. }
  7973. auto bindFuncVal = bindResult.mFunc;
  7974. if (mModule->mCompiler->mOptions.mAllowHotSwapping)
  7975. bindFuncVal = mModule->mBfIRBuilder->RemapBindFunction(bindFuncVal);
  7976. auto result = mModule->mBfIRBuilder->CreateCall(bindFuncVal, irArgs);
  7977. auto destCallingConv = mModule->GetCallingConvention(bindMethodInstance->GetOwner(), bindMethodInstance->mMethodDef);
  7978. if (destCallingConv != BfIRCallingConv_CDecl)
  7979. mModule->mBfIRBuilder->SetCallCallingConv(result, destCallingConv);
  7980. if (methodInstance->mReturnType->IsValuelessType())
  7981. {
  7982. mModule->mBfIRBuilder->CreateRetVoid();
  7983. }
  7984. else
  7985. {
  7986. mModule->mBfIRBuilder->CreateRet(result);
  7987. }
  7988. mModule->mBfIRBuilder->SetActiveFunction(prevActiveFunction);
  7989. mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock);
  7990. mModule->mBfIRBuilder->RestoreDebugLocation();
  7991. }
  7992. else if ((closureTypeInst != NULL) && (captureThisByValue))
  7993. {
  7994. // 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
  7995. auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(mResult.mValue, 0, 1);
  7996. target = mModule->LoadValue(target);
  7997. mModule->mBfIRBuilder->CreateStore(target.mValue, fieldPtr);
  7998. target = BfTypedValue(fieldPtr, target.mType, true);
  7999. }
  8000. BfResolvedArgs resolvedArgs;
  8001. MatchConstructor(delegateBindExpr, delegateBindExpr, mResult, useTypeInstance, resolvedArgs, false, false);
  8002. auto baseDelegateType = VerifyBaseDelegateType(delegateTypeInstance->mBaseType);
  8003. auto baseDelegate = mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->MapType(baseDelegateType, BfIRPopulateType_Full));
  8004. // >> delegate.mTarget = bindResult.mTarget
  8005. BfIRValue valPtr;
  8006. if (mModule->HasCompiledOutput())
  8007. {
  8008. if ((implicitParamCount > 0) || (needsSplat)) // Point back to self, it contains capture data
  8009. valPtr = mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->GetPrimitiveType(BfTypeCode_NullPtr));
  8010. else if (bindResult.mTarget)
  8011. valPtr = mModule->mBfIRBuilder->CreateBitCast(target.mValue, mModule->mBfIRBuilder->GetPrimitiveType(BfTypeCode_NullPtr));
  8012. else
  8013. valPtr = mModule->GetDefaultValue(mModule->GetPrimitiveType(BfTypeCode_NullPtr));
  8014. auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(baseDelegate, 0, 2);
  8015. mModule->mBfIRBuilder->CreateStore(valPtr, fieldPtr);
  8016. }
  8017. if (!funcValue)
  8018. {
  8019. funcValue = bindResult.mFunc;
  8020. if (!funcValue)
  8021. {
  8022. if ((mModule->HasCompiledOutput()) && (!mModule->mBfIRBuilder->mIgnoreWrites))
  8023. mModule->AssertErrorState();
  8024. return;
  8025. }
  8026. if ((mModule->mCompiler->mOptions.mAllowHotSwapping) && (!bindResult.mMethodInstance->mMethodDef->mIsVirtual))
  8027. {
  8028. funcValue = mModule->mBfIRBuilder->RemapBindFunction(funcValue);
  8029. }
  8030. }
  8031. // >> delegate.mFuncPtr = bindResult.mFunc
  8032. auto nullPtrType = mModule->GetPrimitiveType(BfTypeCode_NullPtr);
  8033. valPtr = mModule->mBfIRBuilder->CreateBitCast(funcValue, mModule->mBfIRBuilder->MapType(nullPtrType));
  8034. auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(baseDelegate, 0, 1);
  8035. mModule->mBfIRBuilder->CreateStore(valPtr, fieldPtr);
  8036. }
  8037. void BfExprEvaluator::VisitLambdaBodies(BfAstNode* body, BfFieldDtorDeclaration* fieldDtor)
  8038. {
  8039. if (auto blockBody = BfNodeDynCast<BfBlock>(body))
  8040. mModule->VisitChild(blockBody);
  8041. else if (auto bodyExpr = BfNodeDynCast<BfExpression>(body))
  8042. mModule->CreateValueFromExpression(bodyExpr);
  8043. while (fieldDtor != NULL)
  8044. {
  8045. mModule->VisitChild(fieldDtor->mBody);
  8046. fieldDtor = fieldDtor->mNextFieldDtor;
  8047. }
  8048. }
  8049. BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lambdaBindExpr)
  8050. {
  8051. auto rootMethodState = mModule->mCurMethodState->GetRootMethodState();
  8052. BfLambdaInstance* lambdaInstance = NULL;
  8053. if (rootMethodState->mLambdaCache.TryGetValue(lambdaBindExpr, &lambdaInstance))
  8054. return lambdaInstance;
  8055. static int sBindCount = 0;
  8056. sBindCount++;
  8057. bool isFunctionBind = false;
  8058. BfTypeInstance* delegateTypeInstance = NULL;
  8059. BfMethodInstance* invokeMethodInstance = NULL;
  8060. if (mExpectingType == NULL)
  8061. {
  8062. mModule->Fail("Cannot infer delegate type", lambdaBindExpr);
  8063. delegateTypeInstance = mModule->mContext->mBfObjectType;
  8064. }
  8065. else
  8066. {
  8067. delegateTypeInstance = mExpectingType->ToTypeInstance();
  8068. if ((delegateTypeInstance == NULL) ||
  8069. ((!delegateTypeInstance->mTypeDef->mIsDelegate) && (!delegateTypeInstance->mTypeDef->mIsFunction)))
  8070. {
  8071. if (lambdaBindExpr->mFatArrowToken != NULL)
  8072. mModule->Fail("Can only bind lambdas to delegate types", lambdaBindExpr->mFatArrowToken);
  8073. delegateTypeInstance = mModule->mContext->mBfObjectType;
  8074. }
  8075. else
  8076. {
  8077. invokeMethodInstance = mModule->GetRawMethodInstanceAtIdx(delegateTypeInstance, 0, "Invoke");
  8078. }
  8079. isFunctionBind = delegateTypeInstance->mTypeDef->mIsFunction;
  8080. }
  8081. if (auto tokenNode = BfNodeDynCast<BfTokenNode>(lambdaBindExpr->mNewToken))
  8082. {
  8083. if (isFunctionBind)
  8084. {
  8085. mModule->Fail("Function lambda binding does not require allocation", lambdaBindExpr->mNewToken);
  8086. }
  8087. else if (tokenNode->GetToken() == BfToken_Append)
  8088. {
  8089. mModule->Fail("Append allocation on delegate bind not supported", lambdaBindExpr->mNewToken);
  8090. }
  8091. }
  8092. if (invokeMethodInstance != NULL)
  8093. {
  8094. if ((int)lambdaBindExpr->mParams.size() < invokeMethodInstance->GetParamCount())
  8095. {
  8096. BfAstNode* refNode = lambdaBindExpr->mCloseParen;
  8097. if (refNode == NULL)
  8098. refNode = lambdaBindExpr;
  8099. mModule->Fail(StrFormat("Not enough parameters for delegate type '%s'. Expected %d more.",
  8100. mModule->TypeToString(delegateTypeInstance).c_str(), invokeMethodInstance->GetParamCount() - lambdaBindExpr->mParams.size()), refNode);
  8101. }
  8102. else if ((int)lambdaBindExpr->mParams.size() > invokeMethodInstance->GetParamCount())
  8103. {
  8104. BfAstNode* refNode = lambdaBindExpr->mParams[invokeMethodInstance->GetParamCount()];
  8105. mModule->Fail(StrFormat("Too many parameters for delegate type '%s'. Expected %d fewer.",
  8106. mModule->TypeToString(delegateTypeInstance).c_str(), lambdaBindExpr->mParams.size() - invokeMethodInstance->GetParamCount()), refNode);
  8107. }
  8108. }
  8109. auto autoComplete = GetAutoComplete();
  8110. bool wasCapturingMethodInfo = false;
  8111. if ((autoComplete != NULL) && (invokeMethodInstance != NULL))
  8112. {
  8113. wasCapturingMethodInfo = autoComplete->mIsCapturingMethodMatchInfo;
  8114. autoComplete->CheckInvocation(lambdaBindExpr, lambdaBindExpr->mOpenParen, lambdaBindExpr->mCloseParen, lambdaBindExpr->mCommas);
  8115. if (autoComplete->mIsCapturingMethodMatchInfo)
  8116. {
  8117. autoComplete->mMethodMatchInfo->mInstanceList.Clear();
  8118. auto methodMatchInfo = autoComplete->mMethodMatchInfo;
  8119. BfAutoComplete::MethodMatchEntry methodMatchEntry;
  8120. methodMatchEntry.mTypeInstance = invokeMethodInstance->GetOwner();
  8121. methodMatchEntry.mCurMethodInstance = mModule->mCurMethodInstance;
  8122. methodMatchEntry.mMethodDef = invokeMethodInstance->mMethodDef;
  8123. autoComplete->mMethodMatchInfo->mInstanceList.push_back(methodMatchEntry);
  8124. methodMatchInfo->mBestIdx = 0;
  8125. methodMatchInfo->mMostParamsMatched = 0;
  8126. int cursorIdx = lambdaBindExpr->GetParser()->mCursorIdx;
  8127. if ((lambdaBindExpr->mCloseParen == NULL) || (cursorIdx <= lambdaBindExpr->mCloseParen->GetSrcStart()))
  8128. {
  8129. int paramIdx = 0;
  8130. for (int commaIdx = 0; commaIdx < (int)lambdaBindExpr->mCommas.size(); commaIdx++)
  8131. {
  8132. auto commaNode = lambdaBindExpr->mCommas[commaIdx];
  8133. if ((commaNode != NULL) && (cursorIdx >= commaNode->GetSrcStart()))
  8134. paramIdx = commaIdx + 1;
  8135. }
  8136. bool isEmpty = true;
  8137. if (paramIdx < (int)lambdaBindExpr->mParams.size())
  8138. {
  8139. auto paramNode = lambdaBindExpr->mParams[paramIdx];
  8140. if (paramNode != NULL)
  8141. isEmpty = false;
  8142. }
  8143. if (isEmpty)
  8144. {
  8145. if (paramIdx < (int)invokeMethodInstance->GetParamCount())
  8146. {
  8147. String paramName = invokeMethodInstance->GetParamName(paramIdx);
  8148. autoComplete->mEntriesSet.Clear();
  8149. autoComplete->AddEntry(AutoCompleteEntry("paramName", paramName));
  8150. autoComplete->mInsertStartIdx = cursorIdx;
  8151. autoComplete->mInsertEndIdx = cursorIdx;
  8152. if ((paramIdx == 0) && (lambdaBindExpr->mParams.IsEmpty()))
  8153. {
  8154. String totalNames;
  8155. for (int checkIdx = 0; checkIdx < (int)invokeMethodInstance->GetParamCount(); checkIdx++)
  8156. {
  8157. if (!totalNames.IsEmpty())
  8158. totalNames += ", ";
  8159. totalNames += invokeMethodInstance->GetParamName(checkIdx);
  8160. }
  8161. autoComplete->AddEntry(AutoCompleteEntry("paramNames", totalNames));
  8162. }
  8163. }
  8164. }
  8165. }
  8166. }
  8167. }
  8168. defer
  8169. {
  8170. if (autoComplete != NULL)
  8171. autoComplete->mIsCapturingMethodMatchInfo = (wasCapturingMethodInfo) && (!autoComplete->mIsCapturingMethodMatchInfo);
  8172. };
  8173. if (lambdaBindExpr->mBody == NULL)
  8174. {
  8175. mModule->AssertErrorState();
  8176. return NULL;
  8177. }
  8178. if (lambdaBindExpr->mNewToken == NULL)
  8179. {
  8180. if (lambdaBindExpr->mDtor != NULL)
  8181. {
  8182. mModule->Fail("Valueless method reference cannot contain destructor. Consider either removing destructor or using an allocated lambda.", lambdaBindExpr->mDtor->mTildeToken);
  8183. // Eat it
  8184. auto fieldDtor = lambdaBindExpr->mDtor;
  8185. while (fieldDtor != NULL)
  8186. {
  8187. mModule->VisitEmbeddedStatement(fieldDtor->mBody);
  8188. fieldDtor = fieldDtor->mNextFieldDtor;
  8189. }
  8190. }
  8191. if (invokeMethodInstance != NULL)
  8192. {
  8193. BfLocalMethod* localMethod = new BfLocalMethod();
  8194. localMethod->mMethodName = "anon";
  8195. localMethod->mSystem = mModule->mSystem;
  8196. localMethod->mModule = mModule;
  8197. localMethod->mExpectedFullName = mModule->GetLocalMethodName(localMethod->mMethodName, lambdaBindExpr->mFatArrowToken, mModule->mCurMethodState, mModule->mCurMethodState->mMixinState);
  8198. localMethod->mLambdaInvokeMethodInstance = invokeMethodInstance;
  8199. localMethod->mLambdaBindExpr = lambdaBindExpr;
  8200. localMethod->mDeclMethodState = mModule->mCurMethodState;
  8201. mModule->mContext->mLocalMethodGraveyard.push_back(localMethod);
  8202. auto moduleMethodInstance = mModule->GetLocalMethodInstance(localMethod, BfTypeVector());
  8203. auto methodRefType = mModule->CreateMethodRefType(moduleMethodInstance.mMethodInstance);
  8204. mModule->AddDependency(methodRefType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_Calls);
  8205. mModule->AddCallDependency(moduleMethodInstance.mMethodInstance);
  8206. mResult = BfTypedValue(BfIRValue(BfIRValueFlags_Value, BfIRValue::ID_IMPLICIT), methodRefType);
  8207. return NULL;
  8208. }
  8209. }
  8210. //SetAndRestoreValue<bool> prevIgnoreIRWrites(mModule->mBfIRBuilder->mIgnoreWrites, mModule->mWantsIRIgnoreWrites);
  8211. SetAndRestoreValue<bool> prevIgnoreIRWrites(mModule->mBfIRBuilder->mIgnoreWrites, mModule->mWantsIRIgnoreWrites || mModule->mCurMethodInstance->mIsUnspecialized);
  8212. BfTypeInstance* outerClosure = NULL;
  8213. if ((mModule->mCurMethodState->mClosureState != NULL) && (!mModule->mCurMethodState->mClosureState->mCapturing))
  8214. outerClosure = mModule->mCurMethodState->mClosureState->mClosureType;
  8215. Val128 val128(delegateTypeInstance->mTypeId);
  8216. BfMethodState methodState;
  8217. methodState.mPrevMethodState = mModule->mCurMethodState;
  8218. BfIRFunctionType funcType;
  8219. auto voidType = mModule->GetPrimitiveType(BfTypeCode_None);
  8220. SizedArray<BfIRType, 0> paramTypes;
  8221. funcType = mModule->mBfIRBuilder->CreateFunctionType(mModule->mBfIRBuilder->MapType(voidType), paramTypes, false);
  8222. auto prevInsertBlock = mModule->mBfIRBuilder->GetInsertBlock();
  8223. BF_ASSERT(prevInsertBlock);
  8224. auto prevActiveFunction = mModule->mBfIRBuilder->GetActiveFunction();
  8225. mModule->mBfIRBuilder->SaveDebugLocation();
  8226. SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
  8227. BfDeferredLocalAssignData deferredLocalAssignData;
  8228. if (mModule->mCurMethodState->mDeferredLocalAssignData != NULL)
  8229. deferredLocalAssignData.ExtendFrom(mModule->mCurMethodState->mDeferredLocalAssignData);
  8230. SetAndRestoreValue<BfMethodState*> prevMethodState(mModule->mCurMethodState, &methodState);
  8231. methodState.mIRHeadBlock = mModule->mBfIRBuilder->CreateBlock("head", true);
  8232. methodState.mIRInitBlock = mModule->mBfIRBuilder->CreateBlock("init", true);
  8233. methodState.mIREntryBlock = mModule->mBfIRBuilder->CreateBlock("entry", true);
  8234. methodState.mCurScope->mDIScope = prevMethodState.mPrevVal->mCurScope->mDIScope;//invokeMethodInstance->mDIFunction;
  8235. methodState.mCurLocalVarId = -1;
  8236. methodState.mIRFunction = prevMethodState.mPrevVal->mIRFunction;
  8237. methodState.mDeferredLocalAssignData = &deferredLocalAssignData;
  8238. mModule->mBfIRBuilder->SetInsertPoint(methodState.mIREntryBlock);
  8239. BfClosureState closureState;
  8240. if (delegateTypeInstance->IsDelegate())
  8241. closureState.mReturnType = mModule->GetDelegateReturnType(delegateTypeInstance);
  8242. else
  8243. closureState.mReturnType = mModule->mContext->mBfObjectType;
  8244. closureState.mCapturing = true;
  8245. closureState.mDeclaringMethodIsMutating = mModule->mCurMethodInstance->mMethodDef->mIsMutating;
  8246. methodState.mClosureState = &closureState;
  8247. closureState.mClosureType = outerClosure;
  8248. BF_ASSERT(methodState.mCurLocalVarId == -1);
  8249. int outerLocalsCount = (int)methodState.mLocals.size();
  8250. // static int sItrCount = 0;
  8251. // ++sItrCount;
  8252. // int itrCount = sItrCount;
  8253. // if ((itrCount == 8) || (itrCount == 10))
  8254. // {
  8255. // NOP;
  8256. // }
  8257. String delegateTypeName = mModule->TypeToString(delegateTypeInstance);
  8258. HashContext hashCtx;
  8259. hashCtx.MixinStr(delegateTypeName);
  8260. BfSource* bfSource = delegateTypeInstance->mTypeDef->mSource;
  8261. BfMethodDef* methodDef = new BfMethodDef();
  8262. methodDef->mDeclaringType = mModule->mCurMethodInstance->mMethodDef->mDeclaringType;
  8263. Val128 closureMethodHash;
  8264. OwnedVector<BfParameterDeclaration> tempParamDecls;
  8265. if ((autoComplete != NULL) && (autoComplete->mMethodMatchInfo != NULL) && (autoComplete->IsAutocompleteNode(lambdaBindExpr->mBody)))
  8266. {
  8267. // Don't show outer method match info when our cursor is inside a lambda expression (being passed as a parameter)
  8268. autoComplete->RemoveMethodMatchInfo();
  8269. }
  8270. if (invokeMethodInstance != NULL)
  8271. {
  8272. for (int paramIdx = 0; paramIdx < (int)invokeMethodInstance->mMethodDef->mParams.size(); paramIdx++)
  8273. {
  8274. auto invokeParamDef = invokeMethodInstance->mMethodDef->mParams[paramIdx];
  8275. BfParameterDef* paramDef = new BfParameterDef();
  8276. paramDef->mParamDeclaration = tempParamDecls.Alloc();
  8277. BfLocalVariable* localVar = new BfLocalVariable();
  8278. if (paramIdx < (int)lambdaBindExpr->mParams.size())
  8279. {
  8280. localVar->mName = lambdaBindExpr->mParams[paramIdx]->ToString();
  8281. localVar->mNameNode = lambdaBindExpr->mParams[paramIdx];
  8282. paramDef->mParamDeclaration->mNameNode = lambdaBindExpr->mParams[paramIdx];
  8283. }
  8284. else
  8285. {
  8286. mModule->AssertErrorState();
  8287. localVar->mName = invokeParamDef->mName;
  8288. paramDef->mParamDeclaration->mNameNode = NULL;
  8289. }
  8290. paramDef->mName = localVar->mName;
  8291. methodDef->mParams.push_back(paramDef);
  8292. localVar->mResolvedType = invokeMethodInstance->GetParamType(paramIdx);
  8293. localVar->mIsAssigned = true;
  8294. localVar->mReadFromId = 0;
  8295. auto rootMethodState = methodState.GetRootMethodState();
  8296. localVar->mLocalVarId = rootMethodState->mCurLocalVarId++;
  8297. mModule->DoAddLocalVariable(localVar);
  8298. if (autoComplete != NULL)
  8299. autoComplete->CheckLocalDef(BfNodeDynCast<BfIdentifierNode>(paramDef->mParamDeclaration->mNameNode), methodState.mLocals.back());
  8300. auto resolvePassData = mModule->mCompiler->mResolvePassData;
  8301. if (resolvePassData != NULL)
  8302. resolvePassData->HandleLocalReference(BfNodeDynCast<BfIdentifierNode>(paramDef->mParamDeclaration->mNameNode), mModule->mCurTypeInstance->mTypeDef,
  8303. mModule->mCurMethodInstance->mMethodDef, localVar->mLocalVarId);
  8304. }
  8305. }
  8306. bool isAutocomplete = mModule->mCompiler->IsAutocomplete();
  8307. methodDef->mIdx = mModule->mCurMethodInstance->mMethodDef->mIdx;
  8308. methodDef->mBody = lambdaBindExpr->mBody;
  8309. ///
  8310. BfClosureInstanceInfo* closureInstanceInfo = new BfClosureInstanceInfo();
  8311. auto checkInsertBlock = mModule->mBfIRBuilder->GetInsertBlock();
  8312. closureState.mCaptureStartAccessId = methodState.mPrevMethodState->GetRootMethodState()->mCurAccessId;
  8313. closureState.mCaptureVisitingBody = true;
  8314. closureState.mClosureInstanceInfo = closureInstanceInfo;
  8315. VisitLambdaBodies(lambdaBindExpr->mBody, lambdaBindExpr->mDtor);
  8316. // If we ended up being called by a method with a lower captureStartAccessId, propagate that to whoever is calling us, too...
  8317. if ((methodState.mPrevMethodState->mClosureState != NULL) && (methodState.mPrevMethodState->mClosureState->mCapturing))
  8318. {
  8319. auto prevClosureState = methodState.mPrevMethodState->mClosureState;
  8320. if (closureState.mCaptureStartAccessId < prevClosureState->mCaptureStartAccessId)
  8321. prevClosureState->mCaptureStartAccessId = closureState.mCaptureStartAccessId;
  8322. }
  8323. if (mModule->mCurMethodInstance->mIsUnspecialized)
  8324. {
  8325. prevIgnoreWrites.Restore();
  8326. mModule->mBfIRBuilder->RestoreDebugLocation();
  8327. mResult = mModule->GetDefaultTypedValue(delegateTypeInstance);
  8328. mModule->mBfIRBuilder->SetActiveFunction(prevActiveFunction);
  8329. if (!prevInsertBlock.IsFake())
  8330. mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock);
  8331. delete methodDef;
  8332. delete closureInstanceInfo;
  8333. return NULL;
  8334. }
  8335. closureState.mCaptureVisitingBody = false;
  8336. prevIgnoreWrites.Restore();
  8337. mModule->mBfIRBuilder->RestoreDebugLocation();
  8338. BfCaptureType captureType = BfCaptureType_Value;
  8339. if ((lambdaBindExpr->mLambdaCapture != NULL) && (lambdaBindExpr->mLambdaCapture->mCaptureToken != NULL))
  8340. {
  8341. if (lambdaBindExpr->mLambdaCapture->mCaptureToken->GetToken() == BfToken_Ampersand)
  8342. captureType = BfCaptureType_Reference;
  8343. else
  8344. captureType = BfCaptureType_Copy;
  8345. }
  8346. Array<BfClosureCapturedEntry> capturedEntries;
  8347. bool copyOuterCaptures = false;
  8348. {
  8349. auto varMethodState = methodState.mPrevMethodState;
  8350. while (varMethodState != NULL)
  8351. {
  8352. for (int localIdx = 0; localIdx < varMethodState->mLocals.size(); localIdx++)
  8353. {
  8354. auto localVar = varMethodState->mLocals[localIdx];
  8355. if ((localVar->mReadFromId >= closureState.mCaptureStartAccessId) || (localVar->mWrittenToId >= closureState.mCaptureStartAccessId))
  8356. {
  8357. if ((localVar->mIsThis) && (outerClosure != NULL))
  8358. {
  8359. continue;
  8360. }
  8361. auto outerLocal = localVar;
  8362. if ((localVar->mConstValue) || (localVar->mResolvedType->IsValuelessType()))
  8363. {
  8364. closureState.mConstLocals.push_back(*outerLocal);
  8365. continue;
  8366. }
  8367. BfClosureCapturedEntry capturedEntry;
  8368. auto capturedType = outerLocal->mResolvedType;
  8369. bool captureByRef = false;
  8370. if (!capturedType->IsRef())
  8371. {
  8372. if (captureType == BfCaptureType_Reference)
  8373. {
  8374. if (outerLocal->mIsThis)
  8375. {
  8376. if ((outerLocal->mResolvedType->IsValueType()) && (mModule->mCurMethodInstance->mMethodDef->HasNoThisSplat()))
  8377. captureByRef = true;
  8378. }
  8379. else if ((!localVar->mIsReadOnly) && (localVar->mWrittenToId >= closureState.mCaptureStartAccessId))
  8380. captureByRef = true;
  8381. }
  8382. }
  8383. else
  8384. {
  8385. if ((captureType != BfCaptureType_Reference) || (localVar->mWrittenToId < closureState.mCaptureStartAccessId))
  8386. {
  8387. capturedType = ((BfRefType*)capturedType)->mElementType;
  8388. }
  8389. }
  8390. if (captureByRef)
  8391. {
  8392. capturedType = mModule->CreateRefType(capturedType);
  8393. }
  8394. capturedEntry.mType = capturedType;
  8395. if (outerLocal->mName == "this")
  8396. capturedEntry.mName = "__this";
  8397. else
  8398. capturedEntry.mName = outerLocal->mName;
  8399. capturedEntry.mNameNode = outerLocal->mNameNode;
  8400. capturedEntries.Add(capturedEntry);
  8401. }
  8402. }
  8403. varMethodState = varMethodState->mPrevMethodState;
  8404. if (varMethodState == NULL)
  8405. break;
  8406. if (varMethodState->mMixinState != NULL)
  8407. break;
  8408. if (varMethodState->mClosureState != NULL)
  8409. {
  8410. if (!varMethodState->mClosureState->mCapturing)
  8411. break;
  8412. }
  8413. }
  8414. }
  8415. for (auto copyField : closureState.mReferencedOuterClosureMembers)
  8416. {
  8417. auto fieldDef = copyField->GetFieldDef();
  8418. BfClosureCapturedEntry capturedEntry;
  8419. capturedEntry.mName = fieldDef->mName;
  8420. capturedEntry.mType = copyField->mResolvedType;
  8421. if ((captureType == BfCaptureType_Reference) && (capturedEntry.mType->IsRef()))
  8422. {
  8423. capturedEntry.mExplicitlyByReference = true;
  8424. }
  8425. else if ((captureType != BfCaptureType_Reference) && (capturedEntry.mType->IsRef()))
  8426. {
  8427. auto refType = (BfRefType*)capturedEntry.mType;
  8428. capturedEntry.mType = refType->mElementType;
  8429. }
  8430. else if ((captureType == BfCaptureType_Reference) && (!capturedEntry.mType->IsRef()) && (!fieldDef->mIsReadOnly))
  8431. {
  8432. capturedEntry.mType = mModule->CreateRefType(capturedEntry.mType);
  8433. }
  8434. }
  8435. std::sort(capturedEntries.begin(), capturedEntries.end());
  8436. bool hasCapture = false;
  8437. BfMethodInstanceGroup methodInstanceGroup;
  8438. methodInstanceGroup.mOwner = mModule->mCurTypeInstance;
  8439. methodInstanceGroup.mOnDemandKind = BfMethodOnDemandKind_AlwaysInclude;
  8440. BfMethodInstance* methodInstance = new BfMethodInstance();
  8441. methodInstance->mMethodInstanceGroup = &methodInstanceGroup;
  8442. methodInstance->GetMethodInfoEx()->mClosureInstanceInfo = closureInstanceInfo;
  8443. if (invokeMethodInstance != NULL)
  8444. methodInstance->mParams = invokeMethodInstance->mParams;
  8445. methodInstance->mIsClosure = true;
  8446. // We want the closure ID to match between hot reloads -- otherwise we wouldn't be able to modify them,
  8447. // so we use the charId from the 'fat arrow' token
  8448. int closureId = 0;
  8449. if (lambdaBindExpr->mFatArrowToken != NULL)
  8450. closureId = lambdaBindExpr->mFatArrowToken->GetStartCharId();
  8451. auto curProject = mModule->mCurTypeInstance->mTypeDef->mProject;
  8452. BF_ASSERT(curProject != NULL);
  8453. // We need to make these per-project even though you'd think we might not because we
  8454. // insert generic type specializations in the generic definition's project,
  8455. // BECAUSE: we would need to scan the captured fields the same way we scan the
  8456. // generic arguments to determine if each project can see it or not in the vdata
  8457. BfTypeInstance* useTypeInstance = delegateTypeInstance;
  8458. BfClosureType* closureTypeInst = NULL;
  8459. if ((capturedEntries.size() != 0) || (lambdaBindExpr->mDtor != NULL) || (copyOuterCaptures))
  8460. {
  8461. hashCtx.MixinStr(curProject->mName);
  8462. if (copyOuterCaptures)
  8463. {
  8464. // String typeName = mModule->DoTypeToString(outerClosure, BfTypeNameFlag_DisambiguateDups);
  8465. // hashCtx.MixinStr(typeName);
  8466. hashCtx.Mixin(outerClosure->mTypeId);
  8467. }
  8468. for (auto& capturedEntry : capturedEntries)
  8469. {
  8470. // String typeName = mModule->DoTypeToString(capturedEntry.mType, BfTypeNameFlag_DisambiguateDups);
  8471. // hashCtx.MixinStr(typeName);
  8472. hashCtx.Mixin(capturedEntry.mType->mTypeId);
  8473. hashCtx.MixinStr(capturedEntry.mName);
  8474. hashCtx.Mixin(capturedEntry.mExplicitlyByReference);
  8475. }
  8476. if (lambdaBindExpr->mDtor != NULL)
  8477. {
  8478. // Has DTOR thunk
  8479. bool hasDtorThunk = true;
  8480. hashCtx.Mixin(hasDtorThunk);
  8481. }
  8482. Val128 hash128 = hashCtx.Finish128();
  8483. BfClosureType* checkClosureType = new BfClosureType(delegateTypeInstance, hash128);
  8484. checkClosureType->mContext = mModule->mContext;
  8485. checkClosureType->mBaseType = delegateTypeInstance;
  8486. BfType* resolvedClosureType = mModule->ResolveType(checkClosureType, BfPopulateType_Identity);
  8487. closureTypeInst = (BfClosureType*)resolvedClosureType;
  8488. if (checkClosureType == resolvedClosureType)
  8489. {
  8490. // This is a new closure type
  8491. closureTypeInst->Init(curProject);
  8492. closureTypeInst->mTypeDef->mProject = curProject;
  8493. if (copyOuterCaptures)
  8494. {
  8495. for (auto& fieldInstance : outerClosure->mFieldInstances)
  8496. {
  8497. BfFieldDef* origFieldDef = fieldInstance.GetFieldDef();
  8498. BfFieldDef* fieldDef = closureTypeInst->AddField(fieldInstance.mResolvedType, origFieldDef->mName);
  8499. fieldDef->mIsReadOnly = origFieldDef->mIsReadOnly;
  8500. }
  8501. }
  8502. for (auto& capturedEntry : capturedEntries)
  8503. {
  8504. BfFieldDef* fieldDef = closureTypeInst->AddField(capturedEntry.mType, capturedEntry.mName);
  8505. if (!capturedEntry.mExplicitlyByReference)
  8506. fieldDef->mIsReadOnly = true;
  8507. }
  8508. if (lambdaBindExpr->mDtor != NULL)
  8509. {
  8510. auto dtorDef = closureTypeInst->AddDtor();
  8511. auto voidType = mModule->GetPrimitiveType(BfTypeCode_None);
  8512. auto voidPtrType = mModule->CreatePointerType(voidType);
  8513. closureTypeInst->AddField(voidPtrType, "__dtorThunk");
  8514. }
  8515. closureTypeInst->Finish();
  8516. }
  8517. else
  8518. {
  8519. // Already had this entry
  8520. delete checkClosureType;
  8521. }
  8522. useTypeInstance = closureTypeInst;
  8523. }
  8524. mModule->mBfIRBuilder->PopulateType(useTypeInstance);
  8525. mModule->PopulateType(useTypeInstance);
  8526. // If we are allowing hot swapping, we need to always mangle the name to non-static because if we add a capture
  8527. // later then we need to have the mangled names match
  8528. methodDef->mIsStatic = (closureTypeInst == NULL) && (!mModule->mCompiler->mOptions.mAllowHotSwapping);
  8529. SizedArray<BfIRType, 3> newTypes;
  8530. SizedArray<BfIRType, 8> origParamTypes;
  8531. BfIRType origReturnType;
  8532. if (!methodDef->mIsStatic)
  8533. newTypes.push_back(mModule->mBfIRBuilder->MapType(useTypeInstance));
  8534. if (invokeMethodInstance != NULL)
  8535. {
  8536. auto invokeFunctionType = mModule->mBfIRBuilder->MapMethod(invokeMethodInstance);
  8537. invokeMethodInstance->GetIRFunctionInfo(mModule, origReturnType, origParamTypes, methodDef->mIsStatic);
  8538. }
  8539. else
  8540. {
  8541. origReturnType = mModule->mBfIRBuilder->MapType(mModule->GetPrimitiveType(BfTypeCode_None));
  8542. }
  8543. for (int i = methodDef->mIsStatic ? 0 : 1; i < (int)origParamTypes.size(); i++)
  8544. newTypes.push_back(origParamTypes[i]);
  8545. auto closureFuncType = mModule->mBfIRBuilder->CreateFunctionType(origReturnType, newTypes, false);
  8546. prevMethodState.Restore();
  8547. mModule->mBfIRBuilder->SetActiveFunction(prevActiveFunction);
  8548. if (!prevInsertBlock.IsFake())
  8549. mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock);
  8550. // Just a check
  8551. mModule->mBfIRBuilder->GetInsertBlock();
  8552. //auto rootMethodState = mModule->mCurMethodState;
  8553. HashContext closureHashCtx;
  8554. closureHashCtx.Mixin(closureId);
  8555. // When we're a nested lambda, strip off the outer hash and closureTypeInst markers
  8556. methodDef->mName = mModule->mCurMethodInstance->mMethodDef->mName;
  8557. int prevSepPos = (int)methodDef->mName.LastIndexOf('$');
  8558. if (prevSepPos != -1)
  8559. {
  8560. closureHashCtx.Mixin(methodDef->mName.c_str() + prevSepPos, (int)methodDef->mName.length() - prevSepPos);
  8561. methodDef->mName.RemoveToEnd(prevSepPos);
  8562. }
  8563. // if (closureTypeInst != NULL)
  8564. // {
  8565. // StringT<128> typeInstName;
  8566. // BfMangler::Mangle(typeInstName,mModule->mCompiler->GetMangleKind(), closureTypeInst);
  8567. // closureHashCtx.MixinStr(typeInstName);
  8568. // }
  8569. auto checkMethodState = mModule->mCurMethodState;
  8570. while (checkMethodState != NULL)
  8571. {
  8572. if (checkMethodState->mMethodInstance != NULL)
  8573. {
  8574. if (checkMethodState->mMethodInstance->mMethodInfoEx != NULL)
  8575. {
  8576. for (auto methodGenericArg : checkMethodState->mMethodInstance->mMethodInfoEx->mMethodGenericArguments)
  8577. {
  8578. StringT<128> genericTypeName;
  8579. BfMangler::Mangle(genericTypeName, mModule->mCompiler->GetMangleKind(), methodGenericArg);
  8580. closureHashCtx.MixinStr(genericTypeName);
  8581. }
  8582. }
  8583. }
  8584. checkMethodState = checkMethodState->mPrevMethodState;
  8585. }
  8586. uint64 closureHash = closureHashCtx.Finish64();
  8587. methodDef->mName += "$";
  8588. methodDef->mName += BfTypeUtils::HashEncode64(closureHash);
  8589. methodInstance->mMethodDef = methodDef;
  8590. if (invokeMethodInstance != NULL)
  8591. {
  8592. methodInstance->mParams = invokeMethodInstance->mParams;
  8593. methodInstance->mReturnType = invokeMethodInstance->mReturnType;
  8594. }
  8595. else
  8596. methodInstance->mReturnType = mModule->GetPrimitiveType(BfTypeCode_None);
  8597. StringT<128> closureFuncName;
  8598. BfMangler::Mangle(closureFuncName, mModule->mCompiler->GetMangleKind(), methodInstance);
  8599. auto closureFunc = mModule->mBfIRBuilder->CreateFunction(closureFuncType, BfIRLinkageType_External, closureFuncName);
  8600. methodInstance->mIRFunction = closureFunc;
  8601. if (methodInstance->mIsReified)
  8602. mModule->CheckHotMethod(methodInstance, closureFuncName);
  8603. if ((methodInstance->mHotMethod != NULL) && (mModule->mCurMethodState->mHotDataReferenceBuilder))
  8604. mModule->mCurMethodState->mHotDataReferenceBuilder->mInnerMethods.Add(methodInstance->mHotMethod);
  8605. methodState.Reset();
  8606. lambdaInstance = new BfLambdaInstance();
  8607. rootMethodState->mLambdaCache[lambdaBindExpr] = lambdaInstance;
  8608. lambdaInstance->mDelegateTypeInstance = delegateTypeInstance;
  8609. lambdaInstance->mUseTypeInstance = useTypeInstance;
  8610. lambdaInstance->mClosureTypeInstance = closureTypeInst;
  8611. lambdaInstance->mOuterClosure = outerClosure;
  8612. lambdaInstance->mCopyOuterCaptures = copyOuterCaptures;
  8613. lambdaInstance->mIsStatic = methodDef->mIsStatic;
  8614. lambdaInstance->mClosureFunc = closureFunc;
  8615. lambdaInstance->mMethodInstance = methodInstance;
  8616. lambdaInstance->mConstLocals = closureState.mConstLocals;
  8617. lambdaInstance->mParamDecls = tempParamDecls;
  8618. lambdaInstance->mDeclMixinState = mModule->mCurMethodState->mMixinState;
  8619. if (lambdaInstance->mDeclMixinState != NULL)
  8620. lambdaInstance->mDeclMixinState->mHasDeferredUsage = true;
  8621. tempParamDecls.ClearWithoutDeleting();
  8622. closureState.mCapturing = false;
  8623. closureState.mClosureType = useTypeInstance;
  8624. closureInstanceInfo->mThisOverride = useTypeInstance;
  8625. mModule->mIncompleteMethodCount++;
  8626. SetAndRestoreValue<BfClosureState*> prevClosureState(mModule->mCurMethodState->mClosureState, &closureState);
  8627. if (mModule->HasCompiledOutput())
  8628. mModule->SetupIRMethod(methodInstance, methodInstance->mIRFunction, methodInstance->mAlwaysInline);
  8629. // This keeps us from giving errors twice. ProcessMethod can give errors when we capture by value but needed to
  8630. // capture by reference, so we still need to do it for resolve-only
  8631. bool processMethods = (mModule->mCompiler->GetAutoComplete() == NULL) && !mModule->mHadBuildError;
  8632. mModule->mBfIRBuilder->SaveDebugLocation();
  8633. //
  8634. {
  8635. BfGetSymbolReferenceKind prevSymbolRefKind = BfGetSymbolReferenceKind_None;
  8636. if (mModule->mCompiler->mResolvePassData != NULL)
  8637. {
  8638. prevSymbolRefKind = mModule->mCompiler->mResolvePassData->mGetSymbolReferenceKind;
  8639. mModule->mCompiler->mResolvePassData->mGetSymbolReferenceKind = BfGetSymbolReferenceKind_None;
  8640. }
  8641. if (processMethods)
  8642. {
  8643. // If we are in an always-ignored block, we will have mIgnoreWrites set
  8644. // SetAndRestoreValue<bool> prevWantsIgnoreWrite(mModule->mWantsIRIgnoreWrites, mModule->mBfIRBuilder->mIgnoreWrites);
  8645. // mModule->ProcessMethod(methodInstance);
  8646. }
  8647. if (mModule->mCompiler->mResolvePassData != NULL)
  8648. mModule->mCompiler->mResolvePassData->mGetSymbolReferenceKind = prevSymbolRefKind;
  8649. }
  8650. mModule->mBfIRBuilder->RestoreDebugLocation();
  8651. if (mModule->mCompiler->IsSkippingExtraResolveChecks())
  8652. closureFunc = BfIRFunction();
  8653. BfIRFunction dtorFunc;
  8654. if (lambdaBindExpr->mDtor != NULL)
  8655. {
  8656. SizedArray<BfIRType, 1> newTypes;
  8657. newTypes.push_back(mModule->mBfIRBuilder->MapType(useTypeInstance));
  8658. auto voidType = mModule->GetPrimitiveType(BfTypeCode_None);
  8659. auto dtorFuncType = mModule->mBfIRBuilder->CreateFunctionType(mModule->mBfIRBuilder->MapType(voidType), newTypes, false);
  8660. BfMethodDef* dtorMethodDef = new BfMethodDef();
  8661. dtorMethodDef->mDeclaringType = mModule->mCurMethodInstance->mMethodDef->mDeclaringType;
  8662. dtorMethodDef->mName = "~this$";
  8663. dtorMethodDef->mName += methodDef->mName;
  8664. dtorMethodDef->mMethodType = BfMethodType_Normal;
  8665. dtorMethodDef->mBody = lambdaBindExpr->mDtor;
  8666. dtorMethodDef->mIdx = mModule->mCurMethodInstance->mMethodDef->mIdx;
  8667. BfMethodInstance* dtorMethodInstance = new BfMethodInstance();
  8668. dtorMethodInstance->mMethodDef = dtorMethodDef;
  8669. dtorMethodInstance->mReturnType = mModule->GetPrimitiveType(BfTypeCode_None);
  8670. dtorMethodInstance->mMethodInstanceGroup = &methodInstanceGroup;
  8671. StringT<128> dtorMangledName;
  8672. BfMangler::Mangle(dtorMangledName, mModule->mCompiler->GetMangleKind(), dtorMethodInstance);
  8673. dtorFunc = mModule->mBfIRBuilder->CreateFunction(dtorFuncType, BfIRLinkageType_External, dtorMangledName);
  8674. mModule->SetupIRMethod(NULL, dtorFunc, false);
  8675. dtorMethodInstance->mIRFunction = dtorFunc;
  8676. mModule->mIncompleteMethodCount++;
  8677. mModule->mBfIRBuilder->SaveDebugLocation();
  8678. //
  8679. if (processMethods)
  8680. {
  8681. // If we are in an always-ignored block, we will have mIgnoreWrites set
  8682. // SetAndRestoreValue<bool> prevWantsIgnoreWrite(mModule->mWantsIRIgnoreWrites, mModule->mBfIRBuilder->mIgnoreWrites);
  8683. // mModule->ProcessMethod(dtorMethodInstance);
  8684. }
  8685. mModule->mBfIRBuilder->RestoreDebugLocation();
  8686. if (mModule->mCompiler->IsSkippingExtraResolveChecks())
  8687. dtorFunc = BfIRFunction();
  8688. if (dtorMethodInstance->mIsReified)
  8689. mModule->CheckHotMethod(dtorMethodInstance, dtorMangledName);
  8690. if ((dtorMethodInstance->mHotMethod != NULL) && (mModule->mCurMethodState->mHotDataReferenceBuilder))
  8691. mModule->mCurMethodState->mHotDataReferenceBuilder->mInnerMethods.Add(dtorMethodInstance->mHotMethod);
  8692. lambdaInstance->mDtorMethodInstance = dtorMethodInstance;
  8693. lambdaInstance->mDtorFunc = dtorFunc;
  8694. }
  8695. prevClosureState.Restore();
  8696. if (!prevInsertBlock.IsFake())
  8697. mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock);
  8698. for (auto& capturedEntry : capturedEntries)
  8699. {
  8700. BfLambdaCaptureInfo lambdaCapture;
  8701. if (capturedEntry.mName == "__this")
  8702. lambdaCapture.mName = "this";
  8703. else
  8704. lambdaCapture.mName = capturedEntry.mName;
  8705. // if (capturedEntry.mLocalVarDef != NULL)
  8706. // lambdaCapture.mLocalIdx = capturedEntry.mLocalVarDef->mLocalVarId;
  8707. // lambdaCapture.mCopyField = capturedEntry.mCopyField;
  8708. lambdaInstance->mCaptures.Add(lambdaCapture);
  8709. closureInstanceInfo->mCaptureEntries.Add(capturedEntry);
  8710. }
  8711. if (processMethods)
  8712. rootMethodState->mDeferredLambdaInstances.Add(lambdaInstance);
  8713. methodInstance->mMethodInstanceGroup = NULL;
  8714. return lambdaInstance;
  8715. }
  8716. void BfExprEvaluator::Visit(BfLambdaBindExpression* lambdaBindExpr)
  8717. {
  8718. // if (lambdaBindExpr->ToString() == "new (addr, byteCount, addrType) => { DoCreateMemoryBreakpoint(addr, byteCount, addrType, showOptions); }")
  8719. // {
  8720. // NOP;
  8721. // }
  8722. BfTokenNode* newToken = NULL;
  8723. BfAllocTarget allocTarget = ResolveAllocTarget(lambdaBindExpr->mNewToken, newToken);
  8724. if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mBlindCapturing))
  8725. {
  8726. // We're just capturing. We just need to visit the bodies here. This helps infinite recursion with local methods containing lambdas calling each other
  8727. if (lambdaBindExpr->mBody != NULL)
  8728. mModule->VisitChild(lambdaBindExpr->mBody);
  8729. if ((lambdaBindExpr->mDtor != NULL) && (lambdaBindExpr->mDtor->mBody != NULL))
  8730. mModule->VisitChild(lambdaBindExpr->mDtor->mBody);
  8731. return;
  8732. }
  8733. BfLambdaInstance* lambdaInstance = GetLambdaInstance(lambdaBindExpr);
  8734. if (lambdaInstance == NULL)
  8735. return;
  8736. BfTypeInstance* delegateTypeInstance = lambdaInstance->mDelegateTypeInstance;
  8737. BfTypeInstance* useTypeInstance = lambdaInstance->mUseTypeInstance;
  8738. BfTypeInstance* closureTypeInst = lambdaInstance->mClosureTypeInstance;
  8739. mResult = BfTypedValue(mModule->AllocFromType(useTypeInstance, allocTarget, BfIRValue(), BfIRValue(), 0, BfAllocFlags_None), useTypeInstance);
  8740. if (!delegateTypeInstance->IsDelegate())
  8741. {
  8742. mModule->AssertErrorState();
  8743. return;
  8744. }
  8745. auto baseDelegateType = VerifyBaseDelegateType(delegateTypeInstance->mBaseType);
  8746. if (baseDelegateType == NULL)
  8747. {
  8748. mModule->Fail("Invalid delegate type", lambdaBindExpr);
  8749. return;
  8750. }
  8751. auto baseDelegate = mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->MapType(baseDelegateType));
  8752. // >> delegate.mTarget = bindResult.mTarget
  8753. auto nullPtrType = mModule->GetPrimitiveType(BfTypeCode_NullPtr);
  8754. BfIRValue valPtr;
  8755. if (!lambdaInstance->mIsStatic)
  8756. valPtr = mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->MapType(nullPtrType));
  8757. else
  8758. valPtr = mModule->GetDefaultValue(nullPtrType);
  8759. auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(baseDelegate, 0, 2);
  8760. mModule->mBfIRBuilder->CreateStore(valPtr, fieldPtr);
  8761. // >> delegate.mFuncPtr = bindResult.mFunc
  8762. if (lambdaInstance->mClosureFunc)
  8763. {
  8764. auto nullPtrType = mModule->GetPrimitiveType(BfTypeCode_NullPtr);
  8765. auto valPtr = mModule->mBfIRBuilder->CreateBitCast(lambdaInstance->mClosureFunc, mModule->mBfIRBuilder->MapType(nullPtrType));
  8766. auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(baseDelegate, 0, 1);
  8767. mModule->mBfIRBuilder->CreateStore(valPtr, fieldPtr);
  8768. }
  8769. mModule->AddDependency(useTypeInstance, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_Calls);
  8770. // Copy captures into the delegate
  8771. if (lambdaInstance->mClosureTypeInstance != NULL)
  8772. {
  8773. int fieldIdx = 0;
  8774. if (lambdaInstance->mCopyOuterCaptures)
  8775. {
  8776. for (auto& fieldInstance : lambdaInstance->mOuterClosure->mFieldInstances)
  8777. {
  8778. if (!fieldInstance.mResolvedType->IsValuelessType())
  8779. {
  8780. BF_ASSERT(fieldInstance.mDataIdx == fieldIdx + 1);
  8781. auto localVar = mModule->mCurMethodState->mLocals[0];
  8782. auto capturedValue = mModule->mBfIRBuilder->CreateInBoundsGEP(localVar->mValue, 0, fieldInstance.mDataIdx);
  8783. capturedValue = mModule->mBfIRBuilder->CreateLoad(capturedValue);
  8784. auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(mResult.mValue, 0, fieldInstance.mDataIdx);
  8785. mModule->mBfIRBuilder->CreateStore(capturedValue, fieldPtr);
  8786. fieldIdx++;
  8787. }
  8788. }
  8789. }
  8790. // for (auto& capturedEntry : capturedEntries)
  8791. // {
  8792. // BfIRValue capturedValue;
  8793. // if (capturedEntry.mLocalVarDef != NULL)
  8794. // {
  8795. // BfTypedValue localResult = LoadLocal(capturedEntry.mLocalVarDef, true);
  8796. //
  8797. // if (!capturedEntry.mType->IsRef())
  8798. // {
  8799. // if (localResult.IsSplat())
  8800. // {
  8801. // auto aggResult = mModule->AggregateSplat(localResult);
  8802. // capturedValue = aggResult.mValue;
  8803. // }
  8804. // else
  8805. // {
  8806. // localResult = mModule->LoadValue(localResult);
  8807. // capturedValue = localResult.mValue;
  8808. // if ((capturedEntry.mLocalVarDef->mResolvedType->IsRef()) && (!capturedEntry.mType->IsRef()))
  8809. // capturedValue = mModule->mBfIRBuilder->CreateLoad(capturedValue);
  8810. // }
  8811. // }
  8812. // else
  8813. // {
  8814. // if (capturedEntry.mLocalVarDef->mResolvedType->IsRef())
  8815. // localResult = mModule->LoadValue(localResult);
  8816. // capturedValue = localResult.mValue;
  8817. // }
  8818. // }
  8819. // else
  8820. // {
  8821. // // Read captured field from outer lambda ('this')
  8822. // auto localVar = mModule->mCurMethodState->mLocals[0];
  8823. // capturedValue = mModule->mBfIRBuilder->CreateInBoundsGEP(localVar->mValue, 0, capturedEntry.mCopyField->mDataIdx);
  8824. // if ((capturedEntry.mCopyField->mResolvedType->IsRef()) || (!capturedEntry.mType->IsRef()))
  8825. // {
  8826. // capturedValue = mModule->mBfIRBuilder->CreateLoad(capturedValue);
  8827. // if ((capturedEntry.mCopyField->mResolvedType->IsRef()) && (!capturedEntry.mType->IsRef()))
  8828. // capturedValue = mModule->mBfIRBuilder->CreateLoad(capturedValue);
  8829. // }
  8830. // }
  8831. // if (capturedValue)
  8832. // {
  8833. // auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(mResult.mValue, 0, closureTypeInst->mFieldInstances[fieldIdx].mDataIdx);
  8834. // mModule->mBfIRBuilder->CreateStore(capturedValue, fieldPtr);
  8835. // }
  8836. // fieldIdx++;
  8837. // }
  8838. int captureIdx = 0;
  8839. //for (auto& capturedEntry : lambdaInstance->mCaptures)
  8840. for (int captureIdx = 0; captureIdx < (int)lambdaInstance->mCaptures.size(); captureIdx++)
  8841. {
  8842. auto& capturedEntry = lambdaInstance->mCaptures[captureIdx];
  8843. BfIdentifierNode* identifierNode = lambdaInstance->mMethodInstance->mMethodInfoEx->mClosureInstanceInfo->mCaptureEntries[captureIdx].mNameNode;
  8844. //if (captureIdx < lambdaInstance->mMethodInstance->mClosureInstanceInfo->mCaptureNodes.size)
  8845. BfIRValue capturedValue;
  8846. // if (capturedEntry.mLocalVarDef != NULL)
  8847. // {
  8848. // BfTypedValue localResult = LoadLocal(capturedEntry.mLocalVarDef, true);
  8849. //
  8850. // if (!capturedEntry.mType->IsRef())
  8851. // {
  8852. // if (localResult.IsSplat())
  8853. // {
  8854. // auto aggResult = mModule->AggregateSplat(localResult);
  8855. // capturedValue = aggResult.mValue;
  8856. // }
  8857. // else
  8858. // {
  8859. // localResult = mModule->LoadValue(localResult);
  8860. // capturedValue = localResult.mValue;
  8861. // if ((capturedEntry.mLocalVarDef->mResolvedType->IsRef()) && (!capturedEntry.mType->IsRef()))
  8862. // capturedValue = mModule->mBfIRBuilder->CreateLoad(capturedValue);
  8863. // }
  8864. // }
  8865. // else
  8866. // {
  8867. // if (capturedEntry.mLocalVarDef->mResolvedType->IsRef())
  8868. // localResult = mModule->LoadValue(localResult);
  8869. // capturedValue = localResult.mValue;
  8870. // }
  8871. // }
  8872. // else
  8873. // {
  8874. // // Read captured field from outer lambda ('this')
  8875. // auto localVar = mModule->mCurMethodState->mLocals[0];
  8876. // capturedValue = mModule->mBfIRBuilder->CreateInBoundsGEP(localVar->mValue, 0, capturedEntry.mCopyField->mDataIdx);
  8877. // if ((capturedEntry.mCopyField->mResolvedType->IsRef()) || (!capturedEntry.mType->IsRef()))
  8878. // {
  8879. // capturedValue = mModule->mBfIRBuilder->CreateLoad(capturedValue);
  8880. // if ((capturedEntry.mCopyField->mResolvedType->IsRef()) && (!capturedEntry.mType->IsRef()))
  8881. // capturedValue = mModule->mBfIRBuilder->CreateLoad(capturedValue);
  8882. // }
  8883. // }
  8884. auto fieldInstance = &closureTypeInst->mFieldInstances[fieldIdx];
  8885. BfTypedValue capturedTypedVal;
  8886. if (identifierNode != NULL)
  8887. capturedTypedVal = DoImplicitArgCapture(NULL, identifierNode);
  8888. else
  8889. capturedTypedVal = LookupIdentifier(NULL, capturedEntry.mName);
  8890. if (!fieldInstance->mResolvedType->IsRef())
  8891. capturedTypedVal = mModule->LoadOrAggregateValue(capturedTypedVal);
  8892. else if (!capturedTypedVal.IsAddr())
  8893. {
  8894. mModule->Fail(StrFormat("Unable to capture '%s' by reference", capturedEntry.mName.c_str()), lambdaBindExpr);
  8895. break;
  8896. }
  8897. capturedValue = capturedTypedVal.mValue;
  8898. if (capturedValue)
  8899. {
  8900. auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(mResult.mValue, 0, fieldInstance->mDataIdx);
  8901. mModule->mBfIRBuilder->CreateStore(capturedValue, fieldPtr);
  8902. }
  8903. else
  8904. {
  8905. mModule->Fail(StrFormat("Unable to capture '%s'", capturedEntry.mName.c_str()), lambdaBindExpr);
  8906. mModule->AssertErrorState();
  8907. }
  8908. fieldIdx++;
  8909. }
  8910. if (lambdaInstance->mDtorFunc)
  8911. {
  8912. auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(mResult.mValue, 0, closureTypeInst->mFieldInstances[fieldIdx].mDataIdx);
  8913. auto voidType = mModule->GetPrimitiveType(BfTypeCode_None);
  8914. auto voidPtrType = mModule->CreatePointerType(voidType);
  8915. auto dtorThunk = mModule->mBfIRBuilder->CreateBitCast(lambdaInstance->mDtorFunc, mModule->mBfIRBuilder->MapType(voidPtrType));
  8916. mModule->mBfIRBuilder->CreateStore(dtorThunk, fieldPtr);
  8917. fieldIdx++;
  8918. }
  8919. }
  8920. }
  8921. void BfExprEvaluator::ProcessArrayInitializer(BfTokenNode* openToken, const BfSizedArray<BfExpression*>& valueExprs, const BfSizedArray<BfTokenNode*>& commas, BfTokenNode* closeToken, int dimensions, SizedArrayImpl<int64>& dimLengths, int dim, bool& hasFailed)
  8922. {
  8923. bool setSize = false;
  8924. if (dim == dimLengths.size())
  8925. {
  8926. dimLengths.push_back((int)valueExprs.size());
  8927. setSize = true;
  8928. }
  8929. else if (dimLengths[dim] == -1)
  8930. {
  8931. dimLengths[dim] = (int)valueExprs.size();
  8932. setSize = true;
  8933. }
  8934. int64 initCountDiff = (int)valueExprs.size() - dimLengths[dim];
  8935. if ((dimLengths[dim] != -1) && (initCountDiff != 0) && (!hasFailed))
  8936. {
  8937. if (initCountDiff > 0)
  8938. {
  8939. mModule->Fail(StrFormat("Too many initializers, expected %d fewer", initCountDiff), valueExprs[(int)dimLengths[dim]]);
  8940. hasFailed = true;
  8941. }
  8942. else
  8943. {
  8944. // If it ends with ", ?) or ",)" then allow unsized
  8945. if (((valueExprs.size() == 0) || (BfNodeDynCast<BfUninitializedExpression>(valueExprs.back()) == NULL)) &&
  8946. (commas.size() < valueExprs.size()))
  8947. {
  8948. BfAstNode* refNode = closeToken;
  8949. if ((refNode == NULL) && (mModule->mParentNodeEntry != NULL))
  8950. refNode = mModule->mParentNodeEntry->mNode;
  8951. mModule->Fail(StrFormat("Too few initializer, expected %d more", -initCountDiff), refNode);
  8952. hasFailed = true;
  8953. }
  8954. }
  8955. }
  8956. for (int i = 0; i < (int)valueExprs.size(); i++)
  8957. {
  8958. BfExpression* expr = valueExprs[i];
  8959. if (auto uninitExpr = BfNodeDynCast<BfUninitializedExpression>(expr))
  8960. {
  8961. continue;
  8962. }
  8963. auto innerInitExpr = BfNodeDynCast<BfCollectionInitializerExpression>(expr);
  8964. if (dim < dimensions - 1)
  8965. {
  8966. if (innerInitExpr == NULL)
  8967. {
  8968. if (auto innerTupleExpr = BfNodeDynCast<BfTupleExpression>(expr))
  8969. {
  8970. ProcessArrayInitializer(innerTupleExpr->mOpenParen, innerTupleExpr->mValues, innerTupleExpr->mCommas, innerTupleExpr->mCloseParen, dimensions, dimLengths, dim + 1, hasFailed);
  8971. }
  8972. else if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(expr))
  8973. {
  8974. SizedArray<BfExpression*, 1> values;
  8975. values.Add(parenExpr->mExpression);
  8976. SizedArray<BfTokenNode*, 1> commas;
  8977. ProcessArrayInitializer(parenExpr->mOpenParen, values, commas, parenExpr->mCloseParen, dimensions, dimLengths, dim + 1, hasFailed);
  8978. }
  8979. else
  8980. {
  8981. hasFailed = true;
  8982. mModule->Fail("A nested array initializer is expected", expr);
  8983. continue;
  8984. }
  8985. }
  8986. else
  8987. ProcessArrayInitializer(innerInitExpr->mOpenBrace, innerInitExpr->mValues, innerInitExpr->mCommas, innerInitExpr->mCloseBrace, dimensions, dimLengths, dim + 1, hasFailed);
  8988. }
  8989. else if (innerInitExpr != NULL)
  8990. {
  8991. hasFailed = true;
  8992. mModule->Fail("Unexpected nested initializer", expr);
  8993. ProcessArrayInitializer(innerInitExpr->mOpenBrace, innerInitExpr->mValues, innerInitExpr->mCommas, innerInitExpr->mCloseBrace, dimensions, dimLengths, dim + 1, hasFailed);
  8994. }
  8995. else
  8996. {
  8997. //mModule->Fail("Expected initializer", )
  8998. }
  8999. }
  9000. }
  9001. void BfExprEvaluator::CheckObjectCreateTypeRef(BfType* expectingType, BfAstNode* afterNode)
  9002. {
  9003. auto autoComplete = GetAutoComplete();
  9004. if ((autoComplete != NULL) && (afterNode != NULL) && (autoComplete->mIsAutoComplete) &&
  9005. (afterNode->IsFromParser(mModule->mCompiler->mResolvePassData->mParser)) &&
  9006. (afterNode->GetParser()->mCursorIdx == afterNode->GetSrcEnd() + 1))
  9007. {
  9008. BfType* expectingType = mExpectingType;
  9009. BfTypeInstance* expectingTypeInst = NULL;
  9010. if (mExpectingType != NULL)
  9011. {
  9012. expectingTypeInst = mExpectingType->ToTypeInstance();
  9013. }
  9014. if ((mExpectingType != NULL) && (((expectingTypeInst == NULL) || (!expectingTypeInst->mTypeDef->mIsDelegate))))
  9015. {
  9016. // Why were we doing this? It floods the autocomplete with every possible type
  9017. //autoComplete->AddTopLevelTypes(NULL);
  9018. autoComplete->mInsertStartIdx = afterNode->GetSourceData()->ToParser()->mCursorIdx;
  9019. BF_ASSERT(autoComplete->mInsertStartIdx != -1);
  9020. auto expectingType = mExpectingType;
  9021. while (expectingType->IsArray())
  9022. {
  9023. auto arrayType = (BfArrayType*)expectingType;
  9024. expectingType = arrayType->mTypeGenericArguments[0];
  9025. }
  9026. auto expectingTypeInst = expectingType->ToTypeInstance();
  9027. if (expectingTypeInst != NULL)
  9028. {
  9029. autoComplete->AddTypeInstanceEntry(expectingTypeInst);
  9030. }
  9031. else
  9032. autoComplete->mDefaultSelection = mModule->TypeToString(expectingType);
  9033. }
  9034. }
  9035. }
  9036. void BfExprEvaluator::Visit(BfObjectCreateExpression* objCreateExpr)
  9037. {
  9038. auto autoComplete = GetAutoComplete();
  9039. if ((autoComplete != NULL) && (objCreateExpr->mTypeRef != NULL))
  9040. {
  9041. autoComplete->CheckTypeRef(objCreateExpr->mTypeRef, false, true);
  9042. }
  9043. //if (objCreateExpr->mArraySizeSpecifier == NULL)
  9044. CheckObjectCreateTypeRef(mExpectingType, objCreateExpr->mNewNode);
  9045. BfTokenNode* newToken = NULL;
  9046. BfAllocTarget allocTarget = ResolveAllocTarget(objCreateExpr->mNewNode, newToken);
  9047. bool isScopeAlloc = newToken->GetToken() == BfToken_Scope;
  9048. bool isAppendAlloc = newToken->GetToken() == BfToken_Append;
  9049. bool isStackAlloc = (newToken->GetToken() == BfToken_Stack) || (isScopeAlloc);
  9050. bool isArrayAlloc = false;// (objCreateExpr->mArraySizeSpecifier != NULL);
  9051. bool isRawArrayAlloc = (objCreateExpr->mStarToken != NULL);
  9052. if (isScopeAlloc)
  9053. {
  9054. if ((mBfEvalExprFlags & BfEvalExprFlags_FieldInitializer) != 0)
  9055. {
  9056. mModule->Warn(0, "This allocation will only be in scope during the constructor. Consider using a longer-term allocation such as 'new'", objCreateExpr->mNewNode);
  9057. }
  9058. if (objCreateExpr->mNewNode == newToken) // Scope, no target specified
  9059. {
  9060. if (mModule->mParentNodeEntry != NULL)
  9061. {
  9062. if (auto assignExpr = BfNodeDynCastExact<BfAssignmentExpression>(mModule->mParentNodeEntry->mNode))
  9063. {
  9064. if (mModule->mCurMethodState->mCurScope->mCloseNode == NULL)
  9065. {
  9066. // 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
  9067. if ((mBfEvalExprFlags & BfEvalExprFlags_PendingPropSet) == 0)
  9068. mModule->Warn(0, "This allocation will immediately go out of scope. Consider specifying a wider scope target such as 'scope::'", objCreateExpr->mNewNode);
  9069. }
  9070. }
  9071. }
  9072. }
  9073. }
  9074. BfAutoParentNodeEntry autoParentNodeEntry(mModule, objCreateExpr);
  9075. SizedArray<BfAstNode*, 2> dimLengthRefs;
  9076. SizedArray<BfIRValue, 2> dimLengthVals;
  9077. BfArrayType* arrayType = NULL;
  9078. BfType* unresolvedTypeRef = NULL;
  9079. BfType* resolvedTypeRef = NULL;
  9080. if (objCreateExpr->mTypeRef == NULL)
  9081. {
  9082. if ((!mExpectingType) || (!mExpectingType->IsArray()))
  9083. {
  9084. mModule->Fail("Cannot imply array type. Explicitly state array type or use array in an assignment to an array type.", objCreateExpr);
  9085. resolvedTypeRef = mModule->mContext->mBfObjectType;
  9086. unresolvedTypeRef = resolvedTypeRef;
  9087. }
  9088. else
  9089. {
  9090. auto arrayType = (BfArrayType*)mExpectingType;
  9091. unresolvedTypeRef = arrayType->GetUnderlyingType();
  9092. resolvedTypeRef = unresolvedTypeRef;
  9093. }
  9094. }
  9095. else
  9096. {
  9097. if ((objCreateExpr->mTypeRef->IsExact<BfDotTypeReference>()) && (mExpectingType != NULL))
  9098. {
  9099. //mModule->SetElementType(objCreateExpr->mTypeRef, BfSourceElementType_TypeRef);
  9100. if (mExpectingType->IsObject())
  9101. {
  9102. unresolvedTypeRef = mExpectingType;
  9103. if (unresolvedTypeRef->IsArray())
  9104. {
  9105. arrayType = (BfArrayType*)unresolvedTypeRef;
  9106. unresolvedTypeRef = unresolvedTypeRef->GetUnderlyingType();
  9107. isArrayAlloc = true;
  9108. }
  9109. }
  9110. else if (mExpectingType->IsPointer())
  9111. {
  9112. unresolvedTypeRef = mExpectingType->GetUnderlyingType();
  9113. }
  9114. }
  9115. if (unresolvedTypeRef == NULL)
  9116. {
  9117. if (auto arrayTypeRef = BfNodeDynCast<BfArrayTypeRef>(objCreateExpr->mTypeRef))
  9118. {
  9119. isArrayAlloc = true;
  9120. if (auto dotTypeRef = BfNodeDynCast<BfDotTypeReference>(arrayTypeRef->mElementType))
  9121. {
  9122. if ((mExpectingType != NULL) &&
  9123. ((mExpectingType->IsArray()) || (mExpectingType->IsSizedArray())))
  9124. unresolvedTypeRef = mExpectingType->GetUnderlyingType();
  9125. }
  9126. if (unresolvedTypeRef == NULL)
  9127. unresolvedTypeRef = mModule->ResolveTypeRef(arrayTypeRef->mElementType);
  9128. if (unresolvedTypeRef == NULL)
  9129. unresolvedTypeRef = mModule->mContext->mBfObjectType;
  9130. int dimensions = 1;
  9131. if (arrayTypeRef->mParams.size() != 0)
  9132. {
  9133. auto intType = mModule->ResolveTypeDef(mModule->mSystem->mTypeIntPtr);
  9134. for (auto arg : arrayTypeRef->mParams)
  9135. {
  9136. if (auto tokenNode = BfNodeDynCastExact<BfTokenNode>(arg))
  9137. {
  9138. if (tokenNode->GetToken() == BfToken_Comma)
  9139. {
  9140. if (isRawArrayAlloc)
  9141. {
  9142. mModule->Fail("Sized arrays cannot be multidimensional.", tokenNode);
  9143. continue;
  9144. }
  9145. dimensions++;
  9146. if (dimensions == 5)
  9147. {
  9148. mModule->Fail("Too many array dimensions, consider using a jagged array.", tokenNode);
  9149. }
  9150. continue;
  9151. }
  9152. }
  9153. auto expr = BfNodeDynCast<BfExpression>(arg);
  9154. if ((isRawArrayAlloc) && (!dimLengthVals.IsEmpty()))
  9155. {
  9156. mModule->CreateValueFromExpression(expr, intType);
  9157. continue;
  9158. }
  9159. dimLengthRefs.Add(expr);
  9160. BfTypedValue dimLength;
  9161. if (expr == NULL)
  9162. {
  9163. // Not specified
  9164. dimLengthVals.push_back(BfIRValue());
  9165. continue;
  9166. }
  9167. if (arg != NULL)
  9168. {
  9169. dimLength = mModule->CreateValueFromExpression(expr, intType, BfEvalExprFlags_NoCast);
  9170. BfCastFlags castFlags = BfCastFlags_None;
  9171. if ((dimLength) && (dimLength.mType->IsInteger()))
  9172. {
  9173. // Allow uint for size - just force to int
  9174. if (!((BfPrimitiveType*)dimLength.mType)->IsSigned())
  9175. castFlags = BfCastFlags_Explicit;
  9176. }
  9177. if (dimLength)
  9178. dimLength = mModule->Cast(expr, dimLength, intType, castFlags);
  9179. }
  9180. if (!dimLength)
  9181. {
  9182. dimLength = mModule->GetDefaultTypedValue(intType);
  9183. }
  9184. dimLengthVals.push_back(dimLength.mValue);
  9185. }
  9186. }
  9187. if ((arrayTypeRef->mParams.size() == 0) && (objCreateExpr->mOpenToken == NULL))
  9188. mModule->Fail("Array size or array initializer expected", arrayTypeRef->mOpenBracket);
  9189. if (dimensions > 4)
  9190. dimensions = 4;
  9191. if (!isRawArrayAlloc)
  9192. arrayType = mModule->CreateArrayType(unresolvedTypeRef, dimensions);
  9193. }
  9194. if (unresolvedTypeRef == NULL)
  9195. {
  9196. unresolvedTypeRef = ResolveTypeRef(objCreateExpr->mTypeRef, BfPopulateType_Declaration, BfResolveTypeRefFlag_NoResolveGenericParam);
  9197. }
  9198. }
  9199. resolvedTypeRef = unresolvedTypeRef;
  9200. if ((resolvedTypeRef != NULL) && (resolvedTypeRef->IsVar()))
  9201. resolvedTypeRef = unresolvedTypeRef;
  9202. }
  9203. if (resolvedTypeRef == NULL)
  9204. return;
  9205. auto resultType = resolvedTypeRef;
  9206. if ((resolvedTypeRef->IsInterface()) && (!isArrayAlloc))
  9207. {
  9208. mModule->Fail("Cannot create an instance of an interface", objCreateExpr->mTypeRef);
  9209. resolvedTypeRef = mModule->mContext->mBfObjectType;
  9210. }
  9211. BfTypeInstance* typeInstance = resolvedTypeRef->ToTypeInstance();
  9212. int elementSize = resolvedTypeRef->mSize;
  9213. int elementAlign = resolvedTypeRef->mAlign;
  9214. BfIRType allocType = mModule->mBfIRBuilder->MapType(resolvedTypeRef);
  9215. if (typeInstance != NULL)
  9216. {
  9217. if (!mModule->mCurTypeInstance->mResolvingVarField)
  9218. mModule->PopulateType(typeInstance);
  9219. if ((typeInstance->mTypeDef->mIsDelegate) && (!isArrayAlloc))
  9220. mModule->Fail("Delegates must be constructed through delegate binding", objCreateExpr->mTypeRef);
  9221. elementSize = BF_MAX(0, typeInstance->mInstSize);
  9222. elementAlign = typeInstance->mInstAlign;
  9223. allocType = mModule->mBfIRBuilder->MapTypeInst(typeInstance);
  9224. }
  9225. if (isAppendAlloc)
  9226. {
  9227. if (!mModule->mCurTypeInstance->IsObject())
  9228. {
  9229. mModule->Fail("Append allocations are only allowed in classes", objCreateExpr->mNewNode);
  9230. isAppendAlloc = false;
  9231. }
  9232. else if ((mBfEvalExprFlags & BfEvalExprFlags_VariableDeclaration) == 0)
  9233. {
  9234. mModule->Fail("Append allocations are only allowed as local variable initializers in constructor body", objCreateExpr->mNewNode);
  9235. isAppendAlloc = false;
  9236. }
  9237. else
  9238. {
  9239. auto methodDef = mModule->mCurMethodInstance->mMethodDef;
  9240. if (methodDef->mMethodType == BfMethodType_CtorCalcAppend)
  9241. {
  9242. mModule->Fail("Append allocations are only allowed as local variable declarations in the main method body", objCreateExpr->mNewNode);
  9243. isAppendAlloc = false;
  9244. }
  9245. else if (!methodDef->mHasAppend)
  9246. {
  9247. mModule->Fail("Append allocations can only be used on constructors with [AllowAppend] specified", objCreateExpr->mNewNode);
  9248. isAppendAlloc = false;
  9249. }
  9250. else if (methodDef->mMethodType != BfMethodType_Ctor)
  9251. {
  9252. mModule->Fail("Append allocations are only allowed in constructors", objCreateExpr->mNewNode);
  9253. isAppendAlloc = false;
  9254. }
  9255. else if (methodDef->mIsStatic)
  9256. {
  9257. mModule->Fail("Append allocations are only allowed in non-static constructors", objCreateExpr->mNewNode);
  9258. isAppendAlloc = false;
  9259. }
  9260. }
  9261. }
  9262. if (isArrayAlloc)
  9263. {
  9264. const int MAX_DIMENSIONS = 2;
  9265. int dimensions = 1;
  9266. if (arrayType != NULL)
  9267. {
  9268. dimensions = arrayType->mDimensions;
  9269. mModule->AddDependency(arrayType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_Calls);
  9270. }
  9271. bool zeroMemory = true;
  9272. if (objCreateExpr->mOpenToken != NULL)
  9273. {
  9274. if ((objCreateExpr->mArguments.size() == 1) &&
  9275. (BfNodeDynCastExact<BfUninitializedExpression>(objCreateExpr->mArguments[0]) != NULL))
  9276. {
  9277. // Special case for a single "{ ? }"
  9278. zeroMemory = false;
  9279. }
  9280. else
  9281. {
  9282. SizedArray<int64, 2> dimLengths;
  9283. if (dimLengthVals.size() != 0)
  9284. {
  9285. for (int dim = 0; dim < dimensions; dim++)
  9286. {
  9287. BfIRValue dimLengthVal;
  9288. if (dim < (int)dimLengthVals.size())
  9289. dimLengthVal = dimLengthVals[dim];
  9290. if (!dimLengthVal)
  9291. {
  9292. dimLengths.push_back(-1);
  9293. continue;
  9294. }
  9295. auto constant = mModule->mBfIRBuilder->GetConstant(dimLengthVal);
  9296. if ((constant != NULL) && (mModule->mBfIRBuilder->IsInt(constant->mTypeCode)))
  9297. {
  9298. int64 dimLength = constant->mInt64;
  9299. dimLengths.push_back(dimLength);
  9300. }
  9301. else
  9302. {
  9303. mModule->Fail("A constant length is required when using an initializer", dimLengthRefs[dim]);
  9304. dimLengths.push_back(-1);
  9305. }
  9306. }
  9307. }
  9308. // Ending in an ", )" means we need to zero-fill ending
  9309. zeroMemory = objCreateExpr->mCommas.size() >= objCreateExpr->mArguments.size();
  9310. bool hasFailed = false;
  9311. ProcessArrayInitializer(objCreateExpr->mOpenToken, objCreateExpr->mArguments, objCreateExpr->mCommas, objCreateExpr->mCloseToken, dimensions, dimLengths, 0, hasFailed);
  9312. dimLengthVals.resize(dimLengths.size());
  9313. for (int i = 0; i < (int)dimLengthVals.size(); i++)
  9314. {
  9315. if (!dimLengthVals[i])
  9316. {
  9317. auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  9318. dimLengthVals[i] = mModule->GetConstValue(dimLengths[i], intType);
  9319. }
  9320. }
  9321. }
  9322. }
  9323. while ((int)dimLengthVals.size() < dimensions)
  9324. dimLengthVals.push_back(mModule->GetConstValue(0));
  9325. BfTypedValue arrayValue;
  9326. BfIRValue arraySize;
  9327. for (BfIRValue dimSize : dimLengthVals)
  9328. {
  9329. if (!arraySize)
  9330. arraySize = dimSize;
  9331. else
  9332. arraySize = mModule->mBfIRBuilder->CreateMul(arraySize, dimSize);
  9333. }
  9334. BfAllocFlags allocFlags = BfAllocFlags_None;
  9335. if (isRawArrayAlloc)
  9336. allocFlags = (BfAllocFlags)(allocFlags | BfAllocFlags_RawArray);
  9337. int writeIdx = 0;
  9338. std::function<void(BfIRValue addr, int curDim, const BfSizedArray<BfExpression*>& valueExprs)> _HandleInitExprs = [&](BfIRValue addr, int curDim, const BfSizedArray<BfExpression*>& valueExprs)
  9339. {
  9340. int exprIdx = 0;
  9341. int dimWriteIdx = 0;
  9342. bool isUninit = false;
  9343. int dimLength = -1;
  9344. if (dimLengthVals[curDim].IsConst())
  9345. {
  9346. auto constant = mModule->mBfIRBuilder->GetConstant(dimLengthVals[curDim]);
  9347. dimLength = constant->mInt32;
  9348. }
  9349. while (exprIdx < (int)valueExprs.size())
  9350. {
  9351. auto initExpr = valueExprs[exprIdx];
  9352. exprIdx++;
  9353. if (!initExpr)
  9354. break;
  9355. if (auto unintExpr = BfNodeDynCastExact<BfUninitializedExpression>(initExpr))
  9356. {
  9357. isUninit = true;
  9358. break;
  9359. }
  9360. if (exprIdx > dimLength)
  9361. break;
  9362. if (curDim < dimensions - 1)
  9363. {
  9364. if (auto innerTupleExpr = BfNodeDynCast<BfTupleExpression>(initExpr))
  9365. {
  9366. _HandleInitExprs(addr, curDim + 1, innerTupleExpr->mValues);
  9367. }
  9368. else if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(initExpr))
  9369. {
  9370. SizedArray<BfExpression*, 1> values;
  9371. values.Add(parenExpr->mExpression);
  9372. _HandleInitExprs(addr, curDim + 1, values);
  9373. }
  9374. else if (auto innerInitExpr = BfNodeDynCast<BfCollectionInitializerExpression>(initExpr))
  9375. {
  9376. _HandleInitExprs(addr, curDim + 1, innerInitExpr->mValues);
  9377. }
  9378. dimWriteIdx++;
  9379. continue;
  9380. }
  9381. auto elemAddr = mModule->CreateIndexedValue(resultType, addr, writeIdx);
  9382. writeIdx++;
  9383. dimWriteIdx++;
  9384. BfTypedValue elemPtrTypedVal = BfTypedValue(elemAddr, resultType, BfTypedValueKind_Addr);
  9385. BfExprEvaluator exprEvaluator(mModule);
  9386. exprEvaluator.mExpectingType = resultType;
  9387. exprEvaluator.mReceivingValue = &elemPtrTypedVal;
  9388. exprEvaluator.Evaluate(initExpr);
  9389. exprEvaluator.GetResult();
  9390. if (exprEvaluator.mReceivingValue == NULL)
  9391. {
  9392. // We wrote directly to the array in-place, we're done with this element
  9393. continue;
  9394. }
  9395. auto storeValue = exprEvaluator.mResult;
  9396. if (!storeValue)
  9397. continue;
  9398. storeValue = mModule->Cast(initExpr, storeValue, resultType);
  9399. if (!storeValue)
  9400. continue;
  9401. if (!resultType->IsValuelessType())
  9402. {
  9403. storeValue = mModule->LoadValue(storeValue);
  9404. mModule->mBfIRBuilder->CreateStore(storeValue.mValue, elemAddr);
  9405. }
  9406. }
  9407. int clearFromIdx = writeIdx;
  9408. int sectionElemCount = 1;
  9409. BfIRValue numElemsLeft = arraySize;
  9410. if (dimLength != -1)
  9411. {
  9412. int clearCount = dimLength - dimWriteIdx;
  9413. if (clearCount > 0)
  9414. {
  9415. for (int checkDim = curDim + 1; checkDim < (int)dimLengthVals.size(); checkDim++)
  9416. {
  9417. if (dimLengthVals[checkDim].IsConst())
  9418. {
  9419. auto constant = mModule->mBfIRBuilder->GetConstant(dimLengthVals[checkDim]);
  9420. clearCount *= constant->mInt32;
  9421. sectionElemCount *= constant->mInt32;
  9422. }
  9423. }
  9424. }
  9425. writeIdx += clearCount;
  9426. numElemsLeft = mModule->GetConstValue(clearCount);
  9427. }
  9428. // Actually leave it alone?
  9429. if ((isUninit) && (mModule->IsOptimized()))
  9430. return;
  9431. bool doClear = true;
  9432. if (numElemsLeft.IsConst())
  9433. {
  9434. auto constant = mModule->mBfIRBuilder->GetConstant(numElemsLeft);
  9435. doClear = constant->mInt64 > 0;
  9436. }
  9437. if (doClear)
  9438. {
  9439. // We multiply by GetStride. This relies on the fact that we over-allocate on the array allocation -- the last
  9440. // element doesn't need to be padded out to the element alignment, but we do anyway. Otherwise this would be
  9441. // a more complicated computation
  9442. auto clearBytes = mModule->mBfIRBuilder->CreateMul(numElemsLeft, mModule->GetConstValue(resultType->GetStride()));
  9443. if (isUninit)
  9444. {
  9445. // Limit to a reasonable number of bytes to stomp with 0xCC
  9446. int maxStompBytes = BF_MIN(128, resultType->GetStride() * sectionElemCount);
  9447. if (clearBytes.IsConst())
  9448. {
  9449. auto constant = mModule->mBfIRBuilder->GetConstant(clearBytes);
  9450. if (constant->mInt64 > maxStompBytes)
  9451. clearBytes = mModule->GetConstValue(maxStompBytes);
  9452. }
  9453. else
  9454. {
  9455. auto insertBlock = mModule->mBfIRBuilder->GetInsertBlock();
  9456. auto gtBlock = mModule->mBfIRBuilder->CreateBlock("unint.gt");
  9457. auto contBlock = mModule->mBfIRBuilder->CreateBlock("unint.cont");
  9458. auto cmp = mModule->mBfIRBuilder->CreateCmpLTE(clearBytes, mModule->GetConstValue(maxStompBytes), true);
  9459. mModule->mBfIRBuilder->CreateCondBr(cmp, contBlock, gtBlock);
  9460. mModule->mBfIRBuilder->AddBlock(gtBlock);
  9461. mModule->mBfIRBuilder->SetInsertPoint(gtBlock);
  9462. mModule->mBfIRBuilder->CreateBr(contBlock);
  9463. mModule->mBfIRBuilder->AddBlock(contBlock);
  9464. mModule->mBfIRBuilder->SetInsertPoint(contBlock);
  9465. auto phi = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(mModule->GetPrimitiveType(BfTypeCode_IntPtr)), 2);
  9466. mModule->mBfIRBuilder->AddPhiIncoming(phi, clearBytes, insertBlock);
  9467. mModule->mBfIRBuilder->AddPhiIncoming(phi, mModule->GetConstValue(maxStompBytes), gtBlock);
  9468. clearBytes = phi;
  9469. }
  9470. }
  9471. mModule->mBfIRBuilder->PopulateType(resultType);
  9472. mModule->mBfIRBuilder->CreateMemSet(mModule->CreateIndexedValue(resultType, addr, clearFromIdx),
  9473. mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int8, isUninit ? 0xCC : 0), clearBytes, resultType->mAlign);
  9474. }
  9475. };
  9476. if (isRawArrayAlloc)
  9477. {
  9478. // 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
  9479. BfType* ptrType = mModule->CreatePointerType(resultType);
  9480. if (isAppendAlloc)
  9481. arrayValue = BfTypedValue(mModule->AppendAllocFromType(resultType, BfIRValue(), 0, arraySize, (int)dimLengthVals.size(), isRawArrayAlloc, false), ptrType);
  9482. else
  9483. {
  9484. arrayValue = BfTypedValue(mModule->AllocFromType(resultType, allocTarget, BfIRValue(), arraySize, (int)dimLengthVals.size(), allocFlags), ptrType);
  9485. }
  9486. _HandleInitExprs(arrayValue.mValue, 0, objCreateExpr->mArguments);
  9487. mResult = arrayValue;
  9488. return;
  9489. }
  9490. if (dimLengthVals.size() > 4)
  9491. {
  9492. dimLengthVals.RemoveRange(4, dimLengthVals.size() - 4);
  9493. mModule->Fail("Too many array dimensions, consider using a jagged array.", objCreateExpr);
  9494. }
  9495. if (isAppendAlloc)
  9496. arrayValue = BfTypedValue(mModule->AppendAllocFromType(resultType, BfIRValue(), 0, arraySize, (int)dimLengthVals.size(), isRawArrayAlloc, zeroMemory), arrayType);
  9497. else
  9498. {
  9499. arrayValue = BfTypedValue(mModule->AllocFromType(resultType, allocTarget, BfIRValue(), arraySize, (int)dimLengthVals.size(), allocFlags), arrayType);
  9500. if (isScopeAlloc)
  9501. {
  9502. // See notes below on "general" SkipObjectAccessCheck usage on why we can do this
  9503. mModule->SkipObjectAccessCheck(arrayValue);
  9504. }
  9505. }
  9506. //mModule->InitTypeInst(arrayValue, scopeData);
  9507. BfAstNode* refNode = objCreateExpr->mTypeRef;
  9508. while (true)
  9509. {
  9510. if (auto arrayRef = BfNodeDynCast<BfElementedTypeRef>(refNode))
  9511. {
  9512. refNode = arrayRef->mElementType;
  9513. continue;
  9514. }
  9515. break;
  9516. }
  9517. BfResolvedArgs resolvedArgs;
  9518. if (autoComplete != NULL)
  9519. {
  9520. SetAndRestoreValue<bool> prevCapturing(autoComplete->mIsCapturingMethodMatchInfo, false);
  9521. MatchConstructor(refNode, objCreateExpr, arrayValue, arrayType, resolvedArgs, false, false);
  9522. }
  9523. else
  9524. {
  9525. MatchConstructor(refNode, objCreateExpr, arrayValue, arrayType, resolvedArgs, false, false);
  9526. }
  9527. //TODO: Assert 'length' var is at slot 1
  9528. mModule->PopulateType(arrayType->mBaseType, BfPopulateType_DataAndMethods);
  9529. mModule->mBfIRBuilder->PopulateType(arrayType);
  9530. auto arrayBits = mModule->mBfIRBuilder->CreateBitCast(arrayValue.mValue, mModule->mBfIRBuilder->MapTypeInstPtr(arrayType->mBaseType));
  9531. int arrayLengthBitCount = arrayType->GetLengthBitCount();
  9532. if (arrayLengthBitCount == 0)
  9533. {
  9534. mModule->Fail("INTERNAL ERROR: Unable to find array 'length' field", objCreateExpr);
  9535. return;
  9536. }
  9537. auto addr = mModule->mBfIRBuilder->CreateInBoundsGEP(arrayBits, 0, 1/*, "length"*/);
  9538. if (arrayLengthBitCount == 64)
  9539. mModule->mBfIRBuilder->CreateAlignedStore(arraySize, addr, 8);
  9540. else
  9541. {
  9542. auto arraySize32 = mModule->mBfIRBuilder->CreateNumericCast(arraySize, true, BfTypeCode_Int32);
  9543. mModule->mBfIRBuilder->CreateAlignedStore(arraySize32, addr, 4);
  9544. }
  9545. for (int lowerDim = 1; lowerDim < (int)dimLengthVals.size(); lowerDim++)
  9546. {
  9547. addr = mModule->mBfIRBuilder->CreateInBoundsGEP(arrayValue.mValue, 0, lowerDim/*, "dimLength"*/); // mDimLengthX
  9548. auto lowerDimVal = mModule->mBfIRBuilder->CreateNumericCast(dimLengthVals[lowerDim], true, (arrayLengthBitCount == 64) ? BfTypeCode_Int64 : BfTypeCode_Int32);
  9549. mModule->mBfIRBuilder->CreateStore(lowerDimVal, addr);
  9550. }
  9551. if (resultType->IsValuelessType())
  9552. addr = mModule->mBfIRBuilder->GetFakeVal();
  9553. else
  9554. addr = mModule->mBfIRBuilder->CreateInBoundsGEP(arrayValue.mValue, 0, (int)dimLengthVals.size()/*, "elem"*/); // mFirstElement
  9555. _HandleInitExprs(addr, 0, objCreateExpr->mArguments);
  9556. mResult = arrayValue;
  9557. return;
  9558. }
  9559. else
  9560. {
  9561. if ((!resolvedTypeRef->IsObjectOrInterface()) && (!resolvedTypeRef->IsGenericParam()))
  9562. {
  9563. resultType = mModule->CreatePointerType(resolvedTypeRef);
  9564. }
  9565. }
  9566. if ((isStackAlloc) && (mModule->mCurMethodState == NULL))
  9567. {
  9568. mModule->Fail("Cannot use 'stack' here", objCreateExpr->mNewNode);
  9569. isStackAlloc = false;
  9570. isScopeAlloc = false;
  9571. }
  9572. bool isGenericParam = unresolvedTypeRef->IsGenericParam();
  9573. if (resolvedTypeRef->IsGenericParam())
  9574. {
  9575. auto genericConstraint = mModule->GetGenericParamInstance((BfGenericParamType*)resolvedTypeRef);
  9576. if (genericConstraint->mTypeConstraint == NULL)
  9577. {
  9578. if ((genericConstraint->mGenericParamFlags & (BfGenericParamFlag_New | BfGenericParamFlag_Struct)) == 0)
  9579. {
  9580. mModule->Fail(StrFormat("Must add 'where %s : new' constraint to generic parameter to instantiate type", genericConstraint->GetGenericParamDef()->mName.c_str()), objCreateExpr->mTypeRef);
  9581. }
  9582. if (objCreateExpr->mArguments.size() != 0)
  9583. {
  9584. mModule->Fail(StrFormat("Only default parameterless constructors can be called on generic argument '%s'", genericConstraint->GetGenericParamDef()->mName.c_str()), objCreateExpr->mTypeRef);
  9585. }
  9586. }
  9587. resultType = resolvedTypeRef;
  9588. bool isValueType = ((genericConstraint->mGenericParamFlags & BfGenericParamFlag_Struct) != 0);
  9589. if (genericConstraint->mTypeConstraint != NULL)
  9590. isValueType = genericConstraint->mTypeConstraint->IsValueType();
  9591. if (isValueType)
  9592. resultType = mModule->CreatePointerType(resultType);
  9593. mResult.mType = resultType;
  9594. if (typeInstance == NULL)
  9595. {
  9596. mResult = mModule->GetDefaultTypedValue(resultType);
  9597. return;
  9598. }
  9599. }
  9600. else if (resolvedTypeRef->IsSizedArray())
  9601. {
  9602. // Handle the case of "int[3]* val = new .(1, 2, 3)"
  9603. if (auto dotTypeRef = BfNodeDynCastExact<BfDotTypeReference>(objCreateExpr->mTypeRef))
  9604. {
  9605. BfIRValue allocValue;
  9606. if (isAppendAlloc)
  9607. allocValue = mModule->AppendAllocFromType(resolvedTypeRef, BfIRValue(), 0, BfIRValue(), 0, false, false);
  9608. else
  9609. allocValue = mModule->AllocFromType(resolvedTypeRef, allocTarget, BfIRValue(), BfIRValue(), 0, BfAllocFlags_None);
  9610. auto result = BfTypedValue(allocValue, resolvedTypeRef, BfTypedValueKind_Addr);
  9611. InitializedSizedArray((BfSizedArrayType*)resolvedTypeRef, objCreateExpr->mOpenToken, objCreateExpr->mArguments, objCreateExpr->mCommas, objCreateExpr->mCloseToken, &result);
  9612. // Turn from an addr of a sized array to pointer of sized array
  9613. mResult = BfTypedValue(mResult.mValue, resultType);
  9614. return;
  9615. }
  9616. }
  9617. SetAndRestoreValue<bool> prevNoBind(mNoBind, mNoBind || isGenericParam);
  9618. if ((typeInstance != NULL) && (typeInstance->mTypeDef->mIsAbstract))
  9619. {
  9620. mModule->Fail("Cannot create an instance of an abstract class", objCreateExpr->mTypeRef);
  9621. return;
  9622. }
  9623. BfFunctionBindResult bindResult;
  9624. bindResult.mSkipThis = true;
  9625. bindResult.mWantsArgs = true;
  9626. SetAndRestoreValue<BfFunctionBindResult*> prevBindResult(mFunctionBindResult, &bindResult);
  9627. BfIRValue appendSizeValue;
  9628. //BfTypedValue emtpyThis(BfIRValue(), resolvedTypeRef, resolvedTypeRef->IsStruct());
  9629. BfTypedValue emtpyThis(mModule->mBfIRBuilder->GetFakeVal(), resolvedTypeRef, resolvedTypeRef->IsStruct());
  9630. BfResolvedArgs argValues(objCreateExpr->mOpenToken, &objCreateExpr->mArguments, &objCreateExpr->mCommas, objCreateExpr->mCloseToken);
  9631. ResolveArgValues(argValues, BfResolveArgFlag_DeferParamEval); ////
  9632. /*SetAndRestoreValue<BfAttributeState*> prevAttributeState(mModule->mAttributeState, mPrefixedAttributeState);
  9633. if (mPrefixedAttributeState != NULL)
  9634. mPrefixedAttributeState->mUsed = true;*/
  9635. if (typeInstance == NULL)
  9636. {
  9637. // No CTOR needed
  9638. if (objCreateExpr->mArguments.size() != 0)
  9639. {
  9640. mModule->Fail(StrFormat("Only default parameterless constructors can be called on primitive type '%s'", mModule->TypeToString(resolvedTypeRef).c_str()), objCreateExpr->mTypeRef);
  9641. }
  9642. }
  9643. else if ((autoComplete != NULL) && (objCreateExpr->mOpenToken != NULL))
  9644. {
  9645. auto wasCapturingMethodInfo = autoComplete->mIsCapturingMethodMatchInfo;
  9646. autoComplete->CheckInvocation(objCreateExpr, objCreateExpr->mOpenToken, objCreateExpr->mCloseToken, objCreateExpr->mCommas);
  9647. MatchConstructor(objCreateExpr->mTypeRef, objCreateExpr, emtpyThis, typeInstance, argValues, false, true);
  9648. if ((wasCapturingMethodInfo) && (!autoComplete->mIsCapturingMethodMatchInfo))
  9649. {
  9650. autoComplete->mIsCapturingMethodMatchInfo = true;
  9651. BF_ASSERT(autoComplete->mMethodMatchInfo != NULL);
  9652. }
  9653. else
  9654. autoComplete->mIsCapturingMethodMatchInfo = false;
  9655. }
  9656. else
  9657. {
  9658. MatchConstructor(objCreateExpr->mTypeRef, objCreateExpr, emtpyThis, typeInstance, argValues, false, true);
  9659. }
  9660. mModule->ValidateAllocation(typeInstance, objCreateExpr->mTypeRef);
  9661. //prevAttributeState.Restore();
  9662. prevBindResult.Restore();
  9663. /*if ((typeInstance != NULL) && (bindResult.mMethodInstance == NULL))
  9664. {
  9665. mModule->AssertErrorState();
  9666. return;
  9667. }*/
  9668. int allocAlign = resolvedTypeRef->mAlign;
  9669. if (typeInstance != NULL)
  9670. allocAlign = typeInstance->mInstAlign;
  9671. int appendAllocAlign = 0;
  9672. if ((bindResult.mMethodInstance != NULL) && (bindResult.mMethodInstance->mMethodDef->mHasAppend))
  9673. {
  9674. if (!bindResult.mFunc)
  9675. {
  9676. BF_ASSERT((!mModule->HasCompiledOutput()) || (mModule->mBfIRBuilder->mIgnoreWrites));
  9677. appendSizeValue = mModule->GetConstValue(0);
  9678. }
  9679. else
  9680. {
  9681. auto calcAppendMethodModule = mModule->GetMethodInstanceAtIdx(bindResult.mMethodInstance->GetOwner(), bindResult.mMethodInstance->mMethodDef->mIdx + 1, BF_METHODNAME_CALCAPPEND);
  9682. SizedArray<BfIRValue, 2> irArgs;
  9683. if (bindResult.mIRArgs.size() > 1)
  9684. irArgs.Insert(0, &bindResult.mIRArgs[1], bindResult.mIRArgs.size() - 1);
  9685. BfTypedValue appendSizeTypedValue = mModule->TryConstCalcAppend(calcAppendMethodModule.mMethodInstance, irArgs);
  9686. if (!appendSizeTypedValue)
  9687. {
  9688. BF_ASSERT(calcAppendMethodModule.mFunc);
  9689. appendSizeTypedValue = CreateCall(calcAppendMethodModule.mMethodInstance, calcAppendMethodModule.mFunc, false, irArgs);
  9690. BF_ASSERT(appendSizeTypedValue.mType == mModule->GetPrimitiveType(BfTypeCode_IntPtr));
  9691. }
  9692. appendSizeValue = appendSizeTypedValue.mValue;
  9693. allocAlign = BF_MAX(allocAlign, calcAppendMethodModule.mMethodInstance->mAppendAllocAlign);
  9694. appendAllocAlign = calcAppendMethodModule.mMethodInstance->mAppendAllocAlign;
  9695. }
  9696. if (appendAllocAlign != 0)
  9697. {
  9698. int endingAlign = typeInstance->GetEndingInstanceAlignment();
  9699. if (endingAlign % appendAllocAlign != 0)
  9700. {
  9701. int extraSize = appendAllocAlign - (endingAlign % appendAllocAlign);
  9702. appendSizeValue = mModule->mBfIRBuilder->CreateAdd(appendSizeValue, mModule->GetConstValue(extraSize));
  9703. }
  9704. }
  9705. }
  9706. // WTF? I'm not even sure this is correct - add more tests
  9707. appendAllocAlign = BF_MAX(appendAllocAlign, allocAlign);
  9708. BfIRValue allocValue;
  9709. if (isAppendAlloc)
  9710. allocValue = mModule->AppendAllocFromType(resolvedTypeRef, appendSizeValue, appendAllocAlign);
  9711. else
  9712. {
  9713. allocValue = mModule->AllocFromType(resolvedTypeRef, allocTarget, appendSizeValue, BfIRValue(), 0, BfAllocFlags_None, allocAlign);
  9714. }
  9715. mResult = BfTypedValue(allocValue, resultType);
  9716. if (isScopeAlloc)
  9717. {
  9718. // This allows readonly (ie: 'let') local usage to not require an access check. No matter what scope the alloc is tied to, the
  9719. // lifetime of the local variable will be no longer than that of the allocated value
  9720. mModule->SkipObjectAccessCheck(mResult);
  9721. }
  9722. /*if (typeInstance != NULL)
  9723. {
  9724. mModule->InitTypeInst(mResult, scopeData, true);
  9725. }
  9726. if (isStackAlloc)
  9727. {
  9728. mModule->AddStackAlloc(mResult, objCreateExpr, scopeData);
  9729. }*/
  9730. if (mResult)
  9731. {
  9732. if (bindResult.mMethodInstance == NULL)
  9733. {
  9734. // Why did we have this? It was already zeroed right?
  9735. // Zero
  9736. //mModule->mBfIRBuilder->CreateMemSet(mResult.mValue, mModule->GetConstValue8(0), mModule->GetConstValue(resolvedTypeRef->mSize), resolvedTypeRef->mAlign);
  9737. }
  9738. else if (bindResult.mFunc)
  9739. {
  9740. if (typeInstance->IsObject())
  9741. {
  9742. bool wantsCtorClear = true;
  9743. if (mModule->mCompiler->mOptions.mEnableRealtimeLeakCheck)
  9744. {
  9745. // Dbg_ObjectAlloc clears internally so we don't need to call CtorClear for those
  9746. if ((!isStackAlloc) && (!allocTarget.mCustomAllocator) && (allocTarget.mScopedInvocationTarget == NULL))
  9747. wantsCtorClear = false;
  9748. }
  9749. if (wantsCtorClear)
  9750. {
  9751. auto ctorClear = mModule->GetMethodByName(typeInstance, "__BfCtorClear");
  9752. if (!ctorClear)
  9753. {
  9754. mModule->AssertErrorState();
  9755. }
  9756. else
  9757. {
  9758. SizedArray<BfIRValue, 1> irArgs;
  9759. irArgs.push_back(mResult.mValue);
  9760. CreateCall(ctorClear.mMethodInstance, ctorClear.mFunc, false, irArgs);
  9761. }
  9762. }
  9763. if ((isStackAlloc) && (mModule->mCompiler->mOptions.mEnableRealtimeLeakCheck))
  9764. {
  9765. BfMethodInstance* markMethod = mModule->GetRawMethodByName(mModule->mContext->mBfObjectType, "GCMarkMembers");
  9766. BF_ASSERT(markMethod != NULL);
  9767. if (markMethod != NULL)
  9768. {
  9769. auto& vtableEntry = typeInstance->mVirtualMethodTable[markMethod->mVirtualTableIdx];
  9770. if (vtableEntry.mImplementingMethod.mTypeInstance != mModule->mContext->mBfObjectType)
  9771. {
  9772. auto impMethodInstance = (BfMethodInstance*)vtableEntry.mImplementingMethod;
  9773. bool needsCall = false;
  9774. if (impMethodInstance != NULL)
  9775. {
  9776. needsCall = impMethodInstance->mMethodDef->mBody != NULL;
  9777. }
  9778. else
  9779. {
  9780. needsCall = true;
  9781. BF_ASSERT(vtableEntry.mImplementingMethod.mKind == BfMethodRefKind_AmbiguousRef);
  9782. }
  9783. if (needsCall)
  9784. {
  9785. SizedArray<BfIRValue, 1> irArgs;
  9786. irArgs.push_back(mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->MapType(mModule->mContext->mBfObjectType)));
  9787. auto gcType = mModule->ResolveTypeDef(mModule->mCompiler->mGCTypeDef);
  9788. BF_ASSERT(gcType != NULL);
  9789. if (gcType != NULL)
  9790. {
  9791. auto addStackObjMethod = mModule->GetMethodByName(gcType->ToTypeInstance(), "AddStackMarkableObject", 1);
  9792. BF_ASSERT(addStackObjMethod);
  9793. if (addStackObjMethod)
  9794. {
  9795. mModule->mBfIRBuilder->CreateCall(addStackObjMethod.mFunc, irArgs);
  9796. }
  9797. auto removeStackObjMethod = mModule->GetMethodByName(gcType->ToTypeInstance(), "RemoveStackMarkableObject", 1);
  9798. BF_ASSERT(removeStackObjMethod);
  9799. if (removeStackObjMethod)
  9800. {
  9801. mModule->AddDeferredCall(removeStackObjMethod, irArgs, allocTarget.mScopeData, objCreateExpr);
  9802. }
  9803. }
  9804. }
  9805. }
  9806. }
  9807. }
  9808. }
  9809. if ((bindResult.mMethodInstance->mMethodDef->mHasAppend) && (mResult.mType->IsObject()))
  9810. {
  9811. BF_ASSERT(bindResult.mIRArgs[0].IsFake());
  9812. auto typeInst = mResult.mType->ToTypeInstance();
  9813. auto intPtrType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  9814. auto thisVal = mResult;
  9815. BfIRValue intPtrVal = mModule->CreateAlloca(intPtrType);
  9816. auto intPtrThisVal = mModule->mBfIRBuilder->CreatePtrToInt(thisVal.mValue, (intPtrType->mSize == 4) ? BfTypeCode_Int32 : BfTypeCode_Int64);
  9817. auto curValPtr = mModule->mBfIRBuilder->CreateAdd(intPtrThisVal, mModule->GetConstValue(typeInst->mInstSize, intPtrType));
  9818. mModule->mBfIRBuilder->CreateStore(curValPtr, intPtrVal);
  9819. bindResult.mIRArgs[0] = intPtrVal;
  9820. }
  9821. if (!typeInstance->IsValuelessType())
  9822. bindResult.mIRArgs.Insert(0, mResult.mValue);
  9823. CreateCall(bindResult.mMethodInstance, bindResult.mFunc, false, bindResult.mIRArgs);
  9824. }
  9825. }
  9826. // if ((mResult) && (!isArrayAlloc) && (objCreateExpr->mCollectionInitializer != NULL))
  9827. // {
  9828. // for (BfExpression* initExpr : objCreateExpr->mCollectionInitializer->mValues)
  9829. // {
  9830. // SizedArray<ASTREF(BfExpression*), 1> exprs;
  9831. //
  9832. // if (auto groupExpr = BfNodeDynCast<BfCollectionInitializerExpression>(initExpr))
  9833. // {
  9834. // for (BfExpression* argExpr : groupExpr->mValues)
  9835. // exprs.push_back(argExpr);
  9836. // }
  9837. // else
  9838. // {
  9839. // exprs.push_back(initExpr);
  9840. // }
  9841. //
  9842. // BfExprEvaluator exprEvaluator(mModule);
  9843. // SizedArray<BfExpression*, 8> copiedArgs;
  9844. // for (BfExpression* arg : exprs)
  9845. // copiedArgs.push_back(arg);
  9846. // BfResolvedArgs argValues(copiedArgs);
  9847. // exprEvaluator.ResolveArgValues(argValues);
  9848. // exprEvaluator.MatchMethod(initExpr, NULL, mResult, false, false, "Add", argValues, NULL);
  9849. // }
  9850. // }
  9851. }
  9852. void BfExprEvaluator::Visit(BfBoxExpression* boxExpr)
  9853. {
  9854. /*if ((boxExpr->mAllocNode == NULL) || (boxExpr->mExpression == NULL))
  9855. {
  9856. mModule->AssertErrorState();
  9857. return;
  9858. }*/
  9859. BfTokenNode* newToken = NULL;
  9860. BfAllocTarget allocTarget = ResolveAllocTarget(boxExpr->mAllocNode, newToken);
  9861. if ((boxExpr->mAllocNode != NULL) && (boxExpr->mAllocNode->mToken == BfToken_Scope))
  9862. {
  9863. if ((mBfEvalExprFlags & BfEvalExprFlags_FieldInitializer) != 0)
  9864. {
  9865. mModule->Warn(0, "This allocation will only be in scope during the constructor. Consider using a longer-term allocation such as 'new'", boxExpr->mAllocNode);
  9866. }
  9867. }
  9868. if (boxExpr->mExpression == NULL)
  9869. {
  9870. mModule->AssertErrorState();
  9871. return;
  9872. }
  9873. auto exprValue = mModule->CreateValueFromExpression(boxExpr->mExpression);
  9874. if (exprValue)
  9875. {
  9876. if (exprValue.mType->IsGenericParam())
  9877. {
  9878. BF_ASSERT(mModule->mCurMethodInstance->mIsUnspecialized);
  9879. auto genericParamTarget = (BfGenericParamType*)exprValue.mType;
  9880. auto genericParamInstance = mModule->GetGenericParamInstance(genericParamTarget);
  9881. bool isBoxable = false;
  9882. if (genericParamInstance->mGenericParamFlags & (BfGenericParamFlag_Struct | BfGenericParamFlag_StructPtr))
  9883. isBoxable = true;
  9884. if ((genericParamInstance->mTypeConstraint != NULL) && (exprValue.mType->IsValueTypeOrValueTypePtr()))
  9885. isBoxable = true;
  9886. if (isBoxable)
  9887. {
  9888. mResult = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  9889. return;
  9890. }
  9891. }
  9892. if (!exprValue.mType->IsValueTypeOrValueTypePtr())
  9893. {
  9894. 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);
  9895. return;
  9896. }
  9897. //BfType* boxedType = mModule->CreateBoxedType(exprValue.mType);
  9898. //auto scopeData = mModule->FindScope(boxExpr->mAllocNode);
  9899. mResult = mModule->BoxValue(boxExpr->mExpression, exprValue, mModule->mContext->mBfObjectType, allocTarget);
  9900. if (!mResult)
  9901. {
  9902. mModule->Fail(StrFormat("Type '%s' is not boxable", mModule->TypeToString(exprValue.mType).c_str()), boxExpr->mExpression);
  9903. return;
  9904. }
  9905. }
  9906. }
  9907. BfAllocTarget BfExprEvaluator::ResolveAllocTarget(BfAstNode* allocNode, BfTokenNode*& newToken)
  9908. {
  9909. auto autoComplete = GetAutoComplete();
  9910. BfAllocTarget allocTarget;
  9911. allocTarget.mRefNode = allocNode;
  9912. newToken = BfNodeDynCast<BfTokenNode>(allocNode);
  9913. if (newToken == NULL)
  9914. {
  9915. if (auto scopeNode = BfNodeDynCast<BfScopeNode>(allocNode))
  9916. {
  9917. newToken = scopeNode->mScopeToken;
  9918. allocTarget.mScopeData = mModule->FindScope(scopeNode->mTargetNode, true);
  9919. if (autoComplete != NULL)
  9920. {
  9921. auto targetIdentifier = BfNodeDynCast<BfIdentifierNode>(scopeNode->mTargetNode);
  9922. if ((scopeNode->mTargetNode == NULL) || (targetIdentifier != NULL))
  9923. autoComplete->CheckLabel(targetIdentifier, scopeNode->mColonToken);
  9924. }
  9925. }
  9926. if (auto newNode = BfNodeDynCast<BfNewNode>(allocNode))
  9927. {
  9928. newToken = newNode->mNewToken;
  9929. if (auto allocExpr = BfNodeDynCast<BfExpression>(newNode->mAllocNode))
  9930. {
  9931. allocTarget.mCustomAllocator = mModule->CreateValueFromExpression(allocExpr);
  9932. allocTarget.mRefNode = allocExpr;
  9933. }
  9934. else if (auto scopedInvocationTarget = BfNodeDynCast<BfScopedInvocationTarget>(newNode->mAllocNode))
  9935. {
  9936. allocTarget.mScopedInvocationTarget = scopedInvocationTarget;
  9937. }
  9938. }
  9939. }
  9940. else if (newToken->GetToken() == BfToken_Scope)
  9941. {
  9942. if (mModule->mCurMethodState != NULL)
  9943. allocTarget.mScopeData = mModule->mCurMethodState->mCurScope->GetTargetable();
  9944. }
  9945. else if (newToken->GetToken() == BfToken_Stack)
  9946. {
  9947. if (mModule->mCurMethodState != NULL)
  9948. allocTarget.mScopeData = &mModule->mCurMethodState->mHeadScope;
  9949. }
  9950. return allocTarget;
  9951. }
  9952. BfTypedValue BfExprEvaluator::MakeCallableTarget(BfAstNode* targetSrc, BfTypedValue target)
  9953. {
  9954. if (((target.mType->IsRef()) || (target.mType->IsPointer())) &&
  9955. (target.mType->GetUnderlyingType()->IsStruct()))
  9956. {
  9957. auto pointerType = (BfPointerType*) target.mType;
  9958. target = mModule->LoadValue(target);
  9959. target.mType = pointerType->mElementType;
  9960. target.mKind = BfTypedValueKind_Addr;
  9961. }
  9962. if ((target.mType->IsStruct()) && (!target.IsAddr()))
  9963. {
  9964. target = mModule->MakeAddressable(target);
  9965. }
  9966. if (target.mType->IsVar())
  9967. {
  9968. target.mType = mModule->mContext->mBfObjectType;
  9969. return target;
  9970. }
  9971. if (target.mType->IsWrappableType())
  9972. {
  9973. auto primStructType = mModule->GetWrappedStructType(target.mType);
  9974. if (primStructType != NULL)
  9975. {
  9976. mModule->PopulateType(primStructType);
  9977. target.mType = primStructType;
  9978. if ((primStructType->IsSplattable()) && (!primStructType->IsTypedPrimitive()))
  9979. {
  9980. if (target.IsAddr())
  9981. {
  9982. auto ptrType = mModule->CreatePointerType(primStructType);
  9983. target = BfTypedValue(mModule->mBfIRBuilder->CreateBitCast(target.mValue, mModule->mBfIRBuilder->MapType(ptrType)), primStructType, true);
  9984. }
  9985. else
  9986. target.mKind = BfTypedValueKind_SplatHead;
  9987. }
  9988. }
  9989. return target;
  9990. }
  9991. if (target.mType->IsGenericParam())
  9992. {
  9993. target.mType = mModule->mContext->mBfObjectType;
  9994. return target;
  9995. }
  9996. if ((!target.mType->IsTypeInstance()) && (!target.mType->IsConcreteInterfaceType()))
  9997. {
  9998. mModule->Fail(StrFormat("Invalid target type: '%s'", mModule->TypeToString(target.mType).c_str()), targetSrc);
  9999. return BfTypedValue();
  10000. }
  10001. return target;
  10002. }
  10003. int BfExprEvaluator::GetMixinVariable()
  10004. {
  10005. auto curMethodState = mModule->mCurMethodState;
  10006. for (int localIdx = (int)curMethodState->mLocals.size() - 1; localIdx >= 0; localIdx--)
  10007. {
  10008. auto varDecl = curMethodState->mLocals[localIdx];
  10009. if (varDecl->mName == "mixin")
  10010. return localIdx;
  10011. }
  10012. return -1;
  10013. }
  10014. BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc, BfTypeInstance* curTypeInst, BfMethodDef* methodDef, BfMethodMatcher& methodMatcher)
  10015. {
  10016. bool failed = false;
  10017. auto resolvedCurTypeInst = curTypeInst;//mModule->ResolveGenericType(curTypeInst)->ToTypeInstance();
  10018. bool hasDifferentResolvedTypes = resolvedCurTypeInst != curTypeInst;
  10019. BfTypeVector resolvedGenericArguments;
  10020. auto rootMethodState = mModule->mCurMethodState->GetRootMethodState();
  10021. int localInferrableGenericArgCount = -1;
  10022. if ((methodMatcher.mBestMethodGenericArguments.size() == 0) && (!methodMatcher.mExplicitMethodGenericArguments.IsEmpty()))
  10023. {
  10024. int uniqueGenericStartIdx = mModule->GetLocalInferrableGenericArgCount(methodDef);
  10025. int64 genericArgCountDiff = (int)methodMatcher.mExplicitMethodGenericArguments.size() + uniqueGenericStartIdx - (int)methodDef->mGenericParams.size();
  10026. BfInvocationExpression* invocationExpr = NULL;
  10027. if (mModule->mParentNodeEntry != NULL)
  10028. {
  10029. invocationExpr = BfNodeDynCast<BfInvocationExpression>(mModule->mParentNodeEntry->mNode);
  10030. }
  10031. if (genericArgCountDiff > 0)
  10032. {
  10033. BfAstNode* errorNode = targetSrc;
  10034. if ((invocationExpr != NULL) && (invocationExpr->mGenericArgs != NULL))
  10035. {
  10036. errorNode = invocationExpr->mGenericArgs->mGenericArgs[(int)methodDef->mGenericParams.size()];
  10037. if (errorNode == NULL)
  10038. errorNode = invocationExpr->mGenericArgs->mCommas[(int)methodDef->mGenericParams.size() - 1];
  10039. }
  10040. mModule->Fail(StrFormat("Too many generic arguments, expected %d fewer", genericArgCountDiff), errorNode);
  10041. }
  10042. else if (genericArgCountDiff < 0)
  10043. {
  10044. BfAstNode* errorNode = targetSrc;
  10045. if ((invocationExpr != NULL) && (invocationExpr->mGenericArgs != NULL) && (invocationExpr->mGenericArgs->mCloseChevron != NULL))
  10046. errorNode = invocationExpr->mGenericArgs->mCloseChevron;
  10047. mModule->Fail(StrFormat("Too few generic arguments, expected %d more", -genericArgCountDiff), errorNode);
  10048. }
  10049. methodMatcher.mBestMethodGenericArguments.resize(methodDef->mGenericParams.size());
  10050. for (int i = 0; i < std::min(methodDef->mGenericParams.size() - uniqueGenericStartIdx, methodMatcher.mExplicitMethodGenericArguments.size()); i++)
  10051. {
  10052. methodMatcher.mBestMethodGenericArguments[i + uniqueGenericStartIdx] = methodMatcher.mExplicitMethodGenericArguments[i];
  10053. }
  10054. }
  10055. BfMethodInstance* unspecializedMethod = NULL;
  10056. for (int checkGenericIdx = 0; checkGenericIdx < (int)methodMatcher.mBestMethodGenericArguments.size(); checkGenericIdx++)
  10057. {
  10058. BfMethodInstance* outerMethodInstance = NULL;
  10059. auto& genericArg = methodMatcher.mBestMethodGenericArguments[checkGenericIdx];
  10060. if (genericArg == NULL)
  10061. {
  10062. if ((methodDef->mIsLocalMethod) && (checkGenericIdx < mModule->mCurMethodInstance->GetNumGenericArguments()))
  10063. {
  10064. // If the root method is generic and we need that param then use that...
  10065. auto rootMethodInstance = rootMethodState->mMethodInstance;
  10066. if (checkGenericIdx < rootMethodInstance->mMethodInfoEx->mMethodGenericArguments.size())
  10067. {
  10068. genericArg = rootMethodInstance->mMethodInfoEx->mMethodGenericArguments[checkGenericIdx];
  10069. }
  10070. else
  10071. {
  10072. if (localInferrableGenericArgCount == -1)
  10073. localInferrableGenericArgCount = mModule->GetLocalInferrableGenericArgCount(methodDef);
  10074. // Otherwise we can only infer generics at the level that the called method was contained
  10075. if (checkGenericIdx < localInferrableGenericArgCount)
  10076. genericArg = mModule->mCurMethodInstance->mMethodInfoEx->mMethodGenericArguments[checkGenericIdx];
  10077. }
  10078. }
  10079. }
  10080. if (genericArg == NULL)
  10081. {
  10082. if (unspecializedMethod == NULL)
  10083. unspecializedMethod = mModule->GetRawMethodInstance(curTypeInst, methodDef);
  10084. auto genericParam = unspecializedMethod->mMethodInfoEx->mGenericParams[checkGenericIdx];
  10085. if ((genericParam->mTypeConstraint != NULL) && (genericParam->mTypeConstraint->IsDelegate()))
  10086. {
  10087. // The only other option was to bind to a MethodRef
  10088. genericArg = genericParam->mTypeConstraint;
  10089. }
  10090. else
  10091. {
  10092. if (((genericParam->mGenericParamFlags & BfGenericParamFlag_Const) != 0) && (genericParam->mTypeConstraint != NULL))
  10093. {
  10094. for (int paramIdx = 0; paramIdx < (int)unspecializedMethod->mDefaultValues.size(); paramIdx++)
  10095. {
  10096. auto defaultVal = unspecializedMethod->mDefaultValues[paramIdx];
  10097. if (!defaultVal)
  10098. continue;
  10099. auto& param = unspecializedMethod->mParams[paramIdx];
  10100. if (param.mResolvedType->IsGenericParam())
  10101. {
  10102. auto genericParamType = (BfGenericParamType*)param.mResolvedType;
  10103. if ((genericParamType->mGenericParamKind == BfGenericParamKind_Method) && (genericParamType->mGenericParamIdx == checkGenericIdx))
  10104. {
  10105. BfTypedValue constExprVal;
  10106. constExprVal.mType = genericParam->mTypeConstraint;
  10107. auto constant = curTypeInst->mConstHolder->GetConstant(defaultVal);
  10108. constExprVal.mValue = mModule->ConstantToCurrent(constant, curTypeInst->mConstHolder, genericParam->mTypeConstraint);
  10109. genericArg = mModule->CreateConstExprValueType(constExprVal);
  10110. }
  10111. }
  10112. }
  10113. }
  10114. if (genericArg == NULL)
  10115. {
  10116. failed = true;
  10117. mModule->Fail(StrFormat("Unable to determine generic argument '%s'", methodDef->mGenericParams[checkGenericIdx]->mName.c_str()).c_str(), targetSrc);
  10118. if ((genericParam->mTypeConstraint != NULL) && (!genericParam->mTypeConstraint->IsUnspecializedType()))
  10119. genericArg = genericParam->mTypeConstraint;
  10120. else
  10121. genericArg = mModule->mContext->mBfObjectType;
  10122. }
  10123. }
  10124. resolvedGenericArguments.push_back(genericArg);
  10125. }
  10126. else
  10127. {
  10128. if (genericArg->IsIntUnknown())
  10129. genericArg = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  10130. auto resolvedGenericArg = genericArg;//mModule->ResolveGenericType(genericArg);
  10131. if (resolvedGenericArg != genericArg)
  10132. hasDifferentResolvedTypes = true;
  10133. resolvedGenericArguments.push_back(resolvedGenericArg);
  10134. }
  10135. }
  10136. BfTypeInstance* foreignType = NULL;
  10137. BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None;
  10138. if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) && (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mInlineAttributeTypeDef)))
  10139. {
  10140. flags = (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_ForceInline);
  10141. }
  10142. if ((!mModule->mCurTypeInstance->IsInterface()) && (methodDef->mBody != NULL))
  10143. {
  10144. if ((methodMatcher.mBypassVirtual) && (methodMatcher.mBestMethodTypeInstance->IsInterface()))
  10145. {
  10146. // This is an explicit 'base' call to a default interface method. We pull the methodDef into our own concrete type.
  10147. foreignType = curTypeInst;
  10148. curTypeInst = mModule->mCurTypeInstance;
  10149. flags = (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_ForeignMethodDef);
  10150. }
  10151. else if ((methodDef->mIsStatic) && (curTypeInst->IsInterface()))
  10152. {
  10153. if (mModule->TypeIsSubTypeOf(mModule->mCurTypeInstance, curTypeInst))
  10154. {
  10155. // This is an explicit call to a default static interface method. We pull the methodDef into our own concrete type.
  10156. foreignType = curTypeInst;
  10157. curTypeInst = mModule->mCurTypeInstance;
  10158. flags = (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_ForeignMethodDef);
  10159. }
  10160. }
  10161. }
  10162. BfModuleMethodInstance methodInstance;
  10163. if (methodMatcher.mBestMethodInstance)
  10164. {
  10165. methodInstance = methodMatcher.mBestMethodInstance;
  10166. }
  10167. else
  10168. {
  10169. methodInstance = mModule->GetMethodInstance(resolvedCurTypeInst, methodDef, resolvedGenericArguments, flags, foreignType);
  10170. }
  10171. if (mModule->mCompiler->IsSkippingExtraResolveChecks())
  10172. {
  10173. //BF_ASSERT(methodInstance.mFunc == NULL);
  10174. }
  10175. if (methodInstance.mMethodInstance == NULL)
  10176. return NULL;
  10177. if (methodDef->IsEmptyPartial())
  10178. return methodInstance;
  10179. for (int checkGenericIdx = 0; checkGenericIdx < (int)methodMatcher.mBestMethodGenericArguments.size(); checkGenericIdx++)
  10180. {
  10181. auto& genericParams = methodInstance.mMethodInstance->mMethodInfoEx->mGenericParams;
  10182. auto genericArg = methodMatcher.mBestMethodGenericArguments[checkGenericIdx];
  10183. if (genericArg->IsVar())
  10184. continue;
  10185. if (genericArg->IsPrimitiveType())
  10186. {
  10187. auto primType = (BfPrimitiveType*)genericArg;
  10188. genericArg = mModule->GetPrimitiveStructType(primType->mTypeDef->mTypeCode);
  10189. }
  10190. BfAstNode* paramSrc;
  10191. if (methodMatcher.mBestMethodGenericArgumentSrcs.size() == 0)
  10192. {
  10193. paramSrc = targetSrc;
  10194. }
  10195. else
  10196. paramSrc = methodMatcher.mArguments[methodMatcher.mBestMethodGenericArgumentSrcs[checkGenericIdx]].mExpression;
  10197. BfError* error = NULL;
  10198. if ((!failed) && (!mModule->CheckGenericConstraints(BfGenericParamSource(methodInstance.mMethodInstance), genericArg, paramSrc, genericParams[checkGenericIdx], &methodMatcher.mBestMethodGenericArguments, &error)))
  10199. {
  10200. if (methodInstance.mMethodInstance->IsSpecializedGenericMethod())
  10201. {
  10202. // We mark this as failed to make sure we don't try to process a method that doesn't even follow the constraints
  10203. methodInstance.mMethodInstance->mFailedConstraints = true;
  10204. }
  10205. if (methodInstance.mMethodInstance->mMethodDef->mMethodDeclaration != NULL)
  10206. {
  10207. if (error != NULL)
  10208. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance.mMethodInstance->mMethodDef->GetRefNode());
  10209. }
  10210. return BfModuleMethodInstance();
  10211. }
  10212. }
  10213. return methodInstance;
  10214. }
  10215. void BfExprEvaluator::CheckLocalMethods(BfAstNode* targetSrc, BfTypeInstance* typeInstance, const StringImpl& methodName, BfMethodMatcher& methodMatcher, BfMethodType methodType)
  10216. {
  10217. auto _GetNodeId = [&]()
  10218. {
  10219. auto parser = targetSrc->GetSourceData()->ToParserData();
  10220. return ((int64)parser->mDataId << 32) + targetSrc->GetSrcStart();
  10221. };
  10222. BfMethodState* ctxMethodState = NULL;
  10223. BfClosureInstanceInfo* ctxClosureInstanceInfo = NULL;
  10224. if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL))
  10225. {
  10226. ctxClosureInstanceInfo = mModule->mCurMethodState->mClosureState->mClosureInstanceInfo;
  10227. ctxMethodState = mModule->mCurMethodState;
  10228. }
  10229. bool atCtxMethodState = false;
  10230. auto checkMethodState = mModule->mCurMethodState;
  10231. auto rootMethodState = checkMethodState;
  10232. while (checkMethodState != NULL)
  10233. {
  10234. rootMethodState = checkMethodState;
  10235. if (checkMethodState == ctxMethodState)
  10236. atCtxMethodState = true;
  10237. if ((ctxClosureInstanceInfo != NULL) && (!ctxMethodState->mClosureState->mCapturing))
  10238. {
  10239. BfMethodDef* localMethodDef = NULL;
  10240. if (ctxClosureInstanceInfo->mLocalMethodBindings.TryGetValue(_GetNodeId(), &localMethodDef))
  10241. {
  10242. methodMatcher.CheckMethod(mModule->mCurTypeInstance, localMethodDef, true);
  10243. BF_ASSERT(methodMatcher.mBestMethodDef != NULL);
  10244. return;
  10245. }
  10246. }
  10247. else
  10248. {
  10249. BfLocalMethod* matchedLocalMethod = NULL;
  10250. BfLocalMethod* localMethod = NULL;
  10251. if (checkMethodState->mLocalMethodMap.TryGetValue(methodName, &localMethod))
  10252. {
  10253. while (localMethod != NULL)
  10254. {
  10255. auto methodDef = mModule->GetLocalMethodDef(localMethod);
  10256. if (methodDef->mMethodType == methodType)
  10257. {
  10258. methodMatcher.CheckMethod(mModule->mCurTypeInstance, methodDef, true);
  10259. if (methodMatcher.mBestMethodDef == methodDef)
  10260. matchedLocalMethod = localMethod;
  10261. }
  10262. localMethod = localMethod->mNextWithSameName;
  10263. }
  10264. }
  10265. if (matchedLocalMethod != NULL)
  10266. {
  10267. if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mCapturing))
  10268. {
  10269. BfModuleMethodInstance moduleMethodInstance = GetSelectedMethod(targetSrc, typeInstance, matchedLocalMethod->mMethodDef, methodMatcher);
  10270. auto methodInstance = moduleMethodInstance.mMethodInstance;
  10271. if ((methodInstance->mMethodInfoEx != NULL) && (methodInstance->mMethodInfoEx->mClosureInstanceInfo->mCaptureClosureState != NULL))
  10272. {
  10273. // The called method is calling us from its mLocalMethodRefs set. Stretch our mCaptureStartAccessId back to incorporate its
  10274. // captures as well
  10275. if (methodInstance->mMethodInfoEx->mClosureInstanceInfo->mCaptureClosureState->mCaptureStartAccessId < mModule->mCurMethodState->mClosureState->mCaptureStartAccessId)
  10276. mModule->mCurMethodState->mClosureState->mCaptureStartAccessId = methodInstance->mMethodInfoEx->mClosureInstanceInfo->mCaptureClosureState->mCaptureStartAccessId;
  10277. }
  10278. else
  10279. {
  10280. if (methodInstance->mDisallowCalling) // We need to process the captures from this guy
  10281. {
  10282. if (mModule->mCurMethodState->mClosureState->mLocalMethodRefSet.Add(methodInstance))
  10283. mModule->mCurMethodState->mClosureState->mLocalMethodRefs.Add(methodInstance);
  10284. }
  10285. }
  10286. }
  10287. if (ctxClosureInstanceInfo != NULL)
  10288. {
  10289. BF_ASSERT(mModule->mCurMethodState->mClosureState->mCapturing);
  10290. ctxClosureInstanceInfo->mLocalMethodBindings[_GetNodeId()] = methodMatcher.mBestMethodDef;
  10291. }
  10292. break;
  10293. }
  10294. }
  10295. checkMethodState = checkMethodState->mPrevMethodState;
  10296. }
  10297. }
  10298. void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, bool allowImplicitThis, const StringImpl& name, const BfSizedArray<BfExpression*>& arguments, BfSizedArray<ASTREF(BfTypeReference*)>* methodGenericArgs)
  10299. {
  10300. BfAstNode* origTargetSrc = targetSrc;
  10301. BfScopedInvocationTarget* scopedInvocationTarget = NULL;
  10302. if (mModule->mParentNodeEntry != NULL)
  10303. {
  10304. if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(mModule->mParentNodeEntry->mNode))
  10305. {
  10306. scopedInvocationTarget = BfNodeDynCast<BfScopedInvocationTarget>(invocationExpr->mTarget);
  10307. }
  10308. }
  10309. auto targetNameNode = targetSrc;
  10310. if (scopedInvocationTarget != NULL)
  10311. targetNameNode = scopedInvocationTarget->mTarget;
  10312. BfTypeInstance* mixinClass = NULL;
  10313. if (target.mType != NULL)
  10314. mixinClass = target.mType->ToTypeInstance();
  10315. int inLine = mModule->mCurFilePosition.mCurLine;
  10316. SizedArray<BfResolvedArg, 4> args;
  10317. SizedArray<BfExprEvaluator*, 8> argExprEvaluators;
  10318. OnScopeExit freeMem([&]()
  10319. {
  10320. for (auto exprEvaluator : argExprEvaluators)
  10321. delete exprEvaluator;
  10322. });
  10323. auto _AddArg = [&](BfExpression* argExpr)
  10324. {
  10325. BfResolvedArg resolvedArg;
  10326. argExprEvaluators.push_back(new BfExprEvaluator(mModule));
  10327. BfExprEvaluator* exprEvaluator = argExprEvaluators.back();
  10328. exprEvaluator->mResolveGenericParam = false;
  10329. if (argExpr != NULL)
  10330. exprEvaluator->Evaluate(argExpr, false, false, true);
  10331. auto argValue = exprEvaluator->mResult;
  10332. mModule->FixIntUnknown(argValue);
  10333. if (argValue)
  10334. {
  10335. if (argValue.mType->IsRef())
  10336. {
  10337. exprEvaluator->FinishExpressionResult();
  10338. }
  10339. }
  10340. resolvedArg.mTypedValue = argValue;
  10341. resolvedArg.mExpression = argExpr;
  10342. args.push_back(resolvedArg);
  10343. };
  10344. for (BfExpression* argExpr : arguments)
  10345. {
  10346. _AddArg(argExpr);
  10347. }
  10348. auto autoComplete = GetAutoComplete();
  10349. if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo) && (autoComplete->mMethodMatchInfo->mInstanceList.size() != 0))
  10350. autoComplete->mIsCapturingMethodMatchInfo = false;
  10351. BfMethodMatcher methodMatcher(targetSrc, mModule, name, args, methodGenericArgs);
  10352. methodMatcher.mMethodType = BfMethodType_Mixin;
  10353. methodMatcher.mSkipImplicitParams = true;
  10354. auto curTypeInst = mModule->mCurTypeInstance;
  10355. if (mixinClass != NULL)
  10356. curTypeInst = mixinClass;
  10357. if (target.mType == NULL)
  10358. {
  10359. CheckLocalMethods(targetSrc, curTypeInst, name, methodMatcher, BfMethodType_Mixin);
  10360. }
  10361. if (methodMatcher.mBestMethodDef == NULL)
  10362. methodMatcher.mBestMethodDef = methodMatcher.mBackupMethodDef;
  10363. if (methodMatcher.mBestMethodDef == NULL)
  10364. {
  10365. if (mixinClass != NULL)
  10366. methodMatcher.CheckType(mixinClass, BfTypedValue(), false);
  10367. else
  10368. methodMatcher.CheckType(mModule->mCurTypeInstance, BfTypedValue(), false);
  10369. }
  10370. if ((methodMatcher.mBestMethodDef == NULL) && (mModule->mContext->mCurTypeState != NULL))
  10371. {
  10372. BF_ASSERT(mModule->mCurTypeInstance == mModule->mContext->mCurTypeState->mTypeInstance);
  10373. BfGlobalLookup globalLookup;
  10374. globalLookup.mKind = BfGlobalLookup::Kind_Method;
  10375. globalLookup.mName = name;
  10376. mModule->PopulateGlobalContainersList(globalLookup);
  10377. for (auto& globalContainer : mModule->mContext->mCurTypeState->mGlobalContainers)
  10378. {
  10379. if (globalContainer.mTypeInst == NULL)
  10380. continue;
  10381. methodMatcher.CheckType(globalContainer.mTypeInst, BfTypedValue(), false);
  10382. if (methodMatcher.mBestMethodDef != NULL)
  10383. break;
  10384. }
  10385. }
  10386. if (methodMatcher.mBestMethodDef == NULL)
  10387. {
  10388. mModule->Fail("Cannot find mixin", targetSrc);
  10389. return;
  10390. }
  10391. auto resolvePassData = mModule->mCompiler->mResolvePassData;
  10392. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(targetNameNode)) && (autoComplete->mDefType == NULL))
  10393. {
  10394. autoComplete->mInsertStartIdx = targetNameNode->GetSrcStart();
  10395. autoComplete->mInsertEndIdx = targetNameNode->GetSrcEnd();
  10396. autoComplete->mDefType = methodMatcher.mBestMethodTypeInstance->mTypeDef;
  10397. autoComplete->mDefMethod = methodMatcher.mBestMethodDef;
  10398. autoComplete->SetDefinitionLocation(methodMatcher.mBestMethodDef->GetMethodDeclaration()->mNameNode);
  10399. }
  10400. if ((mModule->mCompiler->mResolvePassData != NULL) && (mModule->mCompiler->mResolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Method))
  10401. {
  10402. targetNameNode->SetSrcEnd(targetNameNode->GetSrcEnd() - 1);
  10403. mModule->mCompiler->mResolvePassData->HandleMethodReference(targetNameNode, methodMatcher.mBestMethodTypeInstance->mTypeDef, methodMatcher.mBestMethodDef);
  10404. targetNameNode->SetSrcEnd(targetNameNode->GetSrcEnd() + 1);
  10405. }
  10406. auto curMethodState = mModule->mCurMethodState;
  10407. //
  10408. {
  10409. bool hasCircularRef = false;
  10410. auto checkMethodState = curMethodState;
  10411. while (checkMethodState != NULL)
  10412. {
  10413. auto curMixinState = checkMethodState->mMixinState;
  10414. while (curMixinState != NULL)
  10415. {
  10416. if (curMixinState->mSource == targetSrc)
  10417. hasCircularRef = true;
  10418. curMixinState = curMixinState->mPrevMixinState;
  10419. }
  10420. if ((checkMethodState->mClosureState != NULL) && (checkMethodState->mClosureState->mActiveDeferredLocalMethod != NULL))
  10421. {
  10422. for (auto& mixinRecord : checkMethodState->mClosureState->mActiveDeferredLocalMethod->mMixinStateRecords)
  10423. {
  10424. if (mixinRecord.mSource == targetSrc)
  10425. hasCircularRef = true;
  10426. }
  10427. }
  10428. checkMethodState = checkMethodState->mPrevMethodState;
  10429. }
  10430. if (hasCircularRef)
  10431. {
  10432. mModule->Fail("Circular reference detected between mixins", targetSrc);
  10433. return;
  10434. }
  10435. }
  10436. auto moduleMethodInstance = GetSelectedMethod(targetSrc, methodMatcher.mBestMethodTypeInstance, methodMatcher.mBestMethodDef, methodMatcher);
  10437. if (!moduleMethodInstance)
  10438. return;
  10439. auto methodInstance = moduleMethodInstance.mMethodInstance;
  10440. // Check circular ref based on methodInstance
  10441. {
  10442. bool hasCircularRef = false;
  10443. auto checkMethodState = curMethodState;
  10444. while (checkMethodState != NULL)
  10445. {
  10446. if (checkMethodState->mMethodInstance == methodInstance)
  10447. hasCircularRef = true;
  10448. auto curMixinState = checkMethodState->mMixinState;
  10449. while (curMixinState != NULL)
  10450. {
  10451. if (curMixinState->mMixinMethodInstance == methodInstance)
  10452. hasCircularRef = true;
  10453. curMixinState = curMixinState->mPrevMixinState;
  10454. }
  10455. checkMethodState = checkMethodState->mPrevMethodState;
  10456. }
  10457. if (hasCircularRef)
  10458. {
  10459. mModule->Fail("Circular reference detected between mixins", targetSrc);
  10460. return;
  10461. }
  10462. }
  10463. AddCallDependencies(methodInstance);
  10464. if (!methodMatcher.mBestMethodDef->mIsStatic)
  10465. {
  10466. if ((!target) && (allowImplicitThis))
  10467. target = mModule->GetThis();
  10468. if (!target)
  10469. {
  10470. mModule->Fail(StrFormat("An instance reference is required to invoke the non-static mixin '%s'",
  10471. mModule->MethodToString(methodInstance).c_str()), targetSrc);
  10472. }
  10473. }
  10474. else
  10475. {
  10476. if (target)
  10477. {
  10478. mModule->Fail(StrFormat("Mixin '%s' cannot be accessed with an instance reference; qualify it with a type name instead",
  10479. mModule->MethodToString(methodInstance).c_str()), targetSrc);
  10480. }
  10481. }
  10482. int methodParamCount = (int)methodInstance->GetParamCount();
  10483. // Implicit params are ignored for calling- they should be resolved at the injection site
  10484. int implicitParamCount = methodInstance->GetImplicitParamCount();
  10485. int explicitParamCount = methodParamCount - implicitParamCount;
  10486. while ((int)args.size() < explicitParamCount)
  10487. {
  10488. int argIdx = (int)args.size();
  10489. BfExpression* expr = methodInstance->GetParamInitializer(argIdx);
  10490. if (expr == NULL)
  10491. break;
  10492. _AddArg(expr);
  10493. }
  10494. if ((int)args.size() < explicitParamCount)
  10495. {
  10496. BfError* error = mModule->Fail(StrFormat("Not enough arguments specified, expected %d more.", explicitParamCount - (int)arguments.size()), targetSrc);
  10497. if ((error != NULL) && (methodInstance->mMethodDef->mMethodDeclaration != NULL))
  10498. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
  10499. return;
  10500. }
  10501. else if ((int)args.size() > explicitParamCount)
  10502. {
  10503. BfError* error = mModule->Fail(StrFormat("Too many arguments specified, expected %d fewer.", (int)arguments.size() - explicitParamCount), targetSrc);
  10504. if ((error != NULL) && (methodInstance->mMethodDef->mMethodDeclaration != NULL))
  10505. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
  10506. return;
  10507. }
  10508. int paramIdx = implicitParamCount;
  10509. auto argExprEvaluatorItr = argExprEvaluators.begin();
  10510. for (int argIdx = 0; argIdx < (int)args.size(); argIdx++)
  10511. {
  10512. auto exprEvaluator = *argExprEvaluatorItr;
  10513. //auto paramType = methodInstance->GetParamKind(paramIdx);
  10514. BfType* wantType = methodInstance->mParams[paramIdx].mResolvedType;
  10515. auto& arg = args[argIdx];
  10516. if (wantType->IsGenericParam())
  10517. {
  10518. //
  10519. }
  10520. else if (!wantType->IsVar())
  10521. {
  10522. if (arg.mTypedValue.mType == NULL)
  10523. {
  10524. mModule->AssertErrorState();
  10525. return;
  10526. }
  10527. if (arg.mTypedValue.mType != wantType)
  10528. {
  10529. exprEvaluator->FinishExpressionResult();
  10530. arg.mTypedValue = mModule->LoadValue(arg.mTypedValue);
  10531. arg.mTypedValue = mModule->Cast(arg.mExpression, arg.mTypedValue, wantType);
  10532. /*// Do this to generate default implicit cast error
  10533. mModule->Fail(StrFormat("Mixin argument type '%s' must match parameter type '%s'.",
  10534. mModule->TypeToString(arg.mTypedValue.mType).c_str(),
  10535. mModule->TypeToString(wantType).c_str()), arg.mExpression);
  10536. return;*/
  10537. }
  10538. }
  10539. paramIdx++;
  10540. argExprEvaluatorItr++;
  10541. }
  10542. mModule->AddDependency(methodInstance->GetOwner(), mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_InlinedCall);
  10543. auto startBlock = mModule->mBfIRBuilder->CreateBlock("mixinStart");
  10544. mModule->mBfIRBuilder->CreateBr(startBlock);
  10545. mModule->mBfIRBuilder->AddBlock(startBlock);
  10546. mModule->mBfIRBuilder->SetInsertPoint(startBlock);
  10547. //auto prevDebugLoc = mModule->mBfIRBuilder->getCurrentDebugLocation();
  10548. // This is so when we debug we can hit a steppoint on the inlined "call line"
  10549. mModule->EmitEnsureInstructionAt();
  10550. auto rootMethodState = mModule->mCurMethodState->GetRootMethodState();
  10551. BfMixinState* mixinState = rootMethodState->mMixinStates.Alloc();
  10552. mixinState->mPrevMixinState = curMethodState->mMixinState;
  10553. mixinState->mLocalsStartIdx = (int)mModule->mCurMethodState->mLocals.size();
  10554. mixinState->mMixinMethodInstance = methodInstance;
  10555. mixinState->mSource = origTargetSrc;
  10556. mixinState->mCallerScope = mModule->mCurMethodState->mCurScope;
  10557. mixinState->mTargetScope = mixinState->mCallerScope;
  10558. mixinState->mResultExpr = NULL;
  10559. mixinState->mHasDeferredUsage = false;
  10560. mixinState->mUsedInvocationScope = false;
  10561. mixinState->mTarget = target;
  10562. auto checkNode = origTargetSrc;
  10563. if (scopedInvocationTarget != NULL)
  10564. {
  10565. auto targetScope = mModule->FindScope(scopedInvocationTarget->mScopeName, curMethodState->mMixinState);
  10566. if (targetScope != NULL)
  10567. mixinState->mTargetScope = targetScope;
  10568. }
  10569. mModule->mBfIRBuilder->SaveDebugLocation();
  10570. SetAndRestoreValue<BfMixinState*> prevMixinState(curMethodState->mMixinState, mixinState);
  10571. BfGetSymbolReferenceKind prevSymbolRefKind = BfGetSymbolReferenceKind_None;
  10572. if (mModule->mCompiler->mResolvePassData != NULL)
  10573. {
  10574. prevSymbolRefKind = mModule->mCompiler->mResolvePassData->mGetSymbolReferenceKind;
  10575. mModule->mCompiler->mResolvePassData->mGetSymbolReferenceKind = BfGetSymbolReferenceKind_None;
  10576. }
  10577. defer
  10578. {
  10579. if (mModule->mCompiler->mResolvePassData != NULL)
  10580. mModule->mCompiler->mResolvePassData->mGetSymbolReferenceKind = prevSymbolRefKind;
  10581. };
  10582. auto methodDef = methodInstance->mMethodDef;
  10583. auto methodDeclaration = methodDef->GetMethodDeclaration();
  10584. BfScopeData scopeData;
  10585. scopeData.mCloseNode = methodDeclaration->mBody;
  10586. if (auto block = BfNodeDynCast<BfBlock>(methodDeclaration->mBody))
  10587. {
  10588. if (block->mCloseBrace != NULL)
  10589. scopeData.mCloseNode = block->mCloseBrace;
  10590. }
  10591. curMethodState->AddScope(&scopeData);
  10592. curMethodState->mCurScope->mMixinDepth++;
  10593. curMethodState->mIsEmbedded = false;
  10594. // We can't flush scope state because we extend params in as arbitrary values
  10595. mModule->NewScopeState(true, false);
  10596. bool wantsDIData = (mModule->mBfIRBuilder->DbgHasInfo()) && (mModule->mHasFullDebugInfo);
  10597. DISubprogram* diFunction = NULL;
  10598. int mixinLocalVarIdx = -1;
  10599. int startLocalIdx = (int)mModule->mCurMethodState->mLocals.size();
  10600. int endLocalIdx = startLocalIdx;
  10601. if (wantsDIData)
  10602. {
  10603. BfIRMDNode diFuncType = mModule->mBfIRBuilder->DbgCreateSubroutineType(SizedArray<BfIRMDNode, 0>());
  10604. //int defLine = mModule->mCurFilePosition.mCurLine;
  10605. int flags = 0;
  10606. curMethodState->mCurScope->mDIInlinedAt = mModule->mBfIRBuilder->DbgGetCurrentLocation();
  10607. // 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
  10608. // definitions, so we need to be consistent and use the actual line
  10609. mModule->UpdateSrcPos(methodDeclaration->mNameNode, BfSrcPosFlag_NoSetDebugLoc);
  10610. int defLine = mModule->mCurFilePosition.mCurLine;
  10611. auto diParentType = mModule->mBfIRBuilder->DbgGetTypeInst(methodInstance->GetOwner());
  10612. if (!mModule->mBfIRBuilder->mIgnoreWrites)
  10613. {
  10614. curMethodState->mCurScope->mDIScope = mModule->mBfIRBuilder->DbgCreateFunction(diParentType, methodDef->mName + "!", "", mModule->mCurFilePosition.mFileInstance->mDIFile,
  10615. defLine + 1, diFuncType, false, true, mModule->mCurFilePosition.mCurLine + 1, flags, false, BfIRValue());
  10616. scopeData.mAltDIFile = mModule->mCurFilePosition.mFileInstance->mDIFile;
  10617. }
  10618. }
  10619. if (methodDef->mBody != NULL)
  10620. mModule->UpdateSrcPos(methodDef->mBody);
  10621. mModule->SetIllegalSrcPos();
  10622. auto _AddLocalVariable = [&](BfLocalVariable* newLocalVar, BfExprEvaluator* exprEvaluator)
  10623. {
  10624. mModule->SetIllegalSrcPos();
  10625. bool hasConstValue = newLocalVar->mConstValue;
  10626. if (hasConstValue)
  10627. {
  10628. auto constant = mModule->mBfIRBuilder->GetConstant(newLocalVar->mConstValue);
  10629. hasConstValue = constant->mConstType < BfConstType_GlobalVar;
  10630. }
  10631. if ((exprEvaluator != NULL) && (exprEvaluator->mResultLocalVar != NULL) && (exprEvaluator->mResultLocalVarField == 0))
  10632. {
  10633. mModule->UpdateSrcPos(methodDeclaration->mNameNode);
  10634. mModule->AddLocalVariableDef(newLocalVar, hasConstValue);
  10635. auto inLocalVar = exprEvaluator->mResultLocalVar;
  10636. newLocalVar->mIsAssigned = inLocalVar->mIsAssigned;
  10637. newLocalVar->mUnassignedFieldFlags = inLocalVar->mUnassignedFieldFlags;
  10638. newLocalVar->mReadFromId = inLocalVar->mReadFromId;
  10639. newLocalVar->mIsReadOnly = inLocalVar->mIsReadOnly;
  10640. if ((!newLocalVar->mIsAssigned) && (mModule->mCurMethodState->mDeferredLocalAssignData != NULL))
  10641. {
  10642. for (auto deferredAssign : mModule->mCurMethodState->mDeferredLocalAssignData->mAssignedLocals)
  10643. {
  10644. if (deferredAssign.mLocalVar == inLocalVar)
  10645. newLocalVar->mIsAssigned = true;
  10646. }
  10647. }
  10648. }
  10649. else
  10650. {
  10651. mModule->AddLocalVariableDef(newLocalVar, hasConstValue);
  10652. }
  10653. if ((wantsDIData) && (!mModule->mBfIRBuilder->mIgnoreWrites))
  10654. {
  10655. mModule->UpdateSrcPos(methodDeclaration->mNameNode);
  10656. if (hasConstValue)
  10657. {
  10658. // Already handled
  10659. }
  10660. else if (mModule->IsTargetingBeefBackend())
  10661. {
  10662. mModule->UpdateSrcPos(methodDeclaration->mNameNode);
  10663. mModule->SetIllegalSrcPos();
  10664. // With the Beef backend we can assign two variables to the same value, but LLVM does not allow this
  10665. // so we have to create a ref to that variable
  10666. auto diType = mModule->mBfIRBuilder->DbgGetType(newLocalVar->mResolvedType);
  10667. auto diVariable = mModule->mBfIRBuilder->DbgCreateAutoVariable(mModule->mCurMethodState->mCurScope->mDIScope,
  10668. newLocalVar->mName, mModule->mCurFilePosition.mFileInstance->mDIFile, mModule->mCurFilePosition.mCurLine, diType);
  10669. if (newLocalVar->mIsSplat)
  10670. {
  10671. //TODO: Implement
  10672. }
  10673. else
  10674. {
  10675. BfIRValue value = newLocalVar->mValue;
  10676. if (newLocalVar->mAddr)
  10677. value = newLocalVar->mAddr;
  10678. else if (newLocalVar->mConstValue)
  10679. value = newLocalVar->mConstValue;
  10680. auto aliasValue = mModule->mBfIRBuilder->CreateAliasValue(value);
  10681. if (mModule->WantsLifetimes())
  10682. scopeData.mDeferredLifetimeEnds.Add(aliasValue);
  10683. if (newLocalVar->mAddr)
  10684. mModule->mBfIRBuilder->DbgInsertDeclare(aliasValue, diVariable);
  10685. else
  10686. {
  10687. mModule->mBfIRBuilder->DbgInsertValueIntrinsic(aliasValue, diVariable);
  10688. //mModule->mBfIRBuilder->DbgInsertValueIntrinsic(newLocalVar->mValue, diVariable);
  10689. }
  10690. }
  10691. }
  10692. else if (newLocalVar->mAddr)
  10693. {
  10694. mModule->UpdateSrcPos(methodDeclaration->mNameNode);
  10695. mModule->SetIllegalSrcPos();
  10696. auto refType = mModule->CreateRefType(newLocalVar->mResolvedType);
  10697. auto allocaVal = mModule->CreateAlloca(refType);
  10698. mModule->mBfIRBuilder->CreateStore(newLocalVar->mAddr, allocaVal);
  10699. if (!mModule->mBfIRBuilder->mIgnoreWrites)
  10700. {
  10701. auto diType = mModule->mBfIRBuilder->DbgGetType(refType);
  10702. auto diVariable = mModule->mBfIRBuilder->DbgCreateAutoVariable(mModule->mCurMethodState->mCurScope->mDIScope,
  10703. newLocalVar->mName, mModule->mCurFilePosition.mFileInstance->mDIFile, mModule->mCurFilePosition.mCurLine, diType);
  10704. mModule->mBfIRBuilder->DbgInsertDeclare(allocaVal, diVariable);
  10705. }
  10706. }
  10707. else if (newLocalVar->mValue)
  10708. {
  10709. mModule->UpdateSrcPos(methodDeclaration->mNameNode);
  10710. mModule->SetIllegalSrcPos();
  10711. auto localVal = LoadLocal(newLocalVar);
  10712. localVal = mModule->LoadValue(localVal);
  10713. localVal = mModule->AggregateSplat(localVal);
  10714. BfType* allocType = localVal.mType;
  10715. auto allocaVal = mModule->CreateAlloca(allocType);
  10716. mModule->mBfIRBuilder->CreateStore(localVal.mValue, allocaVal);
  10717. if (!mModule->mBfIRBuilder->mIgnoreWrites)
  10718. {
  10719. if (newLocalVar->mIsSplat)
  10720. {
  10721. //TODO: Implement
  10722. }
  10723. else
  10724. {
  10725. auto diType = mModule->mBfIRBuilder->DbgGetType(allocType);
  10726. auto diVariable = mModule->mBfIRBuilder->DbgCreateAutoVariable(mModule->mCurMethodState->mCurScope->mDIScope,
  10727. newLocalVar->mName, mModule->mCurFilePosition.mFileInstance->mDIFile, mModule->mCurFilePosition.mCurLine, diType);
  10728. mModule->mBfIRBuilder->DbgInsertDeclare(allocaVal, diVariable);
  10729. }
  10730. }
  10731. }
  10732. }
  10733. newLocalVar->mParamIdx = -3;
  10734. };
  10735. argExprEvaluatorItr = argExprEvaluators.begin();
  10736. for (int argIdx = 0; argIdx < (int)explicitParamCount; argIdx++)
  10737. {
  10738. int paramIdx = argIdx;
  10739. auto exprEvaluator = *argExprEvaluatorItr;
  10740. auto paramDef = methodDef->mParams[paramIdx];
  10741. auto arg = &args[argIdx];
  10742. if (!arg->mTypedValue)
  10743. {
  10744. auto wantType = methodInstance->GetParamType(paramIdx);
  10745. if (wantType->IsVar())
  10746. wantType = mModule->mContext->mBfObjectType;
  10747. arg->mTypedValue = mModule->GetDefaultTypedValue(wantType);
  10748. }
  10749. BfLocalVariable* localVar = new BfLocalVariable();
  10750. localVar->mName = paramDef->mName;
  10751. localVar->mResolvedType = arg->mTypedValue.mType;
  10752. if (arg->mTypedValue.mType->IsRef())
  10753. {
  10754. auto refType = (BfRefType*)localVar->mResolvedType;
  10755. localVar->mAddr = mModule->LoadValue(arg->mTypedValue).mValue;
  10756. localVar->mResolvedType = arg->mTypedValue.mType->GetUnderlyingType();
  10757. localVar->mIsAssigned = refType->mRefKind != BfRefType::RefKind_Out;
  10758. }
  10759. else if (arg->mTypedValue.IsAddr())
  10760. localVar->mAddr = arg->mTypedValue.mValue;
  10761. else
  10762. {
  10763. if (!arg->mTypedValue.mValue)
  10764. {
  10765. // Untyped value
  10766. }
  10767. else if (arg->mTypedValue.mValue.IsConst())
  10768. {
  10769. localVar->mConstValue = arg->mTypedValue.mValue;
  10770. }
  10771. else if (arg->mTypedValue.IsSplat())
  10772. {
  10773. localVar->mValue = arg->mTypedValue.mValue;
  10774. localVar->mIsSplat = true;
  10775. }
  10776. else
  10777. {
  10778. if (arg->mTypedValue.IsAddr())
  10779. localVar->mAddr = arg->mTypedValue.mValue;
  10780. else
  10781. localVar->mValue = arg->mTypedValue.mValue;
  10782. }
  10783. localVar->mIsReadOnly = arg->mTypedValue.IsReadOnly();
  10784. }
  10785. _AddLocalVariable(localVar, exprEvaluator);
  10786. endLocalIdx++;
  10787. ++argExprEvaluatorItr;
  10788. }
  10789. if (auto blockBody = BfNodeDynCast<BfBlock>(methodDef->mBody))
  10790. mModule->VisitCodeBlock(blockBody);
  10791. if (mixinState->mResultExpr != NULL)
  10792. {
  10793. if (auto exprNode = BfNodeDynCast<BfExpression>(mixinState->mResultExpr))
  10794. {
  10795. //if ((exprNode->mTrailingSemicolon == NULL) && (!exprNode->IsA<BfBlock>()))
  10796. if (!exprNode->IsA<BfBlock>())
  10797. {
  10798. // Mixin expression result
  10799. mModule->UpdateSrcPos(exprNode);
  10800. VisitChild(exprNode);
  10801. FinishExpressionResult();
  10802. ResolveGenericType();
  10803. //mResult = mModule->LoadValue(mResult);
  10804. }
  10805. }
  10806. }
  10807. if (!mResult)
  10808. {
  10809. // If we didn't have an expression body then just make the result "void"
  10810. mResult = BfTypedValue(BfIRValue(), mModule->GetPrimitiveType(BfTypeCode_None));
  10811. }
  10812. int localIdx = startLocalIdx;
  10813. if (mixinLocalVarIdx != -1)
  10814. {
  10815. BfLocalVariable* localVar = curMethodState->mLocals[localIdx];
  10816. if (mResultLocalVar != NULL)
  10817. {
  10818. auto inLocalVar = mResultLocalVar;
  10819. if (localVar->mIsAssigned)
  10820. inLocalVar->mIsAssigned = true;
  10821. if (localVar->mReadFromId != -1)
  10822. inLocalVar->mReadFromId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++;
  10823. }
  10824. localIdx++;
  10825. }
  10826. argExprEvaluatorItr = argExprEvaluators.begin();
  10827. for ( ; localIdx < endLocalIdx; localIdx++)
  10828. {
  10829. auto exprEvaluator = *argExprEvaluatorItr;
  10830. BfLocalVariable* localVar = curMethodState->mLocals[localIdx];
  10831. //TODO: Merge unassigned flags together
  10832. if ((exprEvaluator != NULL) && (exprEvaluator->mResultLocalVar != NULL))
  10833. {
  10834. auto inLocalVar = exprEvaluator->mResultLocalVar;
  10835. if (localVar->mIsAssigned)
  10836. inLocalVar->mIsAssigned = true;
  10837. if (localVar->mReadFromId != -1)
  10838. inLocalVar->mReadFromId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++;
  10839. }
  10840. ++argExprEvaluatorItr;
  10841. }
  10842. if (auto blockBody = BfNodeDynCast<BfBlock>(methodDef->mBody))
  10843. if (blockBody->mCloseBrace != NULL)
  10844. mModule->UpdateSrcPos(blockBody->mCloseBrace);
  10845. mModule->RestoreScopeState();
  10846. prevMixinState.Restore();
  10847. if (mixinState->mHasDeferredUsage)
  10848. {
  10849. // if (target)
  10850. // {
  10851. // if (target.mType->IsValuelessType())
  10852. // mixinState->mTarget = target;
  10853. // else
  10854. // {
  10855. // target = mModule->LoadValue(target);
  10856. // auto savedTarget = BfTypedValue(mModule->CreateAlloca(target.mType, false), target.mType, true);
  10857. // mModule->mBfIRBuilder->CreateStore(target.mValue, savedTarget.mValue);
  10858. // mixinState->mTarget = savedTarget;
  10859. // }
  10860. // }
  10861. mixinState->mTarget = BfTypedValue();
  10862. }
  10863. else
  10864. {
  10865. BF_ASSERT(rootMethodState->mMixinStates.back() == mixinState);
  10866. rootMethodState->mMixinStates.pop_back();
  10867. delete mixinState;
  10868. }
  10869. if ((scopedInvocationTarget != NULL) && (scopedInvocationTarget->mScopeName != NULL) && (!mixinState->mUsedInvocationScope))
  10870. {
  10871. mModule->Warn(0, "Scope specifier was not referenced in mixin", scopedInvocationTarget->mScopeName);
  10872. }
  10873. // It's tempting to do this, but it is really just covering up other issues.
  10874. //mModule->mBfIRBuilder->SetCurrentDebugLocation(prevDebugLoc);
  10875. // But does THIS work?
  10876. mModule->mBfIRBuilder->RestoreDebugLocation();
  10877. }
  10878. void BfExprEvaluator::SetMethodElementType(BfAstNode* target)
  10879. {
  10880. if (auto delegateBindExpr = BfNodeDynCast<BfDelegateBindExpression>(target))
  10881. {
  10882. SetMethodElementType(delegateBindExpr->mTarget);
  10883. return;
  10884. }
  10885. if (auto lambdaBindExpr = BfNodeDynCast<BfLambdaBindExpression>(target))
  10886. {
  10887. return;
  10888. }
  10889. if (auto attributedIdentifierNode = BfNodeDynCast<BfAttributedIdentifierNode>(target))
  10890. {
  10891. if (attributedIdentifierNode->mIdentifier != NULL)
  10892. mModule->SetElementType(attributedIdentifierNode->mIdentifier, BfSourceElementType_Method);
  10893. }
  10894. else if (auto memberReferenceExpr = BfNodeDynCast<BfMemberReferenceExpression>(target))
  10895. {
  10896. if (memberReferenceExpr->mMemberName != NULL)
  10897. SetMethodElementType(memberReferenceExpr->mMemberName);
  10898. }
  10899. else if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(target))
  10900. SetMethodElementType(qualifiedNameNode->mRight);
  10901. else
  10902. mModule->SetElementType(target, BfSourceElementType_Method);
  10903. }
  10904. void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* methodBoundExpr, const BfSizedArray<BfExpression*>& args, BfSizedArray<ASTREF(BfTypeReference*)>* methodGenericArguments, BfTypedValue* outCascadeValue)
  10905. {
  10906. // Just a check
  10907. mModule->mBfIRBuilder->GetInsertBlock();
  10908. bool wasCapturingMethodInfo = false;
  10909. auto autoComplete = GetAutoComplete();
  10910. if ((autoComplete != NULL) && (methodGenericArguments != NULL))
  10911. {
  10912. for (BfTypeReference* methodGenericArg : *methodGenericArguments)
  10913. autoComplete->CheckTypeRef(methodGenericArg, false, true);
  10914. }
  10915. if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo))
  10916. {
  10917. // We don't want to capture a call within the target node
  10918. wasCapturingMethodInfo = true;
  10919. autoComplete->mIsCapturingMethodMatchInfo = false;
  10920. }
  10921. bool allowImplicitThis = false;
  10922. BfAstNode* methodNodeSrc = target;
  10923. BfAttributeState attributeState;
  10924. attributeState.mTarget = (BfAttributeTargets)(BfAttributeTargets_Invocation | BfAttributeTargets_MemberAccess);
  10925. if (auto scopedTarget = BfNodeDynCast<BfScopedInvocationTarget>(target))
  10926. {
  10927. target = scopedTarget->mTarget;
  10928. if (autoComplete != NULL)
  10929. {
  10930. if (auto identifier = BfNodeDynCast<BfIdentifierNode>(scopedTarget->mScopeName))
  10931. autoComplete->CheckLabel(identifier, scopedTarget->mColonToken);
  10932. }
  10933. //mModule->FindScope(scopedTarget->mScopeName);
  10934. }
  10935. bool isCascade = false;
  10936. BfAstNode* cascadeOperatorToken = NULL;
  10937. bool bypassVirtual = false;
  10938. bool gaveUnqualifiedDotError = false;
  10939. String targetFunctionName;
  10940. BfTypedValue thisValue;
  10941. //TODO: This may just be a fully qualified static method name, so let's check that also
  10942. if (auto memberRefExpression = BfNodeDynCast<BfMemberReferenceExpression>(target))
  10943. {
  10944. if (autoComplete != NULL)
  10945. {
  10946. if (memberRefExpression->mTarget != NULL)
  10947. autoComplete->CheckMemberReference(memberRefExpression->mTarget, memberRefExpression->mDotToken, memberRefExpression->mMemberName, false, mExpectingType);
  10948. else if (mExpectingType != NULL)
  10949. {
  10950. String filter;
  10951. if ((autoComplete != NULL) && (autoComplete->InitAutocomplete(memberRefExpression->mDotToken, memberRefExpression->mMemberName, filter)))
  10952. {
  10953. auto typeInst = mExpectingType->ToTypeInstance();
  10954. if (typeInst != NULL)
  10955. {
  10956. String filter;
  10957. if ((memberRefExpression->mMemberName != NULL) && (autoComplete->IsAutocompleteNode(memberRefExpression->mMemberName)))
  10958. filter = autoComplete->GetFilter(memberRefExpression->mMemberName);
  10959. bool allowPrivate = typeInst == mModule->mCurTypeInstance;
  10960. autoComplete->AddEnumTypeMembers(typeInst, filter, false, allowPrivate);
  10961. autoComplete->AddSelfResultTypeMembers(typeInst, typeInst, filter, allowPrivate);
  10962. }
  10963. }
  10964. }
  10965. }
  10966. if ((memberRefExpression->mTarget == NULL) && (memberRefExpression->mMemberName == NULL))
  10967. {
  10968. if (mExpectingType != NULL)
  10969. {
  10970. if (mExpectingType->IsSizedArray())
  10971. {
  10972. if (mModule->mParentNodeEntry != NULL)
  10973. {
  10974. if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(mModule->mParentNodeEntry->mNode))
  10975. {
  10976. InitializedSizedArray((BfSizedArrayType*)mExpectingType, invocationExpr->mOpenParen, invocationExpr->mArguments, invocationExpr->mCommas, invocationExpr->mCloseParen);
  10977. return;
  10978. }
  10979. }
  10980. }
  10981. else if (mExpectingType->IsStruct())
  10982. {
  10983. if ((wasCapturingMethodInfo) && (autoComplete->mMethodMatchInfo != NULL))
  10984. {
  10985. autoComplete->mIsCapturingMethodMatchInfo = true;
  10986. BF_ASSERT(autoComplete->mMethodMatchInfo != NULL);
  10987. }
  10988. if (mModule->mParentNodeEntry != NULL)
  10989. {
  10990. if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(mModule->mParentNodeEntry->mNode))
  10991. {
  10992. BfResolvedArgs argValues(invocationExpr->mOpenParen, &invocationExpr->mArguments, &invocationExpr->mCommas, invocationExpr->mCloseParen);
  10993. BfResolveArgFlags resolveArgsFlags = BfResolveArgFlag_DeferParamEval;
  10994. ResolveArgValues(argValues, resolveArgsFlags);
  10995. if ((mReceivingValue != NULL) && (mReceivingValue->mType == mExpectingType) && (mReceivingValue->IsAddr()))
  10996. {
  10997. mResult = *mReceivingValue;
  10998. mReceivingValue = NULL;
  10999. }
  11000. else
  11001. mResult = BfTypedValue(mModule->CreateAlloca(mExpectingType), mExpectingType, BfTypedValueKind_TempAddr);
  11002. MatchConstructor(target, methodBoundExpr, mResult, mExpectingType->ToTypeInstance(), argValues, false, false);
  11003. mModule->ValidateAllocation(mExpectingType, invocationExpr->mTarget);
  11004. return;
  11005. }
  11006. }
  11007. }
  11008. else
  11009. {
  11010. gaveUnqualifiedDotError = true;
  11011. mModule->Fail(StrFormat("Cannot use inferred constructor on type '%s'", mModule->TypeToString(mExpectingType).c_str()), memberRefExpression->mDotToken);
  11012. }
  11013. }
  11014. }
  11015. if (memberRefExpression->IsA<BfBaseExpression>())
  11016. bypassVirtual = true;
  11017. if (memberRefExpression->mMemberName != NULL)
  11018. methodNodeSrc = memberRefExpression->mMemberName;
  11019. if (auto attrIdentifier = BfNodeDynCast<BfAttributedIdentifierNode>(memberRefExpression->mMemberName))
  11020. {
  11021. if (attrIdentifier->mIdentifier != NULL)
  11022. methodNodeSrc = attrIdentifier->mIdentifier;
  11023. attributeState.mCustomAttributes = mModule->GetCustomAttributes(attrIdentifier->mAttributes, attributeState.mTarget);
  11024. if (attrIdentifier->mIdentifier != NULL)
  11025. targetFunctionName = attrIdentifier->mIdentifier->ToString();
  11026. }
  11027. else if (memberRefExpression->mMemberName != NULL)
  11028. targetFunctionName = memberRefExpression->mMemberName->ToString();
  11029. if (memberRefExpression->mTarget == NULL)
  11030. {
  11031. if (mExpectingType)
  11032. mResult = BfTypedValue(mExpectingType);
  11033. else if (!gaveUnqualifiedDotError)
  11034. mModule->Fail("Unqualified dot syntax can only be used when the result type can be inferred", memberRefExpression->mDotToken);
  11035. }
  11036. else if (auto typeRef = BfNodeDynCast<BfTypeReference>(memberRefExpression->mTarget))
  11037. {
  11038. // Static method
  11039. mResult = BfTypedValue(ResolveTypeRef(typeRef));
  11040. }
  11041. if (auto leftIdentifier = BfNodeDynCast<BfIdentifierNode>(memberRefExpression->mTarget))
  11042. {
  11043. bool hadError = false;
  11044. thisValue = LookupIdentifier(leftIdentifier, true, &hadError);
  11045. CheckResultForReading(thisValue);
  11046. if (mPropDef != NULL)
  11047. thisValue = GetResult(true);
  11048. if (hadError)
  11049. {
  11050. mModule->AssertErrorState();
  11051. thisValue = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  11052. }
  11053. if ((!thisValue) && (mPropDef == NULL))
  11054. {
  11055. // Identifier not found. Static method? Just check speculatively don't throw error
  11056. BfType* type;
  11057. {
  11058. SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
  11059. type = mModule->ResolveTypeRef(leftIdentifier, NULL, BfPopulateType_DataAndMethods, BfResolveTypeRefFlag_NoResolveGenericParam);
  11060. }
  11061. if (type != NULL)
  11062. thisValue = BfTypedValue(type);
  11063. else if (auto qualifiedLeft = BfNodeDynCast<BfQualifiedNameNode>(leftIdentifier))
  11064. {
  11065. LookupQualifiedStaticField(qualifiedLeft, true);
  11066. thisValue = mResult;
  11067. mResult = BfTypedValue();
  11068. }
  11069. }
  11070. if (mPropDef != NULL)
  11071. thisValue = GetResult(true);
  11072. if (!thisValue.mType)
  11073. {
  11074. mModule->Fail("Identifier not found", leftIdentifier);
  11075. mModule->CheckTypeRefFixit(leftIdentifier);
  11076. thisValue = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  11077. }
  11078. if (mResult)
  11079. CheckResultForReading(mResult);
  11080. mResult = thisValue;
  11081. }
  11082. else if (auto expr = BfNodeDynCast<BfExpression>(memberRefExpression->mTarget))
  11083. {
  11084. BfType* expectingTargetType = NULL;
  11085. if (memberRefExpression->mDotToken->mToken == BfToken_DotDot)
  11086. expectingTargetType = mExpectingType;
  11087. bool handled = false;
  11088. if (auto subMemberRefExpr = BfNodeDynCast<BfMemberReferenceExpression>(expr))
  11089. {
  11090. String findName;
  11091. if (subMemberRefExpr->mMemberName != NULL)
  11092. findName = subMemberRefExpr->mMemberName->ToString();
  11093. if (findName == "base") // Generic IFace<T>.base
  11094. {
  11095. thisValue = mModule->GetThis();
  11096. if (thisValue)
  11097. {
  11098. VisitChild(subMemberRefExpr->mTarget);
  11099. if (mResult.HasType())
  11100. {
  11101. if (mResult.mValue)
  11102. {
  11103. mModule->Fail("Type name expected", subMemberRefExpr->mTarget);
  11104. }
  11105. else
  11106. {
  11107. auto type = mResult.mType;
  11108. if (type != NULL)
  11109. {
  11110. if ((thisValue.mType == type) || (!mModule->TypeIsSubTypeOf(thisValue.mType->ToTypeInstance(), type->ToTypeInstance())))
  11111. {
  11112. mModule->Fail(StrFormat("Type '%s' is not a base type of '%s'",
  11113. mModule->TypeToString(type).c_str(),
  11114. mModule->TypeToString(thisValue.mType).c_str()), subMemberRefExpr->mTarget);
  11115. }
  11116. else
  11117. {
  11118. if (type->IsInterface())
  11119. {
  11120. thisValue.mType = type;
  11121. }
  11122. else
  11123. {
  11124. auto castedThis = mModule->Cast(subMemberRefExpr->mMemberName, thisValue, type, BfCastFlags_Explicit);
  11125. if (castedThis)
  11126. thisValue = castedThis;
  11127. //mModule->Fail("Explicit base types can only be used for specifying default interface members", qualifiedLeft->mLeft);
  11128. }
  11129. }
  11130. handled = true;
  11131. }
  11132. bypassVirtual = true;
  11133. }
  11134. }
  11135. }
  11136. }
  11137. }
  11138. if (!handled)
  11139. {
  11140. SetAndRestoreValue<BfAttributeState*> prevAttributeState(mModule->mAttributeState, &attributeState);
  11141. auto flags = (BfEvalExprFlags)(BfEvalExprFlags_PropogateNullConditional | BfEvalExprFlags_NoCast);
  11142. if (mFunctionBindResult != NULL)
  11143. {
  11144. if (auto paranExpr = BfNodeDynCast<BfParenthesizedExpression>(expr))
  11145. {
  11146. // Allow 'ref' on binding, to indicate we want to capture 'this' by reference
  11147. flags = (BfEvalExprFlags)(flags | BfEvalExprFlags_AllowRefExpr);
  11148. expr = paranExpr->mExpression;
  11149. }
  11150. }
  11151. if (expr != NULL)
  11152. mResult = mModule->CreateValueFromExpression(expr, expectingTargetType, flags);
  11153. }
  11154. }
  11155. isCascade = (memberRefExpression->mDotToken != NULL) && (memberRefExpression->mDotToken->GetToken() == BfToken_DotDot);
  11156. if (isCascade)
  11157. cascadeOperatorToken = memberRefExpression->mDotToken;
  11158. bool isNullCondLookup = (memberRefExpression->mDotToken != NULL) && (memberRefExpression->mDotToken->GetToken() == BfToken_QuestionDot);
  11159. if (isNullCondLookup)
  11160. mResult = SetupNullConditional(mResult, memberRefExpression->mDotToken);
  11161. if ((mResult.mType == NULL) && (memberRefExpression->mTarget != NULL))
  11162. {
  11163. mModule->AssertErrorState();
  11164. mResult = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  11165. }
  11166. thisValue = mResult;
  11167. mResult = BfTypedValue();
  11168. }
  11169. else if (auto qualifiedName = BfNodeDynCast<BfQualifiedNameNode>(target))
  11170. {
  11171. if (GetAutoComplete() != NULL)
  11172. GetAutoComplete()->CheckMemberReference(qualifiedName->mLeft, qualifiedName->mDot, qualifiedName->mRight);
  11173. if (qualifiedName->mLeft->GetSrcLength() == 4)
  11174. {
  11175. StringT<16> leftName;
  11176. qualifiedName->mLeft->ToString(leftName);
  11177. if (leftName == "base")
  11178. bypassVirtual = true;
  11179. }
  11180. if (qualifiedName->mRight != NULL)
  11181. methodNodeSrc = qualifiedName->mRight;
  11182. if (auto attrIdentifier = BfNodeDynCast<BfAttributedIdentifierNode>(qualifiedName->mRight))
  11183. {
  11184. if (attrIdentifier->mIdentifier != NULL)
  11185. methodNodeSrc = attrIdentifier->mIdentifier;
  11186. attributeState.mCustomAttributes = mModule->GetCustomAttributes(attrIdentifier->mAttributes, attributeState.mTarget);
  11187. targetFunctionName = attrIdentifier->mIdentifier->ToString();
  11188. }
  11189. else
  11190. targetFunctionName = qualifiedName->mRight->ToString();
  11191. bool hadError = false;
  11192. thisValue = LookupIdentifier(qualifiedName->mLeft, true, &hadError);
  11193. CheckResultForReading(thisValue);
  11194. if (mPropDef != NULL)
  11195. thisValue = GetResult(true);
  11196. if (hadError)
  11197. {
  11198. mModule->AssertErrorState();
  11199. thisValue = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  11200. }
  11201. if ((!thisValue) && (mPropDef == NULL))
  11202. {
  11203. // Identifier not found. Static method? Just check speculatively don't throw error
  11204. BfType* type;
  11205. {
  11206. //SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
  11207. type = mModule->ResolveTypeRef(qualifiedName->mLeft, NULL, BfPopulateType_DataAndMethods, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoResolveGenericParam | BfResolveTypeRefFlag_IgnoreLookupError));
  11208. }
  11209. if (type == NULL)
  11210. {
  11211. //SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
  11212. type = mModule->ResolveTypeRef(qualifiedName, methodGenericArguments, BfPopulateType_DataAndMethods, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoResolveGenericParam | BfResolveTypeRefFlag_IgnoreLookupError));
  11213. if (type != NULL)
  11214. {
  11215. // This is a CTOR call, treat it as such
  11216. targetFunctionName.clear();
  11217. }
  11218. }
  11219. if (type != NULL)
  11220. thisValue = BfTypedValue(type);
  11221. else if (auto qualifiedLeft = BfNodeDynCast<BfQualifiedNameNode>(qualifiedName->mLeft))
  11222. {
  11223. String findName = qualifiedLeft->mRight->ToString();
  11224. bool handled = false;
  11225. if (findName == "base")
  11226. {
  11227. auto type = mModule->ResolveTypeRef(qualifiedLeft->mLeft, NULL, BfPopulateType_Data, BfResolveTypeRefFlag_AllowRef);
  11228. mModule->CheckTypeRefFixit(qualifiedLeft->mLeft);
  11229. thisValue = mModule->GetThis();
  11230. if (type != NULL)
  11231. {
  11232. if ((thisValue.mType == type) || (!mModule->TypeIsSubTypeOf(thisValue.mType->ToTypeInstance(), type->ToTypeInstance())))
  11233. {
  11234. mModule->Fail(StrFormat("Type '%s' is not a base type of '%s'",
  11235. mModule->TypeToString(type).c_str(),
  11236. mModule->TypeToString(thisValue.mType).c_str()), qualifiedLeft->mLeft);
  11237. }
  11238. else
  11239. {
  11240. if (type->IsInterface())
  11241. {
  11242. thisValue.mType = type;
  11243. }
  11244. else
  11245. {
  11246. auto castedThis = mModule->Cast(qualifiedLeft->mRight, thisValue, type, BfCastFlags_Explicit);
  11247. if (castedThis)
  11248. thisValue = castedThis;
  11249. //mModule->Fail("Explicit base types can only be used for specifying default interface members", qualifiedLeft->mLeft);
  11250. }
  11251. }
  11252. handled = true;
  11253. }
  11254. bypassVirtual = true;
  11255. }
  11256. if (!handled)
  11257. {
  11258. LookupQualifiedStaticField(qualifiedLeft, true);
  11259. thisValue = mResult;
  11260. mResult = BfTypedValue();
  11261. }
  11262. }
  11263. }
  11264. if (mPropDef != NULL)
  11265. thisValue = GetResult(true);
  11266. if (!thisValue.mType)
  11267. {
  11268. mModule->Fail("Identifier not found", qualifiedName->mLeft);
  11269. mModule->CheckTypeRefFixit(qualifiedName->mLeft);
  11270. mModule->CheckIdentifierFixit(qualifiedName->mLeft);
  11271. thisValue = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  11272. }
  11273. if (mResult)
  11274. CheckResultForReading(mResult);
  11275. mResult = BfTypedValue();
  11276. }
  11277. else if (auto identiferExpr = BfNodeDynCast<BfIdentifierNode>(target))
  11278. {
  11279. if (auto attrIdentifier = BfNodeDynCast<BfAttributedIdentifierNode>(target))
  11280. {
  11281. if (attrIdentifier->mIdentifier != NULL)
  11282. methodNodeSrc = attrIdentifier->mIdentifier;
  11283. attributeState.mCustomAttributes = mModule->GetCustomAttributes(attrIdentifier->mAttributes, attributeState.mTarget);
  11284. }
  11285. allowImplicitThis = true;
  11286. if (autoComplete != NULL)
  11287. autoComplete->CheckIdentifier(identiferExpr);
  11288. targetFunctionName = target->ToString();
  11289. if (targetFunctionName == "PrintF") // Just directly call that one
  11290. {
  11291. BfType* charType = mModule->GetPrimitiveType(BfTypeCode_Char8);
  11292. BfType* charPtrType = mModule->CreatePointerType(charType);
  11293. auto func = mModule->GetBuiltInFunc(BfBuiltInFuncType_PrintF);
  11294. SizedArray<BfIRValue, 4> irArgs;
  11295. for (BfExpression* arg : args)
  11296. {
  11297. BfTypedValue value;
  11298. if (arg != NULL)
  11299. value = mModule->CreateValueFromExpression(arg);
  11300. if (!value)
  11301. return;
  11302. auto typeInst = value.mType->ToTypeInstance();
  11303. if ((typeInst != NULL) && (typeInst->mTypeDef == mModule->mCompiler->mStringTypeDef))
  11304. value = mModule->Cast(arg, value, charPtrType);
  11305. if ((value.mType->IsFloat()) && (value.mType->mSize != 8)) // Always cast float to double
  11306. value = mModule->Cast(arg, value, mModule->GetPrimitiveType(BfTypeCode_Double));
  11307. irArgs.push_back(value.mValue);
  11308. }
  11309. if ((targetFunctionName != "PrintF") || (irArgs.size() > 0))
  11310. {
  11311. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCall(func, irArgs/*, targetFunctionName*/),
  11312. mModule->ResolveTypeDef(mModule->mSystem->mTypeInt32));
  11313. }
  11314. return;
  11315. }
  11316. }
  11317. else if (auto expr = BfNodeDynCast<BfExpression>(target))
  11318. {
  11319. auto innerInvocationResult = mModule->CreateValueFromExpression(expr);
  11320. if (!innerInvocationResult)
  11321. {
  11322. mModule->AssertErrorState();
  11323. innerInvocationResult = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  11324. }
  11325. if (innerInvocationResult.mType->IsVar())
  11326. {
  11327. mResult = innerInvocationResult;
  11328. return;
  11329. }
  11330. targetFunctionName = "Invoke";
  11331. if (innerInvocationResult.mType->IsTypeInstance())
  11332. {
  11333. auto invocationTypeInst = innerInvocationResult.mType->ToTypeInstance();
  11334. if (invocationTypeInst->mTypeDef->mIsDelegate)
  11335. {
  11336. thisValue = innerInvocationResult;
  11337. }
  11338. }
  11339. if (!thisValue)
  11340. {
  11341. mModule->Fail(StrFormat("Cannot perform invocation on type '%s'", mModule->TypeToString(innerInvocationResult.mType).c_str()), expr);
  11342. thisValue = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  11343. }
  11344. }
  11345. else
  11346. {
  11347. mModule->Fail("Invalid invocation target", target);
  11348. thisValue = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  11349. }
  11350. if ((wasCapturingMethodInfo) && (autoComplete->mMethodMatchInfo != NULL))
  11351. {
  11352. autoComplete->mIsCapturingMethodMatchInfo = true;
  11353. BF_ASSERT(autoComplete->mMethodMatchInfo != NULL);
  11354. }
  11355. SetAndRestoreValue<BfAttributeState*> prevAttributeState;
  11356. if (attributeState.mCustomAttributes != NULL)
  11357. prevAttributeState.Init(mModule->mAttributeState, &attributeState);
  11358. if ((targetFunctionName != "") && (targetFunctionName[targetFunctionName.length() - 1] == '!'))
  11359. {
  11360. targetFunctionName = targetFunctionName.Substring(0, targetFunctionName.length() - 1);
  11361. InjectMixin(methodNodeSrc, thisValue, allowImplicitThis, targetFunctionName, args, methodGenericArguments);
  11362. return;
  11363. }
  11364. //TODO: We removed this... Messed up with PrimStruct 'this' non-mut errors
  11365. // 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
  11366. /*if (thisValue)
  11367. {
  11368. if ((!thisValue.mType->IsGenericParam()) && (!thisValue.IsSplat()) && (!thisValue.mType->IsVar()))
  11369. thisValue = MakeCallableTarget(target, thisValue);
  11370. }*/
  11371. int methodCount = 0;
  11372. bool mayBeSkipCall = false;
  11373. if (thisValue.mType != NULL)
  11374. {
  11375. auto checkTypeInst = thisValue.mType->ToTypeInstance();
  11376. while (checkTypeInst != NULL)
  11377. {
  11378. checkTypeInst->mTypeDef->PopulateMemberSets();
  11379. BfMemberSetEntry* memberSetEntry;
  11380. if (checkTypeInst->mTypeDef->mMethodSet.TryGetWith(targetFunctionName, &memberSetEntry))
  11381. {
  11382. BfMethodDef* methodDef = (BfMethodDef*)memberSetEntry->mMemberDef;
  11383. while (methodDef != NULL)
  11384. {
  11385. if (methodDef->mIsSkipCall)
  11386. mayBeSkipCall = true;
  11387. methodDef = methodDef->mNextWithSameName;
  11388. }
  11389. }
  11390. checkTypeInst = checkTypeInst->mBaseType;
  11391. }
  11392. }
  11393. SizedArray<BfExpression*, 8> copiedArgs;
  11394. for (BfExpression* arg : args)
  11395. copiedArgs.push_back(arg);
  11396. BfSizedArray<BfExpression*> sizedCopiedArgs(copiedArgs);
  11397. BfResolvedArgs argValues(&sizedCopiedArgs);
  11398. if (mModule->mParentNodeEntry != NULL)
  11399. {
  11400. if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(mModule->mParentNodeEntry->mNode))
  11401. {
  11402. argValues.mOpenToken = invocationExpr->mOpenParen;
  11403. argValues.mCommas = &invocationExpr->mCommas;
  11404. argValues.mCloseToken = invocationExpr->mCloseParen;
  11405. }
  11406. }
  11407. BfResolveArgFlags resolveArgsFlags = (BfResolveArgFlags)(BfResolveArgFlag_DeferFixits | BfResolveArgFlag_AllowUnresolvedTypes);
  11408. resolveArgsFlags = (BfResolveArgFlags)(resolveArgsFlags | BfResolveArgFlag_DeferParamEval);
  11409. if (mayBeSkipCall)
  11410. resolveArgsFlags = (BfResolveArgFlags)(resolveArgsFlags | BfResolveArgFlag_DeferParamValues);
  11411. // static int sCallIdx = 0;
  11412. // sCallIdx++;
  11413. // int callIdx = sCallIdx;
  11414. // if (callIdx == 1557)
  11415. // {
  11416. // NOP;
  11417. // }
  11418. BfCheckedKind checkedKind = BfCheckedKind_NotSet;
  11419. if (attributeState.mCustomAttributes != NULL)
  11420. {
  11421. if (attributeState.mCustomAttributes->Contains(mModule->mCompiler->mCheckedAttributeTypeDef))
  11422. checkedKind = BfCheckedKind_Checked;
  11423. if (attributeState.mCustomAttributes->Contains(mModule->mCompiler->mUncheckedAttributeTypeDef))
  11424. checkedKind = BfCheckedKind_Unchecked;
  11425. }
  11426. SetAndRestoreValue<bool> prevUsedAsStatement(mUsedAsStatement, mUsedAsStatement || isCascade);
  11427. ResolveArgValues(argValues, resolveArgsFlags);
  11428. mResult = MatchMethod(methodNodeSrc, methodBoundExpr, thisValue, allowImplicitThis, bypassVirtual, targetFunctionName, argValues, methodGenericArguments, checkedKind);
  11429. argValues.HandleFixits(mModule);
  11430. if (isCascade)
  11431. {
  11432. if (outCascadeValue != NULL)
  11433. {
  11434. *outCascadeValue = thisValue;
  11435. }
  11436. else
  11437. {
  11438. mModule->Fail("Invalid use of cascade operator", cascadeOperatorToken);
  11439. }
  11440. }
  11441. }
  11442. void BfExprEvaluator::Visit(BfInvocationExpression* invocationExpr)
  11443. {
  11444. BfAutoParentNodeEntry autoParentNodeEntry(mModule, invocationExpr);
  11445. // We need to check for sized array constructor like "uint8[2](1, 2)"
  11446. if (BfNodeDynCastExact<BfIndexerExpression>(invocationExpr->mTarget) != NULL)
  11447. {
  11448. auto checkTarget = invocationExpr->mTarget;
  11449. while (auto indexerExpr = BfNodeDynCastExact<BfIndexerExpression>(checkTarget))
  11450. {
  11451. checkTarget = indexerExpr->mTarget;
  11452. }
  11453. SetAndRestoreValue<bool> prevIgnoreError(mModule->mIgnoreErrors, true);
  11454. auto resolvedType = mModule->ResolveTypeRef(checkTarget, NULL, BfPopulateType_Identity);
  11455. prevIgnoreError.Restore();
  11456. if (resolvedType != NULL)
  11457. {
  11458. BfType* curType = resolvedType;
  11459. auto checkTarget = invocationExpr->mTarget;
  11460. while (auto indexerExpr = BfNodeDynCastExact<BfIndexerExpression>(checkTarget))
  11461. {
  11462. checkTarget = indexerExpr->mTarget;
  11463. if (indexerExpr->mCommas.size() != 0)
  11464. 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]);
  11465. int arrSize = 0;
  11466. if (indexerExpr->mArguments.size() != 0)
  11467. {
  11468. BfConstResolver constResolver(mModule);
  11469. auto arg = indexerExpr->mArguments[0];
  11470. if (arg != NULL)
  11471. constResolver.Resolve(arg);
  11472. if (constResolver.mResult.mValue.IsConst())
  11473. {
  11474. auto constant = mModule->mBfIRBuilder->GetConstant(constResolver.mResult.mValue);
  11475. if ((mModule->mBfIRBuilder->IsInt(constant->mTypeCode)) && (constant->mInt64 >= 0))
  11476. {
  11477. arrSize = constant->mInt32;
  11478. }
  11479. else
  11480. mModule->Fail("Non-negative integer expected", indexerExpr->mArguments[0]);
  11481. }
  11482. }
  11483. else
  11484. arrSize = invocationExpr->mArguments.size();
  11485. curType = mModule->CreateSizedArrayType(curType, arrSize);
  11486. }
  11487. InitializedSizedArray((BfSizedArrayType*)curType, invocationExpr->mOpenParen, invocationExpr->mArguments, invocationExpr->mCommas, invocationExpr->mCloseParen, NULL);
  11488. return;
  11489. }
  11490. }
  11491. auto autoComplete = GetAutoComplete();
  11492. auto wasCapturingMethodInfo = (autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo);
  11493. if (autoComplete != NULL)
  11494. autoComplete->CheckInvocation(invocationExpr, invocationExpr->mOpenParen, invocationExpr->mCloseParen, invocationExpr->mCommas);
  11495. mModule->UpdateExprSrcPos(invocationExpr);
  11496. BfSizedArray<ASTREF(BfTypeReference*)>* methodGenericArguments = NULL;
  11497. if (invocationExpr->mGenericArgs != NULL)
  11498. methodGenericArguments = &invocationExpr->mGenericArgs->mGenericArgs;
  11499. SizedArray<BfExpression*, 8> copiedArgs;
  11500. for (BfExpression* arg : invocationExpr->mArguments)
  11501. copiedArgs.push_back(arg);
  11502. BfTypedValue cascadeValue;
  11503. DoInvocation(invocationExpr->mTarget, invocationExpr, copiedArgs, methodGenericArguments, &cascadeValue);
  11504. if (autoComplete != NULL)
  11505. {
  11506. if ((wasCapturingMethodInfo) && (!autoComplete->mIsCapturingMethodMatchInfo))
  11507. {
  11508. if (autoComplete->mMethodMatchInfo != NULL)
  11509. autoComplete->mIsCapturingMethodMatchInfo = true;
  11510. else
  11511. autoComplete->mIsCapturingMethodMatchInfo = false;
  11512. //BF_ASSERT(autoComplete->mMethodMatchInfo != NULL);
  11513. }
  11514. else
  11515. autoComplete->mIsCapturingMethodMatchInfo = false;
  11516. }
  11517. /// Previous check for discard
  11518. if (cascadeValue)
  11519. mResult = cascadeValue;
  11520. }
  11521. BfMethodDef* BfExprEvaluator::GetPropertyMethodDef(BfPropertyDef* propDef, BfMethodType methodType, BfCheckedKind checkedKind)
  11522. {
  11523. BfMethodDef* matchedMethod = NULL;
  11524. BfMethodDef* backupMethod = NULL;
  11525. for (auto methodDef : propDef->mMethods)
  11526. {
  11527. if (methodDef->mMethodType != methodType)
  11528. continue;
  11529. if (methodDef->mCheckedKind == checkedKind)
  11530. {
  11531. matchedMethod = methodDef;
  11532. break;
  11533. }
  11534. if ((checkedKind == BfCheckedKind_NotSet) && (methodDef->mCheckedKind == mModule->GetDefaultCheckedKind()))
  11535. matchedMethod = methodDef;
  11536. else
  11537. backupMethod = methodDef;
  11538. }
  11539. if (matchedMethod == NULL)
  11540. matchedMethod = backupMethod;
  11541. return matchedMethod;
  11542. }
  11543. BfModuleMethodInstance BfExprEvaluator::GetPropertyMethodInstance(BfMethodDef* methodDef)
  11544. {
  11545. if (mPropDefBypassVirtual)
  11546. {
  11547. if (mPropTarget.mType->IsInterface())
  11548. {
  11549. auto curTypeInst = mPropTarget.mType->ToTypeInstance();
  11550. if (mModule->TypeIsSubTypeOf(mModule->mCurTypeInstance, curTypeInst))
  11551. {
  11552. // This is an explicit call to a default static interface method. We pull the methodDef into our own concrete type.
  11553. mPropTarget = mModule->GetThis();
  11554. return mModule->GetMethodInstance(mModule->mCurTypeInstance, methodDef, BfTypeVector(), BfGetMethodInstanceFlag_ForeignMethodDef, curTypeInst);
  11555. }
  11556. else
  11557. {
  11558. mModule->Fail("Property is not implemented by this type", mPropSrc);
  11559. return BfModuleMethodInstance();
  11560. }
  11561. }
  11562. else
  11563. {
  11564. auto propTypeInst = mPropTarget.mType->ToTypeInstance();
  11565. auto rawMethodInstance = mModule->GetRawMethodInstance(propTypeInst, methodDef);
  11566. auto useTypeInst = mOrigPropTarget.mType->ToTypeInstance();
  11567. auto virtualMethod = (BfMethodInstance*)useTypeInst->mVirtualMethodTable[rawMethodInstance->mVirtualTableIdx].mImplementingMethod;
  11568. return mModule->ReferenceExternalMethodInstance(virtualMethod);
  11569. }
  11570. }
  11571. if ((mOrigPropTarget) && (mOrigPropTarget.mType != mPropTarget.mType) &&
  11572. ((!mOrigPropTarget.mType->IsGenericParam()) && (mPropTarget.mType->IsInterface())))
  11573. {
  11574. auto checkType = mOrigPropTarget.mType;
  11575. if (checkType->IsPointer())
  11576. checkType = ((BfPointerType*)checkType)->mElementType;
  11577. if (checkType->IsWrappableType())
  11578. checkType = mModule->GetWrappedStructType(checkType);
  11579. if ((checkType != NULL) && (checkType->IsTypeInstance()))
  11580. {
  11581. auto activeTypeDef = mModule->GetActiveTypeDef();
  11582. BfTypeInterfaceEntry* bestIFaceEntry = NULL;
  11583. bool checkedUnderlying = false;
  11584. auto checkTypeInst = checkType->ToTypeInstance();
  11585. while (checkTypeInst != NULL)
  11586. {
  11587. mModule->PopulateType(checkTypeInst, BfPopulateType_DataAndMethods);
  11588. for (auto& iface : checkTypeInst->mInterfaces)
  11589. {
  11590. if (!checkTypeInst->IsTypeMemberAccessible(iface.mDeclaringType, activeTypeDef))
  11591. continue;
  11592. if (iface.mInterfaceType == mPropTarget.mType)
  11593. {
  11594. if (bestIFaceEntry == NULL)
  11595. {
  11596. bestIFaceEntry = &iface;
  11597. continue;
  11598. }
  11599. bool isBetter;
  11600. bool isWorse;
  11601. mModule->CompareDeclTypes(iface.mDeclaringType, bestIFaceEntry->mDeclaringType, isBetter, isWorse);
  11602. if (isBetter == isWorse)
  11603. {
  11604. // Failed
  11605. }
  11606. else
  11607. {
  11608. if (isBetter)
  11609. bestIFaceEntry = &iface;
  11610. }
  11611. }
  11612. }
  11613. if (bestIFaceEntry != NULL)
  11614. break;
  11615. checkTypeInst = checkTypeInst->mBaseType;
  11616. if (checkTypeInst == NULL)
  11617. {
  11618. if (!checkedUnderlying)
  11619. {
  11620. checkedUnderlying = true;
  11621. if (checkType->HasWrappedRepresentation())
  11622. {
  11623. auto underlyingType = checkType->GetUnderlyingType();
  11624. if (underlyingType != NULL)
  11625. checkTypeInst = mModule->GetWrappedStructType(underlyingType);
  11626. }
  11627. }
  11628. }
  11629. }
  11630. if (bestIFaceEntry != NULL)
  11631. {
  11632. auto ifaceMethodEntry = checkTypeInst->mInterfaceMethodTable[bestIFaceEntry->mStartInterfaceTableIdx + methodDef->mIdx];
  11633. BfMethodInstance* bestMethodInstance = ifaceMethodEntry.mMethodRef;
  11634. if (bestMethodInstance != NULL)
  11635. {
  11636. mPropTarget = mOrigPropTarget;
  11637. mPropTarget.mType = checkTypeInst;
  11638. return mModule->GetMethodInstanceAtIdx(ifaceMethodEntry.mMethodRef.mTypeInstance, ifaceMethodEntry.mMethodRef.mMethodNum);
  11639. }
  11640. }
  11641. }
  11642. mModule->AssertErrorState();
  11643. return BfModuleMethodInstance();
  11644. }
  11645. auto propTypeInst = mPropTarget.mType->ToTypeInstance();
  11646. if (propTypeInst == NULL)
  11647. {
  11648. propTypeInst = mModule->GetWrappedStructType(mPropTarget.mType);
  11649. }
  11650. if (propTypeInst == NULL)
  11651. {
  11652. mModule->Fail("INTERNAL ERROR: Invalid property target", mPropSrc);
  11653. return BfModuleMethodInstance();
  11654. }
  11655. return mModule->GetMethodInstance(propTypeInst, methodDef, BfTypeVector(), mPropGetMethodFlags);
  11656. }
  11657. void BfExprEvaluator::CheckPropFail(BfMethodDef* propMethodDef, BfMethodInstance* methodInstance)
  11658. {
  11659. auto propTypeInst = mPropTarget.mType->ToTypeInstance();
  11660. // If mExplicitInterface is null then we are implicitly calling through an interface
  11661. if ((propTypeInst != NULL) && (methodInstance->GetExplicitInterface() == NULL) && (!mModule->CheckAccessMemberProtection(propMethodDef->mProtection, propTypeInst)))
  11662. mModule->Fail(StrFormat("'%s' is inaccessible due to its protection level", mModule->MethodToString(methodInstance).c_str()), mPropSrc);
  11663. else if (mPropCheckedKind != methodInstance->mMethodDef->mCheckedKind)
  11664. {
  11665. bool passes = true;
  11666. if (mPropCheckedKind != BfCheckedKind_NotSet)
  11667. {
  11668. passes = false;
  11669. }
  11670. else
  11671. {
  11672. auto defaultCheckedKind = mModule->GetDefaultCheckedKind();
  11673. if (defaultCheckedKind != methodInstance->mMethodDef->mCheckedKind)
  11674. passes = false;
  11675. }
  11676. if (!passes)
  11677. {
  11678. 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);
  11679. if (error != NULL)
  11680. {
  11681. if ((error != NULL) && (methodInstance->mMethodDef->mMethodDeclaration != NULL))
  11682. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
  11683. }
  11684. }
  11685. }
  11686. }
  11687. BfTypedValue BfExprEvaluator::GetResult(bool clearResult, bool resolveGenericType)
  11688. {
  11689. if ((!mResult) && (mPropDef != NULL))
  11690. {
  11691. BfMethodDef* matchedMethod = GetPropertyMethodDef(mPropDef, BfMethodType_PropertyGetter, mPropCheckedKind);
  11692. if (matchedMethod == NULL)
  11693. {
  11694. mModule->Fail("Property has no getter", mPropSrc);
  11695. return mResult;
  11696. }
  11697. auto methodInstance = GetPropertyMethodInstance(matchedMethod);
  11698. if (methodInstance.mMethodInstance == NULL)
  11699. return mResult;
  11700. if (!mModule->mBfIRBuilder->mIgnoreWrites)
  11701. {
  11702. BF_ASSERT(!methodInstance.mFunc.IsFake());
  11703. }
  11704. if (mPropSrc != NULL)
  11705. mModule->UpdateExprSrcPos(mPropSrc);
  11706. CheckPropFail(matchedMethod, methodInstance.mMethodInstance);
  11707. PerformCallChecks(methodInstance.mMethodInstance, mPropSrc);
  11708. if (methodInstance.mMethodInstance->IsSkipCall())
  11709. {
  11710. mResult = mModule->GetDefaultTypedValue(methodInstance.mMethodInstance->mReturnType);
  11711. }
  11712. else
  11713. {
  11714. SizedArray<BfIRValue, 4> args;
  11715. if (!matchedMethod->mIsStatic)
  11716. {
  11717. if ((mPropDefBypassVirtual) && (mPropTarget.mType != methodInstance.mMethodInstance->GetOwner()))
  11718. mPropTarget = mModule->Cast(mPropSrc, mOrigPropTarget, methodInstance.mMethodInstance->GetOwner());
  11719. mModule->EmitObjectAccessCheck(mPropTarget);
  11720. PushThis(mPropSrc, mPropTarget, methodInstance.mMethodInstance, args);
  11721. }
  11722. bool failed = false;
  11723. for (int paramIdx = 0; paramIdx < (int)mIndexerValues.size(); paramIdx++)
  11724. {
  11725. auto val = mModule->Cast(mPropSrc, mIndexerValues[paramIdx].mTypedValue, methodInstance.mMethodInstance->GetParamType(paramIdx));
  11726. if (!val)
  11727. failed = true;
  11728. else
  11729. PushArg(val, args);
  11730. }
  11731. if (mPropDefBypassVirtual)
  11732. {
  11733. auto methodDef = methodInstance.mMethodInstance->mMethodDef;
  11734. if ((methodDef->mIsAbstract) && (mPropDefBypassVirtual))
  11735. {
  11736. mModule->Fail(StrFormat("Abstract base property method '%s' cannot be invoked", mModule->MethodToString(methodInstance.mMethodInstance).c_str()), mPropSrc);
  11737. }
  11738. }
  11739. if (failed)
  11740. mResult = mModule->GetDefaultTypedValue(methodInstance.mMethodInstance->mReturnType);
  11741. else
  11742. mResult = CreateCall(methodInstance.mMethodInstance, methodInstance.mFunc, mPropDefBypassVirtual, args);
  11743. if (mResult.mType != NULL)
  11744. {
  11745. if ((mResult.mType->IsVar()) && (mModule->mCompiler->mIsResolveOnly))
  11746. mModule->Fail("Property type reference failed to resolve", mPropSrc);
  11747. BF_ASSERT(!mResult.mType->IsRef());
  11748. }
  11749. }
  11750. mPropDef = NULL;
  11751. mPropDefBypassVirtual = false;
  11752. mIndexerValues.clear();
  11753. mResultLocalVar = NULL;
  11754. }
  11755. if (resolveGenericType)
  11756. ResolveGenericType();
  11757. BfTypedValue result = mResult;
  11758. if (clearResult)
  11759. mResult = BfTypedValue();
  11760. return result;
  11761. }
  11762. void BfExprEvaluator::CheckResultForReading(BfTypedValue& typedValue)
  11763. {
  11764. if (mModule->mCurMethodState == NULL)
  11765. return;
  11766. if ((mModule->mCurMethodState->mTempKind != BfMethodState::TempKind_None) || (mModule->mCurMethodState->mAllowUinitReads))
  11767. return;
  11768. if ((mModule->mCurTypeInstance->mResolvingVarField) || (mModule->mCurTypeInstance->mResolvingConstField))
  11769. return;
  11770. if ((typedValue) && (typedValue.IsAddr()))
  11771. {
  11772. if ((mResultLocalVar != NULL) && (mResultLocalVarRefNode != NULL))
  11773. {
  11774. SetAndRestoreValue<bool> prevIgnoreError(mModule->mIgnoreErrors);
  11775. if ((mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mCapturing))
  11776. {
  11777. // These errors can only be detected during capture time, so we don't ignore them on this pass
  11778. mModule->mIgnoreErrors = false;
  11779. }
  11780. int fieldIdx = mResultLocalVarField - 1;
  11781. auto localVar = mResultLocalVar;
  11782. if (localVar->mCompositeCount > 0)
  11783. {
  11784. mModule->Fail(StrFormat("Cannot read from composite '%s', it can only be used in an argument list", localVar->mName.c_str()), mResultLocalVarRefNode);
  11785. typedValue = BfTypedValue();
  11786. return;
  11787. }
  11788. if (!localVar->mIsAssigned)
  11789. {
  11790. mModule->TryLocalVariableInit(localVar);
  11791. }
  11792. if (!localVar->mIsAssigned)
  11793. {
  11794. auto methodStateForLocal = mModule->mCurMethodState->GetMethodStateForLocal(localVar);
  11795. bool isAssigned = false;
  11796. int64 undefinedFieldFlags = localVar->mUnassignedFieldFlags;
  11797. auto deferredLocalAssignData = methodStateForLocal->mDeferredLocalAssignData;
  11798. while ((deferredLocalAssignData != NULL) && (deferredLocalAssignData->mIsChained))
  11799. deferredLocalAssignData = deferredLocalAssignData->mChainedAssignData;
  11800. if (deferredLocalAssignData != NULL)
  11801. {
  11802. for (auto& assignedVar : deferredLocalAssignData->mAssignedLocals)
  11803. {
  11804. auto assignedLocal = assignedVar.mLocalVar;
  11805. if (assignedLocal == localVar)
  11806. {
  11807. int assignedFieldIdx = (assignedVar.mLocalVarField) - 1;
  11808. if (assignedFieldIdx >= 0)
  11809. undefinedFieldFlags &= ~((int64)1 << assignedFieldIdx);
  11810. else
  11811. undefinedFieldFlags = 0;
  11812. }
  11813. }
  11814. }
  11815. if (fieldIdx == -1)
  11816. {
  11817. if (undefinedFieldFlags == 0)
  11818. isAssigned = true;
  11819. }
  11820. else
  11821. {
  11822. isAssigned = true;
  11823. for (int i = 0; i < mResultLocalVarFieldCount; i++)
  11824. if ((undefinedFieldFlags & (1LL << (fieldIdx + i))) != 0)
  11825. isAssigned = false;
  11826. }
  11827. if (!isAssigned)
  11828. {
  11829. if ((localVar->mIsThis) && (fieldIdx != -1))
  11830. {
  11831. // When we have initializers for fields, they won't all be processed in the autocomplte case
  11832. if (!mModule->mCompiler->IsAutocomplete())
  11833. {
  11834. auto bfError = mModule->Fail(StrFormat("Use of possibly unassigned field '%s'", mResultLocalVarRefNode->ToString().c_str()), mResultLocalVarRefNode, true);
  11835. }
  11836. }
  11837. else
  11838. {
  11839. mModule->Fail(StrFormat("Use of unassigned local variable '%s'", localVar->mName.c_str()), mResultLocalVarRefNode);
  11840. }
  11841. }
  11842. }
  11843. localVar->mReadFromId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++;
  11844. }
  11845. }
  11846. }
  11847. void BfExprEvaluator::FinishExpressionResult()
  11848. {
  11849. CheckResultForReading(mResult);
  11850. mResultLocalVar = NULL;
  11851. }
  11852. bool BfExprEvaluator::CheckAllowValue(const BfTypedValue& typedValue, BfAstNode* refNode)
  11853. {
  11854. return true;
  11855. }
  11856. void BfExprEvaluator::MarkResultUsed()
  11857. {
  11858. if (mResultLocalVar != NULL)
  11859. {
  11860. mResultLocalVar->mReadFromId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++;
  11861. }
  11862. }
  11863. void BfExprEvaluator::MarkResultAssigned()
  11864. {
  11865. if (mResultLocalVar != NULL)
  11866. {
  11867. //int localIdx = mResultLocalVarIdx;
  11868. //if (localIdx == 0x7FFF)
  11869. //return;
  11870. auto localVar = mResultLocalVar;
  11871. int fieldIdx = mResultLocalVarField - 1;
  11872. int count = mResultLocalVarFieldCount;
  11873. if (fieldIdx == -1)
  11874. count = 1;
  11875. for (int i = 0; i < count; i++)
  11876. mModule->mCurMethodState->GetMethodStateForLocal(localVar)->LocalDefined(localVar, fieldIdx + i);
  11877. //if (localIdx != 0x7FFF)
  11878. {
  11879. if (localVar->mCompositeCount > 0)
  11880. {
  11881. mModule->Fail(StrFormat("Cannot write to composite '%s', it can only be used in an argument list", localVar->mName.c_str()), mResultLocalVarRefNode);
  11882. }
  11883. }
  11884. }
  11885. }
  11886. void BfExprEvaluator::MakeResultAsValue()
  11887. {
  11888. // Expressions like parens will turn a variable reference into a simple value
  11889. mResultLocalVar = NULL;
  11890. }
  11891. bool BfExprEvaluator::CheckModifyResult(BfTypedValue typedVal, BfAstNode* refNode, const char* modifyType, bool onlyNeedsMut)
  11892. {
  11893. BfLocalVariable* localVar = NULL;
  11894. bool isCapturedLocal = false;
  11895. if (mResultLocalVar != NULL)
  11896. {
  11897. localVar = mResultLocalVar;
  11898. localVar->mWrittenToId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++;
  11899. }
  11900. else if (typedVal.IsThis())
  11901. {
  11902. localVar = mModule->GetThisVariable();
  11903. }
  11904. else if (typedVal.IsSplat())
  11905. {
  11906. for (auto checkLocal : mModule->mCurMethodState->mLocals)
  11907. {
  11908. if (checkLocal->mAddr == typedVal.mValue)
  11909. {
  11910. localVar = checkLocal;
  11911. break;
  11912. }
  11913. }
  11914. }
  11915. else if (typedVal.mValue.IsArg())
  11916. {
  11917. auto methodState = mModule->mCurMethodState->GetNonCaptureState();
  11918. localVar = methodState->mLocals[typedVal.mValue.mId];
  11919. }
  11920. if ((typedVal.mKind == BfTypedValueKind_MutableValue) && (onlyNeedsMut))
  11921. {
  11922. return true;
  11923. }
  11924. if (localVar != NULL)
  11925. {
  11926. if (((!typedVal.IsAddr()) && (!typedVal.mType->IsValuelessType())) ||
  11927. (typedVal.IsReadOnly()))
  11928. {
  11929. BfError* error = NULL;
  11930. if (localVar->mIsThis)
  11931. {
  11932. bool isClosure = false;
  11933. BfTypeInstance* checkTypeInst = localVar->mResolvedType->ToTypeInstance();
  11934. int fieldIdx = mResultLocalVarField - 1;
  11935. if ((!isCapturedLocal) && (mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mClosureType != NULL))
  11936. {
  11937. isClosure = true;
  11938. auto closureThis = mModule->mCurMethodState->mClosureState->mClosureType;
  11939. closureThis = checkTypeInst->mFieldInstances[0].mResolvedType->ToTypeInstance();
  11940. if (fieldIdx >= -1)
  11941. {
  11942. checkTypeInst = closureThis;
  11943. }
  11944. else
  11945. {
  11946. fieldIdx = -fieldIdx - 2;
  11947. isCapturedLocal = true;
  11948. }
  11949. }
  11950. if (fieldIdx < 0)
  11951. {
  11952. if (isClosure)
  11953. {
  11954. if (!mModule->mCurMethodState->mClosureState->mDeclaringMethodIsMutating)
  11955. error = mModule->Fail(StrFormat("Cannot %s 'this' within struct lambda. Consider adding 'mut' specifier to this method.", modifyType), refNode);
  11956. else
  11957. error = mModule->Fail(StrFormat("Cannot %s 'this' within struct lambda. Consider adding by-reference capture specifier [&] to lambda.", modifyType), refNode);
  11958. }
  11959. else
  11960. {
  11961. error = mModule->Fail(StrFormat("Cannot %s 'this' within struct method '%s'. Consider adding 'mut' specifier to this method.", modifyType,
  11962. mModule->MethodToString(mModule->mCurMethodInstance).c_str()), refNode);
  11963. }
  11964. return false;
  11965. }
  11966. else
  11967. {
  11968. while (checkTypeInst != NULL)
  11969. {
  11970. for (auto& checkFieldInstance : checkTypeInst->mFieldInstances)
  11971. {
  11972. if (checkFieldInstance.mMergedDataIdx == fieldIdx)
  11973. {
  11974. if (isCapturedLocal)
  11975. {
  11976. error = mModule->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,
  11977. checkFieldInstance.GetFieldDef()->mName.c_str()), refNode);
  11978. }
  11979. else if (isClosure)
  11980. {
  11981. if (!mModule->mCurMethodState->mClosureState->mDeclaringMethodIsMutating)
  11982. error = mModule->Fail(StrFormat("Cannot %s field '%s.%s' within struct lambda. Consider adding 'mut' specifier to this method.", modifyType,
  11983. mModule->TypeToString(checkFieldInstance.mOwner).c_str(), checkFieldInstance.GetFieldDef()->mName.c_str()), refNode);
  11984. else
  11985. error = mModule->Fail(StrFormat("Cannot %s field '%s.%s' within struct lambda. Consider adding by-reference capture specifier [&] to lambda.", modifyType,
  11986. mModule->TypeToString(checkFieldInstance.mOwner).c_str(), checkFieldInstance.GetFieldDef()->mName.c_str()), refNode);
  11987. }
  11988. else
  11989. {
  11990. error = mModule->Fail(StrFormat("Cannot %s field '%s.%s' within struct method '%s'. Consider adding 'mut' specifier to this method.", modifyType,
  11991. mModule->TypeToString(checkFieldInstance.mOwner).c_str(), checkFieldInstance.GetFieldDef()->mName.c_str(),
  11992. mModule->MethodToString(mModule->mCurMethodInstance).c_str()), refNode);
  11993. }
  11994. return false;
  11995. }
  11996. }
  11997. checkTypeInst = checkTypeInst->mBaseType;
  11998. }
  11999. }
  12000. }
  12001. else if (localVar->IsParam())
  12002. {
  12003. if (!mModule->mCurMethodInstance->IsMixin())
  12004. {
  12005. if ((localVar->mResolvedType->IsGenericParam()) && (onlyNeedsMut))
  12006. error = mModule->Fail(StrFormat("Cannot %s parameter '%s'. Consider adding 'mut' or 'ref' specifier to parameter or copying to a local variable.", modifyType,
  12007. localVar->mName.c_str(), mModule->MethodToString(mModule->mCurMethodInstance).c_str()), refNode);
  12008. else
  12009. error = mModule->Fail(StrFormat("Cannot %s parameter '%s'. Consider adding 'ref' specifier to parameter or copying to a local variable.", modifyType,
  12010. localVar->mName.c_str(), mModule->MethodToString(mModule->mCurMethodInstance).c_str()), refNode);
  12011. return false;
  12012. }
  12013. }
  12014. else
  12015. {
  12016. error = mModule->Fail(StrFormat("Cannot %s read-only local variable '%s'.", modifyType,
  12017. localVar->mName.c_str()), refNode);
  12018. return false;
  12019. }
  12020. }
  12021. else
  12022. {
  12023. // When we are capturing, we need to note that we require capturing by reference here
  12024. localVar->mWrittenToId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++;
  12025. }
  12026. }
  12027. return mModule->CheckModifyValue(typedVal, refNode, modifyType);
  12028. }
  12029. void BfExprEvaluator::Visit(BfConditionalExpression* condExpr)
  12030. {
  12031. static int sCallCount = 0;
  12032. sCallCount++;
  12033. auto condResult = mModule->CreateValueFromExpression(condExpr->mConditionExpression, mModule->GetPrimitiveType(BfTypeCode_Boolean));
  12034. if (!condResult)
  12035. return;
  12036. if (condExpr->mTrueExpression == NULL)
  12037. {
  12038. mModule->AssertErrorState();
  12039. return;
  12040. }
  12041. if (condExpr->mFalseExpression == NULL)
  12042. {
  12043. mModule->CreateValueFromExpression(condExpr->mTrueExpression, mExpectingType, BfEvalExprFlags_NoCast);
  12044. mModule->AssertErrorState();
  12045. return;
  12046. }
  12047. bool isConstBranch = false;
  12048. bool constResult = false;
  12049. bool constResultUndef = false;
  12050. if (condResult.mValue.IsConst())
  12051. {
  12052. auto constValue = mModule->mBfIRBuilder->GetConstant(condResult.mValue);
  12053. if (constValue->mTypeCode == BfTypeCode_Boolean)
  12054. {
  12055. isConstBranch = true;
  12056. constResult = constValue->mBool;
  12057. }
  12058. else if (constValue->mConstType == BfConstType_Undef)
  12059. {
  12060. isConstBranch = true;
  12061. constResultUndef = true;
  12062. }
  12063. }
  12064. if (isConstBranch)
  12065. {
  12066. BfExpression* actualExpr = (constResult) ? condExpr->mTrueExpression : condExpr->mFalseExpression;
  12067. BfExpression* ignoredExpr = (constResult) ? condExpr->mFalseExpression : condExpr->mTrueExpression;
  12068. BfTypedValue actualValue = mModule->CreateValueFromExpression(actualExpr, mExpectingType, BfEvalExprFlags_NoCast);
  12069. BfTypedValue ignoredValue;
  12070. //
  12071. {
  12072. auto curBlock = mModule->mBfIRBuilder->GetInsertBlock();
  12073. SetAndRestoreValue<bool> ignoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
  12074. ignoredValue = mModule->CreateValueFromExpression(ignoredExpr, mExpectingType, BfEvalExprFlags_NoCast);
  12075. mModule->mBfIRBuilder->SetInsertPoint(curBlock);
  12076. }
  12077. if (!actualValue)
  12078. return;
  12079. if ((ignoredValue) && (ignoredValue.mType != actualValue.mType))
  12080. {
  12081. // Cast to more specific 'ignored' type if applicable
  12082. if (mModule->CanImplicitlyCast(actualValue, ignoredValue.mType))
  12083. {
  12084. actualValue = mModule->Cast(actualExpr, actualValue, ignoredValue.mType);
  12085. }
  12086. else if (!mModule->CanImplicitlyCast(ignoredValue, actualValue.mType))
  12087. {
  12088. mModule->Fail(StrFormat("Type of conditional expression cannot be determined because there is no implicit conversion between '%s' and '%s'",
  12089. mModule->TypeToString(actualValue.mType).c_str(), mModule->TypeToString(ignoredValue.mType).c_str()), condExpr);
  12090. }
  12091. }
  12092. mResult = actualValue;
  12093. if (constResultUndef)
  12094. mResult = mModule->GetDefaultTypedValue(mResult.mType, false, BfDefaultValueKind_Undef);
  12095. return;
  12096. }
  12097. auto trueBB = mModule->mBfIRBuilder->CreateBlock("cond.then");
  12098. auto falseBB = mModule->mBfIRBuilder->CreateBlock("cond.else");
  12099. auto endBB = mModule->mBfIRBuilder->CreateBlock("cond.end");
  12100. auto contBB = mModule->mBfIRBuilder->CreateBlock("cond.cont");
  12101. mModule->mBfIRBuilder->CreateCondBr(condResult.mValue, trueBB, falseBB);
  12102. mModule->AddBasicBlock(trueBB);
  12103. auto trueValue = mModule->CreateValueFromExpression(condExpr->mTrueExpression, mExpectingType, (BfEvalExprFlags)(BfEvalExprFlags_NoCast | BfEvalExprFlags_CreateConditionalScope));
  12104. if ((mExpectingType != NULL) && (trueValue) && (trueValue.mType != mExpectingType))
  12105. {
  12106. // In some cases like typed primitives - we CAN individually cast each value which it's a constant still, but not after the merging
  12107. // IE: Color c = isOver ? 0xFF000000 : 0xFFFFFFFF;
  12108. // Otherwise the resulting value would just be 'int' which cannot implicitly convert to Color, but each of those ints can be
  12109. // a uint32 if converted separately
  12110. auto checkTrueValue = mModule->Cast(condExpr->mTrueExpression, trueValue, mExpectingType, BfCastFlags_SilentFail);
  12111. if (checkTrueValue)
  12112. trueValue = checkTrueValue;
  12113. }
  12114. auto trueBlockPos = mModule->mBfIRBuilder->GetInsertBlock();
  12115. mModule->AddBasicBlock(falseBB);
  12116. auto falseValue = mModule->CreateValueFromExpression(condExpr->mFalseExpression, mExpectingType, (BfEvalExprFlags)(BfEvalExprFlags_NoCast | BfEvalExprFlags_CreateConditionalScope));
  12117. auto falseBlockPos = mModule->mBfIRBuilder->GetInsertBlock();
  12118. if ((mExpectingType != NULL) && (falseValue) && (falseValue.mType != mExpectingType))
  12119. {
  12120. auto checkFalseValue = mModule->Cast(condExpr->mFalseExpression, falseValue, mExpectingType, BfCastFlags_SilentFail);
  12121. if (checkFalseValue)
  12122. falseValue = checkFalseValue;
  12123. }
  12124. bool isValid = trueValue && falseValue;
  12125. if (isValid)
  12126. {
  12127. BfTypedValue falseToTrue;
  12128. {
  12129. SetAndRestoreValue<bool> prevIgnoreError(mModule->mIgnoreErrors, true);
  12130. mModule->mBfIRBuilder->SetInsertPoint(falseBlockPos);
  12131. falseToTrue = mModule->Cast(condExpr->mFalseExpression, falseValue, trueValue.mType);
  12132. }
  12133. if (falseToTrue)
  12134. {
  12135. falseValue = falseToTrue;
  12136. }
  12137. else
  12138. {
  12139. BfTypedValue trueToFalse;
  12140. {
  12141. SetAndRestoreValue<bool> prevIgnoreError(mModule->mIgnoreErrors, true);
  12142. mModule->mBfIRBuilder->SetInsertPoint(trueBlockPos);
  12143. trueToFalse = mModule->Cast(condExpr->mTrueExpression, trueValue, falseValue.mType);
  12144. }
  12145. if (!trueToFalse)
  12146. {
  12147. mModule->Fail(StrFormat("Type of conditional expression cannot be determined because there is no implicit conversion between '%s' and '%s'",
  12148. mModule->TypeToString(trueValue.mType).c_str(), mModule->TypeToString(falseValue.mType).c_str()), condExpr);
  12149. //return;
  12150. isValid = false;
  12151. }
  12152. else
  12153. trueValue = trueToFalse;
  12154. }
  12155. }
  12156. mModule->mBfIRBuilder->SetInsertPoint(trueBlockPos);
  12157. if (isValid)
  12158. trueValue = mModule->LoadValue(trueValue);
  12159. mModule->mBfIRBuilder->CreateBr(endBB);
  12160. mModule->mBfIRBuilder->SetInsertPoint(falseBlockPos);
  12161. if (isValid)
  12162. falseValue = mModule->LoadValue(falseValue);
  12163. mModule->mBfIRBuilder->CreateBr(endBB);
  12164. mModule->AddBasicBlock(endBB, false);
  12165. if (!isValid)
  12166. return;
  12167. mModule->mBfIRBuilder->SetInsertPoint(endBB);
  12168. BfIRValue phi;
  12169. if (!trueValue.mType->IsValuelessType())
  12170. {
  12171. phi = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(trueValue.mType), 2);
  12172. mModule->mBfIRBuilder->AddPhiIncoming(phi, trueValue.mValue, trueBlockPos);
  12173. mModule->mBfIRBuilder->AddPhiIncoming(phi, falseValue.mValue, falseBlockPos);
  12174. }
  12175. mModule->mBfIRBuilder->CreateBr(contBB);
  12176. mModule->AddBasicBlock(contBB);
  12177. mResult = BfTypedValue(phi, trueValue.mType);
  12178. }
  12179. void BfExprEvaluator::PopulateDeferrredTupleAssignData(BfTupleExpression* tupleExpr, DeferredTupleAssignData& deferredTupleAssignData)
  12180. {
  12181. BfTypeVector fieldTypes;
  12182. Array<String> fieldNames;
  12183. // We need to evaluate each LHS tuple component in a separate BfExprEvaluator because each one
  12184. // could be a property and the 'mPropDef' target info is tied to a single evaluator
  12185. for (int valueIdx = 0; valueIdx < (int)tupleExpr->mValues.size(); valueIdx++)
  12186. {
  12187. DeferredTupleAssignData::Entry entry;
  12188. entry.mExprEvaluator = NULL;
  12189. entry.mInnerTuple = NULL;
  12190. BfExpression* valueExpr = tupleExpr->mValues[valueIdx];
  12191. entry.mExpr = valueExpr;
  12192. BfType* fieldType = NULL;
  12193. BfType* resultType = NULL;
  12194. if (auto innerTupleExpr = BfNodeDynCast<BfTupleExpression>(valueExpr))
  12195. {
  12196. entry.mInnerTuple = new DeferredTupleAssignData();
  12197. PopulateDeferrredTupleAssignData(innerTupleExpr, *entry.mInnerTuple);
  12198. resultType = entry.mInnerTuple->mTupleType;
  12199. }
  12200. else
  12201. {
  12202. BfExprEvaluator* exprEvaluator = new BfExprEvaluator(mModule);
  12203. entry.mExprEvaluator = exprEvaluator;
  12204. if (valueExpr->IsA<BfUninitializedExpression>())
  12205. {
  12206. resultType = mModule->GetPrimitiveType(BfTypeCode_None);
  12207. }
  12208. if (auto varDecl = BfNodeDynCast<BfVariableDeclaration>(valueExpr))
  12209. {
  12210. if ((varDecl->mTypeRef->IsA<BfLetTypeReference>()) || (varDecl->mTypeRef->IsA<BfVarTypeReference>()))
  12211. {
  12212. resultType = mModule->GetPrimitiveType(BfTypeCode_Var);
  12213. }
  12214. else
  12215. {
  12216. resultType = ResolveTypeRef(varDecl->mTypeRef);
  12217. if (resultType == NULL)
  12218. resultType = mModule->GetPrimitiveType(BfTypeCode_Var);
  12219. }
  12220. }
  12221. if (resultType == NULL)
  12222. {
  12223. exprEvaluator->VisitChild(valueExpr);
  12224. if ((!exprEvaluator->mResult) && (exprEvaluator->mPropDef == NULL))
  12225. exprEvaluator->mResult = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_None));
  12226. resultType = exprEvaluator->mResult.mType;
  12227. }
  12228. if ((resultType == NULL) && (exprEvaluator->mPropDef != NULL) && (exprEvaluator->mPropTarget.mType != NULL))
  12229. {
  12230. auto propTypeInst = exprEvaluator->mPropTarget.mType->ToTypeInstance();
  12231. if ((propTypeInst == NULL) && (exprEvaluator->mPropTarget.mType->IsPointer()))
  12232. {
  12233. BfPointerType* pointerType = (BfPointerType*)exprEvaluator->mPropTarget.mType;
  12234. propTypeInst = pointerType->mElementType->ToTypeInstance();
  12235. }
  12236. auto setMethod = GetPropertyMethodDef(exprEvaluator->mPropDef, BfMethodType_PropertySetter, mPropCheckedKind);
  12237. if (setMethod != NULL)
  12238. {
  12239. auto methodInstance = mModule->GetMethodInstance(propTypeInst, setMethod, BfTypeVector());
  12240. resultType = methodInstance.mMethodInstance->GetParamType(0);
  12241. }
  12242. else
  12243. {
  12244. auto getMethod = GetPropertyMethodDef(exprEvaluator->mPropDef, BfMethodType_PropertyGetter, mPropCheckedKind);
  12245. if (getMethod != NULL)
  12246. {
  12247. auto methodInstance = mModule->GetMethodInstance(propTypeInst, getMethod, BfTypeVector());
  12248. auto retType = methodInstance.mMethodInstance->mReturnType;
  12249. if (retType->IsRef())
  12250. resultType = retType->GetUnderlyingType();
  12251. }
  12252. }
  12253. }
  12254. }
  12255. if (resultType == NULL)
  12256. resultType = mModule->GetPrimitiveType(BfTypeCode_None);
  12257. deferredTupleAssignData.mChildren.push_back(entry);
  12258. fieldTypes.push_back(resultType);
  12259. }
  12260. for (BfTupleNameNode* requestedName : tupleExpr->mNames)
  12261. {
  12262. if (requestedName == NULL)
  12263. fieldNames.push_back("");
  12264. else
  12265. fieldNames.push_back(requestedName->mNameNode->ToString());
  12266. }
  12267. BfTupleType* tupleType = mModule->CreateTupleType(fieldTypes, fieldNames);
  12268. deferredTupleAssignData.mTupleType = tupleType;
  12269. }
  12270. void BfExprEvaluator::AssignDeferrredTupleAssignData(BfAssignmentExpression* assignExpr, DeferredTupleAssignData& deferredTupleAssignData, BfTypedValue rightValue)
  12271. {
  12272. BF_ASSERT(rightValue.mType->IsTuple());
  12273. auto tupleType = (BfTupleType*)rightValue.mType;
  12274. for (int valueIdx = 0; valueIdx < (int)deferredTupleAssignData.mChildren.size(); valueIdx++)
  12275. {
  12276. auto& child = deferredTupleAssignData.mChildren[valueIdx];
  12277. BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[valueIdx];
  12278. BfTypedValue elementValue;
  12279. if (fieldInstance->mDataIdx >= 0)
  12280. {
  12281. auto extractedValue = mModule->mBfIRBuilder->CreateExtractValue(rightValue.mValue, fieldInstance->mDataIdx);
  12282. elementValue = BfTypedValue(extractedValue, fieldInstance->GetResolvedType());
  12283. if (child.mInnerTuple != NULL)
  12284. {
  12285. AssignDeferrredTupleAssignData(assignExpr, *child.mInnerTuple, elementValue);
  12286. delete child.mInnerTuple;
  12287. }
  12288. else
  12289. {
  12290. child.mExprEvaluator->PerformAssignment(assignExpr, true, elementValue);
  12291. }
  12292. }
  12293. if (auto varDecl = BfNodeDynCast<BfVariableDeclaration>(child.mExpr))
  12294. {
  12295. if (!elementValue)
  12296. elementValue = mModule->GetDefaultTypedValue(fieldInstance->GetResolvedType());
  12297. mModule->HandleVariableDeclaration(varDecl, elementValue);
  12298. }
  12299. }
  12300. }
  12301. void BfExprEvaluator::DoTupleAssignment(BfAssignmentExpression* assignExpr)
  12302. {
  12303. auto tupleExpr = BfNodeDynCast<BfTupleExpression>(assignExpr->mLeft);
  12304. DeferredTupleAssignData deferredTupleAssignData;
  12305. PopulateDeferrredTupleAssignData(tupleExpr, deferredTupleAssignData);
  12306. BfTupleType* tupleType = deferredTupleAssignData.mTupleType;
  12307. BfTypedValue rightValue;
  12308. if (assignExpr->mRight != NULL)
  12309. {
  12310. rightValue = mModule->CreateValueFromExpression(assignExpr->mRight, tupleType);
  12311. }
  12312. if (!rightValue)
  12313. {
  12314. tupleType = mModule->SantizeTupleType(tupleType);
  12315. rightValue = mModule->GetDefaultTypedValue(tupleType);
  12316. }
  12317. rightValue = mModule->LoadValue(rightValue);
  12318. AssignDeferrredTupleAssignData(assignExpr, deferredTupleAssignData, rightValue);
  12319. mResult = rightValue;
  12320. }
  12321. void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool evaluatedLeft, BfTypedValue rightValue, BfTypedValue* outCascadeValue)
  12322. {
  12323. auto binaryOp = BfAssignOpToBinaryOp(assignExpr->mOp);
  12324. BfExpression* targetNode = assignExpr->mLeft;
  12325. if ((BfNodeIsA<BfMixinExpression>(targetNode)) && (!mModule->mCurMethodInstance->mIsUnspecialized))
  12326. {
  12327. // If we have a "mixin = <X>" but there's no mixin target then ignore the assignment
  12328. int mixinVar = GetMixinVariable();
  12329. if (mixinVar == -1)
  12330. {
  12331. mResult = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_None));
  12332. return;
  12333. }
  12334. }
  12335. BfAutoComplete* autoComplete = GetAutoComplete();
  12336. bool deferredFixits = false;
  12337. if ((autoComplete != NULL) && (autoComplete->mResolveType == BfResolveType_GetFixits))
  12338. {
  12339. SetAndRestoreValue<bool> ignoreFixits(autoComplete->mIgnoreFixits, true);
  12340. VisitChild(targetNode);
  12341. deferredFixits = true;
  12342. }
  12343. else if (!evaluatedLeft)
  12344. {
  12345. if (auto memberReferenceExpr = BfNodeDynCast<BfMemberReferenceExpression>(targetNode))
  12346. {
  12347. DoMemberReference(memberReferenceExpr, outCascadeValue);
  12348. }
  12349. else
  12350. VisitChild(targetNode);
  12351. }
  12352. if ((!mResult) && (mPropDef == NULL))
  12353. {
  12354. if (assignExpr->mRight != NULL)
  12355. {
  12356. auto result = mModule->CreateValueFromExpression(assignExpr->mRight);
  12357. if (deferredFixits)
  12358. {
  12359. SetAndRestoreValue<bool> ignoreErrors(mModule->mIgnoreErrors, true);
  12360. mExpectingType = result.mType;
  12361. VisitChild(targetNode);
  12362. mResult = BfTypedValue();
  12363. }
  12364. }
  12365. return;
  12366. }
  12367. ResolveGenericType();
  12368. auto ptr = mResult;
  12369. mResult = BfTypedValue();
  12370. if (mPropDef == NULL)
  12371. {
  12372. if (!CheckModifyResult(ptr, assignExpr->mOpToken, "assign to"))
  12373. {
  12374. if (assignExpr->mRight != NULL)
  12375. mModule->CreateValueFromExpression(assignExpr->mRight, ptr.mType, BfEvalExprFlags_NoCast);
  12376. return;
  12377. }
  12378. }
  12379. if (mPropDef != NULL)
  12380. {
  12381. bool hasLeftVal = false;
  12382. auto propDef = mPropDef;
  12383. auto propTarget = mPropTarget;
  12384. auto setMethod = GetPropertyMethodDef(mPropDef, BfMethodType_PropertySetter, mPropCheckedKind);
  12385. if (setMethod == NULL)
  12386. {
  12387. // Allow for a ref return on the getter to be used if a setter is not available
  12388. GetResult();
  12389. if ((mResult) && (mResult.mKind == BfTypedValueKind_Addr))
  12390. {
  12391. ptr = mResult;
  12392. mResult = BfTypedValue();
  12393. hasLeftVal = true;
  12394. }
  12395. else
  12396. {
  12397. mModule->Fail("Property has no setter", mPropSrc);
  12398. if (assignExpr->mRight != NULL)
  12399. mModule->CreateValueFromExpression(assignExpr->mRight, ptr.mType, BfEvalExprFlags_NoCast);
  12400. return;
  12401. }
  12402. }
  12403. if (!hasLeftVal)
  12404. {
  12405. auto methodInstance = GetPropertyMethodInstance(setMethod);
  12406. if (methodInstance.mMethodInstance == NULL)
  12407. return;
  12408. BF_ASSERT(methodInstance.mMethodInstance->mMethodDef == setMethod);
  12409. CheckPropFail(setMethod, methodInstance.mMethodInstance);
  12410. BfTypedValue convVal;
  12411. if (binaryOp != BfBinaryOp_None)
  12412. {
  12413. PerformBinaryOperation(assignExpr->mLeft, assignExpr->mRight, binaryOp, assignExpr->mOpToken, BfBinOpFlag_ForceLeftType);
  12414. if (!mResult)
  12415. return;
  12416. convVal = mResult;
  12417. mResult = BfTypedValue();
  12418. if (!convVal)
  12419. return;
  12420. }
  12421. else
  12422. {
  12423. auto wantType = methodInstance.mMethodInstance->GetParamType(methodInstance.mMethodInstance->GetParamCount() - 1);
  12424. if (rightValue)
  12425. {
  12426. convVal = mModule->Cast(assignExpr->mRight, rightValue, wantType);
  12427. }
  12428. else
  12429. {
  12430. if (assignExpr->mRight == NULL)
  12431. {
  12432. mModule->AssertErrorState();
  12433. return;
  12434. }
  12435. convVal = mModule->CreateValueFromExpression(assignExpr->mRight, wantType, (BfEvalExprFlags)(BfEvalExprFlags_AllowSplat | BfEvalExprFlags_PendingPropSet));
  12436. }
  12437. if (!convVal)
  12438. {
  12439. mPropDef = NULL;
  12440. return;
  12441. }
  12442. }
  12443. if (mPropSrc != NULL)
  12444. mModule->UpdateExprSrcPos(mPropSrc);
  12445. SizedArray<BfIRValue, 4> args;
  12446. if (!setMethod->mIsStatic)
  12447. {
  12448. mModule->EmitObjectAccessCheck(mPropTarget);
  12449. PushThis(mPropSrc, mPropTarget, methodInstance.mMethodInstance, args);
  12450. }
  12451. for (int paramIdx = 0; paramIdx < (int)mIndexerValues.size(); paramIdx++)
  12452. {
  12453. auto val = mModule->Cast(mPropSrc, mIndexerValues[paramIdx].mTypedValue, methodInstance.mMethodInstance->GetParamType(paramIdx));
  12454. if (!val)
  12455. {
  12456. mPropDef = NULL;
  12457. return;
  12458. }
  12459. PushArg(val, args);
  12460. }
  12461. PushArg(convVal, args);
  12462. if (methodInstance)
  12463. CreateCall(methodInstance.mMethodInstance, methodInstance.mFunc, mPropDefBypassVirtual, args);
  12464. mPropDef = NULL;
  12465. mResult = convVal;
  12466. return;
  12467. }
  12468. }
  12469. auto toType = ptr.mType;
  12470. if (toType->IsRef())
  12471. {
  12472. auto refType = (BfRefType*)toType;
  12473. toType = refType->mElementType;
  12474. }
  12475. if ((autoComplete != NULL) && (assignExpr->mOpToken != NULL) && (toType != NULL))
  12476. autoComplete->CheckEmptyStart(assignExpr->mOpToken, toType);
  12477. BfExpression* rightExpr = assignExpr->mRight;
  12478. if (rightExpr == NULL)
  12479. {
  12480. mModule->AssertErrorState();
  12481. return;
  12482. }
  12483. bool alreadyWritten = false;
  12484. BfTypedValue convVal;
  12485. if (binaryOp != BfBinaryOp_None)
  12486. {
  12487. auto expectedType = ptr.mType;
  12488. if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift))
  12489. expectedType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  12490. if ((!rightValue) && (assignExpr->mRight != NULL))
  12491. {
  12492. rightValue = mModule->CreateValueFromExpression(assignExpr->mRight, expectedType, (BfEvalExprFlags)(BfEvalExprFlags_AllowSplat | BfEvalExprFlags_NoCast));
  12493. }
  12494. CheckResultForReading(ptr);
  12495. BfTypedValue leftValue = ptr;
  12496. leftValue = mModule->LoadValue(leftValue);
  12497. if (rightValue)
  12498. PerformBinaryOperation(assignExpr->mLeft, assignExpr->mRight, binaryOp, assignExpr->mOpToken, BfBinOpFlag_ForceLeftType, leftValue, rightValue);
  12499. convVal = mResult;
  12500. mResult = BfTypedValue();
  12501. if (!convVal)
  12502. return;
  12503. }
  12504. else
  12505. {
  12506. convVal = rightValue;
  12507. if (!convVal)
  12508. {
  12509. if (auto uninitExpr = BfNodeDynCast<BfUninitializedExpression>(rightExpr))
  12510. {
  12511. if (mResultLocalVar != NULL)
  12512. {
  12513. MarkResultAssigned();
  12514. return;
  12515. }
  12516. }
  12517. // In the cases like "structVal = GetVal()", the allowDirectStructRetWrite optimization allows us to pass the
  12518. // address of structVal into the sret. We only allow that if structVal is a local, because if it's globally
  12519. // visible then we could see the results of a partially-modified structVal
  12520. //bool allowDirectStructRetWrite = mResultLocalVarIdx != -1;
  12521. // ALTHOUGH- we can only allow this optimization if we can be sure the local value is not aliased- we could
  12522. // have the backend ensure that this local value never gets its address taken.
  12523. bool allowDirectStructWrite = false;
  12524. BfExprEvaluator exprEvaluator(mModule);
  12525. exprEvaluator.mExpectingType = toType;
  12526. if (allowDirectStructWrite)
  12527. exprEvaluator.mReceivingValue = &ptr;
  12528. exprEvaluator.Evaluate(rightExpr, false, false, true);
  12529. exprEvaluator.CheckResultForReading(exprEvaluator.mResult);
  12530. convVal = exprEvaluator.GetResult();
  12531. mModule->FixIntUnknown(convVal);
  12532. alreadyWritten = (allowDirectStructWrite) && (exprEvaluator.mReceivingValue == NULL);
  12533. if (!convVal)
  12534. convVal = mModule->GetDefaultTypedValue(toType);
  12535. // Did we use mReceivingValue as a mixin result?
  12536. if ((convVal.mValue) && (convVal.mValue == ptr.mValue))
  12537. {
  12538. mResult = convVal;
  12539. return;
  12540. }
  12541. }
  12542. }
  12543. BF_ASSERT(convVal);
  12544. if ((convVal) && (convVal.mType->IsNull()) && (ptr.mType->IsNullable()))
  12545. {
  12546. // Allow this to pass through so we can catch it in the memset later in this function
  12547. }
  12548. else
  12549. {
  12550. if (!convVal.mType->IsComposite())
  12551. convVal = mModule->LoadValue(convVal);
  12552. convVal = mModule->Cast(rightExpr, convVal, toType);
  12553. if (!convVal)
  12554. return;
  12555. convVal = mModule->LoadValue(convVal);
  12556. }
  12557. if (ptr.mType->IsVar())
  12558. {
  12559. mResult = ptr;
  12560. return;
  12561. }
  12562. if (convVal.mValue)
  12563. {
  12564. if ((ptr.mType->IsStruct()) && (!ptr.mType->IsValuelessType()) && (convVal.mValue.IsConst()))
  12565. {
  12566. auto constant = mModule->mBfIRBuilder->GetConstant(convVal.mValue);
  12567. if ((constant->mTypeCode == BfTypeCode_NullPtr) || (constant->mConstType == BfConstType_AggZero))
  12568. {
  12569. auto type = ptr.mType;
  12570. mModule->mBfIRBuilder->CreateMemSet(ptr.mValue, mModule->GetConstValue(0, mModule->GetPrimitiveType(BfTypeCode_Int8)),
  12571. mModule->GetConstValue(type->mSize), type->mAlign);
  12572. mResult = ptr;
  12573. MarkResultAssigned();
  12574. return;
  12575. }
  12576. }
  12577. // if (ptr.mType->IsMethodRef())
  12578. // {
  12579. // auto methodRefType = (BfMethodRefType*)ptr.mType;
  12580. // auto methodInstance = methodRefType->mMethodInstance;
  12581. // int implicitParamCount = methodInstance->GetImplicitParamCount();
  12582. // for (int implicitParamIdx = methodInstance->HasThis() ? - 1 : 0; implicitParamIdx < implicitParamCount; implicitParamIdx++)
  12583. // {
  12584. // bool failed = false;
  12585. // auto destPtr = DoImplicitArgCapture(assignExpr, methodRefType->mMethodInstance, implicitParamIdx, failed, BfImplicitParamKind_GenericTypeMember_Addr);
  12586. // auto srcVal = DoImplicitArgCapture(assignExpr, methodRefType->mMethodInstance, implicitParamIdx, failed, BfImplicitParamKind_GenericMethodMember);
  12587. // if ((destPtr) && (srcVal))
  12588. // {
  12589. // srcVal = mModule->AggregateSplat(srcVal);
  12590. // mModule->mBfIRBuilder->CreateStore(srcVal.mValue, destPtr.mValue);
  12591. // }
  12592. // }
  12593. // }
  12594. // else
  12595. {
  12596. mModule->mBfIRBuilder->PopulateType(ptr.mType);
  12597. if (convVal.IsSplat())
  12598. {
  12599. //convVal = mModule->AggregateSplat(convVal);
  12600. mModule->AggregateSplatIntoAddr(convVal, ptr.mValue);
  12601. }
  12602. else
  12603. {
  12604. if (ptr.mType->IsValuelessType())
  12605. {
  12606. mModule->EmitEnsureInstructionAt();
  12607. }
  12608. else if (!alreadyWritten)
  12609. {
  12610. //ptr = mModule->LoadValue(ptr);
  12611. BF_ASSERT(ptr.IsAddr());
  12612. convVal = mModule->LoadValue(convVal);
  12613. auto storeInst = mModule->mBfIRBuilder->CreateAlignedStore(convVal.mValue, ptr.mValue, ptr.mType->mAlign, mIsVolatileReference);
  12614. }
  12615. }
  12616. }
  12617. }
  12618. else
  12619. {
  12620. BF_ASSERT(convVal.mType->IsValuelessType());
  12621. }
  12622. mResult = convVal;
  12623. MarkResultAssigned();
  12624. }
  12625. void BfExprEvaluator::Visit(BfAssignmentExpression* assignExpr)
  12626. {
  12627. if (assignExpr->mLeft->IsA<BfTupleExpression>())
  12628. {
  12629. DoTupleAssignment(assignExpr);
  12630. return;
  12631. }
  12632. BfAutoParentNodeEntry autoParentNodeEntry(mModule, assignExpr);
  12633. BfTypedValue cascadeValue;
  12634. PerformAssignment(assignExpr, false, BfTypedValue(), &cascadeValue);
  12635. if (cascadeValue)
  12636. mResult = cascadeValue;
  12637. }
  12638. void BfExprEvaluator::Visit(BfParenthesizedExpression* parenExpr)
  12639. {
  12640. VisitChild(parenExpr->mExpression);
  12641. MakeResultAsValue();
  12642. }
  12643. void BfExprEvaluator::InitializedSizedArray(BfSizedArrayType* arrayType, BfTokenNode* openToken, const BfSizedArray<BfExpression*>& valueExprs, const BfSizedArray<BfTokenNode*>& commas, BfTokenNode* closeToken, BfTypedValue* receivingValue)
  12644. {
  12645. struct InitValue
  12646. {
  12647. BfTypedValue mValue;
  12648. bool mIsUninitialized;
  12649. bool mIsDefaultInitializer;
  12650. bool mIsDeferred;
  12651. InitValue()
  12652. {
  12653. mIsUninitialized = false;
  12654. mIsDefaultInitializer = false;
  12655. mIsDeferred = false;
  12656. }
  12657. };
  12658. SizedArray<InitValue, 8> values;
  12659. {
  12660. //bool hasFailed = false;
  12661. HashSet<int> failedAt;
  12662. bool isAllConst = true;
  12663. //bool endUninitialzied = false;
  12664. int depth = 0;
  12665. std::function<void(BfSizedArrayType*, BfTokenNode* openToken, const BfSizedArray<BfExpression*>&, const BfSizedArray<BfTokenNode*>&, BfTokenNode*, bool)>
  12666. _GetValues = [&](BfSizedArrayType* checkArrayType, BfTokenNode* openToken, const BfSizedArray<BfExpression*>& valueExprs, const BfSizedArray<BfTokenNode*>& commas, BfTokenNode* closeToken, bool ignore)
  12667. {
  12668. int64 initCountDiff = (int)valueExprs.size() - checkArrayType->mElementCount;
  12669. if ((initCountDiff != 0) && (!failedAt.Contains(depth)))
  12670. {
  12671. if (initCountDiff > 0)
  12672. {
  12673. mModule->Fail(StrFormat("Too many initializers, expected %d fewer", initCountDiff), valueExprs[(int)checkArrayType->mElementCount]);
  12674. failedAt.Add(depth);
  12675. }
  12676. else
  12677. {
  12678. // If it ends with ", ?) or ",)" then allow unsized
  12679. if (((valueExprs.size() == 0) || (BfNodeDynCast<BfUninitializedExpression>(valueExprs.back()) == NULL)) &&
  12680. ((commas.size() < valueExprs.size()) || (valueExprs.size() == 0)))
  12681. {
  12682. BfAstNode* refNode = closeToken;
  12683. if ((refNode == NULL) && (mModule->mParentNodeEntry != NULL))
  12684. refNode = mModule->mParentNodeEntry->mNode;
  12685. BF_ASSERT(refNode != NULL);
  12686. mModule->Fail(StrFormat("Too few initializer, expected %d more", -initCountDiff), refNode);
  12687. failedAt.Add(depth);
  12688. }
  12689. }
  12690. }
  12691. for (int idx = 0; idx < BF_MAX(checkArrayType->mElementCount, valueExprs.size()); idx++)
  12692. {
  12693. BfTypedValue elementValue;
  12694. bool deferredValue = false;
  12695. BfExpression* expr = NULL;
  12696. if (idx < (int)valueExprs.size())
  12697. {
  12698. expr = valueExprs[idx];
  12699. if (expr == NULL)
  12700. {
  12701. if (idx == 0)
  12702. mModule->FailAfter("Expression expected", openToken);
  12703. else
  12704. mModule->FailAfter("Expression expected", commas[idx - 1]);
  12705. }
  12706. if ((BfNodeDynCastExact<BfUninitializedExpression>(expr) != NULL) && (idx == (int)commas.size()))
  12707. {
  12708. isAllConst = false;
  12709. break;
  12710. }
  12711. if (checkArrayType->mElementType->IsSizedArray())
  12712. {
  12713. if (auto arrayInitExpr = BfNodeDynCast<BfTupleExpression>(expr))
  12714. {
  12715. depth++;
  12716. _GetValues((BfSizedArrayType*)checkArrayType->mElementType, arrayInitExpr->mOpenParen, arrayInitExpr->mValues, arrayInitExpr->mCommas, arrayInitExpr->mCloseParen, ignore);
  12717. depth--;
  12718. continue;
  12719. }
  12720. else if (auto arrayInitExpr = BfNodeDynCast<BfCollectionInitializerExpression>(expr))
  12721. {
  12722. depth++;
  12723. _GetValues((BfSizedArrayType*)checkArrayType->mElementType, arrayInitExpr->mOpenBrace, arrayInitExpr->mValues, arrayInitExpr->mCommas, arrayInitExpr->mCloseBrace, ignore);
  12724. depth--;
  12725. continue;
  12726. }
  12727. else if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(expr))
  12728. {
  12729. depth++;
  12730. SizedArray<BfExpression*, 1> values;
  12731. values.Add(parenExpr->mExpression);
  12732. SizedArray<BfTokenNode*, 1> commas;
  12733. _GetValues((BfSizedArrayType*)checkArrayType->mElementType, parenExpr->mOpenParen, values, commas, parenExpr->mCloseParen, ignore);
  12734. depth--;
  12735. continue;
  12736. }
  12737. }
  12738. if (expr != NULL)
  12739. {
  12740. bool tryDefer = false;
  12741. if ((checkArrayType->IsComposite()) &&
  12742. ((expr->IsA<BfInvocationExpression>()) || (expr->IsExact<BfTupleExpression>())))
  12743. {
  12744. tryDefer = true;
  12745. }
  12746. SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, mModule->mBfIRBuilder->mIgnoreWrites || tryDefer);
  12747. elementValue = mModule->CreateValueFromExpression(expr, checkArrayType->mElementType);
  12748. if (!elementValue)
  12749. elementValue = mModule->GetDefaultTypedValue(checkArrayType->mElementType);
  12750. deferredValue = !prevIgnoreWrites.mPrevVal && elementValue.mValue.IsFake();
  12751. if ((!elementValue) || (!CheckAllowValue(elementValue, expr)))
  12752. elementValue = mModule->GetDefaultTypedValue(checkArrayType->mElementType);
  12753. // For now, we can't properly create const-valued non-size-aligned composites
  12754. if (checkArrayType->mElementType->NeedsExplicitAlignment())
  12755. isAllConst = false;
  12756. if (!elementValue.mValue.IsConst())
  12757. isAllConst = false;
  12758. InitValue initValue;
  12759. initValue.mValue = elementValue;
  12760. initValue.mIsDeferred = deferredValue;
  12761. values.push_back(initValue);
  12762. }
  12763. }
  12764. }
  12765. };
  12766. int valueIdx = 0;
  12767. std::function<void(BfTypedValue, BfTokenNode* openToken, const BfSizedArray<BfExpression*>&, const BfSizedArray<BfTokenNode*>&, BfTokenNode*)>
  12768. _CreateMemArray = [&](BfTypedValue arrayValue, BfTokenNode* openToken, const BfSizedArray<BfExpression*>& valueExprs, const BfSizedArray<BfTokenNode*>& commas, BfTokenNode* closeToken)
  12769. {
  12770. BF_ASSERT(arrayValue.mType->IsSizedArray());
  12771. auto checkArrayType = (BfSizedArrayType*)arrayValue.mType;
  12772. int valIdx = 0;
  12773. bool hasUninit = false;
  12774. for (int idx = 0; idx < checkArrayType->mElementCount; idx++)
  12775. {
  12776. BfExpression* expr = NULL;
  12777. BfTypedValue elementValue;
  12778. if (idx >= (int)valueExprs.size())
  12779. break;
  12780. expr = valueExprs[idx];
  12781. if ((BfNodeDynCastExact<BfUninitializedExpression>(expr) != NULL) && (idx == (int)commas.size()))
  12782. {
  12783. hasUninit = true;
  12784. break;
  12785. }
  12786. BfIRValue elemPtrValue = mModule->CreateIndexedValue(checkArrayType->mElementType, arrayValue.mValue, valIdx, true);
  12787. valIdx++;
  12788. if (checkArrayType->mElementType->IsSizedArray())
  12789. {
  12790. if (auto arrayInitExpr = BfNodeDynCast<BfTupleExpression>(expr))
  12791. {
  12792. _CreateMemArray(BfTypedValue(elemPtrValue, checkArrayType->mElementType, true), arrayInitExpr->mOpenParen, arrayInitExpr->mValues, arrayInitExpr->mCommas, arrayInitExpr->mCloseParen);
  12793. continue;
  12794. }
  12795. else if (auto arrayInitExpr = BfNodeDynCast<BfCollectionInitializerExpression>(expr))
  12796. {
  12797. _CreateMemArray(BfTypedValue(elemPtrValue, checkArrayType->mElementType, true), arrayInitExpr->mOpenBrace, arrayInitExpr->mValues, arrayInitExpr->mCommas, arrayInitExpr->mCloseBrace);
  12798. continue;
  12799. }
  12800. else if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(expr))
  12801. {
  12802. depth++;
  12803. SizedArray<BfExpression*, 1> values;
  12804. values.Add(parenExpr->mExpression);
  12805. SizedArray<BfTokenNode*, 1> commas;
  12806. _CreateMemArray(BfTypedValue(elemPtrValue, checkArrayType->mElementType, true), parenExpr->mOpenParen, values, commas, parenExpr->mCloseParen);
  12807. depth--;
  12808. continue;
  12809. }
  12810. }
  12811. if (expr != NULL)
  12812. {
  12813. InitValue initValue = values[valueIdx++];
  12814. elementValue = initValue.mValue;
  12815. if (initValue.mIsDeferred)
  12816. {
  12817. BfTypedValue elemePtrTypedVal = BfTypedValue(elemPtrValue, checkArrayType->mElementType, BfTypedValueKind_Addr);
  12818. BfExprEvaluator exprEvaluator(mModule);
  12819. exprEvaluator.mExpectingType = checkArrayType->mElementType;
  12820. exprEvaluator.mReceivingValue = &elemePtrTypedVal;
  12821. exprEvaluator.Evaluate(expr);
  12822. exprEvaluator.GetResult();
  12823. if (exprEvaluator.mReceivingValue == NULL)
  12824. {
  12825. // We wrote directly to the array in-place, we're done with this element
  12826. continue;
  12827. }
  12828. elementValue = exprEvaluator.mResult;
  12829. elementValue = mModule->Cast(expr, elementValue, checkArrayType->mElementType);
  12830. if (!elementValue)
  12831. {
  12832. mModule->AssertErrorState();
  12833. continue;
  12834. }
  12835. }
  12836. elementValue = mModule->LoadValue(elementValue);
  12837. mModule->mBfIRBuilder->CreateAlignedStore(elementValue.mValue, elemPtrValue, checkArrayType->mElementType->mAlign);
  12838. }
  12839. }
  12840. int fillCount = (int)(checkArrayType->mElementCount - valIdx);
  12841. if (fillCount > 0)
  12842. {
  12843. BfIRValue elemPtrValue = mModule->CreateIndexedValue(checkArrayType->mElementType, arrayValue.mValue, valIdx, true);
  12844. if (hasUninit)
  12845. {
  12846. if (!mModule->IsOptimized())
  12847. {
  12848. int setSize = std::min(checkArrayType->mElementType->mSize, 128); // Keep it to a reasonable number of bytes to trash
  12849. mModule->mBfIRBuilder->CreateMemSet(elemPtrValue, mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int8, 0xCC),
  12850. mModule->GetConstValue(setSize), checkArrayType->mElementType->mAlign);
  12851. }
  12852. }
  12853. else
  12854. {
  12855. int setSize = (int)((checkArrayType->mElementType->GetStride() * (fillCount - 1)) + checkArrayType->mElementType->mSize);
  12856. if (setSize >= 0)
  12857. {
  12858. mModule->mBfIRBuilder->CreateMemSet(elemPtrValue, mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int8, 0),
  12859. mModule->GetConstValue(setSize), checkArrayType->mElementType->mAlign);
  12860. }
  12861. }
  12862. }
  12863. };
  12864. std::function<BfIRValue(BfTypedValue, BfTokenNode*, const BfSizedArray<BfExpression*>&, const BfSizedArray<BfTokenNode*>&, BfTokenNode*)>
  12865. _CreateConstArray = [&](BfTypedValue arrayValue, BfTokenNode* openToken, const BfSizedArray<BfExpression*>& valueExprs, const BfSizedArray<BfTokenNode*>& commas, BfTokenNode* closeToken)
  12866. {
  12867. SizedArray<BfIRValue, 8> members;
  12868. BF_ASSERT(arrayValue.mType->IsSizedArray());
  12869. auto checkArrayType = (BfSizedArrayType*)arrayValue.mType;
  12870. int valIdx = 0;
  12871. for (int idx = 0; idx < checkArrayType->mElementCount; idx++)
  12872. {
  12873. BfTypedValue elementValue;
  12874. if (idx >= (int)valueExprs.size())
  12875. break;
  12876. auto expr = valueExprs[idx];
  12877. if (expr == NULL)
  12878. continue;
  12879. valIdx++;
  12880. if (checkArrayType->mElementType->IsSizedArray())
  12881. {
  12882. if (auto arrayInitExpr = BfNodeDynCast<BfTupleExpression>(expr))
  12883. {
  12884. members.push_back(_CreateConstArray(checkArrayType->mElementType, arrayInitExpr->mOpenParen, arrayInitExpr->mValues, arrayInitExpr->mCommas, arrayInitExpr->mCloseParen));
  12885. continue;
  12886. }
  12887. else if (auto arrayInitExpr = BfNodeDynCast<BfCollectionInitializerExpression>(expr))
  12888. {
  12889. members.push_back(_CreateConstArray(checkArrayType->mElementType, arrayInitExpr->mOpenBrace, arrayInitExpr->mValues, arrayInitExpr->mCommas, arrayInitExpr->mCloseBrace));
  12890. continue;
  12891. }
  12892. else if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(expr))
  12893. {
  12894. depth++;
  12895. SizedArray<BfExpression*, 1> values;
  12896. values.Add(parenExpr->mExpression);
  12897. SizedArray<BfTokenNode*, 1> commas;
  12898. members.push_back(_CreateConstArray(checkArrayType->mElementType, parenExpr->mOpenParen, values, commas, parenExpr->mCloseParen));
  12899. depth--;
  12900. continue;
  12901. }
  12902. }
  12903. InitValue initValue = values[valueIdx++];
  12904. BF_ASSERT(!initValue.mIsUninitialized);
  12905. elementValue = initValue.mValue;
  12906. members.push_back(elementValue.mValue);
  12907. }
  12908. int fillCount = (int)(checkArrayType->mElementCount - valIdx);
  12909. if (fillCount > 0)
  12910. {
  12911. // We just need to insert one default value, it will be duplicated as needed into the backend
  12912. auto defaultVal = mModule->GetDefaultTypedValue(checkArrayType->GetUnderlyingType());
  12913. BF_ASSERT(defaultVal.mValue.IsConst());
  12914. members.push_back(defaultVal.mValue);
  12915. }
  12916. return mModule->mBfIRBuilder->CreateConstArray(mModule->mBfIRBuilder->MapType(checkArrayType), members);
  12917. };
  12918. _GetValues(arrayType, openToken, valueExprs, commas, closeToken, false);
  12919. if (!failedAt.IsEmpty())
  12920. {
  12921. mResult = mModule->GetDefaultTypedValue(arrayType, false, BfDefaultValueKind_Addr);
  12922. return;
  12923. }
  12924. if (receivingValue != NULL)
  12925. {
  12926. BF_ASSERT(receivingValue->mType == arrayType);
  12927. BF_ASSERT(receivingValue->IsAddr());
  12928. mResult = *receivingValue;
  12929. _CreateMemArray(mResult, openToken, valueExprs, commas, closeToken);
  12930. }
  12931. else if (isAllConst)
  12932. {
  12933. mResult = BfTypedValue(_CreateConstArray(arrayType, openToken, valueExprs, commas, closeToken), arrayType, BfTypedValueKind_Value);
  12934. }
  12935. else
  12936. {
  12937. if ((mReceivingValue != NULL) && (mReceivingValue->mType == arrayType) && (mReceivingValue->IsAddr()))
  12938. {
  12939. mResult = *mReceivingValue;
  12940. mReceivingValue = NULL;
  12941. }
  12942. else
  12943. {
  12944. auto arrayValue = mModule->CreateAlloca(arrayType);
  12945. mResult = BfTypedValue(arrayValue, arrayType, BfTypedValueKind_TempAddr);
  12946. }
  12947. _CreateMemArray(mResult, openToken, valueExprs, commas, closeToken);
  12948. }
  12949. }
  12950. }
  12951. void BfExprEvaluator::Visit(BfTupleExpression* tupleExpr)
  12952. {
  12953. if (mExpectingType != NULL)
  12954. {
  12955. if (mExpectingType->IsSizedArray())
  12956. {
  12957. InitializedSizedArray((BfSizedArrayType*)mExpectingType, tupleExpr->mOpenParen, tupleExpr->mValues, tupleExpr->mCommas, tupleExpr->mCloseParen);
  12958. return;
  12959. }
  12960. }
  12961. BfTupleType* tupleType = NULL;
  12962. bool hadFullMatch = false;
  12963. if ((mExpectingType != NULL) && (mExpectingType->IsTuple()))
  12964. {
  12965. tupleType = (BfTupleType*)mExpectingType;
  12966. hadFullMatch = tupleType->mFieldInstances.size() == tupleExpr->mValues.size();
  12967. }
  12968. struct InitValue
  12969. {
  12970. BfTypedValue mValue;
  12971. bool mIsUninitialized;
  12972. bool mIsDefaultInitializer;
  12973. bool mIsDeferred;
  12974. InitValue()
  12975. {
  12976. mIsUninitialized = false;
  12977. mIsDefaultInitializer = false;
  12978. mIsDeferred = false;
  12979. }
  12980. };
  12981. SizedArray<BfTypedValue, 2> typedValues;
  12982. if ((tupleExpr->mCommas.size() != 0) && (tupleExpr->mCommas.size() >= tupleExpr->mValues.size()))
  12983. {
  12984. // We would normally give this error during syntax parsing, but a TupleExpression can be an array initializer
  12985. mModule->FailAfter("Expression expected", tupleExpr->mCommas.back());
  12986. }
  12987. for (int valueIdx = 0; valueIdx < (int)tupleExpr->mValues.size(); valueIdx++)
  12988. {
  12989. BfExpression* valueExpr = tupleExpr->mValues[valueIdx];
  12990. BfType* fieldType = NULL;
  12991. BfFieldInstance* fieldInstance = NULL;
  12992. if (tupleType != NULL)
  12993. {
  12994. if (valueIdx < (int)tupleType->mFieldInstances.size())
  12995. {
  12996. fieldInstance = (BfFieldInstance*)&tupleType->mFieldInstances[valueIdx];
  12997. fieldType = fieldInstance->GetResolvedType();
  12998. if (fieldType->IsVoid())
  12999. {
  13000. typedValues.push_back(BfTypedValue());
  13001. continue;
  13002. }
  13003. if (fieldType->IsVar())
  13004. {
  13005. hadFullMatch = false;
  13006. fieldType = NULL;
  13007. }
  13008. }
  13009. }
  13010. bool tryDefer = false;
  13011. if (((fieldType == NULL) || (fieldType->IsComposite())) &&
  13012. ((valueExpr->IsA<BfInvocationExpression>()) || (valueExpr->IsExact<BfTupleExpression>())))
  13013. {
  13014. tryDefer = true;
  13015. }
  13016. SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, mModule->mBfIRBuilder->mIgnoreWrites || tryDefer);
  13017. BfTypedValue value = mModule->CreateValueFromExpression(valueExpr, fieldType);
  13018. if (!value)
  13019. {
  13020. if (fieldType != NULL)
  13021. value = mModule->GetDefaultTypedValue(fieldType);
  13022. else
  13023. value = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  13024. }
  13025. if ((fieldInstance != NULL) && (!fieldInstance->GetFieldDef()->IsUnnamedTupleField()) && (valueIdx < (int)tupleExpr->mNames.size()))
  13026. {
  13027. auto checkName = tupleExpr->mNames[valueIdx];
  13028. if (checkName != NULL)
  13029. {
  13030. if (checkName->ToString() != fieldInstance->GetFieldDef()->mName)
  13031. hadFullMatch = false;
  13032. }
  13033. }
  13034. value = mModule->LoadValue(value);
  13035. typedValues.push_back(value);
  13036. }
  13037. if (!hadFullMatch)
  13038. {
  13039. BfTypeVector fieldTypes;
  13040. Array<String> fieldNames;
  13041. for (auto typedVal : typedValues)
  13042. {
  13043. auto type = typedVal.mType;
  13044. if (type != NULL)
  13045. fieldTypes.push_back(type);
  13046. else
  13047. fieldTypes.push_back(mModule->mContext->mBfObjectType);
  13048. }
  13049. for (BfTupleNameNode* requestedName : tupleExpr->mNames)
  13050. {
  13051. if (requestedName == NULL)
  13052. fieldNames.push_back("");
  13053. else
  13054. fieldNames.push_back(requestedName->mNameNode->ToString());
  13055. }
  13056. tupleType = mModule->CreateTupleType(fieldTypes, fieldNames);
  13057. }
  13058. mModule->mBfIRBuilder->PopulateType(tupleType);
  13059. BfIRValue curTupleValue;
  13060. if ((mReceivingValue != NULL) && (mReceivingValue->mType == tupleType) && (mReceivingValue->IsAddr()))
  13061. {
  13062. mResult = *mReceivingValue;
  13063. mReceivingValue = NULL;
  13064. curTupleValue = mResult.mValue;
  13065. }
  13066. else
  13067. {
  13068. curTupleValue = mModule->CreateAlloca(tupleType);
  13069. mResultIsTempComposite = true;
  13070. mResult = BfTypedValue(curTupleValue, tupleType, BfTypedValueKind_TempAddr);
  13071. }
  13072. for (int valueIdx = 0; valueIdx < (int)typedValues.size(); valueIdx++)
  13073. {
  13074. BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[valueIdx];
  13075. if (fieldInstance->mResolvedType->IsValuelessType())
  13076. continue;
  13077. auto typedVal = typedValues[valueIdx];
  13078. if (!typedVal)
  13079. {
  13080. mModule->AssertErrorState();
  13081. continue;
  13082. }
  13083. if (fieldInstance->mDataIdx >= 0)
  13084. {
  13085. auto memberVal = mModule->mBfIRBuilder->CreateInBoundsGEP(curTupleValue, 0, fieldInstance->mDataIdx);
  13086. if ((!mModule->mBfIRBuilder->mIgnoreWrites) && (typedVal.mValue.IsFake()))
  13087. {
  13088. // Value was deferred. Allow us to try to init in place
  13089. BfExpression* valueExpr = tupleExpr->mValues[valueIdx];
  13090. BfTypedValue memberPtrTypedVal = BfTypedValue(memberVal, fieldInstance->mResolvedType, BfTypedValueKind_Addr);
  13091. BfExprEvaluator exprEvaluator(mModule);
  13092. exprEvaluator.mExpectingType = fieldInstance->mResolvedType;
  13093. exprEvaluator.mReceivingValue = &memberPtrTypedVal;
  13094. exprEvaluator.Evaluate(valueExpr);
  13095. exprEvaluator.GetResult();
  13096. if (exprEvaluator.mReceivingValue == NULL)
  13097. {
  13098. // We wrote directly to the array in-place, we're done with this element
  13099. continue;
  13100. }
  13101. typedVal = exprEvaluator.mResult;
  13102. typedVal = mModule->Cast(valueExpr, typedVal, fieldInstance->mResolvedType);
  13103. if (!typedVal)
  13104. {
  13105. mModule->AssertErrorState();
  13106. continue;
  13107. }
  13108. typedVal = mModule->LoadValue(typedVal);
  13109. }
  13110. if (typedVal.IsSplat())
  13111. mModule->AggregateSplatIntoAddr(typedVal, memberVal);
  13112. else
  13113. mModule->mBfIRBuilder->CreateStore(typedVal.mValue, memberVal);
  13114. }
  13115. }
  13116. }
  13117. BfTypedValue BfExprEvaluator::SetupNullConditional(BfTypedValue thisValue, BfTokenNode* dotToken)
  13118. {
  13119. bool isStaticLookup = (!thisValue) ||
  13120. ((!thisValue.mType->IsValuelessType()) && (!thisValue.mValue));
  13121. if (isStaticLookup)
  13122. {
  13123. mModule->Fail("Null conditional reference not valid for static field references", dotToken);
  13124. return thisValue;
  13125. }
  13126. //TODO: But make null conditional work for Nullable types
  13127. if (thisValue.mType->IsNullable())
  13128. {
  13129. // Success
  13130. }
  13131. else if ((thisValue.mType->IsPointer()) || (thisValue.mType->IsObjectOrInterface()))
  13132. {
  13133. // Also good
  13134. }
  13135. else
  13136. {
  13137. if (thisValue.mType->IsStruct())
  13138. mModule->Warn(0, "Struct lookups can never fail, null conditional reference is unnecessary", dotToken);
  13139. else
  13140. mModule->AssertErrorState();
  13141. return thisValue;
  13142. }
  13143. thisValue = mModule->LoadValue(thisValue);
  13144. BfPendingNullConditional* pendingNullCond = mModule->mCurMethodState->mPendingNullConditional;
  13145. if (pendingNullCond == NULL)
  13146. {
  13147. pendingNullCond = new BfPendingNullConditional();
  13148. mModule->mCurMethodState->mPendingNullConditional = pendingNullCond;
  13149. }
  13150. if (!pendingNullCond->mPrevBB)
  13151. pendingNullCond->mPrevBB = mModule->mBfIRBuilder->GetInsertBlock();
  13152. if (!pendingNullCond->mDoneBB)
  13153. pendingNullCond->mDoneBB = mModule->mBfIRBuilder->CreateBlock("nullCond.done");
  13154. // We will in the br to checkBB later
  13155. if (!pendingNullCond->mCheckBB)
  13156. {
  13157. pendingNullCond->mCheckBB = mModule->mBfIRBuilder->CreateBlock("nullCond.check");
  13158. mModule->AddBasicBlock(pendingNullCond->mCheckBB);
  13159. }
  13160. BfIRValue isNotNull;
  13161. if (thisValue.mType->IsNullable())
  13162. {
  13163. BfGenericTypeInstance* nullableType = (BfGenericTypeInstance*)thisValue.mType->ToTypeInstance();
  13164. auto elementType = nullableType->GetUnderlyingType();
  13165. if (elementType->IsValuelessType())
  13166. {
  13167. thisValue = mModule->MakeAddressable(thisValue);
  13168. BfIRValue hasValuePtr = mModule->mBfIRBuilder->CreateInBoundsGEP(thisValue.mValue, 0, 1); // mHasValue
  13169. isNotNull = mModule->mBfIRBuilder->CreateLoad(hasValuePtr);
  13170. thisValue = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), elementType, true);
  13171. }
  13172. else
  13173. {
  13174. thisValue = mModule->MakeAddressable(thisValue);
  13175. BfIRValue hasValuePtr = mModule->mBfIRBuilder->CreateInBoundsGEP(thisValue.mValue, 0, 2); // mHasValue
  13176. isNotNull = mModule->mBfIRBuilder->CreateLoad(hasValuePtr);
  13177. BfIRValue valuePtr = mModule->mBfIRBuilder->CreateInBoundsGEP(thisValue.mValue, 0, 1); // mValue
  13178. thisValue = BfTypedValue(valuePtr, elementType, true);
  13179. }
  13180. }
  13181. else
  13182. isNotNull = mModule->mBfIRBuilder->CreateIsNotNull(thisValue.mValue);
  13183. BfIRBlock notNullBB = mModule->mBfIRBuilder->CreateBlock("nullCond.notNull");
  13184. mModule->mBfIRBuilder->CreateCondBr(isNotNull, notNullBB, pendingNullCond->mDoneBB);
  13185. mModule->AddBasicBlock(notNullBB);
  13186. return thisValue;
  13187. }
  13188. void BfExprEvaluator::CheckDotToken(BfTokenNode* tokenNode)
  13189. {
  13190. if ((tokenNode != NULL) && (tokenNode->mToken == BfToken_DotDot))
  13191. mModule->Fail("Unexpected cascade operation. Chaining can only be used for method invocations", tokenNode);
  13192. }
  13193. void BfExprEvaluator::DoMemberReference(BfMemberReferenceExpression* memberRefExpr, BfTypedValue* outCascadeValue)
  13194. {
  13195. CheckDotToken(memberRefExpr->mDotToken);
  13196. BfAttributeState attributeState;
  13197. attributeState.mTarget = (BfAttributeTargets)(BfAttributeTargets_MemberAccess);
  13198. String findName;
  13199. BfAstNode* nameRefNode = memberRefExpr->mMemberName;
  13200. if (auto attrIdentifierExpr = BfNodeDynCast<BfAttributedIdentifierNode>(memberRefExpr->mMemberName))
  13201. {
  13202. nameRefNode = attrIdentifierExpr->mIdentifier;
  13203. // Don't validate
  13204. attributeState.mCustomAttributes = mModule->GetCustomAttributes(attrIdentifierExpr->mAttributes, BfAttributeTargets_SkipValidate);
  13205. if (nameRefNode != NULL)
  13206. findName = attrIdentifierExpr->mIdentifier->ToString();
  13207. }
  13208. else if (memberRefExpr->mMemberName != NULL)
  13209. findName = memberRefExpr->mMemberName->ToString();
  13210. defer
  13211. {
  13212. if (attributeState.mCustomAttributes != NULL)
  13213. {
  13214. if (mPropDef != NULL)
  13215. attributeState.mTarget = BfAttributeTargets_Invocation;
  13216. mModule->ValidateCustomAttributes(attributeState.mCustomAttributes, attributeState.mTarget);
  13217. }
  13218. };
  13219. SetAndRestoreValue<BfAttributeState*> prevAttributeState(mModule->mAttributeState, &attributeState);
  13220. BfTypeInstance* expectingTypeInst = NULL;
  13221. if (mExpectingType != NULL)
  13222. {
  13223. expectingTypeInst = mExpectingType->ToTypeInstance();
  13224. if (mExpectingType->IsPointer())
  13225. expectingTypeInst = mExpectingType->GetUnderlyingType()->ToTypeInstance();
  13226. else if (mExpectingType->IsNullable())
  13227. expectingTypeInst = mExpectingType->GetUnderlyingType()->ToTypeInstance();
  13228. else if (mExpectingType->IsConstExprValue())
  13229. expectingTypeInst = mExpectingType->GetUnderlyingType()->ToTypeInstance();
  13230. else if (mExpectingType->IsGenericParam())
  13231. {
  13232. auto genericParam = mModule->GetGenericParamInstance((BfGenericParamType*)mExpectingType);
  13233. if (genericParam->mTypeConstraint != NULL)
  13234. expectingTypeInst = genericParam->mTypeConstraint->ToTypeInstance();
  13235. }
  13236. }
  13237. BfAutoComplete* autoComplete = GetAutoComplete();
  13238. if (autoComplete != NULL)
  13239. {
  13240. SetAndRestoreValue<bool> prevFriendSet(autoComplete->mHasFriendSet, (attributeState.mCustomAttributes != NULL) && (attributeState.mCustomAttributes->Contains(mModule->mCompiler->mFriendAttributeTypeDef)));
  13241. if (memberRefExpr->mTarget == NULL)
  13242. {
  13243. String filter;
  13244. if ((mExpectingType != NULL) &&
  13245. (autoComplete->InitAutocomplete(memberRefExpr->mDotToken, memberRefExpr->mMemberName, filter)))
  13246. {
  13247. if (expectingTypeInst != NULL)
  13248. {
  13249. bool allowPrivate = expectingTypeInst == mModule->mCurTypeInstance;
  13250. if (expectingTypeInst->IsEnum())
  13251. autoComplete->AddEnumTypeMembers(expectingTypeInst, filter, false, allowPrivate);
  13252. autoComplete->AddSelfResultTypeMembers(expectingTypeInst, expectingTypeInst, filter, allowPrivate);
  13253. }
  13254. }
  13255. }
  13256. else
  13257. {
  13258. autoComplete->CheckMemberReference(memberRefExpr->mTarget, memberRefExpr->mDotToken, memberRefExpr->mMemberName);
  13259. if (auto objCreateExpr = BfNodeDynCast<BfObjectCreateExpression>(memberRefExpr->mTarget))
  13260. {
  13261. // This handles a weird case where we have "obj a = new\nWhatever().Thing = 123;".
  13262. // That gets parsed as "Whatever()" being the type we want to create, and then referencing
  13263. // the "Thing" member of that new object.
  13264. //if (objCreateExpr->mArraySizeSpecifier == NULL)
  13265. CheckObjectCreateTypeRef(mExpectingType, objCreateExpr->mNewNode);
  13266. }
  13267. }
  13268. }
  13269. if (memberRefExpr->mTarget == NULL)
  13270. {
  13271. if (mExpectingType == NULL)
  13272. {
  13273. mModule->Fail("Unqualified dot syntax can only be used when the result type can be inferred", nameRefNode);
  13274. return;
  13275. }
  13276. if (expectingTypeInst == NULL)
  13277. {
  13278. mModule->Fail(StrFormat("Unqualified dot syntax cannot be used with type '%s'", mModule->TypeToString(mExpectingType).c_str()), nameRefNode);
  13279. return;
  13280. }
  13281. if (mExpectingType->IsVar())
  13282. {
  13283. mResult = mModule->GetDefaultTypedValue(mExpectingType);
  13284. return;
  13285. }
  13286. BfTypedValue expectingVal(expectingTypeInst);
  13287. mResult = LookupField(memberRefExpr->mMemberName, expectingVal, findName);
  13288. if ((mResult) || (mPropDef != NULL))
  13289. return;
  13290. }
  13291. bool isNullCondLookup = (memberRefExpr->mDotToken != NULL) && (memberRefExpr->mDotToken->GetToken() == BfToken_QuestionDot);
  13292. bool isCascade = ((memberRefExpr->mDotToken != NULL) && (memberRefExpr->mDotToken->GetToken() == BfToken_DotDot));
  13293. BfIdentifierNode* nameLeft = BfNodeDynCast<BfIdentifierNode>(memberRefExpr->mTarget);
  13294. BfIdentifierNode* nameRight = BfIdentifierCast(memberRefExpr->mMemberName);
  13295. if ((nameLeft != NULL) && (nameRight != NULL) && (!isNullCondLookup) && (!isCascade))
  13296. {
  13297. bool hadError = false;
  13298. LookupQualifiedName(memberRefExpr, nameLeft, nameRight, true, &hadError);
  13299. if ((mResult) || (mPropDef != NULL))
  13300. return;
  13301. if (hadError)
  13302. return;
  13303. LookupQualifiedStaticField(memberRefExpr, nameLeft, nameRight, false);
  13304. return;
  13305. }
  13306. BfTypedValue thisValue;
  13307. if (auto exprTarget = BfNodeDynCast<BfExpression>(memberRefExpr->mTarget))
  13308. {
  13309. if (auto typeOfExpr = BfNodeDynCast<BfTypeOfExpression>(memberRefExpr->mTarget))
  13310. {
  13311. if (auto nameIdentifer = BfNodeDynCast<BfIdentifierNode>(memberRefExpr->mMemberName))
  13312. {
  13313. if (LookupTypeProp(typeOfExpr, nameIdentifer))
  13314. return;
  13315. }
  13316. }
  13317. //Hm, not using VisitChild broke our ability to write to a field for a not-initialized local struct
  13318. VisitChild(memberRefExpr->mTarget);
  13319. GetResult();
  13320. thisValue = mResult;
  13321. if (!thisValue)
  13322. {
  13323. if (auto targetIdentifier = BfNodeDynCast<BfIdentifierNode>(exprTarget))
  13324. thisValue = BfTypedValue(mModule->ResolveTypeRef(targetIdentifier, NULL));
  13325. }
  13326. if (!thisValue.HasType())
  13327. return;
  13328. //thisValue = mResult;
  13329. }
  13330. else if (auto typeRef = BfNodeDynCast<BfTypeReference>(memberRefExpr->mTarget))
  13331. {
  13332. // Look up static field
  13333. thisValue = BfTypedValue(ResolveTypeRef(typeRef));
  13334. }
  13335. if (nameRefNode == NULL)
  13336. {
  13337. mModule->AssertErrorState();
  13338. return;
  13339. }
  13340. if (isNullCondLookup)
  13341. thisValue = SetupNullConditional(thisValue, memberRefExpr->mDotToken);
  13342. mResult = LookupField(nameRefNode, thisValue, findName);
  13343. if ((!mResult) && (mPropDef == NULL))
  13344. {
  13345. if (thisValue.mType != NULL)
  13346. {
  13347. BfTypeInstance* typeInst = thisValue.mType->ToTypeInstance();
  13348. auto compiler = mModule->mCompiler;
  13349. if ((typeInst != NULL) && (compiler->IsAutocomplete()) && (compiler->mResolvePassData->mAutoComplete->CheckFixit(memberRefExpr->mMemberName)))
  13350. {
  13351. FixitAddMember(typeInst, mExpectingType, findName, !thisValue.mValue);
  13352. }
  13353. }
  13354. if ((!thisValue.mValue) && (thisValue.mType != NULL))
  13355. {
  13356. if (auto targetIdentifier = BfNodeDynCast<BfIdentifierNode>(memberRefExpr->mMemberName))
  13357. {
  13358. mResult.mType = mModule->ResolveInnerType(thisValue.mType, targetIdentifier, BfPopulateType_Declaration);
  13359. }
  13360. }
  13361. if (mResult.mType == NULL)
  13362. mModule->Fail("Unable to find member", nameRefNode);
  13363. }
  13364. if (isNullCondLookup)
  13365. mResult = GetResult();
  13366. if (isCascade)
  13367. {
  13368. if (outCascadeValue != NULL)
  13369. *outCascadeValue = thisValue;
  13370. else
  13371. mModule->Fail("Unexpected cascade operation. Chaining can only be used for method invocations", memberRefExpr->mDotToken);
  13372. }
  13373. }
  13374. void BfExprEvaluator::Visit(BfMemberReferenceExpression* memberRefExpr)
  13375. {
  13376. DoMemberReference(memberRefExpr, NULL);
  13377. }
  13378. void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr)
  13379. {
  13380. VisitChild(indexerExpr->mTarget);
  13381. ResolveGenericType();
  13382. auto target = GetResult(true);
  13383. if (!target)
  13384. return;
  13385. BfCheckedKind checkedKind = BfCheckedKind_NotSet;
  13386. bool isInlined = false;
  13387. if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL))
  13388. {
  13389. if (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mInlineAttributeTypeDef))
  13390. {
  13391. isInlined = true;
  13392. mModule->mAttributeState->mUsed = true;
  13393. }
  13394. if (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mCheckedAttributeTypeDef))
  13395. {
  13396. checkedKind = BfCheckedKind_Checked;
  13397. mModule->mAttributeState->mUsed = true;
  13398. }
  13399. if (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mUncheckedAttributeTypeDef))
  13400. {
  13401. checkedKind = BfCheckedKind_Unchecked;
  13402. mModule->mAttributeState->mUsed = true;
  13403. }
  13404. }
  13405. bool isNullCondLookup = (indexerExpr->mOpenBracket != NULL) && (indexerExpr->mOpenBracket->GetToken() == BfToken_QuestionLBracket);
  13406. if (isNullCondLookup)
  13407. target = SetupNullConditional(target, indexerExpr->mOpenBracket);
  13408. if (target.mType->IsVar())
  13409. {
  13410. mResult = BfTypedValue(mModule->GetDefaultValue(target.mType), target.mType, true);
  13411. return;
  13412. }
  13413. if (target.mType->IsTypeInstance())
  13414. {
  13415. mIndexerValues.clear();
  13416. for (BfExpression* expr : indexerExpr->mArguments)
  13417. {
  13418. if (expr == NULL)
  13419. return;
  13420. auto argVal = mModule->CreateValueFromExpression(expr);
  13421. if (!argVal)
  13422. {
  13423. mModule->AssertErrorState();
  13424. argVal = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
  13425. }
  13426. BfResolvedArg resolvedArg;
  13427. resolvedArg.mTypedValue = argVal;
  13428. mIndexerValues.push_back(resolvedArg);
  13429. }
  13430. BfMethodMatcher methodMatcher(indexerExpr->mTarget, mModule, "[]", mIndexerValues, NULL);
  13431. methodMatcher.mCheckedKind = checkedKind;
  13432. //methodMatcher.CheckType(target.mType->ToTypeInstance(), target, false);
  13433. BfMethodDef* methodDef = NULL;
  13434. auto startCheckTypeInst = target.mType->ToTypeInstance();
  13435. for (int pass = 0; pass < 2; pass++)
  13436. {
  13437. bool isFailurePass = pass == 1;
  13438. auto curCheckType = startCheckTypeInst;
  13439. while (curCheckType != NULL)
  13440. {
  13441. BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None;
  13442. BfPropertyDef* foundProp = NULL;
  13443. BfTypeInstance* foundPropTypeInst = NULL;
  13444. int matchedIndexCount = 0;
  13445. curCheckType->mTypeDef->PopulateMemberSets();
  13446. BfMemberSetEntry* entry;
  13447. BfPropertyDef* matchedProp = NULL;
  13448. BfPropertyDef* nextProp = NULL;
  13449. if (curCheckType->mTypeDef->mPropertySet.TryGetWith(String("[]"), &entry))
  13450. nextProp = (BfPropertyDef*)entry->mMemberDef;
  13451. while (nextProp != NULL)
  13452. {
  13453. auto prop = nextProp;
  13454. nextProp = nextProp->mNextWithSameName;
  13455. //TODO: Match against setMethod (minus last param) if we have no 'get' method
  13456. for (auto checkMethod : prop->mMethods)
  13457. {
  13458. if (checkMethod->mMethodType != BfMethodType_PropertyGetter)
  13459. continue;
  13460. // For generic params - check interface constraints for an indexer, call that method
  13461. BF_ASSERT(!target.mType->IsGenericParam());
  13462. if (checkMethod->mExplicitInterface != NULL)
  13463. continue;
  13464. if (checkMethod->mIsOverride)
  13465. continue;
  13466. auto autoComplete = GetAutoComplete();
  13467. bool wasCapturingMethodMatchInfo = false;
  13468. if (autoComplete != NULL)
  13469. {
  13470. // Set to false to make sure we don't capture method match info from 'params' array creation
  13471. wasCapturingMethodMatchInfo = autoComplete->mIsCapturingMethodMatchInfo;
  13472. autoComplete->mIsCapturingMethodMatchInfo = false;
  13473. }
  13474. defer
  13475. {
  13476. if (autoComplete != NULL)
  13477. autoComplete->mIsCapturingMethodMatchInfo = wasCapturingMethodMatchInfo;
  13478. };
  13479. if ((!isFailurePass) && (!methodMatcher.WantsCheckMethod(protectionCheckFlags, startCheckTypeInst, curCheckType, checkMethod)))
  13480. continue;
  13481. methodMatcher.mCheckedKind = checkedKind;
  13482. methodMatcher.CheckMethod(curCheckType, checkMethod, false);
  13483. if ((methodMatcher.mBestMethodDef == checkMethod) ||
  13484. ((foundProp == NULL) && (methodMatcher.mBackupMethodDef == checkMethod)))
  13485. {
  13486. foundPropTypeInst = curCheckType;
  13487. foundProp = prop;
  13488. matchedIndexCount = (int)checkMethod->mParams.size();
  13489. }
  13490. }
  13491. }
  13492. if (foundProp != NULL)
  13493. {
  13494. int indexDiff = matchedIndexCount - (int)mIndexerValues.size();
  13495. if (indexDiff > 0)
  13496. {
  13497. mModule->Fail(StrFormat("Expected %d more indices", indexDiff), indexerExpr->mTarget);
  13498. //mModule->mCompiler->mPassInstance->MoreInfo("See method declaration", methodInstance->mMethodDef->mMethodDeclaration);
  13499. }
  13500. else if (indexDiff < 0)
  13501. {
  13502. mModule->Fail(StrFormat("Expected %d fewer indices", indexDiff), indexerExpr->mTarget);
  13503. }
  13504. else
  13505. {
  13506. mPropSrc = indexerExpr->mOpenBracket;
  13507. mPropDef = foundProp;
  13508. if (foundProp->mIsStatic)
  13509. {
  13510. mPropTarget = BfTypedValue(curCheckType);
  13511. }
  13512. else
  13513. {
  13514. if (target.mType != foundPropTypeInst)
  13515. mPropTarget = mModule->Cast(indexerExpr->mTarget, target, foundPropTypeInst);
  13516. else
  13517. mPropTarget = target;
  13518. }
  13519. mOrigPropTarget = mPropTarget;
  13520. if (isInlined)
  13521. mPropGetMethodFlags = (BfGetMethodInstanceFlags)(mPropGetMethodFlags | BfGetMethodInstanceFlag_ForceInline);
  13522. mPropCheckedKind = checkedKind;
  13523. }
  13524. return;
  13525. }
  13526. curCheckType = curCheckType->mBaseType;
  13527. }
  13528. }
  13529. mModule->Fail("Unable to find indexer property", indexerExpr->mTarget);
  13530. return;
  13531. }
  13532. //target.mType = mModule->ResolveGenericType(target.mType);
  13533. if (target.mType->IsVar())
  13534. {
  13535. mResult = target;
  13536. return;
  13537. }
  13538. if ((!target.mType->IsPointer()) && (!target.mType->IsSizedArray()))
  13539. {
  13540. mModule->Fail("Expected pointer or array type", indexerExpr->mTarget);
  13541. return;
  13542. }
  13543. auto _GetDefaultResult = [&]()
  13544. {
  13545. return mModule->GetDefaultTypedValue(target.mType->GetUnderlyingType(), false, BfDefaultValueKind_Addr);
  13546. };
  13547. if (indexerExpr->mArguments.size() != 1)
  13548. {
  13549. mModule->Fail("Expected single index", indexerExpr->mOpenBracket);
  13550. mResult = _GetDefaultResult();
  13551. return;
  13552. }
  13553. if (indexerExpr->mArguments[0] == NULL)
  13554. {
  13555. mModule->AssertErrorState();
  13556. mResult = _GetDefaultResult();
  13557. return;
  13558. }
  13559. bool isUndefIndex = false;
  13560. auto indexArgument = mModule->CreateValueFromExpression(indexerExpr->mArguments[0]);
  13561. if (!indexArgument)
  13562. return;
  13563. if (!indexArgument.mType->IsIntegral())
  13564. {
  13565. if (indexArgument.mType->IsVar())
  13566. {
  13567. isUndefIndex = true;
  13568. indexArgument = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_IntPtr), false, BfDefaultValueKind_Undef);
  13569. }
  13570. else
  13571. {
  13572. mModule->Fail("Expected integer index", indexerExpr->mArguments[0]);
  13573. indexArgument = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_IntPtr));
  13574. }
  13575. }
  13576. if (indexArgument.mType->IsPrimitiveType())
  13577. {
  13578. auto primType = (BfPrimitiveType*)indexArgument.mType;
  13579. if ((!primType->IsSigned()) && (primType->mSize < 8))
  13580. {
  13581. // GEP will always do a signed upcast so we need to cast manually if we are unsigned
  13582. indexArgument = BfTypedValue(mModule->mBfIRBuilder->CreateNumericCast(indexArgument.mValue, false, BfTypeCode_IntPtr), mModule->GetPrimitiveType(BfTypeCode_IntPtr));
  13583. }
  13584. }
  13585. mModule->PopulateType(target.mType);
  13586. if (target.mType->IsSizedArray())
  13587. {
  13588. BfSizedArrayType* sizedArrayType = (BfSizedArrayType*)target.mType;
  13589. auto underlyingType = sizedArrayType->mElementType;
  13590. if (indexArgument.mValue.IsConst())
  13591. {
  13592. auto indexConst = mModule->mBfIRBuilder->GetConstant(indexArgument.mValue);
  13593. if (indexConst->mUInt64 >= (uint64)sizedArrayType->mElementCount)
  13594. {
  13595. mModule->Fail(StrFormat("Index '%d' is out of bounds for type '%s'", indexConst->mInt32, mModule->TypeToString(target.mType).c_str()), indexerExpr->mArguments[0]);
  13596. mResult = _GetDefaultResult();
  13597. return;
  13598. }
  13599. }
  13600. else if (mModule->HasCompiledOutput())
  13601. {
  13602. if (checkedKind == BfCheckedKind_NotSet)
  13603. checkedKind = mModule->GetDefaultCheckedKind();
  13604. if (checkedKind == BfCheckedKind_Checked)
  13605. {
  13606. auto oobBlock = mModule->mBfIRBuilder->CreateBlock("oob", true);
  13607. auto contBlock = mModule->mBfIRBuilder->CreateBlock("cont", true);
  13608. auto indexType = (BfPrimitiveType*)indexArgument.mType;
  13609. if (!mModule->mSystem->DoesLiteralFit(indexType->mTypeDef->mTypeCode, sizedArrayType->mElementCount))
  13610. {
  13611. // We need to upsize the index so we can compare it against the larger elementCount
  13612. indexType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  13613. indexArgument = mModule->Cast(indexerExpr->mArguments[0], indexArgument, indexType);
  13614. }
  13615. auto cmpRes = mModule->mBfIRBuilder->CreateCmpGTE(indexArgument.mValue, mModule->mBfIRBuilder->CreateConst(indexType->mTypeDef->mTypeCode, (uint64)sizedArrayType->mElementCount), false);
  13616. mModule->mBfIRBuilder->CreateCondBr(cmpRes, oobBlock, contBlock);
  13617. mModule->mBfIRBuilder->SetInsertPoint(oobBlock);
  13618. auto internalType = mModule->ResolveTypeDef(mModule->mCompiler->mInternalTypeDef);
  13619. auto oobFunc = mModule->GetMethodByName(internalType->ToTypeInstance(), "ThrowIndexOutOfRange");
  13620. if (oobFunc.mFunc)
  13621. {
  13622. /*if (!mModule->mCompiler->mIsResolveOnly)
  13623. {
  13624. OutputDebugStrF("-OOB %d %d\n", oobFunc.mFunc.mId, oobFunc.mFunc.mFlags);
  13625. }*/
  13626. SizedArray<BfIRValue, 1> args;
  13627. args.push_back(mModule->GetConstValue(0));
  13628. mModule->mBfIRBuilder->CreateCall(oobFunc.mFunc, args);
  13629. mModule->mBfIRBuilder->CreateUnreachable();
  13630. mModule->mBfIRBuilder->SetInsertPoint(contBlock);
  13631. }
  13632. else
  13633. {
  13634. mModule->Fail("System.Internal class must contain method 'ThrowIndexOutOfRange'");
  13635. }
  13636. }
  13637. }
  13638. // If this is a 'bag of bytes', we should try hard not to have to make this addressable
  13639. if ((!target.IsAddr()) && (!target.mType->IsSizeAligned()))
  13640. mModule->MakeAddressable(target);
  13641. mModule->PopulateType(underlyingType);
  13642. if (sizedArrayType->IsUnknownSizedArray())
  13643. {
  13644. mResult = mModule->GetDefaultTypedValue(underlyingType);
  13645. }
  13646. else if (sizedArrayType->IsValuelessType())
  13647. {
  13648. if (underlyingType->IsValuelessType())
  13649. mResult = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), underlyingType, true);
  13650. else
  13651. {
  13652. mResult = mModule->GetDefaultTypedValue(underlyingType);
  13653. if (sizedArrayType->mElementCount != 0)
  13654. mModule->AssertErrorState();
  13655. }
  13656. }
  13657. else if (target.IsAddr())
  13658. {
  13659. if (target.mType->IsSizeAligned())
  13660. {
  13661. auto ptrType = mModule->CreatePointerType(underlyingType);
  13662. auto ptrValue = mModule->mBfIRBuilder->CreateBitCast(target.mValue, mModule->mBfIRBuilder->MapType(ptrType));
  13663. auto gepResult = mModule->mBfIRBuilder->CreateInBoundsGEP(ptrValue, indexArgument.mValue);
  13664. mResult = BfTypedValue(gepResult, underlyingType, target.IsReadOnly() ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
  13665. }
  13666. else
  13667. {
  13668. auto indexResult = mModule->CreateIndexedValue(underlyingType, target.mValue, indexArgument.mValue);
  13669. mResult = BfTypedValue(indexResult, underlyingType, target.IsReadOnly() ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
  13670. }
  13671. }
  13672. else
  13673. {
  13674. if ((!target.mValue.IsConst()) && (!indexArgument.mValue.IsConst()))
  13675. {
  13676. mModule->Fail("Unable to index value", indexerExpr->mTarget);
  13677. return;
  13678. }
  13679. mModule->mBfIRBuilder->PopulateType(target.mType);
  13680. auto gepResult = mModule->mBfIRBuilder->CreateExtractValue(target.mValue, indexArgument.mValue);
  13681. if ((underlyingType->IsString()) || (underlyingType->IsPointer()))
  13682. {
  13683. auto resultConst = mModule->mBfIRBuilder->GetConstant(gepResult);
  13684. if ((resultConst != NULL) && (resultConst->mTypeCode == BfTypeCode_Int32))
  13685. {
  13686. int strId = resultConst->mInt32;
  13687. const StringImpl& str = mModule->mContext->mStringObjectIdMap[strId].mString;
  13688. if (underlyingType->IsString())
  13689. gepResult = mModule->GetStringObjectValue(str, false);
  13690. else
  13691. gepResult = mModule->GetStringCharPtr(strId);
  13692. }
  13693. }
  13694. mResult = BfTypedValue(gepResult, underlyingType, BfTypedValueKind_Value);
  13695. }
  13696. }
  13697. else
  13698. {
  13699. target = mModule->LoadValue(target);
  13700. BfPointerType* pointerType = (BfPointerType*)target.mType;
  13701. auto underlyingType = pointerType->mElementType;
  13702. mModule->mBfIRBuilder->PopulateType(underlyingType);
  13703. if (isUndefIndex)
  13704. {
  13705. mResult = mModule->GetDefaultTypedValue(underlyingType, false, BfDefaultValueKind_Addr);
  13706. }
  13707. else
  13708. {
  13709. BfIRValue result = mModule->CreateIndexedValue(underlyingType, target.mValue, indexArgument.mValue);
  13710. mResult = BfTypedValue(result, underlyingType, true);
  13711. }
  13712. }
  13713. }
  13714. void BfExprEvaluator::Visit(BfUnaryOperatorExpression* unaryOpExpr)
  13715. {
  13716. BfAutoParentNodeEntry autoParentNodeEntry(mModule, unaryOpExpr);
  13717. PerformUnaryOperation(unaryOpExpr->mExpression, unaryOpExpr->mOp, unaryOpExpr->mOpToken);
  13718. }
  13719. void BfExprEvaluator::PerformUnaryOperation(BfExpression* unaryOpExpr, BfUnaryOp unaryOp, BfTokenNode* opToken)
  13720. {
  13721. {
  13722. // If this is a cast, we don't want the value to be coerced before the unary operator is applied.
  13723. // WAIT: Why not?
  13724. //SetAndRestoreValue<BfType*> prevExpectingType(mExpectingType, NULL);
  13725. BfType* prevExpedcting = mExpectingType;
  13726. switch (unaryOp)
  13727. {
  13728. case BfUnaryOp_Negate:
  13729. case BfUnaryOp_Positive:
  13730. case BfUnaryOp_InvertBits:
  13731. // If we're expecting an int64 or uint64 then just leave the type as unknown
  13732. if ((mExpectingType != NULL) && (mExpectingType->IsInteger()) && (mExpectingType->mSize == 8))
  13733. mExpectingType = NULL;
  13734. // Otherwise keep expecting type
  13735. break;
  13736. default:
  13737. mExpectingType = NULL;
  13738. }
  13739. VisitChild(unaryOpExpr);
  13740. mExpectingType = prevExpedcting;
  13741. }
  13742. BfAstNode* propSrc = mPropSrc;
  13743. BfTypedValue propTarget = mPropTarget;
  13744. BfPropertyDef* propDef = mPropDef;
  13745. SizedArray<BfResolvedArg, 2> indexerVals = mIndexerValues;
  13746. BfTypedValue writeToProp;
  13747. GetResult();
  13748. if (!mResult)
  13749. return;
  13750. if (mResult.mType->IsRef())
  13751. mResult.mType = mResult.mType->GetUnderlyingType();
  13752. if (mResult.mType->IsVar())
  13753. {
  13754. mResult = BfTypedValue(mModule->GetDefaultValue(mResult.mType), mResult.mType);
  13755. return;
  13756. }
  13757. if ((mResult.mType->IsTypeInstance()) || (mResult.mType->IsGenericParam()))
  13758. {
  13759. SizedArray<BfResolvedArg, 1> args;
  13760. BfResolvedArg resolvedArg;
  13761. resolvedArg.mTypedValue = mResult;
  13762. args.push_back(resolvedArg);
  13763. BfMethodMatcher methodMatcher(opToken, mModule, "", args, NULL);
  13764. BfBaseClassWalker baseClassWalker(mResult.mType, NULL, mModule);
  13765. BfUnaryOp findOp = unaryOp;
  13766. bool isPostOp = false;
  13767. if (findOp == BfUnaryOp_PostIncrement)
  13768. {
  13769. findOp = BfUnaryOp_Increment;
  13770. isPostOp = true;
  13771. }
  13772. if (findOp == BfUnaryOp_PostDecrement)
  13773. {
  13774. findOp = BfUnaryOp_Decrement;
  13775. isPostOp = true;
  13776. }
  13777. BfType* bestSelfType = NULL;
  13778. while (true)
  13779. {
  13780. auto entry = baseClassWalker.Next();
  13781. auto checkType = entry.mTypeInstance;
  13782. if (checkType == NULL)
  13783. break;
  13784. for (auto operatorDef : checkType->mTypeDef->mOperators)
  13785. {
  13786. if (operatorDef->mOperatorDeclaration->mUnaryOp == findOp)
  13787. if (methodMatcher.CheckMethod(checkType, operatorDef, false))
  13788. methodMatcher.mSelfType = entry.mSrcType;
  13789. }
  13790. }
  13791. if (methodMatcher.mBestMethodDef != NULL)
  13792. {
  13793. if (!baseClassWalker.mMayBeFromInterface)
  13794. mModule->SetElementType(opToken, BfSourceElementType_Method);
  13795. auto methodDef = methodMatcher.mBestMethodDef;
  13796. auto autoComplete = GetAutoComplete();
  13797. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(opToken)))
  13798. {
  13799. auto operatorDecl = BfNodeDynCast<BfOperatorDeclaration>(methodDef->mMethodDeclaration);
  13800. if ((operatorDecl != NULL) && (operatorDecl->mOpTypeToken != NULL))
  13801. autoComplete->SetDefinitionLocation(operatorDecl->mOpTypeToken);
  13802. }
  13803. SizedArray<BfExpression*, 2> argSrcs;
  13804. argSrcs.push_back(unaryOpExpr);
  13805. mResult = CreateCall(&methodMatcher, BfTypedValue());
  13806. if ((mResult.mType != NULL) && (methodMatcher.mSelfType != NULL) && (mResult.mType->IsSelf()))
  13807. {
  13808. BF_ASSERT(mModule->IsInGeneric());
  13809. mResult = mModule->GetDefaultTypedValue(methodMatcher.mSelfType);
  13810. }
  13811. if (isPostOp)
  13812. mResult = args[0].mTypedValue;
  13813. return;
  13814. }
  13815. }
  13816. bool numericFail = false;
  13817. switch (unaryOp)
  13818. {
  13819. case BfUnaryOp_Not:
  13820. {
  13821. CheckResultForReading(mResult);
  13822. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  13823. auto value = mModule->LoadValue(mResult);
  13824. value = mModule->Cast(unaryOpExpr, value, boolType);
  13825. if (!value)
  13826. return;
  13827. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateNot(value.mValue), boolType);
  13828. }
  13829. break;
  13830. case BfUnaryOp_Positive:
  13831. return;
  13832. case BfUnaryOp_Negate:
  13833. {
  13834. CheckResultForReading(mResult);
  13835. auto value = mModule->LoadValue(mResult);
  13836. if (!value)
  13837. return;
  13838. BfType* origType = value.mType;
  13839. if (value.mType->IsTypedPrimitive())
  13840. value.mType = value.mType->GetUnderlyingType();
  13841. if (value.mType->IsIntegral())
  13842. {
  13843. auto primType = (BfPrimitiveType*)value.mType;
  13844. auto wantType = primType;
  13845. auto constant = mModule->mBfIRBuilder->GetConstant(value.mValue);
  13846. if ((constant != NULL) && (mModule->mBfIRBuilder->IsInt(constant->mTypeCode)))
  13847. {
  13848. if ((primType->mTypeDef->mTypeCode == BfTypeCode_UInt32) && (constant->mInt64 == 0x80000000LL))
  13849. {
  13850. mResult = BfTypedValue(mModule->GetConstValue32(-0x80000000LL), mModule->GetPrimitiveType(BfTypeCode_Int32));
  13851. return;
  13852. }
  13853. else if ((primType->mTypeDef->mTypeCode == BfTypeCode_UInt64) && (constant->mInt64 == 0x8000000000000000LL))
  13854. {
  13855. mResult = BfTypedValue(mModule->GetConstValue64(-0x8000000000000000LL), mModule->GetPrimitiveType(BfTypeCode_Int64));
  13856. return;
  13857. }
  13858. }
  13859. /*if (auto constantInt = dyn_cast<ConstantInt>((Value*)value.mValue))
  13860. {
  13861. int64 i64Val = constantInt->getSExtValue();
  13862. // This is a special case where the user entered -0x80000000 (maxint) but we thought "0x80000000" was a uint in the parser
  13863. // which would get upcasted to an int64 for this negate. Properly bring back down to an int32
  13864. if ((primType->mTypeDef->mTypeCode == BfTypeCode_UInt32) && (i64Val == -0x80000000LL))
  13865. {
  13866. mResult = BfTypedValue(mModule->GetConstValue((int)i64Val), mModule->GetPrimitiveType(BfTypeCode_Int32));
  13867. return;
  13868. }
  13869. }*/
  13870. if (!primType->IsSigned())
  13871. {
  13872. if (primType->mSize == 1)
  13873. wantType = mModule->GetPrimitiveType(BfTypeCode_Int16);
  13874. else if (primType->mSize == 2)
  13875. wantType = mModule->GetPrimitiveType(BfTypeCode_Int32);
  13876. else if (primType->mSize == 4)
  13877. wantType = mModule->GetPrimitiveType(BfTypeCode_Int64);
  13878. else
  13879. mModule->Fail("Operator '-' cannot be applied to uint64", opToken);
  13880. }
  13881. if (primType != wantType)
  13882. {
  13883. value = mModule->Cast(unaryOpExpr, value, wantType, BfCastFlags_Explicit);
  13884. if (!value)
  13885. return;
  13886. }
  13887. if (origType->mSize == wantType->mSize) // Allow negative of primitive typed but not if we had to upsize
  13888. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateNeg(value.mValue), origType);
  13889. else
  13890. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateNeg(value.mValue), wantType);
  13891. }
  13892. else if (value.mType->IsFloat())
  13893. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateNeg(value.mValue), origType);
  13894. else
  13895. numericFail = true;
  13896. }
  13897. break;
  13898. case BfUnaryOp_InvertBits:
  13899. {
  13900. CheckResultForReading(mResult);
  13901. auto value = mModule->LoadValue(mResult);
  13902. if (!value)
  13903. return;
  13904. bool isInteger = value.mType->IsIntegral();
  13905. if (value.mType->IsTypedPrimitive())
  13906. isInteger = value.mType->GetUnderlyingType()->IsIntegral();
  13907. if (!isInteger)
  13908. {
  13909. mModule->Fail("Operator can only be used on integer types", opToken);
  13910. return;
  13911. }
  13912. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateNot(value.mValue), value.mType);
  13913. }
  13914. break;
  13915. case BfUnaryOp_AddressOf:
  13916. {
  13917. MarkResultUsed();
  13918. mModule->FixIntUnknown(mResult);
  13919. auto ptrType = mModule->CreatePointerType(mResult.mType);
  13920. if ((!CheckModifyResult(mResult, unaryOpExpr, "take address of")) || (mResult.mType->IsValuelessType()))
  13921. {
  13922. // Sentinel value
  13923. auto val = mModule->mBfIRBuilder->CreateIntToPtr(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 1), mModule->mBfIRBuilder->MapType(ptrType));
  13924. mResult = BfTypedValue(val, ptrType);
  13925. }
  13926. else
  13927. mResult = BfTypedValue(mResult.mValue, ptrType, false);
  13928. }
  13929. break;
  13930. case BfUnaryOp_Dereference:
  13931. {
  13932. CheckResultForReading(mResult);
  13933. if (!mResult.mType->IsPointer())
  13934. {
  13935. mResult = BfTypedValue();
  13936. mModule->Fail("Cannot dereference non-pointer type", unaryOpExpr);
  13937. return;
  13938. }
  13939. auto derefTarget = mModule->LoadValue(mResult);
  13940. BfPointerType* pointerType = (BfPointerType*)derefTarget.mType;
  13941. auto resolvedType = mModule->ResolveType(pointerType->mElementType);
  13942. if (resolvedType == NULL)
  13943. {
  13944. mResult = BfTypedValue();
  13945. return;
  13946. }
  13947. if (resolvedType->IsValuelessType())
  13948. mResult = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), resolvedType, true);
  13949. else
  13950. mResult = BfTypedValue(derefTarget.mValue, resolvedType, true);
  13951. }
  13952. break;
  13953. case BfUnaryOp_PostIncrement:
  13954. case BfUnaryOp_Increment:
  13955. {
  13956. CheckResultForReading(mResult);
  13957. auto ptr = mResult;
  13958. //if ((propDef == NULL) && (!mModule->CheckModifyValue(ptr, opToken)))
  13959. if ((propDef == NULL) && (!CheckModifyResult(ptr, opToken, "increment")))
  13960. return;
  13961. BfTypedValue origTypedVal = mModule->LoadValue(ptr, NULL, mIsVolatileReference);
  13962. BfIRValue origVal = origTypedVal.mValue;
  13963. BfIRValue constValue = mModule->GetConstValue(1, ptr.mType);
  13964. BfIRValue resultValue;
  13965. if (ptr.mType->IsPointer())
  13966. {
  13967. BfPointerType* ptrType = (BfPointerType*)ptr.mType;
  13968. BfType* intPtrType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  13969. constValue = mModule->GetConstValue(ptrType->mElementType->GetStride(), intPtrType);
  13970. BfIRValue origIntValue = mModule->mBfIRBuilder->CreatePtrToInt(origVal, BfTypeCode_IntPtr);
  13971. BfIRValue newIntValue = mModule->mBfIRBuilder->CreateAdd(origIntValue, constValue/*, "inc"*/);
  13972. resultValue = mModule->mBfIRBuilder->CreateIntToPtr(newIntValue, mModule->mBfIRBuilder->MapType(ptr.mType));
  13973. }
  13974. else
  13975. {
  13976. constValue = mModule->GetConstValue(1, ptr.mType);
  13977. if (!constValue)
  13978. {
  13979. numericFail = true;
  13980. break;
  13981. }
  13982. if ((ptr.mType->IsIntegral()) || (ptr.mType->IsEnum()) || (ptr.mType->IsFloat()))
  13983. {
  13984. resultValue = mModule->mBfIRBuilder->CreateAdd(origVal, constValue/*, "inc"*/);
  13985. }
  13986. else
  13987. {
  13988. numericFail = true;
  13989. break;
  13990. }
  13991. }
  13992. if ((propDef != NULL) && (!ptr.IsAddr()))
  13993. writeToProp = BfTypedValue(resultValue, ptr.mType);
  13994. else
  13995. mModule->mBfIRBuilder->CreateStore(resultValue, ptr.mValue, mIsVolatileReference);
  13996. if (unaryOp == BfUnaryOp_PostIncrement)
  13997. mResult = BfTypedValue(origVal, ptr.mType, false);
  13998. else
  13999. mResult = BfTypedValue(resultValue, ptr.mType, false);
  14000. }
  14001. break;
  14002. case BfUnaryOp_PostDecrement:
  14003. case BfUnaryOp_Decrement:
  14004. {
  14005. CheckResultForReading(mResult);
  14006. auto ptr = mResult;
  14007. //if ((propDef == NULL) && (!mModule->CheckModifyValue(ptr, opToken)))
  14008. //return;
  14009. if ((propDef == NULL) && (!CheckModifyResult(ptr, opToken, "decrement")))
  14010. return;
  14011. BfTypedValue origTypedVal = mModule->LoadValue(ptr, NULL, mIsVolatileReference);
  14012. BfIRValue origVal = origTypedVal.mValue;
  14013. BfIRValue constValue = mModule->GetConstValue(1, ptr.mType);
  14014. BfIRValue resultValue;
  14015. if (ptr.mType->IsPointer())
  14016. {
  14017. BfPointerType* ptrType = (BfPointerType*)ptr.mType;
  14018. BfType* intPtrType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  14019. constValue = mModule->GetConstValue(ptrType->mElementType->GetStride(), intPtrType);
  14020. BfIRValue origIntValue = mModule->mBfIRBuilder->CreatePtrToInt(origVal, BfTypeCode_IntPtr);
  14021. BfIRValue newIntValue = mModule->mBfIRBuilder->CreateSub(origIntValue, constValue);
  14022. resultValue = mModule->mBfIRBuilder->CreateIntToPtr(newIntValue, mModule->mBfIRBuilder->MapType(ptr.mType));
  14023. }
  14024. else
  14025. {
  14026. BfIRValue constValue = mModule->GetConstValue(1, ptr.mType);
  14027. if (!constValue)
  14028. {
  14029. numericFail = true;
  14030. break;
  14031. }
  14032. if ((ptr.mType->IsIntegral()) || (ptr.mType->IsEnum()))
  14033. {
  14034. resultValue = mModule->mBfIRBuilder->CreateSub(origVal, constValue);
  14035. }
  14036. else if (ptr.mType->IsFloat())
  14037. {
  14038. resultValue = mModule->mBfIRBuilder->CreateSub(origVal, constValue);
  14039. }
  14040. else
  14041. {
  14042. numericFail = true;
  14043. break;
  14044. }
  14045. }
  14046. if ((propDef != NULL) && (!ptr.IsAddr()))
  14047. writeToProp = BfTypedValue(resultValue, ptr.mType);
  14048. else
  14049. mModule->mBfIRBuilder->CreateStore(resultValue, ptr.mValue, mIsVolatileReference);
  14050. if (unaryOp == BfUnaryOp_PostDecrement)
  14051. mResult = BfTypedValue(origVal, ptr.mType, false);
  14052. else
  14053. mResult = BfTypedValue(resultValue, ptr.mType, false);
  14054. }
  14055. break;
  14056. case BfUnaryOp_Ref:
  14057. case BfUnaryOp_Mut:
  14058. {
  14059. if (mAllowReadOnlyReference)
  14060. {
  14061. if (mResult.mKind == BfTypedValueKind_ReadOnlyAddr)
  14062. mResult.mKind = BfTypedValueKind_Addr;
  14063. }
  14064. CheckResultForReading(mResult);
  14065. if ((unaryOp == BfUnaryOp_Mut) && (!mResult.mType->IsComposite()) && (!mResult.mType->IsGenericParam()))
  14066. {
  14067. // Non-composite types are already mutable, leave them alone...
  14068. break;
  14069. }
  14070. if ((unaryOp != BfUnaryOp_Mut) || (mResult.mKind != BfTypedValueKind_MutableValue))
  14071. {
  14072. if (!CheckModifyResult(mResult, unaryOpExpr, StrFormat("use '%s' on", BfGetOpName(unaryOp)).c_str()))
  14073. {
  14074. // Just leave the non-ref version in mResult
  14075. return;
  14076. }
  14077. }
  14078. if ((mBfEvalExprFlags & BfEvalExprFlags_AllowRefExpr) == 0)
  14079. {
  14080. mModule->Fail(StrFormat("Invalid usage of '%s' expression", BfGetOpName(unaryOp)), opToken);
  14081. return;
  14082. }
  14083. ResolveGenericType();
  14084. mResult = BfTypedValue(mResult.mValue, mModule->CreateRefType(mResult.mType, (unaryOp == BfUnaryOp_Ref) ? BfRefType::RefKind_Ref : BfRefType::RefKind_Mut));
  14085. }
  14086. break;
  14087. case BfUnaryOp_Out:
  14088. {
  14089. if (!CheckModifyResult(mResult, unaryOpExpr, "use 'out' on"))
  14090. {
  14091. // Just leave the non-ref version in mResult
  14092. return;
  14093. }
  14094. if ((mBfEvalExprFlags & BfEvalExprFlags_AllowOutExpr) == 0)
  14095. {
  14096. mModule->Fail("Invalid usage of 'out' expression", opToken);
  14097. return;
  14098. }
  14099. MarkResultAssigned();
  14100. MarkResultUsed();
  14101. ResolveGenericType();
  14102. mResult = BfTypedValue(mResult.mValue, mModule->CreateRefType(mResult.mType, BfRefType::RefKind_Out));
  14103. }
  14104. break;
  14105. case BfUnaryOp_Params:
  14106. {
  14107. bool allowParams = (mBfEvalExprFlags & BfEvalExprFlags_AllowParamsExpr) != 0;
  14108. if (mResultLocalVar == NULL)
  14109. allowParams = false;
  14110. if (allowParams)
  14111. {
  14112. if (mResultLocalVar->mCompositeCount >= 0) // Delegate params
  14113. {
  14114. allowParams = true;
  14115. }
  14116. else
  14117. {
  14118. auto isValid = false;
  14119. auto genericTypeInst = mResult.mType->ToGenericTypeInstance();
  14120. if ((genericTypeInst != NULL) && (genericTypeInst->mTypeDef == mModule->mCompiler->mSpanTypeDef))
  14121. isValid = true;
  14122. else if (mResult.mType->IsArray())
  14123. isValid = true;
  14124. if (!isValid)
  14125. {
  14126. mModule->Fail(StrFormat("A 'params' expression cannot be used on type '%s'", mModule->TypeToString(mResult.mType).c_str()), opToken);
  14127. }
  14128. }
  14129. }
  14130. if (allowParams)
  14131. {
  14132. mResult = mModule->LoadValue(mResult);
  14133. if (mResult.IsSplat())
  14134. mResult.mKind = BfTypedValueKind_ParamsSplat;
  14135. else
  14136. mResult.mKind = BfTypedValueKind_Params;
  14137. }
  14138. else
  14139. {
  14140. mModule->Fail("Illegal use of 'params' expression", opToken);
  14141. }
  14142. }
  14143. break;
  14144. default:
  14145. mModule->Fail("INTERNAL ERROR: Unhandled unary operator", unaryOpExpr);
  14146. break;
  14147. }
  14148. if (numericFail)
  14149. {
  14150. mModule->Fail("Operator can only be used on numeric types", opToken);
  14151. mResult = BfTypedValue();
  14152. }
  14153. if (writeToProp)
  14154. {
  14155. auto setMethod = GetPropertyMethodDef(propDef, BfMethodType_PropertySetter, mPropCheckedKind);
  14156. if (setMethod == NULL)
  14157. {
  14158. mModule->Fail("Property has no setter", propSrc);
  14159. return;
  14160. }
  14161. auto methodInstance = GetPropertyMethodInstance(setMethod);
  14162. if (!methodInstance.mFunc)
  14163. return;
  14164. if (propSrc != NULL)
  14165. mModule->UpdateExprSrcPos(propSrc);
  14166. SizedArray<BfIRValue, 4> args;
  14167. if (!setMethod->mIsStatic)
  14168. PushThis(propSrc, propTarget, methodInstance.mMethodInstance, args);
  14169. //args.push_back(propTarget.mValue);
  14170. for (int paramIdx = 0; paramIdx < (int)indexerVals.size(); paramIdx++)
  14171. {
  14172. auto val = mModule->Cast(propSrc, indexerVals[paramIdx].mTypedValue, methodInstance.mMethodInstance->GetParamType(paramIdx));
  14173. if (!val)
  14174. return;
  14175. PushArg(val, args);
  14176. }
  14177. PushArg(writeToProp, args);
  14178. CreateCall(methodInstance.mMethodInstance, methodInstance.mFunc, false, args);
  14179. }
  14180. }
  14181. void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExpression* rightExpression, BfBinaryOp binaryOp, BfTokenNode* opToken, BfBinOpFlags flags, BfTypedValue leftValue)
  14182. {
  14183. BfTypedValue rightValue;
  14184. if (rightExpression == NULL)
  14185. {
  14186. mModule->AssertErrorState();
  14187. return;
  14188. }
  14189. if (!leftValue)
  14190. {
  14191. if (!rightValue)
  14192. mModule->CreateValueFromExpression(rightExpression);
  14193. return;
  14194. }
  14195. if (leftValue.mType->IsRef())
  14196. leftValue.mType = leftValue.mType->GetUnderlyingType();
  14197. if ((binaryOp == BfBinaryOp_ConditionalAnd) || (binaryOp == BfBinaryOp_ConditionalOr))
  14198. {
  14199. if (mModule->mCurMethodState->mDeferredLocalAssignData != NULL)
  14200. mModule->mCurMethodState->mDeferredLocalAssignData->BreakExtendChain();
  14201. bool isAnd = binaryOp == BfBinaryOp_ConditionalAnd;
  14202. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  14203. leftValue = mModule->Cast(leftExpression, leftValue, boolType);
  14204. if (!leftValue)
  14205. {
  14206. mModule->CreateValueFromExpression(rightExpression);
  14207. return;
  14208. }
  14209. auto prevBB = mModule->mBfIRBuilder->GetInsertBlock();
  14210. SetAndRestoreValue<bool> prevInCondBlock(mModule->mCurMethodState->mInConditionalBlock, true);
  14211. // The RHS is not guaranteed to be executed
  14212. if ((mModule->mCurMethodState->mDeferredLocalAssignData != NULL) &&
  14213. (mModule->mCurMethodState->mDeferredLocalAssignData->mIsIfCondition))
  14214. mModule->mCurMethodState->mDeferredLocalAssignData->mIfMayBeSkipped = true;
  14215. if (isAnd)
  14216. {
  14217. bool isConstBranch = false;
  14218. bool constResult = false;
  14219. if (leftValue.mValue.IsConst())
  14220. {
  14221. auto constValue = mModule->mBfIRBuilder->GetConstant(leftValue.mValue);
  14222. if (constValue->mTypeCode == BfTypeCode_Boolean)
  14223. {
  14224. isConstBranch = true;
  14225. constResult = constValue->mBool;
  14226. }
  14227. }
  14228. if (isConstBranch)
  14229. {
  14230. if ((constResult) || (HasVariableDeclaration(rightExpression)))
  14231. {
  14232. // Only right side
  14233. rightValue = mModule->CreateValueFromExpression(rightExpression, boolType);
  14234. mResult = rightValue;
  14235. }
  14236. else
  14237. {
  14238. // Always false
  14239. SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
  14240. rightValue = mModule->CreateValueFromExpression(rightExpression, boolType);
  14241. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 0), boolType);
  14242. }
  14243. }
  14244. else
  14245. {
  14246. auto rhsBB = mModule->mBfIRBuilder->CreateBlock("land.rhs");
  14247. auto endBB = mModule->mBfIRBuilder->CreateBlock("land.end");
  14248. // This makes any 'scope' allocs be dyn since we aren't sure if this will be short-circuited
  14249. SetAndRestoreValue<bool> prevIsConditional(mModule->mCurMethodState->mCurScope->mIsConditional, true);
  14250. mModule->mBfIRBuilder->CreateCondBr(leftValue.mValue, rhsBB, endBB);
  14251. mModule->AddBasicBlock(rhsBB);
  14252. rightValue = mModule->CreateValueFromExpression(rightExpression, boolType);
  14253. mModule->mBfIRBuilder->CreateBr(endBB);
  14254. auto endRhsBB = mModule->mBfIRBuilder->GetInsertBlock();
  14255. mModule->AddBasicBlock(endBB);
  14256. auto phi = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(boolType), 2);
  14257. mModule->mBfIRBuilder->AddPhiIncoming(phi, mModule->GetConstValue(0, boolType), prevBB);
  14258. if (rightValue)
  14259. mModule->mBfIRBuilder->AddPhiIncoming(phi, rightValue.mValue, endRhsBB);
  14260. mResult = BfTypedValue(phi, boolType);
  14261. }
  14262. }
  14263. else
  14264. {
  14265. // Put variables in here into a 'possibly assigned' but never commit it.
  14266. // Because if we had "if ((Get(out a)) || (GetOther(out a))" then the LHS would already set it as defined, so
  14267. // the RHS is inconsequential
  14268. BfDeferredLocalAssignData deferredLocalAssignData;
  14269. deferredLocalAssignData.ExtendFrom(mModule->mCurMethodState->mDeferredLocalAssignData, false);
  14270. deferredLocalAssignData.mVarIdBarrier = mModule->mCurMethodState->GetRootMethodState()->mCurLocalVarId;
  14271. SetAndRestoreValue<BfDeferredLocalAssignData*> prevDLA(mModule->mCurMethodState->mDeferredLocalAssignData, &deferredLocalAssignData);
  14272. bool isConstBranch = false;
  14273. bool constResult = false;
  14274. if (leftValue.mValue.IsConst())
  14275. {
  14276. auto constValue = mModule->mBfIRBuilder->GetConstant(leftValue.mValue);
  14277. if (constValue->mTypeCode == BfTypeCode_Boolean)
  14278. {
  14279. isConstBranch = true;
  14280. constResult = constValue->mBool;
  14281. }
  14282. }
  14283. if (isConstBranch)
  14284. {
  14285. if ((constResult) && (!HasVariableDeclaration(rightExpression)))
  14286. {
  14287. // Always true
  14288. SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
  14289. rightValue = mModule->CreateValueFromExpression(rightExpression, boolType);
  14290. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 1), boolType);
  14291. }
  14292. else
  14293. {
  14294. // Only right side
  14295. rightValue = mModule->CreateValueFromExpression(rightExpression, boolType);
  14296. mResult = rightValue;
  14297. }
  14298. }
  14299. else
  14300. {
  14301. auto rhsBB = mModule->mBfIRBuilder->CreateBlock("lor.rhs");
  14302. auto endBB = mModule->mBfIRBuilder->CreateBlock("lor.end");
  14303. // This makes any 'scope' allocs be dyn since we aren't sure if this will be short-circuited
  14304. SetAndRestoreValue<bool> prevIsConditional(mModule->mCurMethodState->mCurScope->mIsConditional, true);
  14305. mModule->mBfIRBuilder->CreateCondBr(leftValue.mValue, endBB, rhsBB);
  14306. mModule->AddBasicBlock(rhsBB);
  14307. rightValue = mModule->CreateValueFromExpression(rightExpression, boolType);
  14308. mModule->mBfIRBuilder->CreateBr(endBB);
  14309. auto endRhsBB = mModule->mBfIRBuilder->GetInsertBlock();
  14310. mModule->AddBasicBlock(endBB);
  14311. auto phi = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(boolType), 2);
  14312. mModule->mBfIRBuilder->AddPhiIncoming(phi, mModule->GetConstValue(1, boolType), prevBB);
  14313. if (rightValue)
  14314. mModule->mBfIRBuilder->AddPhiIncoming(phi, rightValue.mValue, endRhsBB);
  14315. mResult = BfTypedValue(phi, boolType);
  14316. }
  14317. }
  14318. return;
  14319. }
  14320. BfType* wantType = leftValue.mType;
  14321. if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift))
  14322. wantType = NULL; // Don't presume
  14323. rightValue = mModule->CreateValueFromExpression(rightExpression, wantType, BfEvalExprFlags_NoCast);
  14324. if ((!leftValue) || (!rightValue))
  14325. return;
  14326. PerformBinaryOperation(leftExpression, rightExpression, binaryOp, opToken, flags, leftValue, rightValue);
  14327. }
  14328. void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExpression* rightExpression, BfBinaryOp binaryOp, BfTokenNode* opToken, BfBinOpFlags flags)
  14329. {
  14330. BfTypedValue leftValue;
  14331. if (leftExpression != NULL)
  14332. {
  14333. leftValue = mModule->CreateValueFromExpression(leftExpression, mExpectingType, (BfEvalExprFlags)(BfEvalExprFlags_NoCast | BfEvalExprFlags_AllowIntUnknown));
  14334. }
  14335. return PerformBinaryOperation(leftExpression, rightExpression, binaryOp, opToken, flags, leftValue);
  14336. }
  14337. bool BfExprEvaluator::CheckConstCompare(BfBinaryOp binaryOp, BfAstNode* opToken, const BfTypedValue& leftValue, const BfTypedValue& rightValue)
  14338. {
  14339. if ((binaryOp < BfBinaryOp_Equality) || (binaryOp > BfBinaryOp_LessThanOrEqual))
  14340. return false;
  14341. // LHS is expected to be a value and RHS is expected to be a const
  14342. if (!leftValue.mType->IsIntegral())
  14343. return false;
  14344. BF_ASSERT(rightValue.mValue.IsConst());
  14345. auto rightConst = mModule->mBfIRBuilder->GetConstant(rightValue.mValue);
  14346. if (!mModule->mBfIRBuilder->IsInt(rightConst->mTypeCode))
  14347. return false;
  14348. BfType* checkType = leftValue.mType;
  14349. if (checkType->IsTypedPrimitive())
  14350. checkType = checkType->GetUnderlyingType();
  14351. if (!checkType->IsPrimitiveType())
  14352. return false;
  14353. BfTypeCode typeCode = ((BfPrimitiveType*)checkType)->mTypeDef->mTypeCode;
  14354. int64 minValue = 0;
  14355. int64 maxValue = 0;
  14356. switch (typeCode)
  14357. {
  14358. case BfTypeCode_Int8:
  14359. minValue = -0x80;
  14360. maxValue = 0x7F;
  14361. break;
  14362. case BfTypeCode_Int16:
  14363. minValue = -0x8000;
  14364. maxValue = 0x7FFF;
  14365. break;
  14366. case BfTypeCode_Int32:
  14367. minValue = -0x80000000LL;
  14368. maxValue = 0x7FFFFFFF;
  14369. break;
  14370. case BfTypeCode_Int64:
  14371. minValue = -0x8000000000000000LL;
  14372. maxValue = 0x7FFFFFFFFFFFFFFFLL;
  14373. break;
  14374. case BfTypeCode_UInt8:
  14375. maxValue = 0xFF;
  14376. break;
  14377. case BfTypeCode_UInt16:
  14378. maxValue = 0xFFFF;
  14379. break;
  14380. case BfTypeCode_UInt32:
  14381. maxValue = 0xFFFFFFFF;
  14382. break;
  14383. default:
  14384. return false;
  14385. }
  14386. int constResult = -1;
  14387. if (typeCode == BfTypeCode_UInt64)
  14388. {
  14389. switch (binaryOp)
  14390. {
  14391. case BfBinaryOp_Equality:
  14392. if (rightConst->mInt64 < minValue)
  14393. constResult = 0;
  14394. break;
  14395. case BfBinaryOp_InEquality:
  14396. if (rightConst->mInt64 < minValue)
  14397. constResult = 1;
  14398. break;
  14399. case BfBinaryOp_LessThan:
  14400. if (rightConst->mInt64 <= minValue)
  14401. constResult = 0;
  14402. break;
  14403. case BfBinaryOp_LessThanOrEqual:
  14404. if (rightConst->mInt64 < minValue)
  14405. constResult = 0;
  14406. break;
  14407. default: break;
  14408. }
  14409. return false;
  14410. }
  14411. else
  14412. {
  14413. switch (binaryOp)
  14414. {
  14415. case BfBinaryOp_Equality:
  14416. if (rightConst->mInt64 < minValue)
  14417. constResult = 0;
  14418. else if (rightConst->mInt64 > maxValue)
  14419. constResult = 0;
  14420. break;
  14421. case BfBinaryOp_InEquality:
  14422. if (rightConst->mInt64 < minValue)
  14423. constResult = 1;
  14424. else if (rightConst->mInt64 > maxValue)
  14425. constResult = 1;
  14426. break;
  14427. case BfBinaryOp_LessThan:
  14428. if (rightConst->mInt64 <= minValue)
  14429. constResult = 0;
  14430. else if (rightConst->mInt64 > maxValue)
  14431. constResult = 1;
  14432. break;
  14433. case BfBinaryOp_LessThanOrEqual:
  14434. if (rightConst->mInt64 < minValue)
  14435. constResult = 0;
  14436. else if (rightConst->mInt64 >= maxValue)
  14437. constResult = 1;
  14438. break;
  14439. case BfBinaryOp_GreaterThan:
  14440. if (rightConst->mInt64 >= maxValue)
  14441. constResult = 0;
  14442. else if (rightConst->mInt64 < minValue)
  14443. constResult = 1;
  14444. break;
  14445. case BfBinaryOp_GreaterThanOrEqual:
  14446. if (rightConst->mInt64 > maxValue)
  14447. constResult = 0;
  14448. else if (rightConst->mInt64 <= minValue)
  14449. constResult = 1;
  14450. break;
  14451. default: break;
  14452. }
  14453. }
  14454. if (constResult == 0)
  14455. {
  14456. mModule->Warn(0, "The result of this operation is always 'false'", opToken);
  14457. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 1), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  14458. return true;
  14459. }
  14460. else if (constResult == 1)
  14461. {
  14462. mModule->Warn(0, "The result of this operation is always 'true'", opToken);
  14463. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 1), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  14464. return true;
  14465. }
  14466. return false;
  14467. }
  14468. void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNode* rightExpression, BfBinaryOp binaryOp, BfAstNode* opToken, BfBinOpFlags flags, BfTypedValue leftValue, BfTypedValue rightValue)
  14469. {
  14470. bool noClassify = (flags & BfBinOpFlag_NoClassify) != 0;
  14471. bool forceLeftType = (flags & BfBinOpFlag_ForceLeftType) != 0;
  14472. if ((rightValue.mValue.IsConst()) && (!leftValue.mValue.IsConst()))
  14473. {
  14474. if (CheckConstCompare(binaryOp, opToken, leftValue, rightValue))
  14475. return;
  14476. }
  14477. else if ((leftValue.mValue.IsConst()) && (!rightValue.mValue.IsConst()))
  14478. {
  14479. if (CheckConstCompare(GetOppositeBinaryOp(binaryOp), opToken, rightValue, leftValue))
  14480. return;
  14481. }
  14482. if ((binaryOp == BfBinaryOp_NullCoalesce) && ((leftValue.mType->IsPointer()) || (leftValue.mType->IsObject())))
  14483. {
  14484. auto prevBB = mModule->mBfIRBuilder->GetInsertBlock();
  14485. auto rhsBB = mModule->mBfIRBuilder->CreateBlock("nullc.rhs");
  14486. auto endBB = mModule->mBfIRBuilder->CreateBlock("nullc.end");
  14487. auto isNull = mModule->mBfIRBuilder->CreateIsNull(leftValue.mValue);
  14488. mModule->mBfIRBuilder->CreateCondBr(isNull, rhsBB, endBB);
  14489. mModule->AddBasicBlock(rhsBB);
  14490. if (!rightValue)
  14491. {
  14492. mModule->AssertErrorState();
  14493. return;
  14494. }
  14495. else
  14496. {
  14497. auto rightToLeftValue = mModule->CastToValue(rightExpression, rightValue, leftValue.mType, BfCastFlags_SilentFail);
  14498. if (rightToLeftValue)
  14499. {
  14500. rightValue = BfTypedValue(rightToLeftValue, leftValue.mType);
  14501. }
  14502. else
  14503. {
  14504. auto leftToRightValue = mModule->CastToValue(leftExpression, leftValue, rightValue.mType, BfCastFlags_SilentFail);
  14505. if (leftToRightValue)
  14506. {
  14507. leftValue = BfTypedValue(leftToRightValue, rightValue.mType);
  14508. }
  14509. else
  14510. {
  14511. // Note: Annoying trigraph split for '??'
  14512. mModule->Fail(StrFormat("Operator '?" "?' cannot be applied to operands of type '%s' and '%s'",
  14513. mModule->TypeToString(leftValue.mType).c_str(), mModule->TypeToString(rightValue.mType).c_str()), opToken);
  14514. leftValue = mModule->GetDefaultTypedValue(rightValue.mType);
  14515. }
  14516. }
  14517. }
  14518. mModule->mBfIRBuilder->CreateBr(endBB);
  14519. auto endRhsBB = mModule->mBfIRBuilder->GetInsertBlock();
  14520. mModule->AddBasicBlock(endBB);
  14521. auto phi = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(leftValue.mType), 2);
  14522. mModule->mBfIRBuilder->AddPhiIncoming(phi, leftValue.mValue, prevBB);
  14523. mModule->mBfIRBuilder->AddPhiIncoming(phi, rightValue.mValue, endRhsBB);
  14524. mResult = BfTypedValue(phi, leftValue.mType);
  14525. return;
  14526. }
  14527. if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift))
  14528. {
  14529. forceLeftType = true;
  14530. }
  14531. if (rightValue.mType->IsRef())
  14532. rightValue.mType = rightValue.mType->GetUnderlyingType();
  14533. mModule->FixIntUnknown(leftValue, rightValue);
  14534. // Prefer floats, prefer chars
  14535. int leftCompareSize = leftValue.mType->mSize;
  14536. if (leftValue.mType->IsFloat())
  14537. leftCompareSize += 0x10;
  14538. if (leftValue.mType->IsChar())
  14539. leftCompareSize += 0x100;
  14540. if (!leftValue.mType->IsPrimitiveType())
  14541. leftCompareSize += 0x1000;
  14542. int rightCompareSize = rightValue.mType->mSize;
  14543. if (rightValue.mType->IsFloat())
  14544. rightCompareSize += 0x10;
  14545. if (rightValue.mType->IsChar())
  14546. rightCompareSize += 0x100;
  14547. if (!rightValue.mType->IsPrimitiveType())
  14548. rightCompareSize += 0x1000;
  14549. if ((leftValue.mType->IsTypeInstance()) && (rightValue.mType->IsTypeInstance()))
  14550. {
  14551. int leftInheritDepth = leftValue.mType->ToTypeInstance()->mInheritDepth;
  14552. int rightInheritDepth = rightValue.mType->ToTypeInstance()->mInheritDepth;
  14553. if (leftInheritDepth < rightInheritDepth)
  14554. {
  14555. // If both are type instances then choose the type with the lowest inherit depth
  14556. // so we will choose the base type when applicable
  14557. forceLeftType = true;
  14558. }
  14559. }
  14560. auto resultType = leftValue.mType;
  14561. if (!forceLeftType)
  14562. {
  14563. bool handled = false;
  14564. // If one of these is a constant that can be converted into a smaller type, then do that
  14565. if (rightValue.mValue.IsConst())
  14566. {
  14567. if (mModule->CanImplicitlyCast(rightValue, leftValue.mType))
  14568. {
  14569. resultType = leftValue.mType;
  14570. handled = true;
  14571. }
  14572. }
  14573. // If left is an IntUnknown, allow the right to inform the type
  14574. if (leftValue.mType->IsIntUnknown())
  14575. {
  14576. if (leftValue.mValue.IsConst())
  14577. {
  14578. if (mModule->CanImplicitlyCast(leftValue, rightValue.mType))
  14579. {
  14580. resultType = rightValue.mType;
  14581. handled = true;
  14582. }
  14583. }
  14584. }
  14585. if (!handled)
  14586. {
  14587. if ((resultType->IsNull()) ||
  14588. (rightCompareSize > leftCompareSize) ||
  14589. (((rightCompareSize == leftCompareSize) && (!rightValue.mType->IsSigned()))) ||
  14590. (rightValue.mType->IsTypedPrimitive()))
  14591. {
  14592. // Select the type with the "most information"
  14593. if (!rightValue.mType->IsNull())
  14594. resultType = rightValue.mType;
  14595. }
  14596. if ((!resultType->IsPointer()) && (rightValue.mType->IsPointer()))
  14597. resultType = rightValue.mType;
  14598. }
  14599. }
  14600. bool explicitCast = false;
  14601. BfTypedValue* resultTypedValue;
  14602. BfTypedValue* otherTypedValue;
  14603. BfType* otherType;
  14604. BfAstNode* resultTypeSrc;
  14605. BfAstNode* otherTypeSrc;
  14606. if (resultType == leftValue.mType)
  14607. {
  14608. resultTypedValue = &leftValue;
  14609. resultTypeSrc = leftExpression;
  14610. otherTypedValue = &rightValue;
  14611. otherTypeSrc = rightExpression;
  14612. otherType = otherTypedValue->mType;
  14613. }
  14614. else
  14615. {
  14616. resultTypedValue = &rightValue;
  14617. resultTypeSrc = rightExpression;
  14618. otherTypedValue = &leftValue;
  14619. otherTypeSrc = leftExpression;
  14620. otherType = otherTypedValue->mType;
  14621. }
  14622. auto _OpFail = [&]()
  14623. {
  14624. if ((rightValue.mType != NULL) && (leftValue.mType != NULL))
  14625. {
  14626. if (rightValue.mType != leftValue.mType)
  14627. mModule->Fail(StrFormat("Cannot perform binary operation '%s' between types '%s' and '%s'",
  14628. BfGetOpName(binaryOp), mModule->TypeToString(leftValue.mType).c_str(), mModule->TypeToString(rightValue.mType).c_str()), opToken);
  14629. else
  14630. mModule->Fail(StrFormat("Cannot perform binary operation '%s' between two instances of type '%s'",
  14631. BfGetOpName(binaryOp), mModule->TypeToString(leftValue.mType).c_str()), opToken);
  14632. }
  14633. else
  14634. mModule->Fail(StrFormat("Cannot perform binary operation '%s'", BfGetOpName(binaryOp)), opToken);
  14635. };
  14636. // This case fixes cases like "c == 0" where "0" is technically an int but can be reduced
  14637. if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_InEquality))
  14638. {
  14639. if ((resultType != otherType) && (resultTypedValue->mValue.IsConst()) && (mModule->CanImplicitlyCast(*resultTypedValue, otherType)))
  14640. {
  14641. std::swap(resultTypedValue, otherTypedValue);
  14642. std::swap(resultTypeSrc, otherTypeSrc);
  14643. std::swap(resultType, otherType);
  14644. }
  14645. }
  14646. BfIRValue convLeftValue;
  14647. BfIRValue convRightValue;
  14648. if ((resultType->IsVar()) || (otherType->IsVar()))
  14649. {
  14650. mResult = BfTypedValue(mModule->GetDefaultValue(resultType), mModule->GetPrimitiveType(BfTypeCode_Var));
  14651. return;
  14652. }
  14653. if ((otherType->IsNull()) && ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_InEquality)))
  14654. {
  14655. bool isEquality = (binaryOp == BfBinaryOp_Equality);
  14656. if ((resultType->IsValueType()) && (!resultType->IsFunction()))
  14657. {
  14658. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  14659. if (resultType->IsNullable())
  14660. {
  14661. auto elementType = resultType->GetUnderlyingType();
  14662. if (elementType->IsValuelessType())
  14663. {
  14664. mModule->mBfIRBuilder->PopulateType(resultType);
  14665. BfTypedValue nullableTypedVale = mModule->MakeAddressable(*resultTypedValue);
  14666. BfIRValue hasValuePtr = mModule->mBfIRBuilder->CreateInBoundsGEP(nullableTypedVale.mValue, 0, 1);
  14667. BfIRValue hasValueValue = mModule->mBfIRBuilder->CreateLoad(hasValuePtr);
  14668. if (isEquality)
  14669. hasValueValue = mModule->mBfIRBuilder->CreateNot(hasValueValue);
  14670. mResult = BfTypedValue(hasValueValue, boolType);
  14671. }
  14672. else
  14673. {
  14674. mModule->mBfIRBuilder->PopulateType(resultType);
  14675. BfTypedValue nullableTypedVale = mModule->MakeAddressable(*resultTypedValue);
  14676. BfIRValue hasValuePtr = mModule->mBfIRBuilder->CreateInBoundsGEP(nullableTypedVale.mValue, 0, 2);
  14677. BfIRValue hasValueValue = mModule->mBfIRBuilder->CreateLoad(hasValuePtr);
  14678. if (isEquality)
  14679. hasValueValue = mModule->mBfIRBuilder->CreateNot(hasValueValue);
  14680. mResult = BfTypedValue(hasValueValue, boolType);
  14681. }
  14682. return;
  14683. }
  14684. if (resultType->IsNull())
  14685. {
  14686. // Null always equals null
  14687. mResult = BfTypedValue(mModule->GetConstValue(isEquality ? 1 : 0, boolType), boolType);
  14688. return;
  14689. }
  14690. if (!mModule->IsInSpecializedSection())
  14691. {
  14692. //CS0472: The result of the expression is always 'true' since a value of type 'int' is never equal to 'null' of type '<null>'
  14693. mModule->Warn(BfWarning_CS0472_ValueTypeNullCompare,
  14694. StrFormat("The result of the expression is always '%s' since a value of type '%s' can never be null",
  14695. isEquality ? "false" : "true", mModule->TypeToString(resultType).c_str()), otherTypeSrc);
  14696. }
  14697. // Valuetypes never equal null
  14698. mResult = BfTypedValue(mModule->GetConstValue(isEquality ? 0 : 1, boolType), boolType);
  14699. return;
  14700. }
  14701. }
  14702. if ((leftValue.mType->IsTypeInstance()) || (leftValue.mType->IsGenericParam()) ||
  14703. (rightValue.mType->IsTypeInstance()) || (rightValue.mType->IsGenericParam()))
  14704. {
  14705. // As an optimization, we don't call user operator overloads for null checks
  14706. bool skipOpOverload = false;
  14707. if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_InEquality))
  14708. {
  14709. auto leftConstant = mModule->mBfIRBuilder->GetConstant(leftValue.mValue);
  14710. auto rightConstant = mModule->mBfIRBuilder->GetConstant(rightValue.mValue);
  14711. if ((leftConstant != NULL) && (leftConstant->IsNull()))
  14712. skipOpOverload = true;
  14713. if ((rightConstant != NULL) && (rightConstant->IsNull()))
  14714. skipOpOverload = true;
  14715. }
  14716. if (!skipOpOverload)
  14717. {
  14718. BfBinaryOp findBinaryOp = binaryOp;
  14719. bool isComparison = (binaryOp >= BfBinaryOp_Equality) && (binaryOp <= BfBinaryOp_LessThanOrEqual);
  14720. for (int pass = 0; pass < 2; pass++)
  14721. {
  14722. bool foundOp = false;
  14723. SizedArray<BfResolvedArg, 2> args;
  14724. BfResolvedArg leftArg;
  14725. leftArg.mExpression = leftExpression;
  14726. leftArg.mTypedValue = leftValue;
  14727. BfResolvedArg rightArg;
  14728. rightArg.mExpression = rightExpression;
  14729. rightArg.mTypedValue = rightValue;
  14730. if (pass == 0)
  14731. {
  14732. args.push_back(leftArg);
  14733. args.push_back(rightArg);
  14734. }
  14735. else
  14736. {
  14737. args.push_back(rightArg);
  14738. args.push_back(leftArg);
  14739. }
  14740. BfMethodMatcher methodMatcher(opToken, mModule, "", args, NULL);
  14741. BfBaseClassWalker baseClassWalker(leftValue.mType, rightValue.mType, mModule);
  14742. bool invertResult = false;
  14743. BfBinaryOp oppositeBinaryOp = GetOppositeBinaryOp(findBinaryOp);
  14744. while (true)
  14745. {
  14746. auto entry = baseClassWalker.Next();
  14747. auto checkType = entry.mTypeInstance;
  14748. if (checkType == NULL)
  14749. break;
  14750. bool foundExactMatch = false;
  14751. Array<BfMethodDef*> oppositeOperatorDefs;
  14752. for (auto operatorDef : checkType->mTypeDef->mOperators)
  14753. {
  14754. bool allowOp = operatorDef->mOperatorDeclaration->mBinOp == findBinaryOp;
  14755. if ((isComparison) && (operatorDef->mOperatorDeclaration->mBinOp == BfBinaryOp_Compare))
  14756. allowOp = true;
  14757. if (allowOp)
  14758. {
  14759. foundOp = true;
  14760. if (methodMatcher.CheckMethod(checkType, operatorDef, false))
  14761. {
  14762. methodMatcher.mSelfType = entry.mSrcType;
  14763. if (operatorDef->mOperatorDeclaration->mBinOp == findBinaryOp)
  14764. foundExactMatch = true;
  14765. }
  14766. }
  14767. else if (operatorDef->mOperatorDeclaration->mBinOp == oppositeBinaryOp)
  14768. oppositeOperatorDefs.Add(operatorDef);
  14769. }
  14770. if (((methodMatcher.mBestMethodDef == NULL) || (!foundExactMatch)) && (!oppositeOperatorDefs.IsEmpty()))
  14771. {
  14772. foundOp = true;
  14773. for (auto oppositeOperatorDef : oppositeOperatorDefs)
  14774. {
  14775. if (methodMatcher.CheckMethod(checkType, oppositeOperatorDef, false))
  14776. methodMatcher.mSelfType = entry.mSrcType;
  14777. }
  14778. }
  14779. }
  14780. if (methodMatcher.mBestMethodDef != NULL)
  14781. {
  14782. methodMatcher.FlushAmbiguityError();
  14783. auto matchedOp = ((BfOperatorDeclaration*)methodMatcher.mBestMethodDef->mMethodDeclaration)->mBinOp;
  14784. bool invertResult = matchedOp == oppositeBinaryOp;
  14785. auto methodDef = methodMatcher.mBestMethodDef;
  14786. auto autoComplete = GetAutoComplete();
  14787. if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(opToken)))
  14788. {
  14789. auto operatorDecl = BfNodeDynCast<BfOperatorDeclaration>(methodDef->mMethodDeclaration);
  14790. if ((operatorDecl != NULL) && (operatorDecl->mOpTypeToken != NULL))
  14791. autoComplete->SetDefinitionLocation(operatorDecl->mOpTypeToken);
  14792. }
  14793. if (opToken != NULL)
  14794. {
  14795. if ((opToken->IsA<BfTokenNode>()) && (!noClassify) && (!baseClassWalker.mMayBeFromInterface))
  14796. mModule->SetElementType(opToken, BfSourceElementType_Method);
  14797. }
  14798. mResult = CreateCall(&methodMatcher, BfTypedValue());
  14799. if ((mResult.mType != NULL) && (methodMatcher.mSelfType != NULL) && (mResult.mType->IsSelf()))
  14800. {
  14801. BF_ASSERT(mModule->IsInGeneric());
  14802. mResult = mModule->GetDefaultTypedValue(methodMatcher.mSelfType);
  14803. }
  14804. if ((invertResult) && (mResult.mType == mModule->GetPrimitiveType(BfTypeCode_Boolean)))
  14805. mResult.mValue = mModule->mBfIRBuilder->CreateNot(mResult.mValue);
  14806. if (pass == 1)
  14807. {
  14808. if (findBinaryOp == BfBinaryOp_Compare)
  14809. {
  14810. mResult = mModule->LoadValue(mResult);
  14811. if (mResult.mType->IsIntegral())
  14812. mResult.mValue = mModule->mBfIRBuilder->CreateNeg(mResult.mValue);
  14813. }
  14814. }
  14815. if ((isComparison) && (matchedOp == BfBinaryOp_Compare))
  14816. {
  14817. auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  14818. mResult = mModule->LoadValue(mResult);
  14819. if (mResult.mType != intType)
  14820. mResult = mModule->GetDefaultTypedValue(intType);
  14821. auto zeroVal = mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0);
  14822. auto useBinaryOp = binaryOp;
  14823. if (pass == 1)
  14824. useBinaryOp = GetFlippedBinaryOp(useBinaryOp);
  14825. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  14826. switch (useBinaryOp)
  14827. {
  14828. case BfBinaryOp_Equality:
  14829. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(mResult.mValue, zeroVal), boolType);
  14830. break;
  14831. case BfBinaryOp_InEquality:
  14832. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(mResult.mValue, zeroVal), boolType);
  14833. break;
  14834. case BfBinaryOp_GreaterThan:
  14835. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpGT(mResult.mValue, zeroVal, true), boolType);
  14836. break;
  14837. case BfBinaryOp_LessThan:
  14838. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpLT(mResult.mValue, zeroVal, true), boolType);
  14839. break;
  14840. case BfBinaryOp_GreaterThanOrEqual:
  14841. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpGTE(mResult.mValue, zeroVal, true), boolType);
  14842. break;
  14843. case BfBinaryOp_LessThanOrEqual:
  14844. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpLTE(mResult.mValue, zeroVal, true), boolType);
  14845. break;
  14846. default: break;
  14847. }
  14848. }
  14849. return;
  14850. }
  14851. if ((!foundOp) || (pass == 1))
  14852. break;
  14853. switch (findBinaryOp)
  14854. {
  14855. case BfBinaryOp_Add:
  14856. case BfBinaryOp_Multiply:
  14857. case BfBinaryOp_Equality:
  14858. case BfBinaryOp_InEquality:
  14859. case BfBinaryOp_BitwiseAnd:
  14860. case BfBinaryOp_BitwiseOr:
  14861. case BfBinaryOp_ConditionalAnd:
  14862. case BfBinaryOp_ConditionalOr:
  14863. case BfBinaryOp_Compare:
  14864. // Still works
  14865. break;
  14866. case BfBinaryOp_LessThan:
  14867. findBinaryOp = BfBinaryOp_GreaterThanOrEqual;
  14868. break;
  14869. case BfBinaryOp_LessThanOrEqual:
  14870. findBinaryOp = BfBinaryOp_GreaterThan;
  14871. break;
  14872. case BfBinaryOp_GreaterThan:
  14873. findBinaryOp = BfBinaryOp_LessThanOrEqual;
  14874. break;
  14875. case BfBinaryOp_GreaterThanOrEqual:
  14876. findBinaryOp = BfBinaryOp_LessThan;
  14877. break;
  14878. default:
  14879. findBinaryOp = BfBinaryOp_None;
  14880. break;
  14881. }
  14882. if (findBinaryOp == BfBinaryOp_None)
  14883. break;
  14884. }
  14885. }
  14886. }
  14887. if (mModule->IsUnboundGeneric(resultType))
  14888. {
  14889. mResult = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Var));
  14890. return;
  14891. }
  14892. if (resultType->IsPointer() && otherType->IsPointer())
  14893. {
  14894. //TODO: Allow all pointer comparisons, but only allow SUBTRACTION between equal pointer types
  14895. if (binaryOp == BfBinaryOp_Subtract)
  14896. {
  14897. if (resultType != otherType)
  14898. {
  14899. mModule->Fail(StrFormat("Operands must be the same type, '%s' doesn't match '%s'",
  14900. mModule->TypeToString(leftValue.mType).c_str(), mModule->TypeToString(rightValue.mType).c_str()),
  14901. opToken);
  14902. return;
  14903. }
  14904. BfPointerType* resultPointerType = (BfPointerType*)resultType;
  14905. BfType* intPtrType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  14906. convLeftValue = mModule->CastToValue(leftExpression, leftValue, intPtrType, BfCastFlags_Explicit);
  14907. convRightValue = mModule->CastToValue(rightExpression, rightValue, intPtrType, BfCastFlags_Explicit);
  14908. BfIRValue diffValue = mModule->mBfIRBuilder->CreateSub(convLeftValue, convRightValue);
  14909. diffValue = mModule->mBfIRBuilder->CreateDiv(diffValue, mModule->GetConstValue(resultPointerType->mElementType->mSize, intPtrType), true);
  14910. mResult = BfTypedValue(diffValue, intPtrType);
  14911. return;
  14912. }
  14913. else if ((binaryOp != BfBinaryOp_Equality) && (binaryOp != BfBinaryOp_InEquality) &&
  14914. (binaryOp != BfBinaryOp_LessThan) && (binaryOp != BfBinaryOp_LessThanOrEqual) &&
  14915. (binaryOp != BfBinaryOp_GreaterThan) && (binaryOp != BfBinaryOp_GreaterThanOrEqual))
  14916. {
  14917. mModule->Fail("Invalid operation on pointers", opToken);
  14918. return;
  14919. }
  14920. if (((binaryOp != BfBinaryOp_Equality) && (binaryOp != BfBinaryOp_InEquality)) ||
  14921. (resultType != otherType))
  14922. {
  14923. resultType = mModule->GetPrimitiveType(BfTypeCode_UIntPtr);
  14924. explicitCast = true;
  14925. }
  14926. }
  14927. else if (resultType->IsPointer())
  14928. {
  14929. if (otherType->IsNull())
  14930. {
  14931. if ((binaryOp != BfBinaryOp_Equality) && (binaryOp != BfBinaryOp_InEquality))
  14932. {
  14933. mModule->Fail(StrFormat("Invalid operation between '%s' and null", mModule->TypeToString(resultType).c_str()), opToken);
  14934. return;
  14935. }
  14936. if (binaryOp == BfBinaryOp_Equality)
  14937. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateIsNull(resultTypedValue->mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  14938. else
  14939. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateIsNotNull(resultTypedValue->mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  14940. return;
  14941. }
  14942. // One pointer
  14943. if ((!otherType->IsIntegral()) ||
  14944. ((binaryOp != BfBinaryOp_Add) && (binaryOp != BfBinaryOp_Subtract)))
  14945. {
  14946. _OpFail();
  14947. return;
  14948. }
  14949. auto underlyingType = resultType->GetUnderlyingType();
  14950. BfIRValue addValue = otherTypedValue->mValue;
  14951. if ((!otherTypedValue->mType->IsSigned()) && (otherTypedValue->mType->mSize < mModule->mSystem->mPtrSize))
  14952. addValue = mModule->mBfIRBuilder->CreateNumericCast(addValue, false, BfTypeCode_UIntPtr);
  14953. if (binaryOp == BfBinaryOp_Subtract)
  14954. {
  14955. if (resultTypeSrc == rightExpression)
  14956. mModule->Fail("Cannot subtract a pointer from an integer", resultTypeSrc);
  14957. addValue = mModule->mBfIRBuilder->CreateNeg(addValue);
  14958. }
  14959. if (underlyingType->IsValuelessType())
  14960. {
  14961. if (!mModule->IsInSpecializedSection())
  14962. {
  14963. mModule->Warn(0, "Adding to a pointer to a zero-sized element has no effect", opToken);
  14964. }
  14965. mResult = *resultTypedValue;
  14966. return;
  14967. }
  14968. mModule->mBfIRBuilder->PopulateType(underlyingType);
  14969. mResult = BfTypedValue(mModule->CreateIndexedValue(underlyingType, resultTypedValue->mValue, addValue), resultType);
  14970. return;
  14971. }
  14972. if ((resultType->IsFunction()) || (resultType->IsPointer()) || (resultType->IsObject()) || (resultType->IsInterface()) || (resultType->IsGenericParam()))
  14973. {
  14974. //if ((resultType->IsFunction()) || (resultType->IsObject()) || (resultType->IsInterface()) || (resultType->IsGenericParam()))
  14975. {
  14976. if ((binaryOp != BfBinaryOp_Equality) && (binaryOp != BfBinaryOp_InEquality))
  14977. {
  14978. //mModule->Fail("Invalid operation for objects", opToken);
  14979. _OpFail();
  14980. return;
  14981. }
  14982. }
  14983. if (resultType->IsInterface())
  14984. {
  14985. // Compare as objects instead
  14986. resultType = mModule->mContext->mBfObjectType;
  14987. *resultTypedValue = mModule->Cast(resultTypeSrc, *resultTypedValue, resultType);
  14988. }
  14989. if (otherType->IsNull())
  14990. {
  14991. if (resultType->IsFunction())
  14992. {
  14993. if (binaryOp == BfBinaryOp_Equality)
  14994. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0), resultTypedValue->mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  14995. else
  14996. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0), resultTypedValue->mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  14997. }
  14998. else
  14999. {
  15000. if (binaryOp == BfBinaryOp_Equality)
  15001. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateIsNull(resultTypedValue->mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  15002. else
  15003. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateIsNotNull(resultTypedValue->mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  15004. }
  15005. }
  15006. else
  15007. {
  15008. auto convertedValue = mModule->CastToValue(otherTypeSrc, *otherTypedValue, resultType);
  15009. if (!convertedValue)
  15010. return;
  15011. if (binaryOp == BfBinaryOp_Equality)
  15012. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(resultTypedValue->mValue, convertedValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  15013. else
  15014. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(resultTypedValue->mValue, convertedValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
  15015. }
  15016. return;
  15017. }
  15018. if (resultType->IsTypedPrimitive())
  15019. {
  15020. bool needsOtherCast = true;
  15021. if (otherType != resultType)
  15022. {
  15023. if ((otherType->IsPrimitiveType()) && (!otherType->IsValuelessType()))
  15024. {
  15025. // Allow zero comparisons to match all typed primitives
  15026. if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_InEquality))
  15027. {
  15028. auto constant = mModule->mBfIRBuilder->GetConstant(otherTypedValue->mValue);
  15029. if ((constant != NULL) && (mModule->mBfIRBuilder->IsInt(constant->mTypeCode)) && (constant->mInt64 == 0))
  15030. needsOtherCast = false;
  15031. }
  15032. // Allow integer offsetting
  15033. if ((binaryOp == BfBinaryOp_Add) || (binaryOp == BfBinaryOp_Subtract))
  15034. {
  15035. if (otherType->IsIntegral())
  15036. needsOtherCast = false;
  15037. }
  15038. }
  15039. if (needsOtherCast)
  15040. {
  15041. // The only purpose of this cast is to potentially throw a casting error
  15042. BfIRValue otherCastResult = mModule->CastToValue(otherTypeSrc, *otherTypedValue, resultType, explicitCast ? BfCastFlags_Explicit : BfCastFlags_None);
  15043. if (!otherCastResult)
  15044. return;
  15045. }
  15046. }
  15047. auto underlyingType = resultType->GetUnderlyingType();
  15048. BfIRValue convResultValue = mModule->CastToValue(resultTypeSrc, *resultTypedValue, underlyingType, BfCastFlags_Explicit);
  15049. BfIRValue convOtherValue = mModule->CastToValue(otherTypeSrc, *otherTypedValue, underlyingType, BfCastFlags_Explicit);
  15050. if ((!underlyingType->IsValuelessType()) && ((!convResultValue) || (!convOtherValue)))
  15051. return;
  15052. if (resultTypedValue == &leftValue)
  15053. PerformBinaryOperation(underlyingType, convResultValue, convOtherValue, binaryOp, opToken);
  15054. else
  15055. PerformBinaryOperation(underlyingType, convOtherValue, convResultValue, binaryOp, opToken);
  15056. if (mResult.mType == underlyingType)
  15057. mResult.mType = resultType;
  15058. return;
  15059. }
  15060. auto _CallValueTypeEquals = [&]()
  15061. {
  15062. BfModuleMethodInstance moduleMethodInstance;
  15063. auto typeInst = leftValue.mType->ToTypeInstance();
  15064. if (typeInst != NULL)
  15065. {
  15066. moduleMethodInstance = mModule->GetMethodByName(typeInst, BF_METHODNAME_DEFAULT_EQUALS);
  15067. }
  15068. else
  15069. {
  15070. BF_ASSERT(leftValue.mType->IsSizedArray() || leftValue.mType->IsMethodRef());
  15071. auto valueTypeInst = mModule->ResolveTypeDef(mModule->mCompiler->mValueTypeTypeDef)->ToTypeInstance();
  15072. BfMethodDef* equalsMethodDef = mModule->mCompiler->mValueTypeTypeDef->GetMethodByName("Equals");
  15073. BfTypeVector typeVec;
  15074. typeVec.push_back(leftValue.mType);
  15075. moduleMethodInstance = mModule->GetMethodInstance(valueTypeInst, equalsMethodDef, typeVec);
  15076. }
  15077. if (moduleMethodInstance)
  15078. {
  15079. if ((opToken != NULL) && (!noClassify))
  15080. mModule->SetElementType(opToken, BfSourceElementType_Method);
  15081. SizedArray<BfResolvedArg, 4> argValues;
  15082. BfResolvedArg resolvedArg;
  15083. resolvedArg.mTypedValue = leftValue;
  15084. argValues.push_back(resolvedArg);
  15085. resolvedArg.mTypedValue = rightValue;
  15086. argValues.push_back(resolvedArg);
  15087. mResult = CreateCall(opToken, BfTypedValue(), BfTypedValue(), moduleMethodInstance.mMethodInstance->mMethodDef, moduleMethodInstance, false, argValues);
  15088. if ((mResult) && (binaryOp == BfBinaryOp_InEquality))
  15089. mResult.mValue = mModule->mBfIRBuilder->CreateNot(mResult.mValue);
  15090. return true;
  15091. }
  15092. return false;
  15093. };
  15094. if (((leftValue.mType->IsComposite()) || (leftValue.mType->IsObject())))
  15095. {
  15096. bool areEquivalentTuples = false;
  15097. if ((leftValue.mType->IsTuple()) && (rightValue.mType->IsTuple()))
  15098. {
  15099. auto leftTupleType = (BfTupleType*)leftValue.mType;
  15100. auto rightTupleType = (BfTupleType*)rightValue.mType;
  15101. // We only do this for tuples, because we would allow an implicit struct
  15102. // truncation if we allow it for all structs, which would result in only
  15103. // the base class's fields being compared
  15104. if (mModule->CanImplicitlyCast(rightValue, leftValue.mType))
  15105. rightValue = mModule->Cast(opToken, rightValue, leftValue.mType, BfCastFlags_Explicit);
  15106. else if (mModule->CanImplicitlyCast(leftValue, rightValue.mType))
  15107. leftValue = mModule->Cast(opToken, leftValue, rightValue.mType, BfCastFlags_Explicit);
  15108. }
  15109. if (leftValue.mType == rightValue.mType)
  15110. {
  15111. if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_InEquality))
  15112. {
  15113. auto intCoercibleType = mModule->GetIntCoercibleType(leftValue.mType);
  15114. if (intCoercibleType != NULL)
  15115. {
  15116. auto intLHS = mModule->GetIntCoercible(leftValue);
  15117. auto intRHS = mModule->GetIntCoercible(rightValue);
  15118. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  15119. if (binaryOp == BfBinaryOp_Equality)
  15120. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(intLHS.mValue, intRHS.mValue), boolType);
  15121. else
  15122. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(intLHS.mValue, intRHS.mValue), boolType);
  15123. return;
  15124. }
  15125. if (_CallValueTypeEquals())
  15126. return;
  15127. }
  15128. mModule->Fail(StrFormat("Operator '%s' cannot be applied to operands of type '%s'",
  15129. BfGetOpName(binaryOp),
  15130. mModule->TypeToString(leftValue.mType).c_str()), opToken);
  15131. }
  15132. else
  15133. {
  15134. mModule->Fail(StrFormat("Operator '%s' cannot be applied to operands of type '%s' and '%s'",
  15135. BfGetOpName(binaryOp),
  15136. mModule->TypeToString(leftValue.mType).c_str(),
  15137. mModule->TypeToString(rightValue.mType).c_str()), opToken);
  15138. }
  15139. return;
  15140. }
  15141. if (resultType->IsMethodRef() && otherType->IsMethodRef())
  15142. {
  15143. if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_InEquality))
  15144. {
  15145. auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
  15146. BfMethodRefType* lhsMethodRefType = (BfMethodRefType*)leftValue.mType;
  15147. BfMethodRefType* rhsMethodRefType = (BfMethodRefType*)rightValue.mType;
  15148. if (lhsMethodRefType->mMethodRef != rhsMethodRefType->mMethodRef)
  15149. {
  15150. mResult = BfTypedValue(mModule->GetConstValue((binaryOp == BfBinaryOp_Equality) ? 0 : 1, boolType), boolType);
  15151. return;
  15152. }
  15153. if (_CallValueTypeEquals())
  15154. return;
  15155. }
  15156. }
  15157. if (resultType->IsIntegral())
  15158. {
  15159. if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift))
  15160. {
  15161. if (rightValue.mValue.IsConst())
  15162. {
  15163. auto constVal = mModule->mBfIRBuilder->GetConstant(rightValue.mValue);
  15164. if ((constVal->mInt64 < 0) || (constVal->mInt64 >= 8 * resultType->mSize))
  15165. {
  15166. mModule->Fail(StrFormat("Shift value '%lld' is out of range for type '%s'", constVal->mInt64, mModule->TypeToString(resultType).c_str()), opToken);
  15167. }
  15168. }
  15169. }
  15170. // We're trying a simplified scheme that doesn't always try to up-convert into an 'int'
  15171. if (leftValue.mType != rightValue.mType)
  15172. {
  15173. bool isBitwiseExpr =
  15174. (binaryOp == BfBinaryOp_BitwiseAnd) |
  15175. (binaryOp == BfBinaryOp_BitwiseOr) |
  15176. (binaryOp == BfBinaryOp_ExclusiveOr) |
  15177. (binaryOp == BfBinaryOp_LeftShift) |
  15178. (binaryOp == BfBinaryOp_RightShift) |
  15179. (binaryOp == BfBinaryOp_Equality) |
  15180. (binaryOp == BfBinaryOp_InEquality);
  15181. if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift))
  15182. {
  15183. // For shifts we have more lenient rules - shifts are naturally limited so any int type is equally valid
  15184. if (rightValue.mType->IsIntegral())
  15185. explicitCast = true;
  15186. }
  15187. else if (((binaryOp == BfBinaryOp_Add) || (binaryOp == BfBinaryOp_Subtract)) && (resultType->IsChar()) && (otherType->IsInteger()))
  15188. {
  15189. // charVal += intVal;
  15190. explicitCast = true;
  15191. }
  15192. else if ((!resultType->IsSigned()) && (otherType->IsSigned()))
  15193. {
  15194. if (mModule->CanImplicitlyCast(*otherTypedValue, resultType))
  15195. {
  15196. // If we can convert the 'other' value implicitly then it's a convertible literal, leave as uint
  15197. }
  15198. else
  15199. {
  15200. mModule->Fail(StrFormat("Operator cannot be applied to operands of type '%s' and '%s'",
  15201. mModule->TypeToString(leftValue.mType).c_str(),
  15202. mModule->TypeToString(rightValue.mType).c_str()), opToken);
  15203. return;
  15204. }
  15205. }
  15206. else if ((isBitwiseExpr) && (otherType->IsIntegral()) && (resultType->mSize == otherType->mSize))
  15207. {
  15208. // Forget about signed/unsigned mismatches for bitwise operations
  15209. explicitCast = true;
  15210. }
  15211. else
  15212. {
  15213. if ((binaryOp == BfBinaryOp_Subtract) && (resultType->IsChar()) && (otherType->IsChar()))
  15214. {
  15215. // "wchar - char" subtraction will always fit into int32, because of unicode range
  15216. resultType = mModule->GetPrimitiveType(BfTypeCode_Int32);
  15217. explicitCast = true;
  15218. }
  15219. else if ((otherType->IsChar()) &&
  15220. ((binaryOp == BfBinaryOp_Add) || (binaryOp == BfBinaryOp_Subtract)))
  15221. {
  15222. mModule->Fail(StrFormat("Cannot perform operation between types '%s' and '%s'",
  15223. mModule->TypeToString(leftValue.mType).c_str(),
  15224. mModule->TypeToString(rightValue.mType).c_str()), opToken);
  15225. }
  15226. }
  15227. }
  15228. else if ((!resultType->IsSigned()) && (binaryOp == BfBinaryOp_Subtract) && (!forceLeftType))
  15229. {
  15230. if ((mExpectingType == NULL) || (mExpectingType->IsSigned()) || (resultType->IsChar()))
  15231. {
  15232. if ((resultType->IsChar()) && (resultType->mSize == 4))
  15233. {
  15234. // "wchar - wchar" subtraction will always fit into int32, because of unicode range
  15235. resultType = mModule->GetPrimitiveType(BfTypeCode_Int32);
  15236. }
  15237. else
  15238. {
  15239. // The result of uint8 - uint8 is int16 (for example)
  15240. switch (resultType->mSize)
  15241. {
  15242. case 1:
  15243. resultType = mModule->GetPrimitiveType(BfTypeCode_Int16);
  15244. break;
  15245. case 2:
  15246. resultType = mModule->GetPrimitiveType(BfTypeCode_Int32);
  15247. break;
  15248. case 4:
  15249. resultType = mModule->GetPrimitiveType(BfTypeCode_Int64);
  15250. break;
  15251. }
  15252. }
  15253. explicitCast = true;
  15254. }
  15255. }
  15256. else if (resultType->IsChar())
  15257. {
  15258. bool canDoOp =
  15259. (binaryOp == BfBinaryOp_BitwiseAnd) ||
  15260. (binaryOp == BfBinaryOp_BitwiseOr) ||
  15261. ((binaryOp >= BfBinaryOp_Equality) && (binaryOp <= BfBinaryOp_Compare));
  15262. if (!canDoOp)
  15263. {
  15264. mModule->Fail(StrFormat("Cannot perform operation on type '%s'", mModule->TypeToString(resultType).c_str()), opToken);
  15265. return;
  15266. }
  15267. }
  15268. }
  15269. if (!convLeftValue)
  15270. convLeftValue = mModule->CastToValue(leftExpression, leftValue, resultType,
  15271. explicitCast ? (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_FromCompiler) : BfCastFlags_None);
  15272. if (!convRightValue)
  15273. convRightValue = mModule->CastToValue(rightExpression, rightValue, resultType,
  15274. explicitCast ? (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_FromCompiler) : BfCastFlags_None);
  15275. PerformBinaryOperation(resultType, convLeftValue, convRightValue, binaryOp, opToken);
  15276. }
  15277. void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convLeftValue, BfIRValue convRightValue, BfBinaryOp binaryOp, BfAstNode* opToken)
  15278. {
  15279. if (resultType->IsValuelessType())
  15280. {
  15281. switch (binaryOp)
  15282. {
  15283. case BfBinaryOp_Equality:
  15284. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 1),
  15285. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  15286. break;
  15287. case BfBinaryOp_InEquality:
  15288. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 0),
  15289. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  15290. break;
  15291. default:
  15292. mModule->Fail("Invalid operation for void", opToken);
  15293. break;
  15294. }
  15295. return;
  15296. }
  15297. if ((!convLeftValue) || (!convRightValue))
  15298. return;
  15299. if (resultType->IsPrimitiveType())
  15300. {
  15301. auto primType = (BfPrimitiveType*)resultType;
  15302. if (primType->mTypeDef->mTypeCode == BfTypeCode_Boolean)
  15303. {
  15304. switch (binaryOp)
  15305. {
  15306. case BfBinaryOp_Equality:
  15307. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(convLeftValue, convRightValue),
  15308. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  15309. break;
  15310. case BfBinaryOp_InEquality:
  15311. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(convLeftValue, convRightValue),
  15312. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  15313. break;
  15314. case BfBinaryOp_BitwiseAnd:
  15315. case BfBinaryOp_ConditionalAnd:
  15316. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateAnd(convLeftValue, convRightValue),
  15317. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  15318. break;
  15319. case BfBinaryOp_BitwiseOr:
  15320. case BfBinaryOp_ConditionalOr:
  15321. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateOr(convLeftValue, convRightValue),
  15322. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  15323. break;
  15324. case BfBinaryOp_ExclusiveOr:
  15325. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateXor(convLeftValue, convRightValue),
  15326. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  15327. break;
  15328. default:
  15329. mModule->Fail("Invalid operation for booleans", opToken);
  15330. break;
  15331. }
  15332. return;
  15333. }
  15334. }
  15335. if ((!resultType->IsIntegral()) && (!resultType->IsFloat()))
  15336. {
  15337. mModule->Fail(StrFormat("Cannot perform operation on type '%s'", mModule->TypeToString(resultType).c_str()), opToken);
  15338. return;
  15339. }
  15340. if (resultType->IsIntegral())
  15341. {
  15342. switch (binaryOp)
  15343. {
  15344. case BfBinaryOp_BitwiseAnd:
  15345. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateAnd(convLeftValue, convRightValue), resultType);
  15346. return;
  15347. case BfBinaryOp_BitwiseOr:
  15348. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateOr(convLeftValue, convRightValue), resultType);
  15349. return;
  15350. case BfBinaryOp_ExclusiveOr:
  15351. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateXor(convLeftValue, convRightValue), resultType);
  15352. return;
  15353. case BfBinaryOp_LeftShift:
  15354. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateShl(convLeftValue, convRightValue), resultType);
  15355. mModule->CheckRangeError(resultType, opToken);
  15356. return;
  15357. case BfBinaryOp_RightShift:
  15358. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateShr(convLeftValue, convRightValue, resultType->IsSigned()), resultType);
  15359. return;
  15360. }
  15361. }
  15362. if ((resultType->IsChar()) &&
  15363. ((binaryOp == BfBinaryOp_Multiply) ||
  15364. (binaryOp == BfBinaryOp_Divide) ||
  15365. (binaryOp == BfBinaryOp_Modulus)))
  15366. {
  15367. mModule->Fail(StrFormat("Cannot perform operation on type '%s'", mModule->TypeToString(resultType).c_str()), opToken);
  15368. return;
  15369. }
  15370. switch (binaryOp)
  15371. {
  15372. case BfBinaryOp_Add:
  15373. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateAdd(convLeftValue, convRightValue), resultType);
  15374. mModule->CheckRangeError(resultType, opToken);
  15375. break;
  15376. case BfBinaryOp_Subtract:
  15377. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateSub(convLeftValue, convRightValue), resultType);
  15378. mModule->CheckRangeError(resultType, opToken);
  15379. break;
  15380. case BfBinaryOp_Multiply:
  15381. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateMul(convLeftValue, convRightValue), resultType);
  15382. mModule->CheckRangeError(resultType, opToken);
  15383. break;
  15384. case BfBinaryOp_Divide:
  15385. {
  15386. bool isZero = false;
  15387. if (convRightValue.IsConst())
  15388. {
  15389. auto constVal = mModule->mBfIRBuilder->GetConstant(convRightValue);
  15390. if (BfIRBuilder::IsInt(constVal->mTypeCode))
  15391. isZero = constVal->mInt64 == 0;
  15392. }
  15393. if (isZero)
  15394. {
  15395. mModule->Fail("Divide by zero", opToken);
  15396. mResult = mModule->GetDefaultTypedValue(resultType);
  15397. }
  15398. else
  15399. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateDiv(convLeftValue, convRightValue, resultType->IsSigned()), resultType);
  15400. }
  15401. break;
  15402. case BfBinaryOp_Modulus:
  15403. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateRem(convLeftValue, convRightValue, resultType->IsSigned()), resultType);
  15404. break;
  15405. case BfBinaryOp_Equality:
  15406. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(convLeftValue, convRightValue),
  15407. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  15408. break;
  15409. case BfBinaryOp_InEquality:
  15410. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(convLeftValue, convRightValue),
  15411. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  15412. break;
  15413. case BfBinaryOp_LessThan:
  15414. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpLT(convLeftValue, convRightValue, resultType->IsSignedInt()),
  15415. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  15416. break;
  15417. case BfBinaryOp_LessThanOrEqual:
  15418. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpLTE(convLeftValue, convRightValue, resultType->IsSignedInt()),
  15419. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  15420. break;
  15421. case BfBinaryOp_GreaterThan:
  15422. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpGT(convLeftValue, convRightValue, resultType->IsSignedInt()),
  15423. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  15424. break;
  15425. case BfBinaryOp_GreaterThanOrEqual:
  15426. mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpGTE(convLeftValue, convRightValue, resultType->IsSignedInt()),
  15427. mModule->GetPrimitiveType(BfTypeCode_Boolean));
  15428. break;
  15429. case BfBinaryOp_Compare:
  15430. {
  15431. auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
  15432. BfIRBlock checkGtBlock = mModule->mBfIRBuilder->CreateBlock("cmpCheckGt");
  15433. BfIRBlock eqBlock = mModule->mBfIRBuilder->CreateBlock("cmpEq");
  15434. BfIRBlock endBlock = mModule->mBfIRBuilder->CreateBlock("cmpEnd");
  15435. auto startBlock = mModule->mBfIRBuilder->GetInsertBlock();
  15436. auto cmpLtVal = mModule->mBfIRBuilder->CreateCmpLT(convLeftValue, convRightValue, resultType->IsSignedInt());
  15437. mModule->mBfIRBuilder->CreateCondBr(cmpLtVal, endBlock, checkGtBlock);
  15438. mModule->mBfIRBuilder->AddBlock(checkGtBlock);
  15439. mModule->mBfIRBuilder->SetInsertPoint(checkGtBlock);
  15440. auto cmpGtVal = mModule->mBfIRBuilder->CreateCmpGT(convLeftValue, convRightValue, resultType->IsSignedInt());
  15441. mModule->mBfIRBuilder->CreateCondBr(cmpGtVal, endBlock, eqBlock);
  15442. mModule->mBfIRBuilder->AddBlock(eqBlock);
  15443. mModule->mBfIRBuilder->SetInsertPoint(eqBlock);
  15444. mModule->mBfIRBuilder->CreateBr(endBlock);
  15445. mModule->mBfIRBuilder->AddBlock(endBlock);
  15446. mModule->mBfIRBuilder->SetInsertPoint(endBlock);
  15447. auto phiVal = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(intType), 3);
  15448. mModule->mBfIRBuilder->AddPhiIncoming(phiVal, mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, -1), startBlock);
  15449. mModule->mBfIRBuilder->AddPhiIncoming(phiVal, mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 1), checkGtBlock);
  15450. mModule->mBfIRBuilder->AddPhiIncoming(phiVal, mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0), eqBlock);
  15451. mResult = BfTypedValue(phiVal, intType);
  15452. }
  15453. break;
  15454. default:
  15455. mModule->Fail("Invalid operation", opToken);
  15456. break;
  15457. }
  15458. }
  15459. void BfExprEvaluator::Visit(BfBinaryOperatorExpression* binOpExpr)
  15460. {
  15461. BfAutoParentNodeEntry autoParentNodeEntry(mModule, binOpExpr);
  15462. // There are a few binary operations that could actually be casts followed by an unary operation
  15463. // We can't determine that until we know whether the identifier in the parens is a typename or not
  15464. // (double)-1.0 (intptr)&val (BaseStruct)*val
  15465. BfUnaryOp unaryOp = BfUnaryOp_None;
  15466. switch (binOpExpr->mOp)
  15467. {
  15468. case BfBinaryOp_Add: unaryOp = BfUnaryOp_Positive; break;
  15469. case BfBinaryOp_Subtract: unaryOp = BfUnaryOp_Negate; break;
  15470. case BfBinaryOp_Multiply: unaryOp = BfUnaryOp_Dereference; break;
  15471. case BfBinaryOp_BitwiseAnd: unaryOp = BfUnaryOp_AddressOf; break;
  15472. default: break;
  15473. }
  15474. if (unaryOp != BfUnaryOp_None)
  15475. {
  15476. if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(binOpExpr->mLeft))
  15477. {
  15478. if (auto castTypeExpr = BfNodeDynCast<BfIdentifierNode>(parenExpr->mExpression))
  15479. {
  15480. SetAndRestoreValue<bool> prevIgnoreError(mModule->mIgnoreErrors, true);
  15481. auto resolvedType = mModule->ResolveTypeRef(castTypeExpr, NULL);
  15482. prevIgnoreError.Restore();
  15483. if (resolvedType != NULL)
  15484. {
  15485. if (auto rightBinOpExpr = BfNodeDynCast<BfBinaryOperatorExpression>(binOpExpr->mRight))
  15486. {
  15487. int leftPrecedence = BfGetBinaryOpPrecendence(binOpExpr->mOp);
  15488. int rightPrecedence = BfGetBinaryOpPrecendence(rightBinOpExpr->mOp);
  15489. // Do we have a precedence order issue due to mis-parsing this?
  15490. // An example is: "(int)-5.5 * 10"
  15491. if (rightPrecedence > leftPrecedence)
  15492. {
  15493. mModule->FailAfter("Cast target must be wrapped in parentheses", binOpExpr->mLeft);
  15494. }
  15495. }
  15496. PerformUnaryOperation(binOpExpr->mRight, unaryOp, binOpExpr->mOpToken);
  15497. if (mResult)
  15498. {
  15499. mResult = mModule->LoadValue(mResult);
  15500. mResult = mModule->Cast(binOpExpr, mResult, resolvedType, BfCastFlags_Explicit);
  15501. }
  15502. return;
  15503. }
  15504. }
  15505. }
  15506. }
  15507. if (binOpExpr->mRight == NULL)
  15508. {
  15509. // We visit the children for autocompletion only
  15510. if (binOpExpr->mLeft != NULL)
  15511. VisitChild(binOpExpr->mLeft);
  15512. if (mResult)
  15513. {
  15514. auto autoComplete = GetAutoComplete();
  15515. if (autoComplete != NULL)
  15516. autoComplete->CheckEmptyStart(binOpExpr->mOpToken, mResult.mType);
  15517. }
  15518. if (binOpExpr->mRight != NULL)
  15519. VisitChild(binOpExpr->mRight);
  15520. return;
  15521. }
  15522. PerformBinaryOperation(binOpExpr->mLeft, binOpExpr->mRight, binOpExpr->mOp, binOpExpr->mOpToken, BfBinOpFlag_None);
  15523. }