BfModuleTypeUtils.cpp 407 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920
  1. #include "BeefySysLib/util/AllocDebug.h"
  2. #include "BfCompiler.h"
  3. #include "BfSystem.h"
  4. #include "BfParser.h"
  5. #include "BfCodeGen.h"
  6. #include "BfExprEvaluator.h"
  7. #include <fcntl.h>
  8. #include "BfConstResolver.h"
  9. #include "BfMangler.h"
  10. #include "BeefySysLib/util/PerfTimer.h"
  11. #include "BeefySysLib/util/BeefPerf.h"
  12. #include "BfSourceClassifier.h"
  13. #include "BfAutoComplete.h"
  14. #include "BfDemangler.h"
  15. #include "BfResolvePass.h"
  16. #include "BfFixits.h"
  17. #include "BfIRCodeGen.h"
  18. #include "BfDefBuilder.h"
  19. //////////////////////////////////////////////////////////////////////////
  20. int32 GetNumLowZeroBits(int32 n)
  21. {
  22. if (n == 0)
  23. return 32;
  24. int i = 0;
  25. while ((n & 1) == 0)
  26. {
  27. n = (int32)((uint32)n >> 1);
  28. i++;
  29. }
  30. return i;
  31. }
  32. //////////////////////////////////////////////////////////////////////////
  33. USING_NS_BF;
  34. BfGenericExtensionEntry* BfModule::BuildGenericExtensionInfo(BfTypeInstance* genericTypeInst, BfTypeDef* partialTypeDef)
  35. {
  36. if (!partialTypeDef->IsExtension())
  37. return NULL;
  38. if (partialTypeDef->mGenericParamDefs.size() != genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size())
  39. {
  40. AssertErrorState();
  41. return NULL;
  42. }
  43. BfGenericExtensionInfo* genericExtensionInfo = genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo;
  44. if (genericExtensionInfo == NULL)
  45. {
  46. genericExtensionInfo = new BfGenericExtensionInfo();
  47. genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo = genericExtensionInfo;
  48. }
  49. BfTypeState typeState;
  50. typeState.mPrevState = mContext->mCurTypeState;
  51. typeState.mTypeInstance = genericTypeInst;
  52. typeState.mCurTypeDef = partialTypeDef;
  53. SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
  54. BfGenericExtensionEntry* genericExEntry;
  55. genericExtensionInfo->mExtensionMap.TryAdd(partialTypeDef, NULL, &genericExEntry);
  56. int startDefGenericParamIdx = (int)genericExEntry->mGenericParams.size();
  57. for (int paramIdx = startDefGenericParamIdx; paramIdx < (int)genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size(); paramIdx++)
  58. {
  59. auto genericParamInstance = new BfGenericTypeParamInstance(partialTypeDef, paramIdx);
  60. genericParamInstance->mExternType = GetGenericParamType(BfGenericParamKind_Type, paramIdx);
  61. auto prevPtr = genericExEntry->mGenericParams.mVals;
  62. genericExEntry->mGenericParams.push_back(genericParamInstance);
  63. }
  64. for (int externConstraintIdx = 0; externConstraintIdx < (int)partialTypeDef->mExternalConstraints.size(); externConstraintIdx++)
  65. {
  66. auto& genericConstraint = partialTypeDef->mExternalConstraints[externConstraintIdx];
  67. auto genericParamInstance = new BfGenericTypeParamInstance(partialTypeDef, externConstraintIdx + (int)partialTypeDef->mGenericParamDefs.size());
  68. genericParamInstance->mExternType = ResolveTypeRef(genericConstraint.mTypeRef);
  69. auto autoComplete = mCompiler->GetAutoComplete();
  70. if (autoComplete != NULL)
  71. autoComplete->CheckTypeRef(genericConstraint.mTypeRef, false);
  72. if (genericParamInstance->mExternType == NULL)
  73. genericParamInstance->mExternType = GetPrimitiveType(BfTypeCode_Var);
  74. ResolveGenericParamConstraints(genericParamInstance, genericTypeInst->IsUnspecializedType());
  75. genericExEntry->mGenericParams.push_back(genericParamInstance);
  76. }
  77. for (int paramIdx = startDefGenericParamIdx; paramIdx < (int)genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size(); paramIdx++)
  78. {
  79. auto genericParamInstance = genericExEntry->mGenericParams[paramIdx];
  80. auto rootGenericParamInstance = genericTypeInst->mGenericTypeInfo->mGenericParams[paramIdx];
  81. genericParamInstance->mTypeConstraint = rootGenericParamInstance->mTypeConstraint;
  82. genericParamInstance->mInterfaceConstraints = rootGenericParamInstance->mInterfaceConstraints;
  83. genericParamInstance->mGenericParamFlags |= rootGenericParamInstance->mGenericParamFlags;
  84. ResolveGenericParamConstraints(genericParamInstance, genericTypeInst->IsUnspecializedType());
  85. }
  86. for (auto genericParam : genericExEntry->mGenericParams)
  87. {
  88. for (auto constraintTypeInst : genericParam->mInterfaceConstraints)
  89. AddDependency(constraintTypeInst, mCurTypeInstance, BfDependencyMap::DependencyFlag_Constraint);
  90. if (genericParam->mTypeConstraint != NULL)
  91. AddDependency(genericParam->mTypeConstraint, mCurTypeInstance, BfDependencyMap::DependencyFlag_Constraint);
  92. }
  93. return genericExEntry;
  94. }
  95. bool BfModule::BuildGenericParams(BfType* resolvedTypeRef)
  96. {
  97. BfTypeState typeState;
  98. typeState.mPrevState = mContext->mCurTypeState;
  99. typeState.mResolveKind = BfTypeState::ResolveKind_BuildingGenericParams;
  100. typeState.mTypeInstance = resolvedTypeRef->ToTypeInstance();
  101. SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
  102. BF_ASSERT(mCurMethodInstance == NULL);
  103. auto genericTypeInst = resolvedTypeRef->ToGenericTypeInstance();
  104. if (genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[0]->IsGenericParam())
  105. {
  106. BF_ASSERT(genericTypeInst->mGenericTypeInfo->mIsUnspecialized);
  107. }
  108. auto typeDef = genericTypeInst->mTypeDef;
  109. int startDefGenericParamIdx = (int)genericTypeInst->mGenericTypeInfo->mGenericParams.size();
  110. for (int paramIdx = startDefGenericParamIdx; paramIdx < (int)genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size(); paramIdx++)
  111. {
  112. auto genericParamInstance = new BfGenericTypeParamInstance(typeDef, paramIdx);
  113. genericParamInstance->mExternType = GetGenericParamType(BfGenericParamKind_Type, paramIdx);
  114. genericTypeInst->mGenericTypeInfo->mGenericParams.push_back(genericParamInstance);
  115. }
  116. for (int externConstraintIdx = 0; externConstraintIdx < (int)typeDef->mExternalConstraints.size(); externConstraintIdx++)
  117. {
  118. auto genericParamInstance = new BfGenericTypeParamInstance(typeDef, externConstraintIdx + (int)typeDef->mGenericParamDefs.size());
  119. genericTypeInst->mGenericTypeInfo->mGenericParams.push_back(genericParamInstance);
  120. }
  121. if (!typeDef->mPartials.empty())
  122. {
  123. for (auto partialTypeDef : typeDef->mPartials)
  124. {
  125. if (!partialTypeDef->IsExtension())
  126. {
  127. typeState.mCurTypeDef = partialTypeDef;
  128. for (int paramIdx = startDefGenericParamIdx; paramIdx < (int)genericTypeInst->mGenericTypeInfo->mGenericParams.size(); paramIdx++)
  129. {
  130. auto genericParamInstance = genericTypeInst->mGenericTypeInfo->mGenericParams[paramIdx];
  131. auto genericParamDef = genericParamInstance->GetGenericParamDef();
  132. if (paramIdx < (int)typeDef->mGenericParamDefs.size())
  133. {
  134. genericParamInstance->mExternType = GetGenericParamType(BfGenericParamKind_Type, paramIdx);
  135. }
  136. else
  137. {
  138. auto externConstraintDef = genericParamInstance->GetExternConstraintDef();
  139. genericParamInstance->mExternType = ResolveTypeRef(externConstraintDef->mTypeRef);
  140. if (genericParamInstance->mExternType == NULL)
  141. genericParamInstance->mExternType = GetPrimitiveType(BfTypeCode_Var);
  142. }
  143. ResolveGenericParamConstraints(genericParamInstance, genericTypeInst->IsUnspecializedType());
  144. if (genericParamDef != NULL)
  145. {
  146. for (auto nameNode : genericParamDef->mNameNodes)
  147. {
  148. HandleTypeGenericParamRef(nameNode, typeDef, paramIdx);
  149. }
  150. }
  151. }
  152. }
  153. else
  154. {
  155. auto genericExEntry = BuildGenericExtensionInfo(genericTypeInst, partialTypeDef);
  156. if (genericExEntry == NULL)
  157. continue;
  158. if (!genericTypeInst->IsUnspecializedType())
  159. {
  160. SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, true);
  161. for (int paramIdx = 0; paramIdx < genericExEntry->mGenericParams.size(); paramIdx++)
  162. {
  163. auto genericParamInstance = genericExEntry->mGenericParams[paramIdx];
  164. BfGenericParamSource genericParamSource;
  165. genericParamSource.mCheckAccessibility = false;
  166. genericParamSource.mTypeInstance = genericTypeInst;
  167. BfError* error = NULL;
  168. BfType* genericArg;
  169. if (paramIdx < (int)genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size())
  170. {
  171. genericArg = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[paramIdx];
  172. }
  173. else
  174. {
  175. genericArg = genericParamInstance->mExternType;
  176. }
  177. if ((genericArg == NULL) || (!CheckGenericConstraints(genericParamSource, genericArg, NULL, genericParamInstance, NULL, &error)))
  178. {
  179. genericExEntry->mConstraintsPassed = false;
  180. }
  181. }
  182. }
  183. }
  184. }
  185. }
  186. else
  187. {
  188. for (int paramIdx = startDefGenericParamIdx; paramIdx < (int)genericTypeInst->mGenericTypeInfo->mGenericParams.size(); paramIdx++)
  189. {
  190. auto genericParamInstance = genericTypeInst->mGenericTypeInfo->mGenericParams[paramIdx];
  191. if (paramIdx < (int)typeDef->mGenericParamDefs.size())
  192. {
  193. genericParamInstance->mExternType = GetGenericParamType(BfGenericParamKind_Type, paramIdx);
  194. }
  195. else
  196. {
  197. auto externConstraintDef = genericParamInstance->GetExternConstraintDef();
  198. genericParamInstance->mExternType = ResolveTypeRef(externConstraintDef->mTypeRef);
  199. auto autoComplete = mCompiler->GetAutoComplete();
  200. if (autoComplete != NULL)
  201. autoComplete->CheckTypeRef(externConstraintDef->mTypeRef, false);
  202. if (genericParamInstance->mExternType != NULL)
  203. {
  204. //
  205. }
  206. else
  207. genericParamInstance->mExternType = GetPrimitiveType(BfTypeCode_Var);
  208. }
  209. ResolveGenericParamConstraints(genericParamInstance, genericTypeInst->IsUnspecializedType());
  210. auto genericParamDef = genericParamInstance->GetGenericParamDef();
  211. if (genericParamDef != NULL)
  212. {
  213. for (auto nameNode : genericParamDef->mNameNodes)
  214. {
  215. HandleTypeGenericParamRef(nameNode, typeDef, paramIdx);
  216. }
  217. }
  218. }
  219. }
  220. for (auto genericParam : genericTypeInst->mGenericTypeInfo->mGenericParams)
  221. {
  222. for (auto constraintTypeInst : genericParam->mInterfaceConstraints)
  223. AddDependency(constraintTypeInst, mCurTypeInstance, BfDependencyMap::DependencyFlag_Constraint);
  224. if (genericParam->mTypeConstraint != NULL)
  225. AddDependency(genericParam->mTypeConstraint, mCurTypeInstance, BfDependencyMap::DependencyFlag_Constraint);
  226. }
  227. return true;
  228. }
  229. bool BfModule::ValidateGenericConstraints(BfTypeReference* typeRef, BfTypeInstance* genericTypeInst, bool ignoreErrors)
  230. {
  231. if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsTypeAlias()))
  232. {
  233. // Don't validate constraints during the population of a concrete generic type alias instance, we want to
  234. // throw those errors at the usage sites
  235. return true;
  236. }
  237. // We don't validate constraints for things like Tuples/Delegates
  238. if (genericTypeInst->IsOnDemand())
  239. return true;
  240. SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, mIgnoreErrors || ignoreErrors);
  241. genericTypeInst->mGenericTypeInfo->mValidatedGenericConstraints = true;
  242. if (genericTypeInst->IsTypeAlias())
  243. {
  244. auto underlyingType = genericTypeInst->GetUnderlyingType();
  245. if ((underlyingType != NULL) && (underlyingType->IsGenericTypeInstance()))
  246. {
  247. PopulateType(underlyingType, BfPopulateType_Declaration);
  248. return ValidateGenericConstraints(typeRef, (BfTypeInstance*)underlyingType, ignoreErrors);
  249. }
  250. return true;
  251. }
  252. auto typeDef = genericTypeInst->mTypeDef;
  253. //for (int paramIdx = 0; paramIdx < (int)genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size(); paramIdx++)
  254. for (int paramIdx = 0; paramIdx < (int)genericTypeInst->mGenericTypeInfo->mGenericParams.size(); paramIdx++)
  255. {
  256. auto genericParamInstance = genericTypeInst->mGenericTypeInfo->mGenericParams[paramIdx];
  257. BfType* genericArg;
  258. if (paramIdx < (int)genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size())
  259. {
  260. genericArg = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[paramIdx];
  261. }
  262. else
  263. {
  264. genericArg = genericParamInstance->mExternType;
  265. }
  266. BfError* error = NULL;
  267. if ((genericArg == NULL) || (!CheckGenericConstraints(BfGenericParamSource(genericTypeInst), genericArg, typeRef, genericParamInstance, NULL, &error)))
  268. {
  269. genericTypeInst->mGenericTypeInfo->mHadValidateErrors = true;
  270. return false;
  271. }
  272. }
  273. return true;
  274. }
  275. bool BfModule::AreConstraintsSubset(BfGenericParamInstance* checkInner, BfGenericParamInstance* checkOuter)
  276. {
  277. // Added new flags?
  278. if ((checkInner->mGenericParamFlags | checkOuter->mGenericParamFlags) != checkOuter->mGenericParamFlags)
  279. {
  280. // If the outer had a type flag and the inner has a specific type constraint, then see if those are compatible
  281. auto outerFlags = checkOuter->mGenericParamFlags;
  282. if (checkOuter->mTypeConstraint != NULL)
  283. {
  284. if (checkOuter->mTypeConstraint->IsStruct())
  285. outerFlags |= BfGenericParamFlag_Struct;
  286. else if (checkOuter->mTypeConstraint->IsStructOrStructPtr())
  287. outerFlags |= BfGenericParamFlag_StructPtr;
  288. else if (checkOuter->mTypeConstraint->IsObject())
  289. outerFlags |= BfGenericParamFlag_Class;
  290. }
  291. if (((checkInner->mGenericParamFlags | outerFlags) & ~BfGenericParamFlag_Var) != (outerFlags & ~BfGenericParamFlag_Var))
  292. return false;
  293. }
  294. if (checkInner->mTypeConstraint != NULL)
  295. {
  296. if (checkOuter->mTypeConstraint == NULL)
  297. return false;
  298. if (!TypeIsSubTypeOf(checkOuter->mTypeConstraint->ToTypeInstance(), checkInner->mTypeConstraint->ToTypeInstance()))
  299. return false;
  300. }
  301. for (auto& innerIFace : checkInner->mInterfaceConstraints)
  302. {
  303. if (!checkOuter->mInterfaceConstraints.Contains(innerIFace))
  304. return false;
  305. }
  306. for (auto& innerOp : checkInner->mOperatorConstraints)
  307. {
  308. if (!checkOuter->mOperatorConstraints.Contains(innerOp))
  309. return false;
  310. }
  311. return true;
  312. }
  313. bool BfModule::CheckConstraintState(BfAstNode* refNode)
  314. {
  315. if (mContext->mCurConstraintState == NULL)
  316. return true;
  317. auto checkState = mContext->mCurConstraintState->mPrevState;
  318. while (checkState != NULL)
  319. {
  320. if (*checkState == *mContext->mCurConstraintState)
  321. {
  322. if (refNode != NULL)
  323. {
  324. Fail("Constraints cause circular operator invocations", refNode);
  325. }
  326. return false;
  327. }
  328. checkState = checkState->mPrevState;
  329. }
  330. return true;
  331. }
  332. bool BfModule::ShouldAllowMultipleDefinitions(BfTypeInstance* typeInst, BfTypeDef* firstDeclaringTypeDef, BfTypeDef* secondDeclaringTypeDef)
  333. {
  334. if (firstDeclaringTypeDef == secondDeclaringTypeDef)
  335. return false;
  336. // Since we will use shared debugging info, we won't be able to differentiate between these two fields.
  337. // If we created per-target debug info then we could "fix" this.
  338. // Can these projects even see each other?
  339. if ((!firstDeclaringTypeDef->mProject->ContainsReference(secondDeclaringTypeDef->mProject)) &&
  340. (!secondDeclaringTypeDef->mProject->ContainsReference(firstDeclaringTypeDef->mProject)))
  341. return true;
  342. if (typeInst->IsUnspecializedType())
  343. {
  344. bool alwaysCoincide = true;
  345. auto genericTypeInst = (BfTypeInstance*)typeInst;
  346. if (genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo != NULL)
  347. {
  348. auto firstConstraints = genericTypeInst->GetGenericParamsVector(firstDeclaringTypeDef);
  349. auto secondConstraints = genericTypeInst->GetGenericParamsVector(secondDeclaringTypeDef);
  350. for (int genericIdx = 0; genericIdx < (int)firstConstraints->size(); genericIdx++)
  351. {
  352. auto firstConstraint = (*firstConstraints)[genericIdx];
  353. auto secondConstraint = (*secondConstraints)[genericIdx];
  354. if ((!AreConstraintsSubset(firstConstraint, secondConstraint)) &&
  355. (!AreConstraintsSubset(secondConstraint, firstConstraint)))
  356. alwaysCoincide = false;
  357. }
  358. }
  359. // Only show an error if we are certain both members will always appear at the same time
  360. if (!alwaysCoincide)
  361. return true;
  362. }
  363. return false;
  364. }
  365. void BfModule::CheckInjectNewRevision(BfTypeInstance* typeInstance)
  366. {
  367. if ((typeInstance != NULL) && (typeInstance->mTypeDef != NULL))
  368. {
  369. if (typeInstance->mTypeDef->mNextRevision != NULL)
  370. {
  371. // It's possible that our main compiler thread is generating a new typedef while we're autocompleting. This handles that case...
  372. if (typeInstance->mDefineState == BfTypeDefineState_Undefined)
  373. {
  374. if (typeInstance->IsBoxed())
  375. {
  376. BfBoxedType* boxedType = (BfBoxedType*)typeInstance;
  377. BfTypeInstance* innerType = boxedType->mElementType->ToTypeInstance();
  378. PopulateType(innerType, BfPopulateType_Data);
  379. }
  380. else
  381. {
  382. mContext->HandleChangedTypeDef(typeInstance->mTypeDef);
  383. mSystem->InjectNewRevision(typeInstance->mTypeDef);
  384. }
  385. }
  386. else
  387. {
  388. BF_ASSERT(mCompiler->IsAutocomplete());
  389. }
  390. }
  391. if ((!typeInstance->IsDeleting()) && (!mCompiler->IsAutocomplete()))
  392. BF_ASSERT((typeInstance->mTypeDef->mDefState == BfTypeDef::DefState_Defined) || (typeInstance->mTypeDef->mDefState == BfTypeDef::DefState_New));
  393. }
  394. }
  395. void BfModule::InitType(BfType* resolvedTypeRef, BfPopulateType populateType)
  396. {
  397. BP_ZONE("BfModule::InitType");
  398. SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, resolvedTypeRef->ToTypeInstance());
  399. SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, NULL);
  400. if (mCompiler->mHotState != NULL)
  401. mCompiler->mHotState->mHasNewTypes = true;
  402. auto typeInst = resolvedTypeRef->ToTypeInstance();
  403. if (typeInst != NULL)
  404. {
  405. CheckInjectNewRevision(typeInst);
  406. if (typeInst->mBaseType != NULL)
  407. BF_ASSERT((typeInst->mBaseType->mRebuildFlags & BfTypeRebuildFlag_Deleted) == 0);
  408. if ((typeInst->mTypeDef != NULL) && (typeInst->mTypeDef->mDefState == BfTypeDef::DefState_New) &&
  409. (typeInst->mTypeDef->mNextRevision == NULL))
  410. {
  411. mContext->HandleChangedTypeDef(typeInst->mTypeDef);
  412. typeInst->mTypeDef->mDefState = BfTypeDef::DefState_Defined;
  413. }
  414. typeInst->mIsReified = mIsReified;
  415. //BF_ASSERT(typeInst->mTypeDef->mTypeCode != BfTypeCode_Extension);
  416. if (resolvedTypeRef->IsTuple())
  417. {
  418. auto tupleType = (BfTypeInstance*)resolvedTypeRef;
  419. for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
  420. {
  421. auto fieldInstance = (BfFieldInstance*)&tupleType->mFieldInstances[fieldIdx];
  422. // if (fieldInstance->GetResolvedType()->IsUnspecializedType())
  423. // tupleType->mHasUnspecializedMembers = true;
  424. }
  425. }
  426. typeInst->mRevision = mCompiler->mRevision;
  427. if (typeInst->mTypeDef != NULL)
  428. BF_ASSERT(typeInst->mTypeDef->mDefState != BfTypeDef::DefState_Deleted);
  429. }
  430. if (resolvedTypeRef->IsGenericTypeInstance())
  431. {
  432. auto genericTypeInst = (BfTypeInstance*)resolvedTypeRef;
  433. //BF_ASSERT(genericTypeInst->mGenericParams.size() <= genericTypeInst->mTypeGenericArguments.size());
  434. // BF_ASSERT((genericTypeInst->mGenericParams.size() == 0) ||
  435. // (genericTypeInst->mGenericParams.size() == genericTypeInst->mTypeGenericArguments.size()));
  436. for (auto typeGenericArg : genericTypeInst->mGenericTypeInfo->mTypeGenericArguments)
  437. BF_ASSERT((typeGenericArg->mRebuildFlags & BfTypeRebuildFlag_Deleted) == 0);
  438. }
  439. if (!mContext->mSavedTypeDataMap.IsEmpty())
  440. {
  441. String typeName = BfSafeMangler::Mangle(resolvedTypeRef, this);
  442. BfSavedTypeData* savedTypeData;
  443. if (mContext->mSavedTypeDataMap.Remove(typeName, &savedTypeData))
  444. {
  445. // if (resolvedTypeRef->mTypeId != -1)
  446. // {
  447. // // If we have an ID and it as the last one assigned the roll back the ID counter
  448. // if (resolvedTypeRef->mTypeId == mCompiler->mCurTypeId - 1)
  449. // mCompiler->mCurTypeId--;
  450. // }
  451. mContext->mSavedTypeData[savedTypeData->mTypeId] = NULL;
  452. resolvedTypeRef->mTypeId = savedTypeData->mTypeId;
  453. BfLogSysM("Using mSavedTypeData for %p %s\n", resolvedTypeRef, typeName.c_str());
  454. if (typeInst != NULL)
  455. {
  456. if (mCompiler->IsHotCompile())
  457. {
  458. BfLogSysM("Using mSavedTypeData HotTypeData %p for %p\n", savedTypeData->mHotTypeData, resolvedTypeRef);
  459. typeInst->mHotTypeData = savedTypeData->mHotTypeData;
  460. savedTypeData->mHotTypeData = NULL;
  461. }
  462. }
  463. delete savedTypeData;
  464. mContext->mTypes[resolvedTypeRef->mTypeId] = resolvedTypeRef;
  465. }
  466. else
  467. {
  468. BfLogSysM("No mSavedTypeData entry for %p %s\n", resolvedTypeRef, typeName.c_str());
  469. }
  470. }
  471. resolvedTypeRef->mContext = mContext;
  472. if (resolvedTypeRef->IsGenericTypeInstance())
  473. {
  474. auto genericTypeInstance = (BfTypeInstance*)resolvedTypeRef;
  475. #ifdef _DEBUG
  476. for (auto genericArg : genericTypeInstance->mGenericTypeInfo->mTypeGenericArguments)
  477. BF_ASSERT(!genericArg->IsVar());
  478. #endif
  479. // Do it here so the location we attempted to specialize this type will throw the failure if there is one
  480. if (!BuildGenericParams(resolvedTypeRef))
  481. return;
  482. }
  483. BfLogSysM("%p InitType: %s Type: %p TypeDef: %p Revision:%d\n", mContext, TypeToString(resolvedTypeRef).c_str(), resolvedTypeRef, (typeInst != NULL) ? typeInst->mTypeDef : NULL, mCompiler->mRevision);
  484. // When we're autocomplete, we can't do the method processing so we have to add this type to the type work list
  485. if (((populateType < BfPopulateType_Full) || (mCompiler->IsAutocomplete())) /*&& (!resolvedTypeRef->IsUnspecializedTypeVariation())*/ && (resolvedTypeRef->IsTypeInstance()) &&
  486. (!resolvedTypeRef->IsTypeAlias()))
  487. {
  488. BfTypeProcessRequest* typeProcessRequest = mContext->mPopulateTypeWorkList.Alloc();
  489. typeProcessRequest->mType = resolvedTypeRef;
  490. BF_ASSERT(resolvedTypeRef->mContext == mContext);
  491. mCompiler->mStats.mTypesQueued++;
  492. mCompiler->UpdateCompletion();
  493. }
  494. PopulateType(resolvedTypeRef, populateType);
  495. }
  496. void BfModule::AddFieldDependency(BfTypeInstance* typeInstance, BfFieldInstance* fieldInstance, BfType* fieldType)
  497. {
  498. auto fieldTypeInstance = fieldType->ToTypeInstance();
  499. if (fieldTypeInstance == NULL)
  500. {
  501. auto underlyingType = fieldType->GetUnderlyingType();
  502. if (underlyingType != NULL)
  503. AddFieldDependency(typeInstance, fieldInstance, underlyingType);
  504. return;
  505. }
  506. auto depFlag = fieldTypeInstance->IsValueType() ? BfDependencyMap::DependencyFlag_ValueTypeMemberData : BfDependencyMap::DependencyFlag_PtrMemberData;
  507. AddDependency(fieldTypeInstance, typeInstance, depFlag);
  508. if ((fieldTypeInstance->IsStruct()) && (fieldTypeInstance->IsGenericTypeInstance()))
  509. {
  510. // When we're a generic struct, our data layout can depend on our generic parameters as well
  511. auto genericTypeInstance = (BfTypeInstance*)fieldTypeInstance;
  512. for (auto typeGenericArg : genericTypeInstance->mGenericTypeInfo->mTypeGenericArguments)
  513. AddFieldDependency(typeInstance, fieldInstance, typeGenericArg);
  514. }
  515. }
  516. BfFieldInstance* BfModule::GetFieldByName(BfTypeInstance* typeInstance, const StringImpl& fieldName, bool isRequired, BfAstNode* refNode)
  517. {
  518. PopulateType(typeInstance);
  519. typeInstance->mTypeDef->PopulateMemberSets();
  520. BfMemberSetEntry* entry = NULL;
  521. BfFieldDef* fieldDef = NULL;
  522. if (typeInstance->mTypeDef->mFieldSet.TryGetWith(fieldName, &entry))
  523. {
  524. fieldDef = (BfFieldDef*)entry->mMemberDef;
  525. return &typeInstance->mFieldInstances[fieldDef->mIdx];
  526. }
  527. if (isRequired)
  528. {
  529. FailInternal(StrFormat("Field '%s' not found in '%s'", fieldName.c_str(), TypeToString(typeInstance).c_str()), refNode);
  530. }
  531. return NULL;
  532. }
  533. void BfModule::CheckMemberNames(BfTypeInstance* typeInst)
  534. {
  535. struct MemberRef
  536. {
  537. BfMemberDef* mMemberDef;
  538. String mName;
  539. String mKindName;
  540. BfTypeInstance* mTypeInst;
  541. BfAstNode* mNameNode;
  542. BfProtection mProtection;
  543. BfTypeDef* mDeclaringType;
  544. bool mIsOverride;
  545. };
  546. SizedArray<MemberRef, 64> memberList;
  547. // Check base types first and then current type
  548. auto checkType = typeInst;
  549. while (checkType != NULL)
  550. {
  551. for (auto prop : checkType->mTypeDef->mProperties)
  552. {
  553. BfPropertyDeclaration* propDecl = (BfPropertyDeclaration*)prop->mFieldDeclaration;
  554. if ((propDecl != NULL) && (propDecl->mExplicitInterface != NULL))
  555. continue;
  556. if (!typeInst->IsTypeMemberIncluded(prop->mDeclaringType))
  557. continue;
  558. MemberRef memberRef;
  559. memberRef.mMemberDef = prop;
  560. memberRef.mTypeInst = checkType;
  561. memberRef.mProtection = prop->mProtection;
  562. memberRef.mName = prop->mName;
  563. memberRef.mKindName = "property";
  564. if (prop->mFieldDeclaration != NULL)
  565. memberRef.mNameNode = prop->mFieldDeclaration->mNameNode;
  566. memberRef.mDeclaringType = prop->mDeclaringType;
  567. auto propertyDeclaration = BfNodeDynCast<BfPropertyDeclaration>(prop->mFieldDeclaration);
  568. if (propertyDeclaration != NULL)
  569. memberRef.mIsOverride = (propertyDeclaration->mNewSpecifier != NULL) ||
  570. ((propertyDeclaration->mVirtualSpecifier != NULL) && (propertyDeclaration->mVirtualSpecifier->GetToken() == BfToken_Override));
  571. memberList.push_back(memberRef);
  572. }
  573. for (auto field : checkType->mTypeDef->mFields)
  574. {
  575. if (!typeInst->IsTypeMemberIncluded(field->mDeclaringType))
  576. continue;
  577. MemberRef memberRef;
  578. memberRef.mMemberDef = field;
  579. memberRef.mTypeInst = checkType;
  580. memberRef.mProtection = field->mProtection;
  581. memberRef.mName = field->mName;
  582. memberRef.mKindName = "field";
  583. memberRef.mDeclaringType = field->mDeclaringType;
  584. if (field->mFieldDeclaration != NULL)
  585. {
  586. memberRef.mNameNode = field->mFieldDeclaration->mNameNode;
  587. memberRef.mIsOverride = field->mFieldDeclaration->mNewSpecifier != NULL;
  588. }
  589. memberList.push_back(memberRef);
  590. }
  591. checkType = checkType->mBaseType;
  592. }
  593. Dictionary<String, MemberRef> memberMap;
  594. memberMap.Reserve(memberList.size());
  595. for (int i = (int)memberList.size() - 1; i >= 0; i--)
  596. {
  597. MemberRef& memberRef = memberList[i];
  598. if (memberRef.mName.empty())
  599. continue;
  600. if ((memberRef.mTypeInst == typeInst) && (!memberRef.mIsOverride))
  601. {
  602. MemberRef* prevMemberRef = NULL;
  603. if (memberMap.TryGetValue(memberRef.mName, &prevMemberRef))
  604. {
  605. //auto& prevMemberRef = itr->second;
  606. MemberRef* firstMemberRef = &memberRef;
  607. MemberRef* secondMemberRef = prevMemberRef;
  608. bool showPrevious = false;
  609. BfError* error = NULL;
  610. if (prevMemberRef->mTypeInst != typeInst)
  611. {
  612. if ((prevMemberRef->mProtection != BfProtection_Private) && (memberRef.mNameNode != NULL))
  613. {
  614. error = Warn(BfWarning_CS0108_MemberHidesInherited, StrFormat("%s hides inherited member '%s'. Use the 'new' keyword if hiding was intentional.", prevMemberRef->mKindName.c_str(), memberRef.mName.c_str()), memberRef.mNameNode, true);
  615. showPrevious = true;
  616. }
  617. }
  618. else
  619. {
  620. if (ShouldAllowMultipleDefinitions(typeInst, firstMemberRef->mDeclaringType, secondMemberRef->mDeclaringType))
  621. {
  622. if (firstMemberRef->mMemberDef != NULL)
  623. {
  624. firstMemberRef->mMemberDef->mHasMultiDefs = true;
  625. secondMemberRef->mMemberDef->mHasMultiDefs = true;
  626. }
  627. continue;
  628. }
  629. bool wantsSwap = false;
  630. if ((secondMemberRef->mNameNode != NULL) && (firstMemberRef->mNameNode != NULL) &&
  631. (secondMemberRef->mNameNode->GetSourceData() == firstMemberRef->mNameNode->GetSourceData()) &&
  632. (secondMemberRef->mNameNode->GetSrcStart() < firstMemberRef->mNameNode->GetSrcStart()))
  633. {
  634. wantsSwap = true;
  635. }
  636. if (secondMemberRef->mDeclaringType->IsExtension() != firstMemberRef->mDeclaringType->IsExtension())
  637. {
  638. wantsSwap = firstMemberRef->mDeclaringType->IsExtension();
  639. }
  640. if (wantsSwap)
  641. {
  642. std::swap(firstMemberRef, secondMemberRef);
  643. }
  644. if (secondMemberRef->mNameNode != NULL)
  645. error = Fail(StrFormat("A %s named '%s' has already been declared.", secondMemberRef->mKindName.c_str(), memberRef.mName.c_str()), secondMemberRef->mNameNode, true);
  646. showPrevious = true;
  647. }
  648. if ((secondMemberRef->mNameNode != NULL) && (error != NULL))
  649. mCompiler->mPassInstance->MoreInfo("Previous declaration", firstMemberRef->mNameNode);
  650. }
  651. }
  652. memberMap.TryAdd(memberRef.mName, memberRef);
  653. }
  654. }
  655. void BfModule::TypeFailed(BfTypeInstance* typeInstance)
  656. {
  657. BfLogSysM("TypeFailed: %p\n", typeInstance);
  658. typeInstance->mTypeFailed = true;
  659. // Punt on field types - just substitute 'var' where we have NULLs
  660. for (auto& fieldInstance : typeInstance->mFieldInstances)
  661. {
  662. if ((fieldInstance.mResolvedType == NULL) || (fieldInstance.mResolvedType->IsNull()))
  663. {
  664. if (fieldInstance.mDataIdx >= 0)
  665. fieldInstance.mResolvedType = GetPrimitiveType(BfTypeCode_Var);
  666. }
  667. if (fieldInstance.mOwner == NULL)
  668. fieldInstance.mOwner = typeInstance;
  669. }
  670. if (typeInstance->mAlign == -1)
  671. typeInstance->mAlign = 1;
  672. if (typeInstance->mSize == -1)
  673. typeInstance->mSize = 1;
  674. mContext->mFailTypes.Add(typeInstance);
  675. mHadBuildError = true;
  676. }
  677. bool BfModule::CheckCircularDataError()
  678. {
  679. bool hadError = false;
  680. int checkIdx = 0;
  681. auto checkTypeState = mContext->mCurTypeState;
  682. bool isPreBaseCheck = checkTypeState->mPopulateType == BfPopulateType_Declaration;
  683. while (true)
  684. {
  685. if (checkTypeState == NULL)
  686. return hadError;
  687. if (checkTypeState->mResolveKind == BfTypeState::ResolveKind_UnionInnerType)
  688. {
  689. checkTypeState = checkTypeState->mPrevState;
  690. continue;
  691. }
  692. if (isPreBaseCheck)
  693. {
  694. if (checkTypeState->mPopulateType != BfPopulateType_Declaration)
  695. return hadError;
  696. }
  697. else
  698. {
  699. if (checkTypeState->mPopulateType == BfPopulateType_Declaration)
  700. return hadError;
  701. if ((checkIdx > 0) && (checkTypeState->mCurBaseTypeRef == NULL) && (checkTypeState->mCurAttributeTypeRef == NULL) && (checkTypeState->mCurFieldDef == NULL))
  702. return hadError;
  703. }
  704. if ((checkTypeState->mTypeInstance == mCurTypeInstance) && (checkIdx > 0))
  705. break;
  706. checkTypeState = checkTypeState->mPrevState;
  707. checkIdx++;
  708. }
  709. checkTypeState = mContext->mCurTypeState->mPrevState;
  710. while (true)
  711. {
  712. if (checkTypeState == NULL)
  713. return hadError;
  714. if (checkTypeState->mResolveKind == BfTypeState::ResolveKind_UnionInnerType)
  715. {
  716. // Skip over this to actual data references
  717. checkTypeState = checkTypeState->mPrevState;
  718. continue;
  719. }
  720. if ((checkTypeState->mCurAttributeTypeRef == NULL) && (checkTypeState->mCurBaseTypeRef == NULL) && (checkTypeState->mCurFieldDef == NULL) )
  721. return hadError;
  722. // We only get one chance to fire off these errors, they can't be ignored.
  723. SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, false);
  724. hadError = true;
  725. if (checkTypeState->mCurAttributeTypeRef != NULL)
  726. {
  727. Fail(StrFormat("Attribute type '%s' causes a data cycle", BfTypeUtils::TypeToString(checkTypeState->mCurAttributeTypeRef).c_str()), checkTypeState->mCurAttributeTypeRef, true);
  728. }
  729. else if (checkTypeState->mCurBaseTypeRef != NULL)
  730. {
  731. Fail(StrFormat("Base type '%s' causes a data cycle", BfTypeUtils::TypeToString(checkTypeState->mCurBaseTypeRef).c_str()), checkTypeState->mCurBaseTypeRef, true);
  732. }
  733. else if (checkTypeState->mCurFieldDef->mFieldDeclaration != NULL)
  734. {
  735. Fail(StrFormat("Field '%s.%s' causes a data cycle", TypeToString(checkTypeState->mTypeInstance).c_str(), checkTypeState->mCurFieldDef->mName.c_str()),
  736. checkTypeState->mCurFieldDef->mFieldDeclaration->mTypeRef, true);
  737. }
  738. else
  739. {
  740. Fail(StrFormat("Field '%s.%s' causes a data cycle", TypeToString(checkTypeState->mTypeInstance).c_str(), checkTypeState->mCurFieldDef->mName.c_str()));
  741. }
  742. auto module = GetModuleFor(checkTypeState->mTypeInstance);
  743. if (module != NULL)
  744. module->TypeFailed(checkTypeState->mTypeInstance);
  745. else
  746. checkTypeState->mTypeInstance->mTypeFailed = true;
  747. checkTypeState = checkTypeState->mPrevState;
  748. }
  749. }
  750. void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType)
  751. {
  752. if ((populateType == BfPopulateType_Declaration) && (resolvedTypeRef->mDefineState >= BfTypeDefineState_Declared))
  753. return;
  754. // Are we "demanding" to reify a type that is currently resolve-only?
  755. if ((mIsReified) && (populateType >= BfPopulateType_Declaration))
  756. {
  757. if (resolvedTypeRef->IsTypeInstance())
  758. {
  759. auto typeModule = resolvedTypeRef->GetModule();
  760. if ((typeModule != NULL) && (typeModule->mIsSpecialModule))
  761. {
  762. auto typeInst = resolvedTypeRef->ToTypeInstance();
  763. if (!typeInst->mIsReified)
  764. {
  765. BfLogSysM("Reifying type %p in scratch module in PopulateType\n", resolvedTypeRef);
  766. // It's important for unspecialized types to be in the correct module --
  767. // when we process their methods, new types will be determined as
  768. // resolve-only or reified based on the module the unresolved type is in
  769. BF_ASSERT(typeInst->mModule == mContext->mUnreifiedModule);
  770. typeInst->mIsReified = true;
  771. typeInst->mModule = mContext->mScratchModule;
  772. // Why did we need to do this at all? Why is just marking the type as reified not enough?
  773. // This causes issues where we may delete a method instance that is currently being used as the generic bindings for
  774. // a method of a specialized generic type
  775. // if (typeInst->IsOnDemand())
  776. // {
  777. // RebuildMethods(typeInst);
  778. // }
  779. // else
  780. // mContext->RebuildType(typeInst, false, false);
  781. }
  782. }
  783. else
  784. {
  785. if ((typeModule != NULL) && (!typeModule->mIsReified) && (!typeModule->mReifyQueued))
  786. {
  787. BF_ASSERT((mCompiler->mCompileState != BfCompiler::CompileState_Unreified) && (mCompiler->mCompileState != BfCompiler::CompileState_VData));
  788. BfLogSysM("Queued reification of type %p in module %p in PopulateType\n", resolvedTypeRef, typeModule);
  789. BF_ASSERT((typeModule != mContext->mUnreifiedModule) && (typeModule != mContext->mScratchModule));
  790. BF_ASSERT(!typeModule->mIsSpecialModule);
  791. // This caused issues - we may need to reify a type and then request a method
  792. typeModule->mReifyQueued = true;
  793. mContext->mReifyModuleWorkList.Add(typeModule);
  794. //typeModule->ReifyModule();
  795. }
  796. }
  797. }
  798. }
  799. if (!resolvedTypeRef->IsIncomplete())
  800. return;
  801. auto typeInstance = resolvedTypeRef->ToTypeInstance();
  802. CheckInjectNewRevision(typeInstance);
  803. BF_ASSERT((resolvedTypeRef->mRebuildFlags & (BfTypeRebuildFlag_Deleted | BfTypeRebuildFlag_DeleteQueued)) == 0);
  804. /*BfTypeRebuildFlags allowedFlags = (BfTypeRebuildFlags)(BfTypeRebuildFlag_AddedToWorkList | BfTypeRebuildFlag_AwaitingReference | BfTypeRebuildFlag_UnderlyingTypeDeferred);
  805. if ((resolvedTypeRef->mRebuildFlags & ~allowedFlags) != 0)
  806. {
  807. // BfContext::UpdateAfterDeletingTypes should clear out all flags except for the Deleted flag
  808. // If this type was deleted then we should never be able to reach PopulateType here.
  809. // This may happen if dependent types were not properly rebuilt when a used type
  810. // was deleted.
  811. auto hadFlags = resolvedTypeRef->mRebuildFlags;
  812. BF_ASSERT((resolvedTypeRef->mRebuildFlags & ~allowedFlags) == 0);
  813. resolvedTypeRef->mRebuildFlags = (BfTypeRebuildFlags)(resolvedTypeRef->mRebuildFlags & ~allowedFlags);
  814. }*/
  815. bool isNew = resolvedTypeRef->mDefineState == BfTypeDefineState_Undefined;
  816. if (isNew)
  817. {
  818. BP_ZONE("BfModule::PopulateType");
  819. if (resolvedTypeRef->mTypeId == -1)
  820. {
  821. mCompiler->mTypeInitCount++;
  822. auto typeInstance = resolvedTypeRef->ToTypeInstance();
  823. if (!mCompiler->mTypeIdFreeList.IsEmpty())
  824. {
  825. resolvedTypeRef->mTypeId = mCompiler->mTypeIdFreeList.back();
  826. mCompiler->mTypeIdFreeList.pop_back();
  827. }
  828. else
  829. resolvedTypeRef->mTypeId = mCompiler->mCurTypeId++;
  830. while (resolvedTypeRef->mTypeId >= (int)mContext->mTypes.size())
  831. mContext->mTypes.Add(NULL);
  832. mContext->mTypes[resolvedTypeRef->mTypeId] = resolvedTypeRef;
  833. if (typeInstance != NULL)
  834. {
  835. typeInstance->mSignatureRevision = mCompiler->mRevision;
  836. typeInstance->mLastNonGenericUsedRevision = mCompiler->mRevision;
  837. }
  838. }
  839. BfLogSysM("PopulateType: %p %s populateType:%d ResolveOnly:%d Reified:%d AutoComplete:%d Ctx:%p Mod:%p TypeId:%d\n", resolvedTypeRef, TypeToString(resolvedTypeRef, BfTypeNameFlags_None).c_str(), populateType, mCompiler->mIsResolveOnly, mIsReified, mCompiler->IsAutocomplete(), mContext, this, resolvedTypeRef->mTypeId);
  840. BF_ASSERT(!resolvedTypeRef->IsDeleting());
  841. }
  842. if (resolvedTypeRef->IsRef())
  843. {
  844. BfRefType* refType = (BfRefType*)resolvedTypeRef;
  845. if (refType->mElementType->IsValueType())
  846. {
  847. PopulateType(refType->mElementType, populateType);
  848. resolvedTypeRef->mDefineState = refType->mElementType->mDefineState;
  849. }
  850. else
  851. {
  852. PopulateType(refType->mElementType, BfPopulateType_Identity);
  853. resolvedTypeRef->mDefineState = BfTypeDefineState_Defined;
  854. }
  855. refType->mSize = refType->mAlign = mSystem->mPtrSize;
  856. return;
  857. }
  858. if (resolvedTypeRef->IsTypeAlias())
  859. {
  860. auto typeAlias = (BfTypeInstance*)resolvedTypeRef;
  861. SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, typeInstance);
  862. SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, NULL);
  863. SetAndRestoreValue<BfMethodState*> prevMethodState(mCurMethodState, NULL);
  864. BF_ASSERT(mCurMethodInstance == NULL);
  865. auto typeDef = typeAlias->mTypeDef;
  866. auto typeAliasDecl = (BfTypeAliasDeclaration*)typeDef->mTypeDeclaration;
  867. BfType* aliasToType = NULL;
  868. resolvedTypeRef->mDefineState = BfTypeDefineState_ResolvingBaseType;
  869. BfTypeState typeState(mCurTypeInstance, mContext->mCurTypeState);
  870. typeState.mPopulateType = populateType;
  871. typeState.mCurBaseTypeRef = typeAliasDecl->mAliasToType;
  872. SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
  873. if (!CheckCircularDataError())
  874. {
  875. if (typeAliasDecl->mAliasToType != NULL)
  876. aliasToType = ResolveTypeRef(typeAliasDecl->mAliasToType, BfPopulateType_IdentityNoRemapAlias);
  877. }
  878. if (aliasToType != NULL)
  879. {
  880. AddDependency(aliasToType, typeAlias, BfDependencyMap::DependencyFlag_DerivedFrom);
  881. }
  882. else
  883. mContext->mFailTypes.Add(typeAlias);
  884. if (typeAlias->mTypeFailed)
  885. aliasToType = NULL;
  886. ((BfTypeAliasType*)resolvedTypeRef)->mAliasToType = aliasToType;
  887. if (aliasToType != NULL)
  888. {
  889. resolvedTypeRef->mSize = aliasToType->mSize;
  890. resolvedTypeRef->mAlign = aliasToType->mAlign;
  891. if (auto aliasToTypeInst = aliasToType->ToTypeInstance())
  892. {
  893. typeAlias->mInstSize = aliasToTypeInst->mInstSize;
  894. typeAlias->mInstAlign = aliasToTypeInst->mInstAlign;
  895. }
  896. else
  897. {
  898. typeAlias->mInstSize = aliasToType->mSize;
  899. typeAlias->mInstAlign = aliasToType->mAlign;
  900. }
  901. }
  902. else
  903. {
  904. resolvedTypeRef->mSize = 0;
  905. resolvedTypeRef->mAlign = 1;
  906. typeAlias->mInstSize = 0;
  907. typeAlias->mInstAlign = 1;
  908. }
  909. resolvedTypeRef->mDefineState = BfTypeDefineState_DefinedAndMethodsSlotted;
  910. resolvedTypeRef->mRebuildFlags = BfTypeRebuildFlag_None;
  911. if ((typeInstance->mCustomAttributes == NULL) && (typeDef->mTypeDeclaration != NULL) && (typeDef->mTypeDeclaration->mAttributes != NULL))
  912. typeInstance->mCustomAttributes = GetCustomAttributes(typeDef->mTypeDeclaration->mAttributes, BfAttributeTargets_Alias);
  913. // Fall through so generic params are populated in DoPopulateType
  914. }
  915. if (resolvedTypeRef->IsSizedArray())
  916. {
  917. resolvedTypeRef->mRevision = mRevision;
  918. bool typeFailed = false;
  919. BfSizedArrayType* arrayType = (BfSizedArrayType*)resolvedTypeRef;
  920. auto elementType = arrayType->mElementType;
  921. if (elementType->IsValueType())
  922. {
  923. resolvedTypeRef->mDefineState = BfTypeDefineState_ResolvingBaseType;
  924. BfTypeState typeState(mCurTypeInstance, mContext->mCurTypeState);
  925. typeState.mPopulateType = populateType;
  926. SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
  927. if (!CheckCircularDataError())
  928. {
  929. PopulateType(arrayType->mElementType, BfPopulateType_Data);
  930. }
  931. else
  932. {
  933. typeFailed = true;
  934. PopulateType(arrayType->mElementType, BfPopulateType_Identity);
  935. }
  936. resolvedTypeRef->mDefineState = arrayType->mElementType->mDefineState;
  937. AddDependency(elementType, resolvedTypeRef, BfDependencyMap::DependencyFlag_ValueTypeMemberData);
  938. }
  939. else
  940. {
  941. PopulateType(arrayType->mElementType, BfPopulateType_Identity);
  942. resolvedTypeRef->mDefineState = BfTypeDefineState_Defined;
  943. AddDependency(elementType, resolvedTypeRef, BfDependencyMap::DependencyFlag_PtrMemberData);
  944. }
  945. if (arrayType->mElementCount > 0)
  946. {
  947. arrayType->mSize = (arrayType->mElementType->GetStride() * ((int)arrayType->mElementCount - 1)) + arrayType->mElementType->mSize;
  948. arrayType->mAlign = std::max((int32)arrayType->mElementType->mAlign, 1);
  949. }
  950. else if (arrayType->mElementCount < 0)
  951. {
  952. // Unknown size, don't assume it's valueless
  953. arrayType->mSize = 1;
  954. arrayType->mAlign = 1;
  955. }
  956. else
  957. {
  958. arrayType->mSize = 0;
  959. arrayType->mAlign = 1;
  960. }
  961. if (!typeFailed)
  962. arrayType->mWantsGCMarking = elementType->WantsGCMarking();
  963. resolvedTypeRef->mDefineState = BfTypeDefineState_DefinedAndMethodsSlotted;
  964. resolvedTypeRef->mRebuildFlags = BfTypeRebuildFlag_None;
  965. bool isValueless = arrayType->IsValuelessType();
  966. return;
  967. }
  968. if (isNew)
  969. {
  970. BfTypeDef* typeDef = NULL;
  971. if (typeInstance != NULL)
  972. {
  973. if ((populateType == BfPopulateType_Data) && (typeInstance->mNeedsMethodProcessing))
  974. return;
  975. typeDef = typeInstance->mTypeDef;
  976. }
  977. if (resolvedTypeRef->IsMethodRef())
  978. return;
  979. if (resolvedTypeRef->IsPointer())
  980. {
  981. BfPointerType* pointerType = (BfPointerType*)resolvedTypeRef;
  982. if (pointerType->mElementType->IsIncomplete())
  983. PopulateType(pointerType->mElementType, BfPopulateType_Declaration);
  984. pointerType->mSize = pointerType->mAlign = mSystem->mPtrSize;
  985. resolvedTypeRef->mDefineState = BfTypeDefineState_Defined;
  986. return;
  987. }
  988. if (resolvedTypeRef->IsGenericParam())
  989. {
  990. BfGenericParamType* genericParamType = (BfGenericParamType*)resolvedTypeRef;
  991. PopulateType(mContext->mBfObjectType);
  992. genericParamType->mSize = mContext->mBfObjectType->mSize;
  993. genericParamType->mAlign = mContext->mBfObjectType->mAlign;
  994. resolvedTypeRef->mDefineState = BfTypeDefineState_Defined;
  995. return;
  996. }
  997. if (resolvedTypeRef->IsModifiedTypeType())
  998. {
  999. BfModifiedTypeType* retTypeType = (BfModifiedTypeType*)resolvedTypeRef;
  1000. BF_ASSERT(retTypeType->mElementType->IsGenericParam());
  1001. resolvedTypeRef->mSize = mContext->mBfObjectType->mSize;
  1002. resolvedTypeRef->mAlign = mContext->mBfObjectType->mAlign;
  1003. resolvedTypeRef->mDefineState = BfTypeDefineState_Defined;
  1004. return;
  1005. }
  1006. if (resolvedTypeRef->IsConcreteInterfaceType())
  1007. {
  1008. BfConcreteInterfaceType* concreteInterfaceType = (BfConcreteInterfaceType*)resolvedTypeRef;
  1009. BF_ASSERT(concreteInterfaceType->mInterface->IsInterface());
  1010. resolvedTypeRef->mSize = concreteInterfaceType->mInterface->mSize;
  1011. resolvedTypeRef->mAlign = concreteInterfaceType->mInterface->mAlign;
  1012. resolvedTypeRef->mDefineState = BfTypeDefineState_Defined;
  1013. return;
  1014. }
  1015. if (resolvedTypeRef->IsConstExprValue())
  1016. {
  1017. resolvedTypeRef->mSize = 0;
  1018. resolvedTypeRef->mAlign = 0;
  1019. resolvedTypeRef->mDefineState = BfTypeDefineState_Defined;
  1020. return;
  1021. }
  1022. // The autocomplete pass doesn't need to do the method processing, allow type to be (partially) incomplete
  1023. if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL) &&
  1024. (typeInstance != NULL) && (typeInstance->mNeedsMethodProcessing) && (!typeInstance->IsDelegate()))
  1025. return;
  1026. BfPrimitiveType* primitiveType = NULL;
  1027. if (typeInstance == NULL)
  1028. {
  1029. BF_ASSERT(resolvedTypeRef->IsPrimitiveType());
  1030. primitiveType = (BfPrimitiveType*)resolvedTypeRef;
  1031. typeDef = primitiveType->mTypeDef;
  1032. }
  1033. #define PRIMITIVE_TYPE(name, llvmType, size, dType) \
  1034. primitiveType->mSize = primitiveType->mAlign = size; \
  1035. primitiveType->mDefineState = BfTypeDefineState_Defined;
  1036. switch (typeDef->mTypeCode)
  1037. {
  1038. case BfTypeCode_None:
  1039. primitiveType->mSize = primitiveType->mAlign = 0;
  1040. resolvedTypeRef->mDefineState = BfTypeDefineState_Defined;
  1041. return;
  1042. case BfTypeCode_Self:
  1043. case BfTypeCode_Dot:
  1044. case BfTypeCode_Var:
  1045. case BfTypeCode_Let:
  1046. {
  1047. auto objType = mContext->mBfObjectType;
  1048. primitiveType->mSize = objType->mSize;
  1049. primitiveType->mAlign = objType->mAlign;
  1050. resolvedTypeRef->mDefineState = BfTypeDefineState_Defined;
  1051. }
  1052. return;
  1053. case BfTypeCode_NullPtr:
  1054. primitiveType->mSize = primitiveType->mAlign = mSystem->mPtrSize;
  1055. primitiveType->mDefineState = BfTypeDefineState_Defined;
  1056. return;
  1057. case BfTypeCode_Boolean:
  1058. PRIMITIVE_TYPE("bool", Int1, 1, DW_ATE_boolean);
  1059. return;
  1060. case BfTypeCode_Int8:
  1061. PRIMITIVE_TYPE("sbyte", Int8, 1, DW_ATE_signed);
  1062. return;
  1063. case BfTypeCode_UInt8:
  1064. PRIMITIVE_TYPE("byte", Int8, 1, DW_ATE_unsigned);
  1065. return;
  1066. case BfTypeCode_Int16:
  1067. PRIMITIVE_TYPE("short", Int16, 2, DW_ATE_signed);
  1068. return;
  1069. case BfTypeCode_UInt16:
  1070. PRIMITIVE_TYPE("ushort", Int16, 2, DW_ATE_unsigned);
  1071. return;
  1072. case BfTypeCode_Int32:
  1073. PRIMITIVE_TYPE("int", Int32, 4, DW_ATE_signed);
  1074. return;
  1075. case BfTypeCode_UInt32:
  1076. PRIMITIVE_TYPE("uint", Int32, 4, DW_ATE_unsigned);
  1077. return;
  1078. case BfTypeCode_Int64:
  1079. PRIMITIVE_TYPE("long", Int64, 8, DW_ATE_signed);
  1080. return;
  1081. case BfTypeCode_UInt64:
  1082. PRIMITIVE_TYPE("ulong", Int64, 8, DW_ATE_unsigned);
  1083. return;
  1084. case BfTypeCode_IntPtr:
  1085. if (mSystem->mPtrSize == 4)
  1086. {
  1087. PRIMITIVE_TYPE("intptr", Int32, 4, DW_ATE_signed);
  1088. }
  1089. else
  1090. {
  1091. PRIMITIVE_TYPE("intptr", Int64, 8, DW_ATE_signed);
  1092. }
  1093. return;
  1094. case BfTypeCode_UIntPtr:
  1095. if (mSystem->mPtrSize == 4)
  1096. {
  1097. PRIMITIVE_TYPE("uintptr", Int32, 4, DW_ATE_unsigned);
  1098. }
  1099. else
  1100. {
  1101. PRIMITIVE_TYPE("uintptr", Int64, 8, DW_ATE_unsigned);
  1102. }
  1103. return;
  1104. case BfTypeCode_IntUnknown:
  1105. case BfTypeCode_UIntUnknown:
  1106. return;
  1107. case BfTypeCode_Char8:
  1108. PRIMITIVE_TYPE("char8", Int8, 1, DW_ATE_unsigned_char);
  1109. return;
  1110. case BfTypeCode_Char16:
  1111. PRIMITIVE_TYPE("char16", Int16, 2, DW_ATE_unsigned_char);
  1112. return;
  1113. case BfTypeCode_Char32:
  1114. PRIMITIVE_TYPE("char32", Int32, 4, DW_ATE_unsigned_char);
  1115. return;
  1116. case BfTypeCode_Float:
  1117. PRIMITIVE_TYPE("float", Float, 4, DW_ATE_float);
  1118. return;
  1119. case BfTypeCode_Double:
  1120. PRIMITIVE_TYPE("double", Double, 8, DW_ATE_float);
  1121. return;
  1122. case BfTypeCode_Object:
  1123. case BfTypeCode_Struct:
  1124. case BfTypeCode_Interface:
  1125. case BfTypeCode_Enum:
  1126. case BfTypeCode_TypeAlias:
  1127. // Implemented below
  1128. break;
  1129. case BfTypeCode_Extension:
  1130. // This can only happen if we didn't actually find the type the extension referred to
  1131. break;
  1132. default:
  1133. //NotImpl(resolvedTypeRef->mTypeRef);
  1134. BFMODULE_FATAL(this, "Invalid type");
  1135. return;
  1136. }
  1137. //////////////////////////////////////////////////////////////////////////
  1138. BF_ASSERT(typeInstance != NULL);
  1139. if (!typeInstance->IsArray())
  1140. {
  1141. BF_ASSERT(typeInstance->mTypeDef != mContext->mCompiler->mArray1TypeDef);
  1142. }
  1143. if (mContext->mBfObjectType == NULL)
  1144. {
  1145. if (typeInstance->mTypeDef == mCompiler->mBfObjectTypeDef)
  1146. mContext->mBfObjectType = typeInstance;
  1147. else
  1148. ResolveTypeDef(mCompiler->mBfObjectTypeDef);
  1149. }
  1150. if (typeInstance->mModule == NULL)
  1151. {
  1152. // Create a module for this type
  1153. mContext->HandleTypeWorkItem(resolvedTypeRef);
  1154. }
  1155. }
  1156. if (typeInstance == NULL)
  1157. return;
  1158. if (typeInstance->mModule == NULL)
  1159. {
  1160. BF_ASSERT(typeInstance->mTypeFailed);
  1161. return;
  1162. }
  1163. typeInstance->mModule->DoPopulateType(typeInstance, populateType);
  1164. }
  1165. BfTypeOptions* BfModule::GetTypeOptions(BfTypeDef* typeDef)
  1166. {
  1167. if (mContext->mSystem->mTypeOptions.size() == 0)
  1168. {
  1169. return NULL;
  1170. }
  1171. Array<int> matchedIndices;
  1172. if (!mCompiler->mAttributeTypeOptionMap.IsEmpty())
  1173. {
  1174. auto customAttributes = typeDef->mTypeDeclaration->mAttributes;
  1175. while (customAttributes != NULL)
  1176. {
  1177. if (!mCompiler->mAttributeTypeOptionMap.IsEmpty())
  1178. {
  1179. SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, true);
  1180. auto typeRef = customAttributes->mAttributeTypeRef;
  1181. // StringT<128> attrName;
  1182. // for (auto& customAttrs : customAttributes->mAttributeTypeRef)
  1183. // {
  1184. // attrName.Clear();
  1185. // customAttrs.mType->mTypeDef->mFullName.ToString(attrName);
  1186. // Array<int>* arrPtr;
  1187. // if (mCompiler->mAttributeTypeOptionMap.TryGetValue(attrName, &arrPtr))
  1188. // {
  1189. // for (auto optionsIdx : *arrPtr)
  1190. // {
  1191. // matchedIndices.Add(optionsIdx);
  1192. // }
  1193. // }
  1194. // }
  1195. }
  1196. customAttributes = customAttributes->mNextAttribute;
  1197. }
  1198. }
  1199. int typeOptionsCount = (int)mContext->mSystem->mTypeOptions.size();
  1200. auto _CheckTypeName = [&](const StringImpl& typeName)
  1201. {
  1202. for (int optionIdx = 0; optionIdx < (int)mContext->mSystem->mTypeOptions.size(); optionIdx++)
  1203. {
  1204. auto& typeOptions = mContext->mSystem->mTypeOptions[optionIdx];
  1205. bool matched = false;
  1206. for (auto& filter : typeOptions.mTypeFilters)
  1207. {
  1208. int filterIdx = 0;
  1209. int typeNameIdx = 0;
  1210. const char* filterPtr = filter.c_str();
  1211. const char* namePtr = typeName.c_str();
  1212. char prevFilterC = 0;
  1213. while (true)
  1214. {
  1215. char filterC;
  1216. while (true)
  1217. {
  1218. filterC = *(filterPtr++);
  1219. if (filterC != ' ')
  1220. break;
  1221. }
  1222. char nameC;
  1223. while (true)
  1224. {
  1225. nameC = *(namePtr++);
  1226. if (nameC != ' ')
  1227. break;
  1228. }
  1229. if ((filterC == 0) || (nameC == 0))
  1230. {
  1231. matched = (filterC == 0) && (nameC == 0);
  1232. break;
  1233. }
  1234. bool doWildcard = false;
  1235. if (nameC != filterC)
  1236. {
  1237. if (filterC == '*')
  1238. doWildcard = true;
  1239. else if (((filterC == ',') || (filterC == '>')) &&
  1240. ((prevFilterC == '<') || (prevFilterC == ',')))
  1241. {
  1242. doWildcard = true;
  1243. filterPtr--;
  1244. }
  1245. if (!doWildcard)
  1246. {
  1247. matched = false;
  1248. break;
  1249. }
  1250. }
  1251. if (doWildcard)
  1252. {
  1253. int openDepth = 0;
  1254. const char* startNamePtr = namePtr;
  1255. while (true)
  1256. {
  1257. nameC = *(namePtr++);
  1258. if (nameC == 0)
  1259. {
  1260. namePtr--;
  1261. if (openDepth != 0)
  1262. matched = false;
  1263. break;
  1264. }
  1265. if ((nameC == '>') && (openDepth == 0))
  1266. {
  1267. namePtr--;
  1268. break;
  1269. }
  1270. if (nameC == '<')
  1271. openDepth++;
  1272. else if (nameC == '>')
  1273. openDepth--;
  1274. else if ((nameC == ',') && (openDepth == 0))
  1275. {
  1276. namePtr--;
  1277. break;
  1278. }
  1279. }
  1280. if (!matched)
  1281. break;
  1282. }
  1283. prevFilterC = filterC;
  1284. }
  1285. }
  1286. if (matched)
  1287. matchedIndices.push_back(optionIdx);
  1288. }
  1289. };
  1290. // if (typeInstance->IsTypedPrimitive())
  1291. // {
  1292. // auto underlyingType = typeInstance->GetUnderlyingType();
  1293. // if (underlyingType != NULL)
  1294. // {
  1295. // String typeName = TypeToString(underlyingType);
  1296. // _CheckTypeName(typeName);
  1297. // }
  1298. // else
  1299. // {
  1300. // // Can this only happen for functions that are being extended?
  1301. // }
  1302. // }
  1303. //
  1304. // if ((!typeInstance->IsBoxed()) && (typeInstance->mTypeDef == mCompiler->mPointerTTypeDef))
  1305. // {
  1306. // BF_ASSERT(typeInstance->IsGenericTypeInstance());
  1307. // auto innerType = typeInstance->mGenericTypeInfo->mTypeGenericArguments[0];
  1308. // auto ptrType = CreatePointerType(innerType);
  1309. // String typeName = TypeToString(ptrType);
  1310. // _CheckTypeName(typeName);
  1311. // }
  1312. String typeName = BfTypeUtils::TypeToString(typeDef);
  1313. _CheckTypeName(typeName);
  1314. int matchedIdx = -1;
  1315. if (matchedIndices.size() == 1)
  1316. {
  1317. matchedIdx = matchedIndices[0];
  1318. }
  1319. else if (matchedIndices.size() > 1)
  1320. {
  1321. // Try to find a merged typeoptions with these indices
  1322. for (int mergedIdx = 0; mergedIdx < (int)mContext->mSystem->mMergedTypeOptions.size(); mergedIdx++)
  1323. {
  1324. auto& typeOptions = mContext->mSystem->mMergedTypeOptions[mergedIdx];
  1325. if (typeOptions.mMatchedIndices == matchedIndices)
  1326. {
  1327. matchedIdx = typeOptionsCount + mergedIdx;
  1328. break;
  1329. }
  1330. }
  1331. // Otherwise make one...
  1332. if (matchedIdx == -1)
  1333. {
  1334. auto& first = mContext->mSystem->mTypeOptions[matchedIndices[0]];
  1335. BfTypeOptions mergedTypeOptions;
  1336. mergedTypeOptions.mSIMDSetting = first.mSIMDSetting;
  1337. mergedTypeOptions.mOptimizationLevel = first.mOptimizationLevel;
  1338. mergedTypeOptions.mEmitDebugInfo = first.mEmitDebugInfo;
  1339. mergedTypeOptions.mAndFlags = first.mAndFlags;
  1340. mergedTypeOptions.mOrFlags = first.mOrFlags;
  1341. mergedTypeOptions.mAllocStackTraceDepth = first.mAllocStackTraceDepth;
  1342. mergedTypeOptions.mReflectMethodFilters = first.mReflectMethodFilters;
  1343. mergedTypeOptions.mReflectMethodAttributeFilters = first.mReflectMethodAttributeFilters;
  1344. mergedTypeOptions.mMatchedIndices = matchedIndices;
  1345. for (int idx = 1; idx < (int)matchedIndices.size(); idx++)
  1346. {
  1347. auto& typeOptions = mContext->mSystem->mTypeOptions[matchedIndices[idx]];
  1348. if (typeOptions.mSIMDSetting != -1)
  1349. mergedTypeOptions.mSIMDSetting = typeOptions.mSIMDSetting;
  1350. if (typeOptions.mOptimizationLevel != -1)
  1351. mergedTypeOptions.mOptimizationLevel = typeOptions.mOptimizationLevel;
  1352. if (typeOptions.mEmitDebugInfo != -1)
  1353. mergedTypeOptions.mEmitDebugInfo = typeOptions.mEmitDebugInfo;
  1354. if (typeOptions.mReflectMethodFilters.IsEmpty())
  1355. mergedTypeOptions.mOrFlags = (BfOptionFlags)(mergedTypeOptions.mOrFlags | typeOptions.mOrFlags);
  1356. mergedTypeOptions.mAndFlags = (BfOptionFlags)(mergedTypeOptions.mAndFlags | typeOptions.mOrFlags);
  1357. mergedTypeOptions.mAndFlags = (BfOptionFlags)(mergedTypeOptions.mAndFlags & typeOptions.mAndFlags);
  1358. mergedTypeOptions.mOrFlags = (BfOptionFlags)(mergedTypeOptions.mOrFlags & typeOptions.mAndFlags);
  1359. if (mergedTypeOptions.HasReflectMethodFilters())
  1360. {
  1361. // If merging filter has non-default method flags but no filter then we need to append it as a filtered modification
  1362. if ((!typeOptions.HasReflectMethodFilters()) &&
  1363. (((typeOptions.mAndFlags & BfOptionFlags_Reflect_MethodMask) != BfOptionFlags_Reflect_MethodMask) ||
  1364. ((typeOptions.mOrFlags & BfOptionFlags_Reflect_MethodMask) != 0)))
  1365. {
  1366. mergedTypeOptions.mReflectMethodFilters.Add({"*", typeOptions.mAndFlags, typeOptions.mOrFlags});
  1367. }
  1368. mergedTypeOptions.mAndFlags = (BfOptionFlags)(mergedTypeOptions.mAndFlags | BfOptionFlags_Reflect_MethodMask);
  1369. mergedTypeOptions.mOrFlags = (BfOptionFlags)(mergedTypeOptions.mOrFlags & ~BfOptionFlags_Reflect_MethodMask);
  1370. }
  1371. if (typeOptions.mAllocStackTraceDepth != -1)
  1372. mergedTypeOptions.mAllocStackTraceDepth = typeOptions.mAllocStackTraceDepth;
  1373. for (auto filter : typeOptions.mReflectMethodFilters)
  1374. mergedTypeOptions.mReflectMethodFilters.Add(filter);
  1375. for (auto filter : typeOptions.mReflectMethodAttributeFilters)
  1376. mergedTypeOptions.mReflectMethodAttributeFilters.Add(filter);
  1377. }
  1378. matchedIdx = typeOptionsCount + (int)mContext->mSystem->mMergedTypeOptions.size();
  1379. mContext->mSystem->mMergedTypeOptions.push_back(mergedTypeOptions);
  1380. }
  1381. }
  1382. return mSystem->GetTypeOptions( matchedIdx);
  1383. }
  1384. bool BfModule::ApplyTypeOptionMethodFilters(bool includeMethod, BfMethodDef* methodDef, BfTypeOptions* typeOptions)
  1385. {
  1386. BfOptionFlags findFlag = BfOptionFlags_None;
  1387. if (methodDef->mMethodType == BfMethodType_Ctor)
  1388. findFlag = BfOptionFlags_ReflectConstructors;
  1389. else if (methodDef->mIsStatic)
  1390. findFlag = BfOptionFlags_ReflectStaticMethods;
  1391. else
  1392. findFlag = BfOptionFlags_ReflectNonStaticMethods;
  1393. if ((typeOptions->mAndFlags & findFlag) == 0)
  1394. includeMethod = false;
  1395. if ((typeOptions->mOrFlags & findFlag) != 0)
  1396. includeMethod = true;
  1397. if (!typeOptions->mReflectMethodFilters.IsEmpty())
  1398. {
  1399. for (auto& filter : typeOptions->mReflectMethodFilters)
  1400. {
  1401. if (BfCheckWildcard(filter.mFilter, methodDef->mName))
  1402. {
  1403. if ((filter.mAndFlags & findFlag) == 0)
  1404. includeMethod = false;
  1405. if ((filter.mAndFlags | findFlag) != 0)
  1406. includeMethod = true;
  1407. }
  1408. }
  1409. }
  1410. return includeMethod;
  1411. }
  1412. int BfModule::GenerateTypeOptions(BfCustomAttributes* customAttributes, BfTypeInstance* typeInstance, bool checkTypeName)
  1413. {
  1414. if (mContext->mSystem->mTypeOptions.size() == 0)
  1415. {
  1416. return -1;
  1417. }
  1418. Array<int> matchedIndices;
  1419. if ((!checkTypeName) && (typeInstance->mTypeOptionsIdx != -1))
  1420. {
  1421. // Methods should 'inherit' the owner's type options before applying type options from custom attributes
  1422. auto typeOptions = mSystem->GetTypeOptions(typeInstance->mTypeOptionsIdx);
  1423. if (typeOptions->mMatchedIndices.size() == 0)
  1424. matchedIndices.push_back(typeInstance->mTypeOptionsIdx);
  1425. else
  1426. matchedIndices = typeOptions->mMatchedIndices;
  1427. }
  1428. if (customAttributes != NULL)
  1429. {
  1430. if (!mCompiler->mAttributeTypeOptionMap.IsEmpty())
  1431. {
  1432. StringT<128> attrName;
  1433. for (auto& customAttrs : customAttributes->mAttributes)
  1434. {
  1435. attrName.Clear();
  1436. customAttrs.mType->mTypeDef->mFullName.ToString(attrName);
  1437. Array<int>* arrPtr;
  1438. if (mCompiler->mAttributeTypeOptionMap.TryGetValue(attrName, &arrPtr))
  1439. {
  1440. for (auto optionsIdx : *arrPtr)
  1441. {
  1442. matchedIndices.Add(optionsIdx);
  1443. }
  1444. }
  1445. }
  1446. }
  1447. }
  1448. int typeOptionsCount = (int)mContext->mSystem->mTypeOptions.size();
  1449. if (checkTypeName)
  1450. {
  1451. auto _CheckTypeName = [&](const StringImpl& typeName)
  1452. {
  1453. for (int optionIdx = 0; optionIdx < (int)mContext->mSystem->mTypeOptions.size(); optionIdx++)
  1454. {
  1455. auto& typeOptions = mContext->mSystem->mTypeOptions[optionIdx];
  1456. bool matched = false;
  1457. for (auto& filter : typeOptions.mTypeFilters)
  1458. {
  1459. int filterIdx = 0;
  1460. int typeNameIdx = 0;
  1461. if (BfCheckWildcard(filter, typeName))
  1462. {
  1463. matched = true;
  1464. break;
  1465. }
  1466. }
  1467. if (matched)
  1468. matchedIndices.push_back(optionIdx);
  1469. }
  1470. };
  1471. if (typeInstance->IsTypedPrimitive())
  1472. {
  1473. auto underlyingType = typeInstance->GetUnderlyingType();
  1474. if (underlyingType != NULL)
  1475. {
  1476. String typeName = TypeToString(underlyingType);
  1477. _CheckTypeName(typeName);
  1478. }
  1479. else
  1480. {
  1481. // Can this only happen for functions that are being extended?
  1482. }
  1483. }
  1484. if ((!typeInstance->IsBoxed()) && (typeInstance->mTypeDef == mCompiler->mPointerTTypeDef))
  1485. {
  1486. BF_ASSERT(typeInstance->IsGenericTypeInstance());
  1487. auto innerType = typeInstance->mGenericTypeInfo->mTypeGenericArguments[0];
  1488. auto ptrType = CreatePointerType(innerType);
  1489. String typeName = TypeToString(ptrType);
  1490. _CheckTypeName(typeName);
  1491. }
  1492. String typeName = TypeToString(typeInstance);
  1493. _CheckTypeName(typeName);
  1494. }
  1495. int matchedIdx = -1;
  1496. if (matchedIndices.size() == 1)
  1497. {
  1498. matchedIdx = matchedIndices[0];
  1499. }
  1500. else if (matchedIndices.size() > 1)
  1501. {
  1502. // Try to find a merged typeoptions with these indices
  1503. for (int mergedIdx = 0; mergedIdx < (int)mContext->mSystem->mMergedTypeOptions.size(); mergedIdx++)
  1504. {
  1505. auto& typeOptions = mContext->mSystem->mMergedTypeOptions[mergedIdx];
  1506. if (typeOptions.mMatchedIndices == matchedIndices)
  1507. {
  1508. matchedIdx = typeOptionsCount + mergedIdx;
  1509. break;
  1510. }
  1511. }
  1512. // Otherwise make one...
  1513. if (matchedIdx == -1)
  1514. {
  1515. auto& first = mContext->mSystem->mTypeOptions[matchedIndices[0]];
  1516. BfTypeOptions mergedTypeOptions;
  1517. mergedTypeOptions.mSIMDSetting = first.mSIMDSetting;
  1518. mergedTypeOptions.mOptimizationLevel = first.mOptimizationLevel;
  1519. mergedTypeOptions.mEmitDebugInfo = first.mEmitDebugInfo;
  1520. mergedTypeOptions.mAndFlags = first.mAndFlags;
  1521. mergedTypeOptions.mOrFlags = first.mOrFlags;
  1522. mergedTypeOptions.mAllocStackTraceDepth = first.mAllocStackTraceDepth;
  1523. mergedTypeOptions.mReflectMethodFilters = first.mReflectMethodFilters;
  1524. mergedTypeOptions.mReflectMethodAttributeFilters = first.mReflectMethodAttributeFilters;
  1525. mergedTypeOptions.mMatchedIndices = matchedIndices;
  1526. for (int idx = 1; idx < (int)matchedIndices.size(); idx++)
  1527. {
  1528. auto& typeOptions = mContext->mSystem->mTypeOptions[matchedIndices[idx]];
  1529. if (typeOptions.mSIMDSetting != -1)
  1530. mergedTypeOptions.mSIMDSetting = typeOptions.mSIMDSetting;
  1531. if (typeOptions.mOptimizationLevel != -1)
  1532. mergedTypeOptions.mOptimizationLevel = typeOptions.mOptimizationLevel;
  1533. if (typeOptions.mEmitDebugInfo != -1)
  1534. mergedTypeOptions.mEmitDebugInfo = typeOptions.mEmitDebugInfo;
  1535. mergedTypeOptions.mOrFlags = (BfOptionFlags)(mergedTypeOptions.mOrFlags | typeOptions.mOrFlags);
  1536. mergedTypeOptions.mAndFlags = (BfOptionFlags)(mergedTypeOptions.mAndFlags | typeOptions.mOrFlags);
  1537. mergedTypeOptions.mAndFlags = (BfOptionFlags)(mergedTypeOptions.mAndFlags & typeOptions.mAndFlags);
  1538. mergedTypeOptions.mOrFlags = (BfOptionFlags)(mergedTypeOptions.mOrFlags & typeOptions.mAndFlags);
  1539. if (typeOptions.mAllocStackTraceDepth != -1)
  1540. mergedTypeOptions.mAllocStackTraceDepth = typeOptions.mAllocStackTraceDepth;
  1541. for (auto& filter : typeOptions.mReflectMethodFilters)
  1542. mergedTypeOptions.mReflectMethodFilters.Add(filter);
  1543. for (auto& filter : typeOptions.mReflectMethodAttributeFilters)
  1544. mergedTypeOptions.mReflectMethodAttributeFilters.Add(filter);
  1545. }
  1546. matchedIdx = typeOptionsCount + (int)mContext->mSystem->mMergedTypeOptions.size();
  1547. mContext->mSystem->mMergedTypeOptions.push_back(mergedTypeOptions);
  1548. }
  1549. }
  1550. return matchedIdx;
  1551. }
  1552. void BfModule::SetTypeOptions(BfTypeInstance* typeInstance)
  1553. {
  1554. typeInstance->mTypeOptionsIdx = GenerateTypeOptions(typeInstance->mCustomAttributes, typeInstance, true);
  1555. }
  1556. void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateType)
  1557. {
  1558. auto typeInstance = resolvedTypeRef->ToTypeInstance();
  1559. auto typeDef = typeInstance->mTypeDef;
  1560. BF_ASSERT((typeInstance->mTypeDef->mNextRevision == NULL) || (mCompiler->IsAutocomplete()));
  1561. // This is a special case where our base type has been rebuilt but we haven't
  1562. if ((typeInstance->mBaseTypeMayBeIncomplete) && (!typeInstance->mTypeIncomplete))
  1563. {
  1564. BfLogSysM("BaseTypeMayBeIncomplete processing. Type:%p -> Base:%p\n", typeInstance, typeInstance->mBaseType);
  1565. PopulateType(typeInstance->mBaseType, populateType);
  1566. if (!typeInstance->mBaseType->IsIncomplete())
  1567. typeInstance->mBaseTypeMayBeIncomplete = false;
  1568. if (!typeInstance->mTypeIncomplete)
  1569. return;
  1570. }
  1571. typeInstance->mBaseTypeMayBeIncomplete = false;
  1572. BF_ASSERT(mIsModuleMutable);
  1573. // Don't do type instance method processing for an autocomplete pass - this will get handled later on during
  1574. // the PopulateType worklist pass in the full resolver. We do need to handle the methods for delegates, though,
  1575. // since those can affect method declarations of other methods
  1576. // TODO: Investigate this "Delegate" claim
  1577. bool canDoMethodProcessing = ((mCompiler->mResolvePassData == NULL) || (mCompiler->mResolvePassData->mAutoComplete == NULL) /*|| (typeInstance->IsDelegate())*/);
  1578. if (populateType == BfPopulateType_Full_Force)
  1579. canDoMethodProcessing = true;
  1580. if (typeInstance->mResolvingConstField)
  1581. return;
  1582. auto _CheckTypeDone = [&]()
  1583. {
  1584. if (typeInstance->mNeedsMethodProcessing)
  1585. {
  1586. BF_ASSERT(typeInstance->mDefineState >= BfTypeDefineState_Defined);
  1587. if ((canDoMethodProcessing) && (populateType >= BfPopulateType_DataAndMethods))
  1588. DoTypeInstanceMethodProcessing(typeInstance);
  1589. return true;
  1590. }
  1591. return false;
  1592. };
  1593. if (_CheckTypeDone())
  1594. return;
  1595. // Partial population break out point
  1596. if ((populateType >= BfPopulateType_Identity) && (populateType <= BfPopulateType_IdentityNoRemapAlias))
  1597. return;
  1598. if (!resolvedTypeRef->IsValueType())
  1599. {
  1600. resolvedTypeRef->mSize = typeInstance->mAlign = mSystem->mPtrSize;
  1601. }
  1602. BF_ASSERT((typeInstance->mMethodInstanceGroups.size() == 0) || (typeInstance->mMethodInstanceGroups.size() == typeDef->mMethods.size()));
  1603. typeInstance->mMethodInstanceGroups.Resize(typeDef->mMethods.size());
  1604. for (int i = 0; i < (int)typeInstance->mMethodInstanceGroups.size(); i++)
  1605. {
  1606. typeInstance->mMethodInstanceGroups[i].mOwner = typeInstance;
  1607. typeInstance->mMethodInstanceGroups[i].mMethodIdx = i;
  1608. }
  1609. AutoDisallowYield disableYield(mSystem);
  1610. SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, typeInstance);
  1611. SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, NULL);
  1612. SetAndRestoreValue<BfMethodState*> prevMethodState(mCurMethodState, NULL);
  1613. SetAndRestoreValue<bool> prevHadError(mHadBuildError, false);
  1614. SetAndRestoreValue<bool> prevHadWarning(mHadBuildWarning, false);
  1615. BfTypeState typeState(mCurTypeInstance, mContext->mCurTypeState);
  1616. typeState.mPopulateType = populateType;
  1617. SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
  1618. if (typeInstance->IsGenericTypeInstance())
  1619. {
  1620. auto genericTypeInst = (BfTypeInstance*)typeInstance;
  1621. if (genericTypeInst->mGenericTypeInfo->mGenericParams.size() == 0)
  1622. BuildGenericParams(resolvedTypeRef);
  1623. }
  1624. if (resolvedTypeRef->IsTypeAlias())
  1625. {
  1626. typeInstance->mTypeIncomplete = false;
  1627. resolvedTypeRef->mDefineState = BfTypeDefineState_DefinedAndMethodsSlotted;
  1628. return;
  1629. }
  1630. if (_CheckTypeDone())
  1631. return;
  1632. // Don't do TypeToString until down here. Otherwise we can infinitely loop on BuildGenericParams
  1633. bool isStruct = resolvedTypeRef->IsStruct();
  1634. bool reportErrors = true;
  1635. if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL))
  1636. reportErrors = true;
  1637. // If we're not the defining context then we don't report errors for this type, but errors will still put the system
  1638. // into an errored state
  1639. SetAndRestoreValue<bool> prevReportErrors(mReportErrors, reportErrors);
  1640. if (typeInstance->mIsFinishingType)
  1641. {
  1642. // This type already failed
  1643. return;
  1644. }
  1645. CheckCircularDataError();
  1646. bool underlyingTypeDeferred = false;
  1647. BfType* underlyingType = NULL;
  1648. if (typeInstance->mBaseType != NULL)
  1649. {
  1650. if (typeInstance->IsTypedPrimitive())
  1651. underlyingType = typeInstance->GetUnderlyingType();
  1652. if ((typeInstance->mRebuildFlags & BfTypeRebuildFlag_UnderlyingTypeDeferred) != 0)
  1653. underlyingTypeDeferred = true;
  1654. }
  1655. else if (typeInstance->IsEnum())
  1656. {
  1657. bool hasPayloads = false;
  1658. for (auto fieldDef : typeDef->mFields)
  1659. {
  1660. if ((fieldDef->IsEnumCaseEntry()) && (fieldDef->mTypeRef != NULL))
  1661. {
  1662. hasPayloads = true;
  1663. break;
  1664. }
  1665. }
  1666. if (!hasPayloads)
  1667. {
  1668. bool hadType = false;
  1669. for (auto baseTypeRef : typeDef->mBaseTypes)
  1670. {
  1671. SetAndRestoreValue<BfTypeReference*> prevTypeRef(mContext->mCurTypeState->mCurBaseTypeRef, baseTypeRef);
  1672. SetAndRestoreValue<BfTypeDefineState> prevDefineState(typeInstance->mDefineState, BfTypeDefineState_ResolvingBaseType);
  1673. SetAndRestoreValue<bool> prevIgnoreError(mIgnoreErrors, true);
  1674. SetAndRestoreValue<bool> prevSkipTypeProtectionChecks(typeInstance->mSkipTypeProtectionChecks, true);
  1675. auto baseType = ResolveTypeRef(baseTypeRef, BfPopulateType_Declaration);
  1676. if (baseType != NULL)
  1677. {
  1678. if (baseType->IsIntegral())
  1679. {
  1680. if (!hadType)
  1681. {
  1682. hadType = true;
  1683. underlyingType = baseType;
  1684. }
  1685. else
  1686. {
  1687. Fail("Underlying enum type already specified", baseTypeRef);
  1688. }
  1689. }
  1690. else
  1691. {
  1692. Fail("Invalid underlying enum type", baseTypeRef);
  1693. }
  1694. }
  1695. else
  1696. {
  1697. AssertErrorState();
  1698. typeInstance->mTypeFailed = true;
  1699. }
  1700. }
  1701. if (underlyingType == NULL)
  1702. {
  1703. underlyingType = GetPrimitiveType(BfTypeCode_Int64);
  1704. underlyingTypeDeferred = true;
  1705. }
  1706. }
  1707. }
  1708. // else if (typeInstance->IsFunction())
  1709. // {
  1710. // underlyingType = GetPrimitiveType(BfTypeCode_NullPtr);
  1711. // }
  1712. else if (((typeInstance->IsStruct()) || (typeInstance->IsTypedPrimitive())) &&
  1713. (!typeInstance->mTypeFailed))
  1714. {
  1715. for (auto baseTypeRef : typeDef->mBaseTypes)
  1716. {
  1717. auto declTypeDef = typeDef;
  1718. if (typeDef->mIsCombinedPartial)
  1719. declTypeDef = typeDef->mPartials.front();
  1720. SetAndRestoreValue<BfTypeDef*> prevTypeDef(mContext->mCurTypeState->mCurTypeDef, declTypeDef);
  1721. SetAndRestoreValue<BfTypeDefineState> prevDefineState(typeInstance->mDefineState, BfTypeDefineState_ResolvingBaseType);
  1722. SetAndRestoreValue<BfTypeReference*> prevTypeRef(mContext->mCurTypeState->mCurBaseTypeRef, baseTypeRef);
  1723. // We ignore errors here to avoid double-errors for type lookups, but this is where data cycles are detected
  1724. // but that type of error supersedes the mIgnoreErrors setting
  1725. SetAndRestoreValue<bool> prevIgnoreError(mIgnoreErrors, true);
  1726. // Temporarily allow us to derive from private classes, to avoid infinite loop from TypeIsSubTypeOf
  1727. SetAndRestoreValue<bool> prevSkipTypeProtectionChecks(typeInstance->mSkipTypeProtectionChecks, true);
  1728. auto baseType = ResolveTypeRef(baseTypeRef, BfPopulateType_Declaration);
  1729. if (baseType != NULL)
  1730. {
  1731. if (baseType->IsPrimitiveType())
  1732. {
  1733. underlyingType = baseType;
  1734. }
  1735. else if (baseType->IsTypedPrimitive())
  1736. {
  1737. //PopulateType(baseType, true);
  1738. underlyingType = baseType->GetUnderlyingType();
  1739. BF_ASSERT(underlyingType != NULL);
  1740. }
  1741. }
  1742. else
  1743. {
  1744. AssertErrorState();
  1745. typeInstance->mTypeFailed = true;
  1746. }
  1747. }
  1748. // Incase we had re-entry, work this through ourselves again here
  1749. typeInstance->mIsTypedPrimitive = false;
  1750. }
  1751. if (underlyingTypeDeferred)
  1752. typeInstance->mRebuildFlags = (BfTypeRebuildFlags)(typeInstance->mRebuildFlags | BfTypeRebuildFlag_UnderlyingTypeDeferred);
  1753. typeInstance->mIsTypedPrimitive = underlyingType != NULL;
  1754. int wantFieldCount = (int)typeDef->mFields.size() + (((underlyingType != NULL) || (typeInstance->IsPayloadEnum())) ? 1 : 0);
  1755. if ((int)typeInstance->mFieldInstances.size() < wantFieldCount)
  1756. {
  1757. // Closures don't include the enclosed fields on their first pass through PopulateType, and they have no typeDef of their own
  1758. // so we need to take care not to truncate their fieldInstance vector here (thus the 'wantFieldCount' check above)
  1759. typeInstance->mFieldInstances.Resize(wantFieldCount);
  1760. }
  1761. if (underlyingType != NULL)
  1762. {
  1763. auto fieldInstance = &typeInstance->mFieldInstances.back();
  1764. fieldInstance->mDataOffset = 0;
  1765. fieldInstance->mDataSize = underlyingType->mSize;
  1766. fieldInstance->mOwner = typeInstance;
  1767. fieldInstance->mResolvedType = underlyingType;
  1768. typeInstance->mSize = underlyingType->mSize;
  1769. typeInstance->mAlign = underlyingType->mAlign;
  1770. typeInstance->mInstSize = underlyingType->mSize;
  1771. typeInstance->mInstAlign = underlyingType->mAlign;
  1772. typeInstance->mHasPackingHoles = underlyingType->HasPackingHoles();
  1773. }
  1774. // Partial population break out point
  1775. if (typeInstance->mDefineState < BfTypeDefineState_Declared)
  1776. {
  1777. typeInstance->mDefineState = BfTypeDefineState_Declared;
  1778. if (typeInstance->IsGenericTypeInstance())
  1779. {
  1780. auto genericTypeInstance = (BfTypeInstance*)typeInstance;
  1781. // Add generic dependencies if needed
  1782. for (auto genericType : genericTypeInstance->mGenericTypeInfo->mTypeGenericArguments)
  1783. {
  1784. if (genericType->IsPrimitiveType())
  1785. genericType = GetWrappedStructType(genericType);
  1786. if (genericType != NULL)
  1787. {
  1788. AddDependency(genericType, genericTypeInstance, BfDependencyMap::DependencyFlag_TypeGenericArg);
  1789. BfLogSysM("Adding generic dependency of %p for type %p\n", genericType, genericTypeInstance);
  1790. }
  1791. }
  1792. if ((genericTypeInstance->IsSpecializedType()) &&
  1793. (!genericTypeInstance->IsDelegateFromTypeRef()) &&
  1794. (!genericTypeInstance->IsFunctionFromTypeRef()))
  1795. {
  1796. // This ensures we rebuild the unspecialized type whenever the specialized type rebuilds. This is important
  1797. // for generic type binding
  1798. auto unspecializedTypeInstance = GetUnspecializedTypeInstance(genericTypeInstance);
  1799. BF_ASSERT(!unspecializedTypeInstance->IsUnspecializedTypeVariation());
  1800. mContext->mScratchModule->AddDependency(genericTypeInstance, unspecializedTypeInstance, BfDependencyMap::DependencyFlag_UnspecializedType);
  1801. }
  1802. }
  1803. auto _AddStaticSearch = [&](BfTypeDef* typeDef)
  1804. {
  1805. if (typeDef->mStaticSearch.IsEmpty())
  1806. return;
  1807. BfStaticSearch* staticSearch;
  1808. if (typeInstance->mStaticSearchMap.TryAdd(typeDef, NULL, &staticSearch))
  1809. {
  1810. for (auto typeRef : typeDef->mStaticSearch)
  1811. {
  1812. auto staticType = ResolveTypeRef(typeRef, NULL, BfPopulateType_Declaration);
  1813. if (staticType != NULL)
  1814. {
  1815. auto staticTypeInst = staticType->ToTypeInstance();
  1816. if (staticTypeInst == NULL)
  1817. {
  1818. Fail(StrFormat("Type '%s' cannot be used in a 'using static' declaration", TypeToString(staticType).c_str()), typeRef);
  1819. }
  1820. else
  1821. {
  1822. staticSearch->mStaticTypes.Add(staticTypeInst);
  1823. AddDependency(staticTypeInst, typeInstance, BfDependencyMap::DependencyFlag_StaticValue);
  1824. }
  1825. }
  1826. }
  1827. }
  1828. };
  1829. if (typeDef->mIsCombinedPartial)
  1830. {
  1831. for (auto partialTypeDef : typeDef->mPartials)
  1832. _AddStaticSearch(partialTypeDef);
  1833. }
  1834. else
  1835. _AddStaticSearch(typeDef);
  1836. }
  1837. if (populateType == BfPopulateType_Declaration)
  1838. {
  1839. return;
  1840. }
  1841. if ((!mCompiler->mIsResolveOnly) && (!typeInstance->mHasBeenInstantiated))
  1842. {
  1843. for (auto& dep : typeInstance->mDependencyMap)
  1844. {
  1845. auto& depEntry = dep.mValue;
  1846. if ((depEntry.mFlags & BfDependencyMap::DependencyFlag_Allocates) != 0)
  1847. {
  1848. auto depType = dep.mKey;
  1849. if (depType->mRevision == depEntry.mRevision)
  1850. {
  1851. BfLogSysM("Setting mHasBeenInstantiated for %p instantiated from %p\n", typeInstance, depType);
  1852. typeInstance->mHasBeenInstantiated = true;
  1853. }
  1854. }
  1855. }
  1856. }
  1857. //BfLogSysM("Setting revision. Type: %p Revision: %d\n", typeInstance, mRevision);
  1858. //typeInstance->mRevision = mRevision;
  1859. // Temporarily allow us to derive from private classes, to avoid infinite loop from TypeIsSubTypeOf
  1860. SetAndRestoreValue<bool> prevSkipTypeProtectionChecks(typeInstance->mSkipTypeProtectionChecks, true);
  1861. if ((typeDef->mOuterType != NULL) && (typeDef->mOuterType->IsGlobalsContainer()))
  1862. {
  1863. if ((typeDef->mTypeDeclaration != NULL) && (typeDef->mTypeDeclaration->mTypeNode != NULL))
  1864. Fail("Global blocks cannot contain type declarations", typeDef->mTypeDeclaration->mTypeNode);
  1865. }
  1866. /// Create DI data
  1867. SizedArray<BfIRType, 8> llvmFieldTypes;
  1868. int curFieldDataIdx = 0;
  1869. typeInstance->mBaseType = NULL;
  1870. BfTypeInstance* defaultBaseTypeInst = NULL;
  1871. // Find base type
  1872. BfType* baseType = NULL;
  1873. struct BfInterfaceDecl
  1874. {
  1875. BfTypeInstance* mIFaceTypeInst;
  1876. BfTypeReference* mTypeRef;
  1877. BfTypeDef* mDeclaringType;
  1878. };
  1879. SizedArray<BfInterfaceDecl, 8> interfaces;
  1880. HashSet<BfTypeInstance*> ifaceSet;
  1881. if (resolvedTypeRef == mContext->mBfObjectType)
  1882. {
  1883. baseType = NULL;
  1884. }
  1885. else if (typeInstance->IsEnum())
  1886. {
  1887. if (mCompiler->mEnumTypeDef == NULL)
  1888. {
  1889. Fail("Enum type required");
  1890. TypeFailed(typeInstance);
  1891. }
  1892. else
  1893. baseType = ResolveTypeDef(mCompiler->mEnumTypeDef)->ToTypeInstance();
  1894. }
  1895. else if (resolvedTypeRef->IsObject())
  1896. baseType = mContext->mBfObjectType;
  1897. else if (resolvedTypeRef->IsPointer())
  1898. {
  1899. baseType = ResolveTypeDef(mCompiler->mPointerTTypeDef, BfPopulateType_Data);
  1900. }
  1901. else if ((resolvedTypeRef->IsValueType()) && (typeDef != mCompiler->mValueTypeTypeDef))
  1902. {
  1903. baseType = ResolveTypeDef(mCompiler->mValueTypeTypeDef, BfPopulateType_Data)->ToTypeInstance();
  1904. }
  1905. if (baseType != NULL)
  1906. defaultBaseTypeInst = baseType->ToTypeInstance();
  1907. struct _DeferredValidate
  1908. {
  1909. BfTypeReference* mTypeRef;
  1910. BfTypeInstance* mGenericType;
  1911. bool mIgnoreErrors;
  1912. };
  1913. Array<_DeferredValidate> deferredTypeValidateList;
  1914. BfTypeReference* baseTypeRef = NULL;
  1915. if ((typeDef->mIsDelegate) && (!typeInstance->IsClosure()))
  1916. {
  1917. if (mCompiler->mDelegateTypeDef == NULL)
  1918. {
  1919. Fail("Delegate type required");
  1920. TypeFailed(typeInstance);
  1921. }
  1922. else
  1923. baseType = ResolveTypeDef(mCompiler->mDelegateTypeDef)->ToTypeInstance();
  1924. }
  1925. else if (typeDef->mIsFunction)
  1926. {
  1927. if (mCompiler->mFunctionTypeDef == NULL)
  1928. {
  1929. Fail("Function type required");
  1930. TypeFailed(typeInstance);
  1931. }
  1932. else
  1933. baseType = ResolveTypeDef(mCompiler->mFunctionTypeDef)->ToTypeInstance();
  1934. }
  1935. else
  1936. {
  1937. for (auto checkTypeRef : typeDef->mBaseTypes)
  1938. {
  1939. auto declTypeDef = typeDef;
  1940. if (typeDef->mIsCombinedPartial)
  1941. declTypeDef = typeDef->mPartials.front();
  1942. SetAndRestoreValue<BfTypeDef*> prevTypeDef(mContext->mCurTypeState->mCurTypeDef, declTypeDef);
  1943. SetAndRestoreValue<BfTypeReference*> prevTypeRef(mContext->mCurTypeState->mCurBaseTypeRef, checkTypeRef);
  1944. SetAndRestoreValue<BfTypeDefineState> prevDefineState(typeInstance->mDefineState, BfTypeDefineState_ResolvingBaseType);
  1945. bool populateBase = !typeInstance->mTypeFailed;
  1946. auto checkType = ResolveTypeRef(checkTypeRef, populateBase ? BfPopulateType_Data : BfPopulateType_Declaration);
  1947. if (typeInstance->mDefineState >= BfTypeDefineState_Defined)
  1948. {
  1949. prevDefineState.CancelRestore();
  1950. return;
  1951. }
  1952. if (checkType != NULL)
  1953. {
  1954. if (auto genericTypeInst = checkType->ToGenericTypeInstance())
  1955. {
  1956. // Specialized type variations don't need to validate their constraints
  1957. if (!typeInstance->IsUnspecializedTypeVariation())
  1958. deferredTypeValidateList.Add({ checkTypeRef, genericTypeInst, false });
  1959. }
  1960. auto checkTypeInst = checkType->ToTypeInstance();
  1961. bool canDeriveFrom = checkTypeInst != NULL;
  1962. if ((typeInstance->IsStruct()) || (typeInstance->IsTypedPrimitive()) || (typeInstance->IsBoxed()))
  1963. canDeriveFrom |= checkType->IsPrimitiveType();
  1964. if ((typeInstance->IsEnum()) && (!checkType->IsInterface()))
  1965. {
  1966. if (typeInstance->IsTypedPrimitive())
  1967. continue;
  1968. if (checkType->IsPrimitiveType())
  1969. Fail(StrFormat("Enum '%s' cannot be specified as '%s' because it has a payload",
  1970. TypeToString(typeInstance).c_str(), TypeToString(checkType).c_str()),
  1971. checkTypeRef);
  1972. else
  1973. Fail("Enums cannot derive from other types", checkTypeRef);
  1974. continue;
  1975. }
  1976. if ((checkTypeInst != NULL) && (checkTypeInst->mTypeFailed))
  1977. {
  1978. // To keep circular references from breaking type invariants (ie: base type loops)
  1979. continue;
  1980. }
  1981. if (!canDeriveFrom)
  1982. {
  1983. Fail("Cannot derive from this type", checkTypeRef);
  1984. continue;
  1985. }
  1986. if (checkType->IsInterface())
  1987. {
  1988. auto ifaceInst = checkType->ToTypeInstance();
  1989. if (ifaceSet.Add(ifaceInst))
  1990. {
  1991. // Not base type
  1992. BfInterfaceDecl ifaceDecl;
  1993. ifaceDecl.mIFaceTypeInst = ifaceInst;
  1994. ifaceDecl.mTypeRef = checkTypeRef;
  1995. ifaceDecl.mDeclaringType = typeDef;
  1996. interfaces.push_back(ifaceDecl);
  1997. }
  1998. else
  1999. {
  2000. Fail(StrFormat("Interface '%s' is already specified", TypeToString(checkType).c_str()), checkTypeRef);
  2001. }
  2002. }
  2003. else if (resolvedTypeRef == mContext->mBfObjectType)
  2004. {
  2005. Fail(StrFormat("Type '%s' cannot define a base type", TypeToString(baseType).c_str()), checkTypeRef);
  2006. }
  2007. else
  2008. {
  2009. if (baseTypeRef != NULL)
  2010. {
  2011. Fail(StrFormat("Base type '%s' already declared", TypeToString(baseType).c_str()), checkTypeRef);
  2012. }
  2013. else
  2014. {
  2015. baseTypeRef = checkTypeRef;
  2016. if (checkTypeInst != NULL)
  2017. {
  2018. baseType = checkTypeInst;
  2019. /*if ((resolvedTypeRef->IsBoxed()) && (baseType->IsValueType()))
  2020. {
  2021. baseType = CreateBoxedType(baseType);
  2022. }*/
  2023. }
  2024. }
  2025. }
  2026. }
  2027. else
  2028. {
  2029. AssertErrorState();
  2030. // Why did we go around setting mTypeFailed on all these things?
  2031. //typeInstance->mTypeFailed = true;
  2032. }
  2033. }
  2034. for (auto partialTypeDef : typeDef->mPartials)
  2035. {
  2036. if (!typeInstance->IsTypeMemberIncluded(partialTypeDef))
  2037. continue;
  2038. if (partialTypeDef->mTypeDeclaration == typeInstance->mTypeDef->mTypeDeclaration)
  2039. continue;
  2040. for (auto checkTypeRef : partialTypeDef->mBaseTypes)
  2041. {
  2042. SetAndRestoreValue<BfTypeReference*> prevTypeRef(mContext->mCurTypeState->mCurBaseTypeRef, checkTypeRef);
  2043. SetAndRestoreValue<BfTypeDef*> prevTypeDef(mContext->mCurTypeState->mCurTypeDef, partialTypeDef);
  2044. bool populateBase = !typeInstance->mTypeFailed;
  2045. auto checkType = ResolveTypeRef(checkTypeRef, BfPopulateType_Declaration);
  2046. if (checkType != NULL)
  2047. {
  2048. if (checkType->IsInterface())
  2049. {
  2050. BfInterfaceDecl ifaceDecl;
  2051. ifaceDecl.mIFaceTypeInst = checkType->ToTypeInstance();
  2052. ifaceDecl.mTypeRef = checkTypeRef;
  2053. ifaceDecl.mDeclaringType = partialTypeDef;
  2054. interfaces.push_back(ifaceDecl);
  2055. }
  2056. else
  2057. {
  2058. Fail(StrFormat("Extensions can only specify new interfaces, type '%s' is not a valid ", TypeToString(checkType).c_str()), checkTypeRef);
  2059. }
  2060. }
  2061. }
  2062. }
  2063. }
  2064. if (resolvedTypeRef->IsBoxed())
  2065. {
  2066. if ((baseType != NULL) && (baseType->IsStruct()))
  2067. {
  2068. BfBoxedType* boxedType = (BfBoxedType*)resolvedTypeRef;
  2069. BfType* modifiedBaseType = baseType;
  2070. if (boxedType->IsBoxedStructPtr())
  2071. modifiedBaseType = CreatePointerType(modifiedBaseType);
  2072. boxedType->mBoxedBaseType = CreateBoxedType(modifiedBaseType);
  2073. PopulateType(boxedType->mBoxedBaseType);
  2074. AddDependency(boxedType->mBoxedBaseType, typeInstance, BfDependencyMap::DependencyFlag_DerivedFrom);
  2075. }
  2076. baseType = mContext->mBfObjectType;
  2077. }
  2078. BfTypeInstance* baseTypeInst = NULL;
  2079. if (baseType != NULL)
  2080. {
  2081. baseTypeInst = baseType->ToTypeInstance();
  2082. }
  2083. if (typeInstance->mBaseType != NULL)
  2084. {
  2085. BF_ASSERT(typeInstance->mBaseType == baseTypeInst);
  2086. }
  2087. if (auto genericTypeInst = typeInstance->ToGenericTypeInstance())
  2088. {
  2089. if ((genericTypeInst->IsSpecializedType()) && (!genericTypeInst->mGenericTypeInfo->mValidatedGenericConstraints) && (!typeInstance->IsBoxed()))
  2090. {
  2091. deferredTypeValidateList.Add({ NULL, genericTypeInst, true });
  2092. }
  2093. }
  2094. if (!typeInstance->IsBoxed())
  2095. {
  2096. BfType* outerType = GetOuterType(typeInstance);
  2097. if (outerType != NULL)
  2098. {
  2099. PopulateType(outerType, BfPopulateType_BaseType);
  2100. AddDependency(outerType, typeInstance, BfDependencyMap::DependencyFlag_OuterType);
  2101. }
  2102. }
  2103. if ((baseTypeInst != NULL) && (typeInstance->mBaseType == NULL))
  2104. {
  2105. if (typeInstance->mTypeFailed)
  2106. {
  2107. if (baseTypeInst->IsDataIncomplete())
  2108. {
  2109. if (baseTypeInst->IsStruct())
  2110. baseTypeInst = ResolveTypeDef(mCompiler->mValueTypeTypeDef)->ToTypeInstance();
  2111. else if (baseTypeInst->IsObject())
  2112. baseTypeInst = ResolveTypeDef(mCompiler->mBfObjectTypeDef)->ToTypeInstance();
  2113. }
  2114. }
  2115. PopulateType(baseTypeInst, BfPopulateType_Data);
  2116. typeInstance->mBaseTypeMayBeIncomplete = false;
  2117. typeInstance->mMergedFieldDataCount = baseTypeInst->mMergedFieldDataCount;
  2118. if ((resolvedTypeRef->IsObject()) && (!baseTypeInst->IsObject()))
  2119. {
  2120. Fail("Class can only derive from another class", baseTypeRef, true);
  2121. //typeInstance->mTypeFailed = true;
  2122. baseTypeInst = defaultBaseTypeInst;
  2123. typeInstance->mBaseType = baseTypeInst;
  2124. }
  2125. else if ((resolvedTypeRef->IsStruct()) && (!baseTypeInst->IsValueType()))
  2126. {
  2127. Fail("Struct can only derive from another struct", baseTypeRef, true);
  2128. //typeInstance->mTypeFailed = true;
  2129. baseTypeInst = defaultBaseTypeInst;
  2130. typeInstance->mBaseType = baseTypeInst;
  2131. }
  2132. if (!typeInstance->IsIncomplete())
  2133. {
  2134. // Re-entry may cause this type to be completed already
  2135. return;
  2136. }
  2137. //BfLogSysM("Adding DerivedFrom dependency. Used:%p Using:%p\n", baseType, typeInstance);
  2138. auto checkBaseType = baseTypeInst;
  2139. while (checkBaseType != NULL)
  2140. {
  2141. // Add 'DerivedFrom' dependency all the way up the inheritance chain
  2142. AddDependency(checkBaseType, typeInstance, BfDependencyMap::DependencyFlag_DerivedFrom);
  2143. checkBaseType = checkBaseType->mBaseType;
  2144. }
  2145. typeInstance->mBaseType = baseTypeInst;
  2146. typeInstance->mInheritDepth = baseTypeInst->mInheritDepth + 1;
  2147. typeInstance->mHasParameterizedBase = baseTypeInst->mHasParameterizedBase;
  2148. if ((baseTypeInst->IsArray()) || (baseTypeInst->IsSizedArray()) || (baseTypeInst->IsGenericTypeInstance()))
  2149. typeInstance->mHasParameterizedBase = true;
  2150. if (underlyingType == NULL)
  2151. {
  2152. typeInstance->mInstSize = baseTypeInst->mInstSize;
  2153. typeInstance->mInstAlign = baseTypeInst->mInstAlign;
  2154. typeInstance->mAlign = baseTypeInst->mAlign;
  2155. typeInstance->mSize = baseTypeInst->mSize;
  2156. typeInstance->mHasPackingHoles = baseTypeInst->mHasPackingHoles;
  2157. if (baseTypeInst->mIsTypedPrimitive)
  2158. typeInstance->mIsTypedPrimitive = true;
  2159. }
  2160. }
  2161. if (populateType <= BfPopulateType_BaseType)
  2162. return;
  2163. if ((typeInstance->mBaseType != NULL) && (!typeInstance->IsTypedPrimitive()))
  2164. {
  2165. curFieldDataIdx++;
  2166. }
  2167. if (!interfaces.empty())
  2168. {
  2169. for (int iFaceIdx = 0; iFaceIdx < (int)interfaces.size(); iFaceIdx++)
  2170. {
  2171. auto checkInterface = interfaces[iFaceIdx].mIFaceTypeInst;
  2172. PopulateType(checkInterface, BfPopulateType_Data);
  2173. BfTypeInterfaceEntry* found = NULL;
  2174. bool foundExact = false;
  2175. for (auto& typeInterfaceInst : typeInstance->mInterfaces)
  2176. {
  2177. if (typeInterfaceInst.mInterfaceType == checkInterface)
  2178. {
  2179. if (typeInterfaceInst.mDeclaringType == interfaces[iFaceIdx].mDeclaringType)
  2180. {
  2181. foundExact = true;
  2182. break;
  2183. }
  2184. found = &typeInterfaceInst;
  2185. }
  2186. }
  2187. if (foundExact)
  2188. continue;
  2189. BfTypeInterfaceEntry typeInterfaceInst;
  2190. typeInterfaceInst.mDeclaringType = interfaces[iFaceIdx].mDeclaringType;
  2191. typeInterfaceInst.mInterfaceType = checkInterface;
  2192. typeInterfaceInst.mStartInterfaceTableIdx = -1;
  2193. typeInterfaceInst.mStartVirtualIdx = -1;
  2194. typeInterfaceInst.mIsRedeclared = false;
  2195. typeInstance->mInterfaces.push_back(typeInterfaceInst);
  2196. AddDependency(checkInterface, typeInstance, BfDependencyMap::DependencyFlag_ImplementsInterface);
  2197. // Interfaces can list other interfaces in their declaration, so pull those in too
  2198. for (auto depIFace : checkInterface->mInterfaces)
  2199. {
  2200. auto depIFaceEntry = interfaces[iFaceIdx];
  2201. depIFaceEntry.mIFaceTypeInst = depIFace.mInterfaceType;
  2202. interfaces.push_back(depIFaceEntry);
  2203. }
  2204. }
  2205. }
  2206. BF_ASSERT(!typeInstance->mNeedsMethodProcessing);
  2207. typeInstance->mDefineState = BfTypeDefineState_HasInterfaces;
  2208. for (auto& validateEntry : deferredTypeValidateList)
  2209. {
  2210. SetAndRestoreValue<bool> ignoreErrors(mIgnoreErrors, mIgnoreErrors | validateEntry.mIgnoreErrors);
  2211. ValidateGenericConstraints(validateEntry.mTypeRef, validateEntry.mGenericType, false);
  2212. }
  2213. if (populateType <= BfPopulateType_Interfaces)
  2214. return;
  2215. prevSkipTypeProtectionChecks.Restore();
  2216. typeInstance->mInstSize = std::max(0, typeInstance->mInstSize);
  2217. typeInstance->mInstAlign = std::max(0, typeInstance->mInstAlign);
  2218. if (!typeInstance->IsBoxed())
  2219. {
  2220. if ((typeInstance->mCustomAttributes == NULL) && (typeDef->mTypeDeclaration != NULL) && (typeDef->mTypeDeclaration->mAttributes != NULL))
  2221. {
  2222. BfAttributeTargets attrTarget;
  2223. if ((typeDef->mIsDelegate) || (typeDef->mIsFunction))
  2224. attrTarget = BfAttributeTargets_Delegate;
  2225. else if (typeInstance->IsEnum())
  2226. attrTarget = BfAttributeTargets_Enum;
  2227. else if (typeInstance->IsInterface())
  2228. attrTarget = BfAttributeTargets_Interface;
  2229. else if (typeInstance->IsStruct())
  2230. attrTarget = BfAttributeTargets_Struct;
  2231. else
  2232. attrTarget = BfAttributeTargets_Class;
  2233. if (!typeInstance->mTypeFailed)
  2234. {
  2235. // This allows us to avoid reentrancy when checking for inner types
  2236. SetAndRestoreValue<bool> prevSkipTypeProtectionChecks(typeInstance->mSkipTypeProtectionChecks, true);
  2237. if (typeDef->mIsCombinedPartial)
  2238. {
  2239. for (auto partialTypeDef : typeDef->mPartials)
  2240. {
  2241. if (partialTypeDef->mTypeDeclaration->mAttributes == NULL)
  2242. continue;
  2243. BfTypeState typeState;
  2244. typeState.mPrevState = mContext->mCurTypeState;
  2245. typeState.mCurTypeDef = partialTypeDef;
  2246. typeState.mTypeInstance = typeInstance;
  2247. SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
  2248. if (typeInstance->mCustomAttributes == NULL)
  2249. typeInstance->mCustomAttributes = new BfCustomAttributes();
  2250. GetCustomAttributes(typeInstance->mCustomAttributes, partialTypeDef->mTypeDeclaration->mAttributes, attrTarget);
  2251. }
  2252. }
  2253. else
  2254. typeInstance->mCustomAttributes = GetCustomAttributes(typeDef->mTypeDeclaration->mAttributes, attrTarget);
  2255. }
  2256. }
  2257. }
  2258. if (typeInstance->mTypeOptionsIdx == -2)
  2259. SetTypeOptions(typeInstance);
  2260. ProcessCustomAttributeData();
  2261. bool isPacked = false;
  2262. bool isUnion = false;
  2263. bool isCRepr = false;
  2264. bool isOrdered = false;
  2265. BfType* underlyingArrayType = NULL;
  2266. int underlyingArraySize = -1;
  2267. ProcessTypeInstCustomAttributes(isPacked, isUnion, isCRepr, isOrdered, underlyingArrayType, underlyingArraySize);
  2268. if (underlyingArraySize > 0)
  2269. {
  2270. typeInstance->mHasUnderlyingArray = true;
  2271. curFieldDataIdx = 0;
  2272. }
  2273. if (isPacked) // Packed infers ordered
  2274. isOrdered = true;
  2275. typeInstance->mIsUnion = isUnion;
  2276. if ((typeInstance->IsEnum()) && (typeInstance->IsStruct()))
  2277. typeInstance->mIsUnion = true;
  2278. typeInstance->mIsPacked = isPacked;
  2279. typeInstance->mIsCRepr = isCRepr;
  2280. if (typeInstance->mTypeOptionsIdx >= 0)
  2281. {
  2282. auto typeOptions = mSystem->GetTypeOptions(typeInstance->mTypeOptionsIdx);
  2283. if (typeOptions != NULL)
  2284. {
  2285. typeInstance->mHasBeenInstantiated = typeOptions->Apply(typeInstance->mHasBeenInstantiated, BfOptionFlags_ReflectAssumeInstantiated);
  2286. }
  2287. }
  2288. BfType* unionInnerType = NULL;
  2289. bool hadDeferredVars = false;
  2290. int dataPos;
  2291. if (resolvedTypeRef->IsBoxed())
  2292. {
  2293. BfBoxedType* boxedType = (BfBoxedType*)resolvedTypeRef;
  2294. BfType* innerType = boxedType->mElementType;
  2295. if (boxedType->IsBoxedStructPtr())
  2296. innerType = CreatePointerType(innerType);
  2297. if (innerType->IsIncomplete())
  2298. PopulateType(innerType, BfPopulateType_Data);
  2299. auto baseType = typeInstance->mBaseType;
  2300. dataPos = baseType->mInstSize;
  2301. int alignSize = BF_MAX(innerType->mAlign, baseType->mInstAlign);
  2302. if (alignSize > 1)
  2303. dataPos = (dataPos + (alignSize - 1)) & ~(alignSize - 1);
  2304. int dataSize = innerType->mSize;
  2305. typeInstance->mFieldInstances.push_back(BfFieldInstance());
  2306. BfFieldInstance* fieldInstance = &typeInstance->mFieldInstances.back();
  2307. fieldInstance->mDataOffset = dataPos;
  2308. fieldInstance->mDataSize = innerType->mSize;
  2309. fieldInstance->mOwner = typeInstance;
  2310. fieldInstance->mResolvedType = innerType;
  2311. if (!innerType->IsValuelessType())
  2312. {
  2313. curFieldDataIdx++;
  2314. }
  2315. dataPos += dataSize;
  2316. typeInstance->mInstAlign = std::max(baseType->mInstAlign, alignSize);
  2317. int instAlign = typeInstance->mInstAlign;
  2318. if (instAlign != 0)
  2319. {
  2320. int instSize = (dataPos + (instAlign - 1)) & ~(instAlign - 1);
  2321. if (instSize != typeInstance->mInstSize)
  2322. {
  2323. typeInstance->mInstSize = instSize;
  2324. typeInstance->mHasPackingHoles = true;
  2325. }
  2326. }
  2327. typeInstance->mInstSize = std::max(1, typeInstance->mInstSize);
  2328. }
  2329. else
  2330. {
  2331. dataPos = typeInstance->mInstSize;
  2332. if (underlyingType != NULL)
  2333. {
  2334. if (!underlyingType->IsValuelessType())
  2335. {
  2336. curFieldDataIdx++;
  2337. }
  2338. }
  2339. struct DeferredResolveEntry
  2340. {
  2341. BfFieldDef* mFieldDef;
  2342. int mTypeArrayIdx;
  2343. };
  2344. BfSizedVector<DeferredResolveEntry, 8> deferredVarResolves;
  2345. for (auto field : typeDef->mFields)
  2346. {
  2347. auto fieldInstance = &typeInstance->mFieldInstances[field->mIdx];
  2348. if (fieldInstance->mResolvedType != NULL)
  2349. continue;
  2350. if (!typeInstance->IsTypeMemberIncluded(field->mDeclaringType))
  2351. {
  2352. fieldInstance->mFieldIncluded = false;
  2353. continue;
  2354. }
  2355. fieldInstance->mOwner = typeInstance;
  2356. fieldInstance->mFieldIdx = field->mIdx;
  2357. if (typeInstance->IsInterface())
  2358. Fail("Interfaces cannot include fields. Consider making this a property", field->GetRefNode());
  2359. }
  2360. int enumCaseEntryIdx = 0;
  2361. for (int pass = 0; pass < 2; pass++)
  2362. {
  2363. for (auto field : typeDef->mFields)
  2364. {
  2365. // Do consts then non-consts. Somewhat of a hack for using consts as sized array size
  2366. if (field->mIsConst != (pass == 0))
  2367. continue;
  2368. auto fieldInstance = &typeInstance->mFieldInstances[field->mIdx];
  2369. if ((fieldInstance->mResolvedType != NULL) || (!fieldInstance->mFieldIncluded))
  2370. continue;
  2371. SetAndRestoreValue<BfFieldDef*> prevTypeRef(mContext->mCurTypeState->mCurFieldDef, field);
  2372. BfType* resolvedFieldType = NULL;
  2373. if (field->IsEnumCaseEntry())
  2374. {
  2375. fieldInstance->mDataIdx = -(enumCaseEntryIdx++) - 1;
  2376. resolvedFieldType = typeInstance;
  2377. BfType* payloadType = NULL;
  2378. if (field->mTypeRef != NULL)
  2379. payloadType = ResolveTypeRef(field->mTypeRef, BfPopulateType_Data, BfResolveTypeRefFlag_NoResolveGenericParam);
  2380. if (payloadType == NULL)
  2381. {
  2382. if (!typeInstance->IsTypedPrimitive())
  2383. payloadType = CreateTupleType(BfTypeVector(), Array<String>());
  2384. }
  2385. if (payloadType != NULL)
  2386. {
  2387. AddDependency(payloadType, typeInstance, BfDependencyMap::DependencyFlag_ValueTypeMemberData);
  2388. BF_ASSERT(payloadType->IsTuple());
  2389. resolvedFieldType = payloadType;
  2390. fieldInstance->mIsEnumPayloadCase = true;
  2391. }
  2392. }
  2393. else if ((field->mTypeRef != NULL) && ((field->mTypeRef->IsExact<BfVarTypeReference>()) || (field->mTypeRef->IsExact<BfLetTypeReference>()) || (field->mTypeRef->IsExact<BfDeclTypeRef>())))
  2394. {
  2395. resolvedFieldType = GetPrimitiveType(BfTypeCode_Var);
  2396. DeferredResolveEntry resolveEntry;
  2397. resolveEntry.mFieldDef = field;
  2398. resolveEntry.mTypeArrayIdx = (int)llvmFieldTypes.size();
  2399. deferredVarResolves.push_back(resolveEntry);
  2400. fieldInstance->mIsInferredType = true;
  2401. // For 'let', make read-only
  2402. }
  2403. else
  2404. {
  2405. resolvedFieldType = ResolveTypeRef(field->mTypeRef, BfPopulateType_Declaration, BfResolveTypeRefFlag_NoResolveGenericParam);
  2406. if (resolvedFieldType == NULL)
  2407. {
  2408. // Failed, just put in placeholder 'var'
  2409. AssertErrorState();
  2410. resolvedFieldType = GetPrimitiveType(BfTypeCode_Var);
  2411. }
  2412. }
  2413. if (resolvedFieldType->IsMethodRef())
  2414. {
  2415. auto methodRefType = (BfMethodRefType*)resolvedFieldType;
  2416. }
  2417. if (fieldInstance->mResolvedType == NULL)
  2418. fieldInstance->mResolvedType = resolvedFieldType;
  2419. if (field->mIsConst)
  2420. {
  2421. // Resolve in ResolveConstField after we finish populating entire FieldInstance list
  2422. }
  2423. else if (field->mIsStatic)
  2424. {
  2425. // Don't allocate this until after we're finished populating entire FieldInstance list,
  2426. // because we may have re-entry and create multiple instances of this static field
  2427. }
  2428. }
  2429. }
  2430. if (!resolvedTypeRef->IsIncomplete())
  2431. {
  2432. // We finished resolving ourselves through a re-entry, so we're actually done here
  2433. return;
  2434. }
  2435. for (auto& resolveEntry : deferredVarResolves)
  2436. {
  2437. hadDeferredVars = true;
  2438. auto fieldType = ResolveVarFieldType(typeInstance, &typeInstance->mFieldInstances[resolveEntry.mFieldDef->mIdx], resolveEntry.mFieldDef);
  2439. if (fieldType == NULL)
  2440. {
  2441. fieldType = mContext->mBfObjectType;
  2442. // We used to set mTypeFailed, but mHasBuildError is enough to cause a type rebuild properly
  2443. mHadBuildError = true;
  2444. //typeInstance->mTypeFailed = true;
  2445. }
  2446. auto fieldInstance = &typeInstance->mFieldInstances[resolveEntry.mFieldDef->mIdx];
  2447. fieldInstance->SetResolvedType(fieldType);
  2448. }
  2449. if (typeInstance->mResolvingConstField)
  2450. return;
  2451. for (auto& fieldInstanceRef : typeInstance->mFieldInstances)
  2452. {
  2453. auto fieldInstance = &fieldInstanceRef;
  2454. auto fieldDef = fieldInstance->GetFieldDef();
  2455. auto resolvedFieldType = fieldInstance->GetResolvedType();
  2456. if (!fieldInstance->mFieldIncluded)
  2457. continue;
  2458. if (resolvedFieldType == NULL)
  2459. {
  2460. if ((underlyingType != NULL) || (typeInstance->IsPayloadEnum()))
  2461. continue;
  2462. }
  2463. if (!fieldInstance->mFieldIncluded)
  2464. continue;
  2465. if (fieldDef == NULL)
  2466. continue;
  2467. if ((!fieldDef->mIsStatic) && (resolvedFieldType->IsValueType()))
  2468. {
  2469. // We need that type finished up for alignment and data size
  2470. // But if the type has failed then we need to avoid stack overflow so we don't finish it
  2471. SetAndRestoreValue<BfFieldDef*> prevTypeRef(mContext->mCurTypeState->mCurFieldDef, fieldDef);
  2472. bool populateChildType = !typeInstance->mTypeFailed;
  2473. //bool populateChildType = true;
  2474. PopulateType(resolvedFieldType, populateChildType ? BfPopulateType_Data : BfPopulateType_Declaration);
  2475. if (populateChildType)
  2476. {
  2477. BF_ASSERT(!resolvedFieldType->IsDataIncomplete());
  2478. }
  2479. else
  2480. {
  2481. if (resolvedFieldType->IsDataIncomplete())
  2482. {
  2483. AssertErrorState();
  2484. resolvedFieldType = mContext->mBfObjectType;
  2485. fieldInstance->SetResolvedType(resolvedFieldType);
  2486. // We used to set mTypeFailed, but mHasBuildError is enough to cause a type rebuild properly
  2487. mHadBuildError = true;
  2488. }
  2489. }
  2490. }
  2491. }
  2492. }
  2493. if (_CheckTypeDone())
  2494. return;
  2495. BF_ASSERT(mContext->mCurTypeState == &typeState);
  2496. //BF_ASSERT(!typeInstance->mIsFinishingType);
  2497. typeInstance->mIsFinishingType = true;
  2498. // No re-entry is allowed below here -- we will run all the way to the end at this point
  2499. BfSizedVector<BfIRMDNode, 8> diFieldTypes;
  2500. HashContext dataMemberHashCtx;
  2501. if (!resolvedTypeRef->IsBoxed())
  2502. {
  2503. for (auto propDef : typeDef->mProperties)
  2504. {
  2505. if (!typeInstance->IsTypeMemberIncluded(propDef->mDeclaringType))
  2506. continue;
  2507. if (propDef->mFieldDeclaration != NULL)
  2508. {
  2509. BfTypeState typeState;
  2510. typeState.mPrevState = mContext->mCurTypeState;
  2511. typeState.mCurTypeDef = propDef->mDeclaringType;
  2512. typeState.mCurFieldDef = propDef;
  2513. typeState.mTypeInstance = typeInstance;
  2514. SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
  2515. if (propDef->mFieldDeclaration->mAttributes != NULL)
  2516. {
  2517. auto customAttrs = GetCustomAttributes(propDef->mFieldDeclaration->mAttributes, BfAttributeTargets_Property);
  2518. delete customAttrs;
  2519. }
  2520. if (propDef->mFieldDeclaration->mAttributes != NULL)
  2521. {
  2522. auto customAttrs = GetCustomAttributes(propDef->mFieldDeclaration->mAttributes, BfAttributeTargets_Property);
  2523. delete customAttrs;
  2524. }
  2525. auto propDecl = (BfPropertyDeclaration*)propDef->mFieldDeclaration;
  2526. if (propDecl->mExplicitInterface != NULL)
  2527. {
  2528. if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL))
  2529. mCompiler->mResolvePassData->mAutoComplete->CheckTypeRef(propDecl->mExplicitInterface, false);
  2530. auto explicitInterface = ResolveTypeRef(propDecl->mExplicitInterface, BfPopulateType_Declaration);
  2531. if (explicitInterface != NULL)
  2532. {
  2533. bool interfaceFound = false;
  2534. for (auto ifaceInst : typeInstance->mInterfaces)
  2535. interfaceFound |= ifaceInst.mInterfaceType == explicitInterface;
  2536. if (!interfaceFound)
  2537. {
  2538. Fail("Containing class has not declared to implement this interface", propDecl->mExplicitInterface, true);
  2539. }
  2540. }
  2541. }
  2542. }
  2543. if (propDef->mMethods.IsEmpty())
  2544. {
  2545. auto nameNode = ((BfPropertyDeclaration*)propDef->mFieldDeclaration)->mNameNode;
  2546. if (nameNode != NULL)
  2547. {
  2548. Fail(StrFormat("Property or indexer '%s.%s' must have at least one accessor", TypeToString(typeInstance).c_str(), propDef->mName.c_str()),
  2549. nameNode, true); // CS0548
  2550. }
  2551. }
  2552. }
  2553. bool isGlobalContainer = typeDef->IsGlobalsContainer();
  2554. if (typeInstance->mBaseType != NULL)
  2555. {
  2556. dataMemberHashCtx.Mixin(typeInstance->mBaseType->mTypeId);
  2557. if (typeInstance->mBaseType->mHotTypeData != NULL)
  2558. {
  2559. BfHotTypeVersion* ver = typeInstance->mBaseType->mHotTypeData->GetLatestVersion();
  2560. dataMemberHashCtx.Mixin(ver->mDataHash);
  2561. }
  2562. }
  2563. dataMemberHashCtx.Mixin(typeInstance->mIsPacked);
  2564. dataMemberHashCtx.Mixin(typeInstance->mIsCRepr);
  2565. dataMemberHashCtx.Mixin(typeInstance->mIsUnion);
  2566. int startDataPos = dataPos;
  2567. int maxDataPos = dataPos;
  2568. BfSizedVector<BfFieldInstance*, 16> dataFieldVec;
  2569. bool allowInstanceFields = (underlyingType == NULL);
  2570. if (typeInstance->IsTypedPrimitive())
  2571. allowInstanceFields = false;
  2572. // We've resolved all the 'var' entries, so now build the actual composite type
  2573. for (auto& fieldInstanceRef : typeInstance->mFieldInstances)
  2574. {
  2575. auto fieldInstance = &fieldInstanceRef;
  2576. if (!fieldInstance->mFieldIncluded)
  2577. continue;
  2578. auto resolvedFieldType = fieldInstance->GetResolvedType();
  2579. if (fieldInstance->mResolvedType == NULL)
  2580. {
  2581. if ((underlyingType == NULL) && (!typeInstance->IsPayloadEnum()))
  2582. BF_ASSERT(typeInstance->mTypeFailed);
  2583. continue;
  2584. }
  2585. if ((fieldInstance->GetFieldDef() != NULL) && (fieldInstance->GetFieldDef()->mIsConst))
  2586. {
  2587. // Resolve later
  2588. }
  2589. else if (fieldInstance->GetFieldDef() != NULL)
  2590. {
  2591. if (!fieldInstance->GetFieldDef()->mIsStatic)
  2592. AddFieldDependency(typeInstance, fieldInstance, resolvedFieldType);
  2593. else
  2594. AddDependency(resolvedFieldType, typeInstance, BfDependencyMap::DependencyFlag_StaticValue);
  2595. }
  2596. auto fieldDef = fieldInstance->GetFieldDef();
  2597. BF_ASSERT(fieldInstance->mCustomAttributes == NULL);
  2598. if ((fieldDef != NULL) && (fieldDef->mFieldDeclaration != NULL) && (fieldDef->mFieldDeclaration->mAttributes != NULL))
  2599. {
  2600. BfTypeState typeState;
  2601. typeState.mPrevState = mContext->mCurTypeState;
  2602. typeState.mCurFieldDef = fieldDef;
  2603. typeState.mCurTypeDef = fieldDef->mDeclaringType;
  2604. typeState.mTypeInstance = typeInstance;
  2605. SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
  2606. fieldInstance->mCustomAttributes = GetCustomAttributes(fieldDef->mFieldDeclaration->mAttributes, fieldDef->mIsStatic ? BfAttributeTargets_StaticField : BfAttributeTargets_Field);
  2607. for (auto customAttr : fieldInstance->mCustomAttributes->mAttributes)
  2608. {
  2609. if (TypeToString(customAttr.mType) == "System.ThreadStaticAttribute")
  2610. {
  2611. if ((!fieldDef->mIsStatic) || (fieldDef->mIsConst))
  2612. {
  2613. Fail("ThreadStatic attribute can only be used on static fields", fieldDef->mFieldDeclaration->mAttributes);
  2614. }
  2615. }
  2616. }
  2617. }
  2618. if (fieldInstance->mResolvedType != NULL)
  2619. {
  2620. auto resolvedFieldType = fieldInstance->GetResolvedType();
  2621. if ((!typeInstance->IsBoxed()) && (fieldDef != NULL))
  2622. {
  2623. if (fieldInstance->mIsEnumPayloadCase)
  2624. {
  2625. PopulateType(resolvedFieldType, BfPopulateType_Data);
  2626. if (resolvedFieldType->WantsGCMarking())
  2627. typeInstance->mWantsGCMarking = true;
  2628. }
  2629. if ((!fieldDef->mIsConst) && (!fieldDef->mIsStatic))
  2630. {
  2631. PopulateType(resolvedFieldType, resolvedFieldType->IsValueType() ? BfPopulateType_Data : BfPopulateType_Declaration);
  2632. if (resolvedFieldType->WantsGCMarking())
  2633. typeInstance->mWantsGCMarking = true;
  2634. fieldInstance->mMergedDataIdx = typeInstance->mMergedFieldDataCount;
  2635. if (resolvedFieldType->IsStruct())
  2636. {
  2637. auto resolvedFieldTypeInstance = resolvedFieldType->ToTypeInstance();
  2638. typeInstance->mMergedFieldDataCount += resolvedFieldTypeInstance->mMergedFieldDataCount;
  2639. }
  2640. else if (!resolvedFieldType->IsValuelessType())
  2641. typeInstance->mMergedFieldDataCount++;
  2642. if (fieldDef->mIsExtern)
  2643. {
  2644. Fail("Cannot declare instance member as 'extern'", fieldDef->mFieldDeclaration->mExternSpecifier, true);
  2645. }
  2646. BfAstNode* nameRefNode = NULL;
  2647. if (fieldDef->mFieldDeclaration != NULL)
  2648. nameRefNode = fieldDef->mFieldDeclaration->mNameNode;
  2649. if (nameRefNode == NULL)
  2650. nameRefNode = fieldDef->mTypeRef;
  2651. if (!allowInstanceFields)
  2652. {
  2653. if (typeInstance->IsEnum())
  2654. Fail("Cannot declare instance members in an enum", nameRefNode, true);
  2655. else if (typeInstance->IsFunction())
  2656. Fail("Cannot declare instance members in a function", nameRefNode, true);
  2657. else
  2658. Fail("Cannot declare instance members in a typed primitive struct", nameRefNode, true);
  2659. TypeFailed(typeInstance);
  2660. fieldInstance->mDataIdx = -1;
  2661. continue;
  2662. }
  2663. if (typeDef->mIsStatic)
  2664. {
  2665. //CS0708
  2666. Fail("Cannot declare instance members in a static class", nameRefNode, true);
  2667. }
  2668. if (resolvedFieldType->IsValueType())
  2669. {
  2670. BF_ASSERT(!resolvedFieldType->IsDataIncomplete());
  2671. }
  2672. if (!mCompiler->mIsResolveOnly)
  2673. {
  2674. dataMemberHashCtx.MixinStr(fieldDef->mName);
  2675. dataMemberHashCtx.Mixin(resolvedFieldType->mTypeId);
  2676. }
  2677. int dataSize = resolvedFieldType->mSize;
  2678. int alignSize = resolvedFieldType->mAlign;
  2679. fieldInstance->mDataSize = dataSize;
  2680. if (!isUnion)
  2681. {
  2682. if (!resolvedFieldType->IsValuelessType())
  2683. {
  2684. if (isCRepr)
  2685. {
  2686. dataFieldVec.push_back(fieldInstance);
  2687. }
  2688. else
  2689. {
  2690. dataFieldVec.push_back(fieldInstance);
  2691. }
  2692. }
  2693. }
  2694. else
  2695. {
  2696. BF_ASSERT(resolvedFieldType->mSize >= 0);
  2697. if ((alignSize > 1) && (!isPacked))
  2698. dataPos = (dataPos + (alignSize - 1)) & ~(alignSize - 1);
  2699. fieldInstance->mDataOffset = dataPos;
  2700. if (!isPacked)
  2701. typeInstance->mInstAlign = std::max(typeInstance->mInstAlign, alignSize);
  2702. dataPos += dataSize;
  2703. if (dataPos > maxDataPos)
  2704. {
  2705. maxDataPos = dataPos;
  2706. }
  2707. dataPos = startDataPos;
  2708. }
  2709. auto fieldTypeInst = resolvedFieldType->ToTypeInstance();
  2710. if (fieldTypeInst != NULL)
  2711. {
  2712. if ((fieldTypeInst->mRebuildFlags & BfTypeRebuildFlag_UnderlyingTypeDeferred) != 0)
  2713. {
  2714. BfAstNode* refNode = fieldDef->mFieldDeclaration;
  2715. String failStr;
  2716. failStr = StrFormat("Circular data reference detected between '%s' and '%s'", TypeToString(mCurTypeInstance).c_str(), TypeToString(fieldTypeInst).c_str());
  2717. if (!mContext->mFieldResolveReentrys.IsEmpty())
  2718. {
  2719. failStr += StrFormat(" with the following fields:", TypeToString(mCurTypeInstance).c_str());
  2720. for (int i = 0; i < (int)mContext->mFieldResolveReentrys.size(); i++)
  2721. {
  2722. auto checkField = mContext->mFieldResolveReentrys[i];
  2723. if (i > 0)
  2724. failStr += ",";
  2725. failStr += "\n '" + TypeToString(typeInstance) + "." + checkField->GetFieldDef()->mName + "'";
  2726. if (checkField->mOwner == fieldTypeInst)
  2727. refNode = checkField->GetFieldDef()->mFieldDeclaration;
  2728. }
  2729. }
  2730. BfError* err = Fail(failStr, refNode);
  2731. if (err)
  2732. err->mIsPersistent = true;
  2733. }
  2734. }
  2735. }
  2736. bool useForUnion = false;
  2737. if (fieldInstance->mIsEnumPayloadCase)
  2738. {
  2739. if (!typeInstance->IsEnum())
  2740. {
  2741. Fail("Cases can only be used in enum types", fieldDef->mFieldDeclaration);
  2742. }
  2743. else
  2744. {
  2745. BF_ASSERT(typeInstance->mIsUnion);
  2746. }
  2747. }
  2748. if ((!fieldDef->mIsStatic) && (!resolvedFieldType->IsValuelessType()))
  2749. {
  2750. if (isUnion)
  2751. {
  2752. fieldInstance->mDataIdx = curFieldDataIdx;
  2753. }
  2754. }
  2755. }
  2756. if ((!typeInstance->IsSpecializedType()) && (!typeInstance->IsOnDemand()) && (fieldDef != NULL) && (!CheckDefineMemberProtection(fieldDef->mProtection, resolvedFieldType)))
  2757. {
  2758. //CS0052
  2759. Fail(StrFormat("Inconsistent accessibility: field type '%s' is less accessible than field '%s.%s'",
  2760. TypeToString(resolvedFieldType).c_str(), TypeToString(mCurTypeInstance).c_str(), fieldDef->mName.c_str()),
  2761. fieldDef->mTypeRef, true);
  2762. }
  2763. }
  2764. }
  2765. if (typeInstance->mIsUnion)
  2766. {
  2767. SetAndRestoreValue<BfTypeState::ResolveKind> prevResolveKind(typeState.mResolveKind, BfTypeState::ResolveKind_UnionInnerType);
  2768. unionInnerType = typeInstance->GetUnionInnerType();
  2769. }
  2770. if (!isOrdered)
  2771. {
  2772. int dataFieldCount = (int)dataFieldVec.size();
  2773. Array<Deque<BfFieldInstance*>> alignBuckets;
  2774. for (auto fieldInst : dataFieldVec)
  2775. {
  2776. int alignBits = GetHighestBitSet(fieldInst->mResolvedType->mAlign);
  2777. while (alignBits >= alignBuckets.size())
  2778. alignBuckets.Add({});
  2779. alignBuckets[alignBits].Add(fieldInst);
  2780. }
  2781. dataFieldVec.clear();
  2782. int curSize = typeInstance->mInstSize;
  2783. while (dataFieldVec.size() != dataFieldCount)
  2784. {
  2785. // Clear out completed buckets
  2786. while (alignBuckets[alignBuckets.size() - 1].IsEmpty())
  2787. {
  2788. alignBuckets.pop_back();
  2789. }
  2790. int alignBits = GetNumLowZeroBits(curSize) + 1;
  2791. alignBits = BF_MIN(alignBits, (int)alignBuckets.size() - 1);
  2792. bool foundEntry = false;
  2793. while (alignBits >= 0)
  2794. {
  2795. if (alignBuckets[alignBits].IsEmpty())
  2796. {
  2797. alignBits--;
  2798. continue;
  2799. }
  2800. bool isHighestBucket = alignBits == alignBuckets.size() - 1;
  2801. auto fieldInst = alignBuckets[alignBits][0];
  2802. alignBuckets[alignBits].RemoveAt(0);
  2803. dataFieldVec.push_back(fieldInst);
  2804. curSize = BF_ALIGN(curSize, fieldInst->mResolvedType->mAlign);
  2805. curSize += fieldInst->mResolvedType->mSize;
  2806. foundEntry = true;
  2807. if (!isHighestBucket)
  2808. {
  2809. // We may have a larger type that can fit now...
  2810. break;
  2811. }
  2812. }
  2813. if (!foundEntry)
  2814. {
  2815. // If no entries will fit, then force an entry of the smallest alignment
  2816. for (int alignBits = 0; alignBits < alignBuckets.size(); alignBits++)
  2817. {
  2818. if (!alignBuckets[alignBits].IsEmpty())
  2819. {
  2820. auto fieldInst = alignBuckets[alignBits][0];
  2821. alignBuckets[alignBits].RemoveAt(0);
  2822. dataFieldVec.push_back(fieldInst);
  2823. curSize = BF_ALIGN(curSize, fieldInst->mResolvedType->mAlign);
  2824. curSize += fieldInst->mResolvedType->mSize;
  2825. break;
  2826. }
  2827. }
  2828. }
  2829. }
  2830. }
  2831. //bool needsExplicitAlignment = !isCRepr || ((typeInstance->mBaseType != NULL) && (!typeInstance->mBaseType->mIsCRepr));
  2832. bool needsExplicitAlignment = true;
  2833. for (int fieldIdx = 0; fieldIdx < (int)dataFieldVec.size(); fieldIdx++)
  2834. {
  2835. auto fieldInstance = dataFieldVec[fieldIdx];
  2836. auto resolvedFieldType = fieldInstance->GetResolvedType();
  2837. BF_ASSERT(resolvedFieldType->mSize >= 0);
  2838. int dataSize = resolvedFieldType->mSize;
  2839. int alignSize = resolvedFieldType->mAlign;
  2840. fieldInstance->mDataSize = dataSize;
  2841. //bool needsExplicitAlignment = !isCRepr || resolvedFieldType->NeedsExplicitAlignment();
  2842. int nextDataPos = dataPos;
  2843. if (!isPacked)
  2844. nextDataPos = (dataPos + (alignSize - 1)) & ~(alignSize - 1);
  2845. int padding = nextDataPos - dataPos;
  2846. if ((alignSize > 1) && (needsExplicitAlignment) && (padding > 0))
  2847. {
  2848. curFieldDataIdx++;
  2849. }
  2850. dataPos = nextDataPos;
  2851. fieldInstance->mDataOffset = dataPos;
  2852. fieldInstance->mDataIdx = curFieldDataIdx++;
  2853. if (!isPacked)
  2854. typeInstance->mInstAlign = std::max(typeInstance->mInstAlign, alignSize);
  2855. dataPos += dataSize;
  2856. }
  2857. if (unionInnerType != NULL)
  2858. {
  2859. dataPos = unionInnerType->mSize;
  2860. typeInstance->mInstAlign = BF_MAX(unionInnerType->mAlign, typeInstance->mInstAlign);
  2861. }
  2862. // Old dataMemberHash location
  2863. CheckMemberNames(typeInstance);
  2864. if (isPacked)
  2865. typeInstance->mInstAlign = 1;
  2866. else
  2867. typeInstance->mInstAlign = std::max(1, typeInstance->mInstAlign);
  2868. int alignSize = typeInstance->mInstAlign;
  2869. if (isCRepr)
  2870. {
  2871. // Align size to alignment
  2872. if (alignSize >= 1)
  2873. typeInstance->mInstSize = (dataPos + (alignSize - 1)) & ~(alignSize - 1);
  2874. typeInstance->mIsCRepr = true;
  2875. }
  2876. else
  2877. {
  2878. typeInstance->mInstSize = dataPos;
  2879. typeInstance->mIsCRepr = false;
  2880. }
  2881. if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL))
  2882. {
  2883. for (auto propDef : typeInstance->mTypeDef->mProperties)
  2884. if (propDef->mFieldDeclaration != NULL)
  2885. mCompiler->mResolvePassData->mAutoComplete->CheckProperty(BfNodeDynCast<BfPropertyDeclaration>(propDef->mFieldDeclaration));
  2886. }
  2887. }
  2888. if (typeInstance->IsObjectOrInterface())
  2889. typeInstance->mWantsGCMarking = true;
  2890. if ((mCompiler->mOptions.mEnableRealtimeLeakCheck) && (!typeInstance->mWantsGCMarking))
  2891. {
  2892. typeInstance->mTypeDef->PopulateMemberSets();
  2893. BfMemberSetEntry* entry = NULL;
  2894. BfMethodDef* methodDef = NULL;
  2895. if (typeInstance->mTypeDef->mMethodSet.TryGetWith(String(BF_METHODNAME_MARKMEMBERS), &entry))
  2896. {
  2897. methodDef = (BfMethodDef*)entry->mMemberDef;
  2898. if (methodDef->HasBody())
  2899. typeInstance->mWantsGCMarking = true;
  2900. }
  2901. }
  2902. if (typeInstance->IsValueType())
  2903. {
  2904. typeInstance->mSize = typeInstance->mInstSize;
  2905. typeInstance->mAlign = typeInstance->mInstAlign;
  2906. }
  2907. if ((mCompiler->mOptions.mAllowHotSwapping) && (typeInstance->mDefineState < BfTypeDefineState_Defined))
  2908. {
  2909. if (typeInstance->mHotTypeData == NULL)
  2910. {
  2911. typeInstance->mHotTypeData = new BfHotTypeData();
  2912. BfLogSysM("Created HotTypeData %p created for type %p in DoPopulateType\n", typeInstance->mHotTypeData, typeInstance);
  2913. }
  2914. // Clear any unused versions (if we have errors, etc)
  2915. if (mCompiler->mHotState != NULL)
  2916. typeInstance->mHotTypeData->ClearVersionsAfter(mCompiler->mHotState->mCommittedHotCompileIdx);
  2917. else
  2918. BF_ASSERT(typeInstance->mHotTypeData->mTypeVersions.IsEmpty()); // We should have created a new HotTypeData when rebuilding the type
  2919. BfHotTypeVersion* hotTypeVersion = new BfHotTypeVersion();
  2920. hotTypeVersion->mTypeId = typeInstance->mTypeId;
  2921. if (typeInstance->mBaseType != NULL)
  2922. {
  2923. if (typeInstance->mBaseType->mHotTypeData != NULL)
  2924. hotTypeVersion->mBaseType = typeInstance->mBaseType->mHotTypeData->GetLatestVersion();
  2925. else
  2926. {
  2927. AssertErrorState();
  2928. }
  2929. }
  2930. hotTypeVersion->mDeclHotCompileIdx = mCompiler->mOptions.mHotCompileIdx;
  2931. if (mCompiler->IsHotCompile())
  2932. hotTypeVersion->mCommittedHotCompileIdx = -1;
  2933. else
  2934. hotTypeVersion->mCommittedHotCompileIdx = 0;
  2935. hotTypeVersion->mRefCount++;
  2936. typeInstance->mHotTypeData->mTypeVersions.Add(hotTypeVersion);
  2937. if ((typeInstance->mBaseType != NULL) && (typeInstance->mBaseType->mHotTypeData != NULL))
  2938. {
  2939. hotTypeVersion->mMembers.Add(typeInstance->mBaseType->mHotTypeData->GetLatestVersion());
  2940. }
  2941. for (auto& fieldInst : typeInstance->mFieldInstances)
  2942. {
  2943. auto fieldDef = fieldInst.GetFieldDef();
  2944. if ((fieldDef == NULL) || (fieldDef->mIsStatic))
  2945. continue;
  2946. auto depType = fieldInst.mResolvedType;
  2947. while (depType->IsSizedArray())
  2948. depType = ((BfSizedArrayType*)depType)->mElementType;
  2949. if (depType->IsStruct())
  2950. {
  2951. PopulateType(depType);
  2952. auto depTypeInst = depType->ToTypeInstance();
  2953. BF_ASSERT(depTypeInst->mHotTypeData != NULL);
  2954. if (depTypeInst->mHotTypeData != NULL)
  2955. hotTypeVersion->mMembers.Add(depTypeInst->mHotTypeData->GetLatestVersion());
  2956. }
  2957. }
  2958. for (auto member : hotTypeVersion->mMembers)
  2959. member->mRefCount++;
  2960. BfLogSysM("BfHotTypeVersion %p created for type %p\n", hotTypeVersion, typeInstance);
  2961. }
  2962. typeInstance->mDefineState = BfTypeDefineState_Defined;
  2963. if (typeInstance->mTypeFailed)
  2964. mHadBuildError = true;
  2965. CheckAddFailType();
  2966. BfLogSysM("Setting mNeedsMethodProcessing on %p\n", typeInstance);
  2967. typeInstance->mNeedsMethodProcessing = true;
  2968. typeInstance->mIsFinishingType = false;
  2969. ///
  2970. // 'Splattable' means that we can be passed via 3 or fewer primitive/pointer values
  2971. if (typeInstance->mHasUnderlyingArray)
  2972. {
  2973. // Never splat
  2974. }
  2975. else if (typeInstance->IsStruct())
  2976. {
  2977. bool hadNonSplattable = false;
  2978. if (typeInstance->mBaseType != NULL)
  2979. PopulateType(typeInstance->mBaseType, BfPopulateType_Data);
  2980. if ((typeInstance->mBaseType == NULL) || (typeInstance->mBaseType->IsSplattable()))
  2981. {
  2982. int dataCount = 0;
  2983. std::function<void(BfType*)> splatIterate;
  2984. splatIterate = [&](BfType* checkType)
  2985. {
  2986. if (checkType->IsValueType())
  2987. PopulateType(checkType, BfPopulateType_Data);
  2988. if (checkType->IsMethodRef())
  2989. {
  2990. // For simplicity, any methodRef inside a struct makes the struct non-splattable. This reduces cases of needing to
  2991. // handle embedded methodRefs
  2992. hadNonSplattable = true;
  2993. }
  2994. else if (checkType->IsStruct())
  2995. {
  2996. auto checkTypeInstance = checkType->ToTypeInstance();
  2997. if (checkTypeInstance->mBaseType != NULL)
  2998. splatIterate(checkTypeInstance->mBaseType);
  2999. if (checkTypeInstance->mIsUnion)
  3000. {
  3001. bool wantSplat = false;
  3002. auto unionInnerType = checkTypeInstance->GetUnionInnerType(&wantSplat);
  3003. if (!wantSplat)
  3004. hadNonSplattable = true;
  3005. splatIterate(unionInnerType);
  3006. if (checkTypeInstance->IsEnum())
  3007. dataCount++; // Discriminator
  3008. }
  3009. else
  3010. {
  3011. for (int fieldIdx = 0; fieldIdx < (int)checkTypeInstance->mFieldInstances.size(); fieldIdx++)
  3012. {
  3013. auto fieldInstance = (BfFieldInstance*)&checkTypeInstance->mFieldInstances[fieldIdx];
  3014. if (fieldInstance->mDataIdx >= 0)
  3015. splatIterate(fieldInstance->GetResolvedType());
  3016. }
  3017. }
  3018. }
  3019. else if (!checkType->IsValuelessType())
  3020. {
  3021. if (checkType->IsSizedArray())
  3022. hadNonSplattable = true;
  3023. dataCount += checkType->GetSplatCount();
  3024. }
  3025. };
  3026. splatIterate(typeInstance);
  3027. if (isCRepr)
  3028. {
  3029. typeInstance->mIsSplattable = false;
  3030. }
  3031. else
  3032. typeInstance->mIsSplattable = (dataCount <= 3) && (!hadNonSplattable);
  3033. }
  3034. }
  3035. if (typeInstance->IsTypedPrimitive())
  3036. typeInstance->mIsSplattable = true;
  3037. BF_ASSERT(mContext->mCurTypeState == &typeState);
  3038. // This is only required for autocomplete and finding type references
  3039. if (!typeInstance->IsSpecializedType())
  3040. {
  3041. for (auto propDef : typeDef->mProperties)
  3042. {
  3043. if (propDef->mTypeRef == NULL)
  3044. continue;
  3045. BfTypeState typeState;
  3046. typeState.mPrevState = mContext->mCurTypeState;
  3047. typeState.mCurTypeDef = propDef->mDeclaringType;
  3048. typeState.mTypeInstance = typeInstance;
  3049. SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
  3050. ResolveTypeRef(propDef->mTypeRef, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowRef);
  3051. }
  3052. }
  3053. ///
  3054. {
  3055. Dictionary<int64, BfFieldDef*> valueMap;
  3056. for (auto& fieldInstanceRef : typeInstance->mFieldInstances)
  3057. {
  3058. auto fieldInstance = &fieldInstanceRef;
  3059. if (!fieldInstance->mFieldIncluded)
  3060. continue;
  3061. auto fieldDef = fieldInstance->GetFieldDef();
  3062. if (fieldDef == NULL)
  3063. continue;
  3064. if ((fieldInstance->mConstIdx == -1) && (fieldDef->mIsConst))
  3065. {
  3066. SetAndRestoreValue<BfFieldDef*> prevTypeRef(mContext->mCurTypeState->mCurFieldDef, fieldDef);
  3067. typeInstance->mModule->ResolveConstField(typeInstance, fieldInstance, fieldDef);
  3068. auto underlyingType = fieldInstance->mResolvedType->GetUnderlyingType();
  3069. if ((fieldDef->IsEnumCaseEntry()) && (fieldInstance->mConstIdx != -1) && (underlyingType->IsIntegral()))
  3070. {
  3071. auto foreignConst = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
  3072. BfFieldDef** fieldDefPtr;
  3073. if (valueMap.TryAdd(foreignConst->mInt64, NULL, &fieldDefPtr))
  3074. {
  3075. *fieldDefPtr = fieldDef;
  3076. }
  3077. else if ((typeInstance->mCustomAttributes == NULL) || (typeInstance->mCustomAttributes->Get(mCompiler->mAllowDuplicatesAttributeTypeDef) == NULL))
  3078. {
  3079. auto error = Warn(0, StrFormat("Enum value '%lld' for field '%s' is not unique. Considering adding [AllowDuplicates] to the type declaration.", foreignConst->mInt64, fieldDef->mName.c_str()), fieldDef->GetRefNode(), true);
  3080. if (error != NULL)
  3081. mCompiler->mPassInstance->MoreInfo(StrFormat("This value was previously used for field '%s'", (*fieldDefPtr)->mName.c_str()), (*fieldDefPtr)->GetRefNode());
  3082. }
  3083. }
  3084. }
  3085. }
  3086. }
  3087. if ((typeInstance->IsEnum()) && (!typeInstance->IsPayloadEnum()))
  3088. {
  3089. BfLogSysM("Setting underlying type %p %d\n", typeInstance, underlyingTypeDeferred);
  3090. }
  3091. if (typeInstance->IsEnum())
  3092. {
  3093. int64 min = 0;
  3094. int64 max = 0;
  3095. bool isFirst = false;
  3096. if (typeInstance->mTypeInfoEx == NULL)
  3097. typeInstance->mTypeInfoEx = new BfTypeInfoEx();
  3098. for (auto& fieldInstanceRef : typeInstance->mFieldInstances)
  3099. {
  3100. auto fieldInstance = &fieldInstanceRef;
  3101. auto fieldDef = fieldInstance->GetFieldDef();
  3102. if ((fieldDef != NULL) && (fieldDef->IsEnumCaseEntry()))
  3103. {
  3104. if (fieldInstance->mConstIdx == -1)
  3105. continue;
  3106. auto constant = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
  3107. BF_ASSERT((constant->mTypeCode == BfTypeCode_Int64) || (!underlyingTypeDeferred));
  3108. if (isFirst)
  3109. {
  3110. min = constant->mInt64;
  3111. max = constant->mInt64;
  3112. isFirst = false;
  3113. }
  3114. else
  3115. {
  3116. min = BF_MIN(constant->mInt64, min);
  3117. max = BF_MAX(constant->mInt64, max);
  3118. }
  3119. }
  3120. }
  3121. typeInstance->mTypeInfoEx->mMinValue = min;
  3122. typeInstance->mTypeInfoEx->mMaxValue = max;
  3123. if (underlyingTypeDeferred)
  3124. {
  3125. BfTypeCode typeCode;
  3126. if ((min >= -0x80) && (max <= 0x7F))
  3127. typeCode = BfTypeCode_Int8;
  3128. else if ((min >= 0) && (max <= 0xFF))
  3129. typeCode = BfTypeCode_UInt8;
  3130. else if ((min >= -0x8000) && (max <= 0x7FFF))
  3131. typeCode = BfTypeCode_Int16;
  3132. else if ((min >= 0) && (max <= 0xFFFF))
  3133. typeCode = BfTypeCode_UInt16;
  3134. else if ((min >= -0x80000000LL) && (max <= 0x7FFFFFFF))
  3135. typeCode = BfTypeCode_Int32;
  3136. else if ((min >= 0) && (max <= 0xFFFFFFFFLL))
  3137. typeCode = BfTypeCode_UInt32;
  3138. else
  3139. typeCode = BfTypeCode_Int64;
  3140. if (typeCode != BfTypeCode_Int64)
  3141. {
  3142. for (auto& fieldInstanceRef : typeInstance->mFieldInstances)
  3143. {
  3144. auto fieldInstance = &fieldInstanceRef;
  3145. if (fieldInstance->mConstIdx != -1)
  3146. {
  3147. auto constant = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
  3148. BfIRValue newConstant = typeInstance->mConstHolder->CreateConst(typeCode, constant->mUInt64);
  3149. fieldInstance->mConstIdx = newConstant.mId;
  3150. }
  3151. }
  3152. }
  3153. underlyingType = GetPrimitiveType(typeCode);
  3154. auto fieldInstance = &typeInstance->mFieldInstances.back();
  3155. fieldInstance->mResolvedType = underlyingType;
  3156. fieldInstance->mDataSize = underlyingType->mSize;
  3157. typeInstance->mTypeInfoEx->mUnderlyingType = underlyingType;
  3158. typeInstance->mSize = underlyingType->mSize;
  3159. typeInstance->mAlign = underlyingType->mAlign;
  3160. typeInstance->mInstSize = underlyingType->mSize;
  3161. typeInstance->mInstAlign = underlyingType->mAlign;
  3162. typeInstance->mRebuildFlags = (BfTypeRebuildFlags)(typeInstance->mRebuildFlags & ~BfTypeRebuildFlag_UnderlyingTypeDeferred);
  3163. }
  3164. }
  3165. else
  3166. {
  3167. BF_ASSERT(!underlyingTypeDeferred);
  3168. }
  3169. if ((typeInstance->IsPayloadEnum()) && (!typeInstance->IsBoxed()))
  3170. {
  3171. int lastTagId = -1;
  3172. for (auto& fieldInstanceRef : typeInstance->mFieldInstances)
  3173. {
  3174. auto fieldInstance = &fieldInstanceRef;
  3175. auto fieldDef = fieldInstance->GetFieldDef();
  3176. if ((fieldDef != NULL) && (fieldInstance->mDataIdx < 0))
  3177. lastTagId = -fieldInstance->mDataIdx - 1;
  3178. }
  3179. auto fieldInstance = &typeInstance->mFieldInstances.back();
  3180. BF_ASSERT(fieldInstance->mResolvedType == NULL);
  3181. BfPrimitiveType* discriminatorType;
  3182. if (lastTagId > 0x7FFFFFFF) // HOW?
  3183. discriminatorType = GetPrimitiveType(BfTypeCode_Int64);
  3184. else if (lastTagId > 0x7FFF)
  3185. discriminatorType = GetPrimitiveType(BfTypeCode_Int32);
  3186. else if (lastTagId > 0x7F)
  3187. discriminatorType = GetPrimitiveType(BfTypeCode_Int16);
  3188. else
  3189. discriminatorType = GetPrimitiveType(BfTypeCode_Int8);
  3190. fieldInstance->mResolvedType = discriminatorType;
  3191. fieldInstance->mDataOffset = unionInnerType->mSize;
  3192. fieldInstance->mDataIdx = 2; // 0 = base, 1 = payload, 2 = discriminator
  3193. if (!isPacked)
  3194. {
  3195. if ((fieldInstance->mDataOffset % discriminatorType->mAlign) != 0)
  3196. {
  3197. fieldInstance->mDataOffset = BF_ALIGN(fieldInstance->mDataOffset, discriminatorType->mAlign);
  3198. fieldInstance->mDataIdx++; // Add room for explicit padding
  3199. }
  3200. }
  3201. typeInstance->mAlign = BF_MAX(unionInnerType->mAlign, discriminatorType->mAlign);
  3202. typeInstance->mSize = fieldInstance->mDataOffset + discriminatorType->mSize;
  3203. typeInstance->mInstSize = typeInstance->mSize;
  3204. typeInstance->mInstAlign = typeInstance->mAlign;
  3205. dataMemberHashCtx.Mixin(unionInnerType->mTypeId);
  3206. dataMemberHashCtx.Mixin(discriminatorType->mTypeId);
  3207. typeInstance->mMergedFieldDataCount = 1; // Track it as a single entry
  3208. }
  3209. if (!typeInstance->IsBoxed())
  3210. {
  3211. if (typeInstance->IsTypedPrimitive())
  3212. {
  3213. auto underlyingType = typeInstance->GetUnderlyingType();
  3214. dataMemberHashCtx.Mixin(underlyingType->mTypeId);
  3215. }
  3216. Val128 dataMemberHash = dataMemberHashCtx.Finish128();
  3217. if (typeInstance->mHotTypeData != NULL)
  3218. {
  3219. auto newHotTypeVersion = typeInstance->mHotTypeData->GetLatestVersion();
  3220. newHotTypeVersion->mDataHash = dataMemberHash;
  3221. if (mCompiler->mHotState != NULL)
  3222. {
  3223. auto committedHotTypeVersion = typeInstance->mHotTypeData->GetTypeVersion(mCompiler->mHotState->mCommittedHotCompileIdx);
  3224. if (committedHotTypeVersion != NULL)
  3225. {
  3226. if ((newHotTypeVersion->mDataHash != committedHotTypeVersion->mDataHash) && (typeInstance->mIsReified))
  3227. {
  3228. BfLogSysM("Hot compile detected data changes in %p '%s'\n", resolvedTypeRef, TypeToString(typeInstance).c_str());
  3229. if (!typeInstance->mHotTypeData->mPendingDataChange)
  3230. {
  3231. mCompiler->mHotState->mPendingDataChanges.Add(typeInstance->mTypeId);
  3232. typeInstance->mHotTypeData->mPendingDataChange = true;
  3233. }
  3234. else
  3235. {
  3236. BF_ASSERT(mCompiler->mHotState->mPendingDataChanges.Contains(typeInstance->mTypeId));
  3237. }
  3238. bool baseHadChanges = (typeInstance->mBaseType != NULL) && (typeInstance->mBaseType->mHotTypeData != NULL) && (typeInstance->mBaseType->mHotTypeData->mPendingDataChange);
  3239. if (!baseHadChanges)
  3240. Warn(0, StrFormat("Hot compile detected data changes in '%s'", TypeToString(typeInstance).c_str()), typeDef->GetRefNode());
  3241. }
  3242. else if (typeInstance->mHotTypeData->mPendingDataChange)
  3243. {
  3244. BfLogSysM("Hot compile removed pending data change for %p '%s'\n", resolvedTypeRef, TypeToString(typeInstance).c_str());
  3245. mCompiler->mHotState->RemovePendingChanges(typeInstance);
  3246. }
  3247. }
  3248. }
  3249. }
  3250. }
  3251. if (typeInstance == mContext->mBfObjectType)
  3252. typeInstance->mHasBeenInstantiated = true;
  3253. if (populateType == BfPopulateType_Data)
  3254. return;
  3255. disableYield.Release();
  3256. prevTypeState.Restore();
  3257. if (canDoMethodProcessing)
  3258. {
  3259. if (typeInstance->mNeedsMethodProcessing) // May have been handled by GetRawMethodInstanceAtIdx above
  3260. DoTypeInstanceMethodProcessing(typeInstance);
  3261. }
  3262. }
  3263. void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
  3264. {
  3265. if (typeInstance->IsSpecializedByAutoCompleteMethod())
  3266. return;
  3267. BF_ASSERT(typeInstance->mModule == this);
  3268. //TODO: This is new, make sure this is in the right place
  3269. /*if (mAwaitingInitFinish)
  3270. FinishInit();*/
  3271. AutoDisallowYield disableYield(mSystem);
  3272. SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, typeInstance);
  3273. SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, NULL);
  3274. BfLogSysM("DoTypeInstanceMethodProcessing: %p %s Revision:%d\n", typeInstance, TypeToString(typeInstance).c_str(), typeInstance->mRevision);
  3275. auto typeDef = typeInstance->mTypeDef;
  3276. BfTypeOptions* typeOptions = NULL;
  3277. if (typeInstance->mTypeOptionsIdx >= 0)
  3278. typeOptions = mSystem->GetTypeOptions(typeInstance->mTypeOptionsIdx);
  3279. // Generate all methods. Pass 0
  3280. for (auto methodDef : typeDef->mMethods)
  3281. {
  3282. auto methodInstanceGroup = &typeInstance->mMethodInstanceGroups[methodDef->mIdx];
  3283. // This should still be set to the default value
  3284. BF_ASSERT((methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet) || (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude));
  3285. }
  3286. if (typeInstance == mContext->mBfObjectType)
  3287. {
  3288. BF_ASSERT(typeInstance->mInterfaceMethodTable.size() == 0);
  3289. }
  3290. int newIntefaceStartIdx = 0;
  3291. auto implBaseType = typeInstance->GetImplBaseType();
  3292. if (implBaseType != NULL)
  3293. {
  3294. auto baseTypeInst = implBaseType->ToTypeInstance();
  3295. if (implBaseType->IsIncomplete())
  3296. PopulateType(implBaseType, BfPopulateType_Full_Force);
  3297. typeInstance->mInterfaceMethodTable = baseTypeInst->mInterfaceMethodTable;
  3298. typeInstance->mVirtualMethodTable = implBaseType->mVirtualMethodTable;
  3299. typeInstance->mVirtualMethodTableSize = implBaseType->mVirtualMethodTableSize;
  3300. if ((!mCompiler->IsHotCompile()) && (!mCompiler->mPassInstance->HasFailed()) && ((mCompiler->mResolvePassData == NULL) || (mCompiler->mResolvePassData->mAutoComplete == NULL)))
  3301. {
  3302. BF_ASSERT(typeInstance->mVirtualMethodTable.size() == typeInstance->mVirtualMethodTableSize);
  3303. }
  3304. else
  3305. {
  3306. BF_ASSERT(typeInstance->mVirtualMethodTableSize >= (int)typeInstance->mVirtualMethodTable.size());
  3307. }
  3308. }
  3309. // Add new interfaces
  3310. for (int iFaceIdx = 0; iFaceIdx < (int)typeInstance->mInterfaces.size(); iFaceIdx++)
  3311. {
  3312. BfTypeInterfaceEntry& typeInterfaceInst = typeInstance->mInterfaces[iFaceIdx];
  3313. auto checkInterface = typeInterfaceInst.mInterfaceType;
  3314. if (checkInterface->IsIncomplete())
  3315. PopulateType(checkInterface, BfPopulateType_Full_Force);
  3316. typeInterfaceInst.mStartInterfaceTableIdx = (int)typeInstance->mInterfaceMethodTable.size();
  3317. // We don't add to the vtable for interface declarations, we just reference the listed interfaces
  3318. if (!typeInstance->IsInterface())
  3319. {
  3320. auto interfaceTypeDef = checkInterface->mTypeDef;
  3321. BF_ASSERT(interfaceTypeDef->mMethods.size() == checkInterface->mMethodInstanceGroups.size());
  3322. // Reserve empty entries
  3323. for (int methodIdx = 0; methodIdx < (int)interfaceTypeDef->mMethods.size(); methodIdx++)
  3324. typeInstance->mInterfaceMethodTable.push_back(BfTypeInterfaceMethodEntry());
  3325. }
  3326. }
  3327. auto checkTypeInstance = typeInstance;
  3328. while (checkTypeInstance != NULL)
  3329. {
  3330. // These may have been already added
  3331. for (auto&& interfaceEntry : checkTypeInstance->mInterfaces)
  3332. AddDependency(interfaceEntry.mInterfaceType, typeInstance, BfDependencyMap::DependencyFlag_ImplementsInterface);
  3333. checkTypeInstance = checkTypeInstance->GetImplBaseType();
  3334. }
  3335. //for (auto& intefaceInst : typeInstance->mInterfaces)
  3336. if (typeInstance == mContext->mBfObjectType)
  3337. {
  3338. BF_ASSERT(typeInstance->mInterfaceMethodTable.size() == 1);
  3339. }
  3340. // Slot interfaces method blocks in vtable
  3341. {
  3342. int ifaceVirtIdx = 0;
  3343. std::unordered_map<BfTypeInstance*, BfTypeInterfaceEntry*> interfaceMap;
  3344. BfTypeInstance* checkType = typeInstance->GetImplBaseType();
  3345. while (checkType != NULL)
  3346. {
  3347. for (auto&& ifaceEntry : checkType->mInterfaces)
  3348. {
  3349. interfaceMap[ifaceEntry.mInterfaceType] = &ifaceEntry;
  3350. ifaceVirtIdx = std::max(ifaceVirtIdx, ifaceEntry.mStartVirtualIdx + ifaceEntry.mInterfaceType->mVirtualMethodTableSize);
  3351. }
  3352. checkType = checkType->GetImplBaseType();
  3353. }
  3354. for (int iFaceIdx = 0; iFaceIdx < (int)typeInstance->mInterfaces.size(); iFaceIdx++)
  3355. {
  3356. BfTypeInterfaceEntry& typeInterfaceInst = typeInstance->mInterfaces[iFaceIdx];
  3357. auto itr = interfaceMap.find(typeInterfaceInst.mInterfaceType);
  3358. if (itr != interfaceMap.end())
  3359. {
  3360. auto prevEntry = itr->second;
  3361. typeInterfaceInst.mStartVirtualIdx = prevEntry->mStartVirtualIdx;
  3362. }
  3363. else
  3364. {
  3365. typeInterfaceInst.mStartVirtualIdx = ifaceVirtIdx;
  3366. ifaceVirtIdx += typeInterfaceInst.mInterfaceType->mVirtualMethodTableSize;
  3367. interfaceMap[typeInterfaceInst.mInterfaceType] = &typeInterfaceInst;
  3368. }
  3369. }
  3370. }
  3371. auto isBoxed = typeInstance->IsBoxed();
  3372. BfLogSysM("Setting mTypeIncomplete = false on %p\n", typeInstance);
  3373. typeInstance->mNeedsMethodProcessing = false;
  3374. typeInstance->mTypeIncomplete = false;
  3375. auto checkBaseType = typeInstance->GetImplBaseType();
  3376. while (checkBaseType != NULL)
  3377. {
  3378. PopulateType(checkBaseType, BfPopulateType_Full_Force);
  3379. BF_ASSERT((!checkBaseType->IsIncomplete()) || (checkBaseType->mTypeFailed));
  3380. checkBaseType = checkBaseType->GetImplBaseType();
  3381. }
  3382. if ((mCompiler->mOptions.mHasVDataExtender) && (!typeInstance->IsInterface()))
  3383. {
  3384. // This is the vExt entry for this type instance
  3385. BfVirtualMethodEntry entry;
  3386. entry.mDeclaringMethod.mMethodNum = -1;
  3387. entry.mDeclaringMethod.mTypeInstance = typeInstance;
  3388. typeInstance->mVirtualMethodTable.push_back(entry);
  3389. typeInstance->mVirtualMethodTableSize++;
  3390. }
  3391. // Fill out to correct size
  3392. if (typeInstance->mHotTypeData != NULL)
  3393. {
  3394. //auto hotLatestVersionHead = typeInstance->mHotTypeData->GetLatestVersionHead();
  3395. int wantVTableSize = typeInstance->GetImplBaseVTableSize() + (int)typeInstance->mHotTypeData->mVTableEntries.size();
  3396. while ((int)typeInstance->mVirtualMethodTable.size() < wantVTableSize)
  3397. {
  3398. typeInstance->mVirtualMethodTable.push_back(BfVirtualMethodEntry());
  3399. typeInstance->mVirtualMethodTableSize++;
  3400. }
  3401. }
  3402. BfAmbiguityContext ambiguityContext;
  3403. ambiguityContext.mTypeInstance = typeInstance;
  3404. ambiguityContext.mModule = this;
  3405. ambiguityContext.mIsProjectSpecific = false;
  3406. bool wantsOnDemandMethods = false;
  3407. //TODO: Testing having interface methods be "on demand"...
  3408. //if (!typeInstance->IsInterface())
  3409. //
  3410. {
  3411. if (typeInstance->IsSpecializedType())
  3412. wantsOnDemandMethods = true;
  3413. else if ((mCompiler->mOptions.mCompileOnDemandKind != BfCompileOnDemandKind_AlwaysInclude) &&
  3414. (!typeInstance->IsUnspecializedTypeVariation()))
  3415. {
  3416. //if (typeDef->mName->ToString() != "AttributeUsageAttribute")
  3417. auto attributeDef = mCompiler->mAttributeTypeDef;
  3418. auto attributeType = mContext->mUnreifiedModule->ResolveTypeDef(attributeDef, BfPopulateType_Identity)->ToTypeInstance();
  3419. if (!TypeIsSubTypeOf(mCurTypeInstance, attributeType, false))
  3420. {
  3421. wantsOnDemandMethods = true;
  3422. }
  3423. }
  3424. }
  3425. //bool allDeclsRequired = (mIsReified) && (mCompiler->mOptions.mEmitDebugInfo) && ();
  3426. bool allDeclsRequired = false;
  3427. //if ((mIsReified) && (mCompiler->mOptions.mEmitDebugInfo) && (!mCompiler->mWantsDeferMethodDecls))
  3428. // if ((mIsReified) && (mCompiler->mOptions.mEmitDebugInfo))
  3429. // {
  3430. // allDeclsRequired = true;
  3431. // }
  3432. HashSet<String> ifaceMethodNameSet;
  3433. if (wantsOnDemandMethods)
  3434. {
  3435. for (int iFaceIdx = newIntefaceStartIdx; iFaceIdx < (int)typeInstance->mInterfaces.size(); iFaceIdx++)
  3436. {
  3437. BfTypeInterfaceEntry& typeInterfaceInst = typeInstance->mInterfaces[iFaceIdx];
  3438. for (auto checkMethodDef : typeInterfaceInst.mInterfaceType->mTypeDef->mMethods)
  3439. {
  3440. ifaceMethodNameSet.Add(checkMethodDef->mName);
  3441. }
  3442. }
  3443. }
  3444. bool isFailedType = mCurTypeInstance->mTypeFailed;
  3445. if (auto genericTypeInst = mCurTypeInstance->ToGenericTypeInstance())
  3446. {
  3447. if (genericTypeInst->mGenericTypeInfo->mHadValidateErrors)
  3448. isFailedType = true;
  3449. }
  3450. bool typeOptionsIncludeAll = false;
  3451. if (typeOptions != NULL)
  3452. typeOptionsIncludeAll = typeOptions->Apply(typeOptionsIncludeAll, BfOptionFlags_ReflectAlwaysIncludeAll);
  3453. // Generate all methods. Pass 1
  3454. for (auto methodDef : typeDef->mMethods)
  3455. {
  3456. auto methodInstanceGroup = &typeInstance->mMethodInstanceGroups[methodDef->mIdx];
  3457. if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude)
  3458. continue;
  3459. if (isFailedType)
  3460. {
  3461. // We don't want method decls from failed generic types to clog up our type system
  3462. continue;
  3463. }
  3464. // This should still be set to the default value
  3465. BF_ASSERT(methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet);
  3466. if ((isBoxed) && (!methodDef->mIsVirtual))
  3467. {
  3468. if (methodDef->mIsStatic)
  3469. continue;
  3470. bool boxedRequired = false;
  3471. if (((methodDef->mMethodType == BfMethodType_Ctor) && (methodDef->mParams.size() == 0)) ||
  3472. (methodDef->mMethodType == BfMethodType_Dtor) ||
  3473. ((methodDef->mName == BF_METHODNAME_MARKMEMBERS) || (methodDef->mName == BF_METHODNAME_MARKMEMBERS_STATIC) || (methodDef->mName == BF_METHODNAME_INVOKE) || (methodDef->mName == BF_METHODNAME_DYNAMICCAST)) ||
  3474. (methodDef->mGenericParams.size() != 0))
  3475. boxedRequired = true;
  3476. if (!boxedRequired)
  3477. {
  3478. if (wantsOnDemandMethods)
  3479. methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_NoDecl_AwaitingReference;
  3480. continue;
  3481. }
  3482. }
  3483. if (methodDef->mMethodType == BfMethodType_Ignore)
  3484. continue;
  3485. if ((methodDef->mName == BF_METHODNAME_DYNAMICCAST) && (typeInstance->IsValueType()))
  3486. continue; // This is just a placeholder for boxed types
  3487. methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_AlwaysInclude;
  3488. if (wantsOnDemandMethods)
  3489. {
  3490. bool implRequired = false;
  3491. bool declRequired = false;
  3492. if ((!typeInstance->IsGenericTypeInstance()) && (methodDef->mGenericParams.IsEmpty()))
  3493. {
  3494. // For non-generic methods, declare all methods. This is useful for debug info.
  3495. declRequired = true;
  3496. }
  3497. if (methodDef->mMethodType == BfMethodType_CtorNoBody)
  3498. declRequired = true;
  3499. if ((methodDef->mIsStatic) &&
  3500. ((methodDef->mMethodType == BfMethodType_Dtor) || (methodDef->mMethodType == BfMethodType_Ctor)))
  3501. {
  3502. implRequired = true;
  3503. }
  3504. if (mCompiler->mOptions.mEnableRealtimeLeakCheck)
  3505. {
  3506. if ((methodDef->mName == BF_METHODNAME_MARKMEMBERS_STATIC) ||
  3507. (methodDef->mName == BF_METHODNAME_FIND_TLS_MEMBERS) ||
  3508. ((methodDef->mName == BF_METHODNAME_MARKMEMBERS) && (typeInstance->IsObject())))
  3509. implRequired = true;
  3510. }
  3511. BfAttributeDirective* attributes = NULL;
  3512. if (auto methodDeclaration = methodDef->GetMethodDeclaration())
  3513. attributes = methodDeclaration->mAttributes;
  3514. if (auto propertyDeclaration = methodDef->GetPropertyDeclaration())
  3515. attributes = propertyDeclaration->mAttributes;
  3516. while (attributes != NULL)
  3517. {
  3518. if (attributes->mAttributeTypeRef != NULL)
  3519. {
  3520. auto typeRefName = attributes->mAttributeTypeRef->ToString();
  3521. if (typeRefName == "AlwaysInclude")
  3522. implRequired = true;
  3523. else if (typeRefName == "Export")
  3524. implRequired = true;
  3525. else if (typeRefName == "Test")
  3526. implRequired = true;
  3527. else
  3528. declRequired = true; // We need to create so we can check for AlwaysInclude in included attributes
  3529. }
  3530. attributes = attributes->mNextAttribute;
  3531. }
  3532. if ((mProject != NULL) && (mProject->mAlwaysIncludeAll) && (methodDef->mBody != NULL))
  3533. {
  3534. implRequired = true;
  3535. declRequired = true;
  3536. }
  3537. if (typeInstance->mIncludeAllMethods)
  3538. implRequired = true;
  3539. if ((typeOptionsIncludeAll) && (ApplyTypeOptionMethodFilters(true, methodDef, typeOptions)))
  3540. implRequired = true;
  3541. // if ((typeOptions != NULL) && (CheckTypeOptionMethodFilters(typeOptions, methodDef)))
  3542. // implRequired = true;
  3543. if (typeInstance->IsInterface())
  3544. declRequired = true;
  3545. if (methodDef->mIsVirtual)
  3546. declRequired = true;
  3547. if (!implRequired)
  3548. {
  3549. // Any interface with the same name causes us to not be on-demand
  3550. if (ifaceMethodNameSet.Contains(methodDef->mName))
  3551. declRequired = true;
  3552. }
  3553. // Is this strictly necessary? It will reduce our compilation speed in order to ensure methods are available for debug info
  3554. if (allDeclsRequired)
  3555. declRequired = true;
  3556. if (methodDef->mMethodDeclaration == NULL)
  3557. {
  3558. // Internal methods don't need decls
  3559. if ((methodDef->mName == BF_METHODNAME_DEFAULT_EQUALS) ||
  3560. (methodDef->mName == BF_METHODNAME_DEFAULT_STRICT_EQUALS))
  3561. declRequired = false;
  3562. }
  3563. if (!implRequired)
  3564. {
  3565. if (!mIsScratchModule)
  3566. mOnDemandMethodCount++;
  3567. if (!declRequired)
  3568. {
  3569. methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_NoDecl_AwaitingReference;
  3570. continue;
  3571. }
  3572. else
  3573. {
  3574. methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingDecl;
  3575. }
  3576. }
  3577. }
  3578. }
  3579. BfLogSysM("Starting DoTypeInstanceMethodProcessing %p GetMethodInstance pass. OnDemandMethods: %d\n", typeInstance, mOnDemandMethodCount);
  3580. // Pass 2
  3581. for (auto methodDef : typeDef->mMethods)
  3582. {
  3583. auto methodInstanceGroup = &typeInstance->mMethodInstanceGroups[methodDef->mIdx];
  3584. if ((methodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_AlwaysInclude) &&
  3585. (methodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_Decl_AwaitingDecl))
  3586. {
  3587. BfLogSysM("Skipping GetMethodInstance on MethodDef: %p OnDemandKind: %d\n", methodDef, methodInstanceGroup->mOnDemandKind);
  3588. continue;
  3589. }
  3590. int prevWorklistSize = (int)mContext->mMethodWorkList.size();
  3591. auto moduleMethodInstance = GetMethodInstance(typeInstance, methodDef, BfTypeVector(), ((methodDef->mGenericParams.size() != 0) || (typeInstance->IsUnspecializedType())) ? BfGetMethodInstanceFlag_UnspecializedPass : BfGetMethodInstanceFlag_None);
  3592. auto methodInstance = moduleMethodInstance.mMethodInstance;
  3593. if (methodInstance == NULL)
  3594. {
  3595. BF_ASSERT(typeInstance->IsGenericTypeInstance() && (typeInstance->mTypeDef->mIsCombinedPartial));
  3596. continue;
  3597. }
  3598. if ((!mCompiler->mIsResolveOnly) &&
  3599. ((methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingReference) || (!typeInstance->IsReified())))
  3600. {
  3601. bool forceMethodImpl = false;
  3602. BfCustomAttributes* customAttributes = methodInstance->GetCustomAttributes();
  3603. if ((customAttributes != NULL) && (typeInstance->IsReified()))
  3604. {
  3605. for (auto& attr : customAttributes->mAttributes)
  3606. {
  3607. auto attrTypeInst = attr.mType->ToTypeInstance();
  3608. auto attrCustomAttributes = attrTypeInst->mCustomAttributes;
  3609. if (attrCustomAttributes == NULL)
  3610. continue;
  3611. for (auto& attrAttr : attrCustomAttributes->mAttributes)
  3612. {
  3613. if (attrAttr.mType->ToTypeInstance()->mTypeDef == mCompiler->mAttributeUsageAttributeTypeDef)
  3614. {
  3615. // Check for Flags arg
  3616. if (attrAttr.mCtorArgs.size() < 2)
  3617. continue;
  3618. auto constant = attrTypeInst->mConstHolder->GetConstant(attrAttr.mCtorArgs[1]);
  3619. if (constant == NULL)
  3620. continue;
  3621. if (constant->mTypeCode == BfTypeCode_Boolean)
  3622. continue;
  3623. if ((constant->mInt8 & BfCustomAttributeFlags_AlwaysIncludeTarget) != 0)
  3624. forceMethodImpl = true;
  3625. }
  3626. }
  3627. }
  3628. }
  3629. if (typeInstance->mTypeDef->mProject->mTargetType == BfTargetType_BeefTest)
  3630. {
  3631. if ((customAttributes != NULL) && (customAttributes->Contains(mCompiler->mTestAttributeTypeDef)))
  3632. {
  3633. forceMethodImpl = true;
  3634. }
  3635. }
  3636. if (forceMethodImpl)
  3637. {
  3638. if (!typeInstance->IsReified())
  3639. mContext->mScratchModule->PopulateType(typeInstance, BfPopulateType_Data);
  3640. // Reify method
  3641. mContext->mScratchModule->GetMethodInstance(typeInstance, methodDef, BfTypeVector());
  3642. BF_ASSERT(methodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_Decl_AwaitingReference);
  3643. }
  3644. }
  3645. bool methodUsedVirtually = false;
  3646. if (typeInstance->IsInterface())
  3647. {
  3648. if ((!methodDef->mIsConcrete) && (!methodDef->mIsStatic) && (!methodInstance->HasSelf()))
  3649. SlotInterfaceMethod(methodInstance);
  3650. }
  3651. else if (!methodDef->IsEmptyPartial())
  3652. {
  3653. methodUsedVirtually = SlotVirtualMethod(methodInstance, &ambiguityContext);
  3654. }
  3655. // This is important for reducing latency of autocomplete popup, but it's important we don't allow the autocomplete
  3656. // thread to cause any reentry issues by re-populating a type at an "inopportune time". We do allow certain
  3657. // reentries in PopulateType, but not when we're resolving fields (for example)
  3658. if ((mContext->mFieldResolveReentrys.size() == 0) && (!mContext->mResolvingVarField))
  3659. {
  3660. disableYield.Release();
  3661. mSystem->CheckLockYield();
  3662. disableYield.Acquire();
  3663. }
  3664. }
  3665. BF_ASSERT(typeInstance->mVirtualMethodTable.size() == typeInstance->mVirtualMethodTableSize);
  3666. if ((isBoxed) && (!typeInstance->IsUnspecializedTypeVariation()))
  3667. {
  3668. // Any interface method that can be called virtually via an interface pointer needs to go into the boxed type
  3669. auto underlyingType = typeInstance->GetUnderlyingType();
  3670. BfTypeInstance* underlyingTypeInstance;
  3671. if (underlyingType->IsPrimitiveType())
  3672. underlyingTypeInstance = GetPrimitiveStructType(((BfPrimitiveType*)underlyingType)->mTypeDef->mTypeCode);
  3673. else
  3674. underlyingTypeInstance = underlyingType->ToTypeInstance();
  3675. if (underlyingTypeInstance != NULL)
  3676. {
  3677. PopulateType(underlyingTypeInstance, BfPopulateType_Full_Force);
  3678. for (int ifaceIdx = 0; ifaceIdx < (int)underlyingTypeInstance->mInterfaces.size(); ifaceIdx++)
  3679. {
  3680. auto& underlyingIFaceTypeInst = underlyingTypeInstance->mInterfaces[ifaceIdx];
  3681. auto& boxedIFaceTypeInst = typeInstance->mInterfaces[ifaceIdx];
  3682. BF_ASSERT(underlyingIFaceTypeInst.mInterfaceType == boxedIFaceTypeInst.mInterfaceType);
  3683. auto ifaceInst = underlyingIFaceTypeInst.mInterfaceType;
  3684. int startIdx = underlyingIFaceTypeInst.mStartInterfaceTableIdx;
  3685. int boxedStartIdx = boxedIFaceTypeInst.mStartInterfaceTableIdx;
  3686. int iMethodCount = (int)ifaceInst->mMethodInstanceGroups.size();
  3687. for (int iMethodIdx = 0; iMethodIdx < iMethodCount; iMethodIdx++)
  3688. {
  3689. auto matchedMethodRef = &underlyingTypeInstance->mInterfaceMethodTable[iMethodIdx + startIdx].mMethodRef;
  3690. auto boxedMatchedMethodRef = &typeInstance->mInterfaceMethodTable[iMethodIdx + boxedStartIdx].mMethodRef;
  3691. BfMethodInstance* matchedMethod = *matchedMethodRef;
  3692. auto ifaceMethodInst = ifaceInst->mMethodInstanceGroups[iMethodIdx].mDefault;
  3693. if (ifaceMethodInst->mVirtualTableIdx != -1)
  3694. {
  3695. if (matchedMethod == NULL)
  3696. {
  3697. AssertErrorState();
  3698. }
  3699. else
  3700. {
  3701. if (!matchedMethod->mIsForeignMethodDef)
  3702. {
  3703. BfMethodInstanceGroup* boxedMethodInstanceGroup = &typeInstance->mMethodInstanceGroups[matchedMethod->mMethodDef->mIdx];
  3704. if (boxedMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NoDecl_AwaitingReference)
  3705. {
  3706. boxedMethodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingDecl;
  3707. if (!mIsScratchModule)
  3708. mOnDemandMethodCount++;
  3709. }
  3710. }
  3711. auto moduleMethodInstance = GetMethodInstance(typeInstance, matchedMethod->mMethodDef, BfTypeVector(),
  3712. matchedMethod->mIsForeignMethodDef ? BfGetMethodInstanceFlag_ForeignMethodDef : BfGetMethodInstanceFlag_None,
  3713. matchedMethod->GetForeignType());
  3714. auto methodInstance = moduleMethodInstance.mMethodInstance;
  3715. UniqueSlotVirtualMethod(methodInstance);
  3716. *boxedMatchedMethodRef = methodInstance;
  3717. }
  3718. }
  3719. }
  3720. }
  3721. }
  3722. }
  3723. if (typeInstance->mHotTypeData != NULL)
  3724. {
  3725. auto latestVersion = typeInstance->mHotTypeData->GetLatestVersion();
  3726. auto latestVersionHead = typeInstance->mHotTypeData->GetLatestVersionHead();
  3727. if (typeInstance->mHotTypeData->mVTableOrigLength != -1)
  3728. {
  3729. bool hasSlotError = false;
  3730. BF_ASSERT(mCompiler->IsHotCompile());
  3731. //typeInstance->mHotTypeData->mDirty = true;
  3732. //Val128 vtHash;
  3733. Array<int> ifaceMapping;
  3734. ifaceMapping.Resize(latestVersionHead->mInterfaceMapping.size());
  3735. typeInstance->CalcHotVirtualData(&ifaceMapping);
  3736. // Hot swapping allows for interfaces to be added to types or removed from types, but it doesn't allow
  3737. // interfaces to be added when the slot number has already been used -- even if the interface using
  3738. // that slot has been removed.
  3739. for (int slotIdx = 0; slotIdx < (int)ifaceMapping.size(); slotIdx++)
  3740. {
  3741. int newId = ifaceMapping[slotIdx];
  3742. int oldId = 0;
  3743. if (slotIdx < (int)latestVersionHead->mInterfaceMapping.size())
  3744. oldId = latestVersionHead->mInterfaceMapping[slotIdx];
  3745. if ((newId != oldId) && (newId != 0) && (oldId != 0))
  3746. {
  3747. String interfaceName;
  3748. for (auto iface : typeInstance->mInterfaces)
  3749. {
  3750. if (iface.mInterfaceType->mTypeId == newId)
  3751. interfaceName = TypeToString(iface.mInterfaceType);
  3752. }
  3753. Warn(0, StrFormat("Hot swap detected resolvable interface slot collision with '%s'.", interfaceName.c_str()), typeDef->mTypeDeclaration);
  3754. BF_ASSERT(latestVersion != latestVersionHead);
  3755. if (!hasSlotError)
  3756. {
  3757. latestVersion->mInterfaceMapping = ifaceMapping;
  3758. }
  3759. hasSlotError = true;
  3760. }
  3761. else if (hasSlotError)
  3762. {
  3763. if (oldId != 0)
  3764. latestVersion->mInterfaceMapping[slotIdx] = oldId;
  3765. }
  3766. if (oldId != 0)
  3767. ifaceMapping[slotIdx] = oldId;
  3768. }
  3769. latestVersionHead->mInterfaceMapping = ifaceMapping;
  3770. if (hasSlotError)
  3771. mCompiler->mHotState->mPendingFailedSlottings.Add(typeInstance->mTypeId);
  3772. else
  3773. mCompiler->mHotState->mPendingFailedSlottings.Remove(typeInstance->mTypeId);
  3774. }
  3775. }
  3776. if ((typeInstance->IsInterface()) && (!typeInstance->IsUnspecializedType()) && (typeInstance->mIsReified) && (typeInstance->mSlotNum == -1) && (mCompiler->IsHotCompile()))
  3777. {
  3778. mCompiler->mHotState->mHasNewInterfaceTypes = true;
  3779. }
  3780. if ((!typeInstance->IsInterface()) && (!typeInstance->IsUnspecializedTypeVariation()) && (!isBoxed) && (!isFailedType))
  3781. {
  3782. if (!typeInstance->mTypeDef->mIsAbstract)
  3783. {
  3784. for (int methodIdx = 0; methodIdx < (int) typeInstance->mVirtualMethodTable.size(); methodIdx++)
  3785. {
  3786. auto& methodRef = typeInstance->mVirtualMethodTable[methodIdx].mImplementingMethod;
  3787. if (methodRef.mMethodNum == -1)
  3788. {
  3789. BF_ASSERT(mCompiler->mOptions.mHasVDataExtender);
  3790. if (methodRef.mTypeInstance == typeInstance)
  3791. {
  3792. if (typeInstance->GetImplBaseType() != NULL)
  3793. BF_ASSERT(methodIdx == (int)typeInstance->GetImplBaseType()->mVirtualMethodTableSize);
  3794. }
  3795. continue;
  3796. }
  3797. auto methodInstance = (BfMethodInstance*)methodRef;
  3798. if ((methodInstance != NULL) && (methodInstance->mMethodDef->mIsAbstract))
  3799. {
  3800. if (methodInstance->mMethodDef->mIsAbstract)
  3801. {
  3802. if (!typeInstance->IsUnspecializedTypeVariation())
  3803. {
  3804. if (Fail(StrFormat("'%s' does not implement inherited abstract method '%s'", TypeToString(typeInstance).c_str(), MethodToString(methodInstance).c_str()), typeDef->mTypeDeclaration->mNameNode, true) != NULL)
  3805. mCompiler->mPassInstance->MoreInfo("Abstract method declared", methodInstance->mMethodDef->GetRefNode());
  3806. }
  3807. }
  3808. else
  3809. {
  3810. if (!typeInstance->IsUnspecializedType())
  3811. AssertErrorState();
  3812. }
  3813. }
  3814. }
  3815. }
  3816. std::unordered_set<String> missingIFaceMethodNames;
  3817. for (auto& ifaceTypeInst : typeInstance->mInterfaces)
  3818. {
  3819. auto ifaceInst = ifaceTypeInst.mInterfaceType;
  3820. int startIdx = ifaceTypeInst.mStartInterfaceTableIdx;
  3821. int iMethodCount = (int)ifaceInst->mMethodInstanceGroups.size();
  3822. auto declTypeDef = ifaceTypeInst.mDeclaringType;
  3823. for (int iMethodIdx = 0; iMethodIdx < iMethodCount; iMethodIdx++)
  3824. {
  3825. auto matchedMethodRef = &typeInstance->mInterfaceMethodTable[iMethodIdx + startIdx].mMethodRef;
  3826. BfMethodInstance* matchedMethod = *matchedMethodRef;
  3827. auto ifaceMethodInst = ifaceInst->mMethodInstanceGroups[iMethodIdx].mDefault;
  3828. if ((matchedMethod == NULL) && (ifaceMethodInst != NULL))
  3829. {
  3830. missingIFaceMethodNames.insert(ifaceMethodInst->mMethodDef->mName);
  3831. }
  3832. }
  3833. }
  3834. if (!missingIFaceMethodNames.empty())
  3835. {
  3836. // Attempt to find matching entries in base types
  3837. ambiguityContext.mIsReslotting = true;
  3838. auto checkType = typeInstance->GetImplBaseType();
  3839. while (checkType != NULL)
  3840. {
  3841. for (auto& methodGroup : checkType->mMethodInstanceGroups)
  3842. {
  3843. auto methodInstance = methodGroup.mDefault;
  3844. if (methodInstance != NULL)
  3845. {
  3846. if ((methodInstance->mMethodDef->mProtection != BfProtection_Private) &&
  3847. (!methodInstance->mMethodDef->mIsOverride) &&
  3848. (missingIFaceMethodNames.find(methodInstance->mMethodDef->mName) != missingIFaceMethodNames.end()))
  3849. {
  3850. SlotVirtualMethod(methodInstance, &ambiguityContext);
  3851. }
  3852. }
  3853. }
  3854. checkType = checkType->GetImplBaseType();
  3855. }
  3856. }
  3857. for (auto& ifaceTypeInst : typeInstance->mInterfaces)
  3858. {
  3859. auto ifaceInst = ifaceTypeInst.mInterfaceType;
  3860. int startIdx = ifaceTypeInst.mStartInterfaceTableIdx;
  3861. int iMethodCount = (int)ifaceInst->mMethodInstanceGroups.size();
  3862. auto declTypeDef = ifaceTypeInst.mDeclaringType;
  3863. for (int iMethodIdx = 0; iMethodIdx < iMethodCount; iMethodIdx++)
  3864. {
  3865. auto matchedMethodRef = &typeInstance->mInterfaceMethodTable[iMethodIdx + startIdx].mMethodRef;
  3866. BfMethodInstance* matchedMethod = *matchedMethodRef;
  3867. auto ifaceMethodInst = ifaceInst->mMethodInstanceGroups[iMethodIdx].mDefault;
  3868. if (ifaceMethodInst == NULL)
  3869. continue;
  3870. auto iReturnType = ifaceMethodInst->mReturnType;
  3871. if (iReturnType->IsSelf())
  3872. iReturnType = typeInstance;
  3873. if (ifaceMethodInst->mMethodDef->mIsOverride)
  3874. continue; // Don't consider overrides here
  3875. // If we have "ProjA depends on LibBase", "ProjB depends on LibBase", then a type ClassC in LibBase implementing IFaceD,
  3876. // where IFaceD gets extended with MethodE in ProjA, an implementing MethodE is still required to exist on ClassC --
  3877. // the visibility is bidirectional. A type ClassF implementing IFaceD inside ProjB will not be required to implement
  3878. // MethodE, however
  3879. if ((!ifaceInst->IsTypeMemberAccessible(ifaceMethodInst->mMethodDef->mDeclaringType, ifaceTypeInst.mDeclaringType)) &&
  3880. (!ifaceInst->IsTypeMemberAccessible(ifaceTypeInst.mDeclaringType, ifaceMethodInst->mMethodDef->mDeclaringType)))
  3881. continue;
  3882. if (!ifaceInst->IsTypeMemberIncluded(ifaceMethodInst->mMethodDef->mDeclaringType, ifaceTypeInst.mDeclaringType))
  3883. continue;
  3884. bool hadMatch = matchedMethod != NULL;
  3885. bool hadPubFailure = false;
  3886. bool hadStaticFailure = false;
  3887. bool hadMutFailure = false;
  3888. if (hadMatch)
  3889. {
  3890. if ((matchedMethod->GetExplicitInterface() == NULL) && (matchedMethod->mMethodDef->mProtection != BfProtection_Public))
  3891. {
  3892. hadMatch = false;
  3893. hadPubFailure = true;
  3894. }
  3895. if (matchedMethod->mMethodDef->mIsStatic != ifaceMethodInst->mMethodDef->mIsStatic)
  3896. {
  3897. hadMatch = false;
  3898. hadStaticFailure = true;
  3899. }
  3900. if (ifaceMethodInst->mVirtualTableIdx != -1)
  3901. {
  3902. if (matchedMethod->mReturnType != iReturnType)
  3903. hadMatch = false;
  3904. }
  3905. else
  3906. {
  3907. // Concrete/generic
  3908. if (!CanCast(GetFakeTypedValue(matchedMethod->mReturnType), iReturnType))
  3909. hadMatch = false;
  3910. }
  3911. // If we have mExplicitInterface set then we already gave a mut error (if needed)
  3912. if ((typeInstance->IsValueType()) && (matchedMethod->GetExplicitInterface() == NULL) &&
  3913. (matchedMethod->mMethodDef->mIsMutating) && (!ifaceMethodInst->mMethodDef->mIsMutating))
  3914. {
  3915. hadMutFailure = true;
  3916. hadMatch = false;
  3917. }
  3918. }
  3919. if (!hadMatch)
  3920. {
  3921. if (!typeInstance->IsUnspecializedTypeVariation())
  3922. {
  3923. auto bestMethodInst = ifaceMethodInst;
  3924. auto bestInterface = ifaceInst;
  3925. if (matchedMethod == NULL)
  3926. {
  3927. bool searchFailed = false;
  3928. for (auto& checkIFaceTypeInst : typeInstance->mInterfaces)
  3929. {
  3930. auto checkIFaceInst = checkIFaceTypeInst.mInterfaceType;
  3931. int checkStartIdx = checkIFaceTypeInst.mStartInterfaceTableIdx;
  3932. int checkIMethodCount = (int)checkIFaceInst->mMethodInstanceGroups.size();
  3933. for (int checkIMethodIdx = 0; checkIMethodIdx < checkIMethodCount; checkIMethodIdx++)
  3934. {
  3935. auto checkIFaceMethodInst = checkIFaceInst->mMethodInstanceGroups[checkIMethodIdx].mDefault;
  3936. if ((checkIFaceMethodInst != NULL) && (checkIFaceMethodInst->mMethodDef->mIsOverride))
  3937. {
  3938. if (CompareMethodSignatures(checkIFaceMethodInst, ifaceMethodInst))
  3939. {
  3940. bool isBetter = TypeIsSubTypeOf(checkIFaceInst, bestInterface);
  3941. bool isWorse = TypeIsSubTypeOf(bestInterface, checkIFaceInst);
  3942. if (isBetter == isWorse)
  3943. {
  3944. CompareDeclTypes(checkIFaceMethodInst->mMethodDef->mDeclaringType, bestMethodInst->mMethodDef->mDeclaringType, isBetter, isWorse);
  3945. }
  3946. if ((isBetter) && (!isWorse))
  3947. {
  3948. bestInterface = checkIFaceInst;
  3949. bestMethodInst = checkIFaceMethodInst;
  3950. }
  3951. else if (isBetter == isWorse)
  3952. {
  3953. if (!searchFailed)
  3954. {
  3955. searchFailed = true;
  3956. auto error = Fail(StrFormat("There is no most-specific default implementation of '%s'", MethodToString(ifaceMethodInst).c_str()), declTypeDef->mTypeDeclaration->mNameNode);
  3957. if (error != NULL)
  3958. {
  3959. mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' is a candidate",
  3960. MethodToString(bestMethodInst).c_str()), bestMethodInst->mMethodDef->GetRefNode());
  3961. mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' is a candidate",
  3962. MethodToString(checkIFaceMethodInst).c_str()), checkIFaceMethodInst->mMethodDef->GetRefNode());
  3963. }
  3964. //candidate implementations include '%s' and '%s'",
  3965. //TypeToString(checkIFaceInst).c_str(), TypeToString(bestInterface).c_str()), );
  3966. }
  3967. }
  3968. }
  3969. }
  3970. }
  3971. }
  3972. if (bestMethodInst->mReturnType != ifaceMethodInst->mReturnType)
  3973. {
  3974. auto error = Fail(StrFormat("Default interface method '%s' cannot be used because it doesn't have the return type '%s'",
  3975. MethodToString(bestMethodInst).c_str(), TypeToString(ifaceMethodInst->mReturnType).c_str()), declTypeDef->mTypeDeclaration->mNameNode);
  3976. if (error != NULL)
  3977. {
  3978. mCompiler->mPassInstance->MoreInfo("See original method declaration", ifaceMethodInst->mMethodDef->GetRefNode());
  3979. mCompiler->mPassInstance->MoreInfo("See override method declaration", bestMethodInst->mMethodDef->GetRefNode());
  3980. }
  3981. }
  3982. }
  3983. if ((bestMethodInst->mMethodDef->HasBody()) && (matchedMethod == NULL))
  3984. {
  3985. auto methodDef = bestMethodInst->mMethodDef;
  3986. BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_ForeignMethodDef;
  3987. if ((methodDef->mGenericParams.size() != 0) || (typeInstance->IsUnspecializedType()))
  3988. flags = (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_UnspecializedPass);
  3989. auto methodInst = GetMethodInstance(typeInstance, methodDef, BfTypeVector(), flags, ifaceInst);
  3990. if (methodInst)
  3991. {
  3992. *matchedMethodRef = methodInst.mMethodInstance;
  3993. BfMethodInstance* newMethodInstance = methodInst.mMethodInstance;
  3994. BF_ASSERT(newMethodInstance->mIsForeignMethodDef);
  3995. if (newMethodInstance->mMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingReference)
  3996. mOnDemandMethodCount++;
  3997. continue;
  3998. }
  3999. }
  4000. if (typeInstance->IsBoxed())
  4001. {
  4002. if (ifaceMethodInst->mMethodDef->mIsStatic)
  4003. {
  4004. // Skip the statics, those can't be invoked
  4005. }
  4006. else
  4007. {
  4008. // The unboxed version should have had the same error
  4009. if (!typeInstance->GetUnderlyingType()->IsIncomplete())
  4010. AssertErrorState();
  4011. }
  4012. }
  4013. else
  4014. {
  4015. String methodString;
  4016. ///
  4017. {
  4018. SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, ifaceMethodInst);
  4019. methodString = MethodToString(ifaceMethodInst);
  4020. }
  4021. BfTypeDeclaration* typeDecl = declTypeDef->mTypeDeclaration;
  4022. BfError* error = Fail(StrFormat("'%s' does not implement interface member '%s'", TypeToString(typeInstance).c_str(), methodString.c_str()), typeDecl->mNameNode, true);
  4023. if ((matchedMethod != NULL) && (error != NULL))
  4024. {
  4025. if (hadStaticFailure)
  4026. {
  4027. auto staticNodeRef = matchedMethod->mMethodDef->GetRefNode();
  4028. if (auto methodDecl = BfNodeDynCast<BfMethodDeclaration>(matchedMethod->mMethodDef->mMethodDeclaration))
  4029. if (methodDecl->mStaticSpecifier != NULL)
  4030. staticNodeRef = methodDecl->mStaticSpecifier;
  4031. if (matchedMethod->mMethodDef->mIsStatic)
  4032. mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' cannot match because because it's static",
  4033. methodString.c_str()), staticNodeRef);
  4034. else
  4035. mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' cannot match because because it's not static",
  4036. methodString.c_str()), staticNodeRef);
  4037. }
  4038. else if (hadPubFailure)
  4039. {
  4040. mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' cannot match because because it's not public",
  4041. methodString.c_str()), matchedMethod->mMethodDef->mReturnTypeRef);
  4042. }
  4043. else if (ifaceMethodInst->mReturnType->IsConcreteInterfaceType())
  4044. {
  4045. mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' cannot match because because it does not have a concrete return type that implements '%s'",
  4046. methodString.c_str(), TypeToString(ifaceMethodInst->mReturnType).c_str()), matchedMethod->mMethodDef->mReturnTypeRef);
  4047. }
  4048. else if (hadMutFailure)
  4049. {
  4050. mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' cannot match because because it's market as 'mut' but interface method does not allow it",
  4051. methodString.c_str()), matchedMethod->mMethodDef->GetMutNode());
  4052. mCompiler->mPassInstance->MoreInfo(StrFormat("Declare the interface method as 'mut' to allow matching 'mut' implementations"), ifaceMethodInst->mMethodDef->mMethodDeclaration);
  4053. }
  4054. else
  4055. {
  4056. mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' cannot match because because it does not have the return type '%s'",
  4057. methodString.c_str(), TypeToString(ifaceMethodInst->mReturnType).c_str()), matchedMethod->mMethodDef->mReturnTypeRef);
  4058. if ((ifaceMethodInst->mVirtualTableIdx != -1) && (ifaceMethodInst->mReturnType->IsInterface()))
  4059. mCompiler->mPassInstance->MoreInfo("Declare the interface method as 'concrete' to allow matching concrete return values", ifaceMethodInst->mMethodDef->GetMethodDeclaration()->mVirtualSpecifier);
  4060. }
  4061. }
  4062. }
  4063. }
  4064. // Clear out the entry
  4065. *matchedMethodRef = BfMethodRef();
  4066. }
  4067. }
  4068. }
  4069. }
  4070. ambiguityContext.Finish();
  4071. CheckAddFailType();
  4072. typeInstance->mDefineState = BfTypeDefineState_DefinedAndMethodsSlotted;
  4073. mCompiler->mStats.mTypesPopulated++;
  4074. mCompiler->UpdateCompletion();
  4075. BfLogSysM("Finished DoTypeInstanceMethodProcessing %p. OnDemandMethods: %d Virtual Size: %d\n", typeInstance, mOnDemandMethodCount, typeInstance->mVirtualMethodTable.size());
  4076. }
  4077. void BfModule::RebuildMethods(BfTypeInstance* typeInstance)
  4078. {
  4079. if (typeInstance->IsIncomplete())
  4080. return;
  4081. typeInstance->mNeedsMethodProcessing = true;
  4082. typeInstance->mDefineState = BfTypeDefineState_Defined;
  4083. typeInstance->mTypeIncomplete = true;
  4084. for (auto& methodInstanceGroup : typeInstance->mMethodInstanceGroups)
  4085. {
  4086. delete methodInstanceGroup.mDefault;
  4087. methodInstanceGroup.mDefault = NULL;
  4088. delete methodInstanceGroup.mMethodSpecializationMap;
  4089. methodInstanceGroup.mMethodSpecializationMap = NULL;
  4090. methodInstanceGroup.mOnDemandKind = BfMethodOnDemandKind_NotSet;
  4091. }
  4092. BfTypeProcessRequest* typeProcessRequest = mContext->mPopulateTypeWorkList.Alloc();
  4093. typeProcessRequest->mType = typeInstance;
  4094. BF_ASSERT(typeInstance->mContext == mContext);
  4095. mCompiler->mStats.mTypesQueued++;
  4096. mCompiler->UpdateCompletion();
  4097. }
  4098. BfModule* BfModule::GetModuleFor(BfType* type)
  4099. {
  4100. auto typeInst = type->ToTypeInstance();
  4101. if (typeInst == NULL)
  4102. return NULL;
  4103. return typeInst->mModule;
  4104. }
  4105. void BfModule::AddMethodToWorkList(BfMethodInstance* methodInstance)
  4106. {
  4107. BF_ASSERT(!methodInstance->mMethodDef->mIsAbstract);
  4108. if (methodInstance->IsSpecializedByAutoCompleteMethod())
  4109. return;
  4110. BF_ASSERT(mCompiler->mCompileState != BfCompiler::CompileState_VData);
  4111. if ((methodInstance->mIsReified) && (!methodInstance->mIsUnspecialized))
  4112. {
  4113. BF_ASSERT(mCompiler->mCompileState != BfCompiler::CompileState_Unreified);
  4114. }
  4115. if (methodInstance->mIsUnspecializedVariation)
  4116. {
  4117. return;
  4118. }
  4119. BF_ASSERT(methodInstance->mMethodProcessRequest == NULL);
  4120. auto defaultMethod = methodInstance->mMethodInstanceGroup->mDefault;
  4121. if (defaultMethod != methodInstance)
  4122. {
  4123. BF_ASSERT(defaultMethod != NULL);
  4124. if (methodInstance->mMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingReference)
  4125. {
  4126. AddMethodToWorkList(defaultMethod);
  4127. }
  4128. }
  4129. if (methodInstance->mDeclModule != NULL)
  4130. {
  4131. if (methodInstance->mDeclModule != this)
  4132. {
  4133. methodInstance->mDeclModule->AddMethodToWorkList(methodInstance);
  4134. return;
  4135. }
  4136. }
  4137. else
  4138. {
  4139. auto module = GetOrCreateMethodModule(methodInstance);
  4140. methodInstance->mDeclModule = module;
  4141. BfIRValue func = CreateFunctionFrom(methodInstance, false, methodInstance->mAlwaysInline);
  4142. methodInstance->mIRFunction = func;
  4143. module->mFuncReferences[methodInstance] = func;
  4144. module->AddMethodToWorkList(methodInstance);
  4145. return;
  4146. }
  4147. if ((!methodInstance->mIRFunction) && (methodInstance->mIsReified) && (!methodInstance->mIsUnspecialized) &&
  4148. (methodInstance->GetImportCallKind() == BfImportCallKind_None))
  4149. {
  4150. if (!mIsModuleMutable)
  4151. PrepareForIRWriting(methodInstance->GetOwner());
  4152. BfIRValue func = CreateFunctionFrom(methodInstance, false, methodInstance->mAlwaysInline);
  4153. if (func)
  4154. {
  4155. methodInstance->mIRFunction = func;
  4156. mFuncReferences[methodInstance] = func;
  4157. }
  4158. }
  4159. BF_ASSERT(methodInstance->mDeclModule == this);
  4160. if (defaultMethod == methodInstance)
  4161. {
  4162. if (methodInstance->mMethodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_AlwaysInclude)
  4163. {
  4164. auto owningModule = methodInstance->GetOwner()->GetModule();
  4165. BF_ASSERT(methodInstance->mMethodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_Referenced);
  4166. if (!mIsScratchModule)
  4167. {
  4168. if (owningModule->mParentModule != NULL)
  4169. BF_ASSERT(owningModule->mParentModule->mOnDemandMethodCount > 0);
  4170. else
  4171. BF_ASSERT(owningModule->mOnDemandMethodCount > 0);
  4172. }
  4173. methodInstance->mMethodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_InWorkList;
  4174. }
  4175. }
  4176. else
  4177. {
  4178. BF_ASSERT(defaultMethod->mMethodInstanceGroup->IsImplemented());
  4179. }
  4180. BF_ASSERT(methodInstance->mDeclModule != NULL);
  4181. auto typeInstance = methodInstance->GetOwner();
  4182. BfMethodProcessRequest* methodProcessRequest = mContext->mMethodWorkList.Alloc();
  4183. methodProcessRequest->mType = typeInstance;
  4184. methodProcessRequest->mMethodInstance = methodInstance;
  4185. methodProcessRequest->mRevision = typeInstance->mRevision;
  4186. methodProcessRequest->mFromModuleRebuildIdx = mRebuildIdx;
  4187. methodProcessRequest->mFromModule = this;
  4188. if ((!mCompiler->mIsResolveOnly) && (methodInstance->mIsReified))
  4189. BF_ASSERT(mIsModuleMutable || mReifyQueued);
  4190. BF_ASSERT(mBfIRBuilder != NULL);
  4191. BfLogSysM("Adding to mMethodWorkList Module: %p IncompleteMethodCount: %d Type %p MethodInstance: %p Name:%s TypeRevision: %d ModuleRevision: %d ReqId:%d\n", this, mIncompleteMethodCount, typeInstance, methodInstance, methodInstance->mMethodDef->mName.c_str(), methodProcessRequest->mRevision, methodProcessRequest->mFromModuleRevision, methodProcessRequest->mReqId);
  4192. if (mAwaitingFinish)
  4193. {
  4194. BfLogSysM("Module: %p No longer awaiting finish\n", this);
  4195. mAwaitingFinish = false;
  4196. }
  4197. mCompiler->mStats.mMethodsQueued++;
  4198. mCompiler->UpdateCompletion();
  4199. mIncompleteMethodCount++;
  4200. if (methodInstance->GetNumGenericArguments() != 0)
  4201. mHasGenericMethods = true;
  4202. methodInstance->mMethodProcessRequest = methodProcessRequest;
  4203. }
  4204. BfArrayType* BfModule::CreateArrayType(BfType* resolvedType, int dimensions)
  4205. {
  4206. BF_ASSERT(!resolvedType->IsVar());
  4207. auto arrayType = mContext->mArrayTypePool.Get();
  4208. delete arrayType->mGenericTypeInfo;
  4209. arrayType->mGenericTypeInfo = new BfGenericTypeInfo();
  4210. arrayType->mContext = mContext;
  4211. arrayType->mTypeDef = mCompiler->GetArrayTypeDef(dimensions);
  4212. arrayType->mDimensions = dimensions;
  4213. arrayType->mGenericTypeInfo->mTypeGenericArguments.clear();
  4214. arrayType->mGenericTypeInfo->mTypeGenericArguments.push_back(resolvedType);
  4215. auto resolvedArrayType = ResolveType(arrayType);
  4216. if (resolvedArrayType != arrayType)
  4217. mContext->mArrayTypePool.GiveBack(arrayType);
  4218. return (BfArrayType*)resolvedArrayType;
  4219. }
  4220. BfSizedArrayType* BfModule::CreateSizedArrayType(BfType * resolvedType, int size)
  4221. {
  4222. BF_ASSERT(!resolvedType->IsVar());
  4223. auto arrayType = mContext->mSizedArrayTypePool.Get();
  4224. arrayType->mContext = mContext;
  4225. arrayType->mElementType = resolvedType;
  4226. arrayType->mElementCount = size;
  4227. auto resolvedArrayType = ResolveType(arrayType);
  4228. if (resolvedArrayType != arrayType)
  4229. mContext->mSizedArrayTypePool.GiveBack(arrayType);
  4230. return (BfSizedArrayType*)resolvedArrayType;
  4231. }
  4232. BfUnknownSizedArrayType* BfModule::CreateUnknownSizedArrayType(BfType* resolvedType, BfType* sizeParam)
  4233. {
  4234. BF_ASSERT(!resolvedType->IsVar());
  4235. BF_ASSERT(sizeParam->IsGenericParam());
  4236. auto arrayType = mContext->mUnknownSizedArrayTypePool.Get();
  4237. arrayType->mContext = mContext;
  4238. arrayType->mElementType = resolvedType;
  4239. arrayType->mElementCount = -1;
  4240. arrayType->mElementCountSource = sizeParam;
  4241. auto resolvedArrayType = ResolveType(arrayType);
  4242. if (resolvedArrayType != arrayType)
  4243. mContext->mUnknownSizedArrayTypePool.GiveBack(arrayType);
  4244. return (BfUnknownSizedArrayType*)resolvedArrayType;
  4245. }
  4246. BfPointerType* BfModule::CreatePointerType(BfType* resolvedType)
  4247. {
  4248. BF_ASSERT(!resolvedType->IsVar());
  4249. auto pointerType = mContext->mPointerTypePool.Get();
  4250. pointerType->mContext = mContext;
  4251. pointerType->mElementType = resolvedType;
  4252. auto resolvedPointerType = (BfPointerType*)ResolveType(pointerType);
  4253. if (resolvedPointerType != pointerType)
  4254. mContext->mPointerTypePool.GiveBack(pointerType);
  4255. BF_ASSERT(resolvedPointerType->mElementType == resolvedType);
  4256. return resolvedPointerType;
  4257. }
  4258. BfConstExprValueType* BfModule::CreateConstExprValueType(const BfTypedValue& typedValue)
  4259. {
  4260. auto variant = TypedValueToVariant(NULL, typedValue);
  4261. if (variant.mTypeCode == BfTypeCode_None)
  4262. return NULL;
  4263. auto constExprValueType = mContext->mConstExprValueTypePool.Get();
  4264. constExprValueType->mContext = mContext;
  4265. constExprValueType->mType = typedValue.mType;
  4266. constExprValueType->mValue = variant;
  4267. auto resolvedConstExprValueType = (BfConstExprValueType*)ResolveType(constExprValueType);
  4268. if (resolvedConstExprValueType != constExprValueType)
  4269. mContext->mConstExprValueTypePool.GiveBack(constExprValueType);
  4270. BF_ASSERT(resolvedConstExprValueType->mValue.mInt64 == constExprValueType->mValue.mInt64);
  4271. return resolvedConstExprValueType;
  4272. }
  4273. BfTypeInstance* BfModule::GetWrappedStructType(BfType* type, bool allowSpecialized)
  4274. {
  4275. if (type->IsPointer())
  4276. {
  4277. if (allowSpecialized)
  4278. {
  4279. BfPointerType* pointerType = (BfPointerType*)type;
  4280. BfTypeVector typeVector;
  4281. typeVector.Add(pointerType->mElementType);
  4282. return ResolveTypeDef(mCompiler->mPointerTTypeDef, typeVector, BfPopulateType_Data)->ToTypeInstance();
  4283. }
  4284. else
  4285. return ResolveTypeDef(mCompiler->mPointerTTypeDef, BfPopulateType_Data)->ToTypeInstance();
  4286. }
  4287. else if (type->IsMethodRef())
  4288. {
  4289. if (allowSpecialized)
  4290. {
  4291. BfMethodRefType* methodRefType = (BfMethodRefType*)type;
  4292. BfTypeVector typeVector;
  4293. typeVector.Add(methodRefType);
  4294. return ResolveTypeDef(mCompiler->mMethodRefTypeDef, typeVector, BfPopulateType_Data)->ToTypeInstance();
  4295. }
  4296. else
  4297. return ResolveTypeDef(mCompiler->mMethodRefTypeDef, BfPopulateType_Data)->ToTypeInstance();
  4298. }
  4299. else if (type->IsSizedArray())
  4300. {
  4301. if (allowSpecialized)
  4302. {
  4303. if (type->IsUnknownSizedArray())
  4304. {
  4305. BfUnknownSizedArrayType* sizedArrayType = (BfUnknownSizedArrayType*)type;
  4306. BfTypeVector typeVector;
  4307. typeVector.Add(sizedArrayType->mElementType);
  4308. typeVector.Add(sizedArrayType->mElementCountSource);
  4309. return ResolveTypeDef(mCompiler->mSizedArrayTypeDef, typeVector, BfPopulateType_Data)->ToTypeInstance();
  4310. }
  4311. BfSizedArrayType* sizedArrayType = (BfSizedArrayType*)type;
  4312. BfTypeVector typeVector;
  4313. typeVector.Add(sizedArrayType->mElementType);
  4314. auto sizeValue = BfTypedValue(GetConstValue(BF_MAX(sizedArrayType->mElementCount, 0)), GetPrimitiveType(BfTypeCode_IntPtr));
  4315. typeVector.Add(CreateConstExprValueType(sizeValue));
  4316. return ResolveTypeDef(mCompiler->mSizedArrayTypeDef, typeVector, BfPopulateType_Data)->ToTypeInstance();
  4317. }
  4318. else
  4319. return ResolveTypeDef(mCompiler->mSizedArrayTypeDef, BfPopulateType_Data)->ToTypeInstance();
  4320. }
  4321. BF_ASSERT(type->IsPrimitiveType());
  4322. return GetPrimitiveStructType(((BfPrimitiveType*)type)->mTypeDef->mTypeCode);
  4323. }
  4324. BfPrimitiveType* BfModule::GetPrimitiveType(BfTypeCode typeCode)
  4325. {
  4326. BfPrimitiveType* primType = mContext->mPrimitiveTypes[typeCode];
  4327. if (primType == NULL)
  4328. {
  4329. switch (typeCode)
  4330. {
  4331. case BfTypeCode_NullPtr:
  4332. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeNullPtr);
  4333. break;
  4334. case BfTypeCode_Self:
  4335. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeSelf);
  4336. break;
  4337. case BfTypeCode_Dot:
  4338. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeDot);
  4339. break;
  4340. case BfTypeCode_Var:
  4341. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeVar);
  4342. break;
  4343. case BfTypeCode_Let:
  4344. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeLet);
  4345. break;
  4346. case BfTypeCode_None:
  4347. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeVoid);
  4348. break;
  4349. case BfTypeCode_Boolean:
  4350. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeBool);
  4351. break;
  4352. case BfTypeCode_Int8:
  4353. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeInt8);
  4354. break;
  4355. case BfTypeCode_UInt8:
  4356. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeUInt8);
  4357. break;
  4358. case BfTypeCode_Int16:
  4359. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeInt16);
  4360. break;
  4361. case BfTypeCode_UInt16:
  4362. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeUInt16);
  4363. break;
  4364. case BfTypeCode_Int32:
  4365. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeInt32);
  4366. break;
  4367. case BfTypeCode_UInt32:
  4368. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeUInt32);
  4369. break;
  4370. case BfTypeCode_Int64:
  4371. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeInt64);
  4372. break;
  4373. case BfTypeCode_UInt64:
  4374. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeUInt64);
  4375. break;
  4376. case BfTypeCode_Char8:
  4377. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeChar8);
  4378. break;
  4379. case BfTypeCode_Char16:
  4380. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeChar16);
  4381. break;
  4382. case BfTypeCode_Char32:
  4383. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeChar32);
  4384. break;
  4385. case BfTypeCode_Float:
  4386. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeSingle);
  4387. break;
  4388. case BfTypeCode_Double:
  4389. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeDouble);
  4390. break;
  4391. case BfTypeCode_IntPtr:
  4392. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeIntPtr);
  4393. break;
  4394. case BfTypeCode_UIntPtr:
  4395. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeUIntPtr);
  4396. break;
  4397. case BfTypeCode_IntUnknown:
  4398. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeIntUnknown);
  4399. break;
  4400. case BfTypeCode_UIntUnknown:
  4401. primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeUIntUnknown);
  4402. break;
  4403. case BfTypeCode_StringId:
  4404. BFMODULE_FATAL(this, "Invalid use of StringId");
  4405. break;
  4406. default: break;
  4407. }
  4408. mContext->mPrimitiveTypes[typeCode] = primType;
  4409. }
  4410. return primType;
  4411. }
  4412. BfIRType BfModule::GetIRLoweredType(BfTypeCode loweredTypeCode, BfTypeCode loweredTypeCode2)
  4413. {
  4414. BF_ASSERT(loweredTypeCode != BfTypeCode_None);
  4415. if (loweredTypeCode2 == BfTypeCode_None)
  4416. return mBfIRBuilder->GetPrimitiveType(loweredTypeCode);
  4417. SizedArray<BfIRType, 2> types;
  4418. types.push_back(mBfIRBuilder->GetPrimitiveType(loweredTypeCode));
  4419. types.push_back(mBfIRBuilder->GetPrimitiveType(loweredTypeCode2));
  4420. return mBfIRBuilder->CreateStructType(types);
  4421. }
  4422. BfMethodRefType* BfModule::CreateMethodRefType(BfMethodInstance* methodInstance, bool mustAlreadyExist)
  4423. {
  4424. auto methodRefType = new BfMethodRefType();
  4425. methodRefType->mContext = mContext;
  4426. //methodRefType->mCaptureType = NULL;
  4427. methodRefType->mMethodRef = methodInstance;
  4428. methodRefType->mOwner = methodInstance->GetOwner();
  4429. methodRefType->mOwnerRevision = methodRefType->mOwner->mRevision;
  4430. //methodRefType->mMangledName = BfMangler::Mangle(mCompiler->GetMangleKind(), methodInstance);
  4431. methodRefType->mIsAutoCompleteMethod = methodInstance->mIsAutocompleteMethod;
  4432. methodRefType->mIsUnspecialized = methodInstance->mIsUnspecialized;
  4433. methodRefType->mIsUnspecializedVariation = methodInstance->mIsUnspecializedVariation;
  4434. methodRefType->mSize = 0;
  4435. BfResolvedTypeSet::LookupContext lookupCtx;
  4436. lookupCtx.mModule = this;
  4437. BfResolvedTypeSet::Entry* typeEntry = NULL;
  4438. auto inserted = mContext->mResolvedTypes.Insert(methodRefType, &lookupCtx, &typeEntry);
  4439. if (typeEntry->mValue == NULL)
  4440. {
  4441. BF_ASSERT(!mustAlreadyExist);
  4442. BF_ASSERT(!methodInstance->mHasMethodRefType);
  4443. InitType(methodRefType, BfPopulateType_Identity);
  4444. methodRefType->mDefineState = BfTypeDefineState_DefinedAndMethodsSlotted;
  4445. methodInstance->mHasMethodRefType = true;
  4446. methodInstance->mMethodInstanceGroup->mRefCount++;
  4447. typeEntry->mValue = methodRefType;
  4448. BfLogSysM("Create MethodRefType %p MethodInstance: %p\n", methodRefType, methodInstance);
  4449. methodRefType->mRevision = 0;
  4450. AddDependency(methodInstance->GetOwner(), methodRefType, BfDependencyMap::DependencyFlag_Calls);
  4451. BfTypeVector tupleTypes;
  4452. Array<String> tupleNames;
  4453. int offset = 0;
  4454. methodRefType->mAlign = 1;
  4455. int dataIdx = 0;
  4456. // CRepr, just because we're lazy (for now)
  4457. int implicitParamCount = methodInstance->GetImplicitParamCount();
  4458. for (int implicitParamIdx = methodInstance->HasThis() ? -1 : 0; implicitParamIdx < implicitParamCount; implicitParamIdx++)
  4459. {
  4460. auto paramType = methodInstance->GetParamType(implicitParamIdx);
  4461. if (!paramType->IsValuelessType())
  4462. {
  4463. methodRefType->mDataToParamIdx.Add(implicitParamIdx);
  4464. if (implicitParamIdx >= 0)
  4465. methodRefType->mParamToDataIdx.Add(dataIdx);
  4466. offset = BF_ALIGN(offset, paramType->mAlign);
  4467. offset += paramType->mSize;
  4468. methodRefType->mAlign = std::max(methodRefType->mAlign, paramType->mAlign);
  4469. dataIdx++;
  4470. }
  4471. else
  4472. {
  4473. methodRefType->mParamToDataIdx.Add(-1);
  4474. }
  4475. }
  4476. offset = BF_ALIGN(offset, methodRefType->mAlign);
  4477. methodRefType->mSize = offset;
  4478. // if (!tupleTypes.empty())
  4479. // {
  4480. // methodRefType->mCaptureType = CreateTupleType(tupleTypes, tupleNames);
  4481. // AddDependency(methodRefType->mCaptureType, methodRefType, BfDependencyMap::DependencyFlag_ReadFields);
  4482. //
  4483. // methodRefType->mSize = methodRefType->mCaptureType->mSize;
  4484. // methodRefType->mAlign = methodRefType->mCaptureType->mAlign;
  4485. // }
  4486. // else
  4487. // {
  4488. // methodRefType->mSize = 0;
  4489. // methodRefType->mAlign = 0;
  4490. // }
  4491. }
  4492. else
  4493. {
  4494. methodRefType->mMethodRef = NULL;
  4495. delete methodRefType;
  4496. methodRefType = (BfMethodRefType*)typeEntry->mValue;
  4497. }
  4498. return methodRefType;
  4499. }
  4500. BfType* BfModule::FixIntUnknown(BfType* type)
  4501. {
  4502. if ((type != NULL) && (type->IsPrimitiveType()))
  4503. {
  4504. auto primType = (BfPrimitiveType*)type;
  4505. if (primType->mTypeDef->mTypeCode == BfTypeCode_IntUnknown)
  4506. return GetPrimitiveType(BfTypeCode_IntPtr);
  4507. if (primType->mTypeDef->mTypeCode == BfTypeCode_UIntUnknown)
  4508. return GetPrimitiveType(BfTypeCode_UIntPtr);
  4509. }
  4510. return type;
  4511. }
  4512. void BfModule::FixIntUnknown(BfTypedValue& typedVal, BfType* matchType)
  4513. {
  4514. if (!typedVal.mValue.IsConst())
  4515. {
  4516. if ((typedVal.mType != NULL) && (typedVal.mType->IsPrimitiveType()))
  4517. {
  4518. auto primType = (BfPrimitiveType*)typedVal.mType;
  4519. BF_ASSERT((primType->mTypeDef->mTypeCode != BfTypeCode_IntUnknown) && (primType->mTypeDef->mTypeCode != BfTypeCode_UIntUnknown));
  4520. }
  4521. return;
  4522. }
  4523. if (!typedVal.mType->IsPrimitiveType())
  4524. return;
  4525. BfTypeCode wantTypeCode;
  4526. auto primType = (BfPrimitiveType*)typedVal.mType;
  4527. if (primType->mTypeDef->mTypeCode == BfTypeCode_IntUnknown)
  4528. wantTypeCode = BfTypeCode_IntPtr;
  4529. else if (primType->mTypeDef->mTypeCode == BfTypeCode_UIntUnknown)
  4530. wantTypeCode = BfTypeCode_UIntPtr;
  4531. else
  4532. return;
  4533. auto constant = mBfIRBuilder->GetConstant(typedVal.mValue);
  4534. if ((matchType != NULL) && (matchType->IsPrimitiveType()) && (mBfIRBuilder->IsInt(matchType->ToPrimitiveType()->mTypeDef->mTypeCode)))
  4535. {
  4536. auto wantTypeCode = matchType->ToPrimitiveType()->mTypeDef->mTypeCode;
  4537. if (matchType->mSize < 8)
  4538. {
  4539. int64 minVal = -(1LL << (8 * matchType->mSize - 1));
  4540. int64 maxVal = (1LL << (8 * matchType->mSize - 1)) - 1;
  4541. if ((constant->mInt64 >= minVal) && (constant->mInt64 <= maxVal))
  4542. {
  4543. typedVal.mValue = mBfIRBuilder->CreateNumericCast(typedVal.mValue, mBfIRBuilder->IsSigned(wantTypeCode), wantTypeCode);
  4544. typedVal.mType = GetPrimitiveType(wantTypeCode);
  4545. return;
  4546. }
  4547. }
  4548. }
  4549. if (mSystem->mPtrSize == 4)
  4550. {
  4551. if (primType->mTypeDef->mTypeCode == BfTypeCode_IntUnknown)
  4552. {
  4553. if ((constant->mInt64 >= -0x80000000LL) && (constant->mInt64 <= 0x7FFFFFFFLL))
  4554. {
  4555. typedVal.mValue = mBfIRBuilder->CreateNumericCast(typedVal.mValue, true, BfTypeCode_IntPtr);
  4556. typedVal.mType = GetPrimitiveType(BfTypeCode_IntPtr);
  4557. }
  4558. else
  4559. typedVal.mType = GetPrimitiveType(BfTypeCode_Int64);
  4560. return;
  4561. }
  4562. else
  4563. {
  4564. if ((constant->mInt64 >= 0) && (constant->mInt64 <= 0xFFFFFFFF))
  4565. {
  4566. typedVal.mValue = mBfIRBuilder->CreateNumericCast(typedVal.mValue, false, BfTypeCode_IntPtr);
  4567. typedVal.mType = GetPrimitiveType(BfTypeCode_UIntPtr);
  4568. }
  4569. else
  4570. typedVal.mType = GetPrimitiveType(BfTypeCode_UInt64);
  4571. return;
  4572. }
  4573. }
  4574. typedVal.mType = GetPrimitiveType(wantTypeCode);
  4575. }
  4576. void BfModule::FixIntUnknown(BfTypedValue& lhs, BfTypedValue& rhs)
  4577. {
  4578. if ((lhs.mType != NULL) && (lhs.mType->IsIntUnknown()) && (rhs.mType != NULL) && (rhs.mType->IsInteger()))
  4579. {
  4580. if (CanCast(lhs, rhs.mType))
  4581. {
  4582. lhs = Cast(NULL, lhs, rhs.mType, BfCastFlags_SilentFail);
  4583. if (!lhs)
  4584. lhs = GetDefaultTypedValue(GetPrimitiveType(BfTypeCode_IntPtr));
  4585. return;
  4586. }
  4587. }
  4588. if ((rhs.mType != NULL) && (rhs.mType->IsIntUnknown()) && (lhs.mType != NULL) && (lhs.mType->IsInteger()))
  4589. {
  4590. if (CanCast(rhs, lhs.mType))
  4591. {
  4592. rhs = Cast(NULL, rhs, lhs.mType, BfCastFlags_SilentFail);
  4593. if (!rhs)
  4594. rhs = GetDefaultTypedValue(GetPrimitiveType(BfTypeCode_IntPtr));
  4595. return;
  4596. }
  4597. }
  4598. FixIntUnknown(lhs);
  4599. FixIntUnknown(rhs);
  4600. }
  4601. BfTypeInstance* BfModule::GetPrimitiveStructType(BfTypeCode typeCode)
  4602. {
  4603. BfTypeInstance* typeInst = NULL;
  4604. switch (typeCode)
  4605. {
  4606. case BfTypeCode_None:
  4607. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.Void"), BfPopulateType_Identity)->ToTypeInstance(); break;
  4608. case BfTypeCode_Boolean:
  4609. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.Boolean"), BfPopulateType_Identity)->ToTypeInstance(); break;
  4610. case BfTypeCode_Int8:
  4611. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.Int8"), BfPopulateType_Identity)->ToTypeInstance(); break;
  4612. case BfTypeCode_UInt8:
  4613. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.UInt8"), BfPopulateType_Identity)->ToTypeInstance(); break;
  4614. case BfTypeCode_Int16:
  4615. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.Int16"), BfPopulateType_Identity)->ToTypeInstance(); break;
  4616. case BfTypeCode_UInt16:
  4617. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.UInt16"), BfPopulateType_Identity)->ToTypeInstance(); break;
  4618. case BfTypeCode_Int32:
  4619. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.Int32"), BfPopulateType_Identity)->ToTypeInstance(); break;
  4620. case BfTypeCode_UInt32:
  4621. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.UInt32"), BfPopulateType_Identity)->ToTypeInstance(); break;
  4622. case BfTypeCode_Int64:
  4623. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.Int64"), BfPopulateType_Identity)->ToTypeInstance(); break;
  4624. case BfTypeCode_UInt64:
  4625. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.UInt64"), BfPopulateType_Identity)->ToTypeInstance(); break;
  4626. case BfTypeCode_IntPtr:
  4627. case BfTypeCode_IntUnknown:
  4628. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.Int"), BfPopulateType_Identity)->ToTypeInstance(); break;
  4629. case BfTypeCode_UIntPtr:
  4630. case BfTypeCode_UIntUnknown:
  4631. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.UInt"), BfPopulateType_Identity)->ToTypeInstance(); break;
  4632. case BfTypeCode_Char8:
  4633. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.Char8"), BfPopulateType_Identity)->ToTypeInstance(); break;
  4634. case BfTypeCode_Char16:
  4635. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.Char16"), BfPopulateType_Identity)->ToTypeInstance(); break;
  4636. case BfTypeCode_Char32:
  4637. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.Char32"), BfPopulateType_Identity)->ToTypeInstance(); break;
  4638. case BfTypeCode_Float:
  4639. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.Float"), BfPopulateType_Identity)->ToTypeInstance(); break;
  4640. case BfTypeCode_Double:
  4641. typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.Double"), BfPopulateType_Identity)->ToTypeInstance(); break;
  4642. default:
  4643. //BF_FATAL("not implemented");
  4644. break;
  4645. }
  4646. return typeInst;
  4647. }
  4648. BfBoxedType* BfModule::CreateBoxedType(BfType* resolvedTypeRef)
  4649. {
  4650. bool isStructPtr = false;
  4651. if (resolvedTypeRef->IsPrimitiveType())
  4652. {
  4653. auto primType = (BfPrimitiveType*)resolvedTypeRef;
  4654. resolvedTypeRef = GetPrimitiveStructType(primType->mTypeDef->mTypeCode);
  4655. if (resolvedTypeRef == NULL)
  4656. {
  4657. BFMODULE_FATAL(this, "Unable to find primitive type");
  4658. return NULL;
  4659. }
  4660. }
  4661. else if (resolvedTypeRef->IsPointer())
  4662. {
  4663. BfPointerType* pointerType = (BfPointerType*)resolvedTypeRef;
  4664. if (pointerType->mElementType->IsStruct())
  4665. {
  4666. resolvedTypeRef = pointerType->mElementType;
  4667. isStructPtr = true;
  4668. }
  4669. else
  4670. {
  4671. BfTypeVector typeVector;
  4672. typeVector.Add(pointerType->mElementType);
  4673. resolvedTypeRef = ResolveTypeDef(mCompiler->mPointerTTypeDef, typeVector, BfPopulateType_Data)->ToTypeInstance();
  4674. }
  4675. }
  4676. else if (resolvedTypeRef->IsMethodRef())
  4677. {
  4678. BfMethodRefType* methodRefType = (BfMethodRefType*)resolvedTypeRef;
  4679. BfTypeVector typeVector;
  4680. typeVector.Add(methodRefType);
  4681. resolvedTypeRef = ResolveTypeDef(mCompiler->mMethodRefTypeDef, typeVector, BfPopulateType_Data)->ToTypeInstance();
  4682. }
  4683. else if (resolvedTypeRef->IsSizedArray())
  4684. {
  4685. BfSizedArrayType* sizedArrayType = (BfSizedArrayType*)resolvedTypeRef;
  4686. BfTypeVector typeVector;
  4687. typeVector.Add(sizedArrayType->mElementType);
  4688. auto sizeValue = BfTypedValue(GetConstValue(sizedArrayType->mElementCount), GetPrimitiveType(BfTypeCode_IntPtr));
  4689. typeVector.Add(CreateConstExprValueType(sizeValue));
  4690. resolvedTypeRef = ResolveTypeDef(mCompiler->mSizedArrayTypeDef, typeVector, BfPopulateType_Data)->ToTypeInstance();
  4691. }
  4692. BfTypeInstance* typeInst = resolvedTypeRef->ToTypeInstance();
  4693. if ((typeInst == NULL) && (!resolvedTypeRef->IsGenericParam()))
  4694. return NULL;
  4695. auto boxedType = mContext->mBoxedTypePool.Get();
  4696. boxedType->mContext = mContext;
  4697. boxedType->mElementType = resolvedTypeRef;
  4698. if (typeInst != NULL)
  4699. boxedType->mTypeDef = typeInst->mTypeDef;
  4700. else
  4701. boxedType->mTypeDef = mCompiler->mValueTypeTypeDef;
  4702. boxedType->mBoxedFlags = isStructPtr ? BfBoxedType::BoxedFlags_StructPtr : BfBoxedType::BoxedFlags_None;
  4703. auto resolvedBoxedType = ResolveType(boxedType);
  4704. if (resolvedBoxedType != boxedType)
  4705. mContext->mBoxedTypePool.GiveBack(boxedType);
  4706. return (BfBoxedType*)resolvedBoxedType;
  4707. }
  4708. BfTypeInstance* BfModule::CreateTupleType(const BfTypeVector& fieldTypes, const Array<String>& fieldNames, bool allowVar)
  4709. {
  4710. auto baseType = (BfTypeInstance*)ResolveTypeDef(mContext->mCompiler->mValueTypeTypeDef);
  4711. BfTupleType* tupleType = NULL;
  4712. auto actualTupleType = mContext->mTupleTypePool.Get();
  4713. actualTupleType->Init(baseType->mTypeDef->mProject, baseType);
  4714. bool isUnspecialzied = false;
  4715. for (int fieldIdx = 0; fieldIdx < (int)fieldTypes.size(); fieldIdx++)
  4716. {
  4717. String fieldName;
  4718. if (fieldIdx < (int)fieldNames.size())
  4719. fieldName = fieldNames[fieldIdx];
  4720. if (fieldName.empty())
  4721. fieldName = StrFormat("%d", fieldIdx);
  4722. BfFieldDef* fieldDef = actualTupleType->AddField(fieldName);
  4723. auto fieldType = fieldTypes[fieldIdx];
  4724. if ((fieldType->IsUnspecializedType()) || (fieldType->IsVar()))
  4725. isUnspecialzied = true;
  4726. }
  4727. tupleType = actualTupleType;
  4728. tupleType->mContext = mContext;
  4729. tupleType->mFieldInstances.Resize(fieldTypes.size());
  4730. for (int fieldIdx = 0; fieldIdx < (int)fieldTypes.size(); fieldIdx++)
  4731. {
  4732. BfFieldInstance* fieldInstance = (BfFieldInstance*)&tupleType->mFieldInstances[fieldIdx];
  4733. fieldInstance->mFieldIdx = fieldIdx;
  4734. BfType* fieldType = fieldTypes[fieldIdx];
  4735. if ((fieldType->IsVar()) && (!allowVar))
  4736. fieldType = mContext->mBfObjectType;
  4737. fieldInstance->SetResolvedType(fieldType);
  4738. fieldInstance->mOwner = tupleType;
  4739. }
  4740. tupleType->mIsUnspecializedType = false;
  4741. tupleType->mIsUnspecializedTypeVariation = false;
  4742. if (isUnspecialzied)
  4743. {
  4744. tupleType->mIsUnspecializedType = true;
  4745. tupleType->mIsUnspecializedTypeVariation = true;
  4746. }
  4747. auto resolvedTupleType = ResolveType(tupleType);
  4748. if (resolvedTupleType != tupleType)
  4749. {
  4750. BF_ASSERT(tupleType->mContext != NULL);
  4751. mContext->mTupleTypePool.GiveBack((BfTupleType*)tupleType);
  4752. }
  4753. return (BfTupleType*)resolvedTupleType;
  4754. }
  4755. BfTypeInstance* BfModule::SantizeTupleType(BfTypeInstance* tupleType)
  4756. {
  4757. bool needsSanitize = false;
  4758. for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
  4759. {
  4760. BfFieldInstance* fieldInstance = (BfFieldInstance*)&tupleType->mFieldInstances[fieldIdx];
  4761. if ((fieldInstance->mResolvedType->IsVar()) || (fieldInstance->mResolvedType->IsLet()))
  4762. {
  4763. needsSanitize = true;
  4764. break;
  4765. }
  4766. }
  4767. if (!needsSanitize)
  4768. return tupleType;
  4769. BfTypeVector fieldTypes;
  4770. Array<String> fieldNames;
  4771. for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
  4772. {
  4773. BfFieldInstance* fieldInstance = (BfFieldInstance*)&tupleType->mFieldInstances[fieldIdx];
  4774. auto fieldDef = fieldInstance->GetFieldDef();
  4775. if ((fieldInstance->mResolvedType->IsVar()) || (fieldInstance->mResolvedType->IsLet()))
  4776. fieldTypes.Add(mContext->mBfObjectType);
  4777. else
  4778. fieldTypes.Add(fieldInstance->mResolvedType);
  4779. if (!fieldDef->IsUnnamedTupleField())
  4780. {
  4781. for (int i = 0; i < fieldIdx; i++)
  4782. fieldNames.Add(String());
  4783. fieldNames.Add(fieldDef->mName);
  4784. }
  4785. }
  4786. return CreateTupleType(fieldTypes, fieldNames);
  4787. }
  4788. BfRefType* BfModule::CreateRefType(BfType* resolvedTypeRef, BfRefType::RefKind refKind)
  4789. {
  4790. auto refType = mContext->mRefTypePool.Get();
  4791. refType->mContext = mContext;
  4792. refType->mElementType = resolvedTypeRef;
  4793. refType->mRefKind = refKind;
  4794. auto resolvedRefType = ResolveType(refType);
  4795. if (resolvedRefType != refType)
  4796. mContext->mRefTypePool.GiveBack(refType);
  4797. return (BfRefType*)resolvedRefType;
  4798. }
  4799. BfModifiedTypeType* BfModule::CreateModifiedTypeType(BfType* resolvedTypeRef, BfToken modifiedKind)
  4800. {
  4801. auto retTypeType = mContext->mModifiedTypeTypePool.Get();
  4802. retTypeType->mContext = mContext;
  4803. retTypeType->mModifiedKind = modifiedKind;
  4804. retTypeType->mElementType = resolvedTypeRef;
  4805. auto resolvedRetTypeType = ResolveType(retTypeType);
  4806. if (resolvedRetTypeType != retTypeType)
  4807. mContext->mModifiedTypeTypePool.GiveBack(retTypeType);
  4808. return (BfModifiedTypeType*)resolvedRetTypeType;
  4809. }
  4810. BfConcreteInterfaceType* BfModule::CreateConcreteInterfaceType(BfTypeInstance* interfaceType)
  4811. {
  4812. auto concreteInterfaceType = mContext->mConcreteInterfaceTypePool.Get();
  4813. concreteInterfaceType->mContext = mContext;
  4814. concreteInterfaceType->mInterface = interfaceType;
  4815. auto resolvedConcreteInterfaceType = ResolveType(concreteInterfaceType);
  4816. if (resolvedConcreteInterfaceType != concreteInterfaceType)
  4817. mContext->mConcreteInterfaceTypePool.GiveBack(concreteInterfaceType);
  4818. return (BfConcreteInterfaceType*)resolvedConcreteInterfaceType;
  4819. }
  4820. BfPointerType* BfModule::CreatePointerType(BfTypeReference* typeRef)
  4821. {
  4822. auto resolvedTypeRef = ResolveTypeRef(typeRef);
  4823. if (resolvedTypeRef == NULL)
  4824. return NULL;
  4825. return CreatePointerType(resolvedTypeRef);
  4826. }
  4827. BfType* BfModule::ResolveTypeDef(BfTypeDef* typeDef, BfPopulateType populateType)
  4828. {
  4829. //BF_ASSERT(typeDef->mTypeCode != BfTypeCode_Extension);
  4830. BF_ASSERT(!typeDef->mIsPartial || typeDef->mIsCombinedPartial);
  4831. BF_ASSERT(typeDef->mDefState != BfTypeDef::DefState_Deleted);
  4832. BF_ASSERT((typeDef->mOuterType == NULL) || (typeDef->mOuterType->mDefState != BfTypeDef::DefState_Deleted));
  4833. if (typeDef->mGenericParamDefs.size() != 0)
  4834. return ResolveTypeDef(typeDef, BfTypeVector(), populateType);
  4835. auto typeDefTypeRef = mContext->mTypeDefTypeRefPool.Get();
  4836. typeDefTypeRef->mTypeDef = typeDef;
  4837. auto resolvedtypeDefType = ResolveTypeRef(typeDefTypeRef, populateType);
  4838. if (resolvedtypeDefType == NULL)
  4839. {
  4840. mContext->mTypeDefTypeRefPool.GiveBack(typeDefTypeRef);
  4841. return NULL;
  4842. }
  4843. mContext->mTypeDefTypeRefPool.GiveBack(typeDefTypeRef);
  4844. //BF_ASSERT(resolvedtypeDefType->IsTypeInstance() || resolvedtypeDefType->IsPrimitiveType());
  4845. return resolvedtypeDefType;
  4846. }
  4847. // Get BaseClass even when we haven't populated the type yet2
  4848. BfTypeInstance* BfModule::GetBaseType(BfTypeInstance* typeInst)
  4849. {
  4850. if ((mContext->mCurTypeState != NULL) && (mContext->mCurTypeState->mTypeInstance == typeInst))
  4851. {
  4852. if (typeInst->mBaseType == NULL)
  4853. return NULL;
  4854. }
  4855. if ((typeInst->mBaseType == NULL) && (typeInst != mContext->mBfObjectType))
  4856. PopulateType(typeInst, BfPopulateType_BaseType);
  4857. return typeInst->mBaseType;
  4858. }
  4859. void BfModule::HandleTypeGenericParamRef(BfAstNode* refNode, BfTypeDef* typeDef, int typeGenericParamIdx)
  4860. {
  4861. if (mCompiler->IsAutocomplete())
  4862. {
  4863. BfAutoComplete* autoComplete = mCompiler->mResolvePassData->mAutoComplete;
  4864. if ((autoComplete != NULL) && (autoComplete->mIsGetDefinition) && (autoComplete->IsAutocompleteNode(refNode)))
  4865. {
  4866. if ((autoComplete->mDefMethod == NULL) && (autoComplete->mDefField == NULL) &&
  4867. (autoComplete->mDefProp == NULL))
  4868. {
  4869. autoComplete->mDefType = typeDef;
  4870. autoComplete->mDefTypeGenericParamIdx = typeGenericParamIdx;
  4871. autoComplete->SetDefinitionLocation(refNode);
  4872. }
  4873. }
  4874. }
  4875. if (mCompiler->mResolvePassData != NULL)
  4876. mCompiler->mResolvePassData->HandleTypeGenericParam(refNode, typeDef, typeGenericParamIdx);
  4877. }
  4878. void BfModule::HandleMethodGenericParamRef(BfAstNode* refNode, BfTypeDef* typeDef, BfMethodDef* methodDef, int methodGenericParamIdx)
  4879. {
  4880. if (mCompiler->IsAutocomplete())
  4881. {
  4882. BfAutoComplete* autoComplete = mCompiler->mResolvePassData->mAutoComplete;
  4883. if ((autoComplete != NULL) && (autoComplete->mIsGetDefinition) && (autoComplete->IsAutocompleteNode(refNode)))
  4884. {
  4885. if ((autoComplete->mDefMethod == NULL) && (autoComplete->mDefField == NULL) &&
  4886. (autoComplete->mDefProp == NULL))
  4887. {
  4888. autoComplete->mDefType = typeDef;
  4889. autoComplete->mDefMethod = methodDef;
  4890. autoComplete->mDefMethodGenericParamIdx = methodGenericParamIdx;
  4891. autoComplete->SetDefinitionLocation(refNode);
  4892. }
  4893. }
  4894. }
  4895. if (mCompiler->mResolvePassData != NULL)
  4896. mCompiler->mResolvePassData->HandleMethodGenericParam(refNode, typeDef, methodDef, methodGenericParamIdx);
  4897. }
  4898. BfType* BfModule::ResolveInnerType(BfType* outerType, BfTypeReference* typeRef, BfPopulateType populateType, bool ignoreErrors, int numGenericArgs)
  4899. {
  4900. BfTypeDef* nestedTypeDef = NULL;
  4901. if (outerType->IsBoxed())
  4902. outerType = outerType->GetUnderlyingType();
  4903. BfNamedTypeReference* namedTypeRef = NULL;
  4904. BfGenericInstanceTypeRef* genericTypeRef = NULL;
  4905. BfDirectStrTypeReference* directStrTypeRef = NULL;
  4906. if ((namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(typeRef)))
  4907. {
  4908. //TYPEDEF nestedTypeDef = namedTypeRef->mTypeDef;
  4909. }
  4910. else if ((genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef)))
  4911. {
  4912. namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(genericTypeRef->mElementType);
  4913. //TYPEDEF nestedTypeDef = namedTypeRef->mTypeDef;
  4914. }
  4915. else if ((directStrTypeRef = BfNodeDynCast<BfDirectStrTypeReference>(typeRef)))
  4916. {
  4917. //
  4918. }
  4919. BF_ASSERT((namedTypeRef != NULL) || (directStrTypeRef != NULL));
  4920. if (nestedTypeDef == NULL)
  4921. {
  4922. StringView findName;
  4923. if (namedTypeRef != NULL)
  4924. findName = namedTypeRef->mNameNode->ToStringView();
  4925. else
  4926. findName = directStrTypeRef->mTypeName;
  4927. if (!findName.Contains('.'))
  4928. {
  4929. if (outerType->IsTypeInstance())
  4930. {
  4931. auto outerTypeInstance = outerType->ToTypeInstance();
  4932. for (int pass = 0; pass < 2; pass++)
  4933. {
  4934. bool isFailurePass = pass == 1;
  4935. bool allowPrivate = (mCurTypeInstance != NULL) &&
  4936. ((mCurTypeInstance == outerTypeInstance) || TypeHasParentOrEquals(mCurTypeInstance->mTypeDef, outerTypeInstance->mTypeDef));
  4937. bool allowProtected = allowPrivate;/*(mCurTypeInstance != NULL) &&
  4938. (allowPrivate || (mCurTypeInstance->mSkipTypeProtectionChecks) || TypeIsSubTypeOf(mCurTypeInstance, outerTypeInstance));*/
  4939. auto checkOuterType = outerTypeInstance;
  4940. while (checkOuterType != NULL)
  4941. {
  4942. for (auto checkType : checkOuterType->mTypeDef->mNestedTypes)
  4943. {
  4944. auto latestCheckType = checkType->GetLatest();
  4945. if ((!isFailurePass) && (!CheckProtection(latestCheckType->mProtection, allowProtected, allowPrivate)))
  4946. continue;
  4947. if (checkType->mProject != checkOuterType->mTypeDef->mProject)
  4948. {
  4949. auto visibleProjectSet = GetVisibleProjectSet();
  4950. if ((visibleProjectSet == NULL) || (!visibleProjectSet->Contains(checkType->mProject)))
  4951. continue;
  4952. }
  4953. if ((checkType->mName->mString == findName) && (checkType->GetSelfGenericParamCount() == numGenericArgs))
  4954. {
  4955. if (isFailurePass)
  4956. {
  4957. // This is the one error we don't ignore when ignoreErrors is set
  4958. Fail(StrFormat("'%s.%s' is inaccessible due to its protection level", TypeToString(checkOuterType).c_str(), BfTypeUtils::TypeToString(typeRef).c_str()), typeRef); // CS0122
  4959. }
  4960. nestedTypeDef = checkType;
  4961. break;
  4962. }
  4963. }
  4964. if (nestedTypeDef != NULL)
  4965. break;
  4966. allowPrivate = false;
  4967. checkOuterType = GetBaseType(checkOuterType);
  4968. }
  4969. if (nestedTypeDef != NULL)
  4970. break;
  4971. }
  4972. }
  4973. }
  4974. if (nestedTypeDef == NULL)
  4975. {
  4976. if (!mIgnoreErrors && !ignoreErrors)
  4977. {
  4978. StringT<64> name;
  4979. name.Append(findName);
  4980. Fail(StrFormat("'%s' does not contain a definition for '%s'", TypeToString(outerType).c_str(), name.c_str()), typeRef);
  4981. }
  4982. return NULL;
  4983. }
  4984. }
  4985. SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, ignoreErrors || mIgnoreErrors);
  4986. if ((genericTypeRef != NULL) || (outerType->IsGenericTypeInstance()))
  4987. {
  4988. BfTypeVector genericArgs;
  4989. if (outerType->IsGenericTypeInstance())
  4990. {
  4991. auto genericTypeInst = (BfTypeInstance*)outerType;
  4992. genericArgs = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments;
  4993. }
  4994. if (genericTypeRef != NULL)
  4995. {
  4996. for (auto genericArgTypeRef : genericTypeRef->mGenericArguments)
  4997. {
  4998. auto genericArgType = ResolveTypeRef(genericArgTypeRef, BfPopulateType_IdentityNoRemapAlias);
  4999. if (genericArgType == NULL)
  5000. return NULL;
  5001. genericArgs.push_back(genericArgType);
  5002. }
  5003. }
  5004. if (genericArgs.size() != nestedTypeDef->mGenericParamDefs.size())
  5005. {
  5006. if (populateType == BfPopulateType_TypeDef)
  5007. {
  5008. // Probably from inside ResolveGenericInstanceDef, just return unresolved typedef
  5009. genericArgs.clear();
  5010. }
  5011. else
  5012. {
  5013. ShowGenericArgCountError(typeRef, (int)nestedTypeDef->mGenericParamDefs.size() - (int)nestedTypeDef->mOuterType->mGenericParamDefs.size());
  5014. return NULL;
  5015. }
  5016. }
  5017. if (nestedTypeDef->mIsPartial)
  5018. {
  5019. nestedTypeDef = GetCombinedPartialTypeDef(nestedTypeDef);
  5020. if (nestedTypeDef == NULL)
  5021. return NULL;
  5022. }
  5023. return ResolveTypeDef(nestedTypeDef, genericArgs, BfPopulateType_IdentityNoRemapAlias);
  5024. }
  5025. else
  5026. {
  5027. if (nestedTypeDef->mIsPartial)
  5028. {
  5029. nestedTypeDef = GetCombinedPartialTypeDef(nestedTypeDef);
  5030. if (nestedTypeDef == NULL)
  5031. return NULL;
  5032. }
  5033. return ResolveTypeDef(nestedTypeDef, BfPopulateType_IdentityNoRemapAlias);
  5034. }
  5035. return NULL;
  5036. }
  5037. BfTypeDef* BfModule::GetCombinedPartialTypeDef(BfTypeDef* typeDef)
  5038. {
  5039. BF_ASSERT(!typeDef->mIsExplicitPartial);
  5040. if (!typeDef->mIsPartial)
  5041. return typeDef;
  5042. auto result = mSystem->FindTypeDef(typeDef->mFullName.ToString(), (int)typeDef->mGenericParamDefs.size());
  5043. return result;
  5044. }
  5045. BfTypeInstance* BfModule::GetOuterType(BfType* type)
  5046. {
  5047. if (type == NULL)
  5048. return NULL;
  5049. if (type->IsBoxed())
  5050. return GetOuterType(((BfBoxedType*)type)->mElementType);
  5051. auto typeInst = type->ToTypeInstance();
  5052. if ((typeInst == NULL) || (typeInst->mTypeDef->mOuterType == NULL))
  5053. return NULL;
  5054. auto outerTypeDef = typeInst->mTypeDef->mOuterType;
  5055. if (outerTypeDef->mIsPartial)
  5056. {
  5057. outerTypeDef = GetCombinedPartialTypeDef(outerTypeDef);
  5058. if (outerTypeDef == NULL)
  5059. return NULL;
  5060. }
  5061. BfTypeVector typeGenericArguments;
  5062. if (type->IsGenericTypeInstance())
  5063. {
  5064. auto genericType = (BfTypeInstance*)type;
  5065. typeGenericArguments = genericType->mGenericTypeInfo->mTypeGenericArguments;
  5066. }
  5067. BF_ASSERT((intptr)typeGenericArguments.size() >= (intptr)outerTypeDef->mGenericParamDefs.size());
  5068. typeGenericArguments.resize(outerTypeDef->mGenericParamDefs.size());
  5069. //auto outerType = ResolveTypeDef(outerTypeDef, typeGenericArguments, BfPopulateType_Declaration);
  5070. auto outerType = ResolveTypeDef(outerTypeDef, typeGenericArguments, BfPopulateType_Identity);
  5071. if (outerType == NULL)
  5072. return NULL;
  5073. return outerType->ToTypeInstance();
  5074. }
  5075. bool BfModule::IsInnerType(BfType* checkInnerType, BfType* checkOuterType)
  5076. {
  5077. BfType* outerType = GetOuterType(checkInnerType);
  5078. if (outerType == NULL)
  5079. return false;
  5080. if (outerType == checkOuterType)
  5081. return true;
  5082. return IsInnerType(outerType, checkOuterType);
  5083. }
  5084. bool BfModule::IsInnerType(BfTypeDef* checkInnerType, BfTypeDef* checkOuterType)
  5085. {
  5086. BF_ASSERT(!checkOuterType->mIsPartial);
  5087. if (checkInnerType->mNestDepth <= checkOuterType->mNestDepth)
  5088. return false;
  5089. while (true)
  5090. {
  5091. BfTypeDef* outerType = checkInnerType->mOuterType;
  5092. if (outerType == NULL)
  5093. return false;
  5094. if (outerType->mIsPartial)
  5095. outerType = mSystem->GetCombinedPartial(outerType);
  5096. if (outerType == checkOuterType)
  5097. return true;
  5098. checkInnerType = checkInnerType->mOuterType;
  5099. }
  5100. }
  5101. BfType* BfModule::ResolveTypeDef(BfTypeDef* typeDef, const BfTypeVector& genericArgs, BfPopulateType populateType)
  5102. {
  5103. if (typeDef->mGenericParamDefs.size() == 0)
  5104. return ResolveTypeDef(typeDef, populateType);
  5105. if ((typeDef == mCompiler->mArray1TypeDef) || (typeDef == mCompiler->mArray2TypeDef))
  5106. {
  5107. auto arrayInstType = mContext->mArrayTypeInstancePool.Get();
  5108. arrayInstType->mContext = mContext;
  5109. if (typeDef == mCompiler->mArray1TypeDef)
  5110. arrayInstType->mDimensions = 1;
  5111. else
  5112. arrayInstType->mDimensions = 2;
  5113. auto typeRef = mContext->mTypeDefTypeRefPool.Get();
  5114. typeRef->mTypeDef = typeDef;
  5115. delete arrayInstType->mGenericTypeInfo;
  5116. arrayInstType->mGenericTypeInfo = new BfGenericTypeInfo();
  5117. arrayInstType->mTypeDef = typeDef;
  5118. arrayInstType->mGenericTypeInfo->mIsUnspecialized = false;
  5119. arrayInstType->mGenericTypeInfo->mTypeGenericArguments.clear();
  5120. for (auto genericArg : genericArgs)
  5121. {
  5122. arrayInstType->mGenericTypeInfo->mIsUnspecialized |= genericArg->IsGenericParam();
  5123. arrayInstType->mGenericTypeInfo->mTypeGenericArguments.push_back(genericArg);
  5124. }
  5125. if (genericArgs.size() == 0)
  5126. {
  5127. for (int i = 0; i < (int)typeDef->mGenericParamDefs.size(); i++)
  5128. {
  5129. auto genericParamTypeRef = GetGenericParamType(BfGenericParamKind_Type, i);
  5130. arrayInstType->mGenericTypeInfo->mTypeGenericArguments.push_back(genericParamTypeRef);
  5131. arrayInstType->mGenericTypeInfo->mIsUnspecialized = true;
  5132. }
  5133. }
  5134. auto resolvedType = ResolveType(arrayInstType, populateType);
  5135. if (resolvedType != arrayInstType)
  5136. {
  5137. delete arrayInstType->mGenericTypeInfo;
  5138. arrayInstType->mGenericTypeInfo = NULL;
  5139. mContext->mArrayTypeInstancePool.GiveBack(arrayInstType);
  5140. mContext->mTypeDefTypeRefPool.GiveBack(typeRef);
  5141. }
  5142. BF_ASSERT((resolvedType == NULL) || resolvedType->IsTypeInstance() || resolvedType->IsPrimitiveType());
  5143. return resolvedType;
  5144. }
  5145. BfTypeInstance* genericInstType;
  5146. if (typeDef->mTypeCode == BfTypeCode_TypeAlias)
  5147. genericInstType = mContext->mAliasTypePool.Get();
  5148. else
  5149. genericInstType = mContext->mGenericTypeInstancePool.Get();
  5150. delete genericInstType->mGenericTypeInfo;
  5151. genericInstType->mGenericTypeInfo = new BfGenericTypeInfo();
  5152. BF_ASSERT(genericInstType->mGenericTypeInfo->mGenericParams.size() == 0);
  5153. BF_ASSERT((genericInstType->mRebuildFlags & BfTypeRebuildFlag_AddedToWorkList) == 0);
  5154. genericInstType->mRebuildFlags = (BfTypeRebuildFlags)(genericInstType->mRebuildFlags & ~BfTypeRebuildFlag_InTempPool);
  5155. genericInstType->mContext = mContext;
  5156. auto typeRef = mContext->mTypeDefTypeRefPool.Get();
  5157. typeRef->mTypeDef = typeDef;
  5158. genericInstType->mTypeDef = typeDef;
  5159. genericInstType->mGenericTypeInfo->mIsUnspecialized = false;
  5160. genericInstType->mGenericTypeInfo->mTypeGenericArguments.clear();
  5161. genericInstType->mTypeFailed = false;
  5162. for (auto genericArg : genericArgs)
  5163. {
  5164. genericInstType->mGenericTypeInfo->mIsUnspecialized |= genericArg->IsGenericParam();
  5165. genericInstType->mGenericTypeInfo->mTypeGenericArguments.push_back(genericArg);
  5166. }
  5167. if (genericArgs.size() == 0)
  5168. {
  5169. for (int i = 0; i < (int)typeDef->mGenericParamDefs.size(); i++)
  5170. {
  5171. auto genericParamTypeRef = GetGenericParamType(BfGenericParamKind_Type, i);
  5172. genericInstType->mGenericTypeInfo->mTypeGenericArguments.push_back(genericParamTypeRef);
  5173. genericInstType->mGenericTypeInfo->mIsUnspecialized = true;
  5174. }
  5175. }
  5176. BfType* resolvedType = NULL;
  5177. bool failed = false;
  5178. // if (typeDef->mTypeCode == BfTypeCode_TypeAlias)
  5179. // {
  5180. // auto aliasType = (BfGenericTypeAliasType*)genericInstType;
  5181. // aliasType->mAliasToType = NULL;
  5182. // auto typeAliasDecl = (BfTypeAliasDeclaration*)typeDef->mTypeDeclaration;
  5183. // SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, aliasType);
  5184. // SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, NULL);
  5185. // BfTypeState typeState(mCurTypeInstance, mContext->mCurTypeState);
  5186. // typeState.mCurTypeDef = typeDef;
  5187. // SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
  5188. // if (typeAliasDecl->mAliasToType != NULL)
  5189. // aliasType->mAliasToType = ResolveTypeRef(typeAliasDecl->mAliasToType);
  5190. //
  5191. // resolvedType = ResolveType(genericInstType, BfPopulateType_IdentityNoRemapAlias);
  5192. // if ((resolvedType != NULL) && (populateType >= BfPopulateType_Declaration))
  5193. // PopulateType(resolvedType, populateType);
  5194. // }
  5195. // else
  5196. {
  5197. resolvedType = ResolveType(genericInstType, populateType);
  5198. }
  5199. if (resolvedType != genericInstType)
  5200. {
  5201. BF_ASSERT(genericInstType->mGenericTypeInfo->mGenericParams.size() == 0);
  5202. BF_ASSERT((genericInstType->mRebuildFlags & BfTypeRebuildFlag_AddedToWorkList) == 0);
  5203. genericInstType->mRebuildFlags = (BfTypeRebuildFlags)(genericInstType->mRebuildFlags | BfTypeRebuildFlag_InTempPool);
  5204. delete genericInstType->mGenericTypeInfo;
  5205. genericInstType->mGenericTypeInfo = NULL;
  5206. if (typeDef->mTypeCode == BfTypeCode_TypeAlias)
  5207. mContext->mAliasTypePool.GiveBack((BfTypeAliasType*)genericInstType);
  5208. else
  5209. mContext->mGenericTypeInstancePool.GiveBack(genericInstType);
  5210. mContext->mTypeDefTypeRefPool.GiveBack(typeRef);
  5211. }
  5212. BF_ASSERT((resolvedType == NULL) || resolvedType->IsTypeInstance() || resolvedType->IsPrimitiveType());
  5213. return resolvedType;
  5214. }
  5215. int checkIdx = 0;
  5216. BfTypeDef* BfModule::ResolveGenericInstanceDef(BfGenericInstanceTypeRef* genericTypeRef, BfType** outType)
  5217. {
  5218. if (outType != NULL)
  5219. *outType = NULL;
  5220. BfTypeReference* typeRef = genericTypeRef->mElementType;
  5221. int numGenericParams = genericTypeRef->GetGenericArgCount();
  5222. BfTypeDef* curTypeDef = NULL;
  5223. if (mCurTypeInstance != NULL)
  5224. curTypeDef = mCurTypeInstance->mTypeDef;
  5225. if (auto directTypeDef = BfNodeDynCast<BfDirectTypeReference>(typeRef))
  5226. {
  5227. auto typeInst = directTypeDef->mType->ToTypeInstance();
  5228. return typeInst->mTypeDef;
  5229. }
  5230. auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(typeRef);
  5231. auto directStrTypeDef = BfNodeDynCastExact<BfDirectStrTypeReference>(typeRef);
  5232. if ((namedTypeRef != NULL) || (directStrTypeDef != NULL))
  5233. {
  5234. BfTypeLookupError error;
  5235. error.mRefNode = typeRef;
  5236. BfTypeDef* typeDef = FindTypeDef(typeRef, NULL, &error, numGenericParams);
  5237. if (typeDef != NULL)
  5238. {
  5239. BfAutoComplete* autoComplete = NULL;
  5240. if (mCompiler->IsAutocomplete())
  5241. autoComplete = mCompiler->mResolvePassData->mAutoComplete;
  5242. if ((autoComplete != NULL) && (autoComplete->mIsGetDefinition) && (autoComplete->IsAutocompleteNode(typeRef)))
  5243. {
  5244. if ((autoComplete->mDefMethod == NULL) && (autoComplete->mDefField == NULL) &&
  5245. (autoComplete->mDefProp == NULL) && (typeDef->mTypeDeclaration != NULL))
  5246. {
  5247. autoComplete->mDefType = typeDef;
  5248. autoComplete->SetDefinitionLocation(typeDef->mTypeDeclaration->mNameNode);
  5249. }
  5250. }
  5251. if (mCompiler->mResolvePassData != NULL)
  5252. mCompiler->mResolvePassData->HandleTypeReference(typeRef, typeDef);
  5253. return typeDef;
  5254. }
  5255. if (mCurTypeInstance != NULL)
  5256. {
  5257. bool wasGenericParam = false;
  5258. // Check generics first
  5259. if (typeRef->IsA<BfNamedTypeReference>())
  5260. {
  5261. String findName = typeRef->ToString();
  5262. if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsGenericTypeInstance()))
  5263. {
  5264. auto genericTypeInst = (BfTypeInstance*)mCurTypeInstance;
  5265. for (int genericParamIdx = 0; genericParamIdx < (int)curTypeDef->mGenericParamDefs.size(); genericParamIdx++)
  5266. {
  5267. String genericName = curTypeDef->mGenericParamDefs[genericParamIdx]->mName;
  5268. if (genericName == findName)
  5269. wasGenericParam = true;
  5270. }
  5271. }
  5272. if (mCurMethodInstance != NULL)
  5273. {
  5274. for (int genericParamIdx = 0; genericParamIdx < (int)mCurMethodInstance->mMethodDef->mGenericParams.size(); genericParamIdx++)
  5275. {
  5276. String genericName = mCurMethodInstance->mMethodDef->mGenericParams[genericParamIdx]->mName;
  5277. if (genericName == findName)
  5278. wasGenericParam = true;
  5279. }
  5280. }
  5281. }
  5282. if (wasGenericParam)
  5283. Fail("Cannot use generic param as generic instance type", typeRef);
  5284. }
  5285. if (typeDef == NULL)
  5286. {
  5287. TypeRefNotFound(typeRef);
  5288. return NULL;
  5289. }
  5290. }
  5291. if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(typeRef))
  5292. {
  5293. BfAutoParentNodeEntry autoParentNodeEntry(this, genericTypeRef);
  5294. auto type = ResolveTypeRef(qualifiedTypeRef, BfPopulateType_TypeDef, BfResolveTypeRefFlag_None, numGenericParams);
  5295. if (type == NULL)
  5296. return NULL;
  5297. if (outType != NULL)
  5298. *outType = type;
  5299. auto typeInst = type->ToTypeInstance();
  5300. if (typeInst != NULL)
  5301. return typeInst->mTypeDef;
  5302. }
  5303. Fail("Invalid generic type", typeRef);
  5304. return NULL;
  5305. }
  5306. BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* typeGenericArguments, BfTypeVector* methodGenericArguments, bool allowFail)
  5307. {
  5308. if (unspecializedType->IsGenericParam())
  5309. {
  5310. auto genericParam = (BfGenericParamType*)unspecializedType;
  5311. if ((genericParam->mGenericParamKind == BfGenericParamKind_Type) && (typeGenericArguments != NULL))
  5312. {
  5313. if (genericParam->mGenericParamIdx < (int)typeGenericArguments->size())
  5314. return (*typeGenericArguments)[genericParam->mGenericParamIdx];
  5315. BF_ASSERT(allowFail);
  5316. }
  5317. if ((genericParam->mGenericParamKind == BfGenericParamKind_Method) && (methodGenericArguments != NULL))
  5318. {
  5319. if (genericParam->mGenericParamIdx < (int)methodGenericArguments->size())
  5320. return (*methodGenericArguments)[genericParam->mGenericParamIdx];
  5321. BF_ASSERT(allowFail);
  5322. }
  5323. return unspecializedType;
  5324. }
  5325. if (!unspecializedType->IsUnspecializedType())
  5326. return unspecializedType;
  5327. if (unspecializedType->IsUnknownSizedArray())
  5328. {
  5329. auto* arrayType = (BfUnknownSizedArrayType*)unspecializedType;
  5330. auto elementType = ResolveGenericType(arrayType->mElementType, typeGenericArguments, methodGenericArguments, allowFail);
  5331. if (elementType == NULL)
  5332. return NULL;
  5333. if (elementType->IsVar())
  5334. return elementType;
  5335. auto sizeType = ResolveGenericType(arrayType->mElementCountSource, typeGenericArguments, methodGenericArguments, allowFail);
  5336. if (sizeType == NULL)
  5337. return NULL;
  5338. if (sizeType->IsConstExprValue())
  5339. {
  5340. return CreateSizedArrayType(elementType, ((BfConstExprValueType*)sizeType)->mValue.mInt32);
  5341. }
  5342. return CreateUnknownSizedArrayType(elementType, sizeType);
  5343. }
  5344. if (unspecializedType->IsSizedArray())
  5345. {
  5346. auto* arrayType = (BfSizedArrayType*)unspecializedType;
  5347. auto elementType = ResolveGenericType(arrayType->mElementType, typeGenericArguments, methodGenericArguments, allowFail);
  5348. if (elementType == NULL)
  5349. return NULL;
  5350. if (elementType->IsVar())
  5351. return elementType;
  5352. return CreateSizedArrayType(elementType, (int)arrayType->mElementCount);
  5353. }
  5354. if (unspecializedType->IsRef())
  5355. {
  5356. auto refType = (BfRefType*)unspecializedType;
  5357. auto elementType = ResolveGenericType(refType->GetUnderlyingType(), typeGenericArguments, methodGenericArguments, allowFail);
  5358. if (elementType == NULL)
  5359. return NULL;
  5360. if (elementType->IsVar())
  5361. return elementType;
  5362. elementType = FixIntUnknown(elementType);
  5363. return CreateRefType(elementType, refType->mRefKind);
  5364. }
  5365. if (unspecializedType->IsPointer())
  5366. {
  5367. auto ptrType = (BfPointerType*)unspecializedType;
  5368. auto elementType = ResolveGenericType(ptrType->GetUnderlyingType(), typeGenericArguments, methodGenericArguments, allowFail);
  5369. if (elementType == NULL)
  5370. return NULL;
  5371. if (elementType->IsVar())
  5372. return elementType;
  5373. return CreatePointerType(elementType);
  5374. }
  5375. if (unspecializedType->IsArray())
  5376. {
  5377. auto arrayType = (BfArrayType*)unspecializedType;
  5378. auto elementType = ResolveGenericType(arrayType->GetUnderlyingType(), typeGenericArguments, methodGenericArguments, allowFail);
  5379. if (elementType == NULL)
  5380. return NULL;
  5381. if (elementType->IsVar())
  5382. return elementType;
  5383. return CreateArrayType(elementType, arrayType->mDimensions);
  5384. }
  5385. if (unspecializedType->IsTuple())
  5386. {
  5387. bool wantGeneric = false;
  5388. bool isUnspecialized = false;
  5389. auto unspecializedTupleType = (BfTypeInstance*)unspecializedType;
  5390. auto unspecializedGenericTupleType = unspecializedTupleType->ToGenericTypeInstance();
  5391. Array<String> fieldNames;
  5392. BfTypeVector fieldTypes;
  5393. bool hadChange = false;
  5394. for (auto& fieldInstance : unspecializedTupleType->mFieldInstances)
  5395. {
  5396. fieldNames.push_back(fieldInstance.GetFieldDef()->mName);
  5397. auto origGenericArg = fieldInstance.mResolvedType;
  5398. auto newGenericArg = ResolveGenericType(origGenericArg, typeGenericArguments, methodGenericArguments, allowFail);
  5399. if (newGenericArg == NULL)
  5400. return NULL;
  5401. if (newGenericArg->IsVar())
  5402. return newGenericArg;
  5403. if (newGenericArg->IsGenericParam())
  5404. wantGeneric = true;
  5405. if (newGenericArg->IsUnspecializedType())
  5406. isUnspecialized = true;
  5407. if (newGenericArg->IsVar())
  5408. wantGeneric = mContext->mBfObjectType;
  5409. //wantGeneric = true;
  5410. if (newGenericArg != origGenericArg)
  5411. hadChange = true;
  5412. fieldTypes.push_back(newGenericArg);
  5413. }
  5414. if (!hadChange)
  5415. return unspecializedType;
  5416. if (unspecializedGenericTupleType == NULL)
  5417. wantGeneric = false;
  5418. auto baseType = (BfTypeInstance*)ResolveTypeDef(mContext->mCompiler->mValueTypeTypeDef);
  5419. BfTypeInstance* tupleType = NULL;
  5420. if (wantGeneric)
  5421. {
  5422. Array<BfType*> genericArgs;
  5423. for (int genericArgIdx = 0; genericArgIdx < (int)unspecializedGenericTupleType->mGenericTypeInfo->mTypeGenericArguments.size(); genericArgIdx++)
  5424. {
  5425. BfType* resolvedArg = unspecializedGenericTupleType->mGenericTypeInfo->mTypeGenericArguments[genericArgIdx];
  5426. if (resolvedArg->IsUnspecializedType())
  5427. {
  5428. resolvedArg = ResolveGenericType(resolvedArg, typeGenericArguments, methodGenericArguments, allowFail);
  5429. if (resolvedArg == NULL)
  5430. return NULL;
  5431. if (resolvedArg->IsVar())
  5432. return resolvedArg;
  5433. }
  5434. genericArgs.push_back(resolvedArg);
  5435. }
  5436. auto actualTupleType = mContext->mTupleTypePool.Get();
  5437. delete actualTupleType->mGenericTypeInfo;
  5438. actualTupleType->mGenericTypeInfo = new BfGenericTypeInfo();
  5439. actualTupleType->mGenericTypeInfo->mIsUnspecialized = false;
  5440. actualTupleType->mGenericTypeInfo->mIsUnspecializedVariation = false;
  5441. actualTupleType->mGenericTypeInfo->mTypeGenericArguments = genericArgs;
  5442. for (int genericArgIdx = 0; genericArgIdx < (int)unspecializedGenericTupleType->mGenericTypeInfo->mTypeGenericArguments.size(); genericArgIdx++)
  5443. {
  5444. auto typeGenericArg = genericArgs[genericArgIdx];
  5445. if ((typeGenericArg->IsGenericParam()) || (typeGenericArg->IsUnspecializedType()))
  5446. actualTupleType->mGenericTypeInfo->mIsUnspecialized = true;
  5447. actualTupleType->mGenericTypeInfo->mGenericParams.push_back(unspecializedGenericTupleType->mGenericTypeInfo->mGenericParams[genericArgIdx]->AddRef());
  5448. }
  5449. CheckUnspecializedGenericType(actualTupleType, BfPopulateType_Identity);
  5450. if (isUnspecialized)
  5451. {
  5452. actualTupleType->mGenericTypeInfo->mIsUnspecialized = true;
  5453. actualTupleType->mGenericTypeInfo->mIsUnspecializedVariation = true;
  5454. }
  5455. actualTupleType->mIsUnspecializedType = actualTupleType->mGenericTypeInfo->mIsUnspecialized;
  5456. actualTupleType->mIsUnspecializedTypeVariation = actualTupleType->mGenericTypeInfo->mIsUnspecializedVariation;
  5457. actualTupleType->Init(baseType->mTypeDef->mProject, baseType);
  5458. for (int fieldIdx = 0; fieldIdx < (int)fieldTypes.size(); fieldIdx++)
  5459. {
  5460. String fieldName = fieldNames[fieldIdx];
  5461. BfFieldDef* fieldDef = actualTupleType->AddField(fieldName);
  5462. }
  5463. tupleType = actualTupleType;
  5464. }
  5465. else
  5466. {
  5467. auto actualTupleType = new BfTupleType();
  5468. actualTupleType->mIsUnspecializedType = isUnspecialized;
  5469. actualTupleType->mIsUnspecializedTypeVariation = isUnspecialized;
  5470. actualTupleType->Init(baseType->mTypeDef->mProject, baseType);
  5471. for (int fieldIdx = 0; fieldIdx < (int)fieldTypes.size(); fieldIdx++)
  5472. {
  5473. String fieldName = fieldNames[fieldIdx];
  5474. BfFieldDef* fieldDef = actualTupleType->AddField(fieldName);
  5475. }
  5476. tupleType = actualTupleType;
  5477. }
  5478. tupleType->mContext = mContext;
  5479. tupleType->mFieldInstances.Resize(fieldTypes.size());
  5480. for (int fieldIdx = 0; fieldIdx < (int)fieldTypes.size(); fieldIdx++)
  5481. {
  5482. BfFieldInstance* fieldInstance = (BfFieldInstance*)&tupleType->mFieldInstances[fieldIdx];
  5483. fieldInstance->mFieldIdx = fieldIdx;
  5484. fieldInstance->SetResolvedType(fieldTypes[fieldIdx]);
  5485. fieldInstance->mOwner = tupleType;
  5486. }
  5487. bool failed = false;
  5488. BfType* resolvedType = NULL;
  5489. if (!failed)
  5490. resolvedType = ResolveType(tupleType, BfPopulateType_Identity);
  5491. if (resolvedType != tupleType)
  5492. {
  5493. delete tupleType->mGenericTypeInfo;
  5494. tupleType->mGenericTypeInfo = NULL;
  5495. mContext->mTupleTypePool.GiveBack((BfTupleType*)tupleType);
  5496. }
  5497. BF_ASSERT((resolvedType == NULL) || resolvedType->IsTypeInstance() || resolvedType->IsPrimitiveType());
  5498. return resolvedType;
  5499. }
  5500. if ((unspecializedType->IsDelegateFromTypeRef()) || (unspecializedType->IsFunctionFromTypeRef()))
  5501. {
  5502. BfTypeInstance* unspecializedDelegateType = (BfTypeInstance*)unspecializedType;
  5503. BfTypeInstance* unspecializedGenericDelegateType = unspecializedType->ToGenericTypeInstance();
  5504. BfDelegateInfo* unspecializedDelegateInfo = unspecializedType->GetDelegateInfo();
  5505. bool wantGeneric = false;
  5506. bool isUnspecialized = false;
  5507. auto _CheckType = [&](BfType* type)
  5508. {
  5509. if (type->IsGenericParam())
  5510. wantGeneric = true;
  5511. if (type->IsUnspecializedType())
  5512. isUnspecialized = true;
  5513. };
  5514. bool failed = false;
  5515. bool hasTypeGenerics = false;
  5516. auto returnType = ResolveGenericType(unspecializedDelegateInfo->mReturnType, typeGenericArguments, methodGenericArguments, allowFail);
  5517. if (returnType == NULL)
  5518. return NULL;
  5519. if (returnType->IsVar())
  5520. return returnType;
  5521. _CheckType(returnType);
  5522. if (returnType->IsGenericParam())
  5523. hasTypeGenerics |= ((BfGenericParamType*)returnType)->mGenericParamKind == BfGenericParamKind_Type;
  5524. Array<BfType*> paramTypes;
  5525. for (auto param : unspecializedDelegateInfo->mParams)
  5526. {
  5527. auto paramType = ResolveGenericType(param, typeGenericArguments, methodGenericArguments, allowFail);
  5528. if (paramType == NULL)
  5529. return NULL;
  5530. if (paramType->IsVar())
  5531. return paramType;
  5532. paramTypes.Add(paramType);
  5533. _CheckType(paramType);
  5534. }
  5535. if (unspecializedGenericDelegateType == NULL)
  5536. wantGeneric = false;
  5537. BfTypeInstance* delegateType = NULL;
  5538. auto baseDelegateType = ResolveTypeDef(mCompiler->mDelegateTypeDef)->ToTypeInstance();
  5539. if (wantGeneric)
  5540. {
  5541. Array<BfType*> genericArgs;
  5542. for (int genericArgIdx = 0; genericArgIdx < (int)unspecializedGenericDelegateType->mGenericTypeInfo->mTypeGenericArguments.size(); genericArgIdx++)
  5543. {
  5544. BfType* resolvedArg = unspecializedGenericDelegateType->mGenericTypeInfo->mTypeGenericArguments[genericArgIdx];
  5545. if (resolvedArg->IsUnspecializedType())
  5546. {
  5547. resolvedArg = ResolveGenericType(resolvedArg, typeGenericArguments, methodGenericArguments, allowFail);
  5548. if (resolvedArg == NULL)
  5549. return NULL;
  5550. if (resolvedArg->IsVar())
  5551. return resolvedArg;
  5552. }
  5553. genericArgs.push_back(resolvedArg);
  5554. }
  5555. auto dlgType = mContext->mDelegateTypePool.Get();
  5556. delete dlgType->mGenericTypeInfo;
  5557. dlgType->mGenericTypeInfo = new BfGenericTypeInfo();
  5558. dlgType->mGenericTypeInfo->mIsUnspecialized = false;
  5559. dlgType->mGenericTypeInfo->mIsUnspecializedVariation = false;
  5560. dlgType->mGenericTypeInfo->mTypeGenericArguments = genericArgs;
  5561. for (int genericArgIdx = 0; genericArgIdx < (int)unspecializedGenericDelegateType->mGenericTypeInfo->mTypeGenericArguments.size(); genericArgIdx++)
  5562. {
  5563. auto typeGenericArg = genericArgs[genericArgIdx];
  5564. if ((typeGenericArg->IsGenericParam()) || (typeGenericArg->IsUnspecializedType()))
  5565. dlgType->mGenericTypeInfo->mIsUnspecialized = true;
  5566. dlgType->mGenericTypeInfo->mGenericParams.push_back(unspecializedGenericDelegateType->mGenericTypeInfo->mGenericParams[genericArgIdx]->AddRef());
  5567. }
  5568. CheckUnspecializedGenericType(dlgType, BfPopulateType_Identity);
  5569. if (isUnspecialized)
  5570. {
  5571. dlgType->mGenericTypeInfo->mIsUnspecialized = true;
  5572. dlgType->mGenericTypeInfo->mIsUnspecializedVariation = true;
  5573. }
  5574. dlgType->mIsUnspecializedType = dlgType->mGenericTypeInfo->mIsUnspecialized;
  5575. dlgType->mIsUnspecializedTypeVariation = dlgType->mGenericTypeInfo->mIsUnspecializedVariation;
  5576. delegateType = dlgType;
  5577. }
  5578. else
  5579. {
  5580. auto dlgType = mContext->mDelegateTypePool.Get();
  5581. dlgType->mIsUnspecializedType = isUnspecialized;
  5582. dlgType->mIsUnspecializedTypeVariation = isUnspecialized;
  5583. delegateType = dlgType;
  5584. }
  5585. delete delegateType->mTypeDef;
  5586. delegateType->mTypeDef = NULL;
  5587. BfDelegateInfo* delegateInfo = delegateType->GetDelegateInfo();
  5588. delegateInfo->mParams.Clear();
  5589. BfTypeDef* typeDef = new BfTypeDef();
  5590. typeDef->mProject = baseDelegateType->mTypeDef->mProject;
  5591. typeDef->mSystem = mCompiler->mSystem;
  5592. typeDef->mName = mSystem->mEmptyAtom;
  5593. typeDef->mTypeCode = unspecializedDelegateType->mTypeDef->mTypeCode;
  5594. typeDef->mIsDelegate = unspecializedDelegateType->mTypeDef->mIsDelegate;
  5595. typeDef->mIsFunction = unspecializedDelegateType->mTypeDef->mIsFunction;
  5596. BfMethodDef* methodDef = new BfMethodDef();
  5597. methodDef->mDeclaringType = typeDef;
  5598. methodDef->mName = "Invoke";
  5599. methodDef->mProtection = BfProtection_Public;
  5600. methodDef->mIdx = 0;
  5601. methodDef->mIsStatic = !typeDef->mIsDelegate;
  5602. auto directTypeRef = BfAstNode::ZeroedAlloc<BfDirectTypeReference>();
  5603. delegateInfo->mDirectAllocNodes.push_back(directTypeRef);
  5604. if (typeDef->mIsDelegate)
  5605. directTypeRef->Init(delegateType);
  5606. else
  5607. directTypeRef->Init(ResolveTypeDef(mCompiler->mFunctionTypeDef));
  5608. typeDef->mBaseTypes.push_back(directTypeRef);
  5609. directTypeRef = BfAstNode::ZeroedAlloc<BfDirectTypeReference>();
  5610. delegateInfo->mDirectAllocNodes.push_back(directTypeRef);
  5611. directTypeRef->Init(returnType);
  5612. methodDef->mReturnTypeRef = directTypeRef;
  5613. delegateInfo->mReturnType = returnType;
  5614. BfMethodDef* unspecializedInvokeMethodDef = unspecializedDelegateType->mTypeDef->GetMethodByName("Invoke");
  5615. int paramIdx = 0;
  5616. for (int paramIdx = 0; paramIdx < (int)paramTypes.size(); paramIdx++)
  5617. {
  5618. auto paramType = paramTypes[paramIdx];
  5619. BfParameterDef* unspecializedParamDef = unspecializedInvokeMethodDef->mParams[paramIdx];
  5620. if (!paramType->IsReified())
  5621. delegateType->mIsReified = false;
  5622. auto directTypeRef = BfAstNode::ZeroedAlloc<BfDirectTypeReference>();
  5623. delegateInfo->mDirectAllocNodes.push_back(directTypeRef);
  5624. directTypeRef->Init(paramType);
  5625. BfParameterDef* paramDef = new BfParameterDef();
  5626. paramDef->mTypeRef = directTypeRef;
  5627. paramDef->mName = unspecializedParamDef->mName;
  5628. methodDef->mParams.push_back(paramDef);
  5629. paramIdx++;
  5630. delegateInfo->mParams.Add(paramType);
  5631. }
  5632. typeDef->mMethods.push_back(methodDef);
  5633. //
  5634. BfDefBuilder::AddMethod(typeDef, BfMethodType_Ctor, BfProtection_Public, false, "");
  5635. if (typeDef->mIsDelegate)
  5636. BfDefBuilder::AddDynamicCastMethods(typeDef);
  5637. delegateType->mContext = mContext;
  5638. delegateType->mTypeDef = typeDef;
  5639. BfType* resolvedType = NULL;
  5640. if (!failed)
  5641. resolvedType = ResolveType(delegateType, BfPopulateType_Identity);
  5642. if (resolvedType == delegateType)
  5643. {
  5644. AddDependency(directTypeRef->mType, delegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue);
  5645. for (auto paramType : paramTypes)
  5646. AddDependency(paramType, delegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue);
  5647. }
  5648. else
  5649. {
  5650. delete delegateType->mGenericTypeInfo;
  5651. delegateType->mGenericTypeInfo = NULL;
  5652. mContext->mDelegateTypePool.GiveBack((BfDelegateType*)delegateType);
  5653. }
  5654. BF_ASSERT((resolvedType == NULL) || resolvedType->IsTypeInstance() || resolvedType->IsPrimitiveType());
  5655. return resolvedType;
  5656. }
  5657. if (unspecializedType->IsGenericTypeInstance())
  5658. {
  5659. auto genericTypeInst = (BfTypeInstance*)unspecializedType;
  5660. BfTypeVector genericArgs;
  5661. for (auto genericArg : genericTypeInst->mGenericTypeInfo->mTypeGenericArguments)
  5662. {
  5663. if (genericArg->IsUnspecializedType())
  5664. {
  5665. auto resolvedArg = ResolveGenericType(genericArg, typeGenericArguments, methodGenericArguments, allowFail);
  5666. if (resolvedArg == NULL)
  5667. return NULL;
  5668. if (resolvedArg->IsVar())
  5669. return resolvedArg;
  5670. genericArgs.push_back(resolvedArg);
  5671. }
  5672. else
  5673. genericArgs.push_back(genericArg);
  5674. }
  5675. auto resolvedType = ResolveTypeDef(genericTypeInst->mTypeDef, genericArgs, BfPopulateType_BaseType);
  5676. BfTypeInstance* specializedType = NULL;
  5677. if (resolvedType != NULL)
  5678. specializedType = resolvedType->ToGenericTypeInstance();
  5679. if (specializedType != NULL)
  5680. {
  5681. if (specializedType->mGenericTypeInfo->mHadValidateErrors)
  5682. return NULL;
  5683. }
  5684. return specializedType;
  5685. }
  5686. return unspecializedType;
  5687. }
  5688. BfType* BfModule::ResolveType(BfType* lookupType, BfPopulateType populateType)
  5689. {
  5690. BfResolvedTypeSet::LookupContext lookupCtx;
  5691. lookupCtx.mModule = this;
  5692. BfResolvedTypeSet::Entry* resolvedEntry = NULL;
  5693. bool inserted = mContext->mResolvedTypes.Insert(lookupType, &lookupCtx, &resolvedEntry);
  5694. if (!inserted)
  5695. {
  5696. auto resolvedTypeRef = resolvedEntry->mValue;
  5697. PopulateType(resolvedTypeRef, populateType);
  5698. return resolvedTypeRef;
  5699. }
  5700. if (lookupType->IsGenericTypeInstance())
  5701. CheckUnspecializedGenericType((BfTypeInstance*)lookupType, populateType);
  5702. if (lookupType->IsTuple())
  5703. {
  5704. auto tupleType = (BfTupleType*)lookupType;
  5705. tupleType->Finish();
  5706. }
  5707. resolvedEntry->mValue = lookupType;
  5708. InitType(lookupType, populateType);
  5709. return lookupType;
  5710. }
  5711. bool BfModule::IsUnboundGeneric(BfType* type)
  5712. {
  5713. if (type->IsVar())
  5714. return true;
  5715. if (!type->IsGenericParam())
  5716. return false;
  5717. auto genericParamInst = GetGenericParamInstance((BfGenericParamType*)type);
  5718. return (genericParamInst->mGenericParamFlags & BfGenericParamFlag_Var) != 0;
  5719. }
  5720. BfGenericParamInstance* BfModule::GetGenericTypeParamInstance(int genericParamIdx)
  5721. {
  5722. // When we're evaluating a method, make sure the params refer back to that method context
  5723. auto curTypeInstance = mCurTypeInstance;
  5724. if (mCurMethodInstance != NULL)
  5725. curTypeInstance = mCurMethodInstance->mMethodInstanceGroup->mOwner;
  5726. BfTypeInstance* genericTypeInst = curTypeInstance->ToGenericTypeInstance();
  5727. if ((genericTypeInst->IsIncomplete()) && (genericTypeInst->mGenericTypeInfo->mGenericParams.size() == 0))
  5728. {
  5729. // Set this to NULL so we don't recurse infinitely
  5730. SetAndRestoreValue<BfTypeInstance*> prevTypeInst(mCurTypeInstance, NULL);
  5731. PopulateType(genericTypeInst, BfPopulateType_Declaration);
  5732. }
  5733. if (genericParamIdx >= (int)genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size())
  5734. {
  5735. // Extern constraints should always be directly used - they don't get extended
  5736. return genericTypeInst->mGenericTypeInfo->mGenericParams[genericParamIdx];
  5737. }
  5738. if (genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo != NULL)
  5739. {
  5740. auto activeTypeDef = GetActiveTypeDef(NULL, true);
  5741. if ((activeTypeDef->mTypeDeclaration != genericTypeInst->mTypeDef->mTypeDeclaration) && (activeTypeDef->IsExtension()))
  5742. {
  5743. BfTypeDef* lookupTypeDef = activeTypeDef;
  5744. while (lookupTypeDef->mNestDepth > genericTypeInst->mTypeDef->mNestDepth)
  5745. lookupTypeDef = lookupTypeDef->mOuterType;
  5746. BfGenericExtensionEntry* genericExEntry;
  5747. if (genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo->mExtensionMap.TryGetValue(lookupTypeDef, &genericExEntry))
  5748. {
  5749. return genericExEntry->mGenericParams[genericParamIdx];
  5750. }
  5751. else
  5752. {
  5753. if ((mCompiler->mResolvePassData == NULL) || (mCompiler->mResolvePassData->mAutoComplete == NULL))
  5754. {
  5755. BFMODULE_FATAL(this, "Invalid GetGenericParamInstance with extension");
  5756. }
  5757. }
  5758. }
  5759. }
  5760. BF_ASSERT(genericTypeInst != NULL);
  5761. return genericTypeInst->mGenericTypeInfo->mGenericParams[genericParamIdx];
  5762. }
  5763. void BfModule::GetActiveTypeGenericParamInstances(SizedArray<BfGenericParamInstance*, 4>& genericParamInstances)
  5764. {
  5765. // When we're evaluating a method, make sure the params refer back to that method context
  5766. auto curTypeInstance = mCurTypeInstance;
  5767. if (mCurMethodInstance != NULL)
  5768. curTypeInstance = mCurMethodInstance->mMethodInstanceGroup->mOwner;
  5769. BfTypeInstance* genericTypeInst = curTypeInstance->ToGenericTypeInstance();
  5770. if ((genericTypeInst->IsIncomplete()) && (genericTypeInst->mGenericTypeInfo->mGenericParams.size() == 0))
  5771. {
  5772. // Set this to NULL so we don't recurse infinitely
  5773. SetAndRestoreValue<BfTypeInstance*> prevTypeInst(mCurTypeInstance, NULL);
  5774. PopulateType(genericTypeInst, BfPopulateType_Declaration);
  5775. }
  5776. if (genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo != NULL)
  5777. {
  5778. auto activeTypeDef = GetActiveTypeDef(NULL, true);
  5779. if ((activeTypeDef->mTypeDeclaration != genericTypeInst->mTypeDef->mTypeDeclaration) && (activeTypeDef->IsExtension()))
  5780. {
  5781. BfTypeDef* lookupTypeDef = activeTypeDef;
  5782. while (lookupTypeDef->mNestDepth > genericTypeInst->mTypeDef->mNestDepth)
  5783. lookupTypeDef = lookupTypeDef->mOuterType;
  5784. BfGenericExtensionEntry* genericExEntry;
  5785. if (genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo->mExtensionMap.TryGetValue(lookupTypeDef, &genericExEntry))
  5786. {
  5787. for (auto entry : genericExEntry->mGenericParams)
  5788. genericParamInstances.Add(entry);
  5789. auto genericTypeInfo = genericTypeInst->mGenericTypeInfo;
  5790. // Add root extern constraints - they don't get extended
  5791. for (int genericParamIdx = (int)genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size(); genericParamIdx < genericTypeInst->mGenericTypeInfo->mGenericParams.size(); genericParamIdx++)
  5792. genericParamInstances.Add(genericTypeInst->mGenericTypeInfo->mGenericParams[genericParamIdx]);
  5793. return;
  5794. }
  5795. else
  5796. {
  5797. if ((mCompiler->mResolvePassData == NULL) || (mCompiler->mResolvePassData->mAutoComplete == NULL))
  5798. {
  5799. BFMODULE_FATAL(this, "Invalid GetGenericParamInstance with extension");
  5800. }
  5801. }
  5802. }
  5803. }
  5804. BF_ASSERT(genericTypeInst != NULL);
  5805. for (auto entry : genericTypeInst->mGenericTypeInfo->mGenericParams)
  5806. genericParamInstances.Add(entry);
  5807. }
  5808. BfGenericParamInstance* BfModule::GetGenericParamInstance(BfGenericParamType* type)
  5809. {
  5810. if (type->mGenericParamKind == BfGenericParamKind_Method)
  5811. {
  5812. return mCurMethodInstance->mMethodInfoEx->mGenericParams[type->mGenericParamIdx];
  5813. }
  5814. return GetGenericTypeParamInstance(type->mGenericParamIdx);
  5815. }
  5816. BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTypeRef, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags)
  5817. {
  5818. if (mCompiler->mIsResolveOnly)
  5819. {
  5820. bool isGetDefinition = false;
  5821. BfAutoComplete* autoComplete = NULL;
  5822. if (mCompiler->IsAutocomplete())
  5823. {
  5824. autoComplete = mCompiler->mResolvePassData->mAutoComplete;
  5825. isGetDefinition = autoComplete->mIsGetDefinition || (autoComplete->mResolveType == BfResolveType_GetResultString);
  5826. }
  5827. BfSourceData* typeRefSource = NULL;
  5828. if (typeRef->IsTemporary())
  5829. {
  5830. BfTypeReference* checkTypeRef = typeRef;
  5831. if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(checkTypeRef))
  5832. checkTypeRef = genericTypeRef->mElementType;
  5833. if (auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(checkTypeRef))
  5834. typeRefSource = namedTypeRef->mNameNode->GetSourceData();
  5835. }
  5836. else
  5837. typeRefSource = typeRef->GetSourceData();
  5838. bool wantsFileNamespaceInfo = (((mCompiler->mResolvePassData->mSourceClassifier != NULL) || (isGetDefinition) || (mCompiler->mResolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Namespace)) &&
  5839. (typeRefSource != NULL) && (mCompiler->mResolvePassData->mParser != NULL) &&
  5840. (typeRefSource == mCompiler->mResolvePassData->mParser->mSourceData));
  5841. bool wantsAllNamespaceInfo = (mCompiler->mResolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Namespace) && (mCompiler->mResolvePassData->mParser == NULL);
  5842. if (wantsFileNamespaceInfo || wantsAllNamespaceInfo)
  5843. {
  5844. //TODO: By only breaking out for "mIgnoreErrors", we classified elements (below) even when a resolvedTypeRef was not found!
  5845. //Why did we have this mIgnoreErrors check in there?
  5846. // if ((resolvedTypeRef == NULL) && (mIgnoreErrors))
  5847. if (resolvedTypeRef == NULL)
  5848. {
  5849. return NULL;
  5850. }
  5851. BfTypeInstance* resolvedTypeInstance = NULL;
  5852. if (resolvedTypeRef != NULL)
  5853. resolvedTypeInstance = resolvedTypeRef->ToTypeInstance();
  5854. bool isNamespace = false;
  5855. auto checkTypeRef = typeRef;
  5856. if (auto elementedTypeRef = BfNodeDynCast<BfElementedTypeRef>(checkTypeRef))
  5857. checkTypeRef = elementedTypeRef->mElementType;
  5858. if (!mIsInsideAutoComplete)
  5859. {
  5860. if ((resolvedTypeInstance != NULL) && (resolvedTypeInstance->mTypeDef->IsGlobalsContainer()))
  5861. {
  5862. isNamespace = true;
  5863. }
  5864. else
  5865. {
  5866. //TODO: This broke colorizing of inner expressions for things like "T2[T3]"
  5867. //mCompiler->mResolvePassData->mSourceClassifier->VisitChildNoRef(typeRef);
  5868. }
  5869. }
  5870. while (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(checkTypeRef))
  5871. {
  5872. if ((mCompiler->mResolvePassData->mSourceClassifier != NULL) && (resolvedTypeRef->IsObjectOrInterface()))
  5873. mCompiler->mResolvePassData->mSourceClassifier->SetElementType(qualifiedTypeRef->mRight, resolvedTypeRef->IsInterface() ? BfSourceElementType_Interface : BfSourceElementType_RefType);
  5874. StringView leftString = qualifiedTypeRef->mLeft->ToStringView();
  5875. BfSizedAtomComposite leftComposite;
  5876. bool isValid = mSystem->ParseAtomComposite(leftString, leftComposite);
  5877. if (mCompiler->mResolvePassData->mSourceClassifier != NULL)
  5878. mCompiler->mResolvePassData->mSourceClassifier->SetHighestElementType(qualifiedTypeRef->mRight, isNamespace ? BfSourceElementType_Namespace : BfSourceElementType_Type);
  5879. if (resolvedTypeInstance == NULL)
  5880. {
  5881. if ((isValid) && (mCompiler->mSystem->ContainsNamespace(leftComposite, mCurTypeInstance->mTypeDef->mProject)))
  5882. isNamespace = true;
  5883. }
  5884. else if ((isValid) && (resolvedTypeInstance->mTypeDef->mNamespace.EndsWith(leftComposite)))
  5885. {
  5886. if (autoComplete != NULL)
  5887. {
  5888. if (autoComplete->CheckFixit(typeRef))
  5889. autoComplete->FixitCheckNamespace(GetActiveTypeDef(), qualifiedTypeRef->mLeft, qualifiedTypeRef->mDot);
  5890. autoComplete->CheckNamespace(qualifiedTypeRef->mLeft, resolvedTypeInstance->mTypeDef->mNamespace);
  5891. }
  5892. mCompiler->mResolvePassData->HandleNamespaceReference(qualifiedTypeRef->mLeft, resolvedTypeInstance->mTypeDef->mNamespace);
  5893. isNamespace = true;
  5894. }
  5895. checkTypeRef = qualifiedTypeRef->mLeft;
  5896. }
  5897. if (auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(checkTypeRef))
  5898. {
  5899. auto checkNameNode = namedTypeRef->mNameNode;
  5900. bool setType = false;
  5901. if ((mCompiler->mResolvePassData->mSourceClassifier != NULL) && (resolvedTypeRef->IsObjectOrInterface()))
  5902. {
  5903. if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(checkNameNode))
  5904. {
  5905. mCompiler->mResolvePassData->mSourceClassifier->SetElementType(qualifiedNameNode->mRight, resolvedTypeRef->IsInterface() ? BfSourceElementType_Interface : BfSourceElementType_RefType);
  5906. }
  5907. else
  5908. {
  5909. setType = true;
  5910. mCompiler->mResolvePassData->mSourceClassifier->SetElementType(checkNameNode, resolvedTypeRef->IsInterface() ? BfSourceElementType_Interface : BfSourceElementType_RefType);
  5911. }
  5912. }
  5913. while (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(checkNameNode))
  5914. {
  5915. StringView leftString = qualifiedNameNode->mLeft->ToStringView();
  5916. BfSizedAtomComposite leftComposite;
  5917. bool isValid = mSystem->ParseAtomComposite(leftString, leftComposite);
  5918. if (mCompiler->mResolvePassData->mSourceClassifier != NULL)
  5919. mCompiler->mResolvePassData->mSourceClassifier->SetHighestElementType(qualifiedNameNode->mRight, isNamespace ? BfSourceElementType_Namespace : BfSourceElementType_Type);
  5920. if (resolvedTypeInstance == NULL)
  5921. {
  5922. if ((isValid) && (mCompiler->mSystem->ContainsNamespace(leftComposite, mCurTypeInstance->mTypeDef->mProject)))
  5923. isNamespace = true;
  5924. }
  5925. else if ((isValid) && (resolvedTypeInstance->mTypeDef->mNamespace.EndsWith(leftComposite)))
  5926. isNamespace = true;
  5927. checkNameNode = qualifiedNameNode->mLeft;
  5928. }
  5929. if ((mCompiler->mResolvePassData->mSourceClassifier != NULL) &&
  5930. ((!setType) || (checkNameNode != namedTypeRef->mNameNode)))
  5931. mCompiler->mResolvePassData->mSourceClassifier->SetHighestElementType(checkNameNode, isNamespace ? BfSourceElementType_Namespace : BfSourceElementType_Type);
  5932. }
  5933. }
  5934. if (((mCompiler->mResolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Type) || (isGetDefinition)) &&
  5935. ((resolveFlags & BfResolveTypeRefFlag_FromIndirectSource) == 0) && (resolvedTypeRef != NULL) && (typeRefSource != NULL))
  5936. {
  5937. BfAstNode* elementTypeRef = typeRef;
  5938. if (auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(elementTypeRef))
  5939. elementTypeRef = namedTypeRef->mNameNode;
  5940. if (elementTypeRef != NULL)
  5941. {
  5942. BfType* elementType = resolvedTypeRef;
  5943. if (BfTypeInstance* elementTypeInst = elementType->ToTypeInstance())
  5944. {
  5945. mCompiler->mResolvePassData->HandleTypeReference(elementTypeRef, elementTypeInst->mTypeDef);
  5946. if (mCompiler->IsAutocomplete())
  5947. {
  5948. BfAutoComplete* autoComplete = mCompiler->mResolvePassData->mAutoComplete;
  5949. if ((isGetDefinition) && (autoComplete->IsAutocompleteNode(elementTypeRef)))
  5950. {
  5951. BfAstNode* baseNode = elementTypeRef;
  5952. while (true)
  5953. {
  5954. if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(baseNode))
  5955. {
  5956. baseNode = qualifiedTypeRef->mRight;
  5957. }
  5958. else if (auto elementedTypeRef = BfNodeDynCast<BfElementedTypeRef>(baseNode))
  5959. {
  5960. baseNode = elementedTypeRef->mElementType;
  5961. }
  5962. else if (auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(baseNode))
  5963. {
  5964. baseNode = namedTypeRef->mNameNode;
  5965. }
  5966. else if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(baseNode))
  5967. {
  5968. baseNode = qualifiedNameNode->mRight;
  5969. }
  5970. else if (auto declTypeRef = BfNodeDynCast<BfDeclTypeRef>(baseNode))
  5971. {
  5972. baseNode = NULL;
  5973. break;
  5974. }
  5975. else
  5976. break;
  5977. }
  5978. if ((baseNode != NULL) && (autoComplete->IsAutocompleteNode(baseNode)))
  5979. {
  5980. // We didn't have this mDefType check before - why? We always want to catch the FIRST definition,
  5981. // so 'Type?' will catch on 'Type' and not 'Type?'
  5982. if ((autoComplete->mDefType == NULL) &&
  5983. (autoComplete->mDefMethod == NULL) && (autoComplete->mDefField == NULL) &&
  5984. (autoComplete->mDefProp == NULL) && (elementTypeInst->mTypeDef->mTypeDeclaration != NULL))
  5985. {
  5986. autoComplete->mDefType = elementTypeInst->mTypeDef;
  5987. autoComplete->SetDefinitionLocation(elementTypeInst->mTypeDef->mTypeDeclaration->mNameNode);
  5988. }
  5989. if ((autoComplete->mResolveType == BfResolveType_GetResultString) && (resolvedTypeRef != NULL))
  5990. {
  5991. autoComplete->mResultString = ":";
  5992. autoComplete->mResultString += TypeToString(resolvedTypeRef);
  5993. }
  5994. }
  5995. }
  5996. }
  5997. }
  5998. }
  5999. }
  6000. }
  6001. if (resolvedTypeRef == NULL)
  6002. return NULL;
  6003. if (mCurTypeInstance == NULL)
  6004. {
  6005. // No deps
  6006. }
  6007. else if (resolvedTypeRef->IsTuple())
  6008. {
  6009. // Add the fields from the tuple as references since those inner fields types would have been explicitly stated, so we need
  6010. // to make sure to record the current type instance as a referring type. This mostly matters for symbol renaming.
  6011. BfTypeInstance* payloadTupleType = (BfTypeInstance*)resolvedTypeRef;
  6012. for (auto& payloadFieldInst : payloadTupleType->mFieldInstances)
  6013. {
  6014. auto payloadFieldType = payloadFieldInst.mResolvedType;
  6015. AddDependency(payloadFieldType, mCurTypeInstance, BfDependencyMap::DependencyFlag_TypeReference);
  6016. }
  6017. }
  6018. else if (resolvedTypeRef->IsDelegateFromTypeRef() || resolvedTypeRef->IsFunctionFromTypeRef())
  6019. {
  6020. auto delegateInfo = resolvedTypeRef->GetDelegateInfo();
  6021. auto invokeMethod = GetDelegateInvokeMethod(resolvedTypeRef->ToTypeInstance());
  6022. AddDependency(invokeMethod->mReturnType, mCurTypeInstance, BfDependencyMap::DependencyFlag_TypeReference);
  6023. for (auto& param : invokeMethod->mParams)
  6024. {
  6025. AddDependency(param.mResolvedType, mCurTypeInstance, BfDependencyMap::DependencyFlag_TypeReference);
  6026. }
  6027. }
  6028. BfTypeInstance* typeInstance = resolvedTypeRef->ToTypeInstance();
  6029. BfTypeInstance* genericTypeInstance = resolvedTypeRef->ToGenericTypeInstance();
  6030. auto populateModule = this;
  6031. if ((resolveFlags & BfResolveTypeRefFlag_NoReify) != 0)
  6032. populateModule = mContext->mUnreifiedModule;
  6033. populateModule->PopulateType(resolvedTypeRef, populateType);
  6034. if ((genericTypeInstance != NULL) && (genericTypeInstance != mCurTypeInstance) && (populateType > BfPopulateType_Identity))
  6035. {
  6036. bool doValidate = (genericTypeInstance->mGenericTypeInfo->mHadValidateErrors) ||
  6037. (!genericTypeInstance->mGenericTypeInfo->mValidatedGenericConstraints) ||
  6038. (genericTypeInstance->mGenericTypeInfo->mIsUnspecializedVariation);
  6039. if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mIsUnspecializedVariation))
  6040. doValidate = false;
  6041. if (mCurTypeInstance != NULL)
  6042. {
  6043. if (mCurTypeInstance->IsUnspecializedTypeVariation())
  6044. doValidate = false;
  6045. if (auto curGenericTypeInstance = mCurTypeInstance->ToGenericTypeInstance())
  6046. {
  6047. if (curGenericTypeInstance->mGenericTypeInfo->mHadValidateErrors)
  6048. doValidate = false;
  6049. }
  6050. if ((mContext->mCurTypeState != NULL) && (mContext->mCurTypeState->mCurBaseTypeRef != NULL)) // We validate constraints for base types later
  6051. doValidate = false;
  6052. }
  6053. if (doValidate)
  6054. ValidateGenericConstraints(typeRef, genericTypeInstance, false);
  6055. }
  6056. if (populateType != BfPopulateType_IdentityNoRemapAlias)
  6057. {
  6058. while ((resolvedTypeRef != NULL) && (resolvedTypeRef->IsTypeAlias()))
  6059. {
  6060. if (mCurTypeInstance != NULL)
  6061. AddDependency(resolvedTypeRef, mCurTypeInstance, BfDependencyMap::DependencyFlag_NameReference);
  6062. if ((typeInstance->mCustomAttributes != NULL) && (!typeRef->IsTemporary()))
  6063. CheckErrorAttributes(typeInstance, NULL, typeInstance->mCustomAttributes, typeRef);
  6064. resolvedTypeRef = resolvedTypeRef->GetUnderlyingType();
  6065. if (resolvedTypeRef != NULL)
  6066. typeInstance = resolvedTypeRef->ToTypeInstance();
  6067. else
  6068. typeInstance = NULL;
  6069. }
  6070. }
  6071. if (typeInstance != NULL)
  6072. {
  6073. if ((typeInstance->mCustomAttributes != NULL) && (!typeRef->IsTemporary()))
  6074. CheckErrorAttributes(typeInstance, NULL, typeInstance->mCustomAttributes, typeRef);
  6075. }
  6076. return resolvedTypeRef;
  6077. }
  6078. void BfModule::ShowAmbiguousTypeError(BfAstNode* refNode, BfTypeDef* typeDef, BfTypeDef* otherTypeDef)
  6079. {
  6080. BfType* type = ResolveTypeDef(typeDef, BfPopulateType_Identity);
  6081. if (type == NULL)
  6082. return;
  6083. BfType* otherType = ResolveTypeDef(otherTypeDef, BfPopulateType_Identity);
  6084. if (otherType == NULL)
  6085. return;
  6086. auto error = Fail(StrFormat("'%s' is an ambiguous reference between '%s' and '%s'",
  6087. refNode->ToString().c_str(), TypeToString(type, BfTypeNameFlags_None).c_str(), TypeToString(otherType, BfTypeNameFlags_None).c_str()), refNode); // CS0104
  6088. if (error != NULL)
  6089. {
  6090. mCompiler->mPassInstance->MoreInfo("See first definition", typeDef->mTypeDeclaration->mNameNode);
  6091. mCompiler->mPassInstance->MoreInfo("See second definition", otherTypeDef->mTypeDeclaration->mNameNode);
  6092. }
  6093. }
  6094. void BfModule::ShowGenericArgCountError(BfTypeReference* typeRef, int wantedGenericParams)
  6095. {
  6096. BfGenericInstanceTypeRef* genericTypeInstRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef);
  6097. BfAstNode* lastNode = typeRef;
  6098. int genericArgDiffCount;
  6099. if (genericTypeInstRef != NULL)
  6100. {
  6101. genericArgDiffCount = (int)genericTypeInstRef->mGenericArguments.size() - wantedGenericParams;
  6102. lastNode = genericTypeInstRef->mOpenChevron;
  6103. if (genericTypeInstRef->mCloseChevron != NULL)
  6104. lastNode = genericTypeInstRef->mCloseChevron;
  6105. if (genericTypeInstRef->mGenericArguments.size() > wantedGenericParams)
  6106. {
  6107. lastNode = genericTypeInstRef->mGenericArguments[wantedGenericParams];
  6108. if (genericArgDiffCount == 1)
  6109. Fail("Too many generic parameters, expected one fewer", lastNode);
  6110. else
  6111. Fail(StrFormat("Too many generic parameters, expected %d fewer", genericArgDiffCount), lastNode);
  6112. return;
  6113. }
  6114. }
  6115. else
  6116. genericArgDiffCount = -wantedGenericParams;
  6117. if (wantedGenericParams == 1)
  6118. Fail("Too few generic parameters, expected one more", lastNode);
  6119. else
  6120. Fail(StrFormat("Too few generic parameters, expected %d more", -genericArgDiffCount), lastNode);
  6121. }
  6122. BfTypeDef* BfModule::GetActiveTypeDef(BfTypeInstance* typeInstanceOverride, bool useMixinDecl)
  6123. {
  6124. BfTypeDef* useTypeDef = NULL;
  6125. BfTypeInstance* typeInstance = (typeInstanceOverride != NULL) ? typeInstanceOverride : mCurTypeInstance;
  6126. if (typeInstance != NULL)
  6127. useTypeDef = typeInstance->mTypeDef;
  6128. if ((mCurMethodState != NULL) && (mCurMethodState->mMixinState != NULL) && (useMixinDecl))
  6129. useTypeDef = mCurMethodState->mMixinState->mMixinMethodInstance->mMethodDef->mDeclaringType;
  6130. else if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mMethodDef->mDeclaringType != NULL))
  6131. useTypeDef = mCurMethodInstance->mMethodDef->mDeclaringType;
  6132. else if (mContext->mCurTypeState != NULL)
  6133. {
  6134. if ((mContext->mCurTypeState->mCurFieldDef != NULL) && (mContext->mCurTypeState->mCurFieldDef->mDeclaringType != NULL))
  6135. useTypeDef = mContext->mCurTypeState->mCurFieldDef->mDeclaringType;
  6136. else if (mContext->mCurTypeState->mCurTypeDef != NULL)
  6137. useTypeDef = mContext->mCurTypeState->mCurTypeDef;
  6138. }
  6139. return useTypeDef;
  6140. }
  6141. BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGenericArgs, BfTypeInstance* typeInstance, BfTypeDef* useTypeDef, BfTypeLookupError* error)
  6142. {
  6143. if ((findName.mSize == 1) && (findName.mParts[0]->mIsSystemType))
  6144. {
  6145. //BP_ZONE("BfModule::FindTypeDefRaw_1");
  6146. return mSystem->FindTypeDef(findName, 0, useTypeDef->mProject);
  6147. }
  6148. BfTypeInstance* skipCheckBaseType = NULL;
  6149. if (mContext->mCurTypeState != NULL)
  6150. {
  6151. if (mContext->mCurTypeState->mCurBaseTypeRef != NULL)
  6152. skipCheckBaseType = mContext->mCurTypeState->mTypeInstance;
  6153. if (mContext->mCurTypeState->mResolveKind == BfTypeState::ResolveKind_BuildingGenericParams)
  6154. skipCheckBaseType = mContext->mCurTypeState->mTypeInstance;
  6155. }
  6156. BfTypeDefLookupContext lookupCtx;
  6157. bool allowPrivate = true;
  6158. int curPri = 1000;
  6159. auto checkTypeInst = typeInstance;
  6160. BfTypeDef* protErrorTypeDef = NULL;
  6161. BfTypeInstance* protErrorOuterType = NULL;
  6162. if (!lookupCtx.HasValidMatch())
  6163. {
  6164. std::function<bool(BfTypeInstance*)> _CheckType = [&](BfTypeInstance* typeInstance)
  6165. {
  6166. auto checkTypeInst = typeInstance;
  6167. allowPrivate = true;
  6168. while (checkTypeInst != NULL)
  6169. {
  6170. if (!checkTypeInst->mTypeDef->mNestedTypes.IsEmpty())
  6171. {
  6172. if (mSystem->FindTypeDef(findName, numGenericArgs, useTypeDef->mProject, checkTypeInst->mTypeDef->mFullNameEx, allowPrivate, &lookupCtx))
  6173. {
  6174. if (lookupCtx.HasValidMatch())
  6175. return true;
  6176. if ((lookupCtx.mBestTypeDef->mProtection == BfProtection_Private) && (!allowPrivate))
  6177. {
  6178. protErrorTypeDef = lookupCtx.mBestTypeDef;
  6179. protErrorOuterType = checkTypeInst;
  6180. }
  6181. }
  6182. }
  6183. if (checkTypeInst == skipCheckBaseType)
  6184. break;
  6185. checkTypeInst = GetBaseType(checkTypeInst);
  6186. allowPrivate = false;
  6187. }
  6188. checkTypeInst = typeInstance;
  6189. allowPrivate = true;
  6190. while (checkTypeInst != NULL)
  6191. {
  6192. auto outerTypeInst = GetOuterType(checkTypeInst);
  6193. if (outerTypeInst != NULL)
  6194. {
  6195. if (_CheckType(outerTypeInst))
  6196. return true;
  6197. }
  6198. if (checkTypeInst == skipCheckBaseType)
  6199. break;
  6200. checkTypeInst = GetBaseType(checkTypeInst);
  6201. allowPrivate = false;
  6202. }
  6203. return false;
  6204. };
  6205. _CheckType(typeInstance);
  6206. }
  6207. if (!lookupCtx.HasValidMatch())
  6208. {
  6209. if (mSystem->mTypeDefs.TryGet(findName, NULL))
  6210. mSystem->FindTypeDef(findName, numGenericArgs, useTypeDef->mProject, BfAtomComposite(), allowPrivate, &lookupCtx);
  6211. for (auto& checkNamespace : useTypeDef->mNamespaceSearch)
  6212. {
  6213. BfAtom* atom = findName.mParts[0];
  6214. BfAtom* prevAtom = checkNamespace.mParts[checkNamespace.mSize - 1];
  6215. if (atom->mPrevNamesMap.ContainsKey(prevAtom))
  6216. mSystem->FindTypeDef(findName, numGenericArgs, useTypeDef->mProject, checkNamespace, allowPrivate, &lookupCtx);
  6217. }
  6218. }
  6219. if (!lookupCtx.HasValidMatch())
  6220. {
  6221. auto staticSearch = GetStaticSearch();
  6222. if (staticSearch != NULL)
  6223. {
  6224. for (auto staticTypeInstance : staticSearch->mStaticTypes)
  6225. {
  6226. if (mSystem->FindTypeDef(findName, numGenericArgs, useTypeDef->mProject, staticTypeInstance->mTypeDef->mFullNameEx, false, &lookupCtx))
  6227. {
  6228. if (lookupCtx.HasValidMatch())
  6229. break;
  6230. if (lookupCtx.mBestTypeDef->mProtection < BfProtection_Public)
  6231. {
  6232. protErrorTypeDef = lookupCtx.mBestTypeDef;
  6233. protErrorOuterType = staticTypeInstance;
  6234. }
  6235. }
  6236. }
  6237. }
  6238. }
  6239. if ((error != NULL) && (lookupCtx.mAmbiguousTypeDef != NULL))
  6240. {
  6241. if (error->mErrorKind == BfTypeLookupError::BfErrorKind_None)
  6242. error->mErrorKind = BfTypeLookupError::BfErrorKind_Ambiguous;
  6243. error->mAmbiguousTypeDef = lookupCtx.mAmbiguousTypeDef;
  6244. if (error->mRefNode != NULL)
  6245. ShowAmbiguousTypeError(error->mRefNode, lookupCtx.mBestTypeDef, lookupCtx.mAmbiguousTypeDef);
  6246. }
  6247. if ((protErrorTypeDef != NULL) && (lookupCtx.mBestTypeDef == protErrorTypeDef) && (error != NULL) && (error->mRefNode != NULL))
  6248. Fail(StrFormat("'%s.%s' is inaccessible due to its protection level", TypeToString(protErrorOuterType).c_str(), findName.ToString().c_str()), error->mRefNode); // CS0122
  6249. return lookupCtx.mBestTypeDef;
  6250. }
  6251. BfTypeDef* BfModule::FindTypeDef(const BfAtomComposite& findName, int numGenericArgs, BfTypeInstance* typeInstanceOverride, BfTypeLookupError* error)
  6252. {
  6253. BP_ZONE("BfModule::FindTypeDef_1");
  6254. BfTypeInstance* typeInstance = (typeInstanceOverride != NULL) ? typeInstanceOverride : mCurTypeInstance;
  6255. if (typeInstance == NULL)
  6256. {
  6257. BfProject* project = NULL;
  6258. if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mParser != NULL))
  6259. project = mCompiler->mResolvePassData->mParser->mProject;
  6260. BP_ZONE("System.FindTypeDef_2");
  6261. BfTypeDef* ambiguousTypeDef = NULL;
  6262. BfTypeDef *result = mSystem->FindTypeDef(findName, numGenericArgs, project, Array<BfAtomComposite>(), &ambiguousTypeDef);
  6263. if ((ambiguousTypeDef != NULL) && (error != NULL))
  6264. {
  6265. error->mErrorKind = BfTypeLookupError::BfErrorKind_Ambiguous;
  6266. error->mAmbiguousTypeDef = ambiguousTypeDef;
  6267. if (error->mRefNode != NULL)
  6268. ShowAmbiguousTypeError(error->mRefNode, result, ambiguousTypeDef);
  6269. }
  6270. return result;
  6271. }
  6272. auto useTypeDef = GetActiveTypeDef(typeInstanceOverride, true);
  6273. if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL))
  6274. {
  6275. if (mCompiler->mResolvePassData->mAutoCompleteTempTypes.Contains(useTypeDef))
  6276. return FindTypeDefRaw(findName, numGenericArgs, typeInstance, useTypeDef, error);
  6277. }
  6278. BfTypeLookupEntry typeLookupEntry;
  6279. typeLookupEntry.mName = findName;
  6280. typeLookupEntry.mNumGenericParams = numGenericArgs;
  6281. typeLookupEntry.mUseTypeDef = useTypeDef;
  6282. BfTypeLookupEntry* typeLookupEntryPtr = NULL;
  6283. BfTypeLookupResult* resultPtr = NULL;
  6284. if (typeInstance->mLookupResults.TryAdd(typeLookupEntry, &typeLookupEntryPtr, &resultPtr))
  6285. {
  6286. typeLookupEntryPtr->mAtomUpdateIdx = typeLookupEntry.mName.GetAtomUpdateIdx();
  6287. // FindTypeDefRaw may re-enter when finding base types, so we need to expect that resultPtr can change
  6288. resultPtr->mForceLookup = true;
  6289. resultPtr->mTypeDef = NULL;
  6290. int prevAllocSize = (int)typeInstance->mLookupResults.size();
  6291. BfTypeLookupError localError;
  6292. BfTypeLookupError* errorPtr = (error != NULL) ? error : &localError;
  6293. auto typeDef = FindTypeDefRaw(findName, numGenericArgs, typeInstance, useTypeDef, errorPtr);
  6294. if (prevAllocSize != typeInstance->mLookupResults.size())
  6295. {
  6296. bool found = typeInstance->mLookupResults.TryGetValue(typeLookupEntry, &resultPtr);
  6297. BF_ASSERT(found);
  6298. }
  6299. resultPtr->mTypeDef = typeDef;
  6300. resultPtr->mForceLookup = errorPtr->mErrorKind != BfTypeLookupError::BfErrorKind_None;
  6301. return typeDef;
  6302. }
  6303. else
  6304. {
  6305. if (resultPtr->mForceLookup)
  6306. return FindTypeDefRaw(findName, numGenericArgs, typeInstance, useTypeDef, error);
  6307. else
  6308. return resultPtr->mTypeDef;
  6309. }
  6310. }
  6311. BfTypeDef* BfModule::FindTypeDef(const StringImpl& typeName, int numGenericArgs, BfTypeInstance* typeInstanceOverride, BfTypeLookupError* error)
  6312. {
  6313. BP_ZONE("BfModule::FindTypeDef_4");
  6314. BfSizedAtomComposite findName;
  6315. if (!mSystem->ParseAtomComposite(typeName, findName))
  6316. return NULL;
  6317. auto result = FindTypeDef(findName, numGenericArgs, typeInstanceOverride, error);
  6318. // Don't allow just finding extensions here. This can happen in some 'using static' cases but generally shouldn't happen
  6319. if ((result != NULL) && (result->mTypeCode == BfTypeCode_Extension))
  6320. return NULL;
  6321. return result;
  6322. }
  6323. BfTypeDef* BfModule::FindTypeDef(BfTypeReference* typeRef, BfTypeInstance* typeInstanceOverride, BfTypeLookupError* error, int numGenericParams, BfResolveTypeRefFlags resolveFlags)
  6324. {
  6325. BP_ZONE("BfModule::FindTypeDef_5");
  6326. if (auto typeDefTypeRef = BfNodeDynCast<BfDirectTypeDefReference>(typeRef))
  6327. {
  6328. if (typeDefTypeRef->mTypeDef != NULL)
  6329. return mSystem->FilterDeletedTypeDef(typeDefTypeRef->mTypeDef);
  6330. }
  6331. //TODO: When does this get called?
  6332. if (auto elementedType = BfNodeDynCast<BfElementedTypeRef>(typeRef))
  6333. return FindTypeDef(elementedType->mElementType, typeInstanceOverride, error);
  6334. BF_ASSERT(typeRef->IsA<BfNamedTypeReference>() || typeRef->IsA<BfQualifiedTypeReference>() || typeRef->IsA<BfDirectStrTypeReference>());
  6335. auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(typeRef);
  6336. StringView findNameStr;
  6337. if (namedTypeRef != NULL)
  6338. findNameStr = namedTypeRef->mNameNode->ToStringView();
  6339. else
  6340. {
  6341. auto directStrTypeDef = BfNodeDynCastExact<BfDirectStrTypeReference>(typeRef);
  6342. if (directStrTypeDef != NULL)
  6343. findNameStr = directStrTypeDef->mTypeName;
  6344. else
  6345. BFMODULE_FATAL(this, "Error?");
  6346. }
  6347. if (findNameStr.mLength == 6)
  6348. {
  6349. if (findNameStr == "object")
  6350. {
  6351. findNameStr = "System.Object";
  6352. Fail("'object' alias not supported, use 'Object'", typeRef);
  6353. }
  6354. else if (findNameStr == "string")
  6355. {
  6356. findNameStr = "System.String";
  6357. Fail("'string' alias not supported, use 'String'", typeRef);
  6358. }
  6359. }
  6360. BfSizedAtomComposite findName;
  6361. if ((resolveFlags & BfResolveTypeRefFlag_Attribute) != 0)
  6362. {
  6363. String attributeName;
  6364. attributeName += findNameStr;
  6365. attributeName += "Attribute";
  6366. if (!mSystem->ParseAtomComposite(attributeName, findName))
  6367. return NULL;
  6368. }
  6369. else
  6370. {
  6371. if (!mSystem->ParseAtomComposite(findNameStr, findName))
  6372. return NULL;
  6373. }
  6374. #ifdef BF_AST_HAS_PARENT_MEMBER
  6375. if (auto parentGenericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef->mParent))
  6376. {
  6377. if (parentGenericTypeRef->mElementType == typeRef)
  6378. BF_ASSERT(numGenericParams == parentGenericTypeRef->GetGenericArgCount());
  6379. }
  6380. #endif
  6381. auto typeDef = FindTypeDef(findName, numGenericParams, typeInstanceOverride, error);
  6382. //TYPEDEF if (namedTypeRef != NULL)
  6383. // namedTypeRef->mTypeDef = typeDef;
  6384. return typeDef;
  6385. }
  6386. void BfModule::CheckTypeRefFixit(BfAstNode* typeRef, const char* appendName)
  6387. {
  6388. if ((mCompiler->IsAutocomplete()) && (mCompiler->mResolvePassData->mAutoComplete->CheckFixit((typeRef))))
  6389. {
  6390. String typeName = typeRef->ToString();
  6391. if (appendName != NULL)
  6392. typeName += appendName;
  6393. std::set<String> fixitNamespaces;
  6394. //TODO: Do proper value for numGenericArgs
  6395. mSystem->FindFixitNamespaces(typeName, -1, mCompiler->mResolvePassData->mParser->mProject, fixitNamespaces);
  6396. int insertLoc = 0;
  6397. BfUsingFinder usingFinder;
  6398. usingFinder.VisitMembers(typeRef->GetSourceData()->mRootNode);
  6399. for (auto& namespaceStr : fixitNamespaces)
  6400. {
  6401. BfParserData* parser = typeRef->GetSourceData()->ToParserData();
  6402. if (parser != NULL)
  6403. mCompiler->mResolvePassData->mAutoComplete->AddEntry(AutoCompleteEntry("fixit", StrFormat("using %s;\tusing|%s|%d||using %s;", namespaceStr.c_str(), parser->mFileName.c_str(), usingFinder.mLastIdx, namespaceStr.c_str()).c_str()));
  6404. }
  6405. }
  6406. }
  6407. void BfModule::CheckIdentifierFixit(BfAstNode* node)
  6408. {
  6409. //TODO: Check globals, possibly spelling mistakes?
  6410. }
  6411. void BfModule::TypeRefNotFound(BfTypeReference* typeRef, const char* appendName)
  6412. {
  6413. if (typeRef->IsTemporary())
  6414. return;
  6415. Fail("Type could not be found (are you missing a using directive or library reference?)", typeRef);
  6416. if (!mIgnoreErrors)
  6417. {
  6418. while (auto elementedType = BfNodeDynCast<BfElementedTypeRef>(typeRef))
  6419. typeRef = elementedType->mElementType;
  6420. if (auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(typeRef))
  6421. {
  6422. String findNameStr = namedTypeRef->mNameNode->ToString();
  6423. if (appendName != NULL)
  6424. findNameStr += appendName;
  6425. BfSizedAtomComposite findName;
  6426. if ((!mSystem->ParseAtomComposite(findNameStr, findName)) && (mCurTypeInstance != NULL))
  6427. {
  6428. //BfTypeInstance* typeInstance = (typeInstanceOverride != NULL) ? typeInstanceOverride : mCurTypeInstance;
  6429. // We don't need a typeInstanceOverride because that is used to lookup references
  6430. // from mixins, but it's the type using the mixin (mCurTypeInstance) that needs
  6431. // rebuilding if the lookup fails
  6432. BfTypeInstance* typeInstance = mCurTypeInstance;
  6433. BfTypeLookupEntry typeLookupEntry;
  6434. typeLookupEntry.mNumGenericParams = 0;
  6435. typeLookupEntry.mAtomUpdateIdx = mSystem->mAtomUpdateIdx;
  6436. typeInstance->mLookupResults.TryAdd(typeLookupEntry, BfTypeLookupResult());
  6437. }
  6438. }
  6439. }
  6440. CheckTypeRefFixit(typeRef, appendName);
  6441. }
  6442. bool BfModule::ValidateTypeWildcard(BfTypeReference* typeRef, bool isAttributeRef)
  6443. {
  6444. if (typeRef == NULL)
  6445. return false;
  6446. if (auto wildcardTypeRef = BfNodeDynCast<BfWildcardTypeReference>(typeRef))
  6447. return true;
  6448. StringT<128> nameStr;
  6449. typeRef->ToString(nameStr);
  6450. if (isAttributeRef)
  6451. nameStr.Append("Attribute");
  6452. auto typeDef = mSystem->FindTypeDef(nameStr, (BfProject*)NULL);
  6453. if ((typeDef != NULL) && (typeDef->mGenericParamDefs.IsEmpty()))
  6454. return true;
  6455. if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(typeRef))
  6456. {
  6457. if (qualifiedTypeRef->mLeft == NULL)
  6458. return false;
  6459. StringT<128> leftNameStr;
  6460. BfType* leftType = NULL;
  6461. BfAtomComposite leftComposite;
  6462. qualifiedTypeRef->mLeft->ToString(leftNameStr);
  6463. if (!mSystem->ParseAtomComposite(leftNameStr, leftComposite))
  6464. return false;
  6465. if (auto wildcardTypeRef = BfNodeDynCast<BfWildcardTypeReference>(qualifiedTypeRef->mRight))
  6466. {
  6467. if (mSystem->ContainsNamespace(leftComposite, NULL))
  6468. return true;
  6469. return ValidateTypeWildcard(qualifiedTypeRef->mLeft, false);
  6470. }
  6471. }
  6472. if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef))
  6473. {
  6474. StringT<128> nameStr;
  6475. genericTypeRef->mElementType->ToString(nameStr);
  6476. auto typeDef = mSystem->FindTypeDef(nameStr, (int)genericTypeRef->mGenericArguments.size(), NULL);
  6477. if (typeDef == NULL)
  6478. return false;
  6479. if (typeDef->mGenericParamDefs.size() != genericTypeRef->GetGenericArgCount())
  6480. return false;
  6481. for (auto genericArgTypeRef : genericTypeRef->mGenericArguments)
  6482. {
  6483. if ((genericTypeRef != NULL) && (!ValidateTypeWildcard(genericArgTypeRef, false)))
  6484. return false;
  6485. }
  6486. return true;
  6487. }
  6488. if (auto elementedTypeRef = BfNodeDynCast<BfElementedTypeRef>(typeRef))
  6489. {
  6490. return ValidateTypeWildcard(elementedTypeRef->mElementType, false);
  6491. }
  6492. return false;
  6493. }
  6494. //int sResolveTypeRefIdx = 0;
  6495. BfTypedValue BfModule::TryLookupGenericConstVaue(BfIdentifierNode* identifierNode, BfType* expectingType)
  6496. {
  6497. BfTypeInstance* contextTypeInstance = mCurTypeInstance;
  6498. BfMethodInstance* contextMethodInstance = mCurMethodInstance;
  6499. if ((mCurMethodState != NULL) && (mCurMethodState->mMixinState != NULL))
  6500. {
  6501. contextTypeInstance = mCurMethodState->mMixinState->mMixinMethodInstance->GetOwner();
  6502. contextMethodInstance = mCurMethodState->mMixinState->mMixinMethodInstance;
  6503. }
  6504. BfTypeDef* curTypeDef = NULL;
  6505. if (contextTypeInstance != NULL)
  6506. {
  6507. curTypeDef = contextTypeInstance->mTypeDef;
  6508. StringT<128> findName;
  6509. identifierNode->ToString(findName);
  6510. auto genericCheckTypeInstance = contextTypeInstance;
  6511. if (contextTypeInstance->IsBoxed())
  6512. genericCheckTypeInstance = contextTypeInstance->GetUnderlyingType()->ToTypeInstance();
  6513. bool doFakeVal = false;
  6514. if (genericCheckTypeInstance->IsUnspecializedTypeVariation())
  6515. {
  6516. genericCheckTypeInstance = GetUnspecializedTypeInstance(genericCheckTypeInstance);
  6517. doFakeVal = true;
  6518. }
  6519. BfGenericParamDef* genericParamDef = NULL;
  6520. BfGenericParamDef* origGenericParamDef = NULL;
  6521. BfType* genericParamResult = NULL;
  6522. BfType* genericTypeConstraint = NULL;
  6523. bool disallowConstExprValue = false;
  6524. if ((genericCheckTypeInstance != NULL) && (genericCheckTypeInstance->IsGenericTypeInstance()))
  6525. {
  6526. auto genericTypeInst = (BfTypeInstance*)genericCheckTypeInstance;
  6527. auto* genericParams = &curTypeDef->mGenericParamDefs;
  6528. auto* origGenericParams = &curTypeDef->mGenericParamDefs;
  6529. if (genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo != NULL)
  6530. {
  6531. auto activeTypeDef = GetActiveTypeDef(NULL, true);
  6532. genericParams = &activeTypeDef->mGenericParamDefs;
  6533. }
  6534. for (int genericParamIdx = (int)genericParams->size() - 1; genericParamIdx >= 0; genericParamIdx--)
  6535. {
  6536. auto checkGenericParamDef = (*genericParams)[genericParamIdx];
  6537. String genericName = checkGenericParamDef->mName;
  6538. if (genericName == findName)
  6539. {
  6540. genericParamDef = checkGenericParamDef;
  6541. origGenericParamDef = (*origGenericParams)[genericParamIdx];
  6542. genericParamResult = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[genericParamIdx];
  6543. genericTypeConstraint = genericTypeInst->mGenericTypeInfo->mGenericParams[genericParamIdx]->mTypeConstraint;
  6544. HandleTypeGenericParamRef(identifierNode, genericTypeInst->mTypeDef, genericParamIdx);
  6545. }
  6546. }
  6547. }
  6548. if ((contextMethodInstance != NULL) && (genericParamResult == NULL))
  6549. {
  6550. for (int genericParamIdx = (int)contextMethodInstance->mMethodDef->mGenericParams.size() - 1; genericParamIdx >= 0; genericParamIdx--)
  6551. {
  6552. auto checkGenericParamDef = contextMethodInstance->mMethodDef->mGenericParams[genericParamIdx];
  6553. String genericName = checkGenericParamDef->mName;
  6554. if (genericName == findName)
  6555. {
  6556. genericParamDef = checkGenericParamDef;
  6557. origGenericParamDef = checkGenericParamDef;
  6558. genericParamResult = contextMethodInstance->mMethodInfoEx->mMethodGenericArguments[genericParamIdx];
  6559. genericTypeConstraint = contextMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx]->mTypeConstraint;
  6560. HandleMethodGenericParamRef(identifierNode, contextMethodInstance->GetOwner()->mTypeDef, contextMethodInstance->mMethodDef, genericParamIdx);
  6561. }
  6562. }
  6563. }
  6564. if (genericParamResult != NULL)
  6565. {
  6566. auto typeRefSource = identifierNode->GetSourceData();
  6567. if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mSourceClassifier != NULL) && (typeRefSource != NULL) && (typeRefSource == mCompiler->mResolvePassData->mParser->mSourceData))
  6568. mCompiler->mResolvePassData->mSourceClassifier->SetElementType(identifierNode, BfSourceElementType_Type);
  6569. if (genericParamResult->IsConstExprValue())
  6570. {
  6571. BfConstExprValueType* constExprValueType = (BfConstExprValueType*)genericParamResult;
  6572. BfExprEvaluator exprEvaluator(this);
  6573. exprEvaluator.mExpectingType = genericTypeConstraint;
  6574. exprEvaluator.GetLiteral(identifierNode, constExprValueType->mValue);
  6575. // We don't want to validate type here
  6576. return exprEvaluator.mResult;
  6577. }
  6578. else if (genericParamResult->IsGenericParam())
  6579. {
  6580. if ((doFakeVal) && (genericTypeConstraint != NULL))
  6581. {
  6582. return BfTypedValue(mBfIRBuilder->GetFakeVal(), genericTypeConstraint);
  6583. }
  6584. if (((genericParamDef->mGenericParamFlags | origGenericParamDef->mGenericParamFlags) & BfGenericParamFlag_Const) != 0)
  6585. {
  6586. BfTypedValue result;
  6587. result.mType = genericParamResult;
  6588. result.mKind = BfTypedValueKind_GenericConstValue;
  6589. return result;
  6590. }
  6591. }
  6592. }
  6593. }
  6594. return BfTypedValue();
  6595. }
  6596. BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags, int numGenericArgs)
  6597. {
  6598. BP_ZONE("BfModule::ResolveTypeRef");
  6599. if (typeRef == NULL)
  6600. {
  6601. AssertErrorState();
  6602. return NULL;
  6603. }
  6604. if (resolveFlags & BfResolveTypeRefFlag_AutoComplete)
  6605. {
  6606. resolveFlags = (BfResolveTypeRefFlags)(resolveFlags & ~BfResolveTypeRefFlag_AutoComplete);
  6607. auto autoComplete = mCompiler->GetAutoComplete();
  6608. if (autoComplete != NULL)
  6609. autoComplete->CheckTypeRef(typeRef, false);
  6610. }
  6611. if ((resolveFlags & BfResolveTypeRefFlag_AllowRef) == 0)
  6612. {
  6613. if (auto refTypeRef = BfNodeDynCast<BfRefTypeRef>(typeRef))
  6614. {
  6615. const char* refTypeStr = BfTokenToString(refTypeRef->mRefToken->mToken);
  6616. Fail(StrFormat("Invalid use of '%s'. Only method parameters, return types, and local variables can be declared as %s types", refTypeStr, refTypeStr), refTypeRef->mRefToken);
  6617. return ResolveTypeRef(refTypeRef->mElementType);
  6618. }
  6619. }
  6620. if (auto directTypeRef = BfNodeDynCastExact<BfDirectTypeReference>(typeRef))
  6621. {
  6622. return directTypeRef->mType;
  6623. }
  6624. if (auto dotType = BfNodeDynCastExact<BfDotTypeReference>(typeRef))
  6625. {
  6626. Fail(StrFormat("Invalid use of '%s'", BfTokenToString(dotType->mDotToken->mToken)), typeRef);
  6627. return NULL;
  6628. }
  6629. if (auto varRefType = BfNodeDynCastExact<BfVarRefTypeReference>(typeRef))
  6630. {
  6631. Fail("Invalid use of 'var ref'. Generally references are generated with a 'var' declaration with 'ref' applied to the initializer", typeRef);
  6632. return NULL;
  6633. }
  6634. if (mNoResolveGenericParams)
  6635. resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_NoResolveGenericParam);
  6636. SetAndRestoreValue<bool> prevNoResolveGenericParams(mNoResolveGenericParams, (resolveFlags & BfResolveTypeRefFlag_NoResolveGenericParam) != 0);
  6637. //
  6638. resolveFlags = (BfResolveTypeRefFlags)(resolveFlags & ~BfResolveTypeRefFlag_NoResolveGenericParam);
  6639. BfTypeInstance* contextTypeInstance = mCurTypeInstance;
  6640. BfMethodInstance* contextMethodInstance = mCurMethodInstance;
  6641. if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mIsForeignMethodDef))
  6642. contextTypeInstance = mCurMethodInstance->mMethodInfoEx->mForeignType;
  6643. if ((mCurMethodState != NULL) && (mCurMethodState->mMixinState != NULL))
  6644. {
  6645. contextTypeInstance = mCurMethodState->mMixinState->mMixinMethodInstance->GetOwner();
  6646. contextMethodInstance = mCurMethodState->mMixinState->mMixinMethodInstance;
  6647. }
  6648. BfTypeDef* curTypeDef = NULL;
  6649. if (contextTypeInstance != NULL)
  6650. {
  6651. curTypeDef = contextTypeInstance->mTypeDef;
  6652. // Check generics first
  6653. auto namedTypeRef = BfNodeDynCastExact<BfNamedTypeReference>(typeRef);
  6654. auto directStrTypeRef = BfNodeDynCastExact<BfDirectStrTypeReference>(typeRef);
  6655. if (((namedTypeRef != NULL) && (namedTypeRef->mNameNode != NULL)) || (directStrTypeRef != NULL))
  6656. {
  6657. StringT<128> findName;
  6658. if (namedTypeRef != NULL)
  6659. namedTypeRef->mNameNode->ToString(findName);
  6660. else
  6661. findName = directStrTypeRef->mTypeName;
  6662. if (findName == "Self")
  6663. {
  6664. BfType* selfType = mCurTypeInstance;
  6665. if (selfType->IsInterface()) // For interfaces, 'Self' refers to the identity of the implementing type, so we use a placeholder
  6666. return GetPrimitiveType(BfTypeCode_Self);
  6667. else
  6668. resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_FromIndirectSource);
  6669. if (selfType->IsBoxed())
  6670. selfType = selfType->GetUnderlyingType();
  6671. if ((resolveFlags & BfResolveTypeRefFlag_NoResolveGenericParam) != 0)
  6672. {
  6673. if ((selfType->IsSpecializedType()) || (selfType->IsUnspecializedTypeVariation()))
  6674. selfType = ResolveTypeDef(selfType->ToTypeInstance()->mTypeDef, populateType);
  6675. }
  6676. if (selfType == NULL)
  6677. {
  6678. Fail("'Self' type is not usable here", typeRef);
  6679. }
  6680. return ResolveTypeResult(typeRef, selfType, populateType, resolveFlags);
  6681. }
  6682. else if (findName == "SelfBase")
  6683. {
  6684. BfType* selfType = mCurTypeInstance;
  6685. if (selfType->IsInterface())
  6686. resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_FromIndirectSource);
  6687. if (selfType->IsBoxed())
  6688. selfType = selfType->GetUnderlyingType();
  6689. if ((resolveFlags & BfResolveTypeRefFlag_NoResolveGenericParam) != 0)
  6690. {
  6691. if ((selfType->IsSpecializedType()) || (selfType->IsUnspecializedTypeVariation()))
  6692. selfType = ResolveTypeDef(selfType->ToTypeInstance()->mTypeDef, populateType);
  6693. }
  6694. BfType* baseType = NULL;
  6695. if (selfType != NULL)
  6696. {
  6697. if (selfType->IsTypedPrimitive())
  6698. baseType = selfType->GetUnderlyingType();
  6699. else
  6700. {
  6701. auto selfTypeInst = selfType->ToTypeInstance();
  6702. if (selfTypeInst != NULL)
  6703. {
  6704. baseType = selfTypeInst->mBaseType;
  6705. }
  6706. }
  6707. }
  6708. if (baseType == NULL)
  6709. {
  6710. Fail("'SelfBase' type is not usable here", typeRef);
  6711. }
  6712. return ResolveTypeResult(typeRef, baseType, populateType, resolveFlags);
  6713. }
  6714. else if (findName == "ExpectedType")
  6715. {
  6716. Fail("'ExpectedType' is not usable here", typeRef);
  6717. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  6718. }
  6719. auto genericCheckTypeInstance = contextTypeInstance;
  6720. if (contextTypeInstance->IsBoxed())
  6721. genericCheckTypeInstance = contextTypeInstance->GetUnderlyingType()->ToTypeInstance();
  6722. BfGenericParamDef* genericParamDef = NULL;
  6723. BfType* genericParamResult = NULL;
  6724. bool disallowConstExprValue = false;
  6725. if ((genericCheckTypeInstance != NULL) && (genericCheckTypeInstance->IsGenericTypeInstance()))
  6726. {
  6727. auto genericTypeInst = (BfTypeInstance*)genericCheckTypeInstance;
  6728. auto* genericParams = &curTypeDef->mGenericParamDefs;
  6729. if (genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo != NULL)
  6730. {
  6731. auto activeTypeDef = GetActiveTypeDef(NULL, true);
  6732. genericParams = &activeTypeDef->mGenericParamDefs;
  6733. }
  6734. for (int genericParamIdx = (int)genericParams->size() - 1; genericParamIdx >= 0; genericParamIdx--)
  6735. {
  6736. auto checkGenericParamDef = (*genericParams)[genericParamIdx];
  6737. String genericName = checkGenericParamDef->mName;
  6738. if (genericName == findName)
  6739. {
  6740. genericParamDef = checkGenericParamDef;
  6741. if (((genericParamDef->mGenericParamFlags & BfGenericParamFlag_Const) != 0) &&
  6742. ((resolveFlags & BfResolveTypeRefFlag_AllowGenericTypeParamConstValue) == 0))
  6743. disallowConstExprValue = true;
  6744. HandleTypeGenericParamRef(typeRef, curTypeDef, genericParamIdx);
  6745. if ((resolveFlags & BfResolveTypeRefFlag_NoResolveGenericParam) != 0)
  6746. return GetGenericParamType(BfGenericParamKind_Type, genericParamIdx);
  6747. else
  6748. {
  6749. SetAndRestoreValue<BfGetSymbolReferenceKind> prevSymbolRefKind;
  6750. if (mCompiler->mResolvePassData != NULL) // Don't add these typeRefs, they are indirect
  6751. prevSymbolRefKind.Init(mCompiler->mResolvePassData->mGetSymbolReferenceKind, BfGetSymbolReferenceKind_None);
  6752. genericParamResult = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[genericParamIdx];
  6753. if ((genericParamResult != NULL) &&
  6754. (genericParamResult->IsConstExprValue()) &&
  6755. ((resolveFlags & BfResolveTypeRefFlag_AllowGenericTypeParamConstValue) == 0))
  6756. disallowConstExprValue = true;
  6757. }
  6758. }
  6759. }
  6760. }
  6761. if ((contextMethodInstance != NULL) && (genericParamResult == NULL))
  6762. {
  6763. BfMethodInstance* prevMethodInstance = NULL;
  6764. // If we're in a closure then use the outside method generic arguments
  6765. auto checkMethodInstance = contextMethodInstance;
  6766. if ((mCurMethodState != NULL) && (checkMethodInstance->mIsClosure))
  6767. {
  6768. auto checkMethodState = mCurMethodState;
  6769. while (checkMethodState != NULL)
  6770. {
  6771. if ((checkMethodState->mMethodInstance != NULL) && (checkMethodState->mMethodInstance->mIsClosure))
  6772. {
  6773. checkMethodInstance = checkMethodState->mPrevMethodState->mMethodInstance;
  6774. }
  6775. checkMethodState = checkMethodState->mPrevMethodState;
  6776. }
  6777. }
  6778. for (int genericParamIdx = (int)checkMethodInstance->mMethodDef->mGenericParams.size() - 1; genericParamIdx >= 0; genericParamIdx--)
  6779. {
  6780. auto checkGenericParamDef = checkMethodInstance->mMethodDef->mGenericParams[genericParamIdx];
  6781. String genericName = checkGenericParamDef->mName;
  6782. if (genericName == findName)
  6783. {
  6784. genericParamDef = checkGenericParamDef;
  6785. if (((genericParamDef->mGenericParamFlags & BfGenericParamFlag_Const) != 0) &&
  6786. ((resolveFlags & BfResolveTypeRefFlag_AllowGenericMethodParamConstValue) == 0))
  6787. disallowConstExprValue = true;
  6788. HandleMethodGenericParamRef(typeRef, checkMethodInstance->GetOwner()->mTypeDef, checkMethodInstance->mMethodDef, genericParamIdx);
  6789. if ((resolveFlags & BfResolveTypeRefFlag_NoResolveGenericParam) != 0)
  6790. return GetGenericParamType(BfGenericParamKind_Method, genericParamIdx);
  6791. else
  6792. {
  6793. SetAndRestoreValue<BfGetSymbolReferenceKind> prevSymbolRefKind;
  6794. if (mCompiler->mResolvePassData != NULL) // Don't add these typeRefs, they are indirect
  6795. prevSymbolRefKind.Init(mCompiler->mResolvePassData->mGetSymbolReferenceKind, BfGetSymbolReferenceKind_None);
  6796. genericParamResult = checkMethodInstance->mMethodInfoEx->mMethodGenericArguments[genericParamIdx];
  6797. if ((genericParamResult != NULL) &&
  6798. (genericParamResult->IsConstExprValue()) &&
  6799. ((resolveFlags & BfResolveTypeRefFlag_AllowGenericMethodParamConstValue) == 0))
  6800. disallowConstExprValue = true;
  6801. }
  6802. }
  6803. }
  6804. }
  6805. if (genericParamResult != NULL)
  6806. {
  6807. if (disallowConstExprValue)
  6808. {
  6809. Fail("Invalid use of constant generic value", typeRef);
  6810. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  6811. }
  6812. if (genericParamResult->IsRef())
  6813. {
  6814. if ((resolveFlags & BfResolveTypeRefFlag_AllowRefGeneric) == 0)
  6815. genericParamResult = genericParamResult->GetUnderlyingType();
  6816. }
  6817. return ResolveTypeResult(typeRef, genericParamResult, populateType, (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_FromIndirectSource));
  6818. }
  6819. }
  6820. }
  6821. BfTypeDef* typeDef = NULL;
  6822. if (typeRef->IsNamedTypeReference())
  6823. {
  6824. BfTypeLookupError error;
  6825. error.mRefNode = typeRef;
  6826. typeDef = FindTypeDef(typeRef, contextTypeInstance, &error, 0, resolveFlags);
  6827. if (auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(typeRef))
  6828. {
  6829. if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(namedTypeRef->mNameNode))
  6830. {
  6831. // This handles the case where we have an "BaseClass.InnerClass", but the name is qualified as "DerivedClass.InnerClass"
  6832. auto leftType = ResolveTypeRef(qualifiedNameNode->mLeft, NULL, BfPopulateType_Identity, (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_NoResolveGenericParam | BfResolveTypeRefFlag_AllowRef));
  6833. if ((leftType != NULL) && (qualifiedNameNode->mRight != NULL))
  6834. {
  6835. // Try searching within inner type
  6836. auto resolvedType = ResolveInnerType(leftType, qualifiedNameNode->mRight, populateType, true);
  6837. if (resolvedType != NULL)
  6838. {
  6839. if (mCurTypeInstance != NULL)
  6840. AddDependency(leftType, mCurTypeInstance, BfDependencyMap::DependencyFlag_NameReference);
  6841. return ResolveTypeResult(typeRef, resolvedType, populateType, resolveFlags);
  6842. }
  6843. }
  6844. }
  6845. }
  6846. if ((typeDef == NULL) && (mCurTypeInstance != NULL))
  6847. {
  6848. // Try searching within inner type
  6849. auto checkOuterType = mCurTypeInstance;
  6850. while (checkOuterType != NULL)
  6851. {
  6852. // We check for mBaseType to not be NULL because we can't inherit from an inner type, so don't even search there
  6853. // Causes reference cycles (bad).
  6854. if ((checkOuterType != mCurTypeInstance) || (checkOuterType->mBaseType != NULL))
  6855. {
  6856. auto resolvedType = ResolveInnerType(checkOuterType, typeRef, populateType, true);
  6857. if (resolvedType != NULL)
  6858. {
  6859. if (mCurTypeInstance != NULL)
  6860. AddDependency(checkOuterType, mCurTypeInstance, BfDependencyMap::DependencyFlag_NameReference);
  6861. return ResolveTypeResult(typeRef, resolvedType, populateType, resolveFlags);
  6862. }
  6863. }
  6864. checkOuterType = GetOuterType(checkOuterType);
  6865. }
  6866. }
  6867. if (typeDef == NULL)
  6868. {
  6869. auto staticSearch = GetStaticSearch();
  6870. if (staticSearch != NULL)
  6871. {
  6872. for (auto staticTypeInst : staticSearch->mStaticTypes)
  6873. {
  6874. auto resolvedType = ResolveInnerType(staticTypeInst, typeRef, populateType, true);
  6875. if (resolvedType != NULL)
  6876. {
  6877. if (mCurTypeInstance != NULL)
  6878. AddDependency(staticTypeInst, mCurTypeInstance, BfDependencyMap::DependencyFlag_NameReference);
  6879. return ResolveTypeResult(typeRef, resolvedType, populateType, resolveFlags);
  6880. }
  6881. }
  6882. }
  6883. }
  6884. if (typeDef == NULL)
  6885. {
  6886. #ifdef BF_AST_HAS_PARENT_MEMBER
  6887. if (auto parentQualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(typeRef->mParent))
  6888. {
  6889. BF_ASSERT(typeRef->mParent == mParentNodeEntry->mNode);
  6890. }
  6891. #endif
  6892. if (mParentNodeEntry != NULL)
  6893. {
  6894. if (auto parentQualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(mParentNodeEntry->mNode))
  6895. {
  6896. if (typeRef == parentQualifiedTypeRef->mLeft)
  6897. {
  6898. if ((resolveFlags & BfResolveTypeRefFlag_IgnoreLookupError) == 0)
  6899. TypeRefNotFound(typeRef);
  6900. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  6901. }
  6902. }
  6903. }
  6904. if ((resolveFlags & BfResolveTypeRefFlag_IgnoreLookupError) == 0)
  6905. {
  6906. TypeRefNotFound(typeRef, ((resolveFlags & Beefy::BfResolveTypeRefFlag_Attribute) != 0) ? "Attribute" : NULL);
  6907. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  6908. }
  6909. return NULL;
  6910. }
  6911. }
  6912. else if (auto typeDefTypeRef = BfNodeDynCastExact<BfDirectTypeDefReference>(typeRef))
  6913. {
  6914. typeDef = typeDefTypeRef->mTypeDef;
  6915. }
  6916. if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(typeRef))
  6917. {
  6918. //TODO: Determine why we had this prevIgnoreErrors set here. It causes things like IEnumerator<Hey.Test<INVALIDNAME>> not fail
  6919. // properly on INVALIDNAME
  6920. SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, /*true*/mIgnoreErrors);
  6921. StringView leftNameStr;
  6922. BfType* leftType = NULL;
  6923. BfSizedAtomComposite leftComposite;
  6924. bool leftIsValid = false;
  6925. //bool leftIsValid = (qualifiedTypeRef->mLeft != NULL) && mSystem->ParseAtomComposite(qualifiedTypeRef->mLeft->ToString(), leftComposite);
  6926. if (qualifiedTypeRef->mLeft != NULL)
  6927. {
  6928. leftNameStr = qualifiedTypeRef->mLeft->ToStringView();
  6929. if (mSystem->ParseAtomComposite(leftNameStr, leftComposite))
  6930. leftIsValid = true;
  6931. }
  6932. if ((leftIsValid) && (qualifiedTypeRef->mRight != NULL))
  6933. {
  6934. StringT<128> findName;
  6935. auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(qualifiedTypeRef->mRight);
  6936. auto activeTypeDef = GetActiveTypeDef();
  6937. BfProject* bfProject = NULL;
  6938. if (activeTypeDef != NULL)
  6939. bfProject = activeTypeDef->mProject;
  6940. if (mSystem->ContainsNamespace(leftComposite, bfProject))
  6941. {
  6942. qualifiedTypeRef->mLeft->ToString(findName);
  6943. findName.Append('.');
  6944. if (genericTypeRef != NULL)
  6945. genericTypeRef->mElementType->ToString(findName);
  6946. else
  6947. qualifiedTypeRef->mRight->ToString(findName);
  6948. }
  6949. else if ((activeTypeDef != NULL) && (activeTypeDef->mNamespace.EndsWith(leftComposite)))
  6950. {
  6951. // Partial namespace reference, extend to a full reference
  6952. findName += activeTypeDef->mNamespace.ToString();
  6953. findName.Append('.');
  6954. qualifiedTypeRef->mRight->ToString(findName);
  6955. }
  6956. if (!findName.IsEmpty())
  6957. {
  6958. int wantNumGenericArgs = 0;
  6959. #ifdef BF_AST_HAS_PARENT_MEMBER
  6960. if (auto genericTypeParent = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef->mParent))
  6961. {
  6962. BF_ASSERT(mParentNodeEntry->mNode == genericTypeParent);
  6963. //wantNumGenericArgs = (int)genericTypeParent->mGenericArguments.size();
  6964. //genericTypeRef = genericTypeParent;
  6965. }
  6966. #endif
  6967. if (mParentNodeEntry != NULL)
  6968. {
  6969. if (auto genericTypeParent = BfNodeDynCast<BfGenericInstanceTypeRef>(mParentNodeEntry->mNode))
  6970. {
  6971. wantNumGenericArgs = (int)genericTypeParent->mGenericArguments.size();
  6972. genericTypeRef = genericTypeParent;
  6973. }
  6974. }
  6975. BfTypeDef* ambiguousTypeDef = NULL;
  6976. //auto typeDef = mSystem->FindTypeDef(findName, wantNumGenericArgs, bfProject, {}, &ambiguousTypeDef);
  6977. //auto typeDef = mSystem->FindTypeDef(findName, wantNumGenericArgs, bfProject, {}, &ambiguousTypeDef);
  6978. BfTypeLookupError lookupError;
  6979. auto typeDef = FindTypeDef(findName, wantNumGenericArgs, NULL, &lookupError);
  6980. if (typeDef != NULL)
  6981. {
  6982. if (ambiguousTypeDef != NULL)
  6983. ShowAmbiguousTypeError(typeRef, typeDef, ambiguousTypeDef);
  6984. BfTypeVector genericArgs;
  6985. if (populateType != BfPopulateType_TypeDef)
  6986. {
  6987. if (genericTypeRef != NULL)
  6988. {
  6989. for (auto genericParamTypeRef : genericTypeRef->mGenericArguments)
  6990. {
  6991. auto genericParam = ResolveTypeRef(genericParamTypeRef, BfPopulateType_Declaration);
  6992. if (genericParam == NULL)
  6993. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  6994. genericArgs.push_back(genericParam);
  6995. }
  6996. }
  6997. if (typeDef->mGenericParamDefs.size() != genericArgs.size())
  6998. {
  6999. prevIgnoreErrors.Restore();
  7000. BfAstNode* refNode = typeRef;
  7001. if (genericTypeRef != NULL)
  7002. refNode = genericTypeRef->mOpenChevron;
  7003. int wantedGenericParams = (int)typeDef->mGenericParamDefs.size();
  7004. if (wantedGenericParams == 1)
  7005. Fail("Expected one generic argument", refNode);
  7006. else
  7007. Fail(StrFormat("Expected %d generic arguments", wantedGenericParams), refNode);
  7008. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  7009. }
  7010. }
  7011. return ResolveTypeResult(typeRef, ResolveTypeDef(typeDef, genericArgs, populateType), populateType, resolveFlags);
  7012. }
  7013. }
  7014. }
  7015. if (leftType == NULL)
  7016. {
  7017. BfAutoParentNodeEntry autoParentNodeEntry(this, qualifiedTypeRef);
  7018. leftType = ResolveTypeRef(qualifiedTypeRef->mLeft, BfPopulateType_Identity, (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_IgnoreLookupError)); // We throw an error below if we can't find the type
  7019. }
  7020. if (leftType == NULL)
  7021. {
  7022. mIgnoreErrors = prevIgnoreErrors.mPrevVal;
  7023. BfTypeReference* errorRefNode = qualifiedTypeRef->mLeft;
  7024. if ((leftIsValid) && (mCurTypeInstance != NULL) && (mSystem->ContainsNamespace(leftComposite, mCurTypeInstance->mTypeDef->mProject)))
  7025. {
  7026. // The left was a namespace name, so throw an error on the whole string
  7027. errorRefNode = qualifiedTypeRef;
  7028. }
  7029. TypeRefNotFound(errorRefNode);
  7030. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  7031. }
  7032. prevIgnoreErrors.Restore();
  7033. if (qualifiedTypeRef->mRight == NULL)
  7034. {
  7035. FailAfter("Expected identifier", qualifiedTypeRef->mDot);
  7036. //AssertErrorState();
  7037. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  7038. }
  7039. auto resolvedType = ResolveInnerType(leftType, qualifiedTypeRef->mRight, populateType, false, numGenericArgs);
  7040. if ((resolvedType != NULL) && (mCurTypeInstance != NULL))
  7041. AddDependency(leftType, mCurTypeInstance, BfDependencyMap::DependencyFlag_NameReference);
  7042. return ResolveTypeResult(typeRef, resolvedType, populateType, resolveFlags);
  7043. // If we did a ResolveTypeResult, then that may process an alias as the alias-to type instead of the actual alias
  7044. //return ResolveInnerType(leftType, qualifiedTypeRef->mRight, populateType);
  7045. }
  7046. if (auto resolvedTypeRef = BfNodeDynCast<BfResolvedTypeReference>(typeRef))
  7047. {
  7048. return ResolveTypeResult(typeRef, resolvedTypeRef->mType, populateType, resolveFlags);
  7049. }
  7050. if (auto retTypeTypeRef = BfNodeDynCastExact<BfModifiedTypeRef>(typeRef))
  7051. {
  7052. if (retTypeTypeRef->mRetTypeToken->mToken == BfToken_RetType)
  7053. {
  7054. bool allowThrough = false;
  7055. BfType* resolvedType = NULL;
  7056. if (retTypeTypeRef->mElementType != NULL)
  7057. {
  7058. auto innerType = ResolveTypeRef(retTypeTypeRef->mElementType, BfPopulateType_Declaration, BfResolveTypeRefFlag_AllowGenericParamConstValue);
  7059. if (innerType != NULL)
  7060. {
  7061. if ((innerType->IsDelegate()) || (innerType->IsFunction()))
  7062. {
  7063. PopulateType(innerType, BfPopulateType_DataAndMethods);
  7064. BfMethodInstance* invokeMethodInstance = GetRawMethodInstanceAtIdx(innerType->ToTypeInstance(), 0, "Invoke");
  7065. if (invokeMethodInstance != NULL)
  7066. {
  7067. resolvedType = invokeMethodInstance->mReturnType;
  7068. return ResolveTypeResult(typeRef, resolvedType, populateType, resolveFlags);
  7069. }
  7070. }
  7071. else if (innerType->IsGenericParam())
  7072. {
  7073. if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsUnspecializedTypeVariation()))
  7074. {
  7075. // We could have case where we have "rettype(@T0)" and @T0 gets a type variation of @M0, but we can't do a
  7076. // GetGenericParamInstance on that
  7077. allowThrough = true;
  7078. }
  7079. else
  7080. {
  7081. auto genericParamInstance = GetGenericParamInstance((BfGenericParamType*)innerType);
  7082. if (genericParamInstance->mTypeConstraint != NULL)
  7083. {
  7084. if ((genericParamInstance->mTypeConstraint->IsDelegate()) || (genericParamInstance->mTypeConstraint->IsFunction()))
  7085. {
  7086. resolvedType = GetDelegateReturnType(genericParamInstance->mTypeConstraint);
  7087. return ResolveTypeResult(typeRef, resolvedType, populateType, resolveFlags);
  7088. }
  7089. else if ((genericParamInstance->mTypeConstraint->IsTypeInstance()) &&
  7090. ((genericParamInstance->mTypeConstraint->ToTypeInstance()->mTypeDef == mCompiler->mDelegateTypeDef) ||
  7091. (genericParamInstance->mTypeConstraint->ToTypeInstance()->mTypeDef == mCompiler->mFunctionTypeDef)))
  7092. {
  7093. allowThrough = true;
  7094. }
  7095. }
  7096. }
  7097. }
  7098. else if (innerType->IsMethodRef())
  7099. {
  7100. auto methodRefType = (BfMethodRefType*)innerType;
  7101. resolvedType = methodRefType->mMethodRef->mReturnType;
  7102. return ResolveTypeResult(typeRef, resolvedType, populateType, resolveFlags);
  7103. }
  7104. }
  7105. }
  7106. if (!allowThrough)
  7107. {
  7108. Fail("'rettype' can only be used on delegate or function types", retTypeTypeRef->mRetTypeToken);
  7109. return ResolveTypeResult(typeRef, resolvedType, populateType, resolveFlags);
  7110. }
  7111. }
  7112. else if (retTypeTypeRef->mRetTypeToken->mToken == BfToken_AllocType)
  7113. {
  7114. BfType* resolvedType = NULL;
  7115. if (retTypeTypeRef->mElementType != NULL)
  7116. {
  7117. resolvedType = ResolveTypeRef(retTypeTypeRef->mElementType, BfPopulateType_Declaration, BfResolveTypeRefFlag_AllowGenericParamConstValue);
  7118. if (resolvedType != NULL)
  7119. {
  7120. if (resolvedType->IsGenericParam())
  7121. {
  7122. auto genericParam = GetGenericParamInstance((BfGenericParamType*)resolvedType);
  7123. if (((genericParam->mTypeConstraint != NULL) && (genericParam->mTypeConstraint->IsValueType())) ||
  7124. ((genericParam->mGenericParamFlags & (BfGenericParamFlag_Struct | BfGenericParamFlag_StructPtr)) != 0))
  7125. {
  7126. resolvedType = CreatePointerType(resolvedType);
  7127. }
  7128. else if (((genericParam->mTypeConstraint != NULL) && (!genericParam->mTypeConstraint->IsValueType())) ||
  7129. ((genericParam->mGenericParamFlags & (BfGenericParamFlag_Class)) != 0))
  7130. {
  7131. // Leave as 'T'
  7132. }
  7133. else
  7134. resolvedType = CreateModifiedTypeType(resolvedType, BfToken_AllocType);
  7135. }
  7136. else if (resolvedType->IsValueType())
  7137. resolvedType = CreatePointerType(resolvedType);
  7138. }
  7139. }
  7140. return ResolveTypeResult(typeRef, resolvedType, populateType, resolveFlags);
  7141. }
  7142. else if (retTypeTypeRef->mRetTypeToken->mToken == BfToken_Nullable)
  7143. {
  7144. bool allowThrough = false;
  7145. BfType* resolvedType = NULL;
  7146. if (retTypeTypeRef->mElementType != NULL)
  7147. {
  7148. resolvedType = ResolveTypeRef(retTypeTypeRef->mElementType, BfPopulateType_Declaration, BfResolveTypeRefFlag_AllowGenericParamConstValue);
  7149. }
  7150. if ((resolvedType != NULL) && (resolvedType->IsGenericParam()))
  7151. {
  7152. //resolvedType = CreateModifiedTypeType(resolvedType, BfToken_Nullable);
  7153. BfTypeVector typeVec;
  7154. typeVec.push_back(resolvedType);
  7155. resolvedType = ResolveTypeDef(mCompiler->mNullableTypeDef, typeVec, BfPopulateType_Declaration);
  7156. }
  7157. else if (resolvedType != NULL)
  7158. {
  7159. if (resolvedType->IsValueType())
  7160. {
  7161. if (InDefinitionSection())
  7162. Warn(0, StrFormat("Consider using '%s?' instead of nullable modifier", TypeToString(resolvedType).c_str()), retTypeTypeRef);
  7163. BfTypeVector typeVec;
  7164. typeVec.push_back(resolvedType);
  7165. resolvedType = ResolveTypeDef(mCompiler->mNullableTypeDef, typeVec, BfPopulateType_Declaration);
  7166. }
  7167. else
  7168. {
  7169. if (InDefinitionSection())
  7170. Warn(0, StrFormat("Unneeded nullable modifier, %s is already nullable", TypeToString(resolvedType).c_str()), retTypeTypeRef->mRetTypeToken);
  7171. }
  7172. }
  7173. if (resolvedType != NULL)
  7174. PopulateType(resolvedType, populateType);
  7175. return resolvedType;
  7176. }
  7177. else
  7178. BFMODULE_FATAL(this, "Unhandled");
  7179. }
  7180. if (auto refTypeRef = BfNodeDynCastExact<BfRefTypeRef>(typeRef))
  7181. {
  7182. if ((refTypeRef->mRefToken != NULL) && (refTypeRef->mRefToken->GetToken() == BfToken_Mut) && (refTypeRef->mElementType != NULL))
  7183. {
  7184. bool needsRefWrap = false;
  7185. auto resolvedType = ResolveTypeRef(refTypeRef->mElementType, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowGenericParamConstValue);
  7186. if (resolvedType != NULL)
  7187. {
  7188. if ((resolvedType->IsValueType()) || (resolvedType->IsGenericParam()))
  7189. needsRefWrap = true;
  7190. if ((InDefinitionSection()) && (!resolvedType->IsGenericParam()) && ((resolveFlags & BfResolveTypeRefFlag_NoWarnOnMut) == 0))
  7191. {
  7192. if (!resolvedType->IsValueType())
  7193. Warn(0, StrFormat("Specified 'mut' has no effect on '%s' since reference types are always mutable", TypeToString(resolvedType).c_str()), refTypeRef->mRefToken);
  7194. else
  7195. Warn(0, "Use 'mut' for generic arguments which may or may not be reference types. Consider using 'ref' here, instead.", refTypeRef->mRefToken);
  7196. }
  7197. }
  7198. if (!needsRefWrap)
  7199. {
  7200. // Non-composites (including pointers) don't actually need ref-wrapping for 'mut'
  7201. return ResolveTypeResult(typeRef, resolvedType, populateType, resolveFlags);
  7202. }
  7203. }
  7204. }
  7205. BfResolvedTypeSet::LookupContext lookupCtx;
  7206. lookupCtx.mResolveFlags = (BfResolveTypeRefFlags)(resolveFlags & BfResolveTypeRefFlag_NoCreate);
  7207. lookupCtx.mRootTypeRef = typeRef;
  7208. lookupCtx.mRootTypeDef = typeDef;
  7209. lookupCtx.mModule = this;
  7210. BfResolvedTypeSet::Entry* resolvedEntry = NULL;
  7211. auto inserted = mContext->mResolvedTypes.Insert(typeRef, &lookupCtx, &resolvedEntry);
  7212. if (resolvedEntry == NULL)
  7213. {
  7214. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  7215. }
  7216. if (!inserted)
  7217. {
  7218. BF_ASSERT(resolvedEntry->mValue != NULL);
  7219. return ResolveTypeResult(typeRef, resolvedEntry->mValue, populateType, resolveFlags);
  7220. }
  7221. if ((resolveFlags & BfResolveTypeRefFlag_NoCreate) != 0)
  7222. {
  7223. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  7224. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  7225. }
  7226. BfModule* populateModule = this;
  7227. if ((resolveFlags & BfResolveTypeRefFlag_NoReify) != 0)
  7228. populateModule = mContext->mUnreifiedModule;
  7229. if (typeRef->IsTypeDefTypeReference())
  7230. {
  7231. //BF_ASSERT(typeDefTypeRef->mTypeDef != NULL); // Resolved higher up
  7232. //auto typeDef = typeDefTypeRef->mTypeDef;
  7233. if ((typeDef->mTypeCode >= BfTypeCode_None) && (typeDef->mTypeCode <= BfTypeCode_Double))
  7234. {
  7235. BfPrimitiveType* primType = new BfPrimitiveType();
  7236. primType->mTypeDef = typeDef;
  7237. resolvedEntry->mValue = primType;
  7238. BF_ASSERT(BfResolvedTypeSet::Hash(primType, &lookupCtx, false) == resolvedEntry->mHash);
  7239. populateModule->InitType(primType, populateType);
  7240. return ResolveTypeResult(typeRef, primType, populateType, resolveFlags);
  7241. }
  7242. BfTypeInstance* outerTypeInstance = lookupCtx.mRootOuterTypeInstance;
  7243. if (outerTypeInstance == NULL)
  7244. outerTypeInstance = mCurTypeInstance;
  7245. if ((outerTypeInstance != NULL) && (typeDef->mGenericParamDefs.size() != 0))
  7246. {
  7247. // Try to inherit generic params from current parent
  7248. BfTypeDef* outerType = mSystem->GetCombinedPartial(typeDef->mOuterType);
  7249. BF_ASSERT(!outerType->mIsPartial);
  7250. if (TypeHasParentOrEquals(outerTypeInstance->mTypeDef, outerType))
  7251. {
  7252. BfType* checkCurType = outerTypeInstance;
  7253. if (checkCurType->IsBoxed())
  7254. checkCurType = checkCurType->GetUnderlyingType();
  7255. if (checkCurType->IsTypeAlias())
  7256. checkCurType = GetOuterType(checkCurType);
  7257. BF_ASSERT(checkCurType->IsGenericTypeInstance());
  7258. int numParentGenericParams = (int)outerType->mGenericParamDefs.size();
  7259. int wantedGenericParams = (int)typeDef->mGenericParamDefs.size() - numParentGenericParams;
  7260. if (wantedGenericParams != 0)
  7261. {
  7262. if (wantedGenericParams == 1)
  7263. Fail("Expected generic argument", typeRef);
  7264. else
  7265. Fail(StrFormat("Expected %d generic arguments", wantedGenericParams), typeRef);
  7266. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  7267. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  7268. }
  7269. auto parentGenericTypeInstance = (BfTypeInstance*)checkCurType;
  7270. BfTypeInstance* genericTypeInst;
  7271. if (typeDef->mTypeCode == BfTypeCode_TypeAlias)
  7272. {
  7273. auto typeAliasType = new BfTypeAliasType();
  7274. genericTypeInst = typeAliasType;
  7275. }
  7276. else
  7277. genericTypeInst = new BfTypeInstance();
  7278. genericTypeInst->mGenericTypeInfo = new BfGenericTypeInfo();
  7279. genericTypeInst->mTypeDef = typeDef;
  7280. if (parentGenericTypeInstance->mGenericTypeInfo->mGenericParams.IsEmpty())
  7281. PopulateType(parentGenericTypeInstance, BfPopulateType_Declaration);
  7282. for (int i = 0; i < numParentGenericParams; i++)
  7283. {
  7284. genericTypeInst->mGenericTypeInfo->mGenericParams.push_back(parentGenericTypeInstance->mGenericTypeInfo->mGenericParams[i]->AddRef());
  7285. genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.push_back(parentGenericTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i]);
  7286. }
  7287. CheckUnspecializedGenericType(genericTypeInst, populateType);
  7288. resolvedEntry->mValue = genericTypeInst;
  7289. populateModule->InitType(genericTypeInst, populateType);
  7290. BF_ASSERT(BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) == resolvedEntry->mHash);
  7291. return ResolveTypeResult(typeRef, genericTypeInst, populateType, resolveFlags);
  7292. }
  7293. }
  7294. BfTypeInstance* typeInst;
  7295. if (typeDef->mTypeCode == BfTypeCode_TypeAlias)
  7296. {
  7297. auto typeAliasType = new BfTypeAliasType();
  7298. typeInst = typeAliasType;
  7299. }
  7300. else
  7301. {
  7302. typeInst = new BfTypeInstance();
  7303. }
  7304. typeInst->mTypeDef = typeDef;
  7305. if (typeInst->mTypeDef->mGenericParamDefs.size() != 0)
  7306. {
  7307. Fail("Generic type arguments expected", typeRef);
  7308. delete typeInst;
  7309. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  7310. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  7311. }
  7312. resolvedEntry->mValue = typeInst;
  7313. #ifdef _DEBUG
  7314. int typeRefash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx);
  7315. #endif
  7316. populateModule->InitType(typeInst, populateType);
  7317. if (BfResolvedTypeSet::Hash(typeInst, &lookupCtx) != resolvedEntry->mHash)
  7318. {
  7319. int refHash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx);
  7320. int typeHash = BfResolvedTypeSet::Hash(typeInst, &lookupCtx);
  7321. BF_ASSERT(refHash == typeHash);
  7322. }
  7323. {
  7324. BF_ASSERT(BfResolvedTypeSet::Hash(typeInst, &lookupCtx) == resolvedEntry->mHash);
  7325. }
  7326. return ResolveTypeResult(typeRef, typeInst, populateType, resolveFlags);
  7327. }
  7328. else if (auto arrayTypeRef = BfNodeDynCast<BfArrayTypeRef>(typeRef))
  7329. {
  7330. if (arrayTypeRef->mDimensions > 4)
  7331. {
  7332. Fail("Too many array dimensions, consider using a jagged array.", arrayTypeRef);
  7333. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  7334. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  7335. }
  7336. auto elementType = ResolveTypeRef(arrayTypeRef->mElementType, BfPopulateType_Declaration, BfResolveTypeRefFlag_AllowGenericParamConstValue);
  7337. if (elementType == NULL)
  7338. {
  7339. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  7340. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  7341. }
  7342. if ((arrayTypeRef->mDimensions == 1) && (arrayTypeRef->mParams.size() == 1))
  7343. {
  7344. intptr elementCount = -1;
  7345. BfExpression* sizeExpr = BfNodeDynCast<BfExpression>(arrayTypeRef->mParams[0]);
  7346. BF_ASSERT(sizeExpr != NULL);
  7347. if (sizeExpr != NULL)
  7348. {
  7349. BfConstResolver constResolver(this);
  7350. BfType* intType = GetPrimitiveType(BfTypeCode_IntPtr);
  7351. constResolver.mExpectingType = intType;
  7352. constResolver.mAllowGenericConstValue = true;
  7353. BfTypedValue typedVal;
  7354. {
  7355. SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, true);
  7356. typedVal = constResolver.Resolve(sizeExpr, NULL, BfConstResolveFlag_ArrayInitSize);
  7357. }
  7358. if (typedVal.mKind == BfTypedValueKind_GenericConstValue)
  7359. {
  7360. BfUnknownSizedArrayType* arrayType = new BfUnknownSizedArrayType();
  7361. arrayType->mContext = mContext;
  7362. arrayType->mElementType = elementType;
  7363. arrayType->mElementCount = -1;
  7364. arrayType->mElementCountSource = typedVal.mType;
  7365. resolvedEntry->mValue = arrayType;
  7366. BF_ASSERT(BfResolvedTypeSet::Hash(arrayType, &lookupCtx) == resolvedEntry->mHash);
  7367. populateModule->InitType(arrayType, populateType);
  7368. return ResolveTypeResult(typeRef, arrayType, populateType, resolveFlags);
  7369. }
  7370. if (typedVal)
  7371. typedVal = Cast(sizeExpr, typedVal, intType);
  7372. if (typedVal)
  7373. {
  7374. auto constant = mBfIRBuilder->GetConstant(typedVal.mValue);
  7375. if (constant != NULL)
  7376. {
  7377. if (constant->mConstType == BfConstType_Undef)
  7378. elementCount = -1; // Undef marker
  7379. else if (BfIRBuilder::IsInt(constant->mTypeCode))
  7380. elementCount = constant->mInt32;
  7381. }
  7382. }
  7383. }
  7384. /*if (elementCount < 0)
  7385. {
  7386. Fail(StrFormat("Array length '%d' is illegal", elementCount), arrayTypeRef->mParams[0]);
  7387. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  7388. return CreateSizedArrayType(elementType, 0);
  7389. }*/
  7390. BfSizedArrayType* arrayType = new BfSizedArrayType();
  7391. arrayType->mContext = mContext;
  7392. arrayType->mElementType = elementType;
  7393. arrayType->mElementCount = elementCount;
  7394. arrayType->mWantsGCMarking = false; // Fill in in InitType
  7395. resolvedEntry->mValue = arrayType;
  7396. BF_ASSERT(BfResolvedTypeSet::Hash(arrayType, &lookupCtx) == resolvedEntry->mHash);
  7397. populateModule->InitType(arrayType, populateType);
  7398. return ResolveTypeResult(typeRef, arrayType, populateType, resolveFlags);
  7399. }
  7400. BfArrayType* arrayType = new BfArrayType();
  7401. arrayType->mGenericTypeInfo = new BfGenericTypeInfo();
  7402. arrayType->mContext = mContext;
  7403. arrayType->mDimensions = arrayTypeRef->mDimensions;
  7404. arrayType->mTypeDef = mCompiler->GetArrayTypeDef(arrayType->mDimensions);
  7405. arrayType->mGenericTypeInfo->mTypeGenericArguments.push_back(elementType);
  7406. resolvedEntry->mValue = arrayType;
  7407. CheckUnspecializedGenericType(arrayType, populateType);
  7408. BF_ASSERT(BfResolvedTypeSet::Hash(arrayType, &lookupCtx) == resolvedEntry->mHash);
  7409. populateModule->InitType(arrayType, populateType);
  7410. return ResolveTypeResult(typeRef, arrayType, populateType, resolveFlags);
  7411. }
  7412. else if (auto genericTypeInstRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef))
  7413. {
  7414. int wantNumGenericParams = genericTypeInstRef->GetGenericArgCount();
  7415. BfTypeDef* ambiguousTypeDef = NULL;
  7416. Array<BfTypeReference*> genericArguments;
  7417. std::function<void(BfTypeReference*)> _GetTypeRefs = [&](BfTypeReference* typeRef)
  7418. {
  7419. if (auto elementedTypeRef = BfNodeDynCast<BfElementedTypeRef>(typeRef))
  7420. {
  7421. _GetTypeRefs(elementedTypeRef->mElementType);
  7422. }
  7423. else if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(typeRef))
  7424. {
  7425. _GetTypeRefs(qualifiedTypeRef->mLeft);
  7426. }
  7427. if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef))
  7428. {
  7429. for (auto genericArg : genericTypeRef->mGenericArguments)
  7430. genericArguments.push_back(genericArg);
  7431. }
  7432. };
  7433. _GetTypeRefs(genericTypeInstRef);
  7434. BfTypeVector genericArgs;
  7435. BfType* type = NULL;
  7436. BfTypeDef* typeDef = ResolveGenericInstanceDef(genericTypeInstRef, &type);
  7437. if(ambiguousTypeDef != NULL)
  7438. ShowAmbiguousTypeError(typeRef, typeDef, ambiguousTypeDef);
  7439. if (typeDef == NULL)
  7440. {
  7441. Fail("Unable to resolve type", typeRef);
  7442. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  7443. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  7444. }
  7445. BfTypeInstance* outerTypeInstance = mCurTypeInstance;
  7446. auto outerType = typeDef->mOuterType;
  7447. BfTypeDef* commonOuterType = NULL;
  7448. int startDefGenericParamIdx = 0;
  7449. commonOuterType = BfResolvedTypeSet::FindRootCommonOuterType(outerType, &lookupCtx, outerTypeInstance);
  7450. if ((commonOuterType) && (outerTypeInstance->IsGenericTypeInstance()))
  7451. {
  7452. startDefGenericParamIdx = (int)commonOuterType->mGenericParamDefs.size();
  7453. auto parentTypeInstance = outerTypeInstance;
  7454. if (parentTypeInstance->IsTypeAlias())
  7455. parentTypeInstance = (BfTypeInstance*)GetOuterType(parentTypeInstance)->ToTypeInstance();
  7456. for (int i = 0; i < startDefGenericParamIdx; i++)
  7457. genericArgs.push_back(parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i]);
  7458. }
  7459. for (auto genericArgRef : genericArguments)
  7460. {
  7461. auto genericArg = ResolveTypeRef(genericArgRef, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowGenericMethodParamConstValue);
  7462. if (genericArg == NULL)
  7463. {
  7464. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  7465. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  7466. }
  7467. genericArgs.Add(genericArg);
  7468. }
  7469. BfTypeInstance* genericTypeInst;
  7470. if ((type != NULL) &&
  7471. ((type->IsDelegateFromTypeRef()) || (type->IsFunctionFromTypeRef())))
  7472. {
  7473. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  7474. return ResolveGenericType(type, &genericArgs, NULL);
  7475. }
  7476. else if ((type != NULL) && (type->IsTuple()))
  7477. {
  7478. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  7479. return ResolveGenericType(type, &genericArgs, NULL);
  7480. }
  7481. else if ((typeDef != NULL) && (typeDef->mTypeCode == BfTypeCode_TypeAlias))
  7482. {
  7483. auto typeAliasType = new BfTypeAliasType();
  7484. genericTypeInst = typeAliasType;
  7485. }
  7486. else
  7487. genericTypeInst = new BfTypeInstance();
  7488. genericTypeInst->mContext = mContext;
  7489. genericTypeInst->mGenericTypeInfo = new BfGenericTypeInfo();
  7490. BF_ASSERT(typeDef->mDefState != BfTypeDef::DefState_Deleted);
  7491. int genericParamCount = (int)typeDef->mGenericParamDefs.size();
  7492. if ((type != NULL) && (type->IsGenericTypeInstance()))
  7493. {
  7494. // Is a generic type for sure...
  7495. // We need this case for generic methods
  7496. genericParamCount = (int)((BfTypeInstance*)type)->mGenericTypeInfo->mTypeGenericArguments.size();
  7497. }
  7498. else if (typeDef->mGenericParamDefs.size() == 0)
  7499. {
  7500. Fail("Not a generic type", typeRef);
  7501. delete genericTypeInst;
  7502. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  7503. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  7504. }
  7505. genericTypeInst->mTypeDef = typeDef;
  7506. if ((commonOuterType != NULL) && (outerTypeInstance->IsGenericTypeInstance()))
  7507. {
  7508. auto parentTypeInstance = outerTypeInstance;
  7509. if (parentTypeInstance->IsTypeAlias())
  7510. parentTypeInstance = (BfTypeInstance*)GetOuterType(parentTypeInstance)->ToTypeInstance();
  7511. for (int i = 0; i < startDefGenericParamIdx; i++)
  7512. {
  7513. genericTypeInst->mGenericTypeInfo->mGenericParams.push_back(parentTypeInstance->mGenericTypeInfo->mGenericParams[i]->AddRef());
  7514. genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.push_back(parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i]);
  7515. auto typeGenericArg = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[i];
  7516. genericTypeInst->mGenericTypeInfo->mIsUnspecialized |= typeGenericArg->IsGenericParam() || typeGenericArg->IsUnspecializedType();
  7517. }
  7518. }
  7519. int wantedGenericParams = genericParamCount - startDefGenericParamIdx;
  7520. int genericArgDiffCount = (int)genericArguments.size() - wantedGenericParams;
  7521. if (genericArgDiffCount != 0)
  7522. {
  7523. int innerWantedGenericParams = genericParamCount;
  7524. if (typeDef->mOuterType != NULL)
  7525. innerWantedGenericParams -= (int)typeDef->mOuterType->mGenericParamDefs.size();
  7526. ShowGenericArgCountError(genericTypeInstRef, innerWantedGenericParams);
  7527. delete genericTypeInst;
  7528. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  7529. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  7530. }
  7531. int genericParamIdx = 0;
  7532. for (auto genericArgRef : genericArguments)
  7533. {
  7534. auto genericArg = genericArgs[genericParamIdx + startDefGenericParamIdx];
  7535. genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.push_back(genericArg);
  7536. genericTypeInst->mGenericTypeInfo->mTypeGenericArgumentRefs.push_back(genericArgRef);
  7537. genericParamIdx++;
  7538. }
  7539. resolvedEntry->mValue = genericTypeInst;
  7540. CheckUnspecializedGenericType(genericTypeInst, populateType);
  7541. populateModule->InitType(genericTypeInst, populateType);
  7542. #ifdef _DEBUG
  7543. if (BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) != resolvedEntry->mHash)
  7544. {
  7545. int refHash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx);
  7546. int typeHash = BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx);
  7547. BF_ASSERT(refHash == typeHash);
  7548. }
  7549. if (!BfResolvedTypeSet::Equals(genericTypeInst, typeRef, &lookupCtx))
  7550. {
  7551. BF_ASSERT(BfResolvedTypeSet::Equals(genericTypeInst, typeRef, &lookupCtx));
  7552. }
  7553. #endif
  7554. BF_ASSERT(BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) == resolvedEntry->mHash);
  7555. return ResolveTypeResult(typeRef, genericTypeInst, populateType, resolveFlags);
  7556. }
  7557. else if (auto tupleTypeRef = BfNodeDynCast<BfTupleTypeRef>(typeRef))
  7558. {
  7559. Array<BfType*> types;
  7560. Array<String> names;
  7561. bool wantGeneric = false;
  7562. bool isUnspecialized = false;
  7563. for (int fieldIdx = 0; fieldIdx < (int)tupleTypeRef->mFieldTypes.size(); fieldIdx++)
  7564. {
  7565. BfTypeReference* typeRef = tupleTypeRef->mFieldTypes[fieldIdx];
  7566. auto type = ResolveTypeRef(typeRef, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowGenericParamConstValue);
  7567. if (type == NULL)
  7568. {
  7569. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  7570. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  7571. }
  7572. String fieldName;
  7573. BfIdentifierNode* identifierNode = NULL;
  7574. if (fieldIdx < (int)tupleTypeRef->mFieldNames.size())
  7575. identifierNode = tupleTypeRef->mFieldNames[fieldIdx];
  7576. if (identifierNode != NULL)
  7577. fieldName = identifierNode->ToString();
  7578. else
  7579. fieldName = StrFormat("%d", fieldIdx);
  7580. if (type->IsGenericParam())
  7581. wantGeneric = true;
  7582. if (type->IsUnspecializedType())
  7583. isUnspecialized = true;
  7584. BF_ASSERT(!type->IsVar());
  7585. // if (type->IsVar())
  7586. // isUnspecialized = true;
  7587. String typeName = TypeToString(type);
  7588. types.push_back(type);
  7589. names.push_back(fieldName);
  7590. }
  7591. if ((mCurTypeInstance == NULL) || (!mCurTypeInstance->IsGenericTypeInstance()))
  7592. wantGeneric = false;
  7593. auto baseType = (BfTypeInstance*)ResolveTypeDef(mContext->mCompiler->mValueTypeTypeDef, BfPopulateType_Identity);
  7594. BfTypeInstance* tupleType = NULL;
  7595. if (wantGeneric)
  7596. {
  7597. BfTupleType* actualTupleType = new BfTupleType();
  7598. actualTupleType->mGenericTypeInfo = new BfGenericTypeInfo();
  7599. actualTupleType->Init(baseType->mTypeDef->mProject, baseType);
  7600. for (int fieldIdx = 0; fieldIdx < (int)types.size(); fieldIdx++)
  7601. {
  7602. BfFieldDef* fieldDef = actualTupleType->AddField(names[fieldIdx]);
  7603. fieldDef->mProtection = (names[fieldIdx][0] == '_') ? BfProtection_Private : BfProtection_Public;
  7604. }
  7605. actualTupleType->Finish();
  7606. auto parentTypeInstance = (BfTypeInstance*)mCurTypeInstance;
  7607. for (int i = 0; i < parentTypeInstance->mGenericTypeInfo->mGenericParams.size(); i++)
  7608. {
  7609. actualTupleType->mGenericTypeInfo->mGenericParams.push_back(parentTypeInstance->mGenericTypeInfo->mGenericParams[i]->AddRef());
  7610. actualTupleType->mGenericTypeInfo->mTypeGenericArguments.push_back(parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i]);
  7611. auto typeGenericArg = actualTupleType->mGenericTypeInfo->mTypeGenericArguments[i];
  7612. actualTupleType->mGenericTypeInfo->mIsUnspecialized |= typeGenericArg->IsGenericParam() || typeGenericArg->IsUnspecializedType();
  7613. }
  7614. CheckUnspecializedGenericType(actualTupleType, populateType);
  7615. if (isUnspecialized)
  7616. {
  7617. actualTupleType->mGenericTypeInfo->mIsUnspecialized = true;
  7618. actualTupleType->mGenericTypeInfo->mIsUnspecializedVariation = true;
  7619. }
  7620. actualTupleType->mIsUnspecializedType = actualTupleType->mGenericTypeInfo->mIsUnspecialized;
  7621. actualTupleType->mIsUnspecializedTypeVariation = actualTupleType->mGenericTypeInfo->mIsUnspecializedVariation;
  7622. tupleType = actualTupleType;
  7623. }
  7624. else
  7625. {
  7626. BfTupleType* actualTupleType = new BfTupleType();
  7627. actualTupleType->Init(baseType->mTypeDef->mProject, baseType);
  7628. for (int fieldIdx = 0; fieldIdx < (int)types.size(); fieldIdx++)
  7629. {
  7630. BfFieldDef* fieldDef = actualTupleType->AddField(names[fieldIdx]);
  7631. fieldDef->mProtection = (names[fieldIdx][0] == '_') ? BfProtection_Private : BfProtection_Public;
  7632. }
  7633. actualTupleType->Finish();
  7634. tupleType = actualTupleType;
  7635. actualTupleType->mIsUnspecializedType = isUnspecialized;
  7636. actualTupleType->mIsUnspecializedTypeVariation = isUnspecialized;
  7637. }
  7638. tupleType->mFieldInstances.Resize(types.size());
  7639. for (int fieldIdx = 0; fieldIdx < (int)types.size(); fieldIdx++)
  7640. {
  7641. BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx];
  7642. fieldInstance->mFieldIdx = fieldIdx;
  7643. fieldInstance->SetResolvedType(types[fieldIdx]);
  7644. BF_ASSERT(!types[fieldIdx]->IsVar());
  7645. fieldInstance->mOwner = tupleType;
  7646. }
  7647. resolvedEntry->mValue = tupleType;
  7648. BF_ASSERT(BfResolvedTypeSet::Hash(tupleType, &lookupCtx) == resolvedEntry->mHash);
  7649. populateModule->InitType(tupleType, populateType);
  7650. return ResolveTypeResult(typeRef, tupleType, populateType, resolveFlags);
  7651. }
  7652. else if (auto nullableTypeRef = BfNodeDynCast<BfNullableTypeRef>(typeRef))
  7653. {
  7654. BfTypeReference* elementTypeRef = nullableTypeRef->mElementType;
  7655. auto typeDef = mCompiler->mNullableTypeDef;
  7656. auto elementType = ResolveTypeRef(elementTypeRef, BfPopulateType_Declaration, BfResolveTypeRefFlag_AllowGenericParamConstValue);
  7657. if (elementType == NULL)
  7658. {
  7659. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  7660. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  7661. }
  7662. BfTypeInstance* genericTypeInst = new BfTypeInstance();
  7663. genericTypeInst->mGenericTypeInfo = new BfGenericTypeInfo();
  7664. genericTypeInst->mContext = mContext;
  7665. genericTypeInst->mTypeDef = typeDef;
  7666. auto genericParamInstance = new BfGenericTypeParamInstance(typeDef, 0);
  7667. genericTypeInst->mGenericTypeInfo->mGenericParams.push_back(genericParamInstance);
  7668. genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.push_back(elementType);
  7669. //genericTypeInst->mIsUnspecialized = elementType->IsGenericParam() || elementType->IsUnspecializedType();
  7670. CheckUnspecializedGenericType(genericTypeInst, populateType);
  7671. resolvedEntry->mValue = genericTypeInst;
  7672. BF_ASSERT(BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) == resolvedEntry->mHash);
  7673. populateModule->InitType(genericTypeInst, populateType);
  7674. return ResolveTypeResult(typeRef, genericTypeInst, populateType, resolveFlags);
  7675. }
  7676. else if (auto pointerTypeRef = BfNodeDynCast<BfPointerTypeRef>(typeRef))
  7677. {
  7678. BfPointerType* pointerType = new BfPointerType();
  7679. pointerType->mElementType = ResolveTypeRef(pointerTypeRef->mElementType, BfPopulateType_Declaration, BfResolveTypeRefFlag_AllowGenericParamConstValue);
  7680. pointerType->mContext = mContext;
  7681. if (pointerType->mElementType == NULL)
  7682. {
  7683. delete pointerType;
  7684. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  7685. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  7686. }
  7687. resolvedEntry->mValue = pointerType;
  7688. //int hashVal = mContext->mResolvedTypes.Hash(typeRef, &lookupCtx);
  7689. BF_ASSERT(BfResolvedTypeSet::Hash(pointerType, &lookupCtx) == resolvedEntry->mHash);
  7690. populateModule->InitType(pointerType, populateType);
  7691. return ResolveTypeResult(typeRef, pointerType, populateType, resolveFlags);
  7692. }
  7693. else if (auto refTypeRef = BfNodeDynCast<BfRefTypeRef>(typeRef))
  7694. {
  7695. BfRefType* refType = new BfRefType();
  7696. refType->mRefKind = BfRefType::RefKind_Ref;
  7697. if (refTypeRef->mRefToken == NULL)
  7698. refType->mRefKind = BfRefType::RefKind_Ref;
  7699. else if (refTypeRef->mRefToken->GetToken() == BfToken_Out)
  7700. refType->mRefKind = BfRefType::RefKind_Out;
  7701. else if (refTypeRef->mRefToken->GetToken() == BfToken_Mut)
  7702. refType->mRefKind = BfRefType::RefKind_Mut;
  7703. refType->mElementType = ResolveTypeRef(refTypeRef->mElementType, BfPopulateType_Declaration, BfResolveTypeRefFlag_AllowGenericParamConstValue);
  7704. if (refType->mElementType == NULL)
  7705. {
  7706. delete refType;
  7707. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  7708. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  7709. }
  7710. resolvedEntry->mValue = refType;
  7711. BF_ASSERT(BfResolvedTypeSet::Hash(refType, &lookupCtx) == resolvedEntry->mHash);
  7712. populateModule->InitType(refType, populateType);
  7713. return ResolveTypeResult(typeRef, refType, populateType, resolveFlags);
  7714. }
  7715. else if (auto delegateTypeRef = BfNodeDynCast<BfDelegateTypeRef>(typeRef))
  7716. {
  7717. bool wantGeneric = false;
  7718. bool isUnspecialized = false;
  7719. auto _CheckType = [&](BfType* type)
  7720. {
  7721. if (type->IsGenericParam())
  7722. wantGeneric = true;
  7723. if (type->IsUnspecializedType())
  7724. isUnspecialized = true;
  7725. };
  7726. bool failed = false;
  7727. auto returnType = ResolveTypeRef(delegateTypeRef->mReturnType);
  7728. if (returnType == NULL)
  7729. returnType = GetPrimitiveType(BfTypeCode_Var);
  7730. _CheckType(returnType);
  7731. BfType* functionThisType = NULL;
  7732. bool hasMutSpecifier = false;
  7733. bool isFirst = true;
  7734. bool isDelegate = delegateTypeRef->mTypeToken->GetToken() == BfToken_Delegate;
  7735. Array<BfType*> paramTypes;
  7736. for (auto param : delegateTypeRef->mParams)
  7737. {
  7738. BfResolveTypeRefFlags resolveTypeFlags = BfResolveTypeRefFlag_AllowRef;
  7739. if ((param->mNameNode != NULL) && (param->mNameNode->Equals("this")))
  7740. resolveTypeFlags = (BfResolveTypeRefFlags)(resolveTypeFlags | BfResolveTypeRefFlag_NoWarnOnMut);
  7741. auto paramType = ResolveTypeRef(param->mTypeRef, BfPopulateType_Declaration, resolveTypeFlags);
  7742. if (paramType == NULL)
  7743. {
  7744. failed = true;
  7745. paramType = GetPrimitiveType(BfTypeCode_Var);
  7746. }
  7747. if ((!isDelegate) && (isFirst) && (param->mNameNode != NULL) && (param->mNameNode->Equals("this")))
  7748. {
  7749. functionThisType = paramType;
  7750. if (functionThisType->IsRef())
  7751. {
  7752. auto refType = (BfRefType*)functionThisType;
  7753. if (refType->mRefKind != BfRefType::RefKind_Mut)
  7754. {
  7755. if (auto refTypeRef = BfNodeDynCast<BfRefTypeRef>(param->mTypeRef))
  7756. {
  7757. failed = true;
  7758. Fail("Only 'mut' is allowed here", refTypeRef->mRefToken);
  7759. }
  7760. }
  7761. hasMutSpecifier = true;
  7762. functionThisType = refType->mElementType;
  7763. }
  7764. }
  7765. else
  7766. {
  7767. paramTypes.Add(paramType);
  7768. _CheckType(paramType);
  7769. }
  7770. isFirst = false;
  7771. }
  7772. if ((mCurTypeInstance == NULL) || (!mCurTypeInstance->IsGenericTypeInstance()))
  7773. wantGeneric = false;
  7774. auto baseDelegateType = ResolveTypeDef(mCompiler->mDelegateTypeDef)->ToTypeInstance();
  7775. BfDelegateInfo* delegateInfo = NULL;
  7776. BfTypeInstance* delegateType = NULL;
  7777. if (wantGeneric)
  7778. {
  7779. BfDelegateType* genericTypeInst = new BfDelegateType();
  7780. genericTypeInst->mGenericTypeInfo = new BfGenericTypeInfo();
  7781. delegateType = genericTypeInst;
  7782. delegateInfo = delegateType->GetDelegateInfo();
  7783. auto parentTypeInstance = (BfTypeInstance*)mCurTypeInstance;
  7784. for (int i = 0; i < parentTypeInstance->mGenericTypeInfo->mGenericParams.size(); i++)
  7785. {
  7786. genericTypeInst->mGenericTypeInfo->mGenericParams.push_back(parentTypeInstance->mGenericTypeInfo->mGenericParams[i]->AddRef());
  7787. genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.push_back(parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i]);
  7788. auto typeGenericArg = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[i];
  7789. genericTypeInst->mGenericTypeInfo->mIsUnspecialized |= typeGenericArg->IsGenericParam() || typeGenericArg->IsUnspecializedType();
  7790. }
  7791. CheckUnspecializedGenericType(genericTypeInst, populateType);
  7792. // We don't ever need to do an actual pass over generic delegate methods, so it's safe to set the 'unspecialized variation' flag
  7793. if (isUnspecialized)
  7794. {
  7795. genericTypeInst->mGenericTypeInfo->mIsUnspecialized = true;
  7796. genericTypeInst->mGenericTypeInfo->mIsUnspecializedVariation = true;
  7797. }
  7798. genericTypeInst->mIsUnspecializedType = genericTypeInst->mGenericTypeInfo->mIsUnspecialized;
  7799. genericTypeInst->mIsUnspecializedTypeVariation = genericTypeInst->mGenericTypeInfo->mIsUnspecializedVariation;
  7800. }
  7801. else
  7802. {
  7803. auto dlgType = new BfDelegateType();
  7804. delegateInfo = dlgType->GetDelegateInfo();
  7805. dlgType->mIsUnspecializedType = isUnspecialized;
  7806. dlgType->mIsUnspecializedTypeVariation = isUnspecialized;
  7807. delegateType = dlgType;
  7808. }
  7809. Val128 hashContext;
  7810. BfTypeDef* typeDef = new BfTypeDef();
  7811. typeDef->mProject = baseDelegateType->mTypeDef->mProject;
  7812. typeDef->mSystem = mCompiler->mSystem;
  7813. typeDef->mName = mSystem->mEmptyAtom;
  7814. if (delegateTypeRef->mTypeToken->GetToken() == BfToken_Delegate)
  7815. {
  7816. typeDef->mIsDelegate = true;
  7817. typeDef->mTypeCode = BfTypeCode_Object;
  7818. }
  7819. else
  7820. {
  7821. typeDef->mIsFunction = true;
  7822. typeDef->mTypeCode = BfTypeCode_Struct;
  7823. }
  7824. BfMethodDef* methodDef = new BfMethodDef();
  7825. methodDef->mDeclaringType = typeDef;
  7826. methodDef->mName = "Invoke";
  7827. methodDef->mProtection = BfProtection_Public;
  7828. methodDef->mIdx = 0;
  7829. methodDef->mIsStatic = !typeDef->mIsDelegate && (functionThisType == NULL);
  7830. methodDef->mIsMutating = true;
  7831. if ((functionThisType != NULL) && (functionThisType->IsValueType()) && (!hasMutSpecifier))
  7832. methodDef->mIsMutating = false;
  7833. auto directTypeRef = BfAstNode::ZeroedAlloc<BfDirectTypeReference>();
  7834. delegateInfo->mDirectAllocNodes.push_back(directTypeRef);
  7835. if (typeDef->mIsDelegate)
  7836. directTypeRef->Init(delegateType);
  7837. else
  7838. directTypeRef->Init(ResolveTypeDef(mCompiler->mFunctionTypeDef));
  7839. typeDef->mBaseTypes.push_back(directTypeRef);
  7840. directTypeRef = BfAstNode::ZeroedAlloc<BfDirectTypeReference>();
  7841. delegateInfo->mDirectAllocNodes.push_back(directTypeRef);
  7842. directTypeRef->Init(returnType);
  7843. methodDef->mReturnTypeRef = directTypeRef;
  7844. delegateInfo->mReturnType = returnType;
  7845. delegateInfo->mFunctionThisType = functionThisType;
  7846. auto hashVal = mContext->mResolvedTypes.Hash(typeRef, &lookupCtx);
  7847. int paramSrcOfs = (functionThisType != NULL) ? 1 : 0;
  7848. for (int paramIdx = 0; paramIdx < (int)paramTypes.size(); paramIdx++)
  7849. {
  7850. auto param = delegateTypeRef->mParams[paramIdx + paramSrcOfs];
  7851. auto paramType = paramTypes[paramIdx];
  7852. if (paramType == NULL)
  7853. paramType = GetPrimitiveType(BfTypeCode_Var);
  7854. String paramName;
  7855. if (param->mNameNode != NULL)
  7856. paramName = param->mNameNode->ToString();
  7857. if (!paramType->IsReified())
  7858. delegateType->mIsReified = false;
  7859. auto directTypeRef = BfAstNode::ZeroedAlloc<BfDirectTypeReference>();
  7860. delegateInfo->mDirectAllocNodes.push_back(directTypeRef);
  7861. directTypeRef->Init(paramType);
  7862. BfParameterDef* paramDef = new BfParameterDef();
  7863. paramDef->mTypeRef = directTypeRef;
  7864. paramDef->mName = paramName;
  7865. methodDef->mParams.push_back(paramDef);
  7866. delegateInfo->mParams.Add(paramType);
  7867. }
  7868. typeDef->mMethods.push_back(methodDef);
  7869. if (failed)
  7870. {
  7871. delete delegateType;
  7872. mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
  7873. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  7874. }
  7875. //
  7876. BfDefBuilder::AddMethod(typeDef, BfMethodType_Ctor, BfProtection_Public, false, "");
  7877. if (typeDef->mIsDelegate)
  7878. BfDefBuilder::AddDynamicCastMethods(typeDef);
  7879. delegateType->mContext = mContext;
  7880. delegateType->mTypeDef = typeDef;
  7881. populateModule->InitType(delegateType, populateType);
  7882. resolvedEntry->mValue = delegateType;
  7883. AddDependency(directTypeRef->mType, delegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue);
  7884. if (delegateInfo->mFunctionThisType != NULL)
  7885. AddDependency(delegateInfo->mFunctionThisType, delegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue);
  7886. for (auto paramType : paramTypes)
  7887. AddDependency(paramType, delegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue);
  7888. #ifdef _DEBUG
  7889. if (BfResolvedTypeSet::Hash(delegateType, &lookupCtx) != resolvedEntry->mHash)
  7890. {
  7891. int refHash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx);
  7892. int typeHash = BfResolvedTypeSet::Hash(delegateType, &lookupCtx);
  7893. BF_ASSERT(refHash == typeHash);
  7894. }
  7895. BF_ASSERT(BfResolvedTypeSet::Equals(delegateType, typeRef, &lookupCtx));
  7896. #endif
  7897. BF_ASSERT(BfResolvedTypeSet::Hash(delegateType, &lookupCtx) == resolvedEntry->mHash);
  7898. return ResolveTypeResult(typeRef, delegateType, populateType, resolveFlags);
  7899. }
  7900. else if (auto genericParamTypeRef = BfNodeDynCast<BfGenericParamTypeRef>(typeRef))
  7901. {
  7902. auto genericParamType = GetGenericParamType(genericParamTypeRef->mGenericParamKind, genericParamTypeRef->mGenericParamIdx);
  7903. resolvedEntry->mValue = genericParamType;
  7904. BF_ASSERT(BfResolvedTypeSet::Hash(genericParamType, &lookupCtx) == resolvedEntry->mHash);
  7905. return ResolveTypeResult(typeRef, genericParamType, populateType, resolveFlags);
  7906. }
  7907. else if (auto retTypeTypeRef = BfNodeDynCast<BfModifiedTypeRef>(typeRef))
  7908. {
  7909. auto retTypeType = new BfModifiedTypeType();
  7910. retTypeType->mModifiedKind = retTypeTypeRef->mRetTypeToken->mToken;
  7911. retTypeType->mElementType = ResolveTypeRef(retTypeTypeRef->mElementType, BfPopulateType_Declaration, BfResolveTypeRefFlag_AllowGenericParamConstValue);
  7912. // We know this is a generic param type, it can't fail to resolve
  7913. BF_ASSERT(retTypeType->mElementType);
  7914. resolvedEntry->mValue = retTypeType;
  7915. BF_ASSERT(BfResolvedTypeSet::Hash(retTypeType, &lookupCtx) == resolvedEntry->mHash);
  7916. populateModule->InitType(retTypeType, populateType);
  7917. return ResolveTypeResult(typeRef, retTypeType, populateType, resolveFlags);
  7918. }
  7919. else if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(typeRef))
  7920. {
  7921. auto leftType = ResolveTypeRef(qualifiedTypeRef->mLeft, BfPopulateType_Declaration, BfResolveTypeRefFlag_AllowGenericParamConstValue);
  7922. if (leftType == NULL)
  7923. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  7924. return ResolveTypeResult(typeRef, ResolveInnerType(leftType, qualifiedTypeRef->mRight), populateType, resolveFlags);
  7925. }
  7926. else if (auto constTypeRef = BfNodeDynCastExact<BfConstTypeRef>(typeRef))
  7927. {
  7928. return ResolveTypeRef(constTypeRef->mElementType, populateType, (BfResolveTypeRefFlags)(resolveFlags & BfResolveTypeRefFlag_NoResolveGenericParam));
  7929. }
  7930. else if (auto constExprTypeRef = BfNodeDynCastExact<BfConstExprTypeRef>(typeRef))
  7931. {
  7932. auto constExprType = new BfConstExprValueType();
  7933. constExprType->mContext = mContext;
  7934. BfVariant result;
  7935. if (constExprTypeRef->mConstExpr != NULL)
  7936. {
  7937. BfType* constGenericParam = NULL;
  7938. result = mContext->mResolvedTypes.EvaluateToVariant(&lookupCtx, constExprTypeRef->mConstExpr, constGenericParam);
  7939. BF_ASSERT(constGenericParam == NULL);
  7940. }
  7941. constExprType->mType = GetPrimitiveType(result.mTypeCode);
  7942. constExprType->mValue = result;
  7943. resolvedEntry->mValue = constExprType;
  7944. #ifdef _DEBUG
  7945. if (BfResolvedTypeSet::Hash(constExprType, &lookupCtx) != resolvedEntry->mHash)
  7946. {
  7947. int refHash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx);
  7948. int typeHash = BfResolvedTypeSet::Hash(constExprType, &lookupCtx);
  7949. BF_ASSERT(refHash == typeHash);
  7950. }
  7951. BF_ASSERT(BfResolvedTypeSet::Equals(constExprType, typeRef, &lookupCtx));
  7952. #endif
  7953. populateModule->InitType(constExprType, populateType);
  7954. return constExprType;
  7955. }
  7956. else
  7957. {
  7958. BFMODULE_FATAL(this, "Not implemented!");
  7959. NotImpl(typeRef);
  7960. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  7961. }
  7962. return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
  7963. }
  7964. BfType* BfModule::ResolveTypeRefAllowUnboundGenerics(BfTypeReference* typeRef, BfPopulateType populateType, bool resolveGenericParam)
  7965. {
  7966. if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef))
  7967. {
  7968. if (genericTypeRef->mGenericArguments.size() == 0)
  7969. {
  7970. auto genericTypeDef = ResolveGenericInstanceDef(genericTypeRef);
  7971. if (genericTypeDef == NULL)
  7972. return NULL;
  7973. BfTypeVector typeVector;
  7974. for (int i = 0; i < (int)genericTypeDef->mGenericParamDefs.size(); i++)
  7975. typeVector.push_back(GetGenericParamType(BfGenericParamKind_Type, i));
  7976. return ResolveTypeDef(genericTypeDef, typeVector);
  7977. }
  7978. }
  7979. return ResolveTypeRef(typeRef, populateType, resolveGenericParam ? (BfResolveTypeRefFlags)0 : BfResolveTypeRefFlag_NoResolveGenericParam);
  7980. }
  7981. // This finds non-default unspecialized generic type instances and converts them into a BfUnspecializedGenericTypeVariation
  7982. BfType* BfModule::CheckUnspecializedGenericType(BfTypeInstance* genericTypeInst, BfPopulateType populateType)
  7983. {
  7984. int argCount = (int)genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size();
  7985. bool isDefaultUnspecialized = true;
  7986. for (int argIdx = 0; argIdx < argCount; argIdx++)
  7987. {
  7988. auto argType = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[argIdx];
  7989. if (argType->IsGenericParam())
  7990. {
  7991. auto genericParamType = (BfGenericParamType*)argType;
  7992. if ((genericParamType->mGenericParamKind != BfGenericParamKind_Type) || (genericParamType->mGenericParamIdx != argIdx))
  7993. isDefaultUnspecialized = false;
  7994. genericTypeInst->mGenericTypeInfo->mIsUnspecialized = true;
  7995. }
  7996. else if (argType->IsUnspecializedType())
  7997. {
  7998. isDefaultUnspecialized = false;
  7999. genericTypeInst->mGenericTypeInfo->mIsUnspecialized = true;
  8000. }
  8001. else
  8002. isDefaultUnspecialized = false;
  8003. }
  8004. if (genericTypeInst->mGenericTypeInfo->mIsUnspecialized)
  8005. genericTypeInst->mGenericTypeInfo->mIsUnspecializedVariation = !isDefaultUnspecialized;
  8006. return genericTypeInst;
  8007. }
  8008. BfTypeInstance* BfModule::GetUnspecializedTypeInstance(BfTypeInstance* typeInst)
  8009. {
  8010. if (!typeInst->IsGenericTypeInstance())
  8011. return typeInst;
  8012. BF_ASSERT((!typeInst->IsDelegateFromTypeRef()) && (!typeInst->IsFunctionFromTypeRef()));
  8013. auto genericTypeInst = (BfTypeInstance*)typeInst;
  8014. auto result = ResolveTypeDef(genericTypeInst->mTypeDef, BfPopulateType_Declaration);
  8015. BF_ASSERT((result != NULL) && (result->IsUnspecializedType()));
  8016. if (result == NULL)
  8017. return NULL;
  8018. return result->ToTypeInstance();
  8019. }
  8020. BfType* BfModule::ResolveInnerType(BfType* outerType, BfIdentifierNode* identifier, BfPopulateType populateType, bool ignoreErrors)
  8021. {
  8022. BfDirectStrTypeReference typeRef;
  8023. typeRef.Init(identifier->ToString());
  8024. auto type = ResolveInnerType(outerType, &typeRef, populateType, ignoreErrors);
  8025. return type;
  8026. }
  8027. BfType* BfModule::ResolveTypeRef(BfAstNode* astNode, const BfSizedArray<BfTypeReference*>* genericArgs, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags)
  8028. {
  8029. if ((genericArgs == NULL) || (genericArgs->size() == 0))
  8030. {
  8031. if (auto identifier = BfNodeDynCast<BfIdentifierNode>(astNode))
  8032. {
  8033. BfNamedTypeReference typeRef;
  8034. typeRef.mNameNode = identifier;
  8035. typeRef.mSrcEnd = 0;
  8036. typeRef.mToken = BfToken_None;
  8037. auto type = ResolveTypeRef(&typeRef, populateType, resolveFlags);
  8038. return type;
  8039. }
  8040. }
  8041. BfAstAllocator alloc;
  8042. alloc.mSourceData = astNode->GetSourceData();
  8043. std::function<BfTypeReference*(BfAstNode*)> _ConvType = [&] (BfAstNode* astNode) -> BfTypeReference*
  8044. {
  8045. if (auto typeRef = BfNodeDynCast<BfTypeReference>(astNode))
  8046. return typeRef;
  8047. BfTypeReference* result = NULL;
  8048. if (auto identifier = BfNodeDynCast<BfIdentifierNode>(astNode))
  8049. {
  8050. auto* typeRef = alloc.Alloc<BfNamedTypeReference>();
  8051. typeRef->mNameNode = identifier;
  8052. result = typeRef;
  8053. }
  8054. else if (auto memberRefExpr = BfNodeDynCast<BfMemberReferenceExpression>(astNode))
  8055. {
  8056. auto qualifiedTypeRef = alloc.Alloc<BfQualifiedTypeReference>();
  8057. qualifiedTypeRef->mLeft = _ConvType(memberRefExpr->mTarget);
  8058. qualifiedTypeRef->mDot = memberRefExpr->mDotToken;
  8059. qualifiedTypeRef->mRight = _ConvType(memberRefExpr->mMemberName);
  8060. if ((qualifiedTypeRef->mLeft == NULL) || (qualifiedTypeRef->mRight == NULL))
  8061. return NULL;
  8062. result = qualifiedTypeRef;
  8063. }
  8064. if (result == NULL)
  8065. return NULL;
  8066. result->SetSrcStart(astNode->GetSrcStart());
  8067. result->SetSrcEnd(astNode->GetSrcEnd());
  8068. return result;
  8069. };
  8070. auto typeRef = _ConvType(astNode);
  8071. if (typeRef == NULL)
  8072. return NULL;
  8073. if ((genericArgs != NULL) && (genericArgs->size() != 0))
  8074. {
  8075. auto genericInstanceTypeRef = alloc.Alloc<BfGenericInstanceTypeRef>();
  8076. genericInstanceTypeRef->SetSrcStart(typeRef->GetSrcStart());
  8077. genericInstanceTypeRef->mElementType = typeRef;
  8078. #ifdef BF_AST_HAS_PARENT_MEMBER
  8079. typeRef->mParent = genericInstanceTypeRef;
  8080. #endif
  8081. BfDeferredAstSizedArray<BfTypeReference*> arguments(genericInstanceTypeRef->mGenericArguments, &alloc);
  8082. for (auto genericArg : *genericArgs)
  8083. {
  8084. if (genericArg != NULL)
  8085. {
  8086. arguments.push_back(genericArg);
  8087. genericInstanceTypeRef->SetSrcEnd(genericArg->GetSrcEnd());
  8088. }
  8089. }
  8090. typeRef = genericInstanceTypeRef;
  8091. }
  8092. return ResolveTypeRef(typeRef, populateType, resolveFlags);
  8093. }
  8094. // This flow should mirror CastToValue
  8095. bool BfModule::CanCast(BfTypedValue typedVal, BfType* toType, BfCastFlags castFlags)
  8096. {
  8097. BP_ZONE("BfModule::CanCast");
  8098. SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, true);
  8099. return CastToValue(NULL, typedVal, toType, (BfCastFlags)(castFlags | BfCastFlags_SilentFail | BfCastFlags_IsCastCheck));
  8100. }
  8101. bool BfModule::AreSplatsCompatible(BfType* fromType, BfType* toType, bool* outNeedsMemberCasting)
  8102. {
  8103. if ((fromType->IsTypeInstance()) && (!fromType->IsSplattable()))
  8104. return false;
  8105. if ((toType->IsTypeInstance()) && (!toType->IsSplattable()))
  8106. return false;
  8107. auto _GetTypes = [&](BfType* type, Array<BfType*>& types)
  8108. {
  8109. BfTypeUtils::SplatIterate([&](BfType* memberType) { types.Add(memberType); }, type);
  8110. };
  8111. Array<BfType*> fromTypes;
  8112. _GetTypes(fromType, fromTypes);
  8113. Array<BfType*> toTypes;
  8114. _GetTypes(toType, toTypes);
  8115. if (toTypes.size() > fromTypes.size())
  8116. return false;
  8117. for (int i = 0; i < toTypes.size(); i++)
  8118. {
  8119. BfType* fromMemberType = fromTypes[i];
  8120. BfType* toMemberType = toTypes[i];
  8121. if (fromMemberType != toMemberType)
  8122. {
  8123. if ((outNeedsMemberCasting != NULL) &&
  8124. (fromMemberType->IsIntPtrable()) && (toMemberType->IsIntPtrable()))
  8125. *outNeedsMemberCasting = true;
  8126. else
  8127. return false;
  8128. }
  8129. }
  8130. return true;
  8131. }
  8132. BfIRValue BfModule::CastToFunction(BfAstNode* srcNode, BfMethodInstance* methodInstance, BfType* toType, BfCastFlags castFlags)
  8133. {
  8134. auto invokeMethodInstance = GetDelegateInvokeMethod(toType->ToTypeInstance());
  8135. if (invokeMethodInstance->IsExactMatch(methodInstance, false, true))
  8136. {
  8137. BfModuleMethodInstance methodRefMethod;
  8138. if (methodInstance->mDeclModule == this)
  8139. methodRefMethod = methodInstance;
  8140. else
  8141. methodRefMethod = ReferenceExternalMethodInstance(methodInstance);
  8142. auto dataType = GetPrimitiveType(BfTypeCode_IntPtr);
  8143. if (!methodRefMethod.mFunc)
  8144. {
  8145. if (HasCompiledOutput())
  8146. AssertErrorState();
  8147. return GetDefaultValue(dataType);
  8148. }
  8149. auto bindFuncVal = methodRefMethod.mFunc;
  8150. if (mCompiler->mOptions.mAllowHotSwapping)
  8151. bindFuncVal = mBfIRBuilder->RemapBindFunction(bindFuncVal);
  8152. return mBfIRBuilder->CreatePtrToInt(bindFuncVal, BfTypeCode_IntPtr);
  8153. }
  8154. if ((castFlags & BfCastFlags_SilentFail) == 0)
  8155. {
  8156. if (invokeMethodInstance->IsExactMatch(methodInstance, true, true))
  8157. {
  8158. Fail(StrFormat("Non-static method '%s' cannot match '%s' because it contains captured variables, consider using a delegate or removing captures", MethodToString(methodInstance).c_str(), TypeToString(toType).c_str()), srcNode);
  8159. }
  8160. else if (invokeMethodInstance->IsExactMatch(methodInstance, false, false))
  8161. {
  8162. bool handled = false;
  8163. auto thisType = methodInstance->GetParamType(-1);
  8164. if (thisType != NULL)
  8165. {
  8166. if (invokeMethodInstance->HasExplicitThis())
  8167. {
  8168. auto invokeThisType = invokeMethodInstance->GetParamType(-1);
  8169. bool thisWasPtr = false;
  8170. if (thisType->IsPointer())
  8171. {
  8172. thisType = thisType->GetUnderlyingType();
  8173. thisWasPtr = true;
  8174. }
  8175. bool invokeThisWasPtr = false;
  8176. if (invokeThisType->IsPointer())
  8177. {
  8178. invokeThisType = invokeThisType->GetUnderlyingType();
  8179. invokeThisWasPtr = true;
  8180. }
  8181. if (invokeThisType == thisType)
  8182. {
  8183. if (invokeThisWasPtr != thisWasPtr)
  8184. {
  8185. if (invokeThisWasPtr)
  8186. Fail(StrFormat("Non-static method '%s' cannot match '%s', consider removing 'mut' from 'mut %s this' in the function parameters", MethodToString(methodInstance).c_str(), TypeToString(toType).c_str(), TypeToString(thisType).c_str()), srcNode);
  8187. else
  8188. Fail(StrFormat("Non-static method '%s' cannot match '%s', consider adding 'mut' specifier to '%s this' in the function parameters", MethodToString(methodInstance).c_str(), TypeToString(toType).c_str(), TypeToString(thisType).c_str()), srcNode);
  8189. handled = true;
  8190. }
  8191. }
  8192. }
  8193. }
  8194. if ((!methodInstance->mMethodDef->mIsStatic) && (!invokeMethodInstance->HasExplicitThis()))
  8195. {
  8196. handled = true;
  8197. Fail(StrFormat("Non-static method '%s' cannot match '%s', consider adding '%s this' to the function parameters", MethodToString(methodInstance).c_str(), TypeToString(toType).c_str(), TypeToString(thisType).c_str()), srcNode);
  8198. }
  8199. if (!handled)
  8200. {
  8201. if (invokeMethodInstance->mMethodDef->mIsStatic)
  8202. Fail(StrFormat("Static method '%s' cannot match '%s'", MethodToString(methodInstance).c_str(), TypeToString(toType).c_str()).c_str(), srcNode);
  8203. else
  8204. Fail(StrFormat("Non-static method '%s' cannot match '%s'", MethodToString(methodInstance).c_str(), TypeToString(toType).c_str()).c_str(), srcNode);
  8205. }
  8206. }
  8207. }
  8208. return BfIRValue();
  8209. }
  8210. BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfType* toType, BfCastFlags castFlags, BfCastResultFlags* resultFlags)
  8211. {
  8212. bool explicitCast = (castFlags & BfCastFlags_Explicit) != 0;
  8213. bool ignoreErrors = mIgnoreErrors || ((castFlags & BfCastFlags_SilentFail) != 0);
  8214. bool ignoreWrites = mBfIRBuilder->mIgnoreWrites;
  8215. if (typedVal.mType == toType)
  8216. {
  8217. if (resultFlags != NULL)
  8218. {
  8219. if (typedVal.IsAddr())
  8220. *resultFlags = (BfCastResultFlags)(*resultFlags | BfCastResultFlags_IsAddr);
  8221. if (typedVal.mKind == BfTypedValueKind_TempAddr)
  8222. *resultFlags = (BfCastResultFlags)(*resultFlags | BfCastResultFlags_IsTemp);
  8223. }
  8224. else if (typedVal.IsAddr())
  8225. typedVal = LoadValue(typedVal);
  8226. return typedVal.mValue;
  8227. }
  8228. BF_ASSERT(typedVal.mType->mContext == mContext);
  8229. BF_ASSERT(toType->mContext == mContext);
  8230. if ((typedVal.IsAddr()) && (!typedVal.mType->IsValueType()))
  8231. typedVal = LoadValue(typedVal);
  8232. //BF_ASSERT(!typedVal.IsAddr() || typedVal.mType->IsGenericParam() || typedVal.mType->IsValueType());
  8233. // Ref X to Ref Y, X* to Y*
  8234. {
  8235. bool checkUnderlying = false;
  8236. if (((typedVal.mType->IsRef()) && (toType->IsRef())))
  8237. {
  8238. auto fromRefType = (BfRefType*)typedVal.mType;
  8239. auto toRefType = (BfRefType*)toType;
  8240. if (fromRefType->mRefKind == toRefType->mRefKind)
  8241. checkUnderlying = true;
  8242. else if ((fromRefType->mRefKind == BfRefType::RefKind_Ref) && (toRefType->mRefKind == BfRefType::RefKind_Mut))
  8243. checkUnderlying = true; // Allow a ref-to-mut implicit conversion
  8244. }
  8245. if ((typedVal.mType->IsPointer()) && (toType->IsPointer()))
  8246. checkUnderlying = true;
  8247. if (checkUnderlying)
  8248. {
  8249. auto fromInner = typedVal.mType->GetUnderlyingType();
  8250. auto toInner = toType->GetUnderlyingType();
  8251. if (fromInner == toInner)
  8252. {
  8253. return typedVal.mValue;
  8254. }
  8255. if ((fromInner->IsTuple()) && (toInner->IsTuple()))
  8256. {
  8257. auto fromTuple = (BfTupleType*)fromInner;
  8258. auto toTuple = (BfTupleType*)toInner;
  8259. if (fromTuple->mFieldInstances.size() == toTuple->mFieldInstances.size())
  8260. {
  8261. bool matches = true;
  8262. for (int fieldIdx = 0; fieldIdx < (int)fromTuple->mFieldInstances.size(); fieldIdx++)
  8263. {
  8264. if (fromTuple->mFieldInstances[fieldIdx].mResolvedType != toTuple->mFieldInstances[fieldIdx].mResolvedType)
  8265. {
  8266. matches = false;
  8267. break;
  8268. }
  8269. }
  8270. if (matches)
  8271. {
  8272. // This is either a ref or a ptr so we don't need to set the "IsAddr" flag
  8273. typedVal = MakeAddressable(typedVal);
  8274. return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType));
  8275. }
  8276. }
  8277. }
  8278. // ref int <-> ref int64/int32 (of same size)
  8279. if (((fromInner->IsInteger()) && (toInner->IsInteger())) &&
  8280. (fromInner->mSize == toInner->mSize) &&
  8281. (fromInner->IsSigned() == toInner->IsSigned()))
  8282. return typedVal.mValue;
  8283. }
  8284. }
  8285. // Null -> ObjectInst|IFace|ptr
  8286. if ((typedVal.mType->IsNull()) &&
  8287. ((toType->IsObjectOrInterface()) || (toType->IsPointer() || (toType->IsFunction()))))
  8288. {
  8289. return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType));
  8290. }
  8291. if (explicitCast)
  8292. {
  8293. // Func -> void*
  8294. if ((typedVal.mType->IsFunction()) && (toType->IsVoidPtr()))
  8295. {
  8296. return mBfIRBuilder->CreateIntToPtr(typedVal.mValue, mBfIRBuilder->MapType(toType));
  8297. }
  8298. // void* -> Func
  8299. if ((typedVal.mType->IsVoidPtr()) && (toType->IsFunction()))
  8300. {
  8301. return mBfIRBuilder->CreatePtrToInt(typedVal.mValue, BfTypeCode_IntPtr);
  8302. }
  8303. // * -> Valueless
  8304. if (toType->IsVoid())
  8305. return mBfIRBuilder->GetFakeVal();
  8306. // void* -> intptr
  8307. if ((typedVal.mType->IsPointer()) && (toType->IsIntPtr()))
  8308. {
  8309. if ((!ignoreErrors) && (!typedVal.mType->GetUnderlyingType()->IsVoid()) && ((castFlags & BfCastFlags_FromCompiler) == 0))
  8310. {
  8311. Fail(StrFormat("Unable to cast directly from '%s' to '%s', consider casting to void* first", TypeToString(typedVal.mType).c_str(), TypeToString(toType).c_str()), srcNode);
  8312. }
  8313. auto toPrimitive = (BfPrimitiveType*)toType;
  8314. return mBfIRBuilder->CreatePtrToInt(typedVal.mValue, toPrimitive->mTypeDef->mTypeCode);
  8315. }
  8316. // intptr -> void*
  8317. if ((typedVal.mType->IsIntPtr()) && (toType->IsPointer()))
  8318. {
  8319. if ((!ignoreErrors) && (!toType->GetUnderlyingType()->IsVoid()) && ((castFlags & BfCastFlags_FromCompiler) == 0))
  8320. {
  8321. Fail(StrFormat("Unable to cast directly from '%s' to '%s', consider casting to void* first", TypeToString(typedVal.mType).c_str(), TypeToString(toType).c_str()), srcNode);
  8322. }
  8323. return mBfIRBuilder->CreateIntToPtr(typedVal.mValue, mBfIRBuilder->MapType(toType));
  8324. }
  8325. }
  8326. // * <-> Var
  8327. if ((typedVal.mType->IsVar()) || (toType->IsVar()))
  8328. {
  8329. return mBfIRBuilder->CreateUndefValue(mBfIRBuilder->MapType(toType));
  8330. }
  8331. // Generic param -> *
  8332. if ((typedVal.mType->IsGenericParam()) && (!toType->IsGenericParam()))
  8333. {
  8334. if (toType == mContext->mBfObjectType)
  8335. {
  8336. // Always allow casting from generic to object
  8337. return typedVal.mValue;
  8338. }
  8339. auto _CheckGenericParamInstance = [&](BfGenericParamInstance* genericParamInst)
  8340. {
  8341. if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Var) != 0)
  8342. {
  8343. return typedVal.mValue;
  8344. }
  8345. if (toType->IsInterface())
  8346. {
  8347. for (auto iface : genericParamInst->mInterfaceConstraints)
  8348. if (TypeIsSubTypeOf(iface, toType->ToTypeInstance()))
  8349. return GetDefaultValue(toType);
  8350. }
  8351. if (genericParamInst->mTypeConstraint != NULL)
  8352. {
  8353. auto constraintTypeInst = genericParamInst->mTypeConstraint->ToTypeInstance();
  8354. if ((constraintTypeInst != NULL) && (constraintTypeInst->mTypeDef == mCompiler->mEnumTypeDef))
  8355. {
  8356. // Enum->int
  8357. if ((explicitCast) && (toType->IsInteger()))
  8358. return GetDefaultValue(toType);
  8359. }
  8360. auto defaultFromValue = GetDefaultTypedValue(genericParamInst->mTypeConstraint);
  8361. auto result = CastToValue(srcNode, defaultFromValue, toType, (BfCastFlags)(castFlags | BfCastFlags_SilentFail));
  8362. if (result)
  8363. {
  8364. if ((genericParamInst->mTypeConstraint->IsDelegate()) && (toType->IsDelegate()))
  8365. {
  8366. // Don't allow cast when we are constrained by a delegate type, because BfMethodRefs can match and we require an actual alloc
  8367. Fail(StrFormat("Unable to cast '%s' to '%s' because delegate constraints allow valueless direct method references", TypeToString(typedVal.mType).c_str(), TypeToString(toType).c_str()), srcNode);
  8368. return BfIRValue();
  8369. }
  8370. return result;
  8371. }
  8372. }
  8373. // Generic constrained with class or pointer type -> void*
  8374. if (toType->IsVoidPtr())
  8375. {
  8376. if ((genericParamInst->mGenericParamFlags & (BfGenericParamFlag_Class | BfGenericParamFlag_StructPtr)) ||
  8377. ((genericParamInst->mTypeConstraint != NULL) &&
  8378. ((genericParamInst->mTypeConstraint->IsPointer()) ||
  8379. (genericParamInst->mTypeConstraint->IsInstanceOf(mCompiler->mFunctionTypeDef)) ||
  8380. (genericParamInst->mTypeConstraint->IsObjectOrInterface()))))
  8381. {
  8382. return GetDefaultValue(toType);
  8383. }
  8384. }
  8385. return BfIRValue();
  8386. };
  8387. BfIRValue retVal;
  8388. // For these casts, it's just important we get *A* value to work with here,
  8389. // as this is just use for unspecialized parsing. We don't use the generated code
  8390. {
  8391. auto genericParamInst = GetGenericParamInstance((BfGenericParamType*)typedVal.mType);
  8392. retVal = _CheckGenericParamInstance(genericParamInst);
  8393. if (retVal)
  8394. return retVal;
  8395. }
  8396. // Check method generic constraints
  8397. if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mIsUnspecialized) && (mCurMethodInstance->mMethodInfoEx != NULL))
  8398. {
  8399. for (int genericParamIdx = (int)mCurMethodInstance->mMethodInfoEx->mMethodGenericArguments.size();
  8400. genericParamIdx < mCurMethodInstance->mMethodInfoEx->mGenericParams.size(); genericParamIdx++)
  8401. {
  8402. auto genericParamInst = mCurMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
  8403. if (genericParamInst->mExternType == typedVal.mType)
  8404. {
  8405. retVal = _CheckGenericParamInstance(genericParamInst);
  8406. if (retVal)
  8407. return retVal;
  8408. }
  8409. }
  8410. }
  8411. }
  8412. // * -> Generic param
  8413. if (toType->IsGenericParam())
  8414. {
  8415. if (explicitCast)
  8416. {
  8417. // Either an upcast or an unbox
  8418. if ((typedVal.mType == mContext->mBfObjectType) || (typedVal.mType->IsInterface()))
  8419. {
  8420. return GetDefaultValue(toType);
  8421. }
  8422. }
  8423. auto genericParamInst = GetGenericParamInstance((BfGenericParamType*)toType);
  8424. if (genericParamInst->mGenericParamFlags & BfGenericParamFlag_Var)
  8425. return GetDefaultValue(toType);
  8426. if (typedVal.mType->IsNull())
  8427. {
  8428. bool allowCast = (genericParamInst->mGenericParamFlags & BfGenericParamFlag_Class) || (genericParamInst->mGenericParamFlags & BfGenericParamFlag_StructPtr);
  8429. if ((!allowCast) && (genericParamInst->mTypeConstraint != NULL))
  8430. allowCast = genericParamInst->mTypeConstraint->IsObject() || genericParamInst->mTypeConstraint->IsPointer();
  8431. if (allowCast)
  8432. return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType));
  8433. }
  8434. if (genericParamInst->mTypeConstraint != NULL)
  8435. {
  8436. if (genericParamInst->mTypeConstraint->IsInstanceOf(mCompiler->mEnumTypeDef))
  8437. {
  8438. // int->Enum
  8439. if ((explicitCast) && (typedVal.mType->IsInteger()))
  8440. return mBfIRBuilder->GetFakeVal();
  8441. }
  8442. auto castedVal = CastToValue(srcNode, typedVal, genericParamInst->mTypeConstraint, (BfCastFlags)(castFlags | BfCastFlags_SilentFail));
  8443. if (castedVal)
  8444. return castedVal;
  8445. }
  8446. if (explicitCast)
  8447. {
  8448. if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_StructPtr) ||
  8449. ((genericParamInst->mTypeConstraint != NULL) && genericParamInst->mTypeConstraint->IsInstanceOf(mCompiler->mFunctionTypeDef)))
  8450. {
  8451. auto voidPtrType = CreatePointerType(GetPrimitiveType(BfTypeCode_None));
  8452. auto castedVal = CastToValue(srcNode, typedVal, voidPtrType, (BfCastFlags)(castFlags | BfCastFlags_SilentFail));
  8453. if (castedVal)
  8454. return castedVal;
  8455. }
  8456. }
  8457. }
  8458. if ((typedVal.mType->IsTypeInstance()) && (toType->IsTypeInstance()))
  8459. {
  8460. auto fromTypeInstance = typedVal.mType->ToTypeInstance();
  8461. auto toTypeInstance = toType->ToTypeInstance();
  8462. if ((typedVal.mType->IsValueType()) && (toType->IsValueType()))
  8463. {
  8464. bool allowCast = false;
  8465. if (TypeIsSubTypeOf(fromTypeInstance, toTypeInstance))
  8466. allowCast = true;
  8467. if (allowCast)
  8468. {
  8469. PopulateType(toType);
  8470. if (toType->IsValuelessType())
  8471. return BfIRValue::sValueless;
  8472. if (ignoreWrites)
  8473. return mBfIRBuilder->GetFakeVal();
  8474. if (resultFlags != NULL)
  8475. *resultFlags = (BfCastResultFlags)(BfCastResultFlags_IsAddr);
  8476. typedVal = MakeAddressable(typedVal);
  8477. return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapTypeInstPtr(toTypeInstance));
  8478. }
  8479. }
  8480. // ObjectInst|IFace -> object|IFace
  8481. if ((typedVal.mType->IsObject() || (typedVal.mType->IsInterface())) && ((toType->IsObject() || (toType->IsInterface()))))
  8482. {
  8483. bool allowCast = false;
  8484. if (TypeIsSubTypeOf(fromTypeInstance, toTypeInstance))
  8485. allowCast = true;
  8486. else if ((explicitCast) &&
  8487. ((toType->IsInterface()) || (TypeIsSubTypeOf(toTypeInstance, fromTypeInstance))))
  8488. {
  8489. if (toType->IsObjectOrInterface())
  8490. {
  8491. if ((castFlags & BfCastFlags_Unchecked) == 0)
  8492. EmitDynamicCastCheck(typedVal, toType, true);
  8493. }
  8494. allowCast = true;
  8495. }
  8496. if (allowCast)
  8497. {
  8498. if (ignoreWrites)
  8499. return mBfIRBuilder->GetFakeVal();
  8500. return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType));
  8501. }
  8502. }
  8503. }
  8504. // MethodRef -> Function
  8505. if ((typedVal.mType->IsMethodRef()) && (toType->IsFunction()))
  8506. {
  8507. BfMethodInstance* methodInstance = ((BfMethodRefType*)typedVal.mType)->mMethodRef;
  8508. auto result = CastToFunction(srcNode, methodInstance, toType, castFlags);
  8509. if (result)
  8510. return result;
  8511. }
  8512. // concrete IFace -> object|IFace
  8513. if ((typedVal.mType->IsConcreteInterfaceType()) && ((toType->IsObject() || (toType->IsInterface()))))
  8514. {
  8515. auto concreteInterfaceType = (BfConcreteInterfaceType*)typedVal.mType;
  8516. if ((toType->IsObject()) || (concreteInterfaceType->mInterface == toType))
  8517. return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType));
  8518. }
  8519. // IFace -> object
  8520. if ((typedVal.mType->IsInterface()) && (toType == mContext->mBfObjectType))
  8521. return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType));
  8522. // * -> Pointer
  8523. if (toType->IsPointer())
  8524. {
  8525. // Ptr -> Ptr
  8526. if (typedVal.mType->IsPointer())
  8527. {
  8528. bool allowCast = explicitCast;
  8529. auto fromPointerType = (BfPointerType*)typedVal.mType;
  8530. auto toPointerType = (BfPointerType*)toType;
  8531. auto fromUnderlying = fromPointerType->mElementType;
  8532. auto toUnderlying = toPointerType->mElementType;
  8533. // Allow cast from T[size]* to T* implicitly
  8534. // And from T* to T[size]* explicitly
  8535. while (fromUnderlying->IsSizedArray())
  8536. fromUnderlying = fromUnderlying->GetUnderlyingType();
  8537. while ((toUnderlying->IsSizedArray()) && (explicitCast))
  8538. toUnderlying = toUnderlying->GetUnderlyingType();
  8539. if ((fromUnderlying == toUnderlying) ||
  8540. (TypeIsSubTypeOf(fromUnderlying->ToTypeInstance(), toUnderlying->ToTypeInstance())) ||
  8541. (toUnderlying->IsVoid()))
  8542. allowCast = true;
  8543. if (allowCast)
  8544. {
  8545. if (ignoreWrites)
  8546. return mBfIRBuilder->GetFakeVal();
  8547. return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType));
  8548. }
  8549. }
  8550. else if (typedVal.mType->IsObject())
  8551. {
  8552. // ???
  8553. }
  8554. /*else if (typedVal.mType->IsSizedArray())
  8555. {
  8556. if (typedVal.IsAddr())
  8557. {
  8558. BfSizedArrayType* arrayType = (BfSizedArrayType*)typedVal.mType;
  8559. auto ptrType = CreatePointerType(arrayType->mElementType);
  8560. BfTypedValue returnPointer(mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(ptrType)), ptrType);
  8561. return CastToValue(srcNode, returnPointer, toType, castFlags, silentFail);
  8562. }
  8563. }*/
  8564. }
  8565. // Boxing?
  8566. bool mayBeBox = false;
  8567. if (((typedVal.mType->IsValueType()) || (typedVal.mType->IsPointer()) || (typedVal.mType->IsValuelessType())) &&
  8568. ((toType->IsInterface()) || (toType == mContext->mBfObjectType)))
  8569. {
  8570. // Make sure there's no conversion operator before we box
  8571. if ((!typedVal.mType->IsRef()) && (!typedVal.mType->IsModifiedTypeType()))
  8572. mayBeBox = true;
  8573. }
  8574. //TODO: the IsGenericParam is not valid - why did we have that? The generic param could be a struct for example...
  8575. if ((explicitCast) && ((typedVal.mType->IsInterface()) || (typedVal.mType == mContext->mBfObjectType) /*|| (typedVal.mType->IsGenericParam())*/) &&
  8576. ((toType->IsValueType()) || (toType->IsPointer())))
  8577. {
  8578. if (toType->IsValuelessType())
  8579. return BfIRValue::sValueless;
  8580. if (ignoreWrites)
  8581. return mBfIRBuilder->GetFakeVal();
  8582. // Unbox!
  8583. if ((castFlags & BfCastFlags_Unchecked) == 0)
  8584. {
  8585. EmitDynamicCastCheck(typedVal, toType, false);
  8586. EmitObjectAccessCheck(typedVal);
  8587. }
  8588. if (toType->IsNullable())
  8589. {
  8590. auto toTypeInst = toType->ToTypeInstance();
  8591. int valueIdx = toTypeInst->mFieldInstances[0].mDataIdx;
  8592. int hasValueIdx = toTypeInst->mFieldInstances[1].mDataIdx;
  8593. typedVal = MakeAddressable(typedVal);
  8594. auto elementType = toType->GetUnderlyingType();
  8595. auto ptrElementType = CreatePointerType(elementType);
  8596. auto boolType = GetPrimitiveType(BfTypeCode_Boolean);
  8597. auto allocaInst = CreateAlloca(toType, true, "unboxN");
  8598. auto prevBB = mBfIRBuilder->GetInsertBlock();
  8599. auto nullBB = mBfIRBuilder->CreateBlock("unboxN.null");
  8600. auto notNullBB = mBfIRBuilder->CreateBlock("unboxN.notNull");
  8601. auto endBB = mBfIRBuilder->CreateBlock("unboxN.end");
  8602. auto isNull = mBfIRBuilder->CreateIsNull(typedVal.mValue);
  8603. mBfIRBuilder->CreateCondBr(isNull, nullBB, notNullBB);
  8604. int dataIdx = toTypeInst->mFieldInstances[1].mDataIdx;
  8605. mBfIRBuilder->AddBlock(nullBB);
  8606. mBfIRBuilder->SetInsertPoint(nullBB);
  8607. auto hasValueAddr = mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, hasValueIdx); // has_value
  8608. mBfIRBuilder->CreateStore(GetConstValue(0, boolType), hasValueAddr);
  8609. auto nullableValueAddr = mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, valueIdx); // value
  8610. auto nullableValueBits = mBfIRBuilder->CreateBitCast(nullableValueAddr, mBfIRBuilder->GetPrimitiveType(BfTypeCode_NullPtr));
  8611. mBfIRBuilder->CreateMemSet(nullableValueBits, GetConstValue(0, GetPrimitiveType(BfTypeCode_Int8)), GetConstValue(elementType->mSize), elementType->mAlign);
  8612. mBfIRBuilder->CreateBr(endBB);
  8613. mBfIRBuilder->AddBlock(notNullBB);
  8614. mBfIRBuilder->SetInsertPoint(notNullBB);
  8615. hasValueAddr = mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, hasValueIdx); // has_value
  8616. mBfIRBuilder->CreateStore(GetConstValue(1, boolType), hasValueAddr);
  8617. nullableValueAddr = mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, valueIdx); // value
  8618. auto srcObjBits = mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(ptrElementType));
  8619. auto boxedValueAddr = mBfIRBuilder->CreateInBoundsGEP(srcObjBits, 1); // Skip over vdata
  8620. auto boxedValue = mBfIRBuilder->CreateLoad(boxedValueAddr);
  8621. mBfIRBuilder->CreateStore(boxedValue, nullableValueAddr);
  8622. mBfIRBuilder->CreateBr(endBB);
  8623. mBfIRBuilder->AddBlock(endBB);
  8624. mBfIRBuilder->SetInsertPoint(endBB);
  8625. if (resultFlags != NULL)
  8626. *resultFlags = (BfCastResultFlags)(BfCastResultFlags_IsAddr | BfCastResultFlags_IsTemp);
  8627. return allocaInst;
  8628. }
  8629. auto boxedType = CreateBoxedType(toType);
  8630. mBfIRBuilder->PopulateType(boxedType);
  8631. AddDependency(boxedType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields);
  8632. auto boxedObj = mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(boxedType));
  8633. auto valPtr = mBfIRBuilder->CreateInBoundsGEP(boxedObj, 0, 1);
  8634. if ((toType->IsPrimitiveType()) || (toType->IsTypedPrimitive()) || (toType->IsPointer()) || (toType->IsSizedArray()) || (toType->IsMethodRef()))
  8635. {
  8636. valPtr = mBfIRBuilder->CreateBitCast(valPtr, mBfIRBuilder->GetPointerTo(mBfIRBuilder->MapType(toType)));
  8637. }
  8638. if ((toType->IsComposite()) && (resultFlags != NULL))
  8639. {
  8640. *resultFlags = BfCastResultFlags_IsAddr;
  8641. return valPtr;
  8642. }
  8643. else
  8644. return mBfIRBuilder->CreateLoad(valPtr, false);
  8645. }
  8646. // Null -> Nullable<T>
  8647. if ((typedVal.mType->IsNull()) && (toType->IsNullable()))
  8648. {
  8649. if (ignoreWrites)
  8650. return mBfIRBuilder->GetFakeVal();
  8651. if ((castFlags & BfCastFlags_PreferAddr) != 0)
  8652. {
  8653. auto boolType = GetPrimitiveType(BfTypeCode_Boolean);
  8654. auto toTypeInst = toType->ToTypeInstance();
  8655. int hasValueIdx = toTypeInst->mFieldInstances[1].mDataIdx;
  8656. auto allocaInst = CreateAlloca(toType);
  8657. auto hasValueAddr = mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, hasValueIdx); // has_value
  8658. mBfIRBuilder->CreateStore(GetConstValue(0, boolType), hasValueAddr);
  8659. auto typedValue = BfTypedValue(allocaInst, toType, true);
  8660. if (resultFlags != NULL)
  8661. *resultFlags = (BfCastResultFlags)(BfCastResultFlags_IsAddr | BfCastResultFlags_IsTemp);
  8662. return allocaInst;
  8663. }
  8664. auto zeroNullable = mBfIRBuilder->CreateConstStructZero(mBfIRBuilder->MapType(toType));
  8665. return zeroNullable;
  8666. }
  8667. // Nullable<A> -> Nullable<B>
  8668. if ((typedVal.mType->IsNullable()) && (toType->IsNullable()))
  8669. {
  8670. auto fromNullableType = (BfTypeInstance*)typedVal.mType;
  8671. auto toNullableType = (BfTypeInstance*)toType;
  8672. if (ignoreWrites)
  8673. {
  8674. auto toVal = CastToValue(srcNode, BfTypedValue(mBfIRBuilder->GetFakeVal(), fromNullableType->mGenericTypeInfo->mTypeGenericArguments[0]),
  8675. toNullableType->mGenericTypeInfo->mTypeGenericArguments[0], ignoreErrors ? BfCastFlags_SilentFail : BfCastFlags_None);
  8676. if (!toVal)
  8677. return BfIRValue();
  8678. return mBfIRBuilder->GetFakeVal();
  8679. }
  8680. BfIRValue srcPtr = typedVal.mValue;
  8681. if (!typedVal.IsAddr())
  8682. {
  8683. auto srcAlloca = CreateAllocaInst(fromNullableType);
  8684. mBfIRBuilder->CreateStore(typedVal.mValue, srcAlloca);
  8685. srcPtr = srcAlloca;
  8686. }
  8687. auto srcAddr = mBfIRBuilder->CreateInBoundsGEP(srcPtr, 0, 1); // mValue
  8688. auto srcVal = mBfIRBuilder->CreateLoad(srcAddr);
  8689. auto toVal = CastToValue(srcNode, BfTypedValue(srcVal, fromNullableType->mGenericTypeInfo->mTypeGenericArguments[0]),
  8690. toNullableType->mGenericTypeInfo->mTypeGenericArguments[0], ignoreErrors ? BfCastFlags_SilentFail : BfCastFlags_None);
  8691. if (!toVal)
  8692. return BfIRValue();
  8693. auto allocaInst = CreateAllocaInst(toNullableType);
  8694. auto destAddr = mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, 1); // mValue
  8695. mBfIRBuilder->CreateStore(toVal, destAddr);
  8696. srcAddr = mBfIRBuilder->CreateInBoundsGEP(srcPtr, 0, 2); // mHasValue
  8697. srcVal = mBfIRBuilder->CreateLoad(srcAddr);
  8698. destAddr = mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, 2); // mHasValue
  8699. mBfIRBuilder->CreateStore(srcVal, destAddr);
  8700. if (resultFlags != NULL)
  8701. *resultFlags = (BfCastResultFlags)(BfCastResultFlags_IsAddr | BfCastResultFlags_IsTemp);
  8702. return allocaInst;
  8703. }
  8704. // Tuple -> Tuple
  8705. if ((typedVal.mType->IsTuple()) && (toType->IsTuple()))
  8706. {
  8707. auto fromTupleType = (BfTypeInstance*)typedVal.mType;
  8708. auto toTupleType = (BfTypeInstance*)toType;
  8709. PopulateType(fromTupleType);
  8710. PopulateType(toTupleType);
  8711. if (fromTupleType->mFieldInstances.size() == toTupleType->mFieldInstances.size())
  8712. {
  8713. typedVal = LoadValue(typedVal);
  8714. BfIRValue curTupleValue = mBfIRBuilder->CreateUndefValue(mBfIRBuilder->MapType(toTupleType));
  8715. for (int valueIdx = 0; valueIdx < (int)fromTupleType->mFieldInstances.size(); valueIdx++)
  8716. {
  8717. BfFieldInstance* fromFieldInstance = &fromTupleType->mFieldInstances[valueIdx];
  8718. BfFieldInstance* toFieldInstance = &toTupleType->mFieldInstances[valueIdx];
  8719. if (!explicitCast)
  8720. {
  8721. BfFieldDef* fromFieldDef = fromFieldInstance->GetFieldDef();
  8722. BfFieldDef* toFieldDef = toFieldInstance->GetFieldDef();
  8723. // Either the names have to match or one has to be unnamed
  8724. if ((!fromFieldDef->IsUnnamedTupleField()) && (!toFieldDef->IsUnnamedTupleField()) &&
  8725. (fromFieldDef->mName != toFieldDef->mName))
  8726. {
  8727. curTupleValue = BfIRValue();
  8728. break;
  8729. }
  8730. }
  8731. auto fromFieldType = fromFieldInstance->GetResolvedType();
  8732. auto toFieldType = toFieldInstance->GetResolvedType();
  8733. if (toFieldType->IsVoid())
  8734. continue; // Allow sinking to void
  8735. BfIRValue fromFieldValue;
  8736. if (fromFieldInstance->mDataIdx >= 0)
  8737. fromFieldValue = mBfIRBuilder->CreateExtractValue(typedVal.mValue, fromFieldInstance->mDataIdx);
  8738. BfIRValue toFieldValue = CastToValue(srcNode, BfTypedValue(fromFieldValue, fromFieldType), toFieldType, (BfCastFlags)(castFlags | BfCastFlags_Explicit));
  8739. if (!toFieldValue)
  8740. {
  8741. curTupleValue = BfIRValue();
  8742. break;
  8743. }
  8744. if (toFieldInstance->mDataIdx >= 0)
  8745. curTupleValue = mBfIRBuilder->CreateInsertValue(curTupleValue, toFieldValue, toFieldInstance->mDataIdx);
  8746. }
  8747. if (curTupleValue)
  8748. return curTupleValue;
  8749. }
  8750. }
  8751. // -> const <value>
  8752. if (toType->IsConstExprValue())
  8753. {
  8754. auto constant = mBfIRBuilder->GetConstant(typedVal.mValue);
  8755. if (constant != NULL)
  8756. {
  8757. BfConstExprValueType* toConstExprValueType = (BfConstExprValueType*)toType;
  8758. auto variantVal = TypedValueToVariant(srcNode, typedVal);
  8759. if ((mBfIRBuilder->IsInt(variantVal.mTypeCode)) && (mBfIRBuilder->IsInt(toConstExprValueType->mValue.mTypeCode)))
  8760. {
  8761. if (variantVal.mInt64 == toConstExprValueType->mValue.mInt64)
  8762. return typedVal.mValue;
  8763. }
  8764. else if ((mBfIRBuilder->IsFloat(variantVal.mTypeCode)) && (mBfIRBuilder->IsFloat(toConstExprValueType->mValue.mTypeCode)))
  8765. {
  8766. if (variantVal.ToDouble() == toConstExprValueType->mValue.ToDouble())
  8767. return typedVal.mValue;
  8768. }
  8769. if (!ignoreErrors)
  8770. {
  8771. String valStr;
  8772. VariantToString(valStr, variantVal);
  8773. Fail(StrFormat("Unable to cast '%s %s' to '%s'", TypeToString(typedVal.mType).c_str(), valStr.c_str(), TypeToString(toType).c_str()), srcNode);
  8774. }
  8775. }
  8776. }
  8777. if ((typedVal.mType->IsPrimitiveType()) && (toType->IsPrimitiveType()))
  8778. {
  8779. auto fromPrimType = (BfPrimitiveType*)typedVal.mType;
  8780. auto toPrimType = (BfPrimitiveType*)toType;
  8781. BfTypeCode fromTypeCode = fromPrimType->mTypeDef->mTypeCode;
  8782. BfTypeCode toTypeCode = toPrimType->mTypeDef->mTypeCode;
  8783. if (toType->IsIntegral())
  8784. {
  8785. // Allow constant ints to be implicitly casted to a smaller type if they fit
  8786. auto constant = mBfIRBuilder->GetConstant(typedVal.mValue);
  8787. if (constant != NULL)
  8788. {
  8789. if (mBfIRBuilder->IsInt(constant->mTypeCode))
  8790. {
  8791. int64 srcVal = constant->mInt64;
  8792. if (toPrimType->IsChar())
  8793. {
  8794. if (srcVal == 0)
  8795. explicitCast = true;
  8796. }
  8797. else if ((fromPrimType->IsChar()) && (!toPrimType->IsChar()))
  8798. {
  8799. // Never allow this
  8800. }
  8801. else if ((constant->mTypeCode == BfTypeCode_UInt64) && (srcVal < 0))
  8802. {
  8803. // There's nothing that this could fit into
  8804. }
  8805. else if (toType->IsSigned())
  8806. {
  8807. if (toType->mSize == 8) // int64
  8808. explicitCast = true;
  8809. else
  8810. {
  8811. int64 minVal = -(1LL << (8 * toType->mSize - 1));
  8812. int64 maxVal = (1LL << (8 * toType->mSize - 1)) - 1;
  8813. if ((srcVal >= minVal) && (srcVal <= maxVal))
  8814. explicitCast = true;
  8815. }
  8816. }
  8817. else if (toType->mSize == 8) // uint64
  8818. {
  8819. if (srcVal >= 0)
  8820. explicitCast = true;
  8821. }
  8822. else
  8823. {
  8824. int64 minVal = 0;
  8825. int64 maxVal = (1LL << (8 * toType->mSize)) - 1;
  8826. if ((srcVal >= minVal) && (srcVal <= maxVal))
  8827. explicitCast = true;
  8828. }
  8829. }
  8830. else if (constant->mConstType == BfConstType_Undef)
  8831. {
  8832. BF_ASSERT(mBfIRBuilder->mIgnoreWrites);
  8833. auto undefConst = (BfConstantUndef*)constant;
  8834. auto fakeVal = GetFakeTypedValue(GetPrimitiveType(undefConst->mTypeCode));
  8835. // Why did we have this BfCastFlags_Explicit? It broke creating errors on things like "int16 val = TCount;"
  8836. //auto val = CastToValue(srcNode, fakeVal, toType, (BfCastFlags)(castFlags | BfCastFlags_Explicit));
  8837. auto val = CastToValue(srcNode, fakeVal, toType, castFlags);
  8838. if (val)
  8839. return val;
  8840. }
  8841. }
  8842. }
  8843. bool allowCast = false;
  8844. switch (toTypeCode)
  8845. {
  8846. case BfTypeCode_Char16:
  8847. switch (fromTypeCode)
  8848. {
  8849. case BfTypeCode_Char8:
  8850. allowCast = true; break;
  8851. default: break;
  8852. }
  8853. break;
  8854. case BfTypeCode_Int16:
  8855. switch (fromTypeCode)
  8856. {
  8857. case BfTypeCode_Int8:
  8858. allowCast = true; break;
  8859. case BfTypeCode_UInt8:
  8860. allowCast = true; break;
  8861. default: break;
  8862. }
  8863. break;
  8864. case BfTypeCode_UInt16:
  8865. switch (fromTypeCode)
  8866. {
  8867. case BfTypeCode_UInt8:
  8868. allowCast = true; break;
  8869. default: break;
  8870. }
  8871. break;
  8872. case BfTypeCode_Int32:
  8873. switch (fromTypeCode)
  8874. {
  8875. case BfTypeCode_Int8:
  8876. case BfTypeCode_Int16:
  8877. allowCast = true; break;
  8878. case BfTypeCode_IntPtr:
  8879. if (mCompiler->mSystem->mPtrSize == 4)
  8880. allowCast = true;
  8881. break;
  8882. case BfTypeCode_UInt8:
  8883. case BfTypeCode_UInt16:
  8884. allowCast = true; break;
  8885. default: break;
  8886. }
  8887. break;
  8888. case BfTypeCode_Char32:
  8889. switch (fromTypeCode)
  8890. {
  8891. case BfTypeCode_Char8:
  8892. case BfTypeCode_Char16:
  8893. allowCast = true; break;
  8894. default: break;
  8895. }
  8896. break;
  8897. case BfTypeCode_UInt32:
  8898. switch (fromTypeCode)
  8899. {
  8900. case BfTypeCode_UInt8:
  8901. case BfTypeCode_UInt16:
  8902. case BfTypeCode_UInt32:
  8903. allowCast = true; break;
  8904. case BfTypeCode_UIntPtr:
  8905. if (mCompiler->mSystem->mPtrSize == 4)
  8906. allowCast = true;
  8907. break;
  8908. default: break;
  8909. }
  8910. break;
  8911. case BfTypeCode_Int64:
  8912. switch (fromTypeCode)
  8913. {
  8914. case BfTypeCode_Int8:
  8915. case BfTypeCode_Int16:
  8916. case BfTypeCode_Int32:
  8917. case BfTypeCode_IntPtr:
  8918. allowCast = true; break;
  8919. case BfTypeCode_UInt8:
  8920. case BfTypeCode_UInt16:
  8921. case BfTypeCode_UInt32:
  8922. allowCast = true; break;
  8923. default: break;
  8924. }
  8925. break;
  8926. case BfTypeCode_UInt64:
  8927. switch (fromTypeCode)
  8928. {
  8929. case BfTypeCode_UInt8:
  8930. case BfTypeCode_UInt16:
  8931. case BfTypeCode_UInt32:
  8932. case BfTypeCode_UIntPtr:
  8933. allowCast = true; break;
  8934. default: break;
  8935. }
  8936. break;
  8937. case BfTypeCode_IntPtr:
  8938. switch (fromTypeCode)
  8939. {
  8940. case BfTypeCode_Int8:
  8941. case BfTypeCode_Int16:
  8942. case BfTypeCode_Int32:
  8943. allowCast = true; break;
  8944. case BfTypeCode_UInt8:
  8945. case BfTypeCode_UInt16:
  8946. allowCast = true; break;
  8947. case BfTypeCode_UInt32:
  8948. case BfTypeCode_Int64:
  8949. // It may seem that we want this to require an explicit cast,
  8950. // but consider the case of
  8951. // int val = Math.Max(intA, intB)
  8952. // Math.Max has an int32 and int64 override, so we want the correct one to be chosen and
  8953. // to be able to have the int64 return value implicitly used in a 64-bit build
  8954. if (mCompiler->mSystem->mPtrSize == 8)
  8955. allowCast = true;
  8956. break;
  8957. default: break;
  8958. }
  8959. break;
  8960. case BfTypeCode_UIntPtr:
  8961. switch (fromTypeCode)
  8962. {
  8963. case BfTypeCode_UInt8:
  8964. case BfTypeCode_UInt16:
  8965. case BfTypeCode_UInt32:
  8966. allowCast = true; break;
  8967. case BfTypeCode_UInt64:
  8968. if (mCompiler->mSystem->mPtrSize == 8)
  8969. allowCast = true;
  8970. break;
  8971. default: break;
  8972. }
  8973. break;
  8974. case BfTypeCode_Float:
  8975. switch (fromTypeCode)
  8976. {
  8977. case BfTypeCode_Int8:
  8978. case BfTypeCode_Int16:
  8979. case BfTypeCode_Int32:
  8980. case BfTypeCode_Int64:
  8981. case BfTypeCode_IntPtr:
  8982. case BfTypeCode_IntUnknown:
  8983. allowCast = true; break;
  8984. case BfTypeCode_UInt8:
  8985. case BfTypeCode_UInt16:
  8986. case BfTypeCode_UInt32:
  8987. case BfTypeCode_UInt64:
  8988. case BfTypeCode_UIntPtr:
  8989. case BfTypeCode_UIntUnknown:
  8990. allowCast = true; break;
  8991. default: break;
  8992. }
  8993. break;
  8994. case BfTypeCode_Double:
  8995. switch (fromTypeCode)
  8996. {
  8997. case BfTypeCode_Int8:
  8998. case BfTypeCode_Int16:
  8999. case BfTypeCode_Int32:
  9000. case BfTypeCode_Int64:
  9001. case BfTypeCode_IntPtr:
  9002. case BfTypeCode_IntUnknown:
  9003. allowCast = true; break;
  9004. case BfTypeCode_UInt8:
  9005. case BfTypeCode_UInt16:
  9006. case BfTypeCode_UInt32:
  9007. case BfTypeCode_UInt64:
  9008. case BfTypeCode_UIntPtr:
  9009. case BfTypeCode_UIntUnknown:
  9010. allowCast = true; break;
  9011. case BfTypeCode_Float:
  9012. allowCast = true; break;
  9013. default: break;
  9014. }
  9015. break;
  9016. default: break;
  9017. }
  9018. if (explicitCast)
  9019. {
  9020. if (((fromPrimType->IsIntegral()) || (fromPrimType->IsFloat())) &&
  9021. ((toType->IsIntegral()) || (toType->IsFloat())))
  9022. allowCast = true;
  9023. }
  9024. if (allowCast)
  9025. {
  9026. return mBfIRBuilder->CreateNumericCast(typedVal.mValue, typedVal.mType->IsSigned(), toTypeCode);
  9027. }
  9028. }
  9029. if ((typedVal.mValue.IsConst()) && (toType->IsPointer()) && (toType->GetUnderlyingType() == GetPrimitiveType(BfTypeCode_Char8)) && (typedVal.mType->IsInstanceOf(mCompiler->mStringTypeDef)))
  9030. {
  9031. int stringId = GetStringPoolIdx(typedVal.mValue, mBfIRBuilder);
  9032. if (stringId >= 0)
  9033. return GetStringCharPtr(stringId);
  9034. }
  9035. // Check user-defined operators
  9036. if ((castFlags & BfCastFlags_NoConversionOperator) == 0)
  9037. {
  9038. auto fromType = typedVal.mType;
  9039. auto fromTypeInstance = typedVal.mType->ToTypeInstance();
  9040. auto toTypeInstance = toType->ToTypeInstance();
  9041. auto liftedFromType = ((fromTypeInstance != NULL) && fromTypeInstance->IsNullable()) ? fromTypeInstance->GetUnderlyingType() : NULL;
  9042. auto liftedToType = ((toTypeInstance != NULL) && toTypeInstance->IsNullable()) ? toTypeInstance->GetUnderlyingType() : NULL;
  9043. int bestFromDist = INT_MAX;
  9044. BfType* bestFromType = NULL;
  9045. int bestNegFromDist = INT_MAX;
  9046. BfType* bestNegFromType = NULL;
  9047. int bestToDist = INT_MAX;
  9048. BfType* bestToType = NULL;
  9049. int bestNegToDist = INT_MAX;
  9050. BfType* bestNegToType = NULL;
  9051. bool isAmbiguousCast = false;
  9052. BfIRValue conversionResult;
  9053. BfMethodInstance* opMethodInstance = NULL;
  9054. BfType* opMethodSrcType = NULL;
  9055. // Normal, lifted, execute
  9056. for (int pass = 0; pass < 3; pass++)
  9057. {
  9058. auto checkToType = toType;
  9059. auto checkFromType = fromType;
  9060. if (pass == 1)
  9061. {
  9062. if ((bestFromType != NULL) && (bestToType != NULL))
  9063. continue;
  9064. if (liftedFromType != NULL)
  9065. checkFromType = liftedFromType;
  9066. if (liftedToType != NULL)
  9067. checkToType = liftedToType;
  9068. }
  9069. else if (pass == 2)
  9070. {
  9071. if ((bestFromType == NULL) || (bestToType == NULL))
  9072. break;
  9073. }
  9074. BfBaseClassWalker baseClassWalker(fromType, toType, this);
  9075. while (true)
  9076. {
  9077. auto entry = baseClassWalker.Next();
  9078. auto checkInstance = entry.mTypeInstance;
  9079. if (checkInstance == NULL)
  9080. break;
  9081. for (auto operatorDef : checkInstance->mTypeDef->mOperators)
  9082. {
  9083. if (operatorDef->mOperatorDeclaration->mIsConvOperator)
  9084. {
  9085. if ((!explicitCast) && (operatorDef->mOperatorDeclaration->mExplicitToken != NULL) &&
  9086. (operatorDef->mOperatorDeclaration->mExplicitToken->GetToken() == BfToken_Explicit))
  9087. continue;
  9088. auto methodInst = GetRawMethodInstanceAtIdx(checkInstance, operatorDef->mIdx);
  9089. if (methodInst->GetParamCount() != 1)
  9090. {
  9091. AssertErrorState();
  9092. continue;
  9093. }
  9094. auto methodFromType = methodInst->GetParamType(0);
  9095. auto methodToType = methodInst->mReturnType;
  9096. if (methodFromType->IsSelf())
  9097. methodFromType = entry.mSrcType;
  9098. if (methodToType->IsSelf())
  9099. methodToType = entry.mSrcType;
  9100. // Selection pass
  9101. if (pass < 2)
  9102. {
  9103. auto methodCheckFromType = methodFromType;
  9104. auto methodCheckToType = methodToType;
  9105. if (pass == 1)
  9106. {
  9107. // Only check inner type on lifted types when we aren't checking conversions within lifted class
  9108. // This avoid some infinite conversions
  9109. if ((methodCheckFromType->IsNullable()) && (!checkInstance->IsNullable()))
  9110. methodCheckFromType = methodCheckFromType->GetUnderlyingType();
  9111. if ((methodCheckToType->IsNullable()) && (!checkInstance->IsNullable()))
  9112. methodCheckToType = methodCheckToType->GetUnderlyingType();
  9113. }
  9114. int fromDist = GetTypeDistance(methodCheckFromType, checkFromType);
  9115. if (fromDist < 0)
  9116. {
  9117. // Allow us to cast a constant int to a smaller type if it satisfies the cast operator
  9118. if ((typedVal.mValue.IsConst()) && (CanCast(typedVal, methodCheckFromType, BfCastFlags_NoConversionOperator)))
  9119. {
  9120. fromDist = 0;
  9121. }
  9122. }
  9123. int toDist = GetTypeDistance(methodCheckToType, checkToType);
  9124. if ((fromDist == INT_MAX) || (toDist == INT_MAX))
  9125. continue;
  9126. if (((fromDist >= 0) && (toDist >= 0)) || (explicitCast))
  9127. {
  9128. if ((fromDist >= 0) && (fromDist < bestFromDist))
  9129. {
  9130. bestFromDist = fromDist;
  9131. bestFromType = methodFromType;
  9132. }
  9133. if ((toDist >= 0) && (toDist < bestToDist))
  9134. {
  9135. bestToDist = toDist;
  9136. bestToType = methodToType;
  9137. }
  9138. }
  9139. if (explicitCast)
  9140. {
  9141. fromDist = abs(fromDist);
  9142. toDist = abs(toDist);
  9143. if ((fromDist >= 0) && (fromDist < bestNegFromDist))
  9144. {
  9145. bestNegFromDist = fromDist;
  9146. bestNegFromType = methodFromType;
  9147. }
  9148. if ((toDist >= 0) && (toDist < bestNegToDist))
  9149. {
  9150. bestNegToDist = toDist;
  9151. bestNegToType = methodInst->mReturnType;
  9152. }
  9153. }
  9154. }
  9155. else if (pass == 2) // Execution Pass
  9156. {
  9157. if ((methodFromType == bestFromType) && (methodToType == bestToType))
  9158. {
  9159. // Get in native module so our module doesn't get a reference to it - we may not end up calling it at all!
  9160. //BfModuleMethodInstance methodInstance = checkInstance->mModule->GetMethodInstanceAtIdx(checkInstance, operatorDef->mIdx);
  9161. BfMethodInstance* methodInstance = GetRawMethodInstanceAtIdx(checkInstance, operatorDef->mIdx);
  9162. if (opMethodInstance != NULL)
  9163. {
  9164. int prevGenericCount = GetGenericParamAndReturnCount(opMethodInstance);
  9165. int newGenericCount = GetGenericParamAndReturnCount(methodInstance);
  9166. if (newGenericCount > prevGenericCount)
  9167. {
  9168. // Prefer generic match
  9169. opMethodInstance = methodInstance;
  9170. opMethodSrcType = entry.mSrcType;
  9171. }
  9172. else if (newGenericCount < prevGenericCount)
  9173. {
  9174. // Previous was a generic match
  9175. continue;
  9176. }
  9177. else
  9178. {
  9179. isAmbiguousCast = true;
  9180. break;
  9181. }
  9182. }
  9183. else
  9184. {
  9185. opMethodInstance = methodInstance;
  9186. opMethodSrcType = entry.mSrcType;
  9187. }
  9188. }
  9189. }
  9190. }
  9191. }
  9192. if (isAmbiguousCast)
  9193. break;
  9194. if (opMethodInstance != NULL)
  9195. {
  9196. if (mayBeBox)
  9197. {
  9198. if ((!ignoreErrors) && (Fail("Ambiguous cast, may be conversion operator or may be boxing request", srcNode) != NULL))
  9199. mCompiler->mPassInstance->MoreInfo("See conversion operator", opMethodInstance->mMethodDef->GetRefNode());
  9200. }
  9201. BfMethodInstance* methodInstance = GetRawMethodInstance(opMethodInstance->GetOwner(), opMethodInstance->mMethodDef);
  9202. auto methodDeclaration = methodInstance->mMethodDef->GetMethodDeclaration();
  9203. if (methodDeclaration->mBody == NULL)
  9204. {
  9205. // Handle the typedPrim<->underlying part implicitly
  9206. if (fromType->IsTypedPrimitive())
  9207. {
  9208. auto convTypedValue = BfTypedValue(typedVal.mValue, fromType->GetUnderlyingType());
  9209. return CastToValue(srcNode, convTypedValue, toType, (BfCastFlags)(castFlags & ~BfCastFlags_Explicit), NULL);
  9210. }
  9211. else if (toType->IsTypedPrimitive())
  9212. {
  9213. auto castedVal = CastToValue(srcNode, typedVal, toType->GetUnderlyingType(), (BfCastFlags)(castFlags & ~BfCastFlags_Explicit), NULL);
  9214. return castedVal;
  9215. }
  9216. }
  9217. // Actually perform conversion
  9218. BfExprEvaluator exprEvaluator(this);
  9219. auto castedFromValue = Cast(srcNode, typedVal, bestFromType, castFlags);
  9220. if (!castedFromValue)
  9221. return BfIRValue();
  9222. BfTypedValue operatorOut;
  9223. if (ignoreWrites)
  9224. {
  9225. if (opMethodInstance->mReturnType == toType)
  9226. return mBfIRBuilder->GetFakeVal();
  9227. operatorOut = GetDefaultTypedValue(opMethodInstance->mReturnType);
  9228. }
  9229. else
  9230. {
  9231. BfModuleMethodInstance moduleMethodInstance = GetMethodInstance(opMethodInstance->GetOwner(), opMethodInstance->mMethodDef, BfTypeVector());
  9232. SizedArray<BfIRValue, 1> args;
  9233. exprEvaluator.PushArg(castedFromValue, args);
  9234. operatorOut = exprEvaluator.CreateCall(moduleMethodInstance.mMethodInstance, mCompiler->IsSkippingExtraResolveChecks() ? BfIRValue() : moduleMethodInstance.mFunc, false, args);
  9235. if ((operatorOut.mType != NULL) && (operatorOut.mType->IsSelf()))
  9236. {
  9237. BF_ASSERT(IsInGeneric());
  9238. operatorOut = GetDefaultTypedValue(opMethodSrcType);
  9239. }
  9240. }
  9241. return CastToValue(srcNode, operatorOut, toType, castFlags, resultFlags);
  9242. }
  9243. }
  9244. if (bestFromType == NULL)
  9245. bestFromType = bestNegFromType;
  9246. if (bestToType == NULL)
  9247. bestToType = bestNegToType;
  9248. }
  9249. isAmbiguousCast |= ((bestFromType != NULL) && (bestToType != NULL));
  9250. if (isAmbiguousCast)
  9251. {
  9252. if (!ignoreErrors)
  9253. {
  9254. const char* errStr = "Ambiguous conversion operators for casting from '%s' to '%s'";
  9255. Fail(StrFormat(errStr, TypeToString(typedVal.mType).c_str(), TypeToString(toType).c_str()), srcNode);
  9256. }
  9257. return BfIRValue();
  9258. }
  9259. // Check method generic constraints
  9260. if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mIsUnspecialized) && (mCurMethodInstance->mMethodInfoEx != NULL))
  9261. {
  9262. for (int genericParamIdx = 0; genericParamIdx < mCurMethodInstance->mMethodInfoEx->mGenericParams.size(); genericParamIdx++)
  9263. {
  9264. auto genericParam = mCurMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
  9265. for (auto& opConstraint : genericParam->mOperatorConstraints)
  9266. {
  9267. if ((opConstraint.mCastToken == BfToken_Implicit) ||
  9268. ((explicitCast) && (opConstraint.mCastToken == BfToken_Explicit)))
  9269. {
  9270. // If we can convert OUR fromVal to the constraint's fromVal then we may match
  9271. if (CanCast(typedVal, opConstraint.mRightType, BfCastFlags_NoConversionOperator))
  9272. {
  9273. // .. and we can convert the constraint's toType to OUR toType then we're good
  9274. auto opToVal = genericParam->mExternType;
  9275. if (CanCast(BfTypedValue(BfIRValue::sValueless, opToVal), toType, BfCastFlags_NoConversionOperator))
  9276. return mBfIRBuilder->GetFakeVal();
  9277. }
  9278. }
  9279. }
  9280. }
  9281. }
  9282. // Check type generic constraints
  9283. if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsGenericTypeInstance()) && (mCurTypeInstance->IsUnspecializedType()))
  9284. {
  9285. SizedArray<BfGenericParamInstance*, 4> genericParams;
  9286. GetActiveTypeGenericParamInstances(genericParams);
  9287. for (auto genericParam : genericParams)
  9288. {
  9289. for (auto& opConstraint : genericParam->mOperatorConstraints)
  9290. {
  9291. if ((opConstraint.mCastToken == BfToken_Implicit) ||
  9292. ((explicitCast) && (opConstraint.mCastToken == BfToken_Explicit)))
  9293. {
  9294. // If we can convert OUR fromVal to the constraint's fromVal then we may match
  9295. if (CanCast(typedVal, opConstraint.mRightType, BfCastFlags_NoConversionOperator))
  9296. {
  9297. // .. and we can convert the constraint's toType to OUR toType then we're good
  9298. auto opToVal = genericParam->mExternType;
  9299. if (CanCast(BfTypedValue(BfIRValue::sValueless, opToVal), toType, BfCastFlags_NoConversionOperator))
  9300. return mBfIRBuilder->GetFakeVal();
  9301. }
  9302. }
  9303. }
  9304. }
  9305. }
  9306. }
  9307. // Default typed primitive 'underlying casts' happen after checking cast operators
  9308. if (explicitCast)
  9309. {
  9310. // TypedPrimitive -> Primitive
  9311. if ((typedVal.mType->IsTypedPrimitive()) && (!typedVal.mType->IsFunction()) && (toType->IsPrimitiveType()))
  9312. {
  9313. auto fromTypedPrimitiveType = typedVal.mType->ToTypeInstance();
  9314. auto primTypedVal = BfTypedValue(typedVal.mValue, fromTypedPrimitiveType->mFieldInstances.back().mResolvedType, typedVal.IsAddr());
  9315. primTypedVal = LoadValue(primTypedVal);
  9316. return CastToValue(srcNode, primTypedVal, toType, castFlags);
  9317. }
  9318. // TypedPrimitive -> TypedPrimitive
  9319. if ((typedVal.mType->IsTypedPrimitive()) && (!typedVal.mType->IsFunction()) && (toType->IsTypedPrimitive()))
  9320. {
  9321. auto fromTypedPrimitiveType = typedVal.mType->ToTypeInstance();
  9322. auto toTypedPrimitiveType = toType->ToTypeInstance();
  9323. auto fromUnderlyingType = fromTypedPrimitiveType->GetUnderlyingType();
  9324. auto toUnderlyingType = toTypedPrimitiveType->GetUnderlyingType();
  9325. BfTypedValue underlyingTypedValue(typedVal.mValue, fromUnderlyingType, typedVal.IsAddr());
  9326. underlyingTypedValue = LoadValue(underlyingTypedValue);
  9327. BfIRValue castedToValue = CastToValue(srcNode, underlyingTypedValue, toUnderlyingType, (BfCastFlags)(castFlags | BfCastFlags_Explicit));
  9328. if (castedToValue)
  9329. return castedToValue;
  9330. }
  9331. }
  9332. else if ((typedVal.mType->IsTypedPrimitive()) && (toType->IsTypedPrimitive()))
  9333. {
  9334. if (TypeIsSubTypeOf(typedVal.mType->ToTypeInstance(), toType->ToTypeInstance()))
  9335. {
  9336. // These have the same underlying primitive type, just keep it all the same
  9337. if ((resultFlags != NULL) && (typedVal.IsAddr()))
  9338. *resultFlags = BfCastResultFlags_IsAddr;
  9339. return typedVal.mValue;
  9340. }
  9341. }
  9342. // Prim -> TypedPrimitive
  9343. if ((typedVal.mType->IsPrimitiveType()) && (toType->IsTypedPrimitive()))
  9344. {
  9345. bool allowCast = explicitCast;
  9346. if (toType == mCurTypeInstance)
  9347. allowCast = true;
  9348. if ((!allowCast) && (typedVal.mType->IsIntegral()) /*&& (!toType->IsEnum())*/)
  9349. {
  9350. // Allow implicit cast of zero
  9351. auto constant = mBfIRBuilder->GetConstant(typedVal.mValue);
  9352. if ((constant != NULL) && (mBfIRBuilder->IsInt(constant->mTypeCode)))
  9353. {
  9354. allowCast = constant->mInt64 == 0;
  9355. }
  9356. }
  9357. if (allowCast)
  9358. {
  9359. return CastToValue(srcNode, typedVal, toType->GetUnderlyingType(), castFlags);
  9360. }
  9361. }
  9362. if (typedVal.mType->IsBoxed())
  9363. {
  9364. BfBoxedType* boxedType = (BfBoxedType*)typedVal.mType;
  9365. if (boxedType->mElementType->IsGenericParam())
  9366. {
  9367. // If we have a boxed generic param, the actual available interfaces constraints won't be
  9368. // handled, so we need to pass through again as the root generic param
  9369. BfTypedValue unboxedValue = typedVal;
  9370. unboxedValue.mType = boxedType->mElementType;
  9371. auto result = CastToValue(srcNode, unboxedValue, toType, (BfCastFlags)(castFlags | BfCastFlags_SilentFail), resultFlags);
  9372. if (result)
  9373. return result;
  9374. }
  9375. }
  9376. if ((mayBeBox) && ((castFlags & BfCastFlags_NoBox) == 0))
  9377. {
  9378. BfScopeData* scopeData = NULL;
  9379. if (mCurMethodState != NULL)
  9380. {
  9381. if (mCurMethodState->mOverrideScope)
  9382. scopeData = mCurMethodState->mOverrideScope;
  9383. else
  9384. scopeData = mCurMethodState->mCurScope;
  9385. }
  9386. if ((castFlags & BfCastFlags_WarnOnBox) != 0)
  9387. {
  9388. Warn(0, "This implicit boxing will only be in scope during the constructor. Consider using a longer-term allocation such as 'box new'", srcNode);
  9389. }
  9390. SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, ignoreWrites);
  9391. auto value = BoxValue(srcNode, typedVal, toType, scopeData, (castFlags & BfCastFlags_NoBoxDtor) == 0);
  9392. if (value)
  9393. return value.mValue;
  9394. }
  9395. if (!ignoreErrors)
  9396. {
  9397. const char* errStrF = explicitCast ?
  9398. "Unable to cast '%s' to '%s'" :
  9399. "Unable to implicitly cast '%s' to '%s'";
  9400. String errStr = StrFormat(errStrF, TypeToString(typedVal.mType).c_str(), TypeToString(toType).c_str());
  9401. auto error = Fail(errStr, srcNode);
  9402. if ((error != NULL) && (srcNode != NULL))
  9403. {
  9404. if ((mCompiler->IsAutocomplete()) && (mCompiler->mResolvePassData->mAutoComplete->CheckFixit((srcNode))))
  9405. {
  9406. SetAndRestoreValue<bool> ignoreWrites(mBfIRBuilder->mIgnoreWrites);
  9407. SetAndRestoreValue<bool> ignoreErrors(mIgnoreErrors, true);
  9408. if (CastToValue(srcNode, typedVal, toType, (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_SilentFail)))
  9409. {
  9410. bool doWrap = false;
  9411. if (auto unaryOpExpr = BfNodeDynCast<BfUnaryOperatorExpression>(srcNode))
  9412. {
  9413. if ((unaryOpExpr->mOp != BfUnaryOp_AddressOf) && (unaryOpExpr->mOp != BfUnaryOp_Dereference))
  9414. doWrap = true;
  9415. }
  9416. if ((srcNode->IsA<BfCastExpression>()) ||
  9417. (srcNode->IsA<BfBinaryOperatorExpression>()) ||
  9418. (srcNode->IsA<BfConditionalExpression>()))
  9419. doWrap = true;
  9420. BfParserData* parser = srcNode->GetSourceData()->ToParserData();
  9421. String typeName = TypeToString(toType);
  9422. if (doWrap)
  9423. {
  9424. mCompiler->mResolvePassData->mAutoComplete->AddEntry(AutoCompleteEntry("fixit",
  9425. StrFormat("(%s)\tcast|%s|%d|(%s)(|`%d|)", typeName.c_str(), parser->mFileName.c_str(), srcNode->GetSrcStart(), typeName.c_str(), srcNode->GetSrcLength()).c_str()));
  9426. }
  9427. else
  9428. {
  9429. mCompiler->mResolvePassData->mAutoComplete->AddEntry(AutoCompleteEntry("fixit",
  9430. StrFormat("(%s)\tcast|%s|%d|(%s)", typeName.c_str(), parser->mFileName.c_str(), srcNode->GetSrcStart(), typeName.c_str()).c_str()));
  9431. }
  9432. }
  9433. }
  9434. }
  9435. }
  9436. return BfIRValue();
  9437. }
  9438. BfTypedValue BfModule::Cast(BfAstNode* srcNode, const BfTypedValue& typedVal, BfType* toType, BfCastFlags castFlags)
  9439. {
  9440. bool explicitCast = (castFlags & BfCastFlags_Explicit) != 0;
  9441. if (typedVal.mType == toType)
  9442. return typedVal;
  9443. PopulateType(toType, ((castFlags & BfCastFlags_NoConversionOperator) != 0) ? BfPopulateType_Data : BfPopulateType_DataAndMethods);
  9444. if ((castFlags & BfCastFlags_Force) != 0)
  9445. {
  9446. if (toType->IsValuelessType())
  9447. return BfTypedValue(mBfIRBuilder->GetFakeVal(), toType);
  9448. if ((typedVal.mType->IsValueType()) && (!typedVal.IsAddr()) && (typedVal.IsSplat()) && (toType->IsValueType()))
  9449. {
  9450. bool needsMemberCasting = false;
  9451. if (AreSplatsCompatible(typedVal.mType, toType, &needsMemberCasting))
  9452. {
  9453. return BfTypedValue(typedVal.mValue, toType, needsMemberCasting ? BfTypedValueKind_SplatHead_NeedsCasting : BfTypedValueKind_SplatHead);
  9454. }
  9455. }
  9456. if (typedVal.mType->IsValueType())
  9457. {
  9458. auto addrTypedValue = MakeAddressable(typedVal);
  9459. auto toPtrType = CreatePointerType(toType);
  9460. return BfTypedValue(mBfIRBuilder->CreateBitCast(addrTypedValue.mValue, mBfIRBuilder->MapType(toPtrType)), toType, BfTypedValueKind_Addr);
  9461. }
  9462. return BfTypedValue(mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType)), toType);
  9463. }
  9464. // This tuple cast may create a new type if the toType contains 'var' entries
  9465. if ((typedVal.mType->IsTuple()) && (toType->IsTuple()))
  9466. {
  9467. //auto loadedVal = LoadValue(typedVal);
  9468. PopulateType(toType);
  9469. auto fromTupleType = (BfTypeInstance*)typedVal.mType;
  9470. auto toTupleType = (BfTypeInstance*)toType;
  9471. if (fromTupleType == toTupleType)
  9472. return typedVal;
  9473. if (fromTupleType->mFieldInstances.size() == toTupleType->mFieldInstances.size())
  9474. {
  9475. BfTypeVector fieldTypes;
  9476. Array<String> fieldNames;
  9477. bool isCompatible = true;
  9478. bool isExactTypeMatch = true;
  9479. for (int fieldIdx = 0; fieldIdx < (int)fromTupleType->mFieldInstances.size(); fieldIdx++)
  9480. {
  9481. auto fromFieldInst = &fromTupleType->mFieldInstances[fieldIdx];
  9482. auto toFieldInst = &toTupleType->mFieldInstances[fieldIdx];
  9483. auto fromFieldDef = fromFieldInst->GetFieldDef();
  9484. auto toFieldDef = toFieldInst->GetFieldDef();
  9485. if (!toFieldDef->IsUnnamedTupleField())
  9486. {
  9487. if ((!explicitCast) &&
  9488. (!fromFieldDef->IsUnnamedTupleField()) &&
  9489. (fromFieldDef->mName != toFieldDef->mName))
  9490. isCompatible = false;
  9491. fieldNames.push_back(toFieldDef->mName);
  9492. }
  9493. else
  9494. fieldNames.push_back("");
  9495. if (toFieldInst->mResolvedType->IsVar())
  9496. fieldTypes.push_back(fromFieldInst->mResolvedType);
  9497. else
  9498. {
  9499. if (fromFieldInst->mResolvedType != toFieldInst->mResolvedType)
  9500. isExactTypeMatch = false;
  9501. BfCastFlags tryCastFlags = BfCastFlags_SilentFail;
  9502. if (explicitCast)
  9503. tryCastFlags = (BfCastFlags)(tryCastFlags | BfCastFlags_Explicit);
  9504. // The unused-token '?' comes out as 'void', so we allow that to match here. We may want to wrap that with a different fake type
  9505. // so we can give normal implicit-cast-to-void errors
  9506. if ((fromFieldInst->mResolvedType != toFieldInst->mResolvedType) && (!toFieldInst->mResolvedType->IsVoid()) &&
  9507. (!CanCast(GetFakeTypedValue(fromFieldInst->mResolvedType), toFieldInst->mResolvedType, tryCastFlags)))
  9508. isCompatible = false;
  9509. fieldTypes.push_back(toFieldInst->mResolvedType);
  9510. }
  9511. }
  9512. auto tupleType = CreateTupleType(fieldTypes, fieldNames);
  9513. AddDependency(tupleType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields);
  9514. mBfIRBuilder->PopulateType(tupleType);
  9515. if (isCompatible)
  9516. {
  9517. if (isExactTypeMatch)
  9518. {
  9519. if (typedVal.mKind == BfTypedValueKind_TempAddr)
  9520. {
  9521. return BfTypedValue(mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapTypeInstPtr(tupleType)), tupleType, BfTypedValueKind_TempAddr);
  9522. }
  9523. else if (typedVal.IsAddr())
  9524. {
  9525. return BfTypedValue(mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapTypeInstPtr(tupleType)), tupleType, BfTypedValueKind_ReadOnlyAddr);
  9526. }
  9527. else if (typedVal.IsSplat())
  9528. {
  9529. BfTypedValue retTypedValue = typedVal;
  9530. retTypedValue.mType = tupleType;
  9531. return retTypedValue;
  9532. }
  9533. BfIRValue curTupleValue = CreateAlloca(tupleType);
  9534. auto loadedVal = LoadValue(typedVal);
  9535. mBfIRBuilder->CreateStore(loadedVal.mValue, mBfIRBuilder->CreateBitCast(curTupleValue, mBfIRBuilder->MapTypeInstPtr(fromTupleType)));
  9536. return BfTypedValue(curTupleValue, tupleType, BfTypedValueKind_TempAddr);
  9537. }
  9538. BfIRValue curTupleValue = CreateAlloca(tupleType);
  9539. for (int fieldIdx = 0; fieldIdx < (int)fromTupleType->mFieldInstances.size(); fieldIdx++)
  9540. {
  9541. BfFieldInstance* fromFieldInstance = &fromTupleType->mFieldInstances[fieldIdx];
  9542. BfFieldInstance* toFieldInstance = &tupleType->mFieldInstances[fieldIdx];
  9543. if (toFieldInstance->mDataIdx >= 0)
  9544. {
  9545. if (fromFieldInstance->mDataIdx >= 0)
  9546. {
  9547. auto elementVal = ExtractValue(typedVal, fromFieldInstance, fromFieldInstance->mDataIdx);
  9548. elementVal = LoadValue(elementVal);
  9549. auto castedElementVal = Cast(srcNode, elementVal, toFieldInstance->GetResolvedType(), castFlags);
  9550. if (!castedElementVal)
  9551. return BfTypedValue();
  9552. auto fieldRef = mBfIRBuilder->CreateInBoundsGEP(curTupleValue, 0, toFieldInstance->mDataIdx);
  9553. castedElementVal = LoadValue(castedElementVal);
  9554. mBfIRBuilder->CreateStore(castedElementVal.mValue, fieldRef);
  9555. }
  9556. else
  9557. isCompatible = false;
  9558. }
  9559. }
  9560. return BfTypedValue(curTupleValue, tupleType, BfTypedValueKind_TempAddr);
  9561. }
  9562. }
  9563. const char* errStr = explicitCast ?
  9564. "Unable to cast '%s' to '%s'" :
  9565. "Unable to implicitly cast '%s' to '%s'";
  9566. Fail(StrFormat(errStr, TypeToString(typedVal.mType).c_str(), TypeToString(toType).c_str()), srcNode);
  9567. return BfTypedValue();
  9568. }
  9569. // Function->Function and Delegate->Delegate where type is compatible but not exact
  9570. if (((typedVal.mType->IsDelegate()) || (typedVal.mType->IsFunction())) &&
  9571. (typedVal.mType != toType) && // Don't bother to check for exact match, let CastToValue handle this
  9572. ((typedVal.mType->IsDelegate()) == (toType->IsDelegate())) &&
  9573. ((typedVal.mType->IsFunction()) == (toType->IsFunction())))
  9574. {
  9575. auto fromTypeInst = typedVal.mType->ToTypeInstance();
  9576. auto toTypeInst = toType->ToTypeInstance();
  9577. auto fromMethodInst = GetRawMethodByName(fromTypeInst, "Invoke", -1, true);
  9578. auto toMethodInst = GetRawMethodByName(toTypeInst, "Invoke", -1, true);
  9579. if ((fromMethodInst != NULL) && (toMethodInst != NULL) &&
  9580. (fromMethodInst->mMethodDef->mCallingConvention == toMethodInst->mMethodDef->mCallingConvention) &&
  9581. (fromMethodInst->mReturnType == toMethodInst->mReturnType) &&
  9582. (fromMethodInst->GetParamCount() == toMethodInst->GetParamCount()))
  9583. {
  9584. bool matched = true;
  9585. StringT<64> fromParamName;
  9586. StringT<64> toParamName;
  9587. if (fromMethodInst->HasExplicitThis() != toMethodInst->HasExplicitThis())
  9588. {
  9589. matched = false;
  9590. }
  9591. else
  9592. {
  9593. for (int paramIdx = fromMethodInst->HasExplicitThis() ? -1 : 0; paramIdx < (int)fromMethodInst->GetParamCount(); paramIdx++)
  9594. {
  9595. bool nameMatches = true;
  9596. if (!explicitCast)
  9597. {
  9598. fromMethodInst->GetParamName(paramIdx, fromParamName);
  9599. toMethodInst->GetParamName(paramIdx, toParamName);
  9600. if ((!fromParamName.IsEmpty()) && (!toParamName.IsEmpty()))
  9601. nameMatches = fromParamName == toParamName;
  9602. }
  9603. if ((fromMethodInst->GetParamKind(paramIdx) == toMethodInst->GetParamKind(paramIdx)) &&
  9604. (fromMethodInst->GetParamType(paramIdx) == toMethodInst->GetParamType(paramIdx)) &&
  9605. (nameMatches))
  9606. {
  9607. // Matched, required for implicit/explicit
  9608. }
  9609. else
  9610. {
  9611. matched = false;
  9612. break;
  9613. }
  9614. }
  9615. }
  9616. if (matched)
  9617. {
  9618. BfTypedValue loadedVal = LoadValue(typedVal);
  9619. return BfTypedValue(mBfIRBuilder->CreateBitCast(loadedVal.mValue, mBfIRBuilder->MapType(toType)), toType);
  9620. }
  9621. }
  9622. }
  9623. // Struct truncate
  9624. if ((typedVal.mType->IsStruct()) && (toType->IsStruct()))
  9625. {
  9626. auto fromStructTypeInstance = typedVal.mType->ToTypeInstance();
  9627. auto toStructTypeInstance = toType->ToTypeInstance();
  9628. if (TypeIsSubTypeOf(fromStructTypeInstance, toStructTypeInstance))
  9629. {
  9630. if (typedVal.IsSplat())
  9631. {
  9632. BF_ASSERT(toStructTypeInstance->IsSplattable() || (toStructTypeInstance->mInstSize == 0));
  9633. return BfTypedValue(typedVal.mValue, toStructTypeInstance, typedVal.IsThis() ? BfTypedValueKind_ThisSplatHead : BfTypedValueKind_SplatHead);
  9634. }
  9635. if (typedVal.IsAddr())
  9636. {
  9637. BfIRValue castedIRValue;
  9638. if (typedVal.mValue.IsFake())
  9639. castedIRValue = typedVal.mValue;
  9640. else
  9641. castedIRValue = mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapTypeInstPtr(toStructTypeInstance));
  9642. return BfTypedValue(castedIRValue, toType, typedVal.IsThis() ?
  9643. (typedVal.IsReadOnly() ? BfTypedValueKind_ReadOnlyThisAddr : BfTypedValueKind_ThisAddr) :
  9644. (typedVal.IsReadOnly() ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr));
  9645. }
  9646. BfTypedValue curTypedVal = typedVal;
  9647. while (curTypedVal.mType != toStructTypeInstance)
  9648. {
  9649. mBfIRBuilder->PopulateType(curTypedVal.mType);
  9650. auto curTypeInstance = curTypedVal.mType->ToTypeInstance();
  9651. BfIRValue extractedValue;
  9652. if (toStructTypeInstance->IsValuelessType())
  9653. extractedValue = mBfIRBuilder->GetFakeVal();
  9654. else
  9655. extractedValue = mBfIRBuilder->CreateExtractValue(curTypedVal.mValue, 0);
  9656. curTypedVal = BfTypedValue(extractedValue, curTypeInstance->mBaseType, typedVal.IsThis() ?
  9657. (typedVal.IsReadOnly() ? BfTypedValueKind_ReadOnlyThisValue : BfTypedValueKind_ThisValue) :
  9658. BfTypedValueKind_Value);
  9659. }
  9660. return curTypedVal;
  9661. }
  9662. }
  9663. /*if ((explicitCast) && (toType->IsValuelessType()))
  9664. {
  9665. return BfTypedValue(mBfIRBuilder->GetFakeVal(), toType);
  9666. }*/
  9667. BfCastResultFlags castResultFlags = BfCastResultFlags_None;
  9668. auto castedValue = CastToValue(srcNode, typedVal, toType, castFlags, &castResultFlags);
  9669. if (!castedValue)
  9670. return BfTypedValue();
  9671. if ((castResultFlags & BfCastResultFlags_IsAddr) != 0)
  9672. {
  9673. if ((castResultFlags & BfCastResultFlags_IsTemp) != 0)
  9674. return BfTypedValue(castedValue, toType, BfTypedValueKind_TempAddr);
  9675. return BfTypedValue(castedValue, toType, BfTypedValueKind_Addr);
  9676. }
  9677. return BfTypedValue(castedValue, toType, BfTypedValueKind_Value);
  9678. }
  9679. BfPrimitiveType* BfModule::GetIntCoercibleType(BfType* type)
  9680. {
  9681. if (type->IsSizedArray())
  9682. {
  9683. auto sizedArray = (BfSizedArrayType*)type;
  9684. if ((sizedArray->mElementType->IsChar()) && (sizedArray->mElementType->mSize == 1))
  9685. {
  9686. auto primType = (BfPrimitiveType*)sizedArray->mElementType;
  9687. if (sizedArray->mElementCount == 1)
  9688. return GetPrimitiveType(BfTypeCode_UInt8);
  9689. if (sizedArray->mElementCount == 2)
  9690. return GetPrimitiveType(BfTypeCode_UInt16);
  9691. if (sizedArray->mElementCount == 4)
  9692. return GetPrimitiveType(BfTypeCode_UInt32);
  9693. if (sizedArray->mElementCount == 8)
  9694. return GetPrimitiveType(BfTypeCode_UInt64);
  9695. }
  9696. }
  9697. return NULL;
  9698. }
  9699. BfTypedValue BfModule::GetIntCoercible(const BfTypedValue& typedValue)
  9700. {
  9701. auto intType = GetIntCoercibleType(typedValue.mType);
  9702. if (intType == NULL)
  9703. return BfTypedValue();
  9704. if (typedValue.mValue.IsConst())
  9705. {
  9706. auto constant = mBfIRBuilder->GetConstant(typedValue.mValue);
  9707. if (constant->mConstType == BfConstType_Array)
  9708. {
  9709. uint64 intVal = 0;
  9710. auto constantArray = (BfConstantArray*)constant;
  9711. int memberIdx = 0;
  9712. for (int memberIdx = 0; memberIdx < (int)constantArray->mValues.size(); memberIdx++)
  9713. {
  9714. auto memberConstant = mBfIRBuilder->GetConstant(constantArray->mValues[memberIdx]);
  9715. if (memberConstant->mTypeCode == BfTypeCode_Char8)
  9716. {
  9717. intVal |= (uint64)(memberConstant->mUInt8) << (8 * memberIdx);
  9718. //intVal = (intVal << 8) | memberConstant->mUInt8;
  9719. }
  9720. }
  9721. return BfTypedValue(mBfIRBuilder->CreateConst(intType->mTypeDef->mTypeCode, intVal), intType);
  9722. }
  9723. }
  9724. auto convTypedValue = typedValue;
  9725. convTypedValue = MakeAddressable(convTypedValue);
  9726. auto intPtrType = CreatePointerType(intType);
  9727. auto addrVal = mBfIRBuilder->CreateBitCast(convTypedValue.mValue, mBfIRBuilder->MapType(intPtrType));
  9728. auto val = mBfIRBuilder->CreateLoad(addrVal);
  9729. return BfTypedValue(val, intType);
  9730. }
  9731. bool BfModule::TypeHasParentOrEquals(BfTypeDef* checkChildTypeDef, BfTypeDef* checkParentTypeDef)
  9732. {
  9733. BfTypeDef* checkType = checkChildTypeDef;
  9734. if (checkType->mNestDepth < checkParentTypeDef->mNestDepth)
  9735. return false;
  9736. while (checkType->mNestDepth > checkParentTypeDef->mNestDepth)
  9737. checkType = checkType->mOuterType;
  9738. if (checkType == checkParentTypeDef)
  9739. return true;
  9740. if (checkType->mNameEx != checkParentTypeDef->mNameEx)
  9741. return false;
  9742. if (checkType->mIsPartial)
  9743. {
  9744. for (auto partial : checkParentTypeDef->mPartials)
  9745. if (partial == checkType)
  9746. return true;
  9747. }
  9748. return false;
  9749. }
  9750. BfTypeDef* BfModule::FindCommonOuterType(BfTypeDef* type, BfTypeDef* type2)
  9751. {
  9752. if ((type == NULL) || (type2 == NULL))
  9753. return NULL;
  9754. int curNestDepth = std::min(type->mNestDepth, type2->mNestDepth);
  9755. while (type->mNestDepth > curNestDepth)
  9756. type = type->mOuterType;
  9757. while (type2->mNestDepth > curNestDepth)
  9758. type2 = type2->mOuterType;
  9759. while (curNestDepth >= 0)
  9760. {
  9761. if ((!type->mIsPartial) && (!type2->mIsPartial))
  9762. {
  9763. if (type == type2)
  9764. return type;
  9765. }
  9766. else
  9767. {
  9768. if (type->mFullNameEx == type2->mFullNameEx)
  9769. return type;
  9770. }
  9771. type = type->mOuterType;
  9772. type2 = type2->mOuterType;
  9773. curNestDepth--;
  9774. }
  9775. return NULL;
  9776. }
  9777. bool BfModule::TypeIsSubTypeOf(BfTypeInstance* srcType, BfTypeInstance* wantType, bool checkAccessibility)
  9778. {
  9779. if ((srcType == NULL) || (wantType == NULL))
  9780. return false;
  9781. if (srcType == wantType)
  9782. return true;
  9783. if (srcType->mDefineState < BfTypeDefineState_HasInterfaces)
  9784. {
  9785. // Type is incomplete. We don't do the IsIncomplete check here because of re-entry
  9786. // While handling 'var' resolution, we don't want to force a PopulateType reentry
  9787. // but we do have enough information for TypeIsSubTypeOf
  9788. PopulateType(srcType, BfPopulateType_Interfaces);
  9789. }
  9790. if (wantType->IsInterface())
  9791. {
  9792. BfTypeDef* checkActiveTypeDef = NULL;
  9793. bool checkAccessibility = true;
  9794. if (IsInSpecializedSection())
  9795. {
  9796. // When we have a specialized section, the generic params may not be considered "included"
  9797. // in the module that contains the generic type definition. We rely on any casting errors
  9798. // to be thrown on the unspecialized type pass. We have a similar issue with injecting mixins.
  9799. checkAccessibility = false;
  9800. }
  9801. auto checkType = srcType;
  9802. while (checkType != NULL)
  9803. {
  9804. for (auto ifaceInst : checkType->mInterfaces)
  9805. {
  9806. if (ifaceInst.mInterfaceType == wantType)
  9807. {
  9808. if (checkAccessibility)
  9809. {
  9810. if (checkActiveTypeDef == NULL)
  9811. checkActiveTypeDef = GetActiveTypeDef(NULL, false);
  9812. // We need to be lenient when validating generic constraints
  9813. // Otherwise "T<A> where T : IB" declared in a lib won't be able to match a type B in a using project 'C',
  9814. // because this check will see the lib using 'C', which it won't consider visible
  9815. if ((checkActiveTypeDef != NULL) &&
  9816. ((mCurMethodInstance != NULL) && (mContext->mCurTypeState != NULL) && (mContext->mCurTypeState->mResolveKind != BfTypeState::ResolveKind_BuildingGenericParams)))
  9817. {
  9818. if ((!srcType->IsTypeMemberAccessible(ifaceInst.mDeclaringType, checkActiveTypeDef)) ||
  9819. (!srcType->IsTypeMemberIncluded(ifaceInst.mDeclaringType, checkActiveTypeDef, this)))
  9820. {
  9821. continue;
  9822. }
  9823. }
  9824. }
  9825. return true;
  9826. }
  9827. }
  9828. checkType = checkType->GetImplBaseType();
  9829. if ((checkType != NULL) && (checkType->mDefineState < BfTypeDefineState_HasInterfaces))
  9830. {
  9831. PopulateType(checkType, BfPopulateType_Interfaces);
  9832. }
  9833. }
  9834. if (srcType->IsTypedPrimitive())
  9835. {
  9836. BfType* underlyingType = srcType->GetUnderlyingType();
  9837. if (underlyingType->IsWrappableType())
  9838. {
  9839. BfTypeInstance* wrappedType = GetWrappedStructType(underlyingType);
  9840. if ((wrappedType != NULL) && (wrappedType != srcType))
  9841. return TypeIsSubTypeOf(wrappedType, wantType, checkAccessibility);
  9842. }
  9843. }
  9844. return false;
  9845. }
  9846. auto srcBaseType = srcType->mBaseType;
  9847. return TypeIsSubTypeOf(srcBaseType, wantType);
  9848. }
  9849. // Positive value means that toType encompasses fromType, negative value means toType is encompassed by formType
  9850. // INT_MAX means the types are not related
  9851. int BfModule::GetTypeDistance(BfType* fromType, BfType* toType)
  9852. {
  9853. if (fromType == toType)
  9854. return 0;
  9855. if (fromType->IsPrimitiveType())
  9856. {
  9857. if (!toType->IsPrimitiveType())
  9858. return INT_MAX;
  9859. auto fromPrimType = (BfPrimitiveType*)fromType;
  9860. auto toPrimType = (BfPrimitiveType*)toType;
  9861. if ((fromPrimType->IsIntegral()) && (toPrimType->IsIntegral()))
  9862. {
  9863. int fromBitSize = fromPrimType->mSize * 8;
  9864. if (fromPrimType->IsSigned())
  9865. fromBitSize--;
  9866. int toBitSize = toPrimType->mSize * 8;
  9867. if (toPrimType->IsSigned())
  9868. toBitSize--;
  9869. return fromBitSize - toBitSize;
  9870. }
  9871. if ((fromPrimType->IsFloat()) && (toPrimType->IsFloat()))
  9872. {
  9873. return (fromPrimType->mSize * 8) - (toPrimType->mSize * 8);
  9874. }
  9875. if (((fromPrimType->IsIntegral()) || (fromPrimType->IsFloat())) &&
  9876. ((toPrimType->IsIntegral()) || (toPrimType->IsFloat())))
  9877. {
  9878. int sizeDiff = (fromPrimType->mSize * 8) - (toPrimType->mSize * 8);
  9879. if (sizeDiff < 0)
  9880. sizeDiff--;
  9881. else
  9882. sizeDiff++;
  9883. return sizeDiff;
  9884. }
  9885. return INT_MAX;
  9886. }
  9887. auto fromTypeInstance = fromType->ToTypeInstance();
  9888. auto toTypeInstance = toType->ToTypeInstance();
  9889. if ((fromTypeInstance != NULL) != (toTypeInstance != NULL))
  9890. return INT_MAX; // Ever valid?
  9891. if ((fromTypeInstance != NULL) && (toTypeInstance != NULL))
  9892. {
  9893. if ((fromTypeInstance->IsNullable()) && (toTypeInstance->IsNullable()))
  9894. return GetTypeDistance(fromTypeInstance->GetUnderlyingType(), toTypeInstance->GetUnderlyingType());
  9895. int inheritDistance = toTypeInstance->mInheritDepth - fromTypeInstance->mInheritDepth;
  9896. auto mostSpecificInstance = (inheritDistance < 0) ? fromTypeInstance : toTypeInstance;
  9897. auto leastSpecificInstance = (inheritDistance < 0) ? toTypeInstance : fromTypeInstance;
  9898. while (mostSpecificInstance != NULL)
  9899. {
  9900. if (mostSpecificInstance == leastSpecificInstance)
  9901. return inheritDistance;
  9902. mostSpecificInstance = mostSpecificInstance->mBaseType;
  9903. }
  9904. }
  9905. return INT_MAX;
  9906. }
  9907. bool BfModule::IsTypeMoreSpecific(BfType* leftType, BfType* rightType)
  9908. {
  9909. if (leftType->IsGenericTypeInstance())
  9910. {
  9911. if (!rightType->IsGenericTypeInstance())
  9912. return true;
  9913. auto leftGenericType = (BfTypeInstance*)leftType;
  9914. auto rightGenericType = (BfTypeInstance*)rightType;
  9915. if (leftGenericType->mTypeDef != rightGenericType->mTypeDef)
  9916. return false;
  9917. bool isBetter = false;
  9918. bool isWorse = false;
  9919. for (int argIdx = 0; argIdx < (int)leftGenericType->mGenericTypeInfo->mTypeGenericArguments.size(); argIdx++)
  9920. {
  9921. if (IsTypeMoreSpecific(leftGenericType->mGenericTypeInfo->mTypeGenericArguments[argIdx], rightGenericType->mGenericTypeInfo->mTypeGenericArguments[argIdx]))
  9922. isBetter = true;
  9923. if (IsTypeMoreSpecific(rightGenericType->mGenericTypeInfo->mTypeGenericArguments[argIdx], leftGenericType->mGenericTypeInfo->mTypeGenericArguments[argIdx]))
  9924. isWorse = true;
  9925. }
  9926. return (isBetter) && (!isWorse);
  9927. }
  9928. return false;
  9929. }
  9930. StringT<128> BfModule::TypeToString(BfType* resolvedType, Array<String>* genericMethodParamNameOverrides)
  9931. {
  9932. BfTypeNameFlags flags = BfTypeNameFlags_None;
  9933. if ((mCurTypeInstance == NULL) || (!mCurTypeInstance->IsUnspecializedTypeVariation()))
  9934. flags = BfTypeNameFlag_ResolveGenericParamNames;
  9935. StringT<128> str;
  9936. DoTypeToString(str, resolvedType, flags, genericMethodParamNameOverrides);
  9937. return str;
  9938. }
  9939. StringT<128> BfModule::TypeToString(BfType* resolvedType, BfTypeNameFlags typeNameFlags, Array<String>* genericMethodParamNameOverrides)
  9940. {
  9941. StringT<128> str;
  9942. DoTypeToString(str, resolvedType, typeNameFlags, genericMethodParamNameOverrides);
  9943. return str;
  9944. }
  9945. void BfModule::VariantToString(StringImpl& str, const BfVariant& variant)
  9946. {
  9947. switch (variant.mTypeCode)
  9948. {
  9949. case BfTypeCode_Char8:
  9950. case BfTypeCode_Int8:
  9951. case BfTypeCode_UInt8:
  9952. case BfTypeCode_Int16:
  9953. case BfTypeCode_UInt16:
  9954. case BfTypeCode_Int32:
  9955. str += StrFormat("%d", variant.mInt32);
  9956. break;
  9957. case BfTypeCode_UInt32:
  9958. str += StrFormat("%lu", variant.mUInt32);
  9959. break;
  9960. case BfTypeCode_Int64:
  9961. str += StrFormat("%lld", variant.mInt64);
  9962. break;
  9963. case BfTypeCode_UInt64:
  9964. str += StrFormat("%llu", variant.mInt64);
  9965. break;
  9966. case BfTypeCode_Float:
  9967. {
  9968. char cstr[64];
  9969. ExactMinimalFloatToStr(variant.mSingle, cstr);
  9970. str += cstr;
  9971. if (strchr(cstr, '.') == NULL)
  9972. str += ".0f";
  9973. else
  9974. str += "f";
  9975. }
  9976. break;
  9977. case BfTypeCode_Double:
  9978. {
  9979. char cstr[64];
  9980. ExactMinimalDoubleToStr(variant.mDouble, cstr);
  9981. str += cstr;
  9982. if (strchr(cstr, '.') == NULL)
  9983. str += ".0";
  9984. }
  9985. break;
  9986. default: break;
  9987. }
  9988. }
  9989. void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameFlags typeNameFlags, Array<String>* genericMethodNameOverrides)
  9990. {
  9991. BP_ZONE("BfModule::DoTypeToString");
  9992. // This is clearly wrong. If we pass in @T0 from a generic type, this would immediately disable the ability to get its name
  9993. /*if (resolvedType->IsUnspecializedType())
  9994. typeNameFlags = (BfTypeNameFlags)(typeNameFlags & ~BfTypeNameFlag_ResolveGenericParamNames);*/
  9995. if (resolvedType->IsBoxed())
  9996. {
  9997. auto boxedType = (BfBoxedType*)resolvedType;
  9998. str += "boxed ";
  9999. DoTypeToString(str, boxedType->mElementType, typeNameFlags, genericMethodNameOverrides);
  10000. if (boxedType->mBoxedFlags == BfBoxedType::BoxedFlags_StructPtr)
  10001. str += "*";
  10002. return;
  10003. }
  10004. else if ((resolvedType->IsArray()) && ((typeNameFlags & BfTypeNameFlag_UseArrayImplType) == 0))
  10005. {
  10006. auto arrayType = (BfArrayType*)resolvedType;
  10007. DoTypeToString(str, arrayType->mGenericTypeInfo->mTypeGenericArguments[0], typeNameFlags, genericMethodNameOverrides);
  10008. str += "[";
  10009. for (int i = 1; i < arrayType->mDimensions; i++)
  10010. str += ",";
  10011. str += "]";
  10012. return;
  10013. }
  10014. else if (resolvedType->IsNullable())
  10015. {
  10016. auto genericType = (BfTypeInstance*)resolvedType;
  10017. auto elementType = genericType->mGenericTypeInfo->mTypeGenericArguments[0];
  10018. DoTypeToString(str, elementType, typeNameFlags, genericMethodNameOverrides);
  10019. str += "?";
  10020. return;
  10021. }
  10022. else if (resolvedType->IsTuple())
  10023. {
  10024. BfTypeInstance* tupleType = (BfTypeInstance*)resolvedType;
  10025. str += "(";
  10026. for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
  10027. {
  10028. if (fieldIdx > 0)
  10029. str += ", ";
  10030. BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx];
  10031. BfFieldDef* fieldDef = fieldInstance->GetFieldDef();
  10032. BfTypeNameFlags innerFlags = (BfTypeNameFlags)(typeNameFlags & ~(BfTypeNameFlag_OmitNamespace | BfTypeNameFlag_OmitOuterType));
  10033. DoTypeToString(str, fieldInstance->GetResolvedType(), innerFlags, genericMethodNameOverrides);
  10034. char c = fieldDef->mName[0];
  10035. if ((c < '0') || (c > '9'))
  10036. {
  10037. str += " ";
  10038. str += fieldDef->mName;
  10039. }
  10040. }
  10041. str += ")";
  10042. return;
  10043. }
  10044. else if (resolvedType->IsDelegateFromTypeRef() || resolvedType->IsFunctionFromTypeRef())
  10045. {
  10046. SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance);
  10047. auto delegateType = (BfTypeInstance*)resolvedType;
  10048. auto delegateInfo = resolvedType->GetDelegateInfo();
  10049. if (mCurTypeInstance == delegateType)
  10050. {
  10051. // Don't try to use ourselves for generic param resolution. This should only happen for debug printings from
  10052. // within InitType and such, not actual user-facing display
  10053. mCurTypeInstance = NULL;
  10054. }
  10055. auto methodDef = delegateType->mTypeDef->mMethods[0];
  10056. switch (methodDef->mCallingConvention)
  10057. {
  10058. case BfCallingConvention_Stdcall:
  10059. str += "[StdCall] ";
  10060. break;
  10061. case BfCallingConvention_Fastcall:
  10062. str += "[FastCall] ";
  10063. break;
  10064. default:
  10065. break;
  10066. }
  10067. if (resolvedType->IsDelegateFromTypeRef())
  10068. str += "delegate ";
  10069. else
  10070. str += "function ";
  10071. DoTypeToString(str, delegateInfo->mReturnType, typeNameFlags, genericMethodNameOverrides);
  10072. str += "(";
  10073. bool isFirstParam = true;
  10074. if (delegateInfo->mFunctionThisType != NULL)
  10075. {
  10076. if ((methodDef->mIsMutating) && (delegateInfo->mFunctionThisType->IsValueType()))
  10077. str += "mut ";
  10078. DoTypeToString(str, delegateInfo->mFunctionThisType, typeNameFlags, genericMethodNameOverrides);
  10079. str += " this";
  10080. isFirstParam = false;
  10081. }
  10082. for (int paramIdx = 0; paramIdx < methodDef->mParams.size(); paramIdx++)
  10083. {
  10084. if (!isFirstParam)
  10085. str += ", ";
  10086. auto paramDef = methodDef->mParams[paramIdx];
  10087. BfTypeNameFlags innerFlags = (BfTypeNameFlags)(typeNameFlags & ~(BfTypeNameFlag_OmitNamespace | BfTypeNameFlag_OmitOuterType));
  10088. DoTypeToString(str, delegateInfo->mParams[paramIdx], innerFlags, genericMethodNameOverrides);
  10089. if (!paramDef->mName.IsEmpty())
  10090. {
  10091. str += " ";
  10092. str += paramDef->mName;
  10093. }
  10094. isFirstParam = false;
  10095. }
  10096. str += ")";
  10097. return;
  10098. }
  10099. else if (resolvedType->IsMethodRef())
  10100. {
  10101. auto methodRefType = (BfMethodRefType*)resolvedType;
  10102. BfMethodInstance* methodInstance = methodRefType->mMethodRef;
  10103. if (methodRefType->IsDeleting())
  10104. {
  10105. str += "DELETED METHODREF";
  10106. return;
  10107. }
  10108. if (methodInstance == NULL)
  10109. {
  10110. str += "method reference NULL";
  10111. return;
  10112. }
  10113. str += "method reference ";
  10114. str += MethodToString(methodInstance);
  10115. return;
  10116. }
  10117. else if (resolvedType->IsTypeInstance())
  10118. {
  10119. BfTypeInstance* typeInstance = (BfTypeInstance*)resolvedType;
  10120. bool omitNamespace = (typeNameFlags & BfTypeNameFlag_OmitNamespace) != 0;
  10121. if ((typeNameFlags & BfTypeNameFlag_ReduceName) != 0)
  10122. {
  10123. for (auto& checkNamespace : mCurTypeInstance->mTypeDef->mNamespaceSearch)
  10124. {
  10125. if (checkNamespace == typeInstance->mTypeDef->mNamespace)
  10126. omitNamespace = true;
  10127. }
  10128. }
  10129. if ((!typeInstance->mTypeDef->mNamespace.IsEmpty()) && (!omitNamespace))
  10130. {
  10131. if (!typeInstance->mTypeDef->mNamespace.IsEmpty())
  10132. {
  10133. typeInstance->mTypeDef->mNamespace.ToString(str);
  10134. if (!typeInstance->mTypeDef->IsGlobalsContainer())
  10135. str += '.';
  10136. }
  10137. }
  10138. SizedArray<BfTypeDef*, 8> typeDefStack;
  10139. BfTypeDef* endTypeDef = NULL;
  10140. if (((typeNameFlags & BfTypeNameFlag_ReduceName) != 0) && (mCurTypeInstance != NULL))
  10141. {
  10142. auto checkTypeInst = typeInstance;
  10143. auto outerTypeInst = GetOuterType(checkTypeInst);
  10144. if (outerTypeInst != NULL)
  10145. {
  10146. checkTypeInst = outerTypeInst;
  10147. auto checkTypeDef = checkTypeInst->mTypeDef;
  10148. auto checkCurTypeInst = mCurTypeInstance; // Only used for ReduceName
  10149. BfTypeDef* checkCurTypeDef = NULL;
  10150. if (checkCurTypeInst != NULL)
  10151. checkCurTypeDef = checkCurTypeInst->mTypeDef;
  10152. while (checkCurTypeDef->mNestDepth > checkTypeDef->mNestDepth)
  10153. {
  10154. checkCurTypeInst = GetOuterType(checkCurTypeInst);
  10155. checkCurTypeDef = checkCurTypeInst->mTypeDef;
  10156. }
  10157. while (checkTypeDef != NULL)
  10158. {
  10159. if (TypeIsSubTypeOf(checkCurTypeInst, checkTypeInst))
  10160. {
  10161. endTypeDef = checkTypeDef;
  10162. break;
  10163. }
  10164. checkCurTypeInst = GetOuterType(checkCurTypeInst);
  10165. if (checkCurTypeInst == NULL)
  10166. break;
  10167. checkCurTypeDef = checkCurTypeInst->mTypeDef;
  10168. checkTypeInst = GetOuterType(checkTypeInst);
  10169. if (checkTypeInst == NULL)
  10170. break;
  10171. checkTypeDef = checkTypeInst->mTypeDef;
  10172. }
  10173. }
  10174. }
  10175. BfTypeDef* checkTypeDef = typeInstance->mTypeDef;
  10176. while (checkTypeDef != NULL)
  10177. {
  10178. typeDefStack.Add(checkTypeDef);
  10179. checkTypeDef = checkTypeDef->mOuterType;
  10180. if ((typeNameFlags & BfTypeNameFlag_OmitOuterType) != 0)
  10181. break;
  10182. if (checkTypeDef == endTypeDef)
  10183. break;
  10184. }
  10185. while (!typeDefStack.IsEmpty())
  10186. {
  10187. BfTypeDef* checkTypeDef = typeDefStack.back();
  10188. int depth = (int)typeDefStack.size() - 1;
  10189. typeDefStack.pop_back();
  10190. if (checkTypeDef->IsGlobalsContainer())
  10191. {
  10192. if ((typeNameFlags & BfTypeNameFlag_AddGlobalContainerName) != 0)
  10193. {
  10194. str += "G$";
  10195. str += checkTypeDef->mProject->mName;
  10196. }
  10197. }
  10198. else
  10199. {
  10200. checkTypeDef->mName->ToString(str);
  10201. if (!checkTypeDef->mGenericParamDefs.IsEmpty())
  10202. {
  10203. for (int ofs = 0; ofs < 3; ofs++)
  10204. {
  10205. int checkIdx = (int)str.length() - 1 - ofs;
  10206. if (checkIdx < 0)
  10207. break;
  10208. if (str[checkIdx] == '`')
  10209. {
  10210. str.RemoveToEnd(checkIdx);
  10211. break;
  10212. }
  10213. }
  10214. }
  10215. if (((typeNameFlags & BfTypeNameFlag_DisambiguateDups) != 0) && (checkTypeDef->mDupDetectedRevision != -1))
  10216. {
  10217. str += StrFormat("_%p", checkTypeDef);
  10218. }
  10219. }
  10220. int prevGenericParamCount = 0;
  10221. if (checkTypeDef->mOuterType != NULL)
  10222. {
  10223. prevGenericParamCount = (int)checkTypeDef->mOuterType->mGenericParamDefs.size();
  10224. }
  10225. if (resolvedType->IsGenericTypeInstance())
  10226. {
  10227. auto genericTypeInst = (BfTypeInstance*)resolvedType;
  10228. if (prevGenericParamCount != (int)checkTypeDef->mGenericParamDefs.size())
  10229. {
  10230. str += '<';
  10231. for (int i = prevGenericParamCount; i < (int)checkTypeDef->mGenericParamDefs.size(); i++)
  10232. {
  10233. BfType* typeGenericArg = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[i];
  10234. if (typeGenericArg->IsGenericParam())
  10235. {
  10236. if ((typeNameFlags & BfTypeNameFlag_ResolveGenericParamNames) == 0)
  10237. {
  10238. // We don't want the param names, just the commas (this is an unspecialized type reference)
  10239. if (i > prevGenericParamCount)
  10240. str += ',';
  10241. if ((typeNameFlags & BfTypeNameFlag_UseUnspecializedGenericParamNames) != 0)
  10242. {
  10243. str += checkTypeDef->mGenericParamDefs[i]->mName;
  10244. }
  10245. continue;
  10246. }
  10247. }
  10248. if (i > prevGenericParamCount)
  10249. str += ", ";
  10250. DoTypeToString(str, typeGenericArg, (BfTypeNameFlags)(typeNameFlags & ~(BfTypeNameFlag_OmitNamespace | BfTypeNameFlag_OmitOuterType)), genericMethodNameOverrides);
  10251. }
  10252. str += '>';
  10253. }
  10254. }
  10255. if (depth > 0)
  10256. str += '.';
  10257. };
  10258. return;
  10259. }
  10260. else if (resolvedType->IsPrimitiveType())
  10261. {
  10262. auto primitiveType = (BfPrimitiveType*)resolvedType;
  10263. if (!primitiveType->mTypeDef->mNamespace.IsEmpty())
  10264. {
  10265. primitiveType->mTypeDef->mNamespace.ToString(str);
  10266. str += '.';
  10267. primitiveType->mTypeDef->mName->ToString(str);
  10268. return;
  10269. }
  10270. else
  10271. {
  10272. primitiveType->mTypeDef->mName->ToString(str);
  10273. return;
  10274. }
  10275. }
  10276. else if (resolvedType->IsPointer())
  10277. {
  10278. auto pointerType = (BfPointerType*)resolvedType;
  10279. DoTypeToString(str, pointerType->mElementType, typeNameFlags, genericMethodNameOverrides);
  10280. str += '*';
  10281. return;
  10282. }
  10283. else if (resolvedType->IsGenericParam())
  10284. {
  10285. bool doResolveGenericParams = (typeNameFlags & BfTypeNameFlag_ResolveGenericParamNames) != 0;
  10286. if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsUnspecializedTypeVariation()))
  10287. doResolveGenericParams = false;
  10288. auto genericParam = (BfGenericParamType*)resolvedType;
  10289. if (genericParam->mGenericParamKind == BfGenericParamKind_Method)
  10290. {
  10291. if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mIsUnspecializedVariation))
  10292. doResolveGenericParams = false;
  10293. }
  10294. if (!doResolveGenericParams)
  10295. {
  10296. if (genericParam->mGenericParamKind == BfGenericParamKind_Method)
  10297. {
  10298. if (genericMethodNameOverrides != NULL)
  10299. {
  10300. BF_ASSERT(genericParam->mGenericParamIdx < genericMethodNameOverrides->mSize);
  10301. if (genericParam->mGenericParamIdx < genericMethodNameOverrides->mSize)
  10302. {
  10303. str += (*genericMethodNameOverrides)[genericParam->mGenericParamIdx];
  10304. return;
  10305. }
  10306. }
  10307. str += StrFormat("@M%d", genericParam->mGenericParamIdx);
  10308. return;
  10309. }
  10310. str += StrFormat("@T%d", genericParam->mGenericParamIdx);
  10311. return;
  10312. }
  10313. if ((genericParam->mGenericParamKind == BfGenericParamKind_Type) && (mCurTypeInstance == NULL))
  10314. {
  10315. str += StrFormat("@T%d", genericParam->mGenericParamIdx);
  10316. return;
  10317. }
  10318. if (genericParam->mGenericParamKind == BfGenericParamKind_Method)
  10319. {
  10320. if (genericMethodNameOverrides != NULL)
  10321. {
  10322. str += (*genericMethodNameOverrides)[genericParam->mGenericParamIdx];
  10323. return;
  10324. }
  10325. if (mCurMethodInstance == NULL)
  10326. {
  10327. str += StrFormat("@M%d", genericParam->mGenericParamIdx);
  10328. return;
  10329. }
  10330. }
  10331. //TEMPORARY
  10332. if (genericParam->mGenericParamKind == BfGenericParamKind_Type)
  10333. {
  10334. auto curTypeInstance = mCurTypeInstance;
  10335. if (mCurMethodInstance != NULL)
  10336. curTypeInstance = mCurMethodInstance->mMethodInstanceGroup->mOwner;
  10337. if ((curTypeInstance == NULL) || (!curTypeInstance->IsGenericTypeInstance()))
  10338. {
  10339. str += StrFormat("@T%d", genericParam->mGenericParamIdx);
  10340. return;
  10341. }
  10342. }
  10343. auto genericParamInstance = GetGenericParamInstance(genericParam);
  10344. auto genericParamDef = genericParamInstance->GetGenericParamDef();
  10345. if (genericParamDef != NULL)
  10346. str += genericParamInstance->GetGenericParamDef()->mName;
  10347. else
  10348. str += "external generic " + TypeToString(genericParamInstance->mExternType, typeNameFlags, genericMethodNameOverrides);
  10349. return;
  10350. }
  10351. else if (resolvedType->IsRef())
  10352. {
  10353. auto refType = (BfRefType*)resolvedType;
  10354. if (refType->mRefKind == BfRefType::RefKind_Ref)
  10355. {
  10356. str += "ref ";
  10357. DoTypeToString(str, refType->mElementType, typeNameFlags, genericMethodNameOverrides);
  10358. return;
  10359. }
  10360. else if (refType->mRefKind == BfRefType::RefKind_Out)
  10361. {
  10362. str += "out ";
  10363. DoTypeToString(str, refType->mElementType, typeNameFlags, genericMethodNameOverrides);
  10364. return;
  10365. }
  10366. else
  10367. {
  10368. str += "mut ";
  10369. DoTypeToString(str, refType->mElementType, typeNameFlags, genericMethodNameOverrides);
  10370. return;
  10371. }
  10372. }
  10373. else if (resolvedType->IsModifiedTypeType())
  10374. {
  10375. auto retTypeType = (BfModifiedTypeType*)resolvedType;
  10376. str += BfTokenToString(retTypeType->mModifiedKind);
  10377. str += "(";
  10378. DoTypeToString(str, retTypeType->mElementType, typeNameFlags, genericMethodNameOverrides);
  10379. str += ")";
  10380. return;
  10381. }
  10382. else if (resolvedType->IsConcreteInterfaceType())
  10383. {
  10384. auto concreteTypeType = (BfConcreteInterfaceType*)resolvedType;
  10385. str += "concrete ";
  10386. DoTypeToString(str, concreteTypeType->mInterface, typeNameFlags, genericMethodNameOverrides);
  10387. return;
  10388. }
  10389. else if (resolvedType->IsUnknownSizedArray())
  10390. {
  10391. auto arrayType = (BfUnknownSizedArrayType*)resolvedType;
  10392. DoTypeToString(str, arrayType->mElementType, typeNameFlags, genericMethodNameOverrides);
  10393. str += "[";
  10394. DoTypeToString(str, arrayType->mElementCountSource, typeNameFlags, genericMethodNameOverrides);
  10395. str += "]";
  10396. return;
  10397. }
  10398. else if (resolvedType->IsSizedArray())
  10399. {
  10400. auto arrayType = (BfSizedArrayType*)resolvedType;
  10401. if (arrayType->mElementCount == -1)
  10402. {
  10403. DoTypeToString(str, arrayType->mElementType, typeNameFlags, genericMethodNameOverrides);
  10404. str += "[?]";
  10405. return;
  10406. }
  10407. DoTypeToString(str, arrayType->mElementType, typeNameFlags, genericMethodNameOverrides);
  10408. str += StrFormat("[%d]", arrayType->mElementCount);
  10409. return;
  10410. }
  10411. else if (resolvedType->IsConstExprValue())
  10412. {
  10413. auto constExprValueType = (BfConstExprValueType*)resolvedType;
  10414. str += "const ";
  10415. DoTypeToString(str, constExprValueType->mType, typeNameFlags, genericMethodNameOverrides);
  10416. str += " ";
  10417. VariantToString(str, constExprValueType->mValue);
  10418. return;
  10419. }
  10420. BFMODULE_FATAL(this, "Not implemented");
  10421. str += "???";
  10422. return;
  10423. }