SemaHLSL.cpp 417 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116
  1. //===--- SemaHLSL.cpp - HLSL support for AST nodes and operations ---===//
  2. ///////////////////////////////////////////////////////////////////////////////
  3. // //
  4. // SemaHLSL.cpp //
  5. // Copyright (C) Microsoft Corporation. All rights reserved. //
  6. // This file is distributed under the University of Illinois Open Source //
  7. // License. See LICENSE.TXT for details. //
  8. // //
  9. // This file implements the semantic support for HLSL. //
  10. // //
  11. ///////////////////////////////////////////////////////////////////////////////
  12. #include "llvm/ADT/SmallPtrSet.h"
  13. #include "llvm/ADT/DenseMap.h"
  14. #include "clang/AST/ASTContext.h"
  15. #include "clang/AST/Attr.h"
  16. #include "clang/AST/DeclCXX.h"
  17. #include "clang/AST/DeclTemplate.h"
  18. #include "clang/AST/Expr.h"
  19. #include "clang/AST/ExprCXX.h"
  20. #include "clang/AST/ExternalASTSource.h"
  21. #include "clang/AST/RecursiveASTVisitor.h"
  22. #include "clang/AST/TypeLoc.h"
  23. #include "clang/AST/HlslTypes.h"
  24. #include "clang/Sema/Overload.h"
  25. #include "clang/Sema/SemaDiagnostic.h"
  26. #include "clang/Sema/Initialization.h"
  27. #include "clang/Sema/ExternalSemaSource.h"
  28. #include "clang/Sema/Lookup.h"
  29. #include "clang/Sema/Template.h"
  30. #include "clang/Sema/TemplateDeduction.h"
  31. #include "clang/Sema/SemaHLSL.h"
  32. #include "dxc/Support/Global.h"
  33. #include "dxc/Support/WinIncludes.h"
  34. #include "dxc/Support/WinAdapter.h"
  35. #include "dxc/dxcapi.internal.h"
  36. #include "dxc/HlslIntrinsicOp.h"
  37. #include "gen_intrin_main_tables_15.h"
  38. #include "dxc/HLSL/HLOperations.h"
  39. #include "dxc/HLSL/DxilShaderModel.h"
  40. #include <array>
  41. #include <float.h>
  42. enum ArBasicKind {
  43. AR_BASIC_BOOL,
  44. AR_BASIC_LITERAL_FLOAT,
  45. AR_BASIC_FLOAT16,
  46. AR_BASIC_FLOAT32_PARTIAL_PRECISION,
  47. AR_BASIC_FLOAT32,
  48. AR_BASIC_FLOAT64,
  49. AR_BASIC_LITERAL_INT,
  50. AR_BASIC_INT8,
  51. AR_BASIC_UINT8,
  52. AR_BASIC_INT16,
  53. AR_BASIC_UINT16,
  54. AR_BASIC_INT32,
  55. AR_BASIC_UINT32,
  56. AR_BASIC_INT64,
  57. AR_BASIC_UINT64,
  58. AR_BASIC_MIN10FLOAT,
  59. AR_BASIC_MIN16FLOAT,
  60. AR_BASIC_MIN12INT,
  61. AR_BASIC_MIN16INT,
  62. AR_BASIC_MIN16UINT,
  63. AR_BASIC_ENUM,
  64. AR_BASIC_COUNT,
  65. //
  66. // Pseudo-entries for intrinsic tables and such.
  67. //
  68. AR_BASIC_NONE,
  69. AR_BASIC_UNKNOWN,
  70. AR_BASIC_NOCAST,
  71. //
  72. // The following pseudo-entries represent higher-level
  73. // object types that are treated as units.
  74. //
  75. AR_BASIC_POINTER,
  76. AR_BASIC_ENUM_CLASS,
  77. AR_OBJECT_NULL,
  78. AR_OBJECT_STRING,
  79. // AR_OBJECT_TEXTURE,
  80. AR_OBJECT_TEXTURE1D,
  81. AR_OBJECT_TEXTURE1D_ARRAY,
  82. AR_OBJECT_TEXTURE2D,
  83. AR_OBJECT_TEXTURE2D_ARRAY,
  84. AR_OBJECT_TEXTURE3D,
  85. AR_OBJECT_TEXTURECUBE,
  86. AR_OBJECT_TEXTURECUBE_ARRAY,
  87. AR_OBJECT_TEXTURE2DMS,
  88. AR_OBJECT_TEXTURE2DMS_ARRAY,
  89. AR_OBJECT_SAMPLER,
  90. AR_OBJECT_SAMPLER1D,
  91. AR_OBJECT_SAMPLER2D,
  92. AR_OBJECT_SAMPLER3D,
  93. AR_OBJECT_SAMPLERCUBE,
  94. AR_OBJECT_SAMPLERCOMPARISON,
  95. AR_OBJECT_BUFFER,
  96. //
  97. // View objects are only used as variable/types within the Effects
  98. // framework, for example in calls to OMSetRenderTargets.
  99. //
  100. AR_OBJECT_RENDERTARGETVIEW,
  101. AR_OBJECT_DEPTHSTENCILVIEW,
  102. //
  103. // Shader objects are only used as variable/types within the Effects
  104. // framework, for example as a result of CompileShader().
  105. //
  106. AR_OBJECT_COMPUTESHADER,
  107. AR_OBJECT_DOMAINSHADER,
  108. AR_OBJECT_GEOMETRYSHADER,
  109. AR_OBJECT_HULLSHADER,
  110. AR_OBJECT_PIXELSHADER,
  111. AR_OBJECT_VERTEXSHADER,
  112. AR_OBJECT_PIXELFRAGMENT,
  113. AR_OBJECT_VERTEXFRAGMENT,
  114. AR_OBJECT_STATEBLOCK,
  115. AR_OBJECT_RASTERIZER,
  116. AR_OBJECT_DEPTHSTENCIL,
  117. AR_OBJECT_BLEND,
  118. AR_OBJECT_POINTSTREAM,
  119. AR_OBJECT_LINESTREAM,
  120. AR_OBJECT_TRIANGLESTREAM,
  121. AR_OBJECT_INPUTPATCH,
  122. AR_OBJECT_OUTPUTPATCH,
  123. AR_OBJECT_RWTEXTURE1D,
  124. AR_OBJECT_RWTEXTURE1D_ARRAY,
  125. AR_OBJECT_RWTEXTURE2D,
  126. AR_OBJECT_RWTEXTURE2D_ARRAY,
  127. AR_OBJECT_RWTEXTURE3D,
  128. AR_OBJECT_RWBUFFER,
  129. AR_OBJECT_BYTEADDRESS_BUFFER,
  130. AR_OBJECT_RWBYTEADDRESS_BUFFER,
  131. AR_OBJECT_STRUCTURED_BUFFER,
  132. AR_OBJECT_RWSTRUCTURED_BUFFER,
  133. AR_OBJECT_RWSTRUCTURED_BUFFER_ALLOC,
  134. AR_OBJECT_RWSTRUCTURED_BUFFER_CONSUME,
  135. AR_OBJECT_APPEND_STRUCTURED_BUFFER,
  136. AR_OBJECT_CONSUME_STRUCTURED_BUFFER,
  137. AR_OBJECT_CONSTANT_BUFFER,
  138. AR_OBJECT_TEXTURE_BUFFER,
  139. AR_OBJECT_ROVBUFFER,
  140. AR_OBJECT_ROVBYTEADDRESS_BUFFER,
  141. AR_OBJECT_ROVSTRUCTURED_BUFFER,
  142. AR_OBJECT_ROVTEXTURE1D,
  143. AR_OBJECT_ROVTEXTURE1D_ARRAY,
  144. AR_OBJECT_ROVTEXTURE2D,
  145. AR_OBJECT_ROVTEXTURE2D_ARRAY,
  146. AR_OBJECT_ROVTEXTURE3D,
  147. // SPIRV change starts
  148. #ifdef ENABLE_SPIRV_CODEGEN
  149. AR_OBJECT_VK_SUBPASS_INPUT,
  150. AR_OBJECT_VK_SUBPASS_INPUT_MS,
  151. #endif // ENABLE_SPIRV_CODEGEN
  152. // SPIRV change ends
  153. AR_OBJECT_INNER, // Used for internal type object
  154. AR_OBJECT_LEGACY_EFFECT,
  155. AR_OBJECT_WAVE,
  156. AR_OBJECT_RAY_DESC,
  157. AR_OBJECT_ACCELARATION_STRUCT,
  158. AR_OBJECT_USER_DEFINED_TYPE,
  159. AR_OBJECT_TRIANGLE_INTERSECTION_ATTRIBUTES,
  160. AR_BASIC_MAXIMUM_COUNT
  161. };
  162. #define AR_BASIC_TEXTURE_MS_CASES \
  163. case AR_OBJECT_TEXTURE2DMS: \
  164. case AR_OBJECT_TEXTURE2DMS_ARRAY
  165. #define AR_BASIC_NON_TEXTURE_MS_CASES \
  166. case AR_OBJECT_TEXTURE1D: \
  167. case AR_OBJECT_TEXTURE1D_ARRAY: \
  168. case AR_OBJECT_TEXTURE2D: \
  169. case AR_OBJECT_TEXTURE2D_ARRAY: \
  170. case AR_OBJECT_TEXTURE3D: \
  171. case AR_OBJECT_TEXTURECUBE: \
  172. case AR_OBJECT_TEXTURECUBE_ARRAY
  173. #define AR_BASIC_TEXTURE_CASES \
  174. AR_BASIC_TEXTURE_MS_CASES: \
  175. AR_BASIC_NON_TEXTURE_MS_CASES
  176. #define AR_BASIC_NON_CMP_SAMPLER_CASES \
  177. case AR_OBJECT_SAMPLER: \
  178. case AR_OBJECT_SAMPLER1D: \
  179. case AR_OBJECT_SAMPLER2D: \
  180. case AR_OBJECT_SAMPLER3D: \
  181. case AR_OBJECT_SAMPLERCUBE
  182. #define AR_BASIC_ROBJECT_CASES \
  183. case AR_OBJECT_BLEND: \
  184. case AR_OBJECT_RASTERIZER: \
  185. case AR_OBJECT_DEPTHSTENCIL: \
  186. case AR_OBJECT_STATEBLOCK
  187. //
  188. // Properties of entries in the ArBasicKind enumeration.
  189. // These properties are intended to allow easy identification
  190. // of classes of basic kinds. More specific checks on the
  191. // actual kind values could then be done.
  192. //
  193. // The first four bits are used as a subtype indicator,
  194. // such as bit count for primitive kinds or specific
  195. // types for non-primitive-data kinds.
  196. #define BPROP_SUBTYPE_MASK 0x0000000f
  197. // Bit counts must be ordered from smaller to larger.
  198. #define BPROP_BITS0 0x00000000
  199. #define BPROP_BITS8 0x00000001
  200. #define BPROP_BITS10 0x00000002
  201. #define BPROP_BITS12 0x00000003
  202. #define BPROP_BITS16 0x00000004
  203. #define BPROP_BITS32 0x00000005
  204. #define BPROP_BITS64 0x00000006
  205. #define BPROP_BITS_NON_PRIM 0x00000007
  206. #define GET_BPROP_SUBTYPE(_Props) ((_Props) & BPROP_SUBTYPE_MASK)
  207. #define GET_BPROP_BITS(_Props) ((_Props) & BPROP_SUBTYPE_MASK)
  208. #define BPROP_BOOLEAN 0x00000010 // Whether the type is bool
  209. #define BPROP_INTEGER 0x00000020 // Whether the type is an integer
  210. #define BPROP_UNSIGNED 0x00000040 // Whether the type is an unsigned numeric (its absence implies signed)
  211. #define BPROP_NUMERIC 0x00000080 // Whether the type is numeric or boolean
  212. #define BPROP_LITERAL 0x00000100 // Whether the type is a literal float or integer
  213. #define BPROP_FLOATING 0x00000200 // Whether the type is a float
  214. #define BPROP_OBJECT 0x00000400 // Whether the type is an object (including null or stream)
  215. #define BPROP_OTHER 0x00000800 // Whether the type is a pseudo-entry in another table.
  216. #define BPROP_PARTIAL_PRECISION 0x00001000 // Whether the type has partial precision for calculations (i.e., is this 'half')
  217. #define BPROP_POINTER 0x00002000 // Whether the type is a basic pointer.
  218. #define BPROP_TEXTURE 0x00004000 // Whether the type is any kind of texture.
  219. #define BPROP_SAMPLER 0x00008000 // Whether the type is any kind of sampler object.
  220. #define BPROP_STREAM 0x00010000 // Whether the type is a point, line or triangle stream.
  221. #define BPROP_PATCH 0x00020000 // Whether the type is an input or output patch.
  222. #define BPROP_RBUFFER 0x00040000 // Whether the type acts as a read-only buffer.
  223. #define BPROP_RWBUFFER 0x00080000 // Whether the type acts as a read-write buffer.
  224. #define BPROP_PRIMITIVE 0x00100000 // Whether the type is a primitive scalar type.
  225. #define BPROP_MIN_PRECISION 0x00200000 // Whether the type is qualified with a minimum precision.
  226. #define BPROP_ROVBUFFER 0x00400000 // Whether the type is a ROV object.
  227. #define BPROP_ENUM 0x00800000 // Whether the type is a enum
  228. #define GET_BPROP_PRIM_KIND(_Props) \
  229. ((_Props) & (BPROP_BOOLEAN | BPROP_INTEGER | BPROP_FLOATING))
  230. #define GET_BPROP_PRIM_KIND_SU(_Props) \
  231. ((_Props) & (BPROP_BOOLEAN | BPROP_INTEGER | BPROP_FLOATING | BPROP_UNSIGNED))
  232. #define IS_BPROP_PRIMITIVE(_Props) \
  233. (((_Props) & BPROP_PRIMITIVE) != 0)
  234. #define IS_BPROP_BOOL(_Props) \
  235. (((_Props) & BPROP_BOOLEAN) != 0)
  236. #define IS_BPROP_FLOAT(_Props) \
  237. (((_Props) & BPROP_FLOATING) != 0)
  238. #define IS_BPROP_SINT(_Props) \
  239. (((_Props) & (BPROP_INTEGER | BPROP_UNSIGNED | BPROP_BOOLEAN)) == \
  240. BPROP_INTEGER)
  241. #define IS_BPROP_UINT(_Props) \
  242. (((_Props) & (BPROP_INTEGER | BPROP_UNSIGNED | BPROP_BOOLEAN)) == \
  243. (BPROP_INTEGER | BPROP_UNSIGNED))
  244. #define IS_BPROP_AINT(_Props) \
  245. (((_Props) & (BPROP_INTEGER | BPROP_BOOLEAN)) == BPROP_INTEGER)
  246. #define IS_BPROP_STREAM(_Props) \
  247. (((_Props) & BPROP_STREAM) != 0)
  248. #define IS_BPROP_SAMPLER(_Props) \
  249. (((_Props) & BPROP_SAMPLER) != 0)
  250. #define IS_BPROP_TEXTURE(_Props) \
  251. (((_Props) & BPROP_TEXTURE) != 0)
  252. #define IS_BPROP_OBJECT(_Props) \
  253. (((_Props) & BPROP_OBJECT) != 0)
  254. #define IS_BPROP_MIN_PRECISION(_Props) \
  255. (((_Props) & BPROP_MIN_PRECISION) != 0)
  256. #define IS_BPROP_UNSIGNABLE(_Props) \
  257. (IS_BPROP_AINT(_Props) && GET_BPROP_BITS(_Props) != BPROP_BITS12)
  258. #define IS_BPROP_ENUM(_Props) \
  259. (((_Props) & BPROP_ENUM) != 0)
  260. const UINT g_uBasicKindProps[] =
  261. {
  262. BPROP_PRIMITIVE | BPROP_BOOLEAN | BPROP_INTEGER | BPROP_NUMERIC | BPROP_BITS0, // AR_BASIC_BOOL
  263. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_FLOATING | BPROP_LITERAL | BPROP_BITS0, // AR_BASIC_LITERAL_FLOAT
  264. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_FLOATING | BPROP_BITS16, // AR_BASIC_FLOAT16
  265. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_FLOATING | BPROP_BITS32 | BPROP_PARTIAL_PRECISION, // AR_BASIC_FLOAT32_PARTIAL_PRECISION
  266. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_FLOATING | BPROP_BITS32, // AR_BASIC_FLOAT32
  267. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_FLOATING | BPROP_BITS64, // AR_BASIC_FLOAT64
  268. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_INTEGER | BPROP_LITERAL | BPROP_BITS0, // AR_BASIC_LITERAL_INT
  269. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_INTEGER | BPROP_BITS8, // AR_BASIC_INT8
  270. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_INTEGER | BPROP_UNSIGNED | BPROP_BITS8, // AR_BASIC_UINT8
  271. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_INTEGER | BPROP_BITS16, // AR_BASIC_INT16
  272. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_INTEGER | BPROP_UNSIGNED | BPROP_BITS16,// AR_BASIC_UINT16
  273. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_INTEGER | BPROP_BITS32, // AR_BASIC_INT32
  274. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_INTEGER | BPROP_UNSIGNED | BPROP_BITS32,// AR_BASIC_UINT32
  275. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_INTEGER | BPROP_BITS64, // AR_BASIC_INT64
  276. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_INTEGER | BPROP_UNSIGNED | BPROP_BITS64,// AR_BASIC_UINT64
  277. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_FLOATING | BPROP_BITS10 | BPROP_MIN_PRECISION, // AR_BASIC_MIN10FLOAT
  278. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_FLOATING | BPROP_BITS16 | BPROP_MIN_PRECISION, // AR_BASIC_MIN16FLOAT
  279. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_INTEGER | BPROP_BITS12 | BPROP_MIN_PRECISION, // AR_BASIC_MIN12INT
  280. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_INTEGER | BPROP_BITS16 | BPROP_MIN_PRECISION, // AR_BASIC_MIN16INT
  281. BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_INTEGER | BPROP_UNSIGNED | BPROP_BITS16 | BPROP_MIN_PRECISION, // AR_BASIC_MIN16UINT
  282. BPROP_ENUM | BPROP_NUMERIC | BPROP_INTEGER, // AR_BASIC_ENUM
  283. BPROP_OTHER, // AR_BASIC_COUNT
  284. //
  285. // Pseudo-entries for intrinsic tables and such.
  286. //
  287. 0, // AR_BASIC_NONE
  288. BPROP_OTHER, // AR_BASIC_UNKNOWN
  289. BPROP_OTHER, // AR_BASIC_NOCAST
  290. //
  291. // The following pseudo-entries represent higher-level
  292. // object types that are treated as units.
  293. //
  294. BPROP_POINTER, // AR_BASIC_POINTER
  295. BPROP_ENUM, // AR_BASIC_ENUM_CLASS
  296. BPROP_OBJECT | BPROP_RBUFFER, // AR_OBJECT_NULL
  297. BPROP_OBJECT | BPROP_RBUFFER, // AR_OBJECT_STRING
  298. // BPROP_OBJECT | BPROP_TEXTURE, // AR_OBJECT_TEXTURE
  299. BPROP_OBJECT | BPROP_TEXTURE, // AR_OBJECT_TEXTURE1D
  300. BPROP_OBJECT | BPROP_TEXTURE, // AR_OBJECT_TEXTURE1D_ARRAY
  301. BPROP_OBJECT | BPROP_TEXTURE, // AR_OBJECT_TEXTURE2D
  302. BPROP_OBJECT | BPROP_TEXTURE, // AR_OBJECT_TEXTURE2D_ARRAY
  303. BPROP_OBJECT | BPROP_TEXTURE, // AR_OBJECT_TEXTURE3D
  304. BPROP_OBJECT | BPROP_TEXTURE, // AR_OBJECT_TEXTURECUBE
  305. BPROP_OBJECT | BPROP_TEXTURE, // AR_OBJECT_TEXTURECUBE_ARRAY
  306. BPROP_OBJECT | BPROP_TEXTURE, // AR_OBJECT_TEXTURE2DMS
  307. BPROP_OBJECT | BPROP_TEXTURE, // AR_OBJECT_TEXTURE2DMS_ARRAY
  308. BPROP_OBJECT | BPROP_SAMPLER, // AR_OBJECT_SAMPLER
  309. BPROP_OBJECT | BPROP_SAMPLER, // AR_OBJECT_SAMPLER1D
  310. BPROP_OBJECT | BPROP_SAMPLER, // AR_OBJECT_SAMPLER2D
  311. BPROP_OBJECT | BPROP_SAMPLER, // AR_OBJECT_SAMPLER3D
  312. BPROP_OBJECT | BPROP_SAMPLER, // AR_OBJECT_SAMPLERCUBE
  313. BPROP_OBJECT | BPROP_SAMPLER, // AR_OBJECT_SAMPLERCOMPARISON
  314. BPROP_OBJECT | BPROP_RBUFFER, // AR_OBJECT_BUFFER
  315. BPROP_OBJECT, // AR_OBJECT_RENDERTARGETVIEW
  316. BPROP_OBJECT, // AR_OBJECT_DEPTHSTENCILVIEW
  317. BPROP_OBJECT, // AR_OBJECT_COMPUTESHADER
  318. BPROP_OBJECT, // AR_OBJECT_DOMAINSHADER
  319. BPROP_OBJECT, // AR_OBJECT_GEOMETRYSHADER
  320. BPROP_OBJECT, // AR_OBJECT_HULLSHADER
  321. BPROP_OBJECT, // AR_OBJECT_PIXELSHADER
  322. BPROP_OBJECT, // AR_OBJECT_VERTEXSHADER
  323. BPROP_OBJECT, // AR_OBJECT_PIXELFRAGMENT
  324. BPROP_OBJECT, // AR_OBJECT_VERTEXFRAGMENT
  325. BPROP_OBJECT, // AR_OBJECT_STATEBLOCK
  326. BPROP_OBJECT, // AR_OBJECT_RASTERIZER
  327. BPROP_OBJECT, // AR_OBJECT_DEPTHSTENCIL
  328. BPROP_OBJECT, // AR_OBJECT_BLEND
  329. BPROP_OBJECT | BPROP_STREAM, // AR_OBJECT_POINTSTREAM
  330. BPROP_OBJECT | BPROP_STREAM, // AR_OBJECT_LINESTREAM
  331. BPROP_OBJECT | BPROP_STREAM, // AR_OBJECT_TRIANGLESTREAM
  332. BPROP_OBJECT | BPROP_PATCH, // AR_OBJECT_INPUTPATCH
  333. BPROP_OBJECT | BPROP_PATCH, // AR_OBJECT_OUTPUTPATCH
  334. BPROP_OBJECT | BPROP_RWBUFFER, // AR_OBJECT_RWTEXTURE1D
  335. BPROP_OBJECT | BPROP_RWBUFFER, // AR_OBJECT_RWTEXTURE1D_ARRAY
  336. BPROP_OBJECT | BPROP_RWBUFFER, // AR_OBJECT_RWTEXTURE2D
  337. BPROP_OBJECT | BPROP_RWBUFFER, // AR_OBJECT_RWTEXTURE2D_ARRAY
  338. BPROP_OBJECT | BPROP_RWBUFFER, // AR_OBJECT_RWTEXTURE3D
  339. BPROP_OBJECT | BPROP_RWBUFFER, // AR_OBJECT_RWBUFFER
  340. BPROP_OBJECT | BPROP_RBUFFER, // AR_OBJECT_BYTEADDRESS_BUFFER
  341. BPROP_OBJECT | BPROP_RWBUFFER, // AR_OBJECT_RWBYTEADDRESS_BUFFER
  342. BPROP_OBJECT | BPROP_RBUFFER, // AR_OBJECT_STRUCTURED_BUFFER
  343. BPROP_OBJECT | BPROP_RWBUFFER, // AR_OBJECT_RWSTRUCTURED_BUFFER
  344. BPROP_OBJECT | BPROP_RWBUFFER, // AR_OBJECT_RWSTRUCTURED_BUFFER_ALLOC
  345. BPROP_OBJECT | BPROP_RWBUFFER, // AR_OBJECT_RWSTRUCTURED_BUFFER_CONSUME
  346. BPROP_OBJECT | BPROP_RWBUFFER, // AR_OBJECT_APPEND_STRUCTURED_BUFFER
  347. BPROP_OBJECT | BPROP_RWBUFFER, // AR_OBJECT_CONSUME_STRUCTURED_BUFFER
  348. BPROP_OBJECT | BPROP_RBUFFER, // AR_OBJECT_CONSTANT_BUFFER
  349. BPROP_OBJECT | BPROP_RBUFFER, // AR_OBJECT_TEXTURE_BUFFER
  350. BPROP_OBJECT | BPROP_RWBUFFER | BPROP_ROVBUFFER, // AR_OBJECT_ROVBUFFER
  351. BPROP_OBJECT | BPROP_RWBUFFER | BPROP_ROVBUFFER, // AR_OBJECT_ROVBYTEADDRESS_BUFFER
  352. BPROP_OBJECT | BPROP_RWBUFFER | BPROP_ROVBUFFER, // AR_OBJECT_ROVSTRUCTURED_BUFFER
  353. BPROP_OBJECT | BPROP_RWBUFFER | BPROP_ROVBUFFER, // AR_OBJECT_ROVTEXTURE1D
  354. BPROP_OBJECT | BPROP_RWBUFFER | BPROP_ROVBUFFER, // AR_OBJECT_ROVTEXTURE1D_ARRAY
  355. BPROP_OBJECT | BPROP_RWBUFFER | BPROP_ROVBUFFER, // AR_OBJECT_ROVTEXTURE2D
  356. BPROP_OBJECT | BPROP_RWBUFFER | BPROP_ROVBUFFER, // AR_OBJECT_ROVTEXTURE2D_ARRAY
  357. BPROP_OBJECT | BPROP_RWBUFFER | BPROP_ROVBUFFER, // AR_OBJECT_ROVTEXTURE3D
  358. // SPIRV change starts
  359. #ifdef ENABLE_SPIRV_CODEGEN
  360. BPROP_OBJECT | BPROP_RBUFFER, // AR_OBJECT_VK_SUBPASS_INPUT
  361. BPROP_OBJECT | BPROP_RBUFFER, // AR_OBJECT_VK_SUBPASS_INPUT_MS
  362. #endif // ENABLE_SPIRV_CODEGEN
  363. // SPIRV change ends
  364. BPROP_OBJECT, // AR_OBJECT_INNER
  365. BPROP_OBJECT, // AR_OBJECT_LEGACY_EFFECT
  366. BPROP_OBJECT, // AR_OBJECT_WAVE
  367. LICOMPTYPE_RAYDESC, // AR_OBJECT_RAY_DESC
  368. LICOMPTYPE_ACCELERATION_STRUCT, // AR_OBJECT_ACCELARATION_STRUCT
  369. LICOMPTYPE_USER_DEFINED_TYPE, // AR_OBJECT_USER_DEFINED_TYPE
  370. 0, // AR_OBJECT_TRIANGLE_INTERSECTION_ATTRIBUTES
  371. // AR_BASIC_MAXIMUM_COUNT
  372. };
  373. C_ASSERT(ARRAYSIZE(g_uBasicKindProps) == AR_BASIC_MAXIMUM_COUNT);
  374. #define GetBasicKindProps(_Kind) g_uBasicKindProps[(_Kind)]
  375. #define GET_BASIC_BITS(_Kind) \
  376. GET_BPROP_BITS(GetBasicKindProps(_Kind))
  377. #define GET_BASIC_PRIM_KIND(_Kind) \
  378. GET_BPROP_PRIM_KIND(GetBasicKindProps(_Kind))
  379. #define GET_BASIC_PRIM_KIND_SU(_Kind) \
  380. GET_BPROP_PRIM_KIND_SU(GetBasicKindProps(_Kind))
  381. #define IS_BASIC_PRIMITIVE(_Kind) \
  382. IS_BPROP_PRIMITIVE(GetBasicKindProps(_Kind))
  383. #define IS_BASIC_BOOL(_Kind) \
  384. IS_BPROP_BOOL(GetBasicKindProps(_Kind))
  385. #define IS_BASIC_FLOAT(_Kind) \
  386. IS_BPROP_FLOAT(GetBasicKindProps(_Kind))
  387. #define IS_BASIC_SINT(_Kind) \
  388. IS_BPROP_SINT(GetBasicKindProps(_Kind))
  389. #define IS_BASIC_UINT(_Kind) \
  390. IS_BPROP_UINT(GetBasicKindProps(_Kind))
  391. #define IS_BASIC_AINT(_Kind) \
  392. IS_BPROP_AINT(GetBasicKindProps(_Kind))
  393. #define IS_BASIC_STREAM(_Kind) \
  394. IS_BPROP_STREAM(GetBasicKindProps(_Kind))
  395. #define IS_BASIC_SAMPLER(_Kind) \
  396. IS_BPROP_SAMPLER(GetBasicKindProps(_Kind))
  397. #define IS_BASIC_TEXTURE(_Kind) \
  398. IS_BPROP_TEXTURE(GetBasicKindProps(_Kind))
  399. #define IS_BASIC_OBJECT(_Kind) \
  400. IS_BPROP_OBJECT(GetBasicKindProps(_Kind))
  401. #define IS_BASIC_MIN_PRECISION(_Kind) \
  402. IS_BPROP_MIN_PRECISION(GetBasicKindProps(_Kind))
  403. #define IS_BASIC_UNSIGNABLE(_Kind) \
  404. IS_BPROP_UNSIGNABLE(GetBasicKindProps(_Kind))
  405. #define IS_BASIC_ENUM(_Kind) \
  406. IS_BPROP_ENUM(GetBasicKindProps(_Kind))
  407. #define BITWISE_ENUM_OPS(_Type) \
  408. inline _Type operator|(_Type F1, _Type F2) \
  409. { \
  410. return (_Type)((UINT)F1 | (UINT)F2); \
  411. } \
  412. inline _Type operator&(_Type F1, _Type F2) \
  413. { \
  414. return (_Type)((UINT)F1 & (UINT)F2); \
  415. } \
  416. inline _Type& operator|=(_Type& F1, _Type F2) \
  417. { \
  418. F1 = F1 | F2; \
  419. return F1; \
  420. } \
  421. inline _Type& operator&=(_Type& F1, _Type F2) \
  422. { \
  423. F1 = F1 & F2; \
  424. return F1; \
  425. } \
  426. inline _Type& operator&=(_Type& F1, UINT F2) \
  427. { \
  428. F1 = (_Type)((UINT)F1 & F2); \
  429. return F1; \
  430. }
  431. enum ArTypeObjectKind {
  432. AR_TOBJ_INVALID, // Flag for an unassigned / unavailable object type.
  433. AR_TOBJ_VOID, // Represents the type for functions with not returned valued.
  434. AR_TOBJ_BASIC, // Represents a primitive type.
  435. AR_TOBJ_COMPOUND, // Represents a struct or class.
  436. AR_TOBJ_INTERFACE, // Represents an interface.
  437. AR_TOBJ_POINTER, // Represents a pointer to another type.
  438. AR_TOBJ_OBJECT, // Represents a built-in object.
  439. AR_TOBJ_ARRAY, // Represents an array of other types.
  440. AR_TOBJ_MATRIX, // Represents a matrix of basic types.
  441. AR_TOBJ_VECTOR, // Represents a vector of basic types.
  442. AR_TOBJ_QUALIFIER, // Represents another type plus an ArTypeQualifier.
  443. AR_TOBJ_INNER_OBJ, // Represents a built-in inner object, such as an
  444. // indexer object used to implement .mips[1].
  445. };
  446. enum TYPE_CONVERSION_FLAGS
  447. {
  448. TYPE_CONVERSION_DEFAULT = 0x00000000, // Indicates an implicit conversion is done.
  449. TYPE_CONVERSION_EXPLICIT = 0x00000001, // Indicates a conversion is done through an explicit cast.
  450. TYPE_CONVERSION_BY_REFERENCE = 0x00000002, // Indicates a conversion is done to an output parameter.
  451. };
  452. enum TYPE_CONVERSION_REMARKS
  453. {
  454. TYPE_CONVERSION_NONE = 0x00000000,
  455. TYPE_CONVERSION_PRECISION_LOSS = 0x00000001,
  456. TYPE_CONVERSION_IDENTICAL = 0x00000002,
  457. TYPE_CONVERSION_TO_VOID = 0x00000004,
  458. TYPE_CONVERSION_ELT_TRUNCATION = 0x00000008,
  459. };
  460. BITWISE_ENUM_OPS(TYPE_CONVERSION_REMARKS)
  461. #define AR_TOBJ_SCALAR AR_TOBJ_BASIC
  462. #define AR_TOBJ_UNKNOWN AR_TOBJ_INVALID
  463. #define AR_TPROP_VOID 0x0000000000000001
  464. #define AR_TPROP_CONST 0x0000000000000002
  465. #define AR_TPROP_IMP_CONST 0x0000000000000004
  466. #define AR_TPROP_OBJECT 0x0000000000000008
  467. #define AR_TPROP_SCALAR 0x0000000000000010
  468. #define AR_TPROP_UNSIGNED 0x0000000000000020
  469. #define AR_TPROP_NUMERIC 0x0000000000000040
  470. #define AR_TPROP_INTEGRAL 0x0000000000000080
  471. #define AR_TPROP_FLOATING 0x0000000000000100
  472. #define AR_TPROP_LITERAL 0x0000000000000200
  473. #define AR_TPROP_POINTER 0x0000000000000400
  474. #define AR_TPROP_INPUT_PATCH 0x0000000000000800
  475. #define AR_TPROP_OUTPUT_PATCH 0x0000000000001000
  476. #define AR_TPROP_INH_IFACE 0x0000000000002000
  477. #define AR_TPROP_HAS_COMPOUND 0x0000000000004000
  478. #define AR_TPROP_HAS_TEXTURES 0x0000000000008000
  479. #define AR_TPROP_HAS_SAMPLERS 0x0000000000010000
  480. #define AR_TPROP_HAS_SAMPLER_CMPS 0x0000000000020000
  481. #define AR_TPROP_HAS_STREAMS 0x0000000000040000
  482. #define AR_TPROP_HAS_OTHER_OBJECTS 0x0000000000080000
  483. #define AR_TPROP_HAS_BASIC 0x0000000000100000
  484. #define AR_TPROP_HAS_BUFFERS 0x0000000000200000
  485. #define AR_TPROP_HAS_ROBJECTS 0x0000000000400000
  486. #define AR_TPROP_HAS_POINTERS 0x0000000000800000
  487. #define AR_TPROP_INDEXABLE 0x0000000001000000
  488. #define AR_TPROP_HAS_MIPS 0x0000000002000000
  489. #define AR_TPROP_WRITABLE_GLOBAL 0x0000000004000000
  490. #define AR_TPROP_HAS_UAVS 0x0000000008000000
  491. #define AR_TPROP_HAS_BYTEADDRESS 0x0000000010000000
  492. #define AR_TPROP_HAS_STRUCTURED 0x0000000020000000
  493. #define AR_TPROP_HAS_SAMPLE 0x0000000040000000
  494. #define AR_TPROP_MIN_PRECISION 0x0000000080000000
  495. #define AR_TPROP_HAS_CBUFFERS 0x0000000100008000
  496. #define AR_TPROP_HAS_TBUFFERS 0x0000000200008000
  497. #define AR_TPROP_ALL 0xffffffffffffffff
  498. #define AR_TPROP_HAS_OBJECTS \
  499. (AR_TPROP_HAS_TEXTURES | AR_TPROP_HAS_SAMPLERS | \
  500. AR_TPROP_HAS_SAMPLER_CMPS | AR_TPROP_HAS_STREAMS | \
  501. AR_TPROP_HAS_OTHER_OBJECTS | AR_TPROP_HAS_BUFFERS | \
  502. AR_TPROP_HAS_ROBJECTS | AR_TPROP_HAS_UAVS | \
  503. AR_TPROP_HAS_BYTEADDRESS | AR_TPROP_HAS_STRUCTURED)
  504. #define AR_TPROP_HAS_BASIC_RESOURCES \
  505. (AR_TPROP_HAS_TEXTURES | AR_TPROP_HAS_SAMPLERS | \
  506. AR_TPROP_HAS_SAMPLER_CMPS | AR_TPROP_HAS_BUFFERS | \
  507. AR_TPROP_HAS_UAVS)
  508. #define AR_TPROP_UNION_BITS \
  509. (AR_TPROP_INH_IFACE | AR_TPROP_HAS_COMPOUND | AR_TPROP_HAS_TEXTURES | \
  510. AR_TPROP_HAS_SAMPLERS | AR_TPROP_HAS_SAMPLER_CMPS | \
  511. AR_TPROP_HAS_STREAMS | AR_TPROP_HAS_OTHER_OBJECTS | AR_TPROP_HAS_BASIC | \
  512. AR_TPROP_HAS_BUFFERS | AR_TPROP_HAS_ROBJECTS | AR_TPROP_HAS_POINTERS | \
  513. AR_TPROP_WRITABLE_GLOBAL | AR_TPROP_HAS_UAVS | \
  514. AR_TPROP_HAS_BYTEADDRESS | AR_TPROP_HAS_STRUCTURED | AR_TPROP_MIN_PRECISION)
  515. #define AR_TINFO_ALLOW_COMPLEX 0x00000001
  516. #define AR_TINFO_ALLOW_OBJECTS 0x00000002
  517. #define AR_TINFO_IGNORE_QUALIFIERS 0x00000004
  518. #define AR_TINFO_OBJECTS_AS_ELEMENTS 0x00000008
  519. #define AR_TINFO_PACK_SCALAR 0x00000010
  520. #define AR_TINFO_PACK_ROW_MAJOR 0x00000020
  521. #define AR_TINFO_PACK_TEMP_ARRAY 0x00000040
  522. #define AR_TINFO_ALL_VAR_INFO 0x00000080
  523. #define AR_TINFO_ALLOW_ALL (AR_TINFO_ALLOW_COMPLEX | AR_TINFO_ALLOW_OBJECTS)
  524. #define AR_TINFO_PACK_CBUFFER 0
  525. #define AR_TINFO_LAYOUT_PACK_ALL (AR_TINFO_PACK_SCALAR | AR_TINFO_PACK_TEMP_ARRAY)
  526. #define AR_TINFO_SIMPLE_OBJECTS \
  527. (AR_TINFO_ALLOW_OBJECTS | AR_TINFO_OBJECTS_AS_ELEMENTS)
  528. struct ArTypeInfo {
  529. ArTypeObjectKind ShapeKind; // The shape of the type (basic, matrix, etc.)
  530. ArBasicKind EltKind; // The primitive type of elements in this type.
  531. ArBasicKind ObjKind; // The object type for this type (textures, buffers, etc.)
  532. UINT uRows;
  533. UINT uCols;
  534. UINT uTotalElts;
  535. };
  536. using namespace clang;
  537. using namespace clang::sema;
  538. using namespace hlsl;
  539. extern const char *HLSLScalarTypeNames[];
  540. static const bool ExplicitConversionFalse = false;// a conversion operation is not the result of an explicit cast
  541. static const bool ParameterPackFalse = false; // template parameter is not an ellipsis.
  542. static const bool TypenameTrue = false; // 'typename' specified rather than 'class' for a template argument.
  543. static const bool DelayTypeCreationTrue = true; // delay type creation for a declaration
  544. static const SourceLocation NoLoc; // no source location attribution available
  545. static const SourceRange NoRange; // no source range attribution available
  546. static const bool HasWrittenPrototypeTrue = true; // function had the prototype written
  547. static const bool InlineSpecifiedFalse = false; // function was not specified as inline
  548. static const bool IsConstexprFalse = false; // function is not constexpr
  549. static const bool ListInitializationFalse = false;// not performing a list initialization
  550. static const bool SuppressWarningsFalse = false; // do not suppress warning diagnostics
  551. static const bool SuppressErrorsTrue = true; // suppress error diagnostics
  552. static const bool SuppressErrorsFalse = false; // do not suppress error diagnostics
  553. static const int OneRow = 1; // a single row for a type
  554. static const bool MipsFalse = false; // a type does not support the .mips member
  555. static const bool MipsTrue = true; // a type supports the .mips member
  556. static const bool SampleFalse = false; // a type does not support the .sample member
  557. static const bool SampleTrue = true; // a type supports the .sample member
  558. static const size_t MaxVectorSize = 4; // maximum size for a vector
  559. static
  560. QualType GetOrCreateTemplateSpecialization(
  561. ASTContext& context,
  562. Sema& sema,
  563. _In_ ClassTemplateDecl* templateDecl,
  564. ArrayRef<TemplateArgument> templateArgs
  565. )
  566. {
  567. DXASSERT_NOMSG(templateDecl);
  568. DeclContext* currentDeclContext = context.getTranslationUnitDecl();
  569. SmallVector<TemplateArgument, 3> templateArgsForDecl;
  570. for (const TemplateArgument& Arg : templateArgs) {
  571. if (Arg.getKind() == TemplateArgument::Type) {
  572. // the class template need to use CanonicalType
  573. templateArgsForDecl.emplace_back(TemplateArgument(Arg.getAsType().getCanonicalType()));
  574. }else
  575. templateArgsForDecl.emplace_back(Arg);
  576. }
  577. // First, try looking up existing specialization
  578. void* InsertPos = nullptr;
  579. ClassTemplateSpecializationDecl* specializationDecl =
  580. templateDecl->findSpecialization(templateArgsForDecl, InsertPos);
  581. if (specializationDecl) {
  582. // Instantiate the class template if not yet.
  583. if (specializationDecl->getInstantiatedFrom().isNull()) {
  584. // InstantiateClassTemplateSpecialization returns true if it finds an
  585. // error.
  586. DXVERIFY_NOMSG(false ==
  587. sema.InstantiateClassTemplateSpecialization(
  588. NoLoc, specializationDecl,
  589. TemplateSpecializationKind::TSK_ImplicitInstantiation,
  590. true));
  591. }
  592. return context.getTemplateSpecializationType(
  593. TemplateName(templateDecl), templateArgs.data(), templateArgs.size(),
  594. context.getTypeDeclType(specializationDecl));
  595. }
  596. specializationDecl = ClassTemplateSpecializationDecl::Create(
  597. context, TagDecl::TagKind::TTK_Class, currentDeclContext, NoLoc, NoLoc,
  598. templateDecl, templateArgsForDecl.data(), templateArgsForDecl.size(), nullptr);
  599. // InstantiateClassTemplateSpecialization returns true if it finds an error.
  600. DXVERIFY_NOMSG(false == sema.InstantiateClassTemplateSpecialization(
  601. NoLoc, specializationDecl, TemplateSpecializationKind::TSK_ImplicitInstantiation, true));
  602. templateDecl->AddSpecialization(specializationDecl, InsertPos);
  603. specializationDecl->setImplicit(true);
  604. QualType canonType = context.getTypeDeclType(specializationDecl);
  605. DXASSERT(isa<RecordType>(canonType), "type of non-dependent specialization is not a RecordType");
  606. TemplateArgumentListInfo templateArgumentList(NoLoc, NoLoc);
  607. TemplateArgumentLocInfo NoTemplateArgumentLocInfo;
  608. for (unsigned i = 0; i < templateArgs.size(); i++) {
  609. templateArgumentList.addArgument(TemplateArgumentLoc(templateArgs[i], NoTemplateArgumentLocInfo));
  610. }
  611. return context.getTemplateSpecializationType(
  612. TemplateName(templateDecl), templateArgumentList, canonType);
  613. }
  614. /// <summary>Instantiates a new matrix type specialization or gets an existing one from the AST.</summary>
  615. static
  616. QualType GetOrCreateMatrixSpecialization(ASTContext& context, Sema* sema,
  617. _In_ ClassTemplateDecl* matrixTemplateDecl,
  618. QualType elementType, uint64_t rowCount, uint64_t colCount)
  619. {
  620. DXASSERT_NOMSG(sema);
  621. TemplateArgument templateArgs[3] = {
  622. TemplateArgument(elementType),
  623. TemplateArgument(
  624. context,
  625. llvm::APSInt(
  626. llvm::APInt(context.getIntWidth(context.IntTy), rowCount), false),
  627. context.IntTy),
  628. TemplateArgument(
  629. context,
  630. llvm::APSInt(
  631. llvm::APInt(context.getIntWidth(context.IntTy), colCount), false),
  632. context.IntTy)};
  633. QualType matrixSpecializationType = GetOrCreateTemplateSpecialization(context, *sema, matrixTemplateDecl, ArrayRef<TemplateArgument>(templateArgs));
  634. #ifdef DBG
  635. // Verify that we can read the field member from the template record.
  636. DXASSERT(matrixSpecializationType->getAsCXXRecordDecl(),
  637. "type of non-dependent specialization is not a RecordType");
  638. DeclContext::lookup_result lookupResult = matrixSpecializationType->getAsCXXRecordDecl()->
  639. lookup(DeclarationName(&context.Idents.get(StringRef("h"))));
  640. DXASSERT(!lookupResult.empty(), "otherwise matrix handle cannot be looked up");
  641. #endif
  642. return matrixSpecializationType;
  643. }
  644. /// <summary>Instantiates a new vector type specialization or gets an existing one from the AST.</summary>
  645. static
  646. QualType GetOrCreateVectorSpecialization(ASTContext& context, Sema* sema,
  647. _In_ ClassTemplateDecl* vectorTemplateDecl,
  648. QualType elementType, uint64_t colCount)
  649. {
  650. DXASSERT_NOMSG(sema);
  651. DXASSERT_NOMSG(vectorTemplateDecl);
  652. TemplateArgument templateArgs[2] = {
  653. TemplateArgument(elementType),
  654. TemplateArgument(
  655. context,
  656. llvm::APSInt(
  657. llvm::APInt(context.getIntWidth(context.IntTy), colCount), false),
  658. context.IntTy)};
  659. QualType vectorSpecializationType = GetOrCreateTemplateSpecialization(context, *sema, vectorTemplateDecl, ArrayRef<TemplateArgument>(templateArgs));
  660. #ifdef DBG
  661. // Verify that we can read the field member from the template record.
  662. DXASSERT(vectorSpecializationType->getAsCXXRecordDecl(),
  663. "type of non-dependent specialization is not a RecordType");
  664. DeclContext::lookup_result lookupResult = vectorSpecializationType->getAsCXXRecordDecl()->
  665. lookup(DeclarationName(&context.Idents.get(StringRef("h"))));
  666. DXASSERT(!lookupResult.empty(), "otherwise vector handle cannot be looked up");
  667. #endif
  668. return vectorSpecializationType;
  669. }
  670. // Decls.cpp constants start here - these should be refactored or, better, replaced with clang::Type-based constructs.
  671. static const LPCSTR kBuiltinIntrinsicTableName = "op";
  672. static const unsigned kAtomicDstOperandIdx = 1;
  673. static const ArTypeObjectKind g_ScalarTT[] =
  674. {
  675. AR_TOBJ_SCALAR,
  676. AR_TOBJ_UNKNOWN
  677. };
  678. static const ArTypeObjectKind g_VectorTT[] =
  679. {
  680. AR_TOBJ_VECTOR,
  681. AR_TOBJ_UNKNOWN
  682. };
  683. static const ArTypeObjectKind g_MatrixTT[] =
  684. {
  685. AR_TOBJ_MATRIX,
  686. AR_TOBJ_UNKNOWN
  687. };
  688. static const ArTypeObjectKind g_AnyTT[] =
  689. {
  690. AR_TOBJ_SCALAR,
  691. AR_TOBJ_VECTOR,
  692. AR_TOBJ_MATRIX,
  693. AR_TOBJ_UNKNOWN
  694. };
  695. static const ArTypeObjectKind g_ObjectTT[] =
  696. {
  697. AR_TOBJ_OBJECT,
  698. AR_TOBJ_UNKNOWN
  699. };
  700. static const ArTypeObjectKind g_NullTT[] =
  701. {
  702. AR_TOBJ_VOID,
  703. AR_TOBJ_UNKNOWN
  704. };
  705. const ArTypeObjectKind* g_LegalIntrinsicTemplates[] =
  706. {
  707. g_NullTT,
  708. g_ScalarTT,
  709. g_VectorTT,
  710. g_MatrixTT,
  711. g_AnyTT,
  712. g_ObjectTT,
  713. };
  714. C_ASSERT(ARRAYSIZE(g_LegalIntrinsicTemplates) == LITEMPLATE_COUNT);
  715. //
  716. // The first one is used to name the representative group, so make
  717. // sure its name will make sense in error messages.
  718. //
  719. static const ArBasicKind g_BoolCT[] =
  720. {
  721. AR_BASIC_BOOL,
  722. AR_BASIC_UNKNOWN
  723. };
  724. static const ArBasicKind g_IntCT[] =
  725. {
  726. AR_BASIC_INT32,
  727. AR_BASIC_LITERAL_INT,
  728. AR_BASIC_UNKNOWN
  729. };
  730. static const ArBasicKind g_UIntCT[] =
  731. {
  732. AR_BASIC_UINT32,
  733. AR_BASIC_LITERAL_INT,
  734. AR_BASIC_UNKNOWN
  735. };
  736. // We use the first element for default if matching kind is missing in the list.
  737. // AR_BASIC_INT32 should be the default for any int since min precision integers should map to int32, not int16 or int64
  738. static const ArBasicKind g_AnyIntCT[] =
  739. {
  740. AR_BASIC_INT32,
  741. AR_BASIC_INT16,
  742. AR_BASIC_UINT32,
  743. AR_BASIC_UINT16,
  744. AR_BASIC_INT64,
  745. AR_BASIC_UINT64,
  746. AR_BASIC_LITERAL_INT,
  747. AR_BASIC_UNKNOWN
  748. };
  749. static const ArBasicKind g_AnyInt32CT[] =
  750. {
  751. AR_BASIC_INT32,
  752. AR_BASIC_UINT32,
  753. AR_BASIC_LITERAL_INT,
  754. AR_BASIC_UNKNOWN
  755. };
  756. static const ArBasicKind g_UIntOnlyCT[] =
  757. {
  758. AR_BASIC_UINT32,
  759. AR_BASIC_UINT64,
  760. AR_BASIC_LITERAL_INT,
  761. AR_BASIC_NOCAST,
  762. AR_BASIC_UNKNOWN
  763. };
  764. static const ArBasicKind g_FloatCT[] =
  765. {
  766. AR_BASIC_FLOAT32,
  767. AR_BASIC_FLOAT32_PARTIAL_PRECISION,
  768. AR_BASIC_LITERAL_FLOAT,
  769. AR_BASIC_UNKNOWN
  770. };
  771. static const ArBasicKind g_AnyFloatCT[] =
  772. {
  773. AR_BASIC_FLOAT32,
  774. AR_BASIC_FLOAT32_PARTIAL_PRECISION,
  775. AR_BASIC_FLOAT16,
  776. AR_BASIC_FLOAT64,
  777. AR_BASIC_LITERAL_FLOAT,
  778. AR_BASIC_MIN10FLOAT,
  779. AR_BASIC_MIN16FLOAT,
  780. AR_BASIC_UNKNOWN
  781. };
  782. static const ArBasicKind g_FloatLikeCT[] =
  783. {
  784. AR_BASIC_FLOAT32,
  785. AR_BASIC_FLOAT32_PARTIAL_PRECISION,
  786. AR_BASIC_FLOAT16,
  787. AR_BASIC_LITERAL_FLOAT,
  788. AR_BASIC_MIN10FLOAT,
  789. AR_BASIC_MIN16FLOAT,
  790. AR_BASIC_UNKNOWN
  791. };
  792. static const ArBasicKind g_FloatDoubleCT[] =
  793. {
  794. AR_BASIC_FLOAT32,
  795. AR_BASIC_FLOAT32_PARTIAL_PRECISION,
  796. AR_BASIC_FLOAT64,
  797. AR_BASIC_LITERAL_FLOAT,
  798. AR_BASIC_UNKNOWN
  799. };
  800. static const ArBasicKind g_DoubleCT[] =
  801. {
  802. AR_BASIC_FLOAT64,
  803. AR_BASIC_LITERAL_FLOAT,
  804. AR_BASIC_UNKNOWN
  805. };
  806. static const ArBasicKind g_DoubleOnlyCT[] =
  807. {
  808. AR_BASIC_FLOAT64,
  809. AR_BASIC_NOCAST,
  810. AR_BASIC_UNKNOWN
  811. };
  812. static const ArBasicKind g_NumericCT[] =
  813. {
  814. AR_BASIC_LITERAL_FLOAT,
  815. AR_BASIC_FLOAT32,
  816. AR_BASIC_FLOAT32_PARTIAL_PRECISION,
  817. AR_BASIC_FLOAT16,
  818. AR_BASIC_FLOAT64,
  819. AR_BASIC_MIN10FLOAT,
  820. AR_BASIC_MIN16FLOAT,
  821. AR_BASIC_LITERAL_INT,
  822. AR_BASIC_INT16,
  823. AR_BASIC_INT32,
  824. AR_BASIC_UINT16,
  825. AR_BASIC_UINT32,
  826. AR_BASIC_MIN12INT,
  827. AR_BASIC_MIN16INT,
  828. AR_BASIC_MIN16UINT,
  829. AR_BASIC_INT64,
  830. AR_BASIC_UINT64,
  831. AR_BASIC_UNKNOWN
  832. };
  833. static const ArBasicKind g_Numeric32CT[] =
  834. {
  835. AR_BASIC_LITERAL_FLOAT,
  836. AR_BASIC_FLOAT32,
  837. AR_BASIC_FLOAT32_PARTIAL_PRECISION,
  838. AR_BASIC_LITERAL_INT,
  839. AR_BASIC_INT32,
  840. AR_BASIC_UINT32,
  841. AR_BASIC_UNKNOWN
  842. };
  843. static const ArBasicKind g_Numeric32OnlyCT[] =
  844. {
  845. AR_BASIC_LITERAL_FLOAT,
  846. AR_BASIC_FLOAT32,
  847. AR_BASIC_FLOAT32_PARTIAL_PRECISION,
  848. AR_BASIC_LITERAL_INT,
  849. AR_BASIC_INT32,
  850. AR_BASIC_UINT32,
  851. AR_BASIC_NOCAST,
  852. AR_BASIC_UNKNOWN
  853. };
  854. static const ArBasicKind g_AnyCT[] =
  855. {
  856. AR_BASIC_LITERAL_FLOAT,
  857. AR_BASIC_FLOAT32,
  858. AR_BASIC_FLOAT32_PARTIAL_PRECISION,
  859. AR_BASIC_FLOAT16,
  860. AR_BASIC_FLOAT64,
  861. AR_BASIC_MIN10FLOAT,
  862. AR_BASIC_MIN16FLOAT,
  863. AR_BASIC_LITERAL_INT,
  864. AR_BASIC_INT16,
  865. AR_BASIC_UINT16,
  866. AR_BASIC_INT32,
  867. AR_BASIC_UINT32,
  868. AR_BASIC_MIN12INT,
  869. AR_BASIC_MIN16INT,
  870. AR_BASIC_MIN16UINT,
  871. AR_BASIC_BOOL,
  872. AR_BASIC_INT64,
  873. AR_BASIC_UINT64,
  874. AR_BASIC_UNKNOWN
  875. };
  876. static const ArBasicKind g_Sampler1DCT[] =
  877. {
  878. AR_OBJECT_SAMPLER1D,
  879. AR_BASIC_UNKNOWN
  880. };
  881. static const ArBasicKind g_Sampler2DCT[] =
  882. {
  883. AR_OBJECT_SAMPLER2D,
  884. AR_BASIC_UNKNOWN
  885. };
  886. static const ArBasicKind g_Sampler3DCT[] =
  887. {
  888. AR_OBJECT_SAMPLER3D,
  889. AR_BASIC_UNKNOWN
  890. };
  891. static const ArBasicKind g_SamplerCUBECT[] =
  892. {
  893. AR_OBJECT_SAMPLERCUBE,
  894. AR_BASIC_UNKNOWN
  895. };
  896. static const ArBasicKind g_SamplerCmpCT[] =
  897. {
  898. AR_OBJECT_SAMPLERCOMPARISON,
  899. AR_BASIC_UNKNOWN
  900. };
  901. static const ArBasicKind g_SamplerCT[] =
  902. {
  903. AR_OBJECT_SAMPLER,
  904. AR_BASIC_UNKNOWN
  905. };
  906. static const ArBasicKind g_RayDescCT[] =
  907. {
  908. AR_OBJECT_RAY_DESC,
  909. AR_BASIC_UNKNOWN
  910. };
  911. static const ArBasicKind g_AccelarationStructCT[] =
  912. {
  913. AR_OBJECT_ACCELARATION_STRUCT,
  914. AR_BASIC_UNKNOWN
  915. };
  916. static const ArBasicKind g_UDTCT[] =
  917. {
  918. AR_OBJECT_USER_DEFINED_TYPE,
  919. AR_BASIC_UNKNOWN
  920. };
  921. static const ArBasicKind g_StringCT[] =
  922. {
  923. AR_OBJECT_STRING,
  924. AR_BASIC_UNKNOWN
  925. };
  926. static const ArBasicKind g_NullCT[] =
  927. {
  928. AR_OBJECT_NULL,
  929. AR_BASIC_UNKNOWN
  930. };
  931. static const ArBasicKind g_WaveCT[] =
  932. {
  933. AR_OBJECT_WAVE,
  934. AR_BASIC_UNKNOWN
  935. };
  936. static const ArBasicKind g_UInt64CT[] =
  937. {
  938. AR_BASIC_UINT64,
  939. AR_BASIC_UNKNOWN
  940. };
  941. static const ArBasicKind g_Float16CT[] =
  942. {
  943. AR_BASIC_FLOAT16,
  944. AR_BASIC_LITERAL_FLOAT,
  945. AR_BASIC_UNKNOWN
  946. };
  947. static const ArBasicKind g_Int16CT[] =
  948. {
  949. AR_BASIC_INT16,
  950. AR_BASIC_LITERAL_INT,
  951. AR_BASIC_UNKNOWN
  952. };
  953. static const ArBasicKind g_UInt16CT[] =
  954. {
  955. AR_BASIC_UINT16,
  956. AR_BASIC_LITERAL_INT,
  957. AR_BASIC_UNKNOWN
  958. };
  959. static const ArBasicKind g_Numeric16OnlyCT[] =
  960. {
  961. AR_BASIC_FLOAT16,
  962. AR_BASIC_INT16,
  963. AR_BASIC_UINT16,
  964. AR_BASIC_LITERAL_FLOAT,
  965. AR_BASIC_LITERAL_INT,
  966. AR_BASIC_NOCAST,
  967. AR_BASIC_UNKNOWN
  968. };
  969. // Basic kinds, indexed by a LEGAL_INTRINSIC_COMPTYPES value.
  970. const ArBasicKind* g_LegalIntrinsicCompTypes[] =
  971. {
  972. g_NullCT, // LICOMPTYPE_VOID
  973. g_BoolCT, // LICOMPTYPE_BOOL
  974. g_IntCT, // LICOMPTYPE_INT
  975. g_UIntCT, // LICOMPTYPE_UINT
  976. g_AnyIntCT, // LICOMPTYPE_ANY_INT
  977. g_AnyInt32CT, // LICOMPTYPE_ANY_INT32
  978. g_UIntOnlyCT, // LICOMPTYPE_UINT_ONLY
  979. g_FloatCT, // LICOMPTYPE_FLOAT
  980. g_AnyFloatCT, // LICOMPTYPE_ANY_FLOAT
  981. g_FloatLikeCT, // LICOMPTYPE_FLOAT_LIKE
  982. g_FloatDoubleCT, // LICOMPTYPE_FLOAT_DOUBLE
  983. g_DoubleCT, // LICOMPTYPE_DOUBLE
  984. g_DoubleOnlyCT, // LICOMPTYPE_DOUBLE_ONLY
  985. g_NumericCT, // LICOMPTYPE_NUMERIC
  986. g_Numeric32CT, // LICOMPTYPE_NUMERIC32
  987. g_Numeric32OnlyCT, // LICOMPTYPE_NUMERIC32_ONLY
  988. g_AnyCT, // LICOMPTYPE_ANY
  989. g_Sampler1DCT, // LICOMPTYPE_SAMPLER1D
  990. g_Sampler2DCT, // LICOMPTYPE_SAMPLER2D
  991. g_Sampler3DCT, // LICOMPTYPE_SAMPLER3D
  992. g_SamplerCUBECT, // LICOMPTYPE_SAMPLERCUBE
  993. g_SamplerCmpCT, // LICOMPTYPE_SAMPLERCMP
  994. g_SamplerCT, // LICOMPTYPE_SAMPLER
  995. g_StringCT, // LICOMPTYPE_STRING
  996. g_WaveCT, // LICOMPTYPE_WAVE
  997. g_UInt64CT, // LICOMPTYPE_UINT64
  998. g_Float16CT, // LICOMPTYPE_FLOAT16
  999. g_Int16CT, // LICOMPTYPE_INT16
  1000. g_UInt16CT, // LICOMPTYPE_UINT16
  1001. g_Numeric16OnlyCT, // LICOMPTYPE_NUMERIC16_ONLY
  1002. g_RayDescCT, // LICOMPTYPE_RAYDESC
  1003. g_AccelarationStructCT, // LICOMPTYPE_ACCELERATION_STRUCT,
  1004. g_UDTCT, // LICOMPTYPE_USER_DEFINED_TYPE
  1005. };
  1006. C_ASSERT(ARRAYSIZE(g_LegalIntrinsicCompTypes) == LICOMPTYPE_COUNT);
  1007. // Decls.cpp constants ends here - these should be refactored or, better, replaced with clang::Type-based constructs.
  1008. // Basic kind objects that are represented as HLSL structures or templates.
  1009. static
  1010. const ArBasicKind g_ArBasicKindsAsTypes[] =
  1011. {
  1012. AR_OBJECT_BUFFER, // Buffer
  1013. // AR_OBJECT_TEXTURE,
  1014. AR_OBJECT_TEXTURE1D, // Texture1D
  1015. AR_OBJECT_TEXTURE1D_ARRAY, // Texture1DArray
  1016. AR_OBJECT_TEXTURE2D, // Texture2D
  1017. AR_OBJECT_TEXTURE2D_ARRAY, // Texture2DArray
  1018. AR_OBJECT_TEXTURE3D, // Texture3D
  1019. AR_OBJECT_TEXTURECUBE, // TextureCube
  1020. AR_OBJECT_TEXTURECUBE_ARRAY, // TextureCubeArray
  1021. AR_OBJECT_TEXTURE2DMS, // Texture2DMS
  1022. AR_OBJECT_TEXTURE2DMS_ARRAY, // Texture2DMSArray
  1023. AR_OBJECT_SAMPLER,
  1024. //AR_OBJECT_SAMPLER1D,
  1025. //AR_OBJECT_SAMPLER2D,
  1026. //AR_OBJECT_SAMPLER3D,
  1027. //AR_OBJECT_SAMPLERCUBE,
  1028. AR_OBJECT_SAMPLERCOMPARISON,
  1029. AR_OBJECT_POINTSTREAM,
  1030. AR_OBJECT_LINESTREAM,
  1031. AR_OBJECT_TRIANGLESTREAM,
  1032. AR_OBJECT_INPUTPATCH,
  1033. AR_OBJECT_OUTPUTPATCH,
  1034. AR_OBJECT_RWTEXTURE1D,
  1035. AR_OBJECT_RWTEXTURE1D_ARRAY,
  1036. AR_OBJECT_RWTEXTURE2D,
  1037. AR_OBJECT_RWTEXTURE2D_ARRAY,
  1038. AR_OBJECT_RWTEXTURE3D,
  1039. AR_OBJECT_RWBUFFER,
  1040. AR_OBJECT_BYTEADDRESS_BUFFER,
  1041. AR_OBJECT_RWBYTEADDRESS_BUFFER,
  1042. AR_OBJECT_STRUCTURED_BUFFER,
  1043. AR_OBJECT_RWSTRUCTURED_BUFFER,
  1044. // AR_OBJECT_RWSTRUCTURED_BUFFER_ALLOC,
  1045. // AR_OBJECT_RWSTRUCTURED_BUFFER_CONSUME,
  1046. AR_OBJECT_APPEND_STRUCTURED_BUFFER,
  1047. AR_OBJECT_CONSUME_STRUCTURED_BUFFER,
  1048. AR_OBJECT_ROVBUFFER,
  1049. AR_OBJECT_ROVBYTEADDRESS_BUFFER,
  1050. AR_OBJECT_ROVSTRUCTURED_BUFFER,
  1051. AR_OBJECT_ROVTEXTURE1D,
  1052. AR_OBJECT_ROVTEXTURE1D_ARRAY,
  1053. AR_OBJECT_ROVTEXTURE2D,
  1054. AR_OBJECT_ROVTEXTURE2D_ARRAY,
  1055. AR_OBJECT_ROVTEXTURE3D,
  1056. // SPIRV change starts
  1057. #ifdef ENABLE_SPIRV_CODEGEN
  1058. AR_OBJECT_VK_SUBPASS_INPUT,
  1059. AR_OBJECT_VK_SUBPASS_INPUT_MS,
  1060. #endif // ENABLE_SPIRV_CODEGEN
  1061. // SPIRV change ends
  1062. AR_OBJECT_LEGACY_EFFECT, // Used for all unsupported but ignored legacy effect types
  1063. AR_OBJECT_WAVE,
  1064. AR_OBJECT_RAY_DESC,
  1065. AR_OBJECT_ACCELARATION_STRUCT,
  1066. AR_OBJECT_TRIANGLE_INTERSECTION_ATTRIBUTES,
  1067. };
  1068. // Count of template arguments for basic kind of objects that look like templates (one or more type arguments).
  1069. static
  1070. const uint8_t g_ArBasicKindsTemplateCount[] =
  1071. {
  1072. 1, // AR_OBJECT_BUFFER
  1073. // AR_OBJECT_TEXTURE,
  1074. 1, // AR_OBJECT_TEXTURE1D
  1075. 1, // AR_OBJECT_TEXTURE1D_ARRAY
  1076. 1, // AR_OBJECT_TEXTURE2D
  1077. 1, // AR_OBJECT_TEXTURE2D_ARRAY
  1078. 1, // AR_OBJECT_TEXTURE3D
  1079. 1, // AR_OBJECT_TEXTURECUBE
  1080. 1, // AR_OBJECT_TEXTURECUBE_ARRAY
  1081. 2, // AR_OBJECT_TEXTURE2DMS
  1082. 2, // AR_OBJECT_TEXTURE2DMS_ARRAY
  1083. 0, // AR_OBJECT_SAMPLER
  1084. //AR_OBJECT_SAMPLER1D,
  1085. //AR_OBJECT_SAMPLER2D,
  1086. //AR_OBJECT_SAMPLER3D,
  1087. //AR_OBJECT_SAMPLERCUBE,
  1088. 0, // AR_OBJECT_SAMPLERCOMPARISON
  1089. 1, // AR_OBJECT_POINTSTREAM
  1090. 1, // AR_OBJECT_LINESTREAM
  1091. 1, // AR_OBJECT_TRIANGLESTREAM
  1092. 2, // AR_OBJECT_INPUTPATCH
  1093. 2, // AR_OBJECT_OUTPUTPATCH
  1094. 1, // AR_OBJECT_RWTEXTURE1D
  1095. 1, // AR_OBJECT_RWTEXTURE1D_ARRAY
  1096. 1, // AR_OBJECT_RWTEXTURE2D
  1097. 1, // AR_OBJECT_RWTEXTURE2D_ARRAY
  1098. 1, // AR_OBJECT_RWTEXTURE3D
  1099. 1, // AR_OBJECT_RWBUFFER
  1100. 0, // AR_OBJECT_BYTEADDRESS_BUFFER
  1101. 0, // AR_OBJECT_RWBYTEADDRESS_BUFFER
  1102. 1, // AR_OBJECT_STRUCTURED_BUFFER
  1103. 1, // AR_OBJECT_RWSTRUCTURED_BUFFER
  1104. // 1, // AR_OBJECT_RWSTRUCTURED_BUFFER_ALLOC
  1105. // 1, // AR_OBJECT_RWSTRUCTURED_BUFFER_CONSUME
  1106. 1, // AR_OBJECT_APPEND_STRUCTURED_BUFFER
  1107. 1, // AR_OBJECT_CONSUME_STRUCTURED_BUFFER
  1108. 1, // AR_OBJECT_ROVBUFFER
  1109. 0, // AR_OBJECT_ROVBYTEADDRESS_BUFFER
  1110. 1, // AR_OBJECT_ROVSTRUCTURED_BUFFER
  1111. 1, // AR_OBJECT_ROVTEXTURE1D
  1112. 1, // AR_OBJECT_ROVTEXTURE1D_ARRAY
  1113. 1, // AR_OBJECT_ROVTEXTURE2D
  1114. 1, // AR_OBJECT_ROVTEXTURE2D_ARRAY
  1115. 1, // AR_OBJECT_ROVTEXTURE3D
  1116. // SPIRV change starts
  1117. #ifdef ENABLE_SPIRV_CODEGEN
  1118. 1, // AR_OBJECT_VK_SUBPASS_INPUT
  1119. 1, // AR_OBJECT_VK_SUBPASS_INPUT_MS
  1120. #endif // ENABLE_SPIRV_CODEGEN
  1121. // SPIRV change ends
  1122. 0, // AR_OBJECT_LEGACY_EFFECT // Used for all unsupported but ignored legacy effect types
  1123. 0, // AR_OBJECT_WAVE
  1124. 0, // AR_OBJECT_RAY_DESC
  1125. 0, // AR_OBJECT_ACCELARATION_STRUCT
  1126. 0, // AR_OBJECT_TRIANGLE_INTERSECTION_ATTRIBUTES
  1127. };
  1128. C_ASSERT(_countof(g_ArBasicKindsAsTypes) == _countof(g_ArBasicKindsTemplateCount));
  1129. /// <summary>Describes the how the subscript or indexing operators work on a given type.</summary>
  1130. struct SubscriptOperatorRecord
  1131. {
  1132. unsigned int SubscriptCardinality : 4; // Number of elements expected in subscript - zero if operator not supported.
  1133. bool HasMips : 1; // true if the kind has a mips member; false otherwise
  1134. bool HasSample : 1; // true if the kind has a sample member; false otherwise
  1135. };
  1136. // Subscript operators for objects that are represented as HLSL structures or templates.
  1137. static
  1138. const SubscriptOperatorRecord g_ArBasicKindsSubscripts[] =
  1139. {
  1140. { 1, MipsFalse, SampleFalse }, // AR_OBJECT_BUFFER (Buffer)
  1141. // AR_OBJECT_TEXTURE,
  1142. { 1, MipsTrue, SampleFalse }, // AR_OBJECT_TEXTURE1D (Texture1D)
  1143. { 2, MipsTrue, SampleFalse }, // AR_OBJECT_TEXTURE1D_ARRAY (Texture1DArray)
  1144. { 2, MipsTrue, SampleFalse }, // AR_OBJECT_TEXTURE2D (Texture2D)
  1145. { 3, MipsTrue, SampleFalse }, // AR_OBJECT_TEXTURE2D_ARRAY (Texture2DArray)
  1146. { 3, MipsTrue, SampleFalse }, // AR_OBJECT_TEXTURE3D (Texture3D)
  1147. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_TEXTURECUBE (TextureCube)
  1148. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_TEXTURECUBE_ARRAY (TextureCubeArray)
  1149. { 2, MipsFalse, SampleTrue }, // AR_OBJECT_TEXTURE2DMS (Texture2DMS)
  1150. { 3, MipsFalse, SampleTrue }, // AR_OBJECT_TEXTURE2DMS_ARRAY (Texture2DMSArray)
  1151. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_SAMPLER (SamplerState)
  1152. //AR_OBJECT_SAMPLER1D,
  1153. //AR_OBJECT_SAMPLER2D,
  1154. //AR_OBJECT_SAMPLER3D,
  1155. //AR_OBJECT_SAMPLERCUBE,
  1156. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_SAMPLERCOMPARISON (SamplerComparison)
  1157. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_POINTSTREAM (PointStream)
  1158. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_LINESTREAM (LineStream)
  1159. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_TRIANGLESTREAM (TriangleStream)
  1160. { 1, MipsFalse, SampleFalse }, // AR_OBJECT_INPUTPATCH (InputPatch)
  1161. { 1, MipsFalse, SampleFalse }, // AR_OBJECT_OUTPUTPATCH (OutputPatch)
  1162. { 1, MipsFalse, SampleFalse }, // AR_OBJECT_RWTEXTURE1D (RWTexture1D)
  1163. { 2, MipsFalse, SampleFalse }, // AR_OBJECT_RWTEXTURE1D_ARRAY (RWTexture1DArray)
  1164. { 2, MipsFalse, SampleFalse }, // AR_OBJECT_RWTEXTURE2D (RWTexture2D)
  1165. { 3, MipsFalse, SampleFalse }, // AR_OBJECT_RWTEXTURE2D_ARRAY (RWTexture2DArray)
  1166. { 3, MipsFalse, SampleFalse }, // AR_OBJECT_RWTEXTURE3D (RWTexture3D)
  1167. { 1, MipsFalse, SampleFalse }, // AR_OBJECT_RWBUFFER (RWBuffer)
  1168. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_BYTEADDRESS_BUFFER (ByteAddressBuffer)
  1169. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_RWBYTEADDRESS_BUFFER (RWByteAddressBuffer)
  1170. { 1, MipsFalse, SampleFalse }, // AR_OBJECT_STRUCTURED_BUFFER (StructuredBuffer)
  1171. { 1, MipsFalse, SampleFalse }, // AR_OBJECT_RWSTRUCTURED_BUFFER (RWStructuredBuffer)
  1172. // AR_OBJECT_RWSTRUCTURED_BUFFER_ALLOC,
  1173. // AR_OBJECT_RWSTRUCTURED_BUFFER_CONSUME,
  1174. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_APPEND_STRUCTURED_BUFFER (AppendStructuredBuffer)
  1175. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_CONSUME_STRUCTURED_BUFFER (ConsumeStructuredBuffer)
  1176. { 1, MipsFalse, SampleFalse }, // AR_OBJECT_ROVBUFFER (ROVBuffer)
  1177. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_ROVBYTEADDRESS_BUFFER (ROVByteAddressBuffer)
  1178. { 1, MipsFalse, SampleFalse }, // AR_OBJECT_ROVSTRUCTURED_BUFFER (ROVStructuredBuffer)
  1179. { 1, MipsFalse, SampleFalse }, // AR_OBJECT_ROVTEXTURE1D (ROVTexture1D)
  1180. { 2, MipsFalse, SampleFalse }, // AR_OBJECT_ROVTEXTURE1D_ARRAY (ROVTexture1DArray)
  1181. { 2, MipsFalse, SampleFalse }, // AR_OBJECT_ROVTEXTURE2D (ROVTexture2D)
  1182. { 3, MipsFalse, SampleFalse }, // AR_OBJECT_ROVTEXTURE2D_ARRAY (ROVTexture2DArray)
  1183. { 3, MipsFalse, SampleFalse }, // AR_OBJECT_ROVTEXTURE3D (ROVTexture3D)
  1184. // SPIRV change starts
  1185. #ifdef ENABLE_SPIRV_CODEGEN
  1186. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_VK_SUBPASS_INPUT (SubpassInput)
  1187. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_VK_SUBPASS_INPUT_MS (SubpassInputMS)
  1188. #endif // ENABLE_SPIRV_CODEGEN
  1189. // SPIRV change ends
  1190. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_LEGACY_EFFECT (legacy effect objects)
  1191. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_WAVE
  1192. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_RAY_DESC
  1193. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_ACCELARATION_STRUCT
  1194. { 0, MipsFalse, SampleFalse }, // AR_OBJECT_TRIANGLE_INTERSECTION_ATTRIBUTES
  1195. };
  1196. C_ASSERT(_countof(g_ArBasicKindsAsTypes) == _countof(g_ArBasicKindsSubscripts));
  1197. // Type names for ArBasicKind values.
  1198. static
  1199. const char* g_ArBasicTypeNames[] =
  1200. {
  1201. "bool", "float", "half", "half", "float", "double",
  1202. "int", "sbyte", "byte", "short", "ushort",
  1203. "int", "uint", "long", "ulong",
  1204. "min10float", "min16float",
  1205. "min12int", "min16int", "min16uint",
  1206. "enum",
  1207. "<count>",
  1208. "<none>",
  1209. "<unknown>",
  1210. "<nocast>",
  1211. "<pointer>",
  1212. "enum class",
  1213. "null",
  1214. "string",
  1215. // "texture",
  1216. "Texture1D",
  1217. "Texture1DArray",
  1218. "Texture2D",
  1219. "Texture2DArray",
  1220. "Texture3D",
  1221. "TextureCube",
  1222. "TextureCubeArray",
  1223. "Texture2DMS",
  1224. "Texture2DMSArray",
  1225. "SamplerState",
  1226. "sampler1D",
  1227. "sampler2D",
  1228. "sampler3D",
  1229. "samplerCUBE",
  1230. "SamplerComparisonState",
  1231. "Buffer",
  1232. "RenderTargetView",
  1233. "DepthStencilView",
  1234. "ComputeShader",
  1235. "DomainShader",
  1236. "GeometryShader",
  1237. "HullShader",
  1238. "PixelShader",
  1239. "VertexShader",
  1240. "pixelfragment",
  1241. "vertexfragment",
  1242. "StateBlock",
  1243. "Rasterizer",
  1244. "DepthStencil",
  1245. "Blend",
  1246. "PointStream",
  1247. "LineStream",
  1248. "TriangleStream",
  1249. "InputPatch",
  1250. "OutputPatch",
  1251. "RWTexture1D",
  1252. "RWTexture1DArray",
  1253. "RWTexture2D",
  1254. "RWTexture2DArray",
  1255. "RWTexture3D",
  1256. "RWBuffer",
  1257. "ByteAddressBuffer",
  1258. "RWByteAddressBuffer",
  1259. "StructuredBuffer",
  1260. "RWStructuredBuffer",
  1261. "RWStructuredBuffer(Incrementable)",
  1262. "RWStructuredBuffer(Decrementable)",
  1263. "AppendStructuredBuffer",
  1264. "ConsumeStructuredBuffer",
  1265. "ConstantBuffer",
  1266. "TextureBuffer",
  1267. "RasterizerOrderedBuffer",
  1268. "RasterizerOrderedByteAddressBuffer",
  1269. "RasterizerOrderedStructuredBuffer",
  1270. "RasterizerOrderedTexture1D",
  1271. "RasterizerOrderedTexture1DArray",
  1272. "RasterizerOrderedTexture2D",
  1273. "RasterizerOrderedTexture2DArray",
  1274. "RasterizerOrderedTexture3D",
  1275. // SPIRV change starts
  1276. #ifdef ENABLE_SPIRV_CODEGEN
  1277. "SubpassInput",
  1278. "SubpassInputMS",
  1279. #endif // ENABLE_SPIRV_CODEGEN
  1280. // SPIRV change ends
  1281. "<internal inner type object>",
  1282. "deprecated effect object",
  1283. "wave_t",
  1284. "RayDesc",
  1285. "RaytracingAccelerationStructure",
  1286. "user defined type",
  1287. "BuiltInTriangleIntersectionAttributes"
  1288. };
  1289. C_ASSERT(_countof(g_ArBasicTypeNames) == AR_BASIC_MAXIMUM_COUNT);
  1290. // kind should never be a flag value or effects framework type - we simply do not expect to deal with these
  1291. #define DXASSERT_VALIDBASICKIND(kind) \
  1292. DXASSERT(\
  1293. kind != AR_BASIC_COUNT && \
  1294. kind != AR_BASIC_NONE && \
  1295. kind != AR_BASIC_UNKNOWN && \
  1296. kind != AR_BASIC_NOCAST && \
  1297. kind != AR_BASIC_POINTER && \
  1298. kind != AR_OBJECT_RENDERTARGETVIEW && \
  1299. kind != AR_OBJECT_DEPTHSTENCILVIEW && \
  1300. kind != AR_OBJECT_COMPUTESHADER && \
  1301. kind != AR_OBJECT_DOMAINSHADER && \
  1302. kind != AR_OBJECT_GEOMETRYSHADER && \
  1303. kind != AR_OBJECT_HULLSHADER && \
  1304. kind != AR_OBJECT_PIXELSHADER && \
  1305. kind != AR_OBJECT_VERTEXSHADER && \
  1306. kind != AR_OBJECT_PIXELFRAGMENT && \
  1307. kind != AR_OBJECT_VERTEXFRAGMENT, "otherwise caller is using a special flag or an unsupported kind value");
  1308. static
  1309. const char* g_DeprecatedEffectObjectNames[] =
  1310. {
  1311. // These are case insensitive in fxc, but we'll just create two case aliases
  1312. // to capture the majority of cases
  1313. "texture", "Texture",
  1314. "pixelshader", "PixelShader",
  1315. "vertexshader", "VertexShader",
  1316. // These are case sensitive in fxc
  1317. "pixelfragment", // 13
  1318. "vertexfragment", // 14
  1319. "ComputeShader", // 13
  1320. "DomainShader", // 12
  1321. "GeometryShader", // 14
  1322. "HullShader", // 10
  1323. "BlendState", // 10
  1324. "DepthStencilState",// 17
  1325. "DepthStencilView", // 16
  1326. "RasterizerState", // 15
  1327. "RenderTargetView", // 16
  1328. };
  1329. static hlsl::ParameterModifier
  1330. ParamModsFromIntrinsicArg(const HLSL_INTRINSIC_ARGUMENT *pArg) {
  1331. if (pArg->qwUsage == AR_QUAL_IN_OUT) {
  1332. return hlsl::ParameterModifier(hlsl::ParameterModifier::Kind::InOut);
  1333. }
  1334. if (pArg->qwUsage == AR_QUAL_OUT) {
  1335. return hlsl::ParameterModifier(hlsl::ParameterModifier::Kind::Out);
  1336. }
  1337. DXASSERT(pArg->qwUsage & AR_QUAL_IN, "else usage is incorrect");
  1338. return hlsl::ParameterModifier(hlsl::ParameterModifier::Kind::In);
  1339. }
  1340. static void InitParamMods(const HLSL_INTRINSIC *pIntrinsic,
  1341. SmallVectorImpl<hlsl::ParameterModifier> &paramMods) {
  1342. // The first argument is the return value, which isn't included.
  1343. for (UINT i = 1; i < pIntrinsic->uNumArgs; ++i) {
  1344. paramMods.push_back(ParamModsFromIntrinsicArg(&pIntrinsic->pArgs[i]));
  1345. }
  1346. }
  1347. static bool IsAtomicOperation(IntrinsicOp op) {
  1348. switch (op) {
  1349. case IntrinsicOp::IOP_InterlockedAdd:
  1350. case IntrinsicOp::IOP_InterlockedAnd:
  1351. case IntrinsicOp::IOP_InterlockedCompareExchange:
  1352. case IntrinsicOp::IOP_InterlockedCompareStore:
  1353. case IntrinsicOp::IOP_InterlockedExchange:
  1354. case IntrinsicOp::IOP_InterlockedMax:
  1355. case IntrinsicOp::IOP_InterlockedMin:
  1356. case IntrinsicOp::IOP_InterlockedOr:
  1357. case IntrinsicOp::IOP_InterlockedXor:
  1358. case IntrinsicOp::MOP_InterlockedAdd:
  1359. case IntrinsicOp::MOP_InterlockedAnd:
  1360. case IntrinsicOp::MOP_InterlockedCompareExchange:
  1361. case IntrinsicOp::MOP_InterlockedCompareStore:
  1362. case IntrinsicOp::MOP_InterlockedExchange:
  1363. case IntrinsicOp::MOP_InterlockedMax:
  1364. case IntrinsicOp::MOP_InterlockedMin:
  1365. case IntrinsicOp::MOP_InterlockedOr:
  1366. case IntrinsicOp::MOP_InterlockedXor:
  1367. return true;
  1368. default:
  1369. return false;
  1370. }
  1371. }
  1372. static bool IsBuiltinTable(LPCSTR tableName) {
  1373. return tableName == kBuiltinIntrinsicTableName;
  1374. }
  1375. static void AddHLSLIntrinsicAttr(FunctionDecl *FD, ASTContext &context,
  1376. LPCSTR tableName, LPCSTR lowering,
  1377. const HLSL_INTRINSIC *pIntrinsic) {
  1378. unsigned opcode = (unsigned)pIntrinsic->Op;
  1379. if (HasUnsignedOpcode(opcode) && IsBuiltinTable(tableName)) {
  1380. QualType Ty = FD->getReturnType();
  1381. if (pIntrinsic->iOverloadParamIndex != -1) {
  1382. const FunctionProtoType *FT =
  1383. FD->getFunctionType()->getAs<FunctionProtoType>();
  1384. Ty = FT->getParamType(pIntrinsic->iOverloadParamIndex);
  1385. }
  1386. // TODO: refine the code for getting element type
  1387. if (const ExtVectorType *VecTy = hlsl::ConvertHLSLVecMatTypeToExtVectorType(context, Ty)) {
  1388. Ty = VecTy->getElementType();
  1389. }
  1390. if (Ty->isUnsignedIntegerType()) {
  1391. opcode = hlsl::GetUnsignedOpcode(opcode);
  1392. }
  1393. }
  1394. FD->addAttr(HLSLIntrinsicAttr::CreateImplicit(context, tableName, lowering, opcode));
  1395. if (pIntrinsic->bReadNone)
  1396. FD->addAttr(ConstAttr::CreateImplicit(context));
  1397. if (pIntrinsic->bReadOnly)
  1398. FD->addAttr(PureAttr::CreateImplicit(context));
  1399. }
  1400. static
  1401. FunctionDecl *AddHLSLIntrinsicFunction(
  1402. ASTContext &context, _In_ NamespaceDecl *NS,
  1403. LPCSTR tableName, LPCSTR lowering,
  1404. _In_ const HLSL_INTRINSIC *pIntrinsic,
  1405. _In_count_(functionArgTypeCount) QualType *functionArgQualTypes,
  1406. _In_range_(0, g_MaxIntrinsicParamCount - 1) size_t functionArgTypeCount) {
  1407. DXASSERT(functionArgTypeCount - 1 <= g_MaxIntrinsicParamCount,
  1408. "otherwise g_MaxIntrinsicParamCount should be larger");
  1409. DeclContext *currentDeclContext = context.getTranslationUnitDecl();
  1410. SmallVector<hlsl::ParameterModifier, g_MaxIntrinsicParamCount> paramMods;
  1411. InitParamMods(pIntrinsic, paramMods);
  1412. // Change dest address into reference type for atomic.
  1413. if (IsBuiltinTable(tableName)) {
  1414. if (IsAtomicOperation(static_cast<IntrinsicOp>(pIntrinsic->Op))) {
  1415. DXASSERT(functionArgTypeCount > kAtomicDstOperandIdx,
  1416. "else operation was misrecognized");
  1417. functionArgQualTypes[kAtomicDstOperandIdx] =
  1418. context.getLValueReferenceType(functionArgQualTypes[kAtomicDstOperandIdx]);
  1419. }
  1420. }
  1421. for (size_t i = 1; i < functionArgTypeCount; i++) {
  1422. // Change out/inout param to reference type.
  1423. if (paramMods[i-1].isAnyOut()) {
  1424. QualType Ty = functionArgQualTypes[i];
  1425. // Aggregate type will be indirect param convert to pointer type.
  1426. // Don't need add reference for it.
  1427. if ((!Ty->isArrayType() && !Ty->isRecordType()) ||
  1428. hlsl::IsHLSLVecMatType(Ty)) {
  1429. functionArgQualTypes[i] = context.getLValueReferenceType(Ty);
  1430. }
  1431. }
  1432. }
  1433. IdentifierInfo &functionId = context.Idents.get(
  1434. StringRef(pIntrinsic->pArgs[0].pName), tok::TokenKind::identifier);
  1435. DeclarationName functionName(&functionId);
  1436. QualType functionType = context.getFunctionType(
  1437. functionArgQualTypes[0],
  1438. ArrayRef<QualType>(functionArgQualTypes + 1,
  1439. functionArgQualTypes + functionArgTypeCount),
  1440. clang::FunctionProtoType::ExtProtoInfo(), paramMods);
  1441. FunctionDecl *functionDecl = FunctionDecl::Create(
  1442. context, currentDeclContext, NoLoc,
  1443. DeclarationNameInfo(functionName, NoLoc), functionType, nullptr,
  1444. StorageClass::SC_Extern, InlineSpecifiedFalse, HasWrittenPrototypeTrue);
  1445. currentDeclContext->addDecl(functionDecl);
  1446. functionDecl->setLexicalDeclContext(currentDeclContext);
  1447. // put under hlsl namespace
  1448. functionDecl->setDeclContext(NS);
  1449. // Add intrinsic attribute
  1450. AddHLSLIntrinsicAttr(functionDecl, context, tableName, lowering, pIntrinsic);
  1451. ParmVarDecl *paramDecls[g_MaxIntrinsicParamCount];
  1452. for (size_t i = 1; i < functionArgTypeCount; i++) {
  1453. IdentifierInfo &parameterId = context.Idents.get(
  1454. StringRef(pIntrinsic->pArgs[i].pName), tok::TokenKind::identifier);
  1455. ParmVarDecl *paramDecl =
  1456. ParmVarDecl::Create(context, functionDecl, NoLoc, NoLoc, &parameterId,
  1457. functionArgQualTypes[i], nullptr,
  1458. StorageClass::SC_None, nullptr, paramMods[i - 1]);
  1459. functionDecl->addDecl(paramDecl);
  1460. paramDecls[i - 1] = paramDecl;
  1461. }
  1462. functionDecl->setParams(
  1463. ArrayRef<ParmVarDecl *>(paramDecls, functionArgTypeCount - 1));
  1464. functionDecl->setImplicit(true);
  1465. return functionDecl;
  1466. }
  1467. /// <summary>
  1468. /// Checks whether the specified expression is a (possibly parenthesized) comma operator.
  1469. /// </summary>
  1470. static
  1471. bool IsExpressionBinaryComma(_In_ const Expr* expr)
  1472. {
  1473. DXASSERT_NOMSG(expr != nullptr);
  1474. expr = expr->IgnoreParens();
  1475. return
  1476. expr->getStmtClass() == Expr::StmtClass::BinaryOperatorClass &&
  1477. cast<BinaryOperator>(expr)->getOpcode() == BinaryOperatorKind::BO_Comma;
  1478. }
  1479. /// <summary>
  1480. /// Silences diagnostics for the initialization sequence, typically because they have already
  1481. /// been emitted.
  1482. /// </summary>
  1483. static
  1484. void SilenceSequenceDiagnostics(_Inout_ InitializationSequence* initSequence)
  1485. {
  1486. DXASSERT_NOMSG(initSequence != nullptr);
  1487. initSequence->SetFailed(InitializationSequence::FK_ListInitializationFailed);
  1488. }
  1489. class UsedIntrinsic
  1490. {
  1491. public:
  1492. static int compareArgs(const QualType& LHS, const QualType& RHS)
  1493. {
  1494. // The canonical representations are unique'd in an ASTContext, and so these
  1495. // should be stable.
  1496. return RHS.getTypePtr() - LHS.getTypePtr();
  1497. }
  1498. static int compareIntrinsic(const HLSL_INTRINSIC* LHS, const HLSL_INTRINSIC* RHS)
  1499. {
  1500. // The intrinsics are defined in a single static table, and so should be stable.
  1501. return RHS - LHS;
  1502. }
  1503. int compare(const UsedIntrinsic& other) const
  1504. {
  1505. // Check whether it's the same instance.
  1506. if (this == &other) return 0;
  1507. int result = compareIntrinsic(m_intrinsicSource, other.m_intrinsicSource);
  1508. if (result != 0) return result;
  1509. // At this point, it's the exact same intrinsic name.
  1510. // Compare the arguments for ordering then.
  1511. DXASSERT(m_argLength == other.m_argLength, "intrinsics aren't overloaded on argument count, so we should never create a key with different #s");
  1512. for (size_t i = 0; i < m_argLength; i++) {
  1513. int argComparison = compareArgs(m_args[i], other.m_args[i]);
  1514. if (argComparison != 0) return argComparison;
  1515. }
  1516. // Exactly the same.
  1517. return 0;
  1518. }
  1519. public:
  1520. UsedIntrinsic(const HLSL_INTRINSIC* intrinsicSource, _In_count_(argCount) QualType* args, size_t argCount)
  1521. : m_argLength(argCount), m_intrinsicSource(intrinsicSource), m_functionDecl(nullptr)
  1522. {
  1523. std::copy(args, args + argCount, m_args);
  1524. }
  1525. void setFunctionDecl(FunctionDecl* value) const
  1526. {
  1527. DXASSERT(value != nullptr, "no reason to clear this out");
  1528. DXASSERT(m_functionDecl == nullptr, "otherwise cached value is being invaldiated");
  1529. m_functionDecl = value;
  1530. }
  1531. FunctionDecl* getFunctionDecl() const { return m_functionDecl; }
  1532. bool operator==(const UsedIntrinsic& other) const
  1533. {
  1534. return compare(other) == 0;
  1535. }
  1536. bool operator<(const UsedIntrinsic& other) const
  1537. {
  1538. return compare(other) < 0;
  1539. }
  1540. private:
  1541. QualType m_args[g_MaxIntrinsicParamCount+1];
  1542. size_t m_argLength;
  1543. const HLSL_INTRINSIC* m_intrinsicSource;
  1544. mutable FunctionDecl* m_functionDecl;
  1545. };
  1546. template <typename T>
  1547. inline void AssignOpt(T value, _Out_opt_ T* ptr)
  1548. {
  1549. if (ptr != nullptr)
  1550. {
  1551. *ptr = value;
  1552. }
  1553. }
  1554. static bool CombineBasicTypes(ArBasicKind LeftKind,
  1555. ArBasicKind RightKind,
  1556. _Out_ ArBasicKind* pOutKind)
  1557. {
  1558. if ((LeftKind < 0 || LeftKind >= AR_BASIC_COUNT) ||
  1559. (RightKind < 0 || RightKind >= AR_BASIC_COUNT)) {
  1560. return false;
  1561. }
  1562. if (LeftKind == RightKind) {
  1563. *pOutKind = LeftKind;
  1564. return true;
  1565. }
  1566. UINT uLeftProps = GetBasicKindProps(LeftKind);
  1567. UINT uRightProps = GetBasicKindProps(RightKind);
  1568. UINT uBits = GET_BPROP_BITS(uLeftProps) > GET_BPROP_BITS(uRightProps) ?
  1569. GET_BPROP_BITS(uLeftProps) : GET_BPROP_BITS(uRightProps);
  1570. UINT uBothFlags = uLeftProps & uRightProps;
  1571. UINT uEitherFlags = uLeftProps | uRightProps;
  1572. // Notes: all numeric types have either BPROP_FLOATING or BPROP_INTEGER (even bool)
  1573. // unsigned only applies to non-literal ints, not bool or enum
  1574. // literals, bool, and enum are all BPROP_BITS0
  1575. if (uBothFlags & BPROP_BOOLEAN) {
  1576. *pOutKind = AR_BASIC_BOOL;
  1577. return true;
  1578. }
  1579. bool bFloatResult = 0 != (uEitherFlags & BPROP_FLOATING);
  1580. if (uBothFlags & BPROP_LITERAL) {
  1581. *pOutKind = bFloatResult ? AR_BASIC_LITERAL_FLOAT : AR_BASIC_LITERAL_INT;
  1582. return true;
  1583. }
  1584. // Starting approximation of result properties:
  1585. // - float if either are float, otherwise int (see Notes above)
  1586. // - min/partial precision if both have same flag
  1587. // - if not float, add unsigned if either is unsigned
  1588. UINT uResultFlags =
  1589. (uBothFlags & (BPROP_INTEGER | BPROP_MIN_PRECISION | BPROP_PARTIAL_PRECISION)) |
  1590. (uEitherFlags & BPROP_FLOATING) |
  1591. (!bFloatResult ? (uEitherFlags & BPROP_UNSIGNED) : 0);
  1592. // If one is literal/bool/enum, use min/partial precision from the other
  1593. if (uEitherFlags & (BPROP_LITERAL | BPROP_BOOLEAN | BPROP_ENUM)) {
  1594. uResultFlags |= uEitherFlags & (BPROP_MIN_PRECISION | BPROP_PARTIAL_PRECISION);
  1595. }
  1596. // Now if we have partial precision, we know the result must be half
  1597. if (uResultFlags & BPROP_PARTIAL_PRECISION) {
  1598. *pOutKind = AR_BASIC_FLOAT32_PARTIAL_PRECISION;
  1599. return true;
  1600. }
  1601. // uBits are already initialized to max of either side, so now:
  1602. // if only one is float, get result props from float side
  1603. // min16float + int -> min16float
  1604. // also take min precision from that side
  1605. if (bFloatResult && 0 == (uBothFlags & BPROP_FLOATING)) {
  1606. uResultFlags = (uLeftProps & BPROP_FLOATING) ? uLeftProps : uRightProps;
  1607. uBits = GET_BPROP_BITS(uResultFlags);
  1608. uResultFlags &= ~BPROP_LITERAL;
  1609. }
  1610. bool bMinPrecisionResult = uResultFlags & BPROP_MIN_PRECISION;
  1611. // if uBits is 0 here, upgrade to 32-bits
  1612. // this happens if bool, literal or enum on both sides,
  1613. // or if float came from literal side
  1614. if (uBits == BPROP_BITS0)
  1615. uBits = BPROP_BITS32;
  1616. DXASSERT(uBits != BPROP_BITS0, "CombineBasicTypes: uBits should not be zero at this point");
  1617. DXASSERT(uBits != BPROP_BITS8, "CombineBasicTypes: 8-bit types not supported at this time");
  1618. if (bMinPrecisionResult) {
  1619. DXASSERT(uBits < BPROP_BITS32, "CombineBasicTypes: min-precision result must be less than 32-bits");
  1620. } else {
  1621. DXASSERT(uBits > BPROP_BITS12, "CombineBasicTypes: 10 or 12 bit result must be min precision");
  1622. }
  1623. if (bFloatResult) {
  1624. DXASSERT(uBits != BPROP_BITS12, "CombineBasicTypes: 12-bit result must be int");
  1625. } else {
  1626. DXASSERT(uBits != BPROP_BITS10, "CombineBasicTypes: 10-bit result must be float");
  1627. }
  1628. if (uBits == BPROP_BITS12) {
  1629. DXASSERT(!(uResultFlags & BPROP_UNSIGNED), "CombineBasicTypes: 12-bit result must not be unsigned");
  1630. }
  1631. if (bFloatResult) {
  1632. switch (uBits) {
  1633. case BPROP_BITS10:
  1634. *pOutKind = AR_BASIC_MIN10FLOAT;
  1635. break;
  1636. case BPROP_BITS16:
  1637. *pOutKind = bMinPrecisionResult ? AR_BASIC_MIN16FLOAT : AR_BASIC_FLOAT16;
  1638. break;
  1639. case BPROP_BITS32:
  1640. *pOutKind = AR_BASIC_FLOAT32;
  1641. break;
  1642. case BPROP_BITS64:
  1643. *pOutKind = AR_BASIC_FLOAT64;
  1644. break;
  1645. default:
  1646. DXASSERT(false, "Unexpected bit count for float result");
  1647. break;
  1648. }
  1649. } else {
  1650. // int or unsigned int
  1651. switch (uBits) {
  1652. case BPROP_BITS12:
  1653. *pOutKind = AR_BASIC_MIN12INT;
  1654. break;
  1655. case BPROP_BITS16:
  1656. if (uResultFlags & BPROP_UNSIGNED)
  1657. *pOutKind = bMinPrecisionResult ? AR_BASIC_MIN16UINT : AR_BASIC_UINT16;
  1658. else
  1659. *pOutKind = bMinPrecisionResult ? AR_BASIC_MIN16INT : AR_BASIC_INT16;
  1660. break;
  1661. case BPROP_BITS32:
  1662. *pOutKind = (uResultFlags & BPROP_UNSIGNED) ? AR_BASIC_UINT32 : AR_BASIC_INT32;
  1663. break;
  1664. case BPROP_BITS64:
  1665. *pOutKind = (uResultFlags & BPROP_UNSIGNED) ? AR_BASIC_UINT64 : AR_BASIC_INT64;
  1666. break;
  1667. default:
  1668. DXASSERT(false, "Unexpected bit count for int result");
  1669. break;
  1670. }
  1671. }
  1672. return true;
  1673. }
  1674. class UsedIntrinsicStore : public std::set<UsedIntrinsic>
  1675. {
  1676. };
  1677. static
  1678. void GetIntrinsicMethods(ArBasicKind kind, _Outptr_result_buffer_(*intrinsicCount) const HLSL_INTRINSIC** intrinsics, _Out_ size_t* intrinsicCount)
  1679. {
  1680. DXASSERT_NOMSG(intrinsics != nullptr);
  1681. DXASSERT_NOMSG(intrinsicCount != nullptr);
  1682. switch (kind)
  1683. {
  1684. case AR_OBJECT_TRIANGLESTREAM:
  1685. case AR_OBJECT_POINTSTREAM:
  1686. case AR_OBJECT_LINESTREAM:
  1687. *intrinsics = g_StreamMethods;
  1688. *intrinsicCount = _countof(g_StreamMethods);
  1689. break;
  1690. case AR_OBJECT_TEXTURE1D:
  1691. *intrinsics = g_Texture1DMethods;
  1692. *intrinsicCount = _countof(g_Texture1DMethods);
  1693. break;
  1694. case AR_OBJECT_TEXTURE1D_ARRAY:
  1695. *intrinsics = g_Texture1DArrayMethods;
  1696. *intrinsicCount = _countof(g_Texture1DArrayMethods);
  1697. break;
  1698. case AR_OBJECT_TEXTURE2D:
  1699. *intrinsics = g_Texture2DMethods;
  1700. *intrinsicCount = _countof(g_Texture2DMethods);
  1701. break;
  1702. case AR_OBJECT_TEXTURE2DMS:
  1703. *intrinsics = g_Texture2DMSMethods;
  1704. *intrinsicCount = _countof(g_Texture2DMSMethods);
  1705. break;
  1706. case AR_OBJECT_TEXTURE2D_ARRAY:
  1707. *intrinsics = g_Texture2DArrayMethods;
  1708. *intrinsicCount = _countof(g_Texture2DArrayMethods);
  1709. break;
  1710. case AR_OBJECT_TEXTURE2DMS_ARRAY:
  1711. *intrinsics = g_Texture2DArrayMSMethods;
  1712. *intrinsicCount = _countof(g_Texture2DArrayMSMethods);
  1713. break;
  1714. case AR_OBJECT_TEXTURE3D:
  1715. *intrinsics = g_Texture3DMethods;
  1716. *intrinsicCount = _countof(g_Texture3DMethods);
  1717. break;
  1718. case AR_OBJECT_TEXTURECUBE:
  1719. *intrinsics = g_TextureCUBEMethods;
  1720. *intrinsicCount = _countof(g_TextureCUBEMethods);
  1721. break;
  1722. case AR_OBJECT_TEXTURECUBE_ARRAY:
  1723. *intrinsics = g_TextureCUBEArrayMethods;
  1724. *intrinsicCount = _countof(g_TextureCUBEArrayMethods);
  1725. break;
  1726. case AR_OBJECT_BUFFER:
  1727. *intrinsics = g_BufferMethods;
  1728. *intrinsicCount = _countof(g_BufferMethods);
  1729. break;
  1730. case AR_OBJECT_RWTEXTURE1D:
  1731. case AR_OBJECT_ROVTEXTURE1D:
  1732. *intrinsics = g_RWTexture1DMethods;
  1733. *intrinsicCount = _countof(g_RWTexture1DMethods);
  1734. break;
  1735. case AR_OBJECT_RWTEXTURE1D_ARRAY:
  1736. case AR_OBJECT_ROVTEXTURE1D_ARRAY:
  1737. *intrinsics = g_RWTexture1DArrayMethods;
  1738. *intrinsicCount = _countof(g_RWTexture1DArrayMethods);
  1739. break;
  1740. case AR_OBJECT_RWTEXTURE2D:
  1741. case AR_OBJECT_ROVTEXTURE2D:
  1742. *intrinsics = g_RWTexture2DMethods;
  1743. *intrinsicCount = _countof(g_RWTexture2DMethods);
  1744. break;
  1745. case AR_OBJECT_RWTEXTURE2D_ARRAY:
  1746. case AR_OBJECT_ROVTEXTURE2D_ARRAY:
  1747. *intrinsics = g_RWTexture2DArrayMethods;
  1748. *intrinsicCount = _countof(g_RWTexture2DArrayMethods);
  1749. break;
  1750. case AR_OBJECT_RWTEXTURE3D:
  1751. case AR_OBJECT_ROVTEXTURE3D:
  1752. *intrinsics = g_RWTexture3DMethods;
  1753. *intrinsicCount = _countof(g_RWTexture3DMethods);
  1754. break;
  1755. case AR_OBJECT_RWBUFFER:
  1756. case AR_OBJECT_ROVBUFFER:
  1757. *intrinsics = g_RWBufferMethods;
  1758. *intrinsicCount = _countof(g_RWBufferMethods);
  1759. break;
  1760. case AR_OBJECT_BYTEADDRESS_BUFFER:
  1761. *intrinsics = g_ByteAddressBufferMethods;
  1762. *intrinsicCount = _countof(g_ByteAddressBufferMethods);
  1763. break;
  1764. case AR_OBJECT_RWBYTEADDRESS_BUFFER:
  1765. case AR_OBJECT_ROVBYTEADDRESS_BUFFER:
  1766. *intrinsics = g_RWByteAddressBufferMethods;
  1767. *intrinsicCount = _countof(g_RWByteAddressBufferMethods);
  1768. break;
  1769. case AR_OBJECT_STRUCTURED_BUFFER:
  1770. *intrinsics = g_StructuredBufferMethods;
  1771. *intrinsicCount = _countof(g_StructuredBufferMethods);
  1772. break;
  1773. case AR_OBJECT_RWSTRUCTURED_BUFFER:
  1774. case AR_OBJECT_ROVSTRUCTURED_BUFFER:
  1775. *intrinsics = g_RWStructuredBufferMethods;
  1776. *intrinsicCount = _countof(g_RWStructuredBufferMethods);
  1777. break;
  1778. case AR_OBJECT_APPEND_STRUCTURED_BUFFER:
  1779. *intrinsics = g_AppendStructuredBufferMethods;
  1780. *intrinsicCount = _countof(g_AppendStructuredBufferMethods);
  1781. break;
  1782. case AR_OBJECT_CONSUME_STRUCTURED_BUFFER:
  1783. *intrinsics = g_ConsumeStructuredBufferMethods;
  1784. *intrinsicCount = _countof(g_ConsumeStructuredBufferMethods);
  1785. break;
  1786. // SPIRV change starts
  1787. #ifdef ENABLE_SPIRV_CODEGEN
  1788. case AR_OBJECT_VK_SUBPASS_INPUT:
  1789. *intrinsics = g_VkSubpassInputMethods;
  1790. *intrinsicCount = _countof(g_VkSubpassInputMethods);
  1791. break;
  1792. case AR_OBJECT_VK_SUBPASS_INPUT_MS:
  1793. *intrinsics = g_VkSubpassInputMSMethods;
  1794. *intrinsicCount = _countof(g_VkSubpassInputMSMethods);
  1795. break;
  1796. #endif // ENABLE_SPIRV_CODEGEN
  1797. // SPIRV change ends
  1798. default:
  1799. *intrinsics = nullptr;
  1800. *intrinsicCount = 0;
  1801. break;
  1802. }
  1803. }
  1804. static
  1805. bool IsRowOrColumnVariable(size_t value)
  1806. {
  1807. return IA_SPECIAL_BASE <= value && value <= (IA_SPECIAL_BASE + IA_SPECIAL_SLOTS - 1);
  1808. }
  1809. static
  1810. bool DoesComponentTypeAcceptMultipleTypes(LEGAL_INTRINSIC_COMPTYPES value)
  1811. {
  1812. return
  1813. value == LICOMPTYPE_ANY_INT || // signed or unsigned ints
  1814. value == LICOMPTYPE_ANY_INT32 || // signed or unsigned ints
  1815. value == LICOMPTYPE_ANY_FLOAT || // float or double
  1816. value == LICOMPTYPE_FLOAT_LIKE || // float or min16
  1817. value == LICOMPTYPE_FLOAT_DOUBLE || // float or double
  1818. value == LICOMPTYPE_NUMERIC || // all sorts of numbers
  1819. value == LICOMPTYPE_NUMERIC32 || // all sorts of numbers
  1820. value == LICOMPTYPE_NUMERIC32_ONLY || // all sorts of numbers
  1821. value == LICOMPTYPE_ANY; // any time
  1822. }
  1823. static
  1824. bool DoesComponentTypeAcceptMultipleTypes(BYTE value)
  1825. {
  1826. return DoesComponentTypeAcceptMultipleTypes(static_cast<LEGAL_INTRINSIC_COMPTYPES>(value));
  1827. }
  1828. static
  1829. bool DoesLegalTemplateAcceptMultipleTypes(LEGAL_INTRINSIC_TEMPLATES value)
  1830. {
  1831. // Note that LITEMPLATE_OBJECT can accept different types, but it
  1832. // specifies a single 'layout'. In practice, this information is used
  1833. // together with a component type that specifies a single object.
  1834. return value == LITEMPLATE_ANY; // Any layout
  1835. }
  1836. static
  1837. bool DoesLegalTemplateAcceptMultipleTypes(BYTE value)
  1838. {
  1839. return DoesLegalTemplateAcceptMultipleTypes(static_cast<LEGAL_INTRINSIC_TEMPLATES>(value));
  1840. }
  1841. static
  1842. bool TemplateHasDefaultType(ArBasicKind kind)
  1843. {
  1844. switch (kind) {
  1845. case AR_OBJECT_BUFFER:
  1846. case AR_OBJECT_TEXTURE1D:
  1847. case AR_OBJECT_TEXTURE2D:
  1848. case AR_OBJECT_TEXTURE3D:
  1849. case AR_OBJECT_TEXTURE1D_ARRAY:
  1850. case AR_OBJECT_TEXTURE2D_ARRAY:
  1851. case AR_OBJECT_TEXTURECUBE:
  1852. case AR_OBJECT_TEXTURECUBE_ARRAY:
  1853. // SPIRV change starts
  1854. #ifdef ENABLE_SPIRV_CODEGEN
  1855. case AR_OBJECT_VK_SUBPASS_INPUT:
  1856. case AR_OBJECT_VK_SUBPASS_INPUT_MS:
  1857. #endif // ENABLE_SPIRV_CODEGEN
  1858. // SPIRV change ends
  1859. return true;
  1860. default:
  1861. // Objects with default types return true. Everything else is false.
  1862. return false;
  1863. }
  1864. }
  1865. /// <summary>
  1866. /// Use this class to iterate over intrinsic definitions that come from an external source.
  1867. /// </summary>
  1868. class IntrinsicTableDefIter
  1869. {
  1870. private:
  1871. StringRef _typeName;
  1872. StringRef _functionName;
  1873. llvm::SmallVector<CComPtr<IDxcIntrinsicTable>, 2>& _tables;
  1874. const HLSL_INTRINSIC* _tableIntrinsic;
  1875. UINT64 _tableLookupCookie;
  1876. unsigned _tableIndex;
  1877. unsigned _argCount;
  1878. bool _firstChecked;
  1879. IntrinsicTableDefIter(
  1880. llvm::SmallVector<CComPtr<IDxcIntrinsicTable>, 2>& tables,
  1881. StringRef typeName,
  1882. StringRef functionName,
  1883. unsigned argCount) :
  1884. _typeName(typeName), _functionName(functionName), _tables(tables),
  1885. _tableIntrinsic(nullptr), _tableLookupCookie(0), _tableIndex(0),
  1886. _argCount(argCount), _firstChecked(false)
  1887. {
  1888. }
  1889. void CheckForIntrinsic() {
  1890. if (_tableIndex >= _tables.size()) {
  1891. return;
  1892. }
  1893. _firstChecked = true;
  1894. // TODO: review this - this will allocate at least once per string
  1895. CA2WEX<> typeName(_typeName.str().c_str(), CP_UTF8);
  1896. CA2WEX<> functionName(_functionName.str().c_str(), CP_UTF8);
  1897. if (FAILED(_tables[_tableIndex]->LookupIntrinsic(
  1898. typeName, functionName, &_tableIntrinsic, &_tableLookupCookie))) {
  1899. _tableLookupCookie = 0;
  1900. _tableIntrinsic = nullptr;
  1901. }
  1902. }
  1903. void MoveToNext() {
  1904. for (;;) {
  1905. // If we don't have an intrinsic, try the following table.
  1906. if (_firstChecked && _tableIntrinsic == nullptr) {
  1907. _tableIndex++;
  1908. }
  1909. CheckForIntrinsic();
  1910. if (_tableIndex == _tables.size() ||
  1911. (_tableIntrinsic != nullptr &&
  1912. _tableIntrinsic->uNumArgs ==
  1913. (_argCount + 1))) // uNumArgs includes return
  1914. break;
  1915. }
  1916. }
  1917. public:
  1918. static IntrinsicTableDefIter CreateStart(llvm::SmallVector<CComPtr<IDxcIntrinsicTable>, 2>& tables,
  1919. StringRef typeName,
  1920. StringRef functionName,
  1921. unsigned argCount)
  1922. {
  1923. IntrinsicTableDefIter result(tables, typeName, functionName, argCount);
  1924. return result;
  1925. }
  1926. static IntrinsicTableDefIter CreateEnd(llvm::SmallVector<CComPtr<IDxcIntrinsicTable>, 2>& tables)
  1927. {
  1928. IntrinsicTableDefIter result(tables, StringRef(), StringRef(), 0);
  1929. result._tableIndex = tables.size();
  1930. return result;
  1931. }
  1932. bool operator!=(const IntrinsicTableDefIter& other)
  1933. {
  1934. if (!_firstChecked) {
  1935. MoveToNext();
  1936. }
  1937. return _tableIndex != other._tableIndex; // More things could be compared but we only match end.
  1938. }
  1939. const HLSL_INTRINSIC* operator*()
  1940. {
  1941. DXASSERT(_firstChecked, "otherwise deref without comparing to end");
  1942. return _tableIntrinsic;
  1943. }
  1944. LPCSTR GetTableName()
  1945. {
  1946. LPCSTR tableName = nullptr;
  1947. if (FAILED(_tables[_tableIndex]->GetTableName(&tableName))) {
  1948. return nullptr;
  1949. }
  1950. return tableName;
  1951. }
  1952. LPCSTR GetLoweringStrategy()
  1953. {
  1954. LPCSTR lowering = nullptr;
  1955. if (FAILED(_tables[_tableIndex]->GetLoweringStrategy(_tableIntrinsic->Op, &lowering))) {
  1956. return nullptr;
  1957. }
  1958. return lowering;
  1959. }
  1960. IntrinsicTableDefIter& operator++()
  1961. {
  1962. MoveToNext();
  1963. return *this;
  1964. }
  1965. };
  1966. /// <summary>
  1967. /// Use this class to iterate over intrinsic definitions that have the same name and parameter count.
  1968. /// </summary>
  1969. class IntrinsicDefIter
  1970. {
  1971. const HLSL_INTRINSIC* _current;
  1972. const HLSL_INTRINSIC* _end;
  1973. IntrinsicTableDefIter _tableIter;
  1974. IntrinsicDefIter(const HLSL_INTRINSIC* value, const HLSL_INTRINSIC* end, IntrinsicTableDefIter tableIter) :
  1975. _current(value), _end(end), _tableIter(tableIter)
  1976. { }
  1977. public:
  1978. static IntrinsicDefIter CreateStart(const HLSL_INTRINSIC* table, size_t count, const HLSL_INTRINSIC* start, IntrinsicTableDefIter tableIter)
  1979. {
  1980. return IntrinsicDefIter(start, table + count, tableIter);
  1981. }
  1982. static IntrinsicDefIter CreateEnd(const HLSL_INTRINSIC* table, size_t count, IntrinsicTableDefIter tableIter)
  1983. {
  1984. return IntrinsicDefIter(table + count, table + count, tableIter);
  1985. }
  1986. bool operator!=(const IntrinsicDefIter& other)
  1987. {
  1988. return _current != other._current || _tableIter.operator!=(other._tableIter);
  1989. }
  1990. const HLSL_INTRINSIC* operator*()
  1991. {
  1992. return (_current != _end) ? _current : *_tableIter;
  1993. }
  1994. LPCSTR GetTableName()
  1995. {
  1996. return (_current != _end) ? kBuiltinIntrinsicTableName : _tableIter.GetTableName();
  1997. }
  1998. LPCSTR GetLoweringStrategy()
  1999. {
  2000. return (_current != _end) ? "" : _tableIter.GetLoweringStrategy();
  2001. }
  2002. IntrinsicDefIter& operator++()
  2003. {
  2004. if (_current != _end) {
  2005. const HLSL_INTRINSIC* next = _current + 1;
  2006. if (next != _end && _current->uNumArgs == next->uNumArgs && 0 == strcmp(_current->pArgs[0].pName, next->pArgs[0].pName)) {
  2007. _current = next;
  2008. }
  2009. else {
  2010. _current = _end;
  2011. }
  2012. } else {
  2013. ++_tableIter;
  2014. }
  2015. return *this;
  2016. }
  2017. };
  2018. static void AddHLSLSubscriptAttr(Decl *D, ASTContext &context, HLSubscriptOpcode opcode) {
  2019. StringRef group = GetHLOpcodeGroupName(HLOpcodeGroup::HLSubscript);
  2020. D->addAttr(HLSLIntrinsicAttr::CreateImplicit(context, group, "", static_cast<unsigned>(opcode)));
  2021. }
  2022. static void CreateSimpleField(clang::ASTContext &context,
  2023. CXXRecordDecl *recordDecl, StringRef Name,
  2024. QualType Ty) {
  2025. IdentifierInfo &fieldId =
  2026. context.Idents.get(Name, tok::TokenKind::identifier);
  2027. TypeSourceInfo *filedTypeSource = context.getTrivialTypeSourceInfo(Ty, NoLoc);
  2028. const bool MutableFalse = false;
  2029. const InClassInitStyle initStyle = InClassInitStyle::ICIS_NoInit;
  2030. FieldDecl *fieldDecl =
  2031. FieldDecl::Create(context, recordDecl, NoLoc, NoLoc, &fieldId, Ty,
  2032. filedTypeSource, nullptr, MutableFalse, initStyle);
  2033. fieldDecl->setAccess(AccessSpecifier::AS_public);
  2034. fieldDecl->setImplicit(true);
  2035. recordDecl->addDecl(fieldDecl);
  2036. }
  2037. // struct RayDesc
  2038. //{
  2039. // float3 Origin;
  2040. // float TMin;
  2041. // float3 Direction;
  2042. // float TMax;
  2043. //};
  2044. static CXXRecordDecl *CreateRayDescStruct(clang::ASTContext &context,
  2045. QualType float3Ty) {
  2046. DeclContext *currentDeclContext = context.getTranslationUnitDecl();
  2047. IdentifierInfo &rayDesc =
  2048. context.Idents.get(StringRef("RayDesc"), tok::TokenKind::identifier);
  2049. CXXRecordDecl *rayDescDecl = CXXRecordDecl::Create(
  2050. context, TagTypeKind::TTK_Struct, currentDeclContext, NoLoc, NoLoc,
  2051. &rayDesc, nullptr, DelayTypeCreationTrue);
  2052. rayDescDecl->startDefinition();
  2053. QualType floatTy = context.FloatTy;
  2054. // float3 Origin;
  2055. CreateSimpleField(context, rayDescDecl, "Origin", float3Ty);
  2056. // float TMin;
  2057. CreateSimpleField(context, rayDescDecl, "TMin", floatTy);
  2058. // float3 Direction;
  2059. CreateSimpleField(context, rayDescDecl, "Direction", float3Ty);
  2060. // float TMax;
  2061. CreateSimpleField(context, rayDescDecl, "TMax", floatTy);
  2062. rayDescDecl->completeDefinition();
  2063. // Both declarations need to be present for correct handling.
  2064. currentDeclContext->addDecl(rayDescDecl);
  2065. rayDescDecl->setImplicit(true);
  2066. return rayDescDecl;
  2067. }
  2068. // struct BuiltInTriangleIntersectionAttributes
  2069. // {
  2070. // float2 barycentrics;
  2071. // };
  2072. static CXXRecordDecl *AddBuiltInTriangleIntersectionAttributes(ASTContext& context, QualType baryType) {
  2073. DeclContext *curDC = context.getTranslationUnitDecl();
  2074. IdentifierInfo &attributesId =
  2075. context.Idents.get(StringRef("BuiltInTriangleIntersectionAttributes"),
  2076. tok::TokenKind::identifier);
  2077. CXXRecordDecl *attributesDecl = CXXRecordDecl::Create(
  2078. context, TagTypeKind::TTK_Struct, curDC, NoLoc, NoLoc,
  2079. &attributesId, nullptr, DelayTypeCreationTrue);
  2080. attributesDecl->startDefinition();
  2081. // float2 barycentrics;
  2082. CreateSimpleField(context, attributesDecl, "barycentrics", baryType);
  2083. attributesDecl->completeDefinition();
  2084. attributesDecl->setImplicit(true);
  2085. curDC->addDecl(attributesDecl);
  2086. return attributesDecl;
  2087. }
  2088. //
  2089. // This is similar to clang/Analysis/CallGraph, but the following differences
  2090. // motivate this:
  2091. //
  2092. // - track traversed vs. observed nodes explicitly
  2093. // - fully visit all reachable functions
  2094. // - merge graph visiting with checking for recursion
  2095. // - track global variables and types used (NYI)
  2096. //
  2097. namespace hlsl {
  2098. struct CallNode {
  2099. FunctionDecl *CallerFn;
  2100. ::llvm::SmallPtrSet<FunctionDecl *, 4> CalleeFns;
  2101. };
  2102. typedef ::llvm::DenseMap<FunctionDecl*, CallNode> CallNodes;
  2103. typedef ::llvm::SmallPtrSet<Decl *, 8> FnCallStack;
  2104. typedef ::llvm::SmallPtrSet<FunctionDecl*, 128> FunctionSet;
  2105. typedef ::llvm::SmallVector<FunctionDecl*, 32> PendingFunctions;
  2106. // Returns the definition of a function.
  2107. // This serves two purposes - ignore built-in functions, and pick
  2108. // a single Decl * to be used in maps and sets.
  2109. static FunctionDecl *getFunctionWithBody(FunctionDecl *F) {
  2110. if (!F) return nullptr;
  2111. if (F->doesThisDeclarationHaveABody()) return F;
  2112. F = F->getFirstDecl();
  2113. for (auto &&Candidate : F->redecls()) {
  2114. if (Candidate->doesThisDeclarationHaveABody()) {
  2115. return Candidate;
  2116. }
  2117. }
  2118. return nullptr;
  2119. }
  2120. // AST visitor that maintains visited and pending collections, as well
  2121. // as recording nodes of caller/callees.
  2122. class FnReferenceVisitor : public RecursiveASTVisitor<FnReferenceVisitor> {
  2123. private:
  2124. CallNodes &m_callNodes;
  2125. FunctionSet &m_visitedFunctions;
  2126. PendingFunctions &m_pendingFunctions;
  2127. FunctionDecl *m_source;
  2128. CallNodes::iterator m_sourceIt;
  2129. public:
  2130. FnReferenceVisitor(FunctionSet &visitedFunctions,
  2131. PendingFunctions &pendingFunctions, CallNodes &callNodes)
  2132. : m_callNodes(callNodes),
  2133. m_visitedFunctions(visitedFunctions),
  2134. m_pendingFunctions(pendingFunctions) {}
  2135. void setSourceFn(FunctionDecl *F) {
  2136. F = getFunctionWithBody(F);
  2137. m_source = F;
  2138. m_sourceIt = m_callNodes.find(F);
  2139. }
  2140. bool VisitDeclRefExpr(DeclRefExpr *ref) {
  2141. ValueDecl *valueDecl = ref->getDecl();
  2142. FunctionDecl *fnDecl = dyn_cast_or_null<FunctionDecl>(valueDecl);
  2143. fnDecl = getFunctionWithBody(fnDecl);
  2144. if (fnDecl) {
  2145. if (m_sourceIt == m_callNodes.end()) {
  2146. auto result = m_callNodes.insert(
  2147. std::pair<FunctionDecl *, CallNode>(m_source, CallNode{ m_source }));
  2148. DXASSERT(result.second == true,
  2149. "else setSourceFn didn't assign m_sourceIt");
  2150. m_sourceIt = result.first;
  2151. }
  2152. m_sourceIt->second.CalleeFns.insert(fnDecl);
  2153. if (!m_visitedFunctions.count(fnDecl)) {
  2154. m_pendingFunctions.push_back(fnDecl);
  2155. }
  2156. }
  2157. return true;
  2158. }
  2159. };
  2160. // A call graph that can check for reachability and recursion efficiently.
  2161. class CallGraphWithRecurseGuard {
  2162. private:
  2163. CallNodes m_callNodes;
  2164. FunctionSet m_visitedFunctions;
  2165. FunctionDecl *CheckRecursion(FnCallStack &CallStack,
  2166. FunctionDecl *D) const {
  2167. if (CallStack.insert(D).second == false)
  2168. return D;
  2169. auto node = m_callNodes.find(D);
  2170. if (node != m_callNodes.end()) {
  2171. for (FunctionDecl *Callee : node->second.CalleeFns) {
  2172. FunctionDecl *pResult = CheckRecursion(CallStack, Callee);
  2173. if (pResult)
  2174. return pResult;
  2175. }
  2176. }
  2177. CallStack.erase(D);
  2178. return nullptr;
  2179. }
  2180. public:
  2181. void BuildForEntry(FunctionDecl *EntryFnDecl) {
  2182. DXASSERT_NOMSG(EntryFnDecl);
  2183. EntryFnDecl = getFunctionWithBody(EntryFnDecl);
  2184. PendingFunctions pendingFunctions;
  2185. FnReferenceVisitor visitor(m_visitedFunctions, pendingFunctions, m_callNodes);
  2186. pendingFunctions.push_back(EntryFnDecl);
  2187. while (!pendingFunctions.empty()) {
  2188. FunctionDecl *pendingDecl = pendingFunctions.pop_back_val();
  2189. if (m_visitedFunctions.insert(pendingDecl).second == true) {
  2190. visitor.setSourceFn(pendingDecl);
  2191. visitor.TraverseDecl(pendingDecl);
  2192. }
  2193. }
  2194. }
  2195. FunctionDecl *CheckRecursion(FunctionDecl *EntryFnDecl) const {
  2196. FnCallStack CallStack;
  2197. EntryFnDecl = getFunctionWithBody(EntryFnDecl);
  2198. return CheckRecursion(CallStack, EntryFnDecl);
  2199. }
  2200. void dump() const {
  2201. OutputDebugStringW(L"Call Nodes:\r\n");
  2202. for (auto &node : m_callNodes) {
  2203. OutputDebugFormatA("%s [%p]:\r\n", node.first->getName().str().c_str(), (void*)node.first);
  2204. for (auto callee : node.second.CalleeFns) {
  2205. OutputDebugFormatA(" %s [%p]\r\n", callee->getName().str().c_str(), (void*)callee);
  2206. }
  2207. }
  2208. }
  2209. };
  2210. }
  2211. /// <summary>Creates a Typedef in the specified ASTContext.</summary>
  2212. static
  2213. TypedefDecl *CreateGlobalTypedef(ASTContext* context, const char* ident, QualType baseType)
  2214. {
  2215. DXASSERT_NOMSG(context != nullptr);
  2216. DXASSERT_NOMSG(ident != nullptr);
  2217. DXASSERT_NOMSG(!baseType.isNull());
  2218. DeclContext* declContext = context->getTranslationUnitDecl();
  2219. TypeSourceInfo* typeSource = context->getTrivialTypeSourceInfo(baseType);
  2220. TypedefDecl* decl = TypedefDecl::Create(*context, declContext, NoLoc, NoLoc, &context->Idents.get(ident), typeSource);
  2221. declContext->addDecl(decl);
  2222. decl->setImplicit(true);
  2223. return decl;
  2224. }
  2225. class HLSLExternalSource : public ExternalSemaSource {
  2226. private:
  2227. // Inner types.
  2228. struct FindStructBasicTypeResult {
  2229. ArBasicKind Kind; // Kind of struct (eg, AR_OBJECT_TEXTURE2D)
  2230. unsigned int BasicKindsAsTypeIndex; // Index into g_ArBasicKinds*
  2231. FindStructBasicTypeResult(ArBasicKind kind,
  2232. unsigned int basicKindAsTypeIndex)
  2233. : Kind(kind), BasicKindsAsTypeIndex(basicKindAsTypeIndex) {}
  2234. bool Found() const { return Kind != AR_BASIC_UNKNOWN; }
  2235. };
  2236. // Declaration for matrix and vector templates.
  2237. ClassTemplateDecl* m_matrixTemplateDecl;
  2238. ClassTemplateDecl* m_vectorTemplateDecl;
  2239. // Namespace decl for hlsl intrin functions
  2240. NamespaceDecl* m_hlslNSDecl;
  2241. // Context being processed.
  2242. _Notnull_ ASTContext* m_context;
  2243. // Semantic analyzer being processed.
  2244. Sema* m_sema;
  2245. // Intrinsic tables available externally.
  2246. llvm::SmallVector<CComPtr<IDxcIntrinsicTable>, 2> m_intrinsicTables;
  2247. // Scalar types indexed by HLSLScalarType.
  2248. QualType m_scalarTypes[HLSLScalarTypeCount];
  2249. // Scalar types already built.
  2250. TypedefDecl* m_scalarTypeDefs[HLSLScalarTypeCount];
  2251. // 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.
  2252. QualType m_matrixTypes[HLSLScalarTypeCount][4][4];
  2253. // Matrix types already built, in shorthand form.
  2254. TypedefDecl* m_matrixShorthandTypes[HLSLScalarTypeCount][4][4];
  2255. // Vector types already built.
  2256. QualType m_vectorTypes[HLSLScalarTypeCount][4];
  2257. TypedefDecl* m_vectorTypedefs[HLSLScalarTypeCount][4];
  2258. // BuiltinType for each scalar type.
  2259. QualType m_baseTypes[HLSLScalarTypeCount];
  2260. // Built-in object types declarations, indexed by basic kind constant.
  2261. CXXRecordDecl* m_objectTypeDecls[_countof(g_ArBasicKindsAsTypes)];
  2262. // Map from object decl to the object index.
  2263. using ObjectTypeDeclMapType = std::array<std::pair<CXXRecordDecl*,unsigned>, _countof(g_ArBasicKindsAsTypes)+_countof(g_DeprecatedEffectObjectNames)>;
  2264. ObjectTypeDeclMapType m_objectTypeDeclsMap;
  2265. // Mask for object which not has methods created.
  2266. uint64_t m_objectTypeLazyInitMask;
  2267. UsedIntrinsicStore m_usedIntrinsics;
  2268. /// <summary>Add all base QualTypes for each hlsl scalar types.</summary>
  2269. void AddBaseTypes();
  2270. /// <summary>Adds all supporting declarations to reference scalar types.</summary>
  2271. void AddHLSLScalarTypes();
  2272. QualType GetTemplateObjectDataType(_In_ CXXRecordDecl* recordDecl)
  2273. {
  2274. DXASSERT_NOMSG(recordDecl != nullptr);
  2275. TemplateParameterList* parameterList = recordDecl->getTemplateParameterList(0);
  2276. NamedDecl* parameterDecl = parameterList->getParam(0);
  2277. DXASSERT(parameterDecl->getKind() == Decl::Kind::TemplateTypeParm, "otherwise recordDecl isn't one of the built-in objects with templates");
  2278. TemplateTypeParmDecl* parmDecl = dyn_cast<TemplateTypeParmDecl>(parameterDecl);
  2279. return QualType(parmDecl->getTypeForDecl(), 0);
  2280. }
  2281. // Determines whether the given intrinsic parameter type has a single QualType mapping.
  2282. QualType GetSingleQualTypeForMapping(const HLSL_INTRINSIC* intrinsic, int index)
  2283. {
  2284. int templateRef = intrinsic->pArgs[index].uTemplateId;
  2285. int componentRef = intrinsic->pArgs[index].uComponentTypeId;
  2286. const HLSL_INTRINSIC_ARGUMENT* templateArg = &intrinsic->pArgs[templateRef];
  2287. const HLSL_INTRINSIC_ARGUMENT* componentArg = &intrinsic->pArgs[componentRef];
  2288. const HLSL_INTRINSIC_ARGUMENT* matrixArg = &intrinsic->pArgs[index];
  2289. if (
  2290. templateRef >= 0 &&
  2291. templateArg->uTemplateId == templateRef &&
  2292. !DoesLegalTemplateAcceptMultipleTypes(templateArg->uLegalTemplates) &&
  2293. componentRef >= 0 &&
  2294. componentRef != INTRIN_COMPTYPE_FROM_TYPE_ELT0 &&
  2295. componentArg->uComponentTypeId == 0 &&
  2296. !DoesComponentTypeAcceptMultipleTypes(componentArg->uLegalComponentTypes) &&
  2297. !IsRowOrColumnVariable(matrixArg->uCols) &&
  2298. !IsRowOrColumnVariable(matrixArg->uRows))
  2299. {
  2300. ArTypeObjectKind templateKind = g_LegalIntrinsicTemplates[templateArg->uLegalTemplates][0];
  2301. ArBasicKind elementKind = g_LegalIntrinsicCompTypes[componentArg->uLegalComponentTypes][0];
  2302. return NewSimpleAggregateType(templateKind, elementKind, 0, matrixArg->uRows, matrixArg->uCols);
  2303. }
  2304. return QualType();
  2305. }
  2306. // Adds a new template parameter declaration to the specified array and returns the type for the parameter.
  2307. QualType AddTemplateParamToArray(_In_z_ const char* name, _Inout_ CXXRecordDecl* recordDecl, int templateDepth,
  2308. _Inout_count_c_(g_MaxIntrinsicParamCount + 1) NamedDecl* (&templateParamNamedDecls)[g_MaxIntrinsicParamCount + 1],
  2309. _Inout_ size_t* templateParamNamedDeclsCount)
  2310. {
  2311. DXASSERT_NOMSG(name != nullptr);
  2312. DXASSERT_NOMSG(recordDecl != nullptr);
  2313. DXASSERT_NOMSG(templateParamNamedDecls != nullptr);
  2314. DXASSERT_NOMSG(templateParamNamedDeclsCount != nullptr);
  2315. DXASSERT(*templateParamNamedDeclsCount < _countof(templateParamNamedDecls), "otherwise constants should be updated");
  2316. _Analysis_assume_(*templateParamNamedDeclsCount < _countof(templateParamNamedDecls));
  2317. // Create the declaration for the template parameter.
  2318. IdentifierInfo* id = &m_context->Idents.get(StringRef(name));
  2319. TemplateTypeParmDecl* templateTypeParmDecl =
  2320. TemplateTypeParmDecl::Create(*m_context, recordDecl, NoLoc, NoLoc, templateDepth, *templateParamNamedDeclsCount,
  2321. id, TypenameTrue, ParameterPackFalse);
  2322. templateParamNamedDecls[*templateParamNamedDeclsCount] = templateTypeParmDecl;
  2323. // Create the type that the parameter represents.
  2324. QualType result = m_context->getTemplateTypeParmType(
  2325. templateDepth, *templateParamNamedDeclsCount, ParameterPackFalse, templateTypeParmDecl);
  2326. // Increment the declaration count for the array; as long as caller passes in both arguments,
  2327. // it need not concern itself with maintaining this value.
  2328. (*templateParamNamedDeclsCount)++;
  2329. return result;
  2330. }
  2331. // Adds a function specified by the given intrinsic to a record declaration.
  2332. // The template depth will be zero for records that don't have a "template<>" line
  2333. // even if conceptual; or one if it does have one.
  2334. void AddObjectIntrinsicTemplate(_Inout_ CXXRecordDecl* recordDecl, int templateDepth, _In_ const HLSL_INTRINSIC* intrinsic)
  2335. {
  2336. DXASSERT_NOMSG(recordDecl != nullptr);
  2337. DXASSERT_NOMSG(intrinsic != nullptr);
  2338. DXASSERT(intrinsic->uNumArgs > 0, "otherwise there isn't even an intrinsic name");
  2339. DXASSERT(intrinsic->uNumArgs <= (g_MaxIntrinsicParamCount + 1), "otherwise g_MaxIntrinsicParamCount should be updated");
  2340. // uNumArgs includes the result type, g_MaxIntrinsicParamCount doesn't, thus the +1.
  2341. _Analysis_assume_(intrinsic->uNumArgs <= (g_MaxIntrinsicParamCount + 1));
  2342. // TODO: implement template parameter constraints for HLSL intrinsic methods in declarations
  2343. //
  2344. // Build template parameters, parameter types, and the return type.
  2345. // Parameter declarations are built after the function is created, to use it as their scope.
  2346. //
  2347. unsigned int numParams = intrinsic->uNumArgs - 1;
  2348. NamedDecl* templateParamNamedDecls[g_MaxIntrinsicParamCount + 1];
  2349. size_t templateParamNamedDeclsCount = 0;
  2350. QualType argsQTs[g_MaxIntrinsicParamCount];
  2351. StringRef argNames[g_MaxIntrinsicParamCount];
  2352. QualType functionResultQT;
  2353. DXASSERT(
  2354. _countof(templateParamNamedDecls) >= numParams + 1,
  2355. "need enough templates for all parameters and the return type, otherwise constants need updating");
  2356. // Handle the return type.
  2357. // functionResultQT = GetSingleQualTypeForMapping(intrinsic, 0);
  2358. // if (functionResultQT.isNull()) {
  2359. // Workaround for template parameter argument count mismatch.
  2360. // Create template parameter for return type always
  2361. // TODO: reenable the check and skip template argument.
  2362. functionResultQT = AddTemplateParamToArray(
  2363. "TResult", recordDecl, templateDepth, templateParamNamedDecls,
  2364. &templateParamNamedDeclsCount);
  2365. // }
  2366. SmallVector<hlsl::ParameterModifier, g_MaxIntrinsicParamCount> paramMods;
  2367. InitParamMods(intrinsic, paramMods);
  2368. // Consider adding more cases where return type can be handled a priori. Ultimately #260431 should do significantly better.
  2369. // Handle parameters.
  2370. for (unsigned int i = 1; i < intrinsic->uNumArgs; i++)
  2371. {
  2372. //
  2373. // GetSingleQualTypeForMapping can be used here to remove unnecessary template arguments.
  2374. //
  2375. // However this may produce template instantiations with equivalent template arguments
  2376. // for overloaded methods. It's possible to resolve some of these by generating specializations,
  2377. // but the current intrinsic table has rules that are hard to process in their current form
  2378. // to find all cases.
  2379. //
  2380. char name[g_MaxIntrinsicParamName + 2];
  2381. name[0] = 'T';
  2382. name[1] = '\0';
  2383. strcat_s(name, intrinsic->pArgs[i].pName);
  2384. argsQTs[i - 1] = AddTemplateParamToArray(name, recordDecl, templateDepth, templateParamNamedDecls, &templateParamNamedDeclsCount);
  2385. // Change out/inout param to reference type.
  2386. if (paramMods[i-1].isAnyOut())
  2387. argsQTs[i - 1] = m_context->getLValueReferenceType(argsQTs[i - 1]);
  2388. argNames[i - 1] = StringRef(intrinsic->pArgs[i].pName);
  2389. }
  2390. // Create the declaration.
  2391. IdentifierInfo* ii = &m_context->Idents.get(StringRef(intrinsic->pArgs[0].pName));
  2392. DeclarationName declarationName = DeclarationName(ii);
  2393. CXXMethodDecl* functionDecl = CreateObjectFunctionDeclarationWithParams(*m_context, recordDecl,
  2394. functionResultQT, ArrayRef<QualType>(argsQTs, numParams), ArrayRef<StringRef>(argNames, numParams),
  2395. declarationName, true);
  2396. functionDecl->setImplicit(true);
  2397. // If the function is a template function, create the declaration and cross-reference.
  2398. if (templateParamNamedDeclsCount > 0)
  2399. {
  2400. hlsl::CreateFunctionTemplateDecl(
  2401. *m_context, recordDecl, functionDecl, templateParamNamedDecls, templateParamNamedDeclsCount);
  2402. }
  2403. }
  2404. // Checks whether the two specified intrinsics generate equivalent templates.
  2405. // For example: foo (any_int) and foo (any_float) are only unambiguous in the context
  2406. // of HLSL intrinsic rules, and their difference can't be expressed with C++ templates.
  2407. bool AreIntrinsicTemplatesEquivalent(const HLSL_INTRINSIC* left, const HLSL_INTRINSIC* right)
  2408. {
  2409. if (left == right)
  2410. {
  2411. return true;
  2412. }
  2413. if (left == nullptr || right == nullptr)
  2414. {
  2415. return false;
  2416. }
  2417. return (left->uNumArgs == right->uNumArgs &&
  2418. 0 == strcmp(left->pArgs[0].pName, right->pArgs[0].pName));
  2419. }
  2420. // Adds all the intrinsic methods that correspond to the specified type.
  2421. void AddObjectMethods(ArBasicKind kind, _In_ CXXRecordDecl* recordDecl, int templateDepth)
  2422. {
  2423. DXASSERT_NOMSG(recordDecl != nullptr);
  2424. DXASSERT_NOMSG(templateDepth >= 0);
  2425. const HLSL_INTRINSIC* intrinsics;
  2426. const HLSL_INTRINSIC* prior = nullptr;
  2427. size_t intrinsicCount;
  2428. GetIntrinsicMethods(kind, &intrinsics, &intrinsicCount);
  2429. DXASSERT(
  2430. (intrinsics == nullptr) == (intrinsicCount == 0),
  2431. "intrinsic table pointer must match count (null for zero, something valid otherwise");
  2432. while (intrinsicCount--)
  2433. {
  2434. if (!AreIntrinsicTemplatesEquivalent(intrinsics, prior))
  2435. {
  2436. AddObjectIntrinsicTemplate(recordDecl, templateDepth, intrinsics);
  2437. prior = intrinsics;
  2438. }
  2439. intrinsics++;
  2440. }
  2441. }
  2442. void AddDoubleSubscriptSupport(
  2443. _In_ ClassTemplateDecl* typeDecl,
  2444. _In_ CXXRecordDecl* recordDecl,
  2445. _In_z_ const char* memberName, QualType elementType, TemplateTypeParmDecl* templateTypeParmDecl,
  2446. _In_z_ const char* type0Name,
  2447. _In_z_ const char* type1Name,
  2448. _In_z_ const char* indexer0Name, QualType indexer0Type,
  2449. _In_z_ const char* indexer1Name, QualType indexer1Type)
  2450. {
  2451. DXASSERT_NOMSG(typeDecl != nullptr);
  2452. DXASSERT_NOMSG(recordDecl != nullptr);
  2453. DXASSERT_NOMSG(memberName != nullptr);
  2454. DXASSERT_NOMSG(!elementType.isNull());
  2455. DXASSERT_NOMSG(templateTypeParmDecl != nullptr);
  2456. DXASSERT_NOMSG(type0Name != nullptr);
  2457. DXASSERT_NOMSG(type1Name != nullptr);
  2458. DXASSERT_NOMSG(indexer0Name != nullptr);
  2459. DXASSERT_NOMSG(!indexer0Type.isNull());
  2460. DXASSERT_NOMSG(indexer1Name != nullptr);
  2461. DXASSERT_NOMSG(!indexer1Type.isNull());
  2462. //
  2463. // Add inner types to the templates to represent the following C++ code inside the class.
  2464. // public:
  2465. // class sample_slice_type
  2466. // {
  2467. // public: TElement operator[](uint3 index);
  2468. // };
  2469. // class sample_type
  2470. // {
  2471. // public: sample_slice_type operator[](uint slice);
  2472. // };
  2473. // sample_type sample;
  2474. //
  2475. // Variable names reflect this structure, but this code will also produce the types
  2476. // for .mips access.
  2477. //
  2478. const bool MutableTrue = true;
  2479. DeclarationName subscriptName = m_context->DeclarationNames.getCXXOperatorName(OO_Subscript);
  2480. CXXRecordDecl* sampleSliceTypeDecl = CXXRecordDecl::Create(*m_context, TTK_Class, recordDecl, NoLoc, NoLoc,
  2481. &m_context->Idents.get(StringRef(type1Name)));
  2482. sampleSliceTypeDecl->setAccess(AS_public);
  2483. sampleSliceTypeDecl->setImplicit();
  2484. recordDecl->addDecl(sampleSliceTypeDecl);
  2485. sampleSliceTypeDecl->startDefinition();
  2486. const bool MutableFalse = false;
  2487. FieldDecl* sliceHandleDecl = FieldDecl::Create(*m_context, sampleSliceTypeDecl, NoLoc, NoLoc,
  2488. &m_context->Idents.get(StringRef("handle")), indexer0Type,
  2489. m_context->CreateTypeSourceInfo(indexer0Type), nullptr, MutableFalse, ICIS_NoInit);
  2490. sliceHandleDecl->setAccess(AS_private);
  2491. sampleSliceTypeDecl->addDecl(sliceHandleDecl);
  2492. CXXMethodDecl* sampleSliceSubscriptDecl = CreateObjectFunctionDeclarationWithParams(*m_context,
  2493. sampleSliceTypeDecl, elementType,
  2494. ArrayRef<QualType>(indexer1Type), ArrayRef<StringRef>(StringRef(indexer1Name)), subscriptName, true);
  2495. hlsl::CreateFunctionTemplateDecl(*m_context, sampleSliceTypeDecl, sampleSliceSubscriptDecl,
  2496. reinterpret_cast<NamedDecl**>(&templateTypeParmDecl), 1);
  2497. sampleSliceTypeDecl->completeDefinition();
  2498. CXXRecordDecl* sampleTypeDecl = CXXRecordDecl::Create(*m_context, TTK_Class, recordDecl, NoLoc, NoLoc,
  2499. &m_context->Idents.get(StringRef(type0Name)));
  2500. sampleTypeDecl->setAccess(AS_public);
  2501. recordDecl->addDecl(sampleTypeDecl);
  2502. sampleTypeDecl->startDefinition();
  2503. sampleTypeDecl->setImplicit();
  2504. FieldDecl* sampleHandleDecl = FieldDecl::Create(*m_context, sampleTypeDecl, NoLoc, NoLoc,
  2505. &m_context->Idents.get(StringRef("handle")), indexer0Type,
  2506. m_context->CreateTypeSourceInfo(indexer0Type), nullptr, MutableFalse, ICIS_NoInit);
  2507. sampleHandleDecl->setAccess(AS_private);
  2508. sampleTypeDecl->addDecl(sampleHandleDecl);
  2509. QualType sampleSliceType = m_context->getRecordType(sampleSliceTypeDecl);
  2510. CXXMethodDecl* sampleSubscriptDecl = CreateObjectFunctionDeclarationWithParams(*m_context,
  2511. sampleTypeDecl, m_context->getRValueReferenceType(sampleSliceType), // TODO: choose LValueRef if writable.
  2512. ArrayRef<QualType>(indexer0Type), ArrayRef<StringRef>(StringRef(indexer0Name)), subscriptName, true);
  2513. sampleTypeDecl->completeDefinition();
  2514. // Add subscript attribute
  2515. AddHLSLSubscriptAttr(sampleSubscriptDecl, *m_context, HLSubscriptOpcode::DoubleSubscript);
  2516. QualType sampleTypeQT = m_context->getRecordType(sampleTypeDecl);
  2517. FieldDecl* sampleFieldDecl = FieldDecl::Create(*m_context, recordDecl, NoLoc, NoLoc,
  2518. &m_context->Idents.get(StringRef(memberName)), sampleTypeQT,
  2519. m_context->CreateTypeSourceInfo(sampleTypeQT), nullptr, MutableTrue, ICIS_NoInit);
  2520. sampleFieldDecl->setAccess(AS_public);
  2521. recordDecl->addDecl(sampleFieldDecl);
  2522. }
  2523. void AddObjectSubscripts(ArBasicKind kind, _In_ ClassTemplateDecl *typeDecl,
  2524. _In_ CXXRecordDecl *recordDecl,
  2525. SubscriptOperatorRecord op) {
  2526. DXASSERT_NOMSG(typeDecl != nullptr);
  2527. DXASSERT_NOMSG(recordDecl != nullptr);
  2528. DXASSERT_NOMSG(0 <= op.SubscriptCardinality &&
  2529. op.SubscriptCardinality <= 3);
  2530. DXASSERT(op.SubscriptCardinality > 0 ||
  2531. (op.HasMips == false && op.HasSample == false),
  2532. "objects that have .mips or .sample member also have a plain "
  2533. "subscript defined (otherwise static table is "
  2534. "likely incorrect, and this function won't know the cardinality "
  2535. "of the position parameter");
  2536. bool isReadWrite = GetBasicKindProps(kind) & BPROP_RWBUFFER;
  2537. DXASSERT(!isReadWrite || (op.HasMips == false && op.HasSample == false),
  2538. "read/write objects don't have .mips or .sample members");
  2539. // Return early if there is no work to be done.
  2540. if (op.SubscriptCardinality == 0) {
  2541. return;
  2542. }
  2543. const unsigned int templateDepth = 1;
  2544. // Add an operator[].
  2545. TemplateTypeParmDecl *templateTypeParmDecl = cast<TemplateTypeParmDecl>(
  2546. typeDecl->getTemplateParameters()->getParam(0));
  2547. QualType resultType = m_context->getTemplateTypeParmType(
  2548. templateDepth, 0, ParameterPackFalse, templateTypeParmDecl);
  2549. if (isReadWrite)
  2550. resultType = m_context->getLValueReferenceType(resultType, false);
  2551. else
  2552. resultType = m_context->getRValueReferenceType(resultType);
  2553. QualType indexType =
  2554. op.SubscriptCardinality == 1
  2555. ? m_context->UnsignedIntTy
  2556. : NewSimpleAggregateType(AR_TOBJ_VECTOR, AR_BASIC_UINT32, 0, 1,
  2557. op.SubscriptCardinality);
  2558. CXXMethodDecl *functionDecl = CreateObjectFunctionDeclarationWithParams(
  2559. *m_context, recordDecl, resultType, ArrayRef<QualType>(indexType),
  2560. ArrayRef<StringRef>(StringRef("index")),
  2561. m_context->DeclarationNames.getCXXOperatorName(OO_Subscript), true);
  2562. hlsl::CreateFunctionTemplateDecl(
  2563. *m_context, recordDecl, functionDecl,
  2564. reinterpret_cast<NamedDecl **>(&templateTypeParmDecl), 1);
  2565. // Add a .mips member if necessary.
  2566. QualType uintType = m_context->UnsignedIntTy;
  2567. if (op.HasMips) {
  2568. AddDoubleSubscriptSupport(typeDecl, recordDecl, "mips", resultType,
  2569. templateTypeParmDecl, "mips_type",
  2570. "mips_slice_type", "mipSlice", uintType, "pos",
  2571. indexType);
  2572. }
  2573. // Add a .sample member if necessary.
  2574. if (op.HasSample) {
  2575. AddDoubleSubscriptSupport(typeDecl, recordDecl, "sample", resultType,
  2576. templateTypeParmDecl, "sample_type",
  2577. "sample_slice_type", "sampleSlice", uintType,
  2578. "pos", indexType);
  2579. // TODO: support operator[][](indexType, uint).
  2580. }
  2581. }
  2582. static bool ObjectTypeDeclMapTypeCmp(const std::pair<CXXRecordDecl*,unsigned> &a,
  2583. const std::pair<CXXRecordDecl*,unsigned> &b) {
  2584. return a.first < b.first;
  2585. };
  2586. int FindObjectBasicKindIndex(const CXXRecordDecl* recordDecl) {
  2587. auto begin = m_objectTypeDeclsMap.begin();
  2588. auto end = m_objectTypeDeclsMap.end();
  2589. auto val = std::make_pair(const_cast<CXXRecordDecl*>(recordDecl), 0);
  2590. auto low = std::lower_bound(begin, end, val, ObjectTypeDeclMapTypeCmp);
  2591. if (low == end)
  2592. return -1;
  2593. if (recordDecl == low->first)
  2594. return low->second;
  2595. else
  2596. return -1;
  2597. }
  2598. // Adds all built-in HLSL object types.
  2599. void AddObjectTypes()
  2600. {
  2601. DXASSERT(m_context != nullptr, "otherwise caller hasn't initialized context yet");
  2602. QualType float4Type = LookupVectorType(HLSLScalarType_float, 4);
  2603. TypeSourceInfo *float4TypeSourceInfo = m_context->getTrivialTypeSourceInfo(float4Type, NoLoc);
  2604. m_objectTypeLazyInitMask = 0;
  2605. unsigned effectKindIndex = 0;
  2606. for (unsigned i = 0; i < _countof(g_ArBasicKindsAsTypes); i++)
  2607. {
  2608. ArBasicKind kind = g_ArBasicKindsAsTypes[i];
  2609. if (kind == AR_OBJECT_WAVE) { // wave objects are currently unused
  2610. continue;
  2611. }
  2612. if (kind == AR_OBJECT_LEGACY_EFFECT)
  2613. effectKindIndex = i;
  2614. DXASSERT(kind < _countof(g_ArBasicTypeNames), "g_ArBasicTypeNames has the wrong number of entries");
  2615. _Analysis_assume_(kind < _countof(g_ArBasicTypeNames));
  2616. const char* typeName = g_ArBasicTypeNames[kind];
  2617. uint8_t templateArgCount = g_ArBasicKindsTemplateCount[i];
  2618. CXXRecordDecl* recordDecl = nullptr;
  2619. if (kind == AR_OBJECT_RAY_DESC) {
  2620. QualType float3Ty = LookupVectorType(HLSLScalarType::HLSLScalarType_float, 3);
  2621. recordDecl = CreateRayDescStruct(*m_context, float3Ty);
  2622. } else if (kind == AR_OBJECT_TRIANGLE_INTERSECTION_ATTRIBUTES) {
  2623. QualType float2Type = LookupVectorType(HLSLScalarType::HLSLScalarType_float, 2);
  2624. recordDecl = AddBuiltInTriangleIntersectionAttributes(*m_context, float2Type);
  2625. } else
  2626. if (templateArgCount == 0)
  2627. {
  2628. AddRecordTypeWithHandle(*m_context, &recordDecl, typeName);
  2629. DXASSERT(recordDecl != nullptr, "AddRecordTypeWithHandle failed to return the object declaration");
  2630. recordDecl->setImplicit(true);
  2631. }
  2632. else
  2633. {
  2634. DXASSERT(templateArgCount == 1 || templateArgCount == 2, "otherwise a new case has been added");
  2635. ClassTemplateDecl* typeDecl = nullptr;
  2636. TypeSourceInfo* typeDefault = TemplateHasDefaultType(kind) ? float4TypeSourceInfo : nullptr;
  2637. AddTemplateTypeWithHandle(*m_context, &typeDecl, &recordDecl, typeName, templateArgCount, typeDefault);
  2638. DXASSERT(typeDecl != nullptr, "AddTemplateTypeWithHandle failed to return the object declaration");
  2639. typeDecl->setImplicit(true);
  2640. recordDecl->setImplicit(true);
  2641. }
  2642. m_objectTypeDecls[i] = recordDecl;
  2643. m_objectTypeDeclsMap[i] = std::make_pair(recordDecl, i);
  2644. m_objectTypeLazyInitMask |= ((uint64_t)1)<<i;
  2645. }
  2646. // Create an alias for SamplerState. 'sampler' is very commonly used.
  2647. {
  2648. DeclContext* currentDeclContext = m_context->getTranslationUnitDecl();
  2649. IdentifierInfo& samplerId = m_context->Idents.get(StringRef("sampler"), tok::TokenKind::identifier);
  2650. TypeSourceInfo* samplerTypeSource = m_context->getTrivialTypeSourceInfo(GetBasicKindType(AR_OBJECT_SAMPLER));
  2651. TypedefDecl* samplerDecl = TypedefDecl::Create(*m_context, currentDeclContext, NoLoc, NoLoc, &samplerId, samplerTypeSource);
  2652. currentDeclContext->addDecl(samplerDecl);
  2653. samplerDecl->setImplicit(true);
  2654. // Create decls for each deprecated effect object type:
  2655. unsigned effectObjBase = _countof(g_ArBasicKindsAsTypes);
  2656. // TypeSourceInfo* effectObjTypeSource = m_context->getTrivialTypeSourceInfo(GetBasicKindType(AR_OBJECT_LEGACY_EFFECT));
  2657. for (unsigned i = 0; i < _countof(g_DeprecatedEffectObjectNames); i++) {
  2658. IdentifierInfo& idInfo = m_context->Idents.get(StringRef(g_DeprecatedEffectObjectNames[i]), tok::TokenKind::identifier);
  2659. //TypedefDecl* effectObjDecl = TypedefDecl::Create(*m_context, currentDeclContext, NoLoc, NoLoc, &idInfo, effectObjTypeSource);
  2660. CXXRecordDecl *effectObjDecl = CXXRecordDecl::Create(*m_context, TagTypeKind::TTK_Struct, currentDeclContext, NoLoc, NoLoc, &idInfo);
  2661. currentDeclContext->addDecl(effectObjDecl);
  2662. effectObjDecl->setImplicit(true);
  2663. m_objectTypeDeclsMap[i+effectObjBase] = std::make_pair(effectObjDecl, effectKindIndex);
  2664. }
  2665. }
  2666. // Make sure it's in order.
  2667. std::sort(m_objectTypeDeclsMap.begin(), m_objectTypeDeclsMap.end(), ObjectTypeDeclMapTypeCmp);
  2668. }
  2669. FunctionDecl* AddSubscriptSpecialization(
  2670. _In_ FunctionTemplateDecl* functionTemplate,
  2671. QualType objectElement,
  2672. const FindStructBasicTypeResult& findResult);
  2673. ImplicitCastExpr* CreateLValueToRValueCast(Expr* input) {
  2674. return ImplicitCastExpr::Create(*m_context, input->getType(), CK_LValueToRValue, input, nullptr, VK_RValue);
  2675. }
  2676. ImplicitCastExpr* CreateFlatConversionCast(Expr* input) {
  2677. return ImplicitCastExpr::Create(*m_context, input->getType(), CK_LValueToRValue, input, nullptr, VK_RValue);
  2678. }
  2679. static TYPE_CONVERSION_REMARKS RemarksUnused;
  2680. static ImplicitConversionKind ImplicitConversionKindUnused;
  2681. HRESULT CombineDimensions(QualType leftType, QualType rightType, QualType *resultType,
  2682. ImplicitConversionKind &convKind = ImplicitConversionKindUnused,
  2683. TYPE_CONVERSION_REMARKS &Remarks = RemarksUnused);
  2684. clang::TypedefDecl *LookupMatrixShorthandType(HLSLScalarType scalarType, UINT rowCount, UINT colCount) {
  2685. DXASSERT_NOMSG(scalarType != HLSLScalarType::HLSLScalarType_unknown &&
  2686. rowCount <= 4 && colCount <= 4);
  2687. TypedefDecl *qts =
  2688. m_matrixShorthandTypes[scalarType][rowCount - 1][colCount - 1];
  2689. if (qts == nullptr) {
  2690. QualType type = LookupMatrixType(scalarType, rowCount, colCount);
  2691. qts = CreateMatrixSpecializationShorthand(*m_context, type, scalarType,
  2692. rowCount, colCount);
  2693. m_matrixShorthandTypes[scalarType][rowCount - 1][colCount - 1] = qts;
  2694. }
  2695. return qts;
  2696. }
  2697. clang::TypedefDecl *LookupVectorShorthandType(HLSLScalarType scalarType, UINT colCount) {
  2698. DXASSERT_NOMSG(scalarType != HLSLScalarType::HLSLScalarType_unknown &&
  2699. colCount <= 4);
  2700. TypedefDecl *qts = m_vectorTypedefs[scalarType][colCount - 1];
  2701. if (qts == nullptr) {
  2702. QualType type = LookupVectorType(scalarType, colCount);
  2703. qts = CreateVectorSpecializationShorthand(*m_context, type, scalarType,
  2704. colCount);
  2705. m_vectorTypedefs[scalarType][colCount - 1] = qts;
  2706. }
  2707. return qts;
  2708. }
  2709. public:
  2710. HLSLExternalSource() :
  2711. m_matrixTemplateDecl(nullptr),
  2712. m_vectorTemplateDecl(nullptr),
  2713. m_context(nullptr),
  2714. m_sema(nullptr)
  2715. {
  2716. memset(m_matrixTypes, 0, sizeof(m_matrixTypes));
  2717. memset(m_matrixShorthandTypes, 0, sizeof(m_matrixShorthandTypes));
  2718. memset(m_vectorTypes, 0, sizeof(m_vectorTypes));
  2719. memset(m_vectorTypedefs, 0, sizeof(m_vectorTypedefs));
  2720. memset(m_scalarTypes, 0, sizeof(m_scalarTypes));
  2721. memset(m_scalarTypeDefs, 0, sizeof(m_scalarTypeDefs));
  2722. memset(m_baseTypes, 0, sizeof(m_baseTypes));
  2723. }
  2724. ~HLSLExternalSource() { }
  2725. static HLSLExternalSource* FromSema(_In_ Sema* self)
  2726. {
  2727. DXASSERT_NOMSG(self != nullptr);
  2728. ExternalSemaSource* externalSource = self->getExternalSource();
  2729. DXASSERT(externalSource != nullptr, "otherwise caller shouldn't call HLSL-specific function");
  2730. HLSLExternalSource* hlsl = reinterpret_cast<HLSLExternalSource*>(externalSource);
  2731. return hlsl;
  2732. }
  2733. void InitializeSema(Sema& S) override
  2734. {
  2735. m_sema = &S;
  2736. S.addExternalSource(this);
  2737. AddObjectTypes();
  2738. AddStdIsEqualImplementation(S.getASTContext(), S);
  2739. for (auto && intrinsic : m_intrinsicTables) {
  2740. AddIntrinsicTableMethods(intrinsic);
  2741. }
  2742. }
  2743. void ForgetSema() override
  2744. {
  2745. m_sema = nullptr;
  2746. }
  2747. Sema* getSema() {
  2748. return m_sema;
  2749. }
  2750. TypedefDecl* LookupScalarTypeDef(HLSLScalarType scalarType) {
  2751. // We shouldn't create Typedef for built in scalar types.
  2752. // For built in scalar types, this funciton may be called for
  2753. // TypoCorrection. In that case, we return a nullptr.
  2754. if (m_scalarTypes[scalarType].isNull()) {
  2755. m_scalarTypeDefs[scalarType] = CreateGlobalTypedef(m_context, HLSLScalarTypeNames[scalarType], m_baseTypes[scalarType]);
  2756. m_scalarTypes[scalarType] = m_context->getTypeDeclType(m_scalarTypeDefs[scalarType]);
  2757. }
  2758. return m_scalarTypeDefs[scalarType];
  2759. }
  2760. QualType LookupMatrixType(HLSLScalarType scalarType, unsigned int rowCount, unsigned int colCount)
  2761. {
  2762. QualType qt = m_matrixTypes[scalarType][rowCount - 1][colCount - 1];
  2763. if (qt.isNull()) {
  2764. // lazy initialization of scalar types
  2765. if (m_scalarTypes[scalarType].isNull()) {
  2766. LookupScalarTypeDef(scalarType);
  2767. }
  2768. qt = GetOrCreateMatrixSpecialization(*m_context, m_sema, m_matrixTemplateDecl, m_scalarTypes[scalarType], rowCount, colCount);
  2769. m_matrixTypes[scalarType][rowCount - 1][colCount - 1] = qt;
  2770. }
  2771. return qt;
  2772. }
  2773. QualType LookupVectorType(HLSLScalarType scalarType, unsigned int colCount)
  2774. {
  2775. QualType qt = m_vectorTypes[scalarType][colCount - 1];
  2776. if (qt.isNull()) {
  2777. if (m_scalarTypes[scalarType].isNull()) {
  2778. LookupScalarTypeDef(scalarType);
  2779. }
  2780. qt = GetOrCreateVectorSpecialization(*m_context, m_sema, m_vectorTemplateDecl, m_scalarTypes[scalarType], colCount);
  2781. m_vectorTypes[scalarType][colCount - 1] = qt;
  2782. }
  2783. return qt;
  2784. }
  2785. void WarnMinPrecision(HLSLScalarType type, SourceLocation loc) {
  2786. // TODO: enalbe this once we introduce precise master option
  2787. bool UseMinPrecision = m_context->getLangOpts().UseMinPrecision;
  2788. if (type == HLSLScalarType_int_min12) {
  2789. const char *PromotedType =
  2790. UseMinPrecision ? HLSLScalarTypeNames[HLSLScalarType_int_min16]
  2791. : HLSLScalarTypeNames[HLSLScalarType_int16];
  2792. m_sema->Diag(loc, diag::warn_hlsl_sema_minprecision_promotion)
  2793. << HLSLScalarTypeNames[type] << PromotedType;
  2794. } else if (type == HLSLScalarType_float_min10) {
  2795. const char *PromotedType =
  2796. UseMinPrecision ? HLSLScalarTypeNames[HLSLScalarType_float_min16]
  2797. : HLSLScalarTypeNames[HLSLScalarType_float16];
  2798. m_sema->Diag(loc, diag::warn_hlsl_sema_minprecision_promotion)
  2799. << HLSLScalarTypeNames[type] << PromotedType;
  2800. }
  2801. if (!UseMinPrecision) {
  2802. if (type == HLSLScalarType_float_min16) {
  2803. m_sema->Diag(loc, diag::warn_hlsl_sema_minprecision_promotion)
  2804. << HLSLScalarTypeNames[type]
  2805. << HLSLScalarTypeNames[HLSLScalarType_float16];
  2806. } else if (type == HLSLScalarType_int_min16) {
  2807. m_sema->Diag(loc, diag::warn_hlsl_sema_minprecision_promotion)
  2808. << HLSLScalarTypeNames[type]
  2809. << HLSLScalarTypeNames[HLSLScalarType_int16];
  2810. } else if (type == HLSLScalarType_uint_min16) {
  2811. m_sema->Diag(loc, diag::warn_hlsl_sema_minprecision_promotion)
  2812. << HLSLScalarTypeNames[type]
  2813. << HLSLScalarTypeNames[HLSLScalarType_uint16];
  2814. }
  2815. }
  2816. }
  2817. bool DiagnoseHLSLScalarType(HLSLScalarType type, SourceLocation Loc) {
  2818. if (getSema()->getLangOpts().HLSLVersion < 2018) {
  2819. switch (type) {
  2820. case HLSLScalarType_float16:
  2821. case HLSLScalarType_float32:
  2822. case HLSLScalarType_float64:
  2823. case HLSLScalarType_int16:
  2824. case HLSLScalarType_int32:
  2825. case HLSLScalarType_uint16:
  2826. case HLSLScalarType_uint32:
  2827. m_sema->Diag(Loc, diag::err_hlsl_unsupported_keyword_for_version)
  2828. << HLSLScalarTypeNames[type] << "2018";
  2829. return false;
  2830. default:
  2831. break;
  2832. }
  2833. }
  2834. if (getSema()->getLangOpts().UseMinPrecision) {
  2835. switch (type) {
  2836. case HLSLScalarType_float16:
  2837. case HLSLScalarType_int16:
  2838. case HLSLScalarType_uint16:
  2839. m_sema->Diag(Loc, diag::err_hlsl_unsupported_keyword_for_min_precision)
  2840. << HLSLScalarTypeNames[type];
  2841. return false;
  2842. default:
  2843. break;
  2844. }
  2845. }
  2846. return true;
  2847. }
  2848. bool LookupUnqualified(LookupResult &R, Scope *S) override
  2849. {
  2850. const DeclarationNameInfo declName = R.getLookupNameInfo();
  2851. IdentifierInfo* idInfo = declName.getName().getAsIdentifierInfo();
  2852. if (idInfo == nullptr) {
  2853. return false;
  2854. }
  2855. // Currently template instantiation is blocked when a fatal error is
  2856. // detected. So no faulting-in types at this point, instead we simply
  2857. // back out.
  2858. if (this->m_sema->Diags.hasFatalErrorOccurred()) {
  2859. return false;
  2860. }
  2861. StringRef nameIdentifier = idInfo->getName();
  2862. HLSLScalarType parsedType;
  2863. int rowCount;
  2864. int colCount;
  2865. // Try parsing hlsl scalar types that is not initialized at AST time.
  2866. if (TryParseAny(nameIdentifier.data(), nameIdentifier.size(), &parsedType, &rowCount, &colCount, getSema()->getLangOpts())) {
  2867. assert(parsedType != HLSLScalarType_unknown && "otherwise, TryParseHLSLScalarType should not have succeeded.");
  2868. if (rowCount == 0 && colCount == 0) { // scalar
  2869. TypedefDecl *typeDecl = LookupScalarTypeDef(parsedType);
  2870. if (!typeDecl) return false;
  2871. R.addDecl(typeDecl);
  2872. }
  2873. else if (rowCount == 0) { // vector
  2874. TypedefDecl *qts = LookupVectorShorthandType(parsedType, colCount);
  2875. R.addDecl(qts);
  2876. }
  2877. else { // matrix
  2878. TypedefDecl* qts = LookupMatrixShorthandType(parsedType, rowCount, colCount);
  2879. R.addDecl(qts);
  2880. }
  2881. return true;
  2882. }
  2883. return false;
  2884. }
  2885. /// <summary>
  2886. /// Determines whether the specify record type is a matrix, another HLSL object, or a user-defined structure.
  2887. /// </sumary>
  2888. ArTypeObjectKind ClassifyRecordType(const RecordType* type)
  2889. {
  2890. DXASSERT_NOMSG(type != nullptr);
  2891. const CXXRecordDecl* typeRecordDecl = type->getAsCXXRecordDecl();
  2892. const ClassTemplateSpecializationDecl* templateSpecializationDecl = dyn_cast<ClassTemplateSpecializationDecl>(typeRecordDecl);
  2893. if (templateSpecializationDecl) {
  2894. ClassTemplateDecl *decl = templateSpecializationDecl->getSpecializedTemplate();
  2895. if (decl == m_matrixTemplateDecl)
  2896. return AR_TOBJ_MATRIX;
  2897. else if (decl == m_vectorTemplateDecl)
  2898. return AR_TOBJ_VECTOR;
  2899. DXASSERT(decl->isImplicit(), "otherwise object template decl is not set to implicit");
  2900. return AR_TOBJ_OBJECT;
  2901. }
  2902. if (typeRecordDecl && typeRecordDecl->isImplicit()) {
  2903. if (typeRecordDecl->getDeclContext()->isFileContext()) {
  2904. int index = FindObjectBasicKindIndex(typeRecordDecl);
  2905. if (index != -1) {
  2906. ArBasicKind kind = g_ArBasicKindsAsTypes[index];
  2907. if ( AR_OBJECT_RAY_DESC == kind || AR_OBJECT_TRIANGLE_INTERSECTION_ATTRIBUTES == kind)
  2908. return AR_TOBJ_COMPOUND;
  2909. }
  2910. return AR_TOBJ_OBJECT;
  2911. }
  2912. else
  2913. return AR_TOBJ_INNER_OBJ;
  2914. }
  2915. return AR_TOBJ_COMPOUND;
  2916. }
  2917. /// <summary>Given a Clang type, determines whether it is a built-in object type (sampler, texture, etc).</summary>
  2918. bool IsBuiltInObjectType(QualType type)
  2919. {
  2920. type = GetStructuralForm(type);
  2921. if (!type.isNull() && type->isStructureOrClassType()) {
  2922. const RecordType* recordType = type->getAs<RecordType>();
  2923. return ClassifyRecordType(recordType) == AR_TOBJ_OBJECT;
  2924. }
  2925. return false;
  2926. }
  2927. /// <summary>
  2928. /// Given the specified type (typed a DeclContext for convenience), determines its RecordDecl,
  2929. /// possibly refering to original template record if it's a specialization; this makes the result
  2930. /// suitable for looking up in initialization tables.
  2931. /// </summary>
  2932. const CXXRecordDecl* GetRecordDeclForBuiltInOrStruct(const DeclContext* context)
  2933. {
  2934. const CXXRecordDecl* recordDecl;
  2935. if (const ClassTemplateSpecializationDecl* decl = dyn_cast<ClassTemplateSpecializationDecl>(context))
  2936. {
  2937. recordDecl = decl->getSpecializedTemplate()->getTemplatedDecl();
  2938. }
  2939. else
  2940. {
  2941. recordDecl = dyn_cast<CXXRecordDecl>(context);
  2942. }
  2943. return recordDecl;
  2944. }
  2945. /// <summary>Given a Clang type, return the ArTypeObjectKind classification, (eg AR_TOBJ_VECTOR).</summary>
  2946. ArTypeObjectKind GetTypeObjectKind(QualType type)
  2947. {
  2948. DXASSERT_NOMSG(!type.isNull());
  2949. type = GetStructuralForm(type);
  2950. if (type->isVoidType()) return AR_TOBJ_VOID;
  2951. if (type->isArrayType()) return AR_TOBJ_ARRAY;
  2952. if (type->isPointerType()) {
  2953. return AR_TOBJ_POINTER;
  2954. }
  2955. if (type->isStructureOrClassType()) {
  2956. const RecordType* recordType = type->getAs<RecordType>();
  2957. return ClassifyRecordType(recordType);
  2958. } else if (const InjectedClassNameType *ClassNameTy =
  2959. type->getAs<InjectedClassNameType>()) {
  2960. const CXXRecordDecl *typeRecordDecl = ClassNameTy->getDecl();
  2961. const ClassTemplateSpecializationDecl *templateSpecializationDecl =
  2962. dyn_cast<ClassTemplateSpecializationDecl>(typeRecordDecl);
  2963. if (templateSpecializationDecl) {
  2964. ClassTemplateDecl *decl =
  2965. templateSpecializationDecl->getSpecializedTemplate();
  2966. if (decl == m_matrixTemplateDecl)
  2967. return AR_TOBJ_MATRIX;
  2968. else if (decl == m_vectorTemplateDecl)
  2969. return AR_TOBJ_VECTOR;
  2970. DXASSERT(decl->isImplicit(),
  2971. "otherwise object template decl is not set to implicit");
  2972. return AR_TOBJ_OBJECT;
  2973. }
  2974. if (typeRecordDecl && typeRecordDecl->isImplicit()) {
  2975. if (typeRecordDecl->getDeclContext()->isFileContext())
  2976. return AR_TOBJ_OBJECT;
  2977. else
  2978. return AR_TOBJ_INNER_OBJ;
  2979. }
  2980. return AR_TOBJ_COMPOUND;
  2981. }
  2982. if (type->isBuiltinType()) return AR_TOBJ_BASIC;
  2983. if (type->isEnumeralType()) return AR_TOBJ_BASIC;
  2984. return AR_TOBJ_INVALID;
  2985. }
  2986. /// <summary>Gets the element type of a matrix or vector type (eg, the 'float' in 'float4x4' or 'float4').</summary>
  2987. QualType GetMatrixOrVectorElementType(QualType type)
  2988. {
  2989. type = GetStructuralForm(type);
  2990. const CXXRecordDecl* typeRecordDecl = type->getAsCXXRecordDecl();
  2991. DXASSERT_NOMSG(typeRecordDecl);
  2992. const ClassTemplateSpecializationDecl* templateSpecializationDecl = dyn_cast<ClassTemplateSpecializationDecl>(typeRecordDecl);
  2993. DXASSERT_NOMSG(templateSpecializationDecl);
  2994. DXASSERT_NOMSG(templateSpecializationDecl->getSpecializedTemplate() == m_matrixTemplateDecl ||
  2995. templateSpecializationDecl->getSpecializedTemplate() == m_vectorTemplateDecl);
  2996. return templateSpecializationDecl->getTemplateArgs().get(0).getAsType();
  2997. }
  2998. /// <summary>Gets the type with structural information (elements and shape) for the given type.</summary>
  2999. /// <remarks>This function will strip lvalue/rvalue references, attributes and qualifiers.</remarks>
  3000. QualType GetStructuralForm(QualType type)
  3001. {
  3002. if (type.isNull()) {
  3003. return type;
  3004. }
  3005. const ReferenceType *RefType = nullptr;
  3006. const AttributedType *AttrType = nullptr;
  3007. while ( (RefType = dyn_cast<ReferenceType>(type)) ||
  3008. (AttrType = dyn_cast<AttributedType>(type)))
  3009. {
  3010. type = RefType ? RefType->getPointeeType() : AttrType->getEquivalentType();
  3011. }
  3012. return type->getCanonicalTypeUnqualified();
  3013. }
  3014. /// <summary>Given a Clang type, return the ArBasicKind classification for its contents.</summary>
  3015. ArBasicKind GetTypeElementKind(QualType type)
  3016. {
  3017. type = GetStructuralForm(type);
  3018. ArTypeObjectKind kind = GetTypeObjectKind(type);
  3019. if (kind == AR_TOBJ_MATRIX || kind == AR_TOBJ_VECTOR) {
  3020. QualType elementType = GetMatrixOrVectorElementType(type);
  3021. return GetTypeElementKind(elementType);
  3022. }
  3023. if (type->isArrayType()) {
  3024. const ArrayType* arrayType = type->getAsArrayTypeUnsafe();
  3025. return GetTypeElementKind(arrayType->getElementType());
  3026. }
  3027. if (kind == AR_TOBJ_INNER_OBJ) {
  3028. return AR_OBJECT_INNER;
  3029. } else if (kind == AR_TOBJ_OBJECT) {
  3030. // Classify the object as the element type.
  3031. const CXXRecordDecl* typeRecordDecl = GetRecordDeclForBuiltInOrStruct(type->getAsCXXRecordDecl());
  3032. int index = FindObjectBasicKindIndex(typeRecordDecl);
  3033. // NOTE: this will likely need to be updated for specialized records
  3034. DXASSERT(index != -1, "otherwise can't find type we already determined was an object");
  3035. return g_ArBasicKindsAsTypes[index];
  3036. }
  3037. CanQualType canType = type->getCanonicalTypeUnqualified();
  3038. return BasicTypeForScalarType(canType);
  3039. }
  3040. ArBasicKind BasicTypeForScalarType(CanQualType type)
  3041. {
  3042. if (const BuiltinType *BT = dyn_cast<BuiltinType>(type))
  3043. {
  3044. switch (BT->getKind())
  3045. {
  3046. case BuiltinType::Bool: return AR_BASIC_BOOL;
  3047. case BuiltinType::Double: return AR_BASIC_FLOAT64;
  3048. case BuiltinType::Float: return AR_BASIC_FLOAT32;
  3049. case BuiltinType::Half: return AR_BASIC_FLOAT16;
  3050. case BuiltinType::HalfFloat: return AR_BASIC_FLOAT32_PARTIAL_PRECISION;
  3051. case BuiltinType::Int: return AR_BASIC_INT32;
  3052. case BuiltinType::UInt: return AR_BASIC_UINT32;
  3053. case BuiltinType::Short: return AR_BASIC_INT16;
  3054. case BuiltinType::UShort: return AR_BASIC_UINT16;
  3055. case BuiltinType::Long: return AR_BASIC_INT32;
  3056. case BuiltinType::ULong: return AR_BASIC_UINT32;
  3057. case BuiltinType::LongLong: return AR_BASIC_INT64;
  3058. case BuiltinType::ULongLong: return AR_BASIC_UINT64;
  3059. case BuiltinType::Min12Int: return AR_BASIC_MIN12INT;
  3060. case BuiltinType::Min16Float: return AR_BASIC_MIN16FLOAT;
  3061. case BuiltinType::Min16Int: return AR_BASIC_MIN16INT;
  3062. case BuiltinType::Min16UInt: return AR_BASIC_MIN16UINT;
  3063. case BuiltinType::Min10Float: return AR_BASIC_MIN10FLOAT;
  3064. case BuiltinType::LitFloat: return AR_BASIC_LITERAL_FLOAT;
  3065. case BuiltinType::LitInt: return AR_BASIC_LITERAL_INT;
  3066. default:
  3067. // Only builtin types that have basickind equivalents.
  3068. break;
  3069. }
  3070. }
  3071. if (const EnumType *ET = dyn_cast<EnumType>(type)) {
  3072. if (ET->getDecl()->isScopedUsingClassTag())
  3073. return AR_BASIC_ENUM_CLASS;
  3074. return AR_BASIC_ENUM;
  3075. }
  3076. return AR_BASIC_UNKNOWN;
  3077. }
  3078. void AddIntrinsicTableMethods(_In_ IDxcIntrinsicTable *table) {
  3079. DXASSERT_NOMSG(table != nullptr);
  3080. // Function intrinsics are added on-demand, objects get template methods.
  3081. for (unsigned i = 0; i < _countof(g_ArBasicKindsAsTypes); i++) {
  3082. // Grab information already processed by AddObjectTypes.
  3083. ArBasicKind kind = g_ArBasicKindsAsTypes[i];
  3084. const char *typeName = g_ArBasicTypeNames[kind];
  3085. uint8_t templateArgCount = g_ArBasicKindsTemplateCount[i];
  3086. DXASSERT(templateArgCount <= 2, "otherwise a new case has been added");
  3087. int startDepth = (templateArgCount == 0) ? 0 : 1;
  3088. CXXRecordDecl *recordDecl = m_objectTypeDecls[i];
  3089. if (recordDecl == nullptr) {
  3090. DXASSERT(kind == AR_OBJECT_WAVE, "else objects other than reserved not initialized");
  3091. continue;
  3092. }
  3093. // This is a variation of AddObjectMethods using the new table.
  3094. const HLSL_INTRINSIC *pIntrinsic = nullptr;
  3095. const HLSL_INTRINSIC *pPrior = nullptr;
  3096. UINT64 lookupCookie = 0;
  3097. CA2W wideTypeName(typeName);
  3098. HRESULT found = table->LookupIntrinsic(wideTypeName, L"*", &pIntrinsic, &lookupCookie);
  3099. while (pIntrinsic != nullptr && SUCCEEDED(found)) {
  3100. if (!AreIntrinsicTemplatesEquivalent(pIntrinsic, pPrior)) {
  3101. AddObjectIntrinsicTemplate(recordDecl, startDepth, pIntrinsic);
  3102. // NOTE: this only works with the current implementation because
  3103. // intrinsics are alive as long as the table is alive.
  3104. pPrior = pIntrinsic;
  3105. }
  3106. found = table->LookupIntrinsic(wideTypeName, L"*", &pIntrinsic, &lookupCookie);
  3107. }
  3108. }
  3109. }
  3110. void RegisterIntrinsicTable(_In_ IDxcIntrinsicTable *table) {
  3111. DXASSERT_NOMSG(table != nullptr);
  3112. m_intrinsicTables.push_back(table);
  3113. // If already initialized, add methods immediately.
  3114. if (m_sema != nullptr) {
  3115. AddIntrinsicTableMethods(table);
  3116. }
  3117. }
  3118. HLSLScalarType ScalarTypeForBasic(ArBasicKind kind)
  3119. {
  3120. DXASSERT(kind < AR_BASIC_COUNT, "otherwise caller didn't check that the value was in range");
  3121. switch (kind) {
  3122. case AR_BASIC_BOOL: return HLSLScalarType_bool;
  3123. case AR_BASIC_LITERAL_FLOAT: return HLSLScalarType_float_lit;
  3124. case AR_BASIC_FLOAT16: return HLSLScalarType_half;
  3125. case AR_BASIC_FLOAT32_PARTIAL_PRECISION:
  3126. return HLSLScalarType_float;
  3127. case AR_BASIC_FLOAT32: return HLSLScalarType_float;
  3128. case AR_BASIC_FLOAT64: return HLSLScalarType_double;
  3129. case AR_BASIC_LITERAL_INT: return HLSLScalarType_int_lit;
  3130. case AR_BASIC_INT8: return HLSLScalarType_int;
  3131. case AR_BASIC_UINT8: return HLSLScalarType_uint;
  3132. case AR_BASIC_INT16: return HLSLScalarType_int16;
  3133. case AR_BASIC_UINT16: return HLSLScalarType_uint16;
  3134. case AR_BASIC_INT32: return HLSLScalarType_int;
  3135. case AR_BASIC_UINT32: return HLSLScalarType_uint;
  3136. case AR_BASIC_MIN10FLOAT: return HLSLScalarType_float_min10;
  3137. case AR_BASIC_MIN16FLOAT: return HLSLScalarType_float_min16;
  3138. case AR_BASIC_MIN12INT: return HLSLScalarType_int_min12;
  3139. case AR_BASIC_MIN16INT: return HLSLScalarType_int_min16;
  3140. case AR_BASIC_MIN16UINT: return HLSLScalarType_uint_min16;
  3141. case AR_BASIC_INT64: return HLSLScalarType_int64;
  3142. case AR_BASIC_UINT64: return HLSLScalarType_uint64;
  3143. case AR_BASIC_ENUM: return HLSLScalarType_int;
  3144. default:
  3145. return HLSLScalarType_unknown;
  3146. }
  3147. }
  3148. QualType GetBasicKindType(ArBasicKind kind)
  3149. {
  3150. DXASSERT_VALIDBASICKIND(kind);
  3151. switch (kind) {
  3152. case AR_OBJECT_NULL: return m_context->VoidTy;
  3153. case AR_BASIC_BOOL: return m_context->BoolTy;
  3154. case AR_BASIC_LITERAL_FLOAT: return m_context->LitFloatTy;
  3155. case AR_BASIC_FLOAT16: return m_context->HalfTy;
  3156. case AR_BASIC_FLOAT32_PARTIAL_PRECISION: return m_context->HalfFloatTy;
  3157. case AR_BASIC_FLOAT32: return m_context->FloatTy;
  3158. case AR_BASIC_FLOAT64: return m_context->DoubleTy;
  3159. case AR_BASIC_LITERAL_INT: return m_context->LitIntTy;
  3160. case AR_BASIC_INT8: return m_context->IntTy;
  3161. case AR_BASIC_UINT8: return m_context->UnsignedIntTy;
  3162. case AR_BASIC_INT16: return m_context->ShortTy;
  3163. case AR_BASIC_UINT16: return m_context->UnsignedShortTy;
  3164. case AR_BASIC_INT32: return m_context->IntTy;
  3165. case AR_BASIC_UINT32: return m_context->UnsignedIntTy;
  3166. case AR_BASIC_INT64: return m_context->LongLongTy;
  3167. case AR_BASIC_UINT64: return m_context->UnsignedLongLongTy;
  3168. case AR_BASIC_MIN10FLOAT: return m_scalarTypes[HLSLScalarType_float_min10];
  3169. case AR_BASIC_MIN16FLOAT: return m_scalarTypes[HLSLScalarType_float_min16];
  3170. case AR_BASIC_MIN12INT: return m_scalarTypes[HLSLScalarType_int_min12];
  3171. case AR_BASIC_MIN16INT: return m_scalarTypes[HLSLScalarType_int_min16];
  3172. case AR_BASIC_MIN16UINT: return m_scalarTypes[HLSLScalarType_uint_min16];
  3173. case AR_BASIC_ENUM: return m_context->IntTy;
  3174. case AR_BASIC_ENUM_CLASS: return m_context->IntTy;
  3175. case AR_OBJECT_STRING: return QualType();
  3176. case AR_OBJECT_LEGACY_EFFECT: // used for all legacy effect object types
  3177. case AR_OBJECT_TEXTURE1D:
  3178. case AR_OBJECT_TEXTURE1D_ARRAY:
  3179. case AR_OBJECT_TEXTURE2D:
  3180. case AR_OBJECT_TEXTURE2D_ARRAY:
  3181. case AR_OBJECT_TEXTURE3D:
  3182. case AR_OBJECT_TEXTURECUBE:
  3183. case AR_OBJECT_TEXTURECUBE_ARRAY:
  3184. case AR_OBJECT_TEXTURE2DMS:
  3185. case AR_OBJECT_TEXTURE2DMS_ARRAY:
  3186. case AR_OBJECT_SAMPLER:
  3187. case AR_OBJECT_SAMPLERCOMPARISON:
  3188. case AR_OBJECT_BUFFER:
  3189. case AR_OBJECT_POINTSTREAM:
  3190. case AR_OBJECT_LINESTREAM:
  3191. case AR_OBJECT_TRIANGLESTREAM:
  3192. case AR_OBJECT_INPUTPATCH:
  3193. case AR_OBJECT_OUTPUTPATCH:
  3194. case AR_OBJECT_RWTEXTURE1D:
  3195. case AR_OBJECT_RWTEXTURE1D_ARRAY:
  3196. case AR_OBJECT_RWTEXTURE2D:
  3197. case AR_OBJECT_RWTEXTURE2D_ARRAY:
  3198. case AR_OBJECT_RWTEXTURE3D:
  3199. case AR_OBJECT_RWBUFFER:
  3200. case AR_OBJECT_BYTEADDRESS_BUFFER:
  3201. case AR_OBJECT_RWBYTEADDRESS_BUFFER:
  3202. case AR_OBJECT_STRUCTURED_BUFFER:
  3203. case AR_OBJECT_RWSTRUCTURED_BUFFER:
  3204. case AR_OBJECT_APPEND_STRUCTURED_BUFFER:
  3205. case AR_OBJECT_CONSUME_STRUCTURED_BUFFER:
  3206. case AR_OBJECT_WAVE:
  3207. case AR_OBJECT_ACCELARATION_STRUCT:
  3208. case AR_OBJECT_RAY_DESC:
  3209. case AR_OBJECT_TRIANGLE_INTERSECTION_ATTRIBUTES:
  3210. {
  3211. const ArBasicKind* match = std::find(g_ArBasicKindsAsTypes, &g_ArBasicKindsAsTypes[_countof(g_ArBasicKindsAsTypes)], kind);
  3212. DXASSERT(match != &g_ArBasicKindsAsTypes[_countof(g_ArBasicKindsAsTypes)], "otherwise can't find constant in basic kinds");
  3213. size_t index = match - g_ArBasicKindsAsTypes;
  3214. return m_context->getTagDeclType(this->m_objectTypeDecls[index]);
  3215. }
  3216. case AR_OBJECT_SAMPLER1D:
  3217. case AR_OBJECT_SAMPLER2D:
  3218. case AR_OBJECT_SAMPLER3D:
  3219. case AR_OBJECT_SAMPLERCUBE:
  3220. // Turn dimension-typed samplers into sampler states.
  3221. return GetBasicKindType(AR_OBJECT_SAMPLER);
  3222. case AR_OBJECT_STATEBLOCK:
  3223. case AR_OBJECT_RASTERIZER:
  3224. case AR_OBJECT_DEPTHSTENCIL:
  3225. case AR_OBJECT_BLEND:
  3226. case AR_OBJECT_RWSTRUCTURED_BUFFER_ALLOC:
  3227. case AR_OBJECT_RWSTRUCTURED_BUFFER_CONSUME:
  3228. default:
  3229. return QualType();
  3230. }
  3231. }
  3232. /// <summary>Promotes the specified expression to an integer type if it's a boolean type.</summary
  3233. /// <param name="E">Expression to typecast.</param>
  3234. /// <returns>E typecast to a integer type if it's a valid boolean type; E otherwise.</returns>
  3235. ExprResult PromoteToIntIfBool(ExprResult& E);
  3236. QualType NewQualifiedType(UINT64 qwUsages, QualType type)
  3237. {
  3238. // NOTE: NewQualifiedType does quite a bit more in the prior compiler
  3239. (void)(qwUsages);
  3240. return type;
  3241. }
  3242. QualType NewSimpleAggregateType(
  3243. _In_ ArTypeObjectKind ExplicitKind,
  3244. _In_ ArBasicKind componentType,
  3245. _In_ UINT64 qwQual,
  3246. _In_ UINT uRows,
  3247. _In_ UINT uCols)
  3248. {
  3249. DXASSERT_VALIDBASICKIND(componentType);
  3250. QualType pType; // The type to return.
  3251. if (componentType < AR_BASIC_COUNT) {
  3252. // If basic numeric, call LookupScalarTypeDef to ensure on-demand
  3253. // initialization
  3254. LookupScalarTypeDef(ScalarTypeForBasic(componentType));
  3255. }
  3256. QualType pEltType = GetBasicKindType(componentType);
  3257. DXASSERT(!pEltType.isNull(), "otherwise caller is specifying an incorrect basic kind type");
  3258. // TODO: handle adding qualifications like const
  3259. pType = NewQualifiedType(
  3260. qwQual & ~(UINT64)(AR_QUAL_COLMAJOR | AR_QUAL_ROWMAJOR),
  3261. pEltType);
  3262. if (uRows > 1 ||
  3263. uCols > 1 ||
  3264. ExplicitKind == AR_TOBJ_VECTOR ||
  3265. ExplicitKind == AR_TOBJ_MATRIX)
  3266. {
  3267. HLSLScalarType scalarType = ScalarTypeForBasic(componentType);
  3268. DXASSERT(scalarType != HLSLScalarType_unknown, "otherwise caller is specifying an incorrect type");
  3269. if ((uRows == 1 &&
  3270. ExplicitKind != AR_TOBJ_MATRIX) ||
  3271. ExplicitKind == AR_TOBJ_VECTOR)
  3272. {
  3273. pType = LookupVectorType(scalarType, uCols);
  3274. }
  3275. else
  3276. {
  3277. pType = LookupMatrixType(scalarType, uRows, uCols);
  3278. }
  3279. // TODO: handle colmajor/rowmajor
  3280. //if ((qwQual & (AR_QUAL_COLMAJOR | AR_QUAL_ROWMAJOR)) != 0)
  3281. //{
  3282. // VN(pType = NewQualifiedType(pSrcLoc,
  3283. // qwQual & (AR_QUAL_COLMAJOR |
  3284. // AR_QUAL_ROWMAJOR),
  3285. // pMatrix));
  3286. //}
  3287. //else
  3288. //{
  3289. // pType = pMatrix;
  3290. //}
  3291. }
  3292. return pType;
  3293. }
  3294. /// <summary>Attempts to match Args to the signature specification in pIntrinsic.</summary>
  3295. /// <param name="pIntrinsic">Intrinsic function to match.</param>
  3296. /// <param name="objectElement">Type element on the class intrinsic belongs to; possibly null (eg, 'float' in 'Texture2D<float>').</param>
  3297. /// <param name="Args">Invocation arguments to match.</param>
  3298. /// <param name="argTypes">After exectuion, type of arguments.</param>
  3299. /// <param name="argCount">After execution, number of arguments in argTypes.</param>
  3300. /// <remarks>On success, argTypes includes the clang Types to use for the signature, with the first being the return type.</remarks>
  3301. bool MatchArguments(
  3302. const _In_ HLSL_INTRINSIC *pIntrinsic,
  3303. _In_ QualType objectElement,
  3304. _In_ ArrayRef<Expr *> Args,
  3305. _Out_writes_(g_MaxIntrinsicParamCount + 1) QualType(&argTypes)[g_MaxIntrinsicParamCount + 1],
  3306. _Out_range_(0, g_MaxIntrinsicParamCount + 1) size_t* argCount);
  3307. /// <summary>Validate object element on intrinsic to catch case like integer on Sample.</summary>
  3308. /// <param name="pIntrinsic">Intrinsic function to validate.</param>
  3309. /// <param name="objectElement">Type element on the class intrinsic belongs to; possibly null (eg, 'float' in 'Texture2D<float>').</param>
  3310. bool IsValidateObjectElement(
  3311. _In_ const HLSL_INTRINSIC *pIntrinsic,
  3312. _In_ QualType objectElement);
  3313. // Returns the iterator with the first entry that matches the requirement
  3314. IntrinsicDefIter FindIntrinsicByNameAndArgCount(
  3315. _In_count_(tableSize) const HLSL_INTRINSIC* table,
  3316. size_t tableSize,
  3317. StringRef typeName,
  3318. StringRef nameIdentifier,
  3319. size_t argumentCount)
  3320. {
  3321. // This is implemented by a linear scan for now.
  3322. // We tested binary search on tables, and there was no performance gain on
  3323. // samples probably for the following reasons.
  3324. // 1. The tables are not big enough to make noticable difference
  3325. // 2. The user of this function assumes that it returns the first entry in
  3326. // the table that matches name and argument count. So even in the binary
  3327. // search, we have to scan backwards until the entry does not match the name
  3328. // or arg count. For linear search this is not a problem
  3329. for (unsigned int i = 0; i < tableSize; i++) {
  3330. const HLSL_INTRINSIC* pIntrinsic = &table[i];
  3331. // Do some quick checks to verify size and name.
  3332. if (pIntrinsic->uNumArgs != 1 + argumentCount) {
  3333. continue;
  3334. }
  3335. if (!nameIdentifier.equals(StringRef(pIntrinsic->pArgs[0].pName))) {
  3336. continue;
  3337. }
  3338. return IntrinsicDefIter::CreateStart(table, tableSize, pIntrinsic,
  3339. IntrinsicTableDefIter::CreateStart(m_intrinsicTables, typeName, nameIdentifier, argumentCount));
  3340. }
  3341. return IntrinsicDefIter::CreateStart(table, tableSize, table + tableSize,
  3342. IntrinsicTableDefIter::CreateStart(m_intrinsicTables, typeName, nameIdentifier, argumentCount));
  3343. }
  3344. bool AddOverloadedCallCandidates(
  3345. UnresolvedLookupExpr *ULE,
  3346. ArrayRef<Expr *> Args,
  3347. OverloadCandidateSet &CandidateSet,
  3348. bool PartialOverloading) override
  3349. {
  3350. DXASSERT_NOMSG(ULE != nullptr);
  3351. const DeclarationNameInfo declName = ULE->getNameInfo();
  3352. IdentifierInfo* idInfo = declName.getName().getAsIdentifierInfo();
  3353. if (idInfo == nullptr)
  3354. {
  3355. return false;
  3356. }
  3357. StringRef nameIdentifier = idInfo->getName();
  3358. IntrinsicDefIter cursor = FindIntrinsicByNameAndArgCount(
  3359. g_Intrinsics, _countof(g_Intrinsics), StringRef(), nameIdentifier, Args.size());
  3360. IntrinsicDefIter end = IntrinsicDefIter::CreateEnd(
  3361. g_Intrinsics, _countof(g_Intrinsics), IntrinsicTableDefIter::CreateEnd(m_intrinsicTables));
  3362. while (cursor != end)
  3363. {
  3364. // If this is the intrinsic we're interested in, build up a representation
  3365. // of the types we need.
  3366. const HLSL_INTRINSIC* pIntrinsic = *cursor;
  3367. LPCSTR tableName = cursor.GetTableName();
  3368. LPCSTR lowering = cursor.GetLoweringStrategy();
  3369. DXASSERT(
  3370. pIntrinsic->uNumArgs <= g_MaxIntrinsicParamCount + 1,
  3371. "otherwise g_MaxIntrinsicParamCount needs to be updated for wider signatures");
  3372. QualType functionArgTypes[g_MaxIntrinsicParamCount + 1];
  3373. size_t functionArgTypeCount = 0;
  3374. if (!MatchArguments(pIntrinsic, QualType(), Args, functionArgTypes, &functionArgTypeCount))
  3375. {
  3376. ++cursor;
  3377. continue;
  3378. }
  3379. // Get or create the overload we're interested in.
  3380. FunctionDecl* intrinsicFuncDecl = nullptr;
  3381. std::pair<UsedIntrinsicStore::iterator, bool> insertResult = m_usedIntrinsics.insert(UsedIntrinsic(
  3382. pIntrinsic, functionArgTypes, functionArgTypeCount));
  3383. bool insertedNewValue = insertResult.second;
  3384. if (insertedNewValue)
  3385. {
  3386. DXASSERT(tableName, "otherwise IDxcIntrinsicTable::GetTableName() failed");
  3387. intrinsicFuncDecl = AddHLSLIntrinsicFunction(*m_context, m_hlslNSDecl, tableName, lowering, pIntrinsic, functionArgTypes, functionArgTypeCount);
  3388. insertResult.first->setFunctionDecl(intrinsicFuncDecl);
  3389. }
  3390. else
  3391. {
  3392. intrinsicFuncDecl = (*insertResult.first).getFunctionDecl();
  3393. }
  3394. OverloadCandidate& candidate = CandidateSet.addCandidate();
  3395. candidate.Function = intrinsicFuncDecl;
  3396. candidate.FoundDecl.setDecl(intrinsicFuncDecl);
  3397. candidate.Viable = true;
  3398. return true;
  3399. }
  3400. return false;
  3401. }
  3402. bool Initialize(ASTContext& context)
  3403. {
  3404. m_context = &context;
  3405. m_hlslNSDecl = NamespaceDecl::Create(context, context.getTranslationUnitDecl(),
  3406. /*Inline*/ false, SourceLocation(),
  3407. SourceLocation(), &context.Idents.get("hlsl"),
  3408. /*PrevDecl*/ nullptr);
  3409. m_hlslNSDecl->setImplicit();
  3410. AddBaseTypes();
  3411. AddHLSLScalarTypes();
  3412. AddHLSLVectorTemplate(*m_context, &m_vectorTemplateDecl);
  3413. DXASSERT(m_vectorTemplateDecl != nullptr, "AddHLSLVectorTypes failed to return the vector template declaration");
  3414. AddHLSLMatrixTemplate(*m_context, m_vectorTemplateDecl, &m_matrixTemplateDecl);
  3415. DXASSERT(m_matrixTemplateDecl != nullptr, "AddHLSLMatrixTypes failed to return the matrix template declaration");
  3416. // Initializing built in integers for ray tracing
  3417. AddRayFlags(*m_context);
  3418. AddHitKinds(*m_context);
  3419. return true;
  3420. }
  3421. /// <summary>Checks whether the specified type is numeric or composed of numeric elements exclusively.</summary>
  3422. bool IsTypeNumeric(QualType type, _Out_ UINT* count);
  3423. /// <summary>Checks whether the specified type is a scalar type.</summary>
  3424. bool IsScalarType(const QualType& type) {
  3425. DXASSERT(!type.isNull(), "caller should validate its type is initialized");
  3426. return BasicTypeForScalarType(type->getCanonicalTypeUnqualified()) != AR_BASIC_UNKNOWN;
  3427. }
  3428. /// <summary>Checks whether the specified value is a valid vector size.</summary>
  3429. bool IsValidVectorSize(size_t length) {
  3430. return 1 <= length && length <= 4;
  3431. }
  3432. /// <summary>Checks whether the specified value is a valid matrix row or column size.</summary>
  3433. bool IsValidMatrixColOrRowSize(size_t length) {
  3434. return 1 <= length && length <= 4;
  3435. }
  3436. bool IsValidTemplateArgumentType(SourceLocation argLoc, const QualType& type, bool requireScalar) {
  3437. if (type.isNull()) {
  3438. return false;
  3439. }
  3440. if (type.hasQualifiers()) {
  3441. return false;
  3442. }
  3443. // TemplateTypeParm here will be construction of vector return template in matrix operator[]
  3444. if (type->getTypeClass() == Type::TemplateTypeParm)
  3445. return true;
  3446. QualType qt = GetStructuralForm(type);
  3447. if (requireScalar) {
  3448. if (!IsScalarType(qt)) {
  3449. m_sema->Diag(argLoc, diag::err_hlsl_typeintemplateargument_requires_scalar) << type;
  3450. return false;
  3451. }
  3452. return true;
  3453. }
  3454. else {
  3455. ArTypeObjectKind objectKind = GetTypeObjectKind(qt);
  3456. if (qt->isArrayType()) {
  3457. const ArrayType* arrayType = qt->getAsArrayTypeUnsafe();
  3458. return IsValidTemplateArgumentType(argLoc, arrayType->getElementType(), false);
  3459. }
  3460. else if (objectKind == AR_TOBJ_VECTOR) {
  3461. bool valid = true;
  3462. if (!IsValidVectorSize(GetHLSLVecSize(type))) {
  3463. valid = false;
  3464. m_sema->Diag(argLoc, diag::err_hlsl_unsupportedvectorsize) << type << GetHLSLVecSize(type);
  3465. }
  3466. if (!IsScalarType(GetMatrixOrVectorElementType(type))) {
  3467. valid = false;
  3468. m_sema->Diag(argLoc, diag::err_hlsl_unsupportedvectortype) << type << GetMatrixOrVectorElementType(type);
  3469. }
  3470. return valid;
  3471. }
  3472. else if (objectKind == AR_TOBJ_MATRIX) {
  3473. bool valid = true;
  3474. UINT rowCount, colCount;
  3475. GetRowsAndCols(type, rowCount, colCount);
  3476. if (!IsValidMatrixColOrRowSize(rowCount) || !IsValidMatrixColOrRowSize(colCount)) {
  3477. valid = false;
  3478. m_sema->Diag(argLoc, diag::err_hlsl_unsupportedmatrixsize) << type << rowCount << colCount;
  3479. }
  3480. if (!IsScalarType(GetMatrixOrVectorElementType(type))) {
  3481. valid = false;
  3482. m_sema->Diag(argLoc, diag::err_hlsl_unsupportedvectortype) << type << GetMatrixOrVectorElementType(type);
  3483. }
  3484. return valid;
  3485. }
  3486. else if (qt->isStructureType()) {
  3487. const RecordType* recordType = qt->getAsStructureType();
  3488. objectKind = ClassifyRecordType(recordType);
  3489. switch (objectKind)
  3490. {
  3491. case AR_TOBJ_OBJECT:
  3492. m_sema->Diag(argLoc, diag::err_hlsl_objectintemplateargument) << type;
  3493. return false;
  3494. case AR_TOBJ_COMPOUND:
  3495. {
  3496. const RecordDecl* recordDecl = recordType->getDecl();
  3497. RecordDecl::field_iterator begin = recordDecl->field_begin();
  3498. RecordDecl::field_iterator end = recordDecl->field_end();
  3499. bool result = true;
  3500. while (begin != end) {
  3501. const FieldDecl* fieldDecl = *begin;
  3502. if (!IsValidTemplateArgumentType(argLoc, fieldDecl->getType(), false)) {
  3503. m_sema->Diag(argLoc, diag::note_field_type_usage)
  3504. << fieldDecl->getType() << fieldDecl->getIdentifier() << type;
  3505. result = false;
  3506. }
  3507. begin++;
  3508. }
  3509. return result;
  3510. }
  3511. default:
  3512. m_sema->Diag(argLoc, diag::err_hlsl_typeintemplateargument) << type;
  3513. return false;
  3514. }
  3515. }
  3516. else if(IsScalarType(qt)) {
  3517. return true;
  3518. }
  3519. else {
  3520. m_sema->Diag(argLoc, diag::err_hlsl_typeintemplateargument) << type;
  3521. return false;
  3522. }
  3523. }
  3524. }
  3525. /// <summary>Checks whether the source type can be converted to the target type.</summary>
  3526. bool CanConvert(SourceLocation loc, Expr* sourceExpr, QualType target, bool explicitConversion,
  3527. _Out_opt_ TYPE_CONVERSION_REMARKS* remarks,
  3528. _Inout_opt_ StandardConversionSequence* sequence);
  3529. void CollectInfo(QualType type, _Out_ ArTypeInfo* pTypeInfo);
  3530. void GetConversionForm(
  3531. QualType type,
  3532. bool explicitConversion,
  3533. ArTypeInfo* pTypeInfo);
  3534. bool ValidateCast(SourceLocation Loc, _In_ Expr* source, QualType target, bool explicitConversion,
  3535. bool suppressWarnings, bool suppressErrors,
  3536. _Inout_opt_ StandardConversionSequence* sequence);
  3537. bool ValidatePrimitiveTypeForOperand(SourceLocation loc, QualType type, ArTypeObjectKind kind);
  3538. bool ValidateTypeRequirements(
  3539. SourceLocation loc,
  3540. ArBasicKind elementKind,
  3541. ArTypeObjectKind objectKind,
  3542. bool requiresIntegrals,
  3543. bool requiresNumerics);
  3544. /// <summary>Validates and adjusts operands for the specified binary operator.</summary>
  3545. /// <param name="OpLoc">Source location for operator.</param>
  3546. /// <param name="Opc">Kind of binary operator.</param>
  3547. /// <param name="LHS">Left-hand-side expression, possibly updated by this function.</param>
  3548. /// <param name="RHS">Right-hand-side expression, possibly updated by this function.</param>
  3549. /// <param name="ResultTy">Result type for operator expression.</param>
  3550. /// <param name="CompLHSTy">Type of LHS after promotions for computation.</param>
  3551. /// <param name="CompResultTy">Type of computation result.</param>
  3552. void CheckBinOpForHLSL(
  3553. SourceLocation OpLoc,
  3554. BinaryOperatorKind Opc,
  3555. ExprResult& LHS,
  3556. ExprResult& RHS,
  3557. QualType& ResultTy,
  3558. QualType& CompLHSTy,
  3559. QualType& CompResultTy);
  3560. /// <summary>Validates and adjusts operands for the specified unary operator.</summary>
  3561. /// <param name="OpLoc">Source location for operator.</param>
  3562. /// <param name="Opc">Kind of operator.</param>
  3563. /// <param name="InputExpr">Input expression to the operator.</param>
  3564. /// <param name="VK">Value kind for resulting expression.</param>
  3565. /// <param name="OK">Object kind for resulting expression.</param>
  3566. /// <returns>The result type for the expression.</returns>
  3567. QualType CheckUnaryOpForHLSL(
  3568. SourceLocation OpLoc,
  3569. UnaryOperatorKind Opc,
  3570. ExprResult& InputExpr,
  3571. ExprValueKind& VK,
  3572. ExprObjectKind& OK);
  3573. /// <summary>Checks vector conditional operator (Cond ? LHS : RHS).</summary>
  3574. /// <param name="Cond">Vector condition expression.</param>
  3575. /// <param name="LHS">Left hand side.</param>
  3576. /// <param name="RHS">Right hand side.</param>
  3577. /// <param name="QuestionLoc">Location of question mark in operator.</param>
  3578. /// <returns>Result type of vector conditional expression.</returns>
  3579. clang::QualType CheckVectorConditional(
  3580. _In_ ExprResult &Cond,
  3581. _In_ ExprResult &LHS,
  3582. _In_ ExprResult &RHS,
  3583. _In_ SourceLocation QuestionLoc);
  3584. clang::QualType ApplyTypeSpecSignToParsedType(
  3585. _In_ clang::QualType &type,
  3586. _In_ TypeSpecifierSign TSS,
  3587. _In_ SourceLocation Loc
  3588. );
  3589. bool CheckRangedTemplateArgument(SourceLocation diagLoc, llvm::APSInt& sintValue)
  3590. {
  3591. if (!sintValue.isStrictlyPositive() || sintValue.getLimitedValue() > 4)
  3592. {
  3593. m_sema->Diag(diagLoc, diag::err_hlsl_invalid_range_1_4);
  3594. return true;
  3595. }
  3596. return false;
  3597. }
  3598. /// <summary>Performs HLSL-specific processing of template declarations.</summary>
  3599. bool
  3600. CheckTemplateArgumentListForHLSL(_In_ TemplateDecl *Template,
  3601. SourceLocation /* TemplateLoc */,
  3602. TemplateArgumentListInfo &TemplateArgList) {
  3603. DXASSERT_NOMSG(Template != nullptr);
  3604. // Determine which object type the template refers to.
  3605. StringRef templateName = Template->getName();
  3606. // NOTE: this 'escape valve' allows unit tests to perform type checks.
  3607. if (templateName.equals(StringRef("is_same"))) {
  3608. return false;
  3609. }
  3610. bool isMatrix = Template->getCanonicalDecl() ==
  3611. m_matrixTemplateDecl->getCanonicalDecl();
  3612. bool isVector = Template->getCanonicalDecl() ==
  3613. m_vectorTemplateDecl->getCanonicalDecl();
  3614. bool requireScalar = isMatrix || isVector;
  3615. // Check constraints on the type. Right now we only check that template
  3616. // types are primitive types.
  3617. for (unsigned int i = 0; i < TemplateArgList.size(); i++) {
  3618. const TemplateArgumentLoc &argLoc = TemplateArgList[i];
  3619. SourceLocation argSrcLoc = argLoc.getLocation();
  3620. const TemplateArgument &arg = argLoc.getArgument();
  3621. if (arg.getKind() == TemplateArgument::ArgKind::Type) {
  3622. QualType argType = arg.getAsType();
  3623. if (!IsValidTemplateArgumentType(argSrcLoc, argType, requireScalar)) {
  3624. // NOTE: IsValidTemplateArgumentType emits its own diagnostics
  3625. return true;
  3626. }
  3627. }
  3628. else if (arg.getKind() == TemplateArgument::ArgKind::Expression) {
  3629. if (isMatrix || isVector) {
  3630. Expr *expr = arg.getAsExpr();
  3631. llvm::APSInt constantResult;
  3632. if (expr != nullptr &&
  3633. expr->isIntegerConstantExpr(constantResult, *m_context)) {
  3634. if (CheckRangedTemplateArgument(argSrcLoc, constantResult)) {
  3635. return true;
  3636. }
  3637. }
  3638. }
  3639. }
  3640. else if (arg.getKind() == TemplateArgument::ArgKind::Integral) {
  3641. if (isMatrix || isVector) {
  3642. llvm::APSInt Val = arg.getAsIntegral();
  3643. if (CheckRangedTemplateArgument(argSrcLoc, Val)) {
  3644. return true;
  3645. }
  3646. }
  3647. }
  3648. }
  3649. return false;
  3650. }
  3651. FindStructBasicTypeResult FindStructBasicType(_In_ DeclContext* functionDeclContext);
  3652. /// <summary>Finds the table of intrinsics for the declaration context of a member function.</summary>
  3653. /// <param name="functionDeclContext">Declaration context of function.</param>
  3654. /// <param name="name">After execution, the name of the object to which the table applies.</param>
  3655. /// <param name="intrinsics">After execution, the intrinsic table.</param>
  3656. /// <param name="intrinsicCount">After execution, the count of elements in the intrinsic table.</param>
  3657. void FindIntrinsicTable(
  3658. _In_ DeclContext* functionDeclContext,
  3659. _Outptr_result_z_ const char** name,
  3660. _Outptr_result_buffer_(*intrinsicCount) const HLSL_INTRINSIC** intrinsics,
  3661. _Out_ size_t* intrinsicCount);
  3662. /// <summary>Deduces the template arguments by comparing the argument types and the HLSL intrinsic tables.</summary>
  3663. /// <param name="FunctionTemplate">The declaration for the function template being deduced.</param>
  3664. /// <param name="ExplicitTemplateArgs">Explicitly-provided template arguments. Should be empty for an HLSL program.</param>
  3665. /// <param name="Args">Array of expressions being used as arguments.</param>
  3666. /// <param name="Specialization">The declaration for the resolved specialization.</param>
  3667. /// <param name="Info">Provides information about an attempted template argument deduction.</param>
  3668. /// <returns>The result of the template deduction, TDK_Invalid if no HLSL-specific processing done.</returns>
  3669. Sema::TemplateDeductionResult DeduceTemplateArgumentsForHLSL(
  3670. FunctionTemplateDecl *FunctionTemplate,
  3671. TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> Args,
  3672. FunctionDecl *&Specialization, TemplateDeductionInfo &Info);
  3673. clang::OverloadingResult GetBestViableFunction(
  3674. clang::SourceLocation Loc,
  3675. clang::OverloadCandidateSet& set,
  3676. clang::OverloadCandidateSet::iterator& Best);
  3677. /// <summary>
  3678. /// Initializes the specified <paramref name="initSequence" /> describing how
  3679. /// <paramref name="Entity" /> is initialized with <paramref name="Args" />.
  3680. /// </summary>
  3681. /// <param name="Entity">Entity being initialized; a variable, return result, etc.</param>
  3682. /// <param name="Kind">Kind of initialization: copying, list-initializing, constructing, etc.</param>
  3683. /// <param name="Args">Arguments to the initialization.</param>
  3684. /// <param name="TopLevelOfInitList">Whether this is the top-level of an initialization list.</param>
  3685. /// <param name="initSequence">Initialization sequence description to initialize.</param>
  3686. void InitializeInitSequenceForHLSL(
  3687. const InitializedEntity& Entity,
  3688. const InitializationKind& Kind,
  3689. MultiExprArg Args,
  3690. bool TopLevelOfInitList,
  3691. _Inout_ InitializationSequence* initSequence);
  3692. /// <summary>
  3693. /// Checks whether the specified conversion occurs to a type of idential element type but less elements.
  3694. /// </summary>
  3695. /// <remarks>This is an important case because a cast of this type does not turn an lvalue into an rvalue.</remarks>
  3696. bool IsConversionToLessOrEqualElements(
  3697. const ExprResult& sourceExpr,
  3698. const QualType& targetType,
  3699. bool explicitConversion);
  3700. /// <summary>
  3701. /// Checks whether the specified conversion occurs to a type of idential element type but less elements.
  3702. /// </summary>
  3703. /// <remarks>This is an important case because a cast of this type does not turn an lvalue into an rvalue.</remarks>
  3704. bool IsConversionToLessOrEqualElements(
  3705. const QualType& sourceType,
  3706. const QualType& targetType,
  3707. bool explicitConversion);
  3708. /// <summary>Performs a member lookup on the specified BaseExpr if it's a matrix.</summary>
  3709. /// <param name="BaseExpr">Base expression for member access.</param>
  3710. /// <param name="MemberName">Name of member to look up.</param>
  3711. /// <param name="IsArrow">Whether access is through arrow (a->b) rather than period (a.b).</param>
  3712. /// <param name="OpLoc">Location of access operand.</param>
  3713. /// <param name="MemberLoc">Location of member.</param>
  3714. /// <param name="result">Result of lookup operation.</param>
  3715. /// <returns>true if the base type is a matrix and the lookup has been handled.</returns>
  3716. bool LookupMatrixMemberExprForHLSL(
  3717. Expr& BaseExpr,
  3718. DeclarationName MemberName,
  3719. bool IsArrow,
  3720. SourceLocation OpLoc,
  3721. SourceLocation MemberLoc,
  3722. ExprResult* result);
  3723. /// <summary>Performs a member lookup on the specified BaseExpr if it's a vector.</summary>
  3724. /// <param name="BaseExpr">Base expression for member access.</param>
  3725. /// <param name="MemberName">Name of member to look up.</param>
  3726. /// <param name="IsArrow">Whether access is through arrow (a->b) rather than period (a.b).</param>
  3727. /// <param name="OpLoc">Location of access operand.</param>
  3728. /// <param name="MemberLoc">Location of member.</param>
  3729. /// <param name="result">Result of lookup operation.</param>
  3730. /// <returns>true if the base type is a vector and the lookup has been handled.</returns>
  3731. bool LookupVectorMemberExprForHLSL(
  3732. Expr& BaseExpr,
  3733. DeclarationName MemberName,
  3734. bool IsArrow,
  3735. SourceLocation OpLoc,
  3736. SourceLocation MemberLoc,
  3737. ExprResult* result);
  3738. /// <summary>Performs a member lookup on the specified BaseExpr if it's an array.</summary>
  3739. /// <param name="BaseExpr">Base expression for member access.</param>
  3740. /// <param name="MemberName">Name of member to look up.</param>
  3741. /// <param name="IsArrow">Whether access is through arrow (a->b) rather than period (a.b).</param>
  3742. /// <param name="OpLoc">Location of access operand.</param>
  3743. /// <param name="MemberLoc">Location of member.</param>
  3744. /// <param name="result">Result of lookup operation.</param>
  3745. /// <returns>true if the base type is an array and the lookup has been handled.</returns>
  3746. bool LookupArrayMemberExprForHLSL(
  3747. Expr& BaseExpr,
  3748. DeclarationName MemberName,
  3749. bool IsArrow,
  3750. SourceLocation OpLoc,
  3751. SourceLocation MemberLoc,
  3752. ExprResult* result);
  3753. /// <summary>If E is a scalar, converts it to a 1-element vector.</summary>
  3754. /// <param name="E">Expression to convert.</param>
  3755. /// <returns>The result of the conversion; or E if the type is not a scalar.</returns>
  3756. ExprResult MaybeConvertScalarToVector(_In_ clang::Expr* E);
  3757. clang::Expr *HLSLImpCastToScalar(
  3758. _In_ clang::Sema* self,
  3759. _In_ clang::Expr* From,
  3760. ArTypeObjectKind FromShape,
  3761. ArBasicKind EltKind);
  3762. clang::ExprResult PerformHLSLConversion(
  3763. _In_ clang::Expr* From,
  3764. _In_ clang::QualType targetType,
  3765. _In_ const clang::StandardConversionSequence &SCS,
  3766. _In_ clang::Sema::CheckedConversionKind CCK);
  3767. /// <summary>Diagnoses an error when precessing the specified type if nesting is too deep.</summary>
  3768. void ReportUnsupportedTypeNesting(SourceLocation loc, QualType type);
  3769. /// <summary>
  3770. /// Checks if a static cast can be performed, and performs it if possible.
  3771. /// </summary>
  3772. /// <param name="SrcExpr">Expression to cast.</param>
  3773. /// <param name="DestType">Type to cast SrcExpr to.</param>
  3774. /// <param name="CCK">Kind of conversion: implicit, C-style, functional, other.</param>
  3775. /// <param name="OpRange">Source range for the cast operation.</param>
  3776. /// <param name="msg">Error message from the diag::* enumeration to fail with; zero to suppress messages.</param>
  3777. /// <param name="Kind">The kind of operation required for a conversion.</param>
  3778. /// <param name="BasePath">A simple array of base specifiers.</param>
  3779. /// <param name="ListInitialization">Whether the cast is in the context of a list initialization.</param>
  3780. /// <param name="SuppressWarnings">Whether warnings should be omitted.</param>
  3781. /// <param name="SuppressErrors">Whether errors should be omitted.</param>
  3782. bool TryStaticCastForHLSL(ExprResult &SrcExpr,
  3783. QualType DestType,
  3784. Sema::CheckedConversionKind CCK,
  3785. const SourceRange &OpRange, unsigned &msg,
  3786. CastKind &Kind, CXXCastPath &BasePath,
  3787. bool ListInitialization, bool SuppressWarnings, bool SuppressErrors,
  3788. _Inout_opt_ StandardConversionSequence* standard);
  3789. /// <summary>
  3790. /// Checks if a subscript index argument can be initialized from the given expression.
  3791. /// </summary>
  3792. /// <param name="SrcExpr">Source expression used as argument.</param>
  3793. /// <param name="DestType">Parameter type to initialize.</param>
  3794. /// <remarks>
  3795. /// Rules for subscript index initialization follow regular implicit casting rules, with the exception that
  3796. /// no changes in arity are allowed (i.e., int2 can become uint2, but uint or uint3 cannot).
  3797. /// </remarks>
  3798. ImplicitConversionSequence TrySubscriptIndexInitialization(_In_ clang::Expr* SrcExpr, clang::QualType DestType);
  3799. void AddHLSLObjectMethodsIfNotReady(QualType qt) {
  3800. static_assert((sizeof(uint64_t)*8) >= _countof(g_ArBasicKindsAsTypes), "Bitmask size is too small");
  3801. // Everything is ready.
  3802. if (m_objectTypeLazyInitMask == 0)
  3803. return;
  3804. CXXRecordDecl *recordDecl = const_cast<CXXRecordDecl *>(GetRecordDeclForBuiltInOrStruct(qt->getAsCXXRecordDecl()));
  3805. int idx = FindObjectBasicKindIndex(recordDecl);
  3806. // Not object type.
  3807. if (idx == -1)
  3808. return;
  3809. uint64_t bit = ((uint64_t)1)<<idx;
  3810. // Already created.
  3811. if ((m_objectTypeLazyInitMask & bit) == 0)
  3812. return;
  3813. ArBasicKind kind = g_ArBasicKindsAsTypes[idx];
  3814. uint8_t templateArgCount = g_ArBasicKindsTemplateCount[idx];
  3815. int startDepth = 0;
  3816. if (templateArgCount > 0) {
  3817. DXASSERT(templateArgCount == 1 || templateArgCount == 2,
  3818. "otherwise a new case has been added");
  3819. ClassTemplateDecl *typeDecl = recordDecl->getDescribedClassTemplate();
  3820. AddObjectSubscripts(kind, typeDecl, recordDecl,
  3821. g_ArBasicKindsSubscripts[idx]);
  3822. startDepth = 1;
  3823. }
  3824. AddObjectMethods(kind, recordDecl, startDepth);
  3825. // Clear the object.
  3826. m_objectTypeLazyInitMask &= ~bit;
  3827. }
  3828. FunctionDecl* AddHLSLIntrinsicMethod(
  3829. LPCSTR tableName,
  3830. LPCSTR lowering,
  3831. _In_ const HLSL_INTRINSIC* intrinsic,
  3832. _In_ FunctionTemplateDecl *FunctionTemplate,
  3833. ArrayRef<Expr *> Args,
  3834. _In_count_(parameterTypeCount) QualType* parameterTypes,
  3835. size_t parameterTypeCount)
  3836. {
  3837. DXASSERT_NOMSG(intrinsic != nullptr);
  3838. DXASSERT_NOMSG(FunctionTemplate != nullptr);
  3839. DXASSERT_NOMSG(parameterTypes != nullptr);
  3840. DXASSERT(parameterTypeCount >= 1, "otherwise caller didn't initialize - there should be at least a void return type");
  3841. // Create the template arguments.
  3842. SmallVector<TemplateArgument, g_MaxIntrinsicParamCount + 1> templateArgs;
  3843. for (size_t i = 0; i < parameterTypeCount; i++) {
  3844. templateArgs.push_back(TemplateArgument(parameterTypes[i]));
  3845. }
  3846. // Look for an existing specialization.
  3847. void *InsertPos = nullptr;
  3848. FunctionDecl *SpecFunc =
  3849. FunctionTemplate->findSpecialization(templateArgs, InsertPos);
  3850. if (SpecFunc != nullptr) {
  3851. return SpecFunc;
  3852. }
  3853. // Change return type to rvalue reference type for aggregate types
  3854. QualType retTy = parameterTypes[0];
  3855. if (retTy->isAggregateType() && !IsHLSLVecMatType(retTy))
  3856. parameterTypes[0] = m_context->getRValueReferenceType(retTy);
  3857. // Create a new specialization.
  3858. SmallVector<ParameterModifier, g_MaxIntrinsicParamCount> paramMods;
  3859. InitParamMods(intrinsic, paramMods);
  3860. for (unsigned int i = 1; i < parameterTypeCount; i++) {
  3861. // Change out/inout parameter type to rvalue reference type.
  3862. if (paramMods[i - 1].isAnyOut()) {
  3863. parameterTypes[i] = m_context->getLValueReferenceType(parameterTypes[i]);
  3864. }
  3865. }
  3866. IntrinsicOp intrinOp = static_cast<IntrinsicOp>(intrinsic->Op);
  3867. if (intrinOp == IntrinsicOp::MOP_SampleBias) {
  3868. // Remove this when update intrinsic table not affect other things.
  3869. // Change vector<float,1> into float for bias.
  3870. const unsigned biasOperandID = 3; // return type, sampler, coord, bias.
  3871. DXASSERT(parameterTypeCount > biasOperandID,
  3872. "else operation was misrecognized");
  3873. if (const ExtVectorType *VecTy =
  3874. hlsl::ConvertHLSLVecMatTypeToExtVectorType(
  3875. *m_context, parameterTypes[biasOperandID])) {
  3876. if (VecTy->getNumElements() == 1)
  3877. parameterTypes[biasOperandID] = VecTy->getElementType();
  3878. }
  3879. }
  3880. DeclContext *owner = FunctionTemplate->getDeclContext();
  3881. TemplateArgumentList templateArgumentList(
  3882. TemplateArgumentList::OnStackType::OnStack, templateArgs.data(),
  3883. templateArgs.size());
  3884. MultiLevelTemplateArgumentList mlTemplateArgumentList(templateArgumentList);
  3885. TemplateDeclInstantiator declInstantiator(*this->m_sema, owner,
  3886. mlTemplateArgumentList);
  3887. FunctionProtoType::ExtProtoInfo EmptyEPI;
  3888. QualType functionType = m_context->getFunctionType(
  3889. parameterTypes[0],
  3890. ArrayRef<QualType>(parameterTypes + 1, parameterTypeCount - 1),
  3891. EmptyEPI, paramMods);
  3892. TypeSourceInfo *TInfo = m_context->CreateTypeSourceInfo(functionType, 0);
  3893. FunctionProtoTypeLoc Proto =
  3894. TInfo->getTypeLoc().getAs<FunctionProtoTypeLoc>();
  3895. SmallVector<ParmVarDecl*, g_MaxIntrinsicParamCount> Params;
  3896. for (unsigned int i = 1; i < parameterTypeCount; i++) {
  3897. IdentifierInfo* id = &m_context->Idents.get(StringRef(intrinsic->pArgs[i - 1].pName));
  3898. ParmVarDecl *paramDecl = ParmVarDecl::Create(
  3899. *m_context, nullptr, NoLoc, NoLoc, id, parameterTypes[i], nullptr,
  3900. StorageClass::SC_None, nullptr, paramMods[i - 1]);
  3901. Params.push_back(paramDecl);
  3902. }
  3903. QualType T = TInfo->getType();
  3904. DeclarationNameInfo NameInfo(FunctionTemplate->getDeclName(), NoLoc);
  3905. CXXMethodDecl* method = CXXMethodDecl::Create(
  3906. *m_context, dyn_cast<CXXRecordDecl>(owner), NoLoc, NameInfo, T, TInfo,
  3907. SC_Extern, InlineSpecifiedFalse, IsConstexprFalse, NoLoc);
  3908. // Add intrinsic attr
  3909. AddHLSLIntrinsicAttr(method, *m_context, tableName, lowering, intrinsic);
  3910. // Record this function template specialization.
  3911. TemplateArgumentList *argListCopy = TemplateArgumentList::CreateCopy(
  3912. *m_context, templateArgs.data(), templateArgs.size());
  3913. method->setFunctionTemplateSpecialization(FunctionTemplate, argListCopy, 0);
  3914. // Attach the parameters
  3915. for (unsigned P = 0; P < Params.size(); ++P) {
  3916. Params[P]->setOwningFunction(method);
  3917. Proto.setParam(P, Params[P]);
  3918. }
  3919. method->setParams(Params);
  3920. // Adjust access.
  3921. method->setAccess(AccessSpecifier::AS_public);
  3922. FunctionTemplate->setAccess(method->getAccess());
  3923. return method;
  3924. }
  3925. // Overload support.
  3926. UINT64 ScoreCast(QualType leftType, QualType rightType);
  3927. UINT64 ScoreFunction(OverloadCandidateSet::iterator &Cand);
  3928. UINT64 ScoreImplicitConversionSequence(const ImplicitConversionSequence *s);
  3929. unsigned GetNumElements(QualType anyType);
  3930. unsigned GetNumBasicElements(QualType anyType);
  3931. unsigned GetNumConvertCheckElts(QualType leftType, unsigned leftSize, QualType rightType, unsigned rightSize);
  3932. QualType GetNthElementType(QualType type, unsigned index);
  3933. bool IsPromotion(ArBasicKind leftKind, ArBasicKind rightKind);
  3934. bool IsCast(ArBasicKind leftKind, ArBasicKind rightKind);
  3935. bool IsIntCast(ArBasicKind leftKind, ArBasicKind rightKind);
  3936. };
  3937. TYPE_CONVERSION_REMARKS HLSLExternalSource::RemarksUnused = TYPE_CONVERSION_REMARKS::TYPE_CONVERSION_NONE;
  3938. ImplicitConversionKind HLSLExternalSource::ImplicitConversionKindUnused = ImplicitConversionKind::ICK_Identity;
  3939. // Use this class to flatten a type into HLSL primitives and iterate through them.
  3940. class FlattenedTypeIterator
  3941. {
  3942. private:
  3943. enum FlattenedIterKind {
  3944. FK_Simple,
  3945. FK_Fields,
  3946. FK_Expressions,
  3947. FK_IncompleteArray,
  3948. FK_Bases,
  3949. };
  3950. // Use this struct to represent a specific point in the tracked tree.
  3951. struct FlattenedTypeTracker {
  3952. QualType Type; // Type at this position in the tree.
  3953. unsigned int Count; // Count of consecutive types
  3954. CXXRecordDecl::base_class_iterator CurrentBase; // Current base for a structure type.
  3955. CXXRecordDecl::base_class_iterator EndBase; // STL-style end of bases.
  3956. RecordDecl::field_iterator CurrentField; // Current field in for a structure type.
  3957. RecordDecl::field_iterator EndField; // STL-style end of fields.
  3958. MultiExprArg::iterator CurrentExpr; // Current expression (advanceable for a list of expressions).
  3959. MultiExprArg::iterator EndExpr; // STL-style end of expressions.
  3960. FlattenedIterKind IterKind; // Kind of tracker.
  3961. bool IsConsidered; // If a FlattenedTypeTracker already been considered.
  3962. FlattenedTypeTracker(QualType type)
  3963. : Type(type), Count(0), CurrentExpr(nullptr),
  3964. IterKind(FK_IncompleteArray), IsConsidered(false) {}
  3965. FlattenedTypeTracker(QualType type, unsigned int count,
  3966. MultiExprArg::iterator expression)
  3967. : Type(type), Count(count), CurrentExpr(expression),
  3968. IterKind(FK_Simple), IsConsidered(false) {}
  3969. FlattenedTypeTracker(QualType type, RecordDecl::field_iterator current,
  3970. RecordDecl::field_iterator end)
  3971. : Type(type), Count(0), CurrentField(current), EndField(end),
  3972. CurrentExpr(nullptr), IterKind(FK_Fields), IsConsidered(false) {}
  3973. FlattenedTypeTracker(MultiExprArg::iterator current,
  3974. MultiExprArg::iterator end)
  3975. : Count(0), CurrentExpr(current), EndExpr(end),
  3976. IterKind(FK_Expressions), IsConsidered(false) {}
  3977. FlattenedTypeTracker(QualType type,
  3978. CXXRecordDecl::base_class_iterator current,
  3979. CXXRecordDecl::base_class_iterator end)
  3980. : Count(0), CurrentBase(current), EndBase(end), CurrentExpr(nullptr),
  3981. IterKind(FK_Bases), IsConsidered(false) {}
  3982. /// <summary>Gets the current expression if one is available.</summary>
  3983. Expr* getExprOrNull() const { return CurrentExpr ? *CurrentExpr : nullptr; }
  3984. /// <summary>Replaces the current expression.</summary>
  3985. void replaceExpr(Expr* e) { *CurrentExpr = e; }
  3986. };
  3987. HLSLExternalSource& m_source; // Source driving the iteration.
  3988. SmallVector<FlattenedTypeTracker, 4> m_typeTrackers; // Active stack of trackers.
  3989. bool m_draining; // Whether the iterator is meant to drain (will not generate new elements in incomplete arrays).
  3990. bool m_springLoaded; // Whether the current element has been set up by an incomplete array but hasn't been used yet.
  3991. unsigned int m_incompleteCount; // The number of elements in an incomplete array.
  3992. size_t m_typeDepth; // Depth of type analysis, to avoid stack overflows.
  3993. QualType m_firstType; // Name of first type found, used for diagnostics.
  3994. SourceLocation m_loc; // Location used for diagnostics.
  3995. static const size_t MaxTypeDepth = 100;
  3996. void advanceLeafTracker();
  3997. /// <summary>Consumes leaves.</summary>
  3998. void consumeLeaf();
  3999. /// <summary>Considers whether the leaf has a usable expression without consuming anything.</summary>
  4000. bool considerLeaf();
  4001. /// <summary>Pushes a tracker for the specified expression; returns true if there is something to evaluate.</summary>
  4002. bool pushTrackerForExpression(MultiExprArg::iterator expression);
  4003. /// <summary>Pushes a tracker for the specified type; returns true if there is something to evaluate.</summary>
  4004. bool pushTrackerForType(QualType type, _In_opt_ MultiExprArg::iterator expression);
  4005. public:
  4006. /// <summary>Constructs a FlattenedTypeIterator for the specified type.</summary>
  4007. FlattenedTypeIterator(SourceLocation loc, QualType type, HLSLExternalSource& source);
  4008. /// <summary>Constructs a FlattenedTypeIterator for the specified arguments.</summary>
  4009. FlattenedTypeIterator(SourceLocation loc, MultiExprArg args, HLSLExternalSource& source);
  4010. /// <summary>Gets the current element in the flattened type hierarchy.</summary>
  4011. QualType getCurrentElement() const;
  4012. /// <summary>Get the number of repeated current elements.</summary>
  4013. unsigned int getCurrentElementSize() const;
  4014. /// <summary>Checks whether the iterator has a current element type to report.</summary>
  4015. bool hasCurrentElement() const;
  4016. /// <summary>Consumes count elements on this iterator.</summary>
  4017. void advanceCurrentElement(unsigned int count);
  4018. /// <summary>Counts the remaining elements in this iterator (consuming all elements).</summary>
  4019. unsigned int countRemaining();
  4020. /// <summary>Gets the current expression if one is available.</summary>
  4021. Expr* getExprOrNull() const { return m_typeTrackers.back().getExprOrNull(); }
  4022. /// <summary>Replaces the current expression.</summary>
  4023. void replaceExpr(Expr* e) { m_typeTrackers.back().replaceExpr(e); }
  4024. struct ComparisonResult
  4025. {
  4026. unsigned int LeftCount;
  4027. unsigned int RightCount;
  4028. /// <summary>Whether elements from right sequence are identical into left sequence elements.</summary>
  4029. bool AreElementsEqual;
  4030. /// <summary>Whether elements from right sequence can be converted into left sequence elements.</summary>
  4031. bool CanConvertElements;
  4032. /// <summary>Whether the elements can be converted and the sequences have the same length.</summary>
  4033. bool IsConvertibleAndEqualLength() const {
  4034. return LeftCount == RightCount;
  4035. }
  4036. /// <summary>Whether the elements can be converted but the left-hand sequence is longer.</summary>
  4037. bool IsConvertibleAndLeftLonger() const {
  4038. return CanConvertElements && LeftCount > RightCount;
  4039. }
  4040. bool IsRightLonger() const {
  4041. return RightCount > LeftCount;
  4042. }
  4043. };
  4044. static ComparisonResult CompareIterators(
  4045. HLSLExternalSource& source, SourceLocation loc,
  4046. FlattenedTypeIterator& leftIter, FlattenedTypeIterator& rightIter);
  4047. static ComparisonResult CompareTypes(
  4048. HLSLExternalSource& source,
  4049. SourceLocation leftLoc, SourceLocation rightLoc,
  4050. QualType left, QualType right);
  4051. // Compares the arguments to initialize the left type, modifying them if necessary.
  4052. static ComparisonResult CompareTypesForInit(
  4053. HLSLExternalSource& source, QualType left, MultiExprArg args,
  4054. SourceLocation leftLoc, SourceLocation rightLoc);
  4055. };
  4056. static
  4057. QualType GetFirstElementTypeFromDecl(const Decl* decl)
  4058. {
  4059. const ClassTemplateSpecializationDecl* specialization = dyn_cast<ClassTemplateSpecializationDecl>(decl);
  4060. if (specialization) {
  4061. const TemplateArgumentList& list = specialization->getTemplateArgs();
  4062. if (list.size()) {
  4063. return list[0].getAsType();
  4064. }
  4065. }
  4066. return QualType();
  4067. }
  4068. void HLSLExternalSource::AddBaseTypes()
  4069. {
  4070. DXASSERT(m_baseTypes[HLSLScalarType_unknown].isNull(), "otherwise unknown was initialized to an actual type");
  4071. m_baseTypes[HLSLScalarType_bool] = m_context->BoolTy;
  4072. m_baseTypes[HLSLScalarType_int] = m_context->IntTy;
  4073. m_baseTypes[HLSLScalarType_uint] = m_context->UnsignedIntTy;
  4074. m_baseTypes[HLSLScalarType_dword] = m_context->UnsignedIntTy;
  4075. m_baseTypes[HLSLScalarType_half] = m_context->getLangOpts().UseMinPrecision ? m_context->HalfFloatTy : m_context->HalfTy;
  4076. m_baseTypes[HLSLScalarType_float] = m_context->FloatTy;
  4077. m_baseTypes[HLSLScalarType_double] = m_context->DoubleTy;
  4078. m_baseTypes[HLSLScalarType_float_min10] = m_context->Min10FloatTy;
  4079. m_baseTypes[HLSLScalarType_float_min16] = m_context->Min16FloatTy;
  4080. m_baseTypes[HLSLScalarType_int_min12] = m_context->Min12IntTy;
  4081. m_baseTypes[HLSLScalarType_int_min16] = m_context->Min16IntTy;
  4082. m_baseTypes[HLSLScalarType_uint_min16] = m_context->Min16UIntTy;
  4083. m_baseTypes[HLSLScalarType_float_lit] = m_context->LitFloatTy;
  4084. m_baseTypes[HLSLScalarType_int_lit] = m_context->LitIntTy;
  4085. m_baseTypes[HLSLScalarType_int16] = m_context->ShortTy;
  4086. m_baseTypes[HLSLScalarType_int32] = m_context->IntTy;
  4087. m_baseTypes[HLSLScalarType_int64] = m_context->LongLongTy;
  4088. m_baseTypes[HLSLScalarType_uint16] = m_context->UnsignedShortTy;
  4089. m_baseTypes[HLSLScalarType_uint32] = m_context->UnsignedIntTy;
  4090. m_baseTypes[HLSLScalarType_uint64] = m_context->UnsignedLongLongTy;
  4091. m_baseTypes[HLSLScalarType_float16] = m_context->HalfTy;
  4092. m_baseTypes[HLSLScalarType_float32] = m_context->FloatTy;
  4093. m_baseTypes[HLSLScalarType_float64] = m_context->DoubleTy;
  4094. }
  4095. void HLSLExternalSource::AddHLSLScalarTypes()
  4096. {
  4097. DXASSERT(m_scalarTypes[HLSLScalarType_unknown].isNull(), "otherwise unknown was initialized to an actual type");
  4098. m_scalarTypes[HLSLScalarType_bool] = m_baseTypes[HLSLScalarType_bool];
  4099. m_scalarTypes[HLSLScalarType_int] = m_baseTypes[HLSLScalarType_int];
  4100. m_scalarTypes[HLSLScalarType_float] = m_baseTypes[HLSLScalarType_float];
  4101. m_scalarTypes[HLSLScalarType_double] = m_baseTypes[HLSLScalarType_double];
  4102. m_scalarTypes[HLSLScalarType_float_lit] = m_baseTypes[HLSLScalarType_float_lit];
  4103. m_scalarTypes[HLSLScalarType_int_lit] = m_baseTypes[HLSLScalarType_int_lit];
  4104. }
  4105. FunctionDecl* HLSLExternalSource::AddSubscriptSpecialization(
  4106. _In_ FunctionTemplateDecl* functionTemplate,
  4107. QualType objectElement,
  4108. const FindStructBasicTypeResult& findResult)
  4109. {
  4110. DXASSERT_NOMSG(functionTemplate != nullptr);
  4111. DXASSERT_NOMSG(!objectElement.isNull());
  4112. DXASSERT_NOMSG(findResult.Found());
  4113. DXASSERT(
  4114. g_ArBasicKindsSubscripts[findResult.BasicKindsAsTypeIndex].SubscriptCardinality > 0,
  4115. "otherwise the template shouldn't have an operator[] that the caller is trying to specialize");
  4116. // Subscript is templated only on its return type.
  4117. // Create the template argument.
  4118. bool isReadWrite = GetBasicKindProps(findResult.Kind) & BPROP_RWBUFFER;
  4119. QualType resultType = objectElement;
  4120. if (isReadWrite)
  4121. resultType = m_context->getLValueReferenceType(resultType, false);
  4122. else {
  4123. // Add const to avoid write.
  4124. resultType = m_context->getConstType(resultType);
  4125. resultType = m_context->getLValueReferenceType(resultType);
  4126. }
  4127. TemplateArgument templateArgument(resultType);
  4128. unsigned subscriptCardinality =
  4129. g_ArBasicKindsSubscripts[findResult.BasicKindsAsTypeIndex].SubscriptCardinality;
  4130. QualType subscriptIndexType =
  4131. subscriptCardinality == 1
  4132. ? m_context->UnsignedIntTy
  4133. : NewSimpleAggregateType(AR_TOBJ_VECTOR, AR_BASIC_UINT32, 0, 1,
  4134. subscriptCardinality);
  4135. // Look for an existing specialization.
  4136. void* InsertPos = nullptr;
  4137. FunctionDecl *SpecFunc = functionTemplate->findSpecialization(ArrayRef<TemplateArgument>(&templateArgument, 1), InsertPos);
  4138. if (SpecFunc != nullptr) {
  4139. return SpecFunc;
  4140. }
  4141. // Create a new specialization.
  4142. DeclContext* owner = functionTemplate->getDeclContext();
  4143. TemplateArgumentList templateArgumentList(
  4144. TemplateArgumentList::OnStackType::OnStack, &templateArgument, 1);
  4145. MultiLevelTemplateArgumentList mlTemplateArgumentList(templateArgumentList);
  4146. TemplateDeclInstantiator declInstantiator(*this->m_sema, owner, mlTemplateArgumentList);
  4147. const FunctionType *templateFnType = functionTemplate->getTemplatedDecl()->getType()->getAs<FunctionType>();
  4148. const FunctionProtoType *protoType = dyn_cast<FunctionProtoType>(templateFnType);
  4149. FunctionProtoType::ExtProtoInfo templateEPI = protoType->getExtProtoInfo();
  4150. QualType functionType = m_context->getFunctionType(
  4151. resultType, subscriptIndexType, templateEPI, None);
  4152. TypeSourceInfo *TInfo = m_context->CreateTypeSourceInfo(functionType, 0);
  4153. FunctionProtoTypeLoc Proto = TInfo->getTypeLoc().getAs<FunctionProtoTypeLoc>();
  4154. IdentifierInfo* id = &m_context->Idents.get(StringRef("index"));
  4155. ParmVarDecl* indexerParam = ParmVarDecl::Create(
  4156. *m_context, nullptr, NoLoc, NoLoc, id, subscriptIndexType, nullptr, StorageClass::SC_None, nullptr);
  4157. QualType T = TInfo->getType();
  4158. DeclarationNameInfo NameInfo(functionTemplate->getDeclName(), NoLoc);
  4159. CXXMethodDecl* method = CXXMethodDecl::Create(
  4160. *m_context, dyn_cast<CXXRecordDecl>(owner), NoLoc, NameInfo, T, TInfo,
  4161. SC_Extern, InlineSpecifiedFalse, IsConstexprFalse, NoLoc);
  4162. // Add subscript attribute
  4163. AddHLSLSubscriptAttr(method, *m_context, HLSubscriptOpcode::DefaultSubscript);
  4164. // Record this function template specialization.
  4165. method->setFunctionTemplateSpecialization(functionTemplate,
  4166. TemplateArgumentList::CreateCopy(*m_context, &templateArgument, 1), 0);
  4167. // Attach the parameters
  4168. indexerParam->setOwningFunction(method);
  4169. Proto.setParam(0, indexerParam);
  4170. method->setParams(ArrayRef<ParmVarDecl*>(indexerParam));
  4171. // Adjust access.
  4172. method->setAccess(AccessSpecifier::AS_public);
  4173. functionTemplate->setAccess(method->getAccess());
  4174. return method;
  4175. }
  4176. /// <summary>
  4177. /// This routine combines Source into Target. If you have a symmetric operation
  4178. /// and want to treat either side equally you should call it twice, swapping the
  4179. /// parameter order.
  4180. /// </summary>
  4181. static bool CombineObjectTypes(ArBasicKind Target, _In_ ArBasicKind Source,
  4182. _Out_opt_ ArBasicKind *pCombined) {
  4183. if (Target == Source) {
  4184. AssignOpt(Target, pCombined);
  4185. return true;
  4186. }
  4187. if (Source == AR_OBJECT_NULL) {
  4188. // NULL is valid for any object type.
  4189. AssignOpt(Target, pCombined);
  4190. return true;
  4191. }
  4192. switch (Target) {
  4193. AR_BASIC_ROBJECT_CASES:
  4194. if (Source == AR_OBJECT_STATEBLOCK) {
  4195. AssignOpt(Target, pCombined);
  4196. return true;
  4197. }
  4198. break;
  4199. AR_BASIC_TEXTURE_CASES:
  4200. AR_BASIC_NON_CMP_SAMPLER_CASES:
  4201. if (Source == AR_OBJECT_SAMPLER || Source == AR_OBJECT_STATEBLOCK) {
  4202. AssignOpt(Target, pCombined);
  4203. return true;
  4204. }
  4205. break;
  4206. case AR_OBJECT_SAMPLERCOMPARISON:
  4207. if (Source == AR_OBJECT_STATEBLOCK) {
  4208. AssignOpt(Target, pCombined);
  4209. return true;
  4210. }
  4211. break;
  4212. default:
  4213. // Not a combinable target.
  4214. break;
  4215. }
  4216. AssignOpt(AR_BASIC_UNKNOWN, pCombined);
  4217. return false;
  4218. }
  4219. static ArBasicKind LiteralToConcrete(Expr *litExpr,
  4220. HLSLExternalSource *pHLSLExternalSource) {
  4221. if (IntegerLiteral *intLit = dyn_cast<IntegerLiteral>(litExpr)) {
  4222. llvm::APInt val = intLit->getValue();
  4223. unsigned width = val.getActiveBits();
  4224. bool isNeg = val.isNegative();
  4225. if (isNeg) {
  4226. // Signed.
  4227. if (width <= 32)
  4228. return ArBasicKind::AR_BASIC_INT32;
  4229. else
  4230. return ArBasicKind::AR_BASIC_INT64;
  4231. } else {
  4232. // Unsigned.
  4233. if (width <= 32)
  4234. return ArBasicKind::AR_BASIC_UINT32;
  4235. else
  4236. return ArBasicKind::AR_BASIC_UINT64;
  4237. }
  4238. } else if (FloatingLiteral *floatLit = dyn_cast<FloatingLiteral>(litExpr)) {
  4239. llvm::APFloat val = floatLit->getValue();
  4240. unsigned width = val.getSizeInBits(val.getSemantics());
  4241. if (width <= 16)
  4242. return ArBasicKind::AR_BASIC_FLOAT16;
  4243. else if (width <= 32)
  4244. return ArBasicKind::AR_BASIC_FLOAT32;
  4245. else
  4246. return AR_BASIC_FLOAT64;
  4247. } else if (UnaryOperator *UO = dyn_cast<UnaryOperator>(litExpr)) {
  4248. ArBasicKind kind = LiteralToConcrete(UO->getSubExpr(), pHLSLExternalSource);
  4249. if (UO->getOpcode() == UnaryOperator::Opcode::UO_Minus) {
  4250. if (kind == ArBasicKind::AR_BASIC_UINT32)
  4251. kind = ArBasicKind::AR_BASIC_INT32;
  4252. else if (kind == ArBasicKind::AR_BASIC_UINT64)
  4253. kind = ArBasicKind::AR_BASIC_INT64;
  4254. }
  4255. return kind;
  4256. } else if (HLSLVectorElementExpr *VEE = dyn_cast<HLSLVectorElementExpr>(litExpr)) {
  4257. return pHLSLExternalSource->GetTypeElementKind(VEE->getType());
  4258. } else if (BinaryOperator *BO = dyn_cast<BinaryOperator>(litExpr)) {
  4259. ArBasicKind kind = LiteralToConcrete(BO->getLHS(), pHLSLExternalSource);
  4260. ArBasicKind kind1 = LiteralToConcrete(BO->getRHS(), pHLSLExternalSource);
  4261. CombineBasicTypes(kind, kind1, &kind);
  4262. return kind;
  4263. } else if (ParenExpr *PE = dyn_cast<ParenExpr>(litExpr)) {
  4264. ArBasicKind kind = LiteralToConcrete(PE->getSubExpr(), pHLSLExternalSource);
  4265. return kind;
  4266. } else if (ConditionalOperator *CO = dyn_cast<ConditionalOperator>(litExpr)) {
  4267. ArBasicKind kind = LiteralToConcrete(CO->getLHS(), pHLSLExternalSource);
  4268. ArBasicKind kind1 = LiteralToConcrete(CO->getRHS(), pHLSLExternalSource);
  4269. CombineBasicTypes(kind, kind1, &kind);
  4270. return kind;
  4271. } else if (ImplicitCastExpr *IC = dyn_cast<ImplicitCastExpr>(litExpr)) {
  4272. // Use target Type for cast.
  4273. ArBasicKind kind = pHLSLExternalSource->GetTypeElementKind(IC->getType());
  4274. return kind;
  4275. } else {
  4276. // Could only be function call.
  4277. CallExpr *CE = cast<CallExpr>(litExpr);
  4278. // TODO: calculate the function call result.
  4279. if (CE->getNumArgs() == 1)
  4280. return LiteralToConcrete(CE->getArg(0), pHLSLExternalSource);
  4281. else {
  4282. ArBasicKind kind = LiteralToConcrete(CE->getArg(0), pHLSLExternalSource);
  4283. for (unsigned i = 1; i < CE->getNumArgs(); i++) {
  4284. ArBasicKind kindI = LiteralToConcrete(CE->getArg(i), pHLSLExternalSource);
  4285. CombineBasicTypes(kind, kindI, &kind);
  4286. }
  4287. return kind;
  4288. }
  4289. }
  4290. }
  4291. static bool SearchTypeInTable(ArBasicKind kind, const ArBasicKind *pCT) {
  4292. while (AR_BASIC_UNKNOWN != *pCT && AR_BASIC_NOCAST != *pCT) {
  4293. if (kind == *pCT)
  4294. return true;
  4295. pCT++;
  4296. }
  4297. return false;
  4298. }
  4299. static ArBasicKind
  4300. ConcreteLiteralType(Expr *litExpr, ArBasicKind kind,
  4301. unsigned uLegalComponentTypes,
  4302. HLSLExternalSource *pHLSLExternalSource) {
  4303. const ArBasicKind *pCT = g_LegalIntrinsicCompTypes[uLegalComponentTypes];
  4304. ArBasicKind defaultKind = *pCT;
  4305. // Use first none literal kind as defaultKind.
  4306. while (AR_BASIC_UNKNOWN != *pCT && AR_BASIC_NOCAST != *pCT) {
  4307. ArBasicKind kind = *pCT;
  4308. pCT++;
  4309. // Skip literal type.
  4310. if (kind == AR_BASIC_LITERAL_INT || kind == AR_BASIC_LITERAL_FLOAT)
  4311. continue;
  4312. defaultKind = kind;
  4313. break;
  4314. }
  4315. ArBasicKind litKind = LiteralToConcrete(litExpr, pHLSLExternalSource);
  4316. if (kind == AR_BASIC_LITERAL_INT) {
  4317. // Search for match first.
  4318. // For literal arg which don't affect return type, the search should always success.
  4319. // Unless use literal int on a float parameter.
  4320. if (SearchTypeInTable(litKind, g_LegalIntrinsicCompTypes[uLegalComponentTypes]))
  4321. return litKind;
  4322. // Return the default.
  4323. return defaultKind;
  4324. }
  4325. else {
  4326. // Search for float32 first.
  4327. if (SearchTypeInTable(AR_BASIC_FLOAT32, g_LegalIntrinsicCompTypes[uLegalComponentTypes]))
  4328. return AR_BASIC_FLOAT32;
  4329. // Search for float64.
  4330. if (SearchTypeInTable(AR_BASIC_FLOAT64, g_LegalIntrinsicCompTypes[uLegalComponentTypes]))
  4331. return AR_BASIC_FLOAT64;
  4332. // return default.
  4333. return defaultKind;
  4334. }
  4335. }
  4336. _Use_decl_annotations_ bool
  4337. HLSLExternalSource::IsValidateObjectElement(const HLSL_INTRINSIC *pIntrinsic,
  4338. QualType objectElement) {
  4339. IntrinsicOp op = static_cast<IntrinsicOp>(pIntrinsic->Op);
  4340. switch (op) {
  4341. case IntrinsicOp::MOP_Sample:
  4342. case IntrinsicOp::MOP_SampleBias:
  4343. case IntrinsicOp::MOP_SampleCmp:
  4344. case IntrinsicOp::MOP_SampleCmpLevelZero:
  4345. case IntrinsicOp::MOP_SampleGrad:
  4346. case IntrinsicOp::MOP_SampleLevel: {
  4347. ArBasicKind kind = GetTypeElementKind(objectElement);
  4348. UINT uBits = GET_BPROP_BITS(kind);
  4349. return IS_BASIC_FLOAT(kind) && uBits != BPROP_BITS64;
  4350. } break;
  4351. default:
  4352. return true;
  4353. }
  4354. }
  4355. _Use_decl_annotations_
  4356. bool HLSLExternalSource::MatchArguments(
  4357. const HLSL_INTRINSIC* pIntrinsic,
  4358. QualType objectElement,
  4359. ArrayRef<Expr *> Args,
  4360. QualType(&argTypes)[g_MaxIntrinsicParamCount + 1],
  4361. size_t* argCount)
  4362. {
  4363. DXASSERT_NOMSG(pIntrinsic != nullptr);
  4364. DXASSERT_NOMSG(argCount != nullptr);
  4365. static const UINT UnusedSize = 0xFF;
  4366. static const BYTE MaxIntrinsicArgs = g_MaxIntrinsicParamCount + 1;
  4367. #define CAB(_) { if (!(_)) return false; }
  4368. *argCount = 0;
  4369. ArTypeObjectKind Template[MaxIntrinsicArgs]; // Template type for each argument, AR_TOBJ_UNKNOWN if unspecified.
  4370. ArBasicKind ComponentType[MaxIntrinsicArgs]; // Component type for each argument, AR_BASIC_UNKNOWN if unspecified.
  4371. UINT uSpecialSize[IA_SPECIAL_SLOTS]; // row/col matching types, UNUSED_INDEX32 if unspecified.
  4372. // Reset infos
  4373. std::fill(Template, Template + _countof(Template), AR_TOBJ_UNKNOWN);
  4374. std::fill(ComponentType, ComponentType + _countof(ComponentType), AR_BASIC_UNKNOWN);
  4375. std::fill(uSpecialSize, uSpecialSize + _countof(uSpecialSize), UnusedSize);
  4376. const unsigned retArgIdx = 0;
  4377. unsigned retTypeIdx = pIntrinsic->pArgs[retArgIdx].uComponentTypeId;
  4378. // Populate the template for each argument.
  4379. ArrayRef<Expr*>::iterator iterArg = Args.begin();
  4380. ArrayRef<Expr*>::iterator end = Args.end();
  4381. unsigned int iArg = 1;
  4382. for (; iterArg != end; ++iterArg) {
  4383. Expr* pCallArg = *iterArg;
  4384. // No vararg support.
  4385. if (iArg >= _countof(Template) || iArg > pIntrinsic->uNumArgs) {
  4386. return false;
  4387. }
  4388. const HLSL_INTRINSIC_ARGUMENT *pIntrinsicArg;
  4389. pIntrinsicArg = &pIntrinsic->pArgs[iArg];
  4390. DXASSERT(pIntrinsicArg->uTemplateId != INTRIN_TEMPLATE_VARARGS, "no vararg support");
  4391. QualType pType = pCallArg->getType();
  4392. ArTypeObjectKind TypeInfoShapeKind = GetTypeObjectKind(pType);
  4393. ArBasicKind TypeInfoEltKind = GetTypeElementKind(pType);
  4394. if (pIntrinsicArg->uLegalComponentTypes == LICOMPTYPE_RAYDESC) {
  4395. if (TypeInfoShapeKind == AR_TOBJ_COMPOUND) {
  4396. if (CXXRecordDecl *pDecl = pType->getAsCXXRecordDecl()) {
  4397. int index = FindObjectBasicKindIndex(pDecl);
  4398. if (index != -1 && AR_OBJECT_RAY_DESC == g_ArBasicKindsAsTypes[index]) {
  4399. ++iArg;
  4400. continue;
  4401. }
  4402. }
  4403. }
  4404. m_sema->Diag(pCallArg->getExprLoc(),
  4405. diag::err_hlsl_ray_desc_required);
  4406. return false;
  4407. }
  4408. if (pIntrinsicArg->uLegalComponentTypes == LICOMPTYPE_USER_DEFINED_TYPE) {
  4409. DXASSERT(objectElement.isNull(), "");
  4410. QualType Ty = pCallArg->getType();
  4411. // Must be user define type for LICOMPTYPE_USER_DEFINED_TYPE arg.
  4412. if (TypeInfoShapeKind != AR_TOBJ_COMPOUND) {
  4413. m_sema->Diag(pCallArg->getExprLoc(),
  4414. diag::err_hlsl_no_struct_user_defined_type);
  4415. return false;
  4416. }
  4417. objectElement = Ty;
  4418. ++iArg;
  4419. continue;
  4420. }
  4421. // If we are a type and templateID requires one, this isn't a match.
  4422. if (pIntrinsicArg->uTemplateId == INTRIN_TEMPLATE_FROM_TYPE) {
  4423. ++iArg;
  4424. continue;
  4425. }
  4426. if (TypeInfoEltKind == AR_BASIC_LITERAL_INT ||
  4427. TypeInfoEltKind == AR_BASIC_LITERAL_FLOAT) {
  4428. bool affectRetType =
  4429. (iArg != retArgIdx && retTypeIdx == pIntrinsicArg->uComponentTypeId);
  4430. // For literal arg which don't affect return type, find concrete type.
  4431. // For literal arg affect return type,
  4432. // TryEvalIntrinsic in CGHLSLMS.cpp will take care of cases
  4433. // where all argumentss are literal.
  4434. // CombineBasicTypes will cover the rest cases.
  4435. if (!affectRetType) {
  4436. TypeInfoEltKind = ConcreteLiteralType(
  4437. pCallArg, TypeInfoEltKind, pIntrinsicArg->uLegalComponentTypes, this);
  4438. }
  4439. }
  4440. UINT TypeInfoCols = 1;
  4441. UINT TypeInfoRows = 1;
  4442. switch (TypeInfoShapeKind) {
  4443. case AR_TOBJ_MATRIX:
  4444. GetRowsAndCols(pType, TypeInfoRows, TypeInfoCols);
  4445. break;
  4446. case AR_TOBJ_VECTOR:
  4447. TypeInfoCols = GetHLSLVecSize(pType);
  4448. break;
  4449. case AR_TOBJ_BASIC:
  4450. case AR_TOBJ_OBJECT:
  4451. break;
  4452. default:
  4453. return false; // no struct, arrays or void
  4454. }
  4455. DXASSERT(
  4456. pIntrinsicArg->uTemplateId < MaxIntrinsicArgs,
  4457. "otherwise intrinsic table was modified and g_MaxIntrinsicParamCount was not updated (or uTemplateId is out of bounds)");
  4458. // Compare template
  4459. if ((AR_TOBJ_UNKNOWN == Template[pIntrinsicArg->uTemplateId]) ||
  4460. ((AR_TOBJ_SCALAR == Template[pIntrinsicArg->uTemplateId]) &&
  4461. (AR_TOBJ_VECTOR == TypeInfoShapeKind || AR_TOBJ_MATRIX == TypeInfoShapeKind))) {
  4462. Template[pIntrinsicArg->uTemplateId] = TypeInfoShapeKind;
  4463. }
  4464. else if (AR_TOBJ_SCALAR == TypeInfoShapeKind) {
  4465. if (AR_TOBJ_SCALAR != Template[pIntrinsicArg->uTemplateId] &&
  4466. AR_TOBJ_VECTOR != Template[pIntrinsicArg->uTemplateId] &&
  4467. AR_TOBJ_MATRIX != Template[pIntrinsicArg->uTemplateId]) {
  4468. return false;
  4469. }
  4470. }
  4471. else {
  4472. if (TypeInfoShapeKind != Template[pIntrinsicArg->uTemplateId]) {
  4473. return false;
  4474. }
  4475. }
  4476. DXASSERT(
  4477. pIntrinsicArg->uComponentTypeId < MaxIntrinsicArgs,
  4478. "otherwise intrinsic table was modified and MaxIntrinsicArgs was not updated (or uComponentTypeId is out of bounds)");
  4479. // Merge ComponentTypes
  4480. if (AR_BASIC_UNKNOWN == ComponentType[pIntrinsicArg->uComponentTypeId]) {
  4481. ComponentType[pIntrinsicArg->uComponentTypeId] = TypeInfoEltKind;
  4482. }
  4483. else {
  4484. if (!CombineBasicTypes(
  4485. ComponentType[pIntrinsicArg->uComponentTypeId],
  4486. TypeInfoEltKind,
  4487. &ComponentType[pIntrinsicArg->uComponentTypeId])) {
  4488. return false;
  4489. }
  4490. }
  4491. // Rows
  4492. if (AR_TOBJ_SCALAR != TypeInfoShapeKind) {
  4493. if (pIntrinsicArg->uRows >= IA_SPECIAL_BASE) {
  4494. UINT uSpecialId = pIntrinsicArg->uRows - IA_SPECIAL_BASE;
  4495. CAB(uSpecialId < IA_SPECIAL_SLOTS);
  4496. if (uSpecialSize[uSpecialId] > TypeInfoRows) {
  4497. uSpecialSize[uSpecialId] = TypeInfoRows;
  4498. }
  4499. }
  4500. else {
  4501. if (TypeInfoRows < pIntrinsicArg->uRows) {
  4502. return false;
  4503. }
  4504. }
  4505. }
  4506. // Columns
  4507. if (AR_TOBJ_SCALAR != TypeInfoShapeKind) {
  4508. if (pIntrinsicArg->uCols >= IA_SPECIAL_BASE) {
  4509. UINT uSpecialId = pIntrinsicArg->uCols - IA_SPECIAL_BASE;
  4510. CAB(uSpecialId < IA_SPECIAL_SLOTS);
  4511. if (uSpecialSize[uSpecialId] > TypeInfoCols) {
  4512. uSpecialSize[uSpecialId] = TypeInfoCols;
  4513. }
  4514. }
  4515. else {
  4516. if (TypeInfoCols < pIntrinsicArg->uCols) {
  4517. return false;
  4518. }
  4519. }
  4520. }
  4521. // Usage
  4522. if (pIntrinsicArg->qwUsage & AR_QUAL_OUT) {
  4523. if (pCallArg->getType().isConstQualified()) {
  4524. // Can't use a const type in an out or inout parameter.
  4525. return false;
  4526. }
  4527. }
  4528. iArg++;
  4529. }
  4530. DXASSERT(iterArg == end, "otherwise the argument list wasn't fully processed");
  4531. // Default template and component type for return value
  4532. if (pIntrinsic->pArgs[0].qwUsage && pIntrinsic->pArgs[0].uTemplateId != INTRIN_TEMPLATE_FROM_TYPE) {
  4533. CAB(pIntrinsic->pArgs[0].uTemplateId < MaxIntrinsicArgs);
  4534. if (AR_TOBJ_UNKNOWN == Template[pIntrinsic->pArgs[0].uTemplateId]) {
  4535. Template[pIntrinsic->pArgs[0].uTemplateId] =
  4536. g_LegalIntrinsicTemplates[pIntrinsic->pArgs[0].uLegalTemplates][0];
  4537. if (pIntrinsic->pArgs[0].uComponentTypeId != INTRIN_COMPTYPE_FROM_TYPE_ELT0) {
  4538. DXASSERT_NOMSG(pIntrinsic->pArgs[0].uComponentTypeId < MaxIntrinsicArgs);
  4539. if (AR_BASIC_UNKNOWN == ComponentType[pIntrinsic->pArgs[0].uComponentTypeId]) {
  4540. // half return type should map to float for min precision
  4541. if (pIntrinsic->pArgs[0].uLegalComponentTypes ==
  4542. LEGAL_INTRINSIC_COMPTYPES::LICOMPTYPE_FLOAT16 &&
  4543. getSema()->getLangOpts().UseMinPrecision) {
  4544. ComponentType[pIntrinsic->pArgs[0].uComponentTypeId] =
  4545. ArBasicKind::AR_BASIC_FLOAT32;
  4546. }
  4547. else {
  4548. ComponentType[pIntrinsic->pArgs[0].uComponentTypeId] =
  4549. g_LegalIntrinsicCompTypes[pIntrinsic->pArgs[0].uLegalComponentTypes][0];
  4550. }
  4551. }
  4552. }
  4553. }
  4554. }
  4555. // Make sure all template, component type, and texture type selections are valid.
  4556. for (size_t i = 0; i < Args.size() + 1; i++) {
  4557. const HLSL_INTRINSIC_ARGUMENT *pArgument = &pIntrinsic->pArgs[i];
  4558. // Check template.
  4559. if (pArgument->uTemplateId == INTRIN_TEMPLATE_FROM_TYPE) {
  4560. continue; // Already verified that this is available.
  4561. }
  4562. if (pArgument->uLegalComponentTypes == LICOMPTYPE_USER_DEFINED_TYPE) {
  4563. continue;
  4564. }
  4565. const ArTypeObjectKind *pTT = g_LegalIntrinsicTemplates[pArgument->uLegalTemplates];
  4566. if (AR_TOBJ_UNKNOWN != Template[i]) {
  4567. if ((AR_TOBJ_SCALAR == Template[i]) && (AR_TOBJ_VECTOR == *pTT || AR_TOBJ_MATRIX == *pTT)) {
  4568. Template[i] = *pTT;
  4569. }
  4570. else {
  4571. while (AR_TOBJ_UNKNOWN != *pTT) {
  4572. if (Template[i] == *pTT)
  4573. break;
  4574. pTT++;
  4575. }
  4576. }
  4577. if (AR_TOBJ_UNKNOWN == *pTT)
  4578. return false;
  4579. }
  4580. else if (pTT) {
  4581. Template[i] = *pTT;
  4582. }
  4583. // Check component type.
  4584. const ArBasicKind *pCT = g_LegalIntrinsicCompTypes[pArgument->uLegalComponentTypes];
  4585. if (AR_BASIC_UNKNOWN != ComponentType[i]) {
  4586. while (AR_BASIC_UNKNOWN != *pCT && AR_BASIC_NOCAST != *pCT) {
  4587. if (ComponentType[i] == *pCT)
  4588. break;
  4589. pCT++;
  4590. }
  4591. // has to be a strict match
  4592. if (*pCT == AR_BASIC_NOCAST)
  4593. return false;
  4594. // If it is an object, see if it can be cast to the first thing in the
  4595. // list, otherwise move on to next intrinsic.
  4596. if (AR_TOBJ_OBJECT == Template[i] && AR_BASIC_UNKNOWN == *pCT) {
  4597. if (!CombineObjectTypes(g_LegalIntrinsicCompTypes[pArgument->uLegalComponentTypes][0], ComponentType[i], nullptr)) {
  4598. return false;
  4599. }
  4600. }
  4601. if (AR_BASIC_UNKNOWN == *pCT) {
  4602. ComponentType[i] = g_LegalIntrinsicCompTypes[pArgument->uLegalComponentTypes][0];
  4603. }
  4604. }
  4605. else if (pCT) {
  4606. ComponentType[i] = *pCT;
  4607. }
  4608. }
  4609. // Default to a void return type.
  4610. argTypes[0] = m_context->VoidTy;
  4611. // Default specials sizes.
  4612. for (UINT i = 0; i < IA_SPECIAL_SLOTS; i++) {
  4613. if (UnusedSize == uSpecialSize[i]) {
  4614. uSpecialSize[i] = 1;
  4615. }
  4616. }
  4617. // Populate argTypes.
  4618. for (size_t i = 0; i <= Args.size(); i++) {
  4619. const HLSL_INTRINSIC_ARGUMENT *pArgument = &pIntrinsic->pArgs[i];
  4620. if (!pArgument->qwUsage)
  4621. continue;
  4622. QualType pNewType;
  4623. unsigned int quals = 0; // qualifications for this argument
  4624. // If we have no type, set it to our input type (templatized)
  4625. if (pArgument->uTemplateId == INTRIN_TEMPLATE_FROM_TYPE) {
  4626. // Use the templated input type, but resize it if the
  4627. // intrinsic's rows/cols isn't 0
  4628. if (pArgument->uRows && pArgument->uCols) {
  4629. UINT uRows, uCols = 0;
  4630. // if type is overriden, use new type size, for
  4631. // now it only supports scalars
  4632. if (pArgument->uRows >= IA_SPECIAL_BASE) {
  4633. UINT uSpecialId = pArgument->uRows - IA_SPECIAL_BASE;
  4634. CAB(uSpecialId < IA_SPECIAL_SLOTS);
  4635. uRows = uSpecialSize[uSpecialId];
  4636. }
  4637. else if (pArgument->uRows > 0) {
  4638. uRows = pArgument->uRows;
  4639. }
  4640. if (pArgument->uCols >= IA_SPECIAL_BASE) {
  4641. UINT uSpecialId = pArgument->uCols - IA_SPECIAL_BASE;
  4642. CAB(uSpecialId < IA_SPECIAL_SLOTS);
  4643. uCols = uSpecialSize[uSpecialId];
  4644. }
  4645. else if (pArgument->uCols > 0) {
  4646. uCols = pArgument->uCols;
  4647. }
  4648. // 1x1 numeric outputs are always scalar.. since these
  4649. // are most flexible
  4650. if ((1 == uCols) && (1 == uRows)) {
  4651. pNewType = objectElement;
  4652. if (pNewType.isNull()) {
  4653. return false;
  4654. }
  4655. }
  4656. else {
  4657. // non-scalars unsupported right now since nothing
  4658. // uses it, would have to create either a type
  4659. // list for sub-structures or just resize the
  4660. // given type
  4661. // VH(E_NOTIMPL);
  4662. return false;
  4663. }
  4664. }
  4665. else {
  4666. DXASSERT_NOMSG(!pArgument->uRows && !pArgument->uCols);
  4667. if (objectElement.isNull()) {
  4668. return false;
  4669. }
  4670. pNewType = objectElement;
  4671. }
  4672. } else if (pArgument->uLegalComponentTypes == LICOMPTYPE_USER_DEFINED_TYPE) {
  4673. if (objectElement.isNull()) {
  4674. return false;
  4675. }
  4676. pNewType = objectElement;
  4677. } else {
  4678. ArBasicKind pEltType;
  4679. // ComponentType, if the Id is special then it gets the
  4680. // component type from the first component of the type, if
  4681. // we need more (for the second component, e.g.), then we
  4682. // can use more specials, etc.
  4683. if (pArgument->uComponentTypeId == INTRIN_COMPTYPE_FROM_TYPE_ELT0) {
  4684. if (objectElement.isNull()) {
  4685. return false;
  4686. }
  4687. pEltType = GetTypeElementKind(objectElement);
  4688. DXASSERT_VALIDBASICKIND(pEltType);
  4689. }
  4690. else {
  4691. pEltType = ComponentType[pArgument->uComponentTypeId];
  4692. DXASSERT_VALIDBASICKIND(pEltType);
  4693. }
  4694. UINT uRows, uCols;
  4695. // Rows
  4696. if (pArgument->uRows >= IA_SPECIAL_BASE) {
  4697. UINT uSpecialId = pArgument->uRows - IA_SPECIAL_BASE;
  4698. CAB(uSpecialId < IA_SPECIAL_SLOTS);
  4699. uRows = uSpecialSize[uSpecialId];
  4700. }
  4701. else {
  4702. uRows = pArgument->uRows;
  4703. }
  4704. // Cols
  4705. if (pArgument->uCols >= IA_SPECIAL_BASE) {
  4706. UINT uSpecialId = pArgument->uCols - IA_SPECIAL_BASE;
  4707. CAB(uSpecialId < IA_SPECIAL_SLOTS);
  4708. uCols = uSpecialSize[uSpecialId];
  4709. }
  4710. else {
  4711. uCols = pArgument->uCols;
  4712. }
  4713. // Verify that the final results are in bounds.
  4714. CAB(uCols > 0 && uCols <= MaxVectorSize && uRows > 0 && uRows <= MaxVectorSize);
  4715. // Const
  4716. UINT64 qwQual = pArgument->qwUsage & (AR_QUAL_ROWMAJOR | AR_QUAL_COLMAJOR);
  4717. if ((0 == i) || !(pArgument->qwUsage & AR_QUAL_OUT))
  4718. qwQual |= AR_QUAL_CONST;
  4719. DXASSERT_VALIDBASICKIND(pEltType);
  4720. pNewType = NewSimpleAggregateType(Template[pArgument->uTemplateId], pEltType, qwQual, uRows, uCols);
  4721. }
  4722. DXASSERT(!pNewType.isNull(), "otherwise there's a branch in this function that fails to assign this");
  4723. argTypes[i] = QualType(pNewType.getTypePtr(), quals);
  4724. // TODO: support out modifier
  4725. //if (pArgument->qwUsage & AR_QUAL_OUT) {
  4726. // argTypes[i] = m_context->getLValueReferenceType(argTypes[i].withConst());
  4727. //}
  4728. }
  4729. *argCount = iArg;
  4730. DXASSERT(
  4731. *argCount == pIntrinsic->uNumArgs,
  4732. "In the absence of varargs, a successful match would indicate we have as many arguments and types as the intrinsic template");
  4733. return true;
  4734. #undef CAB
  4735. }
  4736. _Use_decl_annotations_
  4737. HLSLExternalSource::FindStructBasicTypeResult
  4738. HLSLExternalSource::FindStructBasicType(DeclContext* functionDeclContext)
  4739. {
  4740. DXASSERT_NOMSG(functionDeclContext != nullptr);
  4741. // functionDeclContext may be a specialization of a template, such as AppendBuffer<MY_STRUCT>, or it
  4742. // may be a simple class, such as RWByteAddressBuffer.
  4743. const CXXRecordDecl* recordDecl = GetRecordDeclForBuiltInOrStruct(functionDeclContext);
  4744. // We save the caller from filtering out other types of context (like the translation unit itself).
  4745. if (recordDecl != nullptr)
  4746. {
  4747. int index = FindObjectBasicKindIndex(recordDecl);
  4748. if (index != -1) {
  4749. ArBasicKind kind = g_ArBasicKindsAsTypes[index];
  4750. return HLSLExternalSource::FindStructBasicTypeResult(kind, index);
  4751. }
  4752. }
  4753. return HLSLExternalSource::FindStructBasicTypeResult(AR_BASIC_UNKNOWN, 0);
  4754. }
  4755. _Use_decl_annotations_
  4756. void HLSLExternalSource::FindIntrinsicTable(DeclContext* functionDeclContext, const char** name, const HLSL_INTRINSIC** intrinsics, size_t* intrinsicCount)
  4757. {
  4758. DXASSERT_NOMSG(functionDeclContext != nullptr);
  4759. DXASSERT_NOMSG(name != nullptr);
  4760. DXASSERT_NOMSG(intrinsics != nullptr);
  4761. DXASSERT_NOMSG(intrinsicCount != nullptr);
  4762. *intrinsics = nullptr;
  4763. *intrinsicCount = 0;
  4764. *name = nullptr;
  4765. HLSLExternalSource::FindStructBasicTypeResult lookup = FindStructBasicType(functionDeclContext);
  4766. if (lookup.Found()) {
  4767. GetIntrinsicMethods(lookup.Kind, intrinsics, intrinsicCount);
  4768. *name = g_ArBasicTypeNames[lookup.Kind];
  4769. }
  4770. }
  4771. static bool BinaryOperatorKindIsArithmetic(BinaryOperatorKind Opc)
  4772. {
  4773. return
  4774. // Arithmetic operators.
  4775. Opc == BinaryOperatorKind::BO_Add ||
  4776. Opc == BinaryOperatorKind::BO_AddAssign ||
  4777. Opc == BinaryOperatorKind::BO_Sub ||
  4778. Opc == BinaryOperatorKind::BO_SubAssign ||
  4779. Opc == BinaryOperatorKind::BO_Rem ||
  4780. Opc == BinaryOperatorKind::BO_RemAssign ||
  4781. Opc == BinaryOperatorKind::BO_Div ||
  4782. Opc == BinaryOperatorKind::BO_DivAssign ||
  4783. Opc == BinaryOperatorKind::BO_Mul ||
  4784. Opc == BinaryOperatorKind::BO_MulAssign;
  4785. }
  4786. static bool BinaryOperatorKindIsCompoundAssignment(BinaryOperatorKind Opc)
  4787. {
  4788. return
  4789. // Arithmetic-and-assignment operators.
  4790. Opc == BinaryOperatorKind::BO_AddAssign ||
  4791. Opc == BinaryOperatorKind::BO_SubAssign ||
  4792. Opc == BinaryOperatorKind::BO_RemAssign ||
  4793. Opc == BinaryOperatorKind::BO_DivAssign ||
  4794. Opc == BinaryOperatorKind::BO_MulAssign ||
  4795. // Bitwise-and-assignment operators.
  4796. Opc == BinaryOperatorKind::BO_ShlAssign ||
  4797. Opc == BinaryOperatorKind::BO_ShrAssign ||
  4798. Opc == BinaryOperatorKind::BO_AndAssign ||
  4799. Opc == BinaryOperatorKind::BO_OrAssign ||
  4800. Opc == BinaryOperatorKind::BO_XorAssign;
  4801. }
  4802. static bool BinaryOperatorKindIsCompoundAssignmentForBool(BinaryOperatorKind Opc)
  4803. {
  4804. return
  4805. Opc == BinaryOperatorKind::BO_AndAssign ||
  4806. Opc == BinaryOperatorKind::BO_OrAssign ||
  4807. Opc == BinaryOperatorKind::BO_XorAssign;
  4808. }
  4809. static bool BinaryOperatorKindIsBitwise(BinaryOperatorKind Opc)
  4810. {
  4811. return
  4812. Opc == BinaryOperatorKind::BO_Shl ||
  4813. Opc == BinaryOperatorKind::BO_ShlAssign ||
  4814. Opc == BinaryOperatorKind::BO_Shr ||
  4815. Opc == BinaryOperatorKind::BO_ShrAssign ||
  4816. Opc == BinaryOperatorKind::BO_And ||
  4817. Opc == BinaryOperatorKind::BO_AndAssign ||
  4818. Opc == BinaryOperatorKind::BO_Or ||
  4819. Opc == BinaryOperatorKind::BO_OrAssign ||
  4820. Opc == BinaryOperatorKind::BO_Xor ||
  4821. Opc == BinaryOperatorKind::BO_XorAssign;
  4822. }
  4823. static bool BinaryOperatorKindIsBitwiseShift(BinaryOperatorKind Opc)
  4824. {
  4825. return
  4826. Opc == BinaryOperatorKind::BO_Shl ||
  4827. Opc == BinaryOperatorKind::BO_ShlAssign ||
  4828. Opc == BinaryOperatorKind::BO_Shr ||
  4829. Opc == BinaryOperatorKind::BO_ShrAssign;
  4830. }
  4831. static bool BinaryOperatorKindIsEqualComparison(BinaryOperatorKind Opc)
  4832. {
  4833. return
  4834. Opc == BinaryOperatorKind::BO_EQ ||
  4835. Opc == BinaryOperatorKind::BO_NE;
  4836. }
  4837. static bool BinaryOperatorKindIsOrderComparison(BinaryOperatorKind Opc)
  4838. {
  4839. return
  4840. Opc == BinaryOperatorKind::BO_LT ||
  4841. Opc == BinaryOperatorKind::BO_GT ||
  4842. Opc == BinaryOperatorKind::BO_LE ||
  4843. Opc == BinaryOperatorKind::BO_GE;
  4844. }
  4845. static bool BinaryOperatorKindIsComparison(BinaryOperatorKind Opc)
  4846. {
  4847. return BinaryOperatorKindIsEqualComparison(Opc) || BinaryOperatorKindIsOrderComparison(Opc);
  4848. }
  4849. static bool BinaryOperatorKindIsLogical(BinaryOperatorKind Opc)
  4850. {
  4851. return
  4852. Opc == BinaryOperatorKind::BO_LAnd ||
  4853. Opc == BinaryOperatorKind::BO_LOr;
  4854. }
  4855. static bool BinaryOperatorKindRequiresNumeric(BinaryOperatorKind Opc)
  4856. {
  4857. return
  4858. BinaryOperatorKindIsArithmetic(Opc) ||
  4859. BinaryOperatorKindIsOrderComparison(Opc) ||
  4860. BinaryOperatorKindIsLogical(Opc);
  4861. }
  4862. static bool BinaryOperatorKindRequiresIntegrals(BinaryOperatorKind Opc)
  4863. {
  4864. return BinaryOperatorKindIsBitwise(Opc);
  4865. }
  4866. static bool BinaryOperatorKindRequiresBoolAsNumeric(BinaryOperatorKind Opc)
  4867. {
  4868. return
  4869. BinaryOperatorKindIsBitwise(Opc) ||
  4870. BinaryOperatorKindIsArithmetic(Opc);
  4871. }
  4872. static bool UnaryOperatorKindRequiresIntegrals(UnaryOperatorKind Opc)
  4873. {
  4874. return Opc == UnaryOperatorKind::UO_Not;
  4875. }
  4876. static bool UnaryOperatorKindRequiresNumerics(UnaryOperatorKind Opc)
  4877. {
  4878. return
  4879. Opc == UnaryOperatorKind::UO_LNot ||
  4880. Opc == UnaryOperatorKind::UO_Plus ||
  4881. Opc == UnaryOperatorKind::UO_Minus ||
  4882. // The omission in fxc caused objects and structs to accept this.
  4883. Opc == UnaryOperatorKind::UO_PreDec || Opc == UnaryOperatorKind::UO_PreInc ||
  4884. Opc == UnaryOperatorKind::UO_PostDec || Opc == UnaryOperatorKind::UO_PostInc;
  4885. }
  4886. static bool UnaryOperatorKindRequiresModifiableValue(UnaryOperatorKind Opc)
  4887. {
  4888. return
  4889. Opc == UnaryOperatorKind::UO_PreDec || Opc == UnaryOperatorKind::UO_PreInc ||
  4890. Opc == UnaryOperatorKind::UO_PostDec || Opc == UnaryOperatorKind::UO_PostInc;
  4891. }
  4892. static bool UnaryOperatorKindRequiresBoolAsNumeric(UnaryOperatorKind Opc)
  4893. {
  4894. return
  4895. Opc == UnaryOperatorKind::UO_Not ||
  4896. Opc == UnaryOperatorKind::UO_Plus ||
  4897. Opc == UnaryOperatorKind::UO_Minus;
  4898. }
  4899. static bool UnaryOperatorKindDisallowsBool(UnaryOperatorKind Opc)
  4900. {
  4901. return
  4902. Opc == UnaryOperatorKind::UO_PreDec || Opc == UnaryOperatorKind::UO_PreInc ||
  4903. Opc == UnaryOperatorKind::UO_PostDec || Opc == UnaryOperatorKind::UO_PostInc;
  4904. }
  4905. static bool IsIncrementOp(UnaryOperatorKind Opc) {
  4906. return Opc == UnaryOperatorKind::UO_PreInc || Opc == UnaryOperatorKind::UO_PostInc;
  4907. }
  4908. /// <summary>
  4909. /// Checks whether the specified AR_TOBJ* value is a primitive or aggregate of primitive elements
  4910. /// (as opposed to a built-in object like a sampler or texture, or a void type).
  4911. /// </summary>
  4912. static bool IsObjectKindPrimitiveAggregate(ArTypeObjectKind value)
  4913. {
  4914. return
  4915. value == AR_TOBJ_BASIC ||
  4916. value == AR_TOBJ_MATRIX ||
  4917. value == AR_TOBJ_VECTOR;
  4918. }
  4919. static bool IsBasicKindIntegral(ArBasicKind value)
  4920. {
  4921. return IS_BASIC_AINT(value) || IS_BASIC_BOOL(value);
  4922. }
  4923. static bool IsBasicKindIntMinPrecision(ArBasicKind kind)
  4924. {
  4925. return IS_BASIC_SINT(kind) && IS_BASIC_MIN_PRECISION(kind);
  4926. }
  4927. static bool IsBasicKindNumeric(ArBasicKind value)
  4928. {
  4929. return GetBasicKindProps(value) & BPROP_NUMERIC;
  4930. }
  4931. ExprResult HLSLExternalSource::PromoteToIntIfBool(ExprResult& E)
  4932. {
  4933. // An invalid expression is pass-through at this point.
  4934. if (E.isInvalid())
  4935. {
  4936. return E;
  4937. }
  4938. QualType qt = E.get()->getType();
  4939. ArBasicKind elementKind = this->GetTypeElementKind(qt);
  4940. if (elementKind != AR_BASIC_BOOL)
  4941. {
  4942. return E;
  4943. }
  4944. // Construct a scalar/vector/matrix type with the same shape as E.
  4945. ArTypeObjectKind objectKind = this->GetTypeObjectKind(qt);
  4946. QualType targetType;
  4947. UINT colCount, rowCount;
  4948. GetRowsAndColsForAny(qt, rowCount, colCount);
  4949. targetType = NewSimpleAggregateType(objectKind, AR_BASIC_INT32, 0, rowCount, colCount)->getCanonicalTypeInternal();
  4950. if (E.get()->isLValue()) {
  4951. E = m_sema->DefaultLvalueConversion(E.get()).get();
  4952. }
  4953. switch (objectKind)
  4954. {
  4955. case AR_TOBJ_SCALAR:
  4956. return ImplicitCastExpr::Create(*m_context, targetType, CastKind::CK_IntegralCast, E.get(), nullptr, ExprValueKind::VK_RValue);
  4957. case AR_TOBJ_ARRAY:
  4958. case AR_TOBJ_VECTOR:
  4959. case AR_TOBJ_MATRIX:
  4960. return ImplicitCastExpr::Create(*m_context, targetType, CastKind::CK_HLSLCC_IntegralCast, E.get(), nullptr, ExprValueKind::VK_RValue);
  4961. default:
  4962. DXASSERT(false, "unsupported objectKind for PromoteToIntIfBool");
  4963. }
  4964. return E;
  4965. }
  4966. _Use_decl_annotations_
  4967. void HLSLExternalSource::CollectInfo(QualType type, ArTypeInfo* pTypeInfo)
  4968. {
  4969. DXASSERT_NOMSG(pTypeInfo != nullptr);
  4970. DXASSERT_NOMSG(!type.isNull());
  4971. memset(pTypeInfo, 0, sizeof(*pTypeInfo));
  4972. // TODO: Get* functions used here add up to a bunch of redundant code.
  4973. // Try to inline that here, making it cheaper to use this function
  4974. // when retrieving multiple properties.
  4975. pTypeInfo->ObjKind = GetTypeElementKind(type);
  4976. pTypeInfo->EltKind = pTypeInfo->ObjKind;
  4977. pTypeInfo->ShapeKind = GetTypeObjectKind(type);
  4978. GetRowsAndColsForAny(type, pTypeInfo->uRows, pTypeInfo->uCols);
  4979. pTypeInfo->uTotalElts = pTypeInfo->uRows * pTypeInfo->uCols;
  4980. }
  4981. // Highest possible score (i.e., worst possible score).
  4982. static const UINT64 SCORE_MAX = 0xFFFFFFFFFFFFFFFF;
  4983. // Leave the first two score bits to handle higher-level
  4984. // variations like target type.
  4985. #define SCORE_MIN_SHIFT 2
  4986. // Space out scores to allow up to 128 parameters to
  4987. // vary between score sets spill into each other.
  4988. #define SCORE_PARAM_SHIFT 7
  4989. unsigned HLSLExternalSource::GetNumElements(QualType anyType) {
  4990. if (anyType.isNull()) {
  4991. return 0;
  4992. }
  4993. anyType = GetStructuralForm(anyType);
  4994. ArTypeObjectKind kind = GetTypeObjectKind(anyType);
  4995. switch (kind) {
  4996. case AR_TOBJ_BASIC:
  4997. case AR_TOBJ_OBJECT:
  4998. return 1;
  4999. case AR_TOBJ_COMPOUND: {
  5000. // TODO: consider caching this value for perf
  5001. unsigned total = 0;
  5002. const RecordType *recordType = anyType->getAs<RecordType>();
  5003. RecordDecl::field_iterator fi = recordType->getDecl()->field_begin();
  5004. RecordDecl::field_iterator fend = recordType->getDecl()->field_end();
  5005. while (fi != fend) {
  5006. total += GetNumElements(fi->getType());
  5007. ++fi;
  5008. }
  5009. return total;
  5010. }
  5011. case AR_TOBJ_ARRAY:
  5012. case AR_TOBJ_MATRIX:
  5013. case AR_TOBJ_VECTOR:
  5014. return GetElementCount(anyType);
  5015. default:
  5016. DXASSERT(kind == AR_TOBJ_VOID,
  5017. "otherwise the type cannot be classified or is not supported");
  5018. return 0;
  5019. }
  5020. }
  5021. unsigned HLSLExternalSource::GetNumBasicElements(QualType anyType) {
  5022. if (anyType.isNull()) {
  5023. return 0;
  5024. }
  5025. anyType = GetStructuralForm(anyType);
  5026. ArTypeObjectKind kind = GetTypeObjectKind(anyType);
  5027. switch (kind) {
  5028. case AR_TOBJ_BASIC:
  5029. case AR_TOBJ_OBJECT:
  5030. return 1;
  5031. case AR_TOBJ_COMPOUND: {
  5032. // TODO: consider caching this value for perf
  5033. unsigned total = 0;
  5034. const RecordType *recordType = anyType->getAs<RecordType>();
  5035. RecordDecl * RD = recordType->getDecl();
  5036. // Take care base.
  5037. if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
  5038. if (CXXRD->getNumBases()) {
  5039. for (const auto &I : CXXRD->bases()) {
  5040. const CXXRecordDecl *BaseDecl =
  5041. cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
  5042. if (BaseDecl->field_empty())
  5043. continue;
  5044. QualType parentTy = QualType(BaseDecl->getTypeForDecl(), 0);
  5045. total += GetNumBasicElements(parentTy);
  5046. }
  5047. }
  5048. }
  5049. RecordDecl::field_iterator fi = RD->field_begin();
  5050. RecordDecl::field_iterator fend = RD->field_end();
  5051. while (fi != fend) {
  5052. total += GetNumBasicElements(fi->getType());
  5053. ++fi;
  5054. }
  5055. return total;
  5056. }
  5057. case AR_TOBJ_ARRAY: {
  5058. unsigned arraySize = GetElementCount(anyType);
  5059. unsigned eltSize = GetNumBasicElements(
  5060. QualType(anyType->getArrayElementTypeNoTypeQual(), 0));
  5061. return arraySize * eltSize;
  5062. }
  5063. case AR_TOBJ_MATRIX:
  5064. case AR_TOBJ_VECTOR:
  5065. return GetElementCount(anyType);
  5066. default:
  5067. DXASSERT(kind == AR_TOBJ_VOID,
  5068. "otherwise the type cannot be classified or is not supported");
  5069. return 0;
  5070. }
  5071. }
  5072. unsigned HLSLExternalSource::GetNumConvertCheckElts(QualType leftType,
  5073. unsigned leftSize,
  5074. QualType rightType,
  5075. unsigned rightSize) {
  5076. // We can convert from a larger type to a smaller
  5077. // but not a smaller type to a larger so default
  5078. // to just comparing the destination size.
  5079. unsigned uElts = leftSize;
  5080. leftType = GetStructuralForm(leftType);
  5081. rightType = GetStructuralForm(rightType);
  5082. if (leftType->isArrayType() && rightType->isArrayType()) {
  5083. //
  5084. // If we're comparing arrays we don't
  5085. // need to compare every element of
  5086. // the arrays since all elements
  5087. // will have the same type.
  5088. // We only need to compare enough
  5089. // elements that we've tried every
  5090. // possible mix of dst and src elements.
  5091. //
  5092. // TODO: handle multidimensional arrays and arrays of arrays
  5093. QualType pDstElt = leftType->getAsArrayTypeUnsafe()->getElementType();
  5094. unsigned uDstEltSize = GetNumElements(pDstElt);
  5095. QualType pSrcElt = rightType->getAsArrayTypeUnsafe()->getElementType();
  5096. unsigned uSrcEltSize = GetNumElements(pSrcElt);
  5097. if (uDstEltSize == uSrcEltSize) {
  5098. uElts = uDstEltSize;
  5099. } else if (uDstEltSize > uSrcEltSize) {
  5100. // If one size is not an even multiple of the other we need to let the
  5101. // full compare run in order to try all alignments.
  5102. if (uSrcEltSize && (uDstEltSize % uSrcEltSize) == 0) {
  5103. uElts = uDstEltSize;
  5104. }
  5105. } else if (uDstEltSize && (uSrcEltSize % uDstEltSize) == 0) {
  5106. uElts = uSrcEltSize;
  5107. }
  5108. }
  5109. return uElts;
  5110. }
  5111. QualType HLSLExternalSource::GetNthElementType(QualType type, unsigned index) {
  5112. if (type.isNull()) {
  5113. return type;
  5114. }
  5115. ArTypeObjectKind kind = GetTypeObjectKind(type);
  5116. switch (kind) {
  5117. case AR_TOBJ_BASIC:
  5118. case AR_TOBJ_OBJECT:
  5119. return (index == 0) ? type : QualType();
  5120. case AR_TOBJ_COMPOUND: {
  5121. // TODO: consider caching this value for perf
  5122. const RecordType *recordType = type->getAsStructureType();
  5123. RecordDecl::field_iterator fi = recordType->getDecl()->field_begin();
  5124. RecordDecl::field_iterator fend = recordType->getDecl()->field_end();
  5125. while (fi != fend) {
  5126. if (!fi->getType().isNull()) {
  5127. unsigned subElements = GetNumElements(fi->getType());
  5128. if (index < subElements) {
  5129. return GetNthElementType(fi->getType(), index);
  5130. } else {
  5131. index -= subElements;
  5132. }
  5133. }
  5134. ++fi;
  5135. }
  5136. return QualType();
  5137. }
  5138. case AR_TOBJ_ARRAY: {
  5139. unsigned arraySize;
  5140. QualType elementType;
  5141. unsigned elementCount;
  5142. elementType = type.getNonReferenceType()->getAsArrayTypeUnsafe()->getElementType();
  5143. elementCount = GetElementCount(elementType);
  5144. if (index < elementCount) {
  5145. return GetNthElementType(elementType, index);
  5146. }
  5147. arraySize = GetArraySize(type);
  5148. if (index >= arraySize * elementCount) {
  5149. return QualType();
  5150. }
  5151. return GetNthElementType(elementType, index % elementCount);
  5152. }
  5153. case AR_TOBJ_MATRIX:
  5154. case AR_TOBJ_VECTOR:
  5155. return (index < GetElementCount(type)) ? GetMatrixOrVectorElementType(type)
  5156. : QualType();
  5157. default:
  5158. DXASSERT(kind == AR_TOBJ_VOID,
  5159. "otherwise the type cannot be classified or is not supported");
  5160. return QualType();
  5161. }
  5162. }
  5163. bool HLSLExternalSource::IsPromotion(ArBasicKind leftKind, ArBasicKind rightKind) {
  5164. // Eliminate exact matches first, then check for promotions.
  5165. if (leftKind == rightKind) {
  5166. return false;
  5167. }
  5168. switch (rightKind) {
  5169. case AR_BASIC_FLOAT16:
  5170. switch (leftKind) {
  5171. case AR_BASIC_FLOAT32:
  5172. case AR_BASIC_FLOAT32_PARTIAL_PRECISION:
  5173. case AR_BASIC_FLOAT64:
  5174. return true;
  5175. default:
  5176. return false; // No other type is a promotion.
  5177. }
  5178. break;
  5179. case AR_BASIC_FLOAT32_PARTIAL_PRECISION:
  5180. switch (leftKind) {
  5181. case AR_BASIC_FLOAT32:
  5182. case AR_BASIC_FLOAT64:
  5183. return true;
  5184. default:
  5185. return false; // No other type is a promotion.
  5186. }
  5187. break;
  5188. case AR_BASIC_FLOAT32:
  5189. switch (leftKind) {
  5190. case AR_BASIC_FLOAT64:
  5191. return true;
  5192. default:
  5193. return false; // No other type is a promotion.
  5194. }
  5195. break;
  5196. case AR_BASIC_MIN10FLOAT:
  5197. switch (leftKind) {
  5198. case AR_BASIC_MIN16FLOAT:
  5199. case AR_BASIC_FLOAT16:
  5200. case AR_BASIC_FLOAT32:
  5201. case AR_BASIC_FLOAT32_PARTIAL_PRECISION:
  5202. case AR_BASIC_FLOAT64:
  5203. return true;
  5204. default:
  5205. return false; // No other type is a promotion.
  5206. }
  5207. break;
  5208. case AR_BASIC_MIN16FLOAT:
  5209. switch (leftKind) {
  5210. case AR_BASIC_FLOAT16:
  5211. case AR_BASIC_FLOAT32:
  5212. case AR_BASIC_FLOAT32_PARTIAL_PRECISION:
  5213. case AR_BASIC_FLOAT64:
  5214. return true;
  5215. default:
  5216. return false; // No other type is a promotion.
  5217. }
  5218. break;
  5219. case AR_BASIC_INT8:
  5220. case AR_BASIC_UINT8:
  5221. // For backwards compat we consider signed/unsigned the same.
  5222. switch (leftKind) {
  5223. case AR_BASIC_INT16:
  5224. case AR_BASIC_INT32:
  5225. case AR_BASIC_INT64:
  5226. case AR_BASIC_UINT16:
  5227. case AR_BASIC_UINT32:
  5228. case AR_BASIC_UINT64:
  5229. return true;
  5230. default:
  5231. return false; // No other type is a promotion.
  5232. }
  5233. break;
  5234. case AR_BASIC_INT16:
  5235. case AR_BASIC_UINT16:
  5236. // For backwards compat we consider signed/unsigned the same.
  5237. switch (leftKind) {
  5238. case AR_BASIC_INT32:
  5239. case AR_BASIC_INT64:
  5240. case AR_BASIC_UINT32:
  5241. case AR_BASIC_UINT64:
  5242. return true;
  5243. default:
  5244. return false; // No other type is a promotion.
  5245. }
  5246. break;
  5247. case AR_BASIC_INT32:
  5248. case AR_BASIC_UINT32:
  5249. // For backwards compat we consider signed/unsigned the same.
  5250. switch (leftKind) {
  5251. case AR_BASIC_INT64:
  5252. case AR_BASIC_UINT64:
  5253. return true;
  5254. default:
  5255. return false; // No other type is a promotion.
  5256. }
  5257. break;
  5258. case AR_BASIC_MIN12INT:
  5259. switch (leftKind) {
  5260. case AR_BASIC_MIN16INT:
  5261. case AR_BASIC_INT32:
  5262. case AR_BASIC_INT64:
  5263. return true;
  5264. default:
  5265. return false; // No other type is a promotion.
  5266. }
  5267. break;
  5268. case AR_BASIC_MIN16INT:
  5269. switch (leftKind) {
  5270. case AR_BASIC_INT32:
  5271. case AR_BASIC_INT64:
  5272. return true;
  5273. default:
  5274. return false; // No other type is a promotion.
  5275. }
  5276. break;
  5277. case AR_BASIC_MIN16UINT:
  5278. switch (leftKind) {
  5279. case AR_BASIC_UINT32:
  5280. case AR_BASIC_UINT64:
  5281. return true;
  5282. default:
  5283. return false; // No other type is a promotion.
  5284. }
  5285. break;
  5286. }
  5287. return false;
  5288. }
  5289. bool HLSLExternalSource::IsCast(ArBasicKind leftKind, ArBasicKind rightKind) {
  5290. // Eliminate exact matches first, then check for casts.
  5291. if (leftKind == rightKind) {
  5292. return false;
  5293. }
  5294. //
  5295. // All minimum-bits types are only considered matches of themselves
  5296. // and thus are not in this table.
  5297. //
  5298. switch (leftKind) {
  5299. case AR_BASIC_LITERAL_INT:
  5300. switch (rightKind) {
  5301. case AR_BASIC_INT8:
  5302. case AR_BASIC_INT16:
  5303. case AR_BASIC_INT32:
  5304. case AR_BASIC_INT64:
  5305. case AR_BASIC_UINT8:
  5306. case AR_BASIC_UINT16:
  5307. case AR_BASIC_UINT32:
  5308. case AR_BASIC_UINT64:
  5309. return false;
  5310. default:
  5311. break; // No other valid cast types
  5312. }
  5313. break;
  5314. case AR_BASIC_INT8:
  5315. switch (rightKind) {
  5316. // For backwards compat we consider signed/unsigned the same.
  5317. case AR_BASIC_LITERAL_INT:
  5318. case AR_BASIC_UINT8:
  5319. return false;
  5320. default:
  5321. break; // No other valid cast types
  5322. }
  5323. break;
  5324. case AR_BASIC_INT16:
  5325. switch (rightKind) {
  5326. // For backwards compat we consider signed/unsigned the same.
  5327. case AR_BASIC_LITERAL_INT:
  5328. case AR_BASIC_UINT16:
  5329. return false;
  5330. default:
  5331. break; // No other valid cast types
  5332. }
  5333. break;
  5334. case AR_BASIC_INT32:
  5335. switch (rightKind) {
  5336. // For backwards compat we consider signed/unsigned the same.
  5337. case AR_BASIC_LITERAL_INT:
  5338. case AR_BASIC_UINT32:
  5339. return false;
  5340. default:
  5341. break; // No other valid cast types.
  5342. }
  5343. break;
  5344. case AR_BASIC_INT64:
  5345. switch (rightKind) {
  5346. // For backwards compat we consider signed/unsigned the same.
  5347. case AR_BASIC_LITERAL_INT:
  5348. case AR_BASIC_UINT64:
  5349. return false;
  5350. default:
  5351. break; // No other valid cast types.
  5352. }
  5353. break;
  5354. case AR_BASIC_UINT8:
  5355. switch (rightKind) {
  5356. // For backwards compat we consider signed/unsigned the same.
  5357. case AR_BASIC_LITERAL_INT:
  5358. case AR_BASIC_INT8:
  5359. return false;
  5360. default:
  5361. break; // No other valid cast types.
  5362. }
  5363. break;
  5364. case AR_BASIC_UINT16:
  5365. switch (rightKind) {
  5366. // For backwards compat we consider signed/unsigned the same.
  5367. case AR_BASIC_LITERAL_INT:
  5368. case AR_BASIC_INT16:
  5369. return false;
  5370. default:
  5371. break; // No other valid cast types.
  5372. }
  5373. break;
  5374. case AR_BASIC_UINT32:
  5375. switch (rightKind) {
  5376. // For backwards compat we consider signed/unsigned the same.
  5377. case AR_BASIC_LITERAL_INT:
  5378. case AR_BASIC_INT32:
  5379. return false;
  5380. default:
  5381. break; // No other valid cast types.
  5382. }
  5383. break;
  5384. case AR_BASIC_UINT64:
  5385. switch (rightKind) {
  5386. // For backwards compat we consider signed/unsigned the same.
  5387. case AR_BASIC_LITERAL_INT:
  5388. case AR_BASIC_INT64:
  5389. return false;
  5390. default:
  5391. break; // No other valid cast types.
  5392. }
  5393. break;
  5394. case AR_BASIC_LITERAL_FLOAT:
  5395. switch (rightKind) {
  5396. case AR_BASIC_LITERAL_FLOAT:
  5397. case AR_BASIC_FLOAT16:
  5398. case AR_BASIC_FLOAT32:
  5399. case AR_BASIC_FLOAT32_PARTIAL_PRECISION:
  5400. case AR_BASIC_FLOAT64:
  5401. return false;
  5402. default:
  5403. break; // No other valid cast types.
  5404. }
  5405. break;
  5406. case AR_BASIC_FLOAT16:
  5407. switch (rightKind) {
  5408. case AR_BASIC_LITERAL_FLOAT:
  5409. return false;
  5410. default:
  5411. break; // No other valid cast types.
  5412. }
  5413. break;
  5414. case AR_BASIC_FLOAT32_PARTIAL_PRECISION:
  5415. switch (rightKind) {
  5416. case AR_BASIC_LITERAL_FLOAT:
  5417. return false;
  5418. default:
  5419. break; // No other valid cast types.
  5420. }
  5421. break;
  5422. case AR_BASIC_FLOAT32:
  5423. switch (rightKind) {
  5424. case AR_BASIC_LITERAL_FLOAT:
  5425. return false;
  5426. default:
  5427. break; // No other valid cast types.
  5428. }
  5429. break;
  5430. case AR_BASIC_FLOAT64:
  5431. switch (rightKind) {
  5432. case AR_BASIC_LITERAL_FLOAT:
  5433. return false;
  5434. default:
  5435. break; // No other valid cast types.
  5436. }
  5437. break;
  5438. default:
  5439. break; // No other relevant targets.
  5440. }
  5441. return true;
  5442. }
  5443. bool HLSLExternalSource::IsIntCast(ArBasicKind leftKind, ArBasicKind rightKind) {
  5444. // Eliminate exact matches first, then check for casts.
  5445. if (leftKind == rightKind) {
  5446. return false;
  5447. }
  5448. //
  5449. // All minimum-bits types are only considered matches of themselves
  5450. // and thus are not in this table.
  5451. //
  5452. switch (leftKind) {
  5453. case AR_BASIC_LITERAL_INT:
  5454. switch (rightKind) {
  5455. case AR_BASIC_INT8:
  5456. case AR_BASIC_INT16:
  5457. case AR_BASIC_INT32:
  5458. case AR_BASIC_INT64:
  5459. case AR_BASIC_UINT8:
  5460. case AR_BASIC_UINT16:
  5461. case AR_BASIC_UINT32:
  5462. case AR_BASIC_UINT64:
  5463. return false;
  5464. default:
  5465. break; // No other valid conversions
  5466. }
  5467. break;
  5468. case AR_BASIC_INT8:
  5469. case AR_BASIC_INT16:
  5470. case AR_BASIC_INT32:
  5471. case AR_BASIC_INT64:
  5472. case AR_BASIC_UINT8:
  5473. case AR_BASIC_UINT16:
  5474. case AR_BASIC_UINT32:
  5475. case AR_BASIC_UINT64:
  5476. switch (rightKind) {
  5477. case AR_BASIC_LITERAL_INT:
  5478. return false;
  5479. default:
  5480. break; // No other valid conversions
  5481. }
  5482. break;
  5483. case AR_BASIC_LITERAL_FLOAT:
  5484. switch (rightKind) {
  5485. case AR_BASIC_LITERAL_FLOAT:
  5486. case AR_BASIC_FLOAT16:
  5487. case AR_BASIC_FLOAT32:
  5488. case AR_BASIC_FLOAT32_PARTIAL_PRECISION:
  5489. case AR_BASIC_FLOAT64:
  5490. return false;
  5491. default:
  5492. break; // No other valid conversions
  5493. }
  5494. break;
  5495. case AR_BASIC_FLOAT16:
  5496. case AR_BASIC_FLOAT32:
  5497. case AR_BASIC_FLOAT32_PARTIAL_PRECISION:
  5498. case AR_BASIC_FLOAT64:
  5499. switch (rightKind) {
  5500. case AR_BASIC_LITERAL_FLOAT:
  5501. return false;
  5502. default:
  5503. break; // No other valid conversions
  5504. }
  5505. break;
  5506. default:
  5507. // No other relevant targets
  5508. break;
  5509. }
  5510. return true;
  5511. }
  5512. UINT64 HLSLExternalSource::ScoreCast(QualType pLType, QualType pRType)
  5513. {
  5514. if (pLType.getCanonicalType() == pRType.getCanonicalType()) {
  5515. return 0;
  5516. }
  5517. UINT64 uScore = 0;
  5518. UINT uLSize = GetNumElements(pLType);
  5519. UINT uRSize = GetNumElements(pRType);
  5520. UINT uCompareSize;
  5521. bool bLCast = false;
  5522. bool bRCast = false;
  5523. bool bLIntCast = false;
  5524. bool bRIntCast = false;
  5525. bool bLPromo = false;
  5526. bool bRPromo = false;
  5527. uCompareSize = GetNumConvertCheckElts(pLType, uLSize, pRType, uRSize);
  5528. if (uCompareSize > uRSize) {
  5529. uCompareSize = uRSize;
  5530. }
  5531. for (UINT i = 0; i < uCompareSize; i++) {
  5532. ArBasicKind LeftElementKind, RightElementKind;
  5533. ArBasicKind CombinedKind = AR_BASIC_BOOL;
  5534. QualType leftSub = GetNthElementType(pLType, i);
  5535. QualType rightSub = GetNthElementType(pRType, i);
  5536. ArTypeObjectKind leftKind = GetTypeObjectKind(leftSub);
  5537. ArTypeObjectKind rightKind = GetTypeObjectKind(rightSub);
  5538. LeftElementKind = GetTypeElementKind(leftSub);
  5539. RightElementKind = GetTypeElementKind(rightSub);
  5540. // CollectInfo is called with AR_TINFO_ALLOW_OBJECTS, and the resulting
  5541. // information needed is the ShapeKind, EltKind and ObjKind.
  5542. if (!leftSub.isNull() && !rightSub.isNull() && leftKind != AR_TOBJ_INVALID && rightKind != AR_TOBJ_INVALID) {
  5543. bool bCombine;
  5544. if (leftKind == AR_TOBJ_OBJECT || rightKind == AR_TOBJ_OBJECT) {
  5545. DXASSERT(rightKind == AR_TOBJ_OBJECT, "otherwise prior check is incorrect");
  5546. ArBasicKind LeftObjKind = LeftElementKind; // actually LeftElementKind would have been the element
  5547. ArBasicKind RightObjKind = RightElementKind;
  5548. LeftElementKind = LeftObjKind;
  5549. RightElementKind = RightObjKind;
  5550. if (leftKind != rightKind) {
  5551. bCombine = false;
  5552. }
  5553. else if (!(bCombine = CombineObjectTypes(LeftObjKind, RightObjKind, &CombinedKind))) {
  5554. bCombine = CombineObjectTypes(RightObjKind, LeftObjKind, &CombinedKind);
  5555. }
  5556. }
  5557. else {
  5558. bCombine = CombineBasicTypes(LeftElementKind, RightElementKind, &CombinedKind);
  5559. }
  5560. if (bCombine && IsPromotion(LeftElementKind, CombinedKind)) {
  5561. bLPromo = true;
  5562. }
  5563. else if (!bCombine || IsCast(LeftElementKind, CombinedKind)) {
  5564. bLCast = true;
  5565. }
  5566. else if (IsIntCast(LeftElementKind, CombinedKind)) {
  5567. bLIntCast = true;
  5568. }
  5569. if (bCombine && IsPromotion(CombinedKind, RightElementKind)) {
  5570. bRPromo = true;
  5571. } else if (!bCombine || IsCast(CombinedKind, RightElementKind)) {
  5572. bRCast = true;
  5573. } else if (IsIntCast(CombinedKind, RightElementKind)) {
  5574. bRIntCast = true;
  5575. }
  5576. } else {
  5577. bLCast = true;
  5578. bRCast = true;
  5579. }
  5580. }
  5581. #define SCORE_COND(shift, cond) { \
  5582. if (cond) uScore += 1ULL << (SCORE_MIN_SHIFT + SCORE_PARAM_SHIFT * shift); }
  5583. SCORE_COND(0, uRSize < uLSize);
  5584. SCORE_COND(1, bLPromo);
  5585. SCORE_COND(2, bRPromo);
  5586. SCORE_COND(3, bLIntCast);
  5587. SCORE_COND(4, bRIntCast);
  5588. SCORE_COND(5, bLCast);
  5589. SCORE_COND(6, bRCast);
  5590. SCORE_COND(7, uLSize < uRSize);
  5591. #undef SCORE_COND
  5592. // Make sure our scores fit in a UINT64.
  5593. C_ASSERT(SCORE_MIN_SHIFT + SCORE_PARAM_SHIFT * 8 <= 64);
  5594. return uScore;
  5595. }
  5596. UINT64 HLSLExternalSource::ScoreImplicitConversionSequence(const ImplicitConversionSequence *ics) {
  5597. DXASSERT(ics, "otherwise conversion has not been initialized");
  5598. if (!ics->isInitialized()) {
  5599. return 0;
  5600. }
  5601. if (!ics->isStandard()) {
  5602. return SCORE_MAX;
  5603. }
  5604. QualType fromType = ics->Standard.getFromType();
  5605. QualType toType = ics->Standard.getToType(2); // final type
  5606. return ScoreCast(toType, fromType);
  5607. }
  5608. UINT64 HLSLExternalSource::ScoreFunction(OverloadCandidateSet::iterator &Cand) {
  5609. // Ignore target version mismatches.
  5610. // in/out considerations have been taken care of by viability.
  5611. // 'this' considerations don't matter without inheritance, other
  5612. // than lookup and viability.
  5613. UINT64 result = 0;
  5614. for (unsigned convIdx = 0; convIdx < Cand->NumConversions; ++convIdx) {
  5615. UINT64 score;
  5616. score = ScoreImplicitConversionSequence(Cand->Conversions + convIdx);
  5617. if (score == SCORE_MAX) {
  5618. return SCORE_MAX;
  5619. }
  5620. result += score;
  5621. score = ScoreImplicitConversionSequence(Cand->OutConversions + convIdx);
  5622. if (score == SCORE_MAX) {
  5623. return SCORE_MAX;
  5624. }
  5625. result += score;
  5626. }
  5627. return result;
  5628. }
  5629. OverloadingResult HLSLExternalSource::GetBestViableFunction(
  5630. SourceLocation Loc,
  5631. OverloadCandidateSet& set,
  5632. OverloadCandidateSet::iterator& Best)
  5633. {
  5634. UINT64 bestScore = SCORE_MAX;
  5635. unsigned scoreMatch = 0;
  5636. Best = set.end();
  5637. if (set.size() == 1 && set.begin()->Viable) {
  5638. Best = set.begin();
  5639. return OR_Success;
  5640. }
  5641. for (OverloadCandidateSet::iterator Cand = set.begin(); Cand != set.end(); ++Cand) {
  5642. if (Cand->Viable) {
  5643. UINT64 score = ScoreFunction(Cand);
  5644. if (score != SCORE_MAX) {
  5645. if (score == bestScore) {
  5646. ++scoreMatch;
  5647. } else if (score < bestScore) {
  5648. Best = Cand;
  5649. scoreMatch = 1;
  5650. bestScore = score;
  5651. }
  5652. }
  5653. }
  5654. }
  5655. if (Best == set.end()) {
  5656. return OR_No_Viable_Function;
  5657. }
  5658. if (scoreMatch > 1) {
  5659. Best = set.end();
  5660. return OR_Ambiguous;
  5661. }
  5662. // No need to check for deleted functions to yield OR_Deleted.
  5663. return OR_Success;
  5664. }
  5665. /// <summary>
  5666. /// Initializes the specified <paramref name="initSequence" /> describing how
  5667. /// <paramref name="Entity" /> is initialized with <paramref name="Args" />.
  5668. /// </summary>
  5669. /// <param name="Entity">Entity being initialized; a variable, return result, etc.</param>
  5670. /// <param name="Kind">Kind of initialization: copying, list-initializing, constructing, etc.</param>
  5671. /// <param name="Args">Arguments to the initialization.</param>
  5672. /// <param name="TopLevelOfInitList">Whether this is the top-level of an initialization list.</param>
  5673. /// <param name="initSequence">Initialization sequence description to initialize.</param>
  5674. void HLSLExternalSource::InitializeInitSequenceForHLSL(
  5675. const InitializedEntity& Entity,
  5676. const InitializationKind& Kind,
  5677. MultiExprArg Args,
  5678. bool TopLevelOfInitList,
  5679. _Inout_ InitializationSequence* initSequence)
  5680. {
  5681. DXASSERT_NOMSG(initSequence != nullptr);
  5682. // In HLSL there are no default initializers, eg float4x4 m();
  5683. if (Kind.getKind() == InitializationKind::IK_Default) {
  5684. return;
  5685. }
  5686. // Value initializers occur for temporaries with empty parens or braces.
  5687. if (Kind.getKind() == InitializationKind::IK_Value) {
  5688. m_sema->Diag(Kind.getLocation(), diag::err_hlsl_type_empty_init) << Entity.getType();
  5689. SilenceSequenceDiagnostics(initSequence);
  5690. return;
  5691. }
  5692. // If we have a DirectList, we should have a single InitListExprClass argument.
  5693. DXASSERT(
  5694. Kind.getKind() != InitializationKind::IK_DirectList ||
  5695. (Args.size() == 1 && Args.front()->getStmtClass() == Stmt::InitListExprClass),
  5696. "otherwise caller is passing in incorrect initialization configuration");
  5697. bool isCast = Kind.isCStyleCast();
  5698. QualType destType = Entity.getType();
  5699. ArTypeObjectKind destShape = GetTypeObjectKind(destType);
  5700. // Direct initialization occurs for explicit constructor arguments.
  5701. // E.g.: http://en.cppreference.com/w/cpp/language/direct_initialization
  5702. if (Kind.getKind() == InitializationKind::IK_Direct && destShape == AR_TOBJ_COMPOUND &&
  5703. !Kind.isCStyleOrFunctionalCast()) {
  5704. m_sema->Diag(Kind.getLocation(), diag::err_hlsl_require_numeric_base_for_ctor);
  5705. SilenceSequenceDiagnostics(initSequence);
  5706. return;
  5707. }
  5708. bool flatten =
  5709. (Kind.getKind() == InitializationKind::IK_Direct && !isCast) ||
  5710. Kind.getKind() == InitializationKind::IK_DirectList ||
  5711. (Args.size() == 1 && Args.front()->getStmtClass() == Stmt::InitListExprClass);
  5712. if (flatten) {
  5713. // TODO: InitializationSequence::Perform in SemaInit should take the arity of incomplete
  5714. // array types to adjust the value - we do calculate this as part of type analysis.
  5715. // Until this is done, s_arr_i_f arr_struct_none[] = { }; succeeds when it should instead fail.
  5716. FlattenedTypeIterator::ComparisonResult comparisonResult =
  5717. FlattenedTypeIterator::CompareTypesForInit(
  5718. *this, destType, Args,
  5719. Kind.getLocation(), Kind.getLocation());
  5720. if (comparisonResult.IsConvertibleAndEqualLength() ||
  5721. (isCast && comparisonResult.IsConvertibleAndLeftLonger()))
  5722. {
  5723. initSequence->AddListInitializationStep(destType);
  5724. }
  5725. else
  5726. {
  5727. SourceLocation diagLocation;
  5728. if (Args.size() > 0)
  5729. {
  5730. diagLocation = Args.front()->getLocStart();
  5731. }
  5732. else
  5733. {
  5734. diagLocation = Entity.getDiagLoc();
  5735. }
  5736. m_sema->Diag(diagLocation,
  5737. diag::err_vector_incorrect_num_initializers)
  5738. << (comparisonResult.RightCount < comparisonResult.LeftCount)
  5739. << comparisonResult.LeftCount << comparisonResult.RightCount;
  5740. SilenceSequenceDiagnostics(initSequence);
  5741. }
  5742. }
  5743. else {
  5744. DXASSERT(Args.size() == 1, "otherwise this was mis-parsed or should be a list initialization");
  5745. Expr* firstArg = Args.front();
  5746. if (IsExpressionBinaryComma(firstArg)) {
  5747. m_sema->Diag(firstArg->getExprLoc(), diag::warn_hlsl_comma_in_init);
  5748. }
  5749. ExprResult expr = ExprResult(firstArg);
  5750. Sema::CheckedConversionKind cck = Kind.isExplicitCast() ?
  5751. Sema::CheckedConversionKind::CCK_CStyleCast :
  5752. Sema::CheckedConversionKind::CCK_ImplicitConversion;
  5753. unsigned int msg = 0;
  5754. CastKind castKind;
  5755. CXXCastPath basePath;
  5756. SourceRange range = Kind.getRange();
  5757. ImplicitConversionSequence ics;
  5758. ics.setStandard();
  5759. bool castWorked = TryStaticCastForHLSL(
  5760. expr, destType, cck, range, msg, castKind, basePath, ListInitializationFalse, SuppressWarningsFalse, SuppressErrorsTrue, &ics.Standard);
  5761. if (castWorked) {
  5762. if (destType.getCanonicalType() ==
  5763. firstArg->getType().getCanonicalType() &&
  5764. (ics.Standard).First != ICK_Lvalue_To_Rvalue) {
  5765. initSequence->AddCAssignmentStep(destType);
  5766. } else {
  5767. initSequence->AddConversionSequenceStep(ics, destType.getNonReferenceType(), TopLevelOfInitList);
  5768. }
  5769. }
  5770. else {
  5771. initSequence->SetFailed(InitializationSequence::FK_ConversionFailed);
  5772. }
  5773. }
  5774. }
  5775. bool HLSLExternalSource::IsConversionToLessOrEqualElements(
  5776. const QualType& sourceType,
  5777. const QualType& targetType,
  5778. bool explicitConversion)
  5779. {
  5780. DXASSERT_NOMSG(!sourceType.isNull());
  5781. DXASSERT_NOMSG(!targetType.isNull());
  5782. ArTypeInfo sourceTypeInfo;
  5783. ArTypeInfo targetTypeInfo;
  5784. GetConversionForm(sourceType, explicitConversion, &sourceTypeInfo);
  5785. GetConversionForm(targetType, explicitConversion, &targetTypeInfo);
  5786. if (sourceTypeInfo.EltKind != targetTypeInfo.EltKind)
  5787. {
  5788. return false;
  5789. }
  5790. bool isVecMatTrunc = sourceTypeInfo.ShapeKind == AR_TOBJ_VECTOR &&
  5791. targetTypeInfo.ShapeKind == AR_TOBJ_BASIC;
  5792. if (sourceTypeInfo.ShapeKind != targetTypeInfo.ShapeKind &&
  5793. !isVecMatTrunc)
  5794. {
  5795. return false;
  5796. }
  5797. if (sourceTypeInfo.ShapeKind == AR_TOBJ_OBJECT &&
  5798. sourceTypeInfo.ObjKind == targetTypeInfo.ObjKind) {
  5799. return true;
  5800. }
  5801. // Same struct is eqaul.
  5802. if (sourceTypeInfo.ShapeKind == AR_TOBJ_COMPOUND &&
  5803. sourceType.getCanonicalType().getUnqualifiedType() ==
  5804. targetType.getCanonicalType().getUnqualifiedType()) {
  5805. return true;
  5806. }
  5807. // DerivedFrom is less.
  5808. if (sourceTypeInfo.ShapeKind == AR_TOBJ_COMPOUND ||
  5809. GetTypeObjectKind(sourceType) == AR_TOBJ_COMPOUND) {
  5810. const RecordType *targetRT = targetType->getAsStructureType();
  5811. if (!targetRT)
  5812. targetRT = dyn_cast<RecordType>(targetType);
  5813. const RecordType *sourceRT = sourceType->getAsStructureType();
  5814. if (!sourceRT)
  5815. sourceRT = dyn_cast<RecordType>(sourceType);
  5816. if (targetRT && sourceRT) {
  5817. RecordDecl *targetRD = targetRT->getDecl();
  5818. RecordDecl *sourceRD = sourceRT->getDecl();
  5819. const CXXRecordDecl *targetCXXRD = dyn_cast<CXXRecordDecl>(targetRD);
  5820. const CXXRecordDecl *sourceCXXRD = dyn_cast<CXXRecordDecl>(sourceRD);
  5821. if (targetCXXRD && sourceCXXRD) {
  5822. if (sourceCXXRD->isDerivedFrom(targetCXXRD))
  5823. return true;
  5824. }
  5825. }
  5826. }
  5827. if (sourceTypeInfo.ShapeKind != AR_TOBJ_SCALAR &&
  5828. sourceTypeInfo.ShapeKind != AR_TOBJ_VECTOR &&
  5829. sourceTypeInfo.ShapeKind != AR_TOBJ_MATRIX)
  5830. {
  5831. return false;
  5832. }
  5833. return targetTypeInfo.uTotalElts <= sourceTypeInfo.uTotalElts;
  5834. }
  5835. bool HLSLExternalSource::IsConversionToLessOrEqualElements(
  5836. const ExprResult& sourceExpr,
  5837. const QualType& targetType,
  5838. bool explicitConversion)
  5839. {
  5840. if (sourceExpr.isInvalid() || targetType.isNull())
  5841. {
  5842. return false;
  5843. }
  5844. return IsConversionToLessOrEqualElements(sourceExpr.get()->getType(), targetType, explicitConversion);
  5845. }
  5846. bool HLSLExternalSource::IsTypeNumeric(QualType type, UINT* count)
  5847. {
  5848. DXASSERT_NOMSG(!type.isNull());
  5849. DXASSERT_NOMSG(count != nullptr);
  5850. *count = 0;
  5851. UINT subCount = 0;
  5852. ArTypeObjectKind shapeKind = GetTypeObjectKind(type);
  5853. switch (shapeKind)
  5854. {
  5855. case AR_TOBJ_ARRAY:
  5856. if (IsTypeNumeric(m_context->getAsArrayType(type)->getElementType(), &subCount))
  5857. {
  5858. *count = subCount * GetArraySize(type);
  5859. return true;
  5860. }
  5861. return false;
  5862. case AR_TOBJ_COMPOUND:
  5863. {
  5864. UINT maxCount = 0;
  5865. { // Determine maximum count to prevent infinite loop on incomplete array
  5866. FlattenedTypeIterator itCount(SourceLocation(), type, *this);
  5867. maxCount = itCount.countRemaining();
  5868. if (!maxCount) {
  5869. return false; // empty struct.
  5870. }
  5871. }
  5872. FlattenedTypeIterator it(SourceLocation(), type, *this);
  5873. while (it.hasCurrentElement()) {
  5874. bool isFieldNumeric = IsTypeNumeric(it.getCurrentElement(), &subCount);
  5875. if (!isFieldNumeric) {
  5876. return false;
  5877. }
  5878. if (*count >= maxCount) {
  5879. // this element is an incomplete array at the end; iterator will not advance past this element.
  5880. // don't add to *count either, so *count will represent minimum size of the structure.
  5881. break;
  5882. }
  5883. *count += (subCount * it.getCurrentElementSize());
  5884. it.advanceCurrentElement(it.getCurrentElementSize());
  5885. }
  5886. return true;
  5887. }
  5888. default:
  5889. DXASSERT(false, "unreachable");
  5890. case AR_TOBJ_BASIC:
  5891. case AR_TOBJ_MATRIX:
  5892. case AR_TOBJ_VECTOR:
  5893. *count = GetElementCount(type);
  5894. return IsBasicKindNumeric(GetTypeElementKind(type));
  5895. case AR_TOBJ_OBJECT:
  5896. return false;
  5897. }
  5898. }
  5899. enum MatrixMemberAccessError {
  5900. MatrixMemberAccessError_None, // No errors found.
  5901. MatrixMemberAccessError_BadFormat, // Formatting error (non-digit).
  5902. MatrixMemberAccessError_MixingRefs, // Mix of zero-based and one-based references.
  5903. MatrixMemberAccessError_Empty, // No members specified.
  5904. MatrixMemberAccessError_ZeroInOneBased, // A zero was used in a one-based reference.
  5905. MatrixMemberAccessError_FourInZeroBased, // A four was used in a zero-based reference.
  5906. MatrixMemberAccessError_TooManyPositions, // Too many positions (more than four) were specified.
  5907. };
  5908. static
  5909. MatrixMemberAccessError TryConsumeMatrixDigit(const char*& memberText, uint32_t* value)
  5910. {
  5911. DXASSERT_NOMSG(memberText != nullptr);
  5912. DXASSERT_NOMSG(value != nullptr);
  5913. if ('0' <= *memberText && *memberText <= '9')
  5914. {
  5915. *value = (*memberText) - '0';
  5916. }
  5917. else
  5918. {
  5919. return MatrixMemberAccessError_BadFormat;
  5920. }
  5921. memberText++;
  5922. return MatrixMemberAccessError_None;
  5923. }
  5924. static
  5925. MatrixMemberAccessError TryParseMatrixMemberAccess(_In_z_ const char* memberText, _Out_ MatrixMemberAccessPositions* value)
  5926. {
  5927. DXASSERT_NOMSG(memberText != nullptr);
  5928. DXASSERT_NOMSG(value != nullptr);
  5929. MatrixMemberAccessPositions result;
  5930. bool zeroBasedDecided = false;
  5931. bool zeroBased = false;
  5932. // Set the output value to invalid to allow early exits when errors are found.
  5933. value->IsValid = 0;
  5934. // Assume this is true until proven otherwise.
  5935. result.IsValid = 1;
  5936. result.Count = 0;
  5937. while (*memberText)
  5938. {
  5939. // Check for a leading underscore.
  5940. if (*memberText != '_')
  5941. {
  5942. return MatrixMemberAccessError_BadFormat;
  5943. }
  5944. ++memberText;
  5945. // Check whether we have an 'm' or a digit.
  5946. if (*memberText == 'm')
  5947. {
  5948. if (zeroBasedDecided && !zeroBased)
  5949. {
  5950. return MatrixMemberAccessError_MixingRefs;
  5951. }
  5952. zeroBased = true;
  5953. zeroBasedDecided = true;
  5954. ++memberText;
  5955. }
  5956. else if (!('0' <= *memberText && *memberText <= '9'))
  5957. {
  5958. return MatrixMemberAccessError_BadFormat;
  5959. }
  5960. else
  5961. {
  5962. if (zeroBasedDecided && zeroBased)
  5963. {
  5964. return MatrixMemberAccessError_MixingRefs;
  5965. }
  5966. zeroBased = false;
  5967. zeroBasedDecided = true;
  5968. }
  5969. // Consume two digits for the position.
  5970. uint32_t rowPosition;
  5971. uint32_t colPosition;
  5972. MatrixMemberAccessError digitError;
  5973. if (MatrixMemberAccessError_None != (digitError = TryConsumeMatrixDigit(memberText, &rowPosition)))
  5974. {
  5975. return digitError;
  5976. }
  5977. if (MatrixMemberAccessError_None != (digitError = TryConsumeMatrixDigit(memberText, &colPosition)))
  5978. {
  5979. return digitError;
  5980. }
  5981. // Look for specific common errors (developer likely mixed up reference style).
  5982. if (zeroBased)
  5983. {
  5984. if (rowPosition == 4 || colPosition == 4)
  5985. {
  5986. return MatrixMemberAccessError_FourInZeroBased;
  5987. }
  5988. }
  5989. else
  5990. {
  5991. if (rowPosition == 0 || colPosition == 0)
  5992. {
  5993. return MatrixMemberAccessError_ZeroInOneBased;
  5994. }
  5995. // SetPosition will use zero-based indices.
  5996. --rowPosition;
  5997. --colPosition;
  5998. }
  5999. if (result.Count == 4)
  6000. {
  6001. return MatrixMemberAccessError_TooManyPositions;
  6002. }
  6003. result.SetPosition(result.Count, rowPosition, colPosition);
  6004. result.Count++;
  6005. }
  6006. if (result.Count == 0)
  6007. {
  6008. return MatrixMemberAccessError_Empty;
  6009. }
  6010. *value = result;
  6011. return MatrixMemberAccessError_None;
  6012. }
  6013. bool HLSLExternalSource::LookupMatrixMemberExprForHLSL(
  6014. Expr& BaseExpr,
  6015. DeclarationName MemberName,
  6016. bool IsArrow,
  6017. SourceLocation OpLoc,
  6018. SourceLocation MemberLoc,
  6019. ExprResult* result)
  6020. {
  6021. DXASSERT_NOMSG(result != nullptr);
  6022. QualType BaseType = BaseExpr.getType();
  6023. DXASSERT(!BaseType.isNull(), "otherwise caller should have stopped analysis much earlier");
  6024. // Assume failure.
  6025. *result = ExprError();
  6026. if (GetTypeObjectKind(BaseType) != AR_TOBJ_MATRIX)
  6027. {
  6028. return false;
  6029. }
  6030. QualType elementType;
  6031. UINT rowCount, colCount;
  6032. GetRowsAndCols(BaseType, rowCount, colCount);
  6033. elementType = GetMatrixOrVectorElementType(BaseType);
  6034. IdentifierInfo *member = MemberName.getAsIdentifierInfo();
  6035. const char *memberText = member->getNameStart();
  6036. MatrixMemberAccessPositions positions;
  6037. MatrixMemberAccessError memberAccessError;
  6038. unsigned msg = 0;
  6039. memberAccessError = TryParseMatrixMemberAccess(memberText, &positions);
  6040. switch (memberAccessError)
  6041. {
  6042. case MatrixMemberAccessError_BadFormat:
  6043. msg = diag::err_hlsl_matrix_member_bad_format;
  6044. break;
  6045. case MatrixMemberAccessError_Empty:
  6046. msg = diag::err_hlsl_matrix_member_empty;
  6047. break;
  6048. case MatrixMemberAccessError_FourInZeroBased:
  6049. msg = diag::err_hlsl_matrix_member_four_in_zero_based;
  6050. break;
  6051. case MatrixMemberAccessError_MixingRefs:
  6052. msg = diag::err_hlsl_matrix_member_mixing_refs;
  6053. break;
  6054. case MatrixMemberAccessError_None:
  6055. msg = 0;
  6056. DXASSERT(positions.IsValid, "otherwise an error should have been returned");
  6057. // Check the position with the type now.
  6058. for (unsigned int i = 0; i < positions.Count; i++)
  6059. {
  6060. uint32_t rowPos, colPos;
  6061. positions.GetPosition(i, &rowPos, &colPos);
  6062. if (rowPos >= rowCount || colPos >= colCount)
  6063. {
  6064. msg = diag::err_hlsl_matrix_member_out_of_bounds;
  6065. break;
  6066. }
  6067. }
  6068. break;
  6069. case MatrixMemberAccessError_TooManyPositions:
  6070. msg = diag::err_hlsl_matrix_member_too_many_positions;
  6071. break;
  6072. case MatrixMemberAccessError_ZeroInOneBased:
  6073. msg = diag::err_hlsl_matrix_member_zero_in_one_based;
  6074. break;
  6075. default:
  6076. llvm_unreachable("Unknown MatrixMemberAccessError value");
  6077. }
  6078. if (msg != 0)
  6079. {
  6080. m_sema->Diag(MemberLoc, msg) << memberText;
  6081. // It's possible that it's a simple out-of-bounds condition. In this case,
  6082. // generate the member access expression with the correct arity and continue
  6083. // processing.
  6084. if (!positions.IsValid)
  6085. {
  6086. return true;
  6087. }
  6088. }
  6089. DXASSERT(positions.IsValid, "otherwise an error should have been returned");
  6090. // Consume elements
  6091. QualType resultType;
  6092. if (positions.Count == 1)
  6093. resultType = elementType;
  6094. else
  6095. resultType = NewSimpleAggregateType(AR_TOBJ_UNKNOWN, GetTypeElementKind(elementType), 0, OneRow, positions.Count);
  6096. // Add qualifiers from BaseType.
  6097. resultType = m_context->getQualifiedType(resultType, BaseType.getQualifiers());
  6098. ExprValueKind VK =
  6099. positions.ContainsDuplicateElements() ? VK_RValue :
  6100. (IsArrow ? VK_LValue : BaseExpr.getValueKind());
  6101. ExtMatrixElementExpr* matrixExpr = new (m_context)ExtMatrixElementExpr(resultType, VK, &BaseExpr, *member, MemberLoc, positions);
  6102. *result = matrixExpr;
  6103. return true;
  6104. }
  6105. enum VectorMemberAccessError {
  6106. VectorMemberAccessError_None, // No errors found.
  6107. VectorMemberAccessError_BadFormat, // Formatting error (not in 'rgba' or 'xyzw').
  6108. VectorMemberAccessError_MixingStyles, // Mix of rgba and xyzw swizzle styles.
  6109. VectorMemberAccessError_Empty, // No members specified.
  6110. VectorMemberAccessError_TooManyPositions, // Too many positions (more than four) were specified.
  6111. };
  6112. static
  6113. VectorMemberAccessError TryConsumeVectorDigit(const char*& memberText, uint32_t* value, bool &rgbaStyle) {
  6114. DXASSERT_NOMSG(memberText != nullptr);
  6115. DXASSERT_NOMSG(value != nullptr);
  6116. rgbaStyle = false;
  6117. switch (*memberText) {
  6118. case 'r':
  6119. rgbaStyle = true;
  6120. case 'x':
  6121. *value = 0;
  6122. break;
  6123. case 'g':
  6124. rgbaStyle = true;
  6125. case 'y':
  6126. *value = 1;
  6127. break;
  6128. case 'b':
  6129. rgbaStyle = true;
  6130. case 'z':
  6131. *value = 2;
  6132. break;
  6133. case 'a':
  6134. rgbaStyle = true;
  6135. case 'w':
  6136. *value = 3;
  6137. break;
  6138. default:
  6139. return VectorMemberAccessError_BadFormat;
  6140. }
  6141. memberText++;
  6142. return VectorMemberAccessError_None;
  6143. }
  6144. static
  6145. VectorMemberAccessError TryParseVectorMemberAccess(_In_z_ const char* memberText, _Out_ VectorMemberAccessPositions* value) {
  6146. DXASSERT_NOMSG(memberText != nullptr);
  6147. DXASSERT_NOMSG(value != nullptr);
  6148. VectorMemberAccessPositions result;
  6149. bool rgbaStyleDecided = false;
  6150. bool rgbaStyle = false;
  6151. // Set the output value to invalid to allow early exits when errors are found.
  6152. value->IsValid = 0;
  6153. // Assume this is true until proven otherwise.
  6154. result.IsValid = 1;
  6155. result.Count = 0;
  6156. while (*memberText) {
  6157. // Consume one character for the swizzle.
  6158. uint32_t colPosition;
  6159. VectorMemberAccessError digitError;
  6160. bool rgbaStyleTmp = false;
  6161. if (VectorMemberAccessError_None != (digitError = TryConsumeVectorDigit(memberText, &colPosition, rgbaStyleTmp))) {
  6162. return digitError;
  6163. }
  6164. if (rgbaStyleDecided && rgbaStyleTmp != rgbaStyle) {
  6165. return VectorMemberAccessError_MixingStyles;
  6166. }
  6167. else {
  6168. rgbaStyleDecided = true;
  6169. rgbaStyle = rgbaStyleTmp;
  6170. }
  6171. if (result.Count == 4) {
  6172. return VectorMemberAccessError_TooManyPositions;
  6173. }
  6174. result.SetPosition(result.Count, colPosition);
  6175. result.Count++;
  6176. }
  6177. if (result.Count == 0) {
  6178. return VectorMemberAccessError_Empty;
  6179. }
  6180. *value = result;
  6181. return VectorMemberAccessError_None;
  6182. }
  6183. bool HLSLExternalSource::LookupVectorMemberExprForHLSL(
  6184. Expr& BaseExpr,
  6185. DeclarationName MemberName,
  6186. bool IsArrow,
  6187. SourceLocation OpLoc,
  6188. SourceLocation MemberLoc,
  6189. ExprResult* result) {
  6190. DXASSERT_NOMSG(result != nullptr);
  6191. QualType BaseType = BaseExpr.getType();
  6192. DXASSERT(!BaseType.isNull(), "otherwise caller should have stopped analysis much earlier");
  6193. // Assume failure.
  6194. *result = ExprError();
  6195. if (GetTypeObjectKind(BaseType) != AR_TOBJ_VECTOR) {
  6196. return false;
  6197. }
  6198. QualType elementType;
  6199. UINT colCount = GetHLSLVecSize(BaseType);
  6200. elementType = GetMatrixOrVectorElementType(BaseType);
  6201. IdentifierInfo *member = MemberName.getAsIdentifierInfo();
  6202. const char *memberText = member->getNameStart();
  6203. VectorMemberAccessPositions positions;
  6204. VectorMemberAccessError memberAccessError;
  6205. unsigned msg = 0;
  6206. memberAccessError = TryParseVectorMemberAccess(memberText, &positions);
  6207. switch (memberAccessError) {
  6208. case VectorMemberAccessError_BadFormat:
  6209. msg = diag::err_hlsl_vector_member_bad_format;
  6210. break;
  6211. case VectorMemberAccessError_Empty:
  6212. msg = diag::err_hlsl_vector_member_empty;
  6213. break;
  6214. case VectorMemberAccessError_MixingStyles:
  6215. msg = diag::err_ext_vector_component_name_mixedsets;
  6216. break;
  6217. case VectorMemberAccessError_None:
  6218. msg = 0;
  6219. DXASSERT(positions.IsValid, "otherwise an error should have been returned");
  6220. // Check the position with the type now.
  6221. for (unsigned int i = 0; i < positions.Count; i++) {
  6222. uint32_t colPos;
  6223. positions.GetPosition(i, &colPos);
  6224. if (colPos >= colCount) {
  6225. msg = diag::err_hlsl_vector_member_out_of_bounds;
  6226. break;
  6227. }
  6228. }
  6229. break;
  6230. case VectorMemberAccessError_TooManyPositions:
  6231. msg = diag::err_hlsl_vector_member_too_many_positions;
  6232. break;
  6233. default:
  6234. llvm_unreachable("Unknown VectorMemberAccessError value");
  6235. }
  6236. if (msg != 0) {
  6237. m_sema->Diag(MemberLoc, msg) << memberText;
  6238. // It's possible that it's a simple out-of-bounds condition. In this case,
  6239. // generate the member access expression with the correct arity and continue
  6240. // processing.
  6241. if (!positions.IsValid) {
  6242. return true;
  6243. }
  6244. }
  6245. DXASSERT(positions.IsValid, "otherwise an error should have been returned");
  6246. // Consume elements
  6247. QualType resultType;
  6248. if (positions.Count == 1)
  6249. resultType = elementType;
  6250. else
  6251. resultType = NewSimpleAggregateType(AR_TOBJ_UNKNOWN, GetTypeElementKind(elementType), 0, OneRow, positions.Count);
  6252. // Add qualifiers from BaseType.
  6253. resultType = m_context->getQualifiedType(resultType, BaseType.getQualifiers());
  6254. ExprValueKind VK =
  6255. positions.ContainsDuplicateElements() ? VK_RValue :
  6256. (IsArrow ? VK_LValue : BaseExpr.getValueKind());
  6257. HLSLVectorElementExpr* vectorExpr = new (m_context)HLSLVectorElementExpr(resultType, VK, &BaseExpr, *member, MemberLoc, positions);
  6258. *result = vectorExpr;
  6259. return true;
  6260. }
  6261. bool HLSLExternalSource::LookupArrayMemberExprForHLSL(
  6262. Expr& BaseExpr,
  6263. DeclarationName MemberName,
  6264. bool IsArrow,
  6265. SourceLocation OpLoc,
  6266. SourceLocation MemberLoc,
  6267. ExprResult* result) {
  6268. DXASSERT_NOMSG(result != nullptr);
  6269. QualType BaseType = BaseExpr.getType();
  6270. DXASSERT(!BaseType.isNull(), "otherwise caller should have stopped analysis much earlier");
  6271. // Assume failure.
  6272. *result = ExprError();
  6273. if (GetTypeObjectKind(BaseType) != AR_TOBJ_ARRAY) {
  6274. return false;
  6275. }
  6276. IdentifierInfo *member = MemberName.getAsIdentifierInfo();
  6277. const char *memberText = member->getNameStart();
  6278. // The only property available on arrays is Length; it is deprecated and available only on HLSL version <=2018
  6279. if (member->getLength() == 6 && 0 == strcmp(memberText, "Length")) {
  6280. if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(BaseType)) {
  6281. // check version support
  6282. unsigned hlslVer = getSema()->getLangOpts().HLSLVersion;
  6283. if (hlslVer > 2016) {
  6284. m_sema->Diag(MemberLoc, diag::err_hlsl_unsupported_for_version_lower) << "Length" << "2016";
  6285. return false;
  6286. }
  6287. if (hlslVer == 2016) {
  6288. m_sema->Diag(MemberLoc, diag::warn_deprecated) << "Length";
  6289. }
  6290. UnaryExprOrTypeTraitExpr *arrayLenExpr = new (m_context) UnaryExprOrTypeTraitExpr(
  6291. UETT_ArrayLength, &BaseExpr, m_context->getSizeType(), MemberLoc, BaseExpr.getSourceRange().getEnd());
  6292. *result = arrayLenExpr;
  6293. return true;
  6294. }
  6295. }
  6296. return false;
  6297. }
  6298. ExprResult HLSLExternalSource::MaybeConvertScalarToVector(_In_ clang::Expr* E) {
  6299. DXASSERT_NOMSG(E != nullptr);
  6300. ArBasicKind basic = GetTypeElementKind(E->getType());
  6301. if (!IS_BASIC_PRIMITIVE(basic)) {
  6302. return E;
  6303. }
  6304. ArTypeObjectKind kind = GetTypeObjectKind(E->getType());
  6305. if (kind != AR_TOBJ_SCALAR) {
  6306. return E;
  6307. }
  6308. QualType targetType = NewSimpleAggregateType(AR_TOBJ_VECTOR, basic, 0, 1, 1);
  6309. return ImplicitCastExpr::Create(*m_context, targetType, CastKind::CK_HLSLVectorSplat, E, nullptr, E->getValueKind());
  6310. }
  6311. static clang::CastKind ImplicitConversionKindToCastKind(
  6312. clang::ImplicitConversionKind ICK,
  6313. ArBasicKind FromKind,
  6314. ArBasicKind ToKind) {
  6315. // TODO: Shouldn't we have more specific ICK enums so we don't have to re-evaluate
  6316. // based on from/to kinds in order to determine CastKind?
  6317. // There's a FIXME note in PerformImplicitConversion that calls out exactly this
  6318. // problem.
  6319. switch (ICK) {
  6320. case ICK_Integral_Promotion:
  6321. case ICK_Integral_Conversion:
  6322. return CK_IntegralCast;
  6323. case ICK_Floating_Promotion:
  6324. case ICK_Floating_Conversion:
  6325. return CK_FloatingCast;
  6326. case ICK_Floating_Integral:
  6327. if (IS_BASIC_FLOAT(FromKind) && IS_BASIC_AINT(ToKind))
  6328. return CK_FloatingToIntegral;
  6329. else if ((IS_BASIC_AINT(FromKind) || IS_BASIC_BOOL(FromKind)) && IS_BASIC_FLOAT(ToKind))
  6330. return CK_IntegralToFloating;
  6331. break;
  6332. case ICK_Boolean_Conversion:
  6333. if (IS_BASIC_FLOAT(FromKind) && IS_BASIC_BOOL(ToKind))
  6334. return CK_FloatingToBoolean;
  6335. else if (IS_BASIC_AINT(FromKind) && IS_BASIC_BOOL(ToKind))
  6336. return CK_IntegralToBoolean;
  6337. break;
  6338. default:
  6339. // Only covers implicit conversions with cast kind equivalents.
  6340. return CK_Invalid;
  6341. }
  6342. return CK_Invalid;
  6343. }
  6344. static clang::CastKind ConvertToComponentCastKind(clang::CastKind CK) {
  6345. switch (CK) {
  6346. case CK_IntegralCast:
  6347. return CK_HLSLCC_IntegralCast;
  6348. case CK_FloatingCast:
  6349. return CK_HLSLCC_FloatingCast;
  6350. case CK_FloatingToIntegral:
  6351. return CK_HLSLCC_FloatingToIntegral;
  6352. case CK_IntegralToFloating:
  6353. return CK_HLSLCC_IntegralToFloating;
  6354. case CK_FloatingToBoolean:
  6355. return CK_HLSLCC_FloatingToBoolean;
  6356. case CK_IntegralToBoolean:
  6357. return CK_HLSLCC_IntegralToBoolean;
  6358. default:
  6359. // Only HLSLCC castkinds are relevant. Ignore the rest.
  6360. return CK_Invalid;
  6361. }
  6362. return CK_Invalid;
  6363. }
  6364. clang::Expr *HLSLExternalSource::HLSLImpCastToScalar(
  6365. _In_ clang::Sema* self,
  6366. _In_ clang::Expr* From,
  6367. ArTypeObjectKind FromShape,
  6368. ArBasicKind EltKind)
  6369. {
  6370. clang::CastKind CK = CK_Invalid;
  6371. if (AR_TOBJ_MATRIX == FromShape)
  6372. CK = CK_HLSLMatrixToScalarCast;
  6373. if (AR_TOBJ_VECTOR == FromShape)
  6374. CK = CK_HLSLVectorToScalarCast;
  6375. if (CK_Invalid != CK) {
  6376. return self->ImpCastExprToType(From,
  6377. NewSimpleAggregateType(AR_TOBJ_BASIC, EltKind, 0, 1, 1), CK, From->getValueKind()).get();
  6378. }
  6379. return From;
  6380. }
  6381. clang::ExprResult HLSLExternalSource::PerformHLSLConversion(
  6382. _In_ clang::Expr* From,
  6383. _In_ clang::QualType targetType,
  6384. _In_ const clang::StandardConversionSequence &SCS,
  6385. _In_ clang::Sema::CheckedConversionKind CCK)
  6386. {
  6387. QualType sourceType = From->getType();
  6388. sourceType = GetStructuralForm(sourceType);
  6389. targetType = GetStructuralForm(targetType);
  6390. ArTypeInfo SourceInfo, TargetInfo;
  6391. CollectInfo(sourceType, &SourceInfo);
  6392. CollectInfo(targetType, &TargetInfo);
  6393. clang::CastKind CK = CK_Invalid;
  6394. QualType intermediateTarget;
  6395. // TODO: construct vector/matrix and component cast expressions
  6396. switch (SCS.Second) {
  6397. case ICK_Flat_Conversion: {
  6398. // TODO: determine how to handle individual component conversions:
  6399. // - have an array of conversions for ComponentConversion in SCS?
  6400. // convert that to an array of casts under a special kind of flat
  6401. // flat conversion node? What do component conversion casts cast
  6402. // from? We don't have a From expression for individiual components.
  6403. From = m_sema->ImpCastExprToType(From, targetType.getUnqualifiedType(), CK_FlatConversion, From->getValueKind(), /*BasePath=*/0, CCK).get();
  6404. break;
  6405. }
  6406. case ICK_HLSL_Derived_To_Base: {
  6407. CXXCastPath BasePath;
  6408. if (m_sema->CheckDerivedToBaseConversion(
  6409. sourceType, targetType.getNonReferenceType(), From->getLocStart(),
  6410. From->getSourceRange(), &BasePath, /*IgnoreAccess=*/true))
  6411. return ExprError();
  6412. From = m_sema->ImpCastExprToType(From, targetType.getUnqualifiedType(), CK_HLSLDerivedToBase, From->getValueKind(), &BasePath, CCK).get();
  6413. break;
  6414. }
  6415. case ICK_HLSLVector_Splat: {
  6416. // 1. optionally convert from vec1 or mat1x1 to scalar
  6417. From = HLSLImpCastToScalar(m_sema, From, SourceInfo.ShapeKind, SourceInfo.EltKind);
  6418. // 2. optionally convert component type
  6419. if (ICK_Identity != SCS.ComponentConversion) {
  6420. CK = ImplicitConversionKindToCastKind(SCS.ComponentConversion, SourceInfo.EltKind, TargetInfo.EltKind);
  6421. if (CK_Invalid != CK) {
  6422. From = m_sema->ImpCastExprToType(From,
  6423. NewSimpleAggregateType(AR_TOBJ_BASIC, TargetInfo.EltKind, 0, 1, 1), CK, From->getValueKind(), /*BasePath=*/0, CCK).get();
  6424. }
  6425. }
  6426. // 3. splat scalar to final vector or matrix
  6427. CK = CK_Invalid;
  6428. if (AR_TOBJ_VECTOR == TargetInfo.ShapeKind)
  6429. CK = CK_HLSLVectorSplat;
  6430. else if (AR_TOBJ_MATRIX == TargetInfo.ShapeKind)
  6431. CK = CK_HLSLMatrixSplat;
  6432. if (CK_Invalid != CK) {
  6433. From = m_sema->ImpCastExprToType(From,
  6434. NewSimpleAggregateType(TargetInfo.ShapeKind, TargetInfo.EltKind, 0, TargetInfo.uRows, TargetInfo.uCols), CK, From->getValueKind(), /*BasePath=*/0, CCK).get();
  6435. }
  6436. break;
  6437. }
  6438. case ICK_HLSLVector_Scalar: {
  6439. // 1. select vector or matrix component
  6440. From = HLSLImpCastToScalar(m_sema, From, SourceInfo.ShapeKind, SourceInfo.EltKind);
  6441. // 2. optionally convert component type
  6442. if (ICK_Identity != SCS.ComponentConversion) {
  6443. CK = ImplicitConversionKindToCastKind(SCS.ComponentConversion, SourceInfo.EltKind, TargetInfo.EltKind);
  6444. if (CK_Invalid != CK) {
  6445. From = m_sema->ImpCastExprToType(From,
  6446. NewSimpleAggregateType(AR_TOBJ_BASIC, TargetInfo.EltKind, 0, 1, 1), CK, From->getValueKind(), /*BasePath=*/0, CCK).get();
  6447. }
  6448. }
  6449. break;
  6450. }
  6451. // The following two (three if we re-introduce ICK_HLSLComponent_Conversion) steps
  6452. // can be done with case fall-through, since this is the order in which we want to
  6453. // do the conversion operations.
  6454. case ICK_HLSLVector_Truncation: {
  6455. // 1. dimension truncation
  6456. // vector truncation or matrix truncation?
  6457. if (SourceInfo.ShapeKind == AR_TOBJ_VECTOR) {
  6458. From = m_sema->ImpCastExprToType(From,
  6459. NewSimpleAggregateType(AR_TOBJ_VECTOR, SourceInfo.EltKind, 0, 1, TargetInfo.uTotalElts),
  6460. CK_HLSLVectorTruncationCast, From->getValueKind(), /*BasePath=*/0, CCK).get();
  6461. } else if (SourceInfo.ShapeKind == AR_TOBJ_MATRIX) {
  6462. if (TargetInfo.ShapeKind == AR_TOBJ_VECTOR && 1 == SourceInfo.uCols) {
  6463. // Handle the column to vector case
  6464. From = m_sema->ImpCastExprToType(From,
  6465. NewSimpleAggregateType(AR_TOBJ_MATRIX, SourceInfo.EltKind, 0, TargetInfo.uCols, 1),
  6466. CK_HLSLMatrixTruncationCast, From->getValueKind(), /*BasePath=*/0, CCK).get();
  6467. } else {
  6468. From = m_sema->ImpCastExprToType(From,
  6469. NewSimpleAggregateType(AR_TOBJ_MATRIX, SourceInfo.EltKind, 0, TargetInfo.uRows, TargetInfo.uCols),
  6470. CK_HLSLMatrixTruncationCast, From->getValueKind(), /*BasePath=*/0, CCK).get();
  6471. }
  6472. } else {
  6473. DXASSERT(false, "PerformHLSLConversion: Invalid source type for truncation cast");
  6474. }
  6475. }
  6476. __fallthrough;
  6477. case ICK_HLSLVector_Conversion: {
  6478. // 2. Do ShapeKind conversion if necessary
  6479. if (SourceInfo.ShapeKind != TargetInfo.ShapeKind) {
  6480. switch (TargetInfo.ShapeKind) {
  6481. case AR_TOBJ_VECTOR:
  6482. DXASSERT(AR_TOBJ_MATRIX == SourceInfo.ShapeKind, "otherwise, invalid casting sequence");
  6483. From = m_sema->ImpCastExprToType(From,
  6484. NewSimpleAggregateType(AR_TOBJ_VECTOR, SourceInfo.EltKind, 0, TargetInfo.uRows, TargetInfo.uCols),
  6485. CK_HLSLMatrixToVectorCast, From->getValueKind(), /*BasePath=*/0, CCK).get();
  6486. break;
  6487. case AR_TOBJ_MATRIX:
  6488. DXASSERT(AR_TOBJ_VECTOR == SourceInfo.ShapeKind, "otherwise, invalid casting sequence");
  6489. From = m_sema->ImpCastExprToType(From,
  6490. NewSimpleAggregateType(AR_TOBJ_MATRIX, SourceInfo.EltKind, 0, TargetInfo.uRows, TargetInfo.uCols),
  6491. CK_HLSLVectorToMatrixCast, From->getValueKind(), /*BasePath=*/0, CCK).get();
  6492. break;
  6493. case AR_TOBJ_BASIC:
  6494. // Truncation may be followed by cast to scalar
  6495. From = HLSLImpCastToScalar(m_sema, From, SourceInfo.ShapeKind, SourceInfo.EltKind);
  6496. break;
  6497. default:
  6498. DXASSERT(false, "otherwise, invalid casting sequence");
  6499. break;
  6500. }
  6501. }
  6502. // 3. Do component type conversion
  6503. if (ICK_Identity != SCS.ComponentConversion) {
  6504. CK = ImplicitConversionKindToCastKind(SCS.ComponentConversion, SourceInfo.EltKind, TargetInfo.EltKind);
  6505. if (TargetInfo.ShapeKind != AR_TOBJ_BASIC)
  6506. CK = ConvertToComponentCastKind(CK);
  6507. if (CK_Invalid != CK) {
  6508. From = m_sema->ImpCastExprToType(From, targetType, CK, From->getValueKind(), /*BasePath=*/0, CCK).get();
  6509. }
  6510. }
  6511. break;
  6512. }
  6513. case ICK_Identity:
  6514. // Nothing to do.
  6515. break;
  6516. default:
  6517. DXASSERT(false, "PerformHLSLConversion: Invalid SCS.Second conversion kind");
  6518. }
  6519. return From;
  6520. }
  6521. void HLSLExternalSource::GetConversionForm(
  6522. QualType type,
  6523. bool explicitConversion,
  6524. ArTypeInfo* pTypeInfo)
  6525. {
  6526. //if (!CollectInfo(AR_TINFO_ALLOW_ALL, pTypeInfo))
  6527. CollectInfo(type, pTypeInfo);
  6528. // The fxc implementation reported pTypeInfo->ShapeKind separately in an output argument,
  6529. // but that value is only used for pointer conversions.
  6530. // When explicitly converting types complex aggregates can be treated
  6531. // as vectors if they are entirely numeric.
  6532. switch (pTypeInfo->ShapeKind)
  6533. {
  6534. case AR_TOBJ_COMPOUND:
  6535. case AR_TOBJ_ARRAY:
  6536. if (explicitConversion && IsTypeNumeric(type, &pTypeInfo->uTotalElts))
  6537. {
  6538. pTypeInfo->ShapeKind = AR_TOBJ_VECTOR;
  6539. }
  6540. else
  6541. {
  6542. pTypeInfo->ShapeKind = AR_TOBJ_COMPOUND;
  6543. }
  6544. DXASSERT_NOMSG(pTypeInfo->uRows == 1);
  6545. pTypeInfo->uCols = pTypeInfo->uTotalElts;
  6546. break;
  6547. case AR_TOBJ_VECTOR:
  6548. case AR_TOBJ_MATRIX:
  6549. // Convert 1x1 types to scalars.
  6550. if (pTypeInfo->uCols == 1 && pTypeInfo->uRows == 1)
  6551. {
  6552. pTypeInfo->ShapeKind = AR_TOBJ_BASIC;
  6553. }
  6554. break;
  6555. default:
  6556. // Only convertable shapekinds are relevant.
  6557. break;
  6558. }
  6559. }
  6560. static
  6561. bool HandleVoidConversion(QualType source, QualType target, bool explicitConversion, _Out_ bool* allowed)
  6562. {
  6563. DXASSERT_NOMSG(allowed != nullptr);
  6564. bool applicable = true;
  6565. *allowed = true;
  6566. if (explicitConversion) {
  6567. // (void) non-void
  6568. if (target->isVoidType()) {
  6569. DXASSERT_NOMSG(*allowed);
  6570. }
  6571. // (non-void) void
  6572. else if (source->isVoidType()) {
  6573. *allowed = false;
  6574. }
  6575. else {
  6576. applicable = false;
  6577. }
  6578. }
  6579. else {
  6580. // (void) void
  6581. if (source->isVoidType() && target->isVoidType()) {
  6582. DXASSERT_NOMSG(*allowed);
  6583. }
  6584. // (void) non-void, (non-void) void
  6585. else if (source->isVoidType() || target->isVoidType()) {
  6586. *allowed = false;
  6587. }
  6588. else {
  6589. applicable = false;
  6590. }
  6591. }
  6592. return applicable;
  6593. }
  6594. static bool ConvertDimensions(ArTypeInfo TargetInfo, ArTypeInfo SourceInfo,
  6595. ImplicitConversionKind &Second,
  6596. TYPE_CONVERSION_REMARKS &Remarks) {
  6597. // The rules for aggregate conversions are:
  6598. // 1. A scalar can be replicated to any layout.
  6599. // 2. Any type may be truncated to anything else with one component.
  6600. // 3. A vector may be truncated to a smaller vector.
  6601. // 4. A matrix may be truncated to a smaller matrix.
  6602. // 5. The result of a vector and a matrix is:
  6603. // a. If the matrix has one row it's a vector-sized
  6604. // piece of the row.
  6605. // b. If the matrix has one column it's a vector-sized
  6606. // piece of the column.
  6607. // c. Otherwise the number of elements in the vector
  6608. // and matrix must match and the result is the vector.
  6609. // 6. The result of a matrix and a vector is similar to #5.
  6610. switch (TargetInfo.ShapeKind) {
  6611. case AR_TOBJ_BASIC:
  6612. switch (SourceInfo.ShapeKind)
  6613. {
  6614. case AR_TOBJ_BASIC:
  6615. Second = ICK_Identity;
  6616. break;
  6617. case AR_TOBJ_VECTOR:
  6618. if (1 < SourceInfo.uCols)
  6619. Second = ICK_HLSLVector_Truncation;
  6620. else
  6621. Second = ICK_HLSLVector_Scalar;
  6622. break;
  6623. case AR_TOBJ_MATRIX:
  6624. if (1 < SourceInfo.uRows * SourceInfo.uCols)
  6625. Second = ICK_HLSLVector_Truncation;
  6626. else
  6627. Second = ICK_HLSLVector_Scalar;
  6628. break;
  6629. default:
  6630. return false;
  6631. }
  6632. break;
  6633. case AR_TOBJ_VECTOR:
  6634. switch (SourceInfo.ShapeKind)
  6635. {
  6636. case AR_TOBJ_BASIC:
  6637. // Conversions between scalars and aggregates are always supported.
  6638. Second = ICK_HLSLVector_Splat;
  6639. break;
  6640. case AR_TOBJ_VECTOR:
  6641. if (TargetInfo.uCols > SourceInfo.uCols) {
  6642. if (SourceInfo.uCols == 1) {
  6643. Second = ICK_HLSLVector_Splat;
  6644. }
  6645. else {
  6646. return false;
  6647. }
  6648. }
  6649. else if (TargetInfo.uCols < SourceInfo.uCols) {
  6650. Second = ICK_HLSLVector_Truncation;
  6651. }
  6652. else {
  6653. Second = ICK_Identity;
  6654. }
  6655. break;
  6656. case AR_TOBJ_MATRIX: {
  6657. UINT SourceComponents = SourceInfo.uRows * SourceInfo.uCols;
  6658. if (1 == SourceComponents && TargetInfo.uCols != 1) {
  6659. // splat: matrix<[..], 1, 1> -> vector<[..], O>
  6660. Second = ICK_HLSLVector_Splat;
  6661. }
  6662. else if (1 == SourceInfo.uRows || 1 == SourceInfo.uCols) {
  6663. // cases for: matrix<[..], M, N> -> vector<[..], O>, where N == 1 or M == 1
  6664. if (TargetInfo.uCols > SourceComponents) // illegal: O > N*M
  6665. return false;
  6666. else if (TargetInfo.uCols < SourceComponents) // truncation: O < N*M
  6667. Second = ICK_HLSLVector_Truncation;
  6668. else // equalivalent: O == N*M
  6669. Second = ICK_HLSLVector_Conversion;
  6670. }
  6671. else if (TargetInfo.uCols == 1 && SourceComponents > 1) {
  6672. Second = ICK_HLSLVector_Truncation;
  6673. }
  6674. else if (TargetInfo.uCols != SourceComponents) {
  6675. // illegal: matrix<[..], M, N> -> vector<[..], O> where N != 1 and M != 1 and O != N*M
  6676. return false;
  6677. }
  6678. else {
  6679. // legal: matrix<[..], M, N> -> vector<[..], O> where N != 1 and M != 1 and O == N*M
  6680. Second = ICK_HLSLVector_Conversion;
  6681. }
  6682. break;
  6683. }
  6684. default:
  6685. return false;
  6686. }
  6687. break;
  6688. case AR_TOBJ_MATRIX: {
  6689. UINT TargetComponents = TargetInfo.uRows * TargetInfo.uCols;
  6690. switch (SourceInfo.ShapeKind)
  6691. {
  6692. case AR_TOBJ_BASIC:
  6693. // Conversions between scalars and aggregates are always supported.
  6694. Second = ICK_HLSLVector_Splat;
  6695. break;
  6696. case AR_TOBJ_VECTOR: {
  6697. // We can only convert vector to matrix in following cases:
  6698. // - splat from vector<...,1>
  6699. // - same number of components
  6700. // - one target component (truncate to scalar)
  6701. // - matrix has one row or one column, and fewer components (truncation)
  6702. // Other cases disallowed even if implicitly convertable in two steps (truncation+conversion).
  6703. if (1 == SourceInfo.uCols && TargetComponents != 1) {
  6704. // splat: vector<[..], 1> -> matrix<[..], M, N>
  6705. Second = ICK_HLSLVector_Splat;
  6706. }
  6707. else if (TargetComponents == SourceInfo.uCols) {
  6708. // legal: vector<[..], O> -> matrix<[..], M, N> where N != 1 and M != 1 and O == N*M
  6709. Second = ICK_HLSLVector_Conversion;
  6710. }
  6711. else if (1 == TargetComponents) {
  6712. // truncate to scalar: matrix<[..], 1, 1>
  6713. Second = ICK_HLSLVector_Truncation;
  6714. }
  6715. else if ((1 == TargetInfo.uRows || 1 == TargetInfo.uCols) &&
  6716. TargetComponents < SourceInfo.uCols) {
  6717. Second = ICK_HLSLVector_Truncation;
  6718. }
  6719. else {
  6720. // illegal: change in components without going to or from scalar equivalent
  6721. return false;
  6722. }
  6723. break;
  6724. }
  6725. case AR_TOBJ_MATRIX: {
  6726. UINT SourceComponents = SourceInfo.uRows * SourceInfo.uCols;
  6727. if (1 == SourceComponents && TargetComponents != 1) {
  6728. // splat: matrix<[..], 1, 1> -> matrix<[..], M, N>
  6729. Second = ICK_HLSLVector_Splat;
  6730. }
  6731. else if (TargetComponents == 1) {
  6732. Second = ICK_HLSLVector_Truncation;
  6733. }
  6734. else if (TargetInfo.uRows > SourceInfo.uRows || TargetInfo.uCols > SourceInfo.uCols) {
  6735. return false;
  6736. }
  6737. else if (TargetInfo.uRows < SourceInfo.uRows || TargetInfo.uCols < SourceInfo.uCols) {
  6738. Second = ICK_HLSLVector_Truncation;
  6739. }
  6740. else {
  6741. Second = ICK_Identity;
  6742. }
  6743. break;
  6744. }
  6745. default:
  6746. return false;
  6747. }
  6748. break;
  6749. }
  6750. default:
  6751. return false;
  6752. }
  6753. if (TargetInfo.uTotalElts < SourceInfo.uTotalElts)
  6754. {
  6755. Remarks |= TYPE_CONVERSION_ELT_TRUNCATION;
  6756. }
  6757. return true;
  6758. }
  6759. static bool ConvertComponent(ArTypeInfo TargetInfo, ArTypeInfo SourceInfo,
  6760. ImplicitConversionKind &ComponentConversion,
  6761. TYPE_CONVERSION_REMARKS &Remarks) {
  6762. // Conversion to/from unknown types not supported.
  6763. if (TargetInfo.EltKind == AR_BASIC_UNKNOWN ||
  6764. SourceInfo.EltKind == AR_BASIC_UNKNOWN) {
  6765. return false;
  6766. }
  6767. bool precisionLoss = false;
  6768. if (GET_BASIC_BITS(TargetInfo.EltKind) != 0 &&
  6769. GET_BASIC_BITS(TargetInfo.EltKind) <
  6770. GET_BASIC_BITS(SourceInfo.EltKind))
  6771. {
  6772. precisionLoss = true;
  6773. Remarks |= TYPE_CONVERSION_PRECISION_LOSS;
  6774. }
  6775. // enum -> enum not allowed
  6776. if ((SourceInfo.EltKind == AR_BASIC_ENUM &&
  6777. TargetInfo.EltKind == AR_BASIC_ENUM) ||
  6778. SourceInfo.EltKind == AR_BASIC_ENUM_CLASS ||
  6779. TargetInfo.EltKind == AR_BASIC_ENUM_CLASS) {
  6780. return false;
  6781. }
  6782. if (SourceInfo.EltKind != TargetInfo.EltKind)
  6783. {
  6784. if (IS_BASIC_BOOL(TargetInfo.EltKind))
  6785. {
  6786. ComponentConversion = ICK_Boolean_Conversion;
  6787. }
  6788. else if (IS_BASIC_ENUM(TargetInfo.EltKind))
  6789. {
  6790. // conversion to enum type not allowed
  6791. return false;
  6792. }
  6793. else if (IS_BASIC_ENUM(SourceInfo.EltKind))
  6794. {
  6795. // enum -> int/float
  6796. ComponentConversion = ICK_Integral_Conversion;
  6797. }
  6798. else
  6799. {
  6800. bool targetIsInt = IS_BASIC_AINT(TargetInfo.EltKind);
  6801. if (IS_BASIC_AINT(SourceInfo.EltKind))
  6802. {
  6803. if (targetIsInt)
  6804. {
  6805. ComponentConversion = precisionLoss ? ICK_Integral_Conversion : ICK_Integral_Promotion;
  6806. }
  6807. else
  6808. {
  6809. ComponentConversion = ICK_Floating_Integral;
  6810. }
  6811. }
  6812. else if (IS_BASIC_FLOAT(SourceInfo.EltKind))
  6813. {
  6814. if (targetIsInt)
  6815. {
  6816. ComponentConversion = ICK_Floating_Integral;
  6817. }
  6818. else
  6819. {
  6820. ComponentConversion = precisionLoss ? ICK_Floating_Conversion : ICK_Floating_Promotion;
  6821. }
  6822. }
  6823. else if (IS_BASIC_BOOL(SourceInfo.EltKind)) {
  6824. if (targetIsInt)
  6825. ComponentConversion = ICK_Integral_Conversion;
  6826. else
  6827. ComponentConversion = ICK_Floating_Integral;
  6828. }
  6829. }
  6830. }
  6831. return true;
  6832. }
  6833. _Use_decl_annotations_
  6834. bool HLSLExternalSource::CanConvert(
  6835. SourceLocation loc,
  6836. Expr* sourceExpr,
  6837. QualType target,
  6838. bool explicitConversion,
  6839. _Out_opt_ TYPE_CONVERSION_REMARKS* remarks,
  6840. _Inout_opt_ StandardConversionSequence* standard)
  6841. {
  6842. bool bCheckElt = false;
  6843. UINT uTSize, uSSize;
  6844. DXASSERT_NOMSG(sourceExpr != nullptr);
  6845. DXASSERT_NOMSG(!target.isNull());
  6846. // Implements the semantics of ArType::CanConvertTo.
  6847. TYPE_CONVERSION_FLAGS Flags = explicitConversion ? TYPE_CONVERSION_EXPLICIT : TYPE_CONVERSION_DEFAULT;
  6848. TYPE_CONVERSION_REMARKS Remarks = TYPE_CONVERSION_NONE;
  6849. QualType source = sourceExpr->getType();
  6850. // Cannot cast function type.
  6851. if (source->isFunctionType())
  6852. return false;
  6853. // Convert to an r-value to begin with.
  6854. bool needsLValueToRValue = sourceExpr->isLValue() &&
  6855. !target->isLValueReferenceType() &&
  6856. IsConversionToLessOrEqualElements(source, target, explicitConversion);
  6857. bool targetRef = target->isReferenceType();
  6858. // Initialize the output standard sequence if available.
  6859. if (standard != nullptr) {
  6860. // Set up a no-op conversion, other than lvalue to rvalue - HLSL does not support references.
  6861. standard->setAsIdentityConversion();
  6862. if (needsLValueToRValue) {
  6863. standard->First = ICK_Lvalue_To_Rvalue;
  6864. }
  6865. standard->setFromType(source);
  6866. standard->setAllToTypes(target);
  6867. }
  6868. source = GetStructuralForm(source);
  6869. target = GetStructuralForm(target);
  6870. // Temporary conversion kind tracking which will be used/fixed up at the end
  6871. ImplicitConversionKind Second = ICK_Identity;
  6872. ImplicitConversionKind ComponentConversion = ICK_Identity;
  6873. // Identical types require no conversion.
  6874. if (source == target) {
  6875. Remarks = TYPE_CONVERSION_IDENTICAL;
  6876. goto lSuccess;
  6877. }
  6878. // Trivial cases for void.
  6879. bool allowed;
  6880. if (HandleVoidConversion(source, target, explicitConversion, &allowed)) {
  6881. if (allowed) {
  6882. Remarks = target->isVoidType() ? TYPE_CONVERSION_TO_VOID : Remarks;
  6883. goto lSuccess;
  6884. }
  6885. else {
  6886. return false;
  6887. }
  6888. }
  6889. ArTypeInfo TargetInfo, SourceInfo;
  6890. CollectInfo(target, &TargetInfo);
  6891. CollectInfo(source, &SourceInfo);
  6892. uTSize = TargetInfo.uTotalElts;
  6893. uSSize = SourceInfo.uTotalElts;
  6894. // TODO: TYPE_CONVERSION_BY_REFERENCE does not seem possible here
  6895. // are we missing cases?
  6896. if ((Flags & TYPE_CONVERSION_BY_REFERENCE) != 0 && uTSize != uSSize) {
  6897. return false;
  6898. }
  6899. // Structure cast.
  6900. if (TargetInfo.ShapeKind == AR_TOBJ_COMPOUND || TargetInfo.ShapeKind == AR_TOBJ_ARRAY ||
  6901. SourceInfo.ShapeKind == AR_TOBJ_COMPOUND || SourceInfo.ShapeKind == AR_TOBJ_ARRAY) {
  6902. if (!explicitConversion && TargetInfo.ShapeKind != SourceInfo.ShapeKind)
  6903. {
  6904. return false;
  6905. }
  6906. const RecordType *targetRT = target->getAsStructureType();
  6907. if (!targetRT)
  6908. targetRT = dyn_cast<RecordType>(target);
  6909. const RecordType *sourceRT = source->getAsStructureType();
  6910. if (!sourceRT)
  6911. sourceRT = dyn_cast<RecordType>(source);
  6912. if (targetRT && sourceRT) {
  6913. RecordDecl *targetRD = targetRT->getDecl();
  6914. RecordDecl *sourceRD = sourceRT->getDecl();
  6915. const CXXRecordDecl *targetCXXRD = dyn_cast<CXXRecordDecl>(targetRD);
  6916. const CXXRecordDecl *sourceCXXRD = dyn_cast<CXXRecordDecl>(sourceRD);
  6917. if (targetCXXRD && sourceCXXRD) {
  6918. if (targetRD == sourceRD) {
  6919. Second = ICK_Flat_Conversion;
  6920. goto lSuccess;
  6921. }
  6922. if (sourceCXXRD->isDerivedFrom(targetCXXRD)) {
  6923. Second = ICK_HLSL_Derived_To_Base;
  6924. goto lSuccess;
  6925. }
  6926. } else {
  6927. if (targetRD == sourceRD) {
  6928. Second = ICK_Flat_Conversion;
  6929. goto lSuccess;
  6930. }
  6931. }
  6932. }
  6933. if (const BuiltinType *BT = source->getAs<BuiltinType>()) {
  6934. BuiltinType::Kind kind = BT->getKind();
  6935. switch (kind) {
  6936. case BuiltinType::Kind::UInt:
  6937. case BuiltinType::Kind::Int:
  6938. case BuiltinType::Kind::Float:
  6939. case BuiltinType::Kind::LitFloat:
  6940. case BuiltinType::Kind::LitInt:
  6941. if (explicitConversion) {
  6942. Second = ICK_Flat_Conversion;
  6943. goto lSuccess;
  6944. }
  6945. break;
  6946. default:
  6947. // Only flat conversion kinds are relevant.
  6948. break;
  6949. }
  6950. }
  6951. FlattenedTypeIterator::ComparisonResult result =
  6952. FlattenedTypeIterator::CompareTypes(*this, loc, loc, target, source);
  6953. if (!result.CanConvertElements) {
  6954. return false;
  6955. }
  6956. // Only allow scalar to compound or array with explicit cast
  6957. if (result.IsConvertibleAndLeftLonger()) {
  6958. if (!explicitConversion || SourceInfo.ShapeKind != AR_TOBJ_SCALAR) {
  6959. return false;
  6960. }
  6961. }
  6962. // Assignment is valid if elements are exactly the same in type and size; if
  6963. // an explicit conversion is being done, we accept converted elements and a
  6964. // longer right-hand sequence.
  6965. if (!explicitConversion &&
  6966. (!result.AreElementsEqual || result.IsRightLonger()))
  6967. {
  6968. return false;
  6969. }
  6970. Second = ICK_Flat_Conversion;
  6971. goto lSuccess;
  6972. }
  6973. // Convert scalar/vector/matrix dimensions
  6974. if (!ConvertDimensions(TargetInfo, SourceInfo, Second, Remarks))
  6975. return false;
  6976. // Convert component type
  6977. if (!ConvertComponent(TargetInfo, SourceInfo, ComponentConversion, Remarks))
  6978. return false;
  6979. lSuccess:
  6980. if (standard)
  6981. {
  6982. if (sourceExpr->isLValue())
  6983. {
  6984. if (needsLValueToRValue) {
  6985. // We don't need LValueToRValue cast before casting a derived object
  6986. // to its base.
  6987. if (Second == ICK_HLSL_Derived_To_Base) {
  6988. standard->First = ICK_Identity;
  6989. } else {
  6990. standard->First = ICK_Lvalue_To_Rvalue;
  6991. }
  6992. } else {
  6993. switch (Second)
  6994. {
  6995. case ICK_NoReturn_Adjustment:
  6996. case ICK_Vector_Conversion:
  6997. case ICK_Vector_Splat:
  6998. DXASSERT(false, "We shouldn't be producing these implicit conversion kinds");
  6999. case ICK_Flat_Conversion:
  7000. case ICK_HLSLVector_Splat:
  7001. standard->First = ICK_Lvalue_To_Rvalue;
  7002. break;
  7003. default:
  7004. // Only flat and splat conversions handled.
  7005. break;
  7006. }
  7007. switch (ComponentConversion)
  7008. {
  7009. case ICK_Integral_Promotion:
  7010. case ICK_Integral_Conversion:
  7011. case ICK_Floating_Promotion:
  7012. case ICK_Floating_Conversion:
  7013. case ICK_Floating_Integral:
  7014. case ICK_Boolean_Conversion:
  7015. standard->First = ICK_Lvalue_To_Rvalue;
  7016. break;
  7017. default:
  7018. // Only potential assignments above covered.
  7019. break;
  7020. }
  7021. }
  7022. }
  7023. // Finally fix up the cases for scalar->scalar component conversion, and
  7024. // identity vector/matrix component conversion
  7025. if (ICK_Identity != ComponentConversion) {
  7026. if (Second == ICK_Identity) {
  7027. if (TargetInfo.ShapeKind == AR_TOBJ_BASIC) {
  7028. // Scalar to scalar type conversion, use normal mechanism (Second)
  7029. Second = ComponentConversion;
  7030. ComponentConversion = ICK_Identity;
  7031. } else {
  7032. // vector or matrix dimensions are not being changed, but component type
  7033. // is being converted, so change Second to signal the conversion
  7034. Second = ICK_HLSLVector_Conversion;
  7035. }
  7036. }
  7037. }
  7038. standard->Second = Second;
  7039. standard->ComponentConversion = ComponentConversion;
  7040. // For conversion which change to RValue but targeting reference type
  7041. // Hold the conversion to codeGen
  7042. if (targetRef && standard->First == ICK_Lvalue_To_Rvalue) {
  7043. standard->First = ICK_Identity;
  7044. standard->Second = ICK_Identity;
  7045. }
  7046. }
  7047. AssignOpt(Remarks, remarks);
  7048. return true;
  7049. }
  7050. bool HLSLExternalSource::ValidateTypeRequirements(
  7051. SourceLocation loc,
  7052. ArBasicKind elementKind,
  7053. ArTypeObjectKind objectKind,
  7054. bool requiresIntegrals,
  7055. bool requiresNumerics)
  7056. {
  7057. if (requiresIntegrals || requiresNumerics)
  7058. {
  7059. if (!IsObjectKindPrimitiveAggregate(objectKind))
  7060. {
  7061. m_sema->Diag(loc, diag::err_hlsl_requires_non_aggregate);
  7062. return false;
  7063. }
  7064. }
  7065. if (requiresIntegrals)
  7066. {
  7067. if (!IsBasicKindIntegral(elementKind))
  7068. {
  7069. m_sema->Diag(loc, diag::err_hlsl_requires_int_or_uint);
  7070. return false;
  7071. }
  7072. }
  7073. else if (requiresNumerics)
  7074. {
  7075. if (!IsBasicKindNumeric(elementKind))
  7076. {
  7077. m_sema->Diag(loc, diag::err_hlsl_requires_numeric);
  7078. return false;
  7079. }
  7080. }
  7081. return true;
  7082. }
  7083. bool HLSLExternalSource::ValidatePrimitiveTypeForOperand(SourceLocation loc, QualType type, ArTypeObjectKind kind)
  7084. {
  7085. bool isValid = true;
  7086. if (IsBuiltInObjectType(type)) {
  7087. m_sema->Diag(loc, diag::err_hlsl_unsupported_builtin_op) << type;
  7088. isValid = false;
  7089. }
  7090. if (kind == AR_TOBJ_COMPOUND) {
  7091. m_sema->Diag(loc, diag::err_hlsl_unsupported_struct_op) << type;
  7092. isValid = false;
  7093. }
  7094. return isValid;
  7095. }
  7096. HRESULT HLSLExternalSource::CombineDimensions(
  7097. QualType leftType, QualType rightType, QualType *resultType,
  7098. ImplicitConversionKind &convKind, TYPE_CONVERSION_REMARKS &Remarks)
  7099. {
  7100. ArTypeInfo leftInfo, rightInfo;
  7101. CollectInfo(leftType, &leftInfo);
  7102. CollectInfo(rightType, &rightInfo);
  7103. // Prefer larger, or left if same.
  7104. if (leftInfo.uTotalElts >= rightInfo.uTotalElts) {
  7105. if (ConvertDimensions(leftInfo, rightInfo, convKind, Remarks))
  7106. *resultType = leftType;
  7107. else if (ConvertDimensions(rightInfo, leftInfo, convKind, Remarks))
  7108. *resultType = rightType;
  7109. else
  7110. return E_FAIL;
  7111. } else {
  7112. if (ConvertDimensions(rightInfo, leftInfo, convKind, Remarks))
  7113. *resultType = rightType;
  7114. else if (ConvertDimensions(leftInfo, rightInfo, convKind, Remarks))
  7115. *resultType = leftType;
  7116. else
  7117. return E_FAIL;
  7118. }
  7119. return S_OK;
  7120. }
  7121. /// <summary>Validates and adjusts operands for the specified binary operator.</summary>
  7122. /// <param name="OpLoc">Source location for operator.</param>
  7123. /// <param name="Opc">Kind of binary operator.</param>
  7124. /// <param name="LHS">Left-hand-side expression, possibly updated by this function.</param>
  7125. /// <param name="RHS">Right-hand-side expression, possibly updated by this function.</param>
  7126. /// <param name="ResultTy">Result type for operator expression.</param>
  7127. /// <param name="CompLHSTy">Type of LHS after promotions for computation.</param>
  7128. /// <param name="CompResultTy">Type of computation result.</param>
  7129. void HLSLExternalSource::CheckBinOpForHLSL(
  7130. SourceLocation OpLoc,
  7131. BinaryOperatorKind Opc,
  7132. ExprResult& LHS,
  7133. ExprResult& RHS,
  7134. QualType& ResultTy,
  7135. QualType& CompLHSTy,
  7136. QualType& CompResultTy)
  7137. {
  7138. // At the start, none of the output types should be valid.
  7139. DXASSERT_NOMSG(ResultTy.isNull());
  7140. DXASSERT_NOMSG(CompLHSTy.isNull());
  7141. DXASSERT_NOMSG(CompResultTy.isNull());
  7142. LHS = m_sema->CorrectDelayedTyposInExpr(LHS);
  7143. RHS = m_sema->CorrectDelayedTyposInExpr(RHS);
  7144. // If either expression is invalid to begin with, propagate that.
  7145. if (LHS.isInvalid() || RHS.isInvalid()) {
  7146. return;
  7147. }
  7148. // TODO: re-review the Check** in Clang and add equivalent diagnostics if/as needed, possibly after conversions
  7149. // Handle Assign and Comma operators and return
  7150. switch (Opc)
  7151. {
  7152. case BO_AddAssign:
  7153. case BO_AndAssign:
  7154. case BO_DivAssign:
  7155. case BO_MulAssign:
  7156. case BO_RemAssign:
  7157. case BO_ShlAssign:
  7158. case BO_ShrAssign:
  7159. case BO_SubAssign:
  7160. case BO_OrAssign:
  7161. case BO_XorAssign: {
  7162. extern bool CheckForModifiableLvalue(Expr * E, SourceLocation Loc,
  7163. Sema & S);
  7164. if (CheckForModifiableLvalue(LHS.get(), OpLoc, *m_sema)) {
  7165. return;
  7166. }
  7167. } break;
  7168. case BO_Assign: {
  7169. extern bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S);
  7170. if (CheckForModifiableLvalue(LHS.get(), OpLoc, *m_sema)) {
  7171. return;
  7172. }
  7173. bool complained = false;
  7174. ResultTy = LHS.get()->getType();
  7175. if (m_sema->DiagnoseAssignmentResult(Sema::AssignConvertType::Compatible,
  7176. OpLoc, ResultTy, RHS.get()->getType(), RHS.get(),
  7177. Sema::AssignmentAction::AA_Assigning, &complained)) {
  7178. return;
  7179. }
  7180. StandardConversionSequence standard;
  7181. if (!ValidateCast(OpLoc, RHS.get(), ResultTy,
  7182. ExplicitConversionFalse, SuppressWarningsFalse, SuppressErrorsFalse, &standard)) {
  7183. return;
  7184. }
  7185. if (RHS.get()->isLValue()) {
  7186. standard.First = ICK_Lvalue_To_Rvalue;
  7187. }
  7188. RHS = m_sema->PerformImplicitConversion(RHS.get(), ResultTy,
  7189. standard, Sema::AA_Converting, Sema::CCK_ImplicitConversion);
  7190. return;
  7191. }
  7192. break;
  7193. case BO_Comma:
  7194. // C performs conversions, C++ doesn't but still checks for type completeness.
  7195. // There are also diagnostics for improper comma use.
  7196. // In the HLSL case these cases don't apply or simply aren't surfaced.
  7197. ResultTy = RHS.get()->getType();
  7198. return;
  7199. default:
  7200. // Only assign and comma operations handled.
  7201. break;
  7202. }
  7203. // Leave this diagnostic for last to emulate fxc behavior.
  7204. bool isCompoundAssignment = BinaryOperatorKindIsCompoundAssignment(Opc);
  7205. bool unsupportedBoolLvalue = isCompoundAssignment &&
  7206. !BinaryOperatorKindIsCompoundAssignmentForBool(Opc) &&
  7207. GetTypeElementKind(LHS.get()->getType()) == AR_BASIC_BOOL;
  7208. // Turn operand inputs into r-values.
  7209. QualType LHSTypeAsPossibleLValue = LHS.get()->getType();
  7210. if (!isCompoundAssignment) {
  7211. LHS = m_sema->DefaultLvalueConversion(LHS.get());
  7212. }
  7213. RHS = m_sema->DefaultLvalueConversion(RHS.get());
  7214. if (LHS.isInvalid() || RHS.isInvalid()) {
  7215. return;
  7216. }
  7217. // Gather type info
  7218. QualType leftType = GetStructuralForm(LHS.get()->getType());
  7219. QualType rightType = GetStructuralForm(RHS.get()->getType());
  7220. ArBasicKind leftElementKind = GetTypeElementKind(leftType);
  7221. ArBasicKind rightElementKind = GetTypeElementKind(rightType);
  7222. ArTypeObjectKind leftObjectKind = GetTypeObjectKind(leftType);
  7223. ArTypeObjectKind rightObjectKind = GetTypeObjectKind(rightType);
  7224. // Validate type requirements
  7225. {
  7226. bool requiresNumerics = BinaryOperatorKindRequiresNumeric(Opc);
  7227. bool requiresIntegrals = BinaryOperatorKindRequiresIntegrals(Opc);
  7228. if (!ValidateTypeRequirements(OpLoc, leftElementKind, leftObjectKind, requiresIntegrals, requiresNumerics)) {
  7229. return;
  7230. }
  7231. if (!ValidateTypeRequirements(OpLoc, rightElementKind, rightObjectKind, requiresIntegrals, requiresNumerics)) {
  7232. return;
  7233. }
  7234. }
  7235. if (unsupportedBoolLvalue) {
  7236. m_sema->Diag(OpLoc, diag::err_hlsl_unsupported_bool_lvalue_op);
  7237. return;
  7238. }
  7239. // We don't support binary operators on built-in object types other than assignment or commas.
  7240. {
  7241. DXASSERT(Opc != BO_Assign, "otherwise this wasn't handled as an early exit");
  7242. DXASSERT(Opc != BO_Comma, "otherwise this wasn't handled as an early exit");
  7243. bool isValid;
  7244. isValid = ValidatePrimitiveTypeForOperand(OpLoc, leftType, leftObjectKind);
  7245. if (leftType != rightType && !ValidatePrimitiveTypeForOperand(OpLoc, rightType, rightObjectKind)) {
  7246. isValid = false;
  7247. }
  7248. if (!isValid) {
  7249. return;
  7250. }
  7251. }
  7252. // We don't support equality comparisons on arrays.
  7253. if ((Opc == BO_EQ || Opc == BO_NE) && (leftObjectKind == AR_TOBJ_ARRAY || rightObjectKind == AR_TOBJ_ARRAY)) {
  7254. m_sema->Diag(OpLoc, diag::err_hlsl_unsupported_array_equality_op);
  7255. return;
  7256. }
  7257. // Combine element types for computation.
  7258. ArBasicKind resultElementKind = leftElementKind;
  7259. {
  7260. if (BinaryOperatorKindIsLogical(Opc)) {
  7261. resultElementKind = AR_BASIC_BOOL;
  7262. } else if (!BinaryOperatorKindIsBitwiseShift(Opc) && leftElementKind != rightElementKind) {
  7263. if (!CombineBasicTypes(leftElementKind, rightElementKind, &resultElementKind)) {
  7264. m_sema->Diag(OpLoc, diag::err_hlsl_type_mismatch);
  7265. return;
  7266. }
  7267. } else if (BinaryOperatorKindIsBitwiseShift(Opc) &&
  7268. (resultElementKind == AR_BASIC_LITERAL_INT ||
  7269. resultElementKind == AR_BASIC_LITERAL_FLOAT) &&
  7270. rightElementKind != AR_BASIC_LITERAL_INT &&
  7271. rightElementKind != AR_BASIC_LITERAL_FLOAT) {
  7272. // For case like 1<<x.
  7273. resultElementKind = AR_BASIC_UINT32;
  7274. } else if (resultElementKind == AR_BASIC_BOOL &&
  7275. BinaryOperatorKindRequiresBoolAsNumeric(Opc)) {
  7276. resultElementKind = AR_BASIC_INT32;
  7277. }
  7278. // The following combines the selected/combined element kind above with
  7279. // the dimensions that are legal to implicitly cast. This means that
  7280. // element kind may be taken from one side and the dimensions from the
  7281. // other.
  7282. if (!isCompoundAssignment) {
  7283. // Legal dimension combinations are identical, splat, and truncation.
  7284. // ResultTy will be set to whichever type can be converted to, if legal,
  7285. // with preference for leftType if both are possible.
  7286. if (FAILED(CombineDimensions(LHS.get()->getType(), RHS.get()->getType(), &ResultTy))) {
  7287. // Just choose leftType, and allow ValidateCast to catch this later
  7288. ResultTy = LHS.get()->getType();
  7289. }
  7290. } else {
  7291. ResultTy = LHS.get()->getType();
  7292. }
  7293. // Here, element kind is combined with dimensions for computation type, if different.
  7294. if (resultElementKind != GetTypeElementKind(ResultTy)) {
  7295. UINT rowCount, colCount;
  7296. GetRowsAndColsForAny(ResultTy, rowCount, colCount);
  7297. ResultTy = NewSimpleAggregateType(GetTypeObjectKind(ResultTy), resultElementKind, 0, rowCount, colCount);
  7298. }
  7299. }
  7300. bool bFailedFirstRHSCast = false;
  7301. // Perform necessary conversion sequences for LHS and RHS
  7302. if (RHS.get()->getType() != ResultTy) {
  7303. StandardConversionSequence standard;
  7304. // Suppress type narrowing or truncation warnings for RHS on bitwise shift, since we only care about the LHS type.
  7305. bool bSuppressWarnings = BinaryOperatorKindIsBitwiseShift(Opc);
  7306. // Suppress errors on compound assignment, since we will vaildate the cast to the final type later.
  7307. bool bSuppressErrors = isCompoundAssignment;
  7308. // If compound assignment, suppress errors until later, but report warning (vector truncation/type narrowing) here.
  7309. if (ValidateCast(SourceLocation(), RHS.get(), ResultTy, ExplicitConversionFalse, bSuppressWarnings, bSuppressErrors, &standard)) {
  7310. if (standard.First != ICK_Identity || !standard.isIdentityConversion())
  7311. RHS = m_sema->PerformImplicitConversion(RHS.get(), ResultTy, standard, Sema::AA_Casting, Sema::CCK_ImplicitConversion);
  7312. } else if (!isCompoundAssignment) {
  7313. // If compound assignment, validate cast from RHS directly to LHS later, otherwise, fail here.
  7314. ResultTy = QualType();
  7315. return;
  7316. } else {
  7317. bFailedFirstRHSCast = true;
  7318. }
  7319. }
  7320. if (isCompoundAssignment) {
  7321. CompResultTy = ResultTy;
  7322. CompLHSTy = CompResultTy;
  7323. // For a compound operation, C/C++ promotes both types, performs the arithmetic,
  7324. // then converts to the result type and then assigns.
  7325. //
  7326. // So int + float promotes the int to float, does a floating-point addition,
  7327. // then the result becomes and int and is assigned.
  7328. ResultTy = LHSTypeAsPossibleLValue;
  7329. // Validate remainder of cast from computation type to final result type
  7330. StandardConversionSequence standard;
  7331. if (!ValidateCast(SourceLocation(), RHS.get(), ResultTy, ExplicitConversionFalse, SuppressWarningsFalse, SuppressErrorsFalse, &standard)) {
  7332. ResultTy = QualType();
  7333. return;
  7334. }
  7335. DXASSERT_LOCALVAR(bFailedFirstRHSCast, !bFailedFirstRHSCast,
  7336. "otherwise, hit compound assign case that failed RHS -> CompResultTy cast, but succeeded RHS -> LHS cast.");
  7337. } else if (LHS.get()->getType() != ResultTy) {
  7338. StandardConversionSequence standard;
  7339. if (ValidateCast(SourceLocation(), LHS.get(), ResultTy, ExplicitConversionFalse, SuppressWarningsFalse, SuppressErrorsFalse, &standard)) {
  7340. if (standard.First != ICK_Identity || !standard.isIdentityConversion())
  7341. LHS = m_sema->PerformImplicitConversion(LHS.get(), ResultTy, standard, Sema::AA_Casting, Sema::CCK_ImplicitConversion);
  7342. } else {
  7343. ResultTy = QualType();
  7344. return;
  7345. }
  7346. }
  7347. if (BinaryOperatorKindIsComparison(Opc) || BinaryOperatorKindIsLogical(Opc))
  7348. {
  7349. DXASSERT(!isCompoundAssignment, "otherwise binary lookup tables are inconsistent");
  7350. // Return bool vector for vector types.
  7351. if (IsVectorType(m_sema, ResultTy)) {
  7352. UINT rowCount, colCount;
  7353. GetRowsAndColsForAny(ResultTy, rowCount, colCount);
  7354. ResultTy = LookupVectorType(HLSLScalarType::HLSLScalarType_bool, colCount);
  7355. } else if (IsMatrixType(m_sema, ResultTy)) {
  7356. UINT rowCount, colCount;
  7357. GetRowsAndColsForAny(ResultTy, rowCount, colCount);
  7358. ResultTy = LookupMatrixType(HLSLScalarType::HLSLScalarType_bool, rowCount, colCount);
  7359. } else
  7360. ResultTy = m_context->BoolTy.withConst();
  7361. }
  7362. // Run diagnostics. Some are emulating checks that occur in IR emission in fxc.
  7363. if (Opc == BO_Div || Opc == BO_DivAssign || Opc == BO_Rem || Opc == BO_RemAssign) {
  7364. if (IsBasicKindIntMinPrecision(resultElementKind)) {
  7365. m_sema->Diag(OpLoc, diag::err_hlsl_unsupported_div_minint);
  7366. return;
  7367. }
  7368. }
  7369. if (Opc == BO_Rem || Opc == BO_RemAssign) {
  7370. if (resultElementKind == AR_BASIC_FLOAT64) {
  7371. m_sema->Diag(OpLoc, diag::err_hlsl_unsupported_mod_double);
  7372. return;
  7373. }
  7374. }
  7375. }
  7376. /// <summary>Validates and adjusts operands for the specified unary operator.</summary>
  7377. /// <param name="OpLoc">Source location for operator.</param>
  7378. /// <param name="Opc">Kind of operator.</param>
  7379. /// <param name="InputExpr">Input expression to the operator.</param>
  7380. /// <param name="VK">Value kind for resulting expression.</param>
  7381. /// <param name="OK">Object kind for resulting expression.</param>
  7382. /// <returns>The result type for the expression.</returns>
  7383. QualType HLSLExternalSource::CheckUnaryOpForHLSL(
  7384. SourceLocation OpLoc,
  7385. UnaryOperatorKind Opc,
  7386. ExprResult& InputExpr,
  7387. ExprValueKind& VK,
  7388. ExprObjectKind& OK)
  7389. {
  7390. InputExpr = m_sema->CorrectDelayedTyposInExpr(InputExpr);
  7391. if (InputExpr.isInvalid())
  7392. return QualType();
  7393. // Reject unsupported operators * and &
  7394. switch (Opc) {
  7395. case UO_AddrOf:
  7396. case UO_Deref:
  7397. m_sema->Diag(OpLoc, diag::err_hlsl_unsupported_operator);
  7398. return QualType();
  7399. default:
  7400. // Only * and & covered.
  7401. break;
  7402. }
  7403. Expr* expr = InputExpr.get();
  7404. if (expr->isTypeDependent())
  7405. return m_context->DependentTy;
  7406. ArBasicKind elementKind = GetTypeElementKind(expr->getType());
  7407. if (UnaryOperatorKindRequiresModifiableValue(Opc)) {
  7408. if (elementKind == AR_BASIC_ENUM) {
  7409. bool isInc = IsIncrementOp(Opc);
  7410. m_sema->Diag(OpLoc, diag::err_increment_decrement_enum) << isInc << expr->getType();
  7411. return QualType();
  7412. }
  7413. extern bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S);
  7414. if (CheckForModifiableLvalue(expr, OpLoc, *m_sema))
  7415. return QualType();
  7416. } else {
  7417. InputExpr = m_sema->DefaultLvalueConversion(InputExpr.get()).get();
  7418. if (InputExpr.isInvalid()) return QualType();
  7419. }
  7420. if (UnaryOperatorKindDisallowsBool(Opc) && IS_BASIC_BOOL(elementKind)) {
  7421. m_sema->Diag(OpLoc, diag::err_hlsl_unsupported_bool_lvalue_op);
  7422. return QualType();
  7423. }
  7424. if (UnaryOperatorKindRequiresBoolAsNumeric(Opc)) {
  7425. InputExpr = PromoteToIntIfBool(InputExpr);
  7426. expr = InputExpr.get();
  7427. elementKind = GetTypeElementKind(expr->getType());
  7428. }
  7429. ArTypeObjectKind objectKind = GetTypeObjectKind(expr->getType());
  7430. bool requiresIntegrals = UnaryOperatorKindRequiresIntegrals(Opc);
  7431. bool requiresNumerics = UnaryOperatorKindRequiresNumerics(Opc);
  7432. if (!ValidateTypeRequirements(OpLoc, elementKind, objectKind, requiresIntegrals, requiresNumerics)) {
  7433. return QualType();
  7434. }
  7435. if (Opc == UnaryOperatorKind::UO_Minus) {
  7436. if (IS_BASIC_UINT(Opc)) {
  7437. m_sema->Diag(OpLoc, diag::warn_hlsl_unary_negate_unsigned);
  7438. }
  7439. }
  7440. // By default, the result type is the operand type.
  7441. // Logical not however should cast to a bool.
  7442. QualType resultType = expr->getType();
  7443. if (Opc == UnaryOperatorKind::UO_LNot) {
  7444. UINT rowCount, colCount;
  7445. GetRowsAndColsForAny(expr->getType(), rowCount, colCount);
  7446. resultType = NewSimpleAggregateType(objectKind, AR_BASIC_BOOL, AR_QUAL_CONST, rowCount, colCount);
  7447. StandardConversionSequence standard;
  7448. if (!CanConvert(OpLoc, expr, resultType, false, nullptr, &standard)) {
  7449. m_sema->Diag(OpLoc, diag::err_hlsl_requires_bool_for_not);
  7450. return QualType();
  7451. }
  7452. // Cast argument.
  7453. ExprResult result = m_sema->PerformImplicitConversion(InputExpr.get(), resultType, standard, Sema::AA_Casting, Sema::CCK_ImplicitConversion);
  7454. if (result.isUsable()) {
  7455. InputExpr = result.get();
  7456. }
  7457. }
  7458. bool isPrefix = Opc == UO_PreInc || Opc == UO_PreDec;
  7459. if (isPrefix) {
  7460. VK = VK_LValue;
  7461. return resultType;
  7462. }
  7463. else {
  7464. VK = VK_RValue;
  7465. return resultType.getUnqualifiedType();
  7466. }
  7467. }
  7468. clang::QualType HLSLExternalSource::CheckVectorConditional(
  7469. _In_ ExprResult &Cond,
  7470. _In_ ExprResult &LHS,
  7471. _In_ ExprResult &RHS,
  7472. _In_ SourceLocation QuestionLoc)
  7473. {
  7474. Cond = m_sema->CorrectDelayedTyposInExpr(Cond);
  7475. LHS = m_sema->CorrectDelayedTyposInExpr(LHS);
  7476. RHS = m_sema->CorrectDelayedTyposInExpr(RHS);
  7477. // If either expression is invalid to begin with, propagate that.
  7478. if (Cond.isInvalid() || LHS.isInvalid() || RHS.isInvalid()) {
  7479. return QualType();
  7480. }
  7481. // Gather type info
  7482. QualType condType = GetStructuralForm(Cond.get()->getType());
  7483. QualType leftType = GetStructuralForm(LHS.get()->getType());
  7484. QualType rightType = GetStructuralForm(RHS.get()->getType());
  7485. ArBasicKind condElementKind = GetTypeElementKind(condType);
  7486. ArBasicKind leftElementKind = GetTypeElementKind(leftType);
  7487. ArBasicKind rightElementKind = GetTypeElementKind(rightType);
  7488. ArTypeObjectKind condObjectKind = GetTypeObjectKind(condType);
  7489. ArTypeObjectKind leftObjectKind = GetTypeObjectKind(leftType);
  7490. ArTypeObjectKind rightObjectKind = GetTypeObjectKind(rightType);
  7491. QualType ResultTy = leftType;
  7492. bool condIsSimple = condObjectKind == AR_TOBJ_BASIC || condObjectKind == AR_TOBJ_VECTOR || condObjectKind == AR_TOBJ_MATRIX;
  7493. if (!condIsSimple) {
  7494. m_sema->Diag(QuestionLoc, diag::err_hlsl_conditional_cond_typecheck);
  7495. return QualType();
  7496. }
  7497. UINT rowCountCond, colCountCond;
  7498. GetRowsAndColsForAny(condType, rowCountCond, colCountCond);
  7499. bool leftIsSimple =
  7500. leftObjectKind == AR_TOBJ_BASIC || leftObjectKind == AR_TOBJ_VECTOR ||
  7501. leftObjectKind == AR_TOBJ_MATRIX;
  7502. bool rightIsSimple =
  7503. rightObjectKind == AR_TOBJ_BASIC || rightObjectKind == AR_TOBJ_VECTOR ||
  7504. rightObjectKind == AR_TOBJ_MATRIX;
  7505. if (!leftIsSimple || !rightIsSimple) {
  7506. if (leftObjectKind == AR_TOBJ_OBJECT && leftObjectKind == AR_TOBJ_OBJECT) {
  7507. if (leftType == rightType) {
  7508. return leftType;
  7509. }
  7510. }
  7511. // NOTE: Limiting this operator to working only on basic numeric types.
  7512. // This is due to extremely limited (and even broken) support for any other case.
  7513. // In the future we may decide to support more cases.
  7514. m_sema->Diag(QuestionLoc, diag::err_hlsl_conditional_result_typecheck);
  7515. return QualType();
  7516. }
  7517. // Types should be only scalar, vector, or matrix after this point.
  7518. ArBasicKind resultElementKind = leftElementKind;
  7519. // Combine LHS and RHS element types for computation.
  7520. if (leftElementKind != rightElementKind) {
  7521. if (!CombineBasicTypes(leftElementKind, rightElementKind, &resultElementKind)) {
  7522. m_sema->Diag(QuestionLoc, diag::err_hlsl_conditional_result_comptype_mismatch);
  7523. return QualType();
  7524. }
  7525. }
  7526. // Restore left/right type to original to avoid stripping attributed type or typedef type
  7527. leftType = LHS.get()->getType();
  7528. rightType = RHS.get()->getType();
  7529. // Combine LHS and RHS dimensions
  7530. if (FAILED(CombineDimensions(leftType, rightType, &ResultTy))) {
  7531. m_sema->Diag(QuestionLoc, diag::err_hlsl_conditional_result_dimensions);
  7532. return QualType();
  7533. }
  7534. UINT rowCount, colCount;
  7535. GetRowsAndColsForAny(ResultTy, rowCount, colCount);
  7536. // If result is scalar, use condition dimensions.
  7537. // Otherwise, condition must either match or is scalar, then use result dimensions
  7538. if (rowCount * colCount == 1) {
  7539. rowCount = rowCountCond;
  7540. colCount = colCountCond;
  7541. }
  7542. else if (rowCountCond * colCountCond != 1 && (rowCountCond != rowCount || colCountCond != colCount)) {
  7543. m_sema->Diag(QuestionLoc, diag::err_hlsl_conditional_dimensions);
  7544. return QualType();
  7545. }
  7546. // Here, element kind is combined with dimensions for result type.
  7547. ResultTy = NewSimpleAggregateType(AR_TOBJ_INVALID, resultElementKind, 0, rowCount, colCount)->getCanonicalTypeInternal();
  7548. // Cast condition to RValue
  7549. if (Cond.get()->isLValue())
  7550. Cond.set(CreateLValueToRValueCast(Cond.get()));
  7551. // Convert condition component type to bool, using result component dimensions
  7552. if (condElementKind != AR_BASIC_BOOL) {
  7553. QualType boolType = NewSimpleAggregateType(AR_TOBJ_INVALID, AR_BASIC_BOOL, 0, rowCount, colCount)->getCanonicalTypeInternal();
  7554. StandardConversionSequence standard;
  7555. if (ValidateCast(SourceLocation(), Cond.get(), boolType, ExplicitConversionFalse, SuppressWarningsFalse, SuppressErrorsFalse, &standard)) {
  7556. if (standard.First != ICK_Identity || !standard.isIdentityConversion())
  7557. Cond = m_sema->PerformImplicitConversion(Cond.get(), boolType, standard, Sema::AA_Casting, Sema::CCK_ImplicitConversion);
  7558. }
  7559. else {
  7560. return QualType();
  7561. }
  7562. }
  7563. // TODO: Is this correct? Does fxc support lvalue return here?
  7564. // Cast LHS/RHS to RValue
  7565. if (LHS.get()->isLValue())
  7566. LHS.set(CreateLValueToRValueCast(LHS.get()));
  7567. if (RHS.get()->isLValue())
  7568. RHS.set(CreateLValueToRValueCast(RHS.get()));
  7569. if (leftType != ResultTy) {
  7570. StandardConversionSequence standard;
  7571. if (ValidateCast(SourceLocation(), LHS.get(), ResultTy, ExplicitConversionFalse, SuppressWarningsFalse, SuppressErrorsFalse, &standard)) {
  7572. if (standard.First != ICK_Identity || !standard.isIdentityConversion())
  7573. LHS = m_sema->PerformImplicitConversion(LHS.get(), ResultTy, standard, Sema::AA_Casting, Sema::CCK_ImplicitConversion);
  7574. }
  7575. else {
  7576. return QualType();
  7577. }
  7578. }
  7579. if (rightType != ResultTy) {
  7580. StandardConversionSequence standard;
  7581. if (ValidateCast(SourceLocation(), RHS.get(), ResultTy, ExplicitConversionFalse, SuppressWarningsFalse, SuppressErrorsFalse, &standard)) {
  7582. if (standard.First != ICK_Identity || !standard.isIdentityConversion())
  7583. RHS = m_sema->PerformImplicitConversion(RHS.get(), ResultTy, standard, Sema::AA_Casting, Sema::CCK_ImplicitConversion);
  7584. }
  7585. else {
  7586. return QualType();
  7587. }
  7588. }
  7589. return ResultTy;
  7590. }
  7591. // Apply type specifier sign to the given QualType.
  7592. // Other than privmitive int type, only allow shorthand vectors and matrices to be unsigned.
  7593. clang::QualType HLSLExternalSource::ApplyTypeSpecSignToParsedType(
  7594. _In_ clang::QualType &type, _In_ clang::TypeSpecifierSign TSS,
  7595. _In_ clang::SourceLocation Loc) {
  7596. if (TSS == TypeSpecifierSign::TSS_unspecified) {
  7597. return type;
  7598. }
  7599. DXASSERT(TSS != TypeSpecifierSign::TSS_signed, "else signed keyword is supported in HLSL");
  7600. ArTypeObjectKind objKind = GetTypeObjectKind(type);
  7601. if (objKind != AR_TOBJ_VECTOR && objKind != AR_TOBJ_MATRIX &&
  7602. objKind != AR_TOBJ_BASIC && objKind != AR_TOBJ_ARRAY) {
  7603. return type;
  7604. }
  7605. // check if element type is unsigned and check if such vector exists
  7606. // If not create a new one, Make a QualType of the new kind
  7607. ArBasicKind elementKind = GetTypeElementKind(type);
  7608. // Only ints can have signed/unsigend ty
  7609. if (!IS_BASIC_UNSIGNABLE(elementKind)) {
  7610. return type;
  7611. }
  7612. else {
  7613. // Check given TypeSpecifierSign. If unsigned, change int to uint.
  7614. HLSLScalarType scalarType = ScalarTypeForBasic(elementKind);
  7615. HLSLScalarType newScalarType = MakeUnsigned(scalarType);
  7616. // Get new vector types for a given TypeSpecifierSign.
  7617. if (objKind == AR_TOBJ_VECTOR) {
  7618. UINT colCount = GetHLSLVecSize(type);
  7619. TypedefDecl *qts = LookupVectorShorthandType(newScalarType, colCount);
  7620. return m_context->getTypeDeclType(qts);
  7621. } else if (objKind == AR_TOBJ_MATRIX) {
  7622. UINT rowCount, colCount;
  7623. GetRowsAndCols(type, rowCount, colCount);
  7624. TypedefDecl *qts = LookupMatrixShorthandType(newScalarType, rowCount, colCount);
  7625. return m_context->getTypeDeclType(qts);
  7626. } else {
  7627. DXASSERT_NOMSG(objKind == AR_TOBJ_BASIC || objKind == AR_TOBJ_ARRAY);
  7628. return m_scalarTypes[newScalarType];
  7629. }
  7630. }
  7631. }
  7632. Sema::TemplateDeductionResult HLSLExternalSource::DeduceTemplateArgumentsForHLSL(
  7633. FunctionTemplateDecl *FunctionTemplate,
  7634. TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> Args,
  7635. FunctionDecl *&Specialization, TemplateDeductionInfo &Info)
  7636. {
  7637. DXASSERT_NOMSG(FunctionTemplate != nullptr);
  7638. // Get information about the function we have.
  7639. CXXMethodDecl* functionMethod = dyn_cast<CXXMethodDecl>(FunctionTemplate->getTemplatedDecl());
  7640. DXASSERT(functionMethod != nullptr,
  7641. "otherwise this is standalone function rather than a method, which isn't supported in the HLSL object model");
  7642. CXXRecordDecl* functionParentRecord = functionMethod->getParent();
  7643. DXASSERT(functionParentRecord != nullptr, "otherwise function is orphaned");
  7644. QualType objectElement = GetFirstElementTypeFromDecl(functionParentRecord);
  7645. // Handle subscript overloads.
  7646. if (FunctionTemplate->getDeclName() == m_context->DeclarationNames.getCXXOperatorName(OO_Subscript))
  7647. {
  7648. DeclContext* functionTemplateContext = FunctionTemplate->getDeclContext();
  7649. FindStructBasicTypeResult findResult = FindStructBasicType(functionTemplateContext);
  7650. if (!findResult.Found())
  7651. {
  7652. // This might be a nested type. Do a lookup on the parent.
  7653. CXXRecordDecl* parentRecordType = dyn_cast_or_null<CXXRecordDecl>(functionTemplateContext);
  7654. if (parentRecordType == nullptr || parentRecordType->getDeclContext() == nullptr)
  7655. {
  7656. return Sema::TemplateDeductionResult::TDK_Invalid;
  7657. }
  7658. findResult = FindStructBasicType(parentRecordType->getDeclContext());
  7659. if (!findResult.Found())
  7660. {
  7661. return Sema::TemplateDeductionResult::TDK_Invalid;
  7662. }
  7663. DXASSERT(
  7664. parentRecordType->getDeclContext()->getDeclKind() == Decl::Kind::CXXRecord ||
  7665. parentRecordType->getDeclContext()->getDeclKind() == Decl::Kind::ClassTemplateSpecialization,
  7666. "otherwise FindStructBasicType should have failed - no other types are allowed");
  7667. objectElement = GetFirstElementTypeFromDecl(
  7668. cast<CXXRecordDecl>(parentRecordType->getDeclContext()));
  7669. }
  7670. Specialization = AddSubscriptSpecialization(FunctionTemplate, objectElement, findResult);
  7671. DXASSERT_NOMSG(Specialization->getPrimaryTemplate()->getCanonicalDecl() ==
  7672. FunctionTemplate->getCanonicalDecl());
  7673. return Sema::TemplateDeductionResult::TDK_Success;
  7674. }
  7675. // Reject overload lookups that aren't identifier-based.
  7676. if (!FunctionTemplate->getDeclName().isIdentifier())
  7677. {
  7678. return Sema::TemplateDeductionResult::TDK_NonDeducedMismatch;
  7679. }
  7680. // Find the table of intrinsics based on the object type.
  7681. const HLSL_INTRINSIC* intrinsics;
  7682. size_t intrinsicCount;
  7683. const char* objectName;
  7684. FindIntrinsicTable(FunctionTemplate->getDeclContext(), &objectName, &intrinsics, &intrinsicCount);
  7685. DXASSERT(intrinsics != nullptr,
  7686. "otherwise FindIntrinsicTable failed to lookup a valid object, "
  7687. "or the parser let a user-defined template object through");
  7688. // Look for an intrinsic for which we can match arguments.
  7689. size_t argCount;
  7690. QualType argTypes[g_MaxIntrinsicParamCount + 1];
  7691. StringRef nameIdentifier = FunctionTemplate->getName();
  7692. IntrinsicDefIter cursor = FindIntrinsicByNameAndArgCount(intrinsics, intrinsicCount, objectName, nameIdentifier, Args.size());
  7693. IntrinsicDefIter end = IntrinsicDefIter::CreateEnd(intrinsics, intrinsicCount, IntrinsicTableDefIter::CreateEnd(m_intrinsicTables));
  7694. while (cursor != end)
  7695. {
  7696. if (!MatchArguments(*cursor, objectElement, Args, argTypes, &argCount))
  7697. {
  7698. ++cursor;
  7699. continue;
  7700. }
  7701. // Currently only intrinsic we allow for explicit template arguments are
  7702. // for Load return types for ByteAddressBuffer/RWByteAddressBuffer
  7703. // TODO: handle template arguments for future intrinsics in a more natural way
  7704. // Check Explicit template arguments
  7705. UINT intrinsicOp = (*cursor)->Op;
  7706. LPCSTR intrinsicName = (*cursor)->pArgs[0].pName;
  7707. bool Is2018 = getSema()->getLangOpts().HLSLVersion >= 2018;
  7708. bool IsBAB =
  7709. objectName == g_ArBasicTypeNames[AR_OBJECT_BYTEADDRESS_BUFFER] ||
  7710. objectName == g_ArBasicTypeNames[AR_OBJECT_RWBYTEADDRESS_BUFFER];
  7711. bool IsBABLoad = IsBAB && intrinsicOp == (UINT)IntrinsicOp::MOP_Load;
  7712. bool IsBABStore = IsBAB && intrinsicOp == (UINT)IntrinsicOp::MOP_Store;
  7713. if (ExplicitTemplateArgs && ExplicitTemplateArgs->size() > 0) {
  7714. bool isLegalTemplate = false;
  7715. SourceLocation Loc = ExplicitTemplateArgs->getLAngleLoc();
  7716. auto TemplateDiag =
  7717. !IsBABLoad
  7718. ? diag::err_hlsl_intrinsic_template_arg_unsupported
  7719. : !Is2018 ? diag::err_hlsl_intrinsic_template_arg_requires_2018
  7720. : diag::err_hlsl_intrinsic_template_arg_requires_2018;
  7721. if (IsBABLoad && Is2018 && ExplicitTemplateArgs->size() == 1) {
  7722. Loc = (*ExplicitTemplateArgs)[0].getLocation();
  7723. QualType explicitType = (*ExplicitTemplateArgs)[0].getArgument().getAsType();
  7724. ArTypeObjectKind explicitKind = GetTypeObjectKind(explicitType);
  7725. if (explicitKind == AR_TOBJ_BASIC || explicitKind == AR_TOBJ_VECTOR) {
  7726. isLegalTemplate = GET_BASIC_BITS(GetTypeElementKind(explicitType)) != BPROP_BITS64 ||
  7727. GetNumElements(explicitType) <= 2;
  7728. }
  7729. if (isLegalTemplate) {
  7730. argTypes[0] = explicitType;
  7731. }
  7732. }
  7733. if (!isLegalTemplate) {
  7734. getSema()->Diag(Loc, TemplateDiag) << intrinsicName;
  7735. return Sema::TemplateDeductionResult::TDK_Invalid;
  7736. }
  7737. } else if (IsBABStore) {
  7738. // Prior to HLSL 2018, Store operation only stored scalar uint.
  7739. if (!Is2018) {
  7740. if (GetNumElements(argTypes[2]) != 1) {
  7741. getSema()->Diag(Args[1]->getLocStart(),
  7742. diag::err_ovl_no_viable_member_function_in_call)
  7743. << intrinsicName;
  7744. return Sema::TemplateDeductionResult::TDK_Invalid;
  7745. }
  7746. argTypes[2] = getSema()->getASTContext().getIntTypeForBitwidth(
  7747. 32, /*signed*/ false);
  7748. } else {
  7749. // not supporting types > 16 bytes yet.
  7750. if (GET_BASIC_BITS(GetTypeElementKind(argTypes[2])) == BPROP_BITS64 &&
  7751. GetNumElements(argTypes[2]) > 2) {
  7752. getSema()->Diag(Args[1]->getLocStart(),
  7753. diag::err_ovl_no_viable_member_function_in_call)
  7754. << intrinsicName;
  7755. return Sema::TemplateDeductionResult::TDK_Invalid;
  7756. }
  7757. }
  7758. }
  7759. Specialization = AddHLSLIntrinsicMethod(cursor.GetTableName(), cursor.GetLoweringStrategy(), *cursor, FunctionTemplate, Args, argTypes, argCount);
  7760. DXASSERT_NOMSG(Specialization->getPrimaryTemplate()->getCanonicalDecl() ==
  7761. FunctionTemplate->getCanonicalDecl());
  7762. if (!IsValidateObjectElement(*cursor, objectElement)) {
  7763. m_sema->Diag(Args[0]->getExprLoc(), diag::err_hlsl_invalid_resource_type_on_intrinsic) <<
  7764. nameIdentifier << g_ArBasicTypeNames[GetTypeElementKind(objectElement)];
  7765. }
  7766. return Sema::TemplateDeductionResult::TDK_Success;
  7767. }
  7768. return Sema::TemplateDeductionResult::TDK_NonDeducedMismatch;
  7769. }
  7770. void HLSLExternalSource::ReportUnsupportedTypeNesting(SourceLocation loc, QualType type)
  7771. {
  7772. m_sema->Diag(loc, diag::err_hlsl_unsupported_type_nesting) << type;
  7773. }
  7774. bool HLSLExternalSource::TryStaticCastForHLSL(ExprResult &SrcExpr,
  7775. QualType DestType,
  7776. Sema::CheckedConversionKind CCK,
  7777. const SourceRange &OpRange, unsigned &msg,
  7778. CastKind &Kind, CXXCastPath &BasePath,
  7779. bool ListInitialization, bool SuppressWarnings, bool SuppressErrors,
  7780. _Inout_opt_ StandardConversionSequence* standard)
  7781. {
  7782. DXASSERT(!SrcExpr.isInvalid(), "caller should check for invalid expressions and placeholder types");
  7783. bool explicitConversion
  7784. = (CCK == Sema::CCK_CStyleCast || CCK == Sema::CCK_FunctionalCast);
  7785. bool suppressWarnings = explicitConversion || SuppressWarnings;
  7786. SourceLocation loc = OpRange.getBegin();
  7787. if (ValidateCast(loc, SrcExpr.get(), DestType, explicitConversion, suppressWarnings, SuppressErrors, standard)) {
  7788. // TODO: LValue to RValue cast was all that CanConvert (ValidateCast) did anyway,
  7789. // so do this here until we figure out why this is needed.
  7790. if (standard && standard->First == ICK_Lvalue_To_Rvalue) {
  7791. SrcExpr.set(CreateLValueToRValueCast(SrcExpr.get()));
  7792. }
  7793. return true;
  7794. }
  7795. // ValidateCast includes its own error messages.
  7796. msg = 0;
  7797. return false;
  7798. }
  7799. /// <summary>
  7800. /// Checks if a subscript index argument can be initialized from the given expression.
  7801. /// </summary>
  7802. /// <param name="SrcExpr">Source expression used as argument.</param>
  7803. /// <param name="DestType">Parameter type to initialize.</param>
  7804. /// <remarks>
  7805. /// Rules for subscript index initialization follow regular implicit casting rules, with the exception that
  7806. /// no changes in arity are allowed (i.e., int2 can become uint2, but uint or uint3 cannot).
  7807. /// </remarks>
  7808. ImplicitConversionSequence
  7809. HLSLExternalSource::TrySubscriptIndexInitialization(_In_ clang::Expr *SrcExpr,
  7810. clang::QualType DestType) {
  7811. DXASSERT_NOMSG(SrcExpr != nullptr);
  7812. DXASSERT_NOMSG(!DestType.isNull());
  7813. unsigned int msg = 0;
  7814. CastKind kind;
  7815. CXXCastPath path;
  7816. ImplicitConversionSequence sequence;
  7817. sequence.setStandard();
  7818. ExprResult sourceExpr(SrcExpr);
  7819. if (GetElementCount(SrcExpr->getType()) != GetElementCount(DestType)) {
  7820. sequence.setBad(BadConversionSequence::FailureKind::no_conversion,
  7821. SrcExpr->getType(), DestType);
  7822. } else if (!TryStaticCastForHLSL(
  7823. sourceExpr, DestType, Sema::CCK_ImplicitConversion, NoRange,
  7824. msg, kind, path, ListInitializationFalse,
  7825. SuppressWarningsFalse, SuppressErrorsTrue, &sequence.Standard)) {
  7826. sequence.setBad(BadConversionSequence::FailureKind::no_conversion,
  7827. SrcExpr->getType(), DestType);
  7828. }
  7829. return sequence;
  7830. }
  7831. template <typename T>
  7832. static
  7833. bool IsValueInRange(T value, T minValue, T maxValue) {
  7834. return minValue <= value && value <= maxValue;
  7835. }
  7836. #define D3DX_16F_MAX 6.550400e+004 // max value
  7837. #define D3DX_16F_MIN 6.1035156e-5f // min positive value
  7838. static
  7839. void GetFloatLimits(ArBasicKind basicKind, double* minValue, double* maxValue)
  7840. {
  7841. DXASSERT_NOMSG(minValue != nullptr);
  7842. DXASSERT_NOMSG(maxValue != nullptr);
  7843. switch (basicKind) {
  7844. case AR_BASIC_MIN10FLOAT:
  7845. case AR_BASIC_MIN16FLOAT:
  7846. case AR_BASIC_FLOAT16: *minValue = -(D3DX_16F_MIN); *maxValue = D3DX_16F_MAX; return;
  7847. case AR_BASIC_FLOAT32_PARTIAL_PRECISION:
  7848. case AR_BASIC_FLOAT32: *minValue = -(FLT_MIN); *maxValue = FLT_MAX; return;
  7849. case AR_BASIC_FLOAT64: *minValue = -(DBL_MIN); *maxValue = DBL_MAX; return;
  7850. default:
  7851. // No other float types.
  7852. break;
  7853. }
  7854. DXASSERT(false, "unreachable");
  7855. *minValue = 0; *maxValue = 0;
  7856. return;
  7857. }
  7858. static
  7859. void GetUnsignedLimit(ArBasicKind basicKind, uint64_t* maxValue)
  7860. {
  7861. DXASSERT_NOMSG(maxValue != nullptr);
  7862. switch (basicKind) {
  7863. case AR_BASIC_BOOL: *maxValue = 1; return;
  7864. case AR_BASIC_UINT8: *maxValue = UINT8_MAX; return;
  7865. case AR_BASIC_MIN16UINT:
  7866. case AR_BASIC_UINT16: *maxValue = UINT16_MAX; return;
  7867. case AR_BASIC_UINT32: *maxValue = UINT32_MAX; return;
  7868. case AR_BASIC_UINT64: *maxValue = UINT64_MAX; return;
  7869. default:
  7870. // No other unsigned int types.
  7871. break;
  7872. }
  7873. DXASSERT(false, "unreachable");
  7874. *maxValue = 0;
  7875. return;
  7876. }
  7877. static
  7878. void GetSignedLimits(ArBasicKind basicKind, int64_t* minValue, int64_t* maxValue)
  7879. {
  7880. DXASSERT_NOMSG(minValue != nullptr);
  7881. DXASSERT_NOMSG(maxValue != nullptr);
  7882. switch (basicKind) {
  7883. case AR_BASIC_INT8: *minValue = INT8_MIN; *maxValue = INT8_MAX; return;
  7884. case AR_BASIC_MIN12INT:
  7885. case AR_BASIC_MIN16INT:
  7886. case AR_BASIC_INT16: *minValue = INT16_MIN; *maxValue = INT16_MAX; return;
  7887. case AR_BASIC_INT32: *minValue = INT32_MIN; *maxValue = INT32_MAX; return;
  7888. case AR_BASIC_INT64: *minValue = INT64_MIN; *maxValue = INT64_MAX; return;
  7889. default:
  7890. // No other signed int types.
  7891. break;
  7892. }
  7893. DXASSERT(false, "unreachable");
  7894. *minValue = 0; *maxValue = 0;
  7895. return;
  7896. }
  7897. static
  7898. bool IsValueInBasicRange(ArBasicKind basicKind, const APValue& value)
  7899. {
  7900. if (IS_BASIC_FLOAT(basicKind)) {
  7901. double val;
  7902. if (value.isInt()) {
  7903. val = value.getInt().getLimitedValue();
  7904. } else if (value.isFloat()) {
  7905. llvm::APFloat floatValue = value.getFloat();
  7906. if (!floatValue.isFinite()) {
  7907. return false;
  7908. }
  7909. llvm::APFloat valueFloat = value.getFloat();
  7910. if (&valueFloat.getSemantics() == &llvm::APFloat::IEEEsingle) {
  7911. val = value.getFloat().convertToFloat();
  7912. }
  7913. else {
  7914. val = value.getFloat().convertToDouble();
  7915. }
  7916. } else {
  7917. return false;
  7918. }
  7919. double minValue, maxValue;
  7920. GetFloatLimits(basicKind, &minValue, &maxValue);
  7921. return IsValueInRange(val, minValue, maxValue);
  7922. }
  7923. else if (IS_BASIC_SINT(basicKind)) {
  7924. if (!value.isInt()) {
  7925. return false;
  7926. }
  7927. int64_t val = value.getInt().getSExtValue();
  7928. int64_t minValue, maxValue;
  7929. GetSignedLimits(basicKind, &minValue, &maxValue);
  7930. return IsValueInRange(val, minValue, maxValue);
  7931. }
  7932. else if (IS_BASIC_UINT(basicKind) || IS_BASIC_BOOL(basicKind)) {
  7933. if (!value.isInt()) {
  7934. return false;
  7935. }
  7936. uint64_t val = value.getInt().getLimitedValue();
  7937. uint64_t maxValue;
  7938. GetUnsignedLimit(basicKind, &maxValue);
  7939. return IsValueInRange(val, (uint64_t)0, maxValue);
  7940. }
  7941. else {
  7942. return false;
  7943. }
  7944. }
  7945. static
  7946. bool IsPrecisionLossIrrelevant(ASTContext& Ctx, _In_ const Expr* sourceExpr, QualType targetType, ArBasicKind targetKind)
  7947. {
  7948. DXASSERT_NOMSG(!targetType.isNull());
  7949. DXASSERT_NOMSG(sourceExpr != nullptr);
  7950. Expr::EvalResult evalResult;
  7951. if (sourceExpr->EvaluateAsRValue(evalResult, Ctx)) {
  7952. if (evalResult.Diag == nullptr || evalResult.Diag->empty()) {
  7953. return IsValueInBasicRange(targetKind, evalResult.Val);
  7954. }
  7955. }
  7956. return false;
  7957. }
  7958. bool HLSLExternalSource::ValidateCast(
  7959. SourceLocation OpLoc,
  7960. _In_ Expr* sourceExpr,
  7961. QualType target,
  7962. bool explicitConversion,
  7963. bool suppressWarnings,
  7964. bool suppressErrors,
  7965. _Inout_opt_ StandardConversionSequence* standard)
  7966. {
  7967. DXASSERT_NOMSG(sourceExpr != nullptr);
  7968. if (OpLoc.isInvalid())
  7969. OpLoc = sourceExpr->getExprLoc();
  7970. QualType source = sourceExpr->getType();
  7971. TYPE_CONVERSION_REMARKS remarks;
  7972. if (!CanConvert(OpLoc, sourceExpr, target, explicitConversion, &remarks, standard))
  7973. {
  7974. const bool IsOutputParameter = false;
  7975. //
  7976. // Check whether the lack of explicit-ness matters.
  7977. //
  7978. // Setting explicitForDiagnostics to true in that case will avoid the message
  7979. // saying anything about the implicit nature of the cast, when adding the
  7980. // explicit cast won't make a difference.
  7981. //
  7982. bool explicitForDiagnostics = explicitConversion;
  7983. if (explicitConversion == false)
  7984. {
  7985. if (!CanConvert(OpLoc, sourceExpr, target, true, &remarks, nullptr))
  7986. {
  7987. // Can't convert either way - implicit/explicit doesn't matter.
  7988. explicitForDiagnostics = true;
  7989. }
  7990. }
  7991. if (!suppressErrors)
  7992. {
  7993. m_sema->Diag(OpLoc, diag::err_hlsl_cannot_convert)
  7994. << explicitForDiagnostics << IsOutputParameter << source << target;
  7995. }
  7996. return false;
  7997. }
  7998. if (!suppressWarnings)
  7999. {
  8000. if (!explicitConversion)
  8001. {
  8002. if ((remarks & TYPE_CONVERSION_PRECISION_LOSS) != 0)
  8003. {
  8004. // This is a much more restricted version of the analysis does
  8005. // StandardConversionSequence::getNarrowingKind
  8006. if (!IsPrecisionLossIrrelevant(*m_context, sourceExpr, target, GetTypeElementKind(target)))
  8007. {
  8008. m_sema->Diag(OpLoc, diag::warn_hlsl_narrowing) << source << target;
  8009. }
  8010. }
  8011. if ((remarks & TYPE_CONVERSION_ELT_TRUNCATION) != 0)
  8012. {
  8013. m_sema->Diag(OpLoc, diag::warn_hlsl_implicit_vector_truncation);
  8014. }
  8015. }
  8016. }
  8017. return true;
  8018. }
  8019. ////////////////////////////////////////////////////////////////////////////////
  8020. // Functions exported from this translation unit. //
  8021. /// <summary>Performs HLSL-specific processing for unary operators.</summary>
  8022. QualType hlsl::CheckUnaryOpForHLSL(Sema& self,
  8023. SourceLocation OpLoc,
  8024. UnaryOperatorKind Opc,
  8025. ExprResult& InputExpr,
  8026. ExprValueKind& VK,
  8027. ExprObjectKind& OK)
  8028. {
  8029. ExternalSemaSource* externalSource = self.getExternalSource();
  8030. if (externalSource == nullptr) {
  8031. return QualType();
  8032. }
  8033. HLSLExternalSource* hlsl = reinterpret_cast<HLSLExternalSource*>(externalSource);
  8034. return hlsl->CheckUnaryOpForHLSL(OpLoc, Opc, InputExpr, VK, OK);
  8035. }
  8036. /// <summary>Performs HLSL-specific processing for binary operators.</summary>
  8037. void hlsl::CheckBinOpForHLSL(Sema& self,
  8038. SourceLocation OpLoc,
  8039. BinaryOperatorKind Opc,
  8040. ExprResult& LHS,
  8041. ExprResult& RHS,
  8042. QualType& ResultTy,
  8043. QualType& CompLHSTy,
  8044. QualType& CompResultTy)
  8045. {
  8046. ExternalSemaSource* externalSource = self.getExternalSource();
  8047. if (externalSource == nullptr) {
  8048. return;
  8049. }
  8050. HLSLExternalSource* hlsl = reinterpret_cast<HLSLExternalSource*>(externalSource);
  8051. return hlsl->CheckBinOpForHLSL(OpLoc, Opc, LHS, RHS, ResultTy, CompLHSTy, CompResultTy);
  8052. }
  8053. /// <summary>Performs HLSL-specific processing of template declarations.</summary>
  8054. bool hlsl::CheckTemplateArgumentListForHLSL(Sema& self, TemplateDecl* Template, SourceLocation TemplateLoc, TemplateArgumentListInfo& TemplateArgList)
  8055. {
  8056. DXASSERT_NOMSG(Template != nullptr);
  8057. ExternalSemaSource* externalSource = self.getExternalSource();
  8058. if (externalSource == nullptr) {
  8059. return false;
  8060. }
  8061. HLSLExternalSource* hlsl = reinterpret_cast<HLSLExternalSource*>(externalSource);
  8062. return hlsl->CheckTemplateArgumentListForHLSL(Template, TemplateLoc, TemplateArgList);
  8063. }
  8064. /// <summary>Deduces template arguments on a function call in an HLSL program.</summary>
  8065. Sema::TemplateDeductionResult hlsl::DeduceTemplateArgumentsForHLSL(Sema* self,
  8066. FunctionTemplateDecl *FunctionTemplate,
  8067. TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> Args,
  8068. FunctionDecl *&Specialization, TemplateDeductionInfo &Info)
  8069. {
  8070. return HLSLExternalSource::FromSema(self)
  8071. ->DeduceTemplateArgumentsForHLSL(FunctionTemplate, ExplicitTemplateArgs, Args, Specialization, Info);
  8072. }
  8073. void hlsl::DiagnoseControlFlowConditionForHLSL(Sema *self, Expr *condExpr, StringRef StmtName) {
  8074. while (ImplicitCastExpr *IC = dyn_cast<ImplicitCastExpr>(condExpr)) {
  8075. if (IC->getCastKind() == CastKind::CK_HLSLMatrixTruncationCast ||
  8076. IC->getCastKind() == CastKind::CK_HLSLVectorTruncationCast) {
  8077. self->Diag(condExpr->getLocStart(),
  8078. diag::err_hlsl_control_flow_cond_not_scalar)
  8079. << StmtName;
  8080. return;
  8081. }
  8082. condExpr = IC->getSubExpr();
  8083. }
  8084. }
  8085. static bool ShaderModelsMatch(const StringRef& left, const StringRef& right)
  8086. {
  8087. // TODO: handle shorthand cases.
  8088. return left.size() == 0 || right.size() == 0 || left.equals(right);
  8089. }
  8090. void hlsl::DiagnosePackingOffset(
  8091. clang::Sema* self,
  8092. SourceLocation loc,
  8093. clang::QualType type,
  8094. int componentOffset)
  8095. {
  8096. DXASSERT_NOMSG(0 <= componentOffset && componentOffset <= 3);
  8097. if (componentOffset > 0) {
  8098. HLSLExternalSource* source = HLSLExternalSource::FromSema(self);
  8099. ArBasicKind element = source->GetTypeElementKind(type);
  8100. ArTypeObjectKind shape = source->GetTypeObjectKind(type);
  8101. // Only perform some simple validation for now.
  8102. if (IsObjectKindPrimitiveAggregate(shape) && IsBasicKindNumeric(element)) {
  8103. int count = GetElementCount(type);
  8104. if (count > (4 - componentOffset)) {
  8105. self->Diag(loc, diag::err_hlsl_register_or_offset_bind_not_valid);
  8106. }
  8107. }
  8108. }
  8109. }
  8110. void hlsl::DiagnoseRegisterType(
  8111. clang::Sema* self,
  8112. clang::SourceLocation loc,
  8113. clang::QualType type,
  8114. char registerType)
  8115. {
  8116. HLSLExternalSource* source = HLSLExternalSource::FromSema(self);
  8117. ArBasicKind element = source->GetTypeElementKind(type);
  8118. StringRef expected("none");
  8119. bool isValid = true;
  8120. bool isWarning = false;
  8121. switch (element)
  8122. {
  8123. case AR_BASIC_BOOL:
  8124. case AR_BASIC_LITERAL_FLOAT:
  8125. case AR_BASIC_FLOAT16:
  8126. case AR_BASIC_FLOAT32_PARTIAL_PRECISION:
  8127. case AR_BASIC_FLOAT32:
  8128. case AR_BASIC_FLOAT64:
  8129. case AR_BASIC_LITERAL_INT:
  8130. case AR_BASIC_INT8:
  8131. case AR_BASIC_UINT8:
  8132. case AR_BASIC_INT16:
  8133. case AR_BASIC_UINT16:
  8134. case AR_BASIC_INT32:
  8135. case AR_BASIC_UINT32:
  8136. case AR_BASIC_INT64:
  8137. case AR_BASIC_UINT64:
  8138. case AR_BASIC_MIN10FLOAT:
  8139. case AR_BASIC_MIN16FLOAT:
  8140. case AR_BASIC_MIN12INT:
  8141. case AR_BASIC_MIN16INT:
  8142. case AR_BASIC_MIN16UINT:
  8143. expected = "'b', 'c', or 'i'";
  8144. isValid = registerType == 'b' || registerType == 'c' || registerType == 'i' ||
  8145. registerType == 'B' || registerType == 'C' || registerType == 'I';
  8146. break;
  8147. case AR_OBJECT_TEXTURE1D:
  8148. case AR_OBJECT_TEXTURE1D_ARRAY:
  8149. case AR_OBJECT_TEXTURE2D:
  8150. case AR_OBJECT_TEXTURE2D_ARRAY:
  8151. case AR_OBJECT_TEXTURE3D:
  8152. case AR_OBJECT_TEXTURECUBE:
  8153. case AR_OBJECT_TEXTURECUBE_ARRAY:
  8154. case AR_OBJECT_TEXTURE2DMS:
  8155. case AR_OBJECT_TEXTURE2DMS_ARRAY:
  8156. expected = "'t' or 's'";
  8157. isValid = registerType == 't' || registerType == 's' ||
  8158. registerType == 'T' || registerType == 'S';
  8159. break;
  8160. case AR_OBJECT_SAMPLER:
  8161. case AR_OBJECT_SAMPLER1D:
  8162. case AR_OBJECT_SAMPLER2D:
  8163. case AR_OBJECT_SAMPLER3D:
  8164. case AR_OBJECT_SAMPLERCUBE:
  8165. case AR_OBJECT_SAMPLERCOMPARISON:
  8166. expected = "'s' or 't'";
  8167. isValid = registerType == 's' || registerType == 't' ||
  8168. registerType == 'S' || registerType == 'T';
  8169. break;
  8170. case AR_OBJECT_BUFFER:
  8171. expected = "'t'";
  8172. isValid = registerType == 't' || registerType == 'T';
  8173. break;
  8174. case AR_OBJECT_POINTSTREAM:
  8175. case AR_OBJECT_LINESTREAM:
  8176. case AR_OBJECT_TRIANGLESTREAM:
  8177. isValid = false;
  8178. isWarning = true;
  8179. break;
  8180. case AR_OBJECT_INPUTPATCH:
  8181. case AR_OBJECT_OUTPUTPATCH:
  8182. isValid = false;
  8183. isWarning = true;
  8184. break;
  8185. case AR_OBJECT_RWTEXTURE1D:
  8186. case AR_OBJECT_RWTEXTURE1D_ARRAY:
  8187. case AR_OBJECT_RWTEXTURE2D:
  8188. case AR_OBJECT_RWTEXTURE2D_ARRAY:
  8189. case AR_OBJECT_RWTEXTURE3D:
  8190. case AR_OBJECT_RWBUFFER:
  8191. expected = "'u'";
  8192. isValid = registerType == 'u' || registerType == 'U';
  8193. break;
  8194. case AR_OBJECT_BYTEADDRESS_BUFFER:
  8195. case AR_OBJECT_STRUCTURED_BUFFER:
  8196. expected = "'t'";
  8197. isValid = registerType == 't' || registerType == 'T';
  8198. break;
  8199. case AR_OBJECT_CONSUME_STRUCTURED_BUFFER:
  8200. case AR_OBJECT_RWBYTEADDRESS_BUFFER:
  8201. case AR_OBJECT_RWSTRUCTURED_BUFFER:
  8202. case AR_OBJECT_RWSTRUCTURED_BUFFER_ALLOC:
  8203. case AR_OBJECT_RWSTRUCTURED_BUFFER_CONSUME:
  8204. case AR_OBJECT_APPEND_STRUCTURED_BUFFER:
  8205. expected = "'u'";
  8206. isValid = registerType == 'u' || registerType == 'U';
  8207. break;
  8208. case AR_OBJECT_CONSTANT_BUFFER:
  8209. expected = "'b'";
  8210. isValid = registerType == 'b' || registerType == 'B';
  8211. break;
  8212. case AR_OBJECT_TEXTURE_BUFFER:
  8213. expected = "'t'";
  8214. isValid = registerType == 't' || registerType == 'T';
  8215. break;
  8216. case AR_OBJECT_ROVBUFFER:
  8217. case AR_OBJECT_ROVBYTEADDRESS_BUFFER:
  8218. case AR_OBJECT_ROVSTRUCTURED_BUFFER:
  8219. case AR_OBJECT_ROVTEXTURE1D:
  8220. case AR_OBJECT_ROVTEXTURE1D_ARRAY:
  8221. case AR_OBJECT_ROVTEXTURE2D:
  8222. case AR_OBJECT_ROVTEXTURE2D_ARRAY:
  8223. case AR_OBJECT_ROVTEXTURE3D:
  8224. expected = "'u'";
  8225. isValid = registerType == 'u' || registerType == 'U';
  8226. break;
  8227. case AR_OBJECT_LEGACY_EFFECT: // Used for all unsupported but ignored legacy effect types
  8228. isWarning = true;
  8229. break; // So we don't care what you tried to bind it to
  8230. default: // Other types have no associated registers.
  8231. break;
  8232. }
  8233. // fxc is inconsistent as to when it reports an error and when it ignores invalid bind semantics, so emit
  8234. // a warning instead.
  8235. if (!isValid)
  8236. {
  8237. if (isWarning)
  8238. self->Diag(loc, diag::warn_hlsl_incorrect_bind_semantic) << expected;
  8239. else
  8240. self->Diag(loc, diag::err_hlsl_incorrect_bind_semantic) << expected;
  8241. }
  8242. }
  8243. struct NameLookup {
  8244. FunctionDecl *Found;
  8245. FunctionDecl *Other;
  8246. };
  8247. static NameLookup GetSingleFunctionDeclByName(clang::Sema *self, StringRef Name, bool checkPatch) {
  8248. auto DN = DeclarationName(&self->getASTContext().Idents.get(Name));
  8249. FunctionDecl *pFoundDecl = nullptr;
  8250. for (auto idIter = self->IdResolver.begin(DN), idEnd = self->IdResolver.end(); idIter != idEnd; ++idIter) {
  8251. FunctionDecl *pFnDecl = dyn_cast<FunctionDecl>(*idIter);
  8252. if (!pFnDecl) continue;
  8253. if (checkPatch && !self->getASTContext().IsPatchConstantFunctionDecl(pFnDecl)) continue;
  8254. if (pFoundDecl) {
  8255. return NameLookup{ pFoundDecl, pFnDecl };
  8256. }
  8257. pFoundDecl = pFnDecl;
  8258. }
  8259. return NameLookup{ pFoundDecl, nullptr };
  8260. }
  8261. void hlsl::DiagnoseTranslationUnit(clang::Sema *self) {
  8262. DXASSERT_NOMSG(self != nullptr);
  8263. // Don't bother with global validation if compilation has already failed.
  8264. if (self->getDiagnostics().hasErrorOccurred()) {
  8265. return;
  8266. }
  8267. // Don't check entry function for library.
  8268. if (self->getLangOpts().IsHLSLLibrary) {
  8269. // TODO: validate no recursion start from every function.
  8270. return;
  8271. }
  8272. // TODO: make these error 'real' errors rather than on-the-fly things
  8273. // Validate that the entry point is available.
  8274. DiagnosticsEngine &Diags = self->getDiagnostics();
  8275. FunctionDecl *pEntryPointDecl = nullptr;
  8276. FunctionDecl *pPatchFnDecl = nullptr;
  8277. const std::string &EntryPointName = self->getLangOpts().HLSLEntryFunction;
  8278. if (!EntryPointName.empty()) {
  8279. NameLookup NL = GetSingleFunctionDeclByName(self, EntryPointName, /*checkPatch*/ false);
  8280. if (NL.Found && NL.Other) {
  8281. // NOTE: currently we cannot hit this codepath when CodeGen is enabled, because
  8282. // CodeGenModule::getMangledName will mangle the entry point name into the bare
  8283. // string, and so ambiguous points will produce an error earlier on.
  8284. unsigned id = Diags.getCustomDiagID(clang::DiagnosticsEngine::Level::Error,
  8285. "ambiguous entry point function");
  8286. Diags.Report(NL.Found->getSourceRange().getBegin(), id);
  8287. Diags.Report(NL.Other->getLocation(), diag::note_previous_definition);
  8288. return;
  8289. }
  8290. pEntryPointDecl = NL.Found;
  8291. if (!pEntryPointDecl || !pEntryPointDecl->hasBody()) {
  8292. unsigned id = Diags.getCustomDiagID(clang::DiagnosticsEngine::Level::Error,
  8293. "missing entry point definition");
  8294. Diags.Report(id);
  8295. return;
  8296. }
  8297. }
  8298. // Validate that there is no recursion; start with the entry function.
  8299. // NOTE: the information gathered here could be used to bypass code generation
  8300. // on functions that are unreachable (as an early form of dead code elimination).
  8301. if (pEntryPointDecl) {
  8302. const auto *shaderModel =
  8303. hlsl::ShaderModel::GetByName(self->getLangOpts().HLSLProfile.c_str());
  8304. if (shaderModel->IsGS()) {
  8305. // Validate that GS has the maxvertexcount attribute
  8306. if (!pEntryPointDecl->hasAttr<HLSLMaxVertexCountAttr>()) {
  8307. self->Diag(pEntryPointDecl->getLocation(),
  8308. diag::err_hlsl_missing_maxvertexcount_attr);
  8309. return;
  8310. }
  8311. } else if (shaderModel->IsHS()) {
  8312. if (const HLSLPatchConstantFuncAttr *Attr =
  8313. pEntryPointDecl->getAttr<HLSLPatchConstantFuncAttr>()) {
  8314. NameLookup NL = GetSingleFunctionDeclByName(
  8315. self, Attr->getFunctionName(), /*checkPatch*/ true);
  8316. if (!NL.Found || !NL.Found->hasBody()) {
  8317. unsigned id =
  8318. Diags.getCustomDiagID(clang::DiagnosticsEngine::Level::Error,
  8319. "missing patch function definition");
  8320. Diags.Report(id);
  8321. return;
  8322. }
  8323. pPatchFnDecl = NL.Found;
  8324. } else {
  8325. self->Diag(pEntryPointDecl->getLocation(),
  8326. diag::err_hlsl_missing_patchconstantfunc_attr);
  8327. return;
  8328. }
  8329. }
  8330. hlsl::CallGraphWithRecurseGuard CG;
  8331. CG.BuildForEntry(pEntryPointDecl);
  8332. Decl *pResult = CG.CheckRecursion(pEntryPointDecl);
  8333. if (pResult) {
  8334. unsigned id = Diags.getCustomDiagID(clang::DiagnosticsEngine::Level::Error,
  8335. "recursive functions not allowed");
  8336. Diags.Report(pResult->getSourceRange().getBegin(), id);
  8337. }
  8338. if (pPatchFnDecl) {
  8339. CG.BuildForEntry(pPatchFnDecl);
  8340. Decl *pPatchFnDecl = CG.CheckRecursion(pEntryPointDecl);
  8341. if (pPatchFnDecl) {
  8342. unsigned id = Diags.getCustomDiagID(clang::DiagnosticsEngine::Level::Error,
  8343. "recursive functions not allowed (via patch function)");
  8344. Diags.Report(pPatchFnDecl->getSourceRange().getBegin(), id);
  8345. }
  8346. }
  8347. }
  8348. }
  8349. void hlsl::DiagnoseUnusualAnnotationsForHLSL(
  8350. Sema& S,
  8351. std::vector<hlsl::UnusualAnnotation *>& annotations)
  8352. {
  8353. bool packoffsetOverriddenReported = false;
  8354. auto && iter = annotations.begin();
  8355. auto && end = annotations.end();
  8356. for (; iter != end; ++iter) {
  8357. switch ((*iter)->getKind()) {
  8358. case hlsl::UnusualAnnotation::UA_ConstantPacking: {
  8359. hlsl::ConstantPacking* constantPacking = cast<hlsl::ConstantPacking>(*iter);
  8360. // Check whether this will conflict with other packoffsets. If so, only issue a warning; last one wins.
  8361. if (!packoffsetOverriddenReported) {
  8362. auto newIter = iter;
  8363. ++newIter;
  8364. while (newIter != end) {
  8365. hlsl::ConstantPacking* other = dyn_cast_or_null<hlsl::ConstantPacking>(*newIter);
  8366. if (other != nullptr &&
  8367. (other->Subcomponent != constantPacking->Subcomponent || other->ComponentOffset != constantPacking->ComponentOffset)) {
  8368. S.Diag(constantPacking->Loc, diag::warn_hlsl_packoffset_overridden);
  8369. packoffsetOverriddenReported = true;
  8370. break;
  8371. }
  8372. ++newIter;
  8373. }
  8374. }
  8375. break;
  8376. }
  8377. case hlsl::UnusualAnnotation::UA_RegisterAssignment: {
  8378. hlsl::RegisterAssignment* registerAssignment = cast<hlsl::RegisterAssignment>(*iter);
  8379. // Check whether this will conflict with other register assignments of the same type.
  8380. auto newIter = iter;
  8381. ++newIter;
  8382. while (newIter != end) {
  8383. hlsl::RegisterAssignment* other = dyn_cast_or_null<hlsl::RegisterAssignment>(*newIter);
  8384. // Same register bank and profile, but different number.
  8385. if (other != nullptr &&
  8386. ShaderModelsMatch(other->ShaderProfile, registerAssignment->ShaderProfile) &&
  8387. other->RegisterType == registerAssignment->RegisterType &&
  8388. (other->RegisterNumber != registerAssignment->RegisterNumber ||
  8389. other->RegisterOffset != registerAssignment->RegisterOffset)) {
  8390. // Obvious conflict - report it up front.
  8391. S.Diag(registerAssignment->Loc, diag::err_hlsl_register_semantics_conflicting);
  8392. }
  8393. ++newIter;
  8394. }
  8395. break;
  8396. }
  8397. case hlsl::UnusualAnnotation::UA_SemanticDecl: {
  8398. // hlsl::SemanticDecl* semanticDecl = cast<hlsl::SemanticDecl>(*iter);
  8399. // No common validation to be performed.
  8400. break;
  8401. }
  8402. }
  8403. }
  8404. }
  8405. clang::OverloadingResult
  8406. hlsl::GetBestViableFunction(clang::Sema &S, clang::SourceLocation Loc,
  8407. clang::OverloadCandidateSet &set,
  8408. clang::OverloadCandidateSet::iterator &Best) {
  8409. return HLSLExternalSource::FromSema(&S)
  8410. ->GetBestViableFunction(Loc, set, Best);
  8411. }
  8412. void hlsl::InitializeInitSequenceForHLSL(Sema *self,
  8413. const InitializedEntity &Entity,
  8414. const InitializationKind &Kind,
  8415. MultiExprArg Args,
  8416. bool TopLevelOfInitList,
  8417. InitializationSequence *initSequence) {
  8418. return HLSLExternalSource::FromSema(self)
  8419. ->InitializeInitSequenceForHLSL(Entity, Kind, Args, TopLevelOfInitList, initSequence);
  8420. }
  8421. static unsigned CaculateInitListSize(HLSLExternalSource *hlslSource,
  8422. const clang::InitListExpr *InitList) {
  8423. unsigned totalSize = 0;
  8424. for (unsigned i = 0; i < InitList->getNumInits(); i++) {
  8425. const clang::Expr *EltInit = InitList->getInit(i);
  8426. QualType EltInitTy = EltInit->getType();
  8427. if (const InitListExpr *EltInitList = dyn_cast<InitListExpr>(EltInit)) {
  8428. totalSize += CaculateInitListSize(hlslSource, EltInitList);
  8429. } else {
  8430. totalSize += hlslSource->GetNumBasicElements(EltInitTy);
  8431. }
  8432. }
  8433. return totalSize;
  8434. }
  8435. unsigned hlsl::CaculateInitListArraySizeForHLSL(
  8436. _In_ clang::Sema* sema,
  8437. _In_ const clang::InitListExpr *InitList,
  8438. _In_ const clang::QualType EltTy) {
  8439. HLSLExternalSource *hlslSource = HLSLExternalSource::FromSema(sema);
  8440. unsigned totalSize = CaculateInitListSize(hlslSource, InitList);
  8441. unsigned eltSize = hlslSource->GetNumBasicElements(EltTy);
  8442. if (totalSize > 0 && (totalSize % eltSize)==0) {
  8443. return totalSize / eltSize;
  8444. } else {
  8445. return 0;
  8446. }
  8447. }
  8448. bool hlsl::IsConversionToLessOrEqualElements(
  8449. _In_ clang::Sema* self,
  8450. const clang::ExprResult& sourceExpr,
  8451. const clang::QualType& targetType,
  8452. bool explicitConversion)
  8453. {
  8454. return HLSLExternalSource::FromSema(self)
  8455. ->IsConversionToLessOrEqualElements(sourceExpr, targetType, explicitConversion);
  8456. }
  8457. bool hlsl::LookupMatrixMemberExprForHLSL(
  8458. Sema* self,
  8459. Expr& BaseExpr,
  8460. DeclarationName MemberName,
  8461. bool IsArrow,
  8462. SourceLocation OpLoc,
  8463. SourceLocation MemberLoc,
  8464. ExprResult* result)
  8465. {
  8466. return HLSLExternalSource::FromSema(self)
  8467. ->LookupMatrixMemberExprForHLSL(BaseExpr, MemberName, IsArrow, OpLoc, MemberLoc, result);
  8468. }
  8469. bool hlsl::LookupVectorMemberExprForHLSL(
  8470. Sema* self,
  8471. Expr& BaseExpr,
  8472. DeclarationName MemberName,
  8473. bool IsArrow,
  8474. SourceLocation OpLoc,
  8475. SourceLocation MemberLoc,
  8476. ExprResult* result)
  8477. {
  8478. return HLSLExternalSource::FromSema(self)
  8479. ->LookupVectorMemberExprForHLSL(BaseExpr, MemberName, IsArrow, OpLoc, MemberLoc, result);
  8480. }
  8481. bool hlsl::LookupArrayMemberExprForHLSL(
  8482. Sema* self,
  8483. Expr& BaseExpr,
  8484. DeclarationName MemberName,
  8485. bool IsArrow,
  8486. SourceLocation OpLoc,
  8487. SourceLocation MemberLoc,
  8488. ExprResult* result)
  8489. {
  8490. return HLSLExternalSource::FromSema(self)
  8491. ->LookupArrayMemberExprForHLSL(BaseExpr, MemberName, IsArrow, OpLoc, MemberLoc, result);
  8492. }
  8493. clang::ExprResult hlsl::MaybeConvertScalarToVector(
  8494. _In_ clang::Sema* self,
  8495. _In_ clang::Expr* E)
  8496. {
  8497. return HLSLExternalSource::FromSema(self)->MaybeConvertScalarToVector(E);
  8498. }
  8499. bool hlsl::TryStaticCastForHLSL(_In_ Sema* self, ExprResult &SrcExpr,
  8500. QualType DestType,
  8501. Sema::CheckedConversionKind CCK,
  8502. const SourceRange &OpRange, unsigned &msg,
  8503. CastKind &Kind, CXXCastPath &BasePath,
  8504. bool ListInitialization,
  8505. bool SuppressDiagnostics,
  8506. _Inout_opt_ StandardConversionSequence* standard)
  8507. {
  8508. return HLSLExternalSource::FromSema(self)->TryStaticCastForHLSL(
  8509. SrcExpr, DestType, CCK, OpRange, msg, Kind, BasePath, ListInitialization,
  8510. SuppressDiagnostics, SuppressDiagnostics, standard);
  8511. }
  8512. clang::ExprResult hlsl::PerformHLSLConversion(
  8513. _In_ clang::Sema* self,
  8514. _In_ clang::Expr* From,
  8515. _In_ clang::QualType targetType,
  8516. _In_ const clang::StandardConversionSequence &SCS,
  8517. _In_ clang::Sema::CheckedConversionKind CCK)
  8518. {
  8519. return HLSLExternalSource::FromSema(self)->PerformHLSLConversion(From, targetType, SCS, CCK);
  8520. }
  8521. clang::ImplicitConversionSequence hlsl::TrySubscriptIndexInitialization(
  8522. _In_ clang::Sema* self,
  8523. _In_ clang::Expr* SrcExpr,
  8524. clang::QualType DestType)
  8525. {
  8526. return HLSLExternalSource::FromSema(self)
  8527. ->TrySubscriptIndexInitialization(SrcExpr, DestType);
  8528. }
  8529. /// <summary>Performs HLSL-specific initialization on the specified context.</summary>
  8530. void hlsl::InitializeASTContextForHLSL(ASTContext& context)
  8531. {
  8532. HLSLExternalSource* hlslSource = new HLSLExternalSource();
  8533. IntrusiveRefCntPtr<ExternalASTSource> externalSource(hlslSource);
  8534. if (hlslSource->Initialize(context)) {
  8535. context.setExternalSource(externalSource);
  8536. }
  8537. }
  8538. ////////////////////////////////////////////////////////////////////////////////
  8539. // FlattenedTypeIterator implementation //
  8540. /// <summary>Constructs a FlattenedTypeIterator for the specified type.</summary>
  8541. FlattenedTypeIterator::FlattenedTypeIterator(SourceLocation loc, QualType type, HLSLExternalSource& source) :
  8542. m_source(source), m_draining(false), m_springLoaded(false), m_incompleteCount(0), m_typeDepth(0), m_loc(loc)
  8543. {
  8544. if (pushTrackerForType(type, nullptr)) {
  8545. considerLeaf();
  8546. }
  8547. }
  8548. /// <summary>Constructs a FlattenedTypeIterator for the specified expressions.</summary>
  8549. FlattenedTypeIterator::FlattenedTypeIterator(SourceLocation loc, MultiExprArg args, HLSLExternalSource& source) :
  8550. m_source(source), m_draining(false), m_springLoaded(false), m_incompleteCount(0), m_typeDepth(0), m_loc(loc)
  8551. {
  8552. if (!args.empty()) {
  8553. MultiExprArg::iterator ii = args.begin();
  8554. MultiExprArg::iterator ie = args.end();
  8555. DXASSERT(ii != ie, "otherwise empty() returned an incorrect value");
  8556. m_typeTrackers.push_back(FlattenedTypeIterator::FlattenedTypeTracker(ii, ie));
  8557. if (!considerLeaf()) {
  8558. m_typeTrackers.clear();
  8559. }
  8560. }
  8561. }
  8562. /// <summary>Gets the current element in the flattened type hierarchy.</summary>
  8563. QualType FlattenedTypeIterator::getCurrentElement() const
  8564. {
  8565. return m_typeTrackers.back().Type;
  8566. }
  8567. /// <summary>Get the number of repeated current elements.</summary>
  8568. unsigned int FlattenedTypeIterator::getCurrentElementSize() const
  8569. {
  8570. const FlattenedTypeTracker& back = m_typeTrackers.back();
  8571. return (back.IterKind == FK_IncompleteArray) ? 1 : back.Count;
  8572. }
  8573. /// <summary>Checks whether the iterator has a current element type to report.</summary>
  8574. bool FlattenedTypeIterator::hasCurrentElement() const
  8575. {
  8576. return m_typeTrackers.size() > 0;
  8577. }
  8578. /// <summary>Consumes count elements on this iterator.</summary>
  8579. void FlattenedTypeIterator::advanceCurrentElement(unsigned int count)
  8580. {
  8581. DXASSERT(!m_typeTrackers.empty(), "otherwise caller should not be trying to advance to another element");
  8582. DXASSERT(m_typeTrackers.back().IterKind == FK_IncompleteArray || count <= m_typeTrackers.back().Count, "caller should never exceed currently pending element count");
  8583. FlattenedTypeTracker& tracker = m_typeTrackers.back();
  8584. if (tracker.IterKind == FK_IncompleteArray)
  8585. {
  8586. tracker.Count += count;
  8587. m_springLoaded = true;
  8588. }
  8589. else
  8590. {
  8591. tracker.Count -= count;
  8592. m_springLoaded = false;
  8593. if (m_typeTrackers.back().Count == 0)
  8594. {
  8595. advanceLeafTracker();
  8596. }
  8597. }
  8598. }
  8599. unsigned int FlattenedTypeIterator::countRemaining()
  8600. {
  8601. m_draining = true; // when draining the iterator, incomplete arrays stop functioning as an infinite array
  8602. size_t result = 0;
  8603. while (hasCurrentElement() && !m_springLoaded)
  8604. {
  8605. size_t pending = getCurrentElementSize();
  8606. result += pending;
  8607. advanceCurrentElement(pending);
  8608. }
  8609. return result;
  8610. }
  8611. void FlattenedTypeIterator::advanceLeafTracker()
  8612. {
  8613. DXASSERT(!m_typeTrackers.empty(), "otherwise caller should not be trying to advance to another element");
  8614. for (;;)
  8615. {
  8616. consumeLeaf();
  8617. if (m_typeTrackers.empty()) {
  8618. return;
  8619. }
  8620. if (considerLeaf()) {
  8621. return;
  8622. }
  8623. }
  8624. }
  8625. bool FlattenedTypeIterator::considerLeaf()
  8626. {
  8627. if (m_typeTrackers.empty()) {
  8628. return false;
  8629. }
  8630. m_typeDepth++;
  8631. if (m_typeDepth > MaxTypeDepth) {
  8632. m_source.ReportUnsupportedTypeNesting(m_loc, m_firstType);
  8633. m_typeTrackers.clear();
  8634. m_typeDepth--;
  8635. return false;
  8636. }
  8637. bool result = false;
  8638. FlattenedTypeTracker& tracker = m_typeTrackers.back();
  8639. tracker.IsConsidered = true;
  8640. switch (tracker.IterKind) {
  8641. case FlattenedIterKind::FK_Expressions:
  8642. if (pushTrackerForExpression(tracker.CurrentExpr)) {
  8643. result = considerLeaf();
  8644. }
  8645. break;
  8646. case FlattenedIterKind::FK_Fields:
  8647. if (pushTrackerForType(tracker.CurrentField->getType(), nullptr)) {
  8648. result = considerLeaf();
  8649. } else {
  8650. // Pop empty struct.
  8651. m_typeTrackers.pop_back();
  8652. }
  8653. break;
  8654. case FlattenedIterKind::FK_Bases:
  8655. if (pushTrackerForType(tracker.CurrentBase->getType(), nullptr)) {
  8656. result = considerLeaf();
  8657. } else {
  8658. // Pop empty base.
  8659. m_typeTrackers.pop_back();
  8660. }
  8661. break;
  8662. case FlattenedIterKind::FK_IncompleteArray:
  8663. m_springLoaded = true; // fall through.
  8664. default:
  8665. case FlattenedIterKind::FK_Simple: {
  8666. ArTypeObjectKind objectKind = m_source.GetTypeObjectKind(tracker.Type);
  8667. if (objectKind != ArTypeObjectKind::AR_TOBJ_BASIC &&
  8668. objectKind != ArTypeObjectKind::AR_TOBJ_OBJECT) {
  8669. if (pushTrackerForType(tracker.Type, tracker.CurrentExpr)) {
  8670. result = considerLeaf();
  8671. }
  8672. } else {
  8673. result = true;
  8674. }
  8675. }
  8676. }
  8677. m_typeDepth--;
  8678. return result;
  8679. }
  8680. void FlattenedTypeIterator::consumeLeaf()
  8681. {
  8682. bool topConsumed = true; // Tracks whether we're processing the topmost item which we should consume.
  8683. for (;;) {
  8684. if (m_typeTrackers.empty()) {
  8685. return;
  8686. }
  8687. FlattenedTypeTracker& tracker = m_typeTrackers.back();
  8688. // Reach a leaf which is not considered before.
  8689. // Stop here.
  8690. if (!tracker.IsConsidered) {
  8691. break;
  8692. }
  8693. switch (tracker.IterKind) {
  8694. case FlattenedIterKind::FK_Expressions:
  8695. ++tracker.CurrentExpr;
  8696. if (tracker.CurrentExpr == tracker.EndExpr) {
  8697. m_typeTrackers.pop_back();
  8698. topConsumed = false;
  8699. } else {
  8700. return;
  8701. }
  8702. break;
  8703. case FlattenedIterKind::FK_Fields:
  8704. ++tracker.CurrentField;
  8705. if (tracker.CurrentField == tracker.EndField) {
  8706. m_typeTrackers.pop_back();
  8707. topConsumed = false;
  8708. } else {
  8709. return;
  8710. }
  8711. break;
  8712. case FlattenedIterKind::FK_Bases:
  8713. ++tracker.CurrentBase;
  8714. if (tracker.CurrentBase == tracker.EndBase) {
  8715. m_typeTrackers.pop_back();
  8716. topConsumed = false;
  8717. } else {
  8718. return;
  8719. }
  8720. break;
  8721. case FlattenedIterKind::FK_IncompleteArray:
  8722. if (m_draining) {
  8723. DXASSERT(m_typeTrackers.size() == 1, "m_typeTrackers.size() == 1, otherwise incomplete array isn't topmost");
  8724. m_incompleteCount = tracker.Count;
  8725. m_typeTrackers.pop_back();
  8726. }
  8727. return;
  8728. default:
  8729. case FlattenedIterKind::FK_Simple: {
  8730. m_springLoaded = false;
  8731. if (!topConsumed) {
  8732. DXASSERT(tracker.Count > 0, "tracker.Count > 0 - otherwise we shouldn't be on stack");
  8733. --tracker.Count;
  8734. }
  8735. else {
  8736. topConsumed = false;
  8737. }
  8738. if (tracker.Count == 0) {
  8739. m_typeTrackers.pop_back();
  8740. } else {
  8741. return;
  8742. }
  8743. }
  8744. }
  8745. }
  8746. }
  8747. bool FlattenedTypeIterator::pushTrackerForExpression(MultiExprArg::iterator expression)
  8748. {
  8749. Expr* e = *expression;
  8750. Stmt::StmtClass expressionClass = e->getStmtClass();
  8751. if (expressionClass == Stmt::StmtClass::InitListExprClass) {
  8752. InitListExpr* initExpr = dyn_cast<InitListExpr>(e);
  8753. if (initExpr->getNumInits() == 0) {
  8754. return false;
  8755. }
  8756. MultiExprArg inits(initExpr->getInits(), initExpr->getNumInits());
  8757. MultiExprArg::iterator ii = inits.begin();
  8758. MultiExprArg::iterator ie = inits.end();
  8759. DXASSERT(ii != ie, "otherwise getNumInits() returned an incorrect value");
  8760. m_typeTrackers.push_back(FlattenedTypeIterator::FlattenedTypeTracker(ii, ie));
  8761. return true;
  8762. }
  8763. return pushTrackerForType(e->getType(), expression);
  8764. }
  8765. // TODO: improve this to provide a 'peek' at intermediate types,
  8766. // which should help compare struct foo[1000] to avoid 1000 steps + per-field steps
  8767. bool FlattenedTypeIterator::pushTrackerForType(QualType type, MultiExprArg::iterator expression)
  8768. {
  8769. if (type->isVoidType()) {
  8770. return false;
  8771. }
  8772. if (type->isFunctionType()) {
  8773. return false;
  8774. }
  8775. if (m_firstType.isNull()) {
  8776. m_firstType = type;
  8777. }
  8778. ArTypeObjectKind objectKind = m_source.GetTypeObjectKind(type);
  8779. QualType elementType;
  8780. unsigned int elementCount;
  8781. const RecordType* recordType;
  8782. RecordDecl::field_iterator fi, fe;
  8783. switch (objectKind)
  8784. {
  8785. case ArTypeObjectKind::AR_TOBJ_ARRAY:
  8786. // TODO: handle multi-dimensional arrays
  8787. elementType = type->getAsArrayTypeUnsafe()->getElementType(); // handle arrays of arrays
  8788. elementCount = GetArraySize(type);
  8789. if (elementCount == 0) {
  8790. if (type->isIncompleteArrayType()) {
  8791. m_typeTrackers.push_back(FlattenedTypeIterator::FlattenedTypeTracker(elementType));
  8792. return true;
  8793. }
  8794. return false;
  8795. }
  8796. m_typeTrackers.push_back(FlattenedTypeIterator::FlattenedTypeTracker(
  8797. elementType, elementCount, nullptr));
  8798. return true;
  8799. case ArTypeObjectKind::AR_TOBJ_BASIC:
  8800. m_typeTrackers.push_back(FlattenedTypeIterator::FlattenedTypeTracker(type, 1, expression));
  8801. return true;
  8802. case ArTypeObjectKind::AR_TOBJ_COMPOUND: {
  8803. recordType = type->getAsStructureType();
  8804. if (recordType == nullptr)
  8805. recordType = dyn_cast<RecordType>(type.getTypePtr());
  8806. fi = recordType->getDecl()->field_begin();
  8807. fe = recordType->getDecl()->field_end();
  8808. bool bAddTracker = false;
  8809. // Skip empty struct.
  8810. if (fi != fe) {
  8811. m_typeTrackers.push_back(
  8812. FlattenedTypeIterator::FlattenedTypeTracker(type, fi, fe));
  8813. type = (*fi)->getType();
  8814. bAddTracker = true;
  8815. }
  8816. if (CXXRecordDecl *cxxRecordDecl =
  8817. dyn_cast<CXXRecordDecl>(recordType->getDecl())) {
  8818. CXXRecordDecl::base_class_iterator bi, be;
  8819. bi = cxxRecordDecl->bases_begin();
  8820. be = cxxRecordDecl->bases_end();
  8821. if (bi != be) {
  8822. // Add type tracker for base.
  8823. // Add base after child to make sure base considered first.
  8824. m_typeTrackers.push_back(
  8825. FlattenedTypeIterator::FlattenedTypeTracker(type, bi, be));
  8826. bAddTracker = true;
  8827. }
  8828. }
  8829. return bAddTracker;
  8830. }
  8831. case ArTypeObjectKind::AR_TOBJ_MATRIX:
  8832. m_typeTrackers.push_back(FlattenedTypeIterator::FlattenedTypeTracker(
  8833. m_source.GetMatrixOrVectorElementType(type),
  8834. GetElementCount(type), nullptr));
  8835. return true;
  8836. case ArTypeObjectKind::AR_TOBJ_VECTOR:
  8837. m_typeTrackers.push_back(FlattenedTypeIterator::FlattenedTypeTracker(
  8838. m_source.GetMatrixOrVectorElementType(type),
  8839. GetHLSLVecSize(type), nullptr));
  8840. return true;
  8841. case ArTypeObjectKind::AR_TOBJ_OBJECT: {
  8842. // Object have no sub-types.
  8843. m_typeTrackers.push_back(FlattenedTypeIterator::FlattenedTypeTracker(
  8844. type.getCanonicalType(), 1, expression));
  8845. return true;
  8846. }
  8847. default:
  8848. DXASSERT(false, "unreachable");
  8849. return false;
  8850. }
  8851. }
  8852. FlattenedTypeIterator::ComparisonResult
  8853. FlattenedTypeIterator::CompareIterators(
  8854. HLSLExternalSource& source,
  8855. SourceLocation loc,
  8856. FlattenedTypeIterator& leftIter,
  8857. FlattenedTypeIterator& rightIter)
  8858. {
  8859. FlattenedTypeIterator::ComparisonResult result;
  8860. result.LeftCount = 0;
  8861. result.RightCount = 0;
  8862. result.AreElementsEqual = true; // Until proven otherwise.
  8863. result.CanConvertElements = true; // Until proven otherwise.
  8864. while (leftIter.hasCurrentElement() && rightIter.hasCurrentElement())
  8865. {
  8866. Expr* actualExpr = rightIter.getExprOrNull();
  8867. bool hasExpr = actualExpr != nullptr;
  8868. StmtExpr scratchExpr(nullptr, rightIter.getCurrentElement(), NoLoc, NoLoc);
  8869. StandardConversionSequence standard;
  8870. ExprResult convertedExpr;
  8871. if (!source.CanConvert(loc,
  8872. hasExpr ? actualExpr : &scratchExpr,
  8873. leftIter.getCurrentElement(),
  8874. ExplicitConversionFalse,
  8875. nullptr,
  8876. &standard)) {
  8877. result.AreElementsEqual = false;
  8878. result.CanConvertElements = false;
  8879. break;
  8880. }
  8881. else if (hasExpr && (standard.First != ICK_Identity || !standard.isIdentityConversion()))
  8882. {
  8883. convertedExpr = source.getSema()->PerformImplicitConversion(actualExpr,
  8884. leftIter.getCurrentElement(),
  8885. standard,
  8886. Sema::AA_Casting,
  8887. Sema::CCK_ImplicitConversion);
  8888. }
  8889. if (rightIter.getCurrentElement()->getCanonicalTypeUnqualified() !=
  8890. leftIter.getCurrentElement()->getCanonicalTypeUnqualified())
  8891. {
  8892. result.AreElementsEqual = false;
  8893. }
  8894. unsigned int advance = std::min(leftIter.getCurrentElementSize(), rightIter.getCurrentElementSize());
  8895. DXASSERT(advance > 0, "otherwise one iterator should report empty");
  8896. // If we need to apply conversions to the expressions, then advance a single element.
  8897. if (hasExpr && convertedExpr.isUsable()) {
  8898. rightIter.replaceExpr(convertedExpr.get());
  8899. advance = 1;
  8900. }
  8901. leftIter.advanceCurrentElement(advance);
  8902. rightIter.advanceCurrentElement(advance);
  8903. result.LeftCount += advance;
  8904. result.RightCount += advance;
  8905. }
  8906. result.LeftCount += leftIter.countRemaining();
  8907. result.RightCount += rightIter.countRemaining();
  8908. return result;
  8909. }
  8910. FlattenedTypeIterator::ComparisonResult
  8911. FlattenedTypeIterator::CompareTypes(
  8912. HLSLExternalSource& source,
  8913. SourceLocation leftLoc, SourceLocation rightLoc,
  8914. QualType left, QualType right)
  8915. {
  8916. FlattenedTypeIterator leftIter(leftLoc, left, source);
  8917. FlattenedTypeIterator rightIter(rightLoc, right, source);
  8918. return CompareIterators(source, leftLoc, leftIter, rightIter);
  8919. }
  8920. FlattenedTypeIterator::ComparisonResult
  8921. FlattenedTypeIterator::CompareTypesForInit(
  8922. HLSLExternalSource& source, QualType left, MultiExprArg args,
  8923. SourceLocation leftLoc, SourceLocation rightLoc)
  8924. {
  8925. FlattenedTypeIterator leftIter(leftLoc, left, source);
  8926. FlattenedTypeIterator rightIter(rightLoc, args, source);
  8927. return CompareIterators(source, leftLoc, leftIter, rightIter);
  8928. }
  8929. ////////////////////////////////////////////////////////////////////////////////
  8930. // Attribute processing support. //
  8931. static int ValidateAttributeIntArg(Sema& S, const AttributeList &Attr, unsigned index = 0)
  8932. {
  8933. int64_t value = 0;
  8934. if (Attr.getNumArgs() > index)
  8935. {
  8936. Expr *E = nullptr;
  8937. if (!Attr.isArgExpr(index)) {
  8938. // For case arg is constant variable.
  8939. IdentifierLoc *loc = Attr.getArgAsIdent(index);
  8940. VarDecl *decl = dyn_cast_or_null<VarDecl>(
  8941. S.LookupSingleName(S.getCurScope(), loc->Ident, loc->Loc,
  8942. Sema::LookupNameKind::LookupOrdinaryName));
  8943. if (!decl) {
  8944. S.Diag(Attr.getLoc(), diag::warn_hlsl_attribute_expects_uint_literal) << Attr.getName();
  8945. return value;
  8946. }
  8947. Expr *init = decl->getInit();
  8948. if (!init) {
  8949. S.Diag(Attr.getLoc(), diag::warn_hlsl_attribute_expects_uint_literal) << Attr.getName();
  8950. return value;
  8951. }
  8952. E = init;
  8953. } else
  8954. E = Attr.getArgAsExpr(index);
  8955. clang::APValue ArgNum;
  8956. bool displayError = false;
  8957. if (E->isTypeDependent() || E->isValueDependent() || !E->isCXX11ConstantExpr(S.Context, &ArgNum))
  8958. {
  8959. displayError = true;
  8960. }
  8961. else
  8962. {
  8963. if (ArgNum.isInt())
  8964. {
  8965. value = ArgNum.getInt().getSExtValue();
  8966. }
  8967. else if (ArgNum.isFloat())
  8968. {
  8969. llvm::APSInt floatInt;
  8970. bool isPrecise;
  8971. if (ArgNum.getFloat().convertToInteger(floatInt, llvm::APFloat::rmTowardZero, &isPrecise) == llvm::APFloat::opStatus::opOK)
  8972. {
  8973. value = floatInt.getSExtValue();
  8974. }
  8975. else
  8976. {
  8977. S.Diag(Attr.getLoc(), diag::warn_hlsl_attribute_expects_uint_literal) << Attr.getName();
  8978. }
  8979. }
  8980. else
  8981. {
  8982. displayError = true;
  8983. }
  8984. if (value < 0)
  8985. {
  8986. S.Diag(Attr.getLoc(), diag::warn_hlsl_attribute_expects_uint_literal) << Attr.getName();
  8987. }
  8988. }
  8989. if (displayError)
  8990. {
  8991. S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
  8992. << Attr.getName() << AANT_ArgumentIntegerConstant
  8993. << E->getSourceRange();
  8994. }
  8995. }
  8996. return (int)value;
  8997. }
  8998. // TODO: support float arg directly.
  8999. static int ValidateAttributeFloatArg(Sema &S, const AttributeList &Attr,
  9000. unsigned index = 0) {
  9001. int value = 0;
  9002. if (Attr.getNumArgs() > index) {
  9003. Expr *E = Attr.getArgAsExpr(index);
  9004. if (FloatingLiteral *FL = dyn_cast<FloatingLiteral>(E)) {
  9005. llvm::APFloat flV = FL->getValue();
  9006. if (flV.getSizeInBits(flV.getSemantics()) == 64) {
  9007. llvm::APInt intV = llvm::APInt::floatToBits(flV.convertToDouble());
  9008. value = intV.getLimitedValue();
  9009. } else {
  9010. llvm::APInt intV = llvm::APInt::floatToBits(flV.convertToFloat());
  9011. value = intV.getLimitedValue();
  9012. }
  9013. } else if (IntegerLiteral *IL = dyn_cast<IntegerLiteral>(E)) {
  9014. llvm::APInt intV =
  9015. llvm::APInt::floatToBits((float)IL->getValue().getLimitedValue());
  9016. value = intV.getLimitedValue();
  9017. } else {
  9018. S.Diag(E->getLocStart(), diag::err_hlsl_attribute_expects_float_literal)
  9019. << Attr.getName();
  9020. }
  9021. }
  9022. return value;
  9023. }
  9024. static Stmt* IgnoreParensAndDecay(Stmt* S)
  9025. {
  9026. for (;;)
  9027. {
  9028. switch (S->getStmtClass())
  9029. {
  9030. case Stmt::ParenExprClass:
  9031. S = cast<ParenExpr>(S)->getSubExpr();
  9032. break;
  9033. case Stmt::ImplicitCastExprClass:
  9034. {
  9035. ImplicitCastExpr* castExpr = cast<ImplicitCastExpr>(S);
  9036. if (castExpr->getCastKind() != CK_ArrayToPointerDecay &&
  9037. castExpr->getCastKind() != CK_NoOp &&
  9038. castExpr->getCastKind() != CK_LValueToRValue)
  9039. {
  9040. return S;
  9041. }
  9042. S = castExpr->getSubExpr();
  9043. }
  9044. break;
  9045. default:
  9046. return S;
  9047. }
  9048. }
  9049. }
  9050. static Expr* ValidateClipPlaneArraySubscriptExpr(Sema& S, ArraySubscriptExpr* E)
  9051. {
  9052. DXASSERT_NOMSG(E != nullptr);
  9053. Expr* subscriptExpr = E->getIdx();
  9054. subscriptExpr = dyn_cast<Expr>(subscriptExpr->IgnoreParens());
  9055. if (subscriptExpr == nullptr ||
  9056. subscriptExpr->isTypeDependent() || subscriptExpr->isValueDependent() ||
  9057. !subscriptExpr->isCXX11ConstantExpr(S.Context))
  9058. {
  9059. S.Diag(
  9060. (subscriptExpr == nullptr) ? E->getLocStart() : subscriptExpr->getLocStart(),
  9061. diag::err_hlsl_unsupported_clipplane_argument_subscript_expression);
  9062. return nullptr;
  9063. }
  9064. return E->getBase();
  9065. }
  9066. static bool IsValidClipPlaneDecl(Decl* D)
  9067. {
  9068. Decl::Kind kind = D->getKind();
  9069. if (kind == Decl::Var)
  9070. {
  9071. VarDecl* varDecl = cast<VarDecl>(D);
  9072. if (varDecl->getStorageClass() == StorageClass::SC_Static &&
  9073. varDecl->getType().isConstQualified())
  9074. {
  9075. return false;
  9076. }
  9077. return true;
  9078. }
  9079. else if (kind == Decl::Field)
  9080. {
  9081. return true;
  9082. }
  9083. return false;
  9084. }
  9085. static Expr* ValidateClipPlaneExpr(Sema& S, Expr* E)
  9086. {
  9087. Stmt* cursor = E;
  9088. // clip plane expressions are a linear path, so no need to traverse the tree here.
  9089. while (cursor != nullptr)
  9090. {
  9091. bool supported = true;
  9092. cursor = IgnoreParensAndDecay(cursor);
  9093. switch (cursor->getStmtClass())
  9094. {
  9095. case Stmt::ArraySubscriptExprClass:
  9096. cursor = ValidateClipPlaneArraySubscriptExpr(S, cast<ArraySubscriptExpr>(cursor));
  9097. if (cursor == nullptr)
  9098. {
  9099. // nullptr indicates failure, and the error message has already been printed out
  9100. return nullptr;
  9101. }
  9102. break;
  9103. case Stmt::DeclRefExprClass:
  9104. {
  9105. DeclRefExpr* declRef = cast<DeclRefExpr>(cursor);
  9106. Decl* decl = declRef->getDecl();
  9107. supported = IsValidClipPlaneDecl(decl);
  9108. cursor = supported ? nullptr : cursor;
  9109. }
  9110. break;
  9111. case Stmt::MemberExprClass:
  9112. {
  9113. MemberExpr* member = cast<MemberExpr>(cursor);
  9114. supported = IsValidClipPlaneDecl(member->getMemberDecl());
  9115. cursor = supported ? member->getBase() : cursor;
  9116. }
  9117. break;
  9118. default:
  9119. supported = false;
  9120. break;
  9121. }
  9122. if (!supported)
  9123. {
  9124. DXASSERT(cursor != nullptr, "otherwise it was cleared when the supported flag was set to false");
  9125. S.Diag(cursor->getLocStart(), diag::err_hlsl_unsupported_clipplane_argument_expression);
  9126. return nullptr;
  9127. }
  9128. }
  9129. // Validate that the type is a float4.
  9130. QualType expressionType = E->getType();
  9131. HLSLExternalSource* hlslSource = HLSLExternalSource::FromSema(&S);
  9132. if (hlslSource->GetTypeElementKind(expressionType) != ArBasicKind::AR_BASIC_FLOAT32 ||
  9133. hlslSource->GetTypeObjectKind(expressionType) != ArTypeObjectKind::AR_TOBJ_VECTOR)
  9134. {
  9135. S.Diag(E->getLocStart(), diag::err_hlsl_unsupported_clipplane_argument_type) << expressionType;
  9136. return nullptr;
  9137. }
  9138. return E;
  9139. }
  9140. static Attr* HandleClipPlanes(Sema& S, const AttributeList &A)
  9141. {
  9142. Expr* clipExprs[6];
  9143. for (unsigned int index = 0; index < _countof(clipExprs); index++)
  9144. {
  9145. if (A.getNumArgs() <= index)
  9146. {
  9147. clipExprs[index] = nullptr;
  9148. continue;
  9149. }
  9150. Expr *E = A.getArgAsExpr(index);
  9151. clipExprs[index] = ValidateClipPlaneExpr(S, E);
  9152. }
  9153. return ::new (S.Context) HLSLClipPlanesAttr(A.getRange(), S.Context,
  9154. clipExprs[0], clipExprs[1], clipExprs[2], clipExprs[3], clipExprs[4], clipExprs[5],
  9155. A.getAttributeSpellingListIndex());
  9156. }
  9157. static Attr* HandleUnrollAttribute(Sema& S, const AttributeList &Attr)
  9158. {
  9159. int argValue = ValidateAttributeIntArg(S, Attr);
  9160. // Default value is 1.
  9161. if (Attr.getNumArgs() == 0) argValue = 1;
  9162. return ::new (S.Context) HLSLUnrollAttr(Attr.getRange(), S.Context,
  9163. argValue, Attr.getAttributeSpellingListIndex());
  9164. }
  9165. static void ValidateAttributeOnLoop(Sema& S, Stmt* St, const AttributeList &Attr)
  9166. {
  9167. Stmt::StmtClass stClass = St->getStmtClass();
  9168. if (stClass != Stmt::ForStmtClass && stClass != Stmt::WhileStmtClass && stClass != Stmt::DoStmtClass)
  9169. {
  9170. S.Diag(Attr.getLoc(), diag::warn_hlsl_unsupported_statement_for_loop_attribute)
  9171. << Attr.getName();
  9172. }
  9173. }
  9174. static void ValidateAttributeOnSwitch(Sema& S, Stmt* St, const AttributeList &Attr)
  9175. {
  9176. Stmt::StmtClass stClass = St->getStmtClass();
  9177. if (stClass != Stmt::SwitchStmtClass)
  9178. {
  9179. S.Diag(Attr.getLoc(), diag::warn_hlsl_unsupported_statement_for_switch_attribute)
  9180. << Attr.getName();
  9181. }
  9182. }
  9183. static void ValidateAttributeOnSwitchOrIf(Sema& S, Stmt* St, const AttributeList &Attr)
  9184. {
  9185. Stmt::StmtClass stClass = St->getStmtClass();
  9186. if (stClass != Stmt::SwitchStmtClass && stClass != Stmt::IfStmtClass)
  9187. {
  9188. S.Diag(Attr.getLoc(), diag::warn_hlsl_unsupported_statement_for_if_switch_attribute)
  9189. << Attr.getName();
  9190. }
  9191. }
  9192. static StringRef ValidateAttributeStringArg(Sema& S, const AttributeList &A, _In_opt_z_ const char* values, unsigned index = 0)
  9193. {
  9194. // values is an optional comma-separated list of potential values.
  9195. if (A.getNumArgs() <= index)
  9196. return StringRef();
  9197. Expr* E = A.getArgAsExpr(index);
  9198. if (E->isTypeDependent() || E->isValueDependent() || E->getStmtClass() != Stmt::StringLiteralClass)
  9199. {
  9200. S.Diag(E->getLocStart(), diag::err_hlsl_attribute_expects_string_literal)
  9201. << A.getName();
  9202. return StringRef();
  9203. }
  9204. StringLiteral* sl = cast<StringLiteral>(E);
  9205. StringRef result = sl->getString();
  9206. // Return result with no additional validation.
  9207. if (values == nullptr)
  9208. {
  9209. return result;
  9210. }
  9211. const char* value = values;
  9212. while (*value != '\0')
  9213. {
  9214. DXASSERT_NOMSG(*value != ','); // no leading commas in values
  9215. // Look for a match.
  9216. const char* argData = result.data();
  9217. size_t argDataLen = result.size();
  9218. while (argDataLen != 0 && *argData == *value && *value)
  9219. {
  9220. ++argData;
  9221. ++value;
  9222. --argDataLen;
  9223. }
  9224. // Match found if every input character matched.
  9225. if (argDataLen == 0 && (*value == '\0' || *value == ','))
  9226. {
  9227. return result;
  9228. }
  9229. // Move to next separator.
  9230. while (*value != '\0' && *value != ',')
  9231. {
  9232. ++value;
  9233. }
  9234. // Move to the start of the next item if any.
  9235. if (*value == ',') value++;
  9236. }
  9237. DXASSERT_NOMSG(*value == '\0'); // no other terminating conditions
  9238. // No match found.
  9239. S.Diag(E->getLocStart(), diag::err_hlsl_attribute_expects_string_literal_from_list)
  9240. << A.getName() << values;
  9241. return StringRef();
  9242. }
  9243. static
  9244. bool ValidateAttributeTargetIsFunction(Sema& S, Decl* D, const AttributeList &A)
  9245. {
  9246. if (D->isFunctionOrFunctionTemplate())
  9247. {
  9248. return true;
  9249. }
  9250. S.Diag(A.getLoc(), diag::err_hlsl_attribute_valid_on_function_only);
  9251. return false;
  9252. }
  9253. void hlsl::HandleDeclAttributeForHLSL(Sema &S, Decl *D, const AttributeList &A, bool& Handled)
  9254. {
  9255. DXASSERT_NOMSG(D != nullptr);
  9256. DXASSERT_NOMSG(!A.isInvalid());
  9257. Attr* declAttr = nullptr;
  9258. Handled = true;
  9259. switch (A.getKind())
  9260. {
  9261. case AttributeList::AT_HLSLIn:
  9262. declAttr = ::new (S.Context) HLSLInAttr(A.getRange(), S.Context,
  9263. A.getAttributeSpellingListIndex());
  9264. break;
  9265. case AttributeList::AT_HLSLOut:
  9266. declAttr = ::new (S.Context) HLSLOutAttr(A.getRange(), S.Context,
  9267. A.getAttributeSpellingListIndex());
  9268. break;
  9269. case AttributeList::AT_HLSLInOut:
  9270. declAttr = ::new (S.Context) HLSLInOutAttr(A.getRange(), S.Context,
  9271. A.getAttributeSpellingListIndex());
  9272. break;
  9273. case AttributeList::AT_HLSLNoInterpolation:
  9274. declAttr = ::new (S.Context) HLSLNoInterpolationAttr(A.getRange(), S.Context,
  9275. A.getAttributeSpellingListIndex());
  9276. break;
  9277. case AttributeList::AT_HLSLLinear:
  9278. case AttributeList::AT_HLSLCenter:
  9279. declAttr = ::new (S.Context) HLSLLinearAttr(A.getRange(), S.Context,
  9280. A.getAttributeSpellingListIndex());
  9281. break;
  9282. case AttributeList::AT_HLSLNoPerspective:
  9283. declAttr = ::new (S.Context) HLSLNoPerspectiveAttr(A.getRange(), S.Context,
  9284. A.getAttributeSpellingListIndex());
  9285. break;
  9286. case AttributeList::AT_HLSLSample:
  9287. declAttr = ::new (S.Context) HLSLSampleAttr(A.getRange(), S.Context,
  9288. A.getAttributeSpellingListIndex());
  9289. break;
  9290. case AttributeList::AT_HLSLCentroid:
  9291. declAttr = ::new (S.Context) HLSLCentroidAttr(A.getRange(), S.Context,
  9292. A.getAttributeSpellingListIndex());
  9293. break;
  9294. case AttributeList::AT_HLSLPrecise:
  9295. declAttr = ::new (S.Context) HLSLPreciseAttr(A.getRange(), S.Context,
  9296. A.getAttributeSpellingListIndex());
  9297. break;
  9298. case AttributeList::AT_HLSLShared:
  9299. declAttr = ::new (S.Context) HLSLSharedAttr(A.getRange(), S.Context,
  9300. A.getAttributeSpellingListIndex());
  9301. break;
  9302. case AttributeList::AT_HLSLGroupShared:
  9303. declAttr = ::new (S.Context) HLSLGroupSharedAttr(A.getRange(), S.Context,
  9304. A.getAttributeSpellingListIndex());
  9305. break;
  9306. case AttributeList::AT_HLSLUniform:
  9307. declAttr = ::new (S.Context) HLSLUniformAttr(A.getRange(), S.Context,
  9308. A.getAttributeSpellingListIndex());
  9309. break;
  9310. case AttributeList::AT_HLSLColumnMajor:
  9311. declAttr = ::new (S.Context) HLSLColumnMajorAttr(A.getRange(), S.Context,
  9312. A.getAttributeSpellingListIndex());
  9313. break;
  9314. case AttributeList::AT_HLSLRowMajor:
  9315. declAttr = ::new (S.Context) HLSLRowMajorAttr(A.getRange(), S.Context,
  9316. A.getAttributeSpellingListIndex());
  9317. break;
  9318. case AttributeList::AT_HLSLUnorm:
  9319. declAttr = ::new (S.Context) HLSLUnormAttr(A.getRange(), S.Context,
  9320. A.getAttributeSpellingListIndex());
  9321. break;
  9322. case AttributeList::AT_HLSLSnorm:
  9323. declAttr = ::new (S.Context) HLSLSnormAttr(A.getRange(), S.Context,
  9324. A.getAttributeSpellingListIndex());
  9325. break;
  9326. case AttributeList::AT_HLSLPoint:
  9327. declAttr = ::new (S.Context) HLSLPointAttr(A.getRange(), S.Context,
  9328. A.getAttributeSpellingListIndex());
  9329. break;
  9330. case AttributeList::AT_HLSLLine:
  9331. declAttr = ::new (S.Context) HLSLLineAttr(A.getRange(), S.Context,
  9332. A.getAttributeSpellingListIndex());
  9333. break;
  9334. case AttributeList::AT_HLSLLineAdj:
  9335. declAttr = ::new (S.Context) HLSLLineAdjAttr(A.getRange(), S.Context,
  9336. A.getAttributeSpellingListIndex());
  9337. break;
  9338. case AttributeList::AT_HLSLTriangle:
  9339. declAttr = ::new (S.Context) HLSLTriangleAttr(A.getRange(), S.Context,
  9340. A.getAttributeSpellingListIndex());
  9341. break;
  9342. case AttributeList::AT_HLSLTriangleAdj:
  9343. declAttr = ::new (S.Context) HLSLTriangleAdjAttr(A.getRange(), S.Context,
  9344. A.getAttributeSpellingListIndex());
  9345. break;
  9346. case AttributeList::AT_HLSLGloballyCoherent:
  9347. declAttr = ::new (S.Context) HLSLGloballyCoherentAttr(
  9348. A.getRange(), S.Context, A.getAttributeSpellingListIndex());
  9349. break;
  9350. default:
  9351. Handled = false;
  9352. break;
  9353. }
  9354. if (declAttr != nullptr)
  9355. {
  9356. DXASSERT_NOMSG(Handled);
  9357. D->addAttr(declAttr);
  9358. return;
  9359. }
  9360. Handled = true;
  9361. switch (A.getKind())
  9362. {
  9363. // These apply to statements, not declarations. The warning messages clarify this properly.
  9364. case AttributeList::AT_HLSLUnroll:
  9365. case AttributeList::AT_HLSLAllowUAVCondition:
  9366. case AttributeList::AT_HLSLLoop:
  9367. case AttributeList::AT_HLSLFastOpt:
  9368. S.Diag(A.getLoc(), diag::warn_hlsl_unsupported_statement_for_loop_attribute)
  9369. << A.getName();
  9370. return;
  9371. case AttributeList::AT_HLSLBranch:
  9372. case AttributeList::AT_HLSLFlatten:
  9373. S.Diag(A.getLoc(), diag::warn_hlsl_unsupported_statement_for_if_switch_attribute)
  9374. << A.getName();
  9375. return;
  9376. case AttributeList::AT_HLSLForceCase:
  9377. case AttributeList::AT_HLSLCall:
  9378. S.Diag(A.getLoc(), diag::warn_hlsl_unsupported_statement_for_switch_attribute)
  9379. << A.getName();
  9380. return;
  9381. // These are the cases that actually apply to declarations.
  9382. case AttributeList::AT_HLSLClipPlanes:
  9383. declAttr = HandleClipPlanes(S, A);
  9384. break;
  9385. case AttributeList::AT_HLSLDomain:
  9386. declAttr = ::new (S.Context) HLSLDomainAttr(A.getRange(), S.Context,
  9387. ValidateAttributeStringArg(S, A, "tri,quad,isoline"), A.getAttributeSpellingListIndex());
  9388. break;
  9389. case AttributeList::AT_HLSLEarlyDepthStencil:
  9390. declAttr = ::new (S.Context) HLSLEarlyDepthStencilAttr(A.getRange(), S.Context, A.getAttributeSpellingListIndex());
  9391. break;
  9392. case AttributeList::AT_HLSLInstance:
  9393. declAttr = ::new (S.Context) HLSLInstanceAttr(A.getRange(), S.Context,
  9394. ValidateAttributeIntArg(S, A), A.getAttributeSpellingListIndex());
  9395. break;
  9396. case AttributeList::AT_HLSLMaxTessFactor:
  9397. declAttr = ::new (S.Context) HLSLMaxTessFactorAttr(A.getRange(), S.Context,
  9398. ValidateAttributeFloatArg(S, A), A.getAttributeSpellingListIndex());
  9399. break;
  9400. case AttributeList::AT_HLSLNumThreads:
  9401. declAttr = ::new (S.Context) HLSLNumThreadsAttr(A.getRange(), S.Context,
  9402. ValidateAttributeIntArg(S, A), ValidateAttributeIntArg(S, A, 1), ValidateAttributeIntArg(S, A, 2),
  9403. A.getAttributeSpellingListIndex());
  9404. break;
  9405. case AttributeList::AT_HLSLRootSignature:
  9406. declAttr = ::new (S.Context) HLSLRootSignatureAttr(A.getRange(), S.Context,
  9407. ValidateAttributeStringArg(S, A, /*validate strings*/nullptr),
  9408. A.getAttributeSpellingListIndex());
  9409. break;
  9410. case AttributeList::AT_HLSLOutputControlPoints:
  9411. declAttr = ::new (S.Context) HLSLOutputControlPointsAttr(A.getRange(), S.Context,
  9412. ValidateAttributeIntArg(S, A), A.getAttributeSpellingListIndex());
  9413. break;
  9414. case AttributeList::AT_HLSLOutputTopology:
  9415. declAttr = ::new (S.Context) HLSLOutputTopologyAttr(A.getRange(), S.Context,
  9416. ValidateAttributeStringArg(S, A, "point,line,triangle,triangle_cw,triangle_ccw"), A.getAttributeSpellingListIndex());
  9417. break;
  9418. case AttributeList::AT_HLSLPartitioning:
  9419. declAttr = ::new (S.Context) HLSLPartitioningAttr(A.getRange(), S.Context,
  9420. ValidateAttributeStringArg(S, A, "integer,fractional_even,fractional_odd,pow2"), A.getAttributeSpellingListIndex());
  9421. break;
  9422. case AttributeList::AT_HLSLPatchConstantFunc:
  9423. declAttr = ::new (S.Context) HLSLPatchConstantFuncAttr(A.getRange(), S.Context,
  9424. ValidateAttributeStringArg(S, A, nullptr), A.getAttributeSpellingListIndex());
  9425. break;
  9426. case AttributeList::AT_HLSLShader:
  9427. declAttr = ::new (S.Context) HLSLShaderAttr(
  9428. A.getRange(), S.Context,
  9429. ValidateAttributeStringArg(S, A,
  9430. "compute,vertex,pixel,hull,domain,geometry,raygeneration,intersection,anyhit,closesthit,miss,callable"),
  9431. A.getAttributeSpellingListIndex());
  9432. break;
  9433. case AttributeList::AT_HLSLMaxVertexCount:
  9434. declAttr = ::new (S.Context) HLSLMaxVertexCountAttr(A.getRange(), S.Context,
  9435. ValidateAttributeIntArg(S, A), A.getAttributeSpellingListIndex());
  9436. break;
  9437. case AttributeList::AT_HLSLExperimental:
  9438. declAttr = ::new (S.Context) HLSLExperimentalAttr(A.getRange(), S.Context,
  9439. ValidateAttributeStringArg(S, A, nullptr, 0), ValidateAttributeStringArg(S, A, nullptr, 1),
  9440. A.getAttributeSpellingListIndex());
  9441. break;
  9442. case AttributeList::AT_NoInline:
  9443. declAttr = ::new (S.Context) NoInlineAttr(A.getRange(), S.Context, A.getAttributeSpellingListIndex());
  9444. break;
  9445. case AttributeList::AT_HLSLExport:
  9446. declAttr = ::new (S.Context) HLSLExportAttr(A.getRange(), S.Context, A.getAttributeSpellingListIndex());
  9447. break;
  9448. default:
  9449. Handled = false;
  9450. break; // SPIRV Change: was return;
  9451. }
  9452. if (declAttr != nullptr)
  9453. {
  9454. DXASSERT_NOMSG(Handled);
  9455. D->addAttr(declAttr);
  9456. // The attribute has been set but will have no effect. Validation will emit a diagnostic
  9457. // and prevent code generation.
  9458. ValidateAttributeTargetIsFunction(S, D, A);
  9459. return; // SPIRV Change
  9460. }
  9461. // SPIRV Change Starts
  9462. Handled = true;
  9463. switch (A.getKind())
  9464. {
  9465. case AttributeList::AT_VKBuiltIn:
  9466. declAttr = ::new (S.Context) VKBuiltInAttr(A.getRange(), S.Context,
  9467. ValidateAttributeStringArg(S, A, "PointSize,HelperInvocation,BaseVertex,BaseInstance,DrawIndex,DeviceIndex"),
  9468. A.getAttributeSpellingListIndex());
  9469. break;
  9470. case AttributeList::AT_VKLocation:
  9471. declAttr = ::new (S.Context) VKLocationAttr(A.getRange(), S.Context,
  9472. ValidateAttributeIntArg(S, A), A.getAttributeSpellingListIndex());
  9473. break;
  9474. case AttributeList::AT_VKIndex:
  9475. declAttr = ::new (S.Context) VKIndexAttr(A.getRange(), S.Context,
  9476. ValidateAttributeIntArg(S, A), A.getAttributeSpellingListIndex());
  9477. break;
  9478. case AttributeList::AT_VKBinding:
  9479. declAttr = ::new (S.Context) VKBindingAttr(A.getRange(), S.Context,
  9480. ValidateAttributeIntArg(S, A), ValidateAttributeIntArg(S, A, 1),
  9481. A.getAttributeSpellingListIndex());
  9482. break;
  9483. case AttributeList::AT_VKCounterBinding:
  9484. declAttr = ::new (S.Context) VKCounterBindingAttr(A.getRange(), S.Context,
  9485. ValidateAttributeIntArg(S, A), A.getAttributeSpellingListIndex());
  9486. break;
  9487. case AttributeList::AT_VKPushConstant:
  9488. declAttr = ::new (S.Context) VKPushConstantAttr(A.getRange(), S.Context,
  9489. A.getAttributeSpellingListIndex());
  9490. break;
  9491. case AttributeList::AT_VKOffset:
  9492. declAttr = ::new (S.Context) VKOffsetAttr(A.getRange(), S.Context,
  9493. ValidateAttributeIntArg(S, A), A.getAttributeSpellingListIndex());
  9494. break;
  9495. case AttributeList::AT_VKInputAttachmentIndex:
  9496. declAttr = ::new (S.Context) VKInputAttachmentIndexAttr(
  9497. A.getRange(), S.Context, ValidateAttributeIntArg(S, A),
  9498. A.getAttributeSpellingListIndex());
  9499. break;
  9500. case AttributeList::AT_VKConstantId:
  9501. declAttr = ::new (S.Context) VKConstantIdAttr(A.getRange(), S.Context,
  9502. ValidateAttributeIntArg(S, A), A.getAttributeSpellingListIndex());
  9503. break;
  9504. case AttributeList::AT_VKPostDepthCoverage:
  9505. declAttr = ::new (S.Context) VKPostDepthCoverageAttr(A.getRange(), S.Context, A.getAttributeSpellingListIndex());
  9506. break;
  9507. default:
  9508. Handled = false;
  9509. return;
  9510. }
  9511. if (declAttr != nullptr)
  9512. {
  9513. DXASSERT_NOMSG(Handled);
  9514. D->addAttr(declAttr);
  9515. }
  9516. // SPIRV Change Ends
  9517. }
  9518. /// <summary>Processes an attribute for a statement.</summary>
  9519. /// <param name="S">Sema with context.</param>
  9520. /// <param name="St">Statement annotated.</param>
  9521. /// <param name="A">Single parsed attribute to process.</param>
  9522. /// <param name="Range">Range of all attribute lists (useful for FixIts to suggest inclusions).</param>
  9523. /// <param name="Handled">After execution, whether this was recognized and handled.</param>
  9524. /// <returns>An attribute instance if processed, nullptr if not recognized or an error was found.</returns>
  9525. Attr *hlsl::ProcessStmtAttributeForHLSL(Sema &S, Stmt *St, const AttributeList &A, SourceRange Range, bool& Handled)
  9526. {
  9527. // | Construct | Allowed Attributes |
  9528. // +------------------+--------------------------------------------+
  9529. // | for, while, do | loop, fastopt, unroll, allow_uav_condition |
  9530. // | if | branch, flatten |
  9531. // | switch | branch, flatten, forcecase, call |
  9532. Attr * result = nullptr;
  9533. Handled = true;
  9534. switch (A.getKind())
  9535. {
  9536. case AttributeList::AT_HLSLUnroll:
  9537. ValidateAttributeOnLoop(S, St, A);
  9538. result = HandleUnrollAttribute(S, A);
  9539. break;
  9540. case AttributeList::AT_HLSLAllowUAVCondition:
  9541. ValidateAttributeOnLoop(S, St, A);
  9542. result = ::new (S.Context) HLSLAllowUAVConditionAttr(
  9543. A.getRange(), S.Context, A.getAttributeSpellingListIndex());
  9544. break;
  9545. case AttributeList::AT_HLSLLoop:
  9546. ValidateAttributeOnLoop(S, St, A);
  9547. result = ::new (S.Context) HLSLLoopAttr(
  9548. A.getRange(), S.Context, A.getAttributeSpellingListIndex());
  9549. break;
  9550. case AttributeList::AT_HLSLFastOpt:
  9551. ValidateAttributeOnLoop(S, St, A);
  9552. result = ::new (S.Context) HLSLFastOptAttr(
  9553. A.getRange(), S.Context, A.getAttributeSpellingListIndex());
  9554. break;
  9555. case AttributeList::AT_HLSLBranch:
  9556. ValidateAttributeOnSwitchOrIf(S, St, A);
  9557. result = ::new (S.Context) HLSLBranchAttr(
  9558. A.getRange(), S.Context, A.getAttributeSpellingListIndex());
  9559. break;
  9560. case AttributeList::AT_HLSLFlatten:
  9561. ValidateAttributeOnSwitchOrIf(S, St, A);
  9562. result = ::new (S.Context) HLSLFlattenAttr(
  9563. A.getRange(), S.Context, A.getAttributeSpellingListIndex());
  9564. break;
  9565. case AttributeList::AT_HLSLForceCase:
  9566. ValidateAttributeOnSwitch(S, St, A);
  9567. result = ::new (S.Context) HLSLForceCaseAttr(
  9568. A.getRange(), S.Context, A.getAttributeSpellingListIndex());
  9569. break;
  9570. case AttributeList::AT_HLSLCall:
  9571. ValidateAttributeOnSwitch(S, St, A);
  9572. result = ::new (S.Context) HLSLCallAttr(
  9573. A.getRange(), S.Context, A.getAttributeSpellingListIndex());
  9574. break;
  9575. default:
  9576. Handled = false;
  9577. break;
  9578. }
  9579. return result;
  9580. }
  9581. ////////////////////////////////////////////////////////////////////////////////
  9582. // Implementation of Sema members. //
  9583. Decl* Sema::ActOnStartHLSLBuffer(
  9584. Scope* bufferScope,
  9585. bool cbuffer, SourceLocation KwLoc,
  9586. IdentifierInfo *Ident, SourceLocation IdentLoc,
  9587. std::vector<hlsl::UnusualAnnotation *>& BufferAttributes,
  9588. SourceLocation LBrace)
  9589. {
  9590. // For anonymous namespace, take the location of the left brace.
  9591. DeclContext* lexicalParent = getCurLexicalContext();
  9592. clang::HLSLBufferDecl *result = HLSLBufferDecl::Create(
  9593. Context, lexicalParent, cbuffer, /*isConstantBufferView*/ false, KwLoc,
  9594. Ident, IdentLoc, BufferAttributes, LBrace);
  9595. // Keep track of the currently active buffer.
  9596. HLSLBuffers.push_back(result);
  9597. // Validate unusual annotations and emit diagnostics.
  9598. DiagnoseUnusualAnnotationsForHLSL(*this, BufferAttributes);
  9599. auto && unusualIter = BufferAttributes.begin();
  9600. auto && unusualEnd = BufferAttributes.end();
  9601. char expectedRegisterType = cbuffer ? 'b' : 't';
  9602. for (; unusualIter != unusualEnd; ++unusualIter) {
  9603. switch ((*unusualIter)->getKind()) {
  9604. case hlsl::UnusualAnnotation::UA_ConstantPacking: {
  9605. hlsl::ConstantPacking* constantPacking = cast<hlsl::ConstantPacking>(*unusualIter);
  9606. Diag(constantPacking->Loc, diag::err_hlsl_unsupported_buffer_packoffset);
  9607. break;
  9608. }
  9609. case hlsl::UnusualAnnotation::UA_RegisterAssignment: {
  9610. hlsl::RegisterAssignment* registerAssignment = cast<hlsl::RegisterAssignment>(*unusualIter);
  9611. if (registerAssignment->RegisterType != expectedRegisterType && registerAssignment->RegisterType != toupper(expectedRegisterType)) {
  9612. Diag(registerAssignment->Loc, cbuffer ? diag::err_hlsl_unsupported_cbuffer_register :
  9613. diag::err_hlsl_unsupported_tbuffer_register);
  9614. } else if (registerAssignment->ShaderProfile.size() > 0) {
  9615. Diag(registerAssignment->Loc, diag::err_hlsl_unsupported_buffer_slot_target_specific);
  9616. }
  9617. break;
  9618. }
  9619. case hlsl::UnusualAnnotation::UA_SemanticDecl: {
  9620. // Ignore semantic declarations.
  9621. break;
  9622. }
  9623. }
  9624. }
  9625. PushOnScopeChains(result, bufferScope);
  9626. PushDeclContext(bufferScope, result);
  9627. ActOnDocumentableDecl(result);
  9628. return result;
  9629. }
  9630. void Sema::ActOnFinishHLSLBuffer(Decl *Dcl, SourceLocation RBrace)
  9631. {
  9632. DXASSERT_NOMSG(Dcl != nullptr);
  9633. DXASSERT(Dcl == HLSLBuffers.back(), "otherwise push/pop is incorrect");
  9634. dyn_cast<HLSLBufferDecl>(Dcl)->setRBraceLoc(RBrace);
  9635. HLSLBuffers.pop_back();
  9636. PopDeclContext();
  9637. }
  9638. Decl* Sema::getActiveHLSLBuffer() const
  9639. {
  9640. return HLSLBuffers.empty() ? nullptr : HLSLBuffers.back();
  9641. }
  9642. Decl *Sema::ActOnHLSLBufferView(Scope *bufferScope, SourceLocation KwLoc,
  9643. DeclGroupPtrTy &dcl, bool iscbuf) {
  9644. DXASSERT(nullptr == HLSLBuffers.back(), "otherwise push/pop is incorrect");
  9645. HLSLBuffers.pop_back();
  9646. DXASSERT(HLSLBuffers.empty(), "otherwise push/pop is incorrect");
  9647. Decl *decl = dcl.get().getSingleDecl();
  9648. NamedDecl *namedDecl = cast<NamedDecl>(decl);
  9649. IdentifierInfo *Ident = namedDecl->getIdentifier();
  9650. // No anonymous namespace for ConstantBuffer, take the location of the decl.
  9651. SourceLocation Loc = decl->getLocation();
  9652. // Prevent array type in template. The only way to specify an array in the template type
  9653. // is to use a typedef, so we will strip non-typedef arrays off, since these are the legal
  9654. // array dimensions for the CBV/TBV, and if any array type remains, that is illegal.
  9655. QualType declType = cast<VarDecl>(namedDecl)->getType();
  9656. while (declType->isArrayType() && declType->getTypeClass() != Type::TypeClass::Typedef) {
  9657. const ArrayType *arrayType = declType->getAsArrayTypeUnsafe();
  9658. declType = arrayType->getElementType();
  9659. }
  9660. // Check to make that sure only structs are allowed as parameter types for
  9661. // ConstantBuffer and TextureBuffer.
  9662. if (!declType->isStructureType()) {
  9663. Diag(decl->getLocStart(),
  9664. diag::err_hlsl_typeintemplateargument_requires_struct)
  9665. << declType;
  9666. return nullptr;
  9667. }
  9668. std::vector<hlsl::UnusualAnnotation *> hlslAttrs;
  9669. DeclContext *lexicalParent = getCurLexicalContext();
  9670. clang::HLSLBufferDecl *result = HLSLBufferDecl::Create(
  9671. Context, lexicalParent, iscbuf, /*isConstantBufferView*/ true,
  9672. KwLoc, Ident, Loc, hlslAttrs, Loc);
  9673. // set relation
  9674. namedDecl->setDeclContext(result);
  9675. result->addDecl(namedDecl);
  9676. // move attribute from constant to constant buffer
  9677. result->setUnusualAnnotations(namedDecl->getUnusualAnnotations());
  9678. namedDecl->setUnusualAnnotations(hlslAttrs);
  9679. return result;
  9680. }
  9681. bool Sema::IsOnHLSLBufferView() {
  9682. // nullptr will not pushed for cbuffer.
  9683. return !HLSLBuffers.empty() && getActiveHLSLBuffer() == nullptr;
  9684. }
  9685. void Sema::ActOnStartHLSLBufferView() {
  9686. // Push nullptr to mark HLSLBufferView.
  9687. DXASSERT(HLSLBuffers.empty(), "otherwise push/pop is incorrect");
  9688. HLSLBuffers.emplace_back(nullptr);
  9689. }
  9690. HLSLBufferDecl::HLSLBufferDecl(
  9691. DeclContext *DC, bool cbuffer, bool cbufferView, SourceLocation KwLoc,
  9692. IdentifierInfo *Id, SourceLocation IdLoc,
  9693. std::vector<hlsl::UnusualAnnotation *> &BufferAttributes,
  9694. SourceLocation LBrace)
  9695. : NamedDecl(Decl::HLSLBuffer, DC, IdLoc, DeclarationName(Id)),
  9696. DeclContext(Decl::HLSLBuffer), LBraceLoc(LBrace), KwLoc(KwLoc),
  9697. IsCBuffer(cbuffer), IsConstantBufferView(cbufferView) {
  9698. if (!BufferAttributes.empty()) {
  9699. setUnusualAnnotations(UnusualAnnotation::CopyToASTContextArray(
  9700. getASTContext(), BufferAttributes.data(), BufferAttributes.size()));
  9701. }
  9702. }
  9703. HLSLBufferDecl *
  9704. HLSLBufferDecl::Create(ASTContext &C, DeclContext *lexicalParent, bool cbuffer,
  9705. bool constantbuffer, SourceLocation KwLoc,
  9706. IdentifierInfo *Id, SourceLocation IdLoc,
  9707. std::vector<hlsl::UnusualAnnotation *> &BufferAttributes,
  9708. SourceLocation LBrace) {
  9709. DeclContext *DC = C.getTranslationUnitDecl();
  9710. HLSLBufferDecl *result = ::new (C) HLSLBufferDecl(
  9711. DC, cbuffer, constantbuffer, KwLoc, Id, IdLoc, BufferAttributes, LBrace);
  9712. if (DC != lexicalParent) {
  9713. result->setLexicalDeclContext(lexicalParent);
  9714. }
  9715. return result;
  9716. }
  9717. const char *HLSLBufferDecl::getDeclKindName() const {
  9718. static const char *HLSLBufferNames[] = {"tbuffer", "cbuffer", "TextureBuffer",
  9719. "ConstantBuffer"};
  9720. unsigned index = (unsigned ) isCBuffer() | (isConstantBufferView()) << 1;
  9721. return HLSLBufferNames[index];
  9722. }
  9723. void Sema::TransferUnusualAttributes(Declarator &D, NamedDecl *NewDecl) {
  9724. assert(NewDecl != nullptr);
  9725. if (!getLangOpts().HLSL) {
  9726. return;
  9727. }
  9728. if (!D.UnusualAnnotations.empty()) {
  9729. NewDecl->setUnusualAnnotations(UnusualAnnotation::CopyToASTContextArray(
  9730. getASTContext(), D.UnusualAnnotations.data(),
  9731. D.UnusualAnnotations.size()));
  9732. D.UnusualAnnotations.clear();
  9733. }
  9734. }
  9735. /// Checks whether a usage attribute is compatible with those seen so far and
  9736. /// maintains history.
  9737. static bool IsUsageAttributeCompatible(AttributeList::Kind kind, bool &usageIn,
  9738. bool &usageOut) {
  9739. switch (kind) {
  9740. case AttributeList::AT_HLSLIn:
  9741. if (usageIn)
  9742. return false;
  9743. usageIn = true;
  9744. break;
  9745. case AttributeList::AT_HLSLOut:
  9746. if (usageOut)
  9747. return false;
  9748. usageOut = true;
  9749. break;
  9750. default:
  9751. assert(kind == AttributeList::AT_HLSLInOut);
  9752. if (usageOut || usageIn)
  9753. return false;
  9754. usageIn = usageOut = true;
  9755. break;
  9756. }
  9757. return true;
  9758. }
  9759. // Diagnose valid/invalid modifiers for HLSL.
  9760. bool Sema::DiagnoseHLSLDecl(Declarator &D, DeclContext *DC,
  9761. TypeSourceInfo *TInfo, bool isParameter) {
  9762. assert(getLangOpts().HLSL &&
  9763. "otherwise this is called without checking language first");
  9764. // NOTE: some tests may declare templates.
  9765. if (DC->isNamespace() || DC->isDependentContext()) return true;
  9766. DeclSpec::SCS storage = D.getDeclSpec().getStorageClassSpec();
  9767. assert(!DC->isClosure() && "otherwise parser accepted closure syntax instead of failing with a syntax error");
  9768. assert(!DC->isDependentContext() && "otherwise parser accepted a template instead of failing with a syntax error");
  9769. assert(!DC->isNamespace() && "otherwise parser accepted a namespace instead of failing a syntax error");
  9770. bool result = true;
  9771. bool isTypedef = storage == DeclSpec::SCS_typedef;
  9772. bool isFunction = D.isFunctionDeclarator() && !DC->isRecord();
  9773. bool isLocalVar = DC->isFunctionOrMethod() && !isFunction && !isTypedef;
  9774. bool isGlobal = !isParameter && !isTypedef && !isFunction && (DC->isTranslationUnit() || DC->getDeclKind() == Decl::HLSLBuffer);
  9775. bool isMethod = DC->isRecord() && D.isFunctionDeclarator() && !isTypedef;
  9776. bool isField = DC->isRecord() && !D.isFunctionDeclarator() && !isTypedef;
  9777. bool isConst = D.getDeclSpec().getTypeQualifiers() & DeclSpec::TQ::TQ_const;
  9778. bool isVolatile = D.getDeclSpec().getTypeQualifiers() & DeclSpec::TQ::TQ_volatile;
  9779. bool isStatic = storage == DeclSpec::SCS::SCS_static;
  9780. bool isExtern = storage == DeclSpec::SCS::SCS_extern;
  9781. bool hasSignSpec = D.getDeclSpec().getTypeSpecSign() != DeclSpec::TSS::TSS_unspecified;
  9782. // Function declarations are not allowed in parameter declaration
  9783. // TODO : Remove this check once we support function declarations/pointers in HLSL
  9784. if (isParameter && isFunction) {
  9785. Diag(D.getLocStart(), diag::err_hlsl_func_in_func_decl);
  9786. D.setInvalidType();
  9787. return false;
  9788. }
  9789. assert(
  9790. (1 == (isLocalVar ? 1 : 0) + (isGlobal ? 1 : 0) + (isField ? 1 : 0) +
  9791. (isTypedef ? 1 : 0) + (isFunction ? 1 : 0) + (isMethod ? 1 : 0) +
  9792. (isParameter ? 1 : 0))
  9793. && "exactly one type of declarator is being processed");
  9794. // qt/pType captures either the type being modified, or the return type in the
  9795. // case of a function (or method).
  9796. QualType qt = TInfo->getType();
  9797. const Type* pType = qt.getTypePtrOrNull();
  9798. // Early checks - these are not simple attribution errors, but constructs that
  9799. // are fundamentally unsupported,
  9800. // and so we avoid errors that might indicate they can be repaired.
  9801. if (DC->isRecord()) {
  9802. unsigned int nestedDiagId = 0;
  9803. if (isTypedef) {
  9804. nestedDiagId = diag::err_hlsl_unsupported_nested_typedef;
  9805. }
  9806. if (isField && pType && pType->isIncompleteArrayType()) {
  9807. nestedDiagId = diag::err_hlsl_unsupported_incomplete_array;
  9808. }
  9809. if (nestedDiagId) {
  9810. Diag(D.getLocStart(), nestedDiagId);
  9811. D.setInvalidType();
  9812. return false;
  9813. }
  9814. }
  9815. const char* declarationType =
  9816. (isLocalVar) ? "local variable" :
  9817. (isTypedef) ? "typedef" :
  9818. (isFunction) ? "function" :
  9819. (isMethod) ? "method" :
  9820. (isGlobal) ? "global variable" :
  9821. (isParameter) ? "parameter" :
  9822. (isField) ? "field" : "<unknown>";
  9823. if (pType && D.isFunctionDeclarator()) {
  9824. const FunctionProtoType *pFP = pType->getAs<FunctionProtoType>();
  9825. if (pFP) {
  9826. qt = pFP->getReturnType();
  9827. pType = qt.getTypePtrOrNull();
  9828. }
  9829. }
  9830. // Check for deprecated effect object type here, warn, and invalidate decl
  9831. bool bDeprecatedEffectObject = false;
  9832. bool bIsObject = false;
  9833. if (hlsl::IsObjectType(this, qt, &bDeprecatedEffectObject)) {
  9834. bIsObject = true;
  9835. if (bDeprecatedEffectObject) {
  9836. Diag(D.getLocStart(), diag::warn_hlsl_effect_object);
  9837. D.setInvalidType();
  9838. return false;
  9839. }
  9840. // Add methods if not ready.
  9841. HLSLExternalSource *hlslSource = HLSLExternalSource::FromSema(this);
  9842. hlslSource->AddHLSLObjectMethodsIfNotReady(qt);
  9843. } else if (qt->isArrayType()) {
  9844. QualType eltQt(qt->getArrayElementTypeNoTypeQual(), 0);
  9845. while (eltQt->isArrayType())
  9846. eltQt = QualType(eltQt->getArrayElementTypeNoTypeQual(), 0);
  9847. if (hlsl::IsObjectType(this, eltQt, &bDeprecatedEffectObject)) {
  9848. // Add methods if not ready.
  9849. HLSLExternalSource *hlslSource = HLSLExternalSource::FromSema(this);
  9850. hlslSource->AddHLSLObjectMethodsIfNotReady(eltQt);
  9851. }
  9852. }
  9853. if (isExtern) {
  9854. if (!(isFunction || isGlobal)) {
  9855. Diag(D.getLocStart(), diag::err_hlsl_varmodifierna) << "'extern'"
  9856. << declarationType;
  9857. result = false;
  9858. }
  9859. }
  9860. if (isStatic) {
  9861. if (!(isLocalVar || isGlobal || isFunction || isMethod || isField)) {
  9862. Diag(D.getLocStart(), diag::err_hlsl_varmodifierna) << "'static'"
  9863. << declarationType;
  9864. result = false;
  9865. }
  9866. }
  9867. if (isVolatile) {
  9868. if (!(isLocalVar || isTypedef)) {
  9869. Diag(D.getLocStart(), diag::err_hlsl_varmodifierna) << "'volatile'"
  9870. << declarationType;
  9871. result = false;
  9872. }
  9873. }
  9874. if (isConst) {
  9875. if (isField && !isStatic) {
  9876. Diag(D.getLocStart(), diag::err_hlsl_varmodifierna) << "'const'"
  9877. << declarationType;
  9878. result = false;
  9879. }
  9880. }
  9881. HLSLExternalSource *hlslSource = HLSLExternalSource::FromSema(this);
  9882. ArBasicKind basicKind = hlslSource->GetTypeElementKind(qt);
  9883. if (hasSignSpec) {
  9884. ArTypeObjectKind objKind = hlslSource->GetTypeObjectKind(qt);
  9885. // vectors or matrices can only have unsigned integer types.
  9886. if (objKind == AR_TOBJ_MATRIX || objKind == AR_TOBJ_VECTOR || objKind == AR_TOBJ_BASIC || objKind == AR_TOBJ_ARRAY) {
  9887. if (!IS_BASIC_UNSIGNABLE(basicKind)) {
  9888. Diag(D.getLocStart(), diag::err_sema_invalid_sign_spec)
  9889. << g_ArBasicTypeNames[basicKind];
  9890. result = false;
  9891. }
  9892. }
  9893. else {
  9894. Diag(D.getLocStart(), diag::err_sema_invalid_sign_spec) << g_ArBasicTypeNames[basicKind];
  9895. result = false;
  9896. }
  9897. }
  9898. // Validate attributes
  9899. clang::AttributeList
  9900. *pUniform = nullptr,
  9901. *pUsage = nullptr,
  9902. *pNoInterpolation = nullptr,
  9903. *pLinear = nullptr,
  9904. *pNoPerspective = nullptr,
  9905. *pSample = nullptr,
  9906. *pCentroid = nullptr,
  9907. *pCenter = nullptr,
  9908. *pAnyLinear = nullptr, // first linear attribute found
  9909. *pTopology = nullptr;
  9910. bool usageIn = false;
  9911. bool usageOut = false;
  9912. for (clang::AttributeList *pAttr = D.getDeclSpec().getAttributes().getList();
  9913. pAttr != NULL; pAttr = pAttr->getNext()) {
  9914. if (pAttr->isInvalid() || pAttr->isUsedAsTypeAttr())
  9915. continue;
  9916. switch (pAttr->getKind()) {
  9917. case AttributeList::AT_HLSLPrecise: // precise is applicable everywhere.
  9918. break;
  9919. case AttributeList::AT_HLSLShared:
  9920. if (!isGlobal) {
  9921. Diag(pAttr->getLoc(), diag::err_hlsl_varmodifierna)
  9922. << pAttr->getName() << declarationType << pAttr->getRange();
  9923. result = false;
  9924. }
  9925. if (isStatic) {
  9926. Diag(pAttr->getLoc(), diag::err_hlsl_varmodifiersna)
  9927. << "'static'" << pAttr->getName() << declarationType
  9928. << pAttr->getRange();
  9929. result = false;
  9930. }
  9931. break;
  9932. case AttributeList::AT_HLSLGroupShared:
  9933. if (!isGlobal) {
  9934. Diag(pAttr->getLoc(), diag::err_hlsl_varmodifierna)
  9935. << pAttr->getName() << declarationType << pAttr->getRange();
  9936. result = false;
  9937. }
  9938. if (isExtern) {
  9939. Diag(pAttr->getLoc(), diag::err_hlsl_varmodifiersna)
  9940. << "'extern'" << pAttr->getName() << declarationType
  9941. << pAttr->getRange();
  9942. result = false;
  9943. }
  9944. break;
  9945. case AttributeList::AT_HLSLGloballyCoherent:
  9946. if (!bIsObject) {
  9947. Diag(pAttr->getLoc(), diag::err_hlsl_varmodifierna)
  9948. << pAttr->getName() << "non-UAV type";
  9949. result = false;
  9950. }
  9951. break;
  9952. case AttributeList::AT_HLSLUniform:
  9953. if (!(isGlobal || isParameter)) {
  9954. Diag(pAttr->getLoc(), diag::err_hlsl_varmodifierna)
  9955. << pAttr->getName() << declarationType << pAttr->getRange();
  9956. result = false;
  9957. }
  9958. if (isStatic) {
  9959. Diag(pAttr->getLoc(), diag::err_hlsl_varmodifiersna)
  9960. << "'static'" << pAttr->getName() << declarationType
  9961. << pAttr->getRange();
  9962. result = false;
  9963. }
  9964. pUniform = pAttr;
  9965. break;
  9966. case AttributeList::AT_HLSLIn:
  9967. case AttributeList::AT_HLSLOut:
  9968. case AttributeList::AT_HLSLInOut:
  9969. if (!isParameter) {
  9970. Diag(pAttr->getLoc(), diag::err_hlsl_usage_not_on_parameter)
  9971. << pAttr->getName() << pAttr->getRange();
  9972. result = false;
  9973. }
  9974. if (!IsUsageAttributeCompatible(pAttr->getKind(), usageIn, usageOut)) {
  9975. Diag(pAttr->getLoc(), diag::err_hlsl_duplicate_parameter_usages)
  9976. << pAttr->getName() << pAttr->getRange();
  9977. result = false;
  9978. }
  9979. pUsage = pAttr;
  9980. break;
  9981. case AttributeList::AT_HLSLNoInterpolation:
  9982. if (!(isParameter || isField || isFunction)) {
  9983. Diag(pAttr->getLoc(), diag::err_hlsl_varmodifierna)
  9984. << pAttr->getName() << declarationType << pAttr->getRange();
  9985. result = false;
  9986. }
  9987. if (pNoInterpolation) {
  9988. Diag(pAttr->getLoc(), diag::warn_hlsl_duplicate_specifier)
  9989. << pAttr->getName() << pAttr->getRange();
  9990. }
  9991. pNoInterpolation = pAttr;
  9992. break;
  9993. case AttributeList::AT_HLSLLinear:
  9994. case AttributeList::AT_HLSLCenter:
  9995. case AttributeList::AT_HLSLNoPerspective:
  9996. case AttributeList::AT_HLSLSample:
  9997. case AttributeList::AT_HLSLCentroid:
  9998. if (!(isParameter || isField || isFunction)) {
  9999. Diag(pAttr->getLoc(), diag::err_hlsl_varmodifierna)
  10000. << pAttr->getName() << declarationType << pAttr->getRange();
  10001. result = false;
  10002. }
  10003. if (nullptr == pAnyLinear)
  10004. pAnyLinear = pAttr;
  10005. switch (pAttr->getKind()) {
  10006. case AttributeList::AT_HLSLLinear:
  10007. if (pLinear) {
  10008. Diag(pAttr->getLoc(), diag::warn_hlsl_duplicate_specifier)
  10009. << pAttr->getName() << pAttr->getRange();
  10010. }
  10011. pLinear = pAttr;
  10012. break;
  10013. case AttributeList::AT_HLSLCenter:
  10014. if (pCenter) {
  10015. Diag(pAttr->getLoc(), diag::warn_hlsl_duplicate_specifier)
  10016. << pAttr->getName() << pAttr->getRange();
  10017. }
  10018. pCenter = pAttr;
  10019. break;
  10020. case AttributeList::AT_HLSLNoPerspective:
  10021. if (pNoPerspective) {
  10022. Diag(pAttr->getLoc(), diag::warn_hlsl_duplicate_specifier)
  10023. << pAttr->getName() << pAttr->getRange();
  10024. }
  10025. pNoPerspective = pAttr;
  10026. break;
  10027. case AttributeList::AT_HLSLSample:
  10028. if (pSample) {
  10029. Diag(pAttr->getLoc(), diag::warn_hlsl_duplicate_specifier)
  10030. << pAttr->getName() << pAttr->getRange();
  10031. }
  10032. pSample = pAttr;
  10033. break;
  10034. case AttributeList::AT_HLSLCentroid:
  10035. if (pCentroid) {
  10036. Diag(pAttr->getLoc(), diag::warn_hlsl_duplicate_specifier)
  10037. << pAttr->getName() << pAttr->getRange();
  10038. }
  10039. pCentroid = pAttr;
  10040. break;
  10041. default:
  10042. // Only relevant to the four attribs included in this block.
  10043. break;
  10044. }
  10045. break;
  10046. case AttributeList::AT_HLSLPoint:
  10047. case AttributeList::AT_HLSLLine:
  10048. case AttributeList::AT_HLSLLineAdj:
  10049. case AttributeList::AT_HLSLTriangle:
  10050. case AttributeList::AT_HLSLTriangleAdj:
  10051. if (!(isParameter)) {
  10052. Diag(pAttr->getLoc(), diag::err_hlsl_varmodifierna)
  10053. << pAttr->getName() << declarationType << pAttr->getRange();
  10054. result = false;
  10055. }
  10056. if (pTopology) {
  10057. if (pTopology->getKind() == pAttr->getKind()) {
  10058. Diag(pAttr->getLoc(), diag::warn_hlsl_duplicate_specifier)
  10059. << pAttr->getName() << pAttr->getRange();
  10060. } else {
  10061. Diag(pAttr->getLoc(), diag::err_hlsl_varmodifiersna)
  10062. << pAttr->getName() << pTopology->getName()
  10063. << declarationType << pAttr->getRange();
  10064. result = false;
  10065. }
  10066. }
  10067. pTopology = pAttr;
  10068. break;
  10069. case AttributeList::AT_HLSLExport:
  10070. if (!isFunction) {
  10071. Diag(pAttr->getLoc(), diag::err_hlsl_varmodifierna)
  10072. << pAttr->getName() << declarationType << pAttr->getRange();
  10073. result = false;
  10074. }
  10075. if (isStatic) {
  10076. Diag(pAttr->getLoc(), diag::err_hlsl_varmodifiersna)
  10077. << "'static'" << pAttr->getName() << declarationType
  10078. << pAttr->getRange();
  10079. result = false;
  10080. }
  10081. break;
  10082. default:
  10083. break;
  10084. }
  10085. }
  10086. if (pNoInterpolation && pAnyLinear) {
  10087. Diag(pNoInterpolation->getLoc(), diag::err_hlsl_varmodifiersna)
  10088. << pNoInterpolation->getName() << pAnyLinear->getName()
  10089. << declarationType << pNoInterpolation->getRange();
  10090. result = false;
  10091. }
  10092. if (pSample && pCentroid) {
  10093. Diag(pCentroid->getLoc(), diag::warn_hlsl_specifier_overridden)
  10094. << pCentroid->getName() << pSample->getName() << pCentroid->getRange();
  10095. }
  10096. if (pCenter && pCentroid) {
  10097. Diag(pCenter->getLoc(), diag::warn_hlsl_specifier_overridden)
  10098. << pCenter->getName() << pCentroid->getName() << pCenter->getRange();
  10099. }
  10100. if (pSample && pCenter) {
  10101. Diag(pCenter->getLoc(), diag::warn_hlsl_specifier_overridden)
  10102. << pCenter->getName() << pSample->getName() << pCenter->getRange();
  10103. }
  10104. clang::AttributeList *pNonUniformAttr = pAnyLinear ? pAnyLinear : (
  10105. pNoInterpolation ? pNoInterpolation : pTopology);
  10106. if (pUniform && pNonUniformAttr) {
  10107. Diag(pUniform->getLoc(), diag::err_hlsl_varmodifiersna)
  10108. << pNonUniformAttr->getName()
  10109. << pUniform->getName() << declarationType << pUniform->getRange();
  10110. result = false;
  10111. }
  10112. if (pAnyLinear && pTopology) {
  10113. Diag(pAnyLinear->getLoc(), diag::err_hlsl_varmodifiersna)
  10114. << pTopology->getName()
  10115. << pAnyLinear->getName() << declarationType << pAnyLinear->getRange();
  10116. result = false;
  10117. }
  10118. if (pNoInterpolation && pTopology) {
  10119. Diag(pNoInterpolation->getLoc(), diag::err_hlsl_varmodifiersna)
  10120. << pTopology->getName()
  10121. << pNoInterpolation->getName() << declarationType << pNoInterpolation->getRange();
  10122. result = false;
  10123. }
  10124. if (pUniform && pUsage) {
  10125. if (pUsage->getKind() != AttributeList::Kind::AT_HLSLIn) {
  10126. Diag(pUniform->getLoc(), diag::err_hlsl_varmodifiersna)
  10127. << pUsage->getName() << pUniform->getName() << declarationType
  10128. << pUniform->getRange();
  10129. result = false;
  10130. }
  10131. }
  10132. // Validate that stream-ouput objects are marked as inout
  10133. if (isParameter && !(usageIn && usageOut) &&
  10134. (basicKind == ArBasicKind::AR_OBJECT_LINESTREAM ||
  10135. basicKind == ArBasicKind::AR_OBJECT_POINTSTREAM ||
  10136. basicKind == ArBasicKind::AR_OBJECT_TRIANGLESTREAM)) {
  10137. Diag(D.getLocStart(), diag::err_hlsl_missing_inout_attr);
  10138. result = false;
  10139. }
  10140. // SPIRV change starts
  10141. #ifdef ENABLE_SPIRV_CODEGEN
  10142. // Validate that Vulkan specific feature is only used when targeting SPIR-V
  10143. if (!getLangOpts().SPIRV) {
  10144. if (basicKind == ArBasicKind::AR_OBJECT_VK_SUBPASS_INPUT ||
  10145. basicKind == ArBasicKind::AR_OBJECT_VK_SUBPASS_INPUT_MS) {
  10146. Diag(D.getLocStart(), diag::err_hlsl_vulkan_specific_feature)
  10147. << g_ArBasicTypeNames[basicKind];
  10148. result = false;
  10149. }
  10150. }
  10151. #endif // ENABLE_SPIRV_CODEGEN
  10152. // SPIRV change ends
  10153. // Validate unusual annotations.
  10154. hlsl::DiagnoseUnusualAnnotationsForHLSL(*this, D.UnusualAnnotations);
  10155. auto && unusualIter = D.UnusualAnnotations.begin();
  10156. auto && unusualEnd = D.UnusualAnnotations.end();
  10157. for (; unusualIter != unusualEnd; ++unusualIter) {
  10158. switch ((*unusualIter)->getKind()) {
  10159. case hlsl::UnusualAnnotation::UA_ConstantPacking: {
  10160. hlsl::ConstantPacking *constantPacking =
  10161. cast<hlsl::ConstantPacking>(*unusualIter);
  10162. if (!isGlobal || HLSLBuffers.size() == 0) {
  10163. Diag(constantPacking->Loc, diag::err_hlsl_packoffset_requires_cbuffer);
  10164. continue;
  10165. }
  10166. if (constantPacking->ComponentOffset > 0) {
  10167. // Validate that this will fit.
  10168. if (!qt.isNull()) {
  10169. hlsl::DiagnosePackingOffset(this, constantPacking->Loc, qt,
  10170. constantPacking->ComponentOffset);
  10171. }
  10172. }
  10173. break;
  10174. }
  10175. case hlsl::UnusualAnnotation::UA_RegisterAssignment: {
  10176. hlsl::RegisterAssignment *registerAssignment =
  10177. cast<hlsl::RegisterAssignment>(*unusualIter);
  10178. if (registerAssignment->IsValid) {
  10179. if (!qt.isNull()) {
  10180. hlsl::DiagnoseRegisterType(this, registerAssignment->Loc, qt,
  10181. registerAssignment->RegisterType);
  10182. }
  10183. }
  10184. break;
  10185. }
  10186. case hlsl::UnusualAnnotation::UA_SemanticDecl: {
  10187. hlsl::SemanticDecl *semanticDecl = cast<hlsl::SemanticDecl>(*unusualIter);
  10188. if (isTypedef || isLocalVar) {
  10189. Diag(semanticDecl->Loc, diag::err_hlsl_varmodifierna)
  10190. << "semantic" << declarationType;
  10191. }
  10192. break;
  10193. }
  10194. }
  10195. }
  10196. if (!result) {
  10197. D.setInvalidType();
  10198. }
  10199. return result;
  10200. }
  10201. // Diagnose HLSL types on lookup
  10202. bool Sema::DiagnoseHLSLLookup(const LookupResult &R) {
  10203. const DeclarationNameInfo declName = R.getLookupNameInfo();
  10204. IdentifierInfo* idInfo = declName.getName().getAsIdentifierInfo();
  10205. if (idInfo) {
  10206. StringRef nameIdentifier = idInfo->getName();
  10207. HLSLScalarType parsedType;
  10208. int rowCount, colCount;
  10209. if (TryParseAny(nameIdentifier.data(), nameIdentifier.size(), &parsedType, &rowCount, &colCount, getLangOpts())) {
  10210. HLSLExternalSource *hlslExternalSource = HLSLExternalSource::FromSema(this);
  10211. hlslExternalSource->WarnMinPrecision(parsedType, R.getNameLoc());
  10212. return hlslExternalSource->DiagnoseHLSLScalarType(parsedType, R.getNameLoc());
  10213. }
  10214. }
  10215. return true;
  10216. }
  10217. static QualType getUnderlyingType(QualType Type)
  10218. {
  10219. while (const TypedefType *TD = dyn_cast<TypedefType>(Type))
  10220. {
  10221. if (const TypedefNameDecl* pDecl = TD->getDecl())
  10222. Type = pDecl->getUnderlyingType();
  10223. else
  10224. break;
  10225. }
  10226. return Type;
  10227. }
  10228. /// <summary>Return HLSL AttributedType objects if they exist on type.</summary>
  10229. /// <param name="self">Sema with context.</param>
  10230. /// <param name="type">QualType to inspect.</param>
  10231. /// <param name="ppMatrixOrientation">Set pointer to column_major/row_major AttributedType if supplied.</param>
  10232. /// <param name="ppNorm">Set pointer to snorm/unorm AttributedType if supplied.</param>
  10233. void hlsl::GetHLSLAttributedTypes(
  10234. _In_ clang::Sema* self,
  10235. clang::QualType type,
  10236. _Inout_opt_ const clang::AttributedType** ppMatrixOrientation,
  10237. _Inout_opt_ const clang::AttributedType** ppNorm)
  10238. {
  10239. if (ppMatrixOrientation)
  10240. *ppMatrixOrientation = nullptr;
  10241. if (ppNorm)
  10242. *ppNorm = nullptr;
  10243. // Note: we clear output pointers once set so we can stop searching
  10244. QualType Desugared = getUnderlyingType(type);
  10245. const AttributedType *AT = dyn_cast<AttributedType>(Desugared);
  10246. while (AT && (ppMatrixOrientation || ppNorm)) {
  10247. AttributedType::Kind Kind = AT->getAttrKind();
  10248. if (Kind == AttributedType::attr_hlsl_row_major ||
  10249. Kind == AttributedType::attr_hlsl_column_major)
  10250. {
  10251. if (ppMatrixOrientation)
  10252. {
  10253. *ppMatrixOrientation = AT;
  10254. ppMatrixOrientation = nullptr;
  10255. }
  10256. }
  10257. else if (Kind == AttributedType::attr_hlsl_unorm ||
  10258. Kind == AttributedType::attr_hlsl_snorm)
  10259. {
  10260. if (ppNorm)
  10261. {
  10262. *ppNorm = AT;
  10263. ppNorm = nullptr;
  10264. }
  10265. }
  10266. Desugared = getUnderlyingType(AT->getEquivalentType());
  10267. AT = dyn_cast<AttributedType>(Desugared);
  10268. }
  10269. // Unwrap component type on vector or matrix and check snorm/unorm
  10270. Desugared = getUnderlyingType(hlsl::GetOriginalElementType(self, Desugared));
  10271. AT = dyn_cast<AttributedType>(Desugared);
  10272. while (AT && ppNorm) {
  10273. AttributedType::Kind Kind = AT->getAttrKind();
  10274. if (Kind == AttributedType::attr_hlsl_unorm ||
  10275. Kind == AttributedType::attr_hlsl_snorm)
  10276. {
  10277. *ppNorm = AT;
  10278. ppNorm = nullptr;
  10279. }
  10280. Desugared = getUnderlyingType(AT->getEquivalentType());
  10281. AT = dyn_cast<AttributedType>(Desugared);
  10282. }
  10283. }
  10284. /// <summary>Returns true if QualType is an HLSL Matrix type.</summary>
  10285. /// <param name="self">Sema with context.</param>
  10286. /// <param name="type">QualType to check.</param>
  10287. bool hlsl::IsMatrixType(
  10288. _In_ clang::Sema* self,
  10289. _In_ clang::QualType type)
  10290. {
  10291. return HLSLExternalSource::FromSema(self)->GetTypeObjectKind(type) == AR_TOBJ_MATRIX;
  10292. }
  10293. /// <summary>Returns true if QualType is an HLSL Vector type.</summary>
  10294. /// <param name="self">Sema with context.</param>
  10295. /// <param name="type">QualType to check.</param>
  10296. bool hlsl::IsVectorType(
  10297. _In_ clang::Sema* self,
  10298. _In_ clang::QualType type)
  10299. {
  10300. return HLSLExternalSource::FromSema(self)->GetTypeObjectKind(type) == AR_TOBJ_VECTOR;
  10301. }
  10302. /// <summary>Get element type for an HLSL Matrix or Vector, preserving AttributedType.</summary>
  10303. /// <param name="self">Sema with context.</param>
  10304. /// <param name="type">Matrix or Vector type.</param>
  10305. clang::QualType hlsl::GetOriginalMatrixOrVectorElementType(
  10306. _In_ clang::QualType type)
  10307. {
  10308. // TODO: Determine if this is really the best way to get the matrix/vector specialization
  10309. // without losing the AttributedType on the template parameter
  10310. if (const Type* pType = type.getTypePtrOrNull()) {
  10311. // A non-dependent template specialization type is always "sugar",
  10312. // typically for a RecordType. For example, a class template
  10313. // specialization type of @c vector<int> will refer to a tag type for
  10314. // the instantiation @c std::vector<int, std::allocator<int>>.
  10315. if (const TemplateSpecializationType* pTemplate = pType->getAs<TemplateSpecializationType>()) {
  10316. // If we have enough arguments, pull them from the template directly, rather than doing
  10317. // the extra lookups.
  10318. if (pTemplate->getNumArgs() > 0)
  10319. return pTemplate->getArg(0).getAsType();
  10320. QualType templateRecord = pTemplate->desugar();
  10321. const Type *pTemplateRecordType = templateRecord.getTypePtr();
  10322. if (pTemplateRecordType) {
  10323. const TagType *pTemplateTagType = pTemplateRecordType->getAs<TagType>();
  10324. if (pTemplateTagType) {
  10325. const ClassTemplateSpecializationDecl *specializationDecl =
  10326. dyn_cast_or_null<ClassTemplateSpecializationDecl>(
  10327. pTemplateTagType->getDecl());
  10328. if (specializationDecl) {
  10329. return specializationDecl->getTemplateArgs()[0].getAsType();
  10330. }
  10331. }
  10332. }
  10333. }
  10334. }
  10335. return QualType();
  10336. }
  10337. /// <summary>Get element type, preserving AttributedType, if vector or matrix, otherwise return the type unmodified.</summary>
  10338. /// <param name="self">Sema with context.</param>
  10339. /// <param name="type">Input type.</param>
  10340. clang::QualType hlsl::GetOriginalElementType(
  10341. _In_ clang::Sema* self,
  10342. _In_ clang::QualType type)
  10343. {
  10344. ArTypeObjectKind Kind = HLSLExternalSource::FromSema(self)->GetTypeObjectKind(type);
  10345. if (Kind == AR_TOBJ_MATRIX || Kind == AR_TOBJ_VECTOR) {
  10346. return GetOriginalMatrixOrVectorElementType(type);
  10347. }
  10348. return type;
  10349. }
  10350. void hlsl::CustomPrintHLSLAttr(const clang::Attr *A, llvm::raw_ostream &Out, const clang::PrintingPolicy &Policy, unsigned int Indentation) {
  10351. switch (A->getKind()) {
  10352. // Parameter modifiers
  10353. case clang::attr::HLSLIn:
  10354. Out << "in ";
  10355. break;
  10356. case clang::attr::HLSLInOut:
  10357. Out << "inout ";
  10358. break;
  10359. case clang::attr::HLSLOut:
  10360. Out << "out ";
  10361. break;
  10362. // Interpolation modifiers
  10363. case clang::attr::HLSLLinear:
  10364. Out << "linear ";
  10365. break;
  10366. case clang::attr::HLSLCenter:
  10367. Out << "center ";
  10368. break;
  10369. case clang::attr::HLSLCentroid:
  10370. Out << "centroid ";
  10371. break;
  10372. case clang::attr::HLSLNoInterpolation:
  10373. Out << "nointerpolation ";
  10374. break;
  10375. case clang::attr::HLSLNoPerspective:
  10376. Out << "noperspective ";
  10377. break;
  10378. case clang::attr::HLSLSample:
  10379. Out << "sample ";
  10380. break;
  10381. // Function attributes
  10382. case clang::attr::HLSLClipPlanes:
  10383. {
  10384. Attr * noconst = const_cast<Attr*>(A);
  10385. HLSLClipPlanesAttr *ACast = static_cast<HLSLClipPlanesAttr*>(noconst);
  10386. if (!ACast->getClipPlane1())
  10387. break;
  10388. Indent(Indentation, Out);
  10389. Out << "[clipplanes(";
  10390. ACast->getClipPlane1()->printPretty(Out, 0, Policy);
  10391. PrintClipPlaneIfPresent(ACast->getClipPlane2(), Out, Policy);
  10392. PrintClipPlaneIfPresent(ACast->getClipPlane3(), Out, Policy);
  10393. PrintClipPlaneIfPresent(ACast->getClipPlane4(), Out, Policy);
  10394. PrintClipPlaneIfPresent(ACast->getClipPlane5(), Out, Policy);
  10395. PrintClipPlaneIfPresent(ACast->getClipPlane6(), Out, Policy);
  10396. Out << ")]\n";
  10397. break;
  10398. }
  10399. case clang::attr::HLSLDomain:
  10400. {
  10401. Attr * noconst = const_cast<Attr*>(A);
  10402. HLSLDomainAttr *ACast = static_cast<HLSLDomainAttr*>(noconst);
  10403. Indent(Indentation, Out);
  10404. Out << "[domain(\"" << ACast->getDomainType() << "\")]\n";
  10405. break;
  10406. }
  10407. case clang::attr::HLSLEarlyDepthStencil:
  10408. Indent(Indentation, Out);
  10409. Out << "[earlydepthstencil]\n";
  10410. break;
  10411. case clang::attr::HLSLInstance: //TODO - test
  10412. {
  10413. Attr * noconst = const_cast<Attr*>(A);
  10414. HLSLInstanceAttr *ACast = static_cast<HLSLInstanceAttr*>(noconst);
  10415. Indent(Indentation, Out);
  10416. Out << "[instance(" << ACast->getCount() << ")]\n";
  10417. break;
  10418. }
  10419. case clang::attr::HLSLMaxTessFactor: //TODO - test
  10420. {
  10421. Attr * noconst = const_cast<Attr*>(A);
  10422. HLSLMaxTessFactorAttr *ACast = static_cast<HLSLMaxTessFactorAttr*>(noconst);
  10423. Indent(Indentation, Out);
  10424. Out << "[maxtessfactor(" << ACast->getFactor() << ")]\n";
  10425. break;
  10426. }
  10427. case clang::attr::HLSLNumThreads: //TODO - test
  10428. {
  10429. Attr * noconst = const_cast<Attr*>(A);
  10430. HLSLNumThreadsAttr *ACast = static_cast<HLSLNumThreadsAttr*>(noconst);
  10431. Indent(Indentation, Out);
  10432. Out << "[numthreads(" << ACast->getX() << ", " << ACast->getY() << ", " << ACast->getZ() << ")]\n";
  10433. break;
  10434. }
  10435. case clang::attr::HLSLRootSignature:
  10436. {
  10437. Attr * noconst = const_cast<Attr*>(A);
  10438. HLSLRootSignatureAttr *ACast = static_cast<HLSLRootSignatureAttr*>(noconst);
  10439. Indent(Indentation, Out);
  10440. Out << "[RootSignature(" << ACast->getSignatureName() << ")]\n";
  10441. break;
  10442. }
  10443. case clang::attr::HLSLOutputControlPoints:
  10444. {
  10445. Attr * noconst = const_cast<Attr*>(A);
  10446. HLSLOutputControlPointsAttr *ACast = static_cast<HLSLOutputControlPointsAttr*>(noconst);
  10447. Indent(Indentation, Out);
  10448. Out << "[outputcontrolpoints(" << ACast->getCount() << ")]\n";
  10449. break;
  10450. }
  10451. case clang::attr::HLSLOutputTopology:
  10452. {
  10453. Attr * noconst = const_cast<Attr*>(A);
  10454. HLSLOutputTopologyAttr *ACast = static_cast<HLSLOutputTopologyAttr*>(noconst);
  10455. Indent(Indentation, Out);
  10456. Out << "[outputtopology(\"" << ACast->getTopology() << "\")]\n";
  10457. break;
  10458. }
  10459. case clang::attr::HLSLPartitioning:
  10460. {
  10461. Attr * noconst = const_cast<Attr*>(A);
  10462. HLSLPartitioningAttr *ACast = static_cast<HLSLPartitioningAttr*>(noconst);
  10463. Indent(Indentation, Out);
  10464. Out << "[partitioning(\"" << ACast->getScheme() << "\")]\n";
  10465. break;
  10466. }
  10467. case clang::attr::HLSLPatchConstantFunc:
  10468. {
  10469. Attr * noconst = const_cast<Attr*>(A);
  10470. HLSLPatchConstantFuncAttr *ACast = static_cast<HLSLPatchConstantFuncAttr*>(noconst);
  10471. Indent(Indentation, Out);
  10472. Out << "[patchconstantfunc(\"" << ACast->getFunctionName() << "\")]\n";
  10473. break;
  10474. }
  10475. case clang::attr::HLSLShader:
  10476. {
  10477. Attr * noconst = const_cast<Attr*>(A);
  10478. HLSLShaderAttr *ACast = static_cast<HLSLShaderAttr*>(noconst);
  10479. Indent(Indentation, Out);
  10480. Out << "[shader(\"" << ACast->getStage() << "\")]\n";
  10481. break;
  10482. }
  10483. case clang::attr::HLSLExperimental:
  10484. {
  10485. Attr * noconst = const_cast<Attr*>(A);
  10486. HLSLExperimentalAttr *ACast = static_cast<HLSLExperimentalAttr*>(noconst);
  10487. Indent(Indentation, Out);
  10488. Out << "[experimental(\"" << ACast->getName() << "\", \"" << ACast->getValue() << "\")]\n";
  10489. break;
  10490. }
  10491. case clang::attr::HLSLMaxVertexCount:
  10492. {
  10493. Attr * noconst = const_cast<Attr*>(A);
  10494. HLSLMaxVertexCountAttr *ACast = static_cast<HLSLMaxVertexCountAttr*>(noconst);
  10495. Indent(Indentation, Out);
  10496. Out << "[maxvertexcount(" << ACast->getCount() << ")]\n";
  10497. break;
  10498. }
  10499. case clang::attr::NoInline:
  10500. Indent(Indentation, Out);
  10501. Out << "[noinline]\n";
  10502. break;
  10503. case clang::attr::HLSLExport:
  10504. Indent(Indentation, Out);
  10505. Out << "export\n";
  10506. break;
  10507. // Statement attributes
  10508. case clang::attr::HLSLAllowUAVCondition:
  10509. Indent(Indentation, Out);
  10510. Out << "[allow_uav_condition]\n";
  10511. break;
  10512. case clang::attr::HLSLBranch:
  10513. Indent(Indentation, Out);
  10514. Out << "[branch]\n";
  10515. break;
  10516. case clang::attr::HLSLCall:
  10517. Indent(Indentation, Out);
  10518. Out << "[call]\n";
  10519. break;
  10520. case clang::attr::HLSLFastOpt:
  10521. Indent(Indentation, Out);
  10522. Out << "[fastopt]\n";
  10523. break;
  10524. case clang::attr::HLSLFlatten:
  10525. Indent(Indentation, Out);
  10526. Out << "[flatten]\n";
  10527. break;
  10528. case clang::attr::HLSLForceCase:
  10529. Indent(Indentation, Out);
  10530. Out << "[forcecase]\n";
  10531. break;
  10532. case clang::attr::HLSLLoop:
  10533. Indent(Indentation, Out);
  10534. Out << "[loop]\n";
  10535. break;
  10536. case clang::attr::HLSLUnroll:
  10537. {
  10538. Attr * noconst = const_cast<Attr*>(A);
  10539. HLSLUnrollAttr *ACast = static_cast<HLSLUnrollAttr*>(noconst);
  10540. Indent(Indentation, Out);
  10541. Out << "[unroll(" << ACast->getCount() << ")]\n";
  10542. break;
  10543. }
  10544. // Variable modifiers
  10545. case clang::attr::HLSLGroupShared:
  10546. Out << "groupshared ";
  10547. break;
  10548. case clang::attr::HLSLPrecise:
  10549. Out << "precise ";
  10550. break;
  10551. case clang::attr::HLSLSemantic: // TODO: Consider removing HLSLSemantic attribute
  10552. break;
  10553. case clang::attr::HLSLShared:
  10554. Out << "shared ";
  10555. break;
  10556. case clang::attr::HLSLUniform:
  10557. Out << "uniform ";
  10558. break;
  10559. // These four cases are printed in TypePrinter::printAttributedBefore
  10560. case clang::attr::HLSLColumnMajor:
  10561. case clang::attr::HLSLRowMajor:
  10562. case clang::attr::HLSLSnorm:
  10563. case clang::attr::HLSLUnorm:
  10564. break;
  10565. case clang::attr::HLSLPoint:
  10566. Out << "point ";
  10567. break;
  10568. case clang::attr::HLSLLine:
  10569. Out << "line ";
  10570. break;
  10571. case clang::attr::HLSLLineAdj:
  10572. Out << "lineadj ";
  10573. break;
  10574. case clang::attr::HLSLTriangle:
  10575. Out << "triangle ";
  10576. break;
  10577. case clang::attr::HLSLTriangleAdj:
  10578. Out << "triangleadj ";
  10579. break;
  10580. case clang::attr::HLSLGloballyCoherent:
  10581. Out << "globallycoherent ";
  10582. break;
  10583. default:
  10584. A->printPretty(Out, Policy);
  10585. break;
  10586. }
  10587. }
  10588. bool hlsl::IsHLSLAttr(clang::attr::Kind AttrKind) {
  10589. switch (AttrKind){
  10590. case clang::attr::HLSLAllowUAVCondition:
  10591. case clang::attr::HLSLBranch:
  10592. case clang::attr::HLSLCall:
  10593. case clang::attr::HLSLCentroid:
  10594. case clang::attr::HLSLClipPlanes:
  10595. case clang::attr::HLSLColumnMajor:
  10596. case clang::attr::HLSLDomain:
  10597. case clang::attr::HLSLEarlyDepthStencil:
  10598. case clang::attr::HLSLFastOpt:
  10599. case clang::attr::HLSLFlatten:
  10600. case clang::attr::HLSLForceCase:
  10601. case clang::attr::HLSLGroupShared:
  10602. case clang::attr::HLSLIn:
  10603. case clang::attr::HLSLInOut:
  10604. case clang::attr::HLSLInstance:
  10605. case clang::attr::HLSLLinear:
  10606. case clang::attr::HLSLCenter:
  10607. case clang::attr::HLSLLoop:
  10608. case clang::attr::HLSLMaxTessFactor:
  10609. case clang::attr::HLSLNoInterpolation:
  10610. case clang::attr::HLSLNoPerspective:
  10611. case clang::attr::HLSLNumThreads:
  10612. case clang::attr::HLSLRootSignature:
  10613. case clang::attr::HLSLOut:
  10614. case clang::attr::HLSLOutputControlPoints:
  10615. case clang::attr::HLSLOutputTopology:
  10616. case clang::attr::HLSLPartitioning:
  10617. case clang::attr::HLSLPatchConstantFunc:
  10618. case clang::attr::HLSLMaxVertexCount:
  10619. case clang::attr::HLSLPrecise:
  10620. case clang::attr::HLSLRowMajor:
  10621. case clang::attr::HLSLSample:
  10622. case clang::attr::HLSLSemantic:
  10623. case clang::attr::HLSLShared:
  10624. case clang::attr::HLSLSnorm:
  10625. case clang::attr::HLSLUniform:
  10626. case clang::attr::HLSLUnorm:
  10627. case clang::attr::HLSLUnroll:
  10628. case clang::attr::HLSLPoint:
  10629. case clang::attr::HLSLLine:
  10630. case clang::attr::HLSLLineAdj:
  10631. case clang::attr::HLSLTriangle:
  10632. case clang::attr::HLSLTriangleAdj:
  10633. case clang::attr::HLSLGloballyCoherent:
  10634. case clang::attr::NoInline:
  10635. case clang::attr::HLSLExport:
  10636. case clang::attr::VKBinding:
  10637. case clang::attr::VKBuiltIn:
  10638. case clang::attr::VKConstantId:
  10639. case clang::attr::VKCounterBinding:
  10640. case clang::attr::VKIndex:
  10641. case clang::attr::VKInputAttachmentIndex:
  10642. case clang::attr::VKLocation:
  10643. case clang::attr::VKOffset:
  10644. case clang::attr::VKPushConstant:
  10645. return true;
  10646. default:
  10647. // Only HLSL/VK Attributes return true. Only used for printPretty(), which doesn't support them.
  10648. break;
  10649. }
  10650. return false;
  10651. }
  10652. void hlsl::PrintClipPlaneIfPresent(clang::Expr *ClipPlane, llvm::raw_ostream &Out, const clang::PrintingPolicy &Policy) {
  10653. if (ClipPlane) {
  10654. Out << ", ";
  10655. ClipPlane->printPretty(Out, 0, Policy);
  10656. }
  10657. }
  10658. bool hlsl::IsObjectType(
  10659. _In_ clang::Sema* self,
  10660. _In_ clang::QualType type,
  10661. _Inout_opt_ bool *isDeprecatedEffectObject)
  10662. {
  10663. HLSLExternalSource *pExternalSource = HLSLExternalSource::FromSema(self);
  10664. if (pExternalSource && pExternalSource->GetTypeObjectKind(type) == AR_TOBJ_OBJECT) {
  10665. if (isDeprecatedEffectObject)
  10666. *isDeprecatedEffectObject = pExternalSource->GetTypeElementKind(type) == AR_OBJECT_LEGACY_EFFECT;
  10667. return true;
  10668. }
  10669. if (isDeprecatedEffectObject)
  10670. *isDeprecatedEffectObject = false;
  10671. return false;
  10672. }
  10673. bool hlsl::CanConvert(
  10674. _In_ clang::Sema* self,
  10675. clang::SourceLocation loc,
  10676. _In_ clang::Expr* sourceExpr,
  10677. clang::QualType target,
  10678. bool explicitConversion,
  10679. _Inout_opt_ clang::StandardConversionSequence* standard)
  10680. {
  10681. return HLSLExternalSource::FromSema(self)->CanConvert(loc, sourceExpr, target, explicitConversion, nullptr, standard);
  10682. }
  10683. void hlsl::Indent(unsigned int Indentation, llvm::raw_ostream &Out)
  10684. {
  10685. for (unsigned i = 0; i != Indentation; ++i)
  10686. Out << " ";
  10687. }
  10688. void hlsl::RegisterIntrinsicTable(_In_ clang::ExternalSemaSource* self, _In_ IDxcIntrinsicTable* table)
  10689. {
  10690. DXASSERT_NOMSG(self != nullptr);
  10691. DXASSERT_NOMSG(table != nullptr);
  10692. HLSLExternalSource* source = (HLSLExternalSource*)self;
  10693. source->RegisterIntrinsicTable(table);
  10694. }
  10695. clang::QualType hlsl::CheckVectorConditional(
  10696. _In_ clang::Sema* self,
  10697. _In_ clang::ExprResult &Cond,
  10698. _In_ clang::ExprResult &LHS,
  10699. _In_ clang::ExprResult &RHS,
  10700. _In_ clang::SourceLocation QuestionLoc)
  10701. {
  10702. return HLSLExternalSource::FromSema(self)->CheckVectorConditional(Cond, LHS, RHS, QuestionLoc);
  10703. }
  10704. bool IsTypeNumeric(_In_ clang::Sema* self, _In_ clang::QualType &type) {
  10705. UINT count;
  10706. return HLSLExternalSource::FromSema(self)->IsTypeNumeric(type, &count);
  10707. }
  10708. void Sema::CheckHLSLArrayAccess(const Expr *expr) {
  10709. DXASSERT_NOMSG(isa<CXXOperatorCallExpr>(expr));
  10710. const CXXOperatorCallExpr *OperatorCallExpr = cast<CXXOperatorCallExpr>(expr);
  10711. DXASSERT_NOMSG(OperatorCallExpr->getOperator() == OverloadedOperatorKind::OO_Subscript);
  10712. const Expr *RHS = OperatorCallExpr->getArg(1); // first subscript expression
  10713. llvm::APSInt index;
  10714. if (RHS->EvaluateAsInt(index, Context)) {
  10715. int64_t intIndex = index.getLimitedValue();
  10716. const QualType LHSQualType = OperatorCallExpr->getArg(0)->getType();
  10717. if (IsVectorType(this, LHSQualType)) {
  10718. uint32_t vectorSize = GetHLSLVecSize(LHSQualType);
  10719. // If expression is a double two subscript operator for matrix (e.g x[0][1])
  10720. // we also have to check the first subscript oprator by recursively calling
  10721. // this funciton for the first CXXOperatorCallExpr
  10722. if (isa<CXXOperatorCallExpr>(OperatorCallExpr->getArg(0))) {
  10723. CheckHLSLArrayAccess(cast<CXXOperatorCallExpr>(OperatorCallExpr->getArg(0)));
  10724. }
  10725. if (intIndex < 0 || (uint32_t)intIndex >= vectorSize) {
  10726. Diag(RHS->getExprLoc(),
  10727. diag::err_hlsl_vector_element_index_out_of_bounds)
  10728. << (int)intIndex;
  10729. }
  10730. }
  10731. else if (IsMatrixType(this, LHSQualType)) {
  10732. uint32_t rowCount, colCount;
  10733. GetHLSLMatRowColCount(LHSQualType, rowCount, colCount);
  10734. if (intIndex < 0 || (uint32_t)intIndex >= rowCount) {
  10735. Diag(RHS->getExprLoc(), diag::err_hlsl_matrix_row_index_out_of_bounds)
  10736. << (int)intIndex;
  10737. }
  10738. }
  10739. }
  10740. }
  10741. clang::QualType ApplyTypeSpecSignToParsedType(
  10742. _In_ clang::Sema* self,
  10743. _In_ clang::QualType &type,
  10744. _In_ clang::TypeSpecifierSign TSS,
  10745. _In_ clang::SourceLocation Loc
  10746. )
  10747. {
  10748. return HLSLExternalSource::FromSema(self)->ApplyTypeSpecSignToParsedType(type, TSS, Loc);
  10749. }