SemaHLSL.cpp 407 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898
  1. //===--- SemaHLSL.cpp - HLSL support for AST nodes and operations ---===//
  2. ///////////////////////////////////////////////////////////////////////////////
  3. // //
  4. // SemaHLSL.cpp //
  5. // Copyright (C) Microsoft Corporation. All rights reserved. //
  6. // This file is distributed under the University of Illinois Open Source //
  7. // License. See LICENSE.TXT for details. //
  8. // //
  9. // This file implements the semantic support for HLSL. //
  10. // //
  11. ///////////////////////////////////////////////////////////////////////////////
  12. #include "llvm/ADT/SmallPtrSet.h"
  13. #include "llvm/ADT/DenseMap.h"
  14. #include "clang/AST/ASTContext.h"
  15. #include "clang/AST/Attr.h"
  16. #include "clang/AST/DeclCXX.h"
  17. #include "clang/AST/DeclTemplate.h"
  18. #include "clang/AST/Expr.h"
  19. #include "clang/AST/ExprCXX.h"
  20. #include "clang/AST/ExternalASTSource.h"
  21. #include "clang/AST/RecursiveASTVisitor.h"
  22. #include "clang/AST/TypeLoc.h"
  23. #include "clang/AST/HlslTypes.h"
  24. #include "clang/Sema/Overload.h"
  25. #include "clang/Sema/SemaDiagnostic.h"
  26. #include "clang/Sema/Initialization.h"
  27. #include "clang/Sema/ExternalSemaSource.h"
  28. #include "clang/Sema/Lookup.h"
  29. #include "clang/Sema/Template.h"
  30. #include "clang/Sema/TemplateDeduction.h"
  31. #include "clang/Sema/SemaHLSL.h"
  32. #include "dxc/Support/Global.h"
  33. #include "dxc/Support/WinIncludes.h"
  34. #include "dxc/Support/WinAdapter.h"
  35. #include "dxc/dxcapi.internal.h"
  36. #include "dxc/HlslIntrinsicOp.h"
  37. #include "gen_intrin_main_tables_15.h"
  38. #include "dxc/HLSL/HLOperations.h"
  39. #include "dxc/HLSL/DxilShaderModel.h"
  40. #include <array>
  41. #include <float.h>
  42. enum ArBasicKind {
  43. AR_BASIC_BOOL,
  44. AR_BASIC_LITERAL_FLOAT,
  45. AR_BASIC_FLOAT16,
  46. AR_BASIC_FLOAT32_PARTIAL_PRECISION,
  47. AR_BASIC_FLOAT32,
  48. AR_BASIC_FLOAT64,
  49. AR_BASIC_LITERAL_INT,
  50. AR_BASIC_INT8,
  51. AR_BASIC_UINT8,
  52. AR_BASIC_INT16,
  53. AR_BASIC_UINT16,
  54. AR_BASIC_INT32,
  55. AR_BASIC_UINT32,
  56. AR_BASIC_INT64,
  57. AR_BASIC_UINT64,
  58. AR_BASIC_MIN10FLOAT,
  59. AR_BASIC_MIN16FLOAT,
  60. AR_BASIC_MIN12INT,
  61. AR_BASIC_MIN16INT,
  62. AR_BASIC_MIN16UINT,
  63. AR_BASIC_ENUM,
  64. AR_BASIC_COUNT,
  65. //
  66. // Pseudo-entries for intrinsic tables and such.
  67. //
  68. AR_BASIC_NONE,
  69. AR_BASIC_UNKNOWN,
  70. AR_BASIC_NOCAST,
  71. //
  72. // The following pseudo-entries represent higher-level
  73. // object types that are treated as units.
  74. //
  75. AR_BASIC_POINTER,
  76. AR_BASIC_ENUM_CLASS,
  77. AR_OBJECT_NULL,
  78. AR_OBJECT_STRING,
  79. // AR_OBJECT_TEXTURE,
  80. AR_OBJECT_TEXTURE1D,
  81. AR_OBJECT_TEXTURE1D_ARRAY,
  82. AR_OBJECT_TEXTURE2D,
  83. AR_OBJECT_TEXTURE2D_ARRAY,
  84. AR_OBJECT_TEXTURE3D,
  85. AR_OBJECT_TEXTURECUBE,
  86. AR_OBJECT_TEXTURECUBE_ARRAY,
  87. AR_OBJECT_TEXTURE2DMS,
  88. AR_OBJECT_TEXTURE2DMS_ARRAY,
  89. AR_OBJECT_SAMPLER,
  90. AR_OBJECT_SAMPLER1D,
  91. AR_OBJECT_SAMPLER2D,
  92. AR_OBJECT_SAMPLER3D,
  93. AR_OBJECT_SAMPLERCUBE,
  94. AR_OBJECT_SAMPLERCOMPARISON,
  95. AR_OBJECT_BUFFER,
  96. //
  97. // View objects are only used as variable/types within the Effects
  98. // framework, for example in calls to OMSetRenderTargets.
  99. //
  100. AR_OBJECT_RENDERTARGETVIEW,
  101. AR_OBJECT_DEPTHSTENCILVIEW,
  102. //
  103. // Shader objects are only used as variable/types within the Effects
  104. // framework, for example as a result of CompileShader().
  105. //
  106. AR_OBJECT_COMPUTESHADER,
  107. AR_OBJECT_DOMAINSHADER,
  108. AR_OBJECT_GEOMETRYSHADER,
  109. AR_OBJECT_HULLSHADER,
  110. AR_OBJECT_PIXELSHADER,
  111. AR_OBJECT_VERTEXSHADER,
  112. AR_OBJECT_PIXELFRAGMENT,
  113. AR_OBJECT_VERTEXFRAGMENT,
  114. AR_OBJECT_STATEBLOCK,
  115. AR_OBJECT_RASTERIZER,
  116. AR_OBJECT_DEPTHSTENCIL,
  117. AR_OBJECT_BLEND,
  118. AR_OBJECT_POINTSTREAM,
  119. AR_OBJECT_LINESTREAM,
  120. AR_OBJECT_TRIANGLESTREAM,
  121. AR_OBJECT_INPUTPATCH,
  122. AR_OBJECT_OUTPUTPATCH,
  123. AR_OBJECT_RWTEXTURE1D,
  124. AR_OBJECT_RWTEXTURE1D_ARRAY,
  125. AR_OBJECT_RWTEXTURE2D,
  126. AR_OBJECT_RWTEXTURE2D_ARRAY,
  127. AR_OBJECT_RWTEXTURE3D,
  128. AR_OBJECT_RWBUFFER,
  129. AR_OBJECT_BYTEADDRESS_BUFFER,
  130. AR_OBJECT_RWBYTEADDRESS_BUFFER,
  131. AR_OBJECT_STRUCTURED_BUFFER,
  132. AR_OBJECT_RWSTRUCTURED_BUFFER,
  133. AR_OBJECT_RWSTRUCTURED_BUFFER_ALLOC,
  134. AR_OBJECT_RWSTRUCTURED_BUFFER_CONSUME,
  135. AR_OBJECT_APPEND_STRUCTURED_BUFFER,
  136. AR_OBJECT_CONSUME_STRUCTURED_BUFFER,
  137. AR_OBJECT_CONSTANT_BUFFER,
  138. AR_OBJECT_TEXTURE_BUFFER,
  139. AR_OBJECT_ROVBUFFER,
  140. AR_OBJECT_ROVBYTEADDRESS_BUFFER,
  141. AR_OBJECT_ROVSTRUCTURED_BUFFER,
  142. AR_OBJECT_ROVTEXTURE1D,
  143. AR_OBJECT_ROVTEXTURE1D_ARRAY,
  144. AR_OBJECT_ROVTEXTURE2D,
  145. AR_OBJECT_ROVTEXTURE2D_ARRAY,
  146. AR_OBJECT_ROVTEXTURE3D,
  147. // SPIRV change starts
  148. #ifdef ENABLE_SPIRV_CODEGEN
  149. AR_OBJECT_VK_SUBPASS_INPUT,
  150. AR_OBJECT_VK_SUBPASS_INPUT_MS,
  151. #endif // ENABLE_SPIRV_CODEGEN
  152. // SPIRV change ends
  153. AR_OBJECT_INNER, // Used for internal type object
  154. AR_OBJECT_LEGACY_EFFECT,
  155. AR_OBJECT_WAVE,
  156. AR_BASIC_MAXIMUM_COUNT
  157. };
  158. #define AR_BASIC_TEXTURE_MS_CASES \
  159. case AR_OBJECT_TEXTURE2DMS: \
  160. case AR_OBJECT_TEXTURE2DMS_ARRAY
  161. #define AR_BASIC_NON_TEXTURE_MS_CASES \
  162. case AR_OBJECT_TEXTURE1D: \
  163. case AR_OBJECT_TEXTURE1D_ARRAY: \
  164. case AR_OBJECT_TEXTURE2D: \
  165. case AR_OBJECT_TEXTURE2D_ARRAY: \
  166. case AR_OBJECT_TEXTURE3D: \
  167. case AR_OBJECT_TEXTURECUBE: \
  168. case AR_OBJECT_TEXTURECUBE_ARRAY
  169. #define AR_BASIC_TEXTURE_CASES \
  170. AR_BASIC_TEXTURE_MS_CASES: \
  171. AR_BASIC_NON_TEXTURE_MS_CASES
  172. #define AR_BASIC_NON_CMP_SAMPLER_CASES \
  173. case AR_OBJECT_SAMPLER: \
  174. case AR_OBJECT_SAMPLER1D: \
  175. case AR_OBJECT_SAMPLER2D: \
  176. case AR_OBJECT_SAMPLER3D: \
  177. case AR_OBJECT_SAMPLERCUBE
  178. #define AR_BASIC_ROBJECT_CASES \
  179. case AR_OBJECT_BLEND: \
  180. case AR_OBJECT_RASTERIZER: \
  181. case AR_OBJECT_DEPTHSTENCIL: \
  182. case AR_OBJECT_STATEBLOCK
  183. //
  184. // Properties of entries in the ArBasicKind enumeration.
  185. // These properties are intended to allow easy identification
  186. // of classes of basic kinds. More specific checks on the
  187. // actual kind values could then be done.
  188. //
  189. // The first four bits are used as a subtype indicator,
  190. // such as bit count for primitive kinds or specific
  191. // types for non-primitive-data kinds.
  192. #define BPROP_SUBTYPE_MASK 0x0000000f
  193. // Bit counts must be ordered from smaller to larger.
  194. #define BPROP_BITS0 0x00000000
  195. #define BPROP_BITS8 0x00000001
  196. #define BPROP_BITS10 0x00000002
  197. #define BPROP_BITS12 0x00000003
  198. #define BPROP_BITS16 0x00000004
  199. #define BPROP_BITS32 0x00000005
  200. #define BPROP_BITS64 0x00000006
  201. #define BPROP_BITS_NON_PRIM 0x00000007
  202. #define GET_BPROP_SUBTYPE(_Props) ((_Props) & BPROP_SUBTYPE_MASK)
  203. #define GET_BPROP_BITS(_Props) ((_Props) & BPROP_SUBTYPE_MASK)
  204. #define BPROP_BOOLEAN 0x00000010 // Whether the type is bool
  205. #define BPROP_INTEGER 0x00000020 // Whether the type is an integer
  206. #define BPROP_UNSIGNED 0x00000040 // Whether the type is an unsigned numeric (its absence implies signed)
  207. #define BPROP_NUMERIC 0x00000080 // Whether the type is numeric or boolean
  208. #define BPROP_LITERAL 0x00000100 // Whether the type is a literal float or integer
  209. #define BPROP_FLOATING 0x00000200 // Whether the type is a float
  210. #define BPROP_OBJECT 0x00000400 // Whether the type is an object (including null or stream)
  211. #define BPROP_OTHER 0x00000800 // Whether the type is a pseudo-entry in another table.
  212. #define BPROP_PARTIAL_PRECISION 0x00001000 // Whether the type has partial precision for calculations (i.e., is this 'half')
  213. #define BPROP_POINTER 0x00002000 // Whether the type is a basic pointer.
  214. #define BPROP_TEXTURE 0x00004000 // Whether the type is any kind of texture.
  215. #define BPROP_SAMPLER 0x00008000 // Whether the type is any kind of sampler object.
  216. #define BPROP_STREAM 0x00010000 // Whether the type is a point, line or triangle stream.
  217. #define BPROP_PATCH 0x00020000 // Whether the type is an input or output patch.
  218. #define BPROP_RBUFFER 0x00040000 // Whether the type acts as a read-only buffer.
  219. #define BPROP_RWBUFFER 0x00080000 // Whether the type acts as a read-write buffer.
  220. #define BPROP_PRIMITIVE 0x00100000 // Whether the type is a primitive scalar type.
  221. #define BPROP_MIN_PRECISION 0x00200000 // Whether the type is qualified with a minimum precision.
  222. #define BPROP_ROVBUFFER 0x00400000 // Whether the type is a ROV object.
  223. #define BPROP_ENUM 0x00800000 // Whether the type is a enum
  224. #define GET_BPROP_PRIM_KIND(_Props) \
  225. ((_Props) & (BPROP_BOOLEAN | BPROP_INTEGER | BPROP_FLOATING))
  226. #define GET_BPROP_PRIM_KIND_SU(_Props) \
  227. ((_Props) & (BPROP_BOOLEAN | BPROP_INTEGER | BPROP_FLOATING | BPROP_UNSIGNED))
  228. #define IS_BPROP_PRIMITIVE(_Props) \
  229. (((_Props) & BPROP_PRIMITIVE) != 0)
  230. #define IS_BPROP_BOOL(_Props) \
  231. (((_Props) & BPROP_BOOLEAN) != 0)
  232. #define IS_BPROP_FLOAT(_Props) \
  233. (((_Props) & BPROP_FLOATING) != 0)
  234. #define IS_BPROP_SINT(_Props) \
  235. (((_Props) & (BPROP_INTEGER | BPROP_UNSIGNED | BPROP_BOOLEAN)) == \
  236. BPROP_INTEGER)
  237. #define IS_BPROP_UINT(_Props) \
  238. (((_Props) & (BPROP_INTEGER | BPROP_UNSIGNED | BPROP_BOOLEAN)) == \
  239. (BPROP_INTEGER | BPROP_UNSIGNED))
  240. #define IS_BPROP_AINT(_Props) \
  241. (((_Props) & (BPROP_INTEGER | BPROP_BOOLEAN)) == BPROP_INTEGER)
  242. #define IS_BPROP_STREAM(_Props) \
  243. (((_Props) & BPROP_STREAM) != 0)
  244. #define IS_BPROP_SAMPLER(_Props) \
  245. (((_Props) & BPROP_SAMPLER) != 0)
  246. #define IS_BPROP_TEXTURE(_Props) \
  247. (((_Props) & BPROP_TEXTURE) != 0)
  248. #define IS_BPROP_OBJECT(_Props) \
  249. (((_Props) & BPROP_OBJECT) != 0)
  250. #define IS_BPROP_MIN_PRECISION(_Props) \
  251. (((_Props) & BPROP_MIN_PRECISION) != 0)
  252. #define IS_BPROP_UNSIGNABLE(_Props) \
  253. (IS_BPROP_AINT(_Props) && GET_BPROP_BITS(_Props) != BPROP_BITS12)
  254. #define IS_BPROP_ENUM(_Props) \
  255. (((_Props) & BPROP_ENUM) != 0)
  256. const UINT g_uBasicKindProps[] =
  257. {
  258. BPROP_PRIMITIVE | BPROP_BOOLEAN | BPROP_INTEGER | BPROP_NUMERIC | BPROP_BITS0, // AR_BASIC_BOOL
  259. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_FLOATING | BPROP_LITERAL | BPROP_BITS0, // AR_BASIC_LITERAL_FLOAT
  260. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_FLOATING | BPROP_BITS16, // AR_BASIC_FLOAT16
  261. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_FLOATING | BPROP_BITS32 | BPROP_PARTIAL_PRECISION, // AR_BASIC_FLOAT32_PARTIAL_PRECISION
  262. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_FLOATING | BPROP_BITS32, // AR_BASIC_FLOAT32
  263. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_FLOATING | BPROP_BITS64, // AR_BASIC_FLOAT64
  264. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_INTEGER | BPROP_LITERAL | BPROP_BITS0, // AR_BASIC_LITERAL_INT
  265. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_INTEGER | BPROP_BITS8, // AR_BASIC_INT8
  266. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_INTEGER | BPROP_UNSIGNED | BPROP_BITS8, // AR_BASIC_UINT8
  267. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_INTEGER | BPROP_BITS16, // AR_BASIC_INT16
  268. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_INTEGER | BPROP_UNSIGNED | BPROP_BITS16,// AR_BASIC_UINT16
  269. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_INTEGER | BPROP_BITS32, // AR_BASIC_INT32
  270. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_INTEGER | BPROP_UNSIGNED | BPROP_BITS32,// AR_BASIC_UINT32
  271. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_INTEGER | BPROP_BITS64, // AR_BASIC_INT64
  272. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_INTEGER | BPROP_UNSIGNED | BPROP_BITS64,// AR_BASIC_UINT64
  273. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_FLOATING | BPROP_BITS10 | BPROP_MIN_PRECISION, // AR_BASIC_MIN10FLOAT
  274. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_FLOATING | BPROP_BITS16 | BPROP_MIN_PRECISION, // AR_BASIC_MIN16FLOAT
  275. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_INTEGER | BPROP_BITS12 | BPROP_MIN_PRECISION, // AR_BASIC_MIN12INT
  276. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_INTEGER | BPROP_BITS16 | BPROP_MIN_PRECISION, // AR_BASIC_MIN16INT
  277. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_INTEGER | BPROP_UNSIGNED | BPROP_BITS16 | BPROP_MIN_PRECISION, // AR_BASIC_MIN16UINT
  278. BPROP_ENUM | BPROP_NUMERIC | BPROP_INTEGER, // AR_BASIC_ENUM
  279. BPROP_OTHER, // AR_BASIC_COUNT
  280. //
  281. // Pseudo-entries for intrinsic tables and such.
  282. //
  283. 0, // AR_BASIC_NONE
  284. BPROP_OTHER, // AR_BASIC_UNKNOWN
  285. BPROP_OTHER, // AR_BASIC_NOCAST
  286. //
  287. // The following pseudo-entries represent higher-level
  288. // object types that are treated as units.
  289. //
  290. BPROP_POINTER, // AR_BASIC_POINTER
  291. BPROP_ENUM, // AR_BASIC_ENUM_CLASS
  292. BPROP_OBJECT | BPROP_RBUFFER, // AR_OBJECT_NULL
  293. BPROP_OBJECT | BPROP_RBUFFER, // AR_OBJECT_STRING
  294. // BPROP_OBJECT | BPROP_TEXTURE, // AR_OBJECT_TEXTURE
  295. BPROP_OBJECT | BPROP_TEXTURE, // AR_OBJECT_TEXTURE1D
  296. BPROP_OBJECT | BPROP_TEXTURE, // AR_OBJECT_TEXTURE1D_ARRAY
  297. BPROP_OBJECT | BPROP_TEXTURE, // AR_OBJECT_TEXTURE2D
  298. BPROP_OBJECT | BPROP_TEXTURE, // AR_OBJECT_TEXTURE2D_ARRAY
  299. BPROP_OBJECT | BPROP_TEXTURE, // AR_OBJECT_TEXTURE3D
  300. BPROP_OBJECT | BPROP_TEXTURE, // AR_OBJECT_TEXTURECUBE
  301. BPROP_OBJECT | BPROP_TEXTURE, // AR_OBJECT_TEXTURECUBE_ARRAY
  302. BPROP_OBJECT | BPROP_TEXTURE, // AR_OBJECT_TEXTURE2DMS
  303. BPROP_OBJECT | BPROP_TEXTURE, // AR_OBJECT_TEXTURE2DMS_ARRAY
  304. BPROP_OBJECT | BPROP_SAMPLER, // AR_OBJECT_SAMPLER
  305. BPROP_OBJECT | BPROP_SAMPLER, // AR_OBJECT_SAMPLER1D
  306. BPROP_OBJECT | BPROP_SAMPLER, // AR_OBJECT_SAMPLER2D
  307. BPROP_OBJECT | BPROP_SAMPLER, // AR_OBJECT_SAMPLER3D
  308. BPROP_OBJECT | BPROP_SAMPLER, // AR_OBJECT_SAMPLERCUBE
  309. BPROP_OBJECT | BPROP_SAMPLER, // AR_OBJECT_SAMPLERCOMPARISON
  310. BPROP_OBJECT | BPROP_RBUFFER, // AR_OBJECT_BUFFER
  311. BPROP_OBJECT, // AR_OBJECT_RENDERTARGETVIEW
  312. BPROP_OBJECT, // AR_OBJECT_DEPTHSTENCILVIEW
  313. BPROP_OBJECT, // AR_OBJECT_COMPUTESHADER
  314. BPROP_OBJECT, // AR_OBJECT_DOMAINSHADER
  315. BPROP_OBJECT, // AR_OBJECT_GEOMETRYSHADER
  316. BPROP_OBJECT, // AR_OBJECT_HULLSHADER
  317. BPROP_OBJECT, // AR_OBJECT_PIXELSHADER
  318. BPROP_OBJECT, // AR_OBJECT_VERTEXSHADER
  319. BPROP_OBJECT, // AR_OBJECT_PIXELFRAGMENT
  320. BPROP_OBJECT, // AR_OBJECT_VERTEXFRAGMENT
  321. BPROP_OBJECT, // AR_OBJECT_STATEBLOCK
  322. BPROP_OBJECT, // AR_OBJECT_RASTERIZER
  323. BPROP_OBJECT, // AR_OBJECT_DEPTHSTENCIL
  324. BPROP_OBJECT, // AR_OBJECT_BLEND
  325. BPROP_OBJECT | BPROP_STREAM, // AR_OBJECT_POINTSTREAM
  326. BPROP_OBJECT | BPROP_STREAM, // AR_OBJECT_LINESTREAM
  327. BPROP_OBJECT | BPROP_STREAM, // AR_OBJECT_TRIANGLESTREAM
  328. BPROP_OBJECT | BPROP_PATCH, // AR_OBJECT_INPUTPATCH
  329. BPROP_OBJECT | BPROP_PATCH, // AR_OBJECT_OUTPUTPATCH
  330. BPROP_OBJECT | BPROP_RWBUFFER, // AR_OBJECT_RWTEXTURE1D
  331. BPROP_OBJECT | BPROP_RWBUFFER, // AR_OBJECT_RWTEXTURE1D_ARRAY
  332. BPROP_OBJECT | BPROP_RWBUFFER, // AR_OBJECT_RWTEXTURE2D
  333. BPROP_OBJECT | BPROP_RWBUFFER, // AR_OBJECT_RWTEXTURE2D_ARRAY
  334. BPROP_OBJECT | BPROP_RWBUFFER, // AR_OBJECT_RWTEXTURE3D
  335. BPROP_OBJECT | BPROP_RWBUFFER, // AR_OBJECT_RWBUFFER
  336. BPROP_OBJECT | BPROP_RBUFFER, // AR_OBJECT_BYTEADDRESS_BUFFER
  337. BPROP_OBJECT | BPROP_RWBUFFER, // AR_OBJECT_RWBYTEADDRESS_BUFFER
  338. BPROP_OBJECT | BPROP_RBUFFER, // AR_OBJECT_STRUCTURED_BUFFER
  339. BPROP_OBJECT | BPROP_RWBUFFER, // AR_OBJECT_RWSTRUCTURED_BUFFER
  340. BPROP_OBJECT | BPROP_RWBUFFER, // AR_OBJECT_RWSTRUCTURED_BUFFER_ALLOC
  341. BPROP_OBJECT | BPROP_RWBUFFER, // AR_OBJECT_RWSTRUCTURED_BUFFER_CONSUME
  342. BPROP_OBJECT | BPROP_RWBUFFER, // AR_OBJECT_APPEND_STRUCTURED_BUFFER
  343. BPROP_OBJECT | BPROP_RWBUFFER, // AR_OBJECT_CONSUME_STRUCTURED_BUFFER
  344. BPROP_OBJECT | BPROP_RBUFFER, // AR_OBJECT_CONSTANT_BUFFER
  345. BPROP_OBJECT | BPROP_RBUFFER, // AR_OBJECT_TEXTURE_BUFFER
  346. BPROP_OBJECT | BPROP_RWBUFFER | BPROP_ROVBUFFER, // AR_OBJECT_ROVBUFFER
  347. BPROP_OBJECT | BPROP_RWBUFFER | BPROP_ROVBUFFER, // AR_OBJECT_ROVBYTEADDRESS_BUFFER
  348. BPROP_OBJECT | BPROP_RWBUFFER | BPROP_ROVBUFFER, // AR_OBJECT_ROVSTRUCTURED_BUFFER
  349. BPROP_OBJECT | BPROP_RWBUFFER | BPROP_ROVBUFFER, // AR_OBJECT_ROVTEXTURE1D
  350. BPROP_OBJECT | BPROP_RWBUFFER | BPROP_ROVBUFFER, // AR_OBJECT_ROVTEXTURE1D_ARRAY
  351. BPROP_OBJECT | BPROP_RWBUFFER | BPROP_ROVBUFFER, // AR_OBJECT_ROVTEXTURE2D
  352. BPROP_OBJECT | BPROP_RWBUFFER | BPROP_ROVBUFFER, // AR_OBJECT_ROVTEXTURE2D_ARRAY
  353. BPROP_OBJECT | BPROP_RWBUFFER | BPROP_ROVBUFFER, // AR_OBJECT_ROVTEXTURE3D
  354. // SPIRV change starts
  355. #ifdef ENABLE_SPIRV_CODEGEN
  356. BPROP_OBJECT | BPROP_RBUFFER, // AR_OBJECT_VK_SUBPASS_INPUT
  357. BPROP_OBJECT | BPROP_RBUFFER, // AR_OBJECT_VK_SUBPASS_INPUT_MS
  358. #endif // ENABLE_SPIRV_CODEGEN
  359. // SPIRV change ends
  360. BPROP_OBJECT, // AR_OBJECT_INNER
  361. BPROP_OBJECT, // AR_OBJECT_LEGACY_EFFECT
  362. BPROP_OBJECT, // AR_OBJECT_WAVE
  363. // AR_BASIC_MAXIMUM_COUNT
  364. };
  365. C_ASSERT(ARRAYSIZE(g_uBasicKindProps) == AR_BASIC_MAXIMUM_COUNT);
  366. #define GetBasicKindProps(_Kind) g_uBasicKindProps[(_Kind)]
  367. #define GET_BASIC_BITS(_Kind) \
  368. GET_BPROP_BITS(GetBasicKindProps(_Kind))
  369. #define GET_BASIC_PRIM_KIND(_Kind) \
  370. GET_BPROP_PRIM_KIND(GetBasicKindProps(_Kind))
  371. #define GET_BASIC_PRIM_KIND_SU(_Kind) \
  372. GET_BPROP_PRIM_KIND_SU(GetBasicKindProps(_Kind))
  373. #define IS_BASIC_PRIMITIVE(_Kind) \
  374. IS_BPROP_PRIMITIVE(GetBasicKindProps(_Kind))
  375. #define IS_BASIC_BOOL(_Kind) \
  376. IS_BPROP_BOOL(GetBasicKindProps(_Kind))
  377. #define IS_BASIC_FLOAT(_Kind) \
  378. IS_BPROP_FLOAT(GetBasicKindProps(_Kind))
  379. #define IS_BASIC_SINT(_Kind) \
  380. IS_BPROP_SINT(GetBasicKindProps(_Kind))
  381. #define IS_BASIC_UINT(_Kind) \
  382. IS_BPROP_UINT(GetBasicKindProps(_Kind))
  383. #define IS_BASIC_AINT(_Kind) \
  384. IS_BPROP_AINT(GetBasicKindProps(_Kind))
  385. #define IS_BASIC_STREAM(_Kind) \
  386. IS_BPROP_STREAM(GetBasicKindProps(_Kind))
  387. #define IS_BASIC_SAMPLER(_Kind) \
  388. IS_BPROP_SAMPLER(GetBasicKindProps(_Kind))
  389. #define IS_BASIC_TEXTURE(_Kind) \
  390. IS_BPROP_TEXTURE(GetBasicKindProps(_Kind))
  391. #define IS_BASIC_OBJECT(_Kind) \
  392. IS_BPROP_OBJECT(GetBasicKindProps(_Kind))
  393. #define IS_BASIC_MIN_PRECISION(_Kind) \
  394. IS_BPROP_MIN_PRECISION(GetBasicKindProps(_Kind))
  395. #define IS_BASIC_UNSIGNABLE(_Kind) \
  396. IS_BPROP_UNSIGNABLE(GetBasicKindProps(_Kind))
  397. #define IS_BASIC_ENUM(_Kind) \
  398. IS_BPROP_ENUM(GetBasicKindProps(_Kind))
  399. #define BITWISE_ENUM_OPS(_Type) \
  400. inline _Type operator|(_Type F1, _Type F2) \
  401. { \
  402. return (_Type)((UINT)F1 | (UINT)F2); \
  403. } \
  404. inline _Type operator&(_Type F1, _Type F2) \
  405. { \
  406. return (_Type)((UINT)F1 & (UINT)F2); \
  407. } \
  408. inline _Type& operator|=(_Type& F1, _Type F2) \
  409. { \
  410. F1 = F1 | F2; \
  411. return F1; \
  412. } \
  413. inline _Type& operator&=(_Type& F1, _Type F2) \
  414. { \
  415. F1 = F1 & F2; \
  416. return F1; \
  417. } \
  418. inline _Type& operator&=(_Type& F1, UINT F2) \
  419. { \
  420. F1 = (_Type)((UINT)F1 & F2); \
  421. return F1; \
  422. }
  423. enum ArTypeObjectKind {
  424. AR_TOBJ_INVALID, // Flag for an unassigned / unavailable object type.
  425. AR_TOBJ_VOID, // Represents the type for functions with not returned valued.
  426. AR_TOBJ_BASIC, // Represents a primitive type.
  427. AR_TOBJ_COMPOUND, // Represents a struct or class.
  428. AR_TOBJ_INTERFACE, // Represents an interface.
  429. AR_TOBJ_POINTER, // Represents a pointer to another type.
  430. AR_TOBJ_OBJECT, // Represents a built-in object.
  431. AR_TOBJ_ARRAY, // Represents an array of other types.
  432. AR_TOBJ_MATRIX, // Represents a matrix of basic types.
  433. AR_TOBJ_VECTOR, // Represents a vector of basic types.
  434. AR_TOBJ_QUALIFIER, // Represents another type plus an ArTypeQualifier.
  435. AR_TOBJ_INNER_OBJ, // Represents a built-in inner object, such as an
  436. // indexer object used to implement .mips[1].
  437. };
  438. enum TYPE_CONVERSION_FLAGS
  439. {
  440. TYPE_CONVERSION_DEFAULT = 0x00000000, // Indicates an implicit conversion is done.
  441. TYPE_CONVERSION_EXPLICIT = 0x00000001, // Indicates a conversion is done through an explicit cast.
  442. TYPE_CONVERSION_BY_REFERENCE = 0x00000002, // Indicates a conversion is done to an output parameter.
  443. };
  444. enum TYPE_CONVERSION_REMARKS
  445. {
  446. TYPE_CONVERSION_NONE = 0x00000000,
  447. TYPE_CONVERSION_PRECISION_LOSS = 0x00000001,
  448. TYPE_CONVERSION_IDENTICAL = 0x00000002,
  449. TYPE_CONVERSION_TO_VOID = 0x00000004,
  450. TYPE_CONVERSION_ELT_TRUNCATION = 0x00000008,
  451. };
  452. BITWISE_ENUM_OPS(TYPE_CONVERSION_REMARKS)
  453. #define AR_TOBJ_SCALAR AR_TOBJ_BASIC
  454. #define AR_TOBJ_UNKNOWN AR_TOBJ_INVALID
  455. #define AR_TPROP_VOID 0x0000000000000001
  456. #define AR_TPROP_CONST 0x0000000000000002
  457. #define AR_TPROP_IMP_CONST 0x0000000000000004
  458. #define AR_TPROP_OBJECT 0x0000000000000008
  459. #define AR_TPROP_SCALAR 0x0000000000000010
  460. #define AR_TPROP_UNSIGNED 0x0000000000000020
  461. #define AR_TPROP_NUMERIC 0x0000000000000040
  462. #define AR_TPROP_INTEGRAL 0x0000000000000080
  463. #define AR_TPROP_FLOATING 0x0000000000000100
  464. #define AR_TPROP_LITERAL 0x0000000000000200
  465. #define AR_TPROP_POINTER 0x0000000000000400
  466. #define AR_TPROP_INPUT_PATCH 0x0000000000000800
  467. #define AR_TPROP_OUTPUT_PATCH 0x0000000000001000
  468. #define AR_TPROP_INH_IFACE 0x0000000000002000
  469. #define AR_TPROP_HAS_COMPOUND 0x0000000000004000
  470. #define AR_TPROP_HAS_TEXTURES 0x0000000000008000
  471. #define AR_TPROP_HAS_SAMPLERS 0x0000000000010000
  472. #define AR_TPROP_HAS_SAMPLER_CMPS 0x0000000000020000
  473. #define AR_TPROP_HAS_STREAMS 0x0000000000040000
  474. #define AR_TPROP_HAS_OTHER_OBJECTS 0x0000000000080000
  475. #define AR_TPROP_HAS_BASIC 0x0000000000100000
  476. #define AR_TPROP_HAS_BUFFERS 0x0000000000200000
  477. #define AR_TPROP_HAS_ROBJECTS 0x0000000000400000
  478. #define AR_TPROP_HAS_POINTERS 0x0000000000800000
  479. #define AR_TPROP_INDEXABLE 0x0000000001000000
  480. #define AR_TPROP_HAS_MIPS 0x0000000002000000
  481. #define AR_TPROP_WRITABLE_GLOBAL 0x0000000004000000
  482. #define AR_TPROP_HAS_UAVS 0x0000000008000000
  483. #define AR_TPROP_HAS_BYTEADDRESS 0x0000000010000000
  484. #define AR_TPROP_HAS_STRUCTURED 0x0000000020000000
  485. #define AR_TPROP_HAS_SAMPLE 0x0000000040000000
  486. #define AR_TPROP_MIN_PRECISION 0x0000000080000000
  487. #define AR_TPROP_HAS_CBUFFERS 0x0000000100008000
  488. #define AR_TPROP_HAS_TBUFFERS 0x0000000200008000
  489. #define AR_TPROP_ALL 0xffffffffffffffff
  490. #define AR_TPROP_HAS_OBJECTS \
  491. (AR_TPROP_HAS_TEXTURES | AR_TPROP_HAS_SAMPLERS | \
  492. AR_TPROP_HAS_SAMPLER_CMPS | AR_TPROP_HAS_STREAMS | \
  493. AR_TPROP_HAS_OTHER_OBJECTS | AR_TPROP_HAS_BUFFERS | \
  494. AR_TPROP_HAS_ROBJECTS | AR_TPROP_HAS_UAVS | \
  495. AR_TPROP_HAS_BYTEADDRESS | AR_TPROP_HAS_STRUCTURED)
  496. #define AR_TPROP_HAS_BASIC_RESOURCES \
  497. (AR_TPROP_HAS_TEXTURES | AR_TPROP_HAS_SAMPLERS | \
  498. AR_TPROP_HAS_SAMPLER_CMPS | AR_TPROP_HAS_BUFFERS | \
  499. AR_TPROP_HAS_UAVS)
  500. #define AR_TPROP_UNION_BITS \
  501. (AR_TPROP_INH_IFACE | AR_TPROP_HAS_COMPOUND | AR_TPROP_HAS_TEXTURES | \
  502. AR_TPROP_HAS_SAMPLERS | AR_TPROP_HAS_SAMPLER_CMPS | \
  503. AR_TPROP_HAS_STREAMS | AR_TPROP_HAS_OTHER_OBJECTS | AR_TPROP_HAS_BASIC | \
  504. AR_TPROP_HAS_BUFFERS | AR_TPROP_HAS_ROBJECTS | AR_TPROP_HAS_POINTERS | \
  505. AR_TPROP_WRITABLE_GLOBAL | AR_TPROP_HAS_UAVS | \
  506. AR_TPROP_HAS_BYTEADDRESS | AR_TPROP_HAS_STRUCTURED | AR_TPROP_MIN_PRECISION)
  507. #define AR_TINFO_ALLOW_COMPLEX 0x00000001
  508. #define AR_TINFO_ALLOW_OBJECTS 0x00000002
  509. #define AR_TINFO_IGNORE_QUALIFIERS 0x00000004
  510. #define AR_TINFO_OBJECTS_AS_ELEMENTS 0x00000008
  511. #define AR_TINFO_PACK_SCALAR 0x00000010
  512. #define AR_TINFO_PACK_ROW_MAJOR 0x00000020
  513. #define AR_TINFO_PACK_TEMP_ARRAY 0x00000040
  514. #define AR_TINFO_ALL_VAR_INFO 0x00000080
  515. #define AR_TINFO_ALLOW_ALL (AR_TINFO_ALLOW_COMPLEX | AR_TINFO_ALLOW_OBJECTS)
  516. #define AR_TINFO_PACK_CBUFFER 0
  517. #define AR_TINFO_LAYOUT_PACK_ALL (AR_TINFO_PACK_SCALAR | AR_TINFO_PACK_TEMP_ARRAY)
  518. #define AR_TINFO_SIMPLE_OBJECTS \
  519. (AR_TINFO_ALLOW_OBJECTS | AR_TINFO_OBJECTS_AS_ELEMENTS)
  520. struct ArTypeInfo {
  521. ArTypeObjectKind ShapeKind; // The shape of the type (basic, matrix, etc.)
  522. ArBasicKind EltKind; // The primitive type of elements in this type.
  523. ArBasicKind ObjKind; // The object type for this type (textures, buffers, etc.)
  524. UINT uRows;
  525. UINT uCols;
  526. UINT uTotalElts;
  527. };
  528. using namespace clang;
  529. using namespace clang::sema;
  530. using namespace hlsl;
  531. extern const char *HLSLScalarTypeNames[];
  532. static const bool ExplicitConversionFalse = false;// a conversion operation is not the result of an explicit cast
  533. static const bool ParameterPackFalse = false; // template parameter is not an ellipsis.
  534. static const bool TypenameTrue = false; // 'typename' specified rather than 'class' for a template argument.
  535. static const SourceLocation NoLoc; // no source location attribution available
  536. static const SourceRange NoRange; // no source range attribution available
  537. static const bool HasWrittenPrototypeTrue = true; // function had the prototype written
  538. static const bool InlineSpecifiedFalse = false; // function was not specified as inline
  539. static const bool IsConstexprFalse = false; // function is not constexpr
  540. static const bool ListInitializationFalse = false;// not performing a list initialization
  541. static const bool SuppressWarningsFalse = false; // do not suppress warning diagnostics
  542. static const bool SuppressErrorsTrue = true; // suppress error diagnostics
  543. static const int OneRow = 1; // a single row for a type
  544. static const bool MipsFalse = false; // a type does not support the .mips member
  545. static const bool MipsTrue = true; // a type supports the .mips member
  546. static const bool SampleFalse = false; // a type does not support the .sample member
  547. static const bool SampleTrue = true; // a type supports the .sample member
  548. static const size_t MaxVectorSize = 4; // maximum size for a vector
  549. static
  550. QualType GetOrCreateTemplateSpecialization(
  551. ASTContext& context,
  552. Sema& sema,
  553. _In_ ClassTemplateDecl* templateDecl,
  554. ArrayRef<TemplateArgument> templateArgs
  555. )
  556. {
  557. DXASSERT_NOMSG(templateDecl);
  558. DeclContext* currentDeclContext = context.getTranslationUnitDecl();
  559. SmallVector<TemplateArgument, 3> templateArgsForDecl;
  560. for (const TemplateArgument& Arg : templateArgs) {
  561. if (Arg.getKind() == TemplateArgument::Type) {
  562. // the class template need to use CanonicalType
  563. templateArgsForDecl.emplace_back(TemplateArgument(Arg.getAsType().getCanonicalType()));
  564. }else
  565. templateArgsForDecl.emplace_back(Arg);
  566. }
  567. // First, try looking up existing specialization
  568. void* InsertPos = nullptr;
  569. ClassTemplateSpecializationDecl* specializationDecl =
  570. templateDecl->findSpecialization(templateArgsForDecl, InsertPos);
  571. if (specializationDecl) {
  572. // Instantiate the class template if not yet.
  573. if (specializationDecl->getInstantiatedFrom().isNull()) {
  574. // InstantiateClassTemplateSpecialization returns true if it finds an
  575. // error.
  576. DXVERIFY_NOMSG(false ==
  577. sema.InstantiateClassTemplateSpecialization(
  578. NoLoc, specializationDecl,
  579. TemplateSpecializationKind::TSK_ImplicitInstantiation,
  580. true));
  581. }
  582. return context.getTemplateSpecializationType(
  583. TemplateName(templateDecl), templateArgs.data(), templateArgs.size(),
  584. context.getTypeDeclType(specializationDecl));
  585. }
  586. specializationDecl = ClassTemplateSpecializationDecl::Create(
  587. context, TagDecl::TagKind::TTK_Class, currentDeclContext, NoLoc, NoLoc,
  588. templateDecl, templateArgsForDecl.data(), templateArgsForDecl.size(), nullptr);
  589. // InstantiateClassTemplateSpecialization returns true if it finds an error.
  590. DXVERIFY_NOMSG(false == sema.InstantiateClassTemplateSpecialization(
  591. NoLoc, specializationDecl, TemplateSpecializationKind::TSK_ImplicitInstantiation, true));
  592. templateDecl->AddSpecialization(specializationDecl, InsertPos);
  593. specializationDecl->setImplicit(true);
  594. QualType canonType = context.getTypeDeclType(specializationDecl);
  595. DXASSERT(isa<RecordType>(canonType), "type of non-dependent specialization is not a RecordType");
  596. TemplateArgumentListInfo templateArgumentList(NoLoc, NoLoc);
  597. TemplateArgumentLocInfo NoTemplateArgumentLocInfo;
  598. for (unsigned i = 0; i < templateArgs.size(); i++) {
  599. templateArgumentList.addArgument(TemplateArgumentLoc(templateArgs[i], NoTemplateArgumentLocInfo));
  600. }
  601. return context.getTemplateSpecializationType(
  602. TemplateName(templateDecl), templateArgumentList, canonType);
  603. }
  604. /// <summary>Instantiates a new matrix type specialization or gets an existing one from the AST.</summary>
  605. static
  606. QualType GetOrCreateMatrixSpecialization(ASTContext& context, Sema* sema,
  607. _In_ ClassTemplateDecl* matrixTemplateDecl,
  608. QualType elementType, uint64_t rowCount, uint64_t colCount)
  609. {
  610. DXASSERT_NOMSG(sema);
  611. TemplateArgument templateArgs[3] = {
  612. TemplateArgument(elementType),
  613. TemplateArgument(
  614. context,
  615. llvm::APSInt(
  616. llvm::APInt(context.getIntWidth(context.IntTy), rowCount), false),
  617. context.IntTy),
  618. TemplateArgument(
  619. context,
  620. llvm::APSInt(
  621. llvm::APInt(context.getIntWidth(context.IntTy), colCount), false),
  622. context.IntTy)};
  623. QualType matrixSpecializationType = GetOrCreateTemplateSpecialization(context, *sema, matrixTemplateDecl, ArrayRef<TemplateArgument>(templateArgs));
  624. #ifdef DBG
  625. // Verify that we can read the field member from the template record.
  626. DXASSERT(matrixSpecializationType->getAsCXXRecordDecl(),
  627. "type of non-dependent specialization is not a RecordType");
  628. DeclContext::lookup_result lookupResult = matrixSpecializationType->getAsCXXRecordDecl()->
  629. lookup(DeclarationName(&context.Idents.get(StringRef("h"))));
  630. DXASSERT(!lookupResult.empty(), "otherwise matrix handle cannot be looked up");
  631. #endif
  632. return matrixSpecializationType;
  633. }
  634. /// <summary>Instantiates a new vector type specialization or gets an existing one from the AST.</summary>
  635. static
  636. QualType GetOrCreateVectorSpecialization(ASTContext& context, Sema* sema,
  637. _In_ ClassTemplateDecl* vectorTemplateDecl,
  638. QualType elementType, uint64_t colCount)
  639. {
  640. DXASSERT_NOMSG(sema);
  641. DXASSERT_NOMSG(vectorTemplateDecl);
  642. TemplateArgument templateArgs[2] = {
  643. TemplateArgument(elementType),
  644. TemplateArgument(
  645. context,
  646. llvm::APSInt(
  647. llvm::APInt(context.getIntWidth(context.IntTy), colCount), false),
  648. context.IntTy)};
  649. QualType vectorSpecializationType = GetOrCreateTemplateSpecialization(context, *sema, vectorTemplateDecl, ArrayRef<TemplateArgument>(templateArgs));
  650. #ifdef DBG
  651. // Verify that we can read the field member from the template record.
  652. DXASSERT(vectorSpecializationType->getAsCXXRecordDecl(),
  653. "type of non-dependent specialization is not a RecordType");
  654. DeclContext::lookup_result lookupResult = vectorSpecializationType->getAsCXXRecordDecl()->
  655. lookup(DeclarationName(&context.Idents.get(StringRef("h"))));
  656. DXASSERT(!lookupResult.empty(), "otherwise vector handle cannot be looked up");
  657. #endif
  658. return vectorSpecializationType;
  659. }
  660. // Decls.cpp constants start here - these should be refactored or, better, replaced with clang::Type-based constructs.
  661. static const LPCSTR kBuiltinIntrinsicTableName = "op";
  662. static const unsigned kAtomicDstOperandIdx = 1;
  663. static const ArTypeObjectKind g_ScalarTT[] =
  664. {
  665. AR_TOBJ_SCALAR,
  666. AR_TOBJ_UNKNOWN
  667. };
  668. static const ArTypeObjectKind g_VectorTT[] =
  669. {
  670. AR_TOBJ_VECTOR,
  671. AR_TOBJ_UNKNOWN
  672. };
  673. static const ArTypeObjectKind g_MatrixTT[] =
  674. {
  675. AR_TOBJ_MATRIX,
  676. AR_TOBJ_UNKNOWN
  677. };
  678. static const ArTypeObjectKind g_AnyTT[] =
  679. {
  680. AR_TOBJ_SCALAR,
  681. AR_TOBJ_VECTOR,
  682. AR_TOBJ_MATRIX,
  683. AR_TOBJ_UNKNOWN
  684. };
  685. static const ArTypeObjectKind g_ObjectTT[] =
  686. {
  687. AR_TOBJ_OBJECT,
  688. AR_TOBJ_UNKNOWN
  689. };
  690. static const ArTypeObjectKind g_NullTT[] =
  691. {
  692. AR_TOBJ_VOID,
  693. AR_TOBJ_UNKNOWN
  694. };
  695. const ArTypeObjectKind* g_LegalIntrinsicTemplates[] =
  696. {
  697. g_NullTT,
  698. g_ScalarTT,
  699. g_VectorTT,
  700. g_MatrixTT,
  701. g_AnyTT,
  702. g_ObjectTT,
  703. };
  704. C_ASSERT(ARRAYSIZE(g_LegalIntrinsicTemplates) == LITEMPLATE_COUNT);
  705. //
  706. // The first one is used to name the representative group, so make
  707. // sure its name will make sense in error messages.
  708. //
  709. static const ArBasicKind g_BoolCT[] =
  710. {
  711. AR_BASIC_BOOL,
  712. AR_BASIC_UNKNOWN
  713. };
  714. static const ArBasicKind g_IntCT[] =
  715. {
  716. AR_BASIC_INT32,
  717. AR_BASIC_LITERAL_INT,
  718. AR_BASIC_UNKNOWN
  719. };
  720. static const ArBasicKind g_UIntCT[] =
  721. {
  722. AR_BASIC_UINT32,
  723. AR_BASIC_LITERAL_INT,
  724. AR_BASIC_UNKNOWN
  725. };
  726. // We use the first element for default if matching kind is missing in the list.
  727. // AR_BASIC_INT32 should be the default for any int since min precision integers should map to int32, not int16 or int64
  728. static const ArBasicKind g_AnyIntCT[] =
  729. {
  730. AR_BASIC_INT32,
  731. AR_BASIC_INT16,
  732. AR_BASIC_UINT32,
  733. AR_BASIC_UINT16,
  734. AR_BASIC_INT64,
  735. AR_BASIC_UINT64,
  736. AR_BASIC_LITERAL_INT,
  737. AR_BASIC_UNKNOWN
  738. };
  739. static const ArBasicKind g_AnyInt32CT[] =
  740. {
  741. AR_BASIC_INT32,
  742. AR_BASIC_UINT32,
  743. AR_BASIC_LITERAL_INT,
  744. AR_BASIC_UNKNOWN
  745. };
  746. static const ArBasicKind g_UIntOnlyCT[] =
  747. {
  748. AR_BASIC_UINT32,
  749. AR_BASIC_UINT64,
  750. AR_BASIC_LITERAL_INT,
  751. AR_BASIC_NOCAST,
  752. AR_BASIC_UNKNOWN
  753. };
  754. static const ArBasicKind g_FloatCT[] =
  755. {
  756. AR_BASIC_FLOAT32,
  757. AR_BASIC_FLOAT32_PARTIAL_PRECISION,
  758. AR_BASIC_LITERAL_FLOAT,
  759. AR_BASIC_UNKNOWN
  760. };
  761. static const ArBasicKind g_AnyFloatCT[] =
  762. {
  763. AR_BASIC_FLOAT32,
  764. AR_BASIC_FLOAT32_PARTIAL_PRECISION,
  765. AR_BASIC_FLOAT16,
  766. AR_BASIC_FLOAT64,
  767. AR_BASIC_LITERAL_FLOAT,
  768. AR_BASIC_MIN10FLOAT,
  769. AR_BASIC_MIN16FLOAT,
  770. AR_BASIC_UNKNOWN
  771. };
  772. static const ArBasicKind g_FloatLikeCT[] =
  773. {
  774. AR_BASIC_FLOAT32,
  775. AR_BASIC_FLOAT32_PARTIAL_PRECISION,
  776. AR_BASIC_FLOAT16,
  777. AR_BASIC_LITERAL_FLOAT,
  778. AR_BASIC_MIN10FLOAT,
  779. AR_BASIC_MIN16FLOAT,
  780. AR_BASIC_UNKNOWN
  781. };
  782. static const ArBasicKind g_FloatDoubleCT[] =
  783. {
  784. AR_BASIC_FLOAT32,
  785. AR_BASIC_FLOAT32_PARTIAL_PRECISION,
  786. AR_BASIC_FLOAT64,
  787. AR_BASIC_LITERAL_FLOAT,
  788. AR_BASIC_UNKNOWN
  789. };
  790. static const ArBasicKind g_DoubleCT[] =
  791. {
  792. AR_BASIC_FLOAT64,
  793. AR_BASIC_LITERAL_FLOAT,
  794. AR_BASIC_UNKNOWN
  795. };
  796. static const ArBasicKind g_DoubleOnlyCT[] =
  797. {
  798. AR_BASIC_FLOAT64,
  799. AR_BASIC_NOCAST,
  800. AR_BASIC_UNKNOWN
  801. };
  802. static const ArBasicKind g_NumericCT[] =
  803. {
  804. AR_BASIC_LITERAL_FLOAT,
  805. AR_BASIC_FLOAT32,
  806. AR_BASIC_FLOAT32_PARTIAL_PRECISION,
  807. AR_BASIC_FLOAT16,
  808. AR_BASIC_FLOAT64,
  809. AR_BASIC_MIN10FLOAT,
  810. AR_BASIC_MIN16FLOAT,
  811. AR_BASIC_LITERAL_INT,
  812. AR_BASIC_INT16,
  813. AR_BASIC_INT32,
  814. AR_BASIC_UINT16,
  815. AR_BASIC_UINT32,
  816. AR_BASIC_MIN12INT,
  817. AR_BASIC_MIN16INT,
  818. AR_BASIC_MIN16UINT,
  819. AR_BASIC_INT64,
  820. AR_BASIC_UINT64,
  821. AR_BASIC_UNKNOWN
  822. };
  823. static const ArBasicKind g_Numeric32CT[] =
  824. {
  825. AR_BASIC_LITERAL_FLOAT,
  826. AR_BASIC_FLOAT32,
  827. AR_BASIC_FLOAT32_PARTIAL_PRECISION,
  828. AR_BASIC_LITERAL_INT,
  829. AR_BASIC_INT32,
  830. AR_BASIC_UINT32,
  831. AR_BASIC_UNKNOWN
  832. };
  833. static const ArBasicKind g_Numeric32OnlyCT[] =
  834. {
  835. AR_BASIC_LITERAL_FLOAT,
  836. AR_BASIC_FLOAT32,
  837. AR_BASIC_FLOAT32_PARTIAL_PRECISION,
  838. AR_BASIC_LITERAL_INT,
  839. AR_BASIC_INT32,
  840. AR_BASIC_UINT32,
  841. AR_BASIC_NOCAST,
  842. AR_BASIC_UNKNOWN
  843. };
  844. static const ArBasicKind g_AnyCT[] =
  845. {
  846. AR_BASIC_LITERAL_FLOAT,
  847. AR_BASIC_FLOAT32,
  848. AR_BASIC_FLOAT32_PARTIAL_PRECISION,
  849. AR_BASIC_FLOAT16,
  850. AR_BASIC_FLOAT64,
  851. AR_BASIC_MIN10FLOAT,
  852. AR_BASIC_MIN16FLOAT,
  853. AR_BASIC_LITERAL_INT,
  854. AR_BASIC_INT16,
  855. AR_BASIC_UINT16,
  856. AR_BASIC_INT32,
  857. AR_BASIC_UINT32,
  858. AR_BASIC_MIN12INT,
  859. AR_BASIC_MIN16INT,
  860. AR_BASIC_MIN16UINT,
  861. AR_BASIC_BOOL,
  862. AR_BASIC_INT64,
  863. AR_BASIC_UINT64,
  864. AR_BASIC_UNKNOWN
  865. };
  866. static const ArBasicKind g_Sampler1DCT[] =
  867. {
  868. AR_OBJECT_SAMPLER1D,
  869. AR_BASIC_UNKNOWN
  870. };
  871. static const ArBasicKind g_Sampler2DCT[] =
  872. {
  873. AR_OBJECT_SAMPLER2D,
  874. AR_BASIC_UNKNOWN
  875. };
  876. static const ArBasicKind g_Sampler3DCT[] =
  877. {
  878. AR_OBJECT_SAMPLER3D,
  879. AR_BASIC_UNKNOWN
  880. };
  881. static const ArBasicKind g_SamplerCUBECT[] =
  882. {
  883. AR_OBJECT_SAMPLERCUBE,
  884. AR_BASIC_UNKNOWN
  885. };
  886. static const ArBasicKind g_SamplerCmpCT[] =
  887. {
  888. AR_OBJECT_SAMPLERCOMPARISON,
  889. AR_BASIC_UNKNOWN
  890. };
  891. static const ArBasicKind g_SamplerCT[] =
  892. {
  893. AR_OBJECT_SAMPLER,
  894. AR_BASIC_UNKNOWN
  895. };
  896. static const ArBasicKind g_StringCT[] =
  897. {
  898. AR_OBJECT_STRING,
  899. AR_BASIC_UNKNOWN
  900. };
  901. static const ArBasicKind g_NullCT[] =
  902. {
  903. AR_OBJECT_NULL,
  904. AR_BASIC_UNKNOWN
  905. };
  906. static const ArBasicKind g_WaveCT[] =
  907. {
  908. AR_OBJECT_WAVE,
  909. AR_BASIC_UNKNOWN
  910. };
  911. static const ArBasicKind g_UInt64CT[] =
  912. {
  913. AR_BASIC_UINT64,
  914. AR_BASIC_UNKNOWN
  915. };
  916. static const ArBasicKind g_Float16CT[] =
  917. {
  918. AR_BASIC_FLOAT16,
  919. AR_BASIC_LITERAL_FLOAT,
  920. AR_BASIC_UNKNOWN
  921. };
  922. static const ArBasicKind g_Int16CT[] =
  923. {
  924. AR_BASIC_INT16,
  925. AR_BASIC_LITERAL_INT,
  926. AR_BASIC_UNKNOWN
  927. };
  928. static const ArBasicKind g_UInt16CT[] =
  929. {
  930. AR_BASIC_UINT16,
  931. AR_BASIC_LITERAL_INT,
  932. AR_BASIC_UNKNOWN
  933. };
  934. static const ArBasicKind g_Numeric16OnlyCT[] =
  935. {
  936. AR_BASIC_FLOAT16,
  937. AR_BASIC_INT16,
  938. AR_BASIC_UINT16,
  939. AR_BASIC_LITERAL_FLOAT,
  940. AR_BASIC_LITERAL_INT,
  941. AR_BASIC_NOCAST,
  942. AR_BASIC_UNKNOWN
  943. };
  944. // Basic kinds, indexed by a LEGAL_INTRINSIC_COMPTYPES value.
  945. const ArBasicKind* g_LegalIntrinsicCompTypes[] =
  946. {
  947. g_NullCT, // LICOMPTYPE_VOID
  948. g_BoolCT, // LICOMPTYPE_BOOL
  949. g_IntCT, // LICOMPTYPE_INT
  950. g_UIntCT, // LICOMPTYPE_UINT
  951. g_AnyIntCT, // LICOMPTYPE_ANY_INT
  952. g_AnyInt32CT, // LICOMPTYPE_ANY_INT32
  953. g_UIntOnlyCT, // LICOMPTYPE_UINT_ONLY
  954. g_FloatCT, // LICOMPTYPE_FLOAT
  955. g_AnyFloatCT, // LICOMPTYPE_ANY_FLOAT
  956. g_FloatLikeCT, // LICOMPTYPE_FLOAT_LIKE
  957. g_FloatDoubleCT, // LICOMPTYPE_FLOAT_DOUBLE
  958. g_DoubleCT, // LICOMPTYPE_DOUBLE
  959. g_DoubleOnlyCT, // LICOMPTYPE_DOUBLE_ONLY
  960. g_NumericCT, // LICOMPTYPE_NUMERIC
  961. g_Numeric32CT, // LICOMPTYPE_NUMERIC32
  962. g_Numeric32OnlyCT, // LICOMPTYPE_NUMERIC32_ONLY
  963. g_AnyCT, // LICOMPTYPE_ANY
  964. g_Sampler1DCT, // LICOMPTYPE_SAMPLER1D
  965. g_Sampler2DCT, // LICOMPTYPE_SAMPLER2D
  966. g_Sampler3DCT, // LICOMPTYPE_SAMPLER3D
  967. g_SamplerCUBECT, // LICOMPTYPE_SAMPLERCUBE
  968. g_SamplerCmpCT, // LICOMPTYPE_SAMPLERCMP
  969. g_SamplerCT, // LICOMPTYPE_SAMPLER
  970. g_StringCT, // LICOMPTYPE_STRING
  971. g_WaveCT, // LICOMPTYPE_WAVE
  972. g_UInt64CT, // LICOMPTYPE_UINT64
  973. g_Float16CT, // LICOMPTYPE_FLOAT16
  974. g_Int16CT, // LICOMPTYPE_INT16
  975. g_UInt16CT, // LICOMPTYPE_UINT16
  976. g_Numeric16OnlyCT // LICOMPTYPE_NUMERIC16_ONLY
  977. };
  978. C_ASSERT(ARRAYSIZE(g_LegalIntrinsicCompTypes) == LICOMPTYPE_COUNT);
  979. // Decls.cpp constants ends here - these should be refactored or, better, replaced with clang::Type-based constructs.
  980. // Basic kind objects that are represented as HLSL structures or templates.
  981. static
  982. const ArBasicKind g_ArBasicKindsAsTypes[] =
  983. {
  984. AR_OBJECT_BUFFER, // Buffer
  985. // AR_OBJECT_TEXTURE,
  986. AR_OBJECT_TEXTURE1D, // Texture1D
  987. AR_OBJECT_TEXTURE1D_ARRAY, // Texture1DArray
  988. AR_OBJECT_TEXTURE2D, // Texture2D
  989. AR_OBJECT_TEXTURE2D_ARRAY, // Texture2DArray
  990. AR_OBJECT_TEXTURE3D, // Texture3D
  991. AR_OBJECT_TEXTURECUBE, // TextureCube
  992. AR_OBJECT_TEXTURECUBE_ARRAY, // TextureCubeArray
  993. AR_OBJECT_TEXTURE2DMS, // Texture2DMS
  994. AR_OBJECT_TEXTURE2DMS_ARRAY, // Texture2DMSArray
  995. AR_OBJECT_SAMPLER,
  996. //AR_OBJECT_SAMPLER1D,
  997. //AR_OBJECT_SAMPLER2D,
  998. //AR_OBJECT_SAMPLER3D,
  999. //AR_OBJECT_SAMPLERCUBE,
  1000. AR_OBJECT_SAMPLERCOMPARISON,
  1001. AR_OBJECT_POINTSTREAM,
  1002. AR_OBJECT_LINESTREAM,
  1003. AR_OBJECT_TRIANGLESTREAM,
  1004. AR_OBJECT_INPUTPATCH,
  1005. AR_OBJECT_OUTPUTPATCH,
  1006. AR_OBJECT_RWTEXTURE1D,
  1007. AR_OBJECT_RWTEXTURE1D_ARRAY,
  1008. AR_OBJECT_RWTEXTURE2D,
  1009. AR_OBJECT_RWTEXTURE2D_ARRAY,
  1010. AR_OBJECT_RWTEXTURE3D,
  1011. AR_OBJECT_RWBUFFER,
  1012. AR_OBJECT_BYTEADDRESS_BUFFER,
  1013. AR_OBJECT_RWBYTEADDRESS_BUFFER,
  1014. AR_OBJECT_STRUCTURED_BUFFER,
  1015. AR_OBJECT_RWSTRUCTURED_BUFFER,
  1016. // AR_OBJECT_RWSTRUCTURED_BUFFER_ALLOC,
  1017. // AR_OBJECT_RWSTRUCTURED_BUFFER_CONSUME,
  1018. AR_OBJECT_APPEND_STRUCTURED_BUFFER,
  1019. AR_OBJECT_CONSUME_STRUCTURED_BUFFER,
  1020. AR_OBJECT_ROVBUFFER,
  1021. AR_OBJECT_ROVBYTEADDRESS_BUFFER,
  1022. AR_OBJECT_ROVSTRUCTURED_BUFFER,
  1023. AR_OBJECT_ROVTEXTURE1D,
  1024. AR_OBJECT_ROVTEXTURE1D_ARRAY,
  1025. AR_OBJECT_ROVTEXTURE2D,
  1026. AR_OBJECT_ROVTEXTURE2D_ARRAY,
  1027. AR_OBJECT_ROVTEXTURE3D,
  1028. // SPIRV change starts
  1029. #ifdef ENABLE_SPIRV_CODEGEN
  1030. AR_OBJECT_VK_SUBPASS_INPUT,
  1031. AR_OBJECT_VK_SUBPASS_INPUT_MS,
  1032. #endif // ENABLE_SPIRV_CODEGEN
  1033. // SPIRV change ends
  1034. AR_OBJECT_LEGACY_EFFECT, // Used for all unsupported but ignored legacy effect types
  1035. AR_OBJECT_WAVE
  1036. };
  1037. // Count of template arguments for basic kind of objects that look like templates (one or more type arguments).
  1038. static
  1039. const uint8_t g_ArBasicKindsTemplateCount[] =
  1040. {
  1041. 1, // AR_OBJECT_BUFFER
  1042. // AR_OBJECT_TEXTURE,
  1043. 1, // AR_OBJECT_TEXTURE1D
  1044. 1, // AR_OBJECT_TEXTURE1D_ARRAY
  1045. 1, // AR_OBJECT_TEXTURE2D
  1046. 1, // AR_OBJECT_TEXTURE2D_ARRAY
  1047. 1, // AR_OBJECT_TEXTURE3D
  1048. 1, // AR_OBJECT_TEXTURECUBE
  1049. 1, // AR_OBJECT_TEXTURECUBE_ARRAY
  1050. 2, // AR_OBJECT_TEXTURE2DMS
  1051. 2, // AR_OBJECT_TEXTURE2DMS_ARRAY
  1052. 0, // AR_OBJECT_SAMPLER
  1053. //AR_OBJECT_SAMPLER1D,
  1054. //AR_OBJECT_SAMPLER2D,
  1055. //AR_OBJECT_SAMPLER3D,
  1056. //AR_OBJECT_SAMPLERCUBE,
  1057. 0, // AR_OBJECT_SAMPLERCOMPARISON
  1058. 1, // AR_OBJECT_POINTSTREAM
  1059. 1, // AR_OBJECT_LINESTREAM
  1060. 1, // AR_OBJECT_TRIANGLESTREAM
  1061. 2, // AR_OBJECT_INPUTPATCH
  1062. 2, // AR_OBJECT_OUTPUTPATCH
  1063. 1, // AR_OBJECT_RWTEXTURE1D
  1064. 1, // AR_OBJECT_RWTEXTURE1D_ARRAY
  1065. 1, // AR_OBJECT_RWTEXTURE2D
  1066. 1, // AR_OBJECT_RWTEXTURE2D_ARRAY
  1067. 1, // AR_OBJECT_RWTEXTURE3D
  1068. 1, // AR_OBJECT_RWBUFFER
  1069. 0, // AR_OBJECT_BYTEADDRESS_BUFFER
  1070. 0, // AR_OBJECT_RWBYTEADDRESS_BUFFER
  1071. 1, // AR_OBJECT_STRUCTURED_BUFFER
  1072. 1, // AR_OBJECT_RWSTRUCTURED_BUFFER
  1073. // 1, // AR_OBJECT_RWSTRUCTURED_BUFFER_ALLOC
  1074. // 1, // AR_OBJECT_RWSTRUCTURED_BUFFER_CONSUME
  1075. 1, // AR_OBJECT_APPEND_STRUCTURED_BUFFER
  1076. 1, // AR_OBJECT_CONSUME_STRUCTURED_BUFFER
  1077. 1, // AR_OBJECT_ROVBUFFER
  1078. 0, // AR_OBJECT_ROVBYTEADDRESS_BUFFER
  1079. 1, // AR_OBJECT_ROVSTRUCTURED_BUFFER
  1080. 1, // AR_OBJECT_ROVTEXTURE1D
  1081. 1, // AR_OBJECT_ROVTEXTURE1D_ARRAY
  1082. 1, // AR_OBJECT_ROVTEXTURE2D
  1083. 1, // AR_OBJECT_ROVTEXTURE2D_ARRAY
  1084. 1, // AR_OBJECT_ROVTEXTURE3D
  1085. // SPIRV change starts
  1086. #ifdef ENABLE_SPIRV_CODEGEN
  1087. 1, // AR_OBJECT_VK_SUBPASS_INPUT
  1088. 1, // AR_OBJECT_VK_SUBPASS_INPUT_MS
  1089. #endif // ENABLE_SPIRV_CODEGEN
  1090. // SPIRV change ends
  1091. 0, // AR_OBJECT_LEGACY_EFFECT // Used for all unsupported but ignored legacy effect types
  1092. 0, // AR_OBJECT_WAVE
  1093. };
  1094. C_ASSERT(_countof(g_ArBasicKindsAsTypes) == _countof(g_ArBasicKindsTemplateCount));
  1095. /// <summary>Describes the how the subscript or indexing operators work on a given type.</summary>
  1096. struct SubscriptOperatorRecord
  1097. {
  1098. unsigned int SubscriptCardinality : 4; // Number of elements expected in subscript - zero if operator not supported.
  1099. bool HasMips : 1; // true if the kind has a mips member; false otherwise
  1100. bool HasSample : 1; // true if the kind has a sample member; false otherwise
  1101. };
  1102. // Subscript operators for objects that are represented as HLSL structures or templates.
  1103. static
  1104. const SubscriptOperatorRecord g_ArBasicKindsSubscripts[] =
  1105. {
  1106. { 1, MipsFalse, SampleFalse }, // AR_OBJECT_BUFFER (Buffer)
  1107. // AR_OBJECT_TEXTURE,
  1108. { 1, MipsTrue, SampleFalse }, // AR_OBJECT_TEXTURE1D (Texture1D)
  1109. { 2, MipsTrue, SampleFalse }, // AR_OBJECT_TEXTURE1D_ARRAY (Texture1DArray)
  1110. { 2, MipsTrue, SampleFalse }, // AR_OBJECT_TEXTURE2D (Texture2D)
  1111. { 3, MipsTrue, SampleFalse }, // AR_OBJECT_TEXTURE2D_ARRAY (Texture2DArray)
  1112. { 3, MipsTrue, SampleFalse }, // AR_OBJECT_TEXTURE3D (Texture3D)
  1113. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_TEXTURECUBE (TextureCube)
  1114. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_TEXTURECUBE_ARRAY (TextureCubeArray)
  1115. { 2, MipsFalse, SampleTrue }, // AR_OBJECT_TEXTURE2DMS (Texture2DMS)
  1116. { 3, MipsFalse, SampleTrue }, // AR_OBJECT_TEXTURE2DMS_ARRAY (Texture2DMSArray)
  1117. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_SAMPLER (SamplerState)
  1118. //AR_OBJECT_SAMPLER1D,
  1119. //AR_OBJECT_SAMPLER2D,
  1120. //AR_OBJECT_SAMPLER3D,
  1121. //AR_OBJECT_SAMPLERCUBE,
  1122. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_SAMPLERCOMPARISON (SamplerComparison)
  1123. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_POINTSTREAM (PointStream)
  1124. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_LINESTREAM (LineStream)
  1125. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_TRIANGLESTREAM (TriangleStream)
  1126. { 1, MipsFalse, SampleFalse }, // AR_OBJECT_INPUTPATCH (InputPatch)
  1127. { 1, MipsFalse, SampleFalse }, // AR_OBJECT_OUTPUTPATCH (OutputPatch)
  1128. { 1, MipsFalse, SampleFalse }, // AR_OBJECT_RWTEXTURE1D (RWTexture1D)
  1129. { 2, MipsFalse, SampleFalse }, // AR_OBJECT_RWTEXTURE1D_ARRAY (RWTexture1DArray)
  1130. { 2, MipsFalse, SampleFalse }, // AR_OBJECT_RWTEXTURE2D (RWTexture2D)
  1131. { 3, MipsFalse, SampleFalse }, // AR_OBJECT_RWTEXTURE2D_ARRAY (RWTexture2DArray)
  1132. { 3, MipsFalse, SampleFalse }, // AR_OBJECT_RWTEXTURE3D (RWTexture3D)
  1133. { 1, MipsFalse, SampleFalse }, // AR_OBJECT_RWBUFFER (RWBuffer)
  1134. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_BYTEADDRESS_BUFFER (ByteAddressBuffer)
  1135. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_RWBYTEADDRESS_BUFFER (RWByteAddressBuffer)
  1136. { 1, MipsFalse, SampleFalse }, // AR_OBJECT_STRUCTURED_BUFFER (StructuredBuffer)
  1137. { 1, MipsFalse, SampleFalse }, // AR_OBJECT_RWSTRUCTURED_BUFFER (RWStructuredBuffer)
  1138. // AR_OBJECT_RWSTRUCTURED_BUFFER_ALLOC,
  1139. // AR_OBJECT_RWSTRUCTURED_BUFFER_CONSUME,
  1140. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_APPEND_STRUCTURED_BUFFER (AppendStructuredBuffer)
  1141. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_CONSUME_STRUCTURED_BUFFER (ConsumeStructuredBuffer)
  1142. { 1, MipsFalse, SampleFalse }, // AR_OBJECT_ROVBUFFER (ROVBuffer)
  1143. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_ROVBYTEADDRESS_BUFFER (ROVByteAddressBuffer)
  1144. { 1, MipsFalse, SampleFalse }, // AR_OBJECT_ROVSTRUCTURED_BUFFER (ROVStructuredBuffer)
  1145. { 1, MipsFalse, SampleFalse }, // AR_OBJECT_ROVTEXTURE1D (ROVTexture1D)
  1146. { 2, MipsFalse, SampleFalse }, // AR_OBJECT_ROVTEXTURE1D_ARRAY (ROVTexture1DArray)
  1147. { 2, MipsFalse, SampleFalse }, // AR_OBJECT_ROVTEXTURE2D (ROVTexture2D)
  1148. { 3, MipsFalse, SampleFalse }, // AR_OBJECT_ROVTEXTURE2D_ARRAY (ROVTexture2DArray)
  1149. { 3, MipsFalse, SampleFalse }, // AR_OBJECT_ROVTEXTURE3D (ROVTexture3D)
  1150. // SPIRV change starts
  1151. #ifdef ENABLE_SPIRV_CODEGEN
  1152. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_VK_SUBPASS_INPUT (SubpassInput)
  1153. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_VK_SUBPASS_INPUT_MS (SubpassInputMS)
  1154. #endif // ENABLE_SPIRV_CODEGEN
  1155. // SPIRV change ends
  1156. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_LEGACY_EFFECT (legacy effect objects)
  1157. { 0, MipsFalse, SampleFalse } // AR_OBJECT_WAVE
  1158. };
  1159. C_ASSERT(_countof(g_ArBasicKindsAsTypes) == _countof(g_ArBasicKindsSubscripts));
  1160. // Type names for ArBasicKind values.
  1161. static
  1162. const char* g_ArBasicTypeNames[] =
  1163. {
  1164. "bool", "float", "half", "half", "float", "double",
  1165. "int", "sbyte", "byte", "short", "ushort",
  1166. "int", "uint", "long", "ulong",
  1167. "min10float", "min16float",
  1168. "min12int", "min16int", "min16uint",
  1169. "enum",
  1170. "<count>",
  1171. "<none>",
  1172. "<unknown>",
  1173. "<nocast>",
  1174. "<pointer>",
  1175. "enum class",
  1176. "null",
  1177. "string",
  1178. // "texture",
  1179. "Texture1D",
  1180. "Texture1DArray",
  1181. "Texture2D",
  1182. "Texture2DArray",
  1183. "Texture3D",
  1184. "TextureCube",
  1185. "TextureCubeArray",
  1186. "Texture2DMS",
  1187. "Texture2DMSArray",
  1188. "SamplerState",
  1189. "sampler1D",
  1190. "sampler2D",
  1191. "sampler3D",
  1192. "samplerCUBE",
  1193. "SamplerComparisonState",
  1194. "Buffer",
  1195. "RenderTargetView",
  1196. "DepthStencilView",
  1197. "ComputeShader",
  1198. "DomainShader",
  1199. "GeometryShader",
  1200. "HullShader",
  1201. "PixelShader",
  1202. "VertexShader",
  1203. "pixelfragment",
  1204. "vertexfragment",
  1205. "StateBlock",
  1206. "Rasterizer",
  1207. "DepthStencil",
  1208. "Blend",
  1209. "PointStream",
  1210. "LineStream",
  1211. "TriangleStream",
  1212. "InputPatch",
  1213. "OutputPatch",
  1214. "RWTexture1D",
  1215. "RWTexture1DArray",
  1216. "RWTexture2D",
  1217. "RWTexture2DArray",
  1218. "RWTexture3D",
  1219. "RWBuffer",
  1220. "ByteAddressBuffer",
  1221. "RWByteAddressBuffer",
  1222. "StructuredBuffer",
  1223. "RWStructuredBuffer",
  1224. "RWStructuredBuffer(Incrementable)",
  1225. "RWStructuredBuffer(Decrementable)",
  1226. "AppendStructuredBuffer",
  1227. "ConsumeStructuredBuffer",
  1228. "ConstantBuffer",
  1229. "TextureBuffer",
  1230. "RasterizerOrderedBuffer",
  1231. "RasterizerOrderedByteAddressBuffer",
  1232. "RasterizerOrderedStructuredBuffer",
  1233. "RasterizerOrderedTexture1D",
  1234. "RasterizerOrderedTexture1DArray",
  1235. "RasterizerOrderedTexture2D",
  1236. "RasterizerOrderedTexture2DArray",
  1237. "RasterizerOrderedTexture3D",
  1238. // SPIRV change starts
  1239. #ifdef ENABLE_SPIRV_CODEGEN
  1240. "SubpassInput",
  1241. "SubpassInputMS",
  1242. #endif // ENABLE_SPIRV_CODEGEN
  1243. // SPIRV change ends
  1244. "<internal inner type object>",
  1245. "deprecated effect object",
  1246. "wave_t"
  1247. };
  1248. C_ASSERT(_countof(g_ArBasicTypeNames) == AR_BASIC_MAXIMUM_COUNT);
  1249. // kind should never be a flag value or effects framework type - we simply do not expect to deal with these
  1250. #define DXASSERT_VALIDBASICKIND(kind) \
  1251. DXASSERT(\
  1252. kind != AR_BASIC_COUNT && \
  1253. kind != AR_BASIC_NONE && \
  1254. kind != AR_BASIC_UNKNOWN && \
  1255. kind != AR_BASIC_NOCAST && \
  1256. kind != AR_BASIC_POINTER && \
  1257. kind != AR_OBJECT_RENDERTARGETVIEW && \
  1258. kind != AR_OBJECT_DEPTHSTENCILVIEW && \
  1259. kind != AR_OBJECT_COMPUTESHADER && \
  1260. kind != AR_OBJECT_DOMAINSHADER && \
  1261. kind != AR_OBJECT_GEOMETRYSHADER && \
  1262. kind != AR_OBJECT_HULLSHADER && \
  1263. kind != AR_OBJECT_PIXELSHADER && \
  1264. kind != AR_OBJECT_VERTEXSHADER && \
  1265. kind != AR_OBJECT_PIXELFRAGMENT && \
  1266. kind != AR_OBJECT_VERTEXFRAGMENT, "otherwise caller is using a special flag or an unsupported kind value");
  1267. static
  1268. const char* g_DeprecatedEffectObjectNames[] =
  1269. {
  1270. // These are case insensitive in fxc, but we'll just create two case aliases
  1271. // to capture the majority of cases
  1272. "texture", "Texture",
  1273. "pixelshader", "PixelShader",
  1274. "vertexshader", "VertexShader",
  1275. // These are case sensitive in fxc
  1276. "pixelfragment", // 13
  1277. "vertexfragment", // 14
  1278. "ComputeShader", // 13
  1279. "DomainShader", // 12
  1280. "GeometryShader", // 14
  1281. "HullShader", // 10
  1282. "BlendState", // 10
  1283. "DepthStencilState",// 17
  1284. "DepthStencilView", // 16
  1285. "RasterizerState", // 15
  1286. "RenderTargetView", // 16
  1287. };
  1288. static hlsl::ParameterModifier
  1289. ParamModsFromIntrinsicArg(const HLSL_INTRINSIC_ARGUMENT *pArg) {
  1290. if (pArg->qwUsage == AR_QUAL_IN_OUT) {
  1291. return hlsl::ParameterModifier(hlsl::ParameterModifier::Kind::InOut);
  1292. }
  1293. if (pArg->qwUsage == AR_QUAL_OUT) {
  1294. return hlsl::ParameterModifier(hlsl::ParameterModifier::Kind::Out);
  1295. }
  1296. DXASSERT(pArg->qwUsage & AR_QUAL_IN, "else usage is incorrect");
  1297. return hlsl::ParameterModifier(hlsl::ParameterModifier::Kind::In);
  1298. }
  1299. static void InitParamMods(const HLSL_INTRINSIC *pIntrinsic,
  1300. SmallVectorImpl<hlsl::ParameterModifier> &paramMods) {
  1301. // The first argument is the return value, which isn't included.
  1302. for (UINT i = 1; i < pIntrinsic->uNumArgs; ++i) {
  1303. paramMods.push_back(ParamModsFromIntrinsicArg(&pIntrinsic->pArgs[i]));
  1304. }
  1305. }
  1306. static bool IsAtomicOperation(IntrinsicOp op) {
  1307. switch (op) {
  1308. case IntrinsicOp::IOP_InterlockedAdd:
  1309. case IntrinsicOp::IOP_InterlockedAnd:
  1310. case IntrinsicOp::IOP_InterlockedCompareExchange:
  1311. case IntrinsicOp::IOP_InterlockedCompareStore:
  1312. case IntrinsicOp::IOP_InterlockedExchange:
  1313. case IntrinsicOp::IOP_InterlockedMax:
  1314. case IntrinsicOp::IOP_InterlockedMin:
  1315. case IntrinsicOp::IOP_InterlockedOr:
  1316. case IntrinsicOp::IOP_InterlockedXor:
  1317. case IntrinsicOp::MOP_InterlockedAdd:
  1318. case IntrinsicOp::MOP_InterlockedAnd:
  1319. case IntrinsicOp::MOP_InterlockedCompareExchange:
  1320. case IntrinsicOp::MOP_InterlockedCompareStore:
  1321. case IntrinsicOp::MOP_InterlockedExchange:
  1322. case IntrinsicOp::MOP_InterlockedMax:
  1323. case IntrinsicOp::MOP_InterlockedMin:
  1324. case IntrinsicOp::MOP_InterlockedOr:
  1325. case IntrinsicOp::MOP_InterlockedXor:
  1326. return true;
  1327. default:
  1328. return false;
  1329. }
  1330. }
  1331. static bool IsBuiltinTable(LPCSTR tableName) {
  1332. return tableName == kBuiltinIntrinsicTableName;
  1333. }
  1334. static void AddHLSLIntrinsicAttr(FunctionDecl *FD, ASTContext &context,
  1335. LPCSTR tableName, LPCSTR lowering,
  1336. const HLSL_INTRINSIC *pIntrinsic) {
  1337. unsigned opcode = (unsigned)pIntrinsic->Op;
  1338. if (HasUnsignedOpcode(opcode) && IsBuiltinTable(tableName)) {
  1339. QualType Ty = FD->getReturnType();
  1340. if (pIntrinsic->iOverloadParamIndex != -1) {
  1341. const FunctionProtoType *FT =
  1342. FD->getFunctionType()->getAs<FunctionProtoType>();
  1343. Ty = FT->getParamType(pIntrinsic->iOverloadParamIndex);
  1344. }
  1345. // TODO: refine the code for getting element type
  1346. if (const ExtVectorType *VecTy = hlsl::ConvertHLSLVecMatTypeToExtVectorType(context, Ty)) {
  1347. Ty = VecTy->getElementType();
  1348. }
  1349. if (Ty->isUnsignedIntegerType()) {
  1350. opcode = hlsl::GetUnsignedOpcode(opcode);
  1351. }
  1352. }
  1353. FD->addAttr(HLSLIntrinsicAttr::CreateImplicit(context, tableName, lowering, opcode));
  1354. if (pIntrinsic->bReadNone)
  1355. FD->addAttr(ConstAttr::CreateImplicit(context));
  1356. if (pIntrinsic->bReadOnly)
  1357. FD->addAttr(PureAttr::CreateImplicit(context));
  1358. }
  1359. static
  1360. FunctionDecl *AddHLSLIntrinsicFunction(
  1361. ASTContext &context, _In_ NamespaceDecl *NS,
  1362. LPCSTR tableName, LPCSTR lowering,
  1363. _In_ const HLSL_INTRINSIC *pIntrinsic,
  1364. _In_count_(functionArgTypeCount) QualType *functionArgQualTypes,
  1365. _In_range_(0, g_MaxIntrinsicParamCount - 1) size_t functionArgTypeCount) {
  1366. DXASSERT(functionArgTypeCount - 1 < g_MaxIntrinsicParamCount,
  1367. "otherwise g_MaxIntrinsicParamCount should be larger");
  1368. DeclContext *currentDeclContext = context.getTranslationUnitDecl();
  1369. SmallVector<hlsl::ParameterModifier, g_MaxIntrinsicParamCount> paramMods;
  1370. InitParamMods(pIntrinsic, paramMods);
  1371. // Change dest address into reference type for atomic.
  1372. if (IsBuiltinTable(tableName)) {
  1373. if (IsAtomicOperation(static_cast<IntrinsicOp>(pIntrinsic->Op))) {
  1374. DXASSERT(functionArgTypeCount > kAtomicDstOperandIdx,
  1375. "else operation was misrecognized");
  1376. functionArgQualTypes[kAtomicDstOperandIdx] =
  1377. context.getLValueReferenceType(functionArgQualTypes[kAtomicDstOperandIdx]);
  1378. }
  1379. }
  1380. for (size_t i = 1; i < functionArgTypeCount; i++) {
  1381. // Change out/inout param to reference type.
  1382. if (paramMods[i-1].isAnyOut()) {
  1383. functionArgQualTypes[i] = context.getLValueReferenceType(functionArgQualTypes[i]);
  1384. }
  1385. }
  1386. IdentifierInfo &functionId = context.Idents.get(
  1387. StringRef(pIntrinsic->pArgs[0].pName), tok::TokenKind::identifier);
  1388. DeclarationName functionName(&functionId);
  1389. QualType functionType = context.getFunctionType(
  1390. functionArgQualTypes[0],
  1391. ArrayRef<QualType>(functionArgQualTypes + 1,
  1392. functionArgQualTypes + functionArgTypeCount),
  1393. clang::FunctionProtoType::ExtProtoInfo(), paramMods);
  1394. FunctionDecl *functionDecl = FunctionDecl::Create(
  1395. context, currentDeclContext, NoLoc,
  1396. DeclarationNameInfo(functionName, NoLoc), functionType, nullptr,
  1397. StorageClass::SC_Extern, InlineSpecifiedFalse, HasWrittenPrototypeTrue);
  1398. currentDeclContext->addDecl(functionDecl);
  1399. functionDecl->setLexicalDeclContext(currentDeclContext);
  1400. // put under hlsl namespace
  1401. functionDecl->setDeclContext(NS);
  1402. // Add intrinsic attribute
  1403. AddHLSLIntrinsicAttr(functionDecl, context, tableName, lowering, pIntrinsic);
  1404. ParmVarDecl *paramDecls[g_MaxIntrinsicParamCount];
  1405. for (size_t i = 1; i < functionArgTypeCount; i++) {
  1406. IdentifierInfo &parameterId = context.Idents.get(
  1407. StringRef(pIntrinsic->pArgs[i].pName), tok::TokenKind::identifier);
  1408. ParmVarDecl *paramDecl =
  1409. ParmVarDecl::Create(context, functionDecl, NoLoc, NoLoc, &parameterId,
  1410. functionArgQualTypes[i], nullptr,
  1411. StorageClass::SC_None, nullptr, paramMods[i - 1]);
  1412. functionDecl->addDecl(paramDecl);
  1413. paramDecls[i - 1] = paramDecl;
  1414. }
  1415. functionDecl->setParams(
  1416. ArrayRef<ParmVarDecl *>(paramDecls, functionArgTypeCount - 1));
  1417. functionDecl->setImplicit(true);
  1418. return functionDecl;
  1419. }
  1420. /// <summary>
  1421. /// Checks whether the specified expression is a (possibly parenthesized) comma operator.
  1422. /// </summary>
  1423. static
  1424. bool IsExpressionBinaryComma(_In_ const Expr* expr)
  1425. {
  1426. DXASSERT_NOMSG(expr != nullptr);
  1427. expr = expr->IgnoreParens();
  1428. return
  1429. expr->getStmtClass() == Expr::StmtClass::BinaryOperatorClass &&
  1430. cast<BinaryOperator>(expr)->getOpcode() == BinaryOperatorKind::BO_Comma;
  1431. }
  1432. /// <summary>
  1433. /// Silences diagnostics for the initialization sequence, typically because they have already
  1434. /// been emitted.
  1435. /// </summary>
  1436. static
  1437. void SilenceSequenceDiagnostics(_Inout_ InitializationSequence* initSequence)
  1438. {
  1439. DXASSERT_NOMSG(initSequence != nullptr);
  1440. initSequence->SetFailed(InitializationSequence::FK_ListInitializationFailed);
  1441. }
  1442. class UsedIntrinsic
  1443. {
  1444. public:
  1445. static int compareArgs(const QualType& LHS, const QualType& RHS)
  1446. {
  1447. // The canonical representations are unique'd in an ASTContext, and so these
  1448. // should be stable.
  1449. return RHS.getTypePtr() - LHS.getTypePtr();
  1450. }
  1451. static int compareIntrinsic(const HLSL_INTRINSIC* LHS, const HLSL_INTRINSIC* RHS)
  1452. {
  1453. // The intrinsics are defined in a single static table, and so should be stable.
  1454. return RHS - LHS;
  1455. }
  1456. int compare(const UsedIntrinsic& other) const
  1457. {
  1458. // Check whether it's the same instance.
  1459. if (this == &other) return 0;
  1460. int result = compareIntrinsic(m_intrinsicSource, other.m_intrinsicSource);
  1461. if (result != 0) return result;
  1462. // At this point, it's the exact same intrinsic name.
  1463. // Compare the arguments for ordering then.
  1464. DXASSERT(m_argLength == other.m_argLength, "intrinsics aren't overloaded on argument count, so we should never create a key with different #s");
  1465. for (size_t i = 0; i < m_argLength; i++) {
  1466. int argComparison = compareArgs(m_args[i], other.m_args[i]);
  1467. if (argComparison != 0) return argComparison;
  1468. }
  1469. // Exactly the same.
  1470. return 0;
  1471. }
  1472. public:
  1473. UsedIntrinsic(const HLSL_INTRINSIC* intrinsicSource, _In_count_(argCount) QualType* args, size_t argCount)
  1474. : m_argLength(argCount), m_intrinsicSource(intrinsicSource), m_functionDecl(nullptr)
  1475. {
  1476. std::copy(args, args + argCount, m_args);
  1477. }
  1478. void setFunctionDecl(FunctionDecl* value) const
  1479. {
  1480. DXASSERT(value != nullptr, "no reason to clear this out");
  1481. DXASSERT(m_functionDecl == nullptr, "otherwise cached value is being invaldiated");
  1482. m_functionDecl = value;
  1483. }
  1484. FunctionDecl* getFunctionDecl() const { return m_functionDecl; }
  1485. bool operator==(const UsedIntrinsic& other) const
  1486. {
  1487. return compare(other) == 0;
  1488. }
  1489. bool operator<(const UsedIntrinsic& other) const
  1490. {
  1491. return compare(other) < 0;
  1492. }
  1493. private:
  1494. QualType m_args[g_MaxIntrinsicParamCount];
  1495. size_t m_argLength;
  1496. const HLSL_INTRINSIC* m_intrinsicSource;
  1497. mutable FunctionDecl* m_functionDecl;
  1498. };
  1499. template <typename T>
  1500. inline void AssignOpt(T value, _Out_opt_ T* ptr)
  1501. {
  1502. if (ptr != nullptr)
  1503. {
  1504. *ptr = value;
  1505. }
  1506. }
  1507. static bool CombineBasicTypes(
  1508. ArBasicKind LeftKind,
  1509. ArBasicKind RightKind,
  1510. _Out_ ArBasicKind* pOutKind,
  1511. _Out_opt_ CastKind* leftCastKind = nullptr,
  1512. _Out_opt_ CastKind* rightCastKind = nullptr)
  1513. {
  1514. AssignOpt(CastKind::CK_NoOp, leftCastKind);
  1515. AssignOpt(CastKind::CK_NoOp, rightCastKind);
  1516. if ((LeftKind < 0 || LeftKind >= AR_BASIC_COUNT) ||
  1517. (RightKind < 0 || RightKind >= AR_BASIC_COUNT)) {
  1518. return false;
  1519. }
  1520. if (LeftKind == RightKind) {
  1521. *pOutKind = LeftKind;
  1522. return true;
  1523. }
  1524. UINT uLeftProps = GetBasicKindProps(LeftKind);
  1525. UINT uRightProps = GetBasicKindProps(RightKind);
  1526. UINT uBits = GET_BPROP_BITS(uLeftProps) > GET_BPROP_BITS(uRightProps) ?
  1527. GET_BPROP_BITS(uLeftProps) : GET_BPROP_BITS(uRightProps);
  1528. UINT uBothFlags = uLeftProps & uRightProps;
  1529. UINT uEitherFlags = uLeftProps | uRightProps;
  1530. if ((BPROP_BOOLEAN & uBothFlags) != 0)
  1531. {
  1532. *pOutKind = AR_BASIC_BOOL;
  1533. return true;
  1534. }
  1535. if ((BPROP_LITERAL & uBothFlags) != 0)
  1536. {
  1537. if ((BPROP_INTEGER & uBothFlags) != 0)
  1538. {
  1539. *pOutKind = AR_BASIC_LITERAL_INT;
  1540. }
  1541. else
  1542. {
  1543. *pOutKind = AR_BASIC_LITERAL_FLOAT;
  1544. }
  1545. return true;
  1546. }
  1547. if ((BPROP_UNSIGNED & uBothFlags) != 0)
  1548. {
  1549. switch (uBits)
  1550. {
  1551. case BPROP_BITS8: *pOutKind = AR_BASIC_UINT8; break;
  1552. case BPROP_BITS16: (uEitherFlags & BPROP_MIN_PRECISION) ?
  1553. *pOutKind = AR_BASIC_MIN16UINT : *pOutKind = AR_BASIC_UINT16; break;
  1554. case BPROP_BITS32: *pOutKind = AR_BASIC_UINT32; break;
  1555. case BPROP_BITS64: *pOutKind = AR_BASIC_UINT64; break;
  1556. default: DXASSERT_NOMSG(false); break;
  1557. }
  1558. AssignOpt(CK_IntegralCast, leftCastKind);
  1559. AssignOpt(CK_IntegralCast, rightCastKind);
  1560. return true;
  1561. }
  1562. if ((BPROP_INTEGER & uBothFlags) != 0)
  1563. {
  1564. if ((BPROP_UNSIGNED & uEitherFlags) != 0)
  1565. {
  1566. switch (uBits)
  1567. {
  1568. case BPROP_BITS8: *pOutKind = AR_BASIC_UINT8; break;
  1569. case BPROP_BITS16: (uEitherFlags & BPROP_MIN_PRECISION) ?
  1570. *pOutKind = AR_BASIC_MIN16UINT : *pOutKind = AR_BASIC_UINT16; break;
  1571. case BPROP_BITS32: *pOutKind = AR_BASIC_UINT32; break;
  1572. case BPROP_BITS64: *pOutKind = AR_BASIC_UINT64; break;
  1573. default: DXASSERT_NOMSG(false); break;
  1574. }
  1575. }
  1576. else
  1577. {
  1578. switch (uBits)
  1579. {
  1580. case BPROP_BITS0: *pOutKind = AR_BASIC_LITERAL_INT; break;
  1581. case BPROP_BITS8: *pOutKind = AR_BASIC_INT8; break;
  1582. case BPROP_BITS12: *pOutKind = AR_BASIC_MIN12INT; break;
  1583. case BPROP_BITS16: (uEitherFlags & BPROP_MIN_PRECISION) ?
  1584. *pOutKind = AR_BASIC_MIN16INT : *pOutKind = AR_BASIC_INT16; break;
  1585. case BPROP_BITS32: *pOutKind = AR_BASIC_INT32; break;
  1586. case BPROP_BITS64: *pOutKind = AR_BASIC_INT64; break;
  1587. default: DXASSERT_NOMSG(false); break;
  1588. }
  1589. }
  1590. AssignOpt(CK_IntegralCast, leftCastKind);
  1591. AssignOpt(CK_IntegralCast, rightCastKind);
  1592. return true;
  1593. }
  1594. // At least one side is floating-point. Assume both are and fix later
  1595. // in this function.
  1596. DXASSERT_NOMSG((BPROP_FLOATING & uEitherFlags) != 0);
  1597. AssignOpt(CK_FloatingCast, leftCastKind);
  1598. AssignOpt(CK_FloatingCast, rightCastKind);
  1599. if ((BPROP_FLOATING & uBothFlags) == 0)
  1600. {
  1601. // One side is floating-point and one isn't,
  1602. // convert to the floating-point type.
  1603. if ((BPROP_FLOATING & uLeftProps) != 0)
  1604. {
  1605. uBits = GET_BPROP_BITS(uLeftProps);
  1606. AssignOpt(CK_IntegralToFloating, rightCastKind);
  1607. }
  1608. else
  1609. {
  1610. DXASSERT_NOMSG((BPROP_FLOATING & uRightProps) != 0);
  1611. uBits = GET_BPROP_BITS(uRightProps);
  1612. AssignOpt(CK_IntegralToFloating, leftCastKind);
  1613. }
  1614. if (uBits == 0)
  1615. {
  1616. // We have a literal plus a non-literal so drop
  1617. // any literalness.
  1618. uBits = BPROP_BITS32;
  1619. }
  1620. }
  1621. switch (uBits)
  1622. {
  1623. case BPROP_BITS10:
  1624. *pOutKind = AR_BASIC_MIN10FLOAT;
  1625. break;
  1626. case BPROP_BITS16:
  1627. if ((uEitherFlags & BPROP_MIN_PRECISION) != 0)
  1628. {
  1629. *pOutKind = AR_BASIC_MIN16FLOAT;
  1630. }
  1631. else
  1632. {
  1633. *pOutKind = AR_BASIC_FLOAT16;
  1634. }
  1635. break;
  1636. case BPROP_BITS32:
  1637. if ((uEitherFlags & BPROP_LITERAL) != 0 &&
  1638. (uEitherFlags & BPROP_PARTIAL_PRECISION) != 0)
  1639. {
  1640. *pOutKind = AR_BASIC_FLOAT32_PARTIAL_PRECISION;
  1641. }
  1642. else if ((uBothFlags & BPROP_PARTIAL_PRECISION) != 0)
  1643. {
  1644. *pOutKind = AR_BASIC_FLOAT32_PARTIAL_PRECISION;
  1645. }
  1646. else
  1647. {
  1648. *pOutKind = AR_BASIC_FLOAT32;
  1649. }
  1650. break;
  1651. case BPROP_BITS64:
  1652. *pOutKind = AR_BASIC_FLOAT64;
  1653. break;
  1654. default:
  1655. DXASSERT(false, "unexpected bit count");
  1656. *pOutKind = AR_BASIC_FLOAT32;
  1657. break;
  1658. }
  1659. return true;
  1660. }
  1661. class UsedIntrinsicStore : public std::set<UsedIntrinsic>
  1662. {
  1663. };
  1664. static
  1665. void GetIntrinsicMethods(ArBasicKind kind, _Outptr_result_buffer_(*intrinsicCount) const HLSL_INTRINSIC** intrinsics, _Out_ size_t* intrinsicCount)
  1666. {
  1667. DXASSERT_NOMSG(intrinsics != nullptr);
  1668. DXASSERT_NOMSG(intrinsicCount != nullptr);
  1669. switch (kind)
  1670. {
  1671. case AR_OBJECT_TRIANGLESTREAM:
  1672. case AR_OBJECT_POINTSTREAM:
  1673. case AR_OBJECT_LINESTREAM:
  1674. *intrinsics = g_StreamMethods;
  1675. *intrinsicCount = _countof(g_StreamMethods);
  1676. break;
  1677. case AR_OBJECT_TEXTURE1D:
  1678. *intrinsics = g_Texture1DMethods;
  1679. *intrinsicCount = _countof(g_Texture1DMethods);
  1680. break;
  1681. case AR_OBJECT_TEXTURE1D_ARRAY:
  1682. *intrinsics = g_Texture1DArrayMethods;
  1683. *intrinsicCount = _countof(g_Texture1DArrayMethods);
  1684. break;
  1685. case AR_OBJECT_TEXTURE2D:
  1686. *intrinsics = g_Texture2DMethods;
  1687. *intrinsicCount = _countof(g_Texture2DMethods);
  1688. break;
  1689. case AR_OBJECT_TEXTURE2DMS:
  1690. *intrinsics = g_Texture2DMSMethods;
  1691. *intrinsicCount = _countof(g_Texture2DMSMethods);
  1692. break;
  1693. case AR_OBJECT_TEXTURE2D_ARRAY:
  1694. *intrinsics = g_Texture2DArrayMethods;
  1695. *intrinsicCount = _countof(g_Texture2DArrayMethods);
  1696. break;
  1697. case AR_OBJECT_TEXTURE2DMS_ARRAY:
  1698. *intrinsics = g_Texture2DArrayMSMethods;
  1699. *intrinsicCount = _countof(g_Texture2DArrayMSMethods);
  1700. break;
  1701. case AR_OBJECT_TEXTURE3D:
  1702. *intrinsics = g_Texture3DMethods;
  1703. *intrinsicCount = _countof(g_Texture3DMethods);
  1704. break;
  1705. case AR_OBJECT_TEXTURECUBE:
  1706. *intrinsics = g_TextureCUBEMethods;
  1707. *intrinsicCount = _countof(g_TextureCUBEMethods);
  1708. break;
  1709. case AR_OBJECT_TEXTURECUBE_ARRAY:
  1710. *intrinsics = g_TextureCUBEArrayMethods;
  1711. *intrinsicCount = _countof(g_TextureCUBEArrayMethods);
  1712. break;
  1713. case AR_OBJECT_BUFFER:
  1714. *intrinsics = g_BufferMethods;
  1715. *intrinsicCount = _countof(g_BufferMethods);
  1716. break;
  1717. case AR_OBJECT_RWTEXTURE1D:
  1718. case AR_OBJECT_ROVTEXTURE1D:
  1719. *intrinsics = g_RWTexture1DMethods;
  1720. *intrinsicCount = _countof(g_RWTexture1DMethods);
  1721. break;
  1722. case AR_OBJECT_RWTEXTURE1D_ARRAY:
  1723. case AR_OBJECT_ROVTEXTURE1D_ARRAY:
  1724. *intrinsics = g_RWTexture1DArrayMethods;
  1725. *intrinsicCount = _countof(g_RWTexture1DArrayMethods);
  1726. break;
  1727. case AR_OBJECT_RWTEXTURE2D:
  1728. case AR_OBJECT_ROVTEXTURE2D:
  1729. *intrinsics = g_RWTexture2DMethods;
  1730. *intrinsicCount = _countof(g_RWTexture2DMethods);
  1731. break;
  1732. case AR_OBJECT_RWTEXTURE2D_ARRAY:
  1733. case AR_OBJECT_ROVTEXTURE2D_ARRAY:
  1734. *intrinsics = g_RWTexture2DArrayMethods;
  1735. *intrinsicCount = _countof(g_RWTexture2DArrayMethods);
  1736. break;
  1737. case AR_OBJECT_RWTEXTURE3D:
  1738. case AR_OBJECT_ROVTEXTURE3D:
  1739. *intrinsics = g_RWTexture3DMethods;
  1740. *intrinsicCount = _countof(g_RWTexture3DMethods);
  1741. break;
  1742. case AR_OBJECT_RWBUFFER:
  1743. case AR_OBJECT_ROVBUFFER:
  1744. *intrinsics = g_RWBufferMethods;
  1745. *intrinsicCount = _countof(g_RWBufferMethods);
  1746. break;
  1747. case AR_OBJECT_BYTEADDRESS_BUFFER:
  1748. *intrinsics = g_ByteAddressBufferMethods;
  1749. *intrinsicCount = _countof(g_ByteAddressBufferMethods);
  1750. break;
  1751. case AR_OBJECT_RWBYTEADDRESS_BUFFER:
  1752. case AR_OBJECT_ROVBYTEADDRESS_BUFFER:
  1753. *intrinsics = g_RWByteAddressBufferMethods;
  1754. *intrinsicCount = _countof(g_RWByteAddressBufferMethods);
  1755. break;
  1756. case AR_OBJECT_STRUCTURED_BUFFER:
  1757. *intrinsics = g_StructuredBufferMethods;
  1758. *intrinsicCount = _countof(g_StructuredBufferMethods);
  1759. break;
  1760. case AR_OBJECT_RWSTRUCTURED_BUFFER:
  1761. case AR_OBJECT_ROVSTRUCTURED_BUFFER:
  1762. *intrinsics = g_RWStructuredBufferMethods;
  1763. *intrinsicCount = _countof(g_RWStructuredBufferMethods);
  1764. break;
  1765. case AR_OBJECT_APPEND_STRUCTURED_BUFFER:
  1766. *intrinsics = g_AppendStructuredBufferMethods;
  1767. *intrinsicCount = _countof(g_AppendStructuredBufferMethods);
  1768. break;
  1769. case AR_OBJECT_CONSUME_STRUCTURED_BUFFER:
  1770. *intrinsics = g_ConsumeStructuredBufferMethods;
  1771. *intrinsicCount = _countof(g_ConsumeStructuredBufferMethods);
  1772. break;
  1773. // SPIRV change starts
  1774. #ifdef ENABLE_SPIRV_CODEGEN
  1775. case AR_OBJECT_VK_SUBPASS_INPUT:
  1776. *intrinsics = g_VkSubpassInputMethods;
  1777. *intrinsicCount = _countof(g_VkSubpassInputMethods);
  1778. break;
  1779. case AR_OBJECT_VK_SUBPASS_INPUT_MS:
  1780. *intrinsics = g_VkSubpassInputMSMethods;
  1781. *intrinsicCount = _countof(g_VkSubpassInputMSMethods);
  1782. break;
  1783. #endif // ENABLE_SPIRV_CODEGEN
  1784. // SPIRV change ends
  1785. default:
  1786. *intrinsics = nullptr;
  1787. *intrinsicCount = 0;
  1788. break;
  1789. }
  1790. }
  1791. static
  1792. bool IsRowOrColumnVariable(size_t value)
  1793. {
  1794. return IA_SPECIAL_BASE <= value && value <= (IA_SPECIAL_BASE + IA_SPECIAL_SLOTS - 1);
  1795. }
  1796. static
  1797. bool DoesComponentTypeAcceptMultipleTypes(LEGAL_INTRINSIC_COMPTYPES value)
  1798. {
  1799. return
  1800. value == LICOMPTYPE_ANY_INT || // signed or unsigned ints
  1801. value == LICOMPTYPE_ANY_INT32 || // signed or unsigned ints
  1802. value == LICOMPTYPE_ANY_FLOAT || // float or double
  1803. value == LICOMPTYPE_FLOAT_LIKE || // float or min16
  1804. value == LICOMPTYPE_FLOAT_DOUBLE || // float or double
  1805. value == LICOMPTYPE_NUMERIC || // all sorts of numbers
  1806. value == LICOMPTYPE_NUMERIC32 || // all sorts of numbers
  1807. value == LICOMPTYPE_NUMERIC32_ONLY || // all sorts of numbers
  1808. value == LICOMPTYPE_ANY; // any time
  1809. }
  1810. static
  1811. bool DoesComponentTypeAcceptMultipleTypes(BYTE value)
  1812. {
  1813. return DoesComponentTypeAcceptMultipleTypes(static_cast<LEGAL_INTRINSIC_COMPTYPES>(value));
  1814. }
  1815. static
  1816. bool DoesLegalTemplateAcceptMultipleTypes(LEGAL_INTRINSIC_TEMPLATES value)
  1817. {
  1818. // Note that LITEMPLATE_OBJECT can accept different types, but it
  1819. // specifies a single 'layout'. In practice, this information is used
  1820. // together with a component type that specifies a single object.
  1821. return value == LITEMPLATE_ANY; // Any layout
  1822. }
  1823. static
  1824. bool DoesLegalTemplateAcceptMultipleTypes(BYTE value)
  1825. {
  1826. return DoesLegalTemplateAcceptMultipleTypes(static_cast<LEGAL_INTRINSIC_TEMPLATES>(value));
  1827. }
  1828. static
  1829. bool TemplateHasDefaultType(ArBasicKind kind)
  1830. {
  1831. switch (kind) {
  1832. case AR_OBJECT_BUFFER:
  1833. case AR_OBJECT_TEXTURE1D:
  1834. case AR_OBJECT_TEXTURE2D:
  1835. case AR_OBJECT_TEXTURE3D:
  1836. case AR_OBJECT_TEXTURE1D_ARRAY:
  1837. case AR_OBJECT_TEXTURE2D_ARRAY:
  1838. case AR_OBJECT_TEXTURECUBE:
  1839. case AR_OBJECT_TEXTURECUBE_ARRAY:
  1840. // SPIRV change starts
  1841. #ifdef ENABLE_SPIRV_CODEGEN
  1842. case AR_OBJECT_VK_SUBPASS_INPUT:
  1843. case AR_OBJECT_VK_SUBPASS_INPUT_MS:
  1844. #endif // ENABLE_SPIRV_CODEGEN
  1845. // SPIRV change ends
  1846. return true;
  1847. default:
  1848. // Objects with default types return true. Everything else is false.
  1849. return false;
  1850. }
  1851. }
  1852. /// <summary>
  1853. /// Use this class to iterate over intrinsic definitions that come from an external source.
  1854. /// </summary>
  1855. class IntrinsicTableDefIter
  1856. {
  1857. private:
  1858. StringRef _typeName;
  1859. StringRef _functionName;
  1860. llvm::SmallVector<CComPtr<IDxcIntrinsicTable>, 2>& _tables;
  1861. const HLSL_INTRINSIC* _tableIntrinsic;
  1862. UINT64 _tableLookupCookie;
  1863. unsigned _tableIndex;
  1864. unsigned _argCount;
  1865. bool _firstChecked;
  1866. IntrinsicTableDefIter(
  1867. llvm::SmallVector<CComPtr<IDxcIntrinsicTable>, 2>& tables,
  1868. StringRef typeName,
  1869. StringRef functionName,
  1870. unsigned argCount) :
  1871. _typeName(typeName), _functionName(functionName), _tables(tables),
  1872. _tableIntrinsic(nullptr), _tableLookupCookie(0), _tableIndex(0),
  1873. _argCount(argCount), _firstChecked(false)
  1874. {
  1875. }
  1876. void CheckForIntrinsic() {
  1877. if (_tableIndex >= _tables.size()) {
  1878. return;
  1879. }
  1880. _firstChecked = true;
  1881. // TODO: review this - this will allocate at least once per string
  1882. CA2WEX<> typeName(_typeName.str().c_str(), CP_UTF8);
  1883. CA2WEX<> functionName(_functionName.str().c_str(), CP_UTF8);
  1884. if (FAILED(_tables[_tableIndex]->LookupIntrinsic(
  1885. typeName, functionName, &_tableIntrinsic, &_tableLookupCookie))) {
  1886. _tableLookupCookie = 0;
  1887. _tableIntrinsic = nullptr;
  1888. }
  1889. }
  1890. void MoveToNext() {
  1891. for (;;) {
  1892. // If we don't have an intrinsic, try the following table.
  1893. if (_firstChecked && _tableIntrinsic == nullptr) {
  1894. _tableIndex++;
  1895. }
  1896. CheckForIntrinsic();
  1897. if (_tableIndex == _tables.size() ||
  1898. (_tableIntrinsic != nullptr &&
  1899. _tableIntrinsic->uNumArgs ==
  1900. (_argCount + 1))) // uNumArgs includes return
  1901. break;
  1902. }
  1903. }
  1904. public:
  1905. static IntrinsicTableDefIter CreateStart(llvm::SmallVector<CComPtr<IDxcIntrinsicTable>, 2>& tables,
  1906. StringRef typeName,
  1907. StringRef functionName,
  1908. unsigned argCount)
  1909. {
  1910. IntrinsicTableDefIter result(tables, typeName, functionName, argCount);
  1911. return result;
  1912. }
  1913. static IntrinsicTableDefIter CreateEnd(llvm::SmallVector<CComPtr<IDxcIntrinsicTable>, 2>& tables)
  1914. {
  1915. IntrinsicTableDefIter result(tables, StringRef(), StringRef(), 0);
  1916. result._tableIndex = tables.size();
  1917. return result;
  1918. }
  1919. bool operator!=(const IntrinsicTableDefIter& other)
  1920. {
  1921. if (!_firstChecked) {
  1922. MoveToNext();
  1923. }
  1924. return _tableIndex != other._tableIndex; // More things could be compared but we only match end.
  1925. }
  1926. const HLSL_INTRINSIC* operator*()
  1927. {
  1928. DXASSERT(_firstChecked, "otherwise deref without comparing to end");
  1929. return _tableIntrinsic;
  1930. }
  1931. LPCSTR GetTableName()
  1932. {
  1933. LPCSTR tableName = nullptr;
  1934. if (FAILED(_tables[_tableIndex]->GetTableName(&tableName))) {
  1935. return nullptr;
  1936. }
  1937. return tableName;
  1938. }
  1939. LPCSTR GetLoweringStrategy()
  1940. {
  1941. LPCSTR lowering = nullptr;
  1942. if (FAILED(_tables[_tableIndex]->GetLoweringStrategy(_tableIntrinsic->Op, &lowering))) {
  1943. return nullptr;
  1944. }
  1945. return lowering;
  1946. }
  1947. IntrinsicTableDefIter& operator++()
  1948. {
  1949. MoveToNext();
  1950. return *this;
  1951. }
  1952. };
  1953. /// <summary>
  1954. /// Use this class to iterate over intrinsic definitions that have the same name and parameter count.
  1955. /// </summary>
  1956. class IntrinsicDefIter
  1957. {
  1958. const HLSL_INTRINSIC* _current;
  1959. const HLSL_INTRINSIC* _end;
  1960. IntrinsicTableDefIter _tableIter;
  1961. IntrinsicDefIter(const HLSL_INTRINSIC* value, const HLSL_INTRINSIC* end, IntrinsicTableDefIter tableIter) :
  1962. _current(value), _end(end), _tableIter(tableIter)
  1963. { }
  1964. public:
  1965. static IntrinsicDefIter CreateStart(const HLSL_INTRINSIC* table, size_t count, const HLSL_INTRINSIC* start, IntrinsicTableDefIter tableIter)
  1966. {
  1967. return IntrinsicDefIter(start, table + count, tableIter);
  1968. }
  1969. static IntrinsicDefIter CreateEnd(const HLSL_INTRINSIC* table, size_t count, IntrinsicTableDefIter tableIter)
  1970. {
  1971. return IntrinsicDefIter(table + count, table + count, tableIter);
  1972. }
  1973. bool operator!=(const IntrinsicDefIter& other)
  1974. {
  1975. return _current != other._current || _tableIter.operator!=(other._tableIter);
  1976. }
  1977. const HLSL_INTRINSIC* operator*()
  1978. {
  1979. return (_current != _end) ? _current : *_tableIter;
  1980. }
  1981. LPCSTR GetTableName()
  1982. {
  1983. return (_current != _end) ? kBuiltinIntrinsicTableName : _tableIter.GetTableName();
  1984. }
  1985. LPCSTR GetLoweringStrategy()
  1986. {
  1987. return (_current != _end) ? "" : _tableIter.GetLoweringStrategy();
  1988. }
  1989. IntrinsicDefIter& operator++()
  1990. {
  1991. if (_current != _end) {
  1992. const HLSL_INTRINSIC* next = _current + 1;
  1993. if (next != _end && _current->uNumArgs == next->uNumArgs && 0 == strcmp(_current->pArgs[0].pName, next->pArgs[0].pName)) {
  1994. _current = next;
  1995. }
  1996. else {
  1997. _current = _end;
  1998. }
  1999. } else {
  2000. ++_tableIter;
  2001. }
  2002. return *this;
  2003. }
  2004. };
  2005. static void AddHLSLSubscriptAttr(Decl *D, ASTContext &context, HLSubscriptOpcode opcode) {
  2006. StringRef group = GetHLOpcodeGroupName(HLOpcodeGroup::HLSubscript);
  2007. D->addAttr(HLSLIntrinsicAttr::CreateImplicit(context, group, "", static_cast<unsigned>(opcode)));
  2008. }
  2009. //
  2010. // This is similar to clang/Analysis/CallGraph, but the following differences
  2011. // motivate this:
  2012. //
  2013. // - track traversed vs. observed nodes explicitly
  2014. // - fully visit all reachable functions
  2015. // - merge graph visiting with checking for recursion
  2016. // - track global variables and types used (NYI)
  2017. //
  2018. namespace hlsl {
  2019. struct CallNode {
  2020. FunctionDecl *CallerFn;
  2021. ::llvm::SmallPtrSet<FunctionDecl *, 4> CalleeFns;
  2022. };
  2023. typedef ::llvm::DenseMap<FunctionDecl*, CallNode> CallNodes;
  2024. typedef ::llvm::SmallPtrSet<Decl *, 8> FnCallStack;
  2025. typedef ::llvm::SmallPtrSet<FunctionDecl*, 128> FunctionSet;
  2026. typedef ::llvm::SmallVector<FunctionDecl*, 32> PendingFunctions;
  2027. // Returns the definition of a function.
  2028. // This serves two purposes - ignore built-in functions, and pick
  2029. // a single Decl * to be used in maps and sets.
  2030. static FunctionDecl *getFunctionWithBody(FunctionDecl *F) {
  2031. if (!F) return nullptr;
  2032. if (F->doesThisDeclarationHaveABody()) return F;
  2033. F = F->getFirstDecl();
  2034. for (auto &&Candidate : F->redecls()) {
  2035. if (Candidate->doesThisDeclarationHaveABody()) {
  2036. return Candidate;
  2037. }
  2038. }
  2039. return nullptr;
  2040. }
  2041. // AST visitor that maintains visited and pending collections, as well
  2042. // as recording nodes of caller/callees.
  2043. class FnReferenceVisitor : public RecursiveASTVisitor<FnReferenceVisitor> {
  2044. private:
  2045. CallNodes &m_callNodes;
  2046. FunctionSet &m_visitedFunctions;
  2047. PendingFunctions &m_pendingFunctions;
  2048. FunctionDecl *m_source;
  2049. CallNodes::iterator m_sourceIt;
  2050. public:
  2051. FnReferenceVisitor(FunctionSet &visitedFunctions,
  2052. PendingFunctions &pendingFunctions, CallNodes &callNodes)
  2053. : m_callNodes(callNodes),
  2054. m_visitedFunctions(visitedFunctions),
  2055. m_pendingFunctions(pendingFunctions) {}
  2056. void setSourceFn(FunctionDecl *F) {
  2057. F = getFunctionWithBody(F);
  2058. m_source = F;
  2059. m_sourceIt = m_callNodes.find(F);
  2060. }
  2061. bool VisitDeclRefExpr(DeclRefExpr *ref) {
  2062. ValueDecl *valueDecl = ref->getDecl();
  2063. FunctionDecl *fnDecl = dyn_cast_or_null<FunctionDecl>(valueDecl);
  2064. fnDecl = getFunctionWithBody(fnDecl);
  2065. if (fnDecl) {
  2066. if (m_sourceIt == m_callNodes.end()) {
  2067. auto result = m_callNodes.insert(
  2068. std::pair<FunctionDecl *, CallNode>(m_source, CallNode{ m_source }));
  2069. DXASSERT(result.second == true,
  2070. "else setSourceFn didn't assign m_sourceIt");
  2071. m_sourceIt = result.first;
  2072. }
  2073. m_sourceIt->second.CalleeFns.insert(fnDecl);
  2074. if (!m_visitedFunctions.count(fnDecl)) {
  2075. m_pendingFunctions.push_back(fnDecl);
  2076. }
  2077. }
  2078. return true;
  2079. }
  2080. };
  2081. // A call graph that can check for reachability and recursion efficiently.
  2082. class CallGraphWithRecurseGuard {
  2083. private:
  2084. CallNodes m_callNodes;
  2085. FunctionSet m_visitedFunctions;
  2086. FunctionDecl *CheckRecursion(FnCallStack &CallStack,
  2087. FunctionDecl *D) const {
  2088. if (CallStack.insert(D).second == false)
  2089. return D;
  2090. auto node = m_callNodes.find(D);
  2091. if (node != m_callNodes.end()) {
  2092. for (FunctionDecl *Callee : node->second.CalleeFns) {
  2093. FunctionDecl *pResult = CheckRecursion(CallStack, Callee);
  2094. if (pResult)
  2095. return pResult;
  2096. }
  2097. }
  2098. CallStack.erase(D);
  2099. return nullptr;
  2100. }
  2101. public:
  2102. void BuildForEntry(FunctionDecl *EntryFnDecl) {
  2103. DXASSERT_NOMSG(EntryFnDecl);
  2104. EntryFnDecl = getFunctionWithBody(EntryFnDecl);
  2105. PendingFunctions pendingFunctions;
  2106. FnReferenceVisitor visitor(m_visitedFunctions, pendingFunctions, m_callNodes);
  2107. pendingFunctions.push_back(EntryFnDecl);
  2108. while (!pendingFunctions.empty()) {
  2109. FunctionDecl *pendingDecl = pendingFunctions.pop_back_val();
  2110. if (m_visitedFunctions.insert(pendingDecl).second == true) {
  2111. visitor.setSourceFn(pendingDecl);
  2112. visitor.TraverseDecl(pendingDecl);
  2113. }
  2114. }
  2115. }
  2116. FunctionDecl *CheckRecursion(FunctionDecl *EntryFnDecl) const {
  2117. FnCallStack CallStack;
  2118. EntryFnDecl = getFunctionWithBody(EntryFnDecl);
  2119. return CheckRecursion(CallStack, EntryFnDecl);
  2120. }
  2121. void dump() const {
  2122. OutputDebugStringW(L"Call Nodes:\r\n");
  2123. for (auto &node : m_callNodes) {
  2124. OutputDebugFormatA("%s [%p]:\r\n", node.first->getName().str().c_str(), (void*)node.first);
  2125. for (auto callee : node.second.CalleeFns) {
  2126. OutputDebugFormatA(" %s [%p]\r\n", callee->getName().str().c_str(), (void*)callee);
  2127. }
  2128. }
  2129. }
  2130. };
  2131. }
  2132. /// <summary>Creates a Typedef in the specified ASTContext.</summary>
  2133. static
  2134. TypedefDecl *CreateGlobalTypedef(ASTContext* context, const char* ident, QualType baseType)
  2135. {
  2136. DXASSERT_NOMSG(context != nullptr);
  2137. DXASSERT_NOMSG(ident != nullptr);
  2138. DXASSERT_NOMSG(!baseType.isNull());
  2139. DeclContext* declContext = context->getTranslationUnitDecl();
  2140. TypeSourceInfo* typeSource = context->getTrivialTypeSourceInfo(baseType);
  2141. TypedefDecl* decl = TypedefDecl::Create(*context, declContext, NoLoc, NoLoc, &context->Idents.get(ident), typeSource);
  2142. declContext->addDecl(decl);
  2143. decl->setImplicit(true);
  2144. return decl;
  2145. }
  2146. class HLSLExternalSource : public ExternalSemaSource {
  2147. private:
  2148. // Inner types.
  2149. struct FindStructBasicTypeResult {
  2150. ArBasicKind Kind; // Kind of struct (eg, AR_OBJECT_TEXTURE2D)
  2151. unsigned int BasicKindsAsTypeIndex; // Index into g_ArBasicKinds*
  2152. FindStructBasicTypeResult(ArBasicKind kind,
  2153. unsigned int basicKindAsTypeIndex)
  2154. : Kind(kind), BasicKindsAsTypeIndex(basicKindAsTypeIndex) {}
  2155. bool Found() const { return Kind != AR_BASIC_UNKNOWN; }
  2156. };
  2157. // Declaration for matrix and vector templates.
  2158. ClassTemplateDecl* m_matrixTemplateDecl;
  2159. ClassTemplateDecl* m_vectorTemplateDecl;
  2160. // Namespace decl for hlsl intrin functions
  2161. NamespaceDecl* m_hlslNSDecl;
  2162. // Context being processed.
  2163. _Notnull_ ASTContext* m_context;
  2164. // Semantic analyzer being processed.
  2165. Sema* m_sema;
  2166. // Intrinsic tables available externally.
  2167. llvm::SmallVector<CComPtr<IDxcIntrinsicTable>, 2> m_intrinsicTables;
  2168. // Scalar types indexed by HLSLScalarType.
  2169. QualType m_scalarTypes[HLSLScalarTypeCount];
  2170. // Scalar types already built.
  2171. TypedefDecl* m_scalarTypeDefs[HLSLScalarTypeCount];
  2172. // Matrix types already built indexed by type, row-count, col-count. Should probably move to a sparse map. Instrument to figure out best initial size.
  2173. QualType m_matrixTypes[HLSLScalarTypeCount][4][4];
  2174. // Matrix types already built, in shorthand form.
  2175. TypedefDecl* m_matrixShorthandTypes[HLSLScalarTypeCount][4][4];
  2176. // Vector types already built.
  2177. QualType m_vectorTypes[HLSLScalarTypeCount][4];
  2178. TypedefDecl* m_vectorTypedefs[HLSLScalarTypeCount][4];
  2179. // BuiltinType for each scalar type.
  2180. QualType m_baseTypes[HLSLScalarTypeCount];
  2181. // Built-in object types declarations, indexed by basic kind constant.
  2182. CXXRecordDecl* m_objectTypeDecls[_countof(g_ArBasicKindsAsTypes)];
  2183. // Map from object decl to the object index.
  2184. using ObjectTypeDeclMapType = std::array<std::pair<CXXRecordDecl*,unsigned>, _countof(g_ArBasicKindsAsTypes)+_countof(g_DeprecatedEffectObjectNames)>;
  2185. ObjectTypeDeclMapType m_objectTypeDeclsMap;
  2186. // Mask for object which not has methods created.
  2187. uint64_t m_objectTypeLazyInitMask;
  2188. UsedIntrinsicStore m_usedIntrinsics;
  2189. /// <summary>Add all base QualTypes for each hlsl scalar types.</summary>
  2190. void AddBaseTypes();
  2191. /// <summary>Adds all supporting declarations to reference scalar types.</summary>
  2192. void AddHLSLScalarTypes();
  2193. QualType GetTemplateObjectDataType(_In_ CXXRecordDecl* recordDecl)
  2194. {
  2195. DXASSERT_NOMSG(recordDecl != nullptr);
  2196. TemplateParameterList* parameterList = recordDecl->getTemplateParameterList(0);
  2197. NamedDecl* parameterDecl = parameterList->getParam(0);
  2198. DXASSERT(parameterDecl->getKind() == Decl::Kind::TemplateTypeParm, "otherwise recordDecl isn't one of the built-in objects with templates");
  2199. TemplateTypeParmDecl* parmDecl = dyn_cast<TemplateTypeParmDecl>(parameterDecl);
  2200. return QualType(parmDecl->getTypeForDecl(), 0);
  2201. }
  2202. // Determines whether the given intrinsic parameter type has a single QualType mapping.
  2203. QualType GetSingleQualTypeForMapping(const HLSL_INTRINSIC* intrinsic, int index)
  2204. {
  2205. int templateRef = intrinsic->pArgs[index].uTemplateId;
  2206. int componentRef = intrinsic->pArgs[index].uComponentTypeId;
  2207. const HLSL_INTRINSIC_ARGUMENT* templateArg = &intrinsic->pArgs[templateRef];
  2208. const HLSL_INTRINSIC_ARGUMENT* componentArg = &intrinsic->pArgs[componentRef];
  2209. const HLSL_INTRINSIC_ARGUMENT* matrixArg = &intrinsic->pArgs[index];
  2210. if (
  2211. templateRef >= 0 &&
  2212. templateArg->uTemplateId == templateRef &&
  2213. !DoesLegalTemplateAcceptMultipleTypes(templateArg->uLegalTemplates) &&
  2214. componentRef >= 0 &&
  2215. componentRef != INTRIN_COMPTYPE_FROM_TYPE_ELT0 &&
  2216. componentArg->uComponentTypeId == 0 &&
  2217. !DoesComponentTypeAcceptMultipleTypes(componentArg->uLegalComponentTypes) &&
  2218. !IsRowOrColumnVariable(matrixArg->uCols) &&
  2219. !IsRowOrColumnVariable(matrixArg->uRows))
  2220. {
  2221. ArTypeObjectKind templateKind = g_LegalIntrinsicTemplates[templateArg->uLegalTemplates][0];
  2222. ArBasicKind elementKind = g_LegalIntrinsicCompTypes[componentArg->uLegalComponentTypes][0];
  2223. return NewSimpleAggregateType(templateKind, elementKind, 0, matrixArg->uRows, matrixArg->uCols);
  2224. }
  2225. return QualType();
  2226. }
  2227. // Adds a new template parameter declaration to the specified array and returns the type for the parameter.
  2228. QualType AddTemplateParamToArray(_In_z_ const char* name, _Inout_ CXXRecordDecl* recordDecl, int templateDepth,
  2229. _Inout_count_c_(g_MaxIntrinsicParamCount + 1) NamedDecl* (&templateParamNamedDecls)[g_MaxIntrinsicParamCount + 1],
  2230. _Inout_ size_t* templateParamNamedDeclsCount)
  2231. {
  2232. DXASSERT_NOMSG(name != nullptr);
  2233. DXASSERT_NOMSG(recordDecl != nullptr);
  2234. DXASSERT_NOMSG(templateParamNamedDecls != nullptr);
  2235. DXASSERT_NOMSG(templateParamNamedDeclsCount != nullptr);
  2236. DXASSERT(*templateParamNamedDeclsCount < _countof(templateParamNamedDecls), "otherwise constants should be updated");
  2237. _Analysis_assume_(*templateParamNamedDeclsCount < _countof(templateParamNamedDecls));
  2238. // Create the declaration for the template parameter.
  2239. IdentifierInfo* id = &m_context->Idents.get(StringRef(name));
  2240. TemplateTypeParmDecl* templateTypeParmDecl =
  2241. TemplateTypeParmDecl::Create(*m_context, recordDecl, NoLoc, NoLoc, templateDepth, *templateParamNamedDeclsCount,
  2242. id, TypenameTrue, ParameterPackFalse);
  2243. templateParamNamedDecls[*templateParamNamedDeclsCount] = templateTypeParmDecl;
  2244. // Create the type that the parameter represents.
  2245. QualType result = m_context->getTemplateTypeParmType(
  2246. templateDepth, *templateParamNamedDeclsCount, ParameterPackFalse, templateTypeParmDecl);
  2247. // Increment the declaration count for the array; as long as caller passes in both arguments,
  2248. // it need not concern itself with maintaining this value.
  2249. (*templateParamNamedDeclsCount)++;
  2250. return result;
  2251. }
  2252. // Adds a function specified by the given intrinsic to a record declaration.
  2253. // The template depth will be zero for records that don't have a "template<>" line
  2254. // even if conceptual; or one if it does have one.
  2255. void AddObjectIntrinsicTemplate(_Inout_ CXXRecordDecl* recordDecl, int templateDepth, _In_ const HLSL_INTRINSIC* intrinsic)
  2256. {
  2257. DXASSERT_NOMSG(recordDecl != nullptr);
  2258. DXASSERT_NOMSG(intrinsic != nullptr);
  2259. DXASSERT(intrinsic->uNumArgs > 0, "otherwise there isn't even an intrinsic name");
  2260. DXASSERT(intrinsic->uNumArgs <= (g_MaxIntrinsicParamCount + 1), "otherwise g_MaxIntrinsicParamCount should be updated");
  2261. // uNumArgs includes the result type, g_MaxIntrinsicParamCount doesn't, thus the +1.
  2262. _Analysis_assume_(intrinsic->uNumArgs <= (g_MaxIntrinsicParamCount + 1));
  2263. // TODO: implement template parameter constraints for HLSL intrinsic methods in declarations
  2264. //
  2265. // Build template parameters, parameter types, and the return type.
  2266. // Parameter declarations are built after the function is created, to use it as their scope.
  2267. //
  2268. unsigned int numParams = intrinsic->uNumArgs - 1;
  2269. NamedDecl* templateParamNamedDecls[g_MaxIntrinsicParamCount + 1];
  2270. size_t templateParamNamedDeclsCount = 0;
  2271. QualType argsQTs[g_MaxIntrinsicParamCount];
  2272. StringRef argNames[g_MaxIntrinsicParamCount];
  2273. QualType functionResultQT;
  2274. DXASSERT(
  2275. _countof(templateParamNamedDecls) >= numParams + 1,
  2276. "need enough templates for all parameters and the return type, otherwise constants need updating");
  2277. // Handle the return type.
  2278. // functionResultQT = GetSingleQualTypeForMapping(intrinsic, 0);
  2279. // if (functionResultQT.isNull()) {
  2280. // Workaround for template parameter argument count mismatch.
  2281. // Create template parameter for return type always
  2282. // TODO: reenable the check and skip template argument.
  2283. functionResultQT = AddTemplateParamToArray(
  2284. "TResult", recordDecl, templateDepth, templateParamNamedDecls,
  2285. &templateParamNamedDeclsCount);
  2286. // }
  2287. SmallVector<hlsl::ParameterModifier, g_MaxIntrinsicParamCount> paramMods;
  2288. InitParamMods(intrinsic, paramMods);
  2289. // Consider adding more cases where return type can be handled a priori. Ultimately #260431 should do significantly better.
  2290. // Handle parameters.
  2291. for (unsigned int i = 1; i < intrinsic->uNumArgs; i++)
  2292. {
  2293. //
  2294. // GetSingleQualTypeForMapping can be used here to remove unnecessary template arguments.
  2295. //
  2296. // However this may produce template instantiations with equivalent template arguments
  2297. // for overloaded methods. It's possible to resolve some of these by generating specializations,
  2298. // but the current intrinsic table has rules that are hard to process in their current form
  2299. // to find all cases.
  2300. //
  2301. char name[g_MaxIntrinsicParamName + 2];
  2302. name[0] = 'T';
  2303. name[1] = '\0';
  2304. strcat_s(name, intrinsic->pArgs[i].pName);
  2305. argsQTs[i - 1] = AddTemplateParamToArray(name, recordDecl, templateDepth, templateParamNamedDecls, &templateParamNamedDeclsCount);
  2306. // Change out/inout param to reference type.
  2307. if (paramMods[i-1].isAnyOut())
  2308. argsQTs[i - 1] = m_context->getLValueReferenceType(argsQTs[i - 1]);
  2309. argNames[i - 1] = StringRef(intrinsic->pArgs[i].pName);
  2310. }
  2311. // Create the declaration.
  2312. IdentifierInfo* ii = &m_context->Idents.get(StringRef(intrinsic->pArgs[0].pName));
  2313. DeclarationName declarationName = DeclarationName(ii);
  2314. CXXMethodDecl* functionDecl = CreateObjectFunctionDeclarationWithParams(*m_context, recordDecl,
  2315. functionResultQT, ArrayRef<QualType>(argsQTs, numParams), ArrayRef<StringRef>(argNames, numParams),
  2316. declarationName, true);
  2317. functionDecl->setImplicit(true);
  2318. // If the function is a template function, create the declaration and cross-reference.
  2319. if (templateParamNamedDeclsCount > 0)
  2320. {
  2321. hlsl::CreateFunctionTemplateDecl(
  2322. *m_context, recordDecl, functionDecl, templateParamNamedDecls, templateParamNamedDeclsCount);
  2323. }
  2324. }
  2325. // Checks whether the two specified intrinsics generate equivalent templates.
  2326. // For example: foo (any_int) and foo (any_float) are only unambiguous in the context
  2327. // of HLSL intrinsic rules, and their difference can't be expressed with C++ templates.
  2328. bool AreIntrinsicTemplatesEquivalent(const HLSL_INTRINSIC* left, const HLSL_INTRINSIC* right)
  2329. {
  2330. if (left == right)
  2331. {
  2332. return true;
  2333. }
  2334. if (left == nullptr || right == nullptr)
  2335. {
  2336. return false;
  2337. }
  2338. return (left->uNumArgs == right->uNumArgs &&
  2339. 0 == strcmp(left->pArgs[0].pName, right->pArgs[0].pName));
  2340. }
  2341. // Adds all the intrinsic methods that correspond to the specified type.
  2342. void AddObjectMethods(ArBasicKind kind, _In_ CXXRecordDecl* recordDecl, int templateDepth)
  2343. {
  2344. DXASSERT_NOMSG(recordDecl != nullptr);
  2345. DXASSERT_NOMSG(templateDepth >= 0);
  2346. const HLSL_INTRINSIC* intrinsics;
  2347. const HLSL_INTRINSIC* prior = nullptr;
  2348. size_t intrinsicCount;
  2349. GetIntrinsicMethods(kind, &intrinsics, &intrinsicCount);
  2350. DXASSERT(
  2351. (intrinsics == nullptr) == (intrinsicCount == 0),
  2352. "intrinsic table pointer must match count (null for zero, something valid otherwise");
  2353. while (intrinsicCount--)
  2354. {
  2355. if (!AreIntrinsicTemplatesEquivalent(intrinsics, prior))
  2356. {
  2357. AddObjectIntrinsicTemplate(recordDecl, templateDepth, intrinsics);
  2358. prior = intrinsics;
  2359. }
  2360. intrinsics++;
  2361. }
  2362. }
  2363. void AddDoubleSubscriptSupport(
  2364. _In_ ClassTemplateDecl* typeDecl,
  2365. _In_ CXXRecordDecl* recordDecl,
  2366. _In_z_ const char* memberName, QualType elementType, TemplateTypeParmDecl* templateTypeParmDecl,
  2367. _In_z_ const char* type0Name,
  2368. _In_z_ const char* type1Name,
  2369. _In_z_ const char* indexer0Name, QualType indexer0Type,
  2370. _In_z_ const char* indexer1Name, QualType indexer1Type)
  2371. {
  2372. DXASSERT_NOMSG(typeDecl != nullptr);
  2373. DXASSERT_NOMSG(recordDecl != nullptr);
  2374. DXASSERT_NOMSG(memberName != nullptr);
  2375. DXASSERT_NOMSG(!elementType.isNull());
  2376. DXASSERT_NOMSG(templateTypeParmDecl != nullptr);
  2377. DXASSERT_NOMSG(type0Name != nullptr);
  2378. DXASSERT_NOMSG(type1Name != nullptr);
  2379. DXASSERT_NOMSG(indexer0Name != nullptr);
  2380. DXASSERT_NOMSG(!indexer0Type.isNull());
  2381. DXASSERT_NOMSG(indexer1Name != nullptr);
  2382. DXASSERT_NOMSG(!indexer1Type.isNull());
  2383. //
  2384. // Add inner types to the templates to represent the following C++ code inside the class.
  2385. // public:
  2386. // class sample_slice_type
  2387. // {
  2388. // public: TElement operator[](uint3 index);
  2389. // };
  2390. // class sample_type
  2391. // {
  2392. // public: sample_slice_type operator[](uint slice);
  2393. // };
  2394. // sample_type sample;
  2395. //
  2396. // Variable names reflect this structure, but this code will also produce the types
  2397. // for .mips access.
  2398. //
  2399. const bool MutableTrue = true;
  2400. DeclarationName subscriptName = m_context->DeclarationNames.getCXXOperatorName(OO_Subscript);
  2401. CXXRecordDecl* sampleSliceTypeDecl = CXXRecordDecl::Create(*m_context, TTK_Class, recordDecl, NoLoc, NoLoc,
  2402. &m_context->Idents.get(StringRef(type1Name)));
  2403. sampleSliceTypeDecl->setAccess(AS_public);
  2404. sampleSliceTypeDecl->setImplicit();
  2405. recordDecl->addDecl(sampleSliceTypeDecl);
  2406. sampleSliceTypeDecl->startDefinition();
  2407. const bool MutableFalse = false;
  2408. FieldDecl* sliceHandleDecl = FieldDecl::Create(*m_context, sampleSliceTypeDecl, NoLoc, NoLoc,
  2409. &m_context->Idents.get(StringRef("handle")), indexer0Type,
  2410. m_context->CreateTypeSourceInfo(indexer0Type), nullptr, MutableFalse, ICIS_NoInit);
  2411. sliceHandleDecl->setAccess(AS_private);
  2412. sampleSliceTypeDecl->addDecl(sliceHandleDecl);
  2413. CXXMethodDecl* sampleSliceSubscriptDecl = CreateObjectFunctionDeclarationWithParams(*m_context,
  2414. sampleSliceTypeDecl, elementType,
  2415. ArrayRef<QualType>(indexer1Type), ArrayRef<StringRef>(StringRef(indexer1Name)), subscriptName, true);
  2416. hlsl::CreateFunctionTemplateDecl(*m_context, sampleSliceTypeDecl, sampleSliceSubscriptDecl,
  2417. reinterpret_cast<NamedDecl**>(&templateTypeParmDecl), 1);
  2418. sampleSliceTypeDecl->completeDefinition();
  2419. CXXRecordDecl* sampleTypeDecl = CXXRecordDecl::Create(*m_context, TTK_Class, recordDecl, NoLoc, NoLoc,
  2420. &m_context->Idents.get(StringRef(type0Name)));
  2421. sampleTypeDecl->setAccess(AS_public);
  2422. recordDecl->addDecl(sampleTypeDecl);
  2423. sampleTypeDecl->startDefinition();
  2424. sampleTypeDecl->setImplicit();
  2425. FieldDecl* sampleHandleDecl = FieldDecl::Create(*m_context, sampleTypeDecl, NoLoc, NoLoc,
  2426. &m_context->Idents.get(StringRef("handle")), indexer0Type,
  2427. m_context->CreateTypeSourceInfo(indexer0Type), nullptr, MutableFalse, ICIS_NoInit);
  2428. sampleHandleDecl->setAccess(AS_private);
  2429. sampleTypeDecl->addDecl(sampleHandleDecl);
  2430. QualType sampleSliceType = m_context->getRecordType(sampleSliceTypeDecl);
  2431. CXXMethodDecl* sampleSubscriptDecl = CreateObjectFunctionDeclarationWithParams(*m_context,
  2432. sampleTypeDecl, m_context->getRValueReferenceType(sampleSliceType), // TODO: choose LValueRef if writable.
  2433. ArrayRef<QualType>(indexer0Type), ArrayRef<StringRef>(StringRef(indexer0Name)), subscriptName, true);
  2434. sampleTypeDecl->completeDefinition();
  2435. // Add subscript attribute
  2436. AddHLSLSubscriptAttr(sampleSubscriptDecl, *m_context, HLSubscriptOpcode::DoubleSubscript);
  2437. QualType sampleTypeQT = m_context->getRecordType(sampleTypeDecl);
  2438. FieldDecl* sampleFieldDecl = FieldDecl::Create(*m_context, recordDecl, NoLoc, NoLoc,
  2439. &m_context->Idents.get(StringRef(memberName)), sampleTypeQT,
  2440. m_context->CreateTypeSourceInfo(sampleTypeQT), nullptr, MutableTrue, ICIS_NoInit);
  2441. sampleFieldDecl->setAccess(AS_public);
  2442. recordDecl->addDecl(sampleFieldDecl);
  2443. }
  2444. void AddObjectSubscripts(ArBasicKind kind, _In_ ClassTemplateDecl *typeDecl,
  2445. _In_ CXXRecordDecl *recordDecl,
  2446. SubscriptOperatorRecord op) {
  2447. DXASSERT_NOMSG(typeDecl != nullptr);
  2448. DXASSERT_NOMSG(recordDecl != nullptr);
  2449. DXASSERT_NOMSG(0 <= op.SubscriptCardinality &&
  2450. op.SubscriptCardinality <= 3);
  2451. DXASSERT(op.SubscriptCardinality > 0 ||
  2452. (op.HasMips == false && op.HasSample == false),
  2453. "objects that have .mips or .sample member also have a plain "
  2454. "subscript defined (otherwise static table is "
  2455. "likely incorrect, and this function won't know the cardinality "
  2456. "of the position parameter");
  2457. bool isReadWrite = GetBasicKindProps(kind) & BPROP_RWBUFFER;
  2458. DXASSERT(!isReadWrite || (op.HasMips == false && op.HasSample == false),
  2459. "read/write objects don't have .mips or .sample members");
  2460. // Return early if there is no work to be done.
  2461. if (op.SubscriptCardinality == 0) {
  2462. return;
  2463. }
  2464. const unsigned int templateDepth = 1;
  2465. // Add an operator[].
  2466. TemplateTypeParmDecl *templateTypeParmDecl = cast<TemplateTypeParmDecl>(
  2467. typeDecl->getTemplateParameters()->getParam(0));
  2468. QualType resultType = m_context->getTemplateTypeParmType(
  2469. templateDepth, 0, ParameterPackFalse, templateTypeParmDecl);
  2470. if (isReadWrite)
  2471. resultType = m_context->getLValueReferenceType(resultType, false);
  2472. else
  2473. resultType = m_context->getRValueReferenceType(resultType);
  2474. QualType indexType =
  2475. op.SubscriptCardinality == 1
  2476. ? m_context->UnsignedIntTy
  2477. : NewSimpleAggregateType(AR_TOBJ_VECTOR, AR_BASIC_UINT32, 0, 1,
  2478. op.SubscriptCardinality);
  2479. CXXMethodDecl *functionDecl = CreateObjectFunctionDeclarationWithParams(
  2480. *m_context, recordDecl, resultType, ArrayRef<QualType>(indexType),
  2481. ArrayRef<StringRef>(StringRef("index")),
  2482. m_context->DeclarationNames.getCXXOperatorName(OO_Subscript), true);
  2483. hlsl::CreateFunctionTemplateDecl(
  2484. *m_context, recordDecl, functionDecl,
  2485. reinterpret_cast<NamedDecl **>(&templateTypeParmDecl), 1);
  2486. // Add a .mips member if necessary.
  2487. QualType uintType = m_context->UnsignedIntTy;
  2488. if (op.HasMips) {
  2489. AddDoubleSubscriptSupport(typeDecl, recordDecl, "mips", resultType,
  2490. templateTypeParmDecl, "mips_type",
  2491. "mips_slice_type", "mipSlice", uintType, "pos",
  2492. indexType);
  2493. }
  2494. // Add a .sample member if necessary.
  2495. if (op.HasSample) {
  2496. AddDoubleSubscriptSupport(typeDecl, recordDecl, "sample", resultType,
  2497. templateTypeParmDecl, "sample_type",
  2498. "sample_slice_type", "sampleSlice", uintType,
  2499. "pos", indexType);
  2500. // TODO: support operator[][](indexType, uint).
  2501. }
  2502. }
  2503. static bool ObjectTypeDeclMapTypeCmp(const std::pair<CXXRecordDecl*,unsigned> &a,
  2504. const std::pair<CXXRecordDecl*,unsigned> &b) {
  2505. return a.first < b.first;
  2506. };
  2507. int FindObjectBasicKindIndex(const CXXRecordDecl* recordDecl) {
  2508. auto begin = m_objectTypeDeclsMap.begin();
  2509. auto end = m_objectTypeDeclsMap.end();
  2510. auto val = std::make_pair(const_cast<CXXRecordDecl*>(recordDecl), 0);
  2511. auto low = std::lower_bound(begin, end, val, ObjectTypeDeclMapTypeCmp);
  2512. if (low == end)
  2513. return -1;
  2514. if (recordDecl == low->first)
  2515. return low->second;
  2516. else
  2517. return -1;
  2518. }
  2519. // Adds all built-in HLSL object types.
  2520. void AddObjectTypes()
  2521. {
  2522. DXASSERT(m_context != nullptr, "otherwise caller hasn't initialized context yet");
  2523. QualType float4Type = LookupVectorType(HLSLScalarType_float, 4);
  2524. TypeSourceInfo *float4TypeSourceInfo = m_context->getTrivialTypeSourceInfo(float4Type, NoLoc);
  2525. m_objectTypeLazyInitMask = 0;
  2526. unsigned effectKindIndex = 0;
  2527. for (unsigned i = 0; i < _countof(g_ArBasicKindsAsTypes); i++)
  2528. {
  2529. ArBasicKind kind = g_ArBasicKindsAsTypes[i];
  2530. if (kind == AR_OBJECT_WAVE) { // wave objects are currently unused
  2531. continue;
  2532. }
  2533. if (kind == AR_OBJECT_LEGACY_EFFECT)
  2534. effectKindIndex = i;
  2535. DXASSERT(kind < _countof(g_ArBasicTypeNames), "g_ArBasicTypeNames has the wrong number of entries");
  2536. _Analysis_assume_(kind < _countof(g_ArBasicTypeNames));
  2537. const char* typeName = g_ArBasicTypeNames[kind];
  2538. uint8_t templateArgCount = g_ArBasicKindsTemplateCount[i];
  2539. CXXRecordDecl* recordDecl = nullptr;
  2540. if (templateArgCount == 0)
  2541. {
  2542. AddRecordTypeWithHandle(*m_context, &recordDecl, typeName);
  2543. DXASSERT(recordDecl != nullptr, "AddRecordTypeWithHandle failed to return the object declaration");
  2544. recordDecl->setImplicit(true);
  2545. }
  2546. else
  2547. {
  2548. DXASSERT(templateArgCount == 1 || templateArgCount == 2, "otherwise a new case has been added");
  2549. ClassTemplateDecl* typeDecl = nullptr;
  2550. TypeSourceInfo* typeDefault = TemplateHasDefaultType(kind) ? float4TypeSourceInfo : nullptr;
  2551. AddTemplateTypeWithHandle(*m_context, &typeDecl, &recordDecl, typeName, templateArgCount, typeDefault);
  2552. DXASSERT(typeDecl != nullptr, "AddTemplateTypeWithHandle failed to return the object declaration");
  2553. typeDecl->setImplicit(true);
  2554. recordDecl->setImplicit(true);
  2555. }
  2556. m_objectTypeDecls[i] = recordDecl;
  2557. m_objectTypeDeclsMap[i] = std::make_pair(recordDecl, i);
  2558. m_objectTypeLazyInitMask |= ((uint64_t)1)<<i;
  2559. }
  2560. // Create an alias for SamplerState. 'sampler' is very commonly used.
  2561. {
  2562. DeclContext* currentDeclContext = m_context->getTranslationUnitDecl();
  2563. IdentifierInfo& samplerId = m_context->Idents.get(StringRef("sampler"), tok::TokenKind::identifier);
  2564. TypeSourceInfo* samplerTypeSource = m_context->getTrivialTypeSourceInfo(GetBasicKindType(AR_OBJECT_SAMPLER));
  2565. TypedefDecl* samplerDecl = TypedefDecl::Create(*m_context, currentDeclContext, NoLoc, NoLoc, &samplerId, samplerTypeSource);
  2566. currentDeclContext->addDecl(samplerDecl);
  2567. samplerDecl->setImplicit(true);
  2568. // Create decls for each deprecated effect object type:
  2569. unsigned effectObjBase = _countof(g_ArBasicKindsAsTypes);
  2570. // TypeSourceInfo* effectObjTypeSource = m_context->getTrivialTypeSourceInfo(GetBasicKindType(AR_OBJECT_LEGACY_EFFECT));
  2571. for (unsigned i = 0; i < _countof(g_DeprecatedEffectObjectNames); i++) {
  2572. IdentifierInfo& idInfo = m_context->Idents.get(StringRef(g_DeprecatedEffectObjectNames[i]), tok::TokenKind::identifier);
  2573. //TypedefDecl* effectObjDecl = TypedefDecl::Create(*m_context, currentDeclContext, NoLoc, NoLoc, &idInfo, effectObjTypeSource);
  2574. CXXRecordDecl *effectObjDecl = CXXRecordDecl::Create(*m_context, TagTypeKind::TTK_Struct, currentDeclContext, NoLoc, NoLoc, &idInfo);
  2575. currentDeclContext->addDecl(effectObjDecl);
  2576. effectObjDecl->setImplicit(true);
  2577. m_objectTypeDeclsMap[i+effectObjBase] = std::make_pair(effectObjDecl, effectKindIndex);
  2578. }
  2579. }
  2580. // Make sure it's in order.
  2581. std::sort(m_objectTypeDeclsMap.begin(), m_objectTypeDeclsMap.end(), ObjectTypeDeclMapTypeCmp);
  2582. }
  2583. FunctionDecl* AddSubscriptSpecialization(
  2584. _In_ FunctionTemplateDecl* functionTemplate,
  2585. QualType objectElement,
  2586. const FindStructBasicTypeResult& findResult);
  2587. ImplicitCastExpr* CreateLValueToRValueCast(Expr* input) {
  2588. return ImplicitCastExpr::Create(*m_context, input->getType(), CK_LValueToRValue, input, nullptr, VK_RValue);
  2589. }
  2590. ImplicitCastExpr* CreateFlatConversionCast(Expr* input) {
  2591. return ImplicitCastExpr::Create(*m_context, input->getType(), CK_LValueToRValue, input, nullptr, VK_RValue);
  2592. }
  2593. HRESULT CombineDimensions(QualType leftType, QualType rightType, ArTypeObjectKind leftKind, ArTypeObjectKind rightKind, QualType *resultType);
  2594. clang::TypedefDecl *LookupMatrixShorthandType(HLSLScalarType scalarType, UINT rowCount, UINT colCount) {
  2595. DXASSERT_NOMSG(scalarType != HLSLScalarType::HLSLScalarType_unknown &&
  2596. rowCount <= 4 && colCount <= 4);
  2597. TypedefDecl *qts =
  2598. m_matrixShorthandTypes[scalarType][rowCount - 1][colCount - 1];
  2599. if (qts == nullptr) {
  2600. QualType type = LookupMatrixType(scalarType, rowCount, colCount);
  2601. qts = CreateMatrixSpecializationShorthand(*m_context, type, scalarType,
  2602. rowCount, colCount);
  2603. m_matrixShorthandTypes[scalarType][rowCount - 1][colCount - 1] = qts;
  2604. }
  2605. return qts;
  2606. }
  2607. clang::TypedefDecl *LookupVectorShorthandType(HLSLScalarType scalarType, UINT colCount) {
  2608. DXASSERT_NOMSG(scalarType != HLSLScalarType::HLSLScalarType_unknown &&
  2609. colCount <= 4);
  2610. TypedefDecl *qts = m_vectorTypedefs[scalarType][colCount - 1];
  2611. if (qts == nullptr) {
  2612. QualType type = LookupVectorType(scalarType, colCount);
  2613. qts = CreateVectorSpecializationShorthand(*m_context, type, scalarType,
  2614. colCount);
  2615. m_vectorTypedefs[scalarType][colCount - 1] = qts;
  2616. }
  2617. return qts;
  2618. }
  2619. public:
  2620. HLSLExternalSource() :
  2621. m_matrixTemplateDecl(nullptr),
  2622. m_vectorTemplateDecl(nullptr),
  2623. m_context(nullptr),
  2624. m_sema(nullptr)
  2625. {
  2626. memset(m_matrixTypes, 0, sizeof(m_matrixTypes));
  2627. memset(m_matrixShorthandTypes, 0, sizeof(m_matrixShorthandTypes));
  2628. memset(m_vectorTypes, 0, sizeof(m_vectorTypes));
  2629. memset(m_vectorTypedefs, 0, sizeof(m_vectorTypedefs));
  2630. memset(m_scalarTypes, 0, sizeof(m_scalarTypes));
  2631. memset(m_scalarTypeDefs, 0, sizeof(m_scalarTypeDefs));
  2632. memset(m_baseTypes, 0, sizeof(m_baseTypes));
  2633. }
  2634. ~HLSLExternalSource() { }
  2635. static HLSLExternalSource* FromSema(_In_ Sema* self)
  2636. {
  2637. DXASSERT_NOMSG(self != nullptr);
  2638. ExternalSemaSource* externalSource = self->getExternalSource();
  2639. DXASSERT(externalSource != nullptr, "otherwise caller shouldn't call HLSL-specific function");
  2640. HLSLExternalSource* hlsl = reinterpret_cast<HLSLExternalSource*>(externalSource);
  2641. return hlsl;
  2642. }
  2643. void InitializeSema(Sema& S) override
  2644. {
  2645. m_sema = &S;
  2646. S.addExternalSource(this);
  2647. AddObjectTypes();
  2648. AddStdIsEqualImplementation(S.getASTContext(), S);
  2649. for (auto && intrinsic : m_intrinsicTables) {
  2650. AddIntrinsicTableMethods(intrinsic);
  2651. }
  2652. }
  2653. void ForgetSema() override
  2654. {
  2655. m_sema = nullptr;
  2656. }
  2657. Sema* getSema() {
  2658. return m_sema;
  2659. }
  2660. TypedefDecl* LookupScalarTypeDef(HLSLScalarType scalarType) {
  2661. // We shouldn't create Typedef for built in scalar types.
  2662. // For built in scalar types, this funciton may be called for
  2663. // TypoCorrection. In that case, we return a nullptr.
  2664. if (m_scalarTypes[scalarType].isNull()) {
  2665. m_scalarTypeDefs[scalarType] = CreateGlobalTypedef(m_context, HLSLScalarTypeNames[scalarType], m_baseTypes[scalarType]);
  2666. m_scalarTypes[scalarType] = m_context->getTypeDeclType(m_scalarTypeDefs[scalarType]);
  2667. }
  2668. return m_scalarTypeDefs[scalarType];
  2669. }
  2670. QualType LookupMatrixType(HLSLScalarType scalarType, unsigned int rowCount, unsigned int colCount)
  2671. {
  2672. QualType qt = m_matrixTypes[scalarType][rowCount - 1][colCount - 1];
  2673. if (qt.isNull()) {
  2674. // lazy initialization of scalar types
  2675. if (m_scalarTypes[scalarType].isNull()) {
  2676. LookupScalarTypeDef(scalarType);
  2677. }
  2678. qt = GetOrCreateMatrixSpecialization(*m_context, m_sema, m_matrixTemplateDecl, m_scalarTypes[scalarType], rowCount, colCount);
  2679. m_matrixTypes[scalarType][rowCount - 1][colCount - 1] = qt;
  2680. }
  2681. return qt;
  2682. }
  2683. QualType LookupVectorType(HLSLScalarType scalarType, unsigned int colCount)
  2684. {
  2685. QualType qt = m_vectorTypes[scalarType][colCount - 1];
  2686. if (qt.isNull()) {
  2687. if (m_scalarTypes[scalarType].isNull()) {
  2688. LookupScalarTypeDef(scalarType);
  2689. }
  2690. qt = GetOrCreateVectorSpecialization(*m_context, m_sema, m_vectorTemplateDecl, m_scalarTypes[scalarType], colCount);
  2691. m_vectorTypes[scalarType][colCount - 1] = qt;
  2692. }
  2693. return qt;
  2694. }
  2695. void WarnMinPrecision(HLSLScalarType type, SourceLocation loc) {
  2696. // TODO: enalbe this once we introduce precise master option
  2697. bool UseMinPrecision = m_context->getLangOpts().UseMinPrecision;
  2698. if (type == HLSLScalarType_int_min12) {
  2699. const char *PromotedType =
  2700. UseMinPrecision ? HLSLScalarTypeNames[HLSLScalarType_int_min16]
  2701. : HLSLScalarTypeNames[HLSLScalarType_int16];
  2702. m_sema->Diag(loc, diag::warn_hlsl_sema_minprecision_promotion)
  2703. << HLSLScalarTypeNames[type] << PromotedType;
  2704. } else if (type == HLSLScalarType_float_min10) {
  2705. const char *PromotedType =
  2706. UseMinPrecision ? HLSLScalarTypeNames[HLSLScalarType_float_min16]
  2707. : HLSLScalarTypeNames[HLSLScalarType_float16];
  2708. m_sema->Diag(loc, diag::warn_hlsl_sema_minprecision_promotion)
  2709. << HLSLScalarTypeNames[type] << PromotedType;
  2710. }
  2711. if (!UseMinPrecision) {
  2712. if (type == HLSLScalarType_float_min16) {
  2713. m_sema->Diag(loc, diag::warn_hlsl_sema_minprecision_promotion)
  2714. << HLSLScalarTypeNames[type]
  2715. << HLSLScalarTypeNames[HLSLScalarType_float16];
  2716. } else if (type == HLSLScalarType_int_min16) {
  2717. m_sema->Diag(loc, diag::warn_hlsl_sema_minprecision_promotion)
  2718. << HLSLScalarTypeNames[type]
  2719. << HLSLScalarTypeNames[HLSLScalarType_int16];
  2720. } else if (type == HLSLScalarType_uint_min16) {
  2721. m_sema->Diag(loc, diag::warn_hlsl_sema_minprecision_promotion)
  2722. << HLSLScalarTypeNames[type]
  2723. << HLSLScalarTypeNames[HLSLScalarType_uint16];
  2724. }
  2725. }
  2726. }
  2727. bool DiagnoseHLSLScalarType(HLSLScalarType type, SourceLocation Loc) {
  2728. if (getSema()->getLangOpts().HLSLVersion < 2018) {
  2729. switch (type) {
  2730. case HLSLScalarType_float16:
  2731. case HLSLScalarType_float32:
  2732. case HLSLScalarType_float64:
  2733. case HLSLScalarType_int16:
  2734. case HLSLScalarType_int32:
  2735. case HLSLScalarType_uint16:
  2736. case HLSLScalarType_uint32:
  2737. m_sema->Diag(Loc, diag::err_hlsl_unsupported_keyword_for_version)
  2738. << HLSLScalarTypeNames[type] << "2018";
  2739. return false;
  2740. default:
  2741. break;
  2742. }
  2743. }
  2744. if (getSema()->getLangOpts().UseMinPrecision) {
  2745. switch (type) {
  2746. case HLSLScalarType_float16:
  2747. case HLSLScalarType_int16:
  2748. case HLSLScalarType_uint16:
  2749. m_sema->Diag(Loc, diag::err_hlsl_unsupported_keyword_for_min_precision)
  2750. << HLSLScalarTypeNames[type];
  2751. return false;
  2752. default:
  2753. break;
  2754. }
  2755. }
  2756. return true;
  2757. }
  2758. bool LookupUnqualified(LookupResult &R, Scope *S) override
  2759. {
  2760. const DeclarationNameInfo declName = R.getLookupNameInfo();
  2761. IdentifierInfo* idInfo = declName.getName().getAsIdentifierInfo();
  2762. if (idInfo == nullptr) {
  2763. return false;
  2764. }
  2765. // Currently template instantiation is blocked when a fatal error is
  2766. // detected. So no faulting-in types at this point, instead we simply
  2767. // back out.
  2768. if (this->m_sema->Diags.hasFatalErrorOccurred()) {
  2769. return false;
  2770. }
  2771. StringRef nameIdentifier = idInfo->getName();
  2772. HLSLScalarType parsedType;
  2773. int rowCount;
  2774. int colCount;
  2775. // Try parsing hlsl scalar types that is not initialized at AST time.
  2776. if (TryParseAny(nameIdentifier.data(), nameIdentifier.size(), &parsedType, &rowCount, &colCount, getSema()->getLangOpts())) {
  2777. assert(parsedType != HLSLScalarType_unknown && "otherwise, TryParseHLSLScalarType should not have succeeded.");
  2778. if (rowCount == 0 && colCount == 0) { // scalar
  2779. TypedefDecl *typeDecl = LookupScalarTypeDef(parsedType);
  2780. if (!typeDecl) return false;
  2781. R.addDecl(typeDecl);
  2782. }
  2783. else if (rowCount == 0) { // vector
  2784. TypedefDecl *qts = LookupVectorShorthandType(parsedType, colCount);
  2785. R.addDecl(qts);
  2786. }
  2787. else { // matrix
  2788. TypedefDecl* qts = LookupMatrixShorthandType(parsedType, rowCount, colCount);
  2789. R.addDecl(qts);
  2790. }
  2791. return true;
  2792. }
  2793. return false;
  2794. }
  2795. /// <summary>
  2796. /// Determines whether the specify record type is a matrix, another HLSL object, or a user-defined structure.
  2797. /// </sumary>
  2798. ArTypeObjectKind ClassifyRecordType(const RecordType* type)
  2799. {
  2800. DXASSERT_NOMSG(type != nullptr);
  2801. const CXXRecordDecl* typeRecordDecl = type->getAsCXXRecordDecl();
  2802. const ClassTemplateSpecializationDecl* templateSpecializationDecl = dyn_cast<ClassTemplateSpecializationDecl>(typeRecordDecl);
  2803. if (templateSpecializationDecl) {
  2804. ClassTemplateDecl *decl = templateSpecializationDecl->getSpecializedTemplate();
  2805. if (decl == m_matrixTemplateDecl)
  2806. return AR_TOBJ_MATRIX;
  2807. else if (decl == m_vectorTemplateDecl)
  2808. return AR_TOBJ_VECTOR;
  2809. DXASSERT(decl->isImplicit(), "otherwise object template decl is not set to implicit");
  2810. return AR_TOBJ_OBJECT;
  2811. }
  2812. if (typeRecordDecl && typeRecordDecl->isImplicit()) {
  2813. if (typeRecordDecl->getDeclContext()->isFileContext())
  2814. return AR_TOBJ_OBJECT;
  2815. else
  2816. return AR_TOBJ_INNER_OBJ;
  2817. }
  2818. return AR_TOBJ_COMPOUND;
  2819. }
  2820. /// <summary>Given a Clang type, determines whether it is a built-in object type (sampler, texture, etc).</summary>
  2821. bool IsBuiltInObjectType(QualType type)
  2822. {
  2823. type = GetStructuralForm(type);
  2824. if (!type.isNull() && type->isStructureOrClassType()) {
  2825. const RecordType* recordType = type->getAs<RecordType>();
  2826. return ClassifyRecordType(recordType) == AR_TOBJ_OBJECT;
  2827. }
  2828. return false;
  2829. }
  2830. /// <summary>
  2831. /// Given the specified type (typed a DeclContext for convenience), determines its RecordDecl,
  2832. /// possibly refering to original template record if it's a specialization; this makes the result
  2833. /// suitable for looking up in initialization tables.
  2834. /// </summary>
  2835. const CXXRecordDecl* GetRecordDeclForBuiltInOrStruct(const DeclContext* context)
  2836. {
  2837. const CXXRecordDecl* recordDecl;
  2838. if (const ClassTemplateSpecializationDecl* decl = dyn_cast<ClassTemplateSpecializationDecl>(context))
  2839. {
  2840. recordDecl = decl->getSpecializedTemplate()->getTemplatedDecl();
  2841. }
  2842. else
  2843. {
  2844. recordDecl = dyn_cast<CXXRecordDecl>(context);
  2845. }
  2846. return recordDecl;
  2847. }
  2848. /// <summary>Given a Clang type, return the ArTypeObjectKind classification, (eg AR_TOBJ_VECTOR).</summary>
  2849. ArTypeObjectKind GetTypeObjectKind(QualType type)
  2850. {
  2851. DXASSERT_NOMSG(!type.isNull());
  2852. type = GetStructuralForm(type);
  2853. if (type->isVoidType()) return AR_TOBJ_VOID;
  2854. if (type->isArrayType()) return AR_TOBJ_ARRAY;
  2855. if (type->isPointerType()) {
  2856. return AR_TOBJ_POINTER;
  2857. }
  2858. if (type->isStructureOrClassType()) {
  2859. const RecordType* recordType = type->getAs<RecordType>();
  2860. return ClassifyRecordType(recordType);
  2861. } else if (const InjectedClassNameType *ClassNameTy =
  2862. type->getAs<InjectedClassNameType>()) {
  2863. const CXXRecordDecl *typeRecordDecl = ClassNameTy->getDecl();
  2864. const ClassTemplateSpecializationDecl *templateSpecializationDecl =
  2865. dyn_cast<ClassTemplateSpecializationDecl>(typeRecordDecl);
  2866. if (templateSpecializationDecl) {
  2867. ClassTemplateDecl *decl =
  2868. templateSpecializationDecl->getSpecializedTemplate();
  2869. if (decl == m_matrixTemplateDecl)
  2870. return AR_TOBJ_MATRIX;
  2871. else if (decl == m_vectorTemplateDecl)
  2872. return AR_TOBJ_VECTOR;
  2873. DXASSERT(decl->isImplicit(),
  2874. "otherwise object template decl is not set to implicit");
  2875. return AR_TOBJ_OBJECT;
  2876. }
  2877. if (typeRecordDecl && typeRecordDecl->isImplicit()) {
  2878. if (typeRecordDecl->getDeclContext()->isFileContext())
  2879. return AR_TOBJ_OBJECT;
  2880. else
  2881. return AR_TOBJ_INNER_OBJ;
  2882. }
  2883. return AR_TOBJ_COMPOUND;
  2884. }
  2885. if (type->isBuiltinType()) return AR_TOBJ_BASIC;
  2886. if (type->isEnumeralType()) return AR_TOBJ_BASIC;
  2887. return AR_TOBJ_INVALID;
  2888. }
  2889. /// <summary>Gets the element type of a matrix or vector type (eg, the 'float' in 'float4x4' or 'float4').</summary>
  2890. QualType GetMatrixOrVectorElementType(QualType type)
  2891. {
  2892. type = GetStructuralForm(type);
  2893. const CXXRecordDecl* typeRecordDecl = type->getAsCXXRecordDecl();
  2894. DXASSERT_NOMSG(typeRecordDecl);
  2895. const ClassTemplateSpecializationDecl* templateSpecializationDecl = dyn_cast<ClassTemplateSpecializationDecl>(typeRecordDecl);
  2896. DXASSERT_NOMSG(templateSpecializationDecl);
  2897. DXASSERT_NOMSG(templateSpecializationDecl->getSpecializedTemplate() == m_matrixTemplateDecl ||
  2898. templateSpecializationDecl->getSpecializedTemplate() == m_vectorTemplateDecl);
  2899. return templateSpecializationDecl->getTemplateArgs().get(0).getAsType();
  2900. }
  2901. /// <summary>Gets the type with structural information (elements and shape) for the given type.</summary>
  2902. /// <remarks>This function will strip lvalue/rvalue references, attributes and qualifiers.</remarks>
  2903. QualType GetStructuralForm(QualType type)
  2904. {
  2905. if (type.isNull()) {
  2906. return type;
  2907. }
  2908. const ReferenceType *RefType = nullptr;
  2909. const AttributedType *AttrType = nullptr;
  2910. while ( (RefType = dyn_cast<ReferenceType>(type)) ||
  2911. (AttrType = dyn_cast<AttributedType>(type)))
  2912. {
  2913. type = RefType ? RefType->getPointeeType() : AttrType->getEquivalentType();
  2914. }
  2915. return type->getCanonicalTypeUnqualified();
  2916. }
  2917. /// <summary>Given a Clang type, return the ArBasicKind classification for its contents.</summary>
  2918. ArBasicKind GetTypeElementKind(QualType type)
  2919. {
  2920. type = GetStructuralForm(type);
  2921. ArTypeObjectKind kind = GetTypeObjectKind(type);
  2922. if (kind == AR_TOBJ_MATRIX || kind == AR_TOBJ_VECTOR) {
  2923. QualType elementType = GetMatrixOrVectorElementType(type);
  2924. return GetTypeElementKind(elementType);
  2925. }
  2926. if (type->isArrayType()) {
  2927. const ArrayType* arrayType = type->getAsArrayTypeUnsafe();
  2928. return GetTypeElementKind(arrayType->getElementType());
  2929. }
  2930. if (kind == AR_TOBJ_INNER_OBJ) {
  2931. return AR_OBJECT_INNER;
  2932. } else if (kind == AR_TOBJ_OBJECT) {
  2933. // Classify the object as the element type.
  2934. const CXXRecordDecl* typeRecordDecl = GetRecordDeclForBuiltInOrStruct(type->getAsCXXRecordDecl());
  2935. int index = FindObjectBasicKindIndex(typeRecordDecl);
  2936. // NOTE: this will likely need to be updated for specialized records
  2937. DXASSERT(index != -1, "otherwise can't find type we already determined was an object");
  2938. return g_ArBasicKindsAsTypes[index];
  2939. }
  2940. CanQualType canType = type->getCanonicalTypeUnqualified();
  2941. return BasicTypeForScalarType(canType);
  2942. }
  2943. ArBasicKind BasicTypeForScalarType(CanQualType type)
  2944. {
  2945. if (const BuiltinType *BT = dyn_cast<BuiltinType>(type))
  2946. {
  2947. switch (BT->getKind())
  2948. {
  2949. case BuiltinType::Bool: return AR_BASIC_BOOL;
  2950. case BuiltinType::Double: return AR_BASIC_FLOAT64;
  2951. case BuiltinType::Float: return AR_BASIC_FLOAT32;
  2952. case BuiltinType::Half: return m_context->getLangOpts().UseMinPrecision ? AR_BASIC_MIN16FLOAT : AR_BASIC_FLOAT16;
  2953. case BuiltinType::Int: return AR_BASIC_INT32;
  2954. case BuiltinType::UInt: return AR_BASIC_UINT32;
  2955. case BuiltinType::Short: return m_context->getLangOpts().UseMinPrecision ? AR_BASIC_MIN16INT : AR_BASIC_INT16;
  2956. case BuiltinType::UShort: return m_context->getLangOpts().UseMinPrecision ? AR_BASIC_MIN16UINT : AR_BASIC_UINT16;
  2957. case BuiltinType::Long: return AR_BASIC_INT32;
  2958. case BuiltinType::ULong: return AR_BASIC_UINT32;
  2959. case BuiltinType::LongLong: return AR_BASIC_INT64;
  2960. case BuiltinType::ULongLong: return AR_BASIC_UINT64;
  2961. case BuiltinType::Min12Int: return AR_BASIC_MIN12INT;
  2962. case BuiltinType::Min10Float: return AR_BASIC_MIN10FLOAT;
  2963. case BuiltinType::LitFloat: return AR_BASIC_LITERAL_FLOAT;
  2964. case BuiltinType::LitInt: return AR_BASIC_LITERAL_INT;
  2965. default:
  2966. // Only builtin types that have basickind equivalents.
  2967. break;
  2968. }
  2969. }
  2970. if (const EnumType *ET = dyn_cast<EnumType>(type)) {
  2971. if (ET->getDecl()->isScopedUsingClassTag())
  2972. return AR_BASIC_ENUM_CLASS;
  2973. return AR_BASIC_ENUM;
  2974. }
  2975. return AR_BASIC_UNKNOWN;
  2976. }
  2977. void AddIntrinsicTableMethods(_In_ IDxcIntrinsicTable *table) {
  2978. DXASSERT_NOMSG(table != nullptr);
  2979. // Function intrinsics are added on-demand, objects get template methods.
  2980. for (unsigned i = 0; i < _countof(g_ArBasicKindsAsTypes); i++) {
  2981. // Grab information already processed by AddObjectTypes.
  2982. ArBasicKind kind = g_ArBasicKindsAsTypes[i];
  2983. const char *typeName = g_ArBasicTypeNames[kind];
  2984. uint8_t templateArgCount = g_ArBasicKindsTemplateCount[i];
  2985. DXASSERT(templateArgCount <= 2, "otherwise a new case has been added");
  2986. int startDepth = (templateArgCount == 0) ? 0 : 1;
  2987. CXXRecordDecl *recordDecl = m_objectTypeDecls[i];
  2988. if (recordDecl == nullptr) {
  2989. DXASSERT(kind == AR_OBJECT_WAVE, "else objects other than reserved not initialized");
  2990. continue;
  2991. }
  2992. // This is a variation of AddObjectMethods using the new table.
  2993. const HLSL_INTRINSIC *pIntrinsic = nullptr;
  2994. const HLSL_INTRINSIC *pPrior = nullptr;
  2995. UINT64 lookupCookie = 0;
  2996. CA2W wideTypeName(typeName);
  2997. HRESULT found = table->LookupIntrinsic(wideTypeName, L"*", &pIntrinsic, &lookupCookie);
  2998. while (pIntrinsic != nullptr && SUCCEEDED(found)) {
  2999. if (!AreIntrinsicTemplatesEquivalent(pIntrinsic, pPrior)) {
  3000. AddObjectIntrinsicTemplate(recordDecl, startDepth, pIntrinsic);
  3001. // NOTE: this only works with the current implementation because
  3002. // intrinsics are alive as long as the table is alive.
  3003. pPrior = pIntrinsic;
  3004. }
  3005. found = table->LookupIntrinsic(wideTypeName, L"*", &pIntrinsic, &lookupCookie);
  3006. }
  3007. }
  3008. }
  3009. void RegisterIntrinsicTable(_In_ IDxcIntrinsicTable *table) {
  3010. DXASSERT_NOMSG(table != nullptr);
  3011. m_intrinsicTables.push_back(table);
  3012. // If already initialized, add methods immediately.
  3013. if (m_sema != nullptr) {
  3014. AddIntrinsicTableMethods(table);
  3015. }
  3016. }
  3017. HLSLScalarType ScalarTypeForBasic(ArBasicKind kind)
  3018. {
  3019. DXASSERT(kind < AR_BASIC_COUNT, "otherwise caller didn't check that the value was in range");
  3020. switch (kind) {
  3021. case AR_BASIC_BOOL: return HLSLScalarType_bool;
  3022. case AR_BASIC_LITERAL_FLOAT: return HLSLScalarType_float_lit;
  3023. case AR_BASIC_FLOAT16: return HLSLScalarType_float_min16;
  3024. case AR_BASIC_FLOAT32_PARTIAL_PRECISION:
  3025. return HLSLScalarType_float;
  3026. case AR_BASIC_FLOAT32: return HLSLScalarType_float;
  3027. case AR_BASIC_FLOAT64: return HLSLScalarType_double;
  3028. case AR_BASIC_LITERAL_INT: return HLSLScalarType_int_lit;
  3029. case AR_BASIC_INT8: return HLSLScalarType_int;
  3030. case AR_BASIC_UINT8: return HLSLScalarType_uint;
  3031. case AR_BASIC_INT16: return HLSLScalarType_int16;
  3032. case AR_BASIC_UINT16: return HLSLScalarType_uint16;
  3033. case AR_BASIC_INT32: return HLSLScalarType_int;
  3034. case AR_BASIC_UINT32: return HLSLScalarType_uint;
  3035. case AR_BASIC_MIN10FLOAT: return HLSLScalarType_float_min10;
  3036. case AR_BASIC_MIN16FLOAT: return HLSLScalarType_float_min16;
  3037. case AR_BASIC_MIN12INT: return HLSLScalarType_int_min12;
  3038. case AR_BASIC_MIN16INT: return HLSLScalarType_int_min16;
  3039. case AR_BASIC_MIN16UINT: return HLSLScalarType_uint_min16;
  3040. case AR_BASIC_INT64: return HLSLScalarType_int64;
  3041. case AR_BASIC_UINT64: return HLSLScalarType_uint64;
  3042. default:
  3043. return HLSLScalarType_unknown;
  3044. }
  3045. }
  3046. QualType GetBasicKindType(ArBasicKind kind)
  3047. {
  3048. DXASSERT_VALIDBASICKIND(kind);
  3049. switch (kind) {
  3050. case AR_OBJECT_NULL: return m_context->VoidTy;
  3051. case AR_BASIC_BOOL: return m_context->BoolTy;
  3052. case AR_BASIC_LITERAL_FLOAT: return m_context->LitFloatTy;
  3053. case AR_BASIC_FLOAT16: return m_context->HalfTy;
  3054. case AR_BASIC_FLOAT32_PARTIAL_PRECISION: return m_context->FloatTy;
  3055. case AR_BASIC_FLOAT32: return m_context->FloatTy;
  3056. case AR_BASIC_FLOAT64: return m_context->DoubleTy;
  3057. case AR_BASIC_LITERAL_INT: return m_context->LitIntTy;
  3058. case AR_BASIC_INT8: return m_context->IntTy;
  3059. case AR_BASIC_UINT8: return m_context->UnsignedIntTy;
  3060. case AR_BASIC_INT16: return m_context->ShortTy;
  3061. case AR_BASIC_UINT16: return m_context->UnsignedShortTy;
  3062. case AR_BASIC_INT32: return m_context->IntTy;
  3063. case AR_BASIC_UINT32: return m_context->UnsignedIntTy;
  3064. case AR_BASIC_INT64: return m_context->LongLongTy;
  3065. case AR_BASIC_UINT64: return m_context->UnsignedLongLongTy;
  3066. case AR_BASIC_MIN10FLOAT: return m_scalarTypes[HLSLScalarType_float_min10];
  3067. case AR_BASIC_MIN16FLOAT: return m_scalarTypes[HLSLScalarType_float_min16];
  3068. case AR_BASIC_MIN12INT: return m_scalarTypes[HLSLScalarType_int_min12];
  3069. case AR_BASIC_MIN16INT: return m_scalarTypes[HLSLScalarType_int_min16];
  3070. case AR_BASIC_MIN16UINT: return m_scalarTypes[HLSLScalarType_uint_min16];
  3071. case AR_OBJECT_STRING: return QualType();
  3072. case AR_OBJECT_LEGACY_EFFECT: // used for all legacy effect object types
  3073. case AR_OBJECT_TEXTURE1D:
  3074. case AR_OBJECT_TEXTURE1D_ARRAY:
  3075. case AR_OBJECT_TEXTURE2D:
  3076. case AR_OBJECT_TEXTURE2D_ARRAY:
  3077. case AR_OBJECT_TEXTURE3D:
  3078. case AR_OBJECT_TEXTURECUBE:
  3079. case AR_OBJECT_TEXTURECUBE_ARRAY:
  3080. case AR_OBJECT_TEXTURE2DMS:
  3081. case AR_OBJECT_TEXTURE2DMS_ARRAY:
  3082. case AR_OBJECT_SAMPLER:
  3083. case AR_OBJECT_SAMPLERCOMPARISON:
  3084. case AR_OBJECT_BUFFER:
  3085. case AR_OBJECT_POINTSTREAM:
  3086. case AR_OBJECT_LINESTREAM:
  3087. case AR_OBJECT_TRIANGLESTREAM:
  3088. case AR_OBJECT_INPUTPATCH:
  3089. case AR_OBJECT_OUTPUTPATCH:
  3090. case AR_OBJECT_RWTEXTURE1D:
  3091. case AR_OBJECT_RWTEXTURE1D_ARRAY:
  3092. case AR_OBJECT_RWTEXTURE2D:
  3093. case AR_OBJECT_RWTEXTURE2D_ARRAY:
  3094. case AR_OBJECT_RWTEXTURE3D:
  3095. case AR_OBJECT_RWBUFFER:
  3096. case AR_OBJECT_BYTEADDRESS_BUFFER:
  3097. case AR_OBJECT_RWBYTEADDRESS_BUFFER:
  3098. case AR_OBJECT_STRUCTURED_BUFFER:
  3099. case AR_OBJECT_RWSTRUCTURED_BUFFER:
  3100. case AR_OBJECT_APPEND_STRUCTURED_BUFFER:
  3101. case AR_OBJECT_CONSUME_STRUCTURED_BUFFER:
  3102. case AR_OBJECT_WAVE:
  3103. {
  3104. const ArBasicKind* match = std::find(g_ArBasicKindsAsTypes, &g_ArBasicKindsAsTypes[_countof(g_ArBasicKindsAsTypes)], kind);
  3105. DXASSERT(match != &g_ArBasicKindsAsTypes[_countof(g_ArBasicKindsAsTypes)], "otherwise can't find constant in basic kinds");
  3106. size_t index = match - g_ArBasicKindsAsTypes;
  3107. return m_context->getTagDeclType(this->m_objectTypeDecls[index]);
  3108. }
  3109. case AR_OBJECT_SAMPLER1D:
  3110. case AR_OBJECT_SAMPLER2D:
  3111. case AR_OBJECT_SAMPLER3D:
  3112. case AR_OBJECT_SAMPLERCUBE:
  3113. // Turn dimension-typed samplers into sampler states.
  3114. return GetBasicKindType(AR_OBJECT_SAMPLER);
  3115. case AR_OBJECT_STATEBLOCK:
  3116. case AR_OBJECT_RASTERIZER:
  3117. case AR_OBJECT_DEPTHSTENCIL:
  3118. case AR_OBJECT_BLEND:
  3119. case AR_OBJECT_RWSTRUCTURED_BUFFER_ALLOC:
  3120. case AR_OBJECT_RWSTRUCTURED_BUFFER_CONSUME:
  3121. default:
  3122. return QualType();
  3123. }
  3124. }
  3125. /// <summary>Promotes the specified expression to an integer type if it's a boolean type.</summary
  3126. /// <param name="E">Expression to typecast.</param>
  3127. /// <returns>E typecast to a integer type if it's a valid boolean type; E otherwise.</returns>
  3128. ExprResult PromoteToIntIfBool(ExprResult& E);
  3129. QualType NewQualifiedType(UINT64 qwUsages, QualType type)
  3130. {
  3131. // NOTE: NewQualifiedType does quite a bit more in the prior compiler
  3132. (void)(qwUsages);
  3133. return type;
  3134. }
  3135. QualType NewSimpleAggregateType(
  3136. _In_ ArTypeObjectKind ExplicitKind,
  3137. _In_ ArBasicKind componentType,
  3138. _In_ UINT64 qwQual,
  3139. _In_ UINT uRows,
  3140. _In_ UINT uCols)
  3141. {
  3142. DXASSERT_VALIDBASICKIND(componentType);
  3143. QualType pType; // The type to return.
  3144. QualType pEltType = GetBasicKindType(componentType);
  3145. DXASSERT(!pEltType.isNull(), "otherwise caller is specifying an incorrect basic kind type");
  3146. // TODO: handle adding qualifications like const
  3147. pType = NewQualifiedType(
  3148. qwQual & ~(UINT64)(AR_QUAL_COLMAJOR | AR_QUAL_ROWMAJOR),
  3149. pEltType);
  3150. if (uRows > 1 ||
  3151. uCols > 1 ||
  3152. ExplicitKind == AR_TOBJ_VECTOR ||
  3153. ExplicitKind == AR_TOBJ_MATRIX)
  3154. {
  3155. HLSLScalarType scalarType = ScalarTypeForBasic(componentType);
  3156. DXASSERT(scalarType != HLSLScalarType_unknown, "otherwise caller is specifying an incorrect type");
  3157. if ((uRows == 1 &&
  3158. ExplicitKind != AR_TOBJ_MATRIX) ||
  3159. ExplicitKind == AR_TOBJ_VECTOR)
  3160. {
  3161. pType = LookupVectorType(scalarType, uCols);
  3162. }
  3163. else
  3164. {
  3165. pType = LookupMatrixType(scalarType, uRows, uCols);
  3166. }
  3167. // TODO: handle colmajor/rowmajor
  3168. //if ((qwQual & (AR_QUAL_COLMAJOR | AR_QUAL_ROWMAJOR)) != 0)
  3169. //{
  3170. // VN(pType = NewQualifiedType(pSrcLoc,
  3171. // qwQual & (AR_QUAL_COLMAJOR |
  3172. // AR_QUAL_ROWMAJOR),
  3173. // pMatrix));
  3174. //}
  3175. //else
  3176. //{
  3177. // pType = pMatrix;
  3178. //}
  3179. }
  3180. return pType;
  3181. }
  3182. /// <summary>Attempts to match Args to the signature specification in pIntrinsic.</summary>
  3183. /// <param name="pIntrinsic">Intrinsic function to match.</param>
  3184. /// <param name="objectElement">Type element on the class intrinsic belongs to; possibly null (eg, 'float' in 'Texture2D<float>').</param>
  3185. /// <param name="Args">Invocation arguments to match.</param>
  3186. /// <param name="argTypes">After exectuion, type of arguments.</param>
  3187. /// <param name="argCount">After execution, number of arguments in argTypes.</param>
  3188. /// <remarks>On success, argTypes includes the clang Types to use for the signature, with the first being the return type.</remarks>
  3189. bool MatchArguments(
  3190. const _In_ HLSL_INTRINSIC *pIntrinsic,
  3191. _In_ QualType objectElement,
  3192. _In_ ArrayRef<Expr *> Args,
  3193. _Out_writes_(g_MaxIntrinsicParamCount + 1) QualType(&argTypes)[g_MaxIntrinsicParamCount + 1],
  3194. _Out_range_(0, g_MaxIntrinsicParamCount + 1) size_t* argCount);
  3195. /// <summary>Validate object element on intrinsic to catch case like integer on Sample.</summary>
  3196. /// <param name="pIntrinsic">Intrinsic function to validate.</param>
  3197. /// <param name="objectElement">Type element on the class intrinsic belongs to; possibly null (eg, 'float' in 'Texture2D<float>').</param>
  3198. bool IsValidateObjectElement(
  3199. _In_ const HLSL_INTRINSIC *pIntrinsic,
  3200. _In_ QualType objectElement);
  3201. // Returns the iterator with the first entry that matches the requirement
  3202. IntrinsicDefIter FindIntrinsicByNameAndArgCount(
  3203. _In_count_(tableSize) const HLSL_INTRINSIC* table,
  3204. size_t tableSize,
  3205. StringRef typeName,
  3206. StringRef nameIdentifier,
  3207. size_t argumentCount)
  3208. {
  3209. // This is implemented by a linear scan for now.
  3210. // We tested binary search on tables, and there was no performance gain on
  3211. // samples probably for the following reasons.
  3212. // 1. The tables are not big enough to make noticable difference
  3213. // 2. The user of this function assumes that it returns the first entry in
  3214. // the table that matches name and argument count. So even in the binary
  3215. // search, we have to scan backwards until the entry does not match the name
  3216. // or arg count. For linear search this is not a problem
  3217. for (unsigned int i = 0; i < tableSize; i++) {
  3218. const HLSL_INTRINSIC* pIntrinsic = &table[i];
  3219. // Do some quick checks to verify size and name.
  3220. if (pIntrinsic->uNumArgs != 1 + argumentCount) {
  3221. continue;
  3222. }
  3223. if (!nameIdentifier.equals(StringRef(pIntrinsic->pArgs[0].pName))) {
  3224. continue;
  3225. }
  3226. return IntrinsicDefIter::CreateStart(table, tableSize, pIntrinsic,
  3227. IntrinsicTableDefIter::CreateStart(m_intrinsicTables, typeName, nameIdentifier, argumentCount));
  3228. }
  3229. return IntrinsicDefIter::CreateStart(table, tableSize, table + tableSize,
  3230. IntrinsicTableDefIter::CreateStart(m_intrinsicTables, typeName, nameIdentifier, argumentCount));
  3231. }
  3232. bool AddOverloadedCallCandidates(
  3233. UnresolvedLookupExpr *ULE,
  3234. ArrayRef<Expr *> Args,
  3235. OverloadCandidateSet &CandidateSet,
  3236. bool PartialOverloading) override
  3237. {
  3238. DXASSERT_NOMSG(ULE != nullptr);
  3239. const DeclarationNameInfo declName = ULE->getNameInfo();
  3240. IdentifierInfo* idInfo = declName.getName().getAsIdentifierInfo();
  3241. if (idInfo == nullptr)
  3242. {
  3243. return false;
  3244. }
  3245. StringRef nameIdentifier = idInfo->getName();
  3246. IntrinsicDefIter cursor = FindIntrinsicByNameAndArgCount(
  3247. g_Intrinsics, _countof(g_Intrinsics), StringRef(), nameIdentifier, Args.size());
  3248. IntrinsicDefIter end = IntrinsicDefIter::CreateEnd(
  3249. g_Intrinsics, _countof(g_Intrinsics), IntrinsicTableDefIter::CreateEnd(m_intrinsicTables));
  3250. while (cursor != end)
  3251. {
  3252. // If this is the intrinsic we're interested in, build up a representation
  3253. // of the types we need.
  3254. const HLSL_INTRINSIC* pIntrinsic = *cursor;
  3255. LPCSTR tableName = cursor.GetTableName();
  3256. LPCSTR lowering = cursor.GetLoweringStrategy();
  3257. DXASSERT(
  3258. pIntrinsic->uNumArgs <= g_MaxIntrinsicParamCount + 1,
  3259. "otherwise g_MaxIntrinsicParamCount needs to be updated for wider signatures");
  3260. QualType functionArgTypes[g_MaxIntrinsicParamCount + 1];
  3261. size_t functionArgTypeCount = 0;
  3262. if (!MatchArguments(pIntrinsic, QualType(), Args, functionArgTypes, &functionArgTypeCount))
  3263. {
  3264. ++cursor;
  3265. continue;
  3266. }
  3267. // Get or create the overload we're interested in.
  3268. FunctionDecl* intrinsicFuncDecl = nullptr;
  3269. std::pair<UsedIntrinsicStore::iterator, bool> insertResult = m_usedIntrinsics.insert(UsedIntrinsic(
  3270. pIntrinsic, functionArgTypes, functionArgTypeCount));
  3271. bool insertedNewValue = insertResult.second;
  3272. if (insertedNewValue)
  3273. {
  3274. DXASSERT(tableName, "otherwise IDxcIntrinsicTable::GetTableName() failed");
  3275. intrinsicFuncDecl = AddHLSLIntrinsicFunction(*m_context, m_hlslNSDecl, tableName, lowering, pIntrinsic, functionArgTypes, functionArgTypeCount);
  3276. insertResult.first->setFunctionDecl(intrinsicFuncDecl);
  3277. }
  3278. else
  3279. {
  3280. intrinsicFuncDecl = (*insertResult.first).getFunctionDecl();
  3281. }
  3282. OverloadCandidate& candidate = CandidateSet.addCandidate();
  3283. candidate.Function = intrinsicFuncDecl;
  3284. candidate.FoundDecl.setDecl(intrinsicFuncDecl);
  3285. candidate.Viable = true;
  3286. return true;
  3287. }
  3288. return false;
  3289. }
  3290. bool Initialize(ASTContext& context)
  3291. {
  3292. m_context = &context;
  3293. m_hlslNSDecl = NamespaceDecl::Create(context, context.getTranslationUnitDecl(),
  3294. /*Inline*/ false, SourceLocation(),
  3295. SourceLocation(), &context.Idents.get("hlsl"),
  3296. /*PrevDecl*/ nullptr);
  3297. m_hlslNSDecl->setImplicit();
  3298. AddBaseTypes();
  3299. AddHLSLScalarTypes();
  3300. AddHLSLVectorTemplate(*m_context, &m_vectorTemplateDecl);
  3301. DXASSERT(m_vectorTemplateDecl != nullptr, "AddHLSLVectorTypes failed to return the vector template declaration");
  3302. AddHLSLMatrixTemplate(*m_context, m_vectorTemplateDecl, &m_matrixTemplateDecl);
  3303. DXASSERT(m_matrixTemplateDecl != nullptr, "AddHLSLMatrixTypes failed to return the matrix template declaration");
  3304. return true;
  3305. }
  3306. /// <summary>Checks whether the specified type is numeric or composed of numeric elements exclusively.</summary>
  3307. bool IsTypeNumeric(QualType type, _Out_ UINT* count);
  3308. /// <summary>Checks whether the specified type is a scalar type.</summary>
  3309. bool IsScalarType(const QualType& type) {
  3310. DXASSERT(!type.isNull(), "caller should validate its type is initialized");
  3311. return BasicTypeForScalarType(type->getCanonicalTypeUnqualified()) != AR_BASIC_UNKNOWN;
  3312. }
  3313. /// <summary>Checks whether the specified value is a valid vector size.</summary>
  3314. bool IsValidVectorSize(size_t length) {
  3315. return 1 <= length && length <= 4;
  3316. }
  3317. /// <summary>Checks whether the specified value is a valid matrix row or column size.</summary>
  3318. bool IsValidMatrixColOrRowSize(size_t length) {
  3319. return 1 <= length && length <= 4;
  3320. }
  3321. bool IsValidTemplateArgumentType(SourceLocation argLoc, const QualType& type, bool requireScalar) {
  3322. if (type.isNull()) {
  3323. return false;
  3324. }
  3325. if (type.hasQualifiers()) {
  3326. return false;
  3327. }
  3328. // TemplateTypeParm here will be construction of vector return template in matrix operator[]
  3329. if (type->getTypeClass() == Type::TemplateTypeParm)
  3330. return true;
  3331. QualType qt = GetStructuralForm(type);
  3332. if (requireScalar) {
  3333. if (!IsScalarType(qt)) {
  3334. m_sema->Diag(argLoc, diag::err_hlsl_typeintemplateargument_requires_scalar) << type;
  3335. return false;
  3336. }
  3337. return true;
  3338. }
  3339. else {
  3340. ArTypeObjectKind objectKind = GetTypeObjectKind(qt);
  3341. if (qt->isArrayType()) {
  3342. const ArrayType* arrayType = qt->getAsArrayTypeUnsafe();
  3343. return IsValidTemplateArgumentType(argLoc, arrayType->getElementType(), false);
  3344. }
  3345. else if (objectKind == AR_TOBJ_VECTOR) {
  3346. bool valid = true;
  3347. if (!IsValidVectorSize(GetHLSLVecSize(type))) {
  3348. valid = false;
  3349. m_sema->Diag(argLoc, diag::err_hlsl_unsupportedvectorsize) << type << GetHLSLVecSize(type);
  3350. }
  3351. if (!IsScalarType(GetMatrixOrVectorElementType(type))) {
  3352. valid = false;
  3353. m_sema->Diag(argLoc, diag::err_hlsl_unsupportedvectortype) << type << GetMatrixOrVectorElementType(type);
  3354. }
  3355. return valid;
  3356. }
  3357. else if (objectKind == AR_TOBJ_MATRIX) {
  3358. bool valid = true;
  3359. UINT rowCount, colCount;
  3360. GetRowsAndCols(type, rowCount, colCount);
  3361. if (!IsValidMatrixColOrRowSize(rowCount) || !IsValidMatrixColOrRowSize(colCount)) {
  3362. valid = false;
  3363. m_sema->Diag(argLoc, diag::err_hlsl_unsupportedmatrixsize) << type << rowCount << colCount;
  3364. }
  3365. if (!IsScalarType(GetMatrixOrVectorElementType(type))) {
  3366. valid = false;
  3367. m_sema->Diag(argLoc, diag::err_hlsl_unsupportedvectortype) << type << GetMatrixOrVectorElementType(type);
  3368. }
  3369. return valid;
  3370. }
  3371. else if (qt->isStructureType()) {
  3372. const RecordType* recordType = qt->getAsStructureType();
  3373. objectKind = ClassifyRecordType(recordType);
  3374. switch (objectKind)
  3375. {
  3376. case AR_TOBJ_OBJECT:
  3377. m_sema->Diag(argLoc, diag::err_hlsl_objectintemplateargument) << type;
  3378. return false;
  3379. case AR_TOBJ_COMPOUND:
  3380. {
  3381. const RecordDecl* recordDecl = recordType->getDecl();
  3382. RecordDecl::field_iterator begin = recordDecl->field_begin();
  3383. RecordDecl::field_iterator end = recordDecl->field_end();
  3384. bool result = true;
  3385. while (begin != end) {
  3386. const FieldDecl* fieldDecl = *begin;
  3387. if (!IsValidTemplateArgumentType(argLoc, fieldDecl->getType(), false)) {
  3388. m_sema->Diag(argLoc, diag::note_field_type_usage)
  3389. << fieldDecl->getType() << fieldDecl->getIdentifier() << type;
  3390. result = false;
  3391. }
  3392. begin++;
  3393. }
  3394. return result;
  3395. }
  3396. default:
  3397. m_sema->Diag(argLoc, diag::err_hlsl_typeintemplateargument) << type;
  3398. return false;
  3399. }
  3400. }
  3401. else if(IsScalarType(qt)) {
  3402. return true;
  3403. }
  3404. else {
  3405. m_sema->Diag(argLoc, diag::err_hlsl_typeintemplateargument) << type;
  3406. return false;
  3407. }
  3408. }
  3409. }
  3410. /// <summary>Checks whether the source type can be converted to the target type.</summary>
  3411. bool CanConvert(SourceLocation loc, Expr* sourceExpr, QualType target, bool explicitConversion,
  3412. _Out_opt_ TYPE_CONVERSION_REMARKS* remarks,
  3413. _Inout_opt_ StandardConversionSequence* sequence);
  3414. /// <summary>Produces an expression that turns the given expression into the specified numeric type.</summary>
  3415. Expr* CastExprToTypeNumeric(Expr* expr, QualType targetType);
  3416. void CollectInfo(QualType type, _Out_ ArTypeInfo* pTypeInfo);
  3417. void GetConversionForm(
  3418. QualType type,
  3419. bool explicitConversion,
  3420. ArTypeInfo* pTypeInfo);
  3421. bool ValidateCast(SourceLocation Loc, _In_ Expr* source, QualType target, bool explicitConversion,
  3422. bool suppressWarnings, bool suppressErrors,
  3423. _Inout_opt_ StandardConversionSequence* sequence);
  3424. bool ValidatePrimitiveTypeForOperand(SourceLocation loc, QualType type, ArTypeObjectKind kind);
  3425. bool ValidateTypeRequirements(
  3426. SourceLocation loc,
  3427. ArBasicKind elementKind,
  3428. ArTypeObjectKind objectKind,
  3429. bool requiresIntegrals,
  3430. bool requiresNumerics);
  3431. /// <summary>Validates and adjusts operands for the specified binary operator.</summary>
  3432. /// <param name="OpLoc">Source location for operator.</param>
  3433. /// <param name="Opc">Kind of binary operator.</param>
  3434. /// <param name="LHS">Left-hand-side expression, possibly updated by this function.</param>
  3435. /// <param name="RHS">Right-hand-side expression, possibly updated by this function.</param>
  3436. /// <param name="ResultTy">Result type for operator expression.</param>
  3437. /// <param name="CompLHSTy">Type of LHS after promotions for computation.</param>
  3438. /// <param name="CompResultTy">Type of computation result.</param>
  3439. void CheckBinOpForHLSL(
  3440. SourceLocation OpLoc,
  3441. BinaryOperatorKind Opc,
  3442. ExprResult& LHS,
  3443. ExprResult& RHS,
  3444. QualType& ResultTy,
  3445. QualType& CompLHSTy,
  3446. QualType& CompResultTy);
  3447. /// <summary>Validates and adjusts operands for the specified unary operator.</summary>
  3448. /// <param name="OpLoc">Source location for operator.</param>
  3449. /// <param name="Opc">Kind of operator.</param>
  3450. /// <param name="InputExpr">Input expression to the operator.</param>
  3451. /// <param name="VK">Value kind for resulting expression.</param>
  3452. /// <param name="OK">Object kind for resulting expression.</param>
  3453. /// <returns>The result type for the expression.</returns>
  3454. QualType CheckUnaryOpForHLSL(
  3455. SourceLocation OpLoc,
  3456. UnaryOperatorKind Opc,
  3457. ExprResult& InputExpr,
  3458. ExprValueKind& VK,
  3459. ExprObjectKind& OK);
  3460. /// <summary>Checks vector conditional operator (Cond ? LHS : RHS).</summary>
  3461. /// <param name="Cond">Vector condition expression.</param>
  3462. /// <param name="LHS">Left hand side.</param>
  3463. /// <param name="RHS">Right hand side.</param>
  3464. /// <param name="QuestionLoc">Location of question mark in operator.</param>
  3465. /// <returns>Result type of vector conditional expression.</returns>
  3466. clang::QualType CheckVectorConditional(
  3467. _In_ ExprResult &Cond,
  3468. _In_ ExprResult &LHS,
  3469. _In_ ExprResult &RHS,
  3470. _In_ SourceLocation QuestionLoc);
  3471. clang::QualType ApplyTypeSpecSignToParsedType(
  3472. _In_ clang::QualType &type,
  3473. _In_ TypeSpecifierSign TSS,
  3474. _In_ SourceLocation Loc
  3475. );
  3476. bool CheckRangedTemplateArgument(SourceLocation diagLoc, llvm::APSInt& sintValue)
  3477. {
  3478. if (!sintValue.isStrictlyPositive() || sintValue.getLimitedValue() > 4)
  3479. {
  3480. m_sema->Diag(diagLoc, diag::err_hlsl_invalid_range_1_4);
  3481. return true;
  3482. }
  3483. return false;
  3484. }
  3485. /// <summary>Performs HLSL-specific processing of template declarations.</summary>
  3486. bool
  3487. CheckTemplateArgumentListForHLSL(_In_ TemplateDecl *Template,
  3488. SourceLocation /* TemplateLoc */,
  3489. TemplateArgumentListInfo &TemplateArgList) {
  3490. DXASSERT_NOMSG(Template != nullptr);
  3491. // Determine which object type the template refers to.
  3492. StringRef templateName = Template->getName();
  3493. // NOTE: this 'escape valve' allows unit tests to perform type checks.
  3494. if (templateName.equals(StringRef("is_same"))) {
  3495. return false;
  3496. }
  3497. bool isMatrix = Template->getCanonicalDecl() ==
  3498. m_matrixTemplateDecl->getCanonicalDecl();
  3499. bool isVector = Template->getCanonicalDecl() ==
  3500. m_vectorTemplateDecl->getCanonicalDecl();
  3501. bool requireScalar = isMatrix || isVector;
  3502. // Check constraints on the type. Right now we only check that template
  3503. // types are primitive types.
  3504. for (unsigned int i = 0; i < TemplateArgList.size(); i++) {
  3505. const TemplateArgumentLoc &argLoc = TemplateArgList[i];
  3506. SourceLocation argSrcLoc = argLoc.getLocation();
  3507. const TemplateArgument &arg = argLoc.getArgument();
  3508. if (arg.getKind() == TemplateArgument::ArgKind::Type) {
  3509. QualType argType = arg.getAsType();
  3510. if (!IsValidTemplateArgumentType(argSrcLoc, argType, requireScalar)) {
  3511. // NOTE: IsValidTemplateArgumentType emits its own diagnostics
  3512. return true;
  3513. }
  3514. }
  3515. else if (arg.getKind() == TemplateArgument::ArgKind::Expression) {
  3516. if (isMatrix || isVector) {
  3517. Expr *expr = arg.getAsExpr();
  3518. llvm::APSInt constantResult;
  3519. if (expr != nullptr &&
  3520. expr->isIntegerConstantExpr(constantResult, *m_context)) {
  3521. if (CheckRangedTemplateArgument(argSrcLoc, constantResult)) {
  3522. return true;
  3523. }
  3524. }
  3525. }
  3526. }
  3527. else if (arg.getKind() == TemplateArgument::ArgKind::Integral) {
  3528. if (isMatrix || isVector) {
  3529. llvm::APSInt Val = arg.getAsIntegral();
  3530. if (CheckRangedTemplateArgument(argSrcLoc, Val)) {
  3531. return true;
  3532. }
  3533. }
  3534. }
  3535. }
  3536. return false;
  3537. }
  3538. /// <summary>Diagnoses an assignment operation.</summary>
  3539. /// <param name="ConvTy">Type of conversion assignment.</param>
  3540. /// <param name="Loc">Location for operation.</param>
  3541. /// <param name="DstType">Destination type.</param>
  3542. /// <param name="SrcType">Source type.</param>
  3543. /// <param name="SrcExpr">Source expression.</param>
  3544. /// <param name="Action">Action that triggers the assignment (assignment, passing, return, etc).</param>
  3545. /// <param name="Complained">Whether a diagnostic was emitted.</param>
  3546. void DiagnoseAssignmentResultForHLSL(
  3547. Sema::AssignConvertType ConvTy,
  3548. SourceLocation Loc,
  3549. QualType DstType, QualType SrcType,
  3550. _In_ Expr *SrcExpr, Sema::AssignmentAction Action,
  3551. _Out_opt_ bool *Complained);
  3552. FindStructBasicTypeResult FindStructBasicType(_In_ DeclContext* functionDeclContext);
  3553. /// <summary>Finds the table of intrinsics for the declaration context of a member function.</summary>
  3554. /// <param name="functionDeclContext">Declaration context of function.</param>
  3555. /// <param name="name">After execution, the name of the object to which the table applies.</param>
  3556. /// <param name="intrinsics">After execution, the intrinsic table.</param>
  3557. /// <param name="intrinsicCount">After execution, the count of elements in the intrinsic table.</param>
  3558. void FindIntrinsicTable(
  3559. _In_ DeclContext* functionDeclContext,
  3560. _Outptr_result_z_ const char** name,
  3561. _Outptr_result_buffer_(*intrinsicCount) const HLSL_INTRINSIC** intrinsics,
  3562. _Out_ size_t* intrinsicCount);
  3563. /// <summary>Deduces the template arguments by comparing the argument types and the HLSL intrinsic tables.</summary>
  3564. /// <param name="FunctionTemplate">The declaration for the function template being deduced.</param>
  3565. /// <param name="ExplicitTemplateArgs">Explicitly-provided template arguments. Should be empty for an HLSL program.</param>
  3566. /// <param name="Args">Array of expressions being used as arguments.</param>
  3567. /// <param name="Specialization">The declaration for the resolved specialization.</param>
  3568. /// <param name="Info">Provides information about an attempted template argument deduction.</param>
  3569. /// <returns>The result of the template deduction, TDK_Invalid if no HLSL-specific processing done.</returns>
  3570. Sema::TemplateDeductionResult DeduceTemplateArgumentsForHLSL(
  3571. FunctionTemplateDecl *FunctionTemplate,
  3572. TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> Args,
  3573. FunctionDecl *&Specialization, TemplateDeductionInfo &Info);
  3574. clang::OverloadingResult GetBestViableFunction(
  3575. clang::SourceLocation Loc,
  3576. clang::OverloadCandidateSet& set,
  3577. clang::OverloadCandidateSet::iterator& Best);
  3578. /// <summary>
  3579. /// Initializes the specified <paramref name="initSequence" /> describing how
  3580. /// <paramref name="Entity" /> is initialized with <paramref name="Args" />.
  3581. /// </summary>
  3582. /// <param name="Entity">Entity being initialized; a variable, return result, etc.</param>
  3583. /// <param name="Kind">Kind of initialization: copying, list-initializing, constructing, etc.</param>
  3584. /// <param name="Args">Arguments to the initialization.</param>
  3585. /// <param name="TopLevelOfInitList">Whether this is the top-level of an initialization list.</param>
  3586. /// <param name="initSequence">Initialization sequence description to initialize.</param>
  3587. void InitializeInitSequenceForHLSL(
  3588. const InitializedEntity& Entity,
  3589. const InitializationKind& Kind,
  3590. MultiExprArg Args,
  3591. bool TopLevelOfInitList,
  3592. _Inout_ InitializationSequence* initSequence);
  3593. /// <summary>
  3594. /// Checks whether the specified conversion occurs to a type of idential element type but less elements.
  3595. /// </summary>
  3596. /// <remarks>This is an important case because a cast of this type does not turn an lvalue into an rvalue.</remarks>
  3597. bool IsConversionToLessOrEqualElements(
  3598. const ExprResult& sourceExpr,
  3599. const QualType& targetType,
  3600. bool explicitConversion);
  3601. /// <summary>
  3602. /// Checks whether the specified conversion occurs to a type of idential element type but less elements.
  3603. /// </summary>
  3604. /// <remarks>This is an important case because a cast of this type does not turn an lvalue into an rvalue.</remarks>
  3605. bool IsConversionToLessOrEqualElements(
  3606. const QualType& sourceType,
  3607. const QualType& targetType,
  3608. bool explicitConversion);
  3609. /// <summary>Performs a member lookup on the specified BaseExpr if it's a matrix.</summary>
  3610. /// <param name="BaseExpr">Base expression for member access.</param>
  3611. /// <param name="MemberName">Name of member to look up.</param>
  3612. /// <param name="IsArrow">Whether access is through arrow (a->b) rather than period (a.b).</param>
  3613. /// <param name="OpLoc">Location of access operand.</param>
  3614. /// <param name="MemberLoc">Location of member.</param>
  3615. /// <param name="result">Result of lookup operation.</param>
  3616. /// <returns>true if the base type is a matrix and the lookup has been handled.</returns>
  3617. bool LookupMatrixMemberExprForHLSL(
  3618. Expr& BaseExpr,
  3619. DeclarationName MemberName,
  3620. bool IsArrow,
  3621. SourceLocation OpLoc,
  3622. SourceLocation MemberLoc,
  3623. ExprResult* result);
  3624. /// <summary>Performs a member lookup on the specified BaseExpr if it's a vector.</summary>
  3625. /// <param name="BaseExpr">Base expression for member access.</param>
  3626. /// <param name="MemberName">Name of member to look up.</param>
  3627. /// <param name="IsArrow">Whether access is through arrow (a->b) rather than period (a.b).</param>
  3628. /// <param name="OpLoc">Location of access operand.</param>
  3629. /// <param name="MemberLoc">Location of member.</param>
  3630. /// <param name="result">Result of lookup operation.</param>
  3631. /// <returns>true if the base type is a vector and the lookup has been handled.</returns>
  3632. bool LookupVectorMemberExprForHLSL(
  3633. Expr& BaseExpr,
  3634. DeclarationName MemberName,
  3635. bool IsArrow,
  3636. SourceLocation OpLoc,
  3637. SourceLocation MemberLoc,
  3638. ExprResult* result);
  3639. /// <summary>If E is a scalar, converts it to a 1-element vector.</summary>
  3640. /// <param name="E">Expression to convert.</param>
  3641. /// <returns>The result of the conversion; or E if the type is not a scalar.</returns>
  3642. ExprResult MaybeConvertScalarToVector(_In_ clang::Expr* E);
  3643. clang::Expr *HLSLImpCastToScalar(
  3644. _In_ clang::Sema* self,
  3645. _In_ clang::Expr* From,
  3646. ArTypeObjectKind FromShape,
  3647. ArBasicKind EltKind);
  3648. clang::ExprResult PerformHLSLConversion(
  3649. _In_ clang::Expr* From,
  3650. _In_ clang::QualType targetType,
  3651. _In_ const clang::StandardConversionSequence &SCS,
  3652. _In_ clang::Sema::CheckedConversionKind CCK);
  3653. /// <summary>Diagnoses an error when precessing the specified type if nesting is too deep.</summary>
  3654. void ReportUnsupportedTypeNesting(SourceLocation loc, QualType type);
  3655. /// <summary>
  3656. /// Checks if a static cast can be performed, and performs it if possible.
  3657. /// </summary>
  3658. /// <param name="SrcExpr">Expression to cast.</param>
  3659. /// <param name="DestType">Type to cast SrcExpr to.</param>
  3660. /// <param name="CCK">Kind of conversion: implicit, C-style, functional, other.</param>
  3661. /// <param name="OpRange">Source range for the cast operation.</param>
  3662. /// <param name="msg">Error message from the diag::* enumeration to fail with; zero to suppress messages.</param>
  3663. /// <param name="Kind">The kind of operation required for a conversion.</param>
  3664. /// <param name="BasePath">A simple array of base specifiers.</param>
  3665. /// <param name="ListInitialization">Whether the cast is in the context of a list initialization.</param>
  3666. /// <param name="SuppressWarnings">Whether warnings should be omitted.</param>
  3667. /// <param name="SuppressErrors">Whether errors should be omitted.</param>
  3668. bool TryStaticCastForHLSL(ExprResult &SrcExpr,
  3669. QualType DestType,
  3670. Sema::CheckedConversionKind CCK,
  3671. const SourceRange &OpRange, unsigned &msg,
  3672. CastKind &Kind, CXXCastPath &BasePath,
  3673. bool ListInitialization, bool SuppressWarnings, bool SuppressErrors,
  3674. _Inout_opt_ StandardConversionSequence* standard);
  3675. /// <summary>
  3676. /// Checks if a subscript index argument can be initialized from the given expression.
  3677. /// </summary>
  3678. /// <param name="SrcExpr">Source expression used as argument.</param>
  3679. /// <param name="DestType">Parameter type to initialize.</param>
  3680. /// <remarks>
  3681. /// Rules for subscript index initialization follow regular implicit casting rules, with the exception that
  3682. /// no changes in arity are allowed (i.e., int2 can become uint2, but uint or uint3 cannot).
  3683. /// </remarks>
  3684. ImplicitConversionSequence TrySubscriptIndexInitialization(_In_ clang::Expr* SrcExpr, clang::QualType DestType);
  3685. void AddHLSLObjectMethodsIfNotReady(QualType qt) {
  3686. static_assert((sizeof(uint64_t)*8) >= _countof(g_ArBasicKindsAsTypes), "Bitmask size is too small");
  3687. // Everything is ready.
  3688. if (m_objectTypeLazyInitMask == 0)
  3689. return;
  3690. CXXRecordDecl *recordDecl = const_cast<CXXRecordDecl *>(GetRecordDeclForBuiltInOrStruct(qt->getAsCXXRecordDecl()));
  3691. int idx = FindObjectBasicKindIndex(recordDecl);
  3692. // Not object type.
  3693. if (idx == -1)
  3694. return;
  3695. uint64_t bit = ((uint64_t)1)<<idx;
  3696. // Already created.
  3697. if ((m_objectTypeLazyInitMask & bit) == 0)
  3698. return;
  3699. ArBasicKind kind = g_ArBasicKindsAsTypes[idx];
  3700. uint8_t templateArgCount = g_ArBasicKindsTemplateCount[idx];
  3701. int startDepth = 0;
  3702. if (templateArgCount > 0) {
  3703. DXASSERT(templateArgCount == 1 || templateArgCount == 2,
  3704. "otherwise a new case has been added");
  3705. ClassTemplateDecl *typeDecl = recordDecl->getDescribedClassTemplate();
  3706. AddObjectSubscripts(kind, typeDecl, recordDecl,
  3707. g_ArBasicKindsSubscripts[idx]);
  3708. startDepth = 1;
  3709. }
  3710. AddObjectMethods(kind, recordDecl, startDepth);
  3711. // Clear the object.
  3712. m_objectTypeLazyInitMask &= ~bit;
  3713. }
  3714. FunctionDecl* AddHLSLIntrinsicMethod(
  3715. LPCSTR tableName,
  3716. LPCSTR lowering,
  3717. _In_ const HLSL_INTRINSIC* intrinsic,
  3718. _In_ FunctionTemplateDecl *FunctionTemplate,
  3719. ArrayRef<Expr *> Args,
  3720. _In_count_(parameterTypeCount) QualType* parameterTypes,
  3721. size_t parameterTypeCount)
  3722. {
  3723. DXASSERT_NOMSG(intrinsic != nullptr);
  3724. DXASSERT_NOMSG(FunctionTemplate != nullptr);
  3725. DXASSERT_NOMSG(parameterTypes != nullptr);
  3726. DXASSERT(parameterTypeCount >= 1, "otherwise caller didn't initialize - there should be at least a void return type");
  3727. // Create the template arguments.
  3728. SmallVector<TemplateArgument, g_MaxIntrinsicParamCount + 1> templateArgs;
  3729. for (size_t i = 0; i < parameterTypeCount; i++) {
  3730. templateArgs.push_back(TemplateArgument(parameterTypes[i]));
  3731. }
  3732. // Look for an existing specialization.
  3733. void *InsertPos = nullptr;
  3734. FunctionDecl *SpecFunc =
  3735. FunctionTemplate->findSpecialization(templateArgs, InsertPos);
  3736. if (SpecFunc != nullptr) {
  3737. return SpecFunc;
  3738. }
  3739. // Change return type to rvalue reference type for aggregate types
  3740. QualType retTy = parameterTypes[0];
  3741. if (retTy->isAggregateType() && !IsHLSLVecMatType(retTy))
  3742. parameterTypes[0] = m_context->getRValueReferenceType(retTy);
  3743. // Create a new specialization.
  3744. SmallVector<ParameterModifier, g_MaxIntrinsicParamCount> paramMods;
  3745. InitParamMods(intrinsic, paramMods);
  3746. for (unsigned int i = 1; i < parameterTypeCount; i++) {
  3747. // Change out/inout parameter type to rvalue reference type.
  3748. if (paramMods[i - 1].isAnyOut()) {
  3749. parameterTypes[i] = m_context->getLValueReferenceType(parameterTypes[i]);
  3750. }
  3751. }
  3752. IntrinsicOp intrinOp = static_cast<IntrinsicOp>(intrinsic->Op);
  3753. if (intrinOp == IntrinsicOp::MOP_SampleBias) {
  3754. // Remove this when update intrinsic table not affect other things.
  3755. // Change vector<float,1> into float for bias.
  3756. const unsigned biasOperandID = 3; // return type, sampler, coord, bias.
  3757. DXASSERT(parameterTypeCount > biasOperandID,
  3758. "else operation was misrecognized");
  3759. if (const ExtVectorType *VecTy =
  3760. hlsl::ConvertHLSLVecMatTypeToExtVectorType(
  3761. *m_context, parameterTypes[biasOperandID])) {
  3762. if (VecTy->getNumElements() == 1)
  3763. parameterTypes[biasOperandID] = VecTy->getElementType();
  3764. }
  3765. }
  3766. DeclContext *owner = FunctionTemplate->getDeclContext();
  3767. TemplateArgumentList templateArgumentList(
  3768. TemplateArgumentList::OnStackType::OnStack, templateArgs.data(),
  3769. templateArgs.size());
  3770. MultiLevelTemplateArgumentList mlTemplateArgumentList(templateArgumentList);
  3771. TemplateDeclInstantiator declInstantiator(*this->m_sema, owner,
  3772. mlTemplateArgumentList);
  3773. FunctionProtoType::ExtProtoInfo EmptyEPI;
  3774. QualType functionType = m_context->getFunctionType(
  3775. parameterTypes[0],
  3776. ArrayRef<QualType>(parameterTypes + 1, parameterTypeCount - 1),
  3777. EmptyEPI, paramMods);
  3778. TypeSourceInfo *TInfo = m_context->CreateTypeSourceInfo(functionType, 0);
  3779. FunctionProtoTypeLoc Proto =
  3780. TInfo->getTypeLoc().getAs<FunctionProtoTypeLoc>();
  3781. SmallVector<ParmVarDecl*, g_MaxIntrinsicParamCount> Params;
  3782. for (unsigned int i = 1; i < parameterTypeCount; i++) {
  3783. IdentifierInfo* id = &m_context->Idents.get(StringRef(intrinsic->pArgs[i - 1].pName));
  3784. ParmVarDecl *paramDecl = ParmVarDecl::Create(
  3785. *m_context, nullptr, NoLoc, NoLoc, id, parameterTypes[i], nullptr,
  3786. StorageClass::SC_None, nullptr, paramMods[i - 1]);
  3787. Params.push_back(paramDecl);
  3788. }
  3789. QualType T = TInfo->getType();
  3790. DeclarationNameInfo NameInfo(FunctionTemplate->getDeclName(), NoLoc);
  3791. CXXMethodDecl* method = CXXMethodDecl::Create(
  3792. *m_context, dyn_cast<CXXRecordDecl>(owner), NoLoc, NameInfo, T, TInfo,
  3793. SC_Extern, InlineSpecifiedFalse, IsConstexprFalse, NoLoc);
  3794. // Add intrinsic attr
  3795. AddHLSLIntrinsicAttr(method, *m_context, tableName, lowering, intrinsic);
  3796. // Record this function template specialization.
  3797. TemplateArgumentList *argListCopy = TemplateArgumentList::CreateCopy(
  3798. *m_context, templateArgs.data(), templateArgs.size());
  3799. method->setFunctionTemplateSpecialization(FunctionTemplate, argListCopy, 0);
  3800. // Attach the parameters
  3801. for (unsigned P = 0; P < Params.size(); ++P) {
  3802. Params[P]->setOwningFunction(method);
  3803. Proto.setParam(P, Params[P]);
  3804. }
  3805. method->setParams(Params);
  3806. // Adjust access.
  3807. method->setAccess(AccessSpecifier::AS_public);
  3808. FunctionTemplate->setAccess(method->getAccess());
  3809. return method;
  3810. }
  3811. // Overload support.
  3812. UINT64 ScoreCast(QualType leftType, QualType rightType);
  3813. UINT64 ScoreFunction(OverloadCandidateSet::iterator &Cand);
  3814. UINT64 ScoreImplicitConversionSequence(const ImplicitConversionSequence *s);
  3815. unsigned GetNumElements(QualType anyType);
  3816. unsigned GetNumBasicElements(QualType anyType);
  3817. unsigned GetNumConvertCheckElts(QualType leftType, unsigned leftSize, QualType rightType, unsigned rightSize);
  3818. QualType GetNthElementType(QualType type, unsigned index);
  3819. bool IsPromotion(ArBasicKind leftKind, ArBasicKind rightKind);
  3820. bool IsCast(ArBasicKind leftKind, ArBasicKind rightKind);
  3821. bool IsIntCast(ArBasicKind leftKind, ArBasicKind rightKind);
  3822. };
  3823. // Use this class to flatten a type into HLSL primitives and iterate through them.
  3824. class FlattenedTypeIterator
  3825. {
  3826. private:
  3827. enum FlattenedIterKind {
  3828. FK_Simple,
  3829. FK_Fields,
  3830. FK_Expressions,
  3831. FK_IncompleteArray,
  3832. FK_Bases,
  3833. };
  3834. // Use this struct to represent a specific point in the tracked tree.
  3835. struct FlattenedTypeTracker {
  3836. QualType Type; // Type at this position in the tree.
  3837. unsigned int Count; // Count of consecutive types
  3838. CXXRecordDecl::base_class_iterator CurrentBase; // Current base for a structure type.
  3839. CXXRecordDecl::base_class_iterator EndBase; // STL-style end of bases.
  3840. RecordDecl::field_iterator CurrentField; // Current field in for a structure type.
  3841. RecordDecl::field_iterator EndField; // STL-style end of fields.
  3842. MultiExprArg::iterator CurrentExpr; // Current expression (advanceable for a list of expressions).
  3843. MultiExprArg::iterator EndExpr; // STL-style end of expressions.
  3844. FlattenedIterKind IterKind; // Kind of tracker.
  3845. bool IsConsidered; // If a FlattenedTypeTracker already been considered.
  3846. FlattenedTypeTracker(QualType type)
  3847. : Type(type), Count(0), CurrentExpr(nullptr),
  3848. IterKind(FK_IncompleteArray), IsConsidered(false) {}
  3849. FlattenedTypeTracker(QualType type, unsigned int count,
  3850. MultiExprArg::iterator expression)
  3851. : Type(type), Count(count), CurrentExpr(expression),
  3852. IterKind(FK_Simple), IsConsidered(false) {}
  3853. FlattenedTypeTracker(QualType type, RecordDecl::field_iterator current,
  3854. RecordDecl::field_iterator end)
  3855. : Type(type), Count(0), CurrentField(current), EndField(end),
  3856. CurrentExpr(nullptr), IterKind(FK_Fields), IsConsidered(false) {}
  3857. FlattenedTypeTracker(MultiExprArg::iterator current,
  3858. MultiExprArg::iterator end)
  3859. : Count(0), CurrentExpr(current), EndExpr(end),
  3860. IterKind(FK_Expressions), IsConsidered(false) {}
  3861. FlattenedTypeTracker(QualType type,
  3862. CXXRecordDecl::base_class_iterator current,
  3863. CXXRecordDecl::base_class_iterator end)
  3864. : Count(0), CurrentBase(current), EndBase(end), CurrentExpr(nullptr),
  3865. IterKind(FK_Bases), IsConsidered(false) {}
  3866. /// <summary>Gets the current expression if one is available.</summary>
  3867. Expr* getExprOrNull() const { return CurrentExpr ? *CurrentExpr : nullptr; }
  3868. /// <summary>Replaces the current expression.</summary>
  3869. void replaceExpr(Expr* e) { *CurrentExpr = e; }
  3870. };
  3871. HLSLExternalSource& m_source; // Source driving the iteration.
  3872. SmallVector<FlattenedTypeTracker, 4> m_typeTrackers; // Active stack of trackers.
  3873. bool m_draining; // Whether the iterator is meant to drain (will not generate new elements in incomplete arrays).
  3874. bool m_springLoaded; // Whether the current element has been set up by an incomplete array but hasn't been used yet.
  3875. unsigned int m_incompleteCount; // The number of elements in an incomplete array.
  3876. size_t m_typeDepth; // Depth of type analysis, to avoid stack overflows.
  3877. QualType m_firstType; // Name of first type found, used for diagnostics.
  3878. SourceLocation m_loc; // Location used for diagnostics.
  3879. static const size_t MaxTypeDepth = 100;
  3880. void advanceLeafTracker();
  3881. /// <summary>Consumes leaves.</summary>
  3882. void consumeLeaf();
  3883. /// <summary>Considers whether the leaf has a usable expression without consuming anything.</summary>
  3884. bool considerLeaf();
  3885. /// <summary>Pushes a tracker for the specified expression; returns true if there is something to evaluate.</summary>
  3886. bool pushTrackerForExpression(MultiExprArg::iterator expression);
  3887. /// <summary>Pushes a tracker for the specified type; returns true if there is something to evaluate.</summary>
  3888. bool pushTrackerForType(QualType type, _In_opt_ MultiExprArg::iterator expression);
  3889. public:
  3890. /// <summary>Constructs a FlattenedTypeIterator for the specified type.</summary>
  3891. FlattenedTypeIterator(SourceLocation loc, QualType type, HLSLExternalSource& source);
  3892. /// <summary>Constructs a FlattenedTypeIterator for the specified arguments.</summary>
  3893. FlattenedTypeIterator(SourceLocation loc, MultiExprArg args, HLSLExternalSource& source);
  3894. /// <summary>Gets the current element in the flattened type hierarchy.</summary>
  3895. QualType getCurrentElement() const;
  3896. /// <summary>Get the number of repeated current elements.</summary>
  3897. unsigned int getCurrentElementSize() const;
  3898. /// <summary>Checks whether the iterator has a current element type to report.</summary>
  3899. bool hasCurrentElement() const;
  3900. /// <summary>Consumes count elements on this iterator.</summary>
  3901. void advanceCurrentElement(unsigned int count);
  3902. /// <summary>Counts the remaining elements in this iterator (consuming all elements).</summary>
  3903. unsigned int countRemaining();
  3904. /// <summary>Gets the current expression if one is available.</summary>
  3905. Expr* getExprOrNull() const { return m_typeTrackers.back().getExprOrNull(); }
  3906. /// <summary>Replaces the current expression.</summary>
  3907. void replaceExpr(Expr* e) { m_typeTrackers.back().replaceExpr(e); }
  3908. struct ComparisonResult
  3909. {
  3910. unsigned int LeftCount;
  3911. unsigned int RightCount;
  3912. /// <summary>Whether elements from right sequence are identical into left sequence elements.</summary>
  3913. bool AreElementsEqual;
  3914. /// <summary>Whether elements from right sequence can be converted into left sequence elements.</summary>
  3915. bool CanConvertElements;
  3916. /// <summary>Whether the elements can be converted and the sequences have the same length.</summary>
  3917. bool IsConvertibleAndEqualLength() const {
  3918. return LeftCount == RightCount;
  3919. }
  3920. /// <summary>Whether the elements can be converted but the left-hand sequence is longer.</summary>
  3921. bool IsConvertibleAndLeftLonger() const {
  3922. return CanConvertElements && LeftCount > RightCount;
  3923. }
  3924. bool IsRightLonger() const {
  3925. return RightCount > LeftCount;
  3926. }
  3927. };
  3928. static ComparisonResult CompareIterators(
  3929. HLSLExternalSource& source, SourceLocation loc,
  3930. FlattenedTypeIterator& leftIter, FlattenedTypeIterator& rightIter);
  3931. static ComparisonResult CompareTypes(
  3932. HLSLExternalSource& source,
  3933. SourceLocation leftLoc, SourceLocation rightLoc,
  3934. QualType left, QualType right);
  3935. // Compares the arguments to initialize the left type, modifying them if necessary.
  3936. static ComparisonResult CompareTypesForInit(
  3937. HLSLExternalSource& source, QualType left, MultiExprArg args,
  3938. SourceLocation leftLoc, SourceLocation rightLoc);
  3939. };
  3940. static
  3941. QualType GetFirstElementTypeFromDecl(const Decl* decl)
  3942. {
  3943. const ClassTemplateSpecializationDecl* specialization = dyn_cast<ClassTemplateSpecializationDecl>(decl);
  3944. if (specialization) {
  3945. const TemplateArgumentList& list = specialization->getTemplateArgs();
  3946. if (list.size()) {
  3947. return list[0].getAsType();
  3948. }
  3949. }
  3950. return QualType();
  3951. }
  3952. void HLSLExternalSource::AddBaseTypes()
  3953. {
  3954. DXASSERT(m_baseTypes[HLSLScalarType_unknown].isNull(), "otherwise unknown was initialized to an actual type");
  3955. m_baseTypes[HLSLScalarType_bool] = m_context->BoolTy;
  3956. m_baseTypes[HLSLScalarType_int] = m_context->IntTy;
  3957. m_baseTypes[HLSLScalarType_uint] = m_context->UnsignedIntTy;
  3958. m_baseTypes[HLSLScalarType_dword] = m_context->UnsignedIntTy;
  3959. m_baseTypes[HLSLScalarType_half] = m_context->getLangOpts().UseMinPrecision ? m_context->FloatTy : m_context->HalfTy;
  3960. m_baseTypes[HLSLScalarType_float] = m_context->FloatTy;
  3961. m_baseTypes[HLSLScalarType_double] = m_context->DoubleTy;
  3962. m_baseTypes[HLSLScalarType_float_min10] = m_context->HalfTy;
  3963. m_baseTypes[HLSLScalarType_float_min16] = m_context->HalfTy;
  3964. m_baseTypes[HLSLScalarType_int_min12] = m_context->ShortTy;
  3965. m_baseTypes[HLSLScalarType_int_min16] = m_context->ShortTy;
  3966. m_baseTypes[HLSLScalarType_uint_min16] = m_context->UnsignedShortTy;
  3967. m_baseTypes[HLSLScalarType_float_lit] = m_context->LitFloatTy;
  3968. m_baseTypes[HLSLScalarType_int_lit] = m_context->LitIntTy;
  3969. m_baseTypes[HLSLScalarType_int16] = m_context->ShortTy;
  3970. m_baseTypes[HLSLScalarType_int32] = m_context->IntTy;
  3971. m_baseTypes[HLSLScalarType_int64] = m_context->LongLongTy;
  3972. m_baseTypes[HLSLScalarType_uint16] = m_context->UnsignedShortTy;
  3973. m_baseTypes[HLSLScalarType_uint32] = m_context->UnsignedIntTy;
  3974. m_baseTypes[HLSLScalarType_uint64] = m_context->UnsignedLongLongTy;
  3975. m_baseTypes[HLSLScalarType_float16] = m_context->HalfTy;
  3976. m_baseTypes[HLSLScalarType_float32] = m_context->FloatTy;
  3977. m_baseTypes[HLSLScalarType_float64] = m_context->DoubleTy;
  3978. }
  3979. void HLSLExternalSource::AddHLSLScalarTypes()
  3980. {
  3981. DXASSERT(m_scalarTypes[HLSLScalarType_unknown].isNull(), "otherwise unknown was initialized to an actual type");
  3982. m_scalarTypes[HLSLScalarType_bool] = m_baseTypes[HLSLScalarType_bool];
  3983. m_scalarTypes[HLSLScalarType_int] = m_baseTypes[HLSLScalarType_int];
  3984. m_scalarTypes[HLSLScalarType_float] = m_baseTypes[HLSLScalarType_float];
  3985. m_scalarTypes[HLSLScalarType_double] = m_baseTypes[HLSLScalarType_double];
  3986. m_scalarTypes[HLSLScalarType_float_lit] = m_baseTypes[HLSLScalarType_float_lit];
  3987. m_scalarTypes[HLSLScalarType_int_lit] = m_baseTypes[HLSLScalarType_int_lit];
  3988. }
  3989. FunctionDecl* HLSLExternalSource::AddSubscriptSpecialization(
  3990. _In_ FunctionTemplateDecl* functionTemplate,
  3991. QualType objectElement,
  3992. const FindStructBasicTypeResult& findResult)
  3993. {
  3994. DXASSERT_NOMSG(functionTemplate != nullptr);
  3995. DXASSERT_NOMSG(!objectElement.isNull());
  3996. DXASSERT_NOMSG(findResult.Found());
  3997. DXASSERT(
  3998. g_ArBasicKindsSubscripts[findResult.BasicKindsAsTypeIndex].SubscriptCardinality > 0,
  3999. "otherwise the template shouldn't have an operator[] that the caller is trying to specialize");
  4000. // Subscript is templated only on its return type.
  4001. // Create the template argument.
  4002. bool isReadWrite = GetBasicKindProps(findResult.Kind) & BPROP_RWBUFFER;
  4003. QualType resultType = objectElement;
  4004. if (isReadWrite)
  4005. resultType = m_context->getLValueReferenceType(resultType, false);
  4006. else {
  4007. // Add const to avoid write.
  4008. resultType = m_context->getConstType(resultType);
  4009. resultType = m_context->getLValueReferenceType(resultType);
  4010. }
  4011. TemplateArgument templateArgument(resultType);
  4012. unsigned subscriptCardinality =
  4013. g_ArBasicKindsSubscripts[findResult.BasicKindsAsTypeIndex].SubscriptCardinality;
  4014. QualType subscriptIndexType =
  4015. subscriptCardinality == 1
  4016. ? m_context->UnsignedIntTy
  4017. : NewSimpleAggregateType(AR_TOBJ_VECTOR, AR_BASIC_UINT32, 0, 1,
  4018. subscriptCardinality);
  4019. // Look for an existing specialization.
  4020. void* InsertPos = nullptr;
  4021. FunctionDecl *SpecFunc = functionTemplate->findSpecialization(ArrayRef<TemplateArgument>(&templateArgument, 1), InsertPos);
  4022. if (SpecFunc != nullptr) {
  4023. return SpecFunc;
  4024. }
  4025. // Create a new specialization.
  4026. DeclContext* owner = functionTemplate->getDeclContext();
  4027. TemplateArgumentList templateArgumentList(
  4028. TemplateArgumentList::OnStackType::OnStack, &templateArgument, 1);
  4029. MultiLevelTemplateArgumentList mlTemplateArgumentList(templateArgumentList);
  4030. TemplateDeclInstantiator declInstantiator(*this->m_sema, owner, mlTemplateArgumentList);
  4031. const FunctionType *templateFnType = functionTemplate->getTemplatedDecl()->getType()->getAs<FunctionType>();
  4032. const FunctionProtoType *protoType = dyn_cast<FunctionProtoType>(templateFnType);
  4033. FunctionProtoType::ExtProtoInfo templateEPI = protoType->getExtProtoInfo();
  4034. QualType functionType = m_context->getFunctionType(
  4035. resultType, subscriptIndexType, templateEPI, None);
  4036. TypeSourceInfo *TInfo = m_context->CreateTypeSourceInfo(functionType, 0);
  4037. FunctionProtoTypeLoc Proto = TInfo->getTypeLoc().getAs<FunctionProtoTypeLoc>();
  4038. IdentifierInfo* id = &m_context->Idents.get(StringRef("index"));
  4039. ParmVarDecl* indexerParam = ParmVarDecl::Create(
  4040. *m_context, nullptr, NoLoc, NoLoc, id, subscriptIndexType, nullptr, StorageClass::SC_None, nullptr);
  4041. QualType T = TInfo->getType();
  4042. DeclarationNameInfo NameInfo(functionTemplate->getDeclName(), NoLoc);
  4043. CXXMethodDecl* method = CXXMethodDecl::Create(
  4044. *m_context, dyn_cast<CXXRecordDecl>(owner), NoLoc, NameInfo, T, TInfo,
  4045. SC_Extern, InlineSpecifiedFalse, IsConstexprFalse, NoLoc);
  4046. // Add subscript attribute
  4047. AddHLSLSubscriptAttr(method, *m_context, HLSubscriptOpcode::DefaultSubscript);
  4048. // Record this function template specialization.
  4049. method->setFunctionTemplateSpecialization(functionTemplate,
  4050. TemplateArgumentList::CreateCopy(*m_context, &templateArgument, 1), 0);
  4051. // Attach the parameters
  4052. indexerParam->setOwningFunction(method);
  4053. Proto.setParam(0, indexerParam);
  4054. method->setParams(ArrayRef<ParmVarDecl*>(indexerParam));
  4055. // Adjust access.
  4056. method->setAccess(AccessSpecifier::AS_public);
  4057. functionTemplate->setAccess(method->getAccess());
  4058. return method;
  4059. }
  4060. /// <summary>
  4061. /// This routine combines Source into Target. If you have a symmetric operation
  4062. /// and want to treat either side equally you should call it twice, swapping the
  4063. /// parameter order.
  4064. /// </summary>
  4065. static bool CombineObjectTypes(ArBasicKind Target, _In_ ArBasicKind Source,
  4066. _Out_opt_ ArBasicKind *pCombined) {
  4067. if (Target == Source) {
  4068. AssignOpt(Target, pCombined);
  4069. return true;
  4070. }
  4071. if (Source == AR_OBJECT_NULL) {
  4072. // NULL is valid for any object type.
  4073. AssignOpt(Target, pCombined);
  4074. return true;
  4075. }
  4076. switch (Target) {
  4077. AR_BASIC_ROBJECT_CASES:
  4078. if (Source == AR_OBJECT_STATEBLOCK) {
  4079. AssignOpt(Target, pCombined);
  4080. return true;
  4081. }
  4082. break;
  4083. AR_BASIC_TEXTURE_CASES:
  4084. AR_BASIC_NON_CMP_SAMPLER_CASES:
  4085. if (Source == AR_OBJECT_SAMPLER || Source == AR_OBJECT_STATEBLOCK) {
  4086. AssignOpt(Target, pCombined);
  4087. return true;
  4088. }
  4089. break;
  4090. case AR_OBJECT_SAMPLERCOMPARISON:
  4091. if (Source == AR_OBJECT_STATEBLOCK) {
  4092. AssignOpt(Target, pCombined);
  4093. return true;
  4094. }
  4095. break;
  4096. default:
  4097. // Not a combinable target.
  4098. break;
  4099. }
  4100. AssignOpt(AR_BASIC_UNKNOWN, pCombined);
  4101. return false;
  4102. }
  4103. static ArBasicKind LiteralToConcrete(Expr *litExpr,
  4104. HLSLExternalSource *pHLSLExternalSource) {
  4105. if (IntegerLiteral *intLit = dyn_cast<IntegerLiteral>(litExpr)) {
  4106. llvm::APInt val = intLit->getValue();
  4107. unsigned width = val.getActiveBits();
  4108. bool isNeg = val.isNegative();
  4109. if (isNeg) {
  4110. // Signed.
  4111. if (width <= 32)
  4112. return ArBasicKind::AR_BASIC_INT32;
  4113. else
  4114. return ArBasicKind::AR_BASIC_INT64;
  4115. } else {
  4116. // Unsigned.
  4117. if (width <= 32)
  4118. return ArBasicKind::AR_BASIC_UINT32;
  4119. else
  4120. return ArBasicKind::AR_BASIC_UINT64;
  4121. }
  4122. } else if (FloatingLiteral *floatLit = dyn_cast<FloatingLiteral>(litExpr)) {
  4123. llvm::APFloat val = floatLit->getValue();
  4124. unsigned width = val.getSizeInBits(val.getSemantics());
  4125. if (width <= 16)
  4126. return ArBasicKind::AR_BASIC_FLOAT16;
  4127. else if (width <= 32)
  4128. return ArBasicKind::AR_BASIC_FLOAT32;
  4129. else
  4130. return AR_BASIC_FLOAT64;
  4131. } else if (UnaryOperator *UO = dyn_cast<UnaryOperator>(litExpr)) {
  4132. ArBasicKind kind = LiteralToConcrete(UO->getSubExpr(), pHLSLExternalSource);
  4133. if (UO->getOpcode() == UnaryOperator::Opcode::UO_Minus) {
  4134. if (kind == ArBasicKind::AR_BASIC_UINT32)
  4135. kind = ArBasicKind::AR_BASIC_INT32;
  4136. else if (kind == ArBasicKind::AR_BASIC_UINT64)
  4137. kind = ArBasicKind::AR_BASIC_INT64;
  4138. }
  4139. return kind;
  4140. } else if (HLSLVectorElementExpr *VEE = dyn_cast<HLSLVectorElementExpr>(litExpr)) {
  4141. return pHLSLExternalSource->GetTypeElementKind(VEE->getType());
  4142. } else if (BinaryOperator *BO = dyn_cast<BinaryOperator>(litExpr)) {
  4143. ArBasicKind kind = LiteralToConcrete(BO->getLHS(), pHLSLExternalSource);
  4144. ArBasicKind kind1 = LiteralToConcrete(BO->getRHS(), pHLSLExternalSource);
  4145. CombineBasicTypes(kind, kind1, &kind);
  4146. return kind;
  4147. } else if (ParenExpr *PE = dyn_cast<ParenExpr>(litExpr)) {
  4148. ArBasicKind kind = LiteralToConcrete(PE->getSubExpr(), pHLSLExternalSource);
  4149. return kind;
  4150. } else if (ConditionalOperator *CO = dyn_cast<ConditionalOperator>(litExpr)) {
  4151. ArBasicKind kind = LiteralToConcrete(CO->getLHS(), pHLSLExternalSource);
  4152. ArBasicKind kind1 = LiteralToConcrete(CO->getRHS(), pHLSLExternalSource);
  4153. CombineBasicTypes(kind, kind1, &kind);
  4154. return kind;
  4155. } else if (ImplicitCastExpr *IC = dyn_cast<ImplicitCastExpr>(litExpr)) {
  4156. // Use target Type for cast.
  4157. ArBasicKind kind = pHLSLExternalSource->GetTypeElementKind(IC->getType());
  4158. return kind;
  4159. } else {
  4160. // Could only be function call.
  4161. CallExpr *CE = cast<CallExpr>(litExpr);
  4162. // TODO: calculate the function call result.
  4163. if (CE->getNumArgs() == 1)
  4164. return LiteralToConcrete(CE->getArg(0), pHLSLExternalSource);
  4165. else {
  4166. ArBasicKind kind = LiteralToConcrete(CE->getArg(0), pHLSLExternalSource);
  4167. for (unsigned i = 1; i < CE->getNumArgs(); i++) {
  4168. ArBasicKind kindI = LiteralToConcrete(CE->getArg(i), pHLSLExternalSource);
  4169. CombineBasicTypes(kind, kindI, &kind);
  4170. }
  4171. return kind;
  4172. }
  4173. }
  4174. }
  4175. static bool SearchTypeInTable(ArBasicKind kind, const ArBasicKind *pCT) {
  4176. while (AR_BASIC_UNKNOWN != *pCT && AR_BASIC_NOCAST != *pCT) {
  4177. if (kind == *pCT)
  4178. return true;
  4179. pCT++;
  4180. }
  4181. return false;
  4182. }
  4183. static ArBasicKind
  4184. ConcreteLiteralType(Expr *litExpr, ArBasicKind kind,
  4185. unsigned uLegalComponentTypes,
  4186. HLSLExternalSource *pHLSLExternalSource) {
  4187. const ArBasicKind *pCT = g_LegalIntrinsicCompTypes[uLegalComponentTypes];
  4188. ArBasicKind defaultKind = *pCT;
  4189. // Use first none literal kind as defaultKind.
  4190. while (AR_BASIC_UNKNOWN != *pCT && AR_BASIC_NOCAST != *pCT) {
  4191. ArBasicKind kind = *pCT;
  4192. pCT++;
  4193. // Skip literal type.
  4194. if (kind == AR_BASIC_LITERAL_INT || kind == AR_BASIC_LITERAL_FLOAT)
  4195. continue;
  4196. defaultKind = kind;
  4197. break;
  4198. }
  4199. ArBasicKind litKind = LiteralToConcrete(litExpr, pHLSLExternalSource);
  4200. if (kind == AR_BASIC_LITERAL_INT) {
  4201. // Search for match first.
  4202. // For literal arg which don't affect return type, the search should always success.
  4203. // Unless use literal int on a float parameter.
  4204. if (SearchTypeInTable(litKind, g_LegalIntrinsicCompTypes[uLegalComponentTypes]))
  4205. return litKind;
  4206. // Return the default.
  4207. return defaultKind;
  4208. }
  4209. else {
  4210. // Search for float32 first.
  4211. if (SearchTypeInTable(AR_BASIC_FLOAT32, g_LegalIntrinsicCompTypes[uLegalComponentTypes]))
  4212. return AR_BASIC_FLOAT32;
  4213. // Search for float64.
  4214. if (SearchTypeInTable(AR_BASIC_FLOAT64, g_LegalIntrinsicCompTypes[uLegalComponentTypes]))
  4215. return AR_BASIC_FLOAT64;
  4216. // return default.
  4217. return defaultKind;
  4218. }
  4219. }
  4220. _Use_decl_annotations_ bool
  4221. HLSLExternalSource::IsValidateObjectElement(const HLSL_INTRINSIC *pIntrinsic,
  4222. QualType objectElement) {
  4223. IntrinsicOp op = static_cast<IntrinsicOp>(pIntrinsic->Op);
  4224. switch (op) {
  4225. case IntrinsicOp::MOP_Sample:
  4226. case IntrinsicOp::MOP_SampleBias:
  4227. case IntrinsicOp::MOP_SampleCmp:
  4228. case IntrinsicOp::MOP_SampleCmpLevelZero:
  4229. case IntrinsicOp::MOP_SampleGrad:
  4230. case IntrinsicOp::MOP_SampleLevel: {
  4231. ArBasicKind kind = GetTypeElementKind(objectElement);
  4232. UINT uBits = GET_BPROP_BITS(kind);
  4233. return IS_BASIC_FLOAT(kind) && uBits != BPROP_BITS64;
  4234. } break;
  4235. default:
  4236. return true;
  4237. }
  4238. }
  4239. _Use_decl_annotations_
  4240. bool HLSLExternalSource::MatchArguments(
  4241. const HLSL_INTRINSIC* pIntrinsic,
  4242. QualType objectElement,
  4243. ArrayRef<Expr *> Args,
  4244. QualType(&argTypes)[g_MaxIntrinsicParamCount + 1],
  4245. size_t* argCount)
  4246. {
  4247. DXASSERT_NOMSG(pIntrinsic != nullptr);
  4248. DXASSERT_NOMSG(argCount != nullptr);
  4249. static const UINT UnusedSize = 0xFF;
  4250. static const BYTE MaxIntrinsicArgs = g_MaxIntrinsicParamCount + 1;
  4251. #define CAB(_) { if (!(_)) return false; }
  4252. *argCount = 0;
  4253. ArTypeObjectKind Template[MaxIntrinsicArgs]; // Template type for each argument, AR_TOBJ_UNKNOWN if unspecified.
  4254. ArBasicKind ComponentType[MaxIntrinsicArgs]; // Component type for each argument, AR_BASIC_UNKNOWN if unspecified.
  4255. UINT uSpecialSize[IA_SPECIAL_SLOTS]; // row/col matching types, UNUSED_INDEX32 if unspecified.
  4256. // Reset infos
  4257. std::fill(Template, Template + _countof(Template), AR_TOBJ_UNKNOWN);
  4258. std::fill(ComponentType, ComponentType + _countof(ComponentType), AR_BASIC_UNKNOWN);
  4259. std::fill(uSpecialSize, uSpecialSize + _countof(uSpecialSize), UnusedSize);
  4260. const unsigned retArgIdx = 0;
  4261. unsigned retTypeIdx = pIntrinsic->pArgs[retArgIdx].uComponentTypeId;
  4262. // Populate the template for each argument.
  4263. ArrayRef<Expr*>::iterator iterArg = Args.begin();
  4264. ArrayRef<Expr*>::iterator end = Args.end();
  4265. unsigned int iArg = 1;
  4266. for (; iterArg != end; ++iterArg) {
  4267. Expr* pCallArg = *iterArg;
  4268. // No vararg support.
  4269. if (iArg >= _countof(Template) || iArg > pIntrinsic->uNumArgs) {
  4270. return false;
  4271. }
  4272. const HLSL_INTRINSIC_ARGUMENT *pIntrinsicArg;
  4273. pIntrinsicArg = &pIntrinsic->pArgs[iArg];
  4274. DXASSERT(pIntrinsicArg->uTemplateId != INTRIN_TEMPLATE_VARARGS, "no vararg support");
  4275. // If we are a type and templateID requires one, this isn't a match.
  4276. if (pIntrinsicArg->uTemplateId == INTRIN_TEMPLATE_FROM_TYPE) {
  4277. ++iArg;
  4278. continue;
  4279. }
  4280. QualType pType = pCallArg->getType();
  4281. ArTypeObjectKind TypeInfoShapeKind = GetTypeObjectKind(pType);
  4282. ArBasicKind TypeInfoEltKind = GetTypeElementKind(pType);
  4283. if (TypeInfoEltKind == AR_BASIC_LITERAL_INT ||
  4284. TypeInfoEltKind == AR_BASIC_LITERAL_FLOAT) {
  4285. bool affectRetType =
  4286. (iArg != retArgIdx && retTypeIdx == pIntrinsicArg->uComponentTypeId);
  4287. // For literal arg which don't affect return type, find concrete type.
  4288. // For literal arg affect return type,
  4289. // TryEvalIntrinsic in CGHLSLMS.cpp will take care of cases
  4290. // where all argumentss are literal.
  4291. // CombineBasicTypes will cover the rest cases.
  4292. if (!affectRetType) {
  4293. TypeInfoEltKind = ConcreteLiteralType(
  4294. pCallArg, TypeInfoEltKind, pIntrinsicArg->uLegalComponentTypes, this);
  4295. }
  4296. }
  4297. UINT TypeInfoCols = 1;
  4298. UINT TypeInfoRows = 1;
  4299. switch (TypeInfoShapeKind) {
  4300. case AR_TOBJ_MATRIX:
  4301. GetRowsAndCols(pType, TypeInfoRows, TypeInfoCols);
  4302. break;
  4303. case AR_TOBJ_VECTOR:
  4304. TypeInfoCols = GetHLSLVecSize(pType);
  4305. break;
  4306. case AR_TOBJ_BASIC:
  4307. case AR_TOBJ_OBJECT:
  4308. break;
  4309. default:
  4310. return false; // no struct, arrays or void
  4311. }
  4312. DXASSERT(
  4313. pIntrinsicArg->uTemplateId < MaxIntrinsicArgs,
  4314. "otherwise intrinsic table was modified and g_MaxIntrinsicParamCount was not updated (or uTemplateId is out of bounds)");
  4315. // Compare template
  4316. if ((AR_TOBJ_UNKNOWN == Template[pIntrinsicArg->uTemplateId]) ||
  4317. ((AR_TOBJ_SCALAR == Template[pIntrinsicArg->uTemplateId]) &&
  4318. (AR_TOBJ_VECTOR == TypeInfoShapeKind || AR_TOBJ_MATRIX == TypeInfoShapeKind))) {
  4319. Template[pIntrinsicArg->uTemplateId] = TypeInfoShapeKind;
  4320. }
  4321. else if (AR_TOBJ_SCALAR == TypeInfoShapeKind) {
  4322. if (AR_TOBJ_SCALAR != Template[pIntrinsicArg->uTemplateId] &&
  4323. AR_TOBJ_VECTOR != Template[pIntrinsicArg->uTemplateId] &&
  4324. AR_TOBJ_MATRIX != Template[pIntrinsicArg->uTemplateId]) {
  4325. return false;
  4326. }
  4327. }
  4328. else {
  4329. if (TypeInfoShapeKind != Template[pIntrinsicArg->uTemplateId]) {
  4330. return false;
  4331. }
  4332. }
  4333. DXASSERT(
  4334. pIntrinsicArg->uComponentTypeId < MaxIntrinsicArgs,
  4335. "otherwise intrinsic table was modified and MaxIntrinsicArgs was not updated (or uComponentTypeId is out of bounds)");
  4336. // Merge ComponentTypes
  4337. if (AR_BASIC_UNKNOWN == ComponentType[pIntrinsicArg->uComponentTypeId]) {
  4338. ComponentType[pIntrinsicArg->uComponentTypeId] = TypeInfoEltKind;
  4339. }
  4340. else {
  4341. if (!CombineBasicTypes(
  4342. ComponentType[pIntrinsicArg->uComponentTypeId],
  4343. TypeInfoEltKind,
  4344. &ComponentType[pIntrinsicArg->uComponentTypeId])) {
  4345. return false;
  4346. }
  4347. }
  4348. // Rows
  4349. if (AR_TOBJ_SCALAR != TypeInfoShapeKind) {
  4350. if (pIntrinsicArg->uRows >= IA_SPECIAL_BASE) {
  4351. UINT uSpecialId = pIntrinsicArg->uRows - IA_SPECIAL_BASE;
  4352. CAB(uSpecialId < IA_SPECIAL_SLOTS);
  4353. if (uSpecialSize[uSpecialId] > TypeInfoRows) {
  4354. uSpecialSize[uSpecialId] = TypeInfoRows;
  4355. }
  4356. }
  4357. else {
  4358. if (TypeInfoRows < pIntrinsicArg->uRows) {
  4359. return false;
  4360. }
  4361. }
  4362. }
  4363. // Columns
  4364. if (AR_TOBJ_SCALAR != TypeInfoShapeKind) {
  4365. if (pIntrinsicArg->uCols >= IA_SPECIAL_BASE) {
  4366. UINT uSpecialId = pIntrinsicArg->uCols - IA_SPECIAL_BASE;
  4367. CAB(uSpecialId < IA_SPECIAL_SLOTS);
  4368. if (uSpecialSize[uSpecialId] > TypeInfoCols) {
  4369. uSpecialSize[uSpecialId] = TypeInfoCols;
  4370. }
  4371. }
  4372. else {
  4373. if (TypeInfoCols < pIntrinsicArg->uCols) {
  4374. return false;
  4375. }
  4376. }
  4377. }
  4378. // Usage
  4379. if (pIntrinsicArg->qwUsage & AR_QUAL_OUT) {
  4380. if (pCallArg->getType().isConstQualified()) {
  4381. // Can't use a const type in an out or inout parameter.
  4382. return false;
  4383. }
  4384. }
  4385. iArg++;
  4386. }
  4387. DXASSERT(iterArg == end, "otherwise the argument list wasn't fully processed");
  4388. // Default template and component type for return value
  4389. if (pIntrinsic->pArgs[0].qwUsage && pIntrinsic->pArgs[0].uTemplateId != INTRIN_TEMPLATE_FROM_TYPE) {
  4390. CAB(pIntrinsic->pArgs[0].uTemplateId < MaxIntrinsicArgs);
  4391. if (AR_TOBJ_UNKNOWN == Template[pIntrinsic->pArgs[0].uTemplateId]) {
  4392. Template[pIntrinsic->pArgs[0].uTemplateId] =
  4393. g_LegalIntrinsicTemplates[pIntrinsic->pArgs[0].uLegalTemplates][0];
  4394. if (pIntrinsic->pArgs[0].uComponentTypeId != INTRIN_COMPTYPE_FROM_TYPE_ELT0) {
  4395. DXASSERT_NOMSG(pIntrinsic->pArgs[0].uComponentTypeId < MaxIntrinsicArgs);
  4396. if (AR_BASIC_UNKNOWN == ComponentType[pIntrinsic->pArgs[0].uComponentTypeId]) {
  4397. // half return type should map to float for min precision
  4398. if (pIntrinsic->pArgs[0].uLegalComponentTypes ==
  4399. LEGAL_INTRINSIC_COMPTYPES::LICOMPTYPE_FLOAT16 &&
  4400. getSema()->getLangOpts().UseMinPrecision) {
  4401. ComponentType[pIntrinsic->pArgs[0].uComponentTypeId] =
  4402. ArBasicKind::AR_BASIC_FLOAT32;
  4403. }
  4404. else {
  4405. ComponentType[pIntrinsic->pArgs[0].uComponentTypeId] =
  4406. g_LegalIntrinsicCompTypes[pIntrinsic->pArgs[0].uLegalComponentTypes][0];
  4407. }
  4408. }
  4409. }
  4410. }
  4411. }
  4412. // Make sure all template, component type, and texture type selections are valid.
  4413. for (size_t i = 0; i < Args.size() + 1; i++) {
  4414. const HLSL_INTRINSIC_ARGUMENT *pArgument = &pIntrinsic->pArgs[i];
  4415. // Check template.
  4416. if (pArgument->uTemplateId == INTRIN_TEMPLATE_FROM_TYPE) {
  4417. continue; // Already verified that this is available.
  4418. }
  4419. const ArTypeObjectKind *pTT = g_LegalIntrinsicTemplates[pArgument->uLegalTemplates];
  4420. if (AR_TOBJ_UNKNOWN != Template[i]) {
  4421. if ((AR_TOBJ_SCALAR == Template[i]) && (AR_TOBJ_VECTOR == *pTT || AR_TOBJ_MATRIX == *pTT)) {
  4422. Template[i] = *pTT;
  4423. }
  4424. else {
  4425. while (AR_TOBJ_UNKNOWN != *pTT) {
  4426. if (Template[i] == *pTT)
  4427. break;
  4428. pTT++;
  4429. }
  4430. }
  4431. if (AR_TOBJ_UNKNOWN == *pTT)
  4432. return false;
  4433. }
  4434. else if (pTT) {
  4435. Template[i] = *pTT;
  4436. }
  4437. // Check component type.
  4438. const ArBasicKind *pCT = g_LegalIntrinsicCompTypes[pArgument->uLegalComponentTypes];
  4439. if (AR_BASIC_UNKNOWN != ComponentType[i]) {
  4440. while (AR_BASIC_UNKNOWN != *pCT && AR_BASIC_NOCAST != *pCT) {
  4441. if (ComponentType[i] == *pCT)
  4442. break;
  4443. pCT++;
  4444. }
  4445. // has to be a strict match
  4446. if (*pCT == AR_BASIC_NOCAST)
  4447. return false;
  4448. // If it is an object, see if it can be cast to the first thing in the
  4449. // list, otherwise move on to next intrinsic.
  4450. if (AR_TOBJ_OBJECT == Template[i] && AR_BASIC_UNKNOWN == *pCT) {
  4451. if (!CombineObjectTypes(g_LegalIntrinsicCompTypes[pArgument->uLegalComponentTypes][0], ComponentType[i], nullptr)) {
  4452. return false;
  4453. }
  4454. }
  4455. if (AR_BASIC_UNKNOWN == *pCT) {
  4456. ComponentType[i] = g_LegalIntrinsicCompTypes[pArgument->uLegalComponentTypes][0];
  4457. }
  4458. }
  4459. else if (pCT) {
  4460. ComponentType[i] = *pCT;
  4461. }
  4462. }
  4463. // Default to a void return type.
  4464. argTypes[0] = m_context->VoidTy;
  4465. // Default specials sizes.
  4466. for (UINT i = 0; i < IA_SPECIAL_SLOTS; i++) {
  4467. if (UnusedSize == uSpecialSize[i]) {
  4468. uSpecialSize[i] = 1;
  4469. }
  4470. }
  4471. // Populate argTypes.
  4472. for (size_t i = 0; i <= Args.size(); i++) {
  4473. const HLSL_INTRINSIC_ARGUMENT *pArgument = &pIntrinsic->pArgs[i];
  4474. if (!pArgument->qwUsage)
  4475. continue;
  4476. QualType pNewType;
  4477. unsigned int quals = 0; // qualifications for this argument
  4478. // If we have no type, set it to our input type (templatized)
  4479. if (pArgument->uTemplateId == INTRIN_TEMPLATE_FROM_TYPE) {
  4480. // Use the templated input type, but resize it if the
  4481. // intrinsic's rows/cols isn't 0
  4482. if (pArgument->uRows && pArgument->uCols) {
  4483. UINT uRows, uCols = 0;
  4484. // if type is overriden, use new type size, for
  4485. // now it only supports scalars
  4486. if (pArgument->uRows >= IA_SPECIAL_BASE) {
  4487. UINT uSpecialId = pArgument->uRows - IA_SPECIAL_BASE;
  4488. CAB(uSpecialId < IA_SPECIAL_SLOTS);
  4489. uRows = uSpecialSize[uSpecialId];
  4490. }
  4491. else if (pArgument->uRows > 0) {
  4492. uRows = pArgument->uRows;
  4493. }
  4494. if (pArgument->uCols >= IA_SPECIAL_BASE) {
  4495. UINT uSpecialId = pArgument->uCols - IA_SPECIAL_BASE;
  4496. CAB(uSpecialId < IA_SPECIAL_SLOTS);
  4497. uCols = uSpecialSize[uSpecialId];
  4498. }
  4499. else if (pArgument->uCols > 0) {
  4500. uCols = pArgument->uCols;
  4501. }
  4502. // 1x1 numeric outputs are always scalar.. since these
  4503. // are most flexible
  4504. if ((1 == uCols) && (1 == uRows)) {
  4505. pNewType = objectElement;
  4506. if (pNewType.isNull()) {
  4507. return false;
  4508. }
  4509. }
  4510. else {
  4511. // non-scalars unsupported right now since nothing
  4512. // uses it, would have to create either a type
  4513. // list for sub-structures or just resize the
  4514. // given type
  4515. // VH(E_NOTIMPL);
  4516. return false;
  4517. }
  4518. }
  4519. else {
  4520. DXASSERT_NOMSG(!pArgument->uRows && !pArgument->uCols);
  4521. if (objectElement.isNull()) {
  4522. return false;
  4523. }
  4524. pNewType = objectElement;
  4525. }
  4526. }
  4527. else {
  4528. ArBasicKind pEltType;
  4529. // ComponentType, if the Id is special then it gets the
  4530. // component type from the first component of the type, if
  4531. // we need more (for the second component, e.g.), then we
  4532. // can use more specials, etc.
  4533. if (pArgument->uComponentTypeId == INTRIN_COMPTYPE_FROM_TYPE_ELT0) {
  4534. if (objectElement.isNull()) {
  4535. return false;
  4536. }
  4537. pEltType = GetTypeElementKind(objectElement);
  4538. DXASSERT_VALIDBASICKIND(pEltType);
  4539. }
  4540. else {
  4541. pEltType = ComponentType[pArgument->uComponentTypeId];
  4542. DXASSERT_VALIDBASICKIND(pEltType);
  4543. }
  4544. UINT uRows, uCols;
  4545. // Rows
  4546. if (pArgument->uRows >= IA_SPECIAL_BASE) {
  4547. UINT uSpecialId = pArgument->uRows - IA_SPECIAL_BASE;
  4548. CAB(uSpecialId < IA_SPECIAL_SLOTS);
  4549. uRows = uSpecialSize[uSpecialId];
  4550. }
  4551. else {
  4552. uRows = pArgument->uRows;
  4553. }
  4554. // Cols
  4555. if (pArgument->uCols >= IA_SPECIAL_BASE) {
  4556. UINT uSpecialId = pArgument->uCols - IA_SPECIAL_BASE;
  4557. CAB(uSpecialId < IA_SPECIAL_SLOTS);
  4558. uCols = uSpecialSize[uSpecialId];
  4559. }
  4560. else {
  4561. uCols = pArgument->uCols;
  4562. }
  4563. // Verify that the final results are in bounds.
  4564. CAB(uCols > 0 && uCols <= MaxVectorSize && uRows > 0 && uRows <= MaxVectorSize);
  4565. // Const
  4566. UINT64 qwQual = pArgument->qwUsage & (AR_QUAL_ROWMAJOR | AR_QUAL_COLMAJOR);
  4567. if ((0 == i) || !(pArgument->qwUsage & AR_QUAL_OUT))
  4568. qwQual |= AR_QUAL_CONST;
  4569. DXASSERT_VALIDBASICKIND(pEltType);
  4570. pNewType = NewSimpleAggregateType(Template[pArgument->uTemplateId], pEltType, qwQual, uRows, uCols);
  4571. }
  4572. DXASSERT(!pNewType.isNull(), "otherwise there's a branch in this function that fails to assign this");
  4573. argTypes[i] = QualType(pNewType.getTypePtr(), quals);
  4574. // TODO: support out modifier
  4575. //if (pArgument->qwUsage & AR_QUAL_OUT) {
  4576. // argTypes[i] = m_context->getLValueReferenceType(argTypes[i].withConst());
  4577. //}
  4578. }
  4579. *argCount = iArg;
  4580. DXASSERT(
  4581. *argCount == pIntrinsic->uNumArgs,
  4582. "In the absence of varargs, a successful match would indicate we have as many arguments and types as the intrinsic template");
  4583. return true;
  4584. #undef CAB
  4585. }
  4586. _Use_decl_annotations_
  4587. HLSLExternalSource::FindStructBasicTypeResult
  4588. HLSLExternalSource::FindStructBasicType(DeclContext* functionDeclContext)
  4589. {
  4590. DXASSERT_NOMSG(functionDeclContext != nullptr);
  4591. // functionDeclContext may be a specialization of a template, such as AppendBuffer<MY_STRUCT>, or it
  4592. // may be a simple class, such as RWByteAddressBuffer.
  4593. const CXXRecordDecl* recordDecl = GetRecordDeclForBuiltInOrStruct(functionDeclContext);
  4594. // We save the caller from filtering out other types of context (like the translation unit itself).
  4595. if (recordDecl != nullptr)
  4596. {
  4597. int index = FindObjectBasicKindIndex(recordDecl);
  4598. if (index != -1) {
  4599. ArBasicKind kind = g_ArBasicKindsAsTypes[index];
  4600. return HLSLExternalSource::FindStructBasicTypeResult(kind, index);
  4601. }
  4602. }
  4603. return HLSLExternalSource::FindStructBasicTypeResult(AR_BASIC_UNKNOWN, 0);
  4604. }
  4605. _Use_decl_annotations_
  4606. void HLSLExternalSource::FindIntrinsicTable(DeclContext* functionDeclContext, const char** name, const HLSL_INTRINSIC** intrinsics, size_t* intrinsicCount)
  4607. {
  4608. DXASSERT_NOMSG(functionDeclContext != nullptr);
  4609. DXASSERT_NOMSG(name != nullptr);
  4610. DXASSERT_NOMSG(intrinsics != nullptr);
  4611. DXASSERT_NOMSG(intrinsicCount != nullptr);
  4612. *intrinsics = nullptr;
  4613. *intrinsicCount = 0;
  4614. *name = nullptr;
  4615. HLSLExternalSource::FindStructBasicTypeResult lookup = FindStructBasicType(functionDeclContext);
  4616. if (lookup.Found()) {
  4617. GetIntrinsicMethods(lookup.Kind, intrinsics, intrinsicCount);
  4618. *name = g_ArBasicTypeNames[lookup.Kind];
  4619. }
  4620. }
  4621. static bool BinaryOperatorKindIsArithmetic(BinaryOperatorKind Opc)
  4622. {
  4623. return
  4624. // Arithmetic operators.
  4625. Opc == BinaryOperatorKind::BO_Add ||
  4626. Opc == BinaryOperatorKind::BO_AddAssign ||
  4627. Opc == BinaryOperatorKind::BO_Sub ||
  4628. Opc == BinaryOperatorKind::BO_SubAssign ||
  4629. Opc == BinaryOperatorKind::BO_Rem ||
  4630. Opc == BinaryOperatorKind::BO_RemAssign ||
  4631. Opc == BinaryOperatorKind::BO_Div ||
  4632. Opc == BinaryOperatorKind::BO_DivAssign ||
  4633. Opc == BinaryOperatorKind::BO_Mul ||
  4634. Opc == BinaryOperatorKind::BO_MulAssign;
  4635. }
  4636. static bool BinaryOperatorKindIsCompoundAssignment(BinaryOperatorKind Opc)
  4637. {
  4638. return
  4639. // Arithmetic-and-assignment operators.
  4640. Opc == BinaryOperatorKind::BO_AddAssign ||
  4641. Opc == BinaryOperatorKind::BO_SubAssign ||
  4642. Opc == BinaryOperatorKind::BO_RemAssign ||
  4643. Opc == BinaryOperatorKind::BO_DivAssign ||
  4644. Opc == BinaryOperatorKind::BO_MulAssign ||
  4645. // Bitwise-and-assignment operators.
  4646. Opc == BinaryOperatorKind::BO_ShlAssign ||
  4647. Opc == BinaryOperatorKind::BO_ShrAssign ||
  4648. Opc == BinaryOperatorKind::BO_AndAssign ||
  4649. Opc == BinaryOperatorKind::BO_OrAssign ||
  4650. Opc == BinaryOperatorKind::BO_XorAssign;
  4651. }
  4652. static bool BinaryOperatorKindIsCompoundAssignmentForBool(BinaryOperatorKind Opc)
  4653. {
  4654. return
  4655. Opc == BinaryOperatorKind::BO_AndAssign ||
  4656. Opc == BinaryOperatorKind::BO_OrAssign ||
  4657. Opc == BinaryOperatorKind::BO_XorAssign;
  4658. }
  4659. static bool BinaryOperatorKindIsBitwise(BinaryOperatorKind Opc)
  4660. {
  4661. return
  4662. Opc == BinaryOperatorKind::BO_Shl ||
  4663. Opc == BinaryOperatorKind::BO_ShlAssign ||
  4664. Opc == BinaryOperatorKind::BO_Shr ||
  4665. Opc == BinaryOperatorKind::BO_ShrAssign ||
  4666. Opc == BinaryOperatorKind::BO_And ||
  4667. Opc == BinaryOperatorKind::BO_AndAssign ||
  4668. Opc == BinaryOperatorKind::BO_Or ||
  4669. Opc == BinaryOperatorKind::BO_OrAssign ||
  4670. Opc == BinaryOperatorKind::BO_Xor ||
  4671. Opc == BinaryOperatorKind::BO_XorAssign;
  4672. }
  4673. static bool BinaryOperatorKindIsBitwiseShift(BinaryOperatorKind Opc)
  4674. {
  4675. return
  4676. Opc == BinaryOperatorKind::BO_Shl ||
  4677. Opc == BinaryOperatorKind::BO_ShlAssign ||
  4678. Opc == BinaryOperatorKind::BO_Shr ||
  4679. Opc == BinaryOperatorKind::BO_ShrAssign;
  4680. }
  4681. static bool BinaryOperatorKindIsEqualComparison(BinaryOperatorKind Opc)
  4682. {
  4683. return
  4684. Opc == BinaryOperatorKind::BO_EQ ||
  4685. Opc == BinaryOperatorKind::BO_NE;
  4686. }
  4687. static bool BinaryOperatorKindIsOrderComparison(BinaryOperatorKind Opc)
  4688. {
  4689. return
  4690. Opc == BinaryOperatorKind::BO_LT ||
  4691. Opc == BinaryOperatorKind::BO_GT ||
  4692. Opc == BinaryOperatorKind::BO_LE ||
  4693. Opc == BinaryOperatorKind::BO_GE;
  4694. }
  4695. static bool BinaryOperatorKindIsComparison(BinaryOperatorKind Opc)
  4696. {
  4697. return BinaryOperatorKindIsEqualComparison(Opc) || BinaryOperatorKindIsOrderComparison(Opc);
  4698. }
  4699. static bool BinaryOperatorKindIsLogical(BinaryOperatorKind Opc)
  4700. {
  4701. return
  4702. Opc == BinaryOperatorKind::BO_LAnd ||
  4703. Opc == BinaryOperatorKind::BO_LOr;
  4704. }
  4705. static bool BinaryOperatorKindRequiresNumeric(BinaryOperatorKind Opc)
  4706. {
  4707. return
  4708. BinaryOperatorKindIsArithmetic(Opc) ||
  4709. BinaryOperatorKindIsOrderComparison(Opc) ||
  4710. BinaryOperatorKindIsLogical(Opc);
  4711. }
  4712. static bool BinaryOperatorKindRequiresIntegrals(BinaryOperatorKind Opc)
  4713. {
  4714. return BinaryOperatorKindIsBitwise(Opc);
  4715. }
  4716. static bool BinaryOperatorKindRequiresBoolAsNumeric(BinaryOperatorKind Opc)
  4717. {
  4718. return
  4719. BinaryOperatorKindIsBitwise(Opc) ||
  4720. BinaryOperatorKindIsArithmetic(Opc);
  4721. }
  4722. static bool UnaryOperatorKindRequiresIntegrals(UnaryOperatorKind Opc)
  4723. {
  4724. return Opc == UnaryOperatorKind::UO_Not;
  4725. }
  4726. static bool UnaryOperatorKindRequiresNumerics(UnaryOperatorKind Opc)
  4727. {
  4728. return
  4729. Opc == UnaryOperatorKind::UO_LNot ||
  4730. Opc == UnaryOperatorKind::UO_Plus ||
  4731. Opc == UnaryOperatorKind::UO_Minus ||
  4732. // The omission in fxc caused objects and structs to accept this.
  4733. Opc == UnaryOperatorKind::UO_PreDec || Opc == UnaryOperatorKind::UO_PreInc ||
  4734. Opc == UnaryOperatorKind::UO_PostDec || Opc == UnaryOperatorKind::UO_PostInc;
  4735. }
  4736. static bool UnaryOperatorKindRequiresModifiableValue(UnaryOperatorKind Opc)
  4737. {
  4738. return
  4739. Opc == UnaryOperatorKind::UO_PreDec || Opc == UnaryOperatorKind::UO_PreInc ||
  4740. Opc == UnaryOperatorKind::UO_PostDec || Opc == UnaryOperatorKind::UO_PostInc;
  4741. }
  4742. static bool UnaryOperatorKindRequiresBoolAsNumeric(UnaryOperatorKind Opc)
  4743. {
  4744. return
  4745. Opc == UnaryOperatorKind::UO_Not ||
  4746. Opc == UnaryOperatorKind::UO_Plus ||
  4747. Opc == UnaryOperatorKind::UO_Minus;
  4748. }
  4749. static bool UnaryOperatorKindDisallowsBool(UnaryOperatorKind Opc)
  4750. {
  4751. return
  4752. Opc == UnaryOperatorKind::UO_PreDec || Opc == UnaryOperatorKind::UO_PreInc ||
  4753. Opc == UnaryOperatorKind::UO_PostDec || Opc == UnaryOperatorKind::UO_PostInc;
  4754. }
  4755. static bool IsIncrementOp(UnaryOperatorKind Opc) {
  4756. return Opc == UnaryOperatorKind::UO_PreInc || Opc == UnaryOperatorKind::UO_PostInc;
  4757. }
  4758. /// <summary>
  4759. /// Checks whether the specified AR_TOBJ* value is a primitive or aggregate of primitive elements
  4760. /// (as opposed to a built-in object like a sampler or texture, or a void type).
  4761. /// </summary>
  4762. static bool IsObjectKindPrimitiveAggregate(ArTypeObjectKind value)
  4763. {
  4764. return
  4765. value == AR_TOBJ_BASIC ||
  4766. value == AR_TOBJ_MATRIX ||
  4767. value == AR_TOBJ_VECTOR;
  4768. }
  4769. static bool IsBasicKindIntegral(ArBasicKind value)
  4770. {
  4771. return IS_BASIC_AINT(value) || IS_BASIC_BOOL(value);
  4772. }
  4773. static bool IsBasicKindIntMinPrecision(ArBasicKind kind)
  4774. {
  4775. return IS_BASIC_SINT(kind) && IS_BASIC_MIN_PRECISION(kind);
  4776. }
  4777. static bool IsBasicKindNumeric(ArBasicKind value)
  4778. {
  4779. return GetBasicKindProps(value) & BPROP_NUMERIC;
  4780. }
  4781. ExprResult HLSLExternalSource::PromoteToIntIfBool(ExprResult& E)
  4782. {
  4783. // An invalid expression is pass-through at this point.
  4784. if (E.isInvalid())
  4785. {
  4786. return E;
  4787. }
  4788. QualType qt = E.get()->getType();
  4789. ArBasicKind elementKind = this->GetTypeElementKind(qt);
  4790. if (elementKind != AR_BASIC_BOOL)
  4791. {
  4792. return E;
  4793. }
  4794. // Construct a scalar/vector/matrix type with the same shape as E.
  4795. ArTypeObjectKind objectKind = this->GetTypeObjectKind(qt);
  4796. QualType targetType;
  4797. UINT colCount, rowCount;
  4798. GetRowsAndColsForAny(qt, rowCount, colCount);
  4799. targetType = NewSimpleAggregateType(objectKind, AR_BASIC_INT32, 0, rowCount, colCount)->getCanonicalTypeInternal();
  4800. if (E.get()->isLValue()) {
  4801. E = m_sema->DefaultLvalueConversion(E.get()).get();
  4802. }
  4803. switch (objectKind)
  4804. {
  4805. case AR_TOBJ_SCALAR:
  4806. return ImplicitCastExpr::Create(*m_context, targetType, CastKind::CK_IntegralCast, E.get(), nullptr, ExprValueKind::VK_RValue);
  4807. case AR_TOBJ_ARRAY:
  4808. case AR_TOBJ_VECTOR:
  4809. case AR_TOBJ_MATRIX:
  4810. return ImplicitCastExpr::Create(*m_context, targetType, CastKind::CK_HLSLCC_IntegralCast, E.get(), nullptr, ExprValueKind::VK_RValue);
  4811. default:
  4812. DXASSERT(false, "unsupported objectKind for PromoteToIntIfBool");
  4813. }
  4814. return E;
  4815. }
  4816. _Use_decl_annotations_
  4817. void HLSLExternalSource::CollectInfo(QualType type, ArTypeInfo* pTypeInfo)
  4818. {
  4819. DXASSERT_NOMSG(pTypeInfo != nullptr);
  4820. DXASSERT_NOMSG(!type.isNull());
  4821. memset(pTypeInfo, 0, sizeof(*pTypeInfo));
  4822. pTypeInfo->ObjKind = GetTypeElementKind(type);
  4823. pTypeInfo->EltKind = pTypeInfo->ObjKind;
  4824. pTypeInfo->ShapeKind = GetTypeObjectKind(type);
  4825. GetRowsAndColsForAny(type, pTypeInfo->uRows, pTypeInfo->uCols);
  4826. pTypeInfo->uTotalElts = pTypeInfo->uRows * pTypeInfo->uCols;
  4827. }
  4828. // Highest possible score (i.e., worst possible score).
  4829. static const UINT64 SCORE_MAX = 0xFFFFFFFFFFFFFFFF;
  4830. // Leave the first two score bits to handle higher-level
  4831. // variations like target type.
  4832. #define SCORE_MIN_SHIFT 2
  4833. // Space out scores to allow up to 128 parameters to
  4834. // vary between score sets spill into each other.
  4835. #define SCORE_PARAM_SHIFT 7
  4836. unsigned HLSLExternalSource::GetNumElements(QualType anyType) {
  4837. if (anyType.isNull()) {
  4838. return 0;
  4839. }
  4840. anyType = GetStructuralForm(anyType);
  4841. ArTypeObjectKind kind = GetTypeObjectKind(anyType);
  4842. switch (kind) {
  4843. case AR_TOBJ_BASIC:
  4844. case AR_TOBJ_OBJECT:
  4845. return 1;
  4846. case AR_TOBJ_COMPOUND: {
  4847. // TODO: consider caching this value for perf
  4848. unsigned total = 0;
  4849. const RecordType *recordType = anyType->getAs<RecordType>();
  4850. RecordDecl::field_iterator fi = recordType->getDecl()->field_begin();
  4851. RecordDecl::field_iterator fend = recordType->getDecl()->field_end();
  4852. while (fi != fend) {
  4853. total += GetNumElements(fi->getType());
  4854. ++fi;
  4855. }
  4856. return total;
  4857. }
  4858. case AR_TOBJ_ARRAY:
  4859. case AR_TOBJ_MATRIX:
  4860. case AR_TOBJ_VECTOR:
  4861. return GetElementCount(anyType);
  4862. default:
  4863. DXASSERT(kind == AR_TOBJ_VOID,
  4864. "otherwise the type cannot be classified or is not supported");
  4865. return 0;
  4866. }
  4867. }
  4868. unsigned HLSLExternalSource::GetNumBasicElements(QualType anyType) {
  4869. if (anyType.isNull()) {
  4870. return 0;
  4871. }
  4872. anyType = GetStructuralForm(anyType);
  4873. ArTypeObjectKind kind = GetTypeObjectKind(anyType);
  4874. switch (kind) {
  4875. case AR_TOBJ_BASIC:
  4876. case AR_TOBJ_OBJECT:
  4877. return 1;
  4878. case AR_TOBJ_COMPOUND: {
  4879. // TODO: consider caching this value for perf
  4880. unsigned total = 0;
  4881. const RecordType *recordType = anyType->getAs<RecordType>();
  4882. RecordDecl * RD = recordType->getDecl();
  4883. // Take care base.
  4884. if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
  4885. if (CXXRD->getNumBases()) {
  4886. for (const auto &I : CXXRD->bases()) {
  4887. const CXXRecordDecl *BaseDecl =
  4888. cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
  4889. if (BaseDecl->field_empty())
  4890. continue;
  4891. QualType parentTy = QualType(BaseDecl->getTypeForDecl(), 0);
  4892. total += GetNumBasicElements(parentTy);
  4893. }
  4894. }
  4895. }
  4896. RecordDecl::field_iterator fi = RD->field_begin();
  4897. RecordDecl::field_iterator fend = RD->field_end();
  4898. while (fi != fend) {
  4899. total += GetNumBasicElements(fi->getType());
  4900. ++fi;
  4901. }
  4902. return total;
  4903. }
  4904. case AR_TOBJ_ARRAY: {
  4905. unsigned arraySize = GetElementCount(anyType);
  4906. unsigned eltSize = GetNumBasicElements(
  4907. QualType(anyType->getArrayElementTypeNoTypeQual(), 0));
  4908. return arraySize * eltSize;
  4909. }
  4910. case AR_TOBJ_MATRIX:
  4911. case AR_TOBJ_VECTOR:
  4912. return GetElementCount(anyType);
  4913. default:
  4914. DXASSERT(kind == AR_TOBJ_VOID,
  4915. "otherwise the type cannot be classified or is not supported");
  4916. return 0;
  4917. }
  4918. }
  4919. unsigned HLSLExternalSource::GetNumConvertCheckElts(QualType leftType,
  4920. unsigned leftSize,
  4921. QualType rightType,
  4922. unsigned rightSize) {
  4923. // We can convert from a larger type to a smaller
  4924. // but not a smaller type to a larger so default
  4925. // to just comparing the destination size.
  4926. unsigned uElts = leftSize;
  4927. leftType = GetStructuralForm(leftType);
  4928. rightType = GetStructuralForm(rightType);
  4929. if (leftType->isArrayType() && rightType->isArrayType()) {
  4930. //
  4931. // If we're comparing arrays we don't
  4932. // need to compare every element of
  4933. // the arrays since all elements
  4934. // will have the same type.
  4935. // We only need to compare enough
  4936. // elements that we've tried every
  4937. // possible mix of dst and src elements.
  4938. //
  4939. // TODO: handle multidimensional arrays and arrays of arrays
  4940. QualType pDstElt = leftType->getAsArrayTypeUnsafe()->getElementType();
  4941. unsigned uDstEltSize = GetNumElements(pDstElt);
  4942. QualType pSrcElt = rightType->getAsArrayTypeUnsafe()->getElementType();
  4943. unsigned uSrcEltSize = GetNumElements(pSrcElt);
  4944. if (uDstEltSize == uSrcEltSize) {
  4945. uElts = uDstEltSize;
  4946. } else if (uDstEltSize > uSrcEltSize) {
  4947. // If one size is not an even multiple of the other we need to let the
  4948. // full compare run in order to try all alignments.
  4949. if (uSrcEltSize && (uDstEltSize % uSrcEltSize) == 0) {
  4950. uElts = uDstEltSize;
  4951. }
  4952. } else if (uDstEltSize && (uSrcEltSize % uDstEltSize) == 0) {
  4953. uElts = uSrcEltSize;
  4954. }
  4955. }
  4956. return uElts;
  4957. }
  4958. QualType HLSLExternalSource::GetNthElementType(QualType type, unsigned index) {
  4959. if (type.isNull()) {
  4960. return type;
  4961. }
  4962. ArTypeObjectKind kind = GetTypeObjectKind(type);
  4963. switch (kind) {
  4964. case AR_TOBJ_BASIC:
  4965. case AR_TOBJ_OBJECT:
  4966. return (index == 0) ? type : QualType();
  4967. case AR_TOBJ_COMPOUND: {
  4968. // TODO: consider caching this value for perf
  4969. const RecordType *recordType = type->getAsStructureType();
  4970. RecordDecl::field_iterator fi = recordType->getDecl()->field_begin();
  4971. RecordDecl::field_iterator fend = recordType->getDecl()->field_end();
  4972. while (fi != fend) {
  4973. if (!fi->getType().isNull()) {
  4974. unsigned subElements = GetNumElements(fi->getType());
  4975. if (index < subElements) {
  4976. return GetNthElementType(fi->getType(), index);
  4977. } else {
  4978. index -= subElements;
  4979. }
  4980. }
  4981. ++fi;
  4982. }
  4983. return QualType();
  4984. }
  4985. case AR_TOBJ_ARRAY: {
  4986. unsigned arraySize;
  4987. QualType elementType;
  4988. unsigned elementCount;
  4989. elementType = type.getNonReferenceType()->getAsArrayTypeUnsafe()->getElementType();
  4990. elementCount = GetElementCount(elementType);
  4991. if (index < elementCount) {
  4992. return GetNthElementType(elementType, index);
  4993. }
  4994. arraySize = GetArraySize(type);
  4995. if (index >= arraySize * elementCount) {
  4996. return QualType();
  4997. }
  4998. return GetNthElementType(elementType, index % elementCount);
  4999. }
  5000. case AR_TOBJ_MATRIX:
  5001. case AR_TOBJ_VECTOR:
  5002. return (index < GetElementCount(type)) ? GetMatrixOrVectorElementType(type)
  5003. : QualType();
  5004. default:
  5005. DXASSERT(kind == AR_TOBJ_VOID,
  5006. "otherwise the type cannot be classified or is not supported");
  5007. return QualType();
  5008. }
  5009. }
  5010. bool HLSLExternalSource::IsPromotion(ArBasicKind leftKind, ArBasicKind rightKind) {
  5011. // Eliminate exact matches first, then check for promotions.
  5012. if (leftKind == rightKind) {
  5013. return false;
  5014. }
  5015. switch (rightKind) {
  5016. case AR_BASIC_FLOAT16:
  5017. switch (leftKind) {
  5018. case AR_BASIC_FLOAT32:
  5019. case AR_BASIC_FLOAT32_PARTIAL_PRECISION:
  5020. case AR_BASIC_FLOAT64:
  5021. return true;
  5022. default:
  5023. return false; // No other type is a promotion.
  5024. }
  5025. break;
  5026. case AR_BASIC_FLOAT32_PARTIAL_PRECISION:
  5027. switch (leftKind) {
  5028. case AR_BASIC_FLOAT32:
  5029. case AR_BASIC_FLOAT64:
  5030. return true;
  5031. default:
  5032. return false; // No other type is a promotion.
  5033. }
  5034. break;
  5035. case AR_BASIC_FLOAT32:
  5036. switch (leftKind) {
  5037. case AR_BASIC_FLOAT64:
  5038. return true;
  5039. default:
  5040. return false; // No other type is a promotion.
  5041. }
  5042. break;
  5043. case AR_BASIC_MIN10FLOAT:
  5044. switch (leftKind) {
  5045. case AR_BASIC_MIN16FLOAT:
  5046. case AR_BASIC_FLOAT16:
  5047. case AR_BASIC_FLOAT32:
  5048. case AR_BASIC_FLOAT32_PARTIAL_PRECISION:
  5049. case AR_BASIC_FLOAT64:
  5050. return true;
  5051. default:
  5052. return false; // No other type is a promotion.
  5053. }
  5054. break;
  5055. case AR_BASIC_MIN16FLOAT:
  5056. switch (leftKind) {
  5057. case AR_BASIC_FLOAT16:
  5058. case AR_BASIC_FLOAT32:
  5059. case AR_BASIC_FLOAT32_PARTIAL_PRECISION:
  5060. case AR_BASIC_FLOAT64:
  5061. return true;
  5062. default:
  5063. return false; // No other type is a promotion.
  5064. }
  5065. break;
  5066. case AR_BASIC_INT8:
  5067. case AR_BASIC_UINT8:
  5068. // For backwards compat we consider signed/unsigned the same.
  5069. switch (leftKind) {
  5070. case AR_BASIC_INT16:
  5071. case AR_BASIC_INT32:
  5072. case AR_BASIC_INT64:
  5073. case AR_BASIC_UINT16:
  5074. case AR_BASIC_UINT32:
  5075. case AR_BASIC_UINT64:
  5076. return true;
  5077. default:
  5078. return false; // No other type is a promotion.
  5079. }
  5080. break;
  5081. case AR_BASIC_INT16:
  5082. case AR_BASIC_UINT16:
  5083. // For backwards compat we consider signed/unsigned the same.
  5084. switch (leftKind) {
  5085. case AR_BASIC_INT32:
  5086. case AR_BASIC_INT64:
  5087. case AR_BASIC_UINT32:
  5088. case AR_BASIC_UINT64:
  5089. return true;
  5090. default:
  5091. return false; // No other type is a promotion.
  5092. }
  5093. break;
  5094. case AR_BASIC_INT32:
  5095. case AR_BASIC_UINT32:
  5096. // For backwards compat we consider signed/unsigned the same.
  5097. switch (leftKind) {
  5098. case AR_BASIC_INT64:
  5099. case AR_BASIC_UINT64:
  5100. return true;
  5101. default:
  5102. return false; // No other type is a promotion.
  5103. }
  5104. break;
  5105. case AR_BASIC_MIN12INT:
  5106. switch (leftKind) {
  5107. case AR_BASIC_MIN16INT:
  5108. case AR_BASIC_INT32:
  5109. case AR_BASIC_INT64:
  5110. return true;
  5111. default:
  5112. return false; // No other type is a promotion.
  5113. }
  5114. break;
  5115. case AR_BASIC_MIN16INT:
  5116. switch (leftKind) {
  5117. case AR_BASIC_INT32:
  5118. case AR_BASIC_INT64:
  5119. return true;
  5120. default:
  5121. return false; // No other type is a promotion.
  5122. }
  5123. break;
  5124. case AR_BASIC_MIN16UINT:
  5125. switch (leftKind) {
  5126. case AR_BASIC_UINT32:
  5127. case AR_BASIC_UINT64:
  5128. return true;
  5129. default:
  5130. return false; // No other type is a promotion.
  5131. }
  5132. break;
  5133. }
  5134. return false;
  5135. }
  5136. bool HLSLExternalSource::IsCast(ArBasicKind leftKind, ArBasicKind rightKind) {
  5137. // Eliminate exact matches first, then check for casts.
  5138. if (leftKind == rightKind) {
  5139. return false;
  5140. }
  5141. //
  5142. // All minimum-bits types are only considered matches of themselves
  5143. // and thus are not in this table.
  5144. //
  5145. switch (leftKind) {
  5146. case AR_BASIC_LITERAL_INT:
  5147. switch (rightKind) {
  5148. case AR_BASIC_INT8:
  5149. case AR_BASIC_INT16:
  5150. case AR_BASIC_INT32:
  5151. case AR_BASIC_INT64:
  5152. case AR_BASIC_UINT8:
  5153. case AR_BASIC_UINT16:
  5154. case AR_BASIC_UINT32:
  5155. case AR_BASIC_UINT64:
  5156. return false;
  5157. default:
  5158. break; // No other valid cast types
  5159. }
  5160. break;
  5161. case AR_BASIC_INT8:
  5162. switch (rightKind) {
  5163. // For backwards compat we consider signed/unsigned the same.
  5164. case AR_BASIC_LITERAL_INT:
  5165. case AR_BASIC_UINT8:
  5166. return false;
  5167. default:
  5168. break; // No other valid cast types
  5169. }
  5170. break;
  5171. case AR_BASIC_INT16:
  5172. switch (rightKind) {
  5173. // For backwards compat we consider signed/unsigned the same.
  5174. case AR_BASIC_LITERAL_INT:
  5175. case AR_BASIC_UINT16:
  5176. return false;
  5177. default:
  5178. break; // No other valid cast types
  5179. }
  5180. break;
  5181. case AR_BASIC_INT32:
  5182. switch (rightKind) {
  5183. // For backwards compat we consider signed/unsigned the same.
  5184. case AR_BASIC_LITERAL_INT:
  5185. case AR_BASIC_UINT32:
  5186. return false;
  5187. default:
  5188. break; // No other valid cast types.
  5189. }
  5190. break;
  5191. case AR_BASIC_INT64:
  5192. switch (rightKind) {
  5193. // For backwards compat we consider signed/unsigned the same.
  5194. case AR_BASIC_LITERAL_INT:
  5195. case AR_BASIC_UINT64:
  5196. return false;
  5197. default:
  5198. break; // No other valid cast types.
  5199. }
  5200. break;
  5201. case AR_BASIC_UINT8:
  5202. switch (rightKind) {
  5203. // For backwards compat we consider signed/unsigned the same.
  5204. case AR_BASIC_LITERAL_INT:
  5205. case AR_BASIC_INT8:
  5206. return false;
  5207. default:
  5208. break; // No other valid cast types.
  5209. }
  5210. break;
  5211. case AR_BASIC_UINT16:
  5212. switch (rightKind) {
  5213. // For backwards compat we consider signed/unsigned the same.
  5214. case AR_BASIC_LITERAL_INT:
  5215. case AR_BASIC_INT16:
  5216. return false;
  5217. default:
  5218. break; // No other valid cast types.
  5219. }
  5220. break;
  5221. case AR_BASIC_UINT32:
  5222. switch (rightKind) {
  5223. // For backwards compat we consider signed/unsigned the same.
  5224. case AR_BASIC_LITERAL_INT:
  5225. case AR_BASIC_INT32:
  5226. return false;
  5227. default:
  5228. break; // No other valid cast types.
  5229. }
  5230. break;
  5231. case AR_BASIC_UINT64:
  5232. switch (rightKind) {
  5233. // For backwards compat we consider signed/unsigned the same.
  5234. case AR_BASIC_LITERAL_INT:
  5235. case AR_BASIC_INT64:
  5236. return false;
  5237. default:
  5238. break; // No other valid cast types.
  5239. }
  5240. break;
  5241. case AR_BASIC_LITERAL_FLOAT:
  5242. switch (rightKind) {
  5243. case AR_BASIC_LITERAL_FLOAT:
  5244. case AR_BASIC_FLOAT16:
  5245. case AR_BASIC_FLOAT32:
  5246. case AR_BASIC_FLOAT32_PARTIAL_PRECISION:
  5247. case AR_BASIC_FLOAT64:
  5248. return false;
  5249. default:
  5250. break; // No other valid cast types.
  5251. }
  5252. break;
  5253. case AR_BASIC_FLOAT16:
  5254. switch (rightKind) {
  5255. case AR_BASIC_LITERAL_FLOAT:
  5256. return false;
  5257. default:
  5258. break; // No other valid cast types.
  5259. }
  5260. break;
  5261. case AR_BASIC_FLOAT32_PARTIAL_PRECISION:
  5262. switch (rightKind) {
  5263. case AR_BASIC_LITERAL_FLOAT:
  5264. return false;
  5265. default:
  5266. break; // No other valid cast types.
  5267. }
  5268. break;
  5269. case AR_BASIC_FLOAT32:
  5270. switch (rightKind) {
  5271. case AR_BASIC_LITERAL_FLOAT:
  5272. return false;
  5273. default:
  5274. break; // No other valid cast types.
  5275. }
  5276. break;
  5277. case AR_BASIC_FLOAT64:
  5278. switch (rightKind) {
  5279. case AR_BASIC_LITERAL_FLOAT:
  5280. return false;
  5281. default:
  5282. break; // No other valid cast types.
  5283. }
  5284. break;
  5285. default:
  5286. break; // No other relevant targets.
  5287. }
  5288. return true;
  5289. }
  5290. bool HLSLExternalSource::IsIntCast(ArBasicKind leftKind, ArBasicKind rightKind) {
  5291. // Eliminate exact matches first, then check for casts.
  5292. if (leftKind == rightKind) {
  5293. return false;
  5294. }
  5295. //
  5296. // All minimum-bits types are only considered matches of themselves
  5297. // and thus are not in this table.
  5298. //
  5299. switch (leftKind) {
  5300. case AR_BASIC_LITERAL_INT:
  5301. switch (rightKind) {
  5302. case AR_BASIC_INT8:
  5303. case AR_BASIC_INT16:
  5304. case AR_BASIC_INT32:
  5305. case AR_BASIC_INT64:
  5306. case AR_BASIC_UINT8:
  5307. case AR_BASIC_UINT16:
  5308. case AR_BASIC_UINT32:
  5309. case AR_BASIC_UINT64:
  5310. return false;
  5311. default:
  5312. break; // No other valid conversions
  5313. }
  5314. break;
  5315. case AR_BASIC_INT8:
  5316. case AR_BASIC_INT16:
  5317. case AR_BASIC_INT32:
  5318. case AR_BASIC_INT64:
  5319. case AR_BASIC_UINT8:
  5320. case AR_BASIC_UINT16:
  5321. case AR_BASIC_UINT32:
  5322. case AR_BASIC_UINT64:
  5323. switch (rightKind) {
  5324. case AR_BASIC_LITERAL_INT:
  5325. return false;
  5326. default:
  5327. break; // No other valid conversions
  5328. }
  5329. break;
  5330. case AR_BASIC_LITERAL_FLOAT:
  5331. switch (rightKind) {
  5332. case AR_BASIC_LITERAL_FLOAT:
  5333. case AR_BASIC_FLOAT16:
  5334. case AR_BASIC_FLOAT32:
  5335. case AR_BASIC_FLOAT32_PARTIAL_PRECISION:
  5336. case AR_BASIC_FLOAT64:
  5337. return false;
  5338. default:
  5339. break; // No other valid conversions
  5340. }
  5341. break;
  5342. case AR_BASIC_FLOAT16:
  5343. case AR_BASIC_FLOAT32:
  5344. case AR_BASIC_FLOAT32_PARTIAL_PRECISION:
  5345. case AR_BASIC_FLOAT64:
  5346. switch (rightKind) {
  5347. case AR_BASIC_LITERAL_FLOAT:
  5348. return false;
  5349. default:
  5350. break; // No other valid conversions
  5351. }
  5352. break;
  5353. default:
  5354. // No other relevant targets
  5355. break;
  5356. }
  5357. return true;
  5358. }
  5359. UINT64 HLSLExternalSource::ScoreCast(QualType pLType, QualType pRType)
  5360. {
  5361. if (pLType.getCanonicalType() == pRType.getCanonicalType()) {
  5362. return 0;
  5363. }
  5364. UINT64 uScore = 0;
  5365. UINT uLSize = GetNumElements(pLType);
  5366. UINT uRSize = GetNumElements(pRType);
  5367. UINT uCompareSize;
  5368. bool bLCast = false;
  5369. bool bRCast = false;
  5370. bool bLIntCast = false;
  5371. bool bRIntCast = false;
  5372. bool bLPromo = false;
  5373. bool bRPromo = false;
  5374. uCompareSize = GetNumConvertCheckElts(pLType, uLSize, pRType, uRSize);
  5375. if (uCompareSize > uRSize) {
  5376. uCompareSize = uRSize;
  5377. }
  5378. for (UINT i = 0; i < uCompareSize; i++) {
  5379. ArBasicKind LeftElementKind, RightElementKind;
  5380. ArBasicKind CombinedKind = AR_BASIC_BOOL;
  5381. QualType leftSub = GetNthElementType(pLType, i);
  5382. QualType rightSub = GetNthElementType(pRType, i);
  5383. ArTypeObjectKind leftKind = GetTypeObjectKind(leftSub);
  5384. ArTypeObjectKind rightKind = GetTypeObjectKind(rightSub);
  5385. LeftElementKind = GetTypeElementKind(leftSub);
  5386. RightElementKind = GetTypeElementKind(rightSub);
  5387. // CollectInfo is called with AR_TINFO_ALLOW_OBJECTS, and the resulting
  5388. // information needed is the ShapeKind, EltKind and ObjKind.
  5389. if (!leftSub.isNull() && !rightSub.isNull() && leftKind != AR_TOBJ_INVALID && rightKind != AR_TOBJ_INVALID) {
  5390. bool bCombine;
  5391. if (leftKind == AR_TOBJ_OBJECT || rightKind == AR_TOBJ_OBJECT) {
  5392. DXASSERT(rightKind == AR_TOBJ_OBJECT, "otherwise prior check is incorrect");
  5393. ArBasicKind LeftObjKind = LeftElementKind; // actually LeftElementKind would have been the element
  5394. ArBasicKind RightObjKind = RightElementKind;
  5395. LeftElementKind = LeftObjKind;
  5396. RightElementKind = RightObjKind;
  5397. if (leftKind != rightKind) {
  5398. bCombine = false;
  5399. }
  5400. else if (!(bCombine = CombineObjectTypes(LeftObjKind, RightObjKind, &CombinedKind))) {
  5401. bCombine = CombineObjectTypes(RightObjKind, LeftObjKind, &CombinedKind);
  5402. }
  5403. }
  5404. else {
  5405. bCombine = CombineBasicTypes(LeftElementKind, RightElementKind, &CombinedKind);
  5406. }
  5407. if (bCombine && IsPromotion(LeftElementKind, CombinedKind)) {
  5408. bLPromo = true;
  5409. }
  5410. else if (!bCombine || IsCast(LeftElementKind, CombinedKind)) {
  5411. bLCast = true;
  5412. }
  5413. else if (IsIntCast(LeftElementKind, CombinedKind)) {
  5414. bLIntCast = true;
  5415. }
  5416. if (bCombine && IsPromotion(CombinedKind, RightElementKind)) {
  5417. bRPromo = true;
  5418. } else if (!bCombine || IsCast(CombinedKind, RightElementKind)) {
  5419. bRCast = true;
  5420. } else if (IsIntCast(CombinedKind, RightElementKind)) {
  5421. bRIntCast = true;
  5422. }
  5423. } else {
  5424. bLCast = true;
  5425. bRCast = true;
  5426. }
  5427. }
  5428. #define SCORE_COND(shift, cond) { \
  5429. if (cond) uScore += 1ULL << (SCORE_MIN_SHIFT + SCORE_PARAM_SHIFT * shift); }
  5430. SCORE_COND(0, uRSize < uLSize);
  5431. SCORE_COND(1, bLPromo);
  5432. SCORE_COND(2, bRPromo);
  5433. SCORE_COND(3, bLIntCast);
  5434. SCORE_COND(4, bRIntCast);
  5435. SCORE_COND(5, bLCast);
  5436. SCORE_COND(6, bRCast);
  5437. SCORE_COND(7, uLSize < uRSize);
  5438. #undef SCORE_COND
  5439. // Make sure our scores fit in a UINT64.
  5440. C_ASSERT(SCORE_MIN_SHIFT + SCORE_PARAM_SHIFT * 8 <= 64);
  5441. return uScore;
  5442. }
  5443. UINT64 HLSLExternalSource::ScoreImplicitConversionSequence(const ImplicitConversionSequence *ics) {
  5444. DXASSERT(ics, "otherwise conversion has not been initialized");
  5445. if (!ics->isInitialized()) {
  5446. return 0;
  5447. }
  5448. if (!ics->isStandard()) {
  5449. return SCORE_MAX;
  5450. }
  5451. QualType fromType = ics->Standard.getFromType();
  5452. QualType toType = ics->Standard.getToType(2); // final type
  5453. return ScoreCast(toType, fromType);
  5454. }
  5455. UINT64 HLSLExternalSource::ScoreFunction(OverloadCandidateSet::iterator &Cand) {
  5456. // Ignore target version mismatches.
  5457. // in/out considerations have been taken care of by viability.
  5458. // 'this' considerations don't matter without inheritance, other
  5459. // than lookup and viability.
  5460. UINT64 result = 0;
  5461. for (unsigned convIdx = 0; convIdx < Cand->NumConversions; ++convIdx) {
  5462. UINT64 score;
  5463. score = ScoreImplicitConversionSequence(Cand->Conversions + convIdx);
  5464. if (score == SCORE_MAX) {
  5465. return SCORE_MAX;
  5466. }
  5467. result += score;
  5468. score = ScoreImplicitConversionSequence(Cand->OutConversions + convIdx);
  5469. if (score == SCORE_MAX) {
  5470. return SCORE_MAX;
  5471. }
  5472. result += score;
  5473. }
  5474. return result;
  5475. }
  5476. OverloadingResult HLSLExternalSource::GetBestViableFunction(
  5477. SourceLocation Loc,
  5478. OverloadCandidateSet& set,
  5479. OverloadCandidateSet::iterator& Best)
  5480. {
  5481. UINT64 bestScore = SCORE_MAX;
  5482. unsigned scoreMatch = 0;
  5483. Best = set.end();
  5484. if (set.size() == 1 && set.begin()->Viable) {
  5485. Best = set.begin();
  5486. return OR_Success;
  5487. }
  5488. for (OverloadCandidateSet::iterator Cand = set.begin(); Cand != set.end(); ++Cand) {
  5489. if (Cand->Viable) {
  5490. UINT64 score = ScoreFunction(Cand);
  5491. if (score != SCORE_MAX) {
  5492. if (score == bestScore) {
  5493. ++scoreMatch;
  5494. } else if (score < bestScore) {
  5495. Best = Cand;
  5496. scoreMatch = 1;
  5497. bestScore = score;
  5498. }
  5499. }
  5500. }
  5501. }
  5502. if (Best == set.end()) {
  5503. return OR_No_Viable_Function;
  5504. }
  5505. if (scoreMatch > 1) {
  5506. Best = set.end();
  5507. return OR_Ambiguous;
  5508. }
  5509. // No need to check for deleted functions to yield OR_Deleted.
  5510. return OR_Success;
  5511. }
  5512. /// <summary>
  5513. /// Initializes the specified <paramref name="initSequence" /> describing how
  5514. /// <paramref name="Entity" /> is initialized with <paramref name="Args" />.
  5515. /// </summary>
  5516. /// <param name="Entity">Entity being initialized; a variable, return result, etc.</param>
  5517. /// <param name="Kind">Kind of initialization: copying, list-initializing, constructing, etc.</param>
  5518. /// <param name="Args">Arguments to the initialization.</param>
  5519. /// <param name="TopLevelOfInitList">Whether this is the top-level of an initialization list.</param>
  5520. /// <param name="initSequence">Initialization sequence description to initialize.</param>
  5521. void HLSLExternalSource::InitializeInitSequenceForHLSL(
  5522. const InitializedEntity& Entity,
  5523. const InitializationKind& Kind,
  5524. MultiExprArg Args,
  5525. bool TopLevelOfInitList,
  5526. _Inout_ InitializationSequence* initSequence)
  5527. {
  5528. DXASSERT_NOMSG(initSequence != nullptr);
  5529. // In HLSL there are no default initializers, eg float4x4 m();
  5530. if (Kind.getKind() == InitializationKind::IK_Default) {
  5531. return;
  5532. }
  5533. // Value initializers occur for temporaries with empty parens or braces.
  5534. if (Kind.getKind() == InitializationKind::IK_Value) {
  5535. m_sema->Diag(Kind.getLocation(), diag::err_hlsl_type_empty_init) << Entity.getType();
  5536. SilenceSequenceDiagnostics(initSequence);
  5537. return;
  5538. }
  5539. // If we have a DirectList, we should have a single InitListExprClass argument.
  5540. DXASSERT(
  5541. Kind.getKind() != InitializationKind::IK_DirectList ||
  5542. (Args.size() == 1 && Args.front()->getStmtClass() == Stmt::InitListExprClass),
  5543. "otherwise caller is passing in incorrect initialization configuration");
  5544. bool isCast = Kind.isCStyleCast();
  5545. QualType destType = Entity.getType();
  5546. ArTypeObjectKind destShape = GetTypeObjectKind(destType);
  5547. // Direct initialization occurs for explicit constructor arguments.
  5548. // E.g.: http://en.cppreference.com/w/cpp/language/direct_initialization
  5549. if (Kind.getKind() == InitializationKind::IK_Direct && destShape == AR_TOBJ_COMPOUND &&
  5550. !Kind.isCStyleOrFunctionalCast()) {
  5551. m_sema->Diag(Kind.getLocation(), diag::err_hlsl_require_numeric_base_for_ctor);
  5552. SilenceSequenceDiagnostics(initSequence);
  5553. return;
  5554. }
  5555. bool flatten =
  5556. (Kind.getKind() == InitializationKind::IK_Direct && !isCast) ||
  5557. Kind.getKind() == InitializationKind::IK_DirectList ||
  5558. (Args.size() == 1 && Args.front()->getStmtClass() == Stmt::InitListExprClass);
  5559. if (flatten) {
  5560. // TODO: InitializationSequence::Perform in SemaInit should take the arity of incomplete
  5561. // array types to adjust the value - we do calculate this as part of type analysis.
  5562. // Until this is done, s_arr_i_f arr_struct_none[] = { }; succeeds when it should instead fail.
  5563. FlattenedTypeIterator::ComparisonResult comparisonResult =
  5564. FlattenedTypeIterator::CompareTypesForInit(
  5565. *this, destType, Args,
  5566. Kind.getLocation(), Kind.getLocation());
  5567. if (comparisonResult.IsConvertibleAndEqualLength() ||
  5568. (isCast && comparisonResult.IsConvertibleAndLeftLonger()))
  5569. {
  5570. initSequence->AddListInitializationStep(destType);
  5571. }
  5572. else
  5573. {
  5574. SourceLocation diagLocation;
  5575. if (Args.size() > 0)
  5576. {
  5577. diagLocation = Args.front()->getLocStart();
  5578. }
  5579. else
  5580. {
  5581. diagLocation = Entity.getDiagLoc();
  5582. }
  5583. m_sema->Diag(diagLocation,
  5584. diag::err_vector_incorrect_num_initializers)
  5585. << (comparisonResult.RightCount < comparisonResult.LeftCount)
  5586. << comparisonResult.LeftCount << comparisonResult.RightCount;
  5587. SilenceSequenceDiagnostics(initSequence);
  5588. }
  5589. }
  5590. else {
  5591. DXASSERT(Args.size() == 1, "otherwise this was mis-parsed or should be a list initialization");
  5592. Expr* firstArg = Args.front();
  5593. if (IsExpressionBinaryComma(firstArg)) {
  5594. m_sema->Diag(firstArg->getExprLoc(), diag::warn_hlsl_comma_in_init);
  5595. }
  5596. ExprResult expr = ExprResult(firstArg);
  5597. Sema::CheckedConversionKind cck = Kind.isExplicitCast() ?
  5598. Sema::CheckedConversionKind::CCK_CStyleCast :
  5599. Sema::CheckedConversionKind::CCK_ImplicitConversion;
  5600. unsigned int msg = 0;
  5601. CastKind castKind;
  5602. CXXCastPath basePath;
  5603. SourceRange range = Kind.getRange();
  5604. ImplicitConversionSequence ics;
  5605. ics.setStandard();
  5606. bool castWorked = TryStaticCastForHLSL(
  5607. expr, destType, cck, range, msg, castKind, basePath, ListInitializationFalse, SuppressWarningsFalse, SuppressErrorsTrue, &ics.Standard);
  5608. if (castWorked) {
  5609. if (destType.getCanonicalType() ==
  5610. firstArg->getType().getCanonicalType() &&
  5611. (ics.Standard).First != ICK_Lvalue_To_Rvalue) {
  5612. initSequence->AddCAssignmentStep(destType);
  5613. } else {
  5614. initSequence->AddConversionSequenceStep(ics, destType.getNonReferenceType(), TopLevelOfInitList);
  5615. }
  5616. }
  5617. else {
  5618. initSequence->SetFailed(InitializationSequence::FK_ConversionFailed);
  5619. }
  5620. }
  5621. }
  5622. bool HLSLExternalSource::IsConversionToLessOrEqualElements(
  5623. const QualType& sourceType,
  5624. const QualType& targetType,
  5625. bool explicitConversion)
  5626. {
  5627. DXASSERT_NOMSG(!sourceType.isNull());
  5628. DXASSERT_NOMSG(!targetType.isNull());
  5629. ArTypeInfo sourceTypeInfo;
  5630. ArTypeInfo targetTypeInfo;
  5631. GetConversionForm(sourceType, explicitConversion, &sourceTypeInfo);
  5632. GetConversionForm(targetType, explicitConversion, &targetTypeInfo);
  5633. if (sourceTypeInfo.EltKind != targetTypeInfo.EltKind)
  5634. {
  5635. return false;
  5636. }
  5637. bool isVecMatTrunc = sourceTypeInfo.ShapeKind == AR_TOBJ_VECTOR &&
  5638. targetTypeInfo.ShapeKind == AR_TOBJ_BASIC;
  5639. if (sourceTypeInfo.ShapeKind != targetTypeInfo.ShapeKind &&
  5640. !isVecMatTrunc)
  5641. {
  5642. return false;
  5643. }
  5644. if (sourceTypeInfo.ShapeKind == AR_TOBJ_OBJECT &&
  5645. sourceTypeInfo.ObjKind == targetTypeInfo.ObjKind) {
  5646. return true;
  5647. }
  5648. // Same struct is eqaul.
  5649. if (sourceTypeInfo.ShapeKind == AR_TOBJ_COMPOUND &&
  5650. sourceType.getCanonicalType().getUnqualifiedType() ==
  5651. targetType.getCanonicalType().getUnqualifiedType()) {
  5652. return true;
  5653. }
  5654. // DerivedFrom is less.
  5655. if (sourceTypeInfo.ShapeKind == AR_TOBJ_COMPOUND ||
  5656. GetTypeObjectKind(sourceType) == AR_TOBJ_COMPOUND) {
  5657. const RecordType *targetRT = targetType->getAsStructureType();
  5658. if (!targetRT)
  5659. targetRT = dyn_cast<RecordType>(targetType);
  5660. const RecordType *sourceRT = sourceType->getAsStructureType();
  5661. if (!sourceRT)
  5662. sourceRT = dyn_cast<RecordType>(sourceType);
  5663. if (targetRT && sourceRT) {
  5664. RecordDecl *targetRD = targetRT->getDecl();
  5665. RecordDecl *sourceRD = sourceRT->getDecl();
  5666. const CXXRecordDecl *targetCXXRD = dyn_cast<CXXRecordDecl>(targetRD);
  5667. const CXXRecordDecl *sourceCXXRD = dyn_cast<CXXRecordDecl>(sourceRD);
  5668. if (targetCXXRD && sourceCXXRD) {
  5669. if (sourceCXXRD->isDerivedFrom(targetCXXRD))
  5670. return true;
  5671. }
  5672. }
  5673. }
  5674. if (sourceTypeInfo.ShapeKind != AR_TOBJ_SCALAR &&
  5675. sourceTypeInfo.ShapeKind != AR_TOBJ_VECTOR &&
  5676. sourceTypeInfo.ShapeKind != AR_TOBJ_MATRIX)
  5677. {
  5678. return false;
  5679. }
  5680. return targetTypeInfo.uTotalElts <= sourceTypeInfo.uTotalElts;
  5681. }
  5682. bool HLSLExternalSource::IsConversionToLessOrEqualElements(
  5683. const ExprResult& sourceExpr,
  5684. const QualType& targetType,
  5685. bool explicitConversion)
  5686. {
  5687. if (sourceExpr.isInvalid() || targetType.isNull())
  5688. {
  5689. return false;
  5690. }
  5691. return IsConversionToLessOrEqualElements(sourceExpr.get()->getType(), targetType, explicitConversion);
  5692. }
  5693. bool HLSLExternalSource::IsTypeNumeric(QualType type, UINT* count)
  5694. {
  5695. DXASSERT_NOMSG(!type.isNull());
  5696. DXASSERT_NOMSG(count != nullptr);
  5697. *count = 0;
  5698. UINT subCount = 0;
  5699. ArTypeObjectKind shapeKind = GetTypeObjectKind(type);
  5700. switch (shapeKind)
  5701. {
  5702. case AR_TOBJ_ARRAY:
  5703. if (IsTypeNumeric(m_context->getAsArrayType(type)->getElementType(), &subCount))
  5704. {
  5705. *count = subCount * GetArraySize(type);
  5706. return true;
  5707. }
  5708. return false;
  5709. case AR_TOBJ_COMPOUND:
  5710. {
  5711. UINT maxCount = 0;
  5712. { // Determine maximum count to prevent infinite loop on incomplete array
  5713. FlattenedTypeIterator itCount(SourceLocation(), type, *this);
  5714. maxCount = itCount.countRemaining();
  5715. if (!maxCount) {
  5716. return false; // empty struct.
  5717. }
  5718. }
  5719. FlattenedTypeIterator it(SourceLocation(), type, *this);
  5720. while (it.hasCurrentElement()) {
  5721. bool isFieldNumeric = IsTypeNumeric(it.getCurrentElement(), &subCount);
  5722. if (!isFieldNumeric) {
  5723. return false;
  5724. }
  5725. if (*count >= maxCount) {
  5726. // this element is an incomplete array at the end; iterator will not advance past this element.
  5727. // don't add to *count either, so *count will represent minimum size of the structure.
  5728. break;
  5729. }
  5730. *count += (subCount * it.getCurrentElementSize());
  5731. it.advanceCurrentElement(it.getCurrentElementSize());
  5732. }
  5733. return true;
  5734. }
  5735. default:
  5736. DXASSERT(false, "unreachable");
  5737. case AR_TOBJ_BASIC:
  5738. case AR_TOBJ_MATRIX:
  5739. case AR_TOBJ_VECTOR:
  5740. *count = GetElementCount(type);
  5741. return IsBasicKindNumeric(GetTypeElementKind(type));
  5742. case AR_TOBJ_OBJECT:
  5743. return false;
  5744. }
  5745. }
  5746. enum MatrixMemberAccessError {
  5747. MatrixMemberAccessError_None, // No errors found.
  5748. MatrixMemberAccessError_BadFormat, // Formatting error (non-digit).
  5749. MatrixMemberAccessError_MixingRefs, // Mix of zero-based and one-based references.
  5750. MatrixMemberAccessError_Empty, // No members specified.
  5751. MatrixMemberAccessError_ZeroInOneBased, // A zero was used in a one-based reference.
  5752. MatrixMemberAccessError_FourInZeroBased, // A four was used in a zero-based reference.
  5753. MatrixMemberAccessError_TooManyPositions, // Too many positions (more than four) were specified.
  5754. };
  5755. static
  5756. MatrixMemberAccessError TryConsumeMatrixDigit(const char*& memberText, uint32_t* value)
  5757. {
  5758. DXASSERT_NOMSG(memberText != nullptr);
  5759. DXASSERT_NOMSG(value != nullptr);
  5760. if ('0' <= *memberText && *memberText <= '9')
  5761. {
  5762. *value = (*memberText) - '0';
  5763. }
  5764. else
  5765. {
  5766. return MatrixMemberAccessError_BadFormat;
  5767. }
  5768. memberText++;
  5769. return MatrixMemberAccessError_None;
  5770. }
  5771. static
  5772. MatrixMemberAccessError TryParseMatrixMemberAccess(_In_z_ const char* memberText, _Out_ MatrixMemberAccessPositions* value)
  5773. {
  5774. DXASSERT_NOMSG(memberText != nullptr);
  5775. DXASSERT_NOMSG(value != nullptr);
  5776. MatrixMemberAccessPositions result;
  5777. bool zeroBasedDecided = false;
  5778. bool zeroBased = false;
  5779. // Set the output value to invalid to allow early exits when errors are found.
  5780. value->IsValid = 0;
  5781. // Assume this is true until proven otherwise.
  5782. result.IsValid = 1;
  5783. result.Count = 0;
  5784. while (*memberText)
  5785. {
  5786. // Check for a leading underscore.
  5787. if (*memberText != '_')
  5788. {
  5789. return MatrixMemberAccessError_BadFormat;
  5790. }
  5791. ++memberText;
  5792. // Check whether we have an 'm' or a digit.
  5793. if (*memberText == 'm')
  5794. {
  5795. if (zeroBasedDecided && !zeroBased)
  5796. {
  5797. return MatrixMemberAccessError_MixingRefs;
  5798. }
  5799. zeroBased = true;
  5800. zeroBasedDecided = true;
  5801. ++memberText;
  5802. }
  5803. else if (!('0' <= *memberText && *memberText <= '9'))
  5804. {
  5805. return MatrixMemberAccessError_BadFormat;
  5806. }
  5807. else
  5808. {
  5809. if (zeroBasedDecided && zeroBased)
  5810. {
  5811. return MatrixMemberAccessError_MixingRefs;
  5812. }
  5813. zeroBased = false;
  5814. zeroBasedDecided = true;
  5815. }
  5816. // Consume two digits for the position.
  5817. uint32_t rowPosition;
  5818. uint32_t colPosition;
  5819. MatrixMemberAccessError digitError;
  5820. if (MatrixMemberAccessError_None != (digitError = TryConsumeMatrixDigit(memberText, &rowPosition)))
  5821. {
  5822. return digitError;
  5823. }
  5824. if (MatrixMemberAccessError_None != (digitError = TryConsumeMatrixDigit(memberText, &colPosition)))
  5825. {
  5826. return digitError;
  5827. }
  5828. // Look for specific common errors (developer likely mixed up reference style).
  5829. if (zeroBased)
  5830. {
  5831. if (rowPosition == 4 || colPosition == 4)
  5832. {
  5833. return MatrixMemberAccessError_FourInZeroBased;
  5834. }
  5835. }
  5836. else
  5837. {
  5838. if (rowPosition == 0 || colPosition == 0)
  5839. {
  5840. return MatrixMemberAccessError_ZeroInOneBased;
  5841. }
  5842. // SetPosition will use zero-based indices.
  5843. --rowPosition;
  5844. --colPosition;
  5845. }
  5846. if (result.Count == 4)
  5847. {
  5848. return MatrixMemberAccessError_TooManyPositions;
  5849. }
  5850. result.SetPosition(result.Count, rowPosition, colPosition);
  5851. result.Count++;
  5852. }
  5853. if (result.Count == 0)
  5854. {
  5855. return MatrixMemberAccessError_Empty;
  5856. }
  5857. *value = result;
  5858. return MatrixMemberAccessError_None;
  5859. }
  5860. bool HLSLExternalSource::LookupMatrixMemberExprForHLSL(
  5861. Expr& BaseExpr,
  5862. DeclarationName MemberName,
  5863. bool IsArrow,
  5864. SourceLocation OpLoc,
  5865. SourceLocation MemberLoc,
  5866. ExprResult* result)
  5867. {
  5868. DXASSERT_NOMSG(result != nullptr);
  5869. QualType BaseType = BaseExpr.getType();
  5870. DXASSERT(!BaseType.isNull(), "otherwise caller should have stopped analysis much earlier");
  5871. // Assume failure.
  5872. *result = ExprError();
  5873. if (GetTypeObjectKind(BaseType) != AR_TOBJ_MATRIX)
  5874. {
  5875. return false;
  5876. }
  5877. QualType elementType;
  5878. UINT rowCount, colCount;
  5879. GetRowsAndCols(BaseType, rowCount, colCount);
  5880. elementType = GetMatrixOrVectorElementType(BaseType);
  5881. IdentifierInfo *member = MemberName.getAsIdentifierInfo();
  5882. const char *memberText = member->getNameStart();
  5883. MatrixMemberAccessPositions positions;
  5884. MatrixMemberAccessError memberAccessError;
  5885. unsigned msg = 0;
  5886. memberAccessError = TryParseMatrixMemberAccess(memberText, &positions);
  5887. switch (memberAccessError)
  5888. {
  5889. case MatrixMemberAccessError_BadFormat:
  5890. msg = diag::err_hlsl_matrix_member_bad_format;
  5891. break;
  5892. case MatrixMemberAccessError_Empty:
  5893. msg = diag::err_hlsl_matrix_member_empty;
  5894. break;
  5895. case MatrixMemberAccessError_FourInZeroBased:
  5896. msg = diag::err_hlsl_matrix_member_four_in_zero_based;
  5897. break;
  5898. case MatrixMemberAccessError_MixingRefs:
  5899. msg = diag::err_hlsl_matrix_member_mixing_refs;
  5900. break;
  5901. case MatrixMemberAccessError_None:
  5902. msg = 0;
  5903. DXASSERT(positions.IsValid, "otherwise an error should have been returned");
  5904. // Check the position with the type now.
  5905. for (unsigned int i = 0; i < positions.Count; i++)
  5906. {
  5907. uint32_t rowPos, colPos;
  5908. positions.GetPosition(i, &rowPos, &colPos);
  5909. if (rowPos >= rowCount || colPos >= colCount)
  5910. {
  5911. msg = diag::err_hlsl_matrix_member_out_of_bounds;
  5912. break;
  5913. }
  5914. }
  5915. break;
  5916. case MatrixMemberAccessError_TooManyPositions:
  5917. msg = diag::err_hlsl_matrix_member_too_many_positions;
  5918. break;
  5919. case MatrixMemberAccessError_ZeroInOneBased:
  5920. msg = diag::err_hlsl_matrix_member_zero_in_one_based;
  5921. break;
  5922. default:
  5923. llvm_unreachable("Unknown MatrixMemberAccessError value");
  5924. }
  5925. if (msg != 0)
  5926. {
  5927. m_sema->Diag(MemberLoc, msg) << memberText;
  5928. // It's possible that it's a simple out-of-bounds condition. In this case,
  5929. // generate the member access expression with the correct arity and continue
  5930. // processing.
  5931. if (!positions.IsValid)
  5932. {
  5933. return true;
  5934. }
  5935. }
  5936. DXASSERT(positions.IsValid, "otherwise an error should have been returned");
  5937. // Consume elements
  5938. QualType resultType;
  5939. if (positions.Count == 1)
  5940. resultType = elementType;
  5941. else
  5942. resultType = NewSimpleAggregateType(AR_TOBJ_UNKNOWN, GetTypeElementKind(elementType), 0, OneRow, positions.Count);
  5943. // Add qualifiers from BaseType.
  5944. resultType = m_context->getQualifiedType(resultType, BaseType.getQualifiers());
  5945. ExprValueKind VK =
  5946. positions.ContainsDuplicateElements() ? VK_RValue :
  5947. (IsArrow ? VK_LValue : BaseExpr.getValueKind());
  5948. ExtMatrixElementExpr* matrixExpr = new (m_context)ExtMatrixElementExpr(resultType, VK, &BaseExpr, *member, MemberLoc, positions);
  5949. *result = matrixExpr;
  5950. return true;
  5951. }
  5952. enum VectorMemberAccessError {
  5953. VectorMemberAccessError_None, // No errors found.
  5954. VectorMemberAccessError_BadFormat, // Formatting error (not in 'rgba' or 'xyzw').
  5955. VectorMemberAccessError_MixingStyles, // Mix of rgba and xyzw swizzle styles.
  5956. VectorMemberAccessError_Empty, // No members specified.
  5957. VectorMemberAccessError_TooManyPositions, // Too many positions (more than four) were specified.
  5958. };
  5959. static
  5960. VectorMemberAccessError TryConsumeVectorDigit(const char*& memberText, uint32_t* value, bool &rgbaStyle) {
  5961. DXASSERT_NOMSG(memberText != nullptr);
  5962. DXASSERT_NOMSG(value != nullptr);
  5963. rgbaStyle = false;
  5964. switch (*memberText) {
  5965. case 'r':
  5966. rgbaStyle = true;
  5967. case 'x':
  5968. *value = 0;
  5969. break;
  5970. case 'g':
  5971. rgbaStyle = true;
  5972. case 'y':
  5973. *value = 1;
  5974. break;
  5975. case 'b':
  5976. rgbaStyle = true;
  5977. case 'z':
  5978. *value = 2;
  5979. break;
  5980. case 'a':
  5981. rgbaStyle = true;
  5982. case 'w':
  5983. *value = 3;
  5984. break;
  5985. default:
  5986. return VectorMemberAccessError_BadFormat;
  5987. }
  5988. memberText++;
  5989. return VectorMemberAccessError_None;
  5990. }
  5991. static
  5992. VectorMemberAccessError TryParseVectorMemberAccess(_In_z_ const char* memberText, _Out_ VectorMemberAccessPositions* value) {
  5993. DXASSERT_NOMSG(memberText != nullptr);
  5994. DXASSERT_NOMSG(value != nullptr);
  5995. VectorMemberAccessPositions result;
  5996. bool rgbaStyleDecided = false;
  5997. bool rgbaStyle = false;
  5998. // Set the output value to invalid to allow early exits when errors are found.
  5999. value->IsValid = 0;
  6000. // Assume this is true until proven otherwise.
  6001. result.IsValid = 1;
  6002. result.Count = 0;
  6003. while (*memberText) {
  6004. // Consume one character for the swizzle.
  6005. uint32_t colPosition;
  6006. VectorMemberAccessError digitError;
  6007. bool rgbaStyleTmp = false;
  6008. if (VectorMemberAccessError_None != (digitError = TryConsumeVectorDigit(memberText, &colPosition, rgbaStyleTmp))) {
  6009. return digitError;
  6010. }
  6011. if (rgbaStyleDecided && rgbaStyleTmp != rgbaStyle) {
  6012. return VectorMemberAccessError_MixingStyles;
  6013. }
  6014. else {
  6015. rgbaStyleDecided = true;
  6016. rgbaStyle = rgbaStyleTmp;
  6017. }
  6018. if (result.Count == 4) {
  6019. return VectorMemberAccessError_TooManyPositions;
  6020. }
  6021. result.SetPosition(result.Count, colPosition);
  6022. result.Count++;
  6023. }
  6024. if (result.Count == 0) {
  6025. return VectorMemberAccessError_Empty;
  6026. }
  6027. *value = result;
  6028. return VectorMemberAccessError_None;
  6029. }
  6030. bool HLSLExternalSource::LookupVectorMemberExprForHLSL(
  6031. Expr& BaseExpr,
  6032. DeclarationName MemberName,
  6033. bool IsArrow,
  6034. SourceLocation OpLoc,
  6035. SourceLocation MemberLoc,
  6036. ExprResult* result) {
  6037. DXASSERT_NOMSG(result != nullptr);
  6038. QualType BaseType = BaseExpr.getType();
  6039. DXASSERT(!BaseType.isNull(), "otherwise caller should have stopped analysis much earlier");
  6040. // Assume failure.
  6041. *result = ExprError();
  6042. if (GetTypeObjectKind(BaseType) != AR_TOBJ_VECTOR) {
  6043. return false;
  6044. }
  6045. QualType elementType;
  6046. UINT colCount = GetHLSLVecSize(BaseType);
  6047. elementType = GetMatrixOrVectorElementType(BaseType);
  6048. IdentifierInfo *member = MemberName.getAsIdentifierInfo();
  6049. const char *memberText = member->getNameStart();
  6050. VectorMemberAccessPositions positions;
  6051. VectorMemberAccessError memberAccessError;
  6052. unsigned msg = 0;
  6053. memberAccessError = TryParseVectorMemberAccess(memberText, &positions);
  6054. switch (memberAccessError) {
  6055. case VectorMemberAccessError_BadFormat:
  6056. msg = diag::err_hlsl_vector_member_bad_format;
  6057. break;
  6058. case VectorMemberAccessError_Empty:
  6059. msg = diag::err_hlsl_vector_member_empty;
  6060. break;
  6061. case VectorMemberAccessError_MixingStyles:
  6062. msg = diag::err_ext_vector_component_name_mixedsets;
  6063. break;
  6064. case VectorMemberAccessError_None:
  6065. msg = 0;
  6066. DXASSERT(positions.IsValid, "otherwise an error should have been returned");
  6067. // Check the position with the type now.
  6068. for (unsigned int i = 0; i < positions.Count; i++) {
  6069. uint32_t colPos;
  6070. positions.GetPosition(i, &colPos);
  6071. if (colPos >= colCount) {
  6072. msg = diag::err_hlsl_vector_member_out_of_bounds;
  6073. break;
  6074. }
  6075. }
  6076. break;
  6077. case VectorMemberAccessError_TooManyPositions:
  6078. msg = diag::err_hlsl_vector_member_too_many_positions;
  6079. break;
  6080. default:
  6081. llvm_unreachable("Unknown VectorMemberAccessError value");
  6082. }
  6083. if (msg != 0) {
  6084. m_sema->Diag(MemberLoc, msg) << memberText;
  6085. // It's possible that it's a simple out-of-bounds condition. In this case,
  6086. // generate the member access expression with the correct arity and continue
  6087. // processing.
  6088. if (!positions.IsValid) {
  6089. return true;
  6090. }
  6091. }
  6092. DXASSERT(positions.IsValid, "otherwise an error should have been returned");
  6093. // Consume elements
  6094. QualType resultType;
  6095. if (positions.Count == 1)
  6096. resultType = elementType;
  6097. else
  6098. resultType = NewSimpleAggregateType(AR_TOBJ_UNKNOWN, GetTypeElementKind(elementType), 0, OneRow, positions.Count);
  6099. // Add qualifiers from BaseType.
  6100. resultType = m_context->getQualifiedType(resultType, BaseType.getQualifiers());
  6101. ExprValueKind VK =
  6102. positions.ContainsDuplicateElements() ? VK_RValue :
  6103. (IsArrow ? VK_LValue : BaseExpr.getValueKind());
  6104. HLSLVectorElementExpr* vectorExpr = new (m_context)HLSLVectorElementExpr(resultType, VK, &BaseExpr, *member, MemberLoc, positions);
  6105. *result = vectorExpr;
  6106. return true;
  6107. }
  6108. ExprResult HLSLExternalSource::MaybeConvertScalarToVector(_In_ clang::Expr* E) {
  6109. DXASSERT_NOMSG(E != nullptr);
  6110. ArBasicKind basic = GetTypeElementKind(E->getType());
  6111. if (!IS_BASIC_PRIMITIVE(basic)) {
  6112. return E;
  6113. }
  6114. ArTypeObjectKind kind = GetTypeObjectKind(E->getType());
  6115. if (kind != AR_TOBJ_SCALAR) {
  6116. return E;
  6117. }
  6118. QualType targetType = NewSimpleAggregateType(AR_TOBJ_VECTOR, basic, 0, 1, 1);
  6119. return ImplicitCastExpr::Create(*m_context, targetType, CastKind::CK_HLSLVectorSplat, E, nullptr, E->getValueKind());
  6120. }
  6121. static clang::CastKind ImplicitConversionKindToCastKind(
  6122. clang::ImplicitConversionKind ICK,
  6123. ArBasicKind FromKind,
  6124. ArBasicKind ToKind) {
  6125. // TODO: Shouldn't we have more specific ICK enums so we don't have to re-evaluate
  6126. // based on from/to kinds in order to determine CastKind?
  6127. // There's a FIXME note in PerformImplicitConversion that calls out exactly this
  6128. // problem.
  6129. switch (ICK) {
  6130. case ICK_Integral_Promotion:
  6131. case ICK_Integral_Conversion:
  6132. return CK_IntegralCast;
  6133. case ICK_Floating_Promotion:
  6134. case ICK_Floating_Conversion:
  6135. return CK_FloatingCast;
  6136. case ICK_Floating_Integral:
  6137. if (IS_BASIC_FLOAT(FromKind) && IS_BASIC_AINT(ToKind))
  6138. return CK_FloatingToIntegral;
  6139. else if ((IS_BASIC_AINT(FromKind) || IS_BASIC_BOOL(FromKind)) && IS_BASIC_FLOAT(ToKind))
  6140. return CK_IntegralToFloating;
  6141. break;
  6142. case ICK_Boolean_Conversion:
  6143. if (IS_BASIC_FLOAT(FromKind) && IS_BASIC_BOOL(ToKind))
  6144. return CK_FloatingToBoolean;
  6145. else if (IS_BASIC_AINT(FromKind) && IS_BASIC_BOOL(ToKind))
  6146. return CK_IntegralToBoolean;
  6147. break;
  6148. default:
  6149. // Only covers implicit conversions with cast kind equivalents.
  6150. return CK_Invalid;
  6151. }
  6152. return CK_Invalid;
  6153. }
  6154. static clang::CastKind ConvertToComponentCastKind(clang::CastKind CK) {
  6155. switch (CK) {
  6156. case CK_IntegralCast:
  6157. return CK_HLSLCC_IntegralCast;
  6158. case CK_FloatingCast:
  6159. return CK_HLSLCC_FloatingCast;
  6160. case CK_FloatingToIntegral:
  6161. return CK_HLSLCC_FloatingToIntegral;
  6162. case CK_IntegralToFloating:
  6163. return CK_HLSLCC_IntegralToFloating;
  6164. case CK_FloatingToBoolean:
  6165. return CK_HLSLCC_FloatingToBoolean;
  6166. case CK_IntegralToBoolean:
  6167. return CK_HLSLCC_IntegralToBoolean;
  6168. default:
  6169. // Only HLSLCC castkinds are relevant. Ignore the rest.
  6170. return CK_Invalid;
  6171. }
  6172. return CK_Invalid;
  6173. }
  6174. clang::Expr *HLSLExternalSource::HLSLImpCastToScalar(
  6175. _In_ clang::Sema* self,
  6176. _In_ clang::Expr* From,
  6177. ArTypeObjectKind FromShape,
  6178. ArBasicKind EltKind)
  6179. {
  6180. clang::CastKind CK = CK_Invalid;
  6181. if (AR_TOBJ_MATRIX == FromShape)
  6182. CK = CK_HLSLMatrixToScalarCast;
  6183. if (AR_TOBJ_VECTOR == FromShape)
  6184. CK = CK_HLSLVectorToScalarCast;
  6185. if (CK_Invalid != CK) {
  6186. return self->ImpCastExprToType(From,
  6187. NewSimpleAggregateType(AR_TOBJ_BASIC, EltKind, 0, 1, 1), CK, From->getValueKind()).get();
  6188. }
  6189. return From;
  6190. }
  6191. clang::ExprResult HLSLExternalSource::PerformHLSLConversion(
  6192. _In_ clang::Expr* From,
  6193. _In_ clang::QualType targetType,
  6194. _In_ const clang::StandardConversionSequence &SCS,
  6195. _In_ clang::Sema::CheckedConversionKind CCK)
  6196. {
  6197. QualType sourceType = From->getType();
  6198. sourceType = GetStructuralForm(sourceType);
  6199. targetType = GetStructuralForm(targetType);
  6200. ArTypeInfo SourceInfo, TargetInfo;
  6201. CollectInfo(sourceType, &SourceInfo);
  6202. CollectInfo(targetType, &TargetInfo);
  6203. clang::CastKind CK = CK_Invalid;
  6204. QualType intermediateTarget;
  6205. // TODO: construct vector/matrix and component cast expressions
  6206. switch (SCS.Second) {
  6207. case ICK_Flat_Conversion: {
  6208. // TODO: determine how to handle individual component conversions:
  6209. // - have an array of conversions for ComponentConversion in SCS?
  6210. // convert that to an array of casts under a special kind of flat
  6211. // flat conversion node? What do component conversion casts cast
  6212. // from? We don't have a From expression for individiual components.
  6213. From = m_sema->ImpCastExprToType(From, targetType.getUnqualifiedType(), CK_FlatConversion, From->getValueKind(), /*BasePath=*/0, CCK).get();
  6214. break;
  6215. }
  6216. case ICK_HLSL_Derived_To_Base: {
  6217. CXXCastPath BasePath;
  6218. if (m_sema->CheckDerivedToBaseConversion(
  6219. sourceType, targetType.getNonReferenceType(), From->getLocStart(),
  6220. From->getSourceRange(), &BasePath, /*IgnoreAccess=*/true))
  6221. return ExprError();
  6222. From = m_sema->ImpCastExprToType(From, targetType.getUnqualifiedType(), CK_HLSLDerivedToBase, From->getValueKind(), &BasePath, CCK).get();
  6223. break;
  6224. }
  6225. case ICK_HLSLVector_Splat: {
  6226. // 1. optionally convert from vec1 or mat1x1 to scalar
  6227. From = HLSLImpCastToScalar(m_sema, From, SourceInfo.ShapeKind, SourceInfo.EltKind);
  6228. // 2. optionally convert component type
  6229. if (ICK_Identity != SCS.ComponentConversion) {
  6230. CK = ImplicitConversionKindToCastKind(SCS.ComponentConversion, SourceInfo.EltKind, TargetInfo.EltKind);
  6231. if (CK_Invalid != CK) {
  6232. From = m_sema->ImpCastExprToType(From,
  6233. NewSimpleAggregateType(AR_TOBJ_BASIC, TargetInfo.EltKind, 0, 1, 1), CK, From->getValueKind(), /*BasePath=*/0, CCK).get();
  6234. }
  6235. }
  6236. // 3. splat scalar to final vector or matrix
  6237. CK = CK_Invalid;
  6238. if (AR_TOBJ_VECTOR == TargetInfo.ShapeKind)
  6239. CK = CK_HLSLVectorSplat;
  6240. else if (AR_TOBJ_MATRIX == TargetInfo.ShapeKind)
  6241. CK = CK_HLSLMatrixSplat;
  6242. if (CK_Invalid != CK) {
  6243. From = m_sema->ImpCastExprToType(From,
  6244. NewSimpleAggregateType(TargetInfo.ShapeKind, TargetInfo.EltKind, 0, TargetInfo.uRows, TargetInfo.uCols), CK, From->getValueKind(), /*BasePath=*/0, CCK).get();
  6245. }
  6246. break;
  6247. }
  6248. case ICK_HLSLVector_Scalar: {
  6249. // 1. select vector or matrix component
  6250. From = HLSLImpCastToScalar(m_sema, From, SourceInfo.ShapeKind, SourceInfo.EltKind);
  6251. // 2. optionally convert component type
  6252. if (ICK_Identity != SCS.ComponentConversion) {
  6253. CK = ImplicitConversionKindToCastKind(SCS.ComponentConversion, SourceInfo.EltKind, TargetInfo.EltKind);
  6254. if (CK_Invalid != CK) {
  6255. From = m_sema->ImpCastExprToType(From,
  6256. NewSimpleAggregateType(AR_TOBJ_BASIC, TargetInfo.EltKind, 0, 1, 1), CK, From->getValueKind(), /*BasePath=*/0, CCK).get();
  6257. }
  6258. }
  6259. break;
  6260. }
  6261. // The following two (three if we re-introduce ICK_HLSLComponent_Conversion) steps
  6262. // can be done with case fall-through, since this is the order in which we want to
  6263. // do the conversion operations.
  6264. case ICK_HLSLVector_Truncation: {
  6265. // 1. dimension truncation
  6266. // vector truncation or matrix truncation?
  6267. if (SourceInfo.ShapeKind == AR_TOBJ_VECTOR) {
  6268. From = m_sema->ImpCastExprToType(From,
  6269. NewSimpleAggregateType(AR_TOBJ_VECTOR, SourceInfo.EltKind, 0, 1, TargetInfo.uTotalElts),
  6270. CK_HLSLVectorTruncationCast, From->getValueKind(), /*BasePath=*/0, CCK).get();
  6271. } else if (SourceInfo.ShapeKind == AR_TOBJ_MATRIX) {
  6272. if (TargetInfo.ShapeKind == AR_TOBJ_VECTOR && 1 == SourceInfo.uCols) {
  6273. // Handle the column to vector case
  6274. From = m_sema->ImpCastExprToType(From,
  6275. NewSimpleAggregateType(AR_TOBJ_MATRIX, SourceInfo.EltKind, 0, TargetInfo.uCols, 1),
  6276. CK_HLSLMatrixTruncationCast, From->getValueKind(), /*BasePath=*/0, CCK).get();
  6277. } else {
  6278. From = m_sema->ImpCastExprToType(From,
  6279. NewSimpleAggregateType(AR_TOBJ_MATRIX, SourceInfo.EltKind, 0, TargetInfo.uRows, TargetInfo.uCols),
  6280. CK_HLSLMatrixTruncationCast, From->getValueKind(), /*BasePath=*/0, CCK).get();
  6281. }
  6282. } else {
  6283. DXASSERT(false, "PerformHLSLConversion: Invalid source type for truncation cast");
  6284. }
  6285. }
  6286. __fallthrough;
  6287. case ICK_HLSLVector_Conversion: {
  6288. // 2. Do ShapeKind conversion if necessary
  6289. if (SourceInfo.ShapeKind != TargetInfo.ShapeKind) {
  6290. switch (TargetInfo.ShapeKind) {
  6291. case AR_TOBJ_VECTOR:
  6292. DXASSERT(AR_TOBJ_MATRIX == SourceInfo.ShapeKind, "otherwise, invalid casting sequence");
  6293. From = m_sema->ImpCastExprToType(From,
  6294. NewSimpleAggregateType(AR_TOBJ_VECTOR, SourceInfo.EltKind, 0, TargetInfo.uRows, TargetInfo.uCols),
  6295. CK_HLSLMatrixToVectorCast, From->getValueKind(), /*BasePath=*/0, CCK).get();
  6296. break;
  6297. case AR_TOBJ_MATRIX:
  6298. DXASSERT(AR_TOBJ_VECTOR == SourceInfo.ShapeKind, "otherwise, invalid casting sequence");
  6299. From = m_sema->ImpCastExprToType(From,
  6300. NewSimpleAggregateType(AR_TOBJ_MATRIX, SourceInfo.EltKind, 0, TargetInfo.uRows, TargetInfo.uCols),
  6301. CK_HLSLVectorToMatrixCast, From->getValueKind(), /*BasePath=*/0, CCK).get();
  6302. break;
  6303. case AR_TOBJ_BASIC:
  6304. // Truncation may be followed by cast to scalar
  6305. From = HLSLImpCastToScalar(m_sema, From, SourceInfo.ShapeKind, SourceInfo.EltKind);
  6306. break;
  6307. default:
  6308. DXASSERT(false, "otherwise, invalid casting sequence");
  6309. break;
  6310. }
  6311. }
  6312. // 3. Do component type conversion
  6313. if (ICK_Identity != SCS.ComponentConversion) {
  6314. CK = ImplicitConversionKindToCastKind(SCS.ComponentConversion, SourceInfo.EltKind, TargetInfo.EltKind);
  6315. if (TargetInfo.ShapeKind != AR_TOBJ_BASIC)
  6316. CK = ConvertToComponentCastKind(CK);
  6317. if (CK_Invalid != CK) {
  6318. From = m_sema->ImpCastExprToType(From, targetType, CK, From->getValueKind(), /*BasePath=*/0, CCK).get();
  6319. }
  6320. }
  6321. break;
  6322. }
  6323. case ICK_Identity:
  6324. // Nothing to do.
  6325. break;
  6326. default:
  6327. DXASSERT(false, "PerformHLSLConversion: Invalid SCS.Second conversion kind");
  6328. }
  6329. return From;
  6330. }
  6331. void HLSLExternalSource::GetConversionForm(
  6332. QualType type,
  6333. bool explicitConversion,
  6334. ArTypeInfo* pTypeInfo)
  6335. {
  6336. //if (!CollectInfo(AR_TINFO_ALLOW_ALL, pTypeInfo))
  6337. CollectInfo(type, pTypeInfo);
  6338. // The fxc implementation reported pTypeInfo->ShapeKind separately in an output argument,
  6339. // but that value is only used for pointer conversions.
  6340. // When explicitly converting types complex aggregates can be treated
  6341. // as vectors if they are entirely numeric.
  6342. switch (pTypeInfo->ShapeKind)
  6343. {
  6344. case AR_TOBJ_COMPOUND:
  6345. case AR_TOBJ_ARRAY:
  6346. if (explicitConversion && IsTypeNumeric(type, &pTypeInfo->uTotalElts))
  6347. {
  6348. pTypeInfo->ShapeKind = AR_TOBJ_VECTOR;
  6349. }
  6350. else
  6351. {
  6352. pTypeInfo->ShapeKind = AR_TOBJ_COMPOUND;
  6353. }
  6354. DXASSERT_NOMSG(pTypeInfo->uRows == 1);
  6355. pTypeInfo->uCols = pTypeInfo->uTotalElts;
  6356. break;
  6357. case AR_TOBJ_VECTOR:
  6358. case AR_TOBJ_MATRIX:
  6359. // Convert 1x1 types to scalars.
  6360. if (pTypeInfo->uCols == 1 && pTypeInfo->uRows == 1)
  6361. {
  6362. pTypeInfo->ShapeKind = AR_TOBJ_BASIC;
  6363. }
  6364. break;
  6365. default:
  6366. // Only convertable shapekinds are relevant.
  6367. break;
  6368. }
  6369. }
  6370. static
  6371. bool HandleVoidConversion(QualType source, QualType target, bool explicitConversion, _Out_ bool* allowed)
  6372. {
  6373. DXASSERT_NOMSG(allowed != nullptr);
  6374. bool applicable = true;
  6375. *allowed = true;
  6376. if (explicitConversion) {
  6377. // (void) non-void
  6378. if (target->isVoidType()) {
  6379. DXASSERT_NOMSG(*allowed);
  6380. }
  6381. // (non-void) void
  6382. else if (source->isVoidType()) {
  6383. *allowed = false;
  6384. }
  6385. else {
  6386. applicable = false;
  6387. }
  6388. }
  6389. else {
  6390. // (void) void
  6391. if (source->isVoidType() && target->isVoidType()) {
  6392. DXASSERT_NOMSG(*allowed);
  6393. }
  6394. // (void) non-void, (non-void) void
  6395. else if (source->isVoidType() || target->isVoidType()) {
  6396. *allowed = false;
  6397. }
  6398. else {
  6399. applicable = false;
  6400. }
  6401. }
  6402. return applicable;
  6403. }
  6404. _Use_decl_annotations_
  6405. bool HLSLExternalSource::CanConvert(
  6406. SourceLocation loc,
  6407. Expr* sourceExpr,
  6408. QualType target,
  6409. bool explicitConversion,
  6410. _Out_opt_ TYPE_CONVERSION_REMARKS* remarks,
  6411. _Inout_opt_ StandardConversionSequence* standard)
  6412. {
  6413. bool bCheckElt = false;
  6414. UINT uTSize, uSSize;
  6415. DXASSERT_NOMSG(sourceExpr != nullptr);
  6416. DXASSERT_NOMSG(!target.isNull());
  6417. // Implements the semantics of ArType::CanConvertTo.
  6418. TYPE_CONVERSION_FLAGS Flags = explicitConversion ? TYPE_CONVERSION_EXPLICIT : TYPE_CONVERSION_DEFAULT;
  6419. TYPE_CONVERSION_REMARKS Remarks = TYPE_CONVERSION_NONE;
  6420. QualType source = sourceExpr->getType();
  6421. // Cannot cast function type.
  6422. if (source->isFunctionType())
  6423. return false;
  6424. // Convert to an r-value to begin with.
  6425. bool needsLValueToRValue = sourceExpr->isLValue() &&
  6426. !target->isLValueReferenceType() &&
  6427. IsConversionToLessOrEqualElements(source, target, explicitConversion);
  6428. bool targetRef = target->isReferenceType();
  6429. // Initialize the output standard sequence if available.
  6430. if (standard != nullptr) {
  6431. // Set up a no-op conversion, other than lvalue to rvalue - HLSL does not support references.
  6432. standard->setAsIdentityConversion();
  6433. if (needsLValueToRValue) {
  6434. standard->First = ICK_Lvalue_To_Rvalue;
  6435. }
  6436. standard->setFromType(source);
  6437. standard->setAllToTypes(target);
  6438. }
  6439. source = GetStructuralForm(source);
  6440. target = GetStructuralForm(target);
  6441. // Temporary conversion kind tracking which will be used/fixed up at the end
  6442. ImplicitConversionKind Second = ICK_Identity;
  6443. ImplicitConversionKind ComponentConversion = ICK_Identity;
  6444. // Identical types require no conversion.
  6445. if (source == target) {
  6446. Remarks = TYPE_CONVERSION_IDENTICAL;
  6447. goto lSuccess;
  6448. }
  6449. // Trivial cases for void.
  6450. bool allowed;
  6451. if (HandleVoidConversion(source, target, explicitConversion, &allowed)) {
  6452. if (allowed) {
  6453. Remarks = target->isVoidType() ? TYPE_CONVERSION_TO_VOID : Remarks;
  6454. goto lSuccess;
  6455. }
  6456. else {
  6457. return false;
  6458. }
  6459. }
  6460. ArTypeInfo TargetInfo, SourceInfo;
  6461. CollectInfo(target, &TargetInfo);
  6462. CollectInfo(source, &SourceInfo);
  6463. uTSize = TargetInfo.uTotalElts;
  6464. uSSize = SourceInfo.uTotalElts;
  6465. // TODO: TYPE_CONVERSION_BY_REFERENCE does not seem possible here
  6466. // are we missing cases?
  6467. if ((Flags & TYPE_CONVERSION_BY_REFERENCE) != 0 && uTSize != uSSize) {
  6468. return false;
  6469. }
  6470. // Structure cast.
  6471. if (TargetInfo.ShapeKind == AR_TOBJ_COMPOUND || TargetInfo.ShapeKind == AR_TOBJ_ARRAY ||
  6472. SourceInfo.ShapeKind == AR_TOBJ_COMPOUND || SourceInfo.ShapeKind == AR_TOBJ_ARRAY) {
  6473. if (!explicitConversion && TargetInfo.ShapeKind != SourceInfo.ShapeKind)
  6474. {
  6475. return false;
  6476. }
  6477. const RecordType *targetRT = target->getAsStructureType();
  6478. if (!targetRT)
  6479. targetRT = dyn_cast<RecordType>(target);
  6480. const RecordType *sourceRT = source->getAsStructureType();
  6481. if (!sourceRT)
  6482. sourceRT = dyn_cast<RecordType>(source);
  6483. if (targetRT && sourceRT) {
  6484. RecordDecl *targetRD = targetRT->getDecl();
  6485. RecordDecl *sourceRD = sourceRT->getDecl();
  6486. const CXXRecordDecl *targetCXXRD = dyn_cast<CXXRecordDecl>(targetRD);
  6487. const CXXRecordDecl *sourceCXXRD = dyn_cast<CXXRecordDecl>(sourceRD);
  6488. if (targetCXXRD && sourceCXXRD) {
  6489. if (targetRD == sourceRD) {
  6490. Second = ICK_Flat_Conversion;
  6491. goto lSuccess;
  6492. }
  6493. if (sourceCXXRD->isDerivedFrom(targetCXXRD)) {
  6494. Second = ICK_HLSL_Derived_To_Base;
  6495. goto lSuccess;
  6496. }
  6497. } else {
  6498. if (targetRD == sourceRD) {
  6499. Second = ICK_Flat_Conversion;
  6500. goto lSuccess;
  6501. }
  6502. }
  6503. }
  6504. if (const BuiltinType *BT = source->getAs<BuiltinType>()) {
  6505. BuiltinType::Kind kind = BT->getKind();
  6506. switch (kind) {
  6507. case BuiltinType::Kind::UInt:
  6508. case BuiltinType::Kind::Int:
  6509. case BuiltinType::Kind::Float:
  6510. case BuiltinType::Kind::LitFloat:
  6511. case BuiltinType::Kind::LitInt:
  6512. if (explicitConversion) {
  6513. Second = ICK_Flat_Conversion;
  6514. goto lSuccess;
  6515. }
  6516. break;
  6517. default:
  6518. // Only flat conversion kinds are relevant.
  6519. break;
  6520. }
  6521. }
  6522. FlattenedTypeIterator::ComparisonResult result =
  6523. FlattenedTypeIterator::CompareTypes(*this, loc, loc, target, source);
  6524. if (!result.CanConvertElements) {
  6525. return false;
  6526. }
  6527. // Only allow scalar to compound or array with explicit cast
  6528. if (result.IsConvertibleAndLeftLonger()) {
  6529. if (!explicitConversion || SourceInfo.ShapeKind != AR_TOBJ_SCALAR) {
  6530. return false;
  6531. }
  6532. }
  6533. // Assignment is valid if elements are exactly the same in type and size; if
  6534. // an explicit conversion is being done, we accept converted elements and a
  6535. // longer right-hand sequence.
  6536. if (!explicitConversion &&
  6537. (!result.AreElementsEqual || result.IsRightLonger()))
  6538. {
  6539. return false;
  6540. }
  6541. Second = ICK_Flat_Conversion;
  6542. goto lSuccess;
  6543. }
  6544. // Base type cast.
  6545. //
  6546. // The rules for aggregate conversions are:
  6547. // 1. A scalar can be replicated to any layout.
  6548. // 2. The result of two vectors is the smaller vector.
  6549. // 3. The result of two matrices is the smaller matrix.
  6550. // 4. The result of a vector and a matrix is:
  6551. // a. If the matrix has one row it's a vector-sized
  6552. // piece of the row.
  6553. // b. If the matrix has one column it's a vector-sized
  6554. // piece of the column.
  6555. // c. Otherwise the number of elements in the vector
  6556. // and matrix must match and the result is the vector.
  6557. // 5. The result of a matrix and a vector is similar to #4.
  6558. //
  6559. switch (TargetInfo.ShapeKind) {
  6560. case AR_TOBJ_BASIC:
  6561. switch (SourceInfo.ShapeKind)
  6562. {
  6563. case AR_TOBJ_BASIC:
  6564. Second = ICK_Identity;
  6565. break;
  6566. case AR_TOBJ_VECTOR:
  6567. if(1 < SourceInfo.uCols)
  6568. Second = ICK_HLSLVector_Truncation;
  6569. else
  6570. Second = ICK_HLSLVector_Scalar;
  6571. break;
  6572. case AR_TOBJ_MATRIX:
  6573. if(1 < SourceInfo.uRows * SourceInfo.uCols)
  6574. Second = ICK_HLSLVector_Truncation;
  6575. else
  6576. Second = ICK_HLSLVector_Scalar;
  6577. break;
  6578. case AR_TOBJ_OBJECT:
  6579. case AR_TOBJ_INTERFACE:
  6580. case AR_TOBJ_POINTER:
  6581. return false;
  6582. default:
  6583. // Only valid conversion source types are handled.
  6584. break;
  6585. }
  6586. bCheckElt = true;
  6587. break;
  6588. case AR_TOBJ_VECTOR:
  6589. switch (SourceInfo.ShapeKind)
  6590. {
  6591. case AR_TOBJ_BASIC:
  6592. // Conversions between scalars and aggregates are always supported.
  6593. Second = ICK_HLSLVector_Splat;
  6594. break;
  6595. case AR_TOBJ_VECTOR:
  6596. if (TargetInfo.uCols > SourceInfo.uCols) {
  6597. if (SourceInfo.uCols == 1) {
  6598. Second = ICK_HLSLVector_Splat;
  6599. } else {
  6600. return false;
  6601. }
  6602. } else if (TargetInfo.uCols < SourceInfo.uCols) {
  6603. Second = ICK_HLSLVector_Truncation;
  6604. } else {
  6605. Second = ICK_Identity;
  6606. }
  6607. break;
  6608. case AR_TOBJ_MATRIX: {
  6609. UINT SourceComponents = SourceInfo.uRows * SourceInfo.uCols;
  6610. if (1 == SourceComponents && TargetInfo.uCols != 1) {
  6611. // splat: matrix<[..], 1, 1> -> vector<[..], O>
  6612. Second = ICK_HLSLVector_Splat;
  6613. } else if (1 == SourceInfo.uRows || 1 == SourceInfo.uCols) {
  6614. // cases for: matrix<[..], M, N> -> vector<[..], O>, where N == 1 or M == 1
  6615. if (TargetInfo.uCols > SourceComponents) // illegal: O > N*M
  6616. return false;
  6617. else if (TargetInfo.uCols < SourceComponents) // truncation: O < N*M
  6618. Second = ICK_HLSLVector_Truncation;
  6619. else // equalivalent: O == N*M
  6620. Second = ICK_HLSLVector_Conversion;
  6621. } else if (TargetInfo.uCols != SourceComponents) {
  6622. // illegal: matrix<[..], M, N> -> vector<[..], O> where N != 1 and M != 1 and O != N*M
  6623. return false;
  6624. } else {
  6625. // legal: matrix<[..], M, N> -> vector<[..], O> where N != 1 and M != 1 and O == N*M
  6626. Second = ICK_HLSLVector_Conversion;
  6627. }
  6628. break;
  6629. }
  6630. case AR_TOBJ_OBJECT:
  6631. case AR_TOBJ_INTERFACE:
  6632. case AR_TOBJ_POINTER:
  6633. return false;
  6634. default:
  6635. // Only valid conversion source types are handled.
  6636. break;
  6637. }
  6638. bCheckElt = true;
  6639. break;
  6640. case AR_TOBJ_MATRIX: {
  6641. UINT TargetComponents = TargetInfo.uRows * TargetInfo.uCols;
  6642. switch (SourceInfo.ShapeKind)
  6643. {
  6644. case AR_TOBJ_BASIC:
  6645. // Conversions between scalars and aggregates are always supported.
  6646. Second = ICK_HLSLVector_Splat;
  6647. break;
  6648. case AR_TOBJ_VECTOR: {
  6649. if (1 == SourceInfo.uCols && TargetComponents != 1) {
  6650. // splat: vector<[..], 1> -> matrix<[..], M, N>
  6651. Second = ICK_HLSLVector_Splat;
  6652. } else if (1 == TargetInfo.uRows || 1 == TargetInfo.uCols) {
  6653. // cases for: vector<[..], O> -> matrix<[..], N, M>, where N == 1 or M == 1
  6654. if (TargetComponents > SourceInfo.uCols) // illegal: N*M > O
  6655. return false;
  6656. else if (TargetComponents < SourceInfo.uCols) // truncation: N*M < O
  6657. Second = ICK_HLSLVector_Truncation;
  6658. else // equalivalent: N*M == O
  6659. Second = ICK_HLSLVector_Conversion;
  6660. } else if (TargetComponents != SourceInfo.uCols) {
  6661. // illegal: vector<[..], O> -> matrix<[..], M, N> where N != 1 and M != 1 and O != N*M
  6662. return false;
  6663. } else {
  6664. // legal: vector<[..], O> -> matrix<[..], M, N> where N != 1 and M != 1 and O == N*M
  6665. Second = ICK_HLSLVector_Conversion;
  6666. }
  6667. break;
  6668. }
  6669. case AR_TOBJ_MATRIX: {
  6670. UINT SourceComponents = SourceInfo.uRows * SourceInfo.uCols;
  6671. if (1 == SourceComponents && TargetComponents != 1) {
  6672. // splat: matrix<[..], 1, 1> -> matrix<[..], M, N>
  6673. Second = ICK_HLSLVector_Splat;
  6674. } else if (TargetInfo.uRows > SourceInfo.uRows || TargetInfo.uCols > SourceInfo.uCols) {
  6675. return false;
  6676. } else if(TargetInfo.uRows < SourceInfo.uRows || TargetInfo.uCols < SourceInfo.uCols) {
  6677. Second = ICK_HLSLVector_Truncation;
  6678. } else {
  6679. Second = ICK_Identity;
  6680. }
  6681. break;
  6682. }
  6683. case AR_TOBJ_OBJECT:
  6684. case AR_TOBJ_INTERFACE:
  6685. case AR_TOBJ_POINTER:
  6686. return false;
  6687. default:
  6688. // Only valid conversion source types are handled.
  6689. break;
  6690. }
  6691. bCheckElt = true;
  6692. break;
  6693. }
  6694. case AR_TOBJ_OBJECT:
  6695. // There are no compatible object assignments that aren't
  6696. // from one type to itself, which is already covered.
  6697. DXASSERT(source != target, "otherwise trivial case was not checked by this function");
  6698. return false;
  6699. default:
  6700. DXASSERT_NOMSG(false);
  6701. return false;
  6702. }
  6703. if (bCheckElt)
  6704. {
  6705. bool precisionLoss = false;
  6706. if (GET_BASIC_BITS(TargetInfo.EltKind) != 0 &&
  6707. GET_BASIC_BITS(TargetInfo.EltKind) <
  6708. GET_BASIC_BITS(SourceInfo.EltKind))
  6709. {
  6710. precisionLoss = true;
  6711. Remarks |= TYPE_CONVERSION_PRECISION_LOSS;
  6712. }
  6713. if (TargetInfo.uTotalElts < SourceInfo.uTotalElts)
  6714. {
  6715. Remarks |= TYPE_CONVERSION_ELT_TRUNCATION;
  6716. }
  6717. // enum -> enum not allowed
  6718. if ((SourceInfo.EltKind == AR_BASIC_ENUM &&
  6719. TargetInfo.EltKind == AR_BASIC_ENUM) ||
  6720. SourceInfo.EltKind == AR_BASIC_ENUM_CLASS ||
  6721. TargetInfo.EltKind == AR_BASIC_ENUM_CLASS) {
  6722. return false;
  6723. }
  6724. if (SourceInfo.EltKind != TargetInfo.EltKind)
  6725. {
  6726. if (TargetInfo.EltKind == AR_BASIC_UNKNOWN ||
  6727. SourceInfo.EltKind == AR_BASIC_UNKNOWN)
  6728. {
  6729. Second = ICK_Flat_Conversion;
  6730. }
  6731. else if (IS_BASIC_BOOL(TargetInfo.EltKind))
  6732. {
  6733. ComponentConversion = ICK_Boolean_Conversion;
  6734. }
  6735. else if (IS_BASIC_ENUM(TargetInfo.EltKind))
  6736. {
  6737. // conversion to enum type not allowed
  6738. return false;
  6739. }
  6740. else if (IS_BASIC_ENUM(SourceInfo.EltKind))
  6741. {
  6742. // enum -> int/float
  6743. ComponentConversion = ICK_Integral_Conversion;
  6744. }
  6745. else
  6746. {
  6747. bool targetIsInt = IS_BASIC_AINT(TargetInfo.EltKind);
  6748. if (IS_BASIC_AINT(SourceInfo.EltKind))
  6749. {
  6750. if (targetIsInt)
  6751. {
  6752. ComponentConversion = precisionLoss ? ICK_Integral_Conversion : ICK_Integral_Promotion;
  6753. }
  6754. else
  6755. {
  6756. ComponentConversion = ICK_Floating_Integral;
  6757. }
  6758. }
  6759. else if (IS_BASIC_FLOAT(SourceInfo.EltKind))
  6760. {
  6761. DXASSERT(IS_BASIC_FLOAT(SourceInfo.EltKind), "otherwise should not be checking element types");
  6762. if (targetIsInt)
  6763. {
  6764. ComponentConversion = ICK_Floating_Integral;
  6765. }
  6766. else
  6767. {
  6768. ComponentConversion = precisionLoss ? ICK_Floating_Conversion : ICK_Floating_Promotion;
  6769. }
  6770. } else if (IS_BASIC_BOOL(SourceInfo.EltKind)) {
  6771. if (targetIsInt)
  6772. ComponentConversion = ICK_Integral_Conversion;
  6773. else
  6774. ComponentConversion = ICK_Floating_Integral;
  6775. }
  6776. }
  6777. }
  6778. }
  6779. lSuccess:
  6780. if (standard)
  6781. {
  6782. if (sourceExpr->isLValue())
  6783. {
  6784. if (needsLValueToRValue) {
  6785. // We don't need LValueToRValue cast before casting a derived object
  6786. // to its base.
  6787. if (Second == ICK_HLSL_Derived_To_Base) {
  6788. standard->First = ICK_Identity;
  6789. } else {
  6790. standard->First = ICK_Lvalue_To_Rvalue;
  6791. }
  6792. } else {
  6793. switch (Second)
  6794. {
  6795. case ICK_NoReturn_Adjustment:
  6796. case ICK_Vector_Conversion:
  6797. case ICK_Vector_Splat:
  6798. DXASSERT(false, "We shouldn't be producing these implicit conversion kinds");
  6799. case ICK_Flat_Conversion:
  6800. case ICK_HLSLVector_Splat:
  6801. standard->First = ICK_Lvalue_To_Rvalue;
  6802. break;
  6803. default:
  6804. // Only flat and splat conversions handled.
  6805. break;
  6806. }
  6807. switch (ComponentConversion)
  6808. {
  6809. case ICK_Integral_Promotion:
  6810. case ICK_Integral_Conversion:
  6811. case ICK_Floating_Promotion:
  6812. case ICK_Floating_Conversion:
  6813. case ICK_Floating_Integral:
  6814. case ICK_Boolean_Conversion:
  6815. standard->First = ICK_Lvalue_To_Rvalue;
  6816. break;
  6817. default:
  6818. // Only potential assignments above covered.
  6819. break;
  6820. }
  6821. }
  6822. }
  6823. // Finally fix up the cases for scalar->scalar component conversion, and
  6824. // identity vector/matrix component conversion
  6825. if (ICK_Identity != ComponentConversion) {
  6826. if (Second == ICK_Identity) {
  6827. if (TargetInfo.ShapeKind == AR_TOBJ_BASIC) {
  6828. // Scalar to scalar type conversion, use normal mechanism (Second)
  6829. Second = ComponentConversion;
  6830. ComponentConversion = ICK_Identity;
  6831. } else {
  6832. // vector or matrix dimensions are not being changed, but component type
  6833. // is being converted, so change Second to signal the conversion
  6834. Second = ICK_HLSLVector_Conversion;
  6835. }
  6836. }
  6837. }
  6838. standard->Second = Second;
  6839. standard->ComponentConversion = ComponentConversion;
  6840. // For conversion which change to RValue but targeting reference type
  6841. // Hold the conversion to codeGen
  6842. if (targetRef && standard->First == ICK_Lvalue_To_Rvalue) {
  6843. standard->First = ICK_Identity;
  6844. standard->Second = ICK_Identity;
  6845. }
  6846. }
  6847. AssignOpt(Remarks, remarks);
  6848. return true;
  6849. }
  6850. Expr* HLSLExternalSource::CastExprToTypeNumeric(Expr* expr, QualType type)
  6851. {
  6852. DXASSERT_NOMSG(expr != nullptr);
  6853. DXASSERT_NOMSG(!type.isNull());
  6854. if (expr->getType() != type) {
  6855. StandardConversionSequence standard;
  6856. TYPE_CONVERSION_REMARKS remarks;
  6857. if (CanConvert(SourceLocation(), expr, type, /*explicitConversion*/false, &remarks, &standard) &&
  6858. (standard.First != ICK_Identity || !standard.isIdentityConversion())) {
  6859. if ((remarks & TYPE_CONVERSION_ELT_TRUNCATION) != 0) {
  6860. m_sema->Diag(expr->getExprLoc(), diag::warn_hlsl_implicit_vector_truncation);
  6861. }
  6862. ExprResult result = m_sema->PerformImplicitConversion(expr, type, standard, Sema::AA_Casting, Sema::CCK_ImplicitConversion);
  6863. if (result.isUsable()) {
  6864. return result.get();
  6865. }
  6866. }
  6867. }
  6868. return expr;
  6869. }
  6870. bool HLSLExternalSource::ValidateTypeRequirements(
  6871. SourceLocation loc,
  6872. ArBasicKind elementKind,
  6873. ArTypeObjectKind objectKind,
  6874. bool requiresIntegrals,
  6875. bool requiresNumerics)
  6876. {
  6877. if (requiresIntegrals || requiresNumerics)
  6878. {
  6879. if (!IsObjectKindPrimitiveAggregate(objectKind))
  6880. {
  6881. m_sema->Diag(loc, diag::err_hlsl_requires_non_aggregate);
  6882. return false;
  6883. }
  6884. }
  6885. if (requiresIntegrals)
  6886. {
  6887. if (!IsBasicKindIntegral(elementKind))
  6888. {
  6889. m_sema->Diag(loc, diag::err_hlsl_requires_int_or_uint);
  6890. return false;
  6891. }
  6892. }
  6893. else if (requiresNumerics)
  6894. {
  6895. if (!IsBasicKindNumeric(elementKind))
  6896. {
  6897. m_sema->Diag(loc, diag::err_hlsl_requires_numeric);
  6898. return false;
  6899. }
  6900. }
  6901. return true;
  6902. }
  6903. bool HLSLExternalSource::ValidatePrimitiveTypeForOperand(SourceLocation loc, QualType type, ArTypeObjectKind kind)
  6904. {
  6905. bool isValid = true;
  6906. if (IsBuiltInObjectType(type)) {
  6907. m_sema->Diag(loc, diag::err_hlsl_unsupported_builtin_op) << type;
  6908. isValid = false;
  6909. }
  6910. if (kind == AR_TOBJ_COMPOUND) {
  6911. m_sema->Diag(loc, diag::err_hlsl_unsupported_struct_op) << type;
  6912. isValid = false;
  6913. }
  6914. return isValid;
  6915. }
  6916. HRESULT HLSLExternalSource::CombineDimensions(QualType leftType, QualType rightType, ArTypeObjectKind leftKind, ArTypeObjectKind rightKind, QualType *resultType)
  6917. {
  6918. UINT leftRows, leftCols;
  6919. UINT rightRows, rightCols;
  6920. GetRowsAndColsForAny(leftType, leftRows, leftCols);
  6921. GetRowsAndColsForAny(rightType, rightRows, rightCols);
  6922. UINT leftTotal = leftRows * leftCols;
  6923. UINT rightTotal = rightRows * rightCols;
  6924. if (rightTotal == 1) {
  6925. *resultType = leftType;
  6926. return S_OK;
  6927. } else if (leftTotal == 1) {
  6928. *resultType = rightType;
  6929. return S_OK;
  6930. } else if (leftRows <= rightRows && leftCols <= rightCols) {
  6931. DXASSERT_NOMSG((leftKind == AR_TOBJ_MATRIX || leftKind == AR_TOBJ_VECTOR) &&
  6932. (rightKind == AR_TOBJ_MATRIX || rightKind == AR_TOBJ_VECTOR));
  6933. if (leftKind == rightKind) {
  6934. *resultType = leftType;
  6935. return S_OK;
  6936. } else {
  6937. // vector & matrix combination - only 1xN is allowed here
  6938. if (leftKind == AR_TOBJ_VECTOR && rightRows == 1) {
  6939. *resultType = leftType;
  6940. return S_OK;
  6941. }
  6942. }
  6943. } else if (rightRows <= leftRows && rightCols <= leftCols) {
  6944. DXASSERT_NOMSG((leftKind == AR_TOBJ_MATRIX || leftKind == AR_TOBJ_VECTOR) &&
  6945. (rightKind == AR_TOBJ_MATRIX || rightKind == AR_TOBJ_VECTOR));
  6946. if (leftKind == rightKind) {
  6947. *resultType = rightType;
  6948. return S_OK;
  6949. } else {
  6950. // matrix & vector combination - only 1xN is allowed here
  6951. if (rightKind == AR_TOBJ_VECTOR && leftRows == 1) {
  6952. *resultType = leftType;
  6953. return S_OK;
  6954. }
  6955. }
  6956. } else if ( (1 == leftRows || 1 == leftCols) &&
  6957. (1 == rightRows || 1 == rightCols)) {
  6958. // Handles cases where 1xN or Nx1 matrices are involved possibly mixed with vectors
  6959. if (leftTotal <= rightTotal) {
  6960. *resultType = leftType;
  6961. return S_OK;
  6962. } else {
  6963. *resultType = rightType;
  6964. return S_OK;
  6965. }
  6966. }
  6967. else if (((leftKind == AR_TOBJ_VECTOR && rightKind == AR_TOBJ_MATRIX) ||
  6968. (leftKind == AR_TOBJ_MATRIX && rightKind == AR_TOBJ_VECTOR)) && leftTotal == rightTotal) {
  6969. *resultType = leftType;
  6970. return S_OK;
  6971. }
  6972. return E_FAIL;
  6973. }
  6974. /// <summary>Validates and adjusts operands for the specified binary operator.</summary>
  6975. /// <param name="OpLoc">Source location for operator.</param>
  6976. /// <param name="Opc">Kind of binary operator.</param>
  6977. /// <param name="LHS">Left-hand-side expression, possibly updated by this function.</param>
  6978. /// <param name="RHS">Right-hand-side expression, possibly updated by this function.</param>
  6979. /// <param name="ResultTy">Result type for operator expression.</param>
  6980. /// <param name="CompLHSTy">Type of LHS after promotions for computation.</param>
  6981. /// <param name="CompResultTy">Type of computation result.</param>
  6982. void HLSLExternalSource::CheckBinOpForHLSL(
  6983. SourceLocation OpLoc,
  6984. BinaryOperatorKind Opc,
  6985. ExprResult& LHS,
  6986. ExprResult& RHS,
  6987. QualType& ResultTy,
  6988. QualType& CompLHSTy,
  6989. QualType& CompResultTy)
  6990. {
  6991. // At the start, none of the output types should be valid.
  6992. DXASSERT_NOMSG(ResultTy.isNull());
  6993. DXASSERT_NOMSG(CompLHSTy.isNull());
  6994. DXASSERT_NOMSG(CompResultTy.isNull());
  6995. LHS = m_sema->CorrectDelayedTyposInExpr(LHS);
  6996. RHS = m_sema->CorrectDelayedTyposInExpr(RHS);
  6997. // If either expression is invalid to begin with, propagate that.
  6998. if (LHS.isInvalid() || RHS.isInvalid()) {
  6999. return;
  7000. }
  7001. // TODO: re-review the Check** in Clang and add equivalent diagnostics if/as needed, possibly after conversions
  7002. // Handle Assign and Comma operators and return
  7003. switch (Opc)
  7004. {
  7005. case BO_AddAssign:
  7006. case BO_AndAssign:
  7007. case BO_DivAssign:
  7008. case BO_MulAssign:
  7009. case BO_RemAssign:
  7010. case BO_ShlAssign:
  7011. case BO_ShrAssign:
  7012. case BO_SubAssign:
  7013. case BO_OrAssign:
  7014. case BO_XorAssign: {
  7015. extern bool CheckForModifiableLvalue(Expr * E, SourceLocation Loc,
  7016. Sema & S);
  7017. if (CheckForModifiableLvalue(LHS.get(), OpLoc, *m_sema)) {
  7018. return;
  7019. }
  7020. } break;
  7021. case BO_Assign: {
  7022. extern bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S);
  7023. if (CheckForModifiableLvalue(LHS.get(), OpLoc, *m_sema)) {
  7024. return;
  7025. }
  7026. bool complained = false;
  7027. ResultTy = LHS.get()->getType();
  7028. if (m_sema->DiagnoseAssignmentResult(Sema::AssignConvertType::Compatible,
  7029. OpLoc, ResultTy, RHS.get()->getType(), RHS.get(),
  7030. Sema::AssignmentAction::AA_Assigning, &complained)) {
  7031. return;
  7032. }
  7033. StandardConversionSequence standard;
  7034. if (!ValidateCast(OpLoc, RHS.get(), ResultTy,
  7035. ExplicitConversionFalse, complained, complained, &standard)) {
  7036. return;
  7037. }
  7038. if (RHS.get()->isLValue()) {
  7039. standard.First = ICK_Lvalue_To_Rvalue;
  7040. }
  7041. RHS = m_sema->PerformImplicitConversion(RHS.get(), ResultTy,
  7042. standard, Sema::AA_Converting, Sema::CCK_ImplicitConversion);
  7043. return;
  7044. }
  7045. break;
  7046. case BO_Comma:
  7047. // C performs conversions, C++ doesn't but still checks for type completeness.
  7048. // There are also diagnostics for improper comma use.
  7049. // In the HLSL case these cases don't apply or simply aren't surfaced.
  7050. ResultTy = RHS.get()->getType();
  7051. return;
  7052. default:
  7053. // Only assign and comma operations handled.
  7054. break;
  7055. }
  7056. // Leave this diagnostic for last to emulate fxc behavior.
  7057. bool isCompoundAssignment = BinaryOperatorKindIsCompoundAssignment(Opc);
  7058. bool unsupportedBoolLvalue = isCompoundAssignment &&
  7059. !BinaryOperatorKindIsCompoundAssignmentForBool(Opc) &&
  7060. GetTypeElementKind(LHS.get()->getType()) == AR_BASIC_BOOL;
  7061. // Turn operand inputs into r-values.
  7062. QualType LHSTypeAsPossibleLValue = LHS.get()->getType();
  7063. if (!isCompoundAssignment) {
  7064. LHS = m_sema->DefaultLvalueConversion(LHS.get());
  7065. }
  7066. RHS = m_sema->DefaultLvalueConversion(RHS.get());
  7067. if (LHS.isInvalid() || RHS.isInvalid()) {
  7068. return;
  7069. }
  7070. // Promote bool to int now if necessary
  7071. if (BinaryOperatorKindRequiresBoolAsNumeric(Opc) &&
  7072. !isCompoundAssignment) {
  7073. LHS = PromoteToIntIfBool(LHS);
  7074. }
  7075. // Gather type info
  7076. QualType leftType = GetStructuralForm(LHS.get()->getType());
  7077. QualType rightType = GetStructuralForm(RHS.get()->getType());
  7078. ArBasicKind leftElementKind = GetTypeElementKind(leftType);
  7079. ArBasicKind rightElementKind = GetTypeElementKind(rightType);
  7080. ArTypeObjectKind leftObjectKind = GetTypeObjectKind(leftType);
  7081. ArTypeObjectKind rightObjectKind = GetTypeObjectKind(rightType);
  7082. // Validate type requirements
  7083. {
  7084. bool requiresNumerics = BinaryOperatorKindRequiresNumeric(Opc);
  7085. bool requiresIntegrals = BinaryOperatorKindRequiresIntegrals(Opc);
  7086. if (!ValidateTypeRequirements(OpLoc, leftElementKind, leftObjectKind, requiresIntegrals, requiresNumerics)) {
  7087. return;
  7088. }
  7089. if (!ValidateTypeRequirements(OpLoc, rightElementKind, rightObjectKind, requiresIntegrals, requiresNumerics)) {
  7090. return;
  7091. }
  7092. }
  7093. // Promote rhs bool to int if necessary.
  7094. if (BinaryOperatorKindRequiresBoolAsNumeric(Opc)) {
  7095. RHS = PromoteToIntIfBool(RHS);
  7096. }
  7097. if (unsupportedBoolLvalue) {
  7098. m_sema->Diag(OpLoc, diag::err_hlsl_unsupported_bool_lvalue_op);
  7099. return;
  7100. }
  7101. // We don't support binary operators on built-in object types other than assignment or commas.
  7102. {
  7103. DXASSERT(Opc != BO_Assign, "otherwise this wasn't handled as an early exit");
  7104. DXASSERT(Opc != BO_Comma, "otherwise this wasn't handled as an early exit");
  7105. bool isValid;
  7106. isValid = ValidatePrimitiveTypeForOperand(OpLoc, leftType, leftObjectKind);
  7107. if (leftType != rightType && !ValidatePrimitiveTypeForOperand(OpLoc, rightType, rightObjectKind)) {
  7108. isValid = false;
  7109. }
  7110. if (!isValid) {
  7111. return;
  7112. }
  7113. }
  7114. // We don't support equality comparisons on arrays.
  7115. if ((Opc == BO_EQ || Opc == BO_NE) && (leftObjectKind == AR_TOBJ_ARRAY || rightObjectKind == AR_TOBJ_ARRAY)) {
  7116. m_sema->Diag(OpLoc, diag::err_hlsl_unsupported_array_equality_op);
  7117. return;
  7118. }
  7119. // Combine element types for computation.
  7120. ArBasicKind resultElementKind = leftElementKind;
  7121. {
  7122. if (BinaryOperatorKindIsLogical(Opc)) {
  7123. resultElementKind = AR_BASIC_BOOL;
  7124. } else if (!BinaryOperatorKindIsBitwiseShift(Opc) && leftElementKind != rightElementKind) {
  7125. if (!CombineBasicTypes(leftElementKind, rightElementKind, &resultElementKind, nullptr, nullptr)) {
  7126. m_sema->Diag(OpLoc, diag::err_hlsl_type_mismatch);
  7127. return;
  7128. }
  7129. } else if (BinaryOperatorKindIsBitwiseShift(Opc) &&
  7130. (resultElementKind == AR_BASIC_LITERAL_INT ||
  7131. resultElementKind == AR_BASIC_LITERAL_FLOAT) &&
  7132. rightElementKind != AR_BASIC_LITERAL_INT &&
  7133. rightElementKind != AR_BASIC_LITERAL_FLOAT) {
  7134. // For case like 1<<x.
  7135. resultElementKind = AR_BASIC_UINT32;
  7136. }
  7137. // The following combines the selected/combined element kind above with
  7138. // the dimensions that are legal to implicitly cast. This means that
  7139. // element kind may be taken from one side and the dimensions from the
  7140. // other.
  7141. if (!isCompoundAssignment) {
  7142. // Legal dimension combinations are identical, splat, and truncation.
  7143. // ResultTy will be set to whichever type can be converted to, if legal,
  7144. // with preference for leftType if both are possible.
  7145. if (FAILED(CombineDimensions(leftType, rightType, leftObjectKind, rightObjectKind, &ResultTy))) {
  7146. m_sema->Diag(OpLoc, diag::err_hlsl_type_mismatch);
  7147. return;
  7148. }
  7149. } else {
  7150. ResultTy = LHS.get()->getType();
  7151. }
  7152. // Here, element kind is combined with dimensions for computation type.
  7153. UINT rowCount, colCount;
  7154. ArTypeObjectKind resultObjectKind = (leftObjectKind == rightObjectKind ? leftObjectKind : AR_TOBJ_INVALID);
  7155. GetRowsAndColsForAny(ResultTy, rowCount, colCount);
  7156. ResultTy = NewSimpleAggregateType(resultObjectKind, resultElementKind, 0, rowCount, colCount)->getCanonicalTypeInternal();
  7157. }
  7158. // Perform necessary conversion sequences for LHS and RHS
  7159. if (RHS.get()->getType() != ResultTy) {
  7160. RHS = CastExprToTypeNumeric(RHS.get(), ResultTy);
  7161. }
  7162. if (isCompoundAssignment) {
  7163. bool complained = false;
  7164. StandardConversionSequence standard;
  7165. if (!ValidateCast(OpLoc, RHS.get(), LHS.get()->getType(), ExplicitConversionFalse,
  7166. complained, complained, &standard)) {
  7167. ResultTy = QualType();
  7168. return;
  7169. }
  7170. CompResultTy = ResultTy;
  7171. CompLHSTy = CompResultTy;
  7172. // For a compound operation, C/C++ promotes both types, performs the arithmetic,
  7173. // then converts to the result type and then assigns.
  7174. //
  7175. // So int + float promotes the int to float, does a floating-point addition,
  7176. // then the result becomes and int and is assigned.
  7177. ResultTy = LHSTypeAsPossibleLValue;
  7178. } else if (LHS.get()->getType() != ResultTy) {
  7179. LHS = CastExprToTypeNumeric(LHS.get(), ResultTy);
  7180. }
  7181. if (BinaryOperatorKindIsComparison(Opc) || BinaryOperatorKindIsLogical(Opc))
  7182. {
  7183. DXASSERT(!isCompoundAssignment, "otherwise binary lookup tables are inconsistent");
  7184. // Return bool vector for vector types.
  7185. if (IsVectorType(m_sema, ResultTy)) {
  7186. UINT rowCount, colCount;
  7187. GetRowsAndColsForAny(ResultTy, rowCount, colCount);
  7188. ResultTy = LookupVectorType(HLSLScalarType::HLSLScalarType_bool, colCount);
  7189. } else if (IsMatrixType(m_sema, ResultTy)) {
  7190. UINT rowCount, colCount;
  7191. GetRowsAndColsForAny(ResultTy, rowCount, colCount);
  7192. ResultTy = LookupMatrixType(HLSLScalarType::HLSLScalarType_bool, rowCount, colCount);
  7193. } else
  7194. ResultTy = m_context->BoolTy.withConst();
  7195. }
  7196. // Run diagnostics. Some are emulating checks that occur in IR emission in fxc.
  7197. if (Opc == BO_Div || Opc == BO_DivAssign || Opc == BO_Rem || Opc == BO_RemAssign) {
  7198. if (IsBasicKindIntMinPrecision(resultElementKind)) {
  7199. m_sema->Diag(OpLoc, diag::err_hlsl_unsupported_div_minint);
  7200. return;
  7201. }
  7202. }
  7203. if (Opc == BO_Rem || Opc == BO_RemAssign) {
  7204. if (resultElementKind == AR_BASIC_FLOAT64) {
  7205. m_sema->Diag(OpLoc, diag::err_hlsl_unsupported_mod_double);
  7206. return;
  7207. }
  7208. }
  7209. }
  7210. /// <summary>Validates and adjusts operands for the specified unary operator.</summary>
  7211. /// <param name="OpLoc">Source location for operator.</param>
  7212. /// <param name="Opc">Kind of operator.</param>
  7213. /// <param name="InputExpr">Input expression to the operator.</param>
  7214. /// <param name="VK">Value kind for resulting expression.</param>
  7215. /// <param name="OK">Object kind for resulting expression.</param>
  7216. /// <returns>The result type for the expression.</returns>
  7217. QualType HLSLExternalSource::CheckUnaryOpForHLSL(
  7218. SourceLocation OpLoc,
  7219. UnaryOperatorKind Opc,
  7220. ExprResult& InputExpr,
  7221. ExprValueKind& VK,
  7222. ExprObjectKind& OK)
  7223. {
  7224. InputExpr = m_sema->CorrectDelayedTyposInExpr(InputExpr);
  7225. if (InputExpr.isInvalid())
  7226. return QualType();
  7227. // Reject unsupported operators * and &
  7228. switch (Opc) {
  7229. case UO_AddrOf:
  7230. case UO_Deref:
  7231. m_sema->Diag(OpLoc, diag::err_hlsl_unsupported_operator);
  7232. return QualType();
  7233. default:
  7234. // Only * and & covered.
  7235. break;
  7236. }
  7237. Expr* expr = InputExpr.get();
  7238. if (expr->isTypeDependent())
  7239. return m_context->DependentTy;
  7240. ArBasicKind elementKind = GetTypeElementKind(expr->getType());
  7241. if (UnaryOperatorKindRequiresModifiableValue(Opc)) {
  7242. if (elementKind == AR_BASIC_ENUM) {
  7243. bool isInc = IsIncrementOp(Opc);
  7244. m_sema->Diag(OpLoc, diag::err_increment_decrement_enum) << isInc << expr->getType();
  7245. return QualType();
  7246. }
  7247. extern bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S);
  7248. if (CheckForModifiableLvalue(expr, OpLoc, *m_sema))
  7249. return QualType();
  7250. } else {
  7251. InputExpr = m_sema->DefaultLvalueConversion(InputExpr.get()).get();
  7252. if (InputExpr.isInvalid()) return QualType();
  7253. }
  7254. if (UnaryOperatorKindDisallowsBool(Opc) && IS_BASIC_BOOL(elementKind)) {
  7255. m_sema->Diag(OpLoc, diag::err_hlsl_unsupported_bool_lvalue_op);
  7256. return QualType();
  7257. }
  7258. if (UnaryOperatorKindRequiresBoolAsNumeric(Opc)) {
  7259. InputExpr = PromoteToIntIfBool(InputExpr);
  7260. expr = InputExpr.get();
  7261. elementKind = GetTypeElementKind(expr->getType());
  7262. }
  7263. ArTypeObjectKind objectKind = GetTypeObjectKind(expr->getType());
  7264. bool requiresIntegrals = UnaryOperatorKindRequiresIntegrals(Opc);
  7265. bool requiresNumerics = UnaryOperatorKindRequiresNumerics(Opc);
  7266. if (!ValidateTypeRequirements(OpLoc, elementKind, objectKind, requiresIntegrals, requiresNumerics)) {
  7267. return QualType();
  7268. }
  7269. if (Opc == UnaryOperatorKind::UO_Minus) {
  7270. if (IS_BASIC_UINT(Opc)) {
  7271. m_sema->Diag(OpLoc, diag::warn_hlsl_unary_negate_unsigned);
  7272. }
  7273. }
  7274. // By default, the result type is the operand type.
  7275. // Logical not however should cast to a bool.
  7276. QualType resultType = expr->getType();
  7277. if (Opc == UnaryOperatorKind::UO_LNot) {
  7278. UINT rowCount, colCount;
  7279. GetRowsAndColsForAny(expr->getType(), rowCount, colCount);
  7280. resultType = NewSimpleAggregateType(objectKind, AR_BASIC_BOOL, AR_QUAL_CONST, rowCount, colCount);
  7281. StandardConversionSequence standard;
  7282. if (!CanConvert(OpLoc, expr, resultType, false, nullptr, &standard)) {
  7283. m_sema->Diag(OpLoc, diag::err_hlsl_requires_bool_for_not);
  7284. return QualType();
  7285. }
  7286. // Cast argument.
  7287. ExprResult result = m_sema->PerformImplicitConversion(InputExpr.get(), resultType, standard, Sema::AA_Casting, Sema::CCK_ImplicitConversion);
  7288. if (result.isUsable()) {
  7289. InputExpr = result.get();
  7290. }
  7291. }
  7292. bool isPrefix = Opc == UO_PreInc || Opc == UO_PreDec;
  7293. if (isPrefix) {
  7294. VK = VK_LValue;
  7295. return resultType;
  7296. }
  7297. else {
  7298. VK = VK_RValue;
  7299. return resultType.getUnqualifiedType();
  7300. }
  7301. }
  7302. clang::QualType HLSLExternalSource::CheckVectorConditional(
  7303. _In_ ExprResult &Cond,
  7304. _In_ ExprResult &LHS,
  7305. _In_ ExprResult &RHS,
  7306. _In_ SourceLocation QuestionLoc)
  7307. {
  7308. Cond = m_sema->CorrectDelayedTyposInExpr(Cond);
  7309. LHS = m_sema->CorrectDelayedTyposInExpr(LHS);
  7310. RHS = m_sema->CorrectDelayedTyposInExpr(RHS);
  7311. // If either expression is invalid to begin with, propagate that.
  7312. if (Cond.isInvalid() || LHS.isInvalid() || RHS.isInvalid()) {
  7313. return QualType();
  7314. }
  7315. // Gather type info
  7316. QualType condType = GetStructuralForm(Cond.get()->getType());
  7317. QualType leftType = GetStructuralForm(LHS.get()->getType());
  7318. QualType rightType = GetStructuralForm(RHS.get()->getType());
  7319. ArBasicKind condElementKind = GetTypeElementKind(condType);
  7320. ArBasicKind leftElementKind = GetTypeElementKind(leftType);
  7321. ArBasicKind rightElementKind = GetTypeElementKind(rightType);
  7322. ArTypeObjectKind condObjectKind = GetTypeObjectKind(condType);
  7323. ArTypeObjectKind leftObjectKind = GetTypeObjectKind(leftType);
  7324. ArTypeObjectKind rightObjectKind = GetTypeObjectKind(rightType);
  7325. QualType ResultTy = leftType;
  7326. bool condIsSimple = condObjectKind == AR_TOBJ_BASIC || condObjectKind == AR_TOBJ_VECTOR || condObjectKind == AR_TOBJ_MATRIX;
  7327. if (!condIsSimple) {
  7328. m_sema->Diag(QuestionLoc, diag::err_hlsl_conditional_cond_typecheck);
  7329. return QualType();
  7330. }
  7331. UINT rowCountCond, colCountCond;
  7332. GetRowsAndColsForAny(condType, rowCountCond, colCountCond);
  7333. bool leftIsSimple =
  7334. leftObjectKind == AR_TOBJ_BASIC || leftObjectKind == AR_TOBJ_VECTOR ||
  7335. leftObjectKind == AR_TOBJ_MATRIX;
  7336. bool rightIsSimple =
  7337. rightObjectKind == AR_TOBJ_BASIC || rightObjectKind == AR_TOBJ_VECTOR ||
  7338. rightObjectKind == AR_TOBJ_MATRIX;
  7339. if (!leftIsSimple || !rightIsSimple) {
  7340. if (leftObjectKind == AR_TOBJ_OBJECT && leftObjectKind == AR_TOBJ_OBJECT) {
  7341. if (leftType == rightType) {
  7342. return leftType;
  7343. }
  7344. }
  7345. // NOTE: Limiting this operator to working only on basic numeric types.
  7346. // This is due to extremely limited (and even broken) support for any other case.
  7347. // In the future we may decide to support more cases.
  7348. m_sema->Diag(QuestionLoc, diag::err_hlsl_conditional_result_typecheck);
  7349. return QualType();
  7350. }
  7351. // Types should be only scalar, vector, or matrix after this point.
  7352. ArBasicKind resultElementKind = leftElementKind;
  7353. // Combine LHS and RHS element types for computation.
  7354. if (leftElementKind != rightElementKind) {
  7355. if (!CombineBasicTypes(leftElementKind, rightElementKind, &resultElementKind, nullptr, nullptr)) {
  7356. m_sema->Diag(QuestionLoc, diag::err_hlsl_conditional_result_comptype_mismatch);
  7357. return QualType();
  7358. }
  7359. }
  7360. // Combine LHS and RHS dimensions
  7361. if (FAILED(CombineDimensions(leftType, rightType, leftObjectKind, rightObjectKind, &ResultTy))) {
  7362. m_sema->Diag(QuestionLoc, diag::err_hlsl_conditional_result_dimensions);
  7363. return QualType();
  7364. }
  7365. UINT rowCount, colCount;
  7366. GetRowsAndColsForAny(ResultTy, rowCount, colCount);
  7367. // If result is scalar, use condition dimensions.
  7368. // Otherwise, condition must either match or is scalar, then use result dimensions
  7369. if (rowCount * colCount == 1) {
  7370. rowCount = rowCountCond;
  7371. colCount = colCountCond;
  7372. }
  7373. else if (rowCountCond * colCountCond != 1 && (rowCountCond != rowCount || colCountCond != colCount)) {
  7374. m_sema->Diag(QuestionLoc, diag::err_hlsl_conditional_dimensions);
  7375. return QualType();
  7376. }
  7377. // Here, element kind is combined with dimensions for result type.
  7378. ResultTy = NewSimpleAggregateType(AR_TOBJ_INVALID, resultElementKind, 0, rowCount, colCount)->getCanonicalTypeInternal();
  7379. // Cast condition to RValue
  7380. if (Cond.get()->isLValue())
  7381. Cond.set(CreateLValueToRValueCast(Cond.get()));
  7382. // Convert condition component type to bool, using result component dimensions
  7383. if (condElementKind != AR_BASIC_BOOL) {
  7384. Cond = CastExprToTypeNumeric(Cond.get(),
  7385. NewSimpleAggregateType(AR_TOBJ_INVALID, AR_BASIC_BOOL, 0, rowCount, colCount)->getCanonicalTypeInternal());
  7386. }
  7387. // Cast LHS/RHS to RValue
  7388. if (LHS.get()->isLValue())
  7389. LHS.set(CreateLValueToRValueCast(LHS.get()));
  7390. if (RHS.get()->isLValue())
  7391. RHS.set(CreateLValueToRValueCast(RHS.get()));
  7392. // TODO: Why isn't vector truncation being reported?
  7393. if (leftType != ResultTy) {
  7394. LHS = CastExprToTypeNumeric(LHS.get(), ResultTy);
  7395. }
  7396. if (rightType != ResultTy) {
  7397. RHS = CastExprToTypeNumeric(RHS.get(), ResultTy);
  7398. }
  7399. return ResultTy;
  7400. }
  7401. // Apply type specifier sign to the given QualType.
  7402. // Other than privmitive int type, only allow shorthand vectors and matrices to be unsigned.
  7403. clang::QualType HLSLExternalSource::ApplyTypeSpecSignToParsedType(
  7404. _In_ clang::QualType &type, _In_ clang::TypeSpecifierSign TSS,
  7405. _In_ clang::SourceLocation Loc) {
  7406. if (TSS == TypeSpecifierSign::TSS_unspecified) {
  7407. return type;
  7408. }
  7409. DXASSERT(TSS != TypeSpecifierSign::TSS_signed, "else signed keyword is supported in HLSL");
  7410. ArTypeObjectKind objKind = GetTypeObjectKind(type);
  7411. if (objKind != AR_TOBJ_VECTOR && objKind != AR_TOBJ_MATRIX &&
  7412. objKind != AR_TOBJ_BASIC && objKind != AR_TOBJ_ARRAY) {
  7413. return type;
  7414. }
  7415. // check if element type is unsigned and check if such vector exists
  7416. // If not create a new one, Make a QualType of the new kind
  7417. ArBasicKind elementKind = GetTypeElementKind(type);
  7418. // Only ints can have signed/unsigend ty
  7419. if (!IS_BASIC_UNSIGNABLE(elementKind)) {
  7420. return type;
  7421. }
  7422. else {
  7423. // Check given TypeSpecifierSign. If unsigned, change int to uint.
  7424. HLSLScalarType scalarType = ScalarTypeForBasic(elementKind);
  7425. HLSLScalarType newScalarType = MakeUnsigned(scalarType);
  7426. // Get new vector types for a given TypeSpecifierSign.
  7427. if (objKind == AR_TOBJ_VECTOR) {
  7428. UINT colCount = GetHLSLVecSize(type);
  7429. TypedefDecl *qts = LookupVectorShorthandType(newScalarType, colCount);
  7430. return m_context->getTypeDeclType(qts);
  7431. } else if (objKind == AR_TOBJ_MATRIX) {
  7432. UINT rowCount, colCount;
  7433. GetRowsAndCols(type, rowCount, colCount);
  7434. TypedefDecl *qts = LookupMatrixShorthandType(newScalarType, rowCount, colCount);
  7435. return m_context->getTypeDeclType(qts);
  7436. } else {
  7437. DXASSERT_NOMSG(objKind == AR_TOBJ_BASIC || objKind == AR_TOBJ_ARRAY);
  7438. return m_scalarTypes[newScalarType];
  7439. }
  7440. }
  7441. }
  7442. Sema::TemplateDeductionResult HLSLExternalSource::DeduceTemplateArgumentsForHLSL(
  7443. FunctionTemplateDecl *FunctionTemplate,
  7444. TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> Args,
  7445. FunctionDecl *&Specialization, TemplateDeductionInfo &Info)
  7446. {
  7447. DXASSERT_NOMSG(FunctionTemplate != nullptr);
  7448. // Get information about the function we have.
  7449. CXXMethodDecl* functionMethod = dyn_cast<CXXMethodDecl>(FunctionTemplate->getTemplatedDecl());
  7450. DXASSERT(functionMethod != nullptr,
  7451. "otherwise this is standalone function rather than a method, which isn't supported in the HLSL object model");
  7452. CXXRecordDecl* functionParentRecord = functionMethod->getParent();
  7453. DXASSERT(functionParentRecord != nullptr, "otherwise function is orphaned");
  7454. QualType objectElement = GetFirstElementTypeFromDecl(functionParentRecord);
  7455. // Handle subscript overloads.
  7456. if (FunctionTemplate->getDeclName() == m_context->DeclarationNames.getCXXOperatorName(OO_Subscript))
  7457. {
  7458. DeclContext* functionTemplateContext = FunctionTemplate->getDeclContext();
  7459. FindStructBasicTypeResult findResult = FindStructBasicType(functionTemplateContext);
  7460. if (!findResult.Found())
  7461. {
  7462. // This might be a nested type. Do a lookup on the parent.
  7463. CXXRecordDecl* parentRecordType = dyn_cast_or_null<CXXRecordDecl>(functionTemplateContext);
  7464. if (parentRecordType == nullptr || parentRecordType->getDeclContext() == nullptr)
  7465. {
  7466. return Sema::TemplateDeductionResult::TDK_Invalid;
  7467. }
  7468. findResult = FindStructBasicType(parentRecordType->getDeclContext());
  7469. if (!findResult.Found())
  7470. {
  7471. return Sema::TemplateDeductionResult::TDK_Invalid;
  7472. }
  7473. DXASSERT(
  7474. parentRecordType->getDeclContext()->getDeclKind() == Decl::Kind::CXXRecord ||
  7475. parentRecordType->getDeclContext()->getDeclKind() == Decl::Kind::ClassTemplateSpecialization,
  7476. "otherwise FindStructBasicType should have failed - no other types are allowed");
  7477. objectElement = GetFirstElementTypeFromDecl(
  7478. cast<CXXRecordDecl>(parentRecordType->getDeclContext()));
  7479. }
  7480. Specialization = AddSubscriptSpecialization(FunctionTemplate, objectElement, findResult);
  7481. DXASSERT_NOMSG(Specialization->getPrimaryTemplate()->getCanonicalDecl() ==
  7482. FunctionTemplate->getCanonicalDecl());
  7483. return Sema::TemplateDeductionResult::TDK_Success;
  7484. }
  7485. // Reject overload lookups that aren't identifier-based.
  7486. if (!FunctionTemplate->getDeclName().isIdentifier())
  7487. {
  7488. return Sema::TemplateDeductionResult::TDK_NonDeducedMismatch;
  7489. }
  7490. // Find the table of intrinsics based on the object type.
  7491. const HLSL_INTRINSIC* intrinsics;
  7492. size_t intrinsicCount;
  7493. const char* objectName;
  7494. FindIntrinsicTable(FunctionTemplate->getDeclContext(), &objectName, &intrinsics, &intrinsicCount);
  7495. DXASSERT(intrinsics != nullptr,
  7496. "otherwise FindIntrinsicTable failed to lookup a valid object, "
  7497. "or the parser let a user-defined template object through");
  7498. // Look for an intrinsic for which we can match arguments.
  7499. size_t argCount;
  7500. QualType argTypes[g_MaxIntrinsicParamCount + 1];
  7501. StringRef nameIdentifier = FunctionTemplate->getName();
  7502. IntrinsicDefIter cursor = FindIntrinsicByNameAndArgCount(intrinsics, intrinsicCount, objectName, nameIdentifier, Args.size());
  7503. IntrinsicDefIter end = IntrinsicDefIter::CreateEnd(intrinsics, intrinsicCount, IntrinsicTableDefIter::CreateEnd(m_intrinsicTables));
  7504. while (cursor != end)
  7505. {
  7506. if (!MatchArguments(*cursor, objectElement, Args, argTypes, &argCount))
  7507. {
  7508. ++cursor;
  7509. continue;
  7510. }
  7511. // Currently only intrinsic we allow for explicit template arguments are
  7512. // for Load return types for ByteAddressBuffer/RWByteAddressBuffer
  7513. // TODO: handle template arguments for future intrinsics in a more natural way
  7514. // Check Explicit template arguments
  7515. UINT intrinsicOp = (*cursor)->Op;
  7516. LPCSTR intrinsicName = (*cursor)->pArgs[0].pName;
  7517. bool Is2018 = getSema()->getLangOpts().HLSLVersion >= 2018;
  7518. bool IsBAB =
  7519. objectName == g_ArBasicTypeNames[AR_OBJECT_BYTEADDRESS_BUFFER] ||
  7520. objectName == g_ArBasicTypeNames[AR_OBJECT_RWBYTEADDRESS_BUFFER];
  7521. bool IsBABLoad = IsBAB && intrinsicOp == (UINT)IntrinsicOp::MOP_Load;
  7522. bool IsBABStore = IsBAB && intrinsicOp == (UINT)IntrinsicOp::MOP_Store;
  7523. if (ExplicitTemplateArgs && ExplicitTemplateArgs->size() > 0) {
  7524. bool isLegalTemplate = false;
  7525. SourceLocation Loc = ExplicitTemplateArgs->getLAngleLoc();
  7526. auto TemplateDiag =
  7527. !IsBABLoad
  7528. ? diag::err_hlsl_intrinsic_template_arg_unsupported
  7529. : !Is2018 ? diag::err_hlsl_intrinsic_template_arg_requires_2018
  7530. : diag::err_hlsl_intrinsic_template_arg_requires_2018;
  7531. if (IsBABLoad && Is2018 && ExplicitTemplateArgs->size() == 1) {
  7532. Loc = (*ExplicitTemplateArgs)[0].getLocation();
  7533. QualType explicitType = (*ExplicitTemplateArgs)[0].getArgument().getAsType();
  7534. ArTypeObjectKind explicitKind = GetTypeObjectKind(explicitType);
  7535. if (explicitKind == AR_TOBJ_BASIC || explicitKind == AR_TOBJ_VECTOR) {
  7536. isLegalTemplate = GET_BASIC_BITS(GetTypeElementKind(explicitType)) != BPROP_BITS64 ||
  7537. GetNumElements(explicitType) <= 2;
  7538. }
  7539. if (isLegalTemplate) {
  7540. argTypes[0] = explicitType;
  7541. }
  7542. }
  7543. if (!isLegalTemplate) {
  7544. getSema()->Diag(Loc, TemplateDiag) << intrinsicName;
  7545. return Sema::TemplateDeductionResult::TDK_Invalid;
  7546. }
  7547. } else if (IsBABStore) {
  7548. // Prior to HLSL 2018, Store operation only stored scalar uint.
  7549. if (!Is2018) {
  7550. if (GetNumElements(argTypes[2]) != 1) {
  7551. getSema()->Diag(Args[1]->getLocStart(),
  7552. diag::err_ovl_no_viable_member_function_in_call)
  7553. << intrinsicName;
  7554. return Sema::TemplateDeductionResult::TDK_Invalid;
  7555. }
  7556. argTypes[2] = getSema()->getASTContext().getIntTypeForBitwidth(
  7557. 32, /*signed*/ false);
  7558. } else {
  7559. // not supporting types > 16 bytes yet.
  7560. if (GET_BASIC_BITS(GetTypeElementKind(argTypes[2])) == BPROP_BITS64 &&
  7561. GetNumElements(argTypes[2]) > 2) {
  7562. getSema()->Diag(Args[1]->getLocStart(),
  7563. diag::err_ovl_no_viable_member_function_in_call)
  7564. << intrinsicName;
  7565. return Sema::TemplateDeductionResult::TDK_Invalid;
  7566. }
  7567. }
  7568. }
  7569. Specialization = AddHLSLIntrinsicMethod(cursor.GetTableName(), cursor.GetLoweringStrategy(), *cursor, FunctionTemplate, Args, argTypes, argCount);
  7570. DXASSERT_NOMSG(Specialization->getPrimaryTemplate()->getCanonicalDecl() ==
  7571. FunctionTemplate->getCanonicalDecl());
  7572. if (!IsValidateObjectElement(*cursor, objectElement)) {
  7573. m_sema->Diag(Args[0]->getExprLoc(), diag::err_hlsl_invalid_resource_type_on_intrinsic) <<
  7574. nameIdentifier << g_ArBasicTypeNames[GetTypeElementKind(objectElement)];
  7575. }
  7576. return Sema::TemplateDeductionResult::TDK_Success;
  7577. }
  7578. return Sema::TemplateDeductionResult::TDK_NonDeducedMismatch;
  7579. }
  7580. void HLSLExternalSource::DiagnoseAssignmentResultForHLSL(
  7581. Sema::AssignConvertType ConvTy,
  7582. SourceLocation Loc,
  7583. QualType DstType, QualType SrcType,
  7584. _In_ Expr *SrcExpr, Sema::AssignmentAction Action,
  7585. _Out_opt_ bool *Complained)
  7586. {
  7587. if (Complained) *Complained = false;
  7588. // No work to do if there is not type change.
  7589. if (DstType == SrcType) {
  7590. return;
  7591. }
  7592. // Don't generate a warning if the user is casting explicitly
  7593. // or if initializing - our initialization handling already emits this.
  7594. if (Action == Sema::AssignmentAction::AA_Casting ||
  7595. Action == Sema::AssignmentAction::AA_Initializing) {
  7596. return;
  7597. }
  7598. ArBasicKind src = BasicTypeForScalarType(SrcType->getCanonicalTypeUnqualified());
  7599. if (src == AR_BASIC_UNKNOWN || src == AR_BASIC_BOOL) {
  7600. return;
  7601. }
  7602. ArBasicKind dst = BasicTypeForScalarType(DstType->getCanonicalTypeUnqualified());
  7603. if (dst == AR_BASIC_UNKNOWN) {
  7604. return;
  7605. }
  7606. bool warnAboutNarrowing = false;
  7607. switch (dst) {
  7608. case AR_BASIC_FLOAT32:
  7609. case AR_BASIC_INT32:
  7610. case AR_BASIC_UINT32:
  7611. case AR_BASIC_FLOAT16:
  7612. warnAboutNarrowing = src == AR_BASIC_FLOAT64;
  7613. break;
  7614. case AR_BASIC_MIN16FLOAT:
  7615. warnAboutNarrowing = (src == AR_BASIC_INT32 || src == AR_BASIC_UINT32 || src == AR_BASIC_FLOAT32 || src == AR_BASIC_FLOAT64);
  7616. break;
  7617. case AR_BASIC_MIN16INT:
  7618. case AR_BASIC_MIN16UINT:
  7619. case AR_BASIC_MIN12INT:
  7620. case AR_BASIC_MIN10FLOAT:
  7621. warnAboutNarrowing = (src == AR_BASIC_INT32 || src == AR_BASIC_UINT32 || src == AR_BASIC_FLOAT32 || src == AR_BASIC_FLOAT64);
  7622. break;
  7623. default:
  7624. // No other destination types result in narrowing.
  7625. break;
  7626. }
  7627. // fxc errors looked like this:
  7628. // warning X3205: conversion from larger type to smaller, possible loss of data
  7629. if (warnAboutNarrowing) {
  7630. m_sema->Diag(Loc, diag::warn_hlsl_narrowing) << SrcType << DstType;
  7631. AssignOpt(true, Complained);
  7632. }
  7633. }
  7634. void HLSLExternalSource::ReportUnsupportedTypeNesting(SourceLocation loc, QualType type)
  7635. {
  7636. m_sema->Diag(loc, diag::err_hlsl_unsupported_type_nesting) << type;
  7637. }
  7638. bool HLSLExternalSource::TryStaticCastForHLSL(ExprResult &SrcExpr,
  7639. QualType DestType,
  7640. Sema::CheckedConversionKind CCK,
  7641. const SourceRange &OpRange, unsigned &msg,
  7642. CastKind &Kind, CXXCastPath &BasePath,
  7643. bool ListInitialization, bool SuppressWarnings, bool SuppressErrors,
  7644. _Inout_opt_ StandardConversionSequence* standard)
  7645. {
  7646. DXASSERT(!SrcExpr.isInvalid(), "caller should check for invalid expressions and placeholder types");
  7647. bool explicitConversion
  7648. = (CCK == Sema::CCK_CStyleCast || CCK == Sema::CCK_FunctionalCast);
  7649. bool suppressWarnings = explicitConversion || SuppressWarnings;
  7650. SourceLocation loc = OpRange.getBegin();
  7651. if (ValidateCast(loc, SrcExpr.get(), DestType, explicitConversion, suppressWarnings, SuppressErrors, standard)) {
  7652. // TODO: LValue to RValue cast was all that CanConvert (ValidateCast) did anyway,
  7653. // so do this here until we figure out why this is needed.
  7654. if (standard && standard->First == ICK_Lvalue_To_Rvalue) {
  7655. SrcExpr.set(CreateLValueToRValueCast(SrcExpr.get()));
  7656. }
  7657. return true;
  7658. }
  7659. // ValidateCast includes its own error messages.
  7660. msg = 0;
  7661. return false;
  7662. }
  7663. /// <summary>
  7664. /// Checks if a subscript index argument can be initialized from the given expression.
  7665. /// </summary>
  7666. /// <param name="SrcExpr">Source expression used as argument.</param>
  7667. /// <param name="DestType">Parameter type to initialize.</param>
  7668. /// <remarks>
  7669. /// Rules for subscript index initialization follow regular implicit casting rules, with the exception that
  7670. /// no changes in arity are allowed (i.e., int2 can become uint2, but uint or uint3 cannot).
  7671. /// </remarks>
  7672. ImplicitConversionSequence
  7673. HLSLExternalSource::TrySubscriptIndexInitialization(_In_ clang::Expr *SrcExpr,
  7674. clang::QualType DestType) {
  7675. DXASSERT_NOMSG(SrcExpr != nullptr);
  7676. DXASSERT_NOMSG(!DestType.isNull());
  7677. unsigned int msg = 0;
  7678. CastKind kind;
  7679. CXXCastPath path;
  7680. ImplicitConversionSequence sequence;
  7681. sequence.setStandard();
  7682. ExprResult sourceExpr(SrcExpr);
  7683. if (GetElementCount(SrcExpr->getType()) != GetElementCount(DestType)) {
  7684. sequence.setBad(BadConversionSequence::FailureKind::no_conversion,
  7685. SrcExpr->getType(), DestType);
  7686. } else if (!TryStaticCastForHLSL(
  7687. sourceExpr, DestType, Sema::CCK_ImplicitConversion, NoRange,
  7688. msg, kind, path, ListInitializationFalse,
  7689. SuppressWarningsFalse, SuppressErrorsTrue, &sequence.Standard)) {
  7690. sequence.setBad(BadConversionSequence::FailureKind::no_conversion,
  7691. SrcExpr->getType(), DestType);
  7692. }
  7693. return sequence;
  7694. }
  7695. template <typename T>
  7696. static
  7697. bool IsValueInRange(T value, T minValue, T maxValue) {
  7698. return minValue <= value && value <= maxValue;
  7699. }
  7700. #define D3DX_16F_MAX 6.550400e+004 // max value
  7701. #define D3DX_16F_MIN 6.1035156e-5f // min positive value
  7702. static
  7703. void GetFloatLimits(ArBasicKind basicKind, double* minValue, double* maxValue)
  7704. {
  7705. DXASSERT_NOMSG(minValue != nullptr);
  7706. DXASSERT_NOMSG(maxValue != nullptr);
  7707. switch (basicKind) {
  7708. case AR_BASIC_MIN10FLOAT:
  7709. case AR_BASIC_MIN16FLOAT:
  7710. case AR_BASIC_FLOAT16: *minValue = -(D3DX_16F_MIN); *maxValue = D3DX_16F_MAX; return;
  7711. case AR_BASIC_FLOAT32_PARTIAL_PRECISION:
  7712. case AR_BASIC_FLOAT32: *minValue = -(FLT_MIN); *maxValue = FLT_MAX; return;
  7713. case AR_BASIC_FLOAT64: *minValue = -(DBL_MIN); *maxValue = DBL_MAX; return;
  7714. default:
  7715. // No other float types.
  7716. break;
  7717. }
  7718. DXASSERT(false, "unreachable");
  7719. *minValue = 0; *maxValue = 0;
  7720. return;
  7721. }
  7722. static
  7723. void GetUnsignedLimit(ArBasicKind basicKind, uint64_t* maxValue)
  7724. {
  7725. DXASSERT_NOMSG(maxValue != nullptr);
  7726. switch (basicKind) {
  7727. case AR_BASIC_BOOL: *maxValue = 1; return;
  7728. case AR_BASIC_UINT8: *maxValue = UINT8_MAX; return;
  7729. case AR_BASIC_MIN16UINT:
  7730. case AR_BASIC_UINT16: *maxValue = UINT16_MAX; return;
  7731. case AR_BASIC_UINT32: *maxValue = UINT32_MAX; return;
  7732. case AR_BASIC_UINT64: *maxValue = UINT64_MAX; return;
  7733. default:
  7734. // No other unsigned int types.
  7735. break;
  7736. }
  7737. DXASSERT(false, "unreachable");
  7738. *maxValue = 0;
  7739. return;
  7740. }
  7741. static
  7742. void GetSignedLimits(ArBasicKind basicKind, int64_t* minValue, int64_t* maxValue)
  7743. {
  7744. DXASSERT_NOMSG(minValue != nullptr);
  7745. DXASSERT_NOMSG(maxValue != nullptr);
  7746. switch (basicKind) {
  7747. case AR_BASIC_INT8: *minValue = INT8_MIN; *maxValue = INT8_MAX; return;
  7748. case AR_BASIC_MIN12INT:
  7749. case AR_BASIC_MIN16INT:
  7750. case AR_BASIC_INT16: *minValue = INT16_MIN; *maxValue = INT16_MAX; return;
  7751. case AR_BASIC_INT32: *minValue = INT32_MIN; *maxValue = INT32_MAX; return;
  7752. case AR_BASIC_INT64: *minValue = INT64_MIN; *maxValue = INT64_MAX; return;
  7753. default:
  7754. // No other signed int types.
  7755. break;
  7756. }
  7757. DXASSERT(false, "unreachable");
  7758. *minValue = 0; *maxValue = 0;
  7759. return;
  7760. }
  7761. static
  7762. bool IsValueInBasicRange(ArBasicKind basicKind, const APValue& value)
  7763. {
  7764. if (IS_BASIC_FLOAT(basicKind)) {
  7765. double val;
  7766. if (value.isInt()) {
  7767. val = value.getInt().getLimitedValue();
  7768. } else if (value.isFloat()) {
  7769. llvm::APFloat floatValue = value.getFloat();
  7770. if (!floatValue.isFinite()) {
  7771. return false;
  7772. }
  7773. llvm::APFloat valueFloat = value.getFloat();
  7774. if (&valueFloat.getSemantics() == &llvm::APFloat::IEEEsingle) {
  7775. val = value.getFloat().convertToFloat();
  7776. }
  7777. else {
  7778. val = value.getFloat().convertToDouble();
  7779. }
  7780. } else {
  7781. return false;
  7782. }
  7783. double minValue, maxValue;
  7784. GetFloatLimits(basicKind, &minValue, &maxValue);
  7785. return IsValueInRange(val, minValue, maxValue);
  7786. }
  7787. else if (IS_BASIC_SINT(basicKind)) {
  7788. if (!value.isInt()) {
  7789. return false;
  7790. }
  7791. int64_t val = value.getInt().getSExtValue();
  7792. int64_t minValue, maxValue;
  7793. GetSignedLimits(basicKind, &minValue, &maxValue);
  7794. return IsValueInRange(val, minValue, maxValue);
  7795. }
  7796. else if (IS_BASIC_UINT(basicKind) || IS_BASIC_BOOL(basicKind)) {
  7797. if (!value.isInt()) {
  7798. return false;
  7799. }
  7800. uint64_t val = value.getInt().getLimitedValue();
  7801. uint64_t maxValue;
  7802. GetUnsignedLimit(basicKind, &maxValue);
  7803. return IsValueInRange(val, (uint64_t)0, maxValue);
  7804. }
  7805. else {
  7806. return false;
  7807. }
  7808. }
  7809. static
  7810. bool IsPrecisionLossIrrelevant(ASTContext& Ctx, _In_ const Expr* sourceExpr, QualType targetType, ArBasicKind targetKind)
  7811. {
  7812. DXASSERT_NOMSG(!targetType.isNull());
  7813. DXASSERT_NOMSG(sourceExpr != nullptr);
  7814. Expr::EvalResult evalResult;
  7815. if (sourceExpr->EvaluateAsRValue(evalResult, Ctx)) {
  7816. if (evalResult.Diag == nullptr || evalResult.Diag->empty()) {
  7817. return IsValueInBasicRange(targetKind, evalResult.Val);
  7818. }
  7819. }
  7820. return false;
  7821. }
  7822. bool HLSLExternalSource::ValidateCast(
  7823. SourceLocation OpLoc,
  7824. _In_ Expr* sourceExpr,
  7825. QualType target,
  7826. bool explicitConversion,
  7827. bool suppressWarnings,
  7828. bool suppressErrors,
  7829. _Inout_opt_ StandardConversionSequence* standard)
  7830. {
  7831. DXASSERT_NOMSG(sourceExpr != nullptr);
  7832. QualType source = sourceExpr->getType();
  7833. TYPE_CONVERSION_REMARKS remarks;
  7834. if (!CanConvert(OpLoc, sourceExpr, target, explicitConversion, &remarks, standard))
  7835. {
  7836. const bool IsOutputParameter = false;
  7837. //
  7838. // Check whether the lack of explicit-ness matters.
  7839. //
  7840. // Setting explicitForDiagnostics to true in that case will avoid the message
  7841. // saying anything about the implicit nature of the cast, when adding the
  7842. // explicit cast won't make a difference.
  7843. //
  7844. bool explicitForDiagnostics = explicitConversion;
  7845. if (explicitConversion == false)
  7846. {
  7847. if (!CanConvert(OpLoc, sourceExpr, target, true, &remarks, nullptr))
  7848. {
  7849. // Can't convert either way - implicit/explicit doesn't matter.
  7850. explicitForDiagnostics = true;
  7851. }
  7852. }
  7853. if (!suppressErrors)
  7854. {
  7855. m_sema->Diag(OpLoc, diag::err_hlsl_cannot_convert)
  7856. << explicitForDiagnostics << IsOutputParameter << source << target;
  7857. }
  7858. return false;
  7859. }
  7860. if (!suppressWarnings)
  7861. {
  7862. if (!explicitConversion)
  7863. {
  7864. if ((remarks & TYPE_CONVERSION_PRECISION_LOSS) != 0)
  7865. {
  7866. // This is a much more restricted version of the analysis does
  7867. // StandardConversionSequence::getNarrowingKind
  7868. if (!IsPrecisionLossIrrelevant(*m_context, sourceExpr, target, GetTypeElementKind(target)))
  7869. {
  7870. m_sema->Diag(OpLoc, diag::warn_hlsl_narrowing) << source << target;
  7871. }
  7872. }
  7873. if ((remarks & TYPE_CONVERSION_ELT_TRUNCATION) != 0)
  7874. {
  7875. m_sema->Diag(OpLoc, diag::warn_hlsl_implicit_vector_truncation);
  7876. }
  7877. }
  7878. }
  7879. return true;
  7880. }
  7881. ////////////////////////////////////////////////////////////////////////////////
  7882. // Functions exported from this translation unit. //
  7883. /// <summary>Performs HLSL-specific processing for unary operators.</summary>
  7884. QualType hlsl::CheckUnaryOpForHLSL(Sema& self,
  7885. SourceLocation OpLoc,
  7886. UnaryOperatorKind Opc,
  7887. ExprResult& InputExpr,
  7888. ExprValueKind& VK,
  7889. ExprObjectKind& OK)
  7890. {
  7891. ExternalSemaSource* externalSource = self.getExternalSource();
  7892. if (externalSource == nullptr) {
  7893. return QualType();
  7894. }
  7895. HLSLExternalSource* hlsl = reinterpret_cast<HLSLExternalSource*>(externalSource);
  7896. return hlsl->CheckUnaryOpForHLSL(OpLoc, Opc, InputExpr, VK, OK);
  7897. }
  7898. /// <summary>Performs HLSL-specific processing for binary operators.</summary>
  7899. void hlsl::CheckBinOpForHLSL(Sema& self,
  7900. SourceLocation OpLoc,
  7901. BinaryOperatorKind Opc,
  7902. ExprResult& LHS,
  7903. ExprResult& RHS,
  7904. QualType& ResultTy,
  7905. QualType& CompLHSTy,
  7906. QualType& CompResultTy)
  7907. {
  7908. ExternalSemaSource* externalSource = self.getExternalSource();
  7909. if (externalSource == nullptr) {
  7910. return;
  7911. }
  7912. HLSLExternalSource* hlsl = reinterpret_cast<HLSLExternalSource*>(externalSource);
  7913. return hlsl->CheckBinOpForHLSL(OpLoc, Opc, LHS, RHS, ResultTy, CompLHSTy, CompResultTy);
  7914. }
  7915. /// <summary>Performs HLSL-specific processing of template declarations.</summary>
  7916. bool hlsl::CheckTemplateArgumentListForHLSL(Sema& self, TemplateDecl* Template, SourceLocation TemplateLoc, TemplateArgumentListInfo& TemplateArgList)
  7917. {
  7918. DXASSERT_NOMSG(Template != nullptr);
  7919. ExternalSemaSource* externalSource = self.getExternalSource();
  7920. if (externalSource == nullptr) {
  7921. return false;
  7922. }
  7923. HLSLExternalSource* hlsl = reinterpret_cast<HLSLExternalSource*>(externalSource);
  7924. return hlsl->CheckTemplateArgumentListForHLSL(Template, TemplateLoc, TemplateArgList);
  7925. }
  7926. /// <summary>Deduces template arguments on a function call in an HLSL program.</summary>
  7927. Sema::TemplateDeductionResult hlsl::DeduceTemplateArgumentsForHLSL(Sema* self,
  7928. FunctionTemplateDecl *FunctionTemplate,
  7929. TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> Args,
  7930. FunctionDecl *&Specialization, TemplateDeductionInfo &Info)
  7931. {
  7932. return HLSLExternalSource::FromSema(self)
  7933. ->DeduceTemplateArgumentsForHLSL(FunctionTemplate, ExplicitTemplateArgs, Args, Specialization, Info);
  7934. }
  7935. void hlsl::DiagnoseAssignmentResultForHLSL(Sema* self,
  7936. Sema::AssignConvertType ConvTy,
  7937. SourceLocation Loc,
  7938. QualType DstType, QualType SrcType,
  7939. Expr *SrcExpr, Sema::AssignmentAction Action,
  7940. bool *Complained)
  7941. {
  7942. return HLSLExternalSource::FromSema(self)
  7943. ->DiagnoseAssignmentResultForHLSL(ConvTy, Loc, DstType, SrcType, SrcExpr, Action, Complained);
  7944. }
  7945. void hlsl::DiagnoseControlFlowConditionForHLSL(Sema *self, Expr *condExpr, StringRef StmtName) {
  7946. while (ImplicitCastExpr *IC = dyn_cast<ImplicitCastExpr>(condExpr)) {
  7947. if (IC->getCastKind() == CastKind::CK_HLSLMatrixTruncationCast ||
  7948. IC->getCastKind() == CastKind::CK_HLSLVectorTruncationCast) {
  7949. self->Diag(condExpr->getLocStart(),
  7950. diag::err_hlsl_control_flow_cond_not_scalar)
  7951. << StmtName;
  7952. return;
  7953. }
  7954. condExpr = IC->getSubExpr();
  7955. }
  7956. }
  7957. static bool ShaderModelsMatch(const StringRef& left, const StringRef& right)
  7958. {
  7959. // TODO: handle shorthand cases.
  7960. return left.size() == 0 || right.size() == 0 || left.equals(right);
  7961. }
  7962. void hlsl::DiagnosePackingOffset(
  7963. clang::Sema* self,
  7964. SourceLocation loc,
  7965. clang::QualType type,
  7966. int componentOffset)
  7967. {
  7968. DXASSERT_NOMSG(0 <= componentOffset && componentOffset <= 3);
  7969. if (componentOffset > 0) {
  7970. HLSLExternalSource* source = HLSLExternalSource::FromSema(self);
  7971. ArBasicKind element = source->GetTypeElementKind(type);
  7972. ArTypeObjectKind shape = source->GetTypeObjectKind(type);
  7973. // Only perform some simple validation for now.
  7974. if (IsObjectKindPrimitiveAggregate(shape) && IsBasicKindNumeric(element)) {
  7975. int count = GetElementCount(type);
  7976. if (count > (4 - componentOffset)) {
  7977. self->Diag(loc, diag::err_hlsl_register_or_offset_bind_not_valid);
  7978. }
  7979. }
  7980. }
  7981. }
  7982. void hlsl::DiagnoseRegisterType(
  7983. clang::Sema* self,
  7984. clang::SourceLocation loc,
  7985. clang::QualType type,
  7986. char registerType)
  7987. {
  7988. HLSLExternalSource* source = HLSLExternalSource::FromSema(self);
  7989. ArBasicKind element = source->GetTypeElementKind(type);
  7990. StringRef expected("none");
  7991. bool isValid = true;
  7992. bool isWarning = false;
  7993. switch (element)
  7994. {
  7995. case AR_BASIC_BOOL:
  7996. case AR_BASIC_LITERAL_FLOAT:
  7997. case AR_BASIC_FLOAT16:
  7998. case AR_BASIC_FLOAT32_PARTIAL_PRECISION:
  7999. case AR_BASIC_FLOAT32:
  8000. case AR_BASIC_FLOAT64:
  8001. case AR_BASIC_LITERAL_INT:
  8002. case AR_BASIC_INT8:
  8003. case AR_BASIC_UINT8:
  8004. case AR_BASIC_INT16:
  8005. case AR_BASIC_UINT16:
  8006. case AR_BASIC_INT32:
  8007. case AR_BASIC_UINT32:
  8008. case AR_BASIC_INT64:
  8009. case AR_BASIC_UINT64:
  8010. case AR_BASIC_MIN10FLOAT:
  8011. case AR_BASIC_MIN16FLOAT:
  8012. case AR_BASIC_MIN12INT:
  8013. case AR_BASIC_MIN16INT:
  8014. case AR_BASIC_MIN16UINT:
  8015. expected = "'b', 'c', or 'i'";
  8016. isValid = registerType == 'b' || registerType == 'c' || registerType == 'i' ||
  8017. registerType == 'B' || registerType == 'C' || registerType == 'I';
  8018. break;
  8019. case AR_OBJECT_TEXTURE1D:
  8020. case AR_OBJECT_TEXTURE1D_ARRAY:
  8021. case AR_OBJECT_TEXTURE2D:
  8022. case AR_OBJECT_TEXTURE2D_ARRAY:
  8023. case AR_OBJECT_TEXTURE3D:
  8024. case AR_OBJECT_TEXTURECUBE:
  8025. case AR_OBJECT_TEXTURECUBE_ARRAY:
  8026. case AR_OBJECT_TEXTURE2DMS:
  8027. case AR_OBJECT_TEXTURE2DMS_ARRAY:
  8028. expected = "'t' or 's'";
  8029. isValid = registerType == 't' || registerType == 's' ||
  8030. registerType == 'T' || registerType == 'S';
  8031. break;
  8032. case AR_OBJECT_SAMPLER:
  8033. case AR_OBJECT_SAMPLER1D:
  8034. case AR_OBJECT_SAMPLER2D:
  8035. case AR_OBJECT_SAMPLER3D:
  8036. case AR_OBJECT_SAMPLERCUBE:
  8037. case AR_OBJECT_SAMPLERCOMPARISON:
  8038. expected = "'s' or 't'";
  8039. isValid = registerType == 's' || registerType == 't' ||
  8040. registerType == 'S' || registerType == 'T';
  8041. break;
  8042. case AR_OBJECT_BUFFER:
  8043. expected = "'t'";
  8044. isValid = registerType == 't' || registerType == 'T';
  8045. break;
  8046. case AR_OBJECT_POINTSTREAM:
  8047. case AR_OBJECT_LINESTREAM:
  8048. case AR_OBJECT_TRIANGLESTREAM:
  8049. isValid = false;
  8050. isWarning = true;
  8051. break;
  8052. case AR_OBJECT_INPUTPATCH:
  8053. case AR_OBJECT_OUTPUTPATCH:
  8054. isValid = false;
  8055. isWarning = true;
  8056. break;
  8057. case AR_OBJECT_RWTEXTURE1D:
  8058. case AR_OBJECT_RWTEXTURE1D_ARRAY:
  8059. case AR_OBJECT_RWTEXTURE2D:
  8060. case AR_OBJECT_RWTEXTURE2D_ARRAY:
  8061. case AR_OBJECT_RWTEXTURE3D:
  8062. case AR_OBJECT_RWBUFFER:
  8063. expected = "'u'";
  8064. isValid = registerType == 'u' || registerType == 'U';
  8065. break;
  8066. case AR_OBJECT_BYTEADDRESS_BUFFER:
  8067. case AR_OBJECT_STRUCTURED_BUFFER:
  8068. expected = "'t'";
  8069. isValid = registerType == 't' || registerType == 'T';
  8070. break;
  8071. case AR_OBJECT_CONSUME_STRUCTURED_BUFFER:
  8072. case AR_OBJECT_RWBYTEADDRESS_BUFFER:
  8073. case AR_OBJECT_RWSTRUCTURED_BUFFER:
  8074. case AR_OBJECT_RWSTRUCTURED_BUFFER_ALLOC:
  8075. case AR_OBJECT_RWSTRUCTURED_BUFFER_CONSUME:
  8076. case AR_OBJECT_APPEND_STRUCTURED_BUFFER:
  8077. expected = "'u'";
  8078. isValid = registerType == 'u' || registerType == 'U';
  8079. break;
  8080. case AR_OBJECT_CONSTANT_BUFFER:
  8081. expected = "'b'";
  8082. isValid = registerType == 'b' || registerType == 'B';
  8083. break;
  8084. case AR_OBJECT_TEXTURE_BUFFER:
  8085. expected = "'t'";
  8086. isValid = registerType == 't' || registerType == 'T';
  8087. break;
  8088. case AR_OBJECT_ROVBUFFER:
  8089. case AR_OBJECT_ROVBYTEADDRESS_BUFFER:
  8090. case AR_OBJECT_ROVSTRUCTURED_BUFFER:
  8091. case AR_OBJECT_ROVTEXTURE1D:
  8092. case AR_OBJECT_ROVTEXTURE1D_ARRAY:
  8093. case AR_OBJECT_ROVTEXTURE2D:
  8094. case AR_OBJECT_ROVTEXTURE2D_ARRAY:
  8095. case AR_OBJECT_ROVTEXTURE3D:
  8096. expected = "'u'";
  8097. isValid = registerType == 'u' || registerType == 'U';
  8098. break;
  8099. case AR_OBJECT_LEGACY_EFFECT: // Used for all unsupported but ignored legacy effect types
  8100. isWarning = true;
  8101. break; // So we don't care what you tried to bind it to
  8102. default: // Other types have no associated registers.
  8103. break;
  8104. }
  8105. // fxc is inconsistent as to when it reports an error and when it ignores invalid bind semantics, so emit
  8106. // a warning instead.
  8107. if (!isValid)
  8108. {
  8109. if (isWarning)
  8110. self->Diag(loc, diag::warn_hlsl_incorrect_bind_semantic) << expected;
  8111. else
  8112. self->Diag(loc, diag::err_hlsl_incorrect_bind_semantic) << expected;
  8113. }
  8114. }
  8115. struct NameLookup {
  8116. FunctionDecl *Found;
  8117. FunctionDecl *Other;
  8118. };
  8119. static NameLookup GetSingleFunctionDeclByName(clang::Sema *self, StringRef Name, bool checkPatch) {
  8120. auto DN = DeclarationName(&self->getASTContext().Idents.get(Name));
  8121. FunctionDecl *pFoundDecl = nullptr;
  8122. for (auto idIter = self->IdResolver.begin(DN), idEnd = self->IdResolver.end(); idIter != idEnd; ++idIter) {
  8123. FunctionDecl *pFnDecl = dyn_cast<FunctionDecl>(*idIter);
  8124. if (!pFnDecl) continue;
  8125. if (checkPatch && !self->getASTContext().IsPatchConstantFunctionDecl(pFnDecl)) continue;
  8126. if (pFoundDecl) {
  8127. return NameLookup{ pFoundDecl, pFnDecl };
  8128. }
  8129. pFoundDecl = pFnDecl;
  8130. }
  8131. return NameLookup{ pFoundDecl, nullptr };
  8132. }
  8133. void hlsl::DiagnoseTranslationUnit(clang::Sema *self) {
  8134. DXASSERT_NOMSG(self != nullptr);
  8135. // Don't bother with global validation if compilation has already failed.
  8136. if (self->getDiagnostics().hasErrorOccurred()) {
  8137. return;
  8138. }
  8139. // Don't check entry function for library.
  8140. if (self->getLangOpts().IsHLSLLibrary) {
  8141. // TODO: validate no recursion start from every function.
  8142. return;
  8143. }
  8144. // TODO: make these error 'real' errors rather than on-the-fly things
  8145. // Validate that the entry point is available.
  8146. DiagnosticsEngine &Diags = self->getDiagnostics();
  8147. FunctionDecl *pEntryPointDecl = nullptr;
  8148. FunctionDecl *pPatchFnDecl = nullptr;
  8149. const std::string &EntryPointName = self->getLangOpts().HLSLEntryFunction;
  8150. if (!EntryPointName.empty()) {
  8151. NameLookup NL = GetSingleFunctionDeclByName(self, EntryPointName, /*checkPatch*/ false);
  8152. if (NL.Found && NL.Other) {
  8153. // NOTE: currently we cannot hit this codepath when CodeGen is enabled, because
  8154. // CodeGenModule::getMangledName will mangle the entry point name into the bare
  8155. // string, and so ambiguous points will produce an error earlier on.
  8156. unsigned id = Diags.getCustomDiagID(clang::DiagnosticsEngine::Level::Error,
  8157. "ambiguous entry point function");
  8158. Diags.Report(NL.Found->getSourceRange().getBegin(), id);
  8159. Diags.Report(NL.Other->getLocation(), diag::note_previous_definition);
  8160. return;
  8161. }
  8162. pEntryPointDecl = NL.Found;
  8163. if (!pEntryPointDecl || !pEntryPointDecl->hasBody()) {
  8164. unsigned id = Diags.getCustomDiagID(clang::DiagnosticsEngine::Level::Error,
  8165. "missing entry point definition");
  8166. Diags.Report(id);
  8167. return;
  8168. }
  8169. }
  8170. // Validate that there is no recursion; start with the entry function.
  8171. // NOTE: the information gathered here could be used to bypass code generation
  8172. // on functions that are unreachable (as an early form of dead code elimination).
  8173. if (pEntryPointDecl) {
  8174. const auto *shaderModel =
  8175. hlsl::ShaderModel::GetByName(self->getLangOpts().HLSLProfile.c_str());
  8176. if (shaderModel->IsGS()) {
  8177. // Validate that GS has the maxvertexcount attribute
  8178. if (!pEntryPointDecl->hasAttr<HLSLMaxVertexCountAttr>()) {
  8179. self->Diag(pEntryPointDecl->getLocation(),
  8180. diag::err_hlsl_missing_maxvertexcount_attr);
  8181. return;
  8182. }
  8183. } else if (shaderModel->IsHS()) {
  8184. if (const HLSLPatchConstantFuncAttr *Attr =
  8185. pEntryPointDecl->getAttr<HLSLPatchConstantFuncAttr>()) {
  8186. NameLookup NL = GetSingleFunctionDeclByName(
  8187. self, Attr->getFunctionName(), /*checkPatch*/ true);
  8188. if (!NL.Found || !NL.Found->hasBody()) {
  8189. unsigned id =
  8190. Diags.getCustomDiagID(clang::DiagnosticsEngine::Level::Error,
  8191. "missing patch function definition");
  8192. Diags.Report(id);
  8193. return;
  8194. }
  8195. pPatchFnDecl = NL.Found;
  8196. } else {
  8197. self->Diag(pEntryPointDecl->getLocation(),
  8198. diag::err_hlsl_missing_patchconstantfunc_attr);
  8199. return;
  8200. }
  8201. }
  8202. hlsl::CallGraphWithRecurseGuard CG;
  8203. CG.BuildForEntry(pEntryPointDecl);
  8204. Decl *pResult = CG.CheckRecursion(pEntryPointDecl);
  8205. if (pResult) {
  8206. unsigned id = Diags.getCustomDiagID(clang::DiagnosticsEngine::Level::Error,
  8207. "recursive functions not allowed");
  8208. Diags.Report(pResult->getSourceRange().getBegin(), id);
  8209. }
  8210. if (pPatchFnDecl) {
  8211. CG.BuildForEntry(pPatchFnDecl);
  8212. Decl *pPatchFnDecl = CG.CheckRecursion(pEntryPointDecl);
  8213. if (pPatchFnDecl) {
  8214. unsigned id = Diags.getCustomDiagID(clang::DiagnosticsEngine::Level::Error,
  8215. "recursive functions not allowed (via patch function)");
  8216. Diags.Report(pPatchFnDecl->getSourceRange().getBegin(), id);
  8217. }
  8218. }
  8219. }
  8220. }
  8221. void hlsl::DiagnoseUnusualAnnotationsForHLSL(
  8222. Sema& S,
  8223. std::vector<hlsl::UnusualAnnotation *>& annotations)
  8224. {
  8225. bool packoffsetOverriddenReported = false;
  8226. auto && iter = annotations.begin();
  8227. auto && end = annotations.end();
  8228. for (; iter != end; ++iter) {
  8229. switch ((*iter)->getKind()) {
  8230. case hlsl::UnusualAnnotation::UA_ConstantPacking: {
  8231. hlsl::ConstantPacking* constantPacking = cast<hlsl::ConstantPacking>(*iter);
  8232. // Check whether this will conflict with other packoffsets. If so, only issue a warning; last one wins.
  8233. if (!packoffsetOverriddenReported) {
  8234. auto newIter = iter;
  8235. ++newIter;
  8236. while (newIter != end) {
  8237. hlsl::ConstantPacking* other = dyn_cast_or_null<hlsl::ConstantPacking>(*newIter);
  8238. if (other != nullptr &&
  8239. (other->Subcomponent != constantPacking->Subcomponent || other->ComponentOffset != constantPacking->ComponentOffset)) {
  8240. S.Diag(constantPacking->Loc, diag::warn_hlsl_packoffset_overridden);
  8241. packoffsetOverriddenReported = true;
  8242. break;
  8243. }
  8244. ++newIter;
  8245. }
  8246. }
  8247. break;
  8248. }
  8249. case hlsl::UnusualAnnotation::UA_RegisterAssignment: {
  8250. hlsl::RegisterAssignment* registerAssignment = cast<hlsl::RegisterAssignment>(*iter);
  8251. // Check whether this will conflict with other register assignments of the same type.
  8252. auto newIter = iter;
  8253. ++newIter;
  8254. while (newIter != end) {
  8255. hlsl::RegisterAssignment* other = dyn_cast_or_null<hlsl::RegisterAssignment>(*newIter);
  8256. // Same register bank and profile, but different number.
  8257. if (other != nullptr &&
  8258. ShaderModelsMatch(other->ShaderProfile, registerAssignment->ShaderProfile) &&
  8259. other->RegisterType == registerAssignment->RegisterType &&
  8260. (other->RegisterNumber != registerAssignment->RegisterNumber ||
  8261. other->RegisterOffset != registerAssignment->RegisterOffset)) {
  8262. // Obvious conflict - report it up front.
  8263. S.Diag(registerAssignment->Loc, diag::err_hlsl_register_semantics_conflicting);
  8264. }
  8265. ++newIter;
  8266. }
  8267. break;
  8268. }
  8269. case hlsl::UnusualAnnotation::UA_SemanticDecl: {
  8270. // hlsl::SemanticDecl* semanticDecl = cast<hlsl::SemanticDecl>(*iter);
  8271. // No common validation to be performed.
  8272. break;
  8273. }
  8274. }
  8275. }
  8276. }
  8277. clang::OverloadingResult
  8278. hlsl::GetBestViableFunction(clang::Sema &S, clang::SourceLocation Loc,
  8279. clang::OverloadCandidateSet &set,
  8280. clang::OverloadCandidateSet::iterator &Best) {
  8281. return HLSLExternalSource::FromSema(&S)
  8282. ->GetBestViableFunction(Loc, set, Best);
  8283. }
  8284. void hlsl::InitializeInitSequenceForHLSL(Sema *self,
  8285. const InitializedEntity &Entity,
  8286. const InitializationKind &Kind,
  8287. MultiExprArg Args,
  8288. bool TopLevelOfInitList,
  8289. InitializationSequence *initSequence) {
  8290. return HLSLExternalSource::FromSema(self)
  8291. ->InitializeInitSequenceForHLSL(Entity, Kind, Args, TopLevelOfInitList, initSequence);
  8292. }
  8293. static unsigned CaculateInitListSize(HLSLExternalSource *hlslSource,
  8294. const clang::InitListExpr *InitList) {
  8295. unsigned totalSize = 0;
  8296. for (unsigned i = 0; i < InitList->getNumInits(); i++) {
  8297. const clang::Expr *EltInit = InitList->getInit(i);
  8298. QualType EltInitTy = EltInit->getType();
  8299. if (const InitListExpr *EltInitList = dyn_cast<InitListExpr>(EltInit)) {
  8300. totalSize += CaculateInitListSize(hlslSource, EltInitList);
  8301. } else {
  8302. totalSize += hlslSource->GetNumBasicElements(EltInitTy);
  8303. }
  8304. }
  8305. return totalSize;
  8306. }
  8307. unsigned hlsl::CaculateInitListArraySizeForHLSL(
  8308. _In_ clang::Sema* sema,
  8309. _In_ const clang::InitListExpr *InitList,
  8310. _In_ const clang::QualType EltTy) {
  8311. HLSLExternalSource *hlslSource = HLSLExternalSource::FromSema(sema);
  8312. unsigned totalSize = CaculateInitListSize(hlslSource, InitList);
  8313. unsigned eltSize = hlslSource->GetNumBasicElements(EltTy);
  8314. if (totalSize > 0 && (totalSize % eltSize)==0) {
  8315. return totalSize / eltSize;
  8316. } else {
  8317. return 0;
  8318. }
  8319. }
  8320. bool hlsl::IsConversionToLessOrEqualElements(
  8321. _In_ clang::Sema* self,
  8322. const clang::ExprResult& sourceExpr,
  8323. const clang::QualType& targetType,
  8324. bool explicitConversion)
  8325. {
  8326. return HLSLExternalSource::FromSema(self)
  8327. ->IsConversionToLessOrEqualElements(sourceExpr, targetType, explicitConversion);
  8328. }
  8329. bool hlsl::LookupMatrixMemberExprForHLSL(
  8330. Sema* self,
  8331. Expr& BaseExpr,
  8332. DeclarationName MemberName,
  8333. bool IsArrow,
  8334. SourceLocation OpLoc,
  8335. SourceLocation MemberLoc,
  8336. ExprResult* result)
  8337. {
  8338. return HLSLExternalSource::FromSema(self)
  8339. ->LookupMatrixMemberExprForHLSL(BaseExpr, MemberName, IsArrow, OpLoc, MemberLoc, result);
  8340. }
  8341. bool hlsl::LookupVectorMemberExprForHLSL(
  8342. Sema* self,
  8343. Expr& BaseExpr,
  8344. DeclarationName MemberName,
  8345. bool IsArrow,
  8346. SourceLocation OpLoc,
  8347. SourceLocation MemberLoc,
  8348. ExprResult* result)
  8349. {
  8350. return HLSLExternalSource::FromSema(self)
  8351. ->LookupVectorMemberExprForHLSL(BaseExpr, MemberName, IsArrow, OpLoc, MemberLoc, result);
  8352. }
  8353. clang::ExprResult hlsl::MaybeConvertScalarToVector(
  8354. _In_ clang::Sema* self,
  8355. _In_ clang::Expr* E)
  8356. {
  8357. return HLSLExternalSource::FromSema(self)->MaybeConvertScalarToVector(E);
  8358. }
  8359. bool hlsl::TryStaticCastForHLSL(_In_ Sema* self, ExprResult &SrcExpr,
  8360. QualType DestType,
  8361. Sema::CheckedConversionKind CCK,
  8362. const SourceRange &OpRange, unsigned &msg,
  8363. CastKind &Kind, CXXCastPath &BasePath,
  8364. bool ListInitialization,
  8365. bool SuppressDiagnostics,
  8366. _Inout_opt_ StandardConversionSequence* standard)
  8367. {
  8368. return HLSLExternalSource::FromSema(self)->TryStaticCastForHLSL(
  8369. SrcExpr, DestType, CCK, OpRange, msg, Kind, BasePath, ListInitialization,
  8370. SuppressDiagnostics, SuppressDiagnostics, standard);
  8371. }
  8372. clang::ExprResult hlsl::PerformHLSLConversion(
  8373. _In_ clang::Sema* self,
  8374. _In_ clang::Expr* From,
  8375. _In_ clang::QualType targetType,
  8376. _In_ const clang::StandardConversionSequence &SCS,
  8377. _In_ clang::Sema::CheckedConversionKind CCK)
  8378. {
  8379. return HLSLExternalSource::FromSema(self)->PerformHLSLConversion(From, targetType, SCS, CCK);
  8380. }
  8381. clang::ImplicitConversionSequence hlsl::TrySubscriptIndexInitialization(
  8382. _In_ clang::Sema* self,
  8383. _In_ clang::Expr* SrcExpr,
  8384. clang::QualType DestType)
  8385. {
  8386. return HLSLExternalSource::FromSema(self)
  8387. ->TrySubscriptIndexInitialization(SrcExpr, DestType);
  8388. }
  8389. /// <summary>Performs HLSL-specific initialization on the specified context.</summary>
  8390. void hlsl::InitializeASTContextForHLSL(ASTContext& context)
  8391. {
  8392. HLSLExternalSource* hlslSource = new HLSLExternalSource();
  8393. IntrusiveRefCntPtr<ExternalASTSource> externalSource(hlslSource);
  8394. if (hlslSource->Initialize(context)) {
  8395. context.setExternalSource(externalSource);
  8396. }
  8397. }
  8398. ////////////////////////////////////////////////////////////////////////////////
  8399. // FlattenedTypeIterator implementation //
  8400. /// <summary>Constructs a FlattenedTypeIterator for the specified type.</summary>
  8401. FlattenedTypeIterator::FlattenedTypeIterator(SourceLocation loc, QualType type, HLSLExternalSource& source) :
  8402. m_source(source), m_draining(false), m_springLoaded(false), m_incompleteCount(0), m_typeDepth(0), m_loc(loc)
  8403. {
  8404. if (pushTrackerForType(type, nullptr)) {
  8405. considerLeaf();
  8406. }
  8407. }
  8408. /// <summary>Constructs a FlattenedTypeIterator for the specified expressions.</summary>
  8409. FlattenedTypeIterator::FlattenedTypeIterator(SourceLocation loc, MultiExprArg args, HLSLExternalSource& source) :
  8410. m_source(source), m_draining(false), m_springLoaded(false), m_incompleteCount(0), m_typeDepth(0), m_loc(loc)
  8411. {
  8412. if (!args.empty()) {
  8413. MultiExprArg::iterator ii = args.begin();
  8414. MultiExprArg::iterator ie = args.end();
  8415. DXASSERT(ii != ie, "otherwise empty() returned an incorrect value");
  8416. m_typeTrackers.push_back(FlattenedTypeIterator::FlattenedTypeTracker(ii, ie));
  8417. if (!considerLeaf()) {
  8418. m_typeTrackers.clear();
  8419. }
  8420. }
  8421. }
  8422. /// <summary>Gets the current element in the flattened type hierarchy.</summary>
  8423. QualType FlattenedTypeIterator::getCurrentElement() const
  8424. {
  8425. return m_typeTrackers.back().Type;
  8426. }
  8427. /// <summary>Get the number of repeated current elements.</summary>
  8428. unsigned int FlattenedTypeIterator::getCurrentElementSize() const
  8429. {
  8430. const FlattenedTypeTracker& back = m_typeTrackers.back();
  8431. return (back.IterKind == FK_IncompleteArray) ? 1 : back.Count;
  8432. }
  8433. /// <summary>Checks whether the iterator has a current element type to report.</summary>
  8434. bool FlattenedTypeIterator::hasCurrentElement() const
  8435. {
  8436. return m_typeTrackers.size() > 0;
  8437. }
  8438. /// <summary>Consumes count elements on this iterator.</summary>
  8439. void FlattenedTypeIterator::advanceCurrentElement(unsigned int count)
  8440. {
  8441. DXASSERT(!m_typeTrackers.empty(), "otherwise caller should not be trying to advance to another element");
  8442. DXASSERT(m_typeTrackers.back().IterKind == FK_IncompleteArray || count <= m_typeTrackers.back().Count, "caller should never exceed currently pending element count");
  8443. FlattenedTypeTracker& tracker = m_typeTrackers.back();
  8444. if (tracker.IterKind == FK_IncompleteArray)
  8445. {
  8446. tracker.Count += count;
  8447. m_springLoaded = true;
  8448. }
  8449. else
  8450. {
  8451. tracker.Count -= count;
  8452. m_springLoaded = false;
  8453. if (m_typeTrackers.back().Count == 0)
  8454. {
  8455. advanceLeafTracker();
  8456. }
  8457. }
  8458. }
  8459. unsigned int FlattenedTypeIterator::countRemaining()
  8460. {
  8461. m_draining = true; // when draining the iterator, incomplete arrays stop functioning as an infinite array
  8462. size_t result = 0;
  8463. while (hasCurrentElement() && !m_springLoaded)
  8464. {
  8465. size_t pending = getCurrentElementSize();
  8466. result += pending;
  8467. advanceCurrentElement(pending);
  8468. }
  8469. return result;
  8470. }
  8471. void FlattenedTypeIterator::advanceLeafTracker()
  8472. {
  8473. DXASSERT(!m_typeTrackers.empty(), "otherwise caller should not be trying to advance to another element");
  8474. for (;;)
  8475. {
  8476. consumeLeaf();
  8477. if (m_typeTrackers.empty()) {
  8478. return;
  8479. }
  8480. if (considerLeaf()) {
  8481. return;
  8482. }
  8483. }
  8484. }
  8485. bool FlattenedTypeIterator::considerLeaf()
  8486. {
  8487. if (m_typeTrackers.empty()) {
  8488. return false;
  8489. }
  8490. m_typeDepth++;
  8491. if (m_typeDepth > MaxTypeDepth) {
  8492. m_source.ReportUnsupportedTypeNesting(m_loc, m_firstType);
  8493. m_typeTrackers.clear();
  8494. m_typeDepth--;
  8495. return false;
  8496. }
  8497. bool result = false;
  8498. FlattenedTypeTracker& tracker = m_typeTrackers.back();
  8499. tracker.IsConsidered = true;
  8500. switch (tracker.IterKind) {
  8501. case FlattenedIterKind::FK_Expressions:
  8502. if (pushTrackerForExpression(tracker.CurrentExpr)) {
  8503. result = considerLeaf();
  8504. }
  8505. break;
  8506. case FlattenedIterKind::FK_Fields:
  8507. if (pushTrackerForType(tracker.CurrentField->getType(), nullptr)) {
  8508. result = considerLeaf();
  8509. } else {
  8510. // Pop empty struct.
  8511. m_typeTrackers.pop_back();
  8512. }
  8513. break;
  8514. case FlattenedIterKind::FK_Bases:
  8515. if (pushTrackerForType(tracker.CurrentBase->getType(), nullptr)) {
  8516. result = considerLeaf();
  8517. } else {
  8518. // Pop empty base.
  8519. m_typeTrackers.pop_back();
  8520. }
  8521. break;
  8522. case FlattenedIterKind::FK_IncompleteArray:
  8523. m_springLoaded = true; // fall through.
  8524. default:
  8525. case FlattenedIterKind::FK_Simple: {
  8526. ArTypeObjectKind objectKind = m_source.GetTypeObjectKind(tracker.Type);
  8527. if (objectKind != ArTypeObjectKind::AR_TOBJ_BASIC &&
  8528. objectKind != ArTypeObjectKind::AR_TOBJ_OBJECT) {
  8529. if (pushTrackerForType(tracker.Type, tracker.CurrentExpr)) {
  8530. result = considerLeaf();
  8531. }
  8532. } else {
  8533. result = true;
  8534. }
  8535. }
  8536. }
  8537. m_typeDepth--;
  8538. return result;
  8539. }
  8540. void FlattenedTypeIterator::consumeLeaf()
  8541. {
  8542. bool topConsumed = true; // Tracks whether we're processing the topmost item which we should consume.
  8543. for (;;) {
  8544. if (m_typeTrackers.empty()) {
  8545. return;
  8546. }
  8547. FlattenedTypeTracker& tracker = m_typeTrackers.back();
  8548. // Reach a leaf which is not considered before.
  8549. // Stop here.
  8550. if (!tracker.IsConsidered) {
  8551. break;
  8552. }
  8553. switch (tracker.IterKind) {
  8554. case FlattenedIterKind::FK_Expressions:
  8555. ++tracker.CurrentExpr;
  8556. if (tracker.CurrentExpr == tracker.EndExpr) {
  8557. m_typeTrackers.pop_back();
  8558. topConsumed = false;
  8559. } else {
  8560. return;
  8561. }
  8562. break;
  8563. case FlattenedIterKind::FK_Fields:
  8564. ++tracker.CurrentField;
  8565. if (tracker.CurrentField == tracker.EndField) {
  8566. m_typeTrackers.pop_back();
  8567. topConsumed = false;
  8568. } else {
  8569. return;
  8570. }
  8571. break;
  8572. case FlattenedIterKind::FK_Bases:
  8573. ++tracker.CurrentBase;
  8574. if (tracker.CurrentBase == tracker.EndBase) {
  8575. m_typeTrackers.pop_back();
  8576. topConsumed = false;
  8577. } else {
  8578. return;
  8579. }
  8580. break;
  8581. case FlattenedIterKind::FK_IncompleteArray:
  8582. if (m_draining) {
  8583. DXASSERT(m_typeTrackers.size() == 1, "m_typeTrackers.size() == 1, otherwise incomplete array isn't topmost");
  8584. m_incompleteCount = tracker.Count;
  8585. m_typeTrackers.pop_back();
  8586. }
  8587. return;
  8588. default:
  8589. case FlattenedIterKind::FK_Simple: {
  8590. m_springLoaded = false;
  8591. if (!topConsumed) {
  8592. DXASSERT(tracker.Count > 0, "tracker.Count > 0 - otherwise we shouldn't be on stack");
  8593. --tracker.Count;
  8594. }
  8595. else {
  8596. topConsumed = false;
  8597. }
  8598. if (tracker.Count == 0) {
  8599. m_typeTrackers.pop_back();
  8600. } else {
  8601. return;
  8602. }
  8603. }
  8604. }
  8605. }
  8606. }
  8607. bool FlattenedTypeIterator::pushTrackerForExpression(MultiExprArg::iterator expression)
  8608. {
  8609. Expr* e = *expression;
  8610. Stmt::StmtClass expressionClass = e->getStmtClass();
  8611. if (expressionClass == Stmt::StmtClass::InitListExprClass) {
  8612. InitListExpr* initExpr = dyn_cast<InitListExpr>(e);
  8613. if (initExpr->getNumInits() == 0) {
  8614. return false;
  8615. }
  8616. MultiExprArg inits(initExpr->getInits(), initExpr->getNumInits());
  8617. MultiExprArg::iterator ii = inits.begin();
  8618. MultiExprArg::iterator ie = inits.end();
  8619. DXASSERT(ii != ie, "otherwise getNumInits() returned an incorrect value");
  8620. m_typeTrackers.push_back(FlattenedTypeIterator::FlattenedTypeTracker(ii, ie));
  8621. return true;
  8622. }
  8623. return pushTrackerForType(e->getType(), expression);
  8624. }
  8625. // TODO: improve this to provide a 'peek' at intermediate types,
  8626. // which should help compare struct foo[1000] to avoid 1000 steps + per-field steps
  8627. bool FlattenedTypeIterator::pushTrackerForType(QualType type, MultiExprArg::iterator expression)
  8628. {
  8629. if (type->isVoidType()) {
  8630. return false;
  8631. }
  8632. if (type->isFunctionType()) {
  8633. return false;
  8634. }
  8635. if (m_firstType.isNull()) {
  8636. m_firstType = type;
  8637. }
  8638. ArTypeObjectKind objectKind = m_source.GetTypeObjectKind(type);
  8639. QualType elementType;
  8640. unsigned int elementCount;
  8641. const RecordType* recordType;
  8642. RecordDecl::field_iterator fi, fe;
  8643. switch (objectKind)
  8644. {
  8645. case ArTypeObjectKind::AR_TOBJ_ARRAY:
  8646. // TODO: handle multi-dimensional arrays
  8647. elementType = type->getAsArrayTypeUnsafe()->getElementType(); // handle arrays of arrays
  8648. elementCount = GetArraySize(type);
  8649. if (elementCount == 0) {
  8650. if (type->isIncompleteArrayType()) {
  8651. m_typeTrackers.push_back(FlattenedTypeIterator::FlattenedTypeTracker(elementType));
  8652. return true;
  8653. }
  8654. return false;
  8655. }
  8656. m_typeTrackers.push_back(FlattenedTypeIterator::FlattenedTypeTracker(
  8657. elementType, elementCount, nullptr));
  8658. return true;
  8659. case ArTypeObjectKind::AR_TOBJ_BASIC:
  8660. m_typeTrackers.push_back(FlattenedTypeIterator::FlattenedTypeTracker(type, 1, expression));
  8661. return true;
  8662. case ArTypeObjectKind::AR_TOBJ_COMPOUND: {
  8663. recordType = type->getAsStructureType();
  8664. if (recordType == nullptr)
  8665. recordType = dyn_cast<RecordType>(type.getTypePtr());
  8666. fi = recordType->getDecl()->field_begin();
  8667. fe = recordType->getDecl()->field_end();
  8668. bool bAddTracker = false;
  8669. // Skip empty struct.
  8670. if (fi != fe) {
  8671. m_typeTrackers.push_back(
  8672. FlattenedTypeIterator::FlattenedTypeTracker(type, fi, fe));
  8673. type = (*fi)->getType();
  8674. bAddTracker = true;
  8675. }
  8676. if (CXXRecordDecl *cxxRecordDecl =
  8677. dyn_cast<CXXRecordDecl>(recordType->getDecl())) {
  8678. CXXRecordDecl::base_class_iterator bi, be;
  8679. bi = cxxRecordDecl->bases_begin();
  8680. be = cxxRecordDecl->bases_end();
  8681. if (bi != be) {
  8682. // Add type tracker for base.
  8683. // Add base after child to make sure base considered first.
  8684. m_typeTrackers.push_back(
  8685. FlattenedTypeIterator::FlattenedTypeTracker(type, bi, be));
  8686. bAddTracker = true;
  8687. }
  8688. }
  8689. return bAddTracker;
  8690. }
  8691. case ArTypeObjectKind::AR_TOBJ_MATRIX:
  8692. m_typeTrackers.push_back(FlattenedTypeIterator::FlattenedTypeTracker(
  8693. m_source.GetMatrixOrVectorElementType(type),
  8694. GetElementCount(type), nullptr));
  8695. return true;
  8696. case ArTypeObjectKind::AR_TOBJ_VECTOR:
  8697. m_typeTrackers.push_back(FlattenedTypeIterator::FlattenedTypeTracker(
  8698. m_source.GetMatrixOrVectorElementType(type),
  8699. GetHLSLVecSize(type), nullptr));
  8700. return true;
  8701. case ArTypeObjectKind::AR_TOBJ_OBJECT:
  8702. // Object have no sub-types.
  8703. m_typeTrackers.push_back(FlattenedTypeIterator::FlattenedTypeTracker(type.getCanonicalType(), 1, expression));
  8704. return true;
  8705. default:
  8706. DXASSERT(false, "unreachable");
  8707. return false;
  8708. }
  8709. }
  8710. FlattenedTypeIterator::ComparisonResult
  8711. FlattenedTypeIterator::CompareIterators(
  8712. HLSLExternalSource& source,
  8713. SourceLocation loc,
  8714. FlattenedTypeIterator& leftIter,
  8715. FlattenedTypeIterator& rightIter)
  8716. {
  8717. FlattenedTypeIterator::ComparisonResult result;
  8718. result.LeftCount = 0;
  8719. result.RightCount = 0;
  8720. result.AreElementsEqual = true; // Until proven otherwise.
  8721. result.CanConvertElements = true; // Until proven otherwise.
  8722. while (leftIter.hasCurrentElement() && rightIter.hasCurrentElement())
  8723. {
  8724. Expr* actualExpr = rightIter.getExprOrNull();
  8725. bool hasExpr = actualExpr != nullptr;
  8726. StmtExpr scratchExpr(nullptr, rightIter.getCurrentElement(), NoLoc, NoLoc);
  8727. StandardConversionSequence standard;
  8728. ExprResult convertedExpr;
  8729. if (!source.CanConvert(loc,
  8730. hasExpr ? actualExpr : &scratchExpr,
  8731. leftIter.getCurrentElement(),
  8732. ExplicitConversionFalse,
  8733. nullptr,
  8734. &standard)) {
  8735. result.AreElementsEqual = false;
  8736. result.CanConvertElements = false;
  8737. break;
  8738. }
  8739. else if (hasExpr && (standard.First != ICK_Identity || !standard.isIdentityConversion()))
  8740. {
  8741. convertedExpr = source.getSema()->PerformImplicitConversion(actualExpr,
  8742. leftIter.getCurrentElement(),
  8743. standard,
  8744. Sema::AA_Casting,
  8745. Sema::CCK_ImplicitConversion);
  8746. }
  8747. if (rightIter.getCurrentElement()->getCanonicalTypeUnqualified() !=
  8748. leftIter.getCurrentElement()->getCanonicalTypeUnqualified())
  8749. {
  8750. result.AreElementsEqual = false;
  8751. }
  8752. unsigned int advance = std::min(leftIter.getCurrentElementSize(), rightIter.getCurrentElementSize());
  8753. DXASSERT(advance > 0, "otherwise one iterator should report empty");
  8754. // If we need to apply conversions to the expressions, then advance a single element.
  8755. if (hasExpr && convertedExpr.isUsable()) {
  8756. rightIter.replaceExpr(convertedExpr.get());
  8757. advance = 1;
  8758. }
  8759. leftIter.advanceCurrentElement(advance);
  8760. rightIter.advanceCurrentElement(advance);
  8761. result.LeftCount += advance;
  8762. result.RightCount += advance;
  8763. }
  8764. result.LeftCount += leftIter.countRemaining();
  8765. result.RightCount += rightIter.countRemaining();
  8766. return result;
  8767. }
  8768. FlattenedTypeIterator::ComparisonResult
  8769. FlattenedTypeIterator::CompareTypes(
  8770. HLSLExternalSource& source,
  8771. SourceLocation leftLoc, SourceLocation rightLoc,
  8772. QualType left, QualType right)
  8773. {
  8774. FlattenedTypeIterator leftIter(leftLoc, left, source);
  8775. FlattenedTypeIterator rightIter(rightLoc, right, source);
  8776. return CompareIterators(source, leftLoc, leftIter, rightIter);
  8777. }
  8778. FlattenedTypeIterator::ComparisonResult
  8779. FlattenedTypeIterator::CompareTypesForInit(
  8780. HLSLExternalSource& source, QualType left, MultiExprArg args,
  8781. SourceLocation leftLoc, SourceLocation rightLoc)
  8782. {
  8783. FlattenedTypeIterator leftIter(leftLoc, left, source);
  8784. FlattenedTypeIterator rightIter(rightLoc, args, source);
  8785. return CompareIterators(source, leftLoc, leftIter, rightIter);
  8786. }
  8787. ////////////////////////////////////////////////////////////////////////////////
  8788. // Attribute processing support. //
  8789. static int ValidateAttributeIntArg(Sema& S, const AttributeList &Attr, unsigned index = 0)
  8790. {
  8791. int64_t value = 0;
  8792. if (Attr.getNumArgs() > index)
  8793. {
  8794. Expr *E = nullptr;
  8795. if (!Attr.isArgExpr(index)) {
  8796. // For case arg is constant variable.
  8797. IdentifierLoc *loc = Attr.getArgAsIdent(index);
  8798. VarDecl *decl = dyn_cast_or_null<VarDecl>(
  8799. S.LookupSingleName(S.getCurScope(), loc->Ident, loc->Loc,
  8800. Sema::LookupNameKind::LookupOrdinaryName));
  8801. if (!decl) {
  8802. S.Diag(Attr.getLoc(), diag::warn_hlsl_attribute_expects_uint_literal) << Attr.getName();
  8803. return value;
  8804. }
  8805. Expr *init = decl->getInit();
  8806. if (!init) {
  8807. S.Diag(Attr.getLoc(), diag::warn_hlsl_attribute_expects_uint_literal) << Attr.getName();
  8808. return value;
  8809. }
  8810. E = init;
  8811. } else
  8812. E = Attr.getArgAsExpr(index);
  8813. clang::APValue ArgNum;
  8814. bool displayError = false;
  8815. if (E->isTypeDependent() || E->isValueDependent() || !E->isCXX11ConstantExpr(S.Context, &ArgNum))
  8816. {
  8817. displayError = true;
  8818. }
  8819. else
  8820. {
  8821. if (ArgNum.isInt())
  8822. {
  8823. value = ArgNum.getInt().getSExtValue();
  8824. }
  8825. else if (ArgNum.isFloat())
  8826. {
  8827. llvm::APSInt floatInt;
  8828. bool isPrecise;
  8829. if (ArgNum.getFloat().convertToInteger(floatInt, llvm::APFloat::rmTowardZero, &isPrecise) == llvm::APFloat::opStatus::opOK)
  8830. {
  8831. value = floatInt.getSExtValue();
  8832. }
  8833. else
  8834. {
  8835. S.Diag(Attr.getLoc(), diag::warn_hlsl_attribute_expects_uint_literal) << Attr.getName();
  8836. }
  8837. }
  8838. else
  8839. {
  8840. displayError = true;
  8841. }
  8842. if (value < 0)
  8843. {
  8844. S.Diag(Attr.getLoc(), diag::warn_hlsl_attribute_expects_uint_literal) << Attr.getName();
  8845. }
  8846. }
  8847. if (displayError)
  8848. {
  8849. S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
  8850. << Attr.getName() << AANT_ArgumentIntegerConstant
  8851. << E->getSourceRange();
  8852. }
  8853. }
  8854. return (int)value;
  8855. }
  8856. // TODO: support float arg directly.
  8857. static int ValidateAttributeFloatArg(Sema &S, const AttributeList &Attr,
  8858. unsigned index = 0) {
  8859. int value = 0;
  8860. if (Attr.getNumArgs() > index) {
  8861. Expr *E = Attr.getArgAsExpr(index);
  8862. if (FloatingLiteral *FL = dyn_cast<FloatingLiteral>(E)) {
  8863. llvm::APFloat flV = FL->getValue();
  8864. if (flV.getSizeInBits(flV.getSemantics()) == 64) {
  8865. llvm::APInt intV = llvm::APInt::floatToBits(flV.convertToDouble());
  8866. value = intV.getLimitedValue();
  8867. } else {
  8868. llvm::APInt intV = llvm::APInt::floatToBits(flV.convertToFloat());
  8869. value = intV.getLimitedValue();
  8870. }
  8871. } else if (IntegerLiteral *IL = dyn_cast<IntegerLiteral>(E)) {
  8872. llvm::APInt intV =
  8873. llvm::APInt::floatToBits((float)IL->getValue().getLimitedValue());
  8874. value = intV.getLimitedValue();
  8875. } else {
  8876. S.Diag(E->getLocStart(), diag::err_hlsl_attribute_expects_float_literal)
  8877. << Attr.getName();
  8878. }
  8879. }
  8880. return value;
  8881. }
  8882. static Stmt* IgnoreParensAndDecay(Stmt* S)
  8883. {
  8884. for (;;)
  8885. {
  8886. switch (S->getStmtClass())
  8887. {
  8888. case Stmt::ParenExprClass:
  8889. S = cast<ParenExpr>(S)->getSubExpr();
  8890. break;
  8891. case Stmt::ImplicitCastExprClass:
  8892. {
  8893. ImplicitCastExpr* castExpr = cast<ImplicitCastExpr>(S);
  8894. if (castExpr->getCastKind() != CK_ArrayToPointerDecay &&
  8895. castExpr->getCastKind() != CK_NoOp &&
  8896. castExpr->getCastKind() != CK_LValueToRValue)
  8897. {
  8898. return S;
  8899. }
  8900. S = castExpr->getSubExpr();
  8901. }
  8902. break;
  8903. default:
  8904. return S;
  8905. }
  8906. }
  8907. }
  8908. static Expr* ValidateClipPlaneArraySubscriptExpr(Sema& S, ArraySubscriptExpr* E)
  8909. {
  8910. DXASSERT_NOMSG(E != nullptr);
  8911. Expr* subscriptExpr = E->getIdx();
  8912. subscriptExpr = dyn_cast<Expr>(subscriptExpr->IgnoreParens());
  8913. if (subscriptExpr == nullptr ||
  8914. subscriptExpr->isTypeDependent() || subscriptExpr->isValueDependent() ||
  8915. !subscriptExpr->isCXX11ConstantExpr(S.Context))
  8916. {
  8917. S.Diag(
  8918. (subscriptExpr == nullptr) ? E->getLocStart() : subscriptExpr->getLocStart(),
  8919. diag::err_hlsl_unsupported_clipplane_argument_subscript_expression);
  8920. return nullptr;
  8921. }
  8922. return E->getBase();
  8923. }
  8924. static bool IsValidClipPlaneDecl(Decl* D)
  8925. {
  8926. Decl::Kind kind = D->getKind();
  8927. if (kind == Decl::Var)
  8928. {
  8929. VarDecl* varDecl = cast<VarDecl>(D);
  8930. if (varDecl->getStorageClass() == StorageClass::SC_Static &&
  8931. varDecl->getType().isConstQualified())
  8932. {
  8933. return false;
  8934. }
  8935. return true;
  8936. }
  8937. else if (kind == Decl::Field)
  8938. {
  8939. return true;
  8940. }
  8941. return false;
  8942. }
  8943. static Expr* ValidateClipPlaneExpr(Sema& S, Expr* E)
  8944. {
  8945. Stmt* cursor = E;
  8946. // clip plane expressions are a linear path, so no need to traverse the tree here.
  8947. while (cursor != nullptr)
  8948. {
  8949. bool supported = true;
  8950. cursor = IgnoreParensAndDecay(cursor);
  8951. switch (cursor->getStmtClass())
  8952. {
  8953. case Stmt::ArraySubscriptExprClass:
  8954. cursor = ValidateClipPlaneArraySubscriptExpr(S, cast<ArraySubscriptExpr>(cursor));
  8955. if (cursor == nullptr)
  8956. {
  8957. // nullptr indicates failure, and the error message has already been printed out
  8958. return nullptr;
  8959. }
  8960. break;
  8961. case Stmt::DeclRefExprClass:
  8962. {
  8963. DeclRefExpr* declRef = cast<DeclRefExpr>(cursor);
  8964. Decl* decl = declRef->getDecl();
  8965. supported = IsValidClipPlaneDecl(decl);
  8966. cursor = supported ? nullptr : cursor;
  8967. }
  8968. break;
  8969. case Stmt::MemberExprClass:
  8970. {
  8971. MemberExpr* member = cast<MemberExpr>(cursor);
  8972. supported = IsValidClipPlaneDecl(member->getMemberDecl());
  8973. cursor = supported ? member->getBase() : cursor;
  8974. }
  8975. break;
  8976. default:
  8977. supported = false;
  8978. break;
  8979. }
  8980. if (!supported)
  8981. {
  8982. DXASSERT(cursor != nullptr, "otherwise it was cleared when the supported flag was set to false");
  8983. S.Diag(cursor->getLocStart(), diag::err_hlsl_unsupported_clipplane_argument_expression);
  8984. return nullptr;
  8985. }
  8986. }
  8987. // Validate that the type is a float4.
  8988. QualType expressionType = E->getType();
  8989. HLSLExternalSource* hlslSource = HLSLExternalSource::FromSema(&S);
  8990. if (hlslSource->GetTypeElementKind(expressionType) != ArBasicKind::AR_BASIC_FLOAT32 ||
  8991. hlslSource->GetTypeObjectKind(expressionType) != ArTypeObjectKind::AR_TOBJ_VECTOR)
  8992. {
  8993. S.Diag(E->getLocStart(), diag::err_hlsl_unsupported_clipplane_argument_type) << expressionType;
  8994. return nullptr;
  8995. }
  8996. return E;
  8997. }
  8998. static Attr* HandleClipPlanes(Sema& S, const AttributeList &A)
  8999. {
  9000. Expr* clipExprs[6];
  9001. for (unsigned int index = 0; index < _countof(clipExprs); index++)
  9002. {
  9003. if (A.getNumArgs() <= index)
  9004. {
  9005. clipExprs[index] = nullptr;
  9006. continue;
  9007. }
  9008. Expr *E = A.getArgAsExpr(index);
  9009. clipExprs[index] = ValidateClipPlaneExpr(S, E);
  9010. }
  9011. return ::new (S.Context) HLSLClipPlanesAttr(A.getRange(), S.Context,
  9012. clipExprs[0], clipExprs[1], clipExprs[2], clipExprs[3], clipExprs[4], clipExprs[5],
  9013. A.getAttributeSpellingListIndex());
  9014. }
  9015. static Attr* HandleUnrollAttribute(Sema& S, const AttributeList &Attr)
  9016. {
  9017. int argValue = ValidateAttributeIntArg(S, Attr);
  9018. // Default value is 1.
  9019. if (Attr.getNumArgs() == 0) argValue = 1;
  9020. return ::new (S.Context) HLSLUnrollAttr(Attr.getRange(), S.Context,
  9021. argValue, Attr.getAttributeSpellingListIndex());
  9022. }
  9023. static void ValidateAttributeOnLoop(Sema& S, Stmt* St, const AttributeList &Attr)
  9024. {
  9025. Stmt::StmtClass stClass = St->getStmtClass();
  9026. if (stClass != Stmt::ForStmtClass && stClass != Stmt::WhileStmtClass && stClass != Stmt::DoStmtClass)
  9027. {
  9028. S.Diag(Attr.getLoc(), diag::warn_hlsl_unsupported_statement_for_loop_attribute)
  9029. << Attr.getName();
  9030. }
  9031. }
  9032. static void ValidateAttributeOnSwitch(Sema& S, Stmt* St, const AttributeList &Attr)
  9033. {
  9034. Stmt::StmtClass stClass = St->getStmtClass();
  9035. if (stClass != Stmt::SwitchStmtClass)
  9036. {
  9037. S.Diag(Attr.getLoc(), diag::warn_hlsl_unsupported_statement_for_switch_attribute)
  9038. << Attr.getName();
  9039. }
  9040. }
  9041. static void ValidateAttributeOnSwitchOrIf(Sema& S, Stmt* St, const AttributeList &Attr)
  9042. {
  9043. Stmt::StmtClass stClass = St->getStmtClass();
  9044. if (stClass != Stmt::SwitchStmtClass && stClass != Stmt::IfStmtClass)
  9045. {
  9046. S.Diag(Attr.getLoc(), diag::warn_hlsl_unsupported_statement_for_if_switch_attribute)
  9047. << Attr.getName();
  9048. }
  9049. }
  9050. static StringRef ValidateAttributeStringArg(Sema& S, const AttributeList &A, _In_opt_z_ const char* values, unsigned index = 0)
  9051. {
  9052. // values is an optional comma-separated list of potential values.
  9053. if (A.getNumArgs() <= index)
  9054. return StringRef();
  9055. Expr* E = A.getArgAsExpr(index);
  9056. if (E->isTypeDependent() || E->isValueDependent() || E->getStmtClass() != Stmt::StringLiteralClass)
  9057. {
  9058. S.Diag(E->getLocStart(), diag::err_hlsl_attribute_expects_string_literal)
  9059. << A.getName();
  9060. return StringRef();
  9061. }
  9062. StringLiteral* sl = cast<StringLiteral>(E);
  9063. StringRef result = sl->getString();
  9064. // Return result with no additional validation.
  9065. if (values == nullptr)
  9066. {
  9067. return result;
  9068. }
  9069. const char* value = values;
  9070. while (*value != '\0')
  9071. {
  9072. DXASSERT_NOMSG(*value != ','); // no leading commas in values
  9073. // Look for a match.
  9074. const char* argData = result.data();
  9075. size_t argDataLen = result.size();
  9076. while (argDataLen != 0 && *argData == *value && *value)
  9077. {
  9078. ++argData;
  9079. ++value;
  9080. --argDataLen;
  9081. }
  9082. // Match found if every input character matched.
  9083. if (argDataLen == 0 && (*value == '\0' || *value == ','))
  9084. {
  9085. return result;
  9086. }
  9087. // Move to next separator.
  9088. while (*value != '\0' && *value != ',')
  9089. {
  9090. ++value;
  9091. }
  9092. // Move to the start of the next item if any.
  9093. if (*value == ',') value++;
  9094. }
  9095. DXASSERT_NOMSG(*value == '\0'); // no other terminating conditions
  9096. // No match found.
  9097. S.Diag(E->getLocStart(), diag::err_hlsl_attribute_expects_string_literal_from_list)
  9098. << A.getName() << values;
  9099. return StringRef();
  9100. }
  9101. static
  9102. bool ValidateAttributeTargetIsFunction(Sema& S, Decl* D, const AttributeList &A)
  9103. {
  9104. if (D->isFunctionOrFunctionTemplate())
  9105. {
  9106. return true;
  9107. }
  9108. S.Diag(A.getLoc(), diag::err_hlsl_attribute_valid_on_function_only);
  9109. return false;
  9110. }
  9111. void hlsl::HandleDeclAttributeForHLSL(Sema &S, Decl *D, const AttributeList &A, bool& Handled)
  9112. {
  9113. DXASSERT_NOMSG(D != nullptr);
  9114. DXASSERT_NOMSG(!A.isInvalid());
  9115. Attr* declAttr = nullptr;
  9116. Handled = true;
  9117. switch (A.getKind())
  9118. {
  9119. case AttributeList::AT_HLSLIn:
  9120. declAttr = ::new (S.Context) HLSLInAttr(A.getRange(), S.Context,
  9121. A.getAttributeSpellingListIndex());
  9122. break;
  9123. case AttributeList::AT_HLSLOut:
  9124. declAttr = ::new (S.Context) HLSLOutAttr(A.getRange(), S.Context,
  9125. A.getAttributeSpellingListIndex());
  9126. break;
  9127. case AttributeList::AT_HLSLInOut:
  9128. declAttr = ::new (S.Context) HLSLInOutAttr(A.getRange(), S.Context,
  9129. A.getAttributeSpellingListIndex());
  9130. break;
  9131. case AttributeList::AT_HLSLNoInterpolation:
  9132. declAttr = ::new (S.Context) HLSLNoInterpolationAttr(A.getRange(), S.Context,
  9133. A.getAttributeSpellingListIndex());
  9134. break;
  9135. case AttributeList::AT_HLSLLinear:
  9136. declAttr = ::new (S.Context) HLSLLinearAttr(A.getRange(), S.Context,
  9137. A.getAttributeSpellingListIndex());
  9138. break;
  9139. case AttributeList::AT_HLSLNoPerspective:
  9140. declAttr = ::new (S.Context) HLSLNoPerspectiveAttr(A.getRange(), S.Context,
  9141. A.getAttributeSpellingListIndex());
  9142. break;
  9143. case AttributeList::AT_HLSLSample:
  9144. declAttr = ::new (S.Context) HLSLSampleAttr(A.getRange(), S.Context,
  9145. A.getAttributeSpellingListIndex());
  9146. break;
  9147. case AttributeList::AT_HLSLCentroid:
  9148. declAttr = ::new (S.Context) HLSLCentroidAttr(A.getRange(), S.Context,
  9149. A.getAttributeSpellingListIndex());
  9150. break;
  9151. case AttributeList::AT_HLSLPrecise:
  9152. declAttr = ::new (S.Context) HLSLPreciseAttr(A.getRange(), S.Context,
  9153. A.getAttributeSpellingListIndex());
  9154. break;
  9155. case AttributeList::AT_HLSLShared:
  9156. declAttr = ::new (S.Context) HLSLSharedAttr(A.getRange(), S.Context,
  9157. A.getAttributeSpellingListIndex());
  9158. break;
  9159. case AttributeList::AT_HLSLGroupShared:
  9160. declAttr = ::new (S.Context) HLSLGroupSharedAttr(A.getRange(), S.Context,
  9161. A.getAttributeSpellingListIndex());
  9162. break;
  9163. case AttributeList::AT_HLSLUniform:
  9164. declAttr = ::new (S.Context) HLSLUniformAttr(A.getRange(), S.Context,
  9165. A.getAttributeSpellingListIndex());
  9166. break;
  9167. case AttributeList::AT_HLSLColumnMajor:
  9168. declAttr = ::new (S.Context) HLSLColumnMajorAttr(A.getRange(), S.Context,
  9169. A.getAttributeSpellingListIndex());
  9170. break;
  9171. case AttributeList::AT_HLSLRowMajor:
  9172. declAttr = ::new (S.Context) HLSLRowMajorAttr(A.getRange(), S.Context,
  9173. A.getAttributeSpellingListIndex());
  9174. break;
  9175. case AttributeList::AT_HLSLUnorm:
  9176. declAttr = ::new (S.Context) HLSLUnormAttr(A.getRange(), S.Context,
  9177. A.getAttributeSpellingListIndex());
  9178. break;
  9179. case AttributeList::AT_HLSLSnorm:
  9180. declAttr = ::new (S.Context) HLSLSnormAttr(A.getRange(), S.Context,
  9181. A.getAttributeSpellingListIndex());
  9182. break;
  9183. case AttributeList::AT_HLSLPoint:
  9184. declAttr = ::new (S.Context) HLSLPointAttr(A.getRange(), S.Context,
  9185. A.getAttributeSpellingListIndex());
  9186. break;
  9187. case AttributeList::AT_HLSLLine:
  9188. declAttr = ::new (S.Context) HLSLLineAttr(A.getRange(), S.Context,
  9189. A.getAttributeSpellingListIndex());
  9190. break;
  9191. case AttributeList::AT_HLSLLineAdj:
  9192. declAttr = ::new (S.Context) HLSLLineAdjAttr(A.getRange(), S.Context,
  9193. A.getAttributeSpellingListIndex());
  9194. break;
  9195. case AttributeList::AT_HLSLTriangle:
  9196. declAttr = ::new (S.Context) HLSLTriangleAttr(A.getRange(), S.Context,
  9197. A.getAttributeSpellingListIndex());
  9198. break;
  9199. case AttributeList::AT_HLSLTriangleAdj:
  9200. declAttr = ::new (S.Context) HLSLTriangleAdjAttr(A.getRange(), S.Context,
  9201. A.getAttributeSpellingListIndex());
  9202. break;
  9203. case AttributeList::AT_HLSLGloballyCoherent:
  9204. declAttr = ::new (S.Context) HLSLGloballyCoherentAttr(
  9205. A.getRange(), S.Context, A.getAttributeSpellingListIndex());
  9206. break;
  9207. default:
  9208. Handled = false;
  9209. break;
  9210. }
  9211. if (declAttr != nullptr)
  9212. {
  9213. DXASSERT_NOMSG(Handled);
  9214. D->addAttr(declAttr);
  9215. return;
  9216. }
  9217. Handled = true;
  9218. switch (A.getKind())
  9219. {
  9220. // These apply to statements, not declarations. The warning messages clarify this properly.
  9221. case AttributeList::AT_HLSLUnroll:
  9222. case AttributeList::AT_HLSLAllowUAVCondition:
  9223. case AttributeList::AT_HLSLLoop:
  9224. case AttributeList::AT_HLSLFastOpt:
  9225. S.Diag(A.getLoc(), diag::warn_hlsl_unsupported_statement_for_loop_attribute)
  9226. << A.getName();
  9227. return;
  9228. case AttributeList::AT_HLSLBranch:
  9229. case AttributeList::AT_HLSLFlatten:
  9230. S.Diag(A.getLoc(), diag::warn_hlsl_unsupported_statement_for_if_switch_attribute)
  9231. << A.getName();
  9232. return;
  9233. case AttributeList::AT_HLSLForceCase:
  9234. case AttributeList::AT_HLSLCall:
  9235. S.Diag(A.getLoc(), diag::warn_hlsl_unsupported_statement_for_switch_attribute)
  9236. << A.getName();
  9237. return;
  9238. // These are the cases that actually apply to declarations.
  9239. case AttributeList::AT_HLSLClipPlanes:
  9240. declAttr = HandleClipPlanes(S, A);
  9241. break;
  9242. case AttributeList::AT_HLSLDomain:
  9243. declAttr = ::new (S.Context) HLSLDomainAttr(A.getRange(), S.Context,
  9244. ValidateAttributeStringArg(S, A, "tri,quad,isoline"), A.getAttributeSpellingListIndex());
  9245. break;
  9246. case AttributeList::AT_HLSLEarlyDepthStencil:
  9247. declAttr = ::new (S.Context) HLSLEarlyDepthStencilAttr(A.getRange(), S.Context, A.getAttributeSpellingListIndex());
  9248. break;
  9249. case AttributeList::AT_HLSLInstance:
  9250. declAttr = ::new (S.Context) HLSLInstanceAttr(A.getRange(), S.Context,
  9251. ValidateAttributeIntArg(S, A), A.getAttributeSpellingListIndex());
  9252. break;
  9253. case AttributeList::AT_HLSLMaxTessFactor:
  9254. declAttr = ::new (S.Context) HLSLMaxTessFactorAttr(A.getRange(), S.Context,
  9255. ValidateAttributeFloatArg(S, A), A.getAttributeSpellingListIndex());
  9256. break;
  9257. case AttributeList::AT_HLSLNumThreads:
  9258. declAttr = ::new (S.Context) HLSLNumThreadsAttr(A.getRange(), S.Context,
  9259. ValidateAttributeIntArg(S, A), ValidateAttributeIntArg(S, A, 1), ValidateAttributeIntArg(S, A, 2),
  9260. A.getAttributeSpellingListIndex());
  9261. break;
  9262. case AttributeList::AT_HLSLRootSignature:
  9263. declAttr = ::new (S.Context) HLSLRootSignatureAttr(A.getRange(), S.Context,
  9264. ValidateAttributeStringArg(S, A, /*validate strings*/nullptr),
  9265. A.getAttributeSpellingListIndex());
  9266. break;
  9267. case AttributeList::AT_HLSLOutputControlPoints:
  9268. declAttr = ::new (S.Context) HLSLOutputControlPointsAttr(A.getRange(), S.Context,
  9269. ValidateAttributeIntArg(S, A), A.getAttributeSpellingListIndex());
  9270. break;
  9271. case AttributeList::AT_HLSLOutputTopology:
  9272. declAttr = ::new (S.Context) HLSLOutputTopologyAttr(A.getRange(), S.Context,
  9273. ValidateAttributeStringArg(S, A, "point,line,triangle,triangle_cw,triangle_ccw"), A.getAttributeSpellingListIndex());
  9274. break;
  9275. case AttributeList::AT_HLSLPartitioning:
  9276. declAttr = ::new (S.Context) HLSLPartitioningAttr(A.getRange(), S.Context,
  9277. ValidateAttributeStringArg(S, A, "integer,fractional_even,fractional_odd,pow2"), A.getAttributeSpellingListIndex());
  9278. break;
  9279. case AttributeList::AT_HLSLPatchConstantFunc:
  9280. declAttr = ::new (S.Context) HLSLPatchConstantFuncAttr(A.getRange(), S.Context,
  9281. ValidateAttributeStringArg(S, A, nullptr), A.getAttributeSpellingListIndex());
  9282. break;
  9283. case AttributeList::AT_HLSLShader:
  9284. declAttr = ::new (S.Context) HLSLShaderAttr(
  9285. A.getRange(), S.Context,
  9286. ValidateAttributeStringArg(S, A,
  9287. "compute,vertex,pixel,hull,domain,geometry"),
  9288. A.getAttributeSpellingListIndex());
  9289. break;
  9290. case AttributeList::AT_HLSLMaxVertexCount:
  9291. declAttr = ::new (S.Context) HLSLMaxVertexCountAttr(A.getRange(), S.Context,
  9292. ValidateAttributeIntArg(S, A), A.getAttributeSpellingListIndex());
  9293. break;
  9294. case AttributeList::AT_HLSLExperimental:
  9295. declAttr = ::new (S.Context) HLSLExperimentalAttr(A.getRange(), S.Context,
  9296. ValidateAttributeStringArg(S, A, nullptr, 0), ValidateAttributeStringArg(S, A, nullptr, 1),
  9297. A.getAttributeSpellingListIndex());
  9298. break;
  9299. case AttributeList::AT_NoInline:
  9300. declAttr = ::new (S.Context) NoInlineAttr(A.getRange(), S.Context, A.getAttributeSpellingListIndex());
  9301. break;
  9302. default:
  9303. Handled = false;
  9304. break; // SPIRV Change: was return;
  9305. }
  9306. if (declAttr != nullptr)
  9307. {
  9308. DXASSERT_NOMSG(Handled);
  9309. D->addAttr(declAttr);
  9310. // The attribute has been set but will have no effect. Validation will emit a diagnostic
  9311. // and prevent code generation.
  9312. ValidateAttributeTargetIsFunction(S, D, A);
  9313. return; // SPIRV Change
  9314. }
  9315. // SPIRV Change Starts
  9316. Handled = true;
  9317. switch (A.getKind())
  9318. {
  9319. case AttributeList::AT_VKBuiltIn:
  9320. declAttr = ::new (S.Context) VKBuiltInAttr(A.getRange(), S.Context,
  9321. ValidateAttributeStringArg(S, A, "PointSize,HelperInvocation,BaseVertex,BaseInstance,DrawIndex,DeviceIndex"),
  9322. A.getAttributeSpellingListIndex());
  9323. break;
  9324. case AttributeList::AT_VKLocation:
  9325. declAttr = ::new (S.Context) VKLocationAttr(A.getRange(), S.Context,
  9326. ValidateAttributeIntArg(S, A), A.getAttributeSpellingListIndex());
  9327. break;
  9328. case AttributeList::AT_VKIndex:
  9329. declAttr = ::new (S.Context) VKIndexAttr(A.getRange(), S.Context,
  9330. ValidateAttributeIntArg(S, A), A.getAttributeSpellingListIndex());
  9331. break;
  9332. case AttributeList::AT_VKBinding:
  9333. declAttr = ::new (S.Context) VKBindingAttr(A.getRange(), S.Context,
  9334. ValidateAttributeIntArg(S, A), ValidateAttributeIntArg(S, A, 1),
  9335. A.getAttributeSpellingListIndex());
  9336. break;
  9337. case AttributeList::AT_VKCounterBinding:
  9338. declAttr = ::new (S.Context) VKCounterBindingAttr(A.getRange(), S.Context,
  9339. ValidateAttributeIntArg(S, A), A.getAttributeSpellingListIndex());
  9340. break;
  9341. case AttributeList::AT_VKPushConstant:
  9342. declAttr = ::new (S.Context) VKPushConstantAttr(A.getRange(), S.Context,
  9343. A.getAttributeSpellingListIndex());
  9344. break;
  9345. case AttributeList::AT_VKOffset:
  9346. declAttr = ::new (S.Context) VKOffsetAttr(A.getRange(), S.Context,
  9347. ValidateAttributeIntArg(S, A), A.getAttributeSpellingListIndex());
  9348. break;
  9349. case AttributeList::AT_VKInputAttachmentIndex:
  9350. declAttr = ::new (S.Context) VKInputAttachmentIndexAttr(
  9351. A.getRange(), S.Context, ValidateAttributeIntArg(S, A),
  9352. A.getAttributeSpellingListIndex());
  9353. break;
  9354. case AttributeList::AT_VKConstantId:
  9355. declAttr = ::new (S.Context) VKConstantIdAttr(A.getRange(), S.Context,
  9356. ValidateAttributeIntArg(S, A), A.getAttributeSpellingListIndex());
  9357. break;
  9358. default:
  9359. Handled = false;
  9360. return;
  9361. }
  9362. if (declAttr != nullptr)
  9363. {
  9364. DXASSERT_NOMSG(Handled);
  9365. D->addAttr(declAttr);
  9366. }
  9367. // SPIRV Change Ends
  9368. }
  9369. /// <summary>Processes an attribute for a statement.</summary>
  9370. /// <param name="S">Sema with context.</param>
  9371. /// <param name="St">Statement annotated.</param>
  9372. /// <param name="A">Single parsed attribute to process.</param>
  9373. /// <param name="Range">Range of all attribute lists (useful for FixIts to suggest inclusions).</param>
  9374. /// <param name="Handled">After execution, whether this was recognized and handled.</param>
  9375. /// <returns>An attribute instance if processed, nullptr if not recognized or an error was found.</returns>
  9376. Attr *hlsl::ProcessStmtAttributeForHLSL(Sema &S, Stmt *St, const AttributeList &A, SourceRange Range, bool& Handled)
  9377. {
  9378. // | Construct | Allowed Attributes |
  9379. // +------------------+--------------------------------------------+
  9380. // | for, while, do | loop, fastopt, unroll, allow_uav_condition |
  9381. // | if | branch, flatten |
  9382. // | switch | branch, flatten, forcecase, call |
  9383. Attr * result = nullptr;
  9384. Handled = true;
  9385. switch (A.getKind())
  9386. {
  9387. case AttributeList::AT_HLSLUnroll:
  9388. ValidateAttributeOnLoop(S, St, A);
  9389. result = HandleUnrollAttribute(S, A);
  9390. break;
  9391. case AttributeList::AT_HLSLAllowUAVCondition:
  9392. ValidateAttributeOnLoop(S, St, A);
  9393. result = ::new (S.Context) HLSLAllowUAVConditionAttr(
  9394. A.getRange(), S.Context, A.getAttributeSpellingListIndex());
  9395. break;
  9396. case AttributeList::AT_HLSLLoop:
  9397. ValidateAttributeOnLoop(S, St, A);
  9398. result = ::new (S.Context) HLSLLoopAttr(
  9399. A.getRange(), S.Context, A.getAttributeSpellingListIndex());
  9400. break;
  9401. case AttributeList::AT_HLSLFastOpt:
  9402. ValidateAttributeOnLoop(S, St, A);
  9403. result = ::new (S.Context) HLSLFastOptAttr(
  9404. A.getRange(), S.Context, A.getAttributeSpellingListIndex());
  9405. break;
  9406. case AttributeList::AT_HLSLBranch:
  9407. ValidateAttributeOnSwitchOrIf(S, St, A);
  9408. result = ::new (S.Context) HLSLBranchAttr(
  9409. A.getRange(), S.Context, A.getAttributeSpellingListIndex());
  9410. break;
  9411. case AttributeList::AT_HLSLFlatten:
  9412. ValidateAttributeOnSwitchOrIf(S, St, A);
  9413. result = ::new (S.Context) HLSLFlattenAttr(
  9414. A.getRange(), S.Context, A.getAttributeSpellingListIndex());
  9415. break;
  9416. case AttributeList::AT_HLSLForceCase:
  9417. ValidateAttributeOnSwitch(S, St, A);
  9418. result = ::new (S.Context) HLSLForceCaseAttr(
  9419. A.getRange(), S.Context, A.getAttributeSpellingListIndex());
  9420. break;
  9421. case AttributeList::AT_HLSLCall:
  9422. ValidateAttributeOnSwitch(S, St, A);
  9423. result = ::new (S.Context) HLSLCallAttr(
  9424. A.getRange(), S.Context, A.getAttributeSpellingListIndex());
  9425. break;
  9426. default:
  9427. Handled = false;
  9428. break;
  9429. }
  9430. return result;
  9431. }
  9432. ////////////////////////////////////////////////////////////////////////////////
  9433. // Implementation of Sema members. //
  9434. Decl* Sema::ActOnStartHLSLBuffer(
  9435. Scope* bufferScope,
  9436. bool cbuffer, SourceLocation KwLoc,
  9437. IdentifierInfo *Ident, SourceLocation IdentLoc,
  9438. std::vector<hlsl::UnusualAnnotation *>& BufferAttributes,
  9439. SourceLocation LBrace)
  9440. {
  9441. // For anonymous namespace, take the location of the left brace.
  9442. DeclContext* lexicalParent = getCurLexicalContext();
  9443. clang::HLSLBufferDecl *result = HLSLBufferDecl::Create(
  9444. Context, lexicalParent, cbuffer, /*isConstantBufferView*/ false, KwLoc,
  9445. Ident, IdentLoc, BufferAttributes, LBrace);
  9446. // Keep track of the currently active buffer.
  9447. HLSLBuffers.push_back(result);
  9448. // Validate unusual annotations and emit diagnostics.
  9449. DiagnoseUnusualAnnotationsForHLSL(*this, BufferAttributes);
  9450. auto && unusualIter = BufferAttributes.begin();
  9451. auto && unusualEnd = BufferAttributes.end();
  9452. char expectedRegisterType = cbuffer ? 'b' : 't';
  9453. for (; unusualIter != unusualEnd; ++unusualIter) {
  9454. switch ((*unusualIter)->getKind()) {
  9455. case hlsl::UnusualAnnotation::UA_ConstantPacking: {
  9456. hlsl::ConstantPacking* constantPacking = cast<hlsl::ConstantPacking>(*unusualIter);
  9457. Diag(constantPacking->Loc, diag::err_hlsl_unsupported_buffer_packoffset);
  9458. break;
  9459. }
  9460. case hlsl::UnusualAnnotation::UA_RegisterAssignment: {
  9461. hlsl::RegisterAssignment* registerAssignment = cast<hlsl::RegisterAssignment>(*unusualIter);
  9462. if (registerAssignment->RegisterType != expectedRegisterType && registerAssignment->RegisterType != toupper(expectedRegisterType)) {
  9463. Diag(registerAssignment->Loc, cbuffer ? diag::err_hlsl_unsupported_cbuffer_register :
  9464. diag::err_hlsl_unsupported_tbuffer_register);
  9465. } else if (registerAssignment->ShaderProfile.size() > 0) {
  9466. Diag(registerAssignment->Loc, diag::err_hlsl_unsupported_buffer_slot_target_specific);
  9467. }
  9468. break;
  9469. }
  9470. case hlsl::UnusualAnnotation::UA_SemanticDecl: {
  9471. // Ignore semantic declarations.
  9472. break;
  9473. }
  9474. }
  9475. }
  9476. PushOnScopeChains(result, bufferScope);
  9477. PushDeclContext(bufferScope, result);
  9478. ActOnDocumentableDecl(result);
  9479. return result;
  9480. }
  9481. void Sema::ActOnFinishHLSLBuffer(Decl *Dcl, SourceLocation RBrace)
  9482. {
  9483. DXASSERT_NOMSG(Dcl != nullptr);
  9484. DXASSERT(Dcl == HLSLBuffers.back(), "otherwise push/pop is incorrect");
  9485. dyn_cast<HLSLBufferDecl>(Dcl)->setRBraceLoc(RBrace);
  9486. HLSLBuffers.pop_back();
  9487. PopDeclContext();
  9488. }
  9489. Decl* Sema::getActiveHLSLBuffer() const
  9490. {
  9491. return HLSLBuffers.empty() ? nullptr : HLSLBuffers.back();
  9492. }
  9493. Decl *Sema::ActOnHLSLBufferView(Scope *bufferScope, SourceLocation KwLoc,
  9494. DeclGroupPtrTy &dcl, bool iscbuf) {
  9495. DXASSERT(nullptr == HLSLBuffers.back(), "otherwise push/pop is incorrect");
  9496. HLSLBuffers.pop_back();
  9497. DXASSERT(HLSLBuffers.empty(), "otherwise push/pop is incorrect");
  9498. Decl *decl = dcl.get().getSingleDecl();
  9499. NamedDecl *namedDecl = cast<NamedDecl>(decl);
  9500. IdentifierInfo *Ident = namedDecl->getIdentifier();
  9501. // No anonymous namespace for ConstantBuffer, take the location of the decl.
  9502. SourceLocation Loc = decl->getLocation();
  9503. // Prevent array type in template. The only way to specify an array in the template type
  9504. // is to use a typedef, so we will strip non-typedef arrays off, since these are the legal
  9505. // array dimensions for the CBV/TBV, and if any array type remains, that is illegal.
  9506. QualType declType = cast<VarDecl>(namedDecl)->getType();
  9507. while (declType->isArrayType() && declType->getTypeClass() != Type::TypeClass::Typedef) {
  9508. const ArrayType *arrayType = declType->getAsArrayTypeUnsafe();
  9509. declType = arrayType->getElementType();
  9510. }
  9511. // Check to make that sure only structs are allowed as parameter types for
  9512. // ConstantBuffer and TextureBuffer.
  9513. if (!declType->isStructureType()) {
  9514. Diag(decl->getLocStart(),
  9515. diag::err_hlsl_typeintemplateargument_requires_struct)
  9516. << declType;
  9517. return nullptr;
  9518. }
  9519. std::vector<hlsl::UnusualAnnotation *> hlslAttrs;
  9520. DeclContext *lexicalParent = getCurLexicalContext();
  9521. clang::HLSLBufferDecl *result = HLSLBufferDecl::Create(
  9522. Context, lexicalParent, iscbuf, /*isConstantBufferView*/ true,
  9523. KwLoc, Ident, Loc, hlslAttrs, Loc);
  9524. // set relation
  9525. namedDecl->setDeclContext(result);
  9526. result->addDecl(namedDecl);
  9527. // move attribute from constant to constant buffer
  9528. result->setUnusualAnnotations(namedDecl->getUnusualAnnotations());
  9529. namedDecl->setUnusualAnnotations(hlslAttrs);
  9530. return result;
  9531. }
  9532. bool Sema::IsOnHLSLBufferView() {
  9533. // nullptr will not pushed for cbuffer.
  9534. return !HLSLBuffers.empty() && getActiveHLSLBuffer() == nullptr;
  9535. }
  9536. void Sema::ActOnStartHLSLBufferView() {
  9537. // Push nullptr to mark HLSLBufferView.
  9538. DXASSERT(HLSLBuffers.empty(), "otherwise push/pop is incorrect");
  9539. HLSLBuffers.emplace_back(nullptr);
  9540. }
  9541. HLSLBufferDecl::HLSLBufferDecl(
  9542. DeclContext *DC, bool cbuffer, bool cbufferView, SourceLocation KwLoc,
  9543. IdentifierInfo *Id, SourceLocation IdLoc,
  9544. std::vector<hlsl::UnusualAnnotation *> &BufferAttributes,
  9545. SourceLocation LBrace)
  9546. : NamedDecl(Decl::HLSLBuffer, DC, IdLoc, DeclarationName(Id)),
  9547. DeclContext(Decl::HLSLBuffer), LBraceLoc(LBrace), KwLoc(KwLoc),
  9548. IsCBuffer(cbuffer), IsConstantBufferView(cbufferView) {
  9549. if (!BufferAttributes.empty()) {
  9550. setUnusualAnnotations(UnusualAnnotation::CopyToASTContextArray(
  9551. getASTContext(), BufferAttributes.data(), BufferAttributes.size()));
  9552. }
  9553. }
  9554. HLSLBufferDecl *
  9555. HLSLBufferDecl::Create(ASTContext &C, DeclContext *lexicalParent, bool cbuffer,
  9556. bool constantbuffer, SourceLocation KwLoc,
  9557. IdentifierInfo *Id, SourceLocation IdLoc,
  9558. std::vector<hlsl::UnusualAnnotation *> &BufferAttributes,
  9559. SourceLocation LBrace) {
  9560. DeclContext *DC = C.getTranslationUnitDecl();
  9561. HLSLBufferDecl *result = ::new (C) HLSLBufferDecl(
  9562. DC, cbuffer, constantbuffer, KwLoc, Id, IdLoc, BufferAttributes, LBrace);
  9563. if (DC != lexicalParent) {
  9564. result->setLexicalDeclContext(lexicalParent);
  9565. }
  9566. return result;
  9567. }
  9568. const char *HLSLBufferDecl::getDeclKindName() const {
  9569. static const char *HLSLBufferNames[] = {"tbuffer", "cbuffer", "TextureBuffer",
  9570. "ConstantBuffer"};
  9571. unsigned index = (unsigned ) isCBuffer() | (isConstantBufferView()) << 1;
  9572. return HLSLBufferNames[index];
  9573. }
  9574. void Sema::TransferUnusualAttributes(Declarator &D, NamedDecl *NewDecl) {
  9575. assert(NewDecl != nullptr);
  9576. if (!getLangOpts().HLSL) {
  9577. return;
  9578. }
  9579. if (!D.UnusualAnnotations.empty()) {
  9580. NewDecl->setUnusualAnnotations(UnusualAnnotation::CopyToASTContextArray(
  9581. getASTContext(), D.UnusualAnnotations.data(),
  9582. D.UnusualAnnotations.size()));
  9583. D.UnusualAnnotations.clear();
  9584. }
  9585. }
  9586. /// Checks whether a usage attribute is compatible with those seen so far and
  9587. /// maintains history.
  9588. static bool IsUsageAttributeCompatible(AttributeList::Kind kind, bool &usageIn,
  9589. bool &usageOut) {
  9590. switch (kind) {
  9591. case AttributeList::AT_HLSLIn:
  9592. if (usageIn)
  9593. return false;
  9594. usageIn = true;
  9595. break;
  9596. case AttributeList::AT_HLSLOut:
  9597. if (usageOut)
  9598. return false;
  9599. usageOut = true;
  9600. break;
  9601. default:
  9602. assert(kind == AttributeList::AT_HLSLInOut);
  9603. if (usageOut || usageIn)
  9604. return false;
  9605. usageIn = usageOut = true;
  9606. break;
  9607. }
  9608. return true;
  9609. }
  9610. // Diagnose valid/invalid modifiers for HLSL.
  9611. bool Sema::DiagnoseHLSLDecl(Declarator &D, DeclContext *DC,
  9612. TypeSourceInfo *TInfo, bool isParameter) {
  9613. assert(getLangOpts().HLSL &&
  9614. "otherwise this is called without checking language first");
  9615. // NOTE: some tests may declare templates.
  9616. if (DC->isNamespace() || DC->isDependentContext()) return true;
  9617. DeclSpec::SCS storage = D.getDeclSpec().getStorageClassSpec();
  9618. assert(!DC->isClosure() && "otherwise parser accepted closure syntax instead of failing with a syntax error");
  9619. assert(!DC->isDependentContext() && "otherwise parser accepted a template instead of failing with a syntax error");
  9620. assert(!DC->isNamespace() && "otherwise parser accepted a namespace instead of failing a syntax error");
  9621. bool result = true;
  9622. bool isTypedef = storage == DeclSpec::SCS_typedef;
  9623. bool isFunction = D.isFunctionDeclarator() && !DC->isRecord();
  9624. bool isLocalVar = DC->isFunctionOrMethod() && !isFunction && !isTypedef;
  9625. bool isGlobal = !isParameter && !isTypedef && !isFunction && (DC->isTranslationUnit() || DC->getDeclKind() == Decl::HLSLBuffer);
  9626. bool isMethod = DC->isRecord() && D.isFunctionDeclarator() && !isTypedef;
  9627. bool isField = DC->isRecord() && !D.isFunctionDeclarator() && !isTypedef;
  9628. bool isConst = D.getDeclSpec().getTypeQualifiers() & DeclSpec::TQ::TQ_const;
  9629. bool isVolatile = D.getDeclSpec().getTypeQualifiers() & DeclSpec::TQ::TQ_volatile;
  9630. bool isStatic = storage == DeclSpec::SCS::SCS_static;
  9631. bool isExtern = storage == DeclSpec::SCS::SCS_extern;
  9632. bool hasSignSpec = D.getDeclSpec().getTypeSpecSign() != DeclSpec::TSS::TSS_unspecified;
  9633. // Function declarations are not allowed in parameter declaration
  9634. // TODO : Remove this check once we support function declarations/pointers in HLSL
  9635. if (isParameter && isFunction) {
  9636. Diag(D.getLocStart(), diag::err_hlsl_func_in_func_decl);
  9637. D.setInvalidType();
  9638. return false;
  9639. }
  9640. assert(
  9641. (1 == (isLocalVar ? 1 : 0) + (isGlobal ? 1 : 0) + (isField ? 1 : 0) +
  9642. (isTypedef ? 1 : 0) + (isFunction ? 1 : 0) + (isMethod ? 1 : 0) +
  9643. (isParameter ? 1 : 0))
  9644. && "exactly one type of declarator is being processed");
  9645. // qt/pType captures either the type being modified, or the return type in the
  9646. // case of a function (or method).
  9647. QualType qt = TInfo->getType();
  9648. const Type* pType = qt.getTypePtrOrNull();
  9649. // Early checks - these are not simple attribution errors, but constructs that
  9650. // are fundamentally unsupported,
  9651. // and so we avoid errors that might indicate they can be repaired.
  9652. if (DC->isRecord()) {
  9653. unsigned int nestedDiagId = 0;
  9654. if (isTypedef) {
  9655. nestedDiagId = diag::err_hlsl_unsupported_nested_typedef;
  9656. }
  9657. if (isField && pType && pType->isIncompleteArrayType()) {
  9658. nestedDiagId = diag::err_hlsl_unsupported_incomplete_array;
  9659. }
  9660. if (nestedDiagId) {
  9661. Diag(D.getLocStart(), nestedDiagId);
  9662. D.setInvalidType();
  9663. return false;
  9664. }
  9665. }
  9666. const char* declarationType =
  9667. (isLocalVar) ? "local variable" :
  9668. (isTypedef) ? "typedef" :
  9669. (isFunction) ? "function" :
  9670. (isMethod) ? "method" :
  9671. (isGlobal) ? "global variable" :
  9672. (isParameter) ? "parameter" :
  9673. (isField) ? "field" : "<unknown>";
  9674. if (pType && D.isFunctionDeclarator()) {
  9675. const FunctionProtoType *pFP = pType->getAs<FunctionProtoType>();
  9676. if (pFP) {
  9677. qt = pFP->getReturnType();
  9678. pType = qt.getTypePtrOrNull();
  9679. }
  9680. }
  9681. // Check for deprecated effect object type here, warn, and invalidate decl
  9682. bool bDeprecatedEffectObject = false;
  9683. bool bIsObject = false;
  9684. if (hlsl::IsObjectType(this, qt, &bDeprecatedEffectObject)) {
  9685. bIsObject = true;
  9686. if (bDeprecatedEffectObject) {
  9687. Diag(D.getLocStart(), diag::warn_hlsl_effect_object);
  9688. D.setInvalidType();
  9689. return false;
  9690. }
  9691. // Add methods if not ready.
  9692. HLSLExternalSource *hlslSource = HLSLExternalSource::FromSema(this);
  9693. hlslSource->AddHLSLObjectMethodsIfNotReady(qt);
  9694. } else if (qt->isArrayType()) {
  9695. QualType eltQt(qt->getArrayElementTypeNoTypeQual(), 0);
  9696. while (eltQt->isArrayType())
  9697. eltQt = QualType(eltQt->getArrayElementTypeNoTypeQual(), 0);
  9698. if (hlsl::IsObjectType(this, eltQt, &bDeprecatedEffectObject)) {
  9699. // Add methods if not ready.
  9700. HLSLExternalSource *hlslSource = HLSLExternalSource::FromSema(this);
  9701. hlslSource->AddHLSLObjectMethodsIfNotReady(eltQt);
  9702. }
  9703. }
  9704. if (isExtern) {
  9705. if (!(isFunction || isGlobal)) {
  9706. Diag(D.getLocStart(), diag::err_hlsl_varmodifierna) << "'extern'"
  9707. << declarationType;
  9708. result = false;
  9709. }
  9710. }
  9711. if (isStatic) {
  9712. if (!(isLocalVar || isGlobal || isFunction || isMethod || isField)) {
  9713. Diag(D.getLocStart(), diag::err_hlsl_varmodifierna) << "'static'"
  9714. << declarationType;
  9715. result = false;
  9716. }
  9717. }
  9718. if (isVolatile) {
  9719. if (!(isLocalVar || isTypedef)) {
  9720. Diag(D.getLocStart(), diag::err_hlsl_varmodifierna) << "'volatile'"
  9721. << declarationType;
  9722. result = false;
  9723. }
  9724. }
  9725. if (isConst) {
  9726. if (isField && !isStatic) {
  9727. Diag(D.getLocStart(), diag::err_hlsl_varmodifierna) << "'const'"
  9728. << declarationType;
  9729. result = false;
  9730. }
  9731. }
  9732. HLSLExternalSource *hlslSource = HLSLExternalSource::FromSema(this);
  9733. ArBasicKind basicKind = hlslSource->GetTypeElementKind(qt);
  9734. if (hasSignSpec) {
  9735. ArTypeObjectKind objKind = hlslSource->GetTypeObjectKind(qt);
  9736. // vectors or matrices can only have unsigned integer types.
  9737. if (objKind == AR_TOBJ_MATRIX || objKind == AR_TOBJ_VECTOR || objKind == AR_TOBJ_BASIC || objKind == AR_TOBJ_ARRAY) {
  9738. if (!IS_BASIC_UNSIGNABLE(basicKind)) {
  9739. Diag(D.getLocStart(), diag::err_sema_invalid_sign_spec)
  9740. << g_ArBasicTypeNames[basicKind];
  9741. result = false;
  9742. }
  9743. }
  9744. else {
  9745. Diag(D.getLocStart(), diag::err_sema_invalid_sign_spec) << g_ArBasicTypeNames[basicKind];
  9746. result = false;
  9747. }
  9748. }
  9749. // Validate attributes
  9750. clang::AttributeList
  9751. *pUniform = nullptr,
  9752. *pUsage = nullptr,
  9753. *pNoInterpolation = nullptr,
  9754. *pLinear = nullptr,
  9755. *pNoPerspective = nullptr,
  9756. *pSample = nullptr,
  9757. *pCentroid = nullptr,
  9758. *pAnyLinear = nullptr, // first linear attribute found
  9759. *pTopology = nullptr;
  9760. bool usageIn = false;
  9761. bool usageOut = false;
  9762. for (clang::AttributeList *pAttr = D.getDeclSpec().getAttributes().getList();
  9763. pAttr != NULL; pAttr = pAttr->getNext()) {
  9764. if (pAttr->isInvalid() || pAttr->isUsedAsTypeAttr())
  9765. continue;
  9766. switch (pAttr->getKind()) {
  9767. case AttributeList::AT_HLSLPrecise: // precise is applicable everywhere.
  9768. break;
  9769. case AttributeList::AT_HLSLShared:
  9770. if (!isGlobal) {
  9771. Diag(pAttr->getLoc(), diag::err_hlsl_varmodifierna)
  9772. << pAttr->getName() << declarationType << pAttr->getRange();
  9773. result = false;
  9774. }
  9775. if (isStatic) {
  9776. Diag(pAttr->getLoc(), diag::err_hlsl_varmodifiersna)
  9777. << "'static'" << pAttr->getName() << declarationType
  9778. << pAttr->getRange();
  9779. result = false;
  9780. }
  9781. break;
  9782. case AttributeList::AT_HLSLGroupShared:
  9783. if (!isGlobal) {
  9784. Diag(pAttr->getLoc(), diag::err_hlsl_varmodifierna)
  9785. << pAttr->getName() << declarationType << pAttr->getRange();
  9786. result = false;
  9787. }
  9788. if (isExtern) {
  9789. Diag(pAttr->getLoc(), diag::err_hlsl_varmodifiersna)
  9790. << "'extern'" << pAttr->getName() << declarationType
  9791. << pAttr->getRange();
  9792. result = false;
  9793. }
  9794. break;
  9795. case AttributeList::AT_HLSLGloballyCoherent:
  9796. if (!bIsObject) {
  9797. Diag(pAttr->getLoc(), diag::err_hlsl_varmodifierna)
  9798. << pAttr->getName() << "non-UAV type";
  9799. result = false;
  9800. }
  9801. break;
  9802. case AttributeList::AT_HLSLUniform:
  9803. if (!(isGlobal || isParameter)) {
  9804. Diag(pAttr->getLoc(), diag::err_hlsl_varmodifierna)
  9805. << pAttr->getName() << declarationType << pAttr->getRange();
  9806. result = false;
  9807. }
  9808. if (isStatic) {
  9809. Diag(pAttr->getLoc(), diag::err_hlsl_varmodifiersna)
  9810. << "'static'" << pAttr->getName() << declarationType
  9811. << pAttr->getRange();
  9812. result = false;
  9813. }
  9814. pUniform = pAttr;
  9815. break;
  9816. case AttributeList::AT_HLSLIn:
  9817. case AttributeList::AT_HLSLOut:
  9818. case AttributeList::AT_HLSLInOut:
  9819. if (!isParameter) {
  9820. Diag(pAttr->getLoc(), diag::err_hlsl_usage_not_on_parameter)
  9821. << pAttr->getName() << pAttr->getRange();
  9822. result = false;
  9823. }
  9824. if (!IsUsageAttributeCompatible(pAttr->getKind(), usageIn, usageOut)) {
  9825. Diag(pAttr->getLoc(), diag::err_hlsl_duplicate_parameter_usages)
  9826. << pAttr->getName() << pAttr->getRange();
  9827. result = false;
  9828. }
  9829. pUsage = pAttr;
  9830. break;
  9831. case AttributeList::AT_HLSLNoInterpolation:
  9832. if (!(isParameter || isField || isFunction)) {
  9833. Diag(pAttr->getLoc(), diag::err_hlsl_varmodifierna)
  9834. << pAttr->getName() << declarationType << pAttr->getRange();
  9835. result = false;
  9836. }
  9837. if (pNoInterpolation) {
  9838. Diag(pAttr->getLoc(), diag::warn_hlsl_duplicate_specifier)
  9839. << pAttr->getName() << pAttr->getRange();
  9840. }
  9841. pNoInterpolation = pAttr;
  9842. break;
  9843. case AttributeList::AT_HLSLLinear:
  9844. case AttributeList::AT_HLSLNoPerspective:
  9845. case AttributeList::AT_HLSLSample:
  9846. case AttributeList::AT_HLSLCentroid:
  9847. if (!(isParameter || isField || isFunction)) {
  9848. Diag(pAttr->getLoc(), diag::err_hlsl_varmodifierna)
  9849. << pAttr->getName() << declarationType << pAttr->getRange();
  9850. result = false;
  9851. }
  9852. if (nullptr == pAnyLinear)
  9853. pAnyLinear = pAttr;
  9854. switch (pAttr->getKind()) {
  9855. case AttributeList::AT_HLSLLinear:
  9856. if (pLinear) {
  9857. Diag(pAttr->getLoc(), diag::warn_hlsl_duplicate_specifier)
  9858. << pAttr->getName() << pAttr->getRange();
  9859. }
  9860. pLinear = pAttr;
  9861. break;
  9862. case AttributeList::AT_HLSLNoPerspective:
  9863. if (pNoPerspective) {
  9864. Diag(pAttr->getLoc(), diag::warn_hlsl_duplicate_specifier)
  9865. << pAttr->getName() << pAttr->getRange();
  9866. }
  9867. pNoPerspective = pAttr;
  9868. break;
  9869. case AttributeList::AT_HLSLSample:
  9870. if (pSample) {
  9871. Diag(pAttr->getLoc(), diag::warn_hlsl_duplicate_specifier)
  9872. << pAttr->getName() << pAttr->getRange();
  9873. }
  9874. pSample = pAttr;
  9875. break;
  9876. case AttributeList::AT_HLSLCentroid:
  9877. if (pCentroid) {
  9878. Diag(pAttr->getLoc(), diag::warn_hlsl_duplicate_specifier)
  9879. << pAttr->getName() << pAttr->getRange();
  9880. }
  9881. pCentroid = pAttr;
  9882. break;
  9883. default:
  9884. // Only relevant to the four attribs included in this block.
  9885. break;
  9886. }
  9887. break;
  9888. case AttributeList::AT_HLSLPoint:
  9889. case AttributeList::AT_HLSLLine:
  9890. case AttributeList::AT_HLSLLineAdj:
  9891. case AttributeList::AT_HLSLTriangle:
  9892. case AttributeList::AT_HLSLTriangleAdj:
  9893. if (!(isParameter)) {
  9894. Diag(pAttr->getLoc(), diag::err_hlsl_varmodifierna)
  9895. << pAttr->getName() << declarationType << pAttr->getRange();
  9896. result = false;
  9897. }
  9898. if (pTopology) {
  9899. if (pTopology->getKind() == pAttr->getKind()) {
  9900. Diag(pAttr->getLoc(), diag::warn_hlsl_duplicate_specifier)
  9901. << pAttr->getName() << pAttr->getRange();
  9902. } else {
  9903. Diag(pAttr->getLoc(), diag::err_hlsl_varmodifiersna)
  9904. << pAttr->getName() << pTopology->getName()
  9905. << declarationType << pAttr->getRange();
  9906. result = false;
  9907. }
  9908. }
  9909. pTopology = pAttr;
  9910. break;
  9911. default:
  9912. break;
  9913. }
  9914. }
  9915. if (pNoInterpolation && pAnyLinear) {
  9916. Diag(pNoInterpolation->getLoc(), diag::err_hlsl_varmodifiersna)
  9917. << pNoInterpolation->getName() << pAnyLinear->getName()
  9918. << declarationType << pNoInterpolation->getRange();
  9919. result = false;
  9920. }
  9921. if (pSample && pCentroid) {
  9922. Diag(pCentroid->getLoc(), diag::warn_hlsl_specifier_overridden)
  9923. << pCentroid->getName() << pSample->getName() << pCentroid->getRange();
  9924. }
  9925. clang::AttributeList *pNonUniformAttr = pAnyLinear ? pAnyLinear : (
  9926. pNoInterpolation ? pNoInterpolation : pTopology);
  9927. if (pUniform && pNonUniformAttr) {
  9928. Diag(pUniform->getLoc(), diag::err_hlsl_varmodifiersna)
  9929. << pNonUniformAttr->getName()
  9930. << pUniform->getName() << declarationType << pUniform->getRange();
  9931. result = false;
  9932. }
  9933. if (pAnyLinear && pTopology) {
  9934. Diag(pAnyLinear->getLoc(), diag::err_hlsl_varmodifiersna)
  9935. << pTopology->getName()
  9936. << pAnyLinear->getName() << declarationType << pAnyLinear->getRange();
  9937. result = false;
  9938. }
  9939. if (pNoInterpolation && pTopology) {
  9940. Diag(pNoInterpolation->getLoc(), diag::err_hlsl_varmodifiersna)
  9941. << pTopology->getName()
  9942. << pNoInterpolation->getName() << declarationType << pNoInterpolation->getRange();
  9943. result = false;
  9944. }
  9945. if (pUniform && pUsage) {
  9946. if (pUsage->getKind() != AttributeList::Kind::AT_HLSLIn) {
  9947. Diag(pUniform->getLoc(), diag::err_hlsl_varmodifiersna)
  9948. << pUsage->getName() << pUniform->getName() << declarationType
  9949. << pUniform->getRange();
  9950. result = false;
  9951. }
  9952. }
  9953. // Validate that stream-ouput objects are marked as inout
  9954. if (isParameter && !(usageIn && usageOut) &&
  9955. (basicKind == ArBasicKind::AR_OBJECT_LINESTREAM ||
  9956. basicKind == ArBasicKind::AR_OBJECT_POINTSTREAM ||
  9957. basicKind == ArBasicKind::AR_OBJECT_TRIANGLESTREAM)) {
  9958. Diag(D.getLocStart(), diag::err_hlsl_missing_inout_attr);
  9959. result = false;
  9960. }
  9961. // SPIRV change starts
  9962. #ifdef ENABLE_SPIRV_CODEGEN
  9963. // Validate that Vulkan specific feature is only used when targeting SPIR-V
  9964. if (!getLangOpts().SPIRV) {
  9965. if (basicKind == ArBasicKind::AR_OBJECT_VK_SUBPASS_INPUT ||
  9966. basicKind == ArBasicKind::AR_OBJECT_VK_SUBPASS_INPUT_MS) {
  9967. Diag(D.getLocStart(), diag::err_hlsl_vulkan_specific_feature)
  9968. << g_ArBasicTypeNames[basicKind];
  9969. result = false;
  9970. }
  9971. }
  9972. #endif // ENABLE_SPIRV_CODEGEN
  9973. // SPIRV change ends
  9974. // Validate unusual annotations.
  9975. hlsl::DiagnoseUnusualAnnotationsForHLSL(*this, D.UnusualAnnotations);
  9976. auto && unusualIter = D.UnusualAnnotations.begin();
  9977. auto && unusualEnd = D.UnusualAnnotations.end();
  9978. for (; unusualIter != unusualEnd; ++unusualIter) {
  9979. switch ((*unusualIter)->getKind()) {
  9980. case hlsl::UnusualAnnotation::UA_ConstantPacking: {
  9981. hlsl::ConstantPacking *constantPacking =
  9982. cast<hlsl::ConstantPacking>(*unusualIter);
  9983. if (!isGlobal || HLSLBuffers.size() == 0) {
  9984. Diag(constantPacking->Loc, diag::err_hlsl_packoffset_requires_cbuffer);
  9985. continue;
  9986. }
  9987. if (constantPacking->ComponentOffset > 0) {
  9988. // Validate that this will fit.
  9989. if (!qt.isNull()) {
  9990. hlsl::DiagnosePackingOffset(this, constantPacking->Loc, qt,
  9991. constantPacking->ComponentOffset);
  9992. }
  9993. }
  9994. break;
  9995. }
  9996. case hlsl::UnusualAnnotation::UA_RegisterAssignment: {
  9997. hlsl::RegisterAssignment *registerAssignment =
  9998. cast<hlsl::RegisterAssignment>(*unusualIter);
  9999. if (registerAssignment->IsValid) {
  10000. if (!qt.isNull()) {
  10001. hlsl::DiagnoseRegisterType(this, registerAssignment->Loc, qt,
  10002. registerAssignment->RegisterType);
  10003. }
  10004. }
  10005. break;
  10006. }
  10007. case hlsl::UnusualAnnotation::UA_SemanticDecl: {
  10008. hlsl::SemanticDecl *semanticDecl = cast<hlsl::SemanticDecl>(*unusualIter);
  10009. if (isTypedef || isLocalVar) {
  10010. Diag(semanticDecl->Loc, diag::err_hlsl_varmodifierna)
  10011. << "semantic" << declarationType;
  10012. }
  10013. break;
  10014. }
  10015. }
  10016. }
  10017. if (!result) {
  10018. D.setInvalidType();
  10019. }
  10020. return result;
  10021. }
  10022. // Diagnose HLSL types on lookup
  10023. bool Sema::DiagnoseHLSLLookup(const LookupResult &R) {
  10024. const DeclarationNameInfo declName = R.getLookupNameInfo();
  10025. IdentifierInfo* idInfo = declName.getName().getAsIdentifierInfo();
  10026. if (idInfo) {
  10027. StringRef nameIdentifier = idInfo->getName();
  10028. HLSLScalarType parsedType;
  10029. int rowCount, colCount;
  10030. if (TryParseAny(nameIdentifier.data(), nameIdentifier.size(), &parsedType, &rowCount, &colCount, getLangOpts())) {
  10031. HLSLExternalSource *hlslExternalSource = HLSLExternalSource::FromSema(this);
  10032. hlslExternalSource->WarnMinPrecision(parsedType, R.getNameLoc());
  10033. return hlslExternalSource->DiagnoseHLSLScalarType(parsedType, R.getNameLoc());
  10034. }
  10035. }
  10036. return true;
  10037. }
  10038. static QualType getUnderlyingType(QualType Type)
  10039. {
  10040. while (const TypedefType *TD = dyn_cast<TypedefType>(Type))
  10041. {
  10042. if (const TypedefNameDecl* pDecl = TD->getDecl())
  10043. Type = pDecl->getUnderlyingType();
  10044. else
  10045. break;
  10046. }
  10047. return Type;
  10048. }
  10049. /// <summary>Return HLSL AttributedType objects if they exist on type.</summary>
  10050. /// <param name="self">Sema with context.</param>
  10051. /// <param name="type">QualType to inspect.</param>
  10052. /// <param name="ppMatrixOrientation">Set pointer to column_major/row_major AttributedType if supplied.</param>
  10053. /// <param name="ppNorm">Set pointer to snorm/unorm AttributedType if supplied.</param>
  10054. void hlsl::GetHLSLAttributedTypes(
  10055. _In_ clang::Sema* self,
  10056. clang::QualType type,
  10057. _Inout_opt_ const clang::AttributedType** ppMatrixOrientation,
  10058. _Inout_opt_ const clang::AttributedType** ppNorm)
  10059. {
  10060. if (ppMatrixOrientation)
  10061. *ppMatrixOrientation = nullptr;
  10062. if (ppNorm)
  10063. *ppNorm = nullptr;
  10064. // Note: we clear output pointers once set so we can stop searching
  10065. QualType Desugared = getUnderlyingType(type);
  10066. const AttributedType *AT = dyn_cast<AttributedType>(Desugared);
  10067. while (AT && (ppMatrixOrientation || ppNorm)) {
  10068. AttributedType::Kind Kind = AT->getAttrKind();
  10069. if (Kind == AttributedType::attr_hlsl_row_major ||
  10070. Kind == AttributedType::attr_hlsl_column_major)
  10071. {
  10072. if (ppMatrixOrientation)
  10073. {
  10074. *ppMatrixOrientation = AT;
  10075. ppMatrixOrientation = nullptr;
  10076. }
  10077. }
  10078. else if (Kind == AttributedType::attr_hlsl_unorm ||
  10079. Kind == AttributedType::attr_hlsl_snorm)
  10080. {
  10081. if (ppNorm)
  10082. {
  10083. *ppNorm = AT;
  10084. ppNorm = nullptr;
  10085. }
  10086. }
  10087. Desugared = getUnderlyingType(AT->getEquivalentType());
  10088. AT = dyn_cast<AttributedType>(Desugared);
  10089. }
  10090. // Unwrap component type on vector or matrix and check snorm/unorm
  10091. Desugared = getUnderlyingType(hlsl::GetOriginalElementType(self, Desugared));
  10092. AT = dyn_cast<AttributedType>(Desugared);
  10093. while (AT && ppNorm) {
  10094. AttributedType::Kind Kind = AT->getAttrKind();
  10095. if (Kind == AttributedType::attr_hlsl_unorm ||
  10096. Kind == AttributedType::attr_hlsl_snorm)
  10097. {
  10098. *ppNorm = AT;
  10099. ppNorm = nullptr;
  10100. }
  10101. Desugared = getUnderlyingType(AT->getEquivalentType());
  10102. AT = dyn_cast<AttributedType>(Desugared);
  10103. }
  10104. }
  10105. /// <summary>Returns true if QualType is an HLSL Matrix type.</summary>
  10106. /// <param name="self">Sema with context.</param>
  10107. /// <param name="type">QualType to check.</param>
  10108. bool hlsl::IsMatrixType(
  10109. _In_ clang::Sema* self,
  10110. _In_ clang::QualType type)
  10111. {
  10112. return HLSLExternalSource::FromSema(self)->GetTypeObjectKind(type) == AR_TOBJ_MATRIX;
  10113. }
  10114. /// <summary>Returns true if QualType is an HLSL Vector type.</summary>
  10115. /// <param name="self">Sema with context.</param>
  10116. /// <param name="type">QualType to check.</param>
  10117. bool hlsl::IsVectorType(
  10118. _In_ clang::Sema* self,
  10119. _In_ clang::QualType type)
  10120. {
  10121. return HLSLExternalSource::FromSema(self)->GetTypeObjectKind(type) == AR_TOBJ_VECTOR;
  10122. }
  10123. /// <summary>Get element type for an HLSL Matrix or Vector, preserving AttributedType.</summary>
  10124. /// <param name="self">Sema with context.</param>
  10125. /// <param name="type">Matrix or Vector type.</param>
  10126. clang::QualType hlsl::GetOriginalMatrixOrVectorElementType(
  10127. _In_ clang::QualType type)
  10128. {
  10129. // TODO: Determine if this is really the best way to get the matrix/vector specialization
  10130. // without losing the AttributedType on the template parameter
  10131. if (const Type* pType = type.getTypePtrOrNull()) {
  10132. // A non-dependent template specialization type is always "sugar",
  10133. // typically for a RecordType. For example, a class template
  10134. // specialization type of @c vector<int> will refer to a tag type for
  10135. // the instantiation @c std::vector<int, std::allocator<int>>.
  10136. if (const TemplateSpecializationType* pTemplate = pType->getAs<TemplateSpecializationType>()) {
  10137. // If we have enough arguments, pull them from the template directly, rather than doing
  10138. // the extra lookups.
  10139. if (pTemplate->getNumArgs() > 0)
  10140. return pTemplate->getArg(0).getAsType();
  10141. QualType templateRecord = pTemplate->desugar();
  10142. const Type *pTemplateRecordType = templateRecord.getTypePtr();
  10143. if (pTemplateRecordType) {
  10144. const TagType *pTemplateTagType = pTemplateRecordType->getAs<TagType>();
  10145. if (pTemplateTagType) {
  10146. const ClassTemplateSpecializationDecl *specializationDecl =
  10147. dyn_cast_or_null<ClassTemplateSpecializationDecl>(
  10148. pTemplateTagType->getDecl());
  10149. if (specializationDecl) {
  10150. return specializationDecl->getTemplateArgs()[0].getAsType();
  10151. }
  10152. }
  10153. }
  10154. }
  10155. }
  10156. return QualType();
  10157. }
  10158. /// <summary>Get element type, preserving AttributedType, if vector or matrix, otherwise return the type unmodified.</summary>
  10159. /// <param name="self">Sema with context.</param>
  10160. /// <param name="type">Input type.</param>
  10161. clang::QualType hlsl::GetOriginalElementType(
  10162. _In_ clang::Sema* self,
  10163. _In_ clang::QualType type)
  10164. {
  10165. ArTypeObjectKind Kind = HLSLExternalSource::FromSema(self)->GetTypeObjectKind(type);
  10166. if (Kind == AR_TOBJ_MATRIX || Kind == AR_TOBJ_VECTOR) {
  10167. return GetOriginalMatrixOrVectorElementType(type);
  10168. }
  10169. return type;
  10170. }
  10171. void hlsl::CustomPrintHLSLAttr(const clang::Attr *A, llvm::raw_ostream &Out, const clang::PrintingPolicy &Policy, unsigned int Indentation) {
  10172. switch (A->getKind()) {
  10173. // Parameter modifiers
  10174. case clang::attr::HLSLIn:
  10175. Out << "in ";
  10176. break;
  10177. case clang::attr::HLSLInOut:
  10178. Out << "inout ";
  10179. break;
  10180. case clang::attr::HLSLOut:
  10181. Out << "out ";
  10182. break;
  10183. // Interpolation modifiers
  10184. case clang::attr::HLSLLinear:
  10185. Out << "linear ";
  10186. break;
  10187. case clang::attr::HLSLCentroid:
  10188. Out << "centroid ";
  10189. break;
  10190. case clang::attr::HLSLNoInterpolation:
  10191. Out << "nointerpolation ";
  10192. break;
  10193. case clang::attr::HLSLNoPerspective:
  10194. Out << "noperspective ";
  10195. break;
  10196. case clang::attr::HLSLSample:
  10197. Out << "sample ";
  10198. break;
  10199. // Function attributes
  10200. case clang::attr::HLSLClipPlanes:
  10201. {
  10202. Attr * noconst = const_cast<Attr*>(A);
  10203. HLSLClipPlanesAttr *ACast = static_cast<HLSLClipPlanesAttr*>(noconst);
  10204. if (!ACast->getClipPlane1())
  10205. break;
  10206. Indent(Indentation, Out);
  10207. Out << "[clipplanes(";
  10208. ACast->getClipPlane1()->printPretty(Out, 0, Policy);
  10209. PrintClipPlaneIfPresent(ACast->getClipPlane2(), Out, Policy);
  10210. PrintClipPlaneIfPresent(ACast->getClipPlane3(), Out, Policy);
  10211. PrintClipPlaneIfPresent(ACast->getClipPlane4(), Out, Policy);
  10212. PrintClipPlaneIfPresent(ACast->getClipPlane5(), Out, Policy);
  10213. PrintClipPlaneIfPresent(ACast->getClipPlane6(), Out, Policy);
  10214. Out << ")]\n";
  10215. break;
  10216. }
  10217. case clang::attr::HLSLDomain:
  10218. {
  10219. Attr * noconst = const_cast<Attr*>(A);
  10220. HLSLDomainAttr *ACast = static_cast<HLSLDomainAttr*>(noconst);
  10221. Indent(Indentation, Out);
  10222. Out << "[domain(\"" << ACast->getDomainType() << "\")]\n";
  10223. break;
  10224. }
  10225. case clang::attr::HLSLEarlyDepthStencil:
  10226. Indent(Indentation, Out);
  10227. Out << "[earlydepthstencil]\n";
  10228. break;
  10229. case clang::attr::HLSLInstance: //TODO - test
  10230. {
  10231. Attr * noconst = const_cast<Attr*>(A);
  10232. HLSLInstanceAttr *ACast = static_cast<HLSLInstanceAttr*>(noconst);
  10233. Indent(Indentation, Out);
  10234. Out << "[instance(" << ACast->getCount() << ")]\n";
  10235. break;
  10236. }
  10237. case clang::attr::HLSLMaxTessFactor: //TODO - test
  10238. {
  10239. Attr * noconst = const_cast<Attr*>(A);
  10240. HLSLMaxTessFactorAttr *ACast = static_cast<HLSLMaxTessFactorAttr*>(noconst);
  10241. Indent(Indentation, Out);
  10242. Out << "[maxtessfactor(" << ACast->getFactor() << ")]\n";
  10243. break;
  10244. }
  10245. case clang::attr::HLSLNumThreads: //TODO - test
  10246. {
  10247. Attr * noconst = const_cast<Attr*>(A);
  10248. HLSLNumThreadsAttr *ACast = static_cast<HLSLNumThreadsAttr*>(noconst);
  10249. Indent(Indentation, Out);
  10250. Out << "[numthreads(" << ACast->getX() << ", " << ACast->getY() << ", " << ACast->getZ() << ")]\n";
  10251. break;
  10252. }
  10253. case clang::attr::HLSLRootSignature:
  10254. {
  10255. Attr * noconst = const_cast<Attr*>(A);
  10256. HLSLRootSignatureAttr *ACast = static_cast<HLSLRootSignatureAttr*>(noconst);
  10257. Indent(Indentation, Out);
  10258. Out << "[RootSignature(" << ACast->getSignatureName() << ")]\n";
  10259. break;
  10260. }
  10261. case clang::attr::HLSLOutputControlPoints:
  10262. {
  10263. Attr * noconst = const_cast<Attr*>(A);
  10264. HLSLOutputControlPointsAttr *ACast = static_cast<HLSLOutputControlPointsAttr*>(noconst);
  10265. Indent(Indentation, Out);
  10266. Out << "[outputcontrolpoints(" << ACast->getCount() << ")]\n";
  10267. break;
  10268. }
  10269. case clang::attr::HLSLOutputTopology:
  10270. {
  10271. Attr * noconst = const_cast<Attr*>(A);
  10272. HLSLOutputTopologyAttr *ACast = static_cast<HLSLOutputTopologyAttr*>(noconst);
  10273. Indent(Indentation, Out);
  10274. Out << "[outputtopology(\"" << ACast->getTopology() << "\")]\n";
  10275. break;
  10276. }
  10277. case clang::attr::HLSLPartitioning:
  10278. {
  10279. Attr * noconst = const_cast<Attr*>(A);
  10280. HLSLPartitioningAttr *ACast = static_cast<HLSLPartitioningAttr*>(noconst);
  10281. Indent(Indentation, Out);
  10282. Out << "[partitioning(\"" << ACast->getScheme() << "\")]\n";
  10283. break;
  10284. }
  10285. case clang::attr::HLSLPatchConstantFunc:
  10286. {
  10287. Attr * noconst = const_cast<Attr*>(A);
  10288. HLSLPatchConstantFuncAttr *ACast = static_cast<HLSLPatchConstantFuncAttr*>(noconst);
  10289. Indent(Indentation, Out);
  10290. Out << "[patchconstantfunc(\"" << ACast->getFunctionName() << "\")]\n";
  10291. break;
  10292. }
  10293. case clang::attr::HLSLShader:
  10294. {
  10295. Attr * noconst = const_cast<Attr*>(A);
  10296. HLSLShaderAttr *ACast = static_cast<HLSLShaderAttr*>(noconst);
  10297. Indent(Indentation, Out);
  10298. Out << "[shader(\"" << ACast->getStage() << "\")]\n";
  10299. break;
  10300. }
  10301. case clang::attr::HLSLExperimental:
  10302. {
  10303. Attr * noconst = const_cast<Attr*>(A);
  10304. HLSLExperimentalAttr *ACast = static_cast<HLSLExperimentalAttr*>(noconst);
  10305. Indent(Indentation, Out);
  10306. Out << "[experimental(\"" << ACast->getName() << "\", \"" << ACast->getValue() << "\")]\n";
  10307. break;
  10308. }
  10309. case clang::attr::HLSLMaxVertexCount:
  10310. {
  10311. Attr * noconst = const_cast<Attr*>(A);
  10312. HLSLMaxVertexCountAttr *ACast = static_cast<HLSLMaxVertexCountAttr*>(noconst);
  10313. Indent(Indentation, Out);
  10314. Out << "[maxvertexcount(" << ACast->getCount() << ")]\n";
  10315. break;
  10316. }
  10317. case clang::attr::NoInline:
  10318. Indent(Indentation, Out);
  10319. Out << "[noinline]\n";
  10320. break;
  10321. // Statement attributes
  10322. case clang::attr::HLSLAllowUAVCondition:
  10323. Indent(Indentation, Out);
  10324. Out << "[allow_uav_condition]\n";
  10325. break;
  10326. case clang::attr::HLSLBranch:
  10327. Indent(Indentation, Out);
  10328. Out << "[branch]\n";
  10329. break;
  10330. case clang::attr::HLSLCall:
  10331. Indent(Indentation, Out);
  10332. Out << "[call]\n";
  10333. break;
  10334. case clang::attr::HLSLFastOpt:
  10335. Indent(Indentation, Out);
  10336. Out << "[fastopt]\n";
  10337. break;
  10338. case clang::attr::HLSLFlatten:
  10339. Indent(Indentation, Out);
  10340. Out << "[flatten]\n";
  10341. break;
  10342. case clang::attr::HLSLForceCase:
  10343. Indent(Indentation, Out);
  10344. Out << "[forcecase]\n";
  10345. break;
  10346. case clang::attr::HLSLLoop:
  10347. Indent(Indentation, Out);
  10348. Out << "[loop]\n";
  10349. break;
  10350. case clang::attr::HLSLUnroll:
  10351. {
  10352. Attr * noconst = const_cast<Attr*>(A);
  10353. HLSLUnrollAttr *ACast = static_cast<HLSLUnrollAttr*>(noconst);
  10354. Indent(Indentation, Out);
  10355. Out << "[unroll(" << ACast->getCount() << ")]\n";
  10356. break;
  10357. }
  10358. // Variable modifiers
  10359. case clang::attr::HLSLGroupShared:
  10360. Out << "groupshared ";
  10361. break;
  10362. case clang::attr::HLSLPrecise:
  10363. Out << "precise ";
  10364. break;
  10365. case clang::attr::HLSLSemantic: // TODO: Consider removing HLSLSemantic attribute
  10366. break;
  10367. case clang::attr::HLSLShared:
  10368. Out << "shared ";
  10369. break;
  10370. case clang::attr::HLSLUniform:
  10371. Out << "uniform ";
  10372. break;
  10373. // These four cases are printed in TypePrinter::printAttributedBefore
  10374. case clang::attr::HLSLColumnMajor:
  10375. case clang::attr::HLSLRowMajor:
  10376. case clang::attr::HLSLSnorm:
  10377. case clang::attr::HLSLUnorm:
  10378. break;
  10379. case clang::attr::HLSLPoint:
  10380. Out << "point ";
  10381. break;
  10382. case clang::attr::HLSLLine:
  10383. Out << "line ";
  10384. break;
  10385. case clang::attr::HLSLLineAdj:
  10386. Out << "lineadj ";
  10387. break;
  10388. case clang::attr::HLSLTriangle:
  10389. Out << "triangle ";
  10390. break;
  10391. case clang::attr::HLSLTriangleAdj:
  10392. Out << "triangleadj ";
  10393. break;
  10394. case clang::attr::HLSLGloballyCoherent:
  10395. Out << "globallycoherent ";
  10396. break;
  10397. default:
  10398. A->printPretty(Out, Policy);
  10399. break;
  10400. }
  10401. }
  10402. bool hlsl::IsHLSLAttr(clang::attr::Kind AttrKind) {
  10403. switch (AttrKind){
  10404. case clang::attr::HLSLAllowUAVCondition:
  10405. case clang::attr::HLSLBranch:
  10406. case clang::attr::HLSLCall:
  10407. case clang::attr::HLSLCentroid:
  10408. case clang::attr::HLSLClipPlanes:
  10409. case clang::attr::HLSLColumnMajor:
  10410. case clang::attr::HLSLDomain:
  10411. case clang::attr::HLSLEarlyDepthStencil:
  10412. case clang::attr::HLSLFastOpt:
  10413. case clang::attr::HLSLFlatten:
  10414. case clang::attr::HLSLForceCase:
  10415. case clang::attr::HLSLGroupShared:
  10416. case clang::attr::HLSLIn:
  10417. case clang::attr::HLSLInOut:
  10418. case clang::attr::HLSLInstance:
  10419. case clang::attr::HLSLLinear:
  10420. case clang::attr::HLSLLoop:
  10421. case clang::attr::HLSLMaxTessFactor:
  10422. case clang::attr::HLSLNoInterpolation:
  10423. case clang::attr::HLSLNoPerspective:
  10424. case clang::attr::HLSLNumThreads:
  10425. case clang::attr::HLSLRootSignature:
  10426. case clang::attr::HLSLOut:
  10427. case clang::attr::HLSLOutputControlPoints:
  10428. case clang::attr::HLSLOutputTopology:
  10429. case clang::attr::HLSLPartitioning:
  10430. case clang::attr::HLSLPatchConstantFunc:
  10431. case clang::attr::HLSLMaxVertexCount:
  10432. case clang::attr::HLSLPrecise:
  10433. case clang::attr::HLSLRowMajor:
  10434. case clang::attr::HLSLSample:
  10435. case clang::attr::HLSLSemantic:
  10436. case clang::attr::HLSLShared:
  10437. case clang::attr::HLSLSnorm:
  10438. case clang::attr::HLSLUniform:
  10439. case clang::attr::HLSLUnorm:
  10440. case clang::attr::HLSLUnroll:
  10441. case clang::attr::HLSLPoint:
  10442. case clang::attr::HLSLLine:
  10443. case clang::attr::HLSLLineAdj:
  10444. case clang::attr::HLSLTriangle:
  10445. case clang::attr::HLSLTriangleAdj:
  10446. case clang::attr::HLSLGloballyCoherent:
  10447. case clang::attr::NoInline:
  10448. case clang::attr::VKBinding:
  10449. case clang::attr::VKBuiltIn:
  10450. case clang::attr::VKConstantId:
  10451. case clang::attr::VKCounterBinding:
  10452. case clang::attr::VKIndex:
  10453. case clang::attr::VKInputAttachmentIndex:
  10454. case clang::attr::VKLocation:
  10455. case clang::attr::VKOffset:
  10456. case clang::attr::VKPushConstant:
  10457. return true;
  10458. default:
  10459. // Only HLSL/VK Attributes return true. Only used for printPretty(), which doesn't support them.
  10460. break;
  10461. }
  10462. return false;
  10463. }
  10464. void hlsl::PrintClipPlaneIfPresent(clang::Expr *ClipPlane, llvm::raw_ostream &Out, const clang::PrintingPolicy &Policy) {
  10465. if (ClipPlane) {
  10466. Out << ", ";
  10467. ClipPlane->printPretty(Out, 0, Policy);
  10468. }
  10469. }
  10470. bool hlsl::IsObjectType(
  10471. _In_ clang::Sema* self,
  10472. _In_ clang::QualType type,
  10473. _Inout_opt_ bool *isDeprecatedEffectObject)
  10474. {
  10475. HLSLExternalSource *pExternalSource = HLSLExternalSource::FromSema(self);
  10476. if (pExternalSource && pExternalSource->GetTypeObjectKind(type) == AR_TOBJ_OBJECT) {
  10477. if (isDeprecatedEffectObject)
  10478. *isDeprecatedEffectObject = pExternalSource->GetTypeElementKind(type) == AR_OBJECT_LEGACY_EFFECT;
  10479. return true;
  10480. }
  10481. if (isDeprecatedEffectObject)
  10482. *isDeprecatedEffectObject = false;
  10483. return false;
  10484. }
  10485. bool hlsl::CanConvert(
  10486. _In_ clang::Sema* self,
  10487. clang::SourceLocation loc,
  10488. _In_ clang::Expr* sourceExpr,
  10489. clang::QualType target,
  10490. bool explicitConversion,
  10491. _Inout_opt_ clang::StandardConversionSequence* standard)
  10492. {
  10493. return HLSLExternalSource::FromSema(self)->CanConvert(loc, sourceExpr, target, explicitConversion, nullptr, standard);
  10494. }
  10495. void hlsl::Indent(unsigned int Indentation, llvm::raw_ostream &Out)
  10496. {
  10497. for (unsigned i = 0; i != Indentation; ++i)
  10498. Out << " ";
  10499. }
  10500. void hlsl::RegisterIntrinsicTable(_In_ clang::ExternalSemaSource* self, _In_ IDxcIntrinsicTable* table)
  10501. {
  10502. DXASSERT_NOMSG(self != nullptr);
  10503. DXASSERT_NOMSG(table != nullptr);
  10504. HLSLExternalSource* source = (HLSLExternalSource*)self;
  10505. source->RegisterIntrinsicTable(table);
  10506. }
  10507. clang::QualType hlsl::CheckVectorConditional(
  10508. _In_ clang::Sema* self,
  10509. _In_ clang::ExprResult &Cond,
  10510. _In_ clang::ExprResult &LHS,
  10511. _In_ clang::ExprResult &RHS,
  10512. _In_ clang::SourceLocation QuestionLoc)
  10513. {
  10514. return HLSLExternalSource::FromSema(self)->CheckVectorConditional(Cond, LHS, RHS, QuestionLoc);
  10515. }
  10516. bool IsTypeNumeric(_In_ clang::Sema* self, _In_ clang::QualType &type) {
  10517. UINT count;
  10518. return HLSLExternalSource::FromSema(self)->IsTypeNumeric(type, &count);
  10519. }
  10520. void Sema::CheckHLSLArrayAccess(const Expr *expr) {
  10521. DXASSERT_NOMSG(isa<CXXOperatorCallExpr>(expr));
  10522. const CXXOperatorCallExpr *OperatorCallExpr = cast<CXXOperatorCallExpr>(expr);
  10523. DXASSERT_NOMSG(OperatorCallExpr->getOperator() == OverloadedOperatorKind::OO_Subscript);
  10524. const Expr *RHS = OperatorCallExpr->getArg(1); // first subscript expression
  10525. llvm::APSInt index;
  10526. if (RHS->EvaluateAsInt(index, Context)) {
  10527. int64_t intIndex = index.getLimitedValue();
  10528. const QualType LHSQualType = OperatorCallExpr->getArg(0)->getType();
  10529. if (IsVectorType(this, LHSQualType)) {
  10530. uint32_t vectorSize = GetHLSLVecSize(LHSQualType);
  10531. // If expression is a double two subscript operator for matrix (e.g x[0][1])
  10532. // we also have to check the first subscript oprator by recursively calling
  10533. // this funciton for the first CXXOperatorCallExpr
  10534. if (isa<CXXOperatorCallExpr>(OperatorCallExpr->getArg(0))) {
  10535. CheckHLSLArrayAccess(cast<CXXOperatorCallExpr>(OperatorCallExpr->getArg(0)));
  10536. }
  10537. if (intIndex < 0 || (uint32_t)intIndex >= vectorSize) {
  10538. Diag(RHS->getExprLoc(),
  10539. diag::err_hlsl_vector_element_index_out_of_bounds)
  10540. << (int)intIndex;
  10541. }
  10542. }
  10543. else if (IsMatrixType(this, LHSQualType)) {
  10544. uint32_t rowCount, colCount;
  10545. GetHLSLMatRowColCount(LHSQualType, rowCount, colCount);
  10546. if (intIndex < 0 || (uint32_t)intIndex >= rowCount) {
  10547. Diag(RHS->getExprLoc(), diag::err_hlsl_matrix_row_index_out_of_bounds)
  10548. << (int)intIndex;
  10549. }
  10550. }
  10551. }
  10552. }
  10553. clang::QualType ApplyTypeSpecSignToParsedType(
  10554. _In_ clang::Sema* self,
  10555. _In_ clang::QualType &type,
  10556. _In_ clang::TypeSpecifierSign TSS,
  10557. _In_ clang::SourceLocation Loc
  10558. )
  10559. {
  10560. return HLSLExternalSource::FromSema(self)->ApplyTypeSpecSignToParsedType(type, TSS, Loc);
  10561. }