SemaHLSL.cpp 392 KB

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