ParseHelper.cpp 397 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783
  1. //
  2. // Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
  3. // Copyright (C) 2012-2015 LunarG, Inc.
  4. // Copyright (C) 2015-2018 Google, Inc.
  5. // Copyright (C) 2017, 2019 ARM Limited.
  6. // Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
  7. //
  8. // All rights reserved.
  9. //
  10. // Redistribution and use in source and binary forms, with or without
  11. // modification, are permitted provided that the following conditions
  12. // are met:
  13. //
  14. // Redistributions of source code must retain the above copyright
  15. // notice, this list of conditions and the following disclaimer.
  16. //
  17. // Redistributions in binary form must reproduce the above
  18. // copyright notice, this list of conditions and the following
  19. // disclaimer in the documentation and/or other materials provided
  20. // with the distribution.
  21. //
  22. // Neither the name of 3Dlabs Inc. Ltd. nor the names of its
  23. // contributors may be used to endorse or promote products derived
  24. // from this software without specific prior written permission.
  25. //
  26. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  27. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  28. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  29. // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  30. // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  31. // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  32. // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  33. // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  34. // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  35. // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  36. // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  37. // POSSIBILITY OF SUCH DAMAGE.
  38. //
  39. #include "ParseHelper.h"
  40. #include "Scan.h"
  41. #include "../OSDependent/osinclude.h"
  42. #include <algorithm>
  43. #include "preprocessor/PpContext.h"
  44. extern int yyparse(glslang::TParseContext*);
  45. namespace glslang {
  46. TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, bool parsingBuiltins,
  47. int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language,
  48. TInfoSink& infoSink, bool forwardCompatible, EShMessages messages,
  49. const TString* entryPoint) :
  50. TParseContextBase(symbolTable, interm, parsingBuiltins, version, profile, spvVersion, language,
  51. infoSink, forwardCompatible, messages, entryPoint),
  52. inMain(false),
  53. blockName(nullptr),
  54. limits(resources.limits)
  55. #ifndef GLSLANG_WEB
  56. ,
  57. atomicUintOffsets(nullptr), anyIndexLimits(false)
  58. #endif
  59. {
  60. // decide whether precision qualifiers should be ignored or respected
  61. if (isEsProfile() || spvVersion.vulkan > 0) {
  62. precisionManager.respectPrecisionQualifiers();
  63. if (! parsingBuiltins && language == EShLangFragment && !isEsProfile() && spvVersion.vulkan > 0)
  64. precisionManager.warnAboutDefaults();
  65. }
  66. setPrecisionDefaults();
  67. globalUniformDefaults.clear();
  68. globalUniformDefaults.layoutMatrix = ElmColumnMajor;
  69. globalUniformDefaults.layoutPacking = spvVersion.spv != 0 ? ElpStd140 : ElpShared;
  70. globalBufferDefaults.clear();
  71. globalBufferDefaults.layoutMatrix = ElmColumnMajor;
  72. globalBufferDefaults.layoutPacking = spvVersion.spv != 0 ? ElpStd430 : ElpShared;
  73. // use storage buffer on SPIR-V 1.3 and up
  74. if (spvVersion.spv >= EShTargetSpv_1_3)
  75. intermediate.setUseStorageBuffer();
  76. globalInputDefaults.clear();
  77. globalOutputDefaults.clear();
  78. globalSharedDefaults.clear();
  79. globalSharedDefaults.layoutMatrix = ElmColumnMajor;
  80. globalSharedDefaults.layoutPacking = ElpStd430;
  81. #ifndef GLSLANG_WEB
  82. // "Shaders in the transform
  83. // feedback capturing mode have an initial global default of
  84. // layout(xfb_buffer = 0) out;"
  85. if (language == EShLangVertex ||
  86. language == EShLangTessControl ||
  87. language == EShLangTessEvaluation ||
  88. language == EShLangGeometry)
  89. globalOutputDefaults.layoutXfbBuffer = 0;
  90. if (language == EShLangGeometry)
  91. globalOutputDefaults.layoutStream = 0;
  92. #endif
  93. if (entryPoint != nullptr && entryPoint->size() > 0 && *entryPoint != "main")
  94. infoSink.info.message(EPrefixError, "Source entry point must be \"main\"");
  95. }
  96. TParseContext::~TParseContext()
  97. {
  98. #ifndef GLSLANG_WEB
  99. delete [] atomicUintOffsets;
  100. #endif
  101. }
  102. // Set up all default precisions as needed by the current environment.
  103. // Intended just as a TParseContext constructor helper.
  104. void TParseContext::setPrecisionDefaults()
  105. {
  106. // Set all precision defaults to EpqNone, which is correct for all types
  107. // when not obeying precision qualifiers, and correct for types that don't
  108. // have defaults (thus getting an error on use) when obeying precision
  109. // qualifiers.
  110. for (int type = 0; type < EbtNumTypes; ++type)
  111. defaultPrecision[type] = EpqNone;
  112. for (int type = 0; type < maxSamplerIndex; ++type)
  113. defaultSamplerPrecision[type] = EpqNone;
  114. // replace with real precision defaults for those that have them
  115. if (obeyPrecisionQualifiers()) {
  116. if (isEsProfile()) {
  117. // Most don't have defaults, a few default to lowp.
  118. TSampler sampler;
  119. sampler.set(EbtFloat, Esd2D);
  120. defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow;
  121. sampler.set(EbtFloat, EsdCube);
  122. defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow;
  123. sampler.set(EbtFloat, Esd2D);
  124. sampler.setExternal(true);
  125. defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow;
  126. }
  127. // If we are parsing built-in computational variables/functions, it is meaningful to record
  128. // whether the built-in has no precision qualifier, as that ambiguity
  129. // is used to resolve the precision from the supplied arguments/operands instead.
  130. // So, we don't actually want to replace EpqNone with a default precision for built-ins.
  131. if (! parsingBuiltins) {
  132. if (isEsProfile() && language == EShLangFragment) {
  133. defaultPrecision[EbtInt] = EpqMedium;
  134. defaultPrecision[EbtUint] = EpqMedium;
  135. } else {
  136. defaultPrecision[EbtInt] = EpqHigh;
  137. defaultPrecision[EbtUint] = EpqHigh;
  138. defaultPrecision[EbtFloat] = EpqHigh;
  139. }
  140. if (!isEsProfile()) {
  141. // Non-ES profile
  142. // All sampler precisions default to highp.
  143. for (int type = 0; type < maxSamplerIndex; ++type)
  144. defaultSamplerPrecision[type] = EpqHigh;
  145. }
  146. }
  147. defaultPrecision[EbtSampler] = EpqLow;
  148. defaultPrecision[EbtAtomicUint] = EpqHigh;
  149. }
  150. }
  151. void TParseContext::setLimits(const TBuiltInResource& r)
  152. {
  153. resources = r;
  154. intermediate.setLimits(r);
  155. #ifndef GLSLANG_WEB
  156. anyIndexLimits = ! limits.generalAttributeMatrixVectorIndexing ||
  157. ! limits.generalConstantMatrixVectorIndexing ||
  158. ! limits.generalSamplerIndexing ||
  159. ! limits.generalUniformIndexing ||
  160. ! limits.generalVariableIndexing ||
  161. ! limits.generalVaryingIndexing;
  162. // "Each binding point tracks its own current default offset for
  163. // inheritance of subsequent variables using the same binding. The initial state of compilation is that all
  164. // binding points have an offset of 0."
  165. atomicUintOffsets = new int[resources.maxAtomicCounterBindings];
  166. for (int b = 0; b < resources.maxAtomicCounterBindings; ++b)
  167. atomicUintOffsets[b] = 0;
  168. #endif
  169. }
  170. //
  171. // Parse an array of strings using yyparse, going through the
  172. // preprocessor to tokenize the shader strings, then through
  173. // the GLSL scanner.
  174. //
  175. // Returns true for successful acceptance of the shader, false if any errors.
  176. //
  177. bool TParseContext::parseShaderStrings(TPpContext& ppContext, TInputScanner& input, bool versionWillBeError)
  178. {
  179. currentScanner = &input;
  180. ppContext.setInput(input, versionWillBeError);
  181. yyparse(this);
  182. finish();
  183. return numErrors == 0;
  184. }
  185. // This is called from bison when it has a parse (syntax) error
  186. // Note though that to stop cascading errors, we set EOF, which
  187. // will usually cause a syntax error, so be more accurate that
  188. // compilation is terminating.
  189. void TParseContext::parserError(const char* s)
  190. {
  191. if (! getScanner()->atEndOfInput() || numErrors == 0)
  192. error(getCurrentLoc(), "", "", s, "");
  193. else
  194. error(getCurrentLoc(), "compilation terminated", "", "");
  195. }
  196. void TParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>& tokens)
  197. {
  198. #ifndef GLSLANG_WEB
  199. if (pragmaCallback)
  200. pragmaCallback(loc.line, tokens);
  201. if (tokens.size() == 0)
  202. return;
  203. if (tokens[0].compare("optimize") == 0) {
  204. if (tokens.size() != 4) {
  205. error(loc, "optimize pragma syntax is incorrect", "#pragma", "");
  206. return;
  207. }
  208. if (tokens[1].compare("(") != 0) {
  209. error(loc, "\"(\" expected after 'optimize' keyword", "#pragma", "");
  210. return;
  211. }
  212. if (tokens[2].compare("on") == 0)
  213. contextPragma.optimize = true;
  214. else if (tokens[2].compare("off") == 0)
  215. contextPragma.optimize = false;
  216. else {
  217. if(relaxedErrors())
  218. // If an implementation does not recognize the tokens following #pragma, then it will ignore that pragma.
  219. warn(loc, "\"on\" or \"off\" expected after '(' for 'optimize' pragma", "#pragma", "");
  220. return;
  221. }
  222. if (tokens[3].compare(")") != 0) {
  223. error(loc, "\")\" expected to end 'optimize' pragma", "#pragma", "");
  224. return;
  225. }
  226. } else if (tokens[0].compare("debug") == 0) {
  227. if (tokens.size() != 4) {
  228. error(loc, "debug pragma syntax is incorrect", "#pragma", "");
  229. return;
  230. }
  231. if (tokens[1].compare("(") != 0) {
  232. error(loc, "\"(\" expected after 'debug' keyword", "#pragma", "");
  233. return;
  234. }
  235. if (tokens[2].compare("on") == 0)
  236. contextPragma.debug = true;
  237. else if (tokens[2].compare("off") == 0)
  238. contextPragma.debug = false;
  239. else {
  240. if(relaxedErrors())
  241. // If an implementation does not recognize the tokens following #pragma, then it will ignore that pragma.
  242. warn(loc, "\"on\" or \"off\" expected after '(' for 'debug' pragma", "#pragma", "");
  243. return;
  244. }
  245. if (tokens[3].compare(")") != 0) {
  246. error(loc, "\")\" expected to end 'debug' pragma", "#pragma", "");
  247. return;
  248. }
  249. } else if (spvVersion.spv > 0 && tokens[0].compare("use_storage_buffer") == 0) {
  250. if (tokens.size() != 1)
  251. error(loc, "extra tokens", "#pragma", "");
  252. intermediate.setUseStorageBuffer();
  253. } else if (spvVersion.spv > 0 && tokens[0].compare("use_vulkan_memory_model") == 0) {
  254. if (tokens.size() != 1)
  255. error(loc, "extra tokens", "#pragma", "");
  256. intermediate.setUseVulkanMemoryModel();
  257. } else if (spvVersion.spv > 0 && tokens[0].compare("use_variable_pointers") == 0) {
  258. if (tokens.size() != 1)
  259. error(loc, "extra tokens", "#pragma", "");
  260. if (spvVersion.spv < glslang::EShTargetSpv_1_3)
  261. error(loc, "requires SPIR-V 1.3", "#pragma use_variable_pointers", "");
  262. intermediate.setUseVariablePointers();
  263. } else if (tokens[0].compare("once") == 0) {
  264. warn(loc, "not implemented", "#pragma once", "");
  265. } else if (tokens[0].compare("glslang_binary_double_output") == 0)
  266. intermediate.setBinaryDoubleOutput();
  267. #endif
  268. }
  269. //
  270. // Handle seeing a variable identifier in the grammar.
  271. //
  272. TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symbol, const TString* string)
  273. {
  274. TIntermTyped* node = nullptr;
  275. // Error check for requiring specific extensions present.
  276. if (symbol && symbol->getNumExtensions())
  277. requireExtensions(loc, symbol->getNumExtensions(), symbol->getExtensions(), symbol->getName().c_str());
  278. #ifndef GLSLANG_WEB
  279. if (symbol && symbol->isReadOnly()) {
  280. // All shared things containing an unsized array must be copied up
  281. // on first use, so that all future references will share its array structure,
  282. // so that editing the implicit size will effect all nodes consuming it,
  283. // and so that editing the implicit size won't change the shared one.
  284. //
  285. // If this is a variable or a block, check it and all it contains, but if this
  286. // is a member of an anonymous block, check the whole block, as the whole block
  287. // will need to be copied up if it contains an unsized array.
  288. //
  289. // This check is being done before the block-name check further down, so guard
  290. // for that too.
  291. if (!symbol->getType().isUnusableName()) {
  292. if (symbol->getType().containsUnsizedArray() ||
  293. (symbol->getAsAnonMember() &&
  294. symbol->getAsAnonMember()->getAnonContainer().getType().containsUnsizedArray()))
  295. makeEditable(symbol);
  296. }
  297. }
  298. #endif
  299. const TVariable* variable;
  300. const TAnonMember* anon = symbol ? symbol->getAsAnonMember() : nullptr;
  301. if (anon) {
  302. // It was a member of an anonymous container.
  303. // Create a subtree for its dereference.
  304. variable = anon->getAnonContainer().getAsVariable();
  305. TIntermTyped* container = intermediate.addSymbol(*variable, loc);
  306. TIntermTyped* constNode = intermediate.addConstantUnion(anon->getMemberNumber(), loc);
  307. node = intermediate.addIndex(EOpIndexDirectStruct, container, constNode, loc);
  308. node->setType(*(*variable->getType().getStruct())[anon->getMemberNumber()].type);
  309. if (node->getType().hiddenMember())
  310. error(loc, "member of nameless block was not redeclared", string->c_str(), "");
  311. } else {
  312. // Not a member of an anonymous container.
  313. // The symbol table search was done in the lexical phase.
  314. // See if it was a variable.
  315. variable = symbol ? symbol->getAsVariable() : nullptr;
  316. if (variable) {
  317. if (variable->getType().isUnusableName()) {
  318. error(loc, "cannot be used (maybe an instance name is needed)", string->c_str(), "");
  319. variable = nullptr;
  320. }
  321. } else {
  322. if (symbol)
  323. error(loc, "variable name expected", string->c_str(), "");
  324. }
  325. // Recovery, if it wasn't found or was not a variable.
  326. if (! variable)
  327. variable = new TVariable(string, TType(EbtVoid));
  328. if (variable->getType().getQualifier().isFrontEndConstant())
  329. node = intermediate.addConstantUnion(variable->getConstArray(), variable->getType(), loc);
  330. else
  331. node = intermediate.addSymbol(*variable, loc);
  332. }
  333. if (variable->getType().getQualifier().isIo())
  334. intermediate.addIoAccessed(*string);
  335. if (variable->getType().isReference() &&
  336. variable->getType().getQualifier().bufferReferenceNeedsVulkanMemoryModel()) {
  337. intermediate.setUseVulkanMemoryModel();
  338. }
  339. return node;
  340. }
  341. //
  342. // Handle seeing a base[index] dereference in the grammar.
  343. //
  344. TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIntermTyped* base, TIntermTyped* index)
  345. {
  346. int indexValue = 0;
  347. if (index->getQualifier().isFrontEndConstant())
  348. indexValue = index->getAsConstantUnion()->getConstArray()[0].getIConst();
  349. // basic type checks...
  350. variableCheck(base);
  351. if (! base->isArray() && ! base->isMatrix() && ! base->isVector() && ! base->getType().isCoopMat() &&
  352. ! base->isReference()) {
  353. if (base->getAsSymbolNode())
  354. error(loc, " left of '[' is not of type array, matrix, or vector ", base->getAsSymbolNode()->getName().c_str(), "");
  355. else
  356. error(loc, " left of '[' is not of type array, matrix, or vector ", "expression", "");
  357. // Insert dummy error-recovery result
  358. return intermediate.addConstantUnion(0.0, EbtFloat, loc);
  359. }
  360. if (!base->isArray() && base->isVector()) {
  361. if (base->getType().contains16BitFloat())
  362. requireFloat16Arithmetic(loc, "[", "does not operate on types containing float16");
  363. if (base->getType().contains16BitInt())
  364. requireInt16Arithmetic(loc, "[", "does not operate on types containing (u)int16");
  365. if (base->getType().contains8BitInt())
  366. requireInt8Arithmetic(loc, "[", "does not operate on types containing (u)int8");
  367. }
  368. // check for constant folding
  369. if (base->getType().getQualifier().isFrontEndConstant() && index->getQualifier().isFrontEndConstant()) {
  370. // both base and index are front-end constants
  371. checkIndex(loc, base->getType(), indexValue);
  372. return intermediate.foldDereference(base, indexValue, loc);
  373. }
  374. // at least one of base and index is not a front-end constant variable...
  375. TIntermTyped* result = nullptr;
  376. #ifndef GLSLANG_WEB
  377. if (base->isReference() && ! base->isArray()) {
  378. requireExtensions(loc, 1, &E_GL_EXT_buffer_reference2, "buffer reference indexing");
  379. if (base->getType().getReferentType()->containsUnsizedArray()) {
  380. error(loc, "cannot index reference to buffer containing an unsized array", "", "");
  381. result = nullptr;
  382. } else {
  383. result = intermediate.addBinaryMath(EOpAdd, base, index, loc);
  384. if (result != nullptr)
  385. result->setType(base->getType());
  386. }
  387. if (result == nullptr) {
  388. error(loc, "cannot index buffer reference", "", "");
  389. result = intermediate.addConstantUnion(0.0, EbtFloat, loc);
  390. }
  391. return result;
  392. }
  393. if (base->getAsSymbolNode() && isIoResizeArray(base->getType()))
  394. handleIoResizeArrayAccess(loc, base);
  395. #endif
  396. if (index->getQualifier().isFrontEndConstant())
  397. checkIndex(loc, base->getType(), indexValue);
  398. if (index->getQualifier().isFrontEndConstant()) {
  399. #ifndef GLSLANG_WEB
  400. if (base->getType().isUnsizedArray()) {
  401. base->getWritableType().updateImplicitArraySize(indexValue + 1);
  402. // For 2D per-view builtin arrays, update the inner dimension size in parent type
  403. if (base->getQualifier().isPerView() && base->getQualifier().builtIn != EbvNone) {
  404. TIntermBinary* binaryNode = base->getAsBinaryNode();
  405. if (binaryNode) {
  406. TType& leftType = binaryNode->getLeft()->getWritableType();
  407. TArraySizes& arraySizes = *leftType.getArraySizes();
  408. assert(arraySizes.getNumDims() == 2);
  409. arraySizes.setDimSize(1, std::max(arraySizes.getDimSize(1), indexValue + 1));
  410. }
  411. }
  412. } else
  413. #endif
  414. checkIndex(loc, base->getType(), indexValue);
  415. result = intermediate.addIndex(EOpIndexDirect, base, index, loc);
  416. } else {
  417. #ifndef GLSLANG_WEB
  418. if (base->getType().isUnsizedArray()) {
  419. // we have a variable index into an unsized array, which is okay,
  420. // depending on the situation
  421. if (base->getAsSymbolNode() && isIoResizeArray(base->getType()))
  422. error(loc, "", "[", "array must be sized by a redeclaration or layout qualifier before being indexed with a variable");
  423. else {
  424. // it is okay for a run-time sized array
  425. checkRuntimeSizable(loc, *base);
  426. }
  427. base->getWritableType().setArrayVariablyIndexed();
  428. }
  429. #endif
  430. if (base->getBasicType() == EbtBlock) {
  431. if (base->getQualifier().storage == EvqBuffer)
  432. requireProfile(base->getLoc(), ~EEsProfile, "variable indexing buffer block array");
  433. else if (base->getQualifier().storage == EvqUniform)
  434. profileRequires(base->getLoc(), EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5,
  435. "variable indexing uniform block array");
  436. else {
  437. // input/output blocks either don't exist or can't be variably indexed
  438. }
  439. } else if (language == EShLangFragment && base->getQualifier().isPipeOutput())
  440. requireProfile(base->getLoc(), ~EEsProfile, "variable indexing fragment shader output array");
  441. else if (base->getBasicType() == EbtSampler && version >= 130) {
  442. const char* explanation = "variable indexing sampler array";
  443. requireProfile(base->getLoc(), EEsProfile | ECoreProfile | ECompatibilityProfile, explanation);
  444. profileRequires(base->getLoc(), EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5, explanation);
  445. profileRequires(base->getLoc(), ECoreProfile | ECompatibilityProfile, 400, nullptr, explanation);
  446. }
  447. result = intermediate.addIndex(EOpIndexIndirect, base, index, loc);
  448. }
  449. // Insert valid dereferenced result type
  450. TType newType(base->getType(), 0);
  451. if (base->getType().getQualifier().isConstant() && index->getQualifier().isConstant()) {
  452. newType.getQualifier().storage = EvqConst;
  453. // If base or index is a specialization constant, the result should also be a specialization constant.
  454. if (base->getType().getQualifier().isSpecConstant() || index->getQualifier().isSpecConstant()) {
  455. newType.getQualifier().makeSpecConstant();
  456. }
  457. } else {
  458. newType.getQualifier().storage = EvqTemporary;
  459. newType.getQualifier().specConstant = false;
  460. }
  461. result->setType(newType);
  462. #ifndef GLSLANG_WEB
  463. inheritMemoryQualifiers(base->getQualifier(), result->getWritableType().getQualifier());
  464. // Propagate nonuniform
  465. if (base->getQualifier().isNonUniform() || index->getQualifier().isNonUniform())
  466. result->getWritableType().getQualifier().nonUniform = true;
  467. if (anyIndexLimits)
  468. handleIndexLimits(loc, base, index);
  469. #endif
  470. return result;
  471. }
  472. #ifndef GLSLANG_WEB
  473. // for ES 2.0 (version 100) limitations for almost all index operations except vertex-shader uniforms
  474. void TParseContext::handleIndexLimits(const TSourceLoc& /*loc*/, TIntermTyped* base, TIntermTyped* index)
  475. {
  476. if ((! limits.generalSamplerIndexing && base->getBasicType() == EbtSampler) ||
  477. (! limits.generalUniformIndexing && base->getQualifier().isUniformOrBuffer() && language != EShLangVertex) ||
  478. (! limits.generalAttributeMatrixVectorIndexing && base->getQualifier().isPipeInput() && language == EShLangVertex && (base->getType().isMatrix() || base->getType().isVector())) ||
  479. (! limits.generalConstantMatrixVectorIndexing && base->getAsConstantUnion()) ||
  480. (! limits.generalVariableIndexing && ! base->getType().getQualifier().isUniformOrBuffer() &&
  481. ! base->getType().getQualifier().isPipeInput() &&
  482. ! base->getType().getQualifier().isPipeOutput() &&
  483. ! base->getType().getQualifier().isConstant()) ||
  484. (! limits.generalVaryingIndexing && (base->getType().getQualifier().isPipeInput() ||
  485. base->getType().getQualifier().isPipeOutput()))) {
  486. // it's too early to know what the inductive variables are, save it for post processing
  487. needsIndexLimitationChecking.push_back(index);
  488. }
  489. }
  490. // Make a shared symbol have a non-shared version that can be edited by the current
  491. // compile, such that editing its type will not change the shared version and will
  492. // effect all nodes sharing it.
  493. void TParseContext::makeEditable(TSymbol*& symbol)
  494. {
  495. TParseContextBase::makeEditable(symbol);
  496. // See if it's tied to IO resizing
  497. if (isIoResizeArray(symbol->getType()))
  498. ioArraySymbolResizeList.push_back(symbol);
  499. }
  500. // Return true if this is a geometry shader input array or tessellation control output array
  501. // or mesh shader output array.
  502. bool TParseContext::isIoResizeArray(const TType& type) const
  503. {
  504. return type.isArray() &&
  505. ((language == EShLangGeometry && type.getQualifier().storage == EvqVaryingIn) ||
  506. (language == EShLangTessControl && type.getQualifier().storage == EvqVaryingOut &&
  507. ! type.getQualifier().patch) ||
  508. (language == EShLangFragment && type.getQualifier().storage == EvqVaryingIn &&
  509. type.getQualifier().pervertexNV) ||
  510. (language == EShLangMeshNV && type.getQualifier().storage == EvqVaryingOut &&
  511. !type.getQualifier().perTaskNV));
  512. }
  513. // If an array is not isIoResizeArray() but is an io array, make sure it has the right size
  514. void TParseContext::fixIoArraySize(const TSourceLoc& loc, TType& type)
  515. {
  516. if (! type.isArray() || type.getQualifier().patch || symbolTable.atBuiltInLevel())
  517. return;
  518. assert(! isIoResizeArray(type));
  519. if (type.getQualifier().storage != EvqVaryingIn || type.getQualifier().patch)
  520. return;
  521. if (language == EShLangTessControl || language == EShLangTessEvaluation) {
  522. if (type.getOuterArraySize() != resources.maxPatchVertices) {
  523. if (type.isSizedArray())
  524. error(loc, "tessellation input array size must be gl_MaxPatchVertices or implicitly sized", "[]", "");
  525. type.changeOuterArraySize(resources.maxPatchVertices);
  526. }
  527. }
  528. }
  529. // Issue any errors if the non-array object is missing arrayness WRT
  530. // shader I/O that has array requirements.
  531. // All arrayness checking is handled in array paths, this is for
  532. void TParseContext::ioArrayCheck(const TSourceLoc& loc, const TType& type, const TString& identifier)
  533. {
  534. if (! type.isArray() && ! symbolTable.atBuiltInLevel()) {
  535. if (type.getQualifier().isArrayedIo(language) && !type.getQualifier().layoutPassthrough)
  536. error(loc, "type must be an array:", type.getStorageQualifierString(), identifier.c_str());
  537. }
  538. }
  539. // Handle a dereference of a geometry shader input array or tessellation control output array.
  540. // See ioArraySymbolResizeList comment in ParseHelper.h.
  541. //
  542. void TParseContext::handleIoResizeArrayAccess(const TSourceLoc& /*loc*/, TIntermTyped* base)
  543. {
  544. TIntermSymbol* symbolNode = base->getAsSymbolNode();
  545. assert(symbolNode);
  546. if (! symbolNode)
  547. return;
  548. // fix array size, if it can be fixed and needs to be fixed (will allow variable indexing)
  549. if (symbolNode->getType().isUnsizedArray()) {
  550. int newSize = getIoArrayImplicitSize(symbolNode->getType().getQualifier());
  551. if (newSize > 0)
  552. symbolNode->getWritableType().changeOuterArraySize(newSize);
  553. }
  554. }
  555. // If there has been an input primitive declaration (geometry shader) or an output
  556. // number of vertices declaration(tessellation shader), make sure all input array types
  557. // match it in size. Types come either from nodes in the AST or symbols in the
  558. // symbol table.
  559. //
  560. // Types without an array size will be given one.
  561. // Types already having a size that is wrong will get an error.
  562. //
  563. void TParseContext::checkIoArraysConsistency(const TSourceLoc &loc, bool tailOnly)
  564. {
  565. int requiredSize = 0;
  566. TString featureString;
  567. size_t listSize = ioArraySymbolResizeList.size();
  568. size_t i = 0;
  569. // If tailOnly = true, only check the last array symbol in the list.
  570. if (tailOnly) {
  571. i = listSize - 1;
  572. }
  573. for (bool firstIteration = true; i < listSize; ++i) {
  574. TType &type = ioArraySymbolResizeList[i]->getWritableType();
  575. // As I/O array sizes don't change, fetch requiredSize only once,
  576. // except for mesh shaders which could have different I/O array sizes based on type qualifiers.
  577. if (firstIteration || (language == EShLangMeshNV)) {
  578. requiredSize = getIoArrayImplicitSize(type.getQualifier(), &featureString);
  579. if (requiredSize == 0)
  580. break;
  581. firstIteration = false;
  582. }
  583. checkIoArrayConsistency(loc, requiredSize, featureString.c_str(), type,
  584. ioArraySymbolResizeList[i]->getName());
  585. }
  586. }
  587. int TParseContext::getIoArrayImplicitSize(const TQualifier &qualifier, TString *featureString) const
  588. {
  589. int expectedSize = 0;
  590. TString str = "unknown";
  591. unsigned int maxVertices = intermediate.getVertices() != TQualifier::layoutNotSet ? intermediate.getVertices() : 0;
  592. if (language == EShLangGeometry) {
  593. expectedSize = TQualifier::mapGeometryToSize(intermediate.getInputPrimitive());
  594. str = TQualifier::getGeometryString(intermediate.getInputPrimitive());
  595. }
  596. else if (language == EShLangTessControl) {
  597. expectedSize = maxVertices;
  598. str = "vertices";
  599. } else if (language == EShLangFragment) {
  600. // Number of vertices for Fragment shader is always three.
  601. expectedSize = 3;
  602. str = "vertices";
  603. } else if (language == EShLangMeshNV) {
  604. unsigned int maxPrimitives =
  605. intermediate.getPrimitives() != TQualifier::layoutNotSet ? intermediate.getPrimitives() : 0;
  606. if (qualifier.builtIn == EbvPrimitiveIndicesNV) {
  607. expectedSize = maxPrimitives * TQualifier::mapGeometryToSize(intermediate.getOutputPrimitive());
  608. str = "max_primitives*";
  609. str += TQualifier::getGeometryString(intermediate.getOutputPrimitive());
  610. }
  611. else if (qualifier.isPerPrimitive()) {
  612. expectedSize = maxPrimitives;
  613. str = "max_primitives";
  614. }
  615. else {
  616. expectedSize = maxVertices;
  617. str = "max_vertices";
  618. }
  619. }
  620. if (featureString)
  621. *featureString = str;
  622. return expectedSize;
  623. }
  624. void TParseContext::checkIoArrayConsistency(const TSourceLoc& loc, int requiredSize, const char* feature, TType& type, const TString& name)
  625. {
  626. if (type.isUnsizedArray())
  627. type.changeOuterArraySize(requiredSize);
  628. else if (type.getOuterArraySize() != requiredSize) {
  629. if (language == EShLangGeometry)
  630. error(loc, "inconsistent input primitive for array size of", feature, name.c_str());
  631. else if (language == EShLangTessControl)
  632. error(loc, "inconsistent output number of vertices for array size of", feature, name.c_str());
  633. else if (language == EShLangFragment) {
  634. if (type.getOuterArraySize() > requiredSize)
  635. error(loc, " cannot be greater than 3 for pervertexNV", feature, name.c_str());
  636. }
  637. else if (language == EShLangMeshNV)
  638. error(loc, "inconsistent output array size of", feature, name.c_str());
  639. else
  640. assert(0);
  641. }
  642. }
  643. #endif // GLSLANG_WEB
  644. // Handle seeing a binary node with a math operation.
  645. // Returns nullptr if not semantically allowed.
  646. TIntermTyped* TParseContext::handleBinaryMath(const TSourceLoc& loc, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right)
  647. {
  648. rValueErrorCheck(loc, str, left->getAsTyped());
  649. rValueErrorCheck(loc, str, right->getAsTyped());
  650. bool allowed = true;
  651. switch (op) {
  652. // TODO: Bring more source language-specific checks up from intermediate.cpp
  653. // to the specific parse helpers for that source language.
  654. case EOpLessThan:
  655. case EOpGreaterThan:
  656. case EOpLessThanEqual:
  657. case EOpGreaterThanEqual:
  658. if (! left->isScalar() || ! right->isScalar())
  659. allowed = false;
  660. break;
  661. default:
  662. break;
  663. }
  664. if (((left->getType().contains16BitFloat() || right->getType().contains16BitFloat()) && !float16Arithmetic()) ||
  665. ((left->getType().contains16BitInt() || right->getType().contains16BitInt()) && !int16Arithmetic()) ||
  666. ((left->getType().contains8BitInt() || right->getType().contains8BitInt()) && !int8Arithmetic())) {
  667. allowed = false;
  668. }
  669. TIntermTyped* result = nullptr;
  670. if (allowed) {
  671. if ((left->isReference() || right->isReference()))
  672. requireExtensions(loc, 1, &E_GL_EXT_buffer_reference2, "buffer reference math");
  673. result = intermediate.addBinaryMath(op, left, right, loc);
  674. }
  675. if (result == nullptr)
  676. binaryOpError(loc, str, left->getCompleteString(), right->getCompleteString());
  677. return result;
  678. }
  679. // Handle seeing a unary node with a math operation.
  680. TIntermTyped* TParseContext::handleUnaryMath(const TSourceLoc& loc, const char* str, TOperator op, TIntermTyped* childNode)
  681. {
  682. rValueErrorCheck(loc, str, childNode);
  683. bool allowed = true;
  684. if ((childNode->getType().contains16BitFloat() && !float16Arithmetic()) ||
  685. (childNode->getType().contains16BitInt() && !int16Arithmetic()) ||
  686. (childNode->getType().contains8BitInt() && !int8Arithmetic())) {
  687. allowed = false;
  688. }
  689. TIntermTyped* result = nullptr;
  690. if (allowed)
  691. result = intermediate.addUnaryMath(op, childNode, loc);
  692. if (result)
  693. return result;
  694. else
  695. unaryOpError(loc, str, childNode->getCompleteString());
  696. return childNode;
  697. }
  698. //
  699. // Handle seeing a base.field dereference in the grammar.
  700. //
  701. TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TIntermTyped* base, const TString& field)
  702. {
  703. variableCheck(base);
  704. //
  705. // .length() can't be resolved until we later see the function-calling syntax.
  706. // Save away the name in the AST for now. Processing is completed in
  707. // handleLengthMethod().
  708. //
  709. if (field == "length") {
  710. if (base->isArray()) {
  711. profileRequires(loc, ENoProfile, 120, E_GL_3DL_array_objects, ".length");
  712. profileRequires(loc, EEsProfile, 300, nullptr, ".length");
  713. } else if (base->isVector() || base->isMatrix()) {
  714. const char* feature = ".length() on vectors and matrices";
  715. requireProfile(loc, ~EEsProfile, feature);
  716. profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, feature);
  717. } else if (!base->getType().isCoopMat()) {
  718. error(loc, "does not operate on this type:", field.c_str(), base->getType().getCompleteString().c_str());
  719. return base;
  720. }
  721. return intermediate.addMethod(base, TType(EbtInt), &field, loc);
  722. }
  723. // It's not .length() if we get to here.
  724. if (base->isArray()) {
  725. error(loc, "cannot apply to an array:", ".", field.c_str());
  726. return base;
  727. }
  728. if (base->getType().isCoopMat()) {
  729. error(loc, "cannot apply to a cooperative matrix type:", ".", field.c_str());
  730. return base;
  731. }
  732. // It's neither an array nor .length() if we get here,
  733. // leaving swizzles and struct/block dereferences.
  734. TIntermTyped* result = base;
  735. if ((base->isVector() || base->isScalar()) &&
  736. (base->isFloatingDomain() || base->isIntegerDomain() || base->getBasicType() == EbtBool)) {
  737. result = handleDotSwizzle(loc, base, field);
  738. } else if (base->isStruct() || base->isReference()) {
  739. const TTypeList* fields = base->isReference() ?
  740. base->getType().getReferentType()->getStruct() :
  741. base->getType().getStruct();
  742. bool fieldFound = false;
  743. int member;
  744. for (member = 0; member < (int)fields->size(); ++member) {
  745. if ((*fields)[member].type->getFieldName() == field) {
  746. fieldFound = true;
  747. break;
  748. }
  749. }
  750. if (fieldFound) {
  751. if (base->getType().getQualifier().isFrontEndConstant())
  752. result = intermediate.foldDereference(base, member, loc);
  753. else {
  754. blockMemberExtensionCheck(loc, base, member, field);
  755. TIntermTyped* index = intermediate.addConstantUnion(member, loc);
  756. result = intermediate.addIndex(EOpIndexDirectStruct, base, index, loc);
  757. result->setType(*(*fields)[member].type);
  758. if ((*fields)[member].type->getQualifier().isIo())
  759. intermediate.addIoAccessed(field);
  760. }
  761. inheritMemoryQualifiers(base->getQualifier(), result->getWritableType().getQualifier());
  762. } else
  763. error(loc, "no such field in structure", field.c_str(), "");
  764. } else
  765. error(loc, "does not apply to this type:", field.c_str(), base->getType().getCompleteString().c_str());
  766. // Propagate noContraction up the dereference chain
  767. if (base->getQualifier().isNoContraction())
  768. result->getWritableType().getQualifier().setNoContraction();
  769. // Propagate nonuniform
  770. if (base->getQualifier().isNonUniform())
  771. result->getWritableType().getQualifier().nonUniform = true;
  772. return result;
  773. }
  774. //
  775. // Handle seeing a base.swizzle, a subset of base.identifier in the grammar.
  776. //
  777. TIntermTyped* TParseContext::handleDotSwizzle(const TSourceLoc& loc, TIntermTyped* base, const TString& field)
  778. {
  779. TIntermTyped* result = base;
  780. if (base->isScalar()) {
  781. const char* dotFeature = "scalar swizzle";
  782. requireProfile(loc, ~EEsProfile, dotFeature);
  783. profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, dotFeature);
  784. }
  785. TSwizzleSelectors<TVectorSelector> selectors;
  786. parseSwizzleSelector(loc, field, base->getVectorSize(), selectors);
  787. if (base->isVector() && selectors.size() != 1 && base->getType().contains16BitFloat())
  788. requireFloat16Arithmetic(loc, ".", "can't swizzle types containing float16");
  789. if (base->isVector() && selectors.size() != 1 && base->getType().contains16BitInt())
  790. requireInt16Arithmetic(loc, ".", "can't swizzle types containing (u)int16");
  791. if (base->isVector() && selectors.size() != 1 && base->getType().contains8BitInt())
  792. requireInt8Arithmetic(loc, ".", "can't swizzle types containing (u)int8");
  793. if (base->isScalar()) {
  794. if (selectors.size() == 1)
  795. return result;
  796. else {
  797. TType type(base->getBasicType(), EvqTemporary, selectors.size());
  798. // Swizzle operations propagate specialization-constantness
  799. if (base->getQualifier().isSpecConstant())
  800. type.getQualifier().makeSpecConstant();
  801. return addConstructor(loc, base, type);
  802. }
  803. }
  804. if (base->getType().getQualifier().isFrontEndConstant())
  805. result = intermediate.foldSwizzle(base, selectors, loc);
  806. else {
  807. if (selectors.size() == 1) {
  808. TIntermTyped* index = intermediate.addConstantUnion(selectors[0], loc);
  809. result = intermediate.addIndex(EOpIndexDirect, base, index, loc);
  810. result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision));
  811. } else {
  812. TIntermTyped* index = intermediate.addSwizzle(selectors, loc);
  813. result = intermediate.addIndex(EOpVectorSwizzle, base, index, loc);
  814. result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision, selectors.size()));
  815. }
  816. // Swizzle operations propagate specialization-constantness
  817. if (base->getType().getQualifier().isSpecConstant())
  818. result->getWritableType().getQualifier().makeSpecConstant();
  819. }
  820. return result;
  821. }
  822. void TParseContext::blockMemberExtensionCheck(const TSourceLoc& loc, const TIntermTyped* base, int member, const TString& memberName)
  823. {
  824. // a block that needs extension checking is either 'base', or if arrayed,
  825. // one level removed to the left
  826. const TIntermSymbol* baseSymbol = nullptr;
  827. if (base->getAsBinaryNode() == nullptr)
  828. baseSymbol = base->getAsSymbolNode();
  829. else
  830. baseSymbol = base->getAsBinaryNode()->getLeft()->getAsSymbolNode();
  831. if (baseSymbol == nullptr)
  832. return;
  833. const TSymbol* symbol = symbolTable.find(baseSymbol->getName());
  834. if (symbol == nullptr)
  835. return;
  836. const TVariable* variable = symbol->getAsVariable();
  837. if (variable == nullptr)
  838. return;
  839. if (!variable->hasMemberExtensions())
  840. return;
  841. // We now have a variable that is the base of a dot reference
  842. // with members that need extension checking.
  843. if (variable->getNumMemberExtensions(member) > 0)
  844. requireExtensions(loc, variable->getNumMemberExtensions(member), variable->getMemberExtensions(member), memberName.c_str());
  845. }
  846. //
  847. // Handle seeing a function declarator in the grammar. This is the precursor
  848. // to recognizing a function prototype or function definition.
  849. //
  850. TFunction* TParseContext::handleFunctionDeclarator(const TSourceLoc& loc, TFunction& function, bool prototype)
  851. {
  852. // ES can't declare prototypes inside functions
  853. if (! symbolTable.atGlobalLevel())
  854. requireProfile(loc, ~EEsProfile, "local function declaration");
  855. //
  856. // Multiple declarations of the same function name are allowed.
  857. //
  858. // If this is a definition, the definition production code will check for redefinitions
  859. // (we don't know at this point if it's a definition or not).
  860. //
  861. // Redeclarations (full signature match) are allowed. But, return types and parameter qualifiers must also match.
  862. // - except ES 100, which only allows a single prototype
  863. //
  864. // ES 100 does not allow redefining, but does allow overloading of built-in functions.
  865. // ES 300 does not allow redefining or overloading of built-in functions.
  866. //
  867. bool builtIn;
  868. TSymbol* symbol = symbolTable.find(function.getMangledName(), &builtIn);
  869. if (symbol && symbol->getAsFunction() && builtIn)
  870. requireProfile(loc, ~EEsProfile, "redefinition of built-in function");
  871. const TFunction* prevDec = symbol ? symbol->getAsFunction() : 0;
  872. if (prevDec) {
  873. if (prevDec->isPrototyped() && prototype)
  874. profileRequires(loc, EEsProfile, 300, nullptr, "multiple prototypes for same function");
  875. if (prevDec->getType() != function.getType())
  876. error(loc, "overloaded functions must have the same return type", function.getName().c_str(), "");
  877. for (int i = 0; i < prevDec->getParamCount(); ++i) {
  878. if ((*prevDec)[i].type->getQualifier().storage != function[i].type->getQualifier().storage)
  879. error(loc, "overloaded functions must have the same parameter storage qualifiers for argument", function[i].type->getStorageQualifierString(), "%d", i+1);
  880. if ((*prevDec)[i].type->getQualifier().precision != function[i].type->getQualifier().precision)
  881. error(loc, "overloaded functions must have the same parameter precision qualifiers for argument", function[i].type->getPrecisionQualifierString(), "%d", i+1);
  882. }
  883. }
  884. arrayObjectCheck(loc, function.getType(), "array in function return type");
  885. if (prototype) {
  886. // All built-in functions are defined, even though they don't have a body.
  887. // Count their prototype as a definition instead.
  888. if (symbolTable.atBuiltInLevel())
  889. function.setDefined();
  890. else {
  891. if (prevDec && ! builtIn)
  892. symbol->getAsFunction()->setPrototyped(); // need a writable one, but like having prevDec as a const
  893. function.setPrototyped();
  894. }
  895. }
  896. // This insert won't actually insert it if it's a duplicate signature, but it will still check for
  897. // other forms of name collisions.
  898. if (! symbolTable.insert(function))
  899. error(loc, "function name is redeclaration of existing name", function.getName().c_str(), "");
  900. //
  901. // If this is a redeclaration, it could also be a definition,
  902. // in which case, we need to use the parameter names from this one, and not the one that's
  903. // being redeclared. So, pass back this declaration, not the one in the symbol table.
  904. //
  905. return &function;
  906. }
  907. //
  908. // Handle seeing the function prototype in front of a function definition in the grammar.
  909. // The body is handled after this function returns.
  910. //
  911. TIntermAggregate* TParseContext::handleFunctionDefinition(const TSourceLoc& loc, TFunction& function)
  912. {
  913. currentCaller = function.getMangledName();
  914. TSymbol* symbol = symbolTable.find(function.getMangledName());
  915. TFunction* prevDec = symbol ? symbol->getAsFunction() : nullptr;
  916. if (! prevDec)
  917. error(loc, "can't find function", function.getName().c_str(), "");
  918. // Note: 'prevDec' could be 'function' if this is the first time we've seen function
  919. // as it would have just been put in the symbol table. Otherwise, we're looking up
  920. // an earlier occurrence.
  921. if (prevDec && prevDec->isDefined()) {
  922. // Then this function already has a body.
  923. error(loc, "function already has a body", function.getName().c_str(), "");
  924. }
  925. if (prevDec && ! prevDec->isDefined()) {
  926. prevDec->setDefined();
  927. // Remember the return type for later checking for RETURN statements.
  928. currentFunctionType = &(prevDec->getType());
  929. } else
  930. currentFunctionType = new TType(EbtVoid);
  931. functionReturnsValue = false;
  932. // Check for entry point
  933. if (function.getName().compare(intermediate.getEntryPointName().c_str()) == 0) {
  934. intermediate.setEntryPointMangledName(function.getMangledName().c_str());
  935. intermediate.incrementEntryPointCount();
  936. inMain = true;
  937. } else
  938. inMain = false;
  939. //
  940. // Raise error message if main function takes any parameters or returns anything other than void
  941. //
  942. if (inMain) {
  943. if (function.getParamCount() > 0)
  944. error(loc, "function cannot take any parameter(s)", function.getName().c_str(), "");
  945. if (function.getType().getBasicType() != EbtVoid)
  946. error(loc, "", function.getType().getBasicTypeString().c_str(), "entry point cannot return a value");
  947. }
  948. //
  949. // New symbol table scope for body of function plus its arguments
  950. //
  951. symbolTable.push();
  952. //
  953. // Insert parameters into the symbol table.
  954. // If the parameter has no name, it's not an error, just don't insert it
  955. // (could be used for unused args).
  956. //
  957. // Also, accumulate the list of parameters into the HIL, so lower level code
  958. // knows where to find parameters.
  959. //
  960. TIntermAggregate* paramNodes = new TIntermAggregate;
  961. for (int i = 0; i < function.getParamCount(); i++) {
  962. TParameter& param = function[i];
  963. if (param.name != nullptr) {
  964. TVariable *variable = new TVariable(param.name, *param.type);
  965. // Insert the parameters with name in the symbol table.
  966. if (! symbolTable.insert(*variable))
  967. error(loc, "redefinition", variable->getName().c_str(), "");
  968. else {
  969. // Transfer ownership of name pointer to symbol table.
  970. param.name = nullptr;
  971. // Add the parameter to the HIL
  972. paramNodes = intermediate.growAggregate(paramNodes,
  973. intermediate.addSymbol(*variable, loc),
  974. loc);
  975. }
  976. } else
  977. paramNodes = intermediate.growAggregate(paramNodes, intermediate.addSymbol(*param.type, loc), loc);
  978. }
  979. intermediate.setAggregateOperator(paramNodes, EOpParameters, TType(EbtVoid), loc);
  980. loopNestingLevel = 0;
  981. statementNestingLevel = 0;
  982. controlFlowNestingLevel = 0;
  983. postEntryPointReturn = false;
  984. return paramNodes;
  985. }
  986. //
  987. // Handle seeing function call syntax in the grammar, which could be any of
  988. // - .length() method
  989. // - constructor
  990. // - a call to a built-in function mapped to an operator
  991. // - a call to a built-in function that will remain a function call (e.g., texturing)
  992. // - user function
  993. // - subroutine call (not implemented yet)
  994. //
  995. TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction* function, TIntermNode* arguments)
  996. {
  997. TIntermTyped* result = nullptr;
  998. if (function->getBuiltInOp() == EOpArrayLength)
  999. result = handleLengthMethod(loc, function, arguments);
  1000. else if (function->getBuiltInOp() != EOpNull) {
  1001. //
  1002. // Then this should be a constructor.
  1003. // Don't go through the symbol table for constructors.
  1004. // Their parameters will be verified algorithmically.
  1005. //
  1006. TType type(EbtVoid); // use this to get the type back
  1007. if (! constructorError(loc, arguments, *function, function->getBuiltInOp(), type)) {
  1008. //
  1009. // It's a constructor, of type 'type'.
  1010. //
  1011. result = addConstructor(loc, arguments, type);
  1012. if (result == nullptr)
  1013. error(loc, "cannot construct with these arguments", type.getCompleteString().c_str(), "");
  1014. }
  1015. } else {
  1016. //
  1017. // Find it in the symbol table.
  1018. //
  1019. const TFunction* fnCandidate;
  1020. bool builtIn;
  1021. fnCandidate = findFunction(loc, *function, builtIn);
  1022. if (fnCandidate) {
  1023. // This is a declared function that might map to
  1024. // - a built-in operator,
  1025. // - a built-in function not mapped to an operator, or
  1026. // - a user function.
  1027. // Error check for a function requiring specific extensions present.
  1028. if (builtIn && fnCandidate->getNumExtensions())
  1029. requireExtensions(loc, fnCandidate->getNumExtensions(), fnCandidate->getExtensions(), fnCandidate->getName().c_str());
  1030. if (builtIn && fnCandidate->getType().contains16BitFloat())
  1031. requireFloat16Arithmetic(loc, "built-in function", "float16 types can only be in uniform block or buffer storage");
  1032. if (builtIn && fnCandidate->getType().contains16BitInt())
  1033. requireInt16Arithmetic(loc, "built-in function", "(u)int16 types can only be in uniform block or buffer storage");
  1034. if (builtIn && fnCandidate->getType().contains8BitInt())
  1035. requireInt8Arithmetic(loc, "built-in function", "(u)int8 types can only be in uniform block or buffer storage");
  1036. if (arguments != nullptr) {
  1037. // Make sure qualifications work for these arguments.
  1038. TIntermAggregate* aggregate = arguments->getAsAggregate();
  1039. for (int i = 0; i < fnCandidate->getParamCount(); ++i) {
  1040. // At this early point there is a slight ambiguity between whether an aggregate 'arguments'
  1041. // is the single argument itself or its children are the arguments. Only one argument
  1042. // means take 'arguments' itself as the one argument.
  1043. TIntermNode* arg = fnCandidate->getParamCount() == 1 ? arguments : (aggregate ? aggregate->getSequence()[i] : arguments);
  1044. TQualifier& formalQualifier = (*fnCandidate)[i].type->getQualifier();
  1045. if (formalQualifier.isParamOutput()) {
  1046. if (lValueErrorCheck(arguments->getLoc(), "assign", arg->getAsTyped()))
  1047. error(arguments->getLoc(), "Non-L-value cannot be passed for 'out' or 'inout' parameters.", "out", "");
  1048. }
  1049. const TType& argType = arg->getAsTyped()->getType();
  1050. const TQualifier& argQualifier = argType.getQualifier();
  1051. if (argQualifier.isMemory() && (argType.containsOpaque() || argType.isReference())) {
  1052. const char* message = "argument cannot drop memory qualifier when passed to formal parameter";
  1053. #ifndef GLSLANG_WEB
  1054. if (argQualifier.volatil && ! formalQualifier.volatil)
  1055. error(arguments->getLoc(), message, "volatile", "");
  1056. if (argQualifier.coherent && ! (formalQualifier.devicecoherent || formalQualifier.coherent))
  1057. error(arguments->getLoc(), message, "coherent", "");
  1058. if (argQualifier.devicecoherent && ! (formalQualifier.devicecoherent || formalQualifier.coherent))
  1059. error(arguments->getLoc(), message, "devicecoherent", "");
  1060. if (argQualifier.queuefamilycoherent && ! (formalQualifier.queuefamilycoherent || formalQualifier.devicecoherent || formalQualifier.coherent))
  1061. error(arguments->getLoc(), message, "queuefamilycoherent", "");
  1062. if (argQualifier.workgroupcoherent && ! (formalQualifier.workgroupcoherent || formalQualifier.queuefamilycoherent || formalQualifier.devicecoherent || formalQualifier.coherent))
  1063. error(arguments->getLoc(), message, "workgroupcoherent", "");
  1064. if (argQualifier.subgroupcoherent && ! (formalQualifier.subgroupcoherent || formalQualifier.workgroupcoherent || formalQualifier.queuefamilycoherent || formalQualifier.devicecoherent || formalQualifier.coherent))
  1065. error(arguments->getLoc(), message, "subgroupcoherent", "");
  1066. if (argQualifier.readonly && ! formalQualifier.readonly)
  1067. error(arguments->getLoc(), message, "readonly", "");
  1068. if (argQualifier.writeonly && ! formalQualifier.writeonly)
  1069. error(arguments->getLoc(), message, "writeonly", "");
  1070. // Don't check 'restrict', it is different than the rest:
  1071. // "...but only restrict can be taken away from a calling argument, by a formal parameter that
  1072. // lacks the restrict qualifier..."
  1073. #endif
  1074. }
  1075. if (!builtIn && argQualifier.getFormat() != formalQualifier.getFormat()) {
  1076. // we have mismatched formats, which should only be allowed if writeonly
  1077. // and at least one format is unknown
  1078. if (!formalQualifier.isWriteOnly() || (formalQualifier.getFormat() != ElfNone &&
  1079. argQualifier.getFormat() != ElfNone))
  1080. error(arguments->getLoc(), "image formats must match", "format", "");
  1081. }
  1082. if (builtIn && arg->getAsTyped()->getType().contains16BitFloat())
  1083. requireFloat16Arithmetic(arguments->getLoc(), "built-in function", "float16 types can only be in uniform block or buffer storage");
  1084. if (builtIn && arg->getAsTyped()->getType().contains16BitInt())
  1085. requireInt16Arithmetic(arguments->getLoc(), "built-in function", "(u)int16 types can only be in uniform block or buffer storage");
  1086. if (builtIn && arg->getAsTyped()->getType().contains8BitInt())
  1087. requireInt8Arithmetic(arguments->getLoc(), "built-in function", "(u)int8 types can only be in uniform block or buffer storage");
  1088. // TODO 4.5 functionality: A shader will fail to compile
  1089. // if the value passed to the memargument of an atomic memory function does not correspond to a buffer or
  1090. // shared variable. It is acceptable to pass an element of an array or a single component of a vector to the
  1091. // memargument of an atomic memory function, as long as the underlying array or vector is a buffer or
  1092. // shared variable.
  1093. }
  1094. // Convert 'in' arguments
  1095. addInputArgumentConversions(*fnCandidate, arguments); // arguments may be modified if it's just a single argument node
  1096. }
  1097. if (builtIn && fnCandidate->getBuiltInOp() != EOpNull) {
  1098. // A function call mapped to a built-in operation.
  1099. result = handleBuiltInFunctionCall(loc, arguments, *fnCandidate);
  1100. } else {
  1101. // This is a function call not mapped to built-in operator.
  1102. // It could still be a built-in function, but only if PureOperatorBuiltins == false.
  1103. result = intermediate.setAggregateOperator(arguments, EOpFunctionCall, fnCandidate->getType(), loc);
  1104. TIntermAggregate* call = result->getAsAggregate();
  1105. call->setName(fnCandidate->getMangledName());
  1106. // this is how we know whether the given function is a built-in function or a user-defined function
  1107. // if builtIn == false, it's a userDefined -> could be an overloaded built-in function also
  1108. // if builtIn == true, it's definitely a built-in function with EOpNull
  1109. if (! builtIn) {
  1110. call->setUserDefined();
  1111. if (symbolTable.atGlobalLevel()) {
  1112. requireProfile(loc, ~EEsProfile, "calling user function from global scope");
  1113. intermediate.addToCallGraph(infoSink, "main(", fnCandidate->getMangledName());
  1114. } else
  1115. intermediate.addToCallGraph(infoSink, currentCaller, fnCandidate->getMangledName());
  1116. }
  1117. #ifndef GLSLANG_WEB
  1118. if (builtIn)
  1119. nonOpBuiltInCheck(loc, *fnCandidate, *call);
  1120. else
  1121. #endif
  1122. userFunctionCallCheck(loc, *call);
  1123. }
  1124. // Convert 'out' arguments. If it was a constant folded built-in, it won't be an aggregate anymore.
  1125. // Built-ins with a single argument aren't called with an aggregate, but they also don't have an output.
  1126. // Also, build the qualifier list for user function calls, which are always called with an aggregate.
  1127. if (result->getAsAggregate()) {
  1128. TQualifierList& qualifierList = result->getAsAggregate()->getQualifierList();
  1129. for (int i = 0; i < fnCandidate->getParamCount(); ++i) {
  1130. TStorageQualifier qual = (*fnCandidate)[i].type->getQualifier().storage;
  1131. qualifierList.push_back(qual);
  1132. }
  1133. result = addOutputArgumentConversions(*fnCandidate, *result->getAsAggregate());
  1134. }
  1135. if (result->getAsTyped()->getType().isCoopMat() &&
  1136. !result->getAsTyped()->getType().isParameterized()) {
  1137. assert(fnCandidate->getBuiltInOp() == EOpCooperativeMatrixMulAdd);
  1138. result->setType(result->getAsAggregate()->getSequence()[2]->getAsTyped()->getType());
  1139. }
  1140. }
  1141. }
  1142. // generic error recovery
  1143. // TODO: simplification: localize all the error recoveries that look like this, and taking type into account to reduce cascades
  1144. if (result == nullptr)
  1145. result = intermediate.addConstantUnion(0.0, EbtFloat, loc);
  1146. return result;
  1147. }
  1148. TIntermTyped* TParseContext::handleBuiltInFunctionCall(TSourceLoc loc, TIntermNode* arguments,
  1149. const TFunction& function)
  1150. {
  1151. checkLocation(loc, function.getBuiltInOp());
  1152. TIntermTyped *result = intermediate.addBuiltInFunctionCall(loc, function.getBuiltInOp(),
  1153. function.getParamCount() == 1,
  1154. arguments, function.getType());
  1155. if (result != nullptr && obeyPrecisionQualifiers())
  1156. computeBuiltinPrecisions(*result, function);
  1157. if (result == nullptr) {
  1158. if (arguments == nullptr)
  1159. error(loc, " wrong operand type", "Internal Error",
  1160. "built in unary operator function. Type: %s", "");
  1161. else
  1162. error(arguments->getLoc(), " wrong operand type", "Internal Error",
  1163. "built in unary operator function. Type: %s",
  1164. static_cast<TIntermTyped*>(arguments)->getCompleteString().c_str());
  1165. } else if (result->getAsOperator())
  1166. builtInOpCheck(loc, function, *result->getAsOperator());
  1167. return result;
  1168. }
  1169. // "The operation of a built-in function can have a different precision
  1170. // qualification than the precision qualification of the resulting value.
  1171. // These two precision qualifications are established as follows.
  1172. //
  1173. // The precision qualification of the operation of a built-in function is
  1174. // based on the precision qualification of its input arguments and formal
  1175. // parameters: When a formal parameter specifies a precision qualifier,
  1176. // that is used, otherwise, the precision qualification of the calling
  1177. // argument is used. The highest precision of these will be the precision
  1178. // qualification of the operation of the built-in function. Generally,
  1179. // this is applied across all arguments to a built-in function, with the
  1180. // exceptions being:
  1181. // - bitfieldExtract and bitfieldInsert ignore the 'offset' and 'bits'
  1182. // arguments.
  1183. // - interpolateAt* functions only look at the 'interpolant' argument.
  1184. //
  1185. // The precision qualification of the result of a built-in function is
  1186. // determined in one of the following ways:
  1187. //
  1188. // - For the texture sampling, image load, and image store functions,
  1189. // the precision of the return type matches the precision of the
  1190. // sampler type
  1191. //
  1192. // Otherwise:
  1193. //
  1194. // - For prototypes that do not specify a resulting precision qualifier,
  1195. // the precision will be the same as the precision of the operation.
  1196. //
  1197. // - For prototypes that do specify a resulting precision qualifier,
  1198. // the specified precision qualifier is the precision qualification of
  1199. // the result."
  1200. //
  1201. void TParseContext::computeBuiltinPrecisions(TIntermTyped& node, const TFunction& function)
  1202. {
  1203. TPrecisionQualifier operationPrecision = EpqNone;
  1204. TPrecisionQualifier resultPrecision = EpqNone;
  1205. TIntermOperator* opNode = node.getAsOperator();
  1206. if (opNode == nullptr)
  1207. return;
  1208. if (TIntermUnary* unaryNode = node.getAsUnaryNode()) {
  1209. operationPrecision = std::max(function[0].type->getQualifier().precision,
  1210. unaryNode->getOperand()->getType().getQualifier().precision);
  1211. if (function.getType().getBasicType() != EbtBool)
  1212. resultPrecision = function.getType().getQualifier().precision == EpqNone ?
  1213. operationPrecision :
  1214. function.getType().getQualifier().precision;
  1215. } else if (TIntermAggregate* agg = node.getAsAggregate()) {
  1216. TIntermSequence& sequence = agg->getSequence();
  1217. unsigned int numArgs = (unsigned int)sequence.size();
  1218. switch (agg->getOp()) {
  1219. case EOpBitfieldExtract:
  1220. numArgs = 1;
  1221. break;
  1222. case EOpBitfieldInsert:
  1223. numArgs = 2;
  1224. break;
  1225. case EOpInterpolateAtCentroid:
  1226. case EOpInterpolateAtOffset:
  1227. case EOpInterpolateAtSample:
  1228. numArgs = 1;
  1229. break;
  1230. case EOpDebugPrintf:
  1231. numArgs = 0;
  1232. break;
  1233. default:
  1234. break;
  1235. }
  1236. // find the maximum precision from the arguments and parameters
  1237. for (unsigned int arg = 0; arg < numArgs; ++arg) {
  1238. operationPrecision = std::max(operationPrecision, sequence[arg]->getAsTyped()->getQualifier().precision);
  1239. operationPrecision = std::max(operationPrecision, function[arg].type->getQualifier().precision);
  1240. }
  1241. // compute the result precision
  1242. if (agg->isSampling() ||
  1243. agg->getOp() == EOpImageLoad || agg->getOp() == EOpImageStore ||
  1244. agg->getOp() == EOpImageLoadLod || agg->getOp() == EOpImageStoreLod)
  1245. resultPrecision = sequence[0]->getAsTyped()->getQualifier().precision;
  1246. else if (function.getType().getBasicType() != EbtBool)
  1247. resultPrecision = function.getType().getQualifier().precision == EpqNone ?
  1248. operationPrecision :
  1249. function.getType().getQualifier().precision;
  1250. }
  1251. // Propagate precision through this node and its children. That algorithm stops
  1252. // when a precision is found, so start by clearing this subroot precision
  1253. opNode->getQualifier().precision = EpqNone;
  1254. if (operationPrecision != EpqNone) {
  1255. opNode->propagatePrecision(operationPrecision);
  1256. opNode->setOperationPrecision(operationPrecision);
  1257. }
  1258. // Now, set the result precision, which might not match
  1259. opNode->getQualifier().precision = resultPrecision;
  1260. }
  1261. TIntermNode* TParseContext::handleReturnValue(const TSourceLoc& loc, TIntermTyped* value)
  1262. {
  1263. #ifndef GLSLANG_WEB
  1264. storage16BitAssignmentCheck(loc, value->getType(), "return");
  1265. #endif
  1266. functionReturnsValue = true;
  1267. TIntermBranch* branch = nullptr;
  1268. if (currentFunctionType->getBasicType() == EbtVoid) {
  1269. error(loc, "void function cannot return a value", "return", "");
  1270. branch = intermediate.addBranch(EOpReturn, loc);
  1271. } else if (*currentFunctionType != value->getType()) {
  1272. TIntermTyped* converted = intermediate.addConversion(EOpReturn, *currentFunctionType, value);
  1273. if (converted) {
  1274. if (*currentFunctionType != converted->getType())
  1275. error(loc, "cannot convert return value to function return type", "return", "");
  1276. if (version < 420)
  1277. warn(loc, "type conversion on return values was not explicitly allowed until version 420",
  1278. "return", "");
  1279. branch = intermediate.addBranch(EOpReturn, converted, loc);
  1280. } else {
  1281. error(loc, "type does not match, or is not convertible to, the function's return type", "return", "");
  1282. branch = intermediate.addBranch(EOpReturn, value, loc);
  1283. }
  1284. } else
  1285. branch = intermediate.addBranch(EOpReturn, value, loc);
  1286. branch->updatePrecision(currentFunctionType->getQualifier().precision);
  1287. return branch;
  1288. }
  1289. // See if the operation is being done in an illegal location.
  1290. void TParseContext::checkLocation(const TSourceLoc& loc, TOperator op)
  1291. {
  1292. #ifndef GLSLANG_WEB
  1293. switch (op) {
  1294. case EOpBarrier:
  1295. if (language == EShLangTessControl) {
  1296. if (controlFlowNestingLevel > 0)
  1297. error(loc, "tessellation control barrier() cannot be placed within flow control", "", "");
  1298. if (! inMain)
  1299. error(loc, "tessellation control barrier() must be in main()", "", "");
  1300. else if (postEntryPointReturn)
  1301. error(loc, "tessellation control barrier() cannot be placed after a return from main()", "", "");
  1302. }
  1303. break;
  1304. case EOpBeginInvocationInterlock:
  1305. if (language != EShLangFragment)
  1306. error(loc, "beginInvocationInterlockARB() must be in a fragment shader", "", "");
  1307. if (! inMain)
  1308. error(loc, "beginInvocationInterlockARB() must be in main()", "", "");
  1309. else if (postEntryPointReturn)
  1310. error(loc, "beginInvocationInterlockARB() cannot be placed after a return from main()", "", "");
  1311. if (controlFlowNestingLevel > 0)
  1312. error(loc, "beginInvocationInterlockARB() cannot be placed within flow control", "", "");
  1313. if (beginInvocationInterlockCount > 0)
  1314. error(loc, "beginInvocationInterlockARB() must only be called once", "", "");
  1315. if (endInvocationInterlockCount > 0)
  1316. error(loc, "beginInvocationInterlockARB() must be called before endInvocationInterlockARB()", "", "");
  1317. beginInvocationInterlockCount++;
  1318. // default to pixel_interlock_ordered
  1319. if (intermediate.getInterlockOrdering() == EioNone)
  1320. intermediate.setInterlockOrdering(EioPixelInterlockOrdered);
  1321. break;
  1322. case EOpEndInvocationInterlock:
  1323. if (language != EShLangFragment)
  1324. error(loc, "endInvocationInterlockARB() must be in a fragment shader", "", "");
  1325. if (! inMain)
  1326. error(loc, "endInvocationInterlockARB() must be in main()", "", "");
  1327. else if (postEntryPointReturn)
  1328. error(loc, "endInvocationInterlockARB() cannot be placed after a return from main()", "", "");
  1329. if (controlFlowNestingLevel > 0)
  1330. error(loc, "endInvocationInterlockARB() cannot be placed within flow control", "", "");
  1331. if (endInvocationInterlockCount > 0)
  1332. error(loc, "endInvocationInterlockARB() must only be called once", "", "");
  1333. if (beginInvocationInterlockCount == 0)
  1334. error(loc, "beginInvocationInterlockARB() must be called before endInvocationInterlockARB()", "", "");
  1335. endInvocationInterlockCount++;
  1336. break;
  1337. default:
  1338. break;
  1339. }
  1340. #endif
  1341. }
  1342. // Finish processing object.length(). This started earlier in handleDotDereference(), where
  1343. // the ".length" part was recognized and semantically checked, and finished here where the
  1344. // function syntax "()" is recognized.
  1345. //
  1346. // Return resulting tree node.
  1347. TIntermTyped* TParseContext::handleLengthMethod(const TSourceLoc& loc, TFunction* function, TIntermNode* intermNode)
  1348. {
  1349. int length = 0;
  1350. if (function->getParamCount() > 0)
  1351. error(loc, "method does not accept any arguments", function->getName().c_str(), "");
  1352. else {
  1353. const TType& type = intermNode->getAsTyped()->getType();
  1354. if (type.isArray()) {
  1355. if (type.isUnsizedArray()) {
  1356. #ifndef GLSLANG_WEB
  1357. if (intermNode->getAsSymbolNode() && isIoResizeArray(type)) {
  1358. // We could be between a layout declaration that gives a built-in io array implicit size and
  1359. // a user redeclaration of that array, meaning we have to substitute its implicit size here
  1360. // without actually redeclaring the array. (It is an error to use a member before the
  1361. // redeclaration, but not an error to use the array name itself.)
  1362. const TString& name = intermNode->getAsSymbolNode()->getName();
  1363. if (name == "gl_in" || name == "gl_out" || name == "gl_MeshVerticesNV" ||
  1364. name == "gl_MeshPrimitivesNV") {
  1365. length = getIoArrayImplicitSize(type.getQualifier());
  1366. }
  1367. }
  1368. #endif
  1369. if (length == 0) {
  1370. #ifndef GLSLANG_WEB
  1371. if (intermNode->getAsSymbolNode() && isIoResizeArray(type))
  1372. error(loc, "", function->getName().c_str(), "array must first be sized by a redeclaration or layout qualifier");
  1373. else if (isRuntimeLength(*intermNode->getAsTyped())) {
  1374. // Create a unary op and let the back end handle it
  1375. return intermediate.addBuiltInFunctionCall(loc, EOpArrayLength, true, intermNode, TType(EbtInt));
  1376. } else
  1377. #endif
  1378. error(loc, "", function->getName().c_str(), "array must be declared with a size before using this method");
  1379. }
  1380. } else if (type.getOuterArrayNode()) {
  1381. // If the array's outer size is specified by an intermediate node, it means the array's length
  1382. // was specified by a specialization constant. In such a case, we should return the node of the
  1383. // specialization constants to represent the length.
  1384. return type.getOuterArrayNode();
  1385. } else
  1386. length = type.getOuterArraySize();
  1387. } else if (type.isMatrix())
  1388. length = type.getMatrixCols();
  1389. else if (type.isVector())
  1390. length = type.getVectorSize();
  1391. else if (type.isCoopMat())
  1392. return intermediate.addBuiltInFunctionCall(loc, EOpArrayLength, true, intermNode, TType(EbtInt));
  1393. else {
  1394. // we should not get here, because earlier semantic checking should have prevented this path
  1395. error(loc, ".length()", "unexpected use of .length()", "");
  1396. }
  1397. }
  1398. if (length == 0)
  1399. length = 1;
  1400. return intermediate.addConstantUnion(length, loc);
  1401. }
  1402. //
  1403. // Add any needed implicit conversions for function-call arguments to input parameters.
  1404. //
  1405. void TParseContext::addInputArgumentConversions(const TFunction& function, TIntermNode*& arguments) const
  1406. {
  1407. #ifndef GLSLANG_WEB
  1408. TIntermAggregate* aggregate = arguments->getAsAggregate();
  1409. // Process each argument's conversion
  1410. for (int i = 0; i < function.getParamCount(); ++i) {
  1411. // At this early point there is a slight ambiguity between whether an aggregate 'arguments'
  1412. // is the single argument itself or its children are the arguments. Only one argument
  1413. // means take 'arguments' itself as the one argument.
  1414. TIntermTyped* arg = function.getParamCount() == 1 ? arguments->getAsTyped() : (aggregate ? aggregate->getSequence()[i]->getAsTyped() : arguments->getAsTyped());
  1415. if (*function[i].type != arg->getType()) {
  1416. if (function[i].type->getQualifier().isParamInput() &&
  1417. !function[i].type->isCoopMat()) {
  1418. // In-qualified arguments just need an extra node added above the argument to
  1419. // convert to the correct type.
  1420. arg = intermediate.addConversion(EOpFunctionCall, *function[i].type, arg);
  1421. if (arg) {
  1422. if (function.getParamCount() == 1)
  1423. arguments = arg;
  1424. else {
  1425. if (aggregate)
  1426. aggregate->getSequence()[i] = arg;
  1427. else
  1428. arguments = arg;
  1429. }
  1430. }
  1431. }
  1432. }
  1433. }
  1434. #endif
  1435. }
  1436. //
  1437. // Add any needed implicit output conversions for function-call arguments. This
  1438. // can require a new tree topology, complicated further by whether the function
  1439. // has a return value.
  1440. //
  1441. // Returns a node of a subtree that evaluates to the return value of the function.
  1442. //
  1443. TIntermTyped* TParseContext::addOutputArgumentConversions(const TFunction& function, TIntermAggregate& intermNode) const
  1444. {
  1445. #ifdef GLSLANG_WEB
  1446. return &intermNode;
  1447. #else
  1448. TIntermSequence& arguments = intermNode.getSequence();
  1449. // Will there be any output conversions?
  1450. bool outputConversions = false;
  1451. for (int i = 0; i < function.getParamCount(); ++i) {
  1452. if (*function[i].type != arguments[i]->getAsTyped()->getType() && function[i].type->getQualifier().isParamOutput()) {
  1453. outputConversions = true;
  1454. break;
  1455. }
  1456. }
  1457. if (! outputConversions)
  1458. return &intermNode;
  1459. // Setup for the new tree, if needed:
  1460. //
  1461. // Output conversions need a different tree topology.
  1462. // Out-qualified arguments need a temporary of the correct type, with the call
  1463. // followed by an assignment of the temporary to the original argument:
  1464. // void: function(arg, ...) -> ( function(tempArg, ...), arg = tempArg, ...)
  1465. // ret = function(arg, ...) -> ret = (tempRet = function(tempArg, ...), arg = tempArg, ..., tempRet)
  1466. // Where the "tempArg" type needs no conversion as an argument, but will convert on assignment.
  1467. TIntermTyped* conversionTree = nullptr;
  1468. TVariable* tempRet = nullptr;
  1469. if (intermNode.getBasicType() != EbtVoid) {
  1470. // do the "tempRet = function(...), " bit from above
  1471. tempRet = makeInternalVariable("tempReturn", intermNode.getType());
  1472. TIntermSymbol* tempRetNode = intermediate.addSymbol(*tempRet, intermNode.getLoc());
  1473. conversionTree = intermediate.addAssign(EOpAssign, tempRetNode, &intermNode, intermNode.getLoc());
  1474. } else
  1475. conversionTree = &intermNode;
  1476. conversionTree = intermediate.makeAggregate(conversionTree);
  1477. // Process each argument's conversion
  1478. for (int i = 0; i < function.getParamCount(); ++i) {
  1479. if (*function[i].type != arguments[i]->getAsTyped()->getType()) {
  1480. if (function[i].type->getQualifier().isParamOutput()) {
  1481. // Out-qualified arguments need to use the topology set up above.
  1482. // do the " ...(tempArg, ...), arg = tempArg" bit from above
  1483. TType paramType;
  1484. paramType.shallowCopy(*function[i].type);
  1485. if (arguments[i]->getAsTyped()->getType().isParameterized() &&
  1486. !paramType.isParameterized()) {
  1487. paramType.shallowCopy(arguments[i]->getAsTyped()->getType());
  1488. paramType.copyTypeParameters(*arguments[i]->getAsTyped()->getType().getTypeParameters());
  1489. }
  1490. TVariable* tempArg = makeInternalVariable("tempArg", paramType);
  1491. tempArg->getWritableType().getQualifier().makeTemporary();
  1492. TIntermSymbol* tempArgNode = intermediate.addSymbol(*tempArg, intermNode.getLoc());
  1493. TIntermTyped* tempAssign = intermediate.addAssign(EOpAssign, arguments[i]->getAsTyped(), tempArgNode, arguments[i]->getLoc());
  1494. conversionTree = intermediate.growAggregate(conversionTree, tempAssign, arguments[i]->getLoc());
  1495. // replace the argument with another node for the same tempArg variable
  1496. arguments[i] = intermediate.addSymbol(*tempArg, intermNode.getLoc());
  1497. }
  1498. }
  1499. }
  1500. // Finalize the tree topology (see bigger comment above).
  1501. if (tempRet) {
  1502. // do the "..., tempRet" bit from above
  1503. TIntermSymbol* tempRetNode = intermediate.addSymbol(*tempRet, intermNode.getLoc());
  1504. conversionTree = intermediate.growAggregate(conversionTree, tempRetNode, intermNode.getLoc());
  1505. }
  1506. conversionTree = intermediate.setAggregateOperator(conversionTree, EOpComma, intermNode.getType(), intermNode.getLoc());
  1507. return conversionTree;
  1508. #endif
  1509. }
  1510. TIntermTyped* TParseContext::addAssign(const TSourceLoc& loc, TOperator op, TIntermTyped* left, TIntermTyped* right)
  1511. {
  1512. if ((op == EOpAddAssign || op == EOpSubAssign) && left->isReference())
  1513. requireExtensions(loc, 1, &E_GL_EXT_buffer_reference2, "+= and -= on a buffer reference");
  1514. return intermediate.addAssign(op, left, right, loc);
  1515. }
  1516. void TParseContext::memorySemanticsCheck(const TSourceLoc& loc, const TFunction& fnCandidate, const TIntermOperator& callNode)
  1517. {
  1518. const TIntermSequence* argp = &callNode.getAsAggregate()->getSequence();
  1519. //const int gl_SemanticsRelaxed = 0x0;
  1520. const int gl_SemanticsAcquire = 0x2;
  1521. const int gl_SemanticsRelease = 0x4;
  1522. const int gl_SemanticsAcquireRelease = 0x8;
  1523. const int gl_SemanticsMakeAvailable = 0x2000;
  1524. const int gl_SemanticsMakeVisible = 0x4000;
  1525. const int gl_SemanticsVolatile = 0x8000;
  1526. //const int gl_StorageSemanticsNone = 0x0;
  1527. const int gl_StorageSemanticsBuffer = 0x40;
  1528. const int gl_StorageSemanticsShared = 0x100;
  1529. const int gl_StorageSemanticsImage = 0x800;
  1530. const int gl_StorageSemanticsOutput = 0x1000;
  1531. unsigned int semantics = 0, storageClassSemantics = 0;
  1532. unsigned int semantics2 = 0, storageClassSemantics2 = 0;
  1533. const TIntermTyped* arg0 = (*argp)[0]->getAsTyped();
  1534. const bool isMS = arg0->getBasicType() == EbtSampler && arg0->getType().getSampler().isMultiSample();
  1535. // Grab the semantics and storage class semantics from the operands, based on opcode
  1536. switch (callNode.getOp()) {
  1537. case EOpAtomicAdd:
  1538. case EOpAtomicMin:
  1539. case EOpAtomicMax:
  1540. case EOpAtomicAnd:
  1541. case EOpAtomicOr:
  1542. case EOpAtomicXor:
  1543. case EOpAtomicExchange:
  1544. case EOpAtomicStore:
  1545. storageClassSemantics = (*argp)[3]->getAsConstantUnion()->getConstArray()[0].getIConst();
  1546. semantics = (*argp)[4]->getAsConstantUnion()->getConstArray()[0].getIConst();
  1547. break;
  1548. case EOpAtomicLoad:
  1549. storageClassSemantics = (*argp)[2]->getAsConstantUnion()->getConstArray()[0].getIConst();
  1550. semantics = (*argp)[3]->getAsConstantUnion()->getConstArray()[0].getIConst();
  1551. break;
  1552. case EOpAtomicCompSwap:
  1553. storageClassSemantics = (*argp)[4]->getAsConstantUnion()->getConstArray()[0].getIConst();
  1554. semantics = (*argp)[5]->getAsConstantUnion()->getConstArray()[0].getIConst();
  1555. storageClassSemantics2 = (*argp)[6]->getAsConstantUnion()->getConstArray()[0].getIConst();
  1556. semantics2 = (*argp)[7]->getAsConstantUnion()->getConstArray()[0].getIConst();
  1557. break;
  1558. case EOpImageAtomicAdd:
  1559. case EOpImageAtomicMin:
  1560. case EOpImageAtomicMax:
  1561. case EOpImageAtomicAnd:
  1562. case EOpImageAtomicOr:
  1563. case EOpImageAtomicXor:
  1564. case EOpImageAtomicExchange:
  1565. case EOpImageAtomicStore:
  1566. storageClassSemantics = (*argp)[isMS ? 5 : 4]->getAsConstantUnion()->getConstArray()[0].getIConst();
  1567. semantics = (*argp)[isMS ? 6 : 5]->getAsConstantUnion()->getConstArray()[0].getIConst();
  1568. break;
  1569. case EOpImageAtomicLoad:
  1570. storageClassSemantics = (*argp)[isMS ? 4 : 3]->getAsConstantUnion()->getConstArray()[0].getIConst();
  1571. semantics = (*argp)[isMS ? 5 : 4]->getAsConstantUnion()->getConstArray()[0].getIConst();
  1572. break;
  1573. case EOpImageAtomicCompSwap:
  1574. storageClassSemantics = (*argp)[isMS ? 6 : 5]->getAsConstantUnion()->getConstArray()[0].getIConst();
  1575. semantics = (*argp)[isMS ? 7 : 6]->getAsConstantUnion()->getConstArray()[0].getIConst();
  1576. storageClassSemantics2 = (*argp)[isMS ? 8 : 7]->getAsConstantUnion()->getConstArray()[0].getIConst();
  1577. semantics2 = (*argp)[isMS ? 9 : 8]->getAsConstantUnion()->getConstArray()[0].getIConst();
  1578. break;
  1579. case EOpBarrier:
  1580. storageClassSemantics = (*argp)[2]->getAsConstantUnion()->getConstArray()[0].getIConst();
  1581. semantics = (*argp)[3]->getAsConstantUnion()->getConstArray()[0].getIConst();
  1582. break;
  1583. case EOpMemoryBarrier:
  1584. storageClassSemantics = (*argp)[1]->getAsConstantUnion()->getConstArray()[0].getIConst();
  1585. semantics = (*argp)[2]->getAsConstantUnion()->getConstArray()[0].getIConst();
  1586. break;
  1587. default:
  1588. break;
  1589. }
  1590. if ((semantics & gl_SemanticsAcquire) &&
  1591. (callNode.getOp() == EOpAtomicStore || callNode.getOp() == EOpImageAtomicStore)) {
  1592. error(loc, "gl_SemanticsAcquire must not be used with (image) atomic store",
  1593. fnCandidate.getName().c_str(), "");
  1594. }
  1595. if ((semantics & gl_SemanticsRelease) &&
  1596. (callNode.getOp() == EOpAtomicLoad || callNode.getOp() == EOpImageAtomicLoad)) {
  1597. error(loc, "gl_SemanticsRelease must not be used with (image) atomic load",
  1598. fnCandidate.getName().c_str(), "");
  1599. }
  1600. if ((semantics & gl_SemanticsAcquireRelease) &&
  1601. (callNode.getOp() == EOpAtomicStore || callNode.getOp() == EOpImageAtomicStore ||
  1602. callNode.getOp() == EOpAtomicLoad || callNode.getOp() == EOpImageAtomicLoad)) {
  1603. error(loc, "gl_SemanticsAcquireRelease must not be used with (image) atomic load/store",
  1604. fnCandidate.getName().c_str(), "");
  1605. }
  1606. if (((semantics | semantics2) & ~(gl_SemanticsAcquire |
  1607. gl_SemanticsRelease |
  1608. gl_SemanticsAcquireRelease |
  1609. gl_SemanticsMakeAvailable |
  1610. gl_SemanticsMakeVisible |
  1611. gl_SemanticsVolatile))) {
  1612. error(loc, "Invalid semantics value", fnCandidate.getName().c_str(), "");
  1613. }
  1614. if (((storageClassSemantics | storageClassSemantics2) & ~(gl_StorageSemanticsBuffer |
  1615. gl_StorageSemanticsShared |
  1616. gl_StorageSemanticsImage |
  1617. gl_StorageSemanticsOutput))) {
  1618. error(loc, "Invalid storage class semantics value", fnCandidate.getName().c_str(), "");
  1619. }
  1620. if (callNode.getOp() == EOpMemoryBarrier) {
  1621. if (!IsPow2(semantics & (gl_SemanticsAcquire | gl_SemanticsRelease | gl_SemanticsAcquireRelease))) {
  1622. error(loc, "Semantics must include exactly one of gl_SemanticsRelease, gl_SemanticsAcquire, or "
  1623. "gl_SemanticsAcquireRelease", fnCandidate.getName().c_str(), "");
  1624. }
  1625. } else {
  1626. if (semantics & (gl_SemanticsAcquire | gl_SemanticsRelease | gl_SemanticsAcquireRelease)) {
  1627. if (!IsPow2(semantics & (gl_SemanticsAcquire | gl_SemanticsRelease | gl_SemanticsAcquireRelease))) {
  1628. error(loc, "Semantics must not include multiple of gl_SemanticsRelease, gl_SemanticsAcquire, or "
  1629. "gl_SemanticsAcquireRelease", fnCandidate.getName().c_str(), "");
  1630. }
  1631. }
  1632. if (semantics2 & (gl_SemanticsAcquire | gl_SemanticsRelease | gl_SemanticsAcquireRelease)) {
  1633. if (!IsPow2(semantics2 & (gl_SemanticsAcquire | gl_SemanticsRelease | gl_SemanticsAcquireRelease))) {
  1634. error(loc, "semUnequal must not include multiple of gl_SemanticsRelease, gl_SemanticsAcquire, or "
  1635. "gl_SemanticsAcquireRelease", fnCandidate.getName().c_str(), "");
  1636. }
  1637. }
  1638. }
  1639. if (callNode.getOp() == EOpMemoryBarrier) {
  1640. if (storageClassSemantics == 0) {
  1641. error(loc, "Storage class semantics must not be zero", fnCandidate.getName().c_str(), "");
  1642. }
  1643. }
  1644. if (callNode.getOp() == EOpBarrier && semantics != 0 && storageClassSemantics == 0) {
  1645. error(loc, "Storage class semantics must not be zero", fnCandidate.getName().c_str(), "");
  1646. }
  1647. if ((callNode.getOp() == EOpAtomicCompSwap || callNode.getOp() == EOpImageAtomicCompSwap) &&
  1648. (semantics2 & (gl_SemanticsRelease | gl_SemanticsAcquireRelease))) {
  1649. error(loc, "semUnequal must not be gl_SemanticsRelease or gl_SemanticsAcquireRelease",
  1650. fnCandidate.getName().c_str(), "");
  1651. }
  1652. if ((semantics & gl_SemanticsMakeAvailable) &&
  1653. !(semantics & (gl_SemanticsRelease | gl_SemanticsAcquireRelease))) {
  1654. error(loc, "gl_SemanticsMakeAvailable requires gl_SemanticsRelease or gl_SemanticsAcquireRelease",
  1655. fnCandidate.getName().c_str(), "");
  1656. }
  1657. if ((semantics & gl_SemanticsMakeVisible) &&
  1658. !(semantics & (gl_SemanticsAcquire | gl_SemanticsAcquireRelease))) {
  1659. error(loc, "gl_SemanticsMakeVisible requires gl_SemanticsAcquire or gl_SemanticsAcquireRelease",
  1660. fnCandidate.getName().c_str(), "");
  1661. }
  1662. if ((semantics & gl_SemanticsVolatile) &&
  1663. (callNode.getOp() == EOpMemoryBarrier || callNode.getOp() == EOpBarrier)) {
  1664. error(loc, "gl_SemanticsVolatile must not be used with memoryBarrier or controlBarrier",
  1665. fnCandidate.getName().c_str(), "");
  1666. }
  1667. if ((callNode.getOp() == EOpAtomicCompSwap || callNode.getOp() == EOpImageAtomicCompSwap) &&
  1668. ((semantics ^ semantics2) & gl_SemanticsVolatile)) {
  1669. error(loc, "semEqual and semUnequal must either both include gl_SemanticsVolatile or neither",
  1670. fnCandidate.getName().c_str(), "");
  1671. }
  1672. }
  1673. //
  1674. // Do additional checking of built-in function calls that is not caught
  1675. // by normal semantic checks on argument type, extension tagging, etc.
  1676. //
  1677. // Assumes there has been a semantically correct match to a built-in function prototype.
  1678. //
  1679. void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCandidate, TIntermOperator& callNode)
  1680. {
  1681. // Set up convenience accessors to the argument(s). There is almost always
  1682. // multiple arguments for the cases below, but when there might be one,
  1683. // check the unaryArg first.
  1684. const TIntermSequence* argp = nullptr; // confusing to use [] syntax on a pointer, so this is to help get a reference
  1685. const TIntermTyped* unaryArg = nullptr;
  1686. const TIntermTyped* arg0 = nullptr;
  1687. if (callNode.getAsAggregate()) {
  1688. argp = &callNode.getAsAggregate()->getSequence();
  1689. if (argp->size() > 0)
  1690. arg0 = (*argp)[0]->getAsTyped();
  1691. } else {
  1692. assert(callNode.getAsUnaryNode());
  1693. unaryArg = callNode.getAsUnaryNode()->getOperand();
  1694. arg0 = unaryArg;
  1695. }
  1696. TString featureString;
  1697. const char* feature = nullptr;
  1698. switch (callNode.getOp()) {
  1699. #ifndef GLSLANG_WEB
  1700. case EOpTextureGather:
  1701. case EOpTextureGatherOffset:
  1702. case EOpTextureGatherOffsets:
  1703. {
  1704. // Figure out which variants are allowed by what extensions,
  1705. // and what arguments must be constant for which situations.
  1706. featureString = fnCandidate.getName();
  1707. featureString += "(...)";
  1708. feature = featureString.c_str();
  1709. profileRequires(loc, EEsProfile, 310, nullptr, feature);
  1710. int compArg = -1; // track which argument, if any, is the constant component argument
  1711. switch (callNode.getOp()) {
  1712. case EOpTextureGather:
  1713. // More than two arguments needs gpu_shader5, and rectangular or shadow needs gpu_shader5,
  1714. // otherwise, need GL_ARB_texture_gather.
  1715. if (fnCandidate.getParamCount() > 2 || fnCandidate[0].type->getSampler().dim == EsdRect || fnCandidate[0].type->getSampler().shadow) {
  1716. profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_gpu_shader5, feature);
  1717. if (! fnCandidate[0].type->getSampler().shadow)
  1718. compArg = 2;
  1719. } else
  1720. profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_texture_gather, feature);
  1721. break;
  1722. case EOpTextureGatherOffset:
  1723. // GL_ARB_texture_gather is good enough for 2D non-shadow textures with no component argument
  1724. if (fnCandidate[0].type->getSampler().dim == Esd2D && ! fnCandidate[0].type->getSampler().shadow && fnCandidate.getParamCount() == 3)
  1725. profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_texture_gather, feature);
  1726. else
  1727. profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_gpu_shader5, feature);
  1728. if (! (*argp)[fnCandidate[0].type->getSampler().shadow ? 3 : 2]->getAsConstantUnion())
  1729. profileRequires(loc, EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5,
  1730. "non-constant offset argument");
  1731. if (! fnCandidate[0].type->getSampler().shadow)
  1732. compArg = 3;
  1733. break;
  1734. case EOpTextureGatherOffsets:
  1735. profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_gpu_shader5, feature);
  1736. if (! fnCandidate[0].type->getSampler().shadow)
  1737. compArg = 3;
  1738. // check for constant offsets
  1739. if (! (*argp)[fnCandidate[0].type->getSampler().shadow ? 3 : 2]->getAsConstantUnion())
  1740. error(loc, "must be a compile-time constant:", feature, "offsets argument");
  1741. break;
  1742. default:
  1743. break;
  1744. }
  1745. if (compArg > 0 && compArg < fnCandidate.getParamCount()) {
  1746. if ((*argp)[compArg]->getAsConstantUnion()) {
  1747. int value = (*argp)[compArg]->getAsConstantUnion()->getConstArray()[0].getIConst();
  1748. if (value < 0 || value > 3)
  1749. error(loc, "must be 0, 1, 2, or 3:", feature, "component argument");
  1750. } else
  1751. error(loc, "must be a compile-time constant:", feature, "component argument");
  1752. }
  1753. bool bias = false;
  1754. if (callNode.getOp() == EOpTextureGather)
  1755. bias = fnCandidate.getParamCount() > 3;
  1756. else if (callNode.getOp() == EOpTextureGatherOffset ||
  1757. callNode.getOp() == EOpTextureGatherOffsets)
  1758. bias = fnCandidate.getParamCount() > 4;
  1759. if (bias) {
  1760. featureString = fnCandidate.getName();
  1761. featureString += "with bias argument";
  1762. feature = featureString.c_str();
  1763. profileRequires(loc, ~EEsProfile, 450, nullptr, feature);
  1764. requireExtensions(loc, 1, &E_GL_AMD_texture_gather_bias_lod, feature);
  1765. }
  1766. break;
  1767. }
  1768. case EOpSparseTextureGather:
  1769. case EOpSparseTextureGatherOffset:
  1770. case EOpSparseTextureGatherOffsets:
  1771. {
  1772. bool bias = false;
  1773. if (callNode.getOp() == EOpSparseTextureGather)
  1774. bias = fnCandidate.getParamCount() > 4;
  1775. else if (callNode.getOp() == EOpSparseTextureGatherOffset ||
  1776. callNode.getOp() == EOpSparseTextureGatherOffsets)
  1777. bias = fnCandidate.getParamCount() > 5;
  1778. if (bias) {
  1779. featureString = fnCandidate.getName();
  1780. featureString += "with bias argument";
  1781. feature = featureString.c_str();
  1782. profileRequires(loc, ~EEsProfile, 450, nullptr, feature);
  1783. requireExtensions(loc, 1, &E_GL_AMD_texture_gather_bias_lod, feature);
  1784. }
  1785. break;
  1786. }
  1787. case EOpSparseTextureGatherLod:
  1788. case EOpSparseTextureGatherLodOffset:
  1789. case EOpSparseTextureGatherLodOffsets:
  1790. {
  1791. requireExtensions(loc, 1, &E_GL_ARB_sparse_texture2, fnCandidate.getName().c_str());
  1792. break;
  1793. }
  1794. case EOpSwizzleInvocations:
  1795. {
  1796. if (! (*argp)[1]->getAsConstantUnion())
  1797. error(loc, "argument must be compile-time constant", "offset", "");
  1798. else {
  1799. unsigned offset[4] = {};
  1800. offset[0] = (*argp)[1]->getAsConstantUnion()->getConstArray()[0].getUConst();
  1801. offset[1] = (*argp)[1]->getAsConstantUnion()->getConstArray()[1].getUConst();
  1802. offset[2] = (*argp)[1]->getAsConstantUnion()->getConstArray()[2].getUConst();
  1803. offset[3] = (*argp)[1]->getAsConstantUnion()->getConstArray()[3].getUConst();
  1804. if (offset[0] > 3 || offset[1] > 3 || offset[2] > 3 || offset[3] > 3)
  1805. error(loc, "components must be in the range [0, 3]", "offset", "");
  1806. }
  1807. break;
  1808. }
  1809. case EOpSwizzleInvocationsMasked:
  1810. {
  1811. if (! (*argp)[1]->getAsConstantUnion())
  1812. error(loc, "argument must be compile-time constant", "mask", "");
  1813. else {
  1814. unsigned mask[3] = {};
  1815. mask[0] = (*argp)[1]->getAsConstantUnion()->getConstArray()[0].getUConst();
  1816. mask[1] = (*argp)[1]->getAsConstantUnion()->getConstArray()[1].getUConst();
  1817. mask[2] = (*argp)[1]->getAsConstantUnion()->getConstArray()[2].getUConst();
  1818. if (mask[0] > 31 || mask[1] > 31 || mask[2] > 31)
  1819. error(loc, "components must be in the range [0, 31]", "mask", "");
  1820. }
  1821. break;
  1822. }
  1823. #endif
  1824. case EOpTextureOffset:
  1825. case EOpTextureFetchOffset:
  1826. case EOpTextureProjOffset:
  1827. case EOpTextureLodOffset:
  1828. case EOpTextureProjLodOffset:
  1829. case EOpTextureGradOffset:
  1830. case EOpTextureProjGradOffset:
  1831. {
  1832. // Handle texture-offset limits checking
  1833. // Pick which argument has to hold constant offsets
  1834. int arg = -1;
  1835. switch (callNode.getOp()) {
  1836. case EOpTextureOffset: arg = 2; break;
  1837. case EOpTextureFetchOffset: arg = (arg0->getType().getSampler().isRect()) ? 2 : 3; break;
  1838. case EOpTextureProjOffset: arg = 2; break;
  1839. case EOpTextureLodOffset: arg = 3; break;
  1840. case EOpTextureProjLodOffset: arg = 3; break;
  1841. case EOpTextureGradOffset: arg = 4; break;
  1842. case EOpTextureProjGradOffset: arg = 4; break;
  1843. default:
  1844. assert(0);
  1845. break;
  1846. }
  1847. if (arg > 0) {
  1848. #ifndef GLSLANG_WEB
  1849. bool f16ShadowCompare = (*argp)[1]->getAsTyped()->getBasicType() == EbtFloat16 &&
  1850. arg0->getType().getSampler().shadow;
  1851. if (f16ShadowCompare)
  1852. ++arg;
  1853. #endif
  1854. if (! (*argp)[arg]->getAsTyped()->getQualifier().isConstant())
  1855. error(loc, "argument must be compile-time constant", "texel offset", "");
  1856. else if ((*argp)[arg]->getAsConstantUnion()) {
  1857. const TType& type = (*argp)[arg]->getAsTyped()->getType();
  1858. for (int c = 0; c < type.getVectorSize(); ++c) {
  1859. int offset = (*argp)[arg]->getAsConstantUnion()->getConstArray()[c].getIConst();
  1860. if (offset > resources.maxProgramTexelOffset || offset < resources.minProgramTexelOffset)
  1861. error(loc, "value is out of range:", "texel offset",
  1862. "[gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]");
  1863. }
  1864. }
  1865. }
  1866. break;
  1867. }
  1868. #ifndef GLSLANG_WEB
  1869. case EOpTraceNV:
  1870. if (!(*argp)[10]->getAsConstantUnion())
  1871. error(loc, "argument must be compile-time constant", "payload number", "a");
  1872. break;
  1873. case EOpTraceKHR:
  1874. if (!(*argp)[10]->getAsConstantUnion())
  1875. error(loc, "argument must be compile-time constant", "payload number", "a");
  1876. else {
  1877. unsigned int location = (*argp)[10]->getAsConstantUnion()->getAsConstantUnion()->getConstArray()[0].getUConst();
  1878. if (intermediate.checkLocationRT(0, location) < 0)
  1879. error(loc, "with layout(location =", "no rayPayloadEXT/rayPayloadInEXT declared", "%d)", location);
  1880. }
  1881. break;
  1882. case EOpExecuteCallableNV:
  1883. if (!(*argp)[1]->getAsConstantUnion())
  1884. error(loc, "argument must be compile-time constant", "callable data number", "");
  1885. break;
  1886. case EOpExecuteCallableKHR:
  1887. if (!(*argp)[1]->getAsConstantUnion())
  1888. error(loc, "argument must be compile-time constant", "callable data number", "");
  1889. else {
  1890. unsigned int location = (*argp)[1]->getAsConstantUnion()->getAsConstantUnion()->getConstArray()[0].getUConst();
  1891. if (intermediate.checkLocationRT(1, location) < 0)
  1892. error(loc, "with layout(location =", "no callableDataEXT/callableDataInEXT declared", "%d)", location);
  1893. }
  1894. break;
  1895. case EOpRayQueryGetIntersectionType:
  1896. case EOpRayQueryGetIntersectionT:
  1897. case EOpRayQueryGetIntersectionInstanceCustomIndex:
  1898. case EOpRayQueryGetIntersectionInstanceId:
  1899. case EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset:
  1900. case EOpRayQueryGetIntersectionGeometryIndex:
  1901. case EOpRayQueryGetIntersectionPrimitiveIndex:
  1902. case EOpRayQueryGetIntersectionBarycentrics:
  1903. case EOpRayQueryGetIntersectionFrontFace:
  1904. case EOpRayQueryGetIntersectionObjectRayDirection:
  1905. case EOpRayQueryGetIntersectionObjectRayOrigin:
  1906. case EOpRayQueryGetIntersectionObjectToWorld:
  1907. case EOpRayQueryGetIntersectionWorldToObject:
  1908. if (!(*argp)[1]->getAsConstantUnion())
  1909. error(loc, "argument must be compile-time constant", "committed", "");
  1910. break;
  1911. case EOpTextureQuerySamples:
  1912. case EOpImageQuerySamples:
  1913. // GL_ARB_shader_texture_image_samples
  1914. profileRequires(loc, ~EEsProfile, 450, E_GL_ARB_shader_texture_image_samples, "textureSamples and imageSamples");
  1915. break;
  1916. case EOpImageAtomicAdd:
  1917. case EOpImageAtomicMin:
  1918. case EOpImageAtomicMax:
  1919. case EOpImageAtomicAnd:
  1920. case EOpImageAtomicOr:
  1921. case EOpImageAtomicXor:
  1922. case EOpImageAtomicExchange:
  1923. case EOpImageAtomicCompSwap:
  1924. case EOpImageAtomicLoad:
  1925. case EOpImageAtomicStore:
  1926. {
  1927. // Make sure the image types have the correct layout() format and correct argument types
  1928. const TType& imageType = arg0->getType();
  1929. if (imageType.getSampler().type == EbtInt || imageType.getSampler().type == EbtUint ||
  1930. imageType.getSampler().type == EbtInt64 || imageType.getSampler().type == EbtUint64) {
  1931. if (imageType.getQualifier().getFormat() != ElfR32i && imageType.getQualifier().getFormat() != ElfR32ui &&
  1932. imageType.getQualifier().getFormat() != ElfR64i && imageType.getQualifier().getFormat() != ElfR64ui)
  1933. error(loc, "only supported on image with format r32i or r32ui", fnCandidate.getName().c_str(), "");
  1934. if (callNode.getType().getBasicType() == EbtInt64 && imageType.getQualifier().getFormat() != ElfR64i)
  1935. error(loc, "only supported on image with format r64i", fnCandidate.getName().c_str(), "");
  1936. else if (callNode.getType().getBasicType() == EbtUint64 && imageType.getQualifier().getFormat() != ElfR64ui)
  1937. error(loc, "only supported on image with format r64ui", fnCandidate.getName().c_str(), "");
  1938. } else {
  1939. bool isImageAtomicOnFloatAllowed = ((fnCandidate.getName().compare(0, 14, "imageAtomicAdd") == 0) ||
  1940. (fnCandidate.getName().compare(0, 15, "imageAtomicLoad") == 0) ||
  1941. (fnCandidate.getName().compare(0, 16, "imageAtomicStore") == 0) ||
  1942. (fnCandidate.getName().compare(0, 19, "imageAtomicExchange") == 0));
  1943. if (imageType.getSampler().type == EbtFloat && isImageAtomicOnFloatAllowed &&
  1944. (fnCandidate.getName().compare(0, 19, "imageAtomicExchange") != 0)) // imageAtomicExchange doesn't require GL_EXT_shader_atomic_float
  1945. requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float, fnCandidate.getName().c_str());
  1946. if (!isImageAtomicOnFloatAllowed)
  1947. error(loc, "only supported on integer images", fnCandidate.getName().c_str(), "");
  1948. else if (imageType.getQualifier().getFormat() != ElfR32f && isEsProfile())
  1949. error(loc, "only supported on image with format r32f", fnCandidate.getName().c_str(), "");
  1950. }
  1951. const size_t maxArgs = imageType.getSampler().isMultiSample() ? 5 : 4;
  1952. if (argp->size() > maxArgs) {
  1953. requireExtensions(loc, 1, &E_GL_KHR_memory_scope_semantics, fnCandidate.getName().c_str());
  1954. memorySemanticsCheck(loc, fnCandidate, callNode);
  1955. }
  1956. break;
  1957. }
  1958. case EOpAtomicAdd:
  1959. case EOpAtomicMin:
  1960. case EOpAtomicMax:
  1961. case EOpAtomicAnd:
  1962. case EOpAtomicOr:
  1963. case EOpAtomicXor:
  1964. case EOpAtomicExchange:
  1965. case EOpAtomicCompSwap:
  1966. case EOpAtomicLoad:
  1967. case EOpAtomicStore:
  1968. {
  1969. if (argp->size() > 3) {
  1970. requireExtensions(loc, 1, &E_GL_KHR_memory_scope_semantics, fnCandidate.getName().c_str());
  1971. memorySemanticsCheck(loc, fnCandidate, callNode);
  1972. if ((callNode.getOp() == EOpAtomicAdd || callNode.getOp() == EOpAtomicExchange ||
  1973. callNode.getOp() == EOpAtomicLoad || callNode.getOp() == EOpAtomicStore) &&
  1974. (arg0->getType().isFloatingDomain())) {
  1975. requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float, fnCandidate.getName().c_str());
  1976. }
  1977. } else if (arg0->getType().getBasicType() == EbtInt64 || arg0->getType().getBasicType() == EbtUint64) {
  1978. const char* const extensions[2] = { E_GL_NV_shader_atomic_int64,
  1979. E_GL_EXT_shader_atomic_int64 };
  1980. requireExtensions(loc, 2, extensions, fnCandidate.getName().c_str());
  1981. } else if ((callNode.getOp() == EOpAtomicAdd || callNode.getOp() == EOpAtomicExchange) &&
  1982. (arg0->getType().isFloatingDomain())) {
  1983. requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float, fnCandidate.getName().c_str());
  1984. }
  1985. break;
  1986. }
  1987. case EOpInterpolateAtCentroid:
  1988. case EOpInterpolateAtSample:
  1989. case EOpInterpolateAtOffset:
  1990. case EOpInterpolateAtVertex:
  1991. // Make sure the first argument is an interpolant, or an array element of an interpolant
  1992. if (arg0->getType().getQualifier().storage != EvqVaryingIn) {
  1993. // It might still be an array element.
  1994. //
  1995. // We could check more, but the semantics of the first argument are already met; the
  1996. // only way to turn an array into a float/vec* is array dereference and swizzle.
  1997. //
  1998. // ES and desktop 4.3 and earlier: swizzles may not be used
  1999. // desktop 4.4 and later: swizzles may be used
  2000. bool swizzleOkay = (!isEsProfile()) && (version >= 440);
  2001. const TIntermTyped* base = TIntermediate::findLValueBase(arg0, swizzleOkay);
  2002. if (base == nullptr || base->getType().getQualifier().storage != EvqVaryingIn)
  2003. error(loc, "first argument must be an interpolant, or interpolant-array element", fnCandidate.getName().c_str(), "");
  2004. }
  2005. if (callNode.getOp() == EOpInterpolateAtVertex) {
  2006. if (!arg0->getType().getQualifier().isExplicitInterpolation())
  2007. error(loc, "argument must be qualified as __explicitInterpAMD in", "interpolant", "");
  2008. else {
  2009. if (! (*argp)[1]->getAsConstantUnion())
  2010. error(loc, "argument must be compile-time constant", "vertex index", "");
  2011. else {
  2012. unsigned vertexIdx = (*argp)[1]->getAsConstantUnion()->getConstArray()[0].getUConst();
  2013. if (vertexIdx > 2)
  2014. error(loc, "must be in the range [0, 2]", "vertex index", "");
  2015. }
  2016. }
  2017. }
  2018. break;
  2019. case EOpEmitStreamVertex:
  2020. case EOpEndStreamPrimitive:
  2021. intermediate.setMultiStream();
  2022. break;
  2023. case EOpSubgroupClusteredAdd:
  2024. case EOpSubgroupClusteredMul:
  2025. case EOpSubgroupClusteredMin:
  2026. case EOpSubgroupClusteredMax:
  2027. case EOpSubgroupClusteredAnd:
  2028. case EOpSubgroupClusteredOr:
  2029. case EOpSubgroupClusteredXor:
  2030. // The <clusterSize> as used in the subgroupClustered<op>() operations must be:
  2031. // - An integral constant expression.
  2032. // - At least 1.
  2033. // - A power of 2.
  2034. if ((*argp)[1]->getAsConstantUnion() == nullptr)
  2035. error(loc, "argument must be compile-time constant", "cluster size", "");
  2036. else {
  2037. int size = (*argp)[1]->getAsConstantUnion()->getConstArray()[0].getIConst();
  2038. if (size < 1)
  2039. error(loc, "argument must be at least 1", "cluster size", "");
  2040. else if (!IsPow2(size))
  2041. error(loc, "argument must be a power of 2", "cluster size", "");
  2042. }
  2043. break;
  2044. case EOpSubgroupBroadcast:
  2045. case EOpSubgroupQuadBroadcast:
  2046. if (spvVersion.spv < EShTargetSpv_1_5) {
  2047. // <id> must be an integral constant expression.
  2048. if ((*argp)[1]->getAsConstantUnion() == nullptr)
  2049. error(loc, "argument must be compile-time constant", "id", "");
  2050. }
  2051. break;
  2052. case EOpBarrier:
  2053. case EOpMemoryBarrier:
  2054. if (argp->size() > 0) {
  2055. requireExtensions(loc, 1, &E_GL_KHR_memory_scope_semantics, fnCandidate.getName().c_str());
  2056. memorySemanticsCheck(loc, fnCandidate, callNode);
  2057. }
  2058. break;
  2059. case EOpMix:
  2060. if (profile == EEsProfile && version < 310) {
  2061. // Look for specific signatures
  2062. if ((*argp)[0]->getAsTyped()->getBasicType() != EbtFloat &&
  2063. (*argp)[1]->getAsTyped()->getBasicType() != EbtFloat &&
  2064. (*argp)[2]->getAsTyped()->getBasicType() == EbtBool) {
  2065. requireExtensions(loc, 1, &E_GL_EXT_shader_integer_mix, "specific signature of builtin mix");
  2066. }
  2067. }
  2068. if (profile != EEsProfile && version < 450) {
  2069. if ((*argp)[0]->getAsTyped()->getBasicType() != EbtFloat &&
  2070. (*argp)[0]->getAsTyped()->getBasicType() != EbtDouble &&
  2071. (*argp)[1]->getAsTyped()->getBasicType() != EbtFloat &&
  2072. (*argp)[1]->getAsTyped()->getBasicType() != EbtDouble &&
  2073. (*argp)[2]->getAsTyped()->getBasicType() == EbtBool) {
  2074. requireExtensions(loc, 1, &E_GL_EXT_shader_integer_mix, fnCandidate.getName().c_str());
  2075. }
  2076. }
  2077. break;
  2078. #endif
  2079. default:
  2080. break;
  2081. }
  2082. // Texture operations on texture objects (aside from texelFetch on a
  2083. // textureBuffer) require EXT_samplerless_texture_functions.
  2084. switch (callNode.getOp()) {
  2085. case EOpTextureQuerySize:
  2086. case EOpTextureQueryLevels:
  2087. case EOpTextureQuerySamples:
  2088. case EOpTextureFetch:
  2089. case EOpTextureFetchOffset:
  2090. {
  2091. const TSampler& sampler = fnCandidate[0].type->getSampler();
  2092. const bool isTexture = sampler.isTexture() && !sampler.isCombined();
  2093. const bool isBuffer = sampler.isBuffer();
  2094. const bool isFetch = callNode.getOp() == EOpTextureFetch || callNode.getOp() == EOpTextureFetchOffset;
  2095. if (isTexture && (!isBuffer || !isFetch))
  2096. requireExtensions(loc, 1, &E_GL_EXT_samplerless_texture_functions, fnCandidate.getName().c_str());
  2097. break;
  2098. }
  2099. default:
  2100. break;
  2101. }
  2102. if (callNode.isSubgroup()) {
  2103. // these require SPIR-V 1.3
  2104. if (spvVersion.spv > 0 && spvVersion.spv < EShTargetSpv_1_3)
  2105. error(loc, "requires SPIR-V 1.3", "subgroup op", "");
  2106. // Check that if extended types are being used that the correct extensions are enabled.
  2107. if (arg0 != nullptr) {
  2108. const TType& type = arg0->getType();
  2109. switch (type.getBasicType()) {
  2110. default:
  2111. break;
  2112. case EbtInt8:
  2113. case EbtUint8:
  2114. requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int8, type.getCompleteString().c_str());
  2115. break;
  2116. case EbtInt16:
  2117. case EbtUint16:
  2118. requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int16, type.getCompleteString().c_str());
  2119. break;
  2120. case EbtInt64:
  2121. case EbtUint64:
  2122. requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int64, type.getCompleteString().c_str());
  2123. break;
  2124. case EbtFloat16:
  2125. requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_float16, type.getCompleteString().c_str());
  2126. break;
  2127. }
  2128. }
  2129. }
  2130. }
  2131. #ifndef GLSLANG_WEB
  2132. extern bool PureOperatorBuiltins;
  2133. // Deprecated! Use PureOperatorBuiltins == true instead, in which case this
  2134. // functionality is handled in builtInOpCheck() instead of here.
  2135. //
  2136. // Do additional checking of built-in function calls that were not mapped
  2137. // to built-in operations (e.g., texturing functions).
  2138. //
  2139. // Assumes there has been a semantically correct match to a built-in function.
  2140. //
  2141. void TParseContext::nonOpBuiltInCheck(const TSourceLoc& loc, const TFunction& fnCandidate, TIntermAggregate& callNode)
  2142. {
  2143. // Further maintenance of this function is deprecated, because the "correct"
  2144. // future-oriented design is to not have to do string compares on function names.
  2145. // If PureOperatorBuiltins == true, then all built-ins should be mapped
  2146. // to a TOperator, and this function would then never get called.
  2147. assert(PureOperatorBuiltins == false);
  2148. // built-in texturing functions get their return value precision from the precision of the sampler
  2149. if (fnCandidate.getType().getQualifier().precision == EpqNone &&
  2150. fnCandidate.getParamCount() > 0 && fnCandidate[0].type->getBasicType() == EbtSampler)
  2151. callNode.getQualifier().precision = callNode.getSequence()[0]->getAsTyped()->getQualifier().precision;
  2152. if (fnCandidate.getName().compare(0, 7, "texture") == 0) {
  2153. if (fnCandidate.getName().compare(0, 13, "textureGather") == 0) {
  2154. TString featureString = fnCandidate.getName() + "(...)";
  2155. const char* feature = featureString.c_str();
  2156. profileRequires(loc, EEsProfile, 310, nullptr, feature);
  2157. int compArg = -1; // track which argument, if any, is the constant component argument
  2158. if (fnCandidate.getName().compare("textureGatherOffset") == 0) {
  2159. // GL_ARB_texture_gather is good enough for 2D non-shadow textures with no component argument
  2160. if (fnCandidate[0].type->getSampler().dim == Esd2D && ! fnCandidate[0].type->getSampler().shadow && fnCandidate.getParamCount() == 3)
  2161. profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_texture_gather, feature);
  2162. else
  2163. profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_gpu_shader5, feature);
  2164. int offsetArg = fnCandidate[0].type->getSampler().shadow ? 3 : 2;
  2165. if (! callNode.getSequence()[offsetArg]->getAsConstantUnion())
  2166. profileRequires(loc, EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5,
  2167. "non-constant offset argument");
  2168. if (! fnCandidate[0].type->getSampler().shadow)
  2169. compArg = 3;
  2170. } else if (fnCandidate.getName().compare("textureGatherOffsets") == 0) {
  2171. profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_gpu_shader5, feature);
  2172. if (! fnCandidate[0].type->getSampler().shadow)
  2173. compArg = 3;
  2174. // check for constant offsets
  2175. int offsetArg = fnCandidate[0].type->getSampler().shadow ? 3 : 2;
  2176. if (! callNode.getSequence()[offsetArg]->getAsConstantUnion())
  2177. error(loc, "must be a compile-time constant:", feature, "offsets argument");
  2178. } else if (fnCandidate.getName().compare("textureGather") == 0) {
  2179. // More than two arguments needs gpu_shader5, and rectangular or shadow needs gpu_shader5,
  2180. // otherwise, need GL_ARB_texture_gather.
  2181. if (fnCandidate.getParamCount() > 2 || fnCandidate[0].type->getSampler().dim == EsdRect || fnCandidate[0].type->getSampler().shadow) {
  2182. profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_gpu_shader5, feature);
  2183. if (! fnCandidate[0].type->getSampler().shadow)
  2184. compArg = 2;
  2185. } else
  2186. profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_texture_gather, feature);
  2187. }
  2188. if (compArg > 0 && compArg < fnCandidate.getParamCount()) {
  2189. if (callNode.getSequence()[compArg]->getAsConstantUnion()) {
  2190. int value = callNode.getSequence()[compArg]->getAsConstantUnion()->getConstArray()[0].getIConst();
  2191. if (value < 0 || value > 3)
  2192. error(loc, "must be 0, 1, 2, or 3:", feature, "component argument");
  2193. } else
  2194. error(loc, "must be a compile-time constant:", feature, "component argument");
  2195. }
  2196. } else {
  2197. // this is only for functions not starting "textureGather"...
  2198. if (fnCandidate.getName().find("Offset") != TString::npos) {
  2199. // Handle texture-offset limits checking
  2200. int arg = -1;
  2201. if (fnCandidate.getName().compare("textureOffset") == 0)
  2202. arg = 2;
  2203. else if (fnCandidate.getName().compare("texelFetchOffset") == 0)
  2204. arg = 3;
  2205. else if (fnCandidate.getName().compare("textureProjOffset") == 0)
  2206. arg = 2;
  2207. else if (fnCandidate.getName().compare("textureLodOffset") == 0)
  2208. arg = 3;
  2209. else if (fnCandidate.getName().compare("textureProjLodOffset") == 0)
  2210. arg = 3;
  2211. else if (fnCandidate.getName().compare("textureGradOffset") == 0)
  2212. arg = 4;
  2213. else if (fnCandidate.getName().compare("textureProjGradOffset") == 0)
  2214. arg = 4;
  2215. if (arg > 0) {
  2216. if (! callNode.getSequence()[arg]->getAsConstantUnion())
  2217. error(loc, "argument must be compile-time constant", "texel offset", "");
  2218. else {
  2219. const TType& type = callNode.getSequence()[arg]->getAsTyped()->getType();
  2220. for (int c = 0; c < type.getVectorSize(); ++c) {
  2221. int offset = callNode.getSequence()[arg]->getAsConstantUnion()->getConstArray()[c].getIConst();
  2222. if (offset > resources.maxProgramTexelOffset || offset < resources.minProgramTexelOffset)
  2223. error(loc, "value is out of range:", "texel offset", "[gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]");
  2224. }
  2225. }
  2226. }
  2227. }
  2228. }
  2229. }
  2230. // GL_ARB_shader_texture_image_samples
  2231. if (fnCandidate.getName().compare(0, 14, "textureSamples") == 0 || fnCandidate.getName().compare(0, 12, "imageSamples") == 0)
  2232. profileRequires(loc, ~EEsProfile, 450, E_GL_ARB_shader_texture_image_samples, "textureSamples and imageSamples");
  2233. if (fnCandidate.getName().compare(0, 11, "imageAtomic") == 0) {
  2234. const TType& imageType = callNode.getSequence()[0]->getAsTyped()->getType();
  2235. if (imageType.getSampler().type == EbtInt || imageType.getSampler().type == EbtUint) {
  2236. if (imageType.getQualifier().getFormat() != ElfR32i && imageType.getQualifier().getFormat() != ElfR32ui)
  2237. error(loc, "only supported on image with format r32i or r32ui", fnCandidate.getName().c_str(), "");
  2238. } else {
  2239. if (fnCandidate.getName().compare(0, 19, "imageAtomicExchange") != 0)
  2240. error(loc, "only supported on integer images", fnCandidate.getName().c_str(), "");
  2241. else if (imageType.getQualifier().getFormat() != ElfR32f && isEsProfile())
  2242. error(loc, "only supported on image with format r32f", fnCandidate.getName().c_str(), "");
  2243. }
  2244. }
  2245. }
  2246. #endif
  2247. //
  2248. // Do any extra checking for a user function call.
  2249. //
  2250. void TParseContext::userFunctionCallCheck(const TSourceLoc& loc, TIntermAggregate& callNode)
  2251. {
  2252. TIntermSequence& arguments = callNode.getSequence();
  2253. for (int i = 0; i < (int)arguments.size(); ++i)
  2254. samplerConstructorLocationCheck(loc, "call argument", arguments[i]);
  2255. }
  2256. //
  2257. // Emit an error if this is a sampler constructor
  2258. //
  2259. void TParseContext::samplerConstructorLocationCheck(const TSourceLoc& loc, const char* token, TIntermNode* node)
  2260. {
  2261. if (node->getAsOperator() && node->getAsOperator()->getOp() == EOpConstructTextureSampler)
  2262. error(loc, "sampler constructor must appear at point of use", token, "");
  2263. }
  2264. //
  2265. // Handle seeing a built-in constructor in a grammar production.
  2266. //
  2267. TFunction* TParseContext::handleConstructorCall(const TSourceLoc& loc, const TPublicType& publicType)
  2268. {
  2269. TType type(publicType);
  2270. type.getQualifier().precision = EpqNone;
  2271. if (type.isArray()) {
  2272. profileRequires(loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed constructor");
  2273. profileRequires(loc, EEsProfile, 300, nullptr, "arrayed constructor");
  2274. }
  2275. TOperator op = intermediate.mapTypeToConstructorOp(type);
  2276. if (op == EOpNull) {
  2277. error(loc, "cannot construct this type", type.getBasicString(), "");
  2278. op = EOpConstructFloat;
  2279. TType errorType(EbtFloat);
  2280. type.shallowCopy(errorType);
  2281. }
  2282. TString empty("");
  2283. return new TFunction(&empty, type, op);
  2284. }
  2285. // Handle seeing a precision qualifier in the grammar.
  2286. void TParseContext::handlePrecisionQualifier(const TSourceLoc& /*loc*/, TQualifier& qualifier, TPrecisionQualifier precision)
  2287. {
  2288. if (obeyPrecisionQualifiers())
  2289. qualifier.precision = precision;
  2290. }
  2291. // Check for messages to give on seeing a precision qualifier used in a
  2292. // declaration in the grammar.
  2293. void TParseContext::checkPrecisionQualifier(const TSourceLoc& loc, TPrecisionQualifier)
  2294. {
  2295. if (precisionManager.shouldWarnAboutDefaults()) {
  2296. warn(loc, "all default precisions are highp; use precision statements to quiet warning, e.g.:\n"
  2297. " \"precision mediump int; precision highp float;\"", "", "");
  2298. precisionManager.defaultWarningGiven();
  2299. }
  2300. }
  2301. //
  2302. // Same error message for all places assignments don't work.
  2303. //
  2304. void TParseContext::assignError(const TSourceLoc& loc, const char* op, TString left, TString right)
  2305. {
  2306. error(loc, "", op, "cannot convert from '%s' to '%s'",
  2307. right.c_str(), left.c_str());
  2308. }
  2309. //
  2310. // Same error message for all places unary operations don't work.
  2311. //
  2312. void TParseContext::unaryOpError(const TSourceLoc& loc, const char* op, TString operand)
  2313. {
  2314. error(loc, " wrong operand type", op,
  2315. "no operation '%s' exists that takes an operand of type %s (or there is no acceptable conversion)",
  2316. op, operand.c_str());
  2317. }
  2318. //
  2319. // Same error message for all binary operations don't work.
  2320. //
  2321. void TParseContext::binaryOpError(const TSourceLoc& loc, const char* op, TString left, TString right)
  2322. {
  2323. error(loc, " wrong operand types:", op,
  2324. "no operation '%s' exists that takes a left-hand operand of type '%s' and "
  2325. "a right operand of type '%s' (or there is no acceptable conversion)",
  2326. op, left.c_str(), right.c_str());
  2327. }
  2328. //
  2329. // A basic type of EbtVoid is a key that the name string was seen in the source, but
  2330. // it was not found as a variable in the symbol table. If so, give the error
  2331. // message and insert a dummy variable in the symbol table to prevent future errors.
  2332. //
  2333. void TParseContext::variableCheck(TIntermTyped*& nodePtr)
  2334. {
  2335. TIntermSymbol* symbol = nodePtr->getAsSymbolNode();
  2336. if (! symbol)
  2337. return;
  2338. if (symbol->getType().getBasicType() == EbtVoid) {
  2339. const char *extraInfoFormat = "";
  2340. if (spvVersion.vulkan != 0 && symbol->getName() == "gl_VertexID") {
  2341. extraInfoFormat = "(Did you mean gl_VertexIndex?)";
  2342. } else if (spvVersion.vulkan != 0 && symbol->getName() == "gl_InstanceID") {
  2343. extraInfoFormat = "(Did you mean gl_InstanceIndex?)";
  2344. }
  2345. error(symbol->getLoc(), "undeclared identifier", symbol->getName().c_str(), extraInfoFormat);
  2346. // Add to symbol table to prevent future error messages on the same name
  2347. if (symbol->getName().size() > 0) {
  2348. TVariable* fakeVariable = new TVariable(&symbol->getName(), TType(EbtFloat));
  2349. symbolTable.insert(*fakeVariable);
  2350. // substitute a symbol node for this new variable
  2351. nodePtr = intermediate.addSymbol(*fakeVariable, symbol->getLoc());
  2352. }
  2353. } else {
  2354. switch (symbol->getQualifier().storage) {
  2355. case EvqPointCoord:
  2356. profileRequires(symbol->getLoc(), ENoProfile, 120, nullptr, "gl_PointCoord");
  2357. break;
  2358. default: break; // some compilers want this
  2359. }
  2360. }
  2361. }
  2362. //
  2363. // Both test and if necessary, spit out an error, to see if the node is really
  2364. // an l-value that can be operated on this way.
  2365. //
  2366. // Returns true if there was an error.
  2367. //
  2368. bool TParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, TIntermTyped* node)
  2369. {
  2370. TIntermBinary* binaryNode = node->getAsBinaryNode();
  2371. if (binaryNode) {
  2372. bool errorReturn = false;
  2373. switch(binaryNode->getOp()) {
  2374. #ifndef GLSLANG_WEB
  2375. case EOpIndexDirect:
  2376. case EOpIndexIndirect:
  2377. // ... tessellation control shader ...
  2378. // If a per-vertex output variable is used as an l-value, it is a
  2379. // compile-time or link-time error if the expression indicating the
  2380. // vertex index is not the identifier gl_InvocationID.
  2381. if (language == EShLangTessControl) {
  2382. const TType& leftType = binaryNode->getLeft()->getType();
  2383. if (leftType.getQualifier().storage == EvqVaryingOut && ! leftType.getQualifier().patch && binaryNode->getLeft()->getAsSymbolNode()) {
  2384. // we have a per-vertex output
  2385. const TIntermSymbol* rightSymbol = binaryNode->getRight()->getAsSymbolNode();
  2386. if (! rightSymbol || rightSymbol->getQualifier().builtIn != EbvInvocationId)
  2387. error(loc, "tessellation-control per-vertex output l-value must be indexed with gl_InvocationID", "[]", "");
  2388. }
  2389. }
  2390. break; // left node is checked by base class
  2391. #endif
  2392. case EOpVectorSwizzle:
  2393. errorReturn = lValueErrorCheck(loc, op, binaryNode->getLeft());
  2394. if (!errorReturn) {
  2395. int offset[4] = {0,0,0,0};
  2396. TIntermTyped* rightNode = binaryNode->getRight();
  2397. TIntermAggregate *aggrNode = rightNode->getAsAggregate();
  2398. for (TIntermSequence::iterator p = aggrNode->getSequence().begin();
  2399. p != aggrNode->getSequence().end(); p++) {
  2400. int value = (*p)->getAsTyped()->getAsConstantUnion()->getConstArray()[0].getIConst();
  2401. offset[value]++;
  2402. if (offset[value] > 1) {
  2403. error(loc, " l-value of swizzle cannot have duplicate components", op, "", "");
  2404. return true;
  2405. }
  2406. }
  2407. }
  2408. return errorReturn;
  2409. default:
  2410. break;
  2411. }
  2412. if (errorReturn) {
  2413. error(loc, " l-value required", op, "", "");
  2414. return true;
  2415. }
  2416. }
  2417. if (binaryNode && binaryNode->getOp() == EOpIndexDirectStruct && binaryNode->getLeft()->isReference())
  2418. return false;
  2419. // Let the base class check errors
  2420. if (TParseContextBase::lValueErrorCheck(loc, op, node))
  2421. return true;
  2422. const char* symbol = nullptr;
  2423. TIntermSymbol* symNode = node->getAsSymbolNode();
  2424. if (symNode != nullptr)
  2425. symbol = symNode->getName().c_str();
  2426. const char* message = nullptr;
  2427. switch (node->getQualifier().storage) {
  2428. case EvqVaryingIn: message = "can't modify shader input"; break;
  2429. case EvqInstanceId: message = "can't modify gl_InstanceID"; break;
  2430. case EvqVertexId: message = "can't modify gl_VertexID"; break;
  2431. case EvqFace: message = "can't modify gl_FrontFace"; break;
  2432. case EvqFragCoord: message = "can't modify gl_FragCoord"; break;
  2433. case EvqPointCoord: message = "can't modify gl_PointCoord"; break;
  2434. case EvqFragDepth:
  2435. intermediate.setDepthReplacing();
  2436. // "In addition, it is an error to statically write to gl_FragDepth in the fragment shader."
  2437. if (isEsProfile() && intermediate.getEarlyFragmentTests())
  2438. message = "can't modify gl_FragDepth if using early_fragment_tests";
  2439. break;
  2440. default:
  2441. break;
  2442. }
  2443. if (message == nullptr && binaryNode == nullptr && symNode == nullptr) {
  2444. error(loc, " l-value required", op, "", "");
  2445. return true;
  2446. }
  2447. //
  2448. // Everything else is okay, no error.
  2449. //
  2450. if (message == nullptr)
  2451. return false;
  2452. //
  2453. // If we get here, we have an error and a message.
  2454. //
  2455. if (symNode)
  2456. error(loc, " l-value required", op, "\"%s\" (%s)", symbol, message);
  2457. else
  2458. error(loc, " l-value required", op, "(%s)", message);
  2459. return true;
  2460. }
  2461. // Test for and give an error if the node can't be read from.
  2462. void TParseContext::rValueErrorCheck(const TSourceLoc& loc, const char* op, TIntermTyped* node)
  2463. {
  2464. // Let the base class check errors
  2465. TParseContextBase::rValueErrorCheck(loc, op, node);
  2466. TIntermSymbol* symNode = node->getAsSymbolNode();
  2467. if (!(symNode && symNode->getQualifier().isWriteOnly())) // base class checks
  2468. if (symNode && symNode->getQualifier().isExplicitInterpolation())
  2469. error(loc, "can't read from explicitly-interpolated object: ", op, symNode->getName().c_str());
  2470. }
  2471. //
  2472. // Both test, and if necessary spit out an error, to see if the node is really
  2473. // a constant.
  2474. //
  2475. void TParseContext::constantValueCheck(TIntermTyped* node, const char* token)
  2476. {
  2477. if (! node->getQualifier().isConstant())
  2478. error(node->getLoc(), "constant expression required", token, "");
  2479. }
  2480. //
  2481. // Both test, and if necessary spit out an error, to see if the node is really
  2482. // an integer.
  2483. //
  2484. void TParseContext::integerCheck(const TIntermTyped* node, const char* token)
  2485. {
  2486. if ((node->getBasicType() == EbtInt || node->getBasicType() == EbtUint) && node->isScalar())
  2487. return;
  2488. error(node->getLoc(), "scalar integer expression required", token, "");
  2489. }
  2490. //
  2491. // Both test, and if necessary spit out an error, to see if we are currently
  2492. // globally scoped.
  2493. //
  2494. void TParseContext::globalCheck(const TSourceLoc& loc, const char* token)
  2495. {
  2496. if (! symbolTable.atGlobalLevel())
  2497. error(loc, "not allowed in nested scope", token, "");
  2498. }
  2499. //
  2500. // Reserved errors for GLSL.
  2501. //
  2502. void TParseContext::reservedErrorCheck(const TSourceLoc& loc, const TString& identifier)
  2503. {
  2504. // "Identifiers starting with "gl_" are reserved for use by OpenGL, and may not be
  2505. // declared in a shader; this results in a compile-time error."
  2506. if (! symbolTable.atBuiltInLevel()) {
  2507. if (builtInName(identifier))
  2508. error(loc, "identifiers starting with \"gl_\" are reserved", identifier.c_str(), "");
  2509. // "__" are not supposed to be an error. ES 300 (and desktop) added the clarification:
  2510. // "In addition, all identifiers containing two consecutive underscores (__) are
  2511. // reserved; using such a name does not itself result in an error, but may result
  2512. // in undefined behavior."
  2513. // however, before that, ES tests required an error.
  2514. if (identifier.find("__") != TString::npos) {
  2515. if (isEsProfile() && version < 300)
  2516. error(loc, "identifiers containing consecutive underscores (\"__\") are reserved, and an error if version < 300", identifier.c_str(), "");
  2517. else
  2518. warn(loc, "identifiers containing consecutive underscores (\"__\") are reserved", identifier.c_str(), "");
  2519. }
  2520. }
  2521. }
  2522. //
  2523. // Reserved errors for the preprocessor.
  2524. //
  2525. void TParseContext::reservedPpErrorCheck(const TSourceLoc& loc, const char* identifier, const char* op)
  2526. {
  2527. // "__" are not supposed to be an error. ES 300 (and desktop) added the clarification:
  2528. // "All macro names containing two consecutive underscores ( __ ) are reserved;
  2529. // defining such a name does not itself result in an error, but may result in
  2530. // undefined behavior. All macro names prefixed with "GL_" ("GL" followed by a
  2531. // single underscore) are also reserved, and defining such a name results in a
  2532. // compile-time error."
  2533. // however, before that, ES tests required an error.
  2534. if (strncmp(identifier, "GL_", 3) == 0)
  2535. ppError(loc, "names beginning with \"GL_\" can't be (un)defined:", op, identifier);
  2536. else if (strncmp(identifier, "defined", 8) == 0)
  2537. if (relaxedErrors())
  2538. ppWarn(loc, "\"defined\" is (un)defined:", op, identifier);
  2539. else
  2540. ppError(loc, "\"defined\" can't be (un)defined:", op, identifier);
  2541. else if (strstr(identifier, "__") != 0) {
  2542. if (isEsProfile() && version >= 300 &&
  2543. (strcmp(identifier, "__LINE__") == 0 ||
  2544. strcmp(identifier, "__FILE__") == 0 ||
  2545. strcmp(identifier, "__VERSION__") == 0))
  2546. ppError(loc, "predefined names can't be (un)defined:", op, identifier);
  2547. else {
  2548. if (isEsProfile() && version < 300 && !relaxedErrors())
  2549. ppError(loc, "names containing consecutive underscores are reserved, and an error if version < 300:", op, identifier);
  2550. else
  2551. ppWarn(loc, "names containing consecutive underscores are reserved:", op, identifier);
  2552. }
  2553. }
  2554. }
  2555. //
  2556. // See if this version/profile allows use of the line-continuation character '\'.
  2557. //
  2558. // Returns true if a line continuation should be done.
  2559. //
  2560. bool TParseContext::lineContinuationCheck(const TSourceLoc& loc, bool endOfComment)
  2561. {
  2562. #ifdef GLSLANG_WEB
  2563. return true;
  2564. #endif
  2565. const char* message = "line continuation";
  2566. bool lineContinuationAllowed = (isEsProfile() && version >= 300) ||
  2567. (!isEsProfile() && (version >= 420 || extensionTurnedOn(E_GL_ARB_shading_language_420pack)));
  2568. if (endOfComment) {
  2569. if (lineContinuationAllowed)
  2570. warn(loc, "used at end of comment; the following line is still part of the comment", message, "");
  2571. else
  2572. warn(loc, "used at end of comment, but this version does not provide line continuation", message, "");
  2573. return lineContinuationAllowed;
  2574. }
  2575. if (relaxedErrors()) {
  2576. if (! lineContinuationAllowed)
  2577. warn(loc, "not allowed in this version", message, "");
  2578. return true;
  2579. } else {
  2580. profileRequires(loc, EEsProfile, 300, nullptr, message);
  2581. profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, message);
  2582. }
  2583. return lineContinuationAllowed;
  2584. }
  2585. bool TParseContext::builtInName(const TString& identifier)
  2586. {
  2587. return identifier.compare(0, 3, "gl_") == 0;
  2588. }
  2589. //
  2590. // Make sure there is enough data and not too many arguments provided to the
  2591. // constructor to build something of the type of the constructor. Also returns
  2592. // the type of the constructor.
  2593. //
  2594. // Part of establishing type is establishing specialization-constness.
  2595. // We don't yet know "top down" whether type is a specialization constant,
  2596. // but a const constructor can becomes a specialization constant if any of
  2597. // its children are, subject to KHR_vulkan_glsl rules:
  2598. //
  2599. // - int(), uint(), and bool() constructors for type conversions
  2600. // from any of the following types to any of the following types:
  2601. // * int
  2602. // * uint
  2603. // * bool
  2604. // - vector versions of the above conversion constructors
  2605. //
  2606. // Returns true if there was an error in construction.
  2607. //
  2608. bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, TFunction& function, TOperator op, TType& type)
  2609. {
  2610. // See if the constructor does not establish the main type, only requalifies
  2611. // it, in which case the type comes from the argument instead of from the
  2612. // constructor function.
  2613. switch (op) {
  2614. #ifndef GLSLANG_WEB
  2615. case EOpConstructNonuniform:
  2616. if (node != nullptr && node->getAsTyped() != nullptr) {
  2617. type.shallowCopy(node->getAsTyped()->getType());
  2618. type.getQualifier().makeTemporary();
  2619. type.getQualifier().nonUniform = true;
  2620. }
  2621. break;
  2622. #endif
  2623. default:
  2624. type.shallowCopy(function.getType());
  2625. break;
  2626. }
  2627. // See if it's a matrix
  2628. bool constructingMatrix = false;
  2629. switch (op) {
  2630. case EOpConstructTextureSampler:
  2631. return constructorTextureSamplerError(loc, function);
  2632. case EOpConstructMat2x2:
  2633. case EOpConstructMat2x3:
  2634. case EOpConstructMat2x4:
  2635. case EOpConstructMat3x2:
  2636. case EOpConstructMat3x3:
  2637. case EOpConstructMat3x4:
  2638. case EOpConstructMat4x2:
  2639. case EOpConstructMat4x3:
  2640. case EOpConstructMat4x4:
  2641. #ifndef GLSLANG_WEB
  2642. case EOpConstructDMat2x2:
  2643. case EOpConstructDMat2x3:
  2644. case EOpConstructDMat2x4:
  2645. case EOpConstructDMat3x2:
  2646. case EOpConstructDMat3x3:
  2647. case EOpConstructDMat3x4:
  2648. case EOpConstructDMat4x2:
  2649. case EOpConstructDMat4x3:
  2650. case EOpConstructDMat4x4:
  2651. case EOpConstructF16Mat2x2:
  2652. case EOpConstructF16Mat2x3:
  2653. case EOpConstructF16Mat2x4:
  2654. case EOpConstructF16Mat3x2:
  2655. case EOpConstructF16Mat3x3:
  2656. case EOpConstructF16Mat3x4:
  2657. case EOpConstructF16Mat4x2:
  2658. case EOpConstructF16Mat4x3:
  2659. case EOpConstructF16Mat4x4:
  2660. #endif
  2661. constructingMatrix = true;
  2662. break;
  2663. default:
  2664. break;
  2665. }
  2666. //
  2667. // Walk the arguments for first-pass checks and collection of information.
  2668. //
  2669. int size = 0;
  2670. bool constType = true;
  2671. bool specConstType = false; // value is only valid if constType is true
  2672. bool full = false;
  2673. bool overFull = false;
  2674. bool matrixInMatrix = false;
  2675. bool arrayArg = false;
  2676. bool floatArgument = false;
  2677. for (int arg = 0; arg < function.getParamCount(); ++arg) {
  2678. if (function[arg].type->isArray()) {
  2679. if (function[arg].type->isUnsizedArray()) {
  2680. // Can't construct from an unsized array.
  2681. error(loc, "array argument must be sized", "constructor", "");
  2682. return true;
  2683. }
  2684. arrayArg = true;
  2685. }
  2686. if (constructingMatrix && function[arg].type->isMatrix())
  2687. matrixInMatrix = true;
  2688. // 'full' will go to true when enough args have been seen. If we loop
  2689. // again, there is an extra argument.
  2690. if (full) {
  2691. // For vectors and matrices, it's okay to have too many components
  2692. // available, but not okay to have unused arguments.
  2693. overFull = true;
  2694. }
  2695. size += function[arg].type->computeNumComponents();
  2696. if (op != EOpConstructStruct && ! type.isArray() && size >= type.computeNumComponents())
  2697. full = true;
  2698. if (! function[arg].type->getQualifier().isConstant())
  2699. constType = false;
  2700. if (function[arg].type->getQualifier().isSpecConstant())
  2701. specConstType = true;
  2702. if (function[arg].type->isFloatingDomain())
  2703. floatArgument = true;
  2704. if (type.isStruct()) {
  2705. if (function[arg].type->contains16BitFloat()) {
  2706. requireFloat16Arithmetic(loc, "constructor", "can't construct structure containing 16-bit type");
  2707. }
  2708. if (function[arg].type->contains16BitInt()) {
  2709. requireInt16Arithmetic(loc, "constructor", "can't construct structure containing 16-bit type");
  2710. }
  2711. if (function[arg].type->contains8BitInt()) {
  2712. requireInt8Arithmetic(loc, "constructor", "can't construct structure containing 8-bit type");
  2713. }
  2714. }
  2715. }
  2716. if (op == EOpConstructNonuniform)
  2717. constType = false;
  2718. #ifndef GLSLANG_WEB
  2719. switch (op) {
  2720. case EOpConstructFloat16:
  2721. case EOpConstructF16Vec2:
  2722. case EOpConstructF16Vec3:
  2723. case EOpConstructF16Vec4:
  2724. if (type.isArray())
  2725. requireFloat16Arithmetic(loc, "constructor", "16-bit arrays not supported");
  2726. if (type.isVector() && function.getParamCount() != 1)
  2727. requireFloat16Arithmetic(loc, "constructor", "16-bit vectors only take vector types");
  2728. break;
  2729. case EOpConstructUint16:
  2730. case EOpConstructU16Vec2:
  2731. case EOpConstructU16Vec3:
  2732. case EOpConstructU16Vec4:
  2733. case EOpConstructInt16:
  2734. case EOpConstructI16Vec2:
  2735. case EOpConstructI16Vec3:
  2736. case EOpConstructI16Vec4:
  2737. if (type.isArray())
  2738. requireInt16Arithmetic(loc, "constructor", "16-bit arrays not supported");
  2739. if (type.isVector() && function.getParamCount() != 1)
  2740. requireInt16Arithmetic(loc, "constructor", "16-bit vectors only take vector types");
  2741. break;
  2742. case EOpConstructUint8:
  2743. case EOpConstructU8Vec2:
  2744. case EOpConstructU8Vec3:
  2745. case EOpConstructU8Vec4:
  2746. case EOpConstructInt8:
  2747. case EOpConstructI8Vec2:
  2748. case EOpConstructI8Vec3:
  2749. case EOpConstructI8Vec4:
  2750. if (type.isArray())
  2751. requireInt8Arithmetic(loc, "constructor", "8-bit arrays not supported");
  2752. if (type.isVector() && function.getParamCount() != 1)
  2753. requireInt8Arithmetic(loc, "constructor", "8-bit vectors only take vector types");
  2754. break;
  2755. default:
  2756. break;
  2757. }
  2758. #endif
  2759. // inherit constness from children
  2760. if (constType) {
  2761. bool makeSpecConst;
  2762. // Finish pinning down spec-const semantics
  2763. if (specConstType) {
  2764. switch (op) {
  2765. case EOpConstructInt8:
  2766. case EOpConstructInt:
  2767. case EOpConstructUint:
  2768. case EOpConstructBool:
  2769. case EOpConstructBVec2:
  2770. case EOpConstructBVec3:
  2771. case EOpConstructBVec4:
  2772. case EOpConstructIVec2:
  2773. case EOpConstructIVec3:
  2774. case EOpConstructIVec4:
  2775. case EOpConstructUVec2:
  2776. case EOpConstructUVec3:
  2777. case EOpConstructUVec4:
  2778. #ifndef GLSLANG_WEB
  2779. case EOpConstructUint8:
  2780. case EOpConstructInt16:
  2781. case EOpConstructUint16:
  2782. case EOpConstructInt64:
  2783. case EOpConstructUint64:
  2784. case EOpConstructI8Vec2:
  2785. case EOpConstructI8Vec3:
  2786. case EOpConstructI8Vec4:
  2787. case EOpConstructU8Vec2:
  2788. case EOpConstructU8Vec3:
  2789. case EOpConstructU8Vec4:
  2790. case EOpConstructI16Vec2:
  2791. case EOpConstructI16Vec3:
  2792. case EOpConstructI16Vec4:
  2793. case EOpConstructU16Vec2:
  2794. case EOpConstructU16Vec3:
  2795. case EOpConstructU16Vec4:
  2796. case EOpConstructI64Vec2:
  2797. case EOpConstructI64Vec3:
  2798. case EOpConstructI64Vec4:
  2799. case EOpConstructU64Vec2:
  2800. case EOpConstructU64Vec3:
  2801. case EOpConstructU64Vec4:
  2802. #endif
  2803. // This was the list of valid ones, if they aren't converting from float
  2804. // and aren't making an array.
  2805. makeSpecConst = ! floatArgument && ! type.isArray();
  2806. break;
  2807. default:
  2808. // anything else wasn't white-listed in the spec as a conversion
  2809. makeSpecConst = false;
  2810. break;
  2811. }
  2812. } else
  2813. makeSpecConst = false;
  2814. if (makeSpecConst)
  2815. type.getQualifier().makeSpecConstant();
  2816. else if (specConstType)
  2817. type.getQualifier().makeTemporary();
  2818. else
  2819. type.getQualifier().storage = EvqConst;
  2820. }
  2821. if (type.isArray()) {
  2822. if (function.getParamCount() == 0) {
  2823. error(loc, "array constructor must have at least one argument", "constructor", "");
  2824. return true;
  2825. }
  2826. if (type.isUnsizedArray()) {
  2827. // auto adapt the constructor type to the number of arguments
  2828. type.changeOuterArraySize(function.getParamCount());
  2829. } else if (type.getOuterArraySize() != function.getParamCount()) {
  2830. error(loc, "array constructor needs one argument per array element", "constructor", "");
  2831. return true;
  2832. }
  2833. if (type.isArrayOfArrays()) {
  2834. // Types have to match, but we're still making the type.
  2835. // Finish making the type, and the comparison is done later
  2836. // when checking for conversion.
  2837. TArraySizes& arraySizes = *type.getArraySizes();
  2838. // At least the dimensionalities have to match.
  2839. if (! function[0].type->isArray() ||
  2840. arraySizes.getNumDims() != function[0].type->getArraySizes()->getNumDims() + 1) {
  2841. error(loc, "array constructor argument not correct type to construct array element", "constructor", "");
  2842. return true;
  2843. }
  2844. if (arraySizes.isInnerUnsized()) {
  2845. // "Arrays of arrays ..., and the size for any dimension is optional"
  2846. // That means we need to adopt (from the first argument) the other array sizes into the type.
  2847. for (int d = 1; d < arraySizes.getNumDims(); ++d) {
  2848. if (arraySizes.getDimSize(d) == UnsizedArraySize) {
  2849. arraySizes.setDimSize(d, function[0].type->getArraySizes()->getDimSize(d - 1));
  2850. }
  2851. }
  2852. }
  2853. }
  2854. }
  2855. if (arrayArg && op != EOpConstructStruct && ! type.isArrayOfArrays()) {
  2856. error(loc, "constructing non-array constituent from array argument", "constructor", "");
  2857. return true;
  2858. }
  2859. if (matrixInMatrix && ! type.isArray()) {
  2860. profileRequires(loc, ENoProfile, 120, nullptr, "constructing matrix from matrix");
  2861. // "If a matrix argument is given to a matrix constructor,
  2862. // it is a compile-time error to have any other arguments."
  2863. if (function.getParamCount() != 1)
  2864. error(loc, "matrix constructed from matrix can only have one argument", "constructor", "");
  2865. return false;
  2866. }
  2867. if (overFull) {
  2868. error(loc, "too many arguments", "constructor", "");
  2869. return true;
  2870. }
  2871. if (op == EOpConstructStruct && ! type.isArray() && (int)type.getStruct()->size() != function.getParamCount()) {
  2872. error(loc, "Number of constructor parameters does not match the number of structure fields", "constructor", "");
  2873. return true;
  2874. }
  2875. if ((op != EOpConstructStruct && size != 1 && size < type.computeNumComponents()) ||
  2876. (op == EOpConstructStruct && size < type.computeNumComponents())) {
  2877. error(loc, "not enough data provided for construction", "constructor", "");
  2878. return true;
  2879. }
  2880. if (type.isCoopMat() && function.getParamCount() != 1) {
  2881. error(loc, "wrong number of arguments", "constructor", "");
  2882. return true;
  2883. }
  2884. if (type.isCoopMat() &&
  2885. !(function[0].type->isScalar() || function[0].type->isCoopMat())) {
  2886. error(loc, "Cooperative matrix constructor argument must be scalar or cooperative matrix", "constructor", "");
  2887. return true;
  2888. }
  2889. TIntermTyped* typed = node->getAsTyped();
  2890. if (typed == nullptr) {
  2891. error(loc, "constructor argument does not have a type", "constructor", "");
  2892. return true;
  2893. }
  2894. if (op != EOpConstructStruct && op != EOpConstructNonuniform && typed->getBasicType() == EbtSampler) {
  2895. error(loc, "cannot convert a sampler", "constructor", "");
  2896. return true;
  2897. }
  2898. if (op != EOpConstructStruct && typed->isAtomic()) {
  2899. error(loc, "cannot convert an atomic_uint", "constructor", "");
  2900. return true;
  2901. }
  2902. if (typed->getBasicType() == EbtVoid) {
  2903. error(loc, "cannot convert a void", "constructor", "");
  2904. return true;
  2905. }
  2906. return false;
  2907. }
  2908. // Verify all the correct semantics for constructing a combined texture/sampler.
  2909. // Return true if the semantics are incorrect.
  2910. bool TParseContext::constructorTextureSamplerError(const TSourceLoc& loc, const TFunction& function)
  2911. {
  2912. TString constructorName = function.getType().getBasicTypeString(); // TODO: performance: should not be making copy; interface needs to change
  2913. const char* token = constructorName.c_str();
  2914. // exactly two arguments needed
  2915. if (function.getParamCount() != 2) {
  2916. error(loc, "sampler-constructor requires two arguments", token, "");
  2917. return true;
  2918. }
  2919. // For now, not allowing arrayed constructors, the rest of this function
  2920. // is set up to allow them, if this test is removed:
  2921. if (function.getType().isArray()) {
  2922. error(loc, "sampler-constructor cannot make an array of samplers", token, "");
  2923. return true;
  2924. }
  2925. // first argument
  2926. // * the constructor's first argument must be a texture type
  2927. // * the dimensionality (1D, 2D, 3D, Cube, Rect, Buffer, MS, and Array)
  2928. // of the texture type must match that of the constructed sampler type
  2929. // (that is, the suffixes of the type of the first argument and the
  2930. // type of the constructor will be spelled the same way)
  2931. if (function[0].type->getBasicType() != EbtSampler ||
  2932. ! function[0].type->getSampler().isTexture() ||
  2933. function[0].type->isArray()) {
  2934. error(loc, "sampler-constructor first argument must be a scalar *texture* type", token, "");
  2935. return true;
  2936. }
  2937. // simulate the first argument's impact on the result type, so it can be compared with the encapsulated operator!=()
  2938. TSampler texture = function.getType().getSampler();
  2939. texture.setCombined(false);
  2940. texture.shadow = false;
  2941. if (texture != function[0].type->getSampler()) {
  2942. error(loc, "sampler-constructor first argument must be a *texture* type"
  2943. " matching the dimensionality and sampled type of the constructor", token, "");
  2944. return true;
  2945. }
  2946. // second argument
  2947. // * the constructor's second argument must be a scalar of type
  2948. // *sampler* or *samplerShadow*
  2949. if ( function[1].type->getBasicType() != EbtSampler ||
  2950. ! function[1].type->getSampler().isPureSampler() ||
  2951. function[1].type->isArray()) {
  2952. error(loc, "sampler-constructor second argument must be a scalar sampler or samplerShadow", token, "");
  2953. return true;
  2954. }
  2955. return false;
  2956. }
  2957. // Checks to see if a void variable has been declared and raise an error message for such a case
  2958. //
  2959. // returns true in case of an error
  2960. //
  2961. bool TParseContext::voidErrorCheck(const TSourceLoc& loc, const TString& identifier, const TBasicType basicType)
  2962. {
  2963. if (basicType == EbtVoid) {
  2964. error(loc, "illegal use of type 'void'", identifier.c_str(), "");
  2965. return true;
  2966. }
  2967. return false;
  2968. }
  2969. // Checks to see if the node (for the expression) contains a scalar boolean expression or not
  2970. void TParseContext::boolCheck(const TSourceLoc& loc, const TIntermTyped* type)
  2971. {
  2972. if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector())
  2973. error(loc, "boolean expression expected", "", "");
  2974. }
  2975. // This function checks to see if the node (for the expression) contains a scalar boolean expression or not
  2976. void TParseContext::boolCheck(const TSourceLoc& loc, const TPublicType& pType)
  2977. {
  2978. if (pType.basicType != EbtBool || pType.arraySizes || pType.matrixCols > 1 || (pType.vectorSize > 1))
  2979. error(loc, "boolean expression expected", "", "");
  2980. }
  2981. void TParseContext::samplerCheck(const TSourceLoc& loc, const TType& type, const TString& identifier, TIntermTyped* /*initializer*/)
  2982. {
  2983. // Check that the appropriate extension is enabled if external sampler is used.
  2984. // There are two extensions. The correct one must be used based on GLSL version.
  2985. if (type.getBasicType() == EbtSampler && type.getSampler().isExternal()) {
  2986. if (version < 300) {
  2987. requireExtensions(loc, 1, &E_GL_OES_EGL_image_external, "samplerExternalOES");
  2988. } else {
  2989. requireExtensions(loc, 1, &E_GL_OES_EGL_image_external_essl3, "samplerExternalOES");
  2990. }
  2991. }
  2992. if (type.getSampler().isYuv()) {
  2993. requireExtensions(loc, 1, &E_GL_EXT_YUV_target, "__samplerExternal2DY2YEXT");
  2994. }
  2995. if (type.getQualifier().storage == EvqUniform)
  2996. return;
  2997. if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtSampler))
  2998. error(loc, "non-uniform struct contains a sampler or image:", type.getBasicTypeString().c_str(), identifier.c_str());
  2999. else if (type.getBasicType() == EbtSampler && type.getQualifier().storage != EvqUniform) {
  3000. // non-uniform sampler
  3001. // not yet: okay if it has an initializer
  3002. // if (! initializer)
  3003. error(loc, "sampler/image types can only be used in uniform variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str());
  3004. }
  3005. }
  3006. #ifndef GLSLANG_WEB
  3007. void TParseContext::atomicUintCheck(const TSourceLoc& loc, const TType& type, const TString& identifier)
  3008. {
  3009. if (type.getQualifier().storage == EvqUniform)
  3010. return;
  3011. if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtAtomicUint))
  3012. error(loc, "non-uniform struct contains an atomic_uint:", type.getBasicTypeString().c_str(), identifier.c_str());
  3013. else if (type.getBasicType() == EbtAtomicUint && type.getQualifier().storage != EvqUniform)
  3014. error(loc, "atomic_uints can only be used in uniform variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str());
  3015. }
  3016. void TParseContext::accStructCheck(const TSourceLoc& loc, const TType& type, const TString& identifier)
  3017. {
  3018. if (type.getQualifier().storage == EvqUniform)
  3019. return;
  3020. if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtAccStruct))
  3021. error(loc, "non-uniform struct contains an accelerationStructureNV:", type.getBasicTypeString().c_str(), identifier.c_str());
  3022. else if (type.getBasicType() == EbtAccStruct && type.getQualifier().storage != EvqUniform)
  3023. error(loc, "accelerationStructureNV can only be used in uniform variables or function parameters:",
  3024. type.getBasicTypeString().c_str(), identifier.c_str());
  3025. }
  3026. #endif // GLSLANG_WEB
  3027. void TParseContext::transparentOpaqueCheck(const TSourceLoc& loc, const TType& type, const TString& identifier)
  3028. {
  3029. if (parsingBuiltins)
  3030. return;
  3031. if (type.getQualifier().storage != EvqUniform)
  3032. return;
  3033. if (type.containsNonOpaque()) {
  3034. // Vulkan doesn't allow transparent uniforms outside of blocks
  3035. if (spvVersion.vulkan > 0)
  3036. vulkanRemoved(loc, "non-opaque uniforms outside a block");
  3037. // OpenGL wants locations on these (unless they are getting automapped)
  3038. if (spvVersion.openGl > 0 && !type.getQualifier().hasLocation() && !intermediate.getAutoMapLocations())
  3039. error(loc, "non-opaque uniform variables need a layout(location=L)", identifier.c_str(), "");
  3040. }
  3041. }
  3042. //
  3043. // Qualifier checks knowing the qualifier and that it is a member of a struct/block.
  3044. //
  3045. void TParseContext::memberQualifierCheck(glslang::TPublicType& publicType)
  3046. {
  3047. globalQualifierFixCheck(publicType.loc, publicType.qualifier, true);
  3048. checkNoShaderLayouts(publicType.loc, publicType.shaderQualifiers);
  3049. if (publicType.qualifier.isNonUniform()) {
  3050. error(publicType.loc, "not allowed on block or structure members", "nonuniformEXT", "");
  3051. publicType.qualifier.nonUniform = false;
  3052. }
  3053. }
  3054. //
  3055. // Check/fix just a full qualifier (no variables or types yet, but qualifier is complete) at global level.
  3056. //
  3057. void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& qualifier, bool isMemberCheck)
  3058. {
  3059. bool nonuniformOkay = false;
  3060. // move from parameter/unknown qualifiers to pipeline in/out qualifiers
  3061. switch (qualifier.storage) {
  3062. case EvqIn:
  3063. profileRequires(loc, ENoProfile, 130, nullptr, "in for stage inputs");
  3064. profileRequires(loc, EEsProfile, 300, nullptr, "in for stage inputs");
  3065. qualifier.storage = EvqVaryingIn;
  3066. nonuniformOkay = true;
  3067. break;
  3068. case EvqOut:
  3069. profileRequires(loc, ENoProfile, 130, nullptr, "out for stage outputs");
  3070. profileRequires(loc, EEsProfile, 300, nullptr, "out for stage outputs");
  3071. qualifier.storage = EvqVaryingOut;
  3072. break;
  3073. case EvqInOut:
  3074. qualifier.storage = EvqVaryingIn;
  3075. error(loc, "cannot use 'inout' at global scope", "", "");
  3076. break;
  3077. case EvqGlobal:
  3078. case EvqTemporary:
  3079. nonuniformOkay = true;
  3080. break;
  3081. case EvqUniform:
  3082. // According to GLSL spec: The std430 qualifier is supported only for shader storage blocks; a shader using
  3083. // the std430 qualifier on a uniform block will fail to compile.
  3084. // Only check the global declaration: layout(std430) uniform;
  3085. if (blockName == nullptr &&
  3086. qualifier.layoutPacking == ElpStd430)
  3087. {
  3088. error(loc, "it is invalid to declare std430 qualifier on uniform", "", "");
  3089. }
  3090. break;
  3091. default:
  3092. break;
  3093. }
  3094. if (!nonuniformOkay && qualifier.isNonUniform())
  3095. error(loc, "for non-parameter, can only apply to 'in' or no storage qualifier", "nonuniformEXT", "");
  3096. // Storage qualifier isn't ready for memberQualifierCheck, we should skip invariantCheck for it.
  3097. if (!isMemberCheck || structNestingLevel > 0)
  3098. invariantCheck(loc, qualifier);
  3099. }
  3100. //
  3101. // Check a full qualifier and type (no variable yet) at global level.
  3102. //
  3103. void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQualifier& qualifier, const TPublicType& publicType)
  3104. {
  3105. if (! symbolTable.atGlobalLevel())
  3106. return;
  3107. if (!(publicType.userDef && publicType.userDef->isReference()) && !parsingBuiltins) {
  3108. if (qualifier.isMemoryQualifierImageAndSSBOOnly() && ! publicType.isImage() && publicType.qualifier.storage != EvqBuffer) {
  3109. error(loc, "memory qualifiers cannot be used on this type", "", "");
  3110. } else if (qualifier.isMemory() && (publicType.basicType != EbtSampler) && !publicType.qualifier.isUniformOrBuffer()) {
  3111. error(loc, "memory qualifiers cannot be used on this type", "", "");
  3112. }
  3113. }
  3114. if (qualifier.storage == EvqBuffer &&
  3115. publicType.basicType != EbtBlock &&
  3116. !qualifier.hasBufferReference())
  3117. error(loc, "buffers can be declared only as blocks", "buffer", "");
  3118. if (qualifier.storage != EvqVaryingIn && publicType.basicType == EbtDouble &&
  3119. extensionTurnedOn(E_GL_ARB_vertex_attrib_64bit) && language == EShLangVertex &&
  3120. version < 400) {
  3121. profileRequires(loc, ECoreProfile | ECompatibilityProfile, 410, E_GL_ARB_gpu_shader_fp64, "vertex-shader `double` type");
  3122. }
  3123. if (qualifier.storage != EvqVaryingIn && qualifier.storage != EvqVaryingOut)
  3124. return;
  3125. if (publicType.shaderQualifiers.hasBlendEquation())
  3126. error(loc, "can only be applied to a standalone 'out'", "blend equation", "");
  3127. // now, knowing it is a shader in/out, do all the in/out semantic checks
  3128. if (publicType.basicType == EbtBool && !parsingBuiltins) {
  3129. error(loc, "cannot be bool", GetStorageQualifierString(qualifier.storage), "");
  3130. return;
  3131. }
  3132. if (isTypeInt(publicType.basicType) || publicType.basicType == EbtDouble)
  3133. profileRequires(loc, EEsProfile, 300, nullptr, "shader input/output");
  3134. if (!qualifier.flat && !qualifier.isExplicitInterpolation() && !qualifier.isPervertexNV()) {
  3135. if (isTypeInt(publicType.basicType) ||
  3136. publicType.basicType == EbtDouble ||
  3137. (publicType.userDef && ( publicType.userDef->containsBasicType(EbtInt)
  3138. || publicType.userDef->containsBasicType(EbtUint)
  3139. || publicType.userDef->contains16BitInt()
  3140. || publicType.userDef->contains8BitInt()
  3141. || publicType.userDef->contains64BitInt()
  3142. || publicType.userDef->containsDouble()))) {
  3143. if (qualifier.storage == EvqVaryingIn && language == EShLangFragment)
  3144. error(loc, "must be qualified as flat", TType::getBasicString(publicType.basicType), GetStorageQualifierString(qualifier.storage));
  3145. else if (qualifier.storage == EvqVaryingOut && language == EShLangVertex && version == 300)
  3146. error(loc, "must be qualified as flat", TType::getBasicString(publicType.basicType), GetStorageQualifierString(qualifier.storage));
  3147. }
  3148. }
  3149. if (qualifier.isPatch() && qualifier.isInterpolation())
  3150. error(loc, "cannot use interpolation qualifiers with patch", "patch", "");
  3151. if (qualifier.isTaskMemory() && publicType.basicType != EbtBlock)
  3152. error(loc, "taskNV variables can be declared only as blocks", "taskNV", "");
  3153. if (qualifier.storage == EvqVaryingIn) {
  3154. switch (language) {
  3155. case EShLangVertex:
  3156. if (publicType.basicType == EbtStruct) {
  3157. error(loc, "cannot be a structure or array", GetStorageQualifierString(qualifier.storage), "");
  3158. return;
  3159. }
  3160. if (publicType.arraySizes) {
  3161. requireProfile(loc, ~EEsProfile, "vertex input arrays");
  3162. profileRequires(loc, ENoProfile, 150, nullptr, "vertex input arrays");
  3163. }
  3164. if (publicType.basicType == EbtDouble)
  3165. profileRequires(loc, ~EEsProfile, 410, E_GL_ARB_vertex_attrib_64bit, "vertex-shader `double` type input");
  3166. if (qualifier.isAuxiliary() || qualifier.isInterpolation() || qualifier.isMemory() || qualifier.invariant)
  3167. error(loc, "vertex input cannot be further qualified", "", "");
  3168. break;
  3169. case EShLangFragment:
  3170. if (publicType.userDef) {
  3171. profileRequires(loc, EEsProfile, 300, nullptr, "fragment-shader struct input");
  3172. profileRequires(loc, ~EEsProfile, 150, nullptr, "fragment-shader struct input");
  3173. if (publicType.userDef->containsStructure())
  3174. requireProfile(loc, ~EEsProfile, "fragment-shader struct input containing structure");
  3175. if (publicType.userDef->containsArray())
  3176. requireProfile(loc, ~EEsProfile, "fragment-shader struct input containing an array");
  3177. }
  3178. break;
  3179. case EShLangCompute:
  3180. if (! symbolTable.atBuiltInLevel())
  3181. error(loc, "global storage input qualifier cannot be used in a compute shader", "in", "");
  3182. break;
  3183. #ifndef GLSLANG_WEB
  3184. case EShLangTessControl:
  3185. if (qualifier.patch)
  3186. error(loc, "can only use on output in tessellation-control shader", "patch", "");
  3187. break;
  3188. #endif
  3189. default:
  3190. break;
  3191. }
  3192. } else {
  3193. // qualifier.storage == EvqVaryingOut
  3194. switch (language) {
  3195. case EShLangVertex:
  3196. if (publicType.userDef) {
  3197. profileRequires(loc, EEsProfile, 300, nullptr, "vertex-shader struct output");
  3198. profileRequires(loc, ~EEsProfile, 150, nullptr, "vertex-shader struct output");
  3199. if (publicType.userDef->containsStructure())
  3200. requireProfile(loc, ~EEsProfile, "vertex-shader struct output containing structure");
  3201. if (publicType.userDef->containsArray())
  3202. requireProfile(loc, ~EEsProfile, "vertex-shader struct output containing an array");
  3203. }
  3204. break;
  3205. case EShLangFragment:
  3206. profileRequires(loc, EEsProfile, 300, nullptr, "fragment shader output");
  3207. if (publicType.basicType == EbtStruct) {
  3208. error(loc, "cannot be a structure", GetStorageQualifierString(qualifier.storage), "");
  3209. return;
  3210. }
  3211. if (publicType.matrixRows > 0) {
  3212. error(loc, "cannot be a matrix", GetStorageQualifierString(qualifier.storage), "");
  3213. return;
  3214. }
  3215. if (qualifier.isAuxiliary())
  3216. error(loc, "can't use auxiliary qualifier on a fragment output", "centroid/sample/patch", "");
  3217. if (qualifier.isInterpolation())
  3218. error(loc, "can't use interpolation qualifier on a fragment output", "flat/smooth/noperspective", "");
  3219. if (publicType.basicType == EbtDouble || publicType.basicType == EbtInt64 || publicType.basicType == EbtUint64)
  3220. error(loc, "cannot contain a double, int64, or uint64", GetStorageQualifierString(qualifier.storage), "");
  3221. break;
  3222. case EShLangCompute:
  3223. error(loc, "global storage output qualifier cannot be used in a compute shader", "out", "");
  3224. break;
  3225. #ifndef GLSLANG_WEB
  3226. case EShLangTessEvaluation:
  3227. if (qualifier.patch)
  3228. error(loc, "can only use on input in tessellation-evaluation shader", "patch", "");
  3229. break;
  3230. #endif
  3231. default:
  3232. break;
  3233. }
  3234. }
  3235. }
  3236. //
  3237. // Merge characteristics of the 'src' qualifier into the 'dst'.
  3238. // If there is duplication, issue error messages, unless 'force'
  3239. // is specified, which means to just override default settings.
  3240. //
  3241. // Also, when force is false, it will be assumed that 'src' follows
  3242. // 'dst', for the purpose of error checking order for versions
  3243. // that require specific orderings of qualifiers.
  3244. //
  3245. void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, const TQualifier& src, bool force)
  3246. {
  3247. // Multiple auxiliary qualifiers (mostly done later by 'individual qualifiers')
  3248. if (src.isAuxiliary() && dst.isAuxiliary())
  3249. error(loc, "can only have one auxiliary qualifier (centroid, patch, and sample)", "", "");
  3250. // Multiple interpolation qualifiers (mostly done later by 'individual qualifiers')
  3251. if (src.isInterpolation() && dst.isInterpolation())
  3252. error(loc, "can only have one interpolation qualifier (flat, smooth, noperspective, __explicitInterpAMD)", "", "");
  3253. // Ordering
  3254. if (! force && ((!isEsProfile() && version < 420) ||
  3255. (isEsProfile() && version < 310))
  3256. && ! extensionTurnedOn(E_GL_ARB_shading_language_420pack)) {
  3257. // non-function parameters
  3258. if (src.isNoContraction() && (dst.invariant || dst.isInterpolation() || dst.isAuxiliary() || dst.storage != EvqTemporary || dst.precision != EpqNone))
  3259. error(loc, "precise qualifier must appear first", "", "");
  3260. if (src.invariant && (dst.isInterpolation() || dst.isAuxiliary() || dst.storage != EvqTemporary || dst.precision != EpqNone))
  3261. error(loc, "invariant qualifier must appear before interpolation, storage, and precision qualifiers ", "", "");
  3262. else if (src.isInterpolation() && (dst.isAuxiliary() || dst.storage != EvqTemporary || dst.precision != EpqNone))
  3263. error(loc, "interpolation qualifiers must appear before storage and precision qualifiers", "", "");
  3264. else if (src.isAuxiliary() && (dst.storage != EvqTemporary || dst.precision != EpqNone))
  3265. error(loc, "Auxiliary qualifiers (centroid, patch, and sample) must appear before storage and precision qualifiers", "", "");
  3266. else if (src.storage != EvqTemporary && (dst.precision != EpqNone))
  3267. error(loc, "precision qualifier must appear as last qualifier", "", "");
  3268. // function parameters
  3269. if (src.isNoContraction() && (dst.storage == EvqConst || dst.storage == EvqIn || dst.storage == EvqOut))
  3270. error(loc, "precise qualifier must appear first", "", "");
  3271. if (src.storage == EvqConst && (dst.storage == EvqIn || dst.storage == EvqOut))
  3272. error(loc, "in/out must appear before const", "", "");
  3273. }
  3274. // Storage qualification
  3275. if (dst.storage == EvqTemporary || dst.storage == EvqGlobal)
  3276. dst.storage = src.storage;
  3277. else if ((dst.storage == EvqIn && src.storage == EvqOut) ||
  3278. (dst.storage == EvqOut && src.storage == EvqIn))
  3279. dst.storage = EvqInOut;
  3280. else if ((dst.storage == EvqIn && src.storage == EvqConst) ||
  3281. (dst.storage == EvqConst && src.storage == EvqIn))
  3282. dst.storage = EvqConstReadOnly;
  3283. else if (src.storage != EvqTemporary &&
  3284. src.storage != EvqGlobal)
  3285. error(loc, "too many storage qualifiers", GetStorageQualifierString(src.storage), "");
  3286. // Precision qualifiers
  3287. if (! force && src.precision != EpqNone && dst.precision != EpqNone)
  3288. error(loc, "only one precision qualifier allowed", GetPrecisionQualifierString(src.precision), "");
  3289. if (dst.precision == EpqNone || (force && src.precision != EpqNone))
  3290. dst.precision = src.precision;
  3291. #ifndef GLSLANG_WEB
  3292. if (!force && ((src.coherent && (dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent || dst.shadercallcoherent)) ||
  3293. (src.devicecoherent && (dst.coherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent || dst.shadercallcoherent)) ||
  3294. (src.queuefamilycoherent && (dst.coherent || dst.devicecoherent || dst.workgroupcoherent || dst.subgroupcoherent || dst.shadercallcoherent)) ||
  3295. (src.workgroupcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.subgroupcoherent || dst.shadercallcoherent)) ||
  3296. (src.subgroupcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.shadercallcoherent)) ||
  3297. (src.shadercallcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent)))) {
  3298. error(loc, "only one coherent/devicecoherent/queuefamilycoherent/workgroupcoherent/subgroupcoherent/shadercallcoherent qualifier allowed",
  3299. GetPrecisionQualifierString(src.precision), "");
  3300. }
  3301. #endif
  3302. // Layout qualifiers
  3303. mergeObjectLayoutQualifiers(dst, src, false);
  3304. // individual qualifiers
  3305. bool repeated = false;
  3306. #define MERGE_SINGLETON(field) repeated |= dst.field && src.field; dst.field |= src.field;
  3307. MERGE_SINGLETON(invariant);
  3308. MERGE_SINGLETON(centroid);
  3309. MERGE_SINGLETON(smooth);
  3310. MERGE_SINGLETON(flat);
  3311. MERGE_SINGLETON(specConstant);
  3312. #ifndef GLSLANG_WEB
  3313. MERGE_SINGLETON(noContraction);
  3314. MERGE_SINGLETON(nopersp);
  3315. MERGE_SINGLETON(explicitInterp);
  3316. MERGE_SINGLETON(perPrimitiveNV);
  3317. MERGE_SINGLETON(perViewNV);
  3318. MERGE_SINGLETON(perTaskNV);
  3319. MERGE_SINGLETON(patch);
  3320. MERGE_SINGLETON(sample);
  3321. MERGE_SINGLETON(coherent);
  3322. MERGE_SINGLETON(devicecoherent);
  3323. MERGE_SINGLETON(queuefamilycoherent);
  3324. MERGE_SINGLETON(workgroupcoherent);
  3325. MERGE_SINGLETON(subgroupcoherent);
  3326. MERGE_SINGLETON(shadercallcoherent);
  3327. MERGE_SINGLETON(nonprivate);
  3328. MERGE_SINGLETON(volatil);
  3329. MERGE_SINGLETON(restrict);
  3330. MERGE_SINGLETON(readonly);
  3331. MERGE_SINGLETON(writeonly);
  3332. MERGE_SINGLETON(nonUniform);
  3333. #endif
  3334. if (repeated)
  3335. error(loc, "replicated qualifiers", "", "");
  3336. }
  3337. void TParseContext::setDefaultPrecision(const TSourceLoc& loc, TPublicType& publicType, TPrecisionQualifier qualifier)
  3338. {
  3339. TBasicType basicType = publicType.basicType;
  3340. if (basicType == EbtSampler) {
  3341. defaultSamplerPrecision[computeSamplerTypeIndex(publicType.sampler)] = qualifier;
  3342. return; // all is well
  3343. }
  3344. if (basicType == EbtInt || basicType == EbtFloat) {
  3345. if (publicType.isScalar()) {
  3346. defaultPrecision[basicType] = qualifier;
  3347. if (basicType == EbtInt) {
  3348. defaultPrecision[EbtUint] = qualifier;
  3349. precisionManager.explicitIntDefaultSeen();
  3350. } else
  3351. precisionManager.explicitFloatDefaultSeen();
  3352. return; // all is well
  3353. }
  3354. }
  3355. if (basicType == EbtAtomicUint) {
  3356. if (qualifier != EpqHigh)
  3357. error(loc, "can only apply highp to atomic_uint", "precision", "");
  3358. return;
  3359. }
  3360. error(loc, "cannot apply precision statement to this type; use 'float', 'int' or a sampler type", TType::getBasicString(basicType), "");
  3361. }
  3362. // used to flatten the sampler type space into a single dimension
  3363. // correlates with the declaration of defaultSamplerPrecision[]
  3364. int TParseContext::computeSamplerTypeIndex(TSampler& sampler)
  3365. {
  3366. int arrayIndex = sampler.arrayed ? 1 : 0;
  3367. int shadowIndex = sampler.shadow ? 1 : 0;
  3368. int externalIndex = sampler.isExternal() ? 1 : 0;
  3369. int imageIndex = sampler.isImageClass() ? 1 : 0;
  3370. int msIndex = sampler.isMultiSample() ? 1 : 0;
  3371. int flattened = EsdNumDims * (EbtNumTypes * (2 * (2 * (2 * (2 * arrayIndex + msIndex) + imageIndex) + shadowIndex) +
  3372. externalIndex) + sampler.type) + sampler.dim;
  3373. assert(flattened < maxSamplerIndex);
  3374. return flattened;
  3375. }
  3376. TPrecisionQualifier TParseContext::getDefaultPrecision(TPublicType& publicType)
  3377. {
  3378. if (publicType.basicType == EbtSampler)
  3379. return defaultSamplerPrecision[computeSamplerTypeIndex(publicType.sampler)];
  3380. else
  3381. return defaultPrecision[publicType.basicType];
  3382. }
  3383. void TParseContext::precisionQualifierCheck(const TSourceLoc& loc, TBasicType baseType, TQualifier& qualifier)
  3384. {
  3385. // Built-in symbols are allowed some ambiguous precisions, to be pinned down
  3386. // later by context.
  3387. if (! obeyPrecisionQualifiers() || parsingBuiltins)
  3388. return;
  3389. #ifndef GLSLANG_WEB
  3390. if (baseType == EbtAtomicUint && qualifier.precision != EpqNone && qualifier.precision != EpqHigh)
  3391. error(loc, "atomic counters can only be highp", "atomic_uint", "");
  3392. #endif
  3393. if (baseType == EbtFloat || baseType == EbtUint || baseType == EbtInt || baseType == EbtSampler || baseType == EbtAtomicUint) {
  3394. if (qualifier.precision == EpqNone) {
  3395. if (relaxedErrors())
  3396. warn(loc, "type requires declaration of default precision qualifier", TType::getBasicString(baseType), "substituting 'mediump'");
  3397. else
  3398. error(loc, "type requires declaration of default precision qualifier", TType::getBasicString(baseType), "");
  3399. qualifier.precision = EpqMedium;
  3400. defaultPrecision[baseType] = EpqMedium;
  3401. }
  3402. } else if (qualifier.precision != EpqNone)
  3403. error(loc, "type cannot have precision qualifier", TType::getBasicString(baseType), "");
  3404. }
  3405. void TParseContext::parameterTypeCheck(const TSourceLoc& loc, TStorageQualifier qualifier, const TType& type)
  3406. {
  3407. if ((qualifier == EvqOut || qualifier == EvqInOut) && type.isOpaque())
  3408. error(loc, "samplers and atomic_uints cannot be output parameters", type.getBasicTypeString().c_str(), "");
  3409. if (!parsingBuiltins && type.contains16BitFloat())
  3410. requireFloat16Arithmetic(loc, type.getBasicTypeString().c_str(), "float16 types can only be in uniform block or buffer storage");
  3411. if (!parsingBuiltins && type.contains16BitInt())
  3412. requireInt16Arithmetic(loc, type.getBasicTypeString().c_str(), "(u)int16 types can only be in uniform block or buffer storage");
  3413. if (!parsingBuiltins && type.contains8BitInt())
  3414. requireInt8Arithmetic(loc, type.getBasicTypeString().c_str(), "(u)int8 types can only be in uniform block or buffer storage");
  3415. }
  3416. bool TParseContext::containsFieldWithBasicType(const TType& type, TBasicType basicType)
  3417. {
  3418. if (type.getBasicType() == basicType)
  3419. return true;
  3420. if (type.getBasicType() == EbtStruct) {
  3421. const TTypeList& structure = *type.getStruct();
  3422. for (unsigned int i = 0; i < structure.size(); ++i) {
  3423. if (containsFieldWithBasicType(*structure[i].type, basicType))
  3424. return true;
  3425. }
  3426. }
  3427. return false;
  3428. }
  3429. //
  3430. // Do size checking for an array type's size.
  3431. //
  3432. void TParseContext::arraySizeCheck(const TSourceLoc& loc, TIntermTyped* expr, TArraySize& sizePair, const char *sizeType)
  3433. {
  3434. bool isConst = false;
  3435. sizePair.node = nullptr;
  3436. int size = 1;
  3437. TIntermConstantUnion* constant = expr->getAsConstantUnion();
  3438. if (constant) {
  3439. // handle true (non-specialization) constant
  3440. size = constant->getConstArray()[0].getIConst();
  3441. isConst = true;
  3442. } else {
  3443. // see if it's a specialization constant instead
  3444. if (expr->getQualifier().isSpecConstant()) {
  3445. isConst = true;
  3446. sizePair.node = expr;
  3447. TIntermSymbol* symbol = expr->getAsSymbolNode();
  3448. if (symbol && symbol->getConstArray().size() > 0)
  3449. size = symbol->getConstArray()[0].getIConst();
  3450. } else if (expr->getAsUnaryNode() &&
  3451. expr->getAsUnaryNode()->getOp() == glslang::EOpArrayLength &&
  3452. expr->getAsUnaryNode()->getOperand()->getType().isCoopMat()) {
  3453. isConst = true;
  3454. size = 1;
  3455. sizePair.node = expr->getAsUnaryNode();
  3456. }
  3457. }
  3458. sizePair.size = size;
  3459. if (! isConst || (expr->getBasicType() != EbtInt && expr->getBasicType() != EbtUint)) {
  3460. error(loc, sizeType, "", "must be a constant integer expression");
  3461. return;
  3462. }
  3463. if (size <= 0) {
  3464. error(loc, sizeType, "", "must be a positive integer");
  3465. return;
  3466. }
  3467. }
  3468. //
  3469. // See if this qualifier can be an array.
  3470. //
  3471. // Returns true if there is an error.
  3472. //
  3473. bool TParseContext::arrayQualifierError(const TSourceLoc& loc, const TQualifier& qualifier)
  3474. {
  3475. if (qualifier.storage == EvqConst) {
  3476. profileRequires(loc, ENoProfile, 120, E_GL_3DL_array_objects, "const array");
  3477. profileRequires(loc, EEsProfile, 300, nullptr, "const array");
  3478. }
  3479. if (qualifier.storage == EvqVaryingIn && language == EShLangVertex) {
  3480. requireProfile(loc, ~EEsProfile, "vertex input arrays");
  3481. profileRequires(loc, ENoProfile, 150, nullptr, "vertex input arrays");
  3482. }
  3483. return false;
  3484. }
  3485. //
  3486. // See if this qualifier and type combination can be an array.
  3487. // Assumes arrayQualifierError() was also called to catch the type-invariant tests.
  3488. //
  3489. // Returns true if there is an error.
  3490. //
  3491. bool TParseContext::arrayError(const TSourceLoc& loc, const TType& type)
  3492. {
  3493. if (type.getQualifier().storage == EvqVaryingOut && language == EShLangVertex) {
  3494. if (type.isArrayOfArrays())
  3495. requireProfile(loc, ~EEsProfile, "vertex-shader array-of-array output");
  3496. else if (type.isStruct())
  3497. requireProfile(loc, ~EEsProfile, "vertex-shader array-of-struct output");
  3498. }
  3499. if (type.getQualifier().storage == EvqVaryingIn && language == EShLangFragment) {
  3500. if (type.isArrayOfArrays())
  3501. requireProfile(loc, ~EEsProfile, "fragment-shader array-of-array input");
  3502. else if (type.isStruct())
  3503. requireProfile(loc, ~EEsProfile, "fragment-shader array-of-struct input");
  3504. }
  3505. if (type.getQualifier().storage == EvqVaryingOut && language == EShLangFragment) {
  3506. if (type.isArrayOfArrays())
  3507. requireProfile(loc, ~EEsProfile, "fragment-shader array-of-array output");
  3508. }
  3509. return false;
  3510. }
  3511. //
  3512. // Require array to be completely sized
  3513. //
  3514. void TParseContext::arraySizeRequiredCheck(const TSourceLoc& loc, const TArraySizes& arraySizes)
  3515. {
  3516. if (!parsingBuiltins && arraySizes.hasUnsized())
  3517. error(loc, "array size required", "", "");
  3518. }
  3519. void TParseContext::structArrayCheck(const TSourceLoc& /*loc*/, const TType& type)
  3520. {
  3521. const TTypeList& structure = *type.getStruct();
  3522. for (int m = 0; m < (int)structure.size(); ++m) {
  3523. const TType& member = *structure[m].type;
  3524. if (member.isArray())
  3525. arraySizeRequiredCheck(structure[m].loc, *member.getArraySizes());
  3526. }
  3527. }
  3528. void TParseContext::arraySizesCheck(const TSourceLoc& loc, const TQualifier& qualifier, TArraySizes* arraySizes,
  3529. const TIntermTyped* initializer, bool lastMember)
  3530. {
  3531. assert(arraySizes);
  3532. // always allow special built-in ins/outs sized to topologies
  3533. if (parsingBuiltins)
  3534. return;
  3535. // initializer must be a sized array, in which case
  3536. // allow the initializer to set any unknown array sizes
  3537. if (initializer != nullptr) {
  3538. if (initializer->getType().isUnsizedArray())
  3539. error(loc, "array initializer must be sized", "[]", "");
  3540. return;
  3541. }
  3542. // No environment allows any non-outer-dimension to be implicitly sized
  3543. if (arraySizes->isInnerUnsized()) {
  3544. error(loc, "only outermost dimension of an array of arrays can be implicitly sized", "[]", "");
  3545. arraySizes->clearInnerUnsized();
  3546. }
  3547. if (arraySizes->isInnerSpecialization() &&
  3548. (qualifier.storage != EvqTemporary && qualifier.storage != EvqGlobal && qualifier.storage != EvqShared && qualifier.storage != EvqConst))
  3549. error(loc, "only outermost dimension of an array of arrays can be a specialization constant", "[]", "");
  3550. #ifndef GLSLANG_WEB
  3551. // desktop always allows outer-dimension-unsized variable arrays,
  3552. if (!isEsProfile())
  3553. return;
  3554. // for ES, if size isn't coming from an initializer, it has to be explicitly declared now,
  3555. // with very few exceptions
  3556. // implicitly-sized io exceptions:
  3557. switch (language) {
  3558. case EShLangGeometry:
  3559. if (qualifier.storage == EvqVaryingIn)
  3560. if ((isEsProfile() && version >= 320) ||
  3561. extensionsTurnedOn(Num_AEP_geometry_shader, AEP_geometry_shader))
  3562. return;
  3563. break;
  3564. case EShLangTessControl:
  3565. if ( qualifier.storage == EvqVaryingIn ||
  3566. (qualifier.storage == EvqVaryingOut && ! qualifier.isPatch()))
  3567. if ((isEsProfile() && version >= 320) ||
  3568. extensionsTurnedOn(Num_AEP_tessellation_shader, AEP_tessellation_shader))
  3569. return;
  3570. break;
  3571. case EShLangTessEvaluation:
  3572. if ((qualifier.storage == EvqVaryingIn && ! qualifier.isPatch()) ||
  3573. qualifier.storage == EvqVaryingOut)
  3574. if ((isEsProfile() && version >= 320) ||
  3575. extensionsTurnedOn(Num_AEP_tessellation_shader, AEP_tessellation_shader))
  3576. return;
  3577. break;
  3578. case EShLangMeshNV:
  3579. if (qualifier.storage == EvqVaryingOut)
  3580. if ((isEsProfile() && version >= 320) ||
  3581. extensionTurnedOn(E_GL_NV_mesh_shader))
  3582. return;
  3583. break;
  3584. default:
  3585. break;
  3586. }
  3587. #endif
  3588. // last member of ssbo block exception:
  3589. if (qualifier.storage == EvqBuffer && lastMember)
  3590. return;
  3591. arraySizeRequiredCheck(loc, *arraySizes);
  3592. }
  3593. void TParseContext::arrayOfArrayVersionCheck(const TSourceLoc& loc, const TArraySizes* sizes)
  3594. {
  3595. if (sizes == nullptr || sizes->getNumDims() == 1)
  3596. return;
  3597. const char* feature = "arrays of arrays";
  3598. requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, feature);
  3599. profileRequires(loc, EEsProfile, 310, nullptr, feature);
  3600. profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, nullptr, feature);
  3601. }
  3602. //
  3603. // Do all the semantic checking for declaring or redeclaring an array, with and
  3604. // without a size, and make the right changes to the symbol table.
  3605. //
  3606. void TParseContext::declareArray(const TSourceLoc& loc, const TString& identifier, const TType& type, TSymbol*& symbol)
  3607. {
  3608. if (symbol == nullptr) {
  3609. bool currentScope;
  3610. symbol = symbolTable.find(identifier, nullptr, &currentScope);
  3611. if (symbol && builtInName(identifier) && ! symbolTable.atBuiltInLevel()) {
  3612. // bad shader (errors already reported) trying to redeclare a built-in name as an array
  3613. symbol = nullptr;
  3614. return;
  3615. }
  3616. if (symbol == nullptr || ! currentScope) {
  3617. //
  3618. // Successfully process a new definition.
  3619. // (Redeclarations have to take place at the same scope; otherwise they are hiding declarations)
  3620. //
  3621. symbol = new TVariable(&identifier, type);
  3622. symbolTable.insert(*symbol);
  3623. if (symbolTable.atGlobalLevel())
  3624. trackLinkage(*symbol);
  3625. #ifndef GLSLANG_WEB
  3626. if (! symbolTable.atBuiltInLevel()) {
  3627. if (isIoResizeArray(type)) {
  3628. ioArraySymbolResizeList.push_back(symbol);
  3629. checkIoArraysConsistency(loc, true);
  3630. } else
  3631. fixIoArraySize(loc, symbol->getWritableType());
  3632. }
  3633. #endif
  3634. return;
  3635. }
  3636. if (symbol->getAsAnonMember()) {
  3637. error(loc, "cannot redeclare a user-block member array", identifier.c_str(), "");
  3638. symbol = nullptr;
  3639. return;
  3640. }
  3641. }
  3642. //
  3643. // Process a redeclaration.
  3644. //
  3645. if (symbol == nullptr) {
  3646. error(loc, "array variable name expected", identifier.c_str(), "");
  3647. return;
  3648. }
  3649. // redeclareBuiltinVariable() should have already done the copyUp()
  3650. TType& existingType = symbol->getWritableType();
  3651. if (! existingType.isArray()) {
  3652. error(loc, "redeclaring non-array as array", identifier.c_str(), "");
  3653. return;
  3654. }
  3655. if (! existingType.sameElementType(type)) {
  3656. error(loc, "redeclaration of array with a different element type", identifier.c_str(), "");
  3657. return;
  3658. }
  3659. if (! existingType.sameInnerArrayness(type)) {
  3660. error(loc, "redeclaration of array with a different array dimensions or sizes", identifier.c_str(), "");
  3661. return;
  3662. }
  3663. #ifndef GLSLANG_WEB
  3664. if (existingType.isSizedArray()) {
  3665. // be more leniant for input arrays to geometry shaders and tessellation control outputs, where the redeclaration is the same size
  3666. if (! (isIoResizeArray(type) && existingType.getOuterArraySize() == type.getOuterArraySize()))
  3667. error(loc, "redeclaration of array with size", identifier.c_str(), "");
  3668. return;
  3669. }
  3670. arrayLimitCheck(loc, identifier, type.getOuterArraySize());
  3671. existingType.updateArraySizes(type);
  3672. if (isIoResizeArray(type))
  3673. checkIoArraysConsistency(loc);
  3674. #endif
  3675. }
  3676. #ifndef GLSLANG_WEB
  3677. // Policy and error check for needing a runtime sized array.
  3678. void TParseContext::checkRuntimeSizable(const TSourceLoc& loc, const TIntermTyped& base)
  3679. {
  3680. // runtime length implies runtime sizeable, so no problem
  3681. if (isRuntimeLength(base))
  3682. return;
  3683. if (base.getType().getQualifier().builtIn == EbvSampleMask)
  3684. return;
  3685. // Check for last member of a bufferreference type, which is runtime sizeable
  3686. // but doesn't support runtime length
  3687. if (base.getType().getQualifier().storage == EvqBuffer) {
  3688. const TIntermBinary* binary = base.getAsBinaryNode();
  3689. if (binary != nullptr &&
  3690. binary->getOp() == EOpIndexDirectStruct &&
  3691. binary->getLeft()->isReference()) {
  3692. const int index = binary->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
  3693. const int memberCount = (int)binary->getLeft()->getType().getReferentType()->getStruct()->size();
  3694. if (index == memberCount - 1)
  3695. return;
  3696. }
  3697. }
  3698. // check for additional things allowed by GL_EXT_nonuniform_qualifier
  3699. if (base.getBasicType() == EbtSampler || base.getBasicType() == EbtAccStruct || base.getBasicType() == EbtRayQuery ||
  3700. (base.getBasicType() == EbtBlock && base.getType().getQualifier().isUniformOrBuffer()))
  3701. requireExtensions(loc, 1, &E_GL_EXT_nonuniform_qualifier, "variable index");
  3702. else
  3703. error(loc, "", "[", "array must be redeclared with a size before being indexed with a variable");
  3704. }
  3705. // Policy decision for whether a run-time .length() is allowed.
  3706. bool TParseContext::isRuntimeLength(const TIntermTyped& base) const
  3707. {
  3708. if (base.getType().getQualifier().storage == EvqBuffer) {
  3709. // in a buffer block
  3710. const TIntermBinary* binary = base.getAsBinaryNode();
  3711. if (binary != nullptr && binary->getOp() == EOpIndexDirectStruct) {
  3712. // is it the last member?
  3713. const int index = binary->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
  3714. if (binary->getLeft()->isReference())
  3715. return false;
  3716. const int memberCount = (int)binary->getLeft()->getType().getStruct()->size();
  3717. if (index == memberCount - 1)
  3718. return true;
  3719. }
  3720. }
  3721. return false;
  3722. }
  3723. // Check if mesh perviewNV attributes have a view dimension
  3724. // and resize it to gl_MaxMeshViewCountNV when implicitly sized.
  3725. void TParseContext::checkAndResizeMeshViewDim(const TSourceLoc& loc, TType& type, bool isBlockMember)
  3726. {
  3727. // see if member is a per-view attribute
  3728. if (!type.getQualifier().isPerView())
  3729. return;
  3730. if ((isBlockMember && type.isArray()) || (!isBlockMember && type.isArrayOfArrays())) {
  3731. // since we don't have the maxMeshViewCountNV set during parsing builtins, we hardcode the value.
  3732. int maxViewCount = parsingBuiltins ? 4 : resources.maxMeshViewCountNV;
  3733. // For block members, outermost array dimension is the view dimension.
  3734. // For non-block members, outermost array dimension is the vertex/primitive dimension
  3735. // and 2nd outermost is the view dimension.
  3736. int viewDim = isBlockMember ? 0 : 1;
  3737. int viewDimSize = type.getArraySizes()->getDimSize(viewDim);
  3738. if (viewDimSize != UnsizedArraySize && viewDimSize != maxViewCount)
  3739. error(loc, "mesh view output array size must be gl_MaxMeshViewCountNV or implicitly sized", "[]", "");
  3740. else if (viewDimSize == UnsizedArraySize)
  3741. type.getArraySizes()->setDimSize(viewDim, maxViewCount);
  3742. }
  3743. else {
  3744. error(loc, "requires a view array dimension", "perviewNV", "");
  3745. }
  3746. }
  3747. #endif // GLSLANG_WEB
  3748. // Returns true if the first argument to the #line directive is the line number for the next line.
  3749. //
  3750. // Desktop, pre-version 3.30: "After processing this directive
  3751. // (including its new-line), the implementation will behave as if it is compiling at line number line+1 and
  3752. // source string number source-string-number."
  3753. //
  3754. // Desktop, version 3.30 and later, and ES: "After processing this directive
  3755. // (including its new-line), the implementation will behave as if it is compiling at line number line and
  3756. // source string number source-string-number.
  3757. bool TParseContext::lineDirectiveShouldSetNextLine() const
  3758. {
  3759. return isEsProfile() || version >= 330;
  3760. }
  3761. //
  3762. // Enforce non-initializer type/qualifier rules.
  3763. //
  3764. void TParseContext::nonInitConstCheck(const TSourceLoc& loc, TString& identifier, TType& type)
  3765. {
  3766. //
  3767. // Make the qualifier make sense, given that there is not an initializer.
  3768. //
  3769. if (type.getQualifier().storage == EvqConst ||
  3770. type.getQualifier().storage == EvqConstReadOnly) {
  3771. type.getQualifier().makeTemporary();
  3772. error(loc, "variables with qualifier 'const' must be initialized", identifier.c_str(), "");
  3773. }
  3774. }
  3775. //
  3776. // See if the identifier is a built-in symbol that can be redeclared, and if so,
  3777. // copy the symbol table's read-only built-in variable to the current
  3778. // global level, where it can be modified based on the passed in type.
  3779. //
  3780. // Returns nullptr if no redeclaration took place; meaning a normal declaration still
  3781. // needs to occur for it, not necessarily an error.
  3782. //
  3783. // Returns a redeclared and type-modified variable if a redeclarated occurred.
  3784. //
  3785. TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TString& identifier,
  3786. const TQualifier& qualifier, const TShaderQualifiers& publicType)
  3787. {
  3788. #ifndef GLSLANG_WEB
  3789. if (! builtInName(identifier) || symbolTable.atBuiltInLevel() || ! symbolTable.atGlobalLevel())
  3790. return nullptr;
  3791. bool nonEsRedecls = (!isEsProfile() && (version >= 130 || identifier == "gl_TexCoord"));
  3792. bool esRedecls = (isEsProfile() &&
  3793. (version >= 320 || extensionsTurnedOn(Num_AEP_shader_io_blocks, AEP_shader_io_blocks)));
  3794. if (! esRedecls && ! nonEsRedecls)
  3795. return nullptr;
  3796. // Special case when using GL_ARB_separate_shader_objects
  3797. bool ssoPre150 = false; // means the only reason this variable is redeclared is due to this combination
  3798. if (!isEsProfile() && version <= 140 && extensionTurnedOn(E_GL_ARB_separate_shader_objects)) {
  3799. if (identifier == "gl_Position" ||
  3800. identifier == "gl_PointSize" ||
  3801. identifier == "gl_ClipVertex" ||
  3802. identifier == "gl_FogFragCoord")
  3803. ssoPre150 = true;
  3804. }
  3805. // Potentially redeclaring a built-in variable...
  3806. if (ssoPre150 ||
  3807. (identifier == "gl_FragDepth" && ((nonEsRedecls && version >= 420) || esRedecls)) ||
  3808. (identifier == "gl_FragCoord" && ((nonEsRedecls && version >= 150) || esRedecls)) ||
  3809. identifier == "gl_ClipDistance" ||
  3810. identifier == "gl_CullDistance" ||
  3811. identifier == "gl_ShadingRateEXT" ||
  3812. identifier == "gl_PrimitiveShadingRateEXT" ||
  3813. identifier == "gl_FrontColor" ||
  3814. identifier == "gl_BackColor" ||
  3815. identifier == "gl_FrontSecondaryColor" ||
  3816. identifier == "gl_BackSecondaryColor" ||
  3817. identifier == "gl_SecondaryColor" ||
  3818. (identifier == "gl_Color" && language == EShLangFragment) ||
  3819. (identifier == "gl_FragStencilRefARB" && (nonEsRedecls && version >= 140)
  3820. && language == EShLangFragment) ||
  3821. identifier == "gl_SampleMask" ||
  3822. identifier == "gl_Layer" ||
  3823. identifier == "gl_PrimitiveIndicesNV" ||
  3824. identifier == "gl_TexCoord") {
  3825. // Find the existing symbol, if any.
  3826. bool builtIn;
  3827. TSymbol* symbol = symbolTable.find(identifier, &builtIn);
  3828. // If the symbol was not found, this must be a version/profile/stage
  3829. // that doesn't have it.
  3830. if (! symbol)
  3831. return nullptr;
  3832. // If it wasn't at a built-in level, then it's already been redeclared;
  3833. // that is, this is a redeclaration of a redeclaration; reuse that initial
  3834. // redeclaration. Otherwise, make the new one.
  3835. if (builtIn)
  3836. makeEditable(symbol);
  3837. // Now, modify the type of the copy, as per the type of the current redeclaration.
  3838. TQualifier& symbolQualifier = symbol->getWritableType().getQualifier();
  3839. if (ssoPre150) {
  3840. if (intermediate.inIoAccessed(identifier))
  3841. error(loc, "cannot redeclare after use", identifier.c_str(), "");
  3842. if (qualifier.hasLayout())
  3843. error(loc, "cannot apply layout qualifier to", "redeclaration", symbol->getName().c_str());
  3844. if (qualifier.isMemory() || qualifier.isAuxiliary() || (language == EShLangVertex && qualifier.storage != EvqVaryingOut) ||
  3845. (language == EShLangFragment && qualifier.storage != EvqVaryingIn))
  3846. error(loc, "cannot change storage, memory, or auxiliary qualification of", "redeclaration", symbol->getName().c_str());
  3847. if (! qualifier.smooth)
  3848. error(loc, "cannot change interpolation qualification of", "redeclaration", symbol->getName().c_str());
  3849. } else if (identifier == "gl_FrontColor" ||
  3850. identifier == "gl_BackColor" ||
  3851. identifier == "gl_FrontSecondaryColor" ||
  3852. identifier == "gl_BackSecondaryColor" ||
  3853. identifier == "gl_SecondaryColor" ||
  3854. identifier == "gl_Color") {
  3855. symbolQualifier.flat = qualifier.flat;
  3856. symbolQualifier.smooth = qualifier.smooth;
  3857. symbolQualifier.nopersp = qualifier.nopersp;
  3858. if (qualifier.hasLayout())
  3859. error(loc, "cannot apply layout qualifier to", "redeclaration", symbol->getName().c_str());
  3860. if (qualifier.isMemory() || qualifier.isAuxiliary() || symbol->getType().getQualifier().storage != qualifier.storage)
  3861. error(loc, "cannot change storage, memory, or auxiliary qualification of", "redeclaration", symbol->getName().c_str());
  3862. } else if (identifier == "gl_TexCoord" ||
  3863. identifier == "gl_ClipDistance" ||
  3864. identifier == "gl_CullDistance") {
  3865. if (qualifier.hasLayout() || qualifier.isMemory() || qualifier.isAuxiliary() ||
  3866. qualifier.nopersp != symbolQualifier.nopersp || qualifier.flat != symbolQualifier.flat ||
  3867. symbolQualifier.storage != qualifier.storage)
  3868. error(loc, "cannot change qualification of", "redeclaration", symbol->getName().c_str());
  3869. } else if (identifier == "gl_FragCoord") {
  3870. if (intermediate.inIoAccessed("gl_FragCoord"))
  3871. error(loc, "cannot redeclare after use", "gl_FragCoord", "");
  3872. if (qualifier.nopersp != symbolQualifier.nopersp || qualifier.flat != symbolQualifier.flat ||
  3873. qualifier.isMemory() || qualifier.isAuxiliary())
  3874. error(loc, "can only change layout qualification of", "redeclaration", symbol->getName().c_str());
  3875. if (qualifier.storage != EvqVaryingIn)
  3876. error(loc, "cannot change input storage qualification of", "redeclaration", symbol->getName().c_str());
  3877. if (! builtIn && (publicType.pixelCenterInteger != intermediate.getPixelCenterInteger() ||
  3878. publicType.originUpperLeft != intermediate.getOriginUpperLeft()))
  3879. error(loc, "cannot redeclare with different qualification:", "redeclaration", symbol->getName().c_str());
  3880. if (publicType.pixelCenterInteger)
  3881. intermediate.setPixelCenterInteger();
  3882. if (publicType.originUpperLeft)
  3883. intermediate.setOriginUpperLeft();
  3884. } else if (identifier == "gl_FragDepth") {
  3885. if (qualifier.nopersp != symbolQualifier.nopersp || qualifier.flat != symbolQualifier.flat ||
  3886. qualifier.isMemory() || qualifier.isAuxiliary())
  3887. error(loc, "can only change layout qualification of", "redeclaration", symbol->getName().c_str());
  3888. if (qualifier.storage != EvqVaryingOut)
  3889. error(loc, "cannot change output storage qualification of", "redeclaration", symbol->getName().c_str());
  3890. if (publicType.layoutDepth != EldNone) {
  3891. if (intermediate.inIoAccessed("gl_FragDepth"))
  3892. error(loc, "cannot redeclare after use", "gl_FragDepth", "");
  3893. if (! intermediate.setDepth(publicType.layoutDepth))
  3894. error(loc, "all redeclarations must use the same depth layout on", "redeclaration", symbol->getName().c_str());
  3895. }
  3896. }
  3897. else if (
  3898. identifier == "gl_PrimitiveIndicesNV" ||
  3899. identifier == "gl_FragStencilRefARB") {
  3900. if (qualifier.hasLayout())
  3901. error(loc, "cannot apply layout qualifier to", "redeclaration", symbol->getName().c_str());
  3902. if (qualifier.storage != EvqVaryingOut)
  3903. error(loc, "cannot change output storage qualification of", "redeclaration", symbol->getName().c_str());
  3904. }
  3905. else if (identifier == "gl_SampleMask") {
  3906. if (!publicType.layoutOverrideCoverage) {
  3907. error(loc, "redeclaration only allowed for override_coverage layout", "redeclaration", symbol->getName().c_str());
  3908. }
  3909. intermediate.setLayoutOverrideCoverage();
  3910. }
  3911. else if (identifier == "gl_Layer") {
  3912. if (!qualifier.layoutViewportRelative && qualifier.layoutSecondaryViewportRelativeOffset == -2048)
  3913. error(loc, "redeclaration only allowed for viewport_relative or secondary_view_offset layout", "redeclaration", symbol->getName().c_str());
  3914. symbolQualifier.layoutViewportRelative = qualifier.layoutViewportRelative;
  3915. symbolQualifier.layoutSecondaryViewportRelativeOffset = qualifier.layoutSecondaryViewportRelativeOffset;
  3916. }
  3917. // TODO: semantics quality: separate smooth from nothing declared, then use IsInterpolation for several tests above
  3918. return symbol;
  3919. }
  3920. #endif
  3921. return nullptr;
  3922. }
  3923. //
  3924. // Either redeclare the requested block, or give an error message why it can't be done.
  3925. //
  3926. // TODO: functionality: explicitly sizing members of redeclared blocks is not giving them an explicit size
  3927. void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newTypeList, const TString& blockName,
  3928. const TString* instanceName, TArraySizes* arraySizes)
  3929. {
  3930. #ifndef GLSLANG_WEB
  3931. const char* feature = "built-in block redeclaration";
  3932. profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, feature);
  3933. profileRequires(loc, ~EEsProfile, 410, E_GL_ARB_separate_shader_objects, feature);
  3934. if (blockName != "gl_PerVertex" && blockName != "gl_PerFragment" &&
  3935. blockName != "gl_MeshPerVertexNV" && blockName != "gl_MeshPerPrimitiveNV") {
  3936. error(loc, "cannot redeclare block: ", "block declaration", blockName.c_str());
  3937. return;
  3938. }
  3939. // Redeclaring a built-in block...
  3940. if (instanceName && ! builtInName(*instanceName)) {
  3941. error(loc, "cannot redeclare a built-in block with a user name", instanceName->c_str(), "");
  3942. return;
  3943. }
  3944. // Blocks with instance names are easy to find, lookup the instance name,
  3945. // Anonymous blocks need to be found via a member.
  3946. bool builtIn;
  3947. TSymbol* block;
  3948. if (instanceName)
  3949. block = symbolTable.find(*instanceName, &builtIn);
  3950. else
  3951. block = symbolTable.find(newTypeList.front().type->getFieldName(), &builtIn);
  3952. // If the block was not found, this must be a version/profile/stage
  3953. // that doesn't have it, or the instance name is wrong.
  3954. const char* errorName = instanceName ? instanceName->c_str() : newTypeList.front().type->getFieldName().c_str();
  3955. if (! block) {
  3956. error(loc, "no declaration found for redeclaration", errorName, "");
  3957. return;
  3958. }
  3959. // Built-in blocks cannot be redeclared more than once, which if happened,
  3960. // we'd be finding the already redeclared one here, rather than the built in.
  3961. if (! builtIn) {
  3962. error(loc, "can only redeclare a built-in block once, and before any use", blockName.c_str(), "");
  3963. return;
  3964. }
  3965. // Copy the block to make a writable version, to insert into the block table after editing.
  3966. block = symbolTable.copyUpDeferredInsert(block);
  3967. if (block->getType().getBasicType() != EbtBlock) {
  3968. error(loc, "cannot redeclare a non block as a block", errorName, "");
  3969. return;
  3970. }
  3971. // Fix XFB stuff up, it applies to the order of the redeclaration, not
  3972. // the order of the original members.
  3973. if (currentBlockQualifier.storage == EvqVaryingOut && globalOutputDefaults.hasXfbBuffer()) {
  3974. if (!currentBlockQualifier.hasXfbBuffer())
  3975. currentBlockQualifier.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer;
  3976. if (!currentBlockQualifier.hasStream())
  3977. currentBlockQualifier.layoutStream = globalOutputDefaults.layoutStream;
  3978. fixXfbOffsets(currentBlockQualifier, newTypeList);
  3979. }
  3980. // Edit and error check the container against the redeclaration
  3981. // - remove unused members
  3982. // - ensure remaining qualifiers/types match
  3983. TType& type = block->getWritableType();
  3984. // if gl_PerVertex is redeclared for the purpose of passing through "gl_Position"
  3985. // for passthrough purpose, the redeclared block should have the same qualifers as
  3986. // the current one
  3987. if (currentBlockQualifier.layoutPassthrough) {
  3988. type.getQualifier().layoutPassthrough = currentBlockQualifier.layoutPassthrough;
  3989. type.getQualifier().storage = currentBlockQualifier.storage;
  3990. type.getQualifier().layoutStream = currentBlockQualifier.layoutStream;
  3991. type.getQualifier().layoutXfbBuffer = currentBlockQualifier.layoutXfbBuffer;
  3992. }
  3993. TTypeList::iterator member = type.getWritableStruct()->begin();
  3994. size_t numOriginalMembersFound = 0;
  3995. while (member != type.getStruct()->end()) {
  3996. // look for match
  3997. bool found = false;
  3998. TTypeList::const_iterator newMember;
  3999. TSourceLoc memberLoc;
  4000. memberLoc.init();
  4001. for (newMember = newTypeList.begin(); newMember != newTypeList.end(); ++newMember) {
  4002. if (member->type->getFieldName() == newMember->type->getFieldName()) {
  4003. found = true;
  4004. memberLoc = newMember->loc;
  4005. break;
  4006. }
  4007. }
  4008. if (found) {
  4009. ++numOriginalMembersFound;
  4010. // - ensure match between redeclared members' types
  4011. // - check for things that can't be changed
  4012. // - update things that can be changed
  4013. TType& oldType = *member->type;
  4014. const TType& newType = *newMember->type;
  4015. if (! newType.sameElementType(oldType))
  4016. error(memberLoc, "cannot redeclare block member with a different type", member->type->getFieldName().c_str(), "");
  4017. if (oldType.isArray() != newType.isArray())
  4018. error(memberLoc, "cannot change arrayness of redeclared block member", member->type->getFieldName().c_str(), "");
  4019. else if (! oldType.getQualifier().isPerView() && ! oldType.sameArrayness(newType) && oldType.isSizedArray())
  4020. error(memberLoc, "cannot change array size of redeclared block member", member->type->getFieldName().c_str(), "");
  4021. else if (! oldType.getQualifier().isPerView() && newType.isArray())
  4022. arrayLimitCheck(loc, member->type->getFieldName(), newType.getOuterArraySize());
  4023. if (oldType.getQualifier().isPerView() && ! newType.getQualifier().isPerView())
  4024. error(memberLoc, "missing perviewNV qualifier to redeclared block member", member->type->getFieldName().c_str(), "");
  4025. else if (! oldType.getQualifier().isPerView() && newType.getQualifier().isPerView())
  4026. error(memberLoc, "cannot add perviewNV qualifier to redeclared block member", member->type->getFieldName().c_str(), "");
  4027. else if (newType.getQualifier().isPerView()) {
  4028. if (oldType.getArraySizes()->getNumDims() != newType.getArraySizes()->getNumDims())
  4029. error(memberLoc, "cannot change arrayness of redeclared block member", member->type->getFieldName().c_str(), "");
  4030. else if (! newType.isUnsizedArray() && newType.getOuterArraySize() != resources.maxMeshViewCountNV)
  4031. error(loc, "mesh view output array size must be gl_MaxMeshViewCountNV or implicitly sized", "[]", "");
  4032. else if (newType.getArraySizes()->getNumDims() == 2) {
  4033. int innerDimSize = newType.getArraySizes()->getDimSize(1);
  4034. arrayLimitCheck(memberLoc, member->type->getFieldName(), innerDimSize);
  4035. oldType.getArraySizes()->setDimSize(1, innerDimSize);
  4036. }
  4037. }
  4038. if (oldType.getQualifier().isPerPrimitive() && ! newType.getQualifier().isPerPrimitive())
  4039. error(memberLoc, "missing perprimitiveNV qualifier to redeclared block member", member->type->getFieldName().c_str(), "");
  4040. else if (! oldType.getQualifier().isPerPrimitive() && newType.getQualifier().isPerPrimitive())
  4041. error(memberLoc, "cannot add perprimitiveNV qualifier to redeclared block member", member->type->getFieldName().c_str(), "");
  4042. if (newType.getQualifier().isMemory())
  4043. error(memberLoc, "cannot add memory qualifier to redeclared block member", member->type->getFieldName().c_str(), "");
  4044. if (newType.getQualifier().hasNonXfbLayout())
  4045. error(memberLoc, "cannot add non-XFB layout to redeclared block member", member->type->getFieldName().c_str(), "");
  4046. if (newType.getQualifier().patch)
  4047. error(memberLoc, "cannot add patch to redeclared block member", member->type->getFieldName().c_str(), "");
  4048. if (newType.getQualifier().hasXfbBuffer() &&
  4049. newType.getQualifier().layoutXfbBuffer != currentBlockQualifier.layoutXfbBuffer)
  4050. error(memberLoc, "member cannot contradict block (or what block inherited from global)", "xfb_buffer", "");
  4051. if (newType.getQualifier().hasStream() &&
  4052. newType.getQualifier().layoutStream != currentBlockQualifier.layoutStream)
  4053. error(memberLoc, "member cannot contradict block (or what block inherited from global)", "xfb_stream", "");
  4054. oldType.getQualifier().centroid = newType.getQualifier().centroid;
  4055. oldType.getQualifier().sample = newType.getQualifier().sample;
  4056. oldType.getQualifier().invariant = newType.getQualifier().invariant;
  4057. oldType.getQualifier().noContraction = newType.getQualifier().noContraction;
  4058. oldType.getQualifier().smooth = newType.getQualifier().smooth;
  4059. oldType.getQualifier().flat = newType.getQualifier().flat;
  4060. oldType.getQualifier().nopersp = newType.getQualifier().nopersp;
  4061. oldType.getQualifier().layoutXfbOffset = newType.getQualifier().layoutXfbOffset;
  4062. oldType.getQualifier().layoutXfbBuffer = newType.getQualifier().layoutXfbBuffer;
  4063. oldType.getQualifier().layoutXfbStride = newType.getQualifier().layoutXfbStride;
  4064. if (oldType.getQualifier().layoutXfbOffset != TQualifier::layoutXfbBufferEnd) {
  4065. // If any member has an xfb_offset, then the block's xfb_buffer inherents current xfb_buffer,
  4066. // and for xfb processing, the member needs it as well, along with xfb_stride.
  4067. type.getQualifier().layoutXfbBuffer = currentBlockQualifier.layoutXfbBuffer;
  4068. oldType.getQualifier().layoutXfbBuffer = currentBlockQualifier.layoutXfbBuffer;
  4069. }
  4070. if (oldType.isUnsizedArray() && newType.isSizedArray())
  4071. oldType.changeOuterArraySize(newType.getOuterArraySize());
  4072. // check and process the member's type, which will include managing xfb information
  4073. layoutTypeCheck(loc, oldType);
  4074. // go to next member
  4075. ++member;
  4076. } else {
  4077. // For missing members of anonymous blocks that have been redeclared,
  4078. // hide the original (shared) declaration.
  4079. // Instance-named blocks can just have the member removed.
  4080. if (instanceName)
  4081. member = type.getWritableStruct()->erase(member);
  4082. else {
  4083. member->type->hideMember();
  4084. ++member;
  4085. }
  4086. }
  4087. }
  4088. if (spvVersion.vulkan > 0) {
  4089. // ...then streams apply to built-in blocks, instead of them being only on stream 0
  4090. type.getQualifier().layoutStream = currentBlockQualifier.layoutStream;
  4091. }
  4092. if (numOriginalMembersFound < newTypeList.size())
  4093. error(loc, "block redeclaration has extra members", blockName.c_str(), "");
  4094. if (type.isArray() != (arraySizes != nullptr) ||
  4095. (type.isArray() && arraySizes != nullptr && type.getArraySizes()->getNumDims() != arraySizes->getNumDims()))
  4096. error(loc, "cannot change arrayness of redeclared block", blockName.c_str(), "");
  4097. else if (type.isArray()) {
  4098. // At this point, we know both are arrays and both have the same number of dimensions.
  4099. // It is okay for a built-in block redeclaration to be unsized, and keep the size of the
  4100. // original block declaration.
  4101. if (!arraySizes->isSized() && type.isSizedArray())
  4102. arraySizes->changeOuterSize(type.getOuterArraySize());
  4103. // And, okay to be giving a size to the array, by the redeclaration
  4104. if (!type.isSizedArray() && arraySizes->isSized())
  4105. type.changeOuterArraySize(arraySizes->getOuterSize());
  4106. // Now, they must match in all dimensions.
  4107. if (type.isSizedArray() && *type.getArraySizes() != *arraySizes)
  4108. error(loc, "cannot change array size of redeclared block", blockName.c_str(), "");
  4109. }
  4110. symbolTable.insert(*block);
  4111. // Check for general layout qualifier errors
  4112. layoutObjectCheck(loc, *block);
  4113. // Tracking for implicit sizing of array
  4114. if (isIoResizeArray(block->getType())) {
  4115. ioArraySymbolResizeList.push_back(block);
  4116. checkIoArraysConsistency(loc, true);
  4117. } else if (block->getType().isArray())
  4118. fixIoArraySize(loc, block->getWritableType());
  4119. // Save it in the AST for linker use.
  4120. trackLinkage(*block);
  4121. #endif // GLSLANG_WEB
  4122. }
  4123. void TParseContext::paramCheckFixStorage(const TSourceLoc& loc, const TStorageQualifier& qualifier, TType& type)
  4124. {
  4125. switch (qualifier) {
  4126. case EvqConst:
  4127. case EvqConstReadOnly:
  4128. type.getQualifier().storage = EvqConstReadOnly;
  4129. break;
  4130. case EvqIn:
  4131. case EvqOut:
  4132. case EvqInOut:
  4133. type.getQualifier().storage = qualifier;
  4134. break;
  4135. case EvqGlobal:
  4136. case EvqTemporary:
  4137. type.getQualifier().storage = EvqIn;
  4138. break;
  4139. default:
  4140. type.getQualifier().storage = EvqIn;
  4141. error(loc, "storage qualifier not allowed on function parameter", GetStorageQualifierString(qualifier), "");
  4142. break;
  4143. }
  4144. }
  4145. void TParseContext::paramCheckFix(const TSourceLoc& loc, const TQualifier& qualifier, TType& type)
  4146. {
  4147. #ifndef GLSLANG_WEB
  4148. if (qualifier.isMemory()) {
  4149. type.getQualifier().volatil = qualifier.volatil;
  4150. type.getQualifier().coherent = qualifier.coherent;
  4151. type.getQualifier().devicecoherent = qualifier.devicecoherent ;
  4152. type.getQualifier().queuefamilycoherent = qualifier.queuefamilycoherent;
  4153. type.getQualifier().workgroupcoherent = qualifier.workgroupcoherent;
  4154. type.getQualifier().subgroupcoherent = qualifier.subgroupcoherent;
  4155. type.getQualifier().shadercallcoherent = qualifier.shadercallcoherent;
  4156. type.getQualifier().nonprivate = qualifier.nonprivate;
  4157. type.getQualifier().readonly = qualifier.readonly;
  4158. type.getQualifier().writeonly = qualifier.writeonly;
  4159. type.getQualifier().restrict = qualifier.restrict;
  4160. }
  4161. #endif
  4162. if (qualifier.isAuxiliary() ||
  4163. qualifier.isInterpolation())
  4164. error(loc, "cannot use auxiliary or interpolation qualifiers on a function parameter", "", "");
  4165. if (qualifier.hasLayout())
  4166. error(loc, "cannot use layout qualifiers on a function parameter", "", "");
  4167. if (qualifier.invariant)
  4168. error(loc, "cannot use invariant qualifier on a function parameter", "", "");
  4169. if (qualifier.isNoContraction()) {
  4170. if (qualifier.isParamOutput())
  4171. type.getQualifier().setNoContraction();
  4172. else
  4173. warn(loc, "qualifier has no effect on non-output parameters", "precise", "");
  4174. }
  4175. if (qualifier.isNonUniform())
  4176. type.getQualifier().nonUniform = qualifier.nonUniform;
  4177. paramCheckFixStorage(loc, qualifier.storage, type);
  4178. }
  4179. void TParseContext::nestedBlockCheck(const TSourceLoc& loc)
  4180. {
  4181. if (structNestingLevel > 0 || blockNestingLevel > 0)
  4182. error(loc, "cannot nest a block definition inside a structure or block", "", "");
  4183. ++blockNestingLevel;
  4184. }
  4185. void TParseContext::nestedStructCheck(const TSourceLoc& loc)
  4186. {
  4187. if (structNestingLevel > 0 || blockNestingLevel > 0)
  4188. error(loc, "cannot nest a structure definition inside a structure or block", "", "");
  4189. ++structNestingLevel;
  4190. }
  4191. void TParseContext::arrayObjectCheck(const TSourceLoc& loc, const TType& type, const char* op)
  4192. {
  4193. // Some versions don't allow comparing arrays or structures containing arrays
  4194. if (type.containsArray()) {
  4195. profileRequires(loc, ENoProfile, 120, E_GL_3DL_array_objects, op);
  4196. profileRequires(loc, EEsProfile, 300, nullptr, op);
  4197. }
  4198. }
  4199. void TParseContext::opaqueCheck(const TSourceLoc& loc, const TType& type, const char* op)
  4200. {
  4201. if (containsFieldWithBasicType(type, EbtSampler))
  4202. error(loc, "can't use with samplers or structs containing samplers", op, "");
  4203. }
  4204. void TParseContext::referenceCheck(const TSourceLoc& loc, const TType& type, const char* op)
  4205. {
  4206. #ifndef GLSLANG_WEB
  4207. if (containsFieldWithBasicType(type, EbtReference))
  4208. error(loc, "can't use with reference types", op, "");
  4209. #endif
  4210. }
  4211. void TParseContext::storage16BitAssignmentCheck(const TSourceLoc& loc, const TType& type, const char* op)
  4212. {
  4213. #ifndef GLSLANG_WEB
  4214. if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtFloat16))
  4215. requireFloat16Arithmetic(loc, op, "can't use with structs containing float16");
  4216. if (type.isArray() && type.getBasicType() == EbtFloat16)
  4217. requireFloat16Arithmetic(loc, op, "can't use with arrays containing float16");
  4218. if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtInt16))
  4219. requireInt16Arithmetic(loc, op, "can't use with structs containing int16");
  4220. if (type.isArray() && type.getBasicType() == EbtInt16)
  4221. requireInt16Arithmetic(loc, op, "can't use with arrays containing int16");
  4222. if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtUint16))
  4223. requireInt16Arithmetic(loc, op, "can't use with structs containing uint16");
  4224. if (type.isArray() && type.getBasicType() == EbtUint16)
  4225. requireInt16Arithmetic(loc, op, "can't use with arrays containing uint16");
  4226. if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtInt8))
  4227. requireInt8Arithmetic(loc, op, "can't use with structs containing int8");
  4228. if (type.isArray() && type.getBasicType() == EbtInt8)
  4229. requireInt8Arithmetic(loc, op, "can't use with arrays containing int8");
  4230. if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtUint8))
  4231. requireInt8Arithmetic(loc, op, "can't use with structs containing uint8");
  4232. if (type.isArray() && type.getBasicType() == EbtUint8)
  4233. requireInt8Arithmetic(loc, op, "can't use with arrays containing uint8");
  4234. #endif
  4235. }
  4236. void TParseContext::specializationCheck(const TSourceLoc& loc, const TType& type, const char* op)
  4237. {
  4238. if (type.containsSpecializationSize())
  4239. error(loc, "can't use with types containing arrays sized with a specialization constant", op, "");
  4240. }
  4241. void TParseContext::structTypeCheck(const TSourceLoc& /*loc*/, TPublicType& publicType)
  4242. {
  4243. const TTypeList& typeList = *publicType.userDef->getStruct();
  4244. // fix and check for member storage qualifiers and types that don't belong within a structure
  4245. for (unsigned int member = 0; member < typeList.size(); ++member) {
  4246. TQualifier& memberQualifier = typeList[member].type->getQualifier();
  4247. const TSourceLoc& memberLoc = typeList[member].loc;
  4248. if (memberQualifier.isAuxiliary() ||
  4249. memberQualifier.isInterpolation() ||
  4250. (memberQualifier.storage != EvqTemporary && memberQualifier.storage != EvqGlobal))
  4251. error(memberLoc, "cannot use storage or interpolation qualifiers on structure members", typeList[member].type->getFieldName().c_str(), "");
  4252. if (memberQualifier.isMemory())
  4253. error(memberLoc, "cannot use memory qualifiers on structure members", typeList[member].type->getFieldName().c_str(), "");
  4254. if (memberQualifier.hasLayout()) {
  4255. error(memberLoc, "cannot use layout qualifiers on structure members", typeList[member].type->getFieldName().c_str(), "");
  4256. memberQualifier.clearLayout();
  4257. }
  4258. if (memberQualifier.invariant)
  4259. error(memberLoc, "cannot use invariant qualifier on structure members", typeList[member].type->getFieldName().c_str(), "");
  4260. }
  4261. }
  4262. //
  4263. // See if this loop satisfies the limitations for ES 2.0 (version 100) for loops in Appendex A:
  4264. //
  4265. // "The loop index has type int or float.
  4266. //
  4267. // "The for statement has the form:
  4268. // for ( init-declaration ; condition ; expression )
  4269. // init-declaration has the form: type-specifier identifier = constant-expression
  4270. // condition has the form: loop-index relational_operator constant-expression
  4271. // where relational_operator is one of: > >= < <= == or !=
  4272. // expression [sic] has one of the following forms:
  4273. // loop-index++
  4274. // loop-index--
  4275. // loop-index += constant-expression
  4276. // loop-index -= constant-expression
  4277. //
  4278. // The body is handled in an AST traversal.
  4279. //
  4280. void TParseContext::inductiveLoopCheck(const TSourceLoc& loc, TIntermNode* init, TIntermLoop* loop)
  4281. {
  4282. #ifndef GLSLANG_WEB
  4283. // loop index init must exist and be a declaration, which shows up in the AST as an aggregate of size 1 of the declaration
  4284. bool badInit = false;
  4285. if (! init || ! init->getAsAggregate() || init->getAsAggregate()->getSequence().size() != 1)
  4286. badInit = true;
  4287. TIntermBinary* binaryInit = 0;
  4288. if (! badInit) {
  4289. // get the declaration assignment
  4290. binaryInit = init->getAsAggregate()->getSequence()[0]->getAsBinaryNode();
  4291. if (! binaryInit)
  4292. badInit = true;
  4293. }
  4294. if (badInit) {
  4295. error(loc, "inductive-loop init-declaration requires the form \"type-specifier loop-index = constant-expression\"", "limitations", "");
  4296. return;
  4297. }
  4298. // loop index must be type int or float
  4299. if (! binaryInit->getType().isScalar() || (binaryInit->getBasicType() != EbtInt && binaryInit->getBasicType() != EbtFloat)) {
  4300. error(loc, "inductive loop requires a scalar 'int' or 'float' loop index", "limitations", "");
  4301. return;
  4302. }
  4303. // init is the form "loop-index = constant"
  4304. if (binaryInit->getOp() != EOpAssign || ! binaryInit->getLeft()->getAsSymbolNode() || ! binaryInit->getRight()->getAsConstantUnion()) {
  4305. error(loc, "inductive-loop init-declaration requires the form \"type-specifier loop-index = constant-expression\"", "limitations", "");
  4306. return;
  4307. }
  4308. // get the unique id of the loop index
  4309. int loopIndex = binaryInit->getLeft()->getAsSymbolNode()->getId();
  4310. inductiveLoopIds.insert(loopIndex);
  4311. // condition's form must be "loop-index relational-operator constant-expression"
  4312. bool badCond = ! loop->getTest();
  4313. if (! badCond) {
  4314. TIntermBinary* binaryCond = loop->getTest()->getAsBinaryNode();
  4315. badCond = ! binaryCond;
  4316. if (! badCond) {
  4317. switch (binaryCond->getOp()) {
  4318. case EOpGreaterThan:
  4319. case EOpGreaterThanEqual:
  4320. case EOpLessThan:
  4321. case EOpLessThanEqual:
  4322. case EOpEqual:
  4323. case EOpNotEqual:
  4324. break;
  4325. default:
  4326. badCond = true;
  4327. }
  4328. }
  4329. if (binaryCond && (! binaryCond->getLeft()->getAsSymbolNode() ||
  4330. binaryCond->getLeft()->getAsSymbolNode()->getId() != loopIndex ||
  4331. ! binaryCond->getRight()->getAsConstantUnion()))
  4332. badCond = true;
  4333. }
  4334. if (badCond) {
  4335. error(loc, "inductive-loop condition requires the form \"loop-index <comparison-op> constant-expression\"", "limitations", "");
  4336. return;
  4337. }
  4338. // loop-index++
  4339. // loop-index--
  4340. // loop-index += constant-expression
  4341. // loop-index -= constant-expression
  4342. bool badTerminal = ! loop->getTerminal();
  4343. if (! badTerminal) {
  4344. TIntermUnary* unaryTerminal = loop->getTerminal()->getAsUnaryNode();
  4345. TIntermBinary* binaryTerminal = loop->getTerminal()->getAsBinaryNode();
  4346. if (unaryTerminal || binaryTerminal) {
  4347. switch(loop->getTerminal()->getAsOperator()->getOp()) {
  4348. case EOpPostDecrement:
  4349. case EOpPostIncrement:
  4350. case EOpAddAssign:
  4351. case EOpSubAssign:
  4352. break;
  4353. default:
  4354. badTerminal = true;
  4355. }
  4356. } else
  4357. badTerminal = true;
  4358. if (binaryTerminal && (! binaryTerminal->getLeft()->getAsSymbolNode() ||
  4359. binaryTerminal->getLeft()->getAsSymbolNode()->getId() != loopIndex ||
  4360. ! binaryTerminal->getRight()->getAsConstantUnion()))
  4361. badTerminal = true;
  4362. if (unaryTerminal && (! unaryTerminal->getOperand()->getAsSymbolNode() ||
  4363. unaryTerminal->getOperand()->getAsSymbolNode()->getId() != loopIndex))
  4364. badTerminal = true;
  4365. }
  4366. if (badTerminal) {
  4367. error(loc, "inductive-loop termination requires the form \"loop-index++, loop-index--, loop-index += constant-expression, or loop-index -= constant-expression\"", "limitations", "");
  4368. return;
  4369. }
  4370. // the body
  4371. inductiveLoopBodyCheck(loop->getBody(), loopIndex, symbolTable);
  4372. #endif
  4373. }
  4374. #ifndef GLSLANG_WEB
  4375. // Do limit checks for built-in arrays.
  4376. void TParseContext::arrayLimitCheck(const TSourceLoc& loc, const TString& identifier, int size)
  4377. {
  4378. if (identifier.compare("gl_TexCoord") == 0)
  4379. limitCheck(loc, size, "gl_MaxTextureCoords", "gl_TexCoord array size");
  4380. else if (identifier.compare("gl_ClipDistance") == 0)
  4381. limitCheck(loc, size, "gl_MaxClipDistances", "gl_ClipDistance array size");
  4382. else if (identifier.compare("gl_CullDistance") == 0)
  4383. limitCheck(loc, size, "gl_MaxCullDistances", "gl_CullDistance array size");
  4384. else if (identifier.compare("gl_ClipDistancePerViewNV") == 0)
  4385. limitCheck(loc, size, "gl_MaxClipDistances", "gl_ClipDistancePerViewNV array size");
  4386. else if (identifier.compare("gl_CullDistancePerViewNV") == 0)
  4387. limitCheck(loc, size, "gl_MaxCullDistances", "gl_CullDistancePerViewNV array size");
  4388. }
  4389. #endif // GLSLANG_WEB
  4390. // See if the provided value is less than or equal to the symbol indicated by limit,
  4391. // which should be a constant in the symbol table.
  4392. void TParseContext::limitCheck(const TSourceLoc& loc, int value, const char* limit, const char* feature)
  4393. {
  4394. TSymbol* symbol = symbolTable.find(limit);
  4395. assert(symbol->getAsVariable());
  4396. const TConstUnionArray& constArray = symbol->getAsVariable()->getConstArray();
  4397. assert(! constArray.empty());
  4398. if (value > constArray[0].getIConst())
  4399. error(loc, "must be less than or equal to", feature, "%s (%d)", limit, constArray[0].getIConst());
  4400. }
  4401. #ifndef GLSLANG_WEB
  4402. //
  4403. // Do any additional error checking, etc., once we know the parsing is done.
  4404. //
  4405. void TParseContext::finish()
  4406. {
  4407. TParseContextBase::finish();
  4408. if (parsingBuiltins)
  4409. return;
  4410. // Check on array indexes for ES 2.0 (version 100) limitations.
  4411. for (size_t i = 0; i < needsIndexLimitationChecking.size(); ++i)
  4412. constantIndexExpressionCheck(needsIndexLimitationChecking[i]);
  4413. // Check for stages that are enabled by extension.
  4414. // Can't do this at the beginning, it is chicken and egg to add a stage by
  4415. // extension.
  4416. // Stage-specific features were correctly tested for already, this is just
  4417. // about the stage itself.
  4418. switch (language) {
  4419. case EShLangGeometry:
  4420. if (isEsProfile() && version == 310)
  4421. requireExtensions(getCurrentLoc(), Num_AEP_geometry_shader, AEP_geometry_shader, "geometry shaders");
  4422. break;
  4423. case EShLangTessControl:
  4424. case EShLangTessEvaluation:
  4425. if (isEsProfile() && version == 310)
  4426. requireExtensions(getCurrentLoc(), Num_AEP_tessellation_shader, AEP_tessellation_shader, "tessellation shaders");
  4427. else if (!isEsProfile() && version < 400)
  4428. requireExtensions(getCurrentLoc(), 1, &E_GL_ARB_tessellation_shader, "tessellation shaders");
  4429. break;
  4430. case EShLangCompute:
  4431. if (!isEsProfile() && version < 430)
  4432. requireExtensions(getCurrentLoc(), 1, &E_GL_ARB_compute_shader, "compute shaders");
  4433. break;
  4434. case EShLangTaskNV:
  4435. requireExtensions(getCurrentLoc(), 1, &E_GL_NV_mesh_shader, "task shaders");
  4436. break;
  4437. case EShLangMeshNV:
  4438. requireExtensions(getCurrentLoc(), 1, &E_GL_NV_mesh_shader, "mesh shaders");
  4439. break;
  4440. default:
  4441. break;
  4442. }
  4443. // Set default outputs for GL_NV_geometry_shader_passthrough
  4444. if (language == EShLangGeometry && extensionTurnedOn(E_SPV_NV_geometry_shader_passthrough)) {
  4445. if (intermediate.getOutputPrimitive() == ElgNone) {
  4446. switch (intermediate.getInputPrimitive()) {
  4447. case ElgPoints: intermediate.setOutputPrimitive(ElgPoints); break;
  4448. case ElgLines: intermediate.setOutputPrimitive(ElgLineStrip); break;
  4449. case ElgTriangles: intermediate.setOutputPrimitive(ElgTriangleStrip); break;
  4450. default: break;
  4451. }
  4452. }
  4453. if (intermediate.getVertices() == TQualifier::layoutNotSet) {
  4454. switch (intermediate.getInputPrimitive()) {
  4455. case ElgPoints: intermediate.setVertices(1); break;
  4456. case ElgLines: intermediate.setVertices(2); break;
  4457. case ElgTriangles: intermediate.setVertices(3); break;
  4458. default: break;
  4459. }
  4460. }
  4461. }
  4462. }
  4463. #endif // GLSLANG_WEB
  4464. //
  4465. // Layout qualifier stuff.
  4466. //
  4467. // Put the id's layout qualification into the public type, for qualifiers not having a number set.
  4468. // This is before we know any type information for error checking.
  4469. void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publicType, TString& id)
  4470. {
  4471. std::transform(id.begin(), id.end(), id.begin(), ::tolower);
  4472. if (id == TQualifier::getLayoutMatrixString(ElmColumnMajor)) {
  4473. publicType.qualifier.layoutMatrix = ElmColumnMajor;
  4474. return;
  4475. }
  4476. if (id == TQualifier::getLayoutMatrixString(ElmRowMajor)) {
  4477. publicType.qualifier.layoutMatrix = ElmRowMajor;
  4478. return;
  4479. }
  4480. if (id == TQualifier::getLayoutPackingString(ElpPacked)) {
  4481. if (spvVersion.spv != 0)
  4482. spvRemoved(loc, "packed");
  4483. publicType.qualifier.layoutPacking = ElpPacked;
  4484. return;
  4485. }
  4486. if (id == TQualifier::getLayoutPackingString(ElpShared)) {
  4487. if (spvVersion.spv != 0)
  4488. spvRemoved(loc, "shared");
  4489. publicType.qualifier.layoutPacking = ElpShared;
  4490. return;
  4491. }
  4492. if (id == TQualifier::getLayoutPackingString(ElpStd140)) {
  4493. publicType.qualifier.layoutPacking = ElpStd140;
  4494. return;
  4495. }
  4496. #ifndef GLSLANG_WEB
  4497. if (id == TQualifier::getLayoutPackingString(ElpStd430)) {
  4498. requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "std430");
  4499. profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_shader_storage_buffer_object, "std430");
  4500. profileRequires(loc, EEsProfile, 310, nullptr, "std430");
  4501. publicType.qualifier.layoutPacking = ElpStd430;
  4502. return;
  4503. }
  4504. if (id == TQualifier::getLayoutPackingString(ElpScalar)) {
  4505. requireVulkan(loc, "scalar");
  4506. requireExtensions(loc, 1, &E_GL_EXT_scalar_block_layout, "scalar block layout");
  4507. publicType.qualifier.layoutPacking = ElpScalar;
  4508. return;
  4509. }
  4510. // TODO: compile-time performance: may need to stop doing linear searches
  4511. for (TLayoutFormat format = (TLayoutFormat)(ElfNone + 1); format < ElfCount; format = (TLayoutFormat)(format + 1)) {
  4512. if (id == TQualifier::getLayoutFormatString(format)) {
  4513. if ((format > ElfEsFloatGuard && format < ElfFloatGuard) ||
  4514. (format > ElfEsIntGuard && format < ElfIntGuard) ||
  4515. (format > ElfEsUintGuard && format < ElfCount))
  4516. requireProfile(loc, ENoProfile | ECoreProfile | ECompatibilityProfile, "image load-store format");
  4517. profileRequires(loc, ENoProfile | ECoreProfile | ECompatibilityProfile, 420, E_GL_ARB_shader_image_load_store, "image load store");
  4518. profileRequires(loc, EEsProfile, 310, E_GL_ARB_shader_image_load_store, "image load store");
  4519. publicType.qualifier.layoutFormat = format;
  4520. return;
  4521. }
  4522. }
  4523. if (id == "push_constant") {
  4524. requireVulkan(loc, "push_constant");
  4525. publicType.qualifier.layoutPushConstant = true;
  4526. return;
  4527. }
  4528. if (id == "buffer_reference") {
  4529. requireVulkan(loc, "buffer_reference");
  4530. requireExtensions(loc, 1, &E_GL_EXT_buffer_reference, "buffer_reference");
  4531. publicType.qualifier.layoutBufferReference = true;
  4532. intermediate.setUseStorageBuffer();
  4533. intermediate.setUsePhysicalStorageBuffer();
  4534. return;
  4535. }
  4536. if (language == EShLangGeometry || language == EShLangTessEvaluation || language == EShLangMeshNV) {
  4537. if (id == TQualifier::getGeometryString(ElgTriangles)) {
  4538. publicType.shaderQualifiers.geometry = ElgTriangles;
  4539. return;
  4540. }
  4541. if (language == EShLangGeometry || language == EShLangMeshNV) {
  4542. if (id == TQualifier::getGeometryString(ElgPoints)) {
  4543. publicType.shaderQualifiers.geometry = ElgPoints;
  4544. return;
  4545. }
  4546. if (id == TQualifier::getGeometryString(ElgLines)) {
  4547. publicType.shaderQualifiers.geometry = ElgLines;
  4548. return;
  4549. }
  4550. if (language == EShLangGeometry) {
  4551. if (id == TQualifier::getGeometryString(ElgLineStrip)) {
  4552. publicType.shaderQualifiers.geometry = ElgLineStrip;
  4553. return;
  4554. }
  4555. if (id == TQualifier::getGeometryString(ElgLinesAdjacency)) {
  4556. publicType.shaderQualifiers.geometry = ElgLinesAdjacency;
  4557. return;
  4558. }
  4559. if (id == TQualifier::getGeometryString(ElgTrianglesAdjacency)) {
  4560. publicType.shaderQualifiers.geometry = ElgTrianglesAdjacency;
  4561. return;
  4562. }
  4563. if (id == TQualifier::getGeometryString(ElgTriangleStrip)) {
  4564. publicType.shaderQualifiers.geometry = ElgTriangleStrip;
  4565. return;
  4566. }
  4567. if (id == "passthrough") {
  4568. requireExtensions(loc, 1, &E_SPV_NV_geometry_shader_passthrough, "geometry shader passthrough");
  4569. publicType.qualifier.layoutPassthrough = true;
  4570. intermediate.setGeoPassthroughEXT();
  4571. return;
  4572. }
  4573. }
  4574. } else {
  4575. assert(language == EShLangTessEvaluation);
  4576. // input primitive
  4577. if (id == TQualifier::getGeometryString(ElgTriangles)) {
  4578. publicType.shaderQualifiers.geometry = ElgTriangles;
  4579. return;
  4580. }
  4581. if (id == TQualifier::getGeometryString(ElgQuads)) {
  4582. publicType.shaderQualifiers.geometry = ElgQuads;
  4583. return;
  4584. }
  4585. if (id == TQualifier::getGeometryString(ElgIsolines)) {
  4586. publicType.shaderQualifiers.geometry = ElgIsolines;
  4587. return;
  4588. }
  4589. // vertex spacing
  4590. if (id == TQualifier::getVertexSpacingString(EvsEqual)) {
  4591. publicType.shaderQualifiers.spacing = EvsEqual;
  4592. return;
  4593. }
  4594. if (id == TQualifier::getVertexSpacingString(EvsFractionalEven)) {
  4595. publicType.shaderQualifiers.spacing = EvsFractionalEven;
  4596. return;
  4597. }
  4598. if (id == TQualifier::getVertexSpacingString(EvsFractionalOdd)) {
  4599. publicType.shaderQualifiers.spacing = EvsFractionalOdd;
  4600. return;
  4601. }
  4602. // triangle order
  4603. if (id == TQualifier::getVertexOrderString(EvoCw)) {
  4604. publicType.shaderQualifiers.order = EvoCw;
  4605. return;
  4606. }
  4607. if (id == TQualifier::getVertexOrderString(EvoCcw)) {
  4608. publicType.shaderQualifiers.order = EvoCcw;
  4609. return;
  4610. }
  4611. // point mode
  4612. if (id == "point_mode") {
  4613. publicType.shaderQualifiers.pointMode = true;
  4614. return;
  4615. }
  4616. }
  4617. }
  4618. if (language == EShLangFragment) {
  4619. if (id == "origin_upper_left") {
  4620. requireProfile(loc, ECoreProfile | ECompatibilityProfile, "origin_upper_left");
  4621. publicType.shaderQualifiers.originUpperLeft = true;
  4622. return;
  4623. }
  4624. if (id == "pixel_center_integer") {
  4625. requireProfile(loc, ECoreProfile | ECompatibilityProfile, "pixel_center_integer");
  4626. publicType.shaderQualifiers.pixelCenterInteger = true;
  4627. return;
  4628. }
  4629. if (id == "early_fragment_tests") {
  4630. profileRequires(loc, ENoProfile | ECoreProfile | ECompatibilityProfile, 420, E_GL_ARB_shader_image_load_store, "early_fragment_tests");
  4631. profileRequires(loc, EEsProfile, 310, nullptr, "early_fragment_tests");
  4632. publicType.shaderQualifiers.earlyFragmentTests = true;
  4633. return;
  4634. }
  4635. if (id == "post_depth_coverage") {
  4636. requireExtensions(loc, Num_post_depth_coverageEXTs, post_depth_coverageEXTs, "post depth coverage");
  4637. if (extensionTurnedOn(E_GL_ARB_post_depth_coverage)) {
  4638. publicType.shaderQualifiers.earlyFragmentTests = true;
  4639. }
  4640. publicType.shaderQualifiers.postDepthCoverage = true;
  4641. return;
  4642. }
  4643. for (TLayoutDepth depth = (TLayoutDepth)(EldNone + 1); depth < EldCount; depth = (TLayoutDepth)(depth+1)) {
  4644. if (id == TQualifier::getLayoutDepthString(depth)) {
  4645. requireProfile(loc, ECoreProfile | ECompatibilityProfile, "depth layout qualifier");
  4646. profileRequires(loc, ECoreProfile | ECompatibilityProfile, 420, nullptr, "depth layout qualifier");
  4647. publicType.shaderQualifiers.layoutDepth = depth;
  4648. return;
  4649. }
  4650. }
  4651. for (TInterlockOrdering order = (TInterlockOrdering)(EioNone + 1); order < EioCount; order = (TInterlockOrdering)(order+1)) {
  4652. if (id == TQualifier::getInterlockOrderingString(order)) {
  4653. requireProfile(loc, ECoreProfile | ECompatibilityProfile, "fragment shader interlock layout qualifier");
  4654. profileRequires(loc, ECoreProfile | ECompatibilityProfile, 450, nullptr, "fragment shader interlock layout qualifier");
  4655. requireExtensions(loc, 1, &E_GL_ARB_fragment_shader_interlock, TQualifier::getInterlockOrderingString(order));
  4656. if (order == EioShadingRateInterlockOrdered || order == EioShadingRateInterlockUnordered)
  4657. requireExtensions(loc, 1, &E_GL_NV_shading_rate_image, TQualifier::getInterlockOrderingString(order));
  4658. publicType.shaderQualifiers.interlockOrdering = order;
  4659. return;
  4660. }
  4661. }
  4662. if (id.compare(0, 13, "blend_support") == 0) {
  4663. bool found = false;
  4664. for (TBlendEquationShift be = (TBlendEquationShift)0; be < EBlendCount; be = (TBlendEquationShift)(be + 1)) {
  4665. if (id == TQualifier::getBlendEquationString(be)) {
  4666. profileRequires(loc, EEsProfile, 320, E_GL_KHR_blend_equation_advanced, "blend equation");
  4667. profileRequires(loc, ~EEsProfile, 0, E_GL_KHR_blend_equation_advanced, "blend equation");
  4668. intermediate.addBlendEquation(be);
  4669. publicType.shaderQualifiers.blendEquation = true;
  4670. found = true;
  4671. break;
  4672. }
  4673. }
  4674. if (! found)
  4675. error(loc, "unknown blend equation", "blend_support", "");
  4676. return;
  4677. }
  4678. if (id == "override_coverage") {
  4679. requireExtensions(loc, 1, &E_GL_NV_sample_mask_override_coverage, "sample mask override coverage");
  4680. publicType.shaderQualifiers.layoutOverrideCoverage = true;
  4681. return;
  4682. }
  4683. }
  4684. if (language == EShLangVertex ||
  4685. language == EShLangTessControl ||
  4686. language == EShLangTessEvaluation ||
  4687. language == EShLangGeometry ) {
  4688. if (id == "viewport_relative") {
  4689. requireExtensions(loc, 1, &E_GL_NV_viewport_array2, "view port array2");
  4690. publicType.qualifier.layoutViewportRelative = true;
  4691. return;
  4692. }
  4693. } else {
  4694. if (language == EShLangRayGen || language == EShLangIntersect ||
  4695. language == EShLangAnyHit || language == EShLangClosestHit ||
  4696. language == EShLangMiss || language == EShLangCallable) {
  4697. if (id == "shaderrecordnv" || id == "shaderrecordext") {
  4698. if (id == "shaderrecordnv") {
  4699. requireExtensions(loc, 1, &E_GL_NV_ray_tracing, "shader record NV");
  4700. } else {
  4701. requireExtensions(loc, 1, &E_GL_EXT_ray_tracing, "shader record EXT");
  4702. }
  4703. publicType.qualifier.layoutShaderRecord = true;
  4704. return;
  4705. }
  4706. }
  4707. }
  4708. if (language == EShLangCompute) {
  4709. if (id.compare(0, 17, "derivative_group_") == 0) {
  4710. requireExtensions(loc, 1, &E_GL_NV_compute_shader_derivatives, "compute shader derivatives");
  4711. if (id == "derivative_group_quadsnv") {
  4712. publicType.shaderQualifiers.layoutDerivativeGroupQuads = true;
  4713. return;
  4714. } else if (id == "derivative_group_linearnv") {
  4715. publicType.shaderQualifiers.layoutDerivativeGroupLinear = true;
  4716. return;
  4717. }
  4718. }
  4719. }
  4720. if (id == "primitive_culling") {
  4721. requireExtensions(loc, 1, &E_GL_EXT_ray_flags_primitive_culling, "primitive culling");
  4722. publicType.shaderQualifiers.layoutPrimitiveCulling = true;
  4723. return;
  4724. }
  4725. #endif
  4726. error(loc, "unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4)", id.c_str(), "");
  4727. }
  4728. // Put the id's layout qualifier value into the public type, for qualifiers having a number set.
  4729. // This is before we know any type information for error checking.
  4730. void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publicType, TString& id, const TIntermTyped* node)
  4731. {
  4732. const char* feature = "layout-id value";
  4733. const char* nonLiteralFeature = "non-literal layout-id value";
  4734. integerCheck(node, feature);
  4735. const TIntermConstantUnion* constUnion = node->getAsConstantUnion();
  4736. int value;
  4737. bool nonLiteral = false;
  4738. if (constUnion) {
  4739. value = constUnion->getConstArray()[0].getIConst();
  4740. if (! constUnion->isLiteral()) {
  4741. requireProfile(loc, ECoreProfile | ECompatibilityProfile, nonLiteralFeature);
  4742. profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, nonLiteralFeature);
  4743. }
  4744. } else {
  4745. // grammar should have give out the error message
  4746. value = 0;
  4747. nonLiteral = true;
  4748. }
  4749. if (value < 0) {
  4750. error(loc, "cannot be negative", feature, "");
  4751. return;
  4752. }
  4753. std::transform(id.begin(), id.end(), id.begin(), ::tolower);
  4754. if (id == "offset") {
  4755. // "offset" can be for either
  4756. // - uniform offsets
  4757. // - atomic_uint offsets
  4758. const char* feature = "offset";
  4759. if (spvVersion.spv == 0) {
  4760. requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, feature);
  4761. const char* exts[2] = { E_GL_ARB_enhanced_layouts, E_GL_ARB_shader_atomic_counters };
  4762. profileRequires(loc, ECoreProfile | ECompatibilityProfile, 420, 2, exts, feature);
  4763. profileRequires(loc, EEsProfile, 310, nullptr, feature);
  4764. }
  4765. publicType.qualifier.layoutOffset = value;
  4766. publicType.qualifier.explicitOffset = true;
  4767. if (nonLiteral)
  4768. error(loc, "needs a literal integer", "offset", "");
  4769. return;
  4770. } else if (id == "align") {
  4771. const char* feature = "uniform buffer-member align";
  4772. if (spvVersion.spv == 0) {
  4773. requireProfile(loc, ECoreProfile | ECompatibilityProfile, feature);
  4774. profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, feature);
  4775. }
  4776. // "The specified alignment must be a power of 2, or a compile-time error results."
  4777. if (! IsPow2(value))
  4778. error(loc, "must be a power of 2", "align", "");
  4779. else
  4780. publicType.qualifier.layoutAlign = value;
  4781. if (nonLiteral)
  4782. error(loc, "needs a literal integer", "align", "");
  4783. return;
  4784. } else if (id == "location") {
  4785. profileRequires(loc, EEsProfile, 300, nullptr, "location");
  4786. const char* exts[2] = { E_GL_ARB_separate_shader_objects, E_GL_ARB_explicit_attrib_location };
  4787. // GL_ARB_explicit_uniform_location requires 330 or GL_ARB_explicit_attrib_location we do not need to add it here
  4788. profileRequires(loc, ~EEsProfile, 330, 2, exts, "location");
  4789. if ((unsigned int)value >= TQualifier::layoutLocationEnd)
  4790. error(loc, "location is too large", id.c_str(), "");
  4791. else
  4792. publicType.qualifier.layoutLocation = value;
  4793. if (nonLiteral)
  4794. error(loc, "needs a literal integer", "location", "");
  4795. return;
  4796. } else if (id == "set") {
  4797. if ((unsigned int)value >= TQualifier::layoutSetEnd)
  4798. error(loc, "set is too large", id.c_str(), "");
  4799. else
  4800. publicType.qualifier.layoutSet = value;
  4801. if (value != 0)
  4802. requireVulkan(loc, "descriptor set");
  4803. if (nonLiteral)
  4804. error(loc, "needs a literal integer", "set", "");
  4805. return;
  4806. } else if (id == "binding") {
  4807. #ifndef GLSLANG_WEB
  4808. profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, "binding");
  4809. profileRequires(loc, EEsProfile, 310, nullptr, "binding");
  4810. #endif
  4811. if ((unsigned int)value >= TQualifier::layoutBindingEnd)
  4812. error(loc, "binding is too large", id.c_str(), "");
  4813. else
  4814. publicType.qualifier.layoutBinding = value;
  4815. if (nonLiteral)
  4816. error(loc, "needs a literal integer", "binding", "");
  4817. return;
  4818. }
  4819. if (id == "constant_id") {
  4820. requireSpv(loc, "constant_id");
  4821. if (value >= (int)TQualifier::layoutSpecConstantIdEnd) {
  4822. error(loc, "specialization-constant id is too large", id.c_str(), "");
  4823. } else {
  4824. publicType.qualifier.layoutSpecConstantId = value;
  4825. publicType.qualifier.specConstant = true;
  4826. if (! intermediate.addUsedConstantId(value))
  4827. error(loc, "specialization-constant id already used", id.c_str(), "");
  4828. }
  4829. if (nonLiteral)
  4830. error(loc, "needs a literal integer", "constant_id", "");
  4831. return;
  4832. }
  4833. #ifndef GLSLANG_WEB
  4834. if (id == "component") {
  4835. requireProfile(loc, ECoreProfile | ECompatibilityProfile, "component");
  4836. profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, "component");
  4837. if ((unsigned)value >= TQualifier::layoutComponentEnd)
  4838. error(loc, "component is too large", id.c_str(), "");
  4839. else
  4840. publicType.qualifier.layoutComponent = value;
  4841. if (nonLiteral)
  4842. error(loc, "needs a literal integer", "component", "");
  4843. return;
  4844. }
  4845. if (id.compare(0, 4, "xfb_") == 0) {
  4846. // "Any shader making any static use (after preprocessing) of any of these
  4847. // *xfb_* qualifiers will cause the shader to be in a transform feedback
  4848. // capturing mode and hence responsible for describing the transform feedback
  4849. // setup."
  4850. intermediate.setXfbMode();
  4851. const char* feature = "transform feedback qualifier";
  4852. requireStage(loc, (EShLanguageMask)(EShLangVertexMask | EShLangGeometryMask | EShLangTessControlMask | EShLangTessEvaluationMask), feature);
  4853. requireProfile(loc, ECoreProfile | ECompatibilityProfile, feature);
  4854. profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, feature);
  4855. if (id == "xfb_buffer") {
  4856. // "It is a compile-time error to specify an *xfb_buffer* that is greater than
  4857. // the implementation-dependent constant gl_MaxTransformFeedbackBuffers."
  4858. if (value >= resources.maxTransformFeedbackBuffers)
  4859. error(loc, "buffer is too large:", id.c_str(), "gl_MaxTransformFeedbackBuffers is %d", resources.maxTransformFeedbackBuffers);
  4860. if (value >= (int)TQualifier::layoutXfbBufferEnd)
  4861. error(loc, "buffer is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbBufferEnd-1);
  4862. else
  4863. publicType.qualifier.layoutXfbBuffer = value;
  4864. if (nonLiteral)
  4865. error(loc, "needs a literal integer", "xfb_buffer", "");
  4866. return;
  4867. } else if (id == "xfb_offset") {
  4868. if (value >= (int)TQualifier::layoutXfbOffsetEnd)
  4869. error(loc, "offset is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbOffsetEnd-1);
  4870. else
  4871. publicType.qualifier.layoutXfbOffset = value;
  4872. if (nonLiteral)
  4873. error(loc, "needs a literal integer", "xfb_offset", "");
  4874. return;
  4875. } else if (id == "xfb_stride") {
  4876. // "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the
  4877. // implementation-dependent constant gl_MaxTransformFeedbackInterleavedComponents."
  4878. if (value > 4 * resources.maxTransformFeedbackInterleavedComponents) {
  4879. error(loc, "1/4 stride is too large:", id.c_str(), "gl_MaxTransformFeedbackInterleavedComponents is %d",
  4880. resources.maxTransformFeedbackInterleavedComponents);
  4881. }
  4882. if (value >= (int)TQualifier::layoutXfbStrideEnd)
  4883. error(loc, "stride is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbStrideEnd-1);
  4884. else
  4885. publicType.qualifier.layoutXfbStride = value;
  4886. if (nonLiteral)
  4887. error(loc, "needs a literal integer", "xfb_stride", "");
  4888. return;
  4889. }
  4890. }
  4891. if (id == "input_attachment_index") {
  4892. requireVulkan(loc, "input_attachment_index");
  4893. if (value >= (int)TQualifier::layoutAttachmentEnd)
  4894. error(loc, "attachment index is too large", id.c_str(), "");
  4895. else
  4896. publicType.qualifier.layoutAttachment = value;
  4897. if (nonLiteral)
  4898. error(loc, "needs a literal integer", "input_attachment_index", "");
  4899. return;
  4900. }
  4901. if (id == "num_views") {
  4902. requireExtensions(loc, Num_OVR_multiview_EXTs, OVR_multiview_EXTs, "num_views");
  4903. publicType.shaderQualifiers.numViews = value;
  4904. if (nonLiteral)
  4905. error(loc, "needs a literal integer", "num_views", "");
  4906. return;
  4907. }
  4908. if (language == EShLangVertex ||
  4909. language == EShLangTessControl ||
  4910. language == EShLangTessEvaluation ||
  4911. language == EShLangGeometry) {
  4912. if (id == "secondary_view_offset") {
  4913. requireExtensions(loc, 1, &E_GL_NV_stereo_view_rendering, "stereo view rendering");
  4914. publicType.qualifier.layoutSecondaryViewportRelativeOffset = value;
  4915. if (nonLiteral)
  4916. error(loc, "needs a literal integer", "secondary_view_offset", "");
  4917. return;
  4918. }
  4919. }
  4920. if (id == "buffer_reference_align") {
  4921. requireExtensions(loc, 1, &E_GL_EXT_buffer_reference, "buffer_reference_align");
  4922. if (! IsPow2(value))
  4923. error(loc, "must be a power of 2", "buffer_reference_align", "");
  4924. else
  4925. #ifdef __ANDROID__
  4926. // Android NDK r15c tageting ABI 15 doesn't have full support for C++11
  4927. // (no std::exp2/log2). ::exp2 is available from C99 but ::log2 isn't
  4928. // available up until ABI 18 so we use the mathematical equivalent form
  4929. publicType.qualifier.layoutBufferReferenceAlign = (unsigned int)(std::log(value) / std::log(2.0));
  4930. #else
  4931. publicType.qualifier.layoutBufferReferenceAlign = (unsigned int)std::log2(value);
  4932. #endif
  4933. if (nonLiteral)
  4934. error(loc, "needs a literal integer", "buffer_reference_align", "");
  4935. return;
  4936. }
  4937. #endif
  4938. switch (language) {
  4939. #ifndef GLSLANG_WEB
  4940. case EShLangTessControl:
  4941. if (id == "vertices") {
  4942. if (value == 0)
  4943. error(loc, "must be greater than 0", "vertices", "");
  4944. else
  4945. publicType.shaderQualifiers.vertices = value;
  4946. if (nonLiteral)
  4947. error(loc, "needs a literal integer", "vertices", "");
  4948. return;
  4949. }
  4950. break;
  4951. case EShLangGeometry:
  4952. if (id == "invocations") {
  4953. profileRequires(loc, ECompatibilityProfile | ECoreProfile, 400, nullptr, "invocations");
  4954. if (value == 0)
  4955. error(loc, "must be at least 1", "invocations", "");
  4956. else
  4957. publicType.shaderQualifiers.invocations = value;
  4958. if (nonLiteral)
  4959. error(loc, "needs a literal integer", "invocations", "");
  4960. return;
  4961. }
  4962. if (id == "max_vertices") {
  4963. publicType.shaderQualifiers.vertices = value;
  4964. if (value > resources.maxGeometryOutputVertices)
  4965. error(loc, "too large, must be less than gl_MaxGeometryOutputVertices", "max_vertices", "");
  4966. if (nonLiteral)
  4967. error(loc, "needs a literal integer", "max_vertices", "");
  4968. return;
  4969. }
  4970. if (id == "stream") {
  4971. requireProfile(loc, ~EEsProfile, "selecting output stream");
  4972. publicType.qualifier.layoutStream = value;
  4973. if (value > 0)
  4974. intermediate.setMultiStream();
  4975. if (nonLiteral)
  4976. error(loc, "needs a literal integer", "stream", "");
  4977. return;
  4978. }
  4979. break;
  4980. case EShLangFragment:
  4981. if (id == "index") {
  4982. requireProfile(loc, ECompatibilityProfile | ECoreProfile | EEsProfile, "index layout qualifier on fragment output");
  4983. const char* exts[2] = { E_GL_ARB_separate_shader_objects, E_GL_ARB_explicit_attrib_location };
  4984. profileRequires(loc, ECompatibilityProfile | ECoreProfile, 330, 2, exts, "index layout qualifier on fragment output");
  4985. profileRequires(loc, EEsProfile ,310, E_GL_EXT_blend_func_extended, "index layout qualifier on fragment output");
  4986. // "It is also a compile-time error if a fragment shader sets a layout index to less than 0 or greater than 1."
  4987. if (value < 0 || value > 1) {
  4988. value = 0;
  4989. error(loc, "value must be 0 or 1", "index", "");
  4990. }
  4991. publicType.qualifier.layoutIndex = value;
  4992. if (nonLiteral)
  4993. error(loc, "needs a literal integer", "index", "");
  4994. return;
  4995. }
  4996. break;
  4997. case EShLangMeshNV:
  4998. if (id == "max_vertices") {
  4999. requireExtensions(loc, 1, &E_GL_NV_mesh_shader, "max_vertices");
  5000. publicType.shaderQualifiers.vertices = value;
  5001. if (value > resources.maxMeshOutputVerticesNV)
  5002. error(loc, "too large, must be less than gl_MaxMeshOutputVerticesNV", "max_vertices", "");
  5003. if (nonLiteral)
  5004. error(loc, "needs a literal integer", "max_vertices", "");
  5005. return;
  5006. }
  5007. if (id == "max_primitives") {
  5008. requireExtensions(loc, 1, &E_GL_NV_mesh_shader, "max_primitives");
  5009. publicType.shaderQualifiers.primitives = value;
  5010. if (value > resources.maxMeshOutputPrimitivesNV)
  5011. error(loc, "too large, must be less than gl_MaxMeshOutputPrimitivesNV", "max_primitives", "");
  5012. if (nonLiteral)
  5013. error(loc, "needs a literal integer", "max_primitives", "");
  5014. return;
  5015. }
  5016. // Fall through
  5017. case EShLangTaskNV:
  5018. // Fall through
  5019. #endif
  5020. case EShLangCompute:
  5021. if (id.compare(0, 11, "local_size_") == 0) {
  5022. #ifndef GLSLANG_WEB
  5023. if (language == EShLangMeshNV || language == EShLangTaskNV) {
  5024. requireExtensions(loc, 1, &E_GL_NV_mesh_shader, "gl_WorkGroupSize");
  5025. } else {
  5026. profileRequires(loc, EEsProfile, 310, 0, "gl_WorkGroupSize");
  5027. profileRequires(loc, ~EEsProfile, 430, E_GL_ARB_compute_shader, "gl_WorkGroupSize");
  5028. }
  5029. #endif
  5030. if (nonLiteral)
  5031. error(loc, "needs a literal integer", "local_size", "");
  5032. if (id.size() == 12 && value == 0) {
  5033. error(loc, "must be at least 1", id.c_str(), "");
  5034. return;
  5035. }
  5036. if (id == "local_size_x") {
  5037. publicType.shaderQualifiers.localSize[0] = value;
  5038. publicType.shaderQualifiers.localSizeNotDefault[0] = true;
  5039. return;
  5040. }
  5041. if (id == "local_size_y") {
  5042. publicType.shaderQualifiers.localSize[1] = value;
  5043. publicType.shaderQualifiers.localSizeNotDefault[1] = true;
  5044. return;
  5045. }
  5046. if (id == "local_size_z") {
  5047. publicType.shaderQualifiers.localSize[2] = value;
  5048. publicType.shaderQualifiers.localSizeNotDefault[2] = true;
  5049. return;
  5050. }
  5051. if (spvVersion.spv != 0) {
  5052. if (id == "local_size_x_id") {
  5053. publicType.shaderQualifiers.localSizeSpecId[0] = value;
  5054. return;
  5055. }
  5056. if (id == "local_size_y_id") {
  5057. publicType.shaderQualifiers.localSizeSpecId[1] = value;
  5058. return;
  5059. }
  5060. if (id == "local_size_z_id") {
  5061. publicType.shaderQualifiers.localSizeSpecId[2] = value;
  5062. return;
  5063. }
  5064. }
  5065. }
  5066. break;
  5067. default:
  5068. break;
  5069. }
  5070. error(loc, "there is no such layout identifier for this stage taking an assigned value", id.c_str(), "");
  5071. }
  5072. // Merge any layout qualifier information from src into dst, leaving everything else in dst alone
  5073. //
  5074. // "More than one layout qualifier may appear in a single declaration.
  5075. // Additionally, the same layout-qualifier-name can occur multiple times
  5076. // within a layout qualifier or across multiple layout qualifiers in the
  5077. // same declaration. When the same layout-qualifier-name occurs
  5078. // multiple times, in a single declaration, the last occurrence overrides
  5079. // the former occurrence(s). Further, if such a layout-qualifier-name
  5080. // will effect subsequent declarations or other observable behavior, it
  5081. // is only the last occurrence that will have any effect, behaving as if
  5082. // the earlier occurrence(s) within the declaration are not present.
  5083. // This is also true for overriding layout-qualifier-names, where one
  5084. // overrides the other (e.g., row_major vs. column_major); only the last
  5085. // occurrence has any effect."
  5086. void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifier& src, bool inheritOnly)
  5087. {
  5088. if (src.hasMatrix())
  5089. dst.layoutMatrix = src.layoutMatrix;
  5090. if (src.hasPacking())
  5091. dst.layoutPacking = src.layoutPacking;
  5092. #ifndef GLSLANG_WEB
  5093. if (src.hasStream())
  5094. dst.layoutStream = src.layoutStream;
  5095. if (src.hasFormat())
  5096. dst.layoutFormat = src.layoutFormat;
  5097. if (src.hasXfbBuffer())
  5098. dst.layoutXfbBuffer = src.layoutXfbBuffer;
  5099. if (src.hasBufferReferenceAlign())
  5100. dst.layoutBufferReferenceAlign = src.layoutBufferReferenceAlign;
  5101. #endif
  5102. if (src.hasAlign())
  5103. dst.layoutAlign = src.layoutAlign;
  5104. if (! inheritOnly) {
  5105. if (src.hasLocation())
  5106. dst.layoutLocation = src.layoutLocation;
  5107. if (src.hasOffset())
  5108. dst.layoutOffset = src.layoutOffset;
  5109. if (src.hasSet())
  5110. dst.layoutSet = src.layoutSet;
  5111. if (src.layoutBinding != TQualifier::layoutBindingEnd)
  5112. dst.layoutBinding = src.layoutBinding;
  5113. if (src.hasSpecConstantId())
  5114. dst.layoutSpecConstantId = src.layoutSpecConstantId;
  5115. #ifndef GLSLANG_WEB
  5116. if (src.hasComponent())
  5117. dst.layoutComponent = src.layoutComponent;
  5118. if (src.hasIndex())
  5119. dst.layoutIndex = src.layoutIndex;
  5120. if (src.hasXfbStride())
  5121. dst.layoutXfbStride = src.layoutXfbStride;
  5122. if (src.hasXfbOffset())
  5123. dst.layoutXfbOffset = src.layoutXfbOffset;
  5124. if (src.hasAttachment())
  5125. dst.layoutAttachment = src.layoutAttachment;
  5126. if (src.layoutPushConstant)
  5127. dst.layoutPushConstant = true;
  5128. if (src.layoutBufferReference)
  5129. dst.layoutBufferReference = true;
  5130. if (src.layoutPassthrough)
  5131. dst.layoutPassthrough = true;
  5132. if (src.layoutViewportRelative)
  5133. dst.layoutViewportRelative = true;
  5134. if (src.layoutSecondaryViewportRelativeOffset != -2048)
  5135. dst.layoutSecondaryViewportRelativeOffset = src.layoutSecondaryViewportRelativeOffset;
  5136. if (src.layoutShaderRecord)
  5137. dst.layoutShaderRecord = true;
  5138. if (src.pervertexNV)
  5139. dst.pervertexNV = true;
  5140. #endif
  5141. }
  5142. }
  5143. // Do error layout error checking given a full variable/block declaration.
  5144. void TParseContext::layoutObjectCheck(const TSourceLoc& loc, const TSymbol& symbol)
  5145. {
  5146. const TType& type = symbol.getType();
  5147. const TQualifier& qualifier = type.getQualifier();
  5148. // first, cross check WRT to just the type
  5149. layoutTypeCheck(loc, type);
  5150. // now, any remaining error checking based on the object itself
  5151. if (qualifier.hasAnyLocation()) {
  5152. switch (qualifier.storage) {
  5153. case EvqUniform:
  5154. case EvqBuffer:
  5155. if (symbol.getAsVariable() == nullptr)
  5156. error(loc, "can only be used on variable declaration", "location", "");
  5157. break;
  5158. default:
  5159. break;
  5160. }
  5161. }
  5162. // user-variable location check, which are required for SPIR-V in/out:
  5163. // - variables have it directly,
  5164. // - blocks have it on each member (already enforced), so check first one
  5165. if (spvVersion.spv > 0 && !parsingBuiltins && qualifier.builtIn == EbvNone &&
  5166. !qualifier.hasLocation() && !intermediate.getAutoMapLocations()) {
  5167. switch (qualifier.storage) {
  5168. case EvqVaryingIn:
  5169. case EvqVaryingOut:
  5170. if (!type.getQualifier().isTaskMemory() &&
  5171. (type.getBasicType() != EbtBlock ||
  5172. (!(*type.getStruct())[0].type->getQualifier().hasLocation() &&
  5173. (*type.getStruct())[0].type->getQualifier().builtIn == EbvNone)))
  5174. error(loc, "SPIR-V requires location for user input/output", "location", "");
  5175. break;
  5176. default:
  5177. break;
  5178. }
  5179. }
  5180. // Check packing and matrix
  5181. if (qualifier.hasUniformLayout()) {
  5182. switch (qualifier.storage) {
  5183. case EvqUniform:
  5184. case EvqBuffer:
  5185. if (type.getBasicType() != EbtBlock) {
  5186. if (qualifier.hasMatrix())
  5187. error(loc, "cannot specify matrix layout on a variable declaration", "layout", "");
  5188. if (qualifier.hasPacking())
  5189. error(loc, "cannot specify packing on a variable declaration", "layout", "");
  5190. // "The offset qualifier can only be used on block members of blocks..."
  5191. if (qualifier.hasOffset() && !type.isAtomic())
  5192. error(loc, "cannot specify on a variable declaration", "offset", "");
  5193. // "The align qualifier can only be used on blocks or block members..."
  5194. if (qualifier.hasAlign())
  5195. error(loc, "cannot specify on a variable declaration", "align", "");
  5196. if (qualifier.isPushConstant())
  5197. error(loc, "can only specify on a uniform block", "push_constant", "");
  5198. if (qualifier.isShaderRecord())
  5199. error(loc, "can only specify on a buffer block", "shaderRecordNV", "");
  5200. }
  5201. break;
  5202. default:
  5203. // these were already filtered by layoutTypeCheck() (or its callees)
  5204. break;
  5205. }
  5206. }
  5207. }
  5208. // "For some blocks declared as arrays, the location can only be applied at the block level:
  5209. // When a block is declared as an array where additional locations are needed for each member
  5210. // for each block array element, it is a compile-time error to specify locations on the block
  5211. // members. That is, when locations would be under specified by applying them on block members,
  5212. // they are not allowed on block members. For arrayed interfaces (those generally having an
  5213. // extra level of arrayness due to interface expansion), the outer array is stripped before
  5214. // applying this rule."
  5215. void TParseContext::layoutMemberLocationArrayCheck(const TSourceLoc& loc, bool memberWithLocation,
  5216. TArraySizes* arraySizes)
  5217. {
  5218. if (memberWithLocation && arraySizes != nullptr) {
  5219. if (arraySizes->getNumDims() > (currentBlockQualifier.isArrayedIo(language) ? 1 : 0))
  5220. error(loc, "cannot use in a block array where new locations are needed for each block element",
  5221. "location", "");
  5222. }
  5223. }
  5224. // Do layout error checking with respect to a type.
  5225. void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
  5226. {
  5227. const TQualifier& qualifier = type.getQualifier();
  5228. // first, intra-layout qualifier-only error checking
  5229. layoutQualifierCheck(loc, qualifier);
  5230. // now, error checking combining type and qualifier
  5231. if (qualifier.hasAnyLocation()) {
  5232. if (qualifier.hasLocation()) {
  5233. if (qualifier.storage == EvqVaryingOut && language == EShLangFragment) {
  5234. if (qualifier.layoutLocation >= (unsigned int)resources.maxDrawBuffers)
  5235. error(loc, "too large for fragment output", "location", "");
  5236. }
  5237. }
  5238. if (qualifier.hasComponent()) {
  5239. // "It is a compile-time error if this sequence of components gets larger than 3."
  5240. if (qualifier.layoutComponent + type.getVectorSize() * (type.getBasicType() == EbtDouble ? 2 : 1) > 4)
  5241. error(loc, "type overflows the available 4 components", "component", "");
  5242. // "It is a compile-time error to apply the component qualifier to a matrix, a structure, a block, or an array containing any of these."
  5243. if (type.isMatrix() || type.getBasicType() == EbtBlock || type.getBasicType() == EbtStruct)
  5244. error(loc, "cannot apply to a matrix, structure, or block", "component", "");
  5245. // " It is a compile-time error to use component 1 or 3 as the beginning of a double or dvec2."
  5246. if (type.getBasicType() == EbtDouble)
  5247. if (qualifier.layoutComponent & 1)
  5248. error(loc, "doubles cannot start on an odd-numbered component", "component", "");
  5249. }
  5250. switch (qualifier.storage) {
  5251. case EvqVaryingIn:
  5252. case EvqVaryingOut:
  5253. if (type.getBasicType() == EbtBlock)
  5254. profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, "location qualifier on in/out block");
  5255. if (type.getQualifier().isTaskMemory())
  5256. error(loc, "cannot apply to taskNV in/out blocks", "location", "");
  5257. break;
  5258. case EvqUniform:
  5259. case EvqBuffer:
  5260. if (type.getBasicType() == EbtBlock)
  5261. error(loc, "cannot apply to uniform or buffer block", "location", "");
  5262. break;
  5263. #ifndef GLSLANG_WEB
  5264. case EvqPayload:
  5265. case EvqPayloadIn:
  5266. case EvqHitAttr:
  5267. case EvqCallableData:
  5268. case EvqCallableDataIn:
  5269. break;
  5270. #endif
  5271. default:
  5272. error(loc, "can only apply to uniform, buffer, in, or out storage qualifiers", "location", "");
  5273. break;
  5274. }
  5275. bool typeCollision;
  5276. int repeated = intermediate.addUsedLocation(qualifier, type, typeCollision);
  5277. if (repeated >= 0 && ! typeCollision)
  5278. error(loc, "overlapping use of location", "location", "%d", repeated);
  5279. // "fragment-shader outputs ... if two variables are placed within the same
  5280. // location, they must have the same underlying type (floating-point or integer)"
  5281. if (typeCollision && language == EShLangFragment && qualifier.isPipeOutput())
  5282. error(loc, "fragment outputs sharing the same location must be the same basic type", "location", "%d", repeated);
  5283. }
  5284. #ifndef GLSLANG_WEB
  5285. if (qualifier.hasXfbOffset() && qualifier.hasXfbBuffer()) {
  5286. int repeated = intermediate.addXfbBufferOffset(type);
  5287. if (repeated >= 0)
  5288. error(loc, "overlapping offsets at", "xfb_offset", "offset %d in buffer %d", repeated, qualifier.layoutXfbBuffer);
  5289. if (type.isUnsizedArray())
  5290. error(loc, "unsized array", "xfb_offset", "in buffer %d", qualifier.layoutXfbBuffer);
  5291. // "The offset must be a multiple of the size of the first component of the first
  5292. // qualified variable or block member, or a compile-time error results. Further, if applied to an aggregate
  5293. // containing a double or 64-bit integer, the offset must also be a multiple of 8..."
  5294. if ((type.containsBasicType(EbtDouble) || type.containsBasicType(EbtInt64) || type.containsBasicType(EbtUint64)) &&
  5295. ! IsMultipleOfPow2(qualifier.layoutXfbOffset, 8))
  5296. error(loc, "type contains double or 64-bit integer; xfb_offset must be a multiple of 8", "xfb_offset", "");
  5297. else if ((type.containsBasicType(EbtBool) || type.containsBasicType(EbtFloat) ||
  5298. type.containsBasicType(EbtInt) || type.containsBasicType(EbtUint)) &&
  5299. ! IsMultipleOfPow2(qualifier.layoutXfbOffset, 4))
  5300. error(loc, "must be a multiple of size of first component", "xfb_offset", "");
  5301. // ..., if applied to an aggregate containing a half float or 16-bit integer, the offset must also be a multiple of 2..."
  5302. else if ((type.contains16BitFloat() || type.containsBasicType(EbtInt16) || type.containsBasicType(EbtUint16)) &&
  5303. !IsMultipleOfPow2(qualifier.layoutXfbOffset, 2))
  5304. error(loc, "type contains half float or 16-bit integer; xfb_offset must be a multiple of 2", "xfb_offset", "");
  5305. }
  5306. if (qualifier.hasXfbStride() && qualifier.hasXfbBuffer()) {
  5307. if (! intermediate.setXfbBufferStride(qualifier.layoutXfbBuffer, qualifier.layoutXfbStride))
  5308. error(loc, "all stride settings must match for xfb buffer", "xfb_stride", "%d", qualifier.layoutXfbBuffer);
  5309. }
  5310. #endif
  5311. if (qualifier.hasBinding()) {
  5312. // Binding checking, from the spec:
  5313. //
  5314. // "If the binding point for any uniform or shader storage block instance is less than zero, or greater than or
  5315. // equal to the implementation-dependent maximum number of uniform buffer bindings, a compile-time
  5316. // error will occur. When the binding identifier is used with a uniform or shader storage block instanced as
  5317. // an array of size N, all elements of the array from binding through binding + N - 1 must be within this
  5318. // range."
  5319. //
  5320. if (! type.isOpaque() && type.getBasicType() != EbtBlock)
  5321. error(loc, "requires block, or sampler/image, or atomic-counter type", "binding", "");
  5322. if (type.getBasicType() == EbtSampler) {
  5323. int lastBinding = qualifier.layoutBinding;
  5324. if (type.isArray()) {
  5325. if (spvVersion.vulkan > 0)
  5326. lastBinding += 1;
  5327. else {
  5328. if (type.isSizedArray())
  5329. lastBinding += type.getCumulativeArraySize();
  5330. else {
  5331. lastBinding += 1;
  5332. #ifndef GLSLANG_WEB
  5333. if (spvVersion.vulkan == 0)
  5334. warn(loc, "assuming binding count of one for compile-time checking of binding numbers for unsized array", "[]", "");
  5335. #endif
  5336. }
  5337. }
  5338. }
  5339. #ifndef GLSLANG_WEB
  5340. if (spvVersion.vulkan == 0 && lastBinding >= resources.maxCombinedTextureImageUnits)
  5341. error(loc, "sampler binding not less than gl_MaxCombinedTextureImageUnits", "binding", type.isArray() ? "(using array)" : "");
  5342. #endif
  5343. }
  5344. if (type.isAtomic()) {
  5345. if (qualifier.layoutBinding >= (unsigned int)resources.maxAtomicCounterBindings) {
  5346. error(loc, "atomic_uint binding is too large; see gl_MaxAtomicCounterBindings", "binding", "");
  5347. return;
  5348. }
  5349. }
  5350. } else if (!intermediate.getAutoMapBindings()) {
  5351. // some types require bindings
  5352. // atomic_uint
  5353. if (type.isAtomic())
  5354. error(loc, "layout(binding=X) is required", "atomic_uint", "");
  5355. // SPIR-V
  5356. if (spvVersion.spv > 0) {
  5357. if (qualifier.isUniformOrBuffer()) {
  5358. if (type.getBasicType() == EbtBlock && !qualifier.isPushConstant() &&
  5359. !qualifier.isShaderRecord() &&
  5360. !qualifier.hasAttachment() &&
  5361. !qualifier.hasBufferReference())
  5362. error(loc, "uniform/buffer blocks require layout(binding=X)", "binding", "");
  5363. else if (spvVersion.vulkan > 0 && type.getBasicType() == EbtSampler)
  5364. error(loc, "sampler/texture/image requires layout(binding=X)", "binding", "");
  5365. }
  5366. }
  5367. }
  5368. // some things can't have arrays of arrays
  5369. if (type.isArrayOfArrays()) {
  5370. if (spvVersion.vulkan > 0) {
  5371. if (type.isOpaque() || (type.getQualifier().isUniformOrBuffer() && type.getBasicType() == EbtBlock))
  5372. warn(loc, "Generating SPIR-V array-of-arrays, but Vulkan only supports single array level for this resource", "[][]", "");
  5373. }
  5374. }
  5375. // "The offset qualifier can only be used on block members of blocks..."
  5376. if (qualifier.hasOffset()) {
  5377. if (type.getBasicType() == EbtBlock)
  5378. error(loc, "only applies to block members, not blocks", "offset", "");
  5379. }
  5380. // Image format
  5381. if (qualifier.hasFormat()) {
  5382. if (! type.isImage())
  5383. error(loc, "only apply to images", TQualifier::getLayoutFormatString(qualifier.getFormat()), "");
  5384. else {
  5385. if (type.getSampler().type == EbtFloat && qualifier.getFormat() > ElfFloatGuard)
  5386. error(loc, "does not apply to floating point images", TQualifier::getLayoutFormatString(qualifier.getFormat()), "");
  5387. if (type.getSampler().type == EbtInt && (qualifier.getFormat() < ElfFloatGuard || qualifier.getFormat() > ElfIntGuard))
  5388. error(loc, "does not apply to signed integer images", TQualifier::getLayoutFormatString(qualifier.getFormat()), "");
  5389. if (type.getSampler().type == EbtUint && qualifier.getFormat() < ElfIntGuard)
  5390. error(loc, "does not apply to unsigned integer images", TQualifier::getLayoutFormatString(qualifier.getFormat()), "");
  5391. if (isEsProfile()) {
  5392. // "Except for image variables qualified with the format qualifiers r32f, r32i, and r32ui, image variables must
  5393. // specify either memory qualifier readonly or the memory qualifier writeonly."
  5394. if (! (qualifier.getFormat() == ElfR32f || qualifier.getFormat() == ElfR32i || qualifier.getFormat() == ElfR32ui)) {
  5395. if (! qualifier.isReadOnly() && ! qualifier.isWriteOnly())
  5396. error(loc, "format requires readonly or writeonly memory qualifier", TQualifier::getLayoutFormatString(qualifier.getFormat()), "");
  5397. }
  5398. }
  5399. }
  5400. } else if (type.isImage() && ! qualifier.isWriteOnly()) {
  5401. const char *explanation = "image variables not declared 'writeonly' and without a format layout qualifier";
  5402. requireProfile(loc, ECoreProfile | ECompatibilityProfile, explanation);
  5403. profileRequires(loc, ECoreProfile | ECompatibilityProfile, 0, E_GL_EXT_shader_image_load_formatted, explanation);
  5404. }
  5405. if (qualifier.isPushConstant() && type.getBasicType() != EbtBlock)
  5406. error(loc, "can only be used with a block", "push_constant", "");
  5407. if (qualifier.hasBufferReference() && type.getBasicType() != EbtBlock)
  5408. error(loc, "can only be used with a block", "buffer_reference", "");
  5409. if (qualifier.isShaderRecord() && type.getBasicType() != EbtBlock)
  5410. error(loc, "can only be used with a block", "shaderRecordNV", "");
  5411. // input attachment
  5412. if (type.isSubpass()) {
  5413. if (! qualifier.hasAttachment())
  5414. error(loc, "requires an input_attachment_index layout qualifier", "subpass", "");
  5415. } else {
  5416. if (qualifier.hasAttachment())
  5417. error(loc, "can only be used with a subpass", "input_attachment_index", "");
  5418. }
  5419. // specialization-constant id
  5420. if (qualifier.hasSpecConstantId()) {
  5421. if (type.getQualifier().storage != EvqConst)
  5422. error(loc, "can only be applied to 'const'-qualified scalar", "constant_id", "");
  5423. if (! type.isScalar())
  5424. error(loc, "can only be applied to a scalar", "constant_id", "");
  5425. switch (type.getBasicType())
  5426. {
  5427. case EbtInt8:
  5428. case EbtUint8:
  5429. case EbtInt16:
  5430. case EbtUint16:
  5431. case EbtInt:
  5432. case EbtUint:
  5433. case EbtInt64:
  5434. case EbtUint64:
  5435. case EbtBool:
  5436. case EbtFloat:
  5437. case EbtDouble:
  5438. case EbtFloat16:
  5439. break;
  5440. default:
  5441. error(loc, "cannot be applied to this type", "constant_id", "");
  5442. break;
  5443. }
  5444. }
  5445. }
  5446. static bool storageCanHaveLayoutInBlock(const enum TStorageQualifier storage)
  5447. {
  5448. switch (storage) {
  5449. case EvqUniform:
  5450. case EvqBuffer:
  5451. case EvqShared:
  5452. return true;
  5453. default:
  5454. return false;
  5455. }
  5456. }
  5457. // Do layout error checking that can be done within a layout qualifier proper, not needing to know
  5458. // if there are blocks, atomic counters, variables, etc.
  5459. void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier& qualifier)
  5460. {
  5461. if (qualifier.storage == EvqShared && qualifier.hasLayout()) {
  5462. if (spvVersion.spv > 0 && spvVersion.spv < EShTargetSpv_1_4) {
  5463. error(loc, "shared block requires at least SPIR-V 1.4", "shared block", "");
  5464. }
  5465. profileRequires(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, 0, E_GL_EXT_shared_memory_block, "shared block");
  5466. }
  5467. // "It is a compile-time error to use *component* without also specifying the location qualifier (order does not matter)."
  5468. if (qualifier.hasComponent() && ! qualifier.hasLocation())
  5469. error(loc, "must specify 'location' to use 'component'", "component", "");
  5470. if (qualifier.hasAnyLocation()) {
  5471. // "As with input layout qualifiers, all shaders except compute shaders
  5472. // allow *location* layout qualifiers on output variable declarations,
  5473. // output block declarations, and output block member declarations."
  5474. switch (qualifier.storage) {
  5475. #ifndef GLSLANG_WEB
  5476. case EvqVaryingIn:
  5477. {
  5478. const char* feature = "location qualifier on input";
  5479. if (isEsProfile() && version < 310)
  5480. requireStage(loc, EShLangVertex, feature);
  5481. else
  5482. requireStage(loc, (EShLanguageMask)~EShLangComputeMask, feature);
  5483. if (language == EShLangVertex) {
  5484. const char* exts[2] = { E_GL_ARB_separate_shader_objects, E_GL_ARB_explicit_attrib_location };
  5485. profileRequires(loc, ~EEsProfile, 330, 2, exts, feature);
  5486. profileRequires(loc, EEsProfile, 300, nullptr, feature);
  5487. } else {
  5488. profileRequires(loc, ~EEsProfile, 410, E_GL_ARB_separate_shader_objects, feature);
  5489. profileRequires(loc, EEsProfile, 310, nullptr, feature);
  5490. }
  5491. break;
  5492. }
  5493. case EvqVaryingOut:
  5494. {
  5495. const char* feature = "location qualifier on output";
  5496. if (isEsProfile() && version < 310)
  5497. requireStage(loc, EShLangFragment, feature);
  5498. else
  5499. requireStage(loc, (EShLanguageMask)~EShLangComputeMask, feature);
  5500. if (language == EShLangFragment) {
  5501. const char* exts[2] = { E_GL_ARB_separate_shader_objects, E_GL_ARB_explicit_attrib_location };
  5502. profileRequires(loc, ~EEsProfile, 330, 2, exts, feature);
  5503. profileRequires(loc, EEsProfile, 300, nullptr, feature);
  5504. } else {
  5505. profileRequires(loc, ~EEsProfile, 410, E_GL_ARB_separate_shader_objects, feature);
  5506. profileRequires(loc, EEsProfile, 310, nullptr, feature);
  5507. }
  5508. break;
  5509. }
  5510. #endif
  5511. case EvqUniform:
  5512. case EvqBuffer:
  5513. {
  5514. const char* feature = "location qualifier on uniform or buffer";
  5515. requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile | ENoProfile, feature);
  5516. profileRequires(loc, ~EEsProfile, 330, E_GL_ARB_explicit_attrib_location, feature);
  5517. profileRequires(loc, ~EEsProfile, 430, E_GL_ARB_explicit_uniform_location, feature);
  5518. profileRequires(loc, EEsProfile, 310, nullptr, feature);
  5519. break;
  5520. }
  5521. default:
  5522. break;
  5523. }
  5524. if (qualifier.hasIndex()) {
  5525. if (qualifier.storage != EvqVaryingOut)
  5526. error(loc, "can only be used on an output", "index", "");
  5527. if (! qualifier.hasLocation())
  5528. error(loc, "can only be used with an explicit location", "index", "");
  5529. }
  5530. }
  5531. if (qualifier.hasBinding()) {
  5532. if (! qualifier.isUniformOrBuffer() && !qualifier.isTaskMemory())
  5533. error(loc, "requires uniform or buffer storage qualifier", "binding", "");
  5534. }
  5535. if (qualifier.hasStream()) {
  5536. if (!qualifier.isPipeOutput())
  5537. error(loc, "can only be used on an output", "stream", "");
  5538. }
  5539. if (qualifier.hasXfb()) {
  5540. if (!qualifier.isPipeOutput())
  5541. error(loc, "can only be used on an output", "xfb layout qualifier", "");
  5542. }
  5543. if (qualifier.hasUniformLayout()) {
  5544. if (!storageCanHaveLayoutInBlock(qualifier.storage) && !qualifier.isTaskMemory()) {
  5545. if (qualifier.hasMatrix() || qualifier.hasPacking())
  5546. error(loc, "matrix or packing qualifiers can only be used on a uniform or buffer", "layout", "");
  5547. if (qualifier.hasOffset() || qualifier.hasAlign())
  5548. error(loc, "offset/align can only be used on a uniform or buffer", "layout", "");
  5549. }
  5550. }
  5551. if (qualifier.isPushConstant()) {
  5552. if (qualifier.storage != EvqUniform)
  5553. error(loc, "can only be used with a uniform", "push_constant", "");
  5554. if (qualifier.hasSet())
  5555. error(loc, "cannot be used with push_constant", "set", "");
  5556. }
  5557. if (qualifier.hasBufferReference()) {
  5558. if (qualifier.storage != EvqBuffer)
  5559. error(loc, "can only be used with buffer", "buffer_reference", "");
  5560. }
  5561. if (qualifier.isShaderRecord()) {
  5562. if (qualifier.storage != EvqBuffer)
  5563. error(loc, "can only be used with a buffer", "shaderRecordNV", "");
  5564. if (qualifier.hasBinding())
  5565. error(loc, "cannot be used with shaderRecordNV", "binding", "");
  5566. if (qualifier.hasSet())
  5567. error(loc, "cannot be used with shaderRecordNV", "set", "");
  5568. }
  5569. if (qualifier.storage == EvqHitAttr && qualifier.hasLayout()) {
  5570. error(loc, "cannot apply layout qualifiers to hitAttributeNV variable", "hitAttributeNV", "");
  5571. }
  5572. }
  5573. // For places that can't have shader-level layout qualifiers
  5574. void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQualifiers& shaderQualifiers)
  5575. {
  5576. #ifndef GLSLANG_WEB
  5577. const char* message = "can only apply to a standalone qualifier";
  5578. if (shaderQualifiers.geometry != ElgNone)
  5579. error(loc, message, TQualifier::getGeometryString(shaderQualifiers.geometry), "");
  5580. if (shaderQualifiers.spacing != EvsNone)
  5581. error(loc, message, TQualifier::getVertexSpacingString(shaderQualifiers.spacing), "");
  5582. if (shaderQualifiers.order != EvoNone)
  5583. error(loc, message, TQualifier::getVertexOrderString(shaderQualifiers.order), "");
  5584. if (shaderQualifiers.pointMode)
  5585. error(loc, message, "point_mode", "");
  5586. if (shaderQualifiers.invocations != TQualifier::layoutNotSet)
  5587. error(loc, message, "invocations", "");
  5588. for (int i = 0; i < 3; ++i) {
  5589. if (shaderQualifiers.localSize[i] > 1)
  5590. error(loc, message, "local_size", "");
  5591. if (shaderQualifiers.localSizeSpecId[i] != TQualifier::layoutNotSet)
  5592. error(loc, message, "local_size id", "");
  5593. }
  5594. if (shaderQualifiers.vertices != TQualifier::layoutNotSet) {
  5595. if (language == EShLangGeometry || language == EShLangMeshNV)
  5596. error(loc, message, "max_vertices", "");
  5597. else if (language == EShLangTessControl)
  5598. error(loc, message, "vertices", "");
  5599. else
  5600. assert(0);
  5601. }
  5602. if (shaderQualifiers.earlyFragmentTests)
  5603. error(loc, message, "early_fragment_tests", "");
  5604. if (shaderQualifiers.postDepthCoverage)
  5605. error(loc, message, "post_depth_coverage", "");
  5606. if (shaderQualifiers.primitives != TQualifier::layoutNotSet) {
  5607. if (language == EShLangMeshNV)
  5608. error(loc, message, "max_primitives", "");
  5609. else
  5610. assert(0);
  5611. }
  5612. if (shaderQualifiers.hasBlendEquation())
  5613. error(loc, message, "blend equation", "");
  5614. if (shaderQualifiers.numViews != TQualifier::layoutNotSet)
  5615. error(loc, message, "num_views", "");
  5616. if (shaderQualifiers.interlockOrdering != EioNone)
  5617. error(loc, message, TQualifier::getInterlockOrderingString(shaderQualifiers.interlockOrdering), "");
  5618. if (shaderQualifiers.layoutPrimitiveCulling)
  5619. error(loc, "can only be applied as standalone", "primitive_culling", "");
  5620. #endif
  5621. }
  5622. // Correct and/or advance an object's offset layout qualifier.
  5623. void TParseContext::fixOffset(const TSourceLoc& loc, TSymbol& symbol)
  5624. {
  5625. const TQualifier& qualifier = symbol.getType().getQualifier();
  5626. #ifndef GLSLANG_WEB
  5627. if (symbol.getType().isAtomic()) {
  5628. if (qualifier.hasBinding() && (int)qualifier.layoutBinding < resources.maxAtomicCounterBindings) {
  5629. // Set the offset
  5630. int offset;
  5631. if (qualifier.hasOffset())
  5632. offset = qualifier.layoutOffset;
  5633. else
  5634. offset = atomicUintOffsets[qualifier.layoutBinding];
  5635. if (offset % 4 != 0)
  5636. error(loc, "atomic counters offset should align based on 4:", "offset", "%d", offset);
  5637. symbol.getWritableType().getQualifier().layoutOffset = offset;
  5638. // Check for overlap
  5639. int numOffsets = 4;
  5640. if (symbol.getType().isArray()) {
  5641. if (symbol.getType().isSizedArray() && !symbol.getType().getArraySizes()->isInnerUnsized())
  5642. numOffsets *= symbol.getType().getCumulativeArraySize();
  5643. else {
  5644. // "It is a compile-time error to declare an unsized array of atomic_uint."
  5645. error(loc, "array must be explicitly sized", "atomic_uint", "");
  5646. }
  5647. }
  5648. int repeated = intermediate.addUsedOffsets(qualifier.layoutBinding, offset, numOffsets);
  5649. if (repeated >= 0)
  5650. error(loc, "atomic counters sharing the same offset:", "offset", "%d", repeated);
  5651. // Bump the default offset
  5652. atomicUintOffsets[qualifier.layoutBinding] = offset + numOffsets;
  5653. }
  5654. }
  5655. #endif
  5656. }
  5657. //
  5658. // Look up a function name in the symbol table, and make sure it is a function.
  5659. //
  5660. // Return the function symbol if found, otherwise nullptr.
  5661. //
  5662. const TFunction* TParseContext::findFunction(const TSourceLoc& loc, const TFunction& call, bool& builtIn)
  5663. {
  5664. if (symbolTable.isFunctionNameVariable(call.getName())) {
  5665. error(loc, "can't use function syntax on variable", call.getName().c_str(), "");
  5666. return nullptr;
  5667. }
  5668. #ifdef GLSLANG_WEB
  5669. return findFunctionExact(loc, call, builtIn);
  5670. #endif
  5671. const TFunction* function = nullptr;
  5672. // debugPrintfEXT has var args and is in the symbol table as "debugPrintfEXT()",
  5673. // mangled to "debugPrintfEXT("
  5674. if (call.getName() == "debugPrintfEXT") {
  5675. TSymbol* symbol = symbolTable.find("debugPrintfEXT(", &builtIn);
  5676. if (symbol)
  5677. return symbol->getAsFunction();
  5678. }
  5679. bool explicitTypesEnabled = extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
  5680. extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int8) ||
  5681. extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int16) ||
  5682. extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int32) ||
  5683. extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int64) ||
  5684. extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float16) ||
  5685. extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float32) ||
  5686. extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float64);
  5687. if (isEsProfile())
  5688. function = (extensionTurnedOn(E_GL_EXT_shader_implicit_conversions) && version >= 310) ?
  5689. findFunction120(loc, call, builtIn) : findFunctionExact(loc, call, builtIn);
  5690. else if (version < 120)
  5691. function = findFunctionExact(loc, call, builtIn);
  5692. else if (version < 400)
  5693. function = extensionTurnedOn(E_GL_ARB_gpu_shader_fp64) ? findFunction400(loc, call, builtIn) : findFunction120(loc, call, builtIn);
  5694. else if (explicitTypesEnabled)
  5695. function = findFunctionExplicitTypes(loc, call, builtIn);
  5696. else
  5697. function = findFunction400(loc, call, builtIn);
  5698. return function;
  5699. }
  5700. // Function finding algorithm for ES and desktop 110.
  5701. const TFunction* TParseContext::findFunctionExact(const TSourceLoc& loc, const TFunction& call, bool& builtIn)
  5702. {
  5703. TSymbol* symbol = symbolTable.find(call.getMangledName(), &builtIn);
  5704. if (symbol == nullptr) {
  5705. error(loc, "no matching overloaded function found", call.getName().c_str(), "");
  5706. return nullptr;
  5707. }
  5708. return symbol->getAsFunction();
  5709. }
  5710. // Function finding algorithm for desktop versions 120 through 330.
  5711. const TFunction* TParseContext::findFunction120(const TSourceLoc& loc, const TFunction& call, bool& builtIn)
  5712. {
  5713. // first, look for an exact match
  5714. TSymbol* symbol = symbolTable.find(call.getMangledName(), &builtIn);
  5715. if (symbol)
  5716. return symbol->getAsFunction();
  5717. // exact match not found, look through a list of overloaded functions of the same name
  5718. // "If no exact match is found, then [implicit conversions] will be applied to find a match. Mismatched types
  5719. // on input parameters (in or inout or default) must have a conversion from the calling argument type to the
  5720. // formal parameter type. Mismatched types on output parameters (out or inout) must have a conversion
  5721. // from the formal parameter type to the calling argument type. When argument conversions are used to find
  5722. // a match, it is a semantic error if there are multiple ways to apply these conversions to make the call match
  5723. // more than one function."
  5724. const TFunction* candidate = nullptr;
  5725. TVector<const TFunction*> candidateList;
  5726. symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn);
  5727. for (auto it = candidateList.begin(); it != candidateList.end(); ++it) {
  5728. const TFunction& function = *(*it);
  5729. // to even be a potential match, number of arguments has to match
  5730. if (call.getParamCount() != function.getParamCount())
  5731. continue;
  5732. bool possibleMatch = true;
  5733. for (int i = 0; i < function.getParamCount(); ++i) {
  5734. // same types is easy
  5735. if (*function[i].type == *call[i].type)
  5736. continue;
  5737. // We have a mismatch in type, see if it is implicitly convertible
  5738. if (function[i].type->isArray() || call[i].type->isArray() ||
  5739. ! function[i].type->sameElementShape(*call[i].type))
  5740. possibleMatch = false;
  5741. else {
  5742. // do direction-specific checks for conversion of basic type
  5743. if (function[i].type->getQualifier().isParamInput()) {
  5744. if (! intermediate.canImplicitlyPromote(call[i].type->getBasicType(), function[i].type->getBasicType()))
  5745. possibleMatch = false;
  5746. }
  5747. if (function[i].type->getQualifier().isParamOutput()) {
  5748. if (! intermediate.canImplicitlyPromote(function[i].type->getBasicType(), call[i].type->getBasicType()))
  5749. possibleMatch = false;
  5750. }
  5751. }
  5752. if (! possibleMatch)
  5753. break;
  5754. }
  5755. if (possibleMatch) {
  5756. if (candidate) {
  5757. // our second match, meaning ambiguity
  5758. error(loc, "ambiguous function signature match: multiple signatures match under implicit type conversion", call.getName().c_str(), "");
  5759. } else
  5760. candidate = &function;
  5761. }
  5762. }
  5763. if (candidate == nullptr)
  5764. error(loc, "no matching overloaded function found", call.getName().c_str(), "");
  5765. return candidate;
  5766. }
  5767. // Function finding algorithm for desktop version 400 and above.
  5768. //
  5769. // "When function calls are resolved, an exact type match for all the arguments
  5770. // is sought. If an exact match is found, all other functions are ignored, and
  5771. // the exact match is used. If no exact match is found, then the implicit
  5772. // conversions in section 4.1.10 Implicit Conversions will be applied to find
  5773. // a match. Mismatched types on input parameters (in or inout or default) must
  5774. // have a conversion from the calling argument type to the formal parameter type.
  5775. // Mismatched types on output parameters (out or inout) must have a conversion
  5776. // from the formal parameter type to the calling argument type.
  5777. //
  5778. // "If implicit conversions can be used to find more than one matching function,
  5779. // a single best-matching function is sought. To determine a best match, the
  5780. // conversions between calling argument and formal parameter types are compared
  5781. // for each function argument and pair of matching functions. After these
  5782. // comparisons are performed, each pair of matching functions are compared.
  5783. // A function declaration A is considered a better match than function
  5784. // declaration B if
  5785. //
  5786. // * for at least one function argument, the conversion for that argument in A
  5787. // is better than the corresponding conversion in B; and
  5788. // * there is no function argument for which the conversion in B is better than
  5789. // the corresponding conversion in A.
  5790. //
  5791. // "If a single function declaration is considered a better match than every
  5792. // other matching function declaration, it will be used. Otherwise, a
  5793. // compile-time semantic error for an ambiguous overloaded function call occurs.
  5794. //
  5795. // "To determine whether the conversion for a single argument in one match is
  5796. // better than that for another match, the following rules are applied, in order:
  5797. //
  5798. // 1. An exact match is better than a match involving any implicit conversion.
  5799. // 2. A match involving an implicit conversion from float to double is better
  5800. // than a match involving any other implicit conversion.
  5801. // 3. A match involving an implicit conversion from either int or uint to float
  5802. // is better than a match involving an implicit conversion from either int
  5803. // or uint to double.
  5804. //
  5805. // "If none of the rules above apply to a particular pair of conversions, neither
  5806. // conversion is considered better than the other."
  5807. //
  5808. const TFunction* TParseContext::findFunction400(const TSourceLoc& loc, const TFunction& call, bool& builtIn)
  5809. {
  5810. // first, look for an exact match
  5811. TSymbol* symbol = symbolTable.find(call.getMangledName(), &builtIn);
  5812. if (symbol)
  5813. return symbol->getAsFunction();
  5814. // no exact match, use the generic selector, parameterized by the GLSL rules
  5815. // create list of candidates to send
  5816. TVector<const TFunction*> candidateList;
  5817. symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn);
  5818. // can 'from' convert to 'to'?
  5819. const auto convertible = [this,builtIn](const TType& from, const TType& to, TOperator, int) -> bool {
  5820. if (from == to)
  5821. return true;
  5822. if (from.coopMatParameterOK(to))
  5823. return true;
  5824. // Allow a sized array to be passed through an unsized array parameter, for coopMatLoad/Store functions
  5825. if (builtIn && from.isArray() && to.isUnsizedArray()) {
  5826. TType fromElementType(from, 0);
  5827. TType toElementType(to, 0);
  5828. if (fromElementType == toElementType)
  5829. return true;
  5830. }
  5831. if (from.isArray() || to.isArray() || ! from.sameElementShape(to))
  5832. return false;
  5833. if (from.isCoopMat() && to.isCoopMat())
  5834. return from.sameCoopMatBaseType(to);
  5835. return intermediate.canImplicitlyPromote(from.getBasicType(), to.getBasicType());
  5836. };
  5837. // Is 'to2' a better conversion than 'to1'?
  5838. // Ties should not be considered as better.
  5839. // Assumes 'convertible' already said true.
  5840. const auto better = [](const TType& from, const TType& to1, const TType& to2) -> bool {
  5841. // 1. exact match
  5842. if (from == to2)
  5843. return from != to1;
  5844. if (from == to1)
  5845. return false;
  5846. // 2. float -> double is better
  5847. if (from.getBasicType() == EbtFloat) {
  5848. if (to2.getBasicType() == EbtDouble && to1.getBasicType() != EbtDouble)
  5849. return true;
  5850. }
  5851. // 3. -> float is better than -> double
  5852. return to2.getBasicType() == EbtFloat && to1.getBasicType() == EbtDouble;
  5853. };
  5854. // for ambiguity reporting
  5855. bool tie = false;
  5856. // send to the generic selector
  5857. const TFunction* bestMatch = selectFunction(candidateList, call, convertible, better, tie);
  5858. if (bestMatch == nullptr)
  5859. error(loc, "no matching overloaded function found", call.getName().c_str(), "");
  5860. else if (tie)
  5861. error(loc, "ambiguous best function under implicit type conversion", call.getName().c_str(), "");
  5862. return bestMatch;
  5863. }
  5864. // "To determine whether the conversion for a single argument in one match
  5865. // is better than that for another match, the conversion is assigned of the
  5866. // three ranks ordered from best to worst:
  5867. // 1. Exact match: no conversion.
  5868. // 2. Promotion: integral or floating-point promotion.
  5869. // 3. Conversion: integral conversion, floating-point conversion,
  5870. // floating-integral conversion.
  5871. // A conversion C1 is better than a conversion C2 if the rank of C1 is
  5872. // better than the rank of C2."
  5873. const TFunction* TParseContext::findFunctionExplicitTypes(const TSourceLoc& loc, const TFunction& call, bool& builtIn)
  5874. {
  5875. // first, look for an exact match
  5876. TSymbol* symbol = symbolTable.find(call.getMangledName(), &builtIn);
  5877. if (symbol)
  5878. return symbol->getAsFunction();
  5879. // no exact match, use the generic selector, parameterized by the GLSL rules
  5880. // create list of candidates to send
  5881. TVector<const TFunction*> candidateList;
  5882. symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn);
  5883. // can 'from' convert to 'to'?
  5884. const auto convertible = [this,builtIn](const TType& from, const TType& to, TOperator, int) -> bool {
  5885. if (from == to)
  5886. return true;
  5887. if (from.coopMatParameterOK(to))
  5888. return true;
  5889. // Allow a sized array to be passed through an unsized array parameter, for coopMatLoad/Store functions
  5890. if (builtIn && from.isArray() && to.isUnsizedArray()) {
  5891. TType fromElementType(from, 0);
  5892. TType toElementType(to, 0);
  5893. if (fromElementType == toElementType)
  5894. return true;
  5895. }
  5896. if (from.isArray() || to.isArray() || ! from.sameElementShape(to))
  5897. return false;
  5898. if (from.isCoopMat() && to.isCoopMat())
  5899. return from.sameCoopMatBaseType(to);
  5900. return intermediate.canImplicitlyPromote(from.getBasicType(), to.getBasicType());
  5901. };
  5902. // Is 'to2' a better conversion than 'to1'?
  5903. // Ties should not be considered as better.
  5904. // Assumes 'convertible' already said true.
  5905. const auto better = [this](const TType& from, const TType& to1, const TType& to2) -> bool {
  5906. // 1. exact match
  5907. if (from == to2)
  5908. return from != to1;
  5909. if (from == to1)
  5910. return false;
  5911. // 2. Promotion (integral, floating-point) is better
  5912. TBasicType from_type = from.getBasicType();
  5913. TBasicType to1_type = to1.getBasicType();
  5914. TBasicType to2_type = to2.getBasicType();
  5915. bool isPromotion1 = (intermediate.isIntegralPromotion(from_type, to1_type) ||
  5916. intermediate.isFPPromotion(from_type, to1_type));
  5917. bool isPromotion2 = (intermediate.isIntegralPromotion(from_type, to2_type) ||
  5918. intermediate.isFPPromotion(from_type, to2_type));
  5919. if (isPromotion2)
  5920. return !isPromotion1;
  5921. if(isPromotion1)
  5922. return false;
  5923. // 3. Conversion (integral, floating-point , floating-integral)
  5924. bool isConversion1 = (intermediate.isIntegralConversion(from_type, to1_type) ||
  5925. intermediate.isFPConversion(from_type, to1_type) ||
  5926. intermediate.isFPIntegralConversion(from_type, to1_type));
  5927. bool isConversion2 = (intermediate.isIntegralConversion(from_type, to2_type) ||
  5928. intermediate.isFPConversion(from_type, to2_type) ||
  5929. intermediate.isFPIntegralConversion(from_type, to2_type));
  5930. return isConversion2 && !isConversion1;
  5931. };
  5932. // for ambiguity reporting
  5933. bool tie = false;
  5934. // send to the generic selector
  5935. const TFunction* bestMatch = selectFunction(candidateList, call, convertible, better, tie);
  5936. if (bestMatch == nullptr)
  5937. error(loc, "no matching overloaded function found", call.getName().c_str(), "");
  5938. else if (tie)
  5939. error(loc, "ambiguous best function under implicit type conversion", call.getName().c_str(), "");
  5940. return bestMatch;
  5941. }
  5942. // When a declaration includes a type, but not a variable name, it can be used
  5943. // to establish defaults.
  5944. void TParseContext::declareTypeDefaults(const TSourceLoc& loc, const TPublicType& publicType)
  5945. {
  5946. #ifndef GLSLANG_WEB
  5947. if (publicType.basicType == EbtAtomicUint && publicType.qualifier.hasBinding()) {
  5948. if (publicType.qualifier.layoutBinding >= (unsigned int)resources.maxAtomicCounterBindings) {
  5949. error(loc, "atomic_uint binding is too large", "binding", "");
  5950. return;
  5951. }
  5952. if (publicType.qualifier.hasOffset())
  5953. atomicUintOffsets[publicType.qualifier.layoutBinding] = publicType.qualifier.layoutOffset;
  5954. return;
  5955. }
  5956. if (publicType.arraySizes) {
  5957. error(loc, "expect an array name", "", "");
  5958. }
  5959. if (publicType.qualifier.hasLayout() && !publicType.qualifier.hasBufferReference())
  5960. warn(loc, "useless application of layout qualifier", "layout", "");
  5961. #endif
  5962. }
  5963. //
  5964. // Do everything necessary to handle a variable (non-block) declaration.
  5965. // Either redeclaring a variable, or making a new one, updating the symbol
  5966. // table, and all error checking.
  5967. //
  5968. // Returns a subtree node that computes an initializer, if needed.
  5969. // Returns nullptr if there is no code to execute for initialization.
  5970. //
  5971. // 'publicType' is the type part of the declaration (to the left)
  5972. // 'arraySizes' is the arrayness tagged on the identifier (to the right)
  5973. //
  5974. TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& identifier, const TPublicType& publicType,
  5975. TArraySizes* arraySizes, TIntermTyped* initializer)
  5976. {
  5977. // Make a fresh type that combines the characteristics from the individual
  5978. // identifier syntax and the declaration-type syntax.
  5979. TType type(publicType);
  5980. type.transferArraySizes(arraySizes);
  5981. type.copyArrayInnerSizes(publicType.arraySizes);
  5982. arrayOfArrayVersionCheck(loc, type.getArraySizes());
  5983. if (initializer) {
  5984. if (type.getBasicType() == EbtRayQuery) {
  5985. error(loc, "ray queries can only be initialized by using the rayQueryInitializeEXT intrinsic:", "=", identifier.c_str());
  5986. }
  5987. }
  5988. if (type.isCoopMat()) {
  5989. intermediate.setUseVulkanMemoryModel();
  5990. intermediate.setUseStorageBuffer();
  5991. if (!publicType.typeParameters || publicType.typeParameters->getNumDims() != 4) {
  5992. error(loc, "expected four type parameters", identifier.c_str(), "");
  5993. }
  5994. if (publicType.typeParameters) {
  5995. if (isTypeFloat(publicType.basicType) &&
  5996. publicType.typeParameters->getDimSize(0) != 16 &&
  5997. publicType.typeParameters->getDimSize(0) != 32 &&
  5998. publicType.typeParameters->getDimSize(0) != 64) {
  5999. error(loc, "expected 16, 32, or 64 bits for first type parameter", identifier.c_str(), "");
  6000. }
  6001. if (isTypeInt(publicType.basicType) &&
  6002. publicType.typeParameters->getDimSize(0) != 8 &&
  6003. publicType.typeParameters->getDimSize(0) != 32) {
  6004. error(loc, "expected 8 or 32 bits for first type parameter", identifier.c_str(), "");
  6005. }
  6006. }
  6007. } else {
  6008. if (publicType.typeParameters && publicType.typeParameters->getNumDims() != 0) {
  6009. error(loc, "unexpected type parameters", identifier.c_str(), "");
  6010. }
  6011. }
  6012. if (voidErrorCheck(loc, identifier, type.getBasicType()))
  6013. return nullptr;
  6014. if (initializer)
  6015. rValueErrorCheck(loc, "initializer", initializer);
  6016. else
  6017. nonInitConstCheck(loc, identifier, type);
  6018. samplerCheck(loc, type, identifier, initializer);
  6019. transparentOpaqueCheck(loc, type, identifier);
  6020. #ifndef GLSLANG_WEB
  6021. atomicUintCheck(loc, type, identifier);
  6022. accStructCheck(loc, type, identifier);
  6023. checkAndResizeMeshViewDim(loc, type, /*isBlockMember*/ false);
  6024. #endif
  6025. if (type.getQualifier().storage == EvqConst && type.containsReference()) {
  6026. error(loc, "variables with reference type can't have qualifier 'const'", "qualifier", "");
  6027. }
  6028. if (type.getQualifier().storage != EvqUniform && type.getQualifier().storage != EvqBuffer) {
  6029. if (type.contains16BitFloat())
  6030. requireFloat16Arithmetic(loc, "qualifier", "float16 types can only be in uniform block or buffer storage");
  6031. if (type.contains16BitInt())
  6032. requireInt16Arithmetic(loc, "qualifier", "(u)int16 types can only be in uniform block or buffer storage");
  6033. if (type.contains8BitInt())
  6034. requireInt8Arithmetic(loc, "qualifier", "(u)int8 types can only be in uniform block or buffer storage");
  6035. }
  6036. if (type.getQualifier().storage == EvqShared && type.containsCoopMat())
  6037. error(loc, "qualifier", "Cooperative matrix types must not be used in shared memory", "");
  6038. if (profile == EEsProfile) {
  6039. if (type.getQualifier().isPipeInput() && type.getBasicType() == EbtStruct) {
  6040. if (type.getQualifier().isArrayedIo(language)) {
  6041. TType perVertexType(type, 0);
  6042. if (perVertexType.containsArray() && perVertexType.containsBuiltIn() == false) {
  6043. error(loc, "A per vertex structure containing an array is not allowed as input in ES", type.getTypeName().c_str(), "");
  6044. }
  6045. }
  6046. else if (type.containsArray() && type.containsBuiltIn() == false) {
  6047. error(loc, "A structure containing an array is not allowed as input in ES", type.getTypeName().c_str(), "");
  6048. }
  6049. if (type.containsStructure())
  6050. error(loc, "A structure containing an struct is not allowed as input in ES", type.getTypeName().c_str(), "");
  6051. }
  6052. }
  6053. if (identifier != "gl_FragCoord" && (publicType.shaderQualifiers.originUpperLeft || publicType.shaderQualifiers.pixelCenterInteger))
  6054. error(loc, "can only apply origin_upper_left and pixel_center_origin to gl_FragCoord", "layout qualifier", "");
  6055. if (identifier != "gl_FragDepth" && publicType.shaderQualifiers.getDepth() != EldNone)
  6056. error(loc, "can only apply depth layout to gl_FragDepth", "layout qualifier", "");
  6057. // Check for redeclaration of built-ins and/or attempting to declare a reserved name
  6058. TSymbol* symbol = redeclareBuiltinVariable(loc, identifier, type.getQualifier(), publicType.shaderQualifiers);
  6059. if (symbol == nullptr)
  6060. reservedErrorCheck(loc, identifier);
  6061. inheritGlobalDefaults(type.getQualifier());
  6062. // Declare the variable
  6063. if (type.isArray()) {
  6064. // Check that implicit sizing is only where allowed.
  6065. arraySizesCheck(loc, type.getQualifier(), type.getArraySizes(), initializer, false);
  6066. if (! arrayQualifierError(loc, type.getQualifier()) && ! arrayError(loc, type))
  6067. declareArray(loc, identifier, type, symbol);
  6068. if (initializer) {
  6069. profileRequires(loc, ENoProfile, 120, E_GL_3DL_array_objects, "initializer");
  6070. profileRequires(loc, EEsProfile, 300, nullptr, "initializer");
  6071. }
  6072. } else {
  6073. // non-array case
  6074. if (symbol == nullptr)
  6075. symbol = declareNonArray(loc, identifier, type);
  6076. else if (type != symbol->getType())
  6077. error(loc, "cannot change the type of", "redeclaration", symbol->getName().c_str());
  6078. }
  6079. if (symbol == nullptr)
  6080. return nullptr;
  6081. // Deal with initializer
  6082. TIntermNode* initNode = nullptr;
  6083. if (symbol != nullptr && initializer) {
  6084. TVariable* variable = symbol->getAsVariable();
  6085. if (! variable) {
  6086. error(loc, "initializer requires a variable, not a member", identifier.c_str(), "");
  6087. return nullptr;
  6088. }
  6089. initNode = executeInitializer(loc, initializer, variable);
  6090. }
  6091. // look for errors in layout qualifier use
  6092. layoutObjectCheck(loc, *symbol);
  6093. // fix up
  6094. fixOffset(loc, *symbol);
  6095. return initNode;
  6096. }
  6097. // Pick up global defaults from the provide global defaults into dst.
  6098. void TParseContext::inheritGlobalDefaults(TQualifier& dst) const
  6099. {
  6100. #ifndef GLSLANG_WEB
  6101. if (dst.storage == EvqVaryingOut) {
  6102. if (! dst.hasStream() && language == EShLangGeometry)
  6103. dst.layoutStream = globalOutputDefaults.layoutStream;
  6104. if (! dst.hasXfbBuffer())
  6105. dst.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer;
  6106. }
  6107. #endif
  6108. }
  6109. //
  6110. // Make an internal-only variable whose name is for debug purposes only
  6111. // and won't be searched for. Callers will only use the return value to use
  6112. // the variable, not the name to look it up. It is okay if the name
  6113. // is the same as other names; there won't be any conflict.
  6114. //
  6115. TVariable* TParseContext::makeInternalVariable(const char* name, const TType& type) const
  6116. {
  6117. TString* nameString = NewPoolTString(name);
  6118. TVariable* variable = new TVariable(nameString, type);
  6119. symbolTable.makeInternalVariable(*variable);
  6120. return variable;
  6121. }
  6122. //
  6123. // Declare a non-array variable, the main point being there is no redeclaration
  6124. // for resizing allowed.
  6125. //
  6126. // Return the successfully declared variable.
  6127. //
  6128. TVariable* TParseContext::declareNonArray(const TSourceLoc& loc, const TString& identifier, const TType& type)
  6129. {
  6130. // make a new variable
  6131. TVariable* variable = new TVariable(&identifier, type);
  6132. #ifndef GLSLANG_WEB
  6133. ioArrayCheck(loc, type, identifier);
  6134. #endif
  6135. // add variable to symbol table
  6136. if (symbolTable.insert(*variable)) {
  6137. if (symbolTable.atGlobalLevel())
  6138. trackLinkage(*variable);
  6139. return variable;
  6140. }
  6141. error(loc, "redefinition", variable->getName().c_str(), "");
  6142. return nullptr;
  6143. }
  6144. //
  6145. // Handle all types of initializers from the grammar.
  6146. //
  6147. // Returning nullptr just means there is no code to execute to handle the
  6148. // initializer, which will, for example, be the case for constant initializers.
  6149. //
  6150. TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyped* initializer, TVariable* variable)
  6151. {
  6152. // A null initializer is an aggregate that hasn't had an op assigned yet
  6153. // (still EOpNull, no relation to nullInit), and has no children.
  6154. bool nullInit = initializer->getAsAggregate() && initializer->getAsAggregate()->getOp() == EOpNull &&
  6155. initializer->getAsAggregate()->getSequence().size() == 0;
  6156. //
  6157. // Identifier must be of type constant, a global, or a temporary, and
  6158. // starting at version 120, desktop allows uniforms to have initializers.
  6159. //
  6160. TStorageQualifier qualifier = variable->getType().getQualifier().storage;
  6161. if (! (qualifier == EvqTemporary || qualifier == EvqGlobal || qualifier == EvqConst ||
  6162. (qualifier == EvqUniform && !isEsProfile() && version >= 120))) {
  6163. if (qualifier == EvqShared) {
  6164. // GL_EXT_null_initializer allows this for shared, if it's a null initializer
  6165. if (nullInit) {
  6166. const char* feature = "initialization with shared qualifier";
  6167. profileRequires(loc, EEsProfile, 0, E_GL_EXT_null_initializer, feature);
  6168. profileRequires(loc, ~EEsProfile, 0, E_GL_EXT_null_initializer, feature);
  6169. } else {
  6170. error(loc, "initializer can only be a null initializer ('{}')", "shared", "");
  6171. }
  6172. } else {
  6173. error(loc, " cannot initialize this type of qualifier ",
  6174. variable->getType().getStorageQualifierString(), "");
  6175. return nullptr;
  6176. }
  6177. }
  6178. if (nullInit) {
  6179. // only some types can be null initialized
  6180. if (variable->getType().containsUnsizedArray()) {
  6181. error(loc, "null initializers can't size unsized arrays", "{}", "");
  6182. return nullptr;
  6183. }
  6184. if (variable->getType().containsOpaque()) {
  6185. error(loc, "null initializers can't be used on opaque values", "{}", "");
  6186. return nullptr;
  6187. }
  6188. variable->getWritableType().getQualifier().setNullInit();
  6189. return nullptr;
  6190. }
  6191. arrayObjectCheck(loc, variable->getType(), "array initializer");
  6192. //
  6193. // If the initializer was from braces { ... }, we convert the whole subtree to a
  6194. // constructor-style subtree, allowing the rest of the code to operate
  6195. // identically for both kinds of initializers.
  6196. //
  6197. // Type can't be deduced from the initializer list, so a skeletal type to
  6198. // follow has to be passed in. Constness and specialization-constness
  6199. // should be deduced bottom up, not dictated by the skeletal type.
  6200. //
  6201. TType skeletalType;
  6202. skeletalType.shallowCopy(variable->getType());
  6203. skeletalType.getQualifier().makeTemporary();
  6204. #ifndef GLSLANG_WEB
  6205. initializer = convertInitializerList(loc, skeletalType, initializer);
  6206. #endif
  6207. if (! initializer) {
  6208. // error recovery; don't leave const without constant values
  6209. if (qualifier == EvqConst)
  6210. variable->getWritableType().getQualifier().makeTemporary();
  6211. return nullptr;
  6212. }
  6213. // Fix outer arrayness if variable is unsized, getting size from the initializer
  6214. if (initializer->getType().isSizedArray() && variable->getType().isUnsizedArray())
  6215. variable->getWritableType().changeOuterArraySize(initializer->getType().getOuterArraySize());
  6216. // Inner arrayness can also get set by an initializer
  6217. if (initializer->getType().isArrayOfArrays() && variable->getType().isArrayOfArrays() &&
  6218. initializer->getType().getArraySizes()->getNumDims() ==
  6219. variable->getType().getArraySizes()->getNumDims()) {
  6220. // adopt unsized sizes from the initializer's sizes
  6221. for (int d = 1; d < variable->getType().getArraySizes()->getNumDims(); ++d) {
  6222. if (variable->getType().getArraySizes()->getDimSize(d) == UnsizedArraySize) {
  6223. variable->getWritableType().getArraySizes()->setDimSize(d,
  6224. initializer->getType().getArraySizes()->getDimSize(d));
  6225. }
  6226. }
  6227. }
  6228. // Uniforms require a compile-time constant initializer
  6229. if (qualifier == EvqUniform && ! initializer->getType().getQualifier().isFrontEndConstant()) {
  6230. error(loc, "uniform initializers must be constant", "=", "'%s'",
  6231. variable->getType().getCompleteString().c_str());
  6232. variable->getWritableType().getQualifier().makeTemporary();
  6233. return nullptr;
  6234. }
  6235. // Global consts require a constant initializer (specialization constant is okay)
  6236. if (qualifier == EvqConst && symbolTable.atGlobalLevel() && ! initializer->getType().getQualifier().isConstant()) {
  6237. error(loc, "global const initializers must be constant", "=", "'%s'",
  6238. variable->getType().getCompleteString().c_str());
  6239. variable->getWritableType().getQualifier().makeTemporary();
  6240. return nullptr;
  6241. }
  6242. // Const variables require a constant initializer, depending on version
  6243. if (qualifier == EvqConst) {
  6244. if (! initializer->getType().getQualifier().isConstant()) {
  6245. const char* initFeature = "non-constant initializer";
  6246. requireProfile(loc, ~EEsProfile, initFeature);
  6247. profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, initFeature);
  6248. variable->getWritableType().getQualifier().storage = EvqConstReadOnly;
  6249. qualifier = EvqConstReadOnly;
  6250. }
  6251. } else {
  6252. // Non-const global variables in ES need a const initializer.
  6253. //
  6254. // "In declarations of global variables with no storage qualifier or with a const
  6255. // qualifier any initializer must be a constant expression."
  6256. if (symbolTable.atGlobalLevel() && ! initializer->getType().getQualifier().isConstant()) {
  6257. const char* initFeature =
  6258. "non-constant global initializer (needs GL_EXT_shader_non_constant_global_initializers)";
  6259. if (isEsProfile()) {
  6260. if (relaxedErrors() && ! extensionTurnedOn(E_GL_EXT_shader_non_constant_global_initializers))
  6261. warn(loc, "not allowed in this version", initFeature, "");
  6262. else
  6263. profileRequires(loc, EEsProfile, 0, E_GL_EXT_shader_non_constant_global_initializers, initFeature);
  6264. }
  6265. }
  6266. }
  6267. if (qualifier == EvqConst || qualifier == EvqUniform) {
  6268. // Compile-time tagging of the variable with its constant value...
  6269. initializer = intermediate.addConversion(EOpAssign, variable->getType(), initializer);
  6270. if (! initializer || ! initializer->getType().getQualifier().isConstant() ||
  6271. variable->getType() != initializer->getType()) {
  6272. error(loc, "non-matching or non-convertible constant type for const initializer",
  6273. variable->getType().getStorageQualifierString(), "");
  6274. variable->getWritableType().getQualifier().makeTemporary();
  6275. return nullptr;
  6276. }
  6277. // We either have a folded constant in getAsConstantUnion, or we have to use
  6278. // the initializer's subtree in the AST to represent the computation of a
  6279. // specialization constant.
  6280. assert(initializer->getAsConstantUnion() || initializer->getType().getQualifier().isSpecConstant());
  6281. if (initializer->getAsConstantUnion())
  6282. variable->setConstArray(initializer->getAsConstantUnion()->getConstArray());
  6283. else {
  6284. // It's a specialization constant.
  6285. variable->getWritableType().getQualifier().makeSpecConstant();
  6286. // Keep the subtree that computes the specialization constant with the variable.
  6287. // Later, a symbol node will adopt the subtree from the variable.
  6288. variable->setConstSubtree(initializer);
  6289. }
  6290. } else {
  6291. // normal assigning of a value to a variable...
  6292. specializationCheck(loc, initializer->getType(), "initializer");
  6293. TIntermSymbol* intermSymbol = intermediate.addSymbol(*variable, loc);
  6294. TIntermTyped* initNode = intermediate.addAssign(EOpAssign, intermSymbol, initializer, loc);
  6295. if (! initNode)
  6296. assignError(loc, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
  6297. return initNode;
  6298. }
  6299. return nullptr;
  6300. }
  6301. //
  6302. // Reprocess any initializer-list (the "{ ... }" syntax) parts of the
  6303. // initializer.
  6304. //
  6305. // Need to hierarchically assign correct types and implicit
  6306. // conversions. Will do this mimicking the same process used for
  6307. // creating a constructor-style initializer, ensuring we get the
  6308. // same form. However, it has to in parallel walk the 'type'
  6309. // passed in, as type cannot be deduced from an initializer list.
  6310. //
  6311. TIntermTyped* TParseContext::convertInitializerList(const TSourceLoc& loc, const TType& type, TIntermTyped* initializer)
  6312. {
  6313. // Will operate recursively. Once a subtree is found that is constructor style,
  6314. // everything below it is already good: Only the "top part" of the initializer
  6315. // can be an initializer list, where "top part" can extend for several (or all) levels.
  6316. // see if we have bottomed out in the tree within the initializer-list part
  6317. TIntermAggregate* initList = initializer->getAsAggregate();
  6318. if (! initList || initList->getOp() != EOpNull)
  6319. return initializer;
  6320. // Of the initializer-list set of nodes, need to process bottom up,
  6321. // so recurse deep, then process on the way up.
  6322. // Go down the tree here...
  6323. if (type.isArray()) {
  6324. // The type's array might be unsized, which could be okay, so base sizes on the size of the aggregate.
  6325. // Later on, initializer execution code will deal with array size logic.
  6326. TType arrayType;
  6327. arrayType.shallowCopy(type); // sharing struct stuff is fine
  6328. arrayType.copyArraySizes(*type.getArraySizes()); // but get a fresh copy of the array information, to edit below
  6329. // edit array sizes to fill in unsized dimensions
  6330. arrayType.changeOuterArraySize((int)initList->getSequence().size());
  6331. TIntermTyped* firstInit = initList->getSequence()[0]->getAsTyped();
  6332. if (arrayType.isArrayOfArrays() && firstInit->getType().isArray() &&
  6333. arrayType.getArraySizes()->getNumDims() == firstInit->getType().getArraySizes()->getNumDims() + 1) {
  6334. for (int d = 1; d < arrayType.getArraySizes()->getNumDims(); ++d) {
  6335. if (arrayType.getArraySizes()->getDimSize(d) == UnsizedArraySize)
  6336. arrayType.getArraySizes()->setDimSize(d, firstInit->getType().getArraySizes()->getDimSize(d - 1));
  6337. }
  6338. }
  6339. TType elementType(arrayType, 0); // dereferenced type
  6340. for (size_t i = 0; i < initList->getSequence().size(); ++i) {
  6341. initList->getSequence()[i] = convertInitializerList(loc, elementType, initList->getSequence()[i]->getAsTyped());
  6342. if (initList->getSequence()[i] == nullptr)
  6343. return nullptr;
  6344. }
  6345. return addConstructor(loc, initList, arrayType);
  6346. } else if (type.isStruct()) {
  6347. if (type.getStruct()->size() != initList->getSequence().size()) {
  6348. error(loc, "wrong number of structure members", "initializer list", "");
  6349. return nullptr;
  6350. }
  6351. for (size_t i = 0; i < type.getStruct()->size(); ++i) {
  6352. initList->getSequence()[i] = convertInitializerList(loc, *(*type.getStruct())[i].type, initList->getSequence()[i]->getAsTyped());
  6353. if (initList->getSequence()[i] == nullptr)
  6354. return nullptr;
  6355. }
  6356. } else if (type.isMatrix()) {
  6357. if (type.getMatrixCols() != (int)initList->getSequence().size()) {
  6358. error(loc, "wrong number of matrix columns:", "initializer list", type.getCompleteString().c_str());
  6359. return nullptr;
  6360. }
  6361. TType vectorType(type, 0); // dereferenced type
  6362. for (int i = 0; i < type.getMatrixCols(); ++i) {
  6363. initList->getSequence()[i] = convertInitializerList(loc, vectorType, initList->getSequence()[i]->getAsTyped());
  6364. if (initList->getSequence()[i] == nullptr)
  6365. return nullptr;
  6366. }
  6367. } else if (type.isVector()) {
  6368. if (type.getVectorSize() != (int)initList->getSequence().size()) {
  6369. error(loc, "wrong vector size (or rows in a matrix column):", "initializer list", type.getCompleteString().c_str());
  6370. return nullptr;
  6371. }
  6372. TBasicType destType = type.getBasicType();
  6373. for (int i = 0; i < type.getVectorSize(); ++i) {
  6374. TBasicType initType = initList->getSequence()[i]->getAsTyped()->getBasicType();
  6375. if (destType != initType && !intermediate.canImplicitlyPromote(initType, destType)) {
  6376. error(loc, "type mismatch in initializer list", "initializer list", type.getCompleteString().c_str());
  6377. return nullptr;
  6378. }
  6379. }
  6380. } else {
  6381. error(loc, "unexpected initializer-list type:", "initializer list", type.getCompleteString().c_str());
  6382. return nullptr;
  6383. }
  6384. // Now that the subtree is processed, process this node as if the
  6385. // initializer list is a set of arguments to a constructor.
  6386. TIntermNode* emulatedConstructorArguments;
  6387. if (initList->getSequence().size() == 1)
  6388. emulatedConstructorArguments = initList->getSequence()[0];
  6389. else
  6390. emulatedConstructorArguments = initList;
  6391. return addConstructor(loc, emulatedConstructorArguments, type);
  6392. }
  6393. //
  6394. // Test for the correctness of the parameters passed to various constructor functions
  6395. // and also convert them to the right data type, if allowed and required.
  6396. //
  6397. // 'node' is what to construct from.
  6398. // 'type' is what type to construct.
  6399. //
  6400. // Returns nullptr for an error or the constructed node (aggregate or typed) for no error.
  6401. //
  6402. TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode* node, const TType& type)
  6403. {
  6404. if (node == nullptr || node->getAsTyped() == nullptr)
  6405. return nullptr;
  6406. rValueErrorCheck(loc, "constructor", node->getAsTyped());
  6407. TIntermAggregate* aggrNode = node->getAsAggregate();
  6408. TOperator op = intermediate.mapTypeToConstructorOp(type);
  6409. // Combined texture-sampler constructors are completely semantic checked
  6410. // in constructorTextureSamplerError()
  6411. if (op == EOpConstructTextureSampler) {
  6412. if (aggrNode->getSequence()[1]->getAsTyped()->getType().getSampler().shadow) {
  6413. // Transfer depth into the texture (SPIR-V image) type, as a hint
  6414. // for tools to know this texture/image is a depth image.
  6415. aggrNode->getSequence()[0]->getAsTyped()->getWritableType().getSampler().shadow = true;
  6416. }
  6417. return intermediate.setAggregateOperator(aggrNode, op, type, loc);
  6418. }
  6419. TTypeList::const_iterator memberTypes;
  6420. if (op == EOpConstructStruct)
  6421. memberTypes = type.getStruct()->begin();
  6422. TType elementType;
  6423. if (type.isArray()) {
  6424. TType dereferenced(type, 0);
  6425. elementType.shallowCopy(dereferenced);
  6426. } else
  6427. elementType.shallowCopy(type);
  6428. bool singleArg;
  6429. if (aggrNode) {
  6430. if (aggrNode->getOp() != EOpNull)
  6431. singleArg = true;
  6432. else
  6433. singleArg = false;
  6434. } else
  6435. singleArg = true;
  6436. TIntermTyped *newNode;
  6437. if (singleArg) {
  6438. // If structure constructor or array constructor is being called
  6439. // for only one parameter inside the structure, we need to call constructAggregate function once.
  6440. if (type.isArray())
  6441. newNode = constructAggregate(node, elementType, 1, node->getLoc());
  6442. else if (op == EOpConstructStruct)
  6443. newNode = constructAggregate(node, *(*memberTypes).type, 1, node->getLoc());
  6444. else
  6445. newNode = constructBuiltIn(type, op, node->getAsTyped(), node->getLoc(), false);
  6446. if (newNode && (type.isArray() || op == EOpConstructStruct))
  6447. newNode = intermediate.setAggregateOperator(newNode, EOpConstructStruct, type, loc);
  6448. return newNode;
  6449. }
  6450. //
  6451. // Handle list of arguments.
  6452. //
  6453. TIntermSequence &sequenceVector = aggrNode->getSequence(); // Stores the information about the parameter to the constructor
  6454. // if the structure constructor contains more than one parameter, then construct
  6455. // each parameter
  6456. int paramCount = 0; // keeps track of the constructor parameter number being checked
  6457. // for each parameter to the constructor call, check to see if the right type is passed or convert them
  6458. // to the right type if possible (and allowed).
  6459. // for structure constructors, just check if the right type is passed, no conversion is allowed.
  6460. for (TIntermSequence::iterator p = sequenceVector.begin();
  6461. p != sequenceVector.end(); p++, paramCount++) {
  6462. if (type.isArray())
  6463. newNode = constructAggregate(*p, elementType, paramCount+1, node->getLoc());
  6464. else if (op == EOpConstructStruct)
  6465. newNode = constructAggregate(*p, *(memberTypes[paramCount]).type, paramCount+1, node->getLoc());
  6466. else
  6467. newNode = constructBuiltIn(type, op, (*p)->getAsTyped(), node->getLoc(), true);
  6468. if (newNode)
  6469. *p = newNode;
  6470. else
  6471. return nullptr;
  6472. }
  6473. return intermediate.setAggregateOperator(aggrNode, op, type, loc);
  6474. }
  6475. // Function for constructor implementation. Calls addUnaryMath with appropriate EOp value
  6476. // for the parameter to the constructor (passed to this function). Essentially, it converts
  6477. // the parameter types correctly. If a constructor expects an int (like ivec2) and is passed a
  6478. // float, then float is converted to int.
  6479. //
  6480. // Returns nullptr for an error or the constructed node.
  6481. //
  6482. TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, TIntermTyped* node, const TSourceLoc& loc,
  6483. bool subset)
  6484. {
  6485. // If we are changing a matrix in both domain of basic type and to a non matrix,
  6486. // do the shape change first (by default, below, basic type is changed before shape).
  6487. // This avoids requesting a matrix of a new type that is going to be discarded anyway.
  6488. // TODO: This could be generalized to more type combinations, but that would require
  6489. // more extensive testing and full algorithm rework. For now, the need to do two changes makes
  6490. // the recursive call work, and avoids the most egregious case of creating integer matrices.
  6491. if (node->getType().isMatrix() && (type.isScalar() || type.isVector()) &&
  6492. type.isFloatingDomain() != node->getType().isFloatingDomain()) {
  6493. TType transitionType(node->getBasicType(), glslang::EvqTemporary, type.getVectorSize(), 0, 0, node->isVector());
  6494. TOperator transitionOp = intermediate.mapTypeToConstructorOp(transitionType);
  6495. node = constructBuiltIn(transitionType, transitionOp, node, loc, false);
  6496. }
  6497. TIntermTyped* newNode;
  6498. TOperator basicOp;
  6499. //
  6500. // First, convert types as needed.
  6501. //
  6502. switch (op) {
  6503. case EOpConstructVec2:
  6504. case EOpConstructVec3:
  6505. case EOpConstructVec4:
  6506. case EOpConstructMat2x2:
  6507. case EOpConstructMat2x3:
  6508. case EOpConstructMat2x4:
  6509. case EOpConstructMat3x2:
  6510. case EOpConstructMat3x3:
  6511. case EOpConstructMat3x4:
  6512. case EOpConstructMat4x2:
  6513. case EOpConstructMat4x3:
  6514. case EOpConstructMat4x4:
  6515. case EOpConstructFloat:
  6516. basicOp = EOpConstructFloat;
  6517. break;
  6518. case EOpConstructIVec2:
  6519. case EOpConstructIVec3:
  6520. case EOpConstructIVec4:
  6521. case EOpConstructInt:
  6522. basicOp = EOpConstructInt;
  6523. break;
  6524. case EOpConstructUVec2:
  6525. if (node->getType().getBasicType() == EbtReference) {
  6526. requireExtensions(loc, 1, &E_GL_EXT_buffer_reference_uvec2, "reference conversion to uvec2");
  6527. TIntermTyped* newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConvPtrToUvec2, true, node,
  6528. type);
  6529. return newNode;
  6530. }
  6531. case EOpConstructUVec3:
  6532. case EOpConstructUVec4:
  6533. case EOpConstructUint:
  6534. basicOp = EOpConstructUint;
  6535. break;
  6536. case EOpConstructBVec2:
  6537. case EOpConstructBVec3:
  6538. case EOpConstructBVec4:
  6539. case EOpConstructBool:
  6540. basicOp = EOpConstructBool;
  6541. break;
  6542. #ifndef GLSLANG_WEB
  6543. case EOpConstructDVec2:
  6544. case EOpConstructDVec3:
  6545. case EOpConstructDVec4:
  6546. case EOpConstructDMat2x2:
  6547. case EOpConstructDMat2x3:
  6548. case EOpConstructDMat2x4:
  6549. case EOpConstructDMat3x2:
  6550. case EOpConstructDMat3x3:
  6551. case EOpConstructDMat3x4:
  6552. case EOpConstructDMat4x2:
  6553. case EOpConstructDMat4x3:
  6554. case EOpConstructDMat4x4:
  6555. case EOpConstructDouble:
  6556. basicOp = EOpConstructDouble;
  6557. break;
  6558. case EOpConstructF16Vec2:
  6559. case EOpConstructF16Vec3:
  6560. case EOpConstructF16Vec4:
  6561. case EOpConstructF16Mat2x2:
  6562. case EOpConstructF16Mat2x3:
  6563. case EOpConstructF16Mat2x4:
  6564. case EOpConstructF16Mat3x2:
  6565. case EOpConstructF16Mat3x3:
  6566. case EOpConstructF16Mat3x4:
  6567. case EOpConstructF16Mat4x2:
  6568. case EOpConstructF16Mat4x3:
  6569. case EOpConstructF16Mat4x4:
  6570. case EOpConstructFloat16:
  6571. basicOp = EOpConstructFloat16;
  6572. // 8/16-bit storage extensions don't support constructing composites of 8/16-bit types,
  6573. // so construct a 32-bit type and convert
  6574. if (!intermediate.getArithemeticFloat16Enabled()) {
  6575. TType tempType(EbtFloat, EvqTemporary, type.getVectorSize());
  6576. newNode = node;
  6577. if (tempType != newNode->getType()) {
  6578. TOperator aggregateOp;
  6579. if (op == EOpConstructFloat16)
  6580. aggregateOp = EOpConstructFloat;
  6581. else
  6582. aggregateOp = (TOperator)(EOpConstructVec2 + op - EOpConstructF16Vec2);
  6583. newNode = intermediate.setAggregateOperator(newNode, aggregateOp, tempType, node->getLoc());
  6584. }
  6585. newNode = intermediate.addConversion(EbtFloat16, newNode);
  6586. return newNode;
  6587. }
  6588. break;
  6589. case EOpConstructI8Vec2:
  6590. case EOpConstructI8Vec3:
  6591. case EOpConstructI8Vec4:
  6592. case EOpConstructInt8:
  6593. basicOp = EOpConstructInt8;
  6594. // 8/16-bit storage extensions don't support constructing composites of 8/16-bit types,
  6595. // so construct a 32-bit type and convert
  6596. if (!intermediate.getArithemeticInt8Enabled()) {
  6597. TType tempType(EbtInt, EvqTemporary, type.getVectorSize());
  6598. newNode = node;
  6599. if (tempType != newNode->getType()) {
  6600. TOperator aggregateOp;
  6601. if (op == EOpConstructInt8)
  6602. aggregateOp = EOpConstructInt;
  6603. else
  6604. aggregateOp = (TOperator)(EOpConstructIVec2 + op - EOpConstructI8Vec2);
  6605. newNode = intermediate.setAggregateOperator(newNode, aggregateOp, tempType, node->getLoc());
  6606. }
  6607. newNode = intermediate.addConversion(EbtInt8, newNode);
  6608. return newNode;
  6609. }
  6610. break;
  6611. case EOpConstructU8Vec2:
  6612. case EOpConstructU8Vec3:
  6613. case EOpConstructU8Vec4:
  6614. case EOpConstructUint8:
  6615. basicOp = EOpConstructUint8;
  6616. // 8/16-bit storage extensions don't support constructing composites of 8/16-bit types,
  6617. // so construct a 32-bit type and convert
  6618. if (!intermediate.getArithemeticInt8Enabled()) {
  6619. TType tempType(EbtUint, EvqTemporary, type.getVectorSize());
  6620. newNode = node;
  6621. if (tempType != newNode->getType()) {
  6622. TOperator aggregateOp;
  6623. if (op == EOpConstructUint8)
  6624. aggregateOp = EOpConstructUint;
  6625. else
  6626. aggregateOp = (TOperator)(EOpConstructUVec2 + op - EOpConstructU8Vec2);
  6627. newNode = intermediate.setAggregateOperator(newNode, aggregateOp, tempType, node->getLoc());
  6628. }
  6629. newNode = intermediate.addConversion(EbtUint8, newNode);
  6630. return newNode;
  6631. }
  6632. break;
  6633. case EOpConstructI16Vec2:
  6634. case EOpConstructI16Vec3:
  6635. case EOpConstructI16Vec4:
  6636. case EOpConstructInt16:
  6637. basicOp = EOpConstructInt16;
  6638. // 8/16-bit storage extensions don't support constructing composites of 8/16-bit types,
  6639. // so construct a 32-bit type and convert
  6640. if (!intermediate.getArithemeticInt16Enabled()) {
  6641. TType tempType(EbtInt, EvqTemporary, type.getVectorSize());
  6642. newNode = node;
  6643. if (tempType != newNode->getType()) {
  6644. TOperator aggregateOp;
  6645. if (op == EOpConstructInt16)
  6646. aggregateOp = EOpConstructInt;
  6647. else
  6648. aggregateOp = (TOperator)(EOpConstructIVec2 + op - EOpConstructI16Vec2);
  6649. newNode = intermediate.setAggregateOperator(newNode, aggregateOp, tempType, node->getLoc());
  6650. }
  6651. newNode = intermediate.addConversion(EbtInt16, newNode);
  6652. return newNode;
  6653. }
  6654. break;
  6655. case EOpConstructU16Vec2:
  6656. case EOpConstructU16Vec3:
  6657. case EOpConstructU16Vec4:
  6658. case EOpConstructUint16:
  6659. basicOp = EOpConstructUint16;
  6660. // 8/16-bit storage extensions don't support constructing composites of 8/16-bit types,
  6661. // so construct a 32-bit type and convert
  6662. if (!intermediate.getArithemeticInt16Enabled()) {
  6663. TType tempType(EbtUint, EvqTemporary, type.getVectorSize());
  6664. newNode = node;
  6665. if (tempType != newNode->getType()) {
  6666. TOperator aggregateOp;
  6667. if (op == EOpConstructUint16)
  6668. aggregateOp = EOpConstructUint;
  6669. else
  6670. aggregateOp = (TOperator)(EOpConstructUVec2 + op - EOpConstructU16Vec2);
  6671. newNode = intermediate.setAggregateOperator(newNode, aggregateOp, tempType, node->getLoc());
  6672. }
  6673. newNode = intermediate.addConversion(EbtUint16, newNode);
  6674. return newNode;
  6675. }
  6676. break;
  6677. case EOpConstructI64Vec2:
  6678. case EOpConstructI64Vec3:
  6679. case EOpConstructI64Vec4:
  6680. case EOpConstructInt64:
  6681. basicOp = EOpConstructInt64;
  6682. break;
  6683. case EOpConstructUint64:
  6684. if (type.isScalar() && node->getType().isReference()) {
  6685. TIntermTyped* newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConvPtrToUint64, true, node, type);
  6686. return newNode;
  6687. }
  6688. // fall through
  6689. case EOpConstructU64Vec2:
  6690. case EOpConstructU64Vec3:
  6691. case EOpConstructU64Vec4:
  6692. basicOp = EOpConstructUint64;
  6693. break;
  6694. case EOpConstructNonuniform:
  6695. // Make a nonuniform copy of node
  6696. newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpCopyObject, true, node, type);
  6697. return newNode;
  6698. case EOpConstructReference:
  6699. // construct reference from reference
  6700. if (node->getType().isReference()) {
  6701. newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConstructReference, true, node, type);
  6702. return newNode;
  6703. // construct reference from uint64
  6704. } else if (node->getType().isScalar() && node->getType().getBasicType() == EbtUint64) {
  6705. TIntermTyped* newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConvUint64ToPtr, true, node,
  6706. type);
  6707. return newNode;
  6708. // construct reference from uvec2
  6709. } else if (node->getType().isVector() && node->getType().getBasicType() == EbtUint &&
  6710. node->getVectorSize() == 2) {
  6711. requireExtensions(loc, 1, &E_GL_EXT_buffer_reference_uvec2, "uvec2 conversion to reference");
  6712. TIntermTyped* newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConvUvec2ToPtr, true, node,
  6713. type);
  6714. return newNode;
  6715. } else {
  6716. return nullptr;
  6717. }
  6718. case EOpConstructCooperativeMatrix:
  6719. if (!node->getType().isCoopMat()) {
  6720. if (type.getBasicType() != node->getType().getBasicType()) {
  6721. node = intermediate.addConversion(type.getBasicType(), node);
  6722. if (node == nullptr)
  6723. return nullptr;
  6724. }
  6725. node = intermediate.setAggregateOperator(node, EOpConstructCooperativeMatrix, type, node->getLoc());
  6726. } else {
  6727. TOperator op = EOpNull;
  6728. switch (type.getBasicType()) {
  6729. default:
  6730. assert(0);
  6731. break;
  6732. case EbtInt:
  6733. switch (node->getType().getBasicType()) {
  6734. case EbtFloat: op = EOpConvFloatToInt; break;
  6735. case EbtFloat16: op = EOpConvFloat16ToInt; break;
  6736. case EbtUint8: op = EOpConvUint8ToInt; break;
  6737. case EbtInt8: op = EOpConvInt8ToInt; break;
  6738. case EbtUint: op = EOpConvUintToInt; break;
  6739. default: assert(0);
  6740. }
  6741. break;
  6742. case EbtUint:
  6743. switch (node->getType().getBasicType()) {
  6744. case EbtFloat: op = EOpConvFloatToUint; break;
  6745. case EbtFloat16: op = EOpConvFloat16ToUint; break;
  6746. case EbtUint8: op = EOpConvUint8ToUint; break;
  6747. case EbtInt8: op = EOpConvInt8ToUint; break;
  6748. case EbtInt: op = EOpConvIntToUint; break;
  6749. case EbtUint: op = EOpConvUintToInt8; break;
  6750. default: assert(0);
  6751. }
  6752. break;
  6753. case EbtInt8:
  6754. switch (node->getType().getBasicType()) {
  6755. case EbtFloat: op = EOpConvFloatToInt8; break;
  6756. case EbtFloat16: op = EOpConvFloat16ToInt8; break;
  6757. case EbtUint8: op = EOpConvUint8ToInt8; break;
  6758. case EbtInt: op = EOpConvIntToInt8; break;
  6759. case EbtUint: op = EOpConvUintToInt8; break;
  6760. default: assert(0);
  6761. }
  6762. break;
  6763. case EbtUint8:
  6764. switch (node->getType().getBasicType()) {
  6765. case EbtFloat: op = EOpConvFloatToUint8; break;
  6766. case EbtFloat16: op = EOpConvFloat16ToUint8; break;
  6767. case EbtInt8: op = EOpConvInt8ToUint8; break;
  6768. case EbtInt: op = EOpConvIntToUint8; break;
  6769. case EbtUint: op = EOpConvUintToUint8; break;
  6770. default: assert(0);
  6771. }
  6772. break;
  6773. case EbtFloat:
  6774. switch (node->getType().getBasicType()) {
  6775. case EbtFloat16: op = EOpConvFloat16ToFloat; break;
  6776. case EbtInt8: op = EOpConvInt8ToFloat; break;
  6777. case EbtUint8: op = EOpConvUint8ToFloat; break;
  6778. case EbtInt: op = EOpConvIntToFloat; break;
  6779. case EbtUint: op = EOpConvUintToFloat; break;
  6780. default: assert(0);
  6781. }
  6782. break;
  6783. case EbtFloat16:
  6784. switch (node->getType().getBasicType()) {
  6785. case EbtFloat: op = EOpConvFloatToFloat16; break;
  6786. case EbtInt8: op = EOpConvInt8ToFloat16; break;
  6787. case EbtUint8: op = EOpConvUint8ToFloat16; break;
  6788. case EbtInt: op = EOpConvIntToFloat16; break;
  6789. case EbtUint: op = EOpConvUintToFloat16; break;
  6790. default: assert(0);
  6791. }
  6792. break;
  6793. }
  6794. node = intermediate.addUnaryNode(op, node, node->getLoc(), type);
  6795. // If it's a (non-specialization) constant, it must be folded.
  6796. if (node->getAsUnaryNode()->getOperand()->getAsConstantUnion())
  6797. return node->getAsUnaryNode()->getOperand()->getAsConstantUnion()->fold(op, node->getType());
  6798. }
  6799. return node;
  6800. case EOpConstructAccStruct:
  6801. if ((node->getType().isScalar() && node->getType().getBasicType() == EbtUint64)) {
  6802. // construct acceleration structure from uint64
  6803. requireExtensions(loc, 1, &E_GL_EXT_ray_tracing, "uint64_t conversion to acclerationStructureEXT");
  6804. return intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConvUint64ToAccStruct, true, node,
  6805. type);
  6806. } else if (node->getType().isVector() && node->getType().getBasicType() == EbtUint && node->getVectorSize() == 2) {
  6807. // construct acceleration structure from uint64
  6808. requireExtensions(loc, 1, &E_GL_EXT_ray_tracing, "uvec2 conversion to accelerationStructureEXT");
  6809. return intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConvUvec2ToAccStruct, true, node,
  6810. type);
  6811. } else
  6812. return nullptr;
  6813. #endif // GLSLANG_WEB
  6814. default:
  6815. error(loc, "unsupported construction", "", "");
  6816. return nullptr;
  6817. }
  6818. newNode = intermediate.addUnaryMath(basicOp, node, node->getLoc());
  6819. if (newNode == nullptr) {
  6820. error(loc, "can't convert", "constructor", "");
  6821. return nullptr;
  6822. }
  6823. //
  6824. // Now, if there still isn't an operation to do the construction, and we need one, add one.
  6825. //
  6826. // Otherwise, skip out early.
  6827. if (subset || (newNode != node && newNode->getType() == type))
  6828. return newNode;
  6829. // setAggregateOperator will insert a new node for the constructor, as needed.
  6830. return intermediate.setAggregateOperator(newNode, op, type, loc);
  6831. }
  6832. // This function tests for the type of the parameters to the structure or array constructor. Raises
  6833. // an error message if the expected type does not match the parameter passed to the constructor.
  6834. //
  6835. // Returns nullptr for an error or the input node itself if the expected and the given parameter types match.
  6836. //
  6837. TIntermTyped* TParseContext::constructAggregate(TIntermNode* node, const TType& type, int paramCount, const TSourceLoc& loc)
  6838. {
  6839. TIntermTyped* converted = intermediate.addConversion(EOpConstructStruct, type, node->getAsTyped());
  6840. if (! converted || converted->getType() != type) {
  6841. error(loc, "", "constructor", "cannot convert parameter %d from '%s' to '%s'", paramCount,
  6842. node->getAsTyped()->getType().getCompleteString().c_str(), type.getCompleteString().c_str());
  6843. return nullptr;
  6844. }
  6845. return converted;
  6846. }
  6847. // If a memory qualifier is present in 'to', also make it present in 'from'.
  6848. void TParseContext::inheritMemoryQualifiers(const TQualifier& from, TQualifier& to)
  6849. {
  6850. #ifndef GLSLANG_WEB
  6851. if (from.isReadOnly())
  6852. to.readonly = from.readonly;
  6853. if (from.isWriteOnly())
  6854. to.writeonly = from.writeonly;
  6855. if (from.coherent)
  6856. to.coherent = from.coherent;
  6857. if (from.volatil)
  6858. to.volatil = from.volatil;
  6859. if (from.restrict)
  6860. to.restrict = from.restrict;
  6861. #endif
  6862. }
  6863. //
  6864. // Do everything needed to add an interface block.
  6865. //
  6866. void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, const TString* instanceName,
  6867. TArraySizes* arraySizes)
  6868. {
  6869. blockStageIoCheck(loc, currentBlockQualifier);
  6870. blockQualifierCheck(loc, currentBlockQualifier, instanceName != nullptr);
  6871. if (arraySizes != nullptr) {
  6872. arraySizesCheck(loc, currentBlockQualifier, arraySizes, nullptr, false);
  6873. arrayOfArrayVersionCheck(loc, arraySizes);
  6874. if (arraySizes->getNumDims() > 1)
  6875. requireProfile(loc, ~EEsProfile, "array-of-array of block");
  6876. }
  6877. // Inherit and check member storage qualifiers WRT to the block-level qualifier.
  6878. for (unsigned int member = 0; member < typeList.size(); ++member) {
  6879. TType& memberType = *typeList[member].type;
  6880. TQualifier& memberQualifier = memberType.getQualifier();
  6881. const TSourceLoc& memberLoc = typeList[member].loc;
  6882. if (memberQualifier.storage != EvqTemporary && memberQualifier.storage != EvqGlobal && memberQualifier.storage != currentBlockQualifier.storage)
  6883. error(memberLoc, "member storage qualifier cannot contradict block storage qualifier", memberType.getFieldName().c_str(), "");
  6884. memberQualifier.storage = currentBlockQualifier.storage;
  6885. globalQualifierFixCheck(memberLoc, memberQualifier);
  6886. #ifndef GLSLANG_WEB
  6887. inheritMemoryQualifiers(currentBlockQualifier, memberQualifier);
  6888. if (currentBlockQualifier.perPrimitiveNV)
  6889. memberQualifier.perPrimitiveNV = currentBlockQualifier.perPrimitiveNV;
  6890. if (currentBlockQualifier.perViewNV)
  6891. memberQualifier.perViewNV = currentBlockQualifier.perViewNV;
  6892. if (currentBlockQualifier.perTaskNV)
  6893. memberQualifier.perTaskNV = currentBlockQualifier.perTaskNV;
  6894. #endif
  6895. if ((currentBlockQualifier.storage == EvqUniform || currentBlockQualifier.storage == EvqBuffer) && (memberQualifier.isInterpolation() || memberQualifier.isAuxiliary()))
  6896. error(memberLoc, "member of uniform or buffer block cannot have an auxiliary or interpolation qualifier", memberType.getFieldName().c_str(), "");
  6897. if (memberType.isArray())
  6898. arraySizesCheck(memberLoc, currentBlockQualifier, memberType.getArraySizes(), nullptr, member == typeList.size() - 1);
  6899. if (memberQualifier.hasOffset()) {
  6900. if (spvVersion.spv == 0) {
  6901. profileRequires(memberLoc, ~EEsProfile, 440, E_GL_ARB_enhanced_layouts, "\"offset\" on block member");
  6902. profileRequires(memberLoc, EEsProfile, 300, E_GL_ARB_enhanced_layouts, "\"offset\" on block member");
  6903. }
  6904. }
  6905. if (memberType.containsOpaque())
  6906. error(memberLoc, "member of block cannot be or contain a sampler, image, or atomic_uint type", typeList[member].type->getFieldName().c_str(), "");
  6907. if (memberType.containsCoopMat())
  6908. error(memberLoc, "member of block cannot be or contain a cooperative matrix type", typeList[member].type->getFieldName().c_str(), "");
  6909. }
  6910. // This might be a redeclaration of a built-in block. If so, redeclareBuiltinBlock() will
  6911. // do all the rest.
  6912. if (! symbolTable.atBuiltInLevel() && builtInName(*blockName)) {
  6913. redeclareBuiltinBlock(loc, typeList, *blockName, instanceName, arraySizes);
  6914. return;
  6915. }
  6916. // Not a redeclaration of a built-in; check that all names are user names.
  6917. reservedErrorCheck(loc, *blockName);
  6918. if (instanceName)
  6919. reservedErrorCheck(loc, *instanceName);
  6920. for (unsigned int member = 0; member < typeList.size(); ++member)
  6921. reservedErrorCheck(typeList[member].loc, typeList[member].type->getFieldName());
  6922. // Make default block qualification, and adjust the member qualifications
  6923. TQualifier defaultQualification;
  6924. switch (currentBlockQualifier.storage) {
  6925. case EvqUniform: defaultQualification = globalUniformDefaults; break;
  6926. case EvqBuffer: defaultQualification = globalBufferDefaults; break;
  6927. case EvqVaryingIn: defaultQualification = globalInputDefaults; break;
  6928. case EvqVaryingOut: defaultQualification = globalOutputDefaults; break;
  6929. case EvqShared: defaultQualification = globalSharedDefaults; break;
  6930. default: defaultQualification.clear(); break;
  6931. }
  6932. // Special case for "push_constant uniform", which has a default of std430,
  6933. // contrary to normal uniform defaults, and can't have a default tracked for it.
  6934. if ((currentBlockQualifier.isPushConstant() && !currentBlockQualifier.hasPacking()) ||
  6935. (currentBlockQualifier.isShaderRecord() && !currentBlockQualifier.hasPacking()))
  6936. currentBlockQualifier.layoutPacking = ElpStd430;
  6937. // Special case for "taskNV in/out", which has a default of std430,
  6938. if (currentBlockQualifier.isTaskMemory() && !currentBlockQualifier.hasPacking())
  6939. currentBlockQualifier.layoutPacking = ElpStd430;
  6940. // fix and check for member layout qualifiers
  6941. mergeObjectLayoutQualifiers(defaultQualification, currentBlockQualifier, true);
  6942. // "The align qualifier can only be used on blocks or block members, and only for blocks declared with std140 or std430 layouts."
  6943. if (currentBlockQualifier.hasAlign()) {
  6944. if (defaultQualification.layoutPacking != ElpStd140 &&
  6945. defaultQualification.layoutPacking != ElpStd430 &&
  6946. defaultQualification.layoutPacking != ElpScalar) {
  6947. error(loc, "can only be used with std140, std430, or scalar layout packing", "align", "");
  6948. defaultQualification.layoutAlign = -1;
  6949. }
  6950. }
  6951. bool memberWithLocation = false;
  6952. bool memberWithoutLocation = false;
  6953. bool memberWithPerViewQualifier = false;
  6954. for (unsigned int member = 0; member < typeList.size(); ++member) {
  6955. TQualifier& memberQualifier = typeList[member].type->getQualifier();
  6956. const TSourceLoc& memberLoc = typeList[member].loc;
  6957. #ifndef GLSLANG_WEB
  6958. if (memberQualifier.hasStream()) {
  6959. if (defaultQualification.layoutStream != memberQualifier.layoutStream)
  6960. error(memberLoc, "member cannot contradict block", "stream", "");
  6961. }
  6962. // "This includes a block's inheritance of the
  6963. // current global default buffer, a block member's inheritance of the block's
  6964. // buffer, and the requirement that any *xfb_buffer* declared on a block
  6965. // member must match the buffer inherited from the block."
  6966. if (memberQualifier.hasXfbBuffer()) {
  6967. if (defaultQualification.layoutXfbBuffer != memberQualifier.layoutXfbBuffer)
  6968. error(memberLoc, "member cannot contradict block (or what block inherited from global)", "xfb_buffer", "");
  6969. }
  6970. #endif
  6971. if (memberQualifier.hasPacking())
  6972. error(memberLoc, "member of block cannot have a packing layout qualifier", typeList[member].type->getFieldName().c_str(), "");
  6973. if (memberQualifier.hasLocation()) {
  6974. const char* feature = "location on block member";
  6975. switch (currentBlockQualifier.storage) {
  6976. #ifndef GLSLANG_WEB
  6977. case EvqVaryingIn:
  6978. case EvqVaryingOut:
  6979. requireProfile(memberLoc, ECoreProfile | ECompatibilityProfile | EEsProfile, feature);
  6980. profileRequires(memberLoc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, feature);
  6981. profileRequires(memberLoc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, feature);
  6982. memberWithLocation = true;
  6983. break;
  6984. #endif
  6985. default:
  6986. error(memberLoc, "can only use in an in/out block", feature, "");
  6987. break;
  6988. }
  6989. } else
  6990. memberWithoutLocation = true;
  6991. // "The offset qualifier can only be used on block members of blocks declared with std140 or std430 layouts."
  6992. // "The align qualifier can only be used on blocks or block members, and only for blocks declared with std140 or std430 layouts."
  6993. if (memberQualifier.hasAlign() || memberQualifier.hasOffset()) {
  6994. if (defaultQualification.layoutPacking != ElpStd140 &&
  6995. defaultQualification.layoutPacking != ElpStd430 &&
  6996. defaultQualification.layoutPacking != ElpScalar)
  6997. error(memberLoc, "can only be used with std140, std430, or scalar layout packing", "offset/align", "");
  6998. }
  6999. if (memberQualifier.isPerView()) {
  7000. memberWithPerViewQualifier = true;
  7001. }
  7002. TQualifier newMemberQualification = defaultQualification;
  7003. mergeQualifiers(memberLoc, newMemberQualification, memberQualifier, false);
  7004. memberQualifier = newMemberQualification;
  7005. }
  7006. layoutMemberLocationArrayCheck(loc, memberWithLocation, arraySizes);
  7007. #ifndef GLSLANG_WEB
  7008. // Ensure that the block has an XfbBuffer assigned. This is needed
  7009. // because if the block has a XfbOffset assigned, then it is
  7010. // assumed that it has implicitly assigned the current global
  7011. // XfbBuffer, and because it's members need to be assigned a
  7012. // XfbOffset if they lack it.
  7013. if (currentBlockQualifier.storage == EvqVaryingOut && globalOutputDefaults.hasXfbBuffer()) {
  7014. if (!currentBlockQualifier.hasXfbBuffer() && currentBlockQualifier.hasXfbOffset())
  7015. currentBlockQualifier.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer;
  7016. }
  7017. #endif
  7018. // Process the members
  7019. fixBlockLocations(loc, currentBlockQualifier, typeList, memberWithLocation, memberWithoutLocation);
  7020. fixXfbOffsets(currentBlockQualifier, typeList);
  7021. fixBlockUniformOffsets(currentBlockQualifier, typeList);
  7022. fixBlockUniformLayoutMatrix(currentBlockQualifier, &typeList, nullptr);
  7023. fixBlockUniformLayoutPacking(currentBlockQualifier, &typeList, nullptr);
  7024. for (unsigned int member = 0; member < typeList.size(); ++member)
  7025. layoutTypeCheck(typeList[member].loc, *typeList[member].type);
  7026. #ifndef GLSLANG_WEB
  7027. if (memberWithPerViewQualifier) {
  7028. for (unsigned int member = 0; member < typeList.size(); ++member) {
  7029. checkAndResizeMeshViewDim(typeList[member].loc, *typeList[member].type, /*isBlockMember*/ true);
  7030. }
  7031. }
  7032. #endif
  7033. // reverse merge, so that currentBlockQualifier now has all layout information
  7034. // (can't use defaultQualification directly, it's missing other non-layout-default-class qualifiers)
  7035. mergeObjectLayoutQualifiers(currentBlockQualifier, defaultQualification, true);
  7036. //
  7037. // Build and add the interface block as a new type named 'blockName'
  7038. //
  7039. TType blockType(&typeList, *blockName, currentBlockQualifier);
  7040. if (arraySizes != nullptr)
  7041. blockType.transferArraySizes(arraySizes);
  7042. #ifndef GLSLANG_WEB
  7043. if (arraySizes == nullptr)
  7044. ioArrayCheck(loc, blockType, instanceName ? *instanceName : *blockName);
  7045. if (currentBlockQualifier.hasBufferReference()) {
  7046. if (currentBlockQualifier.storage != EvqBuffer)
  7047. error(loc, "can only be used with buffer", "buffer_reference", "");
  7048. // Create the block reference type. If it was forward-declared, detect that
  7049. // as a referent struct type with no members. Replace the referent type with
  7050. // blockType.
  7051. TType blockNameType(EbtReference, blockType, *blockName);
  7052. TVariable* blockNameVar = new TVariable(blockName, blockNameType, true);
  7053. if (! symbolTable.insert(*blockNameVar)) {
  7054. TSymbol* existingName = symbolTable.find(*blockName);
  7055. if (existingName->getType().isReference() &&
  7056. existingName->getType().getReferentType()->getStruct() &&
  7057. existingName->getType().getReferentType()->getStruct()->size() == 0 &&
  7058. existingName->getType().getQualifier().storage == blockType.getQualifier().storage) {
  7059. existingName->getType().getReferentType()->deepCopy(blockType);
  7060. } else {
  7061. error(loc, "block name cannot be redefined", blockName->c_str(), "");
  7062. }
  7063. }
  7064. if (!instanceName) {
  7065. return;
  7066. }
  7067. } else
  7068. #endif
  7069. {
  7070. //
  7071. // Don't make a user-defined type out of block name; that will cause an error
  7072. // if the same block name gets reused in a different interface.
  7073. //
  7074. // "Block names have no other use within a shader
  7075. // beyond interface matching; it is a compile-time error to use a block name at global scope for anything
  7076. // other than as a block name (e.g., use of a block name for a global variable name or function name is
  7077. // currently reserved)."
  7078. //
  7079. // Use the symbol table to prevent normal reuse of the block's name, as a variable entry,
  7080. // whose type is EbtBlock, but without all the structure; that will come from the type
  7081. // the instances point to.
  7082. //
  7083. TType blockNameType(EbtBlock, blockType.getQualifier().storage);
  7084. TVariable* blockNameVar = new TVariable(blockName, blockNameType);
  7085. if (! symbolTable.insert(*blockNameVar)) {
  7086. TSymbol* existingName = symbolTable.find(*blockName);
  7087. if (existingName->getType().getBasicType() == EbtBlock) {
  7088. if (existingName->getType().getQualifier().storage == blockType.getQualifier().storage) {
  7089. error(loc, "Cannot reuse block name within the same interface:", blockName->c_str(), blockType.getStorageQualifierString());
  7090. return;
  7091. }
  7092. } else {
  7093. error(loc, "block name cannot redefine a non-block name", blockName->c_str(), "");
  7094. return;
  7095. }
  7096. }
  7097. }
  7098. // Add the variable, as anonymous or named instanceName.
  7099. // Make an anonymous variable if no name was provided.
  7100. if (! instanceName)
  7101. instanceName = NewPoolTString("");
  7102. TVariable& variable = *new TVariable(instanceName, blockType);
  7103. if (! symbolTable.insert(variable)) {
  7104. if (*instanceName == "")
  7105. error(loc, "nameless block contains a member that already has a name at global scope", blockName->c_str(), "");
  7106. else
  7107. error(loc, "block instance name redefinition", variable.getName().c_str(), "");
  7108. return;
  7109. }
  7110. // Check for general layout qualifier errors
  7111. layoutObjectCheck(loc, variable);
  7112. #ifndef GLSLANG_WEB
  7113. // fix up
  7114. if (isIoResizeArray(blockType)) {
  7115. ioArraySymbolResizeList.push_back(&variable);
  7116. checkIoArraysConsistency(loc, true);
  7117. } else
  7118. fixIoArraySize(loc, variable.getWritableType());
  7119. #endif
  7120. // Save it in the AST for linker use.
  7121. trackLinkage(variable);
  7122. }
  7123. // Do all block-declaration checking regarding the combination of in/out/uniform/buffer
  7124. // with a particular stage.
  7125. void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& qualifier)
  7126. {
  7127. const char *extsrt[2] = { E_GL_NV_ray_tracing, E_GL_EXT_ray_tracing };
  7128. switch (qualifier.storage) {
  7129. case EvqUniform:
  7130. profileRequires(loc, EEsProfile, 300, nullptr, "uniform block");
  7131. profileRequires(loc, ENoProfile, 140, E_GL_ARB_uniform_buffer_object, "uniform block");
  7132. if (currentBlockQualifier.layoutPacking == ElpStd430 && ! currentBlockQualifier.isPushConstant())
  7133. requireExtensions(loc, 1, &E_GL_EXT_scalar_block_layout, "std430 requires the buffer storage qualifier");
  7134. break;
  7135. case EvqBuffer:
  7136. requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "buffer block");
  7137. profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_shader_storage_buffer_object, "buffer block");
  7138. profileRequires(loc, EEsProfile, 310, nullptr, "buffer block");
  7139. break;
  7140. case EvqVaryingIn:
  7141. profileRequires(loc, ~EEsProfile, 150, E_GL_ARB_separate_shader_objects, "input block");
  7142. // It is a compile-time error to have an input block in a vertex shader or an output block in a fragment shader
  7143. // "Compute shaders do not permit user-defined input variables..."
  7144. requireStage(loc, (EShLanguageMask)(EShLangTessControlMask|EShLangTessEvaluationMask|EShLangGeometryMask|
  7145. EShLangFragmentMask|EShLangMeshNVMask), "input block");
  7146. if (language == EShLangFragment) {
  7147. profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, "fragment input block");
  7148. } else if (language == EShLangMeshNV && ! qualifier.isTaskMemory()) {
  7149. error(loc, "input blocks cannot be used in a mesh shader", "out", "");
  7150. }
  7151. break;
  7152. case EvqVaryingOut:
  7153. profileRequires(loc, ~EEsProfile, 150, E_GL_ARB_separate_shader_objects, "output block");
  7154. requireStage(loc, (EShLanguageMask)(EShLangVertexMask|EShLangTessControlMask|EShLangTessEvaluationMask|
  7155. EShLangGeometryMask|EShLangMeshNVMask|EShLangTaskNVMask), "output block");
  7156. // ES 310 can have a block before shader_io is turned on, so skip this test for built-ins
  7157. if (language == EShLangVertex && ! parsingBuiltins) {
  7158. profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, "vertex output block");
  7159. } else if (language == EShLangMeshNV && qualifier.isTaskMemory()) {
  7160. error(loc, "can only use on input blocks in mesh shader", "taskNV", "");
  7161. } else if (language == EShLangTaskNV && ! qualifier.isTaskMemory()) {
  7162. error(loc, "output blocks cannot be used in a task shader", "out", "");
  7163. }
  7164. break;
  7165. case EvqShared:
  7166. if (spvVersion.spv > 0 && spvVersion.spv < EShTargetSpv_1_4) {
  7167. error(loc, "shared block requires at least SPIR-V 1.4", "shared block", "");
  7168. }
  7169. profileRequires(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, 0, E_GL_EXT_shared_memory_block, "shared block");
  7170. break;
  7171. #ifndef GLSLANG_WEB
  7172. case EvqPayload:
  7173. profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "rayPayloadNV block");
  7174. requireStage(loc, (EShLanguageMask)(EShLangRayGenMask | EShLangAnyHitMask | EShLangClosestHitMask | EShLangMissMask),
  7175. "rayPayloadNV block");
  7176. break;
  7177. case EvqPayloadIn:
  7178. profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "rayPayloadInNV block");
  7179. requireStage(loc, (EShLanguageMask)(EShLangAnyHitMask | EShLangClosestHitMask | EShLangMissMask),
  7180. "rayPayloadInNV block");
  7181. break;
  7182. case EvqHitAttr:
  7183. profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "hitAttributeNV block");
  7184. requireStage(loc, (EShLanguageMask)(EShLangIntersectMask | EShLangAnyHitMask | EShLangClosestHitMask), "hitAttributeNV block");
  7185. break;
  7186. case EvqCallableData:
  7187. profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "callableDataNV block");
  7188. requireStage(loc, (EShLanguageMask)(EShLangRayGenMask | EShLangClosestHitMask | EShLangMissMask | EShLangCallableMask),
  7189. "callableDataNV block");
  7190. break;
  7191. case EvqCallableDataIn:
  7192. profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "callableDataInNV block");
  7193. requireStage(loc, (EShLanguageMask)(EShLangCallableMask), "callableDataInNV block");
  7194. break;
  7195. #endif
  7196. default:
  7197. error(loc, "only uniform, buffer, in, or out blocks are supported", blockName->c_str(), "");
  7198. break;
  7199. }
  7200. }
  7201. // Do all block-declaration checking regarding its qualifiers.
  7202. void TParseContext::blockQualifierCheck(const TSourceLoc& loc, const TQualifier& qualifier, bool /*instanceName*/)
  7203. {
  7204. // The 4.5 specification says:
  7205. //
  7206. // interface-block :
  7207. // layout-qualifieropt interface-qualifier block-name { member-list } instance-nameopt ;
  7208. //
  7209. // interface-qualifier :
  7210. // in
  7211. // out
  7212. // patch in
  7213. // patch out
  7214. // uniform
  7215. // buffer
  7216. //
  7217. // Note however memory qualifiers aren't included, yet the specification also says
  7218. //
  7219. // "...memory qualifiers may also be used in the declaration of shader storage blocks..."
  7220. if (qualifier.isInterpolation())
  7221. error(loc, "cannot use interpolation qualifiers on an interface block", "flat/smooth/noperspective", "");
  7222. if (qualifier.centroid)
  7223. error(loc, "cannot use centroid qualifier on an interface block", "centroid", "");
  7224. if (qualifier.isSample())
  7225. error(loc, "cannot use sample qualifier on an interface block", "sample", "");
  7226. if (qualifier.invariant)
  7227. error(loc, "cannot use invariant qualifier on an interface block", "invariant", "");
  7228. if (qualifier.isPushConstant())
  7229. intermediate.addPushConstantCount();
  7230. if (qualifier.isShaderRecord())
  7231. intermediate.addShaderRecordCount();
  7232. if (qualifier.isTaskMemory())
  7233. intermediate.addTaskNVCount();
  7234. }
  7235. //
  7236. // "For a block, this process applies to the entire block, or until the first member
  7237. // is reached that has a location layout qualifier. When a block member is declared with a location
  7238. // qualifier, its location comes from that qualifier: The member's location qualifier overrides the block-level
  7239. // declaration. Subsequent members are again assigned consecutive locations, based on the newest location,
  7240. // until the next member declared with a location qualifier. The values used for locations do not have to be
  7241. // declared in increasing order."
  7242. void TParseContext::fixBlockLocations(const TSourceLoc& loc, TQualifier& qualifier, TTypeList& typeList, bool memberWithLocation, bool memberWithoutLocation)
  7243. {
  7244. // "If a block has no block-level location layout qualifier, it is required that either all or none of its members
  7245. // have a location layout qualifier, or a compile-time error results."
  7246. if (! qualifier.hasLocation() && memberWithLocation && memberWithoutLocation)
  7247. error(loc, "either the block needs a location, or all members need a location, or no members have a location", "location", "");
  7248. else {
  7249. if (memberWithLocation) {
  7250. // remove any block-level location and make it per *every* member
  7251. int nextLocation = 0; // by the rule above, initial value is not relevant
  7252. if (qualifier.hasAnyLocation()) {
  7253. nextLocation = qualifier.layoutLocation;
  7254. qualifier.layoutLocation = TQualifier::layoutLocationEnd;
  7255. if (qualifier.hasComponent()) {
  7256. // "It is a compile-time error to apply the *component* qualifier to a ... block"
  7257. error(loc, "cannot apply to a block", "component", "");
  7258. }
  7259. if (qualifier.hasIndex()) {
  7260. error(loc, "cannot apply to a block", "index", "");
  7261. }
  7262. }
  7263. for (unsigned int member = 0; member < typeList.size(); ++member) {
  7264. TQualifier& memberQualifier = typeList[member].type->getQualifier();
  7265. const TSourceLoc& memberLoc = typeList[member].loc;
  7266. if (! memberQualifier.hasLocation()) {
  7267. if (nextLocation >= (int)TQualifier::layoutLocationEnd)
  7268. error(memberLoc, "location is too large", "location", "");
  7269. memberQualifier.layoutLocation = nextLocation;
  7270. memberQualifier.layoutComponent = TQualifier::layoutComponentEnd;
  7271. }
  7272. nextLocation = memberQualifier.layoutLocation + intermediate.computeTypeLocationSize(
  7273. *typeList[member].type, language);
  7274. }
  7275. }
  7276. }
  7277. }
  7278. void TParseContext::fixXfbOffsets(TQualifier& qualifier, TTypeList& typeList)
  7279. {
  7280. #ifndef GLSLANG_WEB
  7281. // "If a block is qualified with xfb_offset, all its
  7282. // members are assigned transform feedback buffer offsets. If a block is not qualified with xfb_offset, any
  7283. // members of that block not qualified with an xfb_offset will not be assigned transform feedback buffer
  7284. // offsets."
  7285. if (! qualifier.hasXfbBuffer() || ! qualifier.hasXfbOffset())
  7286. return;
  7287. int nextOffset = qualifier.layoutXfbOffset;
  7288. for (unsigned int member = 0; member < typeList.size(); ++member) {
  7289. TQualifier& memberQualifier = typeList[member].type->getQualifier();
  7290. bool contains64BitType = false;
  7291. bool contains32BitType = false;
  7292. bool contains16BitType = false;
  7293. int memberSize = intermediate.computeTypeXfbSize(*typeList[member].type, contains64BitType, contains32BitType, contains16BitType);
  7294. // see if we need to auto-assign an offset to this member
  7295. if (! memberQualifier.hasXfbOffset()) {
  7296. // "if applied to an aggregate containing a double or 64-bit integer, the offset must also be a multiple of 8"
  7297. if (contains64BitType)
  7298. RoundToPow2(nextOffset, 8);
  7299. else if (contains32BitType)
  7300. RoundToPow2(nextOffset, 4);
  7301. else if (contains16BitType)
  7302. RoundToPow2(nextOffset, 2);
  7303. memberQualifier.layoutXfbOffset = nextOffset;
  7304. } else
  7305. nextOffset = memberQualifier.layoutXfbOffset;
  7306. nextOffset += memberSize;
  7307. }
  7308. // The above gave all block members an offset, so we can take it off the block now,
  7309. // which will avoid double counting the offset usage.
  7310. qualifier.layoutXfbOffset = TQualifier::layoutXfbOffsetEnd;
  7311. #endif
  7312. }
  7313. // Calculate and save the offset of each block member, using the recursively
  7314. // defined block offset rules and the user-provided offset and align.
  7315. //
  7316. // Also, compute and save the total size of the block. For the block's size, arrayness
  7317. // is not taken into account, as each element is backed by a separate buffer.
  7318. //
  7319. void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typeList)
  7320. {
  7321. if (!storageCanHaveLayoutInBlock(qualifier.storage) && !qualifier.isTaskMemory())
  7322. return;
  7323. if (qualifier.layoutPacking != ElpStd140 && qualifier.layoutPacking != ElpStd430 && qualifier.layoutPacking != ElpScalar)
  7324. return;
  7325. int offset = 0;
  7326. int memberSize;
  7327. for (unsigned int member = 0; member < typeList.size(); ++member) {
  7328. TQualifier& memberQualifier = typeList[member].type->getQualifier();
  7329. const TSourceLoc& memberLoc = typeList[member].loc;
  7330. // "When align is applied to an array, it effects only the start of the array, not the array's internal stride."
  7331. // modify just the children's view of matrix layout, if there is one for this member
  7332. TLayoutMatrix subMatrixLayout = typeList[member].type->getQualifier().layoutMatrix;
  7333. int dummyStride;
  7334. int memberAlignment = intermediate.getMemberAlignment(*typeList[member].type, memberSize, dummyStride, qualifier.layoutPacking,
  7335. subMatrixLayout != ElmNone ? subMatrixLayout == ElmRowMajor : qualifier.layoutMatrix == ElmRowMajor);
  7336. if (memberQualifier.hasOffset()) {
  7337. // "The specified offset must be a multiple
  7338. // of the base alignment of the type of the block member it qualifies, or a compile-time error results."
  7339. if (! IsMultipleOfPow2(memberQualifier.layoutOffset, memberAlignment))
  7340. error(memberLoc, "must be a multiple of the member's alignment", "offset", "");
  7341. // GLSL: "It is a compile-time error to specify an offset that is smaller than the offset of the previous
  7342. // member in the block or that lies within the previous member of the block"
  7343. if (spvVersion.spv == 0) {
  7344. if (memberQualifier.layoutOffset < offset)
  7345. error(memberLoc, "cannot lie in previous members", "offset", "");
  7346. // "The offset qualifier forces the qualified member to start at or after the specified
  7347. // integral-constant expression, which will be its byte offset from the beginning of the buffer.
  7348. // "The actual offset of a member is computed as
  7349. // follows: If offset was declared, start with that offset, otherwise start with the next available offset."
  7350. offset = std::max(offset, memberQualifier.layoutOffset);
  7351. } else {
  7352. // TODO: Vulkan: "It is a compile-time error to have any offset, explicit or assigned,
  7353. // that lies within another member of the block."
  7354. offset = memberQualifier.layoutOffset;
  7355. }
  7356. }
  7357. // "The actual alignment of a member will be the greater of the specified align alignment and the standard
  7358. // (e.g., std140) base alignment for the member's type."
  7359. if (memberQualifier.hasAlign())
  7360. memberAlignment = std::max(memberAlignment, memberQualifier.layoutAlign);
  7361. // "If the resulting offset is not a multiple of the actual alignment,
  7362. // increase it to the first offset that is a multiple of
  7363. // the actual alignment."
  7364. RoundToPow2(offset, memberAlignment);
  7365. typeList[member].type->getQualifier().layoutOffset = offset;
  7366. offset += memberSize;
  7367. }
  7368. }
  7369. //
  7370. // Spread LayoutMatrix to uniform block member, if a uniform block member is a struct,
  7371. // we need spread LayoutMatrix to this struct member too. and keep this rule for recursive.
  7372. //
  7373. void TParseContext::fixBlockUniformLayoutMatrix(TQualifier& qualifier, TTypeList* originTypeList,
  7374. TTypeList* tmpTypeList)
  7375. {
  7376. assert(tmpTypeList == nullptr || originTypeList->size() == tmpTypeList->size());
  7377. for (unsigned int member = 0; member < originTypeList->size(); ++member) {
  7378. if (qualifier.layoutPacking != ElpNone) {
  7379. if (tmpTypeList == nullptr) {
  7380. if (((*originTypeList)[member].type->isMatrix() ||
  7381. (*originTypeList)[member].type->getBasicType() == EbtStruct) &&
  7382. (*originTypeList)[member].type->getQualifier().layoutMatrix == ElmNone) {
  7383. (*originTypeList)[member].type->getQualifier().layoutMatrix = qualifier.layoutMatrix;
  7384. }
  7385. } else {
  7386. if (((*tmpTypeList)[member].type->isMatrix() ||
  7387. (*tmpTypeList)[member].type->getBasicType() == EbtStruct) &&
  7388. (*tmpTypeList)[member].type->getQualifier().layoutMatrix == ElmNone) {
  7389. (*tmpTypeList)[member].type->getQualifier().layoutMatrix = qualifier.layoutMatrix;
  7390. }
  7391. }
  7392. }
  7393. if ((*originTypeList)[member].type->getBasicType() == EbtStruct) {
  7394. TQualifier* memberQualifier = nullptr;
  7395. // block member can be declare a matrix style, so it should be update to the member's style
  7396. if ((*originTypeList)[member].type->getQualifier().layoutMatrix == ElmNone) {
  7397. memberQualifier = &qualifier;
  7398. } else {
  7399. memberQualifier = &((*originTypeList)[member].type->getQualifier());
  7400. }
  7401. const TType* tmpType = tmpTypeList == nullptr ?
  7402. (*originTypeList)[member].type->clone() : (*tmpTypeList)[member].type;
  7403. fixBlockUniformLayoutMatrix(*memberQualifier, (*originTypeList)[member].type->getWritableStruct(),
  7404. tmpType->getWritableStruct());
  7405. const TTypeList* structure = recordStructCopy(matrixFixRecord, (*originTypeList)[member].type, tmpType);
  7406. if (tmpTypeList == nullptr) {
  7407. (*originTypeList)[member].type->setStruct(const_cast<TTypeList*>(structure));
  7408. }
  7409. if (tmpTypeList != nullptr) {
  7410. (*tmpTypeList)[member].type->setStruct(const_cast<TTypeList*>(structure));
  7411. }
  7412. }
  7413. }
  7414. }
  7415. //
  7416. // Spread LayoutPacking to block member, if a block member is a struct, we need spread LayoutPacking to
  7417. // this struct member too. and keep this rule for recursive.
  7418. //
  7419. void TParseContext::fixBlockUniformLayoutPacking(TQualifier& qualifier, TTypeList* originTypeList,
  7420. TTypeList* tmpTypeList)
  7421. {
  7422. assert(tmpTypeList == nullptr || originTypeList->size() == tmpTypeList->size());
  7423. for (unsigned int member = 0; member < originTypeList->size(); ++member) {
  7424. if (qualifier.layoutPacking != ElpNone) {
  7425. if (tmpTypeList == nullptr) {
  7426. if ((*originTypeList)[member].type->getQualifier().layoutPacking == ElpNone) {
  7427. (*originTypeList)[member].type->getQualifier().layoutPacking = qualifier.layoutPacking;
  7428. }
  7429. } else {
  7430. if ((*tmpTypeList)[member].type->getQualifier().layoutPacking == ElpNone) {
  7431. (*tmpTypeList)[member].type->getQualifier().layoutPacking = qualifier.layoutPacking;
  7432. }
  7433. }
  7434. }
  7435. if ((*originTypeList)[member].type->getBasicType() == EbtStruct) {
  7436. // Deep copy the type in pool.
  7437. // Because, struct use in different block may have different layout qualifier.
  7438. // We have to new a object to distinguish between them.
  7439. const TType* tmpType = tmpTypeList == nullptr ?
  7440. (*originTypeList)[member].type->clone() : (*tmpTypeList)[member].type;
  7441. fixBlockUniformLayoutPacking(qualifier, (*originTypeList)[member].type->getWritableStruct(),
  7442. tmpType->getWritableStruct());
  7443. const TTypeList* structure = recordStructCopy(packingFixRecord, (*originTypeList)[member].type, tmpType);
  7444. if (tmpTypeList == nullptr) {
  7445. (*originTypeList)[member].type->setStruct(const_cast<TTypeList*>(structure));
  7446. }
  7447. if (tmpTypeList != nullptr) {
  7448. (*tmpTypeList)[member].type->setStruct(const_cast<TTypeList*>(structure));
  7449. }
  7450. }
  7451. }
  7452. }
  7453. // For an identifier that is already declared, add more qualification to it.
  7454. void TParseContext::addQualifierToExisting(const TSourceLoc& loc, TQualifier qualifier, const TString& identifier)
  7455. {
  7456. TSymbol* symbol = symbolTable.find(identifier);
  7457. // A forward declaration of a block reference looks to the grammar like adding
  7458. // a qualifier to an existing symbol. Detect this and create the block reference
  7459. // type with an empty type list, which will be filled in later in
  7460. // TParseContext::declareBlock.
  7461. if (!symbol && qualifier.hasBufferReference()) {
  7462. TTypeList typeList;
  7463. TType blockType(&typeList, identifier, qualifier);;
  7464. TType blockNameType(EbtReference, blockType, identifier);
  7465. TVariable* blockNameVar = new TVariable(&identifier, blockNameType, true);
  7466. if (! symbolTable.insert(*blockNameVar)) {
  7467. error(loc, "block name cannot redefine a non-block name", blockName->c_str(), "");
  7468. }
  7469. return;
  7470. }
  7471. if (! symbol) {
  7472. error(loc, "identifier not previously declared", identifier.c_str(), "");
  7473. return;
  7474. }
  7475. if (symbol->getAsFunction()) {
  7476. error(loc, "cannot re-qualify a function name", identifier.c_str(), "");
  7477. return;
  7478. }
  7479. if (qualifier.isAuxiliary() ||
  7480. qualifier.isMemory() ||
  7481. qualifier.isInterpolation() ||
  7482. qualifier.hasLayout() ||
  7483. qualifier.storage != EvqTemporary ||
  7484. qualifier.precision != EpqNone) {
  7485. error(loc, "cannot add storage, auxiliary, memory, interpolation, layout, or precision qualifier to an existing variable", identifier.c_str(), "");
  7486. return;
  7487. }
  7488. // For read-only built-ins, add a new symbol for holding the modified qualifier.
  7489. // This will bring up an entire block, if a block type has to be modified (e.g., gl_Position inside a block)
  7490. if (symbol->isReadOnly())
  7491. symbol = symbolTable.copyUp(symbol);
  7492. if (qualifier.invariant) {
  7493. if (intermediate.inIoAccessed(identifier))
  7494. error(loc, "cannot change qualification after use", "invariant", "");
  7495. symbol->getWritableType().getQualifier().invariant = true;
  7496. invariantCheck(loc, symbol->getType().getQualifier());
  7497. } else if (qualifier.isNoContraction()) {
  7498. if (intermediate.inIoAccessed(identifier))
  7499. error(loc, "cannot change qualification after use", "precise", "");
  7500. symbol->getWritableType().getQualifier().setNoContraction();
  7501. } else if (qualifier.specConstant) {
  7502. symbol->getWritableType().getQualifier().makeSpecConstant();
  7503. if (qualifier.hasSpecConstantId())
  7504. symbol->getWritableType().getQualifier().layoutSpecConstantId = qualifier.layoutSpecConstantId;
  7505. } else
  7506. warn(loc, "unknown requalification", "", "");
  7507. }
  7508. void TParseContext::addQualifierToExisting(const TSourceLoc& loc, TQualifier qualifier, TIdentifierList& identifiers)
  7509. {
  7510. for (unsigned int i = 0; i < identifiers.size(); ++i)
  7511. addQualifierToExisting(loc, qualifier, *identifiers[i]);
  7512. }
  7513. // Make sure 'invariant' isn't being applied to a non-allowed object.
  7514. void TParseContext::invariantCheck(const TSourceLoc& loc, const TQualifier& qualifier)
  7515. {
  7516. if (! qualifier.invariant)
  7517. return;
  7518. bool pipeOut = qualifier.isPipeOutput();
  7519. bool pipeIn = qualifier.isPipeInput();
  7520. if ((version >= 300 && isEsProfile()) || (!isEsProfile() && version >= 420)) {
  7521. if (! pipeOut)
  7522. error(loc, "can only apply to an output", "invariant", "");
  7523. } else {
  7524. if ((language == EShLangVertex && pipeIn) || (! pipeOut && ! pipeIn))
  7525. error(loc, "can only apply to an output, or to an input in a non-vertex stage\n", "invariant", "");
  7526. }
  7527. }
  7528. //
  7529. // Updating default qualifier for the case of a declaration with just a qualifier,
  7530. // no type, block, or identifier.
  7531. //
  7532. void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, const TPublicType& publicType)
  7533. {
  7534. #ifndef GLSLANG_WEB
  7535. if (publicType.shaderQualifiers.vertices != TQualifier::layoutNotSet) {
  7536. assert(language == EShLangTessControl || language == EShLangGeometry || language == EShLangMeshNV);
  7537. const char* id = (language == EShLangTessControl) ? "vertices" : "max_vertices";
  7538. if (publicType.qualifier.storage != EvqVaryingOut)
  7539. error(loc, "can only apply to 'out'", id, "");
  7540. if (! intermediate.setVertices(publicType.shaderQualifiers.vertices))
  7541. error(loc, "cannot change previously set layout value", id, "");
  7542. if (language == EShLangTessControl)
  7543. checkIoArraysConsistency(loc);
  7544. }
  7545. if (publicType.shaderQualifiers.primitives != TQualifier::layoutNotSet) {
  7546. assert(language == EShLangMeshNV);
  7547. const char* id = "max_primitives";
  7548. if (publicType.qualifier.storage != EvqVaryingOut)
  7549. error(loc, "can only apply to 'out'", id, "");
  7550. if (! intermediate.setPrimitives(publicType.shaderQualifiers.primitives))
  7551. error(loc, "cannot change previously set layout value", id, "");
  7552. }
  7553. if (publicType.shaderQualifiers.invocations != TQualifier::layoutNotSet) {
  7554. if (publicType.qualifier.storage != EvqVaryingIn)
  7555. error(loc, "can only apply to 'in'", "invocations", "");
  7556. if (! intermediate.setInvocations(publicType.shaderQualifiers.invocations))
  7557. error(loc, "cannot change previously set layout value", "invocations", "");
  7558. }
  7559. if (publicType.shaderQualifiers.geometry != ElgNone) {
  7560. if (publicType.qualifier.storage == EvqVaryingIn) {
  7561. switch (publicType.shaderQualifiers.geometry) {
  7562. case ElgPoints:
  7563. case ElgLines:
  7564. case ElgLinesAdjacency:
  7565. case ElgTriangles:
  7566. case ElgTrianglesAdjacency:
  7567. case ElgQuads:
  7568. case ElgIsolines:
  7569. if (language == EShLangMeshNV) {
  7570. error(loc, "cannot apply to input", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
  7571. break;
  7572. }
  7573. if (intermediate.setInputPrimitive(publicType.shaderQualifiers.geometry)) {
  7574. if (language == EShLangGeometry)
  7575. checkIoArraysConsistency(loc);
  7576. } else
  7577. error(loc, "cannot change previously set input primitive", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
  7578. break;
  7579. default:
  7580. error(loc, "cannot apply to input", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
  7581. }
  7582. } else if (publicType.qualifier.storage == EvqVaryingOut) {
  7583. switch (publicType.shaderQualifiers.geometry) {
  7584. case ElgLines:
  7585. case ElgTriangles:
  7586. if (language != EShLangMeshNV) {
  7587. error(loc, "cannot apply to 'out'", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
  7588. break;
  7589. }
  7590. // Fall through
  7591. case ElgPoints:
  7592. case ElgLineStrip:
  7593. case ElgTriangleStrip:
  7594. if (! intermediate.setOutputPrimitive(publicType.shaderQualifiers.geometry))
  7595. error(loc, "cannot change previously set output primitive", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
  7596. break;
  7597. default:
  7598. error(loc, "cannot apply to 'out'", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
  7599. }
  7600. } else
  7601. error(loc, "cannot apply to:", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), GetStorageQualifierString(publicType.qualifier.storage));
  7602. }
  7603. if (publicType.shaderQualifiers.spacing != EvsNone) {
  7604. if (publicType.qualifier.storage == EvqVaryingIn) {
  7605. if (! intermediate.setVertexSpacing(publicType.shaderQualifiers.spacing))
  7606. error(loc, "cannot change previously set vertex spacing", TQualifier::getVertexSpacingString(publicType.shaderQualifiers.spacing), "");
  7607. } else
  7608. error(loc, "can only apply to 'in'", TQualifier::getVertexSpacingString(publicType.shaderQualifiers.spacing), "");
  7609. }
  7610. if (publicType.shaderQualifiers.order != EvoNone) {
  7611. if (publicType.qualifier.storage == EvqVaryingIn) {
  7612. if (! intermediate.setVertexOrder(publicType.shaderQualifiers.order))
  7613. error(loc, "cannot change previously set vertex order", TQualifier::getVertexOrderString(publicType.shaderQualifiers.order), "");
  7614. } else
  7615. error(loc, "can only apply to 'in'", TQualifier::getVertexOrderString(publicType.shaderQualifiers.order), "");
  7616. }
  7617. if (publicType.shaderQualifiers.pointMode) {
  7618. if (publicType.qualifier.storage == EvqVaryingIn)
  7619. intermediate.setPointMode();
  7620. else
  7621. error(loc, "can only apply to 'in'", "point_mode", "");
  7622. }
  7623. #endif
  7624. for (int i = 0; i < 3; ++i) {
  7625. if (publicType.shaderQualifiers.localSizeNotDefault[i]) {
  7626. if (publicType.qualifier.storage == EvqVaryingIn) {
  7627. if (! intermediate.setLocalSize(i, publicType.shaderQualifiers.localSize[i]))
  7628. error(loc, "cannot change previously set size", "local_size", "");
  7629. else {
  7630. int max = 0;
  7631. if (language == EShLangCompute) {
  7632. switch (i) {
  7633. case 0: max = resources.maxComputeWorkGroupSizeX; break;
  7634. case 1: max = resources.maxComputeWorkGroupSizeY; break;
  7635. case 2: max = resources.maxComputeWorkGroupSizeZ; break;
  7636. default: break;
  7637. }
  7638. if (intermediate.getLocalSize(i) > (unsigned int)max)
  7639. error(loc, "too large; see gl_MaxComputeWorkGroupSize", "local_size", "");
  7640. }
  7641. #ifndef GLSLANG_WEB
  7642. else if (language == EShLangMeshNV) {
  7643. switch (i) {
  7644. case 0: max = resources.maxMeshWorkGroupSizeX_NV; break;
  7645. case 1: max = resources.maxMeshWorkGroupSizeY_NV; break;
  7646. case 2: max = resources.maxMeshWorkGroupSizeZ_NV; break;
  7647. default: break;
  7648. }
  7649. if (intermediate.getLocalSize(i) > (unsigned int)max)
  7650. error(loc, "too large; see gl_MaxMeshWorkGroupSizeNV", "local_size", "");
  7651. } else if (language == EShLangTaskNV) {
  7652. switch (i) {
  7653. case 0: max = resources.maxTaskWorkGroupSizeX_NV; break;
  7654. case 1: max = resources.maxTaskWorkGroupSizeY_NV; break;
  7655. case 2: max = resources.maxTaskWorkGroupSizeZ_NV; break;
  7656. default: break;
  7657. }
  7658. if (intermediate.getLocalSize(i) > (unsigned int)max)
  7659. error(loc, "too large; see gl_MaxTaskWorkGroupSizeNV", "local_size", "");
  7660. }
  7661. #endif
  7662. else {
  7663. assert(0);
  7664. }
  7665. // Fix the existing constant gl_WorkGroupSize with this new information.
  7666. TVariable* workGroupSize = getEditableVariable("gl_WorkGroupSize");
  7667. if (workGroupSize != nullptr)
  7668. workGroupSize->getWritableConstArray()[i].setUConst(intermediate.getLocalSize(i));
  7669. }
  7670. } else
  7671. error(loc, "can only apply to 'in'", "local_size", "");
  7672. }
  7673. if (publicType.shaderQualifiers.localSizeSpecId[i] != TQualifier::layoutNotSet) {
  7674. if (publicType.qualifier.storage == EvqVaryingIn) {
  7675. if (! intermediate.setLocalSizeSpecId(i, publicType.shaderQualifiers.localSizeSpecId[i]))
  7676. error(loc, "cannot change previously set size", "local_size", "");
  7677. } else
  7678. error(loc, "can only apply to 'in'", "local_size id", "");
  7679. // Set the workgroup built-in variable as a specialization constant
  7680. TVariable* workGroupSize = getEditableVariable("gl_WorkGroupSize");
  7681. if (workGroupSize != nullptr)
  7682. workGroupSize->getWritableType().getQualifier().specConstant = true;
  7683. }
  7684. }
  7685. #ifndef GLSLANG_WEB
  7686. if (publicType.shaderQualifiers.earlyFragmentTests) {
  7687. if (publicType.qualifier.storage == EvqVaryingIn)
  7688. intermediate.setEarlyFragmentTests();
  7689. else
  7690. error(loc, "can only apply to 'in'", "early_fragment_tests", "");
  7691. }
  7692. if (publicType.shaderQualifiers.postDepthCoverage) {
  7693. if (publicType.qualifier.storage == EvqVaryingIn)
  7694. intermediate.setPostDepthCoverage();
  7695. else
  7696. error(loc, "can only apply to 'in'", "post_coverage_coverage", "");
  7697. }
  7698. if (publicType.shaderQualifiers.hasBlendEquation()) {
  7699. if (publicType.qualifier.storage != EvqVaryingOut)
  7700. error(loc, "can only apply to 'out'", "blend equation", "");
  7701. }
  7702. if (publicType.shaderQualifiers.interlockOrdering) {
  7703. if (publicType.qualifier.storage == EvqVaryingIn) {
  7704. if (!intermediate.setInterlockOrdering(publicType.shaderQualifiers.interlockOrdering))
  7705. error(loc, "cannot change previously set fragment shader interlock ordering", TQualifier::getInterlockOrderingString(publicType.shaderQualifiers.interlockOrdering), "");
  7706. }
  7707. else
  7708. error(loc, "can only apply to 'in'", TQualifier::getInterlockOrderingString(publicType.shaderQualifiers.interlockOrdering), "");
  7709. }
  7710. if (publicType.shaderQualifiers.layoutDerivativeGroupQuads &&
  7711. publicType.shaderQualifiers.layoutDerivativeGroupLinear) {
  7712. error(loc, "cannot be both specified", "derivative_group_quadsNV and derivative_group_linearNV", "");
  7713. }
  7714. if (publicType.shaderQualifiers.layoutDerivativeGroupQuads) {
  7715. if (publicType.qualifier.storage == EvqVaryingIn) {
  7716. if ((intermediate.getLocalSize(0) & 1) ||
  7717. (intermediate.getLocalSize(1) & 1))
  7718. error(loc, "requires local_size_x and local_size_y to be multiple of two", "derivative_group_quadsNV", "");
  7719. else
  7720. intermediate.setLayoutDerivativeMode(LayoutDerivativeGroupQuads);
  7721. }
  7722. else
  7723. error(loc, "can only apply to 'in'", "derivative_group_quadsNV", "");
  7724. }
  7725. if (publicType.shaderQualifiers.layoutDerivativeGroupLinear) {
  7726. if (publicType.qualifier.storage == EvqVaryingIn) {
  7727. if((intermediate.getLocalSize(0) *
  7728. intermediate.getLocalSize(1) *
  7729. intermediate.getLocalSize(2)) % 4 != 0)
  7730. error(loc, "requires total group size to be multiple of four", "derivative_group_linearNV", "");
  7731. else
  7732. intermediate.setLayoutDerivativeMode(LayoutDerivativeGroupLinear);
  7733. }
  7734. else
  7735. error(loc, "can only apply to 'in'", "derivative_group_linearNV", "");
  7736. }
  7737. // Check mesh out array sizes, once all the necessary out qualifiers are defined.
  7738. if ((language == EShLangMeshNV) &&
  7739. (intermediate.getVertices() != TQualifier::layoutNotSet) &&
  7740. (intermediate.getPrimitives() != TQualifier::layoutNotSet) &&
  7741. (intermediate.getOutputPrimitive() != ElgNone))
  7742. {
  7743. checkIoArraysConsistency(loc);
  7744. }
  7745. if (publicType.shaderQualifiers.layoutPrimitiveCulling) {
  7746. if (publicType.qualifier.storage != EvqTemporary)
  7747. error(loc, "layout qualifier can not have storage qualifiers", "primitive_culling","", "");
  7748. else {
  7749. intermediate.setLayoutPrimitiveCulling();
  7750. }
  7751. // Exit early as further checks are not valid
  7752. return;
  7753. }
  7754. #endif
  7755. const TQualifier& qualifier = publicType.qualifier;
  7756. if (qualifier.isAuxiliary() ||
  7757. qualifier.isMemory() ||
  7758. qualifier.isInterpolation() ||
  7759. qualifier.precision != EpqNone)
  7760. error(loc, "cannot use auxiliary, memory, interpolation, or precision qualifier in a default qualifier declaration (declaration with no type)", "qualifier", "");
  7761. // "The offset qualifier can only be used on block members of blocks..."
  7762. // "The align qualifier can only be used on blocks or block members..."
  7763. if (qualifier.hasOffset() ||
  7764. qualifier.hasAlign())
  7765. error(loc, "cannot use offset or align qualifiers in a default qualifier declaration (declaration with no type)", "layout qualifier", "");
  7766. layoutQualifierCheck(loc, qualifier);
  7767. switch (qualifier.storage) {
  7768. case EvqUniform:
  7769. if (qualifier.hasMatrix())
  7770. globalUniformDefaults.layoutMatrix = qualifier.layoutMatrix;
  7771. if (qualifier.hasPacking())
  7772. globalUniformDefaults.layoutPacking = qualifier.layoutPacking;
  7773. break;
  7774. case EvqBuffer:
  7775. if (qualifier.hasMatrix())
  7776. globalBufferDefaults.layoutMatrix = qualifier.layoutMatrix;
  7777. if (qualifier.hasPacking())
  7778. globalBufferDefaults.layoutPacking = qualifier.layoutPacking;
  7779. break;
  7780. case EvqVaryingIn:
  7781. break;
  7782. case EvqVaryingOut:
  7783. #ifndef GLSLANG_WEB
  7784. if (qualifier.hasStream())
  7785. globalOutputDefaults.layoutStream = qualifier.layoutStream;
  7786. if (qualifier.hasXfbBuffer())
  7787. globalOutputDefaults.layoutXfbBuffer = qualifier.layoutXfbBuffer;
  7788. if (globalOutputDefaults.hasXfbBuffer() && qualifier.hasXfbStride()) {
  7789. if (! intermediate.setXfbBufferStride(globalOutputDefaults.layoutXfbBuffer, qualifier.layoutXfbStride))
  7790. error(loc, "all stride settings must match for xfb buffer", "xfb_stride", "%d", qualifier.layoutXfbBuffer);
  7791. }
  7792. #endif
  7793. break;
  7794. case EvqShared:
  7795. if (qualifier.hasMatrix())
  7796. globalSharedDefaults.layoutMatrix = qualifier.layoutMatrix;
  7797. if (qualifier.hasPacking())
  7798. globalSharedDefaults.layoutPacking = qualifier.layoutPacking;
  7799. break;
  7800. default:
  7801. error(loc, "default qualifier requires 'uniform', 'buffer', 'in', 'out' or 'shared' storage qualification", "", "");
  7802. return;
  7803. }
  7804. if (qualifier.hasBinding())
  7805. error(loc, "cannot declare a default, include a type or full declaration", "binding", "");
  7806. if (qualifier.hasAnyLocation())
  7807. error(loc, "cannot declare a default, use a full declaration", "location/component/index", "");
  7808. if (qualifier.hasXfbOffset())
  7809. error(loc, "cannot declare a default, use a full declaration", "xfb_offset", "");
  7810. if (qualifier.isPushConstant())
  7811. error(loc, "cannot declare a default, can only be used on a block", "push_constant", "");
  7812. if (qualifier.hasBufferReference())
  7813. error(loc, "cannot declare a default, can only be used on a block", "buffer_reference", "");
  7814. if (qualifier.hasSpecConstantId())
  7815. error(loc, "cannot declare a default, can only be used on a scalar", "constant_id", "");
  7816. if (qualifier.isShaderRecord())
  7817. error(loc, "cannot declare a default, can only be used on a block", "shaderRecordNV", "");
  7818. }
  7819. //
  7820. // Take the sequence of statements that has been built up since the last case/default,
  7821. // put it on the list of top-level nodes for the current (inner-most) switch statement,
  7822. // and follow that by the case/default we are on now. (See switch topology comment on
  7823. // TIntermSwitch.)
  7824. //
  7825. void TParseContext::wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode)
  7826. {
  7827. TIntermSequence* switchSequence = switchSequenceStack.back();
  7828. if (statements) {
  7829. if (switchSequence->size() == 0)
  7830. error(statements->getLoc(), "cannot have statements before first case/default label", "switch", "");
  7831. statements->setOperator(EOpSequence);
  7832. switchSequence->push_back(statements);
  7833. }
  7834. if (branchNode) {
  7835. // check all previous cases for the same label (or both are 'default')
  7836. for (unsigned int s = 0; s < switchSequence->size(); ++s) {
  7837. TIntermBranch* prevBranch = (*switchSequence)[s]->getAsBranchNode();
  7838. if (prevBranch) {
  7839. TIntermTyped* prevExpression = prevBranch->getExpression();
  7840. TIntermTyped* newExpression = branchNode->getAsBranchNode()->getExpression();
  7841. if (prevExpression == nullptr && newExpression == nullptr)
  7842. error(branchNode->getLoc(), "duplicate label", "default", "");
  7843. else if (prevExpression != nullptr &&
  7844. newExpression != nullptr &&
  7845. prevExpression->getAsConstantUnion() &&
  7846. newExpression->getAsConstantUnion() &&
  7847. prevExpression->getAsConstantUnion()->getConstArray()[0].getIConst() ==
  7848. newExpression->getAsConstantUnion()->getConstArray()[0].getIConst())
  7849. error(branchNode->getLoc(), "duplicated value", "case", "");
  7850. }
  7851. }
  7852. switchSequence->push_back(branchNode);
  7853. }
  7854. }
  7855. //
  7856. // Turn the top-level node sequence built up of wrapupSwitchSubsequence9)
  7857. // into a switch node.
  7858. //
  7859. TIntermNode* TParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* expression, TIntermAggregate* lastStatements)
  7860. {
  7861. profileRequires(loc, EEsProfile, 300, nullptr, "switch statements");
  7862. profileRequires(loc, ENoProfile, 130, nullptr, "switch statements");
  7863. wrapupSwitchSubsequence(lastStatements, nullptr);
  7864. if (expression == nullptr ||
  7865. (expression->getBasicType() != EbtInt && expression->getBasicType() != EbtUint) ||
  7866. expression->getType().isArray() || expression->getType().isMatrix() || expression->getType().isVector())
  7867. error(loc, "condition must be a scalar integer expression", "switch", "");
  7868. // If there is nothing to do, drop the switch but still execute the expression
  7869. TIntermSequence* switchSequence = switchSequenceStack.back();
  7870. if (switchSequence->size() == 0)
  7871. return expression;
  7872. if (lastStatements == nullptr) {
  7873. // This was originally an ERRROR, because early versions of the specification said
  7874. // "it is an error to have no statement between a label and the end of the switch statement."
  7875. // The specifications were updated to remove this (being ill-defined what a "statement" was),
  7876. // so, this became a warning. However, 3.0 tests still check for the error.
  7877. if (isEsProfile() && version <= 300 && ! relaxedErrors())
  7878. error(loc, "last case/default label not followed by statements", "switch", "");
  7879. else
  7880. warn(loc, "last case/default label not followed by statements", "switch", "");
  7881. // emulate a break for error recovery
  7882. lastStatements = intermediate.makeAggregate(intermediate.addBranch(EOpBreak, loc));
  7883. lastStatements->setOperator(EOpSequence);
  7884. switchSequence->push_back(lastStatements);
  7885. }
  7886. TIntermAggregate* body = new TIntermAggregate(EOpSequence);
  7887. body->getSequence() = *switchSequenceStack.back();
  7888. body->setLoc(loc);
  7889. TIntermSwitch* switchNode = new TIntermSwitch(expression, body);
  7890. switchNode->setLoc(loc);
  7891. return switchNode;
  7892. }
  7893. //
  7894. // When a struct used in block, and has it's own layout packing, layout matrix,
  7895. // record the origin structure of a struct to map, and Record the structure copy to the copy table,
  7896. //
  7897. const TTypeList* TParseContext::recordStructCopy(TStructRecord& record, const TType* originType, const TType* tmpType)
  7898. {
  7899. size_t memberCount = tmpType->getStruct()->size();
  7900. size_t originHash = 0, tmpHash = 0;
  7901. std::hash<size_t> hasher;
  7902. for (size_t i = 0; i < memberCount; i++) {
  7903. size_t originMemberHash = hasher(originType->getStruct()->at(i).type->getQualifier().layoutPacking +
  7904. originType->getStruct()->at(i).type->getQualifier().layoutMatrix);
  7905. size_t tmpMemberHash = hasher(tmpType->getStruct()->at(i).type->getQualifier().layoutPacking +
  7906. tmpType->getStruct()->at(i).type->getQualifier().layoutMatrix);
  7907. originHash = hasher((originHash ^ originMemberHash) << 1);
  7908. tmpHash = hasher((tmpHash ^ tmpMemberHash) << 1);
  7909. }
  7910. const TTypeList* originStruct = originType->getStruct();
  7911. const TTypeList* tmpStruct = tmpType->getStruct();
  7912. if (originHash != tmpHash) {
  7913. auto fixRecords = record.find(originStruct);
  7914. if (fixRecords != record.end()) {
  7915. auto fixRecord = fixRecords->second.find(tmpHash);
  7916. if (fixRecord != fixRecords->second.end()) {
  7917. return fixRecord->second;
  7918. } else {
  7919. record[originStruct][tmpHash] = tmpStruct;
  7920. return tmpStruct;
  7921. }
  7922. } else {
  7923. record[originStruct] = std::map<size_t, const TTypeList*>();
  7924. record[originStruct][tmpHash] = tmpStruct;
  7925. return tmpStruct;
  7926. }
  7927. }
  7928. return originStruct;
  7929. }
  7930. } // end namespace glslang