checker.cpp 191 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542
  1. #define DEBUG_CHECK_ALL_PROCEDURES 1
  2. #include "entity.cpp"
  3. #include "types.cpp"
  4. gb_internal void check_expr(CheckerContext *c, Operand *operand, Ast *expression);
  5. gb_internal void check_expr_or_type(CheckerContext *c, Operand *operand, Ast *expression, Type *type_hint=nullptr);
  6. gb_internal void add_comparison_procedures_for_fields(CheckerContext *c, Type *t);
  7. gb_internal Type *check_type(CheckerContext *ctx, Ast *e);
  8. gb_internal bool is_operand_value(Operand o) {
  9. switch (o.mode) {
  10. case Addressing_Value:
  11. case Addressing_Context:
  12. case Addressing_Variable:
  13. case Addressing_Constant:
  14. case Addressing_MapIndex:
  15. case Addressing_OptionalOk:
  16. case Addressing_OptionalOkPtr:
  17. case Addressing_SoaVariable:
  18. case Addressing_SwizzleValue:
  19. case Addressing_SwizzleVariable:
  20. return true;
  21. }
  22. return false;
  23. }
  24. gb_internal bool is_operand_nil(Operand o) {
  25. return o.mode == Addressing_Value && o.type == t_untyped_nil;
  26. }
  27. gb_internal bool is_operand_uninit(Operand o) {
  28. return o.mode == Addressing_Value && o.type == t_untyped_uninit;
  29. }
  30. gb_internal bool check_rtti_type_disallowed(Token const &token, Type *type, char const *format) {
  31. if (build_context.no_rtti && type) {
  32. if (is_type_any(type)) {
  33. gbString t = type_to_string(type);
  34. error(token, format, t);
  35. gb_string_free(t);
  36. return true;
  37. }
  38. }
  39. return false;
  40. }
  41. gb_internal bool check_rtti_type_disallowed(Ast *expr, Type *type, char const *format) {
  42. GB_ASSERT(expr != nullptr);
  43. return check_rtti_type_disallowed(ast_token(expr), type, format);
  44. }
  45. gb_internal void scope_reset(Scope *scope) {
  46. if (scope == nullptr) return;
  47. rw_mutex_lock(&scope->mutex);
  48. scope->head_child.store(nullptr, std::memory_order_relaxed);
  49. string_map_clear(&scope->elements);
  50. ptr_set_clear(&scope->imported);
  51. rw_mutex_unlock(&scope->mutex);
  52. }
  53. gb_internal void scope_reserve(Scope *scope, isize count) {
  54. string_map_reserve(&scope->elements, 2*count);
  55. }
  56. gb_internal void entity_graph_node_set_destroy(EntityGraphNodeSet *s) {
  57. ptr_set_destroy(s);
  58. }
  59. gb_internal void entity_graph_node_set_add(EntityGraphNodeSet *s, EntityGraphNode *n) {
  60. ptr_set_add(s, n);
  61. }
  62. // gb_internal bool entity_graph_node_set_exists(EntityGraphNodeSet *s, EntityGraphNode *n) {
  63. // return ptr_set_exists(s, n);
  64. // }
  65. gb_internal void entity_graph_node_set_remove(EntityGraphNodeSet *s, EntityGraphNode *n) {
  66. ptr_set_remove(s, n);
  67. }
  68. gb_internal void entity_graph_node_destroy(EntityGraphNode *n, gbAllocator a) {
  69. entity_graph_node_set_destroy(&n->pred);
  70. entity_graph_node_set_destroy(&n->succ);
  71. gb_free(a, n);
  72. }
  73. gb_internal int entity_graph_node_cmp(EntityGraphNode **data, isize i, isize j) {
  74. EntityGraphNode *x = data[i];
  75. EntityGraphNode *y = data[j];
  76. u64 a = x->entity->order_in_src;
  77. u64 b = y->entity->order_in_src;
  78. if (x->dep_count < y->dep_count) {
  79. return -1;
  80. }
  81. if (x->dep_count == y->dep_count) {
  82. return a < b ? -1 : b > a;
  83. }
  84. return +1;
  85. }
  86. gb_internal void entity_graph_node_swap(EntityGraphNode **data, isize i, isize j) {
  87. EntityGraphNode *x = data[i];
  88. EntityGraphNode *y = data[j];
  89. data[i] = y;
  90. data[j] = x;
  91. x->index = j;
  92. y->index = i;
  93. }
  94. gb_internal void import_graph_node_set_destroy(ImportGraphNodeSet *s) {
  95. ptr_set_destroy(s);
  96. }
  97. gb_internal void import_graph_node_set_add(ImportGraphNodeSet *s, ImportGraphNode *n) {
  98. ptr_set_add(s, n);
  99. }
  100. // gb_internal bool import_graph_node_set_exists(ImportGraphNodeSet *s, ImportGraphNode *n) {
  101. // return ptr_set_exists(s, n);
  102. // }
  103. // gb_internal void import_graph_node_set_remove(ImportGraphNodeSet *s, ImportGraphNode *n) {
  104. // ptr_set_remove(s, n);
  105. // }
  106. gb_internal ImportGraphNode *import_graph_node_create(gbAllocator a, AstPackage *pkg) {
  107. ImportGraphNode *n = gb_alloc_item(a, ImportGraphNode);
  108. n->pkg = pkg;
  109. n->scope = pkg->scope;
  110. return n;
  111. }
  112. gb_internal void import_graph_node_destroy(ImportGraphNode *n, gbAllocator a) {
  113. import_graph_node_set_destroy(&n->pred);
  114. import_graph_node_set_destroy(&n->succ);
  115. gb_free(a, n);
  116. }
  117. gb_internal int import_graph_node_cmp(ImportGraphNode **data, isize i, isize j) {
  118. ImportGraphNode *x = data[i];
  119. ImportGraphNode *y = data[j];
  120. GB_ASSERT(x != y);
  121. GB_ASSERT(x->scope != y->scope);
  122. bool xg = (x->scope->flags&ScopeFlag_Global) != 0;
  123. bool yg = (y->scope->flags&ScopeFlag_Global) != 0;
  124. if (xg != yg) return xg ? -1 : +1;
  125. if (xg && yg) return x->pkg->id < y->pkg->id ? +1 : -1;
  126. if (x->dep_count < y->dep_count) return -1;
  127. if (x->dep_count > y->dep_count) return +1;
  128. return 0;
  129. }
  130. gb_internal void import_graph_node_swap(ImportGraphNode **data, isize i, isize j) {
  131. ImportGraphNode *x = data[i];
  132. ImportGraphNode *y = data[j];
  133. data[i] = y;
  134. data[j] = x;
  135. x->index = j;
  136. y->index = i;
  137. }
  138. gb_internal void init_decl_info(DeclInfo *d, Scope *scope, DeclInfo *parent) {
  139. gb_zero_item(d);
  140. if (parent) {
  141. mutex_lock(&parent->next_mutex);
  142. d->next_sibling = parent->next_child;
  143. parent->next_child = d;
  144. mutex_unlock(&parent->next_mutex);
  145. }
  146. d->parent = parent;
  147. d->scope = scope;
  148. ptr_set_init(&d->deps, 0);
  149. ptr_set_init(&d->type_info_deps, 0);
  150. d->labels.allocator = heap_allocator();
  151. }
  152. gb_internal DeclInfo *make_decl_info(Scope *scope, DeclInfo *parent) {
  153. DeclInfo *d = gb_alloc_item(permanent_allocator(), DeclInfo);
  154. init_decl_info(d, scope, parent);
  155. return d;
  156. }
  157. // gb_internal void destroy_declaration_info(DeclInfo *d) {
  158. // mutex_destroy(&d->proc_checked_mutex);
  159. // ptr_set_destroy(&d->deps);
  160. // array_free(&d->labels);
  161. // }
  162. // gb_internal bool decl_info_has_init(DeclInfo *d) {
  163. // if (d->init_expr != nullptr) {
  164. // return true;
  165. // }
  166. // if (d->proc_lit != nullptr) {
  167. // switch (d->proc_lit->kind) {
  168. // case_ast_node(pl, ProcLit, d->proc_lit);
  169. // if (pl->body != nullptr) {
  170. // return true;
  171. // }
  172. // case_end;
  173. // }
  174. // }
  175. // return false;
  176. // }
  177. gb_internal Scope *create_scope(CheckerInfo *info, Scope *parent) {
  178. Scope *s = gb_alloc_item(permanent_allocator(), Scope);
  179. s->parent = parent;
  180. if (parent != nullptr && parent != builtin_pkg->scope) {
  181. Scope *prev_head_child = parent->head_child.exchange(s, std::memory_order_acq_rel);
  182. if (prev_head_child) {
  183. s->next.store(prev_head_child, std::memory_order_release);
  184. }
  185. }
  186. if (parent != nullptr && parent->flags & ScopeFlag_ContextDefined) {
  187. s->flags |= ScopeFlag_ContextDefined;
  188. }
  189. return s;
  190. }
  191. gb_internal Scope *create_scope_from_file(CheckerInfo *info, AstFile *f) {
  192. GB_ASSERT(f != nullptr);
  193. GB_ASSERT(f->pkg != nullptr);
  194. GB_ASSERT(f->pkg->scope != nullptr);
  195. isize init_elements_capacity = gb_max(DEFAULT_SCOPE_CAPACITY, 2*f->total_file_decl_count);
  196. Scope *s = create_scope(info, f->pkg->scope);
  197. string_map_init(&s->elements, init_elements_capacity);
  198. s->flags |= ScopeFlag_File;
  199. s->file = f;
  200. f->scope = s;
  201. return s;
  202. }
  203. gb_internal Scope *create_scope_from_package(CheckerContext *c, AstPackage *pkg) {
  204. GB_ASSERT(pkg != nullptr);
  205. isize total_pkg_decl_count = 0;
  206. for (AstFile *file : pkg->files) {
  207. total_pkg_decl_count += file->total_file_decl_count;
  208. }
  209. isize init_elements_capacity = gb_max(DEFAULT_SCOPE_CAPACITY, 2*total_pkg_decl_count);
  210. Scope *s = create_scope(c->info, builtin_pkg->scope);
  211. string_map_init(&s->elements, init_elements_capacity);
  212. s->flags |= ScopeFlag_Pkg;
  213. s->pkg = pkg;
  214. pkg->scope = s;
  215. if (pkg->fullpath == c->checker->parser->init_fullpath || pkg->kind == Package_Init) {
  216. s->flags |= ScopeFlag_Init;
  217. }
  218. if (pkg->kind == Package_Runtime) {
  219. s->flags |= ScopeFlag_Global;
  220. }
  221. if (s->flags & (ScopeFlag_Init|ScopeFlag_Global)) {
  222. s->flags |= ScopeFlag_HasBeenImported;
  223. }
  224. s->flags |= ScopeFlag_ContextDefined;
  225. return s;
  226. }
  227. gb_internal void destroy_scope(Scope *scope) {
  228. for (Scope *child = scope->head_child; child != nullptr; child = child->next) {
  229. destroy_scope(child);
  230. }
  231. string_map_destroy(&scope->elements);
  232. ptr_set_destroy(&scope->imported);
  233. // NOTE(bill): No need to free scope as it "should" be allocated in an arena (except for the global scope)
  234. }
  235. gb_internal void add_scope(CheckerContext *c, Ast *node, Scope *scope) {
  236. GB_ASSERT(node != nullptr);
  237. GB_ASSERT(scope != nullptr);
  238. scope->node = node;
  239. switch (node->kind) {
  240. case Ast_BlockStmt: node->BlockStmt.scope = scope; break;
  241. case Ast_IfStmt: node->IfStmt.scope = scope; break;
  242. case Ast_ForStmt: node->ForStmt.scope = scope; break;
  243. case Ast_RangeStmt: node->RangeStmt.scope = scope; break;
  244. case Ast_UnrollRangeStmt: node->UnrollRangeStmt.scope = scope; break;
  245. case Ast_CaseClause: node->CaseClause.scope = scope; break;
  246. case Ast_SwitchStmt: node->SwitchStmt.scope = scope; break;
  247. case Ast_TypeSwitchStmt: node->TypeSwitchStmt.scope = scope; break;
  248. case Ast_ProcType: node->ProcType.scope = scope; break;
  249. case Ast_StructType: node->StructType.scope = scope; break;
  250. case Ast_UnionType: node->UnionType.scope = scope; break;
  251. case Ast_EnumType: node->EnumType.scope = scope; break;
  252. case Ast_BitFieldType: node->BitFieldType.scope = scope; break;
  253. default: GB_PANIC("Invalid node for add_scope: %.*s", LIT(ast_strings[node->kind]));
  254. }
  255. }
  256. gb_internal Scope *scope_of_node(Ast *node) {
  257. if (node == nullptr) {
  258. return nullptr;
  259. }
  260. switch (node->kind) {
  261. case Ast_BlockStmt: return node->BlockStmt.scope;
  262. case Ast_IfStmt: return node->IfStmt.scope;
  263. case Ast_ForStmt: return node->ForStmt.scope;
  264. case Ast_RangeStmt: return node->RangeStmt.scope;
  265. case Ast_UnrollRangeStmt: return node->UnrollRangeStmt.scope;
  266. case Ast_CaseClause: return node->CaseClause.scope;
  267. case Ast_SwitchStmt: return node->SwitchStmt.scope;
  268. case Ast_TypeSwitchStmt: return node->TypeSwitchStmt.scope;
  269. case Ast_ProcType: return node->ProcType.scope;
  270. case Ast_StructType: return node->StructType.scope;
  271. case Ast_UnionType: return node->UnionType.scope;
  272. case Ast_EnumType: return node->EnumType.scope;
  273. case Ast_BitFieldType: return node->BitFieldType.scope;
  274. }
  275. GB_PANIC("Invalid node for add_scope: %.*s", LIT(ast_strings[node->kind]));
  276. return nullptr;
  277. }
  278. gb_internal void check_open_scope(CheckerContext *c, Ast *node) {
  279. node = unparen_expr(node);
  280. GB_ASSERT(node->kind == Ast_Invalid ||
  281. is_ast_stmt(node) ||
  282. is_ast_type(node));
  283. Scope *scope = create_scope(c->info, c->scope);
  284. add_scope(c, node, scope);
  285. switch (node->kind) {
  286. case Ast_ProcType:
  287. scope->flags |= ScopeFlag_Proc;
  288. break;
  289. case Ast_StructType:
  290. case Ast_EnumType:
  291. case Ast_UnionType:
  292. case Ast_BitSetType:
  293. case Ast_BitFieldType:
  294. scope->flags |= ScopeFlag_Type;
  295. break;
  296. }
  297. c->scope = scope;
  298. c->state_flags |= StateFlag_bounds_check;
  299. }
  300. gb_internal void check_close_scope(CheckerContext *c) {
  301. c->scope = c->scope->parent;
  302. }
  303. gb_internal Entity *scope_lookup_current(Scope *s, String const &name) {
  304. Entity **found = string_map_get(&s->elements, name);
  305. if (found) {
  306. return *found;
  307. }
  308. return nullptr;
  309. }
  310. gb_internal void scope_lookup_parent(Scope *scope, String const &name, Scope **scope_, Entity **entity_) {
  311. if (scope != nullptr) {
  312. bool gone_thru_proc = false;
  313. bool gone_thru_package = false;
  314. StringHashKey key = string_hash_string(name);
  315. for (Scope *s = scope; s != nullptr; s = s->parent) {
  316. Entity **found = nullptr;
  317. rw_mutex_shared_lock(&s->mutex);
  318. found = string_map_get(&s->elements, key);
  319. rw_mutex_shared_unlock(&s->mutex);
  320. if (found) {
  321. Entity *e = *found;
  322. if (gone_thru_proc) {
  323. if (e->kind == Entity_Label) {
  324. continue;
  325. }
  326. if (e->kind == Entity_Variable) {
  327. if (e->scope->flags&ScopeFlag_File) {
  328. // Global variables are file to access
  329. } else if (e->flags&EntityFlag_Static) {
  330. // Allow static/thread_local variables to be referenced
  331. } else {
  332. continue;
  333. }
  334. }
  335. }
  336. if (entity_) *entity_ = e;
  337. if (scope_) *scope_ = s;
  338. return;
  339. }
  340. if (s->flags&ScopeFlag_Proc) {
  341. gone_thru_proc = true;
  342. }
  343. if (s->flags&ScopeFlag_Pkg) {
  344. gone_thru_package = true;
  345. }
  346. }
  347. }
  348. if (entity_) *entity_ = nullptr;
  349. if (scope_) *scope_ = nullptr;
  350. }
  351. gb_internal Entity *scope_lookup(Scope *s, String const &name) {
  352. Entity *entity = nullptr;
  353. scope_lookup_parent(s, name, nullptr, &entity);
  354. return entity;
  355. }
  356. gb_internal Entity *scope_insert_with_name_no_mutex(Scope *s, String const &name, Entity *entity) {
  357. if (name == "") {
  358. return nullptr;
  359. }
  360. StringHashKey key = string_hash_string(name);
  361. Entity **found = nullptr;
  362. Entity *result = nullptr;
  363. found = string_map_get(&s->elements, key);
  364. if (found) {
  365. if (entity != *found) {
  366. result = *found;
  367. }
  368. goto end;
  369. }
  370. if (s->parent != nullptr && (s->parent->flags & ScopeFlag_Proc) != 0) {
  371. found = string_map_get(&s->parent->elements, key);
  372. if (found) {
  373. if ((*found)->flags & EntityFlag_Result) {
  374. if (entity != *found) {
  375. result = *found;
  376. }
  377. goto end;
  378. }
  379. }
  380. }
  381. string_map_set(&s->elements, key, entity);
  382. if (entity->scope == nullptr) {
  383. entity->scope = s;
  384. }
  385. end:;
  386. return result;
  387. }
  388. gb_internal Entity *scope_insert_with_name(Scope *s, String const &name, Entity *entity) {
  389. if (name == "") {
  390. return nullptr;
  391. }
  392. StringHashKey key = string_hash_string(name);
  393. Entity **found = nullptr;
  394. Entity *result = nullptr;
  395. rw_mutex_lock(&s->mutex);
  396. found = string_map_get(&s->elements, key);
  397. if (found) {
  398. if (entity != *found) {
  399. result = *found;
  400. }
  401. goto end;
  402. }
  403. if (s->parent != nullptr && (s->parent->flags & ScopeFlag_Proc) != 0) {
  404. found = string_map_get(&s->parent->elements, key);
  405. if (found) {
  406. if ((*found)->flags & EntityFlag_Result) {
  407. if (entity != *found) {
  408. result = *found;
  409. }
  410. goto end;
  411. }
  412. }
  413. }
  414. string_map_set(&s->elements, key, entity);
  415. if (entity->scope == nullptr) {
  416. entity->scope = s;
  417. }
  418. end:;
  419. rw_mutex_unlock(&s->mutex);
  420. return result;
  421. }
  422. gb_internal Entity *scope_insert(Scope *s, Entity *entity) {
  423. String name = entity->token.string;
  424. return scope_insert_with_name(s, name, entity);
  425. }
  426. gb_internal Entity *scope_insert_no_mutex(Scope *s, Entity *entity) {
  427. String name = entity->token.string;
  428. return scope_insert_with_name_no_mutex(s, name, entity);
  429. }
  430. GB_COMPARE_PROC(entity_variable_pos_cmp) {
  431. Entity *x = *cast(Entity **)a;
  432. Entity *y = *cast(Entity **)b;
  433. return token_pos_cmp(x->token.pos, y->token.pos);
  434. }
  435. gb_internal u64 check_vet_flags(CheckerContext *c) {
  436. AstFile *file = c->file;
  437. if (file == nullptr &&
  438. c->curr_proc_decl &&
  439. c->curr_proc_decl->proc_lit) {
  440. file = c->curr_proc_decl->proc_lit->file();
  441. }
  442. if (file && file->vet_flags_set) {
  443. return file->vet_flags;
  444. }
  445. return build_context.vet_flags;
  446. }
  447. gb_internal u64 check_vet_flags(Ast *node) {
  448. AstFile *file = node->file();
  449. if (file && file->vet_flags_set) {
  450. return file->vet_flags;
  451. }
  452. return build_context.vet_flags;
  453. }
  454. enum VettedEntityKind {
  455. VettedEntity_Invalid,
  456. VettedEntity_Unused,
  457. VettedEntity_Shadowed,
  458. VettedEntity_Shadowed_And_Unused,
  459. };
  460. struct VettedEntity {
  461. VettedEntityKind kind;
  462. Entity *entity;
  463. Entity *other;
  464. };
  465. gb_internal GB_COMPARE_PROC(vetted_entity_variable_pos_cmp) {
  466. Entity *x = (cast(VettedEntity *)a)->entity;
  467. Entity *y = (cast(VettedEntity *)b)->entity;
  468. GB_ASSERT(x != nullptr);
  469. GB_ASSERT(y != nullptr);
  470. return token_pos_cmp(x->token.pos, y->token.pos);
  471. }
  472. gb_internal bool check_vet_shadowing_assignment(Checker *c, Entity *shadowed, Ast *expr) {
  473. Ast *init = unparen_expr(expr);
  474. if (init == nullptr) {
  475. return false;
  476. }
  477. if (init->kind == Ast_Ident) {
  478. // TODO(bill): Which logic is better? Same name or same entity
  479. // bool ignore = init->Ident.token.string == name;
  480. bool ignore = init->Ident.entity == shadowed;
  481. if (ignore) {
  482. return true;
  483. }
  484. } else if (init->kind == Ast_TernaryIfExpr) {
  485. bool x = check_vet_shadowing_assignment(c, shadowed, init->TernaryIfExpr.x);
  486. bool y = check_vet_shadowing_assignment(c, shadowed, init->TernaryIfExpr.y);
  487. if (x || y) {
  488. return true;
  489. }
  490. }
  491. return false;
  492. }
  493. gb_internal bool check_vet_shadowing(Checker *c, Entity *e, VettedEntity *ve) {
  494. if (e->kind != Entity_Variable) {
  495. return false;
  496. }
  497. String name = e->token.string;
  498. if (name == "_") {
  499. return false;
  500. }
  501. if (e->flags & EntityFlag_Param) {
  502. return false;
  503. }
  504. if (e->scope->flags & (ScopeFlag_Global|ScopeFlag_File|ScopeFlag_Proc)) {
  505. return false;
  506. }
  507. Scope *parent = e->scope->parent;
  508. if (parent->flags & (ScopeFlag_Global|ScopeFlag_File)) {
  509. return false;
  510. }
  511. Entity *shadowed = scope_lookup(parent, name);
  512. if (shadowed == nullptr) {
  513. return false;
  514. }
  515. if (shadowed->kind != Entity_Variable) {
  516. return false;
  517. }
  518. if (shadowed->scope->flags & (ScopeFlag_Global|ScopeFlag_File)) {
  519. // return false;
  520. }
  521. // NOTE(bill): The entities must be in the same file
  522. if (e->token.pos.file_id != shadowed->token.pos.file_id) {
  523. return false;
  524. }
  525. // NOTE(bill): The shaded identifier must appear before this one to be an
  526. // instance of shadowing
  527. if (token_pos_cmp(shadowed->token.pos, e->token.pos) > 0) {
  528. return false;
  529. }
  530. // NOTE(bill): If the types differ, don't complain
  531. if (!are_types_identical(e->type, shadowed->type)) {
  532. return false;
  533. }
  534. // NOTE(bill): Ignore intentional redeclaration
  535. // x := x
  536. // Suggested in issue #637 (2020-05-11)
  537. // Also allow the following
  538. // x := x if cond else y
  539. // x := z if cond else x
  540. if ((e->flags & EntityFlag_Using) == 0 && e->kind == Entity_Variable) {
  541. if (check_vet_shadowing_assignment(c, shadowed, e->Variable.init_expr)) {
  542. return false;
  543. }
  544. }
  545. zero_item(ve);
  546. ve->kind = VettedEntity_Shadowed;
  547. ve->entity = e;
  548. ve->other = shadowed;
  549. return true;
  550. }
  551. gb_internal bool check_vet_unused(Checker *c, Entity *e, VettedEntity *ve) {
  552. if ((e->flags&EntityFlag_Used) == 0) {
  553. switch (e->kind) {
  554. case Entity_Variable:
  555. if (e->scope->flags & (ScopeFlag_Global|ScopeFlag_Type|ScopeFlag_File)) {
  556. return false;
  557. } else if (e->flags & EntityFlag_Static) {
  558. // ignore these for the time being
  559. return false;
  560. }
  561. case Entity_ImportName:
  562. case Entity_LibraryName:
  563. zero_item(ve);
  564. ve->kind = VettedEntity_Unused;
  565. ve->entity = e;
  566. return true;
  567. }
  568. }
  569. return false;
  570. }
  571. gb_internal void check_scope_usage(Checker *c, Scope *scope, u64 vet_flags) {
  572. bool vet_unused = (vet_flags & VetFlag_Unused) != 0;
  573. bool vet_shadowing = (vet_flags & (VetFlag_Shadowing|VetFlag_Using)) != 0;
  574. Array<VettedEntity> vetted_entities = {};
  575. array_init(&vetted_entities, heap_allocator());
  576. rw_mutex_shared_lock(&scope->mutex);
  577. for (auto const &entry : scope->elements) {
  578. Entity *e = entry.value;
  579. if (e == nullptr) continue;
  580. VettedEntity ve_unused = {};
  581. VettedEntity ve_shadowed = {};
  582. bool is_unused = vet_unused && check_vet_unused(c, e, &ve_unused);
  583. bool is_shadowed = vet_shadowing && check_vet_shadowing(c, e, &ve_shadowed);
  584. if (is_unused && is_shadowed) {
  585. VettedEntity ve_both = ve_shadowed;
  586. ve_both.kind = VettedEntity_Shadowed_And_Unused;
  587. array_add(&vetted_entities, ve_both);
  588. } else if (is_unused) {
  589. array_add(&vetted_entities, ve_unused);
  590. } else if (is_shadowed) {
  591. array_add(&vetted_entities, ve_shadowed);
  592. } else if (e->kind == Entity_Variable && (e->flags & (EntityFlag_Param|EntityFlag_Using|EntityFlag_Static)) == 0 && !e->Variable.is_global) {
  593. i64 sz = type_size_of(e->type);
  594. // TODO(bill): When is a good size warn?
  595. // Is >256 KiB good enough?
  596. if (sz > 1ll<<18) {
  597. gbString type_str = type_to_string(e->type);
  598. warning(e->token, "Declaration of '%.*s' may cause a stack overflow due to its type '%s' having a size of %lld bytes", LIT(e->token.string), type_str, cast(long long)sz);
  599. gb_string_free(type_str);
  600. }
  601. }
  602. }
  603. rw_mutex_shared_unlock(&scope->mutex);
  604. gb_sort(vetted_entities.data, vetted_entities.count, gb_size_of(VettedEntity), vetted_entity_variable_pos_cmp);
  605. for (auto const &ve : vetted_entities) {
  606. Entity *e = ve.entity;
  607. Entity *other = ve.other;
  608. String name = e->token.string;
  609. if (ve.kind == VettedEntity_Shadowed_And_Unused) {
  610. error(e->token, "'%.*s' declared but not used, possibly shadows declaration at line %d", LIT(name), other->token.pos.line);
  611. } else if (vet_flags) {
  612. switch (ve.kind) {
  613. case VettedEntity_Unused:
  614. if (e->kind == Entity_Variable && (vet_flags & VetFlag_UnusedVariables) != 0) {
  615. error(e->token, "'%.*s' declared but not used", LIT(name));
  616. }
  617. if ((e->kind == Entity_ImportName || e->kind == Entity_LibraryName) && (vet_flags & VetFlag_UnusedImports) != 0) {
  618. error(e->token, "'%.*s' declared but not used", LIT(name));
  619. }
  620. break;
  621. case VettedEntity_Shadowed:
  622. if ((vet_flags & (VetFlag_Shadowing|VetFlag_Using)) != 0 && e->flags&EntityFlag_Using) {
  623. error(e->token, "Declaration of '%.*s' from 'using' shadows declaration at line %d", LIT(name), other->token.pos.line);
  624. } else if ((vet_flags & (VetFlag_Shadowing)) != 0) {
  625. error(e->token, "Declaration of '%.*s' shadows declaration at line %d", LIT(name), other->token.pos.line);
  626. }
  627. break;
  628. default:
  629. break;
  630. }
  631. }
  632. }
  633. array_free(&vetted_entities);
  634. for (Scope *child = scope->head_child; child != nullptr; child = child->next) {
  635. if (child->flags & (ScopeFlag_Proc|ScopeFlag_Type|ScopeFlag_File)) {
  636. // Ignore these
  637. } else {
  638. check_scope_usage(c, child, vet_flags);
  639. }
  640. }
  641. }
  642. gb_internal void add_dependency(CheckerInfo *info, DeclInfo *d, Entity *e) {
  643. rw_mutex_lock(&d->deps_mutex);
  644. ptr_set_add(&d->deps, e);
  645. rw_mutex_unlock(&d->deps_mutex);
  646. }
  647. gb_internal void add_type_info_dependency(CheckerInfo *info, DeclInfo *d, Type *type) {
  648. if (d == nullptr) {
  649. return;
  650. }
  651. rw_mutex_lock(&d->type_info_deps_mutex);
  652. ptr_set_add(&d->type_info_deps, type);
  653. rw_mutex_unlock(&d->type_info_deps_mutex);
  654. }
  655. gb_internal AstPackage *get_runtime_package(CheckerInfo *info) {
  656. String name = str_lit("runtime");
  657. gbAllocator a = heap_allocator();
  658. String path = get_fullpath_base_collection(a, name, nullptr);
  659. defer (gb_free(a, path.text));
  660. auto found = string_map_get(&info->packages, path);
  661. if (found == nullptr) {
  662. gb_printf_err("Name: %.*s\n", LIT(name));
  663. gb_printf_err("Fullpath: %.*s\n", LIT(path));
  664. for (auto const &entry : info->packages) {
  665. gb_printf_err("%.*s\n", LIT(entry.key));
  666. }
  667. GB_ASSERT_MSG(found != nullptr, "Missing core package %.*s", LIT(name));
  668. }
  669. return *found;
  670. }
  671. gb_internal AstPackage *get_core_package(CheckerInfo *info, String name) {
  672. if (name == "runtime") {
  673. return get_runtime_package(info);
  674. }
  675. gbAllocator a = heap_allocator();
  676. String path = get_fullpath_core_collection(a, name, nullptr);
  677. defer (gb_free(a, path.text));
  678. auto found = string_map_get(&info->packages, path);
  679. if (found == nullptr) {
  680. gb_printf_err("Name: %.*s\n", LIT(name));
  681. gb_printf_err("Fullpath: %.*s\n", LIT(path));
  682. for (auto const &entry : info->packages) {
  683. gb_printf_err("%.*s\n", LIT(entry.key));
  684. }
  685. GB_ASSERT_MSG(found != nullptr, "Missing core package %.*s", LIT(name));
  686. }
  687. return *found;
  688. }
  689. gb_internal void add_package_dependency(CheckerContext *c, char const *package_name, char const *name, bool required=false) {
  690. String n = make_string_c(name);
  691. AstPackage *p = get_core_package(&c->checker->info, make_string_c(package_name));
  692. Entity *e = scope_lookup(p->scope, n);
  693. GB_ASSERT_MSG(e != nullptr, "%s", name);
  694. GB_ASSERT(c->decl != nullptr);
  695. e->flags |= EntityFlag_Used;
  696. if (required) {
  697. e->flags |= EntityFlag_Require;
  698. }
  699. add_dependency(c->info, c->decl, e);
  700. }
  701. gb_internal void try_to_add_package_dependency(CheckerContext *c, char const *package_name, char const *name) {
  702. String n = make_string_c(name);
  703. AstPackage *p = get_core_package(&c->checker->info, make_string_c(package_name));
  704. Entity *e = scope_lookup(p->scope, n);
  705. if (e == nullptr) {
  706. return;
  707. }
  708. GB_ASSERT(c->decl != nullptr);
  709. e->flags |= EntityFlag_Used;
  710. add_dependency(c->info, c->decl, e);
  711. }
  712. gb_internal void add_declaration_dependency(CheckerContext *c, Entity *e) {
  713. if (e == nullptr) {
  714. return;
  715. }
  716. if (c->decl != nullptr) {
  717. add_dependency(c->info, c->decl, e);
  718. }
  719. }
  720. gb_internal Entity *add_global_entity(Entity *entity, Scope *scope=builtin_pkg->scope) {
  721. String name = entity->token.string;
  722. defer (entity->state = EntityState_Resolved);
  723. if (gb_memchr(name.text, ' ', name.len)) {
  724. return entity; // NOTE(bill): Usually an 'untyped thing'
  725. }
  726. if (scope_insert(scope, entity)) {
  727. compiler_error("double declaration");
  728. }
  729. return entity;
  730. }
  731. gb_internal void add_global_constant(char const *name, Type *type, ExactValue value) {
  732. Entity *entity = alloc_entity(Entity_Constant, nullptr, make_token_ident(name), type);
  733. entity->Constant.value = value;
  734. add_global_entity(entity);
  735. }
  736. gb_internal void add_global_string_constant(char const *name, String const &value) {
  737. add_global_constant(name, t_untyped_string, exact_value_string(value));
  738. }
  739. gb_internal void add_global_bool_constant(char const *name, bool value) {
  740. add_global_constant(name, t_untyped_bool, exact_value_bool(value));
  741. }
  742. gb_internal void add_global_type_entity(String name, Type *type) {
  743. add_global_entity(alloc_entity_type_name(nullptr, make_token_ident(name), type));
  744. }
  745. gb_internal AstPackage *create_builtin_package(char const *name) {
  746. gbAllocator a = permanent_allocator();
  747. AstPackage *pkg = gb_alloc_item(a, AstPackage);
  748. pkg->name = make_string_c(name);
  749. pkg->kind = Package_Builtin;
  750. pkg->scope = create_scope(nullptr, nullptr);
  751. pkg->scope->flags |= ScopeFlag_Pkg | ScopeFlag_Global | ScopeFlag_Builtin;
  752. pkg->scope->pkg = pkg;
  753. return pkg;
  754. }
  755. struct GlobalEnumValue {
  756. char const *name;
  757. i64 value;
  758. };
  759. gb_internal Slice<Entity *> add_global_enum_type(String const &type_name, GlobalEnumValue *values, isize value_count, Type **enum_type_ = nullptr) {
  760. Scope *scope = create_scope(nullptr, builtin_pkg->scope);
  761. Entity *entity = alloc_entity_type_name(scope, make_token_ident(type_name), nullptr, EntityState_Resolved);
  762. Type *enum_type = alloc_type_enum();
  763. Type *named_type = alloc_type_named(type_name, enum_type, entity);
  764. set_base_type(named_type, enum_type);
  765. enum_type->Enum.base_type = t_int;
  766. enum_type->Enum.scope = scope;
  767. entity->type = named_type;
  768. auto fields = array_make<Entity *>(permanent_allocator(), value_count);
  769. for (isize i = 0; i < value_count; i++) {
  770. i64 value = values[i].value;
  771. Entity *e = alloc_entity_constant(scope, make_token_ident(values[i].name), named_type, exact_value_i64(value));
  772. e->flags |= EntityFlag_Visited;
  773. e->state = EntityState_Resolved;
  774. fields[i] = e;
  775. Entity *ie = scope_insert(scope, e);
  776. GB_ASSERT(ie == nullptr);
  777. }
  778. enum_type->Enum.fields = fields;
  779. enum_type->Enum.min_value_index = 0;
  780. enum_type->Enum.max_value_index = value_count-1;
  781. enum_type->Enum.min_value = &enum_type->Enum.fields[enum_type->Enum.min_value_index]->Constant.value;
  782. enum_type->Enum.max_value = &enum_type->Enum.fields[enum_type->Enum.max_value_index]->Constant.value;
  783. if (enum_type_) *enum_type_ = named_type;
  784. return slice_from_array(fields);
  785. }
  786. gb_internal void add_global_enum_constant(Slice<Entity *> const &fields, char const *name, i64 value) {
  787. for (Entity *field : fields) {
  788. GB_ASSERT(field->kind == Entity_Constant);
  789. if (value == exact_value_to_i64(field->Constant.value)) {
  790. add_global_constant(name, field->type, field->Constant.value);
  791. return;
  792. }
  793. }
  794. GB_PANIC("Unfound enum value for global constant: %s %lld", name, cast(long long)value);
  795. }
  796. gb_internal Type *add_global_type_name(Scope *scope, String const &type_name, Type *backing_type) {
  797. Entity *e = alloc_entity_type_name(scope, make_token_ident(type_name), nullptr, EntityState_Resolved);
  798. Type *named_type = alloc_type_named(type_name, backing_type, e);
  799. e->type = named_type;
  800. set_base_type(named_type, backing_type);
  801. if (scope_insert(scope, e)) {
  802. compiler_error("double declaration of %.*s", LIT(e->token.string));
  803. }
  804. return named_type;
  805. }
  806. gb_internal i64 odin_compile_timestamp(void) {
  807. i64 us_after_1601 = cast(i64)gb_utc_time_now();
  808. i64 us_after_1970 = us_after_1601 - 11644473600000000ll;
  809. i64 ns_after_1970 = us_after_1970*1000ll;
  810. return ns_after_1970;
  811. }
  812. gb_internal bool lb_use_new_pass_system(void);
  813. gb_internal void init_universal(void) {
  814. BuildContext *bc = &build_context;
  815. builtin_pkg = create_builtin_package("builtin");
  816. intrinsics_pkg = create_builtin_package("intrinsics");
  817. config_pkg = create_builtin_package("config");
  818. // Types
  819. for (isize i = 0; i < gb_count_of(basic_types); i++) {
  820. String const &name = basic_types[i].Basic.name;
  821. add_global_type_entity(name, &basic_types[i]);
  822. }
  823. add_global_type_entity(str_lit("byte"), &basic_types[Basic_u8]);
  824. {
  825. Type *equal_args[2] = {t_rawptr, t_rawptr};
  826. t_equal_proc = alloc_type_proc_from_types(equal_args, gb_count_of(equal_args), t_bool, false, ProcCC_Contextless);
  827. Type *hasher_args[2] = {t_rawptr, t_uintptr};
  828. t_hasher_proc = alloc_type_proc_from_types(hasher_args, gb_count_of(hasher_args), t_uintptr, false, ProcCC_Contextless);
  829. Type *map_get_args[3] = {/*map*/t_rawptr, /*hash*/t_uintptr, /*key*/t_rawptr};
  830. t_map_get_proc = alloc_type_proc_from_types(map_get_args, gb_count_of(map_get_args), t_rawptr, false, ProcCC_Contextless);
  831. }
  832. // Constants
  833. add_global_entity(alloc_entity_nil(str_lit("nil"), t_untyped_nil));
  834. add_global_bool_constant("true", true);
  835. add_global_bool_constant("false", false);
  836. add_global_string_constant("ODIN_VENDOR", bc->ODIN_VENDOR);
  837. add_global_string_constant("ODIN_VERSION", bc->ODIN_VERSION);
  838. add_global_string_constant("ODIN_ROOT", bc->ODIN_ROOT);
  839. add_global_string_constant("ODIN_BUILD_PROJECT_NAME", bc->ODIN_BUILD_PROJECT_NAME);
  840. add_global_string_constant("ODIN_WINDOWS_SUBSYSTEM", bc->ODIN_WINDOWS_SUBSYSTEM);
  841. {
  842. GlobalEnumValue values[TargetOs_COUNT] = {
  843. {"Unknown", TargetOs_Invalid},
  844. {"Windows", TargetOs_windows},
  845. {"Darwin", TargetOs_darwin},
  846. {"Linux", TargetOs_linux},
  847. {"Essence", TargetOs_essence},
  848. {"FreeBSD", TargetOs_freebsd},
  849. {"Haiku", TargetOs_haiku},
  850. {"OpenBSD", TargetOs_openbsd},
  851. {"NetBSD", TargetOs_netbsd},
  852. {"WASI", TargetOs_wasi},
  853. {"JS", TargetOs_js},
  854. {"Orca", TargetOs_orca},
  855. {"Freestanding", TargetOs_freestanding},
  856. };
  857. auto fields = add_global_enum_type(str_lit("Odin_OS_Type"), values, gb_count_of(values));
  858. add_global_enum_constant(fields, "ODIN_OS", bc->metrics.os);
  859. add_global_string_constant("ODIN_OS_STRING", target_os_names[bc->metrics.os]);
  860. }
  861. {
  862. GlobalEnumValue values[TargetArch_COUNT] = {
  863. {"Unknown", TargetArch_Invalid},
  864. {"amd64", TargetArch_amd64},
  865. {"i386", TargetArch_i386},
  866. {"arm32", TargetArch_arm32},
  867. {"arm64", TargetArch_arm64},
  868. {"wasm32", TargetArch_wasm32},
  869. {"wasm64p32", TargetArch_wasm64p32},
  870. };
  871. auto fields = add_global_enum_type(str_lit("Odin_Arch_Type"), values, gb_count_of(values));
  872. add_global_enum_constant(fields, "ODIN_ARCH", bc->metrics.arch);
  873. add_global_string_constant("ODIN_ARCH_STRING", target_arch_names[bc->metrics.arch]);
  874. }
  875. {
  876. GlobalEnumValue values[BuildMode_COUNT] = {
  877. {"Executable", BuildMode_Executable},
  878. {"Dynamic", BuildMode_DynamicLibrary},
  879. {"Static", BuildMode_StaticLibrary},
  880. {"Object", BuildMode_Object},
  881. {"Assembly", BuildMode_Assembly},
  882. {"LLVM_IR", BuildMode_LLVM_IR},
  883. };
  884. auto fields = add_global_enum_type(str_lit("Odin_Build_Mode_Type"), values, gb_count_of(values));
  885. add_global_enum_constant(fields, "ODIN_BUILD_MODE", bc->build_mode);
  886. }
  887. {
  888. GlobalEnumValue values[TargetEndian_COUNT] = {
  889. {"Little", TargetEndian_Little},
  890. {"Big", TargetEndian_Big},
  891. };
  892. auto fields = add_global_enum_type(str_lit("Odin_Endian_Type"), values, gb_count_of(values));
  893. add_global_enum_constant(fields, "ODIN_ENDIAN", target_endians[bc->metrics.arch]);
  894. add_global_string_constant("ODIN_ENDIAN_STRING", target_endian_names[target_endians[bc->metrics.arch]]);
  895. }
  896. {
  897. GlobalEnumValue values[Subtarget_COUNT] = {
  898. {"Default", Subtarget_Default},
  899. {"iOS", Subtarget_iOS},
  900. };
  901. auto fields = add_global_enum_type(str_lit("Odin_Platform_Subtarget_Type"), values, gb_count_of(values));
  902. add_global_enum_constant(fields, "ODIN_PLATFORM_SUBTARGET", selected_subtarget);
  903. }
  904. {
  905. GlobalEnumValue values[ErrorPosStyle_COUNT] = {
  906. {"Default", ErrorPosStyle_Default},
  907. {"Unix", ErrorPosStyle_Unix},
  908. };
  909. auto fields = add_global_enum_type(str_lit("Odin_Error_Pos_Style_Type"), values, gb_count_of(values));
  910. add_global_enum_constant(fields, "ODIN_ERROR_POS_STYLE", build_context.ODIN_ERROR_POS_STYLE);
  911. }
  912. {
  913. GlobalEnumValue values[OdinAtomicMemoryOrder_COUNT] = {
  914. {OdinAtomicMemoryOrder_strings[OdinAtomicMemoryOrder_relaxed], OdinAtomicMemoryOrder_relaxed},
  915. {OdinAtomicMemoryOrder_strings[OdinAtomicMemoryOrder_consume], OdinAtomicMemoryOrder_consume},
  916. {OdinAtomicMemoryOrder_strings[OdinAtomicMemoryOrder_acquire], OdinAtomicMemoryOrder_acquire},
  917. {OdinAtomicMemoryOrder_strings[OdinAtomicMemoryOrder_release], OdinAtomicMemoryOrder_release},
  918. {OdinAtomicMemoryOrder_strings[OdinAtomicMemoryOrder_acq_rel], OdinAtomicMemoryOrder_acq_rel},
  919. {OdinAtomicMemoryOrder_strings[OdinAtomicMemoryOrder_seq_cst], OdinAtomicMemoryOrder_seq_cst},
  920. };
  921. add_global_enum_type(str_lit("Atomic_Memory_Order"), values, gb_count_of(values), &t_atomic_memory_order);
  922. GB_ASSERT(t_atomic_memory_order->kind == Type_Named);
  923. scope_insert(intrinsics_pkg->scope, t_atomic_memory_order->Named.type_name);
  924. }
  925. {
  926. int minimum_os_version = 0;
  927. if (build_context.minimum_os_version_string != "") {
  928. int major, minor, revision = 0;
  929. sscanf(cast(const char *)(build_context.minimum_os_version_string.text), "%d.%d.%d", &major, &minor, &revision);
  930. minimum_os_version = (major*10000)+(minor*100)+revision;
  931. }
  932. add_global_constant("ODIN_MINIMUM_OS_VERSION", t_untyped_integer, exact_value_i64(minimum_os_version));
  933. }
  934. add_global_bool_constant("ODIN_DEBUG", bc->ODIN_DEBUG);
  935. add_global_bool_constant("ODIN_DISABLE_ASSERT", bc->ODIN_DISABLE_ASSERT);
  936. add_global_bool_constant("ODIN_DEFAULT_TO_NIL_ALLOCATOR", bc->ODIN_DEFAULT_TO_NIL_ALLOCATOR);
  937. add_global_bool_constant("ODIN_NO_BOUNDS_CHECK", build_context.no_bounds_check);
  938. add_global_bool_constant("ODIN_NO_TYPE_ASSERT", build_context.no_type_assert);
  939. add_global_bool_constant("ODIN_DEFAULT_TO_PANIC_ALLOCATOR", bc->ODIN_DEFAULT_TO_PANIC_ALLOCATOR);
  940. add_global_bool_constant("ODIN_NO_DYNAMIC_LITERALS", bc->no_dynamic_literals);
  941. add_global_bool_constant("ODIN_NO_CRT", bc->no_crt);
  942. add_global_bool_constant("ODIN_USE_SEPARATE_MODULES", bc->use_separate_modules);
  943. add_global_bool_constant("ODIN_TEST", bc->command_kind == Command_test);
  944. add_global_bool_constant("ODIN_NO_ENTRY_POINT", bc->no_entry_point);
  945. add_global_bool_constant("ODIN_FOREIGN_ERROR_PROCEDURES", bc->ODIN_FOREIGN_ERROR_PROCEDURES);
  946. add_global_bool_constant("ODIN_NO_RTTI", bc->no_rtti);
  947. add_global_bool_constant("ODIN_VALGRIND_SUPPORT", bc->ODIN_VALGRIND_SUPPORT);
  948. add_global_bool_constant("ODIN_TILDE", bc->tilde_backend);
  949. add_global_constant("ODIN_COMPILE_TIMESTAMP", t_untyped_integer, exact_value_i64(odin_compile_timestamp()));
  950. {
  951. bool f16_supported = lb_use_new_pass_system();
  952. if (is_arch_wasm()) {
  953. f16_supported = false;
  954. } else if (build_context.metrics.os == TargetOs_darwin && build_context.metrics.arch == TargetArch_amd64) {
  955. // NOTE(laytan): See #3222 for my ramblings on this.
  956. f16_supported = false;
  957. }
  958. add_global_bool_constant("__ODIN_LLVM_F16_SUPPORTED", f16_supported);
  959. }
  960. {
  961. GlobalEnumValue values[3] = {
  962. {"Address", 0},
  963. {"Memory", 1},
  964. {"Thread", 2},
  965. };
  966. Type *enum_type = nullptr;
  967. auto flags = add_global_enum_type(str_lit("Odin_Sanitizer_Flag"), values, gb_count_of(values), &enum_type);
  968. Type *bit_set_type = alloc_type_bit_set();
  969. bit_set_type->BitSet.elem = enum_type;
  970. bit_set_type->BitSet.underlying = t_u32;
  971. bit_set_type->BitSet.lower = 0;
  972. bit_set_type->BitSet.upper = 2;
  973. type_size_of(bit_set_type);
  974. String type_name = str_lit("Odin_Sanitizer_Flags");
  975. Scope *scope = create_scope(nullptr, builtin_pkg->scope);
  976. Entity *entity = alloc_entity_type_name(scope, make_token_ident(type_name), nullptr, EntityState_Resolved);
  977. Type *named_type = alloc_type_named(type_name, bit_set_type, entity);
  978. set_base_type(named_type, bit_set_type);
  979. add_global_constant("ODIN_SANITIZER_FLAGS", named_type, exact_value_u64(bc->sanitizer_flags));
  980. }
  981. // Builtin Procedures
  982. for (isize i = 0; i < gb_count_of(builtin_procs); i++) {
  983. BuiltinProcId id = cast(BuiltinProcId)i;
  984. String name = builtin_procs[i].name;
  985. if (name != "") {
  986. Entity *entity = alloc_entity(Entity_Builtin, nullptr, make_token_ident(name), t_invalid);
  987. entity->Builtin.id = id;
  988. switch (builtin_procs[i].pkg) {
  989. case BuiltinProcPkg_builtin:
  990. add_global_entity(entity, builtin_pkg->scope);
  991. break;
  992. case BuiltinProcPkg_intrinsics:
  993. add_global_entity(entity, intrinsics_pkg->scope);
  994. GB_ASSERT(scope_lookup_current(intrinsics_pkg->scope, name) != nullptr);
  995. break;
  996. }
  997. }
  998. }
  999. {
  1000. BuiltinProcId id = BuiltinProc_expand_values;
  1001. String name = str_lit("expand_to_tuple");
  1002. Entity *entity = alloc_entity(Entity_Builtin, nullptr, make_token_ident(name), t_invalid);
  1003. entity->Builtin.id = id;
  1004. add_global_entity(entity, builtin_pkg->scope);
  1005. }
  1006. bool defined_values_double_declaration = false;
  1007. for (auto const &entry : bc->defined_values) {
  1008. char const *name = entry.key;
  1009. ExactValue value = entry.value;
  1010. GB_ASSERT(value.kind != ExactValue_Invalid);
  1011. Type *type = nullptr;
  1012. switch (value.kind) {
  1013. case ExactValue_Bool:
  1014. type = t_untyped_bool;
  1015. break;
  1016. case ExactValue_String:
  1017. type = t_untyped_string;
  1018. break;
  1019. case ExactValue_Integer:
  1020. type = t_untyped_integer;
  1021. break;
  1022. case ExactValue_Float:
  1023. type = t_untyped_float;
  1024. break;
  1025. }
  1026. GB_ASSERT(type != nullptr);
  1027. Entity *entity = alloc_entity_constant(nullptr, make_token_ident(name), type, value);
  1028. entity->state = EntityState_Resolved;
  1029. if (scope_insert(config_pkg->scope, entity)) {
  1030. error(entity->token, "'%s' defined as an argument is already declared at the global scope", name);
  1031. defined_values_double_declaration = true;
  1032. // NOTE(bill): Just exit early before anything, even though the compiler will do that anyway
  1033. }
  1034. }
  1035. if (defined_values_double_declaration) {
  1036. exit_with_errors();
  1037. }
  1038. t_u8_ptr = alloc_type_pointer(t_u8);
  1039. t_u8_multi_ptr = alloc_type_multi_pointer(t_u8);
  1040. t_int_ptr = alloc_type_pointer(t_int);
  1041. t_i64_ptr = alloc_type_pointer(t_i64);
  1042. t_f64_ptr = alloc_type_pointer(t_f64);
  1043. t_u8_slice = alloc_type_slice(t_u8);
  1044. t_string_slice = alloc_type_slice(t_string);
  1045. // intrinsics types for objective-c stuff
  1046. {
  1047. t_objc_object = add_global_type_name(intrinsics_pkg->scope, str_lit("objc_object"), alloc_type_struct_complete());
  1048. t_objc_selector = add_global_type_name(intrinsics_pkg->scope, str_lit("objc_selector"), alloc_type_struct_complete());
  1049. t_objc_class = add_global_type_name(intrinsics_pkg->scope, str_lit("objc_class"), alloc_type_struct_complete());
  1050. t_objc_id = alloc_type_pointer(t_objc_object);
  1051. t_objc_SEL = alloc_type_pointer(t_objc_selector);
  1052. t_objc_Class = alloc_type_pointer(t_objc_class);
  1053. }
  1054. }
  1055. gb_internal void init_checker_info(CheckerInfo *i) {
  1056. gbAllocator a = heap_allocator();
  1057. TIME_SECTION("checker info: general");
  1058. array_init(&i->definitions, a);
  1059. array_init(&i->entities, a);
  1060. map_init(&i->global_untyped);
  1061. string_map_init(&i->foreigns);
  1062. // map_init(&i->gen_procs);
  1063. map_init(&i->gen_types);
  1064. array_init(&i->type_info_types, a);
  1065. map_init(&i->type_info_map);
  1066. string_map_init(&i->files);
  1067. string_map_init(&i->packages);
  1068. array_init(&i->variable_init_order, a);
  1069. array_init(&i->testing_procedures, a, 0, 0);
  1070. array_init(&i->init_procedures, a, 0, 0);
  1071. array_init(&i->fini_procedures, a, 0, 0);
  1072. array_init(&i->required_foreign_imports_through_force, a, 0, 0);
  1073. map_init(&i->objc_msgSend_types);
  1074. string_map_init(&i->load_file_cache);
  1075. array_init(&i->all_procedures, heap_allocator());
  1076. mpsc_init(&i->entity_queue, a); // 1<<20);
  1077. mpsc_init(&i->definition_queue, a); //); // 1<<20);
  1078. mpsc_init(&i->required_global_variable_queue, a); // 1<<10);
  1079. mpsc_init(&i->required_foreign_imports_through_force_queue, a); // 1<<10);
  1080. mpsc_init(&i->foreign_imports_to_check_fullpaths, a); // 1<<10);
  1081. mpsc_init(&i->intrinsics_entry_point_usage, a); // 1<<10); // just waste some memory here, even if it probably never used
  1082. string_map_init(&i->load_directory_cache);
  1083. map_init(&i->load_directory_map);
  1084. }
  1085. gb_internal void destroy_checker_info(CheckerInfo *i) {
  1086. array_free(&i->definitions);
  1087. array_free(&i->entities);
  1088. map_destroy(&i->global_untyped);
  1089. string_map_destroy(&i->foreigns);
  1090. // map_destroy(&i->gen_procs);
  1091. map_destroy(&i->gen_types);
  1092. array_free(&i->type_info_types);
  1093. map_destroy(&i->type_info_map);
  1094. string_map_destroy(&i->files);
  1095. string_map_destroy(&i->packages);
  1096. array_free(&i->variable_init_order);
  1097. array_free(&i->required_foreign_imports_through_force);
  1098. mpsc_destroy(&i->entity_queue);
  1099. mpsc_destroy(&i->definition_queue);
  1100. mpsc_destroy(&i->required_global_variable_queue);
  1101. mpsc_destroy(&i->required_foreign_imports_through_force_queue);
  1102. mpsc_destroy(&i->foreign_imports_to_check_fullpaths);
  1103. map_destroy(&i->objc_msgSend_types);
  1104. string_map_destroy(&i->load_file_cache);
  1105. string_map_destroy(&i->load_directory_cache);
  1106. map_destroy(&i->load_directory_map);
  1107. }
  1108. gb_internal CheckerContext make_checker_context(Checker *c) {
  1109. CheckerContext ctx = {};
  1110. ctx.checker = c;
  1111. ctx.info = &c->info;
  1112. ctx.scope = builtin_pkg->scope;
  1113. ctx.pkg = builtin_pkg;
  1114. ctx.type_path = new_checker_type_path();
  1115. ctx.type_level = 0;
  1116. return ctx;
  1117. }
  1118. gb_internal void destroy_checker_context(CheckerContext *ctx) {
  1119. destroy_checker_type_path(ctx->type_path);
  1120. }
  1121. gb_internal bool add_curr_ast_file(CheckerContext *ctx, AstFile *file) {
  1122. if (file != nullptr) {
  1123. ctx->file = file;
  1124. ctx->decl = file->pkg->decl_info;
  1125. ctx->scope = file->scope;
  1126. ctx->pkg = file->pkg;
  1127. return true;
  1128. }
  1129. return false;
  1130. }
  1131. gb_internal void reset_checker_context(CheckerContext *ctx, AstFile *file, UntypedExprInfoMap *untyped) {
  1132. if (ctx == nullptr) {
  1133. return;
  1134. }
  1135. GB_ASSERT(ctx->checker != nullptr);
  1136. mutex_lock(&ctx->mutex);
  1137. auto type_path = ctx->type_path;
  1138. array_clear(type_path);
  1139. zero_size(&ctx->pkg, gb_size_of(CheckerContext) - gb_offset_of(CheckerContext, pkg));
  1140. ctx->file = nullptr;
  1141. ctx->scope = builtin_pkg->scope;
  1142. ctx->pkg = builtin_pkg;
  1143. ctx->decl = nullptr;
  1144. ctx->type_path = type_path;
  1145. ctx->type_level = 0;
  1146. add_curr_ast_file(ctx, file);
  1147. ctx->untyped = untyped;
  1148. mutex_unlock(&ctx->mutex);
  1149. }
  1150. gb_internal void init_checker(Checker *c) {
  1151. gbAllocator a = heap_allocator();
  1152. TIME_SECTION("init checker info");
  1153. init_checker_info(&c->info);
  1154. c->info.checker = c;
  1155. TIME_SECTION("init proc queues");
  1156. mpsc_init(&c->procs_with_deferred_to_check, a); //, 1<<10);
  1157. // NOTE(bill): 1 Mi elements should be enough on average
  1158. array_init(&c->procs_to_check, heap_allocator(), 0, 1<<20);
  1159. array_init(&c->nested_proc_lits, heap_allocator(), 0, 1<<20);
  1160. mpsc_init(&c->global_untyped_queue, a); // , 1<<20);
  1161. mpsc_init(&c->soa_types_to_complete, a); // , 1<<20);
  1162. c->builtin_ctx = make_checker_context(c);
  1163. }
  1164. gb_internal void destroy_checker(Checker *c) {
  1165. destroy_checker_info(&c->info);
  1166. destroy_checker_context(&c->builtin_ctx);
  1167. array_free(&c->nested_proc_lits);
  1168. array_free(&c->procs_to_check);
  1169. mpsc_destroy(&c->global_untyped_queue);
  1170. mpsc_destroy(&c->soa_types_to_complete);
  1171. }
  1172. gb_internal TypeAndValue type_and_value_of_expr(Ast *expr) {
  1173. TypeAndValue tav = {};
  1174. if (expr != nullptr) {
  1175. tav = expr->tav;
  1176. }
  1177. return tav;
  1178. }
  1179. gb_internal Type *type_of_expr(Ast *expr) {
  1180. TypeAndValue tav = expr->tav;
  1181. if (tav.mode != Addressing_Invalid) {
  1182. return tav.type;
  1183. }
  1184. {
  1185. Entity *entity = entity_of_node(expr);
  1186. if (entity) {
  1187. return entity->type;
  1188. }
  1189. }
  1190. return nullptr;
  1191. }
  1192. gb_internal Entity *implicit_entity_of_node(Ast *clause) {
  1193. if (clause != nullptr && clause->kind == Ast_CaseClause) {
  1194. return clause->CaseClause.implicit_entity;
  1195. }
  1196. return nullptr;
  1197. }
  1198. gb_internal Entity *entity_of_node(Ast *expr) {
  1199. expr = unparen_expr(expr);
  1200. switch (expr->kind) {
  1201. case_ast_node(ident, Ident, expr);
  1202. Entity *e = ident->entity;
  1203. if (e && e->flags & EntityFlag_Overridden) {
  1204. // GB_PANIC("use of an overriden entity: %.*s", LIT(e->token.string));
  1205. }
  1206. return e;
  1207. case_end;
  1208. case_ast_node(se, SelectorExpr, expr);
  1209. Ast *s = unselector_expr(se->selector);
  1210. return entity_of_node(s);
  1211. case_end;
  1212. case_ast_node(cc, CaseClause, expr);
  1213. return cc->implicit_entity;
  1214. case_end;
  1215. }
  1216. return nullptr;
  1217. }
  1218. gb_internal DeclInfo *decl_info_of_entity(Entity *e) {
  1219. if (e != nullptr) {
  1220. return e->decl_info;
  1221. }
  1222. return nullptr;
  1223. }
  1224. // gb_internal DeclInfo *decl_info_of_ident(Ast *ident) {
  1225. // return decl_info_of_entity(entity_of_node(ident));
  1226. // }
  1227. // gb_internal AstFile *ast_file_of_filename(CheckerInfo *i, String filename) {
  1228. // AstFile **found = string_map_get(&i->files, filename);
  1229. // if (found != nullptr) {
  1230. // return *found;
  1231. // }
  1232. // return nullptr;
  1233. // }
  1234. gb_internal ExprInfo *check_get_expr_info(CheckerContext *c, Ast *expr) {
  1235. if (c->untyped != nullptr) {
  1236. ExprInfo **found = map_get(c->untyped, expr);
  1237. if (found) {
  1238. return *found;
  1239. }
  1240. return nullptr;
  1241. } else {
  1242. rw_mutex_shared_lock(&c->info->global_untyped_mutex);
  1243. ExprInfo **found = map_get(&c->info->global_untyped, expr);
  1244. rw_mutex_shared_unlock(&c->info->global_untyped_mutex);
  1245. if (found) {
  1246. return *found;
  1247. }
  1248. return nullptr;
  1249. }
  1250. }
  1251. gb_internal void check_set_expr_info(CheckerContext *c, Ast *expr, AddressingMode mode, Type *type, ExactValue value) {
  1252. if (c->untyped != nullptr) {
  1253. map_set(c->untyped, expr, make_expr_info(mode, type, value, false));
  1254. } else {
  1255. rw_mutex_lock(&c->info->global_untyped_mutex);
  1256. map_set(&c->info->global_untyped, expr, make_expr_info(mode, type, value, false));
  1257. rw_mutex_unlock(&c->info->global_untyped_mutex);
  1258. }
  1259. }
  1260. gb_internal void check_remove_expr_info(CheckerContext *c, Ast *e) {
  1261. if (c->untyped != nullptr) {
  1262. map_remove(c->untyped, e);
  1263. GB_ASSERT(map_get(c->untyped, e) == nullptr);
  1264. } else {
  1265. auto *untyped = &c->info->global_untyped;
  1266. rw_mutex_lock(&c->info->global_untyped_mutex);
  1267. map_remove(untyped, e);
  1268. GB_ASSERT(map_get(untyped, e) == nullptr);
  1269. rw_mutex_unlock(&c->info->global_untyped_mutex);
  1270. }
  1271. }
  1272. gb_internal isize type_info_index(CheckerInfo *info, Type *type, bool error_on_failure) {
  1273. type = default_type(type);
  1274. if (type == t_llvm_bool) {
  1275. type = t_bool;
  1276. }
  1277. mutex_lock(&info->type_info_mutex);
  1278. isize entry_index = -1;
  1279. isize *found_entry_index = map_get(&info->type_info_map, type);
  1280. if (found_entry_index) {
  1281. entry_index = *found_entry_index;
  1282. }
  1283. if (entry_index < 0) {
  1284. // NOTE(bill): Do manual linear search
  1285. for (auto const &e : info->type_info_map) {
  1286. if (are_types_identical_unique_tuples(e.key, type)) {
  1287. entry_index = e.value;
  1288. // NOTE(bill): Add it to the search map
  1289. map_set(&info->type_info_map, type, entry_index);
  1290. break;
  1291. }
  1292. }
  1293. }
  1294. mutex_unlock(&info->type_info_mutex);
  1295. if (error_on_failure && entry_index < 0) {
  1296. compiler_error("Type_Info for '%s' could not be found", type_to_string(type));
  1297. }
  1298. return entry_index;
  1299. }
  1300. gb_internal void add_untyped(CheckerContext *c, Ast *expr, AddressingMode mode, Type *type, ExactValue const &value) {
  1301. if (expr == nullptr) {
  1302. return;
  1303. }
  1304. if (mode == Addressing_Invalid) {
  1305. return;
  1306. }
  1307. if (mode == Addressing_Constant && type == t_invalid) {
  1308. compiler_error("add_untyped - invalid type: %s", type_to_string(type));
  1309. }
  1310. if (!is_type_untyped(type)) {
  1311. return;
  1312. }
  1313. check_set_expr_info(c, expr, mode, type, value);
  1314. }
  1315. gb_internal void add_type_and_value(CheckerContext *ctx, Ast *expr, AddressingMode mode, Type *type, ExactValue const &value) {
  1316. if (expr == nullptr) {
  1317. return;
  1318. }
  1319. if (mode == Addressing_Invalid) {
  1320. return;
  1321. }
  1322. if (mode == Addressing_Constant && type == t_invalid) {
  1323. return;
  1324. }
  1325. BlockingMutex *mutex = &ctx->info->type_and_value_mutex;
  1326. if (ctx->decl) {
  1327. mutex = &ctx->decl->type_and_value_mutex;
  1328. } else if (ctx->pkg) {
  1329. mutex = &ctx->pkg->type_and_value_mutex;
  1330. }
  1331. mutex_lock(mutex);
  1332. Ast *prev_expr = nullptr;
  1333. while (prev_expr != expr) {
  1334. prev_expr = expr;
  1335. expr->tav.mode = mode;
  1336. if (type != nullptr && expr->tav.type != nullptr &&
  1337. is_type_any(type) && is_type_untyped(expr->tav.type)) {
  1338. // ignore
  1339. } else {
  1340. expr->tav.type = type;
  1341. }
  1342. if (mode == Addressing_Constant || mode == Addressing_Invalid) {
  1343. expr->tav.value = value;
  1344. } else if (mode == Addressing_Value && is_type_typeid(type)) {
  1345. expr->tav.value = value;
  1346. } else if (mode == Addressing_Value && is_type_proc(type)) {
  1347. expr->tav.value = value;
  1348. }
  1349. expr = unparen_expr(expr);
  1350. }
  1351. mutex_unlock(mutex);
  1352. }
  1353. gb_internal void add_entity_definition(CheckerInfo *i, Ast *identifier, Entity *entity) {
  1354. GB_ASSERT(identifier != nullptr);
  1355. if (identifier->kind != Ast_Ident) {
  1356. return;
  1357. }
  1358. if (identifier->Ident.entity != nullptr) {
  1359. // NOTE(bill): Identifier has already been handled
  1360. return;
  1361. }
  1362. GB_ASSERT(entity != nullptr);
  1363. identifier->Ident.entity = entity;
  1364. entity->identifier = identifier;
  1365. mpsc_enqueue(&i->definition_queue, entity);
  1366. }
  1367. gb_internal bool redeclaration_error(String name, Entity *prev, Entity *found) {
  1368. TokenPos pos = found->token.pos;
  1369. Entity *up = found->using_parent;
  1370. if (up != nullptr) {
  1371. if (pos == up->token.pos) {
  1372. // NOTE(bill): Error should have been handled already
  1373. return false;
  1374. }
  1375. if (found->flags & EntityFlag_Result) {
  1376. error(prev->token,
  1377. "Direct shadowing of the named return value '%.*s' in this scope through 'using'\n"
  1378. "\tat %s",
  1379. LIT(name),
  1380. token_pos_to_string(up->token.pos));
  1381. } else {
  1382. error(prev->token,
  1383. "Redeclaration of '%.*s' in this scope through 'using'\n"
  1384. "\tat %s",
  1385. LIT(name),
  1386. token_pos_to_string(up->token.pos));
  1387. }
  1388. } else {
  1389. if (pos == prev->token.pos) {
  1390. // NOTE(bill): Error should have been handled already
  1391. return false;
  1392. }
  1393. if (found->flags & EntityFlag_Result) {
  1394. error(prev->token,
  1395. "Direct shadowing of the named return value '%.*s' in this scope\n"
  1396. "\tat %s",
  1397. LIT(name),
  1398. token_pos_to_string(pos));
  1399. } else {
  1400. error(prev->token,
  1401. "Redeclaration of '%.*s' in this scope\n"
  1402. "\tat %s",
  1403. LIT(name),
  1404. token_pos_to_string(pos));
  1405. }
  1406. }
  1407. return false;
  1408. }
  1409. gb_internal void add_entity_flags_from_file(CheckerContext *c, Entity *e, Scope *scope) {
  1410. if (c->file != nullptr && (c->file->flags & AstFile_IsLazy) != 0 && scope->flags & ScopeFlag_File) {
  1411. AstPackage *pkg = c->file->pkg;
  1412. if (pkg->kind == Package_Init && e->kind == Entity_Procedure && e->token.string == "main") {
  1413. // Do nothing
  1414. } else if (e->flags & (EntityFlag_Test|EntityFlag_Init|EntityFlag_Fini)) {
  1415. // Do nothing
  1416. } else {
  1417. e->flags |= EntityFlag_Lazy;
  1418. }
  1419. }
  1420. }
  1421. gb_internal bool add_entity_with_name(CheckerContext *c, Scope *scope, Ast *identifier, Entity *entity, String name) {
  1422. if (scope == nullptr) {
  1423. return false;
  1424. }
  1425. if (!is_blank_ident(name)) {
  1426. Entity *ie = scope_insert(scope, entity);
  1427. if (ie != nullptr) {
  1428. return redeclaration_error(name, entity, ie);
  1429. }
  1430. }
  1431. if (identifier != nullptr) {
  1432. if (entity->file == nullptr) {
  1433. entity->file = c->file;
  1434. }
  1435. add_entity_definition(c->info, identifier, entity);
  1436. }
  1437. return true;
  1438. }
  1439. gb_internal bool add_entity_with_name(CheckerInfo *info, Scope *scope, Ast *identifier, Entity *entity, String name) {
  1440. if (scope == nullptr) {
  1441. return false;
  1442. }
  1443. if (!is_blank_ident(name)) {
  1444. Entity *ie = scope_insert(scope, entity);
  1445. if (ie != nullptr) {
  1446. return redeclaration_error(name, entity, ie);
  1447. }
  1448. }
  1449. if (identifier != nullptr) {
  1450. GB_ASSERT(entity->file != nullptr);
  1451. add_entity_definition(info, identifier, entity);
  1452. }
  1453. return true;
  1454. }
  1455. gb_internal bool add_entity(CheckerContext *c, Scope *scope, Ast *identifier, Entity *entity) {
  1456. return add_entity_with_name(c, scope, identifier, entity, entity->token.string);
  1457. }
  1458. gb_internal void add_entity_use(CheckerContext *c, Ast *identifier, Entity *entity) {
  1459. if (entity == nullptr) {
  1460. return;
  1461. }
  1462. add_declaration_dependency(c, entity);
  1463. entity->flags |= EntityFlag_Used;
  1464. if (entity_has_deferred_procedure(entity)) {
  1465. Entity *deferred = entity->Procedure.deferred_procedure.entity;
  1466. add_entity_use(c, nullptr, deferred);
  1467. }
  1468. if (identifier == nullptr || identifier->kind != Ast_Ident) {
  1469. return;
  1470. }
  1471. Ast *empty_ident = nullptr;
  1472. entity->identifier.compare_exchange_strong(empty_ident, identifier);
  1473. identifier->Ident.entity = entity;
  1474. String dmsg = entity->deprecated_message;
  1475. if (dmsg.len > 0) {
  1476. warning(identifier, "%.*s is deprecated: %.*s", LIT(entity->token.string), LIT(dmsg));
  1477. }
  1478. String wmsg = entity->warning_message;
  1479. if (wmsg.len > 0) {
  1480. warning(identifier, "%.*s: %.*s", LIT(entity->token.string), LIT(wmsg));
  1481. }
  1482. }
  1483. gb_internal bool could_entity_be_lazy(Entity *e, DeclInfo *d) {
  1484. if ((e->flags & EntityFlag_Lazy) == 0) {
  1485. return false;
  1486. }
  1487. if (e->flags & (EntityFlag_Test|EntityFlag_Init|EntityFlag_Fini)) {
  1488. return false;
  1489. } else if (e->kind == Entity_Variable && e->Variable.is_export) {
  1490. return false;
  1491. } else if (e->kind == Entity_Procedure && e->Procedure.is_export) {
  1492. return false;
  1493. }
  1494. for (Ast *attr : d->attributes) {
  1495. if (attr->kind != Ast_Attribute) continue;
  1496. for (Ast *elem : attr->Attribute.elems) {
  1497. String name = {};
  1498. switch (elem->kind) {
  1499. case_ast_node(i, Ident, elem);
  1500. name = i->token.string;
  1501. case_end;
  1502. case_ast_node(i, Implicit, elem);
  1503. name = i->string;
  1504. case_end;
  1505. case_ast_node(fv, FieldValue, elem);
  1506. if (fv->field->kind == Ast_Ident) {
  1507. name = fv->field->Ident.token.string;
  1508. }
  1509. case_end;
  1510. }
  1511. if (name.len != 0) {
  1512. if (name == "test") {
  1513. return false;
  1514. } else if (name == "export") {
  1515. return false;
  1516. } else if (name == "init") {
  1517. return false;
  1518. } else if (name == "linkage") {
  1519. return false;
  1520. }
  1521. }
  1522. }
  1523. }
  1524. return true;
  1525. }
  1526. gb_internal void add_entity_and_decl_info(CheckerContext *c, Ast *identifier, Entity *e, DeclInfo *d, bool is_exported) {
  1527. if (identifier == nullptr) {
  1528. // NOTE(bill): Should only happen on errors
  1529. error(e->token, "Invalid variable declaration");
  1530. return;
  1531. }
  1532. if (identifier->kind != Ast_Ident) {
  1533. // NOTE(bill): This is a safety check
  1534. gbString s = expr_to_string(identifier);
  1535. error(identifier, "A variable declaration must be an identifer, got %s", s);
  1536. gb_string_free(s);
  1537. return;
  1538. }
  1539. GB_ASSERT(e != nullptr && d != nullptr);
  1540. GB_ASSERT(identifier->Ident.token.string == e->token.string);
  1541. if (!could_entity_be_lazy(e, d)) {
  1542. e->flags &= ~EntityFlag_Lazy;
  1543. }
  1544. if (e->scope != nullptr) {
  1545. Scope *scope = e->scope;
  1546. if (scope->flags & ScopeFlag_File && is_entity_kind_exported(e->kind) && is_exported) {
  1547. AstPackage *pkg = scope->file->pkg;
  1548. GB_ASSERT(pkg->scope == scope->parent);
  1549. GB_ASSERT(c->pkg == pkg);
  1550. // NOTE(bill): as multiple threads could be accessing this, it needs to be wrapped
  1551. // The current hash map for scopes is not thread safe
  1552. AstPackageExportedEntity ee = {identifier, e};
  1553. mpmc_enqueue(&pkg->exported_entity_queue, ee);
  1554. // mutex_lock(&c->info->scope_mutex);
  1555. // add_entity(c, pkg->scope, identifier, e);
  1556. // mutex_unlock(&c->info->scope_mutex);
  1557. } else {
  1558. add_entity(c, scope, identifier, e);
  1559. }
  1560. }
  1561. CheckerInfo *info = c->info;
  1562. add_entity_definition(info, identifier, e);
  1563. GB_ASSERT(e->decl_info == nullptr);
  1564. e->decl_info = d;
  1565. d->entity = e;
  1566. e->pkg = c->pkg;
  1567. isize queue_count = -1;
  1568. bool is_lazy = false;
  1569. is_lazy = (e->flags & EntityFlag_Lazy) == EntityFlag_Lazy;
  1570. if (!is_lazy) {
  1571. queue_count = mpsc_enqueue(&info->entity_queue, e);
  1572. }
  1573. if (e->token.pos.file_id != 0) {
  1574. e->order_in_src = cast(u64)(e->token.pos.file_id)<<32 | u32(e->token.pos.offset);
  1575. } else {
  1576. GB_ASSERT(!is_lazy);
  1577. e->order_in_src = cast(u64)(1+queue_count);
  1578. }
  1579. }
  1580. gb_internal void add_implicit_entity(CheckerContext *c, Ast *clause, Entity *e) {
  1581. GB_ASSERT(clause != nullptr);
  1582. GB_ASSERT(e != nullptr);
  1583. GB_ASSERT(clause->kind == Ast_CaseClause);
  1584. clause->CaseClause.implicit_entity = e;
  1585. }
  1586. gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t);
  1587. gb_internal void add_type_info_type(CheckerContext *c, Type *t) {
  1588. if (build_context.no_rtti) {
  1589. return;
  1590. }
  1591. if (t == nullptr) {
  1592. return;
  1593. }
  1594. t = default_type(t);
  1595. if (is_type_untyped(t)) {
  1596. return; // Could be nil
  1597. }
  1598. if (is_type_polymorphic(t)) {
  1599. return;
  1600. }
  1601. add_type_info_type_internal(c, t);
  1602. }
  1603. gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t) {
  1604. if (t == nullptr) {
  1605. return;
  1606. }
  1607. add_type_info_dependency(c->info, c->decl, t);
  1608. MUTEX_GUARD_BLOCK(&c->info->type_info_mutex) {
  1609. auto found = map_get(&c->info->type_info_map, t);
  1610. if (found != nullptr) {
  1611. // Types have already been added
  1612. return;
  1613. }
  1614. bool prev = false;
  1615. isize ti_index = -1;
  1616. // NOTE(bill): this is a linear lookup, and is most likely very costly
  1617. // as this map keeps growing linearly
  1618. for (auto const &e : c->info->type_info_map) {
  1619. if (are_types_identical_unique_tuples(t, e.key)) {
  1620. // Duplicate entry
  1621. ti_index = e.value;
  1622. prev = true;
  1623. break;
  1624. }
  1625. }
  1626. if (ti_index < 0) {
  1627. // Unique entry
  1628. // NOTE(bill): map entries grow linearly and in order
  1629. ti_index = c->info->type_info_types.count;
  1630. array_add(&c->info->type_info_types, t);
  1631. }
  1632. map_set(&c->checker->info.type_info_map, t, ti_index);
  1633. if (prev) {
  1634. // NOTE(bill): If a previous one exists already, no need to continue
  1635. return;
  1636. }
  1637. }
  1638. // Add nested types
  1639. if (t->kind == Type_Named) {
  1640. // NOTE(bill): Just in case
  1641. add_type_info_type_internal(c, t->Named.base);
  1642. return;
  1643. }
  1644. Type *bt = base_type(t);
  1645. add_type_info_type_internal(c, bt);
  1646. switch (bt->kind) {
  1647. case Type_Invalid:
  1648. break;
  1649. case Type_Basic:
  1650. switch (bt->Basic.kind) {
  1651. case Basic_cstring:
  1652. add_type_info_type_internal(c, t_u8_ptr);
  1653. break;
  1654. case Basic_string:
  1655. add_type_info_type_internal(c, t_u8_ptr);
  1656. add_type_info_type_internal(c, t_int);
  1657. break;
  1658. case Basic_any:
  1659. add_type_info_type_internal(c, t_type_info_ptr);
  1660. add_type_info_type_internal(c, t_rawptr);
  1661. break;
  1662. case Basic_typeid:
  1663. break;
  1664. case Basic_complex64:
  1665. add_type_info_type_internal(c, t_type_info_float);
  1666. add_type_info_type_internal(c, t_f32);
  1667. break;
  1668. case Basic_complex128:
  1669. add_type_info_type_internal(c, t_type_info_float);
  1670. add_type_info_type_internal(c, t_f64);
  1671. break;
  1672. case Basic_quaternion128:
  1673. add_type_info_type_internal(c, t_type_info_float);
  1674. add_type_info_type_internal(c, t_f32);
  1675. break;
  1676. case Basic_quaternion256:
  1677. add_type_info_type_internal(c, t_type_info_float);
  1678. add_type_info_type_internal(c, t_f64);
  1679. break;
  1680. }
  1681. break;
  1682. case Type_BitSet:
  1683. add_type_info_type_internal(c, bt->BitSet.elem);
  1684. add_type_info_type_internal(c, bt->BitSet.underlying);
  1685. break;
  1686. case Type_Pointer:
  1687. add_type_info_type_internal(c, bt->Pointer.elem);
  1688. break;
  1689. case Type_MultiPointer:
  1690. add_type_info_type_internal(c, bt->MultiPointer.elem);
  1691. break;
  1692. case Type_Array:
  1693. add_type_info_type_internal(c, bt->Array.elem);
  1694. add_type_info_type_internal(c, alloc_type_pointer(bt->Array.elem));
  1695. add_type_info_type_internal(c, t_int);
  1696. break;
  1697. case Type_EnumeratedArray:
  1698. add_type_info_type_internal(c, bt->EnumeratedArray.index);
  1699. add_type_info_type_internal(c, t_int);
  1700. add_type_info_type_internal(c, bt->EnumeratedArray.elem);
  1701. add_type_info_type_internal(c, alloc_type_pointer(bt->EnumeratedArray.elem));
  1702. break;
  1703. case Type_DynamicArray:
  1704. add_type_info_type_internal(c, bt->DynamicArray.elem);
  1705. add_type_info_type_internal(c, alloc_type_pointer(bt->DynamicArray.elem));
  1706. add_type_info_type_internal(c, t_int);
  1707. add_type_info_type_internal(c, t_allocator);
  1708. break;
  1709. case Type_Slice:
  1710. add_type_info_type_internal(c, bt->Slice.elem);
  1711. add_type_info_type_internal(c, alloc_type_pointer(bt->Slice.elem));
  1712. add_type_info_type_internal(c, t_int);
  1713. break;
  1714. case Type_Enum:
  1715. add_type_info_type_internal(c, bt->Enum.base_type);
  1716. break;
  1717. case Type_Union:
  1718. if (union_tag_size(t) > 0) {
  1719. add_type_info_type_internal(c, union_tag_type(t));
  1720. } else {
  1721. add_type_info_type_internal(c, t_type_info_ptr);
  1722. }
  1723. add_type_info_type_internal(c, bt->Union.polymorphic_params);
  1724. for_array(i, bt->Union.variants) {
  1725. add_type_info_type_internal(c, bt->Union.variants[i]);
  1726. }
  1727. if (bt->Union.scope != nullptr) {
  1728. for (auto const &entry : bt->Union.scope->elements) {
  1729. Entity *e = entry.value;
  1730. add_type_info_type_internal(c, e->type);
  1731. }
  1732. }
  1733. break;
  1734. case Type_Struct:
  1735. if (bt->Struct.fields_wait_signal.futex.load() == 0)
  1736. return;
  1737. if (bt->Struct.scope != nullptr) {
  1738. for (auto const &entry : bt->Struct.scope->elements) {
  1739. Entity *e = entry.value;
  1740. switch (bt->Struct.soa_kind) {
  1741. case StructSoa_Dynamic:
  1742. add_type_info_type_internal(c, t_allocator);
  1743. /*fallthrough*/
  1744. case StructSoa_Slice:
  1745. case StructSoa_Fixed:
  1746. add_type_info_type_internal(c, alloc_type_pointer(e->type));
  1747. break;
  1748. default:
  1749. add_type_info_type_internal(c, e->type);
  1750. break;
  1751. }
  1752. }
  1753. }
  1754. add_type_info_type_internal(c, bt->Struct.polymorphic_params);
  1755. for_array(i, bt->Struct.fields) {
  1756. Entity *f = bt->Struct.fields[i];
  1757. if (f && f->type) {
  1758. add_type_info_type_internal(c, f->type);
  1759. }
  1760. }
  1761. add_comparison_procedures_for_fields(c, bt);
  1762. break;
  1763. case Type_Map:
  1764. init_map_internal_types(bt);
  1765. add_type_info_type_internal(c, bt->Map.key);
  1766. add_type_info_type_internal(c, bt->Map.value);
  1767. add_type_info_type_internal(c, t_uintptr); // hash value
  1768. add_type_info_type_internal(c, t_allocator);
  1769. break;
  1770. case Type_Tuple:
  1771. for_array(i, bt->Tuple.variables) {
  1772. Entity *var = bt->Tuple.variables[i];
  1773. add_type_info_type_internal(c, var->type);
  1774. }
  1775. break;
  1776. case Type_Proc:
  1777. add_type_info_type_internal(c, bt->Proc.params);
  1778. add_type_info_type_internal(c, bt->Proc.results);
  1779. break;
  1780. case Type_SimdVector:
  1781. add_type_info_type_internal(c, bt->SimdVector.elem);
  1782. break;
  1783. case Type_RelativePointer:
  1784. add_type_info_type_internal(c, bt->RelativePointer.pointer_type);
  1785. add_type_info_type_internal(c, bt->RelativePointer.base_integer);
  1786. break;
  1787. case Type_RelativeMultiPointer:
  1788. add_type_info_type_internal(c, bt->RelativeMultiPointer.pointer_type);
  1789. add_type_info_type_internal(c, bt->RelativeMultiPointer.base_integer);
  1790. break;
  1791. case Type_Matrix:
  1792. add_type_info_type_internal(c, bt->Matrix.elem);
  1793. break;
  1794. case Type_SoaPointer:
  1795. add_type_info_type_internal(c, bt->SoaPointer.elem);
  1796. break;
  1797. case Type_BitField:
  1798. add_type_info_type_internal(c, bt->BitField.backing_type);
  1799. for (Entity *f : bt->BitField.fields) {
  1800. add_type_info_type_internal(c, f->type);
  1801. }
  1802. break;
  1803. case Type_Generic:
  1804. break;
  1805. default:
  1806. GB_PANIC("Unhandled type: %*.s %d", LIT(type_strings[bt->kind]), bt->kind);
  1807. break;
  1808. }
  1809. }
  1810. gb_global std::atomic<bool> global_procedure_body_in_worker_queue;
  1811. gb_global std::atomic<bool> global_after_checking_procedure_bodies;
  1812. gb_internal WORKER_TASK_PROC(check_proc_info_worker_proc);
  1813. gb_internal void check_procedure_later(Checker *c, ProcInfo *info) {
  1814. GB_ASSERT(info != nullptr);
  1815. GB_ASSERT(info->decl != nullptr);
  1816. if (global_after_checking_procedure_bodies) {
  1817. Entity *e = info->decl->entity;
  1818. debugf("CHECK PROCEDURE LATER! %.*s :: %s {...}\n", LIT(e->token.string), type_to_string(e->type));
  1819. }
  1820. if (global_procedure_body_in_worker_queue.load()) {
  1821. thread_pool_add_task(check_proc_info_worker_proc, info);
  1822. } else {
  1823. array_add(&c->procs_to_check, info);
  1824. }
  1825. if (DEBUG_CHECK_ALL_PROCEDURES) {
  1826. MUTEX_GUARD_BLOCK(&c->info.all_procedures_mutex) {
  1827. GB_ASSERT(info != nullptr);
  1828. GB_ASSERT(info->decl != nullptr);
  1829. array_add(&c->info.all_procedures, info);
  1830. }
  1831. }
  1832. }
  1833. gb_internal void check_procedure_later(Checker *c, AstFile *file, Token token, DeclInfo *decl, Type *type, Ast *body, u64 tags) {
  1834. ProcInfo *info = gb_alloc_item(permanent_allocator(), ProcInfo);
  1835. info->file = file;
  1836. info->token = token;
  1837. info->decl = decl;
  1838. info->type = type;
  1839. info->body = body;
  1840. info->tags = tags;
  1841. check_procedure_later(c, info);
  1842. }
  1843. gb_internal void add_min_dep_type_info(Checker *c, Type *t) {
  1844. if (t == nullptr) {
  1845. return;
  1846. }
  1847. t = default_type(t);
  1848. if (is_type_untyped(t)) {
  1849. return; // Could be nil
  1850. }
  1851. if (is_type_polymorphic(base_type(t))) {
  1852. return;
  1853. }
  1854. auto *set = &c->info.minimum_dependency_type_info_set;
  1855. isize ti_index = type_info_index(&c->info, t, false);
  1856. if (ti_index < 0) {
  1857. add_type_info_type(&c->builtin_ctx, t); // Missing the type information
  1858. ti_index = type_info_index(&c->info, t, false);
  1859. }
  1860. GB_ASSERT(ti_index >= 0);
  1861. // IMPORTANT NOTE(bill): this must be copied as `map_set` takes a const ref
  1862. // and effectively assigns the `+1` of the value
  1863. isize const count = set->count;
  1864. if (map_set_if_not_previously_exists(set, ti_index+1, count)) {
  1865. // Type already exists;
  1866. return;
  1867. }
  1868. // Add nested types
  1869. if (t->kind == Type_Named) {
  1870. // NOTE(bill): Just in case
  1871. add_min_dep_type_info(c, t->Named.base);
  1872. return;
  1873. }
  1874. Type *bt = base_type(t);
  1875. add_min_dep_type_info(c, bt);
  1876. switch (bt->kind) {
  1877. case Type_Invalid:
  1878. break;
  1879. case Type_Basic:
  1880. switch (bt->Basic.kind) {
  1881. case Basic_string:
  1882. add_min_dep_type_info(c, t_u8_ptr);
  1883. add_min_dep_type_info(c, t_int);
  1884. break;
  1885. case Basic_any:
  1886. add_min_dep_type_info(c, t_rawptr);
  1887. add_min_dep_type_info(c, t_typeid);
  1888. break;
  1889. case Basic_complex64:
  1890. add_min_dep_type_info(c, t_type_info_float);
  1891. add_min_dep_type_info(c, t_f32);
  1892. break;
  1893. case Basic_complex128:
  1894. add_min_dep_type_info(c, t_type_info_float);
  1895. add_min_dep_type_info(c, t_f64);
  1896. break;
  1897. case Basic_quaternion128:
  1898. add_min_dep_type_info(c, t_type_info_float);
  1899. add_min_dep_type_info(c, t_f32);
  1900. break;
  1901. case Basic_quaternion256:
  1902. add_min_dep_type_info(c, t_type_info_float);
  1903. add_min_dep_type_info(c, t_f64);
  1904. break;
  1905. }
  1906. break;
  1907. case Type_BitSet:
  1908. add_min_dep_type_info(c, bt->BitSet.elem);
  1909. add_min_dep_type_info(c, bt->BitSet.underlying);
  1910. break;
  1911. case Type_Pointer:
  1912. add_min_dep_type_info(c, bt->Pointer.elem);
  1913. break;
  1914. case Type_MultiPointer:
  1915. add_min_dep_type_info(c, bt->MultiPointer.elem);
  1916. break;
  1917. case Type_Array:
  1918. add_min_dep_type_info(c, bt->Array.elem);
  1919. add_min_dep_type_info(c, alloc_type_pointer(bt->Array.elem));
  1920. add_min_dep_type_info(c, t_int);
  1921. break;
  1922. case Type_EnumeratedArray:
  1923. add_min_dep_type_info(c, bt->EnumeratedArray.index);
  1924. add_min_dep_type_info(c, t_int);
  1925. add_min_dep_type_info(c, bt->EnumeratedArray.elem);
  1926. add_min_dep_type_info(c, alloc_type_pointer(bt->EnumeratedArray.elem));
  1927. break;
  1928. case Type_DynamicArray:
  1929. add_min_dep_type_info(c, bt->DynamicArray.elem);
  1930. add_min_dep_type_info(c, alloc_type_pointer(bt->DynamicArray.elem));
  1931. add_min_dep_type_info(c, t_int);
  1932. add_min_dep_type_info(c, t_allocator);
  1933. break;
  1934. case Type_Slice:
  1935. add_min_dep_type_info(c, bt->Slice.elem);
  1936. add_min_dep_type_info(c, alloc_type_pointer(bt->Slice.elem));
  1937. add_min_dep_type_info(c, t_int);
  1938. break;
  1939. case Type_Enum:
  1940. add_min_dep_type_info(c, bt->Enum.base_type);
  1941. break;
  1942. case Type_Union:
  1943. if (union_tag_size(t) > 0) {
  1944. add_min_dep_type_info(c, union_tag_type(t));
  1945. } else {
  1946. add_min_dep_type_info(c, t_type_info_ptr);
  1947. }
  1948. add_min_dep_type_info(c, bt->Union.polymorphic_params);
  1949. for_array(i, bt->Union.variants) {
  1950. add_min_dep_type_info(c, bt->Union.variants[i]);
  1951. }
  1952. break;
  1953. case Type_Struct:
  1954. if (bt->Struct.scope != nullptr) {
  1955. for (auto const &entry : bt->Struct.scope->elements) {
  1956. Entity *e = entry.value;
  1957. switch (bt->Struct.soa_kind) {
  1958. case StructSoa_Dynamic:
  1959. add_min_dep_type_info(c, t_type_info_ptr); // append_soa
  1960. add_min_dep_type_info(c, t_allocator);
  1961. /*fallthrough*/
  1962. case StructSoa_Slice:
  1963. add_min_dep_type_info(c, t_int);
  1964. add_min_dep_type_info(c, t_uint);
  1965. /*fallthrough*/
  1966. case StructSoa_Fixed:
  1967. add_min_dep_type_info(c, alloc_type_pointer(e->type));
  1968. break;
  1969. default:
  1970. add_min_dep_type_info(c, e->type);
  1971. break;
  1972. }
  1973. }
  1974. }
  1975. add_min_dep_type_info(c, bt->Struct.polymorphic_params);
  1976. for_array(i, bt->Struct.fields) {
  1977. Entity *f = bt->Struct.fields[i];
  1978. add_min_dep_type_info(c, f->type);
  1979. }
  1980. break;
  1981. case Type_Map:
  1982. init_map_internal_types(bt);
  1983. add_min_dep_type_info(c, bt->Map.key);
  1984. add_min_dep_type_info(c, bt->Map.value);
  1985. add_min_dep_type_info(c, t_uintptr); // hash value
  1986. add_min_dep_type_info(c, t_allocator);
  1987. break;
  1988. case Type_Tuple:
  1989. for_array(i, bt->Tuple.variables) {
  1990. Entity *var = bt->Tuple.variables[i];
  1991. add_min_dep_type_info(c, var->type);
  1992. }
  1993. break;
  1994. case Type_Proc:
  1995. add_min_dep_type_info(c, bt->Proc.params);
  1996. add_min_dep_type_info(c, bt->Proc.results);
  1997. break;
  1998. case Type_SimdVector:
  1999. add_min_dep_type_info(c, bt->SimdVector.elem);
  2000. break;
  2001. case Type_RelativePointer:
  2002. add_min_dep_type_info(c, bt->RelativePointer.pointer_type);
  2003. add_min_dep_type_info(c, bt->RelativePointer.base_integer);
  2004. break;
  2005. case Type_RelativeMultiPointer:
  2006. add_min_dep_type_info(c, bt->RelativeMultiPointer.pointer_type);
  2007. add_min_dep_type_info(c, bt->RelativeMultiPointer.base_integer);
  2008. break;
  2009. case Type_Matrix:
  2010. add_min_dep_type_info(c, bt->Matrix.elem);
  2011. break;
  2012. case Type_SoaPointer:
  2013. add_min_dep_type_info(c, bt->SoaPointer.elem);
  2014. break;
  2015. case Type_BitField:
  2016. add_min_dep_type_info(c, bt->BitField.backing_type);
  2017. for (Entity *f : bt->BitField.fields) {
  2018. add_min_dep_type_info(c, f->type);
  2019. }
  2020. break;
  2021. default:
  2022. GB_PANIC("Unhandled type: %*.s", LIT(type_strings[bt->kind]));
  2023. break;
  2024. }
  2025. }
  2026. gb_internal void add_dependency_to_set(Checker *c, Entity *entity) {
  2027. if (entity == nullptr) {
  2028. return;
  2029. }
  2030. CheckerInfo *info = &c->info;
  2031. auto *set = &info->minimum_dependency_set;
  2032. if (entity->type != nullptr &&
  2033. is_type_polymorphic(entity->type)) {
  2034. DeclInfo *decl = decl_info_of_entity(entity);
  2035. if (decl != nullptr && decl->gen_proc_type == nullptr) {
  2036. return;
  2037. }
  2038. }
  2039. if (ptr_set_update(set, entity)) {
  2040. return;
  2041. }
  2042. DeclInfo *decl = decl_info_of_entity(entity);
  2043. if (decl == nullptr) {
  2044. return;
  2045. }
  2046. for (Type *t : decl->type_info_deps) {
  2047. add_min_dep_type_info(c, t);
  2048. }
  2049. for (Entity *e : decl->deps) {
  2050. add_dependency_to_set(c, e);
  2051. if (e->kind == Entity_Procedure && e->Procedure.is_foreign) {
  2052. Entity *fl = e->Procedure.foreign_library;
  2053. if (fl != nullptr) {
  2054. GB_ASSERT_MSG(fl->kind == Entity_LibraryName &&
  2055. (fl->flags&EntityFlag_Used),
  2056. "%.*s", LIT(entity->token.string));
  2057. add_dependency_to_set(c, fl);
  2058. }
  2059. } else if (e->kind == Entity_Variable && e->Variable.is_foreign) {
  2060. Entity *fl = e->Variable.foreign_library;
  2061. if (fl != nullptr) {
  2062. GB_ASSERT_MSG(fl->kind == Entity_LibraryName &&
  2063. (fl->flags&EntityFlag_Used),
  2064. "%.*s", LIT(entity->token.string));
  2065. add_dependency_to_set(c, fl);
  2066. }
  2067. }
  2068. }
  2069. }
  2070. gb_internal void force_add_dependency_entity(Checker *c, Scope *scope, String const &name) {
  2071. Entity *e = scope_lookup(scope, name);
  2072. if (e == nullptr) {
  2073. return;
  2074. }
  2075. GB_ASSERT_MSG(e != nullptr, "unable to find %.*s", LIT(name));
  2076. e->flags |= EntityFlag_Used;
  2077. add_dependency_to_set(c, e);
  2078. }
  2079. gb_internal void collect_testing_procedures_of_package(Checker *c, AstPackage *pkg) {
  2080. AstPackage *testing_package = get_core_package(&c->info, str_lit("testing"));
  2081. Scope *testing_scope = testing_package->scope;
  2082. Entity *test_signature = scope_lookup_current(testing_scope, str_lit("Test_Signature"));
  2083. Scope *s = pkg->scope;
  2084. for (auto const &entry : s->elements) {
  2085. Entity *e = entry.value;
  2086. if (e->kind != Entity_Procedure) {
  2087. continue;
  2088. }
  2089. if ((e->flags & EntityFlag_Test) == 0) {
  2090. continue;
  2091. }
  2092. String name = e->token.string;
  2093. bool is_tester = true;
  2094. Type *t = base_type(e->type);
  2095. GB_ASSERT(t->kind == Type_Proc);
  2096. if (are_types_identical(t, base_type(test_signature->type))) {
  2097. // Good
  2098. } else {
  2099. gbString str = type_to_string(t);
  2100. error(e->token, "Testing procedures must have a signature type of proc(^testing.T), got %s", str);
  2101. gb_string_free(str);
  2102. is_tester = false;
  2103. }
  2104. if (is_tester) {
  2105. add_dependency_to_set(c, e);
  2106. array_add(&c->info.testing_procedures, e);
  2107. }
  2108. }
  2109. }
  2110. gb_internal void generate_minimum_dependency_set_internal(Checker *c, Entity *start) {
  2111. for_array(i, c->info.definitions) {
  2112. Entity *e = c->info.definitions[i];
  2113. if (e->scope == builtin_pkg->scope) {
  2114. if (e->type == nullptr) {
  2115. add_dependency_to_set(c, e);
  2116. }
  2117. } else if (e->kind == Entity_Procedure && e->Procedure.is_export) {
  2118. add_dependency_to_set(c, e);
  2119. } else if (e->kind == Entity_Variable && e->Variable.is_export) {
  2120. add_dependency_to_set(c, e);
  2121. }
  2122. }
  2123. for (Entity *e; mpsc_dequeue(&c->info.required_foreign_imports_through_force_queue, &e); /**/) {
  2124. array_add(&c->info.required_foreign_imports_through_force, e);
  2125. add_dependency_to_set(c, e);
  2126. }
  2127. for (Entity *e; mpsc_dequeue(&c->info.required_global_variable_queue, &e); /**/) {
  2128. e->flags |= EntityFlag_Used;
  2129. add_dependency_to_set(c, e);
  2130. }
  2131. for_array(i, c->info.entities) {
  2132. Entity *e = c->info.entities[i];
  2133. switch (e->kind) {
  2134. case Entity_Variable:
  2135. if (e->Variable.is_export) {
  2136. add_dependency_to_set(c, e);
  2137. } else if (e->flags & EntityFlag_Require) {
  2138. add_dependency_to_set(c, e);
  2139. }
  2140. break;
  2141. case Entity_Procedure:
  2142. if (e->Procedure.is_export) {
  2143. add_dependency_to_set(c, e);
  2144. } else if (e->flags & EntityFlag_Require) {
  2145. add_dependency_to_set(c, e);
  2146. }
  2147. if (e->flags & EntityFlag_Init) {
  2148. Type *t = base_type(e->type);
  2149. GB_ASSERT(t->kind == Type_Proc);
  2150. bool is_init = true;
  2151. if (t->Proc.param_count != 0 || t->Proc.result_count != 0) {
  2152. gbString str = type_to_string(t);
  2153. error(e->token, "@(init) procedures must have a signature type with no parameters nor results, got %s", str);
  2154. gb_string_free(str);
  2155. is_init = false;
  2156. }
  2157. if ((e->scope->flags & (ScopeFlag_File|ScopeFlag_Pkg)) == 0) {
  2158. error(e->token, "@(init) procedures must be declared at the file scope");
  2159. is_init = false;
  2160. }
  2161. if ((e->flags & EntityFlag_Disabled) != 0) {
  2162. warning(e->token, "This @(init) procedure is disabled; you must call it manually");
  2163. is_init = false;
  2164. }
  2165. if (is_init) {
  2166. add_dependency_to_set(c, e);
  2167. array_add(&c->info.init_procedures, e);
  2168. }
  2169. } else if (e->flags & EntityFlag_Fini) {
  2170. Type *t = base_type(e->type);
  2171. GB_ASSERT(t->kind == Type_Proc);
  2172. bool is_fini = true;
  2173. if (t->Proc.param_count != 0 || t->Proc.result_count != 0) {
  2174. gbString str = type_to_string(t);
  2175. error(e->token, "@(fini) procedures must have a signature type with no parameters nor results, got %s", str);
  2176. gb_string_free(str);
  2177. is_fini = false;
  2178. }
  2179. if ((e->scope->flags & (ScopeFlag_File|ScopeFlag_Pkg)) == 0) {
  2180. error(e->token, "@(fini) procedures must be declared at the file scope");
  2181. is_fini = false;
  2182. }
  2183. if (is_fini) {
  2184. add_dependency_to_set(c, e);
  2185. array_add(&c->info.fini_procedures, e);
  2186. }
  2187. }
  2188. break;
  2189. }
  2190. }
  2191. if (build_context.command_kind == Command_test) {
  2192. AstPackage *testing_package = get_core_package(&c->info, str_lit("testing"));
  2193. Scope *testing_scope = testing_package->scope;
  2194. // Add all of testing library as a dependency
  2195. for (auto const &entry : testing_scope->elements) {
  2196. Entity *e = entry.value;
  2197. if (e != nullptr) {
  2198. e->flags |= EntityFlag_Used;
  2199. add_dependency_to_set(c, e);
  2200. }
  2201. }
  2202. AstPackage *pkg = c->info.init_package;
  2203. collect_testing_procedures_of_package(c, pkg);
  2204. if (build_context.test_all_packages) {
  2205. for (auto const &entry : c->info.packages) {
  2206. AstPackage *pkg = entry.value;
  2207. collect_testing_procedures_of_package(c, pkg);
  2208. }
  2209. }
  2210. } else if (start != nullptr) {
  2211. start->flags |= EntityFlag_Used;
  2212. add_dependency_to_set(c, start);
  2213. }
  2214. }
  2215. gb_internal void generate_minimum_dependency_set(Checker *c, Entity *start) {
  2216. isize entity_count = c->info.entities.count;
  2217. isize min_dep_set_cap = next_pow2_isize(entity_count*4); // empirically determined factor
  2218. ptr_set_init(&c->info.minimum_dependency_set, min_dep_set_cap);
  2219. map_init(&c->info.minimum_dependency_type_info_set);
  2220. #define FORCE_ADD_RUNTIME_ENTITIES(condition, ...) do { \
  2221. if (condition) { \
  2222. String entities[] = {__VA_ARGS__}; \
  2223. for (isize i = 0; i < gb_count_of(entities); i++) { \
  2224. force_add_dependency_entity(c, c->info.runtime_package->scope, entities[i]); \
  2225. } \
  2226. } \
  2227. } while (0)
  2228. // required runtime entities
  2229. FORCE_ADD_RUNTIME_ENTITIES(true,
  2230. // Odin types
  2231. str_lit("Source_Code_Location"),
  2232. str_lit("Context"),
  2233. str_lit("Allocator"),
  2234. str_lit("Logger"),
  2235. // Odin internal procedures
  2236. str_lit("__init_context"),
  2237. // str_lit("cstring_to_string"),
  2238. str_lit("_cleanup_runtime"),
  2239. // Pseudo-CRT required procedures
  2240. str_lit("memset"),
  2241. // Utility procedures
  2242. str_lit("memory_equal"),
  2243. str_lit("memory_compare"),
  2244. str_lit("memory_compare_zero"),
  2245. );
  2246. // Only required if no CRT is present
  2247. FORCE_ADD_RUNTIME_ENTITIES(build_context.no_crt,
  2248. str_lit("memcpy"),
  2249. str_lit("memmove"),
  2250. );
  2251. FORCE_ADD_RUNTIME_ENTITIES(build_context.metrics.arch == TargetArch_arm32,
  2252. str_lit("aeabi_d2h")
  2253. );
  2254. FORCE_ADD_RUNTIME_ENTITIES(is_arch_wasm() && !build_context.tilde_backend,
  2255. // // Extended data type internal procedures
  2256. // str_lit("umodti3"),
  2257. // str_lit("udivti3"),
  2258. // str_lit("modti3"),
  2259. // str_lit("divti3"),
  2260. // str_lit("fixdfti"),
  2261. // str_lit("fixunsdfti"),
  2262. // str_lit("fixunsdfdi"),
  2263. // str_lit("floattidf"),
  2264. // str_lit("floattidf_unsigned"),
  2265. // str_lit("truncsfhf2"),
  2266. // str_lit("truncdfhf2"),
  2267. // str_lit("gnu_h2f_ieee"),
  2268. // str_lit("gnu_f2h_ieee"),
  2269. // str_lit("extendhfsf2"),
  2270. // WASM Specific
  2271. str_lit("__ashlti3"),
  2272. str_lit("__multi3"),
  2273. );
  2274. FORCE_ADD_RUNTIME_ENTITIES(!build_context.no_rtti,
  2275. // Odin types
  2276. str_lit("Type_Info"),
  2277. // Global variables
  2278. str_lit("type_table"),
  2279. str_lit("__type_info_of"),
  2280. );
  2281. FORCE_ADD_RUNTIME_ENTITIES(!build_context.no_entry_point,
  2282. // Global variables
  2283. str_lit("args__"),
  2284. );
  2285. FORCE_ADD_RUNTIME_ENTITIES((build_context.no_crt && !is_arch_wasm()),
  2286. // NOTE(bill): Only if these exist
  2287. str_lit("_tls_index"),
  2288. str_lit("_fltused"),
  2289. );
  2290. FORCE_ADD_RUNTIME_ENTITIES(!build_context.no_bounds_check,
  2291. // Bounds checking related procedures
  2292. str_lit("bounds_check_error"),
  2293. str_lit("matrix_bounds_check_error"),
  2294. str_lit("slice_expr_error_hi"),
  2295. str_lit("slice_expr_error_lo_hi"),
  2296. str_lit("multi_pointer_slice_expr_error"),
  2297. );
  2298. add_dependency_to_set(c, c->info.instrumentation_enter_entity);
  2299. add_dependency_to_set(c, c->info.instrumentation_exit_entity);
  2300. generate_minimum_dependency_set_internal(c, start);
  2301. #undef FORCE_ADD_RUNTIME_ENTITIES
  2302. }
  2303. gb_internal bool is_entity_a_dependency(Entity *e) {
  2304. if (e == nullptr) return false;
  2305. switch (e->kind) {
  2306. case Entity_Procedure:
  2307. return true;
  2308. case Entity_Constant:
  2309. case Entity_Variable:
  2310. return e->pkg != nullptr;
  2311. case Entity_TypeName:
  2312. return false;
  2313. }
  2314. return false;
  2315. }
  2316. gb_internal Array<EntityGraphNode *> generate_entity_dependency_graph(CheckerInfo *info, gbAllocator allocator) {
  2317. PtrMap<Entity *, EntityGraphNode *> M = {};
  2318. map_init(&M, info->entities.count);
  2319. defer (map_destroy(&M));
  2320. for_array(i, info->entities) {
  2321. Entity *e = info->entities[i];
  2322. if (is_entity_a_dependency(e)) {
  2323. EntityGraphNode *n = gb_alloc_item(allocator, EntityGraphNode);
  2324. n->entity = e;
  2325. map_set(&M, e, n);
  2326. }
  2327. }
  2328. TIME_SECTION("generate_entity_dependency_graph: Calculate edges for graph M - Part 1");
  2329. // Calculate edges for graph M
  2330. for (auto const &entry : M) {
  2331. EntityGraphNode *n = entry.value;
  2332. Entity *e = n->entity;
  2333. DeclInfo *decl = decl_info_of_entity(e);
  2334. GB_ASSERT(decl != nullptr);
  2335. for (Entity *dep : decl->deps) {
  2336. if (dep->flags & EntityFlag_Field) {
  2337. continue;
  2338. }
  2339. GB_ASSERT(dep != nullptr);
  2340. if (is_entity_a_dependency(dep)) {
  2341. EntityGraphNode *m = map_must_get(&M, dep);
  2342. entity_graph_node_set_add(&n->succ, m);
  2343. entity_graph_node_set_add(&m->pred, n);
  2344. }
  2345. }
  2346. }
  2347. TIME_SECTION("generate_entity_dependency_graph: Calculate edges for graph M - Part 2");
  2348. auto G = array_make<EntityGraphNode *>(allocator, 0, M.count);
  2349. for (auto const &m_entry : M) {
  2350. auto *e = m_entry.key;
  2351. EntityGraphNode *n = m_entry.value;
  2352. if (e->kind == Entity_Procedure) {
  2353. // Connect each pred 'p' of 'n' with each succ 's' and from
  2354. // the procedure node
  2355. for (EntityGraphNode *p : n->pred) {
  2356. // Ignore self-cycles
  2357. if (p != n) {
  2358. // Each succ 's' of 'n' becomes a succ of 'p', and
  2359. // each pred 'p' of 'n' becomes a pred of 's'
  2360. for (EntityGraphNode *s : n->succ) {
  2361. // Ignore self-cycles
  2362. if (s != n) {
  2363. if (p->entity->kind == Entity_Procedure &&
  2364. s->entity->kind == Entity_Procedure) {
  2365. // NOTE(bill, 2020-11-15): Only care about variable initialization ordering
  2366. // TODO(bill): This is probably wrong!!!!
  2367. continue;
  2368. }
  2369. // IMPORTANT NOTE/TODO(bill, 2020-11-15): These three calls take the majority of the
  2370. // the time to process
  2371. entity_graph_node_set_add(&p->succ, s);
  2372. entity_graph_node_set_add(&s->pred, p);
  2373. // Remove edge to 'n'
  2374. entity_graph_node_set_remove(&s->pred, n);
  2375. }
  2376. }
  2377. // Remove edge to 'n'
  2378. entity_graph_node_set_remove(&p->succ, n);
  2379. }
  2380. }
  2381. } else if (e->kind == Entity_Variable) {
  2382. array_add(&G, n);
  2383. }
  2384. }
  2385. TIME_SECTION("generate_entity_dependency_graph: Dependency Count Checker");
  2386. for_array(i, G) {
  2387. EntityGraphNode *n = G[i];
  2388. n->index = i;
  2389. n->dep_count = n->succ.count;
  2390. GB_ASSERT(n->dep_count >= 0);
  2391. }
  2392. // f64 succ_count = 0.0;
  2393. // f64 pred_count = 0.0;
  2394. // f64 succ_capacity = 0.0;
  2395. // f64 pred_capacity = 0.0;
  2396. // f64 succ_max = 0.0;
  2397. // f64 pred_max = 0.0;
  2398. // for_array(i, G) {
  2399. // EntityGraphNode *n = G[i];
  2400. // succ_count += n->succ.entries.count;
  2401. // pred_count += n->pred.entries.count;
  2402. // succ_capacity += n->succ.entries.capacity;
  2403. // pred_capacity += n->pred.entries.capacity;
  2404. // succ_max = gb_max(succ_max, n->succ.entries.capacity);
  2405. // pred_max = gb_max(pred_max, n->pred.entries.capacity);
  2406. // }
  2407. // f64 count = cast(f64)G.count;
  2408. // gb_printf_err(">>>count pred: %f succ: %f\n", pred_count/count, succ_count/count);
  2409. // gb_printf_err(">>>capacity pred: %f succ: %f\n", pred_capacity/count, succ_capacity/count);
  2410. // gb_printf_err(">>>max pred: %f succ: %f\n", pred_max, succ_max);
  2411. return G;
  2412. }
  2413. gb_internal void check_single_global_entity(Checker *c, Entity *e, DeclInfo *d);
  2414. gb_internal Entity *find_core_entity(Checker *c, String name) {
  2415. Entity *e = scope_lookup_current(c->info.runtime_package->scope, name);
  2416. if (e == nullptr) {
  2417. compiler_error("Could not find type declaration for '%.*s'\n"
  2418. , LIT(name));
  2419. // NOTE(bill): This will exit the program as it's cannot continue without it!
  2420. }
  2421. return e;
  2422. }
  2423. gb_internal Type *find_core_type(Checker *c, String name) {
  2424. Entity *e = scope_lookup_current(c->info.runtime_package->scope, name);
  2425. if (e == nullptr) {
  2426. compiler_error("Could not find type declaration for '%.*s'\n"
  2427. , LIT(name));
  2428. // NOTE(bill): This will exit the program as it's cannot continue without it!
  2429. }
  2430. if (e->type == nullptr) {
  2431. check_single_global_entity(c, e, e->decl_info);
  2432. }
  2433. GB_ASSERT(e->type != nullptr);
  2434. return e->type;
  2435. }
  2436. gb_internal Entity *find_entity_in_pkg(CheckerInfo *info, String const &pkg, String const &name) {
  2437. AstPackage *package = get_core_package(info, pkg);
  2438. Entity *e = scope_lookup_current(package->scope, name);
  2439. if (e == nullptr) {
  2440. compiler_error("Could not find type declaration for '%.*s.%.*s'\n", LIT(pkg), LIT(name));
  2441. // NOTE(bill): This will exit the program as it's cannot continue without it!
  2442. }
  2443. return e;
  2444. }
  2445. gb_internal Type *find_type_in_pkg(CheckerInfo *info, String const &pkg, String const &name) {
  2446. AstPackage *package = get_core_package(info, pkg);
  2447. Entity *e = scope_lookup_current(package->scope, name);
  2448. if (e == nullptr) {
  2449. compiler_error("Could not find type declaration for '%.*s.%.*s'\n", LIT(pkg), LIT(name));
  2450. // NOTE(bill): This will exit the program as it's cannot continue without it!
  2451. }
  2452. GB_ASSERT(e->type != nullptr);
  2453. return e->type;
  2454. }
  2455. gb_internal CheckerTypePath *new_checker_type_path() {
  2456. gbAllocator a = heap_allocator();
  2457. auto *tp = gb_alloc_item(a, CheckerTypePath);
  2458. array_init(tp, a, 0, 16);
  2459. return tp;
  2460. }
  2461. gb_internal void destroy_checker_type_path(CheckerTypePath *tp) {
  2462. array_free(tp);
  2463. gb_free(heap_allocator(), tp);
  2464. }
  2465. gb_internal void check_type_path_push(CheckerContext *c, Entity *e) {
  2466. GB_ASSERT(c->type_path != nullptr);
  2467. GB_ASSERT(e != nullptr);
  2468. array_add(c->type_path, e);
  2469. }
  2470. gb_internal Entity *check_type_path_pop(CheckerContext *c) {
  2471. GB_ASSERT(c->type_path != nullptr);
  2472. return array_pop(c->type_path);
  2473. }
  2474. gb_internal Array<Entity *> proc_group_entities(CheckerContext *c, Operand o) {
  2475. Array<Entity *> procs = {};
  2476. if (o.mode == Addressing_ProcGroup) {
  2477. GB_ASSERT(o.proc_group != nullptr);
  2478. if (o.proc_group->kind == Entity_ProcGroup) {
  2479. check_entity_decl(c, o.proc_group, nullptr, nullptr);
  2480. return o.proc_group->ProcGroup.entities;
  2481. }
  2482. }
  2483. return procs;
  2484. }
  2485. gb_internal Array<Entity *> proc_group_entities_cloned(CheckerContext *c, Operand o) {
  2486. auto entities = proc_group_entities(c, o);
  2487. if (entities.count == 0) {
  2488. return {};
  2489. }
  2490. return array_clone(permanent_allocator(), entities);
  2491. }
  2492. gb_internal void init_core_type_info(Checker *c) {
  2493. if (t_type_info != nullptr) {
  2494. return;
  2495. }
  2496. Entity *type_info_entity = find_core_entity(c, str_lit("Type_Info"));
  2497. GB_ASSERT(type_info_entity != nullptr);
  2498. GB_ASSERT(type_info_entity->type != nullptr);
  2499. t_type_info = type_info_entity->type;
  2500. t_type_info_ptr = alloc_type_pointer(t_type_info);
  2501. GB_ASSERT(is_type_struct(type_info_entity->type));
  2502. TypeStruct *tis = &base_type(type_info_entity->type)->Struct;
  2503. Entity *type_info_enum_value = find_core_entity(c, str_lit("Type_Info_Enum_Value"));
  2504. t_type_info_enum_value = type_info_enum_value->type;
  2505. t_type_info_enum_value_ptr = alloc_type_pointer(t_type_info_enum_value);
  2506. GB_ASSERT(tis->fields.count == 5);
  2507. Entity *type_info_variant = tis->fields[4];
  2508. Type *tiv_type = type_info_variant->type;
  2509. GB_ASSERT(is_type_union(tiv_type));
  2510. t_type_info_named = find_core_type(c, str_lit("Type_Info_Named"));
  2511. t_type_info_integer = find_core_type(c, str_lit("Type_Info_Integer"));
  2512. t_type_info_rune = find_core_type(c, str_lit("Type_Info_Rune"));
  2513. t_type_info_float = find_core_type(c, str_lit("Type_Info_Float"));
  2514. t_type_info_quaternion = find_core_type(c, str_lit("Type_Info_Quaternion"));
  2515. t_type_info_complex = find_core_type(c, str_lit("Type_Info_Complex"));
  2516. t_type_info_string = find_core_type(c, str_lit("Type_Info_String"));
  2517. t_type_info_boolean = find_core_type(c, str_lit("Type_Info_Boolean"));
  2518. t_type_info_any = find_core_type(c, str_lit("Type_Info_Any"));
  2519. t_type_info_typeid = find_core_type(c, str_lit("Type_Info_Type_Id"));
  2520. t_type_info_pointer = find_core_type(c, str_lit("Type_Info_Pointer"));
  2521. t_type_info_multi_pointer = find_core_type(c, str_lit("Type_Info_Multi_Pointer"));
  2522. t_type_info_procedure = find_core_type(c, str_lit("Type_Info_Procedure"));
  2523. t_type_info_array = find_core_type(c, str_lit("Type_Info_Array"));
  2524. t_type_info_enumerated_array = find_core_type(c, str_lit("Type_Info_Enumerated_Array"));
  2525. t_type_info_dynamic_array = find_core_type(c, str_lit("Type_Info_Dynamic_Array"));
  2526. t_type_info_slice = find_core_type(c, str_lit("Type_Info_Slice"));
  2527. t_type_info_parameters = find_core_type(c, str_lit("Type_Info_Parameters"));
  2528. t_type_info_struct = find_core_type(c, str_lit("Type_Info_Struct"));
  2529. t_type_info_union = find_core_type(c, str_lit("Type_Info_Union"));
  2530. t_type_info_enum = find_core_type(c, str_lit("Type_Info_Enum"));
  2531. t_type_info_map = find_core_type(c, str_lit("Type_Info_Map"));
  2532. t_type_info_bit_set = find_core_type(c, str_lit("Type_Info_Bit_Set"));
  2533. t_type_info_simd_vector = find_core_type(c, str_lit("Type_Info_Simd_Vector"));
  2534. t_type_info_relative_pointer = find_core_type(c, str_lit("Type_Info_Relative_Pointer"));
  2535. t_type_info_relative_multi_pointer = find_core_type(c, str_lit("Type_Info_Relative_Multi_Pointer"));
  2536. t_type_info_matrix = find_core_type(c, str_lit("Type_Info_Matrix"));
  2537. t_type_info_soa_pointer = find_core_type(c, str_lit("Type_Info_Soa_Pointer"));
  2538. t_type_info_bit_field = find_core_type(c, str_lit("Type_Info_Bit_Field"));
  2539. t_type_info_named_ptr = alloc_type_pointer(t_type_info_named);
  2540. t_type_info_integer_ptr = alloc_type_pointer(t_type_info_integer);
  2541. t_type_info_rune_ptr = alloc_type_pointer(t_type_info_rune);
  2542. t_type_info_float_ptr = alloc_type_pointer(t_type_info_float);
  2543. t_type_info_quaternion_ptr = alloc_type_pointer(t_type_info_quaternion);
  2544. t_type_info_complex_ptr = alloc_type_pointer(t_type_info_complex);
  2545. t_type_info_string_ptr = alloc_type_pointer(t_type_info_string);
  2546. t_type_info_boolean_ptr = alloc_type_pointer(t_type_info_boolean);
  2547. t_type_info_any_ptr = alloc_type_pointer(t_type_info_any);
  2548. t_type_info_typeid_ptr = alloc_type_pointer(t_type_info_typeid);
  2549. t_type_info_pointer_ptr = alloc_type_pointer(t_type_info_pointer);
  2550. t_type_info_multi_pointer_ptr = alloc_type_pointer(t_type_info_multi_pointer);
  2551. t_type_info_procedure_ptr = alloc_type_pointer(t_type_info_procedure);
  2552. t_type_info_array_ptr = alloc_type_pointer(t_type_info_array);
  2553. t_type_info_enumerated_array_ptr = alloc_type_pointer(t_type_info_enumerated_array);
  2554. t_type_info_dynamic_array_ptr = alloc_type_pointer(t_type_info_dynamic_array);
  2555. t_type_info_slice_ptr = alloc_type_pointer(t_type_info_slice);
  2556. t_type_info_parameters_ptr = alloc_type_pointer(t_type_info_parameters);
  2557. t_type_info_struct_ptr = alloc_type_pointer(t_type_info_struct);
  2558. t_type_info_union_ptr = alloc_type_pointer(t_type_info_union);
  2559. t_type_info_enum_ptr = alloc_type_pointer(t_type_info_enum);
  2560. t_type_info_map_ptr = alloc_type_pointer(t_type_info_map);
  2561. t_type_info_bit_set_ptr = alloc_type_pointer(t_type_info_bit_set);
  2562. t_type_info_simd_vector_ptr = alloc_type_pointer(t_type_info_simd_vector);
  2563. t_type_info_relative_pointer_ptr = alloc_type_pointer(t_type_info_relative_pointer);
  2564. t_type_info_relative_multi_pointer_ptr = alloc_type_pointer(t_type_info_relative_multi_pointer);
  2565. t_type_info_matrix_ptr = alloc_type_pointer(t_type_info_matrix);
  2566. t_type_info_soa_pointer_ptr = alloc_type_pointer(t_type_info_soa_pointer);
  2567. t_type_info_bit_field_ptr = alloc_type_pointer(t_type_info_bit_field);
  2568. }
  2569. gb_internal void init_mem_allocator(Checker *c) {
  2570. if (t_allocator != nullptr) {
  2571. return;
  2572. }
  2573. t_allocator = find_core_type(c, str_lit("Allocator"));
  2574. t_allocator_ptr = alloc_type_pointer(t_allocator);
  2575. t_allocator_error = find_core_type(c, str_lit("Allocator_Error"));
  2576. }
  2577. gb_internal void init_core_context(Checker *c) {
  2578. if (t_context != nullptr) {
  2579. return;
  2580. }
  2581. t_context = find_core_type(c, str_lit("Context"));
  2582. t_context_ptr = alloc_type_pointer(t_context);
  2583. }
  2584. gb_internal void init_core_source_code_location(Checker *c) {
  2585. if (t_source_code_location != nullptr) {
  2586. return;
  2587. }
  2588. t_source_code_location = find_core_type(c, str_lit("Source_Code_Location"));
  2589. t_source_code_location_ptr = alloc_type_pointer(t_source_code_location);
  2590. }
  2591. gb_internal void init_core_load_directory_file(Checker *c) {
  2592. if (t_load_directory_file != nullptr) {
  2593. return;
  2594. }
  2595. t_load_directory_file = find_core_type(c, str_lit("Load_Directory_File"));
  2596. t_load_directory_file_ptr = alloc_type_pointer(t_load_directory_file);
  2597. t_load_directory_file_slice = alloc_type_slice(t_load_directory_file);
  2598. }
  2599. gb_internal void init_core_map_type(Checker *c) {
  2600. if (t_map_info != nullptr) {
  2601. return;
  2602. }
  2603. init_mem_allocator(c);
  2604. t_map_info = find_core_type(c, str_lit("Map_Info"));
  2605. t_map_cell_info = find_core_type(c, str_lit("Map_Cell_Info"));
  2606. t_raw_map = find_core_type(c, str_lit("Raw_Map"));
  2607. t_map_info_ptr = alloc_type_pointer(t_map_info);
  2608. t_map_cell_info_ptr = alloc_type_pointer(t_map_cell_info);
  2609. t_raw_map_ptr = alloc_type_pointer(t_raw_map);
  2610. }
  2611. gb_internal void init_preload(Checker *c) {
  2612. init_core_type_info(c);
  2613. init_mem_allocator(c);
  2614. init_core_context(c);
  2615. init_core_source_code_location(c);
  2616. init_core_map_type(c);
  2617. }
  2618. gb_internal ExactValue check_decl_attribute_value(CheckerContext *c, Ast *value) {
  2619. ExactValue ev = {};
  2620. if (value != nullptr) {
  2621. Operand op = {};
  2622. check_expr(c, &op, value);
  2623. if (op.mode) {
  2624. if (op.mode == Addressing_Constant) {
  2625. ev = op.value;
  2626. } else {
  2627. error(value, "Expected a constant attribute element");
  2628. }
  2629. }
  2630. }
  2631. return ev;
  2632. }
  2633. #define ATTRIBUTE_USER_TAG_NAME "tag"
  2634. gb_internal DECL_ATTRIBUTE_PROC(foreign_block_decl_attribute) {
  2635. ExactValue ev = check_decl_attribute_value(c, value);
  2636. if (name == ATTRIBUTE_USER_TAG_NAME) {
  2637. if (ev.kind != ExactValue_String) {
  2638. error(elem, "Expected a string value for '%.*s'", LIT(name));
  2639. }
  2640. return true;
  2641. } else if (name == "default_calling_convention") {
  2642. if (ev.kind == ExactValue_String) {
  2643. auto cc = string_to_calling_convention(ev.value_string);
  2644. if (cc == ProcCC_Invalid) {
  2645. error(elem, "Unknown procedure calling convention: '%.*s'", LIT(ev.value_string));
  2646. } else {
  2647. c->foreign_context.default_cc = cc;
  2648. }
  2649. } else {
  2650. error(elem, "Expected a string value for '%.*s'", LIT(name));
  2651. }
  2652. return true;
  2653. } else if (name == "link_prefix") {
  2654. if (ev.kind == ExactValue_String) {
  2655. String link_prefix = ev.value_string;
  2656. if (!is_foreign_name_valid(link_prefix)) {
  2657. error(elem, "Invalid link prefix: '%.*s'", LIT(link_prefix));
  2658. } else {
  2659. c->foreign_context.link_prefix = link_prefix;
  2660. }
  2661. } else {
  2662. error(elem, "Expected a string value for '%.*s'", LIT(name));
  2663. }
  2664. return true;
  2665. } else if (name == "link_suffix") {
  2666. if (ev.kind == ExactValue_String) {
  2667. String link_suffix = ev.value_string;
  2668. if (!is_foreign_name_valid(link_suffix)) {
  2669. error(elem, "Invalid link suffix: '%.*s'", LIT(link_suffix));
  2670. } else {
  2671. c->foreign_context.link_suffix = link_suffix;
  2672. }
  2673. } else {
  2674. error(elem, "Expected a string value for '%.*s'", LIT(name));
  2675. }
  2676. return true;
  2677. } else if (name == "private") {
  2678. EntityVisiblityKind kind = EntityVisiblity_PrivateToPackage;
  2679. if (ev.kind == ExactValue_Invalid) {
  2680. // Okay
  2681. } else if (ev.kind == ExactValue_String) {
  2682. String v = ev.value_string;
  2683. if (v == "file") {
  2684. kind = EntityVisiblity_PrivateToFile;
  2685. } else if (v == "package") {
  2686. kind = EntityVisiblity_PrivateToPackage;
  2687. } else {
  2688. error(value, "'%.*s' expects no parameter, or a string literal containing \"file\" or \"package\"", LIT(name));
  2689. }
  2690. } else {
  2691. error(value, "'%.*s' expects no parameter, or a string literal containing \"file\" or \"package\"", LIT(name));
  2692. }
  2693. c->foreign_context.visibility_kind = kind;
  2694. return true;
  2695. }
  2696. return false;
  2697. }
  2698. gb_internal DECL_ATTRIBUTE_PROC(proc_group_attribute) {
  2699. if (name == ATTRIBUTE_USER_TAG_NAME) {
  2700. ExactValue ev = check_decl_attribute_value(c, value);
  2701. if (ev.kind != ExactValue_String) {
  2702. error(elem, "Expected a string value for '%.*s'", LIT(name));
  2703. }
  2704. return true;
  2705. } else if (name == "objc_name") {
  2706. ExactValue ev = check_decl_attribute_value(c, value);
  2707. if (ev.kind == ExactValue_String) {
  2708. if (string_is_valid_identifier(ev.value_string)) {
  2709. ac->objc_name = ev.value_string;
  2710. } else {
  2711. error(elem, "Invalid identifier for '%.*s', got '%.*s'", LIT(name), LIT(ev.value_string));
  2712. }
  2713. } else {
  2714. error(elem, "Expected a string value for '%.*s'", LIT(name));
  2715. }
  2716. return true;
  2717. } else if (name == "objc_is_class_method") {
  2718. ExactValue ev = check_decl_attribute_value(c, value);
  2719. if (ev.kind == ExactValue_Bool) {
  2720. ac->objc_is_class_method = ev.value_bool;
  2721. } else {
  2722. error(elem, "Expected a boolean value for '%.*s'", LIT(name));
  2723. }
  2724. return true;
  2725. } else if (name == "objc_type") {
  2726. if (value == nullptr) {
  2727. error(elem, "Expected a type for '%.*s'", LIT(name));
  2728. } else {
  2729. Type *objc_type = check_type(c, value);
  2730. if (objc_type != nullptr) {
  2731. if (!has_type_got_objc_class_attribute(objc_type)) {
  2732. gbString t = type_to_string(objc_type);
  2733. error(value, "'%.*s' expected a named type with the attribute @(obj_class=<string>), got type %s", LIT(name), t);
  2734. gb_string_free(t);
  2735. } else {
  2736. ac->objc_type = objc_type;
  2737. }
  2738. }
  2739. }
  2740. return true;
  2741. } else if (name == "require_results") {
  2742. if (value != nullptr) {
  2743. error(elem, "Expected no value for '%.*s'", LIT(name));
  2744. }
  2745. ac->require_results = true;
  2746. return true;
  2747. }
  2748. return false;
  2749. }
  2750. gb_internal DECL_ATTRIBUTE_PROC(proc_decl_attribute) {
  2751. if (name == ATTRIBUTE_USER_TAG_NAME) {
  2752. ExactValue ev = check_decl_attribute_value(c, value);
  2753. if (ev.kind != ExactValue_String) {
  2754. error(elem, "Expected a string value for '%.*s'", LIT(name));
  2755. }
  2756. return true;
  2757. } else if (name == "test") {
  2758. if (value != nullptr) {
  2759. error(value, "'%.*s' expects no parameter, or a string literal containing \"file\" or \"package\"", LIT(name));
  2760. }
  2761. ac->test = true;
  2762. return true;
  2763. } else if (name == "export") {
  2764. ExactValue ev = check_decl_attribute_value(c, value);
  2765. if (ev.kind == ExactValue_Invalid) {
  2766. ac->is_export = true;
  2767. } else if (ev.kind == ExactValue_Bool) {
  2768. ac->is_export = ev.value_bool;
  2769. } else {
  2770. error(value, "Expected either a boolean or no parameter for 'export'");
  2771. return false;
  2772. }
  2773. return true;
  2774. } else if (name == "linkage") {
  2775. ExactValue ev = check_decl_attribute_value(c, value);
  2776. if (ev.kind != ExactValue_String) {
  2777. error(value, "Expected either a string 'linkage'");
  2778. return false;
  2779. }
  2780. String linkage = ev.value_string;
  2781. if (linkage == "internal" ||
  2782. linkage == "strong" ||
  2783. linkage == "weak" ||
  2784. linkage == "link_once") {
  2785. ac->linkage = linkage;
  2786. } else {
  2787. ERROR_BLOCK();
  2788. error(elem, "Invalid linkage '%.*s'. Valid kinds:", LIT(linkage));
  2789. error_line("\tinternal\n");
  2790. error_line("\tstrong\n");
  2791. error_line("\tweak\n");
  2792. error_line("\tlink_once\n");
  2793. }
  2794. return true;
  2795. } else if (name == "require") {
  2796. ExactValue ev = check_decl_attribute_value(c, value);
  2797. if (ev.kind == ExactValue_Invalid) {
  2798. ac->require_declaration = true;
  2799. } else if (ev.kind == ExactValue_Bool) {
  2800. ac->require_declaration = ev.value_bool;
  2801. } else {
  2802. error(value, "Expected either a boolean or no parameter for 'require'");
  2803. }
  2804. return true;
  2805. } else if (name == "init") {
  2806. if (value != nullptr) {
  2807. error(value, "'%.*s' expects no parameter, or a string literal containing \"file\" or \"package\"", LIT(name));
  2808. }
  2809. ac->init = true;
  2810. return true;
  2811. } else if (name == "fini") {
  2812. if (value != nullptr) {
  2813. error(value, "'%.*s' expects no parameter, or a string literal containing \"file\" or \"package\"", LIT(name));
  2814. }
  2815. ac->fini = true;
  2816. return true;
  2817. } else if (name == "deferred") {
  2818. if (value != nullptr) {
  2819. Operand o = {};
  2820. check_expr(c, &o, value);
  2821. Entity *e = entity_of_node(o.expr);
  2822. if (e != nullptr && e->kind == Entity_Procedure) {
  2823. error(elem, "'%.*s' is not allowed any more, please use one of the following instead: 'deferred_none', 'deferred_in', 'deferred_out'", LIT(name));
  2824. if (ac->deferred_procedure.entity != nullptr) {
  2825. error(elem, "Previous usage of a 'deferred_*' attribute");
  2826. }
  2827. ac->deferred_procedure.kind = DeferredProcedure_out;
  2828. ac->deferred_procedure.entity = e;
  2829. return true;
  2830. }
  2831. }
  2832. error(elem, "Expected a procedure entity for '%.*s'", LIT(name));
  2833. return false;
  2834. } else if (name == "deferred_none") {
  2835. if (value != nullptr) {
  2836. Operand o = {};
  2837. check_expr(c, &o, value);
  2838. Entity *e = entity_of_node(o.expr);
  2839. if (e != nullptr && e->kind == Entity_Procedure) {
  2840. ac->deferred_procedure.kind = DeferredProcedure_none;
  2841. ac->deferred_procedure.entity = e;
  2842. return true;
  2843. }
  2844. }
  2845. error(elem, "Expected a procedure entity for '%.*s'", LIT(name));
  2846. return false;
  2847. } else if (name == "deferred_in") {
  2848. if (value != nullptr) {
  2849. Operand o = {};
  2850. check_expr(c, &o, value);
  2851. Entity *e = entity_of_node(o.expr);
  2852. if (e != nullptr && e->kind == Entity_Procedure) {
  2853. if (ac->deferred_procedure.entity != nullptr) {
  2854. error(elem, "Previous usage of a 'deferred_*' attribute");
  2855. }
  2856. ac->deferred_procedure.kind = DeferredProcedure_in;
  2857. ac->deferred_procedure.entity = e;
  2858. return true;
  2859. }
  2860. }
  2861. error(elem, "Expected a procedure entity for '%.*s'", LIT(name));
  2862. return false;
  2863. } else if (name == "deferred_out") {
  2864. if (value != nullptr) {
  2865. Operand o = {};
  2866. check_expr(c, &o, value);
  2867. Entity *e = entity_of_node(o.expr);
  2868. if (e != nullptr && e->kind == Entity_Procedure) {
  2869. if (ac->deferred_procedure.entity != nullptr) {
  2870. error(elem, "Previous usage of a 'deferred_*' attribute");
  2871. }
  2872. ac->deferred_procedure.kind = DeferredProcedure_out;
  2873. ac->deferred_procedure.entity = e;
  2874. return true;
  2875. }
  2876. }
  2877. error(elem, "Expected a procedure entity for '%.*s'", LIT(name));
  2878. return false;
  2879. } else if (name == "deferred_in_out") {
  2880. if (value != nullptr) {
  2881. Operand o = {};
  2882. check_expr(c, &o, value);
  2883. Entity *e = entity_of_node(o.expr);
  2884. if (e != nullptr && e->kind == Entity_Procedure) {
  2885. if (ac->deferred_procedure.entity != nullptr) {
  2886. error(elem, "Previous usage of a 'deferred_*' attribute");
  2887. }
  2888. ac->deferred_procedure.kind = DeferredProcedure_in_out;
  2889. ac->deferred_procedure.entity = e;
  2890. return true;
  2891. }
  2892. }
  2893. error(elem, "Expected a procedure entity for '%.*s'", LIT(name));
  2894. return false;
  2895. } else if (name == "deferred_in_by_ptr") {
  2896. if (value != nullptr) {
  2897. Operand o = {};
  2898. check_expr(c, &o, value);
  2899. Entity *e = entity_of_node(o.expr);
  2900. if (e != nullptr && e->kind == Entity_Procedure) {
  2901. if (ac->deferred_procedure.entity != nullptr) {
  2902. error(elem, "Previous usage of a 'deferred_*' attribute");
  2903. }
  2904. ac->deferred_procedure.kind = DeferredProcedure_in_by_ptr;
  2905. ac->deferred_procedure.entity = e;
  2906. return true;
  2907. }
  2908. }
  2909. error(elem, "Expected a procedure entity for '%.*s'", LIT(name));
  2910. return false;
  2911. } else if (name == "deferred_out_by_ptr") {
  2912. if (value != nullptr) {
  2913. Operand o = {};
  2914. check_expr(c, &o, value);
  2915. Entity *e = entity_of_node(o.expr);
  2916. if (e != nullptr && e->kind == Entity_Procedure) {
  2917. if (ac->deferred_procedure.entity != nullptr) {
  2918. error(elem, "Previous usage of a 'deferred_*' attribute");
  2919. }
  2920. ac->deferred_procedure.kind = DeferredProcedure_out_by_ptr;
  2921. ac->deferred_procedure.entity = e;
  2922. return true;
  2923. }
  2924. }
  2925. error(elem, "Expected a procedure entity for '%.*s'", LIT(name));
  2926. return false;
  2927. } else if (name == "deferred_in_out_by_ptr") {
  2928. if (value != nullptr) {
  2929. Operand o = {};
  2930. check_expr(c, &o, value);
  2931. Entity *e = entity_of_node(o.expr);
  2932. if (e != nullptr && e->kind == Entity_Procedure) {
  2933. if (ac->deferred_procedure.entity != nullptr) {
  2934. error(elem, "Previous usage of a 'deferred_*' attribute");
  2935. }
  2936. ac->deferred_procedure.kind = DeferredProcedure_in_out_by_ptr;
  2937. ac->deferred_procedure.entity = e;
  2938. return true;
  2939. }
  2940. }
  2941. error(elem, "Expected a procedure entity for '%.*s'", LIT(name));
  2942. return false;
  2943. } else if (name == "link_name") {
  2944. ExactValue ev = check_decl_attribute_value(c, value);
  2945. if (ev.kind == ExactValue_String) {
  2946. ac->link_name = ev.value_string;
  2947. if (!is_foreign_name_valid(ac->link_name)) {
  2948. error(elem, "Invalid link name: %.*s", LIT(ac->link_name));
  2949. }
  2950. } else {
  2951. error(elem, "Expected a string value for '%.*s'", LIT(name));
  2952. }
  2953. return true;
  2954. } else if (name == "link_prefix") {
  2955. ExactValue ev = check_decl_attribute_value(c, value);
  2956. if (ev.kind == ExactValue_String) {
  2957. ac->link_prefix = ev.value_string;
  2958. if (!is_foreign_name_valid(ac->link_prefix)) {
  2959. error(elem, "Invalid link prefix: %.*s", LIT(ac->link_prefix));
  2960. }
  2961. } else {
  2962. error(elem, "Expected a string value for '%.*s'", LIT(name));
  2963. }
  2964. return true;
  2965. } else if (name == "link_suffix") {
  2966. ExactValue ev = check_decl_attribute_value(c, value);
  2967. if (ev.kind == ExactValue_String) {
  2968. ac->link_suffix = ev.value_string;
  2969. if (!is_foreign_name_valid(ac->link_suffix)) {
  2970. error(elem, "Invalid link suffix: %.*s", LIT(ac->link_suffix));
  2971. }
  2972. } else {
  2973. error(elem, "Expected a string value for '%.*s'", LIT(name));
  2974. }
  2975. return true;
  2976. } else if (name == "deprecated") {
  2977. ExactValue ev = check_decl_attribute_value(c, value);
  2978. if (ev.kind == ExactValue_String) {
  2979. String msg = ev.value_string;
  2980. if (msg.len == 0) {
  2981. error(elem, "Deprecation message cannot be an empty string");
  2982. } else {
  2983. ac->deprecated_message = msg;
  2984. }
  2985. } else {
  2986. error(elem, "Expected a string value for '%.*s'", LIT(name));
  2987. }
  2988. return true;
  2989. } else if (name == "warning") {
  2990. ExactValue ev = check_decl_attribute_value(c, value);
  2991. if (ev.kind == ExactValue_String) {
  2992. String msg = ev.value_string;
  2993. if (msg.len == 0) {
  2994. error(elem, "Warning message cannot be an empty string");
  2995. } else {
  2996. ac->warning_message = msg;
  2997. }
  2998. } else {
  2999. error(elem, "Expected a string value for '%.*s'", LIT(name));
  3000. }
  3001. return true;
  3002. } else if (name == "require_results") {
  3003. if (value != nullptr) {
  3004. error(elem, "Expected no value for '%.*s'", LIT(name));
  3005. }
  3006. ac->require_results = true;
  3007. return true;
  3008. } else if (name == "disabled") {
  3009. ExactValue ev = check_decl_attribute_value(c, value);
  3010. if (ev.kind == ExactValue_Bool) {
  3011. ac->has_disabled_proc = true;
  3012. ac->disabled_proc = ev.value_bool;
  3013. } else {
  3014. error(elem, "Expected a boolean value for '%.*s'", LIT(name));
  3015. }
  3016. return true;
  3017. } else if (name == "cold") {
  3018. if (value == nullptr) {
  3019. ac->set_cold = true;
  3020. } else {
  3021. ExactValue ev = check_decl_attribute_value(c, value);
  3022. if (ev.kind == ExactValue_Bool) {
  3023. ac->set_cold = ev.value_bool;
  3024. } else {
  3025. error(elem, "Expected a boolean value for '%.*s' or no value whatsoever", LIT(name));
  3026. }
  3027. }
  3028. return true;
  3029. } else if (name == "optimization_mode") {
  3030. ExactValue ev = check_decl_attribute_value(c, value);
  3031. if (ev.kind == ExactValue_String) {
  3032. String mode = ev.value_string;
  3033. if (mode == "none") {
  3034. ac->optimization_mode = ProcedureOptimizationMode_None;
  3035. } else if (mode == "minimal") {
  3036. ac->optimization_mode = ProcedureOptimizationMode_Minimal;
  3037. } else if (mode == "size") {
  3038. ac->optimization_mode = ProcedureOptimizationMode_Size;
  3039. } else if (mode == "speed") {
  3040. ac->optimization_mode = ProcedureOptimizationMode_Speed;
  3041. } else {
  3042. ERROR_BLOCK();
  3043. error(elem, "Invalid optimization_mode for '%.*s'. Valid modes:", LIT(name));
  3044. error_line("\tnone\n");
  3045. error_line("\tminimal\n");
  3046. error_line("\tsize\n");
  3047. error_line("\tspeed\n");
  3048. }
  3049. } else {
  3050. error(elem, "Expected a string for '%.*s'", LIT(name));
  3051. }
  3052. return true;
  3053. } else if (name == "objc_name") {
  3054. ExactValue ev = check_decl_attribute_value(c, value);
  3055. if (ev.kind == ExactValue_String) {
  3056. if (string_is_valid_identifier(ev.value_string)) {
  3057. ac->objc_name = ev.value_string;
  3058. } else {
  3059. error(elem, "Invalid identifier for '%.*s', got '%.*s'", LIT(name), LIT(ev.value_string));
  3060. }
  3061. } else {
  3062. error(elem, "Expected a string value for '%.*s'", LIT(name));
  3063. }
  3064. return true;
  3065. } else if (name == "objc_is_class_method") {
  3066. ExactValue ev = check_decl_attribute_value(c, value);
  3067. if (ev.kind == ExactValue_Bool) {
  3068. ac->objc_is_class_method = ev.value_bool;
  3069. } else {
  3070. error(elem, "Expected a boolean value for '%.*s'", LIT(name));
  3071. }
  3072. return true;
  3073. } else if (name == "objc_type") {
  3074. if (value == nullptr) {
  3075. error(elem, "Expected a type for '%.*s'", LIT(name));
  3076. } else {
  3077. Type *objc_type = check_type(c, value);
  3078. if (objc_type != nullptr) {
  3079. if (!has_type_got_objc_class_attribute(objc_type)) {
  3080. gbString t = type_to_string(objc_type);
  3081. error(value, "'%.*s' expected a named type with the attribute @(obj_class=<string>), got type %s", LIT(name), t);
  3082. gb_string_free(t);
  3083. } else {
  3084. ac->objc_type = objc_type;
  3085. }
  3086. }
  3087. }
  3088. return true;
  3089. } else if (name == "require_target_feature") {
  3090. ExactValue ev = check_decl_attribute_value(c, value);
  3091. if (ev.kind == ExactValue_String) {
  3092. ac->require_target_feature = ev.value_string;
  3093. } else {
  3094. error(elem, "Expected a string value for '%.*s'", LIT(name));
  3095. }
  3096. return true;
  3097. } else if (name == "enable_target_feature") {
  3098. ExactValue ev = check_decl_attribute_value(c, value);
  3099. if (ev.kind == ExactValue_String) {
  3100. ac->enable_target_feature = ev.value_string;
  3101. } else {
  3102. error(elem, "Expected a string value for '%.*s'", LIT(name));
  3103. }
  3104. return true;
  3105. } else if (name == "entry_point_only") {
  3106. if (value != nullptr) {
  3107. error(value, "'%.*s' expects no parameter", LIT(name));
  3108. }
  3109. ac->entry_point_only = true;
  3110. return true;
  3111. } else if (name == "no_instrumentation") {
  3112. ExactValue ev = check_decl_attribute_value(c, value);
  3113. if (ev.kind == ExactValue_Invalid) {
  3114. ac->no_instrumentation = Instrumentation_Disabled;
  3115. } else if (ev.kind == ExactValue_Bool) {
  3116. if (ev.value_bool) {
  3117. ac->no_instrumentation = Instrumentation_Disabled;
  3118. } else {
  3119. ac->no_instrumentation = Instrumentation_Enabled;
  3120. }
  3121. } else {
  3122. error(value, "Expected either a boolean or no parameter for '%.*s'", LIT(name));
  3123. return false;
  3124. }
  3125. return true;
  3126. } else if (name == "instrumentation_enter") {
  3127. if (value != nullptr) {
  3128. error(value, "'%.*s' expects no parameter", LIT(name));
  3129. }
  3130. ac->instrumentation_enter = true;
  3131. return true;
  3132. } else if (name == "instrumentation_exit") {
  3133. if (value != nullptr) {
  3134. error(value, "'%.*s' expects no parameter", LIT(name));
  3135. }
  3136. ac->instrumentation_exit = true;
  3137. return true;
  3138. }
  3139. return false;
  3140. }
  3141. gb_internal DECL_ATTRIBUTE_PROC(var_decl_attribute) {
  3142. if (name == ATTRIBUTE_USER_TAG_NAME) {
  3143. ExactValue ev = check_decl_attribute_value(c, value);
  3144. if (ev.kind != ExactValue_String) {
  3145. error(elem, "Expected a string value for '%.*s'", LIT(name));
  3146. }
  3147. return true;
  3148. } else if (name == "static") {
  3149. if (value != nullptr) {
  3150. error(elem, "'static' does not have any parameters");
  3151. }
  3152. ac->is_static = true;
  3153. return true;
  3154. } else if (name == "thread_local") {
  3155. ExactValue ev = check_decl_attribute_value(c, value);
  3156. if (ac->init_expr_list_count > 0) {
  3157. error(elem, "A thread local variable declaration cannot have initialization values");
  3158. } else if (c->foreign_context.curr_library) {
  3159. error(elem, "A foreign block variable cannot be thread local");
  3160. } else if (ac->is_export) {
  3161. error(elem, "An exported variable cannot be thread local");
  3162. } else if (ev.kind == ExactValue_Invalid) {
  3163. ac->thread_local_model = str_lit("default");
  3164. } else if (ev.kind == ExactValue_String) {
  3165. String model = ev.value_string;
  3166. if (model == "default" ||
  3167. model == "localdynamic" ||
  3168. model == "initialexec" ||
  3169. model == "localexec") {
  3170. ac->thread_local_model = model;
  3171. } else {
  3172. ERROR_BLOCK();
  3173. error(elem, "Invalid thread local model '%.*s'. Valid models:", LIT(model));
  3174. error_line("\tdefault\n");
  3175. error_line("\tlocaldynamic\n");
  3176. error_line("\tinitialexec\n");
  3177. error_line("\tlocalexec\n");
  3178. }
  3179. } else {
  3180. error(elem, "Expected either no value or a string for '%.*s'", LIT(name));
  3181. }
  3182. return true;
  3183. }
  3184. if (c->curr_proc_decl != nullptr) {
  3185. error(elem, "Only a variable at file scope can have a '%.*s'", LIT(name));
  3186. return true;
  3187. }
  3188. if (name == "require") {
  3189. if (value != nullptr) {
  3190. error(elem, "'require' does not have any parameters");
  3191. }
  3192. ac->require_declaration = true;
  3193. return true;
  3194. } else if (name == "export") {
  3195. ExactValue ev = check_decl_attribute_value(c, value);
  3196. if (ev.kind == ExactValue_Invalid) {
  3197. ac->is_export = true;
  3198. } else if (ev.kind == ExactValue_Bool) {
  3199. ac->is_export = ev.value_bool;
  3200. } else {
  3201. error(value, "Expected either a boolean or no parameter for 'export'");
  3202. return false;
  3203. }
  3204. if (ac->thread_local_model != "") {
  3205. error(elem, "An exported variable cannot be thread local");
  3206. }
  3207. return true;
  3208. } else if (name == "linkage") {
  3209. ExactValue ev = check_decl_attribute_value(c, value);
  3210. if (ev.kind != ExactValue_String) {
  3211. error(value, "Expected either a string 'linkage'");
  3212. return false;
  3213. }
  3214. String linkage = ev.value_string;
  3215. if (linkage == "internal" ||
  3216. linkage == "strong" ||
  3217. linkage == "weak" ||
  3218. linkage == "link_once") {
  3219. ac->linkage = linkage;
  3220. } else {
  3221. ERROR_BLOCK();
  3222. error(elem, "Invalid linkage '%.*s'. Valid kinds:", LIT(linkage));
  3223. error_line("\tinternal\n");
  3224. error_line("\tstrong\n");
  3225. error_line("\tweak\n");
  3226. error_line("\tlink_once\n");
  3227. }
  3228. return true;
  3229. } else if (name == "link_name") {
  3230. ExactValue ev = check_decl_attribute_value(c, value);
  3231. if (ev.kind == ExactValue_String) {
  3232. ac->link_name = ev.value_string;
  3233. if (!is_foreign_name_valid(ac->link_name)) {
  3234. error(elem, "Invalid link name: %.*s", LIT(ac->link_name));
  3235. }
  3236. } else {
  3237. error(elem, "Expected a string value for '%.*s'", LIT(name));
  3238. }
  3239. return true;
  3240. } else if (name == "link_prefix") {
  3241. ExactValue ev = check_decl_attribute_value(c, value);
  3242. if (ev.kind == ExactValue_String) {
  3243. ac->link_prefix = ev.value_string;
  3244. if (!is_foreign_name_valid(ac->link_prefix)) {
  3245. error(elem, "Invalid link prefix: %.*s", LIT(ac->link_prefix));
  3246. }
  3247. } else {
  3248. error(elem, "Expected a string value for '%.*s'", LIT(name));
  3249. }
  3250. return true;
  3251. } else if (name == "link_suffix") {
  3252. ExactValue ev = check_decl_attribute_value(c, value);
  3253. if (ev.kind == ExactValue_String) {
  3254. ac->link_suffix = ev.value_string;
  3255. if (!is_foreign_name_valid(ac->link_suffix)) {
  3256. error(elem, "Invalid link suffix: %.*s", LIT(ac->link_suffix));
  3257. }
  3258. } else {
  3259. error(elem, "Expected a string value for '%.*s'", LIT(name));
  3260. }
  3261. return true;
  3262. } else if (name == "link_section") {
  3263. ExactValue ev = check_decl_attribute_value(c, value);
  3264. if (ev.kind == ExactValue_String) {
  3265. ac->link_section = ev.value_string;
  3266. if (!is_foreign_name_valid(ac->link_section)) {
  3267. error(elem, "Invalid link section: %.*s", LIT(ac->link_section));
  3268. }
  3269. } else {
  3270. error(elem, "Expected a string value for '%.*s'", LIT(name));
  3271. }
  3272. return true;
  3273. }
  3274. return false;
  3275. }
  3276. gb_internal DECL_ATTRIBUTE_PROC(const_decl_attribute) {
  3277. if (name == ATTRIBUTE_USER_TAG_NAME) {
  3278. ExactValue ev = check_decl_attribute_value(c, value);
  3279. if (ev.kind != ExactValue_String) {
  3280. error(elem, "Expected a string value for '%.*s'", LIT(name));
  3281. }
  3282. return true;
  3283. } else if (name == "private") {
  3284. // NOTE(bill): Handled elsewhere `check_collect_value_decl`
  3285. return true;
  3286. } else if (name == "static" ||
  3287. name == "thread_local" ||
  3288. name == "require" ||
  3289. name == "linkage" ||
  3290. name == "link_name" ||
  3291. name == "link_prefix" ||
  3292. name == "link_suffix" ||
  3293. false) {
  3294. error(elem, "@(%.*s) is not supported for compile time constant value declarations", LIT(name));
  3295. return true;
  3296. }
  3297. return false;
  3298. }
  3299. gb_internal DECL_ATTRIBUTE_PROC(type_decl_attribute) {
  3300. if (name == ATTRIBUTE_USER_TAG_NAME) {
  3301. ExactValue ev = check_decl_attribute_value(c, value);
  3302. if (ev.kind != ExactValue_String) {
  3303. error(elem, "Expected a string value for '%.*s'", LIT(name));
  3304. }
  3305. return true;
  3306. } else if (name == "private") {
  3307. // NOTE(bill): Handled elsewhere `check_collect_value_decl`
  3308. return true;
  3309. } else if (name == "objc_class") {
  3310. ExactValue ev = check_decl_attribute_value(c, value);
  3311. if (ev.kind != ExactValue_String || ev.value_string == "") {
  3312. error(elem, "Expected a non-empty string value for '%.*s'", LIT(name));
  3313. } else {
  3314. ac->objc_class = ev.value_string;
  3315. }
  3316. return true;
  3317. }
  3318. return false;
  3319. }
  3320. #include "check_expr.cpp"
  3321. #include "check_builtin.cpp"
  3322. #include "check_type.cpp"
  3323. #include "check_decl.cpp"
  3324. #include "check_stmt.cpp"
  3325. gb_internal void check_decl_attributes(CheckerContext *c, Array<Ast *> const &attributes, DeclAttributeProc *proc, AttributeContext *ac) {
  3326. if (attributes.count == 0) return;
  3327. String original_link_prefix = {};
  3328. String original_link_suffix = {};
  3329. if (ac) {
  3330. original_link_prefix = ac->link_prefix;
  3331. original_link_suffix = ac->link_suffix;
  3332. }
  3333. StringSet set = {};
  3334. defer (string_set_destroy(&set));
  3335. bool is_runtime = false;
  3336. if (c->scope && c->scope->file && (c->scope->flags & ScopeFlag_File) &&
  3337. c->scope->file->pkg &&
  3338. c->scope->file->pkg->kind == Package_Runtime) {
  3339. is_runtime = true;
  3340. } else if (c->scope && c->scope->parent &&
  3341. (c->scope->flags & ScopeFlag_Proc) &&
  3342. (c->scope->parent->flags & ScopeFlag_File) &&
  3343. c->scope->parent->file->pkg &&
  3344. c->scope->parent->file->pkg->kind == Package_Runtime) {
  3345. is_runtime = true;
  3346. }
  3347. for_array(i, attributes) {
  3348. Ast *attr = attributes[i];
  3349. if (attr->kind != Ast_Attribute) continue;
  3350. for_array(j, attr->Attribute.elems) {
  3351. Ast *elem = attr->Attribute.elems[j];
  3352. String name = {};
  3353. Ast *value = nullptr;
  3354. switch (elem->kind) {
  3355. case_ast_node(i, Ident, elem);
  3356. name = i->token.string;
  3357. case_end;
  3358. case_ast_node(i, Implicit, elem);
  3359. name = i->string;
  3360. case_end;
  3361. case_ast_node(fv, FieldValue, elem);
  3362. if (fv->field->kind == Ast_Ident) {
  3363. name = fv->field->Ident.token.string;
  3364. } else if (fv->field->kind == Ast_Implicit) {
  3365. name = fv->field->Implicit.string;
  3366. } else {
  3367. GB_PANIC("Unknown Field Value name");
  3368. }
  3369. value = fv->value;
  3370. case_end;
  3371. default:
  3372. error(elem, "Invalid attribute element");
  3373. continue;
  3374. }
  3375. if (string_set_update(&set, name)) {
  3376. error(elem, "Previous declaration of '%.*s'", LIT(name));
  3377. continue;
  3378. }
  3379. if (name == "builtin" && is_runtime) {
  3380. continue;
  3381. }
  3382. if (!proc(c, elem, name, value, ac)) {
  3383. if (!build_context.ignore_unknown_attributes) {
  3384. ERROR_BLOCK();
  3385. error(elem, "Unknown attribute element name '%.*s'", LIT(name));
  3386. error_line("\tDid you forget to use build flag '-ignore-unknown-attributes'?\n");
  3387. }
  3388. }
  3389. }
  3390. }
  3391. if (ac) {
  3392. if (ac->link_prefix.text == original_link_prefix.text) {
  3393. if (ac->link_name.len > 0) {
  3394. ac->link_prefix.text = nullptr;
  3395. ac->link_prefix.len = 0;
  3396. }
  3397. }
  3398. if (ac->link_suffix.text == original_link_suffix.text) {
  3399. if (ac->link_name.len > 0) {
  3400. ac->link_suffix.text = nullptr;
  3401. ac->link_suffix.len = 0;
  3402. }
  3403. }
  3404. }
  3405. }
  3406. gb_internal isize get_total_value_count(Slice<Ast *> const &values) {
  3407. isize count = 0;
  3408. for_array(i, values) {
  3409. Type *t = type_of_expr(values[i]);
  3410. if (t == nullptr) {
  3411. count += 1;
  3412. continue;
  3413. }
  3414. t = core_type(t);
  3415. if (t->kind == Type_Tuple) {
  3416. count += t->Tuple.variables.count;
  3417. } else {
  3418. count += 1;
  3419. }
  3420. }
  3421. return count;
  3422. }
  3423. gb_internal bool check_arity_match(CheckerContext *c, AstValueDecl *vd, bool is_global) {
  3424. isize lhs = vd->names.count;
  3425. isize rhs = 0;
  3426. if (is_global) {
  3427. // NOTE(bill): Disallow global variables to be multi-valued for a few reasons
  3428. rhs = vd->values.count;
  3429. } else {
  3430. rhs = get_total_value_count(vd->values);
  3431. }
  3432. if (rhs == 0) {
  3433. if (vd->type == nullptr) {
  3434. error(vd->names[0], "Missing type or initial expression");
  3435. return false;
  3436. }
  3437. } else if (lhs < rhs) {
  3438. if (lhs < vd->values.count) {
  3439. Ast *n = vd->values[lhs];
  3440. gbString str = expr_to_string(n);
  3441. error(n, "Extra initial expression '%s'", str);
  3442. gb_string_free(str);
  3443. } else {
  3444. error(vd->names[0], "Extra initial expression");
  3445. }
  3446. return false;
  3447. } else if (lhs > rhs) {
  3448. if (!is_global && rhs != 1) {
  3449. Ast *n = vd->names[rhs];
  3450. gbString str = expr_to_string(n);
  3451. error(n, "Missing expression for '%s'", str);
  3452. gb_string_free(str);
  3453. return false;
  3454. } else if (is_global) {
  3455. ERROR_BLOCK();
  3456. Ast *n = vd->values[rhs-1];
  3457. error(n, "Expected %td expressions on the right hand side, got %td", lhs, rhs);
  3458. error_line("Note: Global declarations do not allow for multi-valued expressions");
  3459. return false;
  3460. }
  3461. }
  3462. return true;
  3463. }
  3464. gb_internal void check_collect_entities_from_when_stmt(CheckerContext *c, AstWhenStmt *ws) {
  3465. Operand operand = {Addressing_Invalid};
  3466. if (!ws->is_cond_determined) {
  3467. check_expr(c, &operand, ws->cond);
  3468. if (operand.mode != Addressing_Invalid && !is_type_boolean(operand.type)) {
  3469. error(ws->cond, "Non-boolean condition in 'when' statement");
  3470. }
  3471. if (operand.mode != Addressing_Constant) {
  3472. error(ws->cond, "Non-constant condition in 'when' statement");
  3473. }
  3474. ws->is_cond_determined = true;
  3475. ws->determined_cond = operand.value.kind == ExactValue_Bool && operand.value.value_bool;
  3476. }
  3477. if (ws->body == nullptr || ws->body->kind != Ast_BlockStmt) {
  3478. error(ws->cond, "Invalid body for 'when' statement");
  3479. } else {
  3480. if (ws->determined_cond) {
  3481. check_collect_entities(c, ws->body->BlockStmt.stmts);
  3482. } else if (ws->else_stmt) {
  3483. switch (ws->else_stmt->kind) {
  3484. case Ast_BlockStmt:
  3485. check_collect_entities(c, ws->else_stmt->BlockStmt.stmts);
  3486. break;
  3487. case Ast_WhenStmt:
  3488. check_collect_entities_from_when_stmt(c, &ws->else_stmt->WhenStmt);
  3489. break;
  3490. default:
  3491. error(ws->else_stmt, "Invalid 'else' statement in 'when' statement");
  3492. break;
  3493. }
  3494. }
  3495. }
  3496. }
  3497. gb_internal void check_builtin_attributes(CheckerContext *ctx, Entity *e, Array<Ast *> *attributes) {
  3498. switch (e->kind) {
  3499. case Entity_ProcGroup:
  3500. case Entity_Procedure:
  3501. case Entity_TypeName:
  3502. case Entity_Constant:
  3503. // Okay
  3504. break;
  3505. default:
  3506. return;
  3507. }
  3508. if (!((ctx->scope->flags&ScopeFlag_File) && ctx->scope->file->pkg->kind == Package_Runtime)) {
  3509. return;
  3510. }
  3511. for_array(j, *attributes) {
  3512. Ast *attr = (*attributes)[j];
  3513. if (attr->kind != Ast_Attribute) continue;
  3514. for (isize k = 0; k < attr->Attribute.elems.count; k++) {
  3515. Ast *elem = attr->Attribute.elems[k];
  3516. String name = {};
  3517. Ast *value = nullptr;
  3518. switch (elem->kind) {
  3519. case_ast_node(i, Ident, elem);
  3520. name = i->token.string;
  3521. case_end;
  3522. case_ast_node(fv, FieldValue, elem);
  3523. GB_ASSERT(fv->field->kind == Ast_Ident);
  3524. name = fv->field->Ident.token.string;
  3525. value = fv->value;
  3526. case_end;
  3527. default:
  3528. continue;
  3529. }
  3530. if (name == "builtin") {
  3531. mutex_lock(&ctx->info->builtin_mutex);
  3532. add_entity(ctx, builtin_pkg->scope, nullptr, e);
  3533. GB_ASSERT(scope_lookup(builtin_pkg->scope, e->token.string) != nullptr);
  3534. if (value != nullptr) {
  3535. error(value, "'builtin' cannot have a field value");
  3536. }
  3537. // Remove the builtin tag
  3538. // attr->Attribute.elems[k] = attr->Attribute.elems[attr->Attribute.elems.count-1];
  3539. // attr->Attribute.elems.count -= 1;
  3540. // k--;
  3541. mutex_unlock(&ctx->info->builtin_mutex);
  3542. }
  3543. }
  3544. }
  3545. for (isize i = 0; i < attributes->count; i++) {
  3546. Ast *attr = (*attributes)[i];
  3547. if (attr->kind != Ast_Attribute) continue;
  3548. if (attr->Attribute.elems.count == 0) {
  3549. (*attributes)[i] = (*attributes)[attributes->count-1];
  3550. attributes->count--;
  3551. i--;
  3552. }
  3553. }
  3554. }
  3555. gb_internal void check_collect_value_decl(CheckerContext *c, Ast *decl) {
  3556. if (decl->state_flags & StateFlag_BeenHandled) return;
  3557. decl->state_flags |= StateFlag_BeenHandled;
  3558. ast_node(vd, ValueDecl, decl);
  3559. EntityVisiblityKind entity_visibility_kind = c->foreign_context.visibility_kind;
  3560. bool is_test = false;
  3561. bool is_init = false;
  3562. bool is_fini = false;
  3563. for_array(i, vd->attributes) {
  3564. Ast *attr = vd->attributes[i];
  3565. if (attr->kind != Ast_Attribute) continue;
  3566. auto *elems = &attr->Attribute.elems;
  3567. for (isize j = 0; j < elems->count; j++) {
  3568. Ast *elem = (*elems)[j];
  3569. String name = {};
  3570. Ast *value = nullptr;
  3571. switch (elem->kind) {
  3572. case_ast_node(i, Ident, elem);
  3573. name = i->token.string;
  3574. case_end;
  3575. case_ast_node(fv, FieldValue, elem);
  3576. GB_ASSERT(fv->field->kind == Ast_Ident);
  3577. name = fv->field->Ident.token.string;
  3578. value = fv->value;
  3579. case_end;
  3580. default:
  3581. continue;
  3582. }
  3583. if (name == "private") {
  3584. EntityVisiblityKind kind = EntityVisiblity_PrivateToPackage;
  3585. bool success = false;
  3586. if (value != nullptr) {
  3587. if (value->kind == Ast_BasicLit && value->BasicLit.token.kind == Token_String) {
  3588. String v = {};
  3589. if (value->tav.value.kind == ExactValue_String) {
  3590. v = value->tav.value.value_string;
  3591. }
  3592. if (v == "file") {
  3593. kind = EntityVisiblity_PrivateToFile;
  3594. success = true;
  3595. } else if (v == "package") {
  3596. kind = EntityVisiblity_PrivateToPackage;
  3597. success = true;
  3598. }
  3599. }
  3600. } else {
  3601. success = true;
  3602. }
  3603. if (!success) {
  3604. error(value, "'%.*s' expects no parameter, or a string literal containing \"file\" or \"package\"", LIT(name));
  3605. }
  3606. if (entity_visibility_kind >= kind) {
  3607. error(elem, "Previous declaration of '%.*s'", LIT(name));
  3608. } else {
  3609. entity_visibility_kind = kind;
  3610. }
  3611. slice_unordered_remove(elems, j);
  3612. j -= 1;
  3613. } else if (name == "test") {
  3614. is_test = true;
  3615. } else if (name == "init") {
  3616. is_init = true;
  3617. } else if (name == "fini") {
  3618. is_fini = true;
  3619. }
  3620. }
  3621. }
  3622. if (entity_visibility_kind == EntityVisiblity_Public &&
  3623. (c->scope->flags&ScopeFlag_File) &&
  3624. c->scope->file) {
  3625. if (c->scope->file->flags & AstFile_IsPrivateFile) {
  3626. entity_visibility_kind = EntityVisiblity_PrivateToFile;
  3627. } else if (c->scope->file->flags & AstFile_IsPrivatePkg) {
  3628. entity_visibility_kind = EntityVisiblity_PrivateToPackage;
  3629. }
  3630. }
  3631. if (entity_visibility_kind != EntityVisiblity_Public && !(c->scope->flags&ScopeFlag_File)) {
  3632. error(decl, "Attribute 'private' is not allowed on a non file scope entity");
  3633. }
  3634. if (vd->is_mutable) {
  3635. if (!(c->scope->flags&ScopeFlag_File)) {
  3636. // NOTE(bill): local scope -> handle later and in order
  3637. return;
  3638. }
  3639. for_array(i, vd->names) {
  3640. Ast *name = vd->names[i];
  3641. Ast *value = nullptr;
  3642. if (i < vd->values.count) {
  3643. value = vd->values[i];
  3644. }
  3645. if (name->kind != Ast_Ident) {
  3646. error(name, "A declaration's name must be an identifier, got %.*s", LIT(ast_strings[name->kind]));
  3647. continue;
  3648. }
  3649. Entity *e = alloc_entity_variable(c->scope, name->Ident.token, nullptr);
  3650. e->identifier = name;
  3651. e->file = c->file;
  3652. e->Variable.is_global = true;
  3653. if (entity_visibility_kind != EntityVisiblity_Public) {
  3654. e->flags |= EntityFlag_NotExported;
  3655. }
  3656. if (vd->is_using) {
  3657. vd->is_using = false; // NOTE(bill): This error will be only caught once
  3658. error(name, "'using' is not allowed at the file scope");
  3659. }
  3660. Ast *fl = c->foreign_context.curr_library;
  3661. if (fl != nullptr) {
  3662. GB_ASSERT(fl->kind == Ast_Ident);
  3663. e->Variable.is_foreign = true;
  3664. e->Variable.foreign_library_ident = fl;
  3665. e->Variable.link_prefix = c->foreign_context.link_prefix;
  3666. e->Variable.link_suffix = c->foreign_context.link_suffix;
  3667. }
  3668. Ast *init_expr = value;
  3669. DeclInfo *d = make_decl_info(c->scope, c->decl);
  3670. d->decl_node = decl;
  3671. d->comment = vd->comment;
  3672. d->docs = vd->docs;
  3673. d->entity = e;
  3674. d->type_expr = vd->type;
  3675. d->init_expr = init_expr;
  3676. d->attributes = vd->attributes;
  3677. bool is_exported = entity_visibility_kind != EntityVisiblity_PrivateToFile;
  3678. add_entity_and_decl_info(c, name, e, d, is_exported);
  3679. }
  3680. check_arity_match(c, vd, true);
  3681. } else {
  3682. for_array(i, vd->names) {
  3683. Ast *name = vd->names[i];
  3684. if (name->kind != Ast_Ident) {
  3685. error(name, "A declaration's name must be an identifier, got %.*s", LIT(ast_strings[name->kind]));
  3686. continue;
  3687. }
  3688. Ast *init = unparen_expr(vd->values[i]);
  3689. if (init == nullptr) {
  3690. error(name, "Expected a value for this constant value declaration");
  3691. continue;
  3692. }
  3693. Token token = name->Ident.token;
  3694. Ast *fl = c->foreign_context.curr_library;
  3695. Entity *e = nullptr;
  3696. DeclInfo *d = make_decl_info(c->scope, c->decl);
  3697. d->decl_node = decl;
  3698. d->comment = vd->comment;
  3699. d->docs = vd->docs;
  3700. d->attributes = vd->attributes;
  3701. d->type_expr = vd->type;
  3702. d->init_expr = init;
  3703. if (is_ast_type(init)) {
  3704. e = alloc_entity_type_name(d->scope, token, nullptr);
  3705. } else if (init->kind == Ast_ProcLit) {
  3706. if (c->scope->flags&ScopeFlag_Type) {
  3707. error(name, "Procedure declarations are not allowed within a struct");
  3708. continue;
  3709. }
  3710. ast_node(pl, ProcLit, init);
  3711. e = alloc_entity_procedure(d->scope, token, nullptr, pl->tags);
  3712. if (fl != nullptr) {
  3713. GB_ASSERT(fl->kind == Ast_Ident);
  3714. e->Procedure.foreign_library_ident = fl;
  3715. e->Procedure.is_foreign = true;
  3716. GB_ASSERT(pl->type->kind == Ast_ProcType);
  3717. auto cc = pl->type->ProcType.calling_convention;
  3718. if (cc == ProcCC_ForeignBlockDefault) {
  3719. cc = ProcCC_CDecl;
  3720. if (c->foreign_context.default_cc > 0) {
  3721. cc = c->foreign_context.default_cc;
  3722. } else if (is_arch_wasm()) {
  3723. ERROR_BLOCK();
  3724. error(init, "For wasm related targets, it is required that you either define the"
  3725. " @(default_calling_convention=<string>) on the foreign block or"
  3726. " explicitly assign it on the procedure signature");
  3727. error_line("\tSuggestion: when dealing with normal Odin code (e.g. js_wasm32), use \"contextless\"; when dealing with Emscripten like code, use \"c\"\n");
  3728. }
  3729. }
  3730. e->Procedure.link_prefix = c->foreign_context.link_prefix;
  3731. e->Procedure.link_suffix = c->foreign_context.link_suffix;
  3732. GB_ASSERT(cc != ProcCC_Invalid);
  3733. pl->type->ProcType.calling_convention = cc;
  3734. }
  3735. d->proc_lit = init;
  3736. d->init_expr = init;
  3737. if (is_test) {
  3738. e->flags |= EntityFlag_Test;
  3739. }
  3740. if (is_init && is_fini) {
  3741. error(name, "A procedure cannot be both declared as @(init) and @(fini)");
  3742. } else if (is_init) {
  3743. e->flags |= EntityFlag_Init;
  3744. } else if (is_fini) {
  3745. e->flags |= EntityFlag_Fini;
  3746. }
  3747. } else if (init->kind == Ast_ProcGroup) {
  3748. ast_node(pg, ProcGroup, init);
  3749. e = alloc_entity_proc_group(d->scope, token, nullptr);
  3750. if (fl != nullptr) {
  3751. error(name, "Procedure groups are not allowed within a foreign block");
  3752. }
  3753. } else {
  3754. e = alloc_entity_constant(d->scope, token, nullptr, empty_exact_value);
  3755. }
  3756. e->identifier = name;
  3757. if (entity_visibility_kind != EntityVisiblity_Public) {
  3758. e->flags |= EntityFlag_NotExported;
  3759. }
  3760. add_entity_flags_from_file(c, e, c->scope);
  3761. if (vd->is_using) {
  3762. if (e->kind == Entity_TypeName && init->kind == Ast_EnumType) {
  3763. d->is_using = true;
  3764. } else {
  3765. error(name, "'using' is not allowed on this constant value declaration");
  3766. }
  3767. }
  3768. if (e->kind != Entity_Procedure) {
  3769. if (fl != nullptr) {
  3770. ERROR_BLOCK();
  3771. AstKind kind = init->kind;
  3772. error(name, "Only procedures and variables are allowed to be in a foreign block, got %.*s", LIT(ast_strings[kind]));
  3773. if (kind == Ast_ProcType) {
  3774. error_line("\tDid you forget to append '---' to the procedure?\n");
  3775. }
  3776. }
  3777. }
  3778. check_builtin_attributes(c, e, &d->attributes);
  3779. bool is_exported = entity_visibility_kind != EntityVisiblity_PrivateToFile;
  3780. add_entity_and_decl_info(c, name, e, d, is_exported);
  3781. }
  3782. check_arity_match(c, vd, true);
  3783. }
  3784. }
  3785. gb_internal bool collect_file_decls(CheckerContext *ctx, Slice<Ast *> const &decls);
  3786. gb_internal bool check_add_foreign_block_decl(CheckerContext *ctx, Ast *decl) {
  3787. ast_node(fb, ForeignBlockDecl, decl);
  3788. Ast *foreign_library = fb->foreign_library;
  3789. CheckerContext c = *ctx;
  3790. if (foreign_library->kind == Ast_Ident) {
  3791. c.foreign_context.curr_library = foreign_library;
  3792. } else {
  3793. error(foreign_library, "Foreign block name must be an identifier or 'export'");
  3794. c.foreign_context.curr_library = nullptr;
  3795. }
  3796. check_decl_attributes(&c, fb->attributes, foreign_block_decl_attribute, nullptr);
  3797. ast_node(block, BlockStmt, fb->body);
  3798. if (c.collect_delayed_decls && (c.scope->flags&ScopeFlag_File) != 0) {
  3799. return collect_file_decls(&c, block->stmts);
  3800. }
  3801. check_collect_entities(&c, block->stmts);
  3802. return false;
  3803. }
  3804. gb_internal bool correct_single_type_alias(CheckerContext *c, Entity *e) {
  3805. if (e->kind == Entity_Constant) {
  3806. DeclInfo *d = e->decl_info;
  3807. if (d != nullptr && d->init_expr != nullptr) {
  3808. Ast *init = d->init_expr;
  3809. Entity *alias_of = check_entity_from_ident_or_selector(c, init, true);
  3810. if (alias_of != nullptr && alias_of->kind == Entity_TypeName) {
  3811. e->kind = Entity_TypeName;
  3812. return true;
  3813. }
  3814. }
  3815. }
  3816. return false;
  3817. }
  3818. gb_internal bool correct_type_alias_in_scope_backwards(CheckerContext *c, Scope *s) {
  3819. bool correction = false;
  3820. for (u32 n = s->elements.count, i = n-1; i < n; i--) {
  3821. auto const &entry = s->elements.entries[i];
  3822. Entity *e = entry.value;
  3823. if (entry.hash && e != nullptr) {
  3824. correction |= correct_single_type_alias(c, e);
  3825. }
  3826. }
  3827. return correction;
  3828. }
  3829. gb_internal bool correct_type_alias_in_scope_forwards(CheckerContext *c, Scope *s) {
  3830. bool correction = false;
  3831. for (auto const &entry : s->elements) {
  3832. Entity *e = entry.value;
  3833. if (e != nullptr) {
  3834. correction |= correct_single_type_alias(c, entry.value);
  3835. }
  3836. }
  3837. return correction;
  3838. }
  3839. gb_internal void correct_type_aliases_in_scope(CheckerContext *c, Scope *s) {
  3840. // NOTE(bill, 2022-02-04): This is used to solve the problem caused by type aliases
  3841. // of type aliases being "confused" as constants
  3842. //
  3843. // A :: C
  3844. // B :: A
  3845. // C :: struct {b: ^B}
  3846. //
  3847. // See @TypeAliasingProblem for more information
  3848. for (;;) {
  3849. bool corrections = false;
  3850. corrections |= correct_type_alias_in_scope_backwards(c, s);
  3851. corrections |= correct_type_alias_in_scope_forwards(c, s);
  3852. if (!corrections) {
  3853. return;
  3854. }
  3855. }
  3856. }
  3857. // NOTE(bill): If file_scopes == nullptr, this will act like a local scope
  3858. gb_internal void check_collect_entities(CheckerContext *c, Slice<Ast *> const &nodes) {
  3859. AstFile *curr_file = nullptr;
  3860. if ((c->scope->flags&ScopeFlag_File) != 0) {
  3861. curr_file = c->scope->file;
  3862. GB_ASSERT(curr_file != nullptr);
  3863. }
  3864. for_array(decl_index, nodes) {
  3865. Ast *decl = nodes[decl_index];
  3866. if (!is_ast_decl(decl) && !is_ast_when_stmt(decl)) {
  3867. if (curr_file && decl->kind == Ast_ExprStmt) {
  3868. Ast *expr = decl->ExprStmt.expr;
  3869. if (expr->kind == Ast_CallExpr && expr->CallExpr.proc->kind == Ast_BasicDirective) {
  3870. if (c->collect_delayed_decls) {
  3871. if (decl->state_flags & StateFlag_BeenHandled) return;
  3872. decl->state_flags |= StateFlag_BeenHandled;
  3873. array_add(&curr_file->delayed_decls_queues[AstDelayQueue_Expr], expr);
  3874. }
  3875. continue;
  3876. }
  3877. }
  3878. continue;
  3879. }
  3880. switch (decl->kind) {
  3881. case_ast_node(bd, BadDecl, decl);
  3882. case_end;
  3883. case_ast_node(ws, WhenStmt, decl);
  3884. // Will be handled later
  3885. case_end;
  3886. case_ast_node(vd, ValueDecl, decl);
  3887. check_collect_value_decl(c, decl);
  3888. case_end;
  3889. case_ast_node(id, ImportDecl, decl);
  3890. if (curr_file == nullptr) {
  3891. error(decl, "import declarations are only allowed in the file scope");
  3892. // NOTE(bill): _Should_ be caught by the parser
  3893. continue;
  3894. }
  3895. // Will be handled later
  3896. array_add(&curr_file->delayed_decls_queues[AstDelayQueue_Import], decl);
  3897. case_end;
  3898. case_ast_node(fl, ForeignImportDecl, decl);
  3899. if ((c->scope->flags&ScopeFlag_File) == 0) {
  3900. error(decl, "%.*s declarations are only allowed in the file scope", LIT(fl->token.string));
  3901. // NOTE(bill): _Should_ be caught by the parser
  3902. continue;
  3903. }
  3904. check_add_foreign_import_decl(c, decl);
  3905. case_end;
  3906. case_ast_node(fb, ForeignBlockDecl, decl);
  3907. check_add_foreign_block_decl(c, decl);
  3908. case_end;
  3909. default:
  3910. if (c->scope->flags&ScopeFlag_File) {
  3911. error(decl, "Only declarations are allowed at file scope");
  3912. }
  3913. break;
  3914. }
  3915. }
  3916. // correct_type_aliases(c);
  3917. // NOTE(bill): 'when' stmts need to be handled after the other as the condition may refer to something
  3918. // declared after this stmt in source
  3919. if (curr_file == nullptr) {
  3920. for_array(decl_index, nodes) {
  3921. Ast *decl = nodes[decl_index];
  3922. if (decl->kind == Ast_WhenStmt) {
  3923. check_collect_entities_from_when_stmt(c, &decl->WhenStmt);
  3924. }
  3925. }
  3926. }
  3927. }
  3928. gb_internal CheckerContext *create_checker_context(Checker *c) {
  3929. CheckerContext *ctx = gb_alloc_item(permanent_allocator(), CheckerContext);
  3930. *ctx = make_checker_context(c);
  3931. return ctx;
  3932. }
  3933. gb_internal void check_single_global_entity(Checker *c, Entity *e, DeclInfo *d) {
  3934. GB_ASSERT(e != nullptr);
  3935. GB_ASSERT(d != nullptr);
  3936. if (d->scope != e->scope) {
  3937. return;
  3938. }
  3939. if (e->state == EntityState_Resolved) {
  3940. return;
  3941. }
  3942. CheckerContext *ctx = create_checker_context(c);
  3943. GB_ASSERT(d->scope->flags&ScopeFlag_File);
  3944. AstFile *file = d->scope->file;
  3945. add_curr_ast_file(ctx, file);
  3946. AstPackage *pkg = file->pkg;
  3947. GB_ASSERT(ctx->pkg != nullptr);
  3948. GB_ASSERT(e->pkg != nullptr);
  3949. ctx->decl = d;
  3950. ctx->scope = d->scope;
  3951. if (pkg->kind == Package_Init) {
  3952. if (e->kind != Entity_Procedure && e->token.string == "main") {
  3953. error(e->token, "'main' is reserved as the entry point procedure in the initial scope");
  3954. return;
  3955. }
  3956. }
  3957. check_entity_decl(ctx, e, d, nullptr);
  3958. }
  3959. gb_internal void check_all_global_entities(Checker *c) {
  3960. // NOTE(bill): This must be single threaded
  3961. // Don't bother trying
  3962. for_array(i, c->info.entities) {
  3963. Entity *e = c->info.entities[i];
  3964. GB_ASSERT(e != nullptr);
  3965. if (e->flags & EntityFlag_Lazy) {
  3966. continue;
  3967. }
  3968. DeclInfo *d = e->decl_info;
  3969. check_single_global_entity(c, e, d);
  3970. if (e->type != nullptr && is_type_typed(e->type)) {
  3971. for (Type *t = nullptr; mpsc_dequeue(&c->soa_types_to_complete, &t); /**/) {
  3972. complete_soa_type(c, t, false);
  3973. }
  3974. (void)type_size_of(e->type);
  3975. (void)type_align_of(e->type);
  3976. }
  3977. }
  3978. }
  3979. gb_internal bool is_string_an_identifier(String s) {
  3980. isize offset = 0;
  3981. if (s.len < 1) {
  3982. return false;
  3983. }
  3984. while (offset < s.len) {
  3985. bool ok = false;
  3986. Rune r = -1;
  3987. isize size = utf8_decode(s.text+offset, s.len-offset, &r);
  3988. if (offset == 0) {
  3989. ok = rune_is_letter(r);
  3990. } else {
  3991. ok = rune_is_letter(r) || rune_is_digit(r);
  3992. }
  3993. if (!ok) {
  3994. return false;
  3995. }
  3996. offset += size;
  3997. }
  3998. return offset == s.len;
  3999. }
  4000. gb_internal String path_to_entity_name(String name, String fullpath, bool strip_extension=true) {
  4001. if (name.len != 0) {
  4002. return name;
  4003. }
  4004. // NOTE(bill): use file name (without extension) as the identifier
  4005. // If it is a valid identifier
  4006. String filename = fullpath;
  4007. isize slash = 0;
  4008. isize dot = 0;
  4009. for (isize i = filename.len-1; i >= 0; i--) {
  4010. u8 c = filename[i];
  4011. if (c == '/' || c == '\\') {
  4012. break;
  4013. }
  4014. slash = i;
  4015. }
  4016. filename = substring(filename, slash, filename.len);
  4017. if (strip_extension) {
  4018. dot = filename.len;
  4019. while (dot --> 0) {
  4020. u8 c = filename[dot];
  4021. if (c == '.') {
  4022. break;
  4023. }
  4024. }
  4025. if (dot > 0) {
  4026. filename = substring(filename, 0, dot);
  4027. }
  4028. }
  4029. if (is_string_an_identifier(filename)) {
  4030. return filename;
  4031. } else {
  4032. return str_lit("_");
  4033. }
  4034. }
  4035. #if 1
  4036. gb_internal void add_import_dependency_node(Checker *c, Ast *decl, PtrMap<AstPackage *, ImportGraphNode *> *M) {
  4037. AstPackage *parent_pkg = decl->file()->pkg;
  4038. switch (decl->kind) {
  4039. case_ast_node(id, ImportDecl, decl);
  4040. String path = id->fullpath;
  4041. if (is_package_name_reserved(path)) {
  4042. return;
  4043. }
  4044. AstPackage **found = string_map_get(&c->info.packages, path);
  4045. if (found == nullptr) {
  4046. Token token = ast_token(decl);
  4047. error(token, "Unable to find package: %.*s", LIT(path));
  4048. exit_with_errors();
  4049. }
  4050. AstPackage *pkg = *found;
  4051. GB_ASSERT(pkg->scope != nullptr);
  4052. id->package = pkg;
  4053. ImportGraphNode **found_node = nullptr;
  4054. ImportGraphNode *m = nullptr;
  4055. ImportGraphNode *n = nullptr;
  4056. found_node = map_get(M, pkg);
  4057. GB_ASSERT(found_node != nullptr);
  4058. m = *found_node;
  4059. found_node = map_get(M, parent_pkg);
  4060. GB_ASSERT(found_node != nullptr);
  4061. n = *found_node;
  4062. import_graph_node_set_add(&n->succ, m);
  4063. import_graph_node_set_add(&m->pred, n);
  4064. ptr_set_add(&m->scope->imported, n->scope);
  4065. case_end;
  4066. case_ast_node(ws, WhenStmt, decl);
  4067. if (ws->body != nullptr) {
  4068. auto stmts = ws->body->BlockStmt.stmts;
  4069. for_array(i, stmts) {
  4070. add_import_dependency_node(c, stmts[i], M);
  4071. }
  4072. }
  4073. if (ws->else_stmt != nullptr) {
  4074. switch (ws->else_stmt->kind) {
  4075. case Ast_BlockStmt: {
  4076. auto stmts = ws->else_stmt->BlockStmt.stmts;
  4077. for_array(i, stmts) {
  4078. add_import_dependency_node(c, stmts[i], M);
  4079. }
  4080. break;
  4081. }
  4082. case Ast_WhenStmt:
  4083. add_import_dependency_node(c, ws->else_stmt, M);
  4084. break;
  4085. }
  4086. }
  4087. case_end;
  4088. }
  4089. }
  4090. gb_internal Array<ImportGraphNode *> generate_import_dependency_graph(Checker *c) {
  4091. PtrMap<AstPackage *, ImportGraphNode *> M = {};
  4092. map_init(&M, 2*c->parser->packages.count);
  4093. defer (map_destroy(&M));
  4094. for_array(i, c->parser->packages) {
  4095. AstPackage *pkg = c->parser->packages[i];
  4096. ImportGraphNode *n = import_graph_node_create(heap_allocator(), pkg);
  4097. map_set(&M, pkg, n);
  4098. }
  4099. // Calculate edges for graph M
  4100. for_array(i, c->parser->packages) {
  4101. AstPackage *p = c->parser->packages[i];
  4102. for_array(j, p->files) {
  4103. AstFile *f = p->files[j];
  4104. for_array(k, f->decls) {
  4105. Ast *decl = f->decls[k];
  4106. add_import_dependency_node(c, decl, &M);
  4107. }
  4108. }
  4109. }
  4110. Array<ImportGraphNode *> G = {};
  4111. array_init(&G, heap_allocator(), 0, M.count);
  4112. isize i = 0;
  4113. for (auto const &entry : M) {
  4114. auto n = entry.value;
  4115. n->index = i++;
  4116. n->dep_count = n->succ.count;
  4117. GB_ASSERT(n->dep_count >= 0);
  4118. array_add(&G, n);
  4119. }
  4120. return G;
  4121. }
  4122. struct ImportPathItem {
  4123. AstPackage *pkg;
  4124. Ast * decl;
  4125. };
  4126. gb_internal Array<ImportPathItem> find_import_path(Checker *c, AstPackage *start, AstPackage *end, PtrSet<AstPackage *> *visited) {
  4127. Array<ImportPathItem> empty_path = {};
  4128. if (ptr_set_update(visited, start)) {
  4129. return empty_path;
  4130. }
  4131. String path = start->fullpath;
  4132. AstPackage **found = string_map_get(&c->info.packages, path);
  4133. if (found) {
  4134. AstPackage *pkg = *found;
  4135. GB_ASSERT(pkg != nullptr);
  4136. for_array(i, pkg->files) {
  4137. AstFile *f = pkg->files[i];
  4138. for_array(j, f->imports) {
  4139. AstPackage *pkg = nullptr;
  4140. Ast *decl = f->imports[j];
  4141. if (decl->kind == Ast_ImportDecl) {
  4142. pkg = decl->ImportDecl.package;
  4143. } else {
  4144. continue;
  4145. }
  4146. if (pkg == nullptr || pkg->scope == nullptr) {
  4147. continue;
  4148. }
  4149. // if (pkg->kind == Package_Runtime) {
  4150. // // NOTE(bill): Allow cyclic imports within the runtime package for the time being
  4151. // continue;
  4152. // }
  4153. ImportPathItem item = {pkg, decl};
  4154. if (pkg == end) {
  4155. auto path = array_make<ImportPathItem>(heap_allocator());
  4156. array_add(&path, item);
  4157. return path;
  4158. }
  4159. auto next_path = find_import_path(c, pkg, end, visited);
  4160. if (next_path.count > 0) {
  4161. array_add(&next_path, item);
  4162. return next_path;
  4163. }
  4164. }
  4165. }
  4166. }
  4167. return empty_path;
  4168. }
  4169. #endif
  4170. gb_internal String get_invalid_import_name(String input) {
  4171. isize slash = 0;
  4172. for (isize i = input.len-1; i >= 0; i--) {
  4173. if (input[i] == '/' || input[i] == '\\') {
  4174. break;
  4175. }
  4176. slash = i;
  4177. }
  4178. input = substring(input, slash, input.len);
  4179. return input;
  4180. }
  4181. gb_internal DECL_ATTRIBUTE_PROC(import_decl_attribute) {
  4182. if (name == ATTRIBUTE_USER_TAG_NAME) {
  4183. ExactValue ev = check_decl_attribute_value(c, value);
  4184. if (ev.kind != ExactValue_String) {
  4185. error(elem, "Expected a string value for '%.*s'", LIT(name));
  4186. }
  4187. return true;
  4188. } else if (name == "require") {
  4189. if (value != nullptr) {
  4190. error(elem, "Expected no parameter for '%.*s'", LIT(name));
  4191. }
  4192. ac->require_declaration = true;
  4193. return true;
  4194. }
  4195. return false;
  4196. }
  4197. gb_internal void check_add_import_decl(CheckerContext *ctx, Ast *decl) {
  4198. if (decl->state_flags & StateFlag_BeenHandled) return;
  4199. decl->state_flags |= StateFlag_BeenHandled;
  4200. ast_node(id, ImportDecl, decl);
  4201. Token token = id->relpath;
  4202. Scope *parent_scope = ctx->scope;
  4203. GB_ASSERT(parent_scope->flags&ScopeFlag_File);
  4204. auto *pkgs = &ctx->checker->info.packages;
  4205. Scope *scope = nullptr;
  4206. bool force_use = false;
  4207. if (id->fullpath == "builtin") {
  4208. scope = builtin_pkg->scope;
  4209. force_use = true;
  4210. } else if (id->fullpath == "intrinsics") {
  4211. scope = intrinsics_pkg->scope;
  4212. force_use = true;
  4213. } else {
  4214. AstPackage **found = string_map_get(pkgs, id->fullpath);
  4215. if (found == nullptr) {
  4216. for (auto const &entry : *pkgs) {
  4217. AstPackage *pkg = entry.value;
  4218. gb_printf_err("%.*s\n", LIT(pkg->fullpath));
  4219. }
  4220. gb_printf_err("%s\n", token_pos_to_string(token.pos));
  4221. GB_PANIC("Unable to find scope for package: %.*s", LIT(id->fullpath));
  4222. } else {
  4223. AstPackage *pkg = *found;
  4224. scope = pkg->scope;
  4225. }
  4226. }
  4227. GB_ASSERT(scope->flags&ScopeFlag_Pkg);
  4228. if (ptr_set_update(&parent_scope->imported, scope)) {
  4229. // error(token, "Multiple import of the same file within this scope");
  4230. }
  4231. String import_name = path_to_entity_name(id->import_name.string, id->fullpath, false);
  4232. if (is_blank_ident(import_name)) {
  4233. force_use = true;
  4234. }
  4235. AttributeContext ac = {};
  4236. check_decl_attributes(ctx, id->attributes, import_decl_attribute, &ac);
  4237. if (ac.require_declaration) {
  4238. force_use = true;
  4239. }
  4240. if (import_name.len == 0) {
  4241. String invalid_name = id->fullpath;
  4242. invalid_name = get_invalid_import_name(invalid_name);
  4243. error(id->token, "Import name %.*s, is not a valid identifier. Perhaps you want to reference the package by a different name like this: import <new_name> \"%.*s\" ", LIT(invalid_name), LIT(invalid_name));
  4244. error(token, "Import name, %.*s, cannot be use as an import name as it is not a valid identifier", LIT(id->import_name.string));
  4245. } else {
  4246. GB_ASSERT(id->import_name.pos.line != 0);
  4247. id->import_name.string = import_name;
  4248. Entity *e = alloc_entity_import_name(parent_scope, id->import_name, t_invalid,
  4249. id->fullpath, id->import_name.string,
  4250. scope);
  4251. add_entity(ctx, parent_scope, nullptr, e);
  4252. if (force_use) {
  4253. add_entity_use(ctx, nullptr, e);
  4254. }
  4255. }
  4256. scope->flags |= ScopeFlag_HasBeenImported;
  4257. }
  4258. gb_internal DECL_ATTRIBUTE_PROC(foreign_import_decl_attribute) {
  4259. if (name == ATTRIBUTE_USER_TAG_NAME) {
  4260. ExactValue ev = check_decl_attribute_value(c, value);
  4261. if (ev.kind != ExactValue_String) {
  4262. error(elem, "Expected a string value for '%.*s'", LIT(name));
  4263. }
  4264. return true;
  4265. } else if (name == "force" || name == "require") {
  4266. if (value != nullptr) {
  4267. error(elem, "Expected no parameter for '%.*s'", LIT(name));
  4268. } else if (name == "force") {
  4269. error(elem, "'force' was replaced with 'require'");
  4270. }
  4271. ac->require_declaration = true;
  4272. return true;
  4273. } else if (name == "priority_index") {
  4274. ExactValue ev = check_decl_attribute_value(c, value);
  4275. if (ev.kind != ExactValue_Integer) {
  4276. error(elem, "Expected an integer value for '%.*s'", LIT(name));
  4277. } else {
  4278. ac->foreign_import_priority_index = exact_value_to_i64(ev);
  4279. }
  4280. return true;
  4281. } else if (name == "extra_linker_flags") {
  4282. ExactValue ev = check_decl_attribute_value(c, value);
  4283. if (ev.kind != ExactValue_String) {
  4284. error(elem, "Expected a string value for '%.*s'", LIT(name));
  4285. } else {
  4286. ac->extra_linker_flags = ev.value_string;
  4287. }
  4288. return true;
  4289. }
  4290. return false;
  4291. }
  4292. gb_internal void check_foreign_import_fullpaths(Checker *c) {
  4293. CheckerContext ctx = make_checker_context(c);
  4294. UntypedExprInfoMap untyped = {};
  4295. defer (map_destroy(&untyped));
  4296. for (Entity *e = nullptr; mpsc_dequeue(&c->info.foreign_imports_to_check_fullpaths, &e); /**/) {
  4297. GB_ASSERT(e != nullptr);
  4298. GB_ASSERT(e->kind == Entity_LibraryName);
  4299. Ast *decl = e->LibraryName.decl;
  4300. ast_node(fl, ForeignImportDecl, decl);
  4301. AstFile *f = decl->file();
  4302. reset_checker_context(&ctx, f, &untyped);
  4303. ctx.collect_delayed_decls = false;
  4304. GB_ASSERT(ctx.scope == e->scope);
  4305. if (fl->fullpaths.count == 0) {
  4306. String base_dir = dir_from_path(decl->file()->fullpath);
  4307. auto fullpaths = array_make<String>(permanent_allocator(), 0, fl->filepaths.count);
  4308. for (Ast *fp_node : fl->filepaths) {
  4309. Operand op = {};
  4310. check_expr(&ctx, &op, fp_node);
  4311. if (op.mode != Addressing_Constant && op.value.kind != ExactValue_String) {
  4312. gbString s = expr_to_string(op.expr);
  4313. error(fp_node, "Expected a constant string value, got '%s'", s);
  4314. gb_string_free(s);
  4315. continue;
  4316. }
  4317. if (!is_type_string(op.type)) {
  4318. gbString s = type_to_string(op.type);
  4319. error(fp_node, "Expected a constant string value, got value of type '%s'", s);
  4320. gb_string_free(s);
  4321. continue;
  4322. }
  4323. String file_str = op.value.value_string;
  4324. file_str = string_trim_whitespace(file_str);
  4325. String fullpath = file_str;
  4326. if (allow_check_foreign_filepath()) {
  4327. String foreign_path = {};
  4328. bool ok = determine_path_from_string(nullptr, decl, base_dir, file_str, &foreign_path, /*use error not syntax_error*/true);
  4329. if (ok) {
  4330. fullpath = foreign_path;
  4331. }
  4332. }
  4333. array_add(&fullpaths, fullpath);
  4334. }
  4335. fl->fullpaths = slice_from_array(fullpaths);
  4336. }
  4337. for (String const &path : fl->fullpaths) {
  4338. String ext = path_extension(path);
  4339. if (str_eq_ignore_case(ext, ".c") ||
  4340. str_eq_ignore_case(ext, ".cpp") ||
  4341. str_eq_ignore_case(ext, ".cxx") ||
  4342. str_eq_ignore_case(ext, ".h") ||
  4343. str_eq_ignore_case(ext, ".hpp") ||
  4344. str_eq_ignore_case(ext, ".hxx") ||
  4345. false
  4346. ) {
  4347. error(fl->token, "With 'foreign import', you cannot import a %.*s file/directory, you must precompile the library and link against that", LIT(ext));
  4348. break;
  4349. }
  4350. }
  4351. add_untyped_expressions(ctx.info, &untyped);
  4352. e->LibraryName.paths = fl->fullpaths;
  4353. }
  4354. }
  4355. gb_internal void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) {
  4356. if (decl->state_flags & StateFlag_BeenHandled) return;
  4357. decl->state_flags |= StateFlag_BeenHandled;
  4358. ast_node(fl, ForeignImportDecl, decl);
  4359. Scope *parent_scope = ctx->scope;
  4360. GB_ASSERT(parent_scope->flags&ScopeFlag_File);
  4361. String library_name = fl->library_name.string;
  4362. if (library_name.len == 0 && fl->fullpaths.count != 0) {
  4363. String fullpath = fl->fullpaths[0];
  4364. library_name = path_to_entity_name(fl->library_name.string, fullpath);
  4365. }
  4366. if (library_name.len == 0 || is_blank_ident(library_name)) {
  4367. error(fl->token, "File name, '%.*s', cannot be as a library name as it is not a valid identifier", LIT(library_name));
  4368. return;
  4369. }
  4370. GB_ASSERT(fl->library_name.pos.line != 0);
  4371. fl->library_name.string = library_name;
  4372. Entity *e = alloc_entity_library_name(parent_scope, fl->library_name, t_invalid,
  4373. fl->fullpaths, library_name);
  4374. e->LibraryName.decl = decl;
  4375. add_entity_flags_from_file(ctx, e, parent_scope);
  4376. add_entity(ctx, parent_scope, nullptr, e);
  4377. AttributeContext ac = {};
  4378. check_decl_attributes(ctx, fl->attributes, foreign_import_decl_attribute, &ac);
  4379. if (ac.require_declaration) {
  4380. mpsc_enqueue(&ctx->info->required_foreign_imports_through_force_queue, e);
  4381. add_entity_use(ctx, nullptr, e);
  4382. }
  4383. if (ac.foreign_import_priority_index != 0) {
  4384. e->LibraryName.priority_index = ac.foreign_import_priority_index;
  4385. }
  4386. String extra_linker_flags = string_trim_whitespace(ac.extra_linker_flags);
  4387. if (extra_linker_flags.len != 0) {
  4388. e->LibraryName.extra_linker_flags = extra_linker_flags;
  4389. }
  4390. mpsc_enqueue(&ctx->info->foreign_imports_to_check_fullpaths, e);
  4391. }
  4392. // Returns true if a new package is present
  4393. gb_internal bool collect_file_decls(CheckerContext *ctx, Slice<Ast *> const &decls);
  4394. gb_internal bool collect_file_decls_from_when_stmt(CheckerContext *ctx, AstWhenStmt *ws);
  4395. gb_internal bool collect_when_stmt_from_file(CheckerContext *ctx, AstWhenStmt *ws) {
  4396. Operand operand = {Addressing_Invalid};
  4397. if (!ws->is_cond_determined) {
  4398. check_expr(ctx, &operand, ws->cond);
  4399. if (operand.mode != Addressing_Invalid && !is_type_boolean(operand.type)) {
  4400. error(ws->cond, "Non-boolean condition in 'when' statement");
  4401. }
  4402. if (operand.mode != Addressing_Constant) {
  4403. error(ws->cond, "Non-constant condition in 'when' statement");
  4404. }
  4405. ws->is_cond_determined = true;
  4406. ws->determined_cond = operand.value.kind == ExactValue_Bool && operand.value.value_bool;
  4407. }
  4408. if (ws->body == nullptr || ws->body->kind != Ast_BlockStmt) {
  4409. error(ws->cond, "Invalid body for 'when' statement");
  4410. } else {
  4411. if (ws->determined_cond) {
  4412. check_collect_entities(ctx, ws->body->BlockStmt.stmts);
  4413. return true;
  4414. } else if (ws->else_stmt) {
  4415. switch (ws->else_stmt->kind) {
  4416. case Ast_BlockStmt:
  4417. check_collect_entities(ctx, ws->else_stmt->BlockStmt.stmts);
  4418. return true;
  4419. case Ast_WhenStmt:
  4420. collect_when_stmt_from_file(ctx, &ws->else_stmt->WhenStmt);
  4421. return true;
  4422. default:
  4423. error(ws->else_stmt, "Invalid 'else' statement in 'when' statement");
  4424. break;
  4425. }
  4426. }
  4427. }
  4428. return false;
  4429. }
  4430. gb_internal bool collect_file_decls_from_when_stmt(CheckerContext *ctx, AstWhenStmt *ws) {
  4431. Operand operand = {Addressing_Invalid};
  4432. if (!ws->is_cond_determined) {
  4433. check_expr(ctx, &operand, ws->cond);
  4434. if (operand.mode != Addressing_Invalid && !is_type_boolean(operand.type)) {
  4435. error(ws->cond, "Non-boolean condition in 'when' statement");
  4436. }
  4437. if (operand.mode != Addressing_Constant) {
  4438. error(ws->cond, "Non-constant condition in 'when' statement");
  4439. }
  4440. ws->is_cond_determined = true;
  4441. ws->determined_cond = operand.value.kind == ExactValue_Bool && operand.value.value_bool;
  4442. }
  4443. if (ws->body == nullptr || ws->body->kind != Ast_BlockStmt) {
  4444. error(ws->cond, "Invalid body for 'when' statement");
  4445. } else {
  4446. if (ws->determined_cond) {
  4447. return collect_file_decls(ctx, ws->body->BlockStmt.stmts);
  4448. } else if (ws->else_stmt) {
  4449. switch (ws->else_stmt->kind) {
  4450. case Ast_BlockStmt:
  4451. return collect_file_decls(ctx, ws->else_stmt->BlockStmt.stmts);
  4452. case Ast_WhenStmt:
  4453. return collect_file_decls_from_when_stmt(ctx, &ws->else_stmt->WhenStmt);
  4454. default:
  4455. error(ws->else_stmt, "Invalid 'else' statement in 'when' statement");
  4456. break;
  4457. }
  4458. }
  4459. }
  4460. return false;
  4461. }
  4462. gb_internal bool collect_file_decl(CheckerContext *ctx, Ast *decl) {
  4463. GB_ASSERT(ctx->scope->flags&ScopeFlag_File);
  4464. AstFile *curr_file = ctx->scope->file;
  4465. GB_ASSERT(curr_file != nullptr);
  4466. if (decl->state_flags & StateFlag_BeenHandled) {
  4467. return false;
  4468. }
  4469. switch (decl->kind) {
  4470. case_ast_node(vd, ValueDecl, decl);
  4471. check_collect_value_decl(ctx, decl);
  4472. case_end;
  4473. case_ast_node(id, ImportDecl, decl);
  4474. check_add_import_decl(ctx, decl);
  4475. case_end;
  4476. case_ast_node(fl, ForeignImportDecl, decl);
  4477. check_add_foreign_import_decl(ctx, decl);
  4478. case_end;
  4479. case_ast_node(fb, ForeignBlockDecl, decl);
  4480. if (check_add_foreign_block_decl(ctx, decl)) {
  4481. return true;
  4482. }
  4483. case_end;
  4484. case_ast_node(ws, WhenStmt, decl);
  4485. if (!ws->is_cond_determined) {
  4486. if (collect_when_stmt_from_file(ctx, ws)) {
  4487. return true;
  4488. }
  4489. CheckerContext nctx = *ctx;
  4490. nctx.collect_delayed_decls = true;
  4491. if (collect_file_decls_from_when_stmt(&nctx, ws)) {
  4492. return true;
  4493. }
  4494. } else {
  4495. CheckerContext nctx = *ctx;
  4496. nctx.collect_delayed_decls = true;
  4497. if (collect_file_decls_from_when_stmt(&nctx, ws)) {
  4498. return true;
  4499. }
  4500. }
  4501. case_end;
  4502. case_ast_node(es, ExprStmt, decl);
  4503. GB_ASSERT(ctx->collect_delayed_decls);
  4504. decl->state_flags |= StateFlag_BeenHandled;
  4505. if (es->expr->kind == Ast_CallExpr) {
  4506. ast_node(ce, CallExpr, es->expr);
  4507. if (ce->proc->kind == Ast_BasicDirective) {
  4508. array_add(&curr_file->delayed_decls_queues[AstDelayQueue_Expr], es->expr);
  4509. }
  4510. }
  4511. case_end;
  4512. }
  4513. return false;
  4514. }
  4515. gb_internal bool collect_file_decls(CheckerContext *ctx, Slice<Ast *> const &decls) {
  4516. GB_ASSERT(ctx->scope->flags&ScopeFlag_File);
  4517. for_array(i, decls) {
  4518. if (collect_file_decl(ctx, decls[i])) {
  4519. correct_type_aliases_in_scope(ctx, ctx->scope);
  4520. return true;
  4521. }
  4522. }
  4523. correct_type_aliases_in_scope(ctx, ctx->scope);
  4524. return false;
  4525. }
  4526. gb_internal GB_COMPARE_PROC(sort_file_by_name) {
  4527. AstFile const *x = *cast(AstFile const **)a;
  4528. AstFile const *y = *cast(AstFile const **)b;
  4529. String x_name = filename_from_path(x->fullpath);
  4530. String y_name = filename_from_path(y->fullpath);
  4531. return string_compare(x_name, y_name);
  4532. }
  4533. gb_internal void check_create_file_scopes(Checker *c) {
  4534. for_array(i, c->parser->packages) {
  4535. AstPackage *pkg = c->parser->packages[i];
  4536. array_sort(pkg->files, sort_file_by_name);
  4537. isize total_pkg_decl_count = 0;
  4538. for_array(j, pkg->files) {
  4539. AstFile *f = pkg->files[j];
  4540. string_map_set(&c->info.files, f->fullpath, f);
  4541. create_scope_from_file(nullptr, f);
  4542. total_pkg_decl_count += f->total_file_decl_count;
  4543. }
  4544. mpmc_init(&pkg->exported_entity_queue, total_pkg_decl_count);
  4545. }
  4546. }
  4547. struct CollectEntityWorkerData {
  4548. Checker *c;
  4549. CheckerContext ctx;
  4550. UntypedExprInfoMap untyped;
  4551. };
  4552. gb_global CollectEntityWorkerData *collect_entity_worker_data;
  4553. gb_internal WORKER_TASK_PROC(check_collect_entities_all_worker_proc) {
  4554. CollectEntityWorkerData *wd = &collect_entity_worker_data[current_thread_index()];
  4555. Checker *c = wd->c;
  4556. CheckerContext *ctx = &wd->ctx;
  4557. UntypedExprInfoMap *untyped = &wd->untyped;
  4558. AstFile *f = cast(AstFile *)data;
  4559. reset_checker_context(ctx, f, untyped);
  4560. check_collect_entities(ctx, f->decls);
  4561. GB_ASSERT(ctx->collect_delayed_decls == false);
  4562. add_untyped_expressions(&c->info, ctx->untyped);
  4563. return 0;
  4564. }
  4565. gb_internal void check_collect_entities_all(Checker *c) {
  4566. isize thread_count = global_thread_pool.threads.count;
  4567. collect_entity_worker_data = gb_alloc_array(permanent_allocator(), CollectEntityWorkerData, thread_count);
  4568. for (isize i = 0; i < thread_count; i++) {
  4569. auto *wd = &collect_entity_worker_data[i];
  4570. wd->c = c;
  4571. wd->ctx = make_checker_context(c);
  4572. map_init(&wd->untyped);
  4573. }
  4574. for (auto const &entry : c->info.files) {
  4575. AstFile *f = entry.value;
  4576. thread_pool_add_task(check_collect_entities_all_worker_proc, f);
  4577. }
  4578. thread_pool_wait();
  4579. }
  4580. gb_internal void check_export_entities_in_pkg(CheckerContext *ctx, AstPackage *pkg, UntypedExprInfoMap *untyped) {
  4581. if (pkg->files.count != 0) {
  4582. AstPackageExportedEntity item = {};
  4583. while (mpmc_dequeue(&pkg->exported_entity_queue, &item)) {
  4584. AstFile *f = item.entity->file;
  4585. if (ctx->file != f) {
  4586. reset_checker_context(ctx, f, untyped);
  4587. }
  4588. add_entity(ctx, pkg->scope, item.identifier, item.entity);
  4589. add_untyped_expressions(ctx->info, untyped);
  4590. }
  4591. }
  4592. }
  4593. gb_internal WORKER_TASK_PROC(check_export_entities_worker_proc) {
  4594. AstPackage *pkg = (AstPackage *)data;
  4595. auto *wd = &collect_entity_worker_data[current_thread_index()];
  4596. check_export_entities_in_pkg(&wd->ctx, pkg, &wd->untyped);
  4597. return 0;
  4598. }
  4599. gb_internal void check_export_entities(Checker *c) {
  4600. isize thread_count = global_thread_pool.threads.count;
  4601. // NOTE(bill): reuse `collect_entity_worker_data`
  4602. for (isize i = 0; i < thread_count; i++) {
  4603. auto *wd = &collect_entity_worker_data[i];
  4604. map_clear(&wd->untyped);
  4605. wd->ctx = make_checker_context(c);
  4606. }
  4607. for (auto const &entry : c->info.packages) {
  4608. AstPackage *pkg = entry.value;
  4609. thread_pool_add_task(check_export_entities_worker_proc, pkg);
  4610. }
  4611. thread_pool_wait();
  4612. }
  4613. gb_internal void check_import_entities(Checker *c) {
  4614. Array<ImportGraphNode *> dep_graph = generate_import_dependency_graph(c);
  4615. defer ({
  4616. for_array(i, dep_graph) {
  4617. import_graph_node_destroy(dep_graph[i], heap_allocator());
  4618. }
  4619. array_free(&dep_graph);
  4620. });
  4621. TIME_SECTION("check_import_entities - sort packages");
  4622. // NOTE(bill): Priority queue
  4623. auto pq = priority_queue_create(dep_graph, import_graph_node_cmp, import_graph_node_swap);
  4624. PtrSet<AstPackage *> emitted = {};
  4625. defer (ptr_set_destroy(&emitted));
  4626. Array<ImportGraphNode *> package_order = {};
  4627. array_init(&package_order, heap_allocator(), 0, c->parser->packages.count);
  4628. defer (array_free(&package_order));
  4629. while (pq.queue.count > 0) {
  4630. ImportGraphNode *n = priority_queue_pop(&pq);
  4631. AstPackage *pkg = n->pkg;
  4632. if (n->dep_count > 0) {
  4633. PtrSet<AstPackage *> visited = {};
  4634. defer (ptr_set_destroy(&visited));
  4635. auto path = find_import_path(c, pkg, pkg, &visited);
  4636. defer (array_free(&path));
  4637. if (path.count > 1) {
  4638. ImportPathItem item = path[path.count-1];
  4639. String pkg_name = item.pkg->name;
  4640. error(item.decl, "Cyclic importation of '%.*s'", LIT(pkg_name));
  4641. for (isize i = 0; i < path.count; i++) {
  4642. error(item.decl, "'%.*s' refers to", LIT(pkg_name));
  4643. item = path[i];
  4644. pkg_name = item.pkg->name;
  4645. }
  4646. error(item.decl, "'%.*s'", LIT(pkg_name));
  4647. }
  4648. }
  4649. for (ImportGraphNode *p : n->pred) {
  4650. p->dep_count = gb_max(p->dep_count-1, 0);
  4651. priority_queue_fix(&pq, p->index);
  4652. }
  4653. if (pkg == nullptr) {
  4654. continue;
  4655. }
  4656. if (ptr_set_update(&emitted, pkg)) {
  4657. continue;
  4658. }
  4659. array_add(&package_order, n);
  4660. }
  4661. TIME_SECTION("check_import_entities - collect file decls");
  4662. CheckerContext ctx = make_checker_context(c);
  4663. UntypedExprInfoMap untyped = {};
  4664. defer (map_destroy(&untyped));
  4665. isize min_pkg_index = 0;
  4666. for (isize pkg_index = 0; pkg_index < package_order.count; pkg_index++) {
  4667. ImportGraphNode *node = package_order[pkg_index];
  4668. AstPackage *pkg = node->pkg;
  4669. pkg->order = 1+pkg_index;
  4670. for_array(i, pkg->files) {
  4671. AstFile *f = pkg->files[i];
  4672. reset_checker_context(&ctx, f, &untyped);
  4673. ctx.collect_delayed_decls = true;
  4674. // Check import declarations first to simplify things
  4675. for (Ast *decl : f->delayed_decls_queues[AstDelayQueue_Import]) {
  4676. check_add_import_decl(&ctx, decl);
  4677. }
  4678. array_clear(&f->delayed_decls_queues[AstDelayQueue_Import]);
  4679. if (collect_file_decls(&ctx, f->decls)) {
  4680. check_export_entities_in_pkg(&ctx, pkg, &untyped);
  4681. pkg_index = min_pkg_index-1;
  4682. break;
  4683. }
  4684. add_untyped_expressions(ctx.info, &untyped);
  4685. }
  4686. if (pkg_index < 0) {
  4687. continue;
  4688. }
  4689. min_pkg_index = pkg_index;
  4690. }
  4691. TIME_SECTION("check_import_entities - check delayed entities");
  4692. for_array(i, package_order) {
  4693. ImportGraphNode *node = package_order[i];
  4694. GB_ASSERT(node->scope->flags&ScopeFlag_Pkg);
  4695. AstPackage *pkg = node->scope->pkg;
  4696. for_array(i, pkg->files) {
  4697. AstFile *f = pkg->files[i];
  4698. reset_checker_context(&ctx, f, &untyped);
  4699. for (Ast *decl : f->delayed_decls_queues[AstDelayQueue_Import]) {
  4700. check_add_import_decl(&ctx, decl);
  4701. }
  4702. array_clear(&f->delayed_decls_queues[AstDelayQueue_Import]);
  4703. add_untyped_expressions(ctx.info, &untyped);
  4704. }
  4705. for_array(i, pkg->files) {
  4706. AstFile *f = pkg->files[i];
  4707. reset_checker_context(&ctx, f, &untyped);
  4708. ctx.collect_delayed_decls = false;
  4709. correct_type_aliases_in_scope(&ctx, pkg->scope);
  4710. }
  4711. for_array(i, pkg->files) {
  4712. AstFile *f = pkg->files[i];
  4713. reset_checker_context(&ctx, f, &untyped);
  4714. for (Ast *expr : f->delayed_decls_queues[AstDelayQueue_Expr]) {
  4715. Operand o = {};
  4716. check_expr(&ctx, &o, expr);
  4717. }
  4718. array_clear(&f->delayed_decls_queues[AstDelayQueue_Expr]);
  4719. add_untyped_expressions(ctx.info, &untyped);
  4720. }
  4721. }
  4722. }
  4723. gb_internal Array<Entity *> find_entity_path(Entity *start, Entity *end, PtrSet<Entity *> *visited = nullptr);
  4724. gb_internal bool find_entity_path_tuple(Type *tuple, Entity *end, PtrSet<Entity *> *visited, Array<Entity *> *path_) {
  4725. GB_ASSERT(path_ != nullptr);
  4726. if (tuple == nullptr) {
  4727. return false;
  4728. }
  4729. GB_ASSERT(tuple->kind == Type_Tuple);
  4730. for_array(i, tuple->Tuple.variables) {
  4731. Entity *var = tuple->Tuple.variables[i];
  4732. DeclInfo *var_decl = var->decl_info;
  4733. if (var_decl == nullptr) {
  4734. continue;
  4735. }
  4736. for (Entity *dep : var_decl->deps) {
  4737. if (dep == end) {
  4738. auto path = array_make<Entity *>(heap_allocator());
  4739. array_add(&path, dep);
  4740. *path_ = path;
  4741. return true;
  4742. }
  4743. auto next_path = find_entity_path(dep, end, visited);
  4744. if (next_path.count > 0) {
  4745. array_add(&next_path, dep);
  4746. *path_ = next_path;
  4747. return true;
  4748. }
  4749. }
  4750. }
  4751. return false;
  4752. }
  4753. gb_internal Array<Entity *> find_entity_path(Entity *start, Entity *end, PtrSet<Entity *> *visited) {
  4754. PtrSet<Entity *> visited_ = {};
  4755. bool made_visited = false;
  4756. if (visited == nullptr) {
  4757. made_visited = true;
  4758. visited = &visited_;
  4759. }
  4760. defer (if (made_visited) {
  4761. ptr_set_destroy(&visited_);
  4762. });
  4763. Array<Entity *> empty_path = {};
  4764. if (ptr_set_update(visited, start)) {
  4765. return empty_path;
  4766. }
  4767. DeclInfo *decl = start->decl_info;
  4768. if (decl) {
  4769. if (start->kind == Entity_Procedure) {
  4770. Type *t = base_type(start->type);
  4771. GB_ASSERT(t->kind == Type_Proc);
  4772. Array<Entity *> path = {};
  4773. if (find_entity_path_tuple(t->Proc.params, end, visited, &path)) {
  4774. return path;
  4775. }
  4776. if (find_entity_path_tuple(t->Proc.results, end, visited, &path)) {
  4777. return path;
  4778. }
  4779. } else {
  4780. for (Entity *dep : decl->deps) {
  4781. if (dep == end) {
  4782. auto path = array_make<Entity *>(heap_allocator());
  4783. array_add(&path, dep);
  4784. return path;
  4785. }
  4786. auto next_path = find_entity_path(dep, end, visited);
  4787. if (next_path.count > 0) {
  4788. array_add(&next_path, dep);
  4789. return next_path;
  4790. }
  4791. }
  4792. }
  4793. }
  4794. return empty_path;
  4795. }
  4796. gb_internal void calculate_global_init_order(Checker *c) {
  4797. CheckerInfo *info = &c->info;
  4798. TIME_SECTION("calculate_global_init_order: generate entity dependency graph");
  4799. Array<EntityGraphNode *> dep_graph = generate_entity_dependency_graph(info, heap_allocator());
  4800. defer ({
  4801. for_array(i, dep_graph) {
  4802. entity_graph_node_destroy(dep_graph[i], heap_allocator());
  4803. }
  4804. array_free(&dep_graph);
  4805. });
  4806. TIME_SECTION("calculate_global_init_order: priority queue create");
  4807. // NOTE(bill): Priority queue
  4808. auto pq = priority_queue_create(dep_graph, entity_graph_node_cmp, entity_graph_node_swap);
  4809. PtrSet<DeclInfo *> emitted = {};
  4810. defer (ptr_set_destroy(&emitted));
  4811. TIME_SECTION("calculate_global_init_order: queue sort");
  4812. while (pq.queue.count > 0) {
  4813. EntityGraphNode *n = priority_queue_pop(&pq);
  4814. Entity *e = n->entity;
  4815. if (n->dep_count > 0) {
  4816. auto path = find_entity_path(e, e);
  4817. defer (array_free(&path));
  4818. if (path.count > 0) {
  4819. Entity *e = path[0];
  4820. error(e->token, "Cyclic initialization of '%.*s'", LIT(e->token.string));
  4821. for (isize i = path.count-1; i >= 0; i--) {
  4822. error(e->token, "\t'%.*s' refers to", LIT(e->token.string));
  4823. e = path[i];
  4824. }
  4825. error(e->token, "\t'%.*s'", LIT(e->token.string));
  4826. }
  4827. }
  4828. for (EntityGraphNode *p : n->pred) {
  4829. p->dep_count -= 1;
  4830. p->dep_count = gb_max(p->dep_count, 0);
  4831. priority_queue_fix(&pq, p->index);
  4832. }
  4833. DeclInfo *d = decl_info_of_entity(e);
  4834. if (e->kind != Entity_Variable) {
  4835. continue;
  4836. }
  4837. // IMPORTANT NOTE(bill, 2019-08-29): Just add it regardless of the ordering
  4838. // because it does not need any initialization other than zero
  4839. // if (!decl_info_has_init(d)) {
  4840. // continue;
  4841. // }
  4842. if (ptr_set_update(&emitted, d)) {
  4843. continue;
  4844. }
  4845. array_add(&info->variable_init_order, d);
  4846. }
  4847. if (false) {
  4848. gb_printf("Variable Initialization Order:\n");
  4849. for_array(i, info->variable_init_order) {
  4850. DeclInfo *d = info->variable_init_order[i];
  4851. Entity *e = d->entity;
  4852. gb_printf("\t'%.*s' %llu\n", LIT(e->token.string), cast(unsigned long long)e->order_in_src);
  4853. }
  4854. gb_printf("\n");
  4855. }
  4856. }
  4857. gb_internal void check_procedure_later_from_entity(Checker *c, Entity *e, char const *from_msg) {
  4858. if (e == nullptr || e->kind != Entity_Procedure) {
  4859. return;
  4860. }
  4861. if (e->Procedure.is_foreign) {
  4862. return;
  4863. }
  4864. if ((e->flags & EntityFlag_ProcBodyChecked) != 0) {
  4865. return;
  4866. }
  4867. Type *type = base_type(e->type);
  4868. if (type == t_invalid) {
  4869. return;
  4870. }
  4871. GB_ASSERT_MSG(type->kind == Type_Proc, "%s", type_to_string(e->type));
  4872. if (is_type_polymorphic(type) && !type->Proc.is_poly_specialized) {
  4873. return;
  4874. }
  4875. GB_ASSERT(e->decl_info != nullptr);
  4876. ProcInfo *pi = gb_alloc_item(permanent_allocator(), ProcInfo);
  4877. pi->file = e->file;
  4878. pi->token = e->token;
  4879. pi->decl = e->decl_info;
  4880. pi->type = e->type;
  4881. Ast *pl = e->decl_info->proc_lit;
  4882. GB_ASSERT(pl != nullptr);
  4883. pi->body = pl->ProcLit.body;
  4884. pi->tags = pl->ProcLit.tags;
  4885. if (pi->body == nullptr) {
  4886. return;
  4887. }
  4888. if (from_msg != nullptr) {
  4889. debugf("CHECK PROCEDURE LATER [FROM %s]! %.*s :: %s {...}\n", from_msg, LIT(e->token.string), type_to_string(e->type));
  4890. }
  4891. check_procedure_later(c, pi);
  4892. }
  4893. gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped) {
  4894. if (pi == nullptr) {
  4895. return false;
  4896. }
  4897. if (pi->type == nullptr) {
  4898. return false;
  4899. }
  4900. if (!mutex_try_lock(&pi->decl->proc_checked_mutex)) {
  4901. return false;
  4902. }
  4903. defer (mutex_unlock(&pi->decl->proc_checked_mutex));
  4904. Entity *e = pi->decl->entity;
  4905. switch (pi->decl->proc_checked_state.load()) {
  4906. case ProcCheckedState_InProgress:
  4907. if (e) {
  4908. GB_ASSERT(global_procedure_body_in_worker_queue.load());
  4909. }
  4910. return false;
  4911. case ProcCheckedState_Checked:
  4912. if (e != nullptr) {
  4913. GB_ASSERT(e->flags & EntityFlag_ProcBodyChecked);
  4914. }
  4915. return true;
  4916. case ProcCheckedState_Unchecked:
  4917. // okay
  4918. break;
  4919. }
  4920. pi->decl->proc_checked_state.store(ProcCheckedState_InProgress);
  4921. GB_ASSERT(pi->type->kind == Type_Proc);
  4922. TypeProc *pt = &pi->type->Proc;
  4923. String name = pi->token.string;
  4924. if (pt->is_polymorphic && !pt->is_poly_specialized) {
  4925. Token token = pi->token;
  4926. if (pi->poly_def_node != nullptr) {
  4927. token = ast_token(pi->poly_def_node);
  4928. }
  4929. error(token, "Unspecialized polymorphic procedure '%.*s'", LIT(name));
  4930. pi->decl->proc_checked_state.store(ProcCheckedState_Unchecked);
  4931. return false;
  4932. }
  4933. if (pt->is_polymorphic && pt->is_poly_specialized) {
  4934. Entity *e = pi->decl->entity;
  4935. GB_ASSERT(e != nullptr);
  4936. if ((e->flags & EntityFlag_Used) == 0) {
  4937. // NOTE(bill, 2019-08-31): It was never used, don't check
  4938. // NOTE(bill, 2023-01-02): This may need to be checked again if it is used elsewhere?
  4939. pi->decl->proc_checked_state.store(ProcCheckedState_Unchecked);
  4940. return false;
  4941. }
  4942. }
  4943. CheckerContext ctx = make_checker_context(c);
  4944. defer (destroy_checker_context(&ctx));
  4945. reset_checker_context(&ctx, pi->file, untyped);
  4946. ctx.decl = pi->decl;
  4947. bool bounds_check = (pi->tags & ProcTag_bounds_check) != 0;
  4948. bool no_bounds_check = (pi->tags & ProcTag_no_bounds_check) != 0;
  4949. bool type_assert = (pi->tags & ProcTag_type_assert) != 0;
  4950. bool no_type_assert = (pi->tags & ProcTag_no_type_assert) != 0;
  4951. if (bounds_check) {
  4952. ctx.state_flags |= StateFlag_bounds_check;
  4953. ctx.state_flags &= ~StateFlag_no_bounds_check;
  4954. } else if (no_bounds_check) {
  4955. ctx.state_flags |= StateFlag_no_bounds_check;
  4956. ctx.state_flags &= ~StateFlag_bounds_check;
  4957. }
  4958. if (type_assert) {
  4959. ctx.state_flags |= StateFlag_type_assert;
  4960. ctx.state_flags &= ~StateFlag_no_type_assert;
  4961. } else if (no_type_assert) {
  4962. ctx.state_flags |= StateFlag_no_type_assert;
  4963. ctx.state_flags &= ~StateFlag_type_assert;
  4964. }
  4965. bool body_was_checked = check_proc_body(&ctx, pi->token, pi->decl, pi->type, pi->body);
  4966. if (body_was_checked) {
  4967. pi->decl->proc_checked_state.store(ProcCheckedState_Checked);
  4968. if (pi->body) {
  4969. Entity *e = pi->decl->entity;
  4970. if (e != nullptr) {
  4971. e->flags |= EntityFlag_ProcBodyChecked;
  4972. }
  4973. }
  4974. } else {
  4975. pi->decl->proc_checked_state.store(ProcCheckedState_Unchecked);
  4976. if (pi->body) {
  4977. Entity *e = pi->decl->entity;
  4978. if (e != nullptr) {
  4979. e->flags &= ~EntityFlag_ProcBodyChecked;
  4980. }
  4981. }
  4982. }
  4983. add_untyped_expressions(&c->info, ctx.untyped);
  4984. rw_mutex_shared_lock(&ctx.decl->deps_mutex);
  4985. for (Entity *dep : ctx.decl->deps) {
  4986. if (dep && dep->kind == Entity_Procedure &&
  4987. (dep->flags & EntityFlag_ProcBodyChecked) == 0) {
  4988. check_procedure_later_from_entity(c, dep, NULL);
  4989. }
  4990. }
  4991. rw_mutex_shared_unlock(&ctx.decl->deps_mutex);
  4992. return true;
  4993. }
  4994. GB_STATIC_ASSERT(sizeof(isize) == sizeof(void *));
  4995. gb_internal bool consume_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped);
  4996. gb_internal void check_unchecked_bodies(Checker *c) {
  4997. // NOTE(2021-02-26, bill): Sanity checker
  4998. // This is a partial hack to make sure all procedure bodies have been checked
  4999. // even ones which should not exist, due to the multithreaded nature of the parser
  5000. // HACK TODO(2021-02-26, bill): Actually fix this race condition
  5001. GB_ASSERT(c->procs_to_check.count == 0);
  5002. UntypedExprInfoMap untyped = {};
  5003. defer (map_destroy(&untyped));
  5004. // use the `procs_to_check` array
  5005. global_procedure_body_in_worker_queue = false;
  5006. for (Entity *e : c->info.minimum_dependency_set) {
  5007. check_procedure_later_from_entity(c, e, "check_unchecked_bodies");
  5008. }
  5009. if (!global_procedure_body_in_worker_queue) {
  5010. for_array(i, c->procs_to_check) {
  5011. ProcInfo *pi = c->procs_to_check[i];
  5012. consume_proc_info(c, pi, &untyped);
  5013. }
  5014. array_clear(&c->procs_to_check);
  5015. } else {
  5016. thread_pool_wait();
  5017. }
  5018. global_procedure_body_in_worker_queue = false;
  5019. global_after_checking_procedure_bodies = true;
  5020. }
  5021. gb_internal void check_safety_all_procedures_for_unchecked(Checker *c) {
  5022. GB_ASSERT(DEBUG_CHECK_ALL_PROCEDURES);
  5023. UntypedExprInfoMap untyped = {};
  5024. defer (map_destroy(&untyped));
  5025. for_array(i, c->info.all_procedures) {
  5026. ProcInfo *pi = c->info.all_procedures[i];
  5027. GB_ASSERT(pi != nullptr);
  5028. GB_ASSERT(pi->decl != nullptr);
  5029. Entity *e = pi->decl->entity;
  5030. auto proc_checked_state = pi->decl->proc_checked_state.load();
  5031. gb_unused(proc_checked_state);
  5032. if (e && ((e->flags & EntityFlag_ProcBodyChecked) == 0)) {
  5033. if ((e->flags & EntityFlag_Used) != 0) {
  5034. // debugf("%.*s :: %s\n", LIT(e->token.string), type_to_string(e->type));
  5035. // debugf("proc body unchecked\n");
  5036. // debugf("Checked State: %s\n\n", ProcCheckedState_strings[proc_checked_state]);
  5037. consume_proc_info(c, pi, &untyped);
  5038. }
  5039. }
  5040. }
  5041. }
  5042. gb_internal GB_COMPARE_PROC(init_procedures_cmp);
  5043. gb_internal GB_COMPARE_PROC(fini_procedures_cmp);
  5044. gb_internal void remove_neighbouring_duplicate_entires_from_sorted_array(Array<Entity *> *array) {
  5045. Entity *prev = nullptr;
  5046. for (isize i = 0; i < array->count; /**/) {
  5047. Entity *curr = array->data[i];
  5048. if (prev == curr) {
  5049. array_ordered_remove(array, i);
  5050. } else {
  5051. prev = curr;
  5052. i += 1;
  5053. }
  5054. }
  5055. }
  5056. gb_internal void check_test_procedures(Checker *c) {
  5057. array_sort(c->info.testing_procedures, init_procedures_cmp);
  5058. remove_neighbouring_duplicate_entires_from_sorted_array(&c->info.testing_procedures);
  5059. }
  5060. gb_global std::atomic<isize> total_bodies_checked;
  5061. gb_internal bool consume_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped) {
  5062. GB_ASSERT(pi->decl != nullptr);
  5063. switch (pi->decl->proc_checked_state.load()) {
  5064. case ProcCheckedState_InProgress:
  5065. return false;
  5066. case ProcCheckedState_Checked:
  5067. return true;
  5068. }
  5069. if (pi->decl->parent && pi->decl->parent->entity) {
  5070. Entity *parent = pi->decl->parent->entity;
  5071. // NOTE(bill): Only check a nested procedure if its parent's body has been checked first
  5072. // This is prevent any possible race conditions in evaluation when multithreaded
  5073. // NOTE(bill): In single threaded mode, this should never happen
  5074. if (parent->kind == Entity_Procedure && (parent->flags & EntityFlag_ProcBodyChecked) == 0) {
  5075. check_procedure_later(c, pi);
  5076. return false;
  5077. }
  5078. }
  5079. if (untyped) {
  5080. map_clear(untyped);
  5081. }
  5082. if (check_proc_info(c, pi, untyped)) {
  5083. total_bodies_checked.fetch_add(1, std::memory_order_relaxed);
  5084. return true;
  5085. }
  5086. return false;
  5087. }
  5088. struct CheckProcedureBodyWorkerData {
  5089. Checker *c;
  5090. UntypedExprInfoMap untyped;
  5091. };
  5092. gb_global CheckProcedureBodyWorkerData *check_procedure_bodies_worker_data;
  5093. gb_internal WORKER_TASK_PROC(check_proc_info_worker_proc) {
  5094. auto *wd = &check_procedure_bodies_worker_data[current_thread_index()];
  5095. UntypedExprInfoMap *untyped = &wd->untyped;
  5096. Checker *c = wd->c;
  5097. ProcInfo *pi = cast(ProcInfo *)data;
  5098. GB_ASSERT(pi->decl != nullptr);
  5099. if (pi->decl->parent && pi->decl->parent->entity) {
  5100. Entity *parent = pi->decl->parent->entity;
  5101. // NOTE(bill): Only check a nested procedure if its parent's body has been checked first
  5102. // This is prevent any possible race conditions in evaluation when multithreaded
  5103. // NOTE(bill): In single threaded mode, this should never happen
  5104. if (parent->kind == Entity_Procedure && (parent->flags & EntityFlag_ProcBodyChecked) == 0) {
  5105. thread_pool_add_task(check_proc_info_worker_proc, pi);
  5106. return 1;
  5107. }
  5108. }
  5109. map_clear(untyped);
  5110. if (check_proc_info(c, pi, untyped)) {
  5111. total_bodies_checked.fetch_add(1, std::memory_order_relaxed);
  5112. return 0;
  5113. }
  5114. return 1;
  5115. }
  5116. gb_internal void check_init_worker_data(Checker *c) {
  5117. u32 thread_count = cast(u32)global_thread_pool.threads.count;
  5118. check_procedure_bodies_worker_data = gb_alloc_array(permanent_allocator(), CheckProcedureBodyWorkerData, thread_count);
  5119. for (isize i = 0; i < thread_count; i++) {
  5120. check_procedure_bodies_worker_data[i].c = c;
  5121. map_init(&check_procedure_bodies_worker_data[i].untyped);
  5122. }
  5123. }
  5124. gb_internal void check_procedure_bodies(Checker *c) {
  5125. GB_ASSERT(c != nullptr);
  5126. u32 thread_count = cast(u32)global_thread_pool.threads.count;
  5127. if (build_context.no_threaded_checker) {
  5128. thread_count = 1;
  5129. }
  5130. if (thread_count == 1) {
  5131. UntypedExprInfoMap *untyped = &check_procedure_bodies_worker_data[0].untyped;
  5132. for_array(i, c->procs_to_check) {
  5133. consume_proc_info(c, c->procs_to_check[i], untyped);
  5134. }
  5135. array_clear(&c->procs_to_check);
  5136. debugf("Total Procedure Bodies Checked: %td\n", total_bodies_checked.load(std::memory_order_relaxed));
  5137. return;
  5138. }
  5139. global_procedure_body_in_worker_queue = true;
  5140. isize prev_procs_to_check_count = c->procs_to_check.count;
  5141. for_array(i, c->procs_to_check) {
  5142. thread_pool_add_task(check_proc_info_worker_proc, c->procs_to_check[i]);
  5143. }
  5144. GB_ASSERT(prev_procs_to_check_count == c->procs_to_check.count);
  5145. array_clear(&c->procs_to_check);
  5146. thread_pool_wait();
  5147. global_procedure_body_in_worker_queue = false;
  5148. }
  5149. gb_internal void add_untyped_expressions(CheckerInfo *cinfo, UntypedExprInfoMap *untyped) {
  5150. if (untyped == nullptr) {
  5151. return;
  5152. }
  5153. for (auto const &entry : *untyped) {
  5154. Ast *expr = entry.key;
  5155. ExprInfo *info = entry.value;
  5156. if (expr != nullptr && info != nullptr) {
  5157. mpsc_enqueue(&cinfo->checker->global_untyped_queue, UntypedExprInfo{expr, info});
  5158. }
  5159. }
  5160. map_clear(untyped);
  5161. }
  5162. gb_internal Type *tuple_to_pointers(Type *ot) {
  5163. if (ot == nullptr) {
  5164. return nullptr;
  5165. }
  5166. GB_ASSERT(ot->kind == Type_Tuple);
  5167. Type *t = alloc_type_tuple();
  5168. t->Tuple.variables = slice_make<Entity *>(heap_allocator(), ot->Tuple.variables.count);
  5169. Scope *scope = nullptr;
  5170. for_array(i, t->Tuple.variables) {
  5171. Entity *e = ot->Tuple.variables[i];
  5172. t->Tuple.variables[i] = alloc_entity_variable(scope, e->token, alloc_type_pointer(e->type));
  5173. }
  5174. t->Tuple.is_packed = ot->Tuple.is_packed;
  5175. return t;
  5176. }
  5177. gb_internal void check_deferred_procedures(Checker *c) {
  5178. for (Entity *src = nullptr; mpsc_dequeue(&c->procs_with_deferred_to_check, &src); /**/) {
  5179. GB_ASSERT(src->kind == Entity_Procedure);
  5180. DeferredProcedureKind dst_kind = src->Procedure.deferred_procedure.kind;
  5181. Entity *dst = src->Procedure.deferred_procedure.entity;
  5182. GB_ASSERT(dst != nullptr);
  5183. GB_ASSERT(dst->kind == Entity_Procedure);
  5184. char const *attribute = "deferred_none";
  5185. switch (dst_kind) {
  5186. case DeferredProcedure_none: attribute = "deferred_none"; break;
  5187. case DeferredProcedure_in: attribute = "deferred_in"; break;
  5188. case DeferredProcedure_out: attribute = "deferred_out"; break;
  5189. case DeferredProcedure_in_out: attribute = "deferred_in_out"; break;
  5190. case DeferredProcedure_in_by_ptr: attribute = "deferred_in_by_ptr"; break;
  5191. case DeferredProcedure_out_by_ptr: attribute = "deferred_out_by_ptr"; break;
  5192. case DeferredProcedure_in_out_by_ptr: attribute = "deferred_in_out_by_ptr"; break;
  5193. }
  5194. if (is_type_polymorphic(src->type) || is_type_polymorphic(dst->type)) {
  5195. error(src->token, "'%s' cannot be used with a polymorphic procedure", attribute);
  5196. continue;
  5197. }
  5198. GB_ASSERT(is_type_proc(src->type));
  5199. GB_ASSERT(is_type_proc(dst->type));
  5200. Type *src_params = base_type(src->type)->Proc.params;
  5201. Type *src_results = base_type(src->type)->Proc.results;
  5202. Type *dst_params = base_type(dst->type)->Proc.params;
  5203. bool by_ptr = false;
  5204. switch (dst_kind) {
  5205. case DeferredProcedure_in_by_ptr:
  5206. by_ptr = true;
  5207. src_params = tuple_to_pointers(src_params);
  5208. break;
  5209. case DeferredProcedure_out_by_ptr:
  5210. by_ptr = true;
  5211. src_results = tuple_to_pointers(src_results);
  5212. break;
  5213. case DeferredProcedure_in_out_by_ptr:
  5214. by_ptr = true;
  5215. src_params = tuple_to_pointers(src_params);
  5216. src_results = tuple_to_pointers(src_results);
  5217. break;
  5218. }
  5219. switch (dst_kind) {
  5220. case DeferredProcedure_none:
  5221. {
  5222. if (dst_params == nullptr) {
  5223. // Okay
  5224. continue;
  5225. }
  5226. error(src->token, "Deferred procedure '%.*s' must have no input parameters", LIT(dst->token.string));
  5227. } break;
  5228. case DeferredProcedure_in:
  5229. case DeferredProcedure_in_by_ptr:
  5230. {
  5231. if (src_params == nullptr && dst_params == nullptr) {
  5232. // Okay
  5233. continue;
  5234. }
  5235. if ((src_params == nullptr && dst_params != nullptr) ||
  5236. (src_params != nullptr && dst_params == nullptr)) {
  5237. error(src->token, "Deferred procedure '%.*s' parameters do not match the inputs of initial procedure '%.*s'", LIT(src->token.string), LIT(dst->token.string));
  5238. continue;
  5239. }
  5240. GB_ASSERT(src_params->kind == Type_Tuple);
  5241. GB_ASSERT(dst_params->kind == Type_Tuple);
  5242. if (are_types_identical(src_params, dst_params)) {
  5243. // Okay!
  5244. } else {
  5245. gbString s = type_to_string(src_params);
  5246. gbString d = type_to_string(dst_params);
  5247. error(src->token, "Deferred procedure '%.*s' parameters do not match the inputs of initial procedure '%.*s':\n\t(%s) =/= (%s)",
  5248. LIT(src->token.string), LIT(dst->token.string),
  5249. s, d
  5250. );
  5251. gb_string_free(d);
  5252. gb_string_free(s);
  5253. continue;
  5254. }
  5255. } break;
  5256. case DeferredProcedure_out:
  5257. case DeferredProcedure_out_by_ptr:
  5258. {
  5259. if (src_results == nullptr && dst_params == nullptr) {
  5260. // Okay
  5261. continue;
  5262. }
  5263. if ((src_results == nullptr && dst_params != nullptr) ||
  5264. (src_results != nullptr && dst_params == nullptr)) {
  5265. error(src->token, "Deferred procedure '%.*s' parameters do not match the results of initial procedure '%.*s'", LIT(src->token.string), LIT(dst->token.string));
  5266. continue;
  5267. }
  5268. GB_ASSERT(src_results->kind == Type_Tuple);
  5269. GB_ASSERT(dst_params->kind == Type_Tuple);
  5270. if (are_types_identical(src_results, dst_params)) {
  5271. // Okay!
  5272. } else {
  5273. gbString s = type_to_string(src_results);
  5274. gbString d = type_to_string(dst_params);
  5275. error(src->token, "Deferred procedure '%.*s' parameters do not match the results of initial procedure '%.*s':\n\t(%s) =/= (%s)",
  5276. LIT(src->token.string), LIT(dst->token.string),
  5277. s, d
  5278. );
  5279. gb_string_free(d);
  5280. gb_string_free(s);
  5281. continue;
  5282. }
  5283. } break;
  5284. case DeferredProcedure_in_out:
  5285. case DeferredProcedure_in_out_by_ptr:
  5286. {
  5287. if (src_params == nullptr && src_results == nullptr && dst_params == nullptr) {
  5288. // Okay
  5289. continue;
  5290. }
  5291. GB_ASSERT(dst_params->kind == Type_Tuple);
  5292. Type *tsrc = alloc_type_tuple();
  5293. auto &sv = tsrc->Tuple.variables;
  5294. auto const &dv = dst_params->Tuple.variables;
  5295. gb_unused(dv);
  5296. isize len = 0;
  5297. if (src_params != nullptr) {
  5298. GB_ASSERT(src_params->kind == Type_Tuple);
  5299. len += src_params->Tuple.variables.count;
  5300. }
  5301. if (src_results != nullptr) {
  5302. GB_ASSERT(src_results->kind == Type_Tuple);
  5303. len += src_results->Tuple.variables.count;
  5304. }
  5305. slice_init(&sv, heap_allocator(), len);
  5306. isize offset = 0;
  5307. if (src_params != nullptr) {
  5308. for_array(i, src_params->Tuple.variables) {
  5309. sv[offset++] = src_params->Tuple.variables[i];
  5310. }
  5311. }
  5312. if (src_results != nullptr) {
  5313. for_array(i, src_results->Tuple.variables) {
  5314. sv[offset++] = src_results->Tuple.variables[i];
  5315. }
  5316. }
  5317. GB_ASSERT(offset == len);
  5318. if (are_types_identical(tsrc, dst_params)) {
  5319. // Okay!
  5320. } else {
  5321. gbString s = type_to_string(tsrc);
  5322. gbString d = type_to_string(dst_params);
  5323. error(src->token, "Deferred procedure '%.*s' parameters do not match the results of initial procedure '%.*s':\n\t(%s) =/= (%s)",
  5324. LIT(src->token.string), LIT(dst->token.string),
  5325. s, d
  5326. );
  5327. gb_string_free(d);
  5328. gb_string_free(s);
  5329. continue;
  5330. }
  5331. } break;
  5332. }
  5333. }
  5334. }
  5335. gb_internal void check_unique_package_names(Checker *c) {
  5336. ERROR_BLOCK();
  5337. StringMap<AstPackage *> pkgs = {}; // Key: package name
  5338. string_map_init(&pkgs, 2*c->info.packages.count);
  5339. defer (string_map_destroy(&pkgs));
  5340. for (auto const &entry : c->info.packages) {
  5341. AstPackage *pkg = entry.value;
  5342. if (pkg->files.count == 0) {
  5343. continue; // Sanity check
  5344. }
  5345. String name = pkg->name;
  5346. auto key = string_hash_string(name);
  5347. auto *found = string_map_get(&pkgs, key);
  5348. if (found == nullptr) {
  5349. string_map_set(&pkgs, key, pkg);
  5350. continue;
  5351. }
  5352. auto *curr = pkg->files[0]->pkg_decl;
  5353. auto *prev = (*found)->files[0]->pkg_decl;
  5354. if (curr == prev) {
  5355. // NOTE(bill): A false positive was found, ignore it
  5356. continue;
  5357. }
  5358. begin_error_block();
  5359. error(curr, "Duplicate declaration of 'package %.*s'", LIT(name));
  5360. error_line("\tA package name must be unique\n"
  5361. "\tThere is no relation between a package name and the directory that contains it, so they can be completely different\n"
  5362. "\tA package name is required for link name prefixing to have a consistent ABI\n");
  5363. error_line("%s found at previous location\n", token_pos_to_string(ast_token(prev).pos));
  5364. end_error_block();
  5365. }
  5366. }
  5367. gb_internal void check_add_entities_from_queues(Checker *c) {
  5368. isize cap = c->info.entities.count + c->info.entity_queue.count.load(std::memory_order_relaxed);
  5369. array_reserve(&c->info.entities, cap);
  5370. for (Entity *e; mpsc_dequeue(&c->info.entity_queue, &e); /**/) {
  5371. array_add(&c->info.entities, e);
  5372. }
  5373. }
  5374. gb_internal void check_add_definitions_from_queues(Checker *c) {
  5375. isize cap = c->info.definitions.count + c->info.definition_queue.count.load(std::memory_order_relaxed);
  5376. array_reserve(&c->info.definitions, cap);
  5377. for (Entity *e; mpsc_dequeue(&c->info.definition_queue, &e); /**/) {
  5378. array_add(&c->info.definitions, e);
  5379. }
  5380. }
  5381. gb_internal void check_merge_queues_into_arrays(Checker *c) {
  5382. for (Type *t = nullptr; mpsc_dequeue(&c->soa_types_to_complete, &t); /**/) {
  5383. complete_soa_type(c, t, false);
  5384. }
  5385. check_add_entities_from_queues(c);
  5386. check_add_definitions_from_queues(c);
  5387. }
  5388. gb_internal GB_COMPARE_PROC(init_procedures_cmp) {
  5389. int cmp = 0;
  5390. Entity *x = *(Entity **)a;
  5391. Entity *y = *(Entity **)b;
  5392. if (x == y) {
  5393. cmp = 0;
  5394. return cmp;
  5395. }
  5396. if (x->pkg != y->pkg) {
  5397. isize order_x = x->pkg ? x->pkg->order : 0;
  5398. isize order_y = y->pkg ? y->pkg->order : 0;
  5399. cmp = isize_cmp(order_x, order_y);
  5400. if (cmp) {
  5401. return cmp;
  5402. }
  5403. }
  5404. if (x->file != y->file) {
  5405. String fullpath_x = x->file ? x->file->fullpath : (String{});
  5406. String fullpath_y = y->file ? y->file->fullpath : (String{});
  5407. String file_x = filename_from_path(fullpath_x);
  5408. String file_y = filename_from_path(fullpath_y);
  5409. cmp = string_compare(file_x, file_y);
  5410. if (cmp) {
  5411. return cmp;
  5412. }
  5413. }
  5414. cmp = u64_cmp(x->order_in_src, y->order_in_src);
  5415. if (cmp) {
  5416. return cmp;
  5417. }
  5418. return i32_cmp(x->token.pos.offset, y->token.pos.offset);
  5419. }
  5420. gb_internal GB_COMPARE_PROC(fini_procedures_cmp) {
  5421. return init_procedures_cmp(b, a);
  5422. }
  5423. gb_internal void check_sort_init_and_fini_procedures(Checker *c) {
  5424. array_sort(c->info.init_procedures, init_procedures_cmp);
  5425. array_sort(c->info.fini_procedures, fini_procedures_cmp);
  5426. // NOTE(bill): remove possible duplicates from the init/fini lists
  5427. // NOTE(bill): because the arrays are sorted, you only need to check the previous element
  5428. remove_neighbouring_duplicate_entires_from_sorted_array(&c->info.init_procedures);
  5429. remove_neighbouring_duplicate_entires_from_sorted_array(&c->info.fini_procedures);
  5430. }
  5431. gb_internal void add_type_info_for_type_definitions(Checker *c) {
  5432. for_array(i, c->info.definitions) {
  5433. Entity *e = c->info.definitions[i];
  5434. if (e->kind == Entity_TypeName && e->type != nullptr) {
  5435. i64 align = type_align_of(e->type);
  5436. if (align > 0 && ptr_set_exists(&c->info.minimum_dependency_set, e)) {
  5437. add_type_info_type(&c->builtin_ctx, e->type);
  5438. }
  5439. }
  5440. }
  5441. }
  5442. gb_internal void check_walk_all_dependencies(DeclInfo *decl) {
  5443. if (decl == nullptr) {
  5444. return;
  5445. }
  5446. for (DeclInfo *child = decl->next_child; child != nullptr; child = child->next_sibling) {
  5447. check_walk_all_dependencies(child);
  5448. }
  5449. add_deps_from_child_to_parent(decl);
  5450. }
  5451. gb_internal void check_update_dependency_tree_for_procedures(Checker *c) {
  5452. mutex_lock(&c->nested_proc_lits_mutex);
  5453. for (DeclInfo *decl : c->nested_proc_lits) {
  5454. check_walk_all_dependencies(decl);
  5455. }
  5456. mutex_unlock(&c->nested_proc_lits_mutex);
  5457. for (Entity *e : c->info.entities) {
  5458. DeclInfo *decl = e->decl_info;
  5459. check_walk_all_dependencies(decl);
  5460. }
  5461. }
  5462. gb_internal void check_parsed_files(Checker *c) {
  5463. TIME_SECTION("map full filepaths to scope");
  5464. add_type_info_type(&c->builtin_ctx, t_invalid);
  5465. // Map full filepaths to Scopes
  5466. for_array(i, c->parser->packages) {
  5467. AstPackage *p = c->parser->packages[i];
  5468. Scope *scope = create_scope_from_package(&c->builtin_ctx, p);
  5469. p->decl_info = make_decl_info(scope, c->builtin_ctx.decl);
  5470. string_map_set(&c->info.packages, p->fullpath, p);
  5471. if (scope->flags&ScopeFlag_Init) {
  5472. c->info.init_package = p;
  5473. c->info.init_scope = scope;
  5474. }
  5475. if (p->kind == Package_Runtime) {
  5476. GB_ASSERT(c->info.runtime_package == nullptr);
  5477. c->info.runtime_package = p;
  5478. }
  5479. }
  5480. TIME_SECTION("init worker data");
  5481. check_init_worker_data(c);
  5482. TIME_SECTION("create file scopes");
  5483. check_create_file_scopes(c);
  5484. TIME_SECTION("collect entities");
  5485. check_collect_entities_all(c);
  5486. TIME_SECTION("export entities - pre");
  5487. check_export_entities(c);
  5488. // NOTE: Timing Section handled internally
  5489. check_import_entities(c);
  5490. TIME_SECTION("export entities - post");
  5491. check_export_entities(c);
  5492. TIME_SECTION("add entities from packages");
  5493. check_merge_queues_into_arrays(c);
  5494. TIME_SECTION("check all global entities");
  5495. check_all_global_entities(c);
  5496. TIME_SECTION("init preload");
  5497. init_preload(c);
  5498. TIME_SECTION("add global untyped expression to queue");
  5499. add_untyped_expressions(&c->info, &c->info.global_untyped);
  5500. CheckerContext prev_context = c->builtin_ctx;
  5501. defer (c->builtin_ctx = prev_context);
  5502. c->builtin_ctx.decl = make_decl_info(nullptr, nullptr);
  5503. TIME_SECTION("check procedure bodies");
  5504. check_procedure_bodies(c);
  5505. TIME_SECTION("check foreign import fullpaths");
  5506. check_foreign_import_fullpaths(c);
  5507. TIME_SECTION("add entities from procedure bodies");
  5508. check_merge_queues_into_arrays(c);
  5509. TIME_SECTION("check scope usage");
  5510. for (auto const &entry : c->info.files) {
  5511. AstFile *f = entry.value;
  5512. u64 vet_flags = build_context.vet_flags;
  5513. if (f->vet_flags_set) {
  5514. vet_flags = f->vet_flags;
  5515. }
  5516. check_scope_usage(c, f->scope, vet_flags);
  5517. }
  5518. TIME_SECTION("add basic type information");
  5519. // Add "Basic" type information
  5520. for (isize i = 0; i < Basic_COUNT; i++) {
  5521. Type *t = &basic_types[i];
  5522. if (t->Basic.size > 0 &&
  5523. (t->Basic.flags & BasicFlag_LLVM) == 0) {
  5524. add_type_info_type(&c->builtin_ctx, t);
  5525. }
  5526. }
  5527. check_merge_queues_into_arrays(c);
  5528. TIME_SECTION("check for type cycles and inline cycles");
  5529. // NOTE(bill): Check for illegal cyclic type declarations
  5530. for_array(i, c->info.definitions) {
  5531. Entity *e = c->info.definitions[i];
  5532. if (e->kind == Entity_TypeName && e->type != nullptr) {
  5533. (void)type_align_of(e->type);
  5534. } else if (e->kind == Entity_Procedure) {
  5535. DeclInfo *decl = e->decl_info;
  5536. ast_node(pl, ProcLit, decl->proc_lit);
  5537. if (pl->inlining == ProcInlining_inline) {
  5538. for (Entity *dep : decl->deps) {
  5539. if (dep == e) {
  5540. error(e->token, "Cannot inline recursive procedure '%.*s'", LIT(e->token.string));
  5541. break;
  5542. }
  5543. }
  5544. }
  5545. }
  5546. }
  5547. TIME_SECTION("check deferred procedures");
  5548. check_deferred_procedures(c);
  5549. TIME_SECTION("calculate global init order");
  5550. calculate_global_init_order(c);
  5551. TIME_SECTION("add type info for type definitions");
  5552. add_type_info_for_type_definitions(c);
  5553. check_merge_queues_into_arrays(c);
  5554. TIME_SECTION("update dependency tree for procedures");
  5555. check_update_dependency_tree_for_procedures(c);
  5556. TIME_SECTION("generate minimum dependency set");
  5557. generate_minimum_dependency_set(c, c->info.entry_point);
  5558. TIME_SECTION("check bodies have all been checked");
  5559. check_unchecked_bodies(c);
  5560. TIME_SECTION("check #soa types");
  5561. check_merge_queues_into_arrays(c);
  5562. thread_pool_wait();
  5563. TIME_SECTION("update minimum dependency set");
  5564. generate_minimum_dependency_set_internal(c, c->info.entry_point);
  5565. // NOTE(laytan): has to be ran after generate_minimum_dependency_set,
  5566. // because that collects the test procedures.
  5567. TIME_SECTION("check test procedures");
  5568. check_test_procedures(c);
  5569. check_merge_queues_into_arrays(c);
  5570. thread_pool_wait();
  5571. TIME_SECTION("check entry point");
  5572. if (build_context.build_mode == BuildMode_Executable && !build_context.no_entry_point && build_context.command_kind != Command_test) {
  5573. Scope *s = c->info.init_scope;
  5574. GB_ASSERT(s != nullptr);
  5575. GB_ASSERT(s->flags&ScopeFlag_Init);
  5576. Entity *e = scope_lookup_current(s, str_lit("main"));
  5577. if (e == nullptr) {
  5578. Token token = {};
  5579. token.pos.file_id = 0;
  5580. token.pos.line = 1;
  5581. token.pos.column = 1;
  5582. if (s->pkg->files.count > 0) {
  5583. AstFile *f = s->pkg->files[0];
  5584. if (f->tokens.count > 0) {
  5585. token = f->tokens[0];
  5586. }
  5587. }
  5588. error(token, "Undefined entry point procedure 'main'");
  5589. }
  5590. } else if (build_context.build_mode == BuildMode_DynamicLibrary && build_context.no_entry_point) {
  5591. c->info.entry_point = nullptr;
  5592. }
  5593. thread_pool_wait();
  5594. GB_ASSERT(c->procs_to_check.count == 0);
  5595. if (DEBUG_CHECK_ALL_PROCEDURES) {
  5596. TIME_SECTION("check unchecked (safety measure)");
  5597. check_safety_all_procedures_for_unchecked(c);
  5598. }
  5599. debugf("Total Procedure Bodies Checked: %td\n", total_bodies_checked.load(std::memory_order_relaxed));
  5600. TIME_SECTION("check unique package names");
  5601. check_unique_package_names(c);
  5602. TIME_SECTION("sanity checks");
  5603. check_merge_queues_into_arrays(c);
  5604. GB_ASSERT(c->info.entity_queue.count.load(std::memory_order_relaxed) == 0);
  5605. GB_ASSERT(c->info.definition_queue.count.load(std::memory_order_relaxed) == 0);
  5606. TIME_SECTION("check instrumentation calls");
  5607. {
  5608. if ((c->info.instrumentation_enter_entity != nullptr) ^
  5609. (c->info.instrumentation_exit_entity != nullptr)) {
  5610. Entity *e = c->info.instrumentation_enter_entity;
  5611. if (!e) e = c->info.instrumentation_exit_entity;
  5612. error(e->token, "Both @(instrumentation_enter) and @(instrumentation_exit) must be defined");
  5613. }
  5614. }
  5615. TIME_SECTION("add untyped expression values");
  5616. // Add untyped expression values
  5617. for (UntypedExprInfo u = {}; mpsc_dequeue(&c->global_untyped_queue, &u); /**/) {
  5618. GB_ASSERT(u.expr != nullptr && u.info != nullptr);
  5619. if (is_type_typed(u.info->type)) {
  5620. compiler_error("%s (type %s) is typed!", expr_to_string(u.expr), type_to_string(u.info->type));
  5621. }
  5622. add_type_and_value(&c->builtin_ctx, u.expr, u.info->mode, u.info->type, u.info->value);
  5623. }
  5624. TIME_SECTION("sort init and fini procedures");
  5625. check_sort_init_and_fini_procedures(c);
  5626. if (c->info.intrinsics_entry_point_usage.count > 0) {
  5627. TIME_SECTION("check intrinsics.__entry_point usage");
  5628. Ast *node = nullptr;
  5629. while (mpsc_dequeue(&c->info.intrinsics_entry_point_usage, &node)) {
  5630. if (c->info.entry_point == nullptr && node != nullptr) {
  5631. if (node->file()->pkg->kind != Package_Runtime) {
  5632. error(node, "usage of intrinsics.__entry_point will be a no-op");
  5633. }
  5634. }
  5635. }
  5636. }
  5637. TIME_SECTION("type check finish");
  5638. }