123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315 |
- //===- SemaTemplateDeduction.cpp - Template Argument Deduction ------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file implements C++ template argument deduction.
- //
- //===----------------------------------------------------------------------===//
- #include "clang/Sema/TemplateDeduction.h"
- #include "TreeTransform.h"
- #include "TypeLocBuilder.h"
- #include "clang/AST/ASTContext.h"
- #include "clang/AST/ASTLambda.h"
- #include "clang/AST/Decl.h"
- #include "clang/AST/DeclAccessPair.h"
- #include "clang/AST/DeclBase.h"
- #include "clang/AST/DeclCXX.h"
- #include "clang/AST/DeclTemplate.h"
- #include "clang/AST/DeclarationName.h"
- #include "clang/AST/Expr.h"
- #include "clang/AST/ExprCXX.h"
- #include "clang/AST/NestedNameSpecifier.h"
- #include "clang/AST/RecursiveASTVisitor.h"
- #include "clang/AST/TemplateBase.h"
- #include "clang/AST/TemplateName.h"
- #include "clang/AST/Type.h"
- #include "clang/AST/TypeLoc.h"
- #include "clang/AST/UnresolvedSet.h"
- #include "clang/Basic/AddressSpaces.h"
- #include "clang/Basic/ExceptionSpecificationType.h"
- #include "clang/Basic/LLVM.h"
- #include "clang/Basic/LangOptions.h"
- #include "clang/Basic/PartialDiagnostic.h"
- #include "clang/Basic/SourceLocation.h"
- #include "clang/Basic/Specifiers.h"
- #include "clang/Sema/Ownership.h"
- #include "clang/Sema/Sema.h"
- #include "clang/Sema/Template.h"
- #include "llvm/ADT/APInt.h"
- #include "llvm/ADT/APSInt.h"
- #include "llvm/ADT/ArrayRef.h"
- #include "llvm/ADT/DenseMap.h"
- #include "llvm/ADT/FoldingSet.h"
- #include "llvm/ADT/SmallBitVector.h"
- #include "llvm/ADT/SmallPtrSet.h"
- #include "llvm/ADT/SmallVector.h"
- #include "llvm/Support/Casting.h"
- #include "llvm/Support/Compiler.h"
- #include "llvm/Support/ErrorHandling.h"
- #include <algorithm>
- #include <cassert>
- #include <optional>
- #include <tuple>
- #include <type_traits>
- #include <utility>
- namespace clang {
- /// Various flags that control template argument deduction.
- ///
- /// These flags can be bitwise-OR'd together.
- enum TemplateDeductionFlags {
- /// No template argument deduction flags, which indicates the
- /// strictest results for template argument deduction (as used for, e.g.,
- /// matching class template partial specializations).
- TDF_None = 0,
- /// Within template argument deduction from a function call, we are
- /// matching with a parameter type for which the original parameter was
- /// a reference.
- TDF_ParamWithReferenceType = 0x1,
- /// Within template argument deduction from a function call, we
- /// are matching in a case where we ignore cv-qualifiers.
- TDF_IgnoreQualifiers = 0x02,
- /// Within template argument deduction from a function call,
- /// we are matching in a case where we can perform template argument
- /// deduction from a template-id of a derived class of the argument type.
- TDF_DerivedClass = 0x04,
- /// Allow non-dependent types to differ, e.g., when performing
- /// template argument deduction from a function call where conversions
- /// may apply.
- TDF_SkipNonDependent = 0x08,
- /// Whether we are performing template argument deduction for
- /// parameters and arguments in a top-level template argument
- TDF_TopLevelParameterTypeList = 0x10,
- /// Within template argument deduction from overload resolution per
- /// C++ [over.over] allow matching function types that are compatible in
- /// terms of noreturn and default calling convention adjustments, or
- /// similarly matching a declared template specialization against a
- /// possible template, per C++ [temp.deduct.decl]. In either case, permit
- /// deduction where the parameter is a function type that can be converted
- /// to the argument type.
- TDF_AllowCompatibleFunctionType = 0x20,
- /// Within template argument deduction for a conversion function, we are
- /// matching with an argument type for which the original argument was
- /// a reference.
- TDF_ArgWithReferenceType = 0x40,
- };
- }
- using namespace clang;
- using namespace sema;
- /// Compare two APSInts, extending and switching the sign as
- /// necessary to compare their values regardless of underlying type.
- static bool hasSameExtendedValue(llvm::APSInt X, llvm::APSInt Y) {
- if (Y.getBitWidth() > X.getBitWidth())
- X = X.extend(Y.getBitWidth());
- else if (Y.getBitWidth() < X.getBitWidth())
- Y = Y.extend(X.getBitWidth());
- // If there is a signedness mismatch, correct it.
- if (X.isSigned() != Y.isSigned()) {
- // If the signed value is negative, then the values cannot be the same.
- if ((Y.isSigned() && Y.isNegative()) || (X.isSigned() && X.isNegative()))
- return false;
- Y.setIsSigned(true);
- X.setIsSigned(true);
- }
- return X == Y;
- }
- static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch(
- Sema &S, TemplateParameterList *TemplateParams, QualType Param,
- QualType Arg, TemplateDeductionInfo &Info,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced, unsigned TDF,
- bool PartialOrdering = false, bool DeducedFromArrayBound = false);
- static Sema::TemplateDeductionResult
- DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
- ArrayRef<TemplateArgument> Ps,
- ArrayRef<TemplateArgument> As,
- TemplateDeductionInfo &Info,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced,
- bool NumberOfArgumentsMustMatch);
- static void MarkUsedTemplateParameters(ASTContext &Ctx,
- const TemplateArgument &TemplateArg,
- bool OnlyDeduced, unsigned Depth,
- llvm::SmallBitVector &Used);
- static void MarkUsedTemplateParameters(ASTContext &Ctx, QualType T,
- bool OnlyDeduced, unsigned Level,
- llvm::SmallBitVector &Deduced);
- /// If the given expression is of a form that permits the deduction
- /// of a non-type template parameter, return the declaration of that
- /// non-type template parameter.
- static const NonTypeTemplateParmDecl *
- getDeducedParameterFromExpr(const Expr *E, unsigned Depth) {
- // If we are within an alias template, the expression may have undergone
- // any number of parameter substitutions already.
- while (true) {
- if (const auto *IC = dyn_cast<ImplicitCastExpr>(E))
- E = IC->getSubExpr();
- else if (const auto *CE = dyn_cast<ConstantExpr>(E))
- E = CE->getSubExpr();
- else if (const auto *Subst = dyn_cast<SubstNonTypeTemplateParmExpr>(E))
- E = Subst->getReplacement();
- else if (const auto *CCE = dyn_cast<CXXConstructExpr>(E)) {
- // Look through implicit copy construction from an lvalue of the same type.
- if (CCE->getParenOrBraceRange().isValid())
- break;
- // Note, there could be default arguments.
- assert(CCE->getNumArgs() >= 1 && "implicit construct expr should have 1 arg");
- E = CCE->getArg(0);
- } else
- break;
- }
- if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
- if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl()))
- if (NTTP->getDepth() == Depth)
- return NTTP;
- return nullptr;
- }
- static const NonTypeTemplateParmDecl *
- getDeducedParameterFromExpr(TemplateDeductionInfo &Info, Expr *E) {
- return getDeducedParameterFromExpr(E, Info.getDeducedDepth());
- }
- /// Determine whether two declaration pointers refer to the same
- /// declaration.
- static bool isSameDeclaration(Decl *X, Decl *Y) {
- if (NamedDecl *NX = dyn_cast<NamedDecl>(X))
- X = NX->getUnderlyingDecl();
- if (NamedDecl *NY = dyn_cast<NamedDecl>(Y))
- Y = NY->getUnderlyingDecl();
- return X->getCanonicalDecl() == Y->getCanonicalDecl();
- }
- /// Verify that the given, deduced template arguments are compatible.
- ///
- /// \returns The deduced template argument, or a NULL template argument if
- /// the deduced template arguments were incompatible.
- static DeducedTemplateArgument
- checkDeducedTemplateArguments(ASTContext &Context,
- const DeducedTemplateArgument &X,
- const DeducedTemplateArgument &Y) {
- // We have no deduction for one or both of the arguments; they're compatible.
- if (X.isNull())
- return Y;
- if (Y.isNull())
- return X;
- // If we have two non-type template argument values deduced for the same
- // parameter, they must both match the type of the parameter, and thus must
- // match each other's type. As we're only keeping one of them, we must check
- // for that now. The exception is that if either was deduced from an array
- // bound, the type is permitted to differ.
- if (!X.wasDeducedFromArrayBound() && !Y.wasDeducedFromArrayBound()) {
- QualType XType = X.getNonTypeTemplateArgumentType();
- if (!XType.isNull()) {
- QualType YType = Y.getNonTypeTemplateArgumentType();
- if (YType.isNull() || !Context.hasSameType(XType, YType))
- return DeducedTemplateArgument();
- }
- }
- switch (X.getKind()) {
- case TemplateArgument::Null:
- llvm_unreachable("Non-deduced template arguments handled above");
- case TemplateArgument::Type: {
- // If two template type arguments have the same type, they're compatible.
- QualType TX = X.getAsType(), TY = Y.getAsType();
- if (Y.getKind() == TemplateArgument::Type && Context.hasSameType(TX, TY))
- return DeducedTemplateArgument(Context.getCommonSugaredType(TX, TY),
- X.wasDeducedFromArrayBound() ||
- Y.wasDeducedFromArrayBound());
- // If one of the two arguments was deduced from an array bound, the other
- // supersedes it.
- if (X.wasDeducedFromArrayBound() != Y.wasDeducedFromArrayBound())
- return X.wasDeducedFromArrayBound() ? Y : X;
- // The arguments are not compatible.
- return DeducedTemplateArgument();
- }
- case TemplateArgument::Integral:
- // If we deduced a constant in one case and either a dependent expression or
- // declaration in another case, keep the integral constant.
- // If both are integral constants with the same value, keep that value.
- if (Y.getKind() == TemplateArgument::Expression ||
- Y.getKind() == TemplateArgument::Declaration ||
- (Y.getKind() == TemplateArgument::Integral &&
- hasSameExtendedValue(X.getAsIntegral(), Y.getAsIntegral())))
- return X.wasDeducedFromArrayBound() ? Y : X;
- // All other combinations are incompatible.
- return DeducedTemplateArgument();
- case TemplateArgument::Template:
- if (Y.getKind() == TemplateArgument::Template &&
- Context.hasSameTemplateName(X.getAsTemplate(), Y.getAsTemplate()))
- return X;
- // All other combinations are incompatible.
- return DeducedTemplateArgument();
- case TemplateArgument::TemplateExpansion:
- if (Y.getKind() == TemplateArgument::TemplateExpansion &&
- Context.hasSameTemplateName(X.getAsTemplateOrTemplatePattern(),
- Y.getAsTemplateOrTemplatePattern()))
- return X;
- // All other combinations are incompatible.
- return DeducedTemplateArgument();
- case TemplateArgument::Expression: {
- if (Y.getKind() != TemplateArgument::Expression)
- return checkDeducedTemplateArguments(Context, Y, X);
- // Compare the expressions for equality
- llvm::FoldingSetNodeID ID1, ID2;
- X.getAsExpr()->Profile(ID1, Context, true);
- Y.getAsExpr()->Profile(ID2, Context, true);
- if (ID1 == ID2)
- return X.wasDeducedFromArrayBound() ? Y : X;
- // Differing dependent expressions are incompatible.
- return DeducedTemplateArgument();
- }
- case TemplateArgument::Declaration:
- assert(!X.wasDeducedFromArrayBound());
- // If we deduced a declaration and a dependent expression, keep the
- // declaration.
- if (Y.getKind() == TemplateArgument::Expression)
- return X;
- // If we deduced a declaration and an integral constant, keep the
- // integral constant and whichever type did not come from an array
- // bound.
- if (Y.getKind() == TemplateArgument::Integral) {
- if (Y.wasDeducedFromArrayBound())
- return TemplateArgument(Context, Y.getAsIntegral(),
- X.getParamTypeForDecl());
- return Y;
- }
- // If we deduced two declarations, make sure that they refer to the
- // same declaration.
- if (Y.getKind() == TemplateArgument::Declaration &&
- isSameDeclaration(X.getAsDecl(), Y.getAsDecl()))
- return X;
- // All other combinations are incompatible.
- return DeducedTemplateArgument();
- case TemplateArgument::NullPtr:
- // If we deduced a null pointer and a dependent expression, keep the
- // null pointer.
- if (Y.getKind() == TemplateArgument::Expression)
- return TemplateArgument(Context.getCommonSugaredType(
- X.getNullPtrType(), Y.getAsExpr()->getType()),
- true);
- // If we deduced a null pointer and an integral constant, keep the
- // integral constant.
- if (Y.getKind() == TemplateArgument::Integral)
- return Y;
- // If we deduced two null pointers, they are the same.
- if (Y.getKind() == TemplateArgument::NullPtr)
- return TemplateArgument(
- Context.getCommonSugaredType(X.getNullPtrType(), Y.getNullPtrType()),
- true);
- // All other combinations are incompatible.
- return DeducedTemplateArgument();
- case TemplateArgument::Pack: {
- if (Y.getKind() != TemplateArgument::Pack ||
- X.pack_size() != Y.pack_size())
- return DeducedTemplateArgument();
- llvm::SmallVector<TemplateArgument, 8> NewPack;
- for (TemplateArgument::pack_iterator XA = X.pack_begin(),
- XAEnd = X.pack_end(),
- YA = Y.pack_begin();
- XA != XAEnd; ++XA, ++YA) {
- TemplateArgument Merged = checkDeducedTemplateArguments(
- Context, DeducedTemplateArgument(*XA, X.wasDeducedFromArrayBound()),
- DeducedTemplateArgument(*YA, Y.wasDeducedFromArrayBound()));
- if (Merged.isNull() && !(XA->isNull() && YA->isNull()))
- return DeducedTemplateArgument();
- NewPack.push_back(Merged);
- }
- return DeducedTemplateArgument(
- TemplateArgument::CreatePackCopy(Context, NewPack),
- X.wasDeducedFromArrayBound() && Y.wasDeducedFromArrayBound());
- }
- }
- llvm_unreachable("Invalid TemplateArgument Kind!");
- }
- /// Deduce the value of the given non-type template parameter
- /// as the given deduced template argument. All non-type template parameter
- /// deduction is funneled through here.
- static Sema::TemplateDeductionResult DeduceNonTypeTemplateArgument(
- Sema &S, TemplateParameterList *TemplateParams,
- const NonTypeTemplateParmDecl *NTTP, const DeducedTemplateArgument &NewDeduced,
- QualType ValueType, TemplateDeductionInfo &Info,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
- assert(NTTP->getDepth() == Info.getDeducedDepth() &&
- "deducing non-type template argument with wrong depth");
- DeducedTemplateArgument Result = checkDeducedTemplateArguments(
- S.Context, Deduced[NTTP->getIndex()], NewDeduced);
- if (Result.isNull()) {
- Info.Param = const_cast<NonTypeTemplateParmDecl*>(NTTP);
- Info.FirstArg = Deduced[NTTP->getIndex()];
- Info.SecondArg = NewDeduced;
- return Sema::TDK_Inconsistent;
- }
- Deduced[NTTP->getIndex()] = Result;
- if (!S.getLangOpts().CPlusPlus17)
- return Sema::TDK_Success;
- if (NTTP->isExpandedParameterPack())
- // FIXME: We may still need to deduce parts of the type here! But we
- // don't have any way to find which slice of the type to use, and the
- // type stored on the NTTP itself is nonsense. Perhaps the type of an
- // expanded NTTP should be a pack expansion type?
- return Sema::TDK_Success;
- // Get the type of the parameter for deduction. If it's a (dependent) array
- // or function type, we will not have decayed it yet, so do that now.
- QualType ParamType = S.Context.getAdjustedParameterType(NTTP->getType());
- if (auto *Expansion = dyn_cast<PackExpansionType>(ParamType))
- ParamType = Expansion->getPattern();
- // FIXME: It's not clear how deduction of a parameter of reference
- // type from an argument (of non-reference type) should be performed.
- // For now, we just remove reference types from both sides and let
- // the final check for matching types sort out the mess.
- ValueType = ValueType.getNonReferenceType();
- if (ParamType->isReferenceType())
- ParamType = ParamType.getNonReferenceType();
- else
- // Top-level cv-qualifiers are irrelevant for a non-reference type.
- ValueType = ValueType.getUnqualifiedType();
- return DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, ParamType, ValueType, Info, Deduced,
- TDF_SkipNonDependent, /*PartialOrdering=*/false,
- /*ArrayBound=*/NewDeduced.wasDeducedFromArrayBound());
- }
- /// Deduce the value of the given non-type template parameter
- /// from the given integral constant.
- static Sema::TemplateDeductionResult DeduceNonTypeTemplateArgument(
- Sema &S, TemplateParameterList *TemplateParams,
- const NonTypeTemplateParmDecl *NTTP, const llvm::APSInt &Value,
- QualType ValueType, bool DeducedFromArrayBound, TemplateDeductionInfo &Info,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
- return DeduceNonTypeTemplateArgument(
- S, TemplateParams, NTTP,
- DeducedTemplateArgument(S.Context, Value, ValueType,
- DeducedFromArrayBound),
- ValueType, Info, Deduced);
- }
- /// Deduce the value of the given non-type template parameter
- /// from the given null pointer template argument type.
- static Sema::TemplateDeductionResult DeduceNullPtrTemplateArgument(
- Sema &S, TemplateParameterList *TemplateParams,
- const NonTypeTemplateParmDecl *NTTP, QualType NullPtrType,
- TemplateDeductionInfo &Info,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
- Expr *Value = S.ImpCastExprToType(
- new (S.Context) CXXNullPtrLiteralExpr(S.Context.NullPtrTy,
- NTTP->getLocation()),
- NullPtrType,
- NullPtrType->isMemberPointerType() ? CK_NullToMemberPointer
- : CK_NullToPointer)
- .get();
- return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
- DeducedTemplateArgument(Value),
- Value->getType(), Info, Deduced);
- }
- /// Deduce the value of the given non-type template parameter
- /// from the given type- or value-dependent expression.
- ///
- /// \returns true if deduction succeeded, false otherwise.
- static Sema::TemplateDeductionResult DeduceNonTypeTemplateArgument(
- Sema &S, TemplateParameterList *TemplateParams,
- const NonTypeTemplateParmDecl *NTTP, Expr *Value, TemplateDeductionInfo &Info,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
- return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
- DeducedTemplateArgument(Value),
- Value->getType(), Info, Deduced);
- }
- /// Deduce the value of the given non-type template parameter
- /// from the given declaration.
- ///
- /// \returns true if deduction succeeded, false otherwise.
- static Sema::TemplateDeductionResult DeduceNonTypeTemplateArgument(
- Sema &S, TemplateParameterList *TemplateParams,
- const NonTypeTemplateParmDecl *NTTP, ValueDecl *D, QualType T,
- TemplateDeductionInfo &Info,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
- D = D ? cast<ValueDecl>(D->getCanonicalDecl()) : nullptr;
- TemplateArgument New(D, T);
- return DeduceNonTypeTemplateArgument(
- S, TemplateParams, NTTP, DeducedTemplateArgument(New), T, Info, Deduced);
- }
- static Sema::TemplateDeductionResult
- DeduceTemplateArguments(Sema &S,
- TemplateParameterList *TemplateParams,
- TemplateName Param,
- TemplateName Arg,
- TemplateDeductionInfo &Info,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
- TemplateDecl *ParamDecl = Param.getAsTemplateDecl();
- if (!ParamDecl) {
- // The parameter type is dependent and is not a template template parameter,
- // so there is nothing that we can deduce.
- return Sema::TDK_Success;
- }
- if (TemplateTemplateParmDecl *TempParam
- = dyn_cast<TemplateTemplateParmDecl>(ParamDecl)) {
- // If we're not deducing at this depth, there's nothing to deduce.
- if (TempParam->getDepth() != Info.getDeducedDepth())
- return Sema::TDK_Success;
- DeducedTemplateArgument NewDeduced(S.Context.getCanonicalTemplateName(Arg));
- DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context,
- Deduced[TempParam->getIndex()],
- NewDeduced);
- if (Result.isNull()) {
- Info.Param = TempParam;
- Info.FirstArg = Deduced[TempParam->getIndex()];
- Info.SecondArg = NewDeduced;
- return Sema::TDK_Inconsistent;
- }
- Deduced[TempParam->getIndex()] = Result;
- return Sema::TDK_Success;
- }
- // Verify that the two template names are equivalent.
- if (S.Context.hasSameTemplateName(Param, Arg))
- return Sema::TDK_Success;
- // Mismatch of non-dependent template parameter to argument.
- Info.FirstArg = TemplateArgument(Param);
- Info.SecondArg = TemplateArgument(Arg);
- return Sema::TDK_NonDeducedMismatch;
- }
- /// Deduce the template arguments by comparing the template parameter
- /// type (which is a template-id) with the template argument type.
- ///
- /// \param S the Sema
- ///
- /// \param TemplateParams the template parameters that we are deducing
- ///
- /// \param P the parameter type
- ///
- /// \param A the argument type
- ///
- /// \param Info information about the template argument deduction itself
- ///
- /// \param Deduced the deduced template arguments
- ///
- /// \returns the result of template argument deduction so far. Note that a
- /// "success" result means that template argument deduction has not yet failed,
- /// but it may still fail, later, for other reasons.
- static Sema::TemplateDeductionResult
- DeduceTemplateSpecArguments(Sema &S, TemplateParameterList *TemplateParams,
- const QualType P, QualType A,
- TemplateDeductionInfo &Info,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
- QualType UP = P;
- if (const auto *IP = P->getAs<InjectedClassNameType>())
- UP = IP->getInjectedSpecializationType();
- // FIXME: Try to preserve type sugar here, which is hard
- // because of the unresolved template arguments.
- const auto *TP = UP.getCanonicalType()->castAs<TemplateSpecializationType>();
- TemplateName TNP = TP->getTemplateName();
- // If the parameter is an alias template, there is nothing to deduce.
- if (const auto *TD = TNP.getAsTemplateDecl(); TD && TD->isTypeAlias())
- return Sema::TDK_Success;
- ArrayRef<TemplateArgument> PResolved = TP->template_arguments();
- QualType UA = A;
- // Treat an injected-class-name as its underlying template-id.
- if (const auto *Injected = A->getAs<InjectedClassNameType>())
- UA = Injected->getInjectedSpecializationType();
- // Check whether the template argument is a dependent template-id.
- // FIXME: Should not lose sugar here.
- if (const auto *SA =
- dyn_cast<TemplateSpecializationType>(UA.getCanonicalType())) {
- TemplateName TNA = SA->getTemplateName();
- // If the argument is an alias template, there is nothing to deduce.
- if (const auto *TD = TNA.getAsTemplateDecl(); TD && TD->isTypeAlias())
- return Sema::TDK_Success;
- // Perform template argument deduction for the template name.
- if (auto Result =
- DeduceTemplateArguments(S, TemplateParams, TNP, TNA, Info, Deduced))
- return Result;
- // Perform template argument deduction on each template
- // argument. Ignore any missing/extra arguments, since they could be
- // filled in by default arguments.
- return DeduceTemplateArguments(S, TemplateParams, PResolved,
- SA->template_arguments(), Info, Deduced,
- /*NumberOfArgumentsMustMatch=*/false);
- }
- // If the argument type is a class template specialization, we
- // perform template argument deduction using its template
- // arguments.
- const auto *RA = UA->getAs<RecordType>();
- const auto *SA =
- RA ? dyn_cast<ClassTemplateSpecializationDecl>(RA->getDecl()) : nullptr;
- if (!SA) {
- Info.FirstArg = TemplateArgument(P);
- Info.SecondArg = TemplateArgument(A);
- return Sema::TDK_NonDeducedMismatch;
- }
- // Perform template argument deduction for the template name.
- if (auto Result = DeduceTemplateArguments(
- S, TemplateParams, TP->getTemplateName(),
- TemplateName(SA->getSpecializedTemplate()), Info, Deduced))
- return Result;
- // Perform template argument deduction for the template arguments.
- return DeduceTemplateArguments(S, TemplateParams, PResolved,
- SA->getTemplateArgs().asArray(), Info, Deduced,
- /*NumberOfArgumentsMustMatch=*/true);
- }
- static bool IsPossiblyOpaquelyQualifiedTypeInternal(const Type *T) {
- assert(T->isCanonicalUnqualified());
- switch (T->getTypeClass()) {
- case Type::TypeOfExpr:
- case Type::TypeOf:
- case Type::DependentName:
- case Type::Decltype:
- case Type::UnresolvedUsing:
- case Type::TemplateTypeParm:
- return true;
- case Type::ConstantArray:
- case Type::IncompleteArray:
- case Type::VariableArray:
- case Type::DependentSizedArray:
- return IsPossiblyOpaquelyQualifiedTypeInternal(
- cast<ArrayType>(T)->getElementType().getTypePtr());
- default:
- return false;
- }
- }
- /// Determines whether the given type is an opaque type that
- /// might be more qualified when instantiated.
- static bool IsPossiblyOpaquelyQualifiedType(QualType T) {
- return IsPossiblyOpaquelyQualifiedTypeInternal(
- T->getCanonicalTypeInternal().getTypePtr());
- }
- /// Helper function to build a TemplateParameter when we don't
- /// know its type statically.
- static TemplateParameter makeTemplateParameter(Decl *D) {
- if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(D))
- return TemplateParameter(TTP);
- if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D))
- return TemplateParameter(NTTP);
- return TemplateParameter(cast<TemplateTemplateParmDecl>(D));
- }
- /// A pack that we're currently deducing.
- struct clang::DeducedPack {
- // The index of the pack.
- unsigned Index;
- // The old value of the pack before we started deducing it.
- DeducedTemplateArgument Saved;
- // A deferred value of this pack from an inner deduction, that couldn't be
- // deduced because this deduction hadn't happened yet.
- DeducedTemplateArgument DeferredDeduction;
- // The new value of the pack.
- SmallVector<DeducedTemplateArgument, 4> New;
- // The outer deduction for this pack, if any.
- DeducedPack *Outer = nullptr;
- DeducedPack(unsigned Index) : Index(Index) {}
- };
- namespace {
- /// A scope in which we're performing pack deduction.
- class PackDeductionScope {
- public:
- /// Prepare to deduce the packs named within Pattern.
- PackDeductionScope(Sema &S, TemplateParameterList *TemplateParams,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced,
- TemplateDeductionInfo &Info, TemplateArgument Pattern)
- : S(S), TemplateParams(TemplateParams), Deduced(Deduced), Info(Info) {
- unsigned NumNamedPacks = addPacks(Pattern);
- finishConstruction(NumNamedPacks);
- }
- /// Prepare to directly deduce arguments of the parameter with index \p Index.
- PackDeductionScope(Sema &S, TemplateParameterList *TemplateParams,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced,
- TemplateDeductionInfo &Info, unsigned Index)
- : S(S), TemplateParams(TemplateParams), Deduced(Deduced), Info(Info) {
- addPack(Index);
- finishConstruction(1);
- }
- private:
- void addPack(unsigned Index) {
- // Save the deduced template argument for the parameter pack expanded
- // by this pack expansion, then clear out the deduction.
- DeducedPack Pack(Index);
- Pack.Saved = Deduced[Index];
- Deduced[Index] = TemplateArgument();
- // FIXME: What if we encounter multiple packs with different numbers of
- // pre-expanded expansions? (This should already have been diagnosed
- // during substitution.)
- if (std::optional<unsigned> ExpandedPackExpansions =
- getExpandedPackSize(TemplateParams->getParam(Index)))
- FixedNumExpansions = ExpandedPackExpansions;
- Packs.push_back(Pack);
- }
- unsigned addPacks(TemplateArgument Pattern) {
- // Compute the set of template parameter indices that correspond to
- // parameter packs expanded by the pack expansion.
- llvm::SmallBitVector SawIndices(TemplateParams->size());
- llvm::SmallVector<TemplateArgument, 4> ExtraDeductions;
- auto AddPack = [&](unsigned Index) {
- if (SawIndices[Index])
- return;
- SawIndices[Index] = true;
- addPack(Index);
- // Deducing a parameter pack that is a pack expansion also constrains the
- // packs appearing in that parameter to have the same deduced arity. Also,
- // in C++17 onwards, deducing a non-type template parameter deduces its
- // type, so we need to collect the pending deduced values for those packs.
- if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(
- TemplateParams->getParam(Index))) {
- if (!NTTP->isExpandedParameterPack())
- if (auto *Expansion = dyn_cast<PackExpansionType>(NTTP->getType()))
- ExtraDeductions.push_back(Expansion->getPattern());
- }
- // FIXME: Also collect the unexpanded packs in any type and template
- // parameter packs that are pack expansions.
- };
- auto Collect = [&](TemplateArgument Pattern) {
- SmallVector<UnexpandedParameterPack, 2> Unexpanded;
- S.collectUnexpandedParameterPacks(Pattern, Unexpanded);
- for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
- unsigned Depth, Index;
- std::tie(Depth, Index) = getDepthAndIndex(Unexpanded[I]);
- if (Depth == Info.getDeducedDepth())
- AddPack(Index);
- }
- };
- // Look for unexpanded packs in the pattern.
- Collect(Pattern);
- assert(!Packs.empty() && "Pack expansion without unexpanded packs?");
- unsigned NumNamedPacks = Packs.size();
- // Also look for unexpanded packs that are indirectly deduced by deducing
- // the sizes of the packs in this pattern.
- while (!ExtraDeductions.empty())
- Collect(ExtraDeductions.pop_back_val());
- return NumNamedPacks;
- }
- void finishConstruction(unsigned NumNamedPacks) {
- // Dig out the partially-substituted pack, if there is one.
- const TemplateArgument *PartialPackArgs = nullptr;
- unsigned NumPartialPackArgs = 0;
- std::pair<unsigned, unsigned> PartialPackDepthIndex(-1u, -1u);
- if (auto *Scope = S.CurrentInstantiationScope)
- if (auto *Partial = Scope->getPartiallySubstitutedPack(
- &PartialPackArgs, &NumPartialPackArgs))
- PartialPackDepthIndex = getDepthAndIndex(Partial);
- // This pack expansion will have been partially or fully expanded if
- // it only names explicitly-specified parameter packs (including the
- // partially-substituted one, if any).
- bool IsExpanded = true;
- for (unsigned I = 0; I != NumNamedPacks; ++I) {
- if (Packs[I].Index >= Info.getNumExplicitArgs()) {
- IsExpanded = false;
- IsPartiallyExpanded = false;
- break;
- }
- if (PartialPackDepthIndex ==
- std::make_pair(Info.getDeducedDepth(), Packs[I].Index)) {
- IsPartiallyExpanded = true;
- }
- }
- // Skip over the pack elements that were expanded into separate arguments.
- // If we partially expanded, this is the number of partial arguments.
- if (IsPartiallyExpanded)
- PackElements += NumPartialPackArgs;
- else if (IsExpanded)
- PackElements += *FixedNumExpansions;
- for (auto &Pack : Packs) {
- if (Info.PendingDeducedPacks.size() > Pack.Index)
- Pack.Outer = Info.PendingDeducedPacks[Pack.Index];
- else
- Info.PendingDeducedPacks.resize(Pack.Index + 1);
- Info.PendingDeducedPacks[Pack.Index] = &Pack;
- if (PartialPackDepthIndex ==
- std::make_pair(Info.getDeducedDepth(), Pack.Index)) {
- Pack.New.append(PartialPackArgs, PartialPackArgs + NumPartialPackArgs);
- // We pre-populate the deduced value of the partially-substituted
- // pack with the specified value. This is not entirely correct: the
- // value is supposed to have been substituted, not deduced, but the
- // cases where this is observable require an exact type match anyway.
- //
- // FIXME: If we could represent a "depth i, index j, pack elem k"
- // parameter, we could substitute the partially-substituted pack
- // everywhere and avoid this.
- if (!IsPartiallyExpanded)
- Deduced[Pack.Index] = Pack.New[PackElements];
- }
- }
- }
- public:
- ~PackDeductionScope() {
- for (auto &Pack : Packs)
- Info.PendingDeducedPacks[Pack.Index] = Pack.Outer;
- }
- /// Determine whether this pack has already been partially expanded into a
- /// sequence of (prior) function parameters / template arguments.
- bool isPartiallyExpanded() { return IsPartiallyExpanded; }
- /// Determine whether this pack expansion scope has a known, fixed arity.
- /// This happens if it involves a pack from an outer template that has
- /// (notionally) already been expanded.
- bool hasFixedArity() { return FixedNumExpansions.has_value(); }
- /// Determine whether the next element of the argument is still part of this
- /// pack. This is the case unless the pack is already expanded to a fixed
- /// length.
- bool hasNextElement() {
- return !FixedNumExpansions || *FixedNumExpansions > PackElements;
- }
- /// Move to deducing the next element in each pack that is being deduced.
- void nextPackElement() {
- // Capture the deduced template arguments for each parameter pack expanded
- // by this pack expansion, add them to the list of arguments we've deduced
- // for that pack, then clear out the deduced argument.
- for (auto &Pack : Packs) {
- DeducedTemplateArgument &DeducedArg = Deduced[Pack.Index];
- if (!Pack.New.empty() || !DeducedArg.isNull()) {
- while (Pack.New.size() < PackElements)
- Pack.New.push_back(DeducedTemplateArgument());
- if (Pack.New.size() == PackElements)
- Pack.New.push_back(DeducedArg);
- else
- Pack.New[PackElements] = DeducedArg;
- DeducedArg = Pack.New.size() > PackElements + 1
- ? Pack.New[PackElements + 1]
- : DeducedTemplateArgument();
- }
- }
- ++PackElements;
- }
- /// Finish template argument deduction for a set of argument packs,
- /// producing the argument packs and checking for consistency with prior
- /// deductions.
- Sema::TemplateDeductionResult finish() {
- // Build argument packs for each of the parameter packs expanded by this
- // pack expansion.
- for (auto &Pack : Packs) {
- // Put back the old value for this pack.
- Deduced[Pack.Index] = Pack.Saved;
- // Always make sure the size of this pack is correct, even if we didn't
- // deduce any values for it.
- //
- // FIXME: This isn't required by the normative wording, but substitution
- // and post-substitution checking will always fail if the arity of any
- // pack is not equal to the number of elements we processed. (Either that
- // or something else has gone *very* wrong.) We're permitted to skip any
- // hard errors from those follow-on steps by the intent (but not the
- // wording) of C++ [temp.inst]p8:
- //
- // If the function selected by overload resolution can be determined
- // without instantiating a class template definition, it is unspecified
- // whether that instantiation actually takes place
- Pack.New.resize(PackElements);
- // Build or find a new value for this pack.
- DeducedTemplateArgument NewPack;
- if (Pack.New.empty()) {
- // If we deduced an empty argument pack, create it now.
- NewPack = DeducedTemplateArgument(TemplateArgument::getEmptyPack());
- } else {
- TemplateArgument *ArgumentPack =
- new (S.Context) TemplateArgument[Pack.New.size()];
- std::copy(Pack.New.begin(), Pack.New.end(), ArgumentPack);
- NewPack = DeducedTemplateArgument(
- TemplateArgument(llvm::ArrayRef(ArgumentPack, Pack.New.size())),
- // FIXME: This is wrong, it's possible that some pack elements are
- // deduced from an array bound and others are not:
- // template<typename ...T, T ...V> void g(const T (&...p)[V]);
- // g({1, 2, 3}, {{}, {}});
- // ... should deduce T = {int, size_t (from array bound)}.
- Pack.New[0].wasDeducedFromArrayBound());
- }
- // Pick where we're going to put the merged pack.
- DeducedTemplateArgument *Loc;
- if (Pack.Outer) {
- if (Pack.Outer->DeferredDeduction.isNull()) {
- // Defer checking this pack until we have a complete pack to compare
- // it against.
- Pack.Outer->DeferredDeduction = NewPack;
- continue;
- }
- Loc = &Pack.Outer->DeferredDeduction;
- } else {
- Loc = &Deduced[Pack.Index];
- }
- // Check the new pack matches any previous value.
- DeducedTemplateArgument OldPack = *Loc;
- DeducedTemplateArgument Result =
- checkDeducedTemplateArguments(S.Context, OldPack, NewPack);
- // If we deferred a deduction of this pack, check that one now too.
- if (!Result.isNull() && !Pack.DeferredDeduction.isNull()) {
- OldPack = Result;
- NewPack = Pack.DeferredDeduction;
- Result = checkDeducedTemplateArguments(S.Context, OldPack, NewPack);
- }
- NamedDecl *Param = TemplateParams->getParam(Pack.Index);
- if (Result.isNull()) {
- Info.Param = makeTemplateParameter(Param);
- Info.FirstArg = OldPack;
- Info.SecondArg = NewPack;
- return Sema::TDK_Inconsistent;
- }
- // If we have a pre-expanded pack and we didn't deduce enough elements
- // for it, fail deduction.
- if (std::optional<unsigned> Expansions = getExpandedPackSize(Param)) {
- if (*Expansions != PackElements) {
- Info.Param = makeTemplateParameter(Param);
- Info.FirstArg = Result;
- return Sema::TDK_IncompletePack;
- }
- }
- *Loc = Result;
- }
- return Sema::TDK_Success;
- }
- private:
- Sema &S;
- TemplateParameterList *TemplateParams;
- SmallVectorImpl<DeducedTemplateArgument> &Deduced;
- TemplateDeductionInfo &Info;
- unsigned PackElements = 0;
- bool IsPartiallyExpanded = false;
- /// The number of expansions, if we have a fully-expanded pack in this scope.
- std::optional<unsigned> FixedNumExpansions;
- SmallVector<DeducedPack, 2> Packs;
- };
- } // namespace
- /// Deduce the template arguments by comparing the list of parameter
- /// types to the list of argument types, as in the parameter-type-lists of
- /// function types (C++ [temp.deduct.type]p10).
- ///
- /// \param S The semantic analysis object within which we are deducing
- ///
- /// \param TemplateParams The template parameters that we are deducing
- ///
- /// \param Params The list of parameter types
- ///
- /// \param NumParams The number of types in \c Params
- ///
- /// \param Args The list of argument types
- ///
- /// \param NumArgs The number of types in \c Args
- ///
- /// \param Info information about the template argument deduction itself
- ///
- /// \param Deduced the deduced template arguments
- ///
- /// \param TDF bitwise OR of the TemplateDeductionFlags bits that describe
- /// how template argument deduction is performed.
- ///
- /// \param PartialOrdering If true, we are performing template argument
- /// deduction for during partial ordering for a call
- /// (C++0x [temp.deduct.partial]).
- ///
- /// \returns the result of template argument deduction so far. Note that a
- /// "success" result means that template argument deduction has not yet failed,
- /// but it may still fail, later, for other reasons.
- static Sema::TemplateDeductionResult
- DeduceTemplateArguments(Sema &S,
- TemplateParameterList *TemplateParams,
- const QualType *Params, unsigned NumParams,
- const QualType *Args, unsigned NumArgs,
- TemplateDeductionInfo &Info,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced,
- unsigned TDF,
- bool PartialOrdering = false) {
- // C++0x [temp.deduct.type]p10:
- // Similarly, if P has a form that contains (T), then each parameter type
- // Pi of the respective parameter-type- list of P is compared with the
- // corresponding parameter type Ai of the corresponding parameter-type-list
- // of A. [...]
- unsigned ArgIdx = 0, ParamIdx = 0;
- for (; ParamIdx != NumParams; ++ParamIdx) {
- // Check argument types.
- const PackExpansionType *Expansion
- = dyn_cast<PackExpansionType>(Params[ParamIdx]);
- if (!Expansion) {
- // Simple case: compare the parameter and argument types at this point.
- // Make sure we have an argument.
- if (ArgIdx >= NumArgs)
- return Sema::TDK_MiscellaneousDeductionFailure;
- if (isa<PackExpansionType>(Args[ArgIdx])) {
- // C++0x [temp.deduct.type]p22:
- // If the original function parameter associated with A is a function
- // parameter pack and the function parameter associated with P is not
- // a function parameter pack, then template argument deduction fails.
- return Sema::TDK_MiscellaneousDeductionFailure;
- }
- if (Sema::TemplateDeductionResult Result =
- DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, Params[ParamIdx].getUnqualifiedType(),
- Args[ArgIdx].getUnqualifiedType(), Info, Deduced, TDF,
- PartialOrdering,
- /*DeducedFromArrayBound=*/false))
- return Result;
- ++ArgIdx;
- continue;
- }
- // C++0x [temp.deduct.type]p10:
- // If the parameter-declaration corresponding to Pi is a function
- // parameter pack, then the type of its declarator- id is compared with
- // each remaining parameter type in the parameter-type-list of A. Each
- // comparison deduces template arguments for subsequent positions in the
- // template parameter packs expanded by the function parameter pack.
- QualType Pattern = Expansion->getPattern();
- PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern);
- // A pack scope with fixed arity is not really a pack any more, so is not
- // a non-deduced context.
- if (ParamIdx + 1 == NumParams || PackScope.hasFixedArity()) {
- for (; ArgIdx < NumArgs && PackScope.hasNextElement(); ++ArgIdx) {
- // Deduce template arguments from the pattern.
- if (Sema::TemplateDeductionResult Result =
- DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, Pattern.getUnqualifiedType(),
- Args[ArgIdx].getUnqualifiedType(), Info, Deduced, TDF,
- PartialOrdering, /*DeducedFromArrayBound=*/false))
- return Result;
- PackScope.nextPackElement();
- }
- } else {
- // C++0x [temp.deduct.type]p5:
- // The non-deduced contexts are:
- // - A function parameter pack that does not occur at the end of the
- // parameter-declaration-clause.
- //
- // FIXME: There is no wording to say what we should do in this case. We
- // choose to resolve this by applying the same rule that is applied for a
- // function call: that is, deduce all contained packs to their
- // explicitly-specified values (or to <> if there is no such value).
- //
- // This is seemingly-arbitrarily different from the case of a template-id
- // with a non-trailing pack-expansion in its arguments, which renders the
- // entire template-argument-list a non-deduced context.
- // If the parameter type contains an explicitly-specified pack that we
- // could not expand, skip the number of parameters notionally created
- // by the expansion.
- std::optional<unsigned> NumExpansions = Expansion->getNumExpansions();
- if (NumExpansions && !PackScope.isPartiallyExpanded()) {
- for (unsigned I = 0; I != *NumExpansions && ArgIdx < NumArgs;
- ++I, ++ArgIdx)
- PackScope.nextPackElement();
- }
- }
- // Build argument packs for each of the parameter packs expanded by this
- // pack expansion.
- if (auto Result = PackScope.finish())
- return Result;
- }
- // DR692, DR1395
- // C++0x [temp.deduct.type]p10:
- // If the parameter-declaration corresponding to P_i ...
- // During partial ordering, if Ai was originally a function parameter pack:
- // - if P does not contain a function parameter type corresponding to Ai then
- // Ai is ignored;
- if (PartialOrdering && ArgIdx + 1 == NumArgs &&
- isa<PackExpansionType>(Args[ArgIdx]))
- return Sema::TDK_Success;
- // Make sure we don't have any extra arguments.
- if (ArgIdx < NumArgs)
- return Sema::TDK_MiscellaneousDeductionFailure;
- return Sema::TDK_Success;
- }
- /// Determine whether the parameter has qualifiers that the argument
- /// lacks. Put another way, determine whether there is no way to add
- /// a deduced set of qualifiers to the ParamType that would result in
- /// its qualifiers matching those of the ArgType.
- static bool hasInconsistentOrSupersetQualifiersOf(QualType ParamType,
- QualType ArgType) {
- Qualifiers ParamQs = ParamType.getQualifiers();
- Qualifiers ArgQs = ArgType.getQualifiers();
- if (ParamQs == ArgQs)
- return false;
- // Mismatched (but not missing) Objective-C GC attributes.
- if (ParamQs.getObjCGCAttr() != ArgQs.getObjCGCAttr() &&
- ParamQs.hasObjCGCAttr())
- return true;
- // Mismatched (but not missing) address spaces.
- if (ParamQs.getAddressSpace() != ArgQs.getAddressSpace() &&
- ParamQs.hasAddressSpace())
- return true;
- // Mismatched (but not missing) Objective-C lifetime qualifiers.
- if (ParamQs.getObjCLifetime() != ArgQs.getObjCLifetime() &&
- ParamQs.hasObjCLifetime())
- return true;
- // CVR qualifiers inconsistent or a superset.
- return (ParamQs.getCVRQualifiers() & ~ArgQs.getCVRQualifiers()) != 0;
- }
- /// Compare types for equality with respect to possibly compatible
- /// function types (noreturn adjustment, implicit calling conventions). If any
- /// of parameter and argument is not a function, just perform type comparison.
- ///
- /// \param P the template parameter type.
- ///
- /// \param A the argument type.
- bool Sema::isSameOrCompatibleFunctionType(QualType P, QualType A) {
- const FunctionType *PF = P->getAs<FunctionType>(),
- *AF = A->getAs<FunctionType>();
- // Just compare if not functions.
- if (!PF || !AF)
- return Context.hasSameType(P, A);
- // Noreturn and noexcept adjustment.
- QualType AdjustedParam;
- if (IsFunctionConversion(P, A, AdjustedParam))
- return Context.hasSameType(AdjustedParam, A);
- // FIXME: Compatible calling conventions.
- return Context.hasSameType(P, A);
- }
- /// Get the index of the first template parameter that was originally from the
- /// innermost template-parameter-list. This is 0 except when we concatenate
- /// the template parameter lists of a class template and a constructor template
- /// when forming an implicit deduction guide.
- static unsigned getFirstInnerIndex(FunctionTemplateDecl *FTD) {
- auto *Guide = dyn_cast<CXXDeductionGuideDecl>(FTD->getTemplatedDecl());
- if (!Guide || !Guide->isImplicit())
- return 0;
- return Guide->getDeducedTemplate()->getTemplateParameters()->size();
- }
- /// Determine whether a type denotes a forwarding reference.
- static bool isForwardingReference(QualType Param, unsigned FirstInnerIndex) {
- // C++1z [temp.deduct.call]p3:
- // A forwarding reference is an rvalue reference to a cv-unqualified
- // template parameter that does not represent a template parameter of a
- // class template.
- if (auto *ParamRef = Param->getAs<RValueReferenceType>()) {
- if (ParamRef->getPointeeType().getQualifiers())
- return false;
- auto *TypeParm = ParamRef->getPointeeType()->getAs<TemplateTypeParmType>();
- return TypeParm && TypeParm->getIndex() >= FirstInnerIndex;
- }
- return false;
- }
- static CXXRecordDecl *getCanonicalRD(QualType T) {
- return cast<CXXRecordDecl>(
- T->castAs<RecordType>()->getDecl()->getCanonicalDecl());
- }
- /// Attempt to deduce the template arguments by checking the base types
- /// according to (C++20 [temp.deduct.call] p4b3.
- ///
- /// \param S the semantic analysis object within which we are deducing.
- ///
- /// \param RD the top level record object we are deducing against.
- ///
- /// \param TemplateParams the template parameters that we are deducing.
- ///
- /// \param P the template specialization parameter type.
- ///
- /// \param Info information about the template argument deduction itself.
- ///
- /// \param Deduced the deduced template arguments.
- ///
- /// \returns the result of template argument deduction with the bases. "invalid"
- /// means no matches, "success" found a single item, and the
- /// "MiscellaneousDeductionFailure" result happens when the match is ambiguous.
- static Sema::TemplateDeductionResult
- DeduceTemplateBases(Sema &S, const CXXRecordDecl *RD,
- TemplateParameterList *TemplateParams, QualType P,
- TemplateDeductionInfo &Info,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
- // C++14 [temp.deduct.call] p4b3:
- // If P is a class and P has the form simple-template-id, then the
- // transformed A can be a derived class of the deduced A. Likewise if
- // P is a pointer to a class of the form simple-template-id, the
- // transformed A can be a pointer to a derived class pointed to by the
- // deduced A. However, if there is a class C that is a (direct or
- // indirect) base class of D and derived (directly or indirectly) from a
- // class B and that would be a valid deduced A, the deduced A cannot be
- // B or pointer to B, respectively.
- //
- // These alternatives are considered only if type deduction would
- // otherwise fail. If they yield more than one possible deduced A, the
- // type deduction fails.
- // Use a breadth-first search through the bases to collect the set of
- // successful matches. Visited contains the set of nodes we have already
- // visited, while ToVisit is our stack of records that we still need to
- // visit. Matches contains a list of matches that have yet to be
- // disqualified.
- llvm::SmallPtrSet<const CXXRecordDecl *, 8> Visited;
- SmallVector<QualType, 8> ToVisit;
- // We iterate over this later, so we have to use MapVector to ensure
- // determinism.
- llvm::MapVector<const CXXRecordDecl *,
- SmallVector<DeducedTemplateArgument, 8>>
- Matches;
- auto AddBases = [&Visited, &ToVisit](const CXXRecordDecl *RD) {
- for (const auto &Base : RD->bases()) {
- QualType T = Base.getType();
- assert(T->isRecordType() && "Base class that isn't a record?");
- if (Visited.insert(::getCanonicalRD(T)).second)
- ToVisit.push_back(T);
- }
- };
- // Set up the loop by adding all the bases.
- AddBases(RD);
- // Search each path of bases until we either run into a successful match
- // (where all bases of it are invalid), or we run out of bases.
- while (!ToVisit.empty()) {
- QualType NextT = ToVisit.pop_back_val();
- SmallVector<DeducedTemplateArgument, 8> DeducedCopy(Deduced.begin(),
- Deduced.end());
- TemplateDeductionInfo BaseInfo(TemplateDeductionInfo::ForBase, Info);
- Sema::TemplateDeductionResult BaseResult = DeduceTemplateSpecArguments(
- S, TemplateParams, P, NextT, BaseInfo, DeducedCopy);
- // If this was a successful deduction, add it to the list of matches,
- // otherwise we need to continue searching its bases.
- const CXXRecordDecl *RD = ::getCanonicalRD(NextT);
- if (BaseResult == Sema::TDK_Success)
- Matches.insert({RD, DeducedCopy});
- else
- AddBases(RD);
- }
- // At this point, 'Matches' contains a list of seemingly valid bases, however
- // in the event that we have more than 1 match, it is possible that the base
- // of one of the matches might be disqualified for being a base of another
- // valid match. We can count on cyclical instantiations being invalid to
- // simplify the disqualifications. That is, if A & B are both matches, and B
- // inherits from A (disqualifying A), we know that A cannot inherit from B.
- if (Matches.size() > 1) {
- Visited.clear();
- for (const auto &Match : Matches)
- AddBases(Match.first);
- // We can give up once we have a single item (or have run out of things to
- // search) since cyclical inheritance isn't valid.
- while (Matches.size() > 1 && !ToVisit.empty()) {
- const CXXRecordDecl *RD = ::getCanonicalRD(ToVisit.pop_back_val());
- Matches.erase(RD);
- // Always add all bases, since the inheritance tree can contain
- // disqualifications for multiple matches.
- AddBases(RD);
- }
- }
- if (Matches.empty())
- return Sema::TDK_Invalid;
- if (Matches.size() > 1)
- return Sema::TDK_MiscellaneousDeductionFailure;
- std::swap(Matches.front().second, Deduced);
- return Sema::TDK_Success;
- }
- /// Deduce the template arguments by comparing the parameter type and
- /// the argument type (C++ [temp.deduct.type]).
- ///
- /// \param S the semantic analysis object within which we are deducing
- ///
- /// \param TemplateParams the template parameters that we are deducing
- ///
- /// \param P the parameter type
- ///
- /// \param A the argument type
- ///
- /// \param Info information about the template argument deduction itself
- ///
- /// \param Deduced the deduced template arguments
- ///
- /// \param TDF bitwise OR of the TemplateDeductionFlags bits that describe
- /// how template argument deduction is performed.
- ///
- /// \param PartialOrdering Whether we're performing template argument deduction
- /// in the context of partial ordering (C++0x [temp.deduct.partial]).
- ///
- /// \returns the result of template argument deduction so far. Note that a
- /// "success" result means that template argument deduction has not yet failed,
- /// but it may still fail, later, for other reasons.
- static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch(
- Sema &S, TemplateParameterList *TemplateParams, QualType P, QualType A,
- TemplateDeductionInfo &Info,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced, unsigned TDF,
- bool PartialOrdering, bool DeducedFromArrayBound) {
- // If the argument type is a pack expansion, look at its pattern.
- // This isn't explicitly called out
- if (const auto *AExp = dyn_cast<PackExpansionType>(A))
- A = AExp->getPattern();
- assert(!isa<PackExpansionType>(A.getCanonicalType()));
- if (PartialOrdering) {
- // C++11 [temp.deduct.partial]p5:
- // Before the partial ordering is done, certain transformations are
- // performed on the types used for partial ordering:
- // - If P is a reference type, P is replaced by the type referred to.
- const ReferenceType *PRef = P->getAs<ReferenceType>();
- if (PRef)
- P = PRef->getPointeeType();
- // - If A is a reference type, A is replaced by the type referred to.
- const ReferenceType *ARef = A->getAs<ReferenceType>();
- if (ARef)
- A = A->getPointeeType();
- if (PRef && ARef && S.Context.hasSameUnqualifiedType(P, A)) {
- // C++11 [temp.deduct.partial]p9:
- // If, for a given type, deduction succeeds in both directions (i.e.,
- // the types are identical after the transformations above) and both
- // P and A were reference types [...]:
- // - if [one type] was an lvalue reference and [the other type] was
- // not, [the other type] is not considered to be at least as
- // specialized as [the first type]
- // - if [one type] is more cv-qualified than [the other type],
- // [the other type] is not considered to be at least as specialized
- // as [the first type]
- // Objective-C ARC adds:
- // - [one type] has non-trivial lifetime, [the other type] has
- // __unsafe_unretained lifetime, and the types are otherwise
- // identical
- //
- // A is "considered to be at least as specialized" as P iff deduction
- // succeeds, so we model this as a deduction failure. Note that
- // [the first type] is P and [the other type] is A here; the standard
- // gets this backwards.
- Qualifiers PQuals = P.getQualifiers(), AQuals = A.getQualifiers();
- if ((PRef->isLValueReferenceType() && !ARef->isLValueReferenceType()) ||
- PQuals.isStrictSupersetOf(AQuals) ||
- (PQuals.hasNonTrivialObjCLifetime() &&
- AQuals.getObjCLifetime() == Qualifiers::OCL_ExplicitNone &&
- PQuals.withoutObjCLifetime() == AQuals.withoutObjCLifetime())) {
- Info.FirstArg = TemplateArgument(P);
- Info.SecondArg = TemplateArgument(A);
- return Sema::TDK_NonDeducedMismatch;
- }
- }
- Qualifiers DiscardedQuals;
- // C++11 [temp.deduct.partial]p7:
- // Remove any top-level cv-qualifiers:
- // - If P is a cv-qualified type, P is replaced by the cv-unqualified
- // version of P.
- P = S.Context.getUnqualifiedArrayType(P, DiscardedQuals);
- // - If A is a cv-qualified type, A is replaced by the cv-unqualified
- // version of A.
- A = S.Context.getUnqualifiedArrayType(A, DiscardedQuals);
- } else {
- // C++0x [temp.deduct.call]p4 bullet 1:
- // - If the original P is a reference type, the deduced A (i.e., the type
- // referred to by the reference) can be more cv-qualified than the
- // transformed A.
- if (TDF & TDF_ParamWithReferenceType) {
- Qualifiers Quals;
- QualType UnqualP = S.Context.getUnqualifiedArrayType(P, Quals);
- Quals.setCVRQualifiers(Quals.getCVRQualifiers() & A.getCVRQualifiers());
- P = S.Context.getQualifiedType(UnqualP, Quals);
- }
- if ((TDF & TDF_TopLevelParameterTypeList) && !P->isFunctionType()) {
- // C++0x [temp.deduct.type]p10:
- // If P and A are function types that originated from deduction when
- // taking the address of a function template (14.8.2.2) or when deducing
- // template arguments from a function declaration (14.8.2.6) and Pi and
- // Ai are parameters of the top-level parameter-type-list of P and A,
- // respectively, Pi is adjusted if it is a forwarding reference and Ai
- // is an lvalue reference, in
- // which case the type of Pi is changed to be the template parameter
- // type (i.e., T&& is changed to simply T). [ Note: As a result, when
- // Pi is T&& and Ai is X&, the adjusted Pi will be T, causing T to be
- // deduced as X&. - end note ]
- TDF &= ~TDF_TopLevelParameterTypeList;
- if (isForwardingReference(P, /*FirstInnerIndex=*/0) &&
- A->isLValueReferenceType())
- P = P->getPointeeType();
- }
- }
- // C++ [temp.deduct.type]p9:
- // A template type argument T, a template template argument TT or a
- // template non-type argument i can be deduced if P and A have one of
- // the following forms:
- //
- // T
- // cv-list T
- if (const auto *TTP = P->getAs<TemplateTypeParmType>()) {
- // Just skip any attempts to deduce from a placeholder type or a parameter
- // at a different depth.
- if (A->isPlaceholderType() || Info.getDeducedDepth() != TTP->getDepth())
- return Sema::TDK_Success;
- unsigned Index = TTP->getIndex();
- // If the argument type is an array type, move the qualifiers up to the
- // top level, so they can be matched with the qualifiers on the parameter.
- if (A->isArrayType()) {
- Qualifiers Quals;
- A = S.Context.getUnqualifiedArrayType(A, Quals);
- if (Quals)
- A = S.Context.getQualifiedType(A, Quals);
- }
- // The argument type can not be less qualified than the parameter
- // type.
- if (!(TDF & TDF_IgnoreQualifiers) &&
- hasInconsistentOrSupersetQualifiersOf(P, A)) {
- Info.Param = cast<TemplateTypeParmDecl>(TemplateParams->getParam(Index));
- Info.FirstArg = TemplateArgument(P);
- Info.SecondArg = TemplateArgument(A);
- return Sema::TDK_Underqualified;
- }
- // Do not match a function type with a cv-qualified type.
- // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1584
- if (A->isFunctionType() && P.hasQualifiers())
- return Sema::TDK_NonDeducedMismatch;
- assert(TTP->getDepth() == Info.getDeducedDepth() &&
- "saw template type parameter with wrong depth");
- assert(A->getCanonicalTypeInternal() != S.Context.OverloadTy &&
- "Unresolved overloaded function");
- QualType DeducedType = A;
- // Remove any qualifiers on the parameter from the deduced type.
- // We checked the qualifiers for consistency above.
- Qualifiers DeducedQs = DeducedType.getQualifiers();
- Qualifiers ParamQs = P.getQualifiers();
- DeducedQs.removeCVRQualifiers(ParamQs.getCVRQualifiers());
- if (ParamQs.hasObjCGCAttr())
- DeducedQs.removeObjCGCAttr();
- if (ParamQs.hasAddressSpace())
- DeducedQs.removeAddressSpace();
- if (ParamQs.hasObjCLifetime())
- DeducedQs.removeObjCLifetime();
- // Objective-C ARC:
- // If template deduction would produce a lifetime qualifier on a type
- // that is not a lifetime type, template argument deduction fails.
- if (ParamQs.hasObjCLifetime() && !DeducedType->isObjCLifetimeType() &&
- !DeducedType->isDependentType()) {
- Info.Param = cast<TemplateTypeParmDecl>(TemplateParams->getParam(Index));
- Info.FirstArg = TemplateArgument(P);
- Info.SecondArg = TemplateArgument(A);
- return Sema::TDK_Underqualified;
- }
- // Objective-C ARC:
- // If template deduction would produce an argument type with lifetime type
- // but no lifetime qualifier, the __strong lifetime qualifier is inferred.
- if (S.getLangOpts().ObjCAutoRefCount && DeducedType->isObjCLifetimeType() &&
- !DeducedQs.hasObjCLifetime())
- DeducedQs.setObjCLifetime(Qualifiers::OCL_Strong);
- DeducedType =
- S.Context.getQualifiedType(DeducedType.getUnqualifiedType(), DeducedQs);
- DeducedTemplateArgument NewDeduced(DeducedType, DeducedFromArrayBound);
- DeducedTemplateArgument Result =
- checkDeducedTemplateArguments(S.Context, Deduced[Index], NewDeduced);
- if (Result.isNull()) {
- Info.Param = cast<TemplateTypeParmDecl>(TemplateParams->getParam(Index));
- Info.FirstArg = Deduced[Index];
- Info.SecondArg = NewDeduced;
- return Sema::TDK_Inconsistent;
- }
- Deduced[Index] = Result;
- return Sema::TDK_Success;
- }
- // Set up the template argument deduction information for a failure.
- Info.FirstArg = TemplateArgument(P);
- Info.SecondArg = TemplateArgument(A);
- // If the parameter is an already-substituted template parameter
- // pack, do nothing: we don't know which of its arguments to look
- // at, so we have to wait until all of the parameter packs in this
- // expansion have arguments.
- if (P->getAs<SubstTemplateTypeParmPackType>())
- return Sema::TDK_Success;
- // Check the cv-qualifiers on the parameter and argument types.
- if (!(TDF & TDF_IgnoreQualifiers)) {
- if (TDF & TDF_ParamWithReferenceType) {
- if (hasInconsistentOrSupersetQualifiersOf(P, A))
- return Sema::TDK_NonDeducedMismatch;
- } else if (TDF & TDF_ArgWithReferenceType) {
- // C++ [temp.deduct.conv]p4:
- // If the original A is a reference type, A can be more cv-qualified
- // than the deduced A
- if (!A.getQualifiers().compatiblyIncludes(P.getQualifiers()))
- return Sema::TDK_NonDeducedMismatch;
- // Strip out all extra qualifiers from the argument to figure out the
- // type we're converting to, prior to the qualification conversion.
- Qualifiers Quals;
- A = S.Context.getUnqualifiedArrayType(A, Quals);
- A = S.Context.getQualifiedType(A, P.getQualifiers());
- } else if (!IsPossiblyOpaquelyQualifiedType(P)) {
- if (P.getCVRQualifiers() != A.getCVRQualifiers())
- return Sema::TDK_NonDeducedMismatch;
- }
- }
- // If the parameter type is not dependent, there is nothing to deduce.
- if (!P->isDependentType()) {
- if (TDF & TDF_SkipNonDependent)
- return Sema::TDK_Success;
- if ((TDF & TDF_IgnoreQualifiers) ? S.Context.hasSameUnqualifiedType(P, A)
- : S.Context.hasSameType(P, A))
- return Sema::TDK_Success;
- if (TDF & TDF_AllowCompatibleFunctionType &&
- S.isSameOrCompatibleFunctionType(P, A))
- return Sema::TDK_Success;
- if (!(TDF & TDF_IgnoreQualifiers))
- return Sema::TDK_NonDeducedMismatch;
- // Otherwise, when ignoring qualifiers, the types not having the same
- // unqualified type does not mean they do not match, so in this case we
- // must keep going and analyze with a non-dependent parameter type.
- }
- switch (P.getCanonicalType()->getTypeClass()) {
- // Non-canonical types cannot appear here.
- #define NON_CANONICAL_TYPE(Class, Base) \
- case Type::Class: llvm_unreachable("deducing non-canonical type: " #Class);
- #define TYPE(Class, Base)
- #include "clang/AST/TypeNodes.inc"
- case Type::TemplateTypeParm:
- case Type::SubstTemplateTypeParmPack:
- llvm_unreachable("Type nodes handled above");
- case Type::Auto:
- // FIXME: Implement deduction in dependent case.
- if (P->isDependentType())
- return Sema::TDK_Success;
- [[fallthrough]];
- case Type::Builtin:
- case Type::VariableArray:
- case Type::Vector:
- case Type::FunctionNoProto:
- case Type::Record:
- case Type::Enum:
- case Type::ObjCObject:
- case Type::ObjCInterface:
- case Type::ObjCObjectPointer:
- case Type::BitInt:
- return (TDF & TDF_SkipNonDependent) ||
- ((TDF & TDF_IgnoreQualifiers)
- ? S.Context.hasSameUnqualifiedType(P, A)
- : S.Context.hasSameType(P, A))
- ? Sema::TDK_Success
- : Sema::TDK_NonDeducedMismatch;
- // _Complex T [placeholder extension]
- case Type::Complex: {
- const auto *CP = P->castAs<ComplexType>(), *CA = A->getAs<ComplexType>();
- if (!CA)
- return Sema::TDK_NonDeducedMismatch;
- return DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, CP->getElementType(), CA->getElementType(), Info,
- Deduced, TDF);
- }
- // _Atomic T [extension]
- case Type::Atomic: {
- const auto *PA = P->castAs<AtomicType>(), *AA = A->getAs<AtomicType>();
- if (!AA)
- return Sema::TDK_NonDeducedMismatch;
- return DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, PA->getValueType(), AA->getValueType(), Info,
- Deduced, TDF);
- }
- // T *
- case Type::Pointer: {
- QualType PointeeType;
- if (const auto *PA = A->getAs<PointerType>()) {
- PointeeType = PA->getPointeeType();
- } else if (const auto *PA = A->getAs<ObjCObjectPointerType>()) {
- PointeeType = PA->getPointeeType();
- } else {
- return Sema::TDK_NonDeducedMismatch;
- }
- return DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, P->castAs<PointerType>()->getPointeeType(),
- PointeeType, Info, Deduced,
- TDF & (TDF_IgnoreQualifiers | TDF_DerivedClass));
- }
- // T &
- case Type::LValueReference: {
- const auto *RP = P->castAs<LValueReferenceType>(),
- *RA = A->getAs<LValueReferenceType>();
- if (!RA)
- return Sema::TDK_NonDeducedMismatch;
- return DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, RP->getPointeeType(), RA->getPointeeType(), Info,
- Deduced, 0);
- }
- // T && [C++0x]
- case Type::RValueReference: {
- const auto *RP = P->castAs<RValueReferenceType>(),
- *RA = A->getAs<RValueReferenceType>();
- if (!RA)
- return Sema::TDK_NonDeducedMismatch;
- return DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, RP->getPointeeType(), RA->getPointeeType(), Info,
- Deduced, 0);
- }
- // T [] (implied, but not stated explicitly)
- case Type::IncompleteArray: {
- const auto *IAA = S.Context.getAsIncompleteArrayType(A);
- if (!IAA)
- return Sema::TDK_NonDeducedMismatch;
- return DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams,
- S.Context.getAsIncompleteArrayType(P)->getElementType(),
- IAA->getElementType(), Info, Deduced, TDF & TDF_IgnoreQualifiers);
- }
- // T [integer-constant]
- case Type::ConstantArray: {
- const auto *CAA = S.Context.getAsConstantArrayType(A),
- *CAP = S.Context.getAsConstantArrayType(P);
- assert(CAP);
- if (!CAA || CAA->getSize() != CAP->getSize())
- return Sema::TDK_NonDeducedMismatch;
- return DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, CAP->getElementType(), CAA->getElementType(), Info,
- Deduced, TDF & TDF_IgnoreQualifiers);
- }
- // type [i]
- case Type::DependentSizedArray: {
- const auto *AA = S.Context.getAsArrayType(A);
- if (!AA)
- return Sema::TDK_NonDeducedMismatch;
- // Check the element type of the arrays
- const auto *DAP = S.Context.getAsDependentSizedArrayType(P);
- assert(DAP);
- if (auto Result = DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, DAP->getElementType(), AA->getElementType(),
- Info, Deduced, TDF & TDF_IgnoreQualifiers))
- return Result;
- // Determine the array bound is something we can deduce.
- const NonTypeTemplateParmDecl *NTTP =
- getDeducedParameterFromExpr(Info, DAP->getSizeExpr());
- if (!NTTP)
- return Sema::TDK_Success;
- // We can perform template argument deduction for the given non-type
- // template parameter.
- assert(NTTP->getDepth() == Info.getDeducedDepth() &&
- "saw non-type template parameter with wrong depth");
- if (const auto *CAA = dyn_cast<ConstantArrayType>(AA)) {
- llvm::APSInt Size(CAA->getSize());
- return DeduceNonTypeTemplateArgument(
- S, TemplateParams, NTTP, Size, S.Context.getSizeType(),
- /*ArrayBound=*/true, Info, Deduced);
- }
- if (const auto *DAA = dyn_cast<DependentSizedArrayType>(AA))
- if (DAA->getSizeExpr())
- return DeduceNonTypeTemplateArgument(
- S, TemplateParams, NTTP, DAA->getSizeExpr(), Info, Deduced);
- // Incomplete type does not match a dependently-sized array type
- return Sema::TDK_NonDeducedMismatch;
- }
- // type(*)(T)
- // T(*)()
- // T(*)(T)
- case Type::FunctionProto: {
- const auto *FPP = P->castAs<FunctionProtoType>(),
- *FPA = A->getAs<FunctionProtoType>();
- if (!FPA)
- return Sema::TDK_NonDeducedMismatch;
- if (FPP->getMethodQuals() != FPA->getMethodQuals() ||
- FPP->getRefQualifier() != FPA->getRefQualifier() ||
- FPP->isVariadic() != FPA->isVariadic())
- return Sema::TDK_NonDeducedMismatch;
- // Check return types.
- if (auto Result = DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, FPP->getReturnType(), FPA->getReturnType(),
- Info, Deduced, 0,
- /*PartialOrdering=*/false,
- /*DeducedFromArrayBound=*/false))
- return Result;
- // Check parameter types.
- if (auto Result = DeduceTemplateArguments(
- S, TemplateParams, FPP->param_type_begin(), FPP->getNumParams(),
- FPA->param_type_begin(), FPA->getNumParams(), Info, Deduced,
- TDF & TDF_TopLevelParameterTypeList, PartialOrdering))
- return Result;
- if (TDF & TDF_AllowCompatibleFunctionType)
- return Sema::TDK_Success;
- // FIXME: Per core-2016/10/1019 (no corresponding core issue yet), permit
- // deducing through the noexcept-specifier if it's part of the canonical
- // type. libstdc++ relies on this.
- Expr *NoexceptExpr = FPP->getNoexceptExpr();
- if (const NonTypeTemplateParmDecl *NTTP =
- NoexceptExpr ? getDeducedParameterFromExpr(Info, NoexceptExpr)
- : nullptr) {
- assert(NTTP->getDepth() == Info.getDeducedDepth() &&
- "saw non-type template parameter with wrong depth");
- llvm::APSInt Noexcept(1);
- switch (FPA->canThrow()) {
- case CT_Cannot:
- Noexcept = 1;
- [[fallthrough]];
- case CT_Can:
- // We give E in noexcept(E) the "deduced from array bound" treatment.
- // FIXME: Should we?
- return DeduceNonTypeTemplateArgument(
- S, TemplateParams, NTTP, Noexcept, S.Context.BoolTy,
- /*DeducedFromArrayBound=*/true, Info, Deduced);
- case CT_Dependent:
- if (Expr *ArgNoexceptExpr = FPA->getNoexceptExpr())
- return DeduceNonTypeTemplateArgument(
- S, TemplateParams, NTTP, ArgNoexceptExpr, Info, Deduced);
- // Can't deduce anything from throw(T...).
- break;
- }
- }
- // FIXME: Detect non-deduced exception specification mismatches?
- //
- // Careful about [temp.deduct.call] and [temp.deduct.conv], which allow
- // top-level differences in noexcept-specifications.
- return Sema::TDK_Success;
- }
- case Type::InjectedClassName:
- // Treat a template's injected-class-name as if the template
- // specialization type had been used.
- // template-name<T> (where template-name refers to a class template)
- // template-name<i>
- // TT<T>
- // TT<i>
- // TT<>
- case Type::TemplateSpecialization: {
- // When Arg cannot be a derived class, we can just try to deduce template
- // arguments from the template-id.
- if (!(TDF & TDF_DerivedClass) || !A->isRecordType())
- return DeduceTemplateSpecArguments(S, TemplateParams, P, A, Info,
- Deduced);
- SmallVector<DeducedTemplateArgument, 8> DeducedOrig(Deduced.begin(),
- Deduced.end());
- auto Result =
- DeduceTemplateSpecArguments(S, TemplateParams, P, A, Info, Deduced);
- if (Result == Sema::TDK_Success)
- return Result;
- // We cannot inspect base classes as part of deduction when the type
- // is incomplete, so either instantiate any templates necessary to
- // complete the type, or skip over it if it cannot be completed.
- if (!S.isCompleteType(Info.getLocation(), A))
- return Result;
- // Reset the incorrectly deduced argument from above.
- Deduced = DeducedOrig;
- // Check bases according to C++14 [temp.deduct.call] p4b3:
- auto BaseResult = DeduceTemplateBases(S, getCanonicalRD(A),
- TemplateParams, P, Info, Deduced);
- return BaseResult != Sema::TDK_Invalid ? BaseResult : Result;
- }
- // T type::*
- // T T::*
- // T (type::*)()
- // type (T::*)()
- // type (type::*)(T)
- // type (T::*)(T)
- // T (type::*)(T)
- // T (T::*)()
- // T (T::*)(T)
- case Type::MemberPointer: {
- const auto *MPP = P->castAs<MemberPointerType>(),
- *MPA = A->getAs<MemberPointerType>();
- if (!MPA)
- return Sema::TDK_NonDeducedMismatch;
- QualType PPT = MPP->getPointeeType();
- if (PPT->isFunctionType())
- S.adjustMemberFunctionCC(PPT, /*IsStatic=*/true,
- /*IsCtorOrDtor=*/false, Info.getLocation());
- QualType APT = MPA->getPointeeType();
- if (APT->isFunctionType())
- S.adjustMemberFunctionCC(APT, /*IsStatic=*/true,
- /*IsCtorOrDtor=*/false, Info.getLocation());
- unsigned SubTDF = TDF & TDF_IgnoreQualifiers;
- if (auto Result = DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, PPT, APT, Info, Deduced, SubTDF))
- return Result;
- return DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, QualType(MPP->getClass(), 0),
- QualType(MPA->getClass(), 0), Info, Deduced, SubTDF);
- }
- // (clang extension)
- //
- // type(^)(T)
- // T(^)()
- // T(^)(T)
- case Type::BlockPointer: {
- const auto *BPP = P->castAs<BlockPointerType>(),
- *BPA = A->getAs<BlockPointerType>();
- if (!BPA)
- return Sema::TDK_NonDeducedMismatch;
- return DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, BPP->getPointeeType(), BPA->getPointeeType(), Info,
- Deduced, 0);
- }
- // (clang extension)
- //
- // T __attribute__(((ext_vector_type(<integral constant>))))
- case Type::ExtVector: {
- const auto *VP = P->castAs<ExtVectorType>();
- QualType ElementType;
- if (const auto *VA = A->getAs<ExtVectorType>()) {
- // Make sure that the vectors have the same number of elements.
- if (VP->getNumElements() != VA->getNumElements())
- return Sema::TDK_NonDeducedMismatch;
- ElementType = VA->getElementType();
- } else if (const auto *VA = A->getAs<DependentSizedExtVectorType>()) {
- // We can't check the number of elements, since the argument has a
- // dependent number of elements. This can only occur during partial
- // ordering.
- ElementType = VA->getElementType();
- } else {
- return Sema::TDK_NonDeducedMismatch;
- }
- // Perform deduction on the element types.
- return DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, VP->getElementType(), ElementType, Info, Deduced,
- TDF);
- }
- case Type::DependentVector: {
- const auto *VP = P->castAs<DependentVectorType>();
- if (const auto *VA = A->getAs<VectorType>()) {
- // Perform deduction on the element types.
- if (auto Result = DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, VP->getElementType(), VA->getElementType(),
- Info, Deduced, TDF))
- return Result;
- // Perform deduction on the vector size, if we can.
- const NonTypeTemplateParmDecl *NTTP =
- getDeducedParameterFromExpr(Info, VP->getSizeExpr());
- if (!NTTP)
- return Sema::TDK_Success;
- llvm::APSInt ArgSize(S.Context.getTypeSize(S.Context.IntTy), false);
- ArgSize = VA->getNumElements();
- // Note that we use the "array bound" rules here; just like in that
- // case, we don't have any particular type for the vector size, but
- // we can provide one if necessary.
- return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP, ArgSize,
- S.Context.UnsignedIntTy, true,
- Info, Deduced);
- }
- if (const auto *VA = A->getAs<DependentVectorType>()) {
- // Perform deduction on the element types.
- if (auto Result = DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, VP->getElementType(), VA->getElementType(),
- Info, Deduced, TDF))
- return Result;
- // Perform deduction on the vector size, if we can.
- const NonTypeTemplateParmDecl *NTTP =
- getDeducedParameterFromExpr(Info, VP->getSizeExpr());
- if (!NTTP)
- return Sema::TDK_Success;
- return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
- VA->getSizeExpr(), Info, Deduced);
- }
- return Sema::TDK_NonDeducedMismatch;
- }
- // (clang extension)
- //
- // T __attribute__(((ext_vector_type(N))))
- case Type::DependentSizedExtVector: {
- const auto *VP = P->castAs<DependentSizedExtVectorType>();
- if (const auto *VA = A->getAs<ExtVectorType>()) {
- // Perform deduction on the element types.
- if (auto Result = DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, VP->getElementType(), VA->getElementType(),
- Info, Deduced, TDF))
- return Result;
- // Perform deduction on the vector size, if we can.
- const NonTypeTemplateParmDecl *NTTP =
- getDeducedParameterFromExpr(Info, VP->getSizeExpr());
- if (!NTTP)
- return Sema::TDK_Success;
- llvm::APSInt ArgSize(S.Context.getTypeSize(S.Context.IntTy), false);
- ArgSize = VA->getNumElements();
- // Note that we use the "array bound" rules here; just like in that
- // case, we don't have any particular type for the vector size, but
- // we can provide one if necessary.
- return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP, ArgSize,
- S.Context.IntTy, true, Info,
- Deduced);
- }
- if (const auto *VA = A->getAs<DependentSizedExtVectorType>()) {
- // Perform deduction on the element types.
- if (auto Result = DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, VP->getElementType(), VA->getElementType(),
- Info, Deduced, TDF))
- return Result;
- // Perform deduction on the vector size, if we can.
- const NonTypeTemplateParmDecl *NTTP =
- getDeducedParameterFromExpr(Info, VP->getSizeExpr());
- if (!NTTP)
- return Sema::TDK_Success;
- return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
- VA->getSizeExpr(), Info, Deduced);
- }
- return Sema::TDK_NonDeducedMismatch;
- }
- // (clang extension)
- //
- // T __attribute__((matrix_type(<integral constant>,
- // <integral constant>)))
- case Type::ConstantMatrix: {
- const auto *MP = P->castAs<ConstantMatrixType>(),
- *MA = A->getAs<ConstantMatrixType>();
- if (!MA)
- return Sema::TDK_NonDeducedMismatch;
- // Check that the dimensions are the same
- if (MP->getNumRows() != MA->getNumRows() ||
- MP->getNumColumns() != MA->getNumColumns()) {
- return Sema::TDK_NonDeducedMismatch;
- }
- // Perform deduction on element types.
- return DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, MP->getElementType(), MA->getElementType(), Info,
- Deduced, TDF);
- }
- case Type::DependentSizedMatrix: {
- const auto *MP = P->castAs<DependentSizedMatrixType>();
- const auto *MA = A->getAs<MatrixType>();
- if (!MA)
- return Sema::TDK_NonDeducedMismatch;
- // Check the element type of the matrixes.
- if (auto Result = DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, MP->getElementType(), MA->getElementType(),
- Info, Deduced, TDF))
- return Result;
- // Try to deduce a matrix dimension.
- auto DeduceMatrixArg =
- [&S, &Info, &Deduced, &TemplateParams](
- Expr *ParamExpr, const MatrixType *A,
- unsigned (ConstantMatrixType::*GetArgDimension)() const,
- Expr *(DependentSizedMatrixType::*GetArgDimensionExpr)() const) {
- const auto *ACM = dyn_cast<ConstantMatrixType>(A);
- const auto *ADM = dyn_cast<DependentSizedMatrixType>(A);
- if (!ParamExpr->isValueDependent()) {
- std::optional<llvm::APSInt> ParamConst =
- ParamExpr->getIntegerConstantExpr(S.Context);
- if (!ParamConst)
- return Sema::TDK_NonDeducedMismatch;
- if (ACM) {
- if ((ACM->*GetArgDimension)() == *ParamConst)
- return Sema::TDK_Success;
- return Sema::TDK_NonDeducedMismatch;
- }
- Expr *ArgExpr = (ADM->*GetArgDimensionExpr)();
- if (std::optional<llvm::APSInt> ArgConst =
- ArgExpr->getIntegerConstantExpr(S.Context))
- if (*ArgConst == *ParamConst)
- return Sema::TDK_Success;
- return Sema::TDK_NonDeducedMismatch;
- }
- const NonTypeTemplateParmDecl *NTTP =
- getDeducedParameterFromExpr(Info, ParamExpr);
- if (!NTTP)
- return Sema::TDK_Success;
- if (ACM) {
- llvm::APSInt ArgConst(
- S.Context.getTypeSize(S.Context.getSizeType()));
- ArgConst = (ACM->*GetArgDimension)();
- return DeduceNonTypeTemplateArgument(
- S, TemplateParams, NTTP, ArgConst, S.Context.getSizeType(),
- /*ArrayBound=*/true, Info, Deduced);
- }
- return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
- (ADM->*GetArgDimensionExpr)(),
- Info, Deduced);
- };
- if (auto Result = DeduceMatrixArg(MP->getRowExpr(), MA,
- &ConstantMatrixType::getNumRows,
- &DependentSizedMatrixType::getRowExpr))
- return Result;
- return DeduceMatrixArg(MP->getColumnExpr(), MA,
- &ConstantMatrixType::getNumColumns,
- &DependentSizedMatrixType::getColumnExpr);
- }
- // (clang extension)
- //
- // T __attribute__(((address_space(N))))
- case Type::DependentAddressSpace: {
- const auto *ASP = P->castAs<DependentAddressSpaceType>();
- if (const auto *ASA = A->getAs<DependentAddressSpaceType>()) {
- // Perform deduction on the pointer type.
- if (auto Result = DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, ASP->getPointeeType(), ASA->getPointeeType(),
- Info, Deduced, TDF))
- return Result;
- // Perform deduction on the address space, if we can.
- const NonTypeTemplateParmDecl *NTTP =
- getDeducedParameterFromExpr(Info, ASP->getAddrSpaceExpr());
- if (!NTTP)
- return Sema::TDK_Success;
- return DeduceNonTypeTemplateArgument(
- S, TemplateParams, NTTP, ASA->getAddrSpaceExpr(), Info, Deduced);
- }
- if (isTargetAddressSpace(A.getAddressSpace())) {
- llvm::APSInt ArgAddressSpace(S.Context.getTypeSize(S.Context.IntTy),
- false);
- ArgAddressSpace = toTargetAddressSpace(A.getAddressSpace());
- // Perform deduction on the pointer types.
- if (auto Result = DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, ASP->getPointeeType(),
- S.Context.removeAddrSpaceQualType(A), Info, Deduced, TDF))
- return Result;
- // Perform deduction on the address space, if we can.
- const NonTypeTemplateParmDecl *NTTP =
- getDeducedParameterFromExpr(Info, ASP->getAddrSpaceExpr());
- if (!NTTP)
- return Sema::TDK_Success;
- return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
- ArgAddressSpace, S.Context.IntTy,
- true, Info, Deduced);
- }
- return Sema::TDK_NonDeducedMismatch;
- }
- case Type::DependentBitInt: {
- const auto *IP = P->castAs<DependentBitIntType>();
- if (const auto *IA = A->getAs<BitIntType>()) {
- if (IP->isUnsigned() != IA->isUnsigned())
- return Sema::TDK_NonDeducedMismatch;
- const NonTypeTemplateParmDecl *NTTP =
- getDeducedParameterFromExpr(Info, IP->getNumBitsExpr());
- if (!NTTP)
- return Sema::TDK_Success;
- llvm::APSInt ArgSize(S.Context.getTypeSize(S.Context.IntTy), false);
- ArgSize = IA->getNumBits();
- return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP, ArgSize,
- S.Context.IntTy, true, Info,
- Deduced);
- }
- if (const auto *IA = A->getAs<DependentBitIntType>()) {
- if (IP->isUnsigned() != IA->isUnsigned())
- return Sema::TDK_NonDeducedMismatch;
- return Sema::TDK_Success;
- }
- return Sema::TDK_NonDeducedMismatch;
- }
- case Type::TypeOfExpr:
- case Type::TypeOf:
- case Type::DependentName:
- case Type::UnresolvedUsing:
- case Type::Decltype:
- case Type::UnaryTransform:
- case Type::DeducedTemplateSpecialization:
- case Type::DependentTemplateSpecialization:
- case Type::PackExpansion:
- case Type::Pipe:
- // No template argument deduction for these types
- return Sema::TDK_Success;
- }
- llvm_unreachable("Invalid Type Class!");
- }
- static Sema::TemplateDeductionResult
- DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
- const TemplateArgument &P, TemplateArgument A,
- TemplateDeductionInfo &Info,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
- // If the template argument is a pack expansion, perform template argument
- // deduction against the pattern of that expansion. This only occurs during
- // partial ordering.
- if (A.isPackExpansion())
- A = A.getPackExpansionPattern();
- switch (P.getKind()) {
- case TemplateArgument::Null:
- llvm_unreachable("Null template argument in parameter list");
- case TemplateArgument::Type:
- if (A.getKind() == TemplateArgument::Type)
- return DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, P.getAsType(), A.getAsType(), Info, Deduced, 0);
- Info.FirstArg = P;
- Info.SecondArg = A;
- return Sema::TDK_NonDeducedMismatch;
- case TemplateArgument::Template:
- if (A.getKind() == TemplateArgument::Template)
- return DeduceTemplateArguments(S, TemplateParams, P.getAsTemplate(),
- A.getAsTemplate(), Info, Deduced);
- Info.FirstArg = P;
- Info.SecondArg = A;
- return Sema::TDK_NonDeducedMismatch;
- case TemplateArgument::TemplateExpansion:
- llvm_unreachable("caller should handle pack expansions");
- case TemplateArgument::Declaration:
- if (A.getKind() == TemplateArgument::Declaration &&
- isSameDeclaration(P.getAsDecl(), A.getAsDecl()))
- return Sema::TDK_Success;
- Info.FirstArg = P;
- Info.SecondArg = A;
- return Sema::TDK_NonDeducedMismatch;
- case TemplateArgument::NullPtr:
- if (A.getKind() == TemplateArgument::NullPtr &&
- S.Context.hasSameType(P.getNullPtrType(), A.getNullPtrType()))
- return Sema::TDK_Success;
- Info.FirstArg = P;
- Info.SecondArg = A;
- return Sema::TDK_NonDeducedMismatch;
- case TemplateArgument::Integral:
- if (A.getKind() == TemplateArgument::Integral) {
- if (hasSameExtendedValue(P.getAsIntegral(), A.getAsIntegral()))
- return Sema::TDK_Success;
- }
- Info.FirstArg = P;
- Info.SecondArg = A;
- return Sema::TDK_NonDeducedMismatch;
- case TemplateArgument::Expression:
- if (const NonTypeTemplateParmDecl *NTTP =
- getDeducedParameterFromExpr(Info, P.getAsExpr())) {
- if (A.getKind() == TemplateArgument::Integral)
- return DeduceNonTypeTemplateArgument(
- S, TemplateParams, NTTP, A.getAsIntegral(), A.getIntegralType(),
- /*ArrayBound=*/false, Info, Deduced);
- if (A.getKind() == TemplateArgument::NullPtr)
- return DeduceNullPtrTemplateArgument(S, TemplateParams, NTTP,
- A.getNullPtrType(), Info, Deduced);
- if (A.getKind() == TemplateArgument::Expression)
- return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
- A.getAsExpr(), Info, Deduced);
- if (A.getKind() == TemplateArgument::Declaration)
- return DeduceNonTypeTemplateArgument(
- S, TemplateParams, NTTP, A.getAsDecl(), A.getParamTypeForDecl(),
- Info, Deduced);
- Info.FirstArg = P;
- Info.SecondArg = A;
- return Sema::TDK_NonDeducedMismatch;
- }
- // Can't deduce anything, but that's okay.
- return Sema::TDK_Success;
- case TemplateArgument::Pack:
- llvm_unreachable("Argument packs should be expanded by the caller!");
- }
- llvm_unreachable("Invalid TemplateArgument Kind!");
- }
- /// Determine whether there is a template argument to be used for
- /// deduction.
- ///
- /// This routine "expands" argument packs in-place, overriding its input
- /// parameters so that \c Args[ArgIdx] will be the available template argument.
- ///
- /// \returns true if there is another template argument (which will be at
- /// \c Args[ArgIdx]), false otherwise.
- static bool hasTemplateArgumentForDeduction(ArrayRef<TemplateArgument> &Args,
- unsigned &ArgIdx) {
- if (ArgIdx == Args.size())
- return false;
- const TemplateArgument &Arg = Args[ArgIdx];
- if (Arg.getKind() != TemplateArgument::Pack)
- return true;
- assert(ArgIdx == Args.size() - 1 && "Pack not at the end of argument list?");
- Args = Arg.pack_elements();
- ArgIdx = 0;
- return ArgIdx < Args.size();
- }
- /// Determine whether the given set of template arguments has a pack
- /// expansion that is not the last template argument.
- static bool hasPackExpansionBeforeEnd(ArrayRef<TemplateArgument> Args) {
- bool FoundPackExpansion = false;
- for (const auto &A : Args) {
- if (FoundPackExpansion)
- return true;
- if (A.getKind() == TemplateArgument::Pack)
- return hasPackExpansionBeforeEnd(A.pack_elements());
- // FIXME: If this is a fixed-arity pack expansion from an outer level of
- // templates, it should not be treated as a pack expansion.
- if (A.isPackExpansion())
- FoundPackExpansion = true;
- }
- return false;
- }
- static Sema::TemplateDeductionResult
- DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
- ArrayRef<TemplateArgument> Ps,
- ArrayRef<TemplateArgument> As,
- TemplateDeductionInfo &Info,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced,
- bool NumberOfArgumentsMustMatch) {
- // C++0x [temp.deduct.type]p9:
- // If the template argument list of P contains a pack expansion that is not
- // the last template argument, the entire template argument list is a
- // non-deduced context.
- if (hasPackExpansionBeforeEnd(Ps))
- return Sema::TDK_Success;
- // C++0x [temp.deduct.type]p9:
- // If P has a form that contains <T> or <i>, then each argument Pi of the
- // respective template argument list P is compared with the corresponding
- // argument Ai of the corresponding template argument list of A.
- unsigned ArgIdx = 0, ParamIdx = 0;
- for (; hasTemplateArgumentForDeduction(Ps, ParamIdx); ++ParamIdx) {
- const TemplateArgument &P = Ps[ParamIdx];
- if (!P.isPackExpansion()) {
- // The simple case: deduce template arguments by matching Pi and Ai.
- // Check whether we have enough arguments.
- if (!hasTemplateArgumentForDeduction(As, ArgIdx))
- return NumberOfArgumentsMustMatch
- ? Sema::TDK_MiscellaneousDeductionFailure
- : Sema::TDK_Success;
- // C++1z [temp.deduct.type]p9:
- // During partial ordering, if Ai was originally a pack expansion [and]
- // Pi is not a pack expansion, template argument deduction fails.
- if (As[ArgIdx].isPackExpansion())
- return Sema::TDK_MiscellaneousDeductionFailure;
- // Perform deduction for this Pi/Ai pair.
- if (auto Result = DeduceTemplateArguments(S, TemplateParams, P,
- As[ArgIdx], Info, Deduced))
- return Result;
- // Move to the next argument.
- ++ArgIdx;
- continue;
- }
- // The parameter is a pack expansion.
- // C++0x [temp.deduct.type]p9:
- // If Pi is a pack expansion, then the pattern of Pi is compared with
- // each remaining argument in the template argument list of A. Each
- // comparison deduces template arguments for subsequent positions in the
- // template parameter packs expanded by Pi.
- TemplateArgument Pattern = P.getPackExpansionPattern();
- // Prepare to deduce the packs within the pattern.
- PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern);
- // Keep track of the deduced template arguments for each parameter pack
- // expanded by this pack expansion (the outer index) and for each
- // template argument (the inner SmallVectors).
- for (; hasTemplateArgumentForDeduction(As, ArgIdx) &&
- PackScope.hasNextElement();
- ++ArgIdx) {
- // Deduce template arguments from the pattern.
- if (auto Result = DeduceTemplateArguments(S, TemplateParams, Pattern,
- As[ArgIdx], Info, Deduced))
- return Result;
- PackScope.nextPackElement();
- }
- // Build argument packs for each of the parameter packs expanded by this
- // pack expansion.
- if (auto Result = PackScope.finish())
- return Result;
- }
- return Sema::TDK_Success;
- }
- static Sema::TemplateDeductionResult
- DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
- const TemplateArgumentList &ParamList,
- const TemplateArgumentList &ArgList,
- TemplateDeductionInfo &Info,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
- return DeduceTemplateArguments(S, TemplateParams, ParamList.asArray(),
- ArgList.asArray(), Info, Deduced,
- /*NumberOfArgumentsMustMatch=*/false);
- }
- /// Determine whether two template arguments are the same.
- static bool isSameTemplateArg(ASTContext &Context,
- TemplateArgument X,
- const TemplateArgument &Y,
- bool PartialOrdering,
- bool PackExpansionMatchesPack = false) {
- // If we're checking deduced arguments (X) against original arguments (Y),
- // we will have flattened packs to non-expansions in X.
- if (PackExpansionMatchesPack && X.isPackExpansion() && !Y.isPackExpansion())
- X = X.getPackExpansionPattern();
- if (X.getKind() != Y.getKind())
- return false;
- switch (X.getKind()) {
- case TemplateArgument::Null:
- llvm_unreachable("Comparing NULL template argument");
- case TemplateArgument::Type:
- return Context.getCanonicalType(X.getAsType()) ==
- Context.getCanonicalType(Y.getAsType());
- case TemplateArgument::Declaration:
- return isSameDeclaration(X.getAsDecl(), Y.getAsDecl());
- case TemplateArgument::NullPtr:
- return Context.hasSameType(X.getNullPtrType(), Y.getNullPtrType());
- case TemplateArgument::Template:
- case TemplateArgument::TemplateExpansion:
- return Context.getCanonicalTemplateName(
- X.getAsTemplateOrTemplatePattern()).getAsVoidPointer() ==
- Context.getCanonicalTemplateName(
- Y.getAsTemplateOrTemplatePattern()).getAsVoidPointer();
- case TemplateArgument::Integral:
- return hasSameExtendedValue(X.getAsIntegral(), Y.getAsIntegral());
- case TemplateArgument::Expression: {
- llvm::FoldingSetNodeID XID, YID;
- X.getAsExpr()->Profile(XID, Context, true);
- Y.getAsExpr()->Profile(YID, Context, true);
- return XID == YID;
- }
- case TemplateArgument::Pack: {
- unsigned PackIterationSize = X.pack_size();
- if (X.pack_size() != Y.pack_size()) {
- if (!PartialOrdering)
- return false;
- // C++0x [temp.deduct.type]p9:
- // During partial ordering, if Ai was originally a pack expansion:
- // - if P does not contain a template argument corresponding to Ai
- // then Ai is ignored;
- bool XHasMoreArg = X.pack_size() > Y.pack_size();
- if (!(XHasMoreArg && X.pack_elements().back().isPackExpansion()) &&
- !(!XHasMoreArg && Y.pack_elements().back().isPackExpansion()))
- return false;
- if (XHasMoreArg)
- PackIterationSize = Y.pack_size();
- }
- ArrayRef<TemplateArgument> XP = X.pack_elements();
- ArrayRef<TemplateArgument> YP = Y.pack_elements();
- for (unsigned i = 0; i < PackIterationSize; ++i)
- if (!isSameTemplateArg(Context, XP[i], YP[i], PartialOrdering,
- PackExpansionMatchesPack))
- return false;
- return true;
- }
- }
- llvm_unreachable("Invalid TemplateArgument Kind!");
- }
- /// Allocate a TemplateArgumentLoc where all locations have
- /// been initialized to the given location.
- ///
- /// \param Arg The template argument we are producing template argument
- /// location information for.
- ///
- /// \param NTTPType For a declaration template argument, the type of
- /// the non-type template parameter that corresponds to this template
- /// argument. Can be null if no type sugar is available to add to the
- /// type from the template argument.
- ///
- /// \param Loc The source location to use for the resulting template
- /// argument.
- TemplateArgumentLoc
- Sema::getTrivialTemplateArgumentLoc(const TemplateArgument &Arg,
- QualType NTTPType, SourceLocation Loc) {
- switch (Arg.getKind()) {
- case TemplateArgument::Null:
- llvm_unreachable("Can't get a NULL template argument here");
- case TemplateArgument::Type:
- return TemplateArgumentLoc(
- Arg, Context.getTrivialTypeSourceInfo(Arg.getAsType(), Loc));
- case TemplateArgument::Declaration: {
- if (NTTPType.isNull())
- NTTPType = Arg.getParamTypeForDecl();
- Expr *E = BuildExpressionFromDeclTemplateArgument(Arg, NTTPType, Loc)
- .getAs<Expr>();
- return TemplateArgumentLoc(TemplateArgument(E), E);
- }
- case TemplateArgument::NullPtr: {
- if (NTTPType.isNull())
- NTTPType = Arg.getNullPtrType();
- Expr *E = BuildExpressionFromDeclTemplateArgument(Arg, NTTPType, Loc)
- .getAs<Expr>();
- return TemplateArgumentLoc(TemplateArgument(NTTPType, /*isNullPtr*/true),
- E);
- }
- case TemplateArgument::Integral: {
- Expr *E =
- BuildExpressionFromIntegralTemplateArgument(Arg, Loc).getAs<Expr>();
- return TemplateArgumentLoc(TemplateArgument(E), E);
- }
- case TemplateArgument::Template:
- case TemplateArgument::TemplateExpansion: {
- NestedNameSpecifierLocBuilder Builder;
- TemplateName Template = Arg.getAsTemplateOrTemplatePattern();
- if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
- Builder.MakeTrivial(Context, DTN->getQualifier(), Loc);
- else if (QualifiedTemplateName *QTN =
- Template.getAsQualifiedTemplateName())
- Builder.MakeTrivial(Context, QTN->getQualifier(), Loc);
- if (Arg.getKind() == TemplateArgument::Template)
- return TemplateArgumentLoc(Context, Arg,
- Builder.getWithLocInContext(Context), Loc);
- return TemplateArgumentLoc(
- Context, Arg, Builder.getWithLocInContext(Context), Loc, Loc);
- }
- case TemplateArgument::Expression:
- return TemplateArgumentLoc(Arg, Arg.getAsExpr());
- case TemplateArgument::Pack:
- return TemplateArgumentLoc(Arg, TemplateArgumentLocInfo());
- }
- llvm_unreachable("Invalid TemplateArgument Kind!");
- }
- TemplateArgumentLoc
- Sema::getIdentityTemplateArgumentLoc(NamedDecl *TemplateParm,
- SourceLocation Location) {
- return getTrivialTemplateArgumentLoc(
- Context.getInjectedTemplateArg(TemplateParm), QualType(), Location);
- }
- /// Convert the given deduced template argument and add it to the set of
- /// fully-converted template arguments.
- static bool ConvertDeducedTemplateArgument(
- Sema &S, NamedDecl *Param, DeducedTemplateArgument Arg, NamedDecl *Template,
- TemplateDeductionInfo &Info, bool IsDeduced,
- SmallVectorImpl<TemplateArgument> &SugaredOutput,
- SmallVectorImpl<TemplateArgument> &CanonicalOutput) {
- auto ConvertArg = [&](DeducedTemplateArgument Arg,
- unsigned ArgumentPackIndex) {
- // Convert the deduced template argument into a template
- // argument that we can check, almost as if the user had written
- // the template argument explicitly.
- TemplateArgumentLoc ArgLoc =
- S.getTrivialTemplateArgumentLoc(Arg, QualType(), Info.getLocation());
- // Check the template argument, converting it as necessary.
- return S.CheckTemplateArgument(
- Param, ArgLoc, Template, Template->getLocation(),
- Template->getSourceRange().getEnd(), ArgumentPackIndex, SugaredOutput,
- CanonicalOutput,
- IsDeduced
- ? (Arg.wasDeducedFromArrayBound() ? Sema::CTAK_DeducedFromArrayBound
- : Sema::CTAK_Deduced)
- : Sema::CTAK_Specified);
- };
- if (Arg.getKind() == TemplateArgument::Pack) {
- // This is a template argument pack, so check each of its arguments against
- // the template parameter.
- SmallVector<TemplateArgument, 2> SugaredPackedArgsBuilder,
- CanonicalPackedArgsBuilder;
- for (const auto &P : Arg.pack_elements()) {
- // When converting the deduced template argument, append it to the
- // general output list. We need to do this so that the template argument
- // checking logic has all of the prior template arguments available.
- DeducedTemplateArgument InnerArg(P);
- InnerArg.setDeducedFromArrayBound(Arg.wasDeducedFromArrayBound());
- assert(InnerArg.getKind() != TemplateArgument::Pack &&
- "deduced nested pack");
- if (P.isNull()) {
- // We deduced arguments for some elements of this pack, but not for
- // all of them. This happens if we get a conditionally-non-deduced
- // context in a pack expansion (such as an overload set in one of the
- // arguments).
- S.Diag(Param->getLocation(),
- diag::err_template_arg_deduced_incomplete_pack)
- << Arg << Param;
- return true;
- }
- if (ConvertArg(InnerArg, SugaredPackedArgsBuilder.size()))
- return true;
- // Move the converted template argument into our argument pack.
- SugaredPackedArgsBuilder.push_back(SugaredOutput.pop_back_val());
- CanonicalPackedArgsBuilder.push_back(CanonicalOutput.pop_back_val());
- }
- // If the pack is empty, we still need to substitute into the parameter
- // itself, in case that substitution fails.
- if (SugaredPackedArgsBuilder.empty()) {
- LocalInstantiationScope Scope(S);
- MultiLevelTemplateArgumentList Args(Template, SugaredOutput,
- /*Final=*/true);
- if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
- Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template,
- NTTP, SugaredOutput,
- Template->getSourceRange());
- if (Inst.isInvalid() ||
- S.SubstType(NTTP->getType(), Args, NTTP->getLocation(),
- NTTP->getDeclName()).isNull())
- return true;
- } else if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) {
- Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template,
- TTP, SugaredOutput,
- Template->getSourceRange());
- if (Inst.isInvalid() || !S.SubstDecl(TTP, S.CurContext, Args))
- return true;
- }
- // For type parameters, no substitution is ever required.
- }
- // Create the resulting argument pack.
- SugaredOutput.push_back(
- TemplateArgument::CreatePackCopy(S.Context, SugaredPackedArgsBuilder));
- CanonicalOutput.push_back(TemplateArgument::CreatePackCopy(
- S.Context, CanonicalPackedArgsBuilder));
- return false;
- }
- return ConvertArg(Arg, 0);
- }
- // FIXME: This should not be a template, but
- // ClassTemplatePartialSpecializationDecl sadly does not derive from
- // TemplateDecl.
- template <typename TemplateDeclT>
- static Sema::TemplateDeductionResult ConvertDeducedTemplateArguments(
- Sema &S, TemplateDeclT *Template, bool IsDeduced,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced,
- TemplateDeductionInfo &Info,
- SmallVectorImpl<TemplateArgument> &SugaredBuilder,
- SmallVectorImpl<TemplateArgument> &CanonicalBuilder,
- LocalInstantiationScope *CurrentInstantiationScope = nullptr,
- unsigned NumAlreadyConverted = 0, bool PartialOverloading = false) {
- TemplateParameterList *TemplateParams = Template->getTemplateParameters();
- for (unsigned I = 0, N = TemplateParams->size(); I != N; ++I) {
- NamedDecl *Param = TemplateParams->getParam(I);
- // C++0x [temp.arg.explicit]p3:
- // A trailing template parameter pack (14.5.3) not otherwise deduced will
- // be deduced to an empty sequence of template arguments.
- // FIXME: Where did the word "trailing" come from?
- if (Deduced[I].isNull() && Param->isTemplateParameterPack()) {
- if (auto Result =
- PackDeductionScope(S, TemplateParams, Deduced, Info, I).finish())
- return Result;
- }
- if (!Deduced[I].isNull()) {
- if (I < NumAlreadyConverted) {
- // We may have had explicitly-specified template arguments for a
- // template parameter pack (that may or may not have been extended
- // via additional deduced arguments).
- if (Param->isParameterPack() && CurrentInstantiationScope &&
- CurrentInstantiationScope->getPartiallySubstitutedPack() == Param) {
- // Forget the partially-substituted pack; its substitution is now
- // complete.
- CurrentInstantiationScope->ResetPartiallySubstitutedPack();
- // We still need to check the argument in case it was extended by
- // deduction.
- } else {
- // We have already fully type-checked and converted this
- // argument, because it was explicitly-specified. Just record the
- // presence of this argument.
- SugaredBuilder.push_back(Deduced[I]);
- CanonicalBuilder.push_back(
- S.Context.getCanonicalTemplateArgument(Deduced[I]));
- continue;
- }
- }
- // We may have deduced this argument, so it still needs to be
- // checked and converted.
- if (ConvertDeducedTemplateArgument(S, Param, Deduced[I], Template, Info,
- IsDeduced, SugaredBuilder,
- CanonicalBuilder)) {
- Info.Param = makeTemplateParameter(Param);
- // FIXME: These template arguments are temporary. Free them!
- Info.reset(
- TemplateArgumentList::CreateCopy(S.Context, SugaredBuilder),
- TemplateArgumentList::CreateCopy(S.Context, CanonicalBuilder));
- return Sema::TDK_SubstitutionFailure;
- }
- continue;
- }
- // Substitute into the default template argument, if available.
- bool HasDefaultArg = false;
- TemplateDecl *TD = dyn_cast<TemplateDecl>(Template);
- if (!TD) {
- assert(isa<ClassTemplatePartialSpecializationDecl>(Template) ||
- isa<VarTemplatePartialSpecializationDecl>(Template));
- return Sema::TDK_Incomplete;
- }
- TemplateArgumentLoc DefArg;
- {
- Qualifiers ThisTypeQuals;
- CXXRecordDecl *ThisContext = nullptr;
- if (auto *Rec = dyn_cast<CXXRecordDecl>(TD->getDeclContext()))
- if (Rec->isLambda())
- if (auto *Method = dyn_cast<CXXMethodDecl>(Rec->getDeclContext())) {
- ThisContext = Method->getParent();
- ThisTypeQuals = Method->getMethodQualifiers();
- }
- Sema::CXXThisScopeRAII ThisScope(S, ThisContext, ThisTypeQuals,
- S.getLangOpts().CPlusPlus17);
- DefArg = S.SubstDefaultTemplateArgumentIfAvailable(
- TD, TD->getLocation(), TD->getSourceRange().getEnd(), Param,
- SugaredBuilder, CanonicalBuilder, HasDefaultArg);
- }
- // If there was no default argument, deduction is incomplete.
- if (DefArg.getArgument().isNull()) {
- Info.Param = makeTemplateParameter(
- const_cast<NamedDecl *>(TemplateParams->getParam(I)));
- Info.reset(TemplateArgumentList::CreateCopy(S.Context, SugaredBuilder),
- TemplateArgumentList::CreateCopy(S.Context, CanonicalBuilder));
- if (PartialOverloading) break;
- return HasDefaultArg ? Sema::TDK_SubstitutionFailure
- : Sema::TDK_Incomplete;
- }
- // Check whether we can actually use the default argument.
- if (S.CheckTemplateArgument(
- Param, DefArg, TD, TD->getLocation(), TD->getSourceRange().getEnd(),
- 0, SugaredBuilder, CanonicalBuilder, Sema::CTAK_Specified)) {
- Info.Param = makeTemplateParameter(
- const_cast<NamedDecl *>(TemplateParams->getParam(I)));
- // FIXME: These template arguments are temporary. Free them!
- Info.reset(TemplateArgumentList::CreateCopy(S.Context, SugaredBuilder),
- TemplateArgumentList::CreateCopy(S.Context, CanonicalBuilder));
- return Sema::TDK_SubstitutionFailure;
- }
- // If we get here, we successfully used the default template argument.
- }
- return Sema::TDK_Success;
- }
- static DeclContext *getAsDeclContextOrEnclosing(Decl *D) {
- if (auto *DC = dyn_cast<DeclContext>(D))
- return DC;
- return D->getDeclContext();
- }
- template<typename T> struct IsPartialSpecialization {
- static constexpr bool value = false;
- };
- template<>
- struct IsPartialSpecialization<ClassTemplatePartialSpecializationDecl> {
- static constexpr bool value = true;
- };
- template<>
- struct IsPartialSpecialization<VarTemplatePartialSpecializationDecl> {
- static constexpr bool value = true;
- };
- template <typename TemplateDeclT>
- static bool DeducedArgsNeedReplacement(TemplateDeclT *Template) {
- return false;
- }
- template <>
- bool DeducedArgsNeedReplacement<VarTemplatePartialSpecializationDecl>(
- VarTemplatePartialSpecializationDecl *Spec) {
- return !Spec->isClassScopeExplicitSpecialization();
- }
- template <>
- bool DeducedArgsNeedReplacement<ClassTemplatePartialSpecializationDecl>(
- ClassTemplatePartialSpecializationDecl *Spec) {
- return !Spec->isClassScopeExplicitSpecialization();
- }
- template <typename TemplateDeclT>
- static Sema::TemplateDeductionResult
- CheckDeducedArgumentConstraints(Sema &S, TemplateDeclT *Template,
- ArrayRef<TemplateArgument> SugaredDeducedArgs,
- ArrayRef<TemplateArgument> CanonicalDeducedArgs,
- TemplateDeductionInfo &Info) {
- llvm::SmallVector<const Expr *, 3> AssociatedConstraints;
- Template->getAssociatedConstraints(AssociatedConstraints);
- bool NeedsReplacement = DeducedArgsNeedReplacement(Template);
- TemplateArgumentList DeducedTAL{TemplateArgumentList::OnStack,
- CanonicalDeducedArgs};
- MultiLevelTemplateArgumentList MLTAL = S.getTemplateInstantiationArgs(
- Template, /*Final=*/false,
- /*InnerMost=*/NeedsReplacement ? nullptr : &DeducedTAL,
- /*RelativeToPrimary=*/true, /*Pattern=*/
- nullptr, /*ForConstraintInstantiation=*/true);
- // getTemplateInstantiationArgs picks up the non-deduced version of the
- // template args when this is a variable template partial specialization and
- // not class-scope explicit specialization, so replace with Deduced Args
- // instead of adding to inner-most.
- if (NeedsReplacement)
- MLTAL.replaceInnermostTemplateArguments(CanonicalDeducedArgs);
- if (S.CheckConstraintSatisfaction(Template, AssociatedConstraints, MLTAL,
- Info.getLocation(),
- Info.AssociatedConstraintsSatisfaction) ||
- !Info.AssociatedConstraintsSatisfaction.IsSatisfied) {
- Info.reset(
- TemplateArgumentList::CreateCopy(S.Context, SugaredDeducedArgs),
- TemplateArgumentList::CreateCopy(S.Context, CanonicalDeducedArgs));
- return Sema::TDK_ConstraintsNotSatisfied;
- }
- return Sema::TDK_Success;
- }
- /// Complete template argument deduction for a partial specialization.
- template <typename T>
- static std::enable_if_t<IsPartialSpecialization<T>::value,
- Sema::TemplateDeductionResult>
- FinishTemplateArgumentDeduction(
- Sema &S, T *Partial, bool IsPartialOrdering,
- const TemplateArgumentList &TemplateArgs,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced,
- TemplateDeductionInfo &Info) {
- // Unevaluated SFINAE context.
- EnterExpressionEvaluationContext Unevaluated(
- S, Sema::ExpressionEvaluationContext::Unevaluated);
- Sema::SFINAETrap Trap(S);
- Sema::ContextRAII SavedContext(S, getAsDeclContextOrEnclosing(Partial));
- // C++ [temp.deduct.type]p2:
- // [...] or if any template argument remains neither deduced nor
- // explicitly specified, template argument deduction fails.
- SmallVector<TemplateArgument, 4> SugaredBuilder, CanonicalBuilder;
- if (auto Result = ConvertDeducedTemplateArguments(
- S, Partial, IsPartialOrdering, Deduced, Info, SugaredBuilder,
- CanonicalBuilder))
- return Result;
- // Form the template argument list from the deduced template arguments.
- TemplateArgumentList *SugaredDeducedArgumentList =
- TemplateArgumentList::CreateCopy(S.Context, SugaredBuilder);
- TemplateArgumentList *CanonicalDeducedArgumentList =
- TemplateArgumentList::CreateCopy(S.Context, CanonicalBuilder);
- Info.reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
- // Substitute the deduced template arguments into the template
- // arguments of the class template partial specialization, and
- // verify that the instantiated template arguments are both valid
- // and are equivalent to the template arguments originally provided
- // to the class template.
- LocalInstantiationScope InstScope(S);
- auto *Template = Partial->getSpecializedTemplate();
- const ASTTemplateArgumentListInfo *PartialTemplArgInfo =
- Partial->getTemplateArgsAsWritten();
- TemplateArgumentListInfo InstArgs(PartialTemplArgInfo->LAngleLoc,
- PartialTemplArgInfo->RAngleLoc);
- if (S.SubstTemplateArguments(PartialTemplArgInfo->arguments(),
- MultiLevelTemplateArgumentList(Partial,
- SugaredBuilder,
- /*Final=*/true),
- InstArgs)) {
- unsigned ArgIdx = InstArgs.size(), ParamIdx = ArgIdx;
- if (ParamIdx >= Partial->getTemplateParameters()->size())
- ParamIdx = Partial->getTemplateParameters()->size() - 1;
- Decl *Param = const_cast<NamedDecl *>(
- Partial->getTemplateParameters()->getParam(ParamIdx));
- Info.Param = makeTemplateParameter(Param);
- Info.FirstArg = (*PartialTemplArgInfo)[ArgIdx].getArgument();
- return Sema::TDK_SubstitutionFailure;
- }
- bool ConstraintsNotSatisfied;
- SmallVector<TemplateArgument, 4> SugaredConvertedInstArgs,
- CanonicalConvertedInstArgs;
- if (S.CheckTemplateArgumentList(
- Template, Partial->getLocation(), InstArgs, false,
- SugaredConvertedInstArgs, CanonicalConvertedInstArgs,
- /*UpdateArgsWithConversions=*/true, &ConstraintsNotSatisfied))
- return ConstraintsNotSatisfied ? Sema::TDK_ConstraintsNotSatisfied
- : Sema::TDK_SubstitutionFailure;
- TemplateParameterList *TemplateParams = Template->getTemplateParameters();
- for (unsigned I = 0, E = TemplateParams->size(); I != E; ++I) {
- TemplateArgument InstArg = SugaredConvertedInstArgs.data()[I];
- if (!isSameTemplateArg(S.Context, TemplateArgs[I], InstArg,
- IsPartialOrdering)) {
- Info.Param = makeTemplateParameter(TemplateParams->getParam(I));
- Info.FirstArg = TemplateArgs[I];
- Info.SecondArg = InstArg;
- return Sema::TDK_NonDeducedMismatch;
- }
- }
- if (Trap.hasErrorOccurred())
- return Sema::TDK_SubstitutionFailure;
- if (auto Result = CheckDeducedArgumentConstraints(S, Partial, SugaredBuilder,
- CanonicalBuilder, Info))
- return Result;
- return Sema::TDK_Success;
- }
- /// Complete template argument deduction for a class or variable template,
- /// when partial ordering against a partial specialization.
- // FIXME: Factor out duplication with partial specialization version above.
- static Sema::TemplateDeductionResult FinishTemplateArgumentDeduction(
- Sema &S, TemplateDecl *Template, bool PartialOrdering,
- const TemplateArgumentList &TemplateArgs,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced,
- TemplateDeductionInfo &Info) {
- // Unevaluated SFINAE context.
- EnterExpressionEvaluationContext Unevaluated(
- S, Sema::ExpressionEvaluationContext::Unevaluated);
- Sema::SFINAETrap Trap(S);
- Sema::ContextRAII SavedContext(S, getAsDeclContextOrEnclosing(Template));
- // C++ [temp.deduct.type]p2:
- // [...] or if any template argument remains neither deduced nor
- // explicitly specified, template argument deduction fails.
- SmallVector<TemplateArgument, 4> SugaredBuilder, CanonicalBuilder;
- if (auto Result = ConvertDeducedTemplateArguments(
- S, Template, /*IsDeduced*/ PartialOrdering, Deduced, Info,
- SugaredBuilder, CanonicalBuilder,
- /*CurrentInstantiationScope=*/nullptr,
- /*NumAlreadyConverted=*/0U, /*PartialOverloading=*/false))
- return Result;
- // Check that we produced the correct argument list.
- TemplateParameterList *TemplateParams = Template->getTemplateParameters();
- for (unsigned I = 0, E = TemplateParams->size(); I != E; ++I) {
- TemplateArgument InstArg = CanonicalBuilder[I];
- if (!isSameTemplateArg(S.Context, TemplateArgs[I], InstArg, PartialOrdering,
- /*PackExpansionMatchesPack=*/true)) {
- Info.Param = makeTemplateParameter(TemplateParams->getParam(I));
- Info.FirstArg = TemplateArgs[I];
- Info.SecondArg = InstArg;
- return Sema::TDK_NonDeducedMismatch;
- }
- }
- if (Trap.hasErrorOccurred())
- return Sema::TDK_SubstitutionFailure;
- if (auto Result = CheckDeducedArgumentConstraints(S, Template, SugaredBuilder,
- CanonicalBuilder, Info))
- return Result;
- return Sema::TDK_Success;
- }
- /// Perform template argument deduction to determine whether
- /// the given template arguments match the given class template
- /// partial specialization per C++ [temp.class.spec.match].
- Sema::TemplateDeductionResult
- Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,
- const TemplateArgumentList &TemplateArgs,
- TemplateDeductionInfo &Info) {
- if (Partial->isInvalidDecl())
- return TDK_Invalid;
- // C++ [temp.class.spec.match]p2:
- // A partial specialization matches a given actual template
- // argument list if the template arguments of the partial
- // specialization can be deduced from the actual template argument
- // list (14.8.2).
- // Unevaluated SFINAE context.
- EnterExpressionEvaluationContext Unevaluated(
- *this, Sema::ExpressionEvaluationContext::Unevaluated);
- SFINAETrap Trap(*this);
- // This deduction has no relation to any outer instantiation we might be
- // performing.
- LocalInstantiationScope InstantiationScope(*this);
- SmallVector<DeducedTemplateArgument, 4> Deduced;
- Deduced.resize(Partial->getTemplateParameters()->size());
- if (TemplateDeductionResult Result
- = ::DeduceTemplateArguments(*this,
- Partial->getTemplateParameters(),
- Partial->getTemplateArgs(),
- TemplateArgs, Info, Deduced))
- return Result;
- SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(), Deduced.end());
- InstantiatingTemplate Inst(*this, Info.getLocation(), Partial, DeducedArgs,
- Info);
- if (Inst.isInvalid())
- return TDK_InstantiationDepth;
- if (Trap.hasErrorOccurred())
- return Sema::TDK_SubstitutionFailure;
- TemplateDeductionResult Result;
- runWithSufficientStackSpace(Info.getLocation(), [&] {
- Result = ::FinishTemplateArgumentDeduction(*this, Partial,
- /*IsPartialOrdering=*/false,
- TemplateArgs, Deduced, Info);
- });
- return Result;
- }
- /// Perform template argument deduction to determine whether
- /// the given template arguments match the given variable template
- /// partial specialization per C++ [temp.class.spec.match].
- Sema::TemplateDeductionResult
- Sema::DeduceTemplateArguments(VarTemplatePartialSpecializationDecl *Partial,
- const TemplateArgumentList &TemplateArgs,
- TemplateDeductionInfo &Info) {
- if (Partial->isInvalidDecl())
- return TDK_Invalid;
- // C++ [temp.class.spec.match]p2:
- // A partial specialization matches a given actual template
- // argument list if the template arguments of the partial
- // specialization can be deduced from the actual template argument
- // list (14.8.2).
- // Unevaluated SFINAE context.
- EnterExpressionEvaluationContext Unevaluated(
- *this, Sema::ExpressionEvaluationContext::Unevaluated);
- SFINAETrap Trap(*this);
- // This deduction has no relation to any outer instantiation we might be
- // performing.
- LocalInstantiationScope InstantiationScope(*this);
- SmallVector<DeducedTemplateArgument, 4> Deduced;
- Deduced.resize(Partial->getTemplateParameters()->size());
- if (TemplateDeductionResult Result = ::DeduceTemplateArguments(
- *this, Partial->getTemplateParameters(), Partial->getTemplateArgs(),
- TemplateArgs, Info, Deduced))
- return Result;
- SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(), Deduced.end());
- InstantiatingTemplate Inst(*this, Info.getLocation(), Partial, DeducedArgs,
- Info);
- if (Inst.isInvalid())
- return TDK_InstantiationDepth;
- if (Trap.hasErrorOccurred())
- return Sema::TDK_SubstitutionFailure;
- TemplateDeductionResult Result;
- runWithSufficientStackSpace(Info.getLocation(), [&] {
- Result = ::FinishTemplateArgumentDeduction(*this, Partial,
- /*IsPartialOrdering=*/false,
- TemplateArgs, Deduced, Info);
- });
- return Result;
- }
- /// Determine whether the given type T is a simple-template-id type.
- static bool isSimpleTemplateIdType(QualType T) {
- if (const TemplateSpecializationType *Spec
- = T->getAs<TemplateSpecializationType>())
- return Spec->getTemplateName().getAsTemplateDecl() != nullptr;
- // C++17 [temp.local]p2:
- // the injected-class-name [...] is equivalent to the template-name followed
- // by the template-arguments of the class template specialization or partial
- // specialization enclosed in <>
- // ... which means it's equivalent to a simple-template-id.
- //
- // This only arises during class template argument deduction for a copy
- // deduction candidate, where it permits slicing.
- if (T->getAs<InjectedClassNameType>())
- return true;
- return false;
- }
- /// Substitute the explicitly-provided template arguments into the
- /// given function template according to C++ [temp.arg.explicit].
- ///
- /// \param FunctionTemplate the function template into which the explicit
- /// template arguments will be substituted.
- ///
- /// \param ExplicitTemplateArgs the explicitly-specified template
- /// arguments.
- ///
- /// \param Deduced the deduced template arguments, which will be populated
- /// with the converted and checked explicit template arguments.
- ///
- /// \param ParamTypes will be populated with the instantiated function
- /// parameters.
- ///
- /// \param FunctionType if non-NULL, the result type of the function template
- /// will also be instantiated and the pointed-to value will be updated with
- /// the instantiated function type.
- ///
- /// \param Info if substitution fails for any reason, this object will be
- /// populated with more information about the failure.
- ///
- /// \returns TDK_Success if substitution was successful, or some failure
- /// condition.
- Sema::TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments(
- FunctionTemplateDecl *FunctionTemplate,
- TemplateArgumentListInfo &ExplicitTemplateArgs,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced,
- SmallVectorImpl<QualType> &ParamTypes, QualType *FunctionType,
- TemplateDeductionInfo &Info) {
- FunctionDecl *Function = FunctionTemplate->getTemplatedDecl();
- TemplateParameterList *TemplateParams
- = FunctionTemplate->getTemplateParameters();
- if (ExplicitTemplateArgs.size() == 0) {
- // No arguments to substitute; just copy over the parameter types and
- // fill in the function type.
- for (auto *P : Function->parameters())
- ParamTypes.push_back(P->getType());
- if (FunctionType)
- *FunctionType = Function->getType();
- return TDK_Success;
- }
- // Unevaluated SFINAE context.
- EnterExpressionEvaluationContext Unevaluated(
- *this, Sema::ExpressionEvaluationContext::Unevaluated);
- SFINAETrap Trap(*this);
- // C++ [temp.arg.explicit]p3:
- // Template arguments that are present shall be specified in the
- // declaration order of their corresponding template-parameters. The
- // template argument list shall not specify more template-arguments than
- // there are corresponding template-parameters.
- SmallVector<TemplateArgument, 4> SugaredBuilder, CanonicalBuilder;
- // Enter a new template instantiation context where we check the
- // explicitly-specified template arguments against this function template,
- // and then substitute them into the function parameter types.
- SmallVector<TemplateArgument, 4> DeducedArgs;
- InstantiatingTemplate Inst(
- *this, Info.getLocation(), FunctionTemplate, DeducedArgs,
- CodeSynthesisContext::ExplicitTemplateArgumentSubstitution, Info);
- if (Inst.isInvalid())
- return TDK_InstantiationDepth;
- if (CheckTemplateArgumentList(FunctionTemplate, SourceLocation(),
- ExplicitTemplateArgs, true, SugaredBuilder,
- CanonicalBuilder,
- /*UpdateArgsWithConversions=*/false) ||
- Trap.hasErrorOccurred()) {
- unsigned Index = SugaredBuilder.size();
- if (Index >= TemplateParams->size())
- return TDK_SubstitutionFailure;
- Info.Param = makeTemplateParameter(TemplateParams->getParam(Index));
- return TDK_InvalidExplicitArguments;
- }
- // Form the template argument list from the explicitly-specified
- // template arguments.
- TemplateArgumentList *SugaredExplicitArgumentList =
- TemplateArgumentList::CreateCopy(Context, SugaredBuilder);
- TemplateArgumentList *CanonicalExplicitArgumentList =
- TemplateArgumentList::CreateCopy(Context, CanonicalBuilder);
- Info.setExplicitArgs(SugaredExplicitArgumentList,
- CanonicalExplicitArgumentList);
- // Template argument deduction and the final substitution should be
- // done in the context of the templated declaration. Explicit
- // argument substitution, on the other hand, needs to happen in the
- // calling context.
- ContextRAII SavedContext(*this, FunctionTemplate->getTemplatedDecl());
- // If we deduced template arguments for a template parameter pack,
- // note that the template argument pack is partially substituted and record
- // the explicit template arguments. They'll be used as part of deduction
- // for this template parameter pack.
- unsigned PartiallySubstitutedPackIndex = -1u;
- if (!CanonicalBuilder.empty()) {
- const TemplateArgument &Arg = CanonicalBuilder.back();
- if (Arg.getKind() == TemplateArgument::Pack) {
- auto *Param = TemplateParams->getParam(CanonicalBuilder.size() - 1);
- // If this is a fully-saturated fixed-size pack, it should be
- // fully-substituted, not partially-substituted.
- std::optional<unsigned> Expansions = getExpandedPackSize(Param);
- if (!Expansions || Arg.pack_size() < *Expansions) {
- PartiallySubstitutedPackIndex = CanonicalBuilder.size() - 1;
- CurrentInstantiationScope->SetPartiallySubstitutedPack(
- Param, Arg.pack_begin(), Arg.pack_size());
- }
- }
- }
- const FunctionProtoType *Proto
- = Function->getType()->getAs<FunctionProtoType>();
- assert(Proto && "Function template does not have a prototype?");
- // Isolate our substituted parameters from our caller.
- LocalInstantiationScope InstScope(*this, /*MergeWithOuterScope*/true);
- ExtParameterInfoBuilder ExtParamInfos;
- MultiLevelTemplateArgumentList MLTAL(FunctionTemplate,
- SugaredExplicitArgumentList->asArray(),
- /*Final=*/true);
- // Instantiate the types of each of the function parameters given the
- // explicitly-specified template arguments. If the function has a trailing
- // return type, substitute it after the arguments to ensure we substitute
- // in lexical order.
- if (Proto->hasTrailingReturn()) {
- if (SubstParmTypes(Function->getLocation(), Function->parameters(),
- Proto->getExtParameterInfosOrNull(), MLTAL, ParamTypes,
- /*params=*/nullptr, ExtParamInfos))
- return TDK_SubstitutionFailure;
- }
- // Instantiate the return type.
- QualType ResultType;
- {
- // C++11 [expr.prim.general]p3:
- // If a declaration declares a member function or member function
- // template of a class X, the expression this is a prvalue of type
- // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
- // and the end of the function-definition, member-declarator, or
- // declarator.
- Qualifiers ThisTypeQuals;
- CXXRecordDecl *ThisContext = nullptr;
- if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Function)) {
- ThisContext = Method->getParent();
- ThisTypeQuals = Method->getMethodQualifiers();
- }
- CXXThisScopeRAII ThisScope(*this, ThisContext, ThisTypeQuals,
- getLangOpts().CPlusPlus11);
- ResultType =
- SubstType(Proto->getReturnType(), MLTAL,
- Function->getTypeSpecStartLoc(), Function->getDeclName());
- if (ResultType.isNull() || Trap.hasErrorOccurred())
- return TDK_SubstitutionFailure;
- // CUDA: Kernel function must have 'void' return type.
- if (getLangOpts().CUDA)
- if (Function->hasAttr<CUDAGlobalAttr>() && !ResultType->isVoidType()) {
- Diag(Function->getLocation(), diag::err_kern_type_not_void_return)
- << Function->getType() << Function->getSourceRange();
- return TDK_SubstitutionFailure;
- }
- }
- // Instantiate the types of each of the function parameters given the
- // explicitly-specified template arguments if we didn't do so earlier.
- if (!Proto->hasTrailingReturn() &&
- SubstParmTypes(Function->getLocation(), Function->parameters(),
- Proto->getExtParameterInfosOrNull(), MLTAL, ParamTypes,
- /*params*/ nullptr, ExtParamInfos))
- return TDK_SubstitutionFailure;
- if (FunctionType) {
- auto EPI = Proto->getExtProtoInfo();
- EPI.ExtParameterInfos = ExtParamInfos.getPointerOrNull(ParamTypes.size());
- // In C++1z onwards, exception specifications are part of the function type,
- // so substitution into the type must also substitute into the exception
- // specification.
- SmallVector<QualType, 4> ExceptionStorage;
- if (getLangOpts().CPlusPlus17 &&
- SubstExceptionSpec(Function->getLocation(), EPI.ExceptionSpec,
- ExceptionStorage, MLTAL))
- return TDK_SubstitutionFailure;
- *FunctionType = BuildFunctionType(ResultType, ParamTypes,
- Function->getLocation(),
- Function->getDeclName(),
- EPI);
- if (FunctionType->isNull() || Trap.hasErrorOccurred())
- return TDK_SubstitutionFailure;
- }
- // C++ [temp.arg.explicit]p2:
- // Trailing template arguments that can be deduced (14.8.2) may be
- // omitted from the list of explicit template-arguments. If all of the
- // template arguments can be deduced, they may all be omitted; in this
- // case, the empty template argument list <> itself may also be omitted.
- //
- // Take all of the explicitly-specified arguments and put them into
- // the set of deduced template arguments. The partially-substituted
- // parameter pack, however, will be set to NULL since the deduction
- // mechanism handles the partially-substituted argument pack directly.
- Deduced.reserve(TemplateParams->size());
- for (unsigned I = 0, N = SugaredExplicitArgumentList->size(); I != N; ++I) {
- const TemplateArgument &Arg = SugaredExplicitArgumentList->get(I);
- if (I == PartiallySubstitutedPackIndex)
- Deduced.push_back(DeducedTemplateArgument());
- else
- Deduced.push_back(Arg);
- }
- return TDK_Success;
- }
- /// Check whether the deduced argument type for a call to a function
- /// template matches the actual argument type per C++ [temp.deduct.call]p4.
- static Sema::TemplateDeductionResult
- CheckOriginalCallArgDeduction(Sema &S, TemplateDeductionInfo &Info,
- Sema::OriginalCallArg OriginalArg,
- QualType DeducedA) {
- ASTContext &Context = S.Context;
- auto Failed = [&]() -> Sema::TemplateDeductionResult {
- Info.FirstArg = TemplateArgument(DeducedA);
- Info.SecondArg = TemplateArgument(OriginalArg.OriginalArgType);
- Info.CallArgIndex = OriginalArg.ArgIdx;
- return OriginalArg.DecomposedParam ? Sema::TDK_DeducedMismatchNested
- : Sema::TDK_DeducedMismatch;
- };
- QualType A = OriginalArg.OriginalArgType;
- QualType OriginalParamType = OriginalArg.OriginalParamType;
- // Check for type equality (top-level cv-qualifiers are ignored).
- if (Context.hasSameUnqualifiedType(A, DeducedA))
- return Sema::TDK_Success;
- // Strip off references on the argument types; they aren't needed for
- // the following checks.
- if (const ReferenceType *DeducedARef = DeducedA->getAs<ReferenceType>())
- DeducedA = DeducedARef->getPointeeType();
- if (const ReferenceType *ARef = A->getAs<ReferenceType>())
- A = ARef->getPointeeType();
- // C++ [temp.deduct.call]p4:
- // [...] However, there are three cases that allow a difference:
- // - If the original P is a reference type, the deduced A (i.e., the
- // type referred to by the reference) can be more cv-qualified than
- // the transformed A.
- if (const ReferenceType *OriginalParamRef
- = OriginalParamType->getAs<ReferenceType>()) {
- // We don't want to keep the reference around any more.
- OriginalParamType = OriginalParamRef->getPointeeType();
- // FIXME: Resolve core issue (no number yet): if the original P is a
- // reference type and the transformed A is function type "noexcept F",
- // the deduced A can be F.
- QualType Tmp;
- if (A->isFunctionType() && S.IsFunctionConversion(A, DeducedA, Tmp))
- return Sema::TDK_Success;
- Qualifiers AQuals = A.getQualifiers();
- Qualifiers DeducedAQuals = DeducedA.getQualifiers();
- // Under Objective-C++ ARC, the deduced type may have implicitly
- // been given strong or (when dealing with a const reference)
- // unsafe_unretained lifetime. If so, update the original
- // qualifiers to include this lifetime.
- if (S.getLangOpts().ObjCAutoRefCount &&
- ((DeducedAQuals.getObjCLifetime() == Qualifiers::OCL_Strong &&
- AQuals.getObjCLifetime() == Qualifiers::OCL_None) ||
- (DeducedAQuals.hasConst() &&
- DeducedAQuals.getObjCLifetime() == Qualifiers::OCL_ExplicitNone))) {
- AQuals.setObjCLifetime(DeducedAQuals.getObjCLifetime());
- }
- if (AQuals == DeducedAQuals) {
- // Qualifiers match; there's nothing to do.
- } else if (!DeducedAQuals.compatiblyIncludes(AQuals)) {
- return Failed();
- } else {
- // Qualifiers are compatible, so have the argument type adopt the
- // deduced argument type's qualifiers as if we had performed the
- // qualification conversion.
- A = Context.getQualifiedType(A.getUnqualifiedType(), DeducedAQuals);
- }
- }
- // - The transformed A can be another pointer or pointer to member
- // type that can be converted to the deduced A via a function pointer
- // conversion and/or a qualification conversion.
- //
- // Also allow conversions which merely strip __attribute__((noreturn)) from
- // function types (recursively).
- bool ObjCLifetimeConversion = false;
- QualType ResultTy;
- if ((A->isAnyPointerType() || A->isMemberPointerType()) &&
- (S.IsQualificationConversion(A, DeducedA, false,
- ObjCLifetimeConversion) ||
- S.IsFunctionConversion(A, DeducedA, ResultTy)))
- return Sema::TDK_Success;
- // - If P is a class and P has the form simple-template-id, then the
- // transformed A can be a derived class of the deduced A. [...]
- // [...] Likewise, if P is a pointer to a class of the form
- // simple-template-id, the transformed A can be a pointer to a
- // derived class pointed to by the deduced A.
- if (const PointerType *OriginalParamPtr
- = OriginalParamType->getAs<PointerType>()) {
- if (const PointerType *DeducedAPtr = DeducedA->getAs<PointerType>()) {
- if (const PointerType *APtr = A->getAs<PointerType>()) {
- if (A->getPointeeType()->isRecordType()) {
- OriginalParamType = OriginalParamPtr->getPointeeType();
- DeducedA = DeducedAPtr->getPointeeType();
- A = APtr->getPointeeType();
- }
- }
- }
- }
- if (Context.hasSameUnqualifiedType(A, DeducedA))
- return Sema::TDK_Success;
- if (A->isRecordType() && isSimpleTemplateIdType(OriginalParamType) &&
- S.IsDerivedFrom(Info.getLocation(), A, DeducedA))
- return Sema::TDK_Success;
- return Failed();
- }
- /// Find the pack index for a particular parameter index in an instantiation of
- /// a function template with specific arguments.
- ///
- /// \return The pack index for whichever pack produced this parameter, or -1
- /// if this was not produced by a parameter. Intended to be used as the
- /// ArgumentPackSubstitutionIndex for further substitutions.
- // FIXME: We should track this in OriginalCallArgs so we don't need to
- // reconstruct it here.
- static unsigned getPackIndexForParam(Sema &S,
- FunctionTemplateDecl *FunctionTemplate,
- const MultiLevelTemplateArgumentList &Args,
- unsigned ParamIdx) {
- unsigned Idx = 0;
- for (auto *PD : FunctionTemplate->getTemplatedDecl()->parameters()) {
- if (PD->isParameterPack()) {
- unsigned NumExpansions =
- S.getNumArgumentsInExpansion(PD->getType(), Args).value_or(1);
- if (Idx + NumExpansions > ParamIdx)
- return ParamIdx - Idx;
- Idx += NumExpansions;
- } else {
- if (Idx == ParamIdx)
- return -1; // Not a pack expansion
- ++Idx;
- }
- }
- llvm_unreachable("parameter index would not be produced from template");
- }
- /// Finish template argument deduction for a function template,
- /// checking the deduced template arguments for completeness and forming
- /// the function template specialization.
- ///
- /// \param OriginalCallArgs If non-NULL, the original call arguments against
- /// which the deduced argument types should be compared.
- Sema::TemplateDeductionResult Sema::FinishTemplateArgumentDeduction(
- FunctionTemplateDecl *FunctionTemplate,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced,
- unsigned NumExplicitlySpecified, FunctionDecl *&Specialization,
- TemplateDeductionInfo &Info,
- SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs,
- bool PartialOverloading, llvm::function_ref<bool()> CheckNonDependent) {
- // Unevaluated SFINAE context.
- EnterExpressionEvaluationContext Unevaluated(
- *this, Sema::ExpressionEvaluationContext::Unevaluated);
- SFINAETrap Trap(*this);
- // Enter a new template instantiation context while we instantiate the
- // actual function declaration.
- SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(), Deduced.end());
- InstantiatingTemplate Inst(
- *this, Info.getLocation(), FunctionTemplate, DeducedArgs,
- CodeSynthesisContext::DeducedTemplateArgumentSubstitution, Info);
- if (Inst.isInvalid())
- return TDK_InstantiationDepth;
- ContextRAII SavedContext(*this, FunctionTemplate->getTemplatedDecl());
- // C++ [temp.deduct.type]p2:
- // [...] or if any template argument remains neither deduced nor
- // explicitly specified, template argument deduction fails.
- SmallVector<TemplateArgument, 4> SugaredBuilder, CanonicalBuilder;
- if (auto Result = ConvertDeducedTemplateArguments(
- *this, FunctionTemplate, /*IsDeduced*/ true, Deduced, Info,
- SugaredBuilder, CanonicalBuilder, CurrentInstantiationScope,
- NumExplicitlySpecified, PartialOverloading))
- return Result;
- // C++ [temp.deduct.call]p10: [DR1391]
- // If deduction succeeds for all parameters that contain
- // template-parameters that participate in template argument deduction,
- // and all template arguments are explicitly specified, deduced, or
- // obtained from default template arguments, remaining parameters are then
- // compared with the corresponding arguments. For each remaining parameter
- // P with a type that was non-dependent before substitution of any
- // explicitly-specified template arguments, if the corresponding argument
- // A cannot be implicitly converted to P, deduction fails.
- if (CheckNonDependent())
- return TDK_NonDependentConversionFailure;
- // Form the template argument list from the deduced template arguments.
- TemplateArgumentList *SugaredDeducedArgumentList =
- TemplateArgumentList::CreateCopy(Context, SugaredBuilder);
- TemplateArgumentList *CanonicalDeducedArgumentList =
- TemplateArgumentList::CreateCopy(Context, CanonicalBuilder);
- Info.reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
- // Substitute the deduced template arguments into the function template
- // declaration to produce the function template specialization.
- DeclContext *Owner = FunctionTemplate->getDeclContext();
- if (FunctionTemplate->getFriendObjectKind())
- Owner = FunctionTemplate->getLexicalDeclContext();
- MultiLevelTemplateArgumentList SubstArgs(
- FunctionTemplate, CanonicalDeducedArgumentList->asArray(),
- /*Final=*/false);
- Specialization = cast_or_null<FunctionDecl>(
- SubstDecl(FunctionTemplate->getTemplatedDecl(), Owner, SubstArgs));
- if (!Specialization || Specialization->isInvalidDecl())
- return TDK_SubstitutionFailure;
- assert(Specialization->getPrimaryTemplate()->getCanonicalDecl() ==
- FunctionTemplate->getCanonicalDecl());
- // If the template argument list is owned by the function template
- // specialization, release it.
- if (Specialization->getTemplateSpecializationArgs() ==
- CanonicalDeducedArgumentList &&
- !Trap.hasErrorOccurred())
- Info.takeCanonical();
- // There may have been an error that did not prevent us from constructing a
- // declaration. Mark the declaration invalid and return with a substitution
- // failure.
- if (Trap.hasErrorOccurred()) {
- Specialization->setInvalidDecl(true);
- return TDK_SubstitutionFailure;
- }
- // C++2a [temp.deduct]p5
- // [...] When all template arguments have been deduced [...] all uses of
- // template parameters [...] are replaced with the corresponding deduced
- // or default argument values.
- // [...] If the function template has associated constraints
- // ([temp.constr.decl]), those constraints are checked for satisfaction
- // ([temp.constr.constr]). If the constraints are not satisfied, type
- // deduction fails.
- if (!PartialOverloading ||
- (CanonicalBuilder.size() ==
- FunctionTemplate->getTemplateParameters()->size())) {
- if (CheckInstantiatedFunctionTemplateConstraints(
- Info.getLocation(), Specialization, CanonicalBuilder,
- Info.AssociatedConstraintsSatisfaction))
- return TDK_MiscellaneousDeductionFailure;
- if (!Info.AssociatedConstraintsSatisfaction.IsSatisfied) {
- Info.reset(Info.takeSugared(),
- TemplateArgumentList::CreateCopy(Context, CanonicalBuilder));
- return TDK_ConstraintsNotSatisfied;
- }
- }
- if (OriginalCallArgs) {
- // C++ [temp.deduct.call]p4:
- // In general, the deduction process attempts to find template argument
- // values that will make the deduced A identical to A (after the type A
- // is transformed as described above). [...]
- llvm::SmallDenseMap<std::pair<unsigned, QualType>, QualType> DeducedATypes;
- for (unsigned I = 0, N = OriginalCallArgs->size(); I != N; ++I) {
- OriginalCallArg OriginalArg = (*OriginalCallArgs)[I];
- auto ParamIdx = OriginalArg.ArgIdx;
- if (ParamIdx >= Specialization->getNumParams())
- // FIXME: This presumably means a pack ended up smaller than we
- // expected while deducing. Should this not result in deduction
- // failure? Can it even happen?
- continue;
- QualType DeducedA;
- if (!OriginalArg.DecomposedParam) {
- // P is one of the function parameters, just look up its substituted
- // type.
- DeducedA = Specialization->getParamDecl(ParamIdx)->getType();
- } else {
- // P is a decomposed element of a parameter corresponding to a
- // braced-init-list argument. Substitute back into P to find the
- // deduced A.
- QualType &CacheEntry =
- DeducedATypes[{ParamIdx, OriginalArg.OriginalParamType}];
- if (CacheEntry.isNull()) {
- ArgumentPackSubstitutionIndexRAII PackIndex(
- *this, getPackIndexForParam(*this, FunctionTemplate, SubstArgs,
- ParamIdx));
- CacheEntry =
- SubstType(OriginalArg.OriginalParamType, SubstArgs,
- Specialization->getTypeSpecStartLoc(),
- Specialization->getDeclName());
- }
- DeducedA = CacheEntry;
- }
- if (auto TDK =
- CheckOriginalCallArgDeduction(*this, Info, OriginalArg, DeducedA))
- return TDK;
- }
- }
- // If we suppressed any diagnostics while performing template argument
- // deduction, and if we haven't already instantiated this declaration,
- // keep track of these diagnostics. They'll be emitted if this specialization
- // is actually used.
- if (Info.diag_begin() != Info.diag_end()) {
- SuppressedDiagnosticsMap::iterator
- Pos = SuppressedDiagnostics.find(Specialization->getCanonicalDecl());
- if (Pos == SuppressedDiagnostics.end())
- SuppressedDiagnostics[Specialization->getCanonicalDecl()]
- .append(Info.diag_begin(), Info.diag_end());
- }
- return TDK_Success;
- }
- /// Gets the type of a function for template-argument-deducton
- /// purposes when it's considered as part of an overload set.
- static QualType GetTypeOfFunction(Sema &S, const OverloadExpr::FindResult &R,
- FunctionDecl *Fn) {
- // We may need to deduce the return type of the function now.
- if (S.getLangOpts().CPlusPlus14 && Fn->getReturnType()->isUndeducedType() &&
- S.DeduceReturnType(Fn, R.Expression->getExprLoc(), /*Diagnose*/ false))
- return {};
- if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn))
- if (Method->isInstance()) {
- // An instance method that's referenced in a form that doesn't
- // look like a member pointer is just invalid.
- if (!R.HasFormOfMemberPointer)
- return {};
- return S.Context.getMemberPointerType(Fn->getType(),
- S.Context.getTypeDeclType(Method->getParent()).getTypePtr());
- }
- if (!R.IsAddressOfOperand) return Fn->getType();
- return S.Context.getPointerType(Fn->getType());
- }
- /// Apply the deduction rules for overload sets.
- ///
- /// \return the null type if this argument should be treated as an
- /// undeduced context
- static QualType
- ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams,
- Expr *Arg, QualType ParamType,
- bool ParamWasReference) {
- OverloadExpr::FindResult R = OverloadExpr::find(Arg);
- OverloadExpr *Ovl = R.Expression;
- // C++0x [temp.deduct.call]p4
- unsigned TDF = 0;
- if (ParamWasReference)
- TDF |= TDF_ParamWithReferenceType;
- if (R.IsAddressOfOperand)
- TDF |= TDF_IgnoreQualifiers;
- // C++0x [temp.deduct.call]p6:
- // When P is a function type, pointer to function type, or pointer
- // to member function type:
- if (!ParamType->isFunctionType() &&
- !ParamType->isFunctionPointerType() &&
- !ParamType->isMemberFunctionPointerType()) {
- if (Ovl->hasExplicitTemplateArgs()) {
- // But we can still look for an explicit specialization.
- if (FunctionDecl *ExplicitSpec
- = S.ResolveSingleFunctionTemplateSpecialization(Ovl))
- return GetTypeOfFunction(S, R, ExplicitSpec);
- }
- DeclAccessPair DAP;
- if (FunctionDecl *Viable =
- S.resolveAddressOfSingleOverloadCandidate(Arg, DAP))
- return GetTypeOfFunction(S, R, Viable);
- return {};
- }
- // Gather the explicit template arguments, if any.
- TemplateArgumentListInfo ExplicitTemplateArgs;
- if (Ovl->hasExplicitTemplateArgs())
- Ovl->copyTemplateArgumentsInto(ExplicitTemplateArgs);
- QualType Match;
- for (UnresolvedSetIterator I = Ovl->decls_begin(),
- E = Ovl->decls_end(); I != E; ++I) {
- NamedDecl *D = (*I)->getUnderlyingDecl();
- if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D)) {
- // - If the argument is an overload set containing one or more
- // function templates, the parameter is treated as a
- // non-deduced context.
- if (!Ovl->hasExplicitTemplateArgs())
- return {};
- // Otherwise, see if we can resolve a function type
- FunctionDecl *Specialization = nullptr;
- TemplateDeductionInfo Info(Ovl->getNameLoc());
- if (S.DeduceTemplateArguments(FunTmpl, &ExplicitTemplateArgs,
- Specialization, Info))
- continue;
- D = Specialization;
- }
- FunctionDecl *Fn = cast<FunctionDecl>(D);
- QualType ArgType = GetTypeOfFunction(S, R, Fn);
- if (ArgType.isNull()) continue;
- // Function-to-pointer conversion.
- if (!ParamWasReference && ParamType->isPointerType() &&
- ArgType->isFunctionType())
- ArgType = S.Context.getPointerType(ArgType);
- // - If the argument is an overload set (not containing function
- // templates), trial argument deduction is attempted using each
- // of the members of the set. If deduction succeeds for only one
- // of the overload set members, that member is used as the
- // argument value for the deduction. If deduction succeeds for
- // more than one member of the overload set the parameter is
- // treated as a non-deduced context.
- // We do all of this in a fresh context per C++0x [temp.deduct.type]p2:
- // Type deduction is done independently for each P/A pair, and
- // the deduced template argument values are then combined.
- // So we do not reject deductions which were made elsewhere.
- SmallVector<DeducedTemplateArgument, 8>
- Deduced(TemplateParams->size());
- TemplateDeductionInfo Info(Ovl->getNameLoc());
- Sema::TemplateDeductionResult Result
- = DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, ParamType,
- ArgType, Info, Deduced, TDF);
- if (Result) continue;
- if (!Match.isNull())
- return {};
- Match = ArgType;
- }
- return Match;
- }
- /// Perform the adjustments to the parameter and argument types
- /// described in C++ [temp.deduct.call].
- ///
- /// \returns true if the caller should not attempt to perform any template
- /// argument deduction based on this P/A pair because the argument is an
- /// overloaded function set that could not be resolved.
- static bool AdjustFunctionParmAndArgTypesForDeduction(
- Sema &S, TemplateParameterList *TemplateParams, unsigned FirstInnerIndex,
- QualType &ParamType, QualType &ArgType, Expr *Arg, unsigned &TDF) {
- // C++0x [temp.deduct.call]p3:
- // If P is a cv-qualified type, the top level cv-qualifiers of P's type
- // are ignored for type deduction.
- if (ParamType.hasQualifiers())
- ParamType = ParamType.getUnqualifiedType();
- // [...] If P is a reference type, the type referred to by P is
- // used for type deduction.
- const ReferenceType *ParamRefType = ParamType->getAs<ReferenceType>();
- if (ParamRefType)
- ParamType = ParamRefType->getPointeeType();
- // Overload sets usually make this parameter an undeduced context,
- // but there are sometimes special circumstances. Typically
- // involving a template-id-expr.
- if (ArgType == S.Context.OverloadTy) {
- ArgType = ResolveOverloadForDeduction(S, TemplateParams,
- Arg, ParamType,
- ParamRefType != nullptr);
- if (ArgType.isNull())
- return true;
- }
- if (ParamRefType) {
- // If the argument has incomplete array type, try to complete its type.
- if (ArgType->isIncompleteArrayType())
- ArgType = S.getCompletedType(Arg);
- // C++1z [temp.deduct.call]p3:
- // If P is a forwarding reference and the argument is an lvalue, the type
- // "lvalue reference to A" is used in place of A for type deduction.
- if (isForwardingReference(QualType(ParamRefType, 0), FirstInnerIndex) &&
- Arg->isLValue()) {
- if (S.getLangOpts().OpenCL && !ArgType.hasAddressSpace())
- ArgType = S.Context.getAddrSpaceQualType(
- ArgType, S.Context.getDefaultOpenCLPointeeAddrSpace());
- ArgType = S.Context.getLValueReferenceType(ArgType);
- }
- } else {
- // C++ [temp.deduct.call]p2:
- // If P is not a reference type:
- // - If A is an array type, the pointer type produced by the
- // array-to-pointer standard conversion (4.2) is used in place of
- // A for type deduction; otherwise,
- // - If A is a function type, the pointer type produced by the
- // function-to-pointer standard conversion (4.3) is used in place
- // of A for type deduction; otherwise,
- if (ArgType->canDecayToPointerType())
- ArgType = S.Context.getDecayedType(ArgType);
- else {
- // - If A is a cv-qualified type, the top level cv-qualifiers of A's
- // type are ignored for type deduction.
- ArgType = ArgType.getUnqualifiedType();
- }
- }
- // C++0x [temp.deduct.call]p4:
- // In general, the deduction process attempts to find template argument
- // values that will make the deduced A identical to A (after the type A
- // is transformed as described above). [...]
- TDF = TDF_SkipNonDependent;
- // - If the original P is a reference type, the deduced A (i.e., the
- // type referred to by the reference) can be more cv-qualified than
- // the transformed A.
- if (ParamRefType)
- TDF |= TDF_ParamWithReferenceType;
- // - The transformed A can be another pointer or pointer to member
- // type that can be converted to the deduced A via a qualification
- // conversion (4.4).
- if (ArgType->isPointerType() || ArgType->isMemberPointerType() ||
- ArgType->isObjCObjectPointerType())
- TDF |= TDF_IgnoreQualifiers;
- // - If P is a class and P has the form simple-template-id, then the
- // transformed A can be a derived class of the deduced A. Likewise,
- // if P is a pointer to a class of the form simple-template-id, the
- // transformed A can be a pointer to a derived class pointed to by
- // the deduced A.
- if (isSimpleTemplateIdType(ParamType) ||
- (isa<PointerType>(ParamType) &&
- isSimpleTemplateIdType(
- ParamType->castAs<PointerType>()->getPointeeType())))
- TDF |= TDF_DerivedClass;
- return false;
- }
- static bool
- hasDeducibleTemplateParameters(Sema &S, FunctionTemplateDecl *FunctionTemplate,
- QualType T);
- static Sema::TemplateDeductionResult DeduceTemplateArgumentsFromCallArgument(
- Sema &S, TemplateParameterList *TemplateParams, unsigned FirstInnerIndex,
- QualType ParamType, Expr *Arg, TemplateDeductionInfo &Info,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced,
- SmallVectorImpl<Sema::OriginalCallArg> &OriginalCallArgs,
- bool DecomposedParam, unsigned ArgIdx, unsigned TDF);
- /// Attempt template argument deduction from an initializer list
- /// deemed to be an argument in a function call.
- static Sema::TemplateDeductionResult DeduceFromInitializerList(
- Sema &S, TemplateParameterList *TemplateParams, QualType AdjustedParamType,
- InitListExpr *ILE, TemplateDeductionInfo &Info,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced,
- SmallVectorImpl<Sema::OriginalCallArg> &OriginalCallArgs, unsigned ArgIdx,
- unsigned TDF) {
- // C++ [temp.deduct.call]p1: (CWG 1591)
- // If removing references and cv-qualifiers from P gives
- // std::initializer_list<P0> or P0[N] for some P0 and N and the argument is
- // a non-empty initializer list, then deduction is performed instead for
- // each element of the initializer list, taking P0 as a function template
- // parameter type and the initializer element as its argument
- //
- // We've already removed references and cv-qualifiers here.
- if (!ILE->getNumInits())
- return Sema::TDK_Success;
- QualType ElTy;
- auto *ArrTy = S.Context.getAsArrayType(AdjustedParamType);
- if (ArrTy)
- ElTy = ArrTy->getElementType();
- else if (!S.isStdInitializerList(AdjustedParamType, &ElTy)) {
- // Otherwise, an initializer list argument causes the parameter to be
- // considered a non-deduced context
- return Sema::TDK_Success;
- }
- // Resolving a core issue: a braced-init-list containing any designators is
- // a non-deduced context.
- for (Expr *E : ILE->inits())
- if (isa<DesignatedInitExpr>(E))
- return Sema::TDK_Success;
- // Deduction only needs to be done for dependent types.
- if (ElTy->isDependentType()) {
- for (Expr *E : ILE->inits()) {
- if (auto Result = DeduceTemplateArgumentsFromCallArgument(
- S, TemplateParams, 0, ElTy, E, Info, Deduced, OriginalCallArgs, true,
- ArgIdx, TDF))
- return Result;
- }
- }
- // in the P0[N] case, if N is a non-type template parameter, N is deduced
- // from the length of the initializer list.
- if (auto *DependentArrTy = dyn_cast_or_null<DependentSizedArrayType>(ArrTy)) {
- // Determine the array bound is something we can deduce.
- if (const NonTypeTemplateParmDecl *NTTP =
- getDeducedParameterFromExpr(Info, DependentArrTy->getSizeExpr())) {
- // We can perform template argument deduction for the given non-type
- // template parameter.
- // C++ [temp.deduct.type]p13:
- // The type of N in the type T[N] is std::size_t.
- QualType T = S.Context.getSizeType();
- llvm::APInt Size(S.Context.getIntWidth(T), ILE->getNumInits());
- if (auto Result = DeduceNonTypeTemplateArgument(
- S, TemplateParams, NTTP, llvm::APSInt(Size), T,
- /*ArrayBound=*/true, Info, Deduced))
- return Result;
- }
- }
- return Sema::TDK_Success;
- }
- /// Perform template argument deduction per [temp.deduct.call] for a
- /// single parameter / argument pair.
- static Sema::TemplateDeductionResult DeduceTemplateArgumentsFromCallArgument(
- Sema &S, TemplateParameterList *TemplateParams, unsigned FirstInnerIndex,
- QualType ParamType, Expr *Arg, TemplateDeductionInfo &Info,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced,
- SmallVectorImpl<Sema::OriginalCallArg> &OriginalCallArgs,
- bool DecomposedParam, unsigned ArgIdx, unsigned TDF) {
- QualType ArgType = Arg->getType();
- QualType OrigParamType = ParamType;
- // If P is a reference type [...]
- // If P is a cv-qualified type [...]
- if (AdjustFunctionParmAndArgTypesForDeduction(
- S, TemplateParams, FirstInnerIndex, ParamType, ArgType, Arg, TDF))
- return Sema::TDK_Success;
- // If [...] the argument is a non-empty initializer list [...]
- if (InitListExpr *ILE = dyn_cast<InitListExpr>(Arg))
- return DeduceFromInitializerList(S, TemplateParams, ParamType, ILE, Info,
- Deduced, OriginalCallArgs, ArgIdx, TDF);
- // [...] the deduction process attempts to find template argument values
- // that will make the deduced A identical to A
- //
- // Keep track of the argument type and corresponding parameter index,
- // so we can check for compatibility between the deduced A and A.
- OriginalCallArgs.push_back(
- Sema::OriginalCallArg(OrigParamType, DecomposedParam, ArgIdx, ArgType));
- return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, ParamType,
- ArgType, Info, Deduced, TDF);
- }
- /// Perform template argument deduction from a function call
- /// (C++ [temp.deduct.call]).
- ///
- /// \param FunctionTemplate the function template for which we are performing
- /// template argument deduction.
- ///
- /// \param ExplicitTemplateArgs the explicit template arguments provided
- /// for this call.
- ///
- /// \param Args the function call arguments
- ///
- /// \param Specialization if template argument deduction was successful,
- /// this will be set to the function template specialization produced by
- /// template argument deduction.
- ///
- /// \param Info the argument will be updated to provide additional information
- /// about template argument deduction.
- ///
- /// \param CheckNonDependent A callback to invoke to check conversions for
- /// non-dependent parameters, between deduction and substitution, per DR1391.
- /// If this returns true, substitution will be skipped and we return
- /// TDK_NonDependentConversionFailure. The callback is passed the parameter
- /// types (after substituting explicit template arguments).
- ///
- /// \returns the result of template argument deduction.
- Sema::TemplateDeductionResult Sema::DeduceTemplateArguments(
- FunctionTemplateDecl *FunctionTemplate,
- TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> Args,
- FunctionDecl *&Specialization, TemplateDeductionInfo &Info,
- bool PartialOverloading,
- llvm::function_ref<bool(ArrayRef<QualType>)> CheckNonDependent) {
- if (FunctionTemplate->isInvalidDecl())
- return TDK_Invalid;
- FunctionDecl *Function = FunctionTemplate->getTemplatedDecl();
- unsigned NumParams = Function->getNumParams();
- unsigned FirstInnerIndex = getFirstInnerIndex(FunctionTemplate);
- // C++ [temp.deduct.call]p1:
- // Template argument deduction is done by comparing each function template
- // parameter type (call it P) with the type of the corresponding argument
- // of the call (call it A) as described below.
- if (Args.size() < Function->getMinRequiredArguments() && !PartialOverloading)
- return TDK_TooFewArguments;
- else if (TooManyArguments(NumParams, Args.size(), PartialOverloading)) {
- const auto *Proto = Function->getType()->castAs<FunctionProtoType>();
- if (Proto->isTemplateVariadic())
- /* Do nothing */;
- else if (!Proto->isVariadic())
- return TDK_TooManyArguments;
- }
- // The types of the parameters from which we will perform template argument
- // deduction.
- LocalInstantiationScope InstScope(*this);
- TemplateParameterList *TemplateParams
- = FunctionTemplate->getTemplateParameters();
- SmallVector<DeducedTemplateArgument, 4> Deduced;
- SmallVector<QualType, 8> ParamTypes;
- unsigned NumExplicitlySpecified = 0;
- if (ExplicitTemplateArgs) {
- TemplateDeductionResult Result;
- runWithSufficientStackSpace(Info.getLocation(), [&] {
- Result = SubstituteExplicitTemplateArguments(
- FunctionTemplate, *ExplicitTemplateArgs, Deduced, ParamTypes, nullptr,
- Info);
- });
- if (Result)
- return Result;
- NumExplicitlySpecified = Deduced.size();
- } else {
- // Just fill in the parameter types from the function declaration.
- for (unsigned I = 0; I != NumParams; ++I)
- ParamTypes.push_back(Function->getParamDecl(I)->getType());
- }
- SmallVector<OriginalCallArg, 8> OriginalCallArgs;
- // Deduce an argument of type ParamType from an expression with index ArgIdx.
- auto DeduceCallArgument = [&](QualType ParamType, unsigned ArgIdx) {
- // C++ [demp.deduct.call]p1: (DR1391)
- // Template argument deduction is done by comparing each function template
- // parameter that contains template-parameters that participate in
- // template argument deduction ...
- if (!hasDeducibleTemplateParameters(*this, FunctionTemplate, ParamType))
- return Sema::TDK_Success;
- // ... with the type of the corresponding argument
- return DeduceTemplateArgumentsFromCallArgument(
- *this, TemplateParams, FirstInnerIndex, ParamType, Args[ArgIdx], Info, Deduced,
- OriginalCallArgs, /*Decomposed*/false, ArgIdx, /*TDF*/ 0);
- };
- // Deduce template arguments from the function parameters.
- Deduced.resize(TemplateParams->size());
- SmallVector<QualType, 8> ParamTypesForArgChecking;
- for (unsigned ParamIdx = 0, NumParamTypes = ParamTypes.size(), ArgIdx = 0;
- ParamIdx != NumParamTypes; ++ParamIdx) {
- QualType ParamType = ParamTypes[ParamIdx];
- const PackExpansionType *ParamExpansion =
- dyn_cast<PackExpansionType>(ParamType);
- if (!ParamExpansion) {
- // Simple case: matching a function parameter to a function argument.
- if (ArgIdx >= Args.size())
- break;
- ParamTypesForArgChecking.push_back(ParamType);
- if (auto Result = DeduceCallArgument(ParamType, ArgIdx++))
- return Result;
- continue;
- }
- QualType ParamPattern = ParamExpansion->getPattern();
- PackDeductionScope PackScope(*this, TemplateParams, Deduced, Info,
- ParamPattern);
- // C++0x [temp.deduct.call]p1:
- // For a function parameter pack that occurs at the end of the
- // parameter-declaration-list, the type A of each remaining argument of
- // the call is compared with the type P of the declarator-id of the
- // function parameter pack. Each comparison deduces template arguments
- // for subsequent positions in the template parameter packs expanded by
- // the function parameter pack. When a function parameter pack appears
- // in a non-deduced context [not at the end of the list], the type of
- // that parameter pack is never deduced.
- //
- // FIXME: The above rule allows the size of the parameter pack to change
- // after we skip it (in the non-deduced case). That makes no sense, so
- // we instead notionally deduce the pack against N arguments, where N is
- // the length of the explicitly-specified pack if it's expanded by the
- // parameter pack and 0 otherwise, and we treat each deduction as a
- // non-deduced context.
- if (ParamIdx + 1 == NumParamTypes || PackScope.hasFixedArity()) {
- for (; ArgIdx < Args.size() && PackScope.hasNextElement();
- PackScope.nextPackElement(), ++ArgIdx) {
- ParamTypesForArgChecking.push_back(ParamPattern);
- if (auto Result = DeduceCallArgument(ParamPattern, ArgIdx))
- return Result;
- }
- } else {
- // If the parameter type contains an explicitly-specified pack that we
- // could not expand, skip the number of parameters notionally created
- // by the expansion.
- std::optional<unsigned> NumExpansions =
- ParamExpansion->getNumExpansions();
- if (NumExpansions && !PackScope.isPartiallyExpanded()) {
- for (unsigned I = 0; I != *NumExpansions && ArgIdx < Args.size();
- ++I, ++ArgIdx) {
- ParamTypesForArgChecking.push_back(ParamPattern);
- // FIXME: Should we add OriginalCallArgs for these? What if the
- // corresponding argument is a list?
- PackScope.nextPackElement();
- }
- }
- }
- // Build argument packs for each of the parameter packs expanded by this
- // pack expansion.
- if (auto Result = PackScope.finish())
- return Result;
- }
- // Capture the context in which the function call is made. This is the context
- // that is needed when the accessibility of template arguments is checked.
- DeclContext *CallingCtx = CurContext;
- TemplateDeductionResult Result;
- runWithSufficientStackSpace(Info.getLocation(), [&] {
- Result = FinishTemplateArgumentDeduction(
- FunctionTemplate, Deduced, NumExplicitlySpecified, Specialization, Info,
- &OriginalCallArgs, PartialOverloading, [&, CallingCtx]() {
- ContextRAII SavedContext(*this, CallingCtx);
- return CheckNonDependent(ParamTypesForArgChecking);
- });
- });
- return Result;
- }
- QualType Sema::adjustCCAndNoReturn(QualType ArgFunctionType,
- QualType FunctionType,
- bool AdjustExceptionSpec) {
- if (ArgFunctionType.isNull())
- return ArgFunctionType;
- const auto *FunctionTypeP = FunctionType->castAs<FunctionProtoType>();
- const auto *ArgFunctionTypeP = ArgFunctionType->castAs<FunctionProtoType>();
- FunctionProtoType::ExtProtoInfo EPI = ArgFunctionTypeP->getExtProtoInfo();
- bool Rebuild = false;
- CallingConv CC = FunctionTypeP->getCallConv();
- if (EPI.ExtInfo.getCC() != CC) {
- EPI.ExtInfo = EPI.ExtInfo.withCallingConv(CC);
- Rebuild = true;
- }
- bool NoReturn = FunctionTypeP->getNoReturnAttr();
- if (EPI.ExtInfo.getNoReturn() != NoReturn) {
- EPI.ExtInfo = EPI.ExtInfo.withNoReturn(NoReturn);
- Rebuild = true;
- }
- if (AdjustExceptionSpec && (FunctionTypeP->hasExceptionSpec() ||
- ArgFunctionTypeP->hasExceptionSpec())) {
- EPI.ExceptionSpec = FunctionTypeP->getExtProtoInfo().ExceptionSpec;
- Rebuild = true;
- }
- if (!Rebuild)
- return ArgFunctionType;
- return Context.getFunctionType(ArgFunctionTypeP->getReturnType(),
- ArgFunctionTypeP->getParamTypes(), EPI);
- }
- /// Deduce template arguments when taking the address of a function
- /// template (C++ [temp.deduct.funcaddr]) or matching a specialization to
- /// a template.
- ///
- /// \param FunctionTemplate the function template for which we are performing
- /// template argument deduction.
- ///
- /// \param ExplicitTemplateArgs the explicitly-specified template
- /// arguments.
- ///
- /// \param ArgFunctionType the function type that will be used as the
- /// "argument" type (A) when performing template argument deduction from the
- /// function template's function type. This type may be NULL, if there is no
- /// argument type to compare against, in C++0x [temp.arg.explicit]p3.
- ///
- /// \param Specialization if template argument deduction was successful,
- /// this will be set to the function template specialization produced by
- /// template argument deduction.
- ///
- /// \param Info the argument will be updated to provide additional information
- /// about template argument deduction.
- ///
- /// \param IsAddressOfFunction If \c true, we are deducing as part of taking
- /// the address of a function template per [temp.deduct.funcaddr] and
- /// [over.over]. If \c false, we are looking up a function template
- /// specialization based on its signature, per [temp.deduct.decl].
- ///
- /// \returns the result of template argument deduction.
- Sema::TemplateDeductionResult Sema::DeduceTemplateArguments(
- FunctionTemplateDecl *FunctionTemplate,
- TemplateArgumentListInfo *ExplicitTemplateArgs, QualType ArgFunctionType,
- FunctionDecl *&Specialization, TemplateDeductionInfo &Info,
- bool IsAddressOfFunction) {
- if (FunctionTemplate->isInvalidDecl())
- return TDK_Invalid;
- FunctionDecl *Function = FunctionTemplate->getTemplatedDecl();
- TemplateParameterList *TemplateParams
- = FunctionTemplate->getTemplateParameters();
- QualType FunctionType = Function->getType();
- // Substitute any explicit template arguments.
- LocalInstantiationScope InstScope(*this);
- SmallVector<DeducedTemplateArgument, 4> Deduced;
- unsigned NumExplicitlySpecified = 0;
- SmallVector<QualType, 4> ParamTypes;
- if (ExplicitTemplateArgs) {
- TemplateDeductionResult Result;
- runWithSufficientStackSpace(Info.getLocation(), [&] {
- Result = SubstituteExplicitTemplateArguments(
- FunctionTemplate, *ExplicitTemplateArgs, Deduced, ParamTypes,
- &FunctionType, Info);
- });
- if (Result)
- return Result;
- NumExplicitlySpecified = Deduced.size();
- }
- // When taking the address of a function, we require convertibility of
- // the resulting function type. Otherwise, we allow arbitrary mismatches
- // of calling convention and noreturn.
- if (!IsAddressOfFunction)
- ArgFunctionType = adjustCCAndNoReturn(ArgFunctionType, FunctionType,
- /*AdjustExceptionSpec*/false);
- // Unevaluated SFINAE context.
- EnterExpressionEvaluationContext Unevaluated(
- *this, Sema::ExpressionEvaluationContext::Unevaluated);
- SFINAETrap Trap(*this);
- Deduced.resize(TemplateParams->size());
- // If the function has a deduced return type, substitute it for a dependent
- // type so that we treat it as a non-deduced context in what follows. If we
- // are looking up by signature, the signature type should also have a deduced
- // return type, which we instead expect to exactly match.
- bool HasDeducedReturnType = false;
- if (getLangOpts().CPlusPlus14 && IsAddressOfFunction &&
- Function->getReturnType()->getContainedAutoType()) {
- FunctionType = SubstAutoTypeDependent(FunctionType);
- HasDeducedReturnType = true;
- }
- if (!ArgFunctionType.isNull() && !FunctionType.isNull()) {
- unsigned TDF =
- TDF_TopLevelParameterTypeList | TDF_AllowCompatibleFunctionType;
- // Deduce template arguments from the function type.
- if (TemplateDeductionResult Result
- = DeduceTemplateArgumentsByTypeMatch(*this, TemplateParams,
- FunctionType, ArgFunctionType,
- Info, Deduced, TDF))
- return Result;
- }
- TemplateDeductionResult Result;
- runWithSufficientStackSpace(Info.getLocation(), [&] {
- Result = FinishTemplateArgumentDeduction(FunctionTemplate, Deduced,
- NumExplicitlySpecified,
- Specialization, Info);
- });
- if (Result)
- return Result;
- // If the function has a deduced return type, deduce it now, so we can check
- // that the deduced function type matches the requested type.
- if (HasDeducedReturnType &&
- Specialization->getReturnType()->isUndeducedType() &&
- DeduceReturnType(Specialization, Info.getLocation(), false))
- return TDK_MiscellaneousDeductionFailure;
- // If the function has a dependent exception specification, resolve it now,
- // so we can check that the exception specification matches.
- auto *SpecializationFPT =
- Specialization->getType()->castAs<FunctionProtoType>();
- if (getLangOpts().CPlusPlus17 &&
- isUnresolvedExceptionSpec(SpecializationFPT->getExceptionSpecType()) &&
- !ResolveExceptionSpec(Info.getLocation(), SpecializationFPT))
- return TDK_MiscellaneousDeductionFailure;
- // Adjust the exception specification of the argument to match the
- // substituted and resolved type we just formed. (Calling convention and
- // noreturn can't be dependent, so we don't actually need this for them
- // right now.)
- QualType SpecializationType = Specialization->getType();
- if (!IsAddressOfFunction)
- ArgFunctionType = adjustCCAndNoReturn(ArgFunctionType, SpecializationType,
- /*AdjustExceptionSpec*/true);
- // If the requested function type does not match the actual type of the
- // specialization with respect to arguments of compatible pointer to function
- // types, template argument deduction fails.
- if (!ArgFunctionType.isNull()) {
- if (IsAddressOfFunction &&
- !isSameOrCompatibleFunctionType(
- Context.getCanonicalType(SpecializationType),
- Context.getCanonicalType(ArgFunctionType)))
- return TDK_MiscellaneousDeductionFailure;
- if (!IsAddressOfFunction &&
- !Context.hasSameType(SpecializationType, ArgFunctionType))
- return TDK_MiscellaneousDeductionFailure;
- }
- return TDK_Success;
- }
- /// Deduce template arguments for a templated conversion
- /// function (C++ [temp.deduct.conv]) and, if successful, produce a
- /// conversion function template specialization.
- Sema::TemplateDeductionResult
- Sema::DeduceTemplateArguments(FunctionTemplateDecl *ConversionTemplate,
- QualType ToType,
- CXXConversionDecl *&Specialization,
- TemplateDeductionInfo &Info) {
- if (ConversionTemplate->isInvalidDecl())
- return TDK_Invalid;
- CXXConversionDecl *ConversionGeneric
- = cast<CXXConversionDecl>(ConversionTemplate->getTemplatedDecl());
- QualType FromType = ConversionGeneric->getConversionType();
- // Canonicalize the types for deduction.
- QualType P = Context.getCanonicalType(FromType);
- QualType A = Context.getCanonicalType(ToType);
- // C++0x [temp.deduct.conv]p2:
- // If P is a reference type, the type referred to by P is used for
- // type deduction.
- if (const ReferenceType *PRef = P->getAs<ReferenceType>())
- P = PRef->getPointeeType();
- // C++0x [temp.deduct.conv]p4:
- // [...] If A is a reference type, the type referred to by A is used
- // for type deduction.
- if (const ReferenceType *ARef = A->getAs<ReferenceType>()) {
- A = ARef->getPointeeType();
- // We work around a defect in the standard here: cv-qualifiers are also
- // removed from P and A in this case, unless P was a reference type. This
- // seems to mostly match what other compilers are doing.
- if (!FromType->getAs<ReferenceType>()) {
- A = A.getUnqualifiedType();
- P = P.getUnqualifiedType();
- }
- // C++ [temp.deduct.conv]p3:
- //
- // If A is not a reference type:
- } else {
- assert(!A->isReferenceType() && "Reference types were handled above");
- // - If P is an array type, the pointer type produced by the
- // array-to-pointer standard conversion (4.2) is used in place
- // of P for type deduction; otherwise,
- if (P->isArrayType())
- P = Context.getArrayDecayedType(P);
- // - If P is a function type, the pointer type produced by the
- // function-to-pointer standard conversion (4.3) is used in
- // place of P for type deduction; otherwise,
- else if (P->isFunctionType())
- P = Context.getPointerType(P);
- // - If P is a cv-qualified type, the top level cv-qualifiers of
- // P's type are ignored for type deduction.
- else
- P = P.getUnqualifiedType();
- // C++0x [temp.deduct.conv]p4:
- // If A is a cv-qualified type, the top level cv-qualifiers of A's
- // type are ignored for type deduction. If A is a reference type, the type
- // referred to by A is used for type deduction.
- A = A.getUnqualifiedType();
- }
- // Unevaluated SFINAE context.
- EnterExpressionEvaluationContext Unevaluated(
- *this, Sema::ExpressionEvaluationContext::Unevaluated);
- SFINAETrap Trap(*this);
- // C++ [temp.deduct.conv]p1:
- // Template argument deduction is done by comparing the return
- // type of the template conversion function (call it P) with the
- // type that is required as the result of the conversion (call it
- // A) as described in 14.8.2.4.
- TemplateParameterList *TemplateParams
- = ConversionTemplate->getTemplateParameters();
- SmallVector<DeducedTemplateArgument, 4> Deduced;
- Deduced.resize(TemplateParams->size());
- // C++0x [temp.deduct.conv]p4:
- // In general, the deduction process attempts to find template
- // argument values that will make the deduced A identical to
- // A. However, there are two cases that allow a difference:
- unsigned TDF = 0;
- // - If the original A is a reference type, A can be more
- // cv-qualified than the deduced A (i.e., the type referred to
- // by the reference)
- if (ToType->isReferenceType())
- TDF |= TDF_ArgWithReferenceType;
- // - The deduced A can be another pointer or pointer to member
- // type that can be converted to A via a qualification
- // conversion.
- //
- // (C++0x [temp.deduct.conv]p6 clarifies that this only happens when
- // both P and A are pointers or member pointers. In this case, we
- // just ignore cv-qualifiers completely).
- if ((P->isPointerType() && A->isPointerType()) ||
- (P->isMemberPointerType() && A->isMemberPointerType()))
- TDF |= TDF_IgnoreQualifiers;
- if (TemplateDeductionResult Result
- = DeduceTemplateArgumentsByTypeMatch(*this, TemplateParams,
- P, A, Info, Deduced, TDF))
- return Result;
- // Create an Instantiation Scope for finalizing the operator.
- LocalInstantiationScope InstScope(*this);
- // Finish template argument deduction.
- FunctionDecl *ConversionSpecialized = nullptr;
- TemplateDeductionResult Result;
- runWithSufficientStackSpace(Info.getLocation(), [&] {
- Result = FinishTemplateArgumentDeduction(ConversionTemplate, Deduced, 0,
- ConversionSpecialized, Info);
- });
- Specialization = cast_or_null<CXXConversionDecl>(ConversionSpecialized);
- return Result;
- }
- /// Deduce template arguments for a function template when there is
- /// nothing to deduce against (C++0x [temp.arg.explicit]p3).
- ///
- /// \param FunctionTemplate the function template for which we are performing
- /// template argument deduction.
- ///
- /// \param ExplicitTemplateArgs the explicitly-specified template
- /// arguments.
- ///
- /// \param Specialization if template argument deduction was successful,
- /// this will be set to the function template specialization produced by
- /// template argument deduction.
- ///
- /// \param Info the argument will be updated to provide additional information
- /// about template argument deduction.
- ///
- /// \param IsAddressOfFunction If \c true, we are deducing as part of taking
- /// the address of a function template in a context where we do not have a
- /// target type, per [over.over]. If \c false, we are looking up a function
- /// template specialization based on its signature, which only happens when
- /// deducing a function parameter type from an argument that is a template-id
- /// naming a function template specialization.
- ///
- /// \returns the result of template argument deduction.
- Sema::TemplateDeductionResult Sema::DeduceTemplateArguments(
- FunctionTemplateDecl *FunctionTemplate,
- TemplateArgumentListInfo *ExplicitTemplateArgs,
- FunctionDecl *&Specialization, TemplateDeductionInfo &Info,
- bool IsAddressOfFunction) {
- return DeduceTemplateArguments(FunctionTemplate, ExplicitTemplateArgs,
- QualType(), Specialization, Info,
- IsAddressOfFunction);
- }
- namespace {
- struct DependentAuto { bool IsPack; };
- /// Substitute the 'auto' specifier or deduced template specialization type
- /// specifier within a type for a given replacement type.
- class SubstituteDeducedTypeTransform :
- public TreeTransform<SubstituteDeducedTypeTransform> {
- QualType Replacement;
- bool ReplacementIsPack;
- bool UseTypeSugar;
- public:
- SubstituteDeducedTypeTransform(Sema &SemaRef, DependentAuto DA)
- : TreeTransform<SubstituteDeducedTypeTransform>(SemaRef),
- ReplacementIsPack(DA.IsPack), UseTypeSugar(true) {}
- SubstituteDeducedTypeTransform(Sema &SemaRef, QualType Replacement,
- bool UseTypeSugar = true)
- : TreeTransform<SubstituteDeducedTypeTransform>(SemaRef),
- Replacement(Replacement), ReplacementIsPack(false),
- UseTypeSugar(UseTypeSugar) {}
- QualType TransformDesugared(TypeLocBuilder &TLB, DeducedTypeLoc TL) {
- assert(isa<TemplateTypeParmType>(Replacement) &&
- "unexpected unsugared replacement kind");
- QualType Result = Replacement;
- TemplateTypeParmTypeLoc NewTL = TLB.push<TemplateTypeParmTypeLoc>(Result);
- NewTL.setNameLoc(TL.getNameLoc());
- return Result;
- }
- QualType TransformAutoType(TypeLocBuilder &TLB, AutoTypeLoc TL) {
- // If we're building the type pattern to deduce against, don't wrap the
- // substituted type in an AutoType. Certain template deduction rules
- // apply only when a template type parameter appears directly (and not if
- // the parameter is found through desugaring). For instance:
- // auto &&lref = lvalue;
- // must transform into "rvalue reference to T" not "rvalue reference to
- // auto type deduced as T" in order for [temp.deduct.call]p3 to apply.
- //
- // FIXME: Is this still necessary?
- if (!UseTypeSugar)
- return TransformDesugared(TLB, TL);
- QualType Result = SemaRef.Context.getAutoType(
- Replacement, TL.getTypePtr()->getKeyword(), Replacement.isNull(),
- ReplacementIsPack, TL.getTypePtr()->getTypeConstraintConcept(),
- TL.getTypePtr()->getTypeConstraintArguments());
- auto NewTL = TLB.push<AutoTypeLoc>(Result);
- NewTL.copy(TL);
- return Result;
- }
- QualType TransformDeducedTemplateSpecializationType(
- TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
- if (!UseTypeSugar)
- return TransformDesugared(TLB, TL);
- QualType Result = SemaRef.Context.getDeducedTemplateSpecializationType(
- TL.getTypePtr()->getTemplateName(),
- Replacement, Replacement.isNull());
- auto NewTL = TLB.push<DeducedTemplateSpecializationTypeLoc>(Result);
- NewTL.setNameLoc(TL.getNameLoc());
- return Result;
- }
- ExprResult TransformLambdaExpr(LambdaExpr *E) {
- // Lambdas never need to be transformed.
- return E;
- }
- QualType Apply(TypeLoc TL) {
- // Create some scratch storage for the transformed type locations.
- // FIXME: We're just going to throw this information away. Don't build it.
- TypeLocBuilder TLB;
- TLB.reserve(TL.getFullDataSize());
- return TransformType(TLB, TL);
- }
- };
- } // namespace
- static bool CheckDeducedPlaceholderConstraints(Sema &S, const AutoType &Type,
- AutoTypeLoc TypeLoc,
- QualType Deduced) {
- ConstraintSatisfaction Satisfaction;
- ConceptDecl *Concept = Type.getTypeConstraintConcept();
- TemplateArgumentListInfo TemplateArgs(TypeLoc.getLAngleLoc(),
- TypeLoc.getRAngleLoc());
- TemplateArgs.addArgument(
- TemplateArgumentLoc(TemplateArgument(Deduced),
- S.Context.getTrivialTypeSourceInfo(
- Deduced, TypeLoc.getNameLoc())));
- for (unsigned I = 0, C = TypeLoc.getNumArgs(); I != C; ++I)
- TemplateArgs.addArgument(TypeLoc.getArgLoc(I));
- llvm::SmallVector<TemplateArgument, 4> SugaredConverted, CanonicalConverted;
- if (S.CheckTemplateArgumentList(Concept, SourceLocation(), TemplateArgs,
- /*PartialTemplateArgs=*/false,
- SugaredConverted, CanonicalConverted))
- return true;
- MultiLevelTemplateArgumentList MLTAL(Concept, CanonicalConverted,
- /*Final=*/false);
- if (S.CheckConstraintSatisfaction(Concept, {Concept->getConstraintExpr()},
- MLTAL, TypeLoc.getLocalSourceRange(),
- Satisfaction))
- return true;
- if (!Satisfaction.IsSatisfied) {
- std::string Buf;
- llvm::raw_string_ostream OS(Buf);
- OS << "'" << Concept->getName();
- if (TypeLoc.hasExplicitTemplateArgs()) {
- printTemplateArgumentList(
- OS, Type.getTypeConstraintArguments(), S.getPrintingPolicy(),
- Type.getTypeConstraintConcept()->getTemplateParameters());
- }
- OS << "'";
- OS.flush();
- S.Diag(TypeLoc.getConceptNameLoc(),
- diag::err_placeholder_constraints_not_satisfied)
- << Deduced << Buf << TypeLoc.getLocalSourceRange();
- S.DiagnoseUnsatisfiedConstraint(Satisfaction);
- return true;
- }
- return false;
- }
- /// Deduce the type for an auto type-specifier (C++11 [dcl.spec.auto]p6)
- ///
- /// Note that this is done even if the initializer is dependent. (This is
- /// necessary to support partial ordering of templates using 'auto'.)
- /// A dependent type will be produced when deducing from a dependent type.
- ///
- /// \param Type the type pattern using the auto type-specifier.
- /// \param Init the initializer for the variable whose type is to be deduced.
- /// \param Result if type deduction was successful, this will be set to the
- /// deduced type.
- /// \param Info the argument will be updated to provide additional information
- /// about template argument deduction.
- /// \param DependentDeduction Set if we should permit deduction in
- /// dependent cases. This is necessary for template partial ordering with
- /// 'auto' template parameters. The template parameter depth to be used
- /// should be specified in the 'Info' parameter.
- /// \param IgnoreConstraints Set if we should not fail if the deduced type does
- /// not satisfy the type-constraint in the auto type.
- Sema::TemplateDeductionResult Sema::DeduceAutoType(TypeLoc Type, Expr *Init,
- QualType &Result,
- TemplateDeductionInfo &Info,
- bool DependentDeduction,
- bool IgnoreConstraints) {
- assert(DependentDeduction || Info.getDeducedDepth() == 0);
- if (Init->containsErrors())
- return TDK_AlreadyDiagnosed;
- const AutoType *AT = Type.getType()->getContainedAutoType();
- assert(AT);
- if (Init->getType()->isNonOverloadPlaceholderType() || AT->isDecltypeAuto()) {
- ExprResult NonPlaceholder = CheckPlaceholderExpr(Init);
- if (NonPlaceholder.isInvalid())
- return TDK_AlreadyDiagnosed;
- Init = NonPlaceholder.get();
- }
- DependentAuto DependentResult = {
- /*.IsPack = */ (bool)Type.getAs<PackExpansionTypeLoc>()};
- if (!DependentDeduction &&
- (Type.getType()->isDependentType() || Init->isTypeDependent() ||
- Init->containsUnexpandedParameterPack())) {
- Result = SubstituteDeducedTypeTransform(*this, DependentResult).Apply(Type);
- assert(!Result.isNull() && "substituting DependentTy can't fail");
- return TDK_Success;
- }
- auto *InitList = dyn_cast<InitListExpr>(Init);
- if (!getLangOpts().CPlusPlus && InitList) {
- Diag(Init->getBeginLoc(), diag::err_auto_init_list_from_c);
- return TDK_AlreadyDiagnosed;
- }
- // Deduce type of TemplParam in Func(Init)
- SmallVector<DeducedTemplateArgument, 1> Deduced;
- Deduced.resize(1);
- // If deduction failed, don't diagnose if the initializer is dependent; it
- // might acquire a matching type in the instantiation.
- auto DeductionFailed = [&](TemplateDeductionResult TDK) {
- if (Init->isTypeDependent()) {
- Result =
- SubstituteDeducedTypeTransform(*this, DependentResult).Apply(Type);
- assert(!Result.isNull() && "substituting DependentTy can't fail");
- return TDK_Success;
- }
- return TDK;
- };
- SmallVector<OriginalCallArg, 4> OriginalCallArgs;
- QualType DeducedType;
- // If this is a 'decltype(auto)' specifier, do the decltype dance.
- if (AT->isDecltypeAuto()) {
- if (InitList) {
- Diag(Init->getBeginLoc(), diag::err_decltype_auto_initializer_list);
- return TDK_AlreadyDiagnosed;
- }
- DeducedType = getDecltypeForExpr(Init);
- assert(!DeducedType.isNull());
- } else {
- LocalInstantiationScope InstScope(*this);
- // Build template<class TemplParam> void Func(FuncParam);
- SourceLocation Loc = Init->getExprLoc();
- TemplateTypeParmDecl *TemplParam = TemplateTypeParmDecl::Create(
- Context, nullptr, SourceLocation(), Loc, Info.getDeducedDepth(), 0,
- nullptr, false, false, false);
- QualType TemplArg = QualType(TemplParam->getTypeForDecl(), 0);
- NamedDecl *TemplParamPtr = TemplParam;
- FixedSizeTemplateParameterListStorage<1, false> TemplateParamsSt(
- Context, Loc, Loc, TemplParamPtr, Loc, nullptr);
- if (InitList) {
- // Notionally, we substitute std::initializer_list<T> for 'auto' and
- // deduce against that. Such deduction only succeeds if removing
- // cv-qualifiers and references results in std::initializer_list<T>.
- if (!Type.getType().getNonReferenceType()->getAs<AutoType>())
- return TDK_Invalid;
- SourceRange DeducedFromInitRange;
- for (Expr *Init : InitList->inits()) {
- // Resolving a core issue: a braced-init-list containing any designators
- // is a non-deduced context.
- if (isa<DesignatedInitExpr>(Init))
- return TDK_Invalid;
- if (auto TDK = DeduceTemplateArgumentsFromCallArgument(
- *this, TemplateParamsSt.get(), 0, TemplArg, Init, Info, Deduced,
- OriginalCallArgs, /*Decomposed=*/true,
- /*ArgIdx=*/0, /*TDF=*/0)) {
- if (TDK == TDK_Inconsistent) {
- Diag(Info.getLocation(), diag::err_auto_inconsistent_deduction)
- << Info.FirstArg << Info.SecondArg << DeducedFromInitRange
- << Init->getSourceRange();
- return DeductionFailed(TDK_AlreadyDiagnosed);
- }
- return DeductionFailed(TDK);
- }
- if (DeducedFromInitRange.isInvalid() &&
- Deduced[0].getKind() != TemplateArgument::Null)
- DeducedFromInitRange = Init->getSourceRange();
- }
- } else {
- if (!getLangOpts().CPlusPlus && Init->refersToBitField()) {
- Diag(Loc, diag::err_auto_bitfield);
- return TDK_AlreadyDiagnosed;
- }
- QualType FuncParam =
- SubstituteDeducedTypeTransform(*this, TemplArg).Apply(Type);
- assert(!FuncParam.isNull() &&
- "substituting template parameter for 'auto' failed");
- if (auto TDK = DeduceTemplateArgumentsFromCallArgument(
- *this, TemplateParamsSt.get(), 0, FuncParam, Init, Info, Deduced,
- OriginalCallArgs, /*Decomposed=*/false, /*ArgIdx=*/0, /*TDF=*/0))
- return DeductionFailed(TDK);
- }
- // Could be null if somehow 'auto' appears in a non-deduced context.
- if (Deduced[0].getKind() != TemplateArgument::Type)
- return DeductionFailed(TDK_Incomplete);
- DeducedType = Deduced[0].getAsType();
- if (InitList) {
- DeducedType = BuildStdInitializerList(DeducedType, Loc);
- if (DeducedType.isNull())
- return TDK_AlreadyDiagnosed;
- }
- }
- if (!Result.isNull()) {
- if (!Context.hasSameType(DeducedType, Result)) {
- Info.FirstArg = Result;
- Info.SecondArg = DeducedType;
- return DeductionFailed(TDK_Inconsistent);
- }
- DeducedType = Context.getCommonSugaredType(Result, DeducedType);
- }
- if (AT->isConstrained() && !IgnoreConstraints &&
- CheckDeducedPlaceholderConstraints(
- *this, *AT, Type.getContainedAutoTypeLoc(), DeducedType))
- return TDK_AlreadyDiagnosed;
- Result = SubstituteDeducedTypeTransform(*this, DeducedType).Apply(Type);
- if (Result.isNull())
- return TDK_AlreadyDiagnosed;
- // Check that the deduced argument type is compatible with the original
- // argument type per C++ [temp.deduct.call]p4.
- QualType DeducedA = InitList ? Deduced[0].getAsType() : Result;
- for (const OriginalCallArg &OriginalArg : OriginalCallArgs) {
- assert((bool)InitList == OriginalArg.DecomposedParam &&
- "decomposed non-init-list in auto deduction?");
- if (auto TDK =
- CheckOriginalCallArgDeduction(*this, Info, OriginalArg, DeducedA)) {
- Result = QualType();
- return DeductionFailed(TDK);
- }
- }
- return TDK_Success;
- }
- QualType Sema::SubstAutoType(QualType TypeWithAuto,
- QualType TypeToReplaceAuto) {
- assert(TypeToReplaceAuto != Context.DependentTy);
- return SubstituteDeducedTypeTransform(*this, TypeToReplaceAuto)
- .TransformType(TypeWithAuto);
- }
- TypeSourceInfo *Sema::SubstAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto,
- QualType TypeToReplaceAuto) {
- assert(TypeToReplaceAuto != Context.DependentTy);
- return SubstituteDeducedTypeTransform(*this, TypeToReplaceAuto)
- .TransformType(TypeWithAuto);
- }
- QualType Sema::SubstAutoTypeDependent(QualType TypeWithAuto) {
- return SubstituteDeducedTypeTransform(*this, DependentAuto{false})
- .TransformType(TypeWithAuto);
- }
- TypeSourceInfo *
- Sema::SubstAutoTypeSourceInfoDependent(TypeSourceInfo *TypeWithAuto) {
- return SubstituteDeducedTypeTransform(*this, DependentAuto{false})
- .TransformType(TypeWithAuto);
- }
- QualType Sema::ReplaceAutoType(QualType TypeWithAuto,
- QualType TypeToReplaceAuto) {
- return SubstituteDeducedTypeTransform(*this, TypeToReplaceAuto,
- /*UseTypeSugar*/ false)
- .TransformType(TypeWithAuto);
- }
- TypeSourceInfo *Sema::ReplaceAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto,
- QualType TypeToReplaceAuto) {
- return SubstituteDeducedTypeTransform(*this, TypeToReplaceAuto,
- /*UseTypeSugar*/ false)
- .TransformType(TypeWithAuto);
- }
- void Sema::DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init) {
- if (isa<InitListExpr>(Init))
- Diag(VDecl->getLocation(),
- VDecl->isInitCapture()
- ? diag::err_init_capture_deduction_failure_from_init_list
- : diag::err_auto_var_deduction_failure_from_init_list)
- << VDecl->getDeclName() << VDecl->getType() << Init->getSourceRange();
- else
- Diag(VDecl->getLocation(),
- VDecl->isInitCapture() ? diag::err_init_capture_deduction_failure
- : diag::err_auto_var_deduction_failure)
- << VDecl->getDeclName() << VDecl->getType() << Init->getType()
- << Init->getSourceRange();
- }
- bool Sema::DeduceReturnType(FunctionDecl *FD, SourceLocation Loc,
- bool Diagnose) {
- assert(FD->getReturnType()->isUndeducedType());
- // For a lambda's conversion operator, deduce any 'auto' or 'decltype(auto)'
- // within the return type from the call operator's type.
- if (isLambdaConversionOperator(FD)) {
- CXXRecordDecl *Lambda = cast<CXXMethodDecl>(FD)->getParent();
- FunctionDecl *CallOp = Lambda->getLambdaCallOperator();
- // For a generic lambda, instantiate the call operator if needed.
- if (auto *Args = FD->getTemplateSpecializationArgs()) {
- CallOp = InstantiateFunctionDeclaration(
- CallOp->getDescribedFunctionTemplate(), Args, Loc);
- if (!CallOp || CallOp->isInvalidDecl())
- return true;
- // We might need to deduce the return type by instantiating the definition
- // of the operator() function.
- if (CallOp->getReturnType()->isUndeducedType()) {
- runWithSufficientStackSpace(Loc, [&] {
- InstantiateFunctionDefinition(Loc, CallOp);
- });
- }
- }
- if (CallOp->isInvalidDecl())
- return true;
- assert(!CallOp->getReturnType()->isUndeducedType() &&
- "failed to deduce lambda return type");
- // Build the new return type from scratch.
- CallingConv RetTyCC = FD->getReturnType()
- ->getPointeeType()
- ->castAs<FunctionType>()
- ->getCallConv();
- QualType RetType = getLambdaConversionFunctionResultType(
- CallOp->getType()->castAs<FunctionProtoType>(), RetTyCC);
- if (FD->getReturnType()->getAs<PointerType>())
- RetType = Context.getPointerType(RetType);
- else {
- assert(FD->getReturnType()->getAs<BlockPointerType>());
- RetType = Context.getBlockPointerType(RetType);
- }
- Context.adjustDeducedFunctionResultType(FD, RetType);
- return false;
- }
- if (FD->getTemplateInstantiationPattern()) {
- runWithSufficientStackSpace(Loc, [&] {
- InstantiateFunctionDefinition(Loc, FD);
- });
- }
- bool StillUndeduced = FD->getReturnType()->isUndeducedType();
- if (StillUndeduced && Diagnose && !FD->isInvalidDecl()) {
- Diag(Loc, diag::err_auto_fn_used_before_defined) << FD;
- Diag(FD->getLocation(), diag::note_callee_decl) << FD;
- }
- return StillUndeduced;
- }
- /// If this is a non-static member function,
- static void
- AddImplicitObjectParameterType(ASTContext &Context,
- CXXMethodDecl *Method,
- SmallVectorImpl<QualType> &ArgTypes) {
- // C++11 [temp.func.order]p3:
- // [...] The new parameter is of type "reference to cv A," where cv are
- // the cv-qualifiers of the function template (if any) and A is
- // the class of which the function template is a member.
- //
- // The standard doesn't say explicitly, but we pick the appropriate kind of
- // reference type based on [over.match.funcs]p4.
- QualType ArgTy = Context.getTypeDeclType(Method->getParent());
- ArgTy = Context.getQualifiedType(ArgTy, Method->getMethodQualifiers());
- if (Method->getRefQualifier() == RQ_RValue)
- ArgTy = Context.getRValueReferenceType(ArgTy);
- else
- ArgTy = Context.getLValueReferenceType(ArgTy);
- ArgTypes.push_back(ArgTy);
- }
- /// Determine whether the function template \p FT1 is at least as
- /// specialized as \p FT2.
- static bool isAtLeastAsSpecializedAs(Sema &S,
- SourceLocation Loc,
- FunctionTemplateDecl *FT1,
- FunctionTemplateDecl *FT2,
- TemplatePartialOrderingContext TPOC,
- unsigned NumCallArguments1,
- bool Reversed) {
- assert(!Reversed || TPOC == TPOC_Call);
- FunctionDecl *FD1 = FT1->getTemplatedDecl();
- FunctionDecl *FD2 = FT2->getTemplatedDecl();
- const FunctionProtoType *Proto1 = FD1->getType()->getAs<FunctionProtoType>();
- const FunctionProtoType *Proto2 = FD2->getType()->getAs<FunctionProtoType>();
- assert(Proto1 && Proto2 && "Function templates must have prototypes");
- TemplateParameterList *TemplateParams = FT2->getTemplateParameters();
- SmallVector<DeducedTemplateArgument, 4> Deduced;
- Deduced.resize(TemplateParams->size());
- // C++0x [temp.deduct.partial]p3:
- // The types used to determine the ordering depend on the context in which
- // the partial ordering is done:
- TemplateDeductionInfo Info(Loc);
- SmallVector<QualType, 4> Args2;
- switch (TPOC) {
- case TPOC_Call: {
- // - In the context of a function call, the function parameter types are
- // used.
- CXXMethodDecl *Method1 = dyn_cast<CXXMethodDecl>(FD1);
- CXXMethodDecl *Method2 = dyn_cast<CXXMethodDecl>(FD2);
- // C++11 [temp.func.order]p3:
- // [...] If only one of the function templates is a non-static
- // member, that function template is considered to have a new
- // first parameter inserted in its function parameter list. The
- // new parameter is of type "reference to cv A," where cv are
- // the cv-qualifiers of the function template (if any) and A is
- // the class of which the function template is a member.
- //
- // Note that we interpret this to mean "if one of the function
- // templates is a non-static member and the other is a non-member";
- // otherwise, the ordering rules for static functions against non-static
- // functions don't make any sense.
- //
- // C++98/03 doesn't have this provision but we've extended DR532 to cover
- // it as wording was broken prior to it.
- SmallVector<QualType, 4> Args1;
- unsigned NumComparedArguments = NumCallArguments1;
- if (!Method2 && Method1 && !Method1->isStatic()) {
- // Compare 'this' from Method1 against first parameter from Method2.
- AddImplicitObjectParameterType(S.Context, Method1, Args1);
- ++NumComparedArguments;
- } else if (!Method1 && Method2 && !Method2->isStatic()) {
- // Compare 'this' from Method2 against first parameter from Method1.
- AddImplicitObjectParameterType(S.Context, Method2, Args2);
- } else if (Method1 && Method2 && Reversed) {
- // Compare 'this' from Method1 against second parameter from Method2
- // and 'this' from Method2 against second parameter from Method1.
- AddImplicitObjectParameterType(S.Context, Method1, Args1);
- AddImplicitObjectParameterType(S.Context, Method2, Args2);
- ++NumComparedArguments;
- }
- Args1.insert(Args1.end(), Proto1->param_type_begin(),
- Proto1->param_type_end());
- Args2.insert(Args2.end(), Proto2->param_type_begin(),
- Proto2->param_type_end());
- // C++ [temp.func.order]p5:
- // The presence of unused ellipsis and default arguments has no effect on
- // the partial ordering of function templates.
- if (Args1.size() > NumComparedArguments)
- Args1.resize(NumComparedArguments);
- if (Args2.size() > NumComparedArguments)
- Args2.resize(NumComparedArguments);
- if (Reversed)
- std::reverse(Args2.begin(), Args2.end());
- if (DeduceTemplateArguments(S, TemplateParams, Args2.data(), Args2.size(),
- Args1.data(), Args1.size(), Info, Deduced,
- TDF_None, /*PartialOrdering=*/true))
- return false;
- break;
- }
- case TPOC_Conversion:
- // - In the context of a call to a conversion operator, the return types
- // of the conversion function templates are used.
- if (DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, Proto2->getReturnType(), Proto1->getReturnType(),
- Info, Deduced, TDF_None,
- /*PartialOrdering=*/true))
- return false;
- break;
- case TPOC_Other:
- // - In other contexts (14.6.6.2) the function template's function type
- // is used.
- if (DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
- FD2->getType(), FD1->getType(),
- Info, Deduced, TDF_None,
- /*PartialOrdering=*/true))
- return false;
- break;
- }
- // C++0x [temp.deduct.partial]p11:
- // In most cases, all template parameters must have values in order for
- // deduction to succeed, but for partial ordering purposes a template
- // parameter may remain without a value provided it is not used in the
- // types being used for partial ordering. [ Note: a template parameter used
- // in a non-deduced context is considered used. -end note]
- unsigned ArgIdx = 0, NumArgs = Deduced.size();
- for (; ArgIdx != NumArgs; ++ArgIdx)
- if (Deduced[ArgIdx].isNull())
- break;
- // FIXME: We fail to implement [temp.deduct.type]p1 along this path. We need
- // to substitute the deduced arguments back into the template and check that
- // we get the right type.
- if (ArgIdx == NumArgs) {
- // All template arguments were deduced. FT1 is at least as specialized
- // as FT2.
- return true;
- }
- // Figure out which template parameters were used.
- llvm::SmallBitVector UsedParameters(TemplateParams->size());
- switch (TPOC) {
- case TPOC_Call:
- for (unsigned I = 0, N = Args2.size(); I != N; ++I)
- ::MarkUsedTemplateParameters(S.Context, Args2[I], false,
- TemplateParams->getDepth(),
- UsedParameters);
- break;
- case TPOC_Conversion:
- ::MarkUsedTemplateParameters(S.Context, Proto2->getReturnType(), false,
- TemplateParams->getDepth(), UsedParameters);
- break;
- case TPOC_Other:
- ::MarkUsedTemplateParameters(S.Context, FD2->getType(), false,
- TemplateParams->getDepth(),
- UsedParameters);
- break;
- }
- for (; ArgIdx != NumArgs; ++ArgIdx)
- // If this argument had no value deduced but was used in one of the types
- // used for partial ordering, then deduction fails.
- if (Deduced[ArgIdx].isNull() && UsedParameters[ArgIdx])
- return false;
- return true;
- }
- /// Returns the more specialized function template according
- /// to the rules of function template partial ordering (C++ [temp.func.order]).
- ///
- /// \param FT1 the first function template
- ///
- /// \param FT2 the second function template
- ///
- /// \param TPOC the context in which we are performing partial ordering of
- /// function templates.
- ///
- /// \param NumCallArguments1 The number of arguments in the call to FT1, used
- /// only when \c TPOC is \c TPOC_Call.
- ///
- /// \param NumCallArguments2 The number of arguments in the call to FT2, used
- /// only when \c TPOC is \c TPOC_Call.
- ///
- /// \param Reversed If \c true, exactly one of FT1 and FT2 is an overload
- /// candidate with a reversed parameter order. In this case, the corresponding
- /// P/A pairs between FT1 and FT2 are reversed.
- ///
- /// \returns the more specialized function template. If neither
- /// template is more specialized, returns NULL.
- FunctionTemplateDecl *Sema::getMoreSpecializedTemplate(
- FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
- TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1,
- unsigned NumCallArguments2, bool Reversed) {
- bool Better1 = isAtLeastAsSpecializedAs(*this, Loc, FT1, FT2, TPOC,
- NumCallArguments1, Reversed);
- bool Better2 = isAtLeastAsSpecializedAs(*this, Loc, FT2, FT1, TPOC,
- NumCallArguments2, Reversed);
- // C++ [temp.deduct.partial]p10:
- // F is more specialized than G if F is at least as specialized as G and G
- // is not at least as specialized as F.
- if (Better1 != Better2) // We have a clear winner
- return Better1 ? FT1 : FT2;
- if (!Better1 && !Better2) // Neither is better than the other
- return nullptr;
- // C++ [temp.deduct.partial]p11:
- // ... and if G has a trailing function parameter pack for which F does not
- // have a corresponding parameter, and if F does not have a trailing
- // function parameter pack, then F is more specialized than G.
- FunctionDecl *FD1 = FT1->getTemplatedDecl();
- FunctionDecl *FD2 = FT2->getTemplatedDecl();
- unsigned NumParams1 = FD1->getNumParams();
- unsigned NumParams2 = FD2->getNumParams();
- bool Variadic1 = NumParams1 && FD1->parameters().back()->isParameterPack();
- bool Variadic2 = NumParams2 && FD2->parameters().back()->isParameterPack();
- if (Variadic1 != Variadic2) {
- if (Variadic1 && NumParams1 > NumParams2)
- return FT2;
- if (Variadic2 && NumParams2 > NumParams1)
- return FT1;
- }
- // This a speculative fix for CWG1432 (Similar to the fix for CWG1395) that
- // there is no wording or even resolution for this issue.
- for (int i = 0, e = std::min(NumParams1, NumParams2); i < e; ++i) {
- QualType T1 = FD1->getParamDecl(i)->getType().getCanonicalType();
- QualType T2 = FD2->getParamDecl(i)->getType().getCanonicalType();
- auto *TST1 = dyn_cast<TemplateSpecializationType>(T1);
- auto *TST2 = dyn_cast<TemplateSpecializationType>(T2);
- if (!TST1 || !TST2)
- continue;
- const TemplateArgument &TA1 = TST1->template_arguments().back();
- if (TA1.getKind() == TemplateArgument::Pack) {
- assert(TST1->template_arguments().size() ==
- TST2->template_arguments().size());
- const TemplateArgument &TA2 = TST2->template_arguments().back();
- assert(TA2.getKind() == TemplateArgument::Pack);
- unsigned PackSize1 = TA1.pack_size();
- unsigned PackSize2 = TA2.pack_size();
- bool IsPackExpansion1 =
- PackSize1 && TA1.pack_elements().back().isPackExpansion();
- bool IsPackExpansion2 =
- PackSize2 && TA2.pack_elements().back().isPackExpansion();
- if (PackSize1 != PackSize2 && IsPackExpansion1 != IsPackExpansion2) {
- if (PackSize1 > PackSize2 && IsPackExpansion1)
- return FT2;
- if (PackSize1 < PackSize2 && IsPackExpansion2)
- return FT1;
- }
- }
- }
- if (!Context.getLangOpts().CPlusPlus20)
- return nullptr;
- // Match GCC on not implementing [temp.func.order]p6.2.1.
- // C++20 [temp.func.order]p6:
- // If deduction against the other template succeeds for both transformed
- // templates, constraints can be considered as follows:
- // C++20 [temp.func.order]p6.1:
- // If their template-parameter-lists (possibly including template-parameters
- // invented for an abbreviated function template ([dcl.fct])) or function
- // parameter lists differ in length, neither template is more specialized
- // than the other.
- TemplateParameterList *TPL1 = FT1->getTemplateParameters();
- TemplateParameterList *TPL2 = FT2->getTemplateParameters();
- if (TPL1->size() != TPL2->size() || NumParams1 != NumParams2)
- return nullptr;
- // C++20 [temp.func.order]p6.2.2:
- // Otherwise, if the corresponding template-parameters of the
- // template-parameter-lists are not equivalent ([temp.over.link]) or if the
- // function parameters that positionally correspond between the two
- // templates are not of the same type, neither template is more specialized
- // than the other.
- if (!TemplateParameterListsAreEqual(
- TPL1, TPL2, false, Sema::TPL_TemplateMatch, SourceLocation(), true))
- return nullptr;
- for (unsigned i = 0; i < NumParams1; ++i)
- if (!Context.hasSameType(FD1->getParamDecl(i)->getType(),
- FD2->getParamDecl(i)->getType()))
- return nullptr;
- // C++20 [temp.func.order]p6.3:
- // Otherwise, if the context in which the partial ordering is done is
- // that of a call to a conversion function and the return types of the
- // templates are not the same, then neither template is more specialized
- // than the other.
- if (TPOC == TPOC_Conversion &&
- !Context.hasSameType(FD1->getReturnType(), FD2->getReturnType()))
- return nullptr;
- llvm::SmallVector<const Expr *, 3> AC1, AC2;
- FT1->getAssociatedConstraints(AC1);
- FT2->getAssociatedConstraints(AC2);
- bool AtLeastAsConstrained1, AtLeastAsConstrained2;
- if (IsAtLeastAsConstrained(FT1, AC1, FT2, AC2, AtLeastAsConstrained1))
- return nullptr;
- if (IsAtLeastAsConstrained(FT2, AC2, FT1, AC1, AtLeastAsConstrained2))
- return nullptr;
- if (AtLeastAsConstrained1 == AtLeastAsConstrained2)
- return nullptr;
- return AtLeastAsConstrained1 ? FT1 : FT2;
- }
- /// Determine if the two templates are equivalent.
- static bool isSameTemplate(TemplateDecl *T1, TemplateDecl *T2) {
- if (T1 == T2)
- return true;
- if (!T1 || !T2)
- return false;
- return T1->getCanonicalDecl() == T2->getCanonicalDecl();
- }
- /// Retrieve the most specialized of the given function template
- /// specializations.
- ///
- /// \param SpecBegin the start iterator of the function template
- /// specializations that we will be comparing.
- ///
- /// \param SpecEnd the end iterator of the function template
- /// specializations, paired with \p SpecBegin.
- ///
- /// \param Loc the location where the ambiguity or no-specializations
- /// diagnostic should occur.
- ///
- /// \param NoneDiag partial diagnostic used to diagnose cases where there are
- /// no matching candidates.
- ///
- /// \param AmbigDiag partial diagnostic used to diagnose an ambiguity, if one
- /// occurs.
- ///
- /// \param CandidateDiag partial diagnostic used for each function template
- /// specialization that is a candidate in the ambiguous ordering. One parameter
- /// in this diagnostic should be unbound, which will correspond to the string
- /// describing the template arguments for the function template specialization.
- ///
- /// \returns the most specialized function template specialization, if
- /// found. Otherwise, returns SpecEnd.
- UnresolvedSetIterator Sema::getMostSpecialized(
- UnresolvedSetIterator SpecBegin, UnresolvedSetIterator SpecEnd,
- TemplateSpecCandidateSet &FailedCandidates,
- SourceLocation Loc, const PartialDiagnostic &NoneDiag,
- const PartialDiagnostic &AmbigDiag, const PartialDiagnostic &CandidateDiag,
- bool Complain, QualType TargetType) {
- if (SpecBegin == SpecEnd) {
- if (Complain) {
- Diag(Loc, NoneDiag);
- FailedCandidates.NoteCandidates(*this, Loc);
- }
- return SpecEnd;
- }
- if (SpecBegin + 1 == SpecEnd)
- return SpecBegin;
- // Find the function template that is better than all of the templates it
- // has been compared to.
- UnresolvedSetIterator Best = SpecBegin;
- FunctionTemplateDecl *BestTemplate
- = cast<FunctionDecl>(*Best)->getPrimaryTemplate();
- assert(BestTemplate && "Not a function template specialization?");
- for (UnresolvedSetIterator I = SpecBegin + 1; I != SpecEnd; ++I) {
- FunctionTemplateDecl *Challenger
- = cast<FunctionDecl>(*I)->getPrimaryTemplate();
- assert(Challenger && "Not a function template specialization?");
- if (isSameTemplate(getMoreSpecializedTemplate(BestTemplate, Challenger,
- Loc, TPOC_Other, 0, 0),
- Challenger)) {
- Best = I;
- BestTemplate = Challenger;
- }
- }
- // Make sure that the "best" function template is more specialized than all
- // of the others.
- bool Ambiguous = false;
- for (UnresolvedSetIterator I = SpecBegin; I != SpecEnd; ++I) {
- FunctionTemplateDecl *Challenger
- = cast<FunctionDecl>(*I)->getPrimaryTemplate();
- if (I != Best &&
- !isSameTemplate(getMoreSpecializedTemplate(BestTemplate, Challenger,
- Loc, TPOC_Other, 0, 0),
- BestTemplate)) {
- Ambiguous = true;
- break;
- }
- }
- if (!Ambiguous) {
- // We found an answer. Return it.
- return Best;
- }
- // Diagnose the ambiguity.
- if (Complain) {
- Diag(Loc, AmbigDiag);
- // FIXME: Can we order the candidates in some sane way?
- for (UnresolvedSetIterator I = SpecBegin; I != SpecEnd; ++I) {
- PartialDiagnostic PD = CandidateDiag;
- const auto *FD = cast<FunctionDecl>(*I);
- PD << FD << getTemplateArgumentBindingsText(
- FD->getPrimaryTemplate()->getTemplateParameters(),
- *FD->getTemplateSpecializationArgs());
- if (!TargetType.isNull())
- HandleFunctionTypeMismatch(PD, FD->getType(), TargetType);
- Diag((*I)->getLocation(), PD);
- }
- }
- return SpecEnd;
- }
- /// Determine whether one partial specialization, P1, is at least as
- /// specialized than another, P2.
- ///
- /// \tparam TemplateLikeDecl The kind of P2, which must be a
- /// TemplateDecl or {Class,Var}TemplatePartialSpecializationDecl.
- /// \param T1 The injected-class-name of P1 (faked for a variable template).
- /// \param T2 The injected-class-name of P2 (faked for a variable template).
- template<typename TemplateLikeDecl>
- static bool isAtLeastAsSpecializedAs(Sema &S, QualType T1, QualType T2,
- TemplateLikeDecl *P2,
- TemplateDeductionInfo &Info) {
- // C++ [temp.class.order]p1:
- // For two class template partial specializations, the first is at least as
- // specialized as the second if, given the following rewrite to two
- // function templates, the first function template is at least as
- // specialized as the second according to the ordering rules for function
- // templates (14.6.6.2):
- // - the first function template has the same template parameters as the
- // first partial specialization and has a single function parameter
- // whose type is a class template specialization with the template
- // arguments of the first partial specialization, and
- // - the second function template has the same template parameters as the
- // second partial specialization and has a single function parameter
- // whose type is a class template specialization with the template
- // arguments of the second partial specialization.
- //
- // Rather than synthesize function templates, we merely perform the
- // equivalent partial ordering by performing deduction directly on
- // the template arguments of the class template partial
- // specializations. This computation is slightly simpler than the
- // general problem of function template partial ordering, because
- // class template partial specializations are more constrained. We
- // know that every template parameter is deducible from the class
- // template partial specialization's template arguments, for
- // example.
- SmallVector<DeducedTemplateArgument, 4> Deduced;
- // Determine whether P1 is at least as specialized as P2.
- Deduced.resize(P2->getTemplateParameters()->size());
- if (DeduceTemplateArgumentsByTypeMatch(S, P2->getTemplateParameters(),
- T2, T1, Info, Deduced, TDF_None,
- /*PartialOrdering=*/true))
- return false;
- SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(),
- Deduced.end());
- Sema::InstantiatingTemplate Inst(S, Info.getLocation(), P2, DeducedArgs,
- Info);
- if (Inst.isInvalid())
- return false;
- const auto *TST1 = cast<TemplateSpecializationType>(T1);
- bool AtLeastAsSpecialized;
- S.runWithSufficientStackSpace(Info.getLocation(), [&] {
- AtLeastAsSpecialized = !FinishTemplateArgumentDeduction(
- S, P2, /*IsPartialOrdering=*/true,
- TemplateArgumentList(TemplateArgumentList::OnStack,
- TST1->template_arguments()),
- Deduced, Info);
- });
- return AtLeastAsSpecialized;
- }
- namespace {
- // A dummy class to return nullptr instead of P2 when performing "more
- // specialized than primary" check.
- struct GetP2 {
- template <typename T1, typename T2,
- std::enable_if_t<std::is_same_v<T1, T2>, bool> = true>
- T2 *operator()(T1 *, T2 *P2) {
- return P2;
- }
- template <typename T1, typename T2,
- std::enable_if_t<!std::is_same_v<T1, T2>, bool> = true>
- T1 *operator()(T1 *, T2 *) {
- return nullptr;
- }
- };
- // The assumption is that two template argument lists have the same size.
- struct TemplateArgumentListAreEqual {
- ASTContext &Ctx;
- TemplateArgumentListAreEqual(ASTContext &Ctx) : Ctx(Ctx) {}
- template <typename T1, typename T2,
- std::enable_if_t<std::is_same_v<T1, T2>, bool> = true>
- bool operator()(T1 *PS1, T2 *PS2) {
- ArrayRef<TemplateArgument> Args1 = PS1->getTemplateArgs().asArray(),
- Args2 = PS2->getTemplateArgs().asArray();
- for (unsigned I = 0, E = Args1.size(); I < E; ++I) {
- // We use profile, instead of structural comparison of the arguments,
- // because canonicalization can't do the right thing for dependent
- // expressions.
- llvm::FoldingSetNodeID IDA, IDB;
- Args1[I].Profile(IDA, Ctx);
- Args2[I].Profile(IDB, Ctx);
- if (IDA != IDB)
- return false;
- }
- return true;
- }
- template <typename T1, typename T2,
- std::enable_if_t<!std::is_same_v<T1, T2>, bool> = true>
- bool operator()(T1 *Spec, T2 *Primary) {
- ArrayRef<TemplateArgument> Args1 = Spec->getTemplateArgs().asArray(),
- Args2 = Primary->getInjectedTemplateArgs();
- for (unsigned I = 0, E = Args1.size(); I < E; ++I) {
- // We use profile, instead of structural comparison of the arguments,
- // because canonicalization can't do the right thing for dependent
- // expressions.
- llvm::FoldingSetNodeID IDA, IDB;
- Args1[I].Profile(IDA, Ctx);
- // Unlike the specialization arguments, the injected arguments are not
- // always canonical.
- Ctx.getCanonicalTemplateArgument(Args2[I]).Profile(IDB, Ctx);
- if (IDA != IDB)
- return false;
- }
- return true;
- }
- };
- } // namespace
- /// Returns the more specialized template specialization between T1/P1 and
- /// T2/P2.
- /// - If IsMoreSpecialThanPrimaryCheck is true, T1/P1 is the partial
- /// specialization and T2/P2 is the primary template.
- /// - otherwise, both T1/P1 and T2/P2 are the partial specialization.
- ///
- /// \param T1 the type of the first template partial specialization
- ///
- /// \param T2 if IsMoreSpecialThanPrimaryCheck is true, the type of the second
- /// template partial specialization; otherwise, the type of the
- /// primary template.
- ///
- /// \param P1 the first template partial specialization
- ///
- /// \param P2 if IsMoreSpecialThanPrimaryCheck is true, the second template
- /// partial specialization; otherwise, the primary template.
- ///
- /// \returns - If IsMoreSpecialThanPrimaryCheck is true, returns P1 if P1 is
- /// more specialized, returns nullptr if P1 is not more specialized.
- /// - otherwise, returns the more specialized template partial
- /// specialization. If neither partial specialization is more
- /// specialized, returns NULL.
- template <typename TemplateLikeDecl, typename PrimaryDel>
- static TemplateLikeDecl *
- getMoreSpecialized(Sema &S, QualType T1, QualType T2, TemplateLikeDecl *P1,
- PrimaryDel *P2, TemplateDeductionInfo &Info) {
- constexpr bool IsMoreSpecialThanPrimaryCheck =
- !std::is_same_v<TemplateLikeDecl, PrimaryDel>;
- bool Better1 = isAtLeastAsSpecializedAs(S, T1, T2, P2, Info);
- if (IsMoreSpecialThanPrimaryCheck && !Better1)
- return nullptr;
- bool Better2 = isAtLeastAsSpecializedAs(S, T2, T1, P1, Info);
- if (IsMoreSpecialThanPrimaryCheck && !Better2)
- return P1;
- // C++ [temp.deduct.partial]p10:
- // F is more specialized than G if F is at least as specialized as G and G
- // is not at least as specialized as F.
- if (Better1 != Better2) // We have a clear winner
- return Better1 ? P1 : GetP2()(P1, P2);
- if (!Better1 && !Better2)
- return nullptr;
- // This a speculative fix for CWG1432 (Similar to the fix for CWG1395) that
- // there is no wording or even resolution for this issue.
- auto *TST1 = cast<TemplateSpecializationType>(T1);
- auto *TST2 = cast<TemplateSpecializationType>(T2);
- const TemplateArgument &TA1 = TST1->template_arguments().back();
- if (TA1.getKind() == TemplateArgument::Pack) {
- assert(TST1->template_arguments().size() ==
- TST2->template_arguments().size());
- const TemplateArgument &TA2 = TST2->template_arguments().back();
- assert(TA2.getKind() == TemplateArgument::Pack);
- unsigned PackSize1 = TA1.pack_size();
- unsigned PackSize2 = TA2.pack_size();
- bool IsPackExpansion1 =
- PackSize1 && TA1.pack_elements().back().isPackExpansion();
- bool IsPackExpansion2 =
- PackSize2 && TA2.pack_elements().back().isPackExpansion();
- if (PackSize1 != PackSize2 && IsPackExpansion1 != IsPackExpansion2) {
- if (PackSize1 > PackSize2 && IsPackExpansion1)
- return GetP2()(P1, P2);
- if (PackSize1 < PackSize2 && IsPackExpansion2)
- return P1;
- }
- }
- if (!S.Context.getLangOpts().CPlusPlus20)
- return nullptr;
- // Match GCC on not implementing [temp.func.order]p6.2.1.
- // C++20 [temp.func.order]p6:
- // If deduction against the other template succeeds for both transformed
- // templates, constraints can be considered as follows:
- TemplateParameterList *TPL1 = P1->getTemplateParameters();
- TemplateParameterList *TPL2 = P2->getTemplateParameters();
- if (TPL1->size() != TPL2->size())
- return nullptr;
- // C++20 [temp.func.order]p6.2.2:
- // Otherwise, if the corresponding template-parameters of the
- // template-parameter-lists are not equivalent ([temp.over.link]) or if the
- // function parameters that positionally correspond between the two
- // templates are not of the same type, neither template is more specialized
- // than the other.
- if (!S.TemplateParameterListsAreEqual(
- TPL1, TPL2, false, Sema::TPL_TemplateMatch, SourceLocation(), true))
- return nullptr;
- if (!TemplateArgumentListAreEqual(S.getASTContext())(P1, P2))
- return nullptr;
- llvm::SmallVector<const Expr *, 3> AC1, AC2;
- P1->getAssociatedConstraints(AC1);
- P2->getAssociatedConstraints(AC2);
- bool AtLeastAsConstrained1, AtLeastAsConstrained2;
- if (S.IsAtLeastAsConstrained(P1, AC1, P2, AC2, AtLeastAsConstrained1) ||
- (IsMoreSpecialThanPrimaryCheck && !AtLeastAsConstrained1))
- return nullptr;
- if (S.IsAtLeastAsConstrained(P2, AC2, P1, AC1, AtLeastAsConstrained2))
- return nullptr;
- if (AtLeastAsConstrained1 == AtLeastAsConstrained2)
- return nullptr;
- return AtLeastAsConstrained1 ? P1 : GetP2()(P1, P2);
- }
- /// Returns the more specialized class template partial specialization
- /// according to the rules of partial ordering of class template partial
- /// specializations (C++ [temp.class.order]).
- ///
- /// \param PS1 the first class template partial specialization
- ///
- /// \param PS2 the second class template partial specialization
- ///
- /// \returns the more specialized class template partial specialization. If
- /// neither partial specialization is more specialized, returns NULL.
- ClassTemplatePartialSpecializationDecl *
- Sema::getMoreSpecializedPartialSpecialization(
- ClassTemplatePartialSpecializationDecl *PS1,
- ClassTemplatePartialSpecializationDecl *PS2,
- SourceLocation Loc) {
- QualType PT1 = PS1->getInjectedSpecializationType();
- QualType PT2 = PS2->getInjectedSpecializationType();
- TemplateDeductionInfo Info(Loc);
- return getMoreSpecialized(*this, PT1, PT2, PS1, PS2, Info);
- }
- bool Sema::isMoreSpecializedThanPrimary(
- ClassTemplatePartialSpecializationDecl *Spec, TemplateDeductionInfo &Info) {
- ClassTemplateDecl *Primary = Spec->getSpecializedTemplate();
- QualType PrimaryT = Primary->getInjectedClassNameSpecialization();
- QualType PartialT = Spec->getInjectedSpecializationType();
- ClassTemplatePartialSpecializationDecl *MaybeSpec =
- getMoreSpecialized(*this, PartialT, PrimaryT, Spec, Primary, Info);
- if (MaybeSpec)
- Info.clearSFINAEDiagnostic();
- return MaybeSpec;
- }
- VarTemplatePartialSpecializationDecl *
- Sema::getMoreSpecializedPartialSpecialization(
- VarTemplatePartialSpecializationDecl *PS1,
- VarTemplatePartialSpecializationDecl *PS2, SourceLocation Loc) {
- // Pretend the variable template specializations are class template
- // specializations and form a fake injected class name type for comparison.
- assert(PS1->getSpecializedTemplate() == PS2->getSpecializedTemplate() &&
- "the partial specializations being compared should specialize"
- " the same template.");
- TemplateName Name(PS1->getSpecializedTemplate());
- TemplateName CanonTemplate = Context.getCanonicalTemplateName(Name);
- QualType PT1 = Context.getTemplateSpecializationType(
- CanonTemplate, PS1->getTemplateArgs().asArray());
- QualType PT2 = Context.getTemplateSpecializationType(
- CanonTemplate, PS2->getTemplateArgs().asArray());
- TemplateDeductionInfo Info(Loc);
- return getMoreSpecialized(*this, PT1, PT2, PS1, PS2, Info);
- }
- bool Sema::isMoreSpecializedThanPrimary(
- VarTemplatePartialSpecializationDecl *Spec, TemplateDeductionInfo &Info) {
- VarTemplateDecl *Primary = Spec->getSpecializedTemplate();
- TemplateName CanonTemplate =
- Context.getCanonicalTemplateName(TemplateName(Primary));
- QualType PrimaryT = Context.getTemplateSpecializationType(
- CanonTemplate, Primary->getInjectedTemplateArgs());
- QualType PartialT = Context.getTemplateSpecializationType(
- CanonTemplate, Spec->getTemplateArgs().asArray());
- VarTemplatePartialSpecializationDecl *MaybeSpec =
- getMoreSpecialized(*this, PartialT, PrimaryT, Spec, Primary, Info);
- if (MaybeSpec)
- Info.clearSFINAEDiagnostic();
- return MaybeSpec;
- }
- bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs(
- TemplateParameterList *P, TemplateDecl *AArg, SourceLocation Loc) {
- // C++1z [temp.arg.template]p4: (DR 150)
- // A template template-parameter P is at least as specialized as a
- // template template-argument A if, given the following rewrite to two
- // function templates...
- // Rather than synthesize function templates, we merely perform the
- // equivalent partial ordering by performing deduction directly on
- // the template parameter lists of the template template parameters.
- //
- // Given an invented class template X with the template parameter list of
- // A (including default arguments):
- TemplateName X = Context.getCanonicalTemplateName(TemplateName(AArg));
- TemplateParameterList *A = AArg->getTemplateParameters();
- // - Each function template has a single function parameter whose type is
- // a specialization of X with template arguments corresponding to the
- // template parameters from the respective function template
- SmallVector<TemplateArgument, 8> AArgs;
- Context.getInjectedTemplateArgs(A, AArgs);
- // Check P's arguments against A's parameter list. This will fill in default
- // template arguments as needed. AArgs are already correct by construction.
- // We can't just use CheckTemplateIdType because that will expand alias
- // templates.
- SmallVector<TemplateArgument, 4> PArgs;
- {
- SFINAETrap Trap(*this);
- Context.getInjectedTemplateArgs(P, PArgs);
- TemplateArgumentListInfo PArgList(P->getLAngleLoc(),
- P->getRAngleLoc());
- for (unsigned I = 0, N = P->size(); I != N; ++I) {
- // Unwrap packs that getInjectedTemplateArgs wrapped around pack
- // expansions, to form an "as written" argument list.
- TemplateArgument Arg = PArgs[I];
- if (Arg.getKind() == TemplateArgument::Pack) {
- assert(Arg.pack_size() == 1 && Arg.pack_begin()->isPackExpansion());
- Arg = *Arg.pack_begin();
- }
- PArgList.addArgument(getTrivialTemplateArgumentLoc(
- Arg, QualType(), P->getParam(I)->getLocation()));
- }
- PArgs.clear();
- // C++1z [temp.arg.template]p3:
- // If the rewrite produces an invalid type, then P is not at least as
- // specialized as A.
- SmallVector<TemplateArgument, 4> SugaredPArgs;
- if (CheckTemplateArgumentList(AArg, Loc, PArgList, false, SugaredPArgs,
- PArgs) ||
- Trap.hasErrorOccurred())
- return false;
- }
- QualType AType = Context.getCanonicalTemplateSpecializationType(X, AArgs);
- QualType PType = Context.getCanonicalTemplateSpecializationType(X, PArgs);
- // ... the function template corresponding to P is at least as specialized
- // as the function template corresponding to A according to the partial
- // ordering rules for function templates.
- TemplateDeductionInfo Info(Loc, A->getDepth());
- return isAtLeastAsSpecializedAs(*this, PType, AType, AArg, Info);
- }
- namespace {
- struct MarkUsedTemplateParameterVisitor :
- RecursiveASTVisitor<MarkUsedTemplateParameterVisitor> {
- llvm::SmallBitVector &Used;
- unsigned Depth;
- MarkUsedTemplateParameterVisitor(llvm::SmallBitVector &Used,
- unsigned Depth)
- : Used(Used), Depth(Depth) { }
- bool VisitTemplateTypeParmType(TemplateTypeParmType *T) {
- if (T->getDepth() == Depth)
- Used[T->getIndex()] = true;
- return true;
- }
- bool TraverseTemplateName(TemplateName Template) {
- if (auto *TTP = llvm::dyn_cast_or_null<TemplateTemplateParmDecl>(
- Template.getAsTemplateDecl()))
- if (TTP->getDepth() == Depth)
- Used[TTP->getIndex()] = true;
- RecursiveASTVisitor<MarkUsedTemplateParameterVisitor>::
- TraverseTemplateName(Template);
- return true;
- }
- bool VisitDeclRefExpr(DeclRefExpr *E) {
- if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(E->getDecl()))
- if (NTTP->getDepth() == Depth)
- Used[NTTP->getIndex()] = true;
- return true;
- }
- };
- }
- /// Mark the template parameters that are used by the given
- /// expression.
- static void
- MarkUsedTemplateParameters(ASTContext &Ctx,
- const Expr *E,
- bool OnlyDeduced,
- unsigned Depth,
- llvm::SmallBitVector &Used) {
- if (!OnlyDeduced) {
- MarkUsedTemplateParameterVisitor(Used, Depth)
- .TraverseStmt(const_cast<Expr *>(E));
- return;
- }
- // We can deduce from a pack expansion.
- if (const PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(E))
- E = Expansion->getPattern();
- const NonTypeTemplateParmDecl *NTTP = getDeducedParameterFromExpr(E, Depth);
- if (!NTTP)
- return;
- if (NTTP->getDepth() == Depth)
- Used[NTTP->getIndex()] = true;
- // In C++17 mode, additional arguments may be deduced from the type of a
- // non-type argument.
- if (Ctx.getLangOpts().CPlusPlus17)
- MarkUsedTemplateParameters(Ctx, NTTP->getType(), OnlyDeduced, Depth, Used);
- }
- /// Mark the template parameters that are used by the given
- /// nested name specifier.
- static void
- MarkUsedTemplateParameters(ASTContext &Ctx,
- NestedNameSpecifier *NNS,
- bool OnlyDeduced,
- unsigned Depth,
- llvm::SmallBitVector &Used) {
- if (!NNS)
- return;
- MarkUsedTemplateParameters(Ctx, NNS->getPrefix(), OnlyDeduced, Depth,
- Used);
- MarkUsedTemplateParameters(Ctx, QualType(NNS->getAsType(), 0),
- OnlyDeduced, Depth, Used);
- }
- /// Mark the template parameters that are used by the given
- /// template name.
- static void
- MarkUsedTemplateParameters(ASTContext &Ctx,
- TemplateName Name,
- bool OnlyDeduced,
- unsigned Depth,
- llvm::SmallBitVector &Used) {
- if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
- if (TemplateTemplateParmDecl *TTP
- = dyn_cast<TemplateTemplateParmDecl>(Template)) {
- if (TTP->getDepth() == Depth)
- Used[TTP->getIndex()] = true;
- }
- return;
- }
- if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName())
- MarkUsedTemplateParameters(Ctx, QTN->getQualifier(), OnlyDeduced,
- Depth, Used);
- if (DependentTemplateName *DTN = Name.getAsDependentTemplateName())
- MarkUsedTemplateParameters(Ctx, DTN->getQualifier(), OnlyDeduced,
- Depth, Used);
- }
- /// Mark the template parameters that are used by the given
- /// type.
- static void
- MarkUsedTemplateParameters(ASTContext &Ctx, QualType T,
- bool OnlyDeduced,
- unsigned Depth,
- llvm::SmallBitVector &Used) {
- if (T.isNull())
- return;
- // Non-dependent types have nothing deducible
- if (!T->isDependentType())
- return;
- T = Ctx.getCanonicalType(T);
- switch (T->getTypeClass()) {
- case Type::Pointer:
- MarkUsedTemplateParameters(Ctx,
- cast<PointerType>(T)->getPointeeType(),
- OnlyDeduced,
- Depth,
- Used);
- break;
- case Type::BlockPointer:
- MarkUsedTemplateParameters(Ctx,
- cast<BlockPointerType>(T)->getPointeeType(),
- OnlyDeduced,
- Depth,
- Used);
- break;
- case Type::LValueReference:
- case Type::RValueReference:
- MarkUsedTemplateParameters(Ctx,
- cast<ReferenceType>(T)->getPointeeType(),
- OnlyDeduced,
- Depth,
- Used);
- break;
- case Type::MemberPointer: {
- const MemberPointerType *MemPtr = cast<MemberPointerType>(T.getTypePtr());
- MarkUsedTemplateParameters(Ctx, MemPtr->getPointeeType(), OnlyDeduced,
- Depth, Used);
- MarkUsedTemplateParameters(Ctx, QualType(MemPtr->getClass(), 0),
- OnlyDeduced, Depth, Used);
- break;
- }
- case Type::DependentSizedArray:
- MarkUsedTemplateParameters(Ctx,
- cast<DependentSizedArrayType>(T)->getSizeExpr(),
- OnlyDeduced, Depth, Used);
- // Fall through to check the element type
- [[fallthrough]];
- case Type::ConstantArray:
- case Type::IncompleteArray:
- MarkUsedTemplateParameters(Ctx,
- cast<ArrayType>(T)->getElementType(),
- OnlyDeduced, Depth, Used);
- break;
- case Type::Vector:
- case Type::ExtVector:
- MarkUsedTemplateParameters(Ctx,
- cast<VectorType>(T)->getElementType(),
- OnlyDeduced, Depth, Used);
- break;
- case Type::DependentVector: {
- const auto *VecType = cast<DependentVectorType>(T);
- MarkUsedTemplateParameters(Ctx, VecType->getElementType(), OnlyDeduced,
- Depth, Used);
- MarkUsedTemplateParameters(Ctx, VecType->getSizeExpr(), OnlyDeduced, Depth,
- Used);
- break;
- }
- case Type::DependentSizedExtVector: {
- const DependentSizedExtVectorType *VecType
- = cast<DependentSizedExtVectorType>(T);
- MarkUsedTemplateParameters(Ctx, VecType->getElementType(), OnlyDeduced,
- Depth, Used);
- MarkUsedTemplateParameters(Ctx, VecType->getSizeExpr(), OnlyDeduced,
- Depth, Used);
- break;
- }
- case Type::DependentAddressSpace: {
- const DependentAddressSpaceType *DependentASType =
- cast<DependentAddressSpaceType>(T);
- MarkUsedTemplateParameters(Ctx, DependentASType->getPointeeType(),
- OnlyDeduced, Depth, Used);
- MarkUsedTemplateParameters(Ctx,
- DependentASType->getAddrSpaceExpr(),
- OnlyDeduced, Depth, Used);
- break;
- }
- case Type::ConstantMatrix: {
- const ConstantMatrixType *MatType = cast<ConstantMatrixType>(T);
- MarkUsedTemplateParameters(Ctx, MatType->getElementType(), OnlyDeduced,
- Depth, Used);
- break;
- }
- case Type::DependentSizedMatrix: {
- const DependentSizedMatrixType *MatType = cast<DependentSizedMatrixType>(T);
- MarkUsedTemplateParameters(Ctx, MatType->getElementType(), OnlyDeduced,
- Depth, Used);
- MarkUsedTemplateParameters(Ctx, MatType->getRowExpr(), OnlyDeduced, Depth,
- Used);
- MarkUsedTemplateParameters(Ctx, MatType->getColumnExpr(), OnlyDeduced,
- Depth, Used);
- break;
- }
- case Type::FunctionProto: {
- const FunctionProtoType *Proto = cast<FunctionProtoType>(T);
- MarkUsedTemplateParameters(Ctx, Proto->getReturnType(), OnlyDeduced, Depth,
- Used);
- for (unsigned I = 0, N = Proto->getNumParams(); I != N; ++I) {
- // C++17 [temp.deduct.type]p5:
- // The non-deduced contexts are: [...]
- // -- A function parameter pack that does not occur at the end of the
- // parameter-declaration-list.
- if (!OnlyDeduced || I + 1 == N ||
- !Proto->getParamType(I)->getAs<PackExpansionType>()) {
- MarkUsedTemplateParameters(Ctx, Proto->getParamType(I), OnlyDeduced,
- Depth, Used);
- } else {
- // FIXME: C++17 [temp.deduct.call]p1:
- // When a function parameter pack appears in a non-deduced context,
- // the type of that pack is never deduced.
- //
- // We should also track a set of "never deduced" parameters, and
- // subtract that from the list of deduced parameters after marking.
- }
- }
- if (auto *E = Proto->getNoexceptExpr())
- MarkUsedTemplateParameters(Ctx, E, OnlyDeduced, Depth, Used);
- break;
- }
- case Type::TemplateTypeParm: {
- const TemplateTypeParmType *TTP = cast<TemplateTypeParmType>(T);
- if (TTP->getDepth() == Depth)
- Used[TTP->getIndex()] = true;
- break;
- }
- case Type::SubstTemplateTypeParmPack: {
- const SubstTemplateTypeParmPackType *Subst
- = cast<SubstTemplateTypeParmPackType>(T);
- if (Subst->getReplacedParameter()->getDepth() == Depth)
- Used[Subst->getIndex()] = true;
- MarkUsedTemplateParameters(Ctx, Subst->getArgumentPack(),
- OnlyDeduced, Depth, Used);
- break;
- }
- case Type::InjectedClassName:
- T = cast<InjectedClassNameType>(T)->getInjectedSpecializationType();
- [[fallthrough]];
- case Type::TemplateSpecialization: {
- const TemplateSpecializationType *Spec
- = cast<TemplateSpecializationType>(T);
- MarkUsedTemplateParameters(Ctx, Spec->getTemplateName(), OnlyDeduced,
- Depth, Used);
- // C++0x [temp.deduct.type]p9:
- // If the template argument list of P contains a pack expansion that is
- // not the last template argument, the entire template argument list is a
- // non-deduced context.
- if (OnlyDeduced &&
- hasPackExpansionBeforeEnd(Spec->template_arguments()))
- break;
- for (const auto &Arg : Spec->template_arguments())
- MarkUsedTemplateParameters(Ctx, Arg, OnlyDeduced, Depth, Used);
- break;
- }
- case Type::Complex:
- if (!OnlyDeduced)
- MarkUsedTemplateParameters(Ctx,
- cast<ComplexType>(T)->getElementType(),
- OnlyDeduced, Depth, Used);
- break;
- case Type::Atomic:
- if (!OnlyDeduced)
- MarkUsedTemplateParameters(Ctx,
- cast<AtomicType>(T)->getValueType(),
- OnlyDeduced, Depth, Used);
- break;
- case Type::DependentName:
- if (!OnlyDeduced)
- MarkUsedTemplateParameters(Ctx,
- cast<DependentNameType>(T)->getQualifier(),
- OnlyDeduced, Depth, Used);
- break;
- case Type::DependentTemplateSpecialization: {
- // C++14 [temp.deduct.type]p5:
- // The non-deduced contexts are:
- // -- The nested-name-specifier of a type that was specified using a
- // qualified-id
- //
- // C++14 [temp.deduct.type]p6:
- // When a type name is specified in a way that includes a non-deduced
- // context, all of the types that comprise that type name are also
- // non-deduced.
- if (OnlyDeduced)
- break;
- const DependentTemplateSpecializationType *Spec
- = cast<DependentTemplateSpecializationType>(T);
- MarkUsedTemplateParameters(Ctx, Spec->getQualifier(),
- OnlyDeduced, Depth, Used);
- for (const auto &Arg : Spec->template_arguments())
- MarkUsedTemplateParameters(Ctx, Arg, OnlyDeduced, Depth, Used);
- break;
- }
- case Type::TypeOf:
- if (!OnlyDeduced)
- MarkUsedTemplateParameters(Ctx, cast<TypeOfType>(T)->getUnmodifiedType(),
- OnlyDeduced, Depth, Used);
- break;
- case Type::TypeOfExpr:
- if (!OnlyDeduced)
- MarkUsedTemplateParameters(Ctx,
- cast<TypeOfExprType>(T)->getUnderlyingExpr(),
- OnlyDeduced, Depth, Used);
- break;
- case Type::Decltype:
- if (!OnlyDeduced)
- MarkUsedTemplateParameters(Ctx,
- cast<DecltypeType>(T)->getUnderlyingExpr(),
- OnlyDeduced, Depth, Used);
- break;
- case Type::UnaryTransform:
- if (!OnlyDeduced)
- MarkUsedTemplateParameters(Ctx,
- cast<UnaryTransformType>(T)->getUnderlyingType(),
- OnlyDeduced, Depth, Used);
- break;
- case Type::PackExpansion:
- MarkUsedTemplateParameters(Ctx,
- cast<PackExpansionType>(T)->getPattern(),
- OnlyDeduced, Depth, Used);
- break;
- case Type::Auto:
- case Type::DeducedTemplateSpecialization:
- MarkUsedTemplateParameters(Ctx,
- cast<DeducedType>(T)->getDeducedType(),
- OnlyDeduced, Depth, Used);
- break;
- case Type::DependentBitInt:
- MarkUsedTemplateParameters(Ctx,
- cast<DependentBitIntType>(T)->getNumBitsExpr(),
- OnlyDeduced, Depth, Used);
- break;
- // None of these types have any template parameters in them.
- case Type::Builtin:
- case Type::VariableArray:
- case Type::FunctionNoProto:
- case Type::Record:
- case Type::Enum:
- case Type::ObjCInterface:
- case Type::ObjCObject:
- case Type::ObjCObjectPointer:
- case Type::UnresolvedUsing:
- case Type::Pipe:
- case Type::BitInt:
- #define TYPE(Class, Base)
- #define ABSTRACT_TYPE(Class, Base)
- #define DEPENDENT_TYPE(Class, Base)
- #define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
- #include "clang/AST/TypeNodes.inc"
- break;
- }
- }
- /// Mark the template parameters that are used by this
- /// template argument.
- static void
- MarkUsedTemplateParameters(ASTContext &Ctx,
- const TemplateArgument &TemplateArg,
- bool OnlyDeduced,
- unsigned Depth,
- llvm::SmallBitVector &Used) {
- switch (TemplateArg.getKind()) {
- case TemplateArgument::Null:
- case TemplateArgument::Integral:
- case TemplateArgument::Declaration:
- break;
- case TemplateArgument::NullPtr:
- MarkUsedTemplateParameters(Ctx, TemplateArg.getNullPtrType(), OnlyDeduced,
- Depth, Used);
- break;
- case TemplateArgument::Type:
- MarkUsedTemplateParameters(Ctx, TemplateArg.getAsType(), OnlyDeduced,
- Depth, Used);
- break;
- case TemplateArgument::Template:
- case TemplateArgument::TemplateExpansion:
- MarkUsedTemplateParameters(Ctx,
- TemplateArg.getAsTemplateOrTemplatePattern(),
- OnlyDeduced, Depth, Used);
- break;
- case TemplateArgument::Expression:
- MarkUsedTemplateParameters(Ctx, TemplateArg.getAsExpr(), OnlyDeduced,
- Depth, Used);
- break;
- case TemplateArgument::Pack:
- for (const auto &P : TemplateArg.pack_elements())
- MarkUsedTemplateParameters(Ctx, P, OnlyDeduced, Depth, Used);
- break;
- }
- }
- /// Mark which template parameters are used in a given expression.
- ///
- /// \param E the expression from which template parameters will be deduced.
- ///
- /// \param Used a bit vector whose elements will be set to \c true
- /// to indicate when the corresponding template parameter will be
- /// deduced.
- void
- Sema::MarkUsedTemplateParameters(const Expr *E, bool OnlyDeduced,
- unsigned Depth,
- llvm::SmallBitVector &Used) {
- ::MarkUsedTemplateParameters(Context, E, OnlyDeduced, Depth, Used);
- }
- /// Mark which template parameters can be deduced from a given
- /// template argument list.
- ///
- /// \param TemplateArgs the template argument list from which template
- /// parameters will be deduced.
- ///
- /// \param Used a bit vector whose elements will be set to \c true
- /// to indicate when the corresponding template parameter will be
- /// deduced.
- void
- Sema::MarkUsedTemplateParameters(const TemplateArgumentList &TemplateArgs,
- bool OnlyDeduced, unsigned Depth,
- llvm::SmallBitVector &Used) {
- // C++0x [temp.deduct.type]p9:
- // If the template argument list of P contains a pack expansion that is not
- // the last template argument, the entire template argument list is a
- // non-deduced context.
- if (OnlyDeduced &&
- hasPackExpansionBeforeEnd(TemplateArgs.asArray()))
- return;
- for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
- ::MarkUsedTemplateParameters(Context, TemplateArgs[I], OnlyDeduced,
- Depth, Used);
- }
- /// Marks all of the template parameters that will be deduced by a
- /// call to the given function template.
- void Sema::MarkDeducedTemplateParameters(
- ASTContext &Ctx, const FunctionTemplateDecl *FunctionTemplate,
- llvm::SmallBitVector &Deduced) {
- TemplateParameterList *TemplateParams
- = FunctionTemplate->getTemplateParameters();
- Deduced.clear();
- Deduced.resize(TemplateParams->size());
- FunctionDecl *Function = FunctionTemplate->getTemplatedDecl();
- for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I)
- ::MarkUsedTemplateParameters(Ctx, Function->getParamDecl(I)->getType(),
- true, TemplateParams->getDepth(), Deduced);
- }
- bool hasDeducibleTemplateParameters(Sema &S,
- FunctionTemplateDecl *FunctionTemplate,
- QualType T) {
- if (!T->isDependentType())
- return false;
- TemplateParameterList *TemplateParams
- = FunctionTemplate->getTemplateParameters();
- llvm::SmallBitVector Deduced(TemplateParams->size());
- ::MarkUsedTemplateParameters(S.Context, T, true, TemplateParams->getDepth(),
- Deduced);
- return Deduced.any();
- }
|